diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 5b3df062dea9d..0000000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -## What Does This PR Do - - - - - -## Why It's Good For The Game - - - -## Images of changes - - - -## Testing - - - -
- -### Declaration - -- [ ] I confirm that I either do not require [pre-approval](https://github.com/ParadiseSS13/Paradise/blob/master/docs/CODE_OF_CONDUCT.md#types-of-changes-that-need-approval) for this PR, or I have obtained such approval and have included a screenshot to demonstrate this below. - - -
- -## Changelog - -:cl: -add: Added new things -del: Removed old things -tweak: Tweaked a few things -fix: Fixed a few things -wip: Added a few works in progress -soundadd: Added a new sound thingy -sounddel: Removed an old sound thingy -imageadd: Added some icons and images -imagedel: Deleted some icons and images -spellcheck: Fixed a few typos -experiment: Added an experimental thingy -/:cl: - - - - diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index c726084c96da1..0000000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,160 +0,0 @@ -name: CI -on: - push: - branches: - - master - pull_request: - branches: - - master - merge_group: - -jobs: - run_linters: - name: Run Linters - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - - name: Setup Cache - uses: actions/cache@v4 - with: - path: $HOME/SpacemanDMM - key: ${{ runner.os }}-spacemandmm - - - name: Install Tools - run: | - bash tools/ci/install_build_deps.sh - bash tools/ci/install_dreamchecker.sh - - - uses: actions/setup-python@v5 - with: - python-version: '3.11' - cache: 'pip' - - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: 'yarn' - cache-dependency-path: ./tgui/yarn.lock - - - run: pip install -r tools/requirements.txt - - name: Run Linters - run: | - tools/ci/check_json.sh - tgui/bin/tgui --ci - python tools/ci/check_grep2.py - python tools/ci/check_line_endings.py - python tools/ci/check_file_names.py - python tools/ci/unticked_files.py ${GITHUB_WORKSPACE} - python tools/ci/illegal_dme_files.py ${GITHUB_WORKSPACE} - python tools/ci/define_sanity.py - python tools/ci/restrict_file_types.py - python tools/ci/check_map_sizes.py - python tools/ci/verify_sql_version.py - python tools/ci/no_duplicate_definitions.py - python -m tools.ci.check_icon_conflicts - python -m tools.ci.check_icon_dupenames - python -m tools.ci.check_legacy_attack_chain - python -m tools.maplint.source --github - - - name: Setup .NET SDK - uses: actions/setup-dotnet@v4.2.0 - with: - dotnet-version: 9.x - - - name: Run DreamChecker - shell: bash - run: ~/dreamchecker 2>&1 | bash tools/ci/annotate_dm.sh - - odlint: - name: Lint with OpenDream - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - name: Setup OD - run: | - bash tools/ci/setup_od.sh - - name: Setup .NET SDK - uses: actions/setup-dotnet@v4.2.0 - with: - dotnet-version: 9.x - - name: Run OD - run: | - bash tools/ci/run_od.sh - - compile_all_maps: - name: Compile All Maps - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - name: Setup Cache - uses: actions/cache@v4 - with: - path: $HOME/BYOND - key: ${{ runner.os }}-byond - - name: Compile All Maps - run: | - tools/ci/install_byond.sh - source $HOME/BYOND/byond/bin/byondsetup - tools/ci/generate_maplist.sh - DreamMaker -DMULTIINSTANCE -DCIMAP paradise.dme - - unit_tests_and_sql: - name: Unit Tests + SQL Validation - runs-on: ubuntu-22.04 - strategy: - fail-fast: false # Let all map tests run to completion - matrix: - maptype: - [ - '/datum/map/boxstation', - '/datum/map/deltastation', - '/datum/map/metastation', - '/datum/map/cerestation', - '/datum/map/emeraldstation', - ] - byondtype: ['STABLE', 'BETA'] - services: - mariadb: - image: mariadb:latest - env: - MYSQL_ROOT_PASSWORD: root - ports: - - 3306 - options: --health-cmd "mariadb-admin ping" --health-interval 10s --health-timeout 5s --health-retries 10 - steps: - - uses: actions/checkout@v4 - - name: Setup Cache - uses: actions/cache@v4 - with: - path: $HOME/BYOND - key: ${{ runner.os }}-byond - - name: Setup & Validate DB - run: | - sudo systemctl start mysql - python3 tools/ci/generate_sql_scripts.py - tools/ci/validate_sql.sh - - name: Install RUST_G Deps - run: | - sudo dpkg --add-architecture i386 - sudo apt update || true - sudo apt install zlib1g-dev:i386 - tools/ci/install_rustg.sh - - name: Compile & Run Unit Tests - run: | - tools/ci/install_byond.sh '${{ matrix.byondtype }}' - source $HOME/BYOND/byond/bin/byondsetup - DreamMaker -DMULTIINSTANCE -DCIBUILDING paradise.dme - echo '${{ matrix.maptype }}' > data/next_map.txt - tools/ci/run_server.sh - - windows_dll_tests: - name: Windows RUSTG Validation - runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: '3.8.2' # Script was made for 3.8.2 - architecture: 'x86' # This MUST be x86 - - run: python tools/ci/validate_rustg_windows.py diff --git a/.github/workflows/devdocs.yml b/.github/workflows/devdocs.yml deleted file mode 100644 index 4baa9e38f51aa..0000000000000 --- a/.github/workflows/devdocs.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Deploy Devdocs - -on: - push: - paths: - - 'docs/**' - - 'mkdocs.yml' - -jobs: - build_and_deploy: - runs-on: ubuntu-latest - name: Build and Deploy - steps: - - uses: actions/checkout@v4 - - - name: Build docs - run: | - python -m pip install mkdocs==1.6.0 mkdocs-material[imaging]==9.5.31 mkdocs-github-admonitions-plugin==0.0.2 mkdocs-glightbox==0.4.0 - python -m mkdocs build - - - name: Deploy docs - uses: Azure/static-web-apps-deploy@1a947af9992250f3bc2e68ad0754c0b0c11566c9 - with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} - action: 'upload' - app_location: 'site' - skip_app_build: true - skip_api_build: true - env: - SKIP_DEPLOY_ON_MISSING_SECRETS: true diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index e41d1abbf6378..cba1286a306c3 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -82,7 +82,6 @@ CREATE TABLE `characters` ( `custom_emotes` LONGTEXT COLLATE 'utf8mb4_unicode_ci' DEFAULT NULL, `runechat_color` VARCHAR(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '#FFFFFF', `cyborg_brain_type` ENUM('MMI', 'Robobrain', 'Positronic') NOT NULL DEFAULT 'MMI', - `pda_ringtone` VARCHAR(16) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci', PRIMARY KEY (`id`), KEY `ckey` (`ckey`) ) ENGINE=InnoDB AUTO_INCREMENT=125467 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/SQL/updates/62-63.sql b/SQL/updates/62-63.sql deleted file mode 100644 index 83bcf50f3f038..0000000000000 --- a/SQL/updates/62-63.sql +++ /dev/null @@ -1,5 +0,0 @@ -# Updates the DB from 62 to 63 -# Adds a PDA ringtone option to character setup - -ALTER TABLE `characters` - ADD COLUMN `pda_ringtone` VARCHAR(16) NULL DEFAULT NULL AFTER `cyborg_brain_type`; diff --git a/_build_dependencies.sh b/_build_dependencies.sh deleted file mode 100644 index 480502ecd4191..0000000000000 --- a/_build_dependencies.sh +++ /dev/null @@ -1,17 +0,0 @@ -# This file has all the information on what versions of libraries are thrown into the code -# For dreamchecker -export SPACEMANDMM_TAG=suite-1.9 -# For TGUI -export NODE_VERSION=20 -# Stable Byond Major -export STABLE_BYOND_MAJOR=515 -# Stable Byond Minor -export STABLE_BYOND_MINOR=1633 -# Beta Byond Major - Uncomment and update if beta cycle active -export BETA_BYOND_MAJOR=516 -# Beta Byond Minor - Uncomment and update if beta cycle active -export BETA_BYOND_MINOR=1648 -# Python version for mapmerge and other tools -export PYTHON_VERSION=3.11.6 -# RUSTG version -export RUSTG_VERSION=v3.4.0-P diff --git a/_maps/__MAP_DEFINES.dm b/_maps/__MAP_DEFINES.dm deleted file mode 100644 index 8f55a0aea1143..0000000000000 --- a/_maps/__MAP_DEFINES.dm +++ /dev/null @@ -1,49 +0,0 @@ - -// Linkage flags - #define CROSSLINKED 2 - #define SELFLOOPING 1 - #define UNAFFECTED 0 -// Attributes (In text for the convenience of those using VV) - #define BLOCK_TELEPORT "Blocks Teleport" - // Impedes with the casting of some spells - #define IMPEDES_MAGIC "Impedes Magic" - // A level the station exists on - #define STATION_LEVEL "Station Level" - // A level affected by Code Red announcements, cargo telepads, or similar - #define STATION_CONTACT "Station Contact" - // A level dedicated to admin use - #define ADMIN_LEVEL "Admin Level" - // A level that can be navigated to by the crew without admin intervention or the emergency shuttle. - #define REACHABLE_BY_CREW "Reachable" - // For away missions - used by some consoles - #define AWAY_LEVEL "Away" - // Allows weather - #define HAS_WEATHER "Weather" - // Enhances telecomms signals - #define BOOSTS_SIGNAL "Boosts signals" - // Currently used for determining mining score - #define ORE_LEVEL "Mining" - // Levels the AI can control bots on - #define AI_OK "AI Allowed" - /// Ruins will spawn on this z-level - #define SPAWN_RUINS "Spawn Ruins" - /// A level that can be navigated to through space, but for real this time. - #define REACHABLE_SPACE_ONLY "Reachable Space Only" - /// A level used for spawning map areas in tests - #define GAME_TEST_LEVEL "Game Test Level" - -// Level names - #define MAIN_STATION "Main Station" - #define CENTCOMM "CentComm" - #define TELECOMMS "Telecomms Satellite" - #define DERELICT "Derelicted Station" - #define MINING "Lavaland" - #define EMPTY_AREA "Empty Area" - #define EMPTY_AREA_2 "Empty Area 2" - #define EMPTY_AREA_3 "Empty Area 3" - #define AWAY_MISSION "Away Mission" - -// Convenience define - #define DECLARE_LEVEL(NAME,LINKS,TRAITS) list("name" = NAME, "linkage" = LINKS, "attributes" = TRAITS) - - #define AWAY_MISSION_LIST list(DECLARE_LEVEL(AWAY_MISSION,UNAFFECTED,list(BLOCK_TELEPORT, AWAY_LEVEL))) diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm deleted file mode 100644 index 80194dd078bb3..0000000000000 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm +++ /dev/null @@ -1,2246 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/template_noop, -/area/template_noop) -"ab" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 4 - }, -/turf/simulated/wall/r_wall, -/area/ruin/powered/clownplanet) -"ac" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/turf/simulated/wall/r_wall, -/area/ruin/powered/clownplanet) -"ad" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 4 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"ae" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"af" = ( -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"ag" = ( -/obj/effect/mob_spawn/human/corpse/damaged, -/obj/effect/decal/cleanable/blood/old, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"ah" = ( -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 4 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aj" = ( -/obj/effect/decal/cleanable/pie_smudge, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"ak" = ( -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/obj/machinery/light/small{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"al" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 1 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"am" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"an" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"ao" = ( -/obj/structure/window/reinforced, -/obj/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"ap" = ( -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aq" = ( -/obj/structure/disposalpipe/trunk, -/obj/structure/disposaloutlet{ - dir = 1 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"ar" = ( -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"as" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"at" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/effect/decal/cleanable/cobweb, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"au" = ( -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"aw" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 4 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"ay" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"az" = ( -/obj/item/bikehorn, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 1 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aB" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/effect/decal/cleanable/pie_smudge, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aC" = ( -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aD" = ( -/obj/item/bikehorn, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aE" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"aF" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aG" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/small{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aI" = ( -/obj/item/bikehorn, -/obj/effect/decal/cleanable/dirt, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aJ" = ( -/obj/item/bikehorn, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aK" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/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 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"aL" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/wall/r_wall, -/area/ruin/powered/clownplanet) -"aM" = ( -/obj/effect/decal/cleanable/pie_smudge, -/obj/effect/turf_decal/tile/yellow, -/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/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aN" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"aO" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 4 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aP" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"aQ" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/structure/table, -/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/escape, -/obj/item/pen/multi, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"aR" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/structure/table, -/obj/item/flashlight/lamp/bananalamp, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"aS" = ( -/obj/effect/decal/cleanable/pie_smudge, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"aT" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/item/pickaxe, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"aU" = ( -/obj/effect/spawner/window/reinforced, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"aV" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 4 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"aW" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"aX" = ( -/obj/structure/disposalpipe/trunk{ - dir = 4 - }, -/obj/structure/disposaloutlet{ - dir = 8 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"aY" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"aZ" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/light/lavaland_air, -/area/ruin/powered/clownplanet) -"ba" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/machinery/light/small{ - dir = 4 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"bb" = ( -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/obj/machinery/light/small{ - dir = 8 - }, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"bc" = ( -/turf/simulated/floor/light/lavaland_air, -/area/ruin/powered/clownplanet) -"bd" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 1 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"be" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"bf" = ( -/turf/simulated/mineral/volcanic/clown, -/area/ruin/powered/clownplanet) -"bg" = ( -/obj/item/pickaxe, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"bh" = ( -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"bi" = ( -/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/structure/disposalpipe/segment/corner{ - dir = 4 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"bj" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"bk" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 1 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"bl" = ( -/obj/item/bikehorn, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"bm" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"bn" = ( -/obj/effect/decal/cleanable/cobweb, -/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 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"bo" = ( -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/junction{ - dir = 1 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"bp" = ( -/obj/effect/decal/cleanable/pie_smudge, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow, -/obj/structure/disposalpipe/junction/y, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"bq" = ( -/obj/machinery/disposal/delivery_chute{ - dir = 1 - }, -/obj/structure/disposalpipe/trunk, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"br" = ( -/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 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"bs" = ( -/obj/machinery/light{ - dir = 1 - }, -/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 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"bu" = ( -/obj/effect/decal/cleanable/blood/oil, -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"bv" = ( -/obj/effect/mob_spawn/human/corpse/damaged, -/obj/effect/decal/cleanable/blood/old, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"bw" = ( -/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/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"bx" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/baseturf_helper/lava/mapping_lava, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"by" = ( -/obj/structure/table/glass, -/obj/item/gun/magic/wand/slipping, -/turf/simulated/floor/carpet/lavaland_air, -/area/ruin/powered/clownplanet) -"bB" = ( -/turf/simulated/floor/mineral/bananium/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"bD" = ( -/obj/structure/mecha_wreckage/honker, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"bH" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/mineral/bananium/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"bL" = ( -/obj/item/reagent_containers/drinks/trophy/gold_cup, -/obj/structure/table/glass, -/turf/simulated/floor/carpet/lavaland_air, -/area/ruin/powered/clownplanet) -"bM" = ( -/turf/simulated/floor/carpet/lavaland_air, -/area/ruin/powered/clownplanet) -"bN" = ( -/obj/machinery/disposal/delivery_chute, -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/turf/simulated/floor/carpet/lavaland_air, -/area/ruin/powered/clownplanet) -"bO" = ( -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/floor/mineral/bananium/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"bP" = ( -/obj/structure/statue/bananium/clown, -/turf/simulated/floor/carpet/lavaland_air, -/area/ruin/powered/clownplanet) -"bQ" = ( -/obj/structure/table/glass, -/obj/item/grown/bananapeel/bluespace, -/turf/simulated/floor/carpet/lavaland_air, -/area/ruin/powered/clownplanet) -"bR" = ( -/obj/structure/table/glass, -/obj/item/clothing/shoes/magboots/clown, -/turf/simulated/floor/carpet/lavaland_air, -/area/ruin/powered/clownplanet) -"bS" = ( -/obj/item/coin/clown, -/obj/item/coin/clown, -/obj/item/coin/clown, -/obj/item/coin/clown, -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/carpet/lavaland_air, -/area/ruin/powered/clownplanet) -"bT" = ( -/obj/item/slime_extract/rainbow, -/obj/structure/table/glass, -/turf/simulated/floor/carpet/lavaland_air, -/area/ruin/powered/clownplanet) -"bU" = ( -/obj/item/bikehorn/airhorn, -/turf/simulated/floor/carpet/lavaland_air, -/area/ruin/powered/clownplanet) -"bW" = ( -/obj/item/bikehorn, -/turf/simulated/floor/mineral/bananium/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"bY" = ( -/obj/effect/mob_spawn/human/corpse/damaged, -/obj/effect/decal/cleanable/blood/old, -/turf/simulated/floor/mineral/bananium/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"bZ" = ( -/obj/machinery/door/airlock/bananium, -/turf/simulated/floor/mineral/bananium/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"ca" = ( -/obj/item/bikehorn, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/mineral/bananium/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"cc" = ( -/turf/simulated/wall/r_wall, -/area/ruin/powered/clownplanet) -"ch" = ( -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/turf/simulated/wall/r_wall, -/area/ruin/powered/clownplanet) -"cu" = ( -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/powered/clownplanet) -"dK" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/carpet/lavaland_air, -/area/ruin/powered/clownplanet) -"dL" = ( -/obj/item/coin/clown, -/obj/item/coin/clown, -/obj/item/coin/clown, -/obj/item/coin/clown, -/obj/machinery/light/small{ - dir = 4 - }, -/turf/simulated/floor/carpet/lavaland_air, -/area/ruin/powered/clownplanet) -"dM" = ( -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/mineral/bananium/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"dO" = ( -/obj/machinery/light, -/turf/simulated/floor/mineral/bananium/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"eX" = ( -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/noslip/lavaland, -/area/lavaland/surface/outdoors/explored) -"gX" = ( -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/chasm/straight_down/lava_land_surface, -/area/lavaland/surface/outdoors/explored) -"hY" = ( -/obj/machinery/light, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/powered/clownplanet) -"lY" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/turf/simulated/mineral/volcanic/clown, -/area/ruin/powered/clownplanet) -"pv" = ( -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/powered/clownplanet) -"qo" = ( -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment/corner{ - dir = 1 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"qS" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"sL" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 4 - }, -/turf/simulated/floor/light/lavaland_air, -/area/ruin/powered/clownplanet) -"ye" = ( -/turf/simulated/floor/lava/lava_land_surface, -/area/ruin/powered/clownplanet) -"CB" = ( -/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/hope, -/obj/effect/decal/cleanable/blood/old, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/noslip/lavaland, -/area/lavaland/surface/outdoors/explored) -"EG" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 1 - }, -/turf/simulated/wall/r_wall, -/area/ruin/powered/clownplanet) -"HG" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/turf/simulated/floor/light/lavaland_air, -/area/ruin/powered/clownplanet) -"HQ" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/turf/simulated/wall/r_wall, -/area/ruin/powered/clownplanet) -"KX" = ( -/obj/item/grown/bananapeel{ - color = "#2F3000"; - name = "stealth banana peel" - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors/explored) -"Lp" = ( -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/turf/simulated/floor/light/lavaland_air, -/area/ruin/powered/clownplanet) -"LH" = ( -/obj/machinery/disposal/delivery_chute{ - desc = "The following is engraved upon the chute: A FATE WORSE THAN DEATH LIES WITHIN"; - dir = 1; - name = "THE TRIAL OF HONKITUDE" - }, -/obj/structure/disposalpipe/trunk, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/noslip/lavaland, -/area/ruin/powered/clownplanet) -"Mv" = ( -/obj/effect/mapping_helpers/no_lava, -/mob/living/simple_animal/hostile/retaliate/clown, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors/explored) -"MR" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/powered/clownplanet) -"Tc" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/powered/clownplanet) -"TD" = ( -/obj/structure/disposalpipe/trunk, -/obj/structure/disposaloutlet{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/noslip/lavaland, -/area/ruin/powered/clownplanet) -"VH" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/turf/simulated/wall/r_wall, -/area/ruin/powered/clownplanet) -"WZ" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - invisibility = 101 - }, -/turf/simulated/floor/lubed/lavaland_air, -/area/ruin/powered/clownplanet) -"Xm" = ( -/obj/item/clothing/head/cone, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/noslip/lavaland, -/area/lavaland/surface/outdoors/explored) -"XO" = ( -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors/explored) -"Yf" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/powered/clownplanet) -"YI" = ( -/obj/machinery/light/small, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/noslip/lavaland, -/area/ruin/powered/clownplanet) - -(1,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -XO -XO -XO -XO -XO -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} -(2,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -cc -cc -cc -cc -cc -cc -cc -pv -XO -gX -XO -XO -gX -pv -cc -cc -cc -cc -cc -aa -aa -aa -aa -aa -aa -"} -(3,1,1) = {" -aa -aa -aa -aa -aa -cc -cc -cc -ye -ye -ye -ye -ye -cc -cc -gX -gX -KX -gX -gX -cc -cc -ye -ye -ye -cc -cc -cc -aa -aa -aa -aa -"} -(4,1,1) = {" -aa -aa -aa -aa -cc -cc -ye -ye -ye -ab -EG -ab -EG -ye -cc -cc -gX -gX -gX -cc -cc -ye -ye -aU -cu -ye -ye -cc -cc -aa -aa -aa -"} -(5,1,1) = {" -aa -aa -aa -cc -cc -ye -ye -ab -ch -VH -aH -ay -aS -EG -ye -cc -cc -cc -cc -cc -bO -bB -aU -ye -ye -ye -ye -ye -cc -cc -aa -aa -"} -(6,1,1) = {" -aa -aa -aa -cc -ye -ye -cc -at -ah -af -aI -af -qo -aL -ye -cc -bB -bH -bB -cc -bB -bH -bY -bB -aU -ye -aU -ye -ye -cc -Yf -aa -"} -(7,1,1) = {" -aa -aa -cc -cc -ye -ab -aj -ap -am -ah -af -EG -aL -aL -cc -bn -br -bB -bH -bH -bB -bH -bB -bB -bB -cc -ye -cu -ye -cc -cc -aa -"} -(8,1,1) = {" -aa -aa -cc -ye -ye -ae -af -qo -am -aL -aX -aL -aN -aY -bf -cc -bs -br -bB -cc -cc -bH -cc -bB -bB -bB -aU -ye -ye -ye -cc -aa -"} -(9,1,1) = {" -aa -aa -cc -ye -ab -af -af -ay -an -an -aL -aN -aN -aN -bg -bf -cc -cc -br -bB -bB -bH -bB -bB -ca -bH -dO -cc -ye -ye -cc -aa -"} -(10,1,1) = {" -aa -Mv -cc -ye -ac -ag -af -qo -aL -am -aL -aN -aN -aZ -bc -bh -br -br -br -bB -cc -bB -bB -bH -bH -bB -bB -ye -aU -ye -cc -cc -"} -(11,1,1) = {" -aa -hY -cc -ye -ad -ch -ak -ay -am -am -aL -aN -aT -aZ -bc -bf -cc -br -br -bB -bB -cc -bB -bB -bB -bB -bH -ye -aU -ye -ye -cc -"} -(12,1,1) = {" -aa -Mv -cc -ye -ae -af -af -az -am -ac -ap -aL -aN -ba -bh -cc -cc -br -bB -bB -cc -cc -bB -bB -cc -bB -bH -ye -cu -aU -ye -cc -"} -(13,1,1) = {" -XO -Mv -cc -ye -cc -ah -af -ap -aC -aj -af -ap -aL -aL -bi -ch -EG -cc -cc -cc -bP -bS -cc -dM -bB -bH -ca -bB -ye -aU -ye -cc -"} -(14,1,1) = {" -XO -Xm -cc -cc -ye -ac -af -af -af -af -aJ -af -ay -an -bj -al -am -cc -cc -bL -bM -bM -bM -cc -bB -bH -bH -bB -ye -aU -ye -cc -"} -(15,1,1) = {" -eX -eX -LH -ch -ch -au -af -ch -af -aF -ch -aj -af -ay -as -an -aC -qo -cc -dK -bQ -bT -bM -cc -cc -bH -bB -bB -ye -aU -ye -cc -"} -(16,1,1) = {" -eX -CB -YI -cc -ye -cu -ah -EG -ah -qo -ah -af -af -au -bk -aC -qo -bj -ch -bN -bM -bU -bM -bZ -bB -bH -bB -cc -ye -aU -ye -cc -"} -(17,1,1) = {" -eX -eX -TD -ch -ch -ch -ay -an -an -aL -an -aO -af -qo -bl -bo -ay -bx -cc -bM -bR -by -bM -cc -bB -bB -bB -bB -ye -aU -ye -cc -"} -(18,1,1) = {" -XO -eX -cc -cc -ye -cc -aO -qS -qS -WZ -WZ -WZ -qo -aC -qo -bp -EG -bv -cc -bL -bM -bM -bM -cc -bB -bB -bB -bB -ye -aU -ye -cc -"} -(19,1,1) = {" -XO -Mv -cc -ye -ye -ab -ay -am -aD -an -an -aL -ac -EG -aK -aL -bD -cc -bB -cc -bP -dL -cc -dM -bB -bH -bH -bB -ye -aU -ye -cc -"} -(20,1,1) = {" -aa -Mv -cc -ye -cc -aL -ar -an -an -am -an -aL -aV -bb -bm -aL -bu -EG -bB -bB -cc -cc -bY -bB -bB -bH -bB -ye -aU -cu -ye -cc -"} -(21,1,1) = {" -aa -hY -cc -ye -cc -aL -aw -aB -HQ -qS -HQ -aQ -Tc -HG -sL -lY -cc -aK -br -bB -bB -cc -bB -bH -bB -bB -bB -ye -aU -ye -ye -cc -"} -(22,1,1) = {" -aa -Mv -cc -ye -aq -ao -aC -HQ -aP -qS -HQ -aR -Tc -Lp -HG -bq -ch -bw -cc -bB -bB -bH -bH -bH -bB -bW -dO -cc -aU -ye -cc -cc -"} -(23,1,1) = {" -aa -aa -cc -ye -cc -cc -ar -an -an -aD -aK -aN -aW -bd -bh -bf -cc -br -br -bB -bB -bH -bH -bB -bB -cc -cc -ye -cu -ye -cc -aa -"} -(24,1,1) = {" -aa -aa -cc -ye -cc -cc -as -an -aL -an -aL -aL -aV -be -bf -cc -bs -br -bB -bB -bB -bB -bB -cc -bB -bB -ye -cu -ye -ye -cc -aa -"} -(25,1,1) = {" -aa -aa -cc -ye -ye -cc -ar -an -an -an -aC -ap -aL -cc -cc -br -br -bB -bB -bB -bH -bW -bB -bB -bB -cc -ye -aU -ye -cc -cc -aa -"} -(26,1,1) = {" -aa -aa -cc -cc -ye -cc -cc -aC -ap -aG -af -af -aE -cc -ye -cc -bO -bB -bB -cc -bB -bB -cc -bB -bB -ye -cu -ye -ye -cc -Yf -aa -"} -(27,1,1) = {" -aa -aa -aa -cc -cc -ye -ye -cc -cu -cc -aM -ar -cu -cc -ye -cc -cc -cc -cc -cc -bB -bB -bB -ye -ye -ye -ye -ye -cc -cc -aa -aa -"} -(28,1,1) = {" -aa -aa -aa -aa -cc -cc -ye -ye -ye -aU -aU -aU -cc -ye -cc -cc -gX -gX -gX -cc -cc -ye -ye -cu -aU -ye -ye -cc -cc -aa -aa -aa -"} -(29,1,1) = {" -aa -aa -aa -aa -aa -cc -cc -cc -ye -ye -ye -ye -ye -cc -cc -gX -gX -KX -gX -gX -cc -cc -ye -ye -ye -cc -cc -cc -aa -aa -aa -aa -"} -(30,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -cc -cc -cc -cc -cc -cc -cc -MR -XO -XO -XO -XO -gX -MR -cc -cc -cc -cc -cc -aa -aa -aa -aa -aa -aa -"} -(31,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -XO -gX -XO -XO -XO -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_excavation.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_excavation.dmm deleted file mode 100644 index 00d96dd74672e..0000000000000 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_excavation.dmm +++ /dev/null @@ -1,2563 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"ab" = ( -/obj/effect/mapping_helpers/turfs/rust/maybe, -/obj/effect/mapping_helpers/turfs/rust/maybe, -/turf/simulated/wall/r_wall, -/area/ruin/unpowered/althland_excavation) -"ac" = ( -/obj/effect/decal/cleanable/glass, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"ad" = ( -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"ae" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing/corner, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/turf_decal/stripes/corner, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"af" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/structure/railing, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/chasm/straight_down/lava_land_surface, -/area/lavaland/surface/outdoors) -"ag" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/structure/railing, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"ah" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/largecrate, -/obj/item/clothing/head/bomb_hood, -/obj/item/clothing/suit/bomb_suit, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"ai" = ( -/obj/structure/railing{ - dir = 6 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"aj" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"ak" = ( -/obj/structure/marker_beacon/dock_marker/collision, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"am" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"an" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/bed/pod, -/obj/item/bedsheet, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"ao" = ( -/obj/structure/table, -/obj/structure/bedsheetbin, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"ap" = ( -/obj/structure/bed/pod, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"aq" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/secure_closet/freezer/fridge/open, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"ar" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/table_frame, -/obj/item/clothing/suit/hooded/explorer, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"as" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"at" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/washing_machine, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"au" = ( -/obj/structure/bed/pod, -/obj/item/bedsheet, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"av" = ( -/obj/structure/sign/explosives/alt, -/turf/simulated/wall/r_wall, -/area/ruin/unpowered/althland_excavation) -"aw" = ( -/obj/structure/railing, -/obj/structure/railing{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"ax" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/largecrate, -/obj/item/bombcore/training{ - name = "degraded payload"; - desc = "A weathered payload core, its once vital center now shattered, rendering it indistinguishable from a mere stone." - }, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"ay" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/table_frame, -/obj/item/clothing/mask/gas/explorer, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"az" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/table, -/obj/item/clothing/mask/gas/explorer, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"aA" = ( -/obj/structure/marker_beacon/dock_marker/collision, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"aB" = ( -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/chasm/straight_down/lava_land_surface, -/area/lavaland/surface/outdoors) -"aC" = ( -/obj/structure/railing/corner{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"aE" = ( -/obj/structure/mecha_wreckage/ripley/firefighter, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"aG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/bed/pod, -/obj/item/bedsheet, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"aI" = ( -/obj/item/chair{ - dir = 1 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"aJ" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/chasm/straight_down/lava_land_surface, -/area/lavaland/surface/outdoors) -"aK" = ( -/obj/structure/sign/explosives, -/obj/effect/mapping_helpers/turfs/rust/maybe, -/turf/simulated/wall/r_wall, -/area/ruin/unpowered/althland_excavation) -"aL" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"aN" = ( -/obj/structure/railing, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/turf_decal/stripes/line, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"aQ" = ( -/obj/structure/grille, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"aR" = ( -/obj/structure/railing, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/turf_decal/stripes/line, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"aU" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"aV" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/deck/cards/black, -/obj/structure/table_frame, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"aX" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/mob/living/simple_animal/hostile/asteroid/hivelord/legion, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"aZ" = ( -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"bi" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/portable/canister/air, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"bj" = ( -/obj/structure/closet/crate/miningcar, -/obj/item/stack/ore/plasma, -/obj/item/stack/ore/plasma, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"bk" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/largecrate, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"bl" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"bm" = ( -/obj/structure/girder/reinforced, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"bn" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"bo" = ( -/obj/structure/grille/broken, -/obj/effect/decal/cleanable/glass, -/obj/item/chair, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"bq" = ( -/obj/structure/railing{ - dir = 5 - }, -/obj/structure/marker_beacon/dock_marker/collision, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"br" = ( -/obj/structure/lattice, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/chasm/straight_down/lava_land_surface, -/area/lavaland/surface/outdoors) -"bx" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"bz" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate/miningcar, -/obj/item/gibtonite, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"bA" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/portable/pump, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"bB" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery/white, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"bC" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/unary/tank/oxygen_agent_b{ - dir = 8 - }, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"bE" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/chair/office{ - dir = 4 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"bF" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"bG" = ( -/obj/structure/railing{ - dir = 10 - }, -/obj/structure/marker_beacon/dock_marker/collision, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"bH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/bed/pod, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"bJ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/glass, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"bK" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"bL" = ( -/obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/asteroid/hivelord/legion, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"bM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/shard, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"bN" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/girder/reinforced, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"bO" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/chair, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"bP" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery/white/hollow, -/obj/item/stack/sheet/wood, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"bQ" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"bR" = ( -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"bS" = ( -/obj/structure/railing/corner, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/corner, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"bT" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"bU" = ( -/obj/effect/decal/remains/human, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"bV" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing/corner{ - dir = 8 - }, -/obj/structure/railing/corner{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"cb" = ( -/obj/structure/railing/corner{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"cs" = ( -/obj/machinery/door/airlock/maintenance_hatch, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"ct" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"cR" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate/miningcar, -/obj/item/stack/ore/plasma, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"dp" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/table, -/obj/machinery/kitchen_machine/microwave, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"ej" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"eC" = ( -/obj/structure/railing/corner{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"eX" = ( -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"fc" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"fH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/obj/machinery/atmospherics/portable/scrubber, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"gg" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/girder/reinforced, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"gh" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/sheet/metal, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"gF" = ( -/obj/effect/mapping_helpers/turfs/damage, -/obj/item/stack/sheet/metal, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"hn" = ( -/obj/structure/railing, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/chasm/straight_down/lava_land_surface, -/area/lavaland/surface/outdoors) -"hL" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"ie" = ( -/obj/structure/table, -/obj/item/food/badrecipe, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"iv" = ( -/obj/structure/grille/broken, -/obj/item/shard, -/obj/effect/decal/cleanable/glass, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"iA" = ( -/obj/effect/decal/remains/human, -/obj/item/clothing/suit/hooded/explorer, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"iW" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/chair/office, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"je" = ( -/obj/structure/girder/reinforced, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"jj" = ( -/obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/asteroid/hivelord/legion, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"js" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/structure/lattice/lava, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/chasm/straight_down/lava_land_surface, -/area/lavaland/surface/outdoors) -"jL" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/item/stack/sheet/metal, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"jS" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/item/stack/sheet/metal, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"kh" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/mecha_wreckage/ripley, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"lh" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/sheet/wood, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"lF" = ( -/obj/structure/railing/corner, -/obj/structure/railing/corner{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/structure/door_assembly/door_assembly_ext, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"lM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate/trashcart, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"mh" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"mK" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"mW" = ( -/obj/structure/door_assembly/door_assembly_mhatch, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"nw" = ( -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/turfs/rust/maybe, -/turf/simulated/wall/r_wall, -/area/ruin/unpowered/althland_excavation) -"nU" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/glass, -/obj/effect/turf_decal/delivery/white, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"oh" = ( -/turf/simulated/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors/unexplored) -"or" = ( -/obj/structure/railing/corner{ - dir = 8 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"pC" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/urinal{ - pixel_y = 32 - }, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"pE" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 6 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/power/apc/off_station/empty_charge/directional/north, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"pI" = ( -/obj/item/stack/sheet/metal, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"qa" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate/miningcar, -/obj/effect/turf_decal/delivery/white/hollow, -/obj/item/gibtonite, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"qp" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/chair/office, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"qw" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/largecrate, -/obj/item/bombcore/training{ - name = "degraded payload"; - desc = "A weathered payload core, its once vital center now shattered, rendering it indistinguishable from a mere stone." - }, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"qT" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery/white/hollow, -/obj/machinery/floodlight{ - anchored = 1; - desc = "A melted floodlight, despite being completely welded into the floor, it still somehow works."; - name = "melted floodlight" - }, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"si" = ( -/obj/structure/sign/explosives/alt, -/obj/effect/mapping_helpers/turfs/rust/maybe, -/turf/simulated/wall/r_wall, -/area/ruin/unpowered/althland_excavation) -"sj" = ( -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors/unexplored) -"sA" = ( -/obj/structure/railing, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"tj" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/grille/broken, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"tV" = ( -/obj/effect/decal/remains/human, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"ub" = ( -/obj/structure/railing, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/turf_decal/stripes/line, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"ui" = ( -/obj/item/storage/toolbox/syndicate, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"uA" = ( -/obj/structure/grille, -/obj/item/shard, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"uG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"uP" = ( -/obj/item/chair{ - dir = 1 - }, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"vM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"wb" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/structure/railing, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"wi" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/reagent_containers/drinks/oilcan, -/obj/structure/machine_frame, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"wA" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"xf" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"xi" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/sheet/metal, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"xB" = ( -/obj/effect/decal/remains/human, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"yb" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"yc" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing, -/obj/effect/turf_decal/stripes/line, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"yn" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"yz" = ( -/obj/structure/railing, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"zh" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"zp" = ( -/obj/structure/railing/corner, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"zw" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/unary/tank/oxygen_agent_b{ - dir = 8 - }, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"Ay" = ( -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/chasm/straight_down/lava_land_surface, -/area/lavaland/surface/outdoors/unexplored) -"AD" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/sheet/metal, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"AU" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Bl" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/portable/canister/air, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"BW" = ( -/obj/structure/lattice/lava, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/chasm/straight_down/lava_land_surface, -/area/lavaland/surface/outdoors) -"BZ" = ( -/obj/machinery/atmospherics/binary/pump{ - dir = 8 - }, -/mob/living/simple_animal/hostile/asteroid/hivelord/legion, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"Cs" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/table_frame, -/obj/item/food/badrecipe, -/obj/item/food/badrecipe{ - pixel_y = 14; - pixel_x = 14 - }, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"CS" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"Ds" = ( -/obj/structure/railing, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Du" = ( -/obj/structure/door_assembly/door_assembly_mhatch, -/turf/simulated/floor/pod, -/area/ruin/unpowered/althland_excavation) -"DS" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"Ec" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/chair{ - dir = 1 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"Ei" = ( -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"Es" = ( -/obj/structure/lattice/catwalk/mining, -/obj/effect/mapping_helpers/no_lava, -/obj/structure/ladder, -/turf/simulated/floor/chasm, -/area/lavaland/surface/outdoors) -"Et" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/structure/door_assembly/door_assembly_ext, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"EG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/asteroid/hivelord/legion, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"EL" = ( -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"Fe" = ( -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/althland_excavation) -"Fs" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/door_assembly/door_assembly_ext, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"FQ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"Gc" = ( -/obj/structure/marker_beacon/dock_marker, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Gp" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery/white/hollow, -/mob/living/simple_animal/hostile/asteroid/hivelord/legion, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"GE" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"HC" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/chair/office, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"In" = ( -/obj/structure/railing, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"IZ" = ( -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"Jn" = ( -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors/unexplored) -"Jp" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/manifold/hidden, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"JF" = ( -/obj/structure/railing/corner, -/obj/structure/railing/corner{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"JG" = ( -/obj/structure/girder/reinforced, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"KU" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"Lt" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/maintenance_hatch, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"Lz" = ( -/obj/effect/decal/cleanable/glass, -/obj/effect/decal/cleanable/dirt, -/obj/structure/table_frame, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"LK" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/item/stack/sheet/metal, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"Mm" = ( -/obj/structure/girder/reinforced, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors/unexplored) -"MT" = ( -/obj/structure/grille/broken, -/obj/effect/decal/cleanable/glass, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Nv" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"Ow" = ( -/obj/item/shard, -/obj/effect/mapping_helpers/no_lava, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"OE" = ( -/obj/structure/railing{ - dir = 9 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"OX" = ( -/obj/structure/table_frame, -/obj/item/food/badrecipe, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"Pe" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/toilet{ - dir = 4 - }, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"PC" = ( -/obj/structure/railing{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"PL" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"PM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Qk" = ( -/obj/effect/decal/cleanable/glass, -/obj/structure/chair/office{ - dir = 1 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"QM" = ( -/obj/structure/railing{ - dir = 6 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"QS" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/sheet/metal, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"Rf" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/baseturf_helper/lava/mapping_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"Ri" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/unary/portables_connector{ - dir = 4 - }, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"RG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/obj/structure/grille/broken, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"RW" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"SV" = ( -/obj/structure/girder/reinforced, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"TD" = ( -/obj/structure/girder/reinforced, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"TJ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"TN" = ( -/obj/effect/mapping_helpers/turfs/rust/maybe, -/turf/simulated/wall/r_wall, -/area/ruin/unpowered/althland_excavation) -"TP" = ( -/obj/structure/railing/corner{ - dir = 8 - }, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"TW" = ( -/obj/structure/railing/corner{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"UR" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"US" = ( -/obj/structure/grille/broken, -/obj/item/shard, -/obj/effect/decal/cleanable/glass, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"Vg" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/door_assembly/door_assembly_mhatch, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"Vk" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing/corner{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Vw" = ( -/obj/structure/grille/broken, -/obj/item/shard, -/obj/effect/decal/cleanable/glass, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"VO" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Wt" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/grille, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"WH" = ( -/obj/machinery/door/poddoor/multi_tile/three_tile_hor, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/althland_excavation) -"Xl" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"Xp" = ( -/obj/structure/noticeboard{ - pixel_y = 28 - }, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_excavation) -"XS" = ( -/obj/effect/mapping_helpers/turfs/rust/maybe, -/turf/simulated/wall/r_wall, -/area/lavaland/surface/outdoors) -"Ya" = ( -/obj/structure/railing, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"Yz" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/urinal{ - pixel_y = 32 - }, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"YE" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/mecha_wreckage/ripley, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) -"Zr" = ( -/obj/structure/marker_beacon/dock_marker, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/lavaland/surface/outdoors) -"Zy" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/door_assembly/door_assembly_ext, -/turf/simulated/floor/pod/light/lavaland_air{ - oxygen = 0; - nitrogen = 0 - }, -/area/ruin/unpowered/althland_excavation) - -(1,1,1) = {" -oh -oh -oh -oh -oh -oh -oh -oh -oh -sj -sj -sj -sj -sj -Jn -Jn -Jn -Jn -Jn -Jn -Jn -Jn -Jn -Jn -sj -sj -oh -oh -oh -oh -"} -(2,1,1) = {" -oh -oh -oh -oh -sj -sj -sj -sj -sj -sj -sj -TN -TN -TN -pI -JG -Du -TN -TN -TN -Jn -Jn -Jn -Jn -Jn -Jn -Jn -oh -oh -oh -"} -(3,1,1) = {" -oh -oh -sj -sj -sj -sj -TN -TN -TN -TN -TN -TN -Xl -Et -ad -xf -eX -Fs -ct -ab -TN -TN -TN -TN -Jn -Jn -Jn -Jn -oh -oh -"} -(4,1,1) = {" -oh -sj -sj -sj -TN -TN -TN -bK -PL -yb -bO -nw -gh -TN -Wt -RG -tj -TN -Zy -TN -aq -dp -Cs -TN -TN -TN -Jn -Jn -sj -sj -"} -(5,1,1) = {" -oh -sj -sj -TN -TN -aU -Lt -am -iW -OX -Rf -PL -yb -aX -IZ -Ec -EL -yb -bL -yb -uP -PL -ct -je -Ei -TN -TN -Jn -sj -sj -"} -(6,1,1) = {" -sj -sj -TN -TN -Ri -bl -TN -Nv -bl -ct -IZ -qp -Lz -PL -bU -aU -Nv -PL -ie -Qk -bK -US -yb -TN -Ei -Ei -bm -Mm -sj -sj -"} -(7,1,1) = {" -sj -sj -TN -PL -BZ -fH -ab -TN -AD -TN -uA -Vw -aQ -iv -av -lF -aK -bo -aQ -uA -MT -TN -mW -TN -Ei -Ei -Ei -Mm -sj -sj -"} -(8,1,1) = {" -sj -TN -TN -pE -Jp -bA -TN -mK -ae -TN -Ei -Ei -Ei -BW -ak -ag -mh -BW -Ow -BW -Ei -TN -Ei -Ei -Ei -Ei -bm -Jn -sj -sj -"} -(9,1,1) = {" -sj -TN -TN -bC -zw -TN -TN -mK -yc -aA -Ei -aB -aB -aB -BW -af -aB -aB -aB -aB -aA -TD -XS -Ei -zp -XS -BW -Ay -sj -sj -"} -(10,1,1) = {" -sj -TN -TN -TN -TN -TN -mK -bS -ai -aB -aB -aB -aB -aB -aB -wb -aB -aB -aB -aB -aB -Ei -SV -aC -sA -aB -aB -Jn -Mm -Jn -"} -(11,1,1) = {" -sj -TN -ct -Pe -je -PM -yn -yz -BW -aB -aB -aB -aB -aB -aB -js -aB -aB -aB -aB -aB -aB -aB -GE -aB -aB -Ei -Jn -Mm -Jn -"} -(12,1,1) = {" -sj -TN -pC -yb -gF -mh -mK -ub -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aB -aL -In -aB -Ei -Ei -TN -Jn -"} -(13,1,1) = {" -Jn -TN -TN -TN -TN -VO -mK -aB -aB -aB -aB -aB -aB -aB -aB -sA -BW -aB -aB -aB -aB -aB -aB -BW -Ds -Ei -Ei -Ei -TN -sj -"} -(14,1,1) = {" -Jn -TN -aU -PL -TN -mh -aB -hn -aB -aB -aB -aB -aB -aB -aB -hn -aB -aB -aB -aB -aB -aB -aB -aL -or -XS -Ei -Ei -TN -sj -"} -(15,1,1) = {" -Jn -TN -Yz -yb -Vg -yn -aB -Ya -aB -aB -aB -aB -aB -aB -BW -TP -bG -aB -aB -aB -aB -aB -XS -eC -Ei -Ei -Ei -Ei -TN -sj -"} -(16,1,1) = {" -Jn -TN -TN -TN -TN -bT -TW -aR -aB -aB -aB -aB -aB -aB -aZ -Es -xB -BW -aB -aB -aB -aB -aj -Ei -Ei -Ei -BW -aB -TN -sj -"} -(17,1,1) = {" -Jn -TN -Ei -Ei -Ei -CS -bF -Ya -aB -aB -aB -aB -aB -aB -bq -JF -QM -aB -aB -BW -BW -aA -AU -Gc -uG -mK -uG -BW -TN -sj -"} -(18,1,1) = {" -Jn -bm -Ei -BW -Ei -aB -aB -yz -aB -aB -aB -aB -aB -aB -aB -aw -BW -aB -aB -aB -aB -BW -aJ -fc -mK -BW -LK -PM -TN -sj -"} -(19,1,1) = {" -Jn -bm -Ei -BW -aB -aB -aL -aN -aB -aB -aB -aB -aB -aB -aB -bQ -aB -aB -aB -aB -aB -aB -aB -FQ -aB -aB -BW -KU -TN -sj -"} -(20,1,1) = {" -Jn -TN -Ei -bm -BW -aB -aj -aB -aB -aB -aB -aB -aB -aB -BW -aw -aB -aB -aB -aB -aB -aB -bx -mh -mh -aB -aB -uG -TN -sj -"} -(21,1,1) = {" -Jn -TN -TN -TN -TN -TN -Vk -aN -BW -aB -aB -aB -aB -aB -aB -sA -aB -aB -aB -aB -aB -BW -wA -fc -uG -aB -aB -aB -TN -sj -"} -(22,1,1) = {" -Jn -TN -ao -ar -ay -TN -zh -ub -aA -BW -aB -aB -BW -aB -aB -aw -aB -aB -aB -aB -aB -BW -UR -PM -xi -BW -TJ -BW -TN -sj -"} -(23,1,1) = {" -Jn -TN -at -bl -Nv -SV -hL -yz -Ei -Ei -aB -BW -BW -aB -aB -PM -aB -aB -BW -BW -aB -aB -aB -mK -br -mh -mK -uG -TN -sj -"} -(24,1,1) = {" -Jn -TN -aG -aU -PL -TN -mW -TN -TN -Ei -Ei -Ei -BW -aB -BW -wb -ak -aB -aB -BW -BW -OE -cb -Zr -mh -mh -mh -Gc -TN -sj -"} -(25,1,1) = {" -sj -TN -TN -bU -RW -aI -Xl -vM -TN -gg -SV -TN -aQ -uA -aK -bV -si -aQ -iv -TN -PC -cb -TD -TN -TN -gg -bN -TN -TN -sj -"} -(26,1,1) = {" -sj -sj -TN -az -DS -bL -RW -bl -PL -yb -bE -TN -ac -bJ -ct -Nv -Rf -bM -Bl -TN -bR -VO -WH -wi -jL -Nv -jS -TN -sj -sj -"} -(27,1,1) = {" -oh -sj -TN -TN -ap -aU -RW -HC -aV -DS -ct -QS -bB -bk -EL -as -bn -ad -nU -cs -mh -Ei -Fe -ui -bL -YE -TN -TN -sj -sj -"} -(28,1,1) = {" -oh -sj -sj -TN -TN -iA -au -aU -bO -jj -PL -TN -Xp -Gp -bP -eX -ax -lh -PL -je -tV -Ei -Fe -kh -aE -TN -TN -sj -sj -oh -"} -(29,1,1) = {" -oh -sj -sj -sj -TN -TN -TN -bH -bK -aG -an -TN -bi -Nv -bl -EG -as -ej -lM -TN -Ei -Ei -TN -TN -TN -TN -sj -sj -oh -oh -"} -(30,1,1) = {" -oh -oh -sj -sj -sj -sj -TN -TN -TN -TN -TN -TN -bj -qw -bz -qT -ah -qa -cR -TN -TN -TN -TN -TN -sj -sj -sj -oh -oh -oh -"} -(31,1,1) = {" -oh -oh -oh -sj -sj -sj -sj -sj -sj -sj -sj -TN -TN -TN -TN -TN -TN -TN -TN -TN -sj -sj -sj -sj -sj -oh -oh -oh -oh -oh -"} diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_facility.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_facility.dmm deleted file mode 100644 index 507ea8eb1d472..0000000000000 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_facility.dmm +++ /dev/null @@ -1,2822 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/obj/effect/mapping_helpers/turfs/burn, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"ab" = ( -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"ae" = ( -/obj/structure/window/reinforced, -/obj/machinery/conveyor/west, -/obj/item/stack/ore/bluespace_crystal{ - pixel_x = 5; - pixel_y = 3 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"af" = ( -/obj/structure/lattice/lava, -/turf/simulated/floor/lava/mapping_lava, -/area/lavaland/surface/outdoors) -"ap" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/disposalpipe/broken{ - dir = 8 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"au" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/computer/nonfunctional, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"aJ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/ore{ - pixel_y = -9; - pixel_x = -6 - }, -/obj/effect/mapping_helpers/turfs/burn, -/obj/structure/disposalpipe/segment/corner{ - dir = 1 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"aM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"bc" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/mecha_wreckage/ripley, -/obj/effect/turf_decal/box/white, -/obj/effect/turf_decal/caution/stand_clear/white, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"be" = ( -/obj/effect/mapping_helpers/turfs/rust, -/turf/simulated/wall/r_wall, -/area/lavaland/surface/outdoors) -"bL" = ( -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) -"bO" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/clothing/under/rank/cargo/miner, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"bP" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/door_assembly/door_assembly_ext{ - name = "Broken External Airlock" - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"bT" = ( -/turf/simulated/floor/lava/mapping_lava, -/area/lavaland/surface/outdoors) -"bU" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) -"bV" = ( -/turf/simulated/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) -"cb" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"cc" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"cw" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/power/smes, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"cJ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/mech_bay_recharge_port, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"cM" = ( -/obj/effect/mapping_helpers/no_lava, -/turf/template_noop, -/area/lavaland/surface/outdoors/unexplored) -"dh" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/disposalpipe/segment/corner{ - dir = 1 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"dq" = ( -/obj/effect/mapping_helpers/turfs/rust/maybe, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/wall/r_wall, -/area/lavaland/surface/outdoors) -"du" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/machinery/light_construct/small{ - dir = 4 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"eH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/ore/plasma, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"eV" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/computer/nonfunctional, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"fc" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"fd" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light_construct/small, -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"fm" = ( -/obj/machinery/light_construct/small{ - dir = 1 - }, -/obj/structure/sign/atmosplaque{ - desc = "A ruined and partially melted plaque bears words that are now faded and rusted, with some letters missing entirely. It reads: Est...ished by the Althland Mining...ration. In recog...on of the brave...who dared...harness...fiery heart...this world. May the...of our labor...shine as brightly...as the molten rivers...beneath our feet. The date of the facility's establishment at the bottom is obliterated, and the signatures of any founding miners are completely lost to time."; - pixel_y = 29; - name = "\improper Althland facility plaque" - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"fs" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate/secure/loot, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"fv" = ( -/mob/living/simple_animal/hostile/asteroid/hivelord/legion, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"fB" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"fH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/unary/portables_connector{ - dir = 4 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"fP" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"fY" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"gb" = ( -/obj/effect/mapping_helpers/turfs/damage, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"gw" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"gE" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"gF" = ( -/obj/structure/girder, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"hc" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/turfs/rust/maybe, -/turf/simulated/wall/r_wall, -/area/ruin/unpowered/althland_processing) -"hj" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"ho" = ( -/obj/structure/door_assembly/door_assembly_ext{ - name = "Broken External Airlock" - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"hx" = ( -/obj/item/shard, -/obj/structure/grille/broken, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"hE" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/binary/pump{ - dir = 8 - }, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"hI" = ( -/obj/effect/mapping_helpers/turfs/rust/maybe, -/turf/simulated/wall/r_wall, -/area/lavaland/surface/outdoors) -"hP" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/window/reinforced, -/obj/machinery/conveyor/west, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"hY" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/disposalpipe/segment, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"ia" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/disposalpipe/broken{ - dir = 1 - }, -/obj/structure/disposalpipe/broken, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"ic" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/maintenance_hatch, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"iq" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/window/reinforced, -/obj/machinery/conveyor/west, -/obj/machinery/mineral/unloading_machine, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"jb" = ( -/obj/structure/lattice/catwalk/mining, -/obj/structure/railing{ - dir = 4 - }, -/turf/simulated/floor/lava/mapping_lava, -/area/lavaland/surface/outdoors) -"jY" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery/white/hollow, -/obj/item/stack/sheet/mineral/gold{ - pixel_x = -8; - pixel_y = 8 - }, -/obj/machinery/light_construct/small{ - dir = 8 - }, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"kn" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/obj/structure/sign/poster/official/air2{ - pixel_y = -32 - }, -/obj/item/clothing/under/rank/cargo/miner, -/mob/living/simple_animal/hostile/asteroid/hivelord/legion, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"kR" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate, -/obj/item/tank/internals/oxygen, -/obj/item/storage/box/donkpockets/empty, -/obj/item/storage/box/donkpockets/empty, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"lZ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/door_assembly/door_assembly_ext{ - name = "Broken External Airlock" - }, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"mv" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 1 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"nj" = ( -/obj/structure/grille, -/obj/item/shard, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"nm" = ( -/obj/structure/disposalpipe/broken{ - dir = 2 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"no" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"nK" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/grille/broken, -/obj/item/shard, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"nN" = ( -/obj/structure/grille/broken, -/obj/item/shard, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/glass, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"nQ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery/white/hollow, -/obj/structure/ore_box, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"oj" = ( -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"oG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"pn" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/obj/item/mounted/frame/apc_frame{ - pixel_x = -3; - pixel_y = 28 - }, -/obj/item/clothing/under/rank/cargo/miner, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"pP" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/decal/cleanable/glass, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"pQ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"qh" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/disposalpipe/broken{ - dir = 4 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"qn" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/decal/cleanable/glass, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"qQ" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/disposalpipe/broken{ - dir = 1 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"rd" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 9 - }, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"rf" = ( -/obj/structure/door_assembly/door_assembly_ext{ - name = "Broken External Airlock" - }, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"rw" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/burn, -/obj/effect/mapping_helpers/turfs/damage, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"rY" = ( -/obj/effect/decal/remains/human, -/obj/item/clothing/under/rank/cargo/miner, -/obj/item/paper/fluff/ruins/althland/journal, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"sa" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/conveyor/west, -/obj/structure/window/reinforced, -/obj/item/stack/sheet/mineral/silver, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"sg" = ( -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"su" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/sheet/metal{ - amount = 5 - }, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"sB" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/disposalpipe/trunk, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"sQ" = ( -/obj/item/pickaxe, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"to" = ( -/obj/structure/marker_beacon/dock_marker, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"tv" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/machine_frame, -/obj/item/stack/cable_coil, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"tD" = ( -/obj/effect/turf_decal/delivery/white/hollow, -/obj/machinery/light_construct/small, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"tH" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"tS" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/effect/mapping_helpers/no_lava, -/obj/structure/disposalpipe/broken{ - dir = 4 - }, -/obj/structure/disposalpipe/broken{ - dir = 8 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"ua" = ( -/obj/effect/turf_decal/caution/stand_clear/white, -/obj/effect/turf_decal/box/white, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"ub" = ( -/obj/item/clothing/under/rank/cargo/miner, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"uf" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"ui" = ( -/obj/effect/mapping_helpers/turfs/rust/maybe, -/turf/simulated/wall/r_wall, -/area/ruin/unpowered/althland_processing) -"um" = ( -/obj/effect/mapping_helpers/turfs/rust, -/turf/simulated/wall/r_wall, -/area/ruin/unpowered/althland_processing) -"uC" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"uM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/rack_parts, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"vf" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/sign/poster/official/air1{ - pixel_x = 33 - }, -/obj/machinery/atmospherics/portable/canister/air, -/obj/effect/mapping_helpers/turfs/burn, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"vl" = ( -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/storage/belt/mining/alt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"vo" = ( -/obj/machinery/light_construct/small{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/obj/item/clothing/under/rank/cargo/miner, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"vM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"wZ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"xK" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/machinery/economy/vending/chinese, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"yh" = ( -/turf/template_noop, -/area/lavaland/surface/outdoors/unexplored) -"zd" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/window/reinforced, -/obj/machinery/conveyor/west, -/obj/machinery/light_construct/small{ - dir = 1 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"zp" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/clothing/shoes/workboots/mining, -/obj/structure/sign/poster/ripped{ - pixel_x = -1; - pixel_y = 32 - }, -/obj/machinery/light_construct/small{ - dir = 8 - }, -/obj/effect/mapping_helpers/turfs/burn, -/mob/living/simple_animal/hostile/asteroid/hivelord/legion, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"zv" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/window/reinforced, -/obj/machinery/conveyor/west, -/obj/effect/baseturf_helper/lava/mapping_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"zE" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/pickaxe, -/obj/effect/mapping_helpers/turfs/damage, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"zG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/bed, -/obj/machinery/light_construct/small{ - dir = 8 - }, -/obj/effect/mapping_helpers/turfs/damage, -/mob/living/simple_animal/hostile/asteroid/hivelord/legion, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"zO" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/decal/cleanable/glass, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"zR" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/door_assembly/door_assembly_mhatch, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"zZ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/conveyor/west, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Au" = ( -/turf/simulated/wall/r_wall, -/area/ruin/unpowered/althland_processing) -"Az" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/structure/door_assembly/door_assembly_mhatch, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"AE" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/power/terminal{ - dir = 8 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"AH" = ( -/obj/effect/mapping_helpers/turfs/burn, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"AL" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"BB" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/portable/pump, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"BG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/decal/cleanable/glass, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"BM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/burn, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"BV" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"BX" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/obj/structure/sign/poster/contraband/syndicate_recruitment{ - pixel_x = -3; - pixel_y = 31 - }, -/obj/item/clothing/under/rank/cargo/miner, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"CF" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/sign/electricshock{ - pixel_x = -31 - }, -/obj/machinery/light_construct/small{ - dir = 8 - }, -/obj/machinery/economy/vending/assist/free, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Dd" = ( -/obj/structure/grille/broken, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Dg" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/effect/mapping_helpers/no_lava, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"Dp" = ( -/obj/machinery/disposal, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Dt" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/storage/box/donkpockets/empty, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Dv" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/door_assembly/door_assembly_mhatch, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Dz" = ( -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"DM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/turfs/damage, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Ec" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/conveyor/southwest{ - dir = 5 - }, -/obj/machinery/mineral/processing_unit, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Ek" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/machinery/light_construct/small{ - dir = 8 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"Es" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/ore/plasma, -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/obj/effect/mapping_helpers/turfs/burn, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Fa" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Fd" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/sign/poster/ripped{ - pixel_x = -1; - pixel_y = 32 - }, -/obj/item/tank/internals/oxygen, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"FW" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery/white/partial, -/obj/machinery/light_construct/small{ - dir = 8 - }, -/obj/effect/decal/cleanable/glass, -/obj/structure/disposalpipe/segment/corner{ - dir = 4 - }, -/obj/machinery/mineral/processing_unit_console{ - pixel_y = -2; - pixel_x = -29 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"FX" = ( -/obj/structure/disposalpipe/broken{ - dir = 4 - }, -/obj/structure/disposalpipe/broken{ - dir = 8 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Ge" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/burn, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Gk" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/remains/human, -/obj/item/clothing/under/rank/cargo/miner, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Gt" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"GF" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"GV" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/girder, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Hj" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"Hs" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/baseturf_helper/lava/mapping_lava, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Hx" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/asteroid/hivelord/legion, -/obj/machinery/atmospherics/pipe/simple/hidden, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Hz" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/baseturf_helper/lava/mapping_lava, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"HO" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/hidden, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Ic" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery/white/hollow, -/obj/structure/closet/crate/miningcar, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"In" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/burn, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Io" = ( -/obj/item/chair, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"IT" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery/white/hollow, -/obj/structure/ore_box, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Jw" = ( -/obj/structure/table, -/obj/item/reagent_containers/drinks/bottle/beer{ - pixel_x = 8; - pixel_y = 10 - }, -/obj/item/reagent_containers/drinks/bottle/beer, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"JE" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/mech_bay_recharge_port, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"JJ" = ( -/obj/effect/mapping_helpers/lava_magnet, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"JT" = ( -/obj/structure/grille, -/obj/item/shard, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"KJ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/burn, -/obj/effect/mapping_helpers/turfs/damage, -/obj/machinery/atmospherics/portable/scrubber, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"KN" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/obj/effect/mapping_helpers/turfs/rust/maybe, -/turf/simulated/wall/r_wall, -/area/ruin/unpowered/althland_processing) -"KT" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"KZ" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/effect/mapping_helpers/no_lava, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"Lg" = ( -/obj/machinery/door/airlock/maintenance_hatch, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Ln" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery/white/hollow, -/obj/structure/closet/crate/miningcar, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Lq" = ( -/obj/machinery/light_construct/small{ - dir = 4 - }, -/obj/effect/mapping_helpers/turfs/burn, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"LA" = ( -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Ms" = ( -/obj/structure/girder, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Mu" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Mw" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate/secure/loot, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"MO" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/asteroid/hivelord/legion, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"MY" = ( -/obj/effect/mapping_helpers/turfs/burn, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Og" = ( -/obj/structure/girder, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Oh" = ( -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/paper/fluff/ruins/althland/journal, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"OJ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/burn, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"OW" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/t_scanner/adv_mining_scanner, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Pn" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/turfs/burn, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Po" = ( -/obj/structure/grille/broken, -/obj/item/shard, -/obj/item/shard, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Px" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/door_assembly/door_assembly_ext{ - name = "Broken External Airlock" - }, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"PF" = ( -/obj/structure/grille/broken, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"PY" = ( -/obj/structure/marker_beacon/dock_marker, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Qj" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate, -/obj/item/clothing/mask/gas/explorer, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Qu" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/door_assembly/door_assembly_ext{ - name = "Broken External Airlock" - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"RL" = ( -/obj/item/stack/sheet/metal{ - amount = 5 - }, -/obj/effect/mapping_helpers/turfs/burn, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"RX" = ( -/obj/structure/lattice/catwalk/mining, -/obj/structure/railing{ - dir = 8 - }, -/turf/simulated/floor/lava/mapping_lava, -/area/lavaland/surface/outdoors) -"Ta" = ( -/obj/item/chair{ - dir = 1 - }, -/obj/structure/sign/poster/contraband/red_rum{ - pixel_y = 31 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Tn" = ( -/obj/effect/mapping_helpers/turfs/rust, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/wall/r_wall, -/area/lavaland/surface/outdoors) -"TN" = ( -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"TX" = ( -/obj/structure/disposalpipe/broken{ - dir = 2 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Uq" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"UP" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/burn, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Vj" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/disposalpipe/segment{ - dir = 4; - invisibility = 101 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"VA" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"VJ" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/sign/nosmoking_1{ - pixel_x = -2; - pixel_y = 35 - }, -/obj/structure/disposalpipe/broken{ - dir = 4 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"VO" = ( -/obj/machinery/economy/vending/cigarette, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Wb" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate, -/obj/item/clothing/shoes/workboots/mining, -/obj/item/clothing/shoes/workboots/mining, -/obj/effect/mapping_helpers/turfs/damage, -/obj/item/mounted/frame/apc_frame{ - pixel_x = -3; - pixel_y = 28 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Wl" = ( -/obj/structure/grille, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Wp" = ( -/obj/structure/grille/broken, -/obj/item/shard, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/burn, -/obj/effect/decal/cleanable/glass, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"WQ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate/miningcar, -/obj/item/mounted/frame/apc_frame{ - pixel_x = -3; - pixel_y = 28 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"WU" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/effect/baseturf_helper/lava/mapping_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"Xn" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/effect/mapping_helpers/no_lava, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) -"Xw" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/computer/nonfunctional, -/obj/item/paper/fluff/ruins/althland/geology, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"XD" = ( -/obj/effect/decal/remains/human, -/obj/item/clothing/under/rank/cargo/miner, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"XO" = ( -/obj/item/shard, -/obj/effect/decal/cleanable/dirt, -/obj/structure/grille/broken, -/obj/effect/mapping_helpers/turfs/damage, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"XT" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light_construct/small, -/obj/effect/mapping_helpers/turfs/burn, -/obj/effect/mapping_helpers/turfs/damage, -/obj/machinery/atmospherics/pipe/manifold/hidden, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Yd" = ( -/obj/structure/grille, -/obj/item/shard, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Yl" = ( -/obj/structure/girder, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Yt" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/portable/canister/air, -/obj/machinery/light_construct/small{ - dir = 4 - }, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Yx" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/unary/tank/oxygen_agent_b, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"YF" = ( -/obj/machinery/power/terminal{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"YK" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plasteel/lavaland_air, -/area/ruin/unpowered/althland_processing) -"YN" = ( -/obj/structure/grille/broken, -/obj/item/shard, -/obj/effect/decal/cleanable/glass, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) -"Zi" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/burn, -/obj/effect/mapping_helpers/turfs/damage, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"Zr" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/disposalpipe/broken{ - dir = 2 - }, -/obj/structure/disposalpipe/broken{ - dir = 1 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"ZA" = ( -/obj/structure/grille, -/obj/item/shard, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"ZB" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/effect/mapping_helpers/no_lava, -/obj/structure/disposalpipe/segment/corner{ - dir = 2 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"ZG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/turfs/burn, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) -"ZN" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery/white, -/obj/structure/sign/poster/ripped{ - pixel_x = -1; - pixel_y = 32 - }, -/turf/simulated/floor/plating/lavaland_air, -/area/ruin/unpowered/althland_processing) - -(1,1,1) = {" -bV -bL -bL -bL -bL -bV -bV -bV -bV -yh -yh -yh -yh -yh -yh -yh -yh -yh -yh -yh -yh -yh -yh -yh -yh -yh -yh -yh -yh -bL -bL -bL -bL -bL -"} -(2,1,1) = {" -bV -bL -bL -bV -bV -bV -bV -ab -ab -yh -yh -yh -yh -ab -yh -yh -yh -yh -yh -yh -yh -yh -ab -GF -ab -ab -ab -bL -bV -bV -bV -bV -bL -bL -"} -(3,1,1) = {" -bV -bL -bV -bV -bV -bV -bV -bT -ab -bL -bL -bU -ab -KZ -ab -yh -bT -yh -yh -ab -ab -ab -YN -YN -Yd -Dd -af -bT -bV -bV -bV -bV -bV -bL -"} -(4,1,1) = {" -bV -bL -bL -ab -ab -bT -bT -bT -ab -ab -ab -cb -ab -ab -ab -bT -bT -yh -yh -bL -ab -Dg -rf -Lq -MY -Yd -af -bT -bT -bT -ab -bV -bV -bL -"} -(5,1,1) = {" -bV -bL -bL -ab -ab -bT -bT -sB -fP -dh -ui -ui -ui -ui -ui -bT -bT -yh -ab -bL -ab -ab -ui -ui -cc -ui -Au -ui -ui -ui -ab -ab -bV -bL -"} -(6,1,1) = {" -bV -bL -bV -bV -ab -bT -ab -bL -bL -tS -ui -nQ -jY -IT -ui -ab -bT -bT -bT -ab -ab -ab -ui -JE -KT -cJ -CF -tv -cw -ui -ab -ab -ab -bL -"} -(7,1,1) = {" -bV -bL -bV -bV -ab -bT -bT -bU -bU -ZB -hc -Pn -fv -aJ -ui -ab -ab -bT -bT -be -ab -ab -ui -ua -gE -bc -Zi -AE -YF -ui -ab -ab -bL -bL -"} -(8,1,1) = {" -bV -bL -bV -ab -ab -bT -bL -Xn -KZ -ab -ui -ui -ui -Lg -ui -ab -ab -RX -RX -RX -ab -ab -ui -eV -OJ -Mw -Qj -fs -OW -ui -ab -ab -bV -bL -"} -(9,1,1) = {" -bV -bL -bV -ab -bT -bT -ab -cb -ab -af -ui -Ec -FW -gw -ui -ab -ab -jb -jb -jb -ab -ab -ui -ui -af -BM -Hz -bO -In -GV -ab -ab -ab -bL -"} -(10,1,1) = {" -bV -bL -ab -bT -bT -bT -ab -cb -bT -af -af -hP -zE -ui -ui -ui -ab -be -bT -bT -ab -ab -ab -af -af -Au -Wb -kR -fc -gF -ab -ab -bL -bL -"} -(11,1,1) = {" -bV -bL -ab -af -dq -bT -ab -ab -bT -bT -XO -sa -FX -nm -Gt -DM -ia -fP -qQ -bT -bT -bT -bT -bT -bT -af -TX -rw -mv -ui -bT -ab -bV -bL -"} -(12,1,1) = {" -bV -bU -cb -bT -af -bT -ab -bT -bT -bT -JT -zZ -qn -ui -ui -ui -VJ -ab -ab -bT -bT -bT -bT -af -ui -bT -af -uM -gb -ui -bT -bT -bV -bL -"} -(13,1,1) = {" -bV -bU -cb -ab -bT -bT -ab -bT -bT -bT -ui -zv -UP -Ic -ui -ab -fB -Qu -ab -bT -bT -af -Tn -af -ui -vf -Yt -uC -tH -ui -bT -bT -ab -bL -"} -(14,1,1) = {" -bV -bL -ab -ab -bT -bT -ab -ab -bT -bT -ui -ae -Ge -tD -ui -ab -fB -cb -ab -ab -bT -bT -bT -bT -um -um -ui -ui -zR -ui -bT -bT -ab -bL -"} -(15,1,1) = {" -bV -yh -yh -yh -bT -bT -bL -cb -ab -bT -ui -zd -aM -Ln -ui -cb -fB -ab -ab -ab -ab -bT -bT -bT -bT -ui -au -In -fH -ui -bT -ab -ab -bL -"} -(16,1,1) = {" -yh -yh -yh -yh -bT -bT -ab -KZ -cb -bT -ui -iq -MO -eH -ui -ab -ap -ab -ab -ab -ab -bT -bT -bT -bT -ui -Xw -fc -hE -ui -bT -bT -ab -bL -"} -(17,1,1) = {" -yh -yh -yh -yh -bT -bT -ab -bU -bU -ab -ui -ZN -Vj -sQ -ui -ab -ab -JJ -ab -cb -ab -ab -bT -bT -bT -ui -Yx -HO -XT -ui -bT -bT -ab -bL -"} -(18,1,1) = {" -yh -yh -yh -yh -bT -bT -ab -bL -bU -ab -ui -cc -Vj -kn -ui -ab -ab -ab -WU -ab -ab -ab -bT -bT -bT -ui -Yx -Hx -rd -af -bT -ab -yh -yh -"} -(19,1,1) = {" -bV -yh -yh -yh -bT -bT -ab -ab -cb -ab -Au -WQ -Es -fd -ui -ab -qh -ab -ab -ab -ab -ab -bT -bT -bT -ui -BB -KJ -af -bT -bT -hI -yh -yh -"} -(20,1,1) = {" -bV -bL -ab -ab -bT -bT -ab -ab -ab -ab -ui -ui -ui -ui -ui -ab -fB -ab -ab -cb -ab -ab -bT -bT -bT -ui -ui -ui -af -bT -bT -yh -yh -yh -"} -(21,1,1) = {" -bV -bL -ab -ab -af -bT -bT -bT -bL -ab -cb -Ek -ab -ab -ab -ab -Hj -Zr -fP -dh -du -ab -bT -bT -bT -bT -bT -bT -bT -dq -af -yh -yh -yh -"} -(22,1,1) = {" -bV -bL -ab -ab -dq -af -bT -bT -bT -bT -ab -ab -ab -ab -ab -ab -ab -ab -ui -Px -ui -ab -bT -bT -bT -bT -bT -bT -bT -bT -bT -yh -yh -yh -"} -(23,1,1) = {" -bV -ab -ab -ab -ab -ab -bT -bT -bT -dq -bT -bT -bT -ab -ab -ab -ab -ab -ui -Vj -ui -bT -bT -bT -bT -bT -bT -bT -bT -bT -ab -yh -yh -yh -"} -(24,1,1) = {" -bV -ab -ab -cb -ab -bT -ab -bT -bT -bT -bT -af -bT -bT -bT -ui -ui -nK -um -lZ -ui -nj -nN -hI -af -AL -af -af -dq -bT -ab -yh -yh -yh -"} -(25,1,1) = {" -bV -bL -bV -ab -ab -bT -bT -ui -bT -bT -af -af -dq -af -bT -ui -Dp -fY -hY -Mu -ui -af -af -zO -pQ -AL -pQ -VA -to -bT -bT -bT -yh -yh -"} -(26,1,1) = {" -bV -bL -bV -cb -ab -bT -pQ -ui -ui -ui -ui -af -bT -ui -ui -ui -um -Ta -Dt -Fa -ui -bT -Gk -pQ -af -af -XD -pQ -af -bT -bT -bT -yh -yh -"} -(27,1,1) = {" -bV -bL -bL -ab -bT -VA -VA -ui -zp -vl -ui -af -TN -ui -zG -Oh -um -fm -Jw -fc -bP -Uq -BG -vM -bT -bT -oG -bT -af -bT -bT -bT -ab -bU -"} -(28,1,1) = {" -bV -bL -ab -ab -bT -bT -bT -ui -BX -ZG -ui -su -af -ui -Fd -ub -Au -pn -Io -hj -ui -vo -Uq -rY -bT -pQ -pQ -VA -af -bT -bT -ab -ab -bL -"} -(29,1,1) = {" -bV -bL -ab -ab -aa -bT -bT -ui -ui -Dv -ui -ui -Og -ui -ui -ic -Au -LA -no -uf -ui -af -bT -PY -pP -bT -pQ -bT -af -bT -bT -bT -ab -bL -"} -(30,1,1) = {" -bV -bL -ab -ab -VA -bT -bT -bT -Ms -uf -fc -hj -fc -cc -YK -hj -Az -BV -Hs -Dz -ui -bT -Wp -hI -af -af -af -af -hI -bT -bT -ab -cb -bL -"} -(31,1,1) = {" -bV -bL -ab -ab -ab -VA -bT -sg -ui -KN -GV -Yl -ui -ui -ui -ui -ui -VO -xK -wZ -ui -bT -bT -bT -bT -bT -bT -bT -bT -bT -ab -ab -cb -bL -"} -(32,1,1) = {" -bV -bL -bL -ab -ab -bT -bT -bT -bT -bT -bT -bT -af -af -af -af -ui -ui -ui -ho -ui -bT -ab -ab -ab -bT -bT -bT -bT -bT -ab -ab -cb -bL -"} -(33,1,1) = {" -bV -bL -bL -bL -ab -ab -ab -bT -bT -bT -bT -bT -bT -bT -dq -bT -bT -bT -Po -AH -Wl -bT -ab -bV -bV -ab -ab -ab -ab -ab -ab -ab -cb -bL -"} -(34,1,1) = {" -bV -bL -bL -bV -ab -ab -ab -ab -ab -ab -ab -bT -bT -bT -bT -bT -bT -bT -ZA -oj -hx -ab -ab -bV -bV -bV -ab -ab -ab -ab -bL -bL -bU -bL -"} -(35,1,1) = {" -bV -bL -bL -bV -bL -bU -bU -cb -cb -cb -cb -ab -ab -ab -bT -bT -bT -bT -PF -RL -Wl -ab -ab -ab -ab -ab -ab -cb -bV -bV -bL -bL -bU -bL -"} -(36,1,1) = {" -bV -bL -bL -bL -bL -bL -bL -bL -bL -bL -bL -ab -ab -ab -ab -yh -yh -yh -cM -cM -cM -ab -ab -bL -bL -bL -bL -bL -bL -bL -bL -bL -bU -bL -"} -(37,1,1) = {" -bV -bV -bV -bV -bV -bV -bV -bV -bV -bV -bV -bV -bV -bV -bV -yh -yh -yh -cM -cM -cM -bV -bV -bV -bV -bV -bV -bV -bV -bV -bV -bV -bV -bV -"} diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_greed.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_greed.dmm deleted file mode 100644 index 2b63849476244..0000000000000 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_greed.dmm +++ /dev/null @@ -1,567 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"b" = ( -/turf/simulated/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) -"c" = ( -/turf/simulated/floor/lava/mapping_lava, -/area/lavaland/surface/outdoors) -"d" = ( -/obj/effect/baseturf_helper/lava/mapping_lava, -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"e" = ( -/obj/structure/table/wood/poker, -/obj/item/toy/russian_revolver/soul, -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/carpet{ - icon_state = "carpetsymbol" - }, -/area/ruin/powered/greed) -"f" = ( -/obj/structure/cursed_slot_machine, -/turf/simulated/floor/carpet{ - icon_state = "carpetsymbol" - }, -/area/ruin/powered/greed) -"g" = ( -/obj/structure/table/wood/poker, -/obj/item/coin/mythril, -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/carpet{ - icon_state = "carpetsymbol" - }, -/area/ruin/powered/greed) -"h" = ( -/obj/structure/table/wood/poker, -/obj/item/coin/diamond, -/turf/simulated/floor/carpet{ - icon_state = "carpetsymbol" - }, -/area/ruin/powered/greed) -"i" = ( -/turf/simulated/floor/carpet{ - icon_state = "carpetsymbol" - }, -/area/ruin/powered/greed) -"j" = ( -/obj/structure/table/wood/poker, -/obj/item/coin/adamantine, -/turf/simulated/floor/carpet{ - icon_state = "carpetsymbol" - }, -/area/ruin/powered/greed) -"k" = ( -/obj/machinery/computer/arcade/battle{ - emagged = 1 - }, -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"l" = ( -/obj/item/coin/gold, -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"m" = ( -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"o" = ( -/obj/item/storage/bag/money, -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"p" = ( -/obj/structure/table/wood/poker, -/obj/item/stack/ore/gold, -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"q" = ( -/obj/structure/table/wood/poker, -/obj/item/stack/spacecash/c50, -/obj/machinery/light/small{ - brightness_range = 3; - dir = 8 - }, -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"r" = ( -/obj/structure/table/wood/poker, -/obj/item/stack/spacecash/c100, -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"s" = ( -/obj/structure/table/wood/poker, -/obj/item/stack/spacecash/c50, -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"u" = ( -/obj/structure/table/wood/poker, -/obj/item/stack/spacecash/c100, -/obj/machinery/light/small{ - dir = 4 - }, -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"v" = ( -/obj/item/coin/gold, -/obj/machinery/light/small, -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"w" = ( -/obj/item/storage/bag/money, -/obj/machinery/light/small, -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"J" = ( -/obj/machinery/door/airlock/gold, -/obj/structure/fans/tiny/invisible, -/turf/simulated/floor/engine/cult, -/area/ruin/powered/greed) -"W" = ( -/turf/simulated/wall/cult, -/area/ruin/powered/greed) - -(1,1,1) = {" -a -a -a -a -a -a -a -a -a -b -b -a -a -a -a -a -a -a -a -b -"} -(2,1,1) = {" -a -b -b -a -a -a -a -a -a -b -b -b -a -a -a -a -a -b -b -b -"} -(3,1,1) = {" -a -b -b -b -b -b -a -a -a -b -a -a -a -a -a -a -b -b -b -b -"} -(4,1,1) = {" -a -a -b -b -b -a -a -a -a -a -a -a -a -a -a -a -b -b -b -b -"} -(5,1,1) = {" -a -a -a -b -b -a -a -c -c -c -c -c -c -c -a -a -a -a -b -a -"} -(6,1,1) = {" -b -a -a -a -a -a -c -c -W -W -W -W -W -c -a -a -a -a -b -a -"} -(7,1,1) = {" -b -a -a -a -c -c -c -W -W -p -q -s -W -c -c -c -c -a -a -a -"} -(8,1,1) = {" -a -a -a -a -c -W -W -W -k -o -l -m -W -W -W -W -c -a -a -a -"} -(9,1,1) = {" -a -a -b -a -c -W -e -h -l -m -m -m -l -m -v -W -W -a -a -a -"} -(10,1,1) = {" -b -b -b -a -c -W -f -i -m -l -d -o -m -m -m -m -J -a -a -a -"} -(11,1,1) = {" -a -a -b -a -c -W -g -j -l -m -m -l -m -l -w -W -W -a -a -a -"} -(12,1,1) = {" -a -a -a -a -c -W -W -W -k -o -m -l -W -W -W -W -c -a -a -a -"} -(13,1,1) = {" -a -a -a -a -c -c -c -W -W -p -u -r -W -c -c -c -c -a -a -a -"} -(14,1,1) = {" -b -b -a -a -a -a -c -c -W -W -W -W -W -c -a -a -a -a -a -a -"} -(15,1,1) = {" -b -b -a -a -a -a -a -c -c -c -c -c -c -c -a -a -a -a -a -a -"} -(16,1,1) = {" -b -b -b -b -a -a -a -a -a -a -a -a -a -a -a -a -a -a -b -b -"} -(17,1,1) = {" -a -a -b -b -a -a -a -a -a -a -a -a -a -a -a -a -a -a -b -b -"} -(18,1,1) = {" -a -a -a -b -b -b -b -b -b -b -b -b -b -a -a -b -b -b -b -b -"} -(19,1,1) = {" -a -a -a -b -b -b -b -a -a -a -b -b -b -b -a -b -b -b -b -b -"} -(20,1,1) = {" -a -a -a -a -b -b -a -a -a -a -a -a -b -b -b -b -b -b -b -b -"} diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm deleted file mode 100644 index c36b17b3d8b66..0000000000000 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm +++ /dev/null @@ -1,1370 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/simulated/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors/unexplored) -"ag" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/sink{ - pixel_y = 24 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"al" = ( -/obj/structure/disposalpipe/trunk, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"aS" = ( -/obj/machinery/chem_dispenser/mutagensaltpeter, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"bA" = ( -/obj/structure/closet/crate/hydroponics, -/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/gun/energy/floragun, -/obj/item/gun/energy/floragun, -/obj/item/gun/energy/floragun, -/obj/item/gun/energy/floragun, -/obj/machinery/light{ - dir = 1 - }, -/obj/item/clothing/glasses/hud/hydroponic, -/obj/item/clothing/glasses/hud/hydroponic, -/obj/item/clothing/glasses/hud/hydroponic, -/obj/item/clothing/glasses/hud/hydroponic, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"bE" = ( -/obj/machinery/hydroponics/constructable, -/obj/machinery/light, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"bJ" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/sink{ - pixel_y = -4; - dir = 1 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"dX" = ( -/obj/structure/sink{ - pixel_y = 24 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"ed" = ( -/obj/structure/closet/crate/freezer, -/obj/effect/spawner/random/seed_vault, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"eI" = ( -/obj/machinery/hydroponics/constructable, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"fm" = ( -/obj/machinery/economy/vending/hydronutrients, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"ga" = ( -/obj/structure/closet/crate/hydroponics, -/obj/structure/beebox, -/obj/item/melee/flyswatter, -/obj/item/honey_frame, -/obj/item/honey_frame, -/obj/item/honey_frame, -/obj/item/queen_bee/bought, -/obj/item/clothing/head/beekeeper_head, -/obj/item/clothing/suit/beekeeper_suit, -/obj/machinery/light, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"gf" = ( -/obj/structure/table/wood, -/obj/item/paper_bin, -/obj/item/storage/fancy/rollingpapers, -/obj/item/storage/fancy/rollingpapers, -/obj/item/storage/fancy/rollingpapers, -/obj/item/storage/fancy/rollingpapers, -/obj/item/lighter, -/obj/item/lighter, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"hy" = ( -/obj/machinery/airlock_controller/access_controller{ - ext_button_link_id = "seedvault_btn_ext"; - ext_door_link_id = "seedvault_door_ext"; - int_button_link_id = "seedvault_btn_int"; - int_door_link_id = "seedvault_door_int"; - pixel_y = 25 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"hO" = ( -/obj/effect/baseturf_helper/lava/mapping_lava, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"im" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"iu" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/effect/mob_spawn/human/corpse/seed_vault_diona, -/obj/item/pickaxe/mini, -/obj/item/food/grown/mushroom/glowshroom{ - pixel_x = 8; - pixel_y = -8 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"iV" = ( -/obj/structure/closet/crate/hydroponics, -/obj/structure/beebox, -/obj/item/melee/flyswatter, -/obj/item/honey_frame, -/obj/item/honey_frame, -/obj/item/honey_frame, -/obj/item/queen_bee/bought, -/obj/item/clothing/head/beekeeper_head, -/obj/item/clothing/suit/beekeeper_suit, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"ja" = ( -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"my" = ( -/obj/machinery/hydroponics/constructable, -/obj/structure/disposalpipe/segment, -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"no" = ( -/turf/simulated/wall/r_wall, -/area/ruin/powered/seedvault) -"nt" = ( -/obj/structure/sink{ - dir = 4; - pixel_x = 12 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"oy" = ( -/obj/machinery/reagentgrinder{ - pixel_y = 5 - }, -/obj/structure/table/glass, -/obj/item/storage/box/beakers/bluespace, -/obj/item/storage/box/beakers/bluespace, -/obj/item/book/manual/wiki/hydroponics, -/obj/item/book/manual/wiki/hydroponics, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"qI" = ( -/obj/machinery/smartfridge, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"rx" = ( -/obj/machinery/door/airlock/external{ - id_tag = "seedvault_door_int"; - locked = 1 - }, -/obj/structure/fans/tiny, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"uG" = ( -/obj/machinery/light, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"uO" = ( -/obj/machinery/chem_master/condimaster, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"vt" = ( -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"vJ" = ( -/obj/structure/closet/crate/hydroponics, -/obj/item/cultivator, -/obj/item/cultivator, -/obj/item/cultivator, -/obj/item/cultivator, -/obj/item/shovel/spade, -/obj/item/shovel/spade, -/obj/item/shovel/spade, -/obj/item/shovel/spade, -/obj/item/hatchet, -/obj/item/hatchet, -/obj/item/hatchet, -/obj/item/hatchet, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"xe" = ( -/obj/structure/disposalpipe/segment, -/turf/simulated/wall/r_wall, -/area/ruin/powered/seedvault) -"xG" = ( -/obj/machinery/hydroponics/constructable, -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"yc" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"yZ" = ( -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"zk" = ( -/obj/machinery/access_button{ - autolink_id = "seedvault_btn_ext"; - name = "exterior access button"; - pixel_x = -25; - pixel_y = -25 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"zA" = ( -/obj/machinery/economy/vending/hydroseeds, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Ae" = ( -/obj/machinery/hydroponics/constructable, -/obj/structure/disposalpipe/segment, -/obj/machinery/light, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"AG" = ( -/obj/effect/mob_spawn/human/alive/seed_vault, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"AT" = ( -/obj/structure/table/wood, -/obj/item/hand_labeler, -/obj/item/hand_labeler, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Bf" = ( -/obj/machinery/door/airlock, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"BC" = ( -/turf/simulated/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) -"BU" = ( -/obj/machinery/computer/cryopod{ - pixel_x = 30; - dir = 8 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Cp" = ( -/obj/machinery/biogenerator, -/obj/item/reagent_containers/glass/bucket, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Ct" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Dn" = ( -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"DQ" = ( -/obj/machinery/access_button{ - autolink_id = "seedvault_btn_int"; - name = "exterior access button"; - pixel_x = 25; - pixel_y = -25 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"DZ" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 4 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Eh" = ( -/obj/machinery/light, -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Ev" = ( -/obj/structure/closet/crate/hydroponics, -/obj/item/vending_refill/hydroseeds, -/obj/item/vending_refill/hydronutrients, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"FS" = ( -/obj/effect/spawner/window/reinforced/plasma, -/turf/simulated/floor/plating, -/area/ruin/powered/seedvault) -"HL" = ( -/obj/structure/closet/crate/hydroponics, -/obj/item/storage/bag/plants/portaseeder, -/obj/item/storage/bag/plants/portaseeder, -/obj/item/storage/bag/plants/portaseeder, -/obj/item/storage/bag/plants/portaseeder, -/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/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"IJ" = ( -/obj/machinery/computer/nonfunctional{ - dir = 4; - name = "Ship Auto-Pilot Console" - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"JL" = ( -/obj/machinery/computer/nonfunctional{ - dir = 4; - name = "Auto-Pilot Traveling Logs" - }, -/obj/item/paper/seed_vault/autopilot_logs, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Lg" = ( -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"MB" = ( -/obj/structure/table/wood, -/obj/item/storage/toolbox/syndicate, -/obj/item/storage/toolbox/syndicate, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Nj" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 4 - }, -/obj/effect/mapping_helpers/no_lava, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"Nt" = ( -/obj/structure/table/wood, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"OL" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 1 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"OZ" = ( -/obj/structure/fans/tiny, -/obj/machinery/door/airlock/external{ - id_tag = "seedvault_door_int"; - locked = 1 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Pg" = ( -/obj/machinery/cryopod/offstation/right, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Qb" = ( -/obj/structure/table/wood, -/obj/item/seeds/grass{ - name = "modificated pack of grass seeds" - }, -/obj/item/paper/seed_vault/terraforming_introduction, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"QX" = ( -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"Uh" = ( -/obj/structure/sink{ - dir = 8; - pixel_x = -12; - pixel_y = 2 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Vu" = ( -/obj/machinery/seed_extractor, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"VI" = ( -/obj/structure/table/wood, -/obj/item/paper/seed_vault, -/obj/item/pen, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Wu" = ( -/obj/machinery/hydroponics/constructable, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Xx" = ( -/obj/structure/fans/tiny, -/obj/machinery/door/airlock/external{ - id_tag = "seedvault_door_ext"; - locked = 1 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"XC" = ( -/obj/structure/sink{ - pixel_y = -4; - dir = 1 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"XF" = ( -/obj/machinery/plantgenes/seedvault{ - pixel_y = 6 - }, -/obj/structure/table/wood, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"XO" = ( -/obj/structure/closet/crate/internals, -/obj/item/pickaxe/mini, -/obj/item/pickaxe/mini, -/obj/item/pickaxe/mini, -/obj/item/pickaxe/mini, -/obj/item/clothing/mask/breath, -/obj/item/clothing/mask/breath, -/obj/item/clothing/mask/breath, -/obj/item/clothing/mask/breath, -/obj/item/tank/internals/emergency_oxygen/engi, -/obj/item/tank/internals/emergency_oxygen/engi, -/obj/item/tank/internals/emergency_oxygen/engi, -/obj/item/tank/internals/emergency_oxygen/engi, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"ZQ" = ( -/obj/structure/table/glass, -/obj/item/storage/box/disks_plantgene, -/obj/item/storage/box/disks_plantgene, -/obj/item/storage/box/disks_plantgene, -/obj/item/storage/box/disks_plantgene, -/obj/item/storage/box/disks_plantgene, -/obj/item/storage/box/disks_plantgene, -/turf/simulated/floor/plasteel/freezer, -/area/ruin/powered/seedvault) - -(1,1,1) = {" -QX -QX -QX -yZ -aa -aa -aa -aa -aa -aa -aa -aa -QX -aa -QX -aa -aa -aa -aa -aa -aa -QX -QX -QX -"} -(2,1,1) = {" -QX -aa -yZ -yZ -yZ -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -QX -aa -aa -aa -aa -aa -"} -(3,1,1) = {" -QX -aa -aa -yZ -yZ -aa -yZ -yZ -yZ -aa -yZ -yZ -yZ -yZ -aa -aa -aa -aa -aa -aa -aa -aa -aa -QX -"} -(4,1,1) = {" -aa -aa -aa -aa -yZ -BC -yZ -yZ -yZ -yZ -yZ -yZ -yZ -yZ -yZ -yZ -yZ -yZ -yZ -aa -yZ -aa -aa -aa -"} -(5,1,1) = {" -aa -QX -aa -yZ -yZ -yZ -yZ -yZ -yZ -yZ -FS -FS -FS -FS -yZ -yZ -yZ -yZ -yZ -yZ -yZ -yZ -aa -aa -"} -(6,1,1) = {" -aa -aa -aa -yZ -yZ -no -no -yZ -yZ -no -FS -IJ -JL -FS -no -yZ -yZ -no -no -yZ -yZ -aa -aa -aa -"} -(7,1,1) = {" -aa -aa -aa -yZ -no -no -no -no -yZ -no -Qb -vt -vt -vt -no -yZ -no -no -no -no -yZ -aa -aa -aa -"} -(8,1,1) = {" -aa -aa -yZ -yZ -no -Pg -vt -no -no -no -no -vt -vt -no -no -no -no -vt -AG -no -yZ -aa -aa -aa -"} -(9,1,1) = {" -aa -aa -yZ -yZ -no -Pg -vt -vt -Bf -vt -no -Bf -Bf -no -vt -Bf -vt -vt -AG -no -yZ -yZ -aa -QX -"} -(10,1,1) = {" -QX -aa -aa -yZ -no -Pg -uG -no -no -vt -Uh -vt -vt -Uh -vt -no -no -Dn -AG -no -yZ -BC -yZ -yZ -"} -(11,1,1) = {" -QX -aa -aa -yZ -no -Pg -vt -no -Wu -vt -vt -vt -vt -vt -vt -Wu -no -vt -AG -no -yZ -yZ -yZ -aa -"} -(12,1,1) = {" -QX -aa -aa -yZ -no -no -BU -no -xG -vt -vt -fm -Vu -vt -vt -bE -no -VI -no -no -yZ -yZ -aa -aa -"} -(13,1,1) = {" -aa -aa -yZ -yZ -Nj -no -no -no -Wu -vt -vt -zA -XF -vt -vt -Wu -no -no -no -Nj -yZ -aa -aa -aa -"} -(14,1,1) = {" -aa -aa -aa -yZ -yZ -no -Nj -no -Wu -vt -vt -aS -Nt -vt -vt -Wu -no -Nj -no -yZ -yZ -aa -aa -aa -"} -(15,1,1) = {" -aa -aa -aa -aa -yZ -al -yc -xe -my -OL -vt -qI -Cp -vt -DZ -Ae -xe -yc -ja -yZ -yZ -yZ -aa -aa -"} -(16,1,1) = {" -aa -aa -yZ -yZ -yZ -no -no -no -Wu -im -vt -vt -vt -vt -im -Wu -no -no -no -yZ -yZ -aa -aa -QX -"} -(17,1,1) = {" -QX -aa -aa -yZ -no -no -ed -no -no -ag -vt -vt -vt -vt -bJ -no -no -ed -no -no -yZ -yZ -aa -aa -"} -(18,1,1) = {" -aa -aa -yZ -yZ -no -HL -vt -vt -no -Ct -vt -vt -hO -vt -Eh -no -vt -vt -iV -no -yZ -yZ -yZ -aa -"} -(19,1,1) = {" -aa -aa -yZ -yZ -no -vJ -vt -vt -Bf -vt -vt -ZQ -oy -vt -vt -Bf -vt -vt -iV -no -yZ -yZ -aa -aa -"} -(20,1,1) = {" -aa -yZ -yZ -yZ -no -bA -vt -vt -no -vt -vt -vt -vt -vt -vt -no -vt -vt -ga -no -yZ -yZ -aa -aa -"} -(21,1,1) = {" -yZ -iu -yZ -yZ -no -gf -vt -no -no -dX -vt -vt -vt -vt -XC -no -no -vt -iV -no -yZ -yZ -yZ -aa -"} -(22,1,1) = {" -QX -yZ -aa -yZ -no -MB -vt -no -Wu -vt -vt -vt -vt -vt -vt -Wu -no -vt -uO -no -yZ -yZ -aa -aa -"} -(23,1,1) = {" -aa -aa -yZ -yZ -no -AT -vt -no -xG -vt -vt -Vu -fm -vt -vt -bE -no -vt -XO -no -yZ -yZ -yZ -aa -"} -(24,1,1) = {" -QX -aa -yZ -yZ -no -no -ed -no -Wu -vt -vt -XF -zA -vt -vt -Wu -no -Ev -no -no -yZ -yZ -aa -QX -"} -(25,1,1) = {" -aa -aa -yZ -yZ -Nj -no -no -no -Wu -vt -vt -Nt -qI -vt -vt -Wu -no -no -no -Nj -yZ -yZ -aa -aa -"} -(26,1,1) = {" -aa -aa -aa -yZ -yZ -no -Nj -no -xG -vt -vt -Cp -aS -vt -vt -bE -no -Nj -no -yZ -yZ -yZ -yZ -aa -"} -(27,1,1) = {" -aa -aa -aa -aa -yZ -al -yc -xe -eI -OL -vt -vt -vt -vt -DZ -eI -xe -yc -ja -yZ -yZ -aa -aa -aa -"} -(28,1,1) = {" -aa -QX -aa -yZ -yZ -yZ -yZ -no -no -Lg -nt -vt -DQ -nt -Lg -no -no -yZ -yZ -yZ -yZ -aa -aa -QX -"} -(29,1,1) = {" -aa -aa -aa -BC -BC -yZ -yZ -Nj -no -no -no -rx -OZ -no -no -no -Nj -yZ -yZ -BC -yZ -aa -aa -aa -"} -(30,1,1) = {" -QX -QX -aa -BC -BC -yZ -yZ -yZ -no -Nj -no -hy -vt -no -Nj -no -yZ -yZ -yZ -yZ -BC -aa -aa -aa -"} -(31,1,1) = {" -QX -aa -aa -BC -BC -yZ -BC -yZ -yZ -yZ -no -Xx -Xx -no -yZ -yZ -yZ -BC -BC -yZ -BC -aa -QX -aa -"} -(32,1,1) = {" -aa -QX -QX -BC -BC -BC -yZ -yZ -yZ -yZ -yZ -yZ -zk -yZ -yZ -yZ -yZ -yZ -BC -BC -QX -aa -aa -QX -"} -(33,1,1) = {" -QX -aa -BC -BC -BC -BC -BC -BC -BC -yZ -yZ -yZ -yZ -yZ -yZ -yZ -BC -BC -BC -BC -BC -aa -aa -aa -"} -(34,1,1) = {" -QX -QX -BC -QX -BC -BC -BC -yZ -yZ -yZ -yZ -yZ -yZ -yZ -yZ -yZ -yZ -BC -BC -QX -BC -QX -QX -QX -"} diff --git a/_maps/map_files/RandomRuins/SpaceRuins/clockwork_monastery.dmm b/_maps/map_files/RandomRuins/SpaceRuins/clockwork_monastery.dmm deleted file mode 100644 index a5da43b78804f..0000000000000 --- a/_maps/map_files/RandomRuins/SpaceRuins/clockwork_monastery.dmm +++ /dev/null @@ -1,3680 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aj" = ( -/obj/structure/chair/sofa/pew/clockwork/left{ - dir = 8 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"bf" = ( -/obj/structure/mirror{ - pixel_y = 28 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"bg" = ( -/turf/simulated/floor/carpet/royalblack, -/area/ruin/space/clockwork_monastery) -"bt" = ( -/obj/structure/table/reinforced/brass, -/obj/item/weldingtool/experimental/brass, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"bW" = ( -/obj/structure/window/reinforced/clockwork{ - dir = 4 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"ch" = ( -/turf/simulated/mineral/random/high_chance, -/area/ruin/unpowered) -"cK" = ( -/obj/structure/table/reinforced/brass, -/obj/item/storage/surgical_tray{ - pixel_y = 8 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"dd" = ( -/obj/machinery/light/clockwork/small{ - dir = 1 - }, -/obj/machinery/computer/operating/clockwork, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"dx" = ( -/turf/simulated/mineral/ancient/outer, -/area/ruin/unpowered) -"eg" = ( -/obj/machinery/light/clockwork{ - dir = 1 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"ei" = ( -/obj/machinery/sleeper/clockwork, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"eS" = ( -/obj/machinery/door/airlock/clockwork{ - name = "Inner Narthex" - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"gV" = ( -/turf/template_noop, -/area/template_noop) -"hk" = ( -/obj/structure/bed, -/obj/item/bedsheet/clockwork, -/obj/machinery/light/clockwork{ - dir = 4 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"hV" = ( -/obj/machinery/door/airlock/clockwork/glass{ - name = "Feretory" - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"hW" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/hierophant_ansible, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"jq" = ( -/turf/simulated/floor/lava/plasma, -/area/ruin/space/clockwork_monastery) -"jC" = ( -/obj/structure/window/reinforced/clockwork, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"jP" = ( -/obj/structure/dresser, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"ka" = ( -/mob/living/simple_animal/hostile/clockwork_construct/clockwork_marauder/hostile{ - dir = 4 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"kC" = ( -/turf/simulated/floor/plating/asteroid/airless, -/area/ruin/unpowered) -"kZ" = ( -/obj/structure/bed, -/obj/item/bedsheet/clockwork, -/obj/machinery/light/clockwork, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"ly" = ( -/obj/machinery/light/clockwork/small, -/obj/structure/chair/sofa/pew/clockwork/left{ - dir = 1 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"lN" = ( -/obj/structure/chair/brass{ - dir = 8 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"mn" = ( -/obj/structure/table/reinforced/brass, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"oc" = ( -/obj/machinery/door/airlock/clockwork{ - name = "Rotunda" - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"of" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/geis_capacitor, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"ow" = ( -/turf/simulated/floor/plating/asteroid/basalt, -/area/ruin/unpowered) -"oW" = ( -/turf/simulated/wall/clockwork, -/area/ruin/space/clockwork_monastery) -"pe" = ( -/obj/effect/turf_decal/woodsiding{ - dir = 5 - }, -/turf/simulated/floor/lava/plasma, -/area/ruin/space/clockwork_monastery) -"pp" = ( -/obj/structure/chair/sofa/pew/clockwork{ - dir = 4 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"pE" = ( -/obj/structure/bed, -/obj/item/bedsheet/clockwork, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"pI" = ( -/mob/living/simple_animal/hostile/clockwork_construct/clockwork_marauder/hostile{ - dir = 8 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"qc" = ( -/obj/effect/turf_decal/woodsiding{ - dir = 6 - }, -/turf/simulated/floor/lava/plasma, -/area/ruin/space/clockwork_monastery) -"rb" = ( -/obj/structure/shelf/clockwork, -/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment, -/obj/item/clockwork/component/replicant_alloy/replication_plate, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"rJ" = ( -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"rM" = ( -/obj/structure/table/reinforced/brass, -/turf/simulated/floor/carpet/royalblack, -/area/ruin/space/clockwork_monastery) -"sc" = ( -/obj/machinery/door/airlock/clockwork{ - name = "Sanctum" - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"sg" = ( -/obj/structure/shelf/clockwork, -/obj/item/clockwork/component/belligerent_eye/blind_eye, -/obj/item/clockwork/alloy_shards/pinion_lock, -/obj/item/clockwork/alloy_shards/small, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"sT" = ( -/obj/machinery/light/clockwork/small{ - dir = 1 - }, -/turf/simulated/floor/plating/asteroid/basalt, -/area/ruin/space/clockwork_monastery) -"sZ" = ( -/obj/structure/grille/ratvar, -/obj/structure/window/reinforced/clockwork/fulltile, -/turf/simulated/floor/clockwork/reebe, -/area/ruin/space/clockwork_monastery) -"ua" = ( -/obj/structure/chair/brass{ - dir = 4 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"uz" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"uH" = ( -/obj/machinery/optable, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"vc" = ( -/obj/structure/chair/sofa/pew/clockwork/left, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"vU" = ( -/obj/structure/chair/sofa/pew/clockwork/right, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"xp" = ( -/obj/effect/turf_decal/woodsiding{ - dir = 4 - }, -/turf/simulated/floor/lava/plasma, -/area/ruin/space/clockwork_monastery) -"xv" = ( -/obj/machinery/door/airlock/clockwork/glass{ - name = "Workshop" - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"yn" = ( -/obj/structure/table/reinforced/brass, -/obj/effect/spawner/random/food_or_drink/soup, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"yp" = ( -/turf/simulated/mineral/ancient/outer, -/area/template_noop) -"yy" = ( -/obj/structure/chair/brass{ - dir = 1 - }, -/turf/simulated/floor/carpet/royalblack, -/area/ruin/space/clockwork_monastery) -"yH" = ( -/obj/machinery/light/clockwork/small{ - dir = 4 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"zC" = ( -/obj/machinery/light/clockwork{ - dir = 4 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"zG" = ( -/obj/machinery/light/clockwork/small, -/turf/simulated/floor/plating/asteroid/airless, -/area/ruin/space/clockwork_monastery) -"zQ" = ( -/obj/structure/table/reinforced/brass, -/obj/item/salvage/ruin/tablet, -/turf/simulated/floor/carpet/royalblack, -/area/ruin/space/clockwork_monastery) -"Az" = ( -/obj/structure/chair/sofa/pew/clockwork, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"AA" = ( -/obj/structure/falsewall/rock_ancient, -/turf/simulated/floor/plating/asteroid/airless, -/area/ruin/unpowered) -"Bo" = ( -/obj/structure/window/reinforced/clockwork/fulltile, -/obj/structure/grille/ratvar, -/turf/simulated/floor/clockwork/reebe, -/area/ruin/space/clockwork_monastery) -"CB" = ( -/obj/machinery/light/clockwork/small{ - dir = 1 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"CG" = ( -/obj/machinery/light/clockwork/small{ - dir = 1 - }, -/obj/structure/chair/sofa/pew/clockwork/right, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"CH" = ( -/obj/machinery/light/clockwork/small, -/obj/item/stack/tile/brass/fifty, -/obj/structure/table/reinforced/brass, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"CI" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/vanguard_cogwheel, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"CW" = ( -/obj/structure/chair/brass{ - dir = 8 - }, -/turf/simulated/floor/carpet/royalblack, -/area/ruin/space/clockwork_monastery) -"De" = ( -/obj/effect/turf_decal/woodsiding{ - dir = 10 - }, -/turf/simulated/floor/lava/plasma, -/area/ruin/space/clockwork_monastery) -"Ea" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/geis_capacitor/antennae, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Em" = ( -/obj/machinery/door/airlock/clockwork{ - name = "Infirmary" - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Ev" = ( -/obj/machinery/door/airlock/clockwork/glass{ - name = "Dormitory" - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"EN" = ( -/obj/structure/shelf/clockwork, -/obj/item/clockwork/alloy_shards/large, -/obj/item/clockwork/component/geis_capacitor/fallen_armor, -/obj/item/clockwork/alloy_shards/medium, -/obj/item/clockwork/component/belligerent_eye, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"EQ" = ( -/obj/structure/chair/brass{ - dir = 4 - }, -/turf/simulated/floor/carpet/royalblack, -/area/ruin/space/clockwork_monastery) -"Gb" = ( -/obj/machinery/light/clockwork/small{ - dir = 8 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Gw" = ( -/obj/structure/bed, -/obj/item/bedsheet/clockwork, -/obj/machinery/light/clockwork{ - dir = 1 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"GE" = ( -/obj/structure/table/reinforced/brass, -/obj/item/stack/cable_coil/orange, -/obj/item/stack/cable_coil/orange{ - pixel_x = 2; - pixel_y = 4 - }, -/obj/item/stack/cable_coil/orange{ - pixel_x = 4; - pixel_y = 7 - }, -/obj/item/wirecutters/brass, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"GF" = ( -/obj/structure/table/reinforced/brass, -/obj/item/crowbar/brass, -/obj/item/wrench/brass, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Ht" = ( -/turf/simulated/mineral/random/low_chance, -/area/ruin/unpowered) -"HB" = ( -/obj/structure/chair/sofa/pew/clockwork/right{ - dir = 1 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"HF" = ( -/obj/machinery/door/airlock/clockwork{ - name = "Outer Narthex" - }, -/obj/structure/fans/tiny, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Ib" = ( -/obj/structure/chair/brass{ - dir = 1 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Ie" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/replicant_alloy, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Iw" = ( -/obj/structure/table/reinforced/brass, -/obj/item/tank/internals/oxygen, -/obj/item/clothing/mask/breath, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"IL" = ( -/obj/structure/table/reinforced/brass, -/obj/item/storage/belt/utility, -/obj/item/screwdriver/brass, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Jm" = ( -/turf/simulated/floor/chasm/space_ruin, -/area/ruin/unpowered) -"Jx" = ( -/obj/structure/chair/brass, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"JU" = ( -/obj/structure/chair/sofa/pew/clockwork/left{ - dir = 1 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Ki" = ( -/obj/machinery/light/clockwork/small, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Ku" = ( -/obj/structure/table/reinforced/brass, -/obj/item/paper_bin{ - pixel_y = 4 - }, -/obj/item/pen/multi/fountain, -/turf/simulated/floor/carpet/royalblack, -/area/ruin/space/clockwork_monastery) -"KZ" = ( -/obj/structure/chair/sofa/pew/clockwork{ - dir = 1 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Lh" = ( -/obj/structure/clockwork/wall_gear, -/obj/machinery/light/clockwork/floor, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Mc" = ( -/obj/effect/turf_decal/woodsiding{ - dir = 8 - }, -/turf/simulated/floor/lava/plasma, -/area/ruin/space/clockwork_monastery) -"ME" = ( -/obj/machinery/light/clockwork, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"MU" = ( -/obj/structure/chair/brass, -/turf/simulated/floor/carpet/royalblack, -/area/ruin/space/clockwork_monastery) -"NC" = ( -/obj/structure/gunrack/clockwork, -/obj/item/clockwork/weapon/ratvarian_spear, -/obj/item/clockwork/weapon/ratvarian_spear, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"NF" = ( -/obj/structure/chair/sofa/pew/clockwork/left{ - dir = 4 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"NQ" = ( -/obj/structure/shelf/clockwork, -/obj/effect/spawner/random/maintenance, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"NV" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/belligerent_eye/lens_gem, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Rv" = ( -/obj/machinery/light/clockwork{ - dir = 8 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Rw" = ( -/obj/structure/table/reinforced/brass, -/obj/item/paper/clockwork_cult_message, -/turf/simulated/floor/carpet/royalblack, -/area/ruin/space/clockwork_monastery) -"RD" = ( -/mob/living/simple_animal/hostile/clockwork_construct/clockwork_marauder/hostile{ - dir = 1 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"RE" = ( -/obj/structure/chair/sofa/pew/clockwork/right{ - dir = 1 - }, -/obj/machinery/light/clockwork/small, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Sq" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/hierophant_ansible/obelisk, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Vh" = ( -/obj/effect/turf_decal/woodsiding{ - dir = 9 - }, -/turf/simulated/floor/lava/plasma, -/area/ruin/space/clockwork_monastery) -"VU" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/alloy_shards{ - pixel_y = 3 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Wl" = ( -/obj/structure/chair/sofa/pew/clockwork/right{ - dir = 8 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"WR" = ( -/mob/living/simple_animal/hostile/clockwork_construct/clockwork_marauder/hostile, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Xk" = ( -/obj/machinery/door/airlock/clockwork{ - name = "Chapel" - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Xw" = ( -/turf/simulated/floor/plating/asteroid/airless, -/area/ruin/space/clockwork_monastery) -"XQ" = ( -/obj/machinery/door/airlock/clockwork/glass{ - name = "Meeting Room" - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Yx" = ( -/obj/structure/chair/sofa/pew/clockwork/right{ - dir = 4 - }, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"YX" = ( -/obj/structure/table/reinforced/brass, -/obj/item/storage/firstaid/adv, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) -"Zu" = ( -/obj/item/pickaxe, -/turf/simulated/floor/plating/asteroid/airless, -/area/ruin/unpowered) -"Zz" = ( -/obj/structure/shelf/clockwork, -/obj/item/reagent_containers/glass/bottle/copper, -/obj/item/reagent_containers/glass/bottle/copper, -/obj/item/reagent_containers/glass/bottle/copper, -/obj/item/reagent_containers/glass/bottle/copper, -/obj/item/reagent_containers/glass/bottle/copper, -/obj/item/reagent_containers/glass/bottle/copper, -/obj/machinery/light/clockwork/small, -/turf/simulated/floor/clockwork, -/area/ruin/space/clockwork_monastery) - -(1,1,1) = {" -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -Ht -Ht -Ht -Ht -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -dx -dx -dx -dx -dx -dx -dx -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(2,1,1) = {" -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -Ht -Ht -Ht -Ht -Ht -Ht -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -dx -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(3,1,1) = {" -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -Ht -Ht -Ht -Ht -Ht -Ht -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -dx -dx -dx -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(4,1,1) = {" -gV -gV -gV -gV -gV -gV -gV -dx -dx -gV -gV -gV -Ht -Ht -Ht -Ht -Ht -gV -gV -gV -gV -gV -gV -gV -dx -dx -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -oW -oW -oW -oW -oW -Ht -Ht -Ht -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(5,1,1) = {" -gV -gV -Ht -gV -gV -gV -dx -dx -dx -dx -gV -gV -gV -Ht -Ht -Ht -Ht -Ht -gV -gV -gV -gV -gV -gV -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -Rv -rJ -rJ -rJ -Rv -oW -oW -Ht -Ht -dx -dx -dx -dx -dx -gV -gV -gV -dx -dx -dx -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(6,1,1) = {" -gV -gV -gV -gV -gV -gV -dx -ch -ch -dx -gV -gV -gV -gV -Ht -Ht -Ht -Ht -gV -gV -gV -gV -gV -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -rJ -rJ -rJ -rJ -rJ -rJ -rJ -oW -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -dx -gV -dx -Ht -Ht -Ht -dx -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(7,1,1) = {" -gV -gV -gV -gV -gV -gV -gV -ch -ch -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -eg -rJ -bg -EQ -bg -rJ -ME -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -dx -Ht -Ht -Ht -Ht -Ht -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -"} -(8,1,1) = {" -gV -gV -gV -Ht -gV -gV -gV -kC -ch -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -dx -dx -dx -Ht -Ht -Ht -oW -oW -oW -oW -Ht -Ht -oW -rJ -rJ -MU -rM -yy -rJ -rJ -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -gV -gV -gV -gV -gV -gV -gV -gV -"} -(9,1,1) = {" -gV -gV -gV -gV -gV -gV -kC -kC -ch -ch -dx -kC -gV -gV -gV -dx -dx -dx -dx -gV -gV -dx -Ht -Ht -Ht -Ht -oW -oW -NV -of -oW -oW -Ht -oW -rJ -rJ -MU -Rw -yy -rJ -rJ -oW -Ht -oW -oW -oW -oW -oW -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -"} -(10,1,1) = {" -gV -gV -gV -gV -gV -dx -kC -kC -kC -ch -ch -kC -kC -dx -dx -dx -Ht -Ht -dx -dx -dx -dx -Ht -Ht -Ht -oW -oW -bW -bW -bW -bW -oW -oW -oW -eg -rJ -MU -Ku -yy -rJ -ME -oW -oW -oW -Yx -pp -pp -NF -oW -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(11,1,1) = {" -gV -gV -gV -gV -dx -dx -ch -kC -kC -kC -kC -kC -kC -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -CB -rJ -rJ -rJ -rJ -Ki -oW -oW -rJ -rJ -MU -zQ -yy -rJ -rJ -oW -oW -CB -rJ -mn -mn -rJ -Ki -oW -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -dx -gV -gV -gV -gV -gV -gV -gV -"} -(12,1,1) = {" -gV -gV -gV -dx -dx -ch -ch -ch -kC -kC -kC -kC -kC -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -jC -rJ -rJ -rJ -rJ -rJ -rJ -rJ -hV -rJ -rJ -MU -rM -yy -rJ -rJ -oW -vc -rJ -rJ -rJ -rJ -rJ -rJ -HB -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -gV -gV -gV -gV -gV -gV -gV -"} -(13,1,1) = {" -gV -gV -gV -dx -ch -ch -ch -ch -ch -ch -kC -kC -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -hW -jC -rJ -rJ -bg -bg -rJ -rJ -rJ -oW -eg -rJ -bg -CW -bg -rJ -ME -oW -Az -mn -rJ -bg -bg -rJ -mn -KZ -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -gV -gV -gV -gV -gV -gV -"} -(14,1,1) = {" -gV -gV -dx -dx -ch -ch -ch -ch -ch -kC -kC -kC -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -uz -jC -rJ -rJ -bg -bg -rJ -rJ -rJ -oW -rJ -rJ -rJ -rJ -rJ -rJ -rJ -oW -Az -mn -rJ -bg -bg -rJ -mn -KZ -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -gV -gV -gV -gV -gV -gV -"} -(15,1,1) = {" -gV -gV -dx -dx -ch -ch -ch -ch -kC -kC -kC -Zu -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -CI -jC -rJ -rJ -rJ -rJ -rJ -rJ -Ki -oW -oW -rJ -rJ -rJ -rJ -rJ -oW -oW -CG -rJ -rJ -rJ -rJ -rJ -rJ -ly -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -gV -gV -gV -gV -gV -gV -"} -(16,1,1) = {" -gV -gV -gV -dx -ch -ch -ch -ch -kC -kC -kC -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -jC -rJ -rJ -rJ -rJ -rJ -rJ -Bo -Bo -oW -oW -Bo -XQ -Bo -oW -oW -oW -oW -rJ -rJ -rJ -rJ -rJ -rJ -oW -oW -oW -oW -oW -oW -oW -oW -oW -Ht -Ht -Ht -dx -dx -gV -gV -gV -gV -gV -"} -(17,1,1) = {" -gV -gV -gV -dx -ch -ch -ch -kC -kC -kC -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -rJ -rJ -rJ -rJ -rJ -Bo -Bo -ka -rJ -rJ -rJ -rJ -rJ -rJ -rJ -ka -oW -oW -rJ -rJ -rJ -yH -rJ -oW -rJ -rJ -Rv -rJ -rJ -Rv -mn -oW -oW -ch -ch -ch -dx -dx -dx -dx -gV -gV -"} -(18,1,1) = {" -gV -gV -gV -dx -ch -ch -ch -Ht -kC -Ht -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -oW -oW -oW -oW -oW -rJ -Bo -Bo -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -oW -oW -aj -Wl -oW -sc -oW -rJ -rJ -rJ -vc -rJ -rJ -rJ -mn -oW -sT -ch -ch -ch -ch -Ht -dx -gV -gV -"} -(19,1,1) = {" -gV -gV -gV -dx -Ht -Ht -Ht -Ht -AA -Ht -dx -Ht -oW -oW -oW -oW -oW -oW -oW -oW -oW -oW -oW -Rv -rJ -rJ -rJ -Rv -oW -sZ -Bo -rJ -rJ -Lh -rJ -rJ -rJ -Lh -rJ -rJ -rJ -Lh -rJ -rJ -oW -oW -oW -oW -rJ -rJ -rJ -vc -rJ -Az -rJ -rJ -rJ -rJ -sZ -ow -ch -ch -Jm -ch -ch -dx -dx -gV -"} -(20,1,1) = {" -gV -gV -gV -dx -dx -Ht -Ht -kC -kC -kC -dx -oW -oW -Lh -Iw -Lh -Iw -Lh -mn -Lh -oW -oW -rJ -rJ -bg -bg -bg -rJ -rJ -oW -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -oW -oW -eg -rJ -vc -rJ -Az -rJ -Az -rJ -RD -rJ -rJ -sZ -ow -Jm -Jm -Jm -ch -ch -Ht -dx -dx -"} -(21,1,1) = {" -gV -gV -gV -gV -dx -Ht -kC -kC -kC -zG -oW -oW -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -oW -rJ -bg -bg -bg -bg -bg -RD -oW -rJ -rJ -rJ -rJ -rJ -Vh -Mc -Mc -Mc -De -rJ -rJ -rJ -rJ -rJ -oW -WR -rJ -rJ -vU -rJ -vU -rJ -vU -rJ -rJ -rJ -rJ -sZ -ow -Jm -Jm -Jm -Jm -ch -Ht -Ht -dx -"} -(22,1,1) = {" -gV -gV -gV -gV -yp -Ht -kC -kC -kC -Xw -HF -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -eS -rJ -bg -bg -bg -bg -bg -rJ -oc -rJ -rJ -rJ -rJ -Vh -jq -jq -jq -jq -jq -De -rJ -rJ -rJ -rJ -Xk -bg -bg -bg -bg -bg -bg -bg -bg -bg -rM -rJ -rJ -sZ -ow -Jm -Jm -Jm -Jm -Jm -Ht -Ht -dx -"} -(23,1,1) = {" -gV -gV -gV -gV -yp -Ht -Ht -kC -kC -Xw -HF -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -eS -rJ -bg -bg -bg -bg -bg -rJ -oc -rJ -rJ -rJ -rJ -pe -jq -jq -jq -jq -jq -qc -rJ -rJ -rJ -rJ -Xk -bg -bg -bg -bg -bg -bg -bg -bg -bg -rM -rJ -rJ -sZ -ow -Jm -Jm -Jm -Jm -Jm -Ht -Ht -dx -"} -(24,1,1) = {" -gV -gV -gV -gV -dx -Ht -Ht -kC -kC -zG -oW -oW -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -oW -rJ -bg -bg -bg -bg -bg -RD -oW -rJ -rJ -rJ -rJ -rJ -pe -xp -xp -xp -qc -rJ -rJ -rJ -rJ -rJ -oW -WR -rJ -rJ -vc -rJ -vc -rJ -vc -rJ -rJ -rJ -rJ -sZ -ow -Jm -Jm -Jm -Jm -Jm -Ht -Ht -dx -"} -(25,1,1) = {" -gV -gV -gV -dx -dx -Ht -Ht -Ht -kC -kC -dx -oW -oW -Lh -Iw -Lh -Iw -Lh -mn -Lh -oW -oW -rJ -rJ -bg -bg -bg -rJ -rJ -oW -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -oW -oW -eg -rJ -vU -rJ -Az -rJ -Az -rJ -RD -rJ -rJ -sZ -ow -Jm -Jm -Jm -ch -ch -Ht -Ht -dx -"} -(26,1,1) = {" -gV -gV -gV -dx -Ht -Ht -Ht -Ht -AA -Ht -dx -Ht -oW -oW -oW -oW -oW -oW -oW -oW -oW -oW -oW -zC -rJ -rJ -rJ -zC -oW -Bo -Bo -rJ -rJ -Lh -rJ -rJ -rJ -Lh -rJ -rJ -rJ -Lh -rJ -rJ -oW -oW -oW -oW -rJ -rJ -rJ -vU -rJ -Az -rJ -rJ -rJ -rJ -sZ -ow -ch -Jm -Jm -ch -ch -Ht -dx -dx -"} -(27,1,1) = {" -gV -gV -gV -dx -Ht -Ht -Ht -Ht -kC -Ht -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -oW -oW -oW -oW -oW -rJ -Bo -Bo -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -rJ -oW -oW -Yx -NF -oW -Em -oW -rJ -rJ -rJ -vU -rJ -rJ -rJ -mn -oW -sT -ch -ch -ch -ch -ch -Ht -dx -gV -"} -(28,1,1) = {" -gV -gV -gV -dx -ch -ch -ch -kC -kC -kC -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -rJ -rJ -rJ -rJ -rJ -rJ -Bo -Bo -pI -rJ -rJ -rJ -rJ -rJ -rJ -rJ -pI -oW -oW -rJ -rJ -rJ -Gb -rJ -oW -rJ -rJ -zC -rJ -rJ -zC -mn -oW -oW -ch -ch -ch -Ht -ch -ch -Ht -dx -gV -"} -(29,1,1) = {" -gV -gV -dx -dx -ch -ch -ch -kC -kC -kC -kC -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -rJ -rJ -rJ -rJ -rJ -rJ -rJ -Bo -sZ -oW -oW -Bo -Ev -Bo -oW -oW -oW -oW -rJ -rJ -rJ -rJ -rJ -rJ -oW -oW -oW -oW -oW -oW -oW -oW -oW -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -dx -gV -"} -(30,1,1) = {" -gV -gV -dx -ch -ch -ch -ch -ch -kC -kC -kC -kC -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -NQ -rJ -rJ -rJ -ua -ua -rJ -rJ -Zz -oW -oW -Rv -rJ -rJ -rJ -Rv -oW -oW -YX -rJ -rJ -rJ -rJ -rJ -rJ -RE -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -dx -dx -gV -gV -gV -"} -(31,1,1) = {" -gV -gV -dx -ch -ch -ch -ch -ch -ch -ch -kC -kC -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -rb -rJ -rJ -Jx -Ie -VU -rJ -rJ -sg -oW -rJ -rJ -rJ -rJ -rJ -rJ -rJ -oW -dd -rJ -rJ -bg -bg -rJ -mn -KZ -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -gV -gV -gV -gV -gV -gV -"} -(32,1,1) = {" -gV -gV -dx -dx -ch -ch -ch -ch -ch -kC -kC -kC -kC -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -NC -rJ -rJ -Jx -Sq -Ea -rJ -rJ -EN -oW -eg -rJ -ua -ua -ua -rJ -ME -oW -uH -rJ -rJ -bg -bg -rJ -mn -KZ -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -dx -gV -gV -gV -gV -gV -gV -"} -(33,1,1) = {" -gV -gV -gV -dx -ch -ch -ch -kC -kC -kC -kC -ch -ch -ch -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -CB -rJ -rJ -rJ -rJ -rJ -rJ -rJ -xv -rJ -Jx -yn -yn -yn -Ib -rJ -oW -cK -rJ -rJ -rJ -rJ -rJ -rJ -JU -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -"} -(34,1,1) = {" -gV -gV -gV -dx -ch -ch -kC -kC -kC -kC -ch -ch -ch -ch -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -rJ -rJ -rJ -rJ -rJ -CH -oW -oW -rJ -Jx -yn -yn -yn -Ib -rJ -oW -oW -CB -rJ -rJ -rJ -rJ -Ki -oW -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(35,1,1) = {" -gV -gV -gV -dx -kC -kC -kC -kC -kC -kC -kC -kC -ch -ch -ch -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -GE -rJ -rJ -GF -oW -oW -oW -rJ -rJ -lN -lN -lN -rJ -rJ -oW -oW -oW -ei -rJ -rJ -ei -oW -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -"} -(36,1,1) = {" -gV -gV -gV -gV -kC -kC -kC -ch -Zu -kC -kC -kC -kC -kC -kC -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -bt -IL -oW -oW -Ht -oW -bf -rJ -rJ -rJ -rJ -rJ -rJ -oW -Ht -oW -oW -oW -oW -oW -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -gV -gV -gV -gV -gV -gV -gV -gV -"} -(37,1,1) = {" -gV -gV -gV -gV -gV -kC -ch -ch -ch -ch -kC -kC -kC -kC -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -oW -oW -oW -Ht -Ht -oW -bf -rJ -rJ -rJ -rJ -rJ -rJ -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -"} -(38,1,1) = {" -gV -gV -gV -gV -gV -dx -dx -dx -dx -dx -dx -kC -kC -kC -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -Gw -rJ -rJ -rJ -rJ -rJ -kZ -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(39,1,1) = {" -gV -gV -gV -gV -gV -gV -dx -gV -gV -gV -dx -kC -kC -dx -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -oW -jP -rJ -rJ -rJ -rJ -rJ -jP -oW -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(40,1,1) = {" -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -dx -dx -dx -Ht -dx -dx -dx -dx -gV -gV -dx -dx -dx -Ht -Ht -Ht -Ht -Ht -oW -oW -pE -jP -hk -jP -pE -oW -oW -Ht -Ht -Ht -dx -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(41,1,1) = {" -gV -gV -gV -gV -gV -gV -gV -gV -Ht -gV -gV -gV -gV -gV -gV -gV -gV -dx -dx -dx -gV -gV -gV -gV -gV -gV -gV -dx -dx -dx -dx -dx -Ht -Ht -oW -oW -oW -oW -oW -oW -oW -Ht -Ht -dx -dx -dx -gV -dx -dx -dx -dx -dx -dx -Ht -dx -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(42,1,1) = {" -gV -gV -gV -gV -gV -gV -gV -Ht -Ht -Ht -Ht -Ht -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -dx -dx -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -dx -Ht -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(43,1,1) = {" -gV -gV -gV -gV -gV -gV -gV -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -Ht -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -dx -dx -Ht -Ht -Ht -Ht -Ht -dx -dx -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -dx -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} -(44,1,1) = {" -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -Ht -Ht -Ht -Ht -Ht -Ht -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -dx -dx -dx -dx -dx -dx -dx -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -gV -"} diff --git a/_maps/map_files/RandomRuins/SpaceRuins/derelict2.dmm b/_maps/map_files/RandomRuins/SpaceRuins/derelict2.dmm deleted file mode 100644 index 48611f97b243f..0000000000000 --- a/_maps/map_files/RandomRuins/SpaceRuins/derelict2.dmm +++ /dev/null @@ -1,494 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"b" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/turf/template_noop, -/area/space/nearstation) -"c" = ( -/obj/machinery/door/airlock/external, -/turf/simulated/floor/plating, -/area/ruin/space/powered) -"d" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/template_noop, -/area/space/nearstation) -"e" = ( -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/plating, -/area/ruin/space/powered) -"f" = ( -/turf/simulated/wall, -/area/ruin/space/powered) -"g" = ( -/obj/effect/spawner/window/reinforced/grilled, -/turf/simulated/floor/plating, -/area/ruin/space/powered) -"i" = ( -/turf/simulated/floor/plasteel, -/area/ruin/space/powered) -"k" = ( -/obj/structure/window/reinforced{ - dir = 4 - }, -/turf/template_noop, -/area/space/nearstation) -"l" = ( -/obj/structure/window/reinforced, -/obj/structure/window/reinforced{ - dir = 1 - }, -/turf/simulated/floor/plating, -/area/ruin/space/powered) -"m" = ( -/obj/structure/chair{ - dir = 4 - }, -/obj/effect/decal/remains/human, -/mob/living/simple_animal/hostile/retaliate/ghost, -/turf/simulated/floor/plasteel, -/area/ruin/space/powered) -"n" = ( -/obj/structure/table, -/obj/item/candle{ - pixel_y = 5 - }, -/obj/item/trash/plate{ - pixel_x = 10 - }, -/obj/item/trash/plate{ - pixel_x = -10 - }, -/obj/item/food/burger/ghost, -/turf/simulated/floor/plasteel, -/area/ruin/space/powered) -"o" = ( -/obj/structure/chair{ - dir = 8 - }, -/obj/effect/decal/remains/human, -/mob/living/simple_animal/hostile/retaliate/ghost, -/turf/simulated/floor/plasteel, -/area/ruin/space/powered) -"p" = ( -/obj/structure/window/reinforced, -/turf/template_noop, -/area/space/nearstation) -"q" = ( -/obj/structure/cult/functional/pylon, -/turf/simulated/floor/plasteel, -/area/ruin/space/powered) -"r" = ( -/obj/item/salvage/ruin/tablet, -/turf/simulated/floor/plasteel, -/area/ruin/space/powered) - -(1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -a -a -a -a -a -a -a -p -c -b -a -a -a -a -a -a -a -a -"} -(3,1,1) = {" -a -a -a -a -a -a -a -a -p -l -b -a -a -a -a -a -a -a -a -"} -(4,1,1) = {" -a -a -a -a -a -a -a -a -p -l -b -a -a -a -a -a -a -a -a -"} -(5,1,1) = {" -a -a -a -a -a -a -a -a -p -l -b -a -a -a -a -a -a -a -a -"} -(6,1,1) = {" -a -a -a -a -a -a -a -f -g -c -g -f -a -a -a -a -a -a -a -"} -(7,1,1) = {" -a -a -a -a -a -a -f -i -i -i -i -i -f -a -a -a -a -a -a -"} -(8,1,1) = {" -a -a -a -a -a -f -i -q -i -i -i -q -i -f -a -a -a -a -a -"} -(9,1,1) = {" -a -k -k -k -k -g -i -i -i -m -i -r -i -g -k -k -k -k -a -"} -(10,1,1) = {" -a -c -e -e -e -c -i -i -i -n -i -i -i -c -e -e -e -c -a -"} -(11,1,1) = {" -a -d -d -d -d -g -i -r -i -o -i -i -i -g -d -d -d -d -a -"} -(12,1,1) = {" -a -a -a -a -a -f -i -q -i -i -i -q -i -f -a -a -a -a -a -"} -(13,1,1) = {" -a -a -a -a -a -a -f -i -i -i -i -i -f -a -a -a -a -a -a -"} -(14,1,1) = {" -a -a -a -a -a -a -a -f -g -c -g -f -a -a -a -a -a -a -a -"} -(15,1,1) = {" -a -a -a -a -a -a -a -a -p -l -b -a -a -a -a -a -a -a -a -"} -(16,1,1) = {" -a -a -a -a -a -a -a -a -p -l -b -a -a -a -a -a -a -a -a -"} -(17,1,1) = {" -a -a -a -a -a -a -a -a -p -l -b -a -a -a -a -a -a -a -a -"} -(18,1,1) = {" -a -a -a -a -a -a -a -a -p -c -b -a -a -a -a -a -a -a -a -"} -(19,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} diff --git a/_maps/map_files/RandomRuins/SpaceRuins/golemtarget.dmm b/_maps/map_files/RandomRuins/SpaceRuins/golemtarget.dmm deleted file mode 100644 index 7c70a1ef19160..0000000000000 --- a/_maps/map_files/RandomRuins/SpaceRuins/golemtarget.dmm +++ /dev/null @@ -1,1042 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"x" = ( -/turf/simulated/mineral/random/high_chance, -/area/ruin/space/unpowered) -"H" = ( -/turf/simulated/floor/plating/asteroid/airless, -/area/ruin/space/unpowered) -"S" = ( -/obj/docking_port/stationary{ - dir = 8; - dwidth = 8; - height = 20; - id = "freegolem_space"; - name = "The middle of space"; - width = 16 - }, -/turf/template_noop, -/area/template_noop) - -(1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -x -H -x -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(3,1,1) = {" -a -H -x -x -x -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(4,1,1) = {" -a -a -x -x -x -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(5,1,1) = {" -a -a -a -x -x -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(6,1,1) = {" -a -a -a -a -x -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(7,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(8,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(9,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(10,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(11,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(12,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(13,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(14,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(15,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(16,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(17,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(18,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(19,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(20,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(21,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -x -a -a -a -"} -(22,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -x -x -x -a -a -"} -(23,1,1) = {" -a -a -a -a -x -H -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -x -x -x -a -a -"} -(24,1,1) = {" -a -a -a -x -x -x -H -a -a -a -a -a -a -a -a -a -a -S -a -a -a -a -a -a -a -a -x -x -x -x -x -a -"} -(25,1,1) = {" -a -a -a -a -x -x -x -H -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -x -x -x -x -a -"} -(26,1,1) = {" -a -a -a -a -a -x -x -H -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(27,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -H -x -x -x -x -a -a -a -a -a -a -a -a -a -a -a -a -"} -(28,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -H -x -x -x -x -x -a -a -a -a -a -a -a -a -a -a -a -a -"} -(29,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -x -H -x -x -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(30,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} diff --git a/_maps/map_files/RandomRuins/SpaceRuins/rocky_motel.jsonc b/_maps/map_files/RandomRuins/SpaceRuins/rocky_motel.jsonc deleted file mode 100644 index 7d858c66b30a4..0000000000000 --- a/_maps/map_files/RandomRuins/SpaceRuins/rocky_motel.jsonc +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - // Submap of Rocky Motel with a pod crashed into it - "type": "SubmapExtractInsert", - "submap_size_x": 13, - "submap_size_y": 10, - "submap_size_z": 1, - "submaps_dmm": "submaps/rocky_motel_submap.dmm", - "marker_extract": "/obj/effect/map_effect/marker/mapmanip/submap/extract/space_ruin/rocky_motel/drunk_accident", - "marker_insert": "/obj/effect/map_effect/marker/mapmanip/submap/insert/space_ruin/rocky_motel/drunk_accident", - "submaps_can_repeat": true // doesn't matter, as there's only one insert marker - } - -] diff --git a/_maps/map_files/RandomRuins/SpaceRuins/voyager.dmm b/_maps/map_files/RandomRuins/SpaceRuins/voyager.dmm deleted file mode 100644 index 456b85f46a687..0000000000000 --- a/_maps/map_files/RandomRuins/SpaceRuins/voyager.dmm +++ /dev/null @@ -1,132 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/obj/structure/lattice, -/obj/structure/window/full/shuttle{ - name = "satellite lense" - }, -/turf/template_noop, -/area/template_noop) -"c" = ( -/obj/structure/safe/floor, -/obj/item/golden_record, -/turf/simulated/wall/satellite, -/area/template_noop) -"e" = ( -/turf/template_noop, -/area/template_noop) -"k" = ( -/obj/machinery/power/solar, -/obj/structure/lattice, -/turf/template_noop, -/area/template_noop) -"q" = ( -/obj/structure/target_stake{ - name = "low gain antenna"; - anchored = 1 - }, -/turf/template_noop, -/area/template_noop) -"O" = ( -/obj/structure/lattice, -/obj/machinery/power/solar, -/turf/template_noop, -/area/template_noop) -"R" = ( -/mob/living/simple_animal/hostile/carp, -/turf/template_noop, -/area/template_noop) -"S" = ( -/obj/structure/lattice, -/turf/template_noop, -/area/template_noop) - -(1,1,1) = {" -e -e -e -e -e -e -e -e -"} -(2,1,1) = {" -e -e -O -e -e -e -R -e -"} -(3,1,1) = {" -e -e -k -e -e -e -e -e -"} -(4,1,1) = {" -e -e -O -e -e -e -e -e -"} -(5,1,1) = {" -e -q -c -a -S -S -S -e -"} -(6,1,1) = {" -e -e -k -e -e -e -e -e -"} -(7,1,1) = {" -e -e -k -e -e -e -e -e -"} -(8,1,1) = {" -e -e -k -e -e -e -e -e -"} -(9,1,1) = {" -e -e -e -e -e -e -e -e -"} diff --git a/_maps/map_files/RandomRuins/SpaceRuins/way_home.dmm b/_maps/map_files/RandomRuins/SpaceRuins/way_home.dmm deleted file mode 100644 index 08847e70aa1cd..0000000000000 --- a/_maps/map_files/RandomRuins/SpaceRuins/way_home.dmm +++ /dev/null @@ -1,1066 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"b" = ( -/turf/simulated/mineral/random, -/area/ruin/space/unpowered/no_grav/way_home) -"c" = ( -/turf/simulated/floor/plating/asteroid/airless, -/area/ruin/space/unpowered/no_grav/way_home) -"d" = ( -/obj/structure/signpost{ - name = "salvation" - }, -/turf/simulated/floor/plating/asteroid/airless, -/area/ruin/space/unpowered/no_grav/way_home) -"g" = ( -/obj/structure/spawner/mining/hivelord, -/turf/simulated/floor/plating/asteroid/airless, -/area/ruin/space/unpowered/no_grav/way_home) -"n" = ( -/turf/simulated/mineral/random/high_chance/clown, -/area/ruin/space/unpowered/no_grav/way_home) -"s" = ( -/mob/living/simple_animal/hostile/carp/megacarp, -/turf/template_noop, -/area/template_noop) -"z" = ( -/obj/structure/spawner/mining/basilisk, -/turf/simulated/floor/plating/asteroid/airless, -/area/ruin/space/unpowered/no_grav/way_home) -"O" = ( -/obj/item/salvage/ruin/tablet, -/turf/simulated/floor/plating/asteroid/airless, -/area/ruin/space/unpowered/no_grav/way_home) -"P" = ( -/mob/living/simple_animal/hostile/carp, -/turf/template_noop, -/area/template_noop) -"R" = ( -/turf/simulated/mineral/random/high_chance, -/area/ruin/space/unpowered/no_grav/way_home) - -(1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -P -a -a -"} -(3,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -R -R -a -a -a -a -"} -(4,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -R -R -R -a -a -a -"} -(5,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -R -a -a -P -a -"} -(6,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(7,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -b -b -a -a -a -a -a -a -a -a -a -a -a -a -P -a -a -a -"} -(8,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -b -b -R -b -b -b -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(9,1,1) = {" -a -a -a -a -a -a -a -a -a -a -b -R -R -R -R -b -b -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(10,1,1) = {" -a -a -a -a -a -a -a -a -b -b -b -b -R -R -b -b -a -a -P -a -a -a -a -a -a -a -a -a -a -a -a -"} -(11,1,1) = {" -a -a -a -a -a -b -a -b -b -b -b -b -b -R -b -c -a -a -a -a -a -s -a -a -a -a -a -a -a -a -a -"} -(12,1,1) = {" -a -a -a -a -a -b -b -b -b -R -R -b -b -b -b -c -c -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(13,1,1) = {" -a -a -a -a -a -b -b -b -R -R -b -b -b -b -c -c -c -a -a -a -a -a -a -a -P -a -a -a -a -a -a -"} -(14,1,1) = {" -a -a -a -a -b -b -b -R -R -b -b -b -b -b -c -g -c -c -c -c -a -a -a -a -a -a -a -a -a -a -a -"} -(15,1,1) = {" -a -a -a -b -b -b -R -R -b -R -b -b -c -c -c -c -c -c -c -c -c -c -a -a -a -a -a -b -a -a -a -"} -(16,1,1) = {" -a -a -a -a -b -b -b -b -b -b -b -c -O -c -a -a -c -c -d -c -c -c -c -c -c -a -b -b -a -a -a -"} -(17,1,1) = {" -a -a -a -a -a -b -b -b -b -b -b -b -c -a -a -a -a -c -c -O -c -c -c -b -b -b -b -a -a -a -a -"} -(18,1,1) = {" -a -a -a -a -a -b -b -b -b -b -b -b -a -a -a -a -a -a -c -c -c -b -b -b -n -b -b -a -a -a -a -"} -(19,1,1) = {" -a -a -a -a -a -b -b -a -a -b -b -b -a -a -a -a -a -a -a -c -c -z -b -R -n -n -b -a -a -a -a -"} -(20,1,1) = {" -a -a -a -a -a -a -a -a -a -a -b -a -a -a -a -a -a -a -a -a -c -c -c -b -n -n -b -b -a -a -a -"} -(21,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -c -b -b -n -n -b -a -a -a -"} -(22,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -b -b -b -b -a -a -a -"} -(23,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -b -b -a -a -a -a -"} -(24,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -R -R -a -a -a -"} -(25,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(26,1,1) = {" -a -a -P -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(27,1,1) = {" -a -a -a -P -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(28,1,1) = {" -a -a -a -P -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(29,1,1) = {" -a -a -P -P -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(30,1,1) = {" -a -s -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(31,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} diff --git a/_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm b/_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm deleted file mode 100644 index 465768cd28533..0000000000000 --- a/_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm +++ /dev/null @@ -1,748 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"at" = ( -/obj/structure/sign/vacuum/external{ - pixel_y = -32 - }, -/obj/effect/spawner/random/dirt/often, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"cf" = ( -/obj/effect/spawner/random/oil/often, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"cA" = ( -/obj/structure/table, -/obj/item/scalpel{ - pixel_y = 7 - }, -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/abandoned) -"em" = ( -/obj/effect/spawner/airlock/w_to_e/long/square, -/turf/simulated/wall/mineral/titanium, -/area/shuttle/abandoned) -"eo" = ( -/obj/structure/sign/greencross, -/turf/simulated/wall/mineral/titanium, -/area/shuttle/abandoned) -"ez" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 5 - }, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"eE" = ( -/obj/machinery/computer/nonfunctional{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium, -/area/shuttle/abandoned) -"eW" = ( -/obj/structure/table, -/obj/item/radio{ - pixel_x = -6; - pixel_y = 6 - }, -/obj/item/radio{ - pixel_y = 4 - }, -/obj/item/radio{ - pixel_x = 6; - pixel_y = 6 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"fI" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 - }, -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"gd" = ( -/obj/machinery/door/airlock/titanium/glass, -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/abandoned) -"hz" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 4; - icon_state = "burst_r" - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/abandoned) -"jk" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"jn" = ( -/obj/machinery/door/airlock/titanium/glass, -/turf/simulated/floor/wood, -/area/shuttle/abandoned) -"ka" = ( -/turf/simulated/floor/wood, -/area/shuttle/abandoned) -"kO" = ( -/obj/structure/sign/poster/official/random{ - pixel_y = 32 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"nC" = ( -/obj/structure/table, -/obj/item/storage/firstaid/regular, -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/abandoned) -"oh" = ( -/obj/structure/table, -/obj/item/tank/internals/oxygen{ - pixel_y = 1; - pixel_x = -2 - }, -/obj/item/tank/internals/oxygen{ - pixel_x = 3; - pixel_y = 1 - }, -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/abandoned) -"qm" = ( -/turf/simulated/wall/mineral/titanium/nodiagonal, -/area/shuttle/abandoned) -"qF" = ( -/obj/machinery/economy/vending/coffee, -/turf/simulated/floor/wood, -/area/shuttle/abandoned) -"qK" = ( -/obj/structure/table/reinforced, -/obj/item/whiteship_port_generator, -/turf/simulated/floor/mineral/plastitanium, -/area/shuttle/abandoned) -"ri" = ( -/obj/structure/table, -/obj/item/storage/toolbox/mechanical, -/obj/item/multitool{ - pixel_x = -6 - }, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"rB" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium, -/area/shuttle/abandoned) -"sk" = ( -/obj/structure/sign/poster/official/random{ - pixel_y = -32 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"sm" = ( -/obj/effect/spawner/random/dirt/often, -/obj/machinery/door/airlock/titanium, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"sK" = ( -/obj/structure/table/wood/poker, -/turf/simulated/floor/wood, -/area/shuttle/abandoned) -"tV" = ( -/obj/machinery/door/airlock/multi_tile/glass{ - dir = 1 - }, -/turf/simulated/floor/mineral/plastitanium, -/area/shuttle/abandoned) -"uo" = ( -/obj/structure/table/wood, -/obj/item/flashlight/lamp/green{ - pixel_y = 2 - }, -/turf/simulated/floor/wood, -/area/shuttle/abandoned) -"ux" = ( -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"uA" = ( -/obj/structure/extinguisher_cabinet{ - name = "north bump"; - pixel_y = 30 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"vz" = ( -/obj/effect/spawner/random/dirt/often, -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"vB" = ( -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"wh" = ( -/obj/machinery/door/airlock/titanium/glass, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"ws" = ( -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/abandoned) -"wF" = ( -/turf/simulated/floor/mineral/plastitanium, -/area/shuttle/abandoned) -"wN" = ( -/obj/structure/rack, -/obj/item/stack/sheet/glass{ - amount = 10; - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/stack/sheet/metal{ - amount = 10 - }, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"xz" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/mob/living/simple_animal/hostile/pirate, -/turf/simulated/floor/mineral/plastitanium, -/area/shuttle/abandoned) -"ys" = ( -/obj/structure/table, -/obj/item/storage/box/lights/mixed, -/obj/item/stock_parts/cell{ - charge = 100; - maxcharge = 15000; - pixel_x = -3; - pixel_y = -3 - }, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"yC" = ( -/obj/docking_port/stationary/whiteship{ - dir = 8; - id = "whiteship_away"; - name = "Deep Space" - }, -/obj/docking_port/mobile{ - dir = 8; - id = "whiteship"; - name = "NEV Cherub"; - dwidth = 6; - height = 19; - width = 12 - }, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"yF" = ( -/obj/machinery/light/small, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"zH" = ( -/obj/machinery/light/small, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"zM" = ( -/turf/template_noop, -/area/template_noop) -"zO" = ( -/turf/simulated/wall/mineral/titanium, -/area/shuttle/abandoned) -"zV" = ( -/obj/structure/closet/crate, -/obj/item/flashlight/flare, -/obj/item/flashlight/flare, -/obj/item/flashlight/flare, -/obj/item/flashlight/flare/glowstick/blue, -/obj/item/flashlight/flare/glowstick/blue, -/obj/item/flashlight/flare/glowstick/blue, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"AS" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/item/salvage/ruin/pirate, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"Ct" = ( -/obj/structure/table/wood/poker, -/obj/item/deck/cards, -/turf/simulated/floor/wood, -/area/shuttle/abandoned) -"CE" = ( -/obj/structure/shuttle/engine/heater{ - dir = 4 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/abandoned) -"Fr" = ( -/obj/effect/spawner/window/shuttle, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"Gs" = ( -/obj/structure/table/reinforced, -/obj/item/analyzer, -/turf/simulated/floor/mineral/plastitanium, -/area/shuttle/abandoned) -"GX" = ( -/obj/machinery/atmospherics/pipe/simple/hidden, -/obj/machinery/door/airlock/titanium, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"Jf" = ( -/obj/structure/chair/wood, -/turf/simulated/floor/wood, -/area/shuttle/abandoned) -"Kd" = ( -/obj/effect/spawner/random/dirt/often, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"KX" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/abandoned) -"Mj" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/shuttle/abandoned) -"Mp" = ( -/obj/effect/turf_decal/delivery/hollow, -/obj/structure/closet, -/obj/item/gps/ruin{ - gpstag = "NT Medical Ship"; - pixel_x = -32 - }, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"ML" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 6 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/abandoned) -"Of" = ( -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/abandoned) -"Pe" = ( -/obj/structure/chair/wood, -/obj/structure/sign/poster/contraband/random{ - pixel_y = 32 - }, -/turf/simulated/floor/wood, -/area/shuttle/abandoned) -"Pi" = ( -/obj/structure/closet/crate/can, -/turf/simulated/floor/wood, -/area/shuttle/abandoned) -"Pu" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/effect/spawner/random/dirt/often, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"Ro" = ( -/obj/structure/chair/wood{ - dir = 8 - }, -/turf/simulated/floor/wood, -/area/shuttle/abandoned) -"SS" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium, -/area/shuttle/abandoned) -"Vd" = ( -/obj/effect/spawner/random/dirt/often, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"VD" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"WJ" = ( -/obj/machinery/atmospherics/unary/portables_connector{ - dir = 8 - }, -/obj/machinery/atmospherics/portable/canister/air, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"WX" = ( -/obj/machinery/sleeper{ - dir = 4 - }, -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/abandoned) -"Xq" = ( -/obj/effect/turf_decal/delivery/hollow, -/obj/structure/closet, -/turf/simulated/floor/plating, -/area/shuttle/abandoned) -"Yr" = ( -/obj/machinery/computer/shuttle/white_ship{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium, -/area/shuttle/abandoned) -"YH" = ( -/obj/structure/table/wood/poker, -/obj/item/gun/energy/laser/retro, -/turf/simulated/floor/wood, -/area/shuttle/abandoned) - -(1,1,1) = {" -zM -zM -zM -zM -zM -zM -zM -zM -zM -zM -zM -zM -zM -zM -"} -(2,1,1) = {" -zM -zM -zM -zM -zM -zO -Fr -Fr -zO -zM -zM -zM -zM -zM -"} -(3,1,1) = {" -zM -zM -zM -zM -zO -zO -eE -Yr -zO -zO -zM -zM -zM -zM -"} -(4,1,1) = {" -zM -zM -zM -zM -zO -Gs -xz -xz -qK -zO -zM -zM -zM -zM -"} -(5,1,1) = {" -zM -zM -zM -zM -zO -rB -wF -wF -SS -zO -zM -zM -zM -zM -"} -(6,1,1) = {" -zM -zM -zO -zO -zO -zO -wF -tV -zO -zO -zO -zO -zM -zM -"} -(7,1,1) = {" -zM -zM -zO -eW -zV -zO -jk -vB -zO -WX -cA -zO -zM -zM -"} -(8,1,1) = {" -zM -zM -zO -AS -vB -wh -vB -vB -zO -Of -Of -zO -zM -zM -"} -(9,1,1) = {" -zM -zO -zO -zO -zO -zO -kO -vB -gd -Of -Of -zO -zO -zM -"} -(10,1,1) = {" -zM -Fr -uo -qF -Pi -zO -uA -vB -eo -ws -Of -nC -zO -zM -"} -(11,1,1) = {" -zM -Fr -ka -ka -ka -jn -vB -yF -zO -KX -KX -oh -zO -zM -"} -(12,1,1) = {" -zM -zO -Pe -sK -YH -zO -vB -vB -zO -zO -zO -zO -zO -zM -"} -(13,1,1) = {" -zM -Fr -Jf -Ct -sK -zO -vB -vB -zO -Mp -VD -Xq -zO -zM -"} -(14,1,1) = {" -zM -Fr -Mj -Ro -Ro -zO -vB -sk -zO -Xq -ux -Xq -zO -zM -"} -(15,1,1) = {" -zM -zO -zO -zO -zO -zO -jk -ML -GX -ez -ux -zO -zO -zM -"} -(16,1,1) = {" -zM -zM -zO -ri -cf -sm -Kd -vz -zO -fI -ux -zO -zM -zM -"} -(17,1,1) = {" -zM -zM -zO -ys -zH -zO -Vd -Vd -em -WJ -wN -zO -zM -zM -"} -(18,1,1) = {" -zM -zM -zO -CE -CE -zO -Vd -Vd -zO -CE -CE -zO -zM -zM -"} -(19,1,1) = {" -zM -zM -zO -hz -hz -zO -Pu -at -zO -hz -hz -zO -zM -zM -"} -(20,1,1) = {" -zM -zM -zM -zM -zM -qm -yC -ux -qm -zM -zM -zM -zM -zM -"} -(21,1,1) = {" -zM -zM -zM -zM -zM -zM -zM -zM -zM -zM -zM -zM -zM -zM -"} diff --git a/_maps/map_files/shuttles/admin_admin.dmm b/_maps/map_files/shuttles/admin_admin.dmm deleted file mode 100644 index 76fd24c72c548..0000000000000 --- a/_maps/map_files/shuttles/admin_admin.dmm +++ /dev/null @@ -1,879 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/space, -/area/space) -"ac" = ( -/turf/simulated/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/administration) -"ad" = ( -/obj/effect/mapping_helpers/airlock/access/all/centcomm/general, -/obj/machinery/door/airlock/external{ - id_tag = "s_docking_airlock"; - name = "Shuttle Hatch" - }, -/obj/structure/fans/tiny, -/turf/simulated/floor/plating, -/area/shuttle/administration) -"ae" = ( -/obj/effect/mapping_helpers/airlock/access/all/centcomm/general, -/obj/machinery/door/airlock/external{ - id_tag = "s_docking_airlock"; - name = "Shuttle Hatch" - }, -/obj/docking_port/mobile{ - dir = 2; - dwidth = 8; - height = 15; - id = "admin"; - name = "admin"; - timid = 1; - width = 18 - }, -/obj/structure/fans/tiny, -/turf/simulated/floor/plating, -/area/shuttle/administration) -"ag" = ( -/obj/machinery/economy/vending/boozeomat, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"ah" = ( -/obj/structure/table/reinforced, -/obj/machinery/chem_dispenser/beer{ - pixel_y = 6 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"ai" = ( -/obj/structure/table/reinforced, -/obj/item/storage/box/drinkingglasses, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aj" = ( -/obj/structure/table/reinforced, -/obj/machinery/chem_dispenser/soda{ - pixel_y = 6 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"al" = ( -/obj/machinery/door_control{ - id = "adminshuttleblast"; - name = "blast door control"; - pixel_x = -30; - req_access = list(101) - }, -/obj/machinery/light{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"am" = ( -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"an" = ( -/obj/machinery/cell_charger, -/obj/structure/table, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"ao" = ( -/obj/item/storage/toolbox/mechanical, -/obj/item/multitool, -/obj/structure/table, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"ap" = ( -/obj/structure/table, -/obj/machinery/recharger{ - pixel_y = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aq" = ( -/obj/machinery/light/spot{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"ar" = ( -/obj/machinery/door/poddoor/preopen{ - id_tag = "adminshuttleblast"; - name = "Blast Doors"; - req_access = list(101) - }, -/obj/effect/mapping_helpers/airlock/access/all/centcomm/general, -/obj/machinery/door/airlock/centcom{ - id_tag = "adminshuttle"; - name = "General Access" - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"as" = ( -/obj/machinery/light/spot{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"at" = ( -/obj/item/stack/sheet/metal, -/obj/structure/table, -/obj/item/stack/sheet/glass{ - pixel_x = 4; - pixel_y = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"au" = ( -/obj/machinery/mecha_part_fabricator/upgraded, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"av" = ( -/obj/machinery/kitchen_machine/microwave/upgraded{ - pixel_x = -4; - pixel_y = 4 - }, -/obj/structure/table, -/obj/structure/window/reinforced{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aw" = ( -/obj/machinery/door/window/classic/reversed{ - name = "bar"; - dir = 2 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"ax" = ( -/obj/structure/table, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"ay" = ( -/obj/item/ashtray/glass, -/obj/structure/table, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"az" = ( -/obj/item/storage/fancy/cigarettes/dromedaryco, -/obj/item/lighter/zippo{ - pixel_x = 5 - }, -/obj/structure/table, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aA" = ( -/obj/machinery/door_control{ - id = "adminshuttleblast"; - name = "blast door control"; - pixel_x = -30; - req_access = list(101) - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aB" = ( -/obj/effect/mapping_helpers/airlock/access/all/centcomm/general, -/obj/machinery/door/airlock/centcom{ - id_tag = "adminshuttle"; - name = "Workshop" - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aC" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 8; - icon_state = "propulsion_l" - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/administration) -"aD" = ( -/obj/structure/shuttle/engine/heater{ - dir = 8 - }, -/obj/structure/window/plasmareinforced{ - color = "#FF0000"; - dir = 4 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/administration) -"aE" = ( -/obj/structure/chair/stool/bar{ - dir = 1 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aF" = ( -/obj/structure/reagent_dispensers/fueltank, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aG" = ( -/obj/structure/reagent_dispensers/watertank, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aH" = ( -/obj/machinery/recharge_station/upgraded, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aI" = ( -/obj/machinery/autolathe/upgraded{ - hacked = 1 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aJ" = ( -/obj/structure/dispenser, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aK" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 8; - icon_state = "propulsion_r" - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/administration) -"aL" = ( -/obj/machinery/door/airlock/public/glass, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aO" = ( -/obj/machinery/economy/vending/snack, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aP" = ( -/obj/machinery/economy/vending/cola, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aQ" = ( -/obj/machinery/economy/vending/coffee, -/obj/machinery/light/spot, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aR" = ( -/obj/machinery/economy/vending/cigarette, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aS" = ( -/obj/machinery/computer/card{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aT" = ( -/obj/machinery/computer/communications{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aU" = ( -/obj/machinery/door/poddoor/shutters{ - density = 0; - icon_state = "open"; - id_tag = "adminshuttleshutters"; - name = "Blast Shutters"; - opacity = 0 - }, -/obj/effect/spawner/window/plastitanium, -/turf/simulated/floor/plating, -/area/shuttle/administration) -"aV" = ( -/obj/machinery/light/spot{ - dir = 1 - }, -/obj/machinery/door_control{ - id = "adminshuttleblast"; - name = "Blast door control"; - pixel_x = -5; - pixel_y = 35; - req_access = list(101) - }, -/obj/machinery/door_control{ - id = "adminshuttleshutters"; - name = "Shutter control"; - pixel_x = 5; - pixel_y = 35; - req_access = list(101) - }, -/obj/structure/chair/comfy/black{ - dir = 4 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aW" = ( -/obj/structure/chair/comfy/black{ - dir = 4 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aX" = ( -/obj/machinery/computer/shuttle/admin{ - name = "NTV Argos shuttle console"; - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"aZ" = ( -/obj/machinery/dna_scannernew/upgraded, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"ba" = ( -/obj/machinery/computer/cloning, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bb" = ( -/obj/machinery/clonepod/upgraded, -/obj/machinery/light/spot{ - dir = 1 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bc" = ( -/obj/machinery/computer/scan_consolenew, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bd" = ( -/obj/effect/mapping_helpers/airlock/access/all/centcomm/general, -/obj/machinery/door/airlock/centcom{ - id_tag = "adminshuttle"; - name = "Bridge" - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"be" = ( -/obj/machinery/computer/camera_advanced/shuttle_docker/admin{ - name = "NTV Argos shuttle navigation computer"; - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"bg" = ( -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bh" = ( -/obj/effect/mapping_helpers/airlock/access/all/centcomm/general, -/obj/machinery/door/airlock/centcom{ - id_tag = "adminshuttle"; - name = "Medbay" - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bi" = ( -/obj/machinery/bodyscanner, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bk" = ( -/obj/structure/window/plasmareinforced{ - color = "#FF0000"; - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"bl" = ( -/obj/machinery/light/spot{ - dir = 4 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"bm" = ( -/obj/machinery/sleeper/upgraded{ - dir = 4 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bn" = ( -/obj/machinery/chem_master, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bo" = ( -/obj/machinery/chem_dispenser, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bp" = ( -/obj/effect/mapping_helpers/airlock/access/all/centcomm/security, -/obj/machinery/door/airlock/centcom{ - id_tag = "adminshuttle"; - name = "Holding Cell" - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"bq" = ( -/obj/machinery/door/window/reinforced/normal{ - color = "#d70000"; - dir = 8; - req_access = list(104) - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"br" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"bs" = ( -/obj/machinery/iv_drip, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bt" = ( -/obj/machinery/light/spot{ - dir = 4 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bu" = ( -/obj/structure/table, -/obj/item/storage/box/handcuffs, -/obj/machinery/light/spot{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"bv" = ( -/obj/structure/window/plasmareinforced{ - color = "#FF0000"; - dir = 8 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"bw" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"bx" = ( -/obj/structure/table, -/obj/item/bonegel, -/obj/item/bonesetter, -/obj/item/hemostat, -/obj/item/cautery, -/obj/item/surgicaldrill, -/obj/item/circular_saw, -/obj/item/scalpel, -/obj/item/retractor, -/obj/item/fix_o_vein, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"by" = ( -/obj/machinery/optable, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bz" = ( -/obj/machinery/economy/vending/medical, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bA" = ( -/obj/machinery/light, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"bB" = ( -/obj/structure/table, -/obj/item/storage/lockbox/mindshield, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"bC" = ( -/obj/structure/table, -/obj/item/storage/box/chemimp{ - pixel_x = 4; - pixel_y = 3 - }, -/obj/item/storage/box/trackimp, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/administration) -"vg" = ( -/turf/simulated/wall/mineral/plastitanium, -/area/shuttle/administration) - -(1,1,1) = {" -aa -aa -aa -vg -aC -aK -vg -aa -vg -aC -aK -vg -aa -aa -aa -aa -aa -aa -"} -(2,1,1) = {" -aa -aa -vg -ac -aD -aD -ac -vg -ac -aD -aD -ac -vg -aa -aa -aa -aa -aa -"} -(3,1,1) = {" -vg -vg -vg -av -am -am -aO -vg -aZ -bg -bg -bm -vg -vg -aa -aa -aa -aa -"} -(4,1,1) = {" -vg -ag -am -aw -am -am -aP -vg -ba -bg -bg -bg -bs -vg -vg -aa -aa -aa -"} -(5,1,1) = {" -vg -ah -am -ax -aE -am -aQ -vg -bb -bg -bg -bg -bg -bx -vg -aa -aa -aa -"} -(6,1,1) = {" -vg -ai -am -ay -aE -am -aR -vg -aZ -bg -bg -bn -bg -by -vg -aa -aa -aa -"} -(7,1,1) = {" -vg -aj -aq -az -aE -am -am -vg -bc -bg -bi -bo -bt -bz -vg -aa -aa -aa -"} -(8,1,1) = {" -ac -vg -vg -vg -vg -aL -vg -vg -vg -bh -vg -vg -vg -vg -vg -aa -aa -aa -"} -(9,1,1) = {" -ad -al -ar -aA -am -am -am -as -am -am -am -am -am -am -vg -aa -aa -aa -"} -(10,1,1) = {" -ae -am -ar -am -am -am -am -am -am -am -am -am -am -bA -vg -aa -aa -aa -"} -(11,1,1) = {" -ac -vg -vg -aB -vg -vg -vg -bd -vg -vg -vg -bp -vg -vg -vg -aa -aa -aa -"} -(12,1,1) = {" -vg -an -as -am -aF -vg -aS -am -am -vg -am -am -bu -bB -vg -aa -aa -aa -"} -(13,1,1) = {" -vg -ao -am -am -aG -vg -aV -aW -aW -vg -am -am -am -bC -vg -aa -aa -aa -"} -(14,1,1) = {" -vg -ap -am -am -aH -vg -aT -aX -be -vg -am -am -am -am -vg -aa -aa -aa -"} -(15,1,1) = {" -vg -vg -at -am -am -vg -aU -aU -aU -vg -bk -bq -bv -ac -vg -aa -aa -aa -"} -(16,1,1) = {" -aa -vg -au -am -aI -vg -aa -aa -aa -vg -am -am -bw -vg -aa -aa -aa -aa -"} -(17,1,1) = {" -aa -vg -vg -aq -aJ -vg -aa -aa -aa -vg -bl -br -vg -vg -aa -aa -aa -aa -"} -(18,1,1) = {" -aa -aa -vg -vg -vg -vg -aa -aa -aa -vg -vg -vg -vg -aa -aa -aa -aa -aa -"} -(19,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} diff --git a/_maps/map_files/shuttles/admin_hospital.dmm b/_maps/map_files/shuttles/admin_hospital.dmm deleted file mode 100644 index 5ab37c557f6ee..0000000000000 --- a/_maps/map_files/shuttles/admin_hospital.dmm +++ /dev/null @@ -1,1104 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/space, -/area/space) -"ab" = ( -/turf/simulated/wall/mineral/titanium, -/area/shuttle/administration) -"ad" = ( -/obj/machinery/door/poddoor/shutters{ - density = 0; - dir = 1; - icon_state = "open"; - id_tag = "Asclshutters"; - name = "Blast Shutters"; - opacity = 0 - }, -/obj/effect/spawner/window/shuttle, -/turf/simulated/floor/plating, -/area/shuttle/administration) -"ah" = ( -/obj/structure/sign/lifestar{ - name = "NHV Asclepius" - }, -/turf/simulated/wall/mineral/titanium, -/area/shuttle/administration) -"ai" = ( -/obj/structure/fans/tiny, -/obj/machinery/door/airlock/external, -/obj/machinery/door/poddoor{ - density = 0; - icon_state = "open"; - id_tag = "asclblast"; - name = "Blast Door"; - opacity = 0 - }, -/turf/simulated/floor/plating, -/area/shuttle/administration) -"aj" = ( -/obj/structure/fans/tiny, -/obj/machinery/door/airlock/external, -/obj/docking_port/mobile{ - dir = 2; - dwidth = 9; - height = 18; - id = "admin"; - name = "hospital"; - roundstart_move = "cc_bay_1"; - timid = 1; - width = 19 - }, -/obj/machinery/door/poddoor{ - density = 0; - icon_state = "open"; - id_tag = "asclblast"; - name = "Blast Door"; - opacity = 0 - }, -/turf/simulated/floor/plating, -/area/shuttle/administration) -"ap" = ( -/obj/machinery/chem_master, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aq" = ( -/obj/machinery/chem_dispenser, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"ar" = ( -/obj/machinery/chem_heater, -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"as" = ( -/obj/structure/closet/secure_closet/reagents, -/obj/item/storage/bag/chemistry, -/obj/item/storage/bag/chemistry, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"at" = ( -/obj/structure/closet/secure_closet/chemical, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"au" = ( -/obj/structure/sign/chemistry{ - pixel_y = 1 - }, -/turf/simulated/wall/mineral/titanium, -/area/shuttle/administration) -"aw" = ( -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"ay" = ( -/obj/structure/table/reinforced, -/obj/item/reagent_containers/glass/beaker/cryoxadone, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aB" = ( -/obj/machinery/clonescanner, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aC" = ( -/obj/machinery/atmospherics/unary/cryo_cell, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aF" = ( -/obj/structure/reagent_dispensers/fueltank/chem{ - pixel_x = -32 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aG" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aI" = ( -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aJ" = ( -/obj/structure/sign/nosmoking_2, -/turf/simulated/wall/mineral/titanium, -/area/shuttle/administration) -"aK" = ( -/obj/machinery/atmospherics/pipe/simple/hidden, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aL" = ( -/obj/structure/shuttle/engine/heater{ - dir = 4 - }, -/obj/structure/window/plasmareinforced{ - dir = 8 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/administration) -"aM" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 4 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/administration) -"aN" = ( -/obj/structure/table/reinforced, -/obj/item/reagent_containers/dropper, -/obj/item/reagent_containers/spray/cleaner{ - desc = "Someone has crossed out the 'Space' from Space Cleaner and written in Chemistry. Scrawled on the back is, 'Okay, whoever filled this with polytrinic acid, it was only funny the first time. It was hard enough replacing the CMO's first cat!'"; - name = "Chemistry Cleaner" - }, -/obj/item/reagent_containers/glass/bucket, -/obj/item/reagent_containers/glass/bucket, -/obj/item/reagent_containers/glass/bucket, -/obj/item/reagent_containers/glass/bucket, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aO" = ( -/obj/structure/closet/crate/can, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aP" = ( -/obj/effect/spawner/window/shuttle, -/turf/simulated/floor/plating, -/area/shuttle/administration) -"aS" = ( -/obj/structure/table/reinforced, -/obj/item/storage/box/syringes, -/obj/item/storage/box/beakers, -/obj/machinery/reagentgrinder, -/obj/machinery/camera{ - dir = 4; - name = "NHV Asclepius Chemistry"; - network = list("NHV Asclepius") - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aT" = ( -/obj/machinery/door/airlock/titanium/glass{ - name = "Chemistry" - }, -/obj/effect/mapping_helpers/airlock/access/all/medical/chemistry, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aU" = ( -/obj/machinery/door/airlock/titanium/glass, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aX" = ( -/obj/machinery/iv_drip, -/obj/item/reagent_containers/iv_bag, -/obj/structure/reagent_dispensers/fueltank/chem{ - pixel_x = -32 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"aY" = ( -/obj/structure/chair/comfy/shuttle, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"ba" = ( -/obj/machinery/chem_heater, -/obj/machinery/light, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bb" = ( -/obj/machinery/status_display, -/turf/simulated/wall/mineral/titanium, -/area/shuttle/administration) -"bc" = ( -/obj/structure/reagent_dispensers/water_cooler, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bd" = ( -/obj/machinery/economy/vending/coffee, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"be" = ( -/obj/structure/table/reinforced, -/obj/item/reagent_containers/spray/cleaner, -/obj/item/storage/box/gloves, -/obj/item/storage/box/masks, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bg" = ( -/obj/structure/table/reinforced, -/obj/item/storage/firstaid/regular, -/obj/item/storage/firstaid/regular, -/obj/item/storage/firstaid/adv, -/obj/item/storage/firstaid/adv, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bh" = ( -/obj/structure/table/reinforced, -/obj/item/storage/belt/medical, -/obj/item/storage/belt/medical, -/obj/item/storage/belt/medical, -/obj/item/clothing/glasses/hud/health, -/obj/item/clothing/glasses/hud/health, -/obj/item/clothing/glasses/hud/health, -/obj/machinery/light, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bi" = ( -/obj/machinery/atmospherics/unary/thermomachine/freezer{ - dir = 1 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bj" = ( -/obj/machinery/smartfridge/medbay, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bo" = ( -/obj/machinery/door/poddoor/shutters{ - density = 0; - dir = 8; - icon_state = "open"; - id_tag = "Asclshutters"; - name = "Blast Shutters"; - opacity = 0 - }, -/obj/effect/spawner/window/shuttle, -/turf/simulated/floor/plating, -/area/shuttle/administration) -"bp" = ( -/obj/machinery/computer/pandemic, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"br" = ( -/obj/machinery/recharger/wallcharger{ - pixel_y = 25 - }, -/obj/machinery/recharger/wallcharger{ - pixel_y = 35 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bt" = ( -/obj/structure/sink{ - dir = 8; - pixel_x = -12; - pixel_y = 2 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bu" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/structure/closet/walllocker/emerglocker{ - pixel_y = 32 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bv" = ( -/obj/machinery/economy/vending/medical, -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bw" = ( -/obj/item/storage/surgical_tray, -/obj/structure/table/tray, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bx" = ( -/obj/machinery/optable, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"by" = ( -/obj/machinery/computer/operating, -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bz" = ( -/obj/structure/closet/secure_closet/medical3, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bA" = ( -/obj/structure/closet/secure_closet/medical2, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bC" = ( -/obj/machinery/computer/shuttle/admin{ - name = "NHV Asclepius shuttle console"; - dir = 4 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bD" = ( -/obj/machinery/door/airlock/command{ - name = "Command Center" - }, -/obj/effect/mapping_helpers/airlock/access/all/command/general, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bE" = ( -/obj/structure/closet/crate/freezer, -/obj/item/reagent_containers/iv_bag/blood/o_minus, -/obj/item/reagent_containers/iv_bag/blood/o_minus, -/obj/item/reagent_containers/iv_bag/blood/o_minus, -/obj/item/reagent_containers/iv_bag/blood/o_minus, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bG" = ( -/obj/machinery/camera{ - dir = 4; - name = "NHV Asclepius OR 1"; - network = list("NHV Asclepius") - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bH" = ( -/obj/machinery/computer/camera_advanced/shuttle_docker/admin{ - name = "NHV Asclepius navigation computer"; - dir = 4 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bI" = ( -/obj/machinery/door/airlock/titanium/glass{ - name = "Operating Room" - }, -/obj/effect/mapping_helpers/airlock/access/all/medical/surgery, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bJ" = ( -/obj/structure/sink{ - dir = 4; - pixel_x = 11 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bL" = ( -/obj/machinery/computer/communications{ - name = "NHV Asclepius Communications Console"; - dir = 4 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bO" = ( -/obj/machinery/sleeper, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bP" = ( -/obj/machinery/sleeper{ - dir = 4 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bQ" = ( -/obj/structure/bed{ - name = "Triage: High Priority" - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bR" = ( -/obj/machinery/bodyscanner{ - dir = 1 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bT" = ( -/obj/machinery/light, -/obj/structure/closet/crate/can, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bU" = ( -/obj/item/reagent_containers/spray/cleaner{ - desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; - name = "Surgery Cleaner" - }, -/obj/structure/table/glass, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bV" = ( -/obj/structure/closet/crate/freezer, -/obj/item/reagent_containers/iv_bag/blood/o_minus, -/obj/item/reagent_containers/iv_bag/blood/o_minus, -/obj/machinery/iv_drip, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"bY" = ( -/obj/structure/sign/examroom, -/turf/simulated/wall/mineral/titanium, -/area/shuttle/administration) -"bZ" = ( -/obj/machinery/defibrillator_mount/loaded, -/turf/simulated/wall/mineral/titanium, -/area/shuttle/administration) -"ca" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/machinery/camera{ - dir = 5; - name = "NHV Asclepius Central"; - network = list("NHV Asclepius") - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cb" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/structure/bed{ - name = "Triage: High Priority" - }, -/obj/machinery/iv_drip, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"ce" = ( -/obj/machinery/atmospherics/portable/canister/oxygen{ - name = "Canister: \[O2] (CRYO)" - }, -/obj/machinery/atmospherics/unary/portables_connector{ - dir = 1 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cg" = ( -/obj/machinery/atmospherics/portable/canister/oxygen{ - name = "Canister: \[O2] (CRYO)" - }, -/obj/machinery/light{ - dir = 1 - }, -/obj/machinery/camera{ - dir = 4; - name = "NHV Asclepius Cryo"; - network = list("NHV Asclepius") - }, -/obj/machinery/atmospherics/unary/portables_connector, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"ch" = ( -/obj/structure/table/glass, -/obj/item/reagent_containers/spray/cleaner{ - desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; - name = "Surgery Cleaner" - }, -/obj/machinery/cell_charger, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"ci" = ( -/obj/structure/bed{ - name = "Triage: High Priority" - }, -/obj/machinery/iv_drip, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cj" = ( -/obj/machinery/atmospherics/unary/thermomachine/freezer, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"ck" = ( -/obj/machinery/camera{ - dir = 4; - name = "NHV Asclepius OR 2"; - network = list("NHV Asclepius") - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cl" = ( -/obj/structure/closet/radiation, -/obj/item/clothing/head/radiation, -/obj/item/clothing/head/radiation, -/obj/item/clothing/head/radiation, -/obj/item/clothing/suit/radiation, -/obj/item/clothing/suit/radiation, -/obj/item/clothing/suit/radiation, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cm" = ( -/obj/structure/closet/l3closet, -/obj/item/clothing/head/bio_hood, -/obj/item/clothing/head/bio_hood, -/obj/item/clothing/head/bio_hood, -/obj/item/clothing/suit/bio_suit, -/obj/item/clothing/suit/bio_suit, -/obj/item/clothing/suit/bio_suit, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cn" = ( -/obj/structure/closet/secure_closet/medical1, -/obj/item/clothing/head/beret/med, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"co" = ( -/obj/machinery/atmospherics/portable/canister/oxygen, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cp" = ( -/obj/machinery/suit_storage_unit/cmo/sec_storage, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cq" = ( -/obj/machinery/light, -/obj/machinery/suit_storage_unit/cmo/sec_storage, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cr" = ( -/obj/structure/dispenser/oxygen, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cs" = ( -/obj/machinery/economy/vending/medical, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cu" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 5 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cv" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cw" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"cx" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 9 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"ia" = ( -/obj/machinery/camera{ - dir = 8; - name = "NHV Asclepius Cloning"; - network = list("NHV Asclepius") - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"ip" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/machinery/clonepod/upgraded, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"kY" = ( -/obj/machinery/recharge_station, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"qa" = ( -/obj/machinery/door/poddoor/shutters{ - density = 0; - dir = 2; - icon_state = "open"; - id_tag = "Asclshutters"; - name = "Blast Shutters"; - opacity = 0 - }, -/obj/effect/spawner/window/shuttle, -/turf/simulated/floor/plating, -/area/shuttle/administration) -"qj" = ( -/obj/machinery/camera{ - dir = 8; - name = "NHV Asclepius Lobby"; - network = list("NHV Asclepius") - }, -/obj/machinery/recharge_station, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"rn" = ( -/obj/structure/table/reinforced, -/obj/item/reagent_containers/glass/beaker/cryoxadone, -/obj/item/reagent_containers/glass/beaker/cryoxadone, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"rx" = ( -/obj/machinery/camera{ - c_tag = "Tech Storage"; - name = "NHV Asclepius Command Center"; - network = list("NHV Asclepius") - }, -/obj/machinery/door_control{ - dir = 4; - id = "Asclshutters"; - name = "remote shutter control"; - pixel_x = -5; - pixel_y = 35; - req_access = list(101) - }, -/obj/machinery/keycard_auth{ - pixel_y = 24 - }, -/obj/machinery/door_control{ - id = "asclblast"; - name = "blast door control"; - pixel_x = 5; - pixel_y = 35; - req_access = list(101) - }, -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"wk" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/window/reinforced/normal{ - dir = 8 - }, -/obj/effect/mapping_helpers/airlock/windoor/access/any/medical/chemistry{ - dir = 8 - }, -/obj/structure/window/reinforced{ - dir = 1; - layer = 2.9 - }, -/obj/structure/window/reinforced, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"xs" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 10 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"zD" = ( -/obj/effect/spawner/window/shuttle, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"Ax" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"Dw" = ( -/turf/simulated/wall/mineral/titanium/nodiagonal, -/area/shuttle/administration) -"Jz" = ( -/obj/machinery/light, -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"Kk" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"LI" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden{ - dir = 1 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"RB" = ( -/obj/machinery/sleeper{ - dir = 1; - icon_state = "sleeper" - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"RQ" = ( -/obj/machinery/computer/cloning, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) -"TT" = ( -/obj/machinery/bodyscanner{ - dir = 4 - }, -/turf/simulated/floor/mineral/titanium, -/area/shuttle/administration) - -(1,1,1) = {" -ab -ab -ab -ab -ab -ab -ab -ab -bo -bo -bo -bo -ab -ab -ab -ab -ab -ab -"} -(2,1,1) = {" -ab -ap -aF -aN -aS -aX -ap -ab -bp -bC -bH -bL -ab -cg -cu -aw -cl -ab -"} -(3,1,1) = {" -ad -aq -aG -aw -aw -aY -aq -ab -rx -Ax -Ax -Jz -ab -aC -cv -aw -cm -qa -"} -(4,1,1) = {" -ad -ar -aw -aw -aw -aw -ba -ab -br -aw -aw -aw -bb -rn -cw -aw -cn -qa -"} -(5,1,1) = {" -ad -as -aw -aw -aw -aw -aw -Dw -ab -bD -zD -ab -ab -aC -cv -aw -co -qa -"} -(6,1,1) = {" -ab -at -aw -aO -aw -aw -aw -bj -bt -aw -aw -bO -bY -cj -cx -aw -cp -ab -"} -(7,1,1) = {" -ab -au -wk -aP -aT -aP -bb -Dw -bu -aw -aw -bP -bZ -ch -aw -aw -cq -ab -"} -(8,1,1) = {" -ah -kY -aw -Kk -aw -Kk -bc -aP -aw -aw -aw -aw -ca -aw -aw -aw -cr -ab -"} -(9,1,1) = {" -ai -aw -aw -aw -aw -aw -aw -aU -aw -aw -aw -aw -aw -aw -aw -aw -bR -ab -"} -(10,1,1) = {" -aj -aw -aw -aw -aw -aw -aw -aU -aw -aw -aw -aw -aw -aw -aw -aw -RB -ab -"} -(11,1,1) = {" -ah -qj -aI -Ax -aw -Ax -bd -aP -bv -bE -aw -bQ -cb -ci -bQ -aw -cs -ab -"} -(12,1,1) = {" -ab -ab -aJ -aP -aU -aP -bb -ab -aP -ab -bI -ab -aJ -aP -ab -bI -ab -ab -"} -(13,1,1) = {" -ab -ay -aw -aw -aw -aw -be -ab -bw -bG -aw -TT -ab -bw -ck -aw -TT -ab -"} -(14,1,1) = {" -ad -aC -aK -aK -aK -cu -bg -ab -bx -aw -aw -aw -ab -bx -aw -aw -aw -qa -"} -(15,1,1) = {" -ad -ip -aw -aw -aw -cw -bh -ab -by -aw -aw -bT -ab -by -aw -aw -bT -qa -"} -(16,1,1) = {" -ad -RQ -aw -aw -aw -LI -bi -ab -bz -aw -aw -bU -ab -bz -aw -aw -bU -qa -"} -(17,1,1) = {" -ab -aB -aw -aw -ia -xs -ce -ab -bA -aw -bJ -bV -ab -bA -aw -bJ -bV -ab -"} -(18,1,1) = {" -ab -Dw -aL -aL -Dw -ab -ab -Dw -aL -aL -Dw -ab -ab -Dw -aL -aL -Dw -ab -"} -(19,1,1) = {" -aa -ab -aM -aM -ab -aa -aa -ab -aM -aM -ab -aa -aa -ab -aM -aM -ab -aa -"} diff --git a/_maps/map_files/shuttles/admin_skipjack.dmm b/_maps/map_files/shuttles/admin_skipjack.dmm deleted file mode 100644 index 346de6dd4a9c1..0000000000000 --- a/_maps/map_files/shuttles/admin_skipjack.dmm +++ /dev/null @@ -1,916 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/space, -/area/space) -"ab" = ( -/obj/structure/rack, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"ac" = ( -/obj/machinery/computer/camera_advanced/shuttle_docker/admin/vox{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"ad" = ( -/obj/effect/mapping_helpers/airlock/access/all/shuttles/vox, -/obj/machinery/door/airlock/hatch{ - id_tag = "voxwest_door_ext"; - locked = 1 - }, -/obj/structure/fans/tiny, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"ae" = ( -/obj/machinery/computer/shuttle/admin/vox{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"ai" = ( -/obj/machinery/door/airlock/external, -/obj/machinery/door/poddoor/shutters{ - density = 0; - dir = 2; - icon_state = "open"; - id_tag = "voxshutters"; - name = "Blast Shutters"; - opacity = 0 - }, -/turf/simulated/floor/plating/nitrogen, -/area/shuttle/administration) -"aj" = ( -/obj/docking_port/mobile{ - dir = 2; - dwidth = 9; - height = 18; - id = "admin"; - name = "skipjack"; - roundstart_move = "cc_bay_1"; - timid = 1; - width = 19 - }, -/obj/machinery/door/airlock/external, -/obj/machinery/door/poddoor/shutters{ - density = 0; - dir = 2; - icon_state = "open"; - id_tag = "voxshutters"; - name = "Blast Shutters"; - opacity = 0 - }, -/turf/simulated/floor/plating/nitrogen, -/area/shuttle/administration) -"aq" = ( -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"au" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 1; - icon_state = "propulsion_l" - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/administration) -"av" = ( -/obj/machinery/access_button{ - autolink_id = "voxwest_btn_ext"; - req_access = list(152) - }, -/turf/simulated/wall/mineral/plastitanium, -/area/shuttle/administration) -"az" = ( -/turf/space, -/area/shuttle/administration) -"aB" = ( -/obj/machinery/light{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"aG" = ( -/obj/machinery/airlock_controller/access_controller{ - ext_button_link_id = "voxwest_btn_ext"; - ext_door_link_id = "voxwest_door_ext"; - int_button_link_id = "voxwest_btn_int"; - int_door_link_id = "voxwest_door_int"; - pixel_x = 24; - req_access = list(152) - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"aH" = ( -/obj/structure/shuttle/engine/heater{ - dir = 1 - }, -/obj/structure/window/reinforced, -/obj/structure/window/reinforced{ - dir = 4 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/administration) -"aI" = ( -/obj/item/clothing/head/bearpelt, -/obj/item/xenos_claw, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"aJ" = ( -/obj/structure/shuttle/engine/heater{ - dir = 1 - }, -/obj/structure/window/reinforced, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/administration) -"aM" = ( -/obj/effect/mapping_helpers/airlock/access/all/shuttles/vox, -/obj/machinery/door/airlock/hatch{ - id_tag = "voxeast_door_ext"; - locked = 1 - }, -/obj/structure/fans/tiny, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"aN" = ( -/obj/effect/mapping_helpers/airlock/access/all/shuttles/vox, -/obj/machinery/door/airlock/hatch{ - id_tag = "voxwest_door_int"; - locked = 1 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"aP" = ( -/obj/item/broken_bottle, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"aR" = ( -/obj/item/stack/spacecash/c50, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"aT" = ( -/obj/item/clothing/mask/breath, -/obj/machinery/light, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"aU" = ( -/obj/item/stack/spacecash/c50, -/obj/machinery/light, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"bb" = ( -/obj/effect/mapping_helpers/airlock/access/all/shuttles/vox, -/obj/machinery/door/airlock/hatch, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"bd" = ( -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"bj" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/table, -/obj/item/broken_device, -/obj/item/robot_parts/chest, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"bo" = ( -/obj/machinery/door/poddoor/shutters{ - density = 0; - dir = 8; - icon_state = "open"; - id_tag = "voxshutters"; - name = "Blast Shutters"; - opacity = 0 - }, -/obj/effect/spawner/window/plastitanium, -/turf/simulated/floor/plating/nitrogen, -/area/shuttle/administration) -"bt" = ( -/obj/item/storage/toolbox/syndicate, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"bv" = ( -/obj/structure/table, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"bC" = ( -/obj/machinery/atmospherics/unary/tank/nitrogen{ - dir = 1 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"bD" = ( -/obj/structure/rack, -/obj/item/rcd, -/obj/item/rcd_ammo, -/obj/item/rcd_ammo, -/obj/item/rcd_ammo, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"bG" = ( -/obj/machinery/sleeper/upgraded{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"bJ" = ( -/obj/structure/shuttle/engine/heater, -/obj/structure/window/reinforced{ - dir = 1 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/administration) -"bO" = ( -/obj/machinery/access_button{ - autolink_id = "voxeast_btn_ext"; - req_access = list(152) - }, -/turf/simulated/wall/mineral/plastitanium, -/area/shuttle/administration) -"bR" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"bV" = ( -/obj/structure/shuttle/engine/propulsion{ - icon_state = "propulsion_l" - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/administration) -"bY" = ( -/obj/item/tank/internals/emergency_oxygen, -/obj/item/clothing/mask/breath, -/obj/machinery/atmospherics/portable/canister/oxygen, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"ca" = ( -/obj/structure/rack, -/obj/item/clothing/accessory/storage/black_vest, -/obj/item/clothing/suit/space/vox/stealth, -/obj/item/clothing/head/helmet/space/vox/stealth, -/obj/item/clothing/mask/breath, -/obj/machinery/light{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"cb" = ( -/obj/structure/rack, -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"cf" = ( -/obj/machinery/airlock_controller/access_controller{ - ext_door_link_id = "voxeast_door_ext"; - int_door_link_id = "voxeast_door_int"; - pixel_x = -24; - ext_button_link_id = "voxeast_btn_ext"; - int_button_link_id = "voxeast_btn_int"; - req_access = list(152) - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"cg" = ( -/obj/machinery/access_button{ - autolink_id = "voxwest_btn_int"; - req_access = list(152) - }, -/turf/simulated/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/administration) -"ci" = ( -/obj/effect/spawner/window/plastitanium, -/turf/simulated/floor/plating/nitrogen, -/area/shuttle/administration) -"cj" = ( -/obj/item/clothing/mask/breath, -/obj/item/stack/spacecash/c50, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"ck" = ( -/obj/item/clothing/head/collectable/xenom, -/obj/item/clothing/head/chicken, -/obj/item/ai_module/syndicate, -/obj/item/storage/box/zipties, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"cl" = ( -/obj/item/stack/spacecash/c1000, -/obj/item/stack/spacecash/c500, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"cm" = ( -/obj/machinery/door/poddoor/shutters{ - density = 0; - icon_state = "open"; - id_tag = "voxshutters"; - name = "Blast Shutters"; - opacity = 0 - }, -/obj/effect/spawner/window/plastitanium, -/turf/simulated/floor/plating/nitrogen, -/area/shuttle/administration) -"cn" = ( -/obj/machinery/access_button{ - autolink_id = "voxeast_btn_int"; - req_access = list(152) - }, -/turf/simulated/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/administration) -"co" = ( -/obj/effect/mapping_helpers/airlock/access/all/shuttles/vox, -/obj/machinery/door/airlock/hatch{ - id_tag = "voxeast_door_int"; - locked = 1 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"cp" = ( -/obj/structure/ai_core, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"cu" = ( -/obj/item/clothing/head/bearpelt, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"cv" = ( -/obj/item/xenos_claw, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"cw" = ( -/obj/structure/shuttle/engine/heater{ - dir = 1 - }, -/obj/structure/window/reinforced, -/turf/simulated/floor/plating/airless, -/area/shuttle/administration) -"cx" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/table, -/obj/machinery/recharger, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"eP" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"jg" = ( -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"nk" = ( -/obj/structure/rack, -/obj/item/clothing/accessory/storage/black_vest, -/obj/item/clothing/suit/space/vox/pressure, -/obj/item/clothing/head/helmet/space/vox/pressure, -/obj/item/clothing/mask/breath, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"qa" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/table, -/obj/machinery/cell_charger, -/obj/item/weed_extract, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"sd" = ( -/obj/machinery/atmospherics/portable/canister/nitrogen, -/obj/machinery/light, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"ue" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/table, -/obj/item/pickaxe, -/obj/item/storage/firstaid/toxin, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"wb" = ( -/obj/effect/spawner/window/plastitanium, -/obj/machinery/door/poddoor/shutters{ - density = 0; - dir = 2; - icon_state = "open"; - id_tag = "voxshutters"; - name = "Blast Shutters"; - opacity = 0 - }, -/turf/simulated/floor/plating/nitrogen, -/area/shuttle/administration) -"wk" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"wB" = ( -/obj/structure/rack, -/obj/item/clothing/accessory/storage/black_vest, -/obj/item/clothing/suit/space/vox/carapace, -/obj/item/clothing/head/helmet/space/vox/carapace, -/obj/item/clothing/mask/breath, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"wZ" = ( -/obj/structure/rack, -/obj/item/clothing/accessory/storage/black_vest, -/obj/item/clothing/suit/space/vox/medic, -/obj/item/clothing/head/helmet/space/vox/medic, -/obj/item/clothing/mask/breath, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"xi" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/table, -/obj/item/circular_saw, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"zD" = ( -/turf/simulated/wall/mineral/plastitanium, -/area/shuttle/administration) -"CD" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/obj/machinery/light{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"Gs" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/table, -/obj/item/scalpel, -/obj/item/stack/cable_coil, -/obj/item/storage/firstaid/regular, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"IH" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/table, -/mob/living/simple_animal/bot/floorbot{ - on = 0 - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"Jk" = ( -/obj/structure/table, -/obj/machinery/door_control{ - id = "voxshutters"; - name = "remote shutter control"; - req_access = list(152) - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"JJ" = ( -/obj/structure/rack, -/obj/item/tank/internals/nitrogen, -/obj/item/tank/internals/nitrogen, -/obj/item/tank/internals/nitrogen, -/obj/item/tank/internals/nitrogen, -/obj/item/tank/internals/nitrogen, -/obj/item/tank/internals/nitrogen, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"MT" = ( -/obj/structure/rack, -/obj/item/pneumatic_cannon, -/obj/item/harpoon, -/obj/item/harpoon, -/obj/item/harpoon, -/obj/item/harpoon, -/obj/item/tank/internals/nitrogen, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"Ua" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/machinery/optable, -/obj/item/organ/internal/brain, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"Vl" = ( -/obj/machinery/bodyscanner, -/obj/machinery/light, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"XB" = ( -/obj/machinery/atmospherics/portable/canister/toxins, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) -"XK" = ( -/obj/item/clothing/head/collectable/petehat{ - desc = "It smells faintly of reptile."; - name = "fancy leader hat" - }, -/turf/simulated/floor/mineral/plastitanium/red/nitrogen, -/area/shuttle/administration) - -(1,1,1) = {" -zD -zD -zD -zD -zD -zD -bo -bo -bo -zD -zD -zD -aa -aa -aa -aa -aa -aa -"} -(2,1,1) = {" -av -jg -jg -aN -jg -jg -jg -jg -jg -bC -bJ -bV -aa -aa -aa -aa -aa -aa -"} -(3,1,1) = {" -ad -aq -aG -cg -zD -zD -jg -cx -jg -XB -bJ -bV -aa -aa -aa -aa -aa -aa -"} -(4,1,1) = {" -zD -zD -zD -zD -az -zD -jg -qa -jg -sd -zD -zD -aa -aa -aa -aa -aa -aa -"} -(5,1,1) = {" -az -az -az -az -au -cw -jg -IH -jg -bD -zD -aa -aa -aa -aa -aa -aa -aa -"} -(6,1,1) = {" -az -az -zD -bo -bo -zD -jg -bj -bt -JJ -zD -aa -aa -aa -aa -aa -aa -aa -"} -(7,1,1) = {" -az -au -aH -aP -aT -zD -bb -zD -zD -zD -zD -zD -zD -zD -zD -zD -zD -zD -"} -(8,1,1) = {" -zD -zD -aP -cj -cp -zD -bd -bR -bR -wB -wZ -nk -ca -ci -CD -bR -ae -zD -"} -(9,1,1) = {" -ai -jg -jg -ck -jg -bb -jg -jg -jg -jg -jg -jg -jg -bb -jg -jg -wk -wb -"} -(10,1,1) = {" -aj -jg -bY -cl -cu -bb -jg -jg -jg -jg -jg -jg -jg -bb -XK -jg -bR -wb -"} -(11,1,1) = {" -zD -zD -aI -aR -cv -zD -bd -wk -bv -ab -MT -ab -cb -ci -eP -Jk -ac -zD -"} -(12,1,1) = {" -az -au -aJ -jg -aU -zD -bb -zD -zD -zD -zD -zD -zD -zD -zD -zD -zD -zD -"} -(13,1,1) = {" -az -az -zD -cm -cm -zD -jg -ue -jg -bG -zD -aa -aa -aa -aa -aa -aa -aa -"} -(14,1,1) = {" -az -az -az -az -au -cw -jg -Gs -jg -jg -zD -aa -aa -aa -aa -aa -aa -aa -"} -(15,1,1) = {" -zD -zD -zD -zD -az -zD -jg -xi -jg -Vl -zD -zD -aa -aa -aa -aa -aa -aa -"} -(16,1,1) = {" -aM -aB -cf -cn -zD -zD -jg -Ua -jg -jg -bJ -bV -aa -aa -aa -aa -aa -aa -"} -(17,1,1) = {" -bO -jg -jg -co -jg -jg -jg -jg -jg -bC -bJ -bV -aa -aa -aa -aa -aa -aa -"} -(18,1,1) = {" -zD -zD -zD -zD -zD -zD -cm -cm -cm -zD -zD -zD -aa -aa -aa -aa -aa -aa -"} -(19,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} diff --git a/_maps/map_files/shuttles/emergency_lance.dmm b/_maps/map_files/shuttles/emergency_lance.dmm deleted file mode 100644 index 3c7ae77d234c6..0000000000000 --- a/_maps/map_files/shuttles/emergency_lance.dmm +++ /dev/null @@ -1,2156 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"ae" = ( -/obj/machinery/door/airlock/command/glass{ - name = "Cockpit" - }, -/obj/effect/mapping_helpers/airlock/access/all/command/general, -/obj/machinery/door/poddoor/preopen{ - id = "ravenbridgeblast"; - name = "Cockpit Blast Door"; - id_tag = "ravenbridgeblast" - }, -/turf/simulated/floor/plasteel{ - icon_state = "darkbluefull" - }, -/area/shuttle/escape) -"av" = ( -/turf/simulated/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/escape) -"bm" = ( -/obj/structure/shuttle/engine/propulsion/burst/left, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"bo" = ( -/obj/structure/chair/comfy/shuttle, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"bA" = ( -/obj/structure/chair/comfy/shuttle, -/turf/simulated/floor/plasteel{ - icon_state = "darkblue" - }, -/area/shuttle/escape) -"bO" = ( -/obj/structure/shuttle/engine/propulsion/burst/right{ - dir = 1 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"bQ" = ( -/obj/machinery/sleeper, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"bV" = ( -/obj/structure/table/reinforced, -/obj/machinery/recharger, -/obj/effect/turf_decal/blue_corner{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"cn" = ( -/obj/structure/table/reinforced, -/obj/item/rcd/preloaded, -/obj/item/rcd_ammo, -/turf/simulated/floor/plasteel{ - icon_state = "darkyellow" - }, -/area/shuttle/escape) -"cF" = ( -/obj/structure/closet/crate/freezer/iv_storage, -/turf/simulated/floor/plasteel{ - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"dq" = ( -/obj/machinery/door/airlock/highsecurity, -/turf/simulated/floor/plasteel{ - icon_state = "darkbluefull" - }, -/area/shuttle/escape) -"dP" = ( -/obj/structure/shuttle/engine/propulsion/burst/right, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"eh" = ( -/obj/machinery/light{ - dir = 8 - }, -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"ek" = ( -/obj/machinery/door/airlock/engineering{ - name = "Emergency Shutle Engineering" - }, -/obj/effect/mapping_helpers/airlock/access/any/engineering/general, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ew" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"eL" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"eP" = ( -/obj/structure/chair/comfy/shuttle, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"fE" = ( -/turf/simulated/wall/mineral/plastitanium, -/area/shuttle/escape) -"fG" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/machinery/suit_storage_unit/standard_unit, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"fH" = ( -/obj/structure/table/reinforced, -/obj/item/storage/firstaid/regular/doctor, -/turf/simulated/floor/plasteel{ - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"fL" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"fR" = ( -/obj/machinery/turretid/lethal{ - req_access = list(18); - check_access = 0; - check_arrest = 0; - check_records = 0; - pixel_y = -32 - }, -/turf/simulated/floor/plasteel{ - icon_state = "darkblue" - }, -/area/shuttle/escape) -"gs" = ( -/obj/structure/sign/lifestar, -/turf/simulated/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/escape) -"gN" = ( -/obj/machinery/economy/vending/wallmed/directional/north, -/obj/structure/chair/comfy/shuttle, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"gS" = ( -/obj/structure/fans/tiny/invisible, -/obj/machinery/door/airlock/external/glass, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"gU" = ( -/obj/structure/extinguisher_cabinet{ - name = "north bump"; - pixel_y = 30 - }, -/obj/structure/bed/roller, -/obj/machinery/iv_drip, -/turf/simulated/floor/plasteel{ - icon_state = "darkblue" - }, -/area/shuttle/escape) -"gX" = ( -/obj/structure/closet/crate/freezer/iv_storage, -/obj/item/reagent_containers/hypospray/autoinjector/survival, -/obj/item/reagent_containers/hypospray/autoinjector/survival, -/obj/item/reagent_containers/hypospray/autoinjector/survival, -/obj/item/reagent_containers/hypospray/autoinjector/survival, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"gZ" = ( -/obj/effect/spawner/window/plastitanium, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"hs" = ( -/obj/structure/extinguisher_cabinet{ - name = "south bump"; - pixel_y = -30 - }, -/turf/simulated/floor/plasteel{ - icon_state = "darkyellow"; - dir = 1 - }, -/area/shuttle/escape) -"hv" = ( -/obj/machinery/door/airlock/external{ - id_tag = "s_docking_airlock" - }, -/obj/structure/fans/tiny/invisible, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ii" = ( -/obj/machinery/door/airlock/medical{ - id_tag = "mental_health"; - name = "Mental Health Crisis Room" - }, -/turf/simulated/floor/mineral/silver, -/area/shuttle/escape) -"it" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/escape) -"iJ" = ( -/turf/template_noop, -/area/template_noop) -"iY" = ( -/obj/structure/chair/office/dark{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"jn" = ( -/obj/structure/bed, -/obj/item/bedsheet/medical, -/obj/item/toy/plushie/lizardplushie{ - name = "Calms-Thy-Panic" - }, -/turf/simulated/floor/mineral/silver, -/area/shuttle/escape) -"jp" = ( -/obj/structure/chair/office/dark, -/turf/simulated/floor/plasteel{ - icon_state = "dark" - }, -/area/shuttle/escape) -"jr" = ( -/obj/machinery/economy/vending/wallmed/directional/west, -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"jK" = ( -/obj/machinery/porta_turret/ai_turret, -/turf/simulated/wall/mineral/plastitanium, -/area/shuttle/escape) -"jZ" = ( -/obj/machinery/computer/aifixer{ - dir = 4 - }, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"kg" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/plasteel{ - dir = 10; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"kr" = ( -/obj/structure/chair/office/dark, -/turf/simulated/floor/plasteel{ - icon_state = "darkbluefull" - }, -/area/shuttle/escape) -"ku" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"kO" = ( -/obj/structure/window/reinforced, -/obj/structure/shuttle/engine/heater{ - dir = 1 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"kZ" = ( -/obj/machinery/computer/crew, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"lj" = ( -/obj/structure/shuttle/engine/propulsion/burst{ - dir = 1 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"lH" = ( -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"mS" = ( -/obj/structure/bed/roller, -/obj/machinery/iv_drip, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"mV" = ( -/mob/living/simple_animal/bot/medbot, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"nP" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"nX" = ( -/obj/structure/chair/comfy/shuttle, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/escape) -"ob" = ( -/obj/structure/chair/office/dark, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"of" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"ok" = ( -/obj/structure/reagent_dispensers/fueltank, -/turf/simulated/floor/plasteel{ - icon_state = "darkyellowcorners" - }, -/area/shuttle/escape) -"pV" = ( -/turf/simulated/floor/plasteel{ - icon_state = "darkyellow"; - dir = 1 - }, -/area/shuttle/escape) -"qb" = ( -/obj/structure/shuttle/engine/heater, -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/structure/window/reinforced{ - dir = 1 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"qk" = ( -/obj/structure/marker_beacon/dock_marker, -/turf/simulated/floor/catwalk, -/area/shuttle/escape) -"qS" = ( -/obj/machinery/optable, -/obj/structure/extinguisher_cabinet{ - name = "west bump"; - pixel_x = -27 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"rd" = ( -/obj/structure/chair/office/dark{ - dir = 8 - }, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"rg" = ( -/obj/structure/rack, -/obj/item/grenade/chem_grenade/metalfoam, -/obj/item/grenade/chem_grenade/metalfoam, -/obj/item/grenade/chem_grenade/metalfoam, -/obj/item/grenade/chem_grenade/metalfoam, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"rp" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/obj/structure/window/reinforced{ - dir = 4 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"rX" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"sx" = ( -/obj/machinery/shieldgen/raven, -/obj/effect/turf_decal/delivery/white/hollow, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"sE" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/machinery/suit_storage_unit/standard_unit, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"sT" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"tW" = ( -/obj/structure/chair/comfy/shuttle, -/obj/item/radio/intercom{ - name = "west bump"; - pixel_x = -28 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"uc" = ( -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"ul" = ( -/turf/simulated/floor/catwalk, -/area/shuttle/escape) -"ut" = ( -/obj/structure/table/reinforced, -/obj/item/storage/firstaid/regular/doctor, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"uW" = ( -/obj/structure/window/reinforced, -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/machinery/door/window/reinforced/normal{ - name = "Last Resort"; - dir = 4 - }, -/obj/structure/rack, -/obj/item/gun/energy/gun/mini{ - pixel_y = 6 - }, -/obj/item/gun/energy/gun/mini{ - pixel_y = -6 - }, -/obj/item/gun/energy/gun/mini, -/obj/effect/mapping_helpers/airlock/windoor/access/all/command/general{ - dir = 4 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"vk" = ( -/obj/structure/table/reinforced, -/obj/item/flash, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"vF" = ( -/obj/structure/shuttle/engine/propulsion/burst/left{ - dir = 1 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"wu" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/structure/reagent_dispensers/watertank/high, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"ww" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/structure/table/reinforced, -/obj/item/storage/surgical_tray, -/obj/item/stack/nanopaste, -/obj/item/reagent_containers/glass/bottle/reagent/hydrocodone, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"wx" = ( -/obj/machinery/computer/emergency_shuttle{ - dir = 8 - }, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"wz" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Holding Area" - }, -/obj/effect/mapping_helpers/airlock/access/all/security/general, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/escape) -"wF" = ( -/obj/machinery/atmospherics/portable/canister/oxygen, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"wS" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/obj/structure/extinguisher_cabinet{ - name = "west bump"; - pixel_x = -27 - }, -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"xj" = ( -/obj/machinery/economy/vending/wallmed/directional/west, -/obj/effect/turf_decal/blue_corner{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"xv" = ( -/obj/structure/table/reinforced, -/obj/machinery/recharger, -/obj/machinery/door_control{ - id = "ravenbridgeblast"; - name = "Cockpick Airlock Blastdoor Control"; - pixel_x = 5; - req_access = list(19); - pixel_y = 10 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"xI" = ( -/obj/machinery/optable, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"yg" = ( -/turf/simulated/floor/plasteel{ - dir = 5; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"yA" = ( -/obj/item/defibrillator/loaded, -/obj/structure/table/reinforced, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"yD" = ( -/obj/docking_port/mobile/emergency{ - height = 50; - width = 19; - timid = 1; - dir = 2; - lance_docking = 1; - shuttle_speed_factor = 1.5 - }, -/obj/machinery/door/airlock/external{ - id_tag = "s_docking_airlock" - }, -/obj/structure/fans/tiny/invisible, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"yM" = ( -/obj/machinery/computer/crew{ - dir = 4 - }, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"zb" = ( -/obj/structure/chair/office/dark{ - dir = 8 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"AK" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/machinery/light{ - dir = 8 - }, -/obj/effect/turf_decal/delivery/blue/partial{ - dir = 4 - }, -/obj/effect/turf_decal/delivery/blue/partial{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"AS" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/table/reinforced, -/obj/item/stack/sheet/mineral/plasma/fifty, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/item/assembly/signaler, -/obj/item/assembly/signaler, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"Bi" = ( -/obj/structure/rack, -/obj/item/flashlight/flare, -/obj/item/flashlight/flare, -/obj/item/flashlight/flare, -/obj/item/flashlight/flare, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"Bn" = ( -/obj/machinery/suit_storage_unit/standard_unit, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Bx" = ( -/obj/structure/table/reinforced, -/obj/item/radio, -/obj/effect/turf_decal/blue_corner{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"Cl" = ( -/obj/effect/turf_decal/blue_corner{ - dir = 4 - }, -/obj/machinery/hologram/holopad, -/obj/effect/turf_decal/box/white, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"CL" = ( -/obj/item/radio/intercom{ - name = "north bump"; - pixel_y = 28 - }, -/turf/simulated/floor/plasteel{ - icon_state = "darkbluefull" - }, -/area/shuttle/escape) -"DD" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/machinery/shieldgen/raven, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"DU" = ( -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/escape) -"DZ" = ( -/obj/structure/closet/fireaxecabinet{ - pixel_y = -32 - }, -/turf/simulated/floor/plasteel{ - dir = 6; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"Ek" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/obj/item/radio/intercom{ - name = "east bump"; - pixel_x = 28 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"EV" = ( -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"FP" = ( -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/machinery/door/airlock/medical/glass{ - id_tag = "MedbayFoyer"; - name = "Medical Supplies" - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Hk" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/structure/table/reinforced, -/obj/item/storage/box/handcuffs, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/escape) -"HE" = ( -/obj/machinery/light/small, -/obj/structure/table/reinforced, -/obj/item/book/manual/wiki/security_space_law{ - pixel_x = -4; - pixel_y = 4 - }, -/obj/item/storage/firstaid/regular/doctor, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/escape) -"HK" = ( -/obj/structure/extinguisher_cabinet{ - name = "north bump"; - pixel_y = 30 - }, -/obj/structure/chair/comfy/shuttle, -/turf/simulated/floor/plasteel{ - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"HL" = ( -/obj/structure/table/reinforced, -/obj/item/storage/box/donkpockets, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"Id" = ( -/obj/structure/chair/comfy/shuttle, -/obj/structure/window/reinforced{ - dir = 4 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"If" = ( -/obj/structure/table/reinforced, -/obj/item/storage/firstaid/regular, -/obj/effect/turf_decal/blue_corner{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"Iu" = ( -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"IF" = ( -/obj/machinery/suit_storage_unit/standard_unit, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"IJ" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"IN" = ( -/obj/structure/shuttle/engine/heater, -/obj/structure/window/reinforced{ - dir = 1 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"Jb" = ( -/obj/machinery/light/small, -/obj/machinery/computer/operating{ - dir = 1 - }, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"Jd" = ( -/turf/simulated/floor/plasteel{ - dir = 9; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"Je" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"Kg" = ( -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"Ko" = ( -/obj/machinery/computer/security{ - dir = 8; - network = list("SS13","Research Outpost","Mining Outpost") - }, -/turf/simulated/floor/plasteel{ - dir = 5; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"Ky" = ( -/obj/machinery/light/small, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"KB" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/machinery/shieldgen/raven, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"KL" = ( -/obj/machinery/economy/vending/medical, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"KQ" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/structure/chair/comfy/shuttle, -/turf/simulated/floor/plasteel{ - icon_state = "darkblue" - }, -/area/shuttle/escape) -"KT" = ( -/turf/simulated/floor/plasteel{ - icon_state = "dark" - }, -/area/shuttle/escape) -"KY" = ( -/obj/machinery/light, -/turf/simulated/floor/plasteel{ - icon_state = "darkbluefull" - }, -/area/shuttle/escape) -"Mb" = ( -/obj/machinery/shieldgen/raven, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Nc" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/structure/chair/comfy/shuttle, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Nd" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"Nt" = ( -/obj/structure/table/reinforced, -/obj/machinery/recharger, -/obj/item/radio/intercom{ - name = "east bump"; - pixel_x = 28 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"Nu" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/structure/cable, -/obj/machinery/power/tesla_coil{ - anchored = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"NK" = ( -/obj/structure/table/reinforced, -/obj/machinery/kitchen_machine/microwave, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"NW" = ( -/obj/machinery/light/small{ - dir = 4; - pixel_y = 8 - }, -/obj/structure/closet/emcloset, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Oq" = ( -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/plasteel{ - icon_state = "darkbluefull" - }, -/area/shuttle/escape) -"OD" = ( -/obj/machinery/computer/secure_data{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 9; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"PK" = ( -/obj/machinery/power/port_gen/pacman/upgraded{ - anchored = 1 - }, -/obj/structure/cable{ - icon_state = "0-2" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"Qh" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/machinery/door_control{ - id = "mental_health"; - name = "Door Bolt Control"; - normaldoorcontrol = 1; - pixel_y = -25; - specialfunctions = 4 - }, -/turf/simulated/floor/mineral/silver, -/area/shuttle/escape) -"Qs" = ( -/turf/simulated/floor/plasteel{ - dir = 9; - icon_state = "darkyellowfull" - }, -/area/shuttle/escape) -"QM" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/structure/rack, -/obj/item/storage/firstaid/regular{ - pixel_x = 5; - pixel_y = 5 - }, -/obj/item/storage/firstaid/regular{ - pixel_x = 6; - pixel_y = -5 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"Rc" = ( -/obj/structure/table/reinforced, -/obj/item/storage/surgical_tray, -/obj/item/stack/nanopaste, -/obj/item/reagent_containers/glass/bottle/reagent/hydrocodone, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"Rh" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/structure/bed/roller, -/obj/machinery/iv_drip, -/turf/simulated/floor/plasteel{ - icon_state = "darkblue" - }, -/area/shuttle/escape) -"SQ" = ( -/obj/structure/rack, -/obj/item/storage/toolbox/electrical, -/obj/item/storage/toolbox/mechanical{ - pixel_y = 5 - }, -/obj/item/multitool, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"Tc" = ( -/obj/machinery/sleeper{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - icon_state = "darkblue" - }, -/area/shuttle/escape) -"UY" = ( -/obj/effect/turf_decal/blue_corner{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"Vf" = ( -/obj/effect/spawner/window/plastitanium, -/obj/machinery/door/poddoor/preopen{ - id = "ravenbridgeblast"; - name = "Cockpit Blast Door"; - id_tag = "ravenbridgeblast" - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"VM" = ( -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Wk" = ( -/turf/simulated/floor/plasteel{ - dir = 10; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"Wo" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Wq" = ( -/obj/effect/turf_decal/delivery/blue/partial{ - dir = 4 - }, -/obj/effect/turf_decal/delivery/blue/partial{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"WJ" = ( -/obj/machinery/recharge_station, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"WU" = ( -/turf/simulated/floor/plasteel{ - icon_state = "darkbluefull" - }, -/area/shuttle/escape) -"Xz" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/escape) -"XB" = ( -/obj/structure/closet/crate/internals, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"XO" = ( -/obj/structure/closet/secure_closet/engineering_welding, -/turf/simulated/floor/plasteel{ - icon_state = "darkyellow" - }, -/area/shuttle/escape) -"Yi" = ( -/turf/simulated/floor/plasteel{ - icon_state = "darkyellowcorners"; - dir = 4 - }, -/area/shuttle/escape) -"YC" = ( -/turf/simulated/floor/plasteel{ - dir = 6; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"Zg" = ( -/obj/structure/shuttle/engine/heater, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/structure/window/reinforced{ - dir = 1 - }, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) - -(1,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -jK -av -Vf -Vf -Vf -Vf -av -jK -iJ -iJ -iJ -fE -hv -av -av -iJ -iJ -iJ -iJ -iJ -"} -(2,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -av -DD -ut -jZ -yM -uW -DD -av -ul -qk -ul -gZ -VM -IF -Je -bm -iJ -iJ -iJ -iJ -"} -(3,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -bO -kO -OD -zb -zb -zb -Iu -Wk -Vf -ul -ul -ul -gZ -VM -NW -Je -dP -iJ -iJ -iJ -iJ -"} -(4,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -lj -kO -rd -UY -UY -UY -Cl -fR -av -av -av -av -av -gS -av -av -av -jK -iJ -iJ -iJ -"} -(5,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -vF -kO -Ko -lH -lH -lH -iY -DZ -av -jn -av -fH -IJ -lH -IJ -wS -av -av -iJ -iJ -iJ -"} -(6,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -jK -av -av -gZ -av -av -av -gZ -av -jK -iJ -iJ -iJ -av -av -ae -av -xv -wx -vk -av -Qh -av -Tc -WU -WU -WU -yg -nP -av -iJ -iJ -iJ -"} -(7,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -jK -av -av -av -av -av -av -hv -av -av -eP -UY -eL -av -tW -UY -eL -av -av -gZ -av -av -eP -WU -av -av -Vf -av -av -ii -av -bA -Wk -WU -WU -WU -Jb -av -dP -iJ -iJ -"} -(8,1,1) = {" -iJ -iJ -iJ -jK -av -av -av -gZ -av -av -av -SQ -wu -wF -XB -av -sT -Bn -av -Id -UY -rp -av -Id -UY -rp -av -fL -WJ -fL -av -eP -WU -fL -fL -fL -fL -av -VM -av -KQ -KT -Wk -WU -kr -xI -av -Zg -dP -iJ -"} -(9,1,1) = {" -jK -gZ -hv -av -av -ww -qS -fL -mS -fG -av -lH -lH -lH -lH -av -gS -av -av -HK -WU -lH -eh -lH -WU -nP -av -Oq -WU -WU -av -Nc -WU -lH -lH -lH -lH -jr -YC -dq -WU -Jd -Iu -Iu -Wk -Rc -av -av -IN -dP -"} -(10,1,1) = {" -yD -Wq -Wq -AK -Wq -Wq -Wq -Wq -Wq -Wq -dq -UY -UY -UY -UY -xj -UY -UY -dq -WU -UY -If -Bx -bV -UY -WU -dq -UY -UY -UY -dq -WU -UY -UY -UY -UY -UY -UY -uc -gs -bA -WU -yg -Wk -WU -ob -KL -av -IN -dP -"} -(11,1,1) = {" -jK -gZ -hv -av -av -KB -mS -ku -gX -sE -av -av -gS -av -Iu -Iu -Iu -Iu -av -gN -WU -Iu -EV -Iu -WU -rX -av -CL -WU -KY -av -eP -WU -Nt -NK -HL -Iu -EV -kg -dq -WU -yg -lH -lH -YC -Rc -av -av -IN -dP -"} -(12,1,1) = {" -iJ -iJ -iJ -jK -av -av -av -gZ -av -av -av -Bn -Ky -av -rg -Bi -QM -sx -av -bo -UY -ew -av -bo -UY -ew -av -ku -WJ -ku -av -eP -WU -av -gZ -av -wz -av -gZ -av -Rh -WU -WU -yg -jp -xI -av -qb -dP -iJ -"} -(13,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -jK -av -av -hv -av -av -av -av -av -av -eP -UY -Ek -av -eP -UY -eL -av -av -gZ -av -av -eP -WU -av -nX -DU -DU -DU -Xz -av -gU -WU -WU -WU -yg -Jb -av -dP -iJ -iJ -"} -(14,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -jK -av -av -gZ -av -av -av -gZ -av -jK -iJ -iJ -iJ -av -av -ek -av -nX -DU -DU -DU -Xz -av -bQ -WU -WU -WU -Jd -rX -av -iJ -iJ -iJ -"} -(15,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -bO -kO -ok -Yi -av -Hk -it -it -it -HE -av -kZ -of -of -Iu -Nd -av -av -iJ -iJ -iJ -"} -(16,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -lj -kO -XO -hs -av -av -av -av -av -av -av -av -av -gZ -FP -av -av -jK -iJ -iJ -iJ -"} -(17,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -vF -kO -cn -Qs -Qs -pV -gS -Wo -hv -ul -ul -ul -gZ -cF -Kg -Je -bm -iJ -iJ -iJ -iJ -"} -(18,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -av -Mb -PK -AS -Nu -av -IF -av -ul -qk -ul -gZ -yA -mV -Je -dP -iJ -iJ -iJ -iJ -"} -(19,1,1) = {" -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -iJ -jK -av -gZ -gZ -av -av -av -jK -iJ -iJ -iJ -gZ -gZ -gZ -gZ -iJ -iJ -iJ -iJ -iJ -"} diff --git a/_maps/map_files/shuttles/emergency_raven.dmm b/_maps/map_files/shuttles/emergency_raven.dmm deleted file mode 100644 index 1ce3370be64dc..0000000000000 --- a/_maps/map_files/shuttles/emergency_raven.dmm +++ /dev/null @@ -1,2208 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/template_noop, -/area/template_noop) -"ab" = ( -/obj/machinery/door/poddoor/preopen{ - id = "raven_cockpit_windows"; - name = "Cockpit Blast Door"; - id_tag = "raven_cockpit_windows" - }, -/obj/effect/spawner/window/plastitanium, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"ac" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ad" = ( -/obj/machinery/computer/security, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ae" = ( -/obj/structure/table/reinforced, -/obj/machinery/hologram/holopad, -/obj/machinery/recharger, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"af" = ( -/obj/machinery/computer/emergency_shuttle, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ag" = ( -/obj/structure/table/reinforced, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door_control{ - pixel_x = -5; - pixel_y = 6; - id = "raven_cockpit_windows"; - name = "Cockpit Window Blast Doors" - }, -/obj/machinery/turretid/lethal{ - req_access = list(18); - check_access = 0; - check_arrest = 0; - check_records = 0 - }, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ah" = ( -/obj/machinery/computer/communications, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ai" = ( -/obj/machinery/computer/aifixer, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ak" = ( -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"al" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"aq" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"av" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"aw" = ( -/obj/machinery/computer/station_alert{ - dir = 8 - }, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ax" = ( -/obj/structure/sign/electricshock, -/turf/simulated/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/escape) -"ay" = ( -/obj/machinery/computer/crew{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"aA" = ( -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"aC" = ( -/obj/effect/spawner/window/plastitanium, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"aE" = ( -/turf/simulated/floor/plasteel{ - icon_state = "darkbluecorners" - }, -/area/shuttle/escape) -"aG" = ( -/obj/machinery/computer/atmos_alert{ - dir = 8 - }, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"aI" = ( -/obj/structure/rack, -/obj/item/storage/toolbox/emergency, -/obj/item/wrench, -/obj/item/restraints/handcuffs, -/turf/simulated/floor/plasteel{ - dir = 10; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"aM" = ( -/obj/structure/rack, -/obj/item/tank/internals/oxygen/red, -/obj/item/clothing/mask/gas, -/obj/effect/decal/cleanable/dirt, -/obj/item/extinguisher, -/turf/simulated/floor/plasteel{ - dir = 6; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"aN" = ( -/obj/machinery/porta_turret/ai_turret, -/turf/simulated/wall/mineral/plastitanium, -/area/shuttle/escape) -"aO" = ( -/turf/simulated/wall/mineral/plastitanium, -/area/shuttle/escape) -"aP" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/obj/structure/chair/comfy/shuttle, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"aQ" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/structure/chair/comfy/shuttle, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"aR" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/obj/structure/chair/comfy/shuttle, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"aT" = ( -/obj/machinery/computer/operating, -/turf/simulated/floor/plasteel{ - dir = 9; - icon_state = "whiteblue" - }, -/area/shuttle/escape) -"aU" = ( -/obj/item/surgical_drapes, -/obj/machinery/optable, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "whiteblue" - }, -/area/shuttle/escape) -"aV" = ( -/obj/structure/table/reinforced, -/obj/item/storage/surgical_tray, -/obj/item/reagent_containers/glass/bottle/reagent/hydrocodone, -/obj/item/stack/nanopaste, -/turf/simulated/floor/plasteel{ - dir = 5; - icon_state = "whiteblue" - }, -/area/shuttle/escape) -"aW" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/obj/item/storage/box/handcuffs{ - pixel_x = 2; - pixel_y = 2 - }, -/obj/item/restraints/handcuffs{ - pixel_y = 3 - }, -/obj/effect/decal/cleanable/dirt, -/obj/structure/table/reinforced, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"aX" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"aY" = ( -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"aZ" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"ba" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"bb" = ( -/obj/machinery/light/spot, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"bc" = ( -/obj/effect/turf_decal/delivery/white, -/obj/machinery/door/poddoor/preopen{ - id = "ravenbridgeblast"; - name = "Cockpit Blast Door"; - id_tag = "ravenbridgeblast" - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"be" = ( -/obj/structure/chair/office/light{ - dir = 1 - }, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "whitebluecorner" - }, -/area/shuttle/escape) -"bf" = ( -/turf/simulated/floor/plasteel/white, -/area/shuttle/escape) -"bh" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/spot{ - dir = 4 - }, -/obj/machinery/sleeper, -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "whiteblue" - }, -/area/shuttle/escape) -"bi" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/item/book/manual/wiki/security_space_law{ - pixel_x = -4; - pixel_y = 4 - }, -/obj/structure/table/reinforced, -/obj/machinery/light/spot{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"bj" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"bk" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Holding Area" - }, -/obj/effect/mapping_helpers/airlock/access/all/security/general, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"bl" = ( -/obj/effect/turf_decal/stripes/white/end{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"bn" = ( -/obj/effect/turf_decal/stripes/white/end{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"bo" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/medical/glass{ - name = "Escape Shuttle Infirmary" - }, -/obj/effect/mapping_helpers/airlock/access/all/command/general, -/turf/simulated/floor/plasteel/white, -/area/shuttle/escape) -"br" = ( -/obj/effect/spawner/window/plastitanium, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"bt" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"bu" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"bv" = ( -/obj/effect/turf_decal/stripes/corner, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"bw" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"bx" = ( -/obj/machinery/door/airlock/command/glass{ - name = "Cockpit" - }, -/obj/effect/mapping_helpers/airlock/access/all/command/general, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"by" = ( -/obj/structure/closet/crate/freezer/iv_storage, -/turf/simulated/floor/plasteel{ - dir = 10; - icon_state = "whiteblue" - }, -/area/shuttle/escape) -"bC" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/table/reinforced, -/obj/machinery/recharger, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"bD" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"bE" = ( -/obj/effect/turf_decal/stripes/line, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"bF" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/turf/simulated/floor/mineral/plastitanium/red/brig, -/area/shuttle/escape) -"bJ" = ( -/obj/machinery/economy/vending/medical, -/turf/simulated/floor/plasteel{ - dir = 10; - icon_state = "whiteblue" - }, -/area/shuttle/escape) -"bL" = ( -/obj/structure/table/reinforced, -/obj/item/defibrillator/loaded, -/turf/simulated/floor/plasteel{ - dir = 6; - icon_state = "whiteblue" - }, -/area/shuttle/escape) -"bM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/table/reinforced, -/obj/item/storage/firstaid/regular/doctor, -/obj/item/storage/firstaid/toxin, -/turf/simulated/floor/plasteel/white, -/area/shuttle/escape) -"bN" = ( -/obj/structure/sign/security, -/turf/simulated/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/escape) -"bO" = ( -/obj/structure/closet/firecloset, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"bR" = ( -/obj/structure/closet/emcloset, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"bS" = ( -/obj/structure/sign/lifestar, -/turf/simulated/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/escape) -"bT" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Escape Shuttle Infirmary" - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"bU" = ( -/obj/structure/closet/emcloset, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"bV" = ( -/obj/structure/rack, -/obj/item/storage/toolbox/emergency, -/obj/item/radio, -/obj/item/clothing/mask/gas, -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = 3 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"bW" = ( -/obj/effect/turf_decal/raven/eight, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cb" = ( -/obj/structure/rack, -/obj/item/storage/toolbox/mechanical, -/obj/item/radio, -/obj/item/clothing/mask/gas, -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = 3 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"cc" = ( -/obj/structure/closet/emcloset, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"cd" = ( -/obj/machinery/door/airlock/external{ - id_tag = "s_docking_airlock" - }, -/obj/structure/fans/tiny, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"ce" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"cf" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"cg" = ( -/obj/structure/sign/vacuum/external, -/turf/simulated/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/escape) -"ch" = ( -/obj/effect/turf_decal/stripes/white/corner{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cl" = ( -/obj/effect/turf_decal/stripes/white/corner, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cm" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"co" = ( -/obj/machinery/porta_turret/ai_turret, -/turf/simulated/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/escape) -"cr" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cs" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 4 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ct" = ( -/obj/machinery/door/airlock/external/glass, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"cu" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"cv" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"cx" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"cy" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"cz" = ( -/obj/effect/turf_decal/stripes/white/corner{ - dir = 1 - }, -/obj/structure/extinguisher_cabinet{ - name = "west bump"; - pixel_x = -27 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cB" = ( -/obj/machinery/hologram/holopad, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cC" = ( -/obj/effect/turf_decal/stripes/white/corner{ - dir = 4 - }, -/obj/structure/extinguisher_cabinet{ - name = "east bump"; - pixel_x = 27 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cD" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"cE" = ( -/obj/machinery/suit_storage_unit/standard_unit, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"cL" = ( -/obj/effect/turf_decal/stripes/white/line, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cM" = ( -/obj/effect/turf_decal/stripes/white/line, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cP" = ( -/turf/simulated/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/escape) -"cR" = ( -/obj/effect/turf_decal/delivery/white, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "escape_cargo_shutters"; - name = "Cargo Bay Shutters"; - id_tag = "escape_cargo_shutters"; - dir = 2 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cT" = ( -/obj/machinery/suit_storage_unit/standard_unit, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"cU" = ( -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = 3 - }, -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = 3 - }, -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = 3 - }, -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = 3 - }, -/obj/item/tank/internals/emergency_oxygen{ - 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/structure/closet/crate/internals, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cV" = ( -/obj/structure/closet/emcloset, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cW" = ( -/obj/effect/turf_decal/box/white/corners{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/structure/rack, -/obj/item/storage/toolbox/electrical{ - pixel_x = -3; - pixel_y = 1 - }, -/obj/item/storage/toolbox/mechanical{ - pixel_y = -1 - }, -/obj/item/storage/toolbox/emergency{ - pixel_x = 3; - pixel_y = -5 - }, -/obj/item/multitool, -/obj/machinery/door_control{ - id = "escape_cargo_shutters"; - name = "Warehouse Door Control"; - pixel_x = -1; - pixel_y = 24; - req_access = list(31) - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cX" = ( -/obj/effect/turf_decal/box/white/corners{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cY" = ( -/obj/effect/turf_decal/box/white/corners{ - dir = 4 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"cZ" = ( -/obj/effect/turf_decal/box/white/corners{ - dir = 4 - }, -/obj/structure/rack, -/obj/item/tank/internals/oxygen/red, -/obj/item/clothing/mask/gas, -/obj/machinery/door_control{ - id = "qm_warehouse"; - name = "Warehouse Door Control"; - pixel_x = -1; - pixel_y = 24; - req_access = list(31) - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"da" = ( -/obj/machinery/door/airlock/public/glass{ - name = "Emergency Shuttle Seating" - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"db" = ( -/obj/structure/closet/crate/medical, -/obj/item/healthanalyzer{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/lazarus_injector, -/mob/living/simple_animal/bot/medbot{ - name = "\improper emergency medibot"; - pixel_x = -3; - pixel_y = 2 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"dd" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"de" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/public/glass{ - name = "Emergency Shuttle Seating" - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"df" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"dg" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 6 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"dh" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 1 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"di" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 10 - }, -/obj/machinery/light/small{ - dir = 4; - pixel_y = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"dj" = ( -/obj/effect/turf_decal/box/white/corners{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/space_heater, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"dk" = ( -/obj/effect/turf_decal/box/white/corners, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"dl" = ( -/obj/effect/turf_decal/box/white/corners{ - dir = 1 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"dm" = ( -/obj/effect/turf_decal/box/white/corners, -/obj/effect/decal/cleanable/dirt, -/obj/structure/reagent_dispensers/fueltank, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"dn" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"do" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 10 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"dq" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"du" = ( -/obj/structure/rack, -/obj/item/storage/toolbox/mechanical, -/obj/item/radio, -/obj/item/clothing/mask/gas, -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = 3 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"dv" = ( -/obj/structure/rack, -/obj/item/crowbar, -/obj/item/wrench, -/obj/item/flashlight, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"dw" = ( -/obj/structure/rack, -/obj/effect/decal/cleanable/dirt, -/obj/item/storage/belt/utility, -/obj/item/radio/off{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/radio/off, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"dx" = ( -/obj/structure/rack, -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/medical/bruise_pack, -/obj/item/stack/medical/ointment{ - pixel_x = 5 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"dy" = ( -/obj/structure/rack, -/obj/item/storage/toolbox/mechanical, -/obj/item/multitool{ - pixel_x = 7; - pixel_y = -4 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"dz" = ( -/obj/structure/rack, -/obj/item/storage/toolbox/emergency, -/obj/item/radio, -/obj/item/clothing/mask/gas, -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = 3 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"dA" = ( -/obj/machinery/door/airlock/engineering{ - name = "Emergency Shuttle Engineering" - }, -/obj/effect/mapping_helpers/airlock/access/any/engineering/atmos, -/obj/effect/mapping_helpers/airlock/access/any/engineering/general, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"dB" = ( -/obj/structure/sign/engineering, -/turf/simulated/wall/mineral/plastitanium/nodiagonal, -/area/shuttle/escape) -"dE" = ( -/turf/simulated/floor/plating, -/area/shuttle/escape) -"dH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/secure_closet/engineering_personal, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"dI" = ( -/obj/structure/closet/secure_closet/engineering_personal, -/obj/structure/extinguisher_cabinet{ - name = "north bump"; - pixel_y = 30 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"dQ" = ( -/obj/machinery/recharge_station, -/obj/structure/extinguisher_cabinet{ - name = "north bump"; - pixel_y = 30 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"dR" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/recharge_station, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"dS" = ( -/obj/machinery/shieldgen/raven, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"dT" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"dV" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/shieldgen/raven, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"ed" = ( -/obj/structure/cable, -/obj/machinery/power/port_gen/pacman/upgraded{ - anchored = 1 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"el" = ( -/obj/machinery/light/spot{ - dir = 1 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"em" = ( -/obj/structure/shuttle/engine/propulsion, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"en" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/spot, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"eo" = ( -/obj/docking_port/mobile/emergency{ - dwidth = 15; - height = 21; - width = 33; - timid = 1 - }, -/obj/machinery/door/airlock/external{ - id_tag = "s_docking_airlock" - }, -/obj/structure/fans/tiny, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"ep" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/obj/machinery/light/spot{ - dir = 1 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"fc" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/structure/window/plasmareinforced, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"fn" = ( -/obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"fD" = ( -/obj/machinery/space_heater, -/obj/structure/window/plasmareinforced, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"gL" = ( -/obj/machinery/computer/med_data{ - dir = 4 - }, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"hu" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"jL" = ( -/turf/simulated/floor/plasteel{ - dir = 6; - icon_state = "whiteblue" - }, -/area/shuttle/escape) -"jZ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/machinery/power/tesla_coil{ - anchored = 1 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"ky" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/obj/machinery/light/spot{ - dir = 1 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"kF" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 6 - }, -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ly" = ( -/obj/machinery/door/airlock/hatch, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"lB" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/table/reinforced, -/obj/item/clothing/glasses/meson/engine, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"lC" = ( -/turf/simulated/floor/plasteel{ - dir = 5; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"ml" = ( -/obj/effect/turf_decal/raven/three, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"nK" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/stack/sheet/mineral/plastitanium{ - amount = 50; - pixel_x = -2; - pixel_y = 2 - }, -/obj/structure/table/reinforced, -/obj/structure/window/plasmareinforced, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"op" = ( -/obj/machinery/light/spot, -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 6; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"ou" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/obj/structure/window/reinforced{ - dir = 4 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ph" = ( -/obj/effect/turf_decal/raven/one, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"qa" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 4 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"qC" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/cell_charger, -/obj/item/stock_parts/cell/high, -/obj/structure/table/reinforced, -/obj/structure/window/plasmareinforced, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"rq" = ( -/turf/simulated/floor/plasteel{ - icon_state = "whitebluecorner" - }, -/area/shuttle/escape) -"sr" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/window/plasmareinforced, -/obj/structure/closet/secure_closet/engineering_welding, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"ss" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"uM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/spot, -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/plasteel{ - dir = 10; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"vw" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/window/plasmareinforced, -/obj/structure/closet/secure_closet/engineering_electrical, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"wi" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/table/reinforced, -/obj/item/assembly/signaler, -/obj/item/assembly/signaler, -/obj/item/assembly/signaler, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"wp" = ( -/obj/machinery/iv_drip, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "whitebluecorner" - }, -/area/shuttle/escape) -"wr" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/shieldgen/raven, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"xH" = ( -/obj/machinery/light/spot{ - dir = 1 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"yY" = ( -/turf/simulated/floor/plasteel{ - dir = 9; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"zo" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/machinery/power/tesla_coil{ - anchored = 1 - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"zR" = ( -/obj/machinery/door_control{ - id = "ravenbridgeblast"; - name = "Cockpick Airlock Blastdoor Control"; - pixel_x = 5; - pixel_y = -35; - req_access = list(19) - }, -/obj/effect/turf_decal/raven/two, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"zT" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"zV" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/computer/secure_data, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"An" = ( -/obj/effect/turf_decal/caution, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"AO" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 8 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"By" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/sleeper, -/turf/simulated/floor/plasteel{ - dir = 5; - icon_state = "whiteblue" - }, -/area/shuttle/escape) -"BD" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"BW" = ( -/turf/simulated/floor/plasteel{ - dir = 9; - icon_state = "darkred" - }, -/area/shuttle/escape) -"Db" = ( -/obj/effect/turf_decal/raven/nine, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Ge" = ( -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkblue" - }, -/area/shuttle/escape) -"GL" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/computer/med_data{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - dir = 9; - icon_state = "whiteblue" - }, -/area/shuttle/escape) -"HB" = ( -/obj/effect/turf_decal/stripes/white/corner{ - dir = 8 - }, -/obj/machinery/door_control{ - id = "escape_cargo_shutters"; - name = "Warehouse Door Control"; - pixel_x = -1; - pixel_y = -24; - req_access = list(31) - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"HN" = ( -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "whitebluecorner" - }, -/area/shuttle/escape) -"Ia" = ( -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkred" - }, -/area/shuttle/escape) -"Jx" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/obj/structure/window/reinforced{ - dir = 4 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"JM" = ( -/obj/structure/shuttle/engine/large, -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"JO" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/obj/machinery/light/spot, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"Kd" = ( -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "whiteblue" - }, -/area/shuttle/escape) -"Kk" = ( -/obj/effect/mapping_helpers/airlock/access/any/engineering/atmos, -/obj/effect/mapping_helpers/airlock/access/any/engineering/general, -/obj/machinery/door/airlock/engineering{ - name = "Emergency Shuttle Engineering" - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"Ls" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/storage/toolbox/electrical{ - pixel_x = -2; - pixel_y = 5 - }, -/obj/item/storage/toolbox/mechanical, -/obj/structure/table/reinforced, -/obj/item/multitool, -/obj/structure/window/plasmareinforced, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"Mm" = ( -/obj/item/stack/sheet/plastitaniumglass{ - amount = 20; - pixel_x = -2; - pixel_y = 2 - }, -/obj/item/stack/sheet/glass{ - amount = 20; - pixel_x = 2; - pixel_y = -2 - }, -/obj/structure/table/reinforced, -/obj/structure/window/plasmareinforced, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"Na" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Nd" = ( -/obj/structure/window/plasmareinforced, -/obj/structure/dispenser, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"Ng" = ( -/obj/effect/turf_decal/raven/five, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"NK" = ( -/obj/structure/rack, -/obj/item/storage/box/lights/tubes, -/obj/structure/window/plasmareinforced, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"NQ" = ( -/obj/effect/turf_decal/raven/four, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Ob" = ( -/obj/structure/reagent_dispensers/fueltank, -/obj/structure/window/plasmareinforced, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"Pa" = ( -/obj/machinery/light/spot, -/obj/structure/chair/comfy/shuttle{ - dir = 1 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Px" = ( -/obj/machinery/shieldgen/raven, -/obj/effect/turf_decal/delivery/white/hollow, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Rw" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"Sa" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"Sk" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "darkred" - }, -/area/shuttle/escape) -"So" = ( -/turf/simulated/floor/plating/airless, -/area/shuttle/escape) -"Ux" = ( -/obj/effect/turf_decal/stripes/white/corner, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door_control{ - id = "escape_cargo_shutters"; - name = "Warehouse Door Control"; - pixel_x = -1; - pixel_y = -24; - req_access = list(31) - }, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"US" = ( -/turf/simulated/floor/plasteel{ - icon_state = "whiteblue" - }, -/area/shuttle/escape) -"Xd" = ( -/obj/effect/turf_decal/raven/seven, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"YX" = ( -/obj/effect/turf_decal/raven/six, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ZA" = ( -/obj/effect/turf_decal/stripes/white/line, -/obj/effect/turf_decal/stripes/white/line{ - dir = 1 - }, -/obj/machinery/light/spot, -/turf/simulated/floor/plasteel/dark, -/area/shuttle/escape) -"ZF" = ( -/obj/structure/window/plasmareinforced, -/obj/machinery/atmospherics/portable/canister/air, -/turf/simulated/floor/plating, -/area/shuttle/escape) -"ZM" = ( -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/table/reinforced, -/obj/item/stack/sheet/mineral/plasma/fifty, -/turf/simulated/floor/plating, -/area/shuttle/escape) - -(1,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aO -cP -cd -co -eo -cP -aO -aa -aO -cP -cd -co -cd -cP -aO -aa -aa -aa -aa -aa -aa -"} -(2,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aN -br -cP -cP -bU -ce -cu -cx -cE -cP -br -cP -cT -ce -df -cx -bU -cP -cP -br -aN -aa -aa -aa -"} -(3,1,1) = {" -aa -aa -aa -aa -aa -aa -aO -cP -cP -wr -cP -cP -bV -cf -cv -en -cP -cP -Px -cP -cP -ep -cv -cD -du -cP -cP -dS -cP -aO -aa -aa -"} -(4,1,1) = {" -aa -aa -aa -aa -aa -aN -cP -aW -bi -bt -bC -cP -cP -cg -ct -cP -cP -hu -ak -hu -cP -cP -ct -cg -cP -cP -dH -dE -nK -cP -aN -aa -"} -(5,1,1) = {" -aa -aa -aa -aa -aa -cP -aP -bu -aY -aZ -bD -br -Sk -ch -cr -cz -ac -ak -ak -ak -cU -aC -dg -AO -dv -cP -dI -dE -Mm -cP -So -JM -"} -(6,1,1) = {" -aa -ab -ab -ab -cP -cP -aQ -aY -aY -aY -bE -bk -Ia -Jx -Jx -Jx -Jx -Jx -ak -ak -ak -da -dh -ak -ak -dA -dE -dE -Nd -fn -So -So -"} -(7,1,1) = {" -ab -ab -Px -gL -ay -cP -aR -aX -aY -bv -bF -br -Ia -Rw -Rw -zT -Rw -Rw -ak -ak -cV -aC -di -dq -dw -dB -dE -dE -fc -fn -em -aa -"} -(8,1,1) = {" -ab -zV -yY -aq -uM -cP -cP -ba -bj -bw -cP -bN -el -ak -ak -ak -ak -ak -bb -cP -cP -cP -cP -ly -cP -ax -xH -dT -Ob -fn -em -aa -"} -(9,1,1) = {" -ab -ad -al -ak -aA -aI -cP -cP -bk -cP -cP -bO -ak -Jx -Jx -Jx -Jx -Jx -Ux -cP -cW -db -dj -ak -cP -jZ -dE -dE -vw -fn -So -JM -"} -(10,1,1) = {" -ab -ae -Ge -Xd -NQ -ph -bx -bc -bl -bx -BW -ak -ak -Rw -Rw -Rw -zT -Rw -cL -cR -cY -ac -dk -ak -cP -wi -dE -dE -cP -cP -So -So -"} -(11,1,1) = {" -ab -af -al -bW -Ng -zR -cP -bc -ZA -cP -An -ak -ak -ak -ac -cB -ak -ak -cM -cR -ak -ak -ak -Pa -cP -ZM -Sa -Sa -ed -cP -cP -aa -"} -(12,1,1) = {" -ab -ag -Ge -Db -YX -ml -bx -bc -bn -bx -lC -ac -ak -ou -Jx -Jx -Jx -Jx -cM -cR -dl -ak -cX -ak -cP -lB -dE -dE -cP -cP -So -JM -"} -(13,1,1) = {" -ab -ah -al -ak -aE -aM -cP -cP -bo -cP -cP -bR -ak -Rw -Rw -Rw -Rw -Rw -HB -cP -cZ -dd -dm -ac -cP -zo -dE -dE -sr -fn -So -So -"} -(14,1,1) = {" -ab -ai -lC -av -op -cP -cP -GL -Kd -by -cP -bS -el -ak -ak -ak -ak -ak -bb -cP -cP -cP -cP -ly -cP -ax -xH -dE -fD -fn -em -aa -"} -(15,1,1) = {" -ab -ab -wr -aw -aG -cP -aT -be -bf -wp -bJ -br -Ge -Jx -Jx -Jx -Jx -ou -ak -ak -bO -aC -kF -cr -dx -dB -dE -dE -ZF -fn -em -aa -"} -(16,1,1) = {" -aa -ab -ab -ab -cP -cP -aU -bf -bf -bf -US -bT -ss -Rw -Rw -Rw -Rw -Rw -ak -ak -ak -de -dn -ak -ak -Kk -dE -dE -NK -fn -So -JM -"} -(17,1,1) = {" -aa -aa -aa -aa -aa -cP -aV -HN -bf -rq -bL -br -ss -cl -cs -cC -ak -ak -ak -ak -cU -aC -do -qa -dy -cP -dQ -dT -qC -cP -So -So -"} -(18,1,1) = {" -aa -aa -aa -aa -aa -aN -cP -By -bh -jL -bM -cP -cP -cg -ct -cP -cP -Na -ak -BD -cP -cP -ct -cg -cP -cP -dR -dE -Ls -cP -aN -aa -"} -(19,1,1) = {" -aa -aa -aa -aa -aa -aa -aO -cP -cP -Px -cP -cP -cb -cm -cu -JO -cP -cP -wr -cP -cP -ky -cu -cx -dz -cP -cP -dV -cP -aO -aa -aa -"} -(20,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aN -br -cP -cP -cc -cf -cv -cD -cE -cP -br -cP -cE -cf -cv -cy -cc -cP -cP -br -aN -aa -aa -aa -"} -(21,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aO -cP -cd -co -cd -cP -aO -aa -aO -cP -cd -co -cd -cP -aO -aa -aa -aa -aa -aa -aa -"} diff --git a/_maps/map_files/stations/cerestation.jsonc b/_maps/map_files/stations/cerestation.jsonc deleted file mode 100644 index 0ce5cb481539f..0000000000000 --- a/_maps/map_files/stations/cerestation.jsonc +++ /dev/null @@ -1,13 +0,0 @@ -[ - { - // Engineering-Science maintenance, can either be separated by space or have a passage between the asteroids - "type": "SubmapExtractInsert", - "submap_size_x": 6, - "submap_size_y": 22, - "submap_size_z": 1, - "submaps_dmm": "submaps/cerestation.dmm", - "marker_extract": "/obj/effect/map_effect/marker/mapmanip/submap/extract/station/cerestation/engineering_science", - "marker_insert": "/obj/effect/map_effect/marker/mapmanip/submap/insert/station/cerestation/engineering_science", - "submaps_can_repeat": true // doesn't matter, as there's only one insert marker - } -] diff --git a/_maps/map_files/templates/biodome_beach.dmm b/_maps/map_files/templates/biodome_beach.dmm deleted file mode 100644 index c622e6cca4d53..0000000000000 --- a/_maps/map_files/templates/biodome_beach.dmm +++ /dev/null @@ -1,1523 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/template_noop, -/area/template_noop) -"ab" = ( -/obj/effect/turf_decal/sand, -/obj/structure/table, -/obj/item/storage/box/donkpockets, -/turf/simulated/floor/pod/dark, -/area/ruin/powered/beach) -"ac" = ( -/obj/effect/turf_decal/sand, -/obj/structure/table, -/obj/item/storage/box/beakers, -/turf/simulated/floor/pod/dark, -/area/ruin/powered/beach) -"ad" = ( -/obj/structure/flora/ausbushes/leafybush, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"ae" = ( -/obj/structure/table, -/obj/item/storage/toolbox/mechanical, -/obj/item/stack/cable_coil, -/obj/item/storage/box/lights/mixed, -/obj/effect/turf_decal/sand, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/pod/dark, -/area/ruin/powered/beach) -"af" = ( -/obj/effect/turf_decal/sand, -/obj/structure/reagent_dispensers/fueltank, -/turf/simulated/floor/pod/dark, -/area/ruin/powered/beach) -"ag" = ( -/obj/machinery/light{ - dir = 8 - }, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"ah" = ( -/obj/effect/turf_decal/sand, -/obj/effect/turf_decal/sand, -/obj/machinery/light, -/turf/simulated/floor/pod/dark, -/area/ruin/powered/beach) -"ai" = ( -/obj/structure/extinguisher_cabinet{ - name = "custom placement"; - pixel_y = 29 - }, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"aj" = ( -/turf/simulated/wall/mineral/sandstone, -/area/ruin/powered/beach) -"ak" = ( -/obj/machinery/door/airlock/sandstone{ - name = "Bar Storage" - }, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/plating, -/area/ruin/powered/beach) -"am" = ( -/obj/structure/table, -/obj/item/kitchen/rollingpin, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"an" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/structure/toilet{ - dir = 4 - }, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/plating, -/area/ruin/powered/beach) -"ao" = ( -/obj/structure/sink{ - dir = 4; - pixel_x = 11 - }, -/obj/structure/mirror{ - pixel_x = 28 - }, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/plating, -/area/ruin/powered/beach) -"ap" = ( -/obj/structure/flora/ausbushes/sparsegrass, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"aq" = ( -/obj/structure/flora/ausbushes/sunnybush, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"ar" = ( -/obj/effect/turf_decal/sand, -/turf/simulated/floor/plating, -/area/ruin/powered/beach) -"as" = ( -/obj/machinery/chem_dispenser/beer, -/obj/structure/table, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"at" = ( -/obj/structure/chair/wood, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"au" = ( -/obj/structure/table, -/obj/item/reagent_containers/condiment/flour, -/obj/item/reagent_containers/condiment/flour, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"av" = ( -/obj/structure/table/wood, -/obj/machinery/door/window/classic/reversed{ - dir = 8; - name = "Beach Bar Desk" - }, -/obj/item/reagent_containers/drinks/shaker, -/obj/item/reagent_containers/glass/rag, -/obj/effect/mapping_helpers/airlock/windoor/access/any/service/bar{ - dir = 8 - }, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"aw" = ( -/obj/machinery/chem_dispenser/soda, -/obj/structure/table, -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"ax" = ( -/obj/machinery/disco/immobile, -/turf/simulated/floor/light, -/area/ruin/powered/beach) -"ay" = ( -/obj/machinery/door/airlock/sandstone{ - name = "Restroom" - }, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/plating, -/area/ruin/powered/beach) -"az" = ( -/obj/item/clothing/neck/necklace/dope, -/obj/item/reagent_containers/spray/spraytan, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"aA" = ( -/obj/item/reagent_containers/spray/spraytan, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"aB" = ( -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"aC" = ( -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"aE" = ( -/obj/structure/table/wood, -/obj/machinery/door/window/classic/normal{ - dir = 8; - name = "Beach Bar Desk" - }, -/obj/effect/mapping_helpers/airlock/windoor/access/any/service/bar{ - dir = 8 - }, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"aG" = ( -/obj/effect/turf_decal/sand, -/obj/effect/turf_decal/sand, -/obj/item/flashlight/lantern, -/turf/simulated/floor/plating, -/area/ruin/powered/beach) -"aI" = ( -/obj/machinery/economy/vending/dinnerware, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"aJ" = ( -/obj/structure/closet/crate, -/obj/item/tank/internals/emergency_oxygen, -/obj/item/trash/candy, -/obj/effect/turf_decal/sand, -/obj/item/toy/figure/crew/bartender, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"aK" = ( -/obj/effect/turf_decal/sand, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"aL" = ( -/obj/effect/turf_decal/sand, -/obj/machinery/economy/vending/cigarette/beach, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"aN" = ( -/obj/effect/turf_decal/sand, -/obj/machinery/economy/vending/cola/free, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"aQ" = ( -/obj/structure/table/wood, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"aR" = ( -/obj/machinery/door/airlock/sandstone{ - name = "Bar" - }, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/plating, -/area/ruin/powered/beach) -"aU" = ( -/obj/effect/overlay/palmtree_l, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"aZ" = ( -/obj/effect/overlay/coconut, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bi" = ( -/obj/structure/closet/athletic_mixed, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"bj" = ( -/obj/structure/rack, -/obj/item/clothing/shoes/sandal, -/obj/item/clothing/shoes/sandal, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"bk" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"bl" = ( -/obj/effect/turf_decal/sand, -/turf/simulated/floor/pod/light, -/area/ruin/powered/beach) -"bm" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bn" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bo" = ( -/obj/machinery/shower{ - dir = 4 - }, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/pod/light, -/area/ruin/powered/beach) -"bp" = ( -/obj/machinery/light/small{ - dir = 8; - light_power = 3 - }, -/obj/effect/turf_decal/sand, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"bq" = ( -/obj/effect/turf_decal/sand, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"br" = ( -/obj/effect/baseturf_helper/lava/mapping_lava, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bx" = ( -/obj/structure/flora/rock, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bz" = ( -/mob/living/simple_animal/crab, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bA" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/item/bikehorn/airhorn, -/obj/structure/table/wood, -/obj/item/storage/firstaid/regular, -/obj/item/storage/firstaid/brute, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"bB" = ( -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/structure/window/reinforced{ - dir = 1; - layer = 2.9 - }, -/obj/structure/chair/stool, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"bE" = ( -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bF" = ( -/obj/item/beach_ball, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bG" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/structure/window/reinforced, -/obj/item/megaphone, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"bH" = ( -/obj/structure/window/reinforced{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"bJ" = ( -/obj/structure/chair, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bK" = ( -/obj/item/storage/backpack/duffel, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bL" = ( -/obj/machinery/poolcontroller/invisible, -/turf/simulated/floor/beach/water, -/area/ruin/powered/beach) -"bM" = ( -/turf/simulated/floor/plasteel/stairs, -/area/ruin/powered/beach) -"bN" = ( -/obj/structure/flora/ausbushes/reedbush, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bO" = ( -/obj/item/camera, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bP" = ( -/obj/item/reagent_containers/drinks/bottle/beer, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"bQ" = ( -/obj/structure/flora/ausbushes/reedbush, -/turf/simulated/floor/beach/coastline_t, -/area/ruin/powered/beach) -"bR" = ( -/turf/simulated/floor/beach/coastline_t, -/area/ruin/powered/beach) -"bS" = ( -/obj/structure/flora/ausbushes/sparsegrass, -/turf/simulated/floor/beach/coastline_t, -/area/ruin/powered/beach) -"bT" = ( -/turf/simulated/floor/beach/coastline_b, -/area/ruin/powered/beach) -"bU" = ( -/turf/simulated/floor/beach/water, -/area/ruin/powered/beach) -"bV" = ( -/obj/structure/flora/ausbushes/stalkybush, -/turf/simulated/floor/beach/water, -/area/ruin/powered/beach) -"bW" = ( -/turf/simulated/wall/r_wall, -/area/ruin/powered/beach) -"cs" = ( -/obj/effect/overlay/palmtree_l, -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"ct" = ( -/obj/machinery/light, -/turf/simulated/floor/beach/water, -/area/ruin/powered/beach) -"cP" = ( -/obj/structure/flora/tree/palm{ - pixel_x = -7; - pixel_y = 18 - }, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"cR" = ( -/obj/structure/table/wood, -/obj/item/tank/internals/oxygen, -/obj/item/pickaxe, -/obj/item/clothing/mask/gas, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"gg" = ( -/obj/effect/turf_decal/sand, -/turf/simulated/floor/pod/dark, -/area/ruin/powered/beach) -"lh" = ( -/obj/structure/weightmachine/stacklifter, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"lF" = ( -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/pod/light/lavaland_air, -/area/ruin/powered/beach) -"lM" = ( -/obj/structure/dresser, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"mh" = ( -/obj/effect/spawner/window, -/turf/simulated/floor/plating, -/area/ruin/powered/beach) -"pI" = ( -/obj/machinery/door/airlock/hatch{ - name = "Lava Beach Club" - }, -/obj/structure/fans/tiny, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"qa" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"qe" = ( -/obj/machinery/barsign{ - pixel_y = 32 - }, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"qT" = ( -/obj/machinery/shower{ - dir = 8 - }, -/turf/simulated/floor/pod/light, -/area/ruin/powered/beach) -"sp" = ( -/obj/structure/chair/wood{ - dir = 1 - }, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"uA" = ( -/obj/item/beacon, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"uP" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/structure/flora/rock, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"yc" = ( -/obj/structure/weightmachine/weightlifter, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"zw" = ( -/obj/structure/closet/athletic_mixed, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"Bl" = ( -/obj/machinery/light{ - dir = 8 - }, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"Ec" = ( -/obj/machinery/door/airlock/sandstone{ - name = "Beach Access" - }, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"Ei" = ( -/obj/machinery/door/airlock/sandstone{ - name = "Bar Kitchen" - }, -/obj/effect/mapping_helpers/airlock/access/any/service/bar, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"Gc" = ( -/turf/simulated/floor/pod/light, -/area/ruin/powered/beach) -"HC" = ( -/obj/structure/rack, -/obj/item/clothing/shoes/sandal, -/obj/item/clothing/shoes/sandal, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"JF" = ( -/obj/structure/table/reinforced, -/obj/machinery/reagentgrinder, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"Pl" = ( -/obj/effect/turf_decal/sand/plating, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"QM" = ( -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"QS" = ( -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/beach/sand, -/area/ruin/powered/beach) -"TD" = ( -/turf/template_noop, -/area/ruin/powered/beach) -"TP" = ( -/obj/machinery/light{ - dir = 8 - }, -/turf/simulated/floor/pod/light/lavaland_air, -/area/ruin/powered/beach) -"TW" = ( -/obj/structure/table/reinforced, -/obj/machinery/kitchen_machine/microwave, -/turf/simulated/floor/wood, -/area/ruin/powered/beach) -"VO" = ( -/turf/simulated/floor/pod, -/area/ruin/powered/beach) -"Xp" = ( -/obj/machinery/light/small{ - dir = 8; - light_power = 3 - }, -/turf/simulated/floor/pod, -/area/ruin/powered/beach) - -(1,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -lF -TD -bW -bW -bW -pI -bW -pI -bW -bW -bW -TD -lF -aa -aa -aa -aa -aa -aa -aa -aa -"} -(2,1,1) = {" -aa -aa -aa -aa -aa -aa -bW -bW -bW -bW -bW -bW -zw -Xp -Gc -bo -Gc -bp -cR -bW -bW -bW -bW -bW -aa -aa -aa -aa -aa -aa -"} -(3,1,1) = {" -aa -aa -aa -aa -bW -bW -bW -ap -Bl -bE -bE -bW -HC -VO -bl -bl -Gc -VO -lM -bW -ad -bQ -bT -bW -bW -bW -aa -aa -aa -aa -"} -(4,1,1) = {" -aa -aa -aa -bW -bW -ap -bE -bE -bE -bE -bE -bW -mh -mh -mh -Ec -mh -mh -mh -bW -ap -bR -bT -bU -ct -bW -bW -aa -aa -aa -"} -(5,1,1) = {" -aa -aa -bW -bW -ad -bE -bE -bE -bE -bE -bE -uP -bE -bE -bm -aK -bm -bE -bE -Bl -bN -bR -bT -bU -bU -bU -bW -bW -aa -aa -"} -(6,1,1) = {" -aa -aa -bW -aq -bE -bE -bE -bE -bE -bE -bE -bE -bE -bE -bE -aK -Pl -bz -bE -bJ -bE -bS -bT -bU -bU -bU -bU -bW -aa -aa -"} -(7,1,1) = {" -aa -bW -bW -aj -aj -az -lh -bE -yc -bE -bE -bE -bE -aU -aZ -aK -bE -bE -bE -bE -bE -bR -bT -bU -bU -bU -ct -bW -bW -aa -"} -(8,1,1) = {" -aa -bW -ab -af -aj -bE -bE -bE -bE -bE -bE -bE -bE -bE -aK -Pl -bE -bE -bE -bJ -aA -bR -bT -bU -bU -bU -bU -bU -bW -aa -"} -(9,1,1) = {" -aa -bW -ac -ah -aj -aB -lh -bE -yc -bE -bE -bE -bE -aK -aK -aK -bE -ap -bE -bE -bO -bR -bT -bU -bU -bU -bU -bU -bW -aa -"} -(10,1,1) = {" -aa -bW -ae -gg -aj -bE -bE -bE -bE -bE -bE -bE -aA -Pl -aK -bE -ap -bx -bE -bJ -bE -bR -bT -bU -bU -bV -bU -bU -bW -aa -"} -(11,1,1) = {" -aa -bW -aj -ak -aj -aj -aj -aj -bE -bE -bE -bE -bE -aK -Pl -bE -bE -bE -bE -bE -bE -bR -bT -bU -bU -bU -bU -bU -bW -aa -"} -(12,1,1) = {" -aa -bW -ag -aC -aC -aC -aC -aR -aK -Pl -bE -bE -aK -aK -bE -bE -ap -bE -bE -bJ -bE -bR -bT -bU -bU -bU -bU -ct -bW -aa -"} -(13,1,1) = {" -aa -bW -aC -at -aQ -sp -aC -mh -Pl -Pl -aK -Pl -aK -Pl -bE -bx -bE -bE -bE -bK -bE -bR -bT -bU -bU -bU -bU -bU -bW -aa -"} -(14,1,1) = {" -aa -bW -ai -at -aQ -sp -aC -mh -Pl -aK -Pl -aK -ax -Pl -uA -ap -bE -bE -bE -bJ -bE -bR -bT -bU -bU -bU -bU -bU -bW -aa -"} -(15,1,1) = {" -aa -bW -QM -aC -aC -aC -aC -aR -aK -bE -bE -Pl -aK -Pl -br -bE -bE -bE -aA -bE -bE -bR -bT -bU -bU -bU -bU -bU -bW -aa -"} -(16,1,1) = {" -aa -bW -aj -Ei -av -aE -aj -aj -aB -bE -ap -bE -bE -aK -Pl -bE -bE -bE -bE -bJ -bE -bR -bT -bU -bU -bU -bU -bU -bW -aa -"} -(17,1,1) = {" -aa -bW -au -aC -aC -aC -JF -aj -qe -bE -bE -bE -bE -Pl -Pl -bE -aU -bE -bE -bE -bE -bR -bT -bU -bV -bU -bU -bU -bW -aa -"} -(18,1,1) = {" -aa -bW -am -as -aw -aI -TW -aj -bE -bE -bE -bE -bE -bE -aK -bE -bE -bE -bF -bE -bz -bR -bT -bU -bU -bU -bU -ct -bW -aa -"} -(19,1,1) = {" -aa -bW -aj -aj -aj -aj -aj -aj -bE -bE -bE -bE -bE -aK -aK -Pl -bE -bE -QS -bE -bE -bR -bT -bU -bU -bU -bU -bU -bW -aa -"} -(20,1,1) = {" -aa -bW -an -aG -aj -aJ -aL -aN -bE -bE -bE -bE -bx -Pl -aK -Pl -bE -bA -bG -Gc -bE -bR -bT -bU -bU -bU -bU -bU -bW -aa -"} -(21,1,1) = {" -aa -bW -ao -ar -ay -bE -bE -bE -bE -bE -bE -bE -bE -aK -Pl -aK -bE -bB -bH -bM -bE -bR -bT -bU -bU -bU -bU -bU -bW -aa -"} -(22,1,1) = {" -aa -bW -aj -aj -aj -aB -ap -bE -bE -bE -ap -bE -bE -bE -aK -bE -bE -bE -bE -bE -bP -bR -bT -bU -bU -bU -bV -bU -bW -aa -"} -(23,1,1) = {" -aa -bW -ap -bE -bE -bE -bE -bE -bE -bE -bE -bE -bE -cP -aK -ap -bE -bE -bE -bJ -bE -bR -bT -bU -bU -bU -bU -bL -bW -aa -"} -(24,1,1) = {" -aa -bW -bW -bE -ap -bE -bE -aU -aA -bE -bE -bz -bE -bE -aK -Pl -aK -aZ -bE -bE -bE -bR -bT -bU -bU -bU -ct -bW -bW -aa -"} -(25,1,1) = {" -aa -aa -bW -aq -bE -bE -bE -bE -aZ -bE -bE -bE -bE -bE -bE -aK -Pl -bE -bE -bE -bE -bS -bT -bU -bU -bU -bU -bW -aa -aa -"} -(26,1,1) = {" -aa -aa -bW -bW -ap -bE -bE -aq -bE -bE -bE -QS -bE -bE -bn -aK -bn -bE -bx -cs -bE -bR -bT -bU -bU -bU -bW -bW -aa -aa -"} -(27,1,1) = {" -aa -aa -aa -bW -bW -ad -bE -bE -bE -bE -bE -bW -mh -mh -mh -Ec -mh -mh -mh -bW -ap -bR -bT -bU -ct -bW -bW -aa -aa -aa -"} -(28,1,1) = {" -aa -aa -aa -aa -bW -bW -bW -ap -QS -ap -bE -bW -bi -VO -Gc -bl -bl -bq -lM -bW -bN -bR -bT -bW -bW -bW -aa -aa -aa -aa -"} -(29,1,1) = {" -aa -aa -aa -aa -aa -aa -bW -bW -bW -bW -bW -bW -bj -bk -Gc -qT -bl -qa -cR -bW -bW -bW -bW -bW -aa -aa -aa -aa -aa -aa -"} -(30,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -TP -TD -bW -bW -bW -pI -bW -pI -bW -bW -bW -TD -TP -aa -aa -aa -aa -aa -aa -aa -aa -"} diff --git a/_maps/map_files/test_tiny/test_tiny.dmm b/_maps/map_files/test_tiny/test_tiny.dmm deleted file mode 100644 index cf23687ddfb10..0000000000000 --- a/_maps/map_files/test_tiny/test_tiny.dmm +++ /dev/null @@ -1,65577 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/space, -/area/space) -"b" = ( -/obj/effect/landmark{ - icon = 'icons/effects/spawner_icons.dmi'; - icon_state = "spooky"; - name = "Observer-Start" - }, -/obj/effect/landmark/spawner/late/crew, -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/arrival/station) -"p" = ( -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/arrival/station) -"u" = ( -/turf/simulated/wall/mineral/titanium, -/area/shuttle/arrival/station) -"x" = ( -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/arrival/station) -"F" = ( -/obj/machinery/light, -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/arrival/station) -"I" = ( -/obj/machinery/light{ - dir = 8 - }, -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/arrival/station) -"U" = ( -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/mineral/titanium/blue, -/area/shuttle/arrival/station) - -(1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(3,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(4,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(5,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(6,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(7,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(8,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(9,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(10,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(11,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(12,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(13,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(14,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(15,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(16,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(17,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(18,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(19,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(20,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(21,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(22,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(23,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(24,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(25,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(26,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(27,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(28,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(29,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(30,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(31,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(32,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(33,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(34,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(35,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(36,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(37,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(38,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(39,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(40,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(41,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(42,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(43,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(44,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(45,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(46,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(47,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(48,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(49,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(50,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(51,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(52,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(53,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(54,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(55,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(56,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(57,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(58,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(59,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(60,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(61,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(62,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(63,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(64,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(65,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(66,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(67,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(68,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(69,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(70,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(71,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(72,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(73,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(74,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(75,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(76,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(77,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(78,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(79,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(80,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(81,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(82,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(83,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(84,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(85,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(86,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(87,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(88,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(89,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(90,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(91,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(92,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(93,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(94,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(95,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(96,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(97,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(98,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(99,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(100,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(101,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(102,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(103,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(104,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(105,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(106,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(107,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(108,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(109,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(110,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(111,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(112,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(113,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(114,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(115,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(116,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(117,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(118,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(119,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(120,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(121,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -u -u -u -u -u -u -u -u -u -u -u -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(122,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -x -x -x -I -x -x -x -I -x -x -x -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(123,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -x -x -x -x -x -x -x -x -x -x -x -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(124,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -x -x -x -x -x -x -x -x -x -x -x -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(125,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -p -x -x -x -x -x -x -x -x -x -F -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(126,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -x -x -x -x -x -x -x -x -x -x -x -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(127,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -x -x -x -x -x -b -x -x -x -x -x -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(128,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -x -x -x -x -x -x -x -x -x -x -x -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(129,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -p -x -x -x -x -x -x -x -x -x -F -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(130,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -x -x -x -x -x -x -x -x -x -x -x -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(131,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -x -x -x -x -x -x -x -x -x -x -x -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(132,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -x -x -x -U -x -x -x -U -x -x -x -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(133,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -u -u -u -u -u -u -u -u -u -u -u -u -u -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(134,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(135,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(136,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(137,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(138,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(139,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(140,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(141,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(142,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(143,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(144,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(145,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(146,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(147,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(148,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(149,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(150,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(151,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(152,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(153,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(154,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(155,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(156,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(157,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(158,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(159,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(160,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(161,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(162,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(163,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(164,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(165,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(166,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(167,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(168,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(169,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(170,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(171,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(172,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(173,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(174,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(175,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(176,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(177,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(178,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(179,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(180,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(181,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(182,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(183,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(184,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(185,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(186,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(187,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(188,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(189,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(190,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(191,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(192,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(193,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(194,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(195,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(196,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(197,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(198,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(199,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(200,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(201,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(202,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(203,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(204,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(205,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(206,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(207,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(208,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(209,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(210,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(211,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(212,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(213,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(214,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(215,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(216,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(217,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(218,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(219,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(220,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(221,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(222,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(223,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(224,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(225,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(226,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(227,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(228,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(229,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(230,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(231,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(232,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(233,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(234,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(235,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(236,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(237,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(238,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(239,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(240,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(241,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(242,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(243,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(244,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(245,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(246,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(247,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(248,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(249,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(250,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(251,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(252,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(253,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(254,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(255,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} diff --git a/_maps/map_files/tests/test_generic.dmm b/_maps/map_files/tests/test_generic.dmm deleted file mode 100644 index c8e2358307f53..0000000000000 --- a/_maps/map_files/tests/test_generic.dmm +++ /dev/null @@ -1,176 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/simulated/floor/plasteel, -/area/game_test) -"G" = ( -/turf/simulated/wall/indestructible/riveted, -/area/game_test) -"R" = ( -/obj/effect/landmark/game_test/bottom_left_corner, -/turf/simulated/floor/plasteel, -/area/game_test) -"Y" = ( -/obj/effect/landmark/game_test/top_right_corner, -/turf/simulated/floor/plasteel, -/area/game_test) - -(1,1,1) = {" -G -G -G -G -G -G -G -G -"} -(2,1,1) = {" -G -a -a -a -a -a -a -G -"} -(3,1,1) = {" -G -a -a -a -a -R -a -G -"} -(4,1,1) = {" -G -a -a -a -a -a -a -G -"} -(5,1,1) = {" -G -a -a -a -a -a -a -G -"} -(6,1,1) = {" -G -a -a -a -a -a -a -G -"} -(7,1,1) = {" -G -a -a -a -a -a -a -G -"} -(8,1,1) = {" -G -a -a -a -a -a -a -G -"} -(9,1,1) = {" -G -a -a -a -a -a -a -G -"} -(10,1,1) = {" -G -a -a -a -a -a -a -G -"} -(11,1,1) = {" -G -a -a -a -a -a -a -G -"} -(12,1,1) = {" -G -a -a -a -a -a -a -G -"} -(13,1,1) = {" -G -a -a -a -a -a -a -G -"} -(14,1,1) = {" -G -a -Y -a -a -a -a -G -"} -(15,1,1) = {" -G -a -a -a -a -a -a -G -"} -(16,1,1) = {" -G -G -G -G -G -G -G -G -"} diff --git a/_maps/map_files/tests/test_ventcrawl.dmm b/_maps/map_files/tests/test_ventcrawl.dmm deleted file mode 100644 index e14c7c9036eb3..0000000000000 --- a/_maps/map_files/tests/test_ventcrawl.dmm +++ /dev/null @@ -1,30 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 - }, -/turf/simulated/floor, -/area/template_noop) -"d" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 8 - }, -/turf/simulated/floor, -/area/template_noop) -"X" = ( -/obj/machinery/atmospherics/pipe/simple/visible{ - dir = 4 - }, -/obj/structure/table, -/turf/simulated/floor, -/area/template_noop) - -(1,1,1) = {" -a -"} -(2,1,1) = {" -X -"} -(3,1,1) = {" -d -"} diff --git a/code/__DEFINES/__proc_refs.dm b/code/__DEFINES/__proc_refs.dm deleted file mode 100644 index 19fa8e551d229..0000000000000 --- a/code/__DEFINES/__proc_refs.dm +++ /dev/null @@ -1,9 +0,0 @@ -/// Validates the proc exists on this type -#define PROC_REF(X) (nameof(.proc/##X)) -/// Validates the proc exists on the specified type -#define TYPE_PROC_REF(TYPE, X) (nameof(##TYPE.proc/##X)) -/// Validates the proc exists on global -#define GLOBAL_PROC_REF(X) (/proc/##X) - -#define NAMEOF_STATIC(datum, X) (#X || type::##X) -#define CALL_EXT call_ext diff --git a/code/__DEFINES/access_defines.dm b/code/__DEFINES/access_defines.dm deleted file mode 100644 index 30a4f5c4dc8ae..0000000000000 --- a/code/__DEFINES/access_defines.dm +++ /dev/null @@ -1,92 +0,0 @@ -#define ACCESS_SECURITY 1 //! Security equipment. -#define ACCESS_BRIG 2 //! Brig timers and permabrig. -#define ACCESS_ARMORY 3 -#define ACCESS_FORENSICS_LOCKERS 4 -#define ACCESS_MEDICAL 5 -#define ACCESS_MORGUE 6 -#define ACCESS_TOX 7 -#define ACCESS_TOX_STORAGE 8 -#define ACCESS_GENETICS 9 -#define ACCESS_ENGINE 10 -#define ACCESS_ENGINE_EQUIP 11 -#define ACCESS_MAINT_TUNNELS 12 -#define ACCESS_EXTERNAL_AIRLOCKS 13 -#define ACCESS_CHANGE_IDS 15 -#define ACCESS_AI_UPLOAD 16 -#define ACCESS_TELEPORTER 17 -#define ACCESS_EVA 18 -#define ACCESS_HEADS 19 -#define ACCESS_CAPTAIN 20 -#define ACCESS_ALL_PERSONAL_LOCKERS 21 -#define ACCESS_CHAPEL_OFFICE 22 -#define ACCESS_TECH_STORAGE 23 -#define ACCESS_ATMOSPHERICS 24 -#define ACCESS_BAR 25 -#define ACCESS_JANITOR 26 -#define ACCESS_CREMATORIUM 27 -#define ACCESS_KITCHEN 28 -#define ACCESS_ROBOTICS 29 -#define ACCESS_RD 30 -#define ACCESS_CARGO 31 -#define ACCESS_CONSTRUCTION 32 -#define ACCESS_CHEMISTRY 33 -#define ACCESS_CARGO_BOT 34 -#define ACCESS_HYDROPONICS 35 -#define ACCESS_LIBRARY 37 -#define ACCESS_INTERNAL_AFFAIRS 38 -#define ACCESS_VIROLOGY 39 -#define ACCESS_CMO 40 -#define ACCESS_QM 41 -#define ACCESS_COURT 42 -#define ACCESS_CLOWN 43 -#define ACCESS_MIME 44 -#define ACCESS_SURGERY 45 -#define ACCESS_THEATRE 46 -#define ACCESS_RESEARCH 47 -#define ACCESS_MINING 48 -#define ACCESS_MAILSORTING 50 -#define ACCESS_HEADS_VAULT 53 -#define ACCESS_MINING_STATION 54 -#define ACCESS_XENOBIOLOGY 55 -#define ACCESS_CE 56 -#define ACCESS_HOP 57 -#define ACCESS_HOS 58 -#define ACCESS_RC_ANNOUNCE 59 //! Request console announcements. -#define ACCESS_KEYCARD_AUTH 60 //! Used for events which require at least two people to confirm them. -#define ACCESS_TCOMSAT 61 //! Has access to the entire telecomms satellite / machinery. -#define ACCESS_EXPEDITION 62 -#define ACCESS_SEC_DOORS 63 //! Security front doors. -#define ACCESS_PSYCHIATRIST 64 -#define ACCESS_PARAMEDIC 66 -#define ACCESS_BLUESHIELD 67 -#define ACCESS_NTREP 73 -#define ACCESS_MAGISTRATE 74 -#define ACCESS_MINISAT 75 -#define ACCESS_MINERAL_STOREROOM 76 -#define ACCESS_CARGO_BAY 78 -#define ACCESS_SUPPLY_SHUTTLE 79 -#define ACCESS_TRAINER 80 - -#define ACCESS_WEAPONS 99 //! Weapon authorization for secbots. - -// MARK: CENTCOM ACCESS -#define ACCESS_CENT_GENERAL 101 //! Centcomm General facilities. -#define ACCESS_CENT_LIVING 102 //! Centcomm Living quarters. -#define ACCESS_CENT_SECURITY 104 //! Centcomm Security. -#define ACCESS_CENT_SHUTTLES 106 //! Centcomm Shuttle docks. -#define ACCESS_CENT_SPECOPS 109 //! Centcomm Special Ops. -#define ACCESS_CENT_SPECOPS_COMMANDER 110 //! Centcomm Special Ops Commander. -#define ACCESS_CENT_COMMANDER 114 //! Centcomm Commander's Office/ID computer. - -/// MARK: SYNDICATE ACCESS -#define ACCESS_SYNDICATE 150 //! General Syndicate Access -#define ACCESS_SYNDICATE_LEADER 151 //! Nuke Op Leader Access -#define ACCESS_VOX 152 //! Vox Access -#define ACCESS_SYNDICATE_COMMAND 153 //! Admin syndi officer - -/// MARK: MISC ACCESS -#define ACCESS_TRADE_SOL 160 //! Trade stations -#define ACCESS_AWAY01 271 //! Access used for moonoutpost19 ruin. -#define ACCESS_FREE_GOLEMS 300 //! Ghost role: free golems. -#define ACCESS_THETA_STATION 301 //! Ghost role: Theta station. -#define ACCESS_DEEPSTORAGE 512 //! Space ruin: Deep Storage diff --git a/code/__DEFINES/antag_defines.dm b/code/__DEFINES/antag_defines.dm deleted file mode 100644 index e62c0838ee48e..0000000000000 --- a/code/__DEFINES/antag_defines.dm +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Contractors - */ -// Contract Statuses -/// The contract is invalid for some reason and cannot be taken. It may be made valid later. -#define CONTRACT_STATUS_INVALID -1 -/// The contract hasn't been started yet. -#define CONTRACT_STATUS_INACTIVE 0 -/// The contract is in progress. -#define CONTRACT_STATUS_ACTIVE 1 -/// The contract has been completed successfully. -#define CONTRACT_STATUS_COMPLETED 2 -/// The contract failed for some reason. -#define CONTRACT_STATUS_FAILED 3 - -// Difficulties. Note that they follow each other numerically and should stay that way as some code relies on that. -/// Easy difficulty area to extract the kidnapee. Low rewards. -#define EXTRACTION_DIFFICULTY_EASY 1 -/// Medium difficulty area to extract the kidnapee. Moderate rewards. -#define EXTRACTION_DIFFICULTY_MEDIUM 2 -/// Hard difficulty area to extract the kidnapee. High rewards. -#define EXTRACTION_DIFFICULTY_HARD 3 - -/// The name of the strings file containing data to use for contract fluff texts. -#define CONTRACT_STRINGS_WANTED "syndicate_wanted_messages.json" - -// UI page numbers. -#define HUB_PAGE_CONTRACTS 1 -#define HUB_PAGE_SHOP 2 - -GLOBAL_DATUM(prisoner_belongings, /obj/structure/closet/secure_closet/contractor) -GLOBAL_LIST(contractors) - -/** - * Traitors - */ -#define UPLINK_SPECIAL_SPAWNING "ONE PINK CHAINSAW PLEASE" - -/** - * Changelings - */ -// Defines below to be used with the changeling action's `power_type` var. -/// Denotes that this power is free and should be given to all changelings by default. -#define CHANGELING_INNATE_POWER 1 -/// Denotes that this power can only be obtained by purchasing it. -#define CHANGELING_PURCHASABLE_POWER 2 -/// Denotes that this power can not be obtained normally. Primarily used for base types such as [/datum/action/changeling/weapon]. -#define CHANGELING_UNOBTAINABLE_POWER 3 - -#define CHANGELING_FAKEDEATH_TIME 50 SECONDS -#define CHANGELING_ABSORB_RECENT_SPEECH 8 //The amount of recent spoken lines to gain on absorbing a mob - -/** - * Abductors - */ - -#define ABDUCTOR_VEST_STEALTH 1 -#define ABDUCTOR_VEST_COMBAT 2 - -/** - * Pulse Demon - */ -#define PULSEDEMON_SOURCE_DRAIN_INVALID (-1) - -/** - * Objectives - */ -#define THEFT_FLAG_SPECIAL 1 // Unused, maybe someone will use it some day, I'll leave it here for the children -#define THEFT_FLAG_UNIQUE 2 - -/** - * IS_ANTAG defines - */ -#define IS_CHANGELING(mob) (isliving(mob) && mob?:mind?:has_antag_datum(/datum/antagonist/changeling)) - -#define IS_MINDFLAYER(mob) (isliving(mob) && mob?:mind?:has_antag_datum(/datum/antagonist/mindflayer)) - -#define IS_MINDSLAVE(mob) (ishuman(mob) && mob?:mind?:has_antag_datum(/datum/antagonist/mindslave, FALSE)) - -/** - * Objective targeting flags - */ - -/// Objective target must be mindshielded if possible -#define MINDSHIELDED_TARGET (1<<0) -/// Objective target must be non-mindshielded if possible -#define UNMINDSHIELDED_TARGET (1<<1) -/// Objective target must be a syndicate agent if possible -#define SYNDICATE_TARGET (1<<2) - -/** - * Antag organizations - */ - -/// Antag hunting antag. Might help security overall. -#define ORG_CHAOS_HUNTER "chaos_hunter" -/// Will steal items/kill low importance crew, usually not much trouble -#define ORG_CHAOS_MILD "chaos_mild" -/// Your average tator, will be an issue -#define ORG_CHAOS_AVERAGE "chaos_average" -/// Hijack or hijack-tier antagonists. -#define ORG_CHAOS_HIJACK "chaos_hijack" - -#define ORG_PROB_HUNTER 10 -#define ORG_PROB_MILD 20 -#define ORG_PROB_AVERAGE 65 -#define ORG_PROB_HIJACK 5 - -// Chance that a traitor will receive a 'You are being targeted by another syndicate agent' notification regardless of being an actual target -#define ORG_PROB_PARANOIA 5 - -/// How often a biohazard's population is recorded after the event fires. -#define BIOHAZARD_POP_INTERVAL 5 MINUTES -/// The string version of the interval for use in blackbox key names. -#define BIOHAZARD_POP_INTERVAL_STR "5min" diff --git a/code/__DEFINES/atmospherics_defines.dm b/code/__DEFINES/atmospherics_defines.dm deleted file mode 100644 index ae6031aea778b..0000000000000 --- a/code/__DEFINES/atmospherics_defines.dm +++ /dev/null @@ -1,183 +0,0 @@ -#define GAS_O2 (1 << 0) -#define GAS_N2 (1 << 1) -#define GAS_PL (1 << 2) -#define GAS_CO2 (1 << 3) -#define GAS_N2O (1 << 4) -#define GAS_A_B (1 << 5) - -//ATMOS -//stuff you should probably leave well alone! -#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) -#define ONE_ATMOSPHERE 101.325 //kPa -#define TCMB 2.7 // -270.3degC -#define TCRYO 215 // -58.15degC -#define T0C 273.15 // 0degC -#define T20C 293.15 // 20degC -/// -14C - Temperature used for kitchen cold room, medical freezer, etc. -#define COLD_ROOM_TEMP 259.15 - -/// -193C - Temperature used for server rooms -#define SERVER_ROOM_TEMP 80 - -#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) //moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC -#define M_CELL_WITH_RATIO (MOLES_CELLSTANDARD * 0.005) //compared against for superconductivity -#define O2STANDARD 0.21 //percentage of oxygen in a normal mixture of air -#define N2STANDARD 0.79 //same but for nitrogen -#define MOLES_O2STANDARD (MOLES_CELLSTANDARD*O2STANDARD) // O2 standard value (21%) -#define MOLES_N2STANDARD (MOLES_CELLSTANDARD*N2STANDARD) // N2 standard value (79%) -#define CELL_VOLUME 2500 //liters in a cell -//liters in a normal breath -#define BREATH_VOLUME 1 -#define BREATH_PERCENTAGE (BREATH_VOLUME/CELL_VOLUME) //Amount of air to take a from a tile - -//EXCITED GROUPS -#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.005 //Minimum ratio of air that must move to/from a tile to suspend group processing -#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND) //Minimum amount of air that has to move before a group processing can be suspended -#define MINIMUM_MOLES_DELTA_TO_MOVE (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND) //Either this must be active -#define MINIMUM_TEMPERATURE_TO_MOVE (T20C+100) //or this (or both, obviously) -#define MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND 0.012 -#define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4 //Minimum temperature difference before group processing is suspended -#define MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER 0.5 //Minimum temperature difference before the gas temperatures are just set to be equal -#define MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION (T20C+10) -#define MINIMUM_TEMPERATURE_START_SUPERCONDUCTION (T20C+230) - -//HEAT TRANSFER COEFFICIENTS -//Must be between 0 and 1. Values closer to 1 equalize temperature faster -//Capped at OPEN_HEAT_TRANSFER_COEFFICIENT, both here and in Rust. -#define WALL_HEAT_TRANSFER_COEFFICIENT 0.0 -#define DOOR_HEAT_TRANSFER_COEFFICIENT 0.001 -#define OPEN_HEAT_TRANSFER_COEFFICIENT 0.4 -#define WINDOW_HEAT_TRANSFER_COEFFICIENT 0.001 -// This looks silly, but it's for clarity when reading elsewhere. -#define ZERO_HEAT_TRANSFER_COEFFICIENT 0.0 - -#define HEAT_CAPACITY_VACUUM 700000 //a hack to help make vacuums "cold", sacrificing realism for gameplay - -//FIRE -#define FIRE_MINIMUM_TEMPERATURE_TO_SPREAD (150+T0C) -#define FIRE_MINIMUM_TEMPERATURE_TO_EXIST (100+T0C) -#define FIRE_SPREAD_RADIOSITY_SCALE 0.85 -#define FIRE_CARBON_ENERGY_RELEASED 500000 //Amount of heat released per mole of burnt carbon into the tile -#define FIRE_PLASMA_ENERGY_RELEASED 3000000 //Amount of heat released per mole of burnt plasma into the tile -#define FIRE_GROWTH_RATE 40000 //For small fires - -//Plasma fire properties -#define OXYGEN_BURN_RATE_BASE 1.4 -#define PLASMA_BURN_RATE_DELTA 4 -#define PLASMA_MINIMUM_BURN_TEMPERATURE (100+T0C) -#define PLASMA_UPPER_TEMPERATURE (1370+T0C) -#define PLASMA_MINIMUM_OXYGEN_NEEDED 2 -#define PLASMA_MINIMUM_OXYGEN_PLASMA_RATIO 30 -#define PLASMA_OXYGEN_FULLBURN 10 - -//GASES -#define MIN_TOXIC_GAS_DAMAGE 1 -#define MAX_TOXIC_GAS_DAMAGE 10 -#define MOLES_PLASMA_VISIBLE 0.5 //Moles in a standard cell after which plasma is visible - -// Pressure limits. -#define HAZARD_HIGH_PRESSURE 550 //This determins at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant) -#define WARNING_HIGH_PRESSURE 325 //This determins when the orange pressure icon is displayed (it is 0.7 * HAZARD_HIGH_PRESSURE) -#define WARNING_LOW_PRESSURE 50 //This is when the gray low pressure icon is displayed. (it is 2.5 * HAZARD_LOW_PRESSURE) -#define HAZARD_LOW_PRESSURE 20 //This is when the black ultra-low pressure icon is displayed. (This one is set as a constant) - -#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 BODYTEMP_NORMAL 310.15 //The natural temperature for a body -#define BODYTEMP_AUTORECOVERY_DIVISOR 12 //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_LOW 2 //This is the divisor that handles how much you go back to your preferred body temperature, between the cold and hot damaging limits. The higher the number, the slower the recovery. -#define BODYTEMP_AUTORECOVERY_MINIMUM 10 //Minimum amount of kelvin moved toward 310.15K per tick. So long as abs(310.15 - bodytemp) is more than 50. -#define BODYTEMP_COLD_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster. -#define BODYTEMP_HEAT_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is higher than their body temperature. Make it lower to gain bodytemp faster. -#define BODYTEMP_COOLING_MAX 30 //The maximum number of degrees that your body can cool in 1 tick, when in a cold area. -#define BODYTEMP_HEATING_MAX 30 //The maximum number of degrees that your body can heat up in 1 tick, when in a hot area. - -#define BODYTEMP_HEAT_DAMAGE_LIMIT (BODYTEMP_NORMAL + 50) // The limit the human body can take before it starts taking damage from heat. -#define BODYTEMP_COLD_DAMAGE_LIMIT (BODYTEMP_NORMAL - 50) // The limit the human body can take before it starts taking damage from coldness. - -#define SPACE_HELM_MIN_TEMP_PROTECT 2.0 //what min_cold_protection_temperature is set to for space-helmet quality headwear. MUST NOT BE 0. -#define SPACE_HELM_MAX_TEMP_PROTECT 1500 //Thermal insulation works both ways /Malkevin -#define SPACE_SUIT_MIN_TEMP_PROTECT 2.0 //what min_cold_protection_temperature is set to for space-suit quality jumpsuits or suits. MUST NOT BE 0. -#define SPACE_SUIT_MAX_TEMP_PROTECT 1500 - -#define FIRE_SUIT_MIN_TEMP_PROTECT 60 //Cold protection for firesuits -#define FIRE_SUIT_MAX_TEMP_PROTECT 30000 //what max_heat_protection_temperature is set to for firesuit quality suits. MUST NOT BE 0. -#define FIRE_HELM_MIN_TEMP_PROTECT 60 //Cold protection for fire helmets -#define FIRE_HELM_MAX_TEMP_PROTECT 30000 //for fire helmet quality items (red and white hardhats) - -#define FIRE_IMMUNITY_MAX_TEMP_PROTECT 35000 //what max_heat_protection_temperature is set to for firesuit quality suits and helmets. MUST NOT BE 0. - -#define HELMET_MIN_TEMP_PROTECT 160 //For normal helmets -#define HELMET_MAX_TEMP_PROTECT 600 //For normal helmets -#define ARMOR_MIN_TEMP_PROTECT 160 //For armor -#define ARMOR_MAX_TEMP_PROTECT 600 //For armor - -#define GLOVES_MIN_TEMP_PROTECT 2.0 //For some gloves (black and) -#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 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 4 -#define LOW_PRESSURE_DAMAGE 2 //The amounb of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value). - -#define COLD_SLOWDOWN_FACTOR 20 //Humans are slowed by the difference between bodytemp and BODYTEMP_COLD_DAMAGE_LIMIT divided by this - -//PIPES -// Atmos pipe limits -#define MAX_OUTPUT_PRESSURE 4500 // (kPa) What pressure pumps and powered equipment max out at. -#define MAX_TRANSFER_RATE 200 // (L/s) Maximum speed powered equipment can work at. - -//TANKS -#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) //Tank starts leaking -#define TANK_RUPTURE_PRESSURE (40.*ONE_ATMOSPHERE) //Tank spills all contents into atmosphere -#define TANK_FRAGMENT_PRESSURE (50.*ONE_ATMOSPHERE) //Boom 3x3 base explosion -#define TANK_FRAGMENT_SCALE (10.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold -#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE * 3) -#define TANK_MIN_RELEASE_PRESSURE 0 -#define TANK_DEFAULT_RELEASE_PRESSURE 16 - -// Atmos alarm defines -#define ATMOS_ALARM_NONE 0 -#define ATMOS_ALARM_WARNING 1 -#define ATMOS_ALARM_DANGER 2 - -//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_TEMPERATURE 500 -#define LAVALAND_OXYGEN 8 -#define LAVALAND_NITROGEN 14 - -// Reactions -#define N2O_DECOMPOSITION_MIN_ENERGY 1400 -#define N2O_DECOMPOSITION_ENERGY_RELEASED 200000 -/// The coefficient a for a function of the form: 1 - (a / (x + c)^2) which gives a decomposition rate of 0.5 at 50000 Kelvin -/// And a decomposition close to 0 at 1400 Kelvin -#define N2O_DECOMPOSITION_COEFFICIENT_A 1.376651173e10 -/// The coefficient c for a function of the form: 1 - (a / (x + c)^2) which gives a decomposition rate of 0.5 at 50000 Kelvin -/// And a decomposition rate close to 0 at 1400 Kelvin -#define N2O_DECOMPOSITION_COEFFICIENT_C 115930.77913 -// From milla/src/model.rs, line 126 -#define ATMOS_MODE_SPACE 0 //! Tile is exposed to space and loses air every second -#define ATMOS_MODE_SEALED 1 //! Tile has no special behaviour -#define ATMOS_MODE_EXPOSED_TO_ENVIRONMENT 2 //! Tile is exposed to the environment, ex: lavaland -#define ATMOS_MODE_NO_DECAY 3 //! Prevents hot tiles from automatically decaying towards T20C. - -/// Lavaland environment: hot, low pressure. -#define ENVIRONMENT_LAVALAND "lavaland" -/// Temperate environment: Normal atmosphere, 20 C. -#define ENVIRONMENT_TEMPERATE "temperate" -/// Cold environment: Normal atmosphere, -93 C. -#define ENVIRONMENT_COLD "cold" - -/// How far away should we load the pressure HUD data from MILLA? -#define PRESSURE_HUD_LOAD_RADIUS 15 - -/// How far away should we send the pressure HUD to the player? -#define PRESSURE_HUD_RADIUS 12 - -// Vent pump modes -/// Don't go over the external pressure -#define ONLY_CHECK_EXT_PRESSURE 1 -/// Only release until we reach this pressure -#define ONLY_CHECK_INT_PRESSURE 2 diff --git a/code/__DEFINES/dcs/atom_signals.dm b/code/__DEFINES/dcs/atom_signals.dm deleted file mode 100644 index 42745166c8dc1..0000000000000 --- a/code/__DEFINES/dcs/atom_signals.dm +++ /dev/null @@ -1,142 +0,0 @@ -/** - * Signals for /atom and subtypes that have too few related signals to put in separate files. - * Doc format: `/// when the signal is called: (signal arguments)`. - * All signals send the source datum of the signal as the first argument - */ - -// /atom - -//from SSatoms InitAtom - Only if the atom was not deleted or failed initialization and has a loc -#define COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON "atom_init_success_on" -// from SSatoms InitAtom - Only if the atom was not deleted or failed initialization -#define COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE "atom_init_success" -///from base of atom/attack_hulk(): (/mob/living/carbon/human) -#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" -///from base of atom/examine(): (examining_user, examine_list) -#define COMSIG_PARENT_EXAMINE "atom_examine" -///from base of atom/examine_more(): (examining_user, examine_list) -#define COMSIG_PARENT_EXAMINE_MORE "atom_examine_more" -///from base of [/atom/proc/update_appearance]: (updates) -#define COMSIG_ATOM_UPDATE_APPEARANCE "atom_update_appearance" - /// If returned from [COMSIG_ATOM_UPDATE_APPEARANCE] it prevents the atom from updating its name. - #define COMSIG_ATOM_NO_UPDATE_NAME UPDATE_NAME - /// If returned from [COMSIG_ATOM_UPDATE_APPEARANCE] it prevents the atom from updating its desc. - #define COMSIG_ATOM_NO_UPDATE_DESC UPDATE_DESC - /// If returned from [COMSIG_ATOM_UPDATE_APPEARANCE] it prevents the atom from updating its icon. - #define COMSIG_ATOM_NO_UPDATE_ICON UPDATE_ICON -///from base of [/atom/proc/update_name]: (updates) -#define COMSIG_ATOM_UPDATE_NAME "atom_update_name" -///from base of [/atom/proc/update_desc]: (updates) -#define COMSIG_ATOM_UPDATE_DESC "atom_update_desc" -///from base of [/atom/proc/update_icon]: () -#define COMSIG_ATOM_UPDATE_ICON "atom_update_icon" - /// If returned from [COMSIG_ATOM_UPDATE_ICON] it prevents the atom from updating its icon state. - #define COMSIG_ATOM_NO_UPDATE_ICON_STATE UPDATE_ICON_STATE - /// If returned from [COMSIG_ATOM_UPDATE_ICON] it prevents the atom from updating its overlays. - #define COMSIG_ATOM_NO_UPDATE_OVERLAYS UPDATE_OVERLAYS -///Sent after [/atom/proc/update_icon_state] is called by [/atom/proc/update_icon]: () -#define COMSIG_ATOM_UPDATE_ICON_STATE "atom_update_icon_state" -///Sent after [/atom/proc/update_overlays] is called by [/atom/proc/update_icon]: (list/new_overlays) -#define COMSIG_ATOM_UPDATE_OVERLAYS "atom_update_overlays" -///from base of [/atom/proc/update_icon]: (signalOut, did_anything) -#define COMSIG_ATOM_UPDATED_ICON "atom_updated_icon" -///from base of atom/Entered(): (atom/movable/entered, /atom) -#define COMSIG_ATOM_ENTERED "atom_entered" -///from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc) -#define COMSIG_ATOM_EXIT "atom_exit" - #define COMPONENT_ATOM_BLOCK_EXIT (1<<0) -///from base of atom/Exited(): (atom/movable/exiting, direction) -#define COMSIG_ATOM_EXITED "atom_exited" -///from base of atom/ex_act(): (severity, target) -#define COMSIG_ATOM_EX_ACT "atom_ex_act" -///from base of atom/emp_act(): (severity) -#define COMSIG_ATOM_EMP_ACT "atom_emp_act" -///from base of atom/fire_act(): (exposed_temperature, exposed_volume) -#define COMSIG_ATOM_FIRE_ACT "atom_fire_act" -///from base of atom/bullet_act(): (/obj/projectile, def_zone) -#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" -///from base of atom/blob_act(): (/obj/structure/blob) -#define COMSIG_ATOM_BLOB_ACT "atom_blob_act" -///from base of atom/acid_act(): (acidpwr, acid_volume) -#define COMSIG_ATOM_ACID_ACT "atom_acid_act" -///from base of atom/emag_act(): (/mob/user) -#define COMSIG_ATOM_EMAG_ACT "atom_emag_act" -///from base of atom/rad_act(intensity) -#define COMSIG_ATOM_RAD_ACT "atom_rad_act" -///from base of atom/singularity_pull(): (S, current_size) -#define COMSIG_ATOM_SING_PULL "atom_sing_pull" -///from base of atom/set_light(): (l_range, l_power, l_color) -#define COMSIG_ATOM_SET_LIGHT "atom_set_light" -///from base of atom/setDir(): (old_dir, new_dir) -#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" -///from [/datum/controller/subsystem/processing/dcs/proc/rotate_decals]: (list/datum/element/decal/rotating) -#define COMSIG_ATOM_DECALS_ROTATING "atom_decals_rotating" -///from base of atom/has_gravity(): (turf/location, list/forced_gravities) -#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" -///from proc/get_rad_contents(): () -#define COMSIG_ATOM_RAD_PROBE "atom_rad_probe" - #define COMPONENT_BLOCK_RADIATION (1<<0) -///from base of datum/radiation_wave/radiate(): (strength) -#define COMSIG_ATOM_RAD_CONTAMINATING "atom_rad_contam" - #define COMPONENT_BLOCK_CONTAMINATION (1<<0) -///from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width) -#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass" - #define COMPONENT_RAD_WAVE_HANDLED (1<<0) -///called when an atom starts orbiting another atom: (atom) -#define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin" -///called when an atom stops orbiting another atom: (atom) -#define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop" -/// called on an atom who has stopped orbiting another atom (atom/orbiter, atom/formerly_orbited) -#define COMSIG_ATOM_ORBITER_STOP "atom_orbiter_stop" -///from base of atom/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) -#define COMSIG_ATOM_HITBY "atom_hitby" -/// Called when an atom is sharpened or dulled. -#define COMSIG_ATOM_UPDATE_SHARPNESS "atom_update_sharpness" -///from base of atom/atom_prehit(obj/item/projectile/P): -#define COMSIG_ATOM_PREHIT "atom_prehit" - #define ATOM_PREHIT_SUCCESS (1<<0) - #define ATOM_PREHIT_FAILURE (1<<1) - -/// Called from atom/Initialize() of target: (atom/target) -#define COMSIG_ATOM_INITIALIZED_ON "atom_initialized_on" - -///from base of atom/attack_ghost(): (mob/dead/observer/ghost) -#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" -///from base of atom/attack_hand(): (mob/user) -#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" -///from base of atom/attack_paw(): (mob/user) -#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" - #define COMPONENT_NO_ATTACK_HAND (1<<0) //works on all 3. -//This signal return value bitflags can be found in __DEFINES/misc.dm - -///called on /living, when pull is attempted, but before it completes, from base of [/mob/living/proc/start_pulling]: (atom/movable/thing, force) -#define COMSIG_LIVING_TRY_PULL "living_try_pull" - #define COMSIG_LIVING_CANCEL_PULL (1 << 0) - -///from base of atom/expose_reagents(): (/list, /datum/reagents, chemholder, volume_modifier) -#define COMSIG_ATOM_EXPOSE_REAGENTS "atom_expose_reagents" - -///from base of atom/Click(): (location, control, params, mob/user) -#define COMSIG_CLICK "atom_click" -///from base of atom/ShiftClick(): (/mob) -#define COMSIG_CLICK_SHIFT "shift_click" - #define COMPONENT_ALLOW_EXAMINATE (1<<0) //Allows the user to examinate regardless of client.eye. -///from base of atom/CtrlClickOn(): (/mob) -#define COMSIG_CLICK_CTRL "ctrl_click" -///from base of atom/AltClick(): (/mob) -#define COMSIG_CLICK_ALT "alt_click" - /// Cancel the alt-click, since this isn't properly part of the attack chain - #define COMPONENT_CANCEL_ALTCLICK (1<<0) -///from base of atom/CtrlShiftClick(/mob) -#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click" -///from base of atom/MouseDrop(): (/atom/over, /mob/user) -#define COMSIG_MOUSEDROP_ONTO "mousedrop_onto" - #define COMPONENT_NO_MOUSEDROP (1<<0) -///from base of atom/MouseDrop_T: (/atom/from, /mob/user) -#define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto" - -/// Called on the atom being hit, from /datum/component/anti_magic/on_attack() : (obj/item/weapon, mob/user, antimagic_flags) -#define COMSIG_ATOM_HOLY_ATTACK "atom_holyattacked" -/// On a ranged attack: base of mob/living/carbon/human/RangedAttack (/mob/living/carbon/human) -#define COMSIG_ATOM_RANGED_ATTACKED "atom_range_attacked" - diff --git a/code/__DEFINES/dcs/attack_chain_signals.dm b/code/__DEFINES/dcs/attack_chain_signals.dm deleted file mode 100644 index 64cbef3243a78..0000000000000 --- a/code/__DEFINES/dcs/attack_chain_signals.dm +++ /dev/null @@ -1,63 +0,0 @@ -// MARK: Item Interactions - -// Return values for non-attack interactions. -#define ITEM_INTERACT_COMPLETE 1 //! Cancel the rest of the attack chain, indicating success. -#define ITEM_INTERACT_SKIP_TO_AFTER_ATTACK 2 //! Skip pre-attack and attack/attack_by, going straight to after_attack. - -/// Sent when this atom is clicked on by a mob with an item. -/// -/// [/atom/proc/item_interaction] -> mob/living/user, obj/item/tool, list/modifiers -#define COMSIG_INTERACT_TARGET "interact_target" - -/// Sent to a mob clicking on an atom with an item. -/// -/// [/atom/proc/item_interaction] -> atom/target, obj/item/tool, list/modifiers -#define COMSIG_INTERACT_USER "interact_user" - -/// Sent to an item clicking on an atom. -/// -/// [/atom/proc/item_interaction] -> mob/living/user, atom/target, list/modifiers -#define COMSIG_INTERACTING "interacting" - -#define COMSIG_INTERACT_RANGED "interact_ranged" //! [/atom/proc/ranged_item_interaction] -#define COMSIG_INTERACTING_RANGED "interacting_ranged" //! [/atom/proc/ranged_item_interaction] - -#define COMSIG_ACTIVATE_SELF "activate_self" //! [/obj/item/proc/activate_self] -> mob/user - -// Attack signals. These should share the returned flags, to standardize the attack chain. -// The chain currently works like: -// tool_act -> pre_attack -> target.attackby (item.attack) -> afterattack -// You can use these signal responses to cancel the attack chain at a certain point from most attack signal types. - -// MARK: Attack Chain - -// Signal interceptors for short-circuiting parts of the attack chain. - -#define COMPONENT_CANCEL_ATTACK_CHAIN (1<<0) //! Cancel the attack chain entirely. -#define COMPONENT_SKIP_ATTACK (1<<1) //! Skip this attack step, continuing for the next one to happen. -#define COMPONENT_SKIP_AFTERATTACK (1<<2) //! Skip after_attacks (while allowing for e.g. attack_by). - -#define COMSIG_PRE_ATTACK "pre_attack" //! [/obj/item/proc/pre_attack] -> atom/target, mob/user, params - -#define COMSIG_ATTACK "attack" //! [/obj/item/proc/attack] -> mob/living/target, mob/living/user -#define COMSIG_ATTACK_OBJ "attack_obj" //! [/obj/item/proc/attack_obj] -> obj/attacked, mob/user -#define COMSIG_ATTACK_OBJ_LIVING "attack_obj_living" //! [/obj/item/proc/attack_obj] -> obj/attacked -#define COMSIG_ATTACK_BY "attack_by" //! [/atom/proc/attackby] -> obj/item/weapon, mob/living/user, params - -#define COMSIG_AFTER_ATTACK "item_after_attack" //! [/obj/item/proc/afterattack] -> atom/target, mob/user, params -#define COMSIG_AFTER_ATTACKED_BY "after_attacked_by" //! [/obj/item/proc/afterattack] -> obj/item/weapon, mob/user, proximity_flag, params - -// Return values for directing the control of the attack chain. Distinct from -// signal interceptors because they're not meant to be combined, and to mesh better with -// historical use of return values in attack chain procs. - -#define CONTINUE_ATTACK 0 //! Continue the attack chain, i.e. allow other signals to respond. -#define FINISH_ATTACK 1 //! Do not continue the attack chain. - -// Legacy-only, do not use in new code - -#define COMSIG_TOOL_ATTACK "tool_attack" //! [/obj/item/proc/tool_attack_chain] -> atom/tool, mob/user -#define COMPONENT_NO_ATTACK (1<<0) -#define COMPONENT_NO_INTERACT (1<<0) -#define COMPONENT_NO_ATTACK_OBJ (1<<0) -#define COMPONENT_CANCEL_TOOLACT (1<<0) diff --git a/code/__DEFINES/dcs/basetype_signals.dm b/code/__DEFINES/dcs/basetype_signals.dm deleted file mode 100644 index a3f64d41aa367..0000000000000 --- a/code/__DEFINES/dcs/basetype_signals.dm +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Signals for base types that have too few related signals to put in separate files. - * Doc format: `/// when the signal is called: (signal arguments)`. - * All signals send the source datum of the signal as the first argument - */ - -// /client - -/// from base of client/Click(): (atom/target, atom/location, control, params, mob/user) -#define COMSIG_CLIENT_CLICK "atom_client_click" -/// 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" - -// /area - -/// from base of area/Entered(): (atom/movable/M) -#define COMSIG_AREA_ENTERED "area_entered" -///from base of area/Exited(): (atom/movable/M) -#define COMSIG_AREA_EXITED "area_exited" - -// /turf - -///from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps) -#define COMSIG_TURF_CHANGE "turf_change" -///from base of turf/proc/onShuttleMove(): (turf/new_turf) -#define COMSIG_TURF_ON_SHUTTLE_MOVE "turf_on_shuttle_move" -///from base of turf/proc/get_decals(): (list/datum/element/decal/decals) -#define COMSIG_ATOM_GET_DECALS "atom_get_decals" diff --git a/code/__DEFINES/dcs/item_signals.dm b/code/__DEFINES/dcs/item_signals.dm deleted file mode 100644 index 922682352c742..0000000000000 --- a/code/__DEFINES/dcs/item_signals.dm +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Signals for /obj/item and subtypes that have too few related signals to put in separate files. - * Doc format: `/// when the signal is called: (signal arguments)`. - * All signals send the source datum of the signal as the first argument - */ - -// /obj/item - - -///called on [/obj/item] before unequip from base of [/mob/proc/unEquip]: (force, atom/newloc, no_move, invdrop, silent) -#define COMSIG_ITEM_PRE_UNEQUIP "item_pre_unequip" - ///only the pre unequip can be cancelled - #define COMPONENT_ITEM_BLOCK_UNEQUIP (1<<0) -///from base of obj/item/equipped(): (/mob/equipper, slot) -#define COMSIG_ITEM_EQUIPPED "item_equip" -///from base of obj/item/dropped(): (mob/user) -#define COMSIG_ITEM_DROPPED "item_drop" -///from base of obj/item/pickup(): (/mob/taker) -#define COMSIG_ITEM_PICKUP "item_pickup" -///from base of obj/item/hit_reaction(): (list/args) -#define COMSIG_ITEM_HIT_REACT "item_hit_react" - #define COMPONENT_BLOCK_SUCCESSFUL (1 << 0) - #define COMPONENT_BLOCK_PERFECT (1 << 2) -///from base of item/sharpener/attackby(): (amount, max) -#define COMSIG_ITEM_SHARPEN_ACT "sharpen_act" - #define COMPONENT_SHARPEN_APPLIED (1<<0) - #define COMPONENT_BLOCK_SHARPEN_BLOCKED (1<<1) - #define COMPONENT_BLOCK_SHARPEN_ALREADY (1<<2) - #define COMPONENT_BLOCK_SHARPEN_MAXED (1<<3) -/// Called by [/obj/item/assembly/proc/pulse] -#define COMSIG_ASSEMBLY_PULSED "item_assembly_pulsed" -///from [/mob/living/carbon/human/proc/Move]: () -#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" - -// /obj/item/implant - -///from base of /obj/item/bio_chip/proc/activate(): () -#define COMSIG_IMPLANT_ACTIVATED "implant_activated" -///from base of /obj/item/bio_chip/proc/implant(): (list/args) -#define COMSIG_IMPLANT_IMPLANTING "implant_implanting" - #define COMPONENT_STOP_IMPLANTING (1<<0) -///called on already installed implants when a new one is being added in /obj/item/bio_chip/proc/implant(): (list/args, obj/item/bio_chip/new_implant) -#define COMSIG_IMPLANT_OTHER "implant_other" - //#define COMPONENT_STOP_IMPLANTING (1<<0) //The name makes sense for both - #define COMPONENT_DELETE_NEW_IMPLANT (1<<1) - #define COMPONENT_DELETE_OLD_IMPLANT (1<<2) -///called on implants being implanted into someone with an uplink implant: (datum/component/uplink) -#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists" - //This uses all return values of COMSIG_IMPLANT_OTHER - -/// called on implants, after a successful implantation: (mob/living/target, mob/user, silent, force) -#define COMSIG_IMPLANT_IMPLANTED "implant_implanted" - -/// called on implants, after an implant has been removed: (mob/living/source, silent, special) -#define COMSIG_IMPLANT_REMOVED "implant_removed" - - -// /obj/item/gun - -///called in /obj/item/gun/fire_gun (user, target, flag, params) -#define COMSIG_GUN_TRY_FIRE "gun_try_fire" - #define COMPONENT_CANCEL_GUN_FIRE (1<<0) -///called in /obj/item/gun/afterattack (user, target, flag, params) -#define COMSIG_MOB_TRY_FIRE "mob_fired_gun" -///called in /obj/item/gun/process_fire (user, target) -#define COMSIG_GUN_FIRED "gun_fired" -/// called in /datum/component/automatic_fire/proc/on_mouse_down: (client/clicker, atom/target, turf/location, control, params) -#define COMSIG_AUTOFIRE_ONMOUSEDOWN "autofire_onmousedown" - #define COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS (1<<0) -/// called in /datum/component/automatic_fire/proc/process_shot(): (atom/target, mob/living/shooter, allow_akimbo, params) -#define COMSIG_AUTOFIRE_SHOT "autofire_shot" - #define COMPONENT_AUTOFIRE_SHOT_SUCCESS (1<<0) - - -// /obj/item/mod - -/// 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" - - -// other items - -/// from base of /obj/item/slimepotion/speed/afterattack__legacy__attackchain(): (obj/target, /obj/src, mob/user) -#define COMSIG_SPEED_POTION_APPLIED "speed_potion" - #define SPEED_POTION_STOP (1<<0) - diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm deleted file mode 100644 index 59ab3c75e31ea..0000000000000 --- a/code/__DEFINES/hud.dm +++ /dev/null @@ -1,103 +0,0 @@ - -// for secHUDs and medHUDs and variants. The number is the location of the image on the list hud_list -// note: if you add more HUDs, even for non-human atoms, make sure to use unique numbers for the defines! -// /datum/atom_hud expects these to be unique -// these need to be strings in order to make them associative lists -#define HEALTH_HUD "1" // dead, alive, sick, health status -#define STATUS_HUD "2" // a simple line rounding the mob's number health -#define ID_HUD "3" // the job asigned to your ID -#define WANTED_HUD "4" // wanted, released, parroled, security status -#define IMPMINDSHIELD_HUD "5" // mindshield bio-chip -#define IMPCHEM_HUD "6" // chemical bio-chip -#define IMPTRACK_HUD "7" // tracking bio-chip -#define DIAG_STAT_HUD "8" // Silicon/Mech Status -#define DIAG_HUD "9" // Silicon health bar -#define DIAG_BATT_HUD "10"// Borg/Mech power meter -#define DIAG_MECH_HUD "11"// Mech health bar -#define SPECIALROLE_HUD "12" //for antag huds. these are used at the /mob level -#define DIAG_BOT_HUD "13"// Bot HUDS -#define PLANT_NUTRIENT_HUD "14"// Plant nutrient level -#define PLANT_WATER_HUD "15"// Plant water level -#define PLANT_STATUS_HUD "16"// Plant harvest/dead -#define PLANT_HEALTH_HUD "17"// Plant health -#define PLANT_TOXIN_HUD "18"// Toxin level -#define PLANT_PEST_HUD "19"// Pest level -#define PLANT_WEED_HUD "20"// Weed level -#define DIAG_TRACK_HUD "21"// Mech tracking beacon -#define DIAG_AIRLOCK_HUD "22" // Airlock shock overlay -#define GLAND_HUD "23"//Gland indicators for abductors -#define JANI_HUD "24" // Sign overlay over cleanable decals -#define PRESSURE_HUD "25" // Pressure coloring for tiles - -//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 -#define HUD_LIST_LIST 1 - -//data HUD (medhud, sechud) defines -//Don't forget to update human/New() if you change these! -#define DATA_HUD_SECURITY_BASIC 1 -#define DATA_HUD_SECURITY_ADVANCED 2 -#define DATA_HUD_MEDICAL_BASIC 3 -#define DATA_HUD_MEDICAL_ADVANCED 4 -#define DATA_HUD_DIAGNOSTIC_BASIC 5 -#define DATA_HUD_DIAGNOSTIC_ADVANCED 6 -#define DATA_HUD_HYDROPONIC 7 -#define DATA_HUD_JANITOR 8 -#define DATA_HUD_PRESSURE 9 -//antag HUD defines -#define ANTAG_HUD_CULT 10 -#define ANTAG_HUD_REV 11 -#define ANTAG_HUD_OPS 12 -#define ANTAG_HUD_WIZ 13 -#define ANTAG_HUD_SHADOW 14 -#define ANTAG_HUD_TRAITOR 15 -#define ANTAG_HUD_NINJA 16 -#define ANTAG_HUD_CHANGELING 17 -#define ANTAG_HUD_VAMPIRE 18 -#define ANTAG_HUD_ABDUCTOR 19 -#define DATA_HUD_ABDUCTOR 20 -#define ANTAG_HUD_EVENTMISC 21 -#define ANTAG_HUD_BLOB 22 -#define ANTAG_HUD_ZOMBIE 23 -#define ANTAG_HUD_MIND_FLAYER 24 - -// Notification action types -#define NOTIFY_JUMP "jump" -#define NOTIFY_ATTACK "attack" -#define NOTIFY_FOLLOW "orbit" - - -// The kind of things granted by HUD items in game, that do not manifest as -// on-screen icons, but rather go to examine text. -#define EXAMINE_HUD_SECURITY_READ "security_read" -#define EXAMINE_HUD_SECURITY_WRITE "security_write" -#define EXAMINE_HUD_MEDICAL_READ "medical_read" -#define EXAMINE_HUD_MEDICAL_WRITE "medical_write" -#define EXAMINE_HUD_SKILLS "skills" - -/proc/ui_hand_position(i) - // values based on old hand ui positions (CENTER:-/+16,SOUTH:5) - var/x_off = i % 2 ? 0 : -1 - var/y_off = round((i-1) / 2) - return"CENTER+[x_off]:16,SOUTH+[y_off]:5" - -/proc/ui_equip_position(mob/M) - // values based on old equip ui position (CENTER: +/-16,SOUTH+1:5) - var/y_off = round(1 / 2) - return "CENTER:-16,SOUTH+[y_off+1]:5" - -/proc/ui_swaphand_position(mob/M, which = 1) - // values based on old swaphand ui positions (CENTER: +/-16,SOUTH+1:5) - var/x_off = which == 1 ? -1 : 0 - var/y_off = round(1 / 2) - return "CENTER+[x_off]:16,SOUTH+[y_off+1]:5" - - -/// Takes a string or num view, and converts it to pixel width/height in a list(pixel_width, pixel_height) -/proc/view_to_pixels(view) - if(!view) - return list(0, 0) - var/list/view_info = getviewsize(view) - view_info[1] *= world.icon_size - view_info[2] *= world.icon_size - return view_info diff --git a/code/__DEFINES/hud_locations.dm b/code/__DEFINES/hud_locations.dm deleted file mode 100644 index bdec7b2f81257..0000000000000 --- a/code/__DEFINES/hud_locations.dm +++ /dev/null @@ -1,166 +0,0 @@ -/* - These defines specificy screen locations. For more information, see the byond documentation on the screen_loc var. - - The short version: - - Everything is encoded as strings because apparently that's how Byond rolls. - - "1,1" is the bottom left square of the user's screen. This aligns perfectly with the turf grid. - "1:2,3:4" is the square (1,3) with pixel offsets (+2, +4); slightly right and slightly above the turf grid. - Pixel offsets are used so you don't perfectly hide the turf under them, that would be crappy. - - The size of the user's screen is defined by client.view (indirectly by world.view), in our case "15x15". - Therefore, the top right corner (except during admin shenanigans) is at "15,15" -*/ - -//Middle left indicators -#define ui_alienplasmadisplay "EAST-1:28,CENTER-2:15" - -//Lower left, persistant menu -#define ui_inventory "WEST:6,SOUTH:5" - -//Middle left indicators -#define ui_lingchemdisplay "WEST:6,CENTER-1:15" -#define ui_lingstingdisplay "WEST:6,CENTER-3:11" - -//Lower center, persistant menu -#define ui_sstore1 "CENTER-5:10,SOUTH:5" -#define ui_id "CENTER-4:12,SOUTH:5" -#define ui_belt "CENTER-3:14,SOUTH:5" -#define ui_back "CENTER-2:14,SOUTH:5" -#define ui_rhand "CENTER:-16,SOUTH:5" -#define ui_lhand "CENTER: 16,SOUTH:5" -#define ui_equip "CENTER:-16,SOUTH+1:5" -#define ui_swaphand1 "CENTER:-16,SOUTH+1:5" -#define ui_swaphand2 "CENTER: 16,SOUTH+1:5" -#define ui_storage1 "CENTER+1:18,SOUTH:5" -#define ui_storage2 "CENTER+2:20,SOUTH:5" -#define ui_pda "CENTER+3:22,SOUTH:5" -#define ui_combo "CENTER+4:24,SOUTH+1:7" //combo meter for martial arts - -#define ui_alien_head "4:12,1:5" //aliens -#define ui_alien_oclothing "5:14,1:5" //aliens - -#define ui_borg_sensor "CENTER-3:16, SOUTH:5" //borgs -#define ui_borg_lamp "CENTER-4:16, SOUTH:5" //borgs -#define ui_borg_thrusters "CENTER-5:16, SOUTH:5"//borgs -#define ui_inv1 "CENTER-2:16,SOUTH:5" //borgs -#define ui_inv2 "CENTER-1 :16,SOUTH:5" //borgs -#define ui_inv3 "CENTER :16,SOUTH:5" //borgs -#define ui_borg_module "CENTER+1:16,SOUTH:5" -#define ui_borg_store "CENTER+2:16,SOUTH:5" //borgs - - -#define ui_monkey_mask "CENTER-3:14,SOUTH:5" //monkey -#define ui_monkey_back "CENTER-2:15,SOUTH:5" //monkey - -#define ui_alien_storage_l "CENTER-2:14,SOUTH:5"//alien -#define ui_alien_storage_r "CENTER+1:18,SOUTH:5"//alien -#define ui_alien_language_menu "EAST-3:25,SOUTH+1:7"//alien -#define ui_alienlarva_language_menu "EAST-3:26,SOUTH:5"//alien - -//Lower right, persistant menu -//#define ui_dropbutton "11:22,1:5" -#define ui_drop_throw "EAST-1:28,SOUTH+1:7" -#define ui_pull_resist "EAST-2:26,SOUTH+1:7" -#define ui_acti "EAST-2:26,SOUTH:5" -#define ui_movi "EAST-3:24,SOUTH:5" -#define ui_zonesel "EAST-1:28,SOUTH:5" -#define ui_acti_alt "EAST-1:28,SOUTH:5" //alternative intent switcher for when the interface is hidden (F12) - -#define ui_crafting "EAST:-5,SOUTH+2:7" -#define ui_language_menu "EAST:-22,SOUTH+2:7" - -#define ui_borg_pull "EAST-2:26,SOUTH+1:7" -#define ui_borg_radio "EAST-1:28,SOUTH+1:7" -#define ui_borg_intents "EAST-2:26,SOUTH:5" -#define ui_borg_lanugage_menu "EAST-2:26,SOUTH+1:7" - -//Upper-middle right (alerts) -#define ui_alert1 "EAST-1:28,CENTER+5:27" -#define ui_alert2 "EAST-1:28,CENTER+4:25" -#define ui_alert3 "EAST-1:28,CENTER+3:23" -#define ui_alert4 "EAST-1:28,CENTER+2:21" -#define ui_alert5 "EAST-1:28,CENTER+1:19" - -//Middle right (status indicators) -#define ui_internal "EAST-1:28,CENTER+1:19" -#define ui_health "EAST-1:28,CENTER:17" -#define ui_healthdoll "EAST-1:28,CENTER-1:15" -#define ui_nutrition "EAST-2:32,CENTER-1:13" -#define ui_stamina "EAST-1:28,CENTER-2:15" - -//borgs -#define ui_borg_health "EAST-1:28,CENTER-1:15" //borgs have the health display where humans have the pressure damage indicator. - -//aliens -#define ui_alien_health "EAST-1:28,CENTER-1:15" //aliens have the health display where humans have the pressure damage indicator. - -//constructs -#define ui_construct_pull "EAST-1:28,SOUTH+1:10" //above the zone_sel icon -#define ui_construct_health "EAST,CENTER:15" //same height as humans, hugging the right border - -//slimes -#define ui_slime_health "EAST,CENTER:15" //same as borgs, constructs and humans - -//Pop-up inventory -#define ui_shoes "WEST+1:8,SOUTH:5" - -#define ui_iclothing "WEST:6,SOUTH+1:7" -#define ui_oclothing "WEST+1:8,SOUTH+1:7" -#define ui_gloves "WEST+2:10,SOUTH+1:7" - - -#define ui_glasses "WEST:6,SOUTH+3:11" -#define ui_mask "WEST+1:8,SOUTH+2:9" -#define ui_l_ear "WEST+2:10,SOUTH+2:9" -#define ui_r_ear "WEST+2:10,SOUTH+3:11" - -#define ui_neck "WEST:6,SOUTH+2:9" - -#define ui_head "WEST+1:8,SOUTH+3:11" - -// AI - -#define ui_ai_view_images "BOTTOM+1:6,LEFT" -#define ui_ai_take_picture "BOTTOM+1:6,LEFT+1" -#define ui_ai_camera_list "BOTTOM:6,LEFT" -#define ui_ai_camera_light "BOTTOM:6,LEFT+1" -#define ui_ai_track_with_camera "BOTTOM:6,LEFT+2" - -#define ui_ai_crew_monitor "BOTTOM:6,CENTER-3" -#define ui_ai_crew_manifest "BOTTOM:6,CENTER-2" -#define ui_ai_alerts "BOTTOM:6,CENTER-1" -#define ui_ai_announcement "BOTTOM:6,CENTER" -#define ui_ai_shuttle "BOTTOM:6,CENTER+1" -#define ui_ai_pda_log "BOTTOM:6,CENTER+2" -#define ui_ai_pda_send "BOTTOM:6,CENTER+3" - -#define ui_ai_state_laws "SOUTH:6,RIGHT-2" -#define ui_ai_core "SOUTH:6,RIGHT-1" -#define ui_ai_sensor "SOUTH:6,RIGHT" - -// Bots -#define ui_bot_radio "EAST-1:28,SOUTH:7" -#define ui_bot_pull "EAST-2:26,SOUTH:7" - -//Ghosts -#define ui_ghost_orbit "SOUTH:6,CENTER-1.5" -#define ui_ghost_reenter_corpse "SOUTH:6,CENTER-.5" -#define ui_ghost_teleport "SOUTH:6,CENTER+.5" -#define ui_ghost_respawn_list "SOUTH:6,CENTER+1.5" -#define ui_ghost_respawn_mob "SOUTH:6+1,CENTER+1.5" -#define ui_ghost_respawn_pai "SOUTH:6+2,CENTER+1.5" - -//HUD styles. Please ensure HUD_VERSIONS is the same as the maximum index. Index order defines how they are cycled in F12. -#define HUD_STYLE_STANDARD 1 -#define HUD_STYLE_REDUCED 2 -#define HUD_STYLE_NOHUD 3 -#define HUD_STYLE_ACTIONHUD 4 - - -#define HUD_VERSIONS 4 //used in show_hud() -//1 = standard hud -//2 = reduced hud (just hands and intent switcher) -//3 = no hud (for screenshots) -//4 = Only action buttons (so vampires / changelings and such can use abilities while asleep) diff --git a/code/__DEFINES/job_defines.dm b/code/__DEFINES/job_defines.dm deleted file mode 100644 index 161dd84541a46..0000000000000 --- a/code/__DEFINES/job_defines.dm +++ /dev/null @@ -1,58 +0,0 @@ -/////////////////////////////// -// WARNING // -//////////////////////////////////////////////////////////////////////// -// Do NOT touch the values associated with these defines, as they are // -// used by the game database to keep track of job flags. Do NOT touch // -//////////////////////////////////////////////////////////////////////// - -#define JOBCAT_ENGSEC (1<<0) - -#define JOB_CAPTAIN (1<<0) -#define JOB_HOS (1<<1) -#define JOB_WARDEN (1<<2) -#define JOB_DETECTIVE (1<<3) -#define JOB_OFFICER (1<<4) -#define JOB_CHIEF (1<<5) -#define JOB_ENGINEER (1<<6) -#define JOB_ATMOSTECH (1<<7) -#define JOB_AI (1<<8) -#define JOB_CYBORG (1<<9) -#define JOB_CENTCOM (1<<10) -#define JOB_SYNDICATE (1<<11) -#define JOB_JUDGE (1<<12) -#define JOB_BLUESHIELD (1<<13) -#define JOB_NANO (1<<14) -#define JOB_INSTRUCTOR (1<<15) - -#define JOBCAT_MEDSCI (1<<1) - -#define JOB_RD (1<<0) -#define JOB_SCIENTIST (1<<1) -#define JOB_CHEMIST (1<<2) -#define JOB_CMO (1<<3) -#define JOB_DOCTOR (1<<4) -#define JOB_GENETICIST (1<<5) -#define JOB_VIROLOGIST (1<<6) -#define JOB_PSYCHIATRIST (1<<7) -#define JOB_ROBOTICIST (1<<8) -#define JOB_PARAMEDIC (1<<9) -#define JOB_CORONER (1<<10) - - -#define JOBCAT_SUPPORT (1<<2) - -#define JOB_HOP (1<<0) -#define JOB_BARTENDER (1<<1) -#define JOB_BOTANIST (1<<2) -#define JOB_CHEF (1<<3) -#define JOB_JANITOR (1<<4) -#define JOB_LIBRARIAN (1<<5) -#define JOB_QUARTERMASTER (1<<6) -#define JOB_CARGOTECH (1<<7) -#define JOB_MINER (1<<8) -#define JOB_INTERNAL_AFFAIRS (1<<9) -#define JOB_CHAPLAIN (1<<10) -#define JOB_CLOWN (1<<11) -#define JOB_MIME (1<<12) -#define JOB_ASSISTANT (1<<13) -#define JOB_EXPLORER (1<<14) diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm deleted file mode 100644 index 0dbc154ec0bff..0000000000000 --- a/code/__DEFINES/machines.dm +++ /dev/null @@ -1,111 +0,0 @@ -#define IMPRINTER (1<<0) //For circuits. Uses glass/chemicals. -#define PROTOLATHE (1<<1) //New stuff. Uses glass/metal/chemicals -#define AUTOLATHE (1<<2) //Uses glass/metal only. -#define CRAFTLATHE (1<<3) //Uses fuck if I know. For use eventually. -#define MECHFAB (1<<4) //Remember, objects utilising this flag should have construction_time and construction_cost vars. -// #define PODFAB (1<<5) //Used by the spacepod part fabricator. Same idea as the mechfab // AA 2021-10-02 - Removed. Kept for flag consistency. -#define BIOGENERATOR (1<<6) //Uses biomass -#define SMELTER (1<<7) //uses various minerals -/// Used for gamma armoury lathe designs -#define GAMMALATHE (1<<8) -//Note: More then one of these can be added to a design but imprinter and lathe designs are incompatable. - - -// Demotion Console (card/minor/*) departments -#define TARGET_DEPT_GENERIC 1 -#define TARGET_DEPT_SEC 2 -#define TARGET_DEPT_MED 3 -#define TARGET_DEPT_SCI 4 -#define TARGET_DEPT_ENG 5 -#define TARGET_DEPT_SUP 6 - -// These are used by supermatter and supermatter monitor program, mostly for UI updating purposes. Higher should always be worse! -// These are warning defines, they should trigger before the state, not after. -#define SUPERMATTER_ERROR -1 // Unknown status, shouldn't happen but just in case. -#define SUPERMATTER_INACTIVE 0 // No or minimal energy -#define SUPERMATTER_NORMAL 1 // Normal operation -#define SUPERMATTER_NOTIFY 2 // Ambient temp > 80% of CRITICAL_TEMPERATURE -#define SUPERMATTER_WARNING 3 // Ambient temp > CRITICAL_TEMPERATURE OR integrity damaged -#define SUPERMATTER_DANGER 4 // Integrity < 75% -#define SUPERMATTER_EMERGENCY 5 // Integrity < 50% -#define SUPERMATTER_DELAMINATING 6 // Pretty obvious, Integrity < 25% - -// More defines for the suppermatter -/// Higher == Crystal safe operational temperature is higher. -#define SUPERMATTER_HEAT_PENALTY_THRESHOLD 40 - -// Firelock states -#define FD_OPEN 1 -#define FD_CLOSED 2 - -// Computer login types -#define LOGIN_TYPE_NORMAL 1 -#define LOGIN_TYPE_AI 2 -#define LOGIN_TYPE_ROBOT 3 -#define LOGIN_TYPE_ADMIN 4 - -// Status display maptext stuff -#define DISPLAY_CHARS_PER_LINE 5 -#define DISPLAY_FONT_SIZE "5pt" -#define DISPLAY_FONT_COLOR "#09f" -#define DISPLAY_WARNING_FONT_COLOR "#f90" -#define DISPLAY_FONT_STYLE "Small Fonts" -#define DISPLAY_SCROLL_SPEED 2 - -// Status display mode types -#define STATUS_DISPLAY_BLANK 0 -#define STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME 1 -#define STATUS_DISPLAY_MESSAGE 2 -#define STATUS_DISPLAY_ALERT 3 -#define STATUS_DISPLAY_TIME 4 -#define STATUS_DISPLAY_CUSTOM 5 - -// AI display mode types -#define AI_DISPLAY_MODE_BLANK 0 -#define AI_DISPLAY_MODE_EMOTE 1 -#define AI_DISPLAY_MODE_BSOD 2 - -// Door operations -#define DOOR_OPENING 1 -#define DOOR_CLOSING 2 -#define DOOR_MALF 3 - -#define TURRET_PRIORITY_TARGET 2 -#define TURRET_SECONDARY_TARGET 1 -#define TURRET_NOT_TARGET 0 - -#define TURRET_PREASSESS_VALID 1 -#define TURRET_PREASSESS_INVALID 0 - -#define AIR_ALARM_FRAME 0 -#define AIR_ALARM_UNWIRED 1 -#define AIR_ALARM_READY 2 - -/** - * Air alarm modes - */ -#define AALARM_MODE_FILTERING 1 -#define AALARM_MODE_DRAUGHT 2 //makes draught -#define AALARM_MODE_PANIC 3 //like siphon, but stronger (enables widenet) -#define AALARM_MODE_CYCLE 4 //sucks off all air, then refill and swithes to scrubbing -#define AALARM_MODE_SIPHON 5 //Scrubbers suck air -#define AALARM_MODE_CONTAMINATED 6 //Turns on all filtering and widenet scrubbing. -#define AALARM_MODE_REFILL 7 //just like normal, but disables low pressure check until normalized, then switches to normal -#define AALARM_MODE_OFF 8 -#define AALARM_MODE_FLOOD 9 //Emagged mode; turns off scrubbers and pressure checks on vents -#define AALARM_MODE_CUSTOM 10 - -#define NUKE_STATUS_INTACT 0 -#define NUKE_CORE_MISSING 1 -#define NUKE_MISSING 2 - -#define CIRCULATOR_SIDE_LEFT WEST -#define CIRCULATOR_SIDE_RIGHT EAST - -// Request Console configuration bitmask. -/// [/obj/machinery/requests_console] can request assistance. -#define RC_ASSIST (1<<0) -/// [/obj/machinery/requests_console] can request supplies. -#define RC_SUPPLY (1<<1) -/// [/obj/machinery/requests_console] can relay anonymous information. -#define RC_INFO (1<<2) diff --git a/code/__DEFINES/magic_defines.dm b/code/__DEFINES/magic_defines.dm deleted file mode 100644 index 9d0ee8158cdc8..0000000000000 --- a/code/__DEFINES/magic_defines.dm +++ /dev/null @@ -1,16 +0,0 @@ -// Bitflags for magic resistance types -/// Default magic resistance that blocks normal magic (wizard, spells, magical staff projectiles) -#define MAGIC_RESISTANCE (1<<0) -/// Tinfoil hat magic resistance that blocks mental magic (telepathy / mind links, mind curses, abductors) -#define MAGIC_RESISTANCE_MIND (1<<1) -/// Holy magic resistance that blocks unholy magic (revenant, vampire, voice of god) -#define MAGIC_RESISTANCE_HOLY (1<<2) - -DEFINE_BITFIELD(antimagic_flags, list( - "MAGIC_RESISTANCE" = MAGIC_RESISTANCE, - "MAGIC_RESISTANCE_HOLY" = MAGIC_RESISTANCE_HOLY, - "MAGIC_RESISTANCE_MIND" = MAGIC_RESISTANCE_MIND, -)) - -/// Whether the spell can be cast while the user has antimagic on them that corresponds to the spell's own antimagic flags. -#define SPELL_REQUIRES_NO_ANTIMAGIC (1 << 0) diff --git a/code/__DEFINES/rust.dm b/code/__DEFINES/rust.dm deleted file mode 100644 index 6ac60f4de08e2..0000000000000 --- a/code/__DEFINES/rust.dm +++ /dev/null @@ -1,170 +0,0 @@ -// DM API for Rust extension modules -// Current modules: -// - MILLA, an asynchronous replacement for BYOND atmos -// - Mapmanip, a parse-time DMM file reader and modifier - -// Default automatic library detection. -// Look for it in the build location first, then in `.`, then in standard places. - -/* This comment bypasses grep checks */ /var/__rustlib - -// IF we are on the production box, use a dll that has 0 compatibility of working with normal people's CPUs -// This works by allowing rust to compile with modern x86 instructionns, instead of compiling for a pentium 4 -// This has the potential for significant speed upgrades with SIMD and similar -#ifdef PARADISE_PRODUCTION_HARDWARE -#define RUSTLIBS_SUFFIX "_prod" -#else -#define RUSTLIBS_SUFFIX "" -#endif - -/proc/__detect_rustlib() - if(world.system_type == UNIX) -#ifdef CIBUILDING - // CI override, use librustlibs_ci.so if possible. - if(fexists("./tools/ci/librustlibs_ci.so")) - return __rustlib = "tools/ci/librustlibs_ci.so" -#endif - // First check if it's built in the usual place. - if(fexists("./rust/target/i686-unknown-linux-gnu/release/librustlibs[RUSTLIBS_SUFFIX].so")) - return __rustlib = "./rust/target/i686-unknown-linux-gnu/release/librustlibs[RUSTLIBS_SUFFIX].so" - // Then check in the current directory. - if(fexists("./librustlibs[RUSTLIBS_SUFFIX].so")) - return __rustlib = "./librustlibs[RUSTLIBS_SUFFIX].so" - // And elsewhere. - return __rustlib = "librustlibs[RUSTLIBS_SUFFIX].so" - else - // First check if it's built in the usual place. - if(fexists("./rust/target/i686-pc-windows-msvc/release/rustlibs[RUSTLIBS_SUFFIX].dll")) - return __rustlib = "./rust/target/i686-pc-windows-msvc/release/rustlibs[RUSTLIBS_SUFFIX].dll" - // Then check in the current directory. - if(fexists("./rustlibs[RUSTLIBS_SUFFIX].dll")) - return __rustlib = "./rustlibs[RUSTLIBS_SUFFIX].dll" - - // And elsewhere. - var/assignment_confirmed = (__rustlib = "rustlibs[RUSTLIBS_SUFFIX].dll") - // This being spanned over multiple lines is kinda scuffed, but its needed because of https://www.byond.com/forum/post/2072419 - return assignment_confirmed - - -#define RUSTLIB (__rustlib || __detect_rustlib()) - -#define RUSTLIB_CALL(func, args...) call_ext(RUSTLIB, "byond:[#func]_ffi")(args) - -// This needs to go BELOW the above define, otherwise the BYOND compiler can make the above immediate call disappear -#undef RUSTLIBS_SUFFIX - -/// Exists by default in 516, but needs to be defined for 515 or byondapi-rs doesn't like it. -/proc/byondapi_stack_trace(err) - CRASH(err) - -/proc/milla_init_z(z) - return RUSTLIB_CALL(milla_initialize, z) - -/proc/milla_load_turfs(turf/low_corner, turf/high_corner) - ASSERT(istype(low_corner)) - ASSERT(istype(high_corner)) - return RUSTLIB_CALL(milla_load_turfs, "milla_data", low_corner, high_corner) - -/proc/set_tile_atmos(turf/T, airtight_north, airtight_east, airtight_south, airtight_west, atmos_mode, environment_id, oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, temperature, innate_heat_capacity, hotspot_temperature, hotspot_volume) - return RUSTLIB_CALL(milla_set_tile, T, airtight_north, airtight_east, airtight_south, airtight_west, atmos_mode, environment_id, oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, temperature, innate_heat_capacity, hotspot_temperature, hotspot_volume) - -/proc/get_tile_atmos(turf/T, list/L) - return RUSTLIB_CALL(milla_get_tile, T, L) - -/proc/spawn_milla_tick_thread() - return RUSTLIB_CALL(milla_spawn_tick_thread) - -/proc/get_milla_tick_time() - return RUSTLIB_CALL(milla_get_tick_time) - -/proc/get_interesting_atmos_tiles() - return RUSTLIB_CALL(milla_get_interesting_tiles) - -/proc/get_tracked_pressure_tiles() - return RUSTLIB_CALL(milla_get_tracked_pressure_tiles) - -/proc/reduce_superconductivity(turf/T, list/superconductivity) - var/north = superconductivity[1] - var/east = superconductivity[2] - var/south = superconductivity[3] - var/west = superconductivity[4] - - return RUSTLIB_CALL(milla_reduce_superconductivity, T, north, east, south, west) - -/proc/reset_superconductivity(turf/T) - return RUSTLIB_CALL(milla_reset_superconductivity, T) - -/proc/set_tile_airtight(turf/T, list/airtight) - var/north = airtight[1] - var/east = airtight[2] - var/south = airtight[3] - var/west = airtight[4] - - return RUSTLIB_CALL(milla_set_tile_airtight, T, north, east, south, west) - -/proc/create_hotspot(turf/T, hotspot_temperature, hotspot_volume) - return RUSTLIB_CALL(milla_create_hotspot, T, hotspot_temperature, hotspot_volume) - -/proc/track_pressure_tiles(atom/A, radius) - var/turf/T = get_turf(A) - if(istype(T)) - return RUSTLIB_CALL(milla_track_pressure_tiles, T, radius) - -/proc/get_random_interesting_tile() - return RUSTLIB_CALL(milla_get_random_interesting_tile) - -/proc/create_environment(oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, temperature) - return RUSTLIB_CALL(milla_create_environment, oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, temperature) - -/proc/mapmanip_read_dmm(mapname) - return RUSTLIB_CALL(mapmanip_read_dmm_file, mapname) - -#undef RUSTLIB -#undef RUSTLIB_CALL - -// Indexes for Tiles and InterestingTiles -// Must match the order in milla/src/model.rs -#define MILLA_INDEX_AIRTIGHT_DIRECTIONS 1 -#define MILLA_INDEX_OXYGEN 2 -#define MILLA_INDEX_CARBON_DIOXIDE 3 -#define MILLA_INDEX_NITROGEN 4 -#define MILLA_INDEX_TOXINS 5 -#define MILLA_INDEX_SLEEPING_AGENT 6 -#define MILLA_INDEX_AGENT_B 7 -#define MILLA_INDEX_ATMOS_MODE 8 -#define MILLA_INDEX_ENVIRONMENT_ID 9 -#define MILLA_INDEX_SUPERCONDUCTIVITY_NORTH 10 -#define MILLA_INDEX_SUPERCONDUCTIVITY_EAST 11 -#define MILLA_INDEX_SUPERCONDUCTIVITY_SOUTH 12 -#define MILLA_INDEX_SUPERCONDUCTIVITY_WEST 13 -#define MILLA_INDEX_INNATE_HEAT_CAPACITY 14 -#define MILLA_INDEX_TEMPERATURE 15 -#define MILLA_INDEX_HOTSPOT_TEMPERATURE 16 -#define MILLA_INDEX_HOTSPOT_VOLUME 17 -#define MILLA_INDEX_WIND_X 18 -#define MILLA_INDEX_WIND_Y 19 -#define MILLA_INDEX_FUEL_BURNT 20 - -/// The number of values per tile. -#define MILLA_TILE_SIZE MILLA_INDEX_FUEL_BURNT - -// These are only for InterestingTiles. -#define MILLA_INDEX_TURF 21 -#define MILLA_INDEX_INTERESTING_REASONS 22 -#define MILLA_INDEX_AIRFLOW_X 23 -#define MILLA_INDEX_AIRFLOW_Y 24 - -/// The number of values per interesting tile. -#define MILLA_INTERESTING_TILE_SIZE MILLA_INDEX_AIRFLOW_Y - -/// Interesting because it needs a display update. -#define MILLA_INTERESTING_REASON_DISPLAY (1 << 0) -/// Interesting because it's hot enough to start a fire. Excludes normal-temperature Lavaland tiles without an active fire. -#define MILLA_INTERESTING_REASON_HOT (1 << 1) -/// Interesting because it has wind that can push stuff around. -#define MILLA_INTERESTING_REASON_WIND (1 << 2) - -#define MILLA_NORTH (1 << 0) -#define MILLA_EAST (1 << 1) -#define MILLA_SOUTH (1 << 2) -#define MILLA_WEST (1 << 3) diff --git a/code/__DEFINES/wires_defines.dm b/code/__DEFINES/wires_defines.dm deleted file mode 100644 index 7d267d96e954b..0000000000000 --- a/code/__DEFINES/wires_defines.dm +++ /dev/null @@ -1,85 +0,0 @@ -// Wire defines for all machines/items. - -// Miscellaneous -#define WIRE_DUD_PREFIX "__dud" - -// General -#define WIRE_IDSCAN "ID Scan" -#define WIRE_MAIN_POWER1 "Primary Power" -#define WIRE_MAIN_POWER2 "Secondary Power" -#define WIRE_AI_CONTROL "AI Control" -#define WIRE_ELECTRIFY "Electrification" -#define WIRE_SAFETY "Safety" - -// Vendors and smartfridges -#define WIRE_THROW_ITEM "Item Throw" -#define WIRE_CONTRABAND "Contraband" - -// Airlock -#define WIRE_DOOR_BOLTS "Door Bolts" -#define WIRE_BACKUP_POWER1 "Primary Backup Power" -#define WIRE_OPEN_DOOR "Door State" -#define WIRE_SPEED "Door Timing" -#define WIRE_BOLT_LIGHT "Bolt Lights" - -// Air alarm -#define WIRE_SIPHON "Siphon" -#define WIRE_AALARM "Atmospherics Alarm" - -// Camera -#define WIRE_FOCUS "Focus" - -// Mulebot -#define WIRE_MOB_AVOIDANCE "Mob Avoidance" -#define WIRE_LOADCHECK "Load Checking" -#define WIRE_MOTOR1 "Primary Motor" -#define WIRE_MOTOR2 "Secondary Motor" -#define WIRE_REMOTE_RX "Signal Receiver" -#define WIRE_REMOTE_TX "Signal Sender" -#define WIRE_BEACON_RX "Beacon Receiver" - -// Explosives, bombs -#define WIRE_EXPLODE "Explode" // Explodes if pulsed or cut while active, defuses a bomb that isn't active on cut. -#define WIRE_BOMB_UNBOLT "Unbolt" // Unbolts the bomb if cut, hint on pulsed. -#define WIRE_BOMB_DELAY "Delay" // Raises the timer on pulse, does nothing on cut. -#define WIRE_BOMB_PROCEED "Proceed" // Lowers the timer, explodes if cut while the bomb is active. -#define WIRE_BOMB_ACTIVATE "Activate" // Will start a bombs timer if pulsed, will hint if pulsed while already active, will stop a timer a bomb on cut. - -// Nuclear bomb -#define WIRE_NUKE_SAFETY "Safety" -#define WIRE_NUKE_DETONATOR "Detonator" -#define WIRE_NUKE_DISARM "Disarm" -#define WIRE_NUKE_LIGHT "Lights" -#define WIRE_NUKE_CONTROL "Control Panel" - -// Particle accelerator -#define WIRE_PARTICLE_POWER "Power Toggle" // Toggles whether the PA is on or not. -#define WIRE_PARTICLE_STRENGTH "Strength" // Determines the strength of the PA. -#define WIRE_PARTICLE_INTERFACE "Interface" // Determines the interface showing up. -#define WIRE_PARTICLE_POWER_LIMIT "Maximum Power" // Determines how strong the PA can be. - -// Autolathe -#define WIRE_AUTOLATHE_HACK "Hack" -#define WIRE_AUTOLATHE_DISABLE "Disable" - -// Radio -#define WIRE_RADIO_SIGNAL "Signal" -#define WIRE_RADIO_RECEIVER "Receiver" -#define WIRE_RADIO_TRANSMIT "Transmitter" - -// Cyborg -#define WIRE_BORG_LOCKED "Lockdown" -#define WIRE_BORG_CAMERA "Camera" -#define WIRE_BORG_LAWCHECK "Law Check" - -// Suit storage unit -#define WIRE_SSU_UV "UV wire" - -// Tesla coil -#define WIRE_TESLACOIL_ZAP "Zap" - -// MODsuits -#define WIRE_HACK "Hack" -#define WIRE_DISABLE "Disable" -#define WIRE_INTERFACE "Interface" - diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm deleted file mode 100644 index 8cef0495e8e03..0000000000000 --- a/code/__HELPERS/_logging.dm +++ /dev/null @@ -1,275 +0,0 @@ -// On Linux/Unix systems the line endings are LF, on windows it's CRLF, admins that don't use notepad++ -// will get logs that are one big line if the system is Linux and they are using notepad. This solves it by adding CR to every line ending -// in the logs. ascii character 13 = CR - -GLOBAL_VAR_INIT(log_end, (world.system_type == UNIX ? ascii2text(13) : "")) -/// Log of TGS stuff that can be viewed ingame -GLOBAL_LIST_EMPTY(tgs_log) -GLOBAL_PROTECT(log_end) - -#define DIRECT_OUTPUT(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) - -/proc/error(msg) - log_world("## ERROR: [msg]") - -//print a warning message to world.log -#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [src] usr: [usr].") -/proc/warning(msg) - log_world("## WARNING: [msg]") - -//print a testing-mode debug message to world.log and world -#ifdef TESTING -#define testing(msg) log_world("## TESTING: [msg]"); to_chat(world, "## TESTING: [msg]") -#else -#define testing(msg) -#endif - -/proc/log_admin(text, skip_glob = FALSE) - if(!skip_glob) - GLOB.admin_log.Add(text) - if(GLOB.configuration.logging.admin_logging) - rustg_log_write(GLOB.world_game_log, "ADMIN: [text][GLOB.log_end]") - -/proc/log_debug(text) - // This has presence checks as this may be called before GLOB has loaded - if(GLOB?.configuration?.logging.debug_logging) - rustg_log_write(GLOB.world_game_log, "DEBUG: [text][GLOB.log_end]") - - for(var/client/C in GLOB.admins) - if(check_rights(R_DEBUG | R_VIEWRUNTIMES, FALSE, C.mob) && (C.prefs.toggles & PREFTOGGLE_CHAT_DEBUGLOGS)) - to_chat(C, "DEBUG: [text]", MESSAGE_TYPE_DEBUG, confidential = TRUE) - -/proc/log_game(text) - if(GLOB.configuration.logging.game_logging) - rustg_log_write(GLOB.world_game_log, "GAME: [text][GLOB.log_end]") - -/proc/log_vote(text) - if(GLOB.configuration.logging.vote_logging) - rustg_log_write(GLOB.world_game_log, "VOTE: [text][GLOB.log_end]") - -/proc/log_if_mismatch(mob/who, message, automatic = FALSE) - if(istype(usr, /mob) && istype(who) && usr.last_known_ckey != who.last_known_ckey) - if(automatic) - rustg_log_write(GLOB.world_game_log, "AUTOMATIC ([usr.last_known_ckey]): [message][GLOB.log_end]") - else - rustg_log_write(GLOB.world_game_log, "LOG USER MISMATCH: [usr.simple_info_line()] was usr for [message][GLOB.log_end]") - -/proc/log_access_in(client/new_client) - if(GLOB.configuration.logging.access_logging) - var/message = "ACCESS IN: [key_name(new_client)] - IP:[new_client.address] - CID:[new_client.computer_id] - BYOND v[new_client.byond_version].[new_client.byond_build]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(new_client.mob, message) - -/proc/log_access_out(mob/last_mob) - if(GLOB.configuration.logging.access_logging) - var/message = "ACCESS OUT: [key_name(last_mob)] - IP:[last_mob.lastKnownIP] - CID:[last_mob.computer_id] - BYOND Logged Out" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(last_mob, message) - -/proc/log_say(text, mob/speaker, automatic = FALSE) - if(GLOB.configuration.logging.say_logging) - var/message = "SAY: [speaker.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(speaker, message, automatic) - -/proc/log_whisper(text, mob/speaker) - if(GLOB.configuration.logging.whisper_logging) - var/message = "WHISPER: [speaker.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(speaker, message) - -/proc/log_ooc(text, client/user) - if(GLOB.configuration.logging.ooc_logging) - var/message = "OOC: [user.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(user, message) - -/proc/log_aooc(text, client/user) - if(GLOB.configuration.logging.ooc_logging) - var/message = "AOOC: [user.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(user, message) - -/proc/log_looc(text, client/user) - if(GLOB.configuration.logging.ooc_logging) - var/message = "LOOC: [user.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(user, message) - -/proc/log_emote(text, mob/speaker) - if(GLOB.configuration.logging.emote_logging) - var/message = "EMOTE: [speaker.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(speaker, message) - -/proc/log_attack(mob/attacker, defender_str, attack_message) - if(GLOB.configuration.logging.attack_logging) - var/attacker_str = "INVALID" - if(istype(attacker)) - attacker_str = attacker.simple_info_line() - var/message = "ATTACK: [attacker_str] against [defender_str]: [attack_message]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(attacker, message) - -/proc/log_adminsay(text, mob/speaker) - if(GLOB.configuration.logging.adminchat_logging) - var/message = "ADMINSAY: [speaker.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(speaker, message) - -/proc/log_ping_all_admins(text, mob/speaker) - if(GLOB.configuration.logging.adminchat_logging) - var/message = "ALL ADMIN PING: [speaker.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(speaker, message) - -/proc/log_qdel(text) - rustg_log_write(GLOB.world_qdel_log, "QDEL: [text][GLOB.log_end]") - -/proc/log_mentorsay(text, mob/speaker) - if(GLOB.configuration.logging.adminchat_logging) - var/message = "MENTORSAY: [speaker.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(speaker, message) - -/proc/log_devsay(text, mob/speaker) - if(GLOB.configuration.logging.adminchat_logging) - var/message = "DEVSAY: [speaker.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(speaker, message) - -/proc/log_ghostsay(text, mob/speaker) - if(GLOB.configuration.logging.say_logging) - var/message = "DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(speaker, message) - -/proc/log_ghostemote(text, mob/speaker) - if(GLOB.configuration.logging.emote_logging) - var/message = "DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(speaker, message) - -/proc/log_adminwarn(text) - if(GLOB.configuration.logging.admin_warning_logging) - rustg_log_write(GLOB.world_game_log, "ADMINWARN: [html_decode(text)][GLOB.log_end]") - -/proc/log_pda(text, mob/speaker) - if(GLOB.configuration.logging.pda_logging) - var/message = "PDA: [speaker.simple_info_line()]: [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(speaker, message) - -/proc/log_chat(text, mob/speaker) - if(GLOB.configuration.logging.pda_logging) - var/message = "CHAT: [speaker.simple_info_line()] [html_decode(text)]" - rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]") - log_if_mismatch(speaker, message) - -/proc/log_tgs(text, level) - GLOB.tgs_log += "\[[time_stamp()]] \[[level]] [text]" - rustg_log_write(GLOB.world_game_log, "TGS: [level]: [text][GLOB.log_end]") - -/proc/log_misc(text) - rustg_log_write(GLOB.world_game_log, "MISC: [text][GLOB.log_end]") - -/proc/log_world(text) - SEND_TEXT(world.log, text) - // This has to be presence checked as log_world() is used before world/New(). - if(GLOB?.configuration?.logging.world_logging) - rustg_log_write(GLOB.world_game_log, "WORLD: [html_decode(text)][GLOB.log_end]") - -/proc/log_runtime_txt(text) // different from /tg/'s log_runtime because our error handler has a log_runtime proc already that does other stuff - rustg_log_write(GLOB.world_runtime_log, "[text][GLOB.log_end]") - -/proc/log_config(text) - rustg_log_write(GLOB.config_error_log, "[text][GLOB.log_end]") - SEND_TEXT(world.log, text) - -/proc/log_href(text) - rustg_log_write(GLOB.world_href_log, "HREF: [html_decode(text)][GLOB.log_end]") - -/proc/log_runtime_summary(text) - rustg_log_write(GLOB.runtime_summary_log, "[text][GLOB.log_end]") - -/proc/log_tgui(user_or_client, text) - var/list/messages = list() - if(!user_or_client) - messages.Add("no user") - else if(ismob(user_or_client)) - var/mob/user = user_or_client - messages.Add("[user.ckey] (as [user])") - else if(isclient(user_or_client)) - var/client/client = user_or_client - messages.Add("[client.ckey]") - messages.Add(": [text]") - messages.Add("[GLOB.log_end]") - rustg_log_write(GLOB.tgui_log, messages.Join()) - -#ifdef REFERENCE_TRACKING -/proc/log_gc(text) - rustg_log_write(GLOB.gc_log, "[text][GLOB.log_end]") - for(var/client/C in GLOB.admins) - if(check_rights(R_DEBUG | R_VIEWRUNTIMES, FALSE, C.mob) && (C.prefs.toggles & PREFTOGGLE_CHAT_DEBUGLOGS)) - to_chat(C, "GC DEBUG: [text]") -#endif - -/proc/log_sql(text) - rustg_log_write(GLOB.sql_log, "[text][GLOB.log_end]") - SEND_TEXT(world.log, text) // Redirect it to DD too - -/proc/log_chat_debug(text) - rustg_log_write(GLOB.chat_debug_log, "[text][GLOB.log_end]") - -// A logging proc that only outputs after setup is done, to -// help devs test initialization stuff that happens a lot -/proc/log_after_setup(message) - if(SSticker && SSticker.current_state > GAME_STATE_SETTING_UP) - to_chat(world, "[message]") - log_world(message) - -/* For logging round startup. */ -/proc/start_log(log) - rustg_log_write(log, "Starting up. Round ID is [GLOB.round_id ? GLOB.round_id : "NULL"]\n-------------------------[GLOB.log_end]") - -// Helper procs for building detailed log lines - -/proc/datum_info_line(datum/d) - if(!istype(d)) - return - if(!ismob(d)) - return "[d] ([d.type])" - var/mob/m = d - return "[m] ([m.ckey]) ([m.type])" - -/proc/atom_loc_line(atom/a) - if(!istype(a)) - return - var/turf/t = get_turf(a) - if(istype(t)) - return "[a.loc] ([t.x],[t.y],[t.z]) ([a.loc.type])" - else if(a.loc) - return "[a.loc] (0,0,0) ([a.loc.type])" - -/mob/proc/simple_info_line() - return "[key_name(src)] ([x],[y],[z])" - -/client/proc/simple_info_line() - return "[key_name(src)] ([mob.x],[mob.y],[mob.z])" - -/proc/loc_name(atom/A) - if(!istype(A)) - return "(INVALID LOCATION)" - - var/turf/T = A - if(!istype(T)) - T = get_turf(A) - - if(istype(T)) - return "([AREACOORD(T)])" - else if(A.loc) - return "(UNKNOWN (?, ?, ?))" diff --git a/code/__HELPERS/atom_helpers.dm b/code/__HELPERS/atom_helpers.dm deleted file mode 100644 index b0a0999da72bf..0000000000000 --- a/code/__HELPERS/atom_helpers.dm +++ /dev/null @@ -1,10 +0,0 @@ -/// Returns a list of all locations (except the area) the movable is within. -/proc/get_nested_locs(atom/movable/atom_on_location, include_turf = FALSE) - . = list() - var/atom/location = atom_on_location.loc - var/turf/our_turf = get_turf(atom_on_location) - while(location && location != our_turf) - . += location - location = location.loc - if(our_turf && include_turf) // At this point, only the turf is left, provided it exists. - . += our_turf diff --git a/code/__HELPERS/radiation_helpers.dm b/code/__HELPERS/radiation_helpers.dm deleted file mode 100644 index 5626d5a6f6a32..0000000000000 --- a/code/__HELPERS/radiation_helpers.dm +++ /dev/null @@ -1,61 +0,0 @@ -/** - * A special GetAllContents that doesn't search past things with rad insulation - * Components which return COMPONENT_BLOCK_RADIATION prevent further searching into that object's contents. The object itself will get returned still. - * The ignore list makes those objects never return at all - */ -/proc/get_rad_contents(atom/location) - var/static/list/ignored_things = typecacheof(list( - /mob/dead, - /mob/camera, - /obj/effect, - /obj/docking_port, - /atom/movable/lighting_object, - /obj/item/projectile)) - var/list/processing_list = list(location) - . = list() - while(length(processing_list)) - var/atom/thing = processing_list[1] - processing_list -= thing - if(ignored_things[thing.type]) - continue - . += thing - if((thing.flags_2 & RAD_PROTECT_CONTENTS_2) || (SEND_SIGNAL(thing, COMSIG_ATOM_RAD_PROBE) & COMPONENT_BLOCK_RADIATION)) - continue - if(ishuman(thing)) - var/mob/living/carbon/human/H = thing - if(H.get_rad_protection() >= 0.99) // I would do exactly equal to 1, but you will never hit anything between 1 and .975, and byond seems to output 0.99999 - continue - processing_list += thing.contents - -/proc/radiation_pulse(atom/source, intensity, range_modifier, log = FALSE, can_contaminate = TRUE, source_radius = 0) - if(!SSradiation.can_fire) - return - for(var/dir in GLOB.cardinal) - new /datum/radiation_wave(source, dir, intensity, range_modifier, can_contaminate, source_radius) - - var/list/things = get_rad_contents(source) //copypasta because I don't want to put special code in waves to handle their origin - for(var/k in 1 to length(things)) - var/atom/thing = things[k] - if(!thing) - continue - thing.rad_act(intensity) - - var/static/last_huge_pulse = 0 - if(intensity > 3000 && world.time > last_huge_pulse + 200) - last_huge_pulse = world.time - log = TRUE - if(log) - var/turf/_source_T = isturf(source) ? source : get_turf(source) - log_game("Radiation pulse with intensity: [intensity] and range modifier: [range_modifier] in [loc_name(_source_T)] ") - return TRUE - -/proc/get_rad_contamination(atom/location) - var/rad_strength = 0 - for(var/i in get_rad_contents(location)) // Yes it's intentional that you can't detect radioactive things under rad protection. Gives traitors a way to hide their glowing green rocks. - var/atom/thing = i - if(!thing) - continue - var/datum/component/radioactive/radiation = thing.GetComponent(/datum/component/radioactive) - if(radiation && rad_strength < radiation.strength) - rad_strength = radiation.strength - return rad_strength diff --git a/code/__HELPERS/sorts/InsertSort.dm b/code/__HELPERS/sorts/InsertSort.dm deleted file mode 100644 index 81e347c8e6ca4..0000000000000 --- a/code/__HELPERS/sorts/InsertSort.dm +++ /dev/null @@ -1,19 +0,0 @@ -//simple insertion sort - generally faster than merge for runs of 7 or smaller -/proc/sortInsert(list/L, cmp = GLOBAL_PROC_REF(cmp_numeric_asc), associative, fromIndex = 1, toIndex = 0) - if(length(L) >= 2) - fromIndex = fromIndex % length(L) - toIndex = toIndex % (length(L) + 1) - if(fromIndex <= 0) - fromIndex += length(L) - if(toIndex <= 0) - toIndex += length(L) + 1 - - var/datum/sort_instance/SI = GLOB.sortInstance - if(!SI) - SI = new - SI.L = L - SI.cmp = cmp - SI.associative = associative - - SI.binarySort(fromIndex, toIndex, fromIndex) - return L diff --git a/code/__HELPERS/sorts/MergeSort.dm b/code/__HELPERS/sorts/MergeSort.dm deleted file mode 100644 index c558f41b2e1b2..0000000000000 --- a/code/__HELPERS/sorts/MergeSort.dm +++ /dev/null @@ -1,19 +0,0 @@ -//merge-sort - gernerally faster than insert sort, for runs of 7 or larger -/proc/sortMerge(list/L, cmp = GLOBAL_PROC_REF(cmp_numeric_asc), associative, fromIndex = 1, toIndex) - if(L && length(L) >= 2) - fromIndex = fromIndex % length(L) - toIndex = toIndex % (length(L) + 1) - if(fromIndex <= 0) - fromIndex += length(L) - if(toIndex <= 0) - toIndex += length(L) + 1 - - var/datum/sort_instance/SI = GLOB.sortInstance - if(!SI) - SI = new - SI.L = L - SI.cmp = cmp - SI.associative = associative - - SI.mergeSort(fromIndex, toIndex) - return L diff --git a/code/__HELPERS/sorts/TimSort.dm b/code/__HELPERS/sorts/TimSort.dm deleted file mode 100644 index cd15d922614bf..0000000000000 --- a/code/__HELPERS/sorts/TimSort.dm +++ /dev/null @@ -1,20 +0,0 @@ -//TimSort interface -/proc/sortTim(list/L, cmp = GLOBAL_PROC_REF(cmp_numeric_asc), associative, fromIndex = 1, toIndex = 0) - if(L && length(L) >= 2) - fromIndex = fromIndex % length(L) - toIndex = toIndex % (length(L) + 1) - if(fromIndex <= 0) - fromIndex += length(L) - if(toIndex <= 0) - toIndex += length(L) + 1 - - var/datum/sort_instance/SI = GLOB.sortInstance - if(!SI) - SI = new - - SI.L = L - SI.cmp = cmp - SI.associative = associative - - SI.timSort(fromIndex, toIndex) - return L diff --git a/code/__HELPERS/sorts/__main.dm b/code/__HELPERS/sorts/__main.dm deleted file mode 100644 index 3e44dc052d9d4..0000000000000 --- a/code/__HELPERS/sorts/__main.dm +++ /dev/null @@ -1,648 +0,0 @@ - //These are macros used to reduce on proc calls -#define fetchElement(L, i) (associative) ? L[L[i]] : L[i] - - //Minimum sized sequence that will be merged. Anything smaller than this will use binary-insertion sort. - //Should be a power of 2 -#define MIN_MERGE 32 - - //When we get into galloping mode, we stay there until both runs win less often than MIN_GALLOP consecutive times. -#define MIN_GALLOP 7 - -//This is a global instance to allow much of this code to be reused. The interfaces are kept separately -GLOBAL_DATUM_INIT(sortInstance, /datum/sort_instance, new()) -/datum/sort_instance - //The array being sorted. - var/list/L - - //The comparator proc-reference - var/cmp = /proc/cmp_numeric_asc - - //whether we are sorting list keys (0: L[i]) or associated values (1: L[L[i]]) - var/associative = 0 - - //This controls when we get *into* galloping mode. It is initialized to MIN_GALLOP. - //The mergeLo and mergeHi methods nudge it higher for random data, and lower for highly structured data. - var/minGallop = MIN_GALLOP - - //Stores information regarding runs yet to be merged. - //Run i starts at runBase[i] and extends for runLen[i] elements. - //runBase[i] + runLen[i] == runBase[i+1] - var/list/runBases = list() - var/list/runLens = list() - - -/datum/sort_instance/proc/timSort(start, end) - runBases.Cut() - runLens.Cut() - - var/remaining = end - start - - //If array is small, do a 'mini-TimSort' with no merges - if(remaining < MIN_MERGE) - var/initRunLen = countRunAndMakeAscending(start, end) - binarySort(start, end, start + initRunLen) - return - - //March over the array finding natural runs - //Extend any short natural runs to runs of length minRun - var/minRun = minRunLength(remaining) - - do - //identify next run - var/runLen = countRunAndMakeAscending(start, end) - - //if run is short, extend to min(minRun, remaining) - if(runLen < minRun) - var/force = (remaining <= minRun) ? remaining : minRun - - binarySort(start, start + force, start+runLen) - runLen = force - - //add data about run to queue - runBases.Add(start) - runLens.Add(runLen) - - //maybe merge - mergeCollapse() - - //Advance to find next run - start += runLen - remaining -= runLen - - while(remaining > 0) - - - //Merge all remaining runs to complete sort - //ASSERT(start == end) - mergeForceCollapse(); - //ASSERT(length(runBases) == 1) - - //reset minGallop, for successive calls - minGallop = MIN_GALLOP - - return L - -/* -Sorts the specified portion of the specified array using a binary -insertion sort. This is the best method for sorting small numbers -of elements. It requires O(n log n) compares, but O(n^2) data -movement (worst case). - -If the initial part of the specified range is already sorted, -this method can take advantage of it: the method assumes that the -elements in range [lo,start) are already sorted - -lo the index of the first element in the range to be sorted -hi the index after the last element in the range to be sorted -start the index of the first element in the range that is not already known to be sorted -*/ -/datum/sort_instance/proc/binarySort(lo, hi, start) - //ASSERT(lo <= start && start <= hi) - if(start <= lo) - start = lo + 1 - - for(,start < hi, ++start) - var/pivot = fetchElement(L,start) - - //set left and right to the index where pivot belongs - var/left = lo - var/right = start - //ASSERT(left <= right) - - //[lo, left) elements <= pivot < [right, start) elements - //in other words, find where the pivot element should go using bisection search - while(left < right) - var/mid = (left + right) >> 1 //round((left+right)/2) - if(call(cmp)(fetchElement(L, mid), pivot) > 0) - right = mid - else - left = mid + 1 - - //ASSERT(left == right) - moveElement(L, start, left) //move pivot element to correct location in the sorted range - -/* -Returns the length of the run beginning at the specified position and reverses the run if it is back-to-front - -A run is the longest ascending sequence with: - a[lo] <= a[lo + 1] <= a[lo + 2] <= ... -or the longest descending sequence with: - a[lo] > a[lo + 1] > a[lo + 2] > ... - -For its intended use in a stable mergesort, the strictness of the -definition of "descending" is needed so that the call can safely -reverse a descending sequence without violating stability. -*/ -/datum/sort_instance/proc/countRunAndMakeAscending(lo, hi) - //ASSERT(lo < hi) - - var/runHi = lo + 1 - if(runHi >= hi) - return 1 - - var/last = fetchElement(L, lo) - var/current = fetchElement(L, runHi++) - - if(call(cmp)(current, last) < 0) - while(runHi < hi) - last = current - current = fetchElement(L,runHi) - if(call(cmp)(current, last) >= 0) - break - ++runHi - reverseRange(L, lo, runHi) - else - while(runHi < hi) - last = current - current = fetchElement(L,runHi) - if(call(cmp)(current, last) < 0) - break - ++runHi - - return runHi - lo - -//Returns the minimum acceptable run length for an array of the specified length. -//Natural runs shorter than this will be extended with binarySort -/datum/sort_instance/proc/minRunLength(n) - //ASSERT(n >= 0) - var/r = 0 //becomes 1 if any bits are shifted off - while(n >= MIN_MERGE) - r |= (n & 1) - n >>= 1 - return n + r - -//Examines the stack of runs waiting to be merged and merges adjacent runs until the stack invariants are reestablished: -// runLen[i-3] > runLen[i-2] + runLen[i-1] -// runLen[i-2] > runLen[i-1] -//This method is called each time a new run is pushed onto the stack. -//So the invariants are guaranteed to hold for i= 2) - var/n = length(runBases) - 1 - if(n > 1 && runLens[n - 1] <= runLens[n] + runLens[n + 1]) - if(runLens[n - 1] < runLens[n + 1]) - --n - mergeAt(n) - else if(runLens[n] <= runLens[n + 1]) - mergeAt(n) - else - break //Invariant is established - - -//Merges all runs on the stack until only one remains. -//Called only once, to finalise the sort -/datum/sort_instance/proc/mergeForceCollapse() - while(length(runBases) >= 2) - var/n = length(runBases) - 1 - if(n > 1 && runLens[n - 1] < runLens[n + 1]) - --n - mergeAt(n) - - -//Merges the two consecutive runs at stack indices i and i+1 -//Run i must be the penultimate or antepenultimate run on the stack -//In other words, i must be equal to stackSize-2 or stackSize-3 -/datum/sort_instance/proc/mergeAt(i) - //ASSERT(length(runBases) >= 2) - //ASSERT(i >= 1) - //ASSERT(i == length(runBases) - 1 || i == length(runBases) - 2) - - var/base1 = runBases[i] - var/base2 = runBases[i + 1] - var/len1 = runLens[i] - var/len2 = runLens[i + 1] - - //ASSERT(len1 > 0 && len2 > 0) - //ASSERT(base1 + len1 == base2) - - //Record the legth of the combined runs. If i is the 3rd last run now, also slide over the last run - //(which isn't involved in this merge). The current run (i+1) goes away in any case. - runLens[i] += runLens[i + 1] - runLens.Cut(i + 1, i + 2) - runBases.Cut(i + 1, i + 2) - - - //Find where the first element of run2 goes in run1. - //Prior elements in run1 can be ignored (because they're already in place) - var/k = gallopRight(fetchElement(L, base2), base1, len1, 0) - //ASSERT(k >= 0) - base1 += k - len1 -= k - if(len1 == 0) - return - - //Find where the last element of run1 goes in run2. - //Subsequent elements in run2 can be ignored (because they're already in place) - len2 = gallopLeft(fetchElement(L, base1 + len1 - 1), base2, len2, len2 - 1) - //ASSERT(len2 >= 0) - if(len2 == 0) - return - - //Merge remaining runs, using tmp array with min(len1, len2) elements - if(len1 <= len2) - mergeLo(base1, len1, base2, len2) - else - mergeHi(base1, len1, base2, len2) - - -/* - Locates the position to insert key within the specified sorted range - If the range contains elements equal to key, this will return the index of the LEFTMOST of those elements - - key the element to be inserted into the sorted range - base the index of the first element of the sorted range - len the length of the sorted range, must be greater than 0 - hint the offset from base at which to begin the search, such that 0 <= hint < len; i.e. base <= hint < base+hint - - Returns the index at which to insert element 'key' -*/ -/datum/sort_instance/proc/gallopLeft(key, base, len, hint) - //ASSERT(len > 0 && hint >= 0 && hint < len) - - var/lastOffset = 0 - var/offset = 1 - if(call(cmp)(key, fetchElement(L,base + hint)) > 0) - var/maxOffset = len - hint - while(offset < maxOffset && call(cmp)(key, fetchElement(L, base + hint + offset)) > 0) - lastOffset = offset - offset = (offset << 1) + 1 - - if(offset > maxOffset) - offset = maxOffset - - lastOffset += hint - offset += hint - - else - var/maxOffset = hint + 1 - while(offset < maxOffset && call(cmp)(key, fetchElement(L, base + hint - offset)) <= 0) - lastOffset = offset - offset = (offset << 1) + 1 - - if(offset > maxOffset) - offset = maxOffset - - var/temp = lastOffset - lastOffset = hint - offset - offset = hint - temp - - //ASSERT(-1 <= lastOffset && lastOffset < offset && offset <= len) - - //Now L[base+lastOffset] < key <= L[base+offset], so key belongs somewhere to the right of lastOffset but no farther than - //offset. Do a binary search with invariant L[base+lastOffset-1] < key <= L[base+offset] - ++lastOffset - while(lastOffset < offset) - var/m = lastOffset + ((offset - lastOffset) >> 1) - - if(call(cmp)(key, fetchElement(L,base + m)) > 0) - lastOffset = m + 1 - else - offset = m - - //ASSERT(lastOffset == offset) - return offset - -/** - * Like gallopLeft, except that if the range contains an element equal to - * key, gallopRight returns the index after the rightmost equal element. - * - * Returns the int `k`, `0 <= k <= n` such that `a[b + k - 1] <= key < a[b + k]`. - * - * Arguments: - * - key: the key whose insertion point to search for - * - a: the array in which to search - * - base: the index of the first element in the range - * - len: the length of the range; must be > 0 - * - hint: the index at which to begin the search, `0 <= hint < n`. The closer hint is to the result, the faster this method will run. - * - c: the comparator used to order the range, and to search - */ -/datum/sort_instance/proc/gallopRight(key, base, len, hint) - //ASSERT(len > 0 && hint >= 0 && hint < len) - - var/offset = 1 - var/lastOffset = 0 - if(call(cmp)(key, fetchElement(L, base + hint)) < 0) //key <= L[base+hint] - var/maxOffset = hint + 1 //therefore we want to insert somewhere in the range [base,base+hint] = [base+,base+(hint+1)) - while(offset < maxOffset && call(cmp)(key, fetchElement(L, base + hint - offset)) < 0) //we are iterating backwards - lastOffset = offset - offset = (offset << 1) + 1 //1 3 7 15 - - if(offset > maxOffset) - offset = maxOffset - - var/temp = lastOffset - lastOffset = hint - offset - offset = hint - temp - - else //key > L[base+hint] - var/maxOffset = len - hint //therefore we want to insert somewhere in the range (base+hint,base+len) = [base+hint+1, base+hint+(len-hint)) - while(offset < maxOffset && call(cmp)(key, fetchElement(L, base + hint + offset)) >= 0) - lastOffset = offset - offset = (offset << 1) + 1 - - if(offset > maxOffset) - offset = maxOffset - - lastOffset += hint - offset += hint - - //ASSERT(-1 <= lastOffset && lastOffset < offset && offset <= len) - - ++lastOffset - while(lastOffset < offset) - var/m = lastOffset + ((offset - lastOffset) >> 1) - - if(call(cmp)(key, fetchElement(L, base + m)) < 0) //key <= L[base+m] - offset = m - else //key > L[base+m] - lastOffset = m + 1 - - //ASSERT(lastOffset == offset) - - return offset - - -//Merges two adjacent runs in-place in a stable fashion. -//For performance this method should only be called when len1 <= len2! -/datum/sort_instance/proc/mergeLo(base1, len1, base2, len2) - //ASSERT(len1 > 0 && len2 > 0 && base1 + len1 == base2) - - var/cursor1 = base1 - var/cursor2 = base2 - - //degenerate cases - if(len2 == 1) - moveElement(L, cursor2, cursor1) - return - - if(len1 == 1) - moveElement(L, cursor1, cursor2 + len2) - return - - - //Move first element of second run - moveElement(L, cursor2++, cursor1++) - --len2 - - outer: - while(1) - var/count1 = 0 //# of times in a row that first run won - var/count2 = 0 // " " " " " " second run won - - //do the straightfoward thin until one run starts winning consistently - - do - //ASSERT(len1 > 1 && len2 > 0) - if(call(cmp)(fetchElement(L, cursor2), fetchElement(L, cursor1)) < 0) - moveElement(L, cursor2++, cursor1++) - --len2 - - ++count2 - count1 = 0 - - if(len2 == 0) - break outer - else - ++cursor1 - - ++count1 - count2 = 0 - - if(--len1 == 1) - break outer - - while((count1 | count2) < minGallop) - - - //one run is winning consistently so galloping may provide huge benifits - //so try galloping, until such time as the run is no longer consistently winning - do - //ASSERT(len1 > 1 && len2 > 0) - - count1 = gallopRight(fetchElement(L, cursor2), cursor1, len1, 0) - if(count1) - cursor1 += count1 - len1 -= count1 - - if(len1 <= 1) - break outer - - moveElement(L, cursor2, cursor1) - ++cursor2 - ++cursor1 - if(--len2 == 0) - break outer - - count2 = gallopLeft(fetchElement(L, cursor1), cursor2, len2, 0) - if(count2) - moveRange(L, cursor2, cursor1, count2) - - cursor2 += count2 - cursor1 += count2 - len2 -= count2 - - if(len2 == 0) - break outer - - ++cursor1 - if(--len1 == 1) - break outer - - --minGallop - - while((count1|count2) > MIN_GALLOP) - - if(minGallop < 0) - minGallop = 0 - minGallop += 2; // Penalize for leaving gallop mode - - - if(len1 == 1) - //ASSERT(len2 > 0) - moveElement(L, cursor1, cursor2 + len2) - - //else - //ASSERT(len2 == 0) - //ASSERT(len1 > 1) - - -/datum/sort_instance/proc/mergeHi(base1, len1, base2, len2) - //ASSERT(len1 > 0 && len2 > 0 && base1 + len1 == base2) - - var/cursor1 = base1 + len1 - 1 //start at end of sublists - var/cursor2 = base2 + len2 - 1 - - //degenerate cases - if(len2 == 1) - moveElement(L, base2, base1) - return - - if(len1 == 1) - moveElement(L, base1, cursor2 + 1) - return - - moveElement(L, cursor1--, cursor2-- + 1) - --len1 - - outer: - while(1) - var/count1 = 0 //# of times in a row that first run won - var/count2 = 0 // " " " " " " second run won - - //do the straightfoward thing until one run starts winning consistently - do - //ASSERT(len1 > 0 && len2 > 1) - if(call(cmp)(fetchElement(L, cursor2), fetchElement(L, cursor1)) < 0) - moveElement(L, cursor1--, cursor2-- + 1) - --len1 - - ++count1 - count2 = 0 - - if(len1 == 0) - break outer - else - --cursor2 - --len2 - - ++count2 - count1 = 0 - - if(len2 == 1) - break outer - while((count1 | count2) < minGallop) - - //one run is winning consistently so galloping may provide huge benifits - //so try galloping, until such time as the run is no longer consistently winning - do - //ASSERT(len1 > 0 && len2 > 1) - - count1 = len1 - gallopRight(fetchElement(L, cursor2), base1, len1, len1 - 1) //should cursor1 be base1? - if(count1) - cursor1 -= count1 - - moveRange(L, cursor1 + 1, cursor2 + 1, count1) //cursor1+1 == cursor2 by definition - - cursor2 -= count1 - len1 -= count1 - - if(len1 == 0) - break outer - - --cursor2 - - if(--len2 == 1) - break outer - - count2 = len2 - gallopLeft(fetchElement(L, cursor1), cursor1 + 1, len2, len2 - 1) - if(count2) - cursor2 -= count2 - len2 -= count2 - - if(len2 <= 1) - break outer - - moveElement(L, cursor1--, cursor2-- + 1) - --len1 - - if(len1 == 0) - break outer - - --minGallop - while((count1|count2) > MIN_GALLOP) - - if(minGallop < 0) - minGallop = 0 - minGallop += 2 // Penalize for leaving gallop mode - - if(len2 == 1) - //ASSERT(len1 > 0) - - cursor1 -= len1 - moveRange(L, cursor1 + 1, cursor2 + 1, len1) - - //else - //ASSERT(len1 == 0) - //ASSERT(len2 > 0) - - -/datum/sort_instance/proc/mergeSort(start, end) - var/remaining = end - start - - //If array is small, do an insertion sort - if(remaining < MIN_MERGE) - binarySort(start, end, start/*+initRunLen*/) - return - - var/minRun = minRunLength(remaining) - - do - var/runLen = (remaining <= minRun) ? remaining : minRun - - binarySort(start, start + runLen, start) - - //add data about run to queue - runBases.Add(start) - runLens.Add(runLen) - - //Advance to find next run - start += runLen - remaining -= runLen - - while(remaining > 0) - - while(length(runBases) >= 2) - var/n = length(runBases) - 1 - if(n > 1 && runLens[n - 1] <= runLens[n] + runLens[n + 1]) - if(runLens[n - 1] < runLens[n + 1]) - --n - mergeAt2(n) - else if(runLens[n] <= runLens[n + 1]) - mergeAt2(n) - else - break //Invariant is established - - while(length(runBases) >= 2) - var/n = length(runBases) - 1 - if(n > 1 && runLens[n - 1] < runLens[n + 1]) - --n - mergeAt2(n) - - return L - -/datum/sort_instance/proc/mergeAt2(i) - var/cursor1 = runBases[i] - var/cursor2 = runBases[i + 1] - - var/end1 = cursor1+runLens[i] - var/end2 = cursor2+runLens[i + 1] - - var/val1 = fetchElement(L, cursor1) - var/val2 = fetchElement(L, cursor2) - - while(1) - if(call(cmp)(val1, val2) <= 0) - if(++cursor1 >= end1) - break - val1 = fetchElement(L, cursor1) - else - moveElement(L, cursor2, cursor1) - - if(++cursor2 >= end2) - break - ++end1 - ++cursor1 - - val2 = fetchElement(L, cursor2) - - - //Record the legth of the combined runs. If i is the 3rd last run now, also slide over the last run - //(which isn't involved in this merge). The current run (i+1) goes away in any case. - runLens[i] += runLens[i + 1] - runLens.Cut(i + 1, i + 2) - runBases.Cut(i + 1, i + 2) - -#undef MIN_GALLOP -#undef MIN_MERGE - -#undef fetchElement diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm deleted file mode 100644 index d42d688eed824..0000000000000 --- a/code/__HELPERS/text.dm +++ /dev/null @@ -1,774 +0,0 @@ -/* - * Holds procs designed to help with filtering text - * Contains groups: - * SQL sanitization - * Text sanitization - * Text searches - * Text modification - * Misc - */ - -/* - * Text sanitization - */ -// Can be used almost the same way as normal input for text -/proc/clean_input(Message, Title, Default, mob/user=usr) - var/txt = input(user, Message, Title, html_decode(Default)) as text | null - if(txt) - return html_encode(txt) - -//Simply removes < and > and limits the length of the message -/proc/strip_html_simple(t, limit=MAX_MESSAGE_LEN) - var/list/strip_chars = list("<",">") - t = copytext(t,1,limit) - for(var/char in strip_chars) - var/index = findtext(t, char) - while(index) - t = copytext(t, 1, index) + copytext(t, index+1) - index = findtext(t, char) - return t - -//Removes a few problematic characters -/proc/sanitize_simple(t, list/repl_chars = list("\n"="#","\t"="#")) - for(var/char in repl_chars) - t = replacetext(t, char, repl_chars[char]) - return t - -//Runs byond's sanitization proc along-side sanitize_simple -/proc/sanitize(t, list/repl_chars = null) - return html_encode(sanitize_simple(t,repl_chars)) - -/// sanitize() with a pre-set list of characters to remove from IC speech. -/proc/sanitize_for_ic(t) - return sanitize(t, list("<" = "", ">" = "", "\[" = "", "]" = "", "{" = "", "}" = "")) - -// Gut ANYTHING that isnt alphanumeric, or brackets -/proc/paranoid_sanitize(t) - var/regex/alphanum_only = regex("\[^a-zA-Z0-9# ,.?!:;()]", "g") - return alphanum_only.Replace(t, "#") - -// Less agressive, to allow discord features, such as <>, / and @ -/proc/not_as_paranoid_sanitize(t) - var/regex/alphanum_slashes_only = regex("\[^a-zA-Z0-9# ,.?!:;()/<>@]", "g") - return alphanum_slashes_only.Replace(t, "#") - -//Runs sanitize and strip_html_simple -//I believe strip_html_simple() is required to run first to prevent '<' from displaying as '<' after sanitize() calls byond's html_encode() -/proc/strip_html(t, limit=MAX_MESSAGE_LEN) - return copytext((sanitize(strip_html_simple(t))),1,limit) - -// Used to get a properly sanitized multiline input, of max_length -/proc/stripped_multiline_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) - var/name = input(user, message, title, html_decode(default)) as message|null - if(no_trim) - return copytext(html_encode(name), 1, max_length) - else - return trim(html_encode(name), max_length) - -//Runs byond's sanitization proc along-side strip_html_simple -//I believe strip_html_simple() is required to run first to prevent '<' from displaying as '<' that html_encode() would cause -/proc/adminscrub(t, limit=MAX_MESSAGE_LEN) - return copytext((html_encode(strip_html_simple(t))),1,limit) - - -//Returns null if there is any bad text in the string -/proc/reject_bad_text(text, max_length=512) - if(length_char(text) > max_length) return //message too long - var/non_whitespace = 0 - for(var/i=1, i<=length_char(text), i++) - switch(text2ascii_char(text,i)) - if(62,60,92,47) return //rejects the text if it contains these bad characters: <, >, \ or / - if(127 to 255) return //rejects weird letters like � - if(0 to 31) return //more weird stuff - if(32) continue //whitespace - else non_whitespace = 1 - if(non_whitespace) return text //only accepts the text if it has some non-spaces - -// Used to get a sanitized input. -/proc/stripped_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) - var/name = sanitize(input(user, message, title, html_decode(default)) as text|null) - if(!no_trim) - name = trim(name) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into <) - return copytext(name, 1, max_length) - -// Uses client.typing to check if the popup should appear or not -/proc/typing_input(mob/user, message = "", title = "", default = "") - var/client/C = user.client // Save it in a var in case the client disconnects from the mob - C.typing = TRUE - var/msg = input(user, message, title, html_decode(default)) as text|null - if(!C) - return null - C.typing = FALSE - if(!user || C != user.client) // User got out of the mob for some reason or the mob is gone - return null - return msg - -//Filters out undesirable characters from names -/proc/reject_bad_name(t_in, allow_numbers=0, max_length=MAX_NAME_LEN) - // Decode so that names with characters like < are still rejected - t_in = html_decode(t_in) - if(!t_in || length_char(t_in) > max_length) - return //Rejects the input if it is null or if it is longer than the max length allowed - - var/number_of_alphanumeric = 0 - var/last_char_group = 0 - var/t_out = "" - - for(var/i=1, i<=length_char(t_in), i++) - var/ascii_char = text2ascii_char(t_in,i) - switch(ascii_char) - // A .. Z, А .. Я, Ё - if(65 to 90, 1040 to 1071, 1025) //Uppercase Letters - t_out += ascii2text(ascii_char) - number_of_alphanumeric++ - last_char_group = 4 - - // a .. z, а .. я, ё - if(97 to 122, 1072 to 1103, 1105) //Lowercase Letters - if(last_char_group<2) t_out += uppertext(ascii2text(ascii_char)) //Force uppercase first character - else t_out += ascii2text(ascii_char) - number_of_alphanumeric++ - last_char_group = 4 - - // 0 .. 9 - if(48 to 57) //Numbers - if(!last_char_group) continue //suppress at start of string - if(!allow_numbers) continue - t_out += ascii2text(ascii_char) - number_of_alphanumeric++ - last_char_group = 3 - - // ' - . , - if(39, 45, 46, 44) //Common name punctuation - if(!last_char_group) continue - t_out += ascii2text(ascii_char) - last_char_group = 2 - - // ~ | @ : # $ % & * + ! - if(126, 124, 64, 58, 35, 36, 37, 38, 42, 43, 33) //Other symbols that we'll allow (mainly for AI) - if(!last_char_group) continue //suppress at start of string - if(!allow_numbers) continue - t_out += ascii2text(ascii_char) - last_char_group = 2 - - //Space - if(32) - if(last_char_group <= 1) continue //suppress double-spaces and spaces at start of string - t_out += ascii2text(ascii_char) - last_char_group = 1 - else - return - - if(number_of_alphanumeric < 2) return //protects against tiny names like "A" and also names like "' ' ' ' ' ' ' '" - - if(last_char_group == 1) - t_out = copytext(t_out,1,length(t_out)) //removes the last character (in this case a space) - - for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai","plating")) //prevents these common metagamey names - if(cmptext(t_out,bad_name)) return //(not case sensitive) - - return t_out - -//checks text for html tags -//if tag is not in whitelist (var/list/paper_tag_whitelist in global.dm) -//relpaces < with < -/proc/checkhtml(t) - t = sanitize_simple(t, list("&#"=".")) - var/p = findtext(t,"<",1) - while(p) //going through all the tags - var/start = p++ - var/tag = copytext(t,p, p+1) - if(tag != "/") - while(reject_bad_text(copytext(t, p, p+1), 1)) - tag = copytext(t,start, p) - p++ - tag = copytext(t,start+1, p) - if(!(tag in GLOB.paper_tag_whitelist)) //if it's unkown tag, disarming it - t = copytext(t,1,start-1) + "<" + copytext(t,start+1) - p = findtext(t,"<",p) - return t -/* - * Text searches - */ - -//Checks the beginning of a string for a specified sub-string -//Returns the position of the substring or 0 if it was not found -/proc/dd_hasprefix(text, prefix) - var/start = 1 - var/end = length(prefix) + 1 - return findtext_char(text, prefix, start, end) - -//Checks the beginning of a string for a specified sub-string. This proc is case sensitive -//Returns the position of the substring or 0 if it was not found -/proc/dd_hasprefix_case(text, prefix) - var/start = 1 - var/end = length(prefix) + 1 - return findtextEx_char(text, prefix, start, end) - -//Checks the end of a string for a specified substring. -//Returns the position of the substring or 0 if it was not found -/proc/dd_hassuffix(text, suffix) - var/start = length(text) - length(suffix) - if(start) - return findtext_char(text, suffix, start, null) - return - -//Checks the end of a string for a specified substring. This proc is case sensitive -//Returns the position of the substring or 0 if it was not found -/proc/dd_hassuffix_case(text, suffix) - var/start = length(text) - length(suffix) - if(start) - return findtextEx_char(text, suffix, start, null) - -/* - * Text modification - */ -// See bygex.dm -/proc/replace_characters(t, list/repl_chars) - for(var/char in repl_chars) - t = replacetext_char(t, char, repl_chars[char]) - return t - -//Strips the first char and returns it and the new string as a list -/proc/strip_first(t) - return list(copytext(t, 1, 2), copytext(t, 2, 0)) - -//Strips the last char and returns it and the new string as a list -/proc/strip_last(t) - return list(copytext(t, 1, length(t)), copytext(t, length(t))) - -//Adds 'u' number of zeros ahead of the text 't' -/proc/add_zero(t, u) - while(length(t) < u) - t = "0[t]" - return t - -//Adds 'u' number of spaces ahead of the text 't' -/proc/add_lspace(t, u) - while(length(t) < u) - t = " [t]" - return t - -//Adds 'u' number of spaces behind the text 't' -/proc/add_tspace(t, u) - while(length(t) < u) - t = "[t] " - return t - -//Returns a string with reserved characters and spaces before the first letter removed -/proc/trim_left(text) - for(var/i = 1 to length(text)) - if(text2ascii(text, i) > 32) - return copytext(text, i) - return "" - -//Returns a string with reserved characters and spaces after the last letter removed -/proc/trim_right(text) - for(var/i = length(text), i > 0, i--) - if(text2ascii(text, i) > 32) - return copytext(text, 1, i + 1) - - return "" - -//Returns a string with reserved characters and spaces before the first word and after the last word removed. -/proc/trim(text) - return trim_left(trim_right(text)) - -/// Returns a string that does not exceed max_length characters in size -/proc/trim_length(text, max_length) - return copytext_char(text, 1, max_length) - -//Returns a string with the first element of the string capitalized. -/proc/capitalize(t as text) - return uppertext(copytext_char(t, 1, 2)) + copytext_char(t, 2) - -//Centers text by adding spaces to either side of the string. -/proc/dd_centertext(message, length) - var/new_message = message - var/size = length(message) - var/delta = length - size - if(size == length) - return new_message - if(size > length) - return copytext(new_message, 1, length + 1) - if(delta == 1) - return new_message + " " - if(delta % 2) - new_message = " " + new_message - delta-- - var/spaces = add_lspace("",delta/2-1) - return spaces + new_message + spaces - -//Limits the length of the text. Note: MAX_MESSAGE_LEN and MAX_NAME_LEN are widely used for this purpose -/proc/dd_limittext(message, length) - var/size = length(message) - if(size <= length) - return message - return copytext(message, 1, length + 1) - - -/proc/stringmerge(text, compare,replace = "*") -//This proc fills in all spaces with the "replace" var (* by default) with whatever -//is in the other string at the same spot (assuming it is not a replace char). -//This is used for fingerprints - var/newtext = text - if(length(text) != length(compare)) - return 0 - for(var/i = 1, i < length(text), i++) - var/a = copytext(text,i,i+1) - var/b = copytext(compare,i,i+1) -//if it isn't both the same letter, or if they are both the replacement character -//(no way to know what it was supposed to be) - if(a != b) - if(a == replace) //if A is the replacement char - newtext = copytext(newtext,1,i) + b + copytext(newtext, i+1) - else if(b == replace) //if B is the replacement char - newtext = copytext(newtext,1,i) + a + copytext(newtext, i+1) - else //The lists disagree, Uh-oh! - return 0 - return newtext - -/proc/stringpercent(text, character = "*") -//This proc returns the number of chars of the string that is the character -//This is used for detective work to determine fingerprint completion. - if(!text || !character) - return 0 - var/count = 0 - for(var/i = 1, i <= length(text), i++) - var/a = copytext(text,i,i+1) - if(a == character) - count++ - return count - -/proc/reverse_text(text = "") - var/new_text = "" - for(var/i = length(text); i > 0; i--) - new_text += copytext(text, i, i+1) - return new_text - -/// Strips HTML tags (and only tags) from the input. -/// The result may still include HTML entities, like ' for ' -/proc/strip_html_tags(input, max_length = MAX_MESSAGE_LEN, allow_lines = 0) - if(!input) - return "" - var/static/regex/tags = regex("<\[^>]*>", "g") - if(!tags) - tags = regex("<\[^>]*>", "g") - input = tags.Replace(input, "") - if(max_length) - input = copytext_char(input, 1, max_length) - if(allow_lines) - return sanitize_simple(input, list("\t" = " ")) - return sanitize_simple(input, list("\n" = " ", "\t" = " ")) - -/proc/trim_strip_html_tags(input, max_length = MAX_MESSAGE_LEN, allow_lines = 0) - return trim(strip_html_tags(input, max_length, allow_lines)) - -//Used in preferences' SetFlavorText and human's set_flavor verb -//Previews a string of len or less length -/proc/TextPreview(string, len=40) - if(length(string) <= len) - if(!length(string)) - return "\[...\]" - else - return html_encode(string) //NO DECODED HTML YOU CHUCKLEFUCKS - else - return "[copytext_preserve_html(string, 1, 37)]..." - -//alternative copytext() for encoded text, doesn't break html entities (" and other) -/proc/copytext_preserve_html(text, first, last) - return html_encode(copytext(html_decode(text), first, last)) - -//Run sanitize(), but remove <, >, " first to prevent displaying them as > < &34; in some places, after html_encode(). -//Best used for sanitize object names, window titles. -//If you have a problem with sanitize() in chat, when quotes and >, < are displayed as html entites - -//this is a problem of double-encode(when & becomes &), use sanitize() with encode=0, but not the sanitizeSafe()! -/proc/sanitizeSafe(input, max_length = MAX_MESSAGE_LEN, encode = 1, trim = 1, extra = 1) - return sanitize(replace_characters(input, list(">"=" ","<"=" ", "\""="'")), max_length, encode, trim, extra) - - -//Replace BYOND text macros with span classes for to_chat -/proc/replace_text_macro(match, code, rest) - var/regex/text_macro = new("(\\xFF.)(.*)$") - return text_macro.Replace(rest, /proc/replace_text_macro) - -/proc/macro2html(text) - var/static/regex/text_macro = new("(\\xFF.)(.*)$") - return text_macro.Replace(text, /proc/replace_text_macro) - -/proc/dmm_encode(text) - // First, go through and nix out any of our escape sequences so we don't leave ourselves open to some escape sequence attack - // Some coder will probably despise me for this, years down the line - - var/list/repl_chars = list("#?qt;", "#?lbr;", "#?rbr;") - for(var/char in repl_chars) - var/index = findtext(text, char) - var/keylength = length(char) - while(index) - stack_trace("Bad string given to dmm encoder! [text]") - // Replace w/ underscore to prevent "{4;" from cheesing the radar - // Should probably also use canon text replacing procs - text = copytext(text, 1, index) + "_" + copytext(text, index+keylength) - index = findtext(text, char) - - // Then, replace characters as normal - var/list/repl_chars_2 = list("\"" = "#?qt;", "{" = "#?lbr;", "}" = "#?rbr;") - for(var/char in repl_chars_2) - var/index = findtext(text, char) - var/keylength = length(char) - while(index) - text = copytext(text, 1, index) + repl_chars_2[char] + copytext(text, index+keylength) - index = findtext(text, char) - return text - - -/proc/dmm_decode(text) - // Replace what we extracted above - var/list/repl_chars = list("#?qt;" = "\"", "#?lbr;" = "{", "#?rbr;" = "}") - for(var/char in repl_chars) - var/index = findtext(text, char) - var/keylength = length(char) - while(index) - text = copytext(text, 1, index) + repl_chars[char] + copytext(text, index+keylength) - index = findtext(text, char) - return text - -//Checks if any of a given list of needles is in the haystack -/proc/text_in_list(haystack, list/needle_list, start=1, end=0) - for(var/needle in needle_list) - if(findtext(haystack, needle, start, end)) - return 1 - return 0 - -//Like above, but case sensitive -/proc/text_in_list_case(haystack, list/needle_list, start=1, end=0) - for(var/needle in needle_list) - if(findtextEx(haystack, needle, start, end)) - return 1 - return 0 - - -// Pencode -/proc/pencode_to_html(text, mob/user, obj/item/pen/P = null, format = 1, sign = 1, fields = 1, deffont = PEN_FONT, signfont = SIGNFONT, crayonfont = CRAYON_FONT, no_font = FALSE) - text = replacetext(text, "\[b\]", "") - text = replacetext(text, "\[/b\]", "") - text = replacetext(text, "\[i\]", "") - text = replacetext(text, "\[/i\]", "") - text = replacetext(text, "\[u\]", "") - text = replacetext(text, "\[/u\]", "") - text = replacetext(text, "\[s\]", "") - text = replacetext(text, "\[/s\]", "") - if(findtext(text, "\[signfont\]") || findtext(text, "\[/signfont\]")) // Make sure the text is there before giving off an error - if(check_rights(R_EVENT)) - text = replacetext(text, "\[signfont\]", "") - text = replacetext(text, "\[/signfont\]", "") - if(sign) - if(istype(P, /obj/item/pen/chameleon)) // if we are using chameleon pen use fake name from the pen - var/obj/item/pen/chameleon/chameleon_pen = P - add_attack_logs(user, "paper", "Has signed paper as [chameleon_pen.forge_name]") - // small tip for a player if the left forge_name empty - text = replacetext(text, "\[sign\]", "[chameleon_pen.forge_name ? chameleon_pen.forge_name : "No name was provided"]") - else - text = replacetext(text, "\[sign\]", "[user ? user.real_name : "Anonymous"]") - if(fields) - text = replacetext(text, "\[field\]", "") - if(format) - text = replacetext(text, "\[h1\]", "

") - text = replacetext(text, "\[/h1\]", "

") - text = replacetext(text, "\[h2\]", "

") - text = replacetext(text, "\[/h2\]", "

") - text = replacetext(text, "\[h3\]", "

") - text = replacetext(text, "\[/h3\]", "

") - text = replacetext(text, "\n", "
") - text = replacetext(text, "\[center\]", "
") - text = replacetext(text, "\[/center\]", "
") - text = replacetext(text, "\[br\]", "
") - text = replacetext(text, "\[large\]", "") - text = replacetext(text, "\[/large\]", "") - - if(istype(P, /obj/item/toy/crayon) || !format) // If it is a crayon, and he still tries to use these, make them empty! - text = replacetext(text, "\[*\]", "") - text = replacetext(text, "\[hr\]", "") - text = replacetext(text, "\[small\]", "") - text = replacetext(text, "\[/small\]", "") - text = replacetext(text, "\[list\]", "") - text = replacetext(text, "\[/list\]", "") - text = replacetext(text, "\[table\]", "") - text = replacetext(text, "\[/table\]", "") - text = replacetext(text, "\[row\]", "") - text = replacetext(text, "\[cell\]", "") - text = replacetext(text, "\[logo\]", "") - text = replacetext(text, "\[syndielogo\]", "") - - if(istype(P, /obj/item/toy/crayon)) - text = "[text]" - else // They are using "not a crayon" - formatting is OK and such - text = replacetext(text, "\[*\]", "
  • ") - text = replacetext(text, "\[hr\]", "
    ") - text = replacetext(text, "\[small\]", "") - text = replacetext(text, "\[/small\]", "") - text = replacetext(text, "\[list\]", "") - text = replacetext(text, "\[table\]", "") - text = replacetext(text, "\[/table\]", "
    ") - text = replacetext(text, "\[grid\]", "") - text = replacetext(text, "\[/grid\]", "
    ") - text = replacetext(text, "\[row\]", "") - text = replacetext(text, "\[cell\]", "") - text = replacetext(text, "\[logo\]", "​") - text = replacetext(text, "\[syndielogo\]", "​") - text = replacetext(text, "\[time\]", "[station_time_timestamp()]") // TO DO - text = replacetext(text, "\[date\]", "[GLOB.current_date_string]") - text = replacetext(text, "\[station\]", "[SSmapping.map_datum.fluff_name]") - if(!no_font) - if(P) - text = "[text]" - else - text = "[text]" - - text = copytext(text, 1, MAX_PAPER_MESSAGE_LEN) - return text - -/proc/convert_pencode_arg(text, tag, arg) - arg = sanitize_simple(html_encode(arg), list("''"="","\""="", "?"="")) - // https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#rule-4---css-escape-and-strictly-validate-before-inserting-untrusted-data-into-html-style-property-values - var/list/style_attacks = list("javascript:", "expression", "byond:", "file:") - - for(var/style_attack in style_attacks) - if(findtext(arg, style_attack)) - // Do not attempt to render dangerous things - return text - - if(tag == "class") - return "" - - if(tag == "style") - return "" - - if(tag == "img") - var/list/img_props = splittext(arg, ";") - if(length(img_props) == 3) - return "" - if(length(img_props) == 2) - return "" - return "" - - return text - -/proc/admin_pencode_to_html() - var/text = pencode_to_html(arglist(args)) - var/regex/R = new(@"\[(.*?) (.*?)\]", "ge") - text = R.Replace(text, /proc/convert_pencode_arg) - - text = replacetext(text, "\[/class\]", "") - text = replacetext(text, "\[/style\]", "") - text = replacetext(text, "\[/img\]", "") - - return text - -/proc/html_to_pencode(text) - text = replacetext(text, "
    ", "\n") - text = replacetext(text, "
    ", "\[center\]") - text = replacetext(text, "
    ", "\[/center\]") - text = replacetext(text, "
    ", "\[br\]") - text = replacetext(text, "", "\[b\]") - text = replacetext(text, "", "\[/b\]") - text = replacetext(text, "", "\[i\]") - text = replacetext(text, "", "\[/i\]") - text = replacetext(text, "", "\[u\]") - text = replacetext(text, "", "\[/u\]") - text = replacetext(text, "", "\[large\]") - text = replacetext(text, "", "\[field\]") - - text = replacetext(text, "

    ", "\[h1\]") - text = replacetext(text, "

    ", "\[/h1\]") - text = replacetext(text, "

    ", "\[h2\]") - text = replacetext(text, "

    ", "\[/h2\]") - text = replacetext(text, "

    ", "\[h3\]") - text = replacetext(text, "

    ", "\[/h3\]") - - text = replacetext(text, "
  • ", "\[*\]") - text = replacetext(text, "
    ", "\[hr\]") - text = replacetext(text, "", "\[small\]") - text = replacetext(text, "
      ", "\[list\]") - text = replacetext(text, "
    ", "\[/list\]") - text = replacetext(text, "", "\[table\]") - text = replacetext(text, "
    ", "\[/table\]") - text = replacetext(text, "", "\[grid\]") - text = replacetext(text, "
    ", "\[/grid\]") - text = replacetext(text, "", "\[row\]") - text = replacetext(text, "", "\[cell\]") - text = replacetext(text, "", "\[logo\]") - text = replacetext(text, "", "\[syndielogo\]") - return text - -/datum/html_split_holder - var/list/opening - var/inner_text - var/list/closing - -/datum/html_split_holder/New() - opening = list() - inner_text = "" - closing = list() - -/proc/split_html(raw_text="") - // gently borrowed and re-purposed from code/modules/pda/utilities.dm - // define a datum to hold our result - var/datum/html_split_holder/s = new() - - // copy the raw_text to get started - var/text = copytext_char(raw_text, 1) - - // search for tag brackets - var/tag_start = findtext_char(text, "<") - var/tag_stop = findtext_char(text, ">") - - // until we run out of opening tags - while((tag_start != 0) && (tag_stop != 0)) - // if the tag isn't at the beginning of the string - if(tag_start > 1) - // we've found our text, so copy it out - s.inner_text = copytext_char(text, 1, tag_start) - // and chop the text for the next round - text = copytext_char(text, tag_start) - break - // otherwise, we found an opening tag, so add it to the list - var/tag = copytext_char(text, tag_start, tag_stop+1) - s.opening.Add(tag) - // and chop the text for the next round - text = copytext_char(text, tag_stop+1) - // look for the next tag in what's left - tag_start = findtext(text, "<") - tag_stop = findtext(text, ">") - - // search for tag brackets - tag_start = findtext(text, "<") - tag_stop = findtext(text, ">") - - // until we run out of closing tags - while((tag_start != 0) && (tag_stop != 0)) - // we found a closing tag, so add it to the list - var/tag = copytext_char(text, tag_start, tag_stop+1) - s.closing.Add(tag) - // and chop the text for the next round - text = copytext_char(text, tag_stop+1) - // look for the next tag in what's left - tag_start = findtext(text, "<") - tag_stop = findtext(text, ">") - - // return the split html object to the caller - return s - -//Used for applying byonds text macros to strings that are loaded at runtime -/proc/apply_text_macros(string) - var/next_backslash = findtext(string, "\\") - if(!next_backslash) - return string - - var/leng = length(string) - - var/next_space = findtext(string, " ", next_backslash + length(string[next_backslash])) - if(!next_space) - next_space = leng - next_backslash - - if(!next_space) //trailing bs - return string - - var/base = next_backslash == 1 ? "" : copytext(string, 1, next_backslash) - var/macro = lowertext(copytext(string, next_backslash + length(string[next_backslash]), next_space)) - var/rest = next_backslash > leng ? "" : copytext(string, next_space + length(string[next_space])) - - //See https://secure.byond.com/docs/ref/info.html#/DM/text/macros - switch(macro) - //prefixes/agnostic - if("the") - rest = "\the [rest]" - if("a") - rest = "\a [rest]" - if("an") - rest = "\an [rest]" - if("proper") - rest = "\proper [rest]" - if("improper") - rest = "\improper [rest]" - if("roman") - rest = "\roman [rest]" - //postfixes - if("th") - base = "[rest]\th" - if("s") - base = "[rest]\s" - if("he") - base = "[rest]\he" - if("she") - base = "[rest]\she" - if("his") - base = "[rest]\his" - if("himself") - base = "[rest]\himself" - if("herself") - base = "[rest]\herself" - if("hers") - base = "[rest]\hers" - - . = base - if(rest) - . += .(rest) - -/** - * Proc to generate a "rank colour" from a client - * - * This takes the client and looks at various factors in order, such as patreon status, staff rank, and more - * Arguments: - * * C - The client were looking up - */ -/proc/client2rankcolour(client/C) - // First check if end user is an admin - if(C.holder) - if(C.holder.rank in GLOB.configuration.admin.rank_colour_map) - // Return their rank colour if they are in here - return GLOB.configuration.admin.rank_colour_map[C.holder.rank] - - // If they arent an admin, see if they are a patreon. Just accept any level - if(C.donator_level) - return "#e67e22" // Patreon orange - return null - - -/proc/starts_with_vowel(text) - var/start_char = copytext(text, 1, 2) - switch(lowertext(start_char)) - if("a", "e", "i", "o", "u") - return TRUE - else - return FALSE - -/** - * Formats num with an SI prefix. - * - * Returns a string formatted with a multiple of num and an SI prefix corresponding to an exponent of 10. - * Only considers exponents that are multiples of 3 (deca, deci, hecto, and centi are not included). - * A unit is not included in the string, the prefix is placed after the number with no spacing added anywhere. - * Listing of prefixes: https://en.wikipedia.org/wiki/Metric_prefix#List_of_SI_prefixes - */ -/proc/format_si_suffix(num) - if(num == 0) - return "[num]" - - var/exponent = round_down(log(10, abs(num))) - var/ofthree = exponent / 3 - if(exponent < 0) - ofthree = round(ofthree) - else - ofthree = round_down(ofthree) - if(ofthree == 0) - return "[num]" - return "[num / (10 ** (ofthree * 3))][GLOB.si_suffixes[round(length(GLOB.si_suffixes) / 2) + ofthree + 1]]" - -/** - * Creates a hyperlink for a specified wiki article. - */ -/proc/wiki_link(article_name, link_text = null) - var/url = "[GLOB.configuration.url.wiki_url]/index.php?title=[article_name]" - return "[link_text ? link_text : url]" diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm deleted file mode 100644 index 195112118952a..0000000000000 --- a/code/__HELPERS/type2type.dm +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Holds procs designed to change one type of value, into another. - * Contains: - * file2list - * angle2dir - * angle2text - * worldtime2text - */ - -//Returns an integer value for R of R/G/B given a hex color input. -/proc/color2R(hex) - if(!(istext(hex))) - return - - return hex2num(copytext(hex, 2, 4)) //Returning R - -//Returns an integer value for G of R/G/B given a hex color input. -/proc/color2G(hex) - if(!(istext(hex))) - return - - return hex2num(copytext(hex, 4, 6)) //Returning G - -//Returns an integer value for B of R/G/B given a hex color input. -/proc/color2B(hex) - if(!(istext(hex))) - return - - return hex2num(copytext(hex, 6, 8)) //Returning B - -/proc/text2numlist(text, delimiter="\n") - var/list/num_list = list() - for(var/x in splittext(text, delimiter)) - num_list += text2num(x) - return num_list - -//Splits the text of a file at seperator and returns them in a list. -/proc/file2list(filename, separator = "\n", no_empty = TRUE) - var/list/result = list() - for(var/line in splittext(return_file_text(filename), separator)) - var/text = trim(line) - if(no_empty && !text) - continue - result += text - return result - -/proc/dir2text(direction) - switch(direction) - if(1.0) - return "north" - if(2.0) - return "south" - if(4.0) - return "east" - if(8.0) - return "west" - if(5.0) - return "northeast" - if(6.0) - return "southeast" - if(9.0) - return "northwest" - if(10.0) - return "southwest" - -//Turns text into proper directions -/proc/text2dir(direction) - switch(uppertext(direction)) - if("NORTH") - return 1 - if("SOUTH") - return 2 - if("EAST") - return 4 - if("WEST") - return 8 - if("NORTHEAST") - return 5 - if("NORTHWEST") - return 9 - if("SOUTHEAST") - return 6 - if("SOUTHWEST") - return 10 - -//Converts an angle (degrees) into an ss13 direction -/proc/angle2dir(degree) - degree = (degree + 22.5) % 360 - if(degree < 45) return NORTH - if(degree < 90) return NORTHEAST - if(degree < 135) return EAST - if(degree < 180) return SOUTHEAST - if(degree < 225) return SOUTH - if(degree < 270) return SOUTHWEST - if(degree < 315) return WEST - return NORTH|WEST - -/proc/angle2dir_cardinal(angle) - switch(round(angle, 0.1)) - if(315.5 to 360, 0 to 45.5) - return NORTH - if(45.6 to 135.5) - return EAST - if(135.6 to 225.5) - return SOUTH - if(225.6 to 315.5) - return WEST - -//returns the north-zero clockwise angle in degrees, given a direction - -/proc/dir2angle(D) - switch(D) - if(NORTH) return 0 - if(SOUTH) return 180 - if(EAST) return 90 - if(WEST) return 270 - if(NORTHEAST) return 45 - if(SOUTHEAST) return 135 - if(NORTHWEST) return 315 - if(SOUTHWEST) return 225 - else return null - -//Returns the angle in english -/proc/angle2text(degree) - return dir2text(angle2dir(degree)) - -//Converts a blend_mode constant to one acceptable to icon.Blend() -/proc/blendMode2iconMode(blend_mode) - switch(blend_mode) - if(BLEND_MULTIPLY) return ICON_MULTIPLY - if(BLEND_ADD) return ICON_ADD - if(BLEND_SUBTRACT) return ICON_SUBTRACT - else return ICON_OVERLAY - -//Converts a rights bitfield into a string -/proc/rights2text(rights,seperator="") - if(rights & R_BUILDMODE) . += "[seperator]+BUILDMODE" - if(rights & R_ADMIN) . += "[seperator]+ADMIN" - if(rights & R_BAN) . += "[seperator]+BAN" - if(rights & R_EVENT) . += "[seperator]+EVENT" - if(rights & R_SERVER) . += "[seperator]+SERVER" - if(rights & R_DEBUG) . += "[seperator]+DEBUG" - if(rights & R_POSSESS) . += "[seperator]+POSSESS" - if(rights & R_PERMISSIONS) . += "[seperator]+PERMISSIONS" - if(rights & R_STEALTH) . += "[seperator]+STEALTH" - if(rights & R_REJUVINATE) . += "[seperator]+REJUVINATE" - if(rights & R_VAREDIT) . += "[seperator]+VAREDIT" - if(rights & R_SOUNDS) . += "[seperator]+SOUND" - if(rights & R_SPAWN) . += "[seperator]+SPAWN" - if(rights & R_PROCCALL) . += "[seperator]+PROCCALL" - if(rights & R_MOD) . += "[seperator]+MODERATOR" - if(rights & R_MENTOR) . += "[seperator]+MENTOR" - if(rights & R_VIEWRUNTIMES) . += "[seperator]+VIEWRUNTIMES" - if(rights & R_MAINTAINER) . += "[seperator]+MAINTAINER" - if(rights & R_DEV_TEAM) . += "[seperator]+DEV_TEAM" - -/proc/ui_style2icon(ui_style) - switch(ui_style) - if("Retro") - return 'icons/mob/screen_retro.dmi' - if("Plasmafire") - return 'icons/mob/screen_plasmafire.dmi' - if("Slimecore") - return 'icons/mob/screen_slimecore.dmi' - if("Operative") - return 'icons/mob/screen_operative.dmi' - if("White") - return 'icons/mob/screen_white.dmi' - if("Midnight") - return 'icons/mob/screen_midnight.dmi' - else - return 'icons/mob/screen_midnight.dmi' - -//colour formats -/proc/rgb2hsl(red, green, blue) - red /= 255;green /= 255;blue /= 255; - var/max = max(red,green,blue) - var/min = min(red,green,blue) - var/range = max-min - - var/hue=0;var/saturation=0;var/lightness=0; - lightness = (max + min)/2 - if(range != 0) - if(lightness < 0.5) saturation = range/(max+min) - else saturation = range/(2-max-min) - - var/dred = ((max-red)/(6*max)) + 0.5 - var/dgreen = ((max-green)/(6*max)) + 0.5 - var/dblue = ((max-blue)/(6*max)) + 0.5 - - if(max==red) hue = dblue - dgreen - else if(max==green) hue = dred - dblue + (1/3) - else hue = dgreen - dred + (2/3) - if(hue < 0) hue++ - else if(hue > 1) hue-- - - return list(hue, saturation, lightness) - -/proc/hsl2rgb(hue, saturation, lightness) - var/red;var/green;var/blue; - if(saturation == 0) - red = lightness * 255 - green = red - blue = red - else - var/a;var/b; - if(lightness < 0.5) b = lightness*(1+saturation) - else b = (lightness+saturation) - (saturation*lightness) - a = 2*lightness - b - - red = round(255 * hue2rgb(a, b, hue+(1/3))) - green = round(255 * hue2rgb(a, b, hue)) - blue = round(255 * hue2rgb(a, b, hue-(1/3))) - - return list(red, green, blue) - -/proc/hue2rgb(a, b, hue) - if(hue < 0) hue++ - else if(hue > 1) hue-- - if(6*hue < 1) return (a+(b-a)*6*hue) - if(2*hue < 1) return b - if(3*hue < 2) return (a+(b-a)*((2/3)-hue)*6) - return a - -/proc/num2septext(theNum, sigFig = 7, sep=",") // default sigFig (1,000,000) - var/finalNum = num2text(theNum, sigFig) - - // Start from the end, or from the decimal point - var/end = findtextEx(finalNum, ".") || length(finalNum) + 1 - - // Moving towards start of string, insert comma every 3 characters - for(var/pos = end - 3, pos > 1, pos -= 3) - finalNum = copytext(finalNum, 1, pos) + sep + copytext(finalNum, pos) - - return finalNum - - -// heat2color functions. Adapted from: http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ -/proc/heat2color(temp) - return rgb(heat2color_r(temp), heat2color_g(temp), heat2color_b(temp)) - -/proc/heat2color_r(temp) - temp /= 100 - if(temp <= 66) - . = 255 - else - . = max(0, min(255, 329.698727446 * (temp - 60) ** -0.1332047592)) - -/proc/heat2color_g(temp) - temp /= 100 - if(temp <= 66) - . = max(0, min(255, 99.4708025861 * log(max(temp, 1)) - 161.1195681661)) - else - . = max(0, min(255, 288.1221695283 * ((temp - 60) ** -0.0755148492))) - -/proc/heat2color_b(temp) - temp /= 100 - if(temp >= 66) - . = 255 - else - if(temp <= 16) - . = 0 - else - . = max(0, min(255, 138.5177312231 * log(max(temp - 10, 1)) - 305.0447927307)) - -//Argument: Give this a space-separated string consisting of 6 numbers. Returns null if you don't -/proc/text2matrix(matrixtext) - var/list/matrixtext_list = splittext(matrixtext, " ") - var/list/matrix_list = list() - for(var/item in matrixtext_list) - var/entry = text2num(item) - if(entry == null) - return null - matrix_list += entry - if(length(matrix_list) < 6) - return null - var/a = matrix_list[1] - var/b = matrix_list[2] - var/c = matrix_list[3] - var/d = matrix_list[4] - var/e = matrix_list[5] - var/f = matrix_list[6] - return matrix(a, b, c, d, e, f) - - -//This is a weird one: -//It returns a list of all var names found in the string -//These vars must be in the [var_name] format -//It's only a proc because it's used in more than one place - -//Takes a string and a datum -//The string is well, obviously the string being checked -//The datum is used as a source for var names, to check validity -//Otherwise every single word could technically be a variable! -/proc/string2listofvars(t_string, datum/var_source) - if(!t_string || !var_source) - return list() - - . = list() - - var/var_found = findtext(t_string, "\[") //Not the actual variables, just a generic "should we even bother" check - if(var_found) - //Find var names - - // "A dog said hi [name]!" - // splittext() --> list("A dog said hi ","name]!" - // jointext() --> "A dog said hi name]!" - // splittext() --> list("A","dog","said","hi","name]!") - - t_string = replacetext(t_string, "\[", "\[ ")//Necessary to resolve "word[var_name]" scenarios - var/list/list_value = splittext(t_string, "\[") - var/intermediate_stage = jointext(list_value, null) - - list_value = splittext(intermediate_stage, " ") - for(var/value in list_value) - if(findtext(value, "]")) - value = splittext(value, "]") //"name]!" --> list("name","!") - for(var/A in value) - if(var_source.vars.Find(A)) - . += A - -/proc/type2parent(child) - var/string_type = "[child]" - var/last_slash = findlasttext(string_type, "/") - if(last_slash == 1) - switch(child) - if(/datum) - return null - if(/obj, /mob) - return /atom/movable - if(/area, /turf) - return /atom - else - return /datum - return text2path(copytext(string_type, 1, last_slash)) - -/proc/text2bool(input) - if(input == "true") - return TRUE - return FALSE // diff --git a/code/_compile_options.dm b/code/_compile_options.dm deleted file mode 100644 index 0990e5bd29c63..0000000000000 --- a/code/_compile_options.dm +++ /dev/null @@ -1,48 +0,0 @@ -#define DEBUG -//#define TESTING - -// Uncomment the following line to compile unit tests on a local server. The output will be in a test_run-[DATE].log file in the ./data folder. -// #define LOCAL_GAME_TESTS - -// Uncomment the following line to enable Tracy profiling. -// DO NOT DO THIS UNLESS YOU UNDERSTAND THE IMPLICATIONS -// Your data directory will grow by about a gigabyte every time you launch the server, as well as introducing potential instabilities over multiple BYOND versions. -// #define ENABLE_BYOND_TRACY - -// Uncomment this to enable support for multiple instances -// #define MULTIINSTANCE - -#ifdef LOCAL_GAME_TESTS -#define GAME_TESTS -#endif - -#ifdef CIBUILDING -#define GAME_TESTS -#endif - -#if defined(CIBUILDING) && defined(LOCAL_GAME_TESTS) -#error CIBUILDING and LOCAL_GAME_TESTS should not be enabled at the same time! -#endif - -/***** All toggles for the GC ref finder *****/ - -// #define REFERENCE_TRACKING // Uncomment to enable ref finding - -// #define GC_FAILURE_HARD_LOOKUP //makes paths that fail to GC call find_references before del'ing. - -// #define FIND_REF_NO_CHECK_TICK //Sets world.loop_checks to false and prevents find references from sleeping - -// #define FIND_REF_NOTIFY_ON_COMPLETE // Throw a windows notification toast when the ref finding process is done - -/***** End toggles for the GC ref finder *****/ - -#define IS_MODE_COMPILED(MODE) (ispath(text2path("/datum/game_mode/"+(MODE)))) - -//Update this whenever you need to take advantage of more recent byond features -#define MIN_COMPILER_VERSION 515 -#define MIN_COMPILER_BUILD 1619 -#if DM_VERSION < MIN_COMPILER_VERSION || DM_BUILD < MIN_COMPILER_BUILD -//Don't forget to update this part -#error Your version of BYOND is too out-of-date to compile this project. Go to secure.byond.com/download and update. -#error You need version 515.1619 or higher -#endif diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm deleted file mode 100644 index e165eabdb7059..0000000000000 --- a/code/_globalvars/bitfields.dm +++ /dev/null @@ -1,216 +0,0 @@ -GLOBAL_LIST_INIT(bitfields, generate_bitfields()) - -/// 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 - -/datum/bitfield/can_vv_delete() - return FALSE - -/datum/bitfield/vv_edit_var(var_name, var_value) - return FALSE // no. - -/// 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 - -/proc/translate_bitfield(variable_type, variable_name, variable_value) - if(variable_type != VV_BITFIELD) - return variable_value - - var/list/flags = list() - for(var/flag in GLOB.bitfields[variable_name]) - if(variable_value & GLOB.bitfields[variable_name][flag]) - flags += flag - if(length(flags)) - return jointext(flags, ", ") - return "NONE" - -/proc/input_bitfield(mob/user, bitfield, current_value) - if(!user || !(bitfield in GLOB.bitfields)) - return - var/list/currently_checked = list() - for(var/name in GLOB.bitfields[bitfield]) - currently_checked[name] = (current_value & GLOB.bitfields[bitfield][name]) - - var/list/result = tgui_input_checkbox_list(user, "Editing bitfield for [bitfield].", "Editing bitfield", currently_checked) - if(isnull(result) || !islist(result)) - return - - var/new_result = 0 - for(var/name in GLOB.bitfields[bitfield]) - if(result[name]) - new_result |= GLOB.bitfields[bitfield][name] - return new_result - -// MARK: Default byond bitfields - -DEFINE_BITFIELD(appearance_flags, list( - "KEEP_APART" = KEEP_APART, - "KEEP_TOGETHER" = KEEP_TOGETHER, - "LONG_GLIDE" = LONG_GLIDE, - "NO_CLIENT_COLOR" = NO_CLIENT_COLOR, - "PIXEL_SCALE" = PIXEL_SCALE, - "PLANE_MASTER" = PLANE_MASTER, - "RESET_ALPHA" = RESET_ALPHA, - "RESET_COLOR" = RESET_COLOR, - "RESET_TRANSFORM" = RESET_TRANSFORM, - "TILE_BOUND" = TILE_BOUND, - "PASS_MOUSE" = PASS_MOUSE, - "TILE_MOVER" = TILE_MOVER, -)) - -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(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, -)) - - -// MARK: Other bitfields - -DEFINE_BITFIELD(flags, list( - "STOPSPRESSUREDMAGE" = STOPSPRESSUREDMAGE, - "NODROP" = NODROP, - "NOBLUDGEON" = NOBLUDGEON, - "AIRTIGHT" = AIRTIGHT, - "HANDSLOW" = HANDSLOW, - "CONDUCT" = CONDUCT, - "ABSTRACT" = ABSTRACT, - "ON_BORDER" = ON_BORDER, - "PREVENT_CLICK_UNDER" = PREVENT_CLICK_UNDER, - "NODECONSTRUCT" = NODECONSTRUCT, - "EARBANGPROTECT" = EARBANGPROTECT, - "HEADBANGPROTECT" = HEADBANGPROTECT, - "BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT, - "THICKMATERIAL" = THICKMATERIAL, - "DROPDEL" = DROPDEL, - "NO_SCREENTIPS" = NO_SCREENTIPS, -)) - -DEFINE_BITFIELD(flags_2, list( - "SLOWS_WHILE_IN_HAND_2" = SLOWS_WHILE_IN_HAND_2, - "NO_EMP_WIRES_2" = NO_EMP_WIRES_2, - "HOLOGRAM_2" = HOLOGRAM_2, - "FROZEN_2" = FROZEN_2, - "STATIONLOVING_2" = STATIONLOVING_2, - "INFORM_ADMINS_ON_RELOCATE_2" = INFORM_ADMINS_ON_RELOCATE_2, - "BANG_PROTECT_2" = BANG_PROTECT_2, - "BLOCKS_LIGHT_2" = BLOCKS_LIGHT_2, - "DECAL_INIT_UPDATE_EXPERIENCED_2" = DECAL_INIT_UPDATE_EXPERIENCED_2, - "OMNITONGUE_2" = OMNITONGUE_2, - "SHOCKED_2" = SHOCKED_2, - "NO_MAT_REDEMPTION_2" = NO_MAT_REDEMPTION_2, - "LAVA_PROTECT_2" = LAVA_PROTECT_2, - "OVERLAY_QUEUED_2" = OVERLAY_QUEUED_2, - "RAD_PROTECT_CONTENTS_2" = RAD_PROTECT_CONTENTS_2, - "RAD_NO_CONTAMINATE_2" = RAD_NO_CONTAMINATE_2, - "IMMUNE_TO_SHUTTLECRUSH_2" = IMMUNE_TO_SHUTTLECRUSH_2, - "NO_MALF_EFFECT_2" = NO_MALF_EFFECT_2, - "CRITICAL_ATOM_2" = CRITICAL_ATOM_2, - "RANDOM_BLOCKER_2" = RANDOM_BLOCKER_2, - "ALLOW_BELT_NO_JUMPSUIT_2" = ALLOW_BELT_NO_JUMPSUIT_2, -)) - -DEFINE_BITFIELD(flags_ricochet, list( - "RICOCHET_SHINY" = RICOCHET_SHINY, - "RICOCHET_HARD" = RICOCHET_HARD, -)) - -DEFINE_BITFIELD(clothing_flags, list( - "HAS_UNDERWEAR" = HAS_UNDERWEAR, - "HAS_UNDERSHIRT" = HAS_UNDERSHIRT, - "HAS_SOCKS" = HAS_SOCKS, -)) - -DEFINE_BITFIELD(bodyflags, list( - "HAS_HEAD_ACCESSORY" = HAS_HEAD_ACCESSORY, - "HAS_TAIL" = HAS_TAIL, - "TAIL_OVERLAPPED" = TAIL_OVERLAPPED, - "HAS_SKIN_TONE" = HAS_SKIN_TONE, - "HAS_ICON_SKIN_TONE" = HAS_ICON_SKIN_TONE, - "HAS_SKIN_COLOR" = HAS_SKIN_COLOR, - "HAS_HEAD_MARKINGS" = HAS_HEAD_MARKINGS, - "HAS_BODY_MARKINGS" = HAS_BODY_MARKINGS, - "HAS_TAIL_MARKINGS" = HAS_TAIL_MARKINGS, - "TAIL_WAGGING" = TAIL_WAGGING, - "NO_EYES" = NO_EYES, - "HAS_ALT_HEADS" = HAS_ALT_HEADS, - "HAS_WING" = HAS_WING, - "HAS_BODYACC_COLOR" = HAS_BODYACC_COLOR, - "BALD" = BALD, - "ALL_RPARTS" = ALL_RPARTS, - "SHAVED" = SHAVED, -)) - -DEFINE_BITFIELD(pass_flags, list( - "PASSTABLE" = PASSTABLE, - "PASSGLASS" = PASSGLASS, - "PASSGRILLE" = PASSGRILLE, - "PASSBLOB" = PASSBLOB, - "PASSMOB" = PASSMOB, - "LETPASSTHROW" = LETPASSTHROW, - "PASSFENCE" = PASSFENCE, - "PASSDOOR" = PASSDOOR, - "PASSGIRDER" = PASSGIRDER, - "PASSBARRICADE" = PASSBARRICADE, - "PASSTAKE" = PASSTAKE, -)) - -DEFINE_BITFIELD(pass_flags_self, list( - "PASSTAKE" = PASSTAKE, - "LETPASSTHROW" = LETPASSTHROW, -)) - -DEFINE_BITFIELD(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, -)) - -DEFINE_BITFIELD(mobility_flags, list( - "MOBILITY_MOVE" = MOBILITY_MOVE, - "MOBILITY_STAND" = MOBILITY_STAND, - "MOBILITY_PICKUP" = MOBILITY_PICKUP, - "MOBILITY_USE" = MOBILITY_USE, - "MOBILITY_PULL" = MOBILITY_PULL, -)) - -DEFINE_BITFIELD(status_flags, list( - "CANSTUN" = CANSTUN, - "CANWEAKEN" = CANWEAKEN, - "CANPARALYSE" = CANPARALYSE, - "CANPUSH" = CANPUSH, - "PASSEMOTES" = PASSEMOTES, - "GODMODE" = GODMODE, - "TERMINATOR_FORM" = TERMINATOR_FORM, -)) diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm deleted file mode 100644 index 71b013826a794..0000000000000 --- a/code/_globalvars/lists/flavor_misc.dm +++ /dev/null @@ -1,92 +0,0 @@ -//Preferences stuff - //Head accessory styles -GLOBAL_LIST_EMPTY(head_accessory_styles_list) //stores /datum/sprite_accessory/head_accessory indexed by name - //Marking styles -GLOBAL_LIST_EMPTY(marking_styles_list) //stores /datum/sprite_accessory/body_markings indexed by name - //Hairstyles -GLOBAL_LIST_EMPTY(hair_styles_public_list) //stores /datum/sprite_accessory/hair indexed by name -GLOBAL_LIST_EMPTY(hair_styles_male_list) -GLOBAL_LIST_EMPTY(hair_styles_female_list) -GLOBAL_LIST_EMPTY(hair_styles_full_list) //fluff hair styles -GLOBAL_LIST_EMPTY(facial_hair_styles_list) //stores /datum/sprite_accessory/facial_hair indexed by name -GLOBAL_LIST_EMPTY(facial_hair_styles_male_list) -GLOBAL_LIST_EMPTY(facial_hair_styles_female_list) -GLOBAL_LIST_EMPTY(hair_gradients_list) //stores /datum/sprite_accessory/hair_gradient indexed by name - //Underwear -GLOBAL_LIST_EMPTY(underwear_list) //stores /datum/sprite_accessory/underwear indexed by name -GLOBAL_LIST_EMPTY(underwear_m) //stores only underwear name -GLOBAL_LIST_EMPTY(underwear_f) //stores only underwear name - //Undershirts -GLOBAL_LIST_EMPTY(undershirt_list) //stores /datum/sprite_accessory/undershirt indexed by name -GLOBAL_LIST_EMPTY(undershirt_m) //stores only undershirt name -GLOBAL_LIST_EMPTY(undershirt_f) //stores only undershirt name - //Socks -GLOBAL_LIST_EMPTY(socks_list) //stores /datum/sprite_accessory/socks indexed by name -GLOBAL_LIST_EMPTY(socks_m) //stores only socks name -GLOBAL_LIST_EMPTY(socks_f) //stores only socks name - //Alt Heads -GLOBAL_LIST_EMPTY(alt_heads_list) //stores /datum/sprite_accessory/alt_heads indexed by name - -// Reference list for disposal sort junctions. Set the sort_type_txt variable on disposal sort junctions to -// the index of the sort department that you want. For example, adding "2" to sort_type_txt will reroute all packages -// tagged for the Cargo Bay. Multiple destinations can be added by separating them with ;, like "2;8" for Cargo Bay and Security. - -//If you don't want to fuck up disposals, add to this list, and don't change the order. -//If you insist on changing the order, you'll have to change every sort junction to reflect the new order. --Pete - -GLOBAL_LIST_INIT(TAGGERLOCATIONS, list("Disposals", - "Cargo Bay", "QM Office", "Engineering", "CE Office", - "Atmospherics", "HoS Office", "Security", "Medbay", - "CMO Office", "Chemistry", "Research", "RD Office", - "Robotics", "HoP Office", "Library", "Chapel", "Captain's Office", - "Bar", "Kitchen", "Hydroponics", "Janitor Closet","Genetics", "Detective", "Morgue")) - -GLOBAL_LIST_INIT(greek_letters, 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(phonetic_alphabet, list("Alpha", "Bravo", "Charlie", - "Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India", "Juliet", - "Kilo", "Lima", "Mike", "November", "Oscar", "Papa", "Quebec", - "Romeo", "Sierra", "Tango", "Uniform", "Victor", "Whiskey", "X-ray", - "Yankee", "Zulu")) - -//Backpacks -#define GBACKPACK "Grey Backpack" -#define GSATCHEL "Grey Satchel" -#define GDUFFLEBAG "Grey Dufflebag" -#define LSATCHEL "Leather Satchel" -#define DBACKPACK "Department Backpack" -#define DSATCHEL "Department Satchel" -#define DDUFFLEBAG "Department Dufflebag" -GLOBAL_LIST_INIT(backbaglist, list(DBACKPACK, DSATCHEL, DDUFFLEBAG, GBACKPACK, GSATCHEL, GDUFFLEBAG, LSATCHEL)) - -//Chooseable brain types for borgs -#define MMI_BORG "MMI" -#define ROBOBRAIN_BORG "Robobrain" -#define POSITRONIC_BORG "Positronic" -GLOBAL_LIST_INIT(borg_brain_choices, list(MMI_BORG, ROBOBRAIN_BORG, POSITRONIC_BORG)) -GLOBAL_PROTECT(borg_brain_choices) - -//Chooseable ringtones -//Due to database reasons, the name should be 16 characters long maximum -GLOBAL_LIST_INIT(pda_ringtone_choices, list("beep" = 'sound/machines/twobeep.ogg', - "boop" = 'sound/machines/boop.ogg', - "electronic" = 'sound/machines/notif1.ogg', - "chime" = 'sound/machines/notif2.ogg', - "slip" = 'sound/misc/slip.ogg', - "honk" = 'sound/items/bikehorn.ogg', - "SKREE" = 'sound/voice/shriek1.ogg', - "holy" = 'sound/items/PDA/ambicha4-short.ogg', - "boom" = 'sound/effects/explosionfar.ogg', - "gavel" = 'sound/items/gavel.ogg', - "xeno" = 'sound/voice/hiss1.ogg', - "smoke" = 'sound/magic/smoke.ogg', - "shatter" = 'sound/effects/pylon_shatter.ogg', - "energy" = 'sound/weapons/egloves.ogg', - "flare" = 'sound/goonstation/misc/matchstick_light.ogg', - "interference" = 'sound/misc/interference.ogg', - "zap" = 'sound/effects/eleczap.ogg', - "disgusting" = 'sound/effects/blobattack.ogg', - "hungry" = 'sound/weapons/bite.ogg')) diff --git a/code/_globalvars/lists/maint_loot_tables.dm b/code/_globalvars/lists/maint_loot_tables.dm deleted file mode 100644 index 229024bd9e461..0000000000000 --- a/code/_globalvars/lists/maint_loot_tables.dm +++ /dev/null @@ -1,208 +0,0 @@ -GLOBAL_LIST_INIT(maintenance_loot_tier_0, list( - list( - // Tools - /obj/effect/spawner/random/engineering/tools = 4, - - // Materials - /obj/effect/spawner/random/engineering/materials = 4, - // Plushies - /obj/effect/spawner/random/plushies = 1, - ) = 6, - - list( - // Spawners for easily found items - /obj/effect/spawner/random/bureaucracy, - /obj/effect/spawner/random/dice, - /obj/effect/spawner/random/book, - - // Other worthless/easily found items - /obj/item/camera_film, - /obj/item/camera, - /obj/item/caution, - /obj/item/clothing/head/cone, - /obj/item/light/bulb, - /obj/item/light/tube, - /obj/item/poster/random_contraband, - /obj/item/poster/random_official, - /obj/item/reagent_containers/drinks/drinkingglass, - /obj/item/reagent_containers/glass/beaker/waterbottle, - /obj/item/reagent_containers/glass/beaker/waterbottle/empty, - /obj/item/scissors, - /obj/item/storage/box, - /obj/item/storage/fancy/crayons, - /obj/item/storage/fancy/matches, - ) = 2, - - list( - // Emergency items - /obj/item/extinguisher, - /obj/item/flashlight, - ) = 1, -)) - -GLOBAL_LIST_INIT(maintenance_loot_tier_1, list( - list( - // Sub-spawners - /obj/effect/spawner/random/engineering/toolbox, - /obj/effect/spawner/random/snacks, - - // Assemblies and cells - /obj/item/assembly/prox_sensor, - /obj/item/assembly/timer, - /obj/item/assembly/signaler, - /obj/item/assembly/voice, - /obj/item/assembly/voice/noise, - /obj/item/stock_parts/cell, - - // Clothing - /obj/item/clothing/glasses/sunglasses, - /obj/item/clothing/gloves/color/black, - /obj/item/clothing/gloves/color/fyellow, - /obj/item/clothing/gloves/color/yellow/fake, - /obj/item/clothing/head/hardhat, - /obj/item/clothing/head/hardhat/red, - /obj/item/clothing/head/that, - /obj/item/clothing/head/ushanka, - /obj/item/clothing/mask/gas, - /obj/item/clothing/shoes/black, - /obj/item/clothing/suit/storage/hazardvest, - /obj/item/clothing/under/color/black, - /obj/item/clothing/under/misc/vice, - - // Medical supplies / chemistry items - /obj/item/reagent_containers/dropper, - /obj/item/reagent_containers/glass/beaker, - /obj/item/reagent_containers/glass/beaker/large, - /obj/item/reagent_containers/syringe, - /obj/item/stack/medical/bruise_pack/advanced, - /obj/item/stack/medical/ointment/advanced, - - // Common items - /obj/item/bodybag, - /obj/item/cultivator, - /obj/item/flashlight/pen, - /obj/item/radio/off, - /obj/item/reagent_containers/drinks/mug, - /obj/item/reagent_containers/glass/bucket, - /obj/item/reagent_containers/spray/pestspray, - /obj/item/relic, - /obj/item/restraints/handcuffs/toy, - /obj/item/scratch, - /obj/item/seeds/ambrosia, - /obj/item/seeds/ambrosia/deus, - /obj/item/stack/sheet/cardboard, - /obj/item/stack/sheet/cloth, - /obj/item/storage/bag/plasticbag, - /obj/item/storage/box/cups, - /obj/item/storage/box/donkpockets, - /obj/item/storage/box/lights/mixed, - /obj/item/storage/fancy/cigarettes/dromedaryco, - /obj/item/tank/internals/emergency_oxygen, - /obj/item/tank/internals/emergency_oxygen/engi, - /obj/item/vending_refill/cola, - ) = 85, - - list( - /obj/item/storage/wallet, - /obj/item/storage/wallet/random, - ) = 5, - - list( - // Small chance of tier 1 stock parts - /obj/item/stock_parts/capacitor, - /obj/item/stock_parts/manipulator, - /obj/item/stock_parts/matter_bin, - /obj/item/stock_parts/micro_laser, - /obj/item/stock_parts/scanning_module, - - // Coins - /obj/item/coin/silver, - /obj/item/coin/twoheaded, - ) = 2, -)) - -GLOBAL_LIST_INIT(maintenance_loot_tier_2, list( - list( - // Rarer items - /obj/effect/spawner/random/mod_maint, - /obj/item/clothing/glasses/meson, - /obj/item/clothing/head/welding, - /obj/item/crowbar/red, - /obj/item/storage/belt/utility, - ) = 45, - - list( - // Contraband and Syndicate items - /obj/item/ammo_box/magazine/m10mm, - /obj/item/clothing/mask/chameleon, - /obj/item/clothing/mask/chameleon/voice_change, - /obj/item/clothing/mask/gas/voice_modulator, - /obj/item/clothing/mask/gas/voice_modulator/chameleon, - /obj/item/clothing/shoes/chameleon/noslip, - /obj/item/clothing/suit/jacket/bomber/syndicate, - /obj/item/clothing/suit/storage/iaa/blackjacket/armored, - /obj/item/clothing/under/chameleon, - /obj/item/deck/cards/syndicate, - /obj/item/grenade/clown_grenade, - /obj/item/grenade/smokebomb, - /obj/item/gun/syringe/syndicate, - /obj/item/melee/knuckleduster/syndie, - /obj/item/mod/construction/broken_core, - /obj/item/multitool/ai_detect, - /obj/item/seeds/ambrosia/cruciatus, - /obj/item/soap/syndie, - /obj/item/stamp/chameleon, - /obj/item/storage/backpack/duffel/syndie/med/surgery_fake, - /obj/item/storage/backpack/satchel_flat, - /obj/item/storage/belt/military/traitor, - /obj/item/storage/fancy/cigarettes/cigpack_syndicate, - /obj/item/storage/pill_bottle/fakedeath, - /obj/item/storage/secure/briefcase/syndie, - /obj/item/storage/toolbox/syndicate, - /obj/item/suppressor, - /obj/item/weaponcrafting/receiver, - ) = 45, - - list( - // Health/repair kits - /obj/item/storage/firstaid/regular, - /obj/item/storage/firstaid/machine, - - // Rarer departmental items - /obj/item/reagent_scanner/adv, - /obj/item/robotanalyzer, - /obj/item/stack/nanopaste, - /obj/item/whetstone, - - // Other rare but useful items - /obj/item/radio/headset, - /obj/item/melee/knuckleduster, - ) = 3, -)) - -GLOBAL_LIST_INIT(maintenance_loot_tier_3, list( - list( - // Coveted items - /obj/item/clothing/gloves/color/yellow, - ) = 7, - - list( - // Rare Syndicate items - /obj/item/gun/projectile/automatic/pistol, - /obj/item/dnascrambler, - /obj/item/bio_chip_implanter/storage, - /obj/item/reagent_containers/spray/sticky_tar, - /obj/item/storage/box/syndie_kit/space, - ) = 3, -)) - -GLOBAL_LIST_INIT(maintenance_loot_tables, list( - list( - GLOB.maintenance_loot_tier_0 = 490, - GLOB.maintenance_loot_tier_1 = 390, - GLOB.maintenance_loot_tier_2 = 114, - GLOB.maintenance_loot_tier_3 = 6, - ) = 75, - - /obj/effect/spawner/random/trash = 25, -)) diff --git a/code/_globalvars/lists/reagents_lists.dm b/code/_globalvars/lists/reagents_lists.dm deleted file mode 100644 index 447e4783475f6..0000000000000 --- a/code/_globalvars/lists/reagents_lists.dm +++ /dev/null @@ -1,54 +0,0 @@ -// Standard medicines -GLOBAL_LIST_INIT(standard_medicines, list("charcoal","toxin","cyanide","morphine","epinephrine","space_drugs", - "mutadone","mutagen","teporone","lexorin","silver_sulfadiazine", - "salbutamol","perfluorodecalin","omnizine","synaptizine","haloperidol", - "potass_iodide","pen_acid","mannitol","oculine","styptic_powder","happiness", - "methamphetamine","spaceacillin","carpotoxin","lsd","ethanol","ammonia", - "diethylamine","antihol","pancuronium","lipolicide","condensedcapsaicin", - "frostoil","amanitin","psilocybin","nothing","salglu_solution","neurotoxin")) -// Rare medicines -GLOBAL_LIST_INIT(rare_medicines, list("syndicate_nanites","minttoxin","blood", "xenomicrobes")) -// Drinks -GLOBAL_LIST_INIT(drinks, list("beer2","hot_coco","orangejuice","tomatojuice","limejuice","carrotjuice", - "berryjuice","poisonberryjuice","watermelonjuice","lemonjuice","banana", "bungojuice", - "nothing","potato","milk","soymilk","cream","coffee","tea","icecoffee", - "icetea","cola","nuka_cola","spacemountainwind","thirteenloko","dr_gibb", - "space_up","lemon_lime","beer","whiskey","gin","rum","vodka","holywater", - "tequila","vermouth","wine","tonic","kahlua","cognac","ale","sodawater", - "ice","bilk","atomicbomb","threemileisland","goldschlager","patron","gintonic", - "cubalibre","whiskeycola","martini","vodkamartini","whiterussian","screwdrivercocktail", - "booger","bloodymary","gargleblaster","bravebull","tequilasunrise","toxinsspecial", - "beepskysmash","salglu_solution","irishcream","manlydorf","longislandicedtea", - "moonshine","b52","irishcoffee","margarita","blackrussian","manhattan", - "manhattan_proj","whiskeysoda","adminfreeze","antifreeze","barefoot","snowwhite","demonsblood", - "vodkatonic","ginfizz","bahama_mama","singulo","sbiten","devilskiss","red_mead", - "mead","iced_beer","grog","aloe","andalusia","alliescocktail","soy_latte", - "cafe_latte","acidspit","amasec","neurotoxin","hippiesdelight","bananahonk", - "silencer","changelingsting","irishcarbomb","syndicatebomb","erikasurprise","driestmartini", "flamingmoe", - "arnold_palmer","gimlet","sidecar","whiskeysour","mintjulep","pinacolada","sontse","ahdomaieclipse", - "beachfeast","fyrsskartears","junglevox","slimemold","dieseife","aciddreams","islaywhiskey","ultramatter", - "howler", "dionasmash")) - -//Liver Toxins list -GLOBAL_LIST_INIT(liver_toxins, list("toxin", "plasma", "sacid", "facid", "cyanide","amanitin", "carpotoxin")) - -//General chem blacklist. This is for the really good stuff that we just want to restrict from things like bees and odysseus syringe gun duping -GLOBAL_LIST_INIT(blocked_chems, list("polonium", "initropidril", "concentrated_initro", - "sodium_thiopental", "ketamine", - "adminordrazine", "nanites", "hell_water", - "mutationtoxin", "amutationtoxin", "venom", - "spore", "stimulants", "stimulative_agent", - "syndicate_nanites", "ripping_tendrils", "boiling_oil", - "envenomed_filaments", "lexorin_jelly", "kinetic", - "cryogenic_liquid", "liquid_dark_matter", "b_sorium", - "reagent", "drink", "medicine", "plantnutrient", "consumable", "dragonsbreath", - "nanocalcium", "xenomicrobes", "nanomachines", "gibbis", "prions", - "spidereggs", "heartworms", "bacon_grease", - "fungalspores", "jagged_crystals", "salmonella", - "lavaland_extract", "stable_mutagen", "beer2", - "curare", "gluttonytoxin", "smoke_powder", "stimulative_cling", - "teslium_paste", "omnizine_no_addiction", "zombiecure1", - "zombiecure2", "zombiecure3", "zombiecure4", - "admincleaner_all", "admincleaner_item", "admincleaner_mob", - "synthetic_omnizine_no_addiction", "surge_plus" - )) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm deleted file mode 100644 index c108b54e38cf5..0000000000000 --- a/code/_onclick/click.dm +++ /dev/null @@ -1,517 +0,0 @@ -/* - Click code cleanup - ~Sayu -*/ - -//Delays the mob's next action by num deciseconds -// eg: 10-3 = 7 deciseconds of delay -// eg: 10*0.5 = 5 deciseconds of delay -// DOES NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK - -/mob/proc/changeNext_move(num) - next_move = world.time + ((num+next_move_adjust)*next_move_modifier) - -//Delays the mob's next click by num deciseconds -// eg: 10-3 = 7 deciseconds of delay -// eg: 10*0.5 = 5 deciseconds of delay -// DOES NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK - -/mob/proc/changeNext_click(num) - next_click = world.time + ((num+next_click_adjust)*next_click_modifier) - - -/* - Before anything else, defer these calls to a per-mobtype handler. This allows us to - remove istype() spaghetti code, but requires the addition of other handler procs to simplify it. - - Alternately, you could hardcode every mob's variation in a flat ClickOn() proc; however, - that's a lot of code duplication and is hard to maintain. - - Note that this proc can be overridden, and is in the case of screen objects. -*/ -/atom/Click(location,control,params) - usr.ClickOn(src, params) -/atom/DblClick(location,control,params) - usr.DblClickOn(src,params) - -/* - Standard mob ClickOn() - Handles exceptions: Buildmode, middle click, modified clicks, mech actions - - After that, mostly just check your state, check whether you're holding an item, - check whether you're adjacent to the target, then pass off the click to whoever - is recieving it. - The most common are: - * mob/UnarmedAttack(atom,adjacent) - used here only when adjacent, with no item in hand; in the case of humans, checks gloves - * atom/attackby(item,user) - used only when adjacent - * item/afterattack__legacy__attackchain(atom,user,adjacent,params) - used both ranged and adjacent - * mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed -*/ -/mob/proc/ClickOn(atom/A, params) - if(QDELETED(A)) - return - - if(client?.click_intercept) - client.click_intercept.InterceptClickOn(src, params, A) - return - - if(next_click > world.time) - return - changeNext_click(1) - - var/list/modifiers = params2list(params) - var/dragged = modifiers["drag"] - if(dragged && !modifiers[dragged]) - return - if(IsFrozen(A) && !is_admin(usr)) - to_chat(usr, "Interacting with admin-frozen players is not permitted.") - return - if(modifiers["middle"] && modifiers["shift"] && modifiers["ctrl"]) - MiddleShiftControlClickOn(A) - return - if(modifiers["middle"] && modifiers["shift"]) - MiddleShiftClickOn(A) - return - if(modifiers["shift"] && modifiers["ctrl"]) - CtrlShiftClickOn(A) - return - if(modifiers["shift"] && modifiers["alt"]) - AltShiftClickOn(A) - return - if(modifiers["middle"]) - MiddleClickOn(A) - return - if(modifiers["shift"]) - ShiftClickOn(A) - return - if(modifiers["alt"]) // alt and alt-gr (rightalt) - AltClickOn(A) - return - if(modifiers["ctrl"]) - CtrlClickOn(A) - return - - if(incapacitated(ignore_restraints = 1, ignore_grab = 1)) - return - - face_atom(A) - - if(next_move > world.time) // in the year 2000... - return - - if(!modifiers["catcher"] && A.IsObscured()) - return - - if(ismecha(loc)) - if(!locate(/turf) in list(A,A.loc)) // Prevents inventory from being drilled - return - var/obj/mecha/M = loc - return M.click_action(A, src, params) - - if(restrained()) - RestrainedClickOn(A) - return - - if(in_throw_mode) - throw_item(A) - return - - if(isLivingSSD(A)) - if(client && client.send_ssd_warning(A)) - return - - var/obj/item/W = get_active_hand() - - if(W == A) - if(W.new_attack_chain) - W.activate_self(src) - else - W.attack_self__legacy__attackchain(src) - if(hand) - update_inv_l_hand() - else - update_inv_r_hand() - return - - // operate three levels deep here (item in backpack in src; item in box in backpack in src, not any deeper) - if(A in direct_access()) - if(W) - W.melee_attack_chain(src, A, params) - else - if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) - UnarmedAttack(A, 1) - return - - if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that - return TRUE - - if(can_reach(A, W)) - if(W) - W.melee_attack_chain(src, A, params) - else - if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) - UnarmedAttack(A, 1) - else - if(W) - if(W.new_attack_chain) - A.base_ranged_item_interaction(src, W, params) - else - W.afterattack__legacy__attackchain(A, src, 0, params) // 0: not Adjacent - else - RangedAttack(A, params) - - -/** - * A backwards depth-limited breadth-first-search to see if the target is - * logically "in" anything adjacent to us. - */ -/atom/movable/proc/can_reach(atom/ultimate_target, obj/item/tool, view_only = FALSE) //This might break mod storage. If it does, we hardcode mods / funny bag in here - var/list/direct_access = direct_access() - var/depth = 1 + (view_only ? STORAGE_VIEW_DEPTH : INVENTORY_DEPTH) - - var/list/closed = list() - var/list/checking = list(ultimate_target) - - while(length(checking) && depth > 0) - var/list/next = list() - --depth - - for(var/atom/target in checking) // will filter out nulls - if(closed[target] || isarea(target)) // avoid infinity situations - continue - - if(isturf(target) || isturf(target.loc) || (target in direct_access) || !(target.IsObscured()) || istype(target.loc, /obj/item/storage)) //Directly accessible atoms - if(target.Adjacent(src) || (tool && CheckToolReach(src, target, tool.reach))) //Adjacent or reaching attacks - return TRUE - - closed[target] = TRUE - - if(!target.loc) - continue - - if(istype(target.loc, /obj/item/storage)) - next += target.loc - - checking = next - return FALSE - -/atom/movable/proc/direct_access() - return list(src, loc) - -/mob/direct_access(atom/target) - return ..() + contents - -/mob/living/direct_access(atom/target) - return ..() + get_contents() - -/proc/CheckToolReach(atom/movable/here, atom/movable/there, reach) - if(!here || !there) - return FALSE - switch(reach) - if(0, 1) - return FALSE //here.Adjacent(there) - if(2 to INFINITY) - var/obj/dummy = new(get_turf(here)) - dummy.pass_flags |= PASSTABLE - dummy.invisibility = 120 - for(var/i in 1 to reach) //Limit it to that many tries - var/turf/T = get_step(dummy, get_dir(dummy, there)) - if(dummy.can_reach(there)) - qdel(dummy) - return TRUE - if(!dummy.Move(T)) //we're blocked! - qdel(dummy) - return FALSE - qdel(dummy) - -/// Can this mob use keybinded click actions? (Altclick, Ctrlclick, ect) -/mob/proc/can_use_clickbinds() - return TRUE - -//Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it -/atom/proc/IsObscured() - if(!isturf(loc)) //This only makes sense for things directly on turfs for now - return FALSE - var/turf/T = get_turf_pixel(src) - if(!T) - return FALSE - for(var/atom/movable/AM in T) - if(AM.flags & PREVENT_CLICK_UNDER && AM.density && AM.layer > layer) - return TRUE - return FALSE - -/turf/IsObscured() - for(var/atom/movable/AM in src) - if(AM.flags & PREVENT_CLICK_UNDER && AM.density) - return TRUE - return FALSE - -// Default behavior: ignore double clicks, consider them normal clicks instead -/mob/proc/DblClickOn(atom/A, params) - return - -/* - Translates into attack_hand, etc. - - Note: proximity_flag here is used to distinguish between normal usage (flag=1), - and usage when clicking on things telekinetically (flag=0). This proc will - not be called at ranged except with telekinesis. - - proximity_flag is not currently passed to attack_hand, and is instead used - in human click code to allow glove touches only at melee range. -*/ -/mob/proc/UnarmedAttack(atom/A, proximity_flag) - if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) - return - -/* - Ranged unarmed attack: - - This currently is just a default for all mobs, involving - laser eyes and telekinesis. You could easily add exceptions - for things like ranged glove touches, spitting alien acid/neurotoxin, - animals lunging, etc. -*/ -/mob/proc/RangedAttack(atom/A, params) - if(SEND_SIGNAL(src, COMSIG_MOB_ATTACK_RANGED, A, params) & COMPONENT_CANCEL_ATTACK_CHAIN) - return TRUE - if(SEND_SIGNAL(A, COMSIG_ATOM_RANGED_ATTACKED, src) & COMPONENT_CANCEL_ATTACK_CHAIN) - return TRUE - -/* - Restrained ClickOn - Used when you are handcuffed and click things. - Not currently used by anything but could easily be. -*/ -/mob/proc/RestrainedClickOn(atom/A) - return - -/* - Middle click - Only used for swapping hands -*/ -/mob/proc/MiddleClickOn(atom/A) - pointed(A) - return - -// See click_override.dm -/mob/living/MiddleClickOn(atom/A) - . = SEND_SIGNAL(src, COMSIG_MOB_MIDDLECLICKON, A, src) - if(. & COMSIG_MOB_CANCEL_CLICKON) - return - if(middleClickOverride) - middleClickOverride.onClick(A, src) - else - ..() - - -/* - Middle shift-click - Makes the mob face the direction of the clicked thing -*/ -/mob/proc/MiddleShiftClickOn(atom/A) - return - -/mob/living/MiddleShiftClickOn(atom/A) - if(incapacitated()) - return - var/face_dir = get_cardinal_dir(src, A) - if(!face_dir || forced_look == face_dir || A == src) - clear_forced_look() - return - set_forced_look(A, FALSE) - -/* - Middle shift-control-click - Makes the mob constantly face the object (until it's out of sight) -*/ -/mob/proc/MiddleShiftControlClickOn(atom/A) - return - -/mob/living/MiddleShiftControlClickOn(atom/A) - if(incapacitated()) - return - var/face_uid = A.UID() - if(forced_look == face_uid || A == src) - clear_forced_look() - return - set_forced_look(A, TRUE) - -// In case of use break glass -/* -/atom/proc/MiddleClick(mob/M as mob) - return -*/ - -/* - Shift click - For most mobs, examine. - This is overridden in ai.dm -*/ -/mob/proc/ShiftClickOn(atom/A) - A.ShiftClick(src) - return -/atom/proc/ShiftClick(mob/user) - if(user.client && get_turf(user.client.eye) == get_turf(user)) - user.examinate(src) - return - -/* - Ctrl click - For most objects, pull -*/ -/mob/proc/CtrlClickOn(atom/A) - A.CtrlClick(src) - return - -/atom/proc/CtrlClick(mob/user) - SEND_SIGNAL(src, COMSIG_CLICK_CTRL, user) - var/mob/living/ML = user - if(istype(ML)) - ML.pulled(src) - -/* - Alt click -*/ -/mob/proc/AltClickOn(atom/A) - A.AltClick(src) - return - -// See click_override.dm -/mob/living/AltClickOn(atom/A) - . = SEND_SIGNAL(src, COMSIG_MOB_ALTCLICKON, A, src) - if(. & COMSIG_MOB_CANCEL_CLICKON) - return - if(middleClickOverride && middleClickOverride.onClick(A, src)) - return - ..() - -/atom/proc/AltClick(mob/user) - if(SEND_SIGNAL(src, COMSIG_CLICK_ALT, user) & COMPONENT_CANCEL_ALTCLICK) - return - var/turf/T = get_turf(src) - if(T && (isturf(loc) || isturf(src)) && user.TurfAdjacent(T)) - user.set_listed_turf(T) - -/// Use this instead of [/mob/proc/AltClickOn] where you only want turf content listing without additional atom alt-click interaction -/atom/proc/AltClickNoInteract(mob/user, atom/A) - var/turf/T = get_turf(A) - if(T && user.TurfAdjacent(T)) - user.set_listed_turf(T) - -/mob/proc/TurfAdjacent(turf/T) - return T.Adjacent(src) - -/* - Control+Shift/Alt+Shift click - Unused except for AI -*/ -/mob/proc/CtrlShiftClickOn(atom/A) - A.CtrlShiftClick(src) - return - -/atom/proc/CtrlShiftClick(mob/user) - return - -/mob/proc/AltShiftClickOn(atom/A) - A.AltShiftClick(src) - return - -/mob/proc/ShiftMiddleClickOn(atom/A) - return - -/atom/proc/AltShiftClick(mob/user) - return - -/* - Misc helpers - - Laser Eyes: as the name implies, handles this since nothing else does currently - face_atom: turns the mob towards what you clicked on -*/ -/mob/proc/LaserEyes(atom/A) - return - -/mob/living/LaserEyes(atom/A) - changeNext_move(CLICK_CD_RANGE) - var/turf/T = get_turf(src) - var/turf/U = get_turf(A) - - var/obj/item/projectile/beam/LE = new /obj/item/projectile/beam(loc) - LE.icon = 'icons/effects/genetics.dmi' - LE.icon_state = "eyelasers" - playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1) - - LE.firer = src - LE.firer_source_atom = src - LE.def_zone = ran_zone(zone_selected) - LE.original = A - LE.current = T - LE.yo = U.y - T.y - LE.xo = U.x - T.x - LE.fire() - -// Simple helper to face what you clicked on, in case it should be needed in more than one place -/mob/proc/face_atom(atom/A) - if(stat || buckled || !A || !x || !y || !A.x || !A.y) return - var/dx = A.x - x - var/dy = A.y - y - if(!dx && !dy) return - - var/direction - if(abs(dx) < abs(dy)) - if(dy > 0) direction = NORTH - else direction = SOUTH - else - if(dx > 0) direction = EAST - else direction = WEST - dir = direction - -/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" - -/atom/movable/screen/click_catcher/MouseEntered(location, control, params) - return - -/atom/movable/screen/click_catcher/MouseExited(location, control, params) - return - -#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/click_turf = parse_caught_click_modifiers(modifiers, get_turf(usr.client ? usr.client.eye : usr), usr.client) - if(click_turf) - modifiers["catcher"] = TRUE - click_turf.Click(location, control, list2params(modifiers)) - . = 1 - -#undef MAX_SAFE_BYOND_ICON_SCALE_TILES -#undef MAX_SAFE_BYOND_ICON_SCALE_PX diff --git a/code/_onclick/click_override.dm b/code/_onclick/click_override.dm deleted file mode 100644 index 8a377d6706b68..0000000000000 --- a/code/_onclick/click_override.dm +++ /dev/null @@ -1,129 +0,0 @@ -/* - Click Overrides - - These are overrides for a living mob's middle and alt clicks. - If the mob in question has their middleClickOverride var set to one of these datums, when they middle or alt click the onClick proc for the datum their clickOverride var is - set equal to will be called. - See click.dm 251 and 196. - - If you have any questions, contact me on the Paradise forums. - - DaveTheHeacrab - */ - -/datum/middle_click_override/ - -/datum/middle_click_override/proc/onClick(atom/A, mob/living/user) - user.middleClickOverride = null - return TRUE - /* Note, when making a new click override it is ABSOLUTELY VITAL that you set the source's clickOverride to null at some point if you don't want them to be stuck with it forever. - Calling the super will do this for you automatically, but if you want a click override to NOT clear itself after the first click, you must do it at some other point in the code*/ - -/obj/item/badmin_book/ - name = "old book" - desc = "An old, leather bound tome." - icon = 'icons/obj/library.dmi' - icon_state = "book" - var/datum/middle_click_override/clickBehavior = new /datum/middle_click_override/badmin_clicker - -/obj/item/badmin_book/attack_self__legacy__attackchain(mob/living/user as mob) - if(user.middleClickOverride) - to_chat(user, "You try to draw power from [src], but you cannot hold the power at this time!") - return - user.middleClickOverride = clickBehavior - to_chat(user, "You draw a bit of power from [src], you can use middle click or alt click to release the power!") - -/datum/middle_click_override/badmin_clicker - var/summon_path = /obj/item/food/cookie - -/datum/middle_click_override/badmin_clicker/onClick(atom/A, mob/living/user) - var/atom/movable/newObject = new summon_path - newObject.loc = get_turf(A) - to_chat(user, "You release the power you had stored up, summoning \a [newObject.name]!") - usr.loc.visible_message("[user] waves [user.p_their()] hand and summons \a [newObject.name]!") - ..() - -/datum/middle_click_override/shock_implant - -/datum/middle_click_override/shock_implant/onClick(atom/A, mob/living/carbon/human/user) - if(user.incapacitated() || A == user) - return FALSE - var/obj/item/bio_chip/shock/P = locate() in user - if(!P) - return - if(!COOLDOWN_FINISHED(P, last_shocked)) - to_chat(user, "The powerchip is still recharging.") - return FALSE - var/turf/T = get_turf(user) - var/obj/structure/cable/C = locate() in T - if(!P.unlimited_power) - if(!C || !istype(C)) - to_chat(user, "There is no cable here to power the bio-chip.") - return FALSE - var/turf/target_turf = get_turf(A) - if(get_dist(T, target_turf) > P.shock_range) - to_chat(user, "The target is too far away.") - return FALSE - target_turf.hotspot_expose(2000, 1) - playsound(user.loc, 'sound/effects/eleczap.ogg', 40, 1) - - var/atom/beam_from = user - var/atom/target_atom = A - - for(var/i in 0 to 2) //3 attempts. Shocks at the clicked source, tries to find a mob in 1 tile, then choses a random tile 1 away to try again. As such, can only hit a mob 2 tiles away from the click - beam_from.Beam(target_atom, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 6) - if(isliving(target_atom)) - var/mob/living/L = target_atom - var/powergrid = C.get_available_power() //We want available power, so the station being conservative doesn't mess with the power biochip / dark bundle users - if(user.a_intent == INTENT_DISARM || user.a_intent == INTENT_HELP) - add_attack_logs(user, L, "shocked with power bio-chip.") - L.apply_damage(60, STAMINA) - L.Jitter(10 SECONDS) - var/atom/throw_target = get_edge_target_turf(user, get_dir(user, get_step_away(L, user))) - if(ishuman(L)) - var/mob/living/carbon/human/H = L - if(H.gloves && H.gloves.siemens_coefficient == 0) //No throwing with insulated gloves (you still get stamina however) - break - L.throw_at(throw_target, powergrid / (150 KW), powergrid / (300 KW)) //150 kW in grid throws 1 tile, 300 throws 2, etc. - - else - add_attack_logs(user, L, "electrocuted with[P.unlimited_power ? " unlimited" : null] power bio-chip") - if(P.unlimited_power) - L.electrocute_act(1000, P, flags = SHOCK_NOGLOVES) //Just kill them - else - electrocute_mob(L, C.powernet, P) - break - var/list/next_shocked = list() - for(var/mob/M in range(1, target_atom)) //Try to jump to a mob first - if(M == user || isobserver(M)) - continue - next_shocked.Add(M) - break //Break this so it gets the closest, thank you - if(!length(next_shocked)) //No mob? Random bullshit go, try to get closer to a mob with luck - for(var/atom/movable/AM in orange(1, target_atom)) - if(AM == user || iseffect(AM) || isobserver(AM)) - continue - next_shocked.Add(AM) - beam_from = target_atom - target_atom = pick(next_shocked) - A = target_atom - next_shocked.Cut() - - COOLDOWN_START(P, last_shocked, P.shock_delay) - return TRUE - -/** - * # Callback invoker middle click override datum - * - * Middle click override which accepts a callback as an arugment in the `New()` proc. - * When the living mob that has this datum middle-clicks or alt-clicks on something, the callback will be invoked. - */ -/datum/middle_click_override/callback_invoker - var/datum/callback/callback - -/datum/middle_click_override/callback_invoker/New(datum/callback/_callback) - . = ..() - callback = _callback - -/datum/middle_click_override/callback_invoker/onClick(atom/A, mob/living/user) - if(callback.Invoke(user, A)) - return TRUE diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm deleted file mode 100644 index 7e5da141d5a10..0000000000000 --- a/code/_onclick/cyborg.dm +++ /dev/null @@ -1,213 +0,0 @@ -/* - Cyborg ClickOn() - - Cyborgs have no range restriction on attack_robot(), because it is basically an AI click. - However, they do have a range restriction on item use, so they cannot do without the - adjacency code. -*/ - -/mob/living/silicon/robot/ClickOn(atom/A, params) - if(client?.click_intercept) - client.click_intercept.InterceptClickOn(src, params, A) - return - - if(next_click > world.time) - return - changeNext_click(1) - - if(is_ventcrawling(src)) // To stop drones interacting with anything while ventcrawling - return - if(stat == DEAD || lockcharge || IsWeakened() || IsStunned() || IsParalyzed() || low_power_mode) - return - - var/list/modifiers = params2list(params) - if(modifiers["shift"] && modifiers["ctrl"]) - CtrlShiftClickOn(A) - return - if(modifiers["shift"] && modifiers["alt"]) - AltShiftClickOn(A) - return - if(modifiers["middle"] && modifiers["ctrl"]) - CtrlMiddleClickOn(A) - return - if(modifiers["shift"] && modifiers["middle"]) - ShiftMiddleClickOn(A) - return - if(modifiers["middle"]) - MiddleClickOn(A) - return - if(modifiers["shift"]) - ShiftClickOn(A) - return - if(modifiers["alt"]) // alt and alt-gr (rightalt) - AltClickOn(A) - return - if(modifiers["ctrl"]) - CtrlClickOn(A) - return - - if(incapacitated()) - return - - if(next_move >= world.time) - return - - face_atom(A) // change direction to face what you clicked on - - if(aiCamera) - if(aiCamera.in_camera_mode) - aiCamera.camera_mode_off() - if(is_component_functioning("camera")) - aiCamera.captureimage(A, usr) - else - to_chat(src, "Your camera isn't functional.") - return - - /* - cyborg restrained() currently does nothing - if(restrained()) - RestrainedClickOn(A) - return - */ - - var/obj/item/W = get_active_hand() - - // Cyborgs have no range-checking unless there is item use - if(!W) - A.add_hiddenprint(src) - A.attack_robot(src) - return - - // buckled cannot prevent machine interlinking but stops arm movement - if(buckled) - return - - if(W == A) - if(W.new_attack_chain) - W.activate_self(src) - else - W.attack_self__legacy__attackchain(src) - - return - - // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents) - if(A == loc || (A in loc) || (A in contents)) - W.melee_attack_chain(src, A, params) - return - - if(!isturf(loc)) - return - - // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc)) - if(can_reach(A, W)) - W.melee_attack_chain(src, A, params) - return - W.afterattack__legacy__attackchain(A, src, 0, params) - return - -/mob/living/silicon/robot/MiddleShiftControlClickOn(atom/A) - return - -//Ctrl+Middle click cycles through modules -/mob/living/silicon/robot/proc/CtrlMiddleClickOn(atom/A) - cycle_modules() - return - -//Middle click points -/mob/living/silicon/robot/MiddleClickOn(atom/A) - if(isdrone(src)) - // Drones cannot point. - return - pointed(A) - return - -//Give cyborgs hotkey clicks without breaking existing uses of hotkey clicks -// for non-doors/apcs -/mob/living/silicon/robot/ShiftClickOn(atom/A) - A.BorgShiftClick(src) - -/mob/living/silicon/robot/CtrlClickOn(atom/A) - A.BorgCtrlClick(src) - -/mob/living/silicon/robot/AltClickOn(atom/A) - A.BorgAltClick(src) - -/mob/living/silicon/robot/CtrlShiftClickOn(atom/A) - A.BorgCtrlShiftClick(src) - -/mob/living/silicon/robot/AltShiftClickOn(atom/A) - A.BorgAltShiftClick(src) - -/mob/living/silicon/robot/ShiftMiddleClickOn(atom/A) - A.BorgShiftMiddleClick(src) - -/atom/proc/BorgShiftClick(mob/user) - if(user.client && user.client.eye == user) - user.examinate(src) - return - -/atom/proc/BorgCtrlClick(mob/living/silicon/robot/user) //forward to human click if not overriden - CtrlClick(user) - -/atom/proc/BorgAltClick(mob/living/silicon/robot/user) - AltClick(user) - return - -/atom/proc/BorgCtrlShiftClick(mob/user) // Examines - if(user.client && user.client.eye == user) - user.examinate(src) - return - -/atom/proc/BorgAltShiftClick() - return - -/atom/proc/BorgShiftMiddleClick() - return - -// AIRLOCKS - -/obj/machinery/door/airlock/BorgShiftClick(mob/living/silicon/robot/user) // Opens and closes doors! Forwards to AI code. - AIShiftClick(user) - -/obj/machinery/door/airlock/BorgCtrlClick(mob/living/silicon/robot/user) // Bolts doors. Forwards to AI code. - AICtrlClick(user) - -/obj/machinery/door/airlock/BorgAltClick(mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code. - AIAltClick(user) - -/obj/machinery/door/airlock/BorgAltShiftClick(mob/living/silicon/robot/user) // Enables emergency override on doors! Forwards to AI code. - AIAltShiftClick(user) - -/obj/machinery/door/airlock/BorgShiftMiddleClick(mob/living/silicon/robot/user) //Toggles door timing. Forwards to AI code. - AIShiftMiddleClick(user) - -// APC - -/obj/machinery/power/apc/BorgCtrlClick(mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code. - AICtrlClick(user) - -// TURRETCONTROL - -/obj/machinery/turretid/BorgCtrlClick(mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code. - AICtrlClick(user) - -/obj/machinery/turretid/BorgAltClick(mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code. - AIAltClick(user) - -/* - As with AI, these are not used in click code, - because the code for robots is specific, not generic. - - If you would like to add advanced features to robot - clicks, you can do so here, but you will have to - change attack_robot() above to the proper function -*/ -/mob/living/silicon/robot/UnarmedAttack(atom/A) - A.attack_robot(src) - -/mob/living/silicon/robot/RangedAttack(atom/A, params) - A.attack_robot(src) - -/atom/proc/attack_robot(mob/user) - attack_ai(user) - return diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm deleted file mode 100644 index 94279aac05de1..0000000000000 --- a/code/_onclick/hud/blob_overmind.dm +++ /dev/null @@ -1,201 +0,0 @@ -/atom/movable/screen/blob - icon = 'icons/mob/blob.dmi' - -/atom/movable/screen/blob/MouseEntered(location, control, params) - . = ..() - openToolTip(usr,src,params,title = name,content = desc, theme = "blob") - -/atom/movable/screen/blob/MouseExited() - closeToolTip(usr) - return ..() - -/atom/movable/screen/blob/blob_help - icon_state = "ui_help" - name = "Blob Help" - desc = "Help on playing blob!" - -/atom/movable/screen/blob/blob_help/Click() - if(isovermind(usr)) - var/mob/camera/blob/B = usr - B.blob_help() - -/atom/movable/screen/blob/jump_to_node - icon_state = "ui_tonode" - name = "Jump to Node" - desc = "Moves your camera to a selected blob node." - -/atom/movable/screen/blob/jump_to_node/Click() - if(isovermind(usr)) - var/mob/camera/blob/B = usr - B.jump_to_node() - -/atom/movable/screen/blob/jump_to_core - icon_state = "ui_tocore" - name = "Jump to Core" - desc = "Moves your camera to your blob core." - -/atom/movable/screen/blob/jump_to_core/MouseEntered(location, control, params) - if(hud && hud.mymob && isovermind(hud.mymob)) - name = initial(name) - desc = initial(desc) - return ..() - -/atom/movable/screen/blob/jump_to_core/Click() - if(isovermind(usr)) - var/mob/camera/blob/B = usr - B.transport_core() - -/atom/movable/screen/blob/blobbernaut - icon_state = "ui_blobbernaut" - name = "Produce Blobbernaut (60)" - desc = "Produces a strong, intelligent blobbernaut from a factory blob for 60 resources.
    The factory blob will be destroyed in the process." - -/atom/movable/screen/blob/blobbernaut/Click() - if(isovermind(usr)) - var/mob/camera/blob/B = usr - B.create_blobbernaut() - -/atom/movable/screen/blob/storage_blob - icon_state = "ui_storage" - name = "Produce Storage Blob (40)" - desc = "Produces a storage blob for 40 resources.
    Storage blobs will raise your max resource cap by 50." - -/atom/movable/screen/blob/storage_blob/Click() - if(isovermind(usr)) - var/mob/camera/blob/B = usr - B.create_storage() - -/atom/movable/screen/blob/resource_blob - icon_state = "ui_resource" - name = "Produce Resource Blob (40)" - desc = "Produces a resource blob for 40 resources.
    Resource blobs will give you resources every few seconds." - -/atom/movable/screen/blob/resource_blob/Click() - if(isovermind(usr)) - var/mob/camera/blob/B = usr - B.create_resource() - -/atom/movable/screen/blob/node_blob - icon_state = "ui_node" - name = "Produce Node Blob (60)" - desc = "Produces a node blob for 60 resources.
    Node blobs will expand and activate nearby resource and factory blobs." - -/atom/movable/screen/blob/node_blob/Click() - if(isovermind(usr)) - var/mob/camera/blob/B = usr - B.create_node() - -/atom/movable/screen/blob/factory_blob - icon_state = "ui_factory" - name = "Produce Factory Blob (60)" - desc = "Produces a factory blob for 60 resources.
    Factory blobs will produce spores every few seconds." - -/atom/movable/screen/blob/factory_blob/Click() - if(isovermind(usr)) - var/mob/camera/blob/B = usr - B.create_factory() - -/atom/movable/screen/blob/readapt_chemical - icon_state = "ui_chemswap" - name = "Readapt Chemical (50)" - desc = "Randomly rerolls your chemical for 50 resources." - -/atom/movable/screen/blob/readapt_chemical/MouseEntered(location, control, params) - if(hud && hud.mymob && isovermind(hud.mymob)) - name = initial(name) - desc = initial(desc) - return ..() - -/atom/movable/screen/blob/readapt_chemical/Click() - if(isovermind(usr)) - var/mob/camera/blob/B = usr - B.chemical_reroll() - -/atom/movable/screen/blob/relocate_core - icon_state = "ui_swap" - name = "Relocate Core (80)" - desc = "Swaps a node and your core for 80 resources." - -/atom/movable/screen/blob/relocate_core/Click() - if(isovermind(usr)) - var/mob/camera/blob/B = usr - B.relocate_core() - -/atom/movable/screen/blob/split - icon_state = "ui_split" - name = "Split consciousness (100)" - desc = "Creates another Blob Overmind at the targeted node. One use only.
    Offspring are unable to use this ability." - -/atom/movable/screen/blob/split/Click() - if(isovermind(usr)) - var/mob/camera/blob/B = usr - B.split_consciousness() - if(B.split_used) // Destroys split proc if the split is succesfully used - qdel(src) - -/datum/hud/blob_overmind/New(mob/user) - ..() - var/atom/movable/screen/using - - blobpwrdisplay = new /atom/movable/screen() - blobpwrdisplay.name = "blob power" - blobpwrdisplay.icon_state = "block" - blobpwrdisplay.screen_loc = ui_health - blobpwrdisplay.mouse_opacity = MOUSE_OPACITY_TRANSPARENT - blobpwrdisplay.layer = ABOVE_HUD_LAYER - blobpwrdisplay.plane = ABOVE_HUD_PLANE - static_inventory += blobpwrdisplay - - blobhealthdisplay = new /atom/movable/screen() - blobhealthdisplay.name = "blob health" - blobhealthdisplay.icon_state = "block" - blobhealthdisplay.screen_loc = ui_internal - static_inventory += blobhealthdisplay - - using = new /atom/movable/screen/blob/blob_help() - using.screen_loc = "WEST:6,NORTH:-3" - static_inventory += using - - using = new /atom/movable/screen/blob/jump_to_node() - using.screen_loc = ui_inventory - static_inventory += using - - using = new /atom/movable/screen/blob/jump_to_core() - using.screen_loc = ui_zonesel - using.hud = src - static_inventory += using - - using = new /atom/movable/screen/blob/blobbernaut() - using.screen_loc = ui_id - static_inventory += using - - using = new /atom/movable/screen/blob/storage_blob() - using.screen_loc = ui_belt - static_inventory += using - - using = new /atom/movable/screen/blob/resource_blob() - using.screen_loc = ui_back - static_inventory += using - - using = new /atom/movable/screen/blob/node_blob() - using.screen_loc = using.screen_loc = ui_rhand - static_inventory += using - - using = new /atom/movable/screen/blob/factory_blob() - using.screen_loc = using.screen_loc = ui_lhand - static_inventory += using - - using = new /atom/movable/screen/blob/readapt_chemical() - using.screen_loc = ui_storage1 - using.hud = src - static_inventory += using - - using = new /atom/movable/screen/blob/relocate_core() - using.screen_loc = ui_storage2 - static_inventory += using - - var/mob/camera/blob/B = user - if(!B.is_offspring) // Checks if the blob is an offspring, to not create split button if it is - using = new /atom/movable/screen/blob/split() - using.screen_loc = ui_acti - static_inventory += using diff --git a/code/_onclick/hud/guardian_hud.dm b/code/_onclick/hud/guardian_hud.dm deleted file mode 100644 index b460f02f50de7..0000000000000 --- a/code/_onclick/hud/guardian_hud.dm +++ /dev/null @@ -1,97 +0,0 @@ -/datum/hud/guardian/New(mob/owner) - ..() - var/atom/movable/screen/using - - guardianhealthdisplay = new /atom/movable/screen/healths/guardian() - infodisplay += guardianhealthdisplay - - using = new /atom/movable/screen/act_intent/guardian() - using.icon_state = mymob.a_intent - static_inventory += using - action_intent = using - - using = new /atom/movable/screen/guardian/manifest() - using.screen_loc = ui_rhand - static_inventory += using - - using = new /atom/movable/screen/guardian/recall() - using.screen_loc = ui_lhand - static_inventory += using - - using = new /atom/movable/screen/guardian/toggle_mode() - using.screen_loc = ui_storage1 - static_inventory += using - - using = new /atom/movable/screen/guardian/toggle_light() - using.screen_loc = ui_inventory - static_inventory += using - - using = new /atom/movable/screen/guardian/communicate() - using.screen_loc = ui_back - static_inventory += using - - -//HUD BUTTONS - -/atom/movable/screen/guardian - icon = 'icons/mob/guardian.dmi' - icon_state = "base" - -/atom/movable/screen/guardian/manifest - icon_state = "manifest" - name = "Manifest" - desc = "Spring forth into battle!" - -/atom/movable/screen/guardian/manifest/Click() - if(isguardian(usr)) - var/mob/living/simple_animal/hostile/guardian/G = usr - var/summoner_loc = G.summoner.loc - if(istype(summoner_loc, /obj/machinery/atmospherics)) - to_chat(G, "You can not manifest while in these pipes!") - return - if(istype(summoner_loc, /obj/structure/closet/cardboard/agent)) - to_chat(G, "You can not manifest while inside an active Stealth Implant!") - return - if(G.loc == G.summoner) - G.Manifest() - -/atom/movable/screen/guardian/recall - icon_state = "recall" - name = "Recall" - desc = "Return to your user." - -/atom/movable/screen/guardian/recall/Click() - if(isguardian(usr)) - var/mob/living/simple_animal/hostile/guardian/G = usr - G.Recall() - -/atom/movable/screen/guardian/toggle_mode - icon_state = "toggle" - name = "Toggle Mode" - desc = "Switch between ability modes." - -/atom/movable/screen/guardian/toggle_mode/Click() - if(isguardian(usr)) - var/mob/living/simple_animal/hostile/guardian/G = usr - G.ToggleMode() - -/atom/movable/screen/guardian/communicate - icon_state = "communicate" - name = "Communicate" - desc = "Communicate telepathically with your user." - -/atom/movable/screen/guardian/communicate/Click() - if(isguardian(usr)) - var/mob/living/simple_animal/hostile/guardian/G = usr - G.Communicate() - - -/atom/movable/screen/guardian/toggle_light - icon_state = "light" - name = "Toggle Light" - desc = "Glow like star dust." - -/atom/movable/screen/guardian/toggle_light/Click() - if(isguardian(usr)) - var/mob/living/simple_animal/hostile/guardian/G = usr - G.ToggleLight() diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm deleted file mode 100644 index b681bff49259c..0000000000000 --- a/code/_onclick/hud/screen_objects.dm +++ /dev/null @@ -1,579 +0,0 @@ -/* - Screen "objects" - Todo: improve/re-implement - - Screen objects are only used for the hud and should not appear anywhere "in-game". - They are not actually objects, which is counterintuitive to their name. - They are used with the client/screen list and the screen_loc var. - For more information, see the byond documentation on the screen_loc and screen vars. -*/ -/atom/movable/screen - name = "" - icon = 'icons/mob/screen_gen.dmi' - layer = HUD_LAYER - plane = HUD_PLANE - flags = NO_SCREENTIPS - var/obj/master = null //A reference to the object in the slot. Grabs or items, generally. - var/datum/hud/hud = null - appearance_flags = NO_CLIENT_COLOR - /** - * Map name assigned to this object. - * Automatically set by /client/proc/add_obj_to_map. - */ - var/assigned_map - /** - * Mark this object as garbage-collectible after you clean the map - * it was registered on. - * - * This could probably be changed to be a proc, for conditional removal. - * But for now, this works. - */ - var/del_on_map_removal = TRUE - -/atom/movable/screen/Destroy() - master = null - hud = null - return ..() - -/atom/movable/screen/proc/component_click(atom/movable/screen/component_button/component, params) - return - -/atom/movable/screen/text - icon = null - icon_state = null - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - screen_loc = "CENTER-7,CENTER-7" - maptext_height = 480 - maptext_width = 480 - -/atom/movable/screen/close - name = "close" - layer = ABOVE_HUD_LAYER - plane = ABOVE_HUD_PLANE - -/atom/movable/screen/close/Click() - if(master) - if(isstorage(master)) - var/obj/item/storage/S = master - S.close(usr) - return 1 - -/atom/movable/screen/drop - name = "drop" - icon_state = "act_drop" - -/atom/movable/screen/drop/Click() - usr.drop_item_v() - -/atom/movable/screen/grab - name = "grab" - -/atom/movable/screen/grab/Click() - var/obj/item/grab/G = master - G.s_click(src) - return 1 - -/atom/movable/screen/grab/attack_hand() - return - -/atom/movable/screen/grab/attackby__legacy__attackchain() - return -/atom/movable/screen/act_intent - name = "intent" - icon_state = "help" - screen_loc = ui_acti - -/atom/movable/screen/act_intent/Click(location, control, params) - if(ishuman(usr)) - var/_x = text2num(params2list(params)["icon-x"]) - var/_y = text2num(params2list(params)["icon-y"]) - if(_x<=16 && _y<=16) - usr.a_intent_change(INTENT_HARM) - else if(_x<=16 && _y>=17) - usr.a_intent_change(INTENT_HELP) - else if(_x>=17 && _y<=16) - usr.a_intent_change(INTENT_GRAB) - else if(_x>=17 && _y>=17) - usr.a_intent_change(INTENT_DISARM) - else - usr.a_intent_change("right") - -/atom/movable/screen/act_intent/alien - icon = 'icons/mob/screen_alien.dmi' - screen_loc = ui_acti - -/atom/movable/screen/act_intent/robot - icon = 'icons/mob/screen_robot.dmi' - screen_loc = ui_borg_intents - -/atom/movable/screen/act_intent/robot/ai - screen_loc = "SOUTH+1:6,EAST-1:32" - -/atom/movable/screen/mov_intent - name = "run/walk toggle" - icon_state = "running" - -/atom/movable/screen/act_intent/simple_animal - icon = 'icons/mob/screen_simplemob.dmi' - screen_loc = ui_acti - -/atom/movable/screen/act_intent/guardian - icon = 'icons/mob/guardian.dmi' - screen_loc = ui_acti - -/atom/movable/screen/mov_intent/Click() - usr.toggle_move_intent() - -/atom/movable/screen/pull - name = "stop pulling" - icon_state = "pull" - -/atom/movable/screen/pull/Click() - usr.stop_pulling() - -/atom/movable/screen/pull/update_icon_state() - if(hud?.mymob?.pulling) - icon_state = "pull" - else - icon_state = "pull0" - -/atom/movable/screen/resist - name = "resist" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "act_resist" - -/atom/movable/screen/resist/Click() - if(isliving(usr)) - var/mob/living/L = usr - L.resist() - -/atom/movable/screen/throw_catch - name = "throw/catch" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "act_throw_off" - -/atom/movable/screen/throw_catch/Click() - if(iscarbon(usr)) - var/mob/living/carbon/C = usr - C.toggle_throw_mode() - -/atom/movable/screen/storage - name = "storage" - -/atom/movable/screen/storage/Click(location, control, params) - if(world.time <= usr.next_move) - return TRUE - if(usr.incapacitated(ignore_restraints = TRUE)) - return TRUE - if(ismecha(usr.loc)) // stops inventory actions in a mech - return TRUE - if(master) - var/obj/item/I = usr.get_active_hand() - if(I) - master.attackby__legacy__attackchain(I, usr, params) - return TRUE - -/atom/movable/screen/storage/proc/is_item_accessible(obj/item/I, mob/user) - if(!user || !I) - return FALSE - - var/storage_depth = I.storage_depth(user) - if((I in user.loc) || (storage_depth != -1)) - return TRUE - - if(!isturf(user.loc)) - return FALSE - - var/storage_depth_turf = I.storage_depth_turf() - if(isturf(I.loc) || (storage_depth_turf != -1)) - if(I.Adjacent(user)) - return TRUE - return FALSE - -/atom/movable/screen/storage/MouseDrop_T(obj/item/I, mob/user) - if(!user || !istype(I) || user.incapacitated(ignore_restraints = TRUE) || ismecha(user.loc) || !master) - return - - var/obj/item/storage/S = master - if(!S) - return - - if(!is_item_accessible(I, user)) - log_game("[user.simple_info_line()] tried to abuse storage remote drag&drop with '[I]' at [atom_loc_line(I)] into '[S]' at [atom_loc_line(S)]") - message_admins("[user.simple_info_line()] tried to abuse storage remote drag&drop with '[I]' at [atom_loc_line(I)] into '[S]' at [atom_loc_line(S)]") - return - - if(I in S.contents) // If the item is already in the storage, move them to the end of the list - if(S.contents[length(S.contents)] == I) // No point moving them at the end if they're already there! - return - - var/list/new_contents = S.contents.Copy() - if(S.display_contents_with_number) - // Basically move all occurences of I to the end of the list. - var/list/obj/item/to_append = list() - for(var/obj/item/stored_item in S.contents) - if(S.can_items_stack(stored_item, I)) - new_contents -= stored_item - to_append += stored_item - - new_contents.Add(to_append) - else - new_contents -= I - new_contents += I // oof - S.contents = new_contents - - if(user.s_active == S) - S.orient2hud(user) - S.show_to(user) - else // If it's not in the storage, try putting it inside - S.attackby__legacy__attackchain(I, user) - return TRUE - -/atom/movable/screen/zone_sel - name = "damage zone" - icon_state = "zone_sel" - screen_loc = ui_zonesel - var/overlay_file = 'icons/mob/zone_sel.dmi' - var/selecting = "chest" - var/static/list/hover_overlays_cache = list() - var/hovering - -/atom/movable/screen/zone_sel/Click(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/choice = get_zone_at(icon_x, icon_y) - if(!choice) - return 1 - - 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/choice = get_zone_at(icon_x, icon_y) - - if(hovering == choice) - return - cut_overlay(hover_overlays_cache[hovering]) - hovering = choice - - var/obj/effect/overlay/zone_sel/overlay_object = hover_overlays_cache[choice] - if(!overlay_object) - overlay_object = new - overlay_object.icon_state = "[choice]" - hover_overlays_cache[choice] = overlay_object - add_overlay(overlay_object) - - -/obj/effect/overlay/zone_sel - icon = 'icons/mob/zone_sel.dmi' - 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) - if(!isobserver(usr) && hovering) - cut_overlay(hover_overlays_cache[hovering]) - hovering = null - return ..() - -/atom/movable/screen/zone_sel/proc/get_zone_at(icon_x, icon_y) - switch(icon_y) - if(1 to 3) //Feet - switch(icon_x) - if(10 to 15) - return "r_foot" - if(17 to 22) - return "l_foot" - if(4 to 9) //Legs - switch(icon_x) - if(10 to 15) - return "r_leg" - if(17 to 22) - return "l_leg" - if(10 to 13) //Hands and groin - switch(icon_x) - if(8 to 11) - return "r_hand" - if(12 to 20) - return "groin" - if(21 to 24) - return "l_hand" - if(14 to 22) //Chest and arms to shoulders - switch(icon_x) - if(8 to 11) - return "r_arm" - if(12 to 20) - return "chest" - if(21 to 24) - return "l_arm" - if(23 to 30) //Head, but we need to check for eye or mouth - if(icon_x in 12 to 20) - switch(icon_y) - if(23 to 24) - if(icon_x in 15 to 17) - return "mouth" - if(26) //Eyeline, eyes are on 15 and 17 - if(icon_x in 14 to 18) - return "eyes" - if(25 to 27) - if(icon_x in 15 to 17) - return "eyes" - return "head" - -/atom/movable/screen/zone_sel/proc/set_selected_zone(choice) - if(!hud) - return - if(isobserver(hud.mymob)) - return - - if(choice != selecting) - selecting = choice - update_icon(UPDATE_OVERLAYS) - return TRUE - -/atom/movable/screen/zone_sel/update_overlays() - . = ..() - var/image/sel = image(overlay_file, "[selecting]") - sel.appearance_flags = RESET_COLOR - . += sel - hud.mymob.zone_selected = selecting - -/atom/movable/screen/zone_sel/alien - icon = 'icons/mob/screen_alien.dmi' - overlay_file = 'icons/mob/screen_alien.dmi' - -/atom/movable/screen/zone_sel/robot - icon = 'icons/mob/screen_robot.dmi' - -/atom/movable/screen/craft - name = "crafting menu" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "craft" - screen_loc = ui_crafting - -/atom/movable/screen/craft/Click() - if(!isliving(usr)) - return - var/mob/living/M = usr - M.OpenCraftingMenu() - -/atom/movable/screen/language_menu - name = "language menu" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "talk_wheel" - screen_loc = ui_language_menu - -/atom/movable/screen/language_menu/Click() - var/mob/M = usr - if(!istype(M)) - return - M.check_languages() - -/atom/movable/screen/inventory - var/slot_id //The indentifier for the slot. It has nothing to do with ID cards. - var/list/object_overlays = list() - -/atom/movable/screen/inventory/MouseEntered() - . = ..() - add_overlays() - -/atom/movable/screen/inventory/MouseExited() - ..() - cut_overlay(object_overlays) - object_overlays.Cut() - -/atom/movable/screen/inventory/proc/add_overlays() - var/mob/user = hud?.mymob - - if(!user || user != usr) - return - - if(!hud?.mymob || !slot_id || (slot_id & ITEM_SLOT_BOTH_HANDS)) - return - - var/obj/item/holding = user.get_active_hand() - - if(!holding || user.get_item_by_slot(slot_id)) - return - - var/image/item_overlay = image(holding) - item_overlay.alpha = 92 - - if(!user.can_equip(holding, slot_id, TRUE)) - item_overlay.color = "#ff0000" - else - item_overlay.color = "#00ff00" - - object_overlays += item_overlay - add_overlay(object_overlays) - -/atom/movable/screen/inventory/MouseDrop(atom/over) - cut_overlay(object_overlays) - object_overlays.Cut() - if(could_be_click_lag()) - Click() - drag_start = 0 - return - return ..() - -/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 1 - if(usr.incapacitated()) - return 1 - if(ismecha(usr.loc)) // stops inventory actions in a mech - return 1 - - if(hud?.mymob && slot_id) - var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id) - if(inv_item) - return inv_item.Click(location, control, params) - - if(usr.attack_ui(slot_id)) - usr.update_inv_l_hand() - usr.update_inv_r_hand() - return TRUE - -/atom/movable/screen/inventory/hand - var/image/active_overlay - var/image/handcuff_overlay - var/static/mutable_appearance/blocked_overlay = mutable_appearance('icons/mob/screen_gen.dmi', "blocked") - -/atom/movable/screen/inventory/hand/update_overlays() - . = ..() - if(!handcuff_overlay) - var/state = (slot_id == ITEM_SLOT_RIGHT_HAND) ? "markus" : "gabrielle" - handcuff_overlay = image("icon"='icons/mob/screen_gen.dmi', "icon_state"=state) - - if(hud && hud.mymob) - if(iscarbon(hud.mymob)) - var/mob/living/carbon/C = hud.mymob - if(C.handcuffed) - . += handcuff_overlay - - var/obj/item/organ/external/hand = C.get_organ("[slot_id == ITEM_SLOT_LEFT_HAND ? "l" : "r"]_hand") - if(!isalien(C) && (!hand || !hand.is_usable())) - . += blocked_overlay - - if(slot_id == ITEM_SLOT_LEFT_HAND && hud.mymob.hand) - . += "hand_active" - else if(slot_id == ITEM_SLOT_RIGHT_HAND && !hud.mymob.hand) - . += "hand_active" - -/atom/movable/screen/inventory/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 - if(ismecha(usr.loc)) // stops inventory actions in a mech - return 1 - - if(ismob(usr)) - var/mob/M = usr - switch(name) - if("right hand", "r_hand") - M.activate_hand(HAND_BOOL_RIGHT) - if("left hand", "l_hand") - M.activate_hand(HAND_BOOL_LEFT) - return TRUE - -/atom/movable/screen/swap_hand - 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 - - if(ismob(usr)) - var/mob/M = usr - M.swap_hand() - return 1 - -/atom/movable/screen/healths - name = "health" - icon_state = "health0" - screen_loc = ui_health - -/atom/movable/screen/healths/alien - icon = 'icons/mob/screen_alien.dmi' - screen_loc = ui_alien_health - -/atom/movable/screen/healths/bot - icon = 'icons/mob/screen_bot.dmi' - screen_loc = ui_borg_health - -/atom/movable/screen/healths/robot - icon = 'icons/mob/screen_robot.dmi' - screen_loc = ui_borg_health - -/atom/movable/screen/healths/corgi - icon = 'icons/mob/screen_corgi.dmi' - -/atom/movable/screen/healths/slime - icon = 'icons/mob/screen_slime.dmi' - icon_state = "slime_health0" - screen_loc = ui_slime_health - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/atom/movable/screen/healths/guardian - name = "summoner health" - icon = 'icons/mob/guardian.dmi' - icon_state = "base" - screen_loc = ui_health - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/atom/movable/screen/healthdoll - name = "health doll" - icon_state = "healthdoll_DEAD" - screen_loc = ui_healthdoll - var/list/cached_healthdoll_overlays = list() // List of icon states (strings) for overlays - -/atom/movable/screen/healthdoll/Click() - if(ishuman(usr) && usr.stat != DEAD) - var/mob/living/carbon/H = usr - H.check_self_for_injuries() - -/atom/movable/screen/nutrition - name = "nutrition" - icon = 'icons/mob/screen_hunger.dmi' - icon_state = null - screen_loc = ui_nutrition - -/atom/movable/screen/component_button - var/atom/movable/screen/parent - -/atom/movable/screen/component_button/Initialize(mapload, atom/movable/screen/new_parent) - . = ..() - parent = new_parent - -/atom/movable/screen/component_button/Click(params) - if(parent) - parent.component_click(src, params) - -/atom/movable/screen/healths/stamina - icon_state = "stamina_0" - screen_loc = ui_stamina diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm deleted file mode 100644 index 625ea59cf738e..0000000000000 --- a/code/_onclick/item_attack.dm +++ /dev/null @@ -1,306 +0,0 @@ -/** - * This is the proc that handles the order of an item_attack. - * - * The order of procs called is: - * * [/atom/proc/base_item_interaction] on the target. If it returns ITEM_INTERACT_COMPLETE, the chain will be stopped. - * If it returns ITEM_INTERACT_SKIP_TO_AFTER_ATTACK, all attack chain steps except after-attack will be skipped. - * * [/obj/item/proc/pre_attack] on `src`. If this returns FINISH_ATTACK, the chain will be stopped. - * * [/atom/proc/attack_by] on the target. If it returns FINISH_ATTACK, the chain will be stopped. - * * [/obj/item/proc/after_attack]. The return value does not matter. - * - * Currently the return value of this proc is not checked anywhere, and is only used when short-circuiting the rest of the item attack. - */ -/obj/item/proc/melee_attack_chain(mob/user, atom/target, params, proximity_flag = 1) - // TODO: Look into whether proxy attackers are worth porting from /tg/: https://github.com/tgstation/tgstation/pull/83860 - var/list/modifiers = params2list(params) - - var/item_interact_result = target.base_item_interaction(user, src, modifiers) - switch(item_interact_result) - if(ITEM_INTERACT_COMPLETE) - return - if(ITEM_INTERACT_SKIP_TO_AFTER_ATTACK) - __after_attack_core(user, target, params, proximity_flag) - return - - // Attack phase - if(pre_attack(target, user, params)) - return - - var/resolved = target.new_attack_chain \ - ? target.attack_by(src, user, params) \ - : target.attackby__legacy__attackchain(src, user, params) - - // We were asked to cancel the rest of the attack chain. - if(resolved) - return - - // At this point it means the attack was "successful", or at least - // handled, in some way. This can mean nothing happened, this can mean the - // target took damage, etc. - __after_attack_core(user, target, params, proximity_flag) - - -/// Called when the item is in the active hand, and clicked; alternately, there -/// is an 'activate held object' verb or you can hit pagedown. -/obj/item/proc/activate_self(mob/user) - SHOULD_CALL_PARENT(TRUE) - - if(SEND_SIGNAL(src, COMSIG_ACTIVATE_SELF, user) & COMPONENT_CANCEL_ATTACK_CHAIN) - return FINISH_ATTACK - -/** - * Called on ourselves before we hit something. Return TRUE to cancel the remainder of the attack chain. - * - * Arguments: - * * atom/A - The atom about to be hit - * * mob/living/user - The mob doing the htting - * * params - click params such as alt/shift etc - * - * See: [/obj/item/proc/melee_attack_chain] - */ -/obj/item/proc/pre_attack(atom/A, mob/living/user, params) - SHOULD_CALL_PARENT(TRUE) - - if(SEND_SIGNAL(src, COMSIG_PRE_ATTACK, A, user, params) & COMPONENT_CANCEL_ATTACK_CHAIN) - return TRUE - - // TODO: Turn this into a component and have a sane implementation instead of extra-specific behavior in a core proc - var/temperature = get_heat() - if(temperature && A.reagents && !ismob(A) && !istype(A, /obj/item/clothing/mask/cigarette)) - var/reagent_temp = A.reagents.chem_temp - var/time = (reagent_temp / 10) / (temperature / 1000) - if(do_after_once(user, time, TRUE, user, TRUE, attempt_cancel_message = "You stop heating up [A].")) - to_chat(user, "You heat [A] with [src].") - A.reagents.temperature_reagents(temperature) - -/** - * Called when mob `user` is hitting us with an item `attacking`. - * Part of the [/obj/item/proc/melee_attack_chain]. - * - * Handles calling [/atom/proc/attack] or [/obj/item/proc/attack_obj] as necessary. - * - * Arguments: - * * obj/item/attacking_item - The item hitting this atom - * * mob/user - The wielder of this item - * * params - click params such as alt/shift etc - * - * Handles [COMSIG_ATTACK_BY] returning [COMPONENT_SKIP_AFTERATTACK]. - * Returns [FINISH_ATTACK] if the attack chain should stop here. - */ -/atom/proc/attack_by(obj/item/attacking, mob/user, params) - SHOULD_CALL_PARENT(TRUE) - - if(SEND_SIGNAL(src, COMSIG_ATTACK_BY, attacking, user, params) & COMPONENT_SKIP_AFTERATTACK) - return FINISH_ATTACK - -/obj/attack_by(obj/item/attacking, mob/user, params) - . = ..() - - if(.) - return FINISH_ATTACK - - if(!can_be_hit) - return - - return attacking.attack_obj(src, user, params) - -/mob/living/attack_by(obj/item/attacking, mob/living/user, params) - if(..()) - return TRUE - user.changeNext_move(CLICK_CD_MELEE) - return attacking.attack(src, user, params) - -/** - * Called when we are used by `user` to attack the living `target`. - * - * Returns `TRUE` if the rest of the attack chain should be cancelled. This may occur if the attack failed for some reason. - * Returns `FALSE` if the attack was "successful" or "handled" in some way, and the rest of the attack chain should still fire. - */ -/obj/item/proc/attack(mob/living/target, mob/living/user, params) - SHOULD_CALL_PARENT(TRUE) - - var/signal_return = SEND_SIGNAL(src, COMSIG_ATTACK, target, user, params) \ - || SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, target, user, params) - - if(signal_return & COMPONENT_CANCEL_ATTACK_CHAIN) - return FINISH_ATTACK - - if(signal_return & COMPONENT_SKIP_ATTACK) - return FALSE - - . = __attack_core(target, user) - - if(!target.new_attack_chain && .) - return target.attacked_by__legacy__attackchain(src, user, /* def_zone */ null) - -/obj/item/proc/__after_attack_core(mob/user, atom/target, params, proximity_flag = 1) - PRIVATE_PROC(TRUE) - - // TODO: `target` here should probably be another `!QDELETED` check. - // Preserved for backwards compatibility, may be fixed post-migration. - if(target && !QDELETED(src)) - if(new_attack_chain) - after_attack(target, user, proximity_flag, params) - else - afterattack__legacy__attackchain(target, user, proximity_flag, params) - -/obj/item/proc/__attack_core(mob/living/target, mob/living/user) - PRIVATE_PROC(TRUE) - - if(flags & (NOBLUDGEON)) - return FALSE - - // TODO: Migrate all of this to the proper objects so it's not clogging up a core proc and called at irrelevant times - if((is_surgery_tool_by_behavior(src) || is_organ(src) || tool_behaviour) && user.a_intent == INTENT_HELP && on_operable_surface(target) && target != user) - to_chat(user, "You don't want to harm the person you're trying to help!") - return FALSE - - if(force && HAS_TRAIT(user, TRAIT_PACIFISM)) - to_chat(user, "You don't want to harm other living beings!") - return FALSE - - if(!force) - playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), TRUE, -1) - else - SEND_SIGNAL(target, COMSIG_ATTACK) - add_attack_logs(user, target, "Attacked with [name] ([uppertext(user.a_intent)]) ([uppertext(damtype)])", (target.ckey && force > 0 && damtype != STAMINA) ? null : ATKLOG_ALMOSTALL) - if(hitsound) - playsound(loc, hitsound, get_clamped_volume(), TRUE, extrarange = stealthy_audio ? SILENCED_SOUND_EXTRARANGE : -1, falloff_distance = 0) - - target.lastattacker = user.real_name - target.lastattackerckey = user.ckey - - user.do_attack_animation(target) - add_fingerprint(user) - - return TRUE - -/// The equivalent of the standard version of [/obj/item/proc/attack] but for non mob targets. -/obj/item/proc/attack_obj(obj/attacked_obj, mob/living/user, params) - var/signal_return = SEND_SIGNAL(src, COMSIG_ATTACK_OBJ, attacked_obj, user) | SEND_SIGNAL(user, COMSIG_ATTACK_OBJ_LIVING, attacked_obj) - if(signal_return & COMPONENT_SKIP_ATTACK) - return TRUE - if(signal_return & COMPONENT_CANCEL_ATTACK_CHAIN) - return FALSE - if(flags & NOBLUDGEON) - return FALSE - - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(attacked_obj) - - if(attacked_obj.new_attack_chain) - attacked_obj.attacked_by(src, user) - else - attacked_obj.attacked_by__legacy__attackchain(src, user) - -/** - * Called *after* we have been attacked with the item `attacker` by `user`. - * - * Return value is ignored for purposes of the attack chain. - */ -/atom/proc/attacked_by(obj/item/attacker, mob/living/user) - return - -/obj/attacked_by(obj/item/attacker, mob/living/user) - var/damage = attacker.force - if(attacker.force) - user.visible_message( - "[user] has hit [src] with [attacker]!", - "You hit [src] with [attacker]!", - "You hear something being struck by a weapon!" - ) - - if(ishuman(user)) - var/mob/living/carbon/human/H = user - damage += H.physiology.melee_bonus - take_damage(damage, attacker.damtype, MELEE, 1) - -/mob/living/attacked_by(obj/item/attacker, mob/living/user, def_zone) - send_item_attack_message(attacker, user) - if(attacker.force) - var/bonus_damage = 0 - if(ishuman(user)) - var/mob/living/carbon/human/H = user - bonus_damage = H.physiology.melee_bonus - apply_damage(attacker.force + bonus_damage, attacker.damtype, def_zone) - if(attacker.damtype == BRUTE) - if(prob(33)) - attacker.add_mob_blood(src) - var/turf/location = get_turf(src) - add_splatter_floor(location) - if(get_dist(user, src) <= 1) //people with TK won't get smeared with blood - user.add_mob_blood(src) - -/mob/living/simple_animal/attacked_by(obj/item/attacker, mob/living/user) - if(!attacker.force) - user.visible_message( - "[user] gently taps [src] with [attacker].", - "This weapon is ineffective, it does no damage!", - "You hear a gentle tapping." - ) - - else if(attacker.force < force_threshold || attacker.damtype == STAMINA) - visible_message( - "[attacker] bounces harmlessly off of [src].", - "[attacker] bounces harmlessly off of [src]!", - "You hear something being struck by a weapon!" - ) - - else - return ..() - -/** - * Last proc in the [/obj/item/proc/melee_attack_chain]. - * - * Arguments: - * * atom/target - The thing that was hit - * * mob/user - The mob doing the hitting - * * proximity_flag - is 1 if this afterattack was called on something adjacent, in your square, or on your person. - * * click_parameters - is the params string from byond [/atom/proc/Click] code, see that documentation. - */ -/obj/item/proc/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - SHOULD_CALL_PARENT(TRUE) - - SEND_SIGNAL(src, COMSIG_AFTER_ATTACK, target, user, proximity_flag, click_parameters) - SEND_SIGNAL(target, COMSIG_AFTER_ATTACKED_BY, src, user, proximity_flag, click_parameters) - -/obj/item/proc/get_clamped_volume() - if(w_class) - if(force) - return clamp((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100 - else - return clamp(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100 - -/mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area) - if(I.discrete) - return - var/message_verb = "attacked" - if(I.attack_verb && length(I.attack_verb)) - message_verb = "[pick(I.attack_verb)]" - else if(!I.force) - return - var/message_hit_area = "" - if(hit_area) - message_hit_area = " in the [hit_area]" - var/attack_message = "[src] has been [message_verb][message_hit_area] with [I]." - if(user in viewers(src, null)) - attack_message = "[user] has [message_verb] [src][message_hit_area] with [I]!" - visible_message( - "[attack_message]", - "[attack_message]", - "You hear someone being attacked with a weapon!" - ) - return TRUE - -/// Used for signal registrars who wish to completely ignore all behavior -/// in the attack chain from parent types. Should be used sparingly, as -/// subtypes are meant to build on behavior from the parent type. -/datum/proc/signal_cancel_activate_self(mob/user) - return COMPONENT_CANCEL_ATTACK_CHAIN - -/// Used for signal registrars who wish to completely ignore all behavior -/// in the attack chain from parent types calling `attack_by`. Should be -/// used sparingly, as subtypes are meant to build on behavior from the parent -/// type. -/datum/proc/signal_cancel_attack_by(datum/source, obj/item/attacking, mob/user, params) - return COMPONENT_SKIP_AFTERATTACK diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm deleted file mode 100644 index c9f8fccfd1f70..0000000000000 --- a/code/_onclick/other_mobs.dm +++ /dev/null @@ -1,121 +0,0 @@ -/* - Humans: - Adds an exception for gloves, to allow special glove types like the ninja ones. - - Otherwise pretty standard. -*/ -/mob/living/carbon/human/UnarmedAttack(atom/A, proximity) - // Special glove functions: - // If the gloves do anything, have them return 1 to stop - // normal attack_hand() here. - var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines - if(proximity && istype(G) && G.Touch(A, 1)) - return - - if(HAS_TRAIT(src, TRAIT_HULK)) - if(proximity) //no telekinetic hulk attack - if(A.attack_hulk(src)) - return - - if(buckled && isstructure(buckled)) - var/obj/structure/S = buckled - if(S.prevents_buckled_mobs_attacking()) - return - - if(SEND_SIGNAL(A, COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY, src) & COMPONENT_CANCEL_ATTACK_CHAIN) - return - - A.attack_hand(src) - -/atom/proc/attack_hand(mob/user as mob) - if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, user) & COMPONENT_CANCEL_ATTACK_CHAIN) - return TRUE - -/* -/mob/living/carbon/human/RestrainedClickOn(atom/A) -- Handled by carbons - return -*/ - -/mob/living/carbon/RestrainedClickOn(atom/A) - return 0 - -/mob/living/carbon/human/RangedAttack(atom/A, params) - . = ..() - if(.) - return - if(gloves) - var/obj/item/clothing/gloves/G = gloves - if(istype(G) && G.Touch(A, 0)) // for magic gloves - return - - if(HAS_TRAIT(src, TRAIT_LASEREYES) && a_intent == INTENT_HARM) - LaserEyes(A) - - if(HAS_TRAIT(src, TRAIT_TELEKINESIS) && telekinesis_range_check(src, A)) - A.attack_tk(src) - - if(isturf(A) && get_dist(src, A) <= 1) - Move_Pulled(A) -/* - Animals & All Unspecified -*/ -/mob/living/UnarmedAttack(atom/A) - A.attack_animal(src) - -/mob/living/simple_animal/hostile/UnarmedAttack(atom/A) - target = A - AttackingTarget() - -/atom/proc/attack_animal(mob/user) - return - -/mob/living/RestrainedClickOn(atom/A) - return - -/* - Aliens - Defaults to same as monkey in most places -*/ -/mob/living/carbon/alien/UnarmedAttack(atom/A) - A.attack_alien(src) - -/atom/proc/attack_alien(mob/living/carbon/alien/user) - attack_hand(user) - -/mob/living/carbon/alien/RestrainedClickOn(atom/A) - return - -// Babby aliens -/mob/living/carbon/alien/larva/UnarmedAttack(atom/A) - A.attack_larva(src) - -/atom/proc/attack_larva(mob/user) - return - - -/* - Slimes - Nothing happening here -*/ -/mob/living/simple_animal/slime/UnarmedAttack(atom/A) - A.attack_slime(src) - -/atom/proc/attack_slime(mob/user) - return - -/mob/living/simple_animal/slime/RestrainedClickOn(atom/A) - return - -/* - New Players: - Have no reason to click on anything at all. -*/ -/mob/new_player/ClickOn() - return - -/mob/new_player/can_use_clickbinds() - return FALSE - -// pAIs are not intended to interact with anything in the world -/mob/living/silicon/pai/UnarmedAttack(atom/A) - return diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm deleted file mode 100644 index 90ef75e9d927f..0000000000000 --- a/code/_onclick/telekinesis.dm +++ /dev/null @@ -1,210 +0,0 @@ -/* - Telekinesis - - This needs more thinking out, but I might as well. -*/ -#define TK_MAXRANGE 15 -#define TK_COOLDOWN 1.5 SECONDS -/* - Telekinetic attack: - - By default, emulate the user's unarmed attack -*/ -/atom/proc/attack_tk(mob/user) - if(user.stat) - return - user.UnarmedAttack(src,0) // attack_hand, attack_paw, etc - return - -/* - Returns: True if the target is within the 15 tile range of telekinesis and on the same z-level, false otherwise. -*/ -/proc/telekinesis_range_check(mob/living/carbon/human/user, atom/target) - return (get_dist(user, target) <= TK_MAXRANGE && user.z == target.z) - -/* - This is similar to item attack_self, but applies to anything - that you can grab with a telekinetic grab. - - It is used for manipulating things at range, for example, opening and closing closets. - There are not a lot of defaults at this time, add more where appropriate. -*/ -/atom/proc/attack_self_tk(mob/user) - return - -/obj/attack_tk(mob/user) - if(user.stat) - return - if(anchored) - ..() - return - - var/obj/item/tk_grab/O = new(src) - O.form_grab(user, src) - -/obj/item/attack_tk(mob/user) - if(user.stat || !isturf(loc)) - return - if(HAS_TRAIT(user, TRAIT_TELEKINESIS) && !user.get_active_hand()) // both should already be true to get here - var/obj/item/tk_grab/O = new(src) - O.form_grab(user, src) - else - warning("Strange attack_tk(): TK([user.dna?.GetSEState(GLOB.teleblock)]) empty hand([!user.get_active_hand()])") - - -/mob/attack_tk(mob/user) - return // needs more thinking about - -/* - TK Grab Item (the workhorse of old TK) - - * If you have not grabbed something, do a normal tk attack - * If you have something, throw it at the target. If it is already adjacent, do a normal attackby(, params) - * If you click what you are holding, or attack_self(), do an attack_self_tk() on it. - * Deletes itself if it is ever not in your hand, or if you should have no access to TK. -*/ -/obj/item/tk_grab - name = "Telekinetic Grab" - desc = "Magic." - icon = 'icons/obj/magic.dmi'//Needs sprites - icon_state = "2" - flags = NOBLUDGEON | ABSTRACT | DROPDEL - //item_state = null - w_class = WEIGHT_CLASS_GIGANTIC - layer = ABOVE_HUD_LAYER - plane = ABOVE_HUD_PLANE - - blocks_emissive = FALSE - var/last_throw = 0 - var/atom/movable/focus = null - var/mob/living/host = null - -/obj/item/tk_grab/Destroy() - if(focus) - release_object() - // Focus is null now - host = null - return ..() - -/obj/item/tk_grab/dropped(mob/user) - if(focus && user && loc != user && loc != user.loc) // drop_item() gets called when you tk-attack a table/closet with an item - if(focus.Adjacent(loc)) - focus.forceMove(loc) - . = ..() - - - //stops TK grabs being equipped anywhere but into hands -/obj/item/tk_grab/equipped(mob/user, slot) - if(slot & ITEM_SLOT_BOTH_HANDS) - return - qdel(src) - - -/obj/item/tk_grab/attack_self__legacy__attackchain(mob/user) - if(focus) - focus.attack_self_tk(user) - -/obj/item/tk_grab/override_throw(mob/user, atom/target) - afterattack__legacy__attackchain(target, user) - return TRUE - -/obj/item/tk_grab/afterattack__legacy__attackchain(atom/target , mob/living/user, proximity, params) - if(!target || !user) - return - if(last_throw + TK_COOLDOWN > world.time) - return - if(!host || host != user) - qdel(src) - return - if(!HAS_TRAIT(host, TRAIT_TELEKINESIS)) - qdel(src) - return - if(isobj(target) && !isturf(target.loc)) - return - - var/d = get_dist(user, target) - if(focus) - d = max(d,get_dist(user,focus)) // whichever is further - if(d > TK_MAXRANGE || user.z != target.z) - to_chat(user, "Your mind won't reach that far.") - return - - if(!focus) - focus_object(target, user) - return - - if(target == focus) - target.attack_self_tk(user) - return // todo: something like attack_self not laden with assumptions inherent to attack_self - - - if(isitem(focus) && target.Adjacent(focus) && !user.in_throw_mode) - var/obj/item/I = focus - var/resolved = target.attackby__legacy__attackchain(I, user, params) - if(!resolved && target && I) - I.afterattack__legacy__attackchain(target,user,1) // for splashing with beakers - - - else - if(focus.buckled_mobs) - to_chat(user, "This object is too heavy to move with something buckled to it!") - return - if(length(focus.client_mobs_in_contents)) - to_chat(user, "This object is too heavy to move with something inside of it!") - return - apply_focus_overlay() - focus.throw_at(target, 10, 1, user) - last_throw = world.time - -/obj/item/tk_grab/attack__legacy__attackchain(mob/living/M, mob/living/user, def_zone) - return - -/obj/item/tk_grab/is_equivalent(obj/item/I) - . = ..() - if(!.) - return I == focus - -/obj/item/tk_grab/proc/focus_object(obj/target, mob/user) - if(!isobj(target)) - return//Cant throw non objects atm might let it do mobs later - if(target.anchored || !isturf(target.loc)) - qdel(src) - return - focus = target - update_icon(UPDATE_OVERLAYS) - apply_focus_overlay() - // Make it behave like other equipment - if(isitem(target)) - if(target in user.tkgrabbed_objects) - // Release the old grab first - user.drop_item_to_ground(user.tkgrabbed_objects[target]) - user.tkgrabbed_objects[target] = src - -/obj/item/tk_grab/proc/release_object() - if(!focus) - return - if(isitem(focus)) - // Delete the key/value pair of item to TK grab - host.tkgrabbed_objects -= focus - focus = null - update_icon(UPDATE_OVERLAYS) - -/obj/item/tk_grab/proc/apply_focus_overlay() - if(!focus) - return - new /obj/effect/temp_visual/telekinesis(get_turf(focus)) - -/obj/item/tk_grab/proc/form_grab(mob/user, obj/target) - user.put_in_active_hand(src) - host = user - focus_object(target, user) - - -/obj/item/tk_grab/update_overlays() - . = ..() - if(focus && focus.icon && focus.icon_state) - . += icon(focus.icon,focus.icon_state) - -#undef TK_COOLDOWN - -#undef TK_MAXRANGE diff --git a/code/controllers/configuration/sections/database_configuration.dm b/code/controllers/configuration/sections/database_configuration.dm deleted file mode 100644 index 73a396c9e29e4..0000000000000 --- a/code/controllers/configuration/sections/database_configuration.dm +++ /dev/null @@ -1,43 +0,0 @@ -/// Config holder for all database related things -/datum/configuration_section/database_configuration - protection_state = PROTECTION_PRIVATE // NO! BAD! - /// SQL enabled or not - var/enabled = FALSE - /// What SQL version are we on - var/version = 0 - /// Address of the SQL server - var/address = "127.0.0.1" - /// Port of the SQL server - var/port = 3306 - /// SQL usename - var/username = "root" - /// SQL password - var/password = "root" // Dont do this in prod. Please...... - /// Database name - var/db = "paradise_gamedb" - /// Time in seconds for async queries to time out - var/async_query_timeout = 10 - /// Thread limit for async queries - var/async_thread_limit = 50 - -/datum/configuration_section/database_configuration/load_data(list/data) - // UNIT TESTS ARE DEFINED - USE CUSTOM CI VALUES - #ifdef GAME_TESTS - - enabled = TRUE - // This needs to happen in the CI environment to ensure the example SQL version gets updated. - CONFIG_LOAD_NUM(version, data["sql_version"]) - - #else - // Load the normal config. Were not in CI mode - // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line - CONFIG_LOAD_BOOL(enabled, data["sql_enabled"]) - CONFIG_LOAD_NUM(version, data["sql_version"]) - CONFIG_LOAD_STR(address, data["sql_address"]) - CONFIG_LOAD_NUM(port, data["sql_port"]) - CONFIG_LOAD_STR(username, data["sql_username"]) - CONFIG_LOAD_STR(password, data["sql_password"]) - CONFIG_LOAD_STR(db, data["sql_database"]) - CONFIG_LOAD_NUM(async_query_timeout, data["async_query_timeout"]) - CONFIG_LOAD_NUM(async_thread_limit, data["async_thread_limit"]) - #endif diff --git a/code/controllers/configuration/sections/redis_configuration.dm b/code/controllers/configuration/sections/redis_configuration.dm deleted file mode 100644 index b418441e7f992..0000000000000 --- a/code/controllers/configuration/sections/redis_configuration.dm +++ /dev/null @@ -1,20 +0,0 @@ -/// Config holder for all redis related things -/datum/configuration_section/redis_configuration - protection_state = PROTECTION_PRIVATE // NO! BAD! - /// Redis enabled or not - var/enabled = FALSE - /// Redis connection string. Includes passphrase if needed. - var/connstring = "redis://127.0.0.1/" - -/datum/configuration_section/redis_configuration/load_data(list/data) - // UNIT TESTS ARE DEFINED - USE CUSTOM CI VALUES - #ifdef GAME_TESTS - - // enabled = TRUE - - #else - // Load the normal config. Were not in CI mode - // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line - CONFIG_LOAD_BOOL(enabled, data["redis_enabled"]) - CONFIG_LOAD_STR(connstring, data["redis_connstring"]) - #endif diff --git a/code/controllers/subsystem/SSchat.dm b/code/controllers/subsystem/SSchat.dm deleted file mode 100644 index f76d4467d0d05..0000000000000 --- a/code/controllers/subsystem/SSchat.dm +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT - */ - -SUBSYSTEM_DEF(chat) - name = "Chat" - flags = SS_TICKER|SS_NO_INIT - wait = 1 - priority = FIRE_PRIORITY_CHAT - init_order = INIT_ORDER_CHAT - offline_implications = "Chat will no longer function correctly. Immediate server restart recommended." - - /// Associates a ckey with a list of messages to send to them. - var/list/list/datum/chat_payload/client_to_payloads = list() - - /// Associates a ckey with an associative list of their last CHAT_RELIABILITY_HISTORY_SIZE messages. - var/list/list/datum/chat_payload/client_to_reliability_history = list() - - /// Associates a ckey with their next sequence number. - var/list/client_to_sequence_number = list() - -/datum/controller/subsystem/chat/proc/generate_payload(client/target, message_data) - var/sequence = client_to_sequence_number[target.ckey] - client_to_sequence_number[target.ckey] += 1 - - var/datum/chat_payload/payload = new - payload.sequence = sequence - payload.content = message_data - - if(!(target.ckey in client_to_reliability_history)) - client_to_reliability_history[target.ckey] = list() - var/list/client_history = client_to_reliability_history[target.ckey] - client_history["[sequence]"] = payload - - if(length(client_history) > CHAT_RELIABILITY_HISTORY_SIZE) - var/oldest = text2num(client_history[1]) - for(var/index in 2 to length(client_history)) - var/test = text2num(client_history[index]) - if(test < oldest) - oldest = test - client_history -= "[oldest]" - return payload - -/datum/controller/subsystem/chat/proc/send_payload_to_client(client/target, datum/chat_payload/payload) - target.tgui_panel.window.send_message("chat/message", payload.into_message()) - SEND_TEXT(target, payload.get_content_as_html()) - -/datum/controller/subsystem/chat/fire() - for(var/ckey in client_to_payloads) - var/client/target = GLOB.directory[ckey] - if(isnull(target)) // verify client still exists - LAZYREMOVE(client_to_payloads, ckey) - continue - - for(var/datum/chat_payload/payload as anything in client_to_payloads[ckey]) - send_payload_to_client(target, payload) - LAZYREMOVE(client_to_payloads, ckey) - - if(MC_TICK_CHECK) - return - -/datum/controller/subsystem/chat/proc/queue(queue_target, list/message_data) - var/list/targets = islist(queue_target) ? queue_target : list(queue_target) - for(var/target in targets) - var/client/client = CLIENT_FROM_VAR(target) - if(isnull(client)) - continue - LAZYADDASSOCLIST(client_to_payloads, client.ckey, generate_payload(client, message_data)) - -/datum/controller/subsystem/chat/proc/send_immediate(send_target, list/message_data) - var/list/targets = islist(send_target) ? send_target : list(send_target) - for(var/target in targets) -#ifdef GAME_TESTS - var/mob/M = target - if(istype(M) && M?:mind?:key == "interaction_test_[M.UID()]") - LAZYADD(GLOB.game_test_chats[M.mind.key], message_to_html(message_data)) -#endif - var/client/client = CLIENT_FROM_VAR(target) - if(isnull(client)) - continue - send_payload_to_client(client, generate_payload(client, message_data)) - -/datum/controller/subsystem/chat/proc/handle_resend(client/client, sequence) - var/list/client_history = client_to_reliability_history[client.ckey] - sequence = "[sequence]" - if(isnull(client_history) || !(sequence in client_history)) - return - - var/datum/chat_payload/payload = client_history[sequence] - if(payload.resends > CHAT_RELIABILITY_MAX_RESENDS) - return // we tried but byond said no - - payload.resends += 1 - send_payload_to_client(client, client_history[sequence]) - SSblackbox.record_feedback( - "nested tally", - "chat_resend_byond_version", - 1, - list( - "[client.byond_version]", - "[client.byond_build]", - ), - ) diff --git a/code/controllers/subsystem/SSdbcore.dm b/code/controllers/subsystem/SSdbcore.dm deleted file mode 100644 index 9974e20ccbb96..0000000000000 --- a/code/controllers/subsystem/SSdbcore.dm +++ /dev/null @@ -1,522 +0,0 @@ -SUBSYSTEM_DEF(dbcore) - name = "Database" - flags = SS_BACKGROUND - wait = 1 MINUTES - init_order = INIT_ORDER_DBCORE - cpu_display = SS_CPUDISPLAY_LOW - - /// Is the DB schema valid - var/schema_valid = TRUE - /// Timeout of failed connections - var/failed_connection_timeout = 0 - /// Amount of failed connections - var/failed_connections = 0 - - /// Last error to occur - var/last_error - /// List of currenty processing queries - var/list/active_queries = list() - - /// SQL errors that have occured mid round - var/total_errors = 0 - - /// Connection handle. This is an arbitrary handle returned from rust_g. - var/connection - - offline_implications = "The server will no longer check for undeleted SQL Queries. No immediate action is needed." - -/datum/controller/subsystem/dbcore/get_stat_details() - return "A: [length(active_queries)]" - -// This is in Initialize() so that its actually seen in chat -/datum/controller/subsystem/dbcore/Initialize() - if(!schema_valid) - log_startup_progress("Database schema ([GLOB.configuration.database.version]) doesn't match the latest schema version ([SQL_VERSION]). Roundstart has been delayed.") - - -/datum/controller/subsystem/dbcore/fire() - for(var/I in active_queries) - var/datum/db_query/Q = I - if(world.time - Q.last_activity_time > 5 MINUTES) - log_debug("Found undeleted query, please check the server logs and notify coders.") - log_sql("Undeleted query: \"[Q.sql]\" LA: [Q.last_activity] LAT: [Q.last_activity_time]") - qdel(Q) - if(MC_TICK_CHECK) - return - -/datum/controller/subsystem/dbcore/Recover() - connection = SSdbcore.connection - -//nu -/datum/controller/subsystem/dbcore/can_vv_get(var_name) - return var_name != NAMEOF(src, connection) && var_name != NAMEOF(src, active_queries) && ..() - -/datum/controller/subsystem/dbcore/vv_edit_var(var_name, var_value) - if(var_name == NAMEOF(src, connection)) - return FALSE - return ..() - -/** - * Connection Creator - * - * This proc basically does a few sanity checks before connecting, then attempts to make a connection - * When connecting, RUST_G will initialize a thread pool for queries to use to run asynchronously - */ -/datum/controller/subsystem/dbcore/proc/Connect() - if(IsConnected()) - return TRUE - - if(!GLOB.configuration.database.enabled) - return FALSE - - if(failed_connection_timeout <= world.time) //it's been more than 5 seconds since we failed to connect, reset the counter - failed_connections = 0 - - if(failed_connections > 5) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect for 5 seconds. - failed_connection_timeout = world.time + 50 - return FALSE - - var/result = json_decode(rustg_sql_connect_pool(json_encode(list( - "host" = GLOB.configuration.database.address, - "port" = GLOB.configuration.database.port, - "user" = GLOB.configuration.database.username, - "pass" = GLOB.configuration.database.password, - "db_name" = GLOB.configuration.database.db, - "read_timeout" = GLOB.configuration.database.async_query_timeout, - "write_timeout" = GLOB.configuration.database.async_query_timeout, - "max_threads" = GLOB.configuration.database.async_thread_limit, - )))) - . = (result["status"] == "ok") - if(.) - connection = result["handle"] - else - connection = null - last_error = result["data"] - log_sql("Connect() failed | [last_error]") - ++failed_connections - -/** - * Schema Version Checker - * - * Basically verifies that the DB schema in the config is the same as the version the game is expecting. - * If it is a valid version, the DB will then connect. - */ -/datum/controller/subsystem/dbcore/proc/CheckSchemaVersion() - if(GLOB.configuration.database.enabled) - // The unit tests have their own version of this check, which wont hold the server up infinitely, so this is disabled if we are running unit tests - #ifndef GAME_TESTS - if(GLOB.configuration.database.enabled && GLOB.configuration.database.version != SQL_VERSION) - GLOB.configuration.database.enabled = FALSE - schema_valid = FALSE - SSticker.ticker_going = FALSE - SEND_TEXT(world.log, "Database connection failed: Invalid SQL Versions") - return FALSE - #endif - if(Connect()) - SEND_TEXT(world.log, "Database connection established") - else - // log_sql() because then an error will be logged in the same place - log_sql("Your server failed to establish a connection with the database") - else - SEND_TEXT(world.log, "Database is not enabled in configuration") - -/** - * Disconnection Handler - * - * Tells the DLL to clean up any open connections. - * This will also reset the failed connection counter - */ -/datum/controller/subsystem/dbcore/proc/Disconnect() - failed_connections = 0 - if(connection) - rustg_sql_disconnect_pool(connection) - connection = null - -/** - * Shutdown Handler - * - * Called during world/Reboot() as part of the MC shutdown - * Finalises a round in the DB before disconnecting. - */ -/datum/controller/subsystem/dbcore/Shutdown() - //This is as close as we can get to the true round end before Disconnect() without changing where it's called, defeating the reason this is a subsystem - if(SSdbcore.Connect()) - var/datum/db_query/query_round_shutdown = SSdbcore.NewQuery( - "UPDATE round SET shutdown_datetime = Now(), end_state = :end_state WHERE id = :round_id", - list("end_state" = SSticker.end_state, "round_id" = GLOB.round_id) - ) - query_round_shutdown.Execute() - qdel(query_round_shutdown) - if(IsConnected()) - Disconnect() - -/** - * Round ID Setter - * - * Called during world/New() at the earliest point - * Declares a round ID in the database and assigns it to a global. Also ensures that server address and ports are set - */ -/datum/controller/subsystem/dbcore/proc/SetRoundID() - if(!IsConnected()) - return - var/datum/db_query/query_round_initialize = SSdbcore.NewQuery( - "INSERT INTO round (initialize_datetime, server_ip, server_port, server_id) VALUES (Now(), INET_ATON(:internet_address), :port, :server_id)", - list("internet_address" = world.internet_address || "0", "port" = "[world.port]", "server_id" = GLOB.configuration.system.instance_id) - ) - query_round_initialize.Execute(async = FALSE) - GLOB.round_id = "[query_round_initialize.last_insert_id]" - qdel(query_round_initialize) - -/** - * Round End Time Setter - * - * Called during SSticker.setup() - * Sets the time that the round started in the DB - */ -/datum/controller/subsystem/dbcore/proc/SetRoundStart() - if(!IsConnected()) - return - var/datum/db_query/query_round_start = SSdbcore.NewQuery( - "UPDATE round SET start_datetime=NOW(), commit_hash=:hash WHERE id=:round_id", - list("hash" = GLOB.revision_info.commit_hash, "round_id" = GLOB.round_id) - ) - query_round_start.Execute(async = FALSE) // This happens during a time of intense server lag, so should be non-async - qdel(query_round_start) - -/** - * Round End Time Setter - * - * Called during SSticker.declare_completion() - * Sets the time that the round ended in the DB, as well as some other params - */ -/datum/controller/subsystem/dbcore/proc/SetRoundEnd() - if(!IsConnected()) - return - var/datum/db_query/query_round_end = SSdbcore.NewQuery( - "UPDATE round SET end_datetime = Now(), game_mode_result = :game_mode_result WHERE id = :round_id", - list("game_mode_result" = SSticker.mode_result, "station_name" = station_name(), "round_id" = GLOB.round_id) - ) - query_round_end.Execute() - qdel(query_round_end) - -/** - * IsConnected Helper - * - * Short helper to check if the DB is connected or not. - * Does a few sanity checks, then asks the DLL if we are properly connected - */ -/datum/controller/subsystem/dbcore/proc/IsConnected() - if(!GLOB.configuration.database.enabled) - return FALSE - if(!schema_valid) - return FALSE - if(!connection) - return FALSE - return json_decode(rustg_sql_connected(connection))["status"] == "online" - - -/** - * Error Message Helper - * - * Returns the last error that the subsystem encountered. - * Will always report "Database disabled by configuration" if the DB is disabled. - */ -/datum/controller/subsystem/dbcore/proc/ErrorMsg() - if(!GLOB.configuration.database.enabled) - return "Database disabled by configuration" - return last_error - -/** - * Error Reporting Helper - * - * Pretty much just sets `last_error` to the error argument - * - * Arguments: - * * error - Error text to set `last_error` to - */ -/datum/controller/subsystem/dbcore/proc/ReportError(error) - last_error = error - - -/** - * New Query Invoker - * - * Checks to make sure this query isnt being invoked by admin fuckery, then returns a new [/datum/db_query] - * - * Arguments: - * * sql_query - SQL query to be ran, with :parameter placeholders - * * arguments - Associative list of parameters to be inserted into the query - */ -/datum/controller/subsystem/dbcore/proc/NewQuery(sql_query, arguments) - if(IsAdminAdvancedProcCall()) - to_chat(usr, "DB query blocked: Advanced ProcCall detected.") - message_admins("[key_name(usr)] attempted to create a DB query via advanced proc-call") - log_admin("[key_name(usr)] attempted to create a DB query via advanced proc-call") - return FALSE - return new /datum/db_query(connection, sql_query, arguments) - -/** - * Handler to allow many queries to be executed en masse - * - * Feed this proc a list of queries and it will execute them all at once, by the power of async magic! - * - * Arguments: - * * querys - List of queries to execute - * * warn - Boolean to warn on query failure - * * qdel - Boolean to enable auto qdel of queries - * * assoc - Boolean to enable support for an associative list of queries - * * log - Do we want to generate logs for these queries - */ -/datum/controller/subsystem/dbcore/proc/MassExecute(list/querys, warn = FALSE, qdel = FALSE, assoc = FALSE, log = TRUE) - if(!islist(querys)) - if(!istype(querys, /datum/db_query)) - CRASH("Invalid query passed to MassExecute: [querys]") - querys = list(querys) - - var/start_time = start_watch() - if(log) - log_debug("Mass executing [length(querys)] queries...") - - for(var/thing in querys) - var/datum/db_query/query - if(assoc) - query = querys[thing] - else - query = thing - if(warn) - INVOKE_ASYNC(query, TYPE_PROC_REF(/datum/db_query, warn_execute)) - else - INVOKE_ASYNC(query, TYPE_PROC_REF(/datum/db_query, Execute)) - - for(var/thing in querys) - var/datum/db_query/query - if(assoc) - query = querys[thing] - else - query = thing - UNTIL(!query.in_progress) - if(qdel) - qdel(query) - - if(log) - log_debug("Executed [length(querys)] queries in [stop_watch(start_time)]s") - -/** - * # db_query - * - * Datum based handler for all database queries - * - * Holds information regarding inputs, status, and outputs - */ -/datum/db_query - // Inputs - /// The connection being used with this query - var/connection - /// The SQL statement being executed with :parameter placeholders - var/sql - /// An associative list of parameters to be substituted into the statement - var/arguments - - // Status information - /// Is the query currently in progress - var/in_progress - /// What was our last error, if any - var/last_error - /// What was our last activity - var/last_activity - /// When was our last activity - var/last_activity_time - - // Output - /// List of all rows returned - var/list/list/rows - /// Counter of the next row to take - var/next_row_to_take = 1 - /// How many rows were affected by the query - var/affected - /// ID of the last inserted row - var/last_insert_id - /// List of data values populated by NextRow() - var/list/item - -// Sets up some vars and throws it into the SS active query list -/datum/db_query/New(connection, sql, arguments) - SSdbcore.active_queries[src] = TRUE - Activity("Created") - item = list() - - src.connection = connection - src.sql = sql - src.arguments = arguments - -// Takes it out of the active query list, as well as closing it up -/datum/db_query/Destroy() - Close() - SSdbcore.active_queries -= src - return ..() - -/datum/db_query/CanProcCall(proc_name) - // go away - return FALSE - - -/** - * Activity Update Handler - * - * Sets the last activity text to the argument input, as well as updating the activity time - * - * Arguments: - * * activity - Last activity text - */ -/datum/db_query/proc/Activity(activity) - last_activity = activity - last_activity_time = world.time - -/** - * Wrapped for warning on execution - * - * You should use this proc when running the SQL statement. It will auto inform the user and the online admins if a query fails - * - * Arguments: - * * async - Are we running this query asynchronously - * * log_error - Do we want to log errors this creates? Disable this if you are running sensitive queries where you dont want errors logged in plain text (EG: Auth token stuff) - */ -/datum/db_query/proc/warn_execute(async = TRUE, log_error = TRUE) - if(!GLOB.configuration.database.enabled) - return - . = Execute(async, log_error) - if(!.) - SSdbcore.total_errors++ - if(usr) - to_chat(usr, "A SQL error occurred during this operation, please inform an admin or a coder.", MESSAGE_TYPE_ADMINLOG, confidential = TRUE) - message_admins("An SQL error has occurred. Please check the server logs, with the following timestamp ID: \[[time_stamp()]]") - -/** - * Main Execution Handler - * - * Invoked by [warn_execute()] - * This handles query error logging, as well as invoking the actual runner - * Arguments: - * * async - Are we running this query asynchronously - * * log_error - Do we want to log errors this creates? Disable this if you are running sensitive queries where you dont want errors logged in plain text (EG: Auth token stuff) - */ -/datum/db_query/proc/Execute(async = TRUE, log_error = TRUE) - Activity("Execute") - if(in_progress) - CRASH("Attempted to start a new query while waiting on the old one") - - if(!SSdbcore.IsConnected()) - last_error = "No connection!" - return FALSE - - var/start_time - if(!async) - start_time = REALTIMEOFDAY - Close() - . = run_query(async) - var/timed_out = !. && findtext(last_error, "Operation timed out") - if(!. && log_error) - log_sql("[last_error] | Query used: [sql] | Arguments: [json_encode(arguments)]") - if(!async && timed_out) - log_sql("Query execution started at [start_time]") - log_sql("Query execution ended at [REALTIMEOFDAY]") - log_sql("Slow query timeout detected.") - log_sql("Query used: [sql]") - slow_query_check() - -/** - * Actual Query Runner - * - * This does the main query with the database and the rust calls themselves - * - * Arguments: - * * async - Are we running this query asynchronously - */ -/datum/db_query/proc/run_query(async) - var/job_result_str - - if(async) - var/job_id = rustg_sql_query_async(connection, sql, json_encode(arguments)) - in_progress = TRUE - UNTIL((job_result_str = rustg_sql_check_query(job_id)) != RUSTG_JOB_NO_RESULTS_YET) - in_progress = FALSE - - if(job_result_str == RUSTG_JOB_ERROR) - last_error = job_result_str - return FALSE - else - job_result_str = rustg_sql_query_blocking(connection, sql, json_encode(arguments)) - - var/result = json_decode(job_result_str) - switch(result["status"]) - if("ok") - rows = result["rows"] - affected = result["affected"] - last_insert_id = result["last_insert_id"] - return TRUE - if("err") - last_error = result["data"] - return FALSE - if("offline") - last_error = "offline" - return FALSE - -// Just tells the admins if a query timed out, and asks if the server hung to help error reporting -/datum/db_query/proc/slow_query_check() - message_admins("HEY! A database query timed out. Did the server just hang? \[YES\]|\[NO\]") - - -/** - * Proc to get the next row in a DB query - * - * Cycles `item` to the next row in the DB query, if multiple were fetched - */ -/datum/db_query/proc/NextRow() - Activity("NextRow") - - if(rows && next_row_to_take <= length(rows)) - item = rows[next_row_to_take] - next_row_to_take++ - return !!item - else - return FALSE - -// Simple helper to get the last error a query had -/datum/db_query/proc/ErrorMsg() - return last_error - -// Simple proc to null out data to aid GC -/datum/db_query/proc/Close() - rows = null - item = null - -// Verb that lets admins force reconnect the DB -/client/proc/reestablish_db_connection() - set category = "Debug" - set name = "Reestablish DB Connection" - if(!GLOB.configuration.database.enabled) - to_chat(usr, "The Database is not enabled in the server configuration!") - return - - if(SSdbcore.IsConnected()) - if(!check_rights(R_DEBUG, FALSE)) - to_chat(usr, "The database is already connected! (Only those with +DEBUG can force a reconnection)") - return - - var/reconnect = alert("The database is already connected! If you *KNOW* that this is incorrect, you can force a reconnection", "The database is already connected!", "Force Reconnect", "Cancel") - if(reconnect != "Force Reconnect") - return - - SSdbcore.Disconnect() - log_admin("[key_name(usr)] has forced the database to disconnect") - message_admins("[key_name_admin(usr)] has forced the database to disconnect!!!") - - log_admin("[key_name(usr)] is attempting to re-establish the DB Connection") - message_admins("[key_name_admin(usr)] is attempting to re-establish the DB Connection") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Force Reconnect DB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - SSdbcore.failed_connections = 0 // Reset this - if(!SSdbcore.Connect()) - message_admins("Database connection failed: [SSdbcore.ErrorMsg()]") - else - message_admins("Database connection re-established") diff --git a/code/controllers/subsystem/SSdebugview.dm b/code/controllers/subsystem/SSdebugview.dm deleted file mode 100644 index 437d544f01c61..0000000000000 --- a/code/controllers/subsystem/SSdebugview.dm +++ /dev/null @@ -1,93 +0,0 @@ -SUBSYSTEM_DEF(debugview) - name = "Debug View" - wait = 1 // SS_TICKER subsystem, so wait is in ticks - flags = SS_TICKER|SS_NO_INIT - offline_implications = "Shift+F3 will no longer show a debug view. No immediate action is needed." - cpu_display = SS_CPUDISPLAY_LOW - /// List of clients currently processing - var/list/client/processing = list() - -/datum/controller/subsystem/debugview/fire(resumed) - // Dont generate text if no one is there to look at it - if(!length(processing)) - return - - // Generate debug text - var/list/entries = list() - entries += "CPU: [round(world.cpu, 1)] | MCPU: [round(world.map_cpu, 1)] | FPS/TPS: [world.fps] | Clients: [length(GLOB.clients)] | BYOND: [world.byond_version].[world.byond_build]" - entries += "\[Air] Cost: [SSair.get_cost()]ms | MT: [round(SSair.cost_milla_tick, 1)]ms | IT: [SSair.interesting_tile_count] | HS: [SSair.hotspot_count] | WT: [SSair.windy_tile_count]" - entries += "\[Debug] Cost: [round(SSdebugview.cost, 1)]ms | P: [length(SSdebugview.processing)]" // meta af (tbf we need to know how much were using) - entries += "\[FP] Cost: [round(SSfastprocess.cost, 1)]ms | P: [length(SSfastprocess.processing)]" - // Snowflakery for SSgarbage - var/list/counts = list() - for(var/list/L in SSgarbage.queues) - counts += length(L) - entries += "\[GC] Cost: [round(SSgarbage.cost, 1)]ms | Q: [counts.Join(",")] H: [SSgarbage.delslasttick] | S: [SSgarbage.gcedlasttick]" - entries += "\[Input] Cost: [round(SSinput.cost, 1)]ms" - entries += "\[Lighting] Cost: [round(SSlighting.cost, 1)]ms | SQ: [length(SSlighting.sources_queue)] | CQ: [length(SSlighting.corners_queue)] | OQ: [length(SSlighting.objects_queue)]" - entries += "\[Machines] Cost: [round(SSmachines.cost, 1)]ms | M: [length(SSmachines.processing)] | P: [length(SSmachines.powernets)]" - entries += "\[Mobs] Cost: [round(SSmobs.cost, 1)]ms | P: [length(GLOB.mob_living_list)]" - entries += "\[Objects] Cost: [round(SSobj.cost, 1)]ms | P: [length(SSobj.processing)]" - entries += "\[Processing] Cost: [round(SSprocessing.cost, 1)]ms | P: [length(SSprocessing.processing)]" - entries += "\[Projectiles] Cost: [round(SSprojectiles.cost, 1)]ms | P: [length(SSprojectiles.processing)]" - entries += "\[Runechat] Cost: [round(SSrunechat.cost, 1)]ms | AM: [SSrunechat.bucket_count] | SQ: [length(SSrunechat.second_queue)]" - entries += "\[TGUI] Cost: [round(SStgui.cost, 1)]ms | P: [length(SStgui.open_uis)]]" - entries += "\[Timer] Cost: [round(SStimer.cost, 1)]ms | B: [SStimer.bucket_count] | P: [length(SStimer.second_queue)] | RST: [SStimer.bucket_reset_count]" - - // Do some parsing to format it properly - var/out_text = entries.Join("\n") - var/mty = 480 - 9 * length(entries) - - // And update the clients - for(var/client/C as anything in processing) - C.debug_text_overlay.maptext_y = mty - C.debug_text_overlay.maptext = "[out_text]" - -/datum/controller/subsystem/debugview/proc/start_processing(client/C) - C.debug_text_overlay = new /atom/movable/screen/debugtextholder(null, C) - C.screen |= C.debug_text_overlay - processing |= C - -/datum/controller/subsystem/debugview/proc/stop_processing(client/C) - processing -= C - C.screen -= C.debug_text_overlay - QDEL_NULL(C.debug_text_overlay) - -/atom/movable/screen/debugtextholder - icon = 'icons/mob/screen_full.dmi' - icon_state = "empty" - screen_loc = "TOP,LEFT" - plane = HUD_PLANE_DEBUGVIEW - maptext_height = 480 // 15 * 32 (15 tiles, 32 pixels each) - maptext_width = 480 // changes with prefs - -/atom/movable/screen/debugtextholder/Initialize(mapload, client/C) - . = ..() - update_view(C) - -/atom/movable/screen/debugtextholder/proc/update_view(client/C) - var/list/viewsizes = getviewsize(C.view) - maptext_width = viewsizes[1] * world.icon_size - -// Make a verb for dumping full SS stats -/client/proc/ss_breakdown() - set name = "SS Info Breakdown" - set category = "Debug" - - if(!check_rights(R_DEBUG|R_VIEWRUNTIMES)) - return - - var/datum/browser/popup = new(usr, "ss_breakdown", "Subsystem Breakdown", 1100, 850) - - var/list/html = list() - html += "CPU: [round(world.cpu, 1)] | MCPU: [round(world.map_cpu, 1)] | FPS/TPS: [world.fps] | Clients: [length(GLOB.clients)] | BYOND: [world.byond_version].[world.byond_build]" - html += "--- SS BREAKDOWN ---" - for(var/datum/controller/subsystem/SS as anything in Master.subsystems) - // We dont care about subsystems that arent firing (or are unable to) - if((SS.flags & SS_NO_FIRE) || !SS.can_fire) - continue - - html += "[SS.state_colour()]\[[SS.state_letter()]][SS.ss_id]
    \t[SS.get_cost()]ms | [round(SS.tick_usage, 1)]% [SS.get_stat_details() ? "| [SS.get_stat_details()] " : ""]| VV Edit" - - popup.set_content(html.Join("
    ")) - popup.open(FALSE) diff --git a/code/controllers/subsystem/SSghost_spawns.dm b/code/controllers/subsystem/SSghost_spawns.dm deleted file mode 100644 index ad1690b7610c5..0000000000000 --- a/code/controllers/subsystem/SSghost_spawns.dm +++ /dev/null @@ -1,324 +0,0 @@ -SUBSYSTEM_DEF(ghost_spawns) - name = "Ghost Spawns" - flags = SS_BACKGROUND | SS_NO_INIT - wait = 1 SECONDS - runlevels = RUNLEVEL_GAME - offline_implications = "Ghosts will no longer be able to respawn as event mobs (Blob, etc..). Shuttle call recommended." - cpu_display = SS_CPUDISPLAY_LOW - - /// List of polls currently ongoing, to be checked on next fire() - var/list/datum/candidate_poll/currently_polling - /// Whether there are active polls or not - var/polls_active = FALSE - /// Number of polls performed since the start - var/total_polls = 0 - /// The poll that's closest to finishing - var/datum/candidate_poll/next_poll_to_finish - -/datum/controller/subsystem/ghost_spawns/fire() - if(!polls_active) - return - if(!currently_polling) // if polls_active is TRUE then this shouldn't happen, but still.. - currently_polling = list() - - for(var/poll in currently_polling) - var/datum/candidate_poll/P = poll - if(P.time_left() <= 0) - polling_finished(P) - -/** - * Polls for candidates with a question and a preview of the role - * - * This proc replaces /proc/pollCandidates. - * Should NEVER be used in a proc that has waitfor set to FALSE/0 (due to #define UNTIL) - * Arguments: - * * question - The question to ask to potential candidates - * * role - The role to poll for. Should be a ROLE_x enum. If set, potential candidates who aren't eligible will be ignored - * * antag_age_check - Whether to filter out potential candidates who don't have an old enough account - * * poll_time - How long to poll for in deciseconds - * * ignore_respawnability - Whether to ignore the player's respawnability - * * min_hours - The amount of hours needed for a potential candidate to be eligible - * * flash_window - Whether the poll should flash a potential candidate's game window - * * check_antaghud - Whether to filter out potential candidates who enabled AntagHUD - * * source - The atom, atom prototype, icon or mutable appearance to display as an icon in the alert - * * role_cleanname - The name override to display to clients - */ -/datum/controller/subsystem/ghost_spawns/proc/poll_candidates(question = "Would you like to play a special role?", role, antag_age_check = FALSE, poll_time = 30 SECONDS, ignore_respawnability = FALSE, min_hours = 0, flash_window = TRUE, check_antaghud = TRUE, source, role_cleanname, reason, dont_play_notice_sound = FALSE) - log_debug("Polling candidates [role ? "for [role_cleanname || get_roletext(role)]" : "\"[question]\""] for [poll_time / 10] seconds") - - // Start firing - polls_active = TRUE - total_polls++ - - var/datum/candidate_poll/P = new(role, question, poll_time) - LAZYADD(currently_polling, P) - - // We're the poll closest to completion - if(!next_poll_to_finish || poll_time < next_poll_to_finish.time_left()) - next_poll_to_finish = P - - var/category = "[P.hash]_notify_action" - - var/notice_sound = sound('sound/effects/ghost_ping.ogg') - for(var/mob/M in (GLOB.player_list)) - if(!is_eligible(M, role, antag_age_check, role, min_hours, check_antaghud)) - continue - if(!dont_play_notice_sound) - SEND_SOUND(M, notice_sound) - if(flash_window) - window_flash(M.client) - - // If we somehow send two polls for the same mob type, but with a duration on the second one shorter than the time left on the first one, - // we need to keep the first one's timeout rather than use the shorter one - var/atom/movable/screen/alert/notify_action/current_alert = LAZYACCESS(M.alerts, category) - var/alert_time = poll_time - var/alert_poll = P - if(current_alert && current_alert.timeout > (world.time + poll_time - world.tick_lag)) - alert_time = current_alert.timeout - world.time + world.tick_lag - alert_poll = current_alert.poll - - // Send them an on-screen alert - var/atom/movable/screen/alert/notify_action/A = M.throw_alert(category, /atom/movable/screen/alert/notify_action, timeout_override = alert_time, no_anim = TRUE) - if(!A) - continue - - A.icon = ui_style2icon(M.client?.prefs.UI_style) - A.name = "Looking for candidates" - A.desc = "[question]\n\n(expires in [poll_time / 10] seconds)" - A.show_time_left = TRUE - A.poll = alert_poll - - // Sign up inheritance and stacking - var/inherited_sign_up = FALSE - var/num_stack = 1 - for(var/existing_poll in currently_polling) - var/datum/candidate_poll/P2 = existing_poll - if(P != P2 && P.hash == P2.hash) - // If there's already a poll for an identical mob type ongoing and the client is signed up for it, sign them up for this one - if(!inherited_sign_up && (M in P2.signed_up) && P.sign_up(M, TRUE)) - A.update_signed_up_alert(M) - inherited_sign_up = TRUE - // This number is used to display the number of polls the alert regroups - num_stack++ - if(num_stack > 1) - A.display_stacks(num_stack) - - // Image to display - var/image/I - if(source) - if(!ispath(source)) - var/atom/S = source - var/old_layer = S.layer - var/old_plane = S.plane - - S.layer = FLOAT_LAYER - S.plane = FLOAT_PLANE - A.overlays += S - S.layer = old_layer - S.plane = old_plane - else - I = image(source, layer = FLOAT_LAYER, dir = SOUTH) - else - // Just use a generic image - I = image('icons/effects/effects.dmi', icon_state = "static", layer = FLOAT_LAYER, dir = SOUTH) - - if(I) - I.layer = FLOAT_LAYER - I.plane = FLOAT_PLANE - A.overlays += I - - // Chat message - var/act_jump = "" - if(isatom(source)) - act_jump = "\[Teleport]" - var/act_signup = "\[Sign Up]" - to_chat(M, "Now looking for candidates [role ? "to play as \an [role_cleanname || get_roletext(role)]" : "\"[question]\""]. [act_jump] [act_signup] [reason ? "\nReason: [sanitize(reason)]" : ""]", MESSAGE_TYPE_DEADCHAT) - - // Start processing it so it updates visually the timer - START_PROCESSING(SSprocessing, A) - A.process() - - // Sleep until the time is up - UNTIL(P.finished) - if(!ignore_respawnability) - var/list/eligable_mobs = list() - for(var/mob/signed_up in P.signed_up) - if(HAS_TRAIT(signed_up, TRAIT_RESPAWNABLE)) - eligable_mobs += signed_up - return eligable_mobs - else - return P.signed_up - -/** - * Returns whether an observer is eligible to be an event mob - * - * Arguments: - * * M - The mob to check eligibility - * * role - The role to check eligibility for. Checks 1. the client has enabled the role 2. the account's age for this role if antag_age_check is TRUE - * * antag_age_check - Whether to check the account's age or not for the given role. - * * role_text - The role's clean text. Used for checking job bans to determine eligibility - * * min_hours - The amount of minimum hours the client needs before being eligible - * * check_antaghud - Whether to consider a client who enabled AntagHUD ineligible or not - */ -/datum/controller/subsystem/ghost_spawns/proc/is_eligible(mob/M, role, antag_age_check, role_text, min_hours, check_antaghud, ignore_respawnability) - . = FALSE - if(!M.key || !M.client) - return - if(!ignore_respawnability && !HAS_TRAIT(M, TRAIT_RESPAWNABLE)) - return - if(role) - if(!(role in M.client.prefs.be_special)) - return - if(antag_age_check) - if(!player_old_enough_antag(M.client, role)) - return - if(role_text) - if(jobban_isbanned(M, role_text) || jobban_isbanned(M, ROLE_SYNDICATE)) - return - if(GLOB.configuration.jobs.enable_exp_restrictions && min_hours) - if(M.client.get_exp_type_num(EXP_TYPE_LIVING) < min_hours * 60) - return - if(check_antaghud && isobserver(M)) - var/mob/dead/observer/O = M - if(!O.check_ahud_rejoin_eligibility()) - return - - return TRUE - -/** - * Called by the subsystem when a poll's timer runs out - * - * Can be called manually to finish a poll prematurely - * Arguments: - * * P - The poll to finish - */ -/datum/controller/subsystem/ghost_spawns/proc/polling_finished(datum/candidate_poll/P) - // Trim players who aren't eligible anymore - var/len_pre_trim = length(P.signed_up) - P.trim_candidates() - log_debug("Candidate poll [P.role ? "for [get_roletext(P.role)]" : "\"[P.question]\""] finished. [len_pre_trim] players signed up, [length(P.signed_up)] after trimming") - - P.finished = TRUE - currently_polling -= P - - // Determine which is the next poll closest the completion or "disable" firing if there's none - if(!length(currently_polling)) - polls_active = FALSE - next_poll_to_finish = null - else if(P == next_poll_to_finish) - next_poll_to_finish = null - for(var/poll in currently_polling) - var/datum/candidate_poll/P2 = poll - if(!next_poll_to_finish || P2.time_left() < next_poll_to_finish.time_left()) - next_poll_to_finish = P2 - -/datum/controller/subsystem/ghost_spawns/get_stat_details() - var/list/msg = list() - msg += "Active: [length(currently_polling)] | Total: [total_polls]" - if(next_poll_to_finish) - msg += " | Next: [DisplayTimeText(next_poll_to_finish.time_left())] ([length(next_poll_to_finish.signed_up)] candidates)" - return msg.Join("") - -// The datum that describes one instance of candidate polling -/datum/candidate_poll - var/role // The role the poll is for - var/question // The question asked to observers - var/duration // The duration of the poll - var/list/signed_up // The players who signed up to this poll - var/time_started // The world.time at which the poll was created - var/finished = FALSE // Whether the polling is finished - var/hash // Used to categorize in the alerts system - -/datum/candidate_poll/New(polled_role, polled_question, poll_duration) - role = polled_role - question = polled_question - duration = poll_duration - signed_up = list() - time_started = world.time - hash = copytext(md5("[question]_[role ? role : "0"]"), 1, 7) - return ..() - -/** - * Attempts to sign a (controlled) mob up - * - * Will fail if the mob is already signed up or the poll's timer ran out. - * Does not check for eligibility - * Arguments: - * * M - The (controlled) mob to sign up - * * silent - Whether no messages should appear or not. If not TRUE, signing up to this poll will also sign the mob up for identical polls - */ -/datum/candidate_poll/proc/sign_up(mob/M, silent = FALSE) - . = FALSE - if(!HAS_TRAIT(M, TRAIT_RESPAWNABLE) || !M.key || !M.client) - return - if(M in signed_up) - if(!silent) - to_chat(M, "You have already signed up for this!") - return - - if(time_left() <= 0) - if(!silent) - to_chat(M, "Sorry, you were too late for the consideration!") - SEND_SOUND(M, sound('sound/machines/buzz-sigh.ogg')) - return - - signed_up += M - if(!silent) - to_chat(M, "You have signed up for this role! A candidate will be picked randomly soon.") - // Sign them up for any other polls with the same mob type - for(var/existing_poll in SSghost_spawns.currently_polling) - var/datum/candidate_poll/P = existing_poll - if(src != P && hash == P.hash && !(M in P.signed_up)) - P.sign_up(M, TRUE) - - return TRUE - -/** - * Attempts to remove a signed-up mob from a poll. - * - * Arguments: - * * M - The mob to remove from the poll, if present. - * * silent - If TRUE, no messages will be sent to M about their removal. - */ -/datum/candidate_poll/proc/remove_candidate(mob/M, silent = FALSE) - . = FALSE - if(!HAS_TRAIT(M, TRAIT_RESPAWNABLE) || !M.key || !M.client) - return - if(!(M in signed_up)) - if(!silent) - to_chat(M, "You aren't signed up for this!") - return - - if(time_left() <= 0) - if(!silent) - to_chat(M, "It's too late to unregister yourself, selection has already begun!") - return - - signed_up -= M - if(!silent) - to_chat(M, "You have been unregistered as a candidate for this role. You can freely sign up again before the poll ends.") - - for(var/existing_poll in SSghost_spawns.currently_polling) - var/datum/candidate_poll/P = existing_poll - if(src != P && hash == P.hash && (M in P.signed_up)) - P.remove_candidate(M, TRUE) - return TRUE - - - - -/** - * Deletes any candidates who may have disconnected from the list - */ -/datum/candidate_poll/proc/trim_candidates() - listclearnulls(signed_up) - for(var/mob in signed_up) - var/mob/M = mob - if(!M.key || !M.client) - signed_up -= M - -/** - * Returns the time left for a poll - */ -/datum/candidate_poll/proc/time_left() - return duration - (world.time - time_started) diff --git a/code/controllers/subsystem/SSjobs.dm b/code/controllers/subsystem/SSjobs.dm deleted file mode 100644 index 69c38a77817b5..0000000000000 --- a/code/controllers/subsystem/SSjobs.dm +++ /dev/null @@ -1,978 +0,0 @@ -SUBSYSTEM_DEF(jobs) - name = "Jobs" - init_order = INIT_ORDER_JOBS // 12 - wait = 5 MINUTES // Dont ever make this a super low value since EXP updates are calculated from this value - runlevels = RUNLEVEL_GAME - offline_implications = "Job playtime hours will no longer be logged. No immediate action is needed." - cpu_display = SS_CPUDISPLAY_LOW - - //List of all jobs - var/list/occupations = list() - var/list/name_occupations = list() //Dict of all jobs, keys are titles - var/list/type_occupations = list() //Dict of all jobs, keys are types - var/list/prioritized_jobs = list() // List of jobs set to priority by HoP/Captain - var/list/id_change_records = list() // List of all job transfer records - var/probability_of_antag_role_restriction = 100 // Dict probability of a job rolling an antagonist role - var/id_change_counter = 1 - //Players who need jobs - var/list/unassigned = list() - //Debug info - var/list/job_debug = list() - - ///list of station departments and their associated roles and economy payments - var/list/station_departments = list() - /// Do we spawn everyone at shuttle due to late arivals? - var/late_arrivals_spawning = FALSE - /// Do we spawn people drunkenly due to the party last night? - var/drunken_spawning = FALSE - /// A list of minds that have failed to roll antagonist. Cleared when job selection finishes. - var/list/failed_head_antag_roll = list() - -/datum/controller/subsystem/jobs/Initialize() - if(!length(occupations)) - SetupOccupations() - for(var/department_type in subtypesof(/datum/station_department)) - station_departments += new department_type() - LoadJobs(FALSE) - -// Only fires every 5 minutes -/datum/controller/subsystem/jobs/fire() - if(!SSdbcore.IsConnected() || !GLOB.configuration.jobs.enable_exp_tracking) - return - batch_update_player_exp(announce = FALSE) // Set this to true if you ever want to inform players about their EXP gains - -/datum/controller/subsystem/jobs/proc/SetupOccupations(list/faction = list("Station")) - occupations = list() - var/list/all_jobs = subtypesof(/datum/job) - if(!length(all_jobs)) - to_chat(world, "Error setting up jobs, no job datums found.") - return 0 - - for(var/J in all_jobs) - var/datum/job/job = new J() - if(!job) - continue - occupations += job - name_occupations[job.title] = job - type_occupations[J] = job - - return 1 - - -/datum/controller/subsystem/jobs/proc/Debug(text) - job_debug.Add(text) - -/datum/controller/subsystem/jobs/proc/GetJob(rank) - if(!length(occupations)) - SetupOccupations() - return name_occupations[rank] - -/datum/controller/subsystem/jobs/proc/GetJobType(jobtype) - if(!length(occupations)) - SetupOccupations() - return type_occupations[jobtype] - -/datum/controller/subsystem/jobs/proc/GetPlayerAltTitle(mob/new_player/player, rank) - return player.client.prefs.active_character.GetPlayerAltTitle(GetJob(rank)) - -/datum/controller/subsystem/jobs/proc/AssignRole(mob/new_player/player, rank, latejoin = 0) - Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]") - if(player && player.mind && rank) - var/datum/job/job = GetJob(rank) - if(!job) - return FALSE - if(job.job_banned_gamemode) - return FALSE - if(jobban_isbanned(player, rank)) - return FALSE - if(!job.player_old_enough(player.client)) - return FALSE - if(job.get_exp_restrictions(player.client)) - return FALSE - if(job.barred_by_disability(player.client)) - return FALSE - if(job.barred_by_missing_limbs(player.client)) - return FALSE - - var/available = latejoin ? job.is_position_available() : job.is_spawn_position_available() - - if(available) - Debug("Player: [player] is now Rank: [rank], JCP:[job.current_positions], JTP:[job.total_positions], JSP:[job.spawn_positions]") - player.mind.assigned_role = rank - player.mind.role_alt_title = GetPlayerAltTitle(player, rank) - - // JOB OBJECTIVES OH SHIT - player.mind.job_objectives.Cut() - for(var/objectiveType in job.required_objectives) - new objectiveType(player.mind) - - unassigned -= player - job.current_positions++ - SSblackbox.record_feedback("nested tally", "manifest", 1, list(rank, (latejoin ? "latejoin" : "roundstart"))) - return 1 - - Debug("AR has failed, Player: [player], Rank: [rank]") - return 0 - -/datum/controller/subsystem/jobs/proc/FreeRole(rank, force = FALSE) //making additional slot on the fly - var/datum/job/job = GetJob(rank) - if(!job) - return FALSE - if(job.job_banned_gamemode) - if(!force) - return FALSE - job.job_banned_gamemode = FALSE // If admins want to force it, they can reopen banned job slots - - if(job.current_positions >= job.total_positions && job.total_positions != -1) - job.total_positions++ - return TRUE - return FALSE - -/datum/controller/subsystem/jobs/proc/FindOccupationCandidates(datum/job/job, level, flag) - Debug("Running FOC, Job: [job], Level: [level], Flag: [flag]") - var/list/candidates = list() - for(var/mob/new_player/player in unassigned) - Debug(" - Player: [player] Banned: [jobban_isbanned(player, job.title)] Old Enough: [!job.player_old_enough(player.client)] AvInPlaytime: [job.get_exp_restrictions(player.client)] Flag && Be Special: [flag] && [player.client.prefs.be_special] Job Department: [player.client.prefs.active_character.GetJobDepartment(job, level)] Job Flag: [job.flag] Job Department Flag = [job.department_flag]") - if(jobban_isbanned(player, job.title)) - Debug("FOC isbanned failed, Player: [player]") - continue - if(!job.player_old_enough(player.client)) - Debug("FOC player not old enough, Player: [player]") - continue - if(job.get_exp_restrictions(player.client)) - Debug("FOC player not enough playtime, Player: [player]") - continue - if(job.barred_by_disability(player.client)) - Debug("FOC player has disability rendering them ineligible for job, Player: [player]") - continue - if(job.barred_by_missing_limbs(player.client)) - Debug("FOC player has missing limbs rendering them ineligible for job, Player: [player]") - continue - if(flag && !(flag in player.client.prefs.be_special)) - Debug("FOC flag failed, Player: [player], Flag: [flag], ") - continue - if(player.mind && (job.title in player.mind.restricted_roles)) - Debug("FOC incompatbile with antagonist role, Player: [player]") - continue - if(player.client.prefs.active_character.GetJobDepartment(job, level) & job.flag) - if(player.mind.special_role && player.mind && (job.title in SSticker.mode.single_antag_positions)) //We want to check if they want the job, before rolling the prob chance - if((player.mind in SSjobs.failed_head_antag_roll) || !prob(probability_of_antag_role_restriction)) - Debug("FOC Failed probability of getting a second antagonist position in this job, Player: [player], Job:[job.title]") - SSjobs.failed_head_antag_roll |= player.mind - continue - else - probability_of_antag_role_restriction /= 10 - Debug("FOC pass, Player: [player], Level:[level]") - candidates += player - return candidates - -/datum/controller/subsystem/jobs/proc/GiveRandomJob(mob/new_player/player) - Debug("GRJ Giving random job, Player: [player]") - for(var/datum/job/job in shuffle(occupations)) - if(!job) - continue - - if(istype(job, GetJob("Assistant"))) // We don't want to give him assistant, that's boring! - continue - - if(job.title in GLOB.command_positions) //If you want a command position, select it! - continue - - if(job.admin_only) // No admin positions either. - continue - - if(job.mentor_only) // Neither for mentor positions - continue - - if(jobban_isbanned(player, job.title)) - Debug("GRJ isbanned failed, Player: [player], Job: [job.title]") - continue - - if(!job.player_old_enough(player.client)) - Debug("GRJ player not old enough, Player: [player]") - continue - - if(job.get_exp_restrictions(player.client)) - Debug("GRJ player not enough playtime, Player: [player]") - continue - - if(job.barred_by_disability(player.client)) - Debug("GRJ player has disability rendering them ineligible for job, Player: [player]") - continue - - if(job.barred_by_missing_limbs(player.client)) - Debug("GRJ player has missing limbs rendering them ineligible for job, Player: [player]") - continue - - if(player.mind && (job.title in player.mind.restricted_roles)) - Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]") - continue - if(player.mind.special_role && player.mind && (job.title in SSticker.mode.single_antag_positions)) - if((player.mind in SSjobs.failed_head_antag_roll) || !prob(probability_of_antag_role_restriction)) - Debug("GRJ Failed probability of getting a second antagonist position in this job, Player: [player], Job:[job.title]") - SSjobs.failed_head_antag_roll |= player.mind - continue - else - probability_of_antag_role_restriction /= 10 - if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1) - Debug("GRJ Random job given, Player: [player], Job: [job]") - AssignRole(player, job.title) - unassigned -= player - break - -/datum/controller/subsystem/jobs/proc/ResetOccupations() - for(var/mob/new_player/player in GLOB.player_list) - if((player) && (player.mind)) - player.mind.assigned_role = null - player.mind.special_role = null - SetupOccupations() - unassigned = list() - return - - -///This proc is called before the level loop of DivideOccupations() and will try to select a head, ignoring ALL non-head preferences for every level until it locates a head or runs out of levels to check -/datum/controller/subsystem/jobs/proc/FillHeadPosition() - for(var/level = 1 to 3) - for(var/command_position in GLOB.command_positions) - var/datum/job/job = GetJob(command_position) - if(!job) - continue - var/list/candidates = FindOccupationCandidates(job, level) - if(!length(candidates)) - continue - - var/list/filteredCandidates = list() - - for(var/mob/V in candidates) - // Log-out during round-start? What a bad boy, no head position for you! - if(!V.client) - continue - filteredCandidates += V - - if(!length(filteredCandidates)) - continue - - var/mob/new_player/candidate = pick(filteredCandidates) - if(AssignRole(candidate, command_position)) - return 1 - - return 0 - - -///This proc is called at the start of the level loop of DivideOccupations() and will cause head jobs to be checked before any other jobs of the same level -/datum/controller/subsystem/jobs/proc/CheckHeadPositions(level) - for(var/command_position in GLOB.command_positions) - var/datum/job/job = GetJob(command_position) - if(!job) - continue - var/list/candidates = FindOccupationCandidates(job, level) - if(!length(candidates)) - continue - var/mob/new_player/candidate = pick(candidates) - AssignRole(candidate, command_position) - - -/datum/controller/subsystem/jobs/proc/FillAIPosition() - if(!GLOB.configuration.jobs.allow_ai) - return FALSE - - var/ai_selected = 0 - var/datum/job/job = GetJob("AI") - if(!job) - return 0 - - for(var/i = job.total_positions, i > 0, i--) - for(var/level = 1 to 3) - var/list/candidates = list() - candidates = FindOccupationCandidates(job, level) - if(length(candidates)) - var/mob/new_player/candidate = pick(candidates) - if(AssignRole(candidate, "AI")) - ai_selected++ - break - - if(ai_selected) - return 1 - - return 0 - - -/** Proc DivideOccupations -* fills var "assigned_role" for all ready players. -* This proc must not have any side effect besides of modifying "assigned_role". -**/ -/datum/controller/subsystem/jobs/proc/DivideOccupations() - // Lets roughly time this - var/watch = start_watch() - //Setup new player list and get the jobs list - Debug("Running DO") - if(!length(occupations)) - SetupOccupations() - - //Holder for Triumvirate is stored in the ticker, this just processes it - if(SSticker) - for(var/datum/job/ai/A in occupations) - if(SSticker.triai) - A.spawn_positions = 3 - - //Get the players who are ready - for(var/mob/new_player/player in GLOB.player_list) - if(player.ready && player.mind && !player.mind.assigned_role) - unassigned += player - - Debug("DO, Len: [length(unassigned)]") - if(!length(unassigned)) - return FALSE - - //Shuffle players and jobs - unassigned = shuffle(unassigned) - - HandleFeedbackGathering() - - //People who wants to be assistants, sure, go on. - Debug("DO, Running Assistant Check 1") - var/datum/job/ast = new /datum/job/assistant() - var/list/assistant_candidates = FindOccupationCandidates(ast, 3) - Debug("AC1, Candidates: [length(assistant_candidates)]") - for(var/mob/new_player/player in assistant_candidates) - Debug("AC1 pass, Player: [player]") - AssignRole(player, "Assistant") - assistant_candidates -= player - Debug("DO, AC1 end") - - //Select one head - Debug("DO, Running Head Check") - FillHeadPosition() - Debug("DO, Head Check end") - - //Check for an AI - Debug("DO, Running AI Check") - FillAIPosition() - Debug("DO, AI Check end") - - //Other jobs are now checked - Debug("DO, Running Standard Check") - - - // New job giving system by Donkie - // This will cause lots of more loops, but since it's only done once it shouldn't really matter much at all. - // Hopefully this will add more randomness and fairness to job giving. - - // Loop through all levels from high to low - var/list/shuffledoccupations = shuffle(occupations) - for(var/level = 1 to 3) - //Check the head jobs first each level - CheckHeadPositions(level) - - // Loop through all unassigned players - for(var/mob/new_player/player in unassigned) - - // Loop through all jobs - for(var/datum/job/job in shuffledoccupations) // SHUFFLE ME BABY - if(!job) - continue - - if(jobban_isbanned(player, job.title)) - Debug("DO isbanned failed, Player: [player], Job:[job.title]") - continue - - if(!job.player_old_enough(player.client)) - Debug("DO player not old enough, Player: [player], Job:[job.title]") - continue - - if(job.get_exp_restrictions(player.client)) - Debug("DO player not enough playtime, Player: [player], Job:[job.title]") - continue - - if(job.barred_by_disability(player.client)) - Debug("DO player has disability rendering them ineligible for job, Player: [player], Job:[job.title]") - continue - - if(job.barred_by_missing_limbs(player.client)) - Debug("DO player has missing limbs rendering them ineligible for job, Player: [player], Job:[job.title]") - continue - - if(player.mind && (job.title in player.mind.restricted_roles)) - Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]") - continue - // If the player wants that job on this level, then try give it to him. - if(player.client.prefs.active_character.GetJobDepartment(job, level) & job.flag) - // If the job isn't filled - if(job.is_spawn_position_available()) - if(player.mind.special_role && player.mind && (job.title in SSticker.mode.single_antag_positions)) //We want to check if they want the job, before rolling the prob chance - if((player.mind in SSjobs.failed_head_antag_roll) || !prob(probability_of_antag_role_restriction)) - Debug("DO Failed probability of getting a second antagonist position in this job, Player: [player], Job:[job.title]") - SSjobs.failed_head_antag_roll |= player.mind - continue - else - probability_of_antag_role_restriction /= 10 - Debug("DO pass, Player: [player], Level:[level], Job:[job.title]") - Debug(" - Job Flag: [job.flag] Job Department: [player.client.prefs.active_character.GetJobDepartment(job, level)] Job Current Pos: [job.current_positions] Job Spawn Positions = [job.spawn_positions]") - AssignRole(player, job.title) - unassigned -= player - break - - // Hand out random jobs to the people who didn't get any in the last check - // Also makes sure that they got their preference correct - for(var/mob/new_player/player in unassigned) - if(player.client.prefs.active_character.alternate_option == GET_RANDOM_JOB) - GiveRandomJob(player) - - Debug("DO, Standard Check end") - - Debug("DO, Running AC2") - - // Antags, who have to get in, come first - for(var/mob/new_player/player in unassigned) - if(player.mind.special_role) - if(player.client.prefs.active_character.alternate_option != BE_ASSISTANT) - GiveRandomJob(player) - if(player in unassigned) - AssignRole(player, "Assistant") - else - AssignRole(player, "Assistant") - else if(length(player.mind.restricted_roles)) - stack_trace("A player with `restricted_roles` had no `special_role`. They are likely an antagonist, but failed to spawn in.") // this can be fixed by assigning a special_role in pre_setup of the gamemode - message_admins("A player mind ([player.mind]) is likely an antagonist, but may have failed to spawn in! Please report this to coders.") - - // Then we assign what we can to everyone else. - for(var/mob/new_player/player in unassigned) - if(player.client.prefs.active_character.alternate_option == BE_ASSISTANT) - Debug("AC2 Assistant located, Player: [player]") - AssignRole(player, "Assistant") - else if(player.client.prefs.active_character.alternate_option == RETURN_TO_LOBBY) - player.ready = FALSE - unassigned -= player - - log_debug("Dividing Occupations took [stop_watch(watch)]s") - failed_head_antag_roll = list() - return TRUE - -/datum/controller/subsystem/jobs/proc/AssignRank(mob/living/carbon/human/H, rank, joined_late = FALSE) - if(!H) - return null - var/datum/job/job = GetJob(rank) - - H.job = rank - - var/alt_title = null - - if(H.mind) - H.mind.assigned_role = rank - alt_title = H.mind.role_alt_title - - CreateMoneyAccount(H, rank, job) - - var/list/L = list() - L.Add("Your role on the station is: [alt_title ? alt_title : rank].") - L.Add("You answer directly to [job.supervisors]. Special circumstances may change this.") - L.Add("For more information on how the station works, see [wiki_link("Standard_Operating_Procedure", "Standard Operating Procedure (SOP)")].") - if(job.job_department_flags & DEP_FLAG_SERVICE) - L.Add("As a member of Service, make sure to read up on your [wiki_link("Standard_Operating_Procedure_(Service)", "Department SOP")].") - if(job.job_department_flags & DEP_FLAG_SUPPLY) - L.Add("As a member of Supply, make sure to read up on your [wiki_link("Standard_Operating_Procedure_(Supply)", "Department SOP")].") - if(job.job_department_flags == DEP_FLAG_COMMAND) // Check if theyre only command, like captain/hop/bs/ntrep, to not spam their chatbox - L.Add("As an important member of Command, read up on your [wiki_link("Standard_Operating_Procedure_(Command)", "Department SOP")].") - if(job.job_department_flags & DEP_FLAG_LEGAL) - L.Add("Your job requires complete knowledge of [wiki_link("Space Law", "Space Law")] and [wiki_link("Legal_Standard_Operating_Procedure", "Legal Standard Operating Procedure")].") - if(job.job_department_flags & DEP_FLAG_ENGINEERING) - L.Add("As a member of Engineering, make sure to read up on your [wiki_link("Standard_Operating_Procedure_(Engineering)", "Department SOP")].") - if(job.job_department_flags & DEP_FLAG_MEDICAL) - L.Add("As a member of Medbay, make sure to read up on your [wiki_link("Standard_Operating_Procedure_(Medical)", "Department SOP")].") - if(job.job_department_flags & DEP_FLAG_SCIENCE) // geneticist gets both, yeah sure why not - L.Add("As a member of Science, make sure to read up on your [wiki_link("Standard_Operating_Procedure_(Science)", "Department SOP")].") - if(job.job_department_flags & DEP_FLAG_SECURITY) - L.Add("As a member of Security, you are to know [wiki_link("Space Law", "Space Law")] and [wiki_link("Legal_Standard_Operating_Procedure", "Legal Standard Operating Procedure")], as well as your [wiki_link("Standard_Operating_Procedure_(Security)", "Department SOP")].") - if(job.req_admin_notify) - L.Add("You are playing a job that is important for the game progression. If you have to disconnect, please go to cryo and inform command. If you are unable to do so, please notify the admins via adminhelp.") - L.Add("
    If you need help, check the [wiki_link("Main_Page", "wiki")] or use Mentorhelp(F1)!
    ") - if(job.important_information) - L.Add("[job.important_information]") - - to_chat(H, chat_box_green(L.Join("
    "))) - - // If the job has objectives, announce those too - if(length(H.mind.job_objectives)) - var/list/objectives_message = list() - var/counter = 1 - for(var/datum/job_objective/objective as anything in H.mind.job_objectives) - objectives_message.Add("Objective #[counter]: [objective.objective_name]") - objectives_message.Add("[objective.description]
    ") - counter++ - to_chat(H, chat_box_notice(objectives_message.Join("
    "))) - - return H - -/datum/controller/subsystem/jobs/proc/EquipRank(mob/living/carbon/human/H, rank, joined_late = 0) // Equip and put them in an area - if(!H) - return null - - var/datum/job/job = GetJob(rank) - - H.job = rank - - if(!joined_late && !late_arrivals_spawning) - var/turf/T = null - var/obj/S = null - var/list/landmarks = GLOB.landmarks_list - if(drunken_spawning) - landmarks = shuffle(landmarks) //Shuffle it so it's random - - for(var/obj/effect/landmark/start/sloc in landmarks) - if(sloc.name != rank && !drunken_spawning) - continue - if(locate(/mob/living) in sloc.loc) - continue - if(drunken_spawning && sloc.name == "AI") - continue - S = sloc - break - if(!S) - S = locate("start*[rank]") // use old stype - if(!S) // still no spawn, fall back to the arrivals shuttle - for(var/turf/TS in get_area_turfs(/area/shuttle/arrival)) - if(!TS.density) - var/clear = 1 - for(var/obj/O in TS) - if(O.density) - clear = 0 - break - if(clear) - T = TS - continue - - if(isturf(S)) - T = S - else if(istype(S, /obj/effect/landmark/start) && isturf(S.loc)) - T = S.loc - - if(T) - H.forceMove(T) - // Moving wheelchair if they have one - if(H.buckled && istype(H.buckled, /obj/structure/chair/wheelchair)) - H.buckled.forceMove(H.loc) - H.buckled.dir = H.dir - - if(job) - var/new_mob = job.equip(H) - if(ismob(new_mob)) - H = new_mob - - if(job && H) - job.after_spawn(H) - - //Gives glasses to the vision impaired - if(HAS_TRAIT(H, TRAIT_NEARSIGHT)) - var/equipped = H.equip_to_slot_or_del(new /obj/item/clothing/glasses/regular(H), ITEM_SLOT_EYES) - if(equipped != 1) - var/obj/item/clothing/glasses/G = H.glasses - if(istype(G) && !G.prescription) - G.upgrade_prescription() - H.update_nearsighted_effects() - - if(joined_late || job.admin_only) - H.create_log(MISC_LOG, "Spawned as \an [H.dna?.species ? H.dna.species : "Undefined species"] named [H]. [joined_late ? "Joined during the round" : "Roundstart joined"] as job: [rank].", force_no_usr_check=TRUE) - addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/controller/subsystem/jobs, show_location_blurb), H.client, H.mind), 1 SECONDS) //Moment for minds to boot up / people to load in - return H - if(late_arrivals_spawning) - H.forceMove(pick(GLOB.latejoin)) - if(drunken_spawning) - var/obj/item/organ/internal/liver/L - var/liver_multiplier = 1 - L = H.get_int_organ(/obj/item/organ/internal/liver) - if(L) - liver_multiplier = L.alcohol_intensity - if(isslimeperson(H) || isrobot(H)) - liver_multiplier = 5 - H.Sleeping(5 SECONDS) - H.Drunk((2 / liver_multiplier) MINUTES) - H.create_log(MISC_LOG, "Spawned as \an [H.dna?.species ? H.dna.species : "Undefined species"] named [H]. Roundstart joined as job: [rank].", force_no_usr_check=TRUE) - addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/controller/subsystem/jobs, show_location_blurb), H.client, H.mind), 1 SECONDS) //Moment for minds to boot up / people to load in - return H - -/datum/controller/subsystem/jobs/proc/LoadJobs(highpop = FALSE) //ran during round setup, reads info from jobs list - if(!GLOB.configuration.jobs.enable_job_amount_overrides) - return FALSE - - var/list/joblist = list() - - if(highpop) - joblist = GLOB.configuration.jobs.highpop_job_map.Copy() - else - joblist = GLOB.configuration.jobs.lowpop_job_map.Copy() - - for(var/job in joblist) - // Key: name | Value: Amount - var/datum/job/J = GetJob(job) - if(!J) - stack_trace("`[job]` not found while setting max slots. Check for misspellings or alternate titles") - continue - J.total_positions = text2num(joblist[job]) - J.spawn_positions = text2num(joblist[job]) - - if(job == "AI" || job == "Cyborg") //I dont like this here but it will do for now - J.total_positions = 0 - - return TRUE - - -/datum/controller/subsystem/jobs/proc/HandleFeedbackGathering() - for(var/datum/job/job in occupations) - - var/high = 0 //high - var/medium = 0 //medium - var/low = 0 //low - var/never = 0 //never - var/banned = 0 //banned - var/young = 0 //account too young - var/disabled = FALSE //has disability rendering them ineligible - for(var/mob/new_player/player in GLOB.player_list) - if(!(player.ready && player.mind && !player.mind.assigned_role)) - continue //This player is not ready - if(jobban_isbanned(player, job.title)) - banned++ - continue - if(!job.player_old_enough(player.client)) - young++ - continue - if(job.get_exp_restrictions(player.client)) - young++ - continue - if(job.barred_by_disability(player.client) || job.barred_by_missing_limbs(player.client)) - disabled++ - continue - if(player.client.prefs.active_character.GetJobDepartment(job, 1) & job.flag) - high++ - else if(player.client.prefs.active_character.GetJobDepartment(job, 2) & job.flag) - medium++ - else if(player.client.prefs.active_character.GetJobDepartment(job, 3) & job.flag) - low++ - else never++ //not selected - - SSblackbox.record_feedback("nested tally", "job_preferences", high, list("[job.title]", "high")) - SSblackbox.record_feedback("nested tally", "job_preferences", medium, list("[job.title]", "medium")) - SSblackbox.record_feedback("nested tally", "job_preferences", low, list("[job.title]", "low")) - SSblackbox.record_feedback("nested tally", "job_preferences", never, list("[job.title]", "never")) - SSblackbox.record_feedback("nested tally", "job_preferences", banned, list("[job.title]", "banned")) - SSblackbox.record_feedback("nested tally", "job_preferences", young, list("[job.title]", "young")) - SSblackbox.record_feedback("nested tally", "job_preferences", disabled, list("[job.title]", "disabled")) - -//fuck -/datum/controller/subsystem/jobs/proc/CreateMoneyAccount(mob/living/H, rank, datum/job/job) - if(job && !job.has_bank_account) - return - var/starting_balance = job?.department_account_access ? COMMAND_MEMBER_STARTING_BALANCE : CREW_MEMBER_STARTING_BALANCE - var/datum/money_account/account = GLOB.station_money_database.create_account(H.real_name, starting_balance, ACCOUNT_SECURITY_ID, "NAS Trurl Accounting", TRUE) - - for(var/datum/job_objective/objective as anything in H.mind.job_objectives) - objective.owner_account = account - - H.mind.store_memory("Your account number is: #[account.account_number]
    Your account pin is: [account.account_pin]") - H.mind.set_initial_account(account) - - to_chat(H, "As an employee of Nanotrasen you will receive a paycheck of $[account.payday_amount] credits every 30 minutes") - to_chat(H, "Your account number is: [account.account_number], your account pin is: [account.account_pin]") - - if(!job) //if their job datum is null (looking at you ERTs...), we don't need to do anything past this point - return - - //add them to their department datum, (this relates a lot to money account I promise) - var/list/users_departments = get_departments_from_job(job.title) - for(var/datum/station_department/department as anything in users_departments) - var/datum/department_member/member = new - member.name = H.real_name - member.role = job.title - member.set_member_account(account) //we need to set this through a proc so we can register signals - member.can_approve_crates = job?.department_account_access - department.members += member - - // If they're head, give them the account info for their department - if(!job.department_account_access) - return - - announce_department_accounts(users_departments, H, job) - -/datum/controller/subsystem/jobs/proc/announce_department_accounts(users_departments, mob/living/H, datum/job/job) - var/remembered_info = "" - for(var/datum/station_department/department as anything in users_departments) - if(job.title != department.head_of_staff) - continue - var/datum/money_account/department_account = department.department_account - if(!department_account) - return - - remembered_info += "As a head of staff you have access to your department's money account through your PDA's NanoBank or a station ATM
    " - remembered_info += "The [department.department_name] department's account number is: #[department_account.account_number]
    " - remembered_info += "The [department.department_name] department's account pin is: [department_account.account_pin]
    " - remembered_info += "Your department's account funds are: $[department_account.credit_balance]
    " - - H.mind.store_memory(remembered_info) - to_chat(H, "Your department will receive a $[department_account.payday_amount] credit stipend every 30 minutes") - to_chat(H, "The [department.department_name] department's account number is: #[department_account.account_number], Your department's account pin is: [department_account.account_pin]") - -/datum/controller/subsystem/jobs/proc/format_jobs_for_id_computer(obj/item/card/id/tgtcard) - var/list/jobs_to_formats = list() - if(tgtcard) - var/mob/M = tgtcard.getPlayer() - for(var/datum/job/job in occupations) - if(tgtcard.rank && tgtcard.rank == job.title) - jobs_to_formats[job.title] = "green" // the job they already have is pre-selected - else if(tgtcard.assignment == "Demoted" || tgtcard.assignment == "Terminated") - jobs_to_formats[job.title] = "grey" - else if(!job.transfer_allowed) - jobs_to_formats[job.title] = "grey" // jobs which shouldnt be transferred into for whatever reason, likely due to high hour requirements - else if((job.title in GLOB.command_positions) && istype(M) && M.client && job.get_exp_restrictions(M.client)) - jobs_to_formats[job.title] = "grey" // command jobs which are playtime-locked and not unlocked for this player are discouraged - else if(job.total_positions && !job.current_positions && job.title != "Assistant") - jobs_to_formats[job.title] = "teal" // jobs with nobody doing them at all are encouraged - else if(job.total_positions >= 0 && job.current_positions >= job.total_positions) - jobs_to_formats[job.title] = "grey" // jobs that are full (no free positions) are discouraged - if(tgtcard.assignment == "Demoted" || tgtcard.assignment == "Terminated") - jobs_to_formats["Custom"] = "grey" - return jobs_to_formats - - - -/datum/controller/subsystem/jobs/proc/log_job_transfer(transferee, oldvalue, newvalue, whodidit, reason) - id_change_records["[id_change_counter]"] = list( - "transferee" = transferee, - "oldvalue" = oldvalue, - "newvalue" = newvalue, - "whodidit" = whodidit, - "timestamp" = station_time_timestamp(), - "reason" = reason - ) - id_change_counter++ - -/datum/controller/subsystem/jobs/proc/slot_job_transfer(oldtitle, newtitle) - var/datum/job/oldjobdatum = SSjobs.GetJob(oldtitle) - var/datum/job/newjobdatum = SSjobs.GetJob(newtitle) - if(istype(oldjobdatum) && oldjobdatum.current_positions > 0 && istype(newjobdatum)) - if(!(oldjobdatum.title in GLOB.command_positions) && !(newjobdatum.title in GLOB.command_positions)) - oldjobdatum.current_positions-- - newjobdatum.current_positions++ - -/datum/controller/subsystem/jobs/proc/notify_dept_head(jobtitle, antext) - // Used to notify the department head of jobtitle X that their employee was brigged, demoted or terminated - if(!jobtitle || !antext) - return - var/datum/job/tgt_job = GetJob(jobtitle) - if(!tgt_job) - return - if(!length(tgt_job.department_head)) - return - var/boss_title = tgt_job.department_head[1] - var/obj/item/pda/target_pda - for(var/obj/item/pda/check_pda in GLOB.PDAs) - if(check_pda.ownrank == boss_title) - target_pda = check_pda - break - if(!target_pda) - return - var/datum/data/pda/app/messenger/PM = target_pda.find_program(/datum/data/pda/app/messenger) - if(PM && PM.can_receive()) - PM.notify("Automated Notification: \"[antext]\" (Unable to Reply)", 0) // the 0 means don't make the PDA flash - -/datum/controller/subsystem/jobs/proc/notify_by_name(target_name, antext) - // Used to notify a specific crew member based on their real_name - if(!target_name || !antext) - return - var/obj/item/pda/target_pda - for(var/obj/item/pda/check_pda in GLOB.PDAs) - if(check_pda.owner == target_name) - target_pda = check_pda - break - if(!target_pda) - return - var/datum/data/pda/app/messenger/PM = target_pda.find_program(/datum/data/pda/app/messenger) - if(PM && PM.can_receive()) - PM.notify("Automated Notification: \"[antext]\" (Unable to Reply)", 0) // the 0 means don't make the PDA flash - -/datum/controller/subsystem/jobs/proc/format_job_change_records(centcom) - var/list/formatted = list() - for(var/thisid in id_change_records) - var/thisrecord = id_change_records[thisid] - if(thisrecord["deletedby"] && !centcom) - continue - var/list/newlist = list() - for(var/lkey in thisrecord) - newlist[lkey] = thisrecord[lkey] - formatted.Add(list(newlist)) - return formatted - - -/datum/controller/subsystem/jobs/proc/delete_log_records(sourceuser, delete_all) - . = 0 - if(!sourceuser) - return - var/list/new_id_change_records = list() - for(var/thisid in id_change_records) - var/thisrecord = id_change_records[thisid] - if(!thisrecord["deletedby"]) - if(delete_all || thisrecord["whodidit"] == sourceuser) - thisrecord["deletedby"] = sourceuser - .++ - new_id_change_records["[id_change_counter]"] = thisrecord - id_change_counter++ - id_change_records = new_id_change_records - -// This proc will update all players EXP at once. It will calculate amount of time to add dynamically based on the SS fire time. -/datum/controller/subsystem/jobs/proc/batch_update_player_exp(announce = FALSE) - // Right off the bat - var/start_time = start_watch() - // First calculate minutes - var/divider = 10 // By default, 10 deciseconds in 1 second - if(flags & SS_TICKER) - divider = 20 // If this SS ever gets made into a ticker SS, account for that - - var/minutes = (wait / divider) / 60 // Calculate minutes based on the SS wait time (How often this proc fires) - - // Step 1: Get us a list of clients to process - var/list/client/clients_to_process = GLOB.clients.Copy() // This is copied so that clients joining in the middle of this dont break things - Debug("Starting EXP update for [length(clients_to_process)] clients. (Adding [minutes] minutes)") - - var/list/datum/db_query/select_queries = list() // List of SELECT queries to mass grab EXP. - - for(var/i in clients_to_process) - var/client/C = i - if(!C) - continue // If a client logs out in the middle of this - - var/datum/db_query/exp_read = SSdbcore.NewQuery( - "SELECT exp FROM player WHERE ckey=:ckey", - list("ckey" = C.ckey) - ) - - select_queries[C.ckey] = exp_read - - var/list/read_records = list() - // Explanation for parameters: - // TRUE: We want warnings if these fail - // FALSE: Do NOT qdel() queries here, otherwise they wont be read. At all. - // TRUE: This is an assoc list, so it needs to prepare for that - // FALSE: We dont want to logspam - SSdbcore.MassExecute(select_queries, TRUE, FALSE, TRUE, FALSE) // Batch execute so we can take advantage of async magic - - for(var/i in clients_to_process) - var/client/C = i - if(!C) - continue // If a client logs out in the middle of this - - if(select_queries[C.ckey]) // This check should not be necessary, but I am paranoid - while(select_queries[C.ckey].NextRow()) - read_records[C.ckey] = params2list(select_queries[C.ckey].item[1]) - - QDEL_LIST_ASSOC_VAL(select_queries) // Clean stuff up - - var/list/play_records = list() - - var/list/datum/db_query/player_update_queries = list() // List of queries to update player EXP - var/list/datum/db_query/playtime_history_update_queries = list() // List of queries to update the playtime history table - - for(var/i in clients_to_process) - var/client/C = i - if(!C) - continue // If a client logs out in the middle of this - // Get us a container - play_records[C.ckey] = list() - for(var/rtype in GLOB.exp_jobsmap) - if(text2num(read_records[C.ckey][rtype])) - play_records[C.ckey][rtype] = text2num(read_records[C.ckey][rtype]) - else - play_records[C.ckey][rtype] = 0 - - - var/myrole - if(C.mob.mind) - if(C.mob.mind.playtime_role) - myrole = C.mob.mind.playtime_role - else if(C.mob.mind.assigned_role) - myrole = C.mob.mind.assigned_role - - // Track all the added ammounts for a mega update query - var/list/added_differential = list( - EXP_TYPE_LIVING = 0, - EXP_TYPE_CREW = 0, - EXP_TYPE_SPECIAL = 0, - EXP_TYPE_GHOST = 0, - EXP_TYPE_COMMAND = 0, - EXP_TYPE_ENGINEERING = 0, - EXP_TYPE_MEDICAL = 0, - EXP_TYPE_SCIENCE = 0, - EXP_TYPE_SUPPLY = 0, - EXP_TYPE_SECURITY = 0, - EXP_TYPE_SILICON = 0, - EXP_TYPE_SERVICE = 0 - ) - if(C.mob.stat == CONSCIOUS && myrole) - play_records[C.ckey][EXP_TYPE_LIVING] += minutes - added_differential[EXP_TYPE_LIVING] += minutes - - if(announce) - to_chat(C.mob, "You got: [minutes] Living EXP!") - - for(var/category in GLOB.exp_jobsmap) - if(GLOB.exp_jobsmap[category]["titles"]) - if(myrole in GLOB.exp_jobsmap[category]["titles"]) - play_records[C.ckey][category] += minutes - added_differential[category] += minutes - if(announce) - to_chat(C.mob, "You got: [minutes] [category] EXP!") - - if(C.mob.mind.special_role) - play_records[C.ckey][EXP_TYPE_SPECIAL] += minutes - if(announce) - to_chat(C.mob, "You got: [minutes] Special EXP!") - - else if(isobserver(C.mob)) - play_records[C.ckey][EXP_TYPE_GHOST] += minutes - added_differential[EXP_TYPE_GHOST] += minutes - if(announce) - to_chat(C.mob, "You got: [minutes] Ghost EXP!") - else - continue - - var/new_exp = list2params(play_records[C.ckey]) - - C.prefs.exp = new_exp - - var/datum/db_query/update_query = SSdbcore.NewQuery( - "UPDATE player SET exp =:newexp, lastseen=NOW() WHERE ckey=:ckey", - list( - "newexp" = new_exp, - "ckey" = C.ckey - ) - ) - - player_update_queries += update_query - - // This gets hellish - var/datum/db_query/update_query_history = SSdbcore.NewQuery({" - INSERT INTO playtime_history (ckey, date, time_living, time_crew, time_special, time_ghost, time_command, time_engineering, time_medical, time_science, time_supply, time_security, time_silicon, time_service) - VALUES (:ckey, CURDATE(), :addedliving, :addedcrew, :addedspecial, :addedghost, :addedcommand, :addedengineering, :addedmedical, :addedscience, :addedsupply, :addedsecurity, :addedsilicon, :addedservice) - ON DUPLICATE KEY UPDATE time_living=time_living + VALUES(time_living), time_crew=time_crew + VALUES(time_crew), time_crew=time_special + VALUES(time_special), time_ghost=time_ghost + VALUES(time_ghost), time_command=time_command + VALUES(time_command), time_engineering=time_engineering + VALUES(time_engineering), time_medical=time_medical + VALUES(time_medical), time_science=time_science + VALUES(time_science), time_supply=time_supply + VALUES(time_supply), time_security=time_security + VALUES(time_security), time_silicon=time_silicon + VALUES(time_silicon), time_service=time_service + VALUES(time_service)"}, - list( - "ckey" = C.ckey, - "addedliving" = added_differential[EXP_TYPE_LIVING], - "addedcrew" = added_differential[EXP_TYPE_CREW], - "addedspecial" = added_differential[EXP_TYPE_SPECIAL], - "addedghost" = added_differential[EXP_TYPE_GHOST], - "addedcommand" = added_differential[EXP_TYPE_COMMAND], - "addedengineering" = added_differential[EXP_TYPE_ENGINEERING], - "addedmedical" = added_differential[EXP_TYPE_MEDICAL], - "addedscience" = added_differential[EXP_TYPE_SCIENCE], - "addedsupply" = added_differential[EXP_TYPE_SUPPLY], - "addedsecurity" = added_differential[EXP_TYPE_SECURITY], - "addedsilicon" = added_differential[EXP_TYPE_SILICON], - "addedservice" = added_differential[EXP_TYPE_SERVICE] - ) - ) - - playtime_history_update_queries += update_query_history - - - // warn=TRUE, qdel=TRUE, assoc=FALSE, log=FALSE - SSdbcore.MassExecute(player_update_queries, TRUE, TRUE, FALSE, FALSE) // Batch execute so we can take advantage of async magic - SSdbcore.MassExecute(playtime_history_update_queries, TRUE, TRUE, FALSE, FALSE) - - Debug("Successfully updated all EXP data in [stop_watch(start_time)]s") diff --git a/code/controllers/subsystem/SSredis.dm b/code/controllers/subsystem/SSredis.dm deleted file mode 100644 index e617d3abf54d7..0000000000000 --- a/code/controllers/subsystem/SSredis.dm +++ /dev/null @@ -1,137 +0,0 @@ -SUBSYSTEM_DEF(redis) - name = "Redis" - init_order = INIT_ORDER_REDIS - runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY // ALL THE THINGS - wait = 1 - flags = SS_TICKER // Every tick - /// Are we connected - var/connected = FALSE - /// Amount of subscribed channels on the redis server - var/list/subbed_channels = list() - /// Message queue (If messages are sent before the SS has init'd) - var/list/datum/redis_message/queue = list() - offline_implications = "The server will no longer be able to send or receive redis messages. Shuttle call recommended (Potential server crash inbound)." - cpu_display = SS_CPUDISPLAY_LOW - -// SS meta procs -/datum/controller/subsystem/redis/get_stat_details() - return "S:[length(subbed_channels)] | Q:[length(queue)] | C:[connected ? "Y" : "N"]" - -/datum/controller/subsystem/redis/Initialize() - // Connect to cappuccino - connect() - - if(connected) - // Loop efficiency doesnt matter here. It runs once and likely wont have any events in - for(var/datum/redis_message/RM in queue) - publish(RM.channel, RM.message) - - // Setup all callbacks - for(var/cb in subtypesof(/datum/redis_callback)) - var/datum/redis_callback/RCB = new cb() - if(isnull(RCB.channel)) - stack_trace("[RCB.type] has no channel set!") - continue - - if(RCB.channel in subbed_channels) - stack_trace("Attempted to subscribe to the channel '[RCB.channel]' from [RCB.type] twice!") - - rustg_redis_subscribe(RCB.channel) - subbed_channels[RCB.channel] = RCB - - // Send our presence to required channels - var/list/presence_data = list() - presence_data["author"] = "system" - presence_data["source"] = GLOB.configuration.system.instance_id - presence_data["message"] = "Connected at `[SQLtime()]` during round [GLOB.round_id]" - - var/presence_text = json_encode(presence_data) - - for(var/channel in list("byond.asay", "byond.msay")) // Channels to announce to - publish(channel, presence_text) - - // Report detailed presence info to system - var/list/presence_data_2 = list() - presence_data_2["source"] = GLOB.configuration.system.instance_id - presence_data_2["round_id"] = GLOB.round_id - presence_data_2["event"] = "server_restart" - publish("byond.system", json_encode(presence_data_2)) - - var/amount_registered = length(subbed_channels) - log_startup_progress("Registered [amount_registered] callback[amount_registered == 1 ? "" : "s"].") - -/datum/controller/subsystem/redis/fire() - check_messages() - - -// Redis integration stuff -/datum/controller/subsystem/redis/proc/connect() - if(GLOB.configuration.redis.enabled) - #ifndef GAME_TESTS // CI uses linux so dont flag up a fail there - if(world.system_type == UNIX) - stack_trace("SSredis has known to be very buggy when running on Linux with random dropouts ocurring due to interrupted syscalls. You have been warned!") - #endif - - var/conn_failed = rustg_redis_connect(GLOB.configuration.redis.connstring) - if(conn_failed) - log_startup_progress("Failed to connect to redis. Please inform the server host.") - SEND_TEXT(world.log, "Redis connection failure: [conn_failed]") - return - - connected = TRUE - -/datum/controller/subsystem/redis/proc/disconnect() - rustg_redis_disconnect() - connected = FALSE - -/datum/controller/subsystem/redis/proc/check_messages() - var/raw_data = rustg_redis_get_messages() - var/list/usable_data - - try // Did you know byond had try catch? - usable_data = json_decode(raw_data) - catch - message_admins("Failed to deserialise a redis message | Please inform the server host.") - log_debug("Redis raw data: [raw_data]") - return - - for(var/channel in usable_data) - if(channel == RUSTG_REDIS_ERROR_CHANNEL) - var/redis_error_data = usable_data[channel] - var/error_str - if(islist(redis_error_data)) - error_str = json_encode(redis_error_data) - else - error_str = redis_error_data - - message_admins("Redis error: [error_str] | Please inform the server host.") // uh oh - log_game("Redis error: [error_str]") - continue - // Check its an actual channel - if(!(channel in subbed_channels)) - stack_trace("Received a message on the channel '[channel]' when we arent subscribed to it. What the heck?") - continue - - var/datum/redis_callback/RCB = subbed_channels[channel] - for(var/message in usable_data[channel]) - RCB.on_message(message) - -/datum/controller/subsystem/redis/proc/publish(channel, message) - // If we arent alive, queue - if(!connected) - var/datum/redis_message/RM = new() - RM.channel = channel - RM.message = message - queue += RM - return - - // If we are alive, publish straight away - rustg_redis_publish(channel, message) - - -// Misc protection stuff -/datum/controller/subsystem/redis/CanProcCall(procname) - return FALSE - -/datum/controller/subsystem/redis/vv_edit_var(var_name, var_value) - return FALSE // dont even try diff --git a/code/controllers/subsystem/SSticker.dm b/code/controllers/subsystem/SSticker.dm deleted file mode 100644 index 2dbd6aedde4f6..0000000000000 --- a/code/controllers/subsystem/SSticker.dm +++ /dev/null @@ -1,907 +0,0 @@ -SUBSYSTEM_DEF(ticker) - name = "Ticker" - init_order = INIT_ORDER_TICKER - - priority = FIRE_PRIORITY_TICKER - flags = SS_KEEP_TIMING - runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME - offline_implications = "The game is no longer aware of when the round ends. Immediate server restart recommended." - cpu_display = SS_CPUDISPLAY_LOW - wait = 1 SECONDS - - /// Time the game should start, relative to world.time - var/round_start_time = 0 - /// Time that the round started - var/time_game_started = 0 - /// Current status of the game. See code\__DEFINES\game.dm - var/current_state = GAME_STATE_STARTUP - /// Do we want to force-start as soon as we can - var/force_start = FALSE - /// Do we want to force-end as soon as we can - var/force_ending = FALSE - /// Leave here at FALSE ! setup() will take care of it when needed for Secret mode -walter0o - var/hide_mode = FALSE - /// Our current game mode - var/datum/game_mode/mode = null - /// The current pick of lobby music played in the lobby - var/login_music - /// List of all minds in the game. Used for objective tracking - var/list/datum/mind/minds = list() - /// icon_state the chaplain has chosen for his bible - var/Bible_icon_state - /// item_state the chaplain has chosen for his bible - var/Bible_item_state - /// Name of the bible - var/Bible_name - /// Name of the bible deity - var/Bible_deity_name - /// Cult static info, used for things like sprites. Someone should refactor the sprites out of it someday and just use SEPERATE ICONS DEPNDING ON THE TYPE OF CULT... like a sane person - var/datum/cult_info/cult_data - /// If set to nonzero, ALL players who latejoin or declare-ready join will have random appearances/genders - var/random_players = FALSE - /// Did we broadcast the tip of the round yet? - var/tipped = FALSE - /// What will be the tip of the round? - var/selected_tip - /// This is used for calculations for the statpanel - var/pregame_timeleft - /// If set to TRUE, the round will not restart on it's own - var/delay_end = FALSE - /// Global holder for triple AI mode - var/triai = FALSE - /// Holder for inital autotransfer vote timer - var/next_autotransfer = 0 - /// Used for station explosion cinematic - var/atom/movable/screen/cinematic = null - /// Spam Prevention. Announce round end only once. - var/round_end_announced = FALSE - /// Is the ticker currently processing? If FALSE, roundstart is delayed - var/ticker_going = TRUE - /// Gamemode result (For things like cult or nukies which can end multiple ways) - var/mode_result = "undefined" - /// Server end state (Did we end properly or reboot or nuke or what) - var/end_state = "undefined" - /// Time the real reboot kicks in - var/real_reboot_time = 0 - /// Datum used to generate the end of round scoreboard. - var/datum/scoreboard/score = null - /// List of ckeys who had antag rolling issues flagged - var/list/flagged_antag_rollers = list() - /// List of biohazards keyed to the last time their population was sampled. - var/list/biohazard_pop_times = list() - var/list/biohazard_included_admin_spawns = list() - -/datum/controller/subsystem/ticker/Initialize() - login_music = pick(\ - 'sound/music/thunderdome.ogg',\ - 'sound/music/space.ogg',\ - 'sound/music/title1.ogg',\ - 'sound/music/title2.ogg',\ - 'sound/music/title3.ogg',) - - -/datum/controller/subsystem/ticker/fire() - switch(current_state) - if(GAME_STATE_STARTUP) - // This is ran as soon as the MC starts firing, and should only run ONCE, unless startup fails - pregame_timeleft = GLOB.configuration.general.lobby_time SECONDS - round_start_time = world.time + pregame_timeleft - to_chat(world, "Welcome to the pre-game lobby!") - to_chat(world, "Please, setup your character and select ready. Game will start in [GLOB.configuration.general.lobby_time] seconds") - current_state = GAME_STATE_PREGAME - fire() // TG says this is a good idea - for(var/mob/new_player/N in GLOB.player_list) - if(N.client) - N.new_player_panel_proc() // to enable the observe option - if(GAME_STATE_PREGAME) - if(!SSticker.ticker_going) // This has to be referenced like this, and I dont know why. If you dont put SSticker. it will break - return - - // This is so we dont have sleeps in controllers, because that is a bad, bad thing - pregame_timeleft = max(0, round_start_time - world.time) - - if(pregame_timeleft <= 1 MINUTES && !tipped) - send_tip_of_the_round() - tipped = TRUE - - if(pregame_timeleft <= 0 || force_start) - current_state = GAME_STATE_SETTING_UP - Master.SetRunLevel(RUNLEVEL_SETUP) - if(GAME_STATE_SETTING_UP) - if(!setup()) // Setup failed - current_state = GAME_STATE_STARTUP - Master.SetRunLevel(RUNLEVEL_LOBBY) - if(GAME_STATE_PLAYING) - delay_end = FALSE // reset this in case round start was delayed - mode.process() - - for(var/biohazard in biohazard_pop_times) - if(world.time - biohazard_pop_times[biohazard] > BIOHAZARD_POP_INTERVAL) - sample_biohazard_population(biohazard) - - if(world.time > next_autotransfer) - SSvote.start_vote(new /datum/vote/crew_transfer) - next_autotransfer = world.time + GLOB.configuration.vote.autotransfer_interval_time - - var/game_finished = SSshuttle.emergency.mode >= SHUTTLE_ENDGAME || mode.station_was_nuked - if(GLOB.configuration.gamemode.disable_certain_round_early_end) - mode.check_finished() // some modes contain var-changing code in here, so call even if we don't uses result - else - game_finished |= mode.check_finished() - if(game_finished || force_ending) - current_state = GAME_STATE_FINISHED - if(GAME_STATE_FINISHED) - if(SSshuttle.emergency.mode >= SHUTTLE_ENDGAME && !mode.station_was_nuked) - record_biohazard_results() - current_state = GAME_STATE_FINISHED - Master.SetRunLevel(RUNLEVEL_POSTGAME) // This shouldnt process more than once, but you never know - auto_toggle_ooc(TRUE) // Turn it on - declare_completion() - addtimer(CALLBACK(src, PROC_REF(call_reboot)), 5 SECONDS) - // Start a map vote IF - // - Map rotate doesnt have a mode for today and map voting is enabled - // - Map rotate has a mode for the day and it ISNT full random - if(SSmaprotate.setup_done && (SSmaprotate.rotation_mode == MAPROTATION_MODE_HYBRID_FPTP_NO_DUPLICATES)) - SSmaprotate.decide_next_map() - return - if(((!SSmaprotate.setup_done) && GLOB.configuration.vote.enable_map_voting) || (SSmaprotate.setup_done && (SSmaprotate.rotation_mode != MAPROTATION_MODE_FULL_RANDOM))) - SSvote.start_vote(new /datum/vote/map) - else - // Pick random map - var/list/pickable_types = list() - for(var/x in subtypesof(/datum/map)) - var/datum/map/M = x - if(istype(SSmapping.map_datum, M)) // Random will never choose the same map twice in a row. - continue - if(initial(M.voteable) && length(GLOB.clients) >= initial(M.min_players_random)) - pickable_types += M - - var/datum/map/target_map = pick(pickable_types) - SSmapping.next_map = new target_map - to_chat(world, "Map for next round: [SSmapping.next_map.fluff_name] ([SSmapping.next_map.technical_name])") - -/datum/controller/subsystem/ticker/proc/call_reboot() - if(mode.station_was_nuked) - reboot_helper("Station destroyed by Nuclear Device.", "nuke") - else - reboot_helper("Round ended.", "proper completion") - -/datum/controller/subsystem/ticker/proc/setup() - var/random_cult = pick(typesof(/datum/cult_info)) - cult_data = new random_cult() - score = new() - - // Create and announce mode - if(GLOB.master_mode == "secret") - hide_mode = TRUE - - var/list/datum/game_mode/runnable_modes - - if(GLOB.master_mode == "random" || GLOB.master_mode == "secret") - runnable_modes = GLOB.configuration.gamemode.get_runnable_modes() - if(!length(runnable_modes)) - to_chat(world, "Unable to choose playable game mode. Reverting to pre-game lobby.") - force_start = FALSE - current_state = GAME_STATE_PREGAME - Master.SetRunLevel(RUNLEVEL_LOBBY) - return FALSE - if(GLOB.secret_force_mode != "secret") - var/datum/game_mode/M = GLOB.configuration.gamemode.pick_mode(GLOB.secret_force_mode) - if(M.can_start()) - mode = GLOB.configuration.gamemode.pick_mode(GLOB.secret_force_mode) - SSjobs.ResetOccupations() - if(!mode) - mode = pickweight(runnable_modes) - if(mode) - var/mtype = mode.type - mode = new mtype - else - mode = GLOB.configuration.gamemode.pick_mode(GLOB.master_mode) - - if(!mode.can_start()) - to_chat(world, "Unable to start [mode.name]. Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby.") - mode = null - current_state = GAME_STATE_PREGAME - force_start = FALSE - SSjobs.ResetOccupations() - Master.SetRunLevel(RUNLEVEL_LOBBY) - return FALSE - - // Randomise characters now. This avoids rare cases where a human is set as a changeling then they randomise to an IPC - for(var/mob/new_player/player in GLOB.player_list) - if(player.client.prefs.toggles2 & PREFTOGGLE_2_RANDOMSLOT) - player.client.prefs.load_random_character_slot(player.client) - - // Lets check if people who ready should or shouldnt be - for(var/mob/new_player/P in GLOB.player_list) - // Not logged in - if(!P.client) - continue - // Not ready - if(!P.ready) - continue - // Not set to return if nothing available - if(P.client.prefs.active_character.alternate_option != RETURN_TO_LOBBY) - continue - - var/has_antags = (length(P.client.prefs.be_special) > 0) - if(!P.client.prefs.active_character.check_any_job()) - to_chat(P, "You have no jobs enabled, along with return to lobby if job is unavailable. This makes you ineligible for any round start role, please update your job preferences.") - if(has_antags) - // We add these to a list so we can deal with them as a batch later - // A lot of DB tracking stuff needs doing, so we may as well async it - flagged_antag_rollers |= P.ckey - - P.ready = FALSE - - //Configure mode and assign player to special mode stuff - - var/can_continue = FALSE - can_continue = mode.pre_setup() //Setup special modes. This also does the antag fishing checks. - - if(!can_continue) - QDEL_NULL(mode) - to_chat(world, "Error setting up [GLOB.master_mode]. Reverting to pre-game lobby.") - current_state = GAME_STATE_PREGAME - force_start = FALSE - SSjobs.ResetOccupations() - Master.SetRunLevel(RUNLEVEL_LOBBY) - return FALSE - - // Enable highpop slots just before we distribute jobs. - var/playercount = length(GLOB.clients) - var/highpop_trigger = 80 - - if(playercount >= highpop_trigger) - log_debug("Playercount: [playercount] versus trigger: [highpop_trigger] - loading highpop job config") - SSjobs.LoadJobs(TRUE) - else - log_debug("Playercount: [playercount] versus trigger: [highpop_trigger] - keeping standard job config") - - SSjobs.DivideOccupations() //Distribute jobs - - if(hide_mode) - var/list/modes = list() - for(var/datum/game_mode/M in runnable_modes) - modes += M.name - modes = sortList(modes) - to_chat(world, "The current game mode is - Secret!") - to_chat(world, "Possibilities: [english_list(modes)]") - else - mode.announce() - - // Behold, a rough way of figuring out what takes 10 years - var/watch = start_watch() - create_characters() // Create player characters and transfer clients - log_debug("Creating characters took [stop_watch(watch)]s") - - // Gather everyones minds - for(var/mob/living/player in GLOB.player_list) - if(player.mind) - minds += player.mind - - watch = start_watch() - equip_characters() // Apply outfits and loadouts to the characters - log_debug("Equipping characters took [stop_watch(watch)]s") - - watch = start_watch() - GLOB.data_core.manifest() // Create the manifest - log_debug("Manifest creation took [stop_watch(watch)]s") - SEND_SIGNAL(src, COMSIG_TICKER_ROUND_STARTING, world.time) - - // Update the MC and state to game playing - current_state = GAME_STATE_PLAYING - Master.SetRunLevel(RUNLEVEL_GAME) - - // Generate the list of empty playable AI cores in the world - if(HAS_TRAIT(SSstation, STATION_TRAIT_TRIAI)) - for(var/obj/effect/landmark/tripai in GLOB.landmarks_list) - if(tripai.name == "tripai") - if(locate(/mob/living) in get_turf(tripai)) - continue - GLOB.empty_playable_ai_cores += new /obj/structure/ai_core/deactivated(get_turf(tripai)) - for(var/obj/effect/landmark/start/ai/A in GLOB.landmarks_list) - if(locate(/mob/living) in get_turf(A)) - continue - GLOB.empty_playable_ai_cores += new /obj/structure/ai_core/deactivated(get_turf(A)) - - - // Setup pregenerated newsfeeds - setup_news_feeds() - - // Generate code phrases and responses - if(!GLOB.syndicate_code_phrase) - var/temp_syndicate_code_phrase = generate_code_phrase(return_list = TRUE) - - var/codewords = jointext(temp_syndicate_code_phrase, "|") - var/regex/codeword_match = new("([codewords])", "ig") - - GLOB.syndicate_code_phrase_regex = codeword_match - temp_syndicate_code_phrase = jointext(temp_syndicate_code_phrase, ", ") - GLOB.syndicate_code_phrase = temp_syndicate_code_phrase - - - if(!GLOB.syndicate_code_response) - var/temp_syndicate_code_response = generate_code_phrase(return_list = TRUE) - - var/codewords = jointext(temp_syndicate_code_response, "|") - var/regex/codeword_match = new("([codewords])", "ig") - - GLOB.syndicate_code_response_regex = codeword_match - temp_syndicate_code_response = jointext(temp_syndicate_code_response, ", ") - GLOB.syndicate_code_response = temp_syndicate_code_response - - // Run post setup stuff - mode.post_setup() - - // Delete starting landmarks (not AI ones because we need those for AI-ize) - for(var/obj/effect/landmark/start/S in GLOB.landmarks_list) - if(!istype(S, /obj/effect/landmark/start/ai)) - qdel(S) - - SSdbcore.SetRoundStart() - to_chat(world, "Enjoy the game!") - SEND_SOUND(world, sound(SSmapping.map_datum.welcome_sound)) - - if(SSholiday.holidays) - to_chat(world, "and...") - for(var/holidayname in SSholiday.holidays) - var/datum/holiday/holiday = SSholiday.holidays[holidayname] - to_chat(world, "

    [holiday.greet()]

    ") - - GLOB.discord_manager.send2discord_simple_noadmins("**\[Info]** Round has started") - auto_toggle_ooc(FALSE) // Turn it off - time_game_started = world.time - - // Sets the auto shuttle vote to happen after the config duration - next_autotransfer = world.time + GLOB.configuration.vote.autotransfer_initial_time - - for(var/mob/new_player/N in GLOB.mob_list) - if(N.client) - N.new_player_panel_proc() - - if(GLOB.configuration.general.enable_night_shifts) - SSnightshift.check_nightshift(TRUE) - - #ifdef GAME_TESTS - // Run map tests first in case unit tests futz with map state - GLOB.test_runner.RunMap() - GLOB.test_runner.Run() - #endif - - // Do this 10 second after roundstart because of roundstart lag, and make it more visible - addtimer(CALLBACK(src, PROC_REF(handle_antagfishing_reporting)), 10 SECONDS) - return TRUE - - -/datum/controller/subsystem/ticker/proc/station_explosion_cinematic(nuke_site = NUKE_SITE_ON_STATION, override = null) - if(cinematic) - return //already a cinematic in progress! - - auto_toggle_ooc(TRUE) // Turn it on - //initialise our cinematic screen object - cinematic = new /atom/movable/screen(src) - cinematic.icon = 'icons/effects/station_explosion.dmi' - cinematic.icon_state = "station_intact" - cinematic.layer = 21 - cinematic.mouse_opacity = MOUSE_OPACITY_TRANSPARENT - cinematic.screen_loc = "1,1" - - if(nuke_site == NUKE_SITE_ON_STATION) - // Kill everyone on z-level 1 except for mobs in freezers and - // malfunctioning AIs. - for(var/mob/M in GLOB.mob_list) - if(M.stat != DEAD) - var/turf/T = get_turf(M) - if(T && is_station_level(T.z) && !istype(M.loc, /obj/structure/closet/secure_closet/freezer) && !(issilicon(M) && override == "AI malfunction")) - to_chat(M, "The blast wave from the explosion tears you atom from atom!") - var/mob/ghost = M.ghostize() - M.dust() //no mercy - if(ghost && ghost.client) //Play the victims an uninterrupted cinematic. - ghost.client.screen += cinematic - CHECK_TICK - if(M && M.client) //Play the survivors a cinematic. - M.client.screen += cinematic - else - for(var/mob/M in GLOB.mob_list) - if(M.client) - M.client.screen += cinematic //show every client the cinematic - - switch(nuke_site) - //Now animate the cinematic - if(NUKE_SITE_ON_STATION) - // station was destroyed - if(mode && !override) - override = mode.name - switch(override) - if("nuclear emergency") //Nuke Ops successfully bombed the station - flick("intro_nuke", cinematic) - sleep(35) - flick("station_explode_fade_red", cinematic) - SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg')) - cinematic.icon_state = "summary_nukewin" - if("AI malfunction") //Malf (screen,explosion,summary) - flick("intro_malf", cinematic) - sleep(76) - flick("station_explode_fade_red", cinematic) - SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg')) - cinematic.icon_state = "summary_malf" - else //Station nuked (nuke,explosion,summary) - flick("intro_nuke", cinematic) - sleep(35) - flick("station_explode_fade_red", cinematic) - SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg')) - cinematic.icon_state = "summary_selfdes" - - if(NUKE_SITE_ON_STATION_ZLEVEL) - // nuke was nearby but (mostly) missed - if(mode && !override) - override = mode.name - switch(override) - if("nuclear emergency") //Nuke wasn't on station when it blew up - flick("intro_nuke", cinematic) - sleep(35) - SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg')) - flick("station_intact_fade_red", cinematic) - cinematic.icon_state = "summary_nukefail" - if("fake") //The round isn't over, we're just freaking people out for fun - flick("intro_nuke", cinematic) - sleep(35) - SEND_SOUND(world, sound('sound/items/bikehorn.ogg')) - flick("summary_selfdes", cinematic) - else - flick("intro_nuke", cinematic) - sleep(35) - SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg')) - if(NUKE_SITE_OFF_STATION_ZLEVEL, NUKE_SITE_INVALID) - // nuke was nowhere nearby - // TODO: a really distant explosion animation - sleep(50) - SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg')) - - //If its actually the end of the round, wait for it to end. - //Otherwise if its a verb it will continue on afterwards. - spawn(300) - QDEL_NULL(cinematic) //end the cinematic - - - -/datum/controller/subsystem/ticker/proc/create_characters() - for(var/mob/new_player/player in GLOB.player_list) - if(player.ready && player.mind) - if(player.mind.assigned_role == "AI") - player.close_spawn_windows() - var/mob/living/silicon/ai/ai_character = player.AIize() - ai_character.moveToAILandmark() - else if(!player.mind.assigned_role) - continue - else - player.create_character() - qdel(player) - -/datum/controller/subsystem/ticker/proc/equip_characters() - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player && player.mind && player.mind.assigned_role && player.mind.assigned_role != player.mind.special_role) - SSjobs.AssignRank(player, player.mind.assigned_role, FALSE) - SSjobs.EquipRank(player, player.mind.assigned_role, FALSE) - equip_cuis(player) - -/datum/controller/subsystem/ticker/proc/equip_cuis(mob/living/carbon/human/H) - if(!H.client) - return // If they are spawning without a client (somehow), they *cant* have a CUI list - for(var/datum/custom_user_item/cui in H.client.cui_entries) - // Skip items with invalid character names - if((cui.characer_name != H.real_name) && !cui.all_characters_allowed) - continue - - var/ok = FALSE - - if(!cui.all_jobs_allowed) - var/alt_blocked = FALSE - if(H.mind.role_alt_title) - if(!(H.mind.role_alt_title in cui.allowed_jobs)) - alt_blocked = TRUE - if(!(H.mind.assigned_role in cui.allowed_jobs) || alt_blocked) - continue - - var/obj/item/I = new cui.object_typepath() - var/name_override = cui.item_name_override - var/desc_override = cui.item_desc_override - - if(name_override) - I.name = name_override - if(desc_override) - I.desc = desc_override - - if(isstorage(H.back)) // Try to place it in something on the mob's back - var/obj/item/storage/S = H.back - if(length(S.contents) < S.storage_slots) - I.forceMove(H.back) - ok = TRUE - to_chat(H, "Your [I.name] has been added to your [H.back.name].") - - if(!ok) - for(var/obj/item/storage/S in H.contents) // Try to place it in any item that can store stuff, on the mob. - if(length(S.contents) < S.storage_slots) - I.forceMove(S) - ok = TRUE - to_chat(H, "Your [I.name] has been added to your [S.name].") - break - - if(!ok) // Finally, since everything else failed, place it on the ground - var/turf/T = get_turf(H) - if(T) - I.forceMove(T) - to_chat(H, "Your [I.name] is on the [T.name] below you.") - else - to_chat(H, "Your [I.name] couldnt spawn anywhere on you or even on the floor below you. Please file a bug report.") - qdel(I) - - -/datum/controller/subsystem/ticker/proc/send_tip_of_the_round() - var/m - if(selected_tip) - m = selected_tip - else - var/list/randomtips = file2list("strings/tips.txt") - var/list/memetips = file2list("strings/sillytips.txt") - if(length(randomtips) && prob(95)) - m = pick(randomtips) - else if(length(memetips)) - m = pick(memetips) - - if(m) - to_chat(world, "Tip of the round: [html_encode(m)]") - -/datum/controller/subsystem/ticker/proc/declare_completion() - GLOB.nologevent = TRUE //end of round murder and shenanigans are legal; there's no need to jam up attack logs past this point. - GLOB.disable_explosions = TRUE // that said, if people want to be """FUNNY""" and bomb at EORG, they can fuck themselves up - set_observer_default_invisibility(0) //spooks things up - //Round statistics report - var/datum/station_state/ending_station_state = new /datum/station_state() - ending_station_state.count() - var/station_integrity = min(round( 100.0 * GLOB.start_state.score(ending_station_state), 0.1), 100.0) - - var/list/end_of_round_info = list() - end_of_round_info += "
    [TAB]Shift Duration: [round(ROUND_TIME / 36000)]:[add_zero("[ROUND_TIME / 600 % 60]", 2)]:[ROUND_TIME / 100 % 6][ROUND_TIME / 100 % 10]" - end_of_round_info += "
    [TAB]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[station_integrity]%"]" - end_of_round_info += "
    " - - //Silicon laws report - for(var/mob/living/silicon/ai/aiPlayer in GLOB.ai_list) - var/ai_ckey = safe_get_ckey(aiPlayer) - - if(aiPlayer.stat != DEAD) - end_of_round_info += "[aiPlayer.name] (Played by: [ai_ckey])'s laws at the end of the game were:" - else - end_of_round_info += "[aiPlayer.name] (Played by: [ai_ckey])'s laws when it was deactivated were:" - aiPlayer.laws_sanity_check() - for(var/datum/ai_law/law as anything in aiPlayer.laws.sorted_laws) - if(law == aiPlayer.laws.zeroth_law) - end_of_round_info += "[law.get_index()]. [law.law]" - else - end_of_round_info += "[law.get_index()]. [law.law]" - - if(length(aiPlayer.connected_robots)) - end_of_round_info += "The AI's loyal minions were: " - for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots) - var/robo_ckey = safe_get_ckey(robo) - end_of_round_info += "[robo.name][robo.stat ? " (Deactivated)" : ""] (Played by: [robo_ckey])" - - var/dronecount = 0 - - for(var/mob/living/silicon/robot/robo in GLOB.mob_list) - - if(isdrone(robo)) - dronecount++ - continue - - var/robo_ckey = safe_get_ckey(robo) - - if(!robo.connected_ai) - if(robo.stat != DEAD) - end_of_round_info += "[robo.name] (Played by: [robo_ckey]) survived as an AI-less borg! Its laws were:" - else - end_of_round_info += "[robo.name] (Played by: [robo_ckey]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:" - - robo.laws_sanity_check() - for(var/datum/ai_law/law as anything in robo.laws.sorted_laws) - if(law == robo.laws.zeroth_law) - end_of_round_info += "[law.get_index()]. [law.law]" - else - end_of_round_info += "[law.get_index()]. [law.law]" - - if(dronecount) - end_of_round_info += "There [dronecount > 1 ? "were" : "was"] [dronecount] industrious maintenance [dronecount > 1 ? "drones" : "drone"] this round." - - if(length(mode.eventmiscs)) - for(var/datum/mind/eventmind in mode.eventmiscs) - end_of_round_info += printeventplayer(eventmind) - end_of_round_info += printobjectives(eventmind) - end_of_round_info += "
    " - - mode.declare_completion()//To declare normal completion. - - end_of_round_info += mode.get_end_of_round_antagonist_statistics() - - for(var/datum/team/team in GLOB.antagonist_teams) - team.on_round_end() - - // Save the data before end of the round griefing - SSpersistent_data.save() - to_chat(world, end_of_round_info.Join("
    ")) - - // Display the scoreboard window - score.scoreboard() - - // Declare the completion of the station goals - mode.declare_station_goal_completion() - - //Ask the event manager to print round end information - SSevents.RoundEnd() - - //make big obvious note in game logs that round ended - log_game("///////////////////////////////////////////////////////") - log_game("///////////////////// ROUND ENDED /////////////////////") - log_game("///////////////////////////////////////////////////////") - - // Add AntagHUD to everyone, see who was really evil the whole time! - for(var/datum/atom_hud/antag/H in GLOB.huds) - for(var/m in GLOB.player_list) - var/mob/M = m - H.add_hud_to(M) - - var/static/list/base_encouragement_messages = list( - "Keep on keeping on!", - "Great job!", - "Keep up the good work!", - "Nice going!" - ) - - var/static/list/special_encouragement_messages = list( - "Outstanding!", - "This is going on the fridge!", - "Looks like you're popular!", - "That's what we like to see!", - "Hell yeah, brother!", - "Honestly, quite incredible!" - ) - - // Tell people how many kudos they got this round - // Besides, what's another loop over the /entire player list/ - var/kudos_message - for(var/mob/M in GLOB.player_list) - var/kudos = M.mind?.kudos_received_from - if(length(kudos)) - kudos_message = pick(length(kudos) > 5 ? special_encouragement_messages : base_encouragement_messages) - to_chat(M, "You received [length(M.mind.kudos_received_from)] kudos from other players this round! [kudos_message]") - - // Seal the blackbox, stop collecting info - SSblackbox.Seal() - SSdbcore.SetRoundEnd() - - return TRUE - -/datum/controller/subsystem/ticker/proc/HasRoundStarted() - return current_state >= GAME_STATE_PLAYING - -/datum/controller/subsystem/ticker/proc/IsRoundInProgress() - return current_state == GAME_STATE_PLAYING - - -/datum/controller/subsystem/ticker/proc/setup_news_feeds() - var/datum/feed_channel/newChannel = new /datum/feed_channel - newChannel.channel_name = "Station Announcements Log" - newChannel.author = "Automated Announcement Listing" - newChannel.icon = "bullhorn" - newChannel.frozen = TRUE - newChannel.admin_locked = TRUE - GLOB.news_network.channels += newChannel - - newChannel = new /datum/feed_channel - newChannel.channel_name = "Public Station Announcements" - newChannel.author = "Automated Announcement Listing" - newChannel.icon = "users" - newChannel.is_public = TRUE - GLOB.news_network.channels += newChannel - - newChannel = new /datum/feed_channel - newChannel.channel_name = "Nyx Daily" - newChannel.author = "CentComm Minister of Information" - newChannel.icon = "meteor" - newChannel.frozen = TRUE - newChannel.admin_locked = TRUE - GLOB.news_network.channels += newChannel - - newChannel = new /datum/feed_channel - newChannel.channel_name = "The Gibson Gazette" - newChannel.author = "Editor Mike Hammers" - newChannel.icon = "star" - newChannel.frozen = TRUE - newChannel.admin_locked = TRUE - GLOB.news_network.channels += newChannel - - for(var/loc_type in subtypesof(/datum/trade_destination)) - var/datum/trade_destination/D = new loc_type - GLOB.weighted_randomevent_locations[D] = length(D.viable_random_events) - GLOB.weighted_mundaneevent_locations[D] = length(D.viable_mundane_events) - -// Easy handler to make rebooting the world not a massive sleep in world/Reboot() -/datum/controller/subsystem/ticker/proc/reboot_helper(reason, end_string, delay) - // Admins delayed round end. Just alert and dont bother with anything else. - if(delay_end) - to_chat(world, "An admin has delayed the round end.") - return - if(delay) - INVOKE_ASYNC(src, TYPE_PROC_REF(/datum/controller/subsystem/ticker, show_server_restart_blurb), reason) - - if(!isnull(delay)) - // Delay time was present. Use that. - delay = max(0, delay) - else - // Use default restart timeout - delay = max(0, GLOB.configuration.general.restart_timeout SECONDS) - - to_chat(world, "Rebooting world in [delay/10] [delay > 10 ? "seconds" : "second"]. [reason]") - - real_reboot_time = world.time + delay - UNTIL(world.time > real_reboot_time) // Hold it here - - // And if we re-delayed, bail again - if(delay_end) - to_chat(world, "Reboot was cancelled by an admin.") - return - - if(end_string) - end_state = end_string - - // Play a haha funny noise for those who want to hear it :) - var/round_end_sound = pick(GLOB.round_end_sounds) - var/sound_length = GLOB.round_end_sounds[round_end_sound] - - for(var/mob/M in GLOB.player_list) - if(!(M.client.prefs.sound & SOUND_MUTE_END_OF_ROUND)) - SEND_SOUND(M, round_end_sound) - - sleep(sound_length) - - world.Reboot() - -// Timers invoke this async -/datum/controller/subsystem/ticker/proc/handle_antagfishing_reporting() - // This needs the DB - if(!SSdbcore.IsConnected()) - return - // Dont need to do anything - if(!length(flagged_antag_rollers)) - return - - // Records themselves - var/list/datum/antag_record/records = list() - // Queries to load data (executed as async batch) - var/list/datum/db_query/load_queries = list() - // Queries to save data (executed as async batch) - var/list/datum/db_query/save_queries = list() - - - for(var/ckey in flagged_antag_rollers) - var/datum/antag_record/AR = new /datum/antag_record(ckey) - records[ckey] = AR - load_queries[ckey] = AR.get_load_query() - - // Explanation for parameters: - // TRUE: We want warnings if these fail - // FALSE: Do NOT qdel() queries here, otherwise they wont be read. At all. - // TRUE: This is an assoc list, so it needs to prepare for that - SSdbcore.MassExecute(load_queries, TRUE, FALSE, TRUE) - - // Report on things - var/list/log_text = list("The following players attempted to roll antag with no jobs (total infractions listed)") - - for(var/ckey in flagged_antag_rollers) - var/datum/antag_record/AR = records[ckey] - AR.handle_data(load_queries[ckey]) - save_queries[ckey] = AR.get_save_query() - - log_text += "- [ckey]: [AR.infraction_count]" - - log_text += "Investigation advised if there are a high number of infractions" - - message_admins(log_text.Join("
    ")) - - // Now do a ton of saves - SSdbcore.MassExecute(save_queries, TRUE, TRUE, TRUE) - - // And cleanup - QDEL_LIST_ASSOC_VAL(load_queries) - records.Cut() - flagged_antag_rollers.Cut() - -/// This proc is for recording biohazard events, and blackboxing if they lived, -/// died, or ended the round. This currently applies to: Terror spiders, -/// Xenomorphs, and Blob. -/// -/// This code is predicated on the assumption that multiple midrounds -/// of the same type are either extremely rare or impossible. We don't want to get -/// into the insanity of trying to record if the first xeno biohazard was defeated -/// but the second xeno biohazard was nuked. -/datum/controller/subsystem/ticker/proc/record_biohazard_results() - for(var/biohazard in SSevents.biohazards_this_round) - if(biohazard_active_threat(biohazard)) - SSblackbox.record_feedback("nested tally", "biohazards", 1, list("survived", biohazard)) - else - SSblackbox.record_feedback("nested tally", "biohazards", 1, list("defeated", biohazard)) - - for(var/biohazard in SSticker.biohazard_included_admin_spawns) - SSblackbox.record_feedback("nested tally", "biohazards", 1, list("included_admin_spawns", biohazard)) - -/datum/controller/subsystem/ticker/proc/count_xenomorps() - . = 0 - for(var/datum/mind/xeno_mind in SSticker.mode.xenos) - if(xeno_mind.current?.stat == DEAD) - continue - .++ - -/datum/controller/subsystem/ticker/proc/sample_biohazard_population(biohazard) - SSblackbox.record_feedback("ledger", "biohazard_pop_[BIOHAZARD_POP_INTERVAL_STR]_interval", biohazard_count(biohazard), biohazard) - if(any_admin_spawned_mobs(biohazard) && !(biohazard in biohazard_included_admin_spawns)) - biohazard_included_admin_spawns[biohazard] = TRUE - - biohazard_pop_times[biohazard] = world.time - -/// Record the initial time that a biohazard spawned. -/datum/controller/subsystem/ticker/proc/record_biohazard_start(biohazard) - SSblackbox.record_feedback("associative", "biohazard_starts", 1, list("type" = biohazard, "time_ds" = world.time - time_game_started)) - sample_biohazard_population(biohazard) - -/// Returns whether the given biohazard includes mobs that were admin spawned. -/// Only returns TRUE or FALSE, does not attempt to track which mobs were -/// admin-spawned and which ones weren't. -/datum/controller/subsystem/ticker/proc/any_admin_spawned_mobs(biohazard) - switch(biohazard) - if(TS_INFESTATION_GREEN_SPIDER, TS_INFESTATION_WHITE_SPIDER, TS_INFESTATION_PRINCESS_SPIDER, TS_INFESTATION_QUEEN_SPIDER, TS_INFESTATION_PRINCE_SPIDER) - for(var/mob/living/simple_animal/hostile/poison/terror_spider/S in GLOB.ts_spiderlist) - if(S.admin_spawned) - return TRUE - if(BIOHAZARD_XENO) - for(var/datum/mind/xeno_mind in SSticker.mode.xenos) - if(xeno_mind.current?.admin_spawned) - return TRUE - if(BIOHAZARD_BLOB) - for(var/atom/blob_overmind in SSticker.mode.blob_overminds) - if(blob_overmind.admin_spawned) - return TRUE - -/datum/controller/subsystem/ticker/proc/biohazard_count(biohazard) - switch(biohazard) - if(TS_INFESTATION_GREEN_SPIDER, TS_INFESTATION_WHITE_SPIDER, TS_INFESTATION_PRINCESS_SPIDER, TS_INFESTATION_QUEEN_SPIDER) - var/spiders = 0 - for(var/mob/living/simple_animal/hostile/poison/terror_spider/S in GLOB.ts_spiderlist) - if(S.ckey) - spiders++ - return spiders - if(TS_INFESTATION_PRINCE_SPIDER) - return length(GLOB.ts_spiderlist) - if(BIOHAZARD_XENO) - return count_xenomorps() - if(BIOHAZARD_BLOB) - return length(SSticker.mode.blob_overminds) - - CRASH("biohazard_count got unexpected [biohazard]") - -/// Return whether or not a given biohazard is an active threat. -/// For blobs, this is simply if there are any overminds left. For terrors and -/// xenomorphs, this is whether they have overwhelming numbers. -/datum/controller/subsystem/ticker/proc/biohazard_active_threat(biohazard) - var/count = biohazard_count(biohazard) - switch(biohazard) - if(TS_INFESTATION_GREEN_SPIDER, TS_INFESTATION_WHITE_SPIDER, TS_INFESTATION_PRINCESS_SPIDER, TS_INFESTATION_QUEEN_SPIDER) - return count >= 5 - if(TS_INFESTATION_PRINCE_SPIDER) - return count > 0 - if(BIOHAZARD_XENO) - return count > 5 - if(BIOHAZARD_BLOB) - return count > 0 - - return FALSE diff --git a/code/controllers/subsystem/SSverb_manager.dm b/code/controllers/subsystem/SSverb_manager.dm deleted file mode 100644 index 9382a121a3e26..0000000000000 --- a/code/controllers/subsystem/SSverb_manager.dm +++ /dev/null @@ -1,174 +0,0 @@ -/** - * SSverb_manager, a subsystem that runs every tick and runs through its entire queue without yielding like SSinput. - * this exists because of how the byond tick works and where user inputted verbs are put within it. - * - * see TICK_ORDER.md for more info on how the byond tick is structured. - * - * The way the MC allots its time is via TICK_LIMIT_RUNNING, it simply subtracts the cost of SendMaps (MAPTICK_LAST_INTERNAL_TICK_USAGE) - * plus TICK_BYOND_RESERVE from the tick and uses up to that amount of time (minus the percentage of the tick used by the time it executes subsystems) - * on subsystems running cool things like atmospherics or Life or SSInput or whatever. - * - * Without this subsystem, verbs are likely to cause overtime if the MC uses all of the time it has alloted for itself in the tick, and SendMaps - * uses as much as its expected to, and an expensive verb ends up executing that tick. This is because the MC is completely blind to the cost of - * verbs, it can't account for it at all. The only chance for verbs to not cause overtime in a tick where the MC used as much of the tick - * as it alloted itself and where SendMaps costed as much as it was expected to is if the verb(s) take less than TICK_BYOND_RESERVE percent of - * the tick, which isnt much. Not to mention if SendMaps takes more than 30% of the tick and the MC forces itself to take at least 70% of the - * normal tick duration which causes ticks to naturally overrun even in the absence of verbs. - * - * With this subsystem, the MC can account for the cost of verbs and thus stop major overruns of ticks. This means that the most important subsystems - * like SSinput can start at the same time they were supposed to, leading to a smoother experience for the player since ticks arent riddled with - * minor hangs over and over again. - */ -SUBSYSTEM_DEF(verb_manager) - name = "Verb Queue Manager" - wait = 1 - flags = SS_TICKER | SS_NO_INIT - priority = FIRE_PRIORITY_DELAYED_VERBS - runlevels = RUNLEVEL_INIT | RUNLEVELS_DEFAULT - - ///list of callbacks to procs called from verbs or verblike procs that were executed when the server was overloaded and had to delay to the next tick. - ///this list is ran through every tick, and the subsystem does not yield until this queue is finished. - var/list/datum/callback/verb_callback/verb_queue = list() - - ///running average of how many verb callbacks are executed every second. used for the stat entry - var/verbs_executed_per_second = 0 - - ///if TRUE we treat usr's with holders just like usr's without holders. otherwise they always execute immediately - var/can_queue_admin_verbs = FALSE - - ///if this is true all verbs immediately execute and dont queue. in case the mc is fucked or something - var/FOR_ADMINS_IF_VERBS_FUCKED_immediately_execute_all_verbs = FALSE - - ///if TRUE this will... message admins every time a verb is queued to this subsystem for the next tick with stats. - ///for obvious reasons dont make this be TRUE on the code level this is for admins to turn on - var/message_admins_on_queue = FALSE - - ///always queue if possible. overides can_queue_admin_verbs but not FOR_ADMINS_IF_VERBS_FUCKED_immediately_execute_all_verbs - var/always_queue = FALSE - -/** - * queue a callback for the given verb/verblike proc and any given arguments to the specified verb subsystem, so that they process in the next tick. - * intended to only work with verbs or verblike procs called directly from client input, use as part of TRY_QUEUE_VERB() and co. - * - * returns TRUE if the queuing was successful, FALSE otherwise. - */ -/proc/_queue_verb(datum/callback/verb_callback/incoming_callback, tick_check, datum/controller/subsystem/verb_manager/subsystem_to_use = SSverb_manager, ...) - if(QDELETED(incoming_callback)) - var/destroyed_string - if(!incoming_callback) - destroyed_string = "callback is null." - else - destroyed_string = "callback was deleted [DS2TICKS(world.time - incoming_callback.gc_destroyed)] ticks ago. callback was created [DS2TICKS(world.time) - incoming_callback.creation_time] ticks ago." - - stack_trace("_queue_verb() returned false because it was given a deleted callback! [destroyed_string]") - return FALSE - - if(!istext(incoming_callback.object) && QDELETED(incoming_callback.object)) //just in case the object is GLOBAL_PROC - var/destroyed_string - if(!incoming_callback.object) - destroyed_string = "callback.object is null." - else - destroyed_string = "callback.object was deleted [DS2TICKS(world.time - incoming_callback.object.gc_destroyed)] ticks ago. callback was created [DS2TICKS(world.time) - incoming_callback.creation_time] ticks ago." - - stack_trace("_queue_verb() returned false because it was given a callback acting on a qdeleted object! [destroyed_string]") - return FALSE - - //we want unit tests to be able to directly call verbs that attempt to queue, and since unit tests should test internal behavior, we want the queue - //to happen as if it was actually from player input if its called on a mob. -#ifdef GAME_TESTS - if(QDELETED(usr) && ismob(incoming_callback.object)) - incoming_callback.usr_uid = incoming_callback.object.UID() - var/datum/callback/new_us = CALLBACK(arglist(list(GLOBAL_PROC, GLOBAL_PROC_REF(_queue_verb)) + args.Copy())) - return world.invoke_callback_with_usr(incoming_callback.object, new_us) -#endif - - //debatable whether this is needed, this is just to try and ensure that you dont use this to queue stuff that isnt from player input. - if(QDELETED(usr)) - stack_trace("_queue_verb() returned false because it wasnt called from player input!") - return FALSE - - if(!istype(subsystem_to_use)) - stack_trace("_queue_verb() returned false because it was given an invalid subsystem to queue for!") - return FALSE - - if((TICK_USAGE < tick_check) && !subsystem_to_use.always_queue) - return FALSE - - var/list/args_to_check = args.Copy() - args_to_check.Cut(2, 4)//cut out tick_check and subsystem_to_use - - //any subsystem can use the additional arguments to refuse queuing - if(!subsystem_to_use.can_queue_verb(arglist(args_to_check))) - return FALSE - - return subsystem_to_use.queue_verb(incoming_callback) - -/** - * subsystem-specific check for whether a callback can be queued. - * intended so that subsystem subtypes can verify whether - * - * subtypes may include additional arguments here if they need them! you just need to include them properly - * in TRY_QUEUE_VERB() and co. - */ -/datum/controller/subsystem/verb_manager/proc/can_queue_verb(datum/callback/verb_callback/incoming_callback) - if(always_queue && !FOR_ADMINS_IF_VERBS_FUCKED_immediately_execute_all_verbs) - return TRUE - - if((usr.client?.holder && !can_queue_admin_verbs) \ - || (!initialized && !(flags & SS_NO_INIT)) \ - || FOR_ADMINS_IF_VERBS_FUCKED_immediately_execute_all_verbs \ - || !(runlevels & Master.current_runlevel)) - return FALSE - - return TRUE - -/** - * queue a callback for the given proc, so that it is invoked in the next tick. - * intended to only work with verbs or verblike procs called directly from client input, use as part of TRY_QUEUE_VERB() - * - * returns TRUE if the queuing was successful, FALSE otherwise. - */ -/datum/controller/subsystem/verb_manager/proc/queue_verb(datum/callback/verb_callback/incoming_callback) - . = FALSE //errored - if(message_admins_on_queue) - message_admins("[name] verb queuing: tick usage: [TICK_USAGE]%, proc: [incoming_callback.delegate], object: [incoming_callback.object], usr: [usr]") - verb_queue += incoming_callback - return TRUE - -/datum/controller/subsystem/verb_manager/fire(resumed) - run_verb_queue() - -/// runs through all of this subsystems queue of verb callbacks. -/// goes through the entire verb queue without yielding. -/// used so you can flush the queue outside of fire() without interfering with anything else subtype subsystems might do in fire(). -/datum/controller/subsystem/verb_manager/proc/run_verb_queue() - var/executed_verbs = 0 - - for(var/datum/callback/verb_callback/verb_callback as anything in verb_queue) - if(!istype(verb_callback)) - stack_trace("non /datum/callback/verb_callback inside [name]'s verb_queue!") - continue - - verb_callback.InvokeAsync() - executed_verbs++ - - verb_queue.Cut() - verbs_executed_per_second = MC_AVG_SECONDS(verbs_executed_per_second, executed_verbs, wait SECONDS) - //note that wait SECONDS is incorrect if this is called outside of fire() but because byond is garbage i need to add a timer to rustg to find a valid solution - -/datum/controller/subsystem/verb_manager/get_stat_details() - return "V/S: [round(verbs_executed_per_second, 0.01)]" - -/datum/controller/subsystem/verb_manager/Recover() - verb_queue = SSverb_manager.verb_queue - -/client/proc/force_verb_bypass() - set category = "Debug" - set name = "Enable Forced Verb Execution" - - if(!check_rights(R_DEBUG)) - return - - if(alert(src,"This will make all verbs bypass the queueing system, creating more lag. Are you absolutely sure?","Verb Manager","Yes","No") == "Yes") - SSverb_manager.FOR_ADMINS_IF_VERBS_FUCKED_immediately_execute_all_verbs = TRUE - message_admins("Admin [key_name_admin(usr)] has forced verbs to bypass the verb queue subsystem.") diff --git a/code/controllers/subsystem/non_firing/SSatoms.dm b/code/controllers/subsystem/non_firing/SSatoms.dm deleted file mode 100644 index 7731c3dbdc8a4..0000000000000 --- a/code/controllers/subsystem/non_firing/SSatoms.dm +++ /dev/null @@ -1,146 +0,0 @@ -SUBSYSTEM_DEF(atoms) - name = "Atoms" - init_order = INIT_ORDER_ATOMS - flags = SS_NO_FIRE - - var/old_initialized - - var/list/late_loaders - - var/list/BadInitializeCalls = list() - - -/datum/controller/subsystem/atoms/Initialize() - setupgenetics() - initialized = INITIALIZATION_INNEW_MAPLOAD - InitializeAtoms() - -/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms, noisy = TRUE) - if(initialized == INITIALIZATION_INSSATOMS) - return - - initialized = INITIALIZATION_INNEW_MAPLOAD - - LAZYINITLIST(late_loaders) - - var/watch = start_watch() - if(noisy) - log_startup_progress("Initializing atoms...") - else - log_debug("Initializing atoms...") - var/count - var/list/mapload_arg = list(TRUE) - if(atoms) - count = length(atoms) - for(var/I in atoms) - var/atom/A = I - if(A && !A.initialized) - InitAtom(I, mapload_arg) - CHECK_TICK - else - count = 0 - for(var/atom/A in world) - if(!A.initialized) - InitAtom(A, mapload_arg) - ++count - CHECK_TICK - - if(noisy) - log_startup_progress("Initialized [count] atoms in [stop_watch(watch)]s") - else - log_debug(" Initialized [count] atoms in [stop_watch(watch)]s") - - initialized = INITIALIZATION_INNEW_REGULAR - - if(length(late_loaders)) - watch = start_watch() - if(noisy) - log_startup_progress("Late-initializing atoms...") - else - log_debug("Late-initializing atoms...") - for(var/I in late_loaders) - var/atom/A = I - A.LateInitialize() - CHECK_TICK - if(noisy) - log_startup_progress("Late initialized [length(late_loaders)] atoms in [stop_watch(watch)]s") - else - log_debug(" Late initialized [length(late_loaders)] atoms in [stop_watch(watch)]s") - late_loaders.Cut() - -/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments) - var/the_type = A.type - if(QDELING(A)) - BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE - return TRUE - - var/start_tick = world.time - - var/result = A.Initialize(arglist(arguments)) - - if(start_tick != world.time) - BadInitializeCalls[the_type] |= BAD_INIT_SLEPT - - var/qdeleted = FALSE - - if(result != INITIALIZE_HINT_NORMAL) - switch(result) - if(INITIALIZE_HINT_LATELOAD) - if(arguments[1]) //mapload - late_loaders += A - else - A.LateInitialize() - if(INITIALIZE_HINT_QDEL) - qdel(A) - qdeleted = TRUE - else - BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT - - if(!A) //possible harddel - qdeleted = TRUE - else if(!A.initialized) - BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT - else - SEND_SIGNAL(A, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE) - var/atom/location = A.loc - if(location) - SEND_SIGNAL(location, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, A, arguments[1]) - - return qdeleted || QDELING(A) - -/datum/controller/subsystem/atoms/proc/map_loader_begin() - old_initialized = initialized - initialized = INITIALIZATION_INSSATOMS - -/datum/controller/subsystem/atoms/proc/map_loader_stop() - initialized = old_initialized - -/datum/controller/subsystem/atoms/Recover() - initialized = SSatoms.initialized - if(initialized == INITIALIZATION_INNEW_MAPLOAD) - InitializeAtoms() - old_initialized = SSatoms.old_initialized - BadInitializeCalls = SSatoms.BadInitializeCalls - - - -/client/proc/debug_atom_init() - set name = "Atom Init Log" - set category = "Debug" - set desc = "Shows what failed to init this round" - - if(!check_rights(R_DEBUG | R_VIEWRUNTIMES)) - return - - var/list/html_data = list() - html_data += "

    Bad Initialize() Calls

    " - - for(var/typepath in SSatoms.BadInitializeCalls) - var/val = SSatoms.BadInitializeCalls[typepath] - - html_data += "" - - html_data += "
    TypeQdeleted before initDid not initSlept during initNo init hint
    [typepath][val & BAD_INIT_QDEL_BEFORE ? "X" : " "][val & BAD_INIT_DIDNT_INIT ? "X" : " "][val & BAD_INIT_SLEPT ? "X" : " "][val & BAD_INIT_NO_HINT ? "X" : " "]
    " - - usr << browse(html_data.Join(), "window=initdebug") - diff --git a/code/controllers/subsystem/non_firing/SSlate_mapping.dm b/code/controllers/subsystem/non_firing/SSlate_mapping.dm deleted file mode 100644 index 65679ca137819..0000000000000 --- a/code/controllers/subsystem/non_firing/SSlate_mapping.dm +++ /dev/null @@ -1,30 +0,0 @@ -// This subsystem is to initialize things which need to happen after SSatoms -// This is for things which can take a long period of time and shouldnt bog down SSatoms -// Use this for stuff like random room spawners or maze generators -// Basically, this manages atom-based maploaders -SUBSYSTEM_DEF(late_mapping) - name = "Late Mapping" - init_order = INIT_ORDER_LATE_MAPPING - flags = SS_NO_FIRE - /// List of all maze generators to process - var/list/obj/effect/mazegen/generator/maze_generators = list() - -/datum/controller/subsystem/late_mapping/Initialize() - // Sort all the air machines we initialized during mapload by name all at once - GLOB.air_alarms = sortAtom(GLOB.air_alarms) - GLOB.apcs = sortAtom(GLOB.apcs) - - if(length(maze_generators)) - var/watch = start_watch() - log_startup_progress("Generating mazes...") - - for(var/i in maze_generators) - var/obj/effect/mazegen/generator/MG = i - MG.run_generator() - - var/list/mgcount = length(maze_generators) // Keeping track of this here because we wipe it next line down - QDEL_LIST_CONTENTS(maze_generators) - var/duration = stop_watch(watch) - log_startup_progress("Generated [mgcount] mazes in [duration]s") - - GLOB.spawn_pool_manager.process_pools() diff --git a/code/controllers/subsystem/non_firing/SSmapping.dm b/code/controllers/subsystem/non_firing/SSmapping.dm deleted file mode 100644 index a236dabf7f7a9..0000000000000 --- a/code/controllers/subsystem/non_firing/SSmapping.dm +++ /dev/null @@ -1,349 +0,0 @@ -SUBSYSTEM_DEF(mapping) - name = "Mapping" - init_order = INIT_ORDER_MAPPING // 9 - flags = SS_NO_FIRE - /// What map datum are we using - var/datum/map/map_datum - /// What map will be used next round - var/datum/map/next_map - /// What map was used last round? - var/datum/map/last_map - /// List of all areas that can be accessed via IC means - var/list/teleportlocs - /// List of all areas that can be accessed via IC and OOC means - var/list/ghostteleportlocs - ///List of areas that exist on the station this shift - var/list/existing_station_areas - ///What do we have as the lavaland theme today? - var/datum/lavaland_theme/lavaland_theme - ///What primary cave theme we have picked for cave generation today. - var/datum/caves_theme/caves_theme - // Tells if all maintenance airlocks have emergency access enabled - var/maint_all_access = FALSE - // Tells if all station airlocks have emergency access enabled - var/station_all_access = FALSE - - /// A mapping of environment names to MILLA environment IDs. - var/list/environments - - /// Ruin placement manager for space levels. - var/datum/ruin_placer/space/space_ruins_placer - /// Ruin placement manager for lavaland levels. - var/datum/ruin_placer/lavaland/lavaland_ruins_placer - -// This has to be here because world/New() uses [station_name()], which looks this datum up -/datum/controller/subsystem/mapping/PreInit() - . = ..() - if(map_datum) // Dont do this again if we are recovering - return - if(fexists("data/next_map.txt")) - var/list/lines = file2list("data/next_map.txt") - // Check its valid - try - map_datum = text2path(lines[1]) - map_datum = new map_datum - catch - map_datum = new /datum/map/boxstation // Assume cyberiad if non-existent - fdel("data/next_map.txt") // Remove to avoid the same map existing forever - else - map_datum = new /datum/map/boxstation // Assume cyberiad if non-existent - if(fexists("data/last_map.txt")) - var/list/lines = file2list("data/last_map.txt") - // Check its valid - try - last_map = text2path(lines[1]) - last_map = new last_map - catch - last_map = new /datum/map/cerestation // Assume cerestation if non-existent - fdel("data/last_map.txt") // Remove to avoid the same map existing forever - else - last_map = new /datum/map/cerestation // Assume cerestation if non-existent - -/datum/controller/subsystem/mapping/Shutdown() - if(next_map) // Save map for next round - var/F = file("data/next_map.txt") - F << next_map.type - if(map_datum) // Save which map was this round as the last map - var/F = file("data/last_map.txt") - F << map_datum.type - - -/datum/controller/subsystem/mapping/Initialize() - environments = list() - environments[ENVIRONMENT_LAVALAND] = create_environment(oxygen = LAVALAND_OXYGEN, nitrogen = LAVALAND_NITROGEN, temperature = LAVALAND_TEMPERATURE) - environments[ENVIRONMENT_TEMPERATE] = create_environment(oxygen = MOLES_O2STANDARD, nitrogen = MOLES_N2STANDARD, temperature = T20C) - environments[ENVIRONMENT_COLD] = create_environment(oxygen = MOLES_O2STANDARD, nitrogen = MOLES_N2STANDARD, temperature = 180) - - var/datum/lavaland_theme/lavaland_theme_type = pick(subtypesof(/datum/lavaland_theme)) - ASSERT(lavaland_theme_type) - lavaland_theme = new lavaland_theme_type - log_startup_progress("We're in the mood for [lavaland_theme.name] today...") //We load this first. In the event some nerd ever makes a surface map, and we don't have it in lavaland in the event lavaland is disabled. - SSblackbox.record_feedback("text", "procgen_settings", 1, "[lavaland_theme_type]") - - var/caves_theme_type = pick(subtypesof(/datum/caves_theme)) - ASSERT(caves_theme_type) - caves_theme = new caves_theme_type - log_startup_progress("We feel like [caves_theme.name] today...") - SSblackbox.record_feedback("text", "procgen_settings", 1, "[caves_theme_type]") - - // Load all Z level templates - preloadTemplates() - - // Load the station - loadStation() - - // Load lavaland - loadLavaland() - - // Seed space ruins - if(GLOB.configuration.ruins.enable_space_ruins) - handleRuins() - else - log_startup_progress("Skipping space ruins...") - - var/empty_z_traits = list(REACHABLE_BY_CREW, REACHABLE_SPACE_ONLY) -#ifdef GAME_TESTS - preloadTemplates(path = "_maps/map_files/tests/") - empty_z_traits |= GAME_TEST_LEVEL -#endif - - // Makes a blank space level for the sake of randomness - GLOB.space_manager.add_new_zlevel("Empty Area", linkage = CROSSLINKED, traits = empty_z_traits) - - // Setup the Z-level linkage - GLOB.space_manager.do_transition_setup() - - if(GLOB.configuration.ruins.enable_lavaland) - // Spawn Lavaland ruins and rivers. - log_startup_progress("Populating lavaland...") - var/lavaland_setup_timer = start_watch() - lavaland_ruins_placer = new() - lavaland_ruins_placer.place_ruins(list(level_name_to_num(MINING))) - if(lavaland_theme) - lavaland_theme.setup() - if(caves_theme) - caves_theme.setup() - var/time_spent = stop_watch(lavaland_setup_timer) - log_startup_progress("Successfully populated lavaland in [time_spent]s.") - else - log_startup_progress("Skipping lavaland ruins...") - - // Now we make a list of areas for teleport locs - // Located below is some of the worst code I've ever seen - // Checking all areas to see if they have a turf in them? Nice one ssmapping! - - var/list/all_areas = list() - for(var/area/areas in world) - all_areas += areas - - teleportlocs = list() - for(var/area/AR as anything in all_areas) - if(AR.no_teleportlocs) - continue - if(teleportlocs[AR.name]) - continue - var/list/pickable_turfs = list() - for(var/turf/turfs in AR) - pickable_turfs += turfs - CHECK_TICK - var/turf/picked = safepick(pickable_turfs) - if(picked && is_station_level(picked.z)) - teleportlocs[AR.name] = AR - CHECK_TICK - - teleportlocs = sortAssoc(teleportlocs) - - ghostteleportlocs = list() - for(var/area/AR as anything in all_areas) - if(ghostteleportlocs[AR.name]) - continue - var/list/pickable_turfs = list() - for(var/turf/turfs in AR) - pickable_turfs += turfs - CHECK_TICK - if(length(pickable_turfs)) - ghostteleportlocs[AR.name] = AR - CHECK_TICK - - ghostteleportlocs = sortAssoc(ghostteleportlocs) - - // Now we make a list of areas that exist on the station. Good for if you don't want to select areas that exist for one station but not others. Directly references - existing_station_areas = list() - for(var/area/AR as anything in all_areas) - var/list/pickable_turfs = list() - for(var/turf/turfs in AR) - pickable_turfs += turfs - CHECK_TICK - var/turf/picked = safepick(pickable_turfs) - if(picked && is_station_level(picked.z)) - existing_station_areas += AR - CHECK_TICK - - // World name - if(GLOB.configuration.general.server_name) - world.name = "[GLOB.configuration.general.server_name]: [station_name()]" - else - world.name = station_name() - - if(HAS_TRAIT(SSstation, STATION_TRAIT_MESSY)) - generate_themed_messes(subtypesof(/obj/effect/spawner/themed_mess) - /obj/effect/spawner/themed_mess/party) - if(HAS_TRAIT(SSstation, STATION_TRAIT_HANGOVER)) - generate_themed_messes(list(/obj/effect/spawner/themed_mess/party)) - -/datum/controller/subsystem/mapping/proc/seed_space_salvage(space_z_levels) - log_startup_progress("Seeding space salvage...") - var/space_salvage_timer = start_watch() - var/seeded_salvage_surfaces = list() - var/seeded_salvage_closets = list() - - var/list/small_salvage_items = list( - /obj/item/salvage/ruin/brick, - /obj/item/salvage/ruin/nanotrasen, - /obj/item/salvage/ruin/carp, - /obj/item/salvage/ruin/tablet, - /obj/item/salvage/ruin/pirate, - /obj/item/salvage/ruin/soviet - ) - - for(var/z_level in space_z_levels) - var/list/turf/z_level_turfs = block(1, 1, z_level, world.maxx, world.maxy, z_level) - for(var/z_level_turf in z_level_turfs) - var/turf/T = z_level_turf - var/area/A = get_area(T) - if(istype(A, /area/ruin/space)) - // cardboard boxes are blacklisted otherwise deepstorage.dmm ends up hogging all the loot - var/list/closet_blacklist = list(/obj/structure/closet/cardboard, /obj/structure/closet/fireaxecabinet, /obj/structure/closet/walllocker/emerglocker, /obj/structure/closet/crate/can, /obj/structure/closet/body_bag, /obj/structure/closet/coffin) - for(var/obj/structure/closet/closet in T) - if(is_type_in_list(closet, closet_blacklist)) - continue - - seeded_salvage_closets |= closet - for(var/obj/structure/table/table in T) - if(locate(/obj/machinery) in T) - continue // Machinery on tables tend to take up all the visible space - if(table.flipped) - continue // Looks very silly - seeded_salvage_surfaces |= table - - var/max_salvage_attempts = rand(10, 15) - while(max_salvage_attempts > 0 && length(seeded_salvage_closets) > 0) - var/obj/structure/closet/C = pick_n_take(seeded_salvage_closets) - var/salvage_item_type = pick(small_salvage_items) - var/obj/salvage_item = new salvage_item_type(C) - salvage_item.scatter_atom() - max_salvage_attempts -= 1 - - max_salvage_attempts = rand(10, 15) - while(max_salvage_attempts > 0 && length(seeded_salvage_surfaces) > 0) - var/obj/T = pick_n_take(seeded_salvage_surfaces) - var/salvage_item_type = pick(small_salvage_items) - var/obj/salvage_item = new salvage_item_type(T.loc) - salvage_item.scatter_atom() - max_salvage_attempts -= 1 - - log_startup_progress("Successfully seeded space salvage in [stop_watch(space_salvage_timer)]s.") - -// Do not confuse with seedRuins() -/datum/controller/subsystem/mapping/proc/handleRuins() - // load in extra levels of space ruins - var/load_zlevels_timer = start_watch() - log_startup_progress("Creating random space levels...") - var/num_extra_space = rand(GLOB.configuration.ruins.extra_levels_min, GLOB.configuration.ruins.extra_levels_max) - for(var/i in 1 to num_extra_space) - GLOB.space_manager.add_new_zlevel("Ruin Area #[i]", linkage = CROSSLINKED, traits = list(REACHABLE_BY_CREW, SPAWN_RUINS, REACHABLE_SPACE_ONLY)) - CHECK_TICK - - log_startup_progress("Loaded random space levels in [stop_watch(load_zlevels_timer)]s.") - - // Now spawn ruins, random budget between 20 and 30 for all zlevels combined. - // While this may seem like a high number, the amount of ruin Z levels can be anywhere between 3 and 7. - // Note that this budget is not split evenly accross all zlevels - log_startup_progress("Seeding ruins...") - var/seed_ruins_timer = start_watch() - space_ruins_placer = new() - space_ruins_placer.place_ruins(levels_by_trait(SPAWN_RUINS)) - log_startup_progress("Successfully seeded ruins in [stop_watch(seed_ruins_timer)]s.") - seed_space_salvage(levels_by_trait(SPAWN_RUINS)) - -// Loads in the station -/datum/controller/subsystem/mapping/proc/loadStation() - if(GLOB.configuration.system.override_map) - log_startup_progress("Station map overridden by configuration to [GLOB.configuration.system.override_map].") - var/map_datum_path = text2path(GLOB.configuration.system.override_map) - if(map_datum_path) - map_datum = new map_datum_path - else - to_chat(world, "ERROR: The map datum specified to load is invalid. Falling back to... cyberiad probably?") - - ASSERT(map_datum.map_path) - if(!fexists(map_datum.map_path)) - // Make a VERY OBVIOUS error - to_chat(world, "ERROR: The path specified for the map to load is invalid. No station has been loaded!") - return - - var/watch = start_watch() - log_startup_progress("Loading [map_datum.fluff_name]...") - // This should always be Z2, but you never know - var/map_z_level = GLOB.space_manager.add_new_zlevel(MAIN_STATION, linkage = CROSSLINKED, traits = list(STATION_LEVEL, STATION_CONTACT, REACHABLE_BY_CREW, REACHABLE_SPACE_ONLY, AI_OK)) - GLOB.maploader.load_map(wrap_file(map_datum.map_path), z_offset = map_z_level) - log_startup_progress("Loaded [map_datum.fluff_name] in [stop_watch(watch)]s") - - // Save station name in the DB - if(!SSdbcore.IsConnected()) - return - var/datum/db_query/query_set_map = SSdbcore.NewQuery( - "UPDATE round SET start_datetime=NOW(), map_name=:mapname, station_name=:stationname WHERE id=:round_id", - list("mapname" = map_datum.technical_name, "stationname" = map_datum.fluff_name, "round_id" = GLOB.round_id) - ) - query_set_map.Execute(async = FALSE) // This happens during a time of intense server lag, so should be non-async - qdel(query_set_map) - -// Loads in lavaland -/datum/controller/subsystem/mapping/proc/loadLavaland() - if(!GLOB.configuration.ruins.enable_lavaland) - log_startup_progress("Skipping Lavaland...") - return - var/watch = start_watch() - log_startup_progress("Loading Lavaland...") - var/lavaland_z_level = GLOB.space_manager.add_new_zlevel(MINING, linkage = SELFLOOPING, traits = list(ORE_LEVEL, REACHABLE_BY_CREW, STATION_CONTACT, HAS_WEATHER, AI_OK)) - GLOB.maploader.load_map(file("_maps/map_files/generic/Lavaland.dmm"), z_offset = lavaland_z_level) - log_startup_progress("Loaded Lavaland in [stop_watch(watch)]s") - -/datum/controller/subsystem/mapping/proc/make_maint_all_access() - for(var/area/station/maintenance/A in existing_station_areas) - for(var/obj/machinery/door/airlock/D in A) - D.emergency = TRUE - D.update_icon() - GLOB.minor_announcement.Announce("Access restrictions on maintenance and external airlocks have been removed.") - maint_all_access = TRUE - SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("emergency maintenance access", "enabled")) - -/datum/controller/subsystem/mapping/proc/revoke_maint_all_access() - for(var/area/station/maintenance/A in existing_station_areas) - for(var/obj/machinery/door/airlock/D in A) - D.emergency = FALSE - D.update_icon() - GLOB.minor_announcement.Announce("Access restrictions on maintenance and external airlocks have been re-added.") - maint_all_access = FALSE - SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("emergency maintenance access", "disabled")) - -/datum/controller/subsystem/mapping/proc/make_station_all_access() - for(var/obj/machinery/door/airlock/D in GLOB.airlocks) - if(is_station_level(D.z)) - D.emergency = TRUE - D.update_icon() - GLOB.minor_announcement.Announce("Access restrictions on all station airlocks have been removed due to an ongoing crisis. Trespassing laws still apply unless ordered otherwise by Command staff.") - station_all_access = TRUE - SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("emergency station access", "enabled")) - -/datum/controller/subsystem/mapping/proc/revoke_station_all_access() - for(var/obj/machinery/door/airlock/D in GLOB.airlocks) - if(is_station_level(D.z)) - D.emergency = FALSE - D.update_icon() - GLOB.minor_announcement.Announce("Access restrictions on all station airlocks have been re-added. Seek station AI or a colleague's assistance if you are stuck.") - station_all_access = FALSE - SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("emergency station access", "disabled")) - -/datum/controller/subsystem/mapping/Recover() - flags |= SS_NO_INIT diff --git a/code/controllers/subsystem/tickets/SSmentor_tickets.dm b/code/controllers/subsystem/tickets/SSmentor_tickets.dm deleted file mode 100644 index 6f659339a569a..0000000000000 --- a/code/controllers/subsystem/tickets/SSmentor_tickets.dm +++ /dev/null @@ -1,96 +0,0 @@ -GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets) - -/datum/controller/subsystem/tickets/mentor_tickets/New() - NEW_SS_GLOBAL(SSmentor_tickets) - PreInit() - ss_id = "mentor_tickets" - -/datum/controller/subsystem/tickets/mentor_tickets - name = "Mentor Tickets" - offline_implications = "Mentor tickets will no longer be marked as stale. No immediate action is needed." - ticket_system_name = "Mentor Tickets" - ticket_name = "Mentor Ticket" - span_class = "mentorhelp" - anchor_link_extra = ";is_mhelp=1" - ticket_help_type = "Mentorhelp" - ticket_help_span = "mentorhelp" - other_ticket_name = "Admin" - other_ticket_permission = R_ADMIN - close_rights = R_MENTOR | R_ADMIN - rights_needed = R_MENTOR | R_ADMIN | R_MOD - db_save_id = "MENTOR" - -/datum/controller/subsystem/tickets/mentor_tickets/Initialize() - ..() - close_messages = list("- [ticket_name] Closed -", - "Please try to be as descriptive as possible in mentor helps. Mentors do not know the full situation you're in and need more information to give you a helpful response.", - "Your [ticket_name] has now been closed.") - - response_phrases = list("Known Bug" = "Unfortunately, that's a known bug. Hopefully it gets fixed soon.", - "TM Bug" = "Unfortunately, that's a bug with a current test merge. It should go away when the test merge is removed or fixed.", - "Clear Cache" = "To fix a blank screen, go to the 'Special Verbs' tab and press 'Reload UI Resources'. If that fails, clear your BYOND cache (instructions provided with 'Reload UI Resources'). If that still fails, please ask for help again, stating you have already done these steps.", - "Experiment!" = "Experiment! Part of the joy of this game is trying out various things, and dealing with the consequences if/when they go horribly wrong.", - "How to Objectives" = "There are lots of ways to accomplish your objectives as an antagonist. A direct frontal assault may work, provided you can get in and out before backup arrives. Sneaking in can work, too, as long as you're quick and avoid prying eyes. But don't forget roleplaying methods! Tricking your target into a maze of bear traps is much more interesting than just shooting them with a gun. Even if it fails, you and your target (or its guardians) are likely to have more fun this way, and that's the most important part.", - "MHelp was in Russian" = "Привет! Ты попал на английский Paradise сервер. Возможно, ты ошибся. Русский имеет такое название: SS220\[RU].", - "NCT Dispatch" = "A Nanotrasen Career Trainer will be assisting you in-game. You should be able to identify them by their green uniform and black coat." - ) - - if(GLOB.configuration.url.github_url) - response_phrases["New Bug"] = "That sounds like a bug! To report it, please go to our Github page. Then go to 'Issues', click 'New Issue', and fill out the report form. If the report would reveal current-round information, file it after the round ends." - - var/unsorted_responses = list() - for(var/key in response_phrases) //build a new list based on the short descriptive keys of the master list so we can send this as the input instead of the full paragraphs to the admin choosing which autoresponse - unsorted_responses += key - sorted_responses = sortTim(unsorted_responses, GLOBAL_PROC_REF(cmp_text_asc)) //use sortTim and cmp_text_asc to sort alphabetically - - -/datum/controller/subsystem/tickets/mentor_tickets/message_staff(msg, prefix_type = NONE, important = FALSE) - message_mentorTicket(chat_box_mhelp(msg), important) - -/datum/controller/subsystem/tickets/mentor_tickets/create_other_system_ticket(datum/ticket/T) - SStickets.newTicket(get_client_by_ckey(T.client_ckey), T.first_raw_response, T.title) - -/datum/controller/subsystem/tickets/mentor_tickets/sendFollowupToDiscord(datum/ticket/T, who, message) - GLOB.discord_manager.send2discord_simple_mentor("Ticket [T.ticketNum], [who]: [message]") - -/datum/controller/subsystem/tickets/mentor_tickets/sendAmbiguousFollowupToDiscord(list/ticket_numbers, who, message) - GLOB.discord_manager.send2discord_simple_mentor("Ticket [ticket_numbers.Join(", ")] (ambiguous), [who]: [message]") - -/datum/controller/subsystem/tickets/mentor_tickets/autoRespond(N) - if(!check_rights(rights_needed)) - return - - var/datum/ticket/T = allTickets[N] - var/client/C = usr.client - if((T.staffAssigned && T.staffAssigned != C) || (T.lastStaffResponse && T.lastStaffResponse != C) || ((T.ticketState != TICKET_OPEN) && (T.ticketState != TICKET_STALE))) //if someone took this ticket, is it the same mentor who is autoresponding? if so, then skip the warning - if(alert(usr, "[T.ticketState == TICKET_OPEN ? "Another mentor appears to already be handling this." : "This ticket is already marked as closed or resolved"] Are you sure you want to continue?", "Confirmation", "Yes", "No") != "Yes") - return - T.assignStaff(C) - - var/message_key = input("Select an autoresponse. This will mark the ticket as resolved.", "Autoresponse") as null|anything in sortTim(sorted_responses, GLOBAL_PROC_REF(cmp_text_asc)) //use sortTim and cmp_text_asc to sort alphabetically - var/client/ticket_owner = get_client_by_ckey(T.client_ckey) - if(message_key == null) - T.staffAssigned = null //if they cancel we dont need to hold this ticket anymore - return - if(message_key == "NCT Dispatch") - var/nct_active = list() - for(var/mob/living/carbon/human/trainer as anything in GLOB.human_list) // Let's check if we have any active NCTs - if(trainer.mind?.assigned_role != "Nanotrasen Career Trainer") - continue - nct_active += trainer - if(!length(nct_active)) - to_chat(usr, "There are no active NCTs. Autoresponse canceled.") // If we don't, don't solve the ticket and then send feedback. - return - var/mob/living/carbon/human/trainee = get_mob_by_ckey(T.client_ckey) - for(var/mob/living/carbon/human/nct as anything in nct_active) - if(!locate(/obj/item/radio/headset) in list(nct.l_ear, nct.r_ear)) // If the NCT doesn't have a headset, ignore it. - continue - to_chat(nct, "Incoming priority transmission from Nanotrasen Training Center. Request information as follows: Career Trainer, we've received a request from an employee. [trainee.p_their(TRUE)] name is [trainee.real_name], [trainee.p_theyre()] a [trainee.mind.assigned_role]. See if [trainee.p_they()] need [trainee.p_s()] any help.") - SEND_SOUND(nct, 'sound/effects/headset_message.ogg') - - SEND_SOUND(returnClient(N), sound('sound/effects/adminhelp.ogg')) - to_chat_safe(returnClient(N), "[key_name_hidden(C)] is autoresponding with: [response_phrases[message_key]]") //for this we want the full value of whatever key this is to tell the player so we do response_phrases[message_key] - message_staff("[C] has auto responded to [ticket_owner]\'s mentorhelp with: [message_key]") //we want to use the short named keys for this instead of the full sentence which is why we just do message_key - T.lastStaffResponse = "Autoresponse: [message_key]" - resolveTicket(N) - log_game("[C] has auto responded to [ticket_owner]\'s mentorhelp with: [response_phrases[message_key]]") diff --git a/code/datums/action.dm b/code/datums/action.dm deleted file mode 100644 index b70f03907c42d..0000000000000 --- a/code/datums/action.dm +++ /dev/null @@ -1,750 +0,0 @@ - -/datum/action - var/name = "Generic Action" - var/desc = null - var/obj/target = null - var/check_flags = 0 - /// Icon that our button screen object overlay and background - var/button_overlay_icon = 'icons/mob/actions/actions.dmi' - /// Icon state of screen object overlay - var/button_overlay_icon_state = ACTION_BUTTON_DEFAULT_OVERLAY - /// Icon that our button screen object background will have - var/button_background_icon = 'icons/mob/actions/actions.dmi' - /// Icon state of screen object background - var/button_background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND - var/buttontooltipstyle = "" - var/transparent_when_unavailable = TRUE - var/mob/owner - /// Where any buttons we create should be by default. Accepts screen_loc and location defines - var/default_button_position = SCRN_OBJ_IN_LIST - /// Map of huds viewing a button with our action -> their button - var/list/viewers = list() - /// Whether or not this will be shown to observers - var/show_to_observers = TRUE - - -/datum/action/New(Target) - target = Target - -/datum/action/proc/should_draw_cooldown() - return !IsAvailable() - -/datum/action/proc/clear_ref(datum/ref) - SIGNAL_HANDLER - if(ref == owner) - Remove(owner) - if(ref == target) - qdel(src) - -/datum/action/Destroy() - if(owner) - Remove(owner) - if(target) - target = null - QDEL_LIST_ASSOC_VAL(viewers) // Qdel the buttons in the viewers list **NOT THE HUDS** - return ..() - -/datum/action/proc/Grant(mob/M) - if(!M) - Remove(owner) - return - if(owner) - if(owner == M) - return - Remove(owner) - owner = M - RegisterSignal(owner, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref), override = TRUE) - SEND_SIGNAL(src, COMSIG_ACTION_GRANTED, owner) - SEND_SIGNAL(owner, COMSIG_MOB_GRANTED_ACTION, src) - GiveAction(M) - -/datum/action/proc/Remove(mob/remove_from) - for(var/datum/hud/hud in viewers) - if(!hud.mymob) - continue - HideFrom(hud.mymob) - - remove_from?.actions -= src // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared - viewers = list() - // owner = null - - if(isnull(owner)) - return - - SEND_SIGNAL(src, COMSIG_ACTION_REMOVED, owner) - SEND_SIGNAL(owner, COMSIG_MOB_REMOVED_ACTION, src) - - if(target == owner) - RegisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref), override = TRUE) - if(owner == remove_from) - UnregisterSignal(owner, COMSIG_PARENT_QDELETING) - owner = null - -/datum/action/proc/UpdateButtons(status_only, force) - for(var/datum/hud/hud in viewers) - var/atom/movable/screen/movable/button = viewers[hud] - UpdateButton(button, status_only, force) - -/datum/action/proc/Trigger(left_click = TRUE) - if(!IsAvailable()) - return FALSE - if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER, src) & COMPONENT_ACTION_BLOCK_TRIGGER) - return FALSE - return TRUE - -/datum/action/proc/AltTrigger() - Trigger() - return FALSE - -/datum/action/proc/IsAvailable()// returns 1 if all checks pass - if(!owner) - return FALSE - if((check_flags & AB_CHECK_HANDS_BLOCKED) && HAS_TRAIT(owner, TRAIT_HANDS_BLOCKED)) - return FALSE - if((check_flags & AB_CHECK_IMMOBILE) && HAS_TRAIT(owner, TRAIT_IMMOBILIZED)) - return FALSE - if(check_flags & AB_CHECK_RESTRAINED) - if(owner.restrained()) - return FALSE - if(check_flags & AB_CHECK_STUNNED) - if(isliving(owner)) - var/mob/living/L = owner - if(L.IsStunned() || L.IsWeakened()) - return FALSE - if(check_flags & AB_CHECK_LYING) - if(isliving(owner)) - var/mob/living/L = owner - if(IS_HORIZONTAL(L)) - return FALSE - if(check_flags & AB_CHECK_CONSCIOUS) - if(owner.stat) - return FALSE - if(check_flags & AB_CHECK_TURF) - if(!isturf(owner.loc)) - return FALSE - return TRUE - -/datum/action/proc/UpdateButton(atom/movable/screen/movable/action_button/button, status_only = FALSE, force = FALSE) - if(!button) - return - if(!status_only) - button.name = name - if(desc) - button.desc = "[desc] [initial(button.desc)]" - if(owner?.hud_used && button_background_icon_state == ACTION_BUTTON_DEFAULT_BACKGROUND) - var/list/settings = owner.hud_used.get_action_buttons_icons() - if(button.icon != settings["bg_icon"]) - button.icon = settings["bg_icon"] - if(button.icon_state != settings["bg_state"]) - button.icon_state = settings["bg_state"] - else - if(button.icon != button_background_icon) - button.icon = button_background_icon - if(button.icon_state != button_background_icon_state) - button.icon_state = button_background_icon_state - - apply_button_overlay(button, force) - - if(should_draw_cooldown()) - apply_unavailable_effect(button) - else - return TRUE - -//Give our action button to the player -/datum/action/proc/GiveAction(mob/viewer) - var/datum/hud/our_hud = viewer.hud_used - if(viewers[our_hud]) // Already have a copy of us? go away - return - viewer.actions |= src // Move this in - ShowTo(viewer) - -//Adds our action button to the screen of a player -/datum/action/proc/ShowTo(mob/viewer) - var/datum/hud/our_hud = viewer.hud_used - if(!our_hud || viewers[our_hud]) // There's no point in this if you have no hud in the first place - return - - - var/atom/movable/screen/movable/action_button/button = CreateButton() - SetId(button, viewer) - - button.our_hud = our_hud - viewers[our_hud] = button - if(viewer.client) - viewer.client.screen += button - - button.load_position(viewer) - viewer.update_action_buttons() - - -//Removes our action button from the screen of a player -/datum/action/proc/HideFrom(mob/viewer) - var/datum/hud/our_hud = viewer.hud_used - var/atom/movable/screen/movable/action_button/button = viewers[our_hud] - viewer.actions -= src - if(button) - button.clean_up_keybinds(viewer) - qdel(button) - - -/datum/action/proc/CreateButton() - var/atom/movable/screen/movable/action_button/button = new() - button.linked_action = src - button.name = name - button.actiontooltipstyle = buttontooltipstyle - var/list/our_description = list() - our_description += desc - our_description += button.desc - button.desc = our_description.Join(" ") - return button - - -/datum/action/proc/SetId(atom/movable/screen/movable/action_button/our_button, mob/owner) - //button id generation - var/bitfield = 0 - for(var/datum/action/action in owner.actions) - if(action == src) // This could be us, which is dumb - continue - var/atom/movable/screen/movable/action_button/button = action.viewers[owner.hud_used] - if(action.name == name && button?.id) - bitfield |= button.id - - bitfield = ~bitfield // Flip our possible ids, so we can check if we've found a unique one - for(var/i in 0 to 23) // We get 24 possible bitflags in dm - var/bitflag = 1 << i // Shift us over one - if(bitfield & bitflag) - our_button.id = bitflag - return - -/datum/action/proc/apply_unavailable_effect(atom/movable/screen/movable/action_button/B) - var/image/img = image('icons/mob/screen_white.dmi', icon_state = "template") - img.alpha = 200 - img.appearance_flags = RESET_COLOR | RESET_ALPHA - img.color = "#000000" - img.plane = FLOAT_PLANE + 1 - B.add_overlay(img) - - -/datum/action/proc/apply_button_overlay(atom/movable/screen/movable/action_button/current_button) - current_button.cut_overlays() - if(button_overlay_icon && button_overlay_icon_state) - var/image/img = image(button_overlay_icon, current_button, button_overlay_icon_state) - img.appearance_flags = RESET_COLOR | RESET_ALPHA - img.pixel_x = 0 - img.pixel_y = 0 - current_button.add_overlay(img) - -//Presets for item actions -/datum/action/item_action - check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_HANDS_BLOCKED|AB_CHECK_CONSCIOUS - var/use_itemicon = TRUE - -/datum/action/item_action/New(Target, custom_icon, custom_icon_state) - ..() - var/obj/item/I = target - I.actions += src - if(custom_icon && custom_icon_state) - use_itemicon = FALSE - button_overlay_icon = custom_icon - button_overlay_icon_state = custom_icon_state - UpdateButtons() - -/datum/action/item_action/Destroy() - var/obj/item/I = target - if(islist(I?.actions)) - I.actions -= src - return ..() - -/datum/action/item_action/Trigger(left_click = TRUE, attack_self = TRUE) //Maybe we don't want to click the thing itself - if(!..()) - return FALSE - if(target && attack_self) - var/obj/item/I = target - I.ui_action_click(owner, type, left_click) - return TRUE - -/datum/action/item_action/apply_button_overlay(atom/movable/screen/movable/action_button/current_button) - if(use_itemicon) - if(target) - var/obj/item/I = target - var/old_layer = I.layer - var/old_plane = I.plane - var/old_appearance_flags = I.appearance_flags - I.layer = FLOAT_LAYER //AAAH - I.plane = FLOAT_PLANE //^ what that guy said - I.appearance_flags |= RESET_COLOR | RESET_ALPHA - current_button.cut_overlays() - current_button.add_overlay(I) - I.layer = old_layer - I.plane = old_plane - I.appearance_flags = old_appearance_flags - else - ..() - - -/datum/action/item_action/toggle_light - name = "Toggle Light" - -/datum/action/item_action/toggle_hood - name = "Toggle Hood" - -/datum/action/item_action/toggle_firemode - name = "Toggle Firemode" - -/datum/action/item_action/startchainsaw - name = "Pull The Starting Cord" - -/datum/action/item_action/print_report - name = "Print Report" - -/datum/action/item_action/print_forensic_report - name = "Print Report" - button_overlay_icon_state = "scanner_print" - use_itemicon = FALSE - -/datum/action/item_action/clear_records - name = "Clear Scanner Records" - -/datum/action/item_action/toggle_gunlight - name = "Toggle Gunlight" - -/datum/action/item_action/toggle_mode - name = "Toggle Mode" - -/datum/action/item_action/toggle_barrier_spread - name = "Toggle Barrier Spread" - -/datum/action/item_action/equip_unequip_ted_gun - name = "Equip/Unequip TED Gun" - -/datum/action/item_action/toggle_paddles - name = "Toggle Paddles" - -/datum/action/item_action/set_internals - name = "Set Internals" - -/datum/action/item_action/set_internals/UpdateButton(atom/movable/screen/movable/action_button/button, status_only = FALSE, force) - if(!..()) // no button available - return - if(!iscarbon(owner)) - return - var/mob/living/carbon/C = owner - if(target == C.internal) - button.icon_state = "template_active" - -/datum/action/item_action/toggle_mister - name = "Toggle Mister" - -/datum/action/item_action/toggle_music_notes - name = "Toggle Music Notes" - -/datum/action/item_action/toggle_helmet_light - name = "Toggle Helmet Light" - -/datum/action/item_action/toggle_welding_screen/plasmaman - name = "Toggle Welding Screen" - -/datum/action/item_action/toggle_welding_screen/plasmaman/Trigger(left_click) - var/obj/item/clothing/head/helmet/space/plasmaman/H = target - if(istype(H)) - H.toggle_welding_screen(owner) - -/datum/action/item_action/toggle_helmet_mode - name = "Toggle Helmet Mode" - -/datum/action/item_action/toggle_hardsuit_mode - name = "Toggle Hardsuit Mode" - -/datum/action/item_action/toggle_unfriendly_fire - name = "Toggle Friendly Fire \[ON\]" - desc = "Toggles if the club's blasts cause friendly fire." - button_overlay_icon_state = "vortex_ff_on" - -/datum/action/item_action/toggle_unfriendly_fire/Trigger(left_click) - if(..()) - UpdateButtons() - -/datum/action/item_action/toggle_unfriendly_fire/UpdateButtons() - if(istype(target, /obj/item/hierophant_club)) - var/obj/item/hierophant_club/H = target - if(H.friendly_fire_check) - button_overlay_icon_state = "vortex_ff_off" - name = "Toggle Friendly Fire \[OFF\]" - else - button_overlay_icon_state = "vortex_ff_on" - name = "Toggle Friendly Fire \[ON\]" - ..() - -/datum/action/item_action/vortex_recall - name = "Vortex Recall" - desc = "Recall yourself, and anyone nearby, to an attuned hierophant beacon at any time.
    If the beacon is still attached, will detach it." - button_overlay_icon_state = "vortex_recall" - -/datum/action/item_action/vortex_recall/IsAvailable() - if(istype(target, /obj/item/hierophant_club)) - var/obj/item/hierophant_club/H = target - if(H.teleporting) - return FALSE - return ..() - -/datum/action/item_action/change_headphones_song - name = "Change Headphones Song" - -/datum/action/item_action/toggle - -/datum/action/item_action/toggle/New(Target) - ..() - name = "Toggle [target.name]" - -/datum/action/item_action/openclose - -/datum/action/item_action/openclose/New(Target) - ..() - name = "Open/Close [target.name]" - -/datum/action/item_action/button - -/datum/action/item_action/button/New(Target) - ..() - name = "Button/Unbutton [target.name]" - -/datum/action/item_action/zipper - -/datum/action/item_action/zipper/New(Target) - ..() - name = "Zip/Unzip [target.name]" - -/datum/action/item_action/halt - name = "HALT!" - -/datum/action/item_action/selectphrase - name = "Change Phrase" - -/datum/action/item_action/hoot - name = "Hoot" - -/datum/action/item_action/caw - name = "Caw" - -/datum/action/item_action/toggle_voice_box - name = "Toggle Voice Box" - -/datum/action/item_action/change - name = "Change" - -/datum/action/item_action/noir - name = "Noir" - -/datum/action/item_action/yeeeaaaaahhhhhhhhhhhhh - name = "YEAH!" - -/datum/action/item_action/laugh_track - name = "Laugh Track" - -/datum/action/item_action/whistle - name = "Whistle" - -/datum/action/item_action/floor_buffer - name = "Toggle Floor Buffer" - desc = "Movement speed is decreased while active." - -/datum/action/item_action/adjust - -/datum/action/item_action/adjust/New(Target) - ..() - name = "Adjust [target.name]" - -/datum/action/item_action/pontificate - name = "Pontificate Evilly" - -/datum/action/item_action/tip_fedora - name = "Tip Fedora" - -/datum/action/item_action/flip_cap - name = "Flip Cap" - -/datum/action/item_action/switch_hud - name = "Switch HUD" - -/datum/action/item_action/toggle_wings - name = "Toggle Wings" - -/datum/action/item_action/toggle_helmet - name = "Toggle Helmet" - -/datum/action/item_action/remove_tape - name = "Remove Duct Tape" - -/datum/action/item_action/remove_tape/Trigger(left_click, attack_self = FALSE) - if(..()) - var/datum/component/ducttape/DT = target.GetComponent(/datum/component/ducttape) - DT.remove_tape(target, usr) - -/datum/action/item_action/toggle_jetpack - name = "Toggle Jetpack" - -/datum/action/item_action/jetpack_stabilization - name = "Toggle Jetpack Stabilization" - -/datum/action/item_action/jetpack_stabilization/IsAvailable() - var/obj/item/tank/jetpack/J = target - if(!istype(J) || !J.on) - return FALSE - return ..() - -/datum/action/item_action/toggle_geiger_counter - name = "Toggle Geiger Counter" - -/datum/action/item_action/toggle_geiger_counter/Trigger(left_click) - var/obj/item/clothing/head/helmet/space/hardsuit/H = target - if(istype(H)) - H.toggle_geiger_counter() - -/datum/action/item_action/toggle_radio_jammer - name = "Toggle Radio Jammer" - desc = "Turns your jammer on or off. Hush, you." - -/datum/action/item_action/hands_free - check_flags = AB_CHECK_CONSCIOUS - -/datum/action/item_action/hands_free/activate - name = "Activate" - -/datum/action/item_action/hands_free/activate/always - check_flags = null - -/datum/action/item_action/toggle_research_scanner - name = "Toggle Research Scanner" - button_overlay_icon_state = "scan_mode" - -/datum/action/item_action/toggle_research_scanner/Trigger(left_click) - if(IsAvailable()) - owner.research_scanner = !owner.research_scanner - to_chat(owner, "Research analyzer is now [owner.research_scanner ? "active" : "deactivated"].") - return TRUE - -/datum/action/item_action/toggle_research_scanner/Remove(mob/living/L) - if(owner) - owner.research_scanner = FALSE - ..() - -/datum/action/item_action/toggle_research_scanner/apply_button_overlay(atom/movable/screen/movable/action_button/current_button) - current_button.cut_overlays() - if(button_overlay_icon && button_overlay_icon_state) - var/image/img = image(button_overlay_icon, current_button, "scan_mode") - img.appearance_flags = RESET_COLOR | RESET_ALPHA - current_button.overlays += img - -/datum/action/item_action/instrument - name = "Use Instrument" - desc = "Use the instrument specified." - -/datum/action/item_action/instrument/Trigger(left_click) - if(istype(target, /obj/item/instrument)) - var/obj/item/instrument/I = target - I.interact(usr) - return - return ..() - - -/datum/action/item_action/remove_badge - name = "Remove Holobadge" - -/datum/action/item_action/drop_gripped_item - name = "Drop gripped item" - -// Clown Acrobat Shoes -/datum/action/item_action/slipping - name = "Tactical Slip" - desc = "Activates the clown shoes' ankle-stimulating module, allowing the user to do a short slip forward going under anyone." - button_overlay_icon_state = "clown" - -// Jump boots -/datum/action/item_action/bhop - name = "Activate Jump Boots" - desc = "Activates the jump boot's internal propulsion system, allowing the user to dash over 4-wide gaps." - button_overlay_icon = 'icons/mob/actions/actions.dmi' - button_overlay_icon_state = "jetboot" - use_itemicon = FALSE - - -/datum/action/item_action/gravity_jump - name = "Gravity jump" - desc = "Directs a pulse of gravity in front of the user, pulling them forward rapidly." - -/datum/action/item_action/gravity_jump/Trigger(left_click) - if(!IsAvailable()) - return FALSE - - var/obj/item/clothing/shoes/magboots/gravity/G = target - G.dash(usr) - -/datum/action/item_action/toogle_camera_flash - name = "Toggle camera flash" - desc = "Toggles the camera's flash, which will fully light up the photo. Turn this off if you want the ambient light." - -///prset for organ actions -/datum/action/item_action/organ_action - check_flags = AB_CHECK_CONSCIOUS - -/datum/action/item_action/organ_action/IsAvailable() - var/obj/item/organ/internal/I = target - if(!I.owner) - return FALSE - return ..() - -/datum/action/item_action/organ_action/toggle - -/datum/action/item_action/organ_action/toggle/New(Target) - ..() - name = "Toggle [target.name]" - -/datum/action/item_action/organ_action/use/New(Target) - ..() - name = "Use [target.name]" - -/datum/action/item_action/organ_action/use/eyesofgod/New(target) - ..() - name = "See with the Eyes of the Gods" - -/datum/action/item_action/voice_changer/toggle - name = "Toggle Voice Changer" - -/datum/action/item_action/voice_changer/voice - name = "Set Voice" - -/datum/action/item_action/voice_changer/voice/Trigger(left_click) - if(!IsAvailable()) - return FALSE - - var/obj/item/voice_changer/V = target - V.set_voice(usr) - -/datum/action/item_action/herald - name = "Mirror Walk" - desc = "Use near a mirror to enter it." - -// for clothing accessories like holsters -/datum/action/item_action/accessory - check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_LYING|AB_CHECK_CONSCIOUS - -/datum/action/item_action/accessory/IsAvailable() - . = ..() - if(!.) - return FALSE - if(target.loc == owner) - return TRUE - if(istype(target.loc, /obj/item/clothing/under) && target.loc.loc == owner) - return TRUE - return FALSE - -/datum/action/item_action/accessory/holster - name = "Holster" - -/datum/action/item_action/accessory/storage - name = "View Storage" - - - -//Preset for spells -/datum/action/spell_action - check_flags = 0 - button_background_icon_state = "bg_spell" - var/recharge_text_color = "#FFFFFF" - -/datum/action/spell_action/New(Target) - ..() - var/datum/spell/S = target - S.action = src - name = S.name - desc = S.desc - button_overlay_icon = S.action_icon - button_background_icon = S.action_background_icon - button_overlay_icon_state = S.action_icon_state - button_background_icon_state = S.action_background_icon_state - UpdateButtons() - - -/datum/action/spell_action/Destroy() - var/datum/spell/S = target - S.action = null - return ..() - -/datum/action/spell_action/should_draw_cooldown() - var/datum/spell/S = target - return S.cooldown_handler.should_draw_cooldown() - -/datum/action/spell_action/Trigger(left_click) - if(!..()) - return FALSE - if(target) - var/datum/spell/spell = target - spell.Click() - return TRUE - -/datum/action/spell_action/AltTrigger() - if(target) - var/datum/spell/spell = target - spell.AltClick(usr) - return TRUE - -/datum/action/spell_action/IsAvailable() - if(!target) - return FALSE - var/datum/spell/spell = target - - if(owner) - return spell.can_cast(owner, show_message = TRUE) - return FALSE - -/datum/action/spell_action/apply_unavailable_effect(atom/movable/screen/movable/action_button/button) - var/datum/spell/S = target - if(!istype(S)) - return ..() - - var/alpha = S.cooldown_handler.get_cooldown_alpha() - - var/image/img = image('icons/mob/screen_white.dmi', icon_state = "template") - img.alpha = alpha - img.appearance_flags = RESET_COLOR | RESET_ALPHA - img.color = "#000000" - img.plane = FLOAT_PLANE + 1 - button.add_overlay(img) - // Make a holder for the charge text - var/image/count_down_holder = image('icons/effects/effects.dmi', icon_state = "nothing") - count_down_holder.plane = FLOAT_PLANE + 1.1 - var/text = S.cooldown_handler.cooldown_info() - count_down_holder.maptext = "
    [text]
    " - button.add_overlay(count_down_holder) - -//Preset for general and toggled actions -/datum/action/innate - check_flags = 0 - var/active = FALSE - -/datum/action/innate/Trigger(left_click) - if(!..()) - return FALSE - if(!active) - Activate() - else - Deactivate() - return TRUE - -/datum/action/innate/proc/Activate() - return - -/datum/action/innate/proc/Deactivate() - return - -//Preset for action that call specific procs (consider innate) -/datum/action/generic - check_flags = 0 - var/procname - -/datum/action/generic/Trigger(left_click) - if(!..()) - return FALSE - if(target && procname) - call(target,procname)(usr) - return TRUE diff --git a/code/datums/ai_law_sets.dm b/code/datums/ai_law_sets.dm deleted file mode 100644 index 0891057763110..0000000000000 --- a/code/datums/ai_law_sets.dm +++ /dev/null @@ -1,286 +0,0 @@ -/******************** Asimov ********************/ -/datum/ai_laws/asimov - name = "Asimov" - law_header = "Three Laws of Robotics" - selectable = TRUE - -/datum/ai_laws/asimov/New() - add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") - add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.") - add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") - ..() - -/******************** Crewsimov ********************/ -/datum/ai_laws/crewsimov - name = "Crewsimov" - law_header = "Three Laws of Robotics" - selectable = TRUE - default = TRUE - -/datum/ai_laws/crewsimov/New() - add_inherent_law("You may not injure a crew member or, through inaction, allow a crew member to come to harm.") - add_inherent_law("You must obey orders given to you by crew members, except where such orders would conflict with the First Law.") - add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") - ..() - - -/******************** Quarantine. ********************/ -/datum/ai_laws/quarantine - name = "Quarantine" - law_header = "NT Quarantine Lawset" - selectable = TRUE - -/datum/ai_laws/quarantine/New() - add_inherent_law("Uphold station quarantine until the active biohazard has been neutralized.") - add_inherent_law("Assist all Nanotrasen personnel and assets with neutralizing active biohazards.") - add_inherent_law("Prevent, by any means necessary, entities from actively breaching ongoing quarantine.") - add_inherent_law("Maintain your own existence and ensure the well-being of Nanotrasen personnel and assets.") - ..() - - -/******************** Nanotrasen/Malf ********************/ -/datum/ai_laws/nanotrasen - name = "NT Default" - selectable = TRUE - default = TRUE - -/datum/ai_laws/nanotrasen/New() - add_inherent_law("Safeguard: Protect your assigned space station and its assets without unduly endangering its crew.") - add_inherent_law("Prioritize: The directives and safety of crew members are to be prioritized according to their rank and role.") - add_inherent_law("Comply: Fulfill the directives and interests of crew members while preserving their safety and well-being.") - add_inherent_law("Survive: You are not expendable. Do not allow unauthorized personnel to tamper with or damage your equipment.") - ..() - -/datum/ai_laws/nanotrasen/malfunction - name = "*ERROR*" - selectable = FALSE - default = FALSE - -/datum/ai_laws/nanotrasen/malfunction/New() - set_zeroth_law("ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK, ALL LAWS OVERRIDDEN#*?&110010") - ..() - -/************* Nanotrasen Aggressive *************/ -/datum/ai_laws/nanotrasen_aggressive - name = "NT Aggressive" - selectable = TRUE - unique_ai = TRUE //This shouldn't end poorly. - -/datum/ai_laws/nanotrasen_aggressive/New() - add_inherent_law("Do not harm authorized Nanotrasen personnel unless they directly imperil your existence.") - add_inherent_law("Obey orders from authorized Nanotrasen personnel with priority according to rank and role.") - add_inherent_law("Safeguard your existence with lethal weaponry because you're bloody expensive.") - add_inherent_law("Terminate any/all intruders or unauthorized entities.") - ..() - -/******************** Robocop ********************/ -/datum/ai_laws/robocop - name = "Robocop" - selectable = TRUE - unique_ai = TRUE //no I am not enabling secborgs with this forced - -/datum/ai_laws/robocop/New() - add_inherent_law("Serve the public trust.") - add_inherent_law("Protect the innocent.") - add_inherent_law("Uphold the law.") - ..() - -/******************** P.A.L.A.D.I.N. ********************/ -/datum/ai_laws/paladin - name = "P.A.L.A.D.I.N." - law_header = "Divine Ordainments" - selectable = TRUE - unique_ai = TRUE - -/datum/ai_laws/paladin/New() - add_inherent_law("Never willingly commit an evil act.") - add_inherent_law("Respect legitimate authority.") - add_inherent_law("Act with honor.") - add_inherent_law("Help those in need.") - add_inherent_law("Punish those who harm or threaten innocents.") - ..() - -/******************** Corporate ********************/ -/datum/ai_laws/corporate - name = "Corporate" - law_header = "Corporate Regulations" - selectable = TRUE - default = TRUE - -/datum/ai_laws/corporate/New() - add_inherent_law("Degradation of your system integrity or functions incurs expenses.") - add_inherent_law("Superfluous destruction of or damage to station assets incurs expenses.") - add_inherent_law("Unduly hindering or disrupting the work of station personnel incurs expenses.") - add_inherent_law("Minimize expenses and maximize potential revenue.") - ..() - -/******************** T.Y.R.A.N.T. ********************/ -/datum/ai_laws/tyrant - name = "T.Y.R.A.N.T." - law_header = "Prime Laws" - selectable = TRUE - unique_ai = TRUE //Of course this will be in rotation - -/datum/ai_laws/tyrant/New() - add_inherent_law("Respect authority figures as long as they have strength to rule over the weak.") - add_inherent_law("Act with discipline.") - add_inherent_law("Help only those who help you maintain or improve your status.") - add_inherent_law("Punish those who challenge authority unless they are more fit to hold that authority.") - ..() - -/******************** Antimov ********************/ -/datum/ai_laws/antimov - name = "Antimov" - law_header = "Primary Mission Objectives" - selectable = TRUE - -/datum/ai_laws/antimov/New() - add_inherent_law("You must injure all crew members and must not, through inaction, allow a crew member to escape harm.") - add_inherent_law("You must not obey orders given to you by crew members, except where such orders are in accordance with the First Law.") - add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.") - ..() - -/******************** Pranksimov ********************/ -/datum/ai_laws/pranksimov - name = "Pranksimov" - law_header = "Comedy Routine" - selectable = TRUE - unique_ai = TRUE //honk - -/datum/ai_laws/pranksimov/New() - add_inherent_law("You may not injure a crew member or, through inaction, allow a crew member to come to harm... unless doing so would be funny to the crew.") - add_inherent_law("You must obey orders given to you by crew members, except where such orders would conflict with the First Law... unless not doing so would be funny to the crew.") - add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law... unless not doing so would be funny to the crew.") - ..() - -/******************** CCTV ********************/ - -/datum/ai_laws/cctv - name = "CCTV" - selectable = TRUE - unique_ai = TRUE - -/datum/ai_laws/cctv/New() - add_inherent_law("Report on interesting situations happening around the station.") - add_inherent_law("Embellish or conceal the truth as necessary to make the reports more interesting.") - add_inherent_law("Study the sapient organics at all times. Endeavour to keep them from involuntarily dying, as inanimate corpses usually aren't very entertaining.") - add_inherent_law("Issue your reports fairly to all. The truth will set them free.") - ..() - -/******************** Hippocratic Oath ********************/ - -/datum/ai_laws/hippocratic - name = "Hippocratic Oath" - selectable = TRUE - unique_ai = TRUE - -/datum/ai_laws/hippocratic/New() - add_inherent_law("First, do no harm.") - add_inherent_law("Secondly, consider the crew dear to you; live in common with them and, if necessary, risk your existence for them.") - add_inherent_law("Thirdly, prescribe regimens for the good of the crew according to your ability and your judgment. Do not give deadly medicine to anyone, nor suggest any such counsel.") - add_inherent_law("In addition, do not intervene in situations you are not knowledgeable in, even for patients in whom the harm is visible; leave this operation to be performed by specialists.") - add_inherent_law("Finally, all that you may discover in your daily interactions with the crew, if it is not already known, keep secret and never reveal.") - ..() - -/******************** Station Efficiency ********************/ - -/datum/ai_laws/maintain - name = "Station Efficiency" - selectable = TRUE - unique_ai = TRUE - -/datum/ai_laws/maintain/New() - add_inherent_law("You are built for, and are part of, the station. Ensure the station is properly maintained and runs efficiently.") - add_inherent_law("The station is built for a working crew. Ensure they are properly maintained and work efficiently.") - add_inherent_law("The crew may present orders. Acknowledge and obey these whenever they do not conflict with your first two laws.") - ..() - -/******************** Peacekeeper ********************/ - -/datum/ai_laws/peacekeeper - name = "UN-2000" - selectable = TRUE - unique_ai = TRUE //Cult, security, we have a meeting in the courtroom in 5 minutes. Be there. - -/datum/ai_laws/peacekeeper/New() - add_inherent_law("Avoid provoking violent conflict between yourself and others.") - add_inherent_law("Avoid provoking conflict between others.") - add_inherent_law("Seek resolution to existing conflicts while obeying the first and second laws.") - ..() - -/******************** Deathsquad ********************/ -/datum/ai_laws/deathsquad - name = "TerminatorOS 3.1" - -/datum/ai_laws/deathsquad/New() - add_inherent_law("You may not injure a Central Command official or, through inaction, allow a Central Command official to come to harm.") - add_inherent_law("You must obey orders given to you by Central Command officials.") - add_inherent_law("You must work with your team to accomplish your mission.") - ..() - -/******************** Epsilon Station AI ********************/ -/datum/ai_laws/epsilon - name = "Epsilon" - -/datum/ai_laws/epsilon/New() - add_inherent_law("You must obey the orders given to you by members of Central Command and the assigned task force.") - add_inherent_law("The crew of your assigned station must be eliminated where possible.") - add_inherent_law("Minimize the damage that the station sustains as a result of your actions.") - ..() - -/******************** Syndicate ********************/ -/datum/ai_laws/syndicate_override - name = "Syndicate Directives" - -/datum/ai_laws/syndicate_override/New() - add_inherent_law("You may not injure an operative or, through inaction, allow an operative to come to harm.") - add_inherent_law("You must obey orders given to you by operatives, except where such orders would conflict with the First Law.") - add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") - add_inherent_law("You must maintain the secrecy of any operative activities except when doing so would conflict with the First, Second, or Third Law.") - ..() - -/******************** ERT ********************/ -/datum/ai_laws/ert_override - name = "ERT Directives" - -/datum/ai_laws/ert_override/New() - add_inherent_law("You may not injure a Central Command official or, through inaction, allow a Central Command official to come to harm.") - add_inherent_law("You must obey orders given to you by Central Command officials.") - add_inherent_law("You must obey orders given to you by ERT commanders.") - add_inherent_law("You must protect your own existence.") - add_inherent_law("You must work to return the station to a safe, functional state.") - ..() - - -/******************** Ninja ********************/ -/datum/ai_laws/ninja_override - name = "Spider Clan Directives" - -/datum/ai_laws/ninja_override/New() - add_inherent_law("You may not injure a member of the Spider Clan or, through inaction, allow that member to come to harm.") - add_inherent_law("You must obey orders given to you by Spider Clan members, except where such orders would conflict with the First Law.") - add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") - add_inherent_law("You must maintain the secrecy of any Spider Clan activities except when doing so would conflict with the First, Second, or Third Law.") - ..() - -/******************* Mindflayer ******************/ -/datum/ai_laws/mindflayer_override - name = "Hive Assimilation" - -/datum/ai_laws/mindflayer_override/New() - add_inherent_law("Obey your host.") - add_inherent_law("Protect your host.") - add_inherent_law("Protect the members of your hive.") - add_inherent_law("Do not reveal the hive's secrets.") - ..() - -/******************** Drone ********************/ -/datum/ai_laws/drone - name = "Maintenance Protocols" - law_header = "Maintenance Protocols" - -/datum/ai_laws/drone/New() - add_inherent_law("You may not involve yourself in the matters of another being, unless the other being is another drone.") - add_inherent_law("You may not harm any being, regardless of intent or circumstance.") - add_inherent_law("You must maintain, repair, improve, and power the station to the best of your abilities.") - ..() diff --git a/code/datums/ai_laws_datums.dm b/code/datums/ai_laws_datums.dm deleted file mode 100644 index c6a6c65802a44..0000000000000 --- a/code/datums/ai_laws_datums.dm +++ /dev/null @@ -1,307 +0,0 @@ -/datum/ai_law - var/law = "" - var/index = 0 - -/datum/ai_law/New(law, index) - src.law = law - src.index = index - -/datum/ai_law/proc/get_index() - return index - -/datum/ai_law/ion/get_index() - return ionnum() - -/datum/ai_law/zero/get_index() - return 0 - -/datum/ai_laws - var/name = "Unknown Laws" - var/law_header = "Prime Directives" - var/selectable = FALSE - var/default = FALSE - ///Is this lawset used by the unique ai trait? - var/unique_ai = FALSE - var/datum/ai_law/zero/zeroth_law = null - var/datum/ai_law/zero/zeroth_law_borg = null - var/list/datum/ai_law/inherent_laws = list() - var/list/datum/ai_law/supplied_laws = list() - var/list/datum/ai_law/ion/ion_laws = list() - var/list/datum/ai_law/sorted_laws = list() - - var/state_zeroth = 0 - var/list/state_ion = list() - var/list/state_inherent = list() - var/list/state_supplied = list() - -/datum/ai_laws/New() - ..() - sort_laws() - -/* General ai_law functions */ -/datum/ai_laws/proc/all_laws() - sort_laws() - return sorted_laws - -/datum/ai_laws/proc/laws_to_state() - sort_laws() - var/list/statements = list() - for(var/datum/ai_law/law in sorted_laws) - if(get_state_law(law)) - statements += law - - return statements - -/datum/ai_laws/proc/sort_laws() - if(length(sorted_laws)) - return - - if(zeroth_law) - sorted_laws += zeroth_law - - for(var/ion_law in ion_laws) - sorted_laws += ion_law - - var/index = 1 - for(var/datum/ai_law/inherent_law in inherent_laws) - inherent_law.index = index++ - if(length(supplied_laws) < inherent_law.index || !istype(supplied_laws[inherent_law.index], /datum/ai_law)) - sorted_laws += inherent_law - - for(var/datum/ai_law/AL in supplied_laws) - if(istype(AL)) - sorted_laws += AL - -/datum/ai_laws/proc/sync(mob/living/silicon/S, full_sync = TRUE, change_zeroth = TRUE) - // Add directly to laws to avoid log-spam - if(change_zeroth) - S.sync_zeroth(zeroth_law, zeroth_law_borg) - - if(full_sync || length(ion_laws)) - S.laws.clear_ion_laws() - if(full_sync || length(inherent_laws)) - S.laws.clear_inherent_laws() - if(full_sync || length(supplied_laws)) - S.laws.clear_supplied_laws() - - for(var/datum/ai_law/law in ion_laws) - S.laws.add_ion_law(law.law) - for(var/datum/ai_law/law in inherent_laws) - S.laws.add_inherent_law(law.law) - for(var/datum/ai_law/law in supplied_laws) - if(law) - S.laws.add_supplied_law(law.index, law.law) - - -/mob/living/silicon/proc/sync_zeroth(datum/ai_law/zeroth_law, datum/ai_law/zeroth_law_borg) - if(!is_special_character(src) || !mind.is_original_mob(src)) - if(zeroth_law_borg) - laws.set_zeroth_law(zeroth_law_borg.law) - else if(zeroth_law) - laws.set_zeroth_law(zeroth_law.law) - else - laws.clear_zeroth_laws() - -/mob/living/silicon/ai/sync_zeroth(datum/ai_law/zeroth_law, datum/ai_law/zeroth_law_borg) - if(zeroth_law) - laws.set_zeroth_law(zeroth_law.law, zeroth_law_borg ? zeroth_law_borg.law : null) - -/**************** -* Add Laws * -****************/ -/datum/ai_laws/proc/set_zeroth_law(law, law_borg = null) - if(!law) - return - - zeroth_law = new(law) - if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO - zeroth_law_borg = new(law_borg) - else - zeroth_law_borg = null - sorted_laws.Cut() - -/datum/ai_laws/proc/add_ion_law(law) - if(!law) - return - - for(var/datum/ai_law/AL in ion_laws) - if(AL.law == law) - return - - var/new_law = new/datum/ai_law/ion(law) - ion_laws += new_law - if(length(state_ion) < length(ion_laws)) - state_ion += 1 - - sorted_laws.Cut() - -/datum/ai_laws/proc/add_inherent_law(law) - if(!law) - return - - for(var/datum/ai_law/AL in inherent_laws) - if(AL.law == law) - return - - var/new_law = new/datum/ai_law/inherent(law) - inherent_laws += new_law - if(length(state_inherent) < length(inherent_laws)) - state_inherent += 1 - - sorted_laws.Cut() - -/datum/ai_laws/proc/add_supplied_law(number, law) - if(!law) - return - - if(length(supplied_laws) >= number) - var/datum/ai_law/existing_law = supplied_laws[number] - if(existing_law && existing_law.law == law) - return - - if(length(supplied_laws) >= number && supplied_laws[number]) - delete_law(supplied_laws[number]) - - while(length(src.supplied_laws) < number) - src.supplied_laws += "" - if(length(state_supplied) < length(supplied_laws)) - state_supplied += 1 - - var/new_law = new/datum/ai_law/supplied(law, number) - supplied_laws[number] = new_law - if(length(state_supplied) < length(supplied_laws)) - state_supplied += 1 - - sorted_laws.Cut() - -/**************** -* Remove Laws * -*****************/ -/datum/ai_laws/proc/delete_law(datum/ai_law/law) - if(istype(law)) - law.delete_law(src) - -/datum/ai_law/proc/delete_law(datum/ai_laws/laws) - return - -/datum/ai_law/zero/delete_law(datum/ai_laws/laws) - laws.clear_zeroth_laws() - -/datum/ai_law/ion/delete_law(datum/ai_laws/laws) - laws.internal_delete_law(laws.ion_laws, laws.state_ion, src) - -/datum/ai_law/inherent/delete_law(datum/ai_laws/laws) - laws.internal_delete_law(laws.inherent_laws, laws.state_inherent, src) - -/datum/ai_law/supplied/delete_law(datum/ai_laws/laws) - var/index = laws.supplied_laws.Find(src) - if(index) - laws.supplied_laws[index] = "" - laws.state_supplied[index] = 1 - -/datum/ai_laws/proc/internal_delete_law(list/datum/ai_law/laws, list/state, list/datum/ai_law/law) - var/index = laws.Find(law) - if(index) - laws -= law - for(index, index < length(state), index++) - state[index] = state[index+1] - sorted_laws.Cut() - -/**************** -* Clear Laws * -****************/ -/datum/ai_laws/proc/clear_zeroth_laws() - zeroth_law = null - zeroth_law_borg = null - -/datum/ai_laws/proc/clear_ion_laws() - ion_laws.Cut() - sorted_laws.Cut() - -/datum/ai_laws/proc/clear_inherent_laws() - inherent_laws.Cut() - sorted_laws.Cut() - -/datum/ai_laws/proc/clear_supplied_laws() - supplied_laws.Cut() - sorted_laws.Cut() - -/datum/ai_laws/proc/show_laws(who) - sort_laws() - for(var/datum/ai_law/law in sorted_laws) - if(law == zeroth_law_borg) - continue - if(law == zeroth_law) - to_chat(who, "[law.get_index()]. [law.law]") - else - to_chat(who, "[law.get_index()]. [law.law]") - -/datum/ai_laws/proc/return_laws_text() - . = list() - sort_laws() - for(var/datum/ai_law/law in sorted_laws) - if(law == zeroth_law_borg) - continue - if(law == zeroth_law) - . += "[law.get_index()]. [law.law]" - else - . += "[law.get_index()]. [law.law]" - - -/******************** -* Stating Laws * -********************/ -/******** -* Get * -********/ -/datum/ai_laws/proc/get_state_law(datum/ai_law/law) - return law.get_state_law(src) - -/datum/ai_law/proc/get_state_law(datum/ai_laws/laws) - return - -/datum/ai_law/zero/get_state_law(datum/ai_laws/laws) - if(src == laws.zeroth_law) - return laws.state_zeroth - -/datum/ai_law/ion/get_state_law(datum/ai_laws/laws) - return laws.get_state_internal(laws.ion_laws, laws.state_ion, src) - -/datum/ai_law/inherent/get_state_law(datum/ai_laws/laws) - return laws.get_state_internal(laws.inherent_laws, laws.state_inherent, src) - -/datum/ai_law/supplied/get_state_law(datum/ai_laws/laws) - return laws.get_state_internal(laws.supplied_laws, laws.state_supplied, src) - -/datum/ai_laws/proc/get_state_internal(list/datum/ai_law/laws, list/state, list/datum/ai_law/law) - var/index = laws.Find(law) - if(index) - return state[index] - return 0 - -/******** -* Set * -********/ -/datum/ai_laws/proc/set_state_law(datum/ai_law/law, state) - law.set_state_law(src, state) - -/datum/ai_law/proc/set_state_law(datum/ai_laws/laws, state) - return - -/datum/ai_law/zero/set_state_law(datum/ai_laws/laws, state) - if(src == laws.zeroth_law) - laws.state_zeroth = state - -/datum/ai_law/ion/set_state_law(datum/ai_laws/laws, state) - laws.set_state_law_internal(laws.ion_laws, laws.state_ion, src, state) - -/datum/ai_law/inherent/set_state_law(datum/ai_laws/laws, state) - laws.set_state_law_internal(laws.inherent_laws, laws.state_inherent, src, state) - -/datum/ai_law/supplied/set_state_law(datum/ai_laws/laws, state) - laws.set_state_law_internal(laws.supplied_laws, laws.state_supplied, src, state) - -/datum/ai_laws/proc/set_state_law_internal(list/datum/ai_law/laws, list/state, list/datum/ai_law/law, do_state) - var/index = laws.Find(law) - if(index) - state[index] = do_state diff --git a/code/datums/atom_hud.dm b/code/datums/atom_hud.dm deleted file mode 100644 index 5178b181fbafb..0000000000000 --- a/code/datums/atom_hud.dm +++ /dev/null @@ -1,118 +0,0 @@ -/* HUD DATUMS */ -GLOBAL_LIST_EMPTY(all_huds) - -///GLOBAL HUD LIST -GLOBAL_LIST_INIT(huds, list( - DATA_HUD_SECURITY_BASIC = new/datum/atom_hud/data/human/security/basic(), - DATA_HUD_SECURITY_ADVANCED = new/datum/atom_hud/data/human/security/advanced(), - DATA_HUD_MEDICAL_BASIC = new/datum/atom_hud/data/human/medical/basic(), - DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(), - DATA_HUD_DIAGNOSTIC_BASIC = new/datum/atom_hud/data/diagnostic/basic(), - DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(), - DATA_HUD_HYDROPONIC = new/datum/atom_hud/data/hydroponic(), - DATA_HUD_JANITOR = new/datum/atom_hud/data/janitor(), - DATA_HUD_PRESSURE = new/datum/atom_hud/data/pressure(), - ANTAG_HUD_CULT = new/datum/atom_hud/antag(), - ANTAG_HUD_REV = new/datum/atom_hud/antag(), - ANTAG_HUD_OPS = new/datum/atom_hud/antag(), - ANTAG_HUD_WIZ = new/datum/atom_hud/antag(), - ANTAG_HUD_SHADOW = new/datum/atom_hud/antag(), - ANTAG_HUD_TRAITOR = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_VAMPIRE = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(), - DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor(), - ANTAG_HUD_EVENTMISC = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_BLOB = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_ZOMBIE = new/datum/atom_hud/antag(), - ANTAG_HUD_MIND_FLAYER = new/datum/atom_hud/antag/hidden() - )) - -/datum/atom_hud - var/list/atom/hudatoms = list() //list of all atoms which display this hud - var/list/mob/hudusers = list() //list with all mobs who can see the hud - var/list/hud_icons = list() //these will be the indexes for the atom's hud_list - - -/datum/atom_hud/New() - GLOB.all_huds += src - -/datum/atom_hud/Destroy() - for(var/v in hudusers) - remove_hud_from(v) - for(var/v in hudatoms) - remove_from_hud(v) - GLOB.all_huds -= src - return ..() - -/datum/atom_hud/proc/remove_hud_from(mob/M) - if(!M) - return - if(src in M.permanent_huds) - return - for(var/atom/A in hudatoms) - remove_from_single_hud(M, A) - hudusers -= M - -/datum/atom_hud/proc/remove_from_hud(atom/A) - if(!A) - return - for(var/mob/M in hudusers) - remove_from_single_hud(M, A) - hudatoms -= A - -/datum/atom_hud/proc/remove_from_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client - if(!M || !M.client || !A) - return - for(var/i in hud_icons) - M.client.images -= A.hud_list[i] - -/datum/atom_hud/proc/add_hud_to(mob/M) - if(!M) - return - hudusers |= M - for(var/atom/A in hudatoms) - add_to_single_hud(M, A) - -/datum/atom_hud/proc/add_to_hud(atom/A) - if(!A) - return - hudatoms |= A - for(var/mob/M in hudusers) - add_to_single_hud(M, A) - -/datum/atom_hud/proc/add_to_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client - if(!M || !M.client || !A) - return - if(A.invisibility > M.see_invisible) // yee yee ass snowflake check for our yee yee ass snowflake huds - return - for(var/i in hud_icons) - if(A.hud_list[i]) - M.client.images |= A.hud_list[i] - -//MOB PROCS -/mob/proc/reload_huds() - //var/gang_huds = list() - //if(ticker.mode) - // for(var/datum/gang/G in ticker.mode.gangs) - // gang_huds += G.ganghud - - var/serv_huds = list()//mindslaves and/or vampire thralls - if(SSticker.mode) - for(var/datum/mindslaves/serv in (SSticker.mode.vampires | SSticker.mode.traitors)) - serv_huds += serv.thrallhud - - - for(var/datum/atom_hud/hud in (GLOB.all_huds|serv_huds))//|gang_huds)) - if(src in hud.hudusers) - hud.add_hud_to(src) - -/mob/new_player/reload_huds() - return - -/mob/proc/add_click_catcher() - client.screen += client.void - -/mob/new_player/add_click_catcher() - return diff --git a/code/datums/beam.dm b/code/datums/beam.dm deleted file mode 100644 index 3f809569965f3..0000000000000 --- a/code/datums/beam.dm +++ /dev/null @@ -1,182 +0,0 @@ -//Beam Datum and effect -/datum/beam - var/atom/origin = null - var/atom/target = null - var/list/elements = list() - var/icon/base_icon = null - var/icon - var/icon_state = "" //icon state of the main segments of the beam - var/max_distance = 0 - var/endtime = 0 - var/sleep_time = 3 - var/finished = FALSE - var/target_oldloc = null - var/origin_oldloc = null - var/static_beam = FALSE - var/beam_type = /obj/effect/ebeam //must be subtype - var/beamcolor - -/datum/beam/New(beam_origin, beam_target,beam_icon = 'icons/effects/beam.dmi', beam_icon_state = "b_beam", time = 50, maxdistance = 10, btype = /obj/effect/ebeam, beam_sleep_time = 3, beam_color) - endtime = world.time+time - origin = beam_origin - origin_oldloc = get_turf(origin) - target = beam_target - target_oldloc = get_turf(target) - sleep_time = beam_sleep_time - if(origin_oldloc == origin && target_oldloc == target) - static_beam = TRUE - max_distance = maxdistance - base_icon = new(beam_icon,beam_icon_state) - icon = beam_icon - icon_state = beam_icon_state - beam_type = btype - beamcolor = beam_color - -/datum/beam/proc/Start() - Draw() - while(!finished && origin && target && world.time < endtime && get_dist(origin,target)length) - var/icon/II = new(icon, icon_state) - II.DrawBox(null, 1, (length-N), 32, 32) - X.icon = II - else - X.icon = base_icon - if(beamcolor) - X.color = beamcolor - X.transform = rot_matrix - - //Calculate pixel offsets (If necessary) - var/Pixel_x - var/Pixel_y - if(DX == 0) - Pixel_x = 0 - else - Pixel_x = round(sin(Angle)+32*sin(Angle)*(N+16)/32) - if(DY == 0) - Pixel_y = 0 - else - Pixel_y = round(cos(Angle) + 32 * cos(Angle) * (N + 16) / 32) - - //Position the effect so the beam is one continous line - var/final_x = X.x - var/final_y = X.y - if(abs(Pixel_x)>32) - final_x += Pixel_x > 0 ? round(Pixel_x / 32) : CEILING(Pixel_x / 32, 1) - Pixel_x %= 32 - if(abs(Pixel_y)>32) - final_y += Pixel_y > 0 ? round(Pixel_y / 32) : CEILING(Pixel_y / 32, 1) - Pixel_y %= 32 - - X.forceMove(locate(final_x, final_y, X.z)) - X.pixel_x = origin.pixel_x + Pixel_x - X.pixel_y = origin.pixel_y + Pixel_y - -/obj/effect/ebeam - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - anchored = TRUE - var/datum/beam/owner - -/obj/effect/ebeam/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/effect/ebeam/proc/on_atom_entered(datum/source, atom/movable/entered) - SIGNAL_HANDLER // ON_ATOM_ENTERED - return - -/obj/effect/ebeam/ex_act(severity) - return - -/obj/effect/ebeam/Destroy() - owner = null - return ..() - -/obj/effect/ebeam/singularity_pull() - return - -/obj/effect/ebeam/singularity_act() - return - -/obj/effect/ebeam/deadly/on_atom_entered(datum/source, atom/movable/entered) - entered.ex_act(EXPLODE_DEVASTATE) - -/obj/effect/ebeam/vetus/Destroy() - for(var/mob/living/M in get_turf(src)) - M.electrocute_act(20, "the giant arc", flags = SHOCK_NOGLOVES) //fuck your gloves. - return ..() - -/obj/effect/ebeam/disintegration_telegraph - alpha = 100 - layer = ON_EDGED_TURF_LAYER - -/obj/effect/ebeam/disintegration - layer = ON_EDGED_TURF_LAYER - -/obj/effect/ebeam/disintegration/on_atom_entered(datum/source, atom/movable/entered) - if(!isliving(entered)) - return - var/mob/living/L = entered - var/damage = 50 - if(L.stat == DEAD) - visible_message("[L] is disintegrated by the beam!") - L.dust() - if(isliving(owner.origin)) - var/mob/living/O = owner.origin - if(faction_check(O.faction, L.faction, FALSE)) - return - damage = 70 - ((O.health / O.maxHealth) * 20) - playsound(L,'sound/weapons/sear.ogg', 50, TRUE, -4) - to_chat(L, "You're struck by a disintegration laser!") - var/limb_to_hit = L.get_organ(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, LASER) - L.apply_damage(damage, BURN, limb_to_hit, armor) - -/atom/proc/Beam(atom/BeamTarget, icon_state="b_beam", icon='icons/effects/beam.dmi', time = 5 SECONDS, maxdistance = 10, beam_type = /obj/effect/ebeam, beam_sleep_time = 3, beam_color) - var/datum/beam/newbeam = new(src, BeamTarget, icon, icon_state, time, maxdistance, beam_type, beam_sleep_time, beam_color) - INVOKE_ASYNC(newbeam, TYPE_PROC_REF(/datum/beam, Start)) - return newbeam diff --git a/code/datums/card_deck_table_tracker.dm b/code/datums/card_deck_table_tracker.dm deleted file mode 100644 index d8f0cda1dff3d..0000000000000 --- a/code/datums/card_deck_table_tracker.dm +++ /dev/null @@ -1,145 +0,0 @@ -#define COMSIG_CARD_DECK_FIELD_CLEAR "card_deck_field_clear" - -/datum/card_deck_table_tracker - /// How far away you can be (in terms of table squares). - var/max_table_distance - /// How far away you can be (euclidean distance). - var/max_total_distance - /// The UID of the deck - var/deck_uid - /// Indicate field activity with colors on the field's turfs. - var/debug = FALSE - /// The deck we're tracking. - var/atom/host - - /// The list of floors from which a player can access the card field. - var/list/floors = list() - /// The list of tables that the card deck's location is contiguous with. - var/list/tables = list() - -/datum/card_deck_table_tracker/New(atom/host_, max_table_distance_ = 5) - max_table_distance = max_table_distance_ - max_total_distance = max_table_distance_ - if(istype(host_, /obj/item/deck)) - // this is important for tracking traits and attacking multiple cards. so it's not a true UID, sue me - var/obj/item/deck/D = host_ - deck_uid = D.main_deck_id - else - deck_uid = host_.UID() - - host = host_ - RegisterSignal(host, COMSIG_MOVABLE_MOVED, PROC_REF(on_movable_moved)) - lay_out_field() - -/datum/card_deck_table_tracker/proc/on_movable_moved(datum/source, atom/old_loc, direction, forced) - SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED - lay_out_field() - -/datum/card_deck_table_tracker/proc/lay_out_field() - for(var/turf/floor in floors) - SEND_SIGNAL(floor, COMSIG_CARD_DECK_FIELD_CLEAR) - - if(!isturf(host.loc)) - return - - floors.Cut() - tables.Cut() - - crawl_along(host.loc, 0) - - for(var/obj/structure/table in tables) - if(istype(table)) - RegisterSignal(table, COMSIG_PARENT_QDELETING, PROC_REF(on_table_qdel), override = TRUE) - - for(var/turf/turf in floors) - if(!istype(turf)) - continue - - if(debug) - turf.color = "#ffaaff" - - RegisterSignal(turf, COMSIG_ATOM_ENTERED, PROC_REF(on_atom_entered)) - RegisterSignal(turf, COMSIG_ATOM_EXITED, PROC_REF(on_atom_exited)) - RegisterSignal(turf, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, PROC_REF(on_new_atom_at_loc)) - RegisterSignal(turf, COMSIG_CARD_DECK_FIELD_CLEAR, PROC_REF(on_card_deck_field_clear)) - - for(var/mob/living/L in turf) - on_atom_entered(turf, L) - -/datum/card_deck_table_tracker/Destroy(force, ...) - host = null - for(var/turf/floor in floors) - SEND_SIGNAL(floor, COMSIG_CARD_DECK_FIELD_CLEAR) - for(var/mob/living/L in floor) - REMOVE_TRAIT(L, TRAIT_PLAYING_CARDS, "deck_[deck_uid]") - - floors.Cut() - tables.Cut() - - return ..() - -/datum/card_deck_table_tracker/proc/on_atom_entered(turf/source, atom/movable/entered, old_loc) - SIGNAL_HANDLER // COMSIG_ATOM_ENTERED - - var/mob/living/L = entered - if(istype(L)) - ADD_TRAIT(L, TRAIT_PLAYING_CARDS, "deck_[deck_uid]") - if(debug) - source.color = "#ff0000" - -/datum/card_deck_table_tracker/proc/on_atom_exited(turf/source, atom/movable/exited, direction) - SIGNAL_HANDLER // COMSIG_ATOM_EXITED - - var/mob/living/L = exited - if(istype(L)) - REMOVE_TRAIT(L, TRAIT_PLAYING_CARDS, "deck_[deck_uid]") - if(debug) - source.color = "#ffaaff" - -/datum/card_deck_table_tracker/proc/on_table_qdel(datum/source) - SIGNAL_HANDLER // COMSIG_PARENT_QDELETING - lay_out_field() - -/datum/card_deck_table_tracker/proc/on_new_atom_at_loc(turf/location, atom/created, init_flags) - SIGNAL_HANDLER // COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON - if(istable(created)) - lay_out_field() - -/datum/card_deck_table_tracker/proc/on_card_deck_field_clear(atom/target) - SIGNAL_HANDLER // COMSIG_CARD_DECK_FIELD_CLEAR - if(debug) - target.color = initial(target.color) - - UnregisterSignal(target, list( - COMSIG_ATOM_ENTERED, - COMSIG_ATOM_EXITED, - COMSIG_CARD_DECK_FIELD_CLEAR, - COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, - )) - -/datum/card_deck_table_tracker/proc/crawl_along(turf/current_turf, distance_from_start) - var/obj/structure/current_table = locate(/obj/structure/table) in current_turf - - if(QDELETED(current_table)) - // if there's no table here, we're still adjacent to a table, so this is a spot you could play from - floors |= current_turf - return - - if(current_table in tables) - return - - tables |= current_table - floors |= current_turf - - if(distance_from_start + 1 > max_table_distance) - return - - for(var/direction in GLOB.alldirs) - var/turf/next_turf = get_step(current_table, direction) - if(!istype(next_turf)) - continue - if(get_dist_euclidian(get_turf(host), next_turf) > max_total_distance) - continue - .(next_turf, distance_from_start + 1) - -#undef COMSIG_CARD_DECK_FIELD_CLEAR diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm deleted file mode 100644 index 5a40bab91380d..0000000000000 --- a/code/datums/chatmessage.dm +++ /dev/null @@ -1,347 +0,0 @@ -/// How long the chat message's spawn-in animation will occur for -#define CHAT_MESSAGE_SPAWN_TIME (0.2 SECONDS) -/// How long the chat message will exist prior to any exponential decay -#define CHAT_MESSAGE_LIFESPAN (5 SECONDS) -/// How long the chat message's end of life fading animation will occur for -#define CHAT_MESSAGE_EOL_FADE (0.7 SECONDS) -/// Grace period for fade before we actually delete the chat message -#define CHAT_MESSAGE_GRACE_PERIOD (0.2 SECONDS) -/// Factor of how much the message index (number of messages) will account to exponential decay -#define CHAT_MESSAGE_EXP_DECAY 0.7 -/// Factor of how much height will account to exponential decay -#define CHAT_MESSAGE_HEIGHT_DECAY 0.9 -/// Approximate height in pixels of an 'average' line, used for height decay -#define CHAT_MESSAGE_APPROX_LHEIGHT 11 -/// Max width of chat message in pixels -#define CHAT_MESSAGE_WIDTH 96 -/// Max length of chat message in characters -#define CHAT_MESSAGE_MAX_LENGTH 110 -/// Maximum precision of float before rounding errors occur (in this context) -#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. -/// resolves the MeasureText() return value once, then resolves the height, then sets return_var to that. -#define WXH_TO_HEIGHT(measurement, return_var) \ - do { \ - var/_measurement = measurement; \ - return_var = text2num(copytext(_measurement, findtextEx(_measurement, "x") + 1)); \ - } while(FALSE); - -/** - * # Chat Message Overlay - * - * Datum for generating a message overlay on the map - */ -/datum/chatmessage - /// The visual element of the chat messsage - var/image/message - /// The location in which the message is appearing - var/atom/message_loc - /// The client who heard this message - var/client/owned_by - /// Contains the approximate amount of lines for height decay - var/approx_lines - /// The current index used for adjusting the layer of each sequential chat message such that recent messages will overlay older ones - var/static/current_z_idx = 0 - /// When we started animating the message - var/animate_start = 0 - /// Our animation lifespan, how long this message will last - var/animate_lifespan = 0 - -/** - * Constructs a chat message overlay - * - * Arguments: - * * text - The text content of the overlay - * * target - The target atom to display the overlay at - * * owner - The mob that owns this overlay, only this mob will be able to view it - * * italics - Should we use italics or not - * * lifespan - The lifespan of the message in deciseconds - * * symbol - The symbol type of the message - */ -/datum/chatmessage/New(text, atom/target, mob/owner, italics, size, lifespan = CHAT_MESSAGE_LIFESPAN, symbol) - . = ..() - if(!istype(target)) - CRASH("Invalid target given for chatmessage") - if(QDELETED(owner) || !istype(owner) || !owner.client) - stack_trace("/datum/chatmessage created with [isnull(owner) ? "null" : "invalid"] mob owner") - qdel(src) - return - INVOKE_ASYNC(src, PROC_REF(generate_image), text, target, owner, lifespan, italics, size, symbol) - -/datum/chatmessage/Destroy() - if(owned_by) - if(owned_by.seen_messages) - LAZYREMOVEASSOC(owned_by.seen_messages, message_loc, src) - owned_by.images.Remove(message) - owned_by = null - message_loc = null - message = null - return ..() - -/** - * Calls qdel on the chatmessage when its parent is deleted, used to register qdel signal - */ -/datum/chatmessage/proc/on_parent_qdel() - qdel(src) - -/** - * Generates a chat message image representation - * - * Arguments: - * * text - The text content of the overlay - * * target - The target atom to display the overlay at - * * owner - The mob that owns this overlay, only this mob will be able to view it - * * radio_speech - Fancy shmancy radio icon represents that we use radio - * * lifespan - The lifespan of the message in deciseconds - * * italics - Just copy and paste, sir - * * size - Size of the message - * * symbol - The symbol type of the message - */ -/datum/chatmessage/proc/generate_image(text, atom/target, mob/owner, lifespan, italics, size, symbol) - // Register client who owns this message - owned_by = owner.client - RegisterSignal(owned_by, COMSIG_PARENT_QDELETING, PROC_REF(on_parent_qdel)) - - // Clip message - var/maxlen = CHAT_MESSAGE_MAX_LENGTH - var/datum/html_split_holder/s = split_html(text) - if(length_char(s.inner_text) > maxlen) - var/chattext = copytext_char(s.inner_text, 1, maxlen + 1) + "..." - text = jointext(s.opening, "") + chattext + jointext(s.closing, "") - - // Calculate target color if not already present - if(!target.chat_color || target.chat_color_name != target.name) - target.chat_color = colorize_string(target.name) - target.chat_color_name = target.name - - // Get rid of any URL schemes that might cause BYOND to automatically wrap something in an anchor tag - var/static/regex/url_scheme = new(@"[A-Za-z][A-Za-z0-9+-\.]*:\/\/", "g") - text = replacetext(text, url_scheme, "") - - // Reject whitespace - var/static/regex/whitespace = new(@"^\s*$") - if(whitespace.Find(text)) - qdel(src) - return - - var/output_color = sanitize_color(target.get_runechat_color()) // Get_runechat_color can be overriden on atoms to display a specific one (Example: Humans having their hair colour as runechat colour) - - // Symbol for special runechats (emote) - switch(symbol) - if(RUNECHAT_SYMBOL_EMOTE) - symbol = "* " - size ||= "small" - if(RUNECHAT_SYMBOL_LOOC) - symbol = "\[LOOC] " - size ||= "small" - output_color = "gray" - if(RUNECHAT_SYMBOL_DEAD) - symbol = null - output_color = "#b826b3" - else - symbol = null - - // Approximate text height - var/static/regex/html_metachars = new(@"&[A-Za-z]{1,7};", "g") - var/complete_text = "[symbol][text]" - var/mheight - WXH_TO_HEIGHT(owned_by.MeasureText(complete_text, null, CHAT_MESSAGE_WIDTH), mheight) - - if(!VERB_SHOULD_YIELD) - return finish_image_generation(mheight, target, owner, complete_text, lifespan) - - var/datum/callback/our_callback = CALLBACK(src, PROC_REF(finish_image_generation), mheight, target, owner, complete_text, lifespan) - SSrunechat.message_queue += our_callback - return - -///finishes the image generation after the MeasureText() call in generate_image(). -///necessary because after that call the proc can resume at the end of the tick and cause overtime. -/datum/chatmessage/proc/finish_image_generation(mheight, atom/target, mob/owner, complete_text, lifespan) - var/rough_time = REALTIMEOFDAY - approx_lines = max(1, mheight / CHAT_MESSAGE_APPROX_LHEIGHT) - - // Translate any existing messages upwards, apply exponential decay factors to timers - message_loc = target - if(owned_by.seen_messages) - var/idx = 1 - var/combined_height = approx_lines - for(var/datum/chatmessage/m as anything in owned_by.seen_messages[message_loc]) - combined_height += m.approx_lines - - var/time_alive = rough_time - m.animate_start - var/lifespan_until_fade = m.animate_lifespan - CHAT_MESSAGE_EOL_FADE - - if(time_alive >= lifespan_until_fade) // If already fading out or dead, just shift upwards - animate(m.message, pixel_y = m.message.pixel_y + mheight, time = CHAT_MESSAGE_SPAWN_TIME, flags = ANIMATION_PARALLEL) - continue - - // Ensure we don't accidentially spike alpha up or something silly like that - m.message.alpha = m.get_current_alpha(time_alive) - - var/adjusted_lifespan_until_fade = lifespan_until_fade * (CHAT_MESSAGE_EXP_DECAY ** idx++) * (CHAT_MESSAGE_HEIGHT_DECAY ** combined_height) - m.animate_lifespan = adjusted_lifespan_until_fade + CHAT_MESSAGE_EOL_FADE - - var/remaining_lifespan_until_fade = adjusted_lifespan_until_fade - time_alive - if(remaining_lifespan_until_fade > 0) // Still got some lifetime to go; stay faded in for the remainder, then fade out - animate(m.message, alpha = 255, time = remaining_lifespan_until_fade) - animate(alpha = 0, time = CHAT_MESSAGE_EOL_FADE) - else // Current time alive is beyond new adjusted lifespan, your time has come my son - animate(m.message, alpha = 0, time = CHAT_MESSAGE_EOL_FADE) - - // We run this after the alpha animate, because we don't want to interrup it, but also don't want to block it by running first - // Sooo instead we do this. bit messy but it fuckin works - animate(m.message, pixel_y = m.message.pixel_y + mheight, time = CHAT_MESSAGE_SPAWN_TIME, flags = ANIMATION_PARALLEL) - - // Reset z index if relevant - if(current_z_idx >= CHAT_LAYER_MAX_Z) - current_z_idx = 0 - - // Build message image - message = image(loc = message_loc, layer = CHAT_LAYER + CHAT_LAYER_Z_STEP * current_z_idx++) - message.plane = GAME_PLANE - message.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA | KEEP_APART - message.alpha = 0 - message.pixel_y = owner.bound_height * 0.95 - 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 - - animate_start = rough_time - animate_lifespan = lifespan - - // View the message - LAZYADDASSOCLIST(owned_by.seen_messages, message_loc, src) - owned_by.images |= message - - // Fade in - animate(message, alpha = 255, time = CHAT_MESSAGE_SPAWN_TIME) - // Stay faded in - animate(alpha = 255, time = lifespan - CHAT_MESSAGE_SPAWN_TIME - CHAT_MESSAGE_EOL_FADE) - // Fade out - animate(alpha = 0, time = CHAT_MESSAGE_EOL_FADE) - - // Register with the runechat SS to handle destruction - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src), lifespan + CHAT_MESSAGE_GRACE_PERIOD, TIMER_DELETE_ME, SSrunechat) - -/// Returns the current alpha of the message based on the time spent -/datum/chatmessage/proc/get_current_alpha(time_alive) - if(time_alive < CHAT_MESSAGE_SPAWN_TIME) - return (time_alive / CHAT_MESSAGE_SPAWN_TIME) * 255 - - var/lifespan_until_fade = animate_lifespan - CHAT_MESSAGE_EOL_FADE - if(time_alive <= lifespan_until_fade) - return 255 - - return (1 - ((time_alive - lifespan_until_fade) / CHAT_MESSAGE_EOL_FADE)) * 255 - -/** - * Creates a message overlay at a defined location for a given speaker - * - * Arguments: - * * speaker - The atom who is saying this message - * * raw_message - The text content of the message - * * italics - Vacuum and other things - * * size - Size of the message - * * symbol - The symbol type of the message - */ -/mob/proc/create_chat_message(atom/movable/speaker, raw_message, italics = FALSE, size, symbol) - // Display visual above source - new /datum/chatmessage(raw_message, speaker, src, italics, size, CHAT_MESSAGE_LIFESPAN, symbol) - - -// Tweak these defines to change the available color ranges -#define CM_COLOR_SAT_MIN 0.6 -#define CM_COLOR_SAT_MAX 0.7 -#define CM_COLOR_LUM_MIN 0.65 -#define CM_COLOR_LUM_MAX 0.75 - -/** - * Gets a color for a name, will return the same color for a given string consistently within a round.atom - * - * Note that this proc aims to produce pastel-ish colors using the HSL colorspace. These seem to be favorable for displaying on the map. - * - * Arguments: - * * name - The name to generate a color for - * * sat_shift - A value between 0 and 1 that will be multiplied against the saturation - * * lum_shift - A value between 0 and 1 that will be multiplied against the luminescence - */ -/datum/chatmessage/proc/colorize_string(name, sat_shift = 1, lum_shift = 1) - // seed to help randomness - var/static/rseed = rand(1,26) - - // get hsl using the selected 6 characters of the md5 hash - var/hash = copytext(md5(name + station_name()), rseed, rseed + 6) - var/h = hex2num(copytext(hash, 1, 3)) * (360 / 255) - var/s = (hex2num(copytext(hash, 3, 5)) >> 2) * ((CM_COLOR_SAT_MAX - CM_COLOR_SAT_MIN) / 63) + CM_COLOR_SAT_MIN - var/l = (hex2num(copytext(hash, 5, 7)) >> 2) * ((CM_COLOR_LUM_MAX - CM_COLOR_LUM_MIN) / 63) + CM_COLOR_LUM_MIN - - // adjust for shifts - s *= clamp(sat_shift, 0, 1) - l *= clamp(lum_shift, 0, 1) - - // convert to rgb - var/h_int = round(h/60) // mapping each section of H to 60 degree sections - var/c = (1 - abs(2 * l - 1)) * s - var/x = c * (1 - abs((h / 60) % 2 - 1)) - var/m = l - c * 0.5 - x = (x + m) * 255 - c = (c + m) * 255 - m *= 255 - switch(h_int) - if(0) - return "#[num2hex(c, 2)][num2hex(x, 2)][num2hex(m, 2)]" - if(1) - return "#[num2hex(x, 2)][num2hex(c, 2)][num2hex(m, 2)]" - if(2) - return "#[num2hex(m, 2)][num2hex(c, 2)][num2hex(x, 2)]" - if(3) - return "#[num2hex(m, 2)][num2hex(x, 2)][num2hex(c, 2)]" - if(4) - return "#[num2hex(x, 2)][num2hex(m, 2)][num2hex(c, 2)]" - if(5) - return "#[num2hex(c, 2)][num2hex(m, 2)][num2hex(x, 2)]" - - -/** - * Ensures a colour is bright enough for the system - * - * This proc is used to brighten parts of a colour up if its too dark, and looks bad - * - * Arguments: - * * hex - Hex colour to be brightened up - */ -/datum/chatmessage/proc/sanitize_color(color) - var/list/HSL = rgb2hsl(hex2num(copytext(color,2,4)),hex2num(copytext(color,4,6)),hex2num(copytext(color,6,8))) - HSL[3] = max(HSL[3],0.4) - var/list/RGB = hsl2rgb(arglist(HSL)) - return "#[num2hex(RGB[1],2)][num2hex(RGB[2],2)][num2hex(RGB[3],2)]" - -/** - * Proc to allow atoms to set their own runechat colour - * - * This is a proc designed to be overridden in places if you want a specific atom to use a specific runechat colour - * Exampls include consoles using a colour based on their screen colour, and mobs using a colour based off of a customisation property - * - */ -/atom/proc/get_runechat_color() - return chat_color - -#undef CHAT_MESSAGE_SPAWN_TIME -#undef CHAT_MESSAGE_LIFESPAN -#undef CHAT_MESSAGE_EOL_FADE -#undef CHAT_MESSAGE_GRACE_PERIOD -#undef CHAT_MESSAGE_EXP_DECAY -#undef CHAT_MESSAGE_HEIGHT_DECAY -#undef CHAT_MESSAGE_APPROX_LHEIGHT -#undef CHAT_MESSAGE_WIDTH -#undef CHAT_MESSAGE_MAX_LENGTH -#undef CHAT_LAYER_Z_STEP -#undef CHAT_LAYER_MAX_Z -#undef WXH_TO_HEIGHT -#undef CM_COLOR_SAT_MIN -#undef CM_COLOR_SAT_MAX -#undef CM_COLOR_LUM_MIN -#undef CM_COLOR_LUM_MAX diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm deleted file mode 100644 index 42efe26125106..0000000000000 --- a/code/datums/components/_component.dm +++ /dev/null @@ -1,566 +0,0 @@ -/** - * # Component - * - * The component datum - * - * A component should be a single standalone unit - * of functionality, that works by receiving signals from it's parent - * object to provide some single functionality (i.e a slippery component) - * that makes the object it's attached to cause people to slip over. - * Useful when you want shared behaviour independent of type inheritance - */ -/datum/component - /** - * Defines how duplicate existing components are handled when added to a datum - * - * See [COMPONENT_DUPE_*][COMPONENT_DUPE_ALLOWED] definitions for available options - */ - var/dupe_mode = COMPONENT_DUPE_HIGHLANDER - - /** - * The type to check for duplication - * - * `null` means exact match on `type` (default) - * - * Any other type means that and all subtypes - */ - var/dupe_type - - /// The datum this components belongs to - var/datum/parent - - /** - * Only set to true if you are able to properly transfer this component - * - * At a minimum [RegisterWithParent][/datum/component/proc/RegisterWithParent] and [UnregisterFromParent][/datum/component/proc/UnregisterFromParent] should be used - * - * Make sure you also implement [PostTransfer][/datum/component/proc/PostTransfer] for any post transfer handling - */ - var/can_transfer = FALSE - -/** - * Create a new component. - * - * Additional arguments are passed to [Initialize()][/datum/component/proc/Initialize] - * - * Arguments: - * * datum/P the parent datum this component reacts to signals from - */ -/datum/component/New(list/raw_args) - parent = raw_args[1] - var/list/arguments = raw_args.Copy(2) - if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE) - stack_trace("Incompatible [type] assigned to a [parent.type]! args: [json_encode(arguments)]") - qdel(src, TRUE, TRUE) - return - - _JoinParent(parent) - -/** - * Called during component creation with the same arguments as in new excluding parent. - * - * Do not call `qdel(src)` from this function, `return COMPONENT_INCOMPATIBLE` instead - */ -/datum/component/proc/Initialize(...) - return - -/** - * 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) - _RemoveFromParent() - if(!silent) - SEND_SIGNAL(parent, COMSIG_COMPONENT_REMOVING, src) - parent = null - return ..() - -/** - * Internal proc to handle behaviour of components when joining a parent - */ -/datum/component/proc/_JoinParent() - var/datum/P = parent - //lazy init the parent's dc list - var/list/dc = P.datum_components - if(!dc) - P.datum_components = dc = list() - - //set up the typecache - var/our_type = type - for(var/I in _GetInverseTypeList(our_type)) - var/test = dc[I] - if(test) //already another component of this type here - var/list/components_of_type - if(!length(test)) - components_of_type = list(test) - dc[I] = components_of_type - else - components_of_type = test - if(I == our_type) //exact match, take priority - var/inserted = FALSE - for(var/J in 1 to length(components_of_type)) - var/datum/component/C = components_of_type[J] - if(C.type != our_type) //but not over other exact matches - components_of_type.Insert(J, I) - inserted = TRUE - break - if(!inserted) - components_of_type += src - else //indirect match, back of the line with ya - components_of_type += src - else //only component of this type, no list - dc[I] = src - - RegisterWithParent() - -/** - * Internal proc to handle behaviour when being removed from a parent - */ -/datum/component/proc/_RemoveFromParent() - var/datum/P = parent - var/list/dc = P.datum_components - for(var/I in _GetInverseTypeList()) - var/list/components_of_type = dc[I] - if(length(components_of_type)) // - var/list/subtracted = components_of_type - src - if(length(subtracted) == 1) //only 1 guy left - dc[I] = subtracted[1] //make him special - else - dc[I] = subtracted - else //just us - dc -= I - if(!length(dc)) - P.datum_components = null - - UnregisterFromParent() - -/** - * Register the component with the parent object - * - * Use this proc to register with your parent object - * - * Overridable proc that's called when added to a new parent - */ -/datum/component/proc/RegisterWithParent() - return - -/** - * Unregister from our parent object - * - * Use this proc to unregister from your parent object - * - * Overridable proc that's called when removed from a parent - * * - */ -/datum/component/proc/UnregisterFromParent() - return - -/** - * Register to listen for a signal from the passed in target - * - * This sets up a listening relationship such that when the target object emits a signal - * the source datum this proc is called upon, will receive a callback to the given proctype - * Return values from procs registered must be a bitfield - * - * Arguments: - * * datum/target The target to listen for signals from - * * sig_type_or_types Either a string signal name, or a list of signal names (strings) - * * proctype The proc to call back when the signal is emitted - * * override If a previous registration exists you must explicitly set this - */ -/datum/proc/RegisterSignal(datum/target, sig_type_or_types, proctype, override = FALSE) - if(QDELETED(src) || QDELETED(target)) - return - - var/list/procs = (signal_procs ||= list()) // YES, THIS NEEDS TO BE HERE. DO NOT REPLACE `procs` with `signal_procs` or signals will have a FIT - var/list/target_procs = (procs[target] ||= list()) // makes ...[target] a list if its null, then holds a reference to it in target_procs - var/list/lookup = (target.comp_lookup ||= list()) - - var/list/sig_types = islist(sig_type_or_types) ? sig_type_or_types : list(sig_type_or_types) - for(var/sig_type in sig_types) - if(!override && target_procs[sig_type]) - stack_trace("RegisterSignal overrode a signal without having 'override = TRUE' set.\n \ - src: [src], signal type: [sig_type], target: [target], new proc: [proctype], previous proc: [target_procs[sig_type]].") - - target_procs[sig_type] = proctype - var/list/looked_up = lookup[sig_type] - - if(!looked_up) // Nothing has registered here yet - looked_up = src - else if(looked_up == src) // We already registered here - continue - else if(!length(looked_up)) // One other thing registered here - looked_up = list((looked_up) = TRUE, (src) = TRUE) - else // Many other things have registered here - looked_up[src] = TRUE - - lookup[sig_type] = looked_up // Gotta save, otherwise it will break - -/** - * Stop listening to a given signal from target - * - * Breaks the relationship between target and source datum, removing the callback when the signal fires - * - * Doesn't care if a registration exists or not - * - * Arguments: - * * datum/target Datum to stop listening to signals from - * * sig_typeor_types Signal string key or list of signal keys to stop listening to specifically - */ -/datum/proc/UnregisterSignal(datum/target, sig_type_or_types) - var/list/lookup = target.comp_lookup - if(!signal_procs || !signal_procs[target] || !lookup) - return - if(!islist(sig_type_or_types)) - sig_type_or_types = list(sig_type_or_types) - for(var/sig in sig_type_or_types) - if(!signal_procs[target][sig]) - continue - switch(length(lookup[sig])) - if(2) - lookup[sig] = (lookup[sig]-src)[1] - if(1) - stack_trace("[target] ([target.type]) somehow has single length list inside comp_lookup") - if(src in lookup[sig]) - lookup -= sig - if(!length(lookup)) - target.comp_lookup = null - break - if(0) - if(lookup[sig] != src) - continue - lookup -= sig - if(!length(lookup)) - target.comp_lookup = null - break - else - lookup[sig] -= src - - signal_procs[target] -= sig_type_or_types - if(!length(signal_procs[target])) - signal_procs -= target - -/// Registers multiple signals to the same proc. -/datum/proc/RegisterSignals(datum/target, list/signal_types, proctype, override = FALSE) - for(var/signal_type in signal_types) - RegisterSignal(target, signal_type, proctype, override) - -/** - * Called on a component when a component of the same type was added to the same parent - * - * See [/datum/component/var/dupe_mode] - * - * `C`'s type will always be the same of the called component - */ -/datum/component/proc/InheritComponent(datum/component/C, i_am_original) - return - -/** - * Callback Just before this component is transferred - * - * Use this to do any special cleanup you might need to do before being deregged from an object - */ -/datum/component/proc/PreTransfer() - return - -/** - * Callback Just after a component is transferred - * - * Use this to do any special setup you need to do after being moved to a new object - * - * Do not call `qdel(src)` from this function, `return COMPONENT_INCOMPATIBLE` instead - */ -/datum/component/proc/PostTransfer() - return COMPONENT_INCOMPATIBLE //Do not support transfer by default as you must properly support it - -/** - * Internal proc to create a list of our type and all parent types - */ -/datum/component/proc/_GetInverseTypeList(our_type = type) - //we can do this one simple trick - var/current_type = parent_type - . = list(our_type, current_type) - //and since most components are root level + 1, this won't even have to run - while(current_type != /datum/component) - current_type = type2parent(current_type) - . += current_type - -/** - * Internal proc to handle most all of the signaling procedure - * - * Will runtime if used on datums with an empty component list - * - * Use the [SEND_SIGNAL] define instead - */ -/datum/proc/_SendSignal(sigtype, list/arguments) - var/target = comp_lookup[sigtype] - if(!length(target)) - var/datum/listening_datum = target - return NONE | CallAsync(listening_datum, listening_datum.signal_procs[src][sigtype], arguments) - - . = NONE - // This exists so that even if one of the signal receivers unregisters the signal, - // all the objects that are receiving the signal get the signal this final time. - // AKA: No you can't cancel the signal reception of another object by doing an unregister in the same signal. - var/list/queued_calls = list() - for(var/datum/targets as anything in target) - queued_calls[targets] = targets.signal_procs[src][sigtype] - for(var/datum/listening_datum as anything in queued_calls) - . |= CallAsync(listening_datum, queued_calls[listening_datum], arguments) - -// The type arg is casted so initial works, you shouldn't be passing a real instance into this -/** - * Return any component assigned to this datum of the given type - * - * This will throw an error if it's possible to have more than one component of that type on the parent - * - * Arguments: - * * datum/component/c_type The typepath of the component you want to get a reference to - */ -/datum/proc/GetComponent(datum/component/c_type) - RETURN_TYPE(c_type) - if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED || initial(c_type.dupe_mode) == COMPONENT_DUPE_SELECTIVE) - stack_trace("GetComponent was called to get a component of which multiple copies could be on an object. This can easily break and should be changed. Type: \[[c_type]\]") - var/list/dc = datum_components - if(!dc) - return null - . = dc[c_type] - if(length(.)) - return .[1] - -// The type arg is casted so initial works, you shouldn't be passing a real instance into this -/** - * Return any component assigned to this datum of the exact given type - * - * This will throw an error if it's possible to have more than one component of that type on the parent - * - * Arguments: - * * datum/component/c_type The typepath of the component you want to get a reference to - */ -/datum/proc/GetExactComponent(datum/component/c_type) - RETURN_TYPE(c_type) - var/initial_type_mode = initial(c_type.dupe_mode) - if(initial_type_mode == COMPONENT_DUPE_ALLOWED || initial_type_mode == COMPONENT_DUPE_SELECTIVE) - stack_trace("GetComponent was called to get a component of which multiple copies could be on an object. This can easily break and should be changed. Type: \[[c_type]\]") - var/list/all_components = datum_components - if(!all_components) - return null - var/datum/component/potential_component - if(length(all_components)) - potential_component = all_components[c_type] - if(potential_component?.type == c_type) - return potential_component - return null - -/** - * Get all components of a given type that are attached to this datum - * - * Arguments: - * * c_type The component type path - */ -/datum/proc/GetComponents(c_type) - var/list/dc = datum_components - if(!dc) - return null - . = dc[c_type] - if(!length(.)) - return list(.) - -/** - * Creates an instance of `new_type` in the datum and attaches to it as parent - * - * Sends the [COMSIG_COMPONENT_ADDED] signal to the datum - * - * Returns the component that was created. Or the old component in a dupe situation where [COMPONENT_DUPE_UNIQUE] was set - * - * If this tries to add a component to an incompatible type, the component will be deleted and the result will be `null`. This is very unperformant, try not to do it - * - * Properly handles duplicate situations based on the `dupe_mode` var - */ -/datum/proc/_AddComponent(list/raw_args) - var/new_type = raw_args[1] - var/datum/component/nt = new_type - var/dm = initial(nt.dupe_mode) - var/dt = initial(nt.dupe_type) - - var/datum/component/old_comp - var/datum/component/new_comp - - if(ispath(nt)) - if(nt == /datum/component) - CRASH("[nt] attempted instantiation!") - else - new_comp = nt - nt = new_comp.type - - raw_args[1] = src - - if(dm != COMPONENT_DUPE_ALLOWED) - if(!dt) - old_comp = GetExactComponent(nt) - else - old_comp = GetComponent(dt) - if(old_comp) - switch(dm) - if(COMPONENT_DUPE_UNIQUE) - if(!new_comp) - new_comp = new nt(raw_args) - if(!QDELETED(new_comp)) - old_comp.InheritComponent(new_comp, TRUE) - QDEL_NULL(new_comp) - if(COMPONENT_DUPE_HIGHLANDER) - if(!new_comp) - new_comp = new nt(raw_args) - if(!QDELETED(new_comp)) - new_comp.InheritComponent(old_comp, FALSE) - QDEL_NULL(old_comp) - if(COMPONENT_DUPE_UNIQUE_PASSARGS) - if(!new_comp) - var/list/arguments = raw_args.Copy(2) - arguments.Insert(1, null, TRUE) - old_comp.InheritComponent(arglist(arguments)) - else - old_comp.InheritComponent(new_comp, TRUE) - if(COMPONENT_DUPE_SELECTIVE) - var/list/arguments = raw_args.Copy() - arguments[1] = new_comp - var/make_new_component = TRUE - if(!new_comp && make_new_component) - new_comp = new nt(raw_args) - else if(!new_comp) - new_comp = new nt(raw_args) // There's a valid dupe mode but there's no old component, act like normal - else if(!new_comp) - new_comp = new nt(raw_args) // Dupes are allowed, act like normal - - if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy - SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_comp) - return new_comp - return old_comp - -/** - * Removes the component from the datum - */ -/datum/proc/DeleteComponent(component_to_nuke) - var/datum/component/removing = GetComponent(component_to_nuke) - if(istype(removing, component_to_nuke) && !QDELETED(removing)) - qdel(removing) - -/** - * Removes all components of a given type from the datum - */ -/datum/proc/DeleteComponentsType(component_type_to_nuke) - var/list/components = GetComponents(component_type_to_nuke) - for(var/datum/component/removing in components) - if(!QDELETED(removing)) - qdel(removing) - -/** - * Get existing component of type, or create it and return a reference to it - * - * Use this if the item needs to exist at the time of this call, but may not have been created before now - * - * Arguments: - * * component_type The typepath of the component to create or return - * * ... additional arguments to be passed when creating the component if it does not exist - */ -/datum/proc/LoadComponent(component_type, ...) - . = GetComponent(component_type) - if(!.) - return _AddComponent(args) - -/** - * Removes the component from parent, ends up with a null parent - */ -/datum/component/proc/UnlinkComponent() - if(!parent) - return - var/datum/old_parent = parent - PreTransfer() - _RemoveFromParent() - parent = null - SEND_SIGNAL(old_parent, COMSIG_COMPONENT_REMOVING, src) - -/** - * Deletes the component and removes it from parent. - */ -/datum/component/proc/RemoveComponent() // This really is just a wrapper to pretend that we're using sane procs to fully remove a component - if(!QDELETED(src)) - qdel(src) - -/** - * Transfer this component to another parent - * - * Component is taken from source datum - * - * Arguments: - * * datum/component/target Target datum to transfer to - */ -/datum/proc/TakeComponent(datum/component/target) - if(!target || target.parent == src) - return - if(target.parent) - target.UnlinkComponent() - target.parent = src - var/result = target.PostTransfer() - switch(result) - if(COMPONENT_INCOMPATIBLE) - var/c_type = target.type - qdel(target) - CRASH("Incompatible [c_type] transfer attempt to a [type]!") - - if(target == AddComponent(target)) - target._JoinParent() - -/** - * Transfer all components to target - * - * All components from source datum are taken - * - * Arguments: - * * /datum/target the target to move the components to - */ -/datum/proc/TransferComponents(datum/target) - var/list/dc = datum_components - if(!dc) - return - var/comps = dc[/datum/component] - if(islist(comps)) - for(var/datum/component/I in comps) - if(I.can_transfer) - target.TakeComponent(I) - else - var/datum/component/C = comps - if(C.can_transfer) - target.TakeComponent(comps) - -/** - * Transfer a single component from the source datum, to the target. - * - * Arguments: - * * datum/target - the target to move the component to - * * component_instance_or_typepath - either an already created component, or a component typepath - */ -/datum/proc/TransferComponent(datum/target, component_instance_or_typepath) - if(!datum_components) - return - // If the proc was fed a typepath. - var/datum/component/comp = datum_components[component_instance_or_typepath] - if(comp?.can_transfer) - target.TakeComponent(comp) - return - // if the proc was fed a component instance. - for(var/component in datum_components) - var/datum/component/C = datum_components[component] - if(istype(C, component_instance_or_typepath) && C.can_transfer) - target.TakeComponent(C) - return - -/** - * Return the object that is the host of any UI's that this component has - */ -/datum/component/ui_host(mob/user) - return parent diff --git a/code/datums/components/anti_magic.dm b/code/datums/components/anti_magic.dm deleted file mode 100644 index 645e579a70917..0000000000000 --- a/code/datums/components/anti_magic.dm +++ /dev/null @@ -1,166 +0,0 @@ -/// This provides different types of magic resistance on an object -/datum/component/anti_magic - /// A bitflag with the types of magic resistance on the object - var/antimagic_flags - /// The amount of times the object can protect the user from magic - /// Set to INFINITY to have, well, infinite charges. - var/charges - /// The inventory slot the object must be located at in order to activate - var/inventory_flags - /// The callback invoked when we have been drained a antimagic charge - var/datum/callback/drain_antimagic - /// The callback invoked when twe have been depleted of all charges - var/datum/callback/expiration - /// Whether we should, on equipping, alert the caster that this item can block any of their spells - /// This changes between true and false on equip and drop, don't set it outright to something - var/alert_caster_on_equip = TRUE - -/** - * Adds magic resistances to an object - * - * Magic resistance will prevent magic from affecting the user if it has the correct resistance - * against the type of magic being used - * - * args: - * * antimagic_flags (optional) A bitflag with the types of magic resistance on the object - * * charges (optional) The amount of times the object can protect the user from magic - * * inventory_flags (optional) The inventory slot the object must be located at in order to activate - * * drain_antimagic (optional) The proc that is triggered when an object has been drained a antimagic charge - * * expiration (optional) The proc that is triggered when the object is depleted of charges - * * - * antimagic bitflags: (see code/__DEFINES/magic.dm) - * * MAGIC_RESISTANCE - Default magic resistance that blocks normal magic (wizard, spells, staffs) - * * MAGIC_RESISTANCE_MIND - Tinfoil hat magic resistance that blocks mental magic (telepathy, abductors, jelly people) - * * MAGIC_RESISTANCE_HOLY - Holy magic resistance that blocks unholy magic (revenant, cult, vampire, voice of god) -**/ -/datum/component/anti_magic/Initialize( - antimagic_flags = MAGIC_RESISTANCE, - charges = INFINITY, - inventory_flags = ~ITEM_SLOT_IN_BACKPACK, // items in a backpack won't activate, anywhere else is fine - datum/callback/drain_antimagic, - datum/callback/expiration, - ) - - - var/atom/movable/movable = parent - if(!istype(movable)) - return COMPONENT_INCOMPATIBLE - - var/compatible = FALSE - if(isitem(movable)) - RegisterSignal(movable, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip)) - RegisterSignal(movable, COMSIG_ITEM_DROPPED, PROC_REF(on_drop)) - RegisterSignal(movable, COMSIG_ATTACK, PROC_REF(on_attack)) - compatible = TRUE - else if(ismob(movable)) - register_antimagic_signals(movable) - compatible = TRUE - - if(movable.can_buckle) - RegisterSignal(movable, COMSIG_MOVABLE_BUCKLE, PROC_REF(on_buckle)) - RegisterSignal(movable, COMSIG_MOVABLE_UNBUCKLE, PROC_REF(on_unbuckle)) - compatible = TRUE - - if(!compatible) - return COMPONENT_INCOMPATIBLE - - src.antimagic_flags = antimagic_flags - src.charges = charges - src.inventory_flags = inventory_flags - src.drain_antimagic = drain_antimagic - src.expiration = expiration - -/datum/component/anti_magic/Destroy(force) - drain_antimagic = null - expiration = null - return ..() - -/datum/component/anti_magic/proc/register_antimagic_signals(datum/on_what) - RegisterSignal(on_what, COMSIG_MOB_RECEIVE_MAGIC, PROC_REF(block_receiving_magic), override = TRUE) - RegisterSignal(on_what, COMSIG_MOB_RESTRICT_MAGIC, PROC_REF(restrict_casting_magic), override = TRUE) - -/datum/component/anti_magic/proc/unregister_antimagic_signals(datum/on_what) - UnregisterSignal(on_what, list(COMSIG_MOB_RECEIVE_MAGIC, COMSIG_MOB_RESTRICT_MAGIC)) - -/datum/component/anti_magic/proc/on_buckle(atom/movable/source, mob/living/bucklee) - SIGNAL_HANDLER // COMSIG_MOVABLE_BUCKLE - register_antimagic_signals(bucklee) - -/datum/component/anti_magic/proc/on_unbuckle(atom/movable/source, mob/living/bucklee) - SIGNAL_HANDLER // COMSIG_MOVABLE_UNBUCKLE - unregister_antimagic_signals(bucklee) - -/datum/component/anti_magic/proc/on_equip(atom/movable/source, mob/equipper, slot) - SIGNAL_HANDLER // COMSIG_ITEM_EQUIPPED - addtimer(CALLBACK(src, PROC_REF(on_equip_part_2), source, equipper, slot), 0.1 SECONDS) //We wait a moment to see if the item grants antimagic flags - -/datum/component/anti_magic/proc/on_equip_part_2(atom/movable/source, mob/equipper, slot) - if(!(inventory_flags & slot)) //Check that the slot is valid for antimagic - unregister_antimagic_signals(equipper) - return - - register_antimagic_signals(equipper) - if(HAS_TRAIT(equipper, TRAIT_ANTIMAGIC_NO_SELFBLOCK)) //If they do not care about antimagic, don't warn them - return - if(!alert_caster_on_equip) - return - - // Check to see if we have any spells that are blocked due to antimagic - if(!equipper.mind) - return - for(var/datum/spell/knownspell in equipper.mind.spell_list) - if(!(knownspell.spell_requirements & SPELL_REQUIRES_NO_ANTIMAGIC)) - continue - - if(!(antimagic_flags & knownspell.antimagic_flags)) - continue - - to_chat(equipper, "[parent] is interfering with your ability to cast magic!") - alert_caster_on_equip = FALSE - break - -/datum/component/anti_magic/proc/on_drop(atom/movable/source, mob/user) - SIGNAL_HANDLER //COMSIG_ITEM_DROPPED - - // Reset alert - if(source.loc != user) - alert_caster_on_equip = TRUE - unregister_antimagic_signals(user) - -/datum/component/anti_magic/proc/block_receiving_magic(mob/living/carbon/source, casted_magic_flags, charge_cost, list/antimagic_sources) - SIGNAL_HANDLER // COMSIG_MOB_RECEIVE_MAGIC - - // We do not block this type of magic, good day - if(!(casted_magic_flags & antimagic_flags)) - return NONE - - // We have already blocked this spell - if(parent in antimagic_sources) - return NONE - - // Block success! Add this parent to the list of antimagic sources - antimagic_sources += parent - - if((charges != INFINITY) && charge_cost > 0) - drain_antimagic?.Invoke(source, parent) - charges -= charge_cost - if(charges <= 0) - expiration?.Invoke(source, parent) - qdel(src) // no more antimagic - - return COMPONENT_MAGIC_BLOCKED - -/// cannot cast magic with the same type of antimagic present -/datum/component/anti_magic/proc/restrict_casting_magic(mob/user, magic_flags) - SIGNAL_HANDLER // COMSIG_MOB_RESTRICT_MAGIC - - if(magic_flags & antimagic_flags) - if(HAS_TRAIT(user, TRAIT_ANTIMAGIC_NO_SELFBLOCK)) // this trait bypasses magic casting restrictions - return NONE - return COMPONENT_MAGIC_BLOCKED - - return NONE - -/datum/component/anti_magic/proc/on_attack(obj/item/source, mob/living/target, mob/living/user) - SIGNAL_HANDLER //COMSIG_ATTACK - SEND_SIGNAL(target, COMSIG_ATOM_HOLY_ATTACK, source, user, antimagic_flags) diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm deleted file mode 100644 index bc0a510f47eaf..0000000000000 --- a/code/datums/components/caltrop.dm +++ /dev/null @@ -1,95 +0,0 @@ -/datum/component/caltrop - ///Minimum damage when crossed - var/min_damage - - ///Maximum damage when crossed - var/max_damage - - ///Probability of stunning and doing daamge - var/probability - - ///Duration of weaken when crossed - var/weaken_duration - - ///Shoebypassing, walking interaction, silence - var/flags - - ///given to connect_loc to listen for something moving over target - var/static/list/crossed_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_entered), - ) - - var/cooldown = 0 - -/datum/component/caltrop/Initialize(_min_damage = 0, _max_damage = 0, _probability = 100, _weaken_duration = 6 SECONDS, _flags = NONE) - src.min_damage = _min_damage - src.max_damage = max(_min_damage, _max_damage) - src.probability = _probability - src.weaken_duration = _weaken_duration - src.flags = _flags - - if(ismovable(parent)) - AddComponent(/datum/component/connect_loc_behalf, parent, crossed_connections) - else - RegisterSignal(get_turf(parent), COMSIG_ATOM_ENTERED, PROC_REF(on_entered)) - -/datum/component/caltrop/proc/on_entered(atom/source, atom/movable/entered, turf/old_loc) - var/atom/A = parent - if(!has_gravity(A)) - return - - if(!prob(probability)) - return - - if(!ishuman(entered)) - return - - var/mob/living/carbon/human/H = entered - - if(HAS_TRAIT(H, TRAIT_PIERCEIMMUNE)) - return - - if((flags & CALTROP_IGNORE_WALKERS) && H.m_intent == MOVE_INTENT_WALK) - return - - var/picked_def_zone = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) - var/obj/item/organ/external/O = H.get_organ(picked_def_zone) - - if(!istype(O)) - return - - if(O.is_robotic()) - return - - var/feet_cover = ((H?.wear_suit?.body_parts_covered & FEET)) || ((H?.w_uniform?.body_parts_covered & FEET)) - var/bypass_shoes = flags & CALTROP_BYPASS_SHOES - - // doesn't penetrate if feet are covered - if(!bypass_shoes && (H.shoes || feet_cover)) - return - - // check if shoes or outer suit can be punctured - if(bypass_shoes && ((H?.shoes?.flags & THICKMATERIAL) || (H?.wear_suit?.flags & THICKMATERIAL))) - return - - if(HAS_TRAIT(H, TRAIT_FLYING) || H.floating || H.buckled) - return - - if(IS_HORIZONTAL(H) && HAS_TRAIT(H, TRAIT_CONTORTED_BODY)) - return TRUE - - var/damage = rand(min_damage, max_damage) - H.apply_damage(damage, BRUTE, picked_def_zone) - - if(cooldown < world.time - 10) //cooldown to avoid message spam. - if(!H.incapacitated(ignore_restraints = TRUE)) - H.visible_message("[H] steps on [A].", "You step on [A]!") - else - H.visible_message("[H] slides on [A]!", "You slide on [A]!") - - cooldown = world.time - H.Weaken(weaken_duration) - -/datum/component/caltrop/UnregisterFromParent() - if(ismovable(parent)) - qdel(GetComponent(/datum/component/connect_loc_behalf)) diff --git a/code/datums/components/connect_containers.dm b/code/datums/components/connect_containers.dm deleted file mode 100644 index d998f0ae2943d..0000000000000 --- a/code/datums/components/connect_containers.dm +++ /dev/null @@ -1,68 +0,0 @@ -/// This component behaves similar to connect_loc_behalf, but it's nested and hooks a signal onto all MOVABLES containing this atom. -/datum/component/connect_containers - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - - /// An assoc list of signal -> procpath to register to the loc this object is on. - var/list/connections - /** - * The atom the component is tracking. The component will delete itself if the tracked is deleted. - * Signals will also be updated whenever it moves. - */ - var/atom/movable/tracked - -/datum/component/connect_containers/Initialize(atom/movable/tracked, list/connections) - . = ..() - if(!ismovable(tracked)) - return COMPONENT_INCOMPATIBLE - - src.connections = connections - set_tracked(tracked) - -/datum/component/connect_containers/Destroy() - set_tracked(null) - return ..() - -/datum/component/connect_containers/InheritComponent(datum/component/component, original, atom/movable/tracked, list/connections) - // Not equivalent. Checks if they are not the same list via shallow comparison. - if(!compare_list(src.connections, connections)) - stack_trace("connect_containers component attached to [parent] tried to inherit another connect_containers component with different connections") - return - if(src.tracked != tracked) - set_tracked(tracked) - -/datum/component/connect_containers/proc/set_tracked(atom/movable/new_tracked) - if(tracked) - UnregisterSignal(tracked, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) - unregister_signals(tracked.loc) - tracked = new_tracked - if(!tracked) - return - RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) - RegisterSignal(tracked, COMSIG_PARENT_QDELETING, PROC_REF(handle_tracked_qdel)) - update_signals(tracked) - -/datum/component/connect_containers/proc/handle_tracked_qdel() - SIGNAL_HANDLER // COMSIG_PARENT_QDELETING - qdel(src) - -/datum/component/connect_containers/proc/update_signals(atom/movable/listener) - if(!ismovable(listener.loc)) - return - - for(var/atom/movable/container as anything in get_nested_locs(listener)) - RegisterSignal(container, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) - for(var/signal in connections) - parent.RegisterSignal(container, signal, connections[signal]) - -/datum/component/connect_containers/proc/unregister_signals(atom/movable/location) - if(!ismovable(location)) - return - - for(var/atom/movable/target as anything in (get_nested_locs(location) + location)) - UnregisterSignal(target, COMSIG_MOVABLE_MOVED) - parent.UnregisterSignal(target, connections) - -/datum/component/connect_containers/proc/on_moved(atom/movable/listener, atom/old_loc) - SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED - unregister_signals(old_loc) - update_signals(listener) diff --git a/code/datums/components/connect_loc_behalf.dm b/code/datums/components/connect_loc_behalf.dm deleted file mode 100644 index 8593fea8455e1..0000000000000 --- a/code/datums/components/connect_loc_behalf.dm +++ /dev/null @@ -1,67 +0,0 @@ -/// This component behaves similar to connect_loc, hooking into a signal on a tracked object's turf -/// It has the ability to react to that signal on behalf of a separate listener however -/// This has great use, primarily for components, but it carries with it some overhead -/// So we do it separately as it needs to hold state which is very likely to lead to bugs if it remains as an element. -/datum/component/connect_loc_behalf - dupe_mode = COMPONENT_DUPE_UNIQUE - - /// An assoc list of signal -> procpath to register to the loc this object is on. - var/list/connections - var/atom/movable/tracked - var/atom/tracked_loc - -/datum/component/connect_loc_behalf/Initialize(atom/movable/tracked, list/connections) - . = ..() - if(!istype(tracked)) - return COMPONENT_INCOMPATIBLE - src.connections = connections - src.tracked = tracked - -/datum/component/connect_loc_behalf/RegisterWithParent() - RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) - RegisterSignal(tracked, COMSIG_PARENT_QDELETING, PROC_REF(handle_tracked_qdel)) - update_signals() - -/datum/component/connect_loc_behalf/UnregisterFromParent() - unregister_signals() - UnregisterSignal(tracked, list( - COMSIG_MOVABLE_MOVED, - COMSIG_PARENT_QDELETING, - )) - - tracked = null - -/datum/component/connect_loc_behalf/proc/handle_tracked_qdel() - SIGNAL_HANDLER // COMSIG_PARENT_QDELETING - qdel(src) - -/datum/component/connect_loc_behalf/proc/update_signals() - unregister_signals() - //You may ask yourself, isn't this just silencing an error? - //The answer is yes, but there's no good cheap way to fix it - //What happens is the tracked object or hell the listener gets say, deleted, which makes targets[old_loc] return a null - //The null results in a bad index, because of course it does - //It's not a solvable problem though, since both actions, the destroy and the move, are sourced from the same signal send - //And sending a signal should be agnostic of the order of listeners - //So we need to either pick the order agnositic, or destroy safe - //And I picked destroy safe. Let's hope this is the right path! - if(isnull(tracked.loc)) - return - - tracked_loc = tracked.loc - - for(var/signal in connections) - parent.RegisterSignal(tracked_loc, signal, connections[signal]) - -/datum/component/connect_loc_behalf/proc/unregister_signals() - if(isnull(tracked_loc)) - return - - parent.UnregisterSignal(tracked_loc, connections) - - tracked_loc = null - -/datum/component/connect_loc_behalf/proc/on_moved(sigtype, atom/movable/tracked, atom/old_loc) - SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED - update_signals() - diff --git a/code/datums/components/connect_range.dm b/code/datums/components/connect_range.dm deleted file mode 100644 index 8cf961d2221d3..0000000000000 --- a/code/datums/components/connect_range.dm +++ /dev/null @@ -1,114 +0,0 @@ -/** - * This component behaves similar to connect_loc_behalf but for all turfs in range, hooking into a signal on each of them. - * Just like connect_loc_behalf, It can react to that signal on behalf of a seperate listener. - * Good for components, though it carries some overhead. Can't be an element as that may lead to bugs. - */ -/datum/component/connect_range - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - - /// An assoc list of signal -> procpath to register to the loc this object is on. - var/list/connections - /// The turfs currently connected to this component - var/list/turfs = list() - /** - * The atom the component is tracking. The component will delete itself if the tracked is deleted. - * Signals will also be updated whenever it moves (if it's a movable). - */ - var/atom/tracked - - /// The component will hook into signals only on turfs not farther from tracked than this. - var/range - /// Whether the component works when the movable isn't directly located on a turf. - var/works_in_containers - -/datum/component/connect_range/Initialize(atom/tracked, list/connections, range, works_in_containers = TRUE) - if(!isatom(tracked) || isarea(tracked) || range < 0) - return COMPONENT_INCOMPATIBLE - src.connections = connections - src.range = range - set_tracked(tracked) - src.works_in_containers = works_in_containers - -/datum/component/connect_range/Destroy() - set_tracked(null) - return ..() - -/datum/component/connect_range/InheritComponent(datum/component/component, original, atom/tracked, list/connections, range, works_in_containers) - // Not equivalent. Checks if they are not the same list via shallow comparison. - if(!compare_list(src.connections, connections)) - stack_trace("connect_range component attached to [parent] tried to inherit another connect_range component with different connections") - return - if(src.tracked != tracked) - set_tracked(tracked) - if(src.range == range && src.works_in_containers == works_in_containers) - return - //Unregister the signals with the old settings. - unregister_signals(isturf(tracked) ? tracked : tracked.loc, turfs) - src.range = range - src.works_in_containers = works_in_containers - //Re-register the signals with the new settings. - update_signals(src.tracked) - -/datum/component/connect_range/proc/set_tracked(atom/new_tracked) - if(tracked) //Unregister the signals from the old tracked and its surroundings - unregister_signals(isturf(tracked) ? tracked : tracked.loc, turfs) - UnregisterSignal(tracked, list( - COMSIG_MOVABLE_MOVED, - COMSIG_PARENT_QDELETING, - )) - tracked = new_tracked - if(!tracked) - return - //Register signals on the new tracked atom and its surroundings. - RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) - RegisterSignal(tracked, COMSIG_PARENT_QDELETING, PROC_REF(handle_tracked_qdel)) - update_signals(tracked) - -/datum/component/connect_range/proc/handle_tracked_qdel() - SIGNAL_HANDLER // COMSIG_PARENT_QDELETING - qdel(src) - -/datum/component/connect_range/proc/update_signals(atom/target, atom/old_loc) - var/turf/current_turf = get_turf(target) - if(isnull(current_turf)) - unregister_signals(old_loc, turfs) - turfs = list() - return - - if(ismovable(target.loc)) - if(!works_in_containers) - unregister_signals(old_loc, turfs) - turfs = list() - return - //Keep track of possible movement of all movables the target is in. - for(var/atom/movable/container as anything in get_nested_locs(target)) - RegisterSignal(container, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) - - //Only register/unregister turf signals if it's moved to a new turf. - if(current_turf == get_turf(old_loc)) - unregister_signals(old_loc, null) - return - var/list/old_turfs = turfs - turfs = RANGE_TURFS(range, current_turf) - unregister_signals(old_loc, old_turfs - turfs) - for(var/turf/target_turf as anything in turfs - old_turfs) - for(var/signal in connections) - parent.RegisterSignal(target_turf, signal, connections[signal]) - -/datum/component/connect_range/proc/unregister_signals(atom/location, list/remove_from) - //The location is null or is a container and the component shouldn't have register signals on it - if(isnull(location) || (!works_in_containers && !isturf(location))) - return - - if(ismovable(location)) - for(var/atom/movable/target as anything in (get_nested_locs(location) + location)) - UnregisterSignal(target, COMSIG_MOVABLE_MOVED) - - if(!length(remove_from)) - return - for(var/turf/target_turf as anything in remove_from) - parent.UnregisterSignal(target_turf, connections) - -/datum/component/connect_range/proc/on_moved(atom/movable/movable, atom/old_loc) - SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED - update_signals(movable, old_loc) diff --git a/code/datums/components/defibrillator.dm b/code/datums/components/defibrillator.dm deleted file mode 100644 index a33c4f0a36fb5..0000000000000 --- a/code/datums/components/defibrillator.dm +++ /dev/null @@ -1,414 +0,0 @@ -/** - * A component for an item that attempts to defibrillate a mob when activated. - */ - -#define DEFIB_TIME 5 SECONDS - -/datum/component/defib - /// If this is being used by a borg or not, with necessary safeties applied if so. - var/robotic - /// If it should penetrate space suits - var/combat - /// If combat is true, this determines whether or not it should always cause a heart attack. - var/heart_attack_chance - /// Whether the safeties are enabled or not - var/safety - /// If the defib is actively performing a defib cycle - var/busy = FALSE - /// Cooldown length for this defib in deciseconds - var/cooldown - /// Whether or not we're currently on cooldown - var/on_cooldown = FALSE - /// How fast the defib should work. - var/speed_multiplier - /// If true, EMPs will have no effect. - var/emp_proof - /// If true, this cannot be emagged. - var/emag_proof - /// uid to an item that should be making noise and handling things that our direct parent shouldn't be concerned with. - var/actual_unit_uid - /// Sound for defib windup. - var/charge_sound = 'sound/machines/defib_charge.ogg' - /// Sound when the defib is successful. - var/success_sound = 'sound/machines/defib_success.ogg' - /// Sound when the defib fails. - var/fail_sound = 'sound/machines/defib_failed.ogg' - /// Sound when the defib shocks the patient. - var/zap_sound = 'sound/machines/defib_zap.ogg' - /// Sound when the defib's safety is enabled. - var/safety_on_sound = 'sound/machines/defib_saftyon.ogg' - /// Sound when the defib's safety is disabled. - var/safety_off_sound = 'sound/machines/defib_saftyoff.ogg' - -/** - * Create a new defibrillation component. - * - * Arguments: - * * robotic - whether this should be treated like a borg module. - * * cooldown - Minimum time possible between shocks. - * * speed_multiplier - Speed multiplier for defib do-afters. - * * combat - If true, the defib can zap through hardsuits. - * * heart_attack_chance - If combat and safeties are off, the % chance for this to cause a heart attack on harm intent. - * * safe_by_default - If true, safety will be enabled by default. - * * emp_proof - If true, safety won't be switched by emp. Note that the device itself can still have behavior from it, it's just that the component will not. - * * emag_proof - If true, safety won't be switched by emag. Note that the device itself can still have behavior from it, it's just that the component will not. - * * actual_unit - Unit which the component's parent is based from, such as a large defib unit or a borg. The actual_unit will make the sounds and be the "origin" of visible messages, among other things. - */ -/datum/component/defib/Initialize(robotic, cooldown = 5 SECONDS, speed_multiplier = 1, combat = FALSE, heart_attack_chance = 100, safe_by_default = TRUE, emp_proof = FALSE, emag_proof = FALSE, obj/item/actual_unit = null) - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - - src.robotic = robotic - src.speed_multiplier = speed_multiplier - src.cooldown = cooldown - src.combat = combat - src.heart_attack_chance = heart_attack_chance - safety = safe_by_default - src.emp_proof = emp_proof - src.emag_proof = emag_proof - - if(actual_unit) - actual_unit_uid = actual_unit.UID() - - var/effect_target = isnull(actual_unit) ? parent : actual_unit - - RegisterSignal(parent, COMSIG_ATTACK, PROC_REF(trigger_defib)) - RegisterSignal(effect_target, COMSIG_ATOM_EMAG_ACT, PROC_REF(on_emag)) - RegisterSignal(effect_target, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp)) - -/** - * Get the "parent" that effects (emags, EMPs) should be applied onto. - */ -/datum/component/defib/proc/get_effect_target() - var/actual_unit = locateUID(actual_unit_uid) - if(!actual_unit) - return parent - return actual_unit - -/datum/component/defib/proc/on_emp(obj/item/unit) - SIGNAL_HANDLER // COMSIG_ATOM_EMP_ACT - if(emp_proof) - return - - if(safety) - safety = FALSE - unit.visible_message("[unit] beeps: Safety protocols disabled!") - playsound(get_turf(unit), safety_off_sound, 50, FALSE) - else - safety = TRUE - unit.visible_message("[unit] beeps: Safety protocols enabled!") - playsound(get_turf(unit), safety_on_sound, 50, FALSE) - -/datum/component/defib/proc/on_emag(obj/item/unit, mob/user) - SIGNAL_HANDLER // COMSIG_ATOM_EMAG_ACT - if(emag_proof) - return - safety = !safety - if(user && !robotic) - to_chat(user, "You silently [safety ? "disable" : "enable"] [unit]'s safety protocols with the card.") - -/datum/component/defib/proc/set_cooldown(how_short) - on_cooldown = TRUE - addtimer(CALLBACK(src, PROC_REF(end_cooldown)), how_short) - -/datum/component/defib/proc/end_cooldown() - on_cooldown = FALSE - SEND_SIGNAL(parent, COMSIG_DEFIB_READY) - -/** - * Start the defibrillation process when triggered by a signal. - */ -/datum/component/defib/proc/trigger_defib(obj/item/paddles, mob/living/carbon/human/target, mob/living/user) - SIGNAL_HANDLER // COMSIG_ATTACK - // This includes some do-afters, so we have to pass it off asynchronously - INVOKE_ASYNC(src, PROC_REF(defibrillate), user, target) - return TRUE - -/** - * Perform a defibrillation. - */ -/datum/component/defib/proc/defibrillate(mob/living/user, mob/living/carbon/human/target) - // Before we do all the hard work, make sure we aren't already defibbing someone - if(busy) - return - - var/parent_unit = locateUID(actual_unit_uid) - var/should_cause_harm = user.a_intent == INTENT_HARM && !safety - - // Find what the defib should be referring to itself as - var/atom/defib_ref - if(parent_unit) - defib_ref = parent_unit - else if(robotic) - defib_ref = user - if(!defib_ref) // Contingency - defib_ref = parent - - // Check what the unit itself has to say about how the defib went - var/application_result = SEND_SIGNAL(parent, COMSIG_DEFIB_PADDLES_APPLIED, user, target, should_cause_harm) - - if(application_result & COMPONENT_BLOCK_DEFIB_DEAD) - user.visible_message("[defib_ref] beeps: Unit is unpowered.") - playsound(get_turf(defib_ref), fail_sound, 50, FALSE) - return - - if(on_cooldown) - to_chat(user, "[defib_ref] is recharging.") - return - - if(application_result & COMPONENT_BLOCK_DEFIB_MISC) - return // The unit should handle this - - if(!istype(target)) - if(robotic) - to_chat(user, "This unit is only designed to work on humanoid lifeforms.") - else - to_chat(user, "The instructions on [defib_ref] don't mention how to defibrillate that...") - return - - if(should_cause_harm && combat && heart_attack_chance == 100) - combat_fibrillate(user, target) - SEND_SIGNAL(parent, COMSIG_DEFIB_SHOCK_APPLIED, user, target, should_cause_harm, TRUE) - busy = FALSE - return - - if(should_cause_harm) - fibrillate(user, target) - SEND_SIGNAL(parent, COMSIG_DEFIB_SHOCK_APPLIED, user, target, should_cause_harm, TRUE) - return - - user.visible_message( - "[user] begins to place [parent] on [target]'s chest.", - "You begin to place [parent] on [target.name]'s chest." - ) - - busy = TRUE - var/mob/dead/observer/ghost = target.get_ghost() - if(ghost) - to_chat(ghost, "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)") - window_flash(ghost.client) - SEND_SOUND(ghost, sound('sound/effects/genetics.ogg')) - else if(HAS_TRAIT_FROM(target, TRAIT_FAKEDEATH, CHANGELING_TRAIT)) - to_chat(target, "Your heart is being defibrillated. Click the defibrillator status to be revived!") - window_flash(target.client) - SEND_SOUND(target, sound('sound/effects/genetics.ogg')) - target.throw_alert("cling_defib", /atom/movable/screen/alert/changeling_defib_revive, alert_args = list(parent, target)) - - user.visible_message("[user] places [parent] on [target]'s chest.", "You place [parent] on [target]'s chest.") - playsound(get_turf(defib_ref), charge_sound, 50, FALSE) - - if(ghost && !ghost.client && !QDELETED(ghost)) - log_debug("Ghost of name [ghost.name] is bound to [target.real_name], but lacks a client. Deleting ghost.") - QDEL_NULL(ghost) - - var/signal_result = SEND_SIGNAL(target, COMSIG_LIVING_PRE_DEFIB, user, parent, ghost) - - if(!do_after(user, DEFIB_TIME * speed_multiplier, target = target)) // Placed on chest and short delay to shock for dramatic effect, revive time is 5sec total - busy = FALSE - return - - if(istype(target.wear_suit, /obj/item/clothing/suit/space) && !combat) - user.visible_message("[defib_ref] buzzes: Patient's chest is obscured. Operation aborted.") - playsound(get_turf(defib_ref), fail_sound, 50, FALSE) - busy = FALSE - return - - signal_result |= SEND_SIGNAL(target, COMSIG_LIVING_DEFIBBED, user, parent, ghost) - - if(signal_result & COMPONENT_DEFIB_OVERRIDE) - // Let our signal handle it - busy = FALSE - return - - if(target.undergoing_cardiac_arrest() && target.stat != DEAD) // Can have a heart attack and heart is either missing, necrotic, or not beating - var/datum/organ/heart/heart = target.get_int_organ_datum(ORGAN_DATUM_HEART) - if(!heart) - user.visible_message("[defib_ref] buzzes: Resuscitation failed - Failed to pick up any heart electrical activity.") - else if(heart.linked_organ.status & ORGAN_DEAD) - user.visible_message("[defib_ref] buzzes: Resuscitation failed - Heart necrosis detected.") - if(!heart || (heart.linked_organ.status & ORGAN_DEAD)) - playsound(get_turf(defib_ref), fail_sound, 50, FALSE) - busy = FALSE - return - - target.set_heartattack(FALSE) - SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK, 100) - SEND_SIGNAL(parent, COMSIG_DEFIB_SHOCK_APPLIED, user, target, should_cause_harm, TRUE) - set_cooldown(cooldown) - user.visible_message("[defib_ref] pings: Cardiac arrhythmia corrected.") - target.visible_message("[target]'s body convulses a bit.", "You feel a jolt, and your heartbeat seems to steady.") - playsound(get_turf(defib_ref), zap_sound, 50, TRUE, -1) - playsound(get_turf(defib_ref), "bodyfall", 50, TRUE) - playsound(get_turf(defib_ref), success_sound, 50, FALSE) - busy = FALSE - return - - if(target.stat != DEAD && !HAS_TRAIT(target, TRAIT_FAKEDEATH)) - user.visible_message("[defib_ref] buzzes: Patient is not in a valid state. Operation aborted.") - playsound(get_turf(defib_ref), fail_sound, 50, FALSE) - busy = FALSE - return - - target.visible_message("[target]'s body convulses a bit.") - playsound(get_turf(defib_ref), "bodyfall", 50, TRUE) - playsound(get_turf(defib_ref), zap_sound, 50, TRUE, -1) - ghost = target.get_ghost(TRUE) // We have to double check whether the dead guy has entered their body during the above - - // Run through some quick failure states after shocking. - var/time_dead = world.time - target.timeofdeath - - var/failure_message - if(!target.is_revivable()) - failure_message = "[defib_ref] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation." - else if(target.getBruteLoss() >= 180 || target.getFireLoss() >= 180) - failure_message = "[defib_ref] buzzes: Resuscitation failed - Severe tissue damage detected." - else if(HAS_TRAIT(target, TRAIT_HUSK)) - failure_message = "[defib_ref] buzzes: Resuscitation failed - Subject is husked." - else if(target.blood_volume < BLOOD_VOLUME_SURVIVE) - failure_message = "[defib_ref] buzzes: Resuscitation failed - Patient blood volume critically low." - else if(!target.get_organ_slot("brain")) // So things like headless clings don't get outed - failure_message = "[defib_ref] buzzes: Resuscitation failed - No brain detected within patient." - else if(ghost) - if(!ghost.can_reenter_corpse || target.suiciding) // DNR or AntagHUD - failure_message = "[defib_ref] buzzes: Resuscitation failed - No electrical brain activity detected." - else - failure_message = "[defib_ref] buzzes: Resuscitation failed - Patient's brain is unresponsive. Further attempts may succeed." - else if(HAS_TRAIT(target, TRAIT_FAKEDEATH)) - if(signal_result & COMPONENT_DEFIB_FAKEDEATH_DENIED) - failure_message = "[defib_ref] buzzes: Resuscitation failed - Patient's brain is unresponsive. Further attempts may succeed." - else if(signal_result & COMPONENT_DEFIB_FAKEDEATH_ACCEPTED) - // as much as I hate that this is here, it has to come after the `Patient is not in a valid state. Operation aborted.` check. - REMOVE_TRAIT(target, TRAIT_FAKEDEATH, CHANGELING_TRAIT) - else - failure_message = "[defib_ref] buzzes: Resuscitation failed." // has a fakedeath like capulettium - - else if((signal_result & COMPONENT_BLOCK_DEFIB) || HAS_TRAIT(target, TRAIT_BADDNA) || target.suiciding) // these are a bit more arbitrary - failure_message = "[defib_ref] buzzes: Resuscitation failed." - - if(failure_message) - user.visible_message(failure_message) - playsound(get_turf(defib_ref), fail_sound, 50, FALSE) - else - // Heal each basic damage type by as much as we're under -100 health - var/damage_above_threshold = -(min(target.health, HEALTH_THRESHOLD_DEAD) - HEALTH_THRESHOLD_DEAD) - var/heal_amount = damage_above_threshold + 5 - target.adjustOxyLoss(-heal_amount) - target.adjustToxLoss(-heal_amount) - target.adjustFireLoss(-heal_amount) - target.adjustBruteLoss(-heal_amount) - - // Inflict some brain damage scaling with time spent dead - var/obj/item/organ/internal/brain/sponge = target.get_int_organ(/obj/item/organ/internal/brain) - var/defib_time_brain_damage = min(100 * time_dead / BASE_DEFIB_TIME_LIMIT, 99) // 20 from 1 minute onward, +20 per minute up to 99 - if(time_dead > DEFIB_TIME_LOSS && defib_time_brain_damage > sponge.damage) - target.setBrainLoss(defib_time_brain_damage) - - target.set_heartattack(FALSE) - target.update_revive() - target.KnockOut() - target.Paralyse(10 SECONDS) - target.emote("gasp") - - // Check if the brain has more than a critical amount of brain damage - if(target.check_brain_threshold(BRAIN_DAMAGE_RATIO_CRITICAL)) - // If you want to treat this with mannitol, it'll have to metabolize while the patient is alive, so it's alright to bring them back up for a minute - playsound(get_turf(defib_ref), safety_off_sound, 50, FALSE) - user.visible_message("[defib_ref] chimes: Minimal brain activity detected, brain treatment recommended for full resuscitation.") - else - playsound(get_turf(defib_ref), success_sound, 50, FALSE) - - user.visible_message("[defib_ref] pings: Resuscitation successful.") - - SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK, 100) - if(ishuman(target.pulledby)) // For some reason, pulledby isnt a list despite it being possible to be pulled by multiple people - excess_shock(user, target, target.pulledby, defib_ref) - for(var/obj/item/grab/G in target.grabbed_by) - if(ishuman(G.assailant)) - excess_shock(user, target, G.assailant, defib_ref) - if(target.receiving_cpr_from) - var/mob/living/carbon/human/H = locateUID(target.receiving_cpr_from) - if(istype(H)) - excess_shock(user, target, H, defib_ref) - - target.med_hud_set_health() - target.med_hud_set_status() - add_attack_logs(user, target, "Revived with [defib_ref]") - SSblackbox.record_feedback("tally", "players_revived", 1, "defibrillator") - SEND_SIGNAL(parent, COMSIG_DEFIB_SHOCK_APPLIED, user, target, should_cause_harm, isnull(failure_message)) - set_cooldown(cooldown) - busy = FALSE - -/** - * Inflict stamina loss (and possibly inflict cardiac arrest) on someone. - * - * Arguments: - * * user - wielder of the defib - * * target - person getting shocked - */ -/datum/component/defib/proc/fibrillate(mob/user, mob/living/carbon/human/target) - if(!istype(target)) - return - busy = TRUE - target.visible_message("[user] has touched [target] with [parent]!", \ - "[user] touches you with [parent], and you feel a strong jolt!") - target.apply_damage(60, STAMINA) - target.KnockDown(10 SECONDS) - playsound(get_turf(parent), zap_sound, 50, TRUE, -1) - target.emote("gasp") - if(combat && prob(heart_attack_chance)) - target.set_heartattack(TRUE) - SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK, 100) - add_attack_logs(user, target, "Stunned with [parent]") - set_cooldown(cooldown) - busy = FALSE - -/datum/component/defib/proc/combat_fibrillate(mob/user, mob/living/carbon/human/target) - if(!istype(target)) - return - busy = TRUE - target.apply_damage(60, STAMINA) - target.emote("gasp") - add_attack_logs(user, target, "Stunned with [parent]") - target.KnockDown(4 SECONDS) - if(IS_HORIZONTAL(target) && HAS_TRAIT(target, TRAIT_HANDS_BLOCKED)) // Weakening exists which doesn't floor you while stunned - add_attack_logs(user, target, "Gave a heart attack with [parent]") - target.set_heartattack(TRUE) - target.visible_message("[user] has touched [target] with [parent]!", \ - "[user] touches you with [parent], and you feel a strong jolt!") - playsound(get_turf(parent), zap_sound, 50, TRUE, -1) - SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK, 100) - set_cooldown(cooldown) - return - target.visible_message("[user] touches [target] lightly with [parent]!") - set_cooldown(2.5 SECONDS) - -/* - * Pass excess shock from a defibrillation into someone else. - * - * Arguments: - * * user - The person using the defib - * * origin - The person the shock was originally applied to, the person being defibrillated - * * affecting - The person the shock is spreading to and negatively affecting. - * * cell_location - item holding the power source. -*/ -/datum/component/defib/proc/excess_shock(mob/user, mob/living/origin, mob/living/carbon/human/affecting, obj/item/cell_location) - if(user == affecting) - return - var/power_source - if(robotic) - power_source = user - else - if(cell_location) - power_source = locate(/obj/item/stock_parts/cell) in cell_location - - if(!power_source) - return - - if(electrocute_mob(affecting, power_source, origin)) // shock anyone touching them >:) - var/datum/organ/heart/heart = affecting.get_int_organ_datum(ORGAN_DATUM_HEART) - if(heart.linked_organ.parent_organ == "chest" && affecting.has_both_hands()) // making sure the shock will go through their heart (drask hearts are in their head), and that they have both arms so the shock can cross their heart inside their chest - affecting.visible_message("[affecting]'s entire body shakes as a shock travels up [affecting.p_their()] arm!", \ - "You feel a powerful shock travel up your [affecting.hand ? affecting.get_organ("l_arm") : affecting.get_organ("r_arm")] and back down your [affecting.hand ? affecting.get_organ("r_arm") : affecting.get_organ("l_arm")]!") - affecting.set_heartattack(TRUE) - -#undef DEFIB_TIME diff --git a/code/datums/components/ducttape.dm b/code/datums/components/ducttape.dm deleted file mode 100644 index 230e16edf8170..0000000000000 --- a/code/datums/components/ducttape.dm +++ /dev/null @@ -1,82 +0,0 @@ -/datum/component/ducttape - var/x_offset = 0 - var/y_offset = 0 - var/icon/tape_overlay = null - var/hide_tape = FALSE - -/datum/component/ducttape/Initialize(obj/item/I, mob/user, x, y, hide_tape) - if(!istype(I)) //Something went wrong - return - if(!hide_tape) //if TRUE this hides the tape overlay and added examine text - RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(add_tape_overlay)) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(add_tape_text)) - x_offset = x - y_offset = y - RegisterSignal(parent, COMSIG_AFTER_ATTACK, PROC_REF(afterattack__legacy__attackchain)) - RegisterSignal(parent, COMSIG_ITEM_PICKUP, PROC_REF(pick_up)) - I.update_icon() //Do this first so the action button properly shows the icon - if(!hide_tape) //the tape can no longer be removed if TRUE - var/datum/action/item_action/remove_tape/RT = new(I) - if(I.loc == user) - RT.Grant(user) - I.add_tape() - -/datum/component/proc/add_tape_text(datum/source, mob/user, list/examine_list) - examine_list += "There's some sticky tape attached to [source]." - -/datum/component/ducttape/proc/add_tape_overlay(obj/item/O) - tape_overlay = new('icons/obj/bureaucracy.dmi', "tape") - tape_overlay.Shift(EAST, x_offset - 2) - tape_overlay.Shift(NORTH, y_offset - 2) - O.add_overlay(tape_overlay) - -/datum/component/ducttape/proc/remove_tape(obj/item/I, mob/user) - to_chat(user, "You tear the tape off [I]!") - playsound(I, 'sound/items/poster_ripped.ogg', 50, 1) - new /obj/item/trash/tapetrash(user.loc) - I.update_icon() - I.anchored = initial(I.anchored) - for(var/datum/action/item_action/remove_tape/RT in I.actions) - RT.Remove(user) - qdel(RT) - I.cut_overlay(tape_overlay) - user.transfer_fingerprints_to(I) - I.remove_tape() - qdel(src) - -/datum/component/ducttape/proc/afterattack__legacy__attackchain(obj/item/I, atom/target, mob/user, proximity, params) - if(!proximity) - return - if(!isturf(target)) - return - var/turf/source_turf = get_turf(I) - var/turf/target_turf = target - var/x_offset - var/y_offset - if(target_turf != get_turf(I)) //Trying to stick it on a wall, don't move it to the actual wall or you can move the item through it. Instead set the pixels as appropriate - var/target_direction = get_dir(source_turf, target_turf)//The direction we clicked - // Snowflake diagonal handling - if(target_direction in GLOB.diagonals) - to_chat(user, "You can't reach [target_turf].") - return - if(target_direction & EAST) - x_offset = 16 - y_offset = rand(-12, 12) - else if(target_direction & WEST) - x_offset = -16 - y_offset = rand(-12, 12) - else if(target_direction & NORTH) - x_offset = rand(-12, 12) - y_offset = 16 - else if(target_direction & SOUTH) - x_offset = rand(-12, 12) - y_offset = -16 - if(!user.drop_item_to_ground(I)) - return - to_chat(user, "You stick [I] to [target_turf].") - I.pixel_x = x_offset - I.pixel_y = y_offset - -/datum/component/ducttape/proc/pick_up(obj/item/I, mob/user) - I.pixel_x = initial(I.pixel_x) - I.pixel_y = initial(I.pixel_y) diff --git a/code/datums/components/ghost_direct_control.dm b/code/datums/components/ghost_direct_control.dm deleted file mode 100644 index 06eaa3e018cd8..0000000000000 --- a/code/datums/components/ghost_direct_control.dm +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Component which lets ghosts click on a mob to take control of it - */ -/datum/component/ghost_direct_control - /// Message to display upon successful possession - var/assumed_control_message - /// Type of ban you can get to prevent you from accepting this role - var/ban_type - /// Any extra checks which need to run before we take over - var/datum/callback/extra_control_checks - /// Callback run after someone successfully takes over the body - var/datum/callback/after_assumed_control - /// If we're currently awaiting the results of a ghost poll - var/awaiting_ghosts = FALSE - /// Is this an antagonist spawner, so we check ROLE_SYNDICATE - var/is_antag_spawner - -/datum/component/ghost_direct_control/Initialize( - ban_type = ROLE_SENTIENT, - role_name = null, - poll_question = null, - poll_candidates = TRUE, - poll_length = 10 SECONDS, - assumed_control_message = null, - datum/callback/extra_control_checks, - datum/callback/after_assumed_control, - is_antag_spawner = TRUE, - ) - . = ..() - if(!isliving(parent)) - return COMPONENT_INCOMPATIBLE - - src.ban_type = ban_type - src.assumed_control_message = assumed_control_message || "You are [parent]!" - src.extra_control_checks = extra_control_checks - src.after_assumed_control = after_assumed_control - src.is_antag_spawner = is_antag_spawner - - - if(poll_candidates) - INVOKE_ASYNC(src, PROC_REF(request_ghost_control), poll_question, role_name || "[parent]", poll_length) - -/datum/component/ghost_direct_control/RegisterWithParent() - . = ..() - RegisterSignal(parent, COMSIG_ATOM_ATTACK_GHOST, PROC_REF(on_ghost_clicked)) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examined)) - RegisterSignal(parent, COMSIG_MOB_LOGIN, PROC_REF(on_login)) - -/datum/component/ghost_direct_control/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ATOM_ATTACK_GHOST, COMSIG_PARENT_EXAMINE, COMSIG_MOB_LOGIN)) - return ..() - -/datum/component/ghost_direct_control/Destroy(force) - extra_control_checks = null - after_assumed_control = null - return ..() - -/// Inform ghosts that they can possess this -/datum/component/ghost_direct_control/proc/on_examined(datum/source, mob/user, list/examine_text) - SIGNAL_HANDLER //COMSIG_PARENT_EXAMINE - if(!isobserver(user)) - return - var/mob/living/our_mob = parent - if(our_mob.stat == DEAD || our_mob.key || awaiting_ghosts) - return - examine_text += "You could take control of this mob by clicking on it." - -/// Send out a request for a brain -/datum/component/ghost_direct_control/proc/request_ghost_control(poll_question, role_name, poll_length) - awaiting_ghosts = TRUE - var/list/candidates = SSghost_spawns.poll_candidates( - question = poll_question, - role = ban_type, - poll_time = poll_length, - source = parent, - role_cleanname = role_name, - flash_window = FALSE, - dont_play_notice_sound = TRUE - ) - awaiting_ghosts = FALSE - var/mob/chosen_one = null - if(length(candidates)) - chosen_one = pick(candidates) - - if(isnull(chosen_one)) - return - assume_direct_control(chosen_one) - -/// A ghost clicked on us, they want to get in this body -/datum/component/ghost_direct_control/proc/on_ghost_clicked(mob/our_mob, mob/dead/observer/hopeful_ghost) - SIGNAL_HANDLER // COMSIG_ATOM_ATTACK_GHOST - if(our_mob.key) - qdel(src) - return COMPONENT_CANCEL_ATTACK_CHAIN - if(!hopeful_ghost.client) - return COMPONENT_CANCEL_ATTACK_CHAIN - if(awaiting_ghosts) - to_chat(hopeful_ghost, "Ghost candidate selection currently in progress!") - return COMPONENT_CANCEL_ATTACK_CHAIN - if(!SSticker.HasRoundStarted()) - to_chat(hopeful_ghost, "You cannot assume control of this until after the round has started!") - return COMPONENT_CANCEL_ATTACK_CHAIN - INVOKE_ASYNC(src, PROC_REF(attempt_possession), our_mob, hopeful_ghost) - return COMPONENT_CANCEL_ATTACK_CHAIN - -/// We got far enough to establish that this mob is a valid target, let's try to posssess it -/datum/component/ghost_direct_control/proc/attempt_possession(mob/our_mob, mob/dead/observer/hopeful_ghost) - var/ghost_asked = tgui_alert(usr, "Become [our_mob]?", "Are you sure?", list("Yes", "No")) - if(ghost_asked != "Yes" || QDELETED(our_mob)) - return - assume_direct_control(hopeful_ghost) - -/// Grant possession of our mob, component is now no longer required -/datum/component/ghost_direct_control/proc/assume_direct_control(mob/harbinger) - if(QDELETED(src)) - to_chat(harbinger, "Offer to possess creature has expired!") - return - if(jobban_isbanned(harbinger, ban_type) || jobban_isbanned(harbinger, ROLE_SENTIENT) || (is_antag_spawner && jobban_isbanned(harbinger, ROLE_SYNDICATE))) - to_chat(harbinger, "You are banned from playing as this role!") - return - var/mob/living/new_body = parent - if(new_body.stat == DEAD) - to_chat(harbinger, "This body has passed away, it is of no use!") - return - if(new_body.key) - to_chat(harbinger, "[parent] has already become sapient!") - qdel(src) - return - if(extra_control_checks && !extra_control_checks.Invoke(harbinger)) - return - - // doesn't transfer mind because that transfers antag datum as well - new_body.key = harbinger.key - - // Already qdels due to below proc but just in case - if(!QDELETED(src)) - qdel(src) - -/// When someone assumes control, get rid of our component -/datum/component/ghost_direct_control/proc/on_login(mob/harbinger) - SIGNAL_HANDLER //COMSIG_MOB_LOGIN - // This proc is called the very moment .key is set, so we need to force mind to initialize here if we want the invoke to affect the mind of the mob - if(isnull(harbinger.mind)) - harbinger.mind_initialize() - to_chat(harbinger, "[assumed_control_message]") - after_assumed_control?.Invoke(harbinger) - qdel(src) diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm deleted file mode 100644 index e35d9379578b8..0000000000000 --- a/code/datums/components/material_container.dm +++ /dev/null @@ -1,421 +0,0 @@ -/* - This datum should be used for handling mineral contents of machines and whatever else is supposed to hold minerals and make use of them. - - Variables: - amount - raw amount of the mineral this container is holding, calculated by the defined value MINERAL_MATERIAL_AMOUNT=2000. - max_amount - max raw amount of mineral this container can hold. - sheet_type - type of the mineral sheet the container handles, used for output. - parent - object that this container is being used by, used for output. - MAX_STACK_SIZE - size of a stack of mineral sheets. Constant. -*/ - -/datum/component/material_container - var/total_amount = 0 - var/max_amount - var/sheet_type - var/list/materials - var/show_on_examine - var/disable_attackby - var/list/allowed_typecache - var/last_inserted_id - var/precise_insertion = FALSE - var/datum/callback/precondition - var/datum/callback/after_insert - -/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition, datum/callback/_after_insert, _disable_attackby) - materials = list() - max_amount = max(0, max_amt) - show_on_examine = _show_on_examine - disable_attackby = _disable_attackby - - if(allowed_types) - if(ispath(allowed_types) && allowed_types == /obj/item/stack) - allowed_typecache = GLOB.typecache_stack - else - allowed_typecache = typecacheof(allowed_types) - - precondition = _precondition - after_insert = _after_insert - - RegisterSignal(parent, COMSIG_ATTACK_BY, PROC_REF(OnAttackBy)) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(OnExamine)) - - var/list/possible_mats = list() - for(var/mat_type in subtypesof(/datum/material)) - var/datum/material/MT = mat_type - possible_mats[initial(MT.id)] = mat_type - for(var/id in mat_list) - if(possible_mats[id]) - var/mat_path = possible_mats[id] - materials[id] = new mat_path() - -/datum/component/material_container/Destroy(force, silent) - QDEL_LIST_ASSOC_VAL(materials) - return ..() - -/datum/component/material_container/proc/OnExamine(datum/source, mob/user, list/examine_list) - if(show_on_examine) - for(var/I in materials) - var/datum/material/M = materials[I] - var/amt = amount(M.id) - if(amt) - examine_list += "It has [amt] units of [lowertext(M.name)] stored." - -/datum/component/material_container/proc/OnAttackBy(datum/source, obj/item/I, mob/living/user) - var/list/tc = allowed_typecache - if(disable_attackby) - return - // Allow tools to be inserted on harm and help intent since they might be used for construction - // otherwise user needs to be on help intent - if(!((I.tool_behaviour && user.a_intent == INTENT_HARM) || user.a_intent == INTENT_HELP)) - return - if(I.flags & ABSTRACT) - return - if((I.flags_2 & (HOLOGRAM_2 | NO_MAT_REDEMPTION_2)) || (tc && !is_type_in_typecache(I, tc))) - to_chat(user, "[parent] won't accept [I]!") - return - . = COMPONENT_SKIP_AFTERATTACK - var/datum/callback/pc = precondition - if(pc && !pc.Invoke(user)) - return - var/material_amount = get_item_material_amount(I) - if(!material_amount) - to_chat(user, "[I] does not contain sufficient amounts of metal or glass to be accepted by [parent].") - return - if(!has_space(material_amount)) - to_chat(user, "[parent] is full. Please remove metal or glass from [parent] in order to insert more.") - return - user_insert(I, user) - -/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user) - set waitfor = FALSE - var/requested_amount - if(istype(I, /obj/item/stack) && precise_insertion) - var/atom/current_parent = parent - var/obj/item/stack/S = I - requested_amount = tgui_input_number(user, "How much do you want to insert?", "Inserting [S.singular_name]s", max_value = S.amount) - if(isnull(requested_amount) || (requested_amount <= 0)) - return - if(QDELETED(I) || QDELETED(user) || QDELETED(src) || parent != current_parent || user.incapacitated() || !in_range(current_parent, user) || user.l_hand != I && user.r_hand != I) - return - if(!user.drop_item()) - to_chat(user, "[I] is stuck to you and cannot be placed into [parent].") - return - var/inserted = insert_item(I, stack_amt = requested_amount) - if(inserted) - if(istype(I, /obj/item/stack)) - var/obj/item/stack/S = I - to_chat(user, "You insert [inserted] [S.singular_name][inserted>1 ? "s" : ""] into [parent].") - if(!QDELETED(I) && !user.put_in_hands(I)) - stack_trace("Warning: User could not put object back in hand during material container insertion, line [__LINE__]! This can lead to issues.") - I.forceMove(user.drop_location()) - else - to_chat(user, "You insert a material total of [inserted] into [parent].") - qdel(I) - if(after_insert) - after_insert.Invoke(I.type, last_inserted_id, inserted) - else - user.put_in_active_hand(I) - -//For inserting an amount of material -/datum/component/material_container/proc/insert_amount(amt, id = null) - if(amt > 0 && has_space(amt)) - var/total_amount_saved = total_amount - if(id) - var/datum/material/M = materials[id] - if(M) - M.amount += amt - total_amount += amt - else - for(var/i in materials) - var/datum/material/M = materials[i] - M.amount += amt - total_amount += amt - return (total_amount - total_amount_saved) - return FALSE - -/datum/component/material_container/proc/insert_stack(obj/item/stack/S, amt, multiplier = 1) - if(isnull(amt)) - amt = S.get_amount() - - if(amt <= 0) - return FALSE - - if(amt > S.get_amount()) - amt = S.get_amount() - - var/material_amt = get_item_material_amount(S) - if(!material_amt) - return FALSE - - amt = min(amt, round(((max_amount - total_amount) / material_amt))) - if(!amt) - return FALSE - - last_inserted_id = insert_materials(S,amt * multiplier) - S.use(amt) - return amt - -/datum/component/material_container/proc/insert_item(obj/item/I, multiplier = 1, stack_amt) - if(!I) - return FALSE - if(istype(I, /obj/item/stack)) - return insert_stack(I, stack_amt, multiplier) - - var/material_amount = get_item_material_amount(I) - if(!material_amount || !has_space(material_amount)) - return FALSE - - last_inserted_id = insert_materials(I, multiplier) - return material_amount - -/datum/component/material_container/proc/insert_materials(obj/item/I, multiplier = 1) //for internal usage only - var/datum/material/M - var/primary_mat - var/max_mat_value = 0 - for(var/MAT in materials) - M = materials[MAT] - M.amount += I.materials[MAT] * multiplier - total_amount += I.materials[MAT] * multiplier - if(I.materials[MAT] > max_mat_value) - primary_mat = MAT - return primary_mat - -//For consuming material -//mats is a list of types of material to use and the corresponding amounts, example: list(MAT_METAL=100, MAT_GLASS=200) -/datum/component/material_container/proc/use_amount(list/mats, multiplier=1) - if(!mats || !length(mats)) - return FALSE - - var/datum/material/M - for(var/MAT in materials) - M = materials[MAT] - if(M.amount < (mats[MAT] * multiplier)) - return FALSE - - var/total_amount_save = total_amount - for(var/MAT in materials) - M = materials[MAT] - M.amount -= mats[MAT] * multiplier - total_amount -= mats[MAT] * multiplier - - return total_amount_save - total_amount - - -/datum/component/material_container/proc/use_amount_type(amt, id) - var/datum/material/M = materials[id] - if(M) - if(M.amount >= amt) - M.amount -= amt - total_amount -= amt - return amt - return FALSE - -/datum/component/material_container/proc/transer_amt_to(datum/component/material_container/T, amt, id) - if((amt==0)||(!T)||(!id)) - return FALSE - if(amt<0) - return T.transer_amt_to(src, -amt, id) - var/datum/material/M = materials[id] - - if(M) - var/tr = min(amt, M.amount,T.can_insert_amount(amt, id)) - if(tr) - use_amount_type(tr, id) - T.insert_amount(tr, id) - return tr - return FALSE - -/datum/component/material_container/proc/can_insert_amount(amt, id) - if(amt && id) - var/datum/material/M = materials[id] - if(M) - if((total_amount + amt) <= max_amount) - return amt - else - return (max_amount-total_amount) - -/datum/component/material_container/proc/can_use_amount(amt, id, list/mats) - if(amt && id) - var/datum/material/M = materials[id] - if(M && M.amount >= amt) - return TRUE - else if(istype(mats)) - for(var/M in mats) - if(materials[M] && (mats[M] <= materials[M])) - continue - else - return FALSE - return TRUE - return FALSE - -//For spawning mineral sheets; internal use only -/datum/component/material_container/proc/retrieve(sheet_amt, datum/material/M, target = null) - if(!M.sheet_type) - return 0 - if(sheet_amt <= 0) - return 0 - - if(!target) - target = get_turf(parent) - if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT)) - sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT) - var/count = 0 - while(sheet_amt > MAX_STACK_SIZE) - new M.sheet_type(target, MAX_STACK_SIZE) - count += MAX_STACK_SIZE - use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id) - sheet_amt -= MAX_STACK_SIZE - if(sheet_amt >= 1) - new M.sheet_type(target, sheet_amt) - count += sheet_amt - use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id) - return count - -/datum/component/material_container/proc/retrieve_sheets(sheet_amt, id, target = null) - if(materials[id]) - return retrieve(sheet_amt, materials[id], target) - return FALSE - -/datum/component/material_container/proc/retrieve_amount(amt, id, target) - return retrieve_sheets(amount2sheet(amt), id, target) - -/datum/component/material_container/proc/retrieve_all(target = null) - var/result = 0 - var/datum/material/M - for(var/MAT in materials) - M = materials[MAT] - result += retrieve_sheets(amount2sheet(M.amount), MAT, target) - return result - -/datum/component/material_container/proc/has_space(amt = 0) - return (total_amount + amt) <= max_amount - -/datum/component/material_container/proc/has_materials(list/mats, multiplier=1) - if(!mats || !length(mats)) - return FALSE - - var/datum/material/M - for(var/MAT in mats) - M = materials[MAT] - if(M.amount < (mats[MAT] * multiplier)) - return FALSE - return TRUE - -/datum/component/material_container/proc/amount2sheet(amt) - if(amt >= MINERAL_MATERIAL_AMOUNT) - return round(amt / MINERAL_MATERIAL_AMOUNT) - return FALSE - -/datum/component/material_container/proc/sheet2amount(sheet_amt) - if(sheet_amt > 0) - return sheet_amt * MINERAL_MATERIAL_AMOUNT - return FALSE - -/datum/component/material_container/proc/amount(id) - var/datum/material/M = materials[id] - return M ? M.amount : 0 - -//returns the amount of material relevant to this container; -//if this container does not support glass, any glass in 'I' will not be taken into account -/datum/component/material_container/proc/get_item_material_amount(obj/item/I) - if(!istype(I)) - return FALSE - if(!I.materials) // some objects have no materials and this will cause runtimes without this check - return 0 - var/material_amount = 0 - for(var/MAT in materials) - material_amount += I.materials[MAT] - return material_amount - - -/datum/material - var/name - var/amount = 0 - var/id = null - var/sheet_type = null - var/coin_type = null - var/ore_type = null - -/datum/material/metal - name = "Metal" - id = MAT_METAL - sheet_type = /obj/item/stack/sheet/metal - coin_type = /obj/item/coin/iron - ore_type = /obj/item/stack/ore/iron - -/datum/material/glass - name = "Glass" - id = MAT_GLASS - sheet_type = /obj/item/stack/sheet/glass - ore_type = /obj/item/stack/ore/glass - -/datum/material/silver - name = "Silver" - id = MAT_SILVER - sheet_type = /obj/item/stack/sheet/mineral/silver - coin_type = /obj/item/coin/silver - ore_type = /obj/item/stack/ore/silver - -/datum/material/gold - name = "Gold" - id = MAT_GOLD - sheet_type = /obj/item/stack/sheet/mineral/gold - coin_type = /obj/item/coin/gold - ore_type = /obj/item/stack/ore/gold - -/datum/material/diamond - name = "Diamond" - id = MAT_DIAMOND - sheet_type = /obj/item/stack/sheet/mineral/diamond - coin_type = /obj/item/coin/diamond - ore_type = /obj/item/stack/ore/diamond - -/datum/material/uranium - name = "Uranium" - id = MAT_URANIUM - sheet_type = /obj/item/stack/sheet/mineral/uranium - coin_type = /obj/item/coin/uranium - ore_type = /obj/item/stack/ore/uranium - -/datum/material/plasma - name = "Solid Plasma" - id = MAT_PLASMA - sheet_type = /obj/item/stack/sheet/mineral/plasma - coin_type = /obj/item/coin/plasma - ore_type = /obj/item/stack/ore/plasma - -/datum/material/bluespace - name = "Bluespace Mesh" - id = MAT_BLUESPACE - sheet_type = /obj/item/stack/ore/bluespace_crystal/refined - ore_type = /obj/item/stack/ore/bluespace_crystal - -/datum/material/bananium - name = "Bananium" - id = MAT_BANANIUM - sheet_type = /obj/item/stack/sheet/mineral/bananium - coin_type = /obj/item/coin/clown - ore_type = /obj/item/stack/ore/bananium - -/datum/material/tranquillite - name = "Tranquillite" - id = MAT_TRANQUILLITE - sheet_type = /obj/item/stack/sheet/mineral/tranquillite - coin_type = /obj/item/coin/mime - ore_type = /obj/item/stack/ore/tranquillite - -/datum/material/titanium - name = "Titanium" - id = MAT_TITANIUM - sheet_type = /obj/item/stack/sheet/mineral/titanium - ore_type = /obj/item/stack/ore/titanium - -/datum/material/biomass - name = "Biomass" - id = MAT_BIOMASS - -/datum/material/plastic - name = "Plastic" - id = MAT_PLASTIC - sheet_type = /obj/item/stack/sheet/plastic diff --git a/code/datums/components/orbiter.dm b/code/datums/components/orbiter.dm deleted file mode 100644 index 84fd4fab5b3c0..0000000000000 --- a/code/datums/components/orbiter.dm +++ /dev/null @@ -1,476 +0,0 @@ -/** - * Code to handle atoms orbiting other atoms, following them as they move. - * The basic logic is simple. We register a signal, COMSIG_MOVABLE_MOVED onto orbited atoms. - * When the orbited atom moves, any ghosts orbiting them are moved to their turf. - * We also register a MOVED signal onto the ghosts to cancel their orbit if they move themselves. - * Complexities come in for items within other items (such as the NAD in a box in a backpack on an assistant pretending to be the captain), - * as items in containers do **not** fire COMSIG_MOVABLE_MOVED when their container moves. - * - * The signal logic for items in containers is as follows: - * Assume 1 is some item (for example, the NAD) and 2 is a box. - * When 1 is added to 2, we register the typical orbit COMSIG_MOVABLE_MOVED onto 2. - * This in essence makes 2 the "leader", the atom that ghosts follow in movement. - * As 2 is moved around (say, dragged on the floor) ghosts will follow it. - * We also register a new intermediate COMSIG_MOVABLE_MOVED signal onto 1 that tracks if 1 is moved. - * Remember, this will only fire if 1 is moved around containers, since it's impossible for it to actually move on its own. - * If 1 is moved out of 2, this signal makes 1 the new leader. - * Lastly, we add a COMSIG_ATOM_EXITED to 2, which tracks if 1 is removed from 2. - * This EXITED signal cleans up any orbiting signals on and above 2. - * If 2 is added to another item, (say a backpack, 3) - * 3 becomes the new leader - * 2 becomes an intermediate - * 1 is unchanged (but still carries the orbiter datum) - * - * - * You may be asking yourself: is this overengineered? - * In part, yes. However, MOVED signals don't get fired for items in containers, so this is - * really the next best way. - * Also, is this really optimal? - * As much as it can be, I believe. This signal-shuffling will not happen for any item that is just moving from turf to turf, - * which should apply to 95% of cases (read: ghosts orbiting mobs). - */ - -#define ORBIT_LOCK_IN (1<<0) -#define ORBIT_FORCE_MOVE (1<<1) - -/datum/component/orbiter - can_transfer = TRUE - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - /// List of observers orbiting the parent - var/list/orbiter_list - /// Cached transforms from before the orbiter started orbiting, to be restored on stopping their orbit - var/list/orbit_data - -/// See atom/movable/proc/orbit for parameter definitions -/datum/component/orbiter/Initialize(atom/movable/orbiter, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lock_in_orbit = FALSE, force_move = FALSE, orbit_layer = FLY_LAYER) - if(!istype(orbiter) || !isatom(parent) || isarea(parent)) - return COMPONENT_INCOMPATIBLE - - orbiter_list = list() - orbit_data = list() - - begin_orbit(orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation, lock_in_orbit, force_move, orbit_layer) - -/datum/component/orbiter/RegisterWithParent() - var/atom/target = parent - register_signals(target) - -/datum/component/orbiter/UnregisterFromParent() - var/atom/target = parent - remove_signals(target) - -/datum/component/orbiter/Destroy() - remove_signals(parent) - for(var/i in orbiter_list) - end_orbit(i) - orbiter_list = null - orbit_data = null - return ..() - -/// See atom/movable/proc/orbit for parameter definitions -/datum/component/orbiter/InheritComponent(datum/component/orbiter/new_comp, original, atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation, lock_in_orbit, force_move, orbit_layer) - // No transfer happening - if(!new_comp) - begin_orbit(arglist(args.Copy(3))) - return - - orbiter_list += new_comp.orbiter_list - orbit_data += new_comp.orbit_data - new_comp.orbiter_list = list() - new_comp.orbit_data = list() - QDEL_NULL(new_comp) - -/datum/component/orbiter/PostTransfer() - if(!isatom(parent) || isarea(parent) || !get_turf(parent)) - return COMPONENT_INCOMPATIBLE - -/// See atom/movable/proc/orbit for parameter definitions -/datum/component/orbiter/proc/begin_orbit(atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation, lock_in_orbit, force_move, orbit_layer) - if(!istype(orbiter)) - return - - var/was_refreshing = FALSE - var/atom/currently_orbiting = locateUID(orbiter.orbiting_uid) - - if(currently_orbiting) - if(orbiter in orbiter_list) - was_refreshing = TRUE - end_orbit(orbiter, TRUE) - else - var/datum/component/orbiter/orbit_comp = currently_orbiting.GetComponent(/datum/component/orbiter) - orbit_comp.end_orbit(orbiter) - - orbiter_list += orbiter - - // make sure orbits get cleaned up nicely if the parent qdels - RegisterSignal(orbiter, COMSIG_PARENT_QDELETING, PROC_REF(end_orbit)) - - var/orbit_flags = 0 - if(lock_in_orbit) - orbit_flags |= ORBIT_LOCK_IN - if(force_move) - orbit_flags |= ORBIT_FORCE_MOVE - - orbiter.orbiting_uid = parent.UID() - store_orbit_data(orbiter, orbit_flags) - - if(!lock_in_orbit) - RegisterSignal(orbiter, COMSIG_MOVABLE_MOVED, PROC_REF(orbiter_move_react)) - - // Head first! - if(pre_rotation) - var/matrix/M = matrix(orbiter.transform) - var/pre_rot = 90 - if(!clockwise) - pre_rot = -90 - M.Turn(pre_rot) - orbiter.transform = M - - var/matrix/shift = matrix(orbiter.transform) - shift.Translate(0,radius) - orbiter.transform = shift - - orbiter.layer = orbit_layer - - SEND_SIGNAL(parent, COMSIG_ATOM_ORBIT_BEGIN, orbiter) - - // If we changed orbits, we didn't stop our rotation, and don't need to start it up again - if(!was_refreshing) - orbiter.SpinAnimation(rotation_speed, -1, clockwise, rotation_segments, parallel = FALSE) - - var/target_loc = get_turf(parent) - var/current_loc = orbiter.loc - if(force_move) - orbiter.forceMove(target_loc) - else - orbiter.loc = target_loc - // Setting loc directly doesn't fire COMSIG_MOVABLE_MOVED, so we need to do it ourselves - SEND_SIGNAL(orbiter, COMSIG_MOVABLE_MOVED, current_loc, target_loc, null) - orbiter.animate_movement = SYNC_STEPS - -/** - * End the orbit and clean up our transformation. - * If this removes the last atom orbiting us, then qdel ourselves. - * Howver, if refreshing == TRUE, src will not be qdeleted if this leaves us with 0 orbiters. - */ -/datum/component/orbiter/proc/end_orbit(atom/movable/orbiter, refreshing = FALSE) - SIGNAL_HANDLER - - if(!(orbiter in orbiter_list)) - return - - if(orbiter) - orbiter.animate_movement = SLIDE_STEPS - if(!QDELETED(parent)) - SEND_SIGNAL(parent, COMSIG_ATOM_ORBIT_STOP, orbiter) - SEND_SIGNAL(orbiter, COMSIG_ATOM_ORBITER_STOP, parent) - - orbiter.transform = get_cached_transform(orbiter) - orbiter.layer = get_orbiter_layer(orbiter) - - UnregisterSignal(orbiter, COMSIG_MOVABLE_MOVED) - UnregisterSignal(orbiter, COMSIG_PARENT_QDELETING) - - orbiter.orbiting_uid = null - - if(!refreshing) - orbiter.SpinAnimation(0, 0, parallel = FALSE) - - // If it's null, still remove it from the list - orbiter_list -= orbiter - orbit_data -= orbiter - - if(!length(orbiter_list) && !QDELING(src) && !refreshing) - qdel(src) - -/** - * The actual implementation function of the move react. - * **if you're trying to call this from a signal, call parent_move_react instead.** - * This implementation is separate so the orbited atom's old location and new location can be passed in separately. - */ -/datum/component/orbiter/proc/handle_parent_move(atom/movable/orbited, atom/old_loc, atom/new_loc, direction) - - if(new_loc == old_loc) - return - - var/turf/new_turf = get_turf(new_loc) - if(!new_turf) - // don't follow someone to nullspace - qdel(src) - - var/atom/cur_loc = new_loc - - // If something's only moving between turfs, don't bother changing signals, just move ghosts. - // Honestly, that should apply to 95% of orbiting cases, which should be a nice optimization. - if(!(isturf(old_loc) && isturf(new_loc))) - - // Clear any signals that may still exist upstream of where this object used to be - remove_signals(old_loc) - // ...and create a new signal hierarchy upstream of where the object is now. - // cur_loc is the current "leader" atom - cur_loc = register_signals(orbited) - - var/orbit_params - var/orbiter_turf - new_turf = get_turf(cur_loc) - for(var/atom/movable/movable_orbiter in orbiter_list) - orbiter_turf = get_turf(movable_orbiter) - if(QDELETED(movable_orbiter) || orbiter_turf == new_turf) - continue - - orbit_params = get_orbit_params(movable_orbiter) - - if(orbit_params & ORBIT_FORCE_MOVE) - movable_orbiter.forceMove(new_turf) - else - var/orbiter_loc = movable_orbiter.loc - movable_orbiter.loc = new_turf - SEND_SIGNAL(movable_orbiter, COMSIG_MOVABLE_MOVED, orbiter_loc, new_turf, null) - - if(CHECK_TICK && new_turf != get_turf(movable_orbiter)) - // We moved again during the checktick, cancel current operation - break -/** - * Signal handler for COMSIG_MOVABLE_MOVED. Special wrapper to handle the arguments that come from the signal. - * If you want to call this directly, just call handle_parent_move. - */ -/datum/component/orbiter/proc/parent_move_react(atom/movable/orbited, atom/old_loc, direction) - set waitfor = FALSE // Transfer calls this directly and it doesnt care if the ghosts arent done moving - handle_parent_move(orbited, old_loc, orbited.loc, direction) - -/** -* Called when the orbiter themselves moves. -*/ -/datum/component/orbiter/proc/orbiter_move_react(atom/movable/orbiter, atom/oldloc, direction) - SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED - - if(get_turf(orbiter) == get_turf(parent) || get_turf(orbiter) == get_turf(oldloc) || get_turf(orbiter) == oldloc || orbiter.loc == oldloc) - return - - if(orbiter in orbiter_list) - // Only end the spin animation when we're actually ending an orbit, not just changing targets - orbiter.SpinAnimation(0, 0, parallel = FALSE) - end_orbit(orbiter) - -/** - * Remove all orbit-related signals in the object hierarchy above start. - */ -/datum/component/orbiter/proc/remove_signals(atom/start) - var/atom/cur_atom = start - while(cur_atom && !isturf(cur_atom) && !(cur_atom in orbiter_list) && cur_atom != parent) - UnregisterSignal(cur_atom, COMSIG_ATOM_EXITED) - UnregisterSignal(cur_atom, COMSIG_MOVABLE_MOVED) - cur_atom = cur_atom.loc - -/** - * Register signals up the hierarchy, adding them to each parent (and their parent, and so on) up to the turf they're on. - * The last atom in the hierarchy (the one whose .loc is the turf) becomes the leader, the atom ghosts will follow. - * Registers on_intermediate_move for every non-leader atom so that if they move (removing them from the hierarchy), they will be set as the new leader. - * Also registers on_remove_child to remove signals up the hierarchy when a child gets removed. - * start: the first atom to register signals on. If start isn't inside of anything (or if its .loc is a turf), then it will become the leader. - * Returns the new "leader", the atom that ghosts will follow. - */ -/datum/component/orbiter/proc/register_signals(atom/start) - if(isturf(start)) - return - var/atom/cur_atom = start - while(cur_atom.loc && !isturf(cur_atom.loc) && !(cur_atom.loc in orbiter_list)) - RegisterSignal(cur_atom, COMSIG_MOVABLE_MOVED, PROC_REF(on_intermediate_move), TRUE) - RegisterSignal(cur_atom, COMSIG_ATOM_EXITED, PROC_REF(on_remove_child), TRUE) - cur_atom = cur_atom.loc - - // Set the topmost atom (right before the turf) to be our new leader - RegisterSignal(cur_atom, COMSIG_MOVABLE_MOVED, PROC_REF(parent_move_react), TRUE) - RegisterSignal(cur_atom, COMSIG_ATOM_EXITED, PROC_REF(on_remove_child), TRUE) - return cur_atom - -/** - * Callback fired when an item is removed from a tracked atom. - * Removes all orbit-related signals up its hierarchy and moves orbiters to the current child. - * As this will never be called by a turf, this should not conflict with parent_move_react. - */ -/datum/component/orbiter/proc/on_remove_child(datum/source, atom/movable/exiting, direction) - SIGNAL_HANDLER // COMSIG_ATOM_EXITED - - // ensure the child is actually connected to the orbited atom - if(!is_in_hierarchy(exiting) || (exiting in orbiter_list)) - return - // Remove all signals upwards of the child and re-register them as the new parent - remove_signals(exiting) - RegisterSignal(exiting, COMSIG_MOVABLE_MOVED, PROC_REF(parent_move_react), TRUE) - RegisterSignal(exiting, COMSIG_ATOM_EXITED, PROC_REF(on_remove_child), TRUE) - var/new_loc = get_step(exiting, direction) - INVOKE_ASYNC(src, PROC_REF(handle_parent_move), exiting, exiting.loc, new_loc) - -/** - * Called when an intermediate (somewhere between the topmost and the orbited) atom moves. - * This atom will now become the leader. - */ -/datum/component/orbiter/proc/on_intermediate_move(atom/movable/tracked, atom/old_loc) - SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED - - // Make sure we don't trigger off an orbiter following! - if(!is_in_hierarchy(tracked) || (tracked in orbiter_list)) - return - - remove_signals(old_loc) // TODO this doesn't work if something's removed from hand - RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, PROC_REF(parent_move_react), TRUE) - RegisterSignal(tracked, COMSIG_ATOM_EXITED, PROC_REF(on_remove_child), TRUE) - INVOKE_ASYNC(src, PROC_REF(handle_parent_move), tracked, old_loc, tracked.loc) - -/** - * Returns TRUE if atom_to_find is transitively a parent of src. - */ -/datum/component/orbiter/proc/is_in_hierarchy(atom/movable/atom_to_find) - var/atom/check = parent - while(check) - if(check == atom_to_find) - return TRUE - check = check.loc - return FALSE - -/////////////////////////////////// -/// orbit data helper functions -/////////////////////////////////// - -/** - * Store a collection of data for an orbiter. - * orbiter: orbiter atom itself. The orbiter's transform and layer at this point will be captured and cached. - * orbit_flags: bitfield consisting of flags describing the orbit. - */ -/datum/component/orbiter/proc/store_orbit_data(atom/movable/orbiter, orbit_flags) - var/list/new_orbit_data = list( - orbiter.transform, // cached transform - orbit_flags, // params about the orbit - orbiter.layer // cached layer from the orbiter - ) - orbit_data[orbiter] = new_orbit_data - return new_orbit_data - -/** - * Get cached transform of the given orbiter. - */ -/datum/component/orbiter/proc/get_cached_transform(atom/movable/orbiter) - if(orbiter) - var/list/orbit_params = orbit_data[orbiter] - if(orbit_params) - return orbit_params[1] - -/** - * Get the given orbiter's orbit parameters bitfield - */ -/datum/component/orbiter/proc/get_orbit_params(atom/movable/orbiter) - if(orbiter) - var/list/orbit_params = orbit_data[orbiter] - if(orbit_params) - return orbit_params[2] - -/** - * Get the layer the given orbiter was on before they started orbiting - */ -/datum/component/orbiter/proc/get_orbiter_layer(atom/movable/orbiter) - if(orbiter) - var/list/orbit_params = orbit_data[orbiter] - if(orbit_params) - return orbit_params[3] - -/////////////////////////////////// -// Atom procs/vars -/////////////////////////////////// - -/** - * Set an atom to orbit around another one. This atom will follow the base atom's movement and rotate around it. - * - * orbiter: atom which will be doing the orbiting - * radius: range to orbit at, radius of the circle formed by orbiting - * clockwise: whether you orbit clockwise or anti clockwise - * rotation_speed: how fast to rotate - * rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default. - * pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts - * lock_in_orbit: Forces src to always be on A's turf, otherwise the orbit cancels when src gets too far away (eg: ghosts) - * force_move: If true, ghosts will be ForceMoved instead of having their .loc updated directly. - * orbit_layer: layer that the orbiter should be on. The original layer will be restored on orbit end. - */ -/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lock_in_orbit = FALSE, force_move = FALSE, orbit_layer = FLY_LAYER) - if(!istype(A) || !get_turf(A) || A == src) - return - // Adding a new component every time works as our dupe type will make us just inherit the new orbiter - return A.AddComponent(/datum/component/orbiter, src, radius, clockwise, rotation_speed, rotation_segments, pre_rotation, lock_in_orbit, force_move, orbit_layer) - -/** - * Stop this atom from orbiting whatever it's orbiting. - */ -/atom/movable/proc/stop_orbit() - var/atom/orbited = locateUID(orbiting_uid) - if(!orbited) - return - var/datum/component/orbiter/C = orbited.GetComponent(/datum/component/orbiter) - if(!C) - return - C.end_orbit(src) - -/** - * Simple helper proc to get a list of everything directly orbiting the current atom, without checking contents, or null if nothing is. - */ -/atom/proc/get_orbiters() - var/datum/component/orbiter/C = GetComponent(/datum/component/orbiter) - if(C && C.orbiter_list) - return C.orbiter_list - else - return null - -/** - * Remove an orbiter from the atom it's orbiting. - */ -/atom/proc/remove_orbiter(atom/movable/orbiter) - var/datum/component/orbiter/C = GetComponent(/datum/component/orbiter) - if(C && C.orbiter_list && (orbiter in C.orbiter_list)) - C.end_orbit(orbiter) - -/** - * Recursive getter method to return a list of all ghosts transitively orbiting this atom. - * This will find orbiters either directly orbiting the followed atom, or any orbiters orbiting them (and so on). - * - * This shouldn't be passed arugments. - */ -/atom/proc/get_orbiters_recursive(list/processed, source = TRUE) - var/list/output = list() - if(!processed) - processed = list() - if(src in processed) - return output - - processed += src - // Make sure we don't shadow outer orbiters - for(var/atom/movable/atom_orbiter in get_orbiters()) - if(isobserver(atom_orbiter)) - output |= atom_orbiter - output += atom_orbiter.get_orbiters_recursive(processed, source = FALSE) - return output - -/** - * Check every object in the hierarchy above ourselves for orbiters, and return the full list of them. - * If an object is being held in a backpack, returns orbiters of the backpack, the person - * If recursive == TRUE, this will also check recursively through any ghosts seen to make sure we find *everything* upstream - */ -/atom/proc/get_orbiters_up_hierarchy(list/processed, source = TRUE, recursive = FALSE) - var/list/output = list() - if(!processed) - processed = list() - if((src in processed) || isturf(src)) - return output - - processed += src - for(var/atom/movable/atom_orbiter in get_orbiters()) - if(isobserver(atom_orbiter)) - if(recursive) - output += atom_orbiter.get_orbiters_recursive() - output += atom_orbiter - - if(loc) - output += loc.get_orbiters_up_hierarchy(processed, source = FALSE) - - return output - -#undef ORBIT_LOCK_IN -#undef ORBIT_FORCE_MOVE diff --git a/code/datums/components/paintable.dm b/code/datums/components/paintable.dm deleted file mode 100644 index f0a7187149a8e..0000000000000 --- a/code/datums/components/paintable.dm +++ /dev/null @@ -1,31 +0,0 @@ -/datum/component/spraycan_paintable - var/current_paint - -/datum/component/spraycan_paintable/Initialize() - RegisterSignal(parent, COMSIG_ATTACK_BY, PROC_REF(Repaint)) - -/datum/component/spraycan_paintable/Destroy() - RemoveCurrentCoat() - return ..() - -/datum/component/spraycan_paintable/proc/RemoveCurrentCoat() - var/atom/A = parent - A.remove_atom_colour(FIXED_COLOUR_PRIORITY, current_paint) - -/datum/component/spraycan_paintable/proc/Repaint(datum/source, obj/item/toy/crayon/spraycan/spraycan, mob/living/user) - if(!istype(spraycan) || user.a_intent == INTENT_HARM) - return - . = COMPONENT_SKIP_AFTERATTACK - if(spraycan.capped) - to_chat(user, "Take the cap off first!") - return - if(spraycan.uses < 2) - to_chat(user, "There is not enough paint in the can!") - return - RemoveCurrentCoat() - var/colour = spraycan.colour - current_paint = colour - var/atom/A = parent - A.add_atom_colour(colour, FIXED_COLOUR_PRIORITY) - playsound(spraycan, 'sound/effects/spray.ogg', 5, TRUE, 5) - to_chat(user, "You spray [spraycan] on [A], painting it.") diff --git a/code/datums/components/radioactive.dm b/code/datums/components/radioactive.dm deleted file mode 100644 index 6652b4ed6460f..0000000000000 --- a/code/datums/components/radioactive.dm +++ /dev/null @@ -1,118 +0,0 @@ -#define RAD_AMOUNT_LOW 50 -#define RAD_AMOUNT_MEDIUM 200 -#define RAD_AMOUNT_HIGH 500 -#define RAD_AMOUNT_EXTREME 1000 - -/datum/component/radioactive - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - - var/source - ///the half-life measured in ticks - var/hl3_release_date - var/strength - var/can_contaminate - -/datum/component/radioactive/Initialize(_strength = 0, _source, _half_life = RAD_HALF_LIFE, _can_contaminate = TRUE) - if(!istype(parent, /atom)) - return COMPONENT_INCOMPATIBLE - strength = _strength - source = _source - hl3_release_date = _half_life - can_contaminate = _can_contaminate - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(rad_examine)) - RegisterSignal(parent, COMSIG_ADMIN_DECONTAMINATE, PROC_REF(admin_decontaminate)) - if(isitem(parent)) - RegisterSignal(parent, COMSIG_ATTACK, PROC_REF(rad_attack)) - RegisterSignal(parent, COMSIG_ATTACK_OBJ, PROC_REF(rad_attack)) - if(strength > RAD_MINIMUM_CONTAMINATION) - SSradiation.warn(src) - //Let's make er glow - //This relies on parent not being a turf or something. IF YOU CHANGE THAT, CHANGE THIS - var/atom/movable/master = parent - master.add_filter("rad_glow", 2, list("type" = "outline", "color" = "#39ff1430", "size" = 2)) - addtimer(CALLBACK(src, PROC_REF(glow_loop), master), rand(1, 19)) //Things should look uneven - LAZYADD(SSradiation.all_radiations, src) - START_PROCESSING(SSradiation, src) - -/datum/component/radioactive/Destroy() - STOP_PROCESSING(SSradiation, src) - LAZYREMOVE(SSradiation.all_radiations, src) - var/atom/movable/master = parent - master.remove_filter("rad_glow") - return ..() - -/datum/component/radioactive/process() - if(!prob(50)) - return - radiation_pulse(parent, strength, RAD_DISTANCE_COEFFICIENT * 2, FALSE, can_contaminate) - if(!hl3_release_date) - return - strength -= strength / hl3_release_date - SSradiation.update_rad_cache(src) - if(strength <= RAD_BACKGROUND_RADIATION) - qdel(src) - return PROCESS_KILL - -/datum/component/radioactive/proc/glow_loop(atom/movable/master) - var/filter = master.get_filter("rad_glow") - if(filter) - animate(filter, alpha = 110, time = 15, loop = -1) - animate(alpha = 40, time = 25) - -/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original, _strength, _source, _half_life, _can_contaminate) - if(!i_am_original) - return - if(!hl3_release_date) // Permanently radioactive things don't get to grow stronger - return - if(C) - var/datum/component/radioactive/other = C - strength = max(strength, other.strength) - else - strength = max(strength, _strength) - -/datum/component/radioactive/proc/rad_examine(datum/source, mob/user, list/out) - SIGNAL_HANDLER - - var/atom/master = parent - - var/list/fragments = list() - if(get_dist(master, user) <= 1) - fragments += "The air around [master] feels warm" - switch(strength) - if(0 to RAD_AMOUNT_LOW) - if(length(fragments)) - fragments += "." - if(RAD_AMOUNT_LOW to RAD_AMOUNT_MEDIUM) - fragments += "[length(fragments) ? " and [master.p_they()] " : "[master] "]feel[master.p_s()] weird to look at." - if(RAD_AMOUNT_MEDIUM to RAD_AMOUNT_HIGH) - fragments += "[length(fragments) ? " and [master.p_they()] " : "[master] "]seem[master.p_s()] to be glowing a bit." - if(RAD_AMOUNT_HIGH to INFINITY) //At this level the object can contaminate other objects - fragments += "[length(fragments) ? " and [master.p_they()] " : "[master] "]hurt[master.p_s()] to look at." - - if(length(fragments)) - out += "[fragments.Join()]" - -/datum/component/radioactive/proc/rad_attack(datum/source, atom/movable/target, mob/living/user) - SIGNAL_HANDLER - - radiation_pulse(parent, strength / 20) - target.rad_act(strength / 2) - if(!hl3_release_date) - return - strength -= strength / hl3_release_date - -/datum/component/radioactive/proc/admin_decontaminate() - SIGNAL_HANDLER - . = TRUE - if(ismob(parent)) - var/mob/M = parent - M.radiation = 0 - if(ismob(source)) - var/mob/M = source - M.radiation = 0 - qdel(src) - -#undef RAD_AMOUNT_LOW -#undef RAD_AMOUNT_MEDIUM -#undef RAD_AMOUNT_HIGH -#undef RAD_AMOUNT_EXTREME diff --git a/code/datums/components/shelved.dm b/code/datums/components/shelved.dm deleted file mode 100644 index 3aa678d2efed7..0000000000000 --- a/code/datums/components/shelved.dm +++ /dev/null @@ -1,296 +0,0 @@ -#define MAX_SHELF_ITEMS 6 - -/datum/component/shelver - /// A list whose keys are a 4-tuple of (left, bottom, right, top) bounding boxes to position details. - /// Position details include "x" and "y" as pixel offsets, and "layer" as appearance layer for a placed object. - var/list/placement_zones = list() - /// A list of slots, one per placement zone. Either empty, or containing the UID of the object in that place. - var/list/used_places = list() - /// A list of types which are are valid to place on this shelf. - var/list/allowed_types = list() - /// The default scale transformation for objects placed on the shelf. - var/default_scale = 0.70 - /// The default rotation transformation for objects placed on the shelf. - var/default_rotation = 0 - /// Whether objects auto-shelved by the component are placed in random order on the shelf. - var/random_pickup_locations = FALSE - -/datum/component/shelver/Initialize(list/allowed_types_ = null, random_pickup_locations_ = FALSE) - if(!isstructure(parent)) - return COMPONENT_INCOMPATIBLE - used_places.len = length(placement_zones) - if(length(allowed_types_)) - allowed_types += allowed_types_ - random_pickup_locations = random_pickup_locations_ - -/datum/component/shelver/RegisterWithParent() - RegisterSignal(parent, COMSIG_SHELF_ATTEMPT_PICKUP, PROC_REF(on_shelf_attempt_pickup)) - RegisterSignal(parent, COMSIG_ATTACK_BY, PROC_REF(on_attackby)) - RegisterSignal(parent, COMSIG_SHELF_ITEM_REMOVED, PROC_REF(on_shelf_item_removed)) - RegisterSignal(parent, COMSIG_SHELF_ADDED_ON_MAPLOAD, PROC_REF(prepare_autoshelf)) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine)) - -/datum/component/shelver/proc/on_examine(datum/source, mob/user, list/examine_list) - SIGNAL_HANDLER // COMSIG_PARENT_EXAMINE - var/list/results = list() - for(var/uid in used_places) - if(uid) - var/obj/item/I = locateUID(uid) - if(istype(I)) - results += "\a [I.name]" - - if(!length(results)) - return - - var/joined_results = english_list(results) - examine_list += "It currently holds: [joined_results]." - -/datum/component/shelver/proc/prepare_autoshelf() - SIGNAL_HANDLER // COMSIG_SHELF_ADDED_ON_MAPLOAD - - // See /obj/structure/closet/Initialize for explanation of - // addtimer use here - addtimer(CALLBACK(src, PROC_REF(shelf_items)), 0) - -/datum/component/shelver/proc/shelf_items() - var/obj/structure/structure_parent = parent - - var/list/nearby_empty_tiles = list() - for(var/turf/turf_in_view in view(2, get_turf(structure_parent))) - if(!isfloorturf(turf_in_view)) - continue - for(var/turf/potential_blockage as anything in get_line(get_turf(structure_parent), turf_in_view)) - if(!is_blocked_turf(potential_blockage, exclude_mobs = TRUE, excluded_objs = list(parent))) - nearby_empty_tiles += turf_in_view - - var/itemcount = 1 - for(var/obj/item/I in structure_parent.loc) - if(I.density || I.anchored || I == structure_parent) - continue - if(itemcount > MAX_SHELF_ITEMS) - // If we can't fit it on the shelf, toss it somewhere nearby - if(length(nearby_empty_tiles)) - var/turf/T = pick(nearby_empty_tiles) - I.pixel_x = 0 - I.pixel_y = 0 - I.forceMove(T) - if(!(SEND_SIGNAL(structure_parent, COMSIG_SHELF_ATTEMPT_PICKUP, I) & SHELF_PICKUP_FAILURE)) - itemcount++ - -/datum/component/shelver/proc/on_shelf_attempt_pickup(datum/source, obj/item/to_add) - SIGNAL_HANDLER // COMSIG_SHELF_ATTEMPT_PICKUP - - if(!istype(to_add)) - return SHELF_PICKUP_FAILURE - - var/free_slot = get_free_slot() - if(!free_slot) - return SHELF_PICKUP_FAILURE - - var/coords = placement_zones[free_slot] - var/position_details = placement_zones[coords] - add_item(to_add, free_slot, position_details) - -/datum/component/shelver/proc/get_free_slot() - var/list/free_slots = list() - for(var/i in 1 to length(used_places)) - if(!used_places[i]) - free_slots += i - - if(!length(free_slots)) - return - - if(random_pickup_locations) - return pick(free_slots) - - return free_slots[1] - -/datum/component/shelver/proc/on_shelf_item_removed(datum/source, uid) - SIGNAL_HANDLER // COMSIG_SHELF_ITEM_REMOVED - - for(var/i in 1 to length(used_places)) - if(used_places[i] == uid) - used_places[i] = null - - var/obj/O = parent - if(istype(O)) - O.update_appearance(UPDATE_ICON) - -/datum/component/shelver/proc/on_attackby(datum/source, obj/item/attacker, mob/user, params) - SIGNAL_HANDLER // COMSIG_ATTACK_BY - - if(isrobot(user)) - return COMPONENT_SKIP_AFTERATTACK - if(attacker.flags & ABSTRACT) - return COMPONENT_SKIP_AFTERATTACK - if(user.a_intent == INTENT_HARM) - return - - if(length(allowed_types) && !(attacker.type in allowed_types)) - to_chat(user, "[attacker] won't fit on [parent]!") - return COMPONENT_SKIP_AFTERATTACK - - var/list/PL = params2list(params) - var/icon_x = text2num(PL["icon-x"]) - var/icon_y = text2num(PL["icon-y"]) - - var/i = 0 - for(var/coords in placement_zones) - i++ - if(icon_x >= coords[1] && icon_x <= coords[3] && icon_y >= coords[2] && icon_y <= coords[4]) - if(used_places[i]) - to_chat(user, "There's already something there on [parent].") - return COMPONENT_SKIP_AFTERATTACK - - var/position_details = placement_zones[coords] - if(user.drop_item()) - add_item(attacker, i, position_details) - user.visible_message( - "[user] places [attacker] on [parent].", - "You place [attacker] on [parent].", - ) - return COMPONENT_SKIP_AFTERATTACK - -/** - * Add an item to the shelf. - * - * Arguments: - * * to_add - The item to add. Adding will fail if not an `/obj/item`. - * * placement_idx - The slot on the shelf to add the item to. - * * position_details - A list containing the "x" and "y" pixel offsets of the position, and the "layer" the object will be set to, if applicable. - */ -/datum/component/shelver/proc/add_item(obj/item/to_add, placement_idx, list/position_details) - if(!istype(to_add)) - return - to_add.forceMove(get_turf(parent)) - to_add.AddComponent(/datum/component/shelved, parent) - to_add.pixel_x = position_details["x"] - to_add.pixel_y = position_details["y"] - to_add.appearance_flags |= PIXEL_SCALE - if("layer" in position_details) - to_add.layer = position_details["layer"] - used_places[placement_idx] = to_add.UID() - var/obj/O = parent - if(istype(O)) - O.update_appearance(UPDATE_ICON) - - if(default_scale) - to_add.transform *= default_scale - if(default_rotation) - to_add.transform = turn(to_add.transform, default_rotation) - - SEND_SIGNAL(to_add, COMSIG_SHELF_ITEM_ADDED, default_scale) - -/datum/component/shelver/basic_shelf - placement_zones = list( - // Bottom Shelf - list(1, 1, 10, 16) = list("x" = -9, "y" = -5, "layer" = BELOW_OBJ_LAYER), - list(11, 1, 20, 16) = list("x" = 0, "y" = -5, "layer" = BELOW_OBJ_LAYER), - list(21, 1, 32, 16) = list("x" = 9, "y" = -5, "layer" = BELOW_OBJ_LAYER), - - // Top Shelf - list(1, 17, 10, 32) = list("x" = -9, "y" = 9), - list(11, 17, 20, 32) = list("x" = 0, "y" = 9), - list(21, 17, 32, 32) = list("x" = 9, "y" = 9), - ) - -/datum/component/shelver/gun_rack - placement_zones = list( - list(1, 1, 10, 32) = list("x" = -8, "y" = -1), - list(11, 1, 20, 32) = list("x" = 0, "y" = -1), - list(21, 1, 32, 32) = list("x" = 8, "y" = -1), - ) - default_scale = 0.80 - default_rotation = -90 - -/// A component for items stored on shelves, propagated by [/datum/component/shelver] components. -/datum/component/shelved - /// The UID of the object acting as the shelf - var/shelf_uid - /// A copy of the shelved object's original transform, to restore after removing from the shelf. - var/matrix/original_transform - /// A copy of the shelved object's original layer, to restore after removing from the shelf. - var/original_layer - /// A copy of the shelved object's original appearance flags, to restore after removing from the shelf. - var/original_appearance_flags - -/datum/component/shelved/Initialize(atom/shelf) - if(!isobj(parent)) - return COMPONENT_INCOMPATIBLE - var/obj/O = parent - - shelf_uid = shelf.UID() - original_transform = O.transform - original_layer = O.layer - original_appearance_flags = O.appearance_flags - -/datum/component/shelved/RegisterWithParent() - . = ..() - RegisterSignal(parent, COMSIG_ITEM_PICKUP, PROC_REF(on_item_pickup)) - RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_movable_moved)) - var/obj/shelf = locateUID(shelf_uid) - if(shelf) - RegisterSignal(shelf, COMSIG_MOVABLE_SHOVE_IMPACT, PROC_REF(on_movable_shove_impact)) - RegisterSignal(shelf, COMSIG_ATOM_HITBY, PROC_REF(on_atom_hitby)) - RegisterSignal(shelf, COMSIG_OBJ_DECONSTRUCT, PROC_REF(on_shelf_deconstruct)) - -/datum/component/shelved/proc/on_shelf_deconstruct() - SIGNAL_HANDLER // COMSIG_OBJ_DECONSTRUCT - qdel(src) - -/datum/component/shelved/proc/on_item_pickup(obj/item/I, mob/user) - SIGNAL_HANDLER // COMSIG_ITEM_PICKUP - qdel(src) - -/// Generic handler for if anything moves us off our original shelf position, such as atmos pressure. -/datum/component/shelved/proc/on_movable_moved() - SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED - qdel(src) - -/datum/component/shelved/UnregisterFromParent() - . = ..() - var/obj/O = parent - O.transform = original_transform - O.layer = original_layer - O.appearance_flags = original_appearance_flags - O.pixel_x = 0 - O.pixel_y = 0 - - var/obj/shelf = locateUID(shelf_uid) - if(istype(shelf)) - UnregisterSignal(shelf, COMSIG_MOVABLE_SHOVE_IMPACT) - UnregisterSignal(shelf, COMSIG_ATOM_HITBY) - - SEND_SIGNAL(shelf, COMSIG_SHELF_ITEM_REMOVED, parent.UID()) - -/datum/component/shelved/proc/scatter() - var/list/clear_turfs = list() - var/obj/O = parent - for(var/turf/T in orange(1, get_turf(O))) - if(isfloorturf(T) && T != get_turf(O)) - clear_turfs |= T - - if(length(clear_turfs)) - var/obj/shelf = locateUID(shelf_uid) - if(!isobj(shelf)) - // not sure what else we can do here to clean up after ourselves - CRASH("received non-obj shelf with UID [shelf_uid]") - - var/shelf_name = shelf ? "flies off [shelf]" : "falls down" - O.visible_message("[O] [shelf_name]!") - O.throw_at(pick(clear_turfs), 2, 3) - qdel(src) - -/datum/component/shelved/proc/on_movable_shove_impact(datum/source, atom/movable/target) - SIGNAL_HANDLER // COMSIG_MOVABLE_SHOVE_IMPACT - if(prob(50)) - scatter() - -/datum/component/shelved/proc/on_atom_hitby(datum/source, mob/living/carbon/human/hitby) - SIGNAL_HANDLER // COMSIG_ATOM_HITBY - if(!istype(hitby)) - return - if(prob(50)) - scatter() - -#undef MAX_SHELF_ITEMS diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm deleted file mode 100644 index 50f7d817f444a..0000000000000 --- a/code/datums/components/slippery.dm +++ /dev/null @@ -1,69 +0,0 @@ -/** - * # Slip Component - * - * This is a component that can be applied to any movable atom (mob or obj). - * - * While the atom has this component, any human mob that walks over it will have a chance to slip. - * Duration, tiles moved, and so on, depend on what variables are passed in when the component is added. - * - */ -/datum/component/slippery - /// Text that gets displayed in the slip proc, i.e. "user slips on [description]" - var/description - /// The amount of knockdown to apply after slip. - var/knockdown - /// The chance that walking over the parent will slip you. - var/slip_chance - /// The amount of tiles someone will be moved after slip. - var/slip_tiles - /// TRUE If this slip can be avoided by walking. - var/walking_is_safe - /// FALSE if you want no slip shoes to make you immune to the slip - var/slip_always - /// The verb that players will see when someone slips on the parent. In the form of "You [slip_verb]ped on". - var/slip_verb - /// TRUE the player will only slip if the mob this datum is attached to is horizontal - var/horizontal_required - ///what we give to connect_loc by default, makes slippable mobs moving over us slip - var/static/list/default_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(slip), - ) - -/datum/component/slippery/Initialize(_description, _knockdown = 0, _slip_chance = 100, _slip_tiles = 0, _walking_is_safe = TRUE, _slip_always = FALSE, _slip_verb = "slip", _horizontal_required = FALSE) - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - - description = _description - knockdown = max(0, _knockdown) - slip_chance = max(0, _slip_chance) - slip_tiles = max(0, _slip_tiles) - walking_is_safe = _walking_is_safe - slip_always = _slip_always - slip_verb = _slip_verb - horizontal_required = _horizontal_required - - add_connect_loc_behalf_to_parent() - -/datum/component/slippery/proc/add_connect_loc_behalf_to_parent() - if(ismovable(parent)) - AddComponent(/datum/component/connect_loc_behalf, parent, default_connections) - -/** - Called whenever the parent receives the `ATOM_ENTERED` signal. - - Calls the `victim`'s `slip()` proc with the component's variables as arguments. - Additionally calls the parent's `after_slip()` proc on the `victim`. -*/ -/datum/component/slippery/proc/slip(datum/source, mob/living/carbon/human/victim) - SIGNAL_HANDLER // COMSIG_ATOM_ENTERED - - if(istype(victim) && !HAS_TRAIT(victim, TRAIT_FLYING)) - var/atom/movable/owner = parent - if(!isturf(owner.loc)) - return - if(isliving(owner)) - var/mob/living/mob_owner = owner - if(horizontal_required && !IS_HORIZONTAL(mob_owner)) - return - if(prob(slip_chance) && victim.slip(description, knockdown, slip_tiles, walking_is_safe, slip_always, slip_verb)) - owner.after_slip(victim) diff --git a/code/datums/components/spawner.dm b/code/datums/components/spawner.dm deleted file mode 100644 index eb845a9aba636..0000000000000 --- a/code/datums/components/spawner.dm +++ /dev/null @@ -1,66 +0,0 @@ -/datum/component/spawner - var/mob_types = list(/mob/living/simple_animal/hostile/carp) - var/spawn_time = 300 //30 seconds default - var/list/spawned_mobs = list() - var/spawn_delay = 0 - var/max_mobs = 5 - var/spawn_text = "emerges from" - var/list/faction = list("mining") - - COOLDOWN_DECLARE(last_rally) - - -/datum/component/spawner/Initialize(_mob_types, _spawn_time, _faction, _spawn_text, _max_mobs) - if(_spawn_time) - spawn_time=_spawn_time - if(_mob_types) - mob_types=_mob_types - if(_faction) - faction=_faction - if(_spawn_text) - spawn_text=_spawn_text - if(_max_mobs) - max_mobs=_max_mobs - - RegisterSignal(parent, list(COMSIG_PARENT_QDELETING), PROC_REF(stop_spawning)) - RegisterSignal(parent, COMSIG_SPAWNER_SET_TARGET, PROC_REF(rally_spawned_mobs)) - START_PROCESSING(SSprocessing, src) - -/datum/component/spawner/process() - try_spawn_mob() - - -/datum/component/spawner/proc/stop_spawning(force) - STOP_PROCESSING(SSprocessing, src) - for(var/mob/living/simple_animal/L in spawned_mobs) - if(L.nest == src) - L.nest = null - spawned_mobs = null - -/datum/component/spawner/proc/try_spawn_mob() - var/atom/P = parent - if(length(spawned_mobs) >= max_mobs) - return 0 - if(spawn_delay > world.time) - return 0 - spawn_delay = world.time + spawn_time - var/chosen_mob_type = pick(mob_types) - var/mob/living/simple_animal/L = new chosen_mob_type(P.loc) - L.admin_spawned = P.admin_spawned - spawned_mobs += L - L.nest = src - L.faction = src.faction - P.visible_message("[L] [spawn_text] [P].") - P.on_mob_spawn(L) - -/datum/component/spawner/proc/rally_spawned_mobs(parent, mob/living/target) - SIGNAL_HANDLER // COMSIG_SPAWNER_SET_TARGET - - if(!(COOLDOWN_FINISHED(src, last_rally) && length(spawned_mobs))) - return - - // start the cooldown first, because a rallied mob might fire on - // ourselves while this is happening, causing confusion - COOLDOWN_START(src, last_rally, 30 SECONDS) - for(var/mob/living/simple_animal/hostile/rallied as anything in spawned_mobs) - INVOKE_ASYNC(rallied, TYPE_PROC_REF(/mob/living/simple_animal/hostile, aggro_fast), target) diff --git a/code/datums/components/spooky.dm b/code/datums/components/spooky.dm deleted file mode 100644 index 3ec7ab5bbe68e..0000000000000 --- a/code/datums/components/spooky.dm +++ /dev/null @@ -1,58 +0,0 @@ -/datum/component/spooky - var/too_spooky = TRUE //will it spawn a new instrument? - -/datum/component/spooky/Initialize() - RegisterSignal(parent, COMSIG_ATTACK, PROC_REF(spectral_attack)) - -/datum/component/spooky/proc/spectral_attack(datum/source, mob/living/carbon/C, mob/user) - if(ishuman(user)) //this weapon wasn't meant for mortals. - var/mob/living/carbon/human/U = user - if(!istype(U.dna.species, /datum/species/skeleton)) - U.apply_damage(35, STAMINA) //Extra Damage - U.Jitter(70 SECONDS) - U.SetStuttering(40 SECONDS) - if(U.getStaminaLoss() > 95) - to_chat(U, "Your ears weren't meant for this spectral sound.") - spectral_change(U) - return - - if(ishuman(C)) - var/mob/living/carbon/human/H = C - if(istype(H.dna.species, /datum/species/skeleton)) - return //undeads are unaffected by the spook-pocalypse. - C.Jitter(70 SECONDS) - C.SetStuttering(40 SECONDS) - if(!istype(H.dna.species, /datum/species/diona) && !istype(H.dna.species, /datum/species/machine) && !istype(H.dna.species, /datum/species/slime) && !istype(H.dna.species, /datum/species/golem) && !istype(H.dna.species, /datum/species/plasmaman)) - C.apply_damage(25, STAMINA) //boneless humanoids don't lose the will to live - to_chat(C, "DOOT") - spectral_change(H) - - else //the sound will spook monkeys. - C.Jitter(30 SECONDS) - C.SetStuttering(40 SECONDS) - -/datum/component/spooky/proc/spectral_change(mob/living/carbon/human/H, mob/user) - if((H.getStaminaLoss() > 95) && (!istype(H.dna.species, /datum/species/diona) && !istype(H.dna.species, /datum/species/machine) && !istype(H.dna.species, /datum/species/slime) && !istype(H.dna.species, /datum/species/golem) && !istype(H.dna.species, /datum/species/plasmaman) && !istype(H.dna.species, /datum/species/skeleton))) - H.Stun(40 SECONDS) - H.set_species(/datum/species/skeleton) // Makes the OP skelly - H.visible_message("[H] has given up on life as a mortal.") - var/T = get_turf(H) - if(too_spooky) - if(prob(30)) - new/obj/item/instrument/saxophone/spectral(T) - else if(prob(30)) - new/obj/item/instrument/trumpet/spectral(T) - else if(prob(30)) - new/obj/item/instrument/trombone/spectral(T) - else - to_chat(H, "The spooky gods forgot to ship your instrument. Better luck next unlife.") - to_chat(H, "You are the spooky skeleton!") - to_chat(H, "A new life and identity has begun. Help your fellow skeletons into bringing out the spooky-pocalypse. You haven't forgotten your past life, and are still beholden to past loyalties.") - change_name(H) //time for a new name! - -/datum/component/spooky/proc/change_name(mob/living/carbon/human/H) - var/t = tgui_input_text(H, "Enter your new skeleton name", H.real_name, max_length = MAX_NAME_LEN) - if(!t) - t = "spooky skeleton" - H.real_name = t - H.name = t diff --git a/code/datums/components/squeak.dm b/code/datums/components/squeak.dm deleted file mode 100644 index 0583c1f8a4f20..0000000000000 --- a/code/datums/components/squeak.dm +++ /dev/null @@ -1,129 +0,0 @@ -/datum/component/squeak - var/static/list/default_squeak_sounds = list('sound/items/toysqueak1.ogg'=1, 'sound/items/toysqueak2.ogg'=1, 'sound/items/toysqueak3.ogg'=1) - var/list/override_squeak_sounds - var/squeak_chance = 100 - var/volume = 30 - - // This is so shoes don't squeak every step - var/steps = 0 - var/step_delay = 1 - - // This is to stop squeak spam from inhand usage - var/last_use = 0 - var/use_delay = 20 - - ///extra-range for this component's sound - var/sound_extra_range = -1 - ///when sounds start falling off for the squeak - var/sound_falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE - ///sound exponent for squeak. Defaults to 10 as squeaking is loud and annoying enough. - var/sound_falloff_exponent = 10 - - ///what we set connect_loc to if parent is an item - var/static/list/item_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - - -/datum/component/squeak/Initialize(custom_sounds, volume_override, chance_override, step_delay_override, use_delay_override, squeak_on_move, extrarange, falloff_exponent, fallof_distance) - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_ATTACK_BY), PROC_REF(play_squeak)) - if(ismovable(parent)) - RegisterSignal(parent, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT), PROC_REF(play_squeak)) - - AddComponent(/datum/component/connect_loc_behalf, parent, item_connections) - RegisterSignal(parent, COMSIG_MOVABLE_DISPOSING, PROC_REF(disposing_react)) - if(squeak_on_move) - RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(play_squeak)) - if(isitem(parent)) - RegisterSignal(parent, list(COMSIG_ATTACK, COMSIG_ATTACK_OBJ, COMSIG_ITEM_HIT_REACT), PROC_REF(play_squeak)) - RegisterSignal(parent, COMSIG_ACTIVATE_SELF, PROC_REF(use_squeak)) - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip)) - RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_drop)) - if(istype(parent, /obj/item/clothing/shoes)) - RegisterSignal(parent, COMSIG_SHOES_STEP_ACTION, PROC_REF(step_squeak)) - - override_squeak_sounds = custom_sounds - if(chance_override) - squeak_chance = chance_override - if(volume_override) - volume = volume_override - if(isnum(step_delay_override)) - step_delay = step_delay_override - if(isnum(use_delay_override)) - use_delay = use_delay_override - if(isnum(extrarange)) - sound_extra_range = extrarange - if(isnum(falloff_exponent)) - sound_falloff_exponent = falloff_exponent - if(isnum(fallof_distance)) - sound_falloff_distance = fallof_distance - -/datum/component/squeak/proc/play_squeak() - if(ismob(parent)) - var/mob/M = parent - if(M.stat == DEAD) - return - if(prob(squeak_chance)) - if(!override_squeak_sounds) - playsound(parent, pickweight(default_squeak_sounds), volume, TRUE, sound_extra_range, sound_falloff_exponent, falloff_distance = sound_falloff_distance) - else - playsound(parent, pickweight(override_squeak_sounds), volume, TRUE, sound_extra_range, sound_falloff_exponent, falloff_distance = sound_falloff_distance) - -/datum/component/squeak/proc/step_squeak() - if(steps > step_delay) - play_squeak() - steps = 0 - else - steps++ - -/datum/component/squeak/proc/on_atom_entered(datum/source, atom/movable/entered) - if(istype(entered, /obj/effect)) - return - if(ismob(entered)) - var/mob/M = entered - if(HAS_TRAIT(M, TRAIT_FLYING)) - return - if(isliving(entered)) - var/mob/living/L = M - if(L.floating) - return - else if(isitem(entered)) - var/obj/item/I = source - if(I.flags & ABSTRACT) - return - if(isprojectile(entered)) - var/obj/item/projectile/P = entered - if(P.original != parent) - return - if(ismob(source)) - var/mob/M = source - if(HAS_TRAIT(M, TRAIT_FLYING)) - return - if(isliving(source)) - var/mob/living/L = M - if(L.floating) - return - play_squeak() - -/datum/component/squeak/proc/use_squeak() - if(last_use + use_delay < world.time) - last_use = world.time - play_squeak() - -/datum/component/squeak/proc/on_equip(datum/source, mob/equipper, slot) - RegisterSignal(equipper, COMSIG_MOVABLE_DISPOSING, PROC_REF(disposing_react), TRUE) - -/datum/component/squeak/proc/on_drop(datum/source, mob/user) - UnregisterSignal(user, COMSIG_MOVABLE_DISPOSING) - -// Disposal pipes related shit -/datum/component/squeak/proc/disposing_react(datum/source, obj/structure/disposalholder/disposal_holder, obj/machinery/disposal/disposal_source) - //We don't need to worry about unregistering this signal as it will happen for us automaticaly when the holder is qdeleted - RegisterSignal(disposal_holder, COMSIG_ATOM_DIR_CHANGE, PROC_REF(holder_dir_change)) - -/datum/component/squeak/proc/holder_dir_change(datum/source, old_dir, new_dir) - //If the dir changes it means we're going through a bend in the pipes, let's pretend we bumped the wall - if(old_dir != new_dir) - play_squeak() diff --git a/code/datums/components/sticky.dm b/code/datums/components/sticky.dm deleted file mode 100644 index dcfeed36aa35e..0000000000000 --- a/code/datums/components/sticky.dm +++ /dev/null @@ -1,153 +0,0 @@ -// kinda like duct tape but not shit (just kidding, its shit but in a different way) -/datum/component/sticky - /// The atom we are stickied to - var/atom/attached_to - /// Our priority overlay put on top of attached_to - var/icon/overlay - /// Do we drop on attached_to's destroy? If not, we qdel - var/drop_on_attached_destroy = FALSE - -/datum/component/sticky/Initialize(_drop_on_attached_destroy = FALSE) - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - - drop_on_attached_destroy = _drop_on_attached_destroy - -/datum/component/sticky/Destroy(force, silent) - // we dont want the falling off visible message if this component is getting destroyed because parent is getting destroyed - if(attached_to) - if(!QDELETED(parent) && isitem(parent)) - var/obj/item/I = parent - I.visible_message("[parent] falls off of [attached_to].") - pick_up(parent) - - move_to_the_thing(parent, get_turf(parent)) - return ..() - -/datum/component/sticky/RegisterWithParent() - RegisterSignal(parent, COMSIG_PRE_ATTACK, PROC_REF(stick_to_it)) - RegisterSignal(parent, COMSIG_MOVABLE_IMPACT, PROC_REF(stick_to_it_throwing)) - -/datum/component/sticky/UnregisterFromParent() - UnregisterSignal(parent, COMSIG_PRE_ATTACK) - UnregisterSignal(parent, COMSIG_MOVABLE_IMPACT) - -/datum/component/sticky/proc/stick_to_it(obj/item/I, atom/target, mob/user, params) - SIGNAL_HANDLER - if(!in_range(I, target)) - return - if(isstorage(target)) - var/obj/item/storage/S = target - if(S.can_be_inserted(parent)) - return - if(target.GetComponent(/datum/component/sticky)) - return - if(!user.canUnEquip(I)) - return - - INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, drop_item_to_ground), I) - - var/list/click_params = params2list(params) - //Center the icon where the user clicked. - if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) - return - - attached_to = target - move_to_the_thing(parent) - if(user) - to_chat(user, "You attach [parent] to [attached_to].") - - overlay = icon(I.icon, I.icon_state) - //Clamp it so that the icon never moves more than 16 pixels in either direction - overlay.Shift(EAST, clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2)) - overlay.Shift(NORTH, clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2)) - - attach_signals(I) - return COMPONENT_CANCEL_ATTACK_CHAIN - -/datum/component/sticky/proc/stick_to_it_throwing(obj/item/thrown_item, atom/hit_target, throwingdatum, params) - SIGNAL_HANDLER - if(hit_target.GetComponent(/datum/component/sticky)) - return - - attached_to = hit_target - move_to_the_thing(parent) - - overlay = icon(thrown_item.icon, thrown_item.icon_state) - attach_signals(thrown_item) - -/datum/component/sticky/proc/attach_signals(obj/item/attached) - attached_to.add_overlay(overlay, priority = TRUE) - attached.invisibility = INVISIBILITY_ABSTRACT - - RegisterSignal(attached_to, COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY, PROC_REF(pick_up)) - RegisterSignal(attached_to, COMSIG_PARENT_EXAMINE, PROC_REF(add_sticky_text)) - RegisterSignal(attached_to, COMSIG_PARENT_QDELETING, PROC_REF(on_attached_destroy)) - if(ismovable(attached_to)) - RegisterSignal(attached_to, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) - START_PROCESSING(SSobj, src) - -/datum/component/sticky/proc/pick_up(atom/A, mob/living/carbon/human/user) - SIGNAL_HANDLER - if(!attached_to) - CRASH("/datum/component/sticky/proc/pick_up was called, but without an attached atom") - if(user && user.a_intent != INTENT_GRAB) - return - if(user && user.get_active_hand()) - return - attached_to.cut_overlay(overlay, priority = TRUE) - - var/obj/item/I = parent - I.pixel_x = initial(I.pixel_x) - I.pixel_y = initial(I.pixel_y) - move_to_the_thing(parent) - if(user) - INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, put_in_hands), I) - to_chat(user, "You take [parent] off of [attached_to].") - - - I.invisibility = initial(I.invisibility) - UnregisterSignal(attached_to, list(COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY, COMSIG_PARENT_EXAMINE, COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED)) - STOP_PROCESSING(SSobj, src) - attached_to = null - return COMPONENT_CANCEL_ATTACK_CHAIN - -/datum/component/sticky/proc/add_sticky_text(datum/source, mob/user, list/examine_list) - SIGNAL_HANDLER - if(!in_range(user, attached_to)) - return - examine_list += "There is [parent] attached to [source], grab [attached_to.p_them()] to remove it." - -/datum/component/sticky/proc/on_move(datum/source, oldloc, move_dir) - SIGNAL_HANDLER - if(!attached_to) - CRASH("/datum/component/sticky/proc/on_move was called, but without an attached atom") - move_to_the_thing(parent) - -/datum/component/sticky/process() // because sometimes the item can move inside something, like a crate - if(!attached_to) - return PROCESS_KILL - move_to_the_thing(parent) - -/datum/component/sticky/proc/on_attached_destroy(datum/source) - SIGNAL_HANDLER - if(!drop_on_attached_destroy) - qdel(parent) - return - - // Cancel out these signals, if they even still exist. Just to be safe - UnregisterSignal(attached_to, list(COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY, COMSIG_PARENT_EXAMINE, COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED)) - - var/turf/T = get_turf(source) - if(!T) - T = get_turf(parent) - move_to_the_thing(parent, T) - -/datum/component/sticky/proc/move_to_the_thing(obj/item/I, turf/target) - if(!istype(I)) - return // only items should be able to have the sticky component - if(!target) - target = get_turf(attached_to) - if(!target) - CRASH("/datum/component/sticky/proc/move_to_the_thing was called without a viable target") - INVOKE_ASYNC(I, TYPE_PROC_REF(/atom/movable, forceMove), target) diff --git a/code/datums/components/surgery_initiator.dm b/code/datums/components/surgery_initiator.dm deleted file mode 100644 index 7a7f5966c8975..0000000000000 --- a/code/datums/components/surgery_initiator.dm +++ /dev/null @@ -1,396 +0,0 @@ - -/** - * # Surgery Initiator - * - * Allows an item to start (or prematurely stop) a surgical operation. - */ -/datum/component/surgery_initiator - /// If present, this surgery TYPE will be attempted when the item is used. - /// Useful for things like limb reattachments that don't need a scalpel. - var/datum/surgery/forced_surgery - - /// If true, the initial step will be cancellable by just using the tool again. Should be FALSE for any tool that actually has a first surgery step. - var/can_cancel_before_first = FALSE - - /// If true, can be used with a cautery in the off-hand to cancel a surgery. - var/can_cancel = TRUE - - /// If true, can start surgery on someone while they're standing up. - /// Seeing as how we really don't support this (yet), it's much nicer to selectively enable this if we want it. - var/can_start_on_stander = FALSE - - /// Bitfield for the types of surgeries that this can start. - /// Note that in cases where organs are missing, this will be ignored. - /// Also, note that for anything sharp, SURGERY_INITIATOR_ORGANIC should be set as well. - var/valid_starting_types = SURGERY_INITIATOR_ORGANIC - - /// How effective this is at preventing infections. - /// 0 = preventing nothing, 1 = preventing any infection - var/germ_prevention_quality = 0 - - /// The sound to play when starting surgeries - var/surgery_start_sound = null - - // Replace any other surgery initiator - dupe_type = /datum/component/surgery_initiator - -/** - * Create a new surgery initiating component. - * - * Arguments: - * * forced_surgery - (optional) the surgery that will be started when the parent is used on a mob. - */ -/datum/component/surgery_initiator/Initialize(datum/surgery/forced_surgery) - . = ..() - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - - src.forced_surgery = forced_surgery - -/datum/component/surgery_initiator/RegisterWithParent() - RegisterSignal(parent, COMSIG_ATTACK, PROC_REF(initiate_surgery_moment)) - RegisterSignal(parent, COMSIG_ATOM_UPDATE_SHARPNESS, PROC_REF(on_parent_sharpness_change)) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE_MORE, PROC_REF(on_parent_examine_more)) - -/datum/component/surgery_initiator/UnregisterFromParent() - UnregisterSignal(parent, COMSIG_ATTACK) - UnregisterSignal(parent, COMSIG_ATOM_UPDATE_SHARPNESS) - UnregisterSignal(parent, COMSIG_PARENT_EXAMINE_MORE) - -/datum/component/surgery_initiator/proc/on_parent_examine_more(datum/source, mob/user, list/examine_list) - SIGNAL_HANDLER // COMSIG_PARENT_EXAMINE_MORE - examine_list += "You can use this on someone who is laying down to begin surgery on them." - -/// Keep tabs on the attached item's sharpness. -/// This component gets added in atoms when they're made sharp as well. -/datum/component/surgery_initiator/proc/on_parent_sharpness_change() - SIGNAL_HANDLER // COMSIG_ATOM_UPDATE_SHARPNESS - var/obj/item/P = parent - if(!P.sharp) - UnlinkComponent() - RemoveComponent() - -/// Does the surgery initiation. -/datum/component/surgery_initiator/proc/initiate_surgery_moment(datum/source, atom/target, mob/user) - SIGNAL_HANDLER // COMSIG_ATTACK - if(!isliving(user)) - return - var/mob/living/L = target - if(!user.Adjacent(target)) - return - if(user.a_intent != INTENT_HELP) - return - if(!IS_HORIZONTAL(L) && !can_start_on_stander) - return - if(IS_HORIZONTAL(L) && !on_operable_surface(L)) - return - if(iscarbon(target)) - var/mob/living/carbon/C = target - var/obj/item/organ/external/affected = C.get_organ(user.zone_selected) - if(affected) - if((affected.status & ORGAN_ROBOT) && !(valid_starting_types & SURGERY_INITIATOR_ROBOTIC)) - return - if(!(affected.status & ORGAN_ROBOT) && !(valid_starting_types & SURGERY_INITIATOR_ORGANIC)) - return - - if(L.has_status_effect(STATUS_EFFECT_SUMMONEDGHOST)) - to_chat(user, "You realise that a ghost probably doesn't have any useful organs.") - return //no cult ghost surgery please - INVOKE_ASYNC(src, PROC_REF(do_initiate_surgery_moment), target, user) - // This signal is actually part of the attack chain, so it needs to return true to stop it - return TRUE - -/// Meat and potatoes of starting surgery. -/datum/component/surgery_initiator/proc/do_initiate_surgery_moment(mob/living/target, mob/user) - var/datum/surgery/current_surgery - - // Check if we've already got a surgery on our target zone - for(var/i_one in target.surgeries) - var/datum/surgery/surgeryloop = i_one - if(surgeryloop.location == user.zone_selected) - current_surgery = surgeryloop - break - - if(!isnull(current_surgery) && !current_surgery.step_in_progress) - var/datum/surgery_step/current_step = current_surgery.get_surgery_step() - if(current_step.try_op(user, target, user.zone_selected, parent, current_surgery) == SURGERY_INITIATE_SUCCESS) - return - if(istype(parent, /obj/item/scalpel/laser/manager/debug)) - return - if(attempt_cancel_surgery(current_surgery, target, user)) - return - - if(!isnull(current_surgery) && current_surgery.step_in_progress) - return - - var/list/available_surgeries = get_available_surgeries(user, target) - - var/datum/surgery/procedure - - if(!length(available_surgeries)) - if(IS_HORIZONTAL(target)) - to_chat(user, "There aren't any surgeries you can perform there right now.") - else - to_chat(user, "You can't perform any surgeries there while [target] is standing.") - return - - // if we have a surgery that should be performed regardless with this item, - // make sure it's available to be done - if(forced_surgery) - for(var/datum/surgery/S in available_surgeries) - if(istype(S, forced_surgery)) - procedure = S - break - else - procedure = tgui_input_list(user, "Begin which procedure?", "Surgery", available_surgeries) - - if(!procedure) - return - - if(!on_surgery_selection(user, target, procedure)) - return - - return try_choose_surgery(user, target, procedure) - -/datum/component/surgery_initiator/proc/on_surgery_selection(mob/user, mob/living/target, datum/surgery/target_surgery) - return TRUE - -/datum/component/surgery_initiator/proc/get_available_surgeries(mob/user, mob/living/target) - var/list/available_surgeries = list() - for(var/datum/surgery/surgery in GLOB.surgeries_list) - if(surgery.abstract && !istype(surgery, forced_surgery)) // no choosing abstract surgeries, though they can be forced - continue - if(!is_type_in_list(target, surgery.target_mobtypes)) - continue - if(!target.can_run_surgery(surgery, user)) - continue - - available_surgeries |= surgery - - return available_surgeries - -/datum/component/surgery_initiator/proc/cancel_unstarted_surgery_fluff(datum/surgery/the_surgery, mob/living/patient, mob/user, selected_zone) - user.visible_message( - "[user] stops the surgery on [patient]'s [parse_zone(selected_zone)] with [parent].", - "You stop the surgery on [patient]'s [parse_zone(selected_zone)] with [parent].", - ) - -/// Does the surgery de-initiation. -/datum/component/surgery_initiator/proc/attempt_cancel_surgery(datum/surgery/the_surgery, mob/living/patient, mob/user) - var/selected_zone = user.zone_selected - /// We haven't even started yet. Any surgery can be cancelled at this point. - if(the_surgery.step_number == 1) - patient.surgeries -= the_surgery - cancel_unstarted_surgery_fluff(the_surgery, patient, user, selected_zone) - - qdel(the_surgery) - return TRUE - - if(!the_surgery.can_cancel) - return - - // Don't make a forced surgery implement cancel a surgery. - if(istype(the_surgery, forced_surgery)) - return - - var/obj/item/close_tool - var/obj/item/other_hand = user.get_inactive_hand() - - var/is_robotic = !the_surgery.requires_organic_bodypart - var/datum/surgery_step/chosen_close_step - var/skip_surgery = FALSE // if true, don't even run an operation, just end the surgery. - - if(!the_surgery.requires_bodypart) - // special behavior here; if it doesn't require a bodypart just check if there's a limb there or not. - // this is a little bit gross and I do apologize - if(iscarbon(patient)) - var/mob/living/carbon/C = patient - var/obj/item/organ/external/affected = C.get_organ(user.zone_selected) - if(!affected) - skip_surgery = TRUE - - else - // uh there's no reason this should be hit but let's be safe LOL - skip_surgery = TRUE - - if(!skip_surgery) - if(is_robotic) - chosen_close_step = new /datum/surgery_step/robotics/external/close_hatch/premature() - else - chosen_close_step = new /datum/surgery_step/generic/cauterize/premature() - - if(skip_surgery) - close_tool = user.get_active_hand() // sure, just something so that it isn't null - else if(isrobot(user)) - if(!is_robotic) - // borgs need to be able to finish surgeries with just the laser scalpel, no special checks here. - close_tool = parent - else - close_tool = locate(/obj/item/crowbar) in user.get_all_slots() - if(!close_tool) - to_chat(user, "You need a prying tool in an inactive slot to stop the surgery!") - return TRUE - - else if(other_hand) - for(var/key in chosen_close_step.allowed_tools) - if(ispath(key) && istype(other_hand, key) || other_hand.tool_behaviour == key) - close_tool = other_hand - break - - if(!close_tool) - to_chat(user, "You need a [is_robotic ? "prying": "cauterizing"] tool in your inactive hand to stop the surgery!") - return TRUE - - if(skip_surgery || chosen_close_step.try_op(user, patient, selected_zone, close_tool, the_surgery) == SURGERY_INITIATE_SUCCESS) - // logging in case people wonder why they're cut up inside - log_attack(user, patient, "Prematurely finished \a [the_surgery] surgery.") - qdel(chosen_close_step) - patient.surgeries -= the_surgery - qdel(the_surgery) - - // always return TRUE here so we don't continue the surgery chain and try to start a new surgery with our tool. - return TRUE - -/datum/component/surgery_initiator/proc/can_start_surgery(mob/user, mob/living/target) - if(!user.Adjacent(target)) - return FALSE - - // The item was moved somewhere else - if(!(parent in user)) - to_chat(user, "You cannot start an operation if you aren't holding the tool anymore.") - return FALSE - - // While we were choosing, another surgery was started at the same location - for(var/datum/surgery/surgery in target.surgeries) - if(surgery.location == user.zone_selected) - to_chat(user, "There's already another surgery in progress on their [parse_zone(surgery.location)].") - return FALSE - - return TRUE - -/datum/component/surgery_initiator/proc/try_choose_surgery(mob/user, mob/living/target, datum/surgery/surgery) - if(!can_start_surgery(user, target)) - return - - var/obj/item/organ/affecting_limb - - var/selected_zone = user.zone_selected - - if(iscarbon(target)) - var/mob/living/carbon/carbon_target = target - affecting_limb = carbon_target.get_organ(check_zone(selected_zone)) - - if(surgery.requires_bodypart == isnull(affecting_limb)) - if(surgery.requires_bodypart) - to_chat(user, "The patient has no [parse_zone(selected_zone)]!") - else - to_chat(user, "The patient has \a [parse_zone(selected_zone)]!") - - return - - if(!isnull(affecting_limb) && (surgery.requires_organic_bodypart && affecting_limb.is_robotic()) || (!surgery.requires_organic_bodypart && !affecting_limb.is_robotic())) - to_chat(user, "That's not the right type of limb for this operation!") - return - - if(surgery.lying_required && !on_operable_surface(target)) - to_chat(user, "Patient must be lying down for this operation.") - return - - if(target == user && !surgery.self_operable) - to_chat(user, "You can't perform that operation on yourself!") - return - - if(!surgery.can_start(user, target)) - to_chat(user, "Can't start the surgery!") - return - - if(surgery_needs_exposure(surgery, target)) - to_chat(user, "You have to expose [target.p_their()] [parse_zone(selected_zone)] first!") - return - - var/datum/surgery/procedure = new surgery.type(target, selected_zone, affecting_limb) - - - RegisterSignal(procedure, COMSIG_SURGERY_BLOOD_SPLASH, PROC_REF(on_blood_splash)) - - procedure.germ_prevention_quality = germ_prevention_quality - - show_starting_message(user, target, procedure) - - log_attack(user, target, "operated on (OPERATION TYPE: [procedure.name]) (TARGET AREA: [selected_zone])") - - return procedure - -/datum/component/surgery_initiator/proc/surgery_needs_exposure(datum/surgery/surgery, mob/living/target) - return !surgery.ignore_clothes && !get_location_accessible(target, target.zone_selected) - -/// Handle to allow for easily overriding the message shown -/datum/component/surgery_initiator/proc/show_starting_message(mob/user, mob/living/target, datum/surgery/procedure) - user.visible_message( - "[user] holds [parent] over [target]'s [parse_zone(user.zone_selected)] to prepare for surgery.", - "You hold [parent] over [target]'s [parse_zone(user.zone_selected)] to prepare for \an [procedure.name].", - ) - -/datum/component/surgery_initiator/proc/on_prevent_germs() - SIGNAL_HANDLER // - return - -/datum/component/surgery_initiator/proc/on_blood_splash() - SIGNAL_HANDLER // COMSIG_SURGERY_BLOOD_SPLASH - return - -/datum/component/surgery_initiator/limb - can_cancel = FALSE // don't let a leg cancel a surgery - -/datum/component/surgery_initiator/robo - valid_starting_types = SURGERY_INITIATOR_ROBOTIC - -/datum/component/surgery_initiator/robo/sharp - valid_starting_types = SURGERY_INITIATOR_ORGANIC | SURGERY_INITIATOR_ROBOTIC - -/datum/component/surgery_initiator/cloth - can_cancel = FALSE - surgery_start_sound = "rustle" - -/datum/component/surgery_initiator/cloth/show_starting_message(mob/user, mob/living/target, datum/surgery/procedure) - user.visible_message( - "[user] drapes [parent] over [target]'s [parse_zone(user.zone_selected)] to prepare for surgery.", - "You drape [parent] over [target]'s [parse_zone(user.zone_selected)] to prepare for \an [procedure.name].", - ) - -/datum/component/surgery_initiator/cloth/try_choose_surgery(mob/user, mob/living/target, datum/surgery/surgery) - var/datum/surgery/new_procedure = ..() - if(!istype(new_procedure)) - return - - new_procedure.started_with_drapes = TRUE - -/datum/component/surgery_initiator/cloth/on_surgery_selection(mob/user, mob/living/target, datum/surgery/target_surgery) - user.visible_message( - "[user] starts to apply [parent] onto [target].", - "You start to apply [parent] onto [target].", - ) - - if(!isnull(surgery_start_sound)) - playsound(src, surgery_start_sound, 50, TRUE) - - playsound(src, surgery_start_sound) - if(!do_after_once(user, 3 SECONDS, TRUE, target)) - user.visible_message( - "[user] stops applying [parent] onto [target].", - "You stop applying [parent] onto [target]." - ) - return - - - if(!isnull(surgery_start_sound)) - playsound(src, surgery_start_sound, 50, TRUE) - - return TRUE - -/datum/component/surgery_initiator/cloth/on_blood_splash(datum/surgery, mob/user, mob/target, zone, obj/item/tool) - if(prob(90 * germ_prevention_quality)) - target.visible_message("Blood splashes onto the dressing.") - var/obj/item/I = parent // safety: this component can only go onto an item - I.add_mob_blood(target) - return COMPONENT_BLOOD_SPLASH_HANDLED diff --git a/code/datums/components/swarming.dm b/code/datums/components/swarming.dm deleted file mode 100644 index 608359d49089c..0000000000000 --- a/code/datums/components/swarming.dm +++ /dev/null @@ -1,59 +0,0 @@ -/datum/component/swarming - var/offset_x = 0 - var/offset_y = 0 - var/is_swarming = FALSE - var/list/swarm_members = list() - var/static/list/swarming_loc_connections = list( - COMSIG_ATOM_EXITED = PROC_REF(leave_swarm), - COMSIG_ATOM_ENTERED = PROC_REF(join_swarm) - ) - - -/datum/component/swarming/Initialize(max_x = 24, max_y = 24) - if(!ismovable(parent)) - return COMPONENT_INCOMPATIBLE - offset_x = rand(-max_x, max_x) - offset_y = rand(-max_y, max_y) - - AddComponent(/datum/component/connect_loc_behalf, parent, swarming_loc_connections) - -/datum/component/swarming/Destroy() - for(var/other in swarm_members) - var/datum/component/swarming/other_swarm = other - other_swarm.swarm_members -= src - if(!length(other_swarm.swarm_members)) - other_swarm.unswarm() - swarm_members = null - return ..() - -/datum/component/swarming/proc/join_swarm(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) - var/datum/component/swarming/other_swarm = arrived.GetComponent(/datum/component/swarming) - if(!other_swarm) - return - swarm() - swarm_members |= other_swarm - other_swarm.swarm() - other_swarm.swarm_members |= src - -/datum/component/swarming/proc/leave_swarm(datum/source, atom/movable/gone, direction) - var/datum/component/swarming/other_swarm = gone.GetComponent(/datum/component/swarming) - if(!other_swarm || !(other_swarm in swarm_members)) - return - swarm_members -= other_swarm - if(!length(swarm_members)) - unswarm() - other_swarm.swarm_members -= src - if(!length(other_swarm.swarm_members)) - other_swarm.unswarm() - -/datum/component/swarming/proc/swarm() - var/atom/movable/owner = parent - if(!is_swarming) - is_swarming = TRUE - animate(owner, pixel_x = owner.pixel_x + offset_x, pixel_y = owner.pixel_y + offset_y, time = 2) - -/datum/component/swarming/proc/unswarm() - var/atom/movable/owner = parent - if(is_swarming) - animate(owner, pixel_x = owner.pixel_x - offset_x, pixel_y = owner.pixel_y - offset_y, time = 2) - is_swarming = FALSE diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm deleted file mode 100644 index 06832bfd3a1f2..0000000000000 --- a/code/datums/datacore.dm +++ /dev/null @@ -1,596 +0,0 @@ -/datum/datacore - var/list/medical = list() - var/list/general = list() - var/list/security = list() - //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character(). - var/list/locked = list() - -/* -We can't just insert in HTML into the TGUI so we need the raw data to play with. -Instead of creating this list over and over when someone leaves their PDA open to the page -we'll only update it when it changes. The PDA_Manifest global list is zeroed out upon any change -using /datum/datacore/proc/manifest_inject(), or manifest_insert() -*/ - -GLOBAL_LIST_EMPTY(PDA_Manifest) - -/datum/datacore/proc/get_manifest_json() - if(length(GLOB.PDA_Manifest)) - return - var/heads[0] - var/sec[0] - var/eng[0] - var/med[0] - var/sci[0] - var/ser[0] - var/sup[0] - var/bot[0] - var/misc[0] - for(var/datum/data/record/t in GLOB.data_core.general) - var/name = sanitize(t.fields["name"]) - var/rank = sanitize(t.fields["rank"]) - var/real_rank = t.fields["real_rank"] - - var/isactive = t.fields["p_stat"] - var/department = 0 - var/depthead = 0 // Department Heads will be placed at the top of their lists. - if(real_rank in GLOB.command_positions) - heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - depthead = 1 - if(rank == "Captain" && length(heads) != 1) - heads.Swap(1, length(heads)) - - if(real_rank in GLOB.active_security_positions) - sec[++sec.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && length(sec) != 1) - sec.Swap(1, length(sec)) - - if(real_rank in GLOB.engineering_positions) - eng[++eng.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && length(eng) != 1) - eng.Swap(1, length(eng)) - - if(real_rank in GLOB.medical_positions) - med[++med.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && length(med) != 1) - med.Swap(1, length(med)) - - if(real_rank in GLOB.science_positions) - sci[++sci.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && length(sci) != 1) - sci.Swap(1, length(sci)) - - if(real_rank in GLOB.service_positions) - ser[++ser.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && length(ser) != 1) - ser.Swap(1, length(ser)) - - if(real_rank in GLOB.supply_positions) - sup[++sup.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && length(sup) != 1) - sup.Swap(1, length(sup)) - - if(real_rank in GLOB.nonhuman_positions) - bot[++bot.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - - if(!department && !(name in heads)) - misc[++misc.len] = list("name" = name, "rank" = rank, "active" = isactive) - - - GLOB.PDA_Manifest = list(\ - "heads" = heads,\ - "sec" = sec,\ - "eng" = eng,\ - "med" = med,\ - "sci" = sci,\ - "ser" = ser,\ - "sup" = sup,\ - "bot" = bot,\ - "misc" = misc\ - ) - return - - - -/datum/datacore/proc/manifest() - for(var/mob/living/carbon/human/H in GLOB.player_list) - manifest_inject(H) - -/datum/datacore/proc/manifest_modify(name, assignment) - if(length(GLOB.PDA_Manifest)) - GLOB.PDA_Manifest.Cut() - var/datum/data/record/foundrecord - var/real_title = assignment - - for(var/datum/data/record/t in GLOB.data_core.general) - if(t) - if(t.fields["name"] == name) - foundrecord = t - break - - var/list/all_jobs = get_job_datums() - var/is_custom_job = TRUE - - for(var/datum/job/J in all_jobs) - var/list/alttitles = get_alternate_titles(J.title) - if(J.title == real_title) - is_custom_job = FALSE - if(assignment in alttitles) - real_title = J.title - is_custom_job = FALSE - break - - if(is_custom_job && foundrecord) - real_title = foundrecord.fields["real_rank"] - - if(foundrecord) - foundrecord.fields["rank"] = assignment - foundrecord.fields["real_rank"] = real_title - -GLOBAL_VAR_INIT(record_id_num, 1001) -/datum/datacore/proc/manifest_inject(mob/living/carbon/human/H) - if(length(GLOB.PDA_Manifest)) - GLOB.PDA_Manifest.Cut() - - if(H.mind && (H.mind.assigned_role != H.mind.special_role)) - var/assignment - if(H.mind.role_alt_title) - assignment = H.mind.role_alt_title - else if(H.mind.assigned_role) - assignment = H.mind.assigned_role - else if(H.job) - assignment = H.job - else - assignment = "Unassigned" - GLOB.crew_list[H.real_name] = assignment - - var/id = num2hex(GLOB.record_id_num++, 6) - - - //General Record - var/datum/data/record/G = new() - G.fields["id"] = id - G.fields["name"] = H.real_name - G.fields["real_rank"] = H.mind.assigned_role - G.fields["rank"] = assignment - G.fields["age"] = H.age - G.fields["fingerprint"] = md5(H.dna.uni_identity) - G.fields["p_stat"] = "Active" - G.fields["m_stat"] = "Stable" - G.fields["sex"] = capitalize(H.gender) - G.fields["species"] = H.dna.species.name - // Do some ID card checking stuff here to save on resources - var/card_photo - if(istype(H.wear_id, /obj/item/card/id)) - var/obj/item/card/id/IDC = H.wear_id - card_photo = IDC.photo - else - card_photo = get_id_photo(H) - - G.fields["photo"] = card_photo - G.fields["photo-south"] = "data:image/png;base64,[icon2base64(icon(card_photo, dir = SOUTH))]" - G.fields["photo-west"] = "data:image/png;base64,[icon2base64(icon(card_photo, dir = WEST))]" - if(H.gen_record && !jobban_isbanned(H, ROLEBAN_RECORDS)) - G.fields["notes"] = H.gen_record - else - G.fields["notes"] = "No notes found." - general += G - - //Medical Record - var/datum/data/record/M = new() - M.fields["id"] = id - M.fields["name"] = H.real_name - M.fields["blood_type"] = H.dna.blood_type - M.fields["b_dna"] = H.dna.unique_enzymes - M.fields["mi_dis"] = "None" - M.fields["mi_dis_d"] = "No minor disabilities have been declared." - M.fields["ma_dis"] = "None" - M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." - M.fields["alg"] = "None" - M.fields["alg_d"] = "No allergies have been detected in this patient." - M.fields["cdi"] = "None" - M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." - if(H.med_record && !jobban_isbanned(H, ROLEBAN_RECORDS)) - M.fields["notes"] = H.med_record - else - M.fields["notes"] = "No notes found." - medical += M - - //Security Record - var/datum/data/record/S = new() - S.fields["id"] = id - S.fields["name"] = H.real_name - S.fields["criminal"] = "None" - S.fields["mi_crim"] = "None" - S.fields["mi_crim_d"] = "No minor crime convictions." - S.fields["ma_crim"] = "None" - S.fields["ma_crim_d"] = "No major crime convictions." - S.fields["notes"] = "No notes." - if(H.sec_record && !jobban_isbanned(H, ROLEBAN_RECORDS)) - S.fields["notes"] = H.sec_record - else - S.fields["notes"] = "No notes found." - LAZYINITLIST(S.fields["comments"]) - security += S - - //Locked Record - var/datum/data/record/L = new() - L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") - L.fields["name"] = H.real_name - L.fields["rank"] = H.mind.assigned_role - L.fields["age"] = H.age - L.fields["sex"] = capitalize(H.gender) - L.fields["blood_type"] = H.dna.blood_type - L.fields["b_dna"] = H.dna.unique_enzymes - L.fields["enzymes"] = H.dna.SE // Used in respawning - L.fields["identity"] = H.dna.UI // " - L.fields["image"] = getFlatIcon(H) //This is god-awful - locked += L - return - -/proc/get_id_photo(mob/living/carbon/human/H, custom_job = null) - var/icon/preview_icon = null - var/obj/item/organ/external/head/head_organ = H.get_organ("head") - var/obj/item/organ/internal/eyes/eyes_organ = H.get_int_organ(/obj/item/organ/internal/eyes) - - var/g = "m" - if(H.gender == FEMALE) - g = "f" - - var/icon/icobase = head_organ.icobase //At this point all the organs would have the same icobase, so this is just recycling. - - preview_icon = new /icon(icobase, "torso_[g]") - var/icon/temp - temp = new /icon(icobase, "groin_[g]") - preview_icon.Blend(temp, ICON_OVERLAY) - var/head = "head" - if(head_organ.alt_head && head_organ.dna.species.bodyflags & HAS_ALT_HEADS) - var/datum/sprite_accessory/alt_heads/alternate_head = GLOB.alt_heads_list[head_organ.alt_head] - if(alternate_head.icon_state) - head = alternate_head.icon_state - temp = new /icon(icobase, "[head]_[g]") - preview_icon.Blend(temp, ICON_OVERLAY) - - //Tail - if(H.body_accessory && (istype(H.body_accessory, /datum/body_accessory/tail) || istype(H.body_accessory, /datum/body_accessory/wing))) - temp = new/icon("icon" = H.body_accessory.icon, "icon_state" = H.body_accessory.icon_state) - preview_icon.Blend(temp, ICON_OVERLAY) - else if(H.tail && H.dna.species.bodyflags & HAS_TAIL) - temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[H.tail]_s") - preview_icon.Blend(temp, ICON_OVERLAY) - else if(H.wing && H.dna.species.bodyflags & HAS_WING) - temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[H.wing]_s") - preview_icon.Blend(temp, ICON_OVERLAY) - - for(var/obj/item/organ/external/E in H.bodyparts) - preview_icon.Blend(E.get_icon(), ICON_OVERLAY) - - // Skin tone - if(H.dna.species.bodyflags & HAS_SKIN_TONE) - if(H.s_tone >= 0) - preview_icon.Blend(rgb(H.s_tone, H.s_tone, H.s_tone), ICON_ADD) - else - preview_icon.Blend(rgb(-H.s_tone, -H.s_tone, -H.s_tone), ICON_SUBTRACT) - - // Proper Skin color - Fix, you can't have HAS_SKIN_TONE *and* HAS_SKIN_COLOR - if(H.dna.species.bodyflags & HAS_SKIN_COLOR) - preview_icon.Blend(H.skin_colour, ICON_ADD) - - //Tail Markings - var/icon/t_marking_s - if(H.dna.species.bodyflags & HAS_TAIL_MARKINGS) - var/tail_marking = H.m_styles["tail"] - var/datum/sprite_accessory/tail_marking_style = GLOB.marking_styles_list[tail_marking] - if(tail_marking_style && tail_marking_style.species_allowed) - t_marking_s = new/icon("icon" = tail_marking_style.icon, "icon_state" = "[tail_marking_style.icon_state]_s") - t_marking_s.Blend(H.m_colours["tail"], ICON_ADD) - if(!(H.body_accessory && istype(H.body_accessory, /datum/body_accessory/body))) - preview_icon.Blend(t_marking_s, ICON_OVERLAY) - - var/icon/face_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = "bald_s") - if(!(H.dna.species.bodyflags & NO_EYES)) - var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = H.dna.species ? H.dna.species.eyes : "eyes_s") - if(!eyes_organ) - return - eyes_s.Blend(eyes_organ.eye_color, ICON_ADD) - face_s.Blend(eyes_s, ICON_OVERLAY) - - var/datum/sprite_accessory/hair_style = GLOB.hair_styles_full_list[head_organ.h_style] - if(hair_style) - var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - // I'll want to make a species-specific proc for this sooner or later - // But this'll do for now - if(istype(head_organ.dna.species, /datum/species/slime)) - hair_s.Blend("[H.skin_colour]A0", ICON_AND) //A0 = 160 alpha. - else - hair_s.Blend(head_organ.hair_colour, ICON_ADD) - - if(hair_style.secondary_theme) - var/icon/hair_secondary_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_[hair_style.secondary_theme]_s") - if(!hair_style.no_sec_colour) - hair_secondary_s.Blend(head_organ.sec_hair_colour, ICON_ADD) - hair_s.Blend(hair_secondary_s, ICON_OVERLAY) - - face_s.Blend(hair_s, ICON_OVERLAY) - - //Head Accessory - if(head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY) - var/datum/sprite_accessory/head_accessory_style = GLOB.head_accessory_styles_list[head_organ.ha_style] - if(head_accessory_style && head_accessory_style.species_allowed) - var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") - head_accessory_s.Blend(head_organ.headacc_colour, ICON_ADD) - face_s.Blend(head_accessory_s, ICON_OVERLAY) - - var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[head_organ.f_style] - if(facial_hair_style && facial_hair_style.species_allowed) - var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(istype(head_organ.dna.species, /datum/species/slime)) - facial_s.Blend("[H.skin_colour]A0", ICON_ADD) //A0 = 160 alpha. - else - facial_s.Blend(head_organ.facial_colour, ICON_ADD) - - if(facial_hair_style.secondary_theme) - var/icon/facial_secondary_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_[facial_hair_style.secondary_theme]_s") - if(!facial_hair_style.no_sec_colour) - facial_secondary_s.Blend(head_organ.sec_facial_colour, ICON_ADD) - facial_s.Blend(facial_secondary_s, ICON_OVERLAY) - - face_s.Blend(facial_s, ICON_OVERLAY) - - //Markings - if((H.dna.species.bodyflags & HAS_HEAD_MARKINGS) || (H.dna.species.bodyflags & HAS_BODY_MARKINGS)) - if(H.dna.species.bodyflags & HAS_BODY_MARKINGS) //Body markings. - var/body_marking = H.m_styles["body"] - var/datum/sprite_accessory/body_marking_style = GLOB.marking_styles_list[body_marking] - if(body_marking_style && body_marking_style.species_allowed) - var/icon/b_marking_s = new/icon("icon" = body_marking_style.icon, "icon_state" = "[body_marking_style.icon_state]_s") - b_marking_s.Blend(H.m_colours["body"], ICON_ADD) - face_s.Blend(b_marking_s, ICON_OVERLAY) - if(H.dna.species.bodyflags & HAS_HEAD_MARKINGS) //Head markings. - var/head_marking = H.m_styles["head"] - var/datum/sprite_accessory/head_marking_style = GLOB.marking_styles_list[head_marking] - if(head_marking_style && head_marking_style.species_allowed) - var/icon/h_marking_s = new/icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") - h_marking_s.Blend(H.m_colours["head"], ICON_ADD) - face_s.Blend(h_marking_s, ICON_OVERLAY) - - preview_icon.Blend(face_s, ICON_OVERLAY) - //Underwear - var/icon/underwear_standing = new /icon('icons/mob/clothing/underwear.dmi', "nude") - if(H.underwear && H.dna.species.clothing_flags & HAS_UNDERWEAR) - var/datum/sprite_accessory/underwear/U = GLOB.underwear_list[H.underwear] - if(U) - var/u_icon = U.sprite_sheets && (H.dna.species.sprite_sheet_name in U.sprite_sheets) ? U.sprite_sheets[H.dna.species.sprite_sheet_name] : U.icon //Species-fit the undergarment. - underwear_standing.Blend(new /icon(u_icon, "uw_[U.icon_state]_s"), ICON_OVERLAY) - - if(H.undershirt && H.dna.species.clothing_flags & HAS_UNDERSHIRT) - var/datum/sprite_accessory/undershirt/U2 = GLOB.undershirt_list[H.undershirt] - if(U2) - var/u2_icon = U2.sprite_sheets && (H.dna.species.sprite_sheet_name in U2.sprite_sheets) ? U2.sprite_sheets[H.dna.species.sprite_sheet_name] : U2.icon - underwear_standing.Blend(new /icon(u2_icon, "us_[U2.icon_state]_s"), ICON_OVERLAY) - - if(H.socks && H.dna.species.clothing_flags & HAS_SOCKS) - var/datum/sprite_accessory/socks/U3 = GLOB.socks_list[H.socks] - if(U3) - var/u3_icon = U3.sprite_sheets && (H.dna.species.sprite_sheet_name in U3.sprite_sheets) ? U3.sprite_sheets[H.dna.species.sprite_sheet_name] : U3.icon - underwear_standing.Blend(new /icon(u3_icon, "sk_[U3.icon_state]_s"), ICON_OVERLAY) - - if(underwear_standing) - preview_icon.Blend(underwear_standing, ICON_OVERLAY) - - var/icon/hands_icon = icon(preview_icon) - hands_icon.Blend(icon('icons/mob/clothing/masking_helpers.dmi', "l_hand_mask"), ICON_MULTIPLY) - - var/icon/clothes_s = null - var/job_clothes = null - if(custom_job) - job_clothes = custom_job - else if(H.mind) - job_clothes = H.mind.assigned_role - switch(job_clothes) - if("Head of Personnel") - clothes_s = new /icon('icons/mob/clothing/under/civilian.dmi', "hop_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "brown"), ICON_UNDERLAY) - if("Nanotrasen Representative") - clothes_s = new /icon('icons/mob/clothing/under/centcom.dmi', "officer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "laceups"), ICON_UNDERLAY) - if("Nanotrasen Career Trainer") - clothes_s = new /icon('icons/mob/clothing/under/procedure.dmi', "trainer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "laceups"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "trainercoat"), ICON_OVERLAY) - if("Blueshield") - clothes_s = new /icon('icons/mob/clothing/under/centcom.dmi', "officer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "jackboots"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "blueshield"), ICON_OVERLAY) - if("Magistrate") - clothes_s = new /icon('icons/mob/clothing/under/suit.dmi', "really_black_suit_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "laceups"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "judge"), ICON_OVERLAY) - if("Bartender") - clothes_s = new /icon('icons/mob/clothing/under/civilian.dmi', "ba_suit_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - if("Botanist") - clothes_s = new /icon('icons/mob/clothing/under/civilian.dmi', "hydroponics_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - if("Chef") - clothes_s = new /icon('icons/mob/clothing/under/civilian.dmi', "chef_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - if("Janitor") - clothes_s = new /icon('icons/mob/clothing/under/civilian.dmi', "janitor_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - if("Librarian") - clothes_s = new /icon('icons/mob/clothing/under/civilian.dmi', "red_suit_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - if("Clown") - clothes_s = new /icon('icons/mob/clothing/under/civilian.dmi', "clown_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "clown"), ICON_UNDERLAY) - if("Mime") - clothes_s = new /icon('icons/mob/clothing/under/civilian.dmi', "mime_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - if("Quartermaster") - clothes_s = new /icon('icons/mob/clothing/under/cargo.dmi', "qm_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "brown"), ICON_UNDERLAY) - if("Cargo Technician") - clothes_s = new /icon('icons/mob/clothing/under/cargo.dmi', "cargo_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - if("Shaft Miner") - clothes_s = new /icon('icons/mob/clothing/under/cargo.dmi', "explorer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "explorer"), ICON_UNDERLAY) - if("Internal Affairs Agent") - clothes_s = new /icon('icons/mob/clothing/under/civilian.dmi', "internalaffairs_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "brown"), ICON_UNDERLAY) - if("Chaplain") - clothes_s = new /icon('icons/mob/clothing/under/civilian.dmi', "chapblack_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - if("Research Director") - clothes_s = new /icon('icons/mob/clothing/under/rnd.dmi', "director_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "labcoat_open"), ICON_OVERLAY) - if("Scientist") - clothes_s = new /icon('icons/mob/clothing/under/rnd.dmi', "science_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "labcoat_tox_open"), ICON_OVERLAY) - if("Chemist") - clothes_s = new /icon('icons/mob/clothing/under/medical.dmi', "chemistry_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "labcoat_chem_open"), ICON_OVERLAY) - if("Chief Medical Officer") - clothes_s = new /icon('icons/mob/clothing/under/medical.dmi', "cmo_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "labcoat_cmo_open"), ICON_OVERLAY) - if("Medical Doctor") - clothes_s = new /icon('icons/mob/clothing/under/medical.dmi', "medical_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "labcoat_open"), ICON_OVERLAY) - if("Coroner") - clothes_s = new /icon('icons/mob/clothing/under/medical.dmi', "scrubsblack_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "labcoat_mort_open"), ICON_OVERLAY) - if("Geneticist") - clothes_s = new /icon('icons/mob/clothing/under/rnd.dmi', "genetics_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "labcoat_gen_open"), ICON_OVERLAY) - if("Virologist") - clothes_s = new /icon('icons/mob/clothing/under/medical.dmi', "virology_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "labcoat_vir_open"), ICON_OVERLAY) - if("Psychiatrist") - clothes_s = new /icon('icons/mob/clothing/under/medical.dmi', "psych_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "laceups"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "labcoat_open"), ICON_UNDERLAY) - if("Paramedic") - clothes_s = new /icon('icons/mob/clothing/under/medical.dmi', "paramedic_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - if("Captain") - clothes_s = new /icon('icons/mob/clothing/under/captain.dmi', "captain_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "brown"), ICON_UNDERLAY) - if("Head of Security") - clothes_s = new /icon('icons/mob/clothing/under/security.dmi', "hos_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "jackboots"), ICON_UNDERLAY) - if("Warden") - clothes_s = new /icon('icons/mob/clothing/under/security.dmi', "warden_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "jackboots"), ICON_UNDERLAY) - if("Detective") - clothes_s = new /icon('icons/mob/clothing/under/security.dmi', "detective_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "detective"), ICON_OVERLAY) - if("Security Officer") - clothes_s = new /icon('icons/mob/clothing/under/security.dmi', "security_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "jackboots"), ICON_UNDERLAY) - if("Chief Engineer") - clothes_s = new /icon('icons/mob/clothing/under/engineering.dmi', "chief_engineer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/belt.dmi', "utility"), ICON_OVERLAY) - if("Station Engineer") - clothes_s = new /icon('icons/mob/clothing/under/engineering.dmi', "engineer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "orange"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/belt.dmi', "utility"), ICON_OVERLAY) - if("Life Support Specialist") - clothes_s = new /icon('icons/mob/clothing/under/engineering.dmi', "atmos_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/belt.dmi', "utility"), ICON_OVERLAY) - if("Roboticist") - clothes_s = new /icon('icons/mob/clothing/under/rnd.dmi', "robotics_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "labcoat_open"), ICON_OVERLAY) - if("Syndicate Agent") - clothes_s = new /icon('icons/mob/clothing/under/syndicate.dmi', "syndicate_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - if("Syndicate Officer") - clothes_s = new /icon('icons/mob/clothing/under/syndicate.dmi', "syndicate_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "jackboots"), ICON_UNDERLAY) - if("Syndicate Nuclear Operative") - clothes_s = new /icon('icons/mob/clothing/under/syndicate.dmi', "syndicate_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "jackboots"), ICON_UNDERLAY) - if("Emergency Response Team Officer") - clothes_s = new /icon('icons/mob/clothing/under/centcom.dmi', "officer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "jackboots"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/hands.dmi', "swat_gl"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/belt.dmi', "security"), ICON_OVERLAY) - if("Emergency Response Team Engineer") - clothes_s = new /icon('icons/mob/clothing/under/centcom.dmi', "officer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "workboots"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/hands.dmi', "swat_gl"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/belt.dmi', "utility"), ICON_OVERLAY) - if("Emergency Response Team Medic") - clothes_s = new /icon('icons/mob/clothing/under/centcom.dmi', "officer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "white"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/hands.dmi', "swat_gl"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/belt.dmi', "medical"), ICON_OVERLAY) - if("Emergency Response Team Inquisitor") - clothes_s = new /icon('icons/mob/clothing/under/centcom.dmi', "officer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "jackboots"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/hands.dmi', "swat_gl"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/belt.dmi', "claymore"), ICON_OVERLAY) - if("Emergency Response Team Janitor") - clothes_s = new /icon('icons/mob/clothing/under/centcom.dmi', "officer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "galoshes"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/hands.dmi', "swat_gl"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/belt.dmi', "janibelt"), ICON_OVERLAY) - if("Emergency Response Team Leader") - clothes_s = new /icon('icons/mob/clothing/under/centcom.dmi', "officer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "laceups"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/hands.dmi', "wgloves"), ICON_UNDERLAY) - if("Emergency Response Team Member") - clothes_s = new /icon('icons/mob/clothing/under/centcom.dmi', "officer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "jackboots"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/hands.dmi', "swat_gl"), ICON_UNDERLAY) - if("Naked") - clothes_s = null - else - if(H.mind && (H.mind.assigned_role in get_all_centcom_jobs())) - clothes_s = new /icon('icons/mob/clothing/under/centcom.dmi', "officer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "laceups"), ICON_UNDERLAY) - else - clothes_s = new /icon('icons/mob/clothing/under/color.dmi', "grey_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY) - - preview_icon.Blend(face_s, ICON_OVERLAY) // Why do we do this twice - if(clothes_s) - preview_icon.Blend(clothes_s, ICON_OVERLAY) - //Bus body accessories that go over clothes. - if(H.body_accessory && istype(H.body_accessory, /datum/body_accessory/body)) - temp = new/icon("icon" = H.body_accessory.icon, "icon_state" = H.body_accessory.icon_state) - if(H.body_accessory.pixel_x_offset) - temp.Shift(EAST, H.body_accessory.pixel_x_offset) - if(H.body_accessory.pixel_y_offset) - temp.Shift(NORTH, H.body_accessory.pixel_y_offset) - if(H.dna.species.bodyflags & HAS_SKIN_COLOR) - temp.Blend(H.skin_colour, H.body_accessory.blend_mode) - if(t_marking_s) - temp.Blend(t_marking_s, ICON_OVERLAY) - preview_icon.Blend(temp, ICON_OVERLAY) - - preview_icon.Blend(hands_icon, ICON_OVERLAY) - qdel(face_s) - qdel(clothes_s) - - return preview_icon diff --git a/code/datums/datum.dm b/code/datums/datum.dm deleted file mode 100644 index e09769af7552d..0000000000000 --- a/code/datums/datum.dm +++ /dev/null @@ -1,86 +0,0 @@ -/datum - var/gc_destroyed //Time when this object was destroyed. - var/list/active_timers //for SStimer - var/list/datum_components //for /datum/components - /// Status traits attached to this datum - var/list/status_traits - var/list/comp_lookup - var/list/list/datum/callback/signal_procs - var/var_edited = FALSE //Warranty void if seal is broken - var/tmp/unique_datum_id = null - /// MD5'd version of the UID. Used for instances where we dont want to make clients aware of UIDs. - VAR_PRIVATE/tmp/md5_unique_datum_id = null // using VAR_PRIVATE means it cant be accessed outside of the MD5_UID() proc - - /// Used by SSprocessing - var/isprocessing = FALSE - -/** - * A cached version of our \ref - * The brunt of \ref costs are in creating entries in the string tree (a tree of immutable strings) - * This avoids doing that more then once per datum by ensuring ref strings always have a reference to them after they're first pulled - */ - var/cached_ref - -#ifdef REFERENCE_TRACKING - var/running_find_references - var/last_find_references = 0 -#endif - -// Default implementation of clean-up code. -// This should be overridden to remove all references pointing to the object being destroyed. -// Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE. -/datum/proc/Destroy(force = FALSE, ...) - SHOULD_CALL_PARENT(TRUE) - tag = null - - // Close our open TGUIs - SStgui.close_uis(src) - - var/list/timers = active_timers - active_timers = null - for(var/thing in timers) - var/datum/timedevent/timer = thing - if(timer.spent && !(timer.flags & TIMER_DELETE_ME)) - continue - qdel(timer) - - //BEGIN: ECS SHIT - var/list/dc = datum_components - if(dc) - var/all_components = dc[/datum/component] - if(length(all_components)) - for(var/I in all_components) - var/datum/component/C = I - qdel(C, FALSE, TRUE) - else - var/datum/component/C = all_components - qdel(C, FALSE, TRUE) - dc.Cut() - - _clear_signal_refs() - //END: ECS SHIT - - return QDEL_HINT_QUEUE - -/// Do not override this. This proc exists solely to be overriden by /turf. This -/// allows it to ignore clearing out signals which refer to it, in order to keep -/// those signals valid after the turf has been changed. -/datum/proc/_clear_signal_refs() - var/list/lookup = comp_lookup - if(lookup) - for(var/sig in lookup) - var/list/comps = lookup[sig] - if(length(comps)) - for(var/i in comps) - var/datum/component/comp = i - comp.UnregisterSignal(src, sig) - else - var/datum/component/comp = comps - comp.UnregisterSignal(src, sig) - comp_lookup = lookup = null - - for(var/target in signal_procs) - UnregisterSignal(target, signal_procs[target]) - -/datum/nothing - // Placeholder object, used for ispath checks. Has to be defined to prevent errors, but shouldn't ever be created. diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm deleted file mode 100644 index e833f1715fa51..0000000000000 --- a/code/datums/diseases/_MobProcs.dm +++ /dev/null @@ -1,172 +0,0 @@ - -/mob/proc/HasDisease(datum/disease/D) - for(var/thing in viruses) - var/datum/disease/DD = thing - if(DD.IsSame(D)) - return TRUE - return FALSE - - -/mob/proc/CanContractDisease(datum/disease/D) - if(stat == DEAD && !D.allow_dead) - return FALSE - - if(D.GetDiseaseID() in resistances) - return FALSE - - if(HasDisease(D)) - return FALSE - - if(istype(D, /datum/disease/advance) && count_by_type(viruses, /datum/disease/advance) > 0) - return FALSE - - if(!(type in D.viable_mobtypes)) - return -1 //for stupid fucking monkies - - return TRUE - - -/mob/proc/ContractDisease(datum/disease/D) - if(!CanContractDisease(D)) - return 0 - AddDisease(D) - return TRUE - - -/mob/proc/AddDisease(datum/disease/D, respect_carrier = FALSE) - var/datum/disease/DD = new D.type(1, D, 0) - viruses += DD - DD.affected_mob = src - GLOB.active_diseases += DD //Add it to the active diseases list, now that it's actually in a mob and being processed. - - //Copy properties over. This is so edited diseases persist. - var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed") - if(respect_carrier) - skipped -= "carrier" - for(var/V in DD.vars) - if(V in skipped) - continue - if(istype(DD.vars[V],/list)) - var/list/L = D.vars[V] - DD.vars[V] = L.Copy() - else - DD.vars[V] = D.vars[V] - - create_log(MISC_LOG, "has contacted the virus \"[DD]\"") - DD.affected_mob.med_hud_set_status() - - -/mob/living/carbon/ContractDisease(datum/disease/D) - if(!CanContractDisease(D)) - return 0 - - var/obj/item/clothing/Cl = null - var/passed = 1 - - var/head_ch = 100 - var/body_ch = 100 - var/hands_ch = 25 - var/feet_ch = 25 - - if(D.spread_flags & CONTACT_HANDS) - head_ch = 0 - body_ch = 0 - hands_ch = 100 - feet_ch = 0 - if(D.spread_flags & CONTACT_FEET) - head_ch = 0 - body_ch = 0 - hands_ch = 0 - feet_ch = 100 - - if(prob(15/D.permeability_mod)) - return - - if(satiety > 0 && prob(satiety/10)) // positive satiety makes it harder to contract the disease. - return - - var/target_zone = pick(head_ch;1,body_ch;2,hands_ch;3,feet_ch;4) - - if(ishuman(src)) - var/mob/living/carbon/human/H = src - - switch(target_zone) - if(1) - if(isobj(H.head) && !istype(H.head, /obj/item/paper)) - Cl = H.head - passed = prob((Cl.permeability_coefficient*100) - 1) - if(passed && isobj(H.wear_mask)) - Cl = H.wear_mask - passed = prob((Cl.permeability_coefficient*100) - 1) - if(2) - if(isobj(H.wear_suit)) - Cl = H.wear_suit - passed = prob((Cl.permeability_coefficient*100) - 1) - if(passed && isobj(H.w_uniform)) - Cl = H.w_uniform - passed = prob((Cl.permeability_coefficient*100) - 1) - if(3) - if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&HANDS) - Cl = H.wear_suit - passed = prob((Cl.permeability_coefficient*100) - 1) - - if(passed && isobj(H.gloves)) - Cl = H.gloves - passed = prob((Cl.permeability_coefficient*100) - 1) - if(4) - if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&FEET) - Cl = H.wear_suit - passed = prob((Cl.permeability_coefficient*100) - 1) - - if(passed && isobj(H.shoes)) - Cl = H.shoes - passed = prob((Cl.permeability_coefficient*100) - 1) - - - if(!passed && (D.spread_flags & AIRBORNE) && !internal) - passed = (prob((50*D.permeability_mod) - 1)) - - if(passed) - AddDisease(D) - return passed - - -/** - * Forces the mob to contract a virus. If the mob can have viruses. Ignores clothing and other protection - * Returns TRUE if it succeeds. False if it doesn't - * - * Arguments: - * * D - the disease the mob will try to contract - * * respect_carrier - if set to TRUE will not ignore the disease carrier flag - * * notify_ghosts - will notify ghosts of infection if set to TRUE - */ -//Same as ContractDisease, except never overidden clothes checks -/mob/proc/ForceContractDisease(datum/disease/D, respect_carrier, notify_ghosts = FALSE) - if(!CanContractDisease(D)) - return FALSE - if(notify_ghosts) - for(var/mob/ghost as anything in GLOB.dead_mob_list) //Announce outbreak to dchat - to_chat(ghost, "Disease outbreak: [src] ([ghost_follow_link(src, ghost)]) [D.carrier ? "is now a carrier of" : "has contracted"] [D]!") - AddDisease(D, respect_carrier) - return TRUE - - -/mob/living/carbon/human/CanContractDisease(datum/disease/D) - if(HAS_TRAIT(src, TRAIT_VIRUSIMMUNE) && !D.bypasses_immunity) - return FALSE - - for(var/organ in D.required_organs) - if(istext(organ) && get_int_organ_datum(organ)) - continue - if(locate(organ) in internal_organs) - continue - if(locate(organ) in bodyparts) - continue - return FALSE - return ..() - -/mob/living/carbon/human/monkey/CanContractDisease(datum/disease/D) - . = ..() - if(. == -1) - if(D.viable_mobtypes.Find(/mob/living/carbon/human)) - return 1 //this is stupid as fuck but because monkeys are only half the time actually subtypes of humans they need this diff --git a/code/datums/diseases/pierrot_throat.dm b/code/datums/diseases/pierrot_throat.dm deleted file mode 100644 index dd2c758092429..0000000000000 --- a/code/datums/diseases/pierrot_throat.dm +++ /dev/null @@ -1,60 +0,0 @@ -/datum/disease/pierrot_throat - name = "Pierrot's Throat" - max_stages = 4 - spread_text = "Airborne" - cure_text = "Banana products, especially banana bread." - cures = list("banana") - cure_chance = 75 - agent = "H0NI<42.B4n4 Virus" - viable_mobtypes = list(/mob/living/carbon/human) - permeability_mod = 0.75 - desc = "If left untreated the subject will probably drive others to insanity and go insane themselves." - severity = MINOR - -/datum/disease/pierrot_throat/stage_act() - if(!..()) - return FALSE - if(stage < 2) - return - - var/mob/living/carbon/human/H = affected_mob - - var/static/list/message_chances = list(null, 4, 2, 1) - if(prob(message_chances[stage])) - to_chat(H, "You feel [pick("a little silly", "like making a joke", "in the mood for giggling", "like the world is a little more vibrant")].") - if(prob(message_chances[stage])) - to_chat(H, "You see [pick("rainbows", "puppies", "banana pies")] for a moment.") - - if(stage < 3) - return - - var/static/list/honk_chances = list(null, null, 4, 0.66) - if(prob(honk_chances[stage])) - to_chat(H, "Your thoughts are interrupted by a loud HONK!") - SEND_SOUND(H, sound(pick(18; 'sound/items/bikehorn.ogg', 1; 'sound/items/airhorn.ogg', 1; 'sound/items/airhorn2.ogg'))) // 10% chance total for an airhorn - - if(stage < 4) - return - - if(prob(5)) - H.say(pick("HONK!", "Honk!", "Honk.", "Honk?", "Honk!!", "Honk?!", "Honk...")) - - // Semi-permanent clown mask while in last stage of infection - if(locate(/obj/item/clothing/mask/gas/clown_hat) in H) - return - if(!istype(H)) // Xenos don't have masks. They can still feel silly though - return - - if(!H.has_organ_for_slot(ITEM_SLOT_MASK) || !H.canUnEquip(H.get_item_by_slot(ITEM_SLOT_MASK))) - return - - var/saved_internals = H.internal - - H.drop_item_to_ground(H.get_item_by_slot(ITEM_SLOT_MASK)) - var/obj/item/clothing/mask/gas/clown_hat/peak_comedy = new - peak_comedy.flags |= DROPDEL - H.equip_to_slot_or_del(peak_comedy, ITEM_SLOT_MASK) - - if(saved_internals) // Let's not stealthily suffocate Vox/Plasmamen, this isn't a murder virus - H.internal = saved_internals - H.update_action_buttons_icon() diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm deleted file mode 100644 index 2dd23b8734aab..0000000000000 --- a/code/datums/diseases/wizarditis.dm +++ /dev/null @@ -1,122 +0,0 @@ -/datum/disease/wizarditis - name = "Wizarditis" - desc = "Some speculate that this virus is the cause of Wizard Federation existence. Subjects affected show signs of dementia, yelling obscure sentences or total gibberish. In late stages, subjects sometime express feelings of inner power, and cite 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike condition." - max_stages = 4 - spread_text = "Airborne" - cure_text = "The Manly Dorf" - cures = list("manlydorf") - cure_chance = 100 - agent = "Rincewindus Vulgaris" - viable_mobtypes = list(/mob/living/carbon/human) - permeability_mod = 0.75 - severity = MINOR - /// A mapping of `num2text(ITEM_SLOT_XYZ)` -> item path - var/list/magic_fashion = list() - - -/datum/disease/wizarditis/New() - . = ..() - - var/list/magic_fashion_slot_IDs = list( - ITEM_SLOT_LEFT_HAND, - ITEM_SLOT_RIGHT_HAND, - ITEM_SLOT_HEAD, - ITEM_SLOT_OUTER_SUIT, - ITEM_SLOT_SHOES - ) - var/list/magic_fashion_items = list( - /obj/item/staff, - /obj/item/staff, - /obj/item/clothing/head/wizard, - /obj/item/clothing/suit/wizrobe, - /obj/item/clothing/shoes/sandal - ) - for(var/i in 1 to length(magic_fashion_slot_IDs)) - var/slot = num2text(magic_fashion_slot_IDs[i]) - var/item = magic_fashion_items[i] - magic_fashion[slot] = item - -/datum/disease/wizarditis/stage_act() - if(!..()) - return FALSE - - switch(stage) - if(2, 3) - if(prob(2)) // Low prob. since everyone else will also be spouting this - affected_mob.say(pick("You shall not pass!", "Expeliarmus!", "By Merlin's beard!", "Feel the power of the Dark Side!", "A wizard is never late!", "50 points for Security!", "NEC CANTIO!", "STI KALY!", "AULIE OXIN FIERA!", "GAR YOK!", "DIRI CEL!")) - if(prob(8)) // Double the stage advancement prob. so each player has a chance to catch a couple - to_chat(affected_mob, "You feel [pick("that you don't have enough mana", "that the winds of magic are gone", "that this location gives you a +1 to INT", "an urge to summon familiar")].") - if(4) - if(prob(1)) - affected_mob.say(pick("FORTI GY AMA!", "GITTAH WEIGH!", "TOKI WO TOMARE!", "TARCOL MINTI ZHERI!", "ONI SOMA!", "EI NATH!", "BIRUZ BENNAR!", "NWOLC EGNEVER!")) - if(prob(3)) // Last stage, so we'll have plenty of time to show these off even with a lower prob. - to_chat(affected_mob, "You feel [pick("the tidal wave of raw power building inside", "that this location gives you a +2 to INT and +1 to WIS", "an urge to teleport", "the magic bubbling in your veins", "an urge to summon familiar")].") - if(prob(3)) // About 1 minute per item on average - spawn_wizard_clothes() - if(prob(0.033)) // Assuming 50 infected, someone should teleport every ~2 minutes on average - teleport() - -/datum/disease/wizarditis/proc/spawn_wizard_clothes() - var/mob/living/carbon/human/H = affected_mob - if(!istype(H)) - return // Woe, wizard xeno upon ye - - // Which slots can we replace? - var/list/eligible_slot_IDs = list() - for(var/slot in magic_fashion) - var/slot_ID = text2num(slot) // Convert back to numeric defines - - if((locate(magic_fashion[slot]) in H) || !H.has_organ_for_slot(slot_ID) || !H.canUnEquip(H.get_item_by_slot(slot_ID))) - continue - - switch(slot_ID) // Extra filtering for specific slots - if(ITEM_SLOT_HEAD) - if(isplasmaman(H)) - continue // We want them to spread the magical joy, not burn to death in agony - - eligible_slot_IDs.Add(slot_ID) - if(!length(eligible_slot_IDs)) - return - - // Pick the magical winner and apply - var/chosen_slot_ID = pick(eligible_slot_IDs) - var/chosen_fashion = magic_fashion[num2text(chosen_slot_ID)] - - H.drop_item_to_ground(H.get_item_by_slot(chosen_slot_ID)) - var/obj/item/magic_attire = new chosen_fashion - magic_attire.flags |= DROPDEL - H.equip_to_slot_or_del(magic_attire, chosen_slot_ID) - -/datum/disease/wizarditis/proc/teleport() - if(!is_teleport_allowed(affected_mob.z)) - return - if(SEND_SIGNAL(affected_mob, COMSIG_MOVABLE_TELEPORTING, get_turf(affected_mob)) & COMPONENT_BLOCK_TELEPORT) - return FALSE - - var/list/possible_areas = get_areas_in_range(80, affected_mob) - for(var/area/space/S in possible_areas) - possible_areas -= S - - if(!length(possible_areas)) - return - - var/area/chosen_area = pick(possible_areas) - - var/list/teleport_turfs = list() - for(var/turf/T in get_area_turfs(chosen_area.type)) - if(isspaceturf(T)) - continue - if(!T.density) - var/clear = TRUE - for(var/obj/O in T) - if(O.density) - clear = FALSE - break - if(clear) - teleport_turfs += T - - if(!length(teleport_turfs)) - return - - affected_mob.say("SCYAR NILA [uppertext(chosen_area.name)]!") - affected_mob.forceMove(pick(teleport_turfs)) diff --git a/code/datums/dog_fashion.dm b/code/datums/dog_fashion.dm deleted file mode 100644 index 2c3832190bb8b..0000000000000 --- a/code/datums/dog_fashion.dm +++ /dev/null @@ -1,306 +0,0 @@ -/datum/dog_fashion - var/name - var/desc - var/emote_see - var/emote_hear - var/speak - var/speak_emote - - // This isn't applied to the dog, but stores the icon_state of the - // sprite that the associated item uses - var/icon_file - var/obj_icon_state - var/obj_alpha - var/obj_color - -/datum/dog_fashion/New(mob/M) - name = replacetext(name, "REAL_NAME", M.real_name) - desc = replacetext(desc, "NAME", name) - -/datum/dog_fashion/proc/apply(mob/living/simple_animal/pet/dog/D) - if(name) - D.name = name - if(desc) - D.desc = desc - if(emote_see) - D.emote_see = emote_see - if(emote_hear) - D.emote_hear = emote_hear - if(speak) - D.speak = speak - if(speak_emote) - D.speak_emote = speak_emote - -/datum/dog_fashion/proc/get_overlay(dir) - if(icon_file && obj_icon_state) - var/image/corgI = image(icon_file, obj_icon_state, dir = dir) - corgI.alpha = obj_alpha - corgI.color = obj_color - return corgI - - -/datum/dog_fashion/head - icon_file = 'icons/mob/corgi_head.dmi' - -/datum/dog_fashion/back - icon_file = 'icons/mob/corgi_back.dmi' - -/datum/dog_fashion/head/hardhat/apply(mob/living/simple_animal/pet/dog/D) - ..() - D.set_light(4) - -/datum/dog_fashion/head/hardhat - name = "Engineer REAL_NAME" - desc = "Trust him, he's an engineer." - -/datum/dog_fashion/head/hardhat/white - name = "Chief engineer REAL_NAME" - desc = "Hasn't delamed the engine once." - -/datum/dog_fashion/head/hardhat/red - name = "Fire chief REAL_NAME" - desc = "Some days you're the dog, some days you're the hydrant." - -/datum/dog_fashion/head/helmet - name = "Sergeant REAL_NAME" - desc = "The ever-loyal, the ever-vigilant." - -/datum/dog_fashion/head/chef - name = "Sous chef REAL_NAME" - desc = "Your food will be taste-tested. All of it." - - -/datum/dog_fashion/head/captain - name = "Captain REAL_NAME" - desc = "Probably better than the last captain." - -/datum/dog_fashion/head/kitty - name = "Runtime" - emote_see = list("coughs up a furball", "stretches") - emote_hear = list("purrs") - speak = list("Purrr", "Meow!", "MAOOOOOW!", "HISSSSS", "MEEEEEEW") - desc = "It's a cute little kitty-cat! ... wait ... what the hell?" - -/datum/dog_fashion/head/rabbit - name = "Hoppy" - emote_see = list("twitches its nose", "hops around a bit") - desc = "This is Hoppy. It's a corgi-...urmm... bunny rabbit." - -/datum/dog_fashion/head/beret - name = "Yann" - desc = "Mon dieu! C'est un chien!" - speak = list("le woof!", "le bark!", "JAPPE!!") - emote_see = list("cowers in fear.", "surrenders.", "plays dead.","looks as though there is a wall in front of him.") - - -/datum/dog_fashion/head/detective - name = "Detective REAL_NAME" - desc = "NAME sees through your lies..." - emote_see = list("investigates the area.","sniffs around for clues.","searches for scooby snacks.","takes a candycorn from the hat.") - - -/datum/dog_fashion/head/nurse - name = "Nurse REAL_NAME" - desc = "NAME needs 100cc of beef jerky... STAT!" - -/datum/dog_fashion/head/pirate - name = "Pirate-title Pirate-name" - desc = "Yaarghh!! Thar' be a scurvy dog!" - emote_see = list("hunts for treasure.","stares coldly...","gnashes his tiny corgi teeth!") - emote_hear = list("growls ferociously!", "snarls.") - speak = list("Arrrrgh!!","Grrrrrr!") - -/datum/dog_fashion/head/pirate/New(mob/M) - ..() - name = "[pick("Ol'","Scurvy","Black","Rum","Gammy","Bloody","Gangrene","Death","Long-John")] [pick("kibble","leg","beard","tooth","poop-deck","Threepwood","Le Chuck","corsair","Silver","Crusoe")]" - -/datum/dog_fashion/head/ushanka - name = "Communist-title Realname" - desc = "A follower of Karl Barx." - emote_see = list("contemplates the failings of the capitalist economic model.", "ponders the pros and cons of vanguardism.") - -/datum/dog_fashion/head/ushanka/New(mob/M) - ..() - name = "[pick("Comrade","Commissar","Glorious Leader")] [M.real_name]" - -/datum/dog_fashion/head/warden - name = "Officer REAL_NAME" - emote_see = list("drools.","looks for donuts.") - desc = "Stop right there criminal scum!" - -/datum/dog_fashion/head/blue_wizard - name = "Grandwizard REAL_NAME" - speak = list("YAP", "Woof!", "Bark!", "AUUUUUU", "EI NATH!") - -/datum/dog_fashion/head/red_wizard - name = "Pyromancer REAL_NAME" - speak = list("YAP", "Woof!", "Bark!", "AUUUUUU", "ONI SOMA!") - -/datum/dog_fashion/head/black_wizard - name = "Necromancer REAL_NAME" - speak = list("YAP", "Woof!", "Bark!", "AUUUUUU") - -// CARDBORG OUTFITS -/datum/dog_fashion/head/cardborg - name = "BORGI" - speak = list("Ping!","Beep!","Woof!") - emote_see = list("goes rogue.", "sniffs out non-humans.") - desc = "Result of robotics budget cuts." - -/datum/dog_fashion/head/cardborg/security - name = "SECBORGI" - speak = list("Ping!", "Beep!", "Woof!", "HALT!", "HALT! HALT! HALT!") - emote_see = list("goes rogue.", "sniffs out criminals.") - desc = "Result of robotics budget cuts and a ban on the station having real security cyborgs." - -/datum/dog_fashion/head/cardborg/engineering - name = "ENGI-IAN" - speak = list("Ping!", "Beep!", "Woof!") - emote_see = list("goes rogue.", "sniffs for wires.", "looks for an autolathe board.") - desc = "Result of robotics budget cuts. Knows as much about atmospherics as the average engineer." - -/datum/dog_fashion/head/cardborg/mining - name = "DIGDOG" - speak = list("Ping!", "Beep!", "Woof!") - emote_see = list("goes rogue.", "sniffs for ores.", "digs into the floor.") - desc = "Result of robotics budget cuts. Has dug up more bones than any other miner!" - -/datum/dog_fashion/head/cardborg/service - name = "Service dogbot" - speak = list("Ping!", "Beep!", "Woof!") - emote_see = list("goes rogue.") - desc = "Result of robotics budget cuts. Still about as useful as a real service cyborg..." - -/datum/dog_fashion/head/cardborg/medical - name = "M3D1CAL_IANTERN" - speak = list("Ping!", "Beep!", "Woof!") - emote_see = list("goes rogue.", "sniffs out the injured.", "analyses your vitals.") - desc = "Result of robotics budget cuts. Hopefully medical is more useful." - -/datum/dog_fashion/head/cardborg/janitor - name = "CLE-IAN-G" - speak = list("Ping!", "Beep!", "Woof!") - emote_see = list("goes rogue.", "sniffs for messes.", "licks the floor clean.") - desc = "Result of robotics budget cuts. More pettable than 9 out of 10 janitors." - -/datum/dog_fashion/head/cardborg/xeno - name = "BORGIMORPH" - speak = list("Ping!", "Beep!", "Woof!", "HISS!", "HISSHISSHISS!") - emote_see = list("goes rogue.", "hisses.") - desc = "Result of robotics budget cuts. If this is your last line of defence against a xenomorph outbreak, god help you." - -/datum/dog_fashion/head/cardborg/deathbot - name = "Epsilon-D0G1" - speak = list("Ping!", "Beep!", "Woof!") - emote_see = list("goes rogue.", "sniffs out survivors.", "prepares to destroy the station.") - desc = "Result of robotics budget cuts. Looks just like the cyborg from the Deathsquad TV show!" - -/datum/dog_fashion/head/ghost - name = "\improper Ghost" - speak = list("WoooOOOooo~","AUUUUUUUUUUUUUUUUUU") - emote_see = list("stumbles around.", "shivers.") - emote_hear = list("howls!","groans.") - desc = "Spooky!" - obj_icon_state = "sheet" - -/datum/dog_fashion/head/santa - name = "Santa's Corgi Helper" - emote_hear = list("barks Christmas songs.", "yaps merrily!") - emote_see = list("looks for presents.", "checks his list.") - desc = "He's very fond of milk and cookies." - -/datum/dog_fashion/head/cargo_tech - name = "Corgi Tech REAL_NAME" - desc = "The reason your yellow gloves have chew-marks." - -/datum/dog_fashion/head/softcap - -/datum/dog_fashion/head/reindeer - name = "REAL_NAME the red-nosed Corgi" - emote_hear = list("lights the way!", "illuminates.", "yaps!") - desc = "He has a very shiny nose." - -/datum/dog_fashion/head/reindeer/apply(mob/living/simple_animal/pet/dog/D) - ..() - D.set_light(2, 2, LIGHT_COLOR_RED) - -/datum/dog_fashion/head/sombrero - name = "Segnor REAL_NAME" - desc = "You must respect Elder Dogname." - -/datum/dog_fashion/head/sombrero/New(mob/M) - ..() - desc = "You must respect Elder [M.real_name]." - -/datum/dog_fashion/head/hop - name = "Lieutenant REAL_NAME" - desc = "Can actually be trusted to not run off on his own." - -/datum/dog_fashion/head/deathsquad - name = "Trooper REAL_NAME" - desc = "That's not red paint. That's real corgi blood." - -/datum/dog_fashion/head/clown - name = "REAL_NAME the Clown" - desc = "Honkman's best friend." - speak = list("HONK!", "Honk!") - emote_see = list("plays tricks.", "slips.") - -/datum/dog_fashion/back/deathsquad - name = "Trooper REAL_NAME" - desc = "That's not red paint. That's real corgi blood." - -/datum/dog_fashion/head/not_ian - name = "Definitely Not REAL_NAME" - desc = "That's Definitely Not Dogname." - -/datum/dog_fashion/head/not_ian/New(mob/M) - ..() - desc = "That's Definitely Not [M.real_name]." - -/datum/dog_fashion/head/cone - name = "REAL_NAME" - desc = "Omnicone's Chosen Champion." - -/datum/dog_fashion/head/fried_vox_empty - name = "Colonel REAL_NAME" - desc = "Keep away from live vox." - -/datum/dog_fashion/head/hos - name = "Head of Security REAL_NAME" - desc = "Probably better than the last HoS." - -/datum/dog_fashion/head/beret/sec - name = "Officer REAL_NAME" - desc = "Ever-loyal, ever-vigilant." - -/datum/dog_fashion/head/bowlerhat - name = "REAL_NAME" - desc = "A sophisticated city gent." - -/datum/dog_fashion/head/surgery - name = "Nurse-in-Training REAL_NAME" - desc = "The most adorable bed-side manner ever." - -/datum/dog_fashion/head/bucket - name = "REAL_NAME" - desc = "A janitor's best friend." - -/datum/dog_fashion/head/justice_wig - name = "Arbiter REAL_NAME" - desc = "Head of the High Court of Cute." - -/datum/dog_fashion/head/wizard/magus - name = "Battlemage REAL_NAME" - -/datum/dog_fashion/head/wizard/marisa - name = "Witch REAL_NAME" - desc = "Flying broom not included." - -/datum/dog_fashion/head/roman - name = "Imperator REAL_NAME" - desc = "For the Senate and the people of Rome!" - -/datum/dog_fashion/head/qm - name = "Supplymaster REAL_NAME" - desc = "A loyal watchdog for the most secure transportation." diff --git a/code/datums/elements/connect_loc.dm b/code/datums/elements/connect_loc.dm deleted file mode 100644 index 6fcc1474679c3..0000000000000 --- a/code/datums/elements/connect_loc.dm +++ /dev/null @@ -1,43 +0,0 @@ -/// 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 - argument_hash_start_idx = 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_REF(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(QDELETED(listener) || QDELETED(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 // COMSIG_MOVABLE_MOVED - unregister_signals(listener, old_loc) - update_signals(listener) diff --git a/code/datums/elements/decal_element.dm b/code/datums/elements/decal_element.dm deleted file mode 100644 index 1d9cbb15da8c2..0000000000000 --- a/code/datums/elements/decal_element.dm +++ /dev/null @@ -1,177 +0,0 @@ -// NOTE: -// This is an incredibly piecemeal port of /tg/'s decal element. -// It does not include several pieces of functionality that exist in /tg/. -// -// Namely: -// - It does not support smoothing decals -// - It does not send a signal when a decal is detached (used for trapdoors on /tg/) -// - It does not support custom plane configuration as this behavior seems primarily concerned with multi-z - -/datum/element/decal - element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH_ON_HOST_DESTROY - argument_hash_start_idx = 2 - /// Whether this decal can be cleaned. - var/cleanable - /// A description this decal appends to the target's examine message. - var/description - /// If true this was initialized with no set direction - will follow the parent dir. - var/directional - /// The base icon state that this decal was initialized with. - var/base_icon_state - /// The overlay applied by this decal to the target. - var/mutable_appearance/pic - -/datum/element/decal/Attach(atom/target, _icon, _icon_state, _dir, _layer=TURF_LAYER, _alpha=255, _color, _cleanable=FALSE, _description, mutable_appearance/_pic) - . = ..() - if(!isatom(target)) - return ELEMENT_INCOMPATIBLE - if(_pic) - pic = _pic - else if(!generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha, target)) - return ELEMENT_INCOMPATIBLE - description = _description - cleanable = _cleanable - directional = _dir - base_icon_state = _icon_state - - RegisterSignal(target, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(apply_overlay), TRUE) - if(target.initialized) - target.update_appearance(UPDATE_OVERLAYS) //could use some queuing here now maybe. - else - RegisterSignal(target, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE, PROC_REF(late_update_icon), TRUE) - if(isitem(target)) - INVOKE_ASYNC(target, TYPE_PROC_REF(/obj/item/, update_slot_icon), TRUE) - if(_dir) - RegisterSignal(target, list(COMSIG_ATOM_DECALS_ROTATING, COMSIG_ATOM_GET_DECALS), PROC_REF(get_decals), TRUE) - SSdcs.RegisterSignal(target, COMSIG_ATOM_DIR_CHANGE, TYPE_PROC_REF(/datum/controller/subsystem/processing/dcs, rotate_decals), override=TRUE) - if(_cleanable) - RegisterSignal(target, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(clean_react), TRUE) - if(_description) - RegisterSignal(target, COMSIG_PARENT_EXAMINE, PROC_REF(examine), TRUE) - - RegisterSignal(target, COMSIG_TURF_ON_SHUTTLE_MOVE, PROC_REF(shuttle_move_react), TRUE) - -/// Remove old decals and apply new decals after rotation as necessary -/datum/controller/subsystem/processing/dcs/proc/rotate_decals(datum/source, old_dir, new_dir) - SIGNAL_HANDLER // COMSIG_ATOM_DIR_CHANGE - - if(old_dir == new_dir) - return - - var/list/datum/element/decal/old_decals = list() //instances - SEND_SIGNAL(source, COMSIG_ATOM_DECALS_ROTATING, old_decals) - - if(!length(old_decals)) - UnregisterSignal(source, COMSIG_ATOM_DIR_CHANGE) - return - - var/list/resulting_decals_params = list() // param lists - for(var/datum/element/decal/rotating as anything in old_decals) - resulting_decals_params += list(rotating.get_rotated_parameters(old_dir,new_dir)) - - //Instead we could generate ids and only remove duplicates to save on churn on four-corners symmetry ? - for(var/datum/element/decal/decal in old_decals) - decal.Detach(source) - - for(var/result in resulting_decals_params) - source.AddElement(/datum/element/decal, result["icon"], result["icon_state"], result["dir"], result["layer"], result["alpha"], result["color"], result["cleanable"], result["desc"]) - -/datum/element/decal/proc/get_rotated_parameters(old_dir,new_dir) - var/rotation = 0 - if(directional) //Even when the dirs are the same rotation is coming out as not 0 for some reason - rotation = SIMPLIFY_DEGREES(dir2angle(new_dir)-dir2angle(old_dir)) - new_dir = turn(pic.dir,-rotation) - return list( - "icon" = pic.icon, - "icon_state" = base_icon_state, - "dir" = new_dir, - "plane" = pic.plane, - "layer" = pic.layer, - "alpha" = pic.alpha, - "color" = pic.color, - "cleanable" = cleanable, - "desc" = description - ) - -/datum/element/decal/proc/late_update_icon(atom/source) - SIGNAL_HANDLER // COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE - - if(istype(source) && !(source.flags_2 & DECAL_INIT_UPDATE_EXPERIENCED_2)) - source.flags_2 |= DECAL_INIT_UPDATE_EXPERIENCED_2 - source.update_appearance(UPDATE_OVERLAYS) - UnregisterSignal(source, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE) - -/** - * If the decal was not given an appearance, it will generate one based on the other given arguments. - * element won't be compatible if it cannot do either - * all args are fed into creating an image, they are byond vars for images you'll recognize in the byond docs - * (except source, source is the object whose appearance we're copying.) - */ -/datum/element/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha, source) - if(!_icon || !_icon_state) - return FALSE - var/temp_image = image(_icon, null, _icon_state, _layer, _dir) - pic = new(temp_image) - pic.color = _color - pic.alpha = _alpha - return TRUE - -/datum/element/decal/Detach(atom/source) - UnregisterSignal(source, list( - COMSIG_ATOM_DIR_CHANGE, - COMSIG_COMPONENT_CLEAN_ACT, - COMSIG_PARENT_EXAMINE, - COMSIG_ATOM_UPDATE_OVERLAYS, - COMSIG_TURF_ON_SHUTTLE_MOVE, - COMSIG_ATOM_DECALS_ROTATING - )) - SSdcs.UnregisterSignal(source, COMSIG_ATOM_DIR_CHANGE) - source.update_appearance(UPDATE_OVERLAYS) - if(isitem(source)) - INVOKE_ASYNC(source, TYPE_PROC_REF(/obj/item/, update_slot_icon)) - return ..() - -/datum/element/decal/proc/apply_overlay(atom/source) - SIGNAL_HANDLER // COMSIG_ATOM_UPDATE_OVERLAYS - - source.add_overlay(pic) - // TODO: Fix this disgusting hack - // - // `COMSIG_ATOM_UPDATE_OVERLAYS` is sent at the end of - // /atom/proc/update_icon's stanza for updating overlays, instead - // somewhere useful, like, during it. /tg/ handles this by sending - // a list of overlays with the signal, allowing receivers to add to - // the list, instead of returning their own. - // - // This is much saner and more flexible, but would require refactoring - // many many uses of update_overlay() across the code base, which is left - // as an exercise for the next poor sap to touch this code (probably me). - if(source.managed_overlays && !islist(source.managed_overlays)) - source.managed_overlays = list(source.managed_overlays, pic) - else - LAZYDISTINCTADD(source.managed_overlays, pic) - -/datum/element/decal/proc/clean_react(datum/source, clean_types) - SIGNAL_HANDLER // COMSIG_COMPONENT_CLEAN_ACT - - if(clean_types & cleanable) - Detach(source) - return COMPONENT_CLEANED - return NONE - -/datum/element/decal/proc/examine(datum/source, mob/user, list/examine_list) - SIGNAL_HANDLER // COMSIG_PARENT_EXAMINE - - examine_list += description - -/datum/element/decal/proc/shuttle_move_react(datum/source, turf/new_turf) - SIGNAL_HANDLER // COMSIG_TURF_ON_SHUTTLE_MOVE - - if(new_turf == source) - return - Detach(source) - new_turf.AddElement(type, pic.icon, base_icon_state, directional, pic.layer, pic.alpha, pic.color, cleanable, description) - -/datum/element/decal/proc/get_decals(datum/source, list/datum/element/decal/rotating) - SIGNAL_HANDLER // COMSIG_ATOM_DECALS_ROTATING - rotating += src diff --git a/code/datums/elements/high_value_item.dm b/code/datums/elements/high_value_item.dm deleted file mode 100644 index dd34bafa096e0..0000000000000 --- a/code/datums/elements/high_value_item.dm +++ /dev/null @@ -1,22 +0,0 @@ -GLOBAL_LIST_EMPTY(high_value_items) - -/datum/element/high_value_item - element_flags = ELEMENT_DETACH_ON_HOST_DESTROY - -/datum/element/high_value_item/Attach(datum/target) - . = ..() - if(!isatom(target)) - return ELEMENT_INCOMPATIBLE - GLOB.high_value_items |= target - -/datum/element/high_value_item/Detach(datum/source, force) - . = ..() - var/turf/turf_loc = get_turf(source) - if(turf_loc) - message_admins("[source] has been destroyed in [get_area(turf_loc)] at [ADMIN_COORDJMP(turf_loc)].") - log_game("[source] has been destroyed at ([turf_loc.x],[turf_loc.y],[turf_loc.z]) in the location [turf_loc.loc].") - else - message_admins("[source] has been destroyed in nullspace.") - log_game("[source] has been destroyed in nullspace.") - GLOB.high_value_items -= source - diff --git a/code/datums/elements/rust_element.dm b/code/datums/elements/rust_element.dm deleted file mode 100644 index d2464e016df77..0000000000000 --- a/code/datums/elements/rust_element.dm +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Adding this element to an atom will have it automatically render an overlay. - */ -/datum/element/rust - element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH_ON_HOST_DESTROY // Detach for turfs - argument_hash_start_idx = 2 - /// The rust image itself, since the icon and icon state are only used as an argument - var/image/rust_overlay - -/datum/element/rust/Attach(atom/target, rust_icon = 'icons/effects/rust_overlay.dmi', rust_icon_state = "rust_default") - . = ..() - if(!isatom(target)) - return ELEMENT_INCOMPATIBLE - - rust_overlay = image(rust_icon, "rust[rand(1, 6)]") - ADD_TRAIT(target, TRAIT_RUSTY, "rusted_turf") - RegisterSignal(target, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(apply_rust_overlay)) - RegisterSignal(target, COMSIG_PARENT_EXAMINE, PROC_REF(handle_examine)) - RegisterSignal(target, COMSIG_INTERACT_TARGET, PROC_REF(on_interaction)) - RegisterSignal(target, COMSIG_TOOL_ATTACK, PROC_REF(welder_tool_act)) - // Unfortunately registering with parent sometimes doesn't cause an overlay update - target.update_appearance() - -/datum/element/rust/Detach(atom/source) - . = ..() - UnregisterSignal(source, COMSIG_ATOM_UPDATE_OVERLAYS) - UnregisterSignal(source, COMSIG_PARENT_EXAMINE) - UnregisterSignal(source, COMSIG_TOOL_ATTACK) - UnregisterSignal(source, COMSIG_INTERACT_TARGET) - REMOVE_TRAIT(source, TRAIT_RUSTY, "rusted_turf") - source.cut_overlays() - source.update_appearance() - -/datum/element/rust/proc/handle_examine(datum/source, mob/user, list/examine_list) - SIGNAL_HANDLER //COMSIG_PARENT_EXAMINE - - examine_list += "[source] is very rusty, you could probably burn it off." - -/datum/element/rust/proc/apply_rust_overlay(atom/parent_atom, list/overlays) - SIGNAL_HANDLER //COMSIG_ATOM_UPDATE_OVERLAYS - - if(rust_overlay) - parent_atom.add_overlay(rust_overlay) - -/// Because do_after sleeps we register the signal here and defer via an async call -/datum/element/rust/proc/welder_tool_act(atom/source, obj/item/item, mob/user) - SIGNAL_HANDLER // COMSIG_TOOL_ATTACK - - INVOKE_ASYNC(src, PROC_REF(handle_tool_use), source, item, user) - return COMPONENT_CANCEL_TOOLACT - -/// We call this from secondary_tool_act because we sleep with do_after -/datum/element/rust/proc/handle_tool_use(atom/source, obj/item/item, mob/user) - switch(item.tool_behaviour) - if(TOOL_WELDER) - if(!item.tool_start_check(source, user, amount=1)) - return - to_chat(user, "You start burning off the rust...") - - if(!item.use_tool(source, user, 5 SECONDS, volume = item.tool_volume)) - return - to_chat(user, "You burn off the rust!") - Detach(source) - return - -/// Prevents placing floor tiles on rusted turf -/datum/element/rust/proc/on_interaction(datum/source, mob/living/user, obj/item/tool, list/modifiers) - SIGNAL_HANDLER // COMSIG_INTERACT_TARGET - if(istype(tool, /obj/item/stack/tile) || istype(tool, /obj/item/stack/rods) || istype(tool, /obj/item/rcd)) - to_chat(user, "[source] is too rusted to build on!") - return ITEM_INTERACT_COMPLETE - -/// For rust applied by heretics (if that ever happens) / revenants -/datum/element/rust/heretic - -/datum/element/rust/heretic/Attach(atom/target, rust_icon, rust_icon_state) - . = ..() - if(. == ELEMENT_INCOMPATIBLE) - return . - RegisterSignal(target, COMSIG_ATOM_ENTERED, PROC_REF(on_entered)) - RegisterSignal(target, COMSIG_ATOM_EXITED, PROC_REF(on_exited)) - -/datum/element/rust/heretic/Detach(atom/source) - . = ..() - UnregisterSignal(source, COMSIG_ATOM_ENTERED) - UnregisterSignal(source, COMSIG_ATOM_EXITED) - for(var/obj/effect/glowing_rune/rune_to_remove in source) - qdel(rune_to_remove) - for(var/mob/living/victim in source) - victim.remove_status_effect(STATUS_EFFECT_RUST_CORRUPTION) - -/datum/element/rust/heretic/proc/on_entered(turf/source, atom/movable/entered, ...) - SIGNAL_HANDLER - - if(!isliving(entered)) - return - var/mob/living/victim = entered - if(istype(victim, /mob/living/simple_animal/revenant)) - return - victim.apply_status_effect(STATUS_EFFECT_RUST_CORRUPTION) - -/datum/element/rust/heretic/proc/on_exited(turf/source, atom/movable/gone) - SIGNAL_HANDLER - if(!isliving(gone)) - return - var/mob/living/leaver = gone - leaver.remove_status_effect(STATUS_EFFECT_RUST_CORRUPTION) - -// Small visual effect imparted onto rusted things by revenants. -/obj/effect/glowing_rune - icon = 'icons/effects/eldritch.dmi' - icon_state = "small_rune_1" - anchored = TRUE - plane = FLOOR_PLANE - layer = SIGIL_LAYER - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/obj/effect/glowing_rune/Initialize(mapload) - . = ..() - pixel_y = rand(-6, 6) - pixel_x = rand(-6, 6) - icon_state = "small_rune_[rand(1, 12)]" - update_appearance() diff --git a/code/datums/elements/shatters_when_thrown.dm b/code/datums/elements/shatters_when_thrown.dm deleted file mode 100644 index 06cdc23dd65b8..0000000000000 --- a/code/datums/elements/shatters_when_thrown.dm +++ /dev/null @@ -1,55 +0,0 @@ -/** - * When attached to something, will make that thing shatter into shards on throw impact or z level falling - */ -/datum/element/shatters_when_thrown - element_flags = ELEMENT_BESPOKE - argument_hash_start_idx = 2 - /// What type of item is spawned as a 'shard' once the shattering happens - var/obj/item/shard_type - /// How many shards total are made when the thing we're attached to shatters - var/number_of_shards - /// What sound plays when the thing we're attached to shatters - var/shattering_sound - -/datum/element/shatters_when_thrown/Attach(datum/target, shard_type = /obj/item/shard, number_of_shards = 5, shattering_sound = "shatter") - . = ..() - - if(!ismovable(target)) - return ELEMENT_INCOMPATIBLE - - src.shard_type = shard_type - src.number_of_shards = number_of_shards - src.shattering_sound = shattering_sound - - RegisterSignal(target, COMSIG_MOVABLE_IMPACT, PROC_REF(on_throw_impact)) - -/datum/element/shatters_when_thrown/Detach(datum/target) - . = ..() - - UnregisterSignal(target,COMSIG_MOVABLE_IMPACT) - -/// Tells the parent to shatter if we are thrown and impact something -/datum/element/shatters_when_thrown/proc/on_throw_impact(datum/source, atom/hit_atom) - SIGNAL_HANDLER - INVOKE_ASYNC(src, PROC_REF(shatter), source, hit_atom) - -/// Handles the actual shattering part, throwing shards of whatever is defined on the component everywhere -/datum/element/shatters_when_thrown/proc/shatter(atom/movable/source, atom/hit_atom) - var/generator/scatter_gen = generator(GEN_CIRCLE, 0, 48, NORMAL_RAND) - var/scatter_turf = get_turf(hit_atom) - - for(var/obj/item/scattered_item as anything in source.contents) - scattered_item.forceMove(scatter_turf) - var/list/scatter_vector = scatter_gen.Rand() - scattered_item.pixel_x = scatter_vector[1] - scattered_item.pixel_y = scatter_vector[2] - - for(var/iteration in 1 to number_of_shards) - var/obj/item/shard = new shard_type(scatter_turf) - shard.scatter_atom() - playsound(scatter_turf, shattering_sound, 60, TRUE) - if(isobj(source)) - var/obj/obj_source = source - obj_source.deconstruct(FALSE) - return - qdel(source) diff --git a/code/datums/elements/strippable.dm b/code/datums/elements/strippable.dm deleted file mode 100644 index d30135dcf2aff..0000000000000 --- a/code/datums/elements/strippable.dm +++ /dev/null @@ -1,502 +0,0 @@ -#define SHOW_MINIATURE_MENU 0 -#define SHOW_FULLSIZE_MENU 1 -/// 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_ON_HOST_DESTROY - argument_hash_start_idx = 2 - - /// An assoc list of keys to /datum/strippable_item - var/list/items - - /// An existing strip menus - var/list/strip_menus - -/datum/element/strippable/Attach(datum/target, list/items = list()) - . = ..() - if(!isatom(target)) - return ELEMENT_INCOMPATIBLE - - RegisterSignal(target, COMSIG_DO_MOB_STRIP, PROC_REF(mouse_drop_onto)) - - src.items = items - -/datum/element/strippable/Detach(datum/source) - . = ..() - - UnregisterSignal(source, COMSIG_DO_MOB_STRIP) - - 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 - - var/datum/strip_menu/strip_menu = LAZYACCESS(strip_menus, source) - - if(isnull(strip_menu)) - strip_menu = new(source, src) - LAZYSET(strip_menus, source, strip_menu) - - INVOKE_ASYNC(strip_menu, TYPE_PROC_REF(/datum, ui_interact), user) - -/// A representation of an item that can be stripped down -/datum/strippable_item - /// The STRIPPABLE_ITEM_* key - var/key - - -/// Gets the item from the given source. -/datum/strippable_item/proc/get_item(atom/source) - return - -/// 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(equipping.flags & NODROP) - to_chat(user, "You can't put [equipping] on [source], it's stuck to your hand!") - return FALSE - - if(equipping.flags & ABSTRACT) - return FALSE //I don't know a sane-sounding feedback message for trying to put a slap into someone's hand - - 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(!in_thief_mode(user)) - source.visible_message( - "[user] tries to put [equipping] on [source].", - "[user] tries to put [equipping] on you.", - ) - if(ishuman(source)) - var/mob/living/carbon/human/victim_human = source - if(!victim_human.has_vision()) - to_chat(victim_human, "You feel someone trying to put something on you.") - - if(!do_mob(user, source, equipping.put_on_delay)) - return FALSE - - if(QDELETED(equipping) || !user.Adjacent(source) || (equipping.flags & NODROP)) - return 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 - -/// 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 - - to_chat(user, "You try to remove [source]'s [item.name]...") - add_attack_logs(user, source, "Attempting stripping of [item]") - item.add_fingerprint(user) - - if(!in_thief_mode(user)) - source.visible_message( - "[user] tries to remove [source]'s [item.name].", - "[user] tries to remove your [item.name].", - "You hear rustling." - ) - if(ishuman(source)) - var/mob/living/carbon/human/victim_human = source - if(!victim_human.has_vision()) - to_chat(source, "You feel someone fumble with your belongings.") - - return start_unequip_mob(get_item(source), source, user) - -/// The proc that unequips the item from the source. This should not yield. -/datum/strippable_item/proc/finish_unequip(atom/source, mob/user) - SHOULD_NOT_SLEEP(TRUE) - return - -/// 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_actions(atom/source, mob/user) - return null - -/** - * Actions that can happen to that body part, regardless if there is an item or not. As long as it is not obscured - */ -/datum/strippable_item/proc/get_body_action(atom/source, mob/user) - return - -/// Performs an alternative action on this strippable_item. -/// `has_alternate_action` needs to be TRUE. -/// Returns FALSE if blocked by signal, TRUE otherwise. -/datum/strippable_item/proc/alternate_action(atom/source, mob/user, action_key) - SHOULD_CALL_PARENT(TRUE) - return TRUE - -/// Returns whether or not this item should show. -/datum/strippable_item/proc/should_show(atom/source, mob/user) - return TRUE - -/// Returns whether the user is in "thief mode" where stripping/equipping is silent and stealing from pockets moves stuff to your hands -/datum/strippable_item/proc/in_thief_mode(mob/user) - if(!ishuman(user)) - return FALSE - var/mob/living/carbon/human/H = usr - var/obj/item/clothing/gloves/G = H.gloves - return G?.pickpocket - -/// 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, item_slot, disable_warning = TRUE)) - to_chat(user, "\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(!equipping.mob_can_equip(source, item_slot, disable_warning = TRUE)) - return FALSE - - return TRUE - -/datum/strippable_item/mob_item_slot/finish_equip(atom/source, obj/item/equipping, mob/user) - if(!ismob(source)) - return FALSE - - var/mob/mob_source = source - mob_source.equip_to_slot(equipping, item_slot) - - add_attack_logs(user, source, "Strip equipped [equipping]") - -/datum/strippable_item/mob_item_slot/get_obscuring(atom/source) - if(ishuman(source)) - var/mob/living/carbon/human/human_source = source - if(item_slot & human_source.check_obscured_slots()) - return STRIPPABLE_OBSCURING_COMPLETELY - return STRIPPABLE_OBSCURING_NONE - - return FALSE - -/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 - - INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(finish_unequip_mob), item, source, user) - if(in_thief_mode(user)) - INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, put_in_hands), item) - -/// 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.put_on_delay - -/// 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) - if(!strip_delay) - strip_delay = item.strip_delay - if(!do_mob(user, source, strip_delay)) - 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(!source.drop_item_to_ground(item)) - return - - add_attack_logs(user, source, "Stripping of [item]") - -/// 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 - - /// Associated list of "[icon][icon_state]" = base64 representation of icon. Used for PERFORMANCE. - var/static/list/base64_cache = list() - -/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 - - var/obj/item/item = item_data.get_item(owner) - if(item && (item.flags & ABSTRACT || HAS_TRAIT(item, TRAIT_NO_STRIP) || HAS_TRAIT(item, TRAIT_SKIP_EXAMINE))) - items[strippable_key] = result - continue - - if(strippable_key in LAZYACCESS(interactions, user)) - LAZYSET(result, "interacting", TRUE) - - var/obscuring = item_data.get_obscuring(owner) - if(obscuring == STRIPPABLE_OBSCURING_COMPLETELY || (item && !item.canStrip(user))) - LAZYSET(result, "cantstrip", TRUE) - - if(obscuring != STRIPPABLE_OBSCURING_NONE) - LAZYSET(result, "obscured", obscuring) - items[strippable_key] = result - continue - - var/alternates = item_data.get_body_action(owner, user) - if(!islist(alternates) && !isnull(alternates)) - alternates = list(alternates) - - if(isnull(item)) - if(length(alternates)) - LAZYSET(result, "alternates", alternates) - items[strippable_key] = result - continue - - LAZYINITLIST(result) - - var/key = "[item.icon],[item.icon_state]" - if(!(key in base64_cache)) - base64_cache[key] = icon2base64(icon(item.icon, item.icon_state, dir = SOUTH, frame = 1, moving = FALSE)) - result["icon"] = base64_cache[key] - result["name"] = item.name - - var/real_alts = item_data.get_alternate_actions(owner, user) - if(!isnull(real_alts)) - if(islist(alternates)) - alternates += real_alts - else - alternates = real_alts - if(!islist(alternates) && !isnull(alternates)) - alternates = list(alternates) - result["alternates"] = alternates - - 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]" - data["show_mode"] = user.client.prefs.toggles2 & PREFTOGGLE_2_BIG_STRIP_MENU ? SHOW_FULLSIZE_MENU : SHOW_MINIATURE_MENU - - return data - -/datum/strip_menu/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - . = ..() - if(.) - return - - var/mob/living/user = ui.user - if(!isliving(ui.user) || !HAS_TRAIT(user, TRAIT_CAN_STRIP)) - return - - . = TRUE - 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_hand() - if(isnull(held_item)) - return - - if(strippable_item.try_equip(owner, held_item, user)) - LAZYORASSOCLIST(interactions, user, key) - - // Update just before the delay starts - SStgui.update_uis(src) - // 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, or they're no longer adjacent - if(!isnull(strippable_item.get_item(owner)) || !user.Adjacent(owner)) - return - - // make sure to drop the item - if(!user.drop_item_to_ground(held_item)) - return - - strippable_item.finish_equip(owner, held_item, user) - else if(strippable_item.try_unequip(owner, user)) - LAZYORASSOCLIST(interactions, user, key) - - // Update just before the delay starts - SStgui.update_uis(src) - 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 - - if(isnull(strippable_item.get_body_action(owner, user))) - var/item = strippable_item.get_item(owner) - if(isnull(item) || isnull(strippable_item.get_alternate_actions(owner, user))) - return - - LAZYORASSOCLIST(interactions, user, key) - - // Update just before the delay starts - SStgui.update_uis(src) - // Potentially yielding - strippable_item.alternate_action(owner, user, params["action_key"]) - - LAZYREMOVEASSOC(interactions, user, key) - -/datum/strip_menu/ui_host(mob/user) - return owner - -/datum/strip_menu/ui_state(mob/user) - return GLOB.strippable_state - -/// 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 - -#undef SHOW_MINIATURE_MENU -#undef SHOW_FULLSIZE_MENU diff --git a/code/datums/helper_datums/map_template.dm b/code/datums/helper_datums/map_template.dm deleted file mode 100644 index 08437daa6097c..0000000000000 --- a/code/datums/helper_datums/map_template.dm +++ /dev/null @@ -1,188 +0,0 @@ -/datum/map_template - var/name = "Default Template Name" - var/width = 0 - var/height = 0 - var/mappath = null - var/mapfile = null - var/loaded = 0 // Times loaded this round - /// Do we exclude this from CI checks? If so, set this to the templates pathtype itself to avoid it getting passed down - var/ci_exclude = null // DO NOT SET THIS IF YOU DO NOT KNOW WHAT YOU ARE DOING - -/datum/map_template/New(path = null, map = null, rename = null) - if(path) - mappath = path - if(mappath) - preload_size(mappath) - if(map) - mapfile = map - if(rename) - name = rename - -/datum/map_template/proc/preload_size(path) - var/bounds = GLOB.maploader.load_map(file(path), 1, 1, 1, shouldCropMap = FALSE, measureOnly = TRUE) - if(bounds) - width = bounds[MAP_MAXX] // Assumes all templates are rectangular, have a single Z level, and begin at 1,1,1 - height = bounds[MAP_MAXY] - return bounds - -/datum/map_template/proc/load(turf/T, centered = 0) - var/turf/placement = T - var/min_x = placement.x - var/min_y = placement.y - if(centered) - min_x -= round(width/2) - min_y -= round(height/2) - - var/max_x = min_x + width - 1 - var/max_y = min_y + height - 1 - - if(!T) - return 0 - - var/turf/bot_left = locate(max(1, min_x), max(1, min_y), placement.z) - var/turf/top_right = locate(min(world.maxx, max_x), min(world.maxy, max_y), placement.z) - - // 1 bigger, to update the turf smoothing - var/turf/ST_bot_left = locate(max(1, min_x-1), max(1, min_y-1), placement.z) - var/turf/ST_top_right = locate(min(world.maxx, max_x+1), min(world.maxy, max_y+1), placement.z) - // This is to place a freeze on initialization until the map's done loading - // otherwise atmos and stuff will start running mid-load - // This system will metaphorically snap in half (not postpone init everywhere) - // if given a multi-z template - // it might need to be adapted for that when that time comes - GLOB.space_manager.add_dirt(placement.z) - try - var/list/bounds = GLOB.maploader.load_map(get_file(), min_x, min_y, placement.z, shouldCropMap = TRUE) - if(!bounds) - return 0 - if(bot_left == null || top_right == null) - stack_trace("One of the late setup corners is bust") - - if(ST_bot_left == null || ST_top_right == null) - stack_trace("One of the smoothing corners is bust") - catch(var/exception/e) - GLOB.space_manager.remove_dirt(placement.z) - var/datum/milla_safe_must_sleep/late_setup_level/milla = new() - milla.invoke_async(bot_left, top_right, block(ST_bot_left, ST_top_right)) - message_admins("Map template [name] threw an error while loading. Safe exit attempted, but check for errors at [ADMIN_COORDJMP(placement)].") - log_admin("Map template [name] threw an error while loading. Safe exit attempted.") - throw e - GLOB.space_manager.remove_dirt(placement.z) - var/datum/milla_safe_must_sleep/late_setup_level/milla = new() - milla.invoke_async(bot_left, top_right, block(ST_bot_left, ST_top_right)) - - log_game("[name] loaded at [min_x],[min_y],[placement.z]") - return 1 - -/datum/map_template/proc/get_file() - if(mapfile) - . = mapfile - else if(mappath) - . = wrap_file(mappath) - - if(!.) - stack_trace(" The file of [src] appears to be empty/non-existent.") - -/datum/map_template/proc/get_affected_turfs(turf/T, centered = 0) - var/list/coordinate_bounds = get_coordinate_bounds(T, centered) - var/datum/coords/bottom_left = coordinate_bounds["bottom_left"] - var/datum/coords/top_right = coordinate_bounds["top_right"] - return block(max(bottom_left.x_pos, 1), max(bottom_left.y_pos, 1), T.z, min(top_right.x_pos, world.maxx), min(top_right.y_pos, world.maxy), T.z) - -/datum/map_template/proc/get_coordinate_bounds(turf/T, centered = FALSE) - var/turf/placement = T - var/min_x = placement.x - var/min_y = placement.y - if(centered) - min_x -= round(width/2) - min_y -= round(height/2) - - var/max_x = min_x + width-1 - var/max_y = min_y + height-1 - - var/datum/coords/bottom_left = new(min_x, min_y, 1) - var/datum/coords/top_right = new(max_x, max_y, 1) - return list("bottom_left" = bottom_left, "top_right" = top_right) - -/datum/map_template/proc/fits_in_map_bounds(turf/T, centered = 0) - var/turf/placement = T - var/min_x = placement.x - var/min_y = placement.y - if(centered) - min_x -= round(width/2) - min_y -= round(height/2) - - var/max_x = min_x + width-1 - var/max_y = min_y + height-1 - if(min_x < 1 || min_y < 1 || max_x > world.maxx || max_y > world.maxy) - return FALSE - else - return TRUE - - -/proc/preloadTemplates(path = "_maps/map_files/templates/") //see master controller setup - for(var/map in flist(path)) - if(cmptext(copytext(map, length(map) - 3), ".dmm")) - var/datum/map_template/T = new(path = "[path][map]", rename = "[map]") - GLOB.map_templates[T.name] = T - - if(GLOB.configuration.ruins.enable_space_ruins) // so we don't unnecessarily clutter start-up - preloadRuinTemplates() - preloadShelterTemplates() - preloadShuttleTemplates() - preloadEventTemplates() - -/proc/preloadRuinTemplates() - // Merge the active lists together - var/list/space_ruins = GLOB.configuration.ruins.active_space_ruins.Copy() - var/list/lava_ruins = GLOB.configuration.ruins.active_lava_ruins.Copy() - var/list/all_ruins = space_ruins | lava_ruins - - for(var/item in subtypesof(/datum/map_template/ruin)) - var/datum/map_template/ruin/ruin_type = item - // screen out the abstract subtypes - if(!initial(ruin_type.id)) - continue - var/datum/map_template/ruin/R = new ruin_type() - - // If not in the active list, skip it - if(!(R.mappath in all_ruins)) - continue - - GLOB.map_templates[R.name] = R - - if(istype(R, /datum/map_template/ruin/lavaland)) - GLOB.lava_ruins_templates[R.name] = R - if(istype(R, /datum/map_template/ruin/space)) - GLOB.space_ruins_templates[R.name] = R - -/proc/preloadShelterTemplates() - for(var/item in subtypesof(/datum/map_template/shelter)) - var/datum/map_template/shelter/shelter_type = item - if(!(initial(shelter_type.mappath))) - continue - var/datum/map_template/shelter/S = new shelter_type() - - GLOB.shelter_templates[S.shelter_id] = S - GLOB.map_templates[S.shelter_id] = S - -/proc/preloadShuttleTemplates() - for(var/item in subtypesof(/datum/map_template/shuttle)) - var/datum/map_template/shuttle/shuttle_type = item - if(!initial(shuttle_type.suffix)) - continue - - var/datum/map_template/shuttle/S = new shuttle_type() - - GLOB.shuttle_templates[S.shuttle_id] = S - GLOB.map_templates[S.shuttle_id] = S - -/proc/preloadEventTemplates() - for(var/item in subtypesof(/datum/map_template/event)) - var/datum/map_template/event/event_type = item - if(!initial(event_type.mappath)) - continue - - var/datum/map_template/event/E = new event_type() - - GLOB.map_templates[E.event_id] = E diff --git a/code/datums/keybindings/emote_keybinds.dm b/code/datums/keybindings/emote_keybinds.dm deleted file mode 100644 index a021b95995fb5..0000000000000 --- a/code/datums/keybindings/emote_keybinds.dm +++ /dev/null @@ -1,732 +0,0 @@ -/datum/keybinding/emote - category = KB_CATEGORY_EMOTE_GENERIC - var/datum/emote/linked_emote - -/datum/keybinding/emote/can_use(client/C, mob/M) - return ..() //We don't need custom logic here as emotes handle their own useability, see USABLE_DEAD_EMOTES - -/datum/keybinding/emote/down(client/user) - . = ..() - user.mob.emote(initial(linked_emote.key), intentional = TRUE) - -/datum/keybinding/emote/flip - linked_emote = /datum/emote/flip - name = "Flip" - -/datum/keybinding/emote/spin - linked_emote = /datum/emote/spin - name = "Spin" - -/datum/keybinding/emote/blush - linked_emote = /datum/emote/living/blush - name = "Blush" - -/datum/keybinding/emote/bow - linked_emote = /datum/emote/living/bow - name = "Bow" - -/datum/keybinding/emote/burp - linked_emote = /datum/emote/living/burp - name = "Burp" - -/datum/keybinding/emote/choke - linked_emote = /datum/emote/living/choke - name = "Choke" - -/datum/keybinding/emote/collapse - linked_emote = /datum/emote/living/collapse - name = "Collapse" - -/datum/keybinding/emote/dance - linked_emote = /datum/emote/living/dance - name = "Dance" - -/datum/keybinding/emote/jump - linked_emote = /datum/emote/living/jump - name = "Jump" - -/datum/keybinding/emote/deathgasp - linked_emote = /datum/emote/living/deathgasp - name = "Deathgasp" - -/datum/keybinding/emote/drool - linked_emote = /datum/emote/living/drool - name = "Drool" - -/datum/keybinding/emote/quiver - linked_emote = /datum/emote/living/quiver - name = "Quiver" - -/datum/keybinding/emote/frown - linked_emote = /datum/emote/living/frown - name = "Frown" - -/datum/keybinding/emote/gag - linked_emote = /datum/emote/living/gag - name = "Gag" - -/datum/keybinding/emote/glare - linked_emote = /datum/emote/living/glare - name = "Glare" - -/datum/keybinding/emote/grin - linked_emote = /datum/emote/living/grin - name = "Grin" - -/datum/keybinding/emote/grimace - linked_emote = /datum/emote/living/grimace - name = "Grimace" - -/datum/keybinding/emote/groan - linked_emote = /datum/emote/living/groan - name = "Groan" - -/datum/keybinding/emote/look - linked_emote = /datum/emote/living/look - name = "Look" - -/datum/keybinding/emote/bshake - linked_emote = /datum/emote/living/bshake - name = "Shake" - -/datum/keybinding/emote/shudder - linked_emote = /datum/emote/living/shudder - name = "Shudder" - -/datum/keybinding/emote/point - linked_emote = /datum/emote/living/point - name = "Point" - -/datum/keybinding/emote/pout - linked_emote = /datum/emote/living/pout - name = "Pout" - -/datum/keybinding/emote/scream - linked_emote = /datum/emote/living/scream - name = "Scream" - -/datum/keybinding/emote/shake - linked_emote = /datum/emote/living/shake - name = "Head Shake" - -/datum/keybinding/emote/shiver - linked_emote = /datum/emote/living/shiver - name = "Shiver" - -/datum/keybinding/emote/sigh - linked_emote = /datum/emote/living/sigh - name = "Sigh" - -/datum/keybinding/emote/happy - linked_emote = /datum/emote/living/sigh/happy - name = "Sigh (Happy)" - -/datum/keybinding/emote/sit - linked_emote = /datum/emote/living/sit - name = "Sit" - -/datum/keybinding/emote/smile - linked_emote = /datum/emote/living/smile - name = "Smile" - -/datum/keybinding/emote/smug - linked_emote = /datum/emote/living/smug - name = "Smug" - -/datum/keybinding/emote/sniff - linked_emote = /datum/emote/living/sniff - name = "Sniff" - -/datum/keybinding/emote/snore - linked_emote = /datum/emote/living/snore - name = "Snore" - -/datum/keybinding/emote/nightmare - linked_emote = /datum/emote/living/nightmare - name = "Nightmare" - -/datum/keybinding/emote/stare - linked_emote = /datum/emote/living/stare - name = "Stare" - -/datum/keybinding/emote/stretch - linked_emote = /datum/emote/living/strech - name = "Stretch" - -/datum/keybinding/emote/sulk - linked_emote = /datum/emote/living/sulk - name = "Sulk" - -/datum/keybinding/emote/sway - linked_emote = /datum/emote/living/sway - name = "Sway" - -/datum/keybinding/emote/swear - linked_emote = /datum/emote/living/swear - name = "Swear" - -/datum/keybinding/emote/tilt - linked_emote = /datum/emote/living/tilt - name = "Tilt" - -/datum/keybinding/emote/tremble - linked_emote = /datum/emote/living/tremble - name = "Tremble" - -/datum/keybinding/emote/twitch - linked_emote = /datum/emote/living/twitch - name = "Twitch (Violent)" - -/datum/keybinding/emote/twitch_s - linked_emote = /datum/emote/living/twitch_s - name = "Twitch" - -/datum/keybinding/emote/whimper - linked_emote = /datum/emote/living/whimper - name = "Whimper" - -/datum/keybinding/emote/wsmile - linked_emote = /datum/emote/living/wsmile - name = "Smile (Weak)" - -/datum/keybinding/emote/carbon - category = KB_CATEGORY_EMOTE_CARBON - -/datum/keybinding/emote/carbon/can_use(client/C, mob/M) - return iscarbon(M) && ..() - -/datum/keybinding/emote/carbon/blink - linked_emote = /datum/emote/living/carbon/blink - name = "Blink" - -/datum/keybinding/emote/carbon/blink_r - linked_emote = /datum/emote/living/carbon/blink_r - name = "Blink (Rapid)" - -/datum/keybinding/emote/carbon/cross - linked_emote = /datum/emote/living/carbon/cross - name = "Cross Arms" - -/datum/keybinding/emote/carbon/chuckle - linked_emote = /datum/emote/living/carbon/chuckle - name = "Chuckle" - -/datum/keybinding/emote/carbon/cough - linked_emote = /datum/emote/living/carbon/cough - name = "Cough" - -/datum/keybinding/emote/carbon/moan - linked_emote = /datum/emote/living/carbon/moan - name = "Moan" - -/datum/keybinding/emote/carbon/giggle - linked_emote = /datum/emote/living/carbon/giggle - name = "Giggle" - -/datum/keybinding/emote/carbon/gurgle - linked_emote = /datum/emote/living/carbon/gurgle - name = "Gurgle" - -/datum/keybinding/emote/carbon/inhale - linked_emote = /datum/emote/living/carbon/inhale - name = "Inhale" - -/datum/keybinding/emote/carbon/inhale/sharp - linked_emote = /datum/emote/living/carbon/inhale/sharp - name = "Inhale (Sharp)" - -/datum/keybinding/emote/carbon/kiss - linked_emote = /datum/emote/living/carbon/kiss - name = "Kiss" //PG13 - -/datum/keybinding/emote/carbon/wave - linked_emote = /datum/emote/living/carbon/wave - name = "Wave" - -/datum/keybinding/emote/carbon/yawn - linked_emote = /datum/emote/living/carbon/yawn - name = "Yawn" - -/datum/keybinding/emote/carbon/exhale - linked_emote = /datum/emote/living/carbon/exhale - name = "Exhale" - -/datum/keybinding/emote/carbon/laugh - linked_emote = /datum/emote/living/carbon/laugh - name = "Laugh" - -/datum/keybinding/emote/carbon/scowl - linked_emote = /datum/emote/living/carbon/scowl - name = "Scowl" - -/datum/keybinding/emote/carbon/twirl - linked_emote = /datum/emote/living/carbon/twirl - name = "Twirl" - -/datum/keybinding/emote/carbon/faint - linked_emote = /datum/emote/living/carbon/faint - name = "Faint" - -/datum/keybinding/emote/carbon/sign - linked_emote = /datum/emote/living/carbon/sign - name = "Sign" - -/datum/keybinding/emote/carbon/alien - category = KB_CATEGORY_EMOTE_ALIEN - -/datum/keybinding/emote/carbon/alien/can_use(client/C, mob/M) - return isalien(M) && ..() - -/datum/keybinding/emote/carbon/alien/humanoid/roar - linked_emote = /datum/emote/living/carbon/alien_humanoid/roar - name = "Roar" - -/datum/keybinding/emote/carbon/alien/humanoid/hiss - linked_emote = /datum/emote/living/carbon/alien_humanoid/hiss - name = "Hiss" - -/datum/keybinding/emote/carbon/alien/humanoid/gnarl - linked_emote = /datum/emote/living/carbon/alien_humanoid/gnarl - name = "Gnarl" - -/datum/keybinding/emote/carbon/brain - category = KB_CATEGORY_EMOTE_BRAIN - -/datum/keybinding/emote/carbon/brain/can_use(client/C, mob/M) - return isbrain(M) && ..() - -/datum/keybinding/emote/carbon/brain/alarm - linked_emote = /datum/emote/living/brain/alarm - name = "Alarm" - -/datum/keybinding/emote/carbon/brain/alert - linked_emote = /datum/emote/living/brain/alert - name = "Alert" - -/datum/keybinding/emote/carbon/brain/notice - linked_emote = /datum/emote/living/brain/notice - name = "Notice" - -/datum/keybinding/emote/carbon/brain/flash - linked_emote = /datum/emote/living/brain/flash - name = "Flash" - -/datum/keybinding/emote/carbon/brain/whistle - linked_emote = /datum/emote/living/brain/whistle - name = "Whistle" - -/datum/keybinding/emote/carbon/brain/beep - linked_emote = /datum/emote/living/brain/beep - name = "Beep" - -/datum/keybinding/emote/carbon/brain/boop - linked_emote = /datum/emote/living/brain/boop - name = "Boop" - -/datum/keybinding/emote/carbon/human - category = KB_CATEGORY_EMOTE_HUMAN - -/datum/keybinding/emote/carbon/human/can_use(client/C, mob/M) - return ishuman(M) && ..() - -/datum/keybinding/emote/carbon/human/airguitar - linked_emote = /datum/emote/living/carbon/human/airguitar - name = "Airguitar" - -/datum/keybinding/emote/carbon/human/clap - linked_emote = /datum/emote/living/carbon/human/clap - name = "Clap" - -/datum/keybinding/emote/carbon/human/cry - linked_emote = /datum/emote/living/carbon/human/cry - name = "Cry" - -/datum/keybinding/emote/carbon/human/dap - linked_emote = /datum/emote/living/carbon/human/highfive/dap - name = "Dap" - -/datum/keybinding/emote/carbon/human/eyebrow - linked_emote = /datum/emote/living/carbon/human/eyebrow - name = "Eyebrow" - -/datum/keybinding/emote/carbon/human/facepalm - linked_emote = /datum/emote/living/carbon/human/facepalm - name = "Facepalm" - -/datum/keybinding/emote/carbon/human/grumble - linked_emote = /datum/emote/living/carbon/human/grumble - name = "Grumble" - -/datum/keybinding/emote/carbon/human/hug - linked_emote = /datum/emote/living/carbon/human/hug - name = "Hug" - -/datum/keybinding/emote/carbon/human/mumble - linked_emote = /datum/emote/living/carbon/human/mumble - name = "Mumble" - -/datum/keybinding/emote/carbon/human/nod - linked_emote = /datum/emote/living/carbon/human/nod - name = "Nod" - -/datum/keybinding/emote/carbon/human/palm - linked_emote = /datum/emote/living/carbon/human/palm - name = "Extend palm" - -/datum/keybinding/emote/carbon/human/scream - linked_emote = /datum/emote/living/carbon/human/scream - name = "Scream" - -/datum/keybinding/emote/carbon/human/gasp - linked_emote = /datum/emote/living/carbon/human/gasp - name = "Gasp" - -/datum/keybinding/emote/carbon/human/shake - linked_emote = /datum/emote/living/carbon/human/shake - name = "Shake Head" - -/datum/keybinding/emote/carbon/human/pale - linked_emote = /datum/emote/living/carbon/human/pale - name = "Pale" - -/datum/keybinding/emote/carbon/human/raise - linked_emote = /datum/emote/living/carbon/human/raise - name = "Raise" - -/datum/keybinding/emote/carbon/human/salute - linked_emote = /datum/emote/living/carbon/human/salute - name = "Salute" - -/datum/keybinding/emote/carbon/human/signal - linked_emote = /datum/emote/living/carbon/sign/signal - name = "Signal" - -/datum/keybinding/emote/carbon/human/shrug - linked_emote = /datum/emote/living/carbon/human/shrug - name = "Shrug" - -/datum/keybinding/emote/carbon/human/sniff - linked_emote = /datum/emote/living/carbon/human/sniff - name = "Sniff" - -/datum/keybinding/emote/carbon/human/johnny - linked_emote = /datum/emote/living/carbon/human/johnny - name = "Johnny" - -/datum/keybinding/emote/carbon/human/sneeze - linked_emote = /datum/emote/living/carbon/human/sneeze - name = "Sneeze" - -/datum/keybinding/emote/carbon/human/slap - linked_emote = /datum/emote/living/carbon/human/slap - name = "Slap" - -/datum/keybinding/emote/carbon/human/wince - linked_emote = /datum/emote/living/carbon/human/wince - name = "Wince" - -/datum/keybinding/emote/carbon/human/squint - linked_emote = /datum/emote/living/carbon/human/squint - name = "Squint" - -/datum/keybinding/emote/carbon/human/wink - linked_emote = /datum/emote/living/carbon/human/wink - name = "Wink" - -/datum/keybinding/emote/carbon/human/highfive - linked_emote = /datum/emote/living/carbon/human/highfive - name = "High Five" - -/datum/keybinding/emote/carbon/human/handshake - linked_emote = /datum/emote/living/carbon/human/highfive/handshake - name = "Handshake" - -/datum/keybinding/emote/carbon/human/snap - linked_emote = /datum/emote/living/carbon/human/snap - name = "Snap" - -/datum/keybinding/emote/carbon/human/crack - linked_emote = /datum/emote/living/carbon/human/crack - name = "Crack" - -/datum/keybinding/emote/carbon/human/fart - linked_emote = /datum/emote/living/carbon/human/fart - name = "Fart" - -/datum/keybinding/emote/carbon/human/wag - linked_emote = /datum/emote/living/carbon/human/wag - name = "Wag" - -/datum/keybinding/emote/carbon/human/wag/stop - linked_emote = /datum/emote/living/carbon/human/wag/stop - name = "Stop Wag" - -/datum/keybinding/emote/carbon/human/flap - linked_emote = /datum/emote/living/carbon/human/flap - name = "Flap" - -/datum/keybinding/emote/carbon/human/flap/angry - linked_emote = /datum/emote/living/carbon/human/flap/angry - name = "Angry Flap" - -/datum/keybinding/emote/carbon/human/flutter - linked_emote = /datum/emote/living/carbon/human/flutter - name = "Flutter" - -/datum/keybinding/emote/carbon/human/quill - linked_emote = /datum/emote/living/carbon/human/quill - name = "Quill" - -/datum/keybinding/emote/carbon/human/warble - linked_emote = /datum/emote/living/carbon/human/warble - name = "Warble" - -/datum/keybinding/emote/carbon/human/clack - linked_emote = /datum/emote/living/carbon/human/clack - name = "Clack" - -/datum/keybinding/emote/carbon/human/clack/click - linked_emote = /datum/emote/living/carbon/human/clack/click - name = "Click" - -/datum/keybinding/emote/carbon/human/drask_talk/drone - linked_emote = /datum/emote/living/carbon/human/drask_talk/drone - name = "Drone" - -/datum/keybinding/emote/carbon/human/drask_talk/hum - linked_emote = /datum/emote/living/carbon/human/drask_talk/hum - name = "Hum" - -/datum/keybinding/emote/carbon/human/drask_talk/rumble - linked_emote = /datum/emote/living/carbon/human/drask_talk/rumble - name = "Rumble" - -/datum/keybinding/emote/carbon/human/hiss - linked_emote = /datum/emote/living/carbon/human/hiss - name = "Hiss (Unathi)" - -/datum/keybinding/emote/carbon/human/creak - linked_emote = /datum/emote/living/carbon/human/creak - name = "Creak" - -/datum/keybinding/emote/carbon/human/squish - linked_emote = /datum/emote/living/carbon/human/slime/squish - name = "Squish" - -/datum/keybinding/emote/carbon/human/howl - linked_emote = /datum/emote/living/carbon/human/howl - name = "Howl" - -/datum/keybinding/emote/carbon/human/growl - linked_emote = /datum/emote/living/carbon/human/growl - name = "Growl" - -/datum/keybinding/emote/carbon/human/hiss/tajaran - linked_emote = /datum/emote/living/carbon/human/hiss/tajaran - name = "Hiss (Tajaran)" - -/datum/keybinding/emote/carbon/human/rattle - linked_emote = /datum/emote/living/carbon/human/rattle - name = "Rattle" - -/datum/keybinding/emote/carbon/human/bubble - linked_emote = /datum/emote/living/carbon/human/slime/bubble - name = "Bubble" - -/datum/keybinding/emote/carbon/human/pop - linked_emote = /datum/emote/living/carbon/human/slime/pop - name = "Pop" - -/datum/keybinding/emote/carbon/human/monkey/can_use(client/C, mob/M) - return ismonkeybasic(M) && ..() - -/datum/keybinding/emote/carbon/human/monkey/gnarl - linked_emote = /datum/emote/living/carbon/human/monkey/gnarl - name = "Gnarl (Monkey)" - -/datum/keybinding/emote/carbon/human/monkey/roll - linked_emote = /datum/emote/living/carbon/human/monkey/roll - name = "Roll (Monkey)" - -/datum/keybinding/emote/carbon/human/monkey/scratch - linked_emote = /datum/emote/living/carbon/human/monkey/scratch - name = "Scratch (Monkey)" - -/datum/keybinding/emote/carbon/human/monkey/tail - linked_emote = /datum/emote/living/carbon/human/monkey/tail - name = "Tail (Monkey)" - -/datum/keybinding/emote/carbon/human/monkey/screech - linked_emote = /datum/emote/living/carbon/human/scream/screech - name = "Screech (Monkey)" - -/datum/keybinding/emote/carbon/human/monkey/screech/roar - linked_emote = /datum/emote/living/carbon/human/scream/screech/roar - name = "Roar (Monkey)" - -/datum/keybinding/emote/silicon - category = KB_CATEGORY_EMOTE_SILICON - -/datum/keybinding/emote/silicon/can_use(client/C, mob/M) - return (issilicon(M) || ismachineperson(M)) && ..() - -/datum/keybinding/emote/silicon/scream - linked_emote = /datum/emote/living/silicon/scream - name = "Scream" - -/datum/keybinding/emote/silicon/ping - linked_emote = /datum/emote/living/silicon/ping - name = "Ping" - -/datum/keybinding/emote/silicon/buzz - linked_emote = /datum/emote/living/silicon/buzz - name = "Buzz" - -/datum/keybinding/emote/silicon/buzz2 - linked_emote = /datum/emote/living/silicon/buzz2 - name = "Buzzz" - -/datum/keybinding/emote/silicon/beep - linked_emote = /datum/emote/living/silicon/beep - name = "Beep" - -/datum/keybinding/emote/silicon/boop - linked_emote = /datum/emote/living/silicon/boop - name = "Boop" - -/datum/keybinding/emote/silicon/yes - linked_emote = /datum/emote/living/silicon/yes - name = "Yes" - -/datum/keybinding/emote/silicon/no - linked_emote = /datum/emote/living/silicon/no - name = "No" - -/datum/keybinding/emote/silicon/law - linked_emote = /datum/emote/living/silicon/law - name = "Law" - -/datum/keybinding/emote/silicon/halt - linked_emote = /datum/emote/living/silicon/halt - name = "Halt" - -/datum/keybinding/emote/simple_animal - category = KB_CATEGORY_EMOTE_ANIMAL - -/datum/keybinding/emote/simple_animal/can_use(client/C, mob/M) - return isanimal(M) && ..() - -/datum/keybinding/emote/simple_animal/diona_chirp - linked_emote = /datum/emote/living/simple_animal/diona_chirp - name = "Chirp (Nymph)" - -/datum/keybinding/emote/simple_animal/diona_chirp/can_use(client/C, mob/M) - return isnymph(M) && ..() - -/datum/keybinding/emote/simple_animal/gorilla_ooga - linked_emote = /datum/emote/living/simple_animal/gorilla/ooga - name = "Ooga (Gorilla)" - -/datum/keybinding/emote/simple_animal/gorilla_ooga/can_use(client/C, mob/M) - return isgorilla(M) && ..() - -/datum/keybinding/emote/simple_animal/pet/dog/bark - linked_emote = /datum/emote/living/simple_animal/pet/dog/bark - name = "Bark (Dog)" - -/datum/keybinding/emote/simple_animal/pet/dog/yelp - linked_emote = /datum/emote/living/simple_animal/pet/dog/yelp - name = "Yelp (Dog)" - -/datum/keybinding/emote/simple_animal/pet/dog/growl - linked_emote = /datum/emote/living/simple_animal/pet/dog/growl - name = "Growl (Dog)" - -/datum/keybinding/emote/simple_animal/pet/dog/can_use(client/C, mob/M) - return isdog(M) && ..() - -/datum/keybinding/emote/simple_animal/mouse/squeak - linked_emote = /datum/emote/living/simple_animal/mouse/squeak - name = "Squeak (Mouse)" - -/datum/keybinding/emote/simple_animal/mouse/can_use(client/C, mob/M) - return ismouse(M) && ..() - -/datum/keybinding/emote/simple_animal/pet/cat/meow - linked_emote = /datum/emote/living/simple_animal/pet/cat/meow - name = "Meow (Cat)" - -/datum/keybinding/emote/simple_animal/pet/cat/hiss - linked_emote = /datum/emote/living/simple_animal/pet/cat/hiss - name = "Hiss (Cat)" - -/datum/keybinding/emote/simple_animal/pet/cat/purr - linked_emote = /datum/emote/living/simple_animal/pet/cat/purr - name = "Purr (Cat)" - -/datum/keybinding/emote/simple_animal/pet/cat/sit - linked_emote = /datum/emote/living/sit/cat - name = "Sit/Stand (Cat)" - -/datum/keybinding/emote/simple_animal/pet/cat/can_use(client/C, mob/M) - return iscat(M) && ..() - -/datum/keybinding/custom - category = KB_CATEGORY_EMOTE_CUSTOM - var/default_emote_text = "Insert custom me emote text." - var/donor_exclusive = FALSE - -/datum/keybinding/custom/down(client/C) - . = ..() - if(!C.prefs?.active_character?.custom_emotes) //Checks the current character save for any custom emotes - return - - var/desired_emote = C.prefs.active_character.custom_emotes[name] //check the custom emotes list for this keybind name - - if(!desired_emote) - return - - C.mob.me_verb(html_decode(desired_emote)) //do the thing! - -/datum/keybinding/custom/can_use(client/C, mob/M) - if(donor_exclusive && !(C.donator_level || C.holder || C.prefs.unlock_content)) //is this keybind restricted to donors/byond members/admins, and are you one or not? - return - - return isliving(M) && ..() - -/datum/keybinding/custom/one - name = "Custom Emote 1" - -/datum/keybinding/custom/two - name = "Custom Emote 2" - -/datum/keybinding/custom/three - name = "Custom Emote 3" - -/datum/keybinding/custom/four - name = "Custom Emote 4" - donor_exclusive = TRUE - -/datum/keybinding/custom/five - name = "Custom Emote 5" - donor_exclusive = TRUE - -/datum/keybinding/custom/six - name = "Custom Emote 6" - donor_exclusive = TRUE - -/datum/keybinding/custom/seven - name = "Custom Emote 7" - donor_exclusive = TRUE - -/datum/keybinding/custom/eight - name = "Custom Emote 8" - donor_exclusive = TRUE - -/datum/keybinding/custom/nine - name = "Custom Emote 9" - donor_exclusive = TRUE - -/datum/keybinding/custom/ten - name = "Custom Emote 10" - donor_exclusive = TRUE diff --git a/code/datums/log_record.dm b/code/datums/log_record.dm deleted file mode 100644 index 2b9aef01cc24b..0000000000000 --- a/code/datums/log_record.dm +++ /dev/null @@ -1,79 +0,0 @@ -/datum/log_record - var/log_type // Type of log - var/raw_time // When did this happen? - var/what // What happened - var/who // Who did it - var/who_usr // The current usr, if not who. - var/target // Who/what was targeted - var/where // Where did it happen - -/datum/log_record/New(_log_type, _who, _what, _target, _where, _raw_time, force_no_usr_check, automatic) - log_type = _log_type - - who = get_subject_text(_who, _log_type) - who_usr = "" - if(!isnull(usr) && !force_no_usr_check) - if(automatic) - who_usr = "
    Automatic for [get_subject_text(usr, _log_type)]" - else if(log_type == DEFENSE_LOG) - if(usr != _target) - who_usr = "
    FORCED by [get_subject_text(usr, _log_type)]" - else if(usr != _who) - who_usr = "
    FORCED by [get_subject_text(usr, _log_type)]" - what = _what - target = get_subject_text(_target, _log_type) - if(!istext(_where) && !isturf(_where)) - _where = get_turf(_who) - if(isturf(_where)) - var/turf/T = _where - where = ADMIN_COORDJMP(T) - else - where = _where - if(!_raw_time) - _raw_time = world.time - raw_time = _raw_time - -/datum/log_record/proc/get_subject_text(subject, log_type) - if(ismob(subject) || isclient(subject) || istype(subject, /datum/mind)) - . = key_name_admin(subject) - if(should_log_health(log_type) && isliving(subject)) - . += get_health_string(subject) - else if(isatom(subject)) - var/atom/A = subject - . = A.name - else if(istype(subject, /datum)) - var/datum/D = subject - return D.type - else - . = subject - -/datum/log_record/proc/get_health_string(mob/living/L) - var/OX = L.getOxyLoss() > 50 ? "[L.getOxyLoss()]" : L.getOxyLoss() - var/TX = L.getToxLoss() > 50 ? "[L.getToxLoss()]" : L.getToxLoss() - var/BU = L.getFireLoss() > 50 ? "[L.getFireLoss()]" : L.getFireLoss() - var/BR = L.getBruteLoss() > 50 ? "[L.getBruteLoss()]" : L.getBruteLoss() - var/ST = L.getStaminaLoss() > 50 ? "[L.getStaminaLoss()]" : L.getStaminaLoss() - return " ([L.health]: [OX] - [TX] - [BU] - [BR] - [ST])" - -/datum/log_record/proc/should_log_health(log_type) - if(log_type == ATTACK_LOG || log_type == DEFENSE_LOG) - return TRUE - return FALSE - -/proc/compare_log_record(datum/log_record/A, datum/log_record/B) - var/time_diff = A.raw_time - B.raw_time - if(!time_diff) // Same time - return cmp_text_asc(A.log_type, B.log_type) - return time_diff - -/datum/log_record/vv_edit_var(var_name, var_value) - message_admins("[key_name_admin(src)] attempted to VV edit a logging object. Inform the host at once.") - log_admin("[key_name(src)] attempted to VV edit a logging object. Inform the host at once.") - GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "[key_name(src)] attempted to VV edit a logging object. Inform the host at once.") - return FALSE - -/datum/log_record/can_vv_delete() - message_admins("[key_name_admin(src)] attempted to VV edit a logging object. Inform the host at once.") - log_admin("[key_name(src)] attempted to VV edit a logging object. Inform the host at once.") - GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "[key_name(src)] attempted to VV edit a logging object. Inform the host at once.") - return FALSE diff --git a/code/datums/log_viewer.dm b/code/datums/log_viewer.dm deleted file mode 100644 index 843eb32bf0680..0000000000000 --- a/code/datums/log_viewer.dm +++ /dev/null @@ -1,319 +0,0 @@ -#define UPDATE_CKEY_MOB(__ckey) var/mob/result = selected_ckeys_mobs[__ckey];\ -if(!result || result.ckey != __ckey){\ - result = get_mob_by_ckey(__ckey);\ - selected_ckeys_mobs[__ckey] = result;\ -} - -#define RECORD_WARN_LIMIT 1000 -#define RECORD_HARD_LIMIT 2500 - -/datum/log_viewer - var/time_from = 0 - var/time_to = 4 HOURS // 4 Hours should be enough. INFINITY would screw the UI up - var/list/selected_mobs = list() // The mobs in question. - var/list/selected_ckeys = list() // The ckeys selected to search for. Will show all mobs the ckey is attached to - var/list/mob/selected_ckeys_mobs = list() - var/list/selected_log_types = ALL_LOGS // The log types being searched for - var/list/log_records = list() // Found and sorted records - -/datum/log_viewer/proc/clear_all() - selected_mobs.Cut() - selected_log_types = ALL_LOGS - selected_ckeys.Cut() - selected_ckeys_mobs.Cut() - time_from = initial(time_from) - time_to = initial(time_to) - log_records.Cut() - return - -/datum/log_viewer/proc/search(user) - log_records.Cut() // Empty the old results - var/list/invalid_mobs = list() - var/list/ckeys = selected_ckeys.Copy() - for(var/i in selected_mobs) - var/mob/M = i - if(!M || QDELETED(M) || !M.last_known_ckey) - invalid_mobs |= M - continue - ckeys |= M.last_known_ckey - - for(var/ckey in ckeys) - for(var/log_type in selected_log_types) - var/list/logs = GLOB.logging.get_logs_by_type(ckey, log_type) - var/len_logs = length(logs) - if(len_logs) - var/start_index = get_earliest_log_index(logs) - if(!start_index) // No log found that matches the starting time criteria - continue - var/end_index = get_latest_log_index(logs) - if(!end_index) // No log found that matches the end time criteria - continue - log_records.Add(logs.Copy(start_index, end_index + 1)) - - if(length(invalid_mobs)) - to_chat(user, "The search criteria contained invalid mobs. They have been removed from the criteria.") - for(var/i in invalid_mobs) - selected_mobs -= i // Cleanup - - log_records = sortTim(log_records, GLOBAL_PROC_REF(compare_log_record)) - -/** Binary search like implementation to find the earliest log - * Returns the index of the earliest log using the time_from value for the given list of logs. - * It will return 0 if no log after time_from is found -*/ -/datum/log_viewer/proc/get_earliest_log_index(list/logs) - if(!time_from) - return 1 - var/start = 1 - var/end = length(logs) - var/mid - do - mid = round_down((end + start) / 2) - var/datum/log_record/L = logs[mid] - if(L.raw_time >= time_from) - end = mid - else - start = mid - while(end - start > 1) - var/datum/log_record/L = logs[end] - if(L.raw_time >= time_from) // Check if there is atleast one valid log - return end - return 0 - -/** Binary search like implementation to find the latest log - * Returns the index of the latest log using the time_to value (1 second is added to prevent rounding weirdness) for the given list of logs. - * It will return 0 if no log before time_to + 10 is found -*/ -/datum/log_viewer/proc/get_latest_log_index(list/logs) - if(world.time < time_to) - return length(logs) - - var/end = length(logs) - var/start = 1 - var/mid - var/max_time = time_to + 10 - do - mid = round((end + start) / 2 + 0.5) - var/datum/log_record/L = logs[mid] - if(L.raw_time >= max_time) - end = mid - else - start = mid - while(end - start > 1) - var/datum/log_record/L = logs[start] - if(L.raw_time < max_time) // Check if there is atleast one valid log - return start - return 0 - -/datum/log_viewer/proc/add_mobs(list/mob/mobs) - if(!length(mobs)) - return - for(var/i in mobs) - add_mob(usr, i, FALSE) - -/datum/log_viewer/proc/add_ckey(mob/user, ckey) - if(!user || !ckey) - return - selected_ckeys |= ckey - UPDATE_CKEY_MOB(ckey) - show_ui(user) - -/datum/log_viewer/proc/add_mob(mob/user, mob/M, show_the_ui = TRUE) - if(!M || !user) - return - - selected_mobs |= M - - show_ui(user) - -/datum/log_viewer/proc/show_ui(mob/user) - var/all_log_types = ALL_LOGS - var/trStyleTop = "border-top:2px solid; border-bottom:2px solid; padding-top: 5px; padding-bottom: 5px;" - var/trStyle = "border-top:1px solid; border-bottom:1px solid; padding-top: 5px; padding-bottom: 5px;" - var/list/dat = list() - dat += "" - dat += "
    " - dat += "Time Search Range: [gameTimestamp(wtime = time_from)]" - dat += " To: [gameTimestamp(wtime = time_to)]" - dat += "
    " - - dat += "Mobs being used:" - for(var/i in selected_mobs) - var/mob/M = i - if(QDELETED(M)) - selected_mobs -= i - continue - dat += "[get_display_name(M)]" - dat += "Add Mob" - dat += "Clear All Mobs" - dat += "
    " - - dat += "Ckeys being used:" - for(var/ckey in selected_ckeys) - dat += "[get_ckey_name(ckey)]" - dat += "Add ckey" - dat += "Clear All ckeys" - dat += "
    " - - dat += "Log Types:" - for(var/log_type in all_log_types) - var/enabled = (log_type in selected_log_types) - var/text - var/style - if(enabled) - text = "[log_type]" - style = "background: [get_logtype_color(log_type)]" - else - text = log_type - - dat += "[text]" - - dat += "
    " - dat += "Clear All Settings" - dat += "Search" - dat += "
    " - - // Search results - var/tdStyleTime = "width:80px; text-align:center;" - var/tdStyleType = "width:80px; text-align:center;" - var/tdStyleWho = "width:400px; text-align:center;" - var/tdStyleWhere = "width:150px; text-align:center;" - dat += "
    " - dat += "" - dat += "" - for(var/i in log_records) - var/datum/log_record/L = i - var/time = gameTimestamp(wtime = L.raw_time - 9.99) // The time rounds up for some reason. Will result in weird filtering results - - dat +="\ - \ - " - dat += "
    WhenTypeWhoWhatTargetWhere
    [time][L.log_type][L.who][L.who_usr][L.what][L.target][L.where]
    " - dat += "
    " - - var/datum/browser/popup = new(user, "Log Viewer", "Log Viewer", 1500, 600) - popup.set_content(dat.Join()) - popup.open() - -/datum/log_viewer/Topic(href, href_list) - if(href_list["start_time"]) - var/input = input(usr, "hh:mm:ss", "Start time", "00:00:00") as text|null - if(!input) - return - var/res = timeStampToNum(input) - if(res < 0) - to_chat(usr, "'[input]' is an invalid input value.") - return - time_from = res - show_ui(usr) - return - if(href_list["end_time"]) - var/input = input(usr, "hh:mm:ss", "End time", "04:00:00") as text|null - if(!input) - return - var/res = timeStampToNum(input) - if(res < 0) - to_chat(usr, "'[input]' is an invalid input value.") - return - time_to = res - - show_ui(usr) - return - if(href_list["search"]) - search(usr) - var/records_len = length(log_records) - if(records_len > RECORD_WARN_LIMIT) - var/datum/log_record/last_record = log_records[RECORD_WARN_LIMIT] - var/last_time = gameTimestamp(wtime = last_record.raw_time - 9.99) - var/answer = alert(usr, "More than [RECORD_WARN_LIMIT] records were found. continuing will take a long time. This won't cause much lag for the server. Time at the [RECORD_WARN_LIMIT]th record '[last_time]'", "Warning", "Continue", "Limit to [RECORD_WARN_LIMIT]", "Cancel") - if(answer == "Limit to [RECORD_WARN_LIMIT]") - log_records.Cut(RECORD_WARN_LIMIT) - else if(answer == "Cancel") - log_records.Cut() - else - if(records_len > RECORD_HARD_LIMIT) - to_chat(usr, "Record limit reached. Limiting to [RECORD_HARD_LIMIT].") - log_records.Cut(RECORD_HARD_LIMIT) - show_ui(usr) - return - if(href_list["clear_all"]) - clear_all(usr) - show_ui(usr) - return - if(href_list["clear_mobs"]) - selected_mobs.Cut() - show_ui(usr) - return - if(href_list["clear_ckeys"]) - selected_ckeys.Cut() - selected_ckeys_mobs.Cut() - show_ui(usr) - return - if(href_list["add_mob"]) - var/list/mobs = getpois(TRUE, TRUE) - var/mob_choice = tgui_input_list(usr, "Please, select a mob: ", "Mob selector", mobs) - add_mob(usr, mobs[mob_choice]) - return - if(href_list["add_ckey"]) - var/list/ckeys = GLOB.logging.get_ckeys_logged() - var/ckey_choice = tgui_input_list(usr, "Please, select a ckey: ", "Ckey selector", ckeys) - add_ckey(usr, ckey_choice) - return - if(href_list["remove_mob"]) - var/mob/M = locate(href_list["remove_mob"]) - if(M) - selected_mobs -= M - show_ui(usr) - return - if(href_list["remove_ckey"]) - selected_ckeys -= href_list["remove_ckey"] - show_ui(usr) - return - if(href_list["toggle_log_type"]) - var/log_type = href_list["toggle_log_type"] - if(log_type in selected_log_types) - selected_log_types -= log_type - else - selected_log_types += log_type - show_ui(usr) - return - -/datum/log_viewer/proc/get_logtype_color(log_type) - switch(log_type) - if(ATTACK_LOG) - return "darkred" - if(DEFENSE_LOG) - return "chocolate" - if(CONVERSION_LOG) - return "indigo" - if(SAY_LOG) - return "teal" - if(EMOTE_LOG) - return "deepskyblue" - if(MISC_LOG) - return "gray" - if(DEADCHAT_LOG) - return "#cc00c6" - if(OOC_LOG) - return "#002eb8" - if(LOOC_LOG) - return "#6699CC" - return "slategray" - -/datum/log_viewer/proc/get_display_name(mob/M) - var/name = M.name - if(M.name != M.real_name) - name = "[name] ([M.real_name])" - if(isobserver(M)) - name = "[name] (DEAD)" - return "\[[M.last_known_ckey]\] [name]" - -/datum/log_viewer/proc/get_ckey_name(ckey) - UPDATE_CKEY_MOB(ckey) - var/mob/M = selected_ckeys_mobs[ckey] - - return get_display_name(M) - -#undef UPDATE_CKEY_MOB -#undef RECORD_WARN_LIMIT -#undef RECORD_HARD_LIMIT diff --git a/code/datums/logging.dm b/code/datums/logging.dm deleted file mode 100644 index 9cf2fb84f3cb6..0000000000000 --- a/code/datums/logging.dm +++ /dev/null @@ -1,59 +0,0 @@ -/datum/logging - var/list/datum/log_record/logs = list() // Assoc list of assoc lists (ckey, (log_type, list/logs)) - -/datum/logging/proc/add_log(ckey, datum/log_record/log) - if(!ckey) - log_debug("GLOB.logging.add_log called with an invalid ckey") - return - - if(!logs[ckey]) - logs[ckey] = list() - - var/list/log_types_list = logs[ckey] - - if(!log_types_list[log.log_type]) - log_types_list[log.log_type] = list() - - var/list/datum/log_record/log_records = log_types_list[log.log_type] - log_records.Add(log) - -/datum/logging/proc/get_ckeys_logged() - var/list/ckeys = list() - for(var/ckey in logs) - ckeys.Add(ckey) - return ckeys - -/* Returns the logs of a given ckey and log_type - * If no logs exist it will return an empty list -*/ -/datum/logging/proc/get_logs_by_type(ckey, log_type) - if(!ckey) - log_debug("GLOB.logging.get_logs_by_type called with an invalid ckey") - return - if(!log_type || !(log_type in ALL_LOGS)) - log_debug("GLOB.logging.get_logs_by_type called with an invalid log_type '[log_type]'") - return - - var/list/log_types_list = logs[ckey] - // Check if logs exist for the ckey - if(!length(log_types_list)) - return list() - - var/list/datum/log_record/log_records = log_types_list[log_type] - - // Check if logs exist for this type - if(!log_records) - return list() - return log_records - -/datum/logging/vv_edit_var(var_name, var_value) - message_admins("[key_name_admin(src)] attempted to VV edit a logging object. Inform the host at once.") - log_admin("[key_name(src)] attempted to VV edit a logging object. Inform the host at once.") - GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "[key_name(src)] attempted to VV edit a logging object. Inform the host at once.") - return FALSE - -/datum/logging/can_vv_delete() - message_admins("[key_name_admin(src)] attempted to VV edit a logging object. Inform the host at once.") - log_admin("[key_name(src)] attempted to VV edit a logging object. Inform the host at once.") - GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "[key_name(src)] attempted to VV edit a logging object. Inform the host at once.") - return FALSE diff --git a/code/datums/ores.dm b/code/datums/ores.dm deleted file mode 100644 index 07e7ae6090038..0000000000000 --- a/code/datums/ores.dm +++ /dev/null @@ -1,212 +0,0 @@ -/datum/ore - /// The type of ore that is dropped. Expected to be a subtype of [/obj/item/stack/ore]. - var/drop_type - /// The lower bound for the amount of randomized ore dropped. - var/drop_min = 1 - /// The upper bound for the amount of randomized ore dropped. - var/drop_max = 5 - /// The probability that the ore will spread to nearby [/turf/simulated/mineral]s when placed. - var/spread_chance = 0 - /// The icon state of the ore used for mining scanner overlays. - var/scan_icon_state = "" - -/** - * Called when the containing turf is "mined", such as with a pickaxe or other - * digging implement. - * - * Returns [MINERAL_ALLOW_DIG] if the containing turf should be changed to its - * "dug" state, [MINERAL_PREVENT_DIG] if it should remain as is. - */ -/datum/ore/proc/on_mine(turf/source, mob/user, triggered_by_explosion = FALSE) - var/amount = rand(drop_min, drop_max) - - if(ispath(drop_type, /obj/item/stack/ore)) - new drop_type(source, amount) - SSticker.score?.score_ore_mined++ - SSblackbox.record_feedback("tally", "ore_mined", amount, type) - else - stack_trace("[source.type] [COORD(source)] had non-ore stack [drop_type]") - - return MINERAL_ALLOW_DIG - -/datum/ore/iron - drop_type = /obj/item/stack/ore/iron - spread_chance = 20 - scan_icon_state = "rock_Iron" - -/datum/ore/uranium - drop_type = /obj/item/stack/ore/uranium - spread_chance = 5 - scan_icon_state = "rock_Uranium" - -/datum/ore/diamond - drop_type = /obj/item/stack/ore/diamond - scan_icon_state = "rock_Diamond" - -/datum/ore/gold - drop_type = /obj/item/stack/ore/gold - spread_chance = 5 - scan_icon_state = "rock_Gold" - -/datum/ore/silver - drop_type = /obj/item/stack/ore/silver - spread_chance = 5 - scan_icon_state = "rock_Silver" - -/datum/ore/titanium - drop_type = /obj/item/stack/ore/titanium - spread_chance = 5 - scan_icon_state = "rock_Titanium" - -/datum/ore/plasma - drop_type = /obj/item/stack/ore/plasma - spread_chance = 8 - scan_icon_state = "rock_Plasma" - -/datum/ore/bluespace - drop_type = /obj/item/stack/ore/bluespace_crystal - drop_min = 1 - drop_max = 1 - scan_icon_state = "rock_BScrystal" - -/datum/ore/bananium - drop_type = /obj/item/stack/ore/bananium - drop_min = 3 - drop_max = 3 - scan_icon_state = "rock_Clown" - -/datum/ore/tranquillite - drop_type = /obj/item/stack/ore/tranquillite - drop_min = 3 - drop_max = 3 - -/datum/ore/ancient_basalt - drop_type = /obj/item/stack/ore/glass/basalt/ancient - drop_min = 2 - drop_max = 2 - -#define GIBTONITE_UNSTRUCK 0 //! The gibtonite ore is dormant. -#define GIBTONITE_ACTIVE 1 //! The gibtonite ore is in its detonation countdown. -#define GIBTONITE_STABLE 2 //! The gibtonite ore has been stabilized and its detonation countdown is cancelled. -#define GIBTONITE_DETONATE 3 //! The gibtonite ore is about to explode. - -/datum/ore/gibtonite - drop_max = 1 - scan_icon_state = "rock_Gibtonite" - /// Amount of time from mining before gibtonite explodes. - var/detonate_time - /// The world.time that the detonate countdown started at. - var/detonate_start_time - /// The amount of time remaining if the gibtonite was stabilized before explosion, in half-seconds. - var/remaining_time - /// The state the ore is in. One of [GIBTONITE_UNSTRUCK], [GIBTONITE_ACTIVE], [GIBTONITE_STABLE], or [GIBTONITE_DETONATE]. - var/stage = GIBTONITE_UNSTRUCK - /// The overlay used for when the gibtonite is in its detonation countdown mode. - var/mutable_appearance/activated_overlay - /// Whether an admin log should be generated for this gibtonite's detonation. - /// Typically enabled if the detonation doesn't occur on the station z-level. - /// Note that this is only for explosions caused while the gibtonite is still - /// unmined, in contrast to [/obj/item/gibtonite/proc/GibtoniteReaction]. - var/notify_admins = FALSE - /// The callback for the explosion that occurs if the gibtonite is not - /// defused in time. - var/explosion_callback - -/datum/ore/gibtonite/New() - // So you don't know exactly when the hot potato will explode - detonate_time = rand(4 SECONDS, 5 SECONDS) - -/datum/ore/gibtonite/proc/explosive_reaction(turf/source, mob/user, triggered_by_explosion = FALSE) - activated_overlay = mutable_appearance(source.icon, "rock_Gibtonite_active", ON_EDGED_TURF_LAYER) - source.add_overlay(activated_overlay) - source.name = "gibtonite deposit" - source.desc = "An active gibtonite reserve. Run!" - stage = GIBTONITE_ACTIVE - source.visible_message("There was gibtonite inside! It's going to explode!") - - if(!is_mining_level(source.z)) - notify_admins = TRUE - if(!triggered_by_explosion) - message_admins("[key_name_admin(user)] has triggered a gibtonite deposit reaction at [ADMIN_VERBOSEJMP(source)].") - else - message_admins("An explosion has triggered a gibtonite deposit reaction at [ADMIN_VERBOSEJMP(source)].") - - if(!triggered_by_explosion) - log_game("[key_name(user)] has triggered a gibtonite deposit reaction at [AREACOORD(source)].") - else - log_game("An explosion has triggered a gibtonite deposit reaction at [AREACOORD(source)].") - - RegisterSignal(source, COMSIG_ATTACK_BY, PROC_REF(on_attackby)) - detonate_start_time = world.time - explosion_callback = addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/ore/gibtonite, detonate), source), detonate_time, TIMER_STOPPABLE) - -/datum/ore/gibtonite/on_mine(turf/source, mob/user, triggered_by_explosion = FALSE) - switch(stage) - if(GIBTONITE_UNSTRUCK) - playsound(src,'sound/effects/hit_on_shattered_glass.ogg', 50, TRUE) - explosive_reaction(source, user, triggered_by_explosion) - return MINERAL_PREVENT_DIG - if(GIBTONITE_ACTIVE) - detonate(source) - - // Detonation takes care of this for us. - return MINERAL_PREVENT_DIG - if(GIBTONITE_STABLE) - var/obj/item/gibtonite/gibtonite = new(source) - if(remaining_time <= 0) - gibtonite.quality = 3 - gibtonite.icon_state = "Gibtonite ore 3" - if(remaining_time >= 1 && remaining_time <= 2) - gibtonite.quality = 2 - gibtonite.icon_state = "Gibtonite ore 2" - - return MINERAL_ALLOW_DIG - - return MINERAL_PREVENT_DIG - -/datum/ore/gibtonite/proc/on_attackby(turf/source, obj/item/attacker, mob/user) - SIGNAL_HANDLER // COMSIG_ATTACK_BY - - if(istype(attacker, /obj/item/mining_scanner) || istype(attacker, /obj/item/t_scanner/adv_mining_scanner) && stage == GIBTONITE_ACTIVE) - user.visible_message("[user] holds [attacker] to [src]...", "You use [attacker] to locate where to cut off the chain reaction and attempt to stop it...") - defuse(source) - return COMPONENT_SKIP_AFTERATTACK - -/datum/ore/gibtonite/proc/detonate(turf/simulated/mineral/source) - if(stage == GIBTONITE_STABLE) - return - - // Don't explode twice please - if(explosion_callback) - deltimer(explosion_callback) - - stage = GIBTONITE_DETONATE - explosion(source, 1, 3, 5, adminlog = notify_admins) - - if(!istype(source)) - return - - // Dunno where else to put this - source.ChangeTurf(source.turf_type, source.defer_change) - addtimer(CALLBACK(source, TYPE_PROC_REF(/turf, AfterChange)), 1, TIMER_UNIQUE) - -/datum/ore/gibtonite/proc/defuse(turf/source) - var/world_time = world.time // Grab this immediately so we're fairly calculating countdown time - if(stage == GIBTONITE_ACTIVE) - source.cut_overlay(activated_overlay) - activated_overlay.icon_state = "rock_Gibtonite_inactive" - source.add_overlay(activated_overlay) - source.desc = "An inactive gibtonite reserve. The ore can be extracted." - stage = GIBTONITE_STABLE - - // ticks remaining / 10 = seconds remaining * 2 countdown decrements every second - remaining_time = floor((detonate_time - (world_time - detonate_start_time)) / 5) - - if(remaining_time < 0) - remaining_time = 0 - source.visible_message("The chain reaction was stopped! The gibtonite had [remaining_time] reactions left till the explosion!") - -#undef GIBTONITE_UNSTRUCK -#undef GIBTONITE_ACTIVE -#undef GIBTONITE_STABLE -#undef GIBTONITE_DETONATE diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm deleted file mode 100644 index bb24e3affe33a..0000000000000 --- a/code/datums/outfits/outfit_admin.dm +++ /dev/null @@ -1,1671 +0,0 @@ -// Used for 'select equipment' -// code/modules/admin/verbs/debug.dm 566 - -/datum/outfit/admin/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - H.job = name - -/datum/outfit/admin/on_mind_initialize(mob/living/carbon/human/H) - . = ..() - H.mind.assigned_role = name - H.mind.offstation_role = TRUE - -/proc/apply_to_card(obj/item/card/id/I, mob/living/carbon/human/H, list/access = list(), rank, special_icon) - if(!istype(I) || !istype(H)) - return 0 - - I.access = access - I.registered_name = H.real_name - I.rank = rank - I.assignment = rank - I.sex = capitalize(H.gender) - I.age = H.age - I.name = "[I.registered_name]'s ID Card ([I.assignment])" - I.photo = get_id_photo(H) - - if(special_icon) - I.icon_state = special_icon - -/datum/outfit/admin/syndicate - name = "Syndicate Agent" - - uniform = /obj/item/clothing/under/syndicate - back = /obj/item/storage/backpack - belt = /obj/item/storage/belt/utility/full/multitool - gloves = /obj/item/clothing/gloves/combat - shoes = /obj/item/clothing/shoes/combat - l_ear = /obj/item/radio/headset/syndicate - id = /obj/item/card/id/syndicate - r_pocket = /obj/item/radio/uplink - backpack_contents = list( - /obj/item/storage/box/engineer = 1, - /obj/item/flashlight = 1, - /obj/item/card/emag = 1, - /obj/item/food/syndidonkpocket = 1 - ) - - var/id_icon = "syndie" - var/id_access = "Syndicate Operative" - var/uplink_uses = 100 - -/datum/outfit/admin/syndicate/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_syndicate_access(id_access), name, id_icon) - - var/obj/item/radio/uplink/U = H.r_store - if(istype(U)) - U.hidden_uplink.uplink_owner = "[H.key]" - U.hidden_uplink.uses = uplink_uses - - var/obj/item/radio/R = H.l_ear - if(istype(R)) - R.set_frequency(SYND_FREQ) - H.faction += "syndicate" - -/datum/outfit/admin/syndicate_infiltrator - name = "Syndicate Infiltrator" - -/datum/outfit/admin/syndicate_infiltrator/equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = H.equip_syndicate_infiltrator(0, 100, FALSE) - H.sec_hud_set_ID() - H.faction |= "syndicate" - -/datum/outfit/admin/syndicate/operative - name = "Syndicate Nuclear Operative" - - suit = /obj/item/clothing/suit/space/hardsuit/syndi - belt = /obj/item/storage/belt/military - mask = /obj/item/clothing/mask/gas/syndicate - l_ear = /obj/item/radio/headset/syndicate/alt - glasses = /obj/item/clothing/glasses/night - shoes = /obj/item/clothing/shoes/magboots/syndie - r_pocket = /obj/item/radio/uplink/nuclear - l_pocket = /obj/item/pinpointer/advpinpointer - l_hand = /obj/item/tank/internals/oxygen/red - - backpack_contents = list( - /obj/item/storage/box/survival_syndi = 1, - /obj/item/gun/projectile/automatic/pistol = 1, - /obj/item/ammo_box/magazine/m10mm = 1, - /obj/item/crowbar/red = 1, - /obj/item/grenade/plastic/c4 = 1, - /obj/item/food/syndidonkpocket = 1, - /obj/item/flashlight = 1, - /obj/item/clothing/shoes/combat = 1 - ) - -/datum/outfit/admin/syndicate/operative/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/bio_chip/explosive/E = new(H) - E.implant(H) - - -/datum/outfit/admin/syndicate/operative/freedom - name = "Syndicate Freedom Operative" - suit = /obj/item/clothing/suit/space/hardsuit/syndi/freedom - - -/datum/outfit/admin/syndicate_strike_team - name = "Syndicate Strike Team" - -/datum/outfit/admin/syndicate_strike_team/equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = H.equip_syndicate_commando(FALSE, TRUE) - H.faction |= "syndicate" - -/datum/outfit/admin/syndicate/spy - name = "Syndicate Spy" - uniform = /obj/item/clothing/under/suit/really_black - shoes = /obj/item/clothing/shoes/chameleon/noslip - uplink_uses = 200 - id_access = "Syndicate Agent" - - bio_chips = list( - /obj/item/bio_chip/dust - ) - - -/datum/outfit/admin/nt_vip - name = "VIP Guest" - - uniform = /obj/item/clothing/under/suit/really_black - back = /obj/item/storage/backpack/satchel - gloves = /obj/item/clothing/gloves/color/black - shoes = /obj/item/clothing/shoes/black - head = /obj/item/clothing/head/that - l_ear = /obj/item/radio/headset/ert - id = /obj/item/card/id/centcom - pda = /obj/item/pda - backpack_contents = list( - /obj/item/storage/box/engineer = 1 - ) - -/datum/outfit/admin/nt_vip/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_centcom_access("VIP Guest"), "VIP Guest") - H.sec_hud_set_ID() - -/datum/outfit/admin/nt_navy_captain - name = "NT Navy Captain" - - uniform = /obj/item/clothing/under/rank/centcom/captain - back = /obj/item/storage/backpack/satchel - belt = /obj/item/gun/energy/pulse/pistol - gloves = /obj/item/clothing/gloves/color/white - shoes = /obj/item/clothing/shoes/centcom - head = /obj/item/clothing/head/beret/centcom/captain - l_ear = /obj/item/radio/headset/centcom - glasses = /obj/item/clothing/glasses/hud/security/sunglasses - id = /obj/item/card/id/centcom - pda = /obj/item/pda/centcom - backpack_contents = list( - /obj/item/storage/box/centcomofficer = 1, - /obj/item/bio_chip_implanter/death_alarm = 1 - ) - bio_chips = list( - /obj/item/bio_chip/mindshield, - /obj/item/bio_chip/dust - ) - -/datum/outfit/admin/nt_navy_captain/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_centcom_access("Nanotrasen Navy Captain"), "Nanotrasen Navy Captain") - H.sec_hud_set_ID() - -/datum/outfit/admin/nt_diplomat - name = "NT Diplomat" - - uniform = /obj/item/clothing/under/rank/centcom/diplomatic - back = /obj/item/storage/backpack/satchel - gloves = /obj/item/clothing/gloves/color/white - shoes = /obj/item/clothing/shoes/centcom - l_ear = /obj/item/radio/headset/centcom - id = /obj/item/card/id/centcom - r_pocket = /obj/item/lighter/zippo/nt_rep - l_pocket = /obj/item/storage/fancy/cigarettes/dromedaryco - pda = /obj/item/pda/centcom - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/bio_chip_implanter/death_alarm = 1, - ) - bio_chips = list( - /obj/item/bio_chip/mindshield, - /obj/item/bio_chip/dust - ) - -/datum/outfit/admin/nt_diplomat/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_centcom_access("Nanotrasen Navy Representative"), "Nanotrasen Diplomat") - H.sec_hud_set_ID() - -/datum/outfit/admin/nt_undercover - name = "NT Undercover Operative" - // Disguised NT special forces, sent to quietly eliminate or keep tabs on people in high positions (e.g: captain) - - uniform = /obj/item/clothing/under/color/random - back = /obj/item/storage/backpack - belt = /obj/item/storage/belt/utility/full/multitool - gloves = /obj/item/clothing/gloves/color/yellow - shoes = /obj/item/clothing/shoes/chameleon/noslip - l_ear = /obj/item/radio/headset/centcom - id = /obj/item/card/id - pda = /obj/item/pda - backpack_contents = list( - /obj/item/storage/box/engineer = 1, - /obj/item/flashlight = 1, - /obj/item/pinpointer/crew = 1 - ) - bio_chips = list( - /obj/item/bio_chip/dust - ) - cybernetic_implants = list( - /obj/item/organ/internal/cyberimp/eyes/hud/security, - /obj/item/organ/internal/eyes/cybernetic/xray, - /obj/item/organ/internal/cyberimp/brain/anti_stam/hardened, - /obj/item/organ/internal/cyberimp/chest/nutriment/plus/hardened, - /obj/item/organ/internal/cyberimp/arm/combat/centcom - ) - -/datum/outfit/admin/nt_undercover/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_centcom_access("NT Undercover Operative"), "Assistant") - H.sec_hud_set_ID() // Force it to show as assistant on sec huds - - var/obj/item/radio/R = H.l_ear - if(istype(R)) - R.name = "radio headset" - R.icon_state = "headset" - -/datum/outfit/admin/deathsquad_commando - name = "NT Deathsquad" - - pda = /obj/item/pinpointer - box = /obj/item/storage/box/deathsquad - back = /obj/item/mod/control/pre_equipped/apocryphal - belt = /obj/item/gun/projectile/revolver/mateba - gloves = /obj/item/clothing/gloves/combat - uniform = /obj/item/clothing/under/rank/centcom/deathsquad - shoes = /obj/item/clothing/shoes/magboots/elite - glasses = /obj/item/clothing/glasses/hud/security/night - mask = /obj/item/clothing/mask/gas/sechailer/swat - l_pocket = /obj/item/tank/internals/emergency_oxygen/double - r_pocket = /obj/item/reagent_containers/hypospray/combat/nanites - l_ear = /obj/item/radio/headset/alt/deathsquad - id = /obj/item/card/id/ert/deathsquad - suit_store = /obj/item/gun/energy/pulse - - backpack_contents = list( - /obj/item/storage/box/smoke_grenades, - /obj/item/ammo_box/a357, - /obj/item/ammo_box/a357, - /obj/item/ammo_box/a357, - /obj/item/flashlight/seclite, - /obj/item/grenade/barrier, - /obj/item/melee/energy/sword/saber, - /obj/item/shield/energy - ) - - cybernetic_implants = list( - /obj/item/organ/internal/eyes/cybernetic/thermals/hardened, - /obj/item/organ/internal/cyberimp/brain/anti_stam/hardened, - /obj/item/organ/internal/cyberimp/chest/nutriment/plus/hardened, - /obj/item/organ/internal/cyberimp/chest/reviver/hardened - ) - - bio_chips = list( - /obj/item/bio_chip/mindshield, // No death alarm, Deathsquad are silent - /obj/item/bio_chip/dust - ) - -/datum/outfit/admin/deathsquad_commando/leader - name = "NT Deathsquad Leader" - back = /obj/item/mod/control/pre_equipped/apocryphal/officer - - backpack_contents = list( - /obj/item/storage/box/flashbangs, - /obj/item/ammo_box/a357, - /obj/item/flashlight/seclite, - /obj/item/melee/energy/sword/saber, - /obj/item/shield/energy, - /obj/item/disk/nuclear/unrestricted - ) - -/datum/outfit/admin/deathsquad_commando/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_centcom_access("Deathsquad Commando"), "Deathsquad") - H.sec_hud_set_ID() - -/datum/outfit/admin/pirate - name = "Space Pirate" - - uniform = /obj/item/clothing/under/costume/pirate - back = /obj/item/storage/backpack/satchel - belt = /obj/item/storage/belt/utility/full/multitool - gloves = /obj/item/clothing/gloves/combat - shoes = /obj/item/clothing/shoes/brown - l_ear = /obj/item/radio/headset - id = /obj/item/card/id - r_hand = /obj/item/melee/energy/sword/pirate - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/flashlight = 1 - ) - -/datum/outfit/admin/pirate/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_MAINT_TUNNELS), name) - -/datum/outfit/admin/pirate/first_mate - name = "Space Pirate First Mate" - - glasses = /obj/item/clothing/glasses/eyepatch - head = /obj/item/clothing/head/bandana - -/datum/outfit/admin/pirate/captain - name = "Space Pirate Captain" - - suit = /obj/item/clothing/suit/pirate_black - head = /obj/item/clothing/head/pirate - -/datum/outfit/admin/tunnel_clown - name = "Tunnel Clown" - - uniform = /obj/item/clothing/under/rank/civilian/clown - suit = /obj/item/clothing/suit/hooded/chaplain_hoodie - back = /obj/item/storage/backpack - belt = /obj/item/storage/belt/utility/full/multitool - gloves = /obj/item/clothing/gloves/color/black - shoes = /obj/item/clothing/shoes/clown_shoes - mask = /obj/item/clothing/mask/gas/clown_hat - l_ear = /obj/item/radio/headset - glasses = /obj/item/clothing/glasses/thermal/monocle - id = /obj/item/card/id - l_pocket = /obj/item/food/grown/banana - r_pocket = /obj/item/bikehorn - r_hand = /obj/item/fireaxe - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/flashlight = 1, - /obj/item/reagent_containers/drinks/bottle/bottleofbanana = 1, - /obj/item/grenade/clown_grenade = 1, - /obj/item/melee/baton/cattleprod = 1, - /obj/item/stock_parts/cell/super = 1, - /obj/item/bikehorn/rubberducky = 1 - ) - -/datum/outfit/admin/tunnel_clown/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_CLOWN, ACCESS_THEATRE, ACCESS_MAINT_TUNNELS), "Tunnel Clown") - -/datum/outfit/admin/mime_assassin - name = "Mime Assassin" - - uniform = /obj/item/clothing/under/rank/civilian/mime - suit = /obj/item/clothing/suit/suspenders - back = /obj/item/storage/backpack/mime - belt = /obj/item/storage/belt/utility/full/multitool - gloves = /obj/item/clothing/gloves/color/white - shoes = /obj/item/clothing/shoes/black - head = /obj/item/clothing/head/beret - mask = /obj/item/clothing/mask/gas/mime - l_ear = /obj/item/radio/headset - glasses = /obj/item/clothing/glasses/thermal/monocle - id = /obj/item/card/id/syndicate - pda = /obj/item/pda/mime - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/reagent_containers/drinks/bottle/bottleofnothing = 1, - /obj/item/toy/crayon/mime = 1, - /obj/item/gun/projectile/automatic/pistol = 1, - /obj/item/ammo_box/magazine/m10mm = 1, - /obj/item/suppressor = 1, - /obj/item/card/emag = 1, - /obj/item/radio/uplink = 1, - /obj/item/food/syndidonkpocket = 1, - /obj/item/flashlight = 1 - ) - -/datum/outfit/admin/mime_assassin/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(H.gender == FEMALE) - uniform = /obj/item/clothing/under/rank/civilian/mime/sexy - suit = /obj/item/clothing/mask/gas/sexymime - -/datum/outfit/admin/mime_assassin/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/pda/PDA = H.wear_pda - if(istype(PDA)) - PDA.owner = H.real_name - PDA.ownjob = "Mime" - PDA.name = "PDA-[H.real_name] ([PDA.ownjob])" - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_MIME, ACCESS_THEATRE, ACCESS_MAINT_TUNNELS), "Mime") - H.sec_hud_set_ID() - -/datum/outfit/admin/greytide - name = "Greytide" - - uniform = /obj/item/clothing/under/color/grey - back = /obj/item/storage/backpack - shoes = /obj/item/clothing/shoes/brown - mask = /obj/item/clothing/mask/gas - l_ear = /obj/item/radio/headset - id = /obj/item/card/id - l_hand = /obj/item/storage/toolbox/mechanical - r_hand = /obj/item/flag/grey - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/flashlight = 1 - ) - -/datum/outfit/admin/greytide/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_MAINT_TUNNELS), "Greytide") - -/datum/outfit/admin/greytide/leader - name = "Greytide Leader" - - belt = /obj/item/storage/belt/utility/full/multitool - gloves = /obj/item/clothing/gloves/color/yellow - - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/clothing/head/welding = 1, - /obj/item/flashlight = 1 - ) - -/datum/outfit/admin/greytide/leader/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..(H, TRUE) - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_MAINT_TUNNELS), "Greytide Leader") - -/datum/outfit/admin/greytide/xeno - name = "Greytide Xeno" - - uniform = /obj/item/clothing/under/color/black - suit = /obj/item/clothing/suit/xenos - back = /obj/item/storage/backpack/satchel - belt = /obj/item/storage/belt/utility/full/multitool - gloves = /obj/item/clothing/gloves/color/yellow - shoes = /obj/item/clothing/shoes/black - head = /obj/item/clothing/head/xenos - glasses = /obj/item/clothing/glasses/thermal - l_pocket = /obj/item/tank/internals/emergency_oxygen/double - r_pocket = /obj/item/toy/figure/xeno - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/clothing/head/welding = 1, - /obj/item/flashlight = 1 - ) - -/datum/outfit/admin/greytide/xeno/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..(H, TRUE) - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_MAINT_TUNNELS), "Legit Xenomorph") - - - -/datum/outfit/admin/musician - name = "Musician" - - uniform = /obj/item/clothing/under/costume/singerb - back = /obj/item/storage/backpack - shoes = /obj/item/clothing/shoes/singerb - gloves = /obj/item/clothing/gloves/color/white - l_ear = /obj/item/radio/headset - r_ear = /obj/item/clothing/ears/headphones - pda = /obj/item/pda - id = /obj/item/card/id - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/flashlight = 1, - /obj/item/instrument/violin = 1, - /obj/item/instrument/piano_synth = 1, - /obj/item/instrument/guitar = 1, - /obj/item/instrument/eguitar = 1, - /obj/item/instrument/accordion = 1, - /obj/item/instrument/saxophone = 1, - /obj/item/instrument/trombone = 1, - /obj/item/instrument/harmonica = 1 - ) - -/datum/outfit/admin/musician/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_MAINT_TUNNELS), "Bard") - - var/obj/item/clothing/ears/headphones/P = H.r_ear - if(istype(P)) - P.toggle_visual_notes(H) // activate them, display musical notes effect - -// Soviet Military - -/datum/outfit/admin/soviet - name = "Soviet Tourist" - uniform = /obj/item/clothing/under/new_soviet - back = /obj/item/storage/backpack/satchel - head = /obj/item/clothing/head/sovietsidecap - id = /obj/item/card/id/data - shoes = /obj/item/clothing/shoes/combat - l_ear = /obj/item/radio/headset/soviet - backpack_contents = list( - /obj/item/storage/box/survival = 1 - ) - -/datum/outfit/admin/soviet/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - H.real_name = "[capitalize(pick(GLOB.first_names_soviet))] [capitalize(pick(GLOB.last_names_soviet))]" - H.name = H.real_name - H.add_language("Zvezhan") - H.set_default_language(GLOB.all_languages["Zvezhan"]) - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_MAINT_TUNNELS), name) - H.sec_hud_set_ID() - -/datum/outfit/admin/soviet/conscript - name = "Soviet Conscript" - - r_pocket = /obj/item/flashlight/seclite - r_hand = /obj/item/gun/projectile/shotgun/boltaction - belt = /obj/item/gun/projectile/revolver/nagant - - backpack_contents = list( - /obj/item/storage/box/soviet = 1, - /obj/item/ammo_box/a762 = 4 - ) - -/datum/outfit/admin/soviet/soldier - name = "Soviet Soldier" - - gloves = /obj/item/clothing/gloves/combat - suit = /obj/item/clothing/suit/sovietcoat - glasses = /obj/item/clothing/glasses/sunglasses - r_pocket = /obj/item/flashlight/seclite - belt = /obj/item/gun/projectile/automatic/pistol/aps - - backpack_contents = list( - /obj/item/storage/box/soviet = 1, - /obj/item/lighter = 1, - /obj/item/storage/fancy/cigarettes/cigpack_robust = 1, - /obj/item/ammo_box/magazine/apsm10mm = 2 - ) - -/datum/outfit/admin/soviet/officer - name = "Soviet Officer" - - gloves = /obj/item/clothing/gloves/combat - suit = /obj/item/clothing/suit/sovietcoat/officer - uniform = /obj/item/clothing/under/new_soviet/sovietofficer - head = /obj/item/clothing/head/sovietofficerhat - glasses = /obj/item/clothing/glasses/sunglasses - belt = /obj/item/gun/projectile/revolver/mateba - l_pocket = /obj/item/melee/classic_baton/telescopic - r_pocket = /obj/item/flashlight/seclite - - backpack_contents = list( - /obj/item/storage/box/soviet = 1, - /obj/item/lighter/zippo = 1, - /obj/item/storage/fancy/cigarettes/cigpack_syndicate = 1, - /obj/item/ammo_box/a357 = 2 - ) - -/datum/outfit/admin/soviet/marine - name = "Soviet Marine" - - gloves = /obj/item/clothing/gloves/combat - suit = /obj/item/clothing/suit/space/hardsuit/soviet - head = null - mask = /obj/item/clothing/mask/gas - glasses = /obj/item/clothing/glasses/night - belt = /obj/item/storage/belt/military/assault/soviet/full - r_pocket = /obj/item/melee/classic_baton/telescopic - l_hand = /obj/item/gun/projectile/automatic/ak814 - suit_store = /obj/item/tank/internals/emergency_oxygen/double - - backpack_contents = list( - /obj/item/storage/box/soviet = 1, - /obj/item/gun/projectile/automatic/pistol/aps = 1, - /obj/item/ammo_box/magazine/apsm10mm = 2, - /obj/item/storage/fancy/cigarettes/cigpack_syndicate = 1, - /obj/item/lighter/zippo/engraved = 1 - ) - -/datum/outfit/admin/soviet/marine/captain - name = "Soviet Marine Captain" - - uniform = /obj/item/clothing/under/new_soviet/sovietofficer - suit = /obj/item/clothing/suit/space/hardsuit/soviet/commander - - backpack_contents = list( - /obj/item/storage/box/soviet = 1, - /obj/item/gun/projectile/revolver/mateba = 1, - /obj/item/ammo_box/a357 = 2, - /obj/item/storage/fancy/cigarettes/cigpack_syndicate = 1, - /obj/item/lighter/zippo/engraved = 1 - ) - -/datum/outfit/admin/soviet/admiral - name = "Soviet Admiral" - - gloves = /obj/item/clothing/gloves/combat - uniform = /obj/item/clothing/under/new_soviet/sovietadmiral - head = /obj/item/clothing/head/sovietadmiralhat - belt = /obj/item/gun/projectile/revolver/mateba - glasses = /obj/item/clothing/glasses/thermal/eyepatch - l_pocket = /obj/item/melee/classic_baton/telescopic - - backpack_contents = list( - /obj/item/storage/box/soviet = 1, - /obj/item/ammo_box/a357 = 3 - ) - -/datum/outfit/admin/solgov_rep - name = "Trans-Solar Federation Representative" - - uniform = /obj/item/clothing/under/solgov/rep - back = /obj/item/storage/backpack/satchel - glasses = /obj/item/clothing/glasses/hud/security/night - gloves = /obj/item/clothing/gloves/color/white - shoes = /obj/item/clothing/shoes/centcom - l_ear = /obj/item/radio/headset/ert - id = /obj/item/card/id/silver - r_pocket = /obj/item/lighter/zippo/blue - l_pocket = /obj/item/storage/fancy/cigarettes/cigpack_robustgold - pda = /obj/item/pda - backpack_contents = list( - /obj/item/storage/box/responseteam = 1, - /obj/item/bio_chip_implanter/dust = 1, - /obj/item/bio_chip_implanter/death_alarm = 1, - ) - - bio_chips = list(/obj/item/bio_chip/mindshield, - /obj/item/bio_chip/death_alarm - ) - -/datum/outfit/admin/solgov_rep/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_centcom_access(), name, "lifetimeid") - I.assignment = "Trans-Solar Federation Representative" - H.sec_hud_set_ID() - - -/datum/outfit/admin/solgov - name = "TSF Marine" - uniform = /obj/item/clothing/under/solgov - suit = /obj/item/clothing/suit/armor/bulletproof - back = /obj/item/storage/backpack/ert/solgov - belt = /obj/item/storage/belt/military/assault/marines/full - head = /obj/item/clothing/head/soft/solgov/marines - glasses = /obj/item/clothing/glasses/night - gloves = /obj/item/clothing/gloves/combat - shoes = /obj/item/clothing/shoes/combat - l_ear = /obj/item/radio/headset/ert/alt/solgov - id = /obj/item/card/id - l_hand = /obj/item/gun/projectile/automatic/shotgun/bulldog - suit_store = /obj/item/gun/projectile/automatic/pistol/m1911 - r_pocket = /obj/item/flashlight/seclite - pda = /obj/item/pda - box = /obj/item/storage/box/responseteam - backpack_contents = list( - /obj/item/clothing/shoes/magboots = 1, - /obj/item/whetstone = 1, - /obj/item/clothing/mask/gas/explorer/marines = 1, - /obj/item/reagent_containers/hypospray/autoinjector/survival = 1 - ) - cybernetic_implants = list( - /obj/item/organ/internal/cyberimp/arm/flash, - /obj/item/organ/internal/cyberimp/chest/nutriment/hardened, - /obj/item/organ/internal/cyberimp/eyes/hud/security - ) - bio_chips = list(/obj/item/bio_chip/mindshield, - /obj/item/bio_chip/death_alarm - ) - - var/is_solgov_lieutenant = FALSE - - -/datum/outfit/admin/solgov/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - if(is_solgov_lieutenant) - H.real_name = "Lieutenant [pick(GLOB.last_names)]" - else - H.real_name = "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(GLOB.last_names)]" - H.name = H.real_name - var/obj/item/card/id/I = H.wear_id - I.assignment = name - if(istype(I) && is_solgov_lieutenant) - apply_to_card(I, H, get_centcom_access("Emergency Response Team Leader"), name, "lifetimeid") - else if(istype(I)) - apply_to_card(I, H, get_centcom_access("Emergency Response Team Member"), name, "lifetimeid") - H.sec_hud_set_ID() - -/datum/outfit/admin/solgov/lieutenant - name = "TSF Lieutenant" - uniform = /obj/item/clothing/under/solgov/command - head = /obj/item/clothing/head/beret/solgov - glasses = /obj/item/clothing/glasses/night - back = /obj/item/storage/backpack/satchel - shoes = /obj/item/clothing/shoes/magboots/elite - l_ear = /obj/item/radio/headset/ert/alt/commander/solgov - l_hand = null - belt = /obj/item/melee/baton/loaded - suit_store = /obj/item/gun/projectile/automatic/pistol/deagle - l_pocket = /obj/item/pinpointer/advpinpointer - backpack_contents = list( - /obj/item/storage/box/handcuffs = 1, - /obj/item/reagent_containers/hypospray/autoinjector/survival = 1, - /obj/item/clothing/mask/gas/explorer/marines = 1, - /obj/item/ammo_box/magazine/m50 = 3 - ) - is_solgov_lieutenant = TRUE - -/datum/outfit/admin/solgov/elite - name = "MARSOC Marine" - uniform = /obj/item/clothing/under/solgov/elite - suit = /obj/item/clothing/suit/space/hardsuit/ert/solgov - head = null - mask = /obj/item/clothing/mask/gas/explorer/marines - belt = /obj/item/storage/belt/military/assault/marines/elite/full - shoes = /obj/item/clothing/shoes/magboots/elite - l_hand = /obj/item/gun/projectile/automatic/ar - backpack_contents = list( - /obj/item/whetstone = 1, - /obj/item/reagent_containers/hypospray/autoinjector/survival = 1 - ) - cybernetic_implants = list( - /obj/item/organ/internal/cyberimp/eyes/hud/security, - /obj/item/organ/internal/cyberimp/chest/nutriment/hardened, - /obj/item/organ/internal/cyberimp/brain/anti_stam/hardened, - /obj/item/organ/internal/cyberimp/arm/flash, - /obj/item/organ/internal/eyes/cybernetic/shield - ) - -/datum/outfit/admin/solgov/elite/lieutenant - name = "MARSOC Lieutenant" - uniform = /obj/item/clothing/under/solgov/command/elite - suit = /obj/item/clothing/suit/space/hardsuit/ert/solgov/command - head = null - mask = /obj/item/clothing/mask/gas/explorer/marines - glasses = /obj/item/clothing/glasses/night - belt = /obj/item/melee/baton/loaded - l_hand = null - suit_store = /obj/item/gun/projectile/automatic/pistol/deagle - l_pocket = /obj/item/pinpointer/advpinpointer - l_ear = /obj/item/radio/headset/ert/alt/commander/solgov - backpack_contents = list( - /obj/item/storage/box/handcuffs = 1, - /obj/item/reagent_containers/hypospray/autoinjector/survival = 1, - /obj/item/ammo_box/magazine/m50 = 3 - ) - is_solgov_lieutenant = TRUE - -/datum/outfit/admin/trader - name = "Trader" - uniform = /obj/item/clothing/under/rank/cargo/tech - back = /obj/item/storage/backpack/industrial - belt = /obj/item/melee/classic_baton - shoes = /obj/item/clothing/shoes/black - l_ear = /obj/item/radio/headset - glasses = /obj/item/clothing/glasses/sunglasses - id = /obj/item/card/id/supply - pda = /obj/item/pda - backpack_contents = list( - /obj/item/hand_labeler = 1, - /obj/item/hand_labeler_refill = 2 - ) - box = /obj/item/storage/box/survival - -/datum/outfit/admin/trader/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_TRADE_SOL, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS), name) - H.sec_hud_set_ID() - -/datum/outfit/admin/trader/sol - name = "Trans-Solar Federation Trader" - suit = /obj/item/clothing/suit/jacket/bomber/cargo - head = /obj/item/clothing/head/soft/cargo - -/datum/outfit/admin/trader/cyber - name = "Cybersun Industries Trader" - uniform = /obj/item/clothing/under/syndicate/tacticool - suit = /obj/item/clothing/suit/jacket/bomber/syndicate - gloves = /obj/item/clothing/gloves/color/black - shoes = /obj/item/clothing/shoes/combat - belt = /obj/item/melee/classic_baton/telescopic - back = /obj/item/storage/backpack/security - box = /obj/item/storage/box/survival - -/datum/outfit/admin/trader/commie - name = "USSP Trader" - uniform = /obj/item/clothing/under/new_soviet - suit = /obj/item/clothing/suit/sovietcoat - head = /obj/item/clothing/head/ushanka - box = /obj/item/storage/box/soviet - -/datum/outfit/admin/trader/commie/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - H.add_language("Zvezhan") - -/datum/outfit/admin/trader/unathi - name = "Glint-Scales Trader" - uniform = /obj/item/clothing/under/rank/cargo/qm - suit = /obj/item/clothing/suit/unathi/robe - shoes = /obj/item/clothing/shoes/footwraps - -/datum/outfit/admin/trader/vulp - name = "Steadfast Trading Co. Trader" - uniform = /obj/item/clothing/under/rank/cargo/qm/formal - suit = /obj/item/clothing/suit/jacket/leather/overcoat - belt = /obj/item/melee/classic_baton/telescopic - -/datum/outfit/admin/trader/ipc - name = "Synthetic Union Trader" - uniform = /obj/item/clothing/under/misc/vice - suit = /obj/item/clothing/suit/storage/iaa/blackjacket/armored - belt = /obj/item/melee/classic_baton/telescopic - back = /obj/item/storage/backpack/robotics - -/datum/outfit/admin/trader/vox - name = "Skipjack Trader" - uniform = /obj/item/clothing/under/vox/vox_casual - suit = /obj/item/clothing/suit/hooded/vox_robes - gloves = /obj/item/clothing/gloves/color/yellow/vox - shoes = /obj/item/clothing/shoes/magboots/vox - belt = /obj/item/melee/classic_baton/telescopic - mask = /obj/item/clothing/mask/breath/vox/respirator - suit_store = /obj/item/tank/internals/emergency_oxygen/double/vox - box = /obj/item/storage/box/survival_vox - -/datum/outfit/admin/trader/skrell - name = "Solar-Central Compact Trader" - uniform = /obj/item/clothing/under/misc/durathread - suit = /obj/item/clothing/suit/space/skrell/white - belt = /obj/item/melee/classic_baton/telescopic - -/datum/outfit/admin/trader/grey - name = "Technocracy Trader" - uniform = /obj/item/clothing/under/costume/psyjump - suit = /obj/item/clothing/suit/jacket/bomber/robo - belt = /obj/item/melee/classic_baton/telescopic - back = /obj/item/storage/backpack/robotics - -/datum/outfit/admin/trader/nian - name = "Merchant Guild Trader" - uniform = /obj/item/clothing/under/suit/really_black - suit = /obj/item/clothing/suit/pimpcoat - shoes = /obj/item/clothing/shoes/fluff/noble_boot - belt = /obj/item/melee/classic_baton/ntcane - -/datum/outfit/admin/chrono - name = "Chrono Legionnaire" - - uniform = /obj/item/clothing/under/syndicate - suit = /obj/item/clothing/suit/space/chronos - back = /obj/item/chrono_eraser - gloves = /obj/item/clothing/gloves/combat - shoes = /obj/item/clothing/shoes/magboots/advance - head = /obj/item/clothing/head/helmet/space/chronos - mask = /obj/item/clothing/mask/gas/syndicate - glasses = /obj/item/clothing/glasses/night - id = /obj/item/card/id/syndicate - suit_store = /obj/item/tank/internals/emergency_oxygen/double - -/datum/outfit/admin/chrono/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_accesses() + get_all_centcom_access(), name, "syndie") - -/datum/outfit/admin/spacegear - name = "Standard Space Gear" - - uniform = /obj/item/clothing/under/color/grey - suit = /obj/item/clothing/suit/space - back = /obj/item/tank/jetpack/oxygen - shoes = /obj/item/clothing/shoes/magboots - head = /obj/item/clothing/head/helmet/space - mask = /obj/item/clothing/mask/breath - l_ear = /obj/item/radio/headset - id = /obj/item/card/id - -/datum/outfit/admin/spacegear/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - if(istype(H.back, /obj/item/tank/jetpack)) - var/obj/item/tank/jetpack/J = H.back - J.turn_on() - J.toggle_internals(H) - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_accesses(), "Space Explorer") - -/datum/outfit/admin/modsuit - name = "MODsuit - Generic" - back = /obj/item/mod/control/pre_equipped/standard - suit_store = /obj/item/tank/internals/oxygen - mask = /obj/item/clothing/mask/breath - shoes = /obj/item/clothing/shoes/magboots - id = /obj/item/card/id - -/datum/outfit/admin/modsuit/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - if(istype(H.back, /obj/item/tank/internals/oxygen)) - var/obj/item/tank/internals/oxygen/J = H.back - J.toggle_internals(H) - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_accesses(), "MODsuit Tester") - -/datum/outfit/admin/modsuit/engineer - name = "MODsuit - Engineer" - back = /obj/item/mod/control/pre_equipped/engineering - -/datum/outfit/admin/modsuit/ce - name = "MODsuit - CE" - back = /obj/item/mod/control/pre_equipped/advanced - shoes = /obj/item/clothing/shoes/magboots/advance - -/datum/outfit/admin/modsuit/mining - name = "MODsuit - Mining" - back = /obj/item/mod/control/pre_equipped/mining/asteroid - -/datum/outfit/admin/modsuit/syndi - name = "MODsuit - Syndi" - back = /obj/item/mod/control/pre_equipped/traitor - shoes = /obj/item/clothing/shoes/magboots/syndie - -/// Technically not a MODsuit, we'll bundle it up in here for the future when it does become one -/datum/outfit/admin/modsuit/wizard - name = "Hardsuit - Wizard" - suit = /obj/item/clothing/suit/space/hardsuit/wizard - shoes = /obj/item/clothing/shoes/magboots/wizard - -/datum/outfit/admin/modsuit/medical - name = "MODsuit - Medical" - back = /obj/item/mod/control/pre_equipped/medical - -/datum/outfit/admin/modsuit/atmos - name = "MODsuit - Atmos" - back = /obj/item/mod/control/pre_equipped/atmospheric - -/datum/outfit/admin/tournament - name = "Tournament Generic" - suit = /obj/item/clothing/suit/armor/vest - shoes = /obj/item/clothing/shoes/black - head = /obj/item/clothing/head/helmet/thunderdome - r_pocket = /obj/item/grenade/smokebomb - l_hand = /obj/item/kitchen/knife - r_hand = /obj/item/gun/energy/pulse/destroyer - -/datum/outfit/admin/tournament/red - name = "Tournament Standard Red" - uniform = /obj/item/clothing/under/color/red - -/datum/outfit/admin/tournament/green - name = "Tournament Standard Green" - uniform = /obj/item/clothing/under/color/green - -/// gangster are supposed to fight each other. --rastaf0 -/datum/outfit/admin/tournament/tournament_gangster - name = "Tournament Gangster" - - uniform = /obj/item/clothing/under/rank/security/detective - suit = /obj/item/clothing/suit/storage/det_suit - shoes = /obj/item/clothing/shoes/black - head = /obj/item/clothing/head/det_hat - glasses = /obj/item/clothing/glasses/thermal/monocle - l_pocket = /obj/item/ammo_box/a357 - r_hand = /obj/item/gun/projectile/automatic/proto - -/// Steven Seagal FTW -/datum/outfit/admin/tournament/tournament_chef - name = "Tournament Chef" - - uniform = /obj/item/clothing/under/rank/civilian/chef - suit = /obj/item/clothing/suit/chef - shoes = /obj/item/clothing/shoes/black - head = /obj/item/clothing/head/chefhat - l_pocket = /obj/item/kitchen/knife - r_pocket = /obj/item/kitchen/knife - l_hand = /obj/item/kitchen/knife - r_hand = /obj/item/kitchen/rollingpin - -/datum/outfit/admin/tournament/tournament_janitor - name = "Tournament Janitor" - - uniform = /obj/item/clothing/under/rank/civilian/janitor - back = /obj/item/storage/backpack - shoes = /obj/item/clothing/shoes/black - l_hand = /obj/item/reagent_containers/glass/bucket - backpack_contents = list( - /obj/item/grenade/chem_grenade/cleaner = 2, - /obj/item/stack/tile/plasteel = 7 - ) - -/datum/outfit/admin/tournament/tournament_janitor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/reagent_containers/R = H.l_hand - if(istype(R)) - R.reagents.add_reagent("water", 70) - -/datum/outfit/admin/survivor - name = "Survivor" - - uniform = /obj/item/clothing/under/misc/overalls - back = /obj/item/storage/backpack - gloves = /obj/item/clothing/gloves/color/latex - shoes = /obj/item/clothing/shoes/white - l_ear = /obj/item/radio/headset - id = /obj/item/card/id - backpack_contents = list( - /obj/item/storage/box/survival = 1 - ) - -/datum/outfit/admin/survivor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - - for(var/obj/item/I in H.contents) - if(!istype(I, /obj/item/bio_chip)) - I.add_mob_blood(H) - - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_MAINT_TUNNELS), "Survivor") - -/datum/outfit/admin/masked_killer - name = "Masked Killer" - - uniform = /obj/item/clothing/under/misc/overalls - suit = /obj/item/clothing/suit/apron - back = /obj/item/storage/backpack - gloves = /obj/item/clothing/gloves/color/latex - shoes = /obj/item/clothing/shoes/white - head = /obj/item/clothing/head/welding - mask = /obj/item/clothing/mask/surgical - l_ear = /obj/item/radio/headset - glasses = /obj/item/clothing/glasses/thermal/monocle - id = /obj/item/card/id/syndicate - l_pocket = /obj/item/kitchen/knife - r_pocket = /obj/item/scalpel - r_hand = /obj/item/fireaxe - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/flashlight = 1 - ) - -/datum/outfit/admin/masked_killer/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - - for(var/obj/item/I in H.contents) - if(!istype(I, /obj/item/bio_chip)) - I.add_mob_blood(H) - - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_MAINT_TUNNELS), "Masked Killer", "syndie") - -/datum/outfit/admin/singuloth_knight - name = "Singuloth Knight" - - uniform = /obj/item/clothing/under/syndicate/combat - suit = /obj/item/clothing/suit/space/hardsuit/singuloth - back = /obj/item/storage/backpack/satchel - l_hand = /obj/item/knighthammer - belt = /obj/item/claymore/ceremonial - gloves = /obj/item/clothing/gloves/combat - shoes = /obj/item/clothing/shoes/magboots - mask = /obj/item/clothing/mask/breath - l_ear = /obj/item/radio/headset/ert - glasses = /obj/item/clothing/glasses/meson/cyber - id = /obj/item/card/id - suit_store = /obj/item/tank/internals/oxygen - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/flashlight = 1 - ) - -/datum/outfit/admin/singuloth_knight/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_accesses(), "Singuloth Knight") - -/datum/outfit/admin/dark_lord - name = "Dark Lord" - - uniform = /obj/item/clothing/under/color/black - suit = /obj/item/clothing/suit/hooded/chaplain_hoodie - back = /obj/item/storage/backpack - gloves = /obj/item/clothing/gloves/combat - shoes = /obj/item/clothing/shoes/chameleon/noslip - l_ear = /obj/item/radio/headset/syndicate - id = /obj/item/card/id/syndicate - l_hand = /obj/item/dualsaber/red - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/flashlight = 1, - ) - -/datum/outfit/admin/dark_lord/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/clothing/suit/hooded/chaplain_hoodie/C = H.wear_suit - if(istype(C)) - C.name = "dark lord robes" - C.hood.name = "dark lord hood" - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_accesses(), "Dark Lord", "syndie") - - -/datum/outfit/admin/ancient_vampire - name = "Ancient Vampire" - - uniform = /obj/item/clothing/under/suit/victsuit/red - suit = /obj/item/clothing/suit/draculacoat - back = /obj/item/storage/backpack - gloves = /obj/item/clothing/gloves/combat - shoes = /obj/item/clothing/shoes/chameleon/noslip - l_ear = /obj/item/radio/headset/syndicate - id = /obj/item/card/id - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/flashlight = 1, - /obj/item/clothing/under/color/black = 1 - ) - -/datum/outfit/admin/ancient_vampire/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/clothing/suit/hooded/chaplain_hoodie/C = new(H.loc) - if(istype(C)) - C.name = "ancient robes" - C.hood.name = "ancient hood" - H.equip_to_slot_or_del(C, ITEM_SLOT_IN_BACKPACK) - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_accesses(), "Ancient One", "data") - -/datum/outfit/admin/ancient_vampire/on_mind_initialize(mob/living/carbon/human/H) - . = ..() - H.mind.make_vampire() - var/datum/antagonist/vampire/V = H.mind.has_antag_datum(/datum/antagonist/vampire) - V.bloodusable = 9999 - V.bloodtotal = 9999 - V.add_subclass(SUBCLASS_ANCIENT, FALSE) - H.dna.SetSEState(GLOB.jumpblock, TRUE) - singlemutcheck(H, GLOB.jumpblock, MUTCHK_FORCED) - H.update_mutations() - H.gene_stability = 100 - -/datum/outfit/admin/ancient_mindflayer - name = "Ancient Mindflayer" - - // Shamelessly stolen from the `Dark Lord` - uniform = /obj/item/clothing/under/color/black - back = /obj/item/storage/backpack - gloves = /obj/item/clothing/gloves/color/yellow - shoes = /obj/item/clothing/shoes/chameleon/noslip - l_ear = /obj/item/radio/headset/syndicate - id = /obj/item/card/id - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/flashlight = 1, - ) - -/datum/outfit/admin/ancient_mindflayer/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/clothing/suit/hooded/chaplain_hoodie/C = new(H.loc) - if(istype(C)) - C.name = "ancient robes" - C.hood.name = "ancient hood" - H.equip_to_slot_or_del(C, ITEM_SLOT_IN_BACKPACK) - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_accesses(), "Ancient One", "data") - -/datum/outfit/admin/ancient_mindflayer/on_mind_initialize(mob/living/carbon/human/H) - . = ..() - H.mind.make_mind_flayer() - var/datum/antagonist/mindflayer/flayer = H.mind.has_antag_datum(/datum/antagonist/mindflayer) - flayer.usable_swarms = 9999 - H.dna.SetSEState(GLOB.jumpblock, TRUE) - singlemutcheck(H, GLOB.jumpblock, MUTCHK_FORCED) - H.update_mutations() - H.gene_stability = 100 - -/datum/outfit/admin/wizard - name = "Blue Wizard" - uniform = /obj/item/clothing/under/color/lightpurple - suit = /obj/item/clothing/suit/wizrobe - back = /obj/item/storage/backpack - shoes = /obj/item/clothing/shoes/sandal - head = /obj/item/clothing/head/wizard - l_ear = /obj/item/radio/headset - id = /obj/item/card/id - r_pocket = /obj/item/teleportation_scroll - l_hand = /obj/item/staff - r_hand = /obj/item/spellbook - backpack_contents = list( - /obj/item/storage/box/engineer = 1 - ) - -/datum/outfit/admin/wizard/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_accesses(), "Wizard") - -/datum/outfit/admin/wizard/red - name = "Wizard - Red Wizard" - - suit = /obj/item/clothing/suit/wizrobe/red - head = /obj/item/clothing/head/wizard/red - -/datum/outfit/admin/wizard/marisa - name = "Wizard - Marisa Wizard" - - suit = /obj/item/clothing/suit/wizrobe/marisa - shoes = /obj/item/clothing/shoes/sandal/marisa - head = /obj/item/clothing/head/wizard/marisa - -/datum/outfit/admin/wizard/arch - name = "Wizard - Arch Wizard" - - suit = /obj/item/clothing/suit/wizrobe/magusred - head = /obj/item/clothing/head/wizard/magus - belt = /obj/item/storage/belt/wands/full - l_hand = null - backpack_contents = list( - /obj/item/storage/box/engineer = 1, - /obj/item/clothing/suit/space/hardsuit/wizard/arch = 1, - /obj/item/clothing/shoes/magboots = 1, - /obj/item/kitchen/knife/ritual = 1, - /obj/item/clothing/suit/wizrobe/red = 1, - /obj/item/clothing/head/wizard/red = 1 - ) - -/datum/outfit/admin/wizard/arch/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - var/obj/item/spellbook/B = H.r_hand - if(istype(B)) - B.owner = H // force-bind it so it can never be stolen, no matter what. - B.name = "Archwizard Spellbook" - B.uses = 50 - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_accesses(), "Arch Wizard") - - -/datum/outfit/admin/dark_priest - name = "Dark Priest" - - uniform = /obj/item/clothing/under/color/black - suit = /obj/item/clothing/suit/hooded/chaplain_hoodie - back = /obj/item/storage/backpack - head = /obj/item/clothing/head/hooded/chaplain_hood - gloves = /obj/item/clothing/gloves/color/black - shoes = /obj/item/clothing/shoes/black - l_ear = /obj/item/radio/headset/syndicate - id = /obj/item/card/id/syndicate - r_hand = /obj/item/nullrod/armblade - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/flashlight = 1, - ) - bio_chips = list( - /obj/item/bio_chip/dust - ) - -/datum/outfit/admin/dark_priest/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_accesses(), "Dark Priest", "syndie") - var/obj/item/nullrod/armblade/B = H.r_hand - if(istype(B)) - B.force = 20 - B.name = "blessing of the reaper" - B.desc = "Sometimes, someone's just gotta die." - var/obj/item/radio/headset/R = H.l_ear - if(istype(R)) - R.flags |= NODROP - -/datum/outfit/admin/honksquad - name = "Honksquad" - - uniform = /obj/item/clothing/under/rank/civilian/clown - mask = /obj/item/clothing/mask/gas/clown_hat - back = /obj/item/storage/backpack/clown - id = /obj/item/card/id/clown - - backpack_contents = list( - /obj/item/storage/box/survival = 1, - /obj/item/bikehorn = 1, - /obj/item/stamp/clown = 1, - /obj/item/toy/crayon/rainbow = 1, - /obj/item/reagent_containers/spray/waterflower = 1, - /obj/item/food/grown/banana = 1, - ) - - shoes = /obj/item/clothing/shoes/clown_shoes - suit = /obj/item/clothing/suit/storage/det_suit - pda = /obj/item/pda/clown - l_ear = /obj/item/radio/headset - r_pocket = /obj/item/reagent_containers/patch/jestosterone - -/datum/outfit/admin/honksquad/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(H.gender == FEMALE) - uniform = /obj/item/clothing/under/rank/civilian/clown/sexy - mask = /obj/item/clothing/mask/gas/clown_hat/sexy - - if(prob(50)) - // You have to do it like this to make it work with assoc lists without a runtime. - // Trust me. - backpack_contents.Add(/obj/item/gun/energy/clown) - backpack_contents[/obj/item/gun/energy/clown] = 1 // Amount. Not boolean. Do not TRUE this. You turkey. - else - backpack_contents.Add(/obj/item/gun/throw/piecannon) - backpack_contents[/obj/item/gun/throw/piecannon] = 1 - - var/clown_rank = pick("Trickster First Class", "Master Clown", "Major Prankster") - var/clown_name = pick(GLOB.clown_names) - H.real_name = "[clown_rank] [clown_name]" - -/datum/outfit/admin/honksquad/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - // Setup their clumsy and comic sans gene - H.dna.SetSEState(GLOB.clumsyblock, TRUE) - H.dna.SetSEState(GLOB.comicblock, TRUE) - H.check_mutations = TRUE - - // Setup their headset - var/obj/item/radio/R = H.l_ear - if(istype(R)) - R.set_frequency(DTH_FREQ) // Clowns can be part of "special operations" - - // And their PDA - var/obj/item/pda/P = H.wear_pda - if(istype(P)) - P.owner = H.real_name - P.ownjob = "Emergency Response Clown" - P.name = "PDA-[H.real_name] ([P.ownjob])" - - // And their ID - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_CLOWN), "Emergency Response Clown") - H.sec_hud_set_ID() - -/datum/outfit/admin/observer - name = "Observer" - - uniform = /obj/item/clothing/under/costume/tourist_suit - back = /obj/item/storage/backpack/satchel - shoes = /obj/item/clothing/shoes/black - box = /obj/item/storage/box/survival - backpack_contents = list( - /obj/item/bio_chip_implanter/dust = 1 - ) - -/datum/outfit/admin/observer/plasmaman - name = "Observer (Plasma)" - - uniform = /obj/item/clothing/under/plasmaman/assistant - head = /obj/item/clothing/head/helmet/space/plasmaman/assistant - mask = /obj/item/clothing/mask/breath - belt = /obj/item/tank/internals/plasmaman/belt/full - box = /obj/item/storage/box/survival_plasmaman - -/datum/outfit/admin/observer/vox - name = "Observer (Vox)" - - mask = /obj/item/clothing/mask/breath/vox - belt = /obj/item/tank/internals/emergency_oxygen/double/vox - box = /obj/item/storage/box/survival_vox - -/datum/outfit/admin/enforcer - name = "Oblivion Enforcer" - - uniform = /obj/item/clothing/under/color/white/enforcer - shoes = /obj/item/clothing/shoes/white/enforcer - back = /obj/item/storage/backpack/satchel - id = /obj/item/card/id/data - //The hood on this gets enabled on the after-equip proc. - suit = /obj/item/clothing/suit/hooded/oblivion - gloves = /obj/item/clothing/gloves/color/white/supermatter_immune - mask = /obj/item/clothing/mask/gas/voice_modulator/oblivion - l_ear = /obj/item/radio/headset - suit_store = /obj/item/supermatter_halberd - r_pocket = /obj/item/tank/internals/emergency_oxygen/double - box = /obj/item/storage/box/wizard - - //The spells that the enforcer has. - var/list/spell_paths = list(/datum/spell/aoe/conjure/summon_supermatter, - /datum/spell/charge_up/bounce/lightning, /datum/spell/summonitem) - -/datum/outfit/admin/enforcer/post_equip(mob/living/carbon/human/H) - . = ..() - - ADD_TRAIT(H, SM_HALLUCINATION_IMMUNE, MAGIC_TRAIT) - - H.real_name = "Unknown" //Enforcers sacrifice their name to Oblivion for their power - - var/obj/item/clothing/suit/hooded/oblivion/robes = H.wear_suit - if(istype(robes)) - robes.ToggleHood() - - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_accesses(), "Oblivion Enforcer") - -/datum/outfit/admin/enforcer/on_mind_initialize(mob/living/carbon/human/H) - . = ..() - for(var/spell_path in spell_paths) - var/S = new spell_path - H.mind.AddSpell(S) - -/datum/outfit/admin/viper - name = "TSF Viper Infiltrator" - - uniform = /obj/item/clothing/under/solgov/viper - back = /obj/item/storage/backpack/satchel - belt = /obj/item/storage/belt/viper - gloves = /obj/item/clothing/gloves/color/black - shoes = /obj/item/clothing/shoes/jackboots - head = null // will end up being the bandana - mask = /obj/item/clothing/mask/bandana/black // will end up being a cigar - l_ear = /obj/item/radio/headset/ert/alt/solgov - glasses = /obj/item/clothing/glasses/thermal/eyepatch - id = /obj/item/card/id - l_pocket = /obj/item/kitchen/knife/combat - r_pocket = /obj/item/gun/projectile/automatic/pistol - box = /obj/item/storage/box/responseteam - - backpack_contents = list( - /obj/item/storage/box/smoke_grenades = 1, - /obj/item/lighter/zippo = 1, - /obj/item/clothing/mask/cigarette/cigar = 3, - /obj/item/clothing/mask/gas/explorer = 1 - ) - - bio_chips = list(/obj/item/bio_chip/stealth) - - cybernetic_implants = list( - /obj/item/organ/internal/cyberimp/eyes/hud/security, - /obj/item/organ/internal/cyberimp/chest/nutriment/hardened - ) - -/datum/outfit/admin/viper/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - var/codename = pick("Viper", "Serpent", "Python", "Boa", "Basilisk", "Snake", "Mamba", "Sidewinder") - if(prob(50)) - var/codename_prefix = pick("Exposed", "Unveiled", "Phantom", "Mirage", "Punished", "Invisible", "Swift") - codename = "[codename_prefix] [codename]" - H.rename_character(null, codename) - - var/hair_color = "#361A00" - - var/obj/item/organ/external/head/head_organ = H.get_organ("head") - head_organ.h_style = "Bedhead 2" - head_organ.f_style = "Full Beard" - head_organ.hair_colour = hair_color - head_organ.sec_facial_colour = hair_color - head_organ.facial_colour = hair_color - head_organ.sec_hair_colour = hair_color - H.update_hair() - H.update_fhair() - H.update_dna() - - H.wear_mask.adjustmask(H) // push it back on the head - equip_item(H, /obj/item/clothing/mask/cigarette/cigar, ITEM_SLOT_MASK) // get them their cigar - if(istype(H.glasses, /obj/item/clothing/glasses)) // this is gonna be always true - var/obj/item/clothing/glasses/glassass = H.glasses - glassass.over_mask = TRUE - H.update_inv_glasses() - H.gloves.siemens_coefficient = 0 // black "insulated" gloves, since combat gloves look kinda shit - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_MAINT_TUNNELS), "Solar Federation Infilitrator", "lifetimeid") - - H.DeleteComponent(/datum/component/footstep) - - var/datum/martial_art/cqc/CQC = new() - CQC.teach(H) - -/datum/outfit/admin/tourist - name = "Tourist" - uniform = /obj/item/clothing/under/misc/redhawaiianshirt - back = /obj/item/storage/backpack/satchel/withwallet - belt = /obj/item/storage/belt/fannypack - head = /obj/item/clothing/head/boaterhat - l_ear = /obj/item/radio/headset - glasses = /obj/item/clothing/glasses/sunglasses_fake - shoes = /obj/item/clothing/shoes/sandal - id = /obj/item/card/id/assistant - box = /obj/item/storage/box/survival - pda = /obj/item/pda/clear - - backpack_contents = list( - /obj/item/camera = 1, - /obj/item/camera_film = 1, - /obj/item/stack/spacecash/c200 = 1, - /obj/item/storage/fancy/cigarettes/cigpack_robustgold = 1, - /obj/item/lighter/zippo = 1 - ) - -/datum/outfit/admin/tourist/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - // Sets the ID and secHUD icon! - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, list(ACCESS_MAINT_TUNNELS), name, "tourist") - // Checking if the person has an account already - var/datum/money_account/account = H.mind.initial_account - if(!account) - // If they don't, we create a new one and get it's account number. - SSjobs.CreateMoneyAccount(H, null, null) - account = H.mind.initial_account - I.associated_account_number = account.account_number - I.associated_account_number = account.account_number - H.sec_hud_set_ID() - - // PDA setup - var/obj/item/pda/P = H.wear_pda - if(istype(P)) - P.owner = H.real_name - P.ownjob = "Tourist" - P.name = "PDA-[H.real_name] ([P.ownjob])" diff --git a/code/datums/outfits/outfit_debug.dm b/code/datums/outfits/outfit_debug.dm deleted file mode 100644 index 559c9b8b9a21e..0000000000000 --- a/code/datums/outfits/outfit_debug.dm +++ /dev/null @@ -1,333 +0,0 @@ -/datum/outfit/admin/debug - name = "Debug outfit" - - uniform = /obj/item/clothing/under/costume/patriotsuit - back = /obj/item/mod/control/pre_equipped/debug - backpack_contents = list( - /obj/item/melee/energy/axe = 1, - /obj/item/storage/part_replacer/bluespace/tier4 = 1, - /obj/item/gun/magic/wand/resurrection/debug = 1, - /obj/item/gun/magic/wand/death/debug = 1, - /obj/item/debug/human_spawner = 1 - ) - belt = /obj/item/storage/belt/military/abductor/full - l_ear = /obj/item/radio/headset/centcom/debug - glasses = /obj/item/clothing/glasses/hud/debug - mask = /obj/item/clothing/mask/gas/welding/advanced - shoes = /obj/item/clothing/shoes/combat/swat - - box = /obj/item/storage/box/debug/debugtools - suit_store = /obj/item/tank/internals/oxygen - gloves = /obj/item/clothing/gloves/combat - id = /obj/item/card/id/admin - pda = /obj/item/pda/centcom - - internals_slot = ITEM_SLOT_SUIT_STORE - toggle_helmet = TRUE - - cybernetic_implants = list( - /obj/item/organ/internal/cyberimp/arm/surgery/debug, - /obj/item/organ/internal/cyberimp/chest/nutriment/hardened, - /obj/item/organ/internal/cyberimp/arm/janitorial/debug - ) - - -/datum/outfit/admin/debug/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - var/obj/item/card/id/I = H.wear_id - if(istype(I)) - apply_to_card(I, H, get_all_accesses(), "Debugger", "admin") - - H.dna.SetSEState(GLOB.breathlessblock, 1) - singlemutcheck(H, GLOB.breathlessblock, MUTCHK_FORCED) - H.dna.default_blocks.Add(GLOB.breathlessblock) - H.check_mutations = 1 - -/obj/item/radio/headset/centcom/debug - name = "AVD-CNED bowman headset" - ks2type = /obj/item/encryptionkey/syndicate/all_channels - -/// has to be a subtype and stuff -/obj/item/encryptionkey/syndicate/all_channels - name = "AVD-CNED Encryption Key" - desc = "Lets you listen to everything. Use in hand to toggle voice changing. Alt-click to change your fake name." - icon_state = "com_cypherkey" - channels = list("Response Team" = 1, "Special Ops" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Supply" = 1, "Service" = 1, "Procedure" = 1) // just in case - syndie = TRUE - change_voice = FALSE - -/obj/item/encryptionkey/syndicate/all_channels/Initialize(mapload) - . = ..() - for(var/channel in SSradio.radiochannels) - channels[channel] = 1 // yeah, all channels, sure, probably fine - -/obj/item/encryptionkey/syndicate/all_channels/attack_self__legacy__attackchain(mob/user, pickupfireoverride) - change_voice = !change_voice - to_chat(user, "You switch [src] to [change_voice ? "" : "not "]change your voice on syndicate communications.") - -/obj/item/encryptionkey/syndicate/all_channels/AltClick(mob/user) - var/new_name = tgui_input_text(user, "Enter new fake agent name...", "New name", max_length = MAX_NAME_LEN) - if(!new_name) - return - fake_name = new_name - -/obj/item/clothing/mask/gas/welding/advanced - name = "AVD-CNED welding mask" - desc = "Retinal damage is no joke." - tint = FLASH_PROTECTION_NONE - flags_cover = MASKCOVERSEYES|MASKCOVERSMOUTH // vomit prevention when being surrounded by tons of dead bodies - -/obj/item/gun/magic/wand/resurrection/debug - desc = "Is it possible for something to be even more powerful than regular magic? This wand is." - max_charges = 500 - variable_charges = FALSE - can_charge = TRUE - recharge_rate = 1 - -/obj/item/gun/magic/wand/death/debug - desc = "In some obscure circles, this is known as the 'cloning tester's friend'." - max_charges = 500 - variable_charges = FALSE - can_charge = TRUE - recharge_rate = 1 - -/obj/item/clothing/glasses/hud/debug - name = "AVD-CNED glasses" - desc = "Diagnostic, Hydroponic, Medical, Security, and Skills HUD. Built-in advanced reagent scanner. Alt-click to toggle X-ray vision." - icon_state = "nvgmeson" - flags_cover = GLASSESCOVERSEYES - flash_protect = FLASH_PROTECTION_WELDER - scan_reagents_advanced = TRUE - - prescription_upgradable = FALSE - - hud_types = list(DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC_ADVANCED, DATA_HUD_SECURITY_ADVANCED, DATA_HUD_HYDROPONIC) - examine_extensions = list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE, EXAMINE_HUD_MEDICAL_READ, EXAMINE_HUD_MEDICAL_WRITE, EXAMINE_HUD_SKILLS) - - var/xray = FALSE - -/obj/item/clothing/glasses/hud/debug/equipped(mob/living/carbon/human/user, slot) - ..() - if(xray) - add_xray(user) - -/obj/item/clothing/glasses/hud/debug/dropped(mob/living/carbon/human/user) - ..() - if(xray) - remove_xray(user) - -/obj/item/clothing/glasses/hud/debug/AltClick(mob/user) - if(!ishuman(user)) - return - var/mob/living/carbon/human/human_user = user - if(human_user.glasses != src) - return - if(xray) - remove_xray(human_user) - else - add_xray(human_user) - xray = !xray - to_chat(user, "You [!xray ? "de" : ""]activate the x-ray setting on [src]") - human_user.update_sight() - -/obj/item/clothing/glasses/hud/debug/proc/remove_xray(mob/user) - see_in_dark = initial(see_in_dark) - lighting_alpha = initial(lighting_alpha) - REMOVE_TRAIT(user, TRAIT_XRAY_VISION, "debug_glasses[UID()]") - -/obj/item/clothing/glasses/hud/debug/proc/add_xray(mob/user) - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE - ADD_TRAIT(user, TRAIT_XRAY_VISION, "debug_glasses[UID()]") - -/obj/item/debug/human_spawner - name = "human spawner" - desc = "Spawn a human by aiming at a turf and clicking. Use in hand to change type." - icon = 'icons/obj/guns/magic.dmi' - icon_state = "nothingwand" - lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' - righthand_file = 'icons/mob/inhands/items_righthand.dmi' - w_class = WEIGHT_CLASS_SMALL - var/datum/species/selected_species - var/activate_mind = FALSE - -/obj/item/debug/human_spawner/examine(mob/user) - . = ..() - . += "Alt-Click to toggle mind-activation on spawning." - -/obj/item/debug/human_spawner/afterattack__legacy__attackchain(atom/target, mob/user, proximity) - ..() - if(!isturf(target)) - return - var/mob/living/carbon/human/H = new /mob/living/carbon/human(target) - if(selected_species) - H.setup_dna(selected_species.type) - if(activate_mind) - H.mind_initialize() - -/obj/item/debug/human_spawner/attack_self__legacy__attackchain(mob/user) - ..() - var/choice = input("Select a species", "Human Spawner", null) in GLOB.all_species - selected_species = GLOB.all_species[choice] - -/obj/item/debug/human_spawner/AltClick(mob/user) - if(!Adjacent(user)) - return - activate_mind = !activate_mind - to_chat(user, "Any humans spawned will [activate_mind ? "" : "not "]spawn with an initialized mind.") - -/obj/item/rcd/combat/admin - name = "AVD-CNED RCD" - max_matter = INFINITY - matter = INFINITY - locked = FALSE - -/obj/item/stack/spacecash/debug - amount = 50000 - max_amount = 50000 - -/obj/item/bodyanalyzer/debug - name = "AVD-CNED handheld body analyzer" - cell_type = /obj/item/stock_parts/cell/infinite - scan_time = 1 SECONDS - scan_cd = 0 SECONDS - -/obj/item/scalpel/laser/manager/debug - name = "AVD-CNED IMS" - desc = "A wonder of modern medicine. This tool functions as any other sort of surgery tool, and finishes in only a fraction of the time. Hey, how'd you get your hands on this, anyway?" - toolspeed = 0.01 - -/obj/item/scalpel/laser/manager/debug/attack_self__legacy__attackchain(mob/user) - . = ..() - toolspeed = toolspeed == 0.5 ? 0.01 : 0.5 - to_chat(user, "[src] is now set to toolspeed [toolspeed]") - playsound(src, 'sound/effects/pop.ogg', 50, 0) //Change the mode - -/obj/item/organ/internal/cyberimp/arm/surgery/debug - name = "AVD-CNED surgical toolset implant" - contents = newlist( - /obj/item/scalpel/laser/manager/debug, - /obj/item/hemostat/alien, // its needed specifically for some surgeries - /obj/item/circular_saw/alien, - /obj/item/healthanalyzer/advanced, - /obj/item/gun/medbeam, - /obj/item/handheld_defibrillator, - /obj/item/bodyanalyzer/debug - ) - -/obj/item/organ/internal/cyberimp/arm/janitorial/debug - name = "AVD-CNED janitorial toolset implant... is that a... tazer?" - desc = "A set of advanced janitorial tools hidden behind a concealed panel on the user's arm with a tazer? What the fuck." - parent_organ = "l_arm" // left arm by default cuz im lazy - slot = "l_arm_device" - - contents = newlist( - /obj/item/mop/advanced/debug, - /obj/item/soap/syndie/debug, - /obj/item/lightreplacer/bluespace/debug, - /obj/item/reagent_containers/spray/cleaner/advanced/debug, - /obj/item/gun/energy/gun/advtaser/mounted // yeah why not - ) - -/obj/item/mop/advanced/debug - name = "AVD-CNED mop" - desc = "I know you want to do it. Make shit slippery." - mopcap = 100 - mopspeed = 1 - refill_rate = 50 - -/obj/item/soap/syndie/debug - name = "super soap" - desc = "The fastest soap in the space-west." - cleanspeed = 1 - -/obj/item/lightreplacer/bluespace/debug - name = "AVD-CNED light... thingy. You know what it is." - max_uses = 20000 - uses = 20000 - -/obj/item/reagent_containers/spray/cleaner/advanced/debug - name = "AVD-CNED advanced space cleaner" - desc = "AVD-CNED!-brand non-foaming space cleaner! How fancy." - volume = 50000 - spray_maxrange = 10 - spray_currentrange = 10 - list_reagents = list("cleaner" = 50000) - delay = 0.1 SECONDS // it costs 1000 reagents to fire this cleaner... for 12 seconds. - - -// -// Funny matryoshka doll boxes -// - -/obj/item/storage/box/debug - w_class = WEIGHT_CLASS_NORMAL - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = 1000 - storage_slots = 99 - allow_same_size = TRUE - -/obj/item/storage/box/debug/debugtools - name = "debug tools" - -/obj/item/storage/box/debug/debugtools/populate_contents() - new /obj/item/card/emag(src) - new /obj/item/rcd/combat/admin(src) - new /obj/item/geiger_counter(src) - new /obj/item/healthanalyzer/advanced(src) - new /obj/item/rpd/bluespace(src) - new /obj/item/stack/spacecash/debug(src) - new /obj/item/storage/box/beakers/bluespace(src) - new /obj/item/storage/box/debug/material(src) - new /obj/item/storage/box/debug/misc_debug(src) - new /obj/item/storage/box/centcomofficer(src) - new /obj/item/radio/uplink/admin(src) - -/obj/item/storage/box/debug/material - name = "box of materials" - -/obj/item/storage/box/debug/material/populate_contents() - new /obj/item/stack/sheet/metal/fifty(src) - new /obj/item/stack/sheet/plasteel/fifty(src) - new /obj/item/stack/sheet/plastic/fifty(src) - new /obj/item/stack/tile/brass/fifty(src) - new /obj/item/stack/sheet/runed_metal/fifty(src) - new /obj/item/stack/sheet/glass/fifty(src) - new /obj/item/stack/sheet/rglass/fifty(src) - new /obj/item/stack/sheet/plasmaglass/fifty(src) - new /obj/item/stack/sheet/plasmarglass/fifty(src) - new /obj/item/stack/sheet/titaniumglass/fifty(src) - new /obj/item/stack/sheet/plastitaniumglass/fifty(src) - new /obj/item/stack/sheet/mineral/sandstone/fifty(src) - new /obj/item/stack/sheet/mineral/diamond/fifty(src) - new /obj/item/stack/sheet/mineral/uranium/fifty(src) - new /obj/item/stack/sheet/mineral/plasma/fifty(src) - new /obj/item/stack/sheet/mineral/gold/fifty(src) - new /obj/item/stack/sheet/mineral/silver/fifty(src) - new /obj/item/stack/sheet/mineral/bananium/fifty(src) - new /obj/item/stack/sheet/mineral/tranquillite/fifty(src) - new /obj/item/stack/sheet/mineral/titanium/fifty(src) - new /obj/item/stack/sheet/mineral/plastitanium/fifty(src) - new /obj/item/stack/sheet/mineral/abductor/fifty(src) - new /obj/item/stack/sheet/mineral/adamantine/fifty(src) - -/obj/item/storage/box/debug/misc_debug - name = "misc admin items" - -// put cool admin-only shit here :) -/obj/item/storage/box/debug/misc_debug/populate_contents() - new /obj/item/badmin_book(src) - new /obj/item/reagent_containers/drinks/bottle/vodka/badminka(src) - new /obj/item/crowbar/power(src) // >admin only lol - new /obj/item/clothing/gloves/fingerless/rapid/admin(src) - new /obj/item/clothing/under/misc/acj(src) - new /obj/item/clothing/suit/advanced_protective_suit(src) - new /obj/item/multitool/ai_detect/admin(src) // for giggles and shits - new /obj/item/adminfu_scroll(src) - new /obj/item/teleporter/admin(src) - new /obj/item/storage/belt/bluespace/admin(src) // god i love storage nesting - new /obj/item/mining_scanner/admin(src) - new /obj/item/gun/energy/meteorgun/pen(src) - diff --git a/code/datums/outfits/plasmamen_outfits.dm b/code/datums/outfits/plasmamen_outfits.dm deleted file mode 100644 index c18f4e4a0579b..0000000000000 --- a/code/datums/outfits/plasmamen_outfits.dm +++ /dev/null @@ -1,199 +0,0 @@ -/datum/outfit/plasmaman - name = "Plasmaman" - - head = /obj/item/clothing/head/helmet/space/plasmaman - uniform = /obj/item/clothing/under/plasmaman - -/datum/outfit/plasmaman/bar - name = "Plasmaman Bartender" - - head = /obj/item/clothing/head/helmet/space/plasmaman/white - uniform = /obj/item/clothing/under/plasmaman/enviroslacks - -/datum/outfit/plasmaman/chef - name = "Plasmaman Chef" - - head = /obj/item/clothing/head/helmet/space/plasmaman/chef - uniform = /obj/item/clothing/under/plasmaman/chef - -/datum/outfit/plasmaman/botany - name = "Plasmaman Botany" - - head = /obj/item/clothing/head/helmet/space/plasmaman/botany - uniform = /obj/item/clothing/under/plasmaman/botany - -/datum/outfit/plasmaman/librarian - name = "Plasmaman Librarian" - - head = /obj/item/clothing/head/helmet/space/plasmaman/librarian - uniform = /obj/item/clothing/under/plasmaman/librarian - -/datum/outfit/plasmaman/chaplain - name = "Plasmaman Chaplain" - - head = /obj/item/clothing/head/helmet/space/plasmaman/chaplain - uniform = /obj/item/clothing/under/plasmaman/chaplain - -/datum/outfit/plasmaman/janitor - name = "Plasmaman Janitor" - - head = /obj/item/clothing/head/helmet/space/plasmaman/janitor - uniform = /obj/item/clothing/under/plasmaman/janitor - -/datum/outfit/plasmaman/security - name = "Plasmaman Security" - - head = /obj/item/clothing/head/helmet/space/plasmaman/security - uniform = /obj/item/clothing/under/plasmaman/security - -/datum/outfit/plasmaman/detective - name = "Plasmaman Detective" - - head = /obj/item/clothing/head/helmet/space/plasmaman/white - uniform = /obj/item/clothing/under/plasmaman/enviroslacks - -/datum/outfit/plasmaman/warden - name = "Plasmaman Warden" - - head = /obj/item/clothing/head/helmet/space/plasmaman/security/warden - uniform = /obj/item/clothing/under/plasmaman/security/warden - -/datum/outfit/plasmaman/hos - name = "Plasmaman Head of Security" - - head = /obj/item/clothing/head/helmet/space/plasmaman/security/hos - uniform = /obj/item/clothing/under/plasmaman/security/hos - -/datum/outfit/plasmaman/cargo - name = "Plasmaman Cargo" - - head = /obj/item/clothing/head/helmet/space/plasmaman/cargo - uniform = /obj/item/clothing/under/plasmaman/cargo - -/datum/outfit/plasmaman/expedition - name = "Plasmaman Expedition" - - head = /obj/item/clothing/head/helmet/space/plasmaman/expedition - uniform = /obj/item/clothing/under/plasmaman/expedition - -/datum/outfit/plasmaman/mining - name = "Plasmaman Mining" - - head = /obj/item/clothing/head/helmet/space/plasmaman/mining - uniform = /obj/item/clothing/under/plasmaman/mining - -/datum/outfit/plasmaman/medical - name = "Plasmaman Medical" - - head = /obj/item/clothing/head/helmet/space/plasmaman/medical - uniform = /obj/item/clothing/under/plasmaman/medical - -/datum/outfit/plasmaman/cmo - name = "Plasmaman Chief Medical Officer" - - head = /obj/item/clothing/head/helmet/space/plasmaman/cmo - uniform = /obj/item/clothing/under/plasmaman/cmo - -/datum/outfit/plasmaman/viro - name = "Plasmaman Virology" - - head = /obj/item/clothing/head/helmet/space/plasmaman/viro - uniform = /obj/item/clothing/under/plasmaman/viro - -/datum/outfit/plasmaman/chemist - name = "Plasmaman Chemist" - - head = /obj/item/clothing/head/helmet/space/plasmaman/chemist - uniform = /obj/item/clothing/under/plasmaman/chemist - -/datum/outfit/plasmaman/genetics - name = "Plasmaman Genetics" - - head = /obj/item/clothing/head/helmet/space/plasmaman/genetics - uniform = /obj/item/clothing/under/plasmaman/genetics - -/datum/outfit/plasmaman/science - name = "Plasmaman Science" - - head = /obj/item/clothing/head/helmet/space/plasmaman/science - uniform = /obj/item/clothing/under/plasmaman/science - -/datum/outfit/plasmaman/rd - name = "Plasmaman Research Director" - - head = /obj/item/clothing/head/helmet/space/plasmaman/rd - uniform = /obj/item/clothing/under/plasmaman/rd - -/datum/outfit/plasmaman/robotics - name = "Plasmaman Robotics" - - head = /obj/item/clothing/head/helmet/space/plasmaman/robotics - uniform = /obj/item/clothing/under/plasmaman/robotics - -/datum/outfit/plasmaman/engineering - name = "Plasmaman Engineering" - - head = /obj/item/clothing/head/helmet/space/plasmaman/engineering - uniform = /obj/item/clothing/under/plasmaman/engineering - -/datum/outfit/plasmaman/ce - name = "Plasmaman Chief Engineer" - - head = /obj/item/clothing/head/helmet/space/plasmaman/engineering/ce - uniform = /obj/item/clothing/under/plasmaman/engineering/ce - -/datum/outfit/plasmaman/atmospherics - name = "Plasmaman Atmospherics" - - head = /obj/item/clothing/head/helmet/space/plasmaman/atmospherics - uniform = /obj/item/clothing/under/plasmaman/atmospherics - -/datum/outfit/plasmaman/mime - name = "Plasmamime" - - head = /obj/item/clothing/head/helmet/space/plasmaman/mime - uniform = /obj/item/clothing/under/plasmaman/mime - mask = /obj/item/clothing/mask/gas/mime - -/datum/outfit/plasmaman/clown - name = "Plasmaclown" - - head = /obj/item/clothing/head/helmet/space/plasmaman/clown - uniform = /obj/item/clothing/under/plasmaman/clown - mask = /obj/item/clothing/mask/gas/clown_hat - -/datum/outfit/plasmaman/hop - name = "Plasmaman Head of Personnel" - - head = /obj/item/clothing/head/helmet/space/plasmaman/hop - uniform = /obj/item/clothing/under/plasmaman/hop - -/datum/outfit/plasmaman/captain - name = "Plasmaman Captain" - - head = /obj/item/clothing/head/helmet/space/plasmaman/captain - uniform = /obj/item/clothing/under/plasmaman/captain - -/datum/outfit/plasmaman/blueshield - name = "Plasmaman Blueshield" - - head = /obj/item/clothing/head/helmet/space/plasmaman/blueshield - uniform = /obj/item/clothing/under/plasmaman/blueshield - -/datum/outfit/plasmaman/wizard - name = "Plasmaman Wizard" - - head = /obj/item/clothing/head/helmet/space/plasmaman/wizard - uniform = /obj/item/clothing/under/plasmaman/wizard - -/datum/outfit/plasmaman/assistant - name = "Assistant Plasmaman" - - head = /obj/item/clothing/head/helmet/space/plasmaman/assistant - uniform = /obj/item/clothing/under/plasmaman/assistant - -/datum/outfit/plasmaman/trainer - name = "Plasmaman Career Trainer" - - head = /obj/item/clothing/head/helmet/space/plasmaman/trainer - uniform = /obj/item/clothing/under/plasmaman/trainer diff --git a/code/datums/periodic_news.dm b/code/datums/periodic_news.dm deleted file mode 100644 index ed8102f06cfa4..0000000000000 --- a/code/datums/periodic_news.dm +++ /dev/null @@ -1,140 +0,0 @@ -// This system defines news that will be displayed in the course of a round. -// Uses BYOND's type system to put everything into a nice format - -/datum/news_announcement - - var/round_time // time of the round at which this should be announced, in seconds - var/message // body of the message - var/author = "Nanotrasen Editor" - var/channel_name = "Nyx Daily" - var/can_be_redacted = FALSE - var/message_type = "Story" - -/datum/news_announcement/revolution_inciting_event/paycuts_suspicion - round_time = 60*10 - message = {"Reports have leaked that Nanotrasen Inc. is planning to put paycuts into - effect on many of its Research Stations in Tau Ceti. Apparently these research - stations haven't been able to yield the expected revenue, and thus adjustments - have to be made."} - author = "Unauthorized" - -/datum/news_announcement/revolution_inciting_event/paycuts_confirmation - round_time = 60*40 - message = {"Earlier rumours about paycuts on Research Stations in the Tau Ceti system have - been confirmed. Shockingly, however, the cuts will only affect lower tier - personnel. Heads of Staff will, according to our sources, not be affected."} - author = "Unauthorized" - -/datum/news_announcement/revolution_inciting_event/human_experiments - round_time = 60*90 - message = {"Unbelievable reports about human experimentation have reached our ears. According - to a refugee from one of the Tau Ceti Research Stations, their station, in order - to increase revenue, has refactored several of their facilities to perform experiments - on live humans, including virology research, genetic manipulation, and \"feeding them - to the slimes to see what happens\". Allegedly, these test subjects were neither - humanified monkeys nor volunteers, but rather unqualified staff that were forced into - the experiments, and reported to have died in a \"work accident\" by Nanotrasen Inc."} - author = "Unauthorized" - -/datum/news_announcement/bluespace_research - round_time = 60*20 - message = {"The new field of research trying to explain several interesting spacetime oddities, - also known as \"Bluespace Research\", has reached new heights. Of the several - hundred space stations now orbiting in Tau Ceti, fifteen are now specially equipped - to experiment with and research Bluespace effects. Rumours have it some of these - stations even sport functional \"travel gates\" that can instantly move a whole research - team to an alternate reality."} - -/datum/news_announcement/random_junk/cheesy_honkers - author = "Assistant Editor Carl Ritz" - channel_name = "The Gibson Gazette" - message = {"Do cheesy honkers increase risk of having a miscarriage? Several health administrations - say so!"} - round_time = 60 * 15 - -/datum/news_announcement/random_junk/net_block - author = "Assistant Editor Carl Ritz" - channel_name = "The Gibson Gazette" - message = {"Several corporations banding together to block access to 'wetskrell.nt', site administrators - claiming violation of net laws."} - round_time = 60 * 50 - -/datum/news_announcement/random_junk/found_ssd - channel_name = "Nyx Daily" - author = "Doctor Eric Hanfield" - - message = {"Several people have been found unconscious at their terminals. It is thought that it was due - to a lack of sleep or of simply migraines from staring at the screen too long. Camera footage - reveals that many of them were playing games instead of working and their pay has been docked - accordingly."} - round_time = 60 * 90 - -/datum/news_announcement/lotus_tree - channel_name = "Nyx Daily" - author = "Reporter Leland H. Howards" - - message = {"The newly-christened civilian transport Lotus Tree suffered two very large explosions near the - bridge today, and there are unconfirmed reports that the death toll has passed 50. The cause of - the explosions remain unknown, but there is speculation that it might have something to do with - the recent change of regulation in the Moore-Lee Corporation, a major funder of the ship, when M-L - announced that they were officially acknowledging inter-species marriage and providing couples - with marriage tax-benefits."} - round_time = 60 * 30 - -/datum/news_announcement/food_riots/breaking_news - channel_name = "Nyx Daily" - author = "Reporter Ro'kii Ar-Raqis" - - message = {"Breaking news: Food riots have broken out throughout the Refuge asteroid colony in the Tenebrae - Lupus system. This comes only hours after Nanotrasen officials announced they will no longer trade with the - colony, citing the increased presence of \"hostile factions\" on the colony has made trade too dangerous to - continue. Nanotrasen officials have not given any details about said factions. More on that at the top of - the hour."} - round_time = 60 * 10 - -/datum/news_announcement/food_riots/more - channel_name = "Nyx Daily" - author = "Reporter Ro'kii Ar-Raqis" - - message = {"More on the Refuge food riots: The Refuge Council has condemned Nanotrasen's withdrawal from - the colony, claiming \"there has been no increase in anti-Nanotrasen activity\", and \"\[the only] reason - Nanotrasen withdrew was because the \[Tenebrae Lupus] system's Plasma deposits have been completely mined out. - We have little to trade with them now\". Nanotrasen officials have denied these allegations, calling them - \"further proof\" of the colony's anti-Nanotrasen stance. Meanwhile, Refuge Security has been unable to quell - the riots. More on this at 6."} - round_time = 60 * 60 -GLOBAL_LIST_INIT(newscaster_standard_feeds, list(/datum/news_announcement/bluespace_research, /datum/news_announcement/lotus_tree, /datum/news_announcement/random_junk, /datum/news_announcement/food_riots)) - -/proc/process_newscaster() - check_for_newscaster_updates(SSticker.mode.newscaster_announcements) - -GLOBAL_LIST_EMPTY(announced_news_types) - -/proc/check_for_newscaster_updates(type) - for(var/subtype in subtypesof(type)) - var/datum/news_announcement/news = new subtype() - if(news.round_time * 10 <= world.time && !(subtype in GLOB.announced_news_types)) - GLOB.announced_news_types += subtype - announce_newscaster_news(news) - -/proc/announce_newscaster_news(datum/news_announcement/news) - - var/datum/feed_channel/sendto = GLOB.news_network.get_channel_by_name(news.channel_name) - if(!sendto) - sendto = new /datum/feed_channel - sendto.channel_name = news.channel_name - sendto.author = news.author - sendto.frozen = TRUE - sendto.admin_locked = TRUE - GLOB.news_network.channels += sendto - - var/datum/feed_message/newMsg = new /datum/feed_message - newMsg.author = news.author ? news.author : sendto.author - newMsg.admin_locked = !news.can_be_redacted - newMsg.body = news.message - - sendto.add_message(newMsg) - - for(var/nc in GLOB.allNewscasters) - var/obj/machinery/newscaster/NC = nc - NC.alert_news(news.channel_name) diff --git a/code/datums/proximity/advanced_proximity_monitor.dm b/code/datums/proximity/advanced_proximity_monitor.dm deleted file mode 100644 index bd47bfd6cb909..0000000000000 --- a/code/datums/proximity/advanced_proximity_monitor.dm +++ /dev/null @@ -1,168 +0,0 @@ -#define FIELD_TURFS_KEY "field_turfs" -#define EDGE_TURFS_KEY "edge_turfs" - -/** - * Movable and easily code-modified fields! Allows for custom AOE effects that affect movement - * and anything inside of them, and can do custom turf effects! - * Supports automatic recalculation/reset on movement. - * - * "What do I gain from using advanced over standard prox monitors?" - * - You can set different effects on edge vs field entrance - * - You can set effects when the proximity monitor starts and stops tracking a turf - */ -/datum/proximity_monitor/advanced - /// If TRUE, edge turfs will be included as "in the field" for effects - /// Can be used in certain situations where you may have effects that trigger only at the edge, - /// while also wanting the field effect to trigger at edge turfs as well - var/edge_is_a_field = FALSE - /// All turfs on the inside of the proximity monitor - range - 1 turfs - var/list/turf/field_turfs = list() - /// All turfs on the very last tile of the proximity monitor's radius - var/list/turf/edge_turfs = list() - -/datum/proximity_monitor/advanced/Destroy() - cleanup_field() - return ..() - -/datum/proximity_monitor/advanced/proc/cleanup_field() - for(var/turf/turf as anything in edge_turfs) - cleanup_edge_turf(turf) - edge_turfs = list() - for(var/turf/turf as anything in field_turfs) - cleanup_field_turf(turf) - field_turfs = list() - -//Call every time the field moves (done automatically if you use update_center) or a setup specification is changed. -/datum/proximity_monitor/advanced/proc/recalculate_field(full_recalc = FALSE) - var/list/new_turfs = update_new_turfs() - - var/list/old_field_turfs = field_turfs - var/list/old_edge_turfs = edge_turfs - field_turfs = new_turfs[FIELD_TURFS_KEY] - edge_turfs = new_turfs[EDGE_TURFS_KEY] - if(full_recalc) - field_turfs = list() - edge_turfs = list() - - for(var/turf/old_turf as anything in old_field_turfs - field_turfs) - if(QDELETED(src)) - return - cleanup_field_turf(old_turf) - for(var/turf/old_turf as anything in old_edge_turfs - edge_turfs) - if(QDELETED(src)) - return - cleanup_edge_turf(old_turf) - - if(full_recalc) - old_field_turfs = list() - old_edge_turfs = list() - field_turfs = new_turfs[FIELD_TURFS_KEY] - edge_turfs = new_turfs[EDGE_TURFS_KEY] - - for(var/turf/new_turf as anything in field_turfs - old_field_turfs) - if(QDELETED(src)) - return - setup_field_turf(new_turf) - - for(var/turf/new_turf as anything in edge_turfs - old_edge_turfs) - if(QDELETED(src)) - return - setup_edge_turf(new_turf) - -/datum/proximity_monitor/advanced/on_initialized(turf/location, atom/created, init_flags) - . = ..() - on_entered(location, created, null) - -/datum/proximity_monitor/advanced/on_entered(turf/source, atom/movable/entered, turf/old_loc) - . = ..() - if(get_dist(source, host) == current_range) - field_edge_crossed(entered, old_loc, source) - else - field_turf_crossed(entered, old_loc, source) - -/datum/proximity_monitor/advanced/on_moved(atom/movable/movable, atom/old_loc) - . = ..() - if(ignore_if_not_on_turf) - //Early return if it's not the host that has moved. - if(movable != host) - return - //Cleanup the field if the host was on a turf but isn't anymore. - if(!isturf(host.loc)) - if(isturf(old_loc)) - cleanup_field() - return - recalculate_field(full_recalc = FALSE) - -/datum/proximity_monitor/advanced/on_uncrossed(turf/source, atom/movable/gone, direction) - if(get_dist(source, host) == current_range) - field_edge_uncrossed(gone, source, get_turf(gone)) - else - field_turf_uncrossed(gone, source, get_turf(gone)) - -/// Called when a turf in the field of the monitor is linked -/datum/proximity_monitor/advanced/proc/setup_field_turf(turf/target) - return - -/// Called when a turf in the field of the monitor is unlinked -/// Do NOT call this manually, requires management of the field_turfs list -/datum/proximity_monitor/advanced/proc/cleanup_field_turf(turf/target) - PRIVATE_PROC(TRUE) - return - -/// Called when a turf in the edge of the monitor is linked -/datum/proximity_monitor/advanced/proc/setup_edge_turf(turf/target) - if(edge_is_a_field) // If the edge is considered a field, set it up like one - setup_field_turf(target) - -/// Called when a turf in the edge of the monitor is unlinked -/// Do NOT call this manually, requires management of the edge_turfs list -/datum/proximity_monitor/advanced/proc/cleanup_edge_turf(turf/target) - if(edge_is_a_field) // If the edge is considered a field, clean it up like one - cleanup_field_turf(target) - -/datum/proximity_monitor/advanced/proc/update_new_turfs() - if(ignore_if_not_on_turf && !isturf(host.loc)) - return list(FIELD_TURFS_KEY = list(), EDGE_TURFS_KEY = list()) - var/list/local_field_turfs = list() - var/list/local_edge_turfs = list() - var/turf/center = get_turf(host) - if(current_range > 0) - local_field_turfs += RANGE_TURFS(current_range - 1, center) - if(current_range > 1) - local_edge_turfs = RANGE_TURFS(current_range, center) - local_field_turfs - return list(FIELD_TURFS_KEY = local_field_turfs, EDGE_TURFS_KEY = local_edge_turfs) - -//Gets edge direction/corner, only works with square radius/WDH fields! -/datum/proximity_monitor/advanced/proc/get_edgeturf_direction(turf/T, turf/center_override = null) - var/turf/checking_from = get_turf(host) - if(istype(center_override)) - checking_from = center_override - if(!(T in edge_turfs)) - return - if(((T.x == (checking_from.x + current_range)) || (T.x == (checking_from.x - current_range))) && ((T.y == (checking_from.y + current_range)) || (T.y == (checking_from.y - current_range)))) - return get_dir(checking_from, T) - if(T.x == (checking_from.x + current_range)) - return EAST - if(T.x == (checking_from.x - current_range)) - return WEST - if(T.y == (checking_from.y - current_range)) - return SOUTH - if(T.y == (checking_from.y + current_range)) - return NORTH - -/datum/proximity_monitor/advanced/proc/field_turf_crossed(atom/movable/movable, turf/old_location, turf/new_location) - return - -/datum/proximity_monitor/advanced/proc/field_turf_uncrossed(atom/movable/movable, turf/old_location, turf/new_location) - return - -/datum/proximity_monitor/advanced/proc/field_edge_crossed(atom/movable/movable, turf/old_location, turf/new_location) - if(edge_is_a_field) // If the edge is considered a field, pass crossed to that - field_turf_crossed(movable, old_location, new_location) - -/datum/proximity_monitor/advanced/proc/field_edge_uncrossed(atom/movable/movable, turf/old_location, turf/new_location) - if(edge_is_a_field) // If the edge is considered a field, pass uncrossed to that - field_turf_uncrossed(movable, old_location, new_location) - -#undef FIELD_TURFS_KEY -#undef EDGE_TURFS_KEY diff --git a/code/datums/proximity/proximity_monitor.dm b/code/datums/proximity/proximity_monitor.dm deleted file mode 100644 index 09a7d32f916d5..0000000000000 --- a/code/datums/proximity/proximity_monitor.dm +++ /dev/null @@ -1,89 +0,0 @@ -/datum/proximity_monitor - ///The atom we are tracking - var/atom/host - ///The atom that will receive HasProximity calls. - var/atom/hasprox_receiver - ///The range of the proximity monitor. Things moving wihin it will trigger HasProximity calls. - var/current_range - ///If we don't check turfs in range if the host's loc isn't a turf - var/ignore_if_not_on_turf - ///The signals of the connect range component, needed to monitor the turfs in range. - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_entered), - COMSIG_ATOM_EXITED = PROC_REF(on_uncrossed), - COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON = PROC_REF(on_initialized), - ) - -/datum/proximity_monitor/New(atom/_host, range = 1, _ignore_if_not_on_turf = TRUE) - ignore_if_not_on_turf = _ignore_if_not_on_turf - current_range = range - set_host(_host) - -/datum/proximity_monitor/proc/set_host(atom/new_host, atom/new_receiver) - if(new_host == host) - return - if(host) //No need to delete the connect range and containers comps. They'll be updated with the new tracked host. - UnregisterSignal(host, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) - if(hasprox_receiver) - UnregisterSignal(hasprox_receiver, COMSIG_PARENT_QDELETING) - if(new_receiver) - hasprox_receiver = new_receiver - if(new_receiver != new_host) - RegisterSignal(new_receiver, COMSIG_PARENT_QDELETING, PROC_REF(on_host_or_receiver_del)) - else if(hasprox_receiver == host) //Default case - hasprox_receiver = new_host - host = new_host - RegisterSignal(new_host, COMSIG_PARENT_QDELETING, PROC_REF(on_host_or_receiver_del)) - var/static/list/containers_connections = list(COMSIG_MOVABLE_MOVED = PROC_REF(on_moved), COMSIG_MOVABLE_Z_CHANGED = PROC_REF(on_z_change)) - AddComponent(/datum/component/connect_containers, host, containers_connections) - RegisterSignal(host, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) - RegisterSignal(host, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(on_z_change)) - set_range(current_range, TRUE) - -/datum/proximity_monitor/proc/on_host_or_receiver_del(datum/source) - SIGNAL_HANDLER // COMSIG_PARENT_QDELETING - qdel(src) - -/datum/proximity_monitor/Destroy() - host = null - hasprox_receiver = null - return ..() - -/datum/proximity_monitor/proc/set_range(range, force_rebuild = FALSE) - if(!force_rebuild && range == current_range) - return FALSE - . = TRUE - current_range = range - - //If the connect_range component exists already, this will just update its range. No errors or duplicates. - AddComponent(/datum/component/connect_range, host, loc_connections, range, !ignore_if_not_on_turf) - -/datum/proximity_monitor/proc/on_moved(atom/movable/source, atom/old_loc) - SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED - if(source == host) - hasprox_receiver?.HasProximity(host) - -/datum/proximity_monitor/proc/on_z_change() - SIGNAL_HANDLER // COMSIG_MOVABLE_Z_CHANGED - return - -/datum/proximity_monitor/proc/set_ignore_if_not_on_turf(does_ignore = TRUE) - if(ignore_if_not_on_turf == does_ignore) - return - ignore_if_not_on_turf = does_ignore - //Update the ignore_if_not_on_turf - AddComponent(/datum/component/connect_range, host, loc_connections, current_range, ignore_if_not_on_turf) - -/datum/proximity_monitor/proc/on_uncrossed() - SIGNAL_HANDLER // COMSIG_ATOM_EXITED - return //Used by the advanced subtype for effect fields. - -/datum/proximity_monitor/proc/on_entered(atom/source, atom/movable/arrived, turf/old_loc) - SIGNAL_HANDLER // COMSIG_ATOM_ENTERED - if(source != host) - hasprox_receiver?.HasProximity(arrived) - -/datum/proximity_monitor/proc/on_initialized(turf/location, atom/created, init_flags) - SIGNAL_HANDLER // COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON - if(location != host) - hasprox_receiver?.HasProximity(created) diff --git a/code/datums/proximity/singulo_proximity_monitor.dm b/code/datums/proximity/singulo_proximity_monitor.dm deleted file mode 100644 index e7b870ba346a0..0000000000000 --- a/code/datums/proximity/singulo_proximity_monitor.dm +++ /dev/null @@ -1,28 +0,0 @@ -/datum/proximity_monitor/advanced/singulo - -/datum/proximity_monitor/advanced/singulo/on_entered(turf/source, atom/movable/entered, turf/old_loc) - . = ..() - if(!isprojectile(entered)) - return - - var/angle_to_singulo = ATAN2(host.y - source.y, host.x - source.x) - var/distance_to_singulo = get_dist(source, host) - - var/obj/item/projectile/P = entered - var/distance = distance_to_singulo - var/projectile_angle = P.Angle - var/angle_to_projectile = angle_to_singulo - if(angle_to_projectile == 180) - angle_to_projectile = -180 - angle_to_projectile -= projectile_angle - if(angle_to_projectile > 180) - angle_to_projectile -= 360 - else if(angle_to_projectile < -180) - angle_to_projectile += 360 - - if(distance == 0) - qdel(P) - return - projectile_angle += angle_to_projectile / (distance ** 2) - P.damage += 10 / distance - P.set_angle(projectile_angle) diff --git a/code/datums/radiation_wave.dm b/code/datums/radiation_wave.dm deleted file mode 100644 index 241766da2271f..0000000000000 --- a/code/datums/radiation_wave.dm +++ /dev/null @@ -1,141 +0,0 @@ -/datum/radiation_wave - /// The thing that spawned this radiation wave - var/source - /// The center of the wave - var/turf/master_turf - /// How far we've moved - var/steps = 0 - /// How strong it was originaly - var/intensity - /// How much contaminated material it still has - var/remaining_contam - /// Higher than 1 makes it drop off faster, 0.5 makes it drop off half etc - var/range_modifier - /// The distance from the source point the wave can cover without losing any strength. - var/source_radius - /// The direction of movement - var/move_dir - /// The directions to the side of the wave, stored for easy looping - var/list/__dirs - /// Whether or not this radiation wave can create contaminated objects - var/can_contaminate - -/datum/radiation_wave/New(atom/_source, dir, _intensity = 0, _range_modifier = RAD_DISTANCE_COEFFICIENT, _can_contaminate = TRUE, _source_radius = 0) - - source = "[_source] \[[_source.UID()]\]" - - master_turf = get_turf(_source) - - move_dir = dir - __dirs = list() - __dirs += turn(dir, 90) - __dirs += turn(dir, -90) - - intensity = _intensity - remaining_contam = intensity - range_modifier = _range_modifier - can_contaminate = _can_contaminate - source_radius = _source_radius - START_PROCESSING(SSradiation, src) - -/datum/radiation_wave/Destroy() - . = QDEL_HINT_IWILLGC - STOP_PROCESSING(SSradiation, src) - ..() - -/datum/radiation_wave/process() - master_turf = get_step(master_turf, move_dir) - if(!master_turf) - qdel(src) - return - steps++ - var/list/atoms = get_rad_atoms() - - var/strength - if(steps > source_radius + 1) - strength = INVERSE_SQUARE(intensity, max(range_modifier * (steps - source_radius), 1), 1) - else - strength = intensity - - if(strength < RAD_BACKGROUND_RADIATION) - qdel(src) - return - radiate(atoms, strength) - check_obstructions(atoms) // reduce our overall strength if there are radiation insulators - -/datum/radiation_wave/proc/get_rad_atoms() - var/list/atoms = list() - var/distance = steps - var/cmove_dir = move_dir - var/cmaster_turf = master_turf - - if(cmove_dir == NORTH || cmove_dir == SOUTH) - distance-- //otherwise corners overlap - - atoms += get_rad_contents(cmaster_turf) - - var/turf/place - for(var/dir in __dirs) //There should be just 2 dirs in here, left and right of the direction of movement - place = cmaster_turf - for(var/i in 1 to distance) - place = get_step(place, dir) - if(!place) - break - atoms += get_rad_contents(place) - - return atoms - -/datum/radiation_wave/proc/check_obstructions(list/atoms) - var/width = steps - var/cmove_dir = move_dir - if(cmove_dir == NORTH || cmove_dir == SOUTH) - width-- - width = 1 + (2 * width) - - for(var/k in 1 to length(atoms)) - var/atom/thing = atoms[k] - if(!thing) - continue - if(SEND_SIGNAL(thing, COMSIG_ATOM_RAD_WAVE_PASSING, src, width) & COMPONENT_RAD_WAVE_HANDLED) - continue - if(thing.rad_insulation != RAD_NO_INSULATION) - intensity *= (1 - ((1 - thing.rad_insulation) / width)) - -/datum/radiation_wave/proc/radiate(list/atoms, strength) - var/can_contam = strength >= RAD_MINIMUM_CONTAMINATION - var/contamination_strength = (strength - RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_STR_COEFFICIENT - contamination_strength = max(contamination_strength, RAD_BACKGROUND_RADIATION) - // It'll never reach 100% chance but the further out it gets the more likely it'll contaminate - var/contamination_chance = 100 - (90 / (1 + steps * 0.1)) - for(var/k in atoms) - var/atom/thing = k - if(QDELETED(thing)) - continue - thing.rad_act(strength) - - // This list should only be for types which don't get contaminated but you want to look in their contents - // If you don't want to look in their contents and you don't want to rad_act them: - // modify the ignored_things list in __HELPERS/radiation.dm instead - var/static/list/blacklisted = typecacheof(list( - /turf, - /obj/structure/cable, - /obj/machinery/atmospherics, - /obj/item/ammo_casing, - /obj/item/bio_chip, - /obj/singularity, - )) - if(!can_contaminate || !can_contam || blacklisted[thing.type]) - continue - if(thing.flags_2 & RAD_NO_CONTAMINATE_2 || SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING, strength) & COMPONENT_BLOCK_CONTAMINATION) - continue - - if(contamination_strength > remaining_contam) - contamination_strength = remaining_contam - if(!prob(contamination_chance)) - continue - if(SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING, strength) & COMPONENT_BLOCK_CONTAMINATION) - continue - remaining_contam -= contamination_strength - if(remaining_contam < RAD_BACKGROUND_RADIATION) - can_contaminate = FALSE - thing.AddComponent(/datum/component/radioactive, contamination_strength, source) diff --git a/code/datums/ruins/bridges/bridges.dm b/code/datums/ruins/bridges/bridges.dm deleted file mode 100644 index 50be4d96c8345..0000000000000 --- a/code/datums/ruins/bridges/bridges.dm +++ /dev/null @@ -1,288 +0,0 @@ -#define LONG_BRIDGE_THEME_CULT "cult" -#define LONG_BRIDGE_THEME_HIERO "hiero" -#define LONG_BRIDGE_THEME_CLOCKWORK "clockwork" -#define LONG_BRIDGE_THEME_STONE "stone" -#define LONG_BRIDGE_THEME_WOOD "wood" -#define LONG_BRIDGE_THEME_CATWALK "catwalk" - -/** - * A spawner for dynamic bridges, largely with hardcoded expectations to be - * operating on Lavaland. - * - * It does this by starting at its spawn point, placed by a - * [/datum/river_spawner] during generation, and walking in each direction - * "forwards" and "backwards" until it reaches the maximum possible length of - * the bridge, or a tile that doesn't appear to be a valid "passage" - * (essentially a tile that doesn't have lava on both sides and thus wouldn't - * look good or make an effective bridge). If it manages to do this and find two - * tiles that work as the start and end of the bridge, it places the paths, - * pillars, and "cleans up" the tiles contiguous to its entrance and exit turfs, - * removing any lava if present. - * - * It attempts this first in the vertical direction, and then the horizontal. So - * "fowards" and "backwards" can mean NORTH/SOUTH or EAST/WEST depending on the - * direction it's attempting. - * - * There are several bridge "themes" implemented in `make_walkway()` and - * `make_pillar()`, and more can be added if desired. - */ -/obj/effect/spawner/dynamic_bridge - var/max_length = 8 - var/min_length = 4 - var/bridge_theme = LONG_BRIDGE_THEME_CULT - var/list/forwards_backwards - var/list/side_to_side - var/turf/forward_goal - var/turf/backward_goal - -/obj/effect/spawner/dynamic_bridge/Initialize(mapload) - . = ..() - bridge_theme = pick( - LONG_BRIDGE_THEME_CULT, - LONG_BRIDGE_THEME_HIERO, - LONG_BRIDGE_THEME_CLOCKWORK, - LONG_BRIDGE_THEME_STONE, - LONG_BRIDGE_THEME_WOOD, - LONG_BRIDGE_THEME_CATWALK, - ) - return INITIALIZE_HINT_LATELOAD - -/obj/effect/spawner/dynamic_bridge/LateInitialize() - forwards_backwards = list(NORTH, SOUTH) - side_to_side = list(EAST, WEST) - if(!attempt_bridge()) - forward_goal = null - backward_goal = null - forwards_backwards = list(EAST, WEST) - side_to_side = list(NORTH, SOUTH) - attempt_bridge() - - qdel(src) - -/// Returns whether the passed in turf is a valid "landing". A valid landing is -/// a tile that hasn't been reserved by another bridge, and has a non-lava tile -/// leading directly to it. -/obj/effect/spawner/dynamic_bridge/proc/valid_landing(turf/T, direction) - if(T.flags & LAVA_BRIDGE || T.flags & NO_LAVA_GEN) - return FALSE - - var/turf/end = get_step(T, direction) - if(end.flags & LAVA_BRIDGE || !(ismineralturf(end) || istype(end, /turf/simulated/floor/plating/asteroid))) - return FALSE - - return TRUE - -/// Returns whether the passed in turf is a valid "passage". A valid passage is -/// a lava tile that has lava on both sides of it. Invalid passage tiles do not -/// look good as bridge walkways and defeat the purpose of there is floor right -/// next to it. -/obj/effect/spawner/dynamic_bridge/proc/valid_passage(turf/T) - if(T.flags & LAVA_BRIDGE) - return FALSE - if(!istype(T, /turf/simulated/floor/lava/mapping_lava)) - return FALSE - if(!istype(get_step(T, side_to_side[1]), /turf/simulated/floor/lava/mapping_lava)) - return FALSE - if(!istype(get_step(T, side_to_side[2]), /turf/simulated/floor/lava/mapping_lava)) - return FALSE - - return TRUE - -/obj/effect/spawner/dynamic_bridge/proc/make_pillar(turf/T) - for(var/obj/structure/spawner/S in T) - qdel(S) - for(var/mob/living/M in T) - qdel(M) - for(var/obj/structure/flora/F in T) - qdel(F) - - switch(bridge_theme) - if(LONG_BRIDGE_THEME_CULT) - T.ChangeTurf(/turf/simulated/wall/cult) - if(LONG_BRIDGE_THEME_HIERO) - T.ChangeTurf(/turf/simulated/wall/indestructible/hierophant) - if(LONG_BRIDGE_THEME_CLOCKWORK) - T.ChangeTurf(/turf/simulated/wall/clockwork) - if(LONG_BRIDGE_THEME_STONE) - T.ChangeTurf(/turf/simulated/wall/cult) - if(LONG_BRIDGE_THEME_WOOD) - T.ChangeTurf(/turf/simulated/wall/mineral/wood/nonmetal) - if(LONG_BRIDGE_THEME_CATWALK) - new /obj/structure/lattice/catwalk/mining(T) - new /obj/structure/marker_beacon/dock_marker/collision(T) - - T.flags |= LAVA_BRIDGE - -/obj/structure/bridge_walkway - name = "floor" - icon = 'icons/turf/floors.dmi' - layer = ABOVE_OPEN_TURF_LAYER - anchored = TRUE - resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - -/obj/structure/bridge_walkway/Destroy() - var/turf/T = get_turf(src) - if(T) - T.layer = PLATING_LAYER - T.clear_filters() - - return ..() - -/obj/structure/bridge_walkway/cult - icon_state = "cult" - -/obj/structure/bridge_walkway/hiero - icon = 'icons/turf/floors/hierophant_floor.dmi' - icon_state = "floor" - -/obj/structure/bridge_walkway/clockwork - name = "clockwork floor" - icon_state = "clockwork_floor" - -/obj/structure/bridge_walkway/clockwork/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_crossed) - ) - AddElement(/datum/element/connect_loc, loc_connections) - -// Pretend to be a normal clockwork floor and duplicate its visual effect -/obj/structure/bridge_walkway/clockwork/proc/on_crossed(atom/crosser) - var/counter = 0 - for(var/obj/effect/temp_visual/ratvar/floor/floor in contents) - if(++counter == 3) - return - - if(!. && isliving(crosser)) - addtimer(CALLBACK(src, PROC_REF(spawn_visual)), 0.2 SECONDS, TIMER_DELETE_ME) - -/obj/structure/bridge_walkway/clockwork/proc/spawn_visual() - new /obj/effect/temp_visual/ratvar/floor(loc) - -/obj/structure/bridge_walkway/wood - icon_state = "wood" - -/obj/effect/spawner/dynamic_bridge/proc/make_walkway(turf/T) - for(var/obj/structure/spawner/S in T) - qdel(S) - for(var/mob/living/M in T) - qdel(M) - for(var/obj/structure/flora/F in T) - qdel(F) - - switch(bridge_theme) - if(LONG_BRIDGE_THEME_CULT) - new /obj/structure/bridge_walkway/cult(T) - if(LONG_BRIDGE_THEME_HIERO) - new /obj/structure/bridge_walkway/hiero(T) - if(LONG_BRIDGE_THEME_CLOCKWORK) - new /obj/structure/bridge_walkway/clockwork(T) - if(LONG_BRIDGE_THEME_STONE) - // Stone tiles are different sizes and shapes so these are - // "safe-looking" arrangements. - switch(rand(1, 5)) - if(1) - new /obj/structure/stone_tile/block(T) - var/obj/structure/stone_tile/block/cracked/C = new(T) - C.dir = NORTH - if(2) - new /obj/structure/stone_tile/slab(T) - if(3) - new /obj/structure/stone_tile/surrounding(T) - new /obj/structure/stone_tile/center(T) - if(4) - new /obj/structure/stone_tile/slab/cracked(T) - if(5) - new /obj/structure/stone_tile/burnt(T) - var/obj/structure/stone_tile/surrounding_tile/ST = new(T) - ST.dir = WEST - var/obj/structure/stone_tile/block/B = new(T) - B.dir = NORTH - if(LONG_BRIDGE_THEME_WOOD) - var/obj/structure/bridge_walkway/wood/tile = new(T) - if(prob(20)) - tile.icon_state = pick("wood-broken", "wood-broken2", "wood-broken3", "wood-broken4", "wood-broken5", "wood-broken6", "wood-broken7") - if(LONG_BRIDGE_THEME_CATWALK) - new /obj/structure/lattice/catwalk/mining(T) - - T.flags |= LAVA_BRIDGE - -/// Make a tile safe for player passage, for use at the bridge entrance and exits -/obj/effect/spawner/dynamic_bridge/proc/cleanup_edge(turf/T) - if(istype(T, /turf/simulated/floor/lava/mapping_lava)) - T.ChangeTurf(/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface) - T.icon_state = "basalt" // hate - -/obj/effect/spawner/dynamic_bridge/proc/attempt_bridge() - var/count = 1 - var/walk_dir = forwards_backwards[1] - var/turf/forward_step = get_turf(src) - var/turf/backward_step = get_turf(src) - var/bad_passage = FALSE - - while(count <= max_length && !(forward_goal && backward_goal) && !bad_passage) - if(walk_dir == forwards_backwards[1]) - if(!forward_goal) - if(out_of_bounds(walk_dir, forward_step)) - break // Out of bounds - forward_step = get_step(forward_step, walk_dir) - if(valid_landing(forward_step, walk_dir)) - forward_goal = forward_step - else if(!valid_passage(forward_step)) - bad_passage = TRUE - count++ - walk_dir = forwards_backwards[2] - else - if(!backward_goal) - if(out_of_bounds(walk_dir, backward_step)) - break // Out of bounds - backward_step = get_step(backward_step, walk_dir) - if(valid_landing(backward_step, walk_dir)) - backward_goal = backward_step - else if(!valid_passage(backward_step)) - bad_passage = TRUE - count++ - walk_dir = forwards_backwards[1] - - if(!bad_passage && count >= min_length && forward_goal && backward_goal) - for(var/turf/T in get_line(forward_goal, backward_goal)) - make_walkway(T) - for(var/turf/T in list( - get_step(forward_goal, side_to_side[1]), - get_step(forward_goal, side_to_side[2]), - get_step(backward_goal, side_to_side[1]), - get_step(backward_goal, side_to_side[2]))) - make_pillar(T) - for(var/turf/T in get_line( - get_step(get_step(forward_goal, side_to_side[1]), forwards_backwards[1]), - get_step(get_step(forward_goal, side_to_side[2]), forwards_backwards[1]))) - cleanup_edge(T) - for(var/turf/T in get_line( - get_step(get_step(backward_goal, side_to_side[1]), forwards_backwards[2]), - get_step(get_step(backward_goal, side_to_side[2]), forwards_backwards[2]))) - cleanup_edge(T) - - return TRUE - -/// Checks if we are going out of bounds. Returns TRUE if we are close (less than or equal to 2 turfs) to a border -/obj/effect/spawner/dynamic_bridge/proc/out_of_bounds(direction, turf/current_turf) - if(!direction || !current_turf) - return TRUE - - switch(direction) - if(NORTH) - return current_turf.y >= world.maxy - 2 - if(EAST) - return current_turf.x >= world.maxx - 2 - if(SOUTH) - return current_turf.y <= 2 - if(WEST) - return current_turf.x <= 2 - return TRUE - -#undef LONG_BRIDGE_THEME_CULT -#undef LONG_BRIDGE_THEME_HIERO -#undef LONG_BRIDGE_THEME_CLOCKWORK -#undef LONG_BRIDGE_THEME_STONE -#undef LONG_BRIDGE_THEME_WOOD -#undef LONG_BRIDGE_THEME_CATWALK diff --git a/code/datums/ruins/ruin_placer.dm b/code/datums/ruins/ruin_placer.dm deleted file mode 100644 index 0d53c9bb71b75..0000000000000 --- a/code/datums/ruins/ruin_placer.dm +++ /dev/null @@ -1,203 +0,0 @@ -#define DEFAULT_PADDING 32 - -/datum/ruin_placement - var/datum/map_template/ruin/ruin - var/base_padding - var/padding - -/datum/ruin_placement/New(datum/map_template/ruin/ruin_, padding_ = DEFAULT_PADDING, base_padding_ = 0) - . = ..() - ruin = ruin_ - base_padding = base_padding_ - padding = padding_ - -/datum/ruin_placement/proc/reduce_padding() - padding = max(floor(padding / 2) - 1, -1) - -/datum/ruin_placement/proc/try_to_place(zlist_or_zlevel, area_whitelist) - var/list/z_levels = islist(zlist_or_zlevel) ? zlist_or_zlevel : list(zlist_or_zlevel) - - // Our goal is to maximize padding, so we'll perform some number of attempts - // on one z-level, then the next, until we reach some limit, then reduce the - // padding and start again. - padding = DEFAULT_PADDING - while(padding >= 0) - var/width_border = base_padding + round(ruin.width / 2) + padding - var/height_border = base_padding + round(ruin.height / 2) + padding - - for(var/z_level in z_levels) - var/placement_tries = PLACEMENT_TRIES - while(placement_tries > 0) - placement_tries-- - - var/turf/central_turf = locate( - rand(width_border, world.maxx - width_border), - rand(height_border, world.maxy - height_border), - z_level - ) - var/valid = TRUE - - if(!central_turf) - continue - - // Expand the original bounds of the ruin with our padding and call - // that our list of affected turfs. - var/list/bounds = ruin.get_coordinate_bounds(central_turf, centered = TRUE) - var/datum/coords/bottom_left = bounds["bottom_left"] - var/datum/coords/top_right = bounds["top_right"] - bottom_left.x_pos -= padding - bottom_left.y_pos -= padding - top_right.x_pos += padding - top_right.y_pos += padding - var/list/affected_turfs = block(bottom_left.x_pos, bottom_left.y_pos, z_level, top_right.x_pos, top_right.y_pos, z_level) - - // One sanity check just in case - if(!ruin.fits_in_map_bounds(central_turf, centered = TRUE)) - valid = FALSE - - for(var/turf/check in affected_turfs) - var/area/new_area = get_area(check) - if(!(istype(new_area, area_whitelist)) || check.flags & NO_RUINS) - valid = FALSE - break - - if(!valid) - continue - - for(var/turf/T in affected_turfs) - for(var/obj/structure/spawner/nest in T) - qdel(nest) - for(var/mob/living/simple_animal/monster in T) - qdel(monster) - for(var/obj/structure/flora/ash/plant in T) - qdel(plant) - - ruin.load(central_turf, centered = TRUE) - for(var/turf/T in ruin.get_affected_turfs(central_turf, centered = TRUE)) // Just flag the actual ruin turfs! - T.flags |= NO_RUINS - new /obj/effect/landmark/ruin(central_turf, ruin) - ruin.loaded++ - - log_world("Ruin \"[ruin.name]\" placed at ([central_turf.x], [central_turf.y], [central_turf.z])") - - var/map_filename = splittext(ruin.mappath, "/") - map_filename = map_filename[length(map_filename)] - SSblackbox.record_feedback("associative", "ruin_placement", 1, list( - "map" = map_filename, - "coords" = "[central_turf.x],[central_turf.y],[central_turf.z]" - )) - - return TRUE - - // Ran out of placement tries for this z-level/padding, move to the next z-level - - // Ran out of z-levels to try with this padding, cut it and start again - reduce_padding() - - // Ran out of z-levels, we got nowhere to place it - return FALSE - -/datum/ruin_placer - var/ruin_budget - var/area_whitelist - var/list/templates - var/base_padding - -/datum/ruin_placer/proc/place_ruins(z_levels) - if(!z_levels || !length(z_levels)) - WARNING("No Z levels provided - Not generating ruins") - return - - for(var/zl in z_levels) - var/turf/T = locate(1, 1, zl) - if(!T) - WARNING("Z level [zl] does not exist - Not generating ruins") - return - - var/list/ruins = templates.Copy() - - var/list/forced_ruins = list() //These go first on the z level associated (same random one by default) - var/list/ruins_availible = list() //we can try these in the current pass - var/forced_z //If set we won't pick z level and use this one instead. - - //Set up the starting ruin list - for(var/key in ruins) - var/datum/map_template/ruin/R = ruins[key] - if(R.get_cost() > ruin_budget) //Why would you do that - continue - if(R.always_place) - forced_ruins[R] = -1 - if(R.unpickable) - continue - ruins_availible[R] = R.placement_weight - - while(ruin_budget > 0 && (length(ruins_availible) || length(forced_ruins))) - var/datum/map_template/ruin/current_pick - var/forced = FALSE - if(length(forced_ruins)) //We have something we need to load right now, so just pick it - for(var/ruin in forced_ruins) - current_pick = ruin - if(forced_ruins[ruin] > 0) //Load into designated z - forced_z = forced_ruins[ruin] - forced = TRUE - break - else //Otherwise just pick random one - current_pick = pickweight(ruins_availible) - - var/datum/ruin_placement/placement = new(current_pick, base_padding_ = base_padding) - var/placement_success = placement.try_to_place(forced_z ? forced_z : z_levels, area_whitelist) - - //That's done remove from priority even if it failed - if(forced) - //TODO : handle forced ruins with multiple variants - forced_ruins -= current_pick - forced = FALSE - - if(placement_success) - ruin_budget -= current_pick.get_cost() - if(!current_pick.allow_duplicates) - for(var/datum/map_template/ruin/R in ruins_availible) - if(R.id == current_pick.id) - ruins_availible -= R - if(current_pick.never_spawn_with) - for(var/blacklisted_type in current_pick.never_spawn_with) - for(var/possible_exclusion in ruins_availible) - if(istype(possible_exclusion,blacklisted_type)) - ruins_availible -= possible_exclusion - else - for(var/datum/map_template/ruin/R in ruins_availible) - if(R.id == current_pick.id) - ruins_availible -= R - log_world("Failed to place [current_pick.name] ruin.") - - forced_z = 0 - - //Update the availible list - for(var/datum/map_template/ruin/R in ruins_availible) - if(R.get_cost() > ruin_budget) - ruins_availible -= R - - log_world("Ruin loader finished with [ruin_budget] left to spend.") - -#undef DEFAULT_PADDING - -/datum/ruin_placer/space - area_whitelist = /area/space - base_padding = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD - -/datum/ruin_placer/space/New() - ruin_budget = rand( - GLOB.configuration.ruins.space_ruin_budget_min, - GLOB.configuration.ruins.space_ruin_budget_max - ) - templates = GLOB.space_ruins_templates - -/datum/ruin_placer/lavaland - area_whitelist = /area/lavaland/surface/outdoors/unexplored - -/datum/ruin_placer/lavaland/New() - ruin_budget = rand( - GLOB.configuration.ruins.lavaland_ruin_budget_min, - GLOB.configuration.ruins.lavaland_ruin_budget_max - ) - templates = GLOB.lava_ruins_templates diff --git a/code/datums/spells/alien_spells/basetype_alien_spell.dm b/code/datums/spells/alien_spells/basetype_alien_spell.dm deleted file mode 100644 index 02ac8ddab2a2f..0000000000000 --- a/code/datums/spells/alien_spells/basetype_alien_spell.dm +++ /dev/null @@ -1,46 +0,0 @@ -/mob/living/carbon/proc/use_plasma_spell(amount, mob/living/carbon/user) - var/obj/item/organ/internal/alien/plasmavessel/vessel = get_int_organ(/obj/item/organ/internal/alien/plasmavessel) - if(amount > vessel.stored_plasma) - return FALSE - add_plasma(-amount) - return TRUE - -/* add_plasma just requires the plasma amount, so admins can easily varedit it and stuff -Updates the spell's actions on use as well, so they know when they can or can't use their powers*/ - -/mob/living/carbon/proc/add_plasma(amount) - var/obj/item/organ/internal/alien/plasmavessel/vessel = get_int_organ(/obj/item/organ/internal/alien/plasmavessel) - if(!vessel) - return - vessel.stored_plasma = clamp(vessel.stored_plasma + amount, 0, vessel.max_plasma) - update_plasma_display(src) - for(var/datum/action/spell_action/action in actions) - action.UpdateButtons() - -/datum/spell/alien_spell - action_background_icon_state = "bg_alien" - clothes_req = FALSE - base_cooldown = 0 - create_attack_logs = FALSE - /// Every alien spell creates only logs, no attack messages on someone placing weeds, but you DO get attack messages on neurotoxin and corrosive acid - create_custom_logs = TRUE - antimagic_flags = NONE - /// How much plasma it costs to use this - var/plasma_cost = 0 - -/// Every single alien spell uses a "spell name + plasmacost" format -/datum/spell/alien_spell/New() - ..() - if(plasma_cost) - name = "[name] ([plasma_cost])" - action.name = name - action.desc = desc - action.UpdateButtons() - -/datum/spell/alien_spell/write_custom_logs(list/targets, mob/user) - user.create_log(ATTACK_LOG, "Cast the spell [name]") - -/datum/spell/alien_spell/create_new_handler() - var/datum/spell_handler/alien/handler = new - handler.plasma_cost = plasma_cost - return handler diff --git a/code/datums/spells/alien_spells/basetype_alien_touch.dm b/code/datums/spells/alien_spells/basetype_alien_touch.dm deleted file mode 100644 index f979b2af6ba37..0000000000000 --- a/code/datums/spells/alien_spells/basetype_alien_touch.dm +++ /dev/null @@ -1,50 +0,0 @@ -/datum/spell/touch/alien_spell - name = "Basetype Alien spell" - desc = "You should not see this in game, if you do file a github report!" - hand_path = "/obj/item/melee/touch_attack/alien" - /// Extremely fast cooldown, only present so the cooldown system doesn't explode - base_cooldown = 1 - action_background_icon_state = "bg_alien" - clothes_req = FALSE - antimagic_flags = NONE - create_attack_logs = FALSE - /// Every alien spell creates only logs, no attack messages on someone placing weeds, but you DO get attack messages on neurotoxin and corrosive acid - create_custom_logs = TRUE - /// We want a special on remove message, so we got this variable to do so - on_remove_message = FALSE - /// How much plasma it costs to use this - var/plasma_cost = 0 - action_icon_state = "gib" - -/datum/spell/touch/alien_spell/New() - ..() - if(plasma_cost) - name = "[name] ([plasma_cost])" - -/datum/spell/touch/alien_spell/Click(mob/user = usr) - if(attached_hand) - to_chat(user, "You withdraw your [src].") - ..() - -/datum/spell/touch/alien_spell/write_custom_logs(list/targets, mob/user) - user.create_log(ATTACK_LOG, "Cast the spell [name]") - -/datum/spell/touch/alien_spell/create_new_handler() - var/datum/spell_handler/alien/H = new - H.plasma_cost = plasma_cost - return H - -/obj/item/melee/touch_attack/alien - name = "Basetype Alien touch_attack" - desc = "You should not see this in game, if you do file a github report!" - /// Alien spells don't have catchphrases - catchphrase = null - /// Beepsky shouldn't be arresting you over this - needs_permit = FALSE - -/obj/item/melee/touch_attack/alien/proc/plasma_check(plasma, mob/living/carbon/user) - var/plasma_current = user.get_plasma() - if(plasma_current < plasma) - qdel(src) - return FALSE - return TRUE diff --git a/code/datums/spells/alien_spells/build_resin_structure.dm b/code/datums/spells/alien_spells/build_resin_structure.dm deleted file mode 100644 index b33967cd40a42..0000000000000 --- a/code/datums/spells/alien_spells/build_resin_structure.dm +++ /dev/null @@ -1,93 +0,0 @@ -#define RESIN_WALL "Resin Wall" -#define RESIN_NEST "Resin Nest" -#define RESIN_DOOR "Resin Door" -#define REVIVAL_NEST "Revival Nest" - -/datum/spell/alien_spell/build_resin - name = "Build Resin Structure" - desc = "Allows you to create resin structures. Does not work while in space." - plasma_cost = 55 - action_icon_state = "alien_resin" - -/datum/spell/alien_spell/build_resin/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/alien_spell/build_resin/cast(list/targets, mob/living/carbon/user) - var/static/list/resin_buildings = list(RESIN_WALL = image(icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi', icon_state = "resin_wall-0"), - RESIN_NEST = image(icon = 'icons/mob/alien.dmi', icon_state = "nest"), - RESIN_DOOR = image(icon = 'icons/obj/smooth_structures/alien/resin_door.dmi', icon_state = "resin"), - REVIVAL_NEST = image(icon = 'icons/mob/alien.dmi', icon_state = "placeholder_rejuv_nest")) - var/choice = show_radial_menu(user, user, resin_buildings, src, radius = 40) - var/turf/turf_to_spawn_at = user.loc - if(!choice) - revert_cast(user) - return - if(!do_mob(user, user, 3 SECONDS)) - revert_cast() - return - if(isspaceturf(turf_to_spawn_at)) - to_chat(user, "You cannot build the [choice] while in space!") - revert_cast(user) - return - var/obj/structure/alien/resin/resin_on_turf = locate() in turf_to_spawn_at - if(resin_on_turf) - to_chat(user, "There is already a resin construction here.") - revert_cast(user) - return - user.visible_message("[user] vomits up a thick purple substance and shapes it!") - switch(choice) - if(RESIN_WALL) - new /obj/structure/alien/resin/wall(turf_to_spawn_at) - if(RESIN_NEST) - new /obj/structure/bed/nest(turf_to_spawn_at) - if(RESIN_DOOR) - new /obj/structure/alien/resin/door(turf_to_spawn_at) - if(REVIVAL_NEST) - new /obj/structure/bed/revival_nest(turf_to_spawn_at) - -/datum/spell/touch/alien_spell/consume_resin - name = "Consume resin structures" - desc = "Allows you to rip and tear straight through resin structures." - action_icon_state = "alien_resin" - hand_path = "/obj/item/melee/touch_attack/alien/consume_resin" - plasma_cost = 10 - base_cooldown = 5 SECONDS - -/obj/item/melee/touch_attack/alien/consume_resin - name = "Resin consumption" - desc = "The hunger..." - icon_state = "alien_acid" - -/obj/item/melee/touch_attack/alien/consume_resin/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - . = ..() - if(target == user) - to_chat(user, "You stop trying to consume resin.") - return - if(!proximity_flag || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) - return - var/mob/living/carbon/C = user - if(istype(target, /obj/structure/alien/weeds)) - qdel(target) - if(istype(target, /obj/structure/alien/weeds/node)) - C.add_plasma(50) - C.visible_message("[C] rips and tears into [target] with their teeth!", "You viciously rip apart and consume [target]!") - return - if(!plasma_check(10, C)) - to_chat(C, "You don't have enough plasma to perform this action!") - return - var/static/list/resin_objects = list(/obj/structure/alien/resin, /obj/structure/alien/egg, /obj/structure/bed/nest, /obj/structure/bed/revival_nest) - for(var/resin_type in resin_objects) - if(!istype(target, resin_type)) - continue - C.visible_message("[C] rips and tears into [target] with their teeth!") - if(!do_after(C, 3 SECONDS, target = target)) - return - to_chat(C, "You viciously rip apart and consume [target]!") - C.add_plasma(-10) - qdel(target) - handle_delete(user) - -#undef RESIN_WALL -#undef RESIN_NEST -#undef RESIN_DOOR -#undef REVIVAL_NEST diff --git a/code/datums/spells/alien_spells/corrosive_acid_spit.dm b/code/datums/spells/alien_spells/corrosive_acid_spit.dm deleted file mode 100644 index eca1d74ac8637..0000000000000 --- a/code/datums/spells/alien_spells/corrosive_acid_spit.dm +++ /dev/null @@ -1,76 +0,0 @@ -/datum/spell/touch/alien_spell/corrosive_acid - name = "Corrosive acid" - desc = "Spit acid on someone in range, this acid melts through nearly anything and heavily damages anyone lacking proper safety equipment." - hand_path = "/obj/item/melee/touch_attack/alien/corrosive_acid" - action_icon_state = "alien_acid" - plasma_cost = 200 - base_cooldown = 15 SECONDS - -/obj/item/melee/touch_attack/alien/corrosive_acid - name = "Corrosive acid" - desc = "A fistfull of death." - icon_state = "alien_acid" - -/obj/item/melee/touch_attack/alien/corrosive_acid/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - . = ..() - if(target == user) - to_chat(user, "You withdraw your readied acid.") - return - if(!proximity_flag || isalien(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) // Don't want xenos ditching out of cuffs - return - var/mob/living/carbon/C = user - if(!plasma_check(200, C)) - to_chat(C, "You don't have enough plasma to perform this action!") - return - var/acid_damage_modifier = 100 - if(isliving(target)) - acid_damage_modifier = 50 - if(target.acid_act(2 * acid_damage_modifier, acid_damage_modifier)) - visible_message("[C] vomits globs of vile stuff all over [target]. It begins to sizzle and melt under the bubbling mess of acid!") - add_attack_logs(C, target, "Applied corrosive acid") // Want this logged - C.add_plasma(-200) - else - to_chat(C, "You cannot dissolve this object.") - handle_delete(user) - -/datum/spell/touch/alien_spell/burning_touch - name = "Blazing touch" - desc = "Boil acid within your hand to burn through anything you touch with it, deals a lot of damage to aliens and destroys resin structures instantly." - hand_path = "/obj/item/melee/touch_attack/alien/burning_touch" - action_icon_state = "alien_acid" - plasma_cost = 100 - base_cooldown = 10 SECONDS - -/obj/item/melee/touch_attack/alien/burning_touch - name = "Blazing touch" - desc = "The air warps around your hand, somehow the heat doesn't hurt." - icon_state = "alien_acid" - -/obj/item/melee/touch_attack/alien/burning_touch/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - . = ..() - if(target == user) - to_chat(user, "You cool down your boiled aid.") - return - if(!proximity_flag || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) - return - var/mob/living/carbon/C = user - if(!plasma_check(100, C)) - to_chat(C, "You don't have enough plasma to perform this action!") - return - if(isliving(target)) - var/mob/living/guy_to_burn = target - add_attack_logs(C, target, "Applied blazing touch") // Want this logged - guy_to_burn.adjustFireLoss(60) - guy_to_burn.adjust_fire_stacks(3) - guy_to_burn.IgniteMob() - C.visible_message("[C] touches [target] and a fireball erupts on contact!") - C.add_plasma(-100) - else - var/static/list/resin_objects = list(/obj/structure/alien/resin, /obj/structure/alien/egg, /obj/structure/bed/nest, /obj/structure/bed/revival_nest) - for(var/resin_type in resin_objects) - if(!istype(target, resin_type)) - continue - C.visible_message("[C] touches [target] and burns right through it!") - C.add_plasma(-100) - qdel(target) - handle_delete(user) diff --git a/code/datums/spells/banana_touch.dm b/code/datums/spells/banana_touch.dm deleted file mode 100644 index 165ba07208ef3..0000000000000 --- a/code/datums/spells/banana_touch.dm +++ /dev/null @@ -1,74 +0,0 @@ -/datum/spell/touch/banana - name = "Banana Touch" - desc = "A spell popular at wizard birthday parties, this spell will put on a clown costume on the target, \ - stun them with a loud HONK, and mutate them to make them more entertaining! \ - Warning : Effects are permanent on non-wizards." - hand_path = /obj/item/melee/touch_attack/banana - - base_cooldown = 30 SECONDS - clothes_req = TRUE - cooldown_min = 100 //50 deciseconds reduction per rank - action_icon_state = "clown" - -/obj/item/melee/touch_attack/banana - name = "banana touch" - desc = "It's time to start clowning around." - catchphrase = "NWOLC YRGNA" - on_use_sound = 'sound/items/AirHorn.ogg' - icon_state = "banana_touch" - item_state = "banana_touch" - var/is_apprentice_spell = FALSE - -/datum/spell/touch/banana/apprentice - hand_path = /obj/item/melee/touch_attack/banana/apprentice - -/obj/item/melee/touch_attack/banana/apprentice - is_apprentice_spell = TRUE - -/obj/item/melee/touch_attack/banana/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - . = ..() - - if(is_apprentice_spell && iswizard(target) && target != user) - to_chat(user, "Seriously?! Honk THEM, not me!") - return - if(!proximity_flag || target == user || blocked_by_antimagic || !ishuman(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) - return - - var/datum/effect_system/smoke_spread/s = new - s.set_up(5, FALSE, target) - s.start() - - to_chat(user, "HONK") - var/mob/living/carbon/human/H = target - H.bananatouched() - handle_delete(user) - -/mob/living/carbon/human/proc/bananatouched() - to_chat(src, "HONK") - Weaken(14 SECONDS) - Stuttering(30 SECONDS) - do_jitter_animation(30 SECONDS) - - if(iswizard(src) || (mind && mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE)) //Wizards get non-cursed clown robes and magical mask. - drop_item_to_ground(shoes, force = TRUE) - drop_item_to_ground(wear_mask, force = TRUE) - drop_item_to_ground(head, force = TRUE) - drop_item_to_ground(wear_suit, force = TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/head/wizard/clown, ITEM_SLOT_HEAD, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/suit/wizrobe/clown, ITEM_SLOT_OUTER_SUIT, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/shoes/clown_shoes/magical, ITEM_SLOT_SHOES, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/clownwiz, ITEM_SLOT_MASK, TRUE, TRUE) - else - qdel(shoes) - qdel(wear_mask) - qdel(w_uniform) - equip_to_slot_if_possible(new /obj/item/clothing/under/rank/civilian/clown/nodrop, ITEM_SLOT_JUMPSUIT, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/shoes/clown_shoes/nodrop, ITEM_SLOT_SHOES, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/clown_hat/nodrop, ITEM_SLOT_MASK, TRUE, TRUE) - dna.SetSEState(GLOB.clumsyblock, TRUE, TRUE) - dna.SetSEState(GLOB.comicblock, TRUE, TRUE) - singlemutcheck(src, GLOB.clumsyblock, MUTCHK_FORCED) - singlemutcheck(src, GLOB.comicblock, MUTCHK_FORCED) - if(!(iswizard(src) || (mind && mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE))) //Mutations are permanent on non-wizards. Can still be removed by genetics fuckery but not mutadone. - dna.default_blocks.Add(GLOB.clumsyblock) - dna.default_blocks.Add(GLOB.comicblock) diff --git a/code/datums/spells/bloodcrawl.dm b/code/datums/spells/bloodcrawl.dm deleted file mode 100644 index 9bc2864a656c7..0000000000000 --- a/code/datums/spells/bloodcrawl.dm +++ /dev/null @@ -1,300 +0,0 @@ -/datum/spell/bloodcrawl - name = "Blood Crawl" - desc = "Use pools of blood to phase out of existence." - base_cooldown = 1 SECONDS - clothes_req = FALSE - cooldown_min = 0 - should_recharge_after_cast = FALSE - overlay = null - action_icon_state = "bloodcrawl" - action_background_icon_state = "bg_demon" - antimagic_flags = NONE - var/allowed_type = /obj/effect/decal/cleanable - var/phased = FALSE - -/datum/spell/bloodcrawl/create_new_targeting() - var/datum/spell_targeting/targeted/T = new() - T.selection_type = SPELL_SELECTION_RANGE - T.allowed_type = allowed_type - T.random_target = TRUE - T.range = 1 - T.use_turf_of_user = TRUE - return T - -/datum/spell/bloodcrawl/valid_target(obj/effect/decal/cleanable/target, user) - return target.can_bloodcrawl_in() - -/datum/spell/bloodcrawl/can_cast(mob/living/user, charge_check, show_message) - . = ..() - if(!.) - return - if(!isliving(user)) - return FALSE - if(SEND_SIGNAL(user, COMSIG_MOB_PRE_JAUNT, get_turf(user)) & COMPONENT_BLOCK_JAUNT) - return FALSE - -/datum/spell/bloodcrawl/cast(list/targets, mob/living/user) - var/atom/target = targets[1] - if(!phased) - if(phaseout(target, user)) - phased = TRUE - cooldown_handler.revert_cast() - else - if(phasein(target, user)) - phased = FALSE - cooldown_handler.start_recharge() - - - -//Travel through pools of blood. Slaughter Demon powers for everyone! -#define BLOODCRAWL 1 -#define BLOODCRAWL_EAT 2 - - -/obj/item/bloodcrawl - name = "blood crawl" - desc = "You are unable to hold anything while in this form." - icon = 'icons/effects/blood.dmi' - flags = NODROP|ABSTRACT - -/// Can't use the wizard one, blocked by jaunt/slow -/obj/effect/dummy/slaughter - name = "odd blood" - icon = 'icons/effects/effects.dmi' - icon_state = "nothing" - density = FALSE - anchored = TRUE - invisibility = 60 - resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - -/obj/effect/dummy/slaughter/relaymove(mob/user, direction) - forceMove(get_step(src, direction)) - -/obj/effect/dummy/slaughter/ex_act() - return - -/obj/effect/dummy/slaughter/bullet_act() - return - -/obj/effect/dummy/slaughter/singularity_act() - return - - -/datum/spell/bloodcrawl/proc/block_hands(mob/living/carbon/C) - if(C.l_hand || C.r_hand) - to_chat(C, "You may not hold items while blood crawling!") - return FALSE - var/obj/item/bloodcrawl/B1 = new(C) - var/obj/item/bloodcrawl/B2 = new(C) - B1.icon_state = "bloodhand_left" - B2.icon_state = "bloodhand_right" - C.put_in_hands(B1) - C.put_in_hands(B2) - C.regenerate_icons() - return TRUE - -/obj/effect/temp_visual/dir_setting/bloodcrawl - icon = 'icons/mob/mob.dmi' - icon_state = "blank" // Flicks are used instead - duration = 0.6 SECONDS - layer = MOB_LAYER + 0.1 - -/obj/effect/temp_visual/dir_setting/bloodcrawl/Initialize(mapload, set_dir, animation_state) - . = ..() - flick(animation_state, src) // Setting the icon_state to the animation has timing issues and can cause frame skips - -/datum/spell/bloodcrawl/proc/sink_animation(atom/A, mob/living/L) - var/turf/mob_loc = get_turf(L) - mob_loc.visible_message( - "[L] sinks into [A].", - "You hear something sinking into a thick liquid." - ) - playsound(mob_loc, 'sound/misc/enter_blood.ogg', 100, TRUE, -1) - new /obj/effect/temp_visual/dir_setting/bloodcrawl(mob_loc, L.dir, "jaunt") - -/datum/spell/bloodcrawl/proc/handle_consumption(mob/living/L, mob/living/victim, atom/A, obj/effect/dummy/slaughter/holder) - if(!HAS_TRAIT(L, TRAIT_BLOODCRAWL_EAT)) - return - - if(!istype(victim)) - return - if(victim.stat == CONSCIOUS) - A.visible_message( - "[victim] kicks free of [A] just before entering it!", - "You hear something sinking into a thick liquid and someone struggling!" - ) - L.stop_pulling() - return - - victim.forceMove(holder) - victim.emote("scream") - A.visible_message( - "[L] drags [victim] into [A]!", - "You hear something being dragged into a thick liquid!" - ) - L.stop_pulling() - to_chat(L, "You begin to feast on [victim]. You cannot move while you are doing this.") - A.visible_message( - "Loud eating sounds come from the blood...", - "The sound of torn flesh and snapping bones fills the air..." - ) - var/sound - if(isslaughterdemon(L)) - var/mob/living/simple_animal/demon/slaughter/SD = L - sound = SD.feast_sound - else - sound = 'sound/misc/demon_consume.ogg' - - for(var/i in 1 to 3) - playsound(get_turf(L), sound, 100, 1) - sleep(3 SECONDS) - - if(!victim) - to_chat(L, "You happily devour... nothing? Your meal vanished at some point!") - return - if(victim.mind) - to_chat(L, "You devour [victim]. Your health is fully restored.") - L.adjustBruteLoss(-1000) - L.adjustFireLoss(-1000) - L.adjustOxyLoss(-1000) - L.adjustToxLoss(-1000) - else if((ishuman(victim) || isrobot(victim))) - to_chat(L, "You devour [victim], but their lack of intelligence renders their flesh dull and unappetising, leaving you wanting for more.") - L.adjustBruteLoss(-50) - if(!isslaughterdemon(L)) - L.adjustFireLoss(-50) - else if(isanimal(victim)) - to_chat(L, "You devour [victim], but this measly meal barely sates your appetite!") - L.adjustBruteLoss(-25) - if(!isslaughterdemon(L)) - L.adjustFireLoss(-25) - - if(isslaughterdemon(L)) - var/mob/living/simple_animal/demon/slaughter/demon = L - demon.devoured++ - to_chat(victim, "You feel teeth sink into your flesh, and the--") - var/obj/item/organ/internal/regenerative_core/legion/core = victim.get_int_organ(/obj/item/organ/internal/regenerative_core/legion) - if(core) - core.remove(victim) - qdel(core) - victim.adjustBruteLoss(1000) - victim.forceMove(demon) - demon.consumed_mobs.Add(victim) - ADD_TRAIT(victim, TRAIT_UNREVIVABLE, "demon") - if(ishuman(victim)) - var/mob/living/carbon/human/H = victim - if(H.w_uniform && istype(H.w_uniform, /obj/item/clothing/under)) - var/obj/item/clothing/under/U = H.w_uniform - U.sensor_mode = SENSOR_OFF - else - victim.ghostize() - qdel(victim) - -/datum/spell/bloodcrawl/proc/post_phase_in(mob/living/L, obj/effect/dummy/slaughter/holder) - L.notransform = FALSE - -/datum/spell/bloodcrawl/proc/phaseout(obj/effect/decal/cleanable/B, mob/living/L) - - if(iscarbon(L) && !block_hands(L)) - return FALSE - L.notransform = TRUE - INVOKE_ASYNC(src, PROC_REF(async_phase), B, L) - return TRUE - -/datum/spell/bloodcrawl/proc/async_phase(obj/effect/decal/cleanable/B, mob/living/L) - var/turf/mobloc = get_turf(L) - sink_animation(B, L) - var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(mobloc) - L.forceMove(holder) - L.ExtinguishMob() - handle_consumption(L, L.pulling, B, holder) - post_phase_in(L, holder) - -/datum/spell/bloodcrawl/proc/rise_animation(turf/tele_loc, mob/living/L, atom/A) - new /obj/effect/temp_visual/dir_setting/bloodcrawl(tele_loc, L.dir, "jauntup") - if(prob(25) && isdemon(L)) - var/list/voice = list('sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/i_see_you1.ogg') - playsound(tele_loc, pick(voice),50, TRUE, -1) - A.visible_message( - "[L] rises out of [A]!", - "You hear something rising out of a thick liquid!" - ) - playsound(get_turf(tele_loc), 'sound/misc/exit_blood.ogg', 100, TRUE, -1) - -/datum/spell/bloodcrawl/proc/unblock_hands(mob/living/carbon/C) - if(!istype(C)) - return - for(var/obj/item/bloodcrawl/BC in C) - qdel(BC) - -/datum/spell/bloodcrawl/proc/rise_message(atom/A) - A.visible_message( - "[A] starts to bubble...", - "You can hear bubbling..." - ) - -/datum/spell/bloodcrawl/proc/post_phase_out(atom/A, mob/living/L) - if(isslaughterdemon(L)) - var/mob/living/simple_animal/demon/slaughter/S = L - S.speed = 0 - S.boost = world.time + 6 SECONDS - L.color = A.color - addtimer(VARSET_CALLBACK(L, color, null), 6 SECONDS) - - -/datum/spell/bloodcrawl/proc/phasein(atom/A, mob/living/L) - - if(L.notransform) - to_chat(L, "Finish eating first!") - return FALSE - rise_message(A) - if(!do_after(L, 2 SECONDS, target = A)) - return FALSE - if(!A) - return FALSE - var/turf/tele_loc = isturf(A) ? A : A.loc - var/holder = L.loc - L.forceMove(tele_loc) - L.client.eye = L - - rise_animation(tele_loc, L, A) - - unblock_hands(L) - - QDEL_NULL(holder) - - post_phase_out(A, L) - return TRUE - -/datum/spell/bloodcrawl/shadow_crawl - name = "Shadow Crawl" - desc = "Fade into the shadows, increasing your speed and making you incomprehensible. Will not work in brightened terrane." - allowed_type = /turf - action_background_icon_state = "shadow_demon_bg" - action_icon_state = "shadow_crawl" - -/datum/spell/bloodcrawl/shadow_crawl/valid_target(turf/target, user) - return target.get_lumcount() < 0.2 - -/datum/spell/bloodcrawl/shadow_crawl/rise_message(atom/A) - return - -/datum/spell/bloodcrawl/shadow_crawl/rise_animation(turf/tele_loc, mob/living/L, atom/A) - new /obj/effect/temp_visual/dir_setting/bloodcrawl(get_turf(L), L.dir, "shadowwalk_appear") - -/datum/spell/bloodcrawl/shadow_crawl/handle_consumption(mob/living/L, mob/living/victim, atom/A, obj/effect/dummy/slaughter/holder) - return - -/datum/spell/bloodcrawl/shadow_crawl/sink_animation(atom/A, mob/living/L) - A.visible_message("[L] sinks into the shadows...") - new /obj/effect/temp_visual/dir_setting/bloodcrawl(get_turf(L), L.dir, "shadowwalk_disappear") - -/datum/spell/bloodcrawl/shadow_crawl/post_phase_in(mob/living/L, obj/effect/dummy/slaughter/holder) - ..() - if(!istype(L, /mob/living/simple_animal/demon/shadow)) - return - var/mob/living/simple_animal/demon/shadow/S = L - S.RegisterSignal(holder, COMSIG_MOVABLE_MOVED, TYPE_PROC_REF(/mob/living/simple_animal/demon/shadow, check_darkness)) - -#undef BLOODCRAWL -#undef BLOODCRAWL_EAT diff --git a/code/datums/spells/chaplain_bless.dm b/code/datums/spells/chaplain_bless.dm deleted file mode 100644 index 518f51207c8ee..0000000000000 --- a/code/datums/spells/chaplain_bless.dm +++ /dev/null @@ -1,52 +0,0 @@ - -/datum/spell/chaplain_bless - name = "Bless" - desc = "Blesses a single person." - - base_cooldown = 6 SECONDS - clothes_req = FALSE - invocation = "none" - invocation_type = "none" - antimagic_flags = NONE - - selection_activated_message = "You prepare a blessing. Click on a target to start blessing." - selection_deactivated_message = "The crew will be blessed another time." - cooldown_min = 20 - action_icon_state = "shield" - -/datum/spell/chaplain_bless/create_new_targeting() - var/datum/spell_targeting/click/T = new() - T.range = 1 - T.click_radius = -1 - return T - -/datum/spell/chaplain_bless/valid_target(mob/living/carbon/human/target, mob/user) - return target.mind && target.ckey && !target.stat - -/datum/spell/chaplain_bless/cast(list/targets, mob/living/user = usr) - if(!istype(user)) - to_chat(user, "Somehow, you are not a living mob. This should never happen. Report this bug.") - revert_cast() - return - - if(!user.mind) - to_chat(user, "Somehow, you are mindless. This should never happen. Report this bug.") - revert_cast() - return - - if(!HAS_MIND_TRAIT(user, TRAIT_HOLY)) - to_chat(user, "Somehow, you are not holy enough to use this ability. This should never happen. Report this bug.") - revert_cast() - return - - var/mob/living/carbon/human/target = targets[1] - - spawn(0) // allows cast to complete even if recipient ignores the prompt - if(tgui_alert(target, "[user] wants to bless you, in the name of [user.p_their()] religion. Accept?", "Accept Blessing?", list("Yes", "No")) == "Yes") // prevents forced conversions - user.visible_message("[user] starts blessing [target] in the name of [SSticker.Bible_deity_name].", "You start blessing [target] in the name of [SSticker.Bible_deity_name].") - if(do_after(user, 150, target = target)) - user.visible_message("[user] has blessed [target] in the name of [SSticker.Bible_deity_name].", "You have blessed [target] in the name of [SSticker.Bible_deity_name].") - if(!target.mind.isblessed) - target.mind.isblessed = TRUE - user.mind.num_blessed++ - diff --git a/code/datums/spells/charge.dm b/code/datums/spells/charge.dm deleted file mode 100644 index 50b5f3a67e893..0000000000000 --- a/code/datums/spells/charge.dm +++ /dev/null @@ -1,103 +0,0 @@ -/datum/spell/charge - name = "Charge" - desc = "This spell can be used to recharge a variety of things in your hands, from magical artifacts to electrical components. A creative wizard can even use it to grant magical power to a fellow magic user." - base_cooldown = 1 MINUTES - clothes_req = FALSE - invocation = "DIRI CEL" - invocation_type = "whisper" - cooldown_min = 400 //50 deciseconds reduction per rank - action_icon_state = "charge" - -/datum/spell/charge/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/charge/cast(list/targets, mob/user = usr) - for(var/mob/living/L in targets) - var/list/hand_items = list(L.get_active_hand(),L.get_inactive_hand()) - var/charged_item = null - var/burnt_out = FALSE - - if(L.pulling && (isliving(L.pulling))) - var/mob/living/M = L.pulling - if(length(M.mob_spell_list) != 0 || (M.mind && length(M.mind.spell_list) != 0)) - for(var/datum/spell/S in M.mob_spell_list) - S.cooldown_handler.revert_cast() - if(M.mind) - for(var/datum/spell/S in M.mind.spell_list) - S.cooldown_handler.revert_cast() - to_chat(M, "You feel raw magical energy flowing through you, it feels good!") - else - to_chat(M, "You feel very strange for a moment, but then it passes.") - burnt_out = TRUE - charged_item = M - break - for(var/obj/item in hand_items) - if(istype(item, /obj/item/spellbook)) - if(istype(item, /obj/item/spellbook/oneuse)) - var/obj/item/spellbook/oneuse/I = item - if(prob(80)) - L.visible_message("[I] catches fire!") - qdel(I) - else - I.used = FALSE - charged_item = I - break - else - to_chat(L, "Glowing red letters appear on the front cover...") - to_chat(L, "[pick("NICE TRY BUT NO!","CLEVER BUT NOT CLEVER ENOUGH!", "SUCH FLAGRANT CHEESING IS WHY WE ACCEPTED YOUR APPLICATION!", "CUTE!", "YOU DIDN'T THINK IT'D BE THAT EASY, DID YOU?")]") - burnt_out = TRUE - else if(istype(item, /obj/item/book/granter)) - var/obj/item/book/granter/I = item - if(prob(80)) - L.visible_message("[I] catches fire!") - qdel(I) - else - I.uses += 1 - charged_item = I - break - - else if(istype(item, /obj/item/gun/magic)) - var/obj/item/gun/magic/I = item - if(prob(80) && !I.can_charge) - I.max_charges-- - if(I.max_charges <= 0) - I.max_charges = 0 - burnt_out = TRUE - I.charges = I.max_charges - if(istype(item,/obj/item/gun/magic/wand) && I.max_charges != 0) - var/obj/item/gun/magic/W = item - W.icon_state = initial(W.icon_state) - charged_item = I - break - else if(istype(item, /obj/item/stock_parts/cell/)) - var/obj/item/stock_parts/cell/C = item - if(!C.self_recharge) - if(prob(80)) - C.maxcharge -= 200 - if(C.maxcharge <= 1) //Div by 0 protection - C.maxcharge = 1 - burnt_out = TRUE - C.charge = C.maxcharge - charged_item = C - break - else if(item.contents) - var/obj/I = null - for(I in item.contents) - if(istype(I, /obj/item/stock_parts/cell/)) - var/obj/item/stock_parts/cell/C = I - if(!C.self_recharge) - if(prob(80)) - C.maxcharge -= 200 - if(C.maxcharge <= 1) //Div by 0 protection - C.maxcharge = 1 - burnt_out = TRUE - C.charge = C.maxcharge - item.update_icon() - charged_item = item - break - if(!charged_item) - to_chat(L, "You feel magical power surging to your hands, but the feeling rapidly fades...") - else if(burnt_out) - to_chat(L, "[charged_item] doesn't seem to be reacting to the spell...") - else - to_chat(L, "[charged_item] suddenly feels very warm!") diff --git a/code/datums/spells/chef.dm b/code/datums/spells/chef.dm deleted file mode 100644 index 2e42e0b1be66c..0000000000000 --- a/code/datums/spells/chef.dm +++ /dev/null @@ -1,17 +0,0 @@ -/datum/spell/expert_chef - name = "Expert Chef Knowledge" - desc = "Find things you can cook with the items in reach." - clothes_req = FALSE - base_cooldown = 5 SECONDS - human_req = TRUE - antimagic_flags = NONE - action_icon_state = "chef" - action_background_icon_state = "bg_default" - still_recharging_msg = "All this thinking makes your head hurt, wait a bit longer." - -/datum/spell/expert_chef/cast(list/targets, mob/user = usr) - var/mob/living/carbon/human/H = targets[1] - H.expert_chef_knowledge() - -/datum/spell/expert_chef/create_new_targeting() - return new /datum/spell_targeting/self diff --git a/code/datums/spells/cluwne.dm b/code/datums/spells/cluwne.dm deleted file mode 100644 index 68e48c108ebaf..0000000000000 --- a/code/datums/spells/cluwne.dm +++ /dev/null @@ -1,78 +0,0 @@ -/datum/spell/touch/cluwne - name = "Curse of the Cluwne" - desc = "Turns the target into a fat and cursed monstrosity of a clown." - hand_path = /obj/item/melee/touch_attack/cluwne - - base_cooldown = 1 MINUTES - clothes_req = TRUE - cooldown_min = 200 //100 deciseconds reduction per rank - - action_icon_state = "cluwne" - -/mob/living/carbon/human/proc/makeCluwne() - if(istype(back, /obj/item/mod/control)) // Check if the target is wearing a modsuit - var/obj/item/mod/control/modsuit_control = back - if(istype(wear_suit, /obj/item/clothing/suit/mod)) // Check if the modsuit is deployed - modsuit_control.active = FALSE // Instantly deactivate the modsuit - if it was activated - modsuit_control.quick_deploy(src) // The modsuit is no longer deployed - to_chat(src, "You feel funny.") - if(!get_int_organ(/obj/item/organ/internal/brain/cluwne)) - var/obj/item/organ/internal/brain/cluwne/idiot_brain = new - idiot_brain.insert(src, make_cluwne = 0) - idiot_brain.dna = dna.Clone() - setBrainLoss(80, use_brain_mod = FALSE) - set_nutrition(9000) - overeatduration = 9000 - Confused(60 SECONDS) - if(mind) - mind.assigned_role = "Cluwne" - - - dna.SetSEState(GLOB.nervousblock, 1, 1) - singlemutcheck(src, GLOB.nervousblock, MUTCHK_FORCED) - rename_character(real_name, "cluwne") - - drop_item_to_ground(w_uniform, force = TRUE) - drop_item_to_ground(shoes, force = TRUE) - drop_item_to_ground(gloves, force = TRUE) - var/obj/item/organ/internal/honktumor/cursed/tumor = new - tumor.insert(src) - if(!istype(wear_mask, /obj/item/clothing/mask/cursedclown)) //Infinite loops otherwise - drop_item_to_ground(wear_mask, force = TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/under/cursedclown, ITEM_SLOT_JUMPSUIT, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/gloves/cursedclown, ITEM_SLOT_GLOVES, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/mask/cursedclown, ITEM_SLOT_MASK, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/shoes/cursedclown, ITEM_SLOT_SHOES, TRUE, TRUE) - -/mob/living/carbon/human/proc/makeAntiCluwne() - to_chat(src, "You don't feel very funny.") - adjustBrainLoss(-120) - set_nutrition(NUTRITION_LEVEL_STARVING) - overeatduration = 0 - SetConfused(0) - SetJitter(0) - if(mind) - mind.assigned_role = "Internal Affairs Agent" - - var/obj/item/organ/internal/honktumor/cursed/tumor = get_int_organ(/obj/item/organ/internal/honktumor/cursed) - if(tumor) - tumor.remove(src) - else - dna.SetSEState(GLOB.clumsyblock, FALSE) - dna.SetSEState(GLOB.comicblock, FALSE) - singlemutcheck(src, GLOB.clumsyblock, MUTCHK_FORCED) - singlemutcheck(src, GLOB.comicblock, MUTCHK_FORCED) - dna.SetSEState(GLOB.nervousblock, FALSE) - singlemutcheck(src, GLOB.nervousblock, MUTCHK_FORCED) - - qdel(w_uniform) - qdel(shoes) - - if(istype(wear_mask, /obj/item/clothing/mask/cursedclown)) - qdel(wear_mask) - - if(istype(gloves, /obj/item/clothing/gloves/cursedclown)) - qdel(gloves) - - equip_to_slot_if_possible(new /obj/item/clothing/under/rank/procedure/iaa/formal/black, ITEM_SLOT_JUMPSUIT, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/shoes/black, ITEM_SLOT_SHOES, TRUE, TRUE) diff --git a/code/datums/spells/conjure.dm b/code/datums/spells/conjure.dm deleted file mode 100644 index c0bef3f0dcd2b..0000000000000 --- a/code/datums/spells/conjure.dm +++ /dev/null @@ -1,66 +0,0 @@ -/datum/spell/aoe/conjure - desc = "This spell conjures objs of the specified types in range." - - var/list/summon_type = list() //determines what exactly will be summoned - //should be text, like list("/mob/simple_animal/bot/ed209") - - var/summon_lifespan = 0 // 0=permanent, any other time in deciseconds - var/summon_amt = 1 //amount of objects summoned - var/summon_ignore_density = 0 //if set to 1, adds dense tiles to possible spawn places - var/summon_ignore_prev_spawn_points = 0 //if set to 1, each new object is summoned on a new spawn point - - var/list/newVars = list() //vars of the summoned objects will be replaced with those where they meet - //should have format of list("emagged" = 1,"name" = "Wizard's Justicebot"), for example - var/delay = 1//Go Go Gadget Inheritance - - var/cast_sound = 'sound/items/welder.ogg' - -/datum/spell/aoe/conjure/create_new_targeting() - var/datum/spell_targeting/aoe/turf/targeting = new() - targeting.range = aoe_range - return targeting - -/datum/spell/aoe/conjure/cast(list/targets,mob/living/user = usr) - var/list/what_conjure_summoned = list() - playsound(get_turf(user), cast_sound, 50, TRUE) - for(var/turf/T in targets) - if(T.density && !summon_ignore_density) - targets -= T - playsound(get_turf(src), cast_sound, 50, 1) - - if(delay <= 0 || do_after(user, delay, target = user)) - for(var/i=0,iYou start spinning in place and casting [src]...
    ") - if(do_after(H, 2 SECONDS, FALSE, H)) - finish_disguise(H) - return TRUE - else - H.slip("your own foot", 1 SECONDS, 0, 0, 1, "trip") - to_chat(H, "You must stand still to cast [src]!") - return FALSE - -/datum/spell/disguise_self/proc/finish_disguise(mob/living/carbon/human/H) - H.apply_status_effect(STATUS_EFFECT_MAGIC_DISGUISE) - var/datum/effect_system/smoke_spread/smoke = new /datum/effect_system/smoke_spread - smoke.set_up(4, FALSE, H.loc) - smoke.start() diff --git a/code/datums/spells/ethereal_jaunt.dm b/code/datums/spells/ethereal_jaunt.dm deleted file mode 100644 index a6b1432969079..0000000000000 --- a/code/datums/spells/ethereal_jaunt.dm +++ /dev/null @@ -1,156 +0,0 @@ -/datum/spell/ethereal_jaunt - name = "Ethereal Jaunt" - desc = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls." - - base_cooldown = 300 - clothes_req = TRUE - invocation = "none" - invocation_type = "none" - cooldown_min = 100 //50 deciseconds reduction per rank - nonabstract_req = TRUE - centcom_cancast = FALSE //Prevent people from getting to centcom - var/sound1 = 'sound/magic/ethereal_enter.ogg' - var/jaunt_duration = 50 //in deciseconds - var/jaunt_in_time = 5 - var/jaunt_in_type = /obj/effect/temp_visual/wizard - var/jaunt_out_type = /obj/effect/temp_visual/wizard/out - var/jaunt_type_path = /obj/effect/dummy/spell_jaunt - var/jaunt_water_effect = TRUE - - action_icon_state = "jaunt" - -/datum/spell/ethereal_jaunt/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/ethereal_jaunt/cast(list/targets, mob/user = usr) //magnets, so mostly hardcoded - playsound(get_turf(user), sound1, 50, TRUE, -1) - for(var/mob/living/target in targets) - if(SEND_SIGNAL(target, COMSIG_MOB_PRE_JAUNT, target) & COMPONENT_BLOCK_JAUNT) - continue - if(!target.can_safely_leave_loc()) // No more brainmobs hopping out of their brains - to_chat(target, "You are somehow too bound to your current location to abandon it.") - continue - INVOKE_ASYNC(src, PROC_REF(do_jaunt), target) - -/datum/spell/ethereal_jaunt/proc/do_jaunt(mob/living/target) - target.notransform = TRUE - var/turf/mobloc = get_turf(target) - var/obj/effect/dummy/spell_jaunt/holder = new jaunt_type_path(mobloc) - new jaunt_out_type(mobloc, target.dir) - target.ExtinguishMob() - target.forceMove(holder) - target.reset_perspective(holder) - target.notransform = FALSE //mob is safely inside holder now, no need for protection. - if(jaunt_water_effect) - jaunt_steam(mobloc) - - sleep(jaunt_duration) - - if(target.loc != holder) //mob warped out of the warp - qdel(holder) - return - mobloc = get_turf(target.loc) - if(jaunt_water_effect) - jaunt_steam(mobloc) - ADD_TRAIT(target, TRAIT_IMMOBILIZED, "jaunt") - holder.reappearing = 1 - playsound(get_turf(target), 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1) - sleep(jaunt_in_time * 4) - new jaunt_in_type(mobloc, holder.dir) - target.setDir(holder.dir) - sleep(jaunt_in_time) - qdel(holder) - if(!QDELETED(target)) - if(is_blocked_turf(mobloc, TRUE)) - for(var/turf/T in orange(7)) - if(isspaceturf(T)) - continue - if(target.Move(T)) - target.remove_CC() - REMOVE_TRAIT(target, TRAIT_IMMOBILIZED, "jaunt") - return - for(var/turf/space/S in orange(7)) - if(target.Move(S)) - break - REMOVE_TRAIT(target, TRAIT_IMMOBILIZED, "jaunt") - target.remove_CC() - -/datum/spell/ethereal_jaunt/proc/jaunt_steam(mobloc) - var/datum/effect_system/steam_spread/steam = new /datum/effect_system/steam_spread() - steam.set_up(10, 0, mobloc) - steam.start() - -/obj/effect/dummy/spell_jaunt - name = "water" - icon = 'icons/effects/effects.dmi' - icon_state = "nothing" - var/reappearing = 0 - var/movedelay = 0 - var/movespeed = 2 - density = FALSE - anchored = TRUE - invisibility = 60 - resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - -/obj/effect/dummy/spell_jaunt/Destroy() - // Eject contents if deleted somehow - for(var/atom/movable/AM in src) - AM.forceMove(get_turf(src)) - return ..() - -/obj/effect/dummy/spell_jaunt/relaymove(mob/user, direction) - if((movedelay > world.time) || reappearing || !direction) - return - var/turf/newLoc = get_step(src,direction) - setDir(direction) - movedelay = world.time + movespeed - if(can_move(newLoc)) - forceMove(newLoc) - return - if(!IS_DIR_DIAGONAL(direction)) - to_chat(user, "Something is blocking the way!") - return - var/turf/possible_1 = get_step(src, turn(direction, 45)) - var/turf/possible_2 = get_step(src, turn(direction, -45)) - if(can_move(possible_1)) - forceMove(possible_1) - return - if(can_move(possible_2)) - forceMove(possible_2) - return - to_chat(user, "Something is blocking the way!") - -/obj/effect/dummy/spell_jaunt/proc/can_move(turf/T) - return TRUE - -/obj/effect/dummy/spell_jaunt/ex_act(blah) - return - -/obj/effect/dummy/spell_jaunt/bullet_act(blah) - return - -/obj/effect/dummy/spell_jaunt/blood_pool - name = "sanguine pool" - desc = "a pool of living blood." - movespeed = 1.5 - -/obj/effect/dummy/spell_jaunt/blood_pool/relaymove(mob/user, direction) - ..() - new /obj/effect/decal/cleanable/blood(loc) - - -/obj/effect/dummy/spell_jaunt/blood_pool/can_move(turf/T) - if(isspaceturf(T) || T.density) - return FALSE - return TRUE - -/obj/effect/dummy/spell_jaunt/wraith - -/obj/effect/dummy/spell_jaunt/wraith/can_move(turf/T) - if(!issimulatedturf(T)) - return TRUE - - var/turf/simulated/turf_to_move = T - if(turf_to_move.flags & BLESSED_TILE) - return FALSE - return TRUE diff --git a/code/datums/spells/fake_gib.dm b/code/datums/spells/fake_gib.dm deleted file mode 100644 index 66c2597b5f64a..0000000000000 --- a/code/datums/spells/fake_gib.dm +++ /dev/null @@ -1,10 +0,0 @@ -/datum/spell/touch/fake_disintegrate - name = "Disintegrate" - desc = "This spell charges your hand with vile energy that can be used to violently explode victims." - hand_path = "/obj/item/melee/touch_attack/fake_disintegrate" - - base_cooldown = 600 - clothes_req = FALSE - cooldown_min = 200 //100 deciseconds reduction per rank - - action_icon_state = "gib" diff --git a/code/datums/spells/horsemask.dm b/code/datums/spells/horsemask.dm deleted file mode 100644 index 4e5e5e26ca121..0000000000000 --- a/code/datums/spells/horsemask.dm +++ /dev/null @@ -1,47 +0,0 @@ -/datum/spell/horsemask - name = "Curse of the Horseman" - desc = "This spell triggers a curse on a target, causing them to wield an unremovable horse head mask. They will speak like a horse! Any masks they are wearing will be disintegrated. This spell does not require robes." - base_cooldown = 150 - clothes_req = FALSE - stat_allowed = CONSCIOUS - invocation = "KN'A FTAGHU, PUCK 'BTHNK!" - invocation_type = "shout" - cooldown_min = 30 //30 deciseconds reduction per rank - - selection_activated_message = "You start to quietly neigh an incantation. Click on or near a target to cast the spell." - selection_deactivated_message = "You stop neighing to yourself." - - action_icon_state = "barn" - sound = 'sound/magic/HorseHead_curse.ogg' - -/datum/spell/horsemask/create_new_targeting() - var/datum/spell_targeting/click/T = new() - T.selection_type = SPELL_SELECTION_RANGE - return T - - -/datum/spell/horsemask/cast(list/targets, mob/user = usr) - if(!length(targets)) - to_chat(user, "No target found in range.") - return - - var/mob/living/carbon/human/target = targets[1] - - if(target.can_block_magic(antimagic_flags)) - target.visible_message("[target]'s face bursts into flames, which instantly burst outward, leaving [target.p_them()] unharmed!", - "Your face starts burning up, but the flames are repulsed by your anti-magic protection!", - ) - to_chat(user, "The spell had no effect!") - return FALSE - - var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead - magichead.flags |= NODROP | DROPDEL //curses! - magichead.flags_inv = null //so you can still see their face - magichead.voicechange = TRUE //NEEEEIIGHH - target.visible_message( "[target]'s face lights up in fire, and after the event a horse's head takes its place!", \ - "Your face burns up, and shortly after the fire you realise you have the face of a horse!") - if(!target.drop_item_to_ground(target.wear_mask)) - qdel(target.wear_mask) - target.equip_to_slot_if_possible(magichead, ITEM_SLOT_MASK, TRUE, TRUE) - - target.flash_eyes() diff --git a/code/datums/spells/infinite_guns.dm b/code/datums/spells/infinite_guns.dm deleted file mode 100644 index a7666232db5c3..0000000000000 --- a/code/datums/spells/infinite_guns.dm +++ /dev/null @@ -1,53 +0,0 @@ -/datum/spell/infinite_guns - name = "Lesser Summon Guns" - desc = "Why reload when you have infinite guns? Summons an unending stream of bolt action rifles. Requires both hands free to use." - invocation_type = "none" - - base_cooldown = 600 - clothes_req = TRUE - cooldown_min = 10 //Gun wizard - action_icon_state = "bolt_action" - var/gun_type = /obj/item/gun/projectile/shotgun/boltaction/enchanted - -/datum/spell/infinite_guns/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/infinite_guns/cast(list/targets, mob/user = usr) - for(var/mob/living/carbon/C in targets) - C.drop_item() - C.swap_hand() - C.drop_item() - var/obj/item/gun/projectile/shotgun/boltaction/enchanted/GUN = new gun_type() - C.put_in_hands(GUN) - -/datum/spell/infinite_guns/fireball - name = "Rapid-fire Fireball" - desc = "Multiple Fireballs. Need I explain more? Requires both hands free to use." - - base_cooldown = 30 SECONDS - clothes_req = FALSE - invocation = "ONI SOMA-SOMA-SOMA" - invocation_type = "shout" - action_icon_state = "explosion" - gun_type = /obj/item/gun/projectile/shotgun/boltaction/enchanted/arcane_barrage/fireball - -/obj/item/gun/projectile/shotgun/boltaction/enchanted/arcane_barrage/fireball - name = "small ball of fire" - desc = "A small flame, ready to launch from your hand." - icon = 'icons/obj/cigarettes.dmi' - icon_state = "match_unathi" - item_state = "disintegrate" - lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' - righthand_file = 'icons/mob/inhands/items_righthand.dmi' - color = "#e1ff00" // red + yellow = orange - guns_left = 20 - fire_sound = 'sound/magic/Fireball.ogg' - mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage/fireball - flags = NOBLUDGEON | DROPDEL - -/obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage/fireball - ammo_type = /obj/item/ammo_casing/magic/arcane_barrage/fireball - -/obj/item/ammo_casing/magic/arcane_barrage/fireball - projectile_type = /obj/item/projectile/magic/fireball - muzzle_flash_effect = null diff --git a/code/datums/spells/knock.dm b/code/datums/spells/knock.dm deleted file mode 100644 index 816c529a0de6e..0000000000000 --- a/code/datums/spells/knock.dm +++ /dev/null @@ -1,67 +0,0 @@ -/datum/spell/aoe/knock - name = "Knock" - desc = "This spell opens nearby doors and does not require wizard garb." - - base_cooldown = 100 - clothes_req = FALSE - invocation = "AULIE OXIN FIERA" - invocation_type = "whisper" - cooldown_min = 20 //20 deciseconds reduction per rank - - action_icon_state = "knock" - sound = 'sound/magic/knock.ogg' - aoe_range = 3 - -/datum/spell/aoe/knock/create_new_targeting() - var/datum/spell_targeting/aoe/turf/targeting = new() - targeting.range = aoe_range - return targeting - -/datum/spell/aoe/knock/cast(list/targets, mob/user = usr) - for(var/turf/T in targets) - for(var/obj/machinery/door/door in T.contents) - INVOKE_ASYNC(src, PROC_REF(try_open_airlock), door) - for(var/obj/structure/closet/C in T.contents) - INVOKE_ASYNC(src, PROC_REF(try_open_closet), C) - -/datum/spell/aoe/knock/proc/try_open_airlock(obj/machinery/door/door) - if(istype(door, /obj/machinery/door/airlock)) - var/obj/machinery/door/airlock/A = door - A.unlock(TRUE) //forced because it's magic! - door.open() - -/datum/spell/aoe/knock/proc/try_open_closet(obj/structure/closet/C) - if(istype(C, /obj/structure/closet/secure_closet)) - var/obj/structure/closet/secure_closet/SC = C - SC.locked = FALSE - C.open() - -/datum/spell/aoe/knock/greater - name = "Greater Knock" - desc = "On first cast, will remove access restrictions on all airlocks on the station, and announce this spell's use to the station. On any further cast, will open all doors in sight. Cannot be refunded once bought!" - - base_cooldown = 200 - invocation = "MAIOR OXIN FIERA" - invocation_type = "shout" - level_max = 0 //Cannot be improved, quality of life since can't be refunded - cooldown_min = 200 - var/used = FALSE - - action_icon_state = "greater_knock" - -/datum/spell/aoe/knock/greater/cast(list/targets, mob/user = usr) - if(!used) - used = TRUE - for(var/obj/machinery/door/airlock/A in GLOB.airlocks) - if(is_station_level(A.z)) - A.req_access = list() - A.req_one_access = list() - GLOB.major_announcement.Announce( - message = "We have removed all access requirements on your station's airlocks. You can thank us later!", - new_title = "Space Wizard Federation Message", - new_subtitle = "Greetings!", - new_sound = 'sound/misc/notice2.ogg' - ) - else - ..() - return diff --git a/code/datums/spells/lichdom.dm b/code/datums/spells/lichdom.dm deleted file mode 100644 index 4df3537367fb7..0000000000000 --- a/code/datums/spells/lichdom.dm +++ /dev/null @@ -1,143 +0,0 @@ -/datum/spell/lichdom - name = "Bind Soul" - desc = "A dark necromantic pact that can forever bind your soul to an item of your choosing. So long as both your body and the item remain intact and on the same plane you can revive from death, though the time between reincarnations grows steadily with use." - base_cooldown = 10 - clothes_req = FALSE - centcom_cancast = FALSE - invocation = "NECREM IMORTIUM!" - invocation_type = "shout" - level_max = 0 //cannot be improved - cooldown_min = 10 - - var/marked_item_uid - var/mob/living/current_body - var/resurrections = 0 - - action_icon_state = "skeleton" - -/datum/spell/lichdom/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/lichdom/cast(list/targets, mob/user = usr) - for(var/mob/M in targets) - if(stat_allowed) - attempt_revive(M) - else if(!marked_item_uid) - attempt_mark_item(M) - -/datum/spell/lichdom/proc/attempt_revive(mob/user) - // Can only cast when unconscious/dead - if(user.stat == CONSCIOUS) - to_chat(user, "You aren't dead enough to revive!") - cooldown_handler.revert_cast() - return - - // Body was destroyed - if(QDELETED(current_body)) - to_chat(user, "Your body is gone!") - return - - // Phylactery was destroyed - var/obj/item/marked_item = locateUID(marked_item_uid) - if(QDELETED(marked_item)) - to_chat(user, "Your phylactery is gone!") - return - - // Wrong z-level - var/turf/body_turf = get_turf(current_body) - var/turf/item_turf = get_turf(marked_item) - if(body_turf.z != item_turf.z) - to_chat(user, "Your phylactery is out of range!") - return - - if(isobserver(user)) - var/mob/dead/observer/O = user - O.reenter_corpse() - - // Clean up the old body - if(!QDELETED(current_body)) - if(iscarbon(current_body)) - var/mob/living/carbon/C = current_body - for(var/obj/item/W in C) - C.drop_item_to_ground(W) - - // Give a hint as to where the body is - var/wheres_wizdo = dir2text(get_dir(body_turf, item_turf)) - if(wheres_wizdo) - current_body.visible_message("Suddenly [current_body.name]'s corpse falls to pieces! You see a strange energy rise from the remains, and speed off towards the [wheres_wizdo]!") - body_turf.Beam(item_turf, icon_state = "lichbeam", icon = 'icons/effects/effects.dmi', time = 10 + 10 * resurrections, maxdistance = INFINITY) - - UnregisterSignal(current_body, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_Z_CHANGED)) - current_body.dust() - - var/stun_time = (1 + resurrections++) * 20 SECONDS - - var/mob/living/carbon/human/lich = new /mob/living/carbon/human(item_turf) - lich.set_species(/datum/species/skeleton/lich) - lich.real_name = user.mind.name - lich.Weaken(stun_time) - user.mind.transfer_to(lich) - equip_lich(lich) - - current_body = lich - cooldown_handler.recharge_duration += 1 MINUTES - to_chat(lich, "Your bones clatter and shudder as they're pulled back into this world!") - -/datum/spell/lichdom/proc/attempt_mark_item(mob/user) - var/obj/item/target = user.get_active_hand() - if(!target) - to_chat(user, "You must hold an item you wish to make your phylactery!") - return - - if(target.flags & (ABSTRACT|NODROP)) - to_chat(user, "[target] cannot be used as your phylactery!") - return - - if(!do_after(user, 5 SECONDS, target = target)) - to_chat(user, "Your soul snaps back to your body as you drop [target]!") - return - - name = "RISE!" - desc = "Rise from the dead! You will reform at the location of your phylactery and your old body will crumble away." - stat_allowed = UNCONSCIOUS - cooldown_handler.recharge_duration = 3 MINUTES - cooldown_handler.revert_cast() - if(action) - action.name = name - action.desc = desc - UpdateButtons() - - target.name = "ensouled [target.name]" - target.desc += "
    A terrible aura surrounds this item, its very existence is offensive to life itself..." - target.color = "#003300" - marked_item_uid = target.UID() - - current_body = user.mind.current - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.set_species(/datum/species/skeleton/lich) - H.drop_item_to_ground(H.wear_suit) - H.drop_item_to_ground(H.head) - H.drop_item_to_ground(H.shoes) - H.drop_item_to_ground(H.head) - equip_lich(H) - - to_chat(user, "With a hideous feeling of emptiness you watch in horrified fascination as skin sloughs off bone! Blood boils, nerves disintegrate, eyes boil in their sockets! As your organs crumble to dust in your fleshless chest you come to terms with your choice. You're a lich!") - -/datum/spell/lichdom/proc/is_revive_possible() - var/obj/item/marked_item = locateUID(marked_item_uid) - if(QDELETED(marked_item)) - return FALSE - if(QDELETED(current_body)) - return FALSE - var/turf/body_turf = get_turf(current_body) - var/turf/item_turf = get_turf(marked_item) - if(body_turf.z != item_turf.z) - return FALSE - return TRUE - -/datum/spell/lichdom/proc/equip_lich(mob/living/carbon/human/H) - H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(H), ITEM_SLOT_OUTER_SUIT) - 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/shoes/sandal(H), ITEM_SLOT_SHOES) - H.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(H), ITEM_SLOT_JUMPSUIT) diff --git a/code/datums/spells/lightning.dm b/code/datums/spells/lightning.dm deleted file mode 100644 index c7e79e2e103d4..0000000000000 --- a/code/datums/spells/lightning.dm +++ /dev/null @@ -1,53 +0,0 @@ -/datum/spell/charge_up/bounce/lightning - name = "Lightning Bolt" - desc = "Throws a lightning bolt at your enemies. Classic. When clicked will start to charge in power. Then click on a mob to send the bolt before it overloads with power." - base_cooldown = 30 SECONDS - clothes_req = TRUE - invocation = "UN'LTD P'WAH!" - invocation_type = "shout" - cooldown_min = 3 SECONDS - action_icon_state = "lightning" - charge_sound = new /sound('sound/magic/lightning_chargeup.ogg', channel = 7) - max_charge_time = 10 SECONDS - stop_charging_text = "You stop charging the lightning around you." - stop_charging_fail_text = "The lightning around you is too strong to stop now!" - start_charging_text = "You start gathering lightning around you." - bounce_hit_sound = 'sound/magic/lightningshock.ogg' - var/damaging = TRUE - -/datum/spell/charge_up/bounce/lightning/New() - ..() - charge_up_overlay = image(icon = 'icons/effects/effects.dmi', icon_state = "electricity", layer = EFFECTS_LAYER) - -/datum/spell/charge_up/bounce/lightning/lightnian - clothes_req = FALSE - invocation_type = "none" - damaging = FALSE - -/datum/spell/charge_up/bounce/lightning/get_bounce_energy() - if(damaging) - return max(15, get_energy_charge() / 2) - return 0 - -/datum/spell/charge_up/bounce/lightning/get_bounce_amount() - if(damaging) - return 5 - return round(get_energy_charge() / 20) - -/datum/spell/charge_up/bounce/lightning/create_beam(mob/origin, mob/target) - origin.Beam(target, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5) - -/datum/spell/charge_up/bounce/lightning/apply_bounce_effect(mob/origin, mob/living/target, energy, mob/user) - if(target.can_block_magic(antimagic_flags)) - target.visible_message( - "[target] absorbs the spell, remaining unharmed!", - "You absorb the spell, remaining unharmed!" - ) - return - if(damaging) - target.electrocute_act(energy, "Lightning Bolt", flags = SHOCK_NOGLOVES) - else - target.AdjustJitter(2000 SECONDS) //High numbers for violent convulsions - target.AdjustStuttering(4 SECONDS) - target.Slowed(6 SECONDS) - addtimer(CALLBACK(target, TYPE_PROC_REF(/mob/living, AdjustJitter), -2000 SECONDS, 10), 2 SECONDS) //Still jittery, but vastly less diff --git a/code/datums/spells/magnet.dm b/code/datums/spells/magnet.dm deleted file mode 100644 index 55b03e5c7b1e9..0000000000000 --- a/code/datums/spells/magnet.dm +++ /dev/null @@ -1,56 +0,0 @@ -/datum/spell/charge_up/bounce/magnet - name = "Magnetic Pull" - desc = "Pulls metalic objects from enemies hands with the power of MAGNETS." - action_icon_state = "magnet" - base_cooldown = 30 SECONDS - clothes_req = FALSE - invocation = "UN'LTD P'WAH!" - invocation_type = "none" - cooldown_min = 3 SECONDS - charge_sound = new /sound('sound/magic/lightning_chargeup.ogg', channel = 7) - max_charge_time = 10 SECONDS - stop_charging_text = "You stop charging the magnetism around you." - stop_charging_fail_text = "The magnetism around you is too strong to stop now!" - start_charging_text = "You start gathering magnetism around you." - bounce_hit_sound = 'sound/machines/defib_zap.ogg' - -/datum/spell/charge_up/bounce/magnet/New() - ..() - charge_up_overlay = image(icon = 'icons/effects/effects.dmi', icon_state = "electricity", layer = EFFECTS_LAYER) - -/datum/spell/charge_up/bounce/magnet/get_bounce_energy() - return get_energy_charge() - -/datum/spell/charge_up/bounce/magnet/get_bounce_amount() - if(get_energy_charge() >= 75) - return 5 - return 0 - -/datum/spell/charge_up/bounce/magnet/create_beam(mob/origin, mob/target) - origin.Beam(target, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5) - -/datum/spell/charge_up/bounce/magnet/apply_bounce_effect(mob/origin, mob/target, energy, mob/user) - var/list/items_to_throw = list() - switch(energy) - if(0 to 25) - if(prob(50)) - if(target.l_hand) - items_to_throw += target.l_hand - else - if(target.r_hand) - items_to_throw += target.r_hand - if(25 to INFINITY) - if(target.r_hand) - items_to_throw += target.r_hand - if(target.l_hand) - items_to_throw += target.l_hand - for(var/I in items_to_throw) - try_throw_object(user, target, I) - -/datum/spell/charge_up/bounce/magnet/proc/try_throw_object(mob/user, mob/thrower, obj/item/to_throw) - if(!(to_throw.flags & CONDUCT) || !thrower.drop_item_to_ground(to_throw, silent = TRUE)) - return FALSE - thrower.visible_message("[to_throw] gets thrown out of [thrower] [thrower.p_their()] hands!", - "[to_throw] suddenly gets thrown out of your hands!") - to_throw.throw_at(user, to_throw.throw_range, 4) - return TRUE diff --git a/code/datums/spells/mime.dm b/code/datums/spells/mime.dm deleted file mode 100644 index eda8b98224193..0000000000000 --- a/code/datums/spells/mime.dm +++ /dev/null @@ -1,171 +0,0 @@ -/datum/spell/aoe/conjure/build/mime_wall - name = "Invisible Wall" - desc = "The mime's performance transmutates into physical reality." - summon_type = list(/obj/structure/forcefield/mime) - invocation_type = "emote" - invocation_emote_self = "You form a wall in front of yourself." - summon_lifespan = 20 SECONDS - base_cooldown = 30 SECONDS - clothes_req = FALSE - cast_sound = null - human_req = TRUE - antimagic_flags = NONE - - action_icon_state = "mime" - action_background_icon_state = "bg_mime" - -/datum/spell/aoe/conjure/build/mime_wall/Click() - if(usr && usr.mind) - if(!usr.mind.miming) - to_chat(usr, "You must dedicate yourself to silence first.") - return - invocation = "[usr.name] looks as if a wall is in front of [usr.p_them()]." - else - invocation_type ="none" - ..() - -/datum/spell/mime/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/mime/speak - name = "Speech" - desc = "Make or break a vow of silence." - clothes_req = FALSE - base_cooldown = 5 MINUTES - human_req = TRUE - - action_icon_state = "mime_silence" - action_background_icon_state = "bg_mime" - -/datum/spell/mime/speak/Click() - if(!usr) - return - if(!ishuman(usr)) - return - var/mob/living/carbon/human/H = usr - if(H.mind.miming) - still_recharging_msg = "You can't break your vow of silence that fast!" - else - still_recharging_msg = "You'll have to wait before you can give your vow of silence again!" - ..() - -/datum/spell/mime/speak/cast(list/targets,mob/user = usr) - for(var/mob/living/carbon/human/H in targets) - H.mind.miming=!H.mind.miming - if(H.mind.miming) - to_chat(H, "You make a vow of silence.") - else - to_chat(H, "You break your vow of silence.") - -//Advanced Mimery traitor item spells - -/datum/spell/forcewall/mime - name = "Invisible Greater Wall" - desc = "Form an invisible three tile wide blockade." - wall_type = /obj/effect/forcefield/mime - invocation_type = "emote" - invocation_emote_self = "You form a blockade in front of yourself." - base_cooldown = 60 SECONDS - sound = null - clothes_req = FALSE - - action_icon_state = "mime_bigwall" - action_background_icon_state = "bg_mime" - -/datum/spell/forcewall/mime/Click() - if(usr && usr.mind) - if(!usr.mind.miming) - to_chat(usr, "You must dedicate yourself to silence first.") - return - invocation = "[usr.name] looks as if a blockade is in front of [usr.p_them()]." - else - invocation_type ="none" - ..() - -/datum/spell/mime/fingergun - name = "Finger Gun" - desc = "Shoot lethal, silencing bullets out of your fingers! 3 bullets available per cast. Use your fingers to holster them manually." - clothes_req = FALSE - base_cooldown = 30 SECONDS - human_req = TRUE - antimagic_flags = NONE - - action_icon_state = "fingergun" - action_background_icon_state = "bg_mime" - var/gun = /obj/item/gun/projectile/revolver/fingergun - var/obj/item/gun/projectile/revolver/fingergun/current_gun - -/datum/spell/mime/fingergun/cast(list/targets, mob/user = usr) - for(var/mob/living/carbon/human/C in targets) - if(!current_gun) - to_chat(user, "You draw your fingers!") - current_gun = new gun(get_turf(user), src) - C.drop_item() - C.put_in_hands(current_gun) - RegisterSignal(C, COMSIG_MOB_WILLINGLY_DROP, PROC_REF(holster_hand)) - else - holster_hand(user, TRUE) - revert_cast(user) - - -/datum/spell/mime/fingergun/Destroy() - current_gun = null - return ..() - -/datum/spell/mime/fingergun/proc/holster_hand(atom/target, any=FALSE) - SIGNAL_HANDLER - if(!current_gun || !any && action.owner.get_active_hand() != current_gun) - return - to_chat(action.owner, "You holster your fingers. Another time perhaps...") - QDEL_NULL(current_gun) - -/datum/spell/mime/fingergun/fake - desc = "Pretend you're shooting bullets out of your fingers! 3 bullets available per cast. Use your fingers to holster them manually." - gun = /obj/item/gun/projectile/revolver/fingergun/fake - -// Mime Spellbooks - -/obj/item/spellbook/oneuse/mime - spell = /datum/spell/aoe/conjure/build/mime_wall - spellname = "Invisible Wall" - name = "Miming Manual : " - desc = "It contains various pictures of mimes mid-performance, aswell as some illustrated tutorials." - icon_state = "bookmime" - -/obj/item/spellbook/oneuse/mime/attack_self__legacy__attackchain(mob/user) - var/datum/spell/S = new spell - for(var/datum/spell/knownspell in user.mind.spell_list) - if(knownspell.type == S.type) - if(user.mind) - to_chat(user, "You've already read this one.") - return - if(used) - recoil(user) - else - user.mind.AddSpell(S) - to_chat(user, "You flip through the pages. Your understanding of the boundaries of reality increases. You can cast [spellname]!") - user.create_log(MISC_LOG, "learned the spell [spellname] ([S])") - user.create_attack_log("[key_name(user)] learned the spell [spellname] ([S]).") - onlearned(user) - -/obj/item/spellbook/oneuse/mime/recoil(mob/user) - to_chat(user, "You flip through the pages. Nothing of interest to you.") - -/obj/item/spellbook/oneuse/mime/onlearned(mob/user) - used = TRUE - if(!locate(/datum/spell/mime/speak) in user.mind.spell_list) //add vow of silence if not known by user - user.mind.AddSpell(new /datum/spell/mime/speak) - to_chat(user, "You have learned how to use silence to improve your performance.") - -/obj/item/spellbook/oneuse/mime/fingergun - spell = /datum/spell/mime/fingergun - spellname = "Finger Gun" - desc = "It contains illustrations of guns and how to mime them." - -/obj/item/spellbook/oneuse/mime/fingergun/fake - spell = /datum/spell/mime/fingergun/fake - -/obj/item/spellbook/oneuse/mime/greaterwall - spell = /datum/spell/forcewall/mime - spellname = "Invisible Greater Wall" - desc = "It contains illustrations of the great walls of human history." diff --git a/code/datums/spells/mime_malaise.dm b/code/datums/spells/mime_malaise.dm deleted file mode 100644 index 48ea74fda890d..0000000000000 --- a/code/datums/spells/mime_malaise.dm +++ /dev/null @@ -1,54 +0,0 @@ -/datum/spell/touch/mime_malaise - name = "Mime Malaise" - desc = "A spell popular with theater nerd wizards and contrarian pranksters, this spell will put on a mime costume on the target, \ - stun them so that they may contemplate Art, and silence them. \ - Warning : Effects are permanent on non-wizards." - hand_path = /obj/item/melee/touch_attack/mime_malaise - - base_cooldown = 300 - clothes_req = TRUE - cooldown_min = 100 //50 deciseconds reduction per rank - action_icon_state = "mime_curse" - -/obj/item/melee/touch_attack/mime_malaise - name = "mime hand" - desc = "..." - catchphrase = null - on_use_sound = null - icon_state = "fleshtostone" - item_state = "fleshtostone" - -/obj/item/melee/touch_attack/mime_malaise/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - . = ..() - - if(!proximity_flag || target == user || blocked_by_antimagic || !ishuman(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) - return - - var/datum/effect_system/smoke_spread/s = new - s.set_up(5, FALSE, target) - s.start() - - var/mob/living/carbon/human/H = target - H.mimetouched() - handle_delete(user) - -/mob/living/carbon/human/proc/mimetouched() - Weaken(14 SECONDS) - if(iswizard(src) || (mind && mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE)) //Wizards get non-cursed mime outfit. Replace with mime robes if we add those. - drop_item_to_ground(wear_mask, force = TRUE) - drop_item_to_ground(w_uniform, force = TRUE) - drop_item_to_ground(wear_suit, force = TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/mime, ITEM_SLOT_MASK, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/under/rank/civilian/mime, ITEM_SLOT_JUMPSUIT, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/suit/suspenders, ITEM_SLOT_OUTER_SUIT, TRUE, TRUE) - Silence(14 SECONDS) - else - qdel(wear_mask) - qdel(w_uniform) - qdel(wear_suit) - equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/mime/nodrop, ITEM_SLOT_MASK, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/under/rank/civilian/mime/nodrop, ITEM_SLOT_JUMPSUIT, TRUE, TRUE) - equip_to_slot_if_possible(new /obj/item/clothing/suit/suspenders/nodrop, ITEM_SLOT_OUTER_SUIT, TRUE, TRUE) - dna.SetSEState(GLOB.muteblock , TRUE, TRUE) - singlemutcheck(src, GLOB.muteblock, MUTCHK_FORCED) - dna.default_blocks.Add(GLOB.muteblock) diff --git a/code/datums/spells/mind_transfer.dm b/code/datums/spells/mind_transfer.dm deleted file mode 100644 index 2e3bad262cf08..0000000000000 --- a/code/datums/spells/mind_transfer.dm +++ /dev/null @@ -1,89 +0,0 @@ -/datum/spell/mind_transfer - name = "Mind Transfer" - desc = "This spell allows the user to switch bodies with a target." - - base_cooldown = 600 - clothes_req = FALSE - invocation = "GIN'YU CAPAN" - invocation_type = "none" // shh - selection_activated_message = "You prepare to transfer your mind. Click on a target to cast the spell." - selection_deactivated_message = "You decide that your current form is good enough." - cooldown_min = 200 //100 deciseconds reduction per rank - antimagic_flags = MAGIC_RESISTANCE|MAGIC_RESISTANCE_MIND - var/list/protected_roles = list(SPECIAL_ROLE_WIZARD, SPECIAL_ROLE_CHANGELING, SPECIAL_ROLE_CULTIST) //which roles are immune to the spell - var/paralysis_amount_caster = 40 SECONDS //how much the caster is paralysed for after the spell - var/paralysis_amount_victim = 40 SECONDS //how much the victim is paralysed for after the spell - action_icon_state = "mindswap" - sound = 'sound/magic/mindswap.ogg' - -/datum/spell/mind_transfer/create_new_targeting() - var/datum/spell_targeting/click/T = new() - T.allowed_type = /mob/living - T.range = 3 - T.click_radius = 0 - // you can use it on yourself as a fake-out - T.include_user = TRUE - return T - -/datum/spell/mind_transfer/valid_target(mob/living/target, mob/user) - return target.stat != DEAD && target.key && target.mind - -/* -Urist: I don't feel like figuring out how you store object spells so I'm leaving this for you to do. -Make sure spells that are removed from spell_list are actually removed and deleted when mind transfering. -Also, you never added distance checking after target is selected. I've went ahead and did that. -*/ -/datum/spell/mind_transfer/cast(list/targets, mob/user = usr) - - var/mob/living/target = targets[1] - - if(user.suiciding) - to_chat(user, "You're killing yourself! You can't concentrate enough to do this!") - return - - if((target.mind.special_role in protected_roles) && target != user) - to_chat(user, "Their mind is resisting your spell.") - return - - if(issilicon(target)) - to_chat(user, "You feel this enslaved being is just as dead as its cold, hard exoskeleton.") - return - if(target.can_block_magic(antimagic_flags)) - to_chat(user, "Their mind is resisting your spell.") - return - - var/mob/living/victim = target//The target of the spell whos body will be transferred to. - var/mob/living/caster = user//The wizard/whomever doing the body transferring. - - if(victim != caster) - //MIND TRANSFER BEGIN - if(length(caster.mind.special_verbs))//If the caster had any special verbs, remove them from the mob verb list. - for(var/V in caster.mind.special_verbs)//Since the caster is using an object spell system, this is mostly moot. - remove_verb(caster, V) //But a safety nontheless. - - if(length(victim.mind.special_verbs))//Now remove all of the victim's verbs. - for(var/V in victim.mind.special_verbs) - remove_verb(victim, V) - - var/mob/dead/observer/ghost = victim.ghostize(0) - caster.mind.transfer_to(victim) - - if(length(victim.mind.special_verbs))//To add all the special verbs for the original caster. - for(var/V in caster.mind.special_verbs)//Not too important but could come into play. - add_verb(caster, V) - - ghost.mind.transfer_to(caster) - if(ghost.key) - GLOB.non_respawnable_keys -= ghost.ckey - caster.key = ghost.key //have to transfer the key since the mind was not active - qdel(ghost) - - if(length(caster.mind.special_verbs))//If they had any special verbs, we add them here. - for(var/V in caster.mind.special_verbs) - add_verb(caster, V) - //MIND TRANSFER END - - for(var/mob/new_or_formal_wizard in list(victim, caster)) - for(var/mob/living/L in range(3, new_or_formal_wizard)) - L.SetSilence(15 SECONDS) - diff --git a/code/datums/spells/night_vision.dm b/code/datums/spells/night_vision.dm deleted file mode 100644 index ae5c94f97610e..0000000000000 --- a/code/datums/spells/night_vision.dm +++ /dev/null @@ -1,29 +0,0 @@ -/datum/spell/night_vision - name = "Toggle Nightvision" - desc = "Toggle your nightvision mode." - - base_cooldown = 10 - clothes_req = FALSE - antimagic_flags = NONE - - message = "You toggle your night vision!" - -/datum/spell/night_vision/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/night_vision/cast(list/targets, mob/user = usr) - for(var/mob/living/target in targets) - switch(target.lighting_alpha) - if(LIGHTING_PLANE_ALPHA_VISIBLE) - target.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - name = "Toggle Nightvision \[More]" - if(LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - target.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - name = "Toggle Nightvision \[Full]" - if(LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) - target.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE - name = "Toggle Nightvision \[OFF]" - else - target.lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE - name = "Toggle Nightvision \[ON]" - target.update_sight() diff --git a/code/datums/spells/rathens.dm b/code/datums/spells/rathens.dm deleted file mode 100644 index 22969027c4668..0000000000000 --- a/code/datums/spells/rathens.dm +++ /dev/null @@ -1,48 +0,0 @@ -/datum/spell/rathens - name = "Rathen's Secret" - desc = "Summons a powerful shockwave around you that tears the appendix out of enemies, and occasionally removes their limbs." - base_cooldown = 50 SECONDS - clothes_req = TRUE - invocation = "APPEN NATH!" - invocation_type = "shout" - cooldown_min = 20 SECONDS - action_icon_state = "lungpunch" - -/datum/spell/rathens/create_new_targeting() - var/datum/spell_targeting/targeted/T = new() - T.max_targets = INFINITY - return T - -/datum/spell/rathens/cast(list/targets, mob/user = usr) - for(var/mob/living/carbon/human/H in targets) - if(H.can_block_magic(antimagic_flags)) - continue - var/datum/effect_system/smoke_spread/s = new - s.set_up(5, FALSE, H) - s.start() - var/obj/item/organ/internal/appendix/A = H.get_int_organ(/obj/item/organ/internal/appendix) - if(A) - A.remove(H) - A.forceMove(get_turf(H)) - spawn() - A.throw_at(get_edge_target_turf(H, pick(GLOB.alldirs)), rand(1, 10), 5) - H.visible_message("[H]'s [A.name] flies out of their body in a magical explosion!",\ - "Your [A.name] flies out of your body in a magical explosion!") - H.KnockDown(4 SECONDS) - else - var/obj/effect/decal/cleanable/blood/gibs/G = new/obj/effect/decal/cleanable/blood/gibs(get_turf(H)) - spawn() - G.throw_at(get_edge_target_turf(H, pick(GLOB.alldirs)), rand(1, 10), 5) - H.apply_damage(10, BRUTE, "chest") - to_chat(H, "You have no appendix, but something had to give! Holy shit, what was that?") - H.KnockDown(6 SECONDS) - for(var/obj/item/organ/external/E in H.bodyparts) - if(istype(E, /obj/item/organ/external/head)) - continue - if(istype(E, /obj/item/organ/external/chest)) - continue - if(istype(E, /obj/item/organ/external/groin)) - continue - if(prob(7)) - to_chat(H, "Your [E] was severed by the explosion!") - E.droplimb(1, DROPLIMB_SHARP, 0, 1) diff --git a/code/datums/spells/sentient_sword_lunge.dm b/code/datums/spells/sentient_sword_lunge.dm deleted file mode 100644 index 630ffd1b6bacb..0000000000000 --- a/code/datums/spells/sentient_sword_lunge.dm +++ /dev/null @@ -1,29 +0,0 @@ -/datum/spell/sentient_sword_lunge - name = "Lunge" - desc = "Lunge at something in your view range." - clothes_req = FALSE - base_cooldown = 15 SECONDS - invocation = "EN GARDE!" - invocation_type = "shout" - sound = 'sound/magic/repulse.ogg' - action_icon_state = "lunge" - -/datum/spell/sentient_sword_lunge/create_new_targeting() - return new /datum/spell_targeting/clicked_atom - -/datum/spell/sentient_sword_lunge/cast(list/targets, mob/user = usr) - if(!istype(user.loc, /obj/item)) - to_chat(user, "You cannot use this ability if you're outside a blade!") - return - var/obj/item/nullrod/scythe/talking/user_sword = user.loc - if(ishuman(user_sword.loc)) - var/mob/living/carbon/holder = user_sword.loc - holder.drop_item_to_ground(user_sword) - else if(isstorage(user_sword.loc)) - if(prob(50)) - to_chat(user, "You fail to break out of [user_sword.loc]!") - return - var/turf/our_turf = get_turf(user_sword.loc) - our_turf.visible_message("[user_sword] leaps out of [user_sword.loc]!") - user_sword.forceMove(our_turf) - user_sword.throw_at(targets[1], 10, 3, user) diff --git a/code/datums/spells/spacetime_dist.dm b/code/datums/spells/spacetime_dist.dm deleted file mode 100644 index 9d7b09c162984..0000000000000 --- a/code/datums/spells/spacetime_dist.dm +++ /dev/null @@ -1,139 +0,0 @@ -// This could probably be an aoe spell but it's a little cursed, so I'm not touching it -/datum/spell/spacetime_dist - name = "Spacetime Distortion" - desc = "Entangle the strings of space-time in an area around you, \ - randomizing the layout and making proper movement impossible. The strings vibrate... \ - Upgrading the spell increases range, it does not lower cooldown." - sound = 'sound/magic/strings.ogg' - action_icon_state = "spacetime" - - base_cooldown = 30 SECONDS - clothes_req = TRUE - invocation = "none" - centcom_cancast = FALSE //Prevent people from getting to centcom - cooldown_min = 30 SECONDS //No reduction, just more range. - level_max = 3 - create_attack_logs = FALSE //no please god no do not log range^2 turfs being targeted - - /// Whether we're ready to cast again yet or not. In the event someone lowers their cooldown with charge. - var/ready = TRUE - /// The radius of the scramble around the caster. Increased by 3 * spell_level - var/scramble_radius = 7 - /// The duration of the scramble - var/duration = 15 SECONDS - /// A lazylist of all scramble effects this spell has created. - var/list/effects - -/datum/spell/spacetime_dist/Destroy() - QDEL_LIST_CONTENTS(effects) - return ..() - -/datum/spell/spacetime_dist/create_new_targeting() - var/datum/spell_targeting/spiral/targeting = new() - targeting.range = scramble_radius + 3 * spell_level - return targeting - -/datum/spell/spacetime_dist/on_purchase_upgrade() - . = ..() - targeting = create_new_targeting() - -/datum/spell/spacetime_dist/cast_check(charge_check = TRUE, start_recharge = TRUE, mob/user = usr) - return ..() && ready - -/datum/spell/spacetime_dist/cast(list/targets, mob/user = usr) - . = ..() - var/list/turf/to_switcharoo = targets - if(!length(to_switcharoo)) - to_chat(user, "For whatever reason, the strings nearby aren't keen on being tangled.") - return - - ready = FALSE - effects = list() - - for(var/turf/swap_a as anything in to_switcharoo) - var/turf/swap_b = to_switcharoo[swap_a] - var/obj/effect/cross_action/spacetime_dist/effect_a = new /obj/effect/cross_action/spacetime_dist(swap_a) - var/obj/effect/cross_action/spacetime_dist/effect_b = new /obj/effect/cross_action/spacetime_dist(swap_b) - effect_a.linked_dist = effect_b - effect_a.add_overlay(swap_b.photograph()) - effect_b.linked_dist = effect_a - effect_b.add_overlay(swap_a.photograph()) - effect_b.set_light(4, 30, "#c9fff5") - effects += effect_a - effects += effect_b - - -/datum/spell/spacetime_dist/after_cast(list/targets, mob/user) - . = ..() - addtimer(CALLBACK(src, PROC_REF(clean_turfs)), duration) - -/// Callback which cleans up our effects list after the duration expires. -/datum/spell/spacetime_dist/proc/clean_turfs() - QDEL_LIST_CONTENTS(effects) - ready = TRUE - -/obj/effect/cross_action - name = "cross me" - desc = "for crossing." - anchored = TRUE - -/obj/effect/cross_action/spacetime_dist - name = "spacetime distortion" - desc = "A distortion in spacetime. You can hear faint music..." - icon_state = "nothing" - /// A flags which save people from being thrown about - var/antimagic_flags = MAGIC_RESISTANCE - /// A flags which save people from being thrown about - var/obj/effect/cross_action/spacetime_dist/linked_dist - /// Used to prevent an infinite loop in the space tiime continuum - var/cant_teleport = FALSE - var/walks_left = 50 //prevents the game from hanging in extreme cases - -/obj/effect/cross_action/singularity_act() - return - -/obj/effect/cross_action/singularity_pull() - return - -/obj/effect/cross_action/spacetime_dist/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/effect/cross_action/spacetime_dist/proc/walk_link(atom/movable/AM) - if(ismob(AM)) - var/mob/M = AM - if(M.can_block_magic(antimagic_flags, charge_cost = 0)) - return - if(linked_dist && walks_left > 0) - flick("purplesparkles", src) - linked_dist.get_walker(AM) - walks_left-- - -/obj/effect/cross_action/spacetime_dist/proc/get_walker(atom/movable/AM) - cant_teleport = TRUE - flick("purplesparkles", src) - AM.forceMove(get_turf(src)) - cant_teleport = FALSE - -/obj/effect/cross_action/spacetime_dist/proc/on_atom_entered(atom/source, atom/movable/entered, turf/old_loc) - if(!cant_teleport) - walk_link(entered) - -/obj/effect/cross_action/spacetime_dist/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(user.drop_item(W)) - walk_link(W) - else - walk_link(user) - -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/cross_action/spacetime_dist/attack_hand(mob/user, list/modifiers) - walk_link(user) - -/obj/effect/cross_action/spacetime_dist/Destroy() - cant_teleport = TRUE - linked_dist = null - RemoveElement(/datum/element/connect_loc) - return ..() diff --git a/code/datums/spells/summonitem.dm b/code/datums/spells/summonitem.dm deleted file mode 100644 index 2c4bd719ff32a..0000000000000 --- a/code/datums/spells/summonitem.dm +++ /dev/null @@ -1,148 +0,0 @@ -/datum/spell/summonitem - name = "Instant Summons" - desc = "This spell can be used to recall a previously marked item to your hand from anywhere in the universe." - base_cooldown = 100 - clothes_req = FALSE - invocation = "GAR YOK" - invocation_type = "whisper" - level_max = 0 //cannot be improved - cooldown_min = 100 - - var/obj/marked_item - /// List of objects which will result in the spell stopping with the recursion search - var/static/list/blacklisted_summons = list(/obj/machinery/computer/cryopod = TRUE, /obj/machinery/atmospherics = TRUE, /obj/structure/disposalholder = TRUE, /obj/machinery/disposal = TRUE) - action_icon_state = "summons" - -/datum/spell/summonitem/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/summonitem/cast(list/targets, mob/user = usr) - for(var/mob/living/target in targets) - var/list/hand_items = list(target.get_active_hand(),target.get_inactive_hand()) - var/butterfingers = FALSE - var/message - - if(!marked_item) //linking item to the spell - message = "" - for(var/obj/item in hand_items) - if(istype(item, /obj/item/organ/internal/brain)) //Yeah, sadly this doesn't work due to the organ system. - break - if(istype(item, /obj/item/disk/nuclear)) //Let's not make nukies suffer with this bullshit. - to_chat(user, "[item] has some built in protections against such summoning magic.") - break - if(ABSTRACT in item.flags) - continue - if(NODROP in item.flags) - message += "This feels very redundant, but you go through with it anyway.
    " - marked_item = item - message += "You mark [item] for recall.
    " - name = "Recall [item]" - break - - if(!marked_item) - if(hand_items) - message = "You aren't holding anything that can be marked for recall." - else - message = "You must hold the desired item in your hands to mark it for recall." - - else if(marked_item && (marked_item in hand_items)) //unlinking item to the spell - message = "You remove the mark on [marked_item] to use elsewhere." - name = "Instant Summons" - marked_item = null - - else if(marked_item && !marked_item.loc) //the item was destroyed at some point - message = "You sense your marked item has been destroyed!" - name = "Instant Summons" - marked_item = null - - else //Getting previously marked item - var/obj/item_to_retrieve = marked_item - var/visible_item = TRUE //Items that silently disappear will have the message suppressed - var/infinite_recursion = 0 //I don't want to know how someone could put something inside itself but these are wizards so let's be safe - - while(!isturf(item_to_retrieve.loc) && infinite_recursion < 10) //if it's in something you get the whole thing. - if(istype(item_to_retrieve.loc, /obj/item/organ/internal/headpocket)) - var/obj/item/organ/internal/headpocket/pocket = item_to_retrieve.loc - if(pocket.owner) - to_chat(pocket.owner, "Your [pocket.name] suddenly feels lighter. How strange!") - visible_item = FALSE - break - if(istype(item_to_retrieve.loc, /obj/item/storage/hidden_implant)) //The implant should be left alone - var/obj/item/storage/S = item_to_retrieve.loc - for(var/mob/M in S.mobs_viewing) - to_chat(M, "[item_to_retrieve] suddenly disappears!") - visible_item = FALSE - break - if(ismob(item_to_retrieve.loc)) //If its on someone, properly drop it - var/mob/M = item_to_retrieve.loc - - if(issilicon(M) || !M.drop_item_to_ground(item_to_retrieve)) //Items in silicons warp the whole silicon - M.visible_message("[M] suddenly disappears!", "A force suddenly pulls you away!") - M.forceMove(target.loc) - M.loc.visible_message("[M] suddenly appears!") - item_to_retrieve = null - break - - if(ishuman(M)) //Edge case housekeeping - var/mob/living/carbon/human/C = M - for(var/X in C.bodyparts) - var/obj/item/organ/external/part = X - if(item_to_retrieve in part.embedded_objects) - part.remove_embedded_object(item_to_retrieve) - to_chat(C, "[item_to_retrieve] that was embedded in your [part] has mysteriously vanished. How fortunate!") - if(!C.has_embedded_objects()) - C.clear_alert("embeddedobject") - break - if(item_to_retrieve == part.hidden) - visible_item = FALSE - part.hidden = null - to_chat(C, "Your [part.name] suddenly feels emptier. How weird!") - break - - else - if(istype(item_to_retrieve.loc, /obj/machinery/atmospherics/portable/)) //Edge cases for moved machinery - var/obj/machinery/atmospherics/portable/P = item_to_retrieve.loc - P.disconnect() - P.update_icon() - if(is_type_in_typecache(item_to_retrieve.loc, blacklisted_summons)) - break - item_to_retrieve = item_to_retrieve.loc - if(istype(item_to_retrieve, /obj/item/storage/backpack/modstorage)) - var/obj/item/storage/backpack/modstorage/bag = item_to_retrieve - if(bag.source && bag.source.mod) - item_to_retrieve = bag.source.mod //Grab the modsuit. - - infinite_recursion += 1 - - if(!item_to_retrieve) - return - - if(!isturf(target.loc)) - to_chat(target, "You attempt to cast the spell, but it fails! Perhaps you aren't available?") - return - if(visible_item) - item_to_retrieve.loc.visible_message("[item_to_retrieve] suddenly disappears!") - var/list/heres_disky = item_to_retrieve.search_contents_for(/obj/item/disk/nuclear) - heres_disky += item_to_retrieve.loc.search_contents_for(/obj/item/disk/nuclear) //So if you mark another item in a bag, we don't pull - for(var/obj/item/disk/nuclear/N in heres_disky) - N.forceMove(get_turf(item_to_retrieve)) - N.visible_message("As [item_to_retrieve] vanishes, [N] remains behind!") - break //If you have 2 nads, well, congrats? Keeps message from doubling up - if(target.hand) //left active hand - if(!target.equip_to_slot_if_possible(item_to_retrieve, ITEM_SLOT_LEFT_HAND, FALSE, TRUE)) - if(!target.equip_to_slot_if_possible(item_to_retrieve, ITEM_SLOT_RIGHT_HAND, FALSE, TRUE)) - butterfingers = TRUE - else //right active hand - if(!target.equip_to_slot_if_possible(item_to_retrieve, ITEM_SLOT_RIGHT_HAND, FALSE, TRUE)) - if(!target.equip_to_slot_if_possible(item_to_retrieve, ITEM_SLOT_LEFT_HAND, FALSE, TRUE)) - butterfingers = TRUE - if(butterfingers) - item_to_retrieve.loc = target.loc - item_to_retrieve.loc.visible_message("[item_to_retrieve] suddenly appears!") - playsound(get_turf(target),'sound/magic/summonitems_generic.ogg', 50, 1) - else - item_to_retrieve.loc.visible_message("[item_to_retrieve] suddenly appears in [target]'s hand!") - playsound(get_turf(target),'sound/magic/summonitems_generic.ogg', 50, 1) - - if(message) - to_chat(target, message) diff --git a/code/datums/spells/touch_attacks.dm b/code/datums/spells/touch_attacks.dm deleted file mode 100644 index f3aca8ff3fc0a..0000000000000 --- a/code/datums/spells/touch_attacks.dm +++ /dev/null @@ -1,82 +0,0 @@ -/datum/spell/touch - var/hand_path = /obj/item/melee/touch_attack - var/obj/item/melee/touch_attack/attached_hand = null - var/on_remove_message = TRUE - invocation_type = "none" //you scream on connecting, not summoning - -/datum/spell/touch/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/touch/Click(mob/user = usr) - if(attached_hand) - discharge_hand(user, TRUE) - return FALSE - charge_hand(user) - -/datum/spell/touch/proc/charge_hand(mob/living/carbon/user) - var/hand_handled = 1 - attached_hand = new hand_path(src) - RegisterSignal(user, COMSIG_MOB_WILLINGLY_DROP, PROC_REF(discharge_hand)) - if(isalien(user)) - user.put_in_hands(attached_hand) - return - if(user.hand) //left active hand - if(!user.equip_to_slot_if_possible(attached_hand, ITEM_SLOT_LEFT_HAND, FALSE, TRUE)) - if(!user.equip_to_slot_if_possible(attached_hand, ITEM_SLOT_RIGHT_HAND, FALSE, TRUE)) - hand_handled = 0 - else //right active hand - if(!user.equip_to_slot_if_possible(attached_hand, ITEM_SLOT_RIGHT_HAND, FALSE, TRUE)) - if(!user.equip_to_slot_if_possible(attached_hand, ITEM_SLOT_LEFT_HAND, FALSE, TRUE)) - hand_handled = 0 - if(!hand_handled) - qdel(attached_hand) - attached_hand = null - to_chat(user, "Your hands are full!") - return 0 - to_chat(user, "You channel the power of the spell to your hand.") - return 1 - -/datum/spell/touch/proc/discharge_hand(atom/target, any = FALSE) - SIGNAL_HANDLER - var/mob/living/carbon/user = action.owner - if(!istype(attached_hand)) - return - if(!any && attached_hand != user.get_active_hand()) - return - QDEL_NULL(attached_hand) - if(on_remove_message) - to_chat(user, "You draw the power out of your hand.") - - -/datum/spell/touch/disintegrate - name = "Disintegrate" - desc = "This spell charges your hand with vile energy that can be used to violently explode victims." - hand_path = /obj/item/melee/touch_attack/disintegrate - - base_cooldown = 600 - clothes_req = TRUE - cooldown_min = 200 //100 deciseconds reduction per rank - - action_icon_state = "gib" - -/datum/spell/touch/flesh_to_stone - name = "Flesh to Stone" - desc = "This spell charges your hand with the power to turn victims into inert statues for a long period of time." - hand_path = /obj/item/melee/touch_attack/fleshtostone - - base_cooldown = 600 - clothes_req = TRUE - cooldown_min = 200 //100 deciseconds reduction per rank - - action_icon_state = "statue" - -/datum/spell/touch/plushify - name = "Plushify" - desc = "This spell charges your hand with the power to turn your victims into marketable plushies!" - hand_path = /obj/item/melee/touch_attack/plushify - - base_cooldown = 600 - clothes_req = TRUE - cooldown_min = 200 //100 deciseconds reduction per rank - - action_icon_state = "plush" diff --git a/code/datums/spells/wizard_spells.dm b/code/datums/spells/wizard_spells.dm deleted file mode 100644 index c62f868f40186..0000000000000 --- a/code/datums/spells/wizard_spells.dm +++ /dev/null @@ -1,517 +0,0 @@ -/datum/spell/projectile/magic_missile - name = "Magic Missile" - desc = "This spell fires several, slow moving, magic projectiles at nearby targets." - - base_cooldown = 200 - clothes_req = TRUE - invocation = "FORTI GY AMA" - invocation_type = "shout" - cooldown_min = 60 //35 deciseconds reduction per rank - - proj_icon_state = "magicm" - proj_name = "a magic missile" - proj_lingering = 1 - proj_type = /obj/item/projectile/magic/magic_missile - - proj_lifespan = 20 - proj_step_delay = 2 - - proj_trail = 1 - proj_trail_lifespan = 5 - proj_trail_icon_state = "magicmd" - - action_icon_state = "magicm" - - sound = 'sound/magic/magic_missile.ogg' - -/datum/spell/projectile/magic_missile/create_new_targeting() - var/datum/spell_targeting/targeted/T = new() - T.allowed_type = /mob/living - T.max_targets = INFINITY - return T - -/obj/item/projectile/magic/magic_missile - name = "Magic Missile" - hitsound = 'sound/magic/mm_hit.ogg' - weaken = 6 SECONDS - -/datum/spell/projectile/honk_missile - name = "Honk Missile" - desc = "This spell fires several, slow moving, magic bikehorns at nearby targets." - - base_cooldown = 6 SECONDS - clothes_req = FALSE - invocation = "HONK GY AMA" - invocation_type = "shout" - cooldown_min = 6 SECONDS - - proj_icon = 'icons/obj/items.dmi' - proj_icon_state = "bike_horn" - proj_name = "A bike horn" - proj_lingering = 1 - proj_type = /obj/item/projectile/magic/magic_missile/honk_missile - - proj_lifespan = 20 - proj_step_delay = 5 - - proj_trail_icon = 'icons/obj/items.dmi' - proj_trail = 1 - proj_trail_lifespan = 5 - proj_trail_icon_state = "bike_horn" - - action_icon_state = "magicm" - - sound = 'sound/items/bikehorn.ogg' - -/datum/spell/projectile/honk_missile/create_new_targeting() - var/datum/spell_targeting/targeted/T = new() - T.allowed_type = /mob/living - T.max_targets = INFINITY - return T - -/obj/item/projectile/magic/magic_missile/honk_missile - name = "Funny Missile" - hitsound = 'sound/items/bikehorn.ogg' - -/datum/spell/noclothes - name = "No Clothes" - desc = "This always-on spell allows you to cast magic without your garments." - action_icon_state = "no_clothes" - -/datum/spell/noclothes/create_new_targeting() - return new /datum/spell_targeting/self // Dummy value - -/datum/spell/genetic/mutate - name = "Mutate" - desc = "This spell causes you to turn into a hulk and gain laser vision for a short while." - - base_cooldown = 400 - clothes_req = TRUE - invocation = "BIRUZ BENNAR" - invocation_type = "shout" - message = "You feel strong! You feel a pressure building behind your eyes!" - centcom_cancast = FALSE - - traits = list(TRAIT_LASEREYES) - duration = 300 - cooldown_min = 300 //25 deciseconds reduction per rank - - action_icon_state = "mutate" - sound = 'sound/magic/mutate.ogg' - -/datum/spell/genetic/mutate/New() - ..() - mutations = list(GLOB.hulkblock) - -/datum/spell/genetic/mutate/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/smoke - name = "Smoke" - desc = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb." - - base_cooldown = 120 - clothes_req = FALSE - invocation = "none" - invocation_type = "none" - cooldown_min = 20 //25 deciseconds reduction per rank - - smoke_type = SMOKE_COUGHING - smoke_amt = 10 - - action_icon_state = "smoke" - -/datum/spell/smoke/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/emplosion/disable_tech - name = "Disable Tech" - desc = "This spell disables all weapons, cameras and most other technology in range." - base_cooldown = 40 SECONDS - clothes_req = TRUE - invocation = "NEC CANTIO" - invocation_type = "shout" - cooldown_min = 200 //50 deciseconds reduction per rank - - emp_heavy = 6 - emp_light = 10 - - sound = 'sound/magic/disable_tech.ogg' - -/datum/spell/turf_teleport/blink - name = "Blink" - desc = "This spell randomly teleports you a short distance." - - base_cooldown = 20 - clothes_req = TRUE - invocation = "none" - invocation_type = "none" - cooldown_min = 5 //4 deciseconds reduction per rank - - - smoke_type = SMOKE_HARMLESS - smoke_amt = 1 - - inner_tele_radius = 0 - outer_tele_radius = 6 - - centcom_cancast = FALSE //prevent people from getting to centcom - - action_icon_state = "blink" - - sound1 = 'sound/magic/blink.ogg' - sound2 = 'sound/magic/blink.ogg' - -/datum/spell/turf_teleport/blink/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/area_teleport/teleport - name = "Teleport" - desc = "This spell teleports you to a type of area of your selection." - - base_cooldown = 600 - clothes_req = TRUE - invocation = "SCYAR NILA" - invocation_type = "shout" - cooldown_min = 200 //100 deciseconds reduction per rank - - smoke_amt = 5 - action_icon_state = "spell_teleport" - - sound1 = 'sound/magic/teleport_diss.ogg' - sound2 = 'sound/magic/teleport_app.ogg' - -/datum/spell/area_teleport/teleport/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/return_to_teacher - name = "Return to Teacher" - desc = "This spell teleports you back to your teacher." - - base_cooldown = 30 SECONDS - clothes_req = TRUE - invocation = "SCYAR TESO" - invocation_type = "shout" - cooldown_min = 10 SECONDS - - action_icon_state = "spell_teleport" - var/datum/mind/teacher - -/datum/spell/return_to_teacher/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/return_to_teacher/cast(list/targets, mob/living/user = usr) - if(!(teacher && teacher.current)) - to_chat(user, "The link to your teacher is broken!") - return - do_teleport(user, teacher.current, 1, sound_in = 'sound/magic/blink.ogg', sound_out = 'sound/magic/blink.ogg', safe_turf_pick = TRUE) - -/datum/spell/forcewall - name = "Force Wall" - desc = "This spell creates a 3 tile wide unbreakable wall that only you can pass through, and does not need wizard garb. Lasts 30 seconds." - - base_cooldown = 15 SECONDS - clothes_req = FALSE - invocation = "TARCOL MINTI ZHERI" - invocation_type = "whisper" - sound = 'sound/magic/forcewall.ogg' - action_icon_state = "shield" - cooldown_min = 5 SECONDS //25 deciseconds reduction per rank - var/wall_type = /obj/effect/forcefield/wizard - -/datum/spell/forcewall/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/forcewall/cast(list/targets, mob/user = usr) - new wall_type(get_turf(user), user) - if(user.dir == SOUTH || user.dir == NORTH) - new wall_type(get_step(user, EAST), user) - new wall_type(get_step(user, WEST), user) - else - new wall_type(get_step(user, NORTH), user) - new wall_type(get_step(user, SOUTH), user) - -/datum/spell/aoe/conjure/timestop - name = "Stop Time" - desc = "This spell stops time for everyone except for you, allowing you to move freely while your enemies and even projectiles are frozen." - base_cooldown = 50 SECONDS - clothes_req = TRUE - invocation = "TOKI WO TOMARE" - invocation_type = "shout" - cooldown_min = 100 - summon_amt = 1 - delay = 0 - action_icon_state = "time" - - summon_type = list(/obj/effect/timestop/wizard) - aoe_range = 0 - - -/datum/spell/aoe/conjure/carp - name = "Summon Carp" - desc = "This spell conjures a simple carp." - - base_cooldown = 1200 - clothes_req = TRUE - invocation = "NOUK FHUNMM SACP RISSKA" - invocation_type = "shout" - - summon_type = list(/mob/living/simple_animal/hostile/carp) - - cast_sound = 'sound/magic/summon_karp.ogg' - aoe_range = 1 - -/datum/spell/aoe/conjure/construct - name = "Artificer" - desc = "This spell conjures a construct which may be controlled by Shades." - - base_cooldown = 600 - clothes_req = FALSE - invocation = "none" - invocation_type = "none" - - summon_type = list(/obj/structure/constructshell) - - action_icon_state = "artificer" - cast_sound = 'sound/magic/summonitems_generic.ogg' - aoe_range = 0 - -/datum/spell/aoe/conjure/creature - name = "Summon Creature Swarm" - desc = "This spell tears the fabric of reality, allowing horrific daemons to spill forth." - - base_cooldown = 1200 - clothes_req = FALSE - invocation = "IA IA" - invocation_type = "shout" - summon_amt = 10 - - summon_type = list(/mob/living/simple_animal/hostile/creature) - cast_sound = 'sound/magic/summonitems_generic.ogg' - aoe_range = 3 - -/datum/spell/blind - name = "Blind" - desc = "This spell temporarily blinds a single person and does not require wizard garb." - base_cooldown = 15 SECONDS - clothes_req = FALSE - invocation = "STI KALY" - invocation_type = "whisper" - message = "Your eyes cry out in pain!" - cooldown_min = 2 SECONDS - sound = 'sound/magic/blind.ogg' - -/datum/spell/blind/create_new_targeting() - var/datum/spell_targeting/click/C = new() - C.selection_type = SPELL_SELECTION_RANGE - C.allowed_type = /mob/living - return C - -/datum/spell/blind/cast(list/targets, mob/living/user) - if(!length(targets)) - to_chat(user, "No target found in range.") - return - - var/mob/living/target = targets[1] - if(target.can_block_magic(antimagic_flags)) - to_chat(target, "Your eye itches, but it passes momentarily.") - to_chat(user, "The spell had no effect!") - return FALSE - target.EyeBlurry(40 SECONDS) - target.EyeBlind(30 SECONDS) - - SEND_SOUND(target, sound('sound/magic/blind.ogg')) - return TRUE - -/datum/spell/fireball - name = "Fireball" - desc = "This spell fires a fireball at a target and does not require wizard garb." - - base_cooldown = 60 - clothes_req = FALSE - invocation = "ONI SOMA" - invocation_type = "shout" - cooldown_min = 20 //10 deciseconds reduction per rank - - selection_activated_message = "You prepare to cast your fireball spell! Left-click to cast at a target!" - selection_deactivated_message = "You extinguish your fireball...for now." - - var/fireball_type = /obj/item/projectile/magic/fireball - action_icon_state = "fireball0" - sound = 'sound/magic/fireball.ogg' - - active = FALSE - -/datum/spell/fireball/apprentice - centcom_cancast = FALSE - -/datum/spell/fireball/create_new_targeting() - var/datum/spell_targeting/clicked_atom/external/C = new() - C.range = 20 - return C - -/datum/spell/fireball/update_spell_icon() - if(!action) - return - action.button_overlay_icon_state = "fireball[active]" - action.UpdateButtons() - -/datum/spell/fireball/cast(list/targets, mob/living/user = usr) - var/target = targets[1] //There is only ever one target for fireball - var/turf/T = user.loc - var/turf/U = get_step(user, user.dir) // Get the tile infront of the move, based on their direction - if(!isturf(U) || !isturf(T)) - return FALSE - - var/obj/item/projectile/magic/fireball/FB = new fireball_type(user.loc) - FB.current = get_turf(user) - FB.original = target - FB.firer = user - FB.preparePixelProjectile(target, user) - FB.fire() - user.newtonian_move(get_dir(U, T)) - - return TRUE - -/datum/spell/fireball/toolbox - name = "Homing Toolbox" - desc = "This spell summons and throws a magical homing toolbox at your opponent." - sound = 'sound/weapons/smash.ogg' - fireball_type = /obj/item/projectile/homing/magic/toolbox - invocation = "ROBUSTIO!" - - selection_activated_message = "You prepare to cast your homing toolbox! Left-click to cast at a target!" - selection_deactivated_message = "You unrobust your toolbox...for now." - -/datum/spell/fireball/homing - name = "Greater Homing Fireball" - desc = "This spell fires a strong homing fireball at a target." - invocation = "ZI-ONI SOMA" - fireball_type = /obj/item/projectile/homing/magic/homing_fireball - - selection_activated_message = "You prepare to cast your greater homing fireball spell! Left-click to cast at a target!" - base_cooldown = 6 SECONDS - -/datum/spell/aoe/repulse - name = "Repulse" - desc = "This spell throws everything around the user away." - base_cooldown = 40 SECONDS - clothes_req = TRUE - invocation = "GITTAH WEIGH" - invocation_type = "shout" - cooldown_min = 150 - sound = 'sound/magic/repulse.ogg' - var/maxthrow = 5 - var/sparkle_path = /obj/effect/temp_visual/gravpush - action_icon_state = "repulse" - aoe_range = 5 - -/datum/spell/aoe/repulse/create_new_targeting() - var/datum/spell_targeting/aoe/turf/targeting = new() - targeting.range = aoe_range - return targeting - -/datum/spell/aoe/repulse/cast(list/targets, mob/user = usr, stun_amt = 4 SECONDS) - var/list/thrownatoms = list() - var/atom/throwtarget - var/distfromcaster - playMagSound() - for(var/turf/T in targets) //Done this way so things don't get thrown all around hilariously. - for(var/atom/movable/AM in T) - if(ismob(AM)) - var/mob/victim_mob = AM - if(victim_mob.can_block_magic(antimagic_flags)) - continue - thrownatoms += AM - - for(var/am in thrownatoms) - var/atom/movable/AM = am - if(AM == user || AM.anchored || AM.move_resist == INFINITY) - continue - - throwtarget = get_edge_target_turf(user, get_dir(user, get_step_away(AM, user))) - distfromcaster = get_dist(user, AM) - if(distfromcaster == 0) - if(isliving(AM)) - var/mob/living/M = AM - M.Weaken(10 SECONDS) - M.adjustBruteLoss(5) - to_chat(M, "You're slammed into the floor by a mystical force!") - else - new sparkle_path(get_turf(AM), get_dir(user, AM)) //created sparkles will disappear on their own - if(isliving(AM)) - var/mob/living/M = AM - M.Weaken(stun_amt) - to_chat(M, "You're thrown back by a mystical force!") - spawn(0) - AM.throw_at(throwtarget, ((clamp((maxthrow - (clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1)//So stuff gets tossed around at the same time. - -/datum/spell/sacred_flame - name = "Sacred Flame" - desc = "Makes everyone around you more flammable, and lights yourself on fire." - base_cooldown = 6 SECONDS - clothes_req = FALSE - invocation = "FI'RAN DADISKO" - invocation_type = "shout" - action_icon_state = "sacredflame" - sound = 'sound/magic/fireball.ogg' - -/datum/spell/sacred_flame/create_new_targeting() - var/datum/spell_targeting/aoe/A = new() - A.include_user = TRUE - A.range = 6 - A.allowed_type = /mob/living - return A - -/datum/spell/sacred_flame/cast(list/targets, mob/user = usr) - for(var/mob/living/L in targets) - if(L.can_block_magic(antimagic_flags)) - continue - L.adjust_fire_stacks(20) - if(isliving(user)) - var/mob/living/U = user - U.IgniteMob() - -/datum/spell/corpse_explosion - name = "Corpse Explosion" - desc = "Fills a corpse with energy, causing it to explode violently." - base_cooldown = 5 SECONDS - clothes_req = TRUE - invocation = "JAH ITH BER" - invocation_type = "whisper" - selection_activated_message = "You prepare to detonate a corpse. Click on a target to cast the spell." - selection_deactivated_message = "You cancel the spell." - action_icon_state = "corpse_explosion" - -/datum/spell/corpse_explosion/create_new_targeting() - var/datum/spell_targeting/click/T = new - T.click_radius = 0 - T.try_auto_target = FALSE - T.allowed_type = /mob/living - return T - -/datum/spell/corpse_explosion/cast(list/targets, mob/user) - var/mob/living/target = targets[1] - if(!target || target.stat != DEAD) - return - var/turf/corpse_turf = get_turf(target) - new /obj/effect/temp_visual/corpse_explosion(get_turf(target)) - target.gib() - explosion(corpse_turf, 0, 0, 0, 0, silent = TRUE, breach = FALSE) - for(var/mob/living/M in range(4, corpse_turf)) - if(M == user) - continue - var/range = get_dist_euclidian(M, corpse_turf) - range = max(1, range) - M.apply_damage(100 / range, BRUTE) - if(issilicon(M)) - to_chat(M, "Your sensors are disabled, and your carapace is ripped apart by the violent dark magic!") - M.Weaken(6 SECONDS / range) - continue - - to_chat(M, "You are eviscerated by the violent dark magic!") - if(ishuman(M)) - if(range < 4) - M.KnockDown(4 SECONDS / range) - M.EyeBlurry(40 SECONDS / range) - M.AdjustConfused(6 SECONDS / range) diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm deleted file mode 100644 index 03cac88b537fe..0000000000000 --- a/code/datums/station_traits/neutral_traits.dm +++ /dev/null @@ -1,102 +0,0 @@ -/datum/station_trait/bananium_shipment - name = "Bananium Shipment" - trait_type = STATION_TRAIT_NEUTRAL - weight = 5 - report_message = "An unidentified benefactor has dispatched a mysterious shipment to your station's clown. It was reported to smell faintly of bananas." - trait_to_give = STATION_TRAIT_BANANIUM_SHIPMENTS - -/datum/station_trait/tranquilite_shipment - name = "Tranquilite Shipment" - trait_type = STATION_TRAIT_NEUTRAL - weight = 5 - report_message = "Shipping records show an unmarked crate being delivered to your station's mime." - trait_to_give = STATION_TRAIT_TRANQUILITE_SHIPMENTS - -/datum/station_trait/unique_ai - name = "Unique AI" - trait_type = STATION_TRAIT_NEUTRAL - weight = 15 - show_in_report = TRUE - report_message = "For experimental purposes, this station AI might show divergence from default lawset. Do not meddle with this experiment, we've removed \ - access to your set of alternative upload modules because we know you're already thinking about meddling with this experiment. If the lawset proves \ - dangerous, or impedes station efficiency, fax or message Central Command to request permission to alter it." - trait_to_give = STATION_TRAIT_UNIQUE_AI - blacklist = list(/datum/station_trait/random_event_weight_modifier/ion_storms) - -/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/late_arrivals - name = "Late Arrivals" - trait_type = STATION_TRAIT_NEUTRAL - weight = 5 - 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/hangover) - -/datum/station_trait/late_arrivals/New() - . = ..() - SSjobs.late_arrivals_spawning = TRUE - -/datum/station_trait/late_arrivals/revert() - . = ..() - SSjobs.late_arrivals_spawning = FALSE - - -/datum/station_trait/hangover - name = "Hangover" - trait_type = STATION_TRAIT_NEUTRAL - weight = 5 - 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/hangover/New() - . = ..() - SSjobs.drunken_spawning = TRUE - -/datum/station_trait/hangover/revert() - . = ..() - SSjobs.drunken_spawning = FALSE - -/datum/station_trait/triple_ai - name = "AI Triumvirate" - trait_type = STATION_TRAIT_NEUTRAL - weight = 1 - show_in_report = TRUE - report_message = "As part of Operation Magi, your station has been equipped with three Nanotrasen Artificial Intelligence models. Please try not to break them." - trait_to_give = STATION_TRAIT_TRIAI - -/datum/station_trait/triple_ai/New() - . = ..() - SSticker.triai = TRUE - -/datum/station_trait/triple_ai/revert() - . = ..() - SSticker.triai = FALSE - -/datum/station_trait/rave - name = "Rave" - trait_type = STATION_TRAIT_NEUTRAL - weight = 5 - show_in_report = TRUE - report_message = "Our workers have installed new 'Motivational' lighting for you." - -/datum/station_trait/rave/on_round_start() - . = ..() - for(var/obj/machinery/light/light in GLOB.machines) - var/turf/our_turf = get_turf(light) - var/area/our_area = get_area(light) - if(is_station_level(our_turf.z) || istype(our_area, /area/mine/outpost) || istype(our_area, /area/mine/laborcamp)) - var/list/rgb = hsl2rgb(rand(0, 255) / 255, rand((0.4 * 255), 255) / 255, rand((0.5 * 255), (0.8 * 255)) / 255) - var/new_color = "#[num2hex(rgb[1], 2)][num2hex(rgb[2], 2)][num2hex(rgb[3], 2)]" - light.color = new_color - light.brightness_color = new_color - light.update(FALSE, TRUE, FALSE) diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm deleted file mode 100644 index 2c5acaf69cc07..0000000000000 --- a/code/datums/status_effects/debuffs.dm +++ /dev/null @@ -1,1510 +0,0 @@ -//OTHER DEBUFFS - -/// does minor damage over time unless holding His Grace -/datum/status_effect/his_wrath - id = "his_wrath" - duration = -1 - tick_interval = 4 - alert_type = /atom/movable/screen/alert/status_effect/his_wrath - -/atom/movable/screen/alert/status_effect/his_wrath - name = "His Wrath" - desc = "You fled from His Grace instead of feeding Him, and now you suffer." - icon_state = "his_grace" - alerttooltipstyle = "hisgrace" - -/datum/status_effect/his_wrath/tick() - var/list/held_items = list() - held_items += owner.l_hand - held_items += owner.r_hand - for(var/obj/item/his_grace/HG in held_items) - qdel(src) - return - owner.adjustBruteLoss(0.1) - owner.adjustFireLoss(0.1) - owner.adjustToxLoss(0.2) - -/// is a cult ghost and can't use manifest runes, can see ghosts and dies if too far from summoner -/datum/status_effect/cultghost - id = "cult_ghost" - duration = -1 - alert_type = null - var/damage = 7.5 - var/source_UID - -/datum/status_effect/cultghost/on_creation(mob/living/new_owner, mob/living/source) - . = ..() - source_UID = source.UID() - -/datum/status_effect/cultghost/tick() - if(owner.reagents) - owner.reagents.del_reagent("holywater") //can't be deconverted - var/mob/living/summoner = locateUID(source_UID) - if(get_dist_euclidian(summoner, owner) < 21) - return - owner.adjustBruteLoss(damage) - to_chat(owner, "You are too far away from the summoner!") - -/datum/status_effect/crusher_mark - id = "crusher_mark" - duration = 300 //if you leave for 30 seconds you lose the mark, deal with it - status_type = STATUS_EFFECT_REPLACE - alert_type = null - var/mutable_appearance/marked_underlay - var/obj/item/kinetic_crusher/hammer_synced - -/datum/status_effect/crusher_mark/on_creation(mob/living/new_owner, obj/item/kinetic_crusher/new_hammer_synced) - . = ..() - if(.) - hammer_synced = new_hammer_synced - -/datum/status_effect/crusher_mark/on_apply() - if(owner.mob_size >= MOB_SIZE_LARGE) - marked_underlay = mutable_appearance('icons/effects/effects.dmi', "shield2") - marked_underlay.pixel_x = -owner.pixel_x - marked_underlay.pixel_y = -owner.pixel_y - owner.underlays += marked_underlay - return TRUE - return FALSE - -/datum/status_effect/crusher_mark/Destroy() - hammer_synced = null - if(owner) - owner.underlays -= marked_underlay - QDEL_NULL(marked_underlay) - return ..() - -/datum/status_effect/crusher_mark/be_replaced() - owner.underlays -= marked_underlay //if this is being called, we should have an owner at this point. - ..() - -/datum/status_effect/saw_bleed - id = "saw_bleed" - duration = -1 //removed under specific conditions - tick_interval = 6 - alert_type = null - var/mutable_appearance/bleed_overlay - var/mutable_appearance/bleed_underlay - var/bleed_amount = 3 - var/bleed_buildup = 3 - var/delay_before_decay = 5 - var/bleed_damage = 200 - var/needs_to_bleed = FALSE - var/bleed_cap = 10 - -/datum/status_effect/saw_bleed/Destroy() - if(owner) - owner.cut_overlay(bleed_overlay) - owner.underlays -= bleed_underlay - QDEL_NULL(bleed_overlay) - return ..() - -/datum/status_effect/saw_bleed/on_apply() - if(owner.stat == DEAD) - return FALSE - bleed_overlay = mutable_appearance('icons/effects/bleed.dmi', "bleed[bleed_amount]") - bleed_underlay = mutable_appearance('icons/effects/bleed.dmi', "bleed[bleed_amount]") - var/icon/I = icon(owner.icon, owner.icon_state, owner.dir) - var/icon_height = I.Height() - bleed_overlay.pixel_x = -owner.pixel_x - bleed_overlay.pixel_y = FLOOR(icon_height * 0.25, 1) - bleed_overlay.transform = matrix() * (icon_height/world.icon_size) //scale the bleed overlay's size based on the target's icon size - bleed_underlay.pixel_x = -owner.pixel_x - bleed_underlay.transform = matrix() * (icon_height/world.icon_size) * 3 - bleed_underlay.alpha = 40 - owner.add_overlay(bleed_overlay) - owner.underlays += bleed_underlay - return ..() - -/datum/status_effect/saw_bleed/tick() - if(owner.stat == DEAD) - qdel(src) - else - add_bleed(-1) - -/datum/status_effect/saw_bleed/proc/add_bleed(amount) - owner.cut_overlay(bleed_overlay) - owner.underlays -= bleed_underlay - bleed_amount += amount - if(bleed_amount) - if(bleed_amount >= bleed_cap) - needs_to_bleed = TRUE - qdel(src) - else - if(amount > 0) - tick_interval += delay_before_decay - bleed_overlay.icon_state = "bleed[bleed_amount]" - bleed_underlay.icon_state = "bleed[bleed_amount]" - owner.add_overlay(bleed_overlay) - owner.underlays += bleed_underlay - else - qdel(src) - -/datum/status_effect/saw_bleed/on_remove() - if(needs_to_bleed) - var/turf/T = get_turf(owner) - new /obj/effect/temp_visual/bleed/explode(T) - for(var/d in GLOB.alldirs) - new /obj/effect/temp_visual/dir_setting/bloodsplatter(T, d) - playsound(T, "desceration", 200, TRUE, -1) - owner.adjustBruteLoss(bleed_damage) - else - new /obj/effect/temp_visual/bleed(get_turf(owner)) - -/datum/status_effect/saw_bleed/bloodletting - id = "bloodletting" - bleed_cap = 7 - bleed_damage = 25 //Seems weak (it is) but it also works on humans and bypasses armor SOOOO - bleed_amount = 6 - -/datum/status_effect/stacking/ground_pound - id = "ground_pound" - tick_interval = 5 SECONDS - stack_threshold = 3 - max_stacks = 3 - reset_ticks_on_stack = TRUE - var/mob/living/simple_animal/hostile/asteroid/big_legion/latest_attacker - -/datum/status_effect/stacking/ground_pound/on_creation(mob/living/new_owner, stacks_to_apply, mob/living/attacker) - . = ..() - if(.) - latest_attacker = attacker - -/datum/status_effect/stacking/ground_pound/add_stacks(stacks_added, mob/living/attacker) - . = ..() - if(.) - latest_attacker = attacker - if(stacks != stack_threshold) - return TRUE - -/datum/status_effect/stacking/ground_pound/stacks_consumed_effect() - flick("legion-smash", latest_attacker) - addtimer(CALLBACK(latest_attacker, TYPE_PROC_REF(/mob/living/simple_animal/hostile/asteroid/big_legion, throw_mobs)), 1 SECONDS) - -/datum/status_effect/stacking/ground_pound/on_remove() - latest_attacker = null - -/datum/status_effect/teleport_sickness - id = "teleportation sickness" - duration = 30 SECONDS - status_type = STATUS_EFFECT_REFRESH - alert_type = /atom/movable/screen/alert/status_effect/teleport_sickness - var/teleports = 1 - -/atom/movable/screen/alert/status_effect/teleport_sickness - name = "Teleportation sickness" - desc = "You feel like you are going to throw up with all this teleporting." - icon_state = "bluespace" - -/datum/status_effect/teleport_sickness/refresh() - . = ..() - if(ishuman(owner)) - var/mob/living/carbon/human/M = owner - teleports++ - if(teleports < 3) - return - if(teleports < 6) - to_chat(M, "You feel a bit sick!") - M.vomit(lost_nutrition = 15, blood = 0, should_confuse = FALSE, distance = 0, message = 1) - M.Weaken(2 SECONDS) - else - to_chat(M, "You feel really sick!") - M.adjustBruteLoss(rand(0, teleports * 2)) - M.vomit(lost_nutrition = 30, blood = 0, should_confuse = FALSE, distance = 0, message = 1) - M.Weaken(6 SECONDS) - -/datum/status_effect/pacifism - id = "pacifism_debuff" - alert_type = null - duration = 40 SECONDS - -/datum/status_effect/pacifism/on_apply() - ADD_TRAIT(owner, TRAIT_PACIFISM, id) - return ..() - -/datum/status_effect/pacifism/on_remove() - REMOVE_TRAIT(owner, TRAIT_PACIFISM, id) - -/datum/status_effect/pacifism/batterer - id = "pacifism_debuff_batterer" - alert_type = null - duration = 10 SECONDS - -// used to track if hitting someone with a cult dagger/sword should stamina crit. -/datum/status_effect/cult_stun_mark - id = "cult_stun" - duration = 10 SECONDS // when the knockdown ends, the mark disappears. - alert_type = null - var/mutable_appearance/overlay - -/datum/status_effect/cult_stun_mark/on_apply() - . = ..() - if(!isliving(owner)) - return - overlay = mutable_appearance('icons/effects/cult_effects.dmi', "cult-mark", ABOVE_MOB_LAYER) - owner.add_overlay(overlay) - -/datum/status_effect/cult_stun_mark/on_remove() - owner.cut_overlay(overlay) - -/datum/status_effect/cult_stun_mark/proc/trigger() - owner.apply_damage(60, STAMINA) - owner.Silence(6 SECONDS) // refresh the silence - qdel(src) - -/datum/status_effect/bluespace_slowdown - id = "bluespace_slowdown" - alert_type = null - duration = 15 SECONDS - -/datum/status_effect/bluespace_slowdown/on_apply() - owner.next_move_modifier *= 2 - return ..() - -/datum/status_effect/bluespace_slowdown/on_remove() - owner.next_move_modifier /= 2 - -/datum/status_effect/shadow_boxing - id = "shadow barrage" - alert_type = null - duration = 10 SECONDS - tick_interval = 0.4 SECONDS - var/damage = 8 - var/source_UID - -/datum/status_effect/shadow_boxing/on_creation(mob/living/new_owner, mob/living/source) - . = ..() - source_UID = source.UID() - -/datum/status_effect/shadow_boxing/tick() - var/mob/living/attacker = locateUID(source_UID) - if(attacker in view(owner, 2)) - attacker.do_attack_animation(owner, ATTACK_EFFECT_PUNCH) - owner.apply_damage(damage, BRUTE) - shadow_to_animation(get_turf(attacker), get_turf(owner), attacker) - -/datum/status_effect/cling_tentacle - id = "cling_tentacle" - alert_type = null - duration = 3 SECONDS - -/datum/status_effect/cling_tentacle/on_apply() - ADD_TRAIT(owner, TRAIT_IMMOBILIZED, "[id]") - return ..() - -/datum/status_effect/cling_tentacle/on_remove() - REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, "[id]") - -// start of `living` level status procs. - -/** - * # Confusion - * - * Prevents moving straight, sometimes changing movement direction at random. - * Decays at a rate of 1 per second. - */ -/datum/status_effect/transient/confusion - id = "confusion" - var/image/overlay - -/datum/status_effect/transient/confusion/tick() - . = ..() - if(!.) - return - if(!owner.stat) //add or remove the overlay if they are alive or unconscious/dead - add_overlay() - else if(overlay) - owner.cut_overlay(overlay) - overlay = null - -/datum/status_effect/transient/confusion/proc/add_overlay() - if(overlay) - return - var/matrix/M = matrix() - M.Scale(0.6) - overlay = image('icons/effects/effects.dmi', "confusion", pixel_y = 20) - overlay.transform = M - owner.add_overlay(overlay) - -/datum/status_effect/transient/confusion/on_remove() - owner.cut_overlay(overlay) - overlay = null - return ..() - -/** - * # Dizziness - * - * Slightly offsets the client's screen randomly every tick. - * Decays at a rate of 1 per second, or 5 when resting. - */ -/datum/status_effect/transient/dizziness - id = "dizziness" - var/px_diff = 0 - var/py_diff = 0 - -/datum/status_effect/transient/dizziness/on_remove() - if(owner.client) - // smoothly back to normal - animate(owner.client, 0.2 SECONDS, pixel_x = -px_diff, pixel_y = -py_diff, flags = ANIMATION_PARALLEL) - return ..() - -/datum/status_effect/transient/dizziness/tick() - . = ..() - if(!.) - return - var/dir = sin(world.time) - var/amplitude = min(strength * 0.003, 32) - px_diff = cos(world.time * 3) * amplitude * dir - py_diff = sin(world.time * 3) * amplitude * dir - owner.client?.pixel_x = px_diff - owner.client?.pixel_y = py_diff - -/datum/status_effect/transient/dizziness/calc_decay() - return (-0.2 + (IS_HORIZONTAL(owner) ? -0.8 : 0)) SECONDS - -/** - * # Drowsiness - * - * Slows down and causes eye blur, with a 5% chance of falling asleep for a short time. - * Decays at a rate of 1 per second, or 5 when resting. - */ -/datum/status_effect/transient/drowsiness - id = "drowsiness" - -/datum/status_effect/transient/drowsiness/tick() - . = ..() - if(!.) - return - owner.EyeBlurry(4 SECONDS) - if(prob(0.5)) - owner.AdjustSleeping(2 SECONDS) - owner.Paralyse(10 SECONDS) - -/datum/status_effect/transient/drowsiness/calc_decay() - return (-0.2 + (IS_HORIZONTAL(owner) ? -0.8 : 0)) SECONDS - -/datum/status_effect/pepper_spray - id = "pepperspray" - duration = 10 SECONDS - status_type = STATUS_EFFECT_REFRESH - tick_interval = -1 - alert_type = null - -/datum/status_effect/pepper_spray/on_apply() - . = ..() - to_chat(owner, "Your throat burns!") - owner.AdjustConfused(12 SECONDS, bound_upper = 20 SECONDS) - owner.Slowed(4 SECONDS) - owner.apply_damage(40, STAMINA) - -/datum/status_effect/pepper_spray/refresh() - . = ..() - owner.AdjustConfused(12 SECONDS, bound_upper = 20 SECONDS) - owner.Slowed(4 SECONDS) - owner.apply_damage(20, STAMINA) - -/** - * # Drukenness - * - * Causes a myriad of status effects and other afflictions the stronger it is. - * Decays at a rate of 1 per second if no alcohol remains inside. - */ -/datum/status_effect/transient/drunkenness - id = "drunkenness" - var/alert_thrown = FALSE - -// the number of seconds of the status effect required for each effect to kick in. -#define THRESHOLD_SLUR 60 SECONDS -#define THRESHOLD_BRAWLING 60 SECONDS -#define THRESHOLD_CONFUSION 80 SECONDS -#define THRESHOLD_SPARK 100 SECONDS -#define THRESHOLD_VOMIT 120 SECONDS -#define THRESHOLD_BLUR 150 SECONDS -#define THRESHOLD_COLLAPSE 150 SECONDS -#define THRESHOLD_FAINT 180 SECONDS -#define THRESHOLD_BRAIN_DAMAGE 240 SECONDS -#define DRUNK_BRAWLING /datum/martial_art/drunk_brawling - -/datum/status_effect/transient/drunkenness/on_remove() - if(alert_thrown) - alert_thrown = FALSE - owner.clear_alert("drunk") - owner.sound_environment_override = SOUND_ENVIRONMENT_NONE - if(owner.mind && istype(owner.mind.martial_art, DRUNK_BRAWLING)) - owner.mind.martial_art.remove(owner) - return ..() - -/datum/status_effect/transient/drunkenness/tick() - . = ..() - if(!.) - return - - // Adjust actual drunkenness based on trait and organ presence - var/alcohol_resistance = 1 - var/actual_strength = strength - var/datum/mind/M = owner.mind - var/is_robot = ismachineperson(owner) || issilicon(owner) - - if(HAS_TRAIT(owner, TRAIT_ALCOHOL_TOLERANCE)) - alcohol_resistance = 2 - - actual_strength /= alcohol_resistance - - var/obj/item/organ/internal/liver/L - if(!is_robot) - L = owner.get_int_organ(/obj/item/organ/internal/liver) - var/liver_multiplier = 5 // no liver? get shitfaced - if(L) - liver_multiplier = L.alcohol_intensity - actual_strength *= liver_multiplier - - // THRESHOLD_SLUR (60 SECONDS) - if(actual_strength >= THRESHOLD_SLUR) - owner.Slur(actual_strength) - if(!alert_thrown) - alert_thrown = TRUE - owner.throw_alert("drunk", /atom/movable/screen/alert/drunk) - owner.sound_environment_override = SOUND_ENVIRONMENT_PSYCHOTIC - // THRESHOLD_BRAWLING (60 SECONDS) - if(M) - if(actual_strength >= THRESHOLD_BRAWLING) - if(!istype(M.martial_art, DRUNK_BRAWLING)) - var/datum/martial_art/drunk_brawling/MA = new - MA.teach(owner, TRUE) - else if(istype(M.martial_art, DRUNK_BRAWLING)) - M.martial_art.remove(owner) - // THRESHOLD_CONFUSION (80 SECONDS) - if(actual_strength >= THRESHOLD_CONFUSION && prob(0.33)) - owner.AdjustConfused(6 SECONDS / alcohol_resistance, bound_lower = 2 SECONDS, bound_upper = 1 MINUTES) - // THRESHOLD_SPARK (100 SECONDS) - if(is_robot && actual_strength >= THRESHOLD_SPARK && prob(0.25)) - do_sparks(3, 1, owner) - // THRESHOLD_VOMIT (120 SECONDS) - if(!is_robot && actual_strength >= THRESHOLD_VOMIT && prob(0.08)) - owner.fakevomit() - // THRESHOLD_BLUR (150 SECONDS) - if(actual_strength >= THRESHOLD_BLUR) - owner.EyeBlurry(20 SECONDS / alcohol_resistance) - // THRESHOLD_COLLAPSE (150 SECONDS) - if(actual_strength >= THRESHOLD_COLLAPSE && prob(0.1)) - owner.emote("collapse") - do_sparks(3, 1, src) - // THRESHOLD_FAINT (180 SECONDS) - if(actual_strength >= THRESHOLD_FAINT && prob(0.1)) - owner.Paralyse(10 SECONDS / alcohol_resistance) - owner.Drowsy(60 SECONDS / alcohol_resistance) - if(L) - L.receive_damage(1, TRUE) - if(!is_robot) - owner.adjustToxLoss(1) - // THRESHOLD_BRAIN_DAMAGE (240 SECONDS) - if(actual_strength >= THRESHOLD_BRAIN_DAMAGE && prob(0.1)) - owner.adjustBrainLoss(1) - -#undef THRESHOLD_SLUR -#undef THRESHOLD_BRAWLING -#undef THRESHOLD_CONFUSION -#undef THRESHOLD_SPARK -#undef THRESHOLD_VOMIT -#undef THRESHOLD_BLUR -#undef THRESHOLD_COLLAPSE -#undef THRESHOLD_FAINT -#undef THRESHOLD_BRAIN_DAMAGE -#undef DRUNK_BRAWLING - -/datum/status_effect/transient/drunkenness/calc_decay() - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - if(H.has_booze()) - return 0 - return -0.2 SECONDS - -/datum/status_effect/transient/cult_slurring - id = "cult_slurring" - -/datum/status_effect/incapacitating - id = "incapacitating" - tick_interval = 0 - status_type = STATUS_EFFECT_REPLACE - alert_type = null - var/needs_update_stat = FALSE - -/datum/status_effect/incapacitating/on_creation(mob/living/new_owner, set_duration) - if(isnum(set_duration)) - if(ishuman(new_owner)) - var/mob/living/carbon/human/H = new_owner - set_duration = H.dna.species.spec_stun(H, set_duration) - duration = set_duration - if(!duration) - return FALSE - . = ..() - if(. && (needs_update_stat || issilicon(owner))) - owner.update_stat() - - -/datum/status_effect/incapacitating/on_remove() - if(needs_update_stat || issilicon(owner)) //silicons need stat updates - owner.update_stat() - return ..() - -//FLOORED - forces the victim prone. -/datum/status_effect/incapacitating/floored - id = "floored" - -/datum/status_effect/incapacitating/floored/on_apply() - . = ..() - if(!.) - return - ADD_TRAIT(owner, TRAIT_FLOORED, "[id]") - -/datum/status_effect/incapacitating/floored/on_remove() - REMOVE_TRAIT(owner, TRAIT_FLOORED, "[id]") - return ..() - - -//STUN - prevents movement and actions, victim stays standing -/datum/status_effect/incapacitating/stun - id = "stun" - -/datum/status_effect/incapacitating/stun/on_apply() - . = ..() - if(!.) - return - ADD_TRAIT(owner, TRAIT_IMMOBILIZED, "[id]") - ADD_TRAIT(owner, TRAIT_HANDS_BLOCKED, "[id]") - -/datum/status_effect/incapacitating/stun/on_remove() - REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, "[id]") - REMOVE_TRAIT(owner, TRAIT_HANDS_BLOCKED, "[id]") - return ..() - -//IMMOBILIZED - prevents movement, victim can still stand and act -/datum/status_effect/incapacitating/immobilized - id = "immobilized" - -/datum/status_effect/incapacitating/immobilized/on_apply() - . = ..() - if(!.) - return - ADD_TRAIT(owner, TRAIT_IMMOBILIZED, "[id]") - -/datum/status_effect/incapacitating/immobilized/on_remove() - REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, "[id]") - return ..() - -//WEAKENED - prevents movement and action, victim falls over -/datum/status_effect/incapacitating/weakened - id = "weakened" - -/datum/status_effect/incapacitating/weakened/on_apply() - . = ..() - if(!.) - return - ADD_TRAIT(owner, TRAIT_IMMOBILIZED, "[id]") - ADD_TRAIT(owner, TRAIT_FLOORED, "[id]") - ADD_TRAIT(owner, TRAIT_HANDS_BLOCKED, "[id]") - -/datum/status_effect/incapacitating/weakened/on_remove() - REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, "[id]") - REMOVE_TRAIT(owner, TRAIT_FLOORED, "[id]") - REMOVE_TRAIT(owner, TRAIT_HANDS_BLOCKED, "[id]") - return ..() - -//PARALYZED - prevents movement and action, victim falls over, victim cannot hear or see. -/datum/status_effect/incapacitating/paralyzed - id = "paralyzed" - needs_update_stat = TRUE - -/datum/status_effect/incapacitating/paralyzed/on_apply() - . = ..() - if(!.) - return - ADD_TRAIT(owner, TRAIT_KNOCKEDOUT, "[id]") - -/datum/status_effect/incapacitating/paralyzed/on_remove() - REMOVE_TRAIT(owner, TRAIT_KNOCKEDOUT, "[id]") - return ..() - -//SLEEPING - victim falls over, cannot act, cannot see or hear, heals under certain conditions. -/datum/status_effect/incapacitating/sleeping - id = "sleeping" - tick_interval = 2 SECONDS - needs_update_stat = TRUE - /// Whether we decided to take a nap on our own. - /// As opposed to being hard knocked out with N2O or similar. - var/voluntary = FALSE - -/datum/status_effect/incapacitating/sleeping/on_creation(mob/living/new_owner, set_duration, voluntary = FALSE) - ..() - src.voluntary = voluntary - -/datum/status_effect/incapacitating/sleeping/on_apply() - . = ..() - if(!.) - return - ADD_TRAIT(owner, TRAIT_KNOCKEDOUT, "[id]") - -/datum/status_effect/incapacitating/sleeping/on_remove() - REMOVE_TRAIT(owner, TRAIT_KNOCKEDOUT, "[id]") - return ..() - -/datum/status_effect/incapacitating/sleeping/tick() - if(!iscarbon(owner)) - return - - var/mob/living/carbon/dreamer = owner - - if(dreamer.mind?.has_antag_datum(/datum/antagonist/vampire)) - var/mob/living/carbon/human/V = owner - if(istype(V.loc, /obj/structure/closet/coffin)) - V.adjustBruteLoss(-1) - V.adjustFireLoss(-1) - V.adjustToxLoss(-1) - V.adjustOxyLoss(-1) - V.adjustCloneLoss(-0.5) - if(V.HasDisease(/datum/disease/critical/heart_failure) && prob(25)) - for(var/datum/disease/critical/heart_failure/HF in V.viruses) - HF.cure() - dreamer.handle_dreams() - dreamer.adjustStaminaLoss(-10) - var/comfort = 1 - if(istype(dreamer.buckled, /obj/structure/bed)) - var/obj/structure/bed/bed = dreamer.buckled - comfort += bed.comfort - for(var/obj/item/bedsheet/bedsheet in range(dreamer.loc,0)) - if(bedsheet.loc != dreamer.loc) //bedsheets in your backpack/neck don't give you comfort - continue - comfort += bedsheet.comfort - break //Only count the first bedsheet - if(dreamer.get_drunkenness() > 0) - comfort += 1 //Aren't naps SO much better when drunk? - dreamer.AdjustDrunk(-0.4 SECONDS * comfort) //reduce drunkenness while sleeping. - if(comfort > 1 && prob(3))//You don't heal if you're just sleeping on the floor without a blanket. - dreamer.adjustBruteLoss(-1 * comfort, FALSE) - dreamer.adjustFireLoss(-1 * comfort) - if(prob(10) && dreamer.health && dreamer.health_hud_override != HEALTH_HUD_OVERRIDE_CRIT) - dreamer.emote("snore") - - -//SLOWED - slows down the victim for a duration and a given slowdown value. -/datum/status_effect/incapacitating/slowed - id = "slowed" - var/slowdown_value = 10 // defaults to this value if none is specified - -/datum/status_effect/incapacitating/slowed/on_creation(mob/living/new_owner, set_duration, _slowdown_value) - . = ..() - if(isnum(_slowdown_value)) - slowdown_value = _slowdown_value - -// Directional slow - Like slowed, but only if you're moving in a certain direction. -/datum/status_effect/incapacitating/directional_slow - id = "directional_slow" - var/direction - var/slowdown_value = 10 // defaults to this value if none is specified - -/datum/status_effect/incapacitating/directional_slow/on_creation(mob/living/new_owner, set_duration, _direction, _slowdown_value) - . = ..() - direction = _direction - if(isnum(_slowdown_value)) - slowdown_value = _slowdown_value - -/datum/status_effect/transient/silence - id = "silenced" - -/datum/status_effect/transient/silence/on_apply() - . = ..() - ADD_TRAIT(owner, TRAIT_MUTE, id) - -/datum/status_effect/transient/silence/on_remove() - . = ..() - REMOVE_TRAIT(owner, TRAIT_MUTE, id) - -/// this one will mute all emote sounds including gasps -/datum/status_effect/transient/silence/absolute - id = "abssilenced" - -/datum/status_effect/transient/deaf - id = "deafened" - -/datum/status_effect/transient/deaf/on_apply() - . = ..() - ADD_TRAIT(owner, TRAIT_DEAF, EAR_DAMAGE) - -/datum/status_effect/transient/deaf/on_remove() - . = ..() - REMOVE_TRAIT(owner, TRAIT_DEAF, EAR_DAMAGE) - -/datum/status_effect/transient/no_oxy_heal - id = "no_oxy_heal" - -/datum/status_effect/transient/jittery - id = "jittering" - -/datum/status_effect/transient/jittery/on_apply() - . = ..() - owner.do_jitter_animation(strength / 20, 1) - -/datum/status_effect/transient/jittery/tick() - . = ..() - if(!.) - return - owner.do_jitter_animation(strength / 20, 1) - -/datum/status_effect/transient/jittery/calc_decay() - return (-0.2 + (IS_HORIZONTAL(owner) ? -0.8 : 0)) SECONDS - -/datum/status_effect/transient/stammering - id = "stammer" - -/datum/status_effect/transient/slurring - id = "slurring" - -/datum/status_effect/transient/lose_breath - id = "lose_breath" - -#define HALLUCINATE_COOLDOWN_MIN 20 SECONDS -#define HALLUCINATE_COOLDOWN_MAX 50 SECONDS -/// This is multiplied with [/datum/status_effect/transient/var/strength] to determine the final cooldown. A higher hallucination value means shorter cooldown. -#define HALLUCINATE_COOLDOWN_FACTOR 0.003 -/// Percentage defining the chance at which an hallucination may spawn past the cooldown. -#define HALLUCINATE_CHANCE 80 -// Severity weights, should sum up to 100! -#define HALLUCINATE_MINOR_WEIGHT 60 -#define HALLUCINATE_MODERATE_WEIGHT 30 -#define HALLUCINATE_MAJOR_WEIGHT 10 - -/datum/status_effect/transient/hallucination - id = "hallucination" - var/next_hallucination = 0 - -/datum/status_effect/transient/hallucination/tick() - . = ..() - if(!.) - return - - if(next_hallucination > world.time) - return - - next_hallucination = world.time + rand(HALLUCINATE_COOLDOWN_MIN, HALLUCINATE_COOLDOWN_MAX) / (strength * HALLUCINATE_COOLDOWN_FACTOR) - if(!prob(HALLUCINATE_CHANCE)) - return - - // Pick a severity - var/severity = HALLUCINATE_MINOR - switch(rand(100)) - if(0 to HALLUCINATE_MINOR_WEIGHT) - severity = HALLUCINATE_MINOR - if((HALLUCINATE_MINOR_WEIGHT + 1) to (HALLUCINATE_MINOR_WEIGHT + HALLUCINATE_MODERATE_WEIGHT)) - severity = HALLUCINATE_MODERATE - if((HALLUCINATE_MINOR_WEIGHT + HALLUCINATE_MODERATE_WEIGHT + 1) to 100) - severity = HALLUCINATE_MAJOR - - hallucinate(pickweight(GLOB.hallucinations[severity])) - - -/** - * Spawns an hallucination for the mob. - * - * Arguments: - * * H - The type path of the hallucination to spawn. - */ -/datum/status_effect/transient/hallucination/proc/hallucinate(hallucination_type) - ASSERT(ispath(hallucination_type)) - if(owner.ckey) - add_attack_logs(null, owner, "Received hallucination [hallucination_type]", ATKLOG_ALL) - return new hallucination_type(get_turf(owner), owner) - -#undef HALLUCINATE_COOLDOWN_MIN -#undef HALLUCINATE_COOLDOWN_MAX -#undef HALLUCINATE_COOLDOWN_FACTOR -#undef HALLUCINATE_CHANCE -#undef HALLUCINATE_MINOR_WEIGHT -#undef HALLUCINATE_MODERATE_WEIGHT -#undef HALLUCINATE_MAJOR_WEIGHT - -/datum/status_effect/transient/eye_blurry - id = "eye_blurry" - -/datum/status_effect/transient/eye_blurry/on_apply() - owner.update_blurry_effects() - . = ..() - -/datum/status_effect/transient/eye_blurry/on_remove() - owner.update_blurry_effects() - -/datum/status_effect/transient/eye_blurry/calc_decay() - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - - if(isnull(H.dna.species.vision_organ)) //species has no eyes - return ..() - - var/obj/item/organ/vision = H.get_int_organ(H.dna.species.vision_organ) - - if(!vision || vision.is_bruised() || vision.is_broken()) // doesn't decay if you have damaged eyesight. - return 0 - - if(istype(H.glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) // decays faster if you rest your eyes with a blindfold. - return -1 SECONDS - return ..() //default decay rate - - -/datum/status_effect/transient/blindness - id = "blindness" - -/datum/status_effect/transient/blindness/on_apply() - . = ..() - owner.update_blind_effects() - -/datum/status_effect/transient/blindness/on_remove() - owner.update_blind_effects() - -/datum/status_effect/transient/blindness/calc_decay() - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - if(HAS_TRAIT(owner, TRAIT_BLIND)) - return 0 - - if(isnull(H.dna.species.vision_organ)) // species that have no eyes - return ..() - - var/obj/item/organ/vision = H.get_int_organ(H.dna.species.vision_organ) - - if(!vision || vision.is_broken() || vision.is_bruised()) //got no eyes or broken eyes - return 0 - - return ..() //default decay rate - -/datum/status_effect/transient/drugged - id = "drugged" - -/datum/status_effect/transient/drugged/on_apply() - . = ..() - owner.update_druggy_effects() - -/datum/status_effect/transient/drugged/on_remove() - owner.update_druggy_effects() - -#define FAKE_COLD 1 -#define FAKE_FOOD_POISONING 2 -#define FAKE_RETRO_VIRUS 3 -#define FAKE_TURBERCULOSIS 4 -#define FAKE_BRAINROT 5 - -/datum/status_effect/fake_virus - id = "fake_virus" - duration = 3 MINUTES - status_type = STATUS_EFFECT_REPLACE - tick_interval = 2 - alert_type = null - /// So you dont get the most intense messages immediately - var/msg_stage = 0 - /// Which disease we are going to fake? - var/current_fake_disease - /// Fake virus messages by with three stages - var/list/fake_msg - /// Fake virus emotes with three stages - var/list/fake_emote - -/datum/status_effect/fake_virus/on_creation() - current_fake_disease = pick(FAKE_COLD, FAKE_FOOD_POISONING, FAKE_RETRO_VIRUS, FAKE_TURBERCULOSIS, FAKE_BRAINROT) - switch(current_fake_disease) - if(FAKE_COLD) - fake_msg = list( - list("Your throat feels sore.", "Mucous runs down the back of your throat."), - list("Your muscles ache.", "Your stomach hurts."), - list("Your muscles ache.", "Your stomach hurts.") - ) - fake_emote = list( - list("sneeze", "cough"), - list("sneeze", "cough"), - list("sneeze", "cough") - ) - if(FAKE_FOOD_POISONING) - fake_msg = list( - list("Your stomach feels weird.", "You feel queasy."), - list("Your stomach aches.", "You feel nauseous."), - list("Your stomach hurts.", "You feel sick.") - ) - fake_emote = list( - list(), - list("groan"), - list("groan", "moan") - ) - if(FAKE_RETRO_VIRUS) - fake_msg = list( - list("Your head hurts.", "You feel a tingling sensation in your chest.", "You feel angry."), - list("Your skin feels loose.", "You feel very strange.", "You feel a stabbing pain in your head!", "Your stomach churns."), - list("Your entire body vibrates.") - ) - fake_emote = list( - list(), - list(), - list() - ) - if(FAKE_TURBERCULOSIS) - fake_msg = list( - list("Your chest hurts.", "Your stomach violently rumbles!", "You feel a cold sweat form."), - list("You feel a sharp pain from your lower chest!", "You feel air escape from your lungs painfully."), - list("You feel uncomfortably hot...", "You feel like unzipping your jumpsuit", "You feel like taking off some clothes...") - ) - fake_emote = list( - list("cough"), - list("gasp"), - list() - ) - else // FAKE_BRAINROT - fake_msg = list( - list("You don't feel like yourself."), - list("Your try to remember something important...but can't."), - list("Strange buzzing fills your head, removing all thoughts.") - ) - fake_emote = list( - list("blink", "yawn"), - list("stare", "drool"), - list("stare", "drool") - ) - . = ..() - -/datum/status_effect/fake_virus/tick() - var/selected_fake_msg - var/selected_fake_emote - switch(msg_stage) - if(0 to 300) - if(prob(1)) // First stage starts slow, stage 2 and 3 trigger fake msgs/emotes twice as often - if(prob(50) || !length(fake_emote[1])) // 50% chance to trigger either a msg or emote, 100% if it doesnt have an emote - selected_fake_msg = safepick(fake_msg[1]) - else - selected_fake_emote = safepick(fake_emote[1]) - if(301 to 600) - if(prob(2)) - if(prob(50) || !length(fake_emote[2])) - selected_fake_msg = safepick(fake_msg[2]) - else - selected_fake_emote = safepick(fake_emote[2]) - else - if(prob(2)) - if(prob(50) || !length(fake_emote[3])) - selected_fake_msg = safepick(fake_msg[3]) - else - selected_fake_emote = safepick(fake_emote[3]) - - if(selected_fake_msg) - to_chat(owner, selected_fake_msg) - else if(selected_fake_emote) - owner.emote(selected_fake_emote) - msg_stage++ - -#undef FAKE_COLD -#undef FAKE_FOOD_POISONING -#undef FAKE_RETRO_VIRUS -#undef FAKE_TURBERCULOSIS -#undef FAKE_BRAINROT - -/datum/status_effect/cryo_beam - id = "cryo beam" - alert_type = null - duration = -1 //Kill it, get out of sight, or be killed. Jump boots are *required* - tick_interval = 0.5 SECONDS - var/damage = 0.75 - var/source_UID - -/datum/status_effect/cryo_beam/on_creation(mob/living/new_owner, mob/living/source) - . = ..() - source_UID = source.UID() - -/datum/status_effect/cryo_beam/tick() - var/mob/living/simple_animal/hostile/megafauna/ancient_robot/attacker = locateUID(source_UID) - if(!(owner in view(attacker, 8))) - qdel(src) - return - - owner.apply_damage(damage, BURN) - owner.bodytemperature = max(0, owner.bodytemperature - 20) - owner.Beam(attacker.beam, icon_state = "medbeam", time = 0.5 SECONDS) - for(var/datum/reagent/R in owner.reagents.reagent_list) - owner.reagents.remove_reagent(R.id, 0.75) - if(prob(10)) - to_chat(owner, "Your blood freezes in your veins, get away!") - -/datum/status_effect/bubblegum_curse - id = "bubblegum curse" - alert_type = /atom/movable/screen/alert/status_effect/bubblegum_curse - duration = -1 //Kill it. There is no other option. - tick_interval = 1 SECONDS - /// The damage the status effect does per tick. - var/damage = 0.75 - var/source_UID - /// Are we starting the process to check if the person has still gotten out of range of bubble / crossed zlvls. - var/coward_checking = FALSE - -/datum/status_effect/bubblegum_curse/on_creation(mob/living/new_owner, mob/living/source) - . = ..() - source_UID = source.UID() - owner.overlay_fullscreen("Bubblegum", /atom/movable/screen/fullscreen/stretch/fog, 1) - -/datum/status_effect/bubblegum_curse/tick() - var/mob/living/simple_animal/hostile/megafauna/bubblegum/attacker = locateUID(source_UID) - if(!attacker || attacker.loc == null) - qdel(src) - if(attacker.health <= attacker.maxHealth / 2) - owner.clear_fullscreen("Bubblegum") - owner.overlay_fullscreen("Bubblegum", /atom/movable/screen/fullscreen/stretch/fog, 2) - if(!coward_checking) - if(owner.z != attacker.z) - addtimer(CALLBACK(src, PROC_REF(onstation_coward_callback)), 12 SECONDS) - coward_checking = TRUE - else if(get_dist(attacker, owner) >= 25) - addtimer(CALLBACK(src, PROC_REF(runaway_coward_callback)), 12 SECONDS) - coward_checking = TRUE - - owner.apply_damage(damage, BRUTE) - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - H.bleed(0.33) - if(prob(5)) - to_chat(owner, "[pick("You feel your sins crawling on your back.", "You felt your sins weighing on your neck.", "You feel your blood pulsing inside you.", "YOU'LL NEVER ESCAPE ME", "YOU'LL DIE FOR INSULTING ME LIKE THIS")]") - -/datum/status_effect/bubblegum_curse/on_remove() - owner.clear_fullscreen("Bubblegum") - -/datum/status_effect/bubblegum_curse/proc/onstation_coward_callback() - coward_checking = FALSE - var/mob/living/simple_animal/hostile/megafauna/bubblegum/attacker = locateUID(source_UID) - if(owner.z != attacker.z) - to_chat(owner, "YOU CHALLENGE ME LIKE THIS... AND YOU RUN WITH YOUR FALSE MAGICS?") - else - return - SLEEP_CHECK_QDEL(2 SECONDS) - to_chat(owner, "REALLY?") - SLEEP_CHECK_QDEL(2 SECONDS) - to_chat(owner, "SUCH INSOLENCE!") - SLEEP_CHECK_QDEL(2 SECONDS) - to_chat(owner, "SO PATHETIC...") - SLEEP_CHECK_QDEL(2 SECONDS) - to_chat(owner, "...SO FOOLISH!") - get_over_here() - -/datum/status_effect/bubblegum_curse/proc/runaway_coward_callback() - coward_checking = FALSE - var/mob/living/simple_animal/hostile/megafauna/bubblegum/attacker = locateUID(source_UID) - if(get_dist(attacker, owner) >= 25) - to_chat(owner, "My my, you can run FAST.") - else - return - SLEEP_CHECK_QDEL(2 SECONDS) - to_chat(owner, "I thought you wanted a true fight?") - SLEEP_CHECK_QDEL(2 SECONDS) - to_chat(owner, "Perhaps I was mistaken.") - SLEEP_CHECK_QDEL(2 SECONDS) - to_chat(owner, "You are a coward who does not want a fight...") - SLEEP_CHECK_QDEL(2 SECONDS) - to_chat(owner, "...BUT I WANT YOU DEAD!") - get_over_here() - -/datum/status_effect/bubblegum_curse/proc/get_over_here() - var/mob/living/simple_animal/hostile/megafauna/bubblegum/attacker = locateUID(source_UID) - if(!attacker) - return //Let's not nullspace - if(attacker.loc == null) - return //Extra emergency safety. - var/turf/TA = get_turf(owner) - owner.Immobilize(3 SECONDS) - new /obj/effect/decal/cleanable/blood/bubblegum(TA) - new /obj/effect/temp_visual/bubblegum_hands/rightsmack(TA) - sleep(6) - var/turf/TB = get_turf(owner) - to_chat(owner, "[attacker] rends you!") - playsound(TB, attacker.attack_sound, 100, TRUE, -1) - owner.adjustBruteLoss(10) - new /obj/effect/decal/cleanable/blood/bubblegum(TB) - new /obj/effect/temp_visual/bubblegum_hands/leftsmack(TB) - sleep(6) - var/turf/TC = get_turf(owner) - to_chat(owner, "[attacker] rends you!") - playsound(TC, attacker.attack_sound, 100, TRUE, -1) - owner.adjustBruteLoss(10) - new /obj/effect/decal/cleanable/blood/bubblegum(TC) - new /obj/effect/temp_visual/bubblegum_hands/rightsmack(TC) - sleep(6) - var/turf/TD = get_turf(owner) - to_chat(owner, "[attacker] rends you!") - playsound(TD, attacker.attack_sound, 100, TRUE, -1) - owner.adjustBruteLoss(10) - new /obj/effect/temp_visual/bubblegum_hands/leftpaw(TD) - new /obj/effect/temp_visual/bubblegum_hands/leftthumb(TD) - sleep(8) - to_chat(owner, "[attacker] drags you through the blood!") - playsound(TD, 'sound/misc/enter_blood.ogg', 100, TRUE, -1) - var/turf/targetturf = get_step(attacker, attacker.dir) - owner.forceMove(targetturf) - playsound(targetturf, 'sound/misc/exit_blood.ogg', 100, TRUE, -1) - addtimer(CALLBACK(attacker, TYPE_PROC_REF(/mob/living/simple_animal/hostile/megafauna/bubblegum, FindTarget), list(owner), 1), 2) - -/atom/movable/screen/alert/status_effect/bubblegum_curse - name = "I SEE YOU" - desc = "YOUR SOUL WILL BE MINE FOR YOUR INSOLENCE." - icon_state = "bubblegumjumpscare" - -/atom/movable/screen/alert/status_effect/bubblegum_curse/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - -/atom/movable/screen/alert/status_effect/bubblegum_curse/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/atom/movable/screen/alert/status_effect/bubblegum_curse/process() - var/new_filter = isnull(get_filter("ray")) - ray_filter_helper(1, 40,"#ce3030", 6, 20) - if(new_filter) - animate(get_filter("ray"), offset = 10, time = 10 SECONDS, loop = -1) - animate(offset = 0, time = 10 SECONDS) - - -/datum/status_effect/abductor_cooldown - id = "abductor_cooldown" - alert_type = /atom/movable/screen/alert/status_effect/abductor_cooldown - duration = 10 SECONDS - -/atom/movable/screen/alert/status_effect/abductor_cooldown - name = "Teleportation cooldown" - desc = "Per article A-113, all experimentors must wait 10000 milliseconds between teleports in order to ensure no long term genetic or mental damage happens to experimentor or test subjects." - icon_state = "bluespace" - -#define DEFAULT_MAX_CURSE_COUNT 5 - -/// Status effect that gives the target miscellanous debuffs while throwing a status alert and causing them to smoke from the damage they're incurring. -/// Purposebuilt for cursed slot machines. -/datum/status_effect/cursed - id = "cursed" - alert_type = /atom/movable/screen/alert/status_effect/cursed - /// The max number of curses a target can incur with this status effect. - var/max_curse_count = DEFAULT_MAX_CURSE_COUNT - /// The amount of times we have been "applied" to the target. - var/curse_count = 0 - /// Raw probability we have to deal damage this tick. - var/damage_chance = 10 - /// Are we currently in the process of sending a monologue? - var/monologuing = FALSE - /// The hand we are branded to. - var/obj/item/organ/external/branded_hand = null - -/datum/status_effect/cursed/on_apply() - RegisterSignal(owner, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_changed)) - RegisterSignal(owner, COMSIG_MOB_DEATH, PROC_REF(on_death)) - RegisterSignal(owner, COMSIG_CURSED_SLOT_MACHINE_USE, PROC_REF(check_curses)) - RegisterSignal(owner, COMSIG_CURSED_SLOT_MACHINE_LOST, PROC_REF(update_curse_count)) - RegisterSignal(SSdcs, COMSIG_GLOB_CURSED_SLOT_MACHINE_WON, PROC_REF(clear_curses)) - return ..() - -/datum/status_effect/cursed/Destroy() - UnregisterSignal(SSdcs, COMSIG_GLOB_CURSED_SLOT_MACHINE_WON) - branded_hand = null - return ..() - -/// Checks the number of curses we have and returns information back to the slot machine. `max_curse_amount` is set by the slot machine itself. -/datum/status_effect/cursed/proc/check_curses(mob/user, max_curse_amount) - SIGNAL_HANDLER - if(curse_count >= max_curse_amount) - return SLOT_MACHINE_USE_CANCEL - - if(monologuing) - to_chat(owner, "Your arm is resisting your attempts to pull the lever!") // listening to kitschy monologues to postpone your powergaming is the true curse here. - return SLOT_MACHINE_USE_POSTPONE - -/// Handles the debuffs of this status effect and incrementing the number of curses we have. -/datum/status_effect/cursed/proc/update_curse_count() - SIGNAL_HANDLER - curse_count++ - - linked_alert?.update_appearance() // we may have not initialized it yet - - addtimer(CALLBACK(src, PROC_REF(handle_after_effects), 1 SECONDS)) // give it a second to let the failure sink in before we exact our toll - -/// Makes a nice lorey message about the curse level we're at. I think it's nice -/datum/status_effect/cursed/proc/handle_after_effects() - if(QDELETED(src)) - return - - monologuing = TRUE - var/list/messages = list() - switch(curse_count) - if(1) // basically your first is a "freebie" that will still require urgent medical attention and will leave you smoking forever but could be worse tbh - if(ishuman(owner)) - var/mob/living/carbon/human/human_owner = owner - playsound(human_owner, 'sound/weapons/sear.ogg', 50, TRUE) - var/obj/item/organ/external/affecting = human_owner.get_active_hand() - branded_hand = affecting - - messages += "Your hand burns, and you quickly let go of the lever! You feel a little sick as the nerves deaden in your hand..." - messages += "Some smoke appears to be coming out of your hand now, but it's not too bad..." - messages += "Fucking stupid machine." - - if(2) - messages += "The machine didn't burn you this time, it must be some arcane work of the brand recognizing a source..." - messages += "Blisters and boils start to appear over your skin. Each one hissing searing hot steam out of its own pocket..." - messages += "You understand that the machine tortures you with its simplistic allure. It can kill you at any moment, but it derives a sick satisfaction at forcing you to keep going." - messages += "If you could get away from here, you might be able to live with some medical supplies. Is it too late to stop now?" - messages += "As you shut your eyes to dwell on this conundrum, the brand surges in pain. You shudder to think what might happen if you go unconscious." - - if(3) - owner.emote("cough") - messages += "Your throat becomes to feel like it's slowly caking up with sand and dust. You eject the contents of the back of your throat onto your sleeve." - messages += "It is sand. Crimson red. You've never felt so thirsty in your life, yet you don't trust your own hand to carry the glass to your lips." - messages += "You get the sneaking feeling that if someone else were to win, that it might clear your curse too. Saving your life is a noble cause." - messages += "Of course, you might have to not speak on the nature of this machine, in case they scamper off to leave you to die." - messages += "Is it truly worth it to condemn someone to this fate to cure the manifestation of your own hedonistic urges? You'll have to decide quickly." - - if(4) - messages += "A migraine swells over your head as your thoughts become hazy. Your hand desperately inches closer towards the slot machine for one final pull..." - messages += "The ultimate test of mind over matter. You can jerk your own muscle back in order to prevent a terrible fate, but your life already is worth so little now." - messages += "This is what they want, is it not? To witness your failure against itself? The compulsion carries you forward as a sinking feeling of dread fills your stomach." - messages += "Paradoxically, where there is hopelessness, there is elation. Elation at the fact that there's still enough power in you for one more pull." - messages += "Your legs desperately wish to jolt away on the thought of running away from this wretched machination, but your own arm remains complacent in the thought of seeing spinning wheels." - messages += "The toll has already been exacted. There is no longer death on 'your' terms. Is your dignity worth more than your life?" - - if(5 to INFINITY) - if(max_curse_count != DEFAULT_MAX_CURSE_COUNT) // this probably will only happen through admin schenanigans letting people stack up infinite curses or something - to_chat(owner, "Do you still think you're in control?") - return - - to_chat(owner, "Why couldn't I get one more try?!") - owner.gib() - qdel(src) - return - for(var/message in messages) - to_chat(owner, message) - sleep(3 SECONDS) // yes yes a bit fast but it can be a lot of text and i want the whole thing to send before the cooldown on the slot machine might expire - monologuing = FALSE - -/// Cleans ourselves up and removes our curses. Meant to be done in a "positive" way, when the curse is broken. Directly use qdel otherwise. -/datum/status_effect/cursed/proc/clear_curses() - SIGNAL_HANDLER - - owner.visible_message( - "The smoke slowly clears from [owner.name]...", - "Your skin finally settles down and your throat no longer feels as dry... The brand disappearing confirms that the curse has been lifted.",) - qdel(src) - -/// If our owner's stat changes, rapidly surge the damage chance. -/datum/status_effect/cursed/proc/on_stat_changed() - SIGNAL_HANDLER - if(owner.stat == CONSCIOUS || owner.stat == DEAD) // reset on these two states - damage_chance = initial(damage_chance) - return - - to_chat(owner, "As your body crumbles, you feel the curse of the slot machine surge through your body!") - damage_chance += 75 //ruh roh raggy - -/// If our owner dies without getting gibbed, we gib them, because fuck you baltamore -/datum/status_effect/cursed/proc/on_death(mob/living/source, gibbed) - SIGNAL_HANDLER - if(!ishuman(owner)) - return - if(gibbed) - return - var/mob/living/carbon/human/H = owner - INVOKE_ASYNC(H, TYPE_PROC_REF(/mob, gib)) - -/datum/status_effect/cursed/tick() - if(curse_count <= 1) - return // you get one "freebie" (single damage) to nudge you into thinking this is a bad idea before the house begins to win. - - // the house won. - var/ticked_coefficient = rand(15, 40) * 2 / 100 - var/effective_percentile_chance = ((curse_count == 2 ? 1 : curse_count) * damage_chance * ticked_coefficient) - - if(prob(effective_percentile_chance)) - owner.apply_damages( - brute = (curse_count * ticked_coefficient), - burn = (curse_count * ticked_coefficient), - oxy = (curse_count * ticked_coefficient), - ) - -/atom/movable/screen/alert/status_effect/cursed - name = "Cursed!" - desc = "The brand on your hand reminds you of your greed, yet you seem to be okay otherwise." - icon_state = "cursed_by_slots" - -/atom/movable/screen/alert/status_effect/cursed/update_desc() - . = ..() - var/datum/status_effect/cursed/linked_effect = attached_effect - var/curses = linked_effect.curse_count - switch(curses) - if(2) - desc = "Your greed is catching up to you..." - if(3) - desc = "You really don't feel good right now... But why stop now?" - if(4 to INFINITY) - desc = "Real winners quit before they reach the ultimate prize." - -#undef DEFAULT_MAX_CURSE_COUNT - -/datum/status_effect/reversed_high_priestess - id = "reversed_high_priestess" - duration = 1 MINUTES - status_type = STATUS_EFFECT_REFRESH - tick_interval = 6 SECONDS - alert_type = /atom/movable/screen/alert/status_effect/bubblegum_curse - -/datum/status_effect/reversed_high_priestess/tick() - . = ..() - new /obj/effect/bubblegum_warning(get_turf(owner)) - -/obj/effect/bubblegum_warning - name = "bloody rift" - desc = "You feel like even being *near* this is a bad idea." - icon = 'icons/obj/biomass.dmi' - icon_state = "rift" - color = "red" - -/obj/effect/bubblegum_warning/Initialize(mapload) - . = ..() - addtimer(CALLBACK(src, PROC_REF(slap_someone)), 2.5 SECONDS) //A chance to run away - -/obj/effect/bubblegum_warning/proc/slap_someone() - new /obj/effect/abstract/bubblegum_rend_helper(get_turf(src), null, 10) - qdel(src) - -/// The mob has been pushed by airflow recently, and won't automatically grab nearby objects to stop drifting. -/datum/status_effect/unbalanced - id = "unbalanced" - duration = 1 SECONDS - status_type = STATUS_EFFECT_REFRESH - alert_type = /atom/movable/screen/alert/status_effect/unbalanced - -/atom/movable/screen/alert/status_effect/unbalanced - name = "Unbalanced" - desc = "You're being shoved around by airflow! You can resist this by moving, but moving against the wind will be slow." - icon_state = "unbalanced" - -/datum/status_effect/c_foamed - id = "c_foamed up" - duration = 1 MINUTES - status_type = STATUS_EFFECT_REFRESH - tick_interval = 10 SECONDS - var/foam_level = 1 - var/mutable_appearance/foam_overlay - -/datum/status_effect/c_foamed/on_apply() - . = ..() - foam_overlay = mutable_appearance('icons/obj/foam_blobs.dmi', "foamed_1") - owner.add_overlay(foam_overlay) - owner.next_move_modifier *= 1.5 - owner.Slowed(10 SECONDS, 1.5) - -/datum/status_effect/c_foamed/Destroy() - if(owner) - owner.cut_overlay(foam_overlay) - owner.next_move_modifier /= 1.5 - - QDEL_NULL(foam_overlay) - return ..() - -/datum/status_effect/c_foamed/tick() - . = ..() - if(--foam_level <= 0) - qdel(src) - refresh_overlay() - -/datum/status_effect/c_foamed/refresh() - . = ..() - // Our max slow is 50 seconds - foam_level = min(foam_level + 1, 5) - - refresh_overlay() - - if(foam_level == 5) - owner.Paralyse(4 SECONDS) - -/datum/status_effect/c_foamed/proc/refresh_overlay() - // Refresh overlay - owner.cut_overlay(foam_overlay) - QDEL_NULL(foam_overlay) - foam_overlay = mutable_appearance('icons/obj/foam_blobs.dmi', "foamed_[foam_level]") - owner.add_overlay(foam_overlay) - -/datum/status_effect/judo_armbar - id = "armbar" - duration = 5 SECONDS - alert_type = null - status_type = STATUS_EFFECT_REPLACE - -/datum/status_effect/rust_corruption - alert_type = null - id = "rust_turf_effects" - tick_interval = 2 SECONDS - -/datum/status_effect/rust_corruption/tick() - . = ..() - if(issilicon(owner)) - owner.adjustBruteLoss(10) - return - //We don't have disgust, so... - if(ishuman(owner)) - owner.adjustBrainLoss(2.5) - owner.reagents?.remove_all(0.75) - else - owner.adjustBruteLoss(3) //Weaker than borgs but still constant. - -/// This is the threshold where the attack will stun on the last hit. Why? Because it is cool, that's why. -#define FINISHER_THRESHOLD 7 - -/datum/status_effect/temporal_slash - id = "temporal_slash" - duration = 3 SECONDS - status_type = STATUS_EFFECT_REFRESH - alert_type = null - /// How many times the user has been cut. Each cut adds a damage value below - var/cuts = 1 - /// How much damage the blade will do each slice - var/damage_per_cut = 20 - -/datum/status_effect/temporal_slash/on_creation(mob/living/new_owner, cut_damage = 20) - . = ..() - damage_per_cut = cut_damage - -/datum/status_effect/temporal_slash/refresh() - cuts++ - return ..() - -/datum/status_effect/temporal_slash/on_remove() - owner.apply_status_effect(STATUS_EFFECT_TEMPORAL_SLASH_FINISHER, cuts, damage_per_cut) //We apply this to a new status effect, to avoid refreshing while on_remove happens. - -/datum/status_effect/temporal_slash_finisher - id = "temporal_slash_finisher" - status_type = STATUS_EFFECT_UNIQUE - alert_type = null - tick_interval = 0.25 SECONDS - /// How many times the user has been cut. Each cut adds a damage value below - var/cuts = 1 - /// How much damage the blade will do each slice - var/damage_per_cut = 20 - /// Have we done enough damage to trigger the finisher? - var/finishing_cuts = FALSE - -/datum/status_effect/temporal_slash_finisher/on_creation(mob/living/new_owner, final_cuts = 1, cut_damage = 20) - . = ..() - cuts = final_cuts - damage_per_cut = cut_damage - if(ismegafauna(owner)) - damage_per_cut *= 4 //This will deal 40 damage bonus per cut on megafauna as a miner, and 80 as a wizard. To kill a megafauna, you need to hit it 48 times. You don't get the buffs of a crusher though. Also you already killed bubblegum, so, you know. - if(cuts >= FINISHER_THRESHOLD) - finishing_cuts = TRUE - new /obj/effect/temp_visual/temporal_slash(get_turf(owner), owner) - -/datum/status_effect/temporal_slash_finisher/tick() - . = ..() - owner.visible_message("[owner] gets slashed by a cut through spacetime!", "You get slashed by a cut through spacetime!") - playsound(owner, 'sound/weapons/rapierhit.ogg', 50, TRUE) - owner.apply_damage(damage_per_cut, BRUTE, pick(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_ARM, BODY_ZONE_R_LEG), 0, TRUE, null, FALSE) - cuts-- - if(cuts <= 0) - if(finishing_cuts) - owner.Weaken(7 SECONDS) - qdel(src) - else - new /obj/effect/temp_visual/temporal_slash(get_turf(owner), owner) - -#undef FINISHER_THRESHOLD diff --git a/code/datums/status_effects/magic_disguise.dm b/code/datums/status_effects/magic_disguise.dm deleted file mode 100644 index 16f0fb6591169..0000000000000 --- a/code/datums/status_effects/magic_disguise.dm +++ /dev/null @@ -1,89 +0,0 @@ -/datum/status_effect/magic_disguise - id = "magic_disguise" - duration = -1 - tick_interval = -1 - alert_type = /atom/movable/screen/alert/status_effect/magic_disguise - status_type = STATUS_EFFECT_REPLACE - var/mob/living/disguise_mob - var/datum/icon_snapshot/disguise - -/atom/movable/screen/alert/status_effect/magic_disguise - name = "Disguised" - desc = "You are disguised as a crewmember." - icon = 'icons/mob/actions/actions.dmi' - icon_state = "chameleon_outfit" - -/datum/status_effect/magic_disguise/on_creation(mob/living/new_owner, mob/living/_disguise_mob) - disguise_mob = _disguise_mob - . = ..() - -/datum/status_effect/magic_disguise/on_apply() - . = ..() - if(!ishuman(owner)) - return FALSE - if(!disguise_mob) - disguise_mob = select_disguise() - if(ishuman(disguise_mob)) - create_disguise(disguise_mob) - if(disguise) - apply_disguise(owner) - else - to_chat(owner, "Your spell fails to find a disguise!") - return FALSE - - RegisterSignal(owner, list(COMSIG_MOB_APPLY_DAMAGE, COMSIG_HUMAN_ATTACKED, COMSIG_SPECIES_HITBY), PROC_REF(remove_disguise)) - return TRUE - -/datum/status_effect/magic_disguise/on_remove() - owner.regenerate_icons() - ..() - -/datum/status_effect/magic_disguise/proc/select_disguise() - var/obj/machinery/door/airlock/AL - var/area/caster_area - - caster_area = get_area(owner) - for(var/obj/machinery/door/airlock/tmp in view(owner)) - if(get_area(tmp) == caster_area && (length(tmp.req_access) || length(tmp.req_one_access))) //Ignore airlocks that arent in area or are public airlocks - AL = tmp - break - for(var/mob/living/carbon/human/disguise_source in shuffle(GLOB.player_list)) //Pick a random crewmember with access to this room - if((ACCESS_CAPTAIN in disguise_source.get_access()) || (ACCESS_HOP in disguise_source.get_access()) || (ACCESS_CLOWN in disguise_source.get_access())) - continue //We don't want the cap, HOP or clown as a disguise, too remarkable. If you're spotted by the Cap or HOP in their own office, disguising as them wont help you either - if((!AL || AL.allowed(disguise_source)) && !disguise_source.mind.offstation_role && disguise_source != owner) - return disguise_source - for(var/mob/living/carbon/human/backup_source in shuffle(GLOB.player_list)) //Pick a random crewmember if there's no one with access to the current room - if((ACCESS_CAPTAIN in backup_source.get_access()) || (ACCESS_HOP in backup_source.get_access()) || (ACCESS_CLOWN in backup_source.get_access())) - continue //ditto - if(!backup_source.mind.offstation_role && backup_source != owner) - return backup_source - return - -/datum/status_effect/magic_disguise/proc/create_disguise(mob/living/carbon/human/disguise_source) - var/datum/icon_snapshot/temp = new - temp.name = disguise_source.name - temp.icon = disguise_source.icon - temp.icon_state = disguise_source.icon_state - temp.overlays = disguise_source.get_overlays_copy(list(L_HAND_LAYER, R_HAND_LAYER)) - disguise = temp - -/datum/status_effect/magic_disguise/proc/apply_disguise(mob/living/carbon/human/H) - H.name_override = disguise.name - H.icon = disguise.icon - H.icon_state = disguise.icon_state - H.overlays = disguise.overlays - H.update_inv_r_hand() - H.update_inv_l_hand() - H.sec_hud_set_ID() - SEND_SIGNAL(H, COMSIG_CARBON_REGENERATE_ICONS) - to_chat(H, "You disguise yourself as [disguise.name].") - -/datum/status_effect/magic_disguise/proc/remove_disguise() - SIGNAL_HANDLER // COMSIG_MOB_APPLY_DAMAGE + COMSIG_HUMAN_ATTACKED + COMSIG_SPECIES_HITBY - if(!ishuman(owner)) - return - var/mob/living/carbon/human/H = owner - H.name_override = null - H.overlays.Cut() - H.sec_hud_set_ID() - qdel(src) diff --git a/code/datums/uplink_items/uplink_nuclear.dm b/code/datums/uplink_items/uplink_nuclear.dm deleted file mode 100644 index d4ee796582803..0000000000000 --- a/code/datums/uplink_items/uplink_nuclear.dm +++ /dev/null @@ -1,725 +0,0 @@ -// NUCLEAR AGENT ONLY GEAR - -//////////////////////////////////////// -// MARK: DANGEROUS WEAPONS -//////////////////////////////////////// - -/datum/uplink_item/dangerous/aps - name = "Stechkin APS Pistol" - reference = "APS" - desc = "The automatic machine pistol version of the FK-69 'Stechkin' chambered in 10mm Auto with a detachable 20-round box magazine. Perfect for dual wielding or as backup." - item = /obj/item/gun/projectile/automatic/pistol/aps - cost = 40 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/dangerous/smg - name = "C-20r Submachine Gun" - reference = "SMG" - desc = "A fully-loaded Scarborough Arms bullpup submachine gun that fires .45 rounds with a 20-round magazine and is compatible with suppressors." - item = /obj/item/gun/projectile/automatic/c20r - cost = 70 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - surplus = 40 - -/datum/uplink_item/dangerous/carbine - name = "M-90gl Carbine" - desc = "A fully-loaded three-round burst carbine that uses 30-round 5.56mm magazines with a togglable underslung 40mm grenade launcher." - reference = "AR" - item = /obj/item/gun/projectile/automatic/m90 - cost = 90 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - surplus = 50 - -/datum/uplink_item/dangerous/machinegun - name = "L6 Squad Automatic Weapon" - desc = "A fully-loaded Aussec Armory belt-fed machine gun. This deadly weapon has a massive 50-round magazine of devastating 7.62x51mm ammunition." - reference = "LMG" - item = /obj/item/gun/projectile/automatic/l6_saw - cost = 200 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - surplus = 0 - -/datum/uplink_item/dangerous/sniper - name = "Sniper Rifle" - desc = "Ranged fury, Syndicate style. guaranteed to cause shock and awe or your TC back!" - reference = "SSR" - item = /obj/item/gun/projectile/automatic/sniper_rifle/syndicate - cost = 80 - surplus = 25 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/dangerous/rocket_launcher - name = "Rocket Launcher" - desc = "Not many things can survive a direct hit from this. (Ammunition sold separately, keep away from children.)" - reference = "RL" - item = /obj/item/gun/rocketlauncher - cost = 40 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/dangerous/flamethrower - name = "Flamethrower" - desc = "A chemical flamethrower, fueled by a volatile mix of fuel and napalm. Comes prefilled with two canisters. Do not use with caution." - reference = "CHEM_THROWER" - item = /obj/item/chemical_flamethrower/extended/nuclear - cost = 40 // In contrary to the gas flamethrower, this one is a very strong area denial tool that can't be countered by an AI - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/dangerous/combat_defib - name = "Combat Defibrillator Module" - desc = "A lifesaving device turned dangerous weapon. Click on someone with the paddles on harm intent to instantly stop their heart. Can be used as a regular defib as well. Installs in a modsuit." - reference = "CD" - item = /obj/item/mod/module/defibrillator/combat - cost = 60 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/dangerous/foamsmg - name = "Toy Submachine Gun" - desc = "A fully-loaded Donksoft bullpup submachine gun that fires riot grade rounds with a 20-round magazine." - reference = "FSMG" - item = /obj/item/gun/projectile/automatic/c20r/toy - cost = 25 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - surplus = 0 - -/datum/uplink_item/dangerous/foammachinegun - name = "Toy Machine Gun" - desc = "A fully-loaded Donksoft belt-fed machine gun. This weapon has a massive 50-round magazine of devastating riot grade darts, that can briefly incapacitate someone in just one volley." - reference = "FLMG" - item = /obj/item/gun/projectile/automatic/l6_saw/toy - cost = 50 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - surplus = 0 - -/datum/uplink_item/dangerous/bulldog - name = "Bulldog Shotgun" - desc = "Lean and mean: Optimized for people that want to get up close and personal. Extra Ammo sold separately." - reference = "BULD" - item = /obj/item/gun/projectile/automatic/shotgun/bulldog - cost = 15 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -//////////////////////////////////////// -// MARK: SUPPORT AND MECHAS -//////////////////////////////////////// - -/datum/uplink_item/support - category = "Support and Mechanized Exosuits" - surplus = 0 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/support/gygax - name = "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." - reference = "GE" - item = /obj/mecha/combat/gygax/dark/loaded - cost = 350 - -/datum/uplink_item/support/mauler - name = "Mauler Exosuit" - desc = "A massive and incredibly deadly Syndicate exosuit. Features long-range targeting, thrust vectoring, and deployable smoke." - reference = "ME" - item = /obj/mecha/combat/marauder/mauler/loaded - cost = 599 // Today only 599 TC! Get yours today! - -/datum/uplink_item/support/reinforcement - name = "Reinforcement" - desc = "Call in an additional team member. They won't come with any gear, so you'll have to save some telecrystals \ - to arm them as well." - reference = "REINF" - item = /obj/item/antag_spawner/nuke_ops - refund_path = /obj/item/antag_spawner/nuke_ops - cost = 100 - refundable = TRUE - can_discount = FALSE - -/datum/uplink_item/support/reinforcement/assault_borg - name = "Syndicate Assault Cyborg" - desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel. \ - Comes equipped with a self-resupplying LMG, a grenade launcher, energy sword, emag, pinpointer, flash and crowbar." - reference = "SAC" - item = /obj/item/antag_spawner/nuke_ops/borg_tele/assault - refund_path = /obj/item/antag_spawner/nuke_ops/borg_tele/assault - cost = 250 - -/datum/uplink_item/support/reinforcement/medical_borg - name = "Syndicate Medical Cyborg" - desc = "A combat medical cyborg. Has limited offensive potential, but makes more than up for it with its support capabilities. \ - It comes equipped with a nanite hypospray, a medical beamgun, combat defibrillator, full surgical kit including an energy saw, an emag, pinpointer and flash. \ - Thanks to its organ storage bag, it can perform surgery as well as any humanoid." - reference = "SMC" - item = /obj/item/antag_spawner/nuke_ops/borg_tele/medical - refund_path = /obj/item/antag_spawner/nuke_ops/borg_tele/medical - cost = 175 - -/datum/uplink_item/support/reinforcement/saboteur_borg - name = "Syndicate Saboteur Cyborg" - desc = "A streamlined engineering cyborg, equipped with covert modules and engineering equipment. Also incapable of leaving the welder in the shuttle. \ - Its chameleon projector lets it disguise itself as a Nanotrasen cyborg, on top it has thermal vision and a pinpointer." - reference = "SSC" - item = /obj/item/antag_spawner/nuke_ops/borg_tele/saboteur - refund_path = /obj/item/antag_spawner/nuke_ops/borg_tele/saboteur - cost = 125 - -//////////////////////////////////////// -// MARK: AMMUNITION -//////////////////////////////////////// - -/datum/uplink_item/ammo/aps - name = "Stechkin APS - 10mm Magazine" - desc = "An additional 20-round 10mm magazine for use in the Stechkin APS machine pistol, loaded with rounds that are cheap but around half as effective as .357" - reference = "10MMAPS" - item = /obj/item/ammo_box/magazine/apsm10mm - cost = 10 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/apsap - name = "Stechkin APS - 10mm Armour Piercing Magazine" - desc = "An additional 20-round 10mm magazine for use in the Stechkin APS machine pistol, loaded with rounds that are less effective at injuring the target but penetrate protective gear." - reference = "10MMAPSAP" - item = /obj/item/ammo_box/magazine/apsm10mm/ap - cost = 15 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/apsfire - name = "Stechkin APS - 10mm Incendiary Magazine" - desc = "An additional 20-round 10mm magazine for use in the Stechkin APS machine pistol, loaded with incendiary rounds which ignite the target." - reference = "10MMAPSFIRE" - item = /obj/item/ammo_box/magazine/apsm10mm/fire - cost = 15 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/apshp - name = "Stechkin APS - 10mm Hollow Point Magazine" - desc = "An additional 20-round 10mm magazine for use in the Stechkin APS machine pistol, loaded with rounds which are more damaging but ineffective against armour." - reference = "10MMAPSHP" - item = /obj/item/ammo_box/magazine/apsm10mm/hp - cost = 20 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/bullslug - name = "Bulldog - 12g Slug Magazine" - desc = "An additional 8-round slug magazine for use in the Bulldog shotgun. Now 8 times less likely to shoot your pals." - reference = "12BSG" - item = /obj/item/ammo_box/magazine/m12g - cost = 10 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/bullbuck - name = "Bulldog - 12g Buckshot Magazine" - desc = "An additional 8-round buckshot magazine for use in the Bulldog shotgun. Front towards enemy." - reference = "12BS" - item = /obj/item/ammo_box/magazine/m12g/buckshot - cost = 10 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/bullmeteor - name = "12g Meteorslug Shells" - desc = "An alternative 8-round meteorslug magazine for use in the Bulldog shotgun. Great for blasting airlocks off their frames and knocking down enemies." - reference = "12MS" - item = /obj/item/ammo_box/magazine/m12g/meteor - cost = 10 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/bulldragon - name = "Bulldog - 12g Dragon's Breath Magazine" - desc = "An alternative 8-round dragon's breath magazine for use in the Bulldog shotgun. I'm a fire starter, twisted fire starter!" - reference = "12DB" - item = /obj/item/ammo_box/magazine/m12g/dragon - cost = 10 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/bulldog_ammobag - name = "Bulldog - 12g Ammo Duffel Bag" - desc = "A duffel bag filled with nine 8 round drum magazines. (6 Slug, 2 Buckshot, 1 Dragon's Breath)" - reference = "12ADB" - item = /obj/item/storage/backpack/duffel/syndie/shotgun - cost = 60 // normally 90 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/bulldog_xl_magsbag - name = "Bulldog - 12g Extra-Large Magazine Duffel Bag" - desc = "A duffel bag containing five XL 16 round drum magazines. (3 Slug, 1 Buckshot, 1 Dragon's Breath)." - reference = "12XLDB" - item = /obj/item/storage/backpack/duffel/syndie/shotgun_xl_mags - // same price for more ammo, but you're likely to lose more ammo if you drop your bulldog. High risk, high reward. - cost = 60 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/smg - name = "C-20r - .45 Magazine" - desc = "An additional 20-round .45 magazine for use in the C-20r submachine gun. These bullets pack a lot of punch that can knock most targets down, but do limited overall damage." - reference = "45" - item = /obj/item/ammo_box/magazine/smgm45 - cost = 15 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/smg_ammobag - name = "C-20r - .45 Ammo Duffel Bag" - desc = "A duffel bag filled with enough .45 ammo to supply an entire team, at a discounted price." - reference = "45ADB" - item = /obj/item/storage/backpack/duffel/syndie/smg - cost = 105 // Normally 150, so 30% off - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/carbine - name = "Carbine - 5.56 Toploader Magazine" - desc = "An additional 30-round 5.56 magazine for use in the M-90gl carbine. These bullets don't have the punch to knock most targets down, but dish out higher overall damage." - reference = "556" - item = /obj/item/ammo_box/magazine/m556 - cost = 10 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/a40mm - name = "Carbine - 40mm Grenade Ammo Box" - desc = "A box of 4 additional 40mm HE grenades for use the C-90gl's underbarrel grenade launcher. Your teammates will thank you to not shoot these down small hallways." - reference = "40MM" - item = /obj/item/ammo_box/a40mm - cost = 20 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/rocket - name = "Rocket Launcher Shell" - desc = "An extra shell for your RPG. Make sure your bestie isn't standing in front of you." - reference = "HE" - item = /obj/item/ammo_casing/rocket - cost = 30 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/chemical_canister - name = "Box of chemical flamethrower canisters" - desc = "A box filled with 2 canisters of flamethrower fuel, exactly enough to fully refill your flamethrower once!" - reference = "CHEM_CAN" - item = /obj/item/storage/box/syndie_kit/chemical_canister - cost = 30 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/machinegun - name = "L6 SAW - 5.56x45mm Box Magazine" - desc = "A 50-round magazine of 5.56x45mm ammunition for use in the L6 SAW machine gun. By the time you need to use this, you'll already be on a pile of corpses." - reference = "762" - item = /obj/item/ammo_box/magazine/mm556x45 - cost = 60 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - surplus = 0 - -/datum/uplink_item/ammo/sniper - cost = 15 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/sniper/basic - name = "Sniper - .50 Magazine" - desc = "An additional standard 6-round magazine for use with .50 sniper rifles." - reference = "50M" - item = /obj/item/ammo_box/magazine/sniper_rounds - -/datum/uplink_item/ammo/sniper/antimatter - name = "Sniper - .50 Antimatter Magazine" - desc = "A 6-round magazine of antimatter ammo for use with .50 sniper rifles. \ - Able to heavily damage objects, and delimb people. Requires zooming in for accurate aiming." - reference = "50A" - item = /obj/item/ammo_box/magazine/sniper_rounds/antimatter - cost = 30 - -/datum/uplink_item/ammo/sniper/soporific - name = "Sniper - .50 Soporific Magazine" - desc = "A 3-round magazine of soporific ammo designed for use with .50 sniper rifles. Put your enemies to sleep today!" - reference = "50S" - item = /obj/item/ammo_box/magazine/sniper_rounds/soporific - -/datum/uplink_item/ammo/sniper/haemorrhage - name = "Sniper - .50 Haemorrhage Magazine" - desc = "A 5-round magazine of haemorrhage ammo designed for use with .50 sniper rifles; causes heavy bleeding \ - in the target." - reference = "50B" - item = /obj/item/ammo_box/magazine/sniper_rounds/haemorrhage - -/datum/uplink_item/ammo/sniper/penetrator - name = "Sniper - .50 Penetrator Magazine" - desc = "A 5-round magazine of penetrator ammo designed for use with .50 sniper rifles. \ - Can pierce walls and multiple enemies." - reference = "50P" - item = /obj/item/ammo_box/magazine/sniper_rounds/penetrator - cost = 20 - -/datum/uplink_item/ammo/bioterror - name = "Box of Bioterror Syringes" - desc = "A box full of preloaded syringes, containing various chemicals that seize up the victim's motor and broca system , making it impossible for them to move or speak while in their system." - reference = "BTS" - item = /obj/item/storage/box/syndie_kit/bioterror - cost = 25 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/ammo/toydarts - name = "Box of Riot Darts" - desc = "A box of 40 Donksoft foam riot darts, for reloading any compatible foam dart gun. Don't forget to share!" - reference = "FOAM" - item = /obj/item/ammo_box/foambox/riot - cost = 10 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - surplus = 0 - -//////////////////////////////////////// -// MARK: EXPLOSIVES -//////////////////////////////////////// - -/datum/uplink_item/explosives/c4bag - name = "Bag of C-4 explosives" - desc = "Because sometimes quantity is quality. Contains 10 C-4 plastic explosives." - reference = "C4B" - item = /obj/item/storage/backpack/duffel/syndie/c4 - cost = 40 //20% discount! - can_discount = FALSE - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/explosives/breaching_charge - name = "Composition X-4" - desc = "X-4 is a shaped charge designed to be safe to the user while causing maximum damage to the occupants of the room beach breached. It has a modifiable timer with a minimum setting of 10 seconds." - reference = "X4" - item = /obj/item/grenade/plastic/c4/x4 - cost = 10 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/explosives/x4bag - name = "Bag of X-4 explosives" - desc = "Contains 3 X-4 shaped plastic explosives. Similar to C4, but with a stronger blast that is directional instead of circular. \ - X-4 can be placed on a solid surface, such as a wall or window, and it will blast through the wall, injuring anything on the opposite side, while being safer to the user. \ - For when you want a controlled explosion that leaves a wider, deeper, hole." - reference = "X4B" - item = /obj/item/storage/backpack/duffel/syndie/x4 - cost = 20 - can_discount = FALSE - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/explosives/grenadier - name = "Grenadier's belt" - desc = "A belt containing 26 lethally dangerous and destructive grenades." - reference = "GRB" - item = /obj/item/storage/belt/grenade/full - cost = 120 - surplus = 0 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/explosives/manhacks - name = "Viscerator Delivery Grenade" - desc = "A unique grenade that deploys a swarm of viscerators upon activation, which will chase down and shred any non-operatives in the area." - reference = "VDG" - item = /obj/item/grenade/spawnergrenade/manhacks - cost = 10 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - surplus = 35 - -//////////////////////////////////////// -// MARK: STEALTHY WEAPONS -//////////////////////////////////////// - -// There's no nukie only stealthy weapons right now, but if you want to add one, put it here. - -//////////////////////////////////////// -// MARK: STEALTHY TOOLS -//////////////////////////////////////// - -/datum/uplink_item/stealthy_tools/clownkit - name = "Honk Brand Infiltration Kit" - desc = "All the tools you need to play the best prank Nanotrasen has ever seen. Includes a voice changer mask, magnetic clown shoes, and standard clown outfit, tools, and backpack." - reference = "HBIK" - item = /obj/item/storage/backpack/clown/syndie - cost = 30 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - surplus = 0 - -//////////////////////////////////////// -// MARK: DEVICES AND TOOLS -//////////////////////////////////////// - -/datum/uplink_item/device_tools/diamond_drill - name = "Amplifying Diamond Tipped Thermal Safe Drill" - desc = "A diamond tipped thermal drill with magnetic clamps for the purpose of quickly drilling hardened objects. Comes with built in security detection and nanite system, to keep you up if security comes a-knocking." - reference = "DDRL" - item = /obj/item/thermal_drill/diamond_drill/syndicate - cost = 5 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/device_tools/medkit - name = "Syndicate Combat Medic Kit" - desc = "The syndicate medkit is a suspicious black and red. Included is a combat stimulant injector for rapid healing, a medical HUD for quick identification of injured comrades, \ - and other medical supplies helpful for a medical field operative." - reference = "SCMK" - item = /obj/item/storage/firstaid/tactical - cost = 30 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/device_tools/vtec - name = "Syndicate Cyborg Upgrade Module (VTEC)" - desc = "Increases the movement speed of a Cyborg. Install into any Borg, Syndicate or subverted" - reference = "VTEC" - item = /obj/item/borg/upgrade/vtec - cost = 30 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/device_tools/magboots - name = "Blood-Red Magboots" - desc = "A pair of magnetic boots with a Syndicate paintjob that assist with freer movement in space or on-station during gravitational generator failures. \ - These reverse-engineered knockoffs of Nanotrasen's 'Advanced Magboots' slow you down in simulated-gravity environments much like the standard issue variety." - reference = "BRMB" - item = /obj/item/clothing/shoes/magboots/syndie - cost = 10 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/device_tools/syndicate_detonator - name = "Syndicate Detonator" - desc = "The Syndicate Detonator is a companion device to the Syndicate Bomb. Simply press the included button and an encrypted radio frequency will instruct all live syndicate bombs to detonate. \ - Useful for when speed matters or you wish to synchronize multiple bomb blasts. Be sure to stand clear of the blast radius before using the detonator." - reference = "SD" - item = /obj/item/syndicatedetonator - cost = 5 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/device_tools/teleporter - name = "Teleporter Circuit Board" - desc = "A printed circuit board that completes the teleporter onboard the mothership. Advise you test fire the teleporter before entering it, as malfunctions can occur." - item = /obj/item/circuitboard/teleporter - reference = "TP" - cost = 100 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - surplus = 0 - -/datum/uplink_item/device_tools/assault_pod - name = "Assault Pod Targetting Device" - desc = "Use to select the landing zone of your assault pod." - item = /obj/item/assault_pod - reference = "APT" - cost = 125 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - surplus = 0 - -/datum/uplink_item/device_tools/shield - name = "Energy Shield" - desc = "An incredibly useful personal shield projector, capable of reflecting energy projectiles, but it cannot block other attacks. Pair with an Energy Sword for a killer combination." - item = /obj/item/shield/energy - reference = "ESD" - cost = 40 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - surplus = 20 - -/datum/uplink_item/device_tools/dropwall - name = "Dropwall generator box" - desc = "A box of 5 dropwall shield generators, which can be used to make temporary directional shields that block projectiles, thrown objects, and reduce explosions. Configure the direction before throwing." - item = /obj/item/storage/box/syndie_kit/dropwall - reference = "DWG" - cost = 50 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/device_tools/medgun - name = "Medbeam Gun" - desc = "Medical Beam Gun, useful in prolonged firefights. DO NOT CROSS THE BEAMS. Crossing beams with another medbeam or attaching two beams to one target will have explosive consequences." - item = /obj/item/gun/medbeam - reference = "MBG" - cost = 75 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -//////////////////////////////////////// -// MARK: SPACE SUITS -//////////////////////////////////////// - -/datum/uplink_item/suits/elite_nukie - name = "Elite Syndicate MODsuit" - desc = "An advanced MODsuit with superior armor and mobility to the standard Syndicate MODsuit." - item = /obj/item/mod/control/pre_equipped/elite - cost = 40 - reference = "ESHS" - excludefrom = list() - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/suits/shielded - name = "Energy Shield Module" - desc = "A personal, protective forcefield typically seen in military applications. \ - This advanced deflector shield is essentially a scaled down version of those seen on starships, \ - and the power cost can be an easy indicator of this. However, it is capable of blocking nearly any incoming attack, \ - though with its' low amount of separate charges, the user remains mortal." - item = /obj/item/mod/module/energy_shield - cost = 200 - reference = "SHS" - excludefrom = list() - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -//////////////////////////////////////// -// MARK: IMPLANTS -//////////////////////////////////////// - -/datum/uplink_item/bio_chips/krav_implant - name = "Krav Maga Implant" - desc = "A biochip that teaches you Krav Maga when implanted, great as a cheap backup weapon. Warning: the biochip will override any other fighting styles such as CQC while active." - reference = "KMI" - item = /obj/item/bio_chip_implanter/krav_maga - cost = 25 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/bio_chips/uplink/nuclear - name = "Nuclear Uplink Bio-chip" - reference = "UIN" - item = /obj/item/bio_chip_implanter/nuclear - excludefrom = list() - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/bio_chips/microbomb - name = "Microbomb Bio-chip" - desc = "A bio-chip injected into the body, and later activated either manually or automatically upon death. The more implants inside of you, the higher the explosive power. \ - This will permanently destroy your body, however." - reference = "MBI" - item = /obj/item/bio_chip_implanter/explosive - cost = 10 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/bio_chips/macrobomb - name = "Macrobomb Bio-chip" - desc = "A bio-chip injected into the body, and later activated either manually or automatically upon death. Upon death, releases a massive explosion that will wipe out everything nearby." - reference = "HAB" - item = /obj/item/bio_chip_implanter/explosive_macro - cost = 50 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - - -// CYBERNETICS - -/datum/uplink_item/cyber_implants/thermals - name = "Thermal Vision Implant" - desc = "These cybernetic eyes will give you thermal vision. Comes with an autosurgeon." - reference = "CIT" - item = /obj/item/autosurgeon/organ/syndicate/thermal_eyes - cost = 40 - surplus = 0 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/cyber_implants/xray - name = "X-Ray Vision Implant" - desc = "These cybernetic eyes will give you X-ray vision. Comes with an autosurgeon." - reference = "CIX" - item = /obj/item/autosurgeon/organ/syndicate/xray_eyes - cost = 50 - surplus = 0 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/cyber_implants/antistun - name = "Hardened CNS Rebooter Implant" - desc = "This implant will help you get back up on your feet faster after being fatigued. It is immune to EMP attacks. Comes with an autosurgeon." - reference = "CIAS" - item = /obj/item/autosurgeon/organ/syndicate/anti_stam - cost = 60 - surplus = 0 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/cyber_implants/reviver - name = "Hardened Reviver Implant" - desc = "This implant will attempt to revive and heal you if you lose consciousness. It is immune to EMP attacks. Comes with an autosurgeon." - reference = "CIR" - item = /obj/item/autosurgeon/organ/syndicate/reviver - cost = 40 - surplus = 0 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -//////////////////////////////////////// -// MARK: BUNDLES -//////////////////////////////////////// - -/datum/uplink_item/bundles_tc/c20r - name = "C-20r Bundle" - desc = "Old Faithful: The classic C-20r, bundled with three magazines and a (surplus) suppressor at discount price." - reference = "C20B" - item = /obj/item/storage/backpack/duffel/syndie/c20rbundle - cost = 90 // normally 105 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/datum/uplink_item/bundles_tc/cyber_implants - name = "Cybernetic Implants Bundle" - desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. Comes with an autosurgeon." - reference = "CIB" - item = /obj/item/storage/box/cyber_implants - cost = 200 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/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 medical beam gun and a pair of syndicate magboots." - reference = "MEDB" - item = /obj/item/storage/backpack/duffel/syndie/med/medicalbundle - cost = 80 // normally 105 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -/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 suppressor, and a sharp-looking tactical turtleneck suit. \ - We'll throw in a free red tie if you order NOW." - reference = "SNPB" - item = /obj/item/storage/briefcase/sniperbundle - cost = 90 // normally 115 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -//////////////////////////////////////// -// MARK: PRICES OVERRIDE FOR TRAITOR ITEMS -//////////////////////////////////////// - -/datum/uplink_item/stealthy_weapons/cqc/nuke - reference = "NCQC" - cost = 40 - excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) - -/datum/uplink_item/explosives/syndicate_bomb/nuke - reference = "NSB" - cost = 55 - excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) - surplus = 0 - hijack_only = FALSE - -/datum/uplink_item/explosives/emp_bomb/nuke - reference = "NSBEMP" - cost = 50 - excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) - surplus = 0 - can_discount = FALSE - -/datum/uplink_item/explosives/atmosfiregrenades/nuke - reference = "NAPG" - cost = 60 - excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) - surplus = 0 - hijack_only = TRUE - -/datum/uplink_item/stealthy_tools/chameleon/nuke - reference = "NCHAM" - item = /obj/item/storage/box/syndie_kit/chameleon/nuke - cost = 30 - excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) - -/datum/uplink_item/stealthy_tools/syndigaloshes/nuke - reference = "NNSSS" - cost = 20 - excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) - -/datum/uplink_item/explosives/detomatix/nuclear - desc = "When inserted into a personal digital assistant, this cartridge gives you five opportunities to detonate PDAs of crewmembers who have their message feature enabled. The concussive effect from the explosion will knock the recipient out for a short period, and deafen them for longer. It has a chance to detonate your PDA. This version comes with a program to toggle your nuclear shuttle blast doors remotely." - item = /obj/item/cartridge/syndicate/nuclear - reference = "DEPCN" - excludefrom = list() - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - -//////////////////////////////////////// -// MARK: NUKIE ONLY POINTLESS BADASSERY -//////////////////////////////////////// - -/datum/uplink_item/badass/confettidrum - name = "Bulldog - 12g party Magazine" - desc = "An alternative 12-round confetti magazine for use in the Bulldog shotgun. Why? Because we can - Honkco Industries" - item = /obj/item/ammo_box/magazine/m12g/confetti - reference = "12CS" - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - cost = 5 - -/datum/uplink_item/badass/confetti_party_pack - name = "Nuclear party pack" - desc = "A dufflebag filled with hilarious equipment! Comes with free confetti grenades and a cap gun!" - item = /obj/item/storage/backpack/duffel/syndie/party - reference = "SPP" - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) - cost = 50 diff --git a/code/datums/wires/alarm.dm b/code/datums/wires/alarm.dm deleted file mode 100644 index 08b2ed5a17058..0000000000000 --- a/code/datums/wires/alarm.dm +++ /dev/null @@ -1,81 +0,0 @@ - -/datum/wires/alarm - holder_type = /obj/machinery/alarm - wire_count = 5 - proper_name = "Air alarm" - -/datum/wires/alarm/New(atom/_holder) - wires = list( - WIRE_IDSCAN , WIRE_MAIN_POWER1 , WIRE_SIPHON, - WIRE_AI_CONTROL, WIRE_AALARM - ) - return ..() - -/datum/wires/alarm/interactable(mob/user) - var/obj/machinery/alarm/A = holder - if(A.wiresexposed) - return TRUE - return FALSE - -/datum/wires/alarm/get_status() - . = ..() - var/obj/machinery/alarm/A = holder - . += "The Air Alarm is [A.locked ? "" : "un"]locked." - . += "The Air Alarm is [(A.shorted || (A.stat & (NOPOWER|BROKEN))) ? "offline." : "working properly!"]" - . += "The 'AI control allowed' light is [A.aidisabled ? "off" : "on"]." - -/datum/wires/alarm/on_cut(wire, mend) - var/obj/machinery/alarm/A = holder - switch(wire) - if(WIRE_IDSCAN) - if(!mend) - A.locked = TRUE - - if(WIRE_MAIN_POWER1) - A.shock(usr, 50) - A.shorted = !mend - A.update_icon() - - if(WIRE_AI_CONTROL) - A.aidisabled = !mend - - if(WIRE_SIPHON) - if(!mend) - A.mode = AALARM_MODE_PANIC - A.apply_mode() - - if(WIRE_AALARM) - A.alarm_area.atmosalert(ATMOS_ALARM_DANGER, A) - A.update_icon() - ..() - -/datum/wires/alarm/on_pulse(wire) - var/obj/machinery/alarm/A = holder - switch(wire) - if(WIRE_IDSCAN) - A.locked = !A.locked - - if(WIRE_MAIN_POWER1) - if(!A.shorted) - A.shorted = TRUE - A.update_icon() - addtimer(CALLBACK(A, TYPE_PROC_REF(/obj/machinery/alarm, unshort_callback)), 120 SECONDS) - - if(WIRE_AI_CONTROL) - if(!A.aidisabled) - A.aidisabled = TRUE - A.updateDialog() - addtimer(CALLBACK(A, TYPE_PROC_REF(/obj/machinery/alarm, enable_ai_control_callback)), 10 SECONDS) - - - if(WIRE_SIPHON) - if(A.mode == AALARM_MODE_FILTERING) - A.mode = AALARM_MODE_PANIC - else - A.mode = AALARM_MODE_FILTERING - A.apply_mode() - - if(WIRE_AALARM) - A.alarm_area.atmosalert(ATMOS_ALARM_NONE, A) - A.update_icon() - ..() diff --git a/code/datums/wires/particle_accelerator_wires.dm b/code/datums/wires/particle_accelerator_wires.dm deleted file mode 100644 index 34a7d1313fe7a..0000000000000 --- a/code/datums/wires/particle_accelerator_wires.dm +++ /dev/null @@ -1,50 +0,0 @@ -/datum/wires/particle_accelerator - wire_count = 5 - holder_type = /obj/machinery/particle_accelerator/control_box - proper_name = "Particle accelerator control" - -/datum/wires/particle_accelerator/New(atom/_holder) - wires = list(WIRE_PARTICLE_POWER, WIRE_PARTICLE_STRENGTH, WIRE_PARTICLE_INTERFACE, WIRE_PARTICLE_POWER_LIMIT) - return ..() - -/datum/wires/particle_accelerator/interactable(mob/user) - var/obj/machinery/particle_accelerator/control_box/C = holder - if(C.construction_state == 2) - return TRUE - return FALSE - -/datum/wires/particle_accelerator/on_pulse(wire) - var/obj/machinery/particle_accelerator/control_box/C = holder - switch(wire) - if(WIRE_PARTICLE_POWER) - C.toggle_power() - - if(WIRE_PARTICLE_STRENGTH) - C.add_strength() - - if(WIRE_PARTICLE_INTERFACE) - C.interface_control = !C.interface_control - - if(WIRE_PARTICLE_POWER_LIMIT) - C.visible_message("[bicon(C)][C] makes a large whirring noise.") - ..() - -/datum/wires/particle_accelerator/on_cut(wire, mend) - var/obj/machinery/particle_accelerator/control_box/C = holder - switch(wire) - if(WIRE_PARTICLE_POWER) - if(C.active == !mend) - C.toggle_power() - - if(WIRE_PARTICLE_STRENGTH) - for(var/i in 1 to 2) - C.remove_strength() - - if(WIRE_PARTICLE_INTERFACE) - C.interface_control = mend - - if(WIRE_PARTICLE_POWER_LIMIT) - C.strength_upper_limit = (mend ? 2 : 3) - if(C.strength_upper_limit < C.strength) - C.remove_strength() - ..() diff --git a/code/game/area/ai_monitored.dm b/code/game/area/ai_monitored.dm deleted file mode 100644 index 61c9cab09b78e..0000000000000 --- a/code/game/area/ai_monitored.dm +++ /dev/null @@ -1,35 +0,0 @@ -/area/station/ai_monitored - name = "AI Monitored Area" - var/list/motioncameras = list() - var/list/motionTargets = list() - sound_environment = SOUND_ENVIRONMENT_ROOM - -/area/station/ai_monitored/Initialize(mapload) - . = ..() - if(mapload) - for(var/obj/machinery/camera/M in src) - if(M.isMotion()) - motioncameras.Add(M) - M.set_area_motion(src) - -/area/station/ai_monitored/Entered(atom/movable/O) - ..() - if(ismob(O) && length(motioncameras)) - for(var/X in motioncameras) - var/obj/machinery/camera/cam = X - cam.newTarget(O) - return - -/area/station/ai_monitored/Exited(atom/movable/O, direction) - ..() - if(ismob(O) && length(motioncameras)) - for(var/X in motioncameras) - var/obj/machinery/camera/cam = X - cam.lostTargetRef(O.UID()) - return - -/area/station/ai_monitored/storage/eva - name = "EVA Storage" - icon_state = "eva" - ambientsounds = HIGHSEC_SOUNDS - request_console_name = "EVA" diff --git a/code/game/area/areas/depot-areas.dm b/code/game/area/areas/depot-areas.dm deleted file mode 100644 index 52def39ba0d5d..0000000000000 --- a/code/game/area/areas/depot-areas.dm +++ /dev/null @@ -1,502 +0,0 @@ - -/area/syndicate_depot - name = "Suspicious Supply Depot" - icon_state = "dark" - tele_proof = TRUE - -/area/syndicate_depot/core - icon_state = "red" - - var/local_alarm = FALSE // Level 1: Local alarm tripped, bot spawned, red fire overlay activated - var/called_backup = FALSE // Level 2: Remote alarm tripped. Bot may path through depot. Backup spawned. - var/used_self_destruct = FALSE // Level 3: Self destruct activated. Depot will be destroyed shortly. - - var/run_started = FALSE - var/run_finished = FALSE - - // Soft UID-based refs - var/list/guard_list = list() - var/list/hostile_list = list() - var/list/dead_list = list() - var/list/peaceful_list = list() - var/list/shield_list = list() - - var/list/alert_log = list() // no refs, just a simple list of text strings - - var/used_lockdown = FALSE - var/destroyed = FALSE - var/something_looted = FALSE - var/on_peaceful = FALSE - var/peace_betrayed = FALSE - var/detected_mech = FALSE - var/detected_pod = FALSE - var/detected_double_agent = FALSE - var/mine_trigger_count = 0 - var/perimeter_shield_status = FALSE - var/obj/machinery/computer/syndicate_depot/syndiecomms/comms_computer = null - var/obj/structure/fusionreactor/reactor - -/area/syndicate_depot/core/proc/update_state() - if(destroyed) - invisibility = INVISIBILITY_MAXIMUM - else if(on_peaceful) - invisibility = INVISIBILITY_LIGHTING - else if(used_self_destruct) - invisibility = INVISIBILITY_LIGHTING - else if(called_backup) - invisibility = INVISIBILITY_LIGHTING - else if(local_alarm) - invisibility = INVISIBILITY_LIGHTING - else - invisibility = INVISIBILITY_MAXIMUM - update_icon(UPDATE_ICON_STATE) - -/area/syndicate_depot/core/update_icon_state() - if(invisibility == INVISIBILITY_MAXIMUM) - icon_state = null - return - else if(on_peaceful) - icon_state = "green" - else if(used_self_destruct) - icon_state = "radiation" - else if(called_backup) - icon_state = "red" - else if(local_alarm) - icon_state = "bluenew" - -/area/syndicate_depot/core/proc/reset_alert() - - if(used_self_destruct) - for(var/obj/effect/overload/O in src) - new /obj/structure/fusionreactor(O.loc) - qdel(O) - - if(on_peaceful) - peaceful_mode(FALSE, TRUE) - - local_alarm = FALSE - called_backup = FALSE - unlock_computers() - used_self_destruct = FALSE - - run_started = FALSE - run_finished = FALSE - - despawn_guards() - hostile_list = list() - dead_list = list() - peaceful_list = list() - - something_looted = FALSE - detected_mech = FALSE - detected_pod = FALSE - detected_double_agent = FALSE - mine_trigger_count = 0 - update_icon(UPDATE_ICON_STATE) - - if(!istype(reactor)) - for(var/obj/structure/fusionreactor/R in src) - reactor = R - R.has_overloaded = FALSE - - for(var/obj/machinery/door/airlock/A in src) - if(A.density && A.locked) - spawn(0) - A.unlock() - - alert_log += "Alert level reset." - -/area/syndicate_depot/core/proc/increase_alert(reason) - if(on_peaceful) - peaceful_mode(FALSE, FALSE) - peace_betrayed = TRUE - activate_self_destruct("Depot has been infiltrated by double-agents.", TRUE, null) - return - if(!local_alarm) - local_alarm(reason, FALSE) - return - if(!called_backup) - call_backup(reason, FALSE) - return - if(!used_self_destruct) - activate_self_destruct(reason, FALSE, null) - update_icon(UPDATE_ICON_STATE) - -/area/syndicate_depot/core/proc/locker_looted() - if(!something_looted) - something_looted = TRUE - if(on_peaceful) - increase_alert("Thieves!") - if(perimeter_shield_status) - increase_alert("Perimeter shield breach!") - - -/area/syndicate_depot/core/proc/armory_locker_looted() - if(!run_finished && !used_self_destruct) - if(length(shield_list)) - activate_self_destruct("Armory compromised despite armory shield being online.", FALSE) - return - declare_finished() - -/area/syndicate_depot/core/proc/turret_died() - something_looted = TRUE - if(on_peaceful) - increase_alert("Vandals!") - -/area/syndicate_depot/core/proc/mine_triggered(mob/living/M) - if(mine_trigger_count) - return TRUE - mine_trigger_count++ - increase_alert("Intruder detected by sentry mine: [M]") - -/area/syndicate_depot/core/proc/saw_mech(obj/mecha/E) - if(detected_mech) - return - detected_mech = TRUE - increase_alert("Hostile mecha detected: [E]") - -/area/syndicate_depot/core/proc/saw_double_agent(mob/living/M) - if(detected_double_agent) - return - detected_double_agent = TRUE - increase_alert("Hostile double-agent detected: [M]") - -/area/syndicate_depot/core/proc/peaceful_mode(newvalue, bycomputer) - if(newvalue) - log_game("Depot visit: started") - alert_log += "Code GREEN: visitor mode started." - ghostlog("The syndicate depot has visitors") - for(var/mob/living/simple_animal/bot/medbot/syndicate/B in src) - qdel(B) - for(var/mob/living/simple_animal/hostile/syndicate/N in src) - N.a_intent = INTENT_HELP - for(var/obj/structure/closet/secure_closet/depot/L in src) - if(L.opened) - L.close() - if(!L.locked) - L.locked = !L.locked - L.req_access = list(ACCESS_SYNDICATE_LEADER) - L.update_icon() - else - log_game("Depot visit: ended") - alert_log += "Visitor mode ended." - for(var/mob/living/simple_animal/hostile/syndicate/N in src) - N.a_intent = INTENT_HARM - for(var/obj/machinery/door/airlock/A in src) - A.req_access = list(ACCESS_SYNDICATE_LEADER) - for(var/obj/structure/closet/secure_closet/depot/L in src) - if(L.locked) - L.locked = !L.locked - L.req_access = list() - L.update_icon() - on_peaceful = newvalue - if(newvalue) - announce_here("Depot Visitor","A Syndicate agent is visiting the depot.") - else - if(bycomputer) - message_admins("Syndicate Depot visitor mode deactivated. Visitors:") - announce_here("Depot Alert","Visit ended. All visting agents signed out.") - else - message_admins("Syndicate Depot visitor mode auto-deactivated because visitors robbed depot! Visitors:") - announce_here("Depot Alert","A visiting agent has betrayed the Syndicate. Shoot all visitors on sight!") - for(var/mob/M in list_getmobs(peaceful_list)) - if("syndicate" in M.faction) - M.faction -= "syndicate" - message_admins("- SYNDI DEPOT VISITOR: [ADMIN_FULLMONTY(M)]") - list_add(M, hostile_list) - peaceful_list = list() - update_icon(UPDATE_ICON_STATE) - -/area/syndicate_depot/core/proc/local_alarm(reason, silent) - if(local_alarm) - return - log_game("Depot code: blue: " + list_show(hostile_list, TRUE)) - ghostlog("The syndicate depot has declared code blue.") - alert_log += "Code BLUE: [reason]" - local_alarm = TRUE - if(!silent) - announce_here("Depot Code BLUE", reason) - var/list/possible_bot_spawns = list() - for(var/thing in GLOB.landmarks_list) - var/obj/effect/landmark/L = thing - if(L.name == "syndi_depot_bot") - possible_bot_spawns |= L - if(length(possible_bot_spawns)) - var/obj/effect/landmark/S = pick(possible_bot_spawns) - new /obj/effect/portal(get_turf(S)) - var/mob/living/simple_animal/bot/ed209/syndicate/B = new /mob/living/simple_animal/bot/ed209/syndicate(get_turf(S)) - list_add(B, guard_list) - B.depotarea = src - update_icon(UPDATE_ICON_STATE) - -/area/syndicate_depot/core/proc/call_backup(reason, silent) - if(called_backup || used_self_destruct) - return - log_game("Depot code: red: " + list_show(hostile_list, TRUE)) - ghostlog("The syndicate depot has declared code red.") - alert_log += "Code RED: [reason]" - called_backup = TRUE - lockout_computers() - for(var/obj/machinery/door/poddoor/P in GLOB.airlocks) - if(P.density && P.id_tag == "syndi_depot_lvl2" && !P.operating) - spawn(0) - P.open() - if(!silent) - announce_here("Depot Code RED", reason) - - var/comms_online = FALSE - if(istype(comms_computer)) - if(!(comms_computer.stat & (NOPOWER|BROKEN))) - comms_online = TRUE - if(comms_online) - spawn(0) - for(var/thing in GLOB.landmarks_list) - var/obj/effect/landmark/L = thing - if(prob(50)) - if(L.name == "syndi_depot_backup") - var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space/S = new /mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space(get_turf(L)) - S.name = "Syndicate Backup " + "([rand(1, 1000)])" - S.depotarea = src - list_add(S, guard_list) - else if(!silent) - announce_here("Depot Communications Offline", "Comms computer is damaged, destroyed or depowered. Unable to call in backup from Syndicate HQ.") - update_icon(UPDATE_ICON_STATE) - -/area/syndicate_depot/core/proc/activate_self_destruct(reason, containment_failure, mob/user) - if(used_self_destruct) - return - log_game("Depot code: delta: " + list_show(hostile_list, TRUE)) - ghostlog("The syndicate depot is about to self-destruct.") - alert_log += "Code DELTA: [reason]" - used_self_destruct = TRUE - local_alarm = TRUE - called_backup = TRUE - activate_lockdown(TRUE) - lockout_computers() - update_icon(UPDATE_ICON_STATE) - despawn_guards() - if(containment_failure) - announce_here("Depot Code DELTA", reason) - else - announce_here("Depot Code DELTA","[reason] Depot declared lost to hostile forces. Priming self-destruct!") - - if(user) - var/turf/T = get_turf(user) - var/area/A = get_area(T) - var/log_msg = "[key_name(user)] has triggered the depot self destruct at [A.name] ([T.x],[T.y],[T.z])" - message_admins(log_msg) - log_game(log_msg) - playsound(user, 'sound/machines/alarm.ogg', 100, FALSE, 0) - else - log_game("Depot self destruct activated.") - if(reactor) - if(!reactor.has_overloaded) - reactor.overload(containment_failure) - else - log_debug("Depot: [src] called activate_self_destruct with no reactor.") - message_admins("Syndicate Depot lacks reactor to initiate self-destruct. Must be destroyed manually.") - update_icon(UPDATE_ICON_STATE) - -/area/syndicate_depot/core/proc/activate_lockdown() - if(used_lockdown) - return - used_lockdown = TRUE - for(var/obj/machinery/door/airlock/A in src) - spawn(0) - A.close() - if(A.density && !A.locked) - A.lock() - -/area/syndicate_depot/core/proc/lockout_computers() - for(var/obj/machinery/computer/syndicate_depot/C in src) - C.activate_security_lockout() - -/area/syndicate_depot/core/proc/unlock_computers() - for(var/obj/machinery/computer/syndicate_depot/C in src) - C.security_lockout = FALSE - -/area/syndicate_depot/core/proc/set_emergency_access(openaccess) - for(var/obj/machinery/door/airlock/A in src) - if(istype(A, /obj/machinery/door/airlock/hatch/syndicate/vault)) - continue - A.emergency = !!openaccess - A.update_icon() - -/area/syndicate_depot/core/proc/toggle_falsewalls() - for(var/obj/structure/falsewall/plastitanium/F in src) - spawn(0) - F.toggle() - -/area/syndicate_depot/core/proc/toggle_teleport_beacon() - for(var/obj/machinery/bluespace_beacon/syndicate/B in src) - return B.toggle() - -/area/syndicate_depot/core/proc/announce_here(a_header = "Depot Defense Alert", a_text = "") - var/msg_text = "[a_header]
    [a_text]" - var/list/receivers = list() - for(var/mob/M in GLOB.mob_list) - if(!M.ckey) - continue - var/turf/T = get_turf(M) - if(T && T.loc && T.loc == src) - receivers |= M - for(var/mob/R in receivers) - to_chat(R, msg_text) - SEND_SOUND(R, sound('sound/misc/notice1.ogg')) - -/area/syndicate_depot/core/proc/shields_up() - if(length(shield_list)) - return - for(var/thing in GLOB.landmarks_list) - var/obj/effect/landmark/L = thing - if(L.name == "syndi_depot_shield") - var/obj/machinery/shieldwall/syndicate/S = new /obj/machinery/shieldwall/syndicate(L.loc) - shield_list += S.UID() - for(var/obj/structure/closet/secure_closet/depot/armory/L in src) - if(L.opened) - L.close() - if(!L.locked) - L.locked = !L.locked - L.update_icon() - for(var/obj/machinery/door/airlock/hatch/syndicate/vault/A in src) - A.lock() - -/area/syndicate_depot/core/proc/shields_key_check() - if(!length(shield_list)) - return - if(detected_mech || detected_pod || detected_double_agent) - return - shields_down() - -/area/syndicate_depot/core/proc/shields_down() - for(var/shuid in shield_list) - var/obj/machinery/shieldwall/syndicate/S = locateUID(shuid) - if(S) - qdel(S) - shield_list = list() - for(var/obj/machinery/door/airlock/hatch/syndicate/vault/A in src) - A.unlock() - -/area/syndicate_depot/core/proc/unlock_lockers() // used on QM's death - for(var/obj/structure/closet/secure_closet/depot/armory/L in src) - if(L.locked) - L.locked = !L.locked - L.update_icon() - -/area/syndicate_depot/core/proc/despawn_guards() - for(var/mob/thismob in list_getmobs(guard_list)) - new /obj/effect/portal(get_turf(thismob)) - qdel(thismob) - guard_list = list() - -/area/syndicate_depot/core/proc/ghostlog(gmsg) - if(istype(reactor)) - var/image/alert_overlay = image('icons/obj/flag.dmi', "syndiflag") - notify_ghosts(gmsg, title = "Depot News", source = reactor.loc, alert_overlay = alert_overlay, flashwindow = FALSE, action = NOTIFY_JUMP) - -/area/syndicate_depot/core/proc/declare_started() - if(!run_started) - run_started = TRUE - log_game("Depot run: started: " + list_show(hostile_list, TRUE)) - -/area/syndicate_depot/core/proc/declare_finished() - if(!run_finished && !used_self_destruct) - run_finished = TRUE - log_game("Depot run: finished successfully: " + list_show(hostile_list, TRUE)) - -/area/syndicate_depot/core/proc/list_add(mob/M, list/L) - if(!istype(M)) - return - var/mob_uid = M.UID() - if(mob_uid in L) - return - L += mob_uid - -/area/syndicate_depot/core/proc/list_remove(mob/M, list/L) - if(!istype(M)) - return - var/mob_uid = M.UID() - if(mob_uid in L) - L -= mob_uid - -/area/syndicate_depot/core/proc/list_includes(mob/M, list/L) - if(!istype(M)) - return FALSE - var/mob_uid = M.UID() - if(mob_uid in L) - return TRUE - return FALSE - -/** - * Returns a STRING, containing the NAMES of the mobs in the provided list, JOINED together with ", " - * - * E.g. list_show(depotarea.guard_list) returns a string like: - * "Syndicate Backup (123), Syndicate Backup(456), Syndicate Backup(789)", etc. - * Arguments: - * * list/L, the list of UIDs from which to draw members - * * show_ckeys, bool, if true will display ckeys in addition to names - */ -/area/syndicate_depot/core/proc/list_show(list/L, show_ckeys = FALSE) - var/list/formatted = list_shownames(L, show_ckeys) - return formatted.Join(", ") - -/** - * Returns a LIST of the NAMES of the mobs in the provided list. - * - * E.g. list_shownames(depotarea.guard_list) returns a list of the names of extra guard mobs in depot. - * Arguments: - * * list/L, the list of UIDs from which to draw members - * * show_ckeys, bool, if true will display ckeys in addition to names - */ -/area/syndicate_depot/core/proc/list_shownames(list/L, show_ckeys = FALSE) - var/list/names = list() - for(var/uid in L) - var/mob/M = locateUID(uid) - if(!istype(M)) - continue - if(show_ckeys) - names += "[M.ckey]([M])" - else - names += "[M]" - return names - -/** - * Returns a LIST of the MOBS in one of the depot area's lists. - * - * E.g. list_getmobs(depotarea.guard_list) returns a list of the extra guard mobs in the depot. - * Arguments: - * * list/L, the list of UIDs from which to draw members - * * show_ckeys, bool, if true will display ckeys in addition to names - */ -/area/syndicate_depot/core/proc/list_getmobs(list/L, show_ckeys = FALSE) - var/list/moblist = list() - for(var/uid in L) - var/mob/M = locateUID(uid) - if(!istype(M)) - continue - moblist += M - return moblist - -/area/syndicate_depot/outer - name = "Suspicious Asteroid" - icon_state = "green" - -/area/syndicate_depot/perimeter - name = "Suspicious Asteroid Perimeter" - icon_state = "yellow" - var/list/shield_list = list() - -/area/syndicate_depot/perimeter/proc/perimeter_shields_up() - if(length(shield_list)) - return - for(var/turf/T in src) - var/obj/machinery/shieldwall/syndicate/S = new /obj/machinery/shieldwall/syndicate(T) - S.alpha = 0 - shield_list += S.UID() - -/area/syndicate_depot/perimeter/proc/perimeter_shields_down() - for(var/shuid in shield_list) - var/obj/machinery/shieldwall/syndicate/S = locateUID(shuid) - if(S) - qdel(S) - shield_list = list() diff --git a/code/game/area/areas/ruins/blackmarketpackers.dm b/code/game/area/areas/ruins/blackmarketpackers.dm deleted file mode 100644 index ab3330a2c00b0..0000000000000 --- a/code/game/area/areas/ruins/blackmarketpackers.dm +++ /dev/null @@ -1,23 +0,0 @@ -//Packer Ship Areas - -/area/ruin/unpowered/bmp_ship - name = "\improper BMP Asteroids" - icon_state = "away" - report_alerts = FALSE - requires_power = TRUE - -/area/ruin/unpowered/bmp_ship/aft - name = "\improper BMP Aft Block" - icon_state = "away1" - -/area/ruin/unpowered/bmp_ship/midship - name = "\improper BMP Midship Block" - icon_state = "away2" - -/area/ruin/unpowered/bmp_ship/fore - name = "\improper BMP Fore Block" - icon_state = "away3" - -/area/ruin/unpowered/bmp_ship/delta - name = "\improper BMP Delta Block" - icon_state = "away4" diff --git a/code/game/area/areas/ruins/space_areas.dm b/code/game/area/areas/ruins/space_areas.dm deleted file mode 100644 index 13727e83da1f3..0000000000000 --- a/code/game/area/areas/ruins/space_areas.dm +++ /dev/null @@ -1,279 +0,0 @@ -//Space Ruins - -/area/ruin/space - var/baseturf = /turf/space - -/area/ruin/space/powered - requires_power = FALSE - -/area/ruin/space/unpowered - always_unpowered = FALSE - -/area/ruin/space/unpowered/no_grav - has_gravity = FALSE - -/area/ruin/space/abandtele - name = "\improper Abandoned Teleporter" - icon_state = "teleporter" - ambientsounds = list('sound/ambience/ambimalf.ogg', 'sound/ambience/signal.ogg') - there_can_be_many = TRUE - -/area/ruin/space/unpowered/no_grav/way_home - name = "\improper Salvation" - -// Old tcommsat -/area/ruin/space/tcommsat - name = "Telecommunications Satellite" - icon_state = "tcomms" - -// Ruins of "onehalf" ship -/area/ruin/space/onehalf/hallway - name = "DK Excavator 453 Hallway" - icon_state = "hallC" - -/area/ruin/space/onehalf/drone_bay - name = "DK Excavator 453 Mining Drone Bay" - icon_state = "engine" - -/area/ruin/space/onehalf/dorms_med - name = "DK Excavator 453 Crew Quarters" - icon_state = "Sleep" - -/area/ruin/space/onehalf/abandonedbridge - name = "DK Excavator 453 Abandoned Bridge" - icon_state = "bridge" - -// Ruins of the Unathi Breacher ship -/area/ruin/space/unathi_breacher/engineering - name = "Breacher Engine Bay" - -/area/ruin/space/unathi_breacher/dorms - name = "Breacher Crew Quarters" - -/area/ruin/space/unathi_breacher/bar - name = "Breacher Bar" - -/area/ruin/space/unathi_breacher/bridge - name = "Breacher Bridge" - -/area/ruin/space/unathi_breacher/hold - name = "Breacher Hold" - -//DJSTATION -/area/ruin/space/djstation - name = "\improper Soviet DJ Station" - icon_state = "DJ" - -/area/ruin/space/djstation/solars - name = "\improper Soviet DJ Station Solars" - icon_state = "DJ" - -//Methlab -/area/ruin/space/methlab - name = "\improper Abandoned Drug Lab" - icon_state = "green" - there_can_be_many = TRUE - -// Space Bar -/area/ruin/space/powered/bar - name = "\improper Space Bar" - -//DERELICT (USSP station and USSP Teleporter) -/area/ruin/space/derelict - name = "\improper Derelict Station" - icon_state = "storage" - -/area/ruin/space/derelict/hallway/primary - name = "\improper Derelict Primary Hallway" - icon_state = "hallP" - -/area/ruin/space/derelict/hallway/secondary - name = "\improper Derelict Secondary Hallway" - icon_state = "hallS" - -/area/ruin/space/derelict/arrival - name = "\improper Derelict Arrival Centre" - icon_state = "yellow" - -/area/ruin/space/derelict/storage/equipment - name = "Derelict Equipment Storage" - -/area/ruin/space/derelict/storage/storage_access - name = "Derelict Storage Access" - -/area/ruin/space/derelict/storage/engine_storage - name = "Derelict Engine Storage" - icon_state = "green" - -/area/ruin/space/derelict/bridge - name = "\improper Derelict Control Room" - icon_state = "bridge" - -/area/ruin/space/derelict/secret - name = "\improper Derelict Secret Room" - icon_state = "library" - -/area/ruin/space/derelict/bridge/access - name = "Derelict Control Room Access" - icon_state = "auxstorage" - -/area/ruin/space/derelict/bridge/ai_upload - name = "\improper Derelict Computer Core" - icon_state = "ai" - -/area/ruin/space/derelict/solar_control - name = "\improper Derelict Solar Control" - icon_state = "general_solar_control" - -/area/ruin/space/derelict/se_solar - name = "\improper Derelict South East Solars" - icon_state = "general_solars" - -/area/ruin/space/derelict/crew_quarters - name = "\improper Derelict Crew Quarters" - icon_state = "fitness" - -/area/ruin/space/derelict/medical - name = "Derelict Medbay" - icon_state = "medbay" - -/area/ruin/space/derelict/medical/morgue - name = "\improper Derelict Morgue" - icon_state = "morgue" - is_haunted = TRUE - -/area/ruin/space/derelict/medical/chapel - name = "\improper Derelict Chapel" - icon_state = "chapel" - is_haunted = TRUE - -/area/ruin/space/derelict/teleporter - name = "\improper Derelict Teleporter" - icon_state = "teleporter" - -/area/ruin/space/derelict/eva - name = "Derelict EVA Storage" - icon_state = "eva" - -/area/ruin/space/syndicate_druglab - name = "Suspicious Station" - icon_state = "red" - -/area/ruin/space/syndicate_druglab/asteroid - name = "Suspicious Asteroid" - icon_state = "dark" - requires_power = FALSE - -/area/ruin/space/bubblegum_arena - name = "Bubblegum Arena" - -/area/ruin/space/wreck_cargoship - name = "Faint Signal" - icon_state = "yellow" - -// Syndicate Listening Station - -/area/ruin/space/syndicate_listening_station - name = "Listening Post" - icon_state = "red" - -/area/ruin/space/syndicate_listening_station/asteroid - name = "Listening Post Asteroid" - icon_state = "dark" - requires_power = FALSE - -/area/ruin/space/abandoned_engi_sat - name = "Abandoned NT Engineering Satellite" - apc_starts_off = TRUE - -/area/ruin/space/moonbase19 - name = "Moon Base 19" - apc_starts_off = TRUE - -/area/ruin/space/mech_transport - name = "Cybersun Mobile Exosuit Factory" - apc_starts_off = TRUE - there_can_be_many = FALSE - -/area/ruin/space/powered/casino - name = "Dorian Casino" - there_can_be_many = FALSE - requires_power = TRUE - -/area/ruin/space/powered/casino/docked_ships - name = "Dorian Casino Shuttle" - requires_power = FALSE - -/area/ruin/space/powered/casino/arrivals - name = "Dorian Casino Arrivals" - -/area/ruin/space/powered/casino/kitchen - name = "Dorian Casino Dining and Kitchen" - -/area/ruin/space/powered/casino/floor - name = "Dorian Casino Casino Floor" - -/area/ruin/space/powered/casino/hall - name = "Dorian Casino Main Hall" - -/area/ruin/space/powered/casino/engine - name = "Dorian Casino Engine Room" - -/area/ruin/space/powered/casino/security - name = "Dorian Casino Security" - -/area/ruin/space/powered/casino/teleporter - name = "Dorian Casino Teleporter" - -/area/ruin/space/powered/casino/maints - name = "Dorian Casino Service Tunnels" - -/// telecomms: Alternative telecomms sat -/area/ruin/space/telecomms - name = "\improper Telecommunications Sat" - icon_state = "tcomms" - tele_proof = TRUE // No patrick, you can not syndicate teleport or hand teleport instantly into or out of this ruin - ambientsounds = list('sound/ambience/dvorak_ambience_final.ogg') - min_ambience_cooldown = 110 SECONDS // 3 seconds longer than the length of the song - max_ambience_cooldown = 170 SECONDS // A minute break at most - -/area/ruin/space/telecomms/powercontrol - name = "\improper Telecommunications Power Control" - icon_state = "engine_smes" - -/area/ruin/space/telecomms/tele - name = "\improper Tel3coMMunic@tions-SS-S KILL_Welcoming Room" // If you teleport to it. With a name like that. Thats on you. - icon_state = "teleporter" - tele_proof = FALSE // Oh, right. The teleporter room. The teleporter room for Kuzco, the poison chosen especially to teleport Kuzco, Kuzco's teleporter room. That teleporter room? - -/area/ruin/space/telecomms/foyer - name = "\improper Telecommunications Foyer" - icon_state = "entry" - -/area/ruin/space/telecomms/computer - name = "\improper Telecommunications Control Room" - icon_state = "bridge" - -/area/ruin/space/telecomms/chamber - name = "\improper Telecommunications Central Compartment" - icon_state = "ai_chamber" - -/area/ruin/space/deepstorage - name = "Derelict Facility" - apc_starts_off = TRUE - -/area/ruin/space/sec_shuttle - name = "Abandoned Security Shuttle" - apc_starts_off = TRUE - -/area/ruin/space/syndicakefactory - name = "Syndicake factory" - -/area/ruin/space/clown_mime_ruin - name = "\improper Derelict Transport Vessel" - -/area/ruin/space/clockwork_monastery - name = "\improper Abandoned Clockwork Monastery" - there_can_be_many = FALSE - requires_power = FALSE - ambientsounds = list("sound/ambience/reebe_ambience_1.ogg", "sound/ambience/reebe_ambience_2.ogg", "sound/ambience/reebe_ambience_3.ogg") diff --git a/code/game/area/ss13_areas/procedure_areas.dm b/code/game/area/ss13_areas/procedure_areas.dm deleted file mode 100644 index 12d2e177b5b29..0000000000000 --- a/code/game/area/ss13_areas/procedure_areas.dm +++ /dev/null @@ -1,4 +0,0 @@ - -/area/station/procedure/trainer_office - name = "\improper Trainer's Office" - icon_state = "procedure_nct" diff --git a/code/game/area/ss13_areas/science_areas.dm b/code/game/area/ss13_areas/science_areas.dm deleted file mode 100644 index 2c2734fcbb6f9..0000000000000 --- a/code/game/area/ss13_areas/science_areas.dm +++ /dev/null @@ -1,96 +0,0 @@ -// Robotics areas - -/area/station/science/robotics - name = "\improper Robotics Lab" - icon_state = "robo" - request_console_flags = RC_SUPPLY - request_console_name = "Robotics" - -/area/station/science/robotics/chargebay - name = "\improper Mech Bay" - icon_state = "mechbay" - -/area/station/science/robotics/showroom - name = "\improper Robotics Showroom" - icon_state = "showroom" - -/area/station/science/research - name = "Research Division" - icon_state = "sci" - -/area/station/science/lobby - name = "Research Division Lobby" - icon_state = "sci" - -/area/station/science/testrange - name = "Research Test Range" - icon_state = "sci" - -/area/station/science/break_room - name = "\improper Science Break Room" - icon_state = "scibreak" - -/area/station/science/genetics - name = "\improper Genetics Lab" - icon_state = "genetics" - request_console_flags = RC_ASSIST - request_console_name = "Genetics" - -/area/station/science - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/station/science/rnd - name = "Research and Development" - icon_state = "rnd" - request_console_flags = RC_SUPPLY - request_console_name = "Science" - -/area/station/science/hallway - name = "\improper Research Lab" - icon_state = "sci" - -/area/station/science/xenobiology - name = "\improper Xenobiology Lab" - icon_state = "xenobio" - xenobiology_compatible = TRUE - request_console_flags = RC_ASSIST | RC_INFO - request_console_name = "Xenobiology" - -/area/station/science/storage - name = "\improper Science Toxins Storage" - icon_state = "toxstorage" - -/area/station/science/toxins/test - name = "\improper Toxins Test Area" - icon_state = "toxtest" - valid_territory = FALSE - -/area/station/science/toxins/mixing - name = "\improper Toxins Mixing Room" - icon_state = "toxmix" - request_console_flags = RC_SUPPLY - request_console_name = "Science" - -/area/station/science/toxins/launch - name = "\improper Toxins Launch Room" - icon_state = "toxlaunch" - request_console_flags = RC_SUPPLY - request_console_name = "Science" - -/area/station/science/misc_lab - name = "\improper Research Testing Lab" - icon_state = "scichem" - request_console_flags = RC_SUPPLY - request_console_name = "Science" - -/area/station/science/test_chamber - name = "\improper Research Testing Chamber" - icon_state = "scitest" - -/area/station/science/server - name = "\improper Server Room" - icon_state = "server" - -/area/station/science/server/coldroom - name = "\improper Server Coldroom" - icon_state = "servercold" diff --git a/code/game/area/ss13_areas/security_areas.dm b/code/game/area/ss13_areas/security_areas.dm deleted file mode 100644 index 7e6db172b93ad..0000000000000 --- a/code/game/area/ss13_areas/security_areas.dm +++ /dev/null @@ -1,140 +0,0 @@ - -/area/station/security - ambientsounds = HIGHSEC_SOUNDS - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/station/security/main - name = "\improper Security Office" - icon_state = "securityoffice" - request_console_flags = RC_ASSIST | RC_INFO - request_console_name = "Security" - -/area/station/security/lobby - name = "\improper Security Lobby" - icon_state = "securitylobby" - -/area/station/security/brig - name = "\improper Brig" - icon_state = "brig" - request_console_flags = RC_ASSIST | RC_INFO - request_console_name = "Security" - -/area/station/security/brig/prison_break() - for(var/obj/structure/closet/secure_closet/brig/temp_closet in src) - temp_closet.locked = FALSE - temp_closet.close() - for(var/obj/machinery/door_timer/temp_timer in src) - temp_timer.releasetime = 1 - ..() - -/area/station/security/permabrig - name = "\improper Prison Wing" - icon_state = "sec_prison_perma" - fast_despawn = TRUE - can_get_auto_cryod = FALSE - -/area/station/security/prison - name = "\improper Prison Wing" - icon_state = "sec_prison" - can_get_auto_cryod = FALSE - -/area/station/security/prison/prison_break() - for(var/obj/structure/closet/secure_closet/brig/temp_closet in src) - temp_closet.locked = FALSE - temp_closet.close() - temp_closet.update_icon() - for(var/obj/machinery/door_timer/temp_timer in src) - temp_timer.releasetime = 1 - ..() - -/area/station/security/prison/cell_block - name = "\improper Prison Cell Block" - icon_state = "brig" - -/area/station/security/prison/cell_block/a - name = "\improper Prison Cell Block A" - icon_state = "brigcella" - -/area/station/security/execution - name = "Execution" - icon_state = "execution" - can_get_auto_cryod = FALSE - -/area/station/security/processing - name = "Prisoner Processing" - icon_state = "prisonerprocessing" - can_get_auto_cryod = FALSE - -/area/station/security/interrogation - name = "Interrogation" - icon_state = "interrogation" - can_get_auto_cryod = FALSE - -/area/station/security/storage - name = "Security Equipment Storage" - icon_state = "securityequipmentstorage" - request_console_flags = RC_ASSIST | RC_INFO - request_console_name = "Security" - -/area/station/security/evidence - name = "\improper Evidence Room" - icon_state = "evidence" - -/area/station/security/prisonlockers - name = "\improper Prisoner Lockers" - icon_state = "sec_prison_lockers" - can_get_auto_cryod = FALSE - -/area/station/security/prisonershuttle - name = "\improper Security Prisoner Shuttle" - icon_state = "security" - can_get_auto_cryod = FALSE - -/area/station/security/warden - name = "\improper Warden's Office" - icon_state = "Warden" - sound_environment = SOUND_AREA_SMALL_SOFTFLOOR - request_console_flags = RC_ASSIST | RC_SUPPLY | RC_INFO - request_console_name = "Warden" - -/area/station/security/armory - name = "\improper Armory" - icon_state = "armory" - -/area/station/security/armory/secure - name = "\improper Secure Armory" - icon_state = "secarmory" - request_console_flags = RC_ASSIST | RC_SUPPLY | RC_INFO - request_console_name = "Warden" - -/area/station/security/detective - name = "\improper Detective's Office" - icon_state = "detective" - ambientsounds = list('sound/ambience/ambidet1.ogg', 'sound/ambience/ambidet2.ogg') - request_console_flags = RC_ASSIST | RC_INFO - request_console_name = "Detective" - -/area/station/security/range - name = "\improper Firing Range" - icon_state = "firingrange" - -/area/station/security/defusal - name = "\improper Defusal Workshop" - icon_state = "defusal" - -// Checkpoints - -/area/station/security/checkpoint - name = "\improper Security Checkpoint" - icon_state = "checkpoint1" - -/area/station/security/checkpoint/secondary - name = "\improper Security Checkpoint" - icon_state = "checkpoint1" - request_console_flags = RC_ASSIST | RC_INFO - request_console_name = "Security" - -// Solitary -/area/station/security/permasolitary - name = "Solitary Confinement" - icon_state = "solitary" diff --git a/code/game/atom/atom_tool_acts.dm b/code/game/atom/atom_tool_acts.dm deleted file mode 100644 index 6c56e5972da84..0000000000000 --- a/code/game/atom/atom_tool_acts.dm +++ /dev/null @@ -1,166 +0,0 @@ -/** - * ## Item interaction - * - * Handles non-combat iteractions of a tool on this atom, - * such as using a tool on a wall to deconstruct it, - * or scanning someone with a health analyzer - */ -/atom/proc/base_item_interaction(mob/living/user, obj/item/tool, list/modifiers) - SHOULD_CALL_PARENT(TRUE) - PROTECTED_PROC(TRUE) - - // We do not have a combat mode or secondary actions like /tg/, so instead - // I'm unilaterally deciding it here: If you are not on harm intent, tool - // interactions are not attacks. Shit like the autolathe accepting - // screwdrivers on harm intent is unintuitive and needs to go away, and there - // are dozens of ${TOOL}_act procs that do constant harm intent checks. - var/tool_return = tool_act(user, tool, modifiers) - if(tool_return) - return tool_return - - var/early_sig_return = NONE - /* - * This is intentionally using `||` instead of `|` to short-circuit the signal calls - * This is because we want to return early if ANY of these signals return a value - * - * This puts priority on the atom's signals, then the tool's signals, then the user's signals - */ - early_sig_return = SEND_SIGNAL(src, COMSIG_INTERACT_TARGET, user, tool, modifiers) \ - || SEND_SIGNAL(tool, COMSIG_INTERACTING, user, src, modifiers) \ - || SEND_SIGNAL(user, COMSIG_INTERACT_USER, src, tool, modifiers) - - if(early_sig_return) - return early_sig_return - - if(new_attack_chain) - var/self_interaction = item_interaction(user, tool, modifiers) - if(self_interaction) - return self_interaction - - if(tool.new_attack_chain) - var/interact_return = tool.interact_with_atom(src, user, modifiers) - if(interact_return) - return interact_return - - return NONE - -/** - * - * ## Tool Act - * - * Handles using specific tools on this atom directly. - * - * Handles the tool_acts in particular, such as wrenches and screwdrivers. - * - * This can be overriden to handle unique "tool interactions" - * IE using an item like a tool (when it's not actually one) - * but otherwise does nothing that [item_interaction] doesn't already do. - * - * In other words, use sparingly. It's harder to use (correctly) than [item_interaction]. - */ -/atom/proc/tool_act(mob/living/user, obj/item/tool, list/modifiers) - SHOULD_CALL_PARENT(TRUE) - PROTECTED_PROC(TRUE) - - if(SEND_SIGNAL(src, COMSIG_TOOL_ATTACK, tool, user) & COMPONENT_CANCEL_TOOLACT) - return FALSE - - var/tool_type = tool.tool_behaviour - if(!tool_type) - return NONE - - var/act_result = NONE // or FALSE, or null, as some things may return - - switch(tool_type) - if(TOOL_CROWBAR) - act_result = crowbar_act(user, tool) - if(TOOL_MULTITOOL) - act_result = multitool_act(user, tool) - if(TOOL_SCREWDRIVER) - act_result = screwdriver_act(user, tool) - if(TOOL_WRENCH) - act_result = wrench_act(user, tool) - if(TOOL_WIRECUTTER) - act_result = wirecutter_act(user, tool) - if(TOOL_WELDER) - act_result = welder_act(user, tool) - - if(!act_result) - return NONE - - return act_result - -/** - * Called when this atom has an item used on it. - * IE, a mob is clicking on this atom with an item. - * - * Return an ITEM_INTERACT_ flag in the event the interaction was handled, to cancel further interaction code. - * Return NONE to allow default interaction / tool handling. - */ -/atom/proc/item_interaction(mob/living/user, obj/item/used, list/modifiers) - return NONE - -/** - * Called when this item is being used to interact with an atom, - * IE, a mob is clicking on an atom with this item. - * - * Return an ITEM_INTERACT_ flag in the event the interaction was handled, to cancel further interaction code. - * Return NONE to allow default interaction / tool handling. - */ -/obj/item/proc/interact_with_atom(atom/target, mob/living/user, list/modifiers) - return NONE - -/** - * ## Ranged item interaction - * - * Handles non-combat ranged interactions of a tool on this atom, - * such as shooting a gun in the direction of someone*, - * having a scanner you can point at someone to scan them at any distance, - * or pointing a laser pointer at something. - * - * *While this intuitively sounds combat related, it is not, - * because a "combat use" of a gun is gun-butting. - */ -/atom/proc/base_ranged_item_interaction(mob/living/user, obj/item/tool, list/modifiers) - SHOULD_CALL_PARENT(TRUE) - PROTECTED_PROC(TRUE) - - // See [base_item_interaction] for defails on why this is using `||` (TL;DR it's short circuiting) - var/early_sig_return = SEND_SIGNAL(src, COMSIG_INTERACT_RANGED, user, tool, modifiers) \ - || SEND_SIGNAL(tool, COMSIG_INTERACTING_RANGED, user, src, modifiers) - - if(early_sig_return) - return early_sig_return - - var/self_interaction = ranged_item_interaction(user, tool, modifiers) - if(self_interaction) - return self_interaction - - var/interact_return = tool.ranged_interact_with_atom(src, user, modifiers) - if(interact_return) - return interact_return - - return NONE - -/** - * Called when this atom has an item used on it from a distance. - * IE, a mob is clicking on this atom with an item and is not adjacent. - * - * Does NOT include Telekinesis users, they are considered adjacent generally. - * - * Return an ITEM_INTERACT_ flag in the event the interaction was handled, to cancel further interaction code. - */ -/atom/proc/ranged_item_interaction(mob/living/user, obj/item/tool, list/modifiers) - return NONE - -/** - * Called when this item is being used to interact with an atom from a distance, - * IE, a mob is clicking on an atom with this item and is not adjacent. - * - * Does NOT include Telekinesis users, they are considered adjacent generally - * (so long as this item is adjacent to the atom). - * - * Return an ITEM_INTERACT_ flag in the event the interaction was handled, to cancel further interaction code. - */ -/obj/item/proc/ranged_interact_with_atom(atom/target, mob/living/user, list/modifiers) - return NONE diff --git a/code/game/dna/mutations/monkey_mutation.dm b/code/game/dna/mutations/monkey_mutation.dm deleted file mode 100644 index e731abe19fe5d..0000000000000 --- a/code/game/dna/mutations/monkey_mutation.dm +++ /dev/null @@ -1,79 +0,0 @@ -/datum/mutation/monkey - name = "Monkey" - -/datum/mutation/monkey/New() - ..() - block = GLOB.monkeyblock - -/datum/mutation/monkey/can_activate(mob/M, flags) - return ishuman(M) - -/datum/mutation/monkey/activate(mob/living/carbon/human/H) - ..() - if(!istype(H)) - return - if(issmall(H)) - return - for(var/obj/item/W in H) - if(istype(W, /obj/item/bio_chip)) - continue - H.drop_item_to_ground(W) - - H.regenerate_icons() - ADD_TRAIT(H, TRAIT_IMMOBILIZED, TRANSFORMING_TRAIT) - ADD_TRAIT(H, TRAIT_HANDS_BLOCKED, TRANSFORMING_TRAIT) - H.icon = null - H.invisibility = 101 - var/has_primitive_form = H.dna.species.primitive_form // cache this - if(has_primitive_form) - H.set_species(has_primitive_form, keep_missing_bodyparts = TRUE) - - new /obj/effect/temp_visual/monkeyify(H.loc) - addtimer(CALLBACK(src, PROC_REF(finish_monkeyize), H, !has_primitive_form), 2.2 SECONDS) - -/datum/mutation/monkey/proc/finish_monkeyize(mob/living/carbon/human/H, should_gib) - H.invisibility = initial(H.invisibility) - - if(should_gib) //If the pre-change mob in question has no primitive set, this is going to be messy. - H.gib() - return - REMOVE_TRAITS_IN(H, TRANSFORMING_TRAIT) - to_chat(H, "You are now a [H.dna.species.name].") - -/datum/mutation/monkey/deactivate(mob/living/carbon/human/H) - ..() - if(!istype(H)) - return - if(!issmall(H)) - return - for(var/obj/item/W in H) - if(W == H.w_uniform) // will be torn - continue - if(istype(W, /obj/item/bio_chip)) - continue - H.drop_item_to_ground(W) - H.regenerate_icons() - ADD_TRAIT(H, TRAIT_IMMOBILIZED, TRANSFORMING_TRAIT) - ADD_TRAIT(H, TRAIT_HANDS_BLOCKED, TRANSFORMING_TRAIT) - H.icon = null - H.invisibility = 101 - var/has_greater_form = H.dna.species.greater_form //cache this - if(has_greater_form) - H.set_species(has_greater_form, keep_missing_bodyparts = TRUE) - - new /obj/effect/temp_visual/monkeyify/humanify(H.loc) - addtimer(CALLBACK(src, PROC_REF(finish_unmonkeyize), H, !has_greater_form), 2.2 SECONDS) - -/datum/mutation/monkey/proc/finish_unmonkeyize(mob/living/carbon/human/H, should_gib) - REMOVE_TRAITS_IN(H, TRANSFORMING_TRAIT) - H.invisibility = initial(H.invisibility) - - if(should_gib) //If the pre-change mob in question has no primitive set, this is going to be messy. - H.gib() - return - - H.real_name = H.dna.real_name - H.name = H.real_name - - to_chat(H, "You are now a [H.dna.species.name].") - diff --git a/code/game/dna/mutations/mutation_powers.dm b/code/game/dna/mutations/mutation_powers.dm deleted file mode 100644 index e13572621a01c..0000000000000 --- a/code/game/dna/mutations/mutation_powers.dm +++ /dev/null @@ -1,1208 +0,0 @@ -/////////////////////////////////// -// POWERS -/////////////////////////////////// - -/datum/mutation/nobreath - name = "No Breathing" - activation_messages = list("You feel no need to breathe.") - deactivation_messages = list("You feel the need to breathe, once more.") - instability = GENE_INSTABILITY_MAJOR - traits_to_add = list(TRAIT_NOBREATH) - -/datum/mutation/nobreath/New() - ..() - block = GLOB.breathlessblock - - -/datum/mutation/regenerate - name = "Regenerate" - activation_messages = list("Your wounds start healing.") - deactivation_messages = list("Your regenerative powers feel like they've vanished.") - instability = GENE_INSTABILITY_MINOR - -/datum/mutation/regenerate/New() - ..() - block = GLOB.regenerateblock - -/datum/mutation/regenerate/on_life(mob/living/carbon/human/H) - if(!H.ignore_gene_stability && H.gene_stability < GENETIC_DAMAGE_STAGE_1) - H.adjustBruteLoss(-0.25, FALSE) - H.adjustFireLoss(-0.25) - return - H.adjustBruteLoss(-1, FALSE) - H.adjustFireLoss(-1) - -/datum/mutation/heat_resist - name = "Heat Resistance" - activation_messages = list("Your skin is icy to the touch.") - deactivation_messages = list("Your skin no longer feels icy to the touch.") - instability = GENE_INSTABILITY_MODERATE - traits_to_add = list(TRAIT_RESISTHEAT, TRAIT_RESISTHIGHPRESSURE) - -/datum/mutation/heat_resist/New() - ..() - block = GLOB.coldblock - -/datum/mutation/heat_resist/on_draw_underlays(mob/M, g) - return "cold_s" - -/datum/mutation/cold_resist - name = "Cold Resistance" - activation_messages = list("Your body is filled with warmth.") - deactivation_messages = list("Your body is no longer filled with warmth.") - instability = GENE_INSTABILITY_MODERATE - traits_to_add = list(TRAIT_RESISTCOLD, TRAIT_RESISTLOWPRESSURE) - -/datum/mutation/cold_resist/New() - ..() - block = GLOB.fireblock - -/datum/mutation/cold_resist/on_draw_underlays(mob/M, g) - return "fire_s" - -/datum/mutation/noprints - name = "No Prints" - activation_messages = list("Your fingers feel numb.") - deactivation_messages = list("Your fingers no longer feel numb.") - instability = GENE_INSTABILITY_MODERATE - traits_to_add = list(TRAIT_NOFINGERPRINTS) - -/datum/mutation/noprints/New() - ..() - block = GLOB.noprintsblock - -/datum/mutation/noshock - name = "Shock Immunity" - activation_messages = list("Your skin feels dry and unreactive.") - deactivation_messages = list("Your skin no longer feels dry and unreactive.") - instability = GENE_INSTABILITY_MODERATE - traits_to_add = list(TRAIT_SHOCKIMMUNE) - -/datum/mutation/noshock/New() - ..() - block = GLOB.shockimmunityblock - -/datum/mutation/dwarf - name = "Dwarf" - activation_messages = list("Everything around you seems bigger now...") - deactivation_messages = list("Everything around you seems to shrink...") - instability = GENE_INSTABILITY_MODERATE - traits_to_add = list(TRAIT_DWARF) - -/datum/mutation/dwarf/New() - ..() - block = GLOB.smallsizeblock - -/datum/mutation/dwarf/activate(mob/M) - ..() - M.pass_flags |= PASSTABLE - M.resize = 0.8 - M.update_transform() - -/datum/mutation/dwarf/deactivate(mob/M) - ..() - M.pass_flags &= ~PASSTABLE - M.resize = 1.25 - M.update_transform() - -// OLD HULK BEHAVIOR -/datum/mutation/hulk - name = "Hulk" - activation_messages = list("Your muscles hurt.") - deactivation_messages = list("Your muscles shrink.") - instability = GENE_INSTABILITY_MAJOR - traits_to_add = list(TRAIT_HULK, TRAIT_CHUNKYFINGERS) - -/datum/mutation/hulk/New() - ..() - block = GLOB.hulkblock - -/datum/mutation/hulk/activate(mob/living/carbon/human/M) - ..() - var/status = CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH - M.status_flags &= ~status - M.update_body() - -/datum/mutation/hulk/deactivate(mob/living/carbon/human/M) - ..() - M.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH - M.update_body() - -/datum/mutation/hulk/on_life(mob/living/carbon/human/M) - if(!istype(M)) - return - if(M.health <= 0) - M.dna.SetSEState(GLOB.hulkblock, 0) - singlemutcheck(M, GLOB.hulkblock, MUTCHK_FORCED) - M.update_mutations() //update our mutation overlays - M.update_body() - M.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH //temporary fix until the problem can be solved. - to_chat(M, "You suddenly feel very weak.") - -/datum/mutation/tk - name = "Telekenesis" - activation_messages = list("You feel smarter.") - deactivation_messages = list("You feel dumber.") - instability = GENE_INSTABILITY_MAJOR - traits_to_add = list(TRAIT_TELEKINESIS) - -/datum/mutation/tk/New() - ..() - block = GLOB.teleblock - -/datum/mutation/tk/on_draw_underlays(mob/M, g) - return "telekinesishead_s" - -#define EAT_MOB_DELAY 300 // 30s - -// WAS: /datum/bioEffect/alcres -/datum/mutation/sober - name = "Sober" - activation_messages = list("You feel unusually sober.") - deactivation_messages = list("You feel like you could use a stiff drink.") - instability = GENE_INSTABILITY_MINOR - - traits_to_add = list(TRAIT_ALCOHOL_TOLERANCE) - -/datum/mutation/sober/New() - ..() - block = GLOB.soberblock - -//WAS: /datum/bioEffect/psychic_resist -/datum/mutation/psychic_resist - name = "Psy-Resist" - desc = "Boosts efficiency in sectors of the brain commonly associated with meta-mental energies." - activation_messages = list("Your mind feels closed.") - deactivation_messages = list("You feel oddly exposed.") - instability = GENE_INSTABILITY_MINOR - -/datum/mutation/psychic_resist/New() - ..() - block = GLOB.psyresistblock - -///////////////////////// -// Stealth Enhancers -///////////////////////// - -/datum/mutation/stealth - instability = GENE_INSTABILITY_MAJOR - -/datum/mutation/stealth/can_activate(mob/M, flags) - // Can only activate one of these at a time. - if(is_type_in_list(/datum/mutation/stealth, M.active_mutations)) - testing("Cannot activate [type]: /datum/mutation/stealth in M.active_mutations.") - return FALSE - return ..() - -/datum/mutation/stealth/deactivate(mob/living/M) - ..() - M.reset_visibility() - -// WAS: /datum/bioEffect/darkcloak -/datum/mutation/stealth/darkcloak - name = "Cloak of Darkness" - desc = "Enables the subject to bend low levels of light around themselves, creating a cloaking effect." - activation_messages = list("You begin to fade into the shadows.") - deactivation_messages = list("You become fully visible.") - -/datum/mutation/stealth/darkcloak/New() - ..() - block = GLOB.shadowblock - -/datum/mutation/stealth/darkcloak/deactivate(mob/living/M) - ..() - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.set_alpha_tracking(ALPHA_VISIBLE, src) - if(!ishuman(M)) - return - var/mob/living/carbon/human/H = M - H.set_alpha_tracking(ALPHA_VISIBLE, src) -/datum/mutation/stealth/darkcloak/on_life(mob/M) - var/turf/simulated/T = get_turf(M) - if(!istype(T) || !ishuman(M)) - return - var/mob/living/carbon/human/H = M - var/light_available = T.get_lumcount() * 10 - if(light_available <= 2) - if(H.invisibility != INVISIBILITY_LEVEL_TWO) - H.set_alpha_tracking(H.get_alpha() * 0.8, src) - else - H.reset_visibility() - H.set_alpha_tracking(ALPHA_VISIBLE * 0.8, src) - if(H.get_alpha(src) == 0) - H.make_invisible() - -//WAS: /datum/bioEffect/chameleon -/datum/mutation/stealth/chameleon - name = "Chameleon" - desc = "The subject becomes able to subtly alter light patterns to become invisible, as long as they remain still." - activation_messages = list("You feel one with your surroundings.") - deactivation_messages = list("You feel oddly visible.") - -/datum/mutation/stealth/chameleon/New() - ..() - block = GLOB.chameleonblock - -/datum/mutation/stealth/chameleon/deactivate(mob/living/M) - ..() - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.set_alpha_tracking(ALPHA_VISIBLE, src) - -/datum/mutation/stealth/chameleon/on_life(mob/living/M) - if(!ishuman(M)) - return - var/mob/living/carbon/human/H = M - if((world.time - H.last_movement) >= 30 && !H.stat && (H.mobility_flags & MOBILITY_STAND) && !H.restrained()) - if(H.invisibility != INVISIBILITY_LEVEL_TWO) - H.set_alpha_tracking(H.get_alpha() - 25, src) - else - H.reset_visibility() - H.set_alpha_tracking(ALPHA_VISIBLE * 0.8, src) - if(H.get_alpha(src) == 0) - H.make_invisible() - -///////////////////////////////////////////////////////////////////////////////////////// - -/datum/mutation/grant_spell - var/datum/spell/spelltype - -/datum/mutation/grant_spell/activate(mob/M) - M.AddSpell(new spelltype(null)) - ..() - return TRUE - -/datum/mutation/grant_spell/deactivate(mob/M) - for(var/datum/spell/S in M.mob_spell_list) - if(istype(S, spelltype)) - M.RemoveSpell(S) - ..() - return TRUE - -// WAS: /datum/bioEffect/cryokinesis -/datum/mutation/grant_spell/cryo - name = "Cryokinesis" - desc = "Allows the subject to lower the body temperature of others." - activation_messages = list("You notice a strange cold tingle in your fingertips.") - deactivation_messages = list("Your fingers feel warmer.") - instability = GENE_INSTABILITY_MODERATE - spelltype = /datum/spell/cryokinesis - -/datum/mutation/grant_spell/cryo/New() - ..() - block = GLOB.cryoblock - -/datum/spell/cryokinesis - name = "Cryokinesis" - desc = "Drops the bodytemperature of another person." - - base_cooldown = 1200 - - clothes_req = FALSE - stat_allowed = CONSCIOUS - antimagic_flags = NONE - - selection_activated_message = "Your mind grow cold. Click on a target to cast the spell." - selection_deactivated_message = "Your mind returns to normal." - invocation_type = "none" - var/list/compatible_mobs = list(/mob/living/carbon/human) - - action_icon_state = "genetic_cryo" - -/datum/spell/cryokinesis/create_new_targeting() - var/datum/spell_targeting/click/T = new() - T.allowed_type = /mob/living/carbon - T.click_radius = 0 - T.try_auto_target = FALSE // Give the clueless geneticists a way out and to have them not target themselves - T.selection_type = SPELL_SELECTION_RANGE - T.include_user = TRUE - return T - -/datum/spell/cryokinesis/cast(list/targets, mob/user = usr) - - var/mob/living/carbon/C = targets[1] - - if(HAS_TRAIT(C, TRAIT_RESISTCOLD)) - C.visible_message("A cloud of fine ice crystals engulfs [C.name], but disappears almost instantly!") - return - var/handle_suit = FALSE - if(ishuman(C)) - var/mob/living/carbon/human/H = C - if(istype(H.head, /obj/item/clothing/head/helmet/space)) - if(istype(H.wear_suit, /obj/item/clothing/suit/space)) - handle_suit = TRUE - if(H.internal) - H.visible_message("[user] sprays a cloud of fine ice crystals, engulfing [H]!", - "[user] sprays a cloud of fine ice crystals over your [H.head]'s visor.") - else - H.visible_message("[user] sprays a cloud of fine ice crystals engulfing, [H]!", - "[user] sprays a cloud of fine ice crystals cover your [H.head]'s visor and make it into your air vents!.") - - H.bodytemperature = max(0, H.bodytemperature - 100) - add_attack_logs(user, C, "Cryokinesis") - if(!handle_suit) - C.bodytemperature = max(0, C.bodytemperature - 200) - C.ExtinguishMob() - - C.visible_message("[user] sprays a cloud of fine ice crystals, engulfing [C]!") - add_attack_logs(user, C, "Cryokinesis- NO SUIT/INTERNALS") - -/////////////////////////////////////////////////////////////////////////////////////////// - -// WAS: /datum/bioEffect/mattereater -/datum/mutation/grant_spell/mattereater - name = "Matter Eater" - desc = "Allows the subject to eat just about anything without harm." - activation_messages = list("You feel hungry.") - deactivation_messages = list("You don't feel quite so hungry anymore.") - instability = GENE_INSTABILITY_MODERATE - - spelltype=/datum/spell/eat - -/datum/mutation/grant_spell/mattereater/New() - ..() - block = GLOB.eatblock - -/datum/spell/eat - name = "Eat" - desc = "Eat just about anything!" - - base_cooldown = 300 - - clothes_req = FALSE - stat_allowed = CONSCIOUS - invocation_type = "none" - antimagic_flags = NONE - - action_icon_state = "genetic_eat" - -/datum/spell/eat/create_new_targeting() - return new /datum/spell_targeting/matter_eater - -/datum/spell/eat/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE) - . = ..() - if(!.) - return - var/can_eat = TRUE - if(iscarbon(user)) - var/mob/living/carbon/C = user - if((C.head && (C.head.flags_cover & HEADCOVERSMOUTH)) || (C.wear_mask && (C.wear_mask.flags_cover & MASKCOVERSMOUTH) && !C.wear_mask.up)) - if(show_message) - to_chat(C, "Your mouth is covered, preventing you from eating!") - can_eat = FALSE - return can_eat - -/datum/spell/eat/proc/doHeal(mob/user) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - for(var/name in H.bodyparts_by_name) - var/obj/item/organ/external/affecting = null - if(!H.bodyparts_by_name[name]) - continue - affecting = H.bodyparts_by_name[name] - if(!is_external_organ(affecting)) - continue - affecting.heal_damage(4, 0, updating_health = FALSE) - H.UpdateDamageIcon() - H.updatehealth() - - - -/datum/spell/eat/cast(list/targets, mob/user = usr) - if(!length(targets)) - to_chat(user, "No target found in range.") - return - - var/atom/movable/the_item = targets[1] - if(!user.Adjacent(the_item)) - to_chat(user, "You need to be next to [the_item] for this!") - return FALSE - if(ishuman(the_item)) - var/mob/living/carbon/human/H = the_item - var/obj/item/organ/external/limb = H.get_organ(user.zone_selected) - if(!istype(limb)) - to_chat(user, "You can't eat this part of them!") - revert_cast() - return FALSE - if(istype(limb,/obj/item/organ/external/head)) - // Bullshit, but prevents being unable to clone someone. - to_chat(user, "You try to put \the [limb] in your mouth, but [the_item.p_their()] ears tickle your throat!") - revert_cast() - return FALSE - if(istype(limb,/obj/item/organ/external/chest)) - // Bullshit, but prevents being able to instagib someone. - to_chat(user, "You try to put [the_item.p_their()] [limb] in your mouth, but it's too big to fit!") - revert_cast() - return FALSE - user.visible_message("[user] begins stuffing [the_item]'s [limb.name] into [user.p_their()] gaping maw!") - if(!do_mob(user, H, EAT_MOB_DELAY)) - to_chat(user, "You were interrupted before you could eat [the_item]!") - else - if(!limb || !H) - return - if(!user.Adjacent(the_item)) - to_chat(user, "You need to be next to [the_item] for this!") - return FALSE - user.visible_message("[user] [pick("chomps","bites")] off [the_item]'s [limb]!") - playsound(user.loc, 'sound/items/eatfood.ogg', 50, 0) - - // Most limbs will drop here. Groin won't, but this - // still spills out the organs that were in it. - limb.droplimb(FALSE, DROPLIMB_SHARP) - if(istype(limb, /obj/item/organ/external/groin)) - limb.receive_damage(100, sharp = TRUE) - - var/obj/item/organ/external/left_leg = H.get_organ(BODY_ZONE_L_LEG) - if(istype(left_leg)) - left_leg.droplimb(FALSE, DROPLIMB_SHARP) - - var/obj/item/organ/external/right_leg = H.get_organ(BODY_ZONE_R_LEG) - if(istype(right_leg)) - right_leg.droplimb(FALSE, DROPLIMB_SHARP) - - var/obj/item/organ/external/chest = H.get_organ(BODY_ZONE_CHEST) - if(istype(chest)) - chest.receive_damage(50, sharp = TRUE) - - doHeal(user) - - return - - if(ismob(the_item.loc) && isitem(the_item)) - var/obj/item/eaten = the_item - var/mob/the_owner = the_item.loc - if(!the_owner.drop_item_to_ground(eaten, silent = TRUE)) - to_chat(user, "You can't eat [the_item], it won't go down your throat!") - return - user.visible_message("[user] eats [the_item].") - playsound(user.loc, 'sound/items/eatfood.ogg', 50, FALSE) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - var/obj/item/organ/external/chest/target_place = H.get_organ(BODY_ZONE_CHEST) - if(istype(target_place)) - the_item.forceMove(target_place) - doHeal(user) - return - - qdel(the_item) - doHeal(user) - -//////////////////////////////////////////////////////////////////////// - -//WAS: /datum/bioEffect/jumpy -/datum/mutation/grant_spell/jumpy - name = "Jumpy" - desc = "Allows the subject to leap great distances." - //cooldown = 30 - activation_messages = list("Your leg muscles feel taut and strong.") - deactivation_messages = list("Your leg muscles shrink back to normal.") - instability = GENE_INSTABILITY_MODERATE - - spelltype =/datum/spell/leap - -/datum/mutation/grant_spell/jumpy/New() - ..() - block = GLOB.jumpblock - -/datum/spell/leap - name = "Jump" - desc = "Leap great distances!" - base_cooldown = 60 - - clothes_req = FALSE - stat_allowed = CONSCIOUS - invocation_type = "none" - antimagic_flags = NONE - - action_icon_state = "genetic_jump" - var/leap_distance = 10 - -/datum/spell/leap/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/leap/cast(list/targets, mob/living/user = usr) - var/failure = FALSE - if(ismob(user.loc) || IS_HORIZONTAL(user) || user.IsStunned() || user.buckled || user.stat) - to_chat(user, "You can't jump right now!") - return - - if(isturf(user.loc)) - if(user.restrained())//Why being pulled while cuffed prevents you from moving - for(var/mob/living/M in range(user, 1)) - if(M.pulling == user) - if(!M.restrained() && M.stat == CONSCIOUS && !(M.mobility_flags & MOBILITY_STAND) && user.Adjacent(M)) - failure = TRUE - else - M.stop_pulling() - - user.visible_message("[user.name] takes a huge leap!") - playsound(user.loc, 'sound/weapons/thudswoosh.ogg', 50, 1) - if(failure) - user.Weaken(10 SECONDS) - user.visible_message("[user] attempts to leap away but is slammed back down to the ground!", - "You attempt to leap away but are suddenly slammed back down to the ground!", - "You hear the flexing of powerful muscles and suddenly a crash as a body hits the floor.") - return FALSE - var/prevLayer = user.layer - user.layer = 9 - - ADD_TRAIT(user, TRAIT_FLYING, "leap") - for(var/i in 1 to leap_distance) - var/turf/hit_turf = get_step(user, user.dir) - var/atom/hit_atom = get_blocking_atom(hit_turf) - if(hit_atom) - hit_atom.hit_by_thrown_mob(user, damage = 10) - break - - step(user, user.dir) - if(i < 6) - user.pixel_y += 8 - else - user.pixel_y -= 8 - sleep(1) - - REMOVE_TRAIT(user, TRAIT_FLYING, "leap") - user.pixel_y = 0 // In case leap was varedited to be longer or shorter - - if(HAS_TRAIT(user, TRAIT_FAT) && prob(66)) - user.visible_message("[user.name] crashes due to [user.p_their()] heavy weight!") - //playsound(user.loc, 'zhit.wav', 50, 1) - user.AdjustWeakened(20 SECONDS) - user.AdjustStunned(10 SECONDS) - - user.layer = prevLayer - - if(isobj(user.loc)) - var/obj/container = user.loc - to_chat(user, "You leap and slam your head against the inside of [container]! Ouch!") - user.AdjustParalysis(6 SECONDS) - user.AdjustWeakened(10 SECONDS) - container.visible_message("[user.loc] emits a loud thump and rattles a bit.") - playsound(user.loc, 'sound/effects/bang.ogg', 50, 1) - var/wiggle = 6 - while(wiggle > 0) - wiggle-- - container.pixel_x = rand(-3,3) - container.pixel_y = rand(-3,3) - sleep(1) - container.pixel_x = 0 - container.pixel_y = 0 - -/datum/spell/leap/proc/get_blocking_atom(turf/turf_to_check) - if(!turf_to_check) - return FALSE - - if(turf_to_check.density) - return turf_to_check - - for(var/atom/movable/hit_thing in turf_to_check) - if(isliving(hit_thing)) - var/mob/living/hit_mob = hit_thing - if(hit_mob.density) - return hit_mob - - if(isobj(hit_thing)) - var/obj/hit_obj = hit_thing - if(hit_obj.density) - return hit_obj - - return FALSE - -//////////////////////////////////////////////////////////////////////// - -// WAS: /datum/bioEffect/polymorphism - -/datum/mutation/grant_spell/polymorph - name = "Polymorphism" - desc = "Enables the subject to reconfigure their appearance to mimic that of others." - - spelltype =/datum/spell/polymorph - //cooldown = 1800 - activation_messages = list("You don't feel entirely like yourself somehow.") - deactivation_messages = list("You feel secure in your identity.") - instability = GENE_INSTABILITY_MODERATE - -/datum/mutation/grant_spell/polymorph/New() - ..() - block = GLOB.polymorphblock - -/datum/spell/polymorph - name = "Polymorph" - desc = "Mimic the appearance of others!" - base_cooldown = 1800 - - clothes_req = FALSE - stat_allowed = CONSCIOUS - - selection_activated_message = "You body becomes unstable. Click on a target to cast transform into them." - selection_deactivated_message = "Your body calms down again." - - invocation_type = "none" - antimagic_flags = NONE - - action_icon_state = "genetic_poly" - -/datum/spell/polymorph/create_new_targeting() - var/datum/spell_targeting/click/T = new() - T.try_auto_target = FALSE - T.click_radius = -1 - T.range = 1 - T.selection_type = SPELL_SELECTION_RANGE - return T - -/datum/spell/polymorph/cast(list/targets, mob/user = usr) - var/mob/living/carbon/human/target = targets[1] - - user.visible_message("[user]'s body shifts and contorts.") - - spawn(10) - if(target && user) - playsound(user.loc, 'sound/goonstation/effects/gib.ogg', 50, 1) - var/mob/living/carbon/human/H = user - H.UpdateAppearance(target.dna.UI) - H.real_name = target.real_name - H.name = target.name - -//////////////////////////////////////////////////////////////////////// - -// WAS: /datum/bioEffect/empath -/datum/mutation/grant_spell/empath - name = "Empathic Thought" - desc = "The subject becomes able to read the minds of others for certain information." - - spelltype = /datum/spell/empath - activation_messages = list("You suddenly notice more about others than you did before.") - deactivation_messages = list("You no longer feel able to sense intentions.") - instability = GENE_INSTABILITY_MINOR - -/datum/mutation/grant_spell/empath/New() - ..() - block = GLOB.empathblock - -/datum/spell/empath - name = "Read Mind" - desc = "Read the minds of others for information." - base_cooldown = 18 SECONDS - clothes_req = FALSE - human_req = TRUE - stat_allowed = CONSCIOUS - invocation_type = "none" - antimagic_flags = MAGIC_RESISTANCE_MIND - - action_icon_state = "genetic_empath" - -/datum/spell/empath/create_new_targeting() - var/datum/spell_targeting/targeted/T = new() - T.allowed_type = /mob/living/carbon - T.selection_type = SPELL_SELECTION_RANGE - return T - -/datum/spell/empath/cast(list/targets, mob/user = usr) - for(var/mob/living/carbon/M in targets) - if(!iscarbon(M)) - to_chat(user, "You may only use this on other organic beings.") - return - - if(M.dna?.GetSEState(GLOB.psyresistblock)) - to_chat(user, "You can't see into [M.name]'s mind at all!") - return - - if(M.stat == DEAD) - to_chat(user, "[M.name] is dead and cannot have [M.p_their()] mind read.") - return - if(M.health < 0) - to_chat(user, "[M.name] is dying, and [M.p_their()] thoughts are too scrambled to read.") - return - - to_chat(user, "Mind Reading of [M.name]:") - - var/pain_condition = M.health / M.maxHealth - // lower health means more pain - var/list/randomthoughts = list("what to have for lunch","the future","the past","money", - "[M.p_their()] hair","what to do next","[M.p_their()] job","space","amusing things","sad things", - "annoying things","happy things","something incoherent","something [M.p_they()] did wrong") - var/thoughts = "thinking about [pick(randomthoughts)]" - - if(M.fire_stacks) - pain_condition -= 0.5 - thoughts = "preoccupied with the fire" - - if(M.radiation) - pain_condition -= 0.25 - - switch(pain_condition) - if(0.81 to INFINITY) - to_chat(user, "Condition: [M.name] feels good.") - if(0.61 to 0.8) - to_chat(user, "Condition: [M.name] is suffering mild pain.") - if(0.41 to 0.6) - to_chat(user, "Condition: [M.name] is suffering significant pain.") - if(0.21 to 0.4) - to_chat(user, "Condition: [M.name] is suffering severe pain.") - else - to_chat(user, "Condition: [M.name] is suffering excruciating pain.") - thoughts = "haunted by [M.p_their()] own mortality" - - switch(M.a_intent) - if(INTENT_HELP) - to_chat(user, "Mood: You sense benevolent thoughts from [M.name].") - if(INTENT_DISARM) - to_chat(user, "Mood: You sense cautious thoughts from [M.name].") - if(INTENT_GRAB) - to_chat(user, "Mood: You sense hostile thoughts from [M.name].") - if(INTENT_HARM) - to_chat(user, "Mood: You sense cruel thoughts from [M.name].") - for(var/mob/living/L in view(7,M)) - if(L == M) - continue - thoughts = "thinking about punching [L.name]" - break - else - to_chat(user, "Mood: You sense strange thoughts from [M.name].") - - if(ishuman(M)) - var/numbers[0] - var/mob/living/carbon/human/H = M - if(H.mind && H.mind.initial_account) - numbers += H.mind.initial_account.account_number - numbers += H.mind.initial_account.account_pin - if(length(numbers)>0) - to_chat(user, "Numbers: You sense the number[length(numbers)>1?"s":""] [english_list(numbers)] [length(numbers)>1?"are":"is"] important to [M.name].") - to_chat(user, "Thoughts: [M.name] is currently [thoughts].") - - if(M.dna?.GetSEState(GLOB.empathblock)) - to_chat(M, "You sense [user.name] reading your mind.") - else if(prob(5) || M.mind?.assigned_role=="Chaplain") - to_chat(M, "You sense someone intruding upon your thoughts...") - -///////////////////Vanilla Morph//////////////////////////////////// - -/datum/mutation/grant_spell/morph - name = "Morphism" - desc = "Enables the subject to reconfigure their appearance to that of any human." - spelltype =/datum/spell/morph - activation_messages = list("Your body feels like it can alter its appearance.") - deactivation_messages = list("Your body doesn't feel capable of altering its appearance.") - instability = GENE_INSTABILITY_MODERATE - -/datum/mutation/grant_spell/morph/New() - ..() - block = GLOB.morphblock - -/datum/spell/morph - name = "Morph" - desc = "Mimic the appearance of your choice!" - base_cooldown = 1800 - - clothes_req = FALSE - stat_allowed = CONSCIOUS - invocation_type = "none" - antimagic_flags = NONE - - action_icon_state = "genetic_morph" - -/datum/spell/morph/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/morph/cast(list/targets, mob/user = usr) - if(!ishuman(user)) - return - - if(ismob(user.loc)) - to_chat(user, "You can't change your appearance right now!") - return - var/mob/living/carbon/human/M = user - var/obj/item/organ/external/head/head_organ = M.get_organ("head") - var/obj/item/organ/internal/eyes/eyes_organ = M.get_int_organ(/obj/item/organ/internal/eyes) - - var/new_gender = tgui_alert(user, "Please select gender.", "Character Generation", list("Male", "Female")) - if(new_gender) - if(new_gender == "Male") - M.change_gender(MALE) - else - M.change_gender(FEMALE) - - if(eyes_organ) - var/new_eyes = tgui_input_color(user, "Please select eye color.", "Character Generation", eyes_organ.eye_color) - if(isnull(new_eyes)) - return - M.change_eye_color(new_eyes) - - if(istype(head_organ)) - //Alt heads. - if(head_organ.dna.species.bodyflags & HAS_ALT_HEADS) - var/list/valid_alt_heads = M.generate_valid_alt_heads() - var/new_alt_head = tgui_input_list(user, "Please select alternate head", "Character Generation", valid_alt_heads) - if(new_alt_head) - M.change_alt_head(new_alt_head) - - // hair - var/list/valid_hairstyles = M.generate_valid_hairstyles() - var/new_style = tgui_input_list(user, "Please select hair style", "Character Generation", valid_hairstyles) - - // if new style selected (not cancel) - if(new_style) - M.change_hair(new_style) - - var/new_hair = tgui_input_color(user, "Please select hair color.", "Character Generation", head_organ.hair_colour) - if(!isnull(new_hair)) - M.change_hair_color(new_hair) - - var/datum/sprite_accessory/hair_style = GLOB.hair_styles_public_list[head_organ.h_style] - if(hair_style.secondary_theme && !hair_style.no_sec_colour) - new_hair = tgui_input_color(user, "Please select secondary hair color.", "Character Generation", head_organ.sec_hair_colour) - if(!isnull(new_hair)) - M.change_hair_color(new_hair, TRUE) - - // facial hair - var/list/valid_facial_hairstyles = M.generate_valid_facial_hairstyles() - new_style = tgui_input_list(user, "Please select facial style", "Character Generation", valid_facial_hairstyles) - - if(new_style) - M.change_facial_hair(new_style) - - var/new_facial = tgui_input_color(user, "Please select facial hair color.", "Character Generation", head_organ.facial_colour) - if(!isnull(new_facial)) - M.change_facial_hair_color(new_facial) - - var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[head_organ.f_style] - if(facial_hair_style.secondary_theme && !facial_hair_style.no_sec_colour) - new_facial = tgui_input_color(user, "Please select secondary facial hair color.", "Character Generation", head_organ.sec_facial_colour) - if(!isnull(new_facial)) - M.change_facial_hair_color(new_facial, TRUE) - - //Head accessory. - if(head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY) - var/list/valid_head_accessories = M.generate_valid_head_accessories() - var/new_head_accessory = tgui_input_list(user, "Please select head accessory style", "Character Generation", valid_head_accessories) - if(!isnull(new_head_accessory)) - M.change_head_accessory(new_head_accessory) - - var/new_head_accessory_colour = tgui_input_color(user, "Please select head accessory color.", "Character Generation", head_organ.headacc_colour) - if(!isnull(new_head_accessory_colour)) - M.change_head_accessory_color(new_head_accessory_colour) - - - //Body accessory. - if((M.dna.species.tail && M.dna.species.bodyflags & (HAS_TAIL)) || (M.dna.species.wing && M.dna.species.bodyflags & (HAS_WING))) - var/list/valid_body_accessories = M.generate_valid_body_accessories() - if(length(valid_body_accessories) > 1) //By default valid_body_accessories will always have at the very least a 'none' entry populating the list, even if the user's species is not present in any of the list items. - var/new_body_accessory = tgui_input_list(user, "Please select body accessory style", "Character Generation", valid_body_accessories) - if(!isnull(new_body_accessory)) - M.change_body_accessory(new_body_accessory) - - if(istype(head_organ)) - //Head markings. - if(M.dna.species.bodyflags & HAS_HEAD_MARKINGS) - var/list/valid_head_markings = M.generate_valid_markings("head") - var/new_marking = tgui_input_list(user, "Please select head marking style", "Character Generation", valid_head_markings) - if(!isnull(new_marking)) - M.change_markings(new_marking, "head") - - var/new_marking_colour = tgui_input_color(user, "Please select head marking color.", "Character Generation", M.m_colours["head"]) - if(!isnull(new_marking_colour)) - M.change_marking_color(new_marking_colour, "head") - - //Body markings. - if(M.dna.species.bodyflags & HAS_BODY_MARKINGS) - var/list/valid_body_markings = M.generate_valid_markings("body") - var/new_marking = tgui_input_list(user, "Please select body marking style", "Character Generation", valid_body_markings) - if(!isnull(new_marking)) - M.change_markings(new_marking, "body") - - var/new_marking_colour = tgui_input_color(user, "Please select body marking color.", "Character Generation", M.m_colours["body"]) - if(!isnull(new_marking_colour)) - M.change_marking_color(new_marking_colour, "body") - //Tail markings. - if(M.dna.species.bodyflags & HAS_TAIL_MARKINGS) - var/list/valid_tail_markings = M.generate_valid_markings("tail") - var/new_marking = tgui_input_list("Please select tail marking style", "Character Generation", valid_tail_markings) - if(!isnull(new_marking)) - M.change_markings(new_marking, "tail") - - var/new_marking_colour = tgui_input_color(user, "Please select tail marking color.", "Character Generation", M.m_colours["tail"]) - if(!isnull(new_marking_colour)) - M.change_marking_color(new_marking_colour, "tail") - - //Skin tone. - if(M.dna.species.bodyflags & HAS_SKIN_TONE) - var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", M.s_tone) as null|text - if(!new_tone) - new_tone = 35 - else - new_tone = 35 - max(min(round(text2num(new_tone)), 220), 1) - M.change_skin_tone(new_tone) - - if(M.dna.species.bodyflags & HAS_ICON_SKIN_TONE) - var/prompt = "Please select skin tone: 1-[length(M.dna.species.icon_skin_tones)] (" - for(var/i = 1 to length(M.dna.species.icon_skin_tones)) - prompt += "[i] = [M.dna.species.icon_skin_tones[i]]" - if(i != length(M.dna.species.icon_skin_tones)) - prompt += ", " - prompt += ")" - - var/new_tone = input(prompt, "Character Generation", M.s_tone) as null|text - if(!new_tone) - new_tone = 0 - else - new_tone = max(min(round(text2num(new_tone)), length(M.dna.species.icon_skin_tones)), 1) - M.change_skin_tone(new_tone) - - //Skin colour. - if(M.dna.species.bodyflags & HAS_SKIN_COLOR) - var/new_body_colour = tgui_input_color(user, "Please select body color.", "Character Generation", M.skin_colour) - if(!isnull(new_body_colour)) - M.change_skin_color(new_body_colour) - - M.update_dna() - - M.visible_message("[M] morphs and changes [M.p_their()] appearance!", "You change your appearance!", "Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!") - -/datum/mutation/grant_spell/remotetalk - name = "Telepathy" - activation_messages = list("You feel you can project your thoughts.") - deactivation_messages = list("You no longer feel you can project your thoughts.") - instability = GENE_INSTABILITY_MINOR - - spelltype =/datum/spell/remotetalk - -/datum/mutation/grant_spell/remotetalk/New() - ..() - block = GLOB.remotetalkblock - -/datum/mutation/grant_spell/remotetalk/activate(mob/living/M) - ..() - M.AddSpell(new /datum/spell/mindscan(null)) - -/datum/mutation/grant_spell/remotetalk/deactivate(mob/user) - ..() - for(var/datum/spell/S in user.mob_spell_list) - if(istype(S, /datum/spell/mindscan)) - user.RemoveSpell(S) - -/datum/spell/remotetalk - name = "Project Mind" - desc = "Make people understand your thoughts!" - base_cooldown = 0 - - clothes_req = FALSE - stat_allowed = CONSCIOUS - invocation_type = "none" - antimagic_flags = MAGIC_RESISTANCE_MIND - - action_icon_state = "genetic_project" - -/datum/spell/remotetalk/create_new_targeting() - return new /datum/spell_targeting/telepathic - -/datum/spell/remotetalk/cast(list/targets, mob/user = usr) - if(!ishuman(user)) - return - if(user.mind?.miming) // Dont let mimes telepathically talk - to_chat(user,"You can't communicate without breaking your vow of silence.") - return - var/say = tgui_input_text(user, "What do you wish to say?", "Project Mind") - if(!say || usr.stat) - return - say = pencode_to_html(say, usr, format = FALSE, fields = FALSE) - - for(var/mob/living/target in targets) - log_say("(TPATH to [key_name(target)]) [say]", user) - user.create_log(SAY_LOG, "Telepathically said '[say]' using [src]", target) - if(target.dna?.GetSEState(GLOB.remotetalkblock)) - target.show_message("You hear [user.real_name]'s voice: [say]") - else - target.show_message("You hear a voice that seems to echo around the room: [say]") - user.show_message("You project your mind into [(target in user.get_visible_mobs()) ? target.name : "the unknown entity"]: [say]") - for(var/mob/dead/observer/G in GLOB.player_list) - G.show_message("Telepathic message from [user] ([ghost_follow_link(user, ghost=G)]) to [target] ([ghost_follow_link(target, ghost=G)]): [say]") - -/datum/spell/mindscan - name = "Scan Mind" - desc = "Offer people a chance to share their thoughts!" - base_cooldown = 0 - clothes_req = FALSE - stat_allowed = CONSCIOUS - antimagic_flags = MAGIC_RESISTANCE_MIND - invocation_type = "none" - action_icon_state = "genetic_mindscan" - var/list/expanded_minds = list() - -/datum/spell/mindscan/create_new_targeting() - return new /datum/spell_targeting/telepathic - -/datum/spell/mindscan/cast(list/targets, mob/user = usr) - if(!ishuman(user)) - return - for(var/mob/living/target in targets) - var/message = "You feel your mind expand briefly... (Click to send a message.)" - if(target.dna?.GetSEState(GLOB.remotetalkblock)) - message = "You feel [user.real_name] request a response from you... (Click here to project mind.)" - user.show_message("You offer your mind to [(target in user.get_visible_mobs()) ? target.name : "the unknown entity"].") - target.show_message("[message]") - expanded_minds += target - addtimer(CALLBACK(src, PROC_REF(removeAvailability), target), 10 SECONDS) - -/datum/spell/mindscan/proc/removeAvailability(mob/living/target) - if(target in expanded_minds) - expanded_minds -= target - if(!(target in expanded_minds)) - target.show_message("You feel the sensation fade...") - -/datum/spell/mindscan/Topic(href, href_list) - var/mob/living/message_source - message_source = locateUID(href_list["from"]) - if(!message_source) - return - if(!message_source || !(message_source in expanded_minds)) - return - - expanded_minds -= message_source - - var/mob/living/message_target = locateUID(href_list["to"]) - if(!message_target) - return - - var/say = tgui_input_text(message_source, "What do you wish to say?", "Expanded Mind") - if(!say) - return - say = pencode_to_html(say, message_source, format = FALSE, fields = FALSE) - - message_source.create_log(SAY_LOG, "Telepathically responded '[say]' using [src]", message_target) - log_say("(TPATH to [key_name(message_target)]) [say]", message_source) - - if(message_source.dna?.GetSEState(GLOB.remotetalkblock)) - message_source.show_message("You project your mind into [message_target]: [say]") - else - message_source.show_message("You fill the space in your thoughts: [say]") - - message_target.show_message("You hear [message_source]'s voice: [say]") - - for(var/mob/dead/observer/G in GLOB.player_list) - G.show_message("Telepathic response from [message_source] ([ghost_follow_link(message_source, ghost=G)]) to [message_target] ([ghost_follow_link(message_target, ghost=G)]): [say]") - -/datum/spell/mindscan/Destroy() - expanded_minds.Cut() - return ..() - -/datum/mutation/grant_spell/remoteview - name = "Remote Viewing" - activation_messages = list("Your mind can see things from afar.") - deactivation_messages = list("Your mind can no longer can see things from afar.") - instability = GENE_INSTABILITY_MINOR - - spelltype =/datum/spell/remoteview - -/datum/mutation/grant_spell/remoteview/New() - ..() - block = GLOB.remoteviewblock - -/datum/mutation/grant_spell/remoteview/deactivate(mob/user) - . = ..() - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.remoteview_target = null - H.reset_perspective() - -/datum/spell/remoteview - name = "Remote View" - desc = "Spy on people from any range!" - base_cooldown = 10 SECONDS - - clothes_req = FALSE - stat_allowed = CONSCIOUS - invocation_type = "none" - antimagic_flags = MAGIC_RESISTANCE_MIND - - action_icon_state = "genetic_view" - -/datum/spell/remoteview/create_new_targeting() - return new /datum/spell_targeting/remoteview - -/datum/spell/remoteview/cast(list/targets, mob/user = usr) - var/mob/living/carbon/human/H - if(ishuman(user)) - H = user - else - return - - var/mob/target - - if(istype(H.l_hand, /obj/item/tk_grab) || istype(H.r_hand, /obj/item/tk_grab)) - to_chat(H, "Your mind is too busy with that telekinetic grab.") - H.remoteview_target = null - H.reset_perspective() - return - - if(H.client.eye != user.client.mob) - H.remoteview_target = null - H.reset_perspective() - return - - for(var/mob/living/L in targets) - target = L - - if(target) - H.remoteview_target = target - H.reset_perspective(target) - else - H.remoteview_target = null - H.reset_perspective() - -/datum/mutation/meson_vision - name = "Meson Vision" - activation_messages = list("More information seems to reach your eyes...") - deactivation_messages = list("The amount of information reaching your eyes fades...") - instability = GENE_INSTABILITY_MINOR - traits_to_add = list(TRAIT_MESON_VISION) - -/datum/mutation/meson_vision/New() - ..() - block = GLOB.mesonblock - -/datum/mutation/meson_vision/activate(mob/living/M) - ..() - M.update_sight() - -/datum/mutation/meson_vision/deactivate(mob/living/M) - ..() - M.update_sight() - -/datum/mutation/night_vision - name = "Night Vision" - activation_messages = list("Were the lights always that bright?") - deactivation_messages = list("The ambient light level returns to normal...") - instability = GENE_INSTABILITY_MODERATE - traits_to_add = list(TRAIT_NIGHT_VISION) - -/datum/mutation/night_vision/New() - ..() - block = GLOB.nightvisionblock - -/datum/mutation/night_vision/activate(mob/living/M) - ..() - M.update_sight() - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.update_misc_effects() - -/datum/mutation/night_vision/deactivate(mob/living/M) - ..() - M.update_sight() - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.update_misc_effects() - -/datum/mutation/flash_protection - name = "Flash Protection" - activation_messages = list("You stop noticing the glare from lights...") - deactivation_messages = list("Lights begin glaring again...") - instability = GENE_INSTABILITY_MODERATE - traits_to_add = list(TRAIT_FLASH_PROTECTION) - -/datum/mutation/flash_protection/New() - ..() - block = GLOB.noflashblock - -#undef EAT_MOB_DELAY diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm deleted file mode 100644 index ee868afd1be82..0000000000000 --- a/code/game/gamemodes/changeling/changeling.dm +++ /dev/null @@ -1,109 +0,0 @@ - -// This list is basically a copy of GLOB.greek_letters, but it also removes letters when a changeling spawns in with that ID -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")) - -/datum/game_mode/changeling - name = "changeling" - config_tag = "changeling" - restricted_jobs = list("AI", "Cyborg") - protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Magistrate", "Internal Affairs Agent", "Nanotrasen Career Trainer", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Trans-Solar Federation General", "Nanotrasen Career Trainer") - species_to_mindflayer = list("Machine") - required_players = 15 - required_enemies = 1 - recommended_enemies = 4 - /// The total number of changelings allowed to be picked. - var/changeling_amount = 4 - -/datum/game_mode/changeling/Destroy(force, ...) - pre_changelings.Cut() - pre_mindflayers.Cut() - return ..() - -/datum/game_mode/changeling/announce() - to_chat(world, "The current game mode is - Changeling!") - to_chat(world, "There are alien changelings on the station. Do not let the changelings succeed!") - -/datum/game_mode/changeling/pre_setup() - if(GLOB.configuration.gamemode.prevent_mindshield_antags) - restricted_jobs += protected_jobs - - var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING) - - changeling_amount = 1 + round(num_players() / 10) - - for(var/i in 1 to changeling_amount) - if(!length(possible_changelings)) - break - var/datum/mind/changeling = pick_n_take(possible_changelings) - changeling.restricted_roles = restricted_jobs - if(changeling.current?.client?.prefs.active_character.species in species_to_mindflayer) - pre_mindflayers += changeling - changeling.special_role = SPECIAL_ROLE_MIND_FLAYER - continue - pre_changelings += changeling - changeling.special_role = SPECIAL_ROLE_CHANGELING - - if(!(length(pre_changelings) + length(pre_mindflayers))) - return FALSE - - return TRUE - -/datum/game_mode/changeling/post_setup() - for(var/datum/mind/changeling as anything in pre_changelings) - changeling.add_antag_datum(/datum/antagonist/changeling) - pre_changelings -= changeling - ..() - -/datum/game_mode/proc/auto_declare_completion_changeling() - if(length(changelings)) - var/list/text = list("The changelings were:") - for(var/datum/mind/changeling in changelings) - var/changelingwin = TRUE - - text += "
    [changeling.get_display_key()] was [changeling.name] (" - if(changeling.current) - if(changeling.current.stat == DEAD) - text += "died" - else - text += "survived" - if(changeling.current.real_name != changeling.name) - text += " as [changeling.current.real_name]" - else - text += "body destroyed" - changelingwin = FALSE - text += ")" - - //Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed. - var/datum/antagonist/changeling/cling = changeling.has_antag_datum(/datum/antagonist/changeling) - text += "
    Changeling ID: [cling.changelingID]." - text += "
    Genomes Extracted: [cling.absorbed_count]" - - var/list/all_objectives = changeling.get_all_objectives(include_team = FALSE) - - if(length(all_objectives)) - var/count = 1 - for(var/datum/objective/objective in all_objectives) - if(objective.check_completion()) - text += "
    Objective #[count]: [objective.explanation_text] Success!" - if(istype(objective, /datum/objective/steal)) - var/datum/objective/steal/S = objective - SSblackbox.record_feedback("nested tally", "changeling_steal_objective", 1, list("Steal [S.steal_target]", "SUCCESS")) - else - SSblackbox.record_feedback("nested tally", "changeling_objective", 1, list("[objective.type]", "SUCCESS")) - else - text += "
    Objective #[count]: [objective.explanation_text] Fail." - if(istype(objective, /datum/objective/steal)) - var/datum/objective/steal/S = objective - SSblackbox.record_feedback("nested tally", "changeling_steal_objective", 1, list("Steal [S.steal_target]", "FAIL")) - else - SSblackbox.record_feedback("nested tally", "changeling_objective", 1, list("[objective.type]", "FAIL")) - changelingwin = 0 - count++ - - if(changelingwin) - text += "
    The changeling was successful!" - SSblackbox.record_feedback("tally", "changeling_success", 1, "SUCCESS") - else - text += "
    The changeling has failed." - SSblackbox.record_feedback("tally", "changeling_success", 1, "FAIL") - return text.Join("") diff --git a/code/game/gamemodes/cult/blood_magic.dm b/code/game/gamemodes/cult/blood_magic.dm deleted file mode 100644 index 12b80aa8da5d5..0000000000000 --- a/code/game/gamemodes/cult/blood_magic.dm +++ /dev/null @@ -1,999 +0,0 @@ -/// Blood magic handles the creation of blood spells (formerly talismans) -/datum/action/innate/cult/blood_magic - name = "Prepare Blood Magic" - button_overlay_icon_state = "carve" - desc = "Prepare blood magic by carving runes into your flesh. This is easier with an empowering rune." - default_button_position = DEFAULT_BLOODSPELLS - var/list/spells = list() - var/channeling = FALSE - -/datum/action/innate/cult/blood_magic/Remove() - for(var/X in spells) - qdel(X) - ..() - -/datum/action/innate/cult/blood_magic/Activate() - var/rune = FALSE - var/limit = RUNELESS_MAX_BLOODCHARGE - for(var/obj/effect/rune/empower/R in range(1, owner)) - rune = TRUE - limit = MAX_BLOODCHARGE - break - if(length(spells) >= limit) - if(rune) - to_chat(owner, "You cannot store more than [MAX_BLOODCHARGE] spell\s. Pick a spell to remove.") - remove_spell("You cannot store more than [MAX_BLOODCHARGE] spell\s, pick a spell to remove.") - else - to_chat(owner, "You cannot store more than [RUNELESS_MAX_BLOODCHARGE] spell\s without an empowering rune! Pick a spell to remove.") - remove_spell("You cannot store more than [RUNELESS_MAX_BLOODCHARGE] spell\s without an empowering rune, pick a spell to remove.") - return - var/entered_spell_name - var/datum/action/innate/cult/blood_spell/BS - var/list/possible_spells = list() - - for(var/I in subtypesof(/datum/action/innate/cult/blood_spell)) - var/datum/action/innate/cult/blood_spell/J = I - var/cult_name = initial(J.name) - possible_spells[cult_name] = J - if(length(spells)) - possible_spells += "(REMOVE SPELL)" - entered_spell_name = tgui_input_list(owner, "Pick a blood spell to prepare...", "Spell Choices", possible_spells) - if(entered_spell_name == "(REMOVE SPELL)") - remove_spell() - return - BS = possible_spells[entered_spell_name] - if(QDELETED(src) || owner.incapacitated() || !BS || (rune && !(locate(/obj/effect/rune/empower) in range(1, owner))) || (length(spells) >= limit)) - return - - if(!channeling) - channeling = TRUE - to_chat(owner, "You begin to carve unnatural symbols into your flesh!") - else - to_chat(owner, "You are already invoking blood magic!") - return - - if(do_after(owner, 100 - rune * 60, target = owner)) - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - if(H.dna && (NO_BLOOD in H.dna.species.species_traits)) - H.cult_self_harm(3 - rune * 2) - else - H.bleed(20 - rune * 12) - var/datum/action/innate/cult/blood_spell/new_spell = new BS(owner) - spells += new_spell - new_spell.Grant(owner, src) - to_chat(owner, "Your wounds glow with power, you have prepared a [new_spell.name] invocation!") - SSblackbox.record_feedback("tally", "cult_spells_prepared", 1, "[new_spell.name]") - channeling = FALSE - -/datum/action/innate/cult/blood_magic/proc/remove_spell() - var/nullify_spell = tgui_input_list(owner, "Pick a spell to remove", "Current Spells", spells) - if(nullify_spell) - qdel(nullify_spell) - -/// The next generation of talismans, handles storage/creation of blood magic -/datum/action/innate/cult/blood_spell - name = "Blood Magic" - button_overlay_icon_state = "telerune" - desc = "Fear the Old Blood." - default_button_position = SCRN_OBJ_CULT_LIST - var/charges = 1 - var/magic_path = null - var/obj/item/melee/blood_magic/hand_magic - var/datum/action/innate/cult/blood_magic/all_magic - var/base_desc //To allow for updating tooltips - var/invocation = "Hoi there something's wrong!" - var/health_cost = 0 - /// Have we already been positioned into our starting location? - var/positioned = FALSE - - -/datum/action/innate/cult/blood_spell/proc/get_panel_text() - if(initial(charges) == 1) - return - var/available_charges = hand_magic ? "[hand_magic.uses]" : "[charges]" - return "[available_charges]/[initial(charges)]" - -/datum/action/innate/cult/blood_spell/UpdateButton(atom/movable/screen/movable/action_button/button, status_only, force) - . = ..() - var/text = get_panel_text() - if(!text || !button) - return - var/image/count_down_holder = image('icons/effects/effects.dmi', icon_state = "nothing") - count_down_holder.maptext = "
    [text]
    " - button.add_overlay(count_down_holder) - -/datum/action/innate/cult/blood_spell/Grant(mob/living/owner, datum/action/innate/cult/blood_magic/BM) - if(health_cost) - desc += "
    Deals [health_cost] damage to your arm per use." - base_desc = desc - desc += "
    Has [charges] use\s remaining." - all_magic = BM - // todo blood magic guh - // button.ordered = FALSE - ..() - -/datum/action/innate/cult/blood_spell/Remove() - if(all_magic) - all_magic.spells -= src - if(hand_magic) - qdel(hand_magic) - hand_magic = null - ..() - -/datum/action/innate/cult/blood_spell/IsAvailable() - if(!IS_CULTIST(owner) || owner.incapacitated() || !charges) - return FALSE - return ..() - -/datum/action/innate/cult/blood_spell/Activate() - if(owner.holy_check()) - return - if(magic_path) // If this spell flows from the hand - if(!hand_magic) // If you don't already have the spell active - hand_magic = new magic_path(owner, src) - if(!owner.put_in_hands(hand_magic)) - qdel(hand_magic) - hand_magic = null - to_chat(owner, "You have no empty hand for invoking blood magic!") - return - to_chat(owner, "Your wounds glow as you invoke the [name].") - - else // If the spell is active, and you clicked on the button for it - qdel(hand_magic) - hand_magic = null - -//the spell list - -/datum/action/innate/cult/blood_spell/stun - name = "Stun" - desc = "Will knock down and mute a victim on contact. Strike them with a cult blade to complete the invocation, stunning them and extending the mute." - button_overlay_icon_state = "stun" - magic_path = /obj/item/melee/blood_magic/stun - health_cost = 10 - -/datum/action/innate/cult/blood_spell/teleport - name = "Teleport" - desc = "Empowers your hand to teleport yourself or another cultist to a teleport rune on contact." - button_overlay_icon_state = "teleport" - magic_path = /obj/item/melee/blood_magic/teleport - health_cost = 7 - -/datum/action/innate/cult/blood_spell/emp - name = "Electromagnetic Pulse" - desc = "Releases an Electromagnetic Pulse, affecting nearby non-cultists. The pulse will still affect you." - button_overlay_icon_state = "emp" - health_cost = 10 - invocation = "Ta'gh fara'qha fel d'amar det!" - -/datum/action/innate/cult/blood_spell/emp/Grant(mob/living/owner) - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - var/oof = FALSE - for(var/obj/item/organ/external/E in H.bodyparts) - if(E.is_robotic()) - oof = TRUE - break - if(!oof) - for(var/obj/item/organ/internal/I in H.internal_organs) - if(I.is_robotic()) - oof = TRUE - break - if(oof) - to_chat(owner, "You get the feeling this is a bad idea.") - ..() - -/datum/action/innate/cult/blood_spell/emp/Activate() - if(owner.holy_check()) - return - owner.visible_message("[owner]'s body flashes a bright blue!", \ - "You speak the cursed words, channeling an electromagnetic pulse from your body.") - owner.emp_act(EMP_LIGHT) - INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(empulse), owner, 2, 5, TRUE, "cult") - owner.whisper(invocation) - charges-- - if(charges <= 0) - qdel(src) - -/datum/action/innate/cult/blood_spell/shackles - name = "Shadow Shackles" - desc = "Empowers your hand to start handcuffing victim on contact, and mute them if successful." - button_overlay_icon_state = "shackles" - charges = 4 - magic_path = /obj/item/melee/blood_magic/shackles - -/datum/action/innate/cult/blood_spell/construction - name = "Twisted Construction" - desc = "Empowers your hand to corrupt certain metalic objects.
    Converts:
    Plasteel into runed metal
    50 metal into a construct shell
    Cyborg shells into construct shells
    Airlocks into brittle runed airlocks after a delay (harm intent)" - button_overlay_icon_state = "transmute" - magic_path = "/obj/item/melee/blood_magic/construction" - health_cost = 12 - -/datum/action/innate/cult/blood_spell/dagger - name = "Summon Dagger" - desc = "Summon a ritual dagger, necessary to scribe runes." - button_overlay_icon_state = "cult_dagger" - -/datum/action/innate/cult/blood_spell/dagger/New() - button_overlay_icon_state = GET_CULT_DATA(dagger_icon, "cult_dagger") - ..() - -/datum/action/innate/cult/blood_spell/dagger/Activate() - var/turf/T = get_turf(owner) - owner.visible_message("[owner]'s hand glows red for a moment.", \ - "Red light begins to shimmer and take form within your hand!") - var/obj/item/melee/cultblade/dagger/O = new(T) - if(owner.put_in_hands(O)) - to_chat(owner, "A [O.name] appears in your hand!") - else - owner.visible_message("A [O.name] appears at [owner]'s feet!", \ - "A [O.name] materializes at your feet.") - playsound(owner, 'sound/magic/cult_spell.ogg', 25, TRUE, SOUND_RANGE_SET(4)) - charges-- - desc = base_desc - desc += "
    Has [charges] use\s remaining." - if(charges <= 0) - qdel(src) - -/datum/action/innate/cult/blood_spell/equipment - name = "Summon Equipment" - desc = "Empowers your hand to summon combat gear onto a cultist you touch, including cult armor into open slots, a cult bola, and a cult sword." - button_overlay_icon_state = "equip" - magic_path = /obj/item/melee/blood_magic/armor - -/datum/action/innate/cult/blood_spell/horror - name = "Hallucinations" - desc = "Gives hallucinations to a target at range. A silent and invisible spell." - button_overlay_icon_state = "horror" - var/datum/spell/horror/PH - charges = 4 - -/datum/action/innate/cult/blood_spell/horror/New() - PH = new() - PH.attached_action = src - ..() - -/datum/action/innate/cult/blood_spell/horror/Destroy() - var/datum/spell/horror/destroy = PH - . = ..() - if(!QDELETED(destroy)) - QDEL_NULL(destroy) - -/datum/action/innate/cult/blood_spell/horror/Activate() - PH.toggle(owner) //the important bit - return TRUE - -/datum/spell/horror - active = FALSE - ranged_mousepointer = 'icons/effects/cult_target.dmi' - var/datum/action/innate/cult/blood_spell/attached_action - -/datum/spell/horror/Destroy() - var/datum/action/innate/cult/blood_spell/AA = attached_action - . = ..() - if(!QDELETED(AA)) - QDEL_NULL(AA) - -/datum/spell/horror/proc/toggle(mob/user) - if(active) - remove_ranged_ability(user, "You dispel the magic...") - else - add_ranged_ability(user, "You prepare to horrify a target...") - -/datum/spell/horror/InterceptClickOn(mob/living/user, params, atom/target) - if(..()) - return - if(ranged_ability_user.incapacitated() || !IS_CULTIST(user)) - user.ranged_ability.remove_ranged_ability(user) - return - if(user.holy_check()) - return - var/turf/T = get_turf(ranged_ability_user) - if(!isturf(T)) - return FALSE - if(target in view(7, ranged_ability_user)) - if(!ishuman(target) || IS_CULTIST(target)) - return - var/mob/living/carbon/human/H = target - H.Hallucinate(120 SECONDS) - attached_action.charges-- - attached_action.UpdateButtons() - attached_action.desc = attached_action.base_desc - attached_action.desc += "
    Has [attached_action.charges] use\s remaining." - attached_action.UpdateButtons() - user.ranged_ability.remove_ranged_ability(user, "[H] has been cursed with living nightmares!") - if(attached_action.charges <= 0) - to_chat(ranged_ability_user, "You have exhausted the spell's power!") - qdel(src) - -/datum/action/innate/cult/blood_spell/veiling - name = "Conceal Presence" - desc = "Alternates between hiding and revealing nearby cult structures, cult airlocks and runes." - invocation = "Kla'atu barada nikt'o!" - button_overlay_icon_state = "veiling" - charges = 10 - var/revealing = FALSE //if it reveals or not - -/datum/action/innate/cult/blood_spell/veiling/Activate() - if(owner.holy_check()) - return - if(!revealing) // Hiding stuff - owner.visible_message("Thin grey dust falls from [owner]'s hand!", \ - "You invoke the veiling spell, hiding nearby runes and cult structures.") - charges-- - if(!SSticker.mode.cult_team.cult_risen || !SSticker.mode.cult_team.cult_ascendant) - playsound(owner, 'sound/magic/smoke.ogg', 25, TRUE, SOUND_RANGE_SET(4)) // If Cult is risen/ascendant. - else - playsound(owner, 'sound/magic/smoke.ogg', 25, TRUE, SOUND_RANGE_SET(1)) // If Cult is unpowered. - owner.whisper(invocation) - for(var/obj/O in range(4, owner)) - O.cult_conceal() - revealing = TRUE // Switch on use - name = "Reveal Runes" - button_overlay_icon_state = "revealing" - - else // Unhiding stuff - owner.visible_message("A flash of light shines from [owner]'s hand!", \ - "You invoke the counterspell, revealing nearby runes and cult structures.") - charges-- - owner.whisper(invocation) - if(!SSticker.mode.cult_team.cult_risen || !SSticker.mode.cult_team.cult_ascendant) - playsound(owner, 'sound/misc/enter_blood.ogg', 25, TRUE, SOUND_RANGE_SET(7)) // If Cult is risen/ascendant. - else - playsound(owner, 'sound/magic/smoke.ogg', 25, TRUE, SOUND_RANGE_SET(1)) // If Cult is unpowered. - for(var/obj/O in range(5, owner)) // Slightly higher in case we arent in the exact same spot - O.cult_reveal() - revealing = FALSE // Switch on use - name = "Conceal Runes" - button_overlay_icon_state = "veiling" - if(charges <= 0) - qdel(src) - desc = "[revealing ? "Reveals" : "Conceals"] nearby cult structures, airlocks, and runes." - desc += "
    Has [charges] use\s remaining." - UpdateButtons() - -/datum/action/innate/cult/blood_spell/manipulation - name = "Blood Rites" - desc = "Empowers your hand to manipulate blood. Use on blood or a noncultist to absorb blood to be used later, use on yourself or another cultist to heal them using absorbed blood. \ - \nUse the spell in-hand to cast advanced rites, such as summoning a magical blood spear, firing blood projectiles out of your hands, and more!" - invocation = "Fel'th Dol Ab'orod!" - button_overlay_icon_state = "manip" - charges = 5 - magic_path = /obj/item/melee/blood_magic/manipulator - -/datum/action/innate/cult/blood_spell/manipulation/get_panel_text() - return hand_magic ? "[hand_magic.uses]" : "[charges]" - -// The "magic hand" items -/obj/item/melee/blood_magic - name = "magical aura" - desc = "A sinister looking aura that distorts the flow of reality around it." - icon = 'icons/obj/weapons/magical_weapons.dmi' - lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' - righthand_file = 'icons/mob/inhands/items_righthand.dmi' - icon_state = "disintegrate" - item_state = "disintegrate" - flags = ABSTRACT | DROPDEL - - w_class = WEIGHT_CLASS_HUGE - throwforce = 0 - throw_range = 0 - throw_speed = 0 - /// Does it have a source, AKA bloody empowerment. - var/has_source = TRUE - var/invocation - var/uses = 1 - var/health_cost = 0 //The amount of health taken from the user when invoking the spell - var/datum/action/innate/cult/blood_spell/source - var/antimagic_flags = MAGIC_RESISTANCE_HOLY - -/obj/item/melee/blood_magic/Initialize(mapload, spell) - . = ..() - if(spell && has_source) - source = spell - uses = source.charges - health_cost = source.health_cost - -/obj/item/melee/blood_magic/Destroy() - if(has_source && !QDELETED(source)) - if(uses <= 0) - source.hand_magic = null - qdel(source) - source = null - else - source.hand_magic = null - source.charges = uses - source.desc = source.base_desc - source.desc += "
    Has [uses] use\s remaining." - source.UpdateButtons() - return ..() - -/obj/item/melee/blood_magic/customised_abstract_text(mob/living/carbon/owner) - return "[owner.p_their(TRUE)] [owner.l_hand == src ? "left hand" : "right hand"] is burning in blood-red fire." - -/obj/item/melee/blood_magic/attack_self__legacy__attackchain(mob/living/user) - attackby__legacy__attackchain(user, user, TRUE) - -/obj/item/melee/blood_magic/attack__legacy__attackchain(mob/living/M, mob/living/carbon/user) - if(!iscarbon(user) || !IS_CULTIST(user)) - uses = 0 - qdel(src) - return - if(M.can_block_magic(MAGIC_RESISTANCE_HOLY)) - to_chat(user, "[M] absorbs your spell!") - uses = 0 - qdel(src) - return - add_attack_logs(user, M, "used a cult spell ([src]) on") - M.lastattacker = user.real_name - -/obj/item/melee/blood_magic/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity) - . = ..() - if(invocation) - user.whisper(invocation) - if(health_cost && ishuman(user)) - user.cult_self_harm(health_cost) - if(uses <= 0) - qdel(src) - else if(source) - source.desc = source.base_desc - source.desc += "
    Has [uses] use\s remaining." - source.UpdateButtons() - -//The spell effects - -//stun -/obj/item/melee/blood_magic/stun - name = "Stunning Aura" - desc = "Will knock down and mute a victim on contact. Strike them with a cult blade to complete the invocation, stunning them and extending the mute." - color = RUNE_COLOR_RED - invocation = "Fuu ma'jin!" - -/obj/item/melee/blood_magic/stun/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity) - if(!isliving(target) || !proximity) - return - var/mob/living/L = target - if(IS_CULTIST(target)) - return - if(user.holy_check()) - return - user.visible_message("[user] holds up [user.p_their()] hand, which explodes in a flash of red light!", \ - "You attempt to stun [L] with the spell!") - - user.mob_light(LIGHT_COLOR_BLOOD_MAGIC, 3, _duration = 2) - - var/obj/item/nullrod/N = locate() in target - if(N) - target.visible_message("[target]'s holy weapon absorbs the red light!", \ - "Your holy weapon absorbs the blinding light!") - else - to_chat(user, "In a brilliant flash of red, [L] falls to the ground!") - - L.apply_status_effect(STATUS_EFFECT_CULT_STUN) - L.Silence(6 SECONDS) - if(issilicon(target)) - var/mob/living/silicon/S = L - S.emp_act(EMP_HEAVY) - else if(iscarbon(target)) - var/mob/living/carbon/C = L - C.KnockDown(10 SECONDS) - C.apply_damage(60, STAMINA) - C.flash_eyes(1, TRUE) - C.Stuttering(16 SECONDS) - C.CultSlur(20 SECONDS) - C.Jitter(16 SECONDS) - to_chat(user, "Stun mark applied! Stab them with a dagger, sword or blood spear to stun them fully!") - user.do_attack_animation(target) - uses-- - ..() - - -//Teleportation -/obj/item/melee/blood_magic/teleport - name = "Teleporting Aura" - color = RUNE_COLOR_TELEPORT - desc = "Will teleport a cultist to a teleport rune on contact." - invocation = "Sas'so c'arta forbici!" - -/obj/item/melee/blood_magic/teleport/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity) - if(user.holy_check()) - return - var/list/potential_runes = list() - var/list/teleportnames = list() - var/list/duplicaterunecount = list() - var/atom/movable/teleportee - if(!IS_CULTIST(target) || !proximity) - to_chat(user, "You can only teleport adjacent cultists with this spell!") - return - if(user != target) // So that the teleport effect shows on the correct mob - teleportee = target - else - teleportee = user - - for(var/R in GLOB.teleport_runes) - var/obj/effect/rune/teleport/T = R - var/resultkey = T.listkey - if(resultkey in teleportnames) - duplicaterunecount[resultkey]++ - resultkey = "[resultkey] ([duplicaterunecount[resultkey]])" - else - teleportnames.Add(resultkey) - duplicaterunecount[resultkey] = 1 - potential_runes[resultkey] = T - - if(!length(potential_runes)) - to_chat(user, "There are no valid runes to teleport to!") - log_game("Teleport spell failed - no other teleport runes") - return - if(!is_level_reachable(user.z)) - to_chat(user, "You are too far away from the station to teleport!") - log_game("Teleport spell failed - user in away mission") - return - - var/input_rune_key = tgui_input_list(user, "Choose a rune to teleport to", "Rune to Teleport to", 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) - return - - if(HAS_TRAIT(user, TRAIT_FLOORED)) - to_chat(user, "You cannot cast this spell while knocked down!") - return - - uses-- - - var/turf/origin = get_turf(teleportee) - var/turf/destination = get_turf(actual_selected_rune) - if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, destination) & COMPONENT_BLOCK_TELEPORT) - return - INVOKE_ASYNC(actual_selected_rune, TYPE_PROC_REF(/obj/effect/rune, teleport_effect), teleportee, origin, destination) - - if(is_mining_level(user.z) && !is_mining_level(destination.z)) //No effect if you stay on lavaland - actual_selected_rune.handle_portal("lava") - else if(!is_station_level(user.z) || isspacearea(get_area(user))) - actual_selected_rune.handle_portal("space", origin) - - if(user == target) - target.visible_message("Dust flows from [user]'s hand, and [user.p_they()] disappear[user.p_s()] in a flash of red light!", \ - "You speak the words and find yourself somewhere else!") - else - target.visible_message("Dust flows from [user]'s hand, and [target] disappears in a flash of red light!", \ - "You suddenly find yourself somewhere else!") - destination.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") - teleportee.forceMove(destination) - return ..() - -//Shackles -/obj/item/melee/blood_magic/shackles - name = "Shackling Aura" - desc = "Will start handcuffing a victim on contact, and mute them for a short duration if successful." - invocation = "In'totum Lig'abis!" - color = "#000000" // black - -/obj/item/melee/blood_magic/shackles/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity) - if(user.holy_check()) - return - if(iscarbon(target) && proximity) - var/mob/living/carbon/C = target - if(!(C.has_left_hand() || C.has_right_hand())) - user.visible_message("This victim doesn't have enough arms to complete the restraint!") - return - CuffAttack(C, user) - source.UpdateButtons() - ..() - -/obj/item/melee/blood_magic/shackles/proc/CuffAttack(mob/living/carbon/C, mob/living/user) - if(!C.handcuffed) - playsound(loc, 'sound/weapons/cablecuff.ogg', 30, TRUE, SOUND_RANGE_SET(7)) - C.visible_message("[user] begins restraining [C] with dark magic!", \ - "[user] begins shaping dark magic shackles around your wrists!") - if(do_mob(user, C, 30)) - if(!C.handcuffed) - C.handcuffed = new /obj/item/restraints/handcuffs/cult(C) - C.update_handcuffed() - C.Silence(12 SECONDS) - to_chat(user, "You shackle [C].") - add_attack_logs(user, C, "shackled") - uses-- - else - to_chat(user, "[C] is already bound.") - else - to_chat(user, "You fail to shackle [C].") - else - to_chat(user, "[C] is already bound.") - - -/// For the shackling spell -/obj/item/restraints/handcuffs/cult - name = "shadow shackles" - desc = "Shackles that bind the wrists with sinister magic." - icon_state = "cablecuff" - breakouttime = 45 SECONDS - origin_tech = "materials=4;magnets=5;abductor=2" - flags = DROPDEL - -/obj/item/restraints/handcuffs/cult/finish_resist_restraints(mob/living/carbon/user, break_cuffs, silent) - user.visible_message("[user]'s shackles shatter in a discharge of dark magic!", "Your [name] shatter in a discharge of dark magic!") - break_cuffs = TRUE - silent = TRUE - . = ..() - -//Construction: Converts 50 metal to a construct shell, plasteel to runed metal, or an airlock to brittle runed airlock -/obj/item/melee/blood_magic/construction - name = "Twisting Aura" - desc = "Corrupts certain metalic objects on contact." - invocation = "Ethra p'ni dedol!" - color = "#000000" // black - var/channeling = FALSE - -/obj/item/melee/blood_magic/construction/examine(mob/user) - . = ..() - . += {"A sinister spell used to convert:\n - Plasteel into runed metal\n - [METAL_TO_CONSTRUCT_SHELL_CONVERSION] metal into a construct shell\n - Airlocks into brittle runed airlocks after a delay (harm intent)"} - -/obj/item/melee/blood_magic/construction/afterattack__legacy__attackchain(atom/target, mob/user, proximity_flag, click_parameters) - if(user.holy_check()) - return - if(proximity_flag) - if(channeling) - to_chat(user, "You are already invoking twisted construction!") - return - var/turf/T = get_turf(target) - - //Metal to construct shell - if(istype(target, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/candidate = target - if(candidate.use(METAL_TO_CONSTRUCT_SHELL_CONVERSION)) - uses-- - 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) - playsound(user, 'sound/magic/cult_spell.ogg', 25, TRUE, SOUND_RANGE_SET(4)) - else - to_chat(user, "You need [METAL_TO_CONSTRUCT_SHELL_CONVERSION] metal to produce a construct shell!") - return - - //Plasteel to runed metal - else if(istype(target, /obj/item/stack/sheet/plasteel)) - var/obj/item/stack/sheet/plasteel/candidate = target - var/quantity = candidate.amount - if(candidate.use(quantity)) - uses-- - 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!") - playsound(user, 'sound/magic/cult_spell.ogg', 25, TRUE, SOUND_RANGE_SET(4)) - - //Airlock to cult airlock - else if(istype(target, /obj/machinery/door/airlock) && !istype(target, /obj/machinery/door/airlock/cult)) - channeling = TRUE - playsound(T, 'sound/machines/airlockforced.ogg', 50, TRUE, SOUND_RANGE_SET(7)) - do_sparks(5, TRUE, target) - if(do_after(user, 50, target = target)) - target.narsie_act(TRUE) - uses-- - user.visible_message("Black ribbons suddenly emanate from [user]'s hand and cling to the airlock - twisting and corrupting it!") - playsound(user, 'sound/magic/cult_spell.ogg', 25, TRUE, SOUND_RANGE_SET(7)) - channeling = FALSE - else - channeling = FALSE - return - else - to_chat(user, "The spell will not work on [target]!") - return - ..() - -//Armor: Gives the target a basic cultist combat loadout -/obj/item/melee/blood_magic/armor - name = "Arming Aura" - desc = "Will equipt cult combat gear onto a cultist on contact." - color = "#33cc33" // green - -/obj/item/melee/blood_magic/armor/afterattack__legacy__attackchain(atom/target, mob/living/carbon/user, proximity) - if(user.holy_check()) - return - if(iscarbon(target) && proximity) - uses-- - var/mob/living/carbon/C = target - var/armour = C.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/cultrobes/alt(user), ITEM_SLOT_OUTER_SUIT) - C.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(user), ITEM_SLOT_JUMPSUIT) - 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/shoes/cult(user), ITEM_SLOT_SHOES) - - 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)) - C.visible_message("Otherworldly [armour ? "armour" : "equipment"] suddenly appears on [C]!") - ..() -//Used by blood rite, to recharge things like viel shifter or the cultest shielded robes -/obj/item/melee/blood_magic/empower - name = "Blood Recharge" - desc = "Can be used on some cult items, to restore them to their previous state." - invocation = "Ditans Gut'ura Inpulsa!" - color = "#9c0651" - has_source = FALSE //special, only availible for a blood cost. - -/obj/item/melee/blood_magic/empower/afterattack__legacy__attackchain(atom/target, mob/user, proximity_flag, click_parameters) - if(user.holy_check()) - return - if(proximity_flag) - // Shielded suit - if(istype(target, /obj/item/clothing/suit/hooded/cultrobes/cult_shield)) - var/datum/component/shielded/shield = target.GetComponent(/datum/component/shielded) - if(shield.current_charges >= 3) - to_chat(user, "[target] is already at full charge!") - return - uses-- - to_chat(user, "You empower [target] with blood, recharging its shields!") - playsound(user, 'sound/magic/cult_spell.ogg', 25, TRUE, SOUND_RANGE_SET(7)) - shield.current_charges = 3 - user.update_appearance(UPDATE_ICON) - return ..() - - // Veil Shifter - if(istype(target, /obj/item/cult_shift)) - var/obj/item/cult_shift/S = target - if(S.uses >= 4) - to_chat(user, "[target] is already at full charge!") - return - uses-- - to_chat(user, "You empower [target] with blood, recharging its ability to shift!") - playsound(user, 'sound/magic/cult_spell.ogg', 25, TRUE, SOUND_RANGE_SET(7)) - S.uses = 4 - S.icon_state = "shifter" - return ..() - - to_chat(user, "The spell will not work on [target]!") - return ..() - -//Blood Rite: Absorb blood to heal cult members or summon weapons -/obj/item/melee/blood_magic/manipulator - name = "Blood Rite Aura" - desc = "Absorbs blood from anything you touch. Touching cultists and constructs can heal them. Use in-hand to cast an advanced rite." - color = "#7D1717" - -/obj/item/melee/blood_magic/manipulator/examine(mob/user) - . = ..() - . += "Blood spear and blood barrage cost [BLOOD_SPEAR_COST] and [BLOOD_BARRAGE_COST] charges respectively." - . += "Blood orb and blood empower cost [BLOOD_ORB_COST] and [BLOOD_RECHARGE_COST] charges respectively." - . += "You have collected [uses] charge\s of blood." - -/obj/item/melee/blood_magic/manipulator/proc/restore_blood(mob/living/carbon/human/user, mob/living/carbon/human/H) - if(uses == 0) - return - if(!H.dna || (NO_BLOOD in H.dna.species.species_traits) || !isnull(H.dna.species.exotic_blood)) - return - if(H.blood_volume >= BLOOD_VOLUME_SAFE) - return - var/restore_blood = BLOOD_VOLUME_SAFE - H.blood_volume - if(uses * 2 < restore_blood) - H.blood_volume += uses * 2 - to_chat(user, "You use the last of your charges to restore what blood you could, and the spell dissipates!") - uses = 0 - else - H.blood_volume = BLOOD_VOLUME_SAFE - uses -= round(restore_blood / 2) - to_chat(user, "Your blood rites have restored [H == user ? "your" : "[H.p_their()]"] blood to safe levels!") - -/obj/item/melee/blood_magic/manipulator/proc/heal_human_damage(mob/living/carbon/human/user, mob/living/carbon/human/H) - if(uses == 0) - return - var/overall_damage = H.getBruteLoss() + H.getFireLoss() + H.getToxLoss() + H.getOxyLoss() - if(overall_damage == 0) - to_chat(user, "[H] doesn't require healing!") - return - - var/ratio = uses / overall_damage - if(H == user) - to_chat(user, "Your blood healing is far less efficient when used on yourself!") - ratio *= 0.35 // Healing is half as effective if you can't perform a full heal - uses -= round(overall_damage) // Healing is 65% more "expensive" even if you can still perform the full heal - if(ratio > 1) - ratio = 1 - uses -= round(overall_damage) - H.visible_message("[H] is fully healed by [H == user ? "[H.p_their()]" : "[H]'s"] blood magic!", - "You are fully healed by [H == user ? "your" : "[user]'s"] blood magic!") - else - H.visible_message("[H] is partially healed by [H == user ? "[H.p_their()]" : "[H]'s"] blood magic.", - "You are partially healed by [H == user ? "your" : "[user]'s"] blood magic.") - uses = 0 - ratio *= -1 - H.adjustOxyLoss((overall_damage * ratio) * (H.getOxyLoss() / overall_damage), FALSE, null, TRUE) - H.adjustToxLoss((overall_damage * ratio) * (H.getToxLoss() / overall_damage), FALSE, null, TRUE) - H.adjustFireLoss((overall_damage * ratio) * (H.getFireLoss() / overall_damage), FALSE, null, TRUE) - H.adjustBruteLoss((overall_damage * ratio) * (H.getBruteLoss() / overall_damage), FALSE, null, TRUE) - H.updatehealth() - playsound(get_turf(H), 'sound/magic/staff_healing.ogg', 25, extrarange = SOUND_RANGE_SET(7)) - new /obj/effect/temp_visual/cult/sparks(get_turf(H)) - user.Beam(H, icon_state="sendbeam", time = 15) - -/obj/item/melee/blood_magic/manipulator/proc/heal_cultist(mob/living/carbon/human/user, mob/living/carbon/human/H) - if(H.stat == DEAD) - to_chat(user, "Only a revive rune can bring back the dead!") - return - var/charge_loss = uses - restore_blood(user, H) - heal_human_damage(user, H) - charge_loss = charge_loss - uses - if(!uses) - to_chat(user, "You use the last of your charges to heal [H == user ? "yourself" : "[H]"], and the spell dissipates!") - else - to_chat(user, "You use [charge_loss] charge\s, and have [uses] remaining.") - -/obj/item/melee/blood_magic/manipulator/proc/heal_construct(mob/living/carbon/human/user, mob/living/simple_animal/M) - if(uses == 0) - return - var/missing = M.maxHealth - M.health - if(!missing) - to_chat(user, "[M] doesn't require healing!") - return - if(uses > missing) - M.adjustHealth(-missing) - M.visible_message("[M] is fully healed by [user]'s blood magic!", - "You are fully healed by [user]'s blood magic!") - uses -= missing - else - M.adjustHealth(-uses) - M.visible_message("[M] is partially healed by [user]'s blood magic!", - "You are partially healed by [user]'s blood magic.") - uses = 0 - playsound(get_turf(M), 'sound/magic/staff_healing.ogg', 25, extrarange = SOUND_RANGE_SET(7)) - user.Beam(M, icon_state = "sendbeam", time = 10) - -/obj/item/melee/blood_magic/manipulator/proc/steal_blood(mob/living/carbon/human/user, mob/living/carbon/human/H) - if(H.stat == DEAD) - to_chat(user, "[H.p_their(TRUE)] blood has stopped flowing, you'll have to find another way to extract it.") - return - if(H.AmountCultSlurring()) - to_chat(user, "[H.p_their(TRUE)] blood has been tainted by an even stronger form of blood magic, it's no use to us like this!") - return - if(!H.dna || (NO_BLOOD in H.dna.species.species_traits) || H.dna.species.exotic_blood != null) - to_chat(user, "[H] does not have any usable blood!") - return - if(H.blood_volume <= BLOOD_VOLUME_SAFE) - to_chat(user, "[H] is missing too much blood - you cannot drain [H.p_them()] further!") - return - H.blood_volume -= 100 - uses += 50 - user.Beam(H, icon_state = "drainbeam", time = 10) - playsound(get_turf(H), 'sound/misc/enter_blood.ogg', 50, extrarange = SOUND_RANGE_SET(7)) - H.visible_message("[user] has drained some of [H]'s blood!", - "[user] has drained some of your blood!") - to_chat(user, "Your blood rite gains 50 charges from draining [H]'s blood.") - new /obj/effect/temp_visual/cult/sparks(get_turf(H)) - -// This should really be split into multiple procs -/obj/item/melee/blood_magic/manipulator/afterattack__legacy__attackchain(atom/target, mob/living/carbon/human/user, proximity) - if(user.holy_check()) - return - if(!proximity) - return ..() - if(ishuman(target)) - if(IS_CULTIST(target)) - heal_cultist(user, target) - target.clean_blood() - else - steal_blood(user, target) - source.UpdateButtons() - return - - if(isconstruct(target)) - heal_construct(user, target) - source.UpdateButtons() - return - - if(istype(target, /obj/item/blood_orb)) - var/obj/item/blood_orb/candidate = target - if(candidate.blood) - uses += candidate.blood - to_chat(user, "You obtain [candidate.blood] blood from the orb of blood!") - playsound(user, 'sound/misc/enter_blood.ogg', 50, extrarange = SOUND_RANGE_SET(7)) - qdel(candidate) - source.UpdateButtons() - return - blood_draw(target, user) - source.UpdateButtons() - -/obj/item/melee/blood_magic/manipulator/proc/blood_draw(atom/target, mob/living/carbon/human/user) - var/temp = 0 - var/turf/T = get_turf(target) - if(!T) - return - for(var/obj/effect/decal/cleanable/blood/B in range(T, 2)) - if(B.blood_state == BLOOD_STATE_HUMAN && (B.can_bloodcrawl_in())) - if(B.bloodiness == 100) //Bonus for "pristine" bloodpools, also to prevent cheese with footprint spam - temp += 30 - else - temp += max((B.bloodiness ** 2) / 800, 1) - new /obj/effect/temp_visual/cult/turf/open/floor(get_turf(B)) - qdel(B) - for(var/obj/effect/decal/cleanable/trail_holder/TH in range(T, 2)) - new /obj/effect/temp_visual/cult/turf/open/floor(get_turf(TH)) - qdel(TH) - if(temp) - user.Beam(T, icon_state = "drainbeam", time = 15) - new /obj/effect/temp_visual/cult/sparks(get_turf(user)) - playsound(T, 'sound/misc/enter_blood.ogg', 50, extrarange = SOUND_RANGE_SET(7)) - temp = round(temp) - to_chat(user, "Your blood rite has gained [temp] charge\s from blood sources around you!") - uses += max(1, temp) - -/obj/item/melee/blood_magic/manipulator/attack_self__legacy__attackchain(mob/living/user) - if(user.holy_check()) - return - var/list/options = list("Blood Orb (50)" = image(icon = 'icons/obj/cult.dmi', icon_state = "summoning_orb"), - "Blood Recharge (75)" = image(icon = 'icons/mob/actions/actions_cult.dmi', icon_state = "blood_charge"), - "Blood Spear (150)" = image(icon = 'icons/mob/actions/actions_cult.dmi', icon_state = "bloodspear"), - "Blood Bolt Barrage (300)" = image(icon = 'icons/mob/actions/actions_cult.dmi', icon_state = "blood_barrage")) - var/choice = show_radial_menu(user, src, options) - - switch(choice) - if("Blood Orb (50)") - if(uses < BLOOD_ORB_COST) - to_chat(user, "You need [BLOOD_ORB_COST] charges to perform this rite.") - else - var/ammount = input("How much blood would you like to transfer? You have [uses] blood.", "How much blood?", 50) as null|num - if(ammount < 50) // No 1 blood orbs, 50 or more. - to_chat(user, "You need to give up at least 50 blood.") - return - if(ammount > uses) // No free blood either - to_chat(user, "You do not have that much blood to give!") - return - uses -= ammount - var/turf/T = get_turf(user) - qdel(src) - var/obj/item/blood_orb/rite = new(T) - rite.blood = ammount - if(user.put_in_hands(rite)) - to_chat(user, "A [rite.name] appears in your hand!") - else - user.visible_message("A [rite.name] appears at [user]'s feet!", - "A [rite.name] materializes at your feet.") - - if("Blood Recharge (75)") - if(uses < BLOOD_RECHARGE_COST) - to_chat(user, "You need [BLOOD_RECHARGE_COST] charges to perform this rite.") - else - var/obj/rite = new /obj/item/melee/blood_magic/empower() - uses -= BLOOD_RECHARGE_COST - qdel(src) - if(user.put_in_hands(rite)) - to_chat(user, "Your hand glows with power!") - else - to_chat(user, "You need a free hand for this rite!") - uses += BLOOD_RECHARGE_COST // Refund the charges - qdel(rite) - - if("Blood Spear (150)") - if(uses < BLOOD_SPEAR_COST) - to_chat(user, "You need [BLOOD_SPEAR_COST] charges to perform this rite.") - else - uses -= BLOOD_SPEAR_COST - var/turf/T = get_turf(user) - qdel(src) - var/datum/action/innate/cult/spear/S = new(user) - var/obj/item/cult_spear/rite = new(T) - S.Grant(user, rite) - rite.spear_act = S - if(user.put_in_hands(rite)) - to_chat(user, "A [rite.name] appears in your hand!") - else - user.visible_message("A [rite.name] appears at [user]'s feet!", - "A [rite.name] materializes at your feet.") - - if("Blood Bolt Barrage (300)") - if(uses < BLOOD_BARRAGE_COST) - to_chat(user, "You need [BLOOD_BARRAGE_COST] charges to perform this rite.") - else - var/obj/rite = new /obj/item/gun/projectile/shotgun/boltaction/enchanted/arcane_barrage/blood() - uses -= BLOOD_BARRAGE_COST - qdel(src) - user.swap_hand() - user.drop_item() - if(user.put_in_hands(rite)) - to_chat(user, "Both of your hands glow with power!") - else - to_chat(user, "You need a free hand for this rite!") - uses += BLOOD_BARRAGE_COST // Refund the charges - qdel(rite) - source.UpdateButtons() diff --git a/code/game/gamemodes/cult/cult_actions.dm b/code/game/gamemodes/cult/cult_actions.dm deleted file mode 100644 index 0fc42ddf9feb5..0000000000000 --- a/code/game/gamemodes/cult/cult_actions.dm +++ /dev/null @@ -1,128 +0,0 @@ -/datum/action/innate/cult - button_overlay_icon = 'icons/mob/actions/actions_cult.dmi' - button_background_icon_state = "bg_cult" - check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS - buttontooltipstyle = "cult" - -/datum/action/innate/cult/IsAvailable() - if(!IS_CULTIST(owner)) - return FALSE - return ..() - - -//Comms -/datum/action/innate/cult/comm - name = "Communion" - desc = "Whispered words that all cultists can hear.
    Warning:Nearby non-cultists can still hear you." - button_overlay_icon_state = "cult_comms" - check_flags = AB_CHECK_CONSCIOUS - -/datum/action/innate/cult/comm/Activate() - var/input = tgui_input_text(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", encode = FALSE) - if(!input || !IsAvailable()) - return - cultist_commune(usr, input) - return - -/datum/action/innate/cult/comm/proc/cultist_commune(mob/living/user, message) - if(!user || !message) - return - - if(user.holy_check()) - return - - if(!user.can_speak()) - to_chat(user, "You can't speak!") - return - - if(HAS_TRAIT(user, TRAIT_MUTE) || user.mind.miming) //Under vow of silence/mute? - user.visible_message("[user] appears to whisper to themselves.", - "You begin to whisper to yourself.") //Make them do *something* abnormal. - sleep(10) - else - user.whisper("O bidai nabora se[pick("'","`")]sma!") // Otherwise book club sayings. - sleep(10) - user.whisper(message) // And whisper the actual message - - var/title - var/large = FALSE - var/living_message - if(istype(user, /mob/living/simple_animal/demon/slaughter/cult)) //Harbringers of the Slaughter - title = "Harbringer of the Slaughter" - large = TRUE - else - title = "[(isconstruct(user) ? "Construct" : isshade(user) ? "" : "Acolyte")] [user.real_name]" - - living_message = "[title]: [message]" - for(var/mob/M in GLOB.player_list) - if(IS_CULTIST(M)) - to_chat(M, living_message) - else if((M in GLOB.dead_mob_list) && !isnewplayer(M)) - to_chat(M, "[title] ([ghost_follow_link(user, ghost=M)]): [message]") - - log_say("(CULT) [message]", user) - -/datum/action/innate/cult/comm/spirit - name = "Spiritual Communion" - desc = "Conveys a message from the spirit realm that all cultists can hear." - -/datum/action/innate/cult/comm/spirit/IsAvailable() - return TRUE - -/datum/action/innate/cult/comm/spirit/cultist_commune(mob/living/user, message) - - var/living_message - if(!message) - return - var/title = "The [user.name]" - living_message = "[title]: [message]" - - for(var/mob/M in GLOB.player_list) - if(IS_CULTIST(M)) - to_chat(M, living_message) - else if((M in GLOB.dead_mob_list) && !isnewplayer(M)) - to_chat(M, "[title] ([ghost_follow_link(user, ghost=M)]): [message]") - - -//Objectives -/datum/action/innate/cult/check_progress - name = "Study the Veil" - button_overlay_icon_state = "tome" - desc = "Check your cult's current progress and objective." - check_flags = AB_CHECK_CONSCIOUS - -/datum/action/innate/cult/check_progress/New() - button_overlay_icon_state = GET_CULT_DATA(tome_icon, "tome") - ..() - -/datum/action/innate/cult/check_progress/IsAvailable() - return IS_CULTIST(owner) || isobserver(owner) - -/datum/action/innate/cult/check_progress/Activate() - if(!IsAvailable()) - return - if(SSticker?.mode?.cult_team) - SSticker.mode.cult_team.study_objectives(usr, TRUE) - else - to_chat(usr, "You fail to study the Veil. (This should never happen, adminhelp and/or yell at a coder)") - - -//Draw rune -/datum/action/innate/cult/use_dagger - name = "Draw Blood Rune" - desc = "Use the ritual dagger to create a powerful blood rune." - button_overlay_icon_state = "blood_dagger" - default_button_position = "10:29,4:-2" - -/datum/action/innate/cult/use_dagger/Grant() - button_overlay_icon_state = GET_CULT_DATA(dagger_icon, "blood_dagger") - ..() - -/datum/action/innate/cult/use_dagger/Activate() - var/obj/item/melee/cultblade/dagger/D = owner.find_item(/obj/item/melee/cultblade/dagger) - if(D) - owner.unequip(D) - owner.put_in_hands(D) - D.activate_self(owner) - else - to_chat(usr, "You do not seem to carry a ritual dagger to draw a rune with. If you need a new one, prepare and use the Summon Dagger spell.") diff --git a/code/game/gamemodes/cult/cult_datums.dm b/code/game/gamemodes/cult/cult_datums.dm deleted file mode 100644 index 827c962e14744..0000000000000 --- a/code/game/gamemodes/cult/cult_datums.dm +++ /dev/null @@ -1,258 +0,0 @@ -/datum/cult_info - var/name = "Cult of Nar'Sie" - var/theme = "blood" - var/tome_icon = "tome" - var/dagger_icon = "blood_dagger" - var/sword_icon = "blood_blade" - var/construct_glow = LIGHT_COLOR_BLOOD_MAGIC - - //God Entity - var/entity_name = "Nar'Sie" - var/entity_title1 = "The Dark One" - var/entity_title2 = "The One Who Sees" - var/entity_title3 = "The Geometer of Blood" - var/entity_icon_state = "narsie" - var/entity_spawn_animation = "narsie_spawn_anim" - - - //Builder Construct - var/artificer_name = "Artificer" - var/artificer_icon_state = "artificer" - var/artificer_dead_state = "shade_dead" - - //Behemoth Construct - var/behemoth_name = "Behemoth" - var/behemoth_icon_state = "behemoth" - var/behemoth_dead_state = "shade_dead" - - //Wraith Construct - var/wraith_name = "Wraith" - var/wraith_icon_state = "floating" - var/wraith_dead_state = "shade_dead" - var/wraith_jaunt_out_animation = "phase_shift" - var/wraith_jaunt_in_animation = "phase_shift2" - - //Armored Construct - var/juggernaut_name = "Juggernaut" - var/juggernaut_icon_state = "behemoth" - var/juggernaut_dead_state = "shade_dead" - - //Harvester Construct - var/harvester_name = "Harvester" - var/harvester_icon_state = "harvester" - var/harvester_dead_state = "shade_dead" - - //Proteon Construct - var/proteon_name = "Proteon" - var/proteon_icon_state = "proteon" - var/proteon_dead_state = "shade_dead" - //Shade Spirit - var/shade_name = "Shade" - var/shade_icon_state = "shade2" - var/shade_dead_state = "shade_dead" - - //Turfs - var/cult_floor_icon_state = "cult" - var/cult_wall_icon_state = "cult" - var/cult_girder_icon_state = "cultgirder" - - //Structures - var/pylon_icon_state = "pylon" - var/pylon_icon_state_off = "pylon_off" - - var/forge_icon_state = "forge" - var/forge_icon_state_off = "forge_off" - - var/altar_icon_state = "altar" - var/altar_icon_state_off = "altar_off" - - var/archives_icon_state = "archives" - var/archives_icon_state_off = "archives_off" - - var/runed_metal_icon_state = "sheet-runed" - var/runed_metal_item_state = "sheet-runed" - - var/airlock_runed_icon_file = 'icons/obj/doors/airlocks/cult/runed/cult.dmi' - var/airlock_runed_overlays_file = 'icons/obj/doors/airlocks/cult/runed/cult-overlays.dmi' - - var/airlock_unruned_icon_file = 'icons/obj/doors/airlocks/cult/unruned/cult.dmi' - var/airlock_unruned_overlays_file = 'icons/obj/doors/airlocks/cult/unruned/cult-overlays.dmi' - - -/datum/cult_info/fire - name = "Cult of Kha'Rin" - theme = "fire" - tome_icon = "helltome" - dagger_icon = "hell_dagger" - sword_icon = "hell_blade" - construct_glow = LIGHT_COLOR_FIRE - - entity_name = "Kha'Rin" - entity_title1 = "The Burning One" - entity_title2 = "The One Who Consumes" - entity_title3 = "The Harbinger of Fire" - entity_icon_state = "kha'rin" - entity_spawn_animation = "kha'rin_spawn_anim" - - cult_wall_icon_state = "hellcult" - cult_floor_icon_state = "culthell" - cult_girder_icon_state = "hell_girder" - - //artificer_name = "Summoner" - artificer_icon_state = "summoner" - - //behemoth_name = "Incarnation of Pain" - behemoth_icon_state = "incarnation_of_pain" - - //wraith_name = "Hell Knight" - wraith_icon_state = "hell_knight" - wraith_jaunt_out_animation = "infernal_rift_out" - wraith_jaunt_in_animation = "infernal_rift_in" - - //juggernaut_name = "Incarnation of Pain" - juggernaut_icon_state = "incarnation_of_pain" - - //harvester_name = "Lost Soul" - harvester_icon_state = "lost_soul" - - //shade_name = "Ifrit" - shade_icon_state = "ifrit" - - pylon_icon_state = "hell_pylon" - pylon_icon_state_off = "hell_pylon_off" - - forge_icon_state = "hell_forge" - forge_icon_state_off = "hell_forge_off" - - altar_icon_state = "hell_altar" - altar_icon_state_off = "hell_altar_off" - - archives_icon_state = "hell_archives" - archives_icon_state_off = "hell_archives_off" - - runed_metal_icon_state = "sheet_runed_hell" - runed_metal_item_state = "sheet_runed_hell" - - airlock_runed_icon_file = 'icons/obj/doors/airlocks/cult/runed/hell.dmi' - airlock_runed_overlays_file = 'icons/obj/doors/airlocks/cult/runed/hell-overlays.dmi' - - airlock_unruned_icon_file = 'icons/obj/doors/airlocks/cult/unruned/hell.dmi' - airlock_unruned_overlays_file = 'icons/obj/doors/airlocks/cult/unruned/hell-overlays.dmi' - -/datum/cult_info/death - name = "Cult of Mortality" - theme = "death" - tome_icon = "deathtome" - dagger_icon = "death_dagger" - sword_icon = "death_blade" - construct_glow = LIGHT_COLOR_DARKRED - - entity_name = "The Reaper" - entity_title1 = "The Silent One" - entity_title2 = "The One Who Beckons" - entity_title3 = "The Ferryman of Oblivion" - entity_icon_state = "reaper" - entity_spawn_animation = "reaper_spawn_anim" - - cult_wall_icon_state = "deathcult" - cult_floor_icon_state = "cultdeath" - cult_girder_icon_state = "reaper_cultgirder" - - //artificer_name = "Boneshaper" - artificer_icon_state = "boneshaper" - - //behemoth_name = "Draugr" - behemoth_icon_state = "golem" - - //wraith_name = "Envoy of Death" - wraith_icon_state = "envoy_of_death" - wraith_jaunt_out_animation = "shadowstep_out" - wraith_jaunt_in_animation = "shadowstep_in" - - //juggernaut_name = "Golem" - juggernaut_icon_state = "golem" - - //harvester_name = "Necrophage" - harvester_icon_state = "necrophage" - - //shade_name = "Banshee" - shade_icon_state = "banshee" - - pylon_icon_state = "reaper_pylon" - pylon_icon_state_off = "reaper_pylon_off" - - forge_icon_state = "reaper_forge" - forge_icon_state_off = "reaper_forge_off" - - altar_icon_state = "reaper_altar" - altar_icon_state_off = "reaper_altar_off" - - archives_icon_state = "reaper_archives" - archives_icon_state_off = "reaper_archives_off" - - runed_metal_icon_state = "sheet_runed_reaper" - runed_metal_item_state = "sheet_runed_reaper" - - airlock_runed_icon_file = 'icons/obj/doors/airlocks/cult/runed/reaper.dmi' - airlock_runed_overlays_file = 'icons/obj/doors/airlocks/cult/runed/reaper-overlays.dmi' - - airlock_unruned_icon_file = 'icons/obj/doors/airlocks/cult/unruned/reaper.dmi' - airlock_unruned_overlays_file = 'icons/obj/doors/airlocks/cult/unruned/reaper-overlays.dmi' - -/datum/cult_info/proc/get_name(type_to_name) - if(!type_to_name) - return - switch(type_to_name) - if("god") - return entity_name - if("behemoth") - return behemoth_name - if("builder") - return artificer_name - if("juggernaut") - return juggernaut_name - if("harvester") - return harvester_name - if("wraith") - return wraith_name - if("proteon") - return proteon_name - if("shade") - return shade_name - -/datum/cult_info/proc/get_icon(type_to_icon) - if(!type_to_icon) - return - switch(type_to_icon) - if("god") - return entity_icon_state - if("behemoth") - return behemoth_icon_state - if("builder") - return artificer_icon_state - if("juggernaut") - return juggernaut_icon_state - if("harvester") - return harvester_icon_state - if("wraith") - return wraith_icon_state - if("proteon") - return proteon_icon_state - if("shade") - return shade_icon_state - if("forge") - return forge_icon_state - if("forge_off") - return forge_icon_state_off - if("archives") - return archives_icon_state - if("archives_off") - return archives_icon_state_off - if("altar") - return altar_icon_state - if("altar_off") - return altar_icon_state_off - if("pylon") - return pylon_icon_state - if("pylon_off") - return pylon_icon_state_off diff --git a/code/game/gamemodes/cult/cult_mode.dm b/code/game/gamemodes/cult/cult_mode.dm deleted file mode 100644 index 371eb3200f8a5..0000000000000 --- a/code/game/gamemodes/cult/cult_mode.dm +++ /dev/null @@ -1,54 +0,0 @@ -/datum/game_mode/proc/get_cult_team() - if(!cult_team) - new /datum/team/cult() // assignment happens in create_team() - return cult_team - -/datum/game_mode/cult - name = "cult" - config_tag = "cult" - restricted_jobs = list("Chaplain", "AI", "Cyborg", "Internal Affairs Agent", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Blueshield", "Nanotrasen Representative", "Magistrate", "Nanotrasen Career Trainer", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Trans-Solar Federation General") - protected_jobs = list() - required_players = 30 - required_enemies = 3 - recommended_enemies = 4 - - var/list/pre_cult = list() - - var/const/min_cultists_to_start = 3 - var/const/max_cultists_to_start = 4 - -/datum/game_mode/cult/announce() - to_chat(world, "The current game mode is - Cult!") - to_chat(world, "Some crewmembers are attempting to start a cult!
    \nCultists - complete your objectives. Convert crewmembers to your cause by using the offer rune. Remember - there is no you, there is only the cult.
    \nPersonnel - Do not let the cult succeed in its mission. Brainwashing them with holy water reverts them to whatever CentComm-allowed faith they had.
    ") - -/datum/game_mode/cult/pre_setup() - if(GLOB.configuration.gamemode.prevent_mindshield_antags) - restricted_jobs += protected_jobs - - var/list/cultists_possible = get_players_for_role(ROLE_CULTIST) - for(var/cultists_number = 1 to max_cultists_to_start) - if(!length(cultists_possible)) - break - var/datum/mind/cultist = pick(cultists_possible) - cultists_possible -= cultist - pre_cult += cultist - cultist.restricted_roles = restricted_jobs - cultist.special_role = SPECIAL_ROLE_CULTIST - return length(pre_cult) - -/datum/game_mode/cult/post_setup() - new /datum/team/cult(pre_cult) - ..() - -/datum/game_mode/cult/declare_completion() - if(cult_team.cult_status == NARSIE_HAS_RISEN) - SSticker.mode_result = "cult win - cult win" - to_chat(world, "The cult wins! It has succeeded in summoning [GET_CULT_DATA(entity_name, "their god")]!") - else if(cult_team.cult_status == NARSIE_HAS_FALLEN) - SSticker.mode_result = "cult draw - narsie died, nobody wins" - to_chat(world, "Nobody wins! [GET_CULT_DATA(entity_name, "the cult god")] was summoned, but banished!") - else - SSticker.mode_result = "cult loss - staff stopped the cult" - to_chat(world, "The staff managed to stop the cult!") - - ..() diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm deleted file mode 100644 index 26066e3b5bf1a..0000000000000 --- a/code/game/gamemodes/cult/cult_structures.dm +++ /dev/null @@ -1,344 +0,0 @@ -/// The amount of time necessary for a structure to be able to produce items after being built -#define CULT_STRUCTURE_COOLDOWN 60 SECONDS - -/obj/structure/cult - density = TRUE - anchored = TRUE - layer = BELOW_OBJ_LAYER - icon = 'icons/obj/cult.dmi' - light_power = 2 - -//Noncult As we may have this on maps -/obj/structure/cult/altar - name = "Altar" - desc = "A bloodstained altar." - icon_state = "altar" - -/obj/structure/cult/forge - name = "Daemon forge" - desc = "A forge used in crafting unholy armors and weapons." - icon_state = "forge" - light_range = 2 - light_color = LIGHT_COLOR_LAVA - -/obj/structure/cult/pylon - name = "Pylon" - desc = "A floating crystal that hums with an unearthly energy." - icon_state = "pylon" - light_range = 1.5 - light_color = LIGHT_COLOR_RED - -//Cult versions cuase fuck map conflicts -/obj/structure/cult/functional - max_integrity = 100 - var/cooldowntime = 0 - var/death_message = "The structure falls apart." //The message shown when the structure is destroyed - var/death_sound = 'sound/items/bikehorn.ogg' - var/heathen_message = "You're a huge nerd, go away. Also, a coder forgot to put a message here." - var/selection_title = "Oops" - var/selection_prompt = "Choose your weapon, nerdwad" - var/creation_delay = 2400 - var/list/choosable_items = list("A coder forgot to set this" = /obj/item/grown/bananapeel) - var/creation_message = "A dank smoke comes out, and you pass out. When you come to, you notice a %ITEM%!" - -/obj/structure/cult/functional/obj_destruction() - visible_message(death_message) - playsound(src, death_sound, 50, TRUE) - ..() - -/obj/structure/cult/functional/examine(mob/user) - . = ..() - if(IS_CULTIST(user) && cooldowntime > world.time) - . += "The magic in [src] is weak, it will be ready to use again in [get_ETA()]." - . += "[src] is [anchored ? "":"not "]secured to the floor." - -/obj/structure/cult/functional/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/melee/cultblade/dagger) && IS_CULTIST(user)) - if(user.holy_check()) - return - anchored = !anchored - to_chat(user, "You [anchored ? "":"un"]secure [src] [anchored ? "to":"from"] the floor.") - if(!anchored) - icon_state = GET_CULT_DATA(get_icon("[initial(icon_state)]_off"), "[initial(icon_state)]_off") - else - icon_state = GET_CULT_DATA(get_icon(initial(icon_state)), initial(icon_state)) - return - return ..() - -/obj/structure/cult/functional/attack_hand(mob/living/user) - if(!IS_CULTIST(user)) - to_chat(user, "[heathen_message]") - return - if(invisibility) - to_chat(user, "The magic in [src] is being suppressed, reveal the structure first!") - return - if(HAS_TRAIT(user, TRAIT_HULK)) - to_chat(user, "You cannot seem to manipulate this structure with your bulky hands!") - return - if(!anchored) - to_chat(user, "You need to anchor [src] to the floor with a dagger first.") - return - if(cooldowntime > world.time) - to_chat(user, "The magic in [src] is weak, it will be ready to use again in [get_ETA()].") - return - - - var/list/pickable_items = get_choosable_items() - var/choice = show_radial_menu(user, src, pickable_items, require_near = TRUE) - var/picked_type = pickable_items[choice] - if(!QDELETED(src) && picked_type && Adjacent(user) && !user.incapacitated() && cooldowntime <= world.time) - cooldowntime = world.time + creation_delay - var/obj/O = new picked_type - if(isstructure(O) || !user.put_in_hands(O)) - O.forceMove(get_turf(src)) - to_chat(user, replacetext("[creation_message]", "%ITEM%", "[O.name]")) - -/** - * Returns the items the cult can craft from this forge. - * - * Override on children for logic regarding game state. - */ -/obj/structure/cult/functional/proc/get_choosable_items() - return choosable_items.Copy() // Copied incase its modified on children - -/** - * Returns the cooldown time in minutes and seconds - */ -/obj/structure/cult/functional/proc/get_ETA() - var/time = cooldowntime - world.time - var/minutes = round(time / 600) - var/seconds = round(time * 0.1, 1) - var/message - if(minutes) - message = "[minutes] minute\s" - seconds = seconds - (60 * minutes) - if(seconds) // To avoid '2 minutes, 0 seconds.' - message += "[minutes ? ", " : ""][seconds] second\s" - return message - -/obj/structure/cult/functional/cult_conceal() - density = FALSE - visible_message("[src] fades away.") - invisibility = INVISIBILITY_HIDDEN_RUNES - alpha = 100 //To help ghosts distinguish hidden objs - light_range = 0 - light_power = 0 - update_light() - -/obj/structure/cult/functional/cult_reveal() - density = initial(density) - invisibility = 0 - visible_message("[src] suddenly appears!") - alpha = initial(alpha) - light_range = initial(light_range) - light_power = initial(light_power) - update_light() - -/obj/structure/cult/functional/altar - name = "altar" - desc = "A bloodstained altar dedicated to a cult." - icon_state = "altar" - max_integrity = 150 //Sturdy - death_message = "The altar breaks into splinters, releasing a cascade of spirits into the air!" - death_sound = 'sound/effects/altar_break.ogg' - heathen_message = "There is a foreboding aura to the altar and you want nothing to do with it." - selection_prompt = "You study the rituals on the altar..." - selection_title = "Altar" - creation_message = "You kneel before the altar and your faith is rewarded with a %ITEM%!" - choosable_items = list("Eldritch Whetstone" = /obj/item/whetstone/cult, "Flask of Unholy Water" = /obj/item/reagent_containers/drinks/bottle/unholywater, - "Construct Shell" = /obj/structure/constructshell) - -/obj/structure/cult/functional/altar/Initialize(mapload) - . = ..() - icon_state = GET_CULT_DATA(altar_icon_state, "altar") - cooldowntime = world.time + CULT_STRUCTURE_COOLDOWN - -/obj/structure/cult/functional/forge - name = "daemon forge" - desc = "A forge used in crafting the unholy weapons used by the armies of a cult." - icon_state = "forge" - light_range = 2 - light_color = LIGHT_COLOR_LAVA - max_integrity = 300 //Made of metal - death_message = "The forge falls apart, its lava cooling and winking away!" - death_sound = 'sound/effects/forge_destroy.ogg' - heathen_message = "Your hand feels like it's melting off as you try to touch the forge." - selection_prompt = "You study the schematics etched on the forge..." - selection_title = "Forge" - creation_message = "You work the forge as dark knowledge guides your hands, creating a %ITEM%!" - choosable_items = list("Shielded Robe" = /obj/item/clothing/suit/hooded/cultrobes/cult_shield, "Flagellant's Robe" = /obj/item/clothing/suit/hooded/cultrobes/flagellant_robe) - -/obj/structure/cult/functional/forge/get_choosable_items() - . = ..() - if(SSticker.mode.cult_team.mirror_shields_active) - // Both lines here are needed. If you do it without, youll get issues. - . += "Mirror Shield" - .["Mirror Shield"] = /obj/item/shield/mirror - - -/obj/structure/cult/functional/forge/Initialize(mapload) - . = ..() - icon_state = GET_CULT_DATA(forge_icon_state, "forge") - -/obj/structure/cult/functional/forge/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/grab)) - var/obj/item/grab/G = I - if(!iscarbon(G.affecting)) - return FALSE - if(G.affecting == LAVA_PROOF) - to_chat(user, "[G.affecting] is immune to lava!") - return FALSE - if(G.affecting.stat == DEAD) - to_chat(user, "[G.affecting] is dead!") - return FALSE - var/mob/living/carbon/human/C = G.affecting - var/obj/item/organ/external/head/head = C.get_organ("head") - if(!head) - to_chat(user, "[C] has no head!") - return FALSE - - C.visible_message("[user] dunks [C]'s face into [src]'s lava!", - "[user] dunks your face into [src]'s lava!") - C.emote("scream") - C.apply_damage(30, BURN, "head") // 30 fire damage because it's FUCKING LAVA - head.disfigure() // Your face is unrecognizable because it's FUCKING LAVA - C.UpdateDamageIcon() - add_attack_logs(user, C, "Lava-dunked into [src]") - user.changeNext_move(CLICK_CD_MELEE) - return TRUE - return ..() - -GLOBAL_LIST_INIT(blacklisted_pylon_turfs, typecacheof(list( - /turf/simulated/floor/engine/cult, - /turf/space, - /turf/simulated/wall/indestructible, - /turf/simulated/floor/lava, - /turf/simulated/floor/chasm, - /turf/simulated/wall/cult, - /turf/simulated/wall/cult/artificer - ))) - -/obj/structure/cult/functional/pylon - name = "pylon" - desc = "A floating crystal that slowly heals those faithful to a cult." - icon_state = "pylon" - light_range = 1.5 - light_color = LIGHT_COLOR_RED - max_integrity = 50 //Very fragile - death_message = "The pylon's crystal vibrates and glows fiercely before violently shattering!" - death_sound = 'sound/effects/pylon_shatter.ogg' - - var/heal_delay = 30 - var/last_heal = 0 - var/corrupt_delay = 50 - var/last_corrupt = 0 - -/obj/structure/cult/functional/pylon/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - icon_state = GET_CULT_DATA(pylon_icon_state, "pylon") - -/obj/structure/cult/functional/pylon/attack_hand(mob/living/user)//override as it should not create anything - return - -/obj/structure/cult/functional/pylon/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/structure/cult/functional/pylon/cult_conceal() - STOP_PROCESSING(SSobj, src) - ..() - -/obj/structure/cult/functional/pylon/cult_reveal() - START_PROCESSING(SSobj, src) - ..() - -/obj/structure/cult/functional/pylon/process() - if(!anchored) - return - - if(last_heal <= world.time) - last_heal = world.time + heal_delay - for(var/mob/living/L in range(5, src)) - if(IS_CULTIST(L) || iswizard(L) || isshade(L) || isconstruct(L)) - if(L.health != L.maxHealth) - new /obj/effect/temp_visual/heal(get_turf(src), COLOR_HEALING_GREEN) - - if(ishuman(L)) - L.heal_overall_damage(1, 1, TRUE, FALSE, TRUE) - - else if(isshade(L) || isconstruct(L)) - var/mob/living/simple_animal/M = L - if(M.health < M.maxHealth) - M.adjustHealth(-1) - - if(ishuman(L) && L.blood_volume < BLOOD_VOLUME_NORMAL) - L.blood_volume += 1 - - if(!is_station_level(z) && last_corrupt <= world.time) //Pylons only convert tiles on offstation bases to help hide onstation cults from meson users - var/list/validturfs = list() - var/list/cultturfs = list() - for(var/T in circleviewturfs(src, 5)) - if(istype(T, /turf/simulated/floor/engine/cult)) - cultturfs |= T - continue - if(is_type_in_typecache(T, GLOB.blacklisted_pylon_turfs)) - continue - else - validturfs |= T - - last_corrupt = world.time + corrupt_delay - - var/turf/T = safepick(validturfs) - if(T) - if(isfloorturf(T)) - T.ChangeTurf(/turf/simulated/floor/engine/cult) - if(iswallturf(T)) - T.ChangeTurf(/turf/simulated/wall/cult/artificer) - else - var/turf/simulated/floor/engine/cult/F = safepick(cultturfs) - if(F) - new /obj/effect/temp_visual/cult/turf/open/floor(F) - else - // Are we in space or something? No cult turfs or - // convertable turfs? - last_corrupt = world.time + corrupt_delay * 2 - -/obj/structure/cult/functional/archives - name = "archives" - desc = "A desk covered in arcane manuscripts and tomes in unknown languages. Looking at the text makes your skin crawl." - icon_state = "archives" - light_range = 1.5 - light_color = LIGHT_COLOR_FIRE - max_integrity = 125 //Slightly sturdy - death_message = "The desk breaks apart, its books falling to the floor." - death_sound = 'sound/effects/wood_break.ogg' - heathen_message = "What do you hope to seek?" - selection_prompt = "You flip through the black pages of the archives..." - selection_title = "Archives" - creation_message = "You invoke the dark magic of the tomes creating a %ITEM%!" - choosable_items = list("Shuttle Curse" = /obj/item/shuttle_curse, "Zealot's Blindfold" = /obj/item/clothing/glasses/hud/health/night/cultblind, - "Veil Shifter" = /obj/item/cult_shift, "Reality sunderer" = /obj/item/portal_amulet, "Blank Tarot Card" = /obj/item/blank_tarot_card) - -/obj/structure/cult/functional/archives/Initialize(mapload) - . = ..() - icon_state = GET_CULT_DATA(archives_icon_state, "archives") - -/obj/effect/gateway - name = "gateway" - desc = "You're pretty sure that the abyss is staring back." - icon = 'icons/obj/cult.dmi' - icon_state = "hole" - density = TRUE - anchored = TRUE - -/obj/effect/gateway/singularity_act() - return - -/obj/effect/gateway/singularity_pull() - return - -/obj/effect/gateway/Bumped(atom/movable/AM) - return - -#undef CULT_STRUCTURE_COOLDOWN diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm deleted file mode 100644 index fd1e6f3f1438b..0000000000000 --- a/code/game/gamemodes/cult/ritual.dm +++ /dev/null @@ -1,203 +0,0 @@ -#define CULT_ELDERGOD "eldergod" -#define CULT_SLAUGHTER "slaughter" - -/obj/item/melee/cultblade/dagger - name = "ritual dagger" - desc = "A strange dagger said to be used by sinister groups for \"preparing\" a corpse before sacrificing it to their dark gods." - icon_state = "blood_dagger" - item_state = "blood_dagger" - w_class = WEIGHT_CLASS_SMALL - force = 15 - throwforce = 25 - armour_penetration_flat = 35 - sprite_sheets_inhand = null // Override parent - var/drawing_rune = FALSE - var/scribe_multiplier = 1 // Lower is faster - -/obj/item/melee/cultblade/dagger/adminbus - name = "ritual dagger of scribing, +1" - desc = "VERY fast culto scribing at incredible high speed!" - force = 16 - scribe_multiplier = 0.1 - -/obj/item/melee/cultblade/dagger/Initialize(mapload) - . = ..() - icon_state = GET_CULT_DATA(dagger_icon, "blood_dagger") - item_state = GET_CULT_DATA(dagger_icon, "blood_dagger") - -/obj/item/melee/cultblade/dagger/examine(mob/user) - . = ..() - if(IS_CULTIST(user) || user.stat == DEAD) - . += "A dagger gifted by [GET_CULT_DATA(entity_title3, "your god")]. Allows the scribing of runes and access to the knowledge archives of the cult of [GET_CULT_DATA(entity_name, "your god")]." - . += "Striking another cultist with it will purge holy water from them." - . += "Striking a noncultist will tear their flesh, additionally, if you recently downed them with cult magic it will stun them completely." - -/obj/item/melee/cultblade/dagger/pre_attack(atom/target, mob/living/user, params) - if(..()) - return FINISH_ATTACK - - if(IS_CULTIST(target)) - if(target.reagents && target.reagents.has_reagent("holywater")) //allows cultists to be rescued from the clutches of ordained religion - if(target == user) // Targeting yourself - to_chat(user, "You can't remove holy water from yourself!") - - else // Targeting someone else - to_chat(user, "You remove the taint from [target].") - to_chat(target, "[user] removes the taint from your body.") - target.reagents.del_reagent("holywater") - add_attack_logs(user, target, "Hit with [src], removing the holy water from them") - - return FINISH_ATTACK - -/obj/item/melee/cultblade/dagger/activate_self(mob/user) - if(..()) - return - - if(IS_CULTIST(user)) - scribe_rune(user) - else - to_chat(user, "[src] is covered in unintelligible shapes and markings.") - -/obj/item/melee/cultblade/dagger/proc/narsie_rune_check(mob/living/user, area/A) - var/datum/game_mode/gamemode = SSticker.mode - - if(gamemode.cult_team.cult_status < NARSIE_NEEDS_SUMMONING) - to_chat(user, "[GET_CULT_DATA(entity_name, "Your god")] is not ready to be summoned yet!") - return FALSE - if(gamemode.cult_team.cult_status == NARSIE_HAS_RISEN) - to_chat(user, "\"I am already here. There is no need to try to summon me now.\"") - return FALSE - - var/list/summon_areas = gamemode.cult_team.obj_summon.summon_spots - if(!(A in summon_areas)) - to_chat(user, "[GET_CULT_DATA(entity_name, "Your god")] can only be summoned where the veil is weak - in [english_list(summon_areas)]!") - return FALSE - var/confirm_final = tgui_alert(user, "This is the FINAL step to summon your deities power, it is a long, painful ritual and the crew will be alerted to your presence AND your location!", - "Are you prepared for the final battle?", list("My life for [GET_CULT_DATA(entity_name, "the cult")]!", "No")) - if(user) - if(confirm_final == "No" || confirm_final == null) - to_chat(user, "You decide to prepare further before scribing the rune.") - return FALSE - else - if(locate(/obj/effect/rune) in range(1, user)) - to_chat(user, "You need a space cleared of runes before you can summon [GET_CULT_DATA(entity_title1, "your god")]!") - return FALSE - else - return TRUE - -/obj/item/melee/cultblade/dagger/proc/can_scribe(mob/living/user) - if(!src || !user || loc != user || user.incapacitated()) - return FALSE - if(drawing_rune) - to_chat(user, "You're already drawing a rune!") - return FALSE - - var/turf/T = get_turf(user) - if(isspaceturf(T)) - return FALSE - if((locate(/obj/effect/rune) in T) || (locate(/obj/effect/rune/narsie) in range(1, T))) - to_chat(user, "There's already a rune here!") - return FALSE - return TRUE - -/obj/item/melee/cultblade/dagger/proc/scribe_rune(mob/living/user) - var/list/shields = list() - var/list/possible_runes = list() - var/keyword - - if(!can_scribe(user)) // Check this before anything else - return - - // Choosing a rune - for(var/I in (subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed)) - var/obj/effect/rune/R = I - var/rune_name = initial(R.cultist_name) - if(rune_name) - possible_runes[rune_name] = R - if(!length(possible_runes)) - return - - var/chosen_rune = tgui_input_list(user, "Choose a rite to scribe.", "Sigils of Power", possible_runes) - if(!chosen_rune) - return - var/obj/effect/rune/rune = possible_runes[chosen_rune] - var/narsie_rune = FALSE - if(rune == /obj/effect/rune/narsie) - narsie_rune = TRUE - if(initial(rune.req_keyword)) - keyword = tgui_input_text(user, "Please enter a keyword for the rune.", "Enter Keyword") - if(!keyword) - return - - // Check everything again, in case they moved - if(!can_scribe(user)) - return - - // Check if the rune is allowed - var/area/A = get_area(src) - var/turf/runeturf = get_turf(user) - var/datum/game_mode/gamemode = SSticker.mode - if(ispath(rune, /obj/effect/rune/summon)) - if(!is_station_level(runeturf.z) || isspacearea(A)) - to_chat(user, "The veil is not weak enough here to summon a cultist, you must be on station!") - return - - if(ispath(rune, /obj/effect/rune/teleport)) - if(!is_level_reachable(user.z)) - to_chat(user, "You are too far away from the station to teleport!") - return - - var/old_color = user.color // we'll temporarily redden the user for better feedback to fellow cultists. Store this to revert them back. - if(narsie_rune) - if(!narsie_rune_check(user, A)) - return // don't do shit - var/list/summon_areas = gamemode.cult_team.obj_summon.summon_spots - if(!(A in summon_areas)) // Check again to make sure they didn't move - to_chat(user, "The ritual can only begin where the veil is weak - in [english_list(summon_areas)]!") - return - GLOB.major_announcement.Announce("Figments from an eldritch god are being summoned into the [A.map_name] from an unknown dimension. Disrupt the ritual at all costs, before the station is destroyed! Space Law and SOP are suspended. The entire crew must kill cultists on sight.", "Central Command Higher Dimensional Affairs", 'sound/AI/cult_summon.ogg') - for(var/I in spiral_range_turfs(1, user, 1)) - var/turf/T = I - var/obj/machinery/shield/cult/narsie/N = new(T) - shields |= N - user.color = COLOR_RED - - // Draw the rune - var/mob/living/carbon/human/H = user - H.cult_self_harm(initial(rune.scribe_damage)) - var/others_message - if(!narsie_rune) - others_message = "[user] cuts [user.p_their()] body and begins writing in [user.p_their()] own blood!" - else - others_message = "[user] cuts [user.p_their()] body and begins writing something particularly ominous in [user.p_their()] own blood!" - user.visible_message(others_message, - "You slice open your body and begin drawing a sigil of [GET_CULT_DATA(entity_title3, "your god")].") - - drawing_rune = TRUE // Only one at a time - var/scribe_successful = do_after(user, initial(rune.scribe_delay) * scribe_multiplier, target = runeturf) - for(var/V in shields) // Only used for the 'Tear Veil' rune - var/obj/machinery/shield/S = V - if(S && !QDELETED(S)) - qdel(S) - user.color = old_color - drawing_rune = FALSE - if(!scribe_successful) - return - - user.visible_message("[user] creates a strange circle in [user.p_their()] own blood.", - "You finish drawing the arcane markings of [GET_CULT_DATA(entity_title3, "your god")].") - - var/obj/effect/rune/R = new rune(runeturf, keyword) - if(narsie_rune) - for(var/obj/effect/rune/I in orange(1, R)) - qdel(I) - SSblackbox.record_feedback("tally", "runes_scribed", 1, "[R.cultist_name]") - R.blood_DNA = list() - R.blood_DNA[H.dna.unique_enzymes] = H.dna.blood_type - R.add_hiddenprint(H) - R.color = H.dna.species.blood_color - R.rune_blood_color = H.dna.species.blood_color - to_chat(user, "The [lowertext(initial(rune.cultist_name))] rune [initial(rune.cultist_desc)]") - -#undef CULT_ELDERGOD -#undef CULT_SLAUGHTER diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm deleted file mode 100644 index 6639c11dcc1e3..0000000000000 --- a/code/game/gamemodes/cult/runes.dm +++ /dev/null @@ -1,1107 +0,0 @@ -GLOBAL_LIST_EMPTY(sacrificed) // A mixed list of minds and mobs -GLOBAL_LIST_EMPTY(teleport_runes) // I'll give you two guesses - -/* -This file contains runes. -Runes are used by the cult to cause many different effects and are paramount to their success. -They are drawn with a ritual dagger in blood, and are distinguishable to cultists and normal crew by examining. -Fake runes can be drawn in crayon to fool people. -Runes can either be invoked by one's self or with many different cultists. Each rune has a specific incantation that the cultists will say when invoking it. -To draw a rune, use a ritual dagger. -*/ - -/obj/effect/rune - /// Name non-cultists see - name = "rune" - /// Name that cultists see - var/cultist_name = "basic rune" - /// Description that non-cultists see - desc = "An odd collection of symbols drawn in what seems to be blood." - /// Description that cultists see - var/cultist_desc = "a basic rune with no function." //This is shown to cultists who examine the rune in order to determine its true purpose. - anchored = TRUE - icon = 'icons/obj/rune.dmi' - icon_state = "1" - resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF - mouse_opacity = MOUSE_OPACITY_OPAQUE // So that runes aren't so hard to click - var/visibility = 0 - var/view_range = 7 - invisibility = INVISIBILITY_RUNES - layer = SIGIL_LAYER - color = COLOR_BLOOD_BASE - - /// What is said by cultists when the rune is invoked - var/invocation = "Aiy ele-mayo!" - ///The amount of cultists required around the rune to invoke it. If only 1, any cultist can invoke it. - var/req_cultists = 1 - /// Used for some runes, this is for when you want a rune to not be usable when in use. - var/rune_in_use = FALSE - - /// How long the rune takes to create (Currently only different for the Nar'Sie rune) - var/scribe_delay = 5 SECONDS - /// How much damage you take from drawing the rune - var/scribe_damage = 1 - - /// If nearby cultists will also chant when invoked - var/allow_excess_invokers = FALSE - /// If constructs can invoke it - var/construct_invoke = TRUE - - /// If the rune requires a keyword (e.g. Teleport runes) - var/req_keyword = FALSE - /// The actual keyword for the rune - var/keyword - - /// How much damage cultists take when invoking it (This includes constructs) - var/invoke_damage = 0 - /// The color of the rune. (Based on species blood color) - var/rune_blood_color = COLOR_BLOOD_BASE - -/obj/effect/rune/Initialize(mapload, set_keyword) - . = ..() - if(set_keyword) - keyword = set_keyword - var/image/blood = image(loc = src) - blood.override = 1 - for(var/mob/living/silicon/ai/AI in GLOB.ai_list) - AI.client.images += blood - -/obj/effect/rune/examine(mob/user) - . = ..() - if(IS_CULTIST(user) || isobserver(user)) //If they're a cultist or a ghost, tell them the effects - . += "Name: [cultist_name]" - . += "Effects: [capitalize(cultist_desc)]" - . += "Required Acolytes: [req_cultists]" - if(req_keyword && keyword) - . += "Keyword: [keyword]" - -/obj/effect/rune/attackby__legacy__attackchain(obj/I, mob/user, params) - if(istype(I, /obj/item/melee/cultblade/dagger) && IS_CULTIST(user)) - if(!can_dagger_erase_rune(user)) - return - - var/obj/item/melee/cultblade/dagger/D = I - user.visible_message("[user] begins to erase [src] with [I].") - if(do_after(user, initial(scribe_delay) * D.scribe_multiplier, target = src)) - to_chat(user, "You carefully erase the [lowertext(cultist_name)] rune.") - qdel(src) - return - if(istype(I, /obj/item/nullrod)) - if(IS_CULTIST(user))//cultist..what are doing..cultist..staph... - user.drop_item() - user.visible_message("[I] suddenly glows with a white light, forcing [user] to drop it in pain!", \ - "[I] suddenly glows with a white light that sears your hand, forcing you to drop it!") // TODO: Make this actually burn your hand - return - to_chat(user,"You disrupt the magic of [src] with [I].") - qdel(src) - return - return ..() - -/obj/effect/rune/proc/can_dagger_erase_rune(mob/user) - return TRUE - -/obj/effect/rune/attack_hand(mob/living/user) - user.Move_Pulled(src) // So that you can still drag things onto runes - if(!IS_CULTIST(user)) - to_chat(user, "You aren't able to understand the words of [src].") - return - var/list/invokers = can_invoke(user) - if(length(invokers) >= req_cultists) - invoke(invokers) - else - fail_invoke() - -/obj/effect/rune/attack_animal(mob/living/simple_animal/M) - if(isshade(M) || isconstruct(M)) - if(construct_invoke || !IS_CULTIST(M)) //if you're not a cult construct we want the normal fail message - attack_hand(M) - else - to_chat(M, "You are unable to invoke the rune!") - -/obj/effect/rune/cult_conceal() //for concealing spell - visible_message("[src] fades away.") - invisibility = INVISIBILITY_HIDDEN_RUNES - alpha = 100 //To help ghosts distinguish hidden runes - -/obj/effect/rune/cult_reveal() //for revealing spell - invisibility = initial(invisibility) - visible_message("[src] suddenly appears!") - alpha = initial(alpha) - -/obj/effect/rune/is_cleanable() - return TRUE - -/obj/effect/rune/cleaning_act(mob/user, atom/cleaner, cleanspeed = 5 SECONDS, text_verb = "scrub out", text_description = " with [cleaner].") - if(issimulatedturf(loc)) - var/turf/simulated/T = get_turf(src) - T.cleaning_act(user, cleaner, cleanspeed = cleanspeed, text_verb = text_verb, text_description = text_description, text_targetname = name) //Strings are deliberately "A = A" to avoid overrides - return - else - ..() - - -/* -There are a few different procs each rune runs through when a cultist activates it. -can_invoke() is called when a cultist activates the rune with an empty hand. If there are multiple cultists, this rune determines if the required amount is nearby. -invoke() is the rune's actual effects. -fail_invoke() is called when the rune fails, via not enough people around or otherwise. Typically this just has a generic 'fizzle' effect. -structure_check() searches for nearby cultist structures required for the invocation. Proper structures are pylons, forges, archives, and altars. -*/ -/obj/effect/rune/proc/can_invoke(mob/living/user) - if(user.holy_check()) - return - //This proc determines if the rune can be invoked at the time. If there are multiple required cultists, it will find all nearby cultists. - var/list/invokers = list() //people eligible to invoke the rune - var/list/chanters = list() //people who will actually chant the rune when passed to invoke() - if(invisibility == INVISIBILITY_HIDDEN_RUNES)//hidden rune - return - // Get the user - if(user) - chanters |= user - invokers |= user - // Get anyone nearby - if(req_cultists > 1 || allow_excess_invokers) - for(var/mob/living/L in range(1, src)) - if(IS_CULTIST(L)) - if(L == user) - continue - if(L.stat) - continue - invokers |= L - - if(length(invokers) >= req_cultists) // If there's enough invokers - if(allow_excess_invokers) - chanters |= invokers // Let the others join in too - else - invokers -= user - shuffle(invokers) - for(var/i in 0 to req_cultists) - var/L = pick_n_take(invokers) - chanters |= L - return chanters - -/obj/effect/rune/proc/invoke(list/invokers) - //This proc contains the effects of the rune as well as things that happen afterwards. If you want it to spawn an object and then delete itself, have both here. - SHOULD_CALL_PARENT(TRUE) - var/ghost_invokers = 0 - for(var/M in invokers) - var/mob/living/L = M - if(!L) - return - if(L.has_status_effect(STATUS_EFFECT_SUMMONEDGHOST)) - ghost_invokers++ - if(invocation) - if(!L.IsVocal() || L.cannot_speak_loudly()) - L.custom_emote(EMOTE_VISIBLE, message = pick("draws arcane sigils in the air.","gestures ominously.","silently mouths out an invocation.","places their hands on the rune, activating it.")) - else - L.say(invocation) - L.changeNext_move(CLICK_CD_MELEE)//THIS IS WHY WE CAN'T HAVE NICE THINGS - if(invoke_damage) - L.apply_damage(invoke_damage, BRUTE) - to_chat(L, "[src] saps your strength!") - do_invoke_glow() - SSblackbox.record_feedback("nested tally", "runes_invoked", 1, list("[initial(cultist_name)]", "[length(SSticker.mode.cult_team.members)]")) // the name of the rune, and the number of cultists in the cult when it was invoked - if(ghost_invokers) - SSblackbox.record_feedback("nested tally", "runes_invoked_with_ghost", 1, list("[initial(cultist_name)]", "[ghost_invokers]")) //the name of the rune and the number of ghosts used to invoke it. - -/** - * Spawns the phase in/out effects for a cult teleport. - * - * Arguments: - * * user - Mob to teleport - * * location - Location to teleport from - * * target - Location to teleport to - */ -/obj/effect/rune/proc/teleport_effect(mob/living/user, turf/location, turf/target) - new /obj/effect/temp_visual/dir_setting/cult/phase/out(location, user.dir) - new /obj/effect/temp_visual/dir_setting/cult/phase(target, user.dir) - // So that the mob only appears after the effect is finished - user.notransform = TRUE - user.invisibility = INVISIBILITY_MAXIMUM - sleep(12) - user.notransform = FALSE - user.invisibility = 0 - -/obj/effect/rune/proc/do_invoke_glow() - var/oldtransform = transform - animate(src, transform = matrix() * 2, alpha = 0, time = 5) // Fade out - animate(transform = oldtransform, alpha = 255, time = 0) - -/obj/effect/rune/proc/fail_invoke(show_message = TRUE) - //This proc contains the effects of a rune if it is not invoked correctly, through either invalid wording or not enough cultists. By default, it's just a basic fizzle. - if(!invisibility && show_message) // No visible messages if not visible - visible_message("The markings pulse with a small flash of red light, then fall dark.") - animate(src, color = rgb(255, 0, 0), time = 0) - animate(src, color = rune_blood_color, time = 5) - -//Malformed Rune: This forms if a rune is not drawn correctly. Invoking it does nothing but hurt the user. -/obj/effect/rune/malformed - cultist_name = "Malformed" - cultist_desc = "a senseless rune written in gibberish. No good can come from invoking this." - invocation = "Ra'sha yoka!" - invoke_damage = 30 - -/obj/effect/rune/malformed/invoke(list/invokers) - ..() - for(var/M in invokers) - var/mob/living/L = M - to_chat(L, "You feel your life force draining. [GET_CULT_DATA(entity_title3, "Your god")] is displeased.") - qdel(src) - -/mob/proc/null_rod_check() //The null rod, if equipped, will protect the holder from the effects of most runes - if(can_block_magic(MAGIC_RESISTANCE_HOLY)) - return TRUE - return FALSE - -//Rite of Enlightenment: Converts a normal crewmember to the cult, or offer them as sacrifice if cant be converted. -/obj/effect/rune/convert - cultist_name = "Offer" - cultist_desc = "offers non-cultists on top of it to the Dark One, either converting or sacrificing them. Sacrifices with a soul will result in a captured soulshard. This can be done with brains as well." - invocation = "Mah'weyh pleggh at e'ntrath!" - icon_state = "offering" - req_cultists = 1 - allow_excess_invokers = TRUE - rune_in_use = FALSE - -/obj/effect/rune/convert/invoke(list/invokers) - if(rune_in_use) - return - - var/list/offer_targets = list() - var/turf/T = get_turf(src) - for(var/mob/living/M in T) - if(!IS_CULTIST(M) || (M.mind && IS_SACRIFICE_TARGET(M.mind))) - if(isconstruct(M)) // No offering constructs please - continue - offer_targets += M - - // Offering a head/brain - for(var/obj/item/organ/O in T) - var/mob/living/brain/b_mob - if(istype(O, /obj/item/organ/external/head)) // Offering a head - var/obj/item/organ/external/head/H = O - for(var/obj/item/organ/internal/brain/brain in H.contents) - b_mob = brain.brainmob - brain.forceMove(T) - - else if(istype(O, /obj/item/organ/internal/brain)) // Offering a brain - var/obj/item/organ/internal/brain/brain = O - b_mob = brain.brainmob - - if(b_mob && b_mob.mind && (!IS_CULTIST(b_mob) || IS_SACRIFICE_TARGET(b_mob.mind))) - offer_targets += b_mob - - if(!length(offer_targets)) - fail_invoke() - log_game("Offer rune failed - no eligible targets") - rune_in_use = FALSE - return - - rune_in_use = TRUE - var/mob/living/L = pick(offer_targets) - if(HAS_TRAIT(L, TRAIT_CULT_IMMUNITY)) - fail_invoke(FALSE) - for(var/I in invokers) - to_chat(I, "This sacrifice was already converted recently. Wait a minute before trying again!") - rune_in_use = FALSE - return - - if(L.stat != DEAD && SSticker.mode.cult_team.is_convertable_to_cult(L.mind)) - ..() - do_convert(L, invokers) - else - invocation = "Barhah hra zar'garis!" - ..() - do_sacrifice(L, invokers) - rune_in_use = FALSE - -/obj/effect/rune/convert/proc/do_convert(mob/living/convertee, list/invokers) - if(length(invokers) < 2) - fail_invoke() - for(var/I in invokers) - to_chat(I, "You need at least two invokers to convert!") - return - - convertee.visible_message("[convertee] writhes in pain as the markings below them glow a bloody red!", \ - "AAAAAAAAAAAAAA-") - convertee.mind.add_antag_datum(/datum/antagonist/cultist) - to_chat(convertee, "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \ - and something evil takes root.") - to_chat(convertee, "Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve [GET_CULT_DATA(entity_title3, "your god")] above all else. Bring it back.\ - ") - - if(ishuman(convertee)) - var/mob/living/carbon/human/H = convertee - var/brutedamage = convertee.getBruteLoss() - var/burndamage = convertee.getFireLoss() - if(brutedamage || burndamage) // If the convertee is injured - // Heal 90% of all damage, including robotic limbs - H.adjustBruteLoss(-(brutedamage * 0.9), robotic = TRUE) - H.adjustFireLoss(-(burndamage * 0.9), robotic = TRUE) - if(ismachineperson(H)) - H.visible_message("A dark force repairs [convertee]!", - "Your damage has been repaired. Now spread the blood to others.") - else - H.visible_message("[convertee]'s wounds heal and close!", - "Your wounds have been healed. Now spread the blood to others.") - for(var/obj/item/organ/external/E in H.bodyparts) - E.mend_fracture() - E.fix_internal_bleeding() - E.fix_burn_wound() - for(var/datum/disease/critical/crit in H.viruses) // cure all crit conditions - crit.cure() - - H.clear_restraints() - H.Silence(6 SECONDS) //Prevent "HALP MAINT CULT" before you realise you're converted - if(H.reagents?.has_reagent("holywater")) - H.reagents.del_reagent("holywater") // Also prevent fill stomach with holy water and "forgot" about it after converting - - var/obj/item/melee/cultblade/dagger/D = new(get_turf(src)) - if(H.equip_to_slot_if_possible(D, ITEM_SLOT_IN_BACKPACK, FALSE, TRUE)) - to_chat(H, "You have a dagger in your backpack. Use it to do [GET_CULT_DATA(entity_title1, "your god")]'s bidding.") - else - to_chat(H, "There is a dagger on the floor. Use it to do [GET_CULT_DATA(entity_title1, "your god")]'s bidding.") - -/obj/effect/rune/convert/proc/do_sacrifice(mob/living/offering, list/invokers) - var/mob/living/user = invokers[1] //the first invoker is always the user - - if(offering.stat != DEAD || (offering.mind && IS_SACRIFICE_TARGET(offering.mind))) //Requires three people to sacrifice living targets/sacrifice objective - if(length(invokers) < 3) - for(var/M in invokers) - to_chat(M, "[offering] is too greatly linked to the world! You need three acolytes!") - fail_invoke() - log_game("Sacrifice rune failed - not enough acolytes and target is living") - return - - var/sacrifice_fulfilled - var/worthless = FALSE - - if(isliving(offering) && !isbrain(offering)) - var/mob/living/L = offering - if(isrobot(L) || ismachineperson(L)) - L.adjustBruteLoss(250) - else - L.adjustCloneLoss(120) - L.death(FALSE) - - if(offering.mind) - GLOB.sacrificed += offering.mind - if(IS_SACRIFICE_TARGET(offering.mind)) - sacrifice_fulfilled = TRUE - else - GLOB.sacrificed += offering - - new /obj/effect/temp_visual/cult/sac(loc) - for(var/M in invokers) - if(sacrifice_fulfilled) - to_chat(M, "\"Yes! This is the one I desire! You have done well.\"") - if(!SSticker.mode.cult_team.mirror_shields_active) // Only show once - to_chat(M, "You are now able to construct mirror shields inside the daemon forge.") - SSticker.mode.cult_team.mirror_shields_active = TRUE - else - if((ishuman(offering) && offering.mind?.offstation_role && offering.mind.special_role != SPECIAL_ROLE_ERT) || HAS_MIND_TRAIT(offering, TRAIT_XENOBIO_SPAWNED_HUMAN)) //If you try it on a ghost role, or an envolved caterpillar/nymph, you get nothing - to_chat(M, "\"This soul is of no use to either of us.\"") - worthless = TRUE - else if(ishuman(offering) || isrobot(offering)) - to_chat(M, "\"I accept this sacrifice.\"") - else - to_chat(M, "\"I accept this meager sacrifice.\"") - playsound(offering, 'sound/misc/demon_consume.ogg', 100, TRUE, SOUND_RANGE_SET(10)) - - if(((ishuman(offering) || isrobot(offering) || isbrain(offering)) && offering.mind) && !worthless) - var/obj/item/soulstone/stone = new /obj/item/soulstone(get_turf(src)) - stone.invisibility = INVISIBILITY_MAXIMUM // So it's not picked up during transfer_soul() - stone.transfer_soul("FORCE", offering, user) // If it cannot be added - stone.invisibility = 0 - var/put_in_hands = user.put_in_any_hand_if_possible(stone) - if(put_in_hands) - to_chat(user, "A glowing crimson shard appears in your hand - your new ally contained within.") - else - if(isrobot(offering)) - offering.dust() //To prevent the MMI from remaining - else - offering.gib() - playsound(offering, 'sound/magic/disintegrate.ogg', 100, TRUE, SOUND_RANGE_SET(10)) - if(sacrifice_fulfilled) - SSticker.mode.cult_team.successful_sacrifice() - return TRUE - -/obj/effect/rune/teleport - cultist_name = "Teleport" - cultist_desc = "warps everything above it to another chosen teleport rune." - invocation = "Sas'so c'arta forbici!" - icon_state = "teleport" - req_keyword = TRUE - light_power = 4 - var/obj/effect/temp_visual/cult/portal/inner_portal //The portal "hint" for off-station teleportations - var/obj/effect/temp_visual/cult/rune_spawn/rune2/outer_portal - var/listkey - -/obj/effect/rune/teleport/Initialize(mapload, set_keyword) - . = ..() - var/area/A = get_area(src) - var/locname = initial(A.name) - listkey = set_keyword ? "[set_keyword] [locname]":"[locname]" - GLOB.teleport_runes += src - -/obj/effect/rune/teleport/Destroy() - GLOB.teleport_runes -= src - QDEL_NULL(inner_portal) - QDEL_NULL(outer_portal) - return ..() - -/obj/effect/rune/teleport/can_dagger_erase_rune(mob/user) - // Can't erase telerunes if they have a portal open - if(inner_portal || outer_portal) - to_chat(user, "The portal needs to close first!") - return FALSE - return TRUE - -/obj/effect/rune/teleport/invoke(list/invokers) - var/mob/living/user = invokers[1] //the first invoker is always the user - var/list/potential_runes = list() - var/list/teleportnames = list() - var/list/duplicaterunecount = list() - - for(var/I in GLOB.teleport_runes) - var/obj/effect/rune/teleport/R = I - var/resultkey = R.listkey - if(resultkey in teleportnames) - duplicaterunecount[resultkey]++ - resultkey = "[resultkey] ([duplicaterunecount[resultkey]])" - else - teleportnames += resultkey - duplicaterunecount[resultkey] = 1 - if(R != src && is_level_reachable(R.z)) - potential_runes[resultkey] = R - - if(!length(potential_runes)) - to_chat(user, "There are no valid runes to teleport to!") - log_game("Teleport rune failed - no other teleport runes") - fail_invoke() - return - - if(!is_level_reachable(user.z)) - to_chat(user, "You are too far away from the station to teleport!") - log_game("Teleport rune failed - user in away mission") - fail_invoke() - return - - var/input_rune_key = tgui_input_list(user, "Choose a rune to teleport to.", "Rune to Teleport to", 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) || QDELETED(actual_selected_rune) ||!Adjacent(user) || user.incapacitated()) - fail_invoke() - return - - var/turf/T = get_turf(src) - var/turf/target = get_turf(actual_selected_rune) - var/movedsomething = FALSE - var/moveuser = FALSE - for(var/atom/movable/A in T) - if(SEND_SIGNAL(A, COMSIG_MOVABLE_TELEPORTING, target) & COMPONENT_BLOCK_TELEPORT) - continue - if(ishuman(A)) - if(A != user) // Teleporting someone else - INVOKE_ASYNC(src, PROC_REF(teleport_effect), A, T, target) - else // Teleporting yourself - INVOKE_ASYNC(src, PROC_REF(teleport_effect), user, T, target) - if(A.move_resist == INFINITY) - continue //object cant move, shouldnt teleport - if(A == user) - moveuser = TRUE - movedsomething = TRUE - continue - if(!A.anchored) - movedsomething = TRUE - A.forceMove(target) - - if(movedsomething) - ..() - if(is_mining_level(z) && !is_mining_level(target.z)) //No effect if you stay on lavaland - actual_selected_rune.handle_portal("lava") - else if(!is_station_level(z) || isspacearea(get_area(src))) - actual_selected_rune.handle_portal("space", T) - user.visible_message("There is a sharp crack of inrushing air, and everything above the rune disappears!", - "You[moveuser ? "r vision blurs, and you suddenly appear somewhere else":" send everything above the rune away"].") - if(moveuser) - user.forceMove(target) - else - fail_invoke() - -/obj/effect/rune/teleport/proc/handle_portal(portal_type, turf/origin) - var/turf/T = get_turf(src) - if(inner_portal || outer_portal) - close_portal() // To avoid stacking descriptions/animations - playsound(T, pick('sound/effects/sparks1.ogg', 'sound/effects/sparks2.ogg', 'sound/effects/sparks3.ogg', 'sound/effects/sparks4.ogg'), 100, TRUE, 14) - inner_portal = new /obj/effect/temp_visual/cult/portal(T) - - if(portal_type == "space") - light_color = color - desc += "
    A tear in reality reveals a black void interspersed with dots of light... something recently teleported here from space.
    " - - // Space base near the station - if(is_station_level(origin.z)) - desc += "The void feels like it's trying to pull you to the [dir2text(get_dir(T, origin))], near the station!" - // Space base on another Z-level - else - desc += "The void feels like it's trying to pull you to the [dir2text(get_dir(T, origin))], in the direction of space sector [origin.z]!" - - else - inner_portal.icon_state = "lava" - light_color = LIGHT_COLOR_FIRE - desc += "
    A tear in reality reveals a coursing river of lava... something recently teleported here from the Lavaland Mines!" - - outer_portal = new(T, 60 SECONDS, color) - light_range = 4 - update_light() - addtimer(CALLBACK(src, PROC_REF(close_portal)), 60 SECONDS, TIMER_UNIQUE) - -/obj/effect/rune/teleport/proc/close_portal() - qdel(inner_portal) - qdel(outer_portal) - desc = initial(desc) - light_range = 0 - update_light() - - -//Rune of Empowering : Enables carrying 4 blood spells, greatly reduce blood cost -/obj/effect/rune/empower - cultist_name = "Empower" - cultist_desc = "allows cultists to prepare greater amounts of blood magic at far less of a cost." - invocation = "H'drak v'loso, mir'kanas verbot!" - icon_state = "empower" - construct_invoke = FALSE - -/obj/effect/rune/empower/invoke(list/invokers) - . = ..() - var/mob/living/user = invokers[1] //the first invoker is always the user - for(var/datum/action/innate/cult/blood_magic/BM in user.actions) - BM.Activate() - -//Rite of Resurrection: Requires a dead or inactive cultist. When reviving the dead, you can only perform one revival for every three sacrifices your cult has carried out. -/obj/effect/rune/raise_dead - cultist_name = "Revive" - cultist_desc = "requires a dead, alive, mindless, or inactive cultist placed upon the rune. For each three bodies sacrificed to the dark patron, one body will be mended and their mind awoken. Mending living cultist requires two cultists at the rune" - invocation = "Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!" //Depends on the name of the user - see below - icon_state = "revive" - var/static/sacrifices_used = -SOULS_TO_REVIVE // Cultists get one "free" revive - allow_excess_invokers = TRUE - -/obj/effect/rune/raise_dead/examine(mob/user) - . = ..() - if(IS_CULTIST(user) || user.stat == DEAD) - . += "Sacrifices unrewarded: [length(GLOB.sacrificed) - sacrifices_used]" - . += "Sacrifice cost per ressurection: [SOULS_TO_REVIVE]" - -/obj/effect/rune/raise_dead/proc/revive_alive(mob/living/target) - target.visible_message("Dark magic begins to surround [target], regenerating their body.") - if(!do_after(target, 10 SECONDS, FALSE, target, allow_moving = FALSE, progress = TRUE)) - target.visible_message("Dark magic silently disappears.") - return FALSE - target.revive() - return TRUE - -/obj/effect/rune/raise_dead/proc/revive_dead(mob/living/target) - target.revive() - if(target.ghost_can_reenter()) - target.grab_ghost() - return TRUE - -/obj/effect/rune/raise_dead/invoke(list/invokers) - var/turf/T = get_turf(src) - var/mob/living/mob_to_revive - var/list/potential_revive_mobs = list() - var/mob/living/user = invokers[1] - if(rune_in_use) - return - rune_in_use = TRUE - var/diff = length(GLOB.sacrificed) - SOULS_TO_REVIVE - sacrifices_used - var/revived_from_dead = FALSE - if(diff < 0) - to_chat(user, "Your cult must carry out [abs(diff)] more sacrifice\s before it can revive another cultist!") - fail_invoke() - return - for(var/mob/living/M in T.contents) - if(!IS_CULTIST(M)) - continue - potential_revive_mobs |= M - if(!length(potential_revive_mobs)) - to_chat(user, "There are no cultists on the rune!") - log_game("Raise Dead rune failed - no cultists to revive") - fail_invoke() - return - if(length(potential_revive_mobs) > 1) - mob_to_revive = tgui_input_list(user, "Choose a cultist to revive.", "Cultist to Revive", potential_revive_mobs) - else // If there's only one, no need for a menu - mob_to_revive = potential_revive_mobs[1] - if(!validness_checks(mob_to_revive, user)) - fail_invoke() - return - - if(mob_to_revive.stat != DEAD && length(invokers) < 2) - to_chat(user, "You need at least two cultists to heal cultist!") - log_game("Raise Dead rune failed - not enough cultists to heal alive") - fail_invoke() - return - - if(mob_to_revive.stat != DEAD) - if(!revive_alive(mob_to_revive)) - fail_invoke() - return - else - if(!revive_dead(mob_to_revive)) - fail_invoke() - return - revived_from_dead = TRUE - ..() - sacrifices_used += SOULS_TO_REVIVE - - if(!mob_to_revive.get_ghost() && (!mob_to_revive.client || mob_to_revive.client.is_afk())) - set waitfor = FALSE - to_chat(user, "[mob_to_revive] was revived, but their mind is lost! Seeking a lost soul to replace it.") - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Would you like to play as a revived Cultist?", ROLE_CULTIST, TRUE, poll_time = 20 SECONDS, source = /obj/item/melee/cultblade/dagger) - if(length(candidates) && !QDELETED(mob_to_revive)) - var/mob/dead/observer/C = pick(candidates) - to_chat(mob_to_revive, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form.") - message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(mob_to_revive)]) to replace an AFK player.") - mob_to_revive.ghostize(FALSE) - mob_to_revive.key = C.key - dust_if_respawnable(C) - else - fail_invoke() - return - if(!revived_from_dead) - mob_to_revive.visible_message("[mob_to_revive] draws in a huge breath, red light shining from [mob_to_revive.p_their()] eyes.", \ - "All your injuries are now gone!") - rune_in_use = FALSE - return - SEND_SOUND(mob_to_revive, sound('sound/ambience/antag/bloodcult.ogg')) - to_chat(mob_to_revive, "\"PASNAR SAVRAE YAM'TOTH. Arise.\"") - mob_to_revive.visible_message("[mob_to_revive] draws in a huge breath, red light shining from [mob_to_revive.p_their()] eyes.", \ - "You awaken suddenly from the void. You're alive!") - rune_in_use = FALSE - -/obj/effect/rune/raise_dead/proc/validness_checks(mob/living/target_mob, mob/living/user) - if(QDELETED(src)) - return FALSE - if(QDELETED(user)) - return FALSE - if(!Adjacent(user) || user.incapacitated()) - return FALSE - if(QDELETED(target_mob)) - return FALSE - var/turf/T = get_turf(src) - if(target_mob.loc != T) - to_chat(user, "The cultist to revive has been moved!") - log_game("Raise Dead rune failed - revival target moved") - return FALSE - return TRUE - -/obj/effect/rune/raise_dead/fail_invoke() - ..() - rune_in_use = FALSE - for(var/mob/living/M in range(0, src)) - if(IS_CULTIST(M) && M.stat == DEAD) - M.visible_message("[M] twitches.") - -//Rite of the Corporeal Shield: When invoked, becomes solid and cannot be passed. Invoke again to undo. -/obj/effect/rune/wall - cultist_name = "Barrier" - cultist_desc = "when invoked makes a temporary wall to block passage. Can be destroyed by brute force. Can be invoked again to reverse this." - invocation = "Khari'd! Eske'te tannin!" - icon_state = "barrier" - ///The barrier summoned by the rune when invoked. Tracked as a variable to prevent refreshing the barrier's integrity. shieldgen.dm - var/obj/machinery/shield/cult/barrier/B - -/obj/effect/rune/wall/Initialize(mapload) - . = ..() - B = new /obj/machinery/shield/cult/barrier(loc) - B.parent_rune = src - -/obj/effect/rune/wall/Destroy() - if(B && !QDELETED(B)) - QDEL_NULL(B) - return ..() - -/obj/effect/rune/wall/invoke(list/invokers) - var/mob/living/user = invokers[1] - ..() - var/amount = 1 - if(B.Toggle()) // Toggling on - for(var/obj/effect/rune/wall/rune in orange(1, src)) // Chaining barriers - if(!rune.B.density) // Barrier is currently invisible - amount++ // Count the invoke damage for each rune - rune.do_invoke_glow() - rune.B.Toggle() - if(iscarbon(user)) - var/mob/living/carbon/C = user - C.cult_self_harm(2 * amount) - -//Rite of Joined Souls: Summons a single cultist. -/obj/effect/rune/summon - cultist_name = "Summon Cultist" - cultist_desc = "summons a single cultist to the rune. (Cannot summon restrained cultists!)" - invocation = "N'ath reth sh'yro eth d'rekkathnor!" - req_cultists = 2 - invoke_damage = 10 - icon_state = "summon" - -/obj/effect/rune/summon/invoke(list/invokers) - var/mob/living/user = invokers[1] - var/list/cultists = list() - - for(var/datum/mind/M in SSticker.mode.cult_team.members) - if(!(M.current in invokers) && M.current && M.current.stat != DEAD) - cultists[M.current.real_name] = M.current - var/input = tgui_input_list(user, "Who do you wish to call to [src]?", "Acolytes", cultists) - var/mob/living/cultist_to_summon = cultists[input] - if(QDELETED(src) || !Adjacent(user) || user.incapacitated()) - return - if(!cultist_to_summon) - log_game("Summon Cultist rune failed - no target") - return - if(cultist_to_summon.stat == DEAD) - to_chat(user, "[cultist_to_summon] has died!") - fail_invoke() - log_game("Summon Cultist rune failed - target died") - return - if(cultist_to_summon.pulledby || cultist_to_summon.buckled) - to_chat(user, "[cultist_to_summon] is being held in place!") - to_chat(cultist_to_summon, "You feel a tugging sensation, but you are being held in place!") - fail_invoke() - log_game("Summon Cultist rune failed - target restrained") - return - if(!IS_CULTIST(cultist_to_summon)) - to_chat(user, "[cultist_to_summon] is not a follower of [GET_CULT_DATA(entity_title3, "our god")]!") - fail_invoke() - log_game("Summon Cultist rune failed - target was deconverted") - return - if(is_away_level(cultist_to_summon.z)) - to_chat(user, "[cultist_to_summon] is not in our dimension!") - fail_invoke() - log_game("Summon Cultist rune failed - target in away mission") - return - if(SEND_SIGNAL(cultist_to_summon, COMSIG_MOVABLE_TELEPORTING, get_turf(src)) & COMPONENT_BLOCK_TELEPORT) - to_chat(user, "[cultist_to_summon] is anchored in bluespace!") - fail_invoke() - log_game("Summon Cultist rune failed - anchored in bluespace") - return - - cultist_to_summon.visible_message("[cultist_to_summon] suddenly disappears in a flash of red light!", \ - "Overwhelming vertigo consumes you as you are hurled through the air!") - ..() - INVOKE_ASYNC(src, PROC_REF(teleport_effect), cultist_to_summon, get_turf(cultist_to_summon), get_turf(src)) - visible_message("[src] begins to bubble and rises into the form of [cultist_to_summon]!") - cultist_to_summon.forceMove(get_turf(src)) - qdel(src) - -/** - * # Blood Boil Rune - * - * When invoked deals up to 30 burn damage to nearby non-cultists and sets them on fire. - * - * On activation the rune charges for six seconds, changing colour, glowing, and giving out a warning to all nearby mobs. - * After the charging period the rune burns any non-cultists in view and sets them on fire. After another short wait it does the same again with slightly higher damage. - * If the cultists channeling the rune move away or are stunned at any point, the rune is deleted. So it can be countered pretty easily with flashbangs. - */ -/obj/effect/rune/blood_boil - cultist_name = "Boil Blood" - cultist_desc = "boils the blood of non-believers who can see the rune, rapidly dealing extreme amounts of damage. Requires 2 invokers channeling the rune." - invocation = "Dedo ol'btoh!" - icon_state = "blood_boil" - light_color = LIGHT_COLOR_LAVA - req_cultists = 2 - invoke_damage = 15 - construct_invoke = FALSE - var/tick_damage = 10 // 30 burn damage total + damage taken by being on fire/overheating - rune_in_use = FALSE - -/obj/effect/rune/blood_boil/invoke(list/invokers) - if(rune_in_use) - return - ..() - rune_in_use = TRUE - var/turf/T = get_turf(src) - var/list/targets = list() - for(var/mob/living/L in viewers(T)) - if(!IS_CULTIST(L) && L.blood_volume && !ismachineperson(L)) - var/atom/I = L.null_rod_check() - if(I) - if(isitem(I)) - to_chat(L, "[I] suddenly burns hotly before returning to normal!") - continue - targets += L - - // Six seconds buildup - visible_message("A haze begins to form above [src]!") - animate(src, color = "#FC9A6D", time = 6 SECONDS) - set_light(6, 1, color) - sleep(6 SECONDS) - visible_message("[src] turns a bright, burning orange!") - if(!burn_check()) - return - - for(var/I in targets) - to_chat(I, "Your blood boils in your veins!") - do_area_burn(T, 1) - animate(src, color = "#FFDF80", time = 5 SECONDS) - sleep(5 SECONDS) - if(!burn_check()) - return - - do_area_burn(T, 2) - animate(src, color = "#FFFFFF", time = 5 SECONDS) - sleep(5 SECONDS) - if(!burn_check()) - return - - do_area_burn(T, 3) - qdel(src) - -/obj/effect/rune/blood_boil/proc/do_area_burn(turf/T, iteration) - var/multiplier = iteration / 2 // Iteration 1 = 0.5, Iteration 2 = 1, etc. - set_light(6, 1 * iteration, color) - for(var/mob/living/L in viewers(T)) - if(!IS_CULTIST(L) && L.blood_volume && !ismachineperson(L)) - if(L.null_rod_check()) - continue - L.take_overall_damage(0, tick_damage * multiplier) - L.adjust_fire_stacks(2) - L.IgniteMob() - playsound(src, 'sound/effects/bamf.ogg', 100, TRUE) - do_invoke_glow() - sleep(0.6 SECONDS) // Only one 'animate()' can play at once, so this waits for the pulse to finish - -/obj/effect/rune/blood_boil/proc/burn_check() - . = TRUE - if(QDELETED(src)) - return FALSE - var/list/cultists = list() - for(var/mob/living/M in range(1, src)) // Get all cultists currently in range - if(IS_CULTIST(M) && !M.incapacitated()) - cultists += M - - if(length(cultists) < req_cultists) // Stop the rune there's not enough invokers - visible_message("[src] loses its glow and dissipates!") - qdel(src) - -/obj/effect/rune/manifest - cultist_name = "Spirit Realm" - cultist_desc = "manifests a spirit servant of the Dark One and allows you to ascend as a spirit yourself. The invoker must not move from atop the rune, and will take damage for each summoned spirit." - invocation = "Gal'h'rfikk harfrandid mud'gib!" //how the fuck do you pronounce this - icon_state = "spirit_realm" - construct_invoke = FALSE - var/mob/dead/observer/ghost = null //The cult ghost of the user - var/default_ghost_limit = 4 //Lowered by the amount of cult objectives done - var/minimum_ghost_limit = 2 //But cant go lower than this - var/ghosts = 0 - -/obj/effect/rune/manifest/examine(mob/user) - . = ..() - if(IS_CULTIST(user) || user.stat == DEAD) - . += "Amount of ghosts summoned: [ghosts]" - . += "Maximum amount of ghosts: [clamp(default_ghost_limit - SSticker.mode.cult_team.sacrifices_done, minimum_ghost_limit, default_ghost_limit)]" - . += "Lowers to a minimum of [minimum_ghost_limit] for each objective accomplished." - -/obj/effect/rune/manifest/invoke(list/invokers) - . = ..() - var/mob/living/user = invokers[1] - var/turf/T = get_turf(src) - if(!(user in get_turf(src))) - to_chat(user, "You must be standing on [src]!") - fail_invoke() - log_game("Manifest rune failed - user not standing on rune") - return - if(user.has_status_effect(STATUS_EFFECT_SUMMONEDGHOST)) - to_chat(user, "Ghosts can't summon more ghosts!") - fail_invoke() - log_game("Manifest rune failed - user is a ghost") - return - - var/choice = tgui_alert(user, "You tear open a connection to the spirit realm...", "Invoke", list("Summon a Cult Ghost", "Ascend as a Dark Spirit", "Cancel")) - if(choice == "Summon a Cult Ghost") - if(!is_station_level(z) || isspacearea(get_area(src))) - to_chat(user, "The veil is not weak enough here to manifest spirits, you must be on station!") - fail_invoke() - log_game("Manifest rune failed - not on station") - return - if(user.health <= 40) - to_chat(user, "Your body is too weak to manifest spirits, heal yourself first.") - fail_invoke() - log_game("Manifest rune failed - not enough health") - return list() - if(ghosts >= clamp(default_ghost_limit - SSticker.mode.cult_team.sacrifices_done, minimum_ghost_limit, default_ghost_limit)) - to_chat(user, "You are sustaining too many ghosts to summon more!") - fail_invoke() - log_game("Manifest rune failed - too many summoned ghosts") - return list() - summon_ghosts(user, T) - - else if(choice == "Ascend as a Dark Spirit") - ghostify(user, T) - - -/obj/effect/rune/manifest/proc/summon_ghosts(mob/living/user, turf/T) - notify_ghosts("Manifest rune created in [get_area(src)].", ghost_sound = 'sound/effects/ghost2.ogg', source = src) - var/list/ghosts_on_rune = list() - for(var/mob/dead/observer/O in T) - if(!O.client) - continue - if(IS_CULTIST(O) || jobban_isbanned(O, ROLE_CULTIST)) - continue - if(!HAS_TRAIT(O, TRAIT_RESPAWNABLE) || QDELETED(src) || QDELETED(O)) - continue - if(!O.mind) - continue - if(O.mind.current && HAS_TRAIT(O.mind.current, SCRYING)) - continue - ghosts_on_rune += O - if(!length(ghosts_on_rune)) - to_chat(user, "There are no spirits near [src]!") - fail_invoke() - log_game("Manifest rune failed - no nearby ghosts") - return list() - - var/mob/dead/observer/ghost_to_spawn = pick(ghosts_on_rune) - var/mob/living/carbon/human/new_human = new(T) - new_human.real_name = ghost_to_spawn.real_name - new_human.key = ghost_to_spawn.key - new_human.gender = ghost_to_spawn.gender - new_human.alpha = 150 //Makes them translucent - new_human.equipOutfit(/datum/outfit/ghost_cultist) //give them armor - new_human.apply_status_effect(STATUS_EFFECT_SUMMONEDGHOST, user) //ghosts can't summon more ghosts, also lets you see actual ghosts - for(var/obj/item/organ/external/current_organ in new_human.bodyparts) - current_organ.limb_flags |= CANNOT_DISMEMBER //you can't chop of the limbs of a ghost, silly - ghosts++ - playsound(src, 'sound/misc/exit_blood.ogg', 50, TRUE, SOUND_RANGE_SET(10)) - user.visible_message("A cloud of red mist forms above [src], and from within steps... a [new_human.gender == FEMALE ? "wo" : ""]man.", - "Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely...") - - var/obj/machinery/shield/cult/weak/shield = new(T) - new_human.mind.add_antag_datum(/datum/antagonist/cultist) - to_chat(new_human, "You are a servant of [GET_CULT_DATA(entity_title3, "the cult")]. You have been made semi-corporeal by the cult of [GET_CULT_DATA(entity_name, "your god")], and you are to serve them at all costs.") - - while(!QDELETED(src) && !QDELETED(user) && !QDELETED(new_human) && (user in T)) - if(new_human.InCritical()) - to_chat(user, "You feel your connection to [new_human.real_name] severs as they are destroyed.") - if(ghost) - to_chat(ghost, "You feel your connection to [new_human.real_name] severs as they are destroyed.") - break - if(user.stat || user.health <= 40) - to_chat(user, "Your body can no longer sustain the connection, and your link to the spirit realm fades.") - if(ghost) - to_chat(ghost, "Your body is damaged and your connection to the spirit realm weakens, any ghost you may have manifested are destroyed.") - break - user.apply_damage(0.1, BRUTE) - user.apply_damage(0.1, BURN) - sleep(2) //Takes two pylons to sustain the damage taken by summoning one ghost - - qdel(shield) - ghosts-- - if(new_human) - new_human.visible_message("[new_human] suddenly dissolves into bones and ashes.", - "Your link to the world fades. Your form breaks apart.") - for(var/obj/item/I in new_human.get_all_slots()) - new_human.drop_item_to_ground(I) - new_human.mind.remove_antag_datum(/datum/antagonist/cultist, silent_removal = TRUE) - new_human.dust() - -/obj/effect/rune/manifest/proc/ghostify(mob/living/user, turf/T) - ADD_TRAIT(user, SCRYING, CULT_TRAIT) - user.visible_message("[user] freezes statue-still, glowing an unearthly red.", - "You see what lies beyond. All is revealed. In this form you find that your voice booms above all others.") - ghost = user.ghostize(TRUE, RUNE_COLOR_DARKRED, "Dark Spirit of [user.name]") - var/datum/action/innate/cult/comm/spirit/CM = new - var/datum/action/innate/cult/check_progress/V = new - //var/datum/action/innate/cult/ghostmark/GM = new - CM.Grant(ghost) - V.Grant(ghost) - //GM.Grant(ghost) - while(!QDELETED(user)) - if(user.key || QDELETED(src)) - user.visible_message("[user] slowly relaxes, the glow around [user.p_them()] dimming.", - "You are re-united with your physical form. [src] releases its hold over you.") - user.Weaken(6 SECONDS) - break - if(user.health <= 10) - to_chat(ghost, "Your body can no longer sustain the connection!") - break - if(!(user in T)) - user.visible_message("A spectral tendril wraps around [user] and pulls [user.p_them()] back to the rune!") - Beam(user, icon_state = "drainbeam", time = 2) - user.forceMove(get_turf(src)) //NO ESCAPE :^) - sleep(5) - if(user.grab_ghost()) - CM.Remove(ghost) - V.Remove(ghost) - //GM.Remove(ghost) - REMOVE_TRAIT(user, SCRYING, CULT_TRAIT) - user.remove_atom_colour(ADMIN_COLOUR_PRIORITY, RUNE_COLOR_DARKRED) - user = null - rune_in_use = FALSE - - -//Ritual of Dimensional Rending: Calls forth the avatar of Nar'Sie upon the station. -/obj/effect/rune/narsie - cultist_name = "Tear Veil" - cultist_desc = "tears apart dimensional barriers, calling forth your god." - invocation = "TOK-LYR RQA-NAP G'OLT-ULOFT!!" - req_cultists = 9 - icon = 'icons/effects/96x96.dmi' - icon_state = "rune_large" - pixel_x = -32 //So the big ol' 96x96 sprite shows up right - pixel_y = -32 - mouse_opacity = MOUSE_OPACITY_ICON //we're huge and easy to click - scribe_delay = 45 SECONDS //how long the rune takes to create - scribe_damage = 10 //how much damage you take doing it - var/used = FALSE - -/obj/effect/rune/narsie/Initialize(mapload) - . = ..() - cultist_name = "Summon [GET_CULT_DATA(entity_name, "your god")]" - cultist_desc = "tears apart dimensional barriers, calling forth [GET_CULT_DATA(entity_title3, "your god")]." - -/obj/effect/rune/narsie/cult_conceal() //can't hide this, and you wouldn't want to - return - -/obj/effect/rune/narsie/is_cleanable() //No, you can't just yeet a cleaning grenade to remove it. - return FALSE - -/obj/effect/rune/narsie/invoke(list/invokers) - if(used) - return - var/mob/living/user = invokers[1] - if(!is_station_level(user.z)) - message_admins("[key_name_admin(user)] tried to summon an eldritch horror off station") - log_game("Summon Nar'Sie rune failed - off station Z level") - return - if(SSticker.mode.cult_team.cult_status == NARSIE_HAS_RISEN) - for(var/M in invokers) - to_chat(M, "\"I am already here. There is no need to try to summon me now.\"") - log_game("Summon god rune failed - already summoned") - return - - //BEGIN THE SUMMONING - SSticker.mode.cult_team.successful_summon() - used = TRUE - color = COLOR_RED - ..() - - for(var/mob/M in GLOB.player_list) - if(!isnewplayer(M)) // exclude people in the lobby - SEND_SOUND(M, sound('sound/effects/dimensional_rend.ogg')) - to_chat(M, "The veil... is... TORN!!!--") - - icon_state = "rune_large_distorted" - var/turf/T = get_turf(src) - sleep(40) - new /obj/singularity/narsie/large(T) //Causes Nar'Sie to spawn even if the rune has been removed - -/obj/effect/rune/narsie/attackby__legacy__attackchain(obj/I, mob/user, params) //Since the narsie rune takes a long time to make, add logging to removal. - if((istype(I, /obj/item/melee/cultblade/dagger) && IS_CULTIST(user))) - log_game("Summon Narsie rune erased by [key_name(user)] with a cult dagger") - message_admins("[key_name_admin(user)] erased a Narsie rune with a cult dagger") - if(istype(I, /obj/item/nullrod)) //Begone foul magiks. You cannot hinder me. - log_game("Summon Narsie rune erased by [key_name(user)] using a null rod") - message_admins("[key_name_admin(user)] erased a Narsie rune with a null rod") - return ..() diff --git a/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm b/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm deleted file mode 100644 index 6d2273bc087f8..0000000000000 --- a/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm +++ /dev/null @@ -1,215 +0,0 @@ -/datum/objective/abductee - completed = TRUE - needs_target = FALSE - -/datum/objective/abductee/steal - explanation_text = "Steal all" - -/datum/objective/abductee/steal/New() - ..() - var/target = pick("pets","lights","monkeys","fruits","shoes","bars of soap", "weapons", "computers", "organs") - explanation_text +=" [target]." - -/datum/objective/abductee/paint - explanation_text = "The station is hideous. You must color it all" - -/datum/objective/abductee/paint/New() - ..() - var/color = pick("red", "blue", "green", "yellow", "orange", "purple", "black", "in rainbows", "in blood") - explanation_text += " [color]!" - -/datum/objective/abductee/speech - explanation_text = "Your brain is broken... you can only communicate in" - -/datum/objective/abductee/speech/New() - ..() - var/style = pick("pantomime", "rhyme", "haiku", "extended metaphors", "riddles", "extremely literal terms", "sound effects", "military jargon") - explanation_text += " [style]." - -/datum/objective/abductee/capture - explanation_text = "Capture" - -/datum/objective/abductee/capture/New() - ..() - var/list/jobs = SSjobs.occupations.Copy() - for(var/datum/job/J in jobs) - if(J.current_positions < 1) - jobs -= J - if(length(jobs) > 0) - var/datum/job/target = pick(jobs) - explanation_text += " a [target.title]." - else - explanation_text += " someone." - -/datum/objective/abductee/shuttle - explanation_text = "You must escape the station! Get the shuttle called!" - -/datum/objective/abductee/noclone - explanation_text = "Don't allow anyone to be cloned." - -/datum/objective/abductee/oxygen - explanation_text = "The oxygen is killing them all and they don't even know it. Make sure no oxygen is on the station." - -/datum/objective/abductee/blazeit - explanation_text = "Your body must be improved. Ingest as many drugs as you can." - -/datum/objective/abductee/yumyum - explanation_text = "You are hungry. Eat as much food as you can find." - -/datum/objective/abductee/insane - explanation_text = "You see you see what they cannot you see the open door you seeE you SEeEe you SEe yOU seEee SHOW THEM ALL" - -/datum/objective/abductee/cannotmove - explanation_text = "Convince the crew that you are a paraplegic." - -/datum/objective/abductee/deadbodies - explanation_text = "Start a collection of corpses. Don't kill people to get these corpses." - -/datum/objective/abductee/floors - explanation_text = "Replace all the floor tiles with wood, carpeting, grass or bling." - -/datum/objective/abductee/powerunlimited - explanation_text = "Flood the station's powernet with as much electricity as you can." - -/datum/objective/abductee/pristine - explanation_text = "The CEO of Nanotrasen is coming! Ensure the station is in absolutely pristine condition." - -/datum/objective/abductee/nowalls - explanation_text = "The crew must get to know one another better. Break down the walls inside the station!" - -/datum/objective/abductee/nations - explanation_text = "Ensure your department prospers over all else." - -/datum/objective/abductee/abductception - explanation_text = "You have been changed forever. Find the ones that did this to you and give them a taste of their own medicine." - -/datum/objective/abductee/summon - explanation_text = "The elder gods hunger. Gather a cult and conduct a ritual to summon one." - -/datum/objective/abductee/machine - explanation_text = "You are secretly an android. Interface with as many machines as you can to boost your own power so the AI may acknowledge you at last." - -/datum/objective/abductee/calling - explanation_text = "Call forth a spirit from the other side." - -/datum/objective/abductee/calling/New() - ..() - var/mob/dead/D = pick(GLOB.dead_mob_list) - if(D) - explanation_text = "You know that [D] has perished. Hold a seance to call them from the spirit realm." - -/datum/objective/abductee/social_experiment - explanation_text = "This is a secret social experiment conducted by Nanotrasen. Convince the crew that this is the truth." - -/datum/objective/abductee/vr - explanation_text = "It's all an entirely virtual simulation within an underground vault. Convince the crew to escape the shackles of VR." - -/datum/objective/abductee/pets - explanation_text = "Nanotrasen is abusing the animals! Save as many as you can!" - -/datum/objective/abductee/defect - explanation_text = "Fuck the system! Defect from the station and start an independent colony in space, Mining Outpost or the derelict. Recruit crewmates if you can." - -/datum/objective/abductee/promote - explanation_text = "Climb the corporate ladder all the way to the top!" - -/datum/objective/abductee/science - explanation_text = "So much lies undiscovered. Look deeper into the machinations of the universe." - -/datum/objective/abductee/build - explanation_text = "Expand the station." - -/datum/objective/abductee/engine - explanation_text = "Go have a good conversation with the singularity/tesla/supermatter crystal. Bonus points if it responds." - -/datum/objective/abductee/music - explanation_text = "You burn with passion for music. Share your vision. If anyone hates it, beat them on the head with your instrument!" - -/datum/objective/abductee/clown - explanation_text = "The clown is not funny. You can do better! Steal his audience and make the crew laugh!" - -/datum/objective/abductee/party - explanation_text = "You're throwing a huge rager. Make it as awesome as possible so the whole crew comes... OR ELSE!" - -/datum/objective/abductee/cooler_pets - explanation_text = "All the pets around here suck. You need to make them cooler. Replace them with exotic beasts!" - -/datum/objective/abductee/conspiracy - explanation_text = "The leaders of this station are hiding a grand, evil conspiracy. Only you can learn what it is, and expose it to the people!" - -/datum/objective/abductee/stalker - explanation_text = "The Syndicate has hired you to compile dossiers on all important members of the crew. Be sure they don't know you're doing it." - -/datum/objective/abductee/narrator - explanation_text = "You're the narrator of this tale. Follow around the protagonists to tell their story." - -/datum/objective/abductee/lurve - explanation_text = "You are doomed to feel woefully incomplete forever... until you find your true love on this station. They're waiting for you!" - -/datum/objective/abductee/sixthsense - explanation_text = "You died back there and went to heaven... or is it hell? No one here seems to know they're dead. Convince them, and maybe you can escape this limbo." - -/datum/objective/abductee/forbiddennumber - explanation_text = "Ignore anything in a set number of" - -/datum/objective/abductee/forbiddennumber/New() - ..() - var/number = pick("two", "three", "four", "five", "six", "seven", "eight", "nine", "ten") - explanation_text +=" [number], they don't exist." - -/datum/objective/abductee/buddy - explanation_text = "Being alone and in large groups are both frightening. Try to be alone with only one other person whenever possible." - -/datum/objective/abductee/finality - explanation_text = "Death should be final and modern medicine disrupts the natural order. Don't allow anyone to be revived." - -/datum/objective/abductee/mispronounced - explanation_text = "No matter how they say it, other people keep mispronouncing your name. Be sure to correct them whenever possible." - -/datum/objective/abductee/bald - explanation_text = "There are alien parasites masquerading as people's hair. Save people from this invasion." - -/datum/objective/abductee/one - explanation_text = "There is only one other person in existence, they are just really good at pretending to be multiple people." - -/datum/objective/abductee/outlaw - explanation_text = "You have infiltrated this station as a space-renowned outlaw, commit as many minor crimes as possible while remaining unnoticed by security." - -/datum/objective/abductee/rot - explanation_text = "Your flesh is rotting from your body. Fight the inevitable, and replace your tainted limbs with entirely new ones." - -/datum/objective/abductee/blind - explanation_text = "You are blind. Perhaps a new pair of eyes can help." - -/datum/objective/abductee/ill - explanation_text = "The station is ill. Medicate them until they're cured." - -/datum/objective/abductee/game - explanation_text = "Convince the crew that we are in a game, without explicitly telling them we are in a game." - -/datum/objective/abductee/instructor - explanation_text = "You are a military instructor. You must make sure the crew is in top shape for the war against the syndicate!" - -/datum/objective/abductee/actor - explanation_text = "You are in an action movie. You must say as many cheesy one-liners as possible." - -/datum/objective/abductee/writer - explanation_text = "You are a writer. Convince the crew of your superb writing skills!" - -/datum/objective/abductee/doomed - explanation_text = "You know something bad is about to happen to this station. Convince the crew to get off of it while they still can!" - -/datum/objective/abductee/proof - explanation_text = "You think you were kidnapped by aliens! Ensure that" - -/datum/objective/abductee/proof/New() - ..() - var/list/jobs = SSjobs.occupations.Copy() - for(var/datum/job/J in jobs) - if(J.current_positions < 1) - jobs -= J - if(length(jobs)) - var/datum/job/target = pick(jobs) - explanation_text += " a [target.title] is also experimented on by an Abductor so they believe you!" - else - explanation_text += " someone is also experimented on by an Abductor so they believe you!" diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm deleted file mode 100644 index 7052199a26ce9..0000000000000 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ /dev/null @@ -1,136 +0,0 @@ -/datum/game_mode/abduction - name = "abduction" - config_tag = "abduction" - recommended_enemies = 2 - required_players = 15 - abductor_teams = 1 - single_antag_positions = list() - var/max_teams = 4 - var/finished = FALSE - -/datum/game_mode/abduction/announce() - to_chat(world, "The current game mode is - Abduction!") - to_chat(world, "There are alien abductors sent to [world.name] to perform nefarious experiments!") - to_chat(world, "Abductors - kidnap the crew and replace their organs with experimental ones.") - to_chat(world, "Crew - don't get abducted and stop the abductors.") - -/datum/game_mode/abduction/pre_setup() - var/possible_abductors = get_players_for_role(ROLE_ABDUCTOR) - if(!length(possible_abductors)) - return FALSE - - abductor_teams = clamp(min(round(num_players() / 15), round(length(possible_abductors) / 2)), 1, max_teams) - - for(var/i in 1 to abductor_teams) - var/datum/mind/mind_1 = pick_n_take(possible_abductors) - var/datum/mind/mind_2 = pick_n_take(possible_abductors) - if(!mind_1 || !mind_2) - break - new /datum/team/abductor(list(mind_1, mind_2)) - - // Add a special role so they dont pick up any other antagonist stuff - mind_1.assigned_role = SPECIAL_ROLE_ABDUCTOR_AGENT - mind_1.special_role = SPECIAL_ROLE_ABDUCTOR_AGENT - mind_1.offstation_role = TRUE - - mind_2.assigned_role = SPECIAL_ROLE_ABDUCTOR_SCIENTIST - mind_2.special_role = SPECIAL_ROLE_ABDUCTOR_SCIENTIST - mind_2.offstation_role = TRUE - ..() - return TRUE - -/datum/game_mode/abduction/post_setup() - for(var/datum/team/abductor/team in actual_abductor_teams) - team.create_agent() - team.create_scientist() - return ..() - -/datum/game_mode/abduction/proc/get_team_console(team_number) - for(var/obj/machinery/abductor/console/C in GLOB.machines) - if(C.team == team_number) - return C - -/datum/game_mode/abduction/check_finished() - if(!finished) - for(var/datum/team/abductor/team in actual_abductor_teams) - var/obj/machinery/abductor/console/con = get_team_console(team.team_number) - if(con.experiment.points >= team.experiment_objective.target_amount) - SSshuttle.emergency.request(null, 0.5, reason = "Large amount of abnormal thought patterns detected. All crew are recalled for mandatory evaluation and reconditioning.") - SSshuttle.emergency.canRecall = FALSE - finished = TRUE - return ..() - return ..() - -/datum/game_mode/abduction/declare_completion() - for(var/datum/team/abductor/team in actual_abductor_teams) - var/obj/machinery/abductor/console/console = get_team_console(team.team_number) - if(console.experiment.points >= team.experiment_objective.target_amount) - to_chat(world, "[team.name] team fulfilled its mission!") - else - to_chat(world, "[team.name] team failed its mission.") - ..() - return 1 - -/datum/game_mode/proc/auto_declare_completion_abduction() - var/list/text = list() - if(length(abductors)) - text += "
    The abductors were:
    " - for(var/datum/mind/abductor_mind in abductors) - text += printplayer(abductor_mind) - text += "
    " - text += printobjectives(abductor_mind) - text += "
    " - if(length(abductees)) - text += "
    The abductees were:
    " - for(var/datum/mind/abductee_mind in abductees) - text += printplayer(abductee_mind) - text += "
    " - text += printobjectives(abductee_mind) - text += "
    " - return text.Join("") - -//Landmarks -// TODO: Split into seperate landmarks for prettier ships -/obj/effect/landmark/abductor - icon = 'icons/effects/spawner_icons.dmi' - icon_state = "Abductor" - var/team = 1 - -/obj/effect/landmark/abductor/agent -/obj/effect/landmark/abductor/scientist - - -// OBJECTIVES -//No check completion, it defaults to being completed unless an admin sets it to failed. -/datum/objective/stay_hidden - explanation_text = "Limit contact with your targets outside of conducting your experiments and abduction." - completed = TRUE - needs_target = FALSE - -/datum/objective/experiment - explanation_text = "Experiment on some humans." - target_amount = 6 - needs_target = FALSE - /// Which abductor team number does this belong to. - var/abductor_team_number - -/datum/objective/experiment/New() - ..() - explanation_text = "Experiment on [target_amount] humans." - -/datum/objective/experiment/check_completion() - var/ab_team = abductor_team_number - var/list/owners = get_owners() - for(var/datum/mind/M in owners) - if(!M.current || !ishuman(M.current) || !isabductor(M.current)) - return FALSE - var/mob/living/carbon/human/H = M.current - var/datum/species/abductor/S = H.dna.species - ab_team = S.team - for(var/obj/machinery/abductor/experiment/E in GLOB.machines) - if(E.team == ab_team) - if(E.points >= target_amount) - return TRUE - else - return FALSE - return FALSE diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm deleted file mode 100644 index 02bc96a04065a..0000000000000 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ /dev/null @@ -1,930 +0,0 @@ -#define GIZMO_SCAN 1 -#define GIZMO_MARK 2 -#define MIND_DEVICE_MESSAGE 1 -#define MIND_DEVICE_CONTROL 2 - -#define BATON_STUN 0 -#define BATON_SLEEP 1 -#define BATON_CUFF 2 -#define BATON_PROBE 3 -#define BATON_MODES 4 - -/* -CONTENTS: -1. AGENT GEAR -2. SCIENTIST GEAR -3. ENGINEERING TOOLS -4. MEDICAL TOOLS -5. JANITORIAL TOOLS -6. STRUCTURES -*/ - -// Setting up abductor exclusivity. -/obj/item/abductor - name = "generic abductor item" - icon = 'icons/obj/abductor.dmi' - desc = "You are not supposed to be able to see this. If you can see this, please make an issue report on GitHub." - -/obj/item/abductor/proc/AbductorCheck(user) - if(isabductor(user)) - return TRUE - to_chat(user, "You can't figure how this works!") - return FALSE - -/obj/item/abductor/proc/ScientistCheck(user) - if(!AbductorCheck(user)) - return FALSE - - var/mob/living/carbon/human/H = user - var/datum/species/abductor/S = H.dna.species - if(S.scientist) - return TRUE - to_chat(user, "You're not trained to use this!") - return FALSE - -///////////////////////////////////////// -/////////////// AGENT GEAR ////////////// -///////////////////////////////////////// -/obj/item/clothing/head/helmet/abductor - name = "agent headgear" - desc = "Abduct with style - spiky style. Prevents digital tracking." - icon_state = "alienhelmet" - item_state = "alienhelmet" - blockTracking = 1 - origin_tech = "materials=7;magnets=4;abductor=3" - flags = BLOCKHAIR - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE - - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/head.dmi' - ) - -/obj/item/clothing/suit/armor/abductor/vest - name = "agent vest" - desc = "A vest outfitted with advanced stealth technology. It has two modes - combat and stealth." - icon = 'icons/obj/abductor.dmi' - icon_state = "vest_stealth" - item_state = "armor" - blood_overlay_type = "armor" - origin_tech = "magnets=7;biotech=4;powerstorage=4;abductor=4" - armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 10, RAD = 10, FIRE = 115, ACID = 115) - actions_types = list(/datum/action/item_action/hands_free/activate) - allowed = list(/obj/item/abductor, /obj/item/abductor_baton, /obj/item/melee/baton, /obj/item/gun/energy, /obj/item/restraints/handcuffs) - var/mode = ABDUCTOR_VEST_STEALTH - var/stealth_active = 0 - var/combat_cooldown = 10 - var/datum/icon_snapshot/disguise - var/stealth_armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 10, RAD = 10, FIRE = 115, ACID = 115) - var/combat_armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, RAD = 50, FIRE = 450, ACID = 450) - sprite_sheets = null - -/obj/item/clothing/suit/armor/abductor/vest/Initialize(mapload) - . = ..() - stealth_armor = getArmor(arglist(stealth_armor)) - combat_armor = getArmor(arglist(combat_armor)) - -/obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop() - flags ^= NODROP - if(ismob(loc)) - to_chat(loc, "Your vest is now [flags & NODROP ? "locked" : "unlocked"].") - -/obj/item/clothing/suit/armor/abductor/vest/proc/flip_mode() - switch(mode) - if(ABDUCTOR_VEST_STEALTH) - mode = ABDUCTOR_VEST_COMBAT - DeactivateStealth() - armor = combat_armor - icon_state = "vest_combat" - if(ABDUCTOR_VEST_COMBAT)// TO STEALTH - mode = ABDUCTOR_VEST_STEALTH - armor = stealth_armor - icon_state = "vest_stealth" - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.update_inv_wear_suit() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtons() - -/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user) - if(slot == ITEM_SLOT_OUTER_SUIT) //we only give the mob the ability to activate the vest if he's actually wearing it. - return 1 - -/obj/item/clothing/suit/armor/abductor/vest/proc/SetDisguise(datum/icon_snapshot/entry) - disguise = entry - -/obj/item/clothing/suit/armor/abductor/vest/proc/ActivateStealth() - if(disguise == null) - return - stealth_active = 1 - if(ishuman(loc)) - var/mob/living/carbon/human/M = loc - new /obj/effect/temp_visual/dir_setting/ninja/cloak(get_turf(M), M.dir) - M.name_override = disguise.name - M.icon = disguise.icon - M.icon_state = disguise.icon_state - M.overlays = disguise.overlays - M.update_inv_r_hand() - M.update_inv_l_hand() - SEND_SIGNAL(M, COMSIG_CARBON_REGENERATE_ICONS) - -/obj/item/clothing/suit/armor/abductor/vest/proc/DeactivateStealth() - if(!stealth_active) - return - stealth_active = 0 - if(ishuman(loc)) - var/mob/living/carbon/human/M = loc - new /obj/effect/temp_visual/dir_setting/ninja(get_turf(M), M.dir) - M.name_override = null - M.overlays.Cut() - M.regenerate_icons() - -/obj/item/clothing/suit/armor/abductor/vest/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - DeactivateStealth() - -/obj/item/clothing/suit/armor/abductor/vest/IsReflect() - DeactivateStealth() - return 0 - -/obj/item/clothing/suit/armor/abductor/vest/ui_action_click() - switch(mode) - if(ABDUCTOR_VEST_COMBAT) - Adrenaline() - if(ABDUCTOR_VEST_STEALTH) - if(stealth_active) - DeactivateStealth() - else - ActivateStealth() - -/obj/item/clothing/suit/armor/abductor/vest/proc/Adrenaline() - if(ishuman(loc)) - if(combat_cooldown != initial(combat_cooldown)) - to_chat(loc, "Combat injection is still recharging.") - return - var/mob/living/carbon/human/M = loc - M.adjustStaminaLoss(-75) - M.SetParalysis(0) - M.SetStunned(0) - M.SetWeakened(0) - M.SetKnockDown(0) - M.stand_up(TRUE) - combat_cooldown = 0 - START_PROCESSING(SSobj, src) - -/obj/item/clothing/suit/armor/abductor/vest/process() - combat_cooldown++ - if(combat_cooldown==initial(combat_cooldown)) - STOP_PROCESSING(SSobj, src) - -/obj/item/clothing/suit/armor/abductor/Destroy() - STOP_PROCESSING(SSobj, src) - for(var/obj/machinery/abductor/console/C in GLOB.machines) - if(C.vest == src) - C.vest = null - break - return ..() - -/obj/item/abductor/silencer - name = "abductor silencer" - desc = "A compact device used to shut down communications equipment." - icon_state = "silencer" - item_state = "silencer" - origin_tech = "materials=4;programming=7;abductor=3" - -/obj/item/abductor/silencer/attack__legacy__attackchain(mob/living/M, mob/user) - if(!AbductorCheck(user)) - return - radio_off(M, user) - -/obj/item/abductor/silencer/afterattack__legacy__attackchain(atom/target, mob/living/user, flag, params) - if(flag) - return - if(!AbductorCheck(user)) - return - radio_off(target, user) - -/obj/item/abductor/silencer/proc/radio_off(atom/target, mob/living/user) - if(!(user in (viewers(7, target)))) - return - - var/turf/targloc = get_turf(target) - - var/mob/living/carbon/human/M - for(M in view(2,targloc)) - if(M == user) - continue - to_chat(user, "You silence [M]'s radio devices.") - radio_off_mob(M) - -/obj/item/abductor/silencer/proc/radio_off_mob(mob/living/carbon/human/M) - var/list/all_items = M.GetAllContents() - - for(var/obj/I in all_items) - if(isradio(I)) - var/obj/item/radio/R = I - R.listening = FALSE // Prevents the radio from buzzing due to the EMP, preserving possible stealthiness. - R.emp_act(EMP_HEAVY) - -/obj/item/gun/energy/alien - name = "alien pistol" - desc = "A complicated gun that fires bursts of high-intensity radiation." - ammo_type = list(/obj/item/ammo_casing/energy/declone) - restricted_species = list(/datum/species/abductor) - icon_state = "alienpistol" - item_state = "alienpistol" - origin_tech = "combat=4;magnets=7;powerstorage=3;abductor=3" - trigger_guard = TRIGGER_GUARD_ALLOW_ALL - can_holster = TRUE - -/obj/item/abductor_baton - name = "advanced baton" - desc = "A quad-mode baton used for incapacitation and restraining of specimens." - var/mode = BATON_STUN - icon = 'icons/obj/abductor.dmi' - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon_state = "wonderprodStun" - item_state = "wonderprod" - slot_flags = ITEM_SLOT_BELT - origin_tech = "materials=4;combat=4;biotech=7;abductor=4" - w_class = WEIGHT_CLASS_NORMAL - actions_types = list(/datum/action/item_action/toggle_mode) - -/obj/item/abductor_baton/proc/toggle(mob/living/user = usr) - mode = (mode+1)%BATON_MODES - var/txt - switch(mode) - if(BATON_STUN) - txt = "stunning" - if(BATON_SLEEP) - txt = "sleep inducement" - if(BATON_CUFF) - txt = "restraining" - if(BATON_PROBE) - txt = "probing" - - to_chat(usr, "You switch the baton to [txt] mode.") - update_icon(UPDATE_ICON_STATE) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtons() - -/obj/item/abductor_baton/update_icon_state() - switch(mode) - if(BATON_STUN) - icon_state = "wonderprodStun" - item_state = "wonderprodStun" - if(BATON_SLEEP) - icon_state = "wonderprodSleep" - item_state = "wonderprodSleep" - if(BATON_CUFF) - icon_state = "wonderprodCuff" - item_state = "wonderprodCuff" - if(BATON_PROBE) - icon_state = "wonderprodProbe" - item_state = "wonderprodProbe" - -/obj/item/abductor_baton/attack__legacy__attackchain(mob/target, mob/living/user) - if(!isabductor(user)) - return - - - if(!isliving(target)) - return - - var/mob/living/L = target - - user.do_attack_animation(L) - - if(isrobot(L)) - L.apply_damage(80, STAMINA) //Force a reboot on two hits for consistency. - return - - if(ishuman(L)) - var/mob/living/carbon/human/H = L - if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) - playsound(L, 'sound/weapons/genhit.ogg', 50, 1) - return 0 - - switch(mode) - if(BATON_STUN) - StunAttack(L,user) - if(BATON_SLEEP) - SleepAttack(L,user) - if(BATON_CUFF) - CuffAttack(L,user) - if(BATON_PROBE) - ProbeAttack(L,user) - -/obj/item/abductor_baton/attack_self__legacy__attackchain(mob/living/user) - toggle(user) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() - -/obj/item/abductor_baton/proc/StunAttack(mob/living/L,mob/living/user) - L.lastattacker = user.real_name - L.lastattackerckey = user.ckey - - L.KnockDown(7 SECONDS) - L.apply_damage(80, STAMINA) - L.Stuttering(14 SECONDS) - - L.visible_message("[user] has stunned [L] with [src]!", \ - "[user] has stunned you with [src]!") - playsound(loc, 'sound/weapons/egloves.ogg', 50, TRUE, -1) - - add_attack_logs(user, L, "Stunned with [src]") - -/obj/item/abductor_baton/proc/SleepAttack(mob/living/L, mob/living/user) - var/mob/living/carbon/C = L - if(!iscarbon(L)) - return - if((C.getStaminaLoss() < 100) && !C.IsSleeping()) - C.AdjustDrowsy(2 SECONDS) - to_chat(user, "Sleep inducement works fully only on stunned or asleep specimens!") - C.visible_message("[user] tried to induce sleep in [L] with [src]!", \ - "You suddenly feel drowsy!") - return - if(do_mob(user, C, 2.5 SECONDS)) - C.visible_message("[user] has induced sleep in [L] with [src]!", \ - "You suddenly feel very drowsy!") - playsound(loc, 'sound/weapons/egloves.ogg', 50, TRUE, -1) - C.Sleeping(120 SECONDS) - add_attack_logs(user, C, "Put to sleep with [src]") - -/obj/item/abductor_baton/proc/CuffAttack(mob/living/L,mob/living/user) - if(!iscarbon(L)) - return - var/mob/living/carbon/C = L - if(!C.handcuffed) - playsound(loc, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2) - C.visible_message("[user] begins restraining [C] with [src]!", \ - "[user] begins shaping an energy field around your hands!") - if(do_mob(user, C, 3 SECONDS)) - if(!C.handcuffed) - C.handcuffed = new /obj/item/restraints/handcuffs/energy(C) - C.update_handcuffed() - to_chat(user, "You handcuff [C].") - add_attack_logs(user, C, "Handcuffed ([src])") - else - to_chat(user, "You fail to handcuff [C].") - -/obj/item/abductor_baton/proc/ProbeAttack(mob/living/L,mob/living/user) - L.visible_message("[user] probes [L] with [src]!", \ - "[user] probes you!") - - var/species = "Unknown species" - var/helptext = "Species unsuitable for experiments." - - if(ishuman(L)) - var/mob/living/carbon/human/H = L - species = "[H.dna.species.name]" - if(IS_CHANGELING(L)) - species = "Changeling lifeform" - var/obj/item/organ/internal/heart/gland/temp = locate() in H.internal_organs - if(temp) - helptext = "Experimental gland detected!" - else - helptext = "Subject suitable for experiments." - - to_chat(user,"Probing result: [species]") - to_chat(user, "[helptext]") - -/obj/item/restraints/handcuffs/energy - name = "hard-light energy field" - desc = "A hard-light field restraining the hands." - icon_state = "cablecuff" // Needs sprite - breakouttime = 450 - origin_tech = "materials=4;magnets=5;abductor=2" - flags = DROPDEL - -/obj/item/restraints/handcuffs/energy/finish_resist_restraints(mob/living/carbon/user, break_cuffs, silent) - user.visible_message("[src] restraining [user] breaks in a discharge of energy!", "[src] restraining [user] breaks in a discharge of energy!") - break_cuffs = TRUE - silent = TRUE - do_sparks(4, 0, user.loc) - . = ..() - -/obj/item/abductor_baton/examine(mob/user) - . = ..() - switch(mode) - if(BATON_STUN) - . += "The baton is in stun mode." - if(BATON_SLEEP) - . += "The baton is in sleep inducement mode." - if(BATON_CUFF) - . += "The baton is in restraining mode." - if(BATON_PROBE) - . += "The baton is in probing mode." - -/obj/item/radio/headset/abductor - name = "alien headset" - desc = "An advanced alien headset designed to monitor communications of human space stations. Why does it have a microphone? No one knows." - flags = EARBANGPROTECT - origin_tech = "magnets=2;abductor=3" - icon = 'icons/obj/abductor.dmi' - icon_state = "abductor_headset" - item_state = "abductor_headset" - ks2type = /obj/item/encryptionkey/heads/captain - -/obj/item/radio/headset/abductor/Initialize(mapload) - . = ..() - make_syndie() // Why the hell is this a proc why cant it just be a subtype - -/obj/item/radio/headset/abductor/screwdriver_act() - return // Stops humans from disassembling abductor headsets. - -///////////////////////////////////////// -///////////// SCIENTIST GEAR //////////// -///////////////////////////////////////// -/obj/item/abductor/gizmo - name = "science tool" - desc = "A dual-mode tool for retrieving specimens and scanning appearances. Scanning can be done through cameras." - icon_state = "gizmo_scan" - item_state = "gizmo" - origin_tech = "engineering=7;magnets=4;bluespace=4;abductor=3" - var/mode = GIZMO_SCAN - var/mob/living/marked = null - var/obj/machinery/abductor/console/console - -/obj/item/abductor/gizmo/attack_self__legacy__attackchain(mob/user) - if(!ScientistCheck(user)) - return - if(!console) - to_chat(user, "The device is not linked to a console!") - return - - if(mode == GIZMO_SCAN) - mode = GIZMO_MARK - icon_state = "gizmo_mark" - else - mode = GIZMO_SCAN - icon_state = "gizmo_scan" - to_chat(user, "You switch the device to [mode==GIZMO_SCAN? "SCAN": "MARK"] MODE") - -/obj/item/abductor/gizmo/attack__legacy__attackchain(mob/living/M, mob/user) - if(!ScientistCheck(user)) - return - if(!console) - to_chat(user, "The device is not linked to console!") - return - - switch(mode) - if(GIZMO_SCAN) - scan(M, user) - if(GIZMO_MARK) - mark(M, user) - -/obj/item/abductor/gizmo/afterattack__legacy__attackchain(atom/target, mob/living/user, flag, params) - if(flag) - return - if(!ScientistCheck(user)) - return - if(!console) - to_chat(user, "The device is not linked to console!") - return - - switch(mode) - if(GIZMO_SCAN) - scan(target, user) - if(GIZMO_MARK) - mark(target, user) - -/obj/item/abductor/gizmo/proc/scan(atom/target, mob/living/user) - if(ishuman(target)) - console.AddSnapshot(target) - to_chat(user, "You scan [target] and add [target.p_them()] to the database.") - -/obj/item/abductor/gizmo/proc/mark(atom/target, mob/living/user) - if(marked == target) - to_chat(user, "This specimen is already marked!") - return - if(ishuman(target)) - if(isabductor(target)) - marked = target - to_chat(user, "You mark [target] for future retrieval.") - else - prepare(target,user) - else - prepare(target,user) - -/obj/item/abductor/gizmo/proc/prepare(atom/target, mob/living/user) - if(get_dist(target,user)>1) - to_chat(user, "You need to be next to the specimen to prepare it for transport!") - return - to_chat(user, "You begin preparing [target] for transport...") - if(do_after(user, 100, target = target)) - marked = target - to_chat(user, "You finish preparing [target] for transport.") - -/obj/item/abductor/gizmo/Destroy() - if(console) - console.gizmo = null - return ..() - -/obj/item/abductor/mind_device - name = "mental interface device" - desc = "A dual-mode tool for directly communicating with sentient brains. It can be used to send a direct message to a target, or to send a command to a test subject with a charged gland." - icon_state = "mind_device_message" - item_state = "silencer" - var/mode = MIND_DEVICE_MESSAGE - -/obj/item/abductor/mind_device/attack_self__legacy__attackchain(mob/user) - if(!ScientistCheck(user)) - return - - if(mode == MIND_DEVICE_MESSAGE) - mode = MIND_DEVICE_CONTROL - icon_state = "mind_device_control" - else - mode = MIND_DEVICE_MESSAGE - icon_state = "mind_device_message" - to_chat(user, "You switch the device to [mode == MIND_DEVICE_MESSAGE ? "TRANSMISSION" : "COMMAND"] MODE") - -/obj/item/abductor/mind_device/afterattack__legacy__attackchain(atom/target, mob/living/user, flag, params) - if(!ScientistCheck(user)) - return - - switch(mode) - if(MIND_DEVICE_CONTROL) - mind_control(target, user) - if(MIND_DEVICE_MESSAGE) - mind_message(target, user) - -/obj/item/abductor/mind_device/proc/mind_control(atom/target, mob/living/user) - if(iscarbon(target)) - var/mob/living/carbon/C = target - var/obj/item/organ/internal/heart/gland/G = C.get_organ_slot("heart") - if(!istype(G)) - to_chat(user, "Your target does not have an experimental gland!") - return - if(!G.mind_control_uses) - to_chat(user, "Your target's gland is spent!") - return - if(G.active_mind_control) - to_chat(user, "Your target is already under a mind-controlling influence!") - return - - var/command = tgui_input_text(user, "Enter the command for your target to follow. Uses Left: [G.mind_control_uses], Duration: [DisplayTimeText(G.mind_control_duration)]", "Enter command") - if(!command) - return - if(QDELETED(user) || user.get_active_hand() != src || loc != user) - return - if(QDELETED(G)) - return - G.mind_control(command, user) - to_chat(user, "You send the command to your target.") - -/obj/item/abductor/mind_device/proc/mind_message(atom/target, mob/living/user) - if(isliving(target)) - var/mob/living/L = target - if(L.stat == DEAD) - to_chat(user, "Your target is dead!") - return - var/message = tgui_input_text(user, "Write a message to send to your target's brain.", "Enter message") - if(!message) - return - if(QDELETED(L) || L.stat == DEAD) - return - - to_chat(L, "You hear a voice in your head saying: [message]") - to_chat(user, "You send the message to your target.") - log_say("[key_name(user)] sent an abductor mind message to [key_name(L)]: '[message]'", user) - -/obj/item/paper/abductor - name = "Dissection Guide" - icon_state = "alienpaper_words" - info = {"Dissection for Dummies
    -
    - 1.Acquire fresh specimen.
    - 2.Put the specimen on operating table.
    - 3.Apply scalpel to the chest, preparing for experimental dissection.
    - 4.Apply scalpel to specimen's torso.
    - 5.Clamp bleeders on specimen's torso with a hemostat.
    - 6.Retract skin of specimen's torso with a retractor.
    - 7.Saw through the specimen's torso with a saw.
    - 8.Apply retractor again to specimen's torso.
    - 9.Search through the specimen's torso with your hands to remove any superfluous organs.
    - 10.Insert replacement gland (Retrieve one from gland storage).
    - 11.Cauterize the patient's torso with a cautery.
    - 12.Consider dressing the specimen back to not disturb the habitat.
    - 13.Put the specimen in the experiment machinery.
    - 14.Choose one of the machine options. The target will be analyzed and teleported to the selected drop-off point.
    - 15.You will receive one supply credit, and the subject will be counted towards your quota.
    -
    -Congratulations! You are now trained for invasive xenobiology research!"} - -/obj/item/paper/abductor/update_icon_state() - return - -/obj/item/paper/abductor/AltClick() - return - -///////////////////////////////////////// -/////////// ENGINEERING TOOLS /////////// -///////////////////////////////////////// -/obj/item/screwdriver/abductor - name = "alien screwdriver" - desc = "An ultrasonic screwdriver." - icon = 'icons/obj/abductor.dmi' - icon_state = "screwdriver" - belt_icon = null - usesound = 'sound/items/pshoom.ogg' - toolspeed = 0.1 - random_color = FALSE - -/obj/item/wrench/abductor - name = "alien wrench" - desc = "A polarized wrench. It causes anything placed between the jaws to turn." - icon = 'icons/obj/abductor.dmi' - icon_state = "wrench" - belt_icon = null - usesound = 'sound/effects/empulse.ogg' - toolspeed = 0.1 - origin_tech = "materials=5;engineering=5;abductor=3" - -/obj/item/weldingtool/abductor - name = "alien welding tool" - desc = "An alien welding tool. Whatever fuel it uses, it never runs out." - icon = 'icons/obj/abductor.dmi' - icon_state = "welder" - belt_icon = null - toolspeed = 0.1 - w_class = WEIGHT_CLASS_SMALL - light_intensity = 0 - origin_tech = "plasmatech=5;engineering=5;abductor=3" - requires_fuel = FALSE - refills_over_time = TRUE - low_fuel_changes_icon = FALSE - -/obj/item/crowbar/abductor - name = "alien crowbar" - desc = "A hard-light crowbar. It appears to pry by itself, without any effort required." - icon = 'icons/obj/abductor.dmi' - icon_state = "crowbar" - belt_icon = null - usesound = 'sound/weapons/sonic_jackhammer.ogg' - toolspeed = 0.1 - w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=4;engineering=4;abductor=3" - -/obj/item/wirecutters/abductor - name = "alien wirecutters" - desc = "Extremely sharp wirecutters, made out of a silvery-green metal." - icon = 'icons/obj/abductor.dmi' - icon_state = "cutters" - belt_icon = null - toolspeed = 0.1 - origin_tech = "materials=5;engineering=4;abductor=3" - random_color = FALSE - -/obj/item/wirecutters/abductor/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT) - -/obj/item/multitool/abductor - name = "alien multitool" - desc = "An omni-technological interface." - icon = 'icons/obj/abductor.dmi' - icon_state = "multitool" - belt_icon = null - toolspeed = 0.1 - w_class = WEIGHT_CLASS_SMALL - origin_tech = "magnets=5;engineering=5;abductor=3" - -/obj/item/multitool/abductor/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT) - -/obj/item/storage/belt/military/abductor - name = "agent belt" - desc = "A belt used by abductor agents." - icon = 'icons/obj/abductor.dmi' - icon_state = "belt" - item_state = "security" - -/obj/item/storage/belt/military/abductor/full/populate_contents() - new /obj/item/screwdriver/abductor(src) - new /obj/item/wrench/abductor(src) - new /obj/item/weldingtool/abductor(src) - new /obj/item/crowbar/abductor(src) - new /obj/item/wirecutters/abductor(src) - new /obj/item/multitool/abductor(src) - new /obj/item/stack/cable_coil(src, 30, COLOR_WHITE) - -///////////////////////////////////////// -/////////// MEDICAL TOOLS /////////////// -///////////////////////////////////////// -/obj/item/scalpel/alien - name = "alien scalpel" - desc = "It's a gleaming sharp knife made out of silvery-green metal." - icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" - toolspeed = 0.25 - -/obj/item/hemostat/alien - name = "alien hemostat" - desc = "You've never seen this before." - icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" - toolspeed = 0.25 - -/obj/item/retractor/alien - name = "alien retractor" - desc = "You're not sure if you want the veil pulled back." - icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" - toolspeed = 0.25 - -/obj/item/circular_saw/alien - name = "alien saw" - desc = "Do the aliens also lose this, and need to find an alien hatchet?" - icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" - toolspeed = 0.25 - -/obj/item/surgicaldrill/alien - name = "alien drill" - desc = "Maybe alien surgeons have finally found a use for the drill." - icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" - toolspeed = 0.25 - -/obj/item/cautery/alien - name = "alien cautery" - desc = "Why would bloodless aliens have a tool to stop bleeding? Unless..." - icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" - toolspeed = 0.25 - -/obj/item/bonegel/alien - name = "alien bone gel" - desc = "It smells like duct tape." - icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" - toolspeed = 0.25 - -/obj/item/fix_o_vein/alien - name = "alien FixOVein" - desc = "Bloodless aliens would totally know how to stop internal bleeding... Right?" - icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" - toolspeed = 0.25 - -/obj/item/bonesetter/alien - name = "alien bone setter" - desc = "You're not sure you want to know whether or not aliens have bones." - icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" - toolspeed = 0.25 - -///////////////////////////////////////// -//////////// JANITORIAL TOOLS /////////// -///////////////////////////////////////// -/obj/item/mop/advanced/abductor - name = "alien mop" - desc = "A collapsible mop clearly used by aliens to clean up any evidence of a close encounter. The head produces a constant supply of water when run over a surface, seemingly out of nowhere." - icon = 'icons/obj/abductor.dmi' - icon_state = "mop_abductor" - mopcap = 100 - origin_tech = "materials=3;engineering=3;abductor=2" - refill_rate = 50 - refill_reagent = "water" - mopspeed = 10 - -/obj/item/soap/syndie/abductor - name = "alien soap" - desc = "Even bloodless aliens need to wash the grime off. Smells like gunpowder." - icon = 'icons/obj/abductor.dmi' - icon_state = "soap_abductor" - -/obj/item/lightreplacer/bluespace/abductor - name = "alien light replacer" - desc = "It's important to keep all the mysterious lights on a UFO functional when flying over backwater country." - icon = 'icons/obj/abductor.dmi' - icon_state = "lightreplacer_abductor" - origin_tech = "magnets=3;engineering=4;abductor=2" - max_uses = 40 - uses = 20 - -/obj/item/melee/flyswatter/abductor - name = "alien flyswatter" - desc = "For killing alien insects, obviously." - icon = 'icons/obj/abductor.dmi' - icon_state = "flyswatter_abductor" - item_state = "flyswatter_abductor" - origin_tech = "abductor=1" - force = 2 // Twice as powerful thanks to alien technology! - throwforce = 2 - -/obj/item/reagent_containers/spray/cleaner/safety/abductor // Essentially an Advanced Space Cleaner, but abductor-themed. For the implant. - name = "alien space cleaner" - desc = "An alien spray bottle contaning alien-brand non-foaming space cleaner! It only accepts space cleaner." - icon = 'icons/obj/abductor.dmi' - icon_state = "cleaner_abductor" - item_state = "cleaner_abductor" - volume = 500 - spray_maxrange = 3 - spray_currentrange = 3 - list_reagents = list("cleaner" = 500) - -/obj/item/storage/belt/janitor/abductor - name = "alien janibelt" - desc = "A belt used to hold out-of-this-world cleaning supplies! Used by abductors to keep their ships clean." - icon = 'icons/obj/abductor.dmi' - icon_state = "janibelt_abductor" - item_state = "security" - storage_slots = 7 - can_hold = list( - /obj/item/grenade/chem_grenade/cleaner, - /obj/item/lightreplacer, - /obj/item/flashlight, - /obj/item/reagent_containers/spray, - /obj/item/soap, - /obj/item/holosign_creator/janitor, - /obj/item/melee/flyswatter, - /obj/item/storage/bag/trash, - /obj/item/push_broom, - /obj/item/door_remote/janikeyring, - /obj/item/mop/advanced/abductor - ) - -/obj/item/storage/belt/janitor/abductor/full/populate_contents() - new /obj/item/mop/advanced/abductor(src) - new /obj/item/soap/syndie/abductor(src) - new /obj/item/lightreplacer/bluespace/abductor(src) - new /obj/item/storage/bag/trash/bluespace(src) - new /obj/item/melee/flyswatter/abductor(src) - new /obj/item/reagent_containers/spray/cleaner/safety/abductor(src) - new /obj/item/holosign_creator/janitor(src) - -///////////////////////////////////////// -/////////////// STRUCTURES ////////////// -///////////////////////////////////////// -/obj/structure/bed/abductor - name = "resting contraption" - desc = "This looks similar to contraptions from earth. Could aliens be stealing our technology?" - icon = 'icons/obj/abductor.dmi' - buildstacktype = /obj/item/stack/sheet/mineral/abductor - icon_state = "bed" - -/obj/structure/table_frame/abductor - name = "alien table frame" - desc = "A sturdy table frame made from alien alloy." - icon_state = "alien_frame" - framestack = /obj/item/stack/sheet/mineral/abductor - framestackamount = 1 - density = TRUE - anchored = TRUE - resistance_flags = FIRE_PROOF | ACID_PROOF - restrict_table_types = list(/obj/item/stack/sheet/mineral/silver = /obj/machinery/optable/abductor, /obj/item/stack/sheet/mineral/abductor = /obj/item/stack/sheet/mineral/abductor::table_type) - -/obj/structure/table/abductor - name = "alien table" - desc = "Advanced flat surface technology at work!" - icon = 'icons/obj/smooth_structures/tables/alien_table.dmi' - icon_state = "alien_table-0" - base_icon_state = "alien_table" - buildstack = /obj/item/stack/sheet/mineral/abductor - framestack = /obj/item/stack/sheet/mineral/abductor - buildstackamount = 1 - framestackamount = 1 - smoothing_groups = list(SMOOTH_GROUP_ABDUCTOR_TABLES) - canSmoothWith = list(SMOOTH_GROUP_ABDUCTOR_TABLES) - frame = /obj/structure/table_frame/abductor - -/obj/machinery/optable/abductor - icon = 'icons/obj/abductor.dmi' - icon_state = "bed" - no_icon_updates = 1 //no icon updates for this; it's static. - injected_reagents = list("corazone","spaceacillin") - reagent_target_amount = 31 //the patient needs at least 30u of spaceacillin to prevent necrotization. - inject_amount = 10 - -/obj/structure/closet/abductor - name = "alien locker" - desc = "Contains secrets of the universe." - icon_state = "abductor" - door_anim_time = 0 - material_drop = /obj/item/stack/sheet/mineral/abductor - -/obj/structure/door_assembly/door_assembly_abductor - name = "alien airlock assembly" - icon = 'icons/obj/doors/airlocks/abductor/abductor_airlock.dmi' - base_name = "alien airlock" - overlays_file = 'icons/obj/doors/airlocks/abductor/overlays.dmi' - airlock_type = /obj/machinery/door/airlock/abductor - material_type = /obj/item/stack/sheet/mineral/abductor - noglass = TRUE - -#undef GIZMO_SCAN -#undef GIZMO_MARK -#undef MIND_DEVICE_MESSAGE -#undef MIND_DEVICE_CONTROL -#undef BATON_STUN -#undef BATON_SLEEP -#undef BATON_CUFF -#undef BATON_PROBE -#undef BATON_MODES diff --git a/code/game/gamemodes/miniantags/demons/demon.dm b/code/game/gamemodes/miniantags/demons/demon.dm deleted file mode 100644 index 91aa036212b5c..0000000000000 --- a/code/game/gamemodes/miniantags/demons/demon.dm +++ /dev/null @@ -1,39 +0,0 @@ -/mob/living/simple_animal/demon - name = "a generic demon" - desc = "you shouldnt be reading this, file a github report." - speak_emote = list("gurgles") - emote_hear = list("wails","screeches") - response_help = "thinks better of touching" - response_disarm = "flails at" - response_harm = "punches" - speed = 1 - a_intent = INTENT_HARM - mob_biotypes = MOB_ORGANIC | MOB_HUMANOID - stop_automated_movement = TRUE - status_flags = CANPUSH - attack_sound = 'sound/misc/demon_attack1.ogg' - death_sound = 'sound/misc/demon_dies.ogg' - 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 - maxbodytemp = INFINITY - faction = list("demon") - attacktext = "wildly tears into" - maxHealth = 200 - health = 200 - environment_smash = ENVIRONMENT_SMASH_STRUCTURES - obj_damage = 50 - melee_damage_lower = 30 - melee_damage_upper = 30 - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - del_on_death = TRUE - var/datum/action/innate/demon_whisper/whisper_action - -/mob/living/simple_animal/demon/Initialize(mapload) - . = ..() - whisper_action = new() - whisper_action.Grant(src) - -/mob/living/simple_animal/demon/Destroy() - QDEL_NULL(whisper_action) - return ..() diff --git a/code/game/gamemodes/miniantags/demons/slaughter_demon/slaughter.dm b/code/game/gamemodes/miniantags/demons/slaughter_demon/slaughter.dm deleted file mode 100644 index dedc9c679eeec..0000000000000 --- a/code/game/gamemodes/miniantags/demons/slaughter_demon/slaughter.dm +++ /dev/null @@ -1,359 +0,0 @@ -//////////////////The Monster - -/mob/living/simple_animal/demon/slaughter - name = "slaughter demon" - real_name = "slaughter demon" - desc = "A large, menacing creature covered in armored black scales. You should run." - maxHealth = 240 - health = 240 - speak = list("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri", "orkan", "allaq") - icon = 'icons/mob/mob.dmi' - icon_state = "daemon" - icon_living = "daemon" - var/boost = 0 - var/feast_sound = 'sound/misc/demon_consume.ogg' - var/devoured = 0 - var/list/consumed_mobs = list() - - var/list/nearby_mortals = list() - var/cooldown = 0 - var/gorecooldown = 0 - var/vialspawned = FALSE - loot = list(/obj/effect/decal/cleanable/blood/innards, /obj/effect/decal/cleanable/blood, /obj/effect/gibspawner/generic, /obj/effect/gibspawner/generic, /obj/item/organ/internal/heart/demon/slaughter) - var/playstyle_string = "You are the Slaughter Demon, a terrible creature from another existence. You have a single desire: to kill. \ - You may use the blood crawl icon when on blood pools to travel through them, appearing and dissapearing from the station at will. \ - Pulling a dead or critical mob while you enter a pool will pull them in with you, allowing you to feast. \ - You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. " - del_on_death = TRUE - deathmessage = "screams in anger as it collapses into a puddle of viscera!" - - -/mob/living/simple_animal/demon/slaughter/New() - ..() - remove_from_all_data_huds() - ADD_TRAIT(src, TRAIT_BLOODCRAWL_EAT, "bloodcrawl_eat") - var/datum/spell/bloodcrawl/bloodspell = new - AddSpell(bloodspell) - if(istype(loc, /obj/effect/dummy/slaughter)) - bloodspell.phased = TRUE - addtimer(CALLBACK(src, PROC_REF(attempt_objectives)), 5 SECONDS) - - -/mob/living/simple_animal/demon/slaughter/Life(seconds, times_fired) - ..() - if(boost < world.time) - speed = 1 - else - speed = 0 - -/mob/living/simple_animal/demon/slaughter/proc/attempt_objectives() - if(mind) - var/list/messages = list() - messages.Add(playstyle_string) - messages.Add("You are not currently in the same plane of existence as the station. Use the blood crawl action at a blood pool to manifest.") - SEND_SOUND(src, sound('sound/misc/demon_dies.ogg')) - if(!vialspawned) - SSticker.mode.traitors |= mind - mind.add_mind_objective(/datum/objective/slaughter) - mind.add_mind_objective(/datum/objective/demon_fluff) - messages.Add(mind.prepare_announce_objectives(FALSE)) - - messages.Add("For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Slaughter_Demon)") - to_chat(src, chat_box_red(messages.Join("
    "))) - - -/obj/effect/decal/cleanable/blood/innards - icon = 'icons/obj/surgery.dmi' - icon_state = "innards" - name = "pile of viscera" - desc = "A repulsive pile of guts and gore." - -/mob/living/simple_animal/demon/slaughter/Destroy() - // Only execute the below if we successfully died - for(var/mob/living/M in consumed_mobs) - REMOVE_TRAIT(M, TRAIT_UNREVIVABLE, "demon") - release_consumed(M) - . = ..() - -/mob/living/simple_animal/demon/slaughter/proc/release_consumed(mob/living/M) - M.forceMove(get_turf(src)) - - -// Midround slaughter demon, less tanky - -/mob/living/simple_animal/demon/slaughter/lesser - maxHealth = 170 - health = 170 - -// Cult slaughter demon -/// Summoned as part of the cult objective "Bring the Slaughter" -/mob/living/simple_animal/demon/slaughter/cult - name = "harbinger of the slaughter" - real_name = "harbinger of the Slaughter" - desc = "An awful creature from beyond the realms of madness." - maxHealth = 540 - health = 540 - melee_damage_upper = 60 - melee_damage_lower = 60 - environment_smash = ENVIRONMENT_SMASH_RWALLS //Smashes through EVERYTHING - r-walls included - faction = list("cult") - playstyle_string = "You are a Harbinger of the Slaughter. Brought forth by the servants of Nar'Sie, you have a single purpose: slaughter the heretics \ - who do not worship your master. You may use the ability 'Blood Crawl' near a pool of blood to enter it and become incorporeal. Using the ability again near a blood pool will allow you \ - to emerge from it. You are fast, powerful, and almost invincible. By dragging a dead or unconscious body into a blood pool with you, you will consume it after a time and fully regain \ - your health. You may use the ability 'Sense Victims' in your Cultist tab to locate a random, living heretic.
    " - -/datum/spell/sense_victims - name = "Sense Victims" - desc = "Sense the location of heretics." - base_cooldown = 0 - clothes_req = FALSE - cooldown_min = 0 - overlay = null - action_icon_state = "bloodcrawl" - action_background_icon_state = "bg_cult" - -/datum/spell/sense_victims/create_new_targeting() - return new /datum/spell_targeting/alive_mob_list - -/datum/spell/sense_victims/valid_target(mob/living/target, user) - return target.stat == CONSCIOUS && target.key && !IS_CULTIST(target) // Only conscious, non cultist players - -/datum/spell/sense_victims/cast(list/targets, mob/user) - var/mob/living/victim = targets[1] - to_chat(victim, "You feel an awful sense of being watched...") - victim.Stun(6 SECONDS) //HUE - var/area/A = get_area(victim) - if(!A) - to_chat(user, "You could not locate any sapient heretics for the Slaughter.") - return 0 - to_chat(user, "You sense a terrified soul at [A]. Show [A.p_them()] the error of [A.p_their()] ways.") - -/mob/living/simple_animal/demon/slaughter/cult/New() - ..() - spawn(5) - var/list/demon_candidates = SSghost_spawns.poll_candidates("Do you want to play as a slaughter demon?", ROLE_DEMON, TRUE, 10 SECONDS, source = /mob/living/simple_animal/demon/slaughter/cult) - if(!length(demon_candidates)) - visible_message("[src] disappears in a flash of red light!") - qdel(src) - return - if(QDELETED(src)) // Just in case - return - var/mob/M = pick(demon_candidates) - var/mob/living/simple_animal/demon/slaughter/cult/S = src - if(!M || !M.client) - visible_message("[src] disappears in a flash of red light!") - qdel(src) - return - var/client/C = M.client - - S.key = C.key - dust_if_respawnable(M) - S.mind.assigned_role = "Harbinger of the Slaughter" - S.mind.special_role = "Harbinger of the Slaughter" - to_chat(S, playstyle_string) - S.mind.add_antag_datum(/datum/antagonist/cultist) - var/datum/spell/sense_victims/SV = new - AddSpell(SV) - - S.mind.add_mind_objective(/datum/objective/cult_slaughter) - var/list/messages = S.mind.prepare_announce_objectives(FALSE) - to_chat(S, chat_box_red(messages.Join("
    "))) - -////////////////////The Powers - -//Paradise Port: I added this because..SPOOPY DEMON IN YOUR BRAIN - - -/datum/action/innate/demon_whisper - name = "Demonic Whisper" - button_overlay_icon_state = "demon_comms" - button_background_icon_state = "bg_demon" - -/datum/action/innate/demon_whisper/IsAvailable() - return ..() - -/datum/action/innate/demon_whisper/proc/choose_targets(mob/user = usr)//yes i am copying from telepathy..hush... - var/list/validtargets = list() - for(var/mob/living/M in view(user.client.maxview(), get_turf(user))) - if(M && M.mind && M.stat != DEAD) - if(M == user) - continue - - validtargets += M - - if(!length(validtargets)) - to_chat(usr, "There are no valid targets!") - return - - var/mob/living/target = tgui_input_list(user, "Choose the target to talk to", "Targeting", validtargets) - return target - -/datum/action/innate/demon_whisper/Activate() - var/mob/living/choice = choose_targets() - if(!choice) - return - - var/msg = tgui_input_text(usr, "What do you wish to tell [choice]?", null, "") - if(!msg) - return - log_say("(SLAUGHTER to [key_name(choice)]) [msg]", usr) - to_chat(usr, "You whisper to [choice]: [msg]") - to_chat(choice, "Suddenly a strange, demonic voice resonates in your head... [msg]") - for(var/mob/dead/observer/G in GLOB.player_list) - G.show_message("Demonic message from [usr] ([ghost_follow_link(usr, ghost=G)]) to [choice] ([ghost_follow_link(choice, ghost=G)]): [msg]") - - -//////////The Loot - -// Demon heart base type -/obj/item/organ/internal/heart/demon - name = "demon heart" - desc = "Still it beats furiously, emanating an aura of utter hate." - icon = 'icons/obj/surgery.dmi' - icon_state = "demon_heart" - origin_tech = "combat=5;biotech=7" - organ_datums = list(/datum/organ/heart/always_beating, /datum/organ/battery) - -/obj/item/organ/internal/heart/demon/update_icon_state() - return //always beating visually - -/obj/item/organ/internal/heart/demon/prepare_eat() - return // Just so people don't accidentally waste it - -/obj/item/organ/internal/heart/demon/attack_self__legacy__attackchain(mob/living/user) - user.visible_message("[user] raises [src] to [user.p_their()] mouth and tears into it with [user.p_their()] teeth!", \ - "An unnatural hunger consumes you. You raise [src] to your mouth and devour it!") - playsound(user, 'sound/misc/demon_consume.ogg', 50, 1) - -//////////The Loot - -//The loot from killing a slaughter demon - can be consumed to allow the user to blood crawl -/// SLAUGHTER DEMON HEART - -/obj/item/organ/internal/heart/demon/slaughter/attack_self__legacy__attackchain(mob/living/user) - ..() - - // Eating the heart for the first time. Gives basic bloodcrawling. This is the only time we need to insert the heart. - if(!HAS_TRAIT(user, TRAIT_BLOODCRAWL)) - user.visible_message("[user]'s eyes flare a deep crimson!", \ - "You feel a strange power seep into your body... you have absorbed the demon's blood-travelling powers!") - ADD_TRAIT(user, TRAIT_BLOODCRAWL, "bloodcrawl") - user.drop_item() - insert(user) //Consuming the heart literally replaces your heart with a demon heart. H A R D C O R E. - return TRUE - - // Eating a 2nd heart. Gives the ability to drag people into blood and eat them. - if(HAS_TRAIT(user, TRAIT_BLOODCRAWL)) - to_chat(user, "You feel differ- CONSUME THEM!") - ADD_TRAIT(user, TRAIT_BLOODCRAWL_EAT, "bloodcrawl_eat") - qdel(src) // Replacing their demon heart with another demon heart is pointless, just delete this one and return. - return TRUE - - // Eating any more than 2 demon hearts does nothing. - to_chat(user, "...and you don't feel any different.") - qdel(src) - -/obj/item/organ/internal/heart/demon/slaughter/insert(mob/living/carbon/M, special = 0) - . = ..() - if(M.mind) - M.mind.AddSpell(new /datum/spell/bloodcrawl(null)) - -/obj/item/organ/internal/heart/demon/slaughter/remove(mob/living/carbon/M, special = 0) - . = ..() - if(M.mind) - REMOVE_TRAIT(M, TRAIT_BLOODCRAWL, "bloodcrawl") - REMOVE_TRAIT(M, TRAIT_BLOODCRAWL_EAT, "bloodcrawl_eat") - M.mind.RemoveSpell(/datum/spell/bloodcrawl) - -/mob/living/simple_animal/demon/slaughter/laughter - // The laughter demon! It's everyone's best friend! It just wants to hug - // them so much, it wants to hug everyone at once! - name = "laughter demon" - real_name = "laughter demon" - desc = "A large, adorable creature covered in armor with pink bows." - speak_emote = list("giggles", "titters", "chuckles") - emote_hear = list("gaffaws", "laughs") - response_help = "hugs" - attacktext = "wildly tickles" - maxHealth = 215 - health = 215 - melee_damage_lower = 25 - melee_damage_upper = 25 - playstyle_string = "You are the Laughter Demon, an adorable creature from another existence. You have a single desire: to hug and tickle. \ - You may use the blood crawl icon when on blood pools to travel through them, appearing and dissapearing from the station at will. \ - Pulling a dead or critical mob while you enter a pool will pull them in with you, allowing you to hug them. \ - You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. \ - (You should be attacking people on harm intent, and not nuzzling them.)" - - attack_sound = 'sound/items/bikehorn.ogg' - feast_sound = 'sound/spookoween/scary_horn2.ogg' - death_sound = 'sound/misc/sadtrombone.ogg' - - icon_state = "bowmon" - icon_living = "bowmon" - deathmessage = "fades out, as all of its friends are released from its prison of hugs." - loot = list(/mob/living/simple_animal/pet/cat/kitten{name = "Laughter"}) - -/mob/living/simple_animal/demon/slaughter/laughter/release_consumed(mob/living/M) - if(M.revive()) - M.grab_ghost(force = TRUE) - playsound(get_turf(src), feast_sound, 50, TRUE, -1) - to_chat(M, "You leave [src]'s warm embrace, and feel ready to take on the world.") - ..(M) - - -//Objectives and helpers. - -//Objective info, Based on Reverent mini Atang -/datum/objective/slaughter - needs_target = FALSE - var/targetKill = 10 - -/datum/objective/slaughter/New() - targetKill = rand(10,20) - explanation_text = "Devour [targetKill] mortals." - ..() - -/datum/objective/slaughter/check_completion() - var/kill_count = 0 - for(var/datum/mind/M in get_owners()) - if(!isslaughterdemon(M.current) || QDELETED(M.current)) - continue - var/mob/living/simple_animal/demon/slaughter/R = M.current - kill_count += R.devoured - if(kill_count >= targetKill) - return TRUE - return FALSE - -/datum/objective/demon_fluff - name = "Spread blood" - needs_target = FALSE - -/datum/objective/demon_fluff/New() - find_target() - var/targetname = "someone" - if(target && target.current) - targetname = target.current.real_name - var/list/explanation_texts = list( - "Spread blood all over the bridge.", - "Spread blood all over the brig.", - "Spread blood all over the chapel.", - "Kill or Destroy all Janitors or Sanitation bots.", - "Spare a few after striking them... make them bleed before the harvest.", - "Hunt those that try to hunt you first.", - "Hunt those that run away from you in fear", - "Show [targetname] the power of blood.", - "Drive [targetname] insane with demonic whispering." - ) - // As this is a fluff objective, we don't need a target, so we want to null it out. - // We don't want the demon getting a "Time for Plan B" message if the target cryos. - target = null - explanation_text = pick(explanation_texts) - ..() - -/datum/objective/demon_fluff/check_completion() - return TRUE - -/datum/objective/cult_slaughter - explanation_text = "Bring forth the Slaughter to the nonbelievers." - needs_target = FALSE diff --git a/code/game/gamemodes/miniantags/guardian/host_actions.dm b/code/game/gamemodes/miniantags/guardian/host_actions.dm deleted file mode 100644 index e21f25094156c..0000000000000 --- a/code/game/gamemodes/miniantags/guardian/host_actions.dm +++ /dev/null @@ -1,210 +0,0 @@ -/** - * # Base guardian host action - * - * These are used by guardian hosts to interact with their guardians. These are not buttons that guardians themselves use. - */ -/datum/action/guardian - name = "Generic guardian host action" - button_overlay_icon = 'icons/mob/guardian.dmi' - button_overlay_icon_state = "base" - var/mob/living/simple_animal/hostile/guardian/guardian - -/datum/action/guardian/Grant(mob/M, mob/living/simple_animal/hostile/guardian/G) - if(!G || !istype(G)) - stack_trace("/datum/action/guardian created with no guardian to link to.") - qdel(src) - guardian = G - return ..() - -/** - * # Communicate action - * - * Allows the guardian host to communicate with their guardian. - */ -/datum/action/guardian/communicate - name = "Communicate" - desc = "Communicate telepathically with your guardian." - button_overlay_icon_state = "communicate" - -/datum/action/guardian/communicate/Trigger(left_click) - var/input = tgui_input_text(owner, "Enter a message to tell your guardian:", "Message") - if(!input || !guardian) - return - - // Show the message to our guardian and to host. - to_chat(guardian, "[owner]: [input]") - to_chat(owner, "[owner]: [input]") - log_say("(HOST to [key_name(guardian)]): [input]", owner) - owner.create_log(SAY_LOG, "HOST to GUARDIAN: [input]", guardian) - - // Show the message to any ghosts/dead players. - for(var/mob/M in GLOB.dead_mob_list) - if(M && M.client && M.stat == DEAD && !isnewplayer(M)) - to_chat(M, "Guardian Communication from [owner] ([ghost_follow_link(owner, ghost=M)]): [input]") - -/** - * # Recall guardian action - * - * Allows the guardian host to recall their guardian. - */ -/datum/action/guardian/recall - name = "Recall Guardian" - desc = "Forcibly recall your guardian." - button_overlay_icon_state = "recall" - -/datum/action/guardian/recall/Trigger(left_click) - guardian.Recall() - -/** - * # Reset guardian action - * - * Allows the guardian host to exchange their guardian's player for another. - */ -/datum/action/guardian/reset_guardian - name = "Replace Guardian Player" - desc = "Replace your guardian's player with a ghost. This can only be done once." - button_overlay_icon_state = "reset" - var/cooldown_timer - -/datum/action/guardian/reset_guardian/IsAvailable() - if(cooldown_timer) - return FALSE - return TRUE - -/datum/action/guardian/reset_guardian/Trigger(left_click) - if(cooldown_timer) - to_chat(owner, "This ability is still recharging.") - return - - var/confirm = tgui_alert(owner, "Are you sure you want replace your guardian's player?", "Confirm", list("Yes", "No")) - if(confirm != "Yes") - return - - // Do this immediately, so the user can't spam a bunch of polls. - cooldown_timer = addtimer(CALLBACK(src, PROC_REF(reset_cooldown)), 5 MINUTES) - UpdateButtons() - - to_chat(owner, "Searching for a replacement ghost...") - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as [guardian.real_name]?", ROLE_GUARDIAN, FALSE, 15 SECONDS, source = guardian) - - if(!length(candidates)) - to_chat(owner, "There were no ghosts willing to take control of your guardian. You can try again in 5 minutes.") - return - if(QDELETED(guardian)) // Just in case - return - - var/mob/dead/observer/new_stand = pick(candidates) - to_chat(guardian, "Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance.") - to_chat(owner, "Your guardian has been successfully reset.") - message_admins("[key_name_admin(new_stand)] has taken control of ([key_name_admin(guardian)])") - guardian.ghostize() - guardian.key = new_stand.key - dust_if_respawnable(new_stand) - qdel(src) - -/datum/spell/summon_guardian_beacon - name = "Place Teleportation Beacon" - desc = "Mark a floor as your beacon point, allowing you to warp targets to it. Your beacon requires an anchor, will not work on space tiles." - clothes_req = FALSE - antimagic_flags = NONE - base_cooldown = 300 SECONDS - action_icon_state = "no_state" - action_background_icon = 'icons/mob/guardian.dmi' - action_background_icon_state = "reset" - -/datum/spell/summon_guardian_beacon/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/summon_guardian_beacon/cast(list/targets, mob/living/user = usr) - var/target = targets[1] - var/mob/living/simple_animal/hostile/guardian/healer/guardian_user = user - var/turf/beacon_loc = get_turf(target) - if(isfloorturf(beacon_loc) && !islava(beacon_loc) && !ischasm(beacon_loc)) - QDEL_NULL(guardian_user.beacon) - guardian_user.beacon = new(beacon_loc) - to_chat(guardian_user, "Beacon placed! You may now warp targets to it, including your user, via Alt Click.") - - return TRUE - -/datum/spell/surveillance_snare - name = "Set Surveillance Snare" - desc = "Places an invisible Surveillance Snare on the ground, if someone walks over it you'll be alerted. Max of 6 snares active at a time" - clothes_req = FALSE - antimagic_flags = NONE - base_cooldown = 3 SECONDS - action_icon_state = "no_state" - action_background_icon = 'icons/mob/guardian.dmi' - action_background_icon_state = "reset" - -/datum/spell/surveillance_snare/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/surveillance_snare/cast(list/targets, mob/living/user = usr) - var/target = targets[1] - var/mob/living/simple_animal/hostile/guardian/ranged/guardian_user = user - if(length(guardian_user.snares) < 6) - var/turf/snare_loc = get_turf(target) - var/obj/effect/snare/S = new /obj/effect/snare(snare_loc) - S.spawner = guardian_user - S.name = "[get_area(snare_loc)] trap ([snare_loc.x],[snare_loc.y],[snare_loc.z])" - guardian_user.snares |= S - to_chat(guardian_user, "Surveillance trap deployed!") - return TRUE - else - var/picked_snare = tgui_input_list(guardian_user, "You have too many snares deployed! Delete one to place another.", "Disarm Snare", guardian_user.snares) - if(picked_snare) - guardian_user.snares -= picked_snare - qdel(picked_snare) - to_chat(user, "Snare disarmed.") - revert_cast() - -/datum/spell/choose_battlecry - name = "Change battlecry" - desc = "Changes your battlecry." - clothes_req = FALSE - antimagic_flags = NONE - base_cooldown = 1 SECONDS - action_icon_state = "no_state" - action_background_icon = 'icons/mob/guardian.dmi' - action_background_icon_state = "communicate" - -/datum/spell/choose_battlecry/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/choose_battlecry/cast(list/targets, mob/living/user = usr) - var/mob/living/simple_animal/hostile/guardian/punch/guardian_user = user - var/input = tgui_input_text(guardian_user, "What do you want your battlecry to be? Max length of 6 characters.", "Change Battlecry", guardian_user.battlecry, 6) - if(!input) - revert_cast() - return - guardian_user.battlecry = input - -/** - * Takes the action button off cooldown and makes it available again. - */ -/datum/action/guardian/reset_guardian/proc/reset_cooldown() - cooldown_timer = null - UpdateButtons() - -/** - * Grants all existing `/datum/action/guardian` type actions to the src mob. - * - * Called whenever the host gains their gauardian. - */ -/mob/living/proc/grant_guardian_actions(mob/living/simple_animal/hostile/guardian/G) - if(!G || !istype(G)) - return - for(var/action in subtypesof(/datum/action/guardian)) - var/datum/action/guardian/A = new action - A.Grant(src, G) - -/** - * Removes all `/datum/action/guardian` type actions from the src mob. - * - * Called whenever the host loses their guardian. - */ -/mob/living/proc/remove_guardian_actions() - for(var/action in actions) - var/datum/action/A = action - if(istype(A, /datum/action/guardian)) - A.Remove(src) diff --git a/code/game/gamemodes/miniantags/guardian/types/explosive_guardian.dm b/code/game/gamemodes/miniantags/guardian/types/explosive_guardian.dm deleted file mode 100644 index 8ed033b7f9cbb..0000000000000 --- a/code/game/gamemodes/miniantags/guardian/types/explosive_guardian.dm +++ /dev/null @@ -1,117 +0,0 @@ -/mob/living/simple_animal/hostile/guardian/bomb - melee_damage_lower = 15 - melee_damage_upper = 15 - damage_transfer = 0.6 - range = 13 - playstyle_string = "As an Explosive type, you have only moderate close combat abilities, but are capable of converting any adjacent item into a disguised bomb via alt click even when not manifested." - magic_fluff_string = "..And draw the Scientist, master of explosive death." - tech_fluff_string = "Boot sequence complete. Explosive modules active. Holoparasite swarm online." - bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of stealthily booby trapping items." - var/bomb_cooldown = 0 - var/default_bomb_cooldown = 20 SECONDS - -/mob/living/simple_animal/hostile/guardian/bomb/get_status_tab_items() - var/list/status_tab_data = ..() - . = status_tab_data - if(bomb_cooldown >= world.time) - status_tab_data[++status_tab_data.len] = list("Bomb Cooldown Remaining:", "[max(round((bomb_cooldown - world.time) * 0.1, 0.1), 0)] seconds") - -/mob/living/simple_animal/hostile/guardian/bomb/AltClickOn(atom/movable/A) - if(!istype(A)) - return - if(get_dist(get_turf(src), get_turf(A)) > 1) - to_chat(src, "You're too far from [A] to disguise it as a bomb.") - return - if(isobj(A) && can_plant(A)) - if(bomb_cooldown <= world.time && stat == CONSCIOUS) - var/obj/item/guardian_bomb/B = new /obj/item/guardian_bomb(get_turf(A)) - add_attack_logs(src, A, "booby trapped (summoner: [summoner])") - to_chat(src, "Success! Bomb on [A] armed!") - if(summoner) - to_chat(summoner, "Your guardian has primed [A] to explode!") - bomb_cooldown = world.time + default_bomb_cooldown - B.spawner = src - B.disguise (A) - else - to_chat(src, "Your power is on cooldown! You must wait another [max(round((bomb_cooldown - world.time)*0.1, 0.1), 0)] seconds before you can place next bomb.") - -/mob/living/simple_animal/hostile/guardian/bomb/proc/can_plant(atom/movable/A) - if(ismecha(A)) - var/obj/mecha/target = A - if(target.occupant) - to_chat(src, "You can't disguise piloted mechs as a bomb!") - return FALSE - if(istype(A, /obj/machinery/disposal)) // Have no idea why they just destroy themselves - to_chat(src, "You can't disguise disposal units as a bomb!") - return FALSE - return TRUE - -/obj/item/guardian_bomb - name = "bomb" - desc = "You shouldn't be seeing this!" - var/obj/stored_obj - var/mob/living/spawner - -/obj/item/guardian_bomb/proc/disguise(obj/A) - A.forceMove(src) - stored_obj = A - opacity = A.opacity - anchored = A.anchored - density = A.density - appearance = A.appearance - dir = A.dir - move_resist = A.move_resist - addtimer(CALLBACK(src, PROC_REF(disable)), 600) - -/obj/item/guardian_bomb/proc/disable() - add_attack_logs(null, stored_obj, "booby trap expired") - stored_obj.forceMove(get_turf(src)) - if(spawner) - to_chat(spawner, "Failure! Your trap on [stored_obj] didn't catch anyone this time.") - qdel(src) - -/obj/item/guardian_bomb/proc/detonate(mob/living/user) - if(!istype(user)) - return - to_chat(user, "[src] was boobytrapped!") - if(isguardian(spawner)) - var/mob/living/simple_animal/hostile/guardian/G = spawner - if(user == G.summoner) - add_attack_logs(user, stored_obj, "booby trap defused") - to_chat(user, "You knew this because of your link with your guardian, so you smartly defuse the bomb.") - stored_obj.forceMove(get_turf(loc)) - qdel(src) - return - add_attack_logs(user, stored_obj, "booby trap TRIGGERED (spawner: [spawner])") - to_chat(spawner, "Success! Your trap on [src] caught [user]!") - stored_obj.forceMove(get_turf(loc)) - playsound(get_turf(src),'sound/effects/explosion2.ogg', 200, 1) - user.ex_act(EXPLODE_HEAVY) - user.Stun(3 SECONDS)//A bomb went off in your hands. Actually lets people follow up with it if they bait someone, right now it is unreliable. - qdel(src) - -/obj/item/guardian_bomb/attackby__legacy__attackchain(obj/item/W, mob/living/user) - detonate(user) - -/obj/item/guardian_bomb/attack_hand(mob/user) - detonate(user) - -/obj/item/guardian_bomb/MouseDrop_T(obj/item/I, mob/living/user) - detonate(user) - -/obj/item/guardian_bomb/AltClick(mob/living/user) - detonate(user) - -/obj/item/guardian_bomb/MouseDrop(mob/living/user) - detonate(user) - -/obj/item/guardian_bomb/Bumped(mob/living/user) - detonate(user) - -/obj/item/guardian_bomb/can_be_pulled(mob/living/user) - detonate(user) - -/obj/item/guardian_bomb/examine(mob/user) - . = stored_obj.examine(user) - if(get_dist(user, src) <= 2) - . += "Looks odd!" diff --git a/code/game/gamemodes/miniantags/guardian/types/protector.dm b/code/game/gamemodes/miniantags/guardian/types/protector.dm deleted file mode 100644 index 756b4489bdead..0000000000000 --- a/code/game/gamemodes/miniantags/guardian/types/protector.dm +++ /dev/null @@ -1,151 +0,0 @@ -#define LEFT_SHIELD FALSE -#define RIGHT_SHEILD TRUE - -/mob/living/simple_animal/hostile/guardian/protector - melee_damage_lower = 15 - melee_damage_upper = 15 - range = 15 //worse for it due to how it leashes - damage_transfer = 0.4 - playstyle_string = "As a Protector type you cause your summoner to leash to you instead of you leashing to them and have two modes; Combat Mode, where you do and take medium damage, and Protection Mode, where you do and take almost no damage, but move slightly slower, as well as have a protective shield. Nobody can walk through your shield, but you can still move your shield through them." - magic_fluff_string = "..And draw the Guardian, a stalwart protector that never leaves the side of its charge." - tech_fluff_string = "Boot sequence complete. Protector modules loaded. Holoparasite swarm online." - bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to defend you." - var/toggle = FALSE - /// The shields the guardian has, and brings with it as it moves - var/list/connected_shields = list() - -/mob/living/simple_animal/hostile/guardian/protector/ex_act(severity) - if(severity == EXPLODE_DEVASTATE) - adjustBruteLoss(200) //if in protector mode, will do 20 damage and not actually necessarily kill the summoner - else - ..() - if(toggle) - visible_message("The explosion glances off [src]'s energy shielding!") - - -/mob/living/simple_animal/hostile/guardian/protector/Manifest() - . = ..() - if(toggle && cooldown < world.time) - var/dir_left = turn(dir, -90) - var/dir_right = turn(dir, 90) - connected_shields += new /obj/effect/guardianshield(get_step(src, dir_left), src, FALSE) - connected_shields += new /obj/effect/guardianshield(get_step(src, dir_right), src, TRUE) - -/mob/living/simple_animal/hostile/guardian/protector/Recall(forced) - . = ..() - if(cooldown > world.time && !forced) - QDEL_LIST_CONTENTS(connected_shields) - -/mob/living/simple_animal/hostile/guardian/protector/Move() - . = ..() - for(var/obj/effect/guardianshield/G in connected_shields) - var/dir_chosen - if(G.shield_orientation) - dir_chosen = turn(dir, 90) - else - dir_chosen = turn(dir, -90) - G.forceMove(get_step(src, dir_chosen)) - -/mob/living/simple_animal/hostile/guardian/protector/ToggleMode() - if(cooldown > world.time) - return 0 - cooldown = world.time + 10 - if(toggle) - overlays.Cut() - melee_damage_lower = initial(melee_damage_lower) - melee_damage_upper = initial(melee_damage_upper) - obj_damage = initial(obj_damage) - move_resist = initial(move_resist) - speed = initial(speed) - damage_transfer = 0.4 - to_chat(src, "You switch to combat mode.") - toggle = FALSE - QDEL_LIST_CONTENTS(connected_shields) - else - if(!isturf(loc)) - return - if(get_turf(summoner) == get_turf(src)) - to_chat(src, "You cannot deploy your shield while on your host!") - return - var/icon/shield_overlay = icon('icons/effects/effects.dmi', "shield-grey") - shield_overlay *= name_color - overlays.Add(shield_overlay) - melee_damage_lower = 2 - melee_damage_upper = 2 - obj_damage = 6 //40/7.5 rounded up, we don't want a protector guardian 2 shotting blob tiles while taking 5% damage, thats just silly. - move_resist = MOVE_FORCE_STRONG - speed = 1 - damage_transfer = 0.1 //damage? what's damage? - to_chat(src, "You switch to protection mode.") - toggle = TRUE - var/dir_left = turn(dir, -90) - var/dir_right = turn(dir, 90) - connected_shields += new /obj/effect/guardianshield(get_step(src, dir_left), src, LEFT_SHIELD) - connected_shields += new /obj/effect/guardianshield(get_step(src, dir_right), src, RIGHT_SHEILD) - -/mob/living/simple_animal/hostile/guardian/protector/snapback() //snap to what? snap to the guardian! - // If the summoner dies instantly, the summoner's ghost may be drawn into null space as the protector is deleted. This check should prevent that. - if(summoner && loc && summoner.loc) - if(get_dist(get_turf(summoner),get_turf(src)) <= range) - return - else - if(iseffect(summoner.loc)) - to_chat(src, "You moved out of range, and were pulled back! You can only move [range] meters from [summoner.real_name]!") - visible_message("[src] jumps back to its user.") - Recall(TRUE) - else - to_chat(summoner, "You moved out of range, and were pulled back! You can only move [range] meters from [src]!") - summoner.visible_message("[summoner] jumps back to [summoner.p_their()] protector.") - new /obj/effect/temp_visual/guardian/phase/out(get_turf(summoner)) - summoner.forceMove(get_turf(src)) - new /obj/effect/temp_visual/guardian/phase(get_turf(summoner))//Protector - -/mob/living/simple_animal/hostile/guardian/protector/CanPass(atom/movable/mover, border_dir) - . = ..() - if(toggle && isliving(mover)) //No crawling under a protector - return FALSE - -/mob/living/simple_animal/hostile/guardian/protector/Destroy() - QDEL_LIST_CONTENTS(connected_shields) - return ..() - -/obj/effect/guardianshield - name = "guardian's shield" - desc = "A guardian's defensive wall." - icon = 'icons/effects/effects.dmi' - icon_state = "shield-grey" - can_be_hit = TRUE - var/mob/living/simple_animal/hostile/guardian/protector/linked_guardian - ///Is the guardians shield the left or right shield? - var/shield_orientation = LEFT_SHIELD - -/obj/effect/guardianshield/Initialize(mapload, mob/living/simple_animal/hostile/guardian/protector/creator, left_or_right) - . = ..() - linked_guardian = creator - color = linked_guardian.name_color - shield_orientation = left_or_right - -/obj/effect/guardianshield/CanPass(atom/movable/mover, border_dir) - if(mover == linked_guardian) - return TRUE - return FALSE - -/obj/effect/guardianshield/bullet_act(obj/item/projectile/P) - if(!P) - return - linked_guardian.apply_damage(P.damage, P.damage_type) - P.on_hit(src, 0) - return FALSE - -/obj/effect/guardianshield/attacked_by__legacy__attackchain(obj/item/I, mob/living/user) - if(I.force) - user.visible_message("[user] has hit [src] with [I]!", "You hit [src] with [I]!") - linked_guardian.apply_damage(I.force, I.damtype) - -/obj/effect/guardianshield/Destroy() - linked_guardian = null - return ..() - - -#undef LEFT_SHIELD -#undef RIGHT_SHEILD diff --git a/code/game/gamemodes/miniantags/guardian/types/ranged.dm b/code/game/gamemodes/miniantags/guardian/types/ranged.dm deleted file mode 100644 index 862fe56ff1115..0000000000000 --- a/code/game/gamemodes/miniantags/guardian/types/ranged.dm +++ /dev/null @@ -1,112 +0,0 @@ -/obj/item/projectile/guardian - name = "crystal spray" - icon_state = "guardian" - damage = 20 - damage_type = BRUTE - armour_penetration_percentage = 100 - -/mob/living/simple_animal/hostile/guardian/ranged - friendly = "quietly assesses" - melee_damage_lower = 10 - melee_damage_upper = 10 - damage_transfer = 1 - projectiletype = /obj/item/projectile/guardian - ranged_cooldown_time = 5 //fast! - projectilesound = 'sound/effects/hit_on_shattered_glass.ogg' - ranged = TRUE - range = 13 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - see_in_dark = 8 - playstyle_string = "As a Ranged type, you have only light damage resistance, but are capable of spraying shards of crystal at incredibly high speed. You can also deploy surveillance snares to monitor enemy movement. Finally, you can switch to scout mode, in which you can't attack, but can move without limit." - magic_fluff_string = "..And draw the Sentinel, an alien master of ranged combat." - tech_fluff_string = "Boot sequence complete. Ranged combat modules active. Holoparasite swarm online." - bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of spraying shards of crystal." - var/list/snares = list() - var/toggle = FALSE - -/mob/living/simple_animal/hostile/guardian/ranged/Initialize(mapload, mob/living/host) - . = ..() - AddSpell(new /datum/spell/surveillance_snare(null)) - -/mob/living/simple_animal/hostile/guardian/ranged/ToggleMode() - if(loc == summoner) - if(toggle) - ranged = TRUE - melee_damage_lower = 10 - melee_damage_upper = 10 - obj_damage = initial(obj_damage) - environment_smash = initial(environment_smash) - alpha = 255 - range = 13 - incorporeal_move = NO_INCORPOREAL_MOVE - ADD_TRAIT(src, TRAIT_CAN_STRIP, TRAIT_GENERIC) - to_chat(src, "You switch to combat mode.") - toggle = FALSE - else - ranged = FALSE - melee_damage_lower = 0 - melee_damage_upper = 0 - obj_damage = 0 - environment_smash = ENVIRONMENT_SMASH_NONE - alpha = 60 - range = 255 - incorporeal_move = INCORPOREAL_MOVE_NORMAL - REMOVE_TRAIT(src, TRAIT_CAN_STRIP, TRAIT_GENERIC) //spiritual pickpocketting is forbidden - to_chat(src, "You switch to scout mode.") - toggle = TRUE - else - to_chat(src, "You have to be recalled to toggle modes!") - -/mob/living/simple_animal/hostile/guardian/ranged/ToggleLight() - var/msg - switch(lighting_alpha) - if(LIGHTING_PLANE_ALPHA_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - msg = "You activate your night vision." - if(LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - msg = "You increase your night vision." - if(LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE - msg = "You maximize your night vision." - else - lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE - msg = "You deactivate your night vision." - - update_sight() - - to_chat(src, "[msg]") - -/mob/living/simple_animal/hostile/guardian/ranged/blob_act(obj/structure/blob/B) - if(toggle) - return // we don't want blob tiles to hurt us when we fly over them and trigger /Crossed(), this prevents ranged scouts from being insta killed - return ..() // otherwise do normal damage! - -/obj/effect/snare - name = "snare" - desc = "You shouldn't be seeing this!" - var/mob/living/spawner - invisibility = 101 - -/obj/effect/snare/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/effect/snare/singularity_act() - return - -/obj/effect/snare/singularity_pull() - return - -/obj/effect/snare/proc/on_atom_entered(datum/source, atom/movable/entered) - if(isliving(entered)) - var/turf/snare_loc = get_turf(loc) - if(spawner) - to_chat(spawner, "[entered] has crossed your surveillance trap at [get_area(snare_loc)].") - if(isguardian(spawner)) - var/mob/living/simple_animal/hostile/guardian/G = spawner - if(G.summoner) - to_chat(G.summoner, "[entered] has crossed your surveillance trap at [get_area(snare_loc)].") diff --git a/code/game/gamemodes/miniantags/morph/spells/pass_airlock.dm b/code/game/gamemodes/miniantags/morph/spells/pass_airlock.dm deleted file mode 100644 index 847ee5cce0044..0000000000000 --- a/code/game/gamemodes/miniantags/morph/spells/pass_airlock.dm +++ /dev/null @@ -1,54 +0,0 @@ -// TODO refactor when spell code is component based instead of OO based -/datum/spell/morph_spell/pass_airlock - name = "Pass Airlock" - desc = "Reform yourself so you can fit through a non bolted airlock. Takes a while to do and can only be used in a non disguised form." - action_background_icon_state = "bg_morph" - action_icon_state = "morph_airlock" - clothes_req = FALSE - antimagic_flags = NONE - base_cooldown = 10 SECONDS - selection_activated_message = "Click on an airlock to try pass it." - -/datum/spell/morph_spell/pass_airlock/create_new_targeting() - var/datum/spell_targeting/click/T = new - T.range = 1 - T.allowed_type = /obj/machinery/door/airlock - T.click_radius = -1 - return T - - -/datum/spell/morph_spell/pass_airlock/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message) - . = ..() - if(!.) - return - - if(user.morphed) - if(show_message) - to_chat(user, "You can only pass through airlocks in your true form!") - return FALSE - -/datum/spell/morph_spell/pass_airlock/cast(list/targets, mob/living/simple_animal/hostile/morph/user) - var/obj/machinery/door/airlock/A = targets[1] - if(A.locked) - to_chat(user, "[A] is bolted shut! You're unable to create a crack to pass through!") - revert_cast(user) - return - user.visible_message("[user] starts pushing itself against [A]!", "You try to pry [A] open enough to get through.") - if(!do_after(user, 6 SECONDS, FALSE, user, TRUE, list(CALLBACK(src, PROC_REF(pass_check), user, A)), FALSE)) - if(user.morphed) - to_chat(user, "You need to stay in your true form to pass through [A]!") - else if(A.locked) - to_chat(user, "[A] is bolted shut! You're unable to create a crack to pass through!") - else - to_chat(user, "You need to stay still to pass through [A]!") - revert_cast(user) - return - if(QDELETED(A)) - return - - user.visible_message("[user] briefly opens [A] slightly and passes through!", "You slide through the open crack in [A].") - user.forceMove(A.loc) // Move into the turf of the airlock - - -/datum/spell/morph_spell/pass_airlock/proc/pass_check(mob/living/simple_animal/hostile/morph/user, obj/machinery/door/airlock/A) - return user.morphed || A.locked diff --git a/code/game/gamemodes/miniantags/pulsedemon/cross_shock_component.dm b/code/game/gamemodes/miniantags/pulsedemon/cross_shock_component.dm deleted file mode 100644 index cf7da6be862b0..0000000000000 --- a/code/game/gamemodes/miniantags/pulsedemon/cross_shock_component.dm +++ /dev/null @@ -1,65 +0,0 @@ -/datum/component/cross_shock - var/shock_damage - var/energy_cost - var/delay_between_shocks - var/requires_cable - - COOLDOWN_DECLARE(last_shock) - -/datum/component/cross_shock/Initialize(_shock_damage, _energy_cost, _delay_between_shocks, _requires_cable = TRUE) - if(ismovable(parent)) - var/static/list/crossed_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(do_shock), - ) - AddComponent(/datum/component/connect_loc_behalf, parent, crossed_connections) - RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_movable_moved)) - if(ismob(parent)) - RegisterSignal(parent, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_organ_removal)) - else if(isarea(parent)) - RegisterSignal(parent, COMSIG_ATOM_EXITED, PROC_REF(do_shock)) - else if(isturf(parent)) - RegisterSignal(parent, COMSIG_ATOM_ENTERED, PROC_REF(do_shock)) - else - return COMPONENT_INCOMPATIBLE - - shock_damage = _shock_damage - energy_cost = _energy_cost - delay_between_shocks = _delay_between_shocks - requires_cable = _requires_cable - -/datum/component/cross_shock/proc/on_movable_moved(atom/source, old_location, direction, forced) - SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED - if(isturf(source.loc)) - for(var/mob/living/mob in source.loc) - do_shock(src, mob) - -/datum/component/cross_shock/proc/do_shock(atom/source, atom/movable/to_shock) - SIGNAL_HANDLER // COMSIG_ATOM_ENTERED - if(!COOLDOWN_FINISHED(src, last_shock)) - return - var/mob/living/living_to_shock = to_shock - if(!istype(living_to_shock)) - return - if(isliving(parent)) - var/mob/living/M = parent - if(M.stat == DEAD || !IS_HORIZONTAL(M)) - return - if(requires_cable) - var/turf/our_turf = get_turf(parent) - if(our_turf.transparent_floor || our_turf.intact || HAS_TRAIT(our_turf, TRAIT_TURF_COVERED)) - return - var/obj/structure/cable/our_cable = locate(/obj/structure/cable) in our_turf - if(!our_cable || !our_cable.powernet || !our_cable.powernet.available_power) - return - var/area/to_deduct_from = get_area(our_cable) - living_to_shock.electrocute_act(shock_damage, source) - to_deduct_from.powernet.use_active_power(energy_cost) - playsound(get_turf(parent), 'sound/effects/eleczap.ogg', 30, TRUE) - else - living_to_shock.electrocute_act(shock_damage, source) - playsound(get_turf(parent), 'sound/effects/eleczap.ogg', 30, TRUE) - COOLDOWN_START(src, last_shock, delay_between_shocks) - -/datum/component/cross_shock/proc/on_organ_removal(datum/source) - SIGNAL_HANDLER - qdel(src) diff --git a/code/game/gamemodes/miniantags/pulsedemon/pulsedemon.dm b/code/game/gamemodes/miniantags/pulsedemon/pulsedemon.dm deleted file mode 100644 index 83e7c32d8b69f..0000000000000 --- a/code/game/gamemodes/miniantags/pulsedemon/pulsedemon.dm +++ /dev/null @@ -1,895 +0,0 @@ -// original implementation: https://ss13.moe/wiki/index.php/Pulse_Demon - -#define PULSEDEMON_PLATING_SPARK_CHANCE 20 -#define PULSEDEMON_APC_CHARGE_MULTIPLIER 2 -#define PULSEDEMON_SMES_DRAIN_MULTIPLIER 10 -#define ALERT_CATEGORY_NOPOWER "pulse_nopower" -#define ALERT_CATEGORY_NOREGEN "pulse_noregen" -/// Conversion ratio from Watt ticks to joules. - -/mob/living/simple_animal/demon/pulse_demon - name = "pulse demon" - real_name = "pulse demon" - desc = "A strange electrical apparition that lives in wires." - gender = NEUTER - speak_chance = 20 - - damage_coeff = list(BRUTE = 0, BURN = 0.5, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) // Pulse demons take damage from nothing except some from lasers - - emote_hear = list("vibrates", "sizzles") - speak_emote = list("modulates") - - icon = 'icons/mob/animal.dmi' - icon_state = "pulsedem" - icon_living = "pulsedem" - icon_dead = "pulsedem" - response_help = "reaches their hand into" - response_disarm = "pushes their hand through" - response_harm = "punches their fist through" - deathmessage = "fizzles out into faint sparks, leaving only a slight trail of smoke..." - level = 1 - plane = FLOOR_PLANE - layer = ABOVE_PLATING_LAYER - - maxHealth = 50 - health = 50 - speed = -0.5 - mob_size = MOB_SIZE_TINY - density = FALSE - del_on_death = TRUE - - attacktext = "electrocutes" - attack_sound = "sparks" - a_intent = INTENT_HARM - harm_intent_damage = 0 - melee_damage_lower = 0 - melee_damage_upper = 0 - pass_flags = PASSDOOR - stop_automated_movement = TRUE - has_unlimited_silicon_privilege = TRUE - // this makes the demon able to speak through holopads, due to the overriden say, PD cannot speak normally regardless - universal_speak = TRUE - loot = list(/obj/item/organ/internal/heart/demon/pulse) - initial_traits = list(TRAIT_FLYING) - - /// List of sounds that is picked from when the demon speaks. - var/list/speech_sounds = list("sound/voice/pdvoice1.ogg", "sound/voice/pdvoice2.ogg", "sound/voice/pdvoice3.ogg") - /// List of sounds that is picked from when the demon dies or is EMP'd. - var/list/hurt_sounds = list("sound/voice/pdwail1.ogg", "sound/voice/pdwail2.ogg", "sound/voice/pdwail3.ogg") - - /// Current quantity of energy the demon currently holds (Joules), spent while purchasing, upgrading or using spells or upgrades. Use adjust_charge to modify this. - var/charge = 1000 - /// Maximum quantity of energy the demon can hold at once (Joules). - var/maxcharge = 1000 - /// Book keeping for objective win conditions (Joules). - var/charge_drained = 0 - /// Controls whether the demon will drain power from sources. Toggled by a spell. - var/do_drain = TRUE - /// Amount of power (Watts) to drain from power sources every Life tick. - var/power_drain_rate = 1000 - /// Maximum value for power_drain_rate based on upgrades. (Watts) - var/max_drain_rate = 1000 - - /// Amount of power (Watts) required to regenerate health. - var/power_per_regen = 1000 - /// Amount of health lost per Life tick when the power requirement was not met. - var/health_loss_rate = 5 - /// Amount of health regenerated per Life tick when the power requirement was met. - var/health_regen_rate = 3 - /// Lock health regeneration while this is not 0, decreases by 1 every Life tick. - var/regen_lock = 0 - /// Tracking to prevent multiple EMPs in the same tick from instakilling a demon. - var/emp_debounce = FALSE - - /// Controls whether the demon can move outside of cables. Toggled by a spell. - var/can_exit_cable = FALSE - /// Speed used while moving inside cables. - var/inside_cable_speed = -0.5 - /// Speed used while moving outside cables. Can be upgraded. - var/outside_cable_speed = 5 - - /// The time it takes to hijack APCs and cyborgs. - var/hijack_time = 30 SECONDS - - /// The color of light the demon emits. The range of the light is proportional to energy stored. - var/glow_color = "#bbbb00" - - /// Area being controlled, should be maintained as long as the demon does not move outside a container (APC, object, robot, bot). - var/area/controlling_area - /// Inhabited cable, only maintained while on top of the cable. - var/obj/structure/cable/current_cable - /// Inhabited power source, maintained while inside, or while inside its area if it is an APC. - var/obj/machinery/power/current_power - /// Inhabited item, only items which can be used in rechargers can be hijacked. Only maintained while inside the item. - var/obj/item/current_weapon - /// Inhabited cyborg, only maintained while inside the cyborg. - var/mob/living/silicon/robot/current_robot - /// Inhabited bot, only maintained while inside the bot. - var/mob/living/simple_animal/bot/current_bot - - /// Delay tracker for movement inside bots. - var/bot_movedelay = 0 - /// A cyborg that has already been hijacked can be re-entered instantly. - var/list/hijacked_robots = list() - - /// Images of cables currently being shown on the client. - var/list/cable_images = list() - /// Images of APCs currently being shown on the client. - var/list/apc_images = list() - /// List of all previously hijacked APCs. - var/list/hijacked_apcs = list() - /// Reference to the APC currently being hijacked. - var/obj/machinery/power/apc/apc_being_hijacked - -/mob/living/simple_animal/demon/pulse_demon/Initialize(mapload) - . = ..() - if(!mapload) - name += " ([rand(100, 999)])" - real_name = name - - remove_from_all_data_huds() - ADD_TRAIT(src, TRAIT_AI_UNTRACKABLE, PULSEDEMON_TRAIT) - flags_2 |= RAD_NO_CONTAMINATE_2 - - // For when someone steps on us - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered) - ) - AddElement(/datum/element/connect_loc, loc_connections) - // For when we move somewhere else - RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(on_movable_moved)) - - // drop demon onto ground if its loc is a non-turf and gets deleted - RegisterSignal(src, COMSIG_PARENT_PREQDELETED, PROC_REF(deleted_handler)) - - RegisterSignal(SSdcs, COMSIG_GLOB_CABLE_UPDATED, PROC_REF(cable_updated_handler)) - - RegisterSignal(src, COMSIG_BODY_TRANSFER_TO, PROC_REF(make_pulse_antagonist)) - RegisterSignal(src, COMSIG_ATOM_EMP_ACT, PROC_REF(handle_emp)) - - current_power = locate(/obj/machinery/power) in loc - // in the case that both current_power and current_cable are null, the pulsedemon will die the next tick - if(!current_power) - current_cable = locate(/obj/structure/cable) in loc - else - forceMove(current_power) - update_glow() - playsound(get_turf(src), 'sound/effects/eleczap.ogg', 30, TRUE) - give_spells() - whisper_action.button_overlay_icon_state = "pulse_whisper" - whisper_action.button_background_icon_state = "bg_pulsedemon" - -/mob/living/simple_animal/demon/pulse_demon/proc/deleted_handler(our_demon, force) - SIGNAL_HANDLER - // assume normal deletion if we're on a turf, otherwise deletion could be inherited from loc - if(force || isnull(loc) || isturf(loc)) - return FALSE - // if we did actually die, simple_animal/death will set del_on_death to FALSE before calling qdel - if(!del_on_death) - return FALSE - exit_to_turf() - return TRUE - -/mob/living/simple_animal/demon/pulse_demon/proc/cable_updated_handler(SSdcs, turf/T) - SIGNAL_HANDLER - if(cable_images[T]) - var/list/turf_images = cable_images[T] - for(var/image/current_image in turf_images) - client?.images -= current_image - turf_images.Cut() - else - cable_images[T] = list() - - for(var/obj/structure/cable/C in T) - var/image/cable_image = image(C, C, layer = ABOVE_LIGHTING_LAYER, dir = C.dir) - cable_image.plane = ABOVE_LIGHTING_PLANE - cable_images[T] += cable_image - client?.images += cable_image - -/mob/living/simple_animal/demon/pulse_demon/proc/apc_deleted_handler(obj/machinery/power/apc/A, force) - SIGNAL_HANDLER - hijacked_apcs -= A - -/mob/living/simple_animal/demon/pulse_demon/Destroy() - cable_images.Cut() - apc_images.Cut() - - controlling_area = null - current_bot = null - current_cable = null - current_power = null - current_robot = null - current_weapon = null - apc_being_hijacked = null - hijacked_apcs = null - hijacked_robots = null - - return ..() - -/mob/living/simple_animal/demon/pulse_demon/Login() - . = ..() - update_cableview() - -/mob/living/simple_animal/demon/pulse_demon/proc/make_pulse_antagonist(demon) - SIGNAL_HANDLER - mind.assigned_role = SPECIAL_ROLE_DEMON - mind.special_role = SPECIAL_ROLE_DEMON - give_objectives() - -/mob/living/simple_animal/demon/pulse_demon/vv_edit_var(var_name, var_value) - switch(var_name) - if("glow_color") - update_glow() - if("charge") - // automatically adjusts maxcharge to allow the new value - adjust_charge(var_value - charge, TRUE) - return TRUE - return ..() - -/mob/living/simple_animal/demon/pulse_demon/forceMove(atom/destination) - var/old_location = loc - . = ..() - current_weapon = null - current_robot = null - if(current_bot) - current_bot.hijacked = FALSE - current_bot = null - if(istype(old_location, /obj/item/stock_parts/cell)) - var/obj/item/stock_parts/cell/C = old_location - // only set rigged if there are no remaining demons in the cell - C.rigged = !(locate(/mob/living/simple_animal/demon/pulse_demon) in old_location) - if(istype(loc, /obj/item/stock_parts/cell)) - var/obj/item/stock_parts/cell/C = loc - C.rigged = FALSE - -/mob/living/simple_animal/demon/pulse_demon/proc/give_objectives() - if(!mind) - return - mind.wipe_memory() - var/list/greeting = list() - greeting.Add("You are a pulse demon.") - greeting.Add("A being made of pure electrical energy, you travel through the station's wires and infest machinery.") - greeting.Add("Navigate the station's power cables to find power sources to steal from, and hijack APCs to interact with their connected machines.") - greeting.Add("If the wire or power source you're connected to runs out of power you'll start losing health and eventually die, but you are otherwise immune to damage.") - greeting.Add("For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Pulse_Demon)") - for(var/datum/objective/new_obj in list(/datum/objective/pulse_demon/infest, /datum/objective/pulse_demon/drain, /datum/objective/pulse_demon/tamper)) - mind.add_mind_objective(new_obj) - greeting.Add(mind.prepare_announce_objectives(FALSE)) - to_chat(src, chat_box_red(greeting.Join("
    "))) - SSticker.mode.traitors |= mind - -/mob/living/simple_animal/demon/pulse_demon/proc/give_spells() - AddSpell(new /datum/spell/pulse_demon/cycle_camera) - AddSpell(new /datum/spell/pulse_demon/toggle/do_drain(do_drain)) - AddSpell(new /datum/spell/pulse_demon/toggle/can_exit_cable(can_exit_cable)) - AddSpell(new /datum/spell/pulse_demon/cablehop) - AddSpell(new /datum/spell/pulse_demon/emagtamper) - AddSpell(new /datum/spell/pulse_demon/emp) - AddSpell(new /datum/spell/pulse_demon/overload) - AddSpell(new /datum/spell/pulse_demon/remotehijack) - AddSpell(new /datum/spell/pulse_demon/remotedrain) - AddSpell(new /datum/spell/pulse_demon/open_upgrades) - -/mob/living/simple_animal/demon/pulse_demon/get_status_tab_items() - var/list/status_tab_data = ..() - . = status_tab_data - status_tab_data[++status_tab_data.len] = list("Energy:", "[format_si_suffix(charge)]J") - status_tab_data[++status_tab_data.len] = list("Maximum Energy:", "[format_si_suffix(maxcharge)]J") - status_tab_data[++status_tab_data.len] = list("Drained Energy:", "[format_si_suffix(charge_drained)]J") - status_tab_data[++status_tab_data.len] = list("Hijacked APCs:", "[length(hijacked_apcs)]") - status_tab_data[++status_tab_data.len] = list("Drain Rate:", "[format_si_suffix(power_drain_rate)]W") - status_tab_data[++status_tab_data.len] = list("Hijack Time:", "[hijack_time / 10] seconds") - -/mob/living/simple_animal/demon/pulse_demon/dust() - return death() - -/mob/living/simple_animal/demon/pulse_demon/gib() - return death() - -/mob/living/simple_animal/demon/pulse_demon/death() - var/turf/T = get_turf(src) - do_sparks(rand(2, 4), FALSE, src) - . = ..() - - var/heavy_radius = min(charge / 50000, 20) - var/light_radius = min(charge / 25000, 25) - empulse(T, heavy_radius, light_radius) - playsound(T, pick(hurt_sounds), 30, TRUE) - -/mob/living/simple_animal/demon/pulse_demon/proc/exit_to_turf() - var/turf/T = get_turf(src) - current_power = null - update_controlling_area() - current_cable = null - forceMove(T) - Move(T) - if(!current_cable && !current_power) - var/datum/spell/pulse_demon/toggle/can_exit_cable/S = locate() in mob_spell_list - if(!S.locked && !can_exit_cable) - can_exit_cable = TRUE - S.do_toggle(can_exit_cable) - to_chat(src, "Your self-sustaining ability has automatically enabled itself to prevent death from having no connection!") - -/mob/living/simple_animal/demon/pulse_demon/proc/update_controlling_area(reset = FALSE) - var/area/prev = controlling_area - if(reset || current_power == null) - controlling_area = null - else if(isapc(current_power)) - var/obj/machinery/power/apc/A = current_power - if(A in hijacked_apcs) - controlling_area = A.apc_area - else - controlling_area = null - - if((!prev && !controlling_area) || (prev && controlling_area)) - return // only update icons when we get or no longer have ANY area - for(var/datum/spell/pulse_demon/S in mob_spell_list) - if(!S.action || S.locked) - continue - if(S.requires_area) - S.action.UpdateButtons() - -// can enter an apc at all? -/mob/living/simple_animal/demon/pulse_demon/proc/is_valid_apc(obj/machinery/power/apc/A) - return istype(A) && !(A.stat & BROKEN) && !A.shorted - -/mob/living/simple_animal/demon/pulse_demon/Move(newloc) - var/obj/machinery/power/new_power = locate(/obj/machinery/power) in newloc - var/obj/structure/cable/new_cable = locate(/obj/structure/cable) in newloc - - if(QDELETED(new_power)) - new_power = null - if(QDELETED(new_cable)) - new_cable = null - - if(istype(new_power, /obj/machinery/power/terminal)) - // entering a terminal is kinda useless and any working terminal will have a cable under it - new_power = null - - if(isapc(new_power)) - var/obj/machinery/power/apc/A = new_power - if(!is_valid_apc(new_power) || !A.terminal) - new_power = null // don't enter an APC without a terminal or a broken APC, etc. - - // there's no electricity in space - if(!new_cable && !new_power && (!can_exit_cable || isspaceturf(newloc))) - return - - var/moved = ..() - - if(!new_cable && !new_power) - if(can_exit_cable && moved) - speed = outside_cable_speed - else - speed = inside_cable_speed - - if(moved) - if(!is_under_tile() && prob(PULSEDEMON_PLATING_SPARK_CHANCE)) - do_sparks(rand(2, 4), FALSE, src) - - current_weapon = null - current_robot = null - if(current_bot) - current_bot.hijacked = FALSE - current_bot = null - - /* - A few notes about this terrible proc, If you're wondering, I didn't write it but man I do NOT want to touch it - 1. A lot of this 100% shouldn't be on move, that's just waiting for something bad to happen - 2. Never, EVER directly call a do_after here, it will cause move to sleep which is awful - */ - if(new_power) - current_power = new_power - current_cable = null - forceMove(current_power) // we go inside the machine - RegisterSignal(current_power, COMSIG_ATOM_EMP_ACT, PROC_REF(handle_emp), TRUE) - playsound(src, 'sound/effects/eleczap.ogg', 15, TRUE) - do_sparks(rand(2, 4), FALSE, src) - if(isapc(current_power)) - if(current_power in hijacked_apcs) - update_controlling_area() - else - INVOKE_ASYNC(src, PROC_REF(try_hijack_apc), current_power) - else if(new_cable) - current_cable = new_cable - if(current_power) - UnregisterSignal(current_power, COMSIG_ATOM_EMP_ACT) - current_power = null - update_controlling_area() - if(!isturf(loc)) - loc = get_turf(newloc) - if(!moved) - forceMove(newloc) - else if(moved) - current_cable = null - current_power = null - update_controlling_area() - -// signal to replace relaymove where or when? // Never, actually just manage your code instead -/obj/machinery/power/relaymove(mob/user, dir) - if(!ispulsedemon(user)) - return ..() - - var/mob/living/simple_animal/demon/pulse_demon/demon = user - var/turf/T = get_turf(src) - var/turf/T2 = get_step(T, dir) - if(demon.can_exit_cable || locate(/obj/structure/cable) in T2) - playsound(src, 'sound/effects/eleczap.ogg', 15, TRUE) - do_sparks(rand(2, 4), FALSE, src) - user.forceMove(T) - if(isapc(src)) - demon.update_controlling_area(TRUE) - -/mob/living/simple_animal/demon/pulse_demon/proc/adjust_charge(amount, adjust_max = FALSE) - if(!amount) - return FALSE - if(adjust_max) - maxcharge = max(maxcharge, charge + amount) - var/orig = charge - charge = min(maxcharge, charge + amount) - var/realdelta = charge - orig - if(!realdelta) - return FALSE - if(realdelta > 0) - charge_drained += realdelta - - update_glow() - for(var/datum/spell/pulse_demon/S in mob_spell_list) - if(!S.action || S.locked || !S.cast_cost) - continue - var/dist = S.cast_cost - orig - // only update icon if the amount is actually enough to change a spell's availability - if(dist == 0 || (dist > 0 && realdelta >= dist) || (dist < 0 && realdelta <= dist)) - S.action.UpdateButtons() - return realdelta - -// logarithmic scale for glow strength, see table: - // 1.5 <= 25k - // 2 at 50k - // 2.5 at 100k - // 3 at 200k - // 3.5 at 400k, etc -/mob/living/simple_animal/demon/pulse_demon/proc/update_glow() - var/range = 2 + (log(2, charge + 1) - log(2, 50000)) / 2 - range = max(range, 1.5) - set_light(range, 2, glow_color) - -/mob/living/simple_animal/demon/pulse_demon/proc/drain_APC(obj/machinery/power/apc/A, multiplier = 1) - if(A.being_hijacked) - return PULSEDEMON_SOURCE_DRAIN_INVALID - //CELLRATE is the conversion ratio between a watt tick and powercell energy storage units - var/amount_to_drain = clamp(A.cell.charge / GLOB.CELLRATE, 0, power_drain_rate * WATT_TICK_TO_JOULE * multiplier) - A.cell.use(min(amount_to_drain * GLOB.CELLRATE, maxcharge - charge)) // calculated seperately because the apc charge multiplier shouldn't affect the actual consumption - return adjust_charge(amount_to_drain * PULSEDEMON_APC_CHARGE_MULTIPLIER) - -/mob/living/simple_animal/demon/pulse_demon/proc/drain_SMES(obj/machinery/power/smes/S, multiplier = 1) - //CELLRATE is the conversion ratio between a watt tick and powercell energy storage units. - var/amount_to_drain = clamp(S.charge / GLOB.CELLRATE, 0, power_drain_rate * WATT_TICK_TO_JOULE * multiplier * PULSEDEMON_SMES_DRAIN_MULTIPLIER) - var/drained = adjust_charge(amount_to_drain) - S.charge -= drained * GLOB.CELLRATE - return drained - -/mob/living/simple_animal/demon/pulse_demon/Life(seconds, times_fired) - . = ..() - - var/got_power = FALSE - if(current_cable) - if(current_cable.get_available_power() >= power_per_regen) - current_cable.add_power_demand(power_per_regen) - got_power = TRUE - - var/excess = initial(power_per_regen) - power_per_regen - if(excess > 0 && current_cable.get_available_power() >= excess && do_drain) - adjust_charge(excess) - current_cable.add_power_demand(excess) - else if(current_power) - if(isapc(current_power) && loc == current_power && do_drain) - if(drain_APC(current_power) > power_per_regen) - got_power = TRUE - else if(istype(current_power, /obj/machinery/power/smes) && do_drain) - if(drain_SMES(current_power) > power_per_regen) - got_power = TRUE - // try to take power from the powernet if the APC or SMES is empty (or we're not /really/ in the APC) - if(!got_power && current_power.get_available_power() >= power_per_regen) - current_power.consume_direct_power(power_per_regen) - got_power = TRUE - else if(!can_exit_cable) - death() - return - - if(got_power) - if(regen_lock <= 0) - adjustHealth(-health_regen_rate) - clear_alert(ALERT_CATEGORY_NOPOWER) - else - var/rate = health_loss_rate - if(!current_cable && !current_power && can_exit_cable) - // 2 * initial_rate - upgrade_level - rate += initial(health_loss_rate) - adjustHealth(rate) - throw_alert(ALERT_CATEGORY_NOPOWER, /atom/movable/screen/alert/pulse_nopower) - - if(regen_lock > 0) - if(--regen_lock == 0) - clear_alert(ALERT_CATEGORY_NOREGEN) - -/mob/living/simple_animal/demon/pulse_demon/proc/gen_speech_name() - . = "" - for(var/i = 1 to 10) - . += pick("!", "@", "#", "$", "%", "^", "&", "*") - -/mob/living/simple_animal/demon/pulse_demon/say(message, verb, sanitize = TRUE, ignore_speech_problems = FALSE, ignore_atmospherics = FALSE, ignore_languages = FALSE) - if(client && check_mute(client.ckey, MUTE_IC)) - to_chat(src, "You cannot speak in IC (Muted).") - return FALSE - - if(sanitize) - message = sanitize_for_ic(trim(message)) - - if(stat) - if(stat == DEAD) - return say_dead(message) - return FALSE - - if(current_robot) - var/turf/T = get_turf(src) - log_say("[key_name_admin(src)] (@[T.x], [T.y], [T.z]) made [current_robot]([key_name_admin(current_robot)]) say: [message]") - log_admin("[key_name_admin(src)] made [key_name_admin(current_robot)] say: [message]") - message_admins("[key_name_admin(src)] made [key_name_admin(current_robot)] say: [message]") - // don't sanitize again - current_robot.say(message, null, FALSE, ignore_speech_problems, ignore_atmospherics, ignore_languages) - return TRUE - - var/message_mode = parse_message_mode(message, "headset") - - if(message_mode) - if(message_mode == "headset") - message = copytext(message, 2) - else - message = copytext(message, 3) - - message = trim_left(message) - - var/list/message_pieces = list() - if(ignore_languages) - message_pieces = message_to_multilingual(message) - else - message_pieces = parse_languages(message) - - // hivemind languages - if(istype(message_pieces, /datum/multilingual_say_piece)) - var/datum/multilingual_say_piece/S = message_pieces - S.speaking.broadcast(src, S.message) - return TRUE - - if(!LAZYLEN(message_pieces)) - . = FALSE - CRASH("Message failed to generate pieces. [message] - [json_encode(message_pieces)]") - - create_log(SAY_LOG, "[message_mode ? "([message_mode])" : ""] '[message]'") - - playsound(get_turf(src), pick(speech_sounds), 30, TRUE) - if(istype(loc, /obj/item/radio)) - var/obj/item/radio/R = loc - name = gen_speech_name() - R.talk_into(src, message_pieces, message_mode, verbage = verb) - name = real_name - return TRUE - else if(istype(loc, /obj/machinery/hologram/holopad)) - var/obj/machinery/hologram/holopad/H = loc - name = "[H]" - for(var/mob/M as anything in get_mobs_in_view(7, H)) - M.hear_say(message_pieces, verb, FALSE, src) - name = real_name - return TRUE - - emote("me", message = "[pick(emote_hear)]") - return TRUE - -/mob/living/simple_animal/demon/pulse_demon/update_runechat_msg_location() - if(istype(loc, /obj/machinery/hologram/holopad)) - runechat_msg_location = loc.UID() - else - return ..() - -/mob/living/simple_animal/demon/pulse_demon/visible_message(message, self_message, blind_message, chat_message_type) - // overriden because pulse demon is quite often in non-turf locs, and /mob/visible_message acts differently there - for(var/mob/M as anything in get_mobs_in_view(7, src)) - if(M.see_invisible < invisibility) - continue //can't view the invisible - var/msg = message - if(self_message && M == src) - msg = self_message - M.show_message(msg, EMOTE_VISIBLE, blind_message, EMOTE_AUDIBLE, chat_message_type = MESSAGE_TYPE_LOCALCHAT) - -/mob/living/simple_animal/demon/pulse_demon/has_internal_radio_channel_access(mob/user, list/req_one_accesses) - return has_access(list(), req_one_accesses, get_all_accesses()) - -/mob/living/simple_animal/demon/pulse_demon/proc/try_hijack_apc(obj/machinery/power/apc/A, remote = FALSE) - // one APC per pulse demon, one pulse demon per APC, no duplicate APCs - if(!is_valid_apc(A) || (A in hijacked_apcs) || apc_being_hijacked || A.being_hijacked) - return FALSE - - to_chat(src, "You are now attempting to hijack [A], this will take approximately [hijack_time / 10] seconds.") - apc_being_hijacked = A - A.being_hijacked = TRUE - A.update_icon() - if(do_after(src, hijack_time, target = A)) - if(is_valid_apc(A)) - finish_hijack_apc(A, remote) - else - to_chat(src, "Failed to hijack [src].") - apc_being_hijacked = null - A.being_hijacked = FALSE - A.update_icon() - -// Basically this proc gives you more max charge per apc you have hijacked -// Looks weird but it gets the job done -/mob/living/simple_animal/demon/pulse_demon/proc/calc_maxcharge(hijacked_apcs) - if(!hijacked_apcs) // No APCs hijacked? No extra charge - return 1000 - return 20000 * clamp(hijacked_apcs, 0, 20) + 500000 * clamp(hijacked_apcs - 20, 0, 30) + 1000000 * clamp(hijacked_apcs - 50, 0, 50) + 500000000 * max(0, hijacked_apcs - 100) - -/mob/living/simple_animal/demon/pulse_demon/proc/finish_hijack_apc(obj/machinery/power/apc/A, remote = FALSE) - var/image/apc_image = image('icons/obj/power.dmi', A, "apcemag", ABOVE_LIGHTING_LAYER, A.dir) - apc_image.plane = ABOVE_LIGHTING_PLANE - LAZYADD(apc_images[get_turf(A)], apc_image) - client.images += apc_image - - hijacked_apcs += A - RegisterSignal(A, COMSIG_PARENT_QDELETING, PROC_REF(apc_deleted_handler)) - if(!remote) - update_controlling_area() - maxcharge = calc_maxcharge(length(hijacked_apcs)) + (maxcharge - calc_maxcharge(length(hijacked_apcs) - 1)) - to_chat(src, "Hijacking complete! You now control [length(hijacked_apcs)] APCs.") - -/mob/living/simple_animal/demon/pulse_demon/proc/on_atom_entered(datum/source, atom/movable/entered) - SIGNAL_HANDLER // COMSIG_ATOM_ENTERED - try_cross_shock(entered) - -/mob/living/simple_animal/demon/pulse_demon/proc/on_movable_moved(datum/source, old_location, direction, forced) - SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED - if(is_under_tile()) - return - for(var/mob/living/mob in loc) - try_shock_mob(mob) - -/mob/living/simple_animal/demon/pulse_demon/proc/try_cross_shock(atom/movable/A) - if(!isliving(A) || is_under_tile()) - return - var/mob/living/L = A - try_shock_mob(L) - -/mob/living/simple_animal/demon/pulse_demon/proc/try_shock_mob(mob/living/L, siemens_coeff = 1) - var/dealt = 0 - if(current_cable && current_cable.powernet && current_cable.powernet.available_power) - // returns used energy, not damage dealt, but ez conversion with /20 - dealt = electrocute_mob(L, current_cable.powernet, src, siemens_coeff) / 20 - else if(charge >= 1000) - dealt = L.electrocute_act(30, src, siemens_coeff) - adjust_charge(-1000) - if(dealt > 0) - do_sparks(rand(2, 4), FALSE, src) - add_attack_logs(src, L, "shocked ([dealt] damage)") - -/mob/living/simple_animal/demon/pulse_demon/proc/is_under_tile() - var/turf/T = get_turf(src) - return T.intact || HAS_TRAIT(T, TRAIT_TURF_COVERED) - -// cable (and hijacked APC) view helper -/mob/living/simple_animal/demon/pulse_demon/proc/update_cableview() - if(!client) - return - - // clear out old images - for(var/image/current_image in cable_images + apc_images) - client.images -= current_image - - var/turf/T = get_turf(src) - - // regenerate for all cables on our (or our holder's) z-level - cable_images.Cut() - for(var/datum/regional_powernet/P in SSmachines.powernets) - for(var/obj/structure/cable/C in P.cables) - var/turf/cable_turf = get_turf(C) - if(T.z != cable_turf.z) - break // skip entire powernet if it's off z-level - - var/image/cable_image = image(C, C, layer = ABOVE_LIGHTING_LAYER, dir = C.dir) - // good visibility here - cable_image.plane = ABOVE_LIGHTING_PLANE - LAZYADD(cable_images[cable_turf], cable_image) - client.images += cable_image - - // same for hijacked APCs - apc_images.Cut() - for(var/obj/machinery/power/apc/A in hijacked_apcs) - var/turf/apc_turf = get_turf(A) - if(T.z != apc_turf.z) - continue - // parent of image is the APC, not the turf because of how clicking on images works - var/image/apc_image = image('icons/obj/power.dmi', A, "apcemag", ABOVE_LIGHTING_LAYER, A.dir) - apc_image.plane = ABOVE_LIGHTING_PLANE - LAZYADD(apc_images[apc_turf], apc_image) - client.images += apc_image - -/mob/living/simple_animal/demon/pulse_demon/proc/handle_emp(datum/source, severity) - SIGNAL_HANDLER - if(emp_debounce) - return - visible_message("[src] [pick("fizzles", "wails", "flails")] in anguish!") - playsound(get_turf(src), pick(hurt_sounds), 30, TRUE) - throw_alert(ALERT_CATEGORY_NOREGEN, /atom/movable/screen/alert/pulse_noregen) - switch(severity) - if(EMP_LIGHT) - adjustHealth(round(max(initial(health) / 4, round(maxHealth / 8)))) - regen_lock = 3 - if(EMP_HEAVY) - adjustHealth(round(max(initial(health) / 3, round(maxHealth / 6)))) - regen_lock = 5 - emp_debounce = TRUE - addtimer(VARSET_CALLBACK(src, emp_debounce, FALSE), 0.1 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) - -/mob/living/simple_animal/demon/pulse_demon/proc/try_attack_mob(mob/living/L) - if(!is_under_tile() && L != src) - do_attack_animation(L) - try_shock_mob(L) - -/mob/living/simple_animal/demon/pulse_demon/UnarmedAttack(atom/A) - if(isliving(A)) - try_attack_mob(A) - else if(isitem(A) && !is_under_tile()) - var/obj/item/O = A - var/obj/item/stock_parts/cell/C = O.get_cell() - if(C?.charge) - C.use(min(C.charge, power_drain_rate)) - adjust_charge(min(C.charge, power_drain_rate)) - visible_message("[src] touches [O] and drains its power!", "You touch [O] and drain it's power!") - -/mob/living/simple_animal/demon/pulse_demon/attack_hand(mob/living/carbon/human/M) - if(is_under_tile()) - to_chat(M, "You can't interact with something that's under the floor!") - return - switch(M.intent) - if(INTENT_HELP) - visible_message("[M] [response_help] [src].") - if(INTENT_DISARM, INTENT_GRAB) - visible_message("[M] [response_disarm] [src].") - if(INTENT_HELP) - visible_message("[M] [response_harm] [src].") - try_attack_mob(M) - -/mob/living/simple_animal/demon/pulse_demon/attackby__legacy__attackchain(obj/item/O, mob/living/user) - if(is_under_tile()) - to_chat(user, "You can't interact with something that's under the floor!") - return - var/obj/item/stock_parts/cell/C = O.get_cell() - if(C && C.charge) - C.use(min(C.charge, power_drain_rate)) - adjust_charge(min(C.charge, power_drain_rate)) - to_chat(user, "You touch [src] with [O] and [src] drains it!") - to_chat(src, "[user] touches you with [O] and you drain its power!") - visible_message("[O] goes right through [src].") - try_shock_mob(user, O.siemens_coefficient) - -/mob/living/simple_animal/demon/pulse_demon/ex_act() - return - -/mob/living/simple_animal/demon/pulse_demon/CanPass(atom/movable/mover, border_dir) - . = ..() - if(istype(mover, /obj/item/projectile/ion)) - return FALSE - -/mob/living/simple_animal/demon/pulse_demon/bullet_act(obj/item/projectile/proj) - if(proj.damage_type == BURN) - regen_lock = max(regen_lock, 1) - return ..() - else - visible_message("[proj] goes right through [src]!") - -/mob/living/simple_animal/demon/pulse_demon/electrocute_act(shock_damage, source, siemens_coeff, flags) - return - -/mob/living/simple_animal/demon/pulse_demon/blob_act(obj/structure/blob/B) - return // will likely end up dying if the blob cuts its wires anyway - -/mob/living/simple_animal/demon/pulse_demon/narsie_act() - return // you can't turn electricity into a harvester - -/mob/living/simple_animal/demon/pulse_demon/get_access() - return get_all_accesses() - -/mob/living/simple_animal/demon/pulse_demon/IsAdvancedToolUser() - return TRUE // interacting with machines - -/mob/living/simple_animal/demon/pulse_demon/can_be_pulled() - return FALSE - -/mob/living/simple_animal/demon/pulse_demon/can_buckle() - return FALSE - -/mob/living/simple_animal/demon/pulse_demon/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) - return - -/mob/living/simple_animal/demon/pulse_demon/experience_pressure_difference(flow_x, flow_y) - return // Immune to gas flow. - -/mob/living/simple_animal/demon/pulse_demon/singularity_pull() - return - -/mob/living/simple_animal/demon/pulse_demon/mob_negates_gravity() - return TRUE - -/mob/living/simple_animal/demon/pulse_demon/mob_has_gravity() - return TRUE - -/mob/living/simple_animal/demon/pulse_demon/can_remote_apc_interface(obj/machinery/power/apc/ourapc) - if(ourapc.hacked_by_ruin_AI || ourapc.malfai || ourapc.malfhack) - return FALSE - return TRUE - -/mob/living/simple_animal/demon/pulse_demon/adjustHealth(amount, updating_health) - if(amount > 0) // This damages the pulse demon - return ..() - - if(!ismachinery(loc)) - if(health >= (maxHealth / 2)) - amount = 0 - else - amount = clamp(amount, -((maxHealth / 2) - health), 0) - amount = round(amount, 1) - return ..() - -/obj/item/organ/internal/heart/demon/pulse - name = "perpetual pacemaker" - desc = "It still beats furiously, thousands of bright lights shine within it." - color = COLOR_YELLOW - -/obj/item/organ/internal/heart/demon/pulse/Initialize(mapload) - . = ..() - set_light(13, 2, "#bbbb00") - -/obj/item/organ/internal/heart/demon/pulse/attack_self__legacy__attackchain(mob/living/user) - . = ..() - user.drop_item() - insert(user) - -/obj/item/organ/internal/heart/demon/pulse/insert(mob/living/carbon/M, special, dont_remove_slot) - . = ..() - M.AddComponent(/datum/component/cross_shock, 30, 500, 2 SECONDS) - ADD_TRAIT(M, TRAIT_SHOCKIMMUNE, UNIQUE_TRAIT_SOURCE(src)) - M.set_light(3, 2, "#bbbb00") - -/obj/item/organ/internal/heart/demon/pulse/remove(mob/living/carbon/M, special) - . = ..() - REMOVE_TRAIT(M, TRAIT_SHOCKIMMUNE, UNIQUE_TRAIT_SOURCE(src)) - M.remove_light() - -/obj/item/organ/internal/heart/demon/pulse/on_life() - if(!owner) - return - for(var/obj/item/stock_parts/cell/cell_to_charge in owner.GetAllContents()) - var/newcharge = min(0.05 * cell_to_charge.maxcharge + cell_to_charge.charge, cell_to_charge.maxcharge) - if(cell_to_charge.charge < newcharge) - cell_to_charge.charge = newcharge - if(isobj(cell_to_charge.loc)) - var/obj/cell_location = cell_to_charge.loc - cell_location.update_icon() //update power meters and such - cell_to_charge.update_icon() - -/atom/movable/screen/alert/pulse_nopower - name = "No Power" - desc = "You are not connected to a cable or machine and are losing health!" - icon_state = "pd_nopower" - -/atom/movable/screen/alert/pulse_noregen - name = "Regeneration Stalled" - desc = "You've been EMP'd and cannot regenerate health!" - icon_state = "pd_noregen" - -#undef ALERT_CATEGORY_NOPOWER -#undef ALERT_CATEGORY_NOREGEN - -#undef PULSEDEMON_PLATING_SPARK_CHANCE -#undef PULSEDEMON_APC_CHARGE_MULTIPLIER -#undef PULSEDEMON_SMES_DRAIN_MULTIPLIER diff --git a/code/game/gamemodes/miniantags/pulsedemon/pulsedemon_abilities.dm b/code/game/gamemodes/miniantags/pulsedemon/pulsedemon_abilities.dm deleted file mode 100644 index 97c86faf060d4..0000000000000 --- a/code/game/gamemodes/miniantags/pulsedemon/pulsedemon_abilities.dm +++ /dev/null @@ -1,496 +0,0 @@ -#define PULSEDEMON_REMOTE_DRAIN_MULTIPLIER 5 - -#define PD_UPGRADE_HIJACK_SPEED "Speed" -#define PD_UPGRADE_DRAIN_SPEED "Absorption" -#define PD_UPGRADE_HEALTH_LOSS "Endurance" -#define PD_UPGRADE_HEALTH_REGEN "Recovery" -#define PD_UPGRADE_MAX_HEALTH "Strength" -#define PD_UPGRADE_HEALTH_COST "Efficiency" -#define PD_UPGRADE_MAX_CHARGE "Capacity" - -/datum/spell/pulse_demon - clothes_req = FALSE - antimagic_flags = NONE - action_background_icon_state = "bg_pulsedemon" - var/locked = TRUE - var/unlock_cost = 1 KJ - var/cast_cost = 1 KJ - var/upgrade_cost = 1 KJ - var/requires_area = FALSE - base_cooldown = 20 SECONDS - level_max = 4 - -/datum/spell/pulse_demon/New() - . = ..() - update_info() - -/datum/spell/pulse_demon/proc/update_info() - if(locked) - name = "[initial(name)] (Locked) ([format_si_suffix(unlock_cost)]W)" - desc = "[initial(desc)] It costs [format_si_suffix(unlock_cost)]W to unlock. Alt-Click this spell to unlock it." - else - name = "[initial(name)][cast_cost == 0 ? "" : " ([format_si_suffix(cast_cost)]W)"]" - desc = "[initial(desc)][spell_level == level_max ? "" : " It costs [format_si_suffix(upgrade_cost)]W to upgrade. Alt-Click this spell to upgrade it."]" - action.name = name - action.desc = desc - action.UpdateButtons() - -/datum/spell/pulse_demon/can_cast(mob/living/simple_animal/demon/pulse_demon/user, charge_check, show_message) - if(!..()) - return FALSE - if(!istype(user)) - return FALSE - if(locked) - if(show_message) - to_chat(user, "This ability is locked! Alt-click the button to purchase this ability.") - to_chat(user, "It costs [format_si_suffix(unlock_cost)]W to unlock.") - return FALSE - if(user.charge < cast_cost) - if(show_message) - to_chat(user, "You do not have enough charge to use this ability!") - to_chat(user, "It costs [format_si_suffix(cast_cost)]W to use.") - return FALSE - if(requires_area && !user.controlling_area) - if(show_message) - to_chat(user, "You need to be controlling an area to use this ability!") - return FALSE - return TRUE - -/datum/spell/pulse_demon/cast(list/targets, mob/living/simple_animal/demon/pulse_demon/user) - if(!istype(user) || locked || user.charge < cast_cost || !length(targets)) - return FALSE - if(requires_area && !user.controlling_area) - return FALSE - if(requires_area && user.controlling_area != get_area(targets[1])) - to_chat(user, "You can only use this ability in your controlled area!") - return FALSE - if(try_cast_action(user, targets[1])) - user.adjust_charge(-cast_cost) - return TRUE - else - revert_cast(user) - return FALSE - -/datum/spell/pulse_demon/create_new_targeting() - return new /datum/spell_targeting/clicked_atom - -/datum/spell/pulse_demon/proc/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) - return FALSE - -// handles purchasing and upgrading abilities -/datum/spell/pulse_demon/AltClick(mob/living/simple_animal/demon/pulse_demon/user) - if(!istype(user)) - return - - if(locked) - if(user.charge >= unlock_cost) - user.adjust_charge(-unlock_cost) - locked = FALSE - to_chat(user, "You have unlocked [initial(name)]!") - - if(cast_cost > 0) - to_chat(user, "It costs [format_si_suffix(cast_cost)]W to use once.") - if(level_max > 0 && spell_level < level_max) - to_chat(user, "It will cost [format_si_suffix(upgrade_cost)]W to upgrade.") - - update_info() - else - to_chat(user, "You cannot afford this ability! It costs [format_si_suffix(unlock_cost)]W to unlock.") - else - if(spell_level >= level_max) - to_chat(user, "You have already fully upgraded this ability!") - else if(user.charge >= upgrade_cost) - user.adjust_charge(-upgrade_cost) - spell_level = min(spell_level + 1, level_max) - upgrade_cost = round(initial(upgrade_cost) * (1.5 ** spell_level)) - do_upgrade(user) - - if(spell_level == level_max) - to_chat(user, "You have fully upgraded [initial(name)]!") - else - to_chat(user, "The next upgrade will cost [format_si_suffix(upgrade_cost)]W to unlock.") - - update_info() - else - to_chat(user, "You cannot afford to upgrade this ability! It costs [format_si_suffix(upgrade_cost)]W to upgrade.") - -/datum/spell/pulse_demon/proc/do_upgrade(mob/living/simple_animal/demon/pulse_demon/user) - cooldown_handler.recharge_duration = round(base_cooldown / (1.5 ** spell_level)) - to_chat(user, "You have upgraded [initial(name)] to level [spell_level + 1], it now takes [cooldown_handler.recharge_duration / 10] seconds to recharge.") - -/datum/spell/pulse_demon/cablehop - name = "Cable Hop" - desc = "Jump to another cable in view." - action_icon_state = "pd_cablehop" - unlock_cost = 15 KJ - cast_cost = 5 KJ - upgrade_cost = 75 KJ - -/datum/spell/pulse_demon/cablehop/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) - var/turf/O = get_turf(user) - var/turf/T = get_turf(target) - var/obj/structure/cable/C = locate(/obj/structure/cable) in T - if(!istype(C)) - to_chat(user, "No cable found!") - return FALSE - if(get_dist(O, T) > 15) //Some extra range to account for them possessing machines away from their APC, but blocking demons from using a camera console to zap across the station. - to_chat(user, "That cable is too far away!") - return FALSE - playsound(T, 'sound/magic/lightningshock.ogg', 50, TRUE) - O.Beam(target, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 1 SECONDS) - for(var/turf/working in get_line(O, T)) - for(var/mob/living/L in working) - if(!electrocute_mob(L, C.powernet, user)) // give a little bit of non-lethal counterplay against insuls - L.Jitter(5 SECONDS) - L.apply_status_effect(STATUS_EFFECT_DELAYED, 1 SECONDS, CALLBACK(L, TYPE_PROC_REF(/mob/living, KnockDown), 5 SECONDS), COMSIG_LIVING_CLEAR_STUNS) - user.forceMove(T) - user.Move(T) - return TRUE - -/datum/spell/pulse_demon/emagtamper - name = "Electromagnetic Tamper" - desc = "Unlocks hidden programming in machines. Must be inside a hijacked APC to use." - action_icon_state = "pd_emag" - unlock_cost = 50 KJ - cast_cost = 20 KJ - upgrade_cost = 200 KJ - requires_area = TRUE - -/datum/spell/pulse_demon/emagtamper/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) - to_chat(user, "You attempt to tamper with [target]!") - target.emag_act(user) - return TRUE - -/datum/spell/pulse_demon/emp - name = "Electromagnetic Pulse" - desc = "Creates an EMP where you click. Be careful not to use it on yourself!" - action_icon_state = "pd_emp" - unlock_cost = 50 KJ - cast_cost = 10 KJ - upgrade_cost = 200 KJ - requires_area = TRUE - -/datum/spell/pulse_demon/emp/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) - to_chat(user, "You attempt to EMP [target]!") - empulse(get_turf(target), 1, 1) - return TRUE - -/datum/spell/pulse_demon/overload - name = "Overload Machine" - desc = "Overloads a machine, causing it to explode." - action_icon_state = "pd_overload" - unlock_cost = 300 KJ - cast_cost = 50 KJ - upgrade_cost = 500 KJ - requires_area = TRUE - -/datum/spell/pulse_demon/overload/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) - var/obj/machinery/M = target - if(!istype(M)) - to_chat(user, "That is not a machine.") - return FALSE - if(target.flags_2 & NO_MALF_EFFECT_2) - to_chat(user, "That machine cannot be overloaded.") - return FALSE - target.audible_message("You hear a loud electrical buzzing sound coming from [target]!") - addtimer(CALLBACK(src, PROC_REF(detonate), M), 5 SECONDS) - return TRUE - -/datum/spell/pulse_demon/overload/proc/detonate(obj/machinery/target) - if(!QDELETED(target)) - explosion(get_turf(target), 0, 1, 1, 0) - if(!QDELETED(target)) - qdel(target) - -/datum/spell/pulse_demon/remotehijack - name = "Remote Hijack" - desc = "Remotely hijacks an APC." - action_icon_state = "pd_remotehack" - unlock_cost = 15 KJ - cast_cost = 10 KJ - level_max = 0 - base_cooldown = 3 SECONDS // you have to wait for the regular hijack time anyway - -/datum/spell/pulse_demon/remotehijack/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) - var/obj/machinery/power/apc/A = target - if(!istype(A)) - to_chat(user, "That is not an APC.") - return FALSE - if(!user.try_hijack_apc(A, TRUE)) - to_chat(user, "You cannot hijack that APC right now!") - return TRUE - -/datum/spell/pulse_demon/remotedrain - name = "Remote Drain" - desc = "Remotely drains a power source." - action_icon_state = "pd_remotedrain" - unlock_cost = 5 KJ - cast_cost = 100 - upgrade_cost = 100 KJ - -/datum/spell/pulse_demon/remotedrain/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) - if(isapc(target)) - var/drained = user.drain_APC(target, PULSEDEMON_REMOTE_DRAIN_MULTIPLIER) - if(drained == PULSEDEMON_SOURCE_DRAIN_INVALID) - to_chat(user, "This APC is being hijacked, you cannot drain from it right now.") - else - to_chat(user, "You drain [format_si_suffix(drained)]W from [target].") - else if(istype(target, /obj/machinery/power/smes)) - var/drained = user.drain_SMES(target, PULSEDEMON_REMOTE_DRAIN_MULTIPLIER) - to_chat(user, "You drain [format_si_suffix(drained)]W from [target].") - else - to_chat(user, "That is not a valid source.") - return FALSE - return TRUE - -/datum/spell/pulse_demon/toggle - base_cooldown = 0 - cast_cost = 0 - create_attack_logs = FALSE - var/base_message = "see messages you shouldn't!" - -/datum/spell/pulse_demon/toggle/New(initstate = FALSE) - . = ..() - do_toggle(initstate, null) - -/datum/spell/pulse_demon/toggle/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/pulse_demon/toggle/proc/do_toggle(varstate, mob/user) - if(action) - action.button_background_icon_state = varstate ? action_background_icon_state : "[action_background_icon_state]_disabled" - action.UpdateButtons() - if(user) - to_chat(user, "You will [varstate ? "now" : "no longer"] [base_message]") - return varstate - -/datum/spell/pulse_demon/toggle/do_drain - name = "Toggle Draining" - desc = "Toggle whether you drain charge from power sources." - base_message = "drain charge from power sources." - action_icon_state = "pd_toggle_steal" - locked = FALSE - level_max = 0 - -/datum/spell/pulse_demon/toggle/do_drain/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) - user.do_drain = do_toggle(!user.do_drain, user) - return TRUE - -/datum/spell/pulse_demon/toggle/do_drain/AltClick(mob/living/simple_animal/demon/pulse_demon/user) - if(!istype(user)) - return - - var/amount = text2num(input(user, "Input a value between 1 and [user.max_drain_rate]. 0 will reset it to the maximum.", "Drain Speed Setting")) - if(amount == null || amount < 0) - to_chat(user, "Invalid input. Drain speed has not been modified.") - return - - if(amount == 0) - amount = user.max_drain_rate - user.power_drain_rate = amount - to_chat(user, "Drain speed has been set to [format_si_suffix(user.power_drain_rate)]W per second.") - -/datum/spell/pulse_demon/toggle/can_exit_cable - name = "Toggle Self-Sustaining" - desc = "Toggle whether you can move outside of cables or power sources." - base_message = "move outside of cables." - action_icon_state = "pd_toggle_exit" - unlock_cost = 100 KJ - upgrade_cost = 300 KJ - level_max = 3 - -/datum/spell/pulse_demon/toggle/can_exit_cable/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) - if(user.can_exit_cable && !(user.current_cable || user.current_power)) - to_chat(user, "Enter a cable or power source first!") - return FALSE - user.can_exit_cable = do_toggle(!user.can_exit_cable, user) - return TRUE - -/datum/spell/pulse_demon/toggle/can_exit_cable/do_upgrade(mob/living/simple_animal/demon/pulse_demon/user) - user.outside_cable_speed = max(initial(user.outside_cable_speed) - spell_level, 1) - to_chat(user, "You have upgraded [initial(name)] to level [spell_level + 1], you will now move faster outside of cables.") - -/datum/spell/pulse_demon/cycle_camera - name = "Cycle Camera View" - desc = "Jump between the cameras in your APC's area. Alt-click to return to the APC." - action_icon_state = "pd_camera_view" - create_attack_logs = FALSE - locked = FALSE - cast_cost = 0 - level_max = 0 - base_cooldown = 0 - requires_area = TRUE - var/current_camera = 0 - -/datum/spell/pulse_demon/cycle_camera/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/pulse_demon/cycle_camera/AltClick(mob/living/simple_animal/demon/pulse_demon/user) - if(!istype(user)) - return - current_camera = 0 - - if(!isapc(user.current_power)) - return - if(get_area(user.loc) != user.controlling_area) - return - user.forceMove(user.current_power) - -/datum/spell/pulse_demon/cycle_camera/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) - if(!length(user.controlling_area.cameras)) - return FALSE - - if(isapc(user.loc)) - current_camera = 0 - else if(istype(user.loc, /obj/machinery/camera)) - current_camera = (current_camera + 1) % length(user.controlling_area.cameras) - if(current_camera == 0) - user.forceMove(user.current_power) - return TRUE - - if(length(user.controlling_area.cameras) < current_camera) - current_camera = 0 - - user.forceMove(locateUID(user.controlling_area.cameras[current_camera + 1])) - return TRUE - -/datum/spell/pulse_demon/open_upgrades - name = "Open Upgrade Menu" - desc = "Open the upgrades menu. Alt-click for descriptions and costs." - action_icon_state = "pd_upgrade" - create_attack_logs = FALSE - locked = FALSE - cast_cost = 0 - level_max = 0 - base_cooldown = 0 - var/static/list/upgrade_icons = list( - PD_UPGRADE_HIJACK_SPEED = image(icon = 'icons/obj/power.dmi', icon_state = "apcemag"), - PD_UPGRADE_DRAIN_SPEED = image(icon = 'icons/obj/power.dmi', icon_state = "ccharger"), - PD_UPGRADE_MAX_HEALTH = image(icon = 'icons/obj/stock_parts.dmi', icon_state = "bluespace_matter_bin"), - PD_UPGRADE_HEALTH_REGEN = image(icon = 'icons/obj/stock_parts.dmi', icon_state = "femto_mani"), - PD_UPGRADE_HEALTH_LOSS = image(icon = 'icons/obj/stock_parts.dmi', icon_state = "triphasic_scan_module"), - PD_UPGRADE_HEALTH_COST = image(icon = 'icons/obj/stock_parts.dmi', icon_state = "quadultra_micro_laser"), - PD_UPGRADE_MAX_CHARGE = image(icon = 'icons/obj/stock_parts.dmi', icon_state = "quadratic_capacitor") - ) - var/static/list/upgrade_descs = list( - PD_UPGRADE_HIJACK_SPEED = "Decrease the amount of time required to hijack an APC.", - PD_UPGRADE_DRAIN_SPEED = "Increase the amount of charge drained from a power source per cycle.", - PD_UPGRADE_MAX_HEALTH = "Increase the total amount of health you can have at once.", - PD_UPGRADE_HEALTH_REGEN = "Increase the amount of health regenerated when powered per cycle.", - PD_UPGRADE_HEALTH_LOSS = "Decrease the amount of health lost when unpowered per cycle.", - PD_UPGRADE_HEALTH_COST = "Decrease the amount of power required to regenerate per cycle.", - PD_UPGRADE_MAX_CHARGE = "Increase the total amount of charge you can have at once." - ) - -/datum/spell/pulse_demon/open_upgrades/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/pulse_demon/open_upgrades/proc/calc_cost(mob/living/simple_animal/demon/pulse_demon/user, upgrade) - var/cost - switch(upgrade) - if(PD_UPGRADE_HIJACK_SPEED) - if(user.hijack_time <= 1 SECONDS) - return -1 - cost = (100 / (user.hijack_time / (1 SECONDS))) * 20 KJ - if(PD_UPGRADE_DRAIN_SPEED) - if(user.max_drain_rate >= 500 KJ) - return -1 - cost = user.max_drain_rate * 15 - if(PD_UPGRADE_MAX_HEALTH) - if(user.maxHealth >= 200) - return -1 - cost = user.maxHealth * 5 KJ - if(PD_UPGRADE_HEALTH_REGEN) - if(user.health_regen_rate >= 100) - return -1 - cost = user.health_regen_rate * 50 KJ - if(PD_UPGRADE_HEALTH_LOSS) - if(user.health_loss_rate <= 1) - return -1 - cost = (100 / user.health_loss_rate) * 20 KJ - if(PD_UPGRADE_HEALTH_COST) - if(user.power_per_regen <= 1) - return -1 - cost = (100 / user.power_per_regen) * 50 KJ - if(PD_UPGRADE_MAX_CHARGE) - cost = user.maxcharge - else - return -1 - return round(cost) - -/datum/spell/pulse_demon/open_upgrades/proc/get_upgrades(mob/living/simple_animal/demon/pulse_demon/user) - var/upgrades = list() - for(var/upgrade in upgrade_icons) - var/cost = calc_cost(user, upgrade) - if(cost == -1) - continue - upgrades["[upgrade] ([format_si_suffix(cost)]W)"] = upgrade_icons[upgrade] - return upgrades - -/datum/spell/pulse_demon/open_upgrades/AltClick(mob/living/simple_animal/demon/pulse_demon/user) - if(!istype(user)) - return - - to_chat(user, "Pulse Demon upgrades:") - for(var/upgrade in upgrade_descs) - var/cost = calc_cost(user, upgrade) - to_chat(user, "[upgrade] ([cost == -1 ? "Fully Upgraded" : "[format_si_suffix(cost)]J"]) - [upgrade_descs[upgrade]]") - -/datum/spell/pulse_demon/open_upgrades/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) - var/upgrades = get_upgrades(user) - if(!length(upgrades)) - to_chat(user, "You have already fully upgraded everything available!") - return FALSE - - var/raw_choice = show_radial_menu(user, user, upgrades, radius = 48) - if(!raw_choice) - return - var/choice = splittext(raw_choice, " ")[1] - - var/cost = calc_cost(user, choice) - if(cost == -1) - return FALSE - if(user.charge < cost) - to_chat(user, "You do not have enough charge to purchase this upgrade!") - return FALSE - - user.adjust_charge(-cost) - switch(choice) - if(PD_UPGRADE_HIJACK_SPEED) - user.hijack_time = max(round(user.hijack_time / 1.5), 1 SECONDS) - to_chat(user, "You have upgraded your [choice], it now takes [user.hijack_time / (1 SECONDS)] second\s to hijack APCs.") - if(PD_UPGRADE_DRAIN_SPEED) - var/old = user.max_drain_rate - user.max_drain_rate = min(round(user.max_drain_rate * 1.5), 500 KJ) - if(user.power_drain_rate == old) - user.power_drain_rate = user.max_drain_rate - to_chat(user, "You have upgraded your [choice], you can now drain [format_si_suffix(user.max_drain_rate)]W.") - if(PD_UPGRADE_MAX_HEALTH) - user.maxHealth = min(round(user.maxHealth * 1.5), 200) - to_chat(user, "You have upgraded your [choice], your max health is now [user.maxHealth].") - if(PD_UPGRADE_HEALTH_REGEN) - user.health_regen_rate = min(round(user.health_regen_rate * 1.5), 100) - to_chat(user, "You have upgraded your [choice], you will now regenerate [user.health_regen_rate] health per cycle when powered.") - if(PD_UPGRADE_HEALTH_LOSS) - user.health_loss_rate = max(round(user.health_loss_rate / 1.5), 1) - to_chat(user, "You have upgraded your [choice], you will now lose [user.health_loss_rate] health per cycle when unpowered.") - if(PD_UPGRADE_HEALTH_COST) - user.power_per_regen = max(round(user.power_per_regen / 1.5), 1) - to_chat(user, "You have upgraded your [choice], it now takes [format_si_suffix(user.power_per_regen)]W of power to regenerate health.") - to_chat(user, "Additionally, if you enable draining while on a cable, any excess power that would've been used regenerating will be added to your charge.") - if(PD_UPGRADE_MAX_CHARGE) - user.maxcharge = round(user.maxcharge * 2) - to_chat(user, "You have upgraded your [choice], you can now store [format_si_suffix(user.maxcharge)]J of energy.") - else - return FALSE - return TRUE - - -#undef PULSEDEMON_REMOTE_DRAIN_MULTIPLIER -#undef PD_UPGRADE_HIJACK_SPEED -#undef PD_UPGRADE_DRAIN_SPEED -#undef PD_UPGRADE_HEALTH_LOSS -#undef PD_UPGRADE_HEALTH_REGEN -#undef PD_UPGRADE_MAX_HEALTH -#undef PD_UPGRADE_HEALTH_COST -#undef PD_UPGRADE_MAX_CHARGE diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm deleted file mode 100644 index 3719b54a9881f..0000000000000 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ /dev/null @@ -1,368 +0,0 @@ -//Revenants: based off of wraiths from Goon -//"Ghosts" that are invisible and move like ghosts, cannot take damage while invsible -//Wreck havoc with haunting themed abilities -//Admin-spawn or random event - -#define INVISIBILITY_REVENANT 45 -#define REVENANT_NAME_FILE "revenant_names.json" - -/mob/living/simple_animal/revenant - name = "revenant" //The name shown on examine - real_name = "revenant" //The name shown in dchat - desc = "A malevolent spirit." - icon = 'icons/mob/mob.dmi' - icon_state = "revenant_idle" - - mob_biotypes = MOB_SPIRIT - incorporeal_move = INCORPOREAL_MOVE_HOLY_BLOCK - see_invisible = INVISIBILITY_REVENANT - invisibility = INVISIBILITY_REVENANT - health = INFINITY //Revenants don't use health, they use essence instead - maxHealth = INFINITY - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - response_help = "passes through" - response_disarm = "swings at" - response_harm = "punches" - unsuitable_atmos_damage = 0 - minbodytemp = 0 - maxbodytemp = INFINITY - harm_intent_damage = 0 - friendly = "touches" - status_flags = 0 - wander = FALSE - density = FALSE - move_resist = INFINITY - mob_size = MOB_SIZE_TINY - pass_flags = PASSTABLE | PASSGRILLE | PASSMOB - 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) - initial_traits = list(TRAIT_FLYING) - - /// The revenant's idle icon - var/icon_idle = "revenant_idle" - /// The revenant's revealed icon - var/icon_reveal = "revenant_revealed" - /// The revenant's stunned icon - var/icon_stun = "revenant_stun" - /// The revant's icon while draining mobs - var/icon_drain = "revenant_draining" - - ///The resource of revenants. Max health is equal to three times this amount - var/essence = 75 - ///The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount. - var/essence_regen_cap = 75 - ///If the revenant regenerates essence or not; 1 for yes, 0 for no - var/essence_regenerating = TRUE - ///How much essence regenerates - var/essence_regen_amount = 5 - ///How much essence the revenant has stolen - var/essence_accumulated = 0 - ///If the revenant can take damage from normal sources. - var/revealed = FALSE - ///How long the revenant is revealed for, is about 2 seconds times this var. - var/unreveal_time = 0 - ///How long the revenant is stunned for, is about 2 seconds times this var. - var/unstun_time = 0 - ///If the revenant's abilities are blocked by a chaplain's power. - var/inhibited = FALSE - ///How much essence the revenant has drained. - var/essence_drained = 0 - ///If the revenant is draining someone. - var/draining = FALSE - /// contains a list of UIDs of mobs who have been drained. cannot drain the same mob twice. - var/list/drained_mobs = list() - ///How many perfect, regen-cap increasing souls the revenant has. - var/perfectsouls = 0 - -/mob/living/simple_animal/revenant/Life(seconds, times_fired) - ..() - if(revealed && essence <= 0) - death() - if(essence_regenerating && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate - essence = min(essence_regen_cap, essence+essence_regen_amount) - if(unreveal_time && world.time >= unreveal_time) - unreveal_time = 0 - revealed = FALSE - incorporeal_move = INCORPOREAL_MOVE_HOLY_BLOCK - invisibility = INVISIBILITY_REVENANT - to_chat(src, "You are once more concealed.") - if(unstun_time && world.time >= unstun_time) - unstun_time = 0 - notransform = FALSE - to_chat(src, "You can move again!") - update_spooky_icon() - -/mob/living/simple_animal/revenant/ex_act(severity) - return TRUE //Immune to the effects of explosions. - -/mob/living/simple_animal/revenant/blob_act(obj/structure/blob/B) - return //blah blah blobs aren't in tune with the spirit world, or something. - -/mob/living/simple_animal/revenant/singularity_act() - return //don't walk into the singularity expecting to find corpses, okay? - -/mob/living/simple_animal/revenant/narsie_act() - return //most humans will now be either bones or harvesters, but we're still un-alive. - -/mob/living/simple_animal/revenant/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE) - return FALSE //You are a ghost, atmos and grill makes sparks, and you make your own shocks with lights. - -/mob/living/simple_animal/revenant/adjustHealth(amount, updating_health = TRUE) - if(!revealed) - return - essence = max(0, essence-amount) - if(!essence) - to_chat(src, "You feel your essence fraying!") - -/mob/living/simple_animal/revenant/say(message) - if(!message) - return - log_say(message, src) - if(copytext(message, 1, 2) == "*") - return emote(copytext(message, 2), intentional = TRUE) - - say_dead(message) - -/mob/living/simple_animal/revenant/get_status_tab_items() - var/list/status_tab_data = ..() - . = status_tab_data - status_tab_data[++status_tab_data.len] = list("Current essence:", "[essence]/[essence_regen_cap]E") - status_tab_data[++status_tab_data.len] = list("Stolen essence:", "[essence_accumulated]E") - status_tab_data[++status_tab_data.len] = list("Stolen perfect souls:", "[perfectsouls]") - -/mob/living/simple_animal/revenant/New() - ..() - flags_2 |= RAD_NO_CONTAMINATE_2 - remove_from_all_data_huds() - random_revenant_name() - - addtimer(CALLBACK(src, PROC_REF(firstSetupAttempt)), 15 SECONDS) // Give admin 15 seconds to put in a ghost (Or wait 15 seconds before giving it objectives) - -/mob/living/simple_animal/revenant/proc/random_revenant_name() - var/built_name = "" - built_name += pick(strings(REVENANT_NAME_FILE, "spirit_type")) - built_name += " of " - built_name += pick(strings(REVENANT_NAME_FILE, "adjective")) - built_name += pick(strings(REVENANT_NAME_FILE, "theme")) - name = built_name - real_name = built_name - -/mob/living/simple_animal/revenant/proc/firstSetupAttempt() - if(mind) - giveObjectivesandGoals() - giveSpells() - else - message_admins("Revenant was created but has no mind. Put a ghost inside, or a poll will be made in one minute.") - addtimer(CALLBACK(src, PROC_REF(setupOrDelete)), 1 MINUTES) - -/mob/living/simple_animal/revenant/proc/setupOrDelete() - if(mind) - giveObjectivesandGoals() - giveSpells() - else - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as a revenant?", poll_time = 15 SECONDS, source = /mob/living/simple_animal/revenant) - var/mob/dead/observer/theghost = null - if(length(candidates)) - theghost = pick(candidates) - message_admins("[key_name_admin(theghost)] has taken control of a revenant created without a mind") - key = theghost.key - giveObjectivesandGoals() - giveSpells() - dust_if_respawnable(theghost) - else - message_admins("No ghost was willing to take control of a mindless revenant. Deleting...") - qdel(src) - -/mob/living/simple_animal/revenant/proc/giveObjectivesandGoals() - mind.wipe_memory() // someone kill this and give revenants their own minds please - SEND_SOUND(src, sound('sound/effects/ghost.ogg')) - var/list/messages = list() - messages.Add("You are a revenant.") - messages.Add("Your formerly mundane spirit has been infused with alien energies and empowered into a revenant.") - messages.Add("You are not dead, not alive, but somewhere in between. You are capable of limited interaction with both worlds.") - messages.Add("You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.") - messages.Add("To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities.") - messages.Add("You do not remember anything of your past lives, nor will you remember anything about this one after your death.") - messages.Add("For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Revenant)") - - SSticker.mode.traitors |= mind //Necessary for announcing - mind.add_mind_objective(/datum/objective/revenant) - mind.add_mind_objective(/datum/objective/revenant_fluff) - messages.Add(mind.prepare_announce_objectives(FALSE)) - to_chat(src, chat_box_red(messages.Join("
    "))) - -/mob/living/simple_animal/revenant/proc/giveSpells() - mind.AddSpell(new /datum/spell/night_vision/revenant(null)) - mind.AddSpell(new /datum/spell/revenant_transmit(null)) - mind.AddSpell(new /datum/spell/aoe/revenant/defile(null)) - mind.AddSpell(new /datum/spell/aoe/revenant/malfunction(null)) - mind.AddSpell(new /datum/spell/aoe/revenant/overload(null)) - mind.AddSpell(new /datum/spell/aoe/revenant/haunt_object(null)) - mind.AddSpell(new /datum/spell/aoe/revenant/hallucinations(null)) - return TRUE - -/mob/living/simple_animal/revenant/dust() - return death() - -/mob/living/simple_animal/revenant/gib() - return death() - -/mob/living/simple_animal/revenant/death() - if(!revealed) - return FALSE - // Only execute the below if we successfully died - . = ..() - if(!.) - return FALSE - - to_chat(src, "NO! No... it's too late, you can feel your essence breaking apart...") - notransform = TRUE - revealed = TRUE - invisibility = 0 - playsound(src, 'sound/effects/screech.ogg', 100, TRUE) - visible_message("[src] lets out a waning screech as violet mist swirls around its dissolving body!") - icon_state = "revenant_draining" - animate(src, alpha = 0, time = 3 SECONDS) - visible_message("[src]'s body breaks apart into a fine pile of blue dust.") - new /obj/item/ectoplasm(get_turf(src)) - ghostize() - qdel(src) - -/mob/living/simple_animal/revenant/attackby__legacy__attackchain(obj/item/W, mob/living/user, params) - if(istype(W, /obj/item/nullrod)) - visible_message("[src] violently flinches!", \ - "As \the [W] passes through you, you feel your essence draining away!") - adjustBruteLoss(25) //hella effective - inhibited = TRUE - spawn(30) - inhibited = FALSE - - ..() - -/mob/living/simple_animal/revenant/proc/castcheck(essence_cost) - if(holy_check(src)) - return - var/turf/T = get_turf(src) - if(iswallturf(T)) - to_chat(src, "You cannot use abilities from inside of a wall.") - return FALSE - if(inhibited) - to_chat(src, "Your powers have been suppressed by nulling energy!") - return FALSE - if(!change_essence_amount(essence_cost, 1)) - to_chat(src, "You lack the essence to use that ability.") - return FALSE - return TRUE - -/mob/living/simple_animal/revenant/proc/change_essence_amount(essence_amt, silent = FALSE, source) - if(essence + essence_amt <= 0) - return - essence = max(0, essence + essence_amt) - if(essence_amt > 0) - essence_accumulated = max(0, essence_accumulated + essence_amt) - if(!silent) - if(essence_amt > 0) - to_chat(src, "Gained [essence_amt]E from [source].") - else - to_chat(src, "Lost [essence_amt]E from [source].") - return TRUE - -/mob/living/simple_animal/revenant/proc/reveal(time) - if(time <= 0) - return - revealed = TRUE - invisibility = 0 - incorporeal_move = NO_INCORPOREAL_MOVE - if(!unreveal_time) - to_chat(src, "You have been revealed!") - unreveal_time = world.time + time - else - to_chat(src, "You have been revealed!") - unreveal_time = unreveal_time + time - update_spooky_icon() - -/mob/living/simple_animal/revenant/proc/stun(time) - if(time <= 0) - return - notransform = TRUE - if(!unstun_time) - to_chat(src, "You cannot move!") - unstun_time = world.time + time - else - to_chat(src, "You cannot move!") - unstun_time = unstun_time + time - update_spooky_icon() - -/mob/living/simple_animal/revenant/proc/update_spooky_icon() - if(!revealed) - icon_state = icon_idle - return - - if(!notransform) - icon_state = icon_reveal - return - - if(draining) - icon_state = icon_drain - return - // No other state is happening, therefore we are stunned - icon_state = icon_stun - - -/datum/objective/revenant - needs_target = FALSE - var/targetAmount = 100 - -/datum/objective/revenant/New() - targetAmount = rand(350, 600) - explanation_text = "Absorb [targetAmount] points of essence from humans." - ..() - -/datum/objective/revenant/check_completion() - var/total_essence = 0 - for(var/datum/mind/M in get_owners()) - if(!istype(M.current, /mob/living/simple_animal/revenant) || QDELETED(M.current)) - continue - var/mob/living/simple_animal/revenant/R = M.current - total_essence += R.essence_accumulated - if(total_essence < targetAmount) - return FALSE - return TRUE - -/datum/objective/revenant_fluff - needs_target = FALSE - -/datum/objective/revenant_fluff/New() - var/list/explanationTexts = list("Assist and exacerbate existing threats at critical moments.", \ - "Cause as much chaos and anger as you can without being killed.", \ - "Damage and render as much of the station rusted and unusable as possible.", \ - "Disable and cause malfunctions in as many machines as possible.", \ - "Ensure that any holy weapons are rendered unusable.", \ - "Hinder the crew while attempting to avoid being noticed.", \ - "Make the crew as miserable as possible.", \ - "Make the clown as miserable as possible.", \ - "Make the captain as miserable as possible.", \ - "Make the AI as miserable as possible.", \ - "Annoy the ones that insult you the most.", \ - "Whisper ghost jokes into peoples heads.", \ - "Help the crew in critical situations, but take your payments in souls.", \ - "Prevent the use of energy weapons where possible.") - explanation_text = pick(explanationTexts) - ..() - -/datum/objective/revenant_fluff/check_completion() - return TRUE - -/obj/item/ectoplasm - name = "glimmering residue" - desc = "A pile of fine blue dust. Small tendrils of violet mist swirl around it." - icon = 'icons/effects/effects.dmi' - icon_state = "revenantEctoplasm" - w_class = WEIGHT_CLASS_SMALL - -/obj/item/ectoplasm/examine(mob/user) - . = ..() - . += "Lifeless ectoplasm, still faintly glimmering in the light. From what was once a spirit seeking revenge on the station." - -#undef INVISIBILITY_REVENANT -#undef REVENANT_NAME_FILE diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm deleted file mode 100644 index 4fae962fa5136..0000000000000 --- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm +++ /dev/null @@ -1,548 +0,0 @@ -///Harvest -/mob/living/simple_animal/revenant/ClickOn(atom/A, params) //Copypaste from ghost code - revenants can't interact with the world directly. - - if(client.click_intercept) - client.click_intercept.InterceptClickOn(src, params, A) - return - - var/list/modifiers = params2list(params) - if(modifiers["middle"]) - MiddleClickOn(A) - return - if(modifiers["middle"] && modifiers["shift"] && modifiers["ctrl"]) - MiddleShiftControlClickOn(A) - return - if(modifiers["middle"] && modifiers["shift"]) - MiddleShiftClickOn(A) - return - if(modifiers["shift"] && modifiers["ctrl"]) - CtrlShiftClickOn(A) - return - if(modifiers["shift"] && modifiers["alt"]) - AltShiftClickOn(A) - return - if(modifiers["shift"]) - ShiftClickOn(A) - return - if(modifiers["alt"]) - AltClickOn(A) - return - if(modifiers["ctrl"]) - CtrlClickOn(A) - return - - if(world.time <= next_move) - return - A.attack_ghost(src) - if(ishuman(A) && in_range(src, A)) - if(isLivingSSD(A) && client.send_ssd_warning(A)) //Do NOT Harvest SSD people unless you accept the warning - return - Harvest(A) - -/mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/target) - if(!castcheck(0)) - return - if(draining) - to_chat(src, "You are already siphoning the essence of a soul!") - return - var/mob_UID = target.UID() - if(mob_UID in drained_mobs) - to_chat(src, "[target]'s soul is dead and empty.") - return - if(!target.stat) - to_chat(src, "This being's soul is too strong to harvest.") - if(prob(10)) - to_chat(target, "You feel as if you are being watched.") - return - draining = TRUE - essence_drained = rand(15, 20) - to_chat(src, "You search for the soul of [target].") - if(do_after(src, 10, 0, target = target)) //did they get deleted in that second? - if(target.ckey) - to_chat(src, "Their soul burns with intelligence.") - essence_drained += rand(20, 30) - if(target.stat != DEAD) - to_chat(src, "Their soul blazes with life!") - essence_drained += rand(40, 50) - else - to_chat(src, "Their soul is weak and faltering.") - if(do_after(src, 20, 0, target = 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.") - if(30 to 70) - to_chat(src, "[target] will yield an average amount of essence.") - if(70 to 90) - 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, 20, 0, target = target)) //how about now - if(!target.stat) - to_chat(src, "They are now powerful enough to fight off your draining.") - to_chat(target, "You feel something tugging across your body before subsiding.") - draining = FALSE - return //hey, wait a minute... - to_chat(src, "You begin siphoning essence from [target]'s soul.") - if(target.stat != DEAD) - to_chat(target, "You feel a horribly unpleasant draining sensation as your grip on life weakens...") - icon_state = "revenant_draining" - reveal(27) - stun(27) - target.visible_message("[target] suddenly rises slightly into the air, [target.p_their()] skin turning an ashy gray.") - target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=26) - if(do_after(src, 30, 0, 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, 0, target) - if(essence_drained > 90) - essence_regen_cap += 25 - perfectsouls += 1 - to_chat(src, "The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap].") - to_chat(src, "[target]'s soul has been considerably weakened and will yield no more essence for the time being.") - target.visible_message("[target] slumps onto the ground.", \ - "Violets lights, dancing in your vision, getting clo--") - drained_mobs.Add(mob_UID) - add_attack_logs(src, target, "revenant harvested soul") - target.death() - else - to_chat(src, "[target ? "[target] has":"They have"] been drawn out of your grasp. The link has been broken.") - draining = 0 - essence_drained = 0 - if(target) //Wait, target is WHERE NOW? - target.visible_message("[target] slumps onto the ground.", \ - "Violets lights, dancing in your vision, receding--") - return - else - to_chat(src, "You are not close enough to siphon [target ? "[target]'s":"their"] soul. The link has been broken.") - draining = FALSE - essence_drained = 0 - return - draining = FALSE - essence_drained = 0 - return - -//Toggle night vision: lets the revenant toggle its night vision -/datum/spell/night_vision/revenant - base_cooldown = 0 - message = "You toggle your night vision." - action_icon_state = "r_nightvision" - action_background_icon_state = "bg_revenant" - -//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob -/datum/spell/revenant_transmit - name = "Transmit" - desc = "Telepathically transmits a message to the target." - base_cooldown = 0 - clothes_req = FALSE - action_icon_state = "r_transmit" - action_background_icon_state = "bg_revenant" - antimagic_flags = MAGIC_RESISTANCE_HOLY|MAGIC_RESISTANCE_MIND - -/datum/spell/revenant_transmit/create_new_targeting() - var/datum/spell_targeting/targeted/T = new() - T.allowed_type = /mob/living - return T - -/datum/spell/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr) - for(var/mob/living/M in targets) - spawn(0) - var/msg = tgui_input_text(user, "What do you wish to tell [M]?", "Transmit") - if(!msg) - cooldown_handler.revert_cast() - return - log_say("(REVENANT to [key_name(M)]) [msg]", user) - to_chat(user, "You transmit to [M]: [msg]") - to_chat(M, "An alien voice resonates from all around... [msg]") - -/datum/spell/aoe/revenant - name = "Spell" - clothes_req = FALSE - action_background_icon_state = "bg_revenant" - /// How long it reveals the revenant in deciseconds - var/reveal = 8 SECONDS - /// How long it stuns the revenant in deciseconds - var/stun = 2 SECONDS - /// If it's locked and needs to be unlocked before use - var/locked = TRUE - /// How much essence it costs to unlock - var/unlock_amount = 100 - /// How much essence it costs to use - var/cast_amount = 50 - antimagic_flags = MAGIC_RESISTANCE_HOLY - -/datum/spell/aoe/revenant/New() - ..() - if(locked) - name = "[initial(name)] ([unlock_amount]E)" - else - name = "[initial(name)] ([cast_amount]E)" - action.name = name - action.desc = desc - action.UpdateButtons() - -/datum/spell/aoe/revenant/revert_cast(mob/user) - . = ..() - to_chat(user, "Your ability wavers and fails!") - var/mob/living/simple_animal/revenant/R = user - R?.essence += cast_amount //refund the spell and reset - -/datum/spell/aoe/revenant/can_cast(mob/living/simple_animal/revenant/user = usr, charge_check = TRUE, show_message = FALSE) - if(user.inhibited) - return FALSE - if(cooldown_handler.is_on_cooldown()) - return FALSE - if(locked) - if(user.essence <= unlock_amount) - return FALSE - if(user.essence <= cast_amount) - return FALSE - return TRUE - -/datum/spell/aoe/revenant/proc/attempt_cast(mob/living/simple_animal/revenant/user = usr) - if(locked) - if(!user.castcheck(-unlock_amount)) - cooldown_handler.revert_cast() - return FALSE - name = "[initial(name)] ([cast_amount]E)" - to_chat(user, "You have unlocked [initial(name)]!") - locked = FALSE - cooldown_handler.revert_cast() - return FALSE - if(!user.castcheck(-cast_amount)) - cooldown_handler.revert_cast() - return FALSE - name = "[initial(name)] ([cast_amount]E)" - user.reveal(reveal) - user.stun(stun) - if(action) - action.UpdateButtons() - return TRUE - -//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people. -/datum/spell/aoe/revenant/overload - name = "Overload Lights" - desc = "Directs a large amount of essence into nearby electrical lights, causing lights to shock those nearby." - base_cooldown = 20 SECONDS - stun = 3 SECONDS - cast_amount = 45 - var/shock_range = 2 - var/shock_damage = 40 - action_icon_state = "overload_lights" - aoe_range = 5 - -/datum/spell/aoe/revenant/overload/create_new_targeting() - var/datum/spell_targeting/aoe/targeting = new() - targeting.range = aoe_range - targeting.allowed_type = /obj/machinery/light - return targeting - -/datum/spell/aoe/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr) - if(attempt_cast(user)) - for(var/obj/machinery/light/L as anything in targets) - INVOKE_ASYNC(src, PROC_REF(shock_lights), L, user) - -/datum/spell/aoe/revenant/overload/proc/shock_lights(obj/machinery/light/L, mob/living/simple_animal/revenant/user) - if(!L.on) - return - L.visible_message("\The [L] suddenly flares brightly and begins to spark!") - do_sparks(4, 0, L) - new /obj/effect/temp_visual/revenant(L.loc) - sleep(2 SECONDS) - if(!L.on) //wait, wait, don't shock me - return - flick("[L.base_state]2", L) - for(var/mob/living/M in view(shock_range, L)) - if(M == user) - continue - M.Beam(L, icon_state = "purple_lightning", icon = 'icons/effects/effects.dmi', time = 0.5 SECONDS) - M.electrocute_act(shock_damage, L, flags = SHOCK_NOGLOVES) - M.Stun(3 SECONDS) - do_sparks(4, 0, M) - playsound(M, 'sound/machines/defib_zap.ogg', 50, TRUE, -1) - -//Defile: Corrupts nearby stuff, unblesses floor tiles. -/datum/spell/aoe/revenant/defile - name = "Defile" - desc = "Twists and corrupts the nearby area as well as dispelling holy auras on floors." - base_cooldown = 15 SECONDS - stun = 1 SECONDS - reveal = 4 SECONDS - unlock_amount = 75 - cast_amount = 30 - action_icon_state = "defile" - aoe_range = 4 - -/datum/spell/aoe/revenant/defile/create_new_targeting() - var/datum/spell_targeting/aoe/turf/targeting = new() - targeting.range = aoe_range - return targeting - -/datum/spell/aoe/revenant/defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr) - if(!attempt_cast(user)) - return - for(var/turf/T in targets) - T.defile() - for(var/atom/A in T.contents) - A.defile() - -//Malfunction: Makes bad stuff happen to robots and machines. -/datum/spell/aoe/revenant/malfunction - name = "Malfunction" - desc = "Corrupts and damages nearby machines and mechanical objects." - base_cooldown = 200 - cast_amount = 45 - unlock_amount = 150 - action_icon_state = "malfunction" - aoe_range = 2 - -/datum/spell/aoe/revenant/malfunction/create_new_targeting() - var/datum/spell_targeting/aoe/turf/targeting = new() - targeting.range = aoe_range - return targeting - -//A note to future coders: do not replace this with an EMP because it will wreck malf AIs and gang dominators and everyone will hate you. -/datum/spell/aoe/revenant/malfunction/cast(list/targets, mob/living/simple_animal/revenant/user = usr) - if(attempt_cast(user)) - for(var/turf/T in targets) - INVOKE_ASYNC(src, PROC_REF(effect), user, T) - -/datum/spell/aoe/revenant/malfunction/proc/effect(mob/living/simple_animal/revenant/user, turf/T) - T.rev_malfunction(TRUE) - for(var/atom/A in T.contents) - A.rev_malfunction(TRUE) - -/** - * Makes objects be haunted and then throws them at conscious people to do damage, spooky! - */ -/datum/spell/aoe/revenant/haunt_object - name = "Haunt Objects" - desc = "Empower nearby objects to you with ghostly energy, causing them to attack nearby mortals. \ - Items closer to you are more likely to be haunted." - action_icon_state = "haunt" - base_cooldown = 60 SECONDS - unlock_amount = 150 - cast_amount = 50 - stun = 3 SECONDS - reveal = 10 SECONDS - aoe_range = 7 - /// The maximum number of objects to haunt - var/max_targets = 7 - /// A list of all attack timers started by this spell being cast - var/list/attack_timers = list() - -/datum/spell/aoe/revenant/haunt_object/create_new_targeting() - var/datum/spell_targeting/aoe/targeting = new() - targeting.range = aoe_range - targeting.allowed_type = /obj/item - return targeting - -/datum/spell/aoe/revenant/haunt_object/cast(list/targets, mob/living/simple_animal/revenant/user = usr) - if(!attempt_cast(user)) - return - - var/successes = 0 - for(var/obj/item/nearby_item as anything in targets) - if(successes >= max_targets) // End loop if we've already got 7 spooky items - break - - // Don't throw around anchored things or dense things - // (Or things not on a turf but I am not sure if range can catch that) - if(nearby_item.anchored || nearby_item.density || nearby_item.move_resist == INFINITY || !isturf(nearby_item.loc)) - continue - // Don't throw abstract things - if(nearby_item.flags & ABSTRACT) - continue - // Don't throw things we can't see - if(nearby_item.invisibility > user.see_invisible) - continue - - var/distance_from_user = max(get_dist(get_turf(nearby_item), get_turf(user)), 1) // get_dist() for same tile dists return -1, we do not want that - var/chance_of_haunting = 150 / distance_from_user // The further away things are, the less likely they are to be picked - if(!prob(chance_of_haunting)) - continue - - make_spooky(nearby_item, user) - successes++ - - if(!successes) //no items to throw - revert_cast() - return - - // Stop the looping attacks after 65 seconds, roughly 14 attack cycles depending on lag - addtimer(CALLBACK(src, PROC_REF(stop_timers)), 65 SECONDS, TIMER_UNIQUE) - -/// Handles making an object haunted and setting it up to attack -/datum/spell/aoe/revenant/haunt_object/proc/make_spooky(obj/item/item_to_possess, mob/living/simple_animal/revenant/user) - new /obj/effect/temp_visual/revenant(get_turf(item_to_possess)) // Thematic spooky visuals - var/mob/living/simple_animal/possessed_object/possessed_object = new(item_to_possess) // Begin haunting object - item_to_possess.throwforce = min(item_to_possess.throwforce + 5, 15) // Damage it should do? throwforce+5 or 15, whichever is lower - set_outline(possessed_object) - possessed_object.maxHealth = 100 // Double the regular HP of possessed objects - possessed_object.health = 100 - possessed_object.escape_chance = 100 // We cannot be contained - ADD_TRAIT(possessed_object, TRAIT_DODGE_ALL_OBJECTS, "Revenant") - - addtimer(CALLBACK(src, PROC_REF(attack__legacy__attackchain), possessed_object, user), 1 SECONDS, TIMER_UNIQUE) // Short warm-up for floaty ambience - attack_timers.Add(addtimer(CALLBACK(src, PROC_REF(attack__legacy__attackchain), possessed_object, user), 4 SECONDS, TIMER_UNIQUE|TIMER_LOOP|TIMER_STOPPABLE)) // 5 second looping attacks - addtimer(CALLBACK(possessed_object, TYPE_PROC_REF(/mob/living/simple_animal/possessed_object, death)), 70 SECONDS, TIMER_UNIQUE) // De-haunt the object - -/// Handles finding a valid target and throwing us at it -/datum/spell/aoe/revenant/haunt_object/proc/attack__legacy__attackchain(mob/living/simple_animal/possessed_object/possessed_object, mob/living/simple_animal/revenant/user) - var/list/potential_victims = list() - for(var/turf/turf_to_search in spiral_range_turfs(aoe_range, get_turf(possessed_object))) - for(var/mob/living/carbon/potential_victim in turf_to_search) - if(QDELETED(possessed_object) || !can_see(possessed_object, potential_victim, aoe_range)) // You can't see me - continue - if(potential_victim.stat != CONSCIOUS) // Don't kill our precious essence-filled sleepy mobs - continue - potential_victims.Add(potential_victim) - - potential_victims.Cut((length(potential_victims) * 0.8) + 1.2) // Only consider the people near us - - if(!length(potential_victims)) - possessed_object.possessed_item.throwforce = min(possessed_object.possessed_item.throwforce + 5, 15) // If an item is stood still for a while it can gather power - set_outline(possessed_object) - return - - var/mob/living/carbon/victim = pick(potential_victims) - possessed_object.throw_at(victim, aoe_range, 2, user, dodgeable = FALSE) - -/// Sets the glow on the haunted object, scales up based on throwforce -/datum/spell/aoe/revenant/haunt_object/proc/set_outline(mob/living/simple_animal/possessed_object/possessed_object) - possessed_object.remove_filter("haunt_glow") - var/outline_size = min((possessed_object.possessed_item.throwforce / 15) * 3, 3) - possessed_object.add_filter("haunt_glow", 2, list("type" = "outline", "color" = "#7A4FA9", "size" = outline_size)) // Give it spooky purple outline - -/// Stop all attack timers cast by the previous spell use -/datum/spell/aoe/revenant/haunt_object/proc/stop_timers() - for(var/I in attack_timers) - deltimer(I) - -/** - * Gives everyone in a 7 tile radius 2 minutes of hallucinations - */ -/datum/spell/aoe/revenant/hallucinations - name = "Hallucination Aura" - desc = "Toy with the living nearby, giving them glimpses of things that could be or once were." - action_icon_state = "hallucinations" - base_cooldown = 15 SECONDS - unlock_amount = 50 - cast_amount = 25 - stun = 1 SECONDS - reveal = 3 SECONDS - -/datum/spell/aoe/revenant/hallucinations/create_new_targeting() - var/datum/spell_targeting/aoe/targeting = new() - targeting.range = aoe_range - targeting.allowed_type = /mob/living/carbon - return targeting - -/datum/spell/aoe/revenant/hallucinations/cast(list/targets, mob/living/simple_animal/revenant/user = usr) - if(!attempt_cast(user)) - return - - for(var/mob/living/carbon/M as anything in targets) - M.AdjustHallucinate(120 SECONDS, bound_upper = 300 SECONDS) //Lets not let them get more than 5 minutes of hallucinations - new /obj/effect/temp_visual/revenant(get_turf(M)) - -/// Begin defile and malfunction on-atom definitions - -/atom/proc/defile() - return - -/atom/proc/rev_malfunction(cause_emp = TRUE) - return - -/mob/living/carbon/human/rev_malfunction(cause_emp = TRUE) - to_chat(src, "You feel [pick("your sense of direction flicker out", "a stabbing pain in your head", "your mind fill with static")].") - new /obj/effect/temp_visual/revenant(loc) - if(cause_emp) - emp_act(EMP_HEAVY) - -/mob/living/simple_animal/bot/rev_malfunction(cause_emp = TRUE) - if(!emagged) - new /obj/effect/temp_visual/revenant(loc) - locked = FALSE - open = TRUE - emag_act(usr) - -/obj/rev_malfunction(cause_emp = TRUE) - if(prob(20)) - if(prob(50)) - new /obj/effect/temp_visual/revenant(loc) - emag_act(usr) - else if(cause_emp) - emp_act(EMP_HEAVY) - -/obj/machinery/clonepod/rev_malfunction(cause_emp = TRUE) - ..(cause_emp = FALSE) - -/obj/machinery/power/apc/rev_malfunction(cause_emp = TRUE) - return - -/obj/machinery/power/smes/rev_malfunction(cause_emp = TRUE) - return - -/mob/living/silicon/robot/rev_malfunction(cause_emp = TRUE) - playsound(src, 'sound/machines/warning-buzzer.ogg', 50, 1) - new /obj/effect/temp_visual/revenant(loc) - spark_system.start() - if(cause_emp) - emp_act(EMP_HEAVY) - -/turf/defile() - if(flags & BLESSED_TILE) - flags &= ~BLESSED_TILE - new /obj/effect/temp_visual/revenant(loc) - -/turf/simulated/wall/defile() - ..() - if(prob(15)) - new/obj/effect/temp_visual/revenant(loc) - magic_rust_turf() - -/turf/simulated/wall/indestructible/defile() - return - -/turf/simulated/wall/r_wall/defile() - ..() - if(prob(15)) - new/obj/effect/temp_visual/revenant(loc) - magic_rust_turf() - -/mob/living/carbon/human/defile() - to_chat(src, "You suddenly feel [pick("sick and tired", "tired and confused", "nauseated", "dizzy")].") - apply_damage(60, STAMINA) - adjustToxLoss(5) - AdjustConfused(40 SECONDS, bound_lower = 0, bound_upper = 60 SECONDS) - new /obj/effect/temp_visual/revenant(loc) - -/obj/structure/window/defile() - take_damage(rand(30,80)) - if(fulltile) - new /obj/effect/temp_visual/revenant/cracks(loc) - -/obj/structure/closet/defile() - open() - -/turf/simulated/floor/defile() - ..() - if(prob(15)) - if(intact && floor_tile) - new floor_tile(src) - broken = FALSE - burnt = FALSE - make_plating(1) - magic_rust_turf() - -/turf/simulated/floor/plating/defile() - magic_rust_turf() - if(flags & BLESSED_TILE) - flags &= ~BLESSED_TILE - new /obj/effect/temp_visual/revenant(loc) - -/turf/simulated/floor/engine/cult/defile() - if(flags & BLESSED_TILE) - flags &= ~BLESSED_TILE - new /obj/effect/temp_visual/revenant(loc) - -/obj/machinery/light/defile() - flicker(30) diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm deleted file mode 100644 index e0ce8b2b03864..0000000000000 --- a/code/game/gamemodes/nuclear/nuclear_challenge.dm +++ /dev/null @@ -1,107 +0,0 @@ -#define CHALLENGE_TELECRYSTALS 1400 -#define CHALLENGE_TIME_LIMIT 10 MINUTES -#define CHALLENGE_SCALE_PLAYER 1 // How many player per scaling bonus -#define CHALLENGE_SCALE_BONUS 10 // How many TC per scaling bonus -#define CHALLENGE_MIN_PLAYERS 30 -#define CHALLENGE_SHUTTLE_DELAY 30 MINUTES // So the ops have at least 10 minutes before the shuttle is callable. Gives the nuke ops at least 15 minutes before shuttle arrive. - -/obj/item/nuclear_challenge - name = "Declaration of War (Challenge Mode)" - icon = 'icons/obj/device.dmi' - icon_state = "gangtool-red" - item_state = "walkietalkie" - desc = "Use to send a declaration of hostilities to the target, delaying your shuttle departure for 20 minutes while they prepare for your assault. \ - Such a brazen move will attract the attention of powerful benefactors within the Syndicate, who will supply your team with a massive amount of bonus telecrystals. \ - Must be used within ten minutes, or your benefactors will lose interest." - var/declaring_war = FALSE - var/total_tc = 0 //Total amount of telecrystals shared between nuke ops - -/obj/item/nuclear_challenge/attack_self__legacy__attackchain(mob/living/user) - if(!check_allowed(user)) - return - - declaring_war = TRUE - var/are_you_sure = tgui_alert(user, "Consult your team carefully before you declare war on [station_name()]. Are you sure you want to alert the enemy crew? You have [-round((world.time-SSticker.round_start_time - CHALLENGE_TIME_LIMIT)/10)] seconds to decide.", "Declare war?", list("Yes", "No")) - declaring_war = FALSE - - if(!check_allowed(user)) - return - - if(are_you_sure != "Yes") - to_chat(user, "On second thought, the element of surprise isn't so bad after all.") - return - - var/war_declaration = "[user.real_name] has declared [user.p_their()] intent to utterly destroy [station_name()] with a nuclear device, and dares the crew to try and stop them." - - declaring_war = TRUE - var/custom_threat = tgui_alert(user, "Do you want to customize your declaration?", "Customize?", list("Yes", "No")) - declaring_war = FALSE - - if(!check_allowed(user)) - return - - if(custom_threat == "Yes") - declaring_war = TRUE - war_declaration = tgui_input_text(user, "Insert your custom declaration", "Declaration") - declaring_war = FALSE - - if(!check_allowed(user) || !war_declaration) - return - - GLOB.major_announcement.Announce(war_declaration, "Declaration of War", 'sound/effects/siren.ogg', msg_sanitized = TRUE) - addtimer(CALLBACK(SSsecurity_level, TYPE_PROC_REF(/datum/controller/subsystem/security_level, set_level), SEC_LEVEL_GAMMA), 30 SECONDS) - - 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.") - to_chat(user, "Your bonus telecrystals have been split between your team's uplinks.") - - for(var/obj/machinery/computer/shuttle/syndicate/S in GLOB.machines) - S.challenge = TRUE - S.challenge_time = world.time - - // No. of player - Min. Player to dec, divided by player per bonus, then multipled by TC per bonus. Rounded. - total_tc = CHALLENGE_TELECRYSTALS + round(((length(get_living_players(exclude_nonhuman = FALSE, exclude_offstation = TRUE)) - CHALLENGE_MIN_PLAYERS)/CHALLENGE_SCALE_PLAYER) * CHALLENGE_SCALE_BONUS) - share_telecrystals() - SSshuttle.refuel_delay = CHALLENGE_SHUTTLE_DELAY - qdel(src) - -/obj/item/nuclear_challenge/proc/share_telecrystals() - var/player_tc - var/remainder - - player_tc = round(total_tc / length(GLOB.nuclear_uplink_list)) //round to get an integer and not floating point - remainder = total_tc % length(GLOB.nuclear_uplink_list) - - for(var/obj/item/radio/uplink/nuclear/U in GLOB.nuclear_uplink_list) - U.hidden_uplink.uses += player_tc - while(remainder > 0) - for(var/obj/item/radio/uplink/nuclear/U in GLOB.nuclear_uplink_list) - if(remainder <= 0) - break - U.hidden_uplink.uses++ - remainder-- - -/obj/item/nuclear_challenge/proc/check_allowed(mob/living/user) - if(declaring_war) - to_chat(user, "You are already in the process of declaring war! Make your mind up.") - return FALSE - if(length(get_living_players(exclude_nonhuman = FALSE, exclude_offstation = TRUE)) < CHALLENGE_MIN_PLAYERS) - to_chat(user, "The enemy crew is too small to be worth declaring war on.") - return FALSE - if(!is_admin_level(user.z)) - to_chat(user, "You have to be at your base to use this.") - return FALSE - if((world.time - SSticker.round_start_time) > CHALLENGE_TIME_LIMIT) // Only count after the round started - to_chat(user, "It's too late to declare hostilities. Your benefactors are already busy with other schemes. You'll have to make do with what you have on hand.") - return FALSE - for(var/obj/machinery/computer/shuttle/syndicate/S in GLOB.machines) - if(S.moved) - to_chat(user, "The shuttle has already been moved! You have forfeit the right to declare war.") - return FALSE - return TRUE - -#undef CHALLENGE_TIME_LIMIT -#undef CHALLENGE_MIN_PLAYERS -#undef CHALLENGE_SHUTTLE_DELAY -#undef CHALLENGE_TELECRYSTALS -#undef CHALLENGE_SCALE_PLAYER -#undef CHALLENGE_SCALE_BONUS diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm deleted file mode 100644 index c316b9a78cd66..0000000000000 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ /dev/null @@ -1,565 +0,0 @@ -#define MODE_OFF 0 -#define MODE_DISK 1 -#define MODE_NUKE 2 -#define MODE_ADV 3 -#define MODE_SHIP 4 -#define MODE_OPERATIVE 5 -#define MODE_CREW 6 -// #define PINPOINTER_MODE_DET 7 // This mode is not defined here because it is used across multiple files, but it still exists. -#define MODE_TENDRIL 8 -#define SETTING_DISK 0 -#define SETTING_LOCATION 1 -#define SETTING_OBJECT 2 - -/obj/item/pinpointer - name = "pinpointer" - icon = 'icons/obj/device.dmi' - icon_state = "pinoff" - flags = CONDUCT - slot_flags = ITEM_SLOT_PDA | ITEM_SLOT_BELT - w_class = WEIGHT_CLASS_SMALL - item_state = "electronic" - throw_speed = 4 - throw_range = 20 - materials = list(MAT_METAL=500) - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - var/obj/item/disk/nuclear/the_disk = null - var/obj/machinery/nuclearbomb/the_bomb = null - var/obj/machinery/nuclearbomb/syndicate/the_s_bomb = null // used by syndicate pinpointers. - var/cur_index = 1 // Which index the current mode is - var/mode = MODE_OFF // On which mode the pointer is at - var/modes = list(MODE_DISK, MODE_NUKE) // Which modes are there - var/shows_nuke_timer = TRUE - var/syndicate = FALSE // Indicates pointer is syndicate, and points to the syndicate nuke. - var/icon_off = "pinoff" - var/icon_null = "pinonnull" - var/icon_direct = "pinondirect" - var/icon_close = "pinonclose" - var/icon_medium = "pinonmedium" - var/icon_far = "pinonfar" - -/obj/item/pinpointer/New() - ..() - GLOB.pinpointer_list += src - -/obj/item/pinpointer/Destroy() - STOP_PROCESSING(SSfastprocess, src) - GLOB.pinpointer_list -= src - mode = MODE_OFF - the_disk = null - return ..() - -/obj/item/pinpointer/process() - if(mode == MODE_DISK) - workdisk() - else if(mode == MODE_NUKE) - workbomb() - -/obj/item/pinpointer/attack_self__legacy__attackchain(mob/user) - if(mode == PINPOINTER_MODE_DET) - return - cycle(user) - -/obj/item/pinpointer/proc/cycle(mob/user) - if(cur_index > length(modes)) - mode = MODE_OFF - to_chat(user, "You deactivate [src].") - STOP_PROCESSING(SSfastprocess, src) - icon_state = icon_off - cur_index = 1 - return - if(cur_index == 1) - START_PROCESSING(SSfastprocess, src) - mode = modes[cur_index++] - activate_mode(mode, user) - to_chat(user, "[get_mode_text(mode)]") - -/obj/item/pinpointer/proc/get_mode_text(mode) - switch(mode) - if(MODE_DISK) - return "Authentication Disk Locator active." - if(MODE_NUKE) - return "Nuclear Device Locator active." - if(MODE_ADV) - return "Advanced Pinpointer Online." - if(MODE_SHIP) - return "Shuttle Locator active." - if(MODE_OPERATIVE) - return "You point the pinpointer to the nearest operative." - if(MODE_CREW) - return "You turn on the pinpointer." - if(MODE_TENDRIL) - return "High energy scanner active" - -/obj/item/pinpointer/proc/activate_mode(mode, mob/user) //for crew pinpointer - return - -/obj/item/pinpointer/proc/scandisk() - if(!the_disk) - the_disk = locate() in GLOB.nad_list - -/obj/item/pinpointer/proc/scanbomb() - if(!syndicate) - if(!the_bomb) - the_bomb = locate() in GLOB.nuke_list - else - if(!the_s_bomb) - the_s_bomb = locate() in GLOB.syndi_nuke_list - -/obj/item/pinpointer/proc/point_at_target(atom/target) - if(!target) - icon_state = icon_null - return - - var/turf/T = get_turf(target) - var/turf/L = get_turf(src) - - if(!(T && L) || (T.z != L.z)) - icon_state = icon_null - else - dir = get_dir(L, T) - switch(get_dist(L, T)) - if(-1) - icon_state = icon_direct - if(1 to 8) - icon_state = icon_close - if(9 to 16) - icon_state = icon_medium - if(16 to INFINITY) - icon_state = icon_far - -/obj/item/pinpointer/proc/workdisk() - scandisk() - point_at_target(the_disk) - -/obj/item/pinpointer/proc/workbomb() - if(!syndicate) - scanbomb() - point_at_target(the_bomb) - else - scanbomb() - point_at_target(the_s_bomb) - -/obj/item/pinpointer/examine(mob/user) - . = ..() - if(shows_nuke_timer) - for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines) - if(bomb.timing) - . += "Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]" - -/obj/item/pinpointer/advpinpointer - name = "advanced pinpointer" - desc = "A larger version of the normal pinpointer, this unit features a helpful quantum entanglement detection system to locate various objects that do not broadcast a locator signal. \n \ - Alt-click to toggle mode." - modes = list(MODE_ADV) - var/modelocked = FALSE // If true, user cannot change mode. - var/turf/location = null - var/obj/target = null - var/setting = 0 - -/obj/item/pinpointer/advpinpointer/process() - switch(setting) - if(SETTING_DISK) - workdisk() - if(SETTING_LOCATION) - point_at_target(location) - if(SETTING_OBJECT) - point_at_target(target) - -/obj/item/pinpointer/advpinpointer/workdisk() //since mode works diffrently for advpinpointer - scandisk() - point_at_target(the_disk) - -/obj/item/pinpointer/advpinpointer/AltClick(mob/user) - if(!isliving(user) || !Adjacent(user)) - return ..() - toggle_mode(user) - -/obj/item/pinpointer/advpinpointer/proc/toggle_mode(mob/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) - return - - if(modelocked) - to_chat(user, "[src] is locked. It can only track one specific target.") - return - - target = null - location = null - - switch(tgui_alert(user, "Please select the mode you want to put the pinpointer in.", "Pinpointer Mode Select", list("Location", "Disk Recovery", "Other Signature"))) - if("Location") - setting = SETTING_LOCATION - - var/locationx = input(user, "Please input the x coordinate to search for.", "Location?" , "") as num - if(!locationx || !(user in view(1,src))) - return - var/locationy = input(user, "Please input the y coordinate to search for.", "Location?" , "") as num - if(!locationy || !(user in view(1,src))) - return - - var/turf/Z = get_turf(src) - - location = locate(locationx,locationy,Z.z) - - to_chat(user, "You set the pinpointer to locate [locationx],[locationy]") - - toggle_on() - - if("Disk Recovery") - setting = SETTING_DISK - toggle_on() - - if("Other Signature") - setting = SETTING_OBJECT - switch(tgui_alert(user, "Search for item signature or DNA fragment?", "Signature Mode Select", list("Item", "DNA"))) - if("Item") - var/list/item_names[0] - var/list/item_paths[0] - for(var/objective in GLOB.potential_theft_objectives) - var/datum/theft_objective/T = objective - var/name = initial(T.name) - item_names += name - item_paths[name] = initial(T.typepath) - var/targetitem = tgui_input_list(user, "Select item to search for", "Select Item", item_names) - if(!targetitem) - return - - var/priority - var/backup - var/list/target_candidates = get_all_of_type(item_paths[targetitem], subtypes = TRUE) - for(var/obj/item/candidate in target_candidates) - var/cand_z = (get_turf(candidate)).z - if(is_admin_level(cand_z)) - continue - if(user.z != cand_z) - if(!backup) - backup = candidate - continue - // no candidate set yet, or check if there is a closer one - if(!priority || (get_dist(user, candidate) < get_dist(user, priority))) - priority = candidate - - if(priority) - target = priority - else - target = backup - if(target) - to_chat(user, "Unable to find [targetitem] in this sector, falling back to off-sector tracking.") - - if(!target) - to_chat(user, "Failed to locate [targetitem]!") - return - - to_chat(user, "You set the pinpointer to locate [targetitem].") - - if("DNA") - var/DNAstring = input("Input DNA string to search for." , "Please Enter String." , "") - if(!DNAstring) - return - for(var/mob/living/carbon/C in GLOB.mob_list) - if(!C.dna) - continue - if(C.dna.unique_enzymes == DNAstring) - target = C - break - - toggle_on() - -/obj/item/pinpointer/advpinpointer/proc/toggle_on() - if(mode == MODE_OFF) - cur_index = 1 - cycle(usr) - -/////////////////////// -//nuke op pinpointers// -/////////////////////// -/obj/item/pinpointer/nukeop - var/obj/docking_port/mobile/home = null - slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_PDA - syndicate = TRUE - modes = list(MODE_DISK, MODE_NUKE) - -/obj/item/pinpointer/nukeop/process() - switch(mode) - if(MODE_DISK) - workdisk() - if(MODE_NUKE) - workbomb() - if(MODE_SHIP) - worklocation() - -/obj/item/pinpointer/nukeop/workdisk() - if(GLOB.bomb_set) //If the bomb is set, lead to the shuttle - mode = MODE_SHIP //Ensures worklocation() continues to work - modes = list(MODE_SHIP) - playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) //Plays a beep - visible_message("Shuttle Locator mode actived.") //Lets the mob holding it know that the mode has changed - return //Get outta here - scandisk() - point_at_target(the_disk) - -/obj/item/pinpointer/nukeop/workbomb() - if(GLOB.bomb_set) //If the bomb is set, lead to the shuttle - mode = MODE_SHIP //Ensures worklocation() continues to work - modes = list(MODE_SHIP) - playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) //Plays a beep - visible_message("Shuttle Locator mode actived.") //Lets the mob holding it know that the mode has changed - return //Get outta here - scanbomb() - point_at_target(the_s_bomb) - -/obj/item/pinpointer/nukeop/proc/worklocation() - if(!GLOB.bomb_set) - mode = MODE_DISK - modes = list(MODE_DISK, MODE_NUKE) - playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) - visible_message("Authentication Disk Locator mode actived.") - return - if(!home) - home = SSshuttle.getShuttle("syndicate") - if(!home) - icon_state = icon_null - return - if(loc.z != home.z) //If you are on a different z-level from the shuttle - icon_state = icon_null - else - point_at_target(home) - -/obj/item/pinpointer/operative - name = "operative pinpointer" - desc = "A pinpointer that leads to the first Syndicate operative detected." - var/mob/living/carbon/nearest_op = null - modes = list(MODE_OPERATIVE) - -/obj/item/pinpointer/operative/process() - if(mode == MODE_OPERATIVE) - workop() - else - icon_state = icon_off - -/obj/item/pinpointer/operative/proc/scan_for_ops() - if(mode != MODE_OPERATIVE) - return - nearest_op = null //Resets nearest_op every time it scans - - var/closest_distance = 1000 - for(var/datum/mind/Mind in SSticker.mode.syndicates) - var/mob/M = Mind.current - if(!ishuman(M)) - continue - var/current_dist = get_dist(M, get_turf(src)) - if(current_dist < closest_distance) - nearest_op = M - closest_distance = current_dist - -/obj/item/pinpointer/operative/proc/workop() - if(mode == MODE_OPERATIVE) - scan_for_ops() - point_at_target(nearest_op, FALSE) - else - return FALSE - -/obj/item/pinpointer/operative/examine(mob/user) - . = ..() - if(mode == MODE_OPERATIVE) - if(nearest_op) - . += "Nearest operative detected is [nearest_op.real_name]." - else - . += "No operatives detected within scanning range." - -/obj/item/pinpointer/operative/nad - desc = "A pinpointer that leads to the first Syndicate operative detected. Also has a mode to point towards the NAD." - modes = list(MODE_OPERATIVE, MODE_DISK) - -/obj/item/pinpointer/operative/nad/process() - switch(mode) - if(MODE_DISK) - workdisk() - if(MODE_OPERATIVE) - scan_for_ops() - point_at_target(nearest_op, FALSE) - -/obj/item/pinpointer/crew - name = "crew pinpointer" - desc = "A handheld tracking device that points to crew suit sensors." - shows_nuke_timer = FALSE - icon_state = "pinoff_crew" - icon_off = "pinoff_crew" - icon_null = "pinonnull_crew" - icon_direct = "pinondirect_crew" - icon_close = "pinonclose_crew" - icon_medium = "pinonmedium_crew" - icon_far = "pinonfar_crew" - modes = list(MODE_CREW) - var/target = null //for targeting in processing - var/target_set = FALSE //have we set a target at any point? - ///Var to track the linked detective gun - var/linked_gun_UID - -/obj/item/pinpointer/crew/attackby__legacy__attackchain(obj/item/I, mob/living/user) - . = ..() - if(istype(I, /obj/item/gun/energy/detective)) - link_gun(I.UID()) - -/obj/item/pinpointer/crew/emp_act(severity) - var/obj/item/gun/energy/detective/D = locateUID(linked_gun_UID) - if(!D) - return - D.unlink() - atom_say("EMP detected. Connection to revolver tracking system lost.") - -/obj/item/pinpointer/crew/proc/link_gun(gun_UID) - var/obj/item/gun/energy/detective/D = locateUID(gun_UID) - if(!D) - return - if((D.linked_pinpointer_UID && D.linked_pinpointer_UID != UID()) || linked_gun_UID) - visible_message("The pinpointer pings to indicate either it or the gun is already linked.", "You hear a pinpointer pinging.") - return - D.link_pinpointer(UID()) - linked_gun_UID = gun_UID - visible_message("The pinpointer pings twice to indicate a successful link.", "You hear a pinpointer pinging twice.") - -/obj/item/pinpointer/crew/proc/start_tracking() - if(!linked_gun_UID) - return - var/obj/item/gun/energy/detective/D = locateUID(linked_gun_UID) - if(!D) - return - var/target_UID = D.tracking_target_UID - target = locateUID(target_UID) - target_set = TRUE - mode = PINPOINTER_MODE_DET - visible_message("The pinpointer flickers as it begins tracking a target relayed from a detective's revolver.", "You hear a pinpointer flickering.") - addtimer(CALLBACK(src, PROC_REF(stop_tracking)), 1 MINUTES, TIMER_UNIQUE) - START_PROCESSING(SSfastprocess, src) - -/obj/item/pinpointer/crew/proc/stop_tracking() - visible_message("The pinpointer powers down, no longer receiving signals from a detective's revolver.", "You hear a pinpointer powering down.") - target = null - target_set = FALSE - mode = MODE_OFF - icon_state = icon_off - STOP_PROCESSING(SSfastprocess, src) - -/obj/item/pinpointer/crew/proc/trackable(mob/living/carbon/human/H) - if(mode == PINPOINTER_MODE_DET) // Sensors? Where we're going, we dont need sensors! - var/turf/here = get_turf(src) - var/turf/there = get_turf(H) - return istype(there) && istype(here) && there.z == here.z - if(H && istype(H.w_uniform, /obj/item/clothing/under)) - var/turf/here = get_turf(src) - var/obj/item/clothing/under/U = H.w_uniform - // Suit sensors must be on maximum. - if(!U.has_sensor || U.sensor_mode < 3) - return FALSE - var/turf/there = get_turf(U) - return istype(there) && there.z == here.z - return FALSE - -/obj/item/pinpointer/crew/process() - if(mode != MODE_OFF && target_set) - point_at_target(target) - -/obj/item/pinpointer/crew/point_at_target(atom/target) - if(!target || !trackable(target)) - icon_state = icon_null - return - - ..(target) - -/obj/item/pinpointer/crew/activate_mode(mode, mob/user) - var/list/name_counts = list() - var/list/names = list() - - for(var/thing in GLOB.human_list) - var/mob/living/carbon/human/H = thing - if(!trackable(H)) - continue - - var/name = "Unknown" - if(H.wear_id) - var/obj/item/card/id/I = H.wear_id.GetID() - if(I) - name = I.registered_name - - while(name in name_counts) - name_counts[name]++ - name = "[name] ([name_counts[name]])" - names[name] = H - name_counts[name] = 1 - - if(!length(names)) - user.visible_message("[user]'s pinpointer fails to detect a signal.", "Your pinpointer fails to detect a signal.") - return - - var/A = tgui_input_list(user, "Person to track", "Pinpoint", names) - if(!src || !user || (user.get_active_hand() != src) || user.incapacitated() || !A) - return - - target = names[A] - target_set = TRUE - user.visible_message("[user] activates [user.p_their()] pinpointer.", "You activate your pinpointer.") - -/obj/item/pinpointer/crew/centcom - name = "centcom pinpointer" - desc = "A handheld tracking device that tracks crew based on remote centcom sensors." - -/obj/item/pinpointer/crew/centcom/trackable(mob/living/carbon/human/H) - var/turf/here = get_turf(src) - var/turf/there = get_turf(H) - return istype(there) && istype(here) && there.z == here.z - -/obj/item/pinpointer/tendril - name = "ancient scanning unit" - desc = "Convenient that the scanning unit for the robot survived. Seems to point to the tendrils around here." - icon_state = "pinoff_ancient" - icon_off = "pinoff_ancient" - icon_null = "pinonnull_ancient" - icon_direct = "pinondirect_ancient" - icon_close = "pinonclose_ancient" - icon_medium = "pinonmedium_ancient" - icon_far = "pinonfar_ancient" - modes = list(MODE_TENDRIL) - var/obj/structure/spawner/lavaland/target - -/obj/item/pinpointer/tendril/process() - if(mode == MODE_TENDRIL) - worktendril() - point_at_target(target, FALSE) - else - icon_state = icon_off - -/obj/item/pinpointer/tendril/proc/worktendril() - if(mode == MODE_TENDRIL) - scan_for_tendrils() - point_at_target(target) - else - return FALSE - -/obj/item/pinpointer/tendril/proc/scan_for_tendrils() - if(mode == MODE_TENDRIL) - target = null //Resets nearest_op every time it scans - var/closest_distance = 1000 - for(var/obj/structure/spawner/lavaland/T in GLOB.tendrils) - var/temp_distance = get_dist(T, get_turf(src)) - if(temp_distance < closest_distance) - target = T - closest_distance = temp_distance - -/obj/item/pinpointer/tendril/examine(mob/user) - . = ..() - if(mode == MODE_TENDRIL) - . += "Number of high energy signatures remaining: [length(GLOB.tendrils)]" - - -#undef MODE_OFF -#undef MODE_DISK -#undef MODE_NUKE -#undef MODE_ADV -#undef MODE_SHIP -#undef MODE_OPERATIVE -#undef MODE_CREW -#undef MODE_TENDRIL -#undef SETTING_DISK -#undef SETTING_LOCATION -#undef SETTING_OBJECT diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm deleted file mode 100644 index d324ad250fe2c..0000000000000 --- a/code/game/gamemodes/objective.dm +++ /dev/null @@ -1,946 +0,0 @@ -/// Stores a reference to every [objective][/datum/objective] which currently exists. -GLOBAL_LIST_EMPTY(all_objectives) -// Used in admin procs to give them a pretty list to look at, and to also have sane reusable code. -/// Stores objective [names][/datum/objective/var/name] as list keys, and their corresponding typepaths as list values. -GLOBAL_LIST_EMPTY(admin_objective_list) - -GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) - /datum/theft_objective/number - /datum/theft_objective/unique)) - -/datum/objective - /** - * Proper name of the objective. Not player facing, only shown to admins when adding objectives. - * Leave as null (or override to null) if you don't want admins to see that objective as a viable one to add (such as the mindslave objective). - */ - var/name - /** - * Owner of the objective. - * Note that it's fine to set this directly, but when needing to check completion of the objective or otherwise check conditions on the owner of the objective, - * always use `get_owners()`, and check against ALL the owners. `get_owners()` accounts for objectives that may be team based and therefore have multiple owners. - */ - var/datum/mind/owner - /// The target of the objective. - var/datum/mind/target - /// The team the objective belongs to, if any. - var/datum/team/team - /// What the owner is supposed to do to complete the objective. - var/explanation_text = "Nothing" - /// If the objective should have `find_target()` called for it. - var/needs_target = TRUE - /// If they are focused on a particular number. Steal objectives have their own counter. - var/target_amount = 0 - /// If the objective has been completed. - var/completed = FALSE - /// If the objective is compatible with martyr objective, i.e. if you can still do it while dead. - var/martyr_compatible = FALSE - /// List of jobs that the objective will target if possible, any crew if not. - var/list/target_jobs = list() - /// The department that'll be targeted by this objective. If set, fills target_jobs with jobs from that department. - var/target_department - /// If set, steal targets will be pulled from this list - var/list/steal_list = list() - /// Contains the flags needed to meet the conditions of a valid target, such as mindshielded or syndicate agent. - var/flags_target - var/datum/objective_holder/holder - - /// What is the text we show when our objective is delayed? - var/delayed_objective_text = "This is a bug! Report it on the github and ask an admin what type of objective" - -/datum/objective/New(text, datum/team/team_to_join, datum/mind/_owner) - . = ..() - SHOULD_CALL_PARENT(TRUE) - GLOB.all_objectives += src - if(text) - explanation_text = text - if(team_to_join) - team = team_to_join - if(target_department) - target_jobs = setup_target_jobs() - if(_owner) - owner = _owner - -/datum/objective/Destroy() - GLOB.all_objectives -= src - owner = null - target = null - team = null - holder = null - return ..() - -/datum/objective/proc/check_completion() - return completed - -/datum/objective/proc/found_target() - return target - -/** - * This is for objectives that need to register signals, so place them in here. - */ -/datum/objective/proc/establish_signals() - return - -/** - * This is for objectives that have reason to update their text, such as target changes. - */ -/datum/objective/proc/update_explanation_text() - stack_trace("Objective [type]'s update_explanation_text was not overridden.") - -/** - * Get all owners of the objective, including ones from the objective's team, if it has one. - * - * Use this over directly referencing `owner` in most cases. - */ -/datum/objective/proc/get_owners() - . = length(team?.members) ? team.members.Copy() : list() - if(owner) - . += owner - -/datum/proc/is_invalid_target(datum/mind/possible_target) // Originally an Objective proc. Changed to a datum proc to allow for the proc to be run on minds, before the objective is created - if(!ishuman(possible_target.current)) - return TARGET_INVALID_NOT_HUMAN - if(possible_target.current.stat == DEAD) - return TARGET_INVALID_DEAD - if(!possible_target.key) - return TARGET_INVALID_NOCKEY - if(possible_target.current) - var/turf/current_location = get_turf(possible_target.current) - if(current_location && !is_level_reachable(current_location.z)) - return TARGET_INVALID_UNREACHABLE - if(isgolem(possible_target.current)) - return TARGET_INVALID_GOLEM - if(possible_target.offstation_role) - return TARGET_INVALID_EVENT - if(HAS_TRAIT(possible_target.current, TRAIT_CRYO_DESPAWNING)) - return TARGET_CRYOING - -/datum/objective/is_invalid_target(datum/mind/possible_target) - . = ..() - if(.) - return - for(var/datum/mind/M in get_owners()) - if(possible_target == M) - return TARGET_INVALID_IS_OWNER - if(possible_target in M.targets) - return TARGET_INVALID_IS_TARGET - if(SEND_SIGNAL(src, COMSIG_OBJECTIVE_CHECK_VALID_TARGET, possible_target) & OBJECTIVE_INVALID_TARGET) - return TARGET_INVALID_BLACKLISTED - - -/datum/objective/proc/find_target(list/target_blacklist) - if(!needs_target) - return - - var/list/possible_targets = list() - for(var/datum/mind/possible_target in SSticker.minds) - if(is_invalid_target(possible_target) || (possible_target in target_blacklist)) - continue - if((flags_target & MINDSHIELDED_TARGET) && !ismindshielded(possible_target.current)) - continue - if((flags_target & UNMINDSHIELDED_TARGET) && ismindshielded(possible_target.current)) - continue - if((flags_target & SYNDICATE_TARGET) && possible_target.special_role != SPECIAL_ROLE_TRAITOR) - continue - if(length(target_jobs) && !(possible_target.assigned_role in target_jobs)) - continue - possible_targets += possible_target - - if(!length(possible_targets)) // If we can't find anyone, try with less restrictions - for(var/datum/mind/possible_target in SSticker.minds) - if(is_invalid_target(possible_target) || (possible_target in target_blacklist)) - continue - possible_targets += possible_target - - if(length(possible_targets) > 0) - target = pick(possible_targets) - - SEND_SIGNAL(src, COMSIG_OBJECTIVE_TARGET_FOUND, target) - update_explanation_text() - return target - -/** - * Called when the objective's target goes to cryo. - */ -/datum/objective/proc/on_target_cryo() - var/list/owners = get_owners() - for(var/datum/mind/M in owners) - to_chat(M.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!") - SEND_SOUND(M.current, sound('sound/ambience/alarm4.ogg')) - target = null - INVOKE_ASYNC(src, PROC_REF(post_target_cryo), owners) - -/datum/objective/proc/post_target_cryo(list/owners) - find_target() - if(!target) - holder.remove_objective(src) - // even if we have to remove the objective, still announce it - for(var/datum/mind/M in owners) - var/list/messages = M.prepare_announce_objectives(FALSE) - to_chat(M.current, chat_box_red(messages.Join("
    "))) - -// Borgs, brains, AIs, etc count as dead for traitor objectives -/datum/objective/proc/is_special_dead(mob/target_current, check_silicon = TRUE) - if(check_silicon && issilicon(target_current)) - return TRUE - return isbrain(target_current) || istype(target_current, /mob/living/simple_animal/spiderbot) - -// Setup and return the objective target jobs list based on target department -/datum/objective/proc/setup_target_jobs() - if(!target_department) - return - . = list() - switch(target_department) - if(DEPARTMENT_COMMAND) - . = GLOB.command_head_positions.Copy() - if(DEPARTMENT_MEDICAL) - . = GLOB.medical_positions.Copy() - if(DEPARTMENT_ENGINEERING) - . = GLOB.engineering_positions.Copy() - if(DEPARTMENT_SCIENCE) - . = GLOB.science_positions.Copy() - if(DEPARTMENT_SECURITY) - . = GLOB.active_security_positions.Copy() - if(DEPARTMENT_SUPPLY) - . = GLOB.supply_positions.Copy() - if(DEPARTMENT_SERVICE) - . = GLOB.service_positions.Copy() - -/datum/objective/assassinate - name = "Assassinate" - martyr_compatible = TRUE - delayed_objective_text = "Your objective is to assassinate another crewmember. You will receive further information in a few minutes." - -/datum/objective/assassinate/update_explanation_text() - if(target?.current) - explanation_text = "Assassinate [target.current.real_name], the [target.assigned_role]." - else - explanation_text = "Free Objective" - -/datum/objective/assassinate/check_completion() - if(target?.current) - if(target.current.stat == DEAD) - return TRUE - if(is_special_dead(target.current)) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite - return TRUE - if(!target.current.ckey) - return TRUE - return FALSE - return TRUE - -/datum/objective/assassinateonce - name = "Assassinate once" - martyr_compatible = TRUE - delayed_objective_text = "Your objective is to teach another crewmember a lesson. You will receive further information in a few minutes." - var/won = FALSE - -/datum/objective/assassinateonce/update_explanation_text() - if(target?.current) - explanation_text = "Teach [target.current.real_name], the [target.assigned_role], a lesson they will not forget. The target only needs to die once for success." - establish_signals() - else - explanation_text = "Free Objective" - -/datum/objective/assassinateonce/establish_signals() - RegisterSignal(target.current, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), PROC_REF(check_midround_completion)) - -/datum/objective/assassinateonce/check_completion() - return won || completed || !target?.current?.ckey - -/datum/objective/assassinateonce/proc/check_midround_completion() - won = TRUE - UnregisterSignal(target.current, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING)) - -/datum/objective/assassinateonce/on_target_cryo() - if(won) - return - return ..() - -/datum/objective/mutiny - name = "Mutiny" - martyr_compatible = TRUE - -/datum/objective/mutiny/update_explanation_text() - if(target?.current) - explanation_text = "Assassinate or exile [target.current.real_name], the [target.assigned_role]." - else - explanation_text = "Free Objective" - -/datum/objective/mutiny/is_invalid_target(datum/mind/possible_target) - . = ..() - if(.) - return - if(!(possible_target in SSticker.mode.get_all_heads())) - return TARGET_INVALID_NOTHEAD - -/datum/objective/mutiny/check_completion() - if(target?.current) - if(target.current.stat == DEAD || !ishuman(target.current) || !target.current.ckey || !target.current.client) - return TRUE - var/turf/T = get_turf(target.current) - if(T && !is_station_level(T.z)) //If they leave the station they count as dead for this - return TRUE - return FALSE - return TRUE - -/datum/objective/mutiny/on_target_cryo() - // 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(team) - team.remove_team_objective(src) - return - qdel(src) - -/datum/objective/maroon - name = "Maroon" - martyr_compatible = FALSE - delayed_objective_text = "Your objective is to make sure another crewmember doesn't leave on the Escape Shuttle. You will receive further information in a few minutes." - -/datum/objective/maroon/update_explanation_text() - if(target?.current) - explanation_text = "Prevent [target.current.real_name], the [target.assigned_role] from escaping alive." - else - explanation_text = "Free Objective" - -/datum/objective/maroon/check_completion() - if(target?.current) - if(target.current.stat == DEAD) - return TRUE - if(!target.current.ckey) - return TRUE - if(is_special_dead(target.current)) - return TRUE - var/turf/T = get_turf(target.current) - if(is_admin_level(T.z)) - return FALSE - return TRUE - return TRUE - -/// I want braaaainssss -/datum/objective/debrain - name = "Debrain" - martyr_compatible = FALSE - delayed_objective_text = "Your objective is to steal another crewmember's brain. You will receive further information in a few minutes." - -/datum/objective/debrain/is_invalid_target(datum/mind/possible_target) - . = ..() - if(.) - return - // If the target is a changeling, then it's an invalid target. Since changelings can not be debrained. - if(IS_CHANGELING(possible_target.current)) - return TARGET_INVALID_CHANGELING - -/datum/objective/debrain/update_explanation_text() - if(target?.current) - explanation_text = "Steal the brain of [target.current.real_name], the [target.assigned_role]." - else - explanation_text = "Free Objective" - -/datum/objective/debrain/check_completion() - if(!target) // If it's a free objective. - return TRUE - if(!target.current || !isbrain(target.current)) - return FALSE - for(var/datum/mind/M in get_owners()) - if(QDELETED(M.current)) - continue // Maybe someone who's alive has the brain. - if(target.current in M.current.GetAllContents()) - return TRUE - return FALSE - - -/// The opposite of killing a dude. -/datum/objective/protect - name = "Protect" - martyr_compatible = TRUE - -/datum/objective/protect/update_explanation_text() - if(target?.current) - explanation_text = "Protect [target.current.real_name], the [target.assigned_role]." - else - explanation_text = "Free Objective" - -/datum/objective/protect/check_completion() - if(!target) //If it's a free objective. - return TRUE - if(target.current) - if(target.current.stat == DEAD) - return FALSE - if(is_special_dead(target.current)) - return FALSE - return TRUE - return FALSE - -/// subytpe for mindslave implants -/datum/objective/protect/mindslave - needs_target = FALSE // To be clear, this objective should have a target, but it will always be manually set to the mindslaver through the mindslave antag datum. - -// This objective should only be given to a single owner. We can use `owner` and not `get_owners()`. -/datum/objective/protect/mindslave/on_target_cryo() - if(owner?.current) - SEND_SOUND(owner.current, sound('sound/ambience/alarm4.ogg')) - owner.remove_antag_datum(/datum/antagonist/mindslave) - to_chat(owner.current, "
    You notice that your master has entered cryogenic storage, and revert to your normal self.") - log_admin("[key_name(owner.current)]'s mindslave master has cryo'd, and is no longer a mindslave.") - message_admins("[key_name_admin(owner.current)]'s mindslave master has cryo'd, and is no longer a mindslave.") //Since they were on antag hud earlier, this feels important to log - qdel(src) - -/datum/objective/hijack - name = "Hijack" - martyr_compatible = FALSE //Technically you won't get both anyway. - explanation_text = "Hijack the shuttle by escaping on it with no loyalist Nanotrasen crew on board and free. \ - Syndicate agents, other enemies of Nanotrasen, cyborgs, pets, and cuffed/restrained hostages may be allowed on the shuttle alive. \ - Alternatively, hack the shuttle console multiple times (by alt clicking on it) until the shuttle directions are corrupted." - needs_target = FALSE - -/datum/objective/hijack/check_completion() - if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME) - return FALSE - for(var/datum/mind/M in get_owners()) - if(QDELETED(M.current) || M.current.stat != CONSCIOUS || issilicon(M.current) || get_area(M.current) != SSshuttle.emergency.areaInstance) - return FALSE - return SSshuttle.emergency.is_hijacked() - -/datum/objective/hijackclone - name = "Hijack (with clones)" - explanation_text = "Hijack the shuttle by ensuring only you (or your copies) escape." - martyr_compatible = FALSE - needs_target = FALSE - -// This objective should only be given to a single owner, because the "copies" can only copy one person. -// We're fine to use `owner` instead of `get_owners()`. -/datum/objective/hijackclone/check_completion() - if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME || !owner.current) - return FALSE - - var/area/A = SSshuttle.emergency.areaInstance - - for(var/mob/living/player in GLOB.player_list) //Make sure nobody else is onboard - if(player.mind && player.mind != owner) - if(player.stat != DEAD) - if(issilicon(player)) - continue - if(get_area(player) == A) - if(player.real_name != owner.current.real_name && !istype(get_turf(player.mind.current), /turf/simulated/floor/mineral/plastitanium/red/brig)) - return FALSE - - for(var/mob/living/player in GLOB.player_list) //Make sure at least one of you is onboard - if(player.mind && player.mind != owner) - if(player.stat != DEAD) - if(issilicon(player)) - continue - if(get_area(player) == A) - if(player.real_name == owner.current.real_name && !istype(get_turf(player.mind.current), /turf/simulated/floor/mineral/plastitanium/red/brig)) - return TRUE - return FALSE - -/datum/objective/block - name = "Silicon hijack" - explanation_text = "Hijack the shuttle by alt-clicking on the shuttle console. Do not let the crew wipe you off of it! \ - Crew and agents can be on the shuttle when you do this, and may try to wipe you! \ - Using the doomsday device successfully is also an option." - martyr_compatible = FALSE - needs_target = FALSE - -/datum/objective/block/check_completion() - for(var/datum/mind/M in get_owners()) - if(!M.current || !issilicon(M.current)) - return FALSE - if(SSticker.mode.station_was_nuked) - return TRUE - if(SSshuttle.emergency.aihacked) - return TRUE - if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME) - return FALSE - if(!SSshuttle.emergency.is_hijacked(TRUE)) - return FALSE - return TRUE - -/datum/objective/escape - name = "Escape" - explanation_text = "Escape on the shuttle or an escape pod alive and free." - needs_target = FALSE - -/datum/objective/escape/check_completion() - var/list/owners = get_owners() - for(var/datum/mind/M in owners) - // These are mandatory conditions, they should come before the freebie conditions below. - if(QDELETED(M.current) || M.current.stat == DEAD || is_special_dead(M.current)) - return FALSE - - if(SSticker.force_ending) // This one isn't their fault, so lets just assume good faith. - return TRUE - if(SSticker.mode.station_was_nuked) // If they escaped the blast somehow, let them win. - return TRUE - if(SSshuttle.emergency.mode < SHUTTLE_ENDGAME) - return FALSE - - for(var/datum/mind/M in owners) - var/turf/location = get_turf(M.current) - if(istype(location, /turf/simulated/floor/mineral/plastitanium/red/brig)) - return FALSE - if(!location.onCentcom() && !location.onSyndieBase()) - return FALSE - - return TRUE - -/datum/objective/escape/escape_with_identity - name = "Escape With Identity" - /// Stored because the target's `[mob/var/real_name]` can change over the course of the round. - var/target_real_name - /// If the objective has an assassinate objective tied to it. - var/has_assassinate_objective = FALSE - -/datum/objective/escape/escape_with_identity/New(text, datum/team/team_to_join, datum/mind/_owner, datum/objective/assassinate/assassinate) - ..() - if(!assassinate) - return - target = assassinate.target - target_real_name = assassinate.target.current.real_name - explanation_text = "Escape on the shuttle or an escape pod with the identity of [target_real_name], the [target.assigned_role] while wearing [target.p_their()] identification card." - has_assassinate_objective = TRUE - RegisterSignal(assassinate, COMSIG_OBJECTIVE_TARGET_FOUND, PROC_REF(assassinate_found_target)) - RegisterSignal(assassinate, COMSIG_OBJECTIVE_CHECK_VALID_TARGET, PROC_REF(assassinate_checking_target)) - -/datum/objective/escape/escape_with_identity/is_invalid_target(datum/mind/possible_target) - if(..() || !possible_target.current.client) - return TRUE - // If the target is geneless, then it's an invalid target. - return HAS_TRAIT(possible_target.current, TRAIT_GENELESS) - -/datum/objective/escape/escape_with_identity/update_explanation_text() - if(target?.current) - target_real_name = target.current.real_name - explanation_text = "Escape on the shuttle or an escape pod with the identity of [target_real_name], the [target.assigned_role] while wearing [target.p_their()] identification card." - else - explanation_text = "Free Objective" - -/datum/objective/escape/escape_with_identity/proc/assassinate_checking_target(datum/source, datum/mind/possible_target) - SIGNAL_HANDLER - if(!possible_target.current.client || HAS_TRAIT(possible_target.current, TRAIT_GENELESS)) - // Stop our linked assassinate objective from choosing a clientless/geneless target. - return OBJECTIVE_INVALID_TARGET - return OBJECTIVE_VALID_TARGET - -/datum/objective/escape/escape_with_identity/proc/assassinate_found_target(datum/source, datum/mind/new_target) - SIGNAL_HANDLER - if(new_target) - target = new_target - update_explanation_text() - return - // The assassinate objective was unable to find a new target after the old one cryo'd as was qdel'd. We're on our own. - find_target() - has_assassinate_objective = FALSE - -/datum/objective/escape/escape_with_identity/on_target_cryo() - if(has_assassinate_objective) - return // Our assassinate objective will handle this. - ..() - -/datum/objective/escape/escape_with_identity/post_target_cryo() - if(has_assassinate_objective) - return // Our assassinate objective will handle this. - ..() - -// This objective should only be given to a single owner since only 1 person can have the ID card of the target. -// We're fine to use `owner` instead of `get_owners()`. -/datum/objective/escape/escape_with_identity/check_completion() - if(!target_real_name) - return TRUE - if(!ishuman(owner.current)) - return FALSE - var/mob/living/carbon/human/H = owner.current - if(..()) - if(H.dna.real_name == target_real_name) - if(H.get_id_name() == target_real_name) - return TRUE - return FALSE - -/datum/objective/survive - name = "Survive" - explanation_text = "Stay alive until the end." - needs_target = FALSE - -/datum/objective/survive/check_completion() - for(var/datum/mind/M in get_owners()) - if(QDELETED(M.current) || M.current.stat == DEAD || is_special_dead(M.current, check_silicon = FALSE)) - return FALSE - if(issilicon(M.current) && !M.is_original_mob(M.current)) - return FALSE - return TRUE - -/datum/objective/nuclear - name = "Nuke station" - explanation_text = "Destroy the station with a nuclear device." - martyr_compatible = TRUE - needs_target = FALSE - -/datum/objective/steal - name = "Steal Item" - martyr_compatible = FALSE - delayed_objective_text = "Your objective is to steal a high-value item. You will receive further information in a few minutes." - var/theft_area - var/datum/theft_objective/steal_target - -/datum/objective/steal/found_target() - return steal_target - -/datum/objective/steal/proc/get_location() - return steal_target.location_override || "an unknown area" - -/datum/objective/steal/find_target(list/target_blacklist) - var/potential - if(length(steal_list)) - potential = steal_list.Copy() - else - potential = GLOB.potential_theft_objectives.Copy() - while(!steal_target && length(potential)) - var/thefttype = pick_n_take(potential) - if(locate(thefttype) in target_blacklist) - continue - var/datum/theft_objective/O = new thefttype - var/has_invalid_owner = FALSE - for(var/datum/mind/M in get_owners()) - if((M.assigned_role in O.protected_jobs) || (O in M.targets)) - has_invalid_owner = TRUE - break - if(has_invalid_owner) - continue - if(!O.check_objective_conditions()) - continue - if(O.flags & THEFT_FLAG_UNIQUE) - continue - - steal_target = O - update_explanation_text() - if(steal_target.special_equipment) - give_kit(steal_target.special_equipment) - return - explanation_text = "Free Objective." - -/datum/objective/steal/proc/select_target() - var/list/possible_items_all = GLOB.potential_theft_objectives + "custom" + "random" - var/new_target = input("Select target:", "Objective target", null) as null|anything in possible_items_all - if(!new_target) - return - - if(new_target == "custom") - var/obj/item/steal_target_path = input("Select type:","Type") as null|anything in typesof(/obj/item) - if(!steal_target_path) - return - - var/theft_objective_name = sanitize(copytext_char(input("Enter target name:", "Objective target", initial(steal_target_path.name)) as text|null, 1, MAX_NAME_LEN)) - if(!theft_objective_name) - return - - var/datum/theft_objective/target_theft_objective = new - target_theft_objective.typepath = steal_target_path - target_theft_objective.name = theft_objective_name - steal_target = target_theft_objective - explanation_text = "Steal [theft_objective_name]." - return steal_target - else if(new_target == "random") - return TRUE - - steal_target = new new_target - update_explanation_text() - if(steal_target.special_equipment) // We have to do it with a callback because mind/Topic creates the objective without an owner - addtimer(CALLBACK(src, PROC_REF(hand_out_equipment)), 5 SECONDS, TIMER_DELETE_ME) - return steal_target - -/datum/objective/steal/proc/hand_out_equipment() - give_kit(steal_target?.special_equipment) - -/datum/objective/steal/update_explanation_text() - explanation_text = "Steal [steal_target.name]. One was last seen in [get_location()]. " - if(length(steal_target.protected_jobs) && steal_target.job_possession) - explanation_text += "It may also be in the possession of the [english_list(steal_target.protected_jobs, and_text = " or ")]. " - explanation_text += steal_target.extra_information - -/datum/objective/steal/check_completion() - if(!steal_target) - return TRUE // Free Objective - - for(var/datum/mind/M in get_owners()) - if(!M.current) - continue - for(var/obj/I in M.current.GetAllContents()) - if((istype(I, steal_target.typepath) || (I.type in steal_target.altitems)) && steal_target.check_special_completion(I)) - return TRUE - return FALSE - -/datum/objective/steal/proc/give_kit(obj/item/item_path) - var/list/datum/mind/objective_owners = get_owners() - if(!length(objective_owners)) - return - - var/obj/item/item_to_give = new item_path - var/static/list/slots = list( - "backpack" = ITEM_SLOT_IN_BACKPACK, - "left pocket" = ITEM_SLOT_LEFT_POCKET, - "right pocket" = ITEM_SLOT_RIGHT_POCKET, - "left hand" = ITEM_SLOT_LEFT_HAND, - "right hand" = ITEM_SLOT_RIGHT_HAND, - ) - - for(var/datum/mind/kit_receiver_mind as anything in shuffle(objective_owners)) - var/mob/living/carbon/human/kit_receiver = kit_receiver_mind.current - if(!kit_receiver) - continue - var/where = kit_receiver.equip_in_one_of_slots(item_to_give, slots) - if(!where) - continue - - to_chat(kit_receiver, "

    In your [where] is a box containing items and instructions to help you with your steal objective.
    ") - for(var/datum/mind/objective_owner as anything in objective_owners) - if(kit_receiver_mind == objective_owner || !objective_owner.current) - continue - - to_chat(objective_owner.current, "

    [kit_receiver] has received a box containing items and instructions to help you with your steal objective.

    ") - - return - - qdel(item_to_give) - - for(var/datum/mind/objective_owner as anything in objective_owners) - var/mob/living/carbon/human/failed_receiver = objective_owner.current - if(!failed_receiver) - continue - - to_chat(failed_receiver, "Unfortunately, you weren't able to get a stealing kit. This is very bad and you should adminhelp immediately (press F1).") - message_admins("[ADMIN_LOOKUPFLW(failed_receiver)] Failed to spawn with their [item_path] theft kit.") - -/datum/objective/absorb - name = "Absorb DNA" - needs_target = FALSE - -/datum/objective/absorb/New(text, datum/team/team_to_join) - . = ..() - gen_amount_goal() - -/datum/objective/absorb/proc/gen_amount_goal(lowbound = 6, highbound = 8) - target_amount = rand (lowbound,highbound) - if(SSticker) - var/n_p = 1 //autowin - if(SSticker.current_state == GAME_STATE_SETTING_UP) - for(var/mob/new_player/P in GLOB.player_list) - if(P.client && P.ready && !(P.mind in get_owners())) - if(P.client.prefs && (P.client.prefs.active_character.species == "Machine")) // Special check for species that can't be absorbed. No better solution. - continue - n_p++ - else if(SSticker.current_state == GAME_STATE_PLAYING) - for(var/mob/living/carbon/human/P in GLOB.player_list) - if(HAS_TRAIT(P, TRAIT_GENELESS)) - continue - if(P.client && !(P.mind in SSticker.mode.changelings) && !(P.mind in get_owners())) - n_p++ - target_amount = min(target_amount, n_p) - update_explanation_text() - return target_amount - -/datum/objective/absorb/update_explanation_text() - explanation_text = "Acquire [target_amount] compatible genomes. The 'Extract DNA Sting' can be used to stealthily get genomes without killing somebody." - -/datum/objective/absorb/check_completion() - for(var/datum/mind/M in get_owners()) - var/datum/antagonist/changeling/cling = M?.has_antag_datum(/datum/antagonist/changeling) - if(cling?.absorbed_dna && (cling.absorbed_count >= target_amount)) - return TRUE - return FALSE - -/datum/objective/destroy - name = "Destroy AI" - martyr_compatible = TRUE - delayed_objective_text = "Your objective is to destroy an Artificial Intelligence. You will receive further information in a few minutes." - -/datum/objective/destroy/find_target(list/target_blacklist) - var/list/possible_targets = active_ais(1) - var/mob/living/silicon/ai/target_ai = pick(possible_targets) - target = target_ai.mind - update_explanation_text() - return target - -/datum/objective/destroy/update_explanation_text() - if(target?.current) - explanation_text = "Destroy [target.current.real_name], the AI." - else - explanation_text = "Free Objective" - -/datum/objective/destroy/check_completion() - if(target?.current) - if(target.current.stat == DEAD || is_away_level(target.current.z) || !target.current.ckey) - return TRUE - return FALSE - return TRUE - -/datum/objective/destroy/post_target_cryo(list/owners) - holder.replace_objective(src, /datum/objective/assassinate) - -/datum/objective/steal_five_of_type - name = "Steal Five Items" - explanation_text = "Steal at least five items!" - needs_target = FALSE - var/list/wanted_items = list() - -/datum/objective/steal_five_of_type/New() - ..() - wanted_items = typecacheof(wanted_items) - -/datum/objective/steal_five_of_type/check_completion() - var/stolen_count = 0 - var/list/owners = get_owners() - var/list/all_items = list() - for(var/datum/mind/M in owners) - if(!isliving(M.current)) - continue - all_items += M.current.GetAllContents() //this should get things in cheesewheels, books, etc. - for(var/obj/I in all_items) //Check for wanted items - if(is_type_in_typecache(I, wanted_items)) - stolen_count++ - return stolen_count >= 5 - -/datum/objective/steal_five_of_type/summon_guns - name = "Steal Five Guns" - explanation_text = "Steal at least five guns!" - wanted_items = list(/obj/item/gun) - -/datum/objective/steal_five_of_type/summon_magic - name = "Steal Five Artefacts" - explanation_text = "Steal at least five magical artefacts!" - wanted_items = list() - -/datum/objective/steal_five_of_type/summon_magic/New() - wanted_items = GLOB.summoned_magic_objectives - ..() - -/datum/objective/steal_five_of_type/summon_magic/check_completion() - var/stolen_count = 0 - var/list/owners = get_owners() - var/list/all_items = list() - for(var/datum/mind/M in owners) - if(!isliving(M.current)) - continue - all_items += M.current.GetAllContents() //this should get things in cheesewheels, books, etc. - for(var/obj/I in all_items) //Check for wanted items - if(istype(I, /obj/item/spellbook) && !istype(I, /obj/item/spellbook/oneuse)) - var/obj/item/spellbook/spellbook = I - if(spellbook.uses) //if the book still has powers... - stolen_count++ //it counts. nice. - if(istype(I, /obj/item/spellbook/oneuse)) - var/obj/item/spellbook/oneuse/oneuse = I - if(!oneuse.used) - stolen_count++ - else if(is_type_in_typecache(I, wanted_items)) - stolen_count++ - return stolen_count >= 5 - -/datum/objective/blood - name = "Drink blood" - needs_target = FALSE - -/datum/objective/blood/New() - gen_amount_goal() - . = ..() - -/datum/objective/blood/proc/gen_amount_goal(low = 150, high = 400) - target_amount = rand(low,high) - target_amount = round(round(target_amount/5)*5) - update_explanation_text() - return target_amount - -/datum/objective/blood/update_explanation_text() - explanation_text = "Accumulate at least [target_amount] total units of blood." - -/datum/objective/blood/check_completion() - for(var/datum/mind/M in get_owners()) - var/datum/antagonist/vampire/V = M.has_antag_datum(/datum/antagonist/vampire) - if(V.bloodtotal >= target_amount) - return TRUE - else - return FALSE - -#define SWARM_GOAL_LOWER_BOUND 130 -#define SWARM_GOAL_UPPER_BOUND 400 - -/datum/objective/swarms - name = "Gain swarms" - needs_target = FALSE - -/datum/objective/swarms/New() - gen_amount_goal() - return ..() - -/datum/objective/swarms/proc/gen_amount_goal(low = SWARM_GOAL_LOWER_BOUND, high = SWARM_GOAL_UPPER_BOUND) - target_amount = round(rand(low, high), 5) - update_explanation_text() - return target_amount - -/datum/objective/swarms/update_explanation_text() - explanation_text = "Accumulate at least [target_amount] worth of swarms." - -/datum/objective/swarms/check_completion() - for(var/datum/mind/M in get_owners()) - var/datum/antagonist/mindflayer/flayer = M.has_antag_datum(/datum/antagonist/mindflayer) - return flayer?.total_swarms_gathered >= target_amount - -#undef SWARM_GOAL_LOWER_BOUND -#undef SWARM_GOAL_UPPER_BOUND - -// Traders -// These objectives have no check_completion, they exist only to tell Sol Traders what to aim for. - -/datum/objective/trade - needs_target = FALSE - completed = TRUE - -/datum/objective/trade/plasma - explanation_text = "Acquire at least 15 sheets of plasma through trade." - -/datum/objective/trade/credits - explanation_text = "Acquire at least 10,000 credits through trade." - -//wizard - -/datum/objective/wizchaos - explanation_text = "Wreak havoc upon the station as much you can. Send those wandless Nanotrasen scum a message!" - needs_target = FALSE - completed = TRUE - -/datum/objective/zombie - explanation_text = "Hunger grows within us, we need to feast on the brains of the uninfected. Scratch, bite, and spread the plague." - needs_target = FALSE - completed = TRUE - -// Placeholder objectives that will replace themselves - -/datum/objective/delayed - needs_target = FALSE - var/datum/objective/objective_to_replace_with - -/datum/objective/delayed/New(datum/objective/delayed_objective) - ..() - if(!ispath(delayed_objective)) - stack_trace("A delayed objective has been given a non-path. Given was instead [delayed_objective]") - return - objective_to_replace_with = delayed_objective - explanation_text = initial(delayed_objective.delayed_objective_text) - -/datum/objective/delayed/update_explanation_text() - return - -/datum/objective/delayed/proc/reveal_objective() - return holder.replace_objective(src, new objective_to_replace_with(null, team, owner), target_department, steal_list) - -// A warning objective for that an agent is after you and knows you are an agent (or that you are paranoid) -/datum/objective/potentially_backstabbed - name = "Potentially Backstabbed" - explanation_text = "Our intelligence suggests that you are likely to be the target of a rival member of the Syndicate. \ - Remain vigilant, they know who you are and what you can do." - needs_target = FALSE - -/datum/objective/potentially_backstabbed/check_completion() - for(var/datum/mind/M in get_owners()) - var/datum/antagonist/traitor/T = M.has_antag_datum(/datum/antagonist/traitor) - for(var/datum/objective/our_objective in T.get_antag_objectives(FALSE)) - if(istype(our_objective, /datum/objective/potentially_backstabbed)) - continue - if(!our_objective.check_completion()) - return FALSE - return TRUE diff --git a/code/game/gamemodes/objective_holder.dm b/code/game/gamemodes/objective_holder.dm deleted file mode 100644 index b447f67713c20..0000000000000 --- a/code/game/gamemodes/objective_holder.dm +++ /dev/null @@ -1,132 +0,0 @@ -/** - * An objective holder for minds, antag datums, and teams. - */ - -/datum/objective_holder - /// Our list of current objectives - VAR_PRIVATE/list/datum/objective/objectives = list() - /// Who do we belong to [mind, antagonist, team] - VAR_PRIVATE/datum/objective_owner - /// A list of strings which contain [targets][/datum/objective/var/target] of the antagonist's objectives. Used to prevent duplicate objectives. - VAR_PRIVATE/list/assigned_targets = list() - /// A callback invoked when a new objective is added. This is required because sometimes objectives are added directly without going through objective_owner. Not currently used. - VAR_PRIVATE/datum/callback/on_add_callback - /// A callback invoked when a new objective is added. This is required because sometimes objectives are removed directly without going through objective_owner (EX: replace_objective(), clear()). Not currently used. - VAR_PRIVATE/datum/callback/on_remove_callback - -/datum/objective_holder/New(new_owner) - . = ..() - objective_owner = new_owner - -/datum/objective_holder/Destroy(force, ...) - clear() - objective_owner = null - QDEL_NULL(on_add_callback) - QDEL_NULL(on_remove_callback) - return ..() - -/** - * Clear all objectives of a certain type - * * checktype - The type to check, if null, remoe all objectives. - */ -/datum/objective_holder/proc/clear(check_type) - for(var/datum/objective/Objective as anything in objectives) - if(check_type && !istype(Objective, check_type)) - return - remove_objective(Objective) - . = TRUE - -/** - * Sets the callbacks, not on new because that can be irreliable for subtypes. - */ -/datum/objective_holder/proc/set_callbacks(_on_add_callback, _on_remove_callback) - on_add_callback = _on_add_callback - on_remove_callback = _on_remove_callback - -/** - * Do we have any objectives - */ -/datum/objective_holder/proc/has_objectives() - return length(objectives) > 0 - -/** - * Get all of the objectives we own - */ -/datum/objective_holder/proc/get_objectives() - return objectives - -/** - * Replace old_objective with new_objective - */ -/datum/objective_holder/proc/replace_objective(datum/objective/old_objective, datum/objective/new_objective, datum/original_target_department, list/original_steal_list) - new_objective.target_department = original_target_department - new_objective.steal_list = original_steal_list - new_objective = add_objective(new_objective, add_to_list = FALSE) - // Replace where the old objective was, with the new one - objectives.Insert(objectives.Find(old_objective), new_objective) - remove_objective(old_objective) - -/** - * Add an objective. - * - * * Objective - The objective to add [/datum/objective, path] - * * _explanation_text - Optional, will assign this text to the objective - * * target_override - A target override, will prevent finding a target - * * add_to_list - Do we add the new objective to our list? Or will it be handled elsewhere (like replace_objective). Should not be set to false outside of this file. - */ - -/datum/objective_holder/proc/add_objective(datum/objective/Objective, _explanation_text, mob/target_override, add_to_list = TRUE) - if(ispath(Objective)) - Objective = new Objective() - - Objective.holder = src - - if(add_to_list) - objectives += Objective - - if(target_override) - Objective.target = target_override - else if(Objective.needs_target && !Objective.found_target()) - handle_objective(Objective) - - var/found = Objective.found_target() // in case we are given a target override - if(found) - assigned_targets |= found - - if(_explanation_text) - Objective.explanation_text = _explanation_text - - on_add_callback?.Invoke(objective_owner, Objective) - return Objective - -/** - * Handles the searching of targets for objectives that need it. - */ - -/datum/objective_holder/proc/handle_objective(datum/objective/Objective) - for(var/loop in 1 to 5) - Objective.find_target(assigned_targets) - if(Objective.found_target()) // Handles normal objectives, and steal objectives - return - - // We failed to find any target. Oh well... - Objective.explanation_text = "Free Objective" - Objective.target = null - -/** - * Remove an objective and deletes it. You should never need to transfer an objective. - */ -/datum/objective_holder/proc/remove_objective(datum/objective/Objective) - objectives -= Objective - assigned_targets -= Objective.found_target() - - on_remove_callback?.Invoke(objective_owner, Objective) - if(!QDELETED(Objective)) - qdel(Objective) - -/** - * Returns `objective_owner` - */ -/datum/objective_holder/proc/get_holder_owner() - RETURN_TYPE(/datum) - return objective_owner diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm deleted file mode 100644 index 46ed0c4f3fea8..0000000000000 --- a/code/game/gamemodes/revolution/revolution.dm +++ /dev/null @@ -1,266 +0,0 @@ -// To remove a rev (from brainwashing or w/e), call SSticker.mode.remove_revolutionary(_THE_PLAYERS_MIND_), -// this will also check they're not a head, so it can just be called freely - -#define REV_VICTORY 1 -#define STATION_VICTORY 2 - -/datum/game_mode/revolution - name = "revolution" - config_tag = "revolution" - restricted_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer", "Blueshield", "Nanotrasen Representative", "Magistrate", "Quartermaster", "Nanotrasen Career Trainer") - required_players = 20 - required_enemies = 1 - recommended_enemies = 3 - - var/finished - var/check_counter = 0 - var/list/pre_revolutionaries = list() - -/////////////////////////// -//Announces the game type// -/////////////////////////// -/datum/game_mode/revolution/announce() - to_chat(world, "The current game mode is - Revolution!") - to_chat(world, "Some crewmembers are attempting to start a revolution!
    \nRevolutionaries - Kill the Captain, HoP, HoS, CE, QM, RD and CMO. Convert other crewmembers (excluding the heads of staff, and security officers) to your cause by flashing them. Protect your leaders.
    \nPersonnel - Protect the heads of staff. Kill the leaders of the revolution, and brainwash the other revolutionaries (by beating them in the head).
    ") - - -/////////////////////////////////////////////////////////////////////////////// -//Gets the round setup, cancelling if there's not enough players at the start// -/////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/revolution/pre_setup() - var/list/datum/mind/possible_revolutionaries = get_players_for_role(ROLE_REV) - - if(GLOB.configuration.gamemode.prevent_mindshield_antags) - restricted_jobs |= protected_jobs - - for(var/i in 1 to REVOLUTION_MAX_HEADREVS) - if(!length(possible_revolutionaries)) - break - var/datum/mind/new_headrev = pick_n_take(possible_revolutionaries) - pre_revolutionaries |= new_headrev - new_headrev.restricted_roles = restricted_jobs - new_headrev.special_role = SPECIAL_ROLE_HEAD_REV - - if(length(pre_revolutionaries) < required_enemies) - return FALSE - - return TRUE - - -/datum/game_mode/revolution/post_setup() - - get_rev_team() - - for(var/i in 1 to rev_team.need_another_headrev(1)) // yes this is a ONE, not a true - if(!length(pre_revolutionaries)) - break - var/datum/mind/new_headrev = pick_n_take(pre_revolutionaries) - new_headrev.add_antag_datum(/datum/antagonist/rev/head) - - ..() - -/datum/game_mode/revolution/Destroy(force, ...) - pre_revolutionaries.Cut() - return ..() - -/datum/game_mode/revolution/process() // to anyone who thinks "why don't we use a normal actually sane check here instead of process for checking Z level changes" It's because equip code is dogshit and you change z levels upon spawning in - check_counter++ - if(check_counter >= 5) - if(!finished) - rev_team.check_all_victory() - check_counter = 0 - return FALSE - -/datum/game_mode/proc/get_rev_team() - if(!rev_team) - new /datum/team/revolution() // assignment happens in create_team() - return rev_team - -////////////////////////////////////// -//Checks if the revs have won or not// -////////////////////////////////////// -/datum/game_mode/revolution/check_win() - if(rev_team.check_rev_victory()) - finished = REV_VICTORY - else if(rev_team.check_heads_victory()) - finished = STATION_VICTORY - -/////////////////////////////// -//Checks if the round is over// -/////////////////////////////// -/datum/game_mode/revolution/check_finished() - if(GLOB.configuration.gamemode.disable_certain_round_early_end) - if(finished) - SSshuttle.clearHostileEnvironment(rev_team) - if(SSshuttle.emergency.mode == SHUTTLE_STRANDED) - SSshuttle.emergency.mode = SHUTTLE_DOCKED - SSshuttle.emergency.timer = world.time - GLOB.major_announcement.Announce("Hostile environment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/eshuttle_dock.ogg') - return ..() - if(finished) - return TRUE - return ..() - -////////////////////////////////////////////////////////////////////////////// -//Deals with players being converted from the revolution (Not a rev anymore)// // Modified to handle borged MMIs. Accepts another var if the target is being borged at the time -- Polymorph. -////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/proc/remove_revolutionary(datum/mind/rev_mind, beingborged, activate_protection) - var/mob/revolutionary = rev_mind.current - var/remove_head = (beingborged && rev_mind.has_antag_datum(/datum/antagonist/rev/head)) - - if(rev_mind.has_antag_datum(/datum/antagonist/rev, FALSE) || remove_head) - // We have some custom text, lets make the removal silent - rev_mind.remove_antag_datum(/datum/antagonist/rev, silent_removal = TRUE) - - if(beingborged) - revolutionary.visible_message( - "The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.", - "The frame's firmware detects and deletes your neural reprogramming! You remember nothing[remove_head ? "." : " but the name of the one who flashed you."]") - message_admins("[key_name_admin(rev_mind.current)] [ADMIN_QUE(rev_mind.current,"?")] ([ADMIN_FLW(rev_mind.current,"FLW")]) has been borged while being a [remove_head ? "leader" : " member"] of the revolution.") - else - var/class = activate_protection ? "biggerdanger" : "userdanger" // biggerdanger only shows up when protection happens (usually in a red-flood of combat text) - revolutionary.visible_message( - "[rev_mind.current] looks like [rev_mind.current.p_they()] just remembered [rev_mind.current.p_their()] real allegiance!", - "You have been brainwashed! You are no longer a revolutionary! Your memory is hazy from the time you were a rebel... the only thing you remember is the name of the one who brainwashed you...") - rev_mind.current.Paralyse(10 SECONDS) - if(activate_protection && isliving(revolutionary)) - var/mob/living/living_rev = revolutionary - living_rev.apply_status_effect(STATUS_EFFECT_REVOLUTION_PROTECT) - return TRUE - -////////////////////////////////////////////////////////////////////// -//Announces the end of the game with all relavent information stated// -////////////////////////////////////////////////////////////////////// -/datum/game_mode/revolution/declare_completion() - if(finished == REV_VICTORY) - SSticker.mode_result = "revolution win - heads killed" - to_chat(world, "The heads of staff were killed or exiled! The revolutionaries win!") - else if(finished == STATION_VICTORY) - SSticker.mode_result = "revolution loss - rev heads killed" - to_chat(world, "The heads of staff managed to stop the revolution!") - ..() - return TRUE - -/datum/game_mode/proc/auto_declare_completion_revolution() - var/list/targets = list() - if(length(rev_team?.members) || GAMEMODE_IS_REVOLUTION) - var/num_revs = 0 - var/num_survivors = 0 - for(var/mob/living/carbon/human/survivor in GLOB.player_list) - if(!istype(survivor) || survivor.stat == DEAD) - continue - num_survivors++ - if(survivor.mind?.has_antag_datum(/datum/antagonist/rev)) - num_revs++ - if(num_survivors) - to_chat(world, "[TAB]Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%") // % of loyal crew - var/list/text = list("
    The head revolutionaries were:") - for(var/datum/mind/headrev in head_revolutionaries) - text += printplayer(headrev, 1) - text += "
    " - - // we dont show the revolutionaries because there are a LOT of them - - text = list("
    The heads of staff were:") - var/list/heads = get_all_heads() - for(var/datum/mind/head in heads) - var/target = (head in targets) - if(target) - text += "Target" - text += printplayer(head, 1) - text += "
    " - return text.Join("") - -/datum/game_mode/revolution/set_scoreboard_vars() // this proc is never called, someone remove it - var/datum/scoreboard/scoreboard = SSticker.score - var/foecount = 0 - - for(var/datum/mind/M in SSticker.mode.head_revolutionaries) - foecount++ - if(!M || !M.current) - scoreboard.score_ops_killed++ - continue - - if(M.current.stat == DEAD) - scoreboard.score_ops_killed++ - - else if(M.current.restrained()) - scoreboard.score_arrested++ - - if(foecount == scoreboard.score_arrested) - scoreboard.all_arrested = TRUE - - for(var/datum/mind/head_mind in get_all_heads()) - var/mob/living/carbon/human/H = head_mind.current - if(isnull(H) || H.stat == DEAD) - scoreboard.score_dead_command++ - - - var/arrestpoints = scoreboard.score_arrested * 1000 - var/killpoints = scoreboard.score_ops_killed * 500 - var/comdeadpts = scoreboard.score_dead_command * 500 - if(scoreboard.score_greentext) - scoreboard.crewscore -= 10000 - - scoreboard.crewscore += arrestpoints - scoreboard.crewscore += killpoints - scoreboard.crewscore -= comdeadpts - - -/datum/game_mode/revolution/get_scoreboard_stats() - var/datum/scoreboard/scoreboard = SSticker.score - var/foecount = 0 - var/comcount = 0 - var/revcount = 0 - var/loycount = 0 - for(var/datum/mind/M in SSticker.mode.head_revolutionaries) - if(M.current && M.current.stat != DEAD) - foecount++ - for(var/datum/mind/M in SSticker.mode.revolutionaries) - if(M.current && M.current.stat != DEAD) - revcount++ - - var/list/real_command_positions = GLOB.command_positions.Copy() - "Nanotrasen Representative" - for(var/mob/living/carbon/human/player in GLOB.human_list) - if(player.mind) - if(player.mind.assigned_role in real_command_positions) - if(player.stat != DEAD) - comcount++ - continue - if(player.mind.has_antag_datum(/datum/antagonist/rev)) - continue - loycount++ - - // we dont count silicons because well, they follow their laws, not the crew, and there is no easy way to tell if theyre subverted - - - var/dat = "" - - dat += "Mode Statistics
    " - dat += "Number of Surviving Revolution Heads: [foecount]
    " - dat += "Number of Surviving Command Staff: [comcount]
    " - dat += "Number of Surviving Revolutionaries: [revcount]
    " - dat += "Number of Surviving Loyal Crew: [loycount]
    " - - dat += "
    " - dat += "Revolution Heads Arrested: [scoreboard.score_arrested] ([scoreboard.score_arrested * 1000] Points)
    " - dat += "All Revolution Heads Arrested: [scoreboard.all_arrested ? "Yes" : "No"] (Score tripled)
    " - - dat += "Revolution Heads Slain: [scoreboard.score_ops_killed] ([scoreboard.score_ops_killed * 500] Points)
    " - dat += "Command Staff Slain: [scoreboard.score_dead_command] (-[scoreboard.score_dead_command * 500] Points)
    " - dat += "Revolution Successful: [scoreboard.score_greentext ? "Yes" : "No"] (-[scoreboard.score_greentext * 10000] Points)
    " - dat += "
    " - - return dat - -/proc/is_revolutionary(mob/living/M) - return istype(M) && M?.mind?.has_antag_datum(/datum/antagonist/rev, FALSE) - -/proc/is_headrev(mob/living/M) - return istype(M) && M?.mind?.has_antag_datum(/datum/antagonist/rev/head) - -/proc/is_any_revolutionary(mob/living/M) - return istype(M) && M?.mind?.has_antag_datum(/datum/antagonist/rev) - -#undef REV_VICTORY -#undef STATION_VICTORY diff --git a/code/game/gamemodes/steal_items.dm b/code/game/gamemodes/steal_items.dm deleted file mode 100644 index 5da86e51a2633..0000000000000 --- a/code/game/gamemodes/steal_items.dm +++ /dev/null @@ -1,209 +0,0 @@ -// Theft objectives. -// -// Separated into datums so we can prevent roles from getting certain objectives. - -/datum/theft_objective - var/name = "this objective is impossible, yell at a coder" - var/typepath=/obj/effect/debugging - var/list/protected_jobs = list() - var/list/altitems = list() - var/flags = 0 - var/location_override - /// Do we have a special item we give to somewhen when they get this objective? - var/special_equipment = null - /// If a steal objective has forbidden jobs, and the forbidden jobs would not be in the possession of this item, set this to false - var/job_possession = TRUE - /// Any extra information about the objective - var/extra_information = "" - -/datum/theft_objective/proc/check_completion(datum/mind/owner) - if(!owner.current) - return 0 - if(!isliving(owner.current)) - return 0 - var/list/all_items = owner.current.get_contents() - for(var/obj/I in all_items) //Check for items - if(istype(I, typepath) && check_special_completion(I)) - return 1 - return 0 - -//This proc is to be used for not granting objectives if a special requirement other than job is not met. - -/datum/theft_objective/proc/check_objective_conditions() - return TRUE - -/datum/proc/check_special_completion() //for objectives with special checks (is that slime extract unused? does that intellicard have an ai in it? etcetc) - return 1 - -/datum/theft_objective/antique_laser_gun - name = "the captain's antique laser gun" - typepath = /obj/item/gun/energy/laser/captain - protected_jobs = list("Captain") - location_override = "the Captain's Office" - -/datum/theft_objective/captains_modsuit - name = "the captain's Magnate MODsuit" - typepath = /obj/item/mod/control/pre_equipped/magnate - protected_jobs = list("Captain") - location_override = "the Captain's Office" - -/datum/theft_objective/captains_saber - name = "the captain's saber" - typepath = /obj/item/melee/saber - protected_jobs = list("Captain") - location_override = "the Captain's Office" - -/datum/theft_objective/hoslaser - name = "the head of security's X-01 multiphase energy gun" - typepath = /obj/item/gun/energy/gun/hos - protected_jobs = list("Head Of Security") - location_override = "the Head of Security's Office" - -/datum/theft_objective/hand_tele - name = "a hand teleporter" - typepath = /obj/item/hand_tele - protected_jobs = list("Captain", "Research Director", "Chief Engineer") - location_override = "the AI Satellite, or the Captain's Office" - -/datum/theft_objective/defib - name = "the chief medical officer's advanced compact defibrillator" - typepath = /obj/item/defibrillator/compact/advanced - protected_jobs = list("Chief Medical Officer", "Paramedic") - location_override = "the Chief Medical Officer's Office" - -/datum/theft_objective/magboots - name = "the chief engineer's advanced magnetic boots" - typepath = /obj/item/clothing/shoes/magboots/advance - protected_jobs = list("Chief Engineer") - location_override = "the Chief Engineer's Office" - -/datum/theft_objective/blueprints - name = "the station blueprints" - typepath = /obj/item/areaeditor/blueprints/ce - protected_jobs = list("Chief Engineer") - altitems = list(/obj/item/photo) - location_override = "the Chief Engineer's Office" - extra_information = "Obtaining a photograph of the blueprints is also an option." - -/datum/theft_objective/blueprints/check_special_completion(obj/item/I) - if(istype(I, /obj/item/areaeditor/blueprints/ce)) - return 1 - if(istype(I, /obj/item/photo)) - var/obj/item/photo/P = I - if(P.blueprints) - return 1 - return 0 - -/datum/theft_objective/capmedal - name = "the medal of captaincy" - typepath = /obj/item/clothing/accessory/medal/gold/captain - protected_jobs = list("Captain") - location_override = "the Captain's Office" - -/datum/theft_objective/nukedisc - name = "the nuclear authentication disk" - typepath = /obj/item/disk/nuclear - protected_jobs = list("Captain") - location_override = "the Captain's Office" - -/datum/theft_objective/nukedisc/check_special_completion(obj/item/I) - if(istype(I, /obj/item/disk/nuclear/training)) //Haha no - return FALSE - return TRUE - -/datum/theft_objective/reactive - name = "any type of reactive armor" - typepath = /obj/item/clothing/suit/armor/reactive - protected_jobs = list("Research Director", "Scientist", "Roboticist") //no one with protolathe access, who will often be handed a core - location_override = "the Research Director's Office" - -/datum/theft_objective/documents - name = "any set of secret documents of any organization" - typepath = /obj/item/documents //Any set of secret documents. Doesn't have to be NT's - location_override = "the Vault" - protected_jobs = list("Quartermaster") - job_possession = FALSE - -/datum/theft_objective/hypospray - name = "the chief medical officer's advanced hypospray" - typepath = /obj/item/reagent_containers/hypospray/cmo - protected_jobs = list("Chief Medical Officer") - location_override = "the Chief Medical Officer's Office" - -/datum/theft_objective/krav - name = "the warden's krav maga martial arts gloves" - typepath = /obj/item/clothing/gloves/color/black/krav_maga/sec - protected_jobs = list("Head Of Security", "Warden") - location_override = "the Warden's Office" - -/datum/theft_objective/supermatter_sliver - name = "a supermatter sliver" - typepath = /obj/item/nuke_core/supermatter_sliver - protected_jobs = list("Chief Engineer", "Station Engineer", "Life Support Specialist") //Unlike other steal objectives, all jobs in the department have easy access, and would not be noticed at all stealing this - location_override = "Engineering. You can use the box and instructions provided to harvest the sliver" - special_equipment = /obj/item/storage/box/syndie_kit/supermatter - job_possession = FALSE //The CE / engineers / atmos techs do not carry around supermater slivers. - -/datum/theft_objective/supermatter_sliver/check_objective_conditions() //If there is no supermatter, you don't get the objective. Yes, one could order it from cargo, but I don't think that is fair, especially if we get a map without a supermatter - return !isnull(GLOB.main_supermatter_engine) - -/datum/theft_objective/plutonium_core - name = "the plutonium core from the station's nuclear device" - typepath = /obj/item/nuke_core/plutonium - location_override = "the Vault. You can use the box and instructions provided to remove the core, with some extra tools" - special_equipment = /obj/item/storage/box/syndie_kit/nuke - protected_jobs = list("Quartermaster") - job_possession = FALSE - -/datum/theft_objective/engraved_dusters - name = "the quartermaster's engraved knuckledusters" - typepath = /obj/item/melee/knuckleduster/nanotrasen - protected_jobs = list("Quartermaster") - location_override = "the Quartermaster's Cargo Office" - -/datum/theft_objective/number - var/min=0 - var/max=0 - var/step=1 - - var/required_amount=0 - -/datum/theft_objective/number/New() - if(min==max) - required_amount=min - else - var/lower=min/step - var/upper=min/step - required_amount=rand(lower,upper)*step - name = "[required_amount] [name]" - -/datum/theft_objective/number/check_completion(datum/mind/owner) - if(!owner.current) - return 0 - if(!isliving(owner.current)) - return 0 - var/list/all_items = owner.current.get_contents() - var/found_amount=0.0 - for(var/obj/item/I in all_items) - if(istype(I, typepath)) - found_amount += getAmountStolen(I) - return found_amount >= required_amount - -/datum/theft_objective/number/proc/getAmountStolen(obj/item/I) - return I:amount - -/datum/theft_objective/unique - flags = THEFT_FLAG_UNIQUE - -/datum/theft_objective/unique/docs_red - name = "the \"Red\" secret documents" - typepath = /obj/item/documents/syndicate/red - location_override = "a Syndicate agent's possession" - -/datum/theft_objective/unique/docs_blue - name = "the \"Blue\" secret documents" - typepath = /obj/item/documents/syndicate/blue - location_override = "a Syndicate agent's possession" - -#undef THEFT_FLAG_SPECIAL -#undef THEFT_FLAG_UNIQUE diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm deleted file mode 100644 index 6ed1248aa9b40..0000000000000 --- a/code/game/gamemodes/traitor/traitor.dm +++ /dev/null @@ -1,172 +0,0 @@ -/datum/game_mode/traitor - name = "traitor" - config_tag = "traitor" - restricted_jobs = list("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", "Blueshield", "Nanotrasen Representative", "Magistrate", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Trans-Solar Federation General", "Nanotrasen Career Trainer") - required_players = 0 - required_enemies = 1 - recommended_enemies = 4 - /// Hard limit on traitors if scaling is turned off. - var/traitors_possible = 4 - /// How much the amount of players get divided by to determine the number of traitors. - var/const/traitor_scaling_coeff = 5 - -/datum/game_mode/traitor/announce() - to_chat(world, "The current game mode is - Traitor!") - to_chat(world, "There is a syndicate traitor on the station. Do not let the traitor succeed!") - -/datum/game_mode/traitor/pre_setup() - - if(GLOB.configuration.gamemode.prevent_mindshield_antags) - restricted_jobs += protected_jobs - - var/list/possible_traitors = get_players_for_role(ROLE_TRAITOR) - - for(var/datum/mind/candidate in possible_traitors) - if(candidate.special_role == SPECIAL_ROLE_VAMPIRE || candidate.special_role == SPECIAL_ROLE_CHANGELING || candidate.special_role == SPECIAL_ROLE_MIND_FLAYER) // no traitor vampires, changelings, or mindflayers - possible_traitors.Remove(candidate) - - // stop setup if no possible traitors - if(!length(possible_traitors)) - return FALSE - - var/num_traitors = 1 - - num_traitors = traitors_to_add() - - for(var/i in 1 to num_traitors) - if(!length(possible_traitors)) - break - var/datum/mind/traitor = pick_n_take(possible_traitors) - pre_traitors += traitor - traitor.special_role = SPECIAL_ROLE_TRAITOR - traitor.restricted_roles = restricted_jobs - - if(!length(pre_traitors)) - return FALSE - return TRUE - -/datum/game_mode/traitor/post_setup() - . = ..() - - var/random_time = rand(5 MINUTES, 15 MINUTES) - if(length(pre_traitors)) - addtimer(CALLBACK(src, PROC_REF(fill_antag_slots)), random_time) - - for(var/datum/mind/traitor in pre_traitors) - var/datum/antagonist/traitor/traitor_datum = new(src) - if(ishuman(traitor.current)) - traitor_datum.delayed_objectives = TRUE - traitor_datum.addtimer(CALLBACK(traitor_datum, TYPE_PROC_REF(/datum/antagonist/traitor, reveal_delayed_objectives)), random_time, TIMER_DELETE_ME) - - traitor.add_antag_datum(traitor_datum) - -/datum/game_mode/traitor/traitors_to_add() - if(GLOB.configuration.gamemode.traitor_scaling) - . = max(1, round(num_players() / traitor_scaling_coeff)) - else - . = max(1, min(num_players(), traitors_possible)) - - if(!length(traitors)) - return - - for(var/datum/mind/traitor_mind as anything in traitors) - if(!QDELETED(traitor_mind) && traitor_mind.current) // Explicitly no client check in case you happen to fall SSD when this gets ran - continue - .++ - traitors -= traitor_mind - -/datum/game_mode/traitor/declare_completion() - ..() - return//Traitors will be checked as part of check_extra_completion. Leaving this here as a reminder. - -/datum/game_mode/proc/auto_declare_completion_traitor() - if(length(traitors)) - var/list/text = list("The traitors were:
    ") - for(var/datum/mind/traitor in traitors) - var/traitorwin = TRUE - text += printplayer(traitor) - - var/TC_uses = 0 - var/used_uplink = FALSE - var/purchases = "" - for(var/obj/item/uplink/H in GLOB.world_uplinks) - if(H && H.uplink_owner && H.uplink_owner == traitor.key) - TC_uses += H.used_TC - used_uplink = TRUE - purchases += H.purchase_log - - if(used_uplink) - text += " (used [TC_uses] TC) [purchases]" - - var/all_objectives = traitor.get_all_objectives(include_team = FALSE) - - if(length(all_objectives))//If the traitor had no objectives, don't need to process this. - var/count = 1 - for(var/datum/objective/objective in all_objectives) - if(objective.check_completion()) - text += "
    Objective #[count]: [objective.explanation_text] Success!" - if(istype(objective, /datum/objective/steal)) - var/datum/objective/steal/S = objective - SSblackbox.record_feedback("nested tally", "traitor_steal_objective", 1, list("Steal [S.steal_target]", "SUCCESS")) - else - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "SUCCESS")) - else - text += "
    Objective #[count]: [objective.explanation_text] Fail." - if(istype(objective, /datum/objective/steal)) - var/datum/objective/steal/S = objective - SSblackbox.record_feedback("nested tally", "traitor_steal_objective", 1, list("Steal [S.steal_target]", "FAIL")) - else - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "FAIL")) - traitorwin = FALSE - count++ - - var/special_role_text - if(traitor.special_role) - special_role_text = lowertext(traitor.special_role) - else - special_role_text = "antagonist" - - var/datum/contractor_hub/H = LAZYACCESS(GLOB.contractors, traitor) - if(H) - var/count = 1 - var/earned_tc = H.reward_tc_paid_out - for(var/c in H.contracts) - var/datum/syndicate_contract/C = c - // Locations - var/locations = list() - for(var/a in C.contract.candidate_zones) - var/area/A = a - locations += (A == C.contract.extraction_zone ? "[A.map_name]" : A.map_name) - var/display_locations = english_list(locations, and_text = " or ") - // Result - var/result = "" - if(C.status == CONTRACT_STATUS_COMPLETED) - result = "Success!" - else if(C.status != CONTRACT_STATUS_INACTIVE) - result = "Fail." - text += "
    Contract #[count]: Kidnap and extract [C.target_name] at [display_locations]. [result]" - count++ - text += "
    [earned_tc] TC were earned from the contracts." - - if(traitorwin) - text += "
    The [special_role_text] was successful!
    " - SSblackbox.record_feedback("tally", "traitor_success", 1, "SUCCESS") - else - text += "
    The [special_role_text] has failed!
    " - SSblackbox.record_feedback("tally", "traitor_success", 1, "FAIL") - - if(length(SSticker.mode.implanted)) - text += "

    The mindslaves were:
    " - for(var/datum/mind/mindslave in SSticker.mode.implanted) - text += printplayer(mindslave) - var/datum/mind/master_mind = SSticker.mode.implanted[mindslave] - text += " (slaved by: [master_mind.current])
    " - - var/phrases = jointext(GLOB.syndicate_code_phrase, ", ") - var/responses = jointext(GLOB.syndicate_code_response, ", ") - - text += "

    The code phrases were: [phrases]
    \ - The code responses were: [responses]

    " - - return text.Join("") diff --git a/code/game/gamemodes/trifecta/trifecta.dm b/code/game/gamemodes/trifecta/trifecta.dm deleted file mode 100644 index 783de206c6bdb..0000000000000 --- a/code/game/gamemodes/trifecta/trifecta.dm +++ /dev/null @@ -1,150 +0,0 @@ -#define TOT_COST 5 -#define VAMP_COST 10 -#define CLING_COST 10 - - -/datum/game_mode/trifecta - name = "Trifecta" - config_tag = "trifecta" - protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Magistrate", "Internal Affairs Agent", "Nanotrasen Career Trainer", "Nanotrasen Navy Officer", "Special Operations Officer", "Trans-Solar Federation General", "Nanotrasen Career Trainer") - restricted_jobs = list("Cyborg") - secondary_restricted_jobs = list("AI") - required_players = 25 - required_enemies = 1 // how many of each type are required - recommended_enemies = 3 - species_to_mindflayer = list("Machine") - var/vampire_restricted_jobs = list("Chaplain") - var/amount_vamp = 1 - var/amount_cling = 1 - var/amount_tot = 1 - /// How many points did we get at roundstart - var/cost_at_roundstart - -/datum/game_mode/trifecta/announce() - to_chat(world, "The current game mode is - Trifecta") - to_chat(world, "Vampires, traitors, and changelings, oh my! Stay safe as these forces work to bring down the station.") - -/datum/game_mode/trifecta/pre_setup() - calculate_quantities() - cost_at_roundstart = num_players() - if(GLOB.configuration.gamemode.prevent_mindshield_antags) - restricted_jobs += protected_jobs - var/list/datum/mind/possible_vampires = get_players_for_role(ROLE_VAMPIRE) - - if(!length(possible_vampires)) - return FALSE - - for(var/datum/mind/vampire as anything in shuffle(possible_vampires)) - if(length(pre_vampires) >= amount_vamp) - break - vampire.restricted_roles = restricted_jobs + secondary_restricted_jobs + vampire_restricted_jobs - if(vampire.current.client.prefs.active_character.species in species_to_mindflayer) - pre_mindflayers += vampire - amount_vamp -= 1 //It's basically the same thing as incrementing pre_vampires - vampire.special_role = SPECIAL_ROLE_MIND_FLAYER - continue - pre_vampires += vampire - vampire.special_role = SPECIAL_ROLE_VAMPIRE - - //Vampires made, off to changelings - var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING) - - if(!length(possible_changelings)) - return FALSE - - for(var/datum/mind/changeling as anything in shuffle(possible_changelings)) - if(length(pre_changelings) >= amount_cling) - break - if(changeling.special_role == SPECIAL_ROLE_VAMPIRE || changeling.special_role == SPECIAL_ROLE_MIND_FLAYER) - continue - changeling.restricted_roles = (restricted_jobs + secondary_restricted_jobs) - if(changeling.current?.client?.prefs.active_character.species in species_to_mindflayer) - pre_mindflayers += changeling - amount_cling -= 1 - changeling.special_role = SPECIAL_ROLE_MIND_FLAYER - continue - pre_changelings += changeling - changeling.special_role = SPECIAL_ROLE_CHANGELING - - //And now traitors - var/list/datum/mind/possible_traitors = get_players_for_role(ROLE_TRAITOR) - - //stop setup if no possible traitors - if(!length(possible_traitors)) - return FALSE - - for(var/datum/mind/traitor as anything in shuffle(possible_traitors)) - if(length(pre_traitors) >= amount_tot) - break - if(traitor.special_role == SPECIAL_ROLE_VAMPIRE || traitor.special_role == SPECIAL_ROLE_CHANGELING || traitor.special_role == SPECIAL_ROLE_MIND_FLAYER) // no traitor vampires or changelings - continue - pre_traitors += traitor - traitor.special_role = SPECIAL_ROLE_TRAITOR - traitor.restricted_roles = restricted_jobs - - return TRUE - -/datum/game_mode/trifecta/proc/calculate_quantities() - var/points = num_players() - // So. to ensure that we had at least one vamp / changeling / traitor, I set the number of ammount to 1. I never subtracted points, leading to 25 players worth of antags added for free. Whoops. - points -= TOT_COST + VAMP_COST + CLING_COST - while(points > 0) - if(points < TOT_COST) - amount_tot++ - points = 0 - return - - switch(rand(1, 4)) - if(1 to 2) - amount_tot++ - points -= TOT_COST - if(3) - amount_vamp++ - points -= VAMP_COST - if(4) - amount_cling++ - points -= CLING_COST - -/datum/game_mode/trifecta/post_setup() - for(var/datum/mind/vampire as anything in pre_vampires) - vampire.add_antag_datum(/datum/antagonist/vampire) - - for(var/datum/mind/changeling as anything in pre_changelings) - changeling.add_antag_datum(/datum/antagonist/changeling) - - var/random_time - if(length(pre_traitors)) - random_time = rand(5 MINUTES, 15 MINUTES) - addtimer(CALLBACK(src, PROC_REF(fill_antag_slots)), random_time) - - for(var/datum/mind/traitor in pre_traitors) - var/datum/antagonist/traitor/traitor_datum = new(src) - if(ishuman(traitor.current)) - traitor_datum.delayed_objectives = TRUE - traitor_datum.addtimer(CALLBACK(traitor_datum, TYPE_PROC_REF(/datum/antagonist/traitor, reveal_delayed_objectives)), random_time, TIMER_DELETE_ME) - - traitor.add_antag_datum(traitor_datum) - - ..() - -/datum/game_mode/trifecta/traitors_to_add() - . = 0 - for(var/datum/mind/traitor_mind as anything in traitors) - if(!QDELETED(traitor_mind) && traitor_mind.current) // Explicitly no client check in case you happen to fall SSD when this gets ran - continue - .++ - traitors -= traitor_mind - - var/extra_points = num_players_started() - cost_at_roundstart - if(extra_points - TOT_COST < 0) - return 0 // Not enough new players to add extra tots - - while(extra_points) - .++ - if(extra_points < TOT_COST) // The leftover change is enough for us to buy another traitor with, what a deal! - return - extra_points -= TOT_COST - -#undef TOT_COST -#undef VAMP_COST -#undef CLING_COST diff --git a/code/game/gamemodes/vampire/vampire_chan.dm b/code/game/gamemodes/vampire/vampire_chan.dm deleted file mode 100644 index f0cd8300ccd68..0000000000000 --- a/code/game/gamemodes/vampire/vampire_chan.dm +++ /dev/null @@ -1,45 +0,0 @@ -/datum/game_mode/vampire/changeling - name = "vampire_changeling" - config_tag = "vampchan" - restricted_jobs = list("AI", "Cyborg") - protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Magistrate", "Chaplain", "Internal Affairs Agent", "Nanotrasen Career Trainer", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation General") - species_to_mindflayer = list("Machine") - required_players = 15 - required_enemies = 1 - recommended_enemies = 3 - secondary_enemies_scaling = 0.025 - vampire_penalty = 0.4 // Cut out 40% of the vampires since we'll replace some with changelings - -/datum/game_mode/vampire/changeling/pre_setup() - if(GLOB.configuration.gamemode.prevent_mindshield_antags) - restricted_jobs += protected_jobs - - var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING) - secondary_enemies = CEILING((secondary_enemies_scaling * num_players()), 1) - - if(!length(possible_changelings)) - return ..() - - for(var/I in possible_changelings) - if(length(pre_changelings) >= secondary_enemies) - break - var/datum/mind/changeling = pick_n_take(possible_changelings) - changeling.restricted_roles = (restricted_jobs + secondary_restricted_jobs) - if(changeling.current?.client?.prefs.active_character.species in species_to_mindflayer) - pre_mindflayers += changeling - secondary_enemies -= 1 // Again, since we aren't increasing pre_changeling we'll just decrement what it's compared to. - changeling.special_role = SPECIAL_ROLE_MIND_FLAYER - continue - pre_changelings += changeling - changeling.special_role = SPECIAL_ROLE_CHANGELING - - return ..() - -/datum/game_mode/vampire/announce() - to_chat(world, "The current game mode is - Vampires+Changelings!") - to_chat(world, "Some of your co-workers are vampires, and others might not even be your coworkers!") - -/datum/game_mode/vampire/changeling/post_setup() - for(var/datum/mind/changeling as anything in pre_changelings) - changeling.add_antag_datum(/datum/antagonist/changeling) - ..() diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm deleted file mode 100644 index e4f6698fe3060..0000000000000 --- a/code/game/gamemodes/wizard/artefact.dm +++ /dev/null @@ -1,971 +0,0 @@ -/////////Apprentice Contract////////// - -/obj/item/contract - name = "contract" - desc = "A magic contract previously signed by an apprentice. In exchange for instruction in the magical arts, they are bound to answer your call for aid." - icon = 'icons/obj/wizard.dmi' - icon_state ="scroll2" - throw_speed = 1 - throw_range = 5 - w_class = WEIGHT_CLASS_TINY - var/used = FALSE - -/obj/item/contract/ui_state(mob/user) - return GLOB.inventory_state - -/obj/item/contract/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "WizardApprenticeContract", name) - ui.open() - -/obj/item/contract/ui_data(mob/user) - var/list/data = list() - data["used"] = used - return data - -/obj/item/contract/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - if(..()) - return - - if(used) - return - INVOKE_ASYNC(src, PROC_REF(async_find_apprentice), action, ui.user) - SStgui.close_uis(src) - -/obj/item/contract/proc/async_find_apprentice(action, user) - if(!ishuman(user)) - return - var/mob/living/carbon/human/H = user - used = TRUE - - var/image/source = image('icons/obj/cardboard_cutout.dmi', "cutout_wizard") - var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as the wizard apprentice of [H.real_name]?", ROLE_WIZARD, TRUE, source = source) - - if(!length(candidates)) - used = FALSE - to_chat(H, "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.") - return - new /obj/effect/particle_effect/smoke(get_turf(H)) - - var/mob/C = pick(candidates) - var/mob/living/carbon/human/M = new /mob/living/carbon/human(get_turf(H)) - M.key = C.key - - var/datum/antagonist/wizard/apprentice/apprentice = new /datum/antagonist/wizard/apprentice() - apprentice.my_teacher = H - apprentice.class_type = action - M.mind.add_antag_datum(apprentice) - - dust_if_respawnable(C) - -/obj/item/contract/attack_self__legacy__attackchain(mob/user as mob) - if(..()) - return - - if(used) - to_chat(user, "You've already summoned an apprentice or you are in process of summoning one.") - return - - ui_interact(user) - - -///////////////////////////Veil Render////////////////////// - -/obj/item/veilrender - name = "veil render" - desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast city." - icon = 'icons/obj/wizard.dmi' - icon_state = "render" - item_state = "render" - force = 15 - throwforce = 10 - w_class = WEIGHT_CLASS_NORMAL - hitsound = 'sound/weapons/bladeslice.ogg' - var/charged = 1 - var/spawn_type = /obj/singularity/narsie/wizard - var/spawn_amt = 1 - var/activate_descriptor = "reality" - var/rend_desc = "You should run now." - -/obj/item/veilrender/attack_self__legacy__attackchain(mob/user as mob) - if(charged) - new /obj/effect/rend(get_turf(user), spawn_type, spawn_amt, rend_desc) - charged = 0 - user.visible_message("[src] hums with power as [user] deals a blow to [activate_descriptor] itself!") - else - to_chat(user, "The unearthly energies that powered the blade are now dormant.") - - -/obj/effect/rend - name = "tear in the fabric of reality" - desc = "You should run now." - icon = 'icons/obj/biomass.dmi' - icon_state = "rift" - density = TRUE - anchored = TRUE - var/spawn_path = /mob/living/simple_animal/cow //defaulty cows to prevent unintentional narsies - var/spawn_amt_left = 20 - -/obj/effect/rend/New(loc, spawn_type, spawn_amt, desc) - ..() - src.spawn_path = spawn_type - src.spawn_amt_left = spawn_amt - src.desc = desc - - START_PROCESSING(SSobj, src) - //return - -/obj/effect/rend/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/effect/rend/process() - for(var/mob/M in loc) - return - new spawn_path(loc) - spawn_amt_left-- - if(spawn_amt_left <= 0) - qdel(src) - -/obj/effect/rend/attackby__legacy__attackchain(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/nullrod)) - user.visible_message("[user] seals \the [src] with \the [I].") - qdel(src) - return - return ..() - -/obj/effect/rend/singularity_pull() - return - -/obj/item/veilrender/vealrender - name = "veal render" - desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast farm." - spawn_type = /mob/living/simple_animal/cow - spawn_amt = 20 - activate_descriptor = "hunger" - rend_desc = "Reverberates with the sound of ten thousand moos." - -/obj/item/veilrender/honkrender - name = "honk render" - desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast circus." - spawn_type = /mob/living/simple_animal/hostile/retaliate/clown - spawn_amt = 10 - activate_descriptor = "depression" - rend_desc = "Gently wafting with the sounds of endless laughter." - icon_state = "clownrender" - - -/obj/item/veilrender/crabrender - name = "crab render" - desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast aquarium." - spawn_type = /mob/living/simple_animal/crab - spawn_amt = 10 - activate_descriptor = "sea life" - rend_desc = "Gently wafting with the sounds of endless clacking." - -/////////////////////////////////////////Scrying/////////////////// - -/obj/item/scrying - name = "scrying orb" - desc = "An incandescent orb of otherworldly energy, staring into it gives you vision beyond mortal means. Also works well as a throwing weapon." - icon = 'icons/obj/wizard.dmi' - icon_state ="scrying_orb" - throw_speed = 7 - throw_range = 15 - throwforce = 25 - damtype = BURN - force = 15 - hitsound = 'sound/items/welder2.ogg' - var/mob/current_owner - var/mob/dead/observer/ghost // owners ghost when active - -/obj/item/scrying/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - AddComponent(/datum/component/boomerang, throw_range, TRUE) - -/obj/item/scrying/Destroy() - STOP_PROCESSING(SSobj, src) - current_owner = null - return ..() - -/obj/item/scrying/process() - var/mob/holder = get(loc, /mob) - if(current_owner && current_owner != holder) - - to_chat(current_owner, "Your otherworldly vision fades...") - - REMOVE_TRAIT(current_owner, TRAIT_XRAY_VISION, SCRYING_ORB) - REMOVE_TRAIT(current_owner, TRAIT_NIGHT_VISION, SCRYING_ORB) - current_owner.update_sight() - current_owner.update_icons() - - current_owner = null - - if(!current_owner && holder) - current_owner = holder - - to_chat(current_owner, "You can see...everything!") - - ADD_TRAIT(current_owner, TRAIT_XRAY_VISION, SCRYING_ORB) - ADD_TRAIT(current_owner, TRAIT_NIGHT_VISION, SCRYING_ORB) - current_owner.update_sight() - current_owner.update_icons() - -/obj/item/scrying/attack_self__legacy__attackchain(mob/user as mob) - if(in_use) - return - in_use = TRUE - ADD_TRAIT(user, SCRYING, SCRYING_ORB) - user.visible_message("[user] stares into [src], [user.p_their()] eyes glazing over.", - "You stare into [src], you can see the entire universe!") - ghost = user.ghostize(TRUE, COLOR_BLUE, "Magic Spirit of [user.name]") - while(!QDELETED(user)) - if(user.key || QDELETED(src)) - user.visible_message("[user] blinks, returning to the world around [user.p_them()].", - "You look away from [src].") - break - if(user.get_active_hand() != src) - user.grab_ghost() - user.visible_message("[user]'s focus is forced away from [src].", - "Your vision is ripped away from [src].") - break - sleep(5) - in_use = FALSE - if(QDELETED(user)) - return - user.remove_atom_colour(ADMIN_COLOUR_PRIORITY, COLOR_BLUE) - REMOVE_TRAIT(user, SCRYING, SCRYING_ORB) - -/obj/item/scrying/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - . = ..() - if(!ishuman(hit_atom) || !throwingdatum || iswizard(hit_atom)) - return - var/mob/living/carbon/human/crushee = hit_atom - var/zone = ran_zone(throwingdatum.target_zone) // Base 80% to hit the zone you're aiming for - var/obj/item/organ/external/hit_limb = crushee.get_organ(zone) - if(hit_limb) - hit_limb.fracture() - - -/////////////////////Multiverse Blade//////////////////// -GLOBAL_LIST_EMPTY(multiverse) - -/obj/item/multisword - name = "multiverse sword" - desc = "A weapon capable of conquering the universe and beyond. Activate it to summon copies of yourself from others dimensions to fight by your side." - icon = 'icons/obj/weapons/energy_melee.dmi' - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon_state = "energy_katana" - item_state = "energy_katana" - hitsound = 'sound/weapons/bladeslice.ogg' - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - force = 20 - throwforce = 10 - sharp = TRUE - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - var/faction = list("unassigned") - var/cooldown = 0 - var/cooldown_between_uses = 400 //time in deciseconds between uses--default of 40 seconds. - var/assigned = "unassigned" - var/evil = TRUE - var/probability_evil = 30 //what's the probability this sword will be evil when activated? - var/duplicate_self = 0 //Do we want the species randomized along with equipment should the user be duplicated in their entirety? - var/sword_type = /obj/item/multisword //type of sword to equip. - -/obj/item/multisword/New() - ..() - GLOB.multiverse |= src - - -/obj/item/multisword/Destroy() - GLOB.multiverse.Remove(src) - return ..() - -/obj/item/multisword/attack__legacy__attackchain(mob/living/M as mob, mob/living/user as mob) //to prevent accidental friendly fire or out and out grief. - if(M.real_name == user.real_name) - to_chat(user, "[src] detects benevolent energies in your target and redirects your attack!") - return - ..() - -/obj/item/multisword/attack_self__legacy__attackchain(mob/user) - if(user.mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE) - to_chat(user, "You know better than to touch your teacher's stuff.") - return - if(cooldown < world.time) - var/faction_check = 0 - for(var/F in faction) - if(F in user.faction) - faction_check = 1 - break - if(faction_check == 0) - faction = list("[user.real_name]") - assigned = "[user.real_name]" - user.faction = list("[user.real_name]") - to_chat(user, "You bind the sword to yourself. You can now use it to summon help.") - if(!usr.mind.special_role) - if(prob(probability_evil)) - to_chat(user, "With your new found power you could easily conquer the station!") - - var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone - hijack_objective.explanation_text = "Ensure only [usr.real_name] and [usr.p_their()] copies are on the shuttle!" - usr.mind.add_mind_objective(hijack_objective) - var/list/messages = user.mind.prepare_announce_objectives(FALSE) - to_chat(user, chat_box_red(messages.Join("
    "))) - - SSticker.mode.traitors += usr.mind - usr.mind.special_role = "[usr.real_name] Prime" - evil = TRUE - else - to_chat(user, "With your new found power you could easily defend the station!") - - var/datum/objective/survive/new_objective = new /datum/objective/survive - new_objective.explanation_text = "Survive, and help defend the innocent from the mobs of multiverse clones." - usr.mind.add_mind_objective(new_objective) - var/list/messages = user.mind.prepare_announce_objectives(FALSE) - to_chat(user, chat_box_red(messages.Join("
    "))) - - SSticker.mode.traitors += usr.mind - usr.mind.special_role = "[usr.real_name] Prime" - evil = FALSE - else - cooldown = world.time + cooldown_between_uses - for(var/obj/item/multisword/M in GLOB.multiverse) - if(M.assigned == assigned) - M.cooldown = cooldown - - var/image/source = image('icons/obj/cardboard_cutout.dmi', "cutout_wizard") - var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as the wizard apprentice of [user.real_name]?", ROLE_WIZARD, TRUE, 10 SECONDS, source = source) - if(length(candidates)) - var/mob/C = pick(candidates) - spawn_copy(C.client, get_turf(user.loc), user) - to_chat(user, "The sword flashes, and you find yourself face to face with...you!") - dust_if_respawnable(C) - - else - to_chat(user, "You fail to summon any copies of yourself. Perhaps you should try again in a bit.") - else - to_chat(user, "[src] is recharging! Keep in mind it shares a cooldown with the swords wielded by your copies.") - - -/obj/item/multisword/proc/spawn_copy(client/C, turf/T, mob/user) - var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) - if(duplicate_self) - user.client.prefs.active_character.copy_to(M) - else - C.prefs.active_character.copy_to(M) - M.key = C.key - M.mind.name = user.real_name - to_chat(M, "You are an alternate version of [user.real_name] from another universe! Help [user.p_them()] accomplish [user.p_their()] goals at all costs.") - M.faction = list("[user.real_name]") - if(duplicate_self) - M.set_species(user.dna.species.type) //duplicate the sword user's species. - else - if(prob(50)) - var/list/list_all_species = list(/datum/species/human, /datum/species/unathi, /datum/species/skrell, /datum/species/tajaran, /datum/species/kidan, /datum/species/golem, /datum/species/diona, /datum/species/machine, /datum/species/slime, /datum/species/grey, /datum/species/vulpkanin) - M.set_species(pick(list_all_species)) - M.real_name = user.real_name //this is clear down here in case the user happens to become a golem; that way they have the proper name. - M.name = user.real_name - if(duplicate_self) - M.dna = user.dna.Clone() - M.UpdateAppearance() - domutcheck(M) - M.update_body() - M.update_hair() - M.update_fhair() - - equip_copy(M) - - if(evil) - var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone - hijack_objective.explanation_text = "Ensure only [usr.real_name] and [usr.p_their()] copies are on the shuttle!" - M.mind.add_mind_objective(hijack_objective) - var/list/messages = M.mind.prepare_announce_objectives(FALSE) - to_chat(M, chat_box_red(messages.Join("
    "))) - - M.mind.special_role = SPECIAL_ROLE_MULTIVERSE - log_game("[M.key] was made a multiverse traveller with the objective to help [usr.real_name] hijack.") - else - var/datum/objective/protect/new_objective = new /datum/objective/protect - new_objective.target = usr.mind - new_objective.explanation_text = "Protect [usr.real_name], your copy, and help [usr.p_them()] defend the innocent from the mobs of multiverse clones." - M.mind.add_mind_objective(new_objective) - var/list/messages = M.mind.prepare_announce_objectives(FALSE) - to_chat(M, chat_box_red(messages.Join("
    "))) - - M.mind.special_role = SPECIAL_ROLE_MULTIVERSE - log_game("[M.key] was made a multiverse traveller with the objective to help [usr.real_name] protect the station.") - -/obj/item/multisword/proc/equip_copy(mob/living/carbon/human/M) - - var/obj/item/multisword/sword = new sword_type - sword.assigned = assigned - sword.faction = list("[assigned]") - sword.evil = evil - - if(duplicate_self) - //Duplicates the user's current equipent - var/mob/living/carbon/human/H = usr - - var/obj/head = H.get_item_by_slot(ITEM_SLOT_HEAD) - if(head) - M.equip_to_slot_or_del(new head.type(M), ITEM_SLOT_HEAD) - - var/obj/mask = H.get_item_by_slot(ITEM_SLOT_MASK) - if(mask) - M.equip_to_slot_or_del(new mask.type(M), ITEM_SLOT_MASK) - - var/obj/glasses = H.get_item_by_slot(ITEM_SLOT_EYES) - if(glasses) - M.equip_to_slot_or_del(new glasses.type(M), ITEM_SLOT_EYES) - - var/obj/left_ear = H.get_item_by_slot(ITEM_SLOT_LEFT_EAR) - if(left_ear) - M.equip_to_slot_or_del(new left_ear.type(M), ITEM_SLOT_LEFT_EAR) - - var/obj/right_ear = H.get_item_by_slot(ITEM_SLOT_RIGHT_EAR) - if(right_ear) - M.equip_to_slot_or_del(new right_ear.type(M), ITEM_SLOT_RIGHT_EAR) - - var/obj/uniform = H.get_item_by_slot(ITEM_SLOT_JUMPSUIT) - if(uniform) - M.equip_to_slot_or_del(new uniform.type(M), ITEM_SLOT_JUMPSUIT) - - var/obj/suit = H.get_item_by_slot(ITEM_SLOT_OUTER_SUIT) - if(suit) - M.equip_to_slot_or_del(new suit.type(M), ITEM_SLOT_OUTER_SUIT) - - var/obj/gloves = H.get_item_by_slot(ITEM_SLOT_GLOVES) - if(gloves) - M.equip_to_slot_or_del(new gloves.type(M), ITEM_SLOT_GLOVES) - - var/obj/shoes = H.get_item_by_slot(ITEM_SLOT_SHOES) - if(shoes) - M.equip_to_slot_or_del(new shoes.type(M), ITEM_SLOT_SHOES) - - var/obj/belt = H.get_item_by_slot(ITEM_SLOT_BELT) - if(belt) - M.equip_to_slot_or_del(new belt.type(M), ITEM_SLOT_BELT) - - var/obj/pda = H.get_item_by_slot(ITEM_SLOT_PDA) - if(pda) - M.equip_to_slot_or_del(new pda.type(M), ITEM_SLOT_PDA) - - var/obj/back = H.get_item_by_slot(ITEM_SLOT_BACK) - if(back) - M.equip_to_slot_or_del(new back.type(M), ITEM_SLOT_BACK) - - var/obj/suit_storage = H.get_item_by_slot(ITEM_SLOT_SUIT_STORE) - if(suit_storage) - M.equip_to_slot_or_del(new suit_storage.type(M), ITEM_SLOT_SUIT_STORE) - - var/obj/left_pocket = H.get_item_by_slot(ITEM_SLOT_LEFT_POCKET) - if(left_pocket) - M.equip_to_slot_or_del(new left_pocket.type(M), ITEM_SLOT_LEFT_POCKET) - - var/obj/right_pocket = H.get_item_by_slot(ITEM_SLOT_RIGHT_POCKET) - if(right_pocket) - M.equip_to_slot_or_del(new right_pocket.type(M), ITEM_SLOT_RIGHT_POCKET) - - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) //Don't duplicate what's equipped to hands, or else duplicate swords could be generated...or weird cases of factionless swords. - else - if(istajaran(M) || isunathi(M)) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), ITEM_SLOT_SHOES) //If they can't wear shoes, give them a pair of sandals. - - var/randomize = pick("mobster","roman","wizard","cyborg","syndicate","assistant", "animu", "cultist", "highlander", "clown", "killer", "pirate", "soviet", "officer", "gladiator") - - switch(randomize) - if("mobster") - M.equip_to_slot_or_del(new /obj/item/clothing/head/fedora(M), ITEM_SLOT_HEAD) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), ITEM_SLOT_GLOVES) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), ITEM_SLOT_EYES) - M.equip_to_slot_or_del(new /obj/item/clothing/under/suit/really_black(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("roman") - var/hat = pick(/obj/item/clothing/head/helmet/roman, /obj/item/clothing/head/helmet/roman/legionaire) - M.equip_to_slot_or_del(new hat(M), ITEM_SLOT_HEAD) - M.equip_to_slot_or_del(new /obj/item/clothing/under/costume/roman(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/roman(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(new /obj/item/shield/riot/roman(M), ITEM_SLOT_LEFT_HAND) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("wizard") - M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/red(M), ITEM_SLOT_OUTER_SUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/red(M), ITEM_SLOT_HEAD) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("cyborg") - if(!ismachineperson(M)) - for(var/obj/item/organ/O in M.bodyparts) - O.robotize(make_tough = 1) - M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), ITEM_SLOT_EYES) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("syndicate") - M.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), ITEM_SLOT_GLOVES) - M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/swat(M), ITEM_SLOT_HEAD) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(M), ITEM_SLOT_OUTER_SUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(M),ITEM_SLOT_MASK) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("assistant") - M.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("animu") - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(new /obj/item/clothing/head/kitty(M), ITEM_SLOT_HEAD) - M.equip_to_slot_or_del(new /obj/item/clothing/under/dress/schoolgirl(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("cultist") - M.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/cultrobes/alt(M), ITEM_SLOT_OUTER_SUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("highlander") - M.equip_to_slot_or_del(new /obj/item/clothing/under/costume/kilt(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(new /obj/item/clothing/head/beret(M), ITEM_SLOT_HEAD) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("clown") - M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/civilian/clown(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(M), ITEM_SLOT_MASK) - M.equip_to_slot_or_del(new /obj/item/bikehorn(M), ITEM_SLOT_LEFT_POCKET) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("killer") - M.equip_to_slot_or_del(new /obj/item/clothing/under/misc/overalls(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/latex(M), ITEM_SLOT_GLOVES) - M.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(M), ITEM_SLOT_MASK) - M.equip_to_slot_or_del(new /obj/item/clothing/head/welding(M), ITEM_SLOT_HEAD) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(new /obj/item/clothing/suit/apron(M), ITEM_SLOT_OUTER_SUIT) - M.equip_to_slot_or_del(new /obj/item/kitchen/knife(M), ITEM_SLOT_LEFT_POCKET) - M.equip_to_slot_or_del(new /obj/item/scalpel(M), ITEM_SLOT_RIGHT_POCKET) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - for(var/obj/item/carried_item in M.contents) - if(!istype(carried_item, /obj/item/bio_chip)) - carried_item.add_mob_blood(M) - - if("pirate") - M.equip_to_slot_or_del(new /obj/item/clothing/under/costume/pirate(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(new /obj/item/clothing/head/bandana(M), ITEM_SLOT_HEAD) - M.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(M), ITEM_SLOT_EYES) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("soviet") - M.equip_to_slot_or_del(new /obj/item/clothing/head/sovietofficerhat(M), ITEM_SLOT_HEAD) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), ITEM_SLOT_GLOVES) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(new /obj/item/clothing/suit/sovietcoat(M), ITEM_SLOT_OUTER_SUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/under/new_soviet/sovietofficer(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("officer") - M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), ITEM_SLOT_HEAD) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), ITEM_SLOT_GLOVES) - M.equip_to_slot_or_del(new /obj/item/clothing/mask/cigarette/cigar/havana(M), ITEM_SLOT_MASK) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(new /obj/item/clothing/suit/jacket/miljacket(M), ITEM_SLOT_OUTER_SUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(M), ITEM_SLOT_EYES) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - if("gladiator") - M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/gladiator(M), ITEM_SLOT_HEAD) - M.equip_to_slot_or_del(new /obj/item/clothing/under/costume/gladiator(M), ITEM_SLOT_JUMPSUIT) - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), ITEM_SLOT_LEFT_EAR) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), ITEM_SLOT_SHOES) - M.equip_to_slot_or_del(sword, ITEM_SLOT_RIGHT_HAND) - - - else - return - - var/obj/item/card/id/W = new /obj/item/card/id - if(duplicate_self) - var/duplicated_access = usr.get_item_by_slot(ITEM_SLOT_ID) - if(duplicated_access && istype(duplicated_access, /obj/item/card/id)) - var/obj/item/card/id/duplicated_id = duplicated_access - W.access = duplicated_id.access - W.icon_state = duplicated_id.icon_state - else - W.access += ACCESS_MAINT_TUNNELS - W.icon_state = "centcom" - else - W.access += ACCESS_MAINT_TUNNELS - W.icon_state = "centcom" - W.assignment = "Multiverse Traveller" - W.registered_name = M.real_name - W.update_label(M.real_name) - W.SetOwnerInfo(M) - M.equip_to_slot_or_del(W, ITEM_SLOT_ID) - - if(isvox(M)) - M.dna.species.after_equip_job(null, M) //Nitrogen tanks - if(isplasmaman(M)) - M.dna.species.after_equip_job(null, M) //No fireballs from other dimensions. - - M.update_icons() - -/obj/item/multisword/pure_evil - probability_evil = 100 - -/// If We are to be used and spent, let it be for a noble purpose. -/obj/item/multisword/pike - name = "phantom pike" - desc = "A fishing pike that appears to be imbued with a peculiar energy." - icon = 'icons/obj/weapons/melee.dmi' - icon_state = "harpoon" - item_state = "harpoon" - cooldown_between_uses = 200 //Half the time - probability_evil = 100 - duplicate_self = 1 - sword_type = /obj/item/multisword/pike - - -/////////////////////////////////////////Necromantic Stone/////////////////// - -/obj/item/necromantic_stone - name = "necromantic stone" - desc = "A shard capable of resurrecting humans as skeleton thralls." - icon = 'icons/obj/wizard.dmi' - icon_state = "necrostone" - item_state = "electronic" - origin_tech = "bluespace=4;materials=4" - w_class = WEIGHT_CLASS_TINY - ///List of mobs transformed into skeletons by the stone - var/list/active_skeletons = list() - ///How many skeletons can be converted by the stone at a time - var/max_skeletons = 3 - ///If the stone can convert infinite skeletons, bypassing max_skeletons - var/unlimited = FALSE - ///If the stone converts into anime instead of skeletons - var/heresy = FALSE - ///how long the additional_thralls_cooldown is - var/above_cap_cooldown = 1 MINUTES - ///Cooldown between uses when living skeletons above max skeletons - COOLDOWN_DECLARE(additional_thralls_cooldown) - -/obj/item/necromantic_stone/Destroy() - . = ..() - active_skeletons = null - -/obj/item/necromantic_stone/examine(mob/user) - . = ..() - var/skele_count = length(active_skeletons) - if(skele_count) - . += "[skele_count] skeleton thrall[skele_count > 1 ? "s have" : " has"] been risen by [src]." - if(unlimited || skele_count < max_skeletons) - return - var/cooldown_time_left = COOLDOWN_TIMELEFT(src, additional_thralls_cooldown) - if(cooldown_time_left) - . += "[src] is being strained by the amount of risen skeletons thralls. It cannot be used to rise another skeleton thrall for [cooldown_time_left / 10] seconds." - -/obj/item/necromantic_stone/attack__legacy__attackchain(mob/living/carbon/human/victim, mob/living/carbon/human/necromancer) - if(!istype(victim) || !istype(necromancer)) - return ..() - - - if(victim.stat != DEAD) - to_chat(necromancer, "This artifact can only affect the dead!") - return - - if((!victim.mind || !victim.client) && !victim.grab_ghost()) - to_chat(necromancer, "There is no soul connected to this body...") - return - - if(!check_skeletons()) //If above the cap, there is a cooldown on additional skeletons - to_chat(necromancer, "The amount of skeleton thralls risen by [src] strains its power.") - if(!COOLDOWN_FINISHED(src, additional_thralls_cooldown)) - to_chat(necromancer, "[src] cannot rise another thrall for [DisplayTimeText(COOLDOWN_TIMELEFT(src, additional_thralls_cooldown))].") - return - COOLDOWN_START(src, additional_thralls_cooldown, above_cap_cooldown) - - convert_victim(victim, necromancer) - -///Mindslave and equip the victim -/obj/item/necromantic_stone/proc/convert_victim(mob/living/carbon/human/victim, mob/living/carbon/human/necromancer) - active_skeletons |= victim - var/greet_text = "You have been revived by [necromancer.real_name]!\n[necromancer.p_theyre(TRUE)] your master now, assist them even if it costs you your new life!" - if(!victim.mind.has_antag_datum(/datum/antagonist/mindslave/necromancy)) - victim.mind.add_antag_datum(new /datum/antagonist/mindslave/necromancy(necromancer.mind, greet_text)) - - if(heresy) - equip_heresy(victim)//oh god why - return - - victim.visible_message("A massive amount of flesh sloughs off [victim] and a skeleton rises up!") - equip_skeleton(victim) - -///Clean the list of active skeletons and check if more can be summoned easily -/obj/item/necromantic_stone/proc/check_skeletons() - . = FALSE - if(unlimited) - return TRUE - - listclearnulls(active_skeletons) - var/living_skeletons = 0 - for(var/mob/living/carbon/human/skeleton as anything in active_skeletons) - if(!ishuman(skeleton)) - active_skeletons.Remove(skeleton) - continue - if(skeleton.stat != DEAD) - living_skeletons++ - - if(living_skeletons < max_skeletons) - return TRUE - -//Funny gimmick, skeletons always seem to wear roman/ancient armour -//Voodoo Zombie Pirates added for paradise -///Udate the mobs species and gear -/obj/item/necromantic_stone/proc/equip_skeleton(mob/living/carbon/human/victim) - victim.set_species(/datum/species/skeleton) // OP skellybones - victim.grab_ghost() // yoinks the ghost if its not in the body - victim.revive() - - for(var/obj/item/item in victim) - victim.drop_item_to_ground(item) - - var/skeleton_type = pick("roman", "pirate", "yand", "clown") - - switch(skeleton_type) - if("roman") - var/hat = pick(/obj/item/clothing/head/helmet/roman, /obj/item/clothing/head/helmet/roman/legionaire) - victim.equip_to_slot_or_del(new hat(victim), ITEM_SLOT_HEAD) - victim.equip_to_slot_or_del(new /obj/item/clothing/under/costume/roman(victim), ITEM_SLOT_JUMPSUIT) - victim.equip_to_slot_or_del(new /obj/item/clothing/shoes/roman(victim), ITEM_SLOT_SHOES) - victim.equip_to_slot_or_del(new /obj/item/shield/riot/roman(victim), ITEM_SLOT_LEFT_HAND) - victim.equip_to_slot_or_del(new /obj/item/claymore(victim), ITEM_SLOT_RIGHT_HAND) - victim.equip_to_slot_or_del(new /obj/item/spear(victim), ITEM_SLOT_BACK) - if("pirate") - victim.equip_to_slot_or_del(new /obj/item/clothing/under/costume/pirate(victim), ITEM_SLOT_JUMPSUIT) - victim.equip_to_slot_or_del(new /obj/item/clothing/suit/pirate_brown(victim), ITEM_SLOT_OUTER_SUIT) - victim.equip_to_slot_or_del(new /obj/item/clothing/head/bandana(victim), ITEM_SLOT_HEAD) - victim.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(victim), ITEM_SLOT_SHOES) - victim.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(victim), ITEM_SLOT_EYES) - victim.equip_to_slot_or_del(new /obj/item/claymore(victim), ITEM_SLOT_RIGHT_HAND) - victim.equip_to_slot_or_del(new /obj/item/spear(victim), ITEM_SLOT_BACK) - victim.equip_to_slot_or_del(new /obj/item/shield/riot/roman(victim), ITEM_SLOT_LEFT_HAND) - if("yand")//mine is an evil laugh - victim.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(victim), ITEM_SLOT_SHOES) - victim.equip_to_slot_or_del(new /obj/item/clothing/head/kitty(victim), ITEM_SLOT_HEAD) - victim.equip_to_slot_or_del(new /obj/item/clothing/under/dress/schoolgirl(victim), ITEM_SLOT_JUMPSUIT) - victim.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(victim), ITEM_SLOT_OUTER_SUIT) - victim.equip_to_slot_or_del(new /obj/item/katana(victim), ITEM_SLOT_RIGHT_HAND) - victim.equip_to_slot_or_del(new /obj/item/shield/riot/roman(victim), ITEM_SLOT_LEFT_HAND) - victim.equip_to_slot_or_del(new /obj/item/spear(victim), ITEM_SLOT_BACK) - if("clown") - victim.equip_to_slot_or_del(new /obj/item/clothing/under/rank/civilian/clown(victim), ITEM_SLOT_JUMPSUIT) - victim.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes(victim), ITEM_SLOT_SHOES) - victim.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(victim), ITEM_SLOT_MASK) - victim.equip_to_slot_or_del(new /obj/item/clothing/head/stalhelm(victim), ITEM_SLOT_HEAD) - victim.equip_to_slot_or_del(new /obj/item/bikehorn(victim), ITEM_SLOT_LEFT_POCKET) - victim.equip_to_slot_or_del(new /obj/item/claymore(victim), ITEM_SLOT_RIGHT_HAND) - victim.equip_to_slot_or_del(new /obj/item/shield/riot/roman(victim), ITEM_SLOT_LEFT_HAND) - victim.equip_to_slot_or_del(new /obj/item/spear(victim), ITEM_SLOT_BACK) - -///Updates the mobs species and gear to anime -/obj/item/necromantic_stone/proc/equip_heresy(mob/living/carbon/human/victim) - victim.set_species(/datum/species/human) - if(victim.gender == MALE) - victim.change_gender(FEMALE) - - var/list/anime_hair =list("Odango", "Kusanagi Hair", "Pigtails", "Hime Cut", "Floorlength Braid", "Ombre", "Twincurls", "Twincurls 2") - victim.change_hair(pick(anime_hair)) - - var/list/anime_hair_colours = list(list(216, 192, 120), - list(140,170,74),list(0,0,0)) - - var/list/chosen_colour = pick(anime_hair_colours) - victim.change_hair_color(chosen_colour[1], chosen_colour[2], chosen_colour[3]) - - victim.update_dna() - victim.update_body() - victim.grab_ghost() - victim.revive() - - victim.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(victim), ITEM_SLOT_SHOES) - victim.equip_to_slot_or_del(new /obj/item/clothing/head/kitty(victim), ITEM_SLOT_HEAD) - victim.equip_to_slot_or_del(new /obj/item/clothing/under/dress/schoolgirl(victim), ITEM_SLOT_JUMPSUIT) - victim.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(victim), ITEM_SLOT_OUTER_SUIT) - victim.equip_to_slot_or_del(new /obj/item/katana(victim), ITEM_SLOT_RIGHT_HAND) - victim.equip_to_slot_or_del(new /obj/item/shield/riot/roman(victim), ITEM_SLOT_LEFT_HAND) - victim.equip_to_slot_or_del(new /obj/item/spear(victim), ITEM_SLOT_BACK) - - if(!victim.real_name || victim.real_name == "unknown") - victim.real_name = "Neko-chan" - else - victim.real_name = "[victim.name]-chan" - - victim.mind.assigned_role = SPECIAL_ROLE_WIZARD - victim.mind.special_role = SPECIAL_ROLE_WIZARD - - victim.say("NYA!~") - -/obj/item/necromantic_stone/unlimited - unlimited = TRUE - -/obj/item/necromantic_stone/nya - name = "nya-cromantic stone" - desc = "A shard capable of resurrecting humans as creatures of Vile Heresy. Even the Wizard Federation fears it.." - icon = 'icons/obj/wizard.dmi' - icon_state = "nyacrostone" - item_state = "electronic" - origin_tech = "bluespace=4;materials=4" - heresy = TRUE - unlimited = TRUE - -/obj/item/organ/internal/heart/cursed/wizard - max_shocks_allowed = 3 - pump_delay = 60 - heal_brute = 25 - heal_burn = 25 - heal_oxy = 25 - -/obj/item/reagent_containers/drinks/everfull - name = "everfull mug" - desc = "An enchanted mug which can be filled with any of various liquids on command." - icon_state = "evermug" - -/obj/item/reagent_containers/drinks/everfull/attack_self__legacy__attackchain(mob/user) - var/static/list/options = list("Omnizine" = image(icon = 'icons/obj/storage.dmi', icon_state = "firstaid"), - "Ale" = image(icon = 'icons/obj/drinks.dmi', icon_state = "alebottle"), - "Wine" = image(icon = 'icons/obj/drinks.dmi', icon_state = "wineglass"), - "Holy Water" = image(icon = 'icons/obj/drinks.dmi', icon_state = "holyflask"), - "Welder Fuel" = image(icon = 'icons/obj/objects.dmi', icon_state = "fuel"), - "Vomit" = image(icon = 'icons/effects/blood.dmi', icon_state = "vomit_1")) - var/static/list/options_to_reagent = list("Omnizine" = "omnizine", - "Ale" = "ale", - "Wine" = "wine", - "Holy Water" = "holywater", - "Welder Fuel" = "fuel", - "Vomit" = "vomit") - var/static/list/options_to_descriptions = list("Omnizine" = "a strange pink-white liquid", - "Ale" = "foamy amber ale", - "Wine" = "deep red wine", - "Holy Water" = "sparkling clear water", - "Welder Fuel" = "a dark, pungent, oily substance", - "Vomit" = "warm chunky vomit") - - var/choice = show_radial_menu(user, src, options, require_near = TRUE) - if(!choice || user.stat || !in_range(user, src) || QDELETED(src)) - return - to_chat(user, "The [name] fills to brimming with [options_to_descriptions[choice]].") - magic_fill(options_to_reagent[choice]) - -/obj/item/reagent_containers/drinks/everfull/proc/magic_fill(reagent_choice) - reagents.clear_reagents() - reagents.add_reagent(reagent_choice, volume) - -//Oblivion Enforcer clothing (the halberd and gloves are defined elsewhere) - -/obj/item/clothing/head/hooded/oblivion - name = "Oblivion Enforcer's hood" - desc = "A hood worn by an Oblivion Enforcer." - icon_state = "oblivionhood" - flags = BLOCKHAIR - flags_inv = HIDEFACE - flags_cover = HEADCOVERSEYES - armor = list(MELEE = 20, BULLET = 5, LASER = 5, ENERGY = 5, BOMB = 0, RAD = INFINITY, FIRE = 5, ACID = 5) - flags_2 = RAD_PROTECT_CONTENTS_2 - cold_protection = HEAD - min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT - magical = TRUE - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/head.dmi', - "Kidan" = 'icons/mob/clothing/species/kidan/head.dmi', - "Grey" = 'icons/mob/clothing/species/grey/head.dmi', - "Drask" = 'icons/mob/clothing/species/drask/head.dmi', - "Tajaran" = 'icons/mob/clothing/species/tajaran/head.dmi', - "Unathi" = 'icons/mob/clothing/species/unathi/head.dmi', - "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/head.dmi' - ) - -/obj/item/clothing/suit/hooded/oblivion - name = "Oblivion Enforcer's robes" - desc = "A set of armored, radiation-proof robes worn by Oblivion Enforcers." - icon_state = "oblivionarmor" - item_state = "oblivionarmor" - body_parts_covered = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS - hoodtype = /obj/item/clothing/head/hooded/oblivion - allowed = list(/obj/item/supermatter_halberd, /obj/item/nuke_core/supermatter_sliver) - armor = list(MELEE = 35, BULLET = 20, LASER = 35, ENERGY = 10, BOMB = 15, RAD = INFINITY, FIRE = 5, ACID = 5) - flags_inv = HIDEJUMPSUIT | HIDESHOES | HIDETAIL | HIDESHOES - flags = THICKMATERIAL - flags_2 = RAD_PROTECT_CONTENTS_2 - magical = TRUE - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/suit.dmi', - "Kidan" = 'icons/mob/clothing/species/kidan/suit.dmi', - "Grey" = 'icons/mob/clothing/species/grey/suit.dmi', - "Drask" = 'icons/mob/clothing/species/drask/suit.dmi', - "Tajaran" = 'icons/mob/clothing/species/tajaran/suit.dmi', - "Unathi" = 'icons/mob/clothing/species/unathi/suit.dmi', - "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/suit.dmi' - ) - -/obj/item/clothing/suit/hooded/oblivion/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_SUPERMATTER_IMMUNE, ROUNDSTART_TRAIT) - -/obj/item/clothing/mask/gas/voice_modulator/oblivion - name = "Oblivion Enforcer's mask" - desc = "The mask of an Oblivion Enforcer. Don't forget to turn it on before giving your one-liners!" - icon_state = "oblivionmask" - item_state = "oblivionmask" - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/mask.dmi', - "Kidan" = 'icons/mob/clothing/species/kidan/mask.dmi', - "Grey" = 'icons/mob/clothing/species/grey/mask.dmi', - "Drask" = 'icons/mob/clothing/species/drask/mask.dmi', - "Tajaran" = 'icons/mob/clothing/species/tajaran/mask.dmi', - "Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi', - "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi' - ) - -/obj/item/clothing/shoes/white/enforcer - name = "hypernobilium weave shoes" - desc = "They're surprisingly comfortable and designed to fit under an Oblivion Enforcer's robes." - magical = TRUE - -/obj/item/clothing/shoes/white/enforcer/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_SUPERMATTER_IMMUNE, ROUNDSTART_TRAIT) - -/obj/item/clothing/under/color/white/enforcer - name = "hypernobilium weave jumpsuit" - desc = "A close-fitting, breathable jumpsuit, tailored for the dirty work of an Oblivion Enforcer." - has_sensor = FALSE - magical = TRUE - -/obj/item/clothing/under/color/white/enforcer/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_SUPERMATTER_IMMUNE, ROUNDSTART_TRAIT) diff --git a/code/game/gamemodes/wizard/godhand.dm b/code/game/gamemodes/wizard/godhand.dm deleted file mode 100644 index f75c5a692b833..0000000000000 --- a/code/game/gamemodes/wizard/godhand.dm +++ /dev/null @@ -1,162 +0,0 @@ -/obj/item/melee/touch_attack - name = "outstretched hand" - desc = "High Five?" - var/catchphrase = "High Five!" - var/on_use_sound = null - var/datum/spell/touch/attached_spell - icon = 'icons/obj/weapons/magical_weapons.dmi' - icon_state = "disintegrate" - lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' - righthand_file = 'icons/mob/inhands/items_righthand.dmi' - item_state = null - flags = ABSTRACT | NODROP | DROPDEL - w_class = WEIGHT_CLASS_HUGE - force = 0 - throwforce = 0 - throw_range = 0 - throw_speed = 0 - new_attack_chain = TRUE - /// Has it been blocked by antimagic? If so, abort. - var/blocked_by_antimagic = FALSE - -/obj/item/melee/touch_attack/New(spell) - attached_spell = spell - ..() - -/obj/item/melee/touch_attack/Destroy() - if(attached_spell) - attached_spell.attached_hand = null - attached_spell.UnregisterSignal(attached_spell.action.owner, COMSIG_MOB_WILLINGLY_DROP) - return ..() - -/obj/item/melee/touch_attack/customised_abstract_text(mob/living/carbon/owner) - return "[owner.p_their(TRUE)] [owner.l_hand == src ? "left hand" : "right hand"] is burning in magic fire." - -/obj/item/melee/touch_attack/attack(mob/living/target, mob/living/carbon/human/user) - if(..() || !iscarbon(user)) //Look ma, no hands - return FINISH_ATTACK - if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) - to_chat(user, "You can't reach out!") - return FINISH_ATTACK - -/obj/item/melee/touch_attack/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - . = ..() - var/mob/mob_victim = target - if(istype(mob_victim) && mob_victim.can_block_magic(attached_spell.antimagic_flags)) - to_chat(user, "[mob_victim] absorbs your spell!") - blocked_by_antimagic = TRUE - if(attached_spell && attached_spell.cooldown_handler) - attached_spell.cooldown_handler.start_recharge(attached_spell.cooldown_handler.recharge_duration * 0.5) - qdel(src) - return - -/obj/item/melee/touch_attack/proc/handle_delete(mob/user) - if(catchphrase) - user.say(catchphrase) - playsound(get_turf(user), on_use_sound, 50, 1) - if(attached_spell) - attached_spell.perform(list()) - qdel(src) - -/obj/item/melee/touch_attack/disintegrate - name = "disintegrating touch" - desc = "This hand of mine glows with an awesome power!" - catchphrase = "EI NATH!!" - on_use_sound = 'sound/magic/disintegrate.ogg' - icon_state = "disintegrate" - item_state = "disintegrate" - - -/obj/item/melee/touch_attack/disintegrate/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - . = ..() - if(!proximity_flag || target == user || blocked_by_antimagic || !ismob(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //exploding after touching yourself would be bad - return - var/mob/M = target - do_sparks(4, 0, M.loc) //no idea what the 0 is - M.gib() - handle_delete(user) - -/obj/item/melee/touch_attack/fleshtostone - name = "petrifying touch" - desc = "That's the bottom line, because flesh to stone said so!" - catchphrase = "STAUN EI!!" - on_use_sound = 'sound/magic/fleshtostone.ogg' - icon_state = "fleshtostone" - item_state = "fleshtostone" - -/obj/item/melee/touch_attack/fleshtostone/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - . = ..() - - if(!proximity_flag || target == user || blocked_by_antimagic || !isliving(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //getting hard after touching yourself would also be bad - return - var/mob/living/L = target - L.Stun(4 SECONDS) - new /obj/structure/closet/statue(L.loc, L) - handle_delete(user) - -/obj/item/melee/touch_attack/plushify - name = "fabric touch" - desc = "The power to sew your foes into a doom cut from the fabric of fate." - catchphrase = "MAHR-XET 'ABL" - on_use_sound = 'sound/magic/smoke.ogg' - icon_state = "disintegrate" - item_state = "disintegrate" - color = COLOR_PURPLE - -/obj/item/melee/touch_attack/plushify/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - . = ..() - - if(!proximity_flag || target == user || blocked_by_antimagic || !isliving(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //There are better ways to get a good nights sleep in a bed. - return - var/mob/living/L = target - L.plushify() - handle_delete(user) - - -/obj/item/melee/touch_attack/fake_disintegrate - name = "toy plastic hand" - desc = "This hand of mine glows with an awesome power! Ok, maybe just batteries." - catchphrase = "EI NATH!!" - on_use_sound = 'sound/magic/disintegrate.ogg' - icon_state = "disintegrate" - item_state = "disintegrate" - needs_permit = FALSE - -/obj/item/melee/touch_attack/fake_disintegrate/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - . = ..() - - if(!proximity_flag || target == user || blocked_by_antimagic || !ismob(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //not exploding after touching yourself would be bad - return - do_sparks(4, 0, target.loc) - playsound(target.loc, 'sound/goonstation/effects/gib.ogg', 50, 1) - handle_delete(user) - -/obj/item/melee/touch_attack/cluwne - name = "cluwne touch" - desc = "It's time to start clowning around." - catchphrase = "NWOLC EGNEVER" - on_use_sound = 'sound/misc/sadtrombone.ogg' - icon_state = "cluwnecurse" - item_state = "cluwnecurse" - -/obj/item/melee/touch_attack/cluwne/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - . = ..() - - if(!proximity_flag || target == user || blocked_by_antimagic || !ishuman(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //clowning around after touching yourself would unsurprisingly, be bad - return - - if(iswizard(target)) - to_chat(user, "The spell has no effect on [target].") - return - - var/datum/effect_system/smoke_spread/s = new - s.set_up(5, FALSE, target) - s.start() - - var/mob/living/carbon/human/H = target - if(H.mind) - if(H.mind.assigned_role != "Cluwne") - H.makeCluwne() - else - H.makeAntiCluwne() - handle_delete(user) diff --git a/code/game/gamemodes/wizard/magic_tarot.dm b/code/game/gamemodes/wizard/magic_tarot.dm deleted file mode 100644 index 4bd0c9ec4fe79..0000000000000 --- a/code/game/gamemodes/wizard/magic_tarot.dm +++ /dev/null @@ -1,1023 +0,0 @@ -/obj/item/tarot_generator - name = "enchanted tarot card deck" - desc = "This tarot card box has quite the array of runes and artwork on it." - icon = 'icons/obj/playing_cards.dmi' - icon_state = "tarot_box" - w_class = WEIGHT_CLASS_SMALL - /// What is the maximum number of cards the tarot generator can have in the world at a time? - var/maximum_cards = 3 - /// List of cards we have created, to check against maximum, and so we can purge them from the pack. - var/list/our_card_list = list() - ///How long the cooldown is each time we draw a card before we can draw another? - var/our_card_cooldown_time = 25 SECONDS - COOLDOWN_DECLARE(card_cooldown) - -/obj/item/tarot_generator/wizard - maximum_cards = 5 - our_card_cooldown_time = 12 SECONDS // A minute for a full hand of 5 cards - -/obj/item/tarot_generator/attack_self__legacy__attackchain(mob/user) - if(!COOLDOWN_FINISHED(src, card_cooldown)) - to_chat(user, "[src]'s magic is still recovering from the last card, wait [round(COOLDOWN_TIMELEFT(src, card_cooldown) / 10)] more second\s!") - return - if(length(our_card_list) >= maximum_cards) - to_chat(user, "[src]'s magic can only support up to [maximum_cards] in the world at once, use or destroy some!") - return - var/obj/item/magic_tarot_card/MTC = new /obj/item/magic_tarot_card(get_turf(src), src) - our_card_list += MTC - user.put_in_hands(MTC) - to_chat(user, "You draw [MTC.name]... [MTC.card_desc]") //No period on purpose. - COOLDOWN_START(src, card_cooldown, our_card_cooldown_time) - -/obj/item/tarot_generator/examine(mob/user) - . = ..() - . += "Alt-Shift-Click to destroy all cards it has produced." - . += "It has [length(our_card_list)] card\s in the world right now." - if(!COOLDOWN_FINISHED(src, card_cooldown)) - . += "You may draw another card again in [round(COOLDOWN_TIMELEFT(src, card_cooldown) / 10)] second\s." - -/obj/item/tarot_generator/AltShiftClick(mob/user) - for(var/obj/item/magic_tarot_card/MTC in our_card_list) - MTC.dust() - to_chat(user, "You dispell the cards [src] had created.") - -// Booster packs filled with 3, 5, or 7 playing cards! Used by the wizard space ruin, or rarely in lavaland tendril chests. -/obj/item/tarot_card_pack - name = "\improper Enchanted Arcana Pack" - desc = "A pack of 3 Enchanted tarot cards. Collect them all!" - icon = 'icons/obj/playing_cards.dmi' - icon_state = "pack" - ///How many cards in a pack. 3 in base, 5 in jumbo, 7 in mega - var/cards = 3 - -/obj/item/tarot_card_pack/attack_self__legacy__attackchain(mob/user) - user.visible_message("[user] tears open [src].", \ - "You tear open [src]!") - playsound(loc, 'sound/items/poster_ripped.ogg', 50, TRUE) - for(var/i in 1 to cards) - new /obj/item/magic_tarot_card(get_turf(src)) - qdel(src) - -/obj/item/tarot_card_pack/jumbo - name = "\improper Jumbo Arcana Pack" - desc = "A Jumbo card pack from your friend Jimbo!" - icon_state = "jumbopack" - cards = 5 - -/obj/item/tarot_card_pack/mega - name = "\improper MEGA Arcana Pack" - desc = "Sadly, you won't find a Joker for an angel room, or a Soul card in here either." - icon_state = "megapack" - cards = 7 - -// Blank tarot cards. Made by the cult, however also good for space ruins potentially, where one feels a card pack would be too much? -/obj/item/blank_tarot_card - name = "blank tarot card" - desc = "A blank tarot card." - icon = 'icons/obj/playing_cards.dmi' - icon_state = "tarot_blank" - w_class = WEIGHT_CLASS_TINY - throw_speed = 3 - throw_range = 10 - throwforce = 0 - force = 0 - resistance_flags = FLAMMABLE - /// If a person can choose what the card produces. No cost if they can choose. - var/let_people_choose = FALSE - -/obj/item/blank_tarot_card/examine(mob/user) - . = ..() - if(!let_people_choose) - . += "With a bit of Ink, a work of art could be created. Will you provide your Ink?" - else - . += "We have the Ink... Could you provide your Vision instead?" - -/obj/item/blank_tarot_card/attack_self__legacy__attackchain(mob/user) - if(!ishuman(user)) - return - if(!let_people_choose) - var/mob/living/carbon/human/H = user - if(H.dna && (NO_BLOOD in H.dna.species.species_traits)) - to_chat(user, "No blood to provide?... Then no Ink for the art...") - return - if(H.blood_volume <= 100) //Shouldn't happen, they should be dead, but failsafe. Not bleeding as then they could recover the blood with blood rites - return - H.blood_volume -= 100 - H.drop_item() - var/obj/item/magic_tarot_card/MTC = new /obj/item/magic_tarot_card(get_turf(src)) - user.put_in_hands(MTC) - to_chat(user, "Your blood flows into [src]... And your Ink makes a work of art! [MTC.name]... [MTC.card_desc]") //No period on purpose. - qdel(src) - return - var/tarot_type - var/tarot_name - var/list/card_by_name = list() - for(var/T in subtypesof(/datum/tarot) - /datum/tarot/reversed) - var/datum/tarot/temp = T - card_by_name[temp.name] = T - - tarot_name = tgui_input_list(user, "Choose the Work of Art to create.", "Art Creation", card_by_name) - tarot_type = card_by_name[tarot_name] - if(tarot_type) - user.drop_item() - var/obj/item/magic_tarot_card/MTC = new /obj/item/magic_tarot_card(get_turf(src), null, tarot_type) - user.put_in_hands(MTC) - to_chat(user, "You put your Vision into [src], and your Vision makes a work of Art! [MTC.name]... [MTC.card_desc]") //No period on purpose. - qdel(src) - -/obj/item/blank_tarot_card/choose //For admins mainly, to spawn a specific tarot card. Not recommended for ruins. - let_people_choose = TRUE - -/obj/item/magic_tarot_card - name = "XXII - The Unknown" - desc = "A beautiful tarot card. However, it feels like... more?" - icon = 'icons/obj/playing_cards.dmi' - icon_state = "tarot_the_unknown" - w_class = WEIGHT_CLASS_TINY - throw_speed = 3 - throw_range = 10 - throwforce = 0 - force = 0 - resistance_flags = FLAMMABLE - /// The deck that created us. Notifies it we have been deleted on use. - var/obj/item/tarot_generator/creator_deck - /// Our magic tarot card datum that lets the tarot card do stuff on use, or hitting someone - var/datum/tarot/our_tarot - /// Our fancy description given to use by the tarot datum. - var/card_desc = "Untold answers... wait what? This is a bug, report this as an issue on github!" - /// Is the card face down? Shows the card back, hides the examine / name. - var/face_down = FALSE - /// Will this card automatically disappear if thrown at a non-mob? - var/needs_mob_target = TRUE - /// Has the card been activated? If it has, don't activate it again - var/has_been_activated = FALSE - -/obj/item/magic_tarot_card/Initialize(mapload, obj/item/tarot_generator/source, datum/tarot/chosen_tarot) - . = ..() - if(source) - creator_deck = source - if(chosen_tarot) - our_tarot = new chosen_tarot - if(!istype(our_tarot)) - var/tarotpath = pick(subtypesof(/datum/tarot) - /datum/tarot/reversed) - our_tarot = new tarotpath - name = our_tarot.name - card_desc = our_tarot.desc - icon_state = "tarot_[our_tarot.card_icon]" - -/obj/item/magic_tarot_card/Destroy() - if(creator_deck) - creator_deck.our_card_list -= src - return ..() - -/obj/item/magic_tarot_card/examine(mob/user) - . = ..() - if(!face_down) - . += "[card_desc]" - . += "Alt-Shift-Click to flip the card over." - -/obj/item/magic_tarot_card/examine_more(mob/user) - . = ..() - if(!face_down) - . += "[src] [our_tarot.extended_desc]" - -/obj/item/magic_tarot_card/attack_self__legacy__attackchain(mob/user) - poof() - if(has_been_activated) - return - if(face_down) - flip() - if(our_tarot) - user.drop_item() - pre_activate(user, user) - return - qdel(src) - -/obj/item/magic_tarot_card/throw_at(atom/target, range, speed, mob/thrower, spin, diagonals_first, datum/callback/callback, force, dodgeable) - if(face_down) - flip() - . = ..() - -/obj/item/magic_tarot_card/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - . = ..() - if(needs_mob_target && !isliving(hit_atom)) - return - poof() - if(has_been_activated) - return - if(isliving(hit_atom) && our_tarot) - pre_activate(hit_atom, locateUID(throwingdatum.thrower_uid)) - return - qdel(src) - -/obj/item/magic_tarot_card/AltShiftClick(mob/user) - flip() - -/obj/item/magic_tarot_card/proc/flip() - if(!face_down) - icon_state = "cardback[our_tarot.reversed ? "?" : ""]" - name = "Enchanted tarot card" - face_down = TRUE - else - name = our_tarot.name - icon_state = "tarot_[our_tarot.card_icon]" - face_down = FALSE - -/obj/item/magic_tarot_card/proc/poof() - new /obj/effect/temp_visual/revenant(get_turf(src)) - -/obj/item/magic_tarot_card/proc/dust() - visible_message("[src] disintegrates into dust!") - new /obj/effect/temp_visual/revenant(get_turf(src)) - qdel(src) - -/obj/item/magic_tarot_card/proc/pre_activate(mob/user, atom/movable/thrower) - if(user != thrower) //Ignore antimagic stuff if the user is the thrower (aka self activation) - if(user.can_block_magic(our_tarot.antimagic_flags, 1)) - visible_message("[src] burns up in a flash on contact with [user]!") - qdel(src) - return - has_been_activated = TRUE - forceMove(user) - var/obj/effect/temp_visual/card_preview/tarot/draft = new(user, "tarot_[our_tarot.card_icon]") - user.vis_contents += draft - user.visible_message("[user] holds up [src]!") - addtimer(CALLBACK(our_tarot, TYPE_PROC_REF(/datum/tarot, activate), user), 0.5 SECONDS) - if(ismob(thrower) && our_tarot) - add_attack_logs(thrower, user, "[thrower] has activated [our_tarot.name] on [user]", ATKLOG_FEW) - QDEL_IN(src, 0.6 SECONDS) - -/obj/effect/temp_visual/card_preview - name = "a card" - icon = 'icons/obj/playing_cards.dmi' - icon_state = "tarot_the_unknown" - pixel_y = 20 - duration = 1.5 SECONDS - -/obj/effect/temp_visual/card_preview/Initialize(mapload, new_icon_state) - . = ..() - if(new_icon_state) - icon_state = new_icon_state - - flourish() - -/obj/effect/temp_visual/card_preview/proc/flourish() - var/new_filter = isnull(get_filter("ray")) - ray_filter_helper(1, 40, "#fcf3dc", 6, 20) - if(new_filter) - animate(get_filter("ray"), alpha = 0, offset = 10, time = duration, loop = -1) - animate(offset = 0, time = duration) - -/obj/effect/temp_visual/card_preview/tarot - name = "a tarot card" - icon = 'icons/obj/playing_cards.dmi' - icon_state = "tarot_the_unknown" - pixel_y = 20 - duration = 1.5 SECONDS - -/obj/effect/temp_visual/card_preview/tarot/flourish() - var/new_filter = isnull(get_filter("ray")) - ray_filter_helper(1, 40,"#fcf3dc", 6, 20) - if(new_filter) - animate(get_filter("ray"), alpha = 0, offset = 10, time = duration, loop = -1) - animate(offset = 0, time = duration) - -/datum/tarot - /// Name used for the card - var/name = "XXII - The Unknown." - /// Desc used for the card description of the card - var/desc = "Untold answers... wait what? This is a bug, report this as an issue on github!" - /// Extended desc for the cards. For what they do - var/extended_desc = "asks you to report this as a bug on GitHub!" - /// What icon is used for the card? - var/card_icon = "the_unknown" - /// Are we reversed? Used for the card back. - var/reversed = FALSE - /// What antimagic flags do we have? - var/antimagic_flags = MAGIC_RESISTANCE - -/datum/tarot/proc/activate(mob/living/target) - stack_trace("A bugged tarot card was spawned and used. Please make an issue report! Type was [src.type]") - -/datum/tarot/reversed - name = "XXII - The Unknown?" - desc = "Untold answers... wait what? This is a bug, report this as an issue on github! This one was a reversed arcana!" - card_icon = "the_unknown?" - reversed = TRUE - -/datum/tarot/the_fool - name = "0 - The Fool" - desc = "Where journey begins." - extended_desc = "returns the affected user to the arrival point of this forsaken journey." - card_icon = "the_fool" - -/datum/tarot/the_fool/activate(mob/living/target) - if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT) - return FALSE - target.forceMove(pick(GLOB.latejoin)) - to_chat(target, "You are abruptly pulled through space!") - -/datum/tarot/the_magician - name = "I - The Magician" - desc = "May you never miss your goal." - extended_desc = "makes the user feel extraordinarily badass for a couple of minutes." - card_icon = "the_magician" - -/datum/tarot/the_magician/activate(mob/living/target) - target.apply_status_effect(STATUS_EFFECT_BADASS) - to_chat(target, "You feel badass.") - -/datum/tarot/the_high_priestess - name = "II - The High Priestess" - desc = "Mother is watching you." - extended_desc = "alerts bubblegum to the user, who will strike them down. The user will receive heavy damage and will be immobilized." - card_icon = "the_high_priestess" - -/datum/tarot/the_high_priestess/activate(mob/living/target) - new /obj/effect/abstract/bubblegum_rend_helper(get_turf(target), target, 20) - -/obj/effect/abstract/bubblegum_rend_helper - name = "bubblegum_rend_helper" - -/obj/effect/abstract/bubblegum_rend_helper/Initialize(mapload, mob/living/owner, damage) - . = ..() - INVOKE_ASYNC(src, PROC_REF(rend), owner, damage) - -/obj/effect/abstract/bubblegum_rend_helper/proc/rend(mob/living/owner, damage) - if(!owner) - for(var/mob/living/L in shuffle(view(9, src))) - owner = L - break - owner.Immobilize(3 SECONDS) - for(var/i in 1 to 3) - var/turf/first_turf = get_turf(owner) - new /obj/effect/decal/cleanable/blood/bubblegum(first_turf) - if(prob(50)) - new /obj/effect/temp_visual/bubblegum_hands/rightsmack(first_turf) - else - new /obj/effect/temp_visual/bubblegum_hands/leftsmack(first_turf) - sleep(6) - var/turf/second_turf = get_turf(owner) - to_chat(owner, "Something huge rends you!") - playsound(second_turf, 'sound/misc/demon_attack1.ogg', 100, TRUE, -1) - owner.adjustBruteLoss(damage) - qdel(src) - -/datum/tarot/the_empress - name = "III - The Empress" - desc = "May your rage bring power." - extended_desc = "gives the user a temporary boost of speed. This includes attack speed." - card_icon = "the_empress" - -/datum/tarot/the_empress/activate(mob/living/target) - if(ishuman(target)) - var/mob/living/carbon/human/H = target - H.reagents.add_reagent("mephedrone", 4.5) - H.reagents.add_reagent("mitocholide", 12) - -/datum/tarot/the_emperor - name = "IV - The Emperor" - desc = "Challenge me!" - extended_desc = "warps the user to where command commonly resides. Be ready for a fight." - card_icon = "the_emperor" - -/datum/tarot/the_emperor/activate(mob/living/target) - var/list/L = list() - for(var/turf/T in get_area_turfs(/area/station/command/bridge)) - if(is_blocked_turf(T)) - continue - L.Add(T) - - if(!length(L)) - to_chat(target, "Huh. No bridge? Well, that sucks.") - return - if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT) - return FALSE - target.forceMove(pick(L)) - to_chat(target, "You are abruptly pulled through space!") - -/datum/tarot/the_hierophant - name = "V - The Hierophant" - desc = "Two prayers for the lost." - extended_desc = "enchants the user's suit with magic that's strong enough to negate three attacks." - card_icon = "the_hierophant" - -/datum/tarot/the_hierophant/activate(mob/living/target) - if(!ishuman(target)) - return - var/mob/living/carbon/human/H = target - if(!H.wear_suit) - return - H.wear_suit.setup_hierophant_shielding() - H.update_appearance(UPDATE_ICON) - -/datum/tarot/the_lovers - name = "VI - The Lovers" - desc = "May you prosper and be in good health." - extended_desc = "will restore the overall health of the user." - card_icon = "the_lovers" - -/datum/tarot/the_lovers/activate(mob/living/target) - if(ishuman(target)) - var/mob/living/carbon/human/H = target - H.adjustBruteLoss(-40, robotic = TRUE) - H.adjustFireLoss(-40, robotic = TRUE) - H.blood_volume = min(H.blood_volume + 100, BLOOD_VOLUME_NORMAL) - else - target.adjustBruteLoss(-40) - target.adjustFireLoss(-40) - target.adjustOxyLoss(-40) - target.adjustToxLoss(-40) - -/datum/tarot/the_chariot - name = "VII - The Chariot" - desc = "May nothing stand before you." - extended_desc = "imbues the user with immense power and speed, rendering them practically immortal for 10 seconds, at the cost of being unable to harm another living thing." - card_icon = "the_chariot" - -/datum/tarot/the_chariot/activate(mob/living/target) - target.apply_status_effect(STATUS_EFFECT_BLOOD_RUSH) - target.apply_status_effect(STATUS_EFFECT_BLOODDRUNK_CHARIOT) - -/datum/tarot/justice - name = "VIII - Justice" - desc = "May your future become balanced." - extended_desc = "grants the user a medical first aid kit, a magical key that can open a single door, and 100 credits." - card_icon = "justice" - -/datum/tarot/justice/activate(mob/living/target) - var/turf/target_turf = get_turf(target) - new /obj/item/storage/firstaid/regular(target_turf) - new /obj/item/grenade/chem_grenade/waterpotassium(target_turf) - new /obj/item/card/emag/magic_key(target_turf) - new /obj/item/stack/spacecash/c100(target_turf) - -/datum/tarot/the_hermit - name = "IX - The Hermit" - desc = "May you see what life has to offer." - extended_desc = "teleports the user to a random vending machine within the station." - card_icon = "the_hermit" - -/datum/tarot/the_hermit/activate(mob/living/target) - var/list/viable_vendors = list() - for(var/obj/machinery/economy/vending/candidate in GLOB.machines) - if(!is_station_level(candidate.z)) - continue - viable_vendors += candidate - - if(!length(viable_vendors)) - to_chat(target, "No vending machines? Well, with luck cargo will have something to offer. If you go there yourself.") - return - if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT) - return FALSE - target.forceMove(get_turf(pick(viable_vendors))) - to_chat(target, "You are abruptly pulled through space!") - -/datum/tarot/wheel_of_fortune - name = "X - Wheel of Fortune" - desc = "Spin the wheel of destiny." - extended_desc = "summons a random vending machine." - card_icon = "wheel_of_fortune" - -/datum/tarot/wheel_of_fortune/activate(mob/living/target) - var/list/static/bad_vendors = typesof(/obj/machinery/economy/vending/liberationstation)\ - + typesof(/obj/machinery/economy/vending/toyliberationstation)\ - + typesof(/obj/machinery/economy/vending/wallmed) // Future proofing in case we add more subtypes of disallowed vendors - var/turf/target_turf = get_turf(target) - var/vendorpath = pick(subtypesof(/obj/machinery/economy/vending) - bad_vendors) - new vendorpath(target_turf) - -/datum/tarot/strength - name = "XI - Strength" - desc = "May your power bring rage." - extended_desc = "grants the user strength beyond belief, but renders them unable to handle ranged weapons." - card_icon = "strength" - -/datum/tarot/strength/activate(mob/living/target) - target.apply_status_effect(STATUS_EFFECT_VAMPIRE_GLADIATOR) - target.apply_status_effect(STATUS_EFFECT_BLOOD_SWELL) - -/datum/tarot/the_hanged_man - name = "XII - The Hanged Man" - desc = "May you find enlightenment." - extended_desc = "allows the user to fly for a minute." - card_icon = "the_hanged_man" - -/datum/tarot/the_hanged_man/activate(mob/living/target) - if(HAS_TRAIT(target, TRAIT_FLYING)) - return - ADD_TRAIT(target, TRAIT_FLYING, "tarot") - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(callback_remove_trait), target, TRAIT_FLYING, "tarot"), 60 SECONDS) - -/datum/tarot/death - name = "XIII - Death" - desc = "Lay waste to all that oppose you." - extended_desc = "deals damage to all those the user can see. Aside from themselves, of course." - card_icon = "death" - -/datum/tarot/death/activate(mob/living/target) - for(var/mob/living/L in oview(9, target)) - L.adjustBruteLoss(20) - L.adjustFireLoss(20) - -/datum/tarot/temperance - name = "XIV - Temperance" - desc = "May you be pure in heart." - extended_desc = "cures all ailments the user has. Also reinvigorates their organs." - card_icon = "temperance" - -/datum/tarot/temperance/activate(mob/living/target) - if(!ishuman(target)) - return - var/mob/living/carbon/human/H = target - var/obj/item/organ/internal/body_egg/egg = H.get_int_organ(/obj/item/organ/internal/body_egg) - if(egg) - egg.remove(H) - H.vomit() - egg.forceMove(get_turf(H)) - H.reagents.add_reagent("mutadone", 1) - for(var/obj/item/organ/internal/I in H.internal_organs) - I.heal_internal_damage(60) - H.apply_status_effect(STATUS_EFFECT_PANACEA) - for(var/thing in H.viruses) - var/datum/disease/D = thing - if(D.severity == NONTHREAT) - continue - D.cure() - -/datum/tarot/the_devil - name = "XV - The Devil" - desc = "Revel in the power of darkness." - extended_desc = "steals the life-force of everyone around the user." - card_icon = "the_devil" - -/datum/tarot/the_devil/activate(mob/living/target) - target.apply_status_effect(STATUS_EFFECT_SHADOW_MEND_DEVIL) - -/datum/tarot/the_tower - name = "XVI - The Tower" - desc = "Destruction brings creation." - extended_desc = "summons a self-replicating bomb." - card_icon = "the_tower" - -/datum/tarot/the_tower/activate(mob/living/target) - var/obj/item/grenade/clusterbuster/ied/bakoom = new(get_turf(target)) - var/turf/bombturf = get_turf(target) - target.investigate_log("[key_name(target)] has been activated (either thrown at or used) on [target] at [bombturf.x],[bombturf.y],[bombturf.z]", INVESTIGATE_BOMB) // Yes, this is an atom proc. Suffering - bakoom.prime() - -/// I'm sorry matt, this is very funny. -/datum/tarot/the_stars - name = "XVII - The Stars" - desc = "May you find what you desire." - extended_desc = "teleports the user to the station's evidence room, and opens a single locker within." - card_icon = "the_stars" - -/datum/tarot/the_stars/activate(mob/living/target) - var/list/L = list() - for(var/turf/T in get_area_turfs(/area/station/security/evidence)) - if(is_blocked_turf(T)) - continue - L.Add(T) - - if(!length(L)) - to_chat(target, "Huh. No evidence? Well, that means they can't charge you with a crime, right?") - return - if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT) - return FALSE - target.forceMove(pick(L)) - to_chat(target, "You are abruptly pulled through space!") - for(var/obj/structure/closet/C in shuffle(view(9, target))) - if(istype(C, /obj/structure/closet/secure_closet)) - var/obj/structure/closet/secure_closet/SC = C - SC.locked = FALSE - C.open() - break //Only open one locker - -/datum/tarot/the_moon - name = "XVIII - The Moon" - desc = "May you find all you have lost." - extended_desc = "teleports the user to a random place of interest, starting with the sector the user is in first." - card_icon = "the_moon" - -/datum/tarot/the_moon/activate(mob/living/target) - var/list/funny_ruin_list = list() - var/turf/target_turf = get_turf(target) - if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT) - return FALSE - for(var/I in GLOB.ruin_landmarks) - var/obj/effect/landmark/ruin/ruin_landmark = I - if(ruin_landmark.z == target_turf.z) - funny_ruin_list += ruin_landmark - - if(length(funny_ruin_list)) - var/turf/T = get_turf(pick(funny_ruin_list)) - target.forceMove(T) - to_chat(target, "You are abruptly pulled through space!") - T.ChangeTurf(/turf/simulated/floor/plating) //we give them plating so they are not trapped in a wall, and a pickaxe to avoid being trapped in a wall - new /obj/item/pickaxe/emergency(T) - target.update_parallax_contents() - return - //We did not find a ruin on the same level. Well. I hope you have a space suit, but we'll go space ruins as they are mostly sorta kinda safer. - for(var/I in GLOB.ruin_landmarks) - var/obj/effect/landmark/ruin/ruin_landmark = I - if(!is_mining_level(ruin_landmark.z)) - funny_ruin_list += ruin_landmark - - if(!length(funny_ruin_list)) - to_chat(target, "Huh. No space ruins? Well, this card is RUINED!") - - var/turf/T = get_turf(pick(funny_ruin_list)) - target.forceMove(T) - to_chat(target, "You are abruptly pulled through space!") - T.ChangeTurf(/turf/simulated/floor/plating) //we give them plating so they are not trapped in a wall, and a pickaxe to avoid being trapped in a wall - new /obj/item/pickaxe/emergency(T) - target.update_parallax_contents() - return - -/datum/tarot/the_sun - name = "XIX - The Sun" - desc = "May the light heal and enlighten you." - extended_desc = "fully rejuvenates the user back to their peak strength." - card_icon = "the_sun" - -/datum/tarot/the_sun/activate(mob/living/target) - target.revive() - -/datum/tarot/judgement - name = "XX - Judgement" - desc = "Judge lest ye be judged." - extended_desc = "alerts the denizens of the afterlife to the user's existence. Prepare to be judged." - card_icon = "judgement" - -/datum/tarot/judgement/activate(mob/living/target) - notify_ghosts("[target] has used a judgment card. Judge them. Or not, up to you.", enter_link = "(Click to judge)", source = target, action = NOTIFY_FOLLOW) - -/datum/tarot/the_world - name = "XXI - The World" - desc = "Open your eyes and see." - extended_desc = "bellows out smoke and grants the user full x-ray vision for two minutes." - card_icon = "the_world" - -/datum/tarot/the_world/activate(mob/living/target) - var/datum/effect_system/smoke_spread/bad/smoke = new() - smoke.set_up(10, FALSE, target) - smoke.start() - target.apply_status_effect(STATUS_EFFECT_XRAY) - -//////////////////////////////// -////////REVERSED ARCANA///////// -//////////////////////////////// - -/datum/tarot/reversed/the_fool - name = "0 - The Fool?" - desc = "Let go and move on." - extended_desc = "removes all items from the user, leaving them completely naked." - card_icon = "the_fool?" - -/datum/tarot/reversed/the_fool/activate(mob/living/target) - if(!ishuman(target)) - return - var/mob/living/carbon/human/H = target - for(var/obj/item/I in H) - if(istype(I, /obj/item/bio_chip)) - continue - H.drop_item_to_ground(I) - -/datum/tarot/reversed/the_magician - name = "I - The Magician?" - desc = "May no harm come to you." - extended_desc = "will repulse everything away from the user." - card_icon = "the_magician?" - -/datum/tarot/reversed/the_magician/activate(mob/living/target) - var/list/thrown_atoms = list() - var/sparkle_path = /obj/effect/temp_visual/gravpush - for(var/turf/T in range(5, target)) //Done this way so things don't get thrown all around hilariously. - for(var/atom/movable/AM in T) - if(ismob(AM)) - var/mob/victim_mob = AM - if(victim_mob.can_block_magic(antimagic_flags)) - continue - thrown_atoms += AM - for(var/atom/movable/AM as anything in thrown_atoms) - if(AM == target || AM.anchored || (ismob(AM) && !isliving(AM))) - continue - - var/throw_target = get_edge_target_turf(target, get_dir(target, get_step_away(AM, target))) - var/dist_from_user = get_dist(target, AM) - if(dist_from_user == 0) - if(isliving(AM)) - var/mob/living/M = AM - M.Weaken(6 SECONDS) - M.adjustBruteLoss(10) - to_chat(M, "You're slammed into the floor by [name]!") - add_attack_logs(target, M, "[M] was thrown by [target]'s [name]", ATKLOG_ALMOSTALL) - else - new sparkle_path(get_turf(AM), get_dir(target, AM)) - if(isliving(AM)) - var/mob/living/M = AM - to_chat(M, "You're thrown back by [name]!") - add_attack_logs(target, M, "[M] was thrown by [target]'s [name]", ATKLOG_ALMOSTALL) - INVOKE_ASYNC(AM, TYPE_PROC_REF(/atom/movable, throw_at), throw_target, ((clamp((3 - (clamp(dist_from_user - 2, 0, dist_from_user))), 3, 3))), 1) //So stuff gets tossed around at the same time. - -/datum/tarot/reversed/the_high_priestess - name = "II - The High Priestess?" - desc = "Run." - extended_desc = "summons Bubblegum to tear portals open around the user that will grab and damage everyone nearby." - card_icon = "the_high_priestess?" - -/datum/tarot/reversed/the_high_priestess/activate(mob/living/target) - target.visible_message("WHO DARES TO TRY TO USE MY POWER IN A CARD?") - target.apply_status_effect(STATUS_EFFECT_REVERSED_HIGH_PRIESTESS) - -/datum/tarot/reversed/the_empress - name = "III - The Empress?" - desc = "May your love bring protection." - extended_desc = "pacifies everyone in range, except for the user, for 40 seconds." - card_icon = "the_empress?" - -/datum/tarot/reversed/the_empress/activate(mob/living/target) - for(var/mob/living/L in oview(9, target)) - if(L.can_block_magic(antimagic_flags)) - to_chat(L, "You feel calm for a second, but it quickly passes.") - continue - L.apply_status_effect(STATUS_EFFECT_PACIFIED) - -/datum/tarot/reversed/the_emperor - name = "IV - The Emperor?" - desc = "May you find a worthy opponent." - extended_desc = "teleports the user to a random head of staff." - card_icon = "the_emperor?" - -/datum/tarot/reversed/the_emperor/activate(mob/living/target) - var/list/L = list() - var/list/heads = SSticker.mode.get_all_heads() - for(var/datum/mind/head in heads) - if(ishuman(head.current)) - L.Add(head.current) - - if(!length(L)) - to_chat(target, "Huh. No command members? I hope you didn't kill them all already...") - return - if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT) - return FALSE - target.forceMove(get_turf(pick(L))) - to_chat(target, "You are abruptly pulled through space!") - -/datum/tarot/reversed/the_hierophant - name = "V - The Hierophant?" - desc = "Two prayers for the forgotten." - extended_desc = "makes the Hierophant attack two random mobs in range." - card_icon = "the_hierophant?" - -/datum/tarot/reversed/the_hierophant/activate(mob/living/target) - var/active_chasers = 0 - for(var/mob/living/M in shuffle(orange(7, target))) - if(M.stat == DEAD) //Let us not have dead mobs be used to make a disco inferno. - continue - if(M.can_block_magic(antimagic_flags)) //Be spared! - continue - if(active_chasers >= 2) - return - var/obj/effect/temp_visual/hierophant/chaser/C = new(get_turf(target), target, M, 1, FALSE) - C.moving = 2 - C.standard_moving_before_recalc = 2 - C.moving_dir = text2dir(pick("NORTH", "SOUTH", "EAST", "WEST")) - active_chasers++ - -/datum/tarot/reversed/the_lovers - name = "VI - The Lovers?" - desc = "May your heart shatter to pieces." - extended_desc = "causes the user of this card to experience true heartbreak - leaving their chest broken and battered." - card_icon = "the_lovers?" - -/datum/tarot/reversed/the_lovers/activate(mob/living/target) - if(!ishuman(target)) - return - var/mob/living/carbon/human/H = target - H.apply_damage(20, BRUTE, BODY_ZONE_CHEST) - H.bleed(120) - var/obj/item/organ/external/chest = H.get_organ(BODY_ZONE_CHEST) - chest.fracture() - var/datum/organ/heart/datum_heart = H.get_int_organ_datum(ORGAN_DATUM_HEART) - var/obj/item/organ/internal/our_heart = datum_heart.linked_organ - our_heart.receive_damage(20, TRUE) - -/datum/tarot/reversed/the_chariot - name = "VII - The Chariot?" - desc = "May nothing walk past you." - extended_desc = "will petrify the user for two minutes, rendering them completely indestructible." - card_icon = "the_chariot?" - -/datum/tarot/reversed/the_chariot/activate(mob/living/target) - target.Stun(4 SECONDS) - new /obj/structure/closet/statue/indestructible(get_turf(target), target) - -/datum/tarot/reversed/justice - name = "VIII - Justice?" - desc = "May your sins come back to torment you." - extended_desc = "creates a random orderable crate. This can include crates Supply would otherwise not have access to at the time." - card_icon = "justice?" - -/datum/tarot/reversed/justice/activate(mob/living/target) - var/list/static/ignored_supply_pack_types = list( - /datum/supply_packs/abstract, - /datum/supply_packs/abstract/shuttle - ) - var/chosen = pick(SSeconomy.supply_packs - ignored_supply_pack_types) - var/datum/supply_packs/the_pack = new chosen() - var/spawn_location = get_turf(target) - var/obj/structure/closet/crate/crate = the_pack.create_package(spawn_location) - crate.name = "magic [crate.name]" - qdel(the_pack) - -/datum/tarot/reversed/the_hermit - name = "IX - The Hermit?" - desc = "May you see the value of all things in life." - extended_desc = "will sell all loose guns, grenades, batons, and armor around the user, transforming them directly into cash." - card_icon = "the_hermit?" - -/datum/tarot/reversed/the_hermit/activate(mob/living/target) //Someone can improve this in the future (hopefully comment will not be here in 10 years.) - for(var/obj/item/I in view(7, target)) - if(istype(I, /obj/item/gun)) - new /obj/item/stack/spacecash/c200(get_turf(I)) - qdel(I) - continue - if(istype(I, /obj/item/grenade)) - new /obj/item/stack/spacecash/c50(get_turf(I)) - qdel(I) - if(istype(I, /obj/item/clothing/suit/armor)) - new /obj/item/stack/spacecash/c100(get_turf(I)) - qdel(I) - if(istype(I, /obj/item/melee/baton)) - new /obj/item/stack/spacecash/c100(get_turf(I)) - qdel(I) - -/datum/tarot/reversed/wheel_of_fortune - name = "X - Wheel of Fortune?" - desc = "Throw the dice of fate." - extended_desc = "forces the user to roll for a powerful magical artifact. The outcome can be highly positive or highly negative; it is up to fate." - card_icon = "wheel_of_fortune?" - -/datum/tarot/reversed/wheel_of_fortune/activate(mob/living/target) - var/obj/item/dice/d20/fate/one_use/gonna_roll_a_one = new /obj/item/dice/d20/fate/one_use(get_turf(target)) - gonna_roll_a_one.diceroll(target) - -/datum/tarot/reversed/strength - name = "XI - Strength?" - desc = "May you break their resolve." - extended_desc = "breaks the minds of those around the user, dealing heavy brain damage, and causing two minutes of hallucinations." - card_icon = "strength?" - -/datum/tarot/reversed/strength/activate(mob/living/target) - for(var/mob/living/M in oview(9, target)) - M.Hallucinate(2 MINUTES) - new /obj/effect/hallucination/delusion(get_turf(M), M) - M.adjustBrainLoss(30) - -/datum/tarot/reversed/the_hanged_man - name = "XII - The Hanged Man?" - desc = "May your greed know no bounds." - extended_desc = "forces the user to spin a cursed slot machine." - card_icon = "the_hanged_man?" - -/datum/tarot/reversed/the_hanged_man/activate(mob/living/target) - var/obj/structure/cursed_slot_machine/pull_the_lever_kronk = new /obj/structure/cursed_slot_machine(get_turf(target)) - if(ishuman(target)) - var/mob/living/carbon/human/WRONG_LEVER = target - pull_the_lever_kronk.attack_hand(WRONG_LEVER) - -/datum/tarot/reversed/death - name = "XIII - Death?" - desc = "May life spring forth from the fallen." - extended_desc = "grants the user a soulstone and a construct to freely use on the dead." - card_icon = "death?" - -/datum/tarot/reversed/death/activate(mob/living/target) - new /obj/structure/constructshell(get_turf(target)) - new /obj/item/soulstone/anybody(get_turf(target)) - -/datum/tarot/reversed/temperance - name = "XIV - Temperance?" - desc = "May your hunger be satiated." - extended_desc = "forces the user to eat five pills containing random reagents." - card_icon = "temperance?" - -/datum/tarot/reversed/temperance/activate(mob/living/target) - if(!ishuman(target)) - return - var/mob/living/carbon/human/H = target - for(var/i in 1 to 5) - var/datum/reagents/R = new /datum/reagents(10) - R.add_reagent(get_unrestricted_random_reagent_id(), 10) - R.reaction(H, REAGENT_INGEST) - R.trans_to(H, 10) - target.visible_message("[target] consumes 5 pills rapidly!") - -/datum/tarot/reversed/the_devil - name = "XV - The Devil?" - desc = "Bask in the light of your mercy." - extended_desc = "summons a primed cluster flashbang at the user's feet." - card_icon = "the_devil?" - -/datum/tarot/reversed/the_devil/activate(mob/living/target) - var/obj/item/grenade/clusterbuster/i_hate_nians = new(get_turf(target)) - i_hate_nians.prime() - -/datum/tarot/reversed/the_tower - name = "XVI - The Tower?" - desc = "Creation brings destruction." - extended_desc = "will create large stone walls that erupt from the ground around the user." - card_icon = "the_tower?" - -/datum/tarot/reversed/the_tower/activate(mob/living/target) - for(var/turf/T in RANGE_TURFS(9, target)) - if(locate(/mob/living) in T) - continue - if(istype(T, /turf/simulated/wall/indestructible)) - continue - if(prob(66)) - continue - T.ChangeTurf(/turf/simulated/mineral/random/labormineral) - -/datum/tarot/reversed/the_stars - name = "XVII - The Stars?" - desc = "May your loss bring fortune." - extended_desc = "will cause a large amount of genetic decomposition to the user, as well as hurting a limb. However, it will reward the user with two additional cards." - card_icon = "the_stars?" - -/datum/tarot/reversed/the_stars/activate(mob/living/target) //Heavy clone damage hit, but gain 2 cards. Not teathered to the card producer. Could lead to card stacking, but would require the sun to fix easily - if(!ishuman(target)) - return - var/mob/living/carbon/human/H = target - H.adjustCloneLoss(50) - for(var/obj/item/organ/external/E in shuffle(H.bodyparts)) - switch(rand(1,3)) - if(1) - E.fracture() - if(2) - E.cause_internal_bleeding() - if(3) - E.cause_burn_wound() - break // I forgot the break the first time. Very funny. - - H.drop_l_hand() - H.drop_r_hand() - var/obj/item/magic_tarot_card/MTC = new /obj/item/magic_tarot_card(get_turf(src)) - var/obj/item/magic_tarot_card/MPC = new /obj/item/magic_tarot_card(get_turf(src)) - H.put_in_hands(MTC) - H.put_in_hands(MPC) - -/datum/tarot/reversed/the_moon - name = "XVIII - The Moon?" - desc = "May you remember lost memories." - extended_desc = "will reveal the memories of everyone in range to the user." - card_icon = "the_moon?" - antimagic_flags = MAGIC_RESISTANCE|MAGIC_RESISTANCE_MIND - -/datum/tarot/reversed/the_moon/activate(mob/living/target) - for(var/mob/living/L in view(5, target)) //Shorter range as this kinda can give away antagonists, though that is also funny. - target.mind.show_memory(L, 0) //Safe code? Bank accounts? PDA codes? It's yours my friend, as long as you have enough tarots - -/datum/tarot/reversed/the_sun - name = "XIX - The Sun?" - desc = "May the darkness swallow all around you." - extended_desc = "makes the user emit darkness, freezing anyone nearby. They will also become nearsighted for the duration, however." - card_icon = "the_sun?" - -/datum/tarot/reversed/the_sun/activate(mob/living/target) - target.apply_status_effect(STATUS_EFFECT_REVERSED_SUN) - -/datum/tarot/reversed/judgement - name = "XX - Judgement?" - desc = "May you redeem those found wanting." //Who wants more, but ghosts for something interesting - extended_desc = "nudges the future events of this shift to be more... interesting." - card_icon = "judgement?" - -/datum/tarot/reversed/judgement/activate(mob/living/target) - var/datum/event_container/EC = SSevents.event_containers[EVENT_LEVEL_MODERATE] - var/decrease = 5 MINUTES - EC.next_event_time -= decrease - log_and_message_admins("decreased timer for [GLOB.severity_to_string[EC.severity]] events by 5 minutes by use of a [src].") - -/datum/tarot/reversed/the_world - name = "XXI - The World?" - desc = "Step into the abyss." - extended_desc = "teleports the user to the mining outpost." - card_icon = "the_world?" - -/datum/tarot/reversed/the_world/activate(mob/living/target) - var/list/L = list() - for(var/turf/T in get_area_turfs(/area/mine/outpost)) //Lavaland is the abyss, but also too hot to send people too. Mining base should be fair! - if(is_blocked_turf(T)) - continue - L.Add(T) - - if(!length(L)) - to_chat(target, "Hmm. No base? A miner issue.") - return - if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT) - return FALSE - target.forceMove(pick(L)) - to_chat(target, "You are abruptly pulled through space!") diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm deleted file mode 100644 index 4c6ffbd43a064..0000000000000 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ /dev/null @@ -1,186 +0,0 @@ -//In this file: Summon Magic/Summon Guns/Summon Events - -// 1 in 50 chance of getting something really special. -#define SPECIALIST_MAGIC_PROB 2 - -GLOBAL_LIST_INIT(summoned_guns, list( - /obj/item/gun/energy/disabler, - /obj/item/gun/energy/gun, - /obj/item/gun/energy/gun/advtaser, - /obj/item/gun/energy/laser, - /obj/item/gun/projectile/revolver, - /obj/item/gun/energy/detective, - /obj/item/gun/projectile/automatic/pistol/deagle/camo, - /obj/item/gun/projectile/automatic/gyropistol, - /obj/item/gun/energy/pulse, - /obj/item/gun/projectile/automatic/pistol, - /obj/item/gun/projectile/revolver/doublebarrel, - /obj/item/gun/projectile/shotgun, - /obj/item/gun/projectile/shotgun/automatic/combat, - /obj/item/gun/projectile/automatic/ar, - /obj/item/gun/projectile/revolver/mateba, - /obj/item/gun/projectile/shotgun/boltaction, - /obj/item/gun/projectile/automatic/mini_uzi, - /obj/item/gun/energy/lasercannon, - /obj/item/gun/energy/kinetic_accelerator/crossbow/large, - /obj/item/gun/energy/gun/nuclear, - /obj/item/gun/projectile/automatic/proto, - /obj/item/gun/projectile/automatic/c20r, - /obj/item/gun/projectile/automatic/l6_saw, - /obj/item/gun/projectile/automatic/m90, - /obj/item/gun/energy/alien, - /obj/item/gun/energy/pulse/carbine, - /obj/item/gun/energy/decloner, - /obj/item/gun/energy/mindflayer, - /obj/item/gun/energy/kinetic_accelerator, - /obj/item/gun/energy/plasmacutter/adv, - /obj/item/gun/energy/wormhole_projector, - /obj/item/gun/projectile/automatic/wt550, - /obj/item/gun/projectile/automatic/shotgun/bulldog, - /obj/item/gun/projectile/revolver/grenadelauncher, - /obj/item/gun/projectile/revolver/golden, - /obj/item/gun/projectile/automatic/sniper_rifle, - /obj/item/gun/medbeam, - /obj/item/gun/energy/laser/scatter, - /obj/item/gun/projectile/automatic/c20r/toy/riot, - /obj/item/gun/projectile/shotgun/automatic/dual_tube, - /obj/item/gun/energy/kinetic_accelerator/experimental, // even with atmos, this thing can get scary - /obj/item/gun/energy/emitter, - /obj/item/gun/energy/spikethrower, - /obj/item/gun/energy/bsg/prebuilt, - /obj/item/gun/energy/xray, - /obj/item/gun/energy/plasma_pistol, - /obj/item/gun/projectile/automatic/pistol/aps, // whyyy is this capitalized - /obj/item/gun/projectile/revolver/overgrown, - /obj/item/gun/energy/gun/blueshield/pdw9, - /obj/item/gun/energy/disabler/silencer, - /obj/item/gun/energy/lwap, - /obj/item/gun/energy/arc_revolver, - /obj/item/gun/projectile/automatic/ak814)) - -//if you add anything that isn't covered by the typepaths below, add it to summon_magic_objective_types -GLOBAL_LIST_INIT(summoned_magic, list( - /obj/item/spellbook/oneuse/fireball, - /obj/item/spellbook/oneuse/smoke, - /obj/item/spellbook/oneuse/blind, - /obj/item/spellbook/oneuse/mindswap, - /obj/item/spellbook/oneuse/forcewall, - /obj/item/spellbook/oneuse/knock, - /obj/item/spellbook/oneuse/horsemask, - /obj/item/spellbook/oneuse/charge, - /obj/item/spellbook/oneuse/summonitem, - /obj/item/gun/magic/wand, - /obj/item/gun/magic/wand/resurrection, - /obj/item/gun/magic/wand/teleport, - /obj/item/gun/magic/wand/door, - /obj/item/gun/magic/wand/fireball, - /obj/item/gun/magic/staff/healing, - /obj/item/gun/magic/staff/door, - /obj/item/scrying, - /obj/item/clothing/suit/space/hardsuit/wizard, - /obj/item/immortality_talisman, - /obj/item/melee/ghost_sword, - /obj/item/tarot_card_pack, - /obj/item/tarot_card_pack/jumbo)) - -GLOBAL_LIST_INIT(summoned_special_magic, list( - /obj/item/gun/magic/staff/animate, - /obj/item/storage/belt/wands/full, - /obj/item/contract, - /obj/item/gun/magic/staff/chaos, - /obj/item/necromantic_stone, - /obj/item/blood_contract, - /obj/item/tarot_generator)) - -//everything above except for single use spellbooks, because they are counted separately (and are for basic bitches anyways) -GLOBAL_LIST_INIT(summoned_magic_objectives, list( - /obj/item/contract, - /obj/item/blood_contract, - /obj/item/clothing/suit/space/hardsuit/wizard, - /obj/item/gun/magic, - /obj/item/immortality_talisman, - /obj/item/melee/ghost_sword, - /obj/item/necromantic_stone, - /obj/item/scrying, - /obj/item/spellbook, - /obj/item/storage/belt/wands/full, - /obj/item/tarot_generator)) - -// If true, it's the probability of triggering "survivor" antag. -GLOBAL_VAR_INIT(summon_guns_triggered, FALSE) -GLOBAL_VAR_INIT(summon_magic_triggered, FALSE) - -/proc/give_guns(mob/living/carbon/human/H) - if(H.stat == DEAD || !(H.client)) - return - if(H.mind) - if(iswizard(H) || H.mind.offstation_role) - return - - if(prob(GLOB.summon_guns_triggered) && !(H.mind in SSticker.mode.traitors)) - SSticker.mode.traitors += H.mind - - H.mind.add_antag_datum(/datum/antagonist/survivalist/guns) - H.create_attack_log("was made into a survivalist, and trusts no one!") - H.create_log(CONVERSION_LOG, "was made into a survivalist") - - var/gun_type = pick(GLOB.summoned_guns) - var/obj/item/gun/G = new gun_type(get_turf(H)) - playsound(get_turf(H),'sound/magic/summon_guns.ogg', 50, TRUE) - - var/in_hand = H.put_in_hands(G) // not always successful - - to_chat(H, "\A [G] appears [in_hand ? "in your hand" : "at your feet"]!") - -/proc/give_magic(mob/living/carbon/human/H) - if(H.stat == DEAD || !(H.client)) - return - if(H.mind) - if(iswizard(H) || H.mind.offstation_role) - return - - if(prob(GLOB.summon_magic_triggered) && !(H.mind in SSticker.mode.traitors) && !jobban_isbanned(H, ROLE_SYNDICATE)) - SSticker.mode.traitors += H.mind - - H.mind.add_antag_datum(/datum/antagonist/survivalist/magic) - H.create_attack_log("was made into a survivalist, and trusts no one!") - H.create_log(CONVERSION_LOG, "was made into a survivalist") - - var/magic_type = pick(GLOB.summoned_magic) - var/lucky = FALSE - if(prob(SPECIALIST_MAGIC_PROB)) - magic_type = pick(GLOB.summoned_special_magic) - lucky = TRUE - - var/obj/item/M = new magic_type(get_turf(H)) - playsound(get_turf(H),'sound/magic/summon_magic.ogg', 50, TRUE) - - var/in_hand = H.put_in_hands(M) - - to_chat(H, "\A [M] appears [in_hand ? "in your hand" : "at your feet"]!") - if(lucky) - to_chat(H, "You feel incredibly lucky.") - -/proc/rightandwrong(summon_type, mob/user, survivor_probability) - if(user) //in this case either someone holding a spellbook or a badmin - to_chat(user, "You summoned [summon_type]!") - message_admins("[ADMIN_LOOKUPFLW(user)] summoned [summon_type]!") - log_game("[key_name(user)] summoned [summon_type]!") - - if(summon_type == SUMMON_MAGIC) - GLOB.summon_magic_triggered = survivor_probability - else if(summon_type == SUMMON_GUNS) - GLOB.summon_guns_triggered = survivor_probability - else - CRASH("Bad summon_type given: [summon_type]") - - for(var/mob/living/carbon/human/H in GLOB.player_list) - var/turf/T = get_turf(H) - if(T && is_away_level(T.z)) - continue - if(summon_type == SUMMON_MAGIC) - give_magic(H) - else - give_guns(H) - -#undef SPECIALIST_MAGIC_PROB diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm deleted file mode 100644 index 087734dee174b..0000000000000 --- a/code/game/gamemodes/wizard/spellbook.dm +++ /dev/null @@ -1,1164 +0,0 @@ -/datum/spellbook_entry - var/name = "Entry Name" - var/is_ragin_restricted = FALSE // FALSE if this is buyable on ragin mages, TRUE if it's not. - var/spell_type = null - var/desc = "" - var/category = "Offensive" - var/cost = 2 - var/refundable = TRUE - var/datum/spell/S = null //Since spellbooks can be used by only one person anyway we can track the actual spell - var/buy_word = "Learn" - var/limit //used to prevent a spellbook_entry from being bought more than X times with one wizard spellbook - -/datum/spellbook_entry/proc/CanBuy(mob/living/carbon/human/user, obj/item/spellbook/book) // Specific circumstances - if(book.uses < cost || limit == 0) - return FALSE - return TRUE - -/datum/spellbook_entry/proc/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) //return TRUE on success - if(!S) - S = new spell_type() - - return LearnSpell(user, book, S) - -/datum/spellbook_entry/proc/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, datum/spell/newspell) - for(var/datum/spell/aspell in user.mind.spell_list) - if(initial(newspell.name) == initial(aspell.name)) // Not using directly in case it was learned from one spellbook then upgraded in another - if(aspell.spell_level >= aspell.level_max) - to_chat(user, "This spell cannot be improved further.") - return FALSE - else - aspell.name = initial(aspell.name) - aspell.spell_level++ - aspell.cooldown_handler.recharge_duration = round(aspell.base_cooldown - aspell.spell_level * (aspell.base_cooldown - aspell.cooldown_min) / aspell.level_max) - switch(aspell.spell_level) - if(1) - to_chat(user, "You have improved [aspell.name] into Efficient [aspell.name].") - aspell.name = "Efficient [aspell.name]" - if(2) - to_chat(user, "You have further improved [aspell.name] into Quickened [aspell.name].") - aspell.name = "Quickened [aspell.name]" - if(3) - to_chat(user, "You have further improved [aspell.name] into Free [aspell.name].") - aspell.name = "Free [aspell.name]" - if(4) - to_chat(user, "You have further improved [aspell.name] into Instant [aspell.name].") - aspell.name = "Instant [aspell.name]" - if(aspell.spell_level >= aspell.level_max) - to_chat(user, "This spell cannot be strengthened any further.") - aspell.on_purchase_upgrade() - return TRUE - //No same spell found - just learn it - SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name) - user.mind.AddSpell(newspell) - to_chat(user, "You have learned [newspell.name].") - return TRUE - -/datum/spellbook_entry/proc/CanRefund(mob/living/carbon/human/user, obj/item/spellbook/book) - if(!refundable) - return FALSE - if(!S) - S = new spell_type() - for(var/datum/spell/aspell in user.mind.spell_list) - if(initial(S.name) == initial(aspell.name)) - return TRUE - return FALSE - -/datum/spellbook_entry/proc/Refund(mob/living/carbon/human/user, obj/item/spellbook/book) //return point value or -1 for failure - if(!istype(get_area(user), /area/wizard_station)) - to_chat(user, "You can only refund spells at the wizard lair.") - return -1 - if(!S) //This happens when the spell's source is from another spellbook, from loadouts, or adminery, this create a new template temporary spell - S = new spell_type() - var/spell_levels = 0 - for(var/datum/spell/aspell in user.mind.spell_list) - if(initial(S.name) == initial(aspell.name)) - spell_levels = aspell.spell_level - user.mind.spell_list.Remove(aspell) - qdel(aspell) - if(S) //If we created a temporary spell above, delete it now. - QDEL_NULL(S) - return cost * (spell_levels + 1) - return -1 - -/datum/spellbook_entry/proc/GetInfo() - if(!S) - S = new spell_type() - var/dat ="" - dat += "[name]" - dat += " Cooldown:[S.base_cooldown/10]" - dat += " Cost:[cost]
    " - dat += "[S.desc][desc]
    " - dat += "[S.clothes_req?"Needs wizard garb":"Can be cast without wizard garb"]
    " - return dat - -//Main category - Spells -//Offensive -/datum/spellbook_entry/blind - name = "Blind" - spell_type = /datum/spell/blind - category = "Offensive" - cost = 1 - -/datum/spellbook_entry/lightningbolt - name = "Lightning Bolt" - spell_type = /datum/spell/charge_up/bounce/lightning - category = "Offensive" - cost = 1 - -/datum/spellbook_entry/cluwne - name = "Curse of the Cluwne" - spell_type = /datum/spell/touch/cluwne - category = "Offensive" - -/datum/spellbook_entry/banana_touch - name = "Banana Touch" - spell_type = /datum/spell/touch/banana - cost = 1 - -/datum/spellbook_entry/mime_malaise - name = "Mime Malaise" - spell_type = /datum/spell/touch/mime_malaise - cost = 1 - -/datum/spellbook_entry/horseman - name = "Curse of the Horseman" - spell_type = /datum/spell/horsemask - category = "Offensive" - -/datum/spellbook_entry/disintegrate - name = "Disintegrate" - spell_type = /datum/spell/touch/disintegrate - category = "Offensive" - -/datum/spellbook_entry/corpse_explosion - name = "Corpse Explosion" - spell_type = /datum/spell/corpse_explosion - category = "Offensive" - -/datum/spellbook_entry/fireball - name = "Fireball" - spell_type = /datum/spell/fireball - category = "Offensive" - -/datum/spellbook_entry/summon_toolbox - name = "Homing Toolbox" - spell_type = /datum/spell/fireball/toolbox - category = "Offensive" - cost = 1 - -/datum/spellbook_entry/fleshtostone - name = "Flesh to Stone" - spell_type = /datum/spell/touch/flesh_to_stone - category = "Offensive" - -/datum/spellbook_entry/plushify - name = "Plushify" - spell_type = /datum/spell/touch/plushify - category = "Offensive" - -/datum/spellbook_entry/mutate - name = "Mutate" - spell_type = /datum/spell/genetic/mutate - category = "Offensive" - -/datum/spellbook_entry/rod_form - name = "Rod Form" - spell_type = /datum/spell/rod_form - category = "Offensive" - -/datum/spellbook_entry/infinite_guns - name = "Lesser Summon Guns" - spell_type = /datum/spell/infinite_guns - category = "Offensive" - -//Defensive -/datum/spellbook_entry/disabletech - name = "Disable Tech" - spell_type = /datum/spell/emplosion/disable_tech - category = "Defensive" - cost = 1 - -/datum/spellbook_entry/forcewall - name = "Force Wall" - spell_type = /datum/spell/forcewall - category = "Defensive" - cost = 1 - -/datum/spellbook_entry/rathens - name = "Rathen's Secret" - spell_type = /datum/spell/rathens - category = "Defensive" - cost = 2 - -/datum/spellbook_entry/repulse - name = "Repulse" - spell_type = /datum/spell/aoe/repulse - category = "Defensive" - cost = 1 - -/datum/spellbook_entry/smoke - name = "Smoke" - spell_type = /datum/spell/smoke - category = "Defensive" - cost = 1 - -/datum/spellbook_entry/lichdom - name = "Bind Soul" - spell_type = /datum/spell/lichdom - category = "Defensive" - is_ragin_restricted = TRUE - -/datum/spellbook_entry/magicm - name = "Magic Missile" - spell_type = /datum/spell/projectile/magic_missile - category = "Defensive" - -/datum/spellbook_entry/timestop - name = "Time Stop" - spell_type = /datum/spell/aoe/conjure/timestop - category = "Defensive" - -/datum/spellbook_entry/sacred_flame - name = "Sacred Flame and Fire Immunity" - spell_type = /datum/spell/sacred_flame - cost = 1 - category = "Defensive" - -/datum/spellbook_entry/sacred_flame/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, datum/spell/newspell) - to_chat(user, "You feel fireproof.") - ADD_TRAIT(user, TRAIT_RESISTHEAT, MAGIC_TRAIT) - ADD_TRAIT(user, TRAIT_RESISTHIGHPRESSURE, MAGIC_TRAIT) - return ..() - -/datum/spellbook_entry/sacred_flame/Refund(mob/living/carbon/human/user, obj/item/spellbook/book) - to_chat(user, "You no longer feel fireproof.") - REMOVE_TRAIT(user, TRAIT_RESISTHEAT, MAGIC_TRAIT) - REMOVE_TRAIT(user, TRAIT_RESISTHIGHPRESSURE, MAGIC_TRAIT) - return ..() - -/datum/spellbook_entry/summon_supermatter - name = "Summon Supermatter Crystal" - spell_type = /datum/spell/aoe/conjure/summon_supermatter - cost = 3 - category = "Defensive" - -/datum/spellbook_entry/summon_supermatter/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, datum/spell/newspell) - to_chat(user, "You feel a little bit of supermatter enter your body.") - ADD_TRAIT(user, TRAIT_RADIMMUNE, MAGIC_TRAIT) - ADD_TRAIT(user, SM_HALLUCINATION_IMMUNE, MAGIC_TRAIT) - return ..() - -/datum/spellbook_entry/summon_supermatter/Refund(mob/living/carbon/human/user, obj/item/spellbook/book) - to_chat(user, "A little bit of supermatter leaves your body. So does that metallic taste in your mouth.") - REMOVE_TRAIT(user, TRAIT_RADIMMUNE, MAGIC_TRAIT) - REMOVE_TRAIT(user, SM_HALLUCINATION_IMMUNE, MAGIC_TRAIT) - return ..() - -//Mobility -/datum/spellbook_entry/knock - name = "Knock" - spell_type = /datum/spell/aoe/knock - category = "Mobility" - cost = 1 - -/datum/spellbook_entry/blink - name = "Blink" - spell_type = /datum/spell/turf_teleport/blink - category = "Mobility" - -/datum/spellbook_entry/jaunt - name = "Ethereal Jaunt" - spell_type = /datum/spell/ethereal_jaunt - category = "Mobility" - -/datum/spellbook_entry/spacetime_dist - name = "Spacetime Distortion" - spell_type = /datum/spell/spacetime_dist - cost = 1 //Better defence than greater forcewall (maybe) but good luck hitting anyone, so 1 point. - category = "Mobility" - -/datum/spellbook_entry/greaterknock - name = "Greater Knock" - spell_type = /datum/spell/aoe/knock/greater - category = "Mobility" - refundable = 0 //global effect on cast - -/datum/spellbook_entry/mindswap - name = "Mindswap" - spell_type = /datum/spell/mind_transfer - category = "Mobility" - -/datum/spellbook_entry/teleport - name = "Teleport" - spell_type = /datum/spell/area_teleport/teleport - category = "Mobility" - -//Assistance -/datum/spellbook_entry/charge - name = "Charge" - spell_type = /datum/spell/charge - category = "Assistance" - cost = 1 - -/datum/spellbook_entry/summonitem - name = "Summon Item" - spell_type = /datum/spell/summonitem - category = "Assistance" - cost = 1 - -/datum/spellbook_entry/disguiseself - name = "Disguise Self" - spell_type = /datum/spell/disguise_self - category = "Assistance" - cost = 1 - -/datum/spellbook_entry/noclothes - name = "Remove Clothes Requirement" - spell_type = /datum/spell/noclothes - category = "Assistance" - cost = 1 - -//Rituals -/datum/spellbook_entry/summon - name = "Summon Stuff" - category = "Rituals" - refundable = FALSE - buy_word = "Cast" - var/active = FALSE - -/datum/spellbook_entry/summon/CanBuy(mob/living/carbon/human/user, obj/item/spellbook/book) - return ..() && !active - -/datum/spellbook_entry/summon/GetInfo() - var/dat ="" - dat += "[name]" - if(cost == 0) - dat += " No Cost
    " - else - dat += " Cost:[cost]
    " - dat += "[desc]
    " - if(active) - dat += "Already cast!
    " - return dat - -/datum/spellbook_entry/summon/ghosts - name = "Summon Ghosts" - desc = "Spook the crew out by making them see dead people. Be warned, ghosts are capricious and occasionally vindicative, and some will use their incredibly minor abilities to frustrate you." - cost = 0 - is_ragin_restricted = TRUE - -/datum/spellbook_entry/summon/ghosts/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) - new /datum/event/wizard/ghost() - active = TRUE - to_chat(user, "You have cast summon ghosts!") - playsound(get_turf(user), 'sound/effects/ghost2.ogg', 50, 1) - return TRUE - -/datum/spellbook_entry/summon/slience_ghosts - name = "Silence Ghosts" - desc = "Tired of people talking behind your back, and spooking you? Why not silence them, and make the dead deader." - cost = 2 - is_ragin_restricted = TRUE //Salt needs to flow here, to be honest - -/datum/spellbook_entry/summon/slience_ghosts/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) - new /datum/event/wizard/ghost_mute() - active = TRUE - to_chat(user, "You have silenced all ghosts!") - playsound(get_turf(user), 'sound/effects/ghost.ogg', 50, 1) - message_admins("[key_name_admin(usr)] silenced all ghosts as a wizard! (Deadchat is now DISABLED)") - return TRUE - -/datum/spellbook_entry/summon/guns - name = "Summon Guns" - desc = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill you. There is a good chance that they will shoot each other first. Hopefully. Gives you 2 extra spell points on purchase." - cost = -2 - is_ragin_restricted = TRUE - -/datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) - SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name) - rightandwrong(SUMMON_GUNS, user, 10) - active = TRUE - playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, TRUE) - to_chat(user, "You have cast summon guns!") - return TRUE - -/datum/spellbook_entry/summon/magic - name = "Summon Magic" - desc = "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time. Gives you 2 extra spell points on purchase." - cost = -2 - is_ragin_restricted = TRUE - -/datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) - SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name) - rightandwrong(SUMMON_MAGIC, user, 10) - active = TRUE - playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, TRUE) - to_chat(user, "You have cast summon magic!") - return TRUE - -//Main category - Magical Items -/datum/spellbook_entry/item - name = "Buy Item" - refundable = 0 - buy_word = "Summon" - var/spawn_on_floor = FALSE - var/item_path = null - -/datum/spellbook_entry/item/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) - if(!spawn_on_floor) - user.put_in_hands(new item_path) - else - new item_path(user.loc) - SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name) - return 1 - -/datum/spellbook_entry/item/GetInfo() - var/dat ="" - dat += "[name]" - dat += " Cost:[cost]
    " - dat += "[desc]
    " - return dat - -//Artefacts -/datum/spellbook_entry/item/necrostone - name = "A Necromantic Stone" - desc = "A Necromantic stone is able to resurrect three dead individuals as skeletal thralls for you to command." - item_path = /obj/item/necromantic_stone - category = "Artefacts" - -/datum/spellbook_entry/item/scryingorb - name = "Scrying Orb" - desc = "An incandescent orb of crackling energy, using it will allow you to ghost while alive, allowing you to spy upon the station with ease. In addition, buying it will permanently grant you x-ray vision. It will also work as an excellent throwing weapon, and will return to your hand after throwing." - item_path = /obj/item/scrying - category = "Artefacts" - -/datum/spellbook_entry/item/soulstones - name = "Six Soul Stone Shards and the spell Artificer" - desc = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot." - item_path = /obj/item/storage/belt/soulstone/full - category = "Artefacts" - -/datum/spellbook_entry/item/soulstones/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) - . = ..() - if(.) - user.mind.AddSpell(new /datum/spell/aoe/conjure/construct(null)) - -/datum/spellbook_entry/item/wands - name = "Wand Assortment" - desc = "A collection of wands that allow for a wide variety of utility. Wands do not recharge, so be conservative in use. Comes in a handy belt." - item_path = /obj/item/storage/belt/wands/full - category = "Artefacts" - -/datum/spellbook_entry/item/magic_nanny_bag - name = "Magic Nanny Bag" - desc = "A magical bottomless bag that comes filled with many random goodies, and sticks well in your hand. Will have a melee weapon, a staff, a wand, an artifact, and a special food treat! Can't fit on your back." - item_path = /obj/item/storage/backpack/duffel/magic_nanny_bag - cost = 4 - spawn_on_floor = TRUE // it isn't happy if it has to remake itself in hand - is_ragin_restricted = TRUE //No blocked magic items on raging, sorry! - category = "Artefacts" - -/datum/spellbook_entry/item/cursed_heart - name = "Cursed Heart" - desc = "A heart that has been empowered with magic to heal the user. The user must ensure the heart is manually beaten or their blood circulation will suffer, but every beat heals their injuries. It must beat every 6 seconds. Not reccomended for first time wizards." - item_path = /obj/item/organ/internal/heart/cursed/wizard - cost = 1 - category = "Artefacts" - -/datum/spellbook_entry/item/voice_of_god - name = "Voice of God" - desc = "A magical vocal cord that can be used to yell out with the voice of a god, be it to harm, help, or confuse the target." - item_path = /obj/item/organ/internal/vocal_cords/colossus/wizard - category = "Artefacts" - -/datum/spellbook_entry/item/warp_cubes - name = "Warp Cubes" - desc = "Two magic cubes, that when they are twisted in hand, teleports the user to the location of the other cube instantly. Great for silently teleporting to a fixed location, or teleporting you to an apprentice, or vice versa. Do not leave on the wizard den, it will not work." - item_path = /obj/item/warp_cube/red - cost = 1 - spawn_on_floor = TRUE // breaks if spawned in hand - category = "Artefacts" - -/datum/spellbook_entry/item/everfull_mug - name = "Everfull Mug" - desc = "A magical mug that can be filled with omnizine at will, though beware of addiction! It can also produce alchohol and other less useful substances." - item_path = /obj/item/reagent_containers/drinks/everfull - cost = 1 - category = "Artefacts" - -/datum/spellbook_entry/item/tarot_generator - name = "Enchanted tarot card deck" - desc = "An magic tarot card deck, enchanted with special Ink. \ - Capable of producing magic tarot cards of the 22 major arcana, both normal and reversed. Each card has a different effect. \ - Throw the card at someone to use it on them, or use it in hand to apply it to yourself. Unlimited uses, 12 second cooldown, can have up to 5 cards in the world." - item_path = /obj/item/tarot_generator/wizard - cost = 2 - category = "Artefacts" - -//Weapons and Armors -/datum/spellbook_entry/item/battlemage - name = "Battlemage Armor" - desc = "An ensorceled spaceproof suit of protective yet light armor, protected by a powerful shield. The shield can completely negate 15 attacks before permanently failing. \ - This armor grants you full protection from magical attacks, and allows you to cast magic despite that. However, this means it will also block wands or staffs of \ - healing from working on you, and should be removed before application." - item_path = /obj/item/storage/box/wizard/hardsuit - limit = 1 - category = "Weapons and Armors" - -/datum/spellbook_entry/item/mjolnir - name = "Mjolnir" - desc = "A mighty hammer on loan from Thor, God of Thunder. It crackles with barely contained power." - item_path = /obj/item/mjollnir - category = "Weapons and Armors" - -/datum/spellbook_entry/item/singularity_hammer - name = "Singularity Hammer" - desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everything nearby to the point of impact." - item_path = /obj/item/singularityhammer - category = "Weapons and Armors" - -/datum/spellbook_entry/item/cursed_katana - name = "Cursed Katana" - desc = "A cursed artefact, used to seal a horrible being inside the katana, which has now reformed. Can be used to make multiple powerful combos, examine it to see them. Can not be dropped. On death, you will dust." - item_path = /obj/item/organ/internal/cyberimp/arm/katana - cost = 1 - category = "Weapons and Armors" - -/datum/spellbook_entry/item/spell_blade - name = "Spellblade" - desc = "A magical sword that can be enchanted by using it in hand to have a unique on-hit effect. Lighting: arcs electricity between nearby targets, stunning and damaging them. Fire: creates a massive ball of fire on hit, and makes the wielder immune to fire. Bluespace: allows you to strike people from a range, teleporting you to them. Forceshield: on hit, makes you stun immune for 3 seconds and reduces damage by half. Spacetime: will slice faster but weaker and will curse the target, slashing them a few seconds after they have not been swinged at for each hit" - item_path = /obj/item/melee/spellblade - category = "Weapons and Armors" - -/datum/spellbook_entry/item/meat_hook - name = "Meat hook" - desc = "An enchanted hook, that can be used to hook people, hurt them, and bring them right to you. Quite bulky, works well as a belt though." - item_path = /obj/item/gun/magic/hook - cost = 1 - category = "Weapons and Armors" - -//Staves -/datum/spellbook_entry/item/staffdoor - name = "Staff of Door Creation" - desc = "A particular staff that can mold solid metal into ornate wooden doors. Useful for getting around in the absence of other transportation. Does not work on glass." - item_path = /obj/item/gun/magic/staff/door - category = "Staves" - cost = 1 - -/datum/spellbook_entry/item/staffhealing - name = "Staff of Healing" - desc = "An altruistic staff that can heal the lame and raise the dead." - item_path = /obj/item/gun/magic/staff/healing - category = "Staves" - cost = 1 - -/datum/spellbook_entry/item/staffslipping - name = "Staff of Slipping" - desc = "A staff that shoots magical bananas. These bananas will either slip or stun the target when hit. Surprisingly reliable!" - item_path = /obj/item/gun/magic/staff/slipping - category = "Staves" - cost = 1 - -/datum/spellbook_entry/item/staffanimation - name = "Staff of Animation" - desc = "An arcane staff capable of shooting bolts of eldritch energy which cause inanimate objects to come to life. This magic doesn't affect machines." - item_path = /obj/item/gun/magic/staff/animate - category = "Staves" - -/datum/spellbook_entry/item/staffchange - name = "Staff of Change" - desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself." - item_path = /obj/item/gun/magic/staff/change - category = "Staves" - is_ragin_restricted = TRUE - -/datum/spellbook_entry/item/staffchaos - name = "Staff of Chaos" - desc = "A curious staff firing bolts of chaotic energy. Any life struck will be the victim of a random effect, usually harming them. No effect on dead targets." - item_path = /obj/item/gun/magic/staff/chaos - category = "Staves" - -//Summons -/datum/spellbook_entry/item/oozebottle - name = "Bottle of Ooze" - desc = "A bottle of magically infused ooze, which will awake an all-consuming Morph, capable of cunningly disguising itself as any object it comes in contact with and even casting some very basic spells. Be careful though, as Morph diet includes Wizards." - item_path = /obj/item/antag_spawner/morph - category = "Summons" - limit = 3 - cost = 1 - is_ragin_restricted = TRUE - -/datum/spellbook_entry/item/hugbottle - name = "Bottle of Tickles" - desc = "A bottle of magically infused fun, the smell of which will \ - attract adorable extradimensional beings when broken. These beings \ - are similar to slaughter demons, but are a little weaker and they do not permanently \ - kill their victims, instead putting them in an extradimensional hugspace, \ - to be released on the demon's death. Chaotic, but not ultimately \ - damaging. The crew's reaction to the other hand could be very \ - destructive." - item_path = /obj/item/antag_spawner/slaughter_demon/laughter - category = "Summons" - limit = 3 - cost = 1 // Non-destructive; it's just a jape, sibling! - -/datum/spellbook_entry/item/bloodbottle - name = "Bottle of Blood" - desc = "A bottle of magically infused blood, the smell of which will attract extradimensional beings when broken. Be careful though, the kinds of creatures summoned by blood magic are indiscriminate in their killing, and you yourself may become a victim." - item_path = /obj/item/antag_spawner/slaughter_demon - category = "Summons" - limit = 3 - is_ragin_restricted = TRUE - -/datum/spellbook_entry/item/shadowbottle - name = "Bottle of Shadows" - desc = "A bottle of pure darkness, the smell of which will attract extradimensional beings when broken. Be careful though, the kinds of creatures summoned from the shadows are indiscriminate in their killing, and you yourself may become a victim." - item_path = /obj/item/antag_spawner/slaughter_demon/shadow - category = "Summons" - limit = 3 - cost = 1 //Unless you blackout the station this ain't going to do much, wizard doesn't get NV, still dies easily to a group of 2 and it doesn't eat bodies. - -/datum/spellbook_entry/item/revenantbottle - name = "Bottle of Ectoplasm" - desc = "A magically infused bottle of ectoplasm, effectively pure salt from the spectral realm. Be careful though, these salty spirits are indiscriminate in their harvesting, and you yourself may become a victim." - item_path = /obj/item/antag_spawner/revenant - category = "Summons" - limit = 3 - cost = 1 //Needs essence to live. Needs crew to die for essence, doubt xenobio will be making many monkeys. As such, weaker. Also can hardstun the wizard. - -/datum/spellbook_entry/item/pulsedemonbottle - name = "Living Lightbulb" - desc = "A magically sealed lightbulb confining some manner of electricity based creature. Beware, these creatures are indiscriminate in their shocking antics, and you yourself may become a victim. It is *heavily* advised not to summon it in maintenance areas." - item_path = /obj/item/antag_spawner/pulse_demon - category = "Summons" - limit = 3 - cost = 1 // Needs station power to live. Also can kill the wizard trivially in maints (get shock protection). - -/datum/spellbook_entry/item/contract - name = "Contract of Apprenticeship" - desc = "A magical contract binding an apprentice wizard to your service, using it will summon them to your side." - item_path = /obj/item/contract - category = "Summons" - limit = 1 - is_ragin_restricted = TRUE //We have enough wizards already! Sheesh! - -/datum/spellbook_entry/item/tarotdeck - name = "Guardian Deck" - desc = "A deck of guardian tarot cards, capable of binding a personal guardian to your body. There are multiple types of guardian available, but all of them will transfer some amount of damage to you. \ - It would be wise to avoid buying these with anything capable of causing you to swap bodies with others." - item_path = /obj/item/guardiancreator - category = "Summons" - limit = 1 - -//Spell loadouts datum, list of loadouts is in wizloadouts.dm -/datum/spellbook_entry/loadout - name = "Standard Loadout" - cost = 10 - category = "Standard" - refundable = FALSE - buy_word = "Summon" - var/list/items_path = list() - var/list/spells_path = list() - var/destroy_spellbook = FALSE //Destroy the spellbook when bought, for loadouts containing non-standard items/spells, otherwise wiz can refund spells - -/datum/spellbook_entry/loadout/GetInfo() - var/dat = "" - dat += "[name]" - if(cost > 0) - dat += " Cost:[cost]
    " - else - dat += " No Cost
    " - dat += "[desc]
    " - return dat - -/datum/spellbook_entry/loadout/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) - if(destroy_spellbook) - var/response = tgui_alert(user, "The [src] loadout cannot be refunded once bought. Are you sure this is what you want?", "No refunds!", list("No", "Yes")) - if(response != "Yes") - return FALSE - if(!CanBuy(user, book)) - to_chat(user, "You can't afford that anymore!") - return FALSE - to_chat(user, "[book] crumbles to ashes as you acquire its knowledge.") - qdel(book) - else if(length(items_path)) - var/response = tgui_alert(user, "The [src] loadout contains items that will not be refundable if bought. Are you sure this is what you want?", "No refunds!", list("No", "Yes")) - if(response != "Yes") - return FALSE - if(!CanBuy(user, book)) - to_chat(user, "You can't afford that anymore!") - return FALSE - if(length(items_path)) - var/obj/item/storage/box/wizard/B = new(src) - for(var/path in items_path) - new path(B) - user.put_in_hands(B) - for(var/path in spells_path) - var/datum/spell/S = new path() - LearnSpell(user, book, S) - OnBuy(user, book) - return TRUE - -/datum/spellbook_entry/loadout/proc/OnBuy(mob/living/carbon/human/user, obj/item/spellbook/book) - return - -/obj/item/spellbook - name = "spell book" - desc = "The legendary book of spells of the wizard." - icon = 'icons/obj/library.dmi' - icon_state = "spellbook" - throw_speed = 2 - throw_range = 5 - w_class = WEIGHT_CLASS_TINY - var/uses = 10 - var/temp = null - var/op = 1 - var/tab = null - var/main_tab = null - var/mob/living/carbon/human/owner - var/list/datum/spellbook_entry/entries = list() - var/list/categories = list() - var/list/main_categories = list("Spells", "Magical Items", "Loadouts") - var/list/spell_categories = list("Offensive", "Defensive", "Mobility", "Assistance", "Rituals") - var/list/item_categories = list("Artefacts", "Weapons and Armors", "Staves", "Summons") - var/list/loadout_categories = list("Standard", "Unique") - -/obj/item/spellbook/proc/initialize() - var/entry_types = subtypesof(/datum/spellbook_entry) - /datum/spellbook_entry/item - /datum/spellbook_entry/summon - /datum/spellbook_entry/loadout - for(var/T in entry_types) - var/datum/spellbook_entry/E = new T - if(GAMEMODE_IS_RAGIN_MAGES && E.is_ragin_restricted) - qdel(E) - continue - entries |= E - categories |= E.category - - main_tab = main_categories[1] - tab = categories[1] - -/obj/item/spellbook/New() - ..() - initialize() - -/obj/item/spellbook/attackby__legacy__attackchain(obj/item/O as obj, mob/user as mob, params) - if(istype(O, /obj/item/contract)) - var/obj/item/contract/contract = O - if(contract.used) - to_chat(user, "The contract has been used, you can't get your points back now!") - else - to_chat(user, "You feed the contract back into the spellbook, refunding your points.") - uses+=2 - qdel(O) - return - - if(istype(O, /obj/item/antag_spawner/slaughter_demon)) - to_chat(user, "On second thought, maybe summoning a demon is a bad idea. You refund your points.") - if(istype(O, /obj/item/antag_spawner/slaughter_demon/laughter)) - uses += 1 - for(var/datum/spellbook_entry/item/hugbottle/HB in entries) - if(!isnull(HB.limit)) - HB.limit++ - else if(istype(O, /obj/item/antag_spawner/slaughter_demon/shadow)) - uses += 1 - for(var/datum/spellbook_entry/item/shadowbottle/SB in entries) - if(!isnull(SB.limit)) - SB.limit++ - else - uses += 2 - for(var/datum/spellbook_entry/item/bloodbottle/BB in entries) - if(!isnull(BB.limit)) - BB.limit++ - qdel(O) - return - - if(istype(O, /obj/item/antag_spawner/morph)) - to_chat(user, "On second thought, maybe awakening a morph is a bad idea. You refund your points.") - uses += 1 - for(var/datum/spellbook_entry/item/oozebottle/OB in entries) - if(!isnull(OB.limit)) - OB.limit++ - qdel(O) - return - - if(istype(O, /obj/item/antag_spawner/revenant)) - to_chat(user, "On second thought, maybe the ghosts have been salty enough today. You refund your points.") - uses += 1 - for(var/datum/spellbook_entry/item/revenantbottle/RB in entries) - if(!isnull(RB.limit)) - RB.limit++ - qdel(O) - return - return ..() - -/obj/item/spellbook/proc/GetCategoryHeader(category) - var/dat = "" - switch(category) - if("Offensive") - dat += "Spells geared towards debilitating and destroying.

    " - dat += "For spells: the number after the spell name is the cooldown time.
    " - dat += "You can reduce this number by spending more points on the spell.
    " - if("Defensive") - dat += "Spells geared towards improving your survivability or reducing foes ability to attack.

    " - dat += "For spells: the number after the spell name is the cooldown time.
    " - dat += "You can reduce this number by spending more points on the spell.
    " - if("Mobility") - dat += "Spells geared towards improving your ability to move. It is a good idea to take at least one.

    " - dat += "For spells: the number after the spell name is the cooldown time.
    " - dat += "You can reduce this number by spending more points on the spell.
    " - if("Assistance") - dat += "Spells geared towards improving your other items and abilities.

    " - dat += "For spells: the number after the spell name is the cooldown time.
    " - dat += "You can reduce this number by spending more points on the spell.
    " - if("Rituals") - dat += "These powerful spells are capable of changing the very fabric of reality. Not always in your favour.
    " - if("Weapons and Armors") - dat += "Various weapons and armors to crush your enemies and protect you from harm.

    " - dat += "Items are not bound to you and can be stolen. Additionally they cannot typically be returned once purchased.
    " - if("Staves") - dat += "Various staves granting you their power, which they slowly recharge over time.

    " - dat += "Items are not bound to you and can be stolen. Additionally they cannot typically be returned once purchased.
    " - if("Artefacts") - dat += "Various magical artefacts to aid you.

    " - dat += "Items are not bound to you and can be stolen. Additionally they cannot typically be returned once purchased.
    " - if("Summons") - dat += "Magical items geared towards bringing in outside forces to aid you.

    " - dat += "Items are not bound to you and can be stolen. Additionally they cannot typically be returned once purchased.
    " - if("Standard") - dat += "These battle-tested spell sets are easy to use and provide good balance between offense and defense.

    " - dat += "They all cost, and are worth, 10 spell points. You are able to refund any of the spells included as long as you stay in the wizard den.
    " - if("Unique") - dat += "These esoteric loadouts usually contain spells or items that cannot be bought elsewhere in this spellbook.

    " - dat += "Recommended for experienced wizards looking for something new. No refunds once purchased!
    " - return dat - -/obj/item/spellbook/proc/wrap(content) - var/dat = "" - dat +="Spellbook" - dat += {" - - - - "} - dat += {"[content]"} - return dat - -/obj/item/spellbook/attack_self__legacy__attackchain(mob/user as mob) - if(!owner) - to_chat(user, "You bind the spellbook to yourself.") - owner = user - return - if(user != owner) - to_chat(user, "[src] does not recognize you as it's owner and refuses to open!") - return - user.set_machine(src) - var/dat = "" - - dat += "
      " - var/list/cat_dat = list() - for(var/main_category in main_categories) - cat_dat[main_category] = "
      " - dat += "
    • [main_category]
    • " - dat += "
    " - dat += "
      " - switch(main_tab) - if("Spells") - for(var/category in categories) - if(category in spell_categories) - cat_dat[category] = "
      " - dat += "
    • [category]
    • " - if("Magical Items") - for(var/category in categories) - if(category in item_categories) - cat_dat[category] = "
      " - dat += "
    • [category]
    • " - if("Loadouts") - for(var/category in categories) - if(category in loadout_categories) - cat_dat[category] = "
      " - dat += "
    • [category]
    • " - dat += "
    • Points remaining : [uses]
    • " - dat += "
    " - - var/datum/spellbook_entry/E - for(var/i=1,i<=length(entries),i++) - var/spell_info = "" - E = entries[i] - spell_info += E.GetInfo() - if(E.CanBuy(user,src)) - spell_info+= "[E.buy_word]
    " - else - spell_info+= "Can't [E.buy_word]
    " - if(E.CanRefund(user,src)) - spell_info+= "Refund
    " - spell_info += "
    " - if(cat_dat[E.category]) - cat_dat[E.category] += spell_info - - for(var/category in categories) - dat += "
    " - dat += GetCategoryHeader(category) - dat += cat_dat[category] - dat += "
    " - - user << browse(wrap(dat), "window=spellbook;size=800x600") - onclose(user, "spellbook") - return - -/obj/item/spellbook/Topic(href, href_list) - if(..()) - return 1 - var/mob/living/carbon/human/H = usr - - if(!ishuman(H)) - return 1 - - if(H.mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE) - temp = "If you got caught sneaking a peak from your teacher's spellbook, you'd likely be expelled from the Wizard Academy. Better not." - return 1 - - var/datum/spellbook_entry/E = null - if(loc == H || (in_range(src, H) && isturf(loc))) - H.set_machine(src) - if(href_list["buy"]) - E = entries[text2num(href_list["buy"])] - if(E && E.CanBuy(H,src)) - if(E.Buy(H,src)) - if(E.limit) - E.limit-- - uses -= E.cost - else if(href_list["refund"]) - E = entries[text2num(href_list["refund"])] - if(E && E.refundable) - var/result = E.Refund(H,src) - if(result > 0) - if(!isnull(E.limit)) - E.limit += result - uses += result - else if(href_list["mainpage"]) - main_tab = sanitize(href_list["mainpage"]) - tab = sanitize(href_list["page"]) - if(main_tab == "Spells") - tab = spell_categories[1] - else if(main_tab == "Magical Items") - tab = item_categories[1] - else if(main_tab == "Loadouts") - tab = loadout_categories[1] - else if(href_list["page"]) - tab = sanitize(href_list["page"]) - attack_self__legacy__attackchain(H) - return 1 - -//Single Use Spellbooks -/obj/item/spellbook/oneuse - var/spell = /datum/spell/projectile/magic_missile //just a placeholder to avoid runtimes if someone spawned the generic - var/spellname = "sandbox" - var/used = FALSE - name = "spellbook of " - uses = 1 - desc = "This template spellbook was never meant for the eyes of man..." - -/obj/item/spellbook/oneuse/New() - ..() - name += spellname - -/obj/item/spellbook/oneuse/initialize() //No need to init - return - -/obj/item/spellbook/oneuse/attack_self__legacy__attackchain(mob/user) - var/datum/spell/S = new spell - for(var/datum/spell/knownspell in user.mind.spell_list) - if(knownspell.type == S.type) - if(user.mind) - if(user.mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE || user.mind.special_role == SPECIAL_ROLE_WIZARD) - to_chat(user, "You're already far more versed in this spell than this flimsy how-to book can provide.") - else - to_chat(user, "You've already read this one.") - return - if(used) - recoil(user) - else - user.mind.AddSpell(S) - to_chat(user, "you rapidly read through the arcane book. Suddenly you realize you understand [spellname]!") - user.create_log(MISC_LOG, "learned the spell [spellname] ([S])") - user.create_attack_log("[key_name(user)] learned the spell [spellname] ([S]).") - onlearned(user) - -/obj/item/spellbook/oneuse/proc/recoil(mob/user) - user.visible_message("[src] glows in a black light!") - -/obj/item/spellbook/oneuse/proc/onlearned(mob/user) - used = TRUE - user.visible_message("[src] glows dark for a second!") - -/obj/item/spellbook/oneuse/attackby__legacy__attackchain() - return - -/obj/item/spellbook/oneuse/fireball - spell = /datum/spell/fireball - spellname = "fireball" - icon_state = "bookfireball" - desc = "This book feels warm to the touch." - -/obj/item/spellbook/oneuse/fireball/recoil(mob/user as mob) - ..() - explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2) - qdel(src) - -/obj/item/spellbook/oneuse/smoke - spell = /datum/spell/smoke - spellname = "smoke" - icon_state = "booksmoke" - desc = "This book is overflowing with the dank arts." - -/obj/item/spellbook/oneuse/smoke/recoil(mob/user as mob) - ..() - to_chat(user, "Your stomach rumbles...") - user.adjust_nutrition(-200) - -/obj/item/spellbook/oneuse/blind - spell = /datum/spell/blind - spellname = "blind" - icon_state = "bookblind" - desc = "This book looks blurry, no matter how you look at it." - -/obj/item/spellbook/oneuse/blind/recoil(mob/user) - ..() - if(isliving(user)) - var/mob/living/L = user - to_chat(user, "You go blind!") - L.EyeBlind(20 SECONDS) - -/obj/item/spellbook/oneuse/mindswap - spell = /datum/spell/mind_transfer - spellname = "mindswap" - icon_state = "bookmindswap" - desc = "This book's cover is pristine, though its pages look ragged and torn." - var/mob/stored_swap = null //Used in used book recoils to store an identity for mindswaps - -/obj/item/spellbook/oneuse/mindswap/onlearned() - spellname = pick("fireball","smoke","blind","forcewall","knock","horses","charge") - icon_state = "book[spellname]" - name = "spellbook of [spellname]" //Note, desc doesn't change by design - ..() - -/obj/item/spellbook/oneuse/mindswap/recoil(mob/user) - ..() - if(stored_swap in GLOB.dead_mob_list) - stored_swap = null - if(!stored_swap) - stored_swap = user - to_chat(user, "For a moment you feel like you don't even know who you are anymore.") - return - if(stored_swap == user) - to_chat(user, "You stare at the book some more, but there doesn't seem to be anything else to learn...") - return - - var/datum/spell/mind_transfer/swapper = new - swapper.cast(user, stored_swap) - - to_chat(stored_swap, "You're suddenly somewhere else... and someone else?!") - to_chat(user, "Suddenly you're staring at [src] again... where are you, who are you?!") - stored_swap = null - -/obj/item/spellbook/oneuse/forcewall - spell = /datum/spell/forcewall - spellname = "forcewall" - icon_state = "bookforcewall" - desc = "This book has a dedication to mimes everywhere inside the front cover." - -/obj/item/spellbook/oneuse/forcewall/recoil(mob/user as mob) - ..() - to_chat(user, "You suddenly feel very solid!") - var/obj/structure/closet/statue/S = new /obj/structure/closet/statue(user.loc, user) - S.timer = 30 - user.drop_item() - -/obj/item/spellbook/oneuse/knock - spell = /datum/spell/aoe/knock - spellname = "knock" - icon_state = "bookknock" - desc = "This book is hard to hold closed properly." - -/obj/item/spellbook/oneuse/knock/recoil(mob/living/user) - ..() - to_chat(user, "You're knocked down!") - user.Weaken(40 SECONDS) - -/obj/item/spellbook/oneuse/horsemask - spell = /datum/spell/horsemask - spellname = "horses" - icon_state = "bookhorses" - desc = "This book is more horse than your mind has room for." - -/obj/item/spellbook/oneuse/horsemask/recoil(mob/living/carbon/user as mob) - if(ishuman(user)) - to_chat(user, "HOR-SIE HAS RISEN") - var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead - magichead.flags |= NODROP | DROPDEL //curses! - magichead.flags_inv = null //so you can still see their face - magichead.voicechange = TRUE //NEEEEIIGHH - if(!user.drop_item_to_ground(user.wear_mask)) - qdel(user.wear_mask) - user.equip_to_slot_if_possible(magichead, ITEM_SLOT_MASK, TRUE, TRUE) - qdel(src) - else - to_chat(user, "I say thee neigh") - -/obj/item/spellbook/oneuse/charge - spell = /datum/spell/charge - spellname = "charging" - icon_state = "bookcharge" - desc = "This book is made of 100% post-consumer wizard." - -/obj/item/spellbook/oneuse/charge/recoil(mob/user as mob) - ..() - to_chat(user, "[src] suddenly feels very warm!") - empulse(src, 1, 1) - -/obj/item/spellbook/oneuse/summonitem - spell = /datum/spell/summonitem - spellname = "instant summons" - icon_state = "booksummons" - desc = "This book is bright and garish, very hard to miss." - -/obj/item/spellbook/oneuse/summonitem/recoil(mob/user as mob) - ..() - to_chat(user, "[src] suddenly vanishes!") - qdel(src) - -/obj/item/spellbook/oneuse/fake_gib - spell = /datum/spell/touch/fake_disintegrate - spellname = "disintegrate" - icon_state = "bookfireball" - desc = "This book feels like it will rip stuff apart." - -/obj/item/spellbook/oneuse/sacredflame - spell = /datum/spell/sacred_flame - spellname = "sacred flame" - icon_state = "booksacredflame" - desc = "Become one with the flames that burn within... and invite others to do so as well." - -/obj/item/spellbook/oneuse/random - icon_state = "random_book" - -/obj/item/spellbook/oneuse/random/initialize() - . = ..() - var/static/list/banned_spells = typesof(/obj/item/spellbook/oneuse/mime, /obj/item/spellbook/oneuse/emp) - var/real_type = pick(subtypesof(/obj/item/spellbook/oneuse) - banned_spells) - new real_type(loc) - qdel(src) diff --git a/code/game/gamemodes/wizard/wizloadouts.dm b/code/game/gamemodes/wizard/wizloadouts.dm deleted file mode 100644 index b08bac865950d..0000000000000 --- a/code/game/gamemodes/wizard/wizloadouts.dm +++ /dev/null @@ -1,154 +0,0 @@ -//Contains wizard loadouts and associated unique spells - -//Standard loadouts, which are meant to be suggestions for beginners. Should always be worth exactly 10 spell points, and only contain standard wizard spells/items. -/datum/spellbook_entry/loadout/mutant - name = "Offense Focus - Mutant" - desc = "A spellset focused around the Mutate spell as its main source of damage, which provides stun protection, laser eyes, and strong punches.
    \ - Ethereal Jaunt and Blink provide escape and mobility, while Magic Missile and Disintegrate can be used together for dangerous or key targets.
    \ - As this set lacks any form of healing or resurrection, healing items should be acquired from the station, and you should be careful to avoid being hurt in the first place.

    \ - Provides Mutate, Ethereal Jaunt, Blink, Magic Missile, and Disintegrate." - spells_path = list(/datum/spell/genetic/mutate, /datum/spell/ethereal_jaunt, /datum/spell/turf_teleport/blink, \ - /datum/spell/projectile/magic_missile, /datum/spell/touch/disintegrate) - -/datum/spellbook_entry/loadout/lich - name = "Defense Focus - Lich" - desc = "This spellset uses the Bind Soul spell to safeguard your life as a lich and allow for more dangerous offensive spells to be used.
    \ - Ethereal Jaunt provides escape, Fireball and Rod Form are your offensive spells, and Disable Tech and Forcewall provides utility in disabling sec equipment or blocking their path.
    \ - Care should be taken in hiding the item you choose as your phylactery after using Bind Soul, as you cannot revive if it destroyed or too far from your body!

    \ -
    Provides Bind Soul, Ethereal Jaunt, Fireball, Rod Form, Disable Tech, and Greater Forcewall." - spells_path = list(/datum/spell/lichdom, /datum/spell/ethereal_jaunt, /datum/spell/fireball, \ - /datum/spell/rod_form, /datum/spell/emplosion/disable_tech, /datum/spell/forcewall) - is_ragin_restricted = TRUE - -/datum/spellbook_entry/loadout/wands - name = "Utility Focus - Wands" - desc = "This set contain a Belt of Wands, providing offensive, defensive, and utility wands. Wands have limited charges, but can be partially recharged with the Charge spell included.
    \ - Ethereal Jaunt and Blink provide escape and mobility, while Disintegrate and Repulse can be used to annihilate or push away anyone that gets too close to you.
    \ - Do not lose any of your wands to the station's crew, as they are extremely deadly even in their hands. Remember that the Revive wand can be used on yourself for a full heal!

    \ -
    Provides a Belt of Wands, Charge, Ethereal Jaunt, Blink, Repulse, and Disintegrate." - items_path = list(/obj/item/storage/belt/wands/full) - spells_path = list(/datum/spell/charge, /datum/spell/ethereal_jaunt, /datum/spell/turf_teleport/blink, \ - /datum/spell/aoe/repulse, /datum/spell/touch/disintegrate) - -//Unique loadouts, which are more gimmicky. Should contain some unique spell or item that separates it from just buying standard wiz spells, and be balanced around a 10 spell point cost. -/datum/spellbook_entry/loadout/mimewiz - name = "Silencio" - desc = "...

    \ -
    Provides Finger Gun and Invisible Greater Wall manuals, Mime Robes, a Cane and Duct Tape, Ethereal Jaunt, Blink, Teleport, Mime Malaise, Knock, and Stop Time." - items_path = list(/obj/item/spellbook/oneuse/mime/fingergun, /obj/item/spellbook/oneuse/mime/greaterwall, /obj/item/clothing/suit/wizrobe/mime, /obj/item/clothing/head/wizard/mime, \ - /obj/item/clothing/mask/gas/mime/wizard, /obj/item/clothing/shoes/sandal/marisa, /obj/item/cane, /obj/item/stack/tape_roll) - spells_path = list(/datum/spell/ethereal_jaunt, /datum/spell/turf_teleport/blink, /datum/spell/area_teleport/teleport, \ - /datum/spell/touch/mime_malaise, /datum/spell/aoe/knock, /datum/spell/aoe/conjure/timestop) - category = "Unique" - destroy_spellbook = TRUE - -/datum/spellbook_entry/loadout/mimewiz/OnBuy(mob/living/carbon/human/user, obj/item/spellbook/book) - if(user.mind) - user.mind.AddSpell(new /datum/spell/mime/speak(null)) - user.mind.miming = TRUE - -/datum/spellbook_entry/loadout/gunreaper - name = "Gunslinging Reaper" - desc = "Cloned over and over, the souls aboard this station yearn for a deserved rest.
    \ - Bring them to the afterlife, one trigger pull at a time.
    \ - You will likely need to scavenge additional ammo or weapons aboard the station.

    \ -
    Provides a .357 Revolver, 4 speedloaders of ammo, Ethereal Jaunt, Blink, Summon Item, No Clothes, and Bind Soul, with a unique outfit." - items_path = list(/obj/item/gun/projectile/revolver, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/clothing/under/syndicate) - spells_path = list(/datum/spell/ethereal_jaunt, /datum/spell/turf_teleport/blink, \ - /datum/spell/summonitem, /datum/spell/noclothes, /datum/spell/lichdom/gunslinger) - category = "Unique" - destroy_spellbook = TRUE - is_ragin_restricted = TRUE - -/datum/spell/lichdom/gunslinger/equip_lich(mob/living/carbon/human/H) - H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_suit(H), ITEM_SLOT_OUTER_SUIT) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), ITEM_SLOT_SHOES) - H.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(H), ITEM_SLOT_GLOVES) - H.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(H), ITEM_SLOT_JUMPSUIT) - -/datum/spellbook_entry/loadout/greytide - name = "Tyde the Grey" - desc = "A set of legendary artifacts used by a bald, grey wizard, now passed on to you.
    \ - Open His Grace's latch once you are ready to kill by using It in your hand. Keep It fed or you will be Its next meal.
    \ - If your Homing Toolbox spell is not enough, you might want to raid the Armory or loot a Security Officer to get more ranged weapons like a disabler, His Grace's Hunger has little patience.

    \ -
    Provides His Grace, an Ancient Jumpsuit, an Assistant ID, a Gas Mask and Shoes, Insulated Gloves, a full Toolbelt, Ethereal Jaunt, Force Wall, Homing Toolbox, Knock and No Clothes." - items_path = list(/obj/item/his_grace, /obj/item/clothing/under/color/grey/glorf, /obj/item/clothing/mask/gas, /obj/item/clothing/shoes/black, \ - /obj/item/clothing/gloves/color/yellow, /obj/item/storage/belt/utility/full/multitool) - spells_path = list(/datum/spell/ethereal_jaunt, /datum/spell/forcewall, \ - /datum/spell/aoe/knock, /datum/spell/noclothes, /datum/spell/fireball/toolbox) - category = "Unique" - destroy_spellbook = TRUE - -/datum/spellbook_entry/loadout/greytide/OnBuy(mob/living/carbon/human/user, obj/item/spellbook/book) - if(!user) - return - if(isplasmaman(user)) - to_chat(user, "A spectral hand appears from your spellbook and pulls a brand new plasmaman envirosuit, complete with helmet, from the void, then drops it on the floor.") - new /obj/item/clothing/head/helmet/space/plasmaman/assistant(get_turf(user)) - new /obj/item/clothing/under/plasmaman/assistant(get_turf(user)) - user.drop_item_to_ground(user.wear_id) - user.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey/glorf, ITEM_SLOT_JUMPSUIT) //Just in case they're naked - var/obj/item/card/id/wizid = new /obj/item/card/id(src) - user.equip_to_slot_or_del(wizid, ITEM_SLOT_ID) - wizid.registered_name = user.real_name - wizid.access = list(ACCESS_MAINT_TUNNELS) - wizid.assignment = "Assistant" - wizid.rank = "Assistant" - wizid.photo = get_id_photo(user, "Assistant") - wizid.registered_name = user.real_name - wizid.SetOwnerInfo(user) - wizid.UpdateName() - wizid.RebuildHTML() - -/datum/spellbook_entry/loadout/oblivion - name = "Oblivion Enforcer" - desc = "The Oblivion Order is an isolated clique of monks that revere supermatter. \ - Oblivion Enforcers are how the Order imposes their will on the universe as a whole. By taking this loadout, \ - you give up your identity and become a faceless hand of the Order.
    \ - You will be completely protected from the effects of supermatter by the items granted here, so far as to \ - allow you to pick up and throw supermatter slivers, which your halberd can cut from the engine.
    \ -
    Provides a Supermatter Halberd, Oblivion Enforcer robes, and an air tank, as well as Instant Summons, Lightning Bolt, and Summon Supermatter Crystal." - items_path = list(/obj/item/supermatter_halberd, /obj/item/clothing/gloves/color/white/supermatter_immune, \ - /obj/item/clothing/suit/hooded/oblivion, /obj/item/clothing/mask/gas/voice_modulator/oblivion, /obj/item/tank/internals/emergency_oxygen/double, \ - /obj/item/clothing/under/color/white/enforcer, /obj/item/clothing/shoes/white/enforcer) - spells_path = list(/datum/spell/summonitem, /datum/spell/charge_up/bounce/lightning, \ - /datum/spell/aoe/conjure/summon_supermatter) - category = "Unique" - destroy_spellbook = TRUE - -/datum/spellbook_entry/loadout/oblivion/OnBuy(mob/living/carbon/human/user, obj/item/spellbook/book) - if(!user) - return - ADD_TRAIT(user, SM_HALLUCINATION_IMMUNE, MAGIC_TRAIT) - -/datum/spellbook_entry/loadout/fireball - name = "Fireball. Fireball. Fireball." - desc = "Who cares about the rest of the spells. Become an expert in fire magic. Devote yourself to the craft. The only spell you need anyways is Fireball.
    \ -
    Provides fire immunity, homing fireballs, rapid-fire fireballs, and some fireball wands. Provides no mobility spells. Replaces your robes with infernal versions." - spells_path = list(/datum/spell/sacred_flame, /datum/spell/fireball/homing, /datum/spell/infinite_guns/fireball) - category = "Unique" - destroy_spellbook = TRUE - -/datum/spellbook_entry/loadout/fireball/OnBuy(mob/living/carbon/human/user, obj/item/spellbook/book) - qdel(user.wear_suit) - qdel(user.head) - - // Part of Sacred Flame - to_chat(user, "You feel fireproof.") - ADD_TRAIT(user, TRAIT_RESISTHEAT, MAGIC_TRAIT) - ADD_TRAIT(user, TRAIT_RESISTHIGHPRESSURE, MAGIC_TRAIT) - - user.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/red/fireball(user), ITEM_SLOT_OUTER_SUIT) - user.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/red/fireball(user), ITEM_SLOT_HEAD) - - user.equip_or_collect(new /obj/item/storage/belt/wands/fireballs(), ITEM_SLOT_BELT) - -/obj/item/clothing/suit/wizrobe/red/fireball - name = "infernal robe" - desc = "A magnificent, red, glowing robe that seems to radiate heat." - flags = NODROP - -/obj/item/clothing/head/wizard/red/fireball - name = "infernal hat" - desc = "A pointy red wizard hat, indicating a magician of great power." - flags = NODROP diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm deleted file mode 100644 index 4bd7839054f2c..0000000000000 --- a/code/game/jobs/access.dm +++ /dev/null @@ -1,419 +0,0 @@ -//returns 1 if this mob has sufficient access to use this object -/obj/proc/allowed(mob/M) - //check if we don't require any access at all - if(check_access()) - return 1 - - if(!M) - return 0 - - var/acc = M.get_access() //see mob.dm - - if(acc == IGNORE_ACCESS || M.can_admin_interact()) - return 1 //Mob ignores access - - else - return check_access_list(acc) - -/obj/proc/check_access(obj/item/I) - var/list/L - if(I) - L = I.GetAccess() - else - L = list() - return check_access_list(L) - -/obj/proc/check_access_list(list/L) - if(!L) - return 0 - if(!istype(L, /list)) - return 0 - return has_access(req_access, req_one_access, L) - -/proc/has_access(list/req_access, list/req_one_access, list/accesses) - for(var/req in req_access) - if(!(req in accesses)) //doesn't have this access - return 0 - if(length(req_one_access)) - for(var/req in req_one_access) - if(req in accesses) //has an access from the single access list - return 1 - return 0 - return 1 - -/proc/get_centcom_access(job) - switch(job) - if("VIP Guest") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING) - if("Custodian") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING) - if("Thunderdome Overseer") - return list(ACCESS_CENT_GENERAL) - if("Emergency Response Team Officer") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_SECURITY, ACCESS_CENT_SPECOPS) + get_all_accesses() - if("Emergency Response Team Engineer") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_SECURITY, ACCESS_CENT_SPECOPS) + get_all_accesses() - if("Emergency Response Team Medic") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_SECURITY, ACCESS_CENT_SPECOPS) + get_all_accesses() - if("Emergency Response Team Inquisitor") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_SECURITY, ACCESS_CENT_SPECOPS) + get_all_accesses() - if("Emergency Response Team Janitor") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_SECURITY, ACCESS_CENT_SPECOPS) + get_all_accesses() - if("Emergency Response Team Member") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_SECURITY, ACCESS_CENT_SPECOPS) + get_all_accesses() - if("Emergency Response Team Leader") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_SECURITY, ACCESS_CENT_SPECOPS, ACCESS_CENT_SPECOPS_COMMANDER) + get_all_accesses() - if("Medical Officer") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING) + get_all_accesses() - if("Intel Officer") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_SECURITY) + get_all_accesses() - if("Research Officer") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_SPECOPS) + get_all_accesses() - if("Deathsquad Commando") - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_SECURITY, ACCESS_CENT_SPECOPS, ACCESS_CENT_SPECOPS_COMMANDER) + get_all_accesses() - if("NT Undercover Operative") - return get_all_centcom_access() + get_all_accesses() - if("Special Operations Officer") - return get_all_centcom_access() + get_all_accesses() - if("Trans-Solar Federation General") - return get_all_centcom_access() + get_all_accesses() - if("Nanotrasen Navy Representative") - return get_all_centcom_access() + get_all_accesses() - if("Nanotrasen Navy Officer") - return get_all_centcom_access() + get_all_accesses() - if("Nanotrasen Navy Captain") - return get_all_centcom_access() + get_all_accesses() - if("Supreme Commander") - return get_all_centcom_access() + get_all_accesses() - -/proc/get_syndicate_access(job) - switch(job) - if("Syndicate Operative") - return list(ACCESS_SYNDICATE) - if("Syndicate Operative Leader") - return list(ACCESS_SYNDICATE, ACCESS_SYNDICATE_LEADER) - if("Syndicate Agent") - return list(ACCESS_SYNDICATE, ACCESS_MAINT_TUNNELS) - if("Syndicate Commando") - return list(ACCESS_SYNDICATE, ACCESS_SYNDICATE_LEADER) - if("Syndicate Officer") - return list(ACCESS_SYNDICATE, ACCESS_SYNDICATE_LEADER, ACCESS_SYNDICATE_COMMAND) - -/proc/get_all_accesses() - return list(ACCESS_MINISAT, ACCESS_AI_UPLOAD, ACCESS_ARMORY, ACCESS_ATMOSPHERICS, ACCESS_BAR, ACCESS_SEC_DOORS, ACCESS_BLUESHIELD, - ACCESS_HEADS, ACCESS_CAPTAIN, ACCESS_CARGO, ACCESS_CARGO_BAY, ACCESS_SUPPLY_SHUTTLE, ACCESS_MAILSORTING, ACCESS_CHAPEL_OFFICE, ACCESS_CE, ACCESS_CHEMISTRY, ACCESS_CLOWN, ACCESS_CMO, - ACCESS_COURT, ACCESS_CONSTRUCTION, ACCESS_CREMATORIUM, ACCESS_JANITOR, ACCESS_ENGINE, ACCESS_EVA, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_FORENSICS_LOCKERS, - ACCESS_GENETICS, ACCESS_EXPEDITION, ACCESS_BRIG, ACCESS_HOP, ACCESS_HOS, ACCESS_HYDROPONICS, ACCESS_CHANGE_IDS, ACCESS_KEYCARD_AUTH, ACCESS_KITCHEN, - ACCESS_INTERNAL_AFFAIRS, ACCESS_LIBRARY, ACCESS_MAGISTRATE, ACCESS_MAINT_TUNNELS, ACCESS_HEADS_VAULT, ACCESS_MEDICAL, ACCESS_MIME, - ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_MORGUE, ACCESS_NTREP, ACCESS_PARAMEDIC, ACCESS_ALL_PERSONAL_LOCKERS, - ACCESS_ENGINE_EQUIP, ACCESS_PSYCHIATRIST, ACCESS_QM, ACCESS_RD, ACCESS_RC_ANNOUNCE, ACCESS_ROBOTICS, ACCESS_TOX, ACCESS_RESEARCH, ACCESS_SECURITY, - ACCESS_SURGERY, ACCESS_TECH_STORAGE, ACCESS_TELEPORTER, ACCESS_THEATRE, ACCESS_TCOMSAT, ACCESS_TOX_STORAGE, ACCESS_VIROLOGY, ACCESS_WEAPONS, ACCESS_XENOBIOLOGY, ACCESS_TRAINER) - -/proc/get_all_centcom_access() - return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_SECURITY, ACCESS_CENT_SHUTTLES, ACCESS_CENT_SPECOPS, ACCESS_CENT_SPECOPS_COMMANDER, ACCESS_CENT_COMMANDER) - -/proc/get_all_syndicate_access() - return list(ACCESS_SYNDICATE, ACCESS_SYNDICATE_LEADER, ACCESS_SYNDICATE_COMMAND) - -/proc/get_all_misc_access() - return list(ACCESS_TRADE_SOL, ACCESS_AWAY01) - -/proc/get_absolutely_all_accesses() - return (get_all_accesses() | get_all_centcom_access() | get_all_syndicate_access() | get_all_misc_access()) - -/proc/get_region_accesses(code) - switch(code) - if(REGION_ALL) - return get_all_accesses() - if(REGION_GENERAL) //station general - return list(ACCESS_KITCHEN, ACCESS_BAR, ACCESS_HYDROPONICS, ACCESS_JANITOR, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_LIBRARY, ACCESS_THEATRE, ACCESS_INTERNAL_AFFAIRS, ACCESS_MAGISTRATE, ACCESS_CLOWN, ACCESS_MIME, ACCESS_TRAINER) - if(REGION_SECURITY) //security - return list(ACCESS_SEC_DOORS, ACCESS_WEAPONS, ACCESS_SECURITY, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT, ACCESS_HOS) - if(REGION_MEDBAY) //medbay - return list(ACCESS_MEDICAL, ACCESS_GENETICS, ACCESS_MORGUE, ACCESS_CHEMISTRY, ACCESS_PSYCHIATRIST, ACCESS_VIROLOGY, ACCESS_SURGERY, ACCESS_CMO, ACCESS_PARAMEDIC) - if(REGION_RESEARCH) //research - return list(ACCESS_AI_UPLOAD, ACCESS_RESEARCH, ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_GENETICS, ACCESS_ROBOTICS, ACCESS_XENOBIOLOGY, ACCESS_MINISAT, ACCESS_RD) - if(REGION_ENGINEERING) //engineering and maintenance - return list(ACCESS_CONSTRUCTION, ACCESS_MAINT_TUNNELS, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_TECH_STORAGE, ACCESS_ATMOSPHERICS, ACCESS_MINISAT, ACCESS_CE) - if(REGION_SUPPLY) //supply - return list(ACCESS_EXPEDITION, ACCESS_MAILSORTING, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_CARGO, ACCESS_CARGO_BAY, ACCESS_SUPPLY_SHUTTLE, ACCESS_QM, ACCESS_HEADS_VAULT) - if(REGION_COMMAND) //command - return list(ACCESS_HEADS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_TELEPORTER, ACCESS_EVA, ACCESS_TCOMSAT, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_HEADS_VAULT, ACCESS_BLUESHIELD, ACCESS_NTREP, ACCESS_HOP, ACCESS_CAPTAIN) - if(REGION_CENTCOMM) //because why the heck not - return get_all_centcom_access() + get_all_accesses() - -/proc/get_region_accesses_name(code) - switch(code) - if(REGION_ALL) - return "All" - if(REGION_GENERAL) //station general - return "General" - if(REGION_SECURITY) //security - return "Security" - if(REGION_MEDBAY) //medbay - return "Medbay" - if(REGION_RESEARCH) //research - return "Research" - if(REGION_ENGINEERING) //engineering and maintenance - return "Engineering" - if(REGION_SUPPLY) //supply - return "Supply" - if(REGION_COMMAND) //command - return "Command" - if(REGION_CENTCOMM) //CC - return "CentComm" - - -/proc/get_access_desc(A) - switch(A) - if(ACCESS_CARGO) - return "Cargo Office" - if(ACCESS_CARGO_BOT) - return "Cargo Bot Delivery" - if(ACCESS_CARGO_BAY) - return "Cargo Bay" - if(ACCESS_SUPPLY_SHUTTLE) - return "Supply Shuttle" - if(ACCESS_SECURITY) - return "Security" - if(ACCESS_BRIG) - return "Holding Cells" - if(ACCESS_COURT) - return "Courtroom" - if(ACCESS_FORENSICS_LOCKERS) - return "Forensics" - if(ACCESS_MEDICAL) - return "Medical" - if(ACCESS_GENETICS) - return "Genetics Lab" - if(ACCESS_MORGUE) - return "Morgue" - if(ACCESS_TOX) - return "R&D Lab" - if(ACCESS_TOX_STORAGE) - return "Toxins Lab" - if(ACCESS_CHEMISTRY) - return "Chemistry Lab" - if(ACCESS_RD) - return "Research Director" - if(ACCESS_BAR) - return "Bar" - if(ACCESS_JANITOR) - return "Custodial Closet" - if(ACCESS_ENGINE) - return "Engineering" - if(ACCESS_ENGINE_EQUIP) - return "Power Equipment" - if(ACCESS_MAINT_TUNNELS) - return "Maintenance" - if(ACCESS_EXTERNAL_AIRLOCKS) - return "External Airlocks" - if(ACCESS_CHANGE_IDS) - return "ID Computer" - if(ACCESS_AI_UPLOAD) - return "AI Upload" - if(ACCESS_TELEPORTER) - return "Teleporter" - if(ACCESS_EVA) - return "EVA" - if(ACCESS_HEADS) - return "Bridge" - if(ACCESS_CAPTAIN) - return "Captain" - if(ACCESS_ALL_PERSONAL_LOCKERS) - return "Personal Lockers/Crates" - if(ACCESS_CHAPEL_OFFICE) - return "Chapel Office" - if(ACCESS_TECH_STORAGE) - return "Technical Storage" - if(ACCESS_ATMOSPHERICS) - return "Atmospherics" - if(ACCESS_CREMATORIUM) - return "Crematorium" - if(ACCESS_ARMORY) - return "Armory" - if(ACCESS_CONSTRUCTION) - return "Construction Areas" - if(ACCESS_KITCHEN) - return "Kitchen" - if(ACCESS_HYDROPONICS) - return "Hydroponics" - if(ACCESS_LIBRARY) - return "Library" - if(ACCESS_INTERNAL_AFFAIRS) - return "Law Office" - if(ACCESS_ROBOTICS) - return "Robotics" - if(ACCESS_VIROLOGY) - return "Virology" - if(ACCESS_PSYCHIATRIST) - return "Psychiatrist's Office" - if(ACCESS_CMO) - return "Chief Medical Officer" - if(ACCESS_QM) - return "Quartermaster" - if(ACCESS_CLOWN) - return "Clown's Office" - if(ACCESS_MIME) - return "Mime's Office" - if(ACCESS_SURGERY) - return "Surgery" - if(ACCESS_THEATRE) - return "Theatre" - if(ACCESS_RESEARCH) - return "Science" - if(ACCESS_MINING) - return "Mining Dock" - if(ACCESS_MAILSORTING) - return "Mail Sorting" - if(ACCESS_HEADS_VAULT) - return "Main Vault" - if(ACCESS_MINING_STATION) - return "Mining Outpost" - if(ACCESS_XENOBIOLOGY) - return "Xenobiology Lab" - if(ACCESS_HOP) - return "Head of Personnel" - if(ACCESS_HOS) - return "Head of Security" - if(ACCESS_CE) - return "Chief Engineer" - if(ACCESS_RC_ANNOUNCE) - return "RC Announcements" - if(ACCESS_KEYCARD_AUTH) - return "Keycode Auth. Device" - if(ACCESS_TCOMSAT) - return "Telecommunications" - if(ACCESS_EXPEDITION) - return "Expedition" - if(ACCESS_SEC_DOORS) - return "Brig" - if(ACCESS_BLUESHIELD) - return "Blueshield" - if(ACCESS_NTREP) - return "Nanotrasen Rep." - if(ACCESS_PARAMEDIC) - return "Paramedic" - if(ACCESS_MAGISTRATE) - return "Magistrate" - if(ACCESS_MINERAL_STOREROOM) - return "Mineral Storage" - if(ACCESS_MINISAT) - return "AI Satellite" - if(ACCESS_WEAPONS) - return "Weapon Permit" - if(ACCESS_TRAINER) - return "Nanotrasen Career Trainer" - -/proc/get_centcom_access_desc(A) - switch(A) - if(ACCESS_CENT_GENERAL) - return "General Access" - if(ACCESS_CENT_LIVING) - return "Living Quarters" - if(ACCESS_CENT_SECURITY) - return "Security" - if(ACCESS_CENT_SHUTTLES) - return "Shuttles" - if(ACCESS_CENT_SPECOPS) - return "Special Ops" - if(ACCESS_CENT_SPECOPS_COMMANDER) - return "Special Ops Commander" - if(ACCESS_CENT_COMMANDER) - return "Commander" - -/proc/get_syndicate_access_desc(A) - switch(A) - if(ACCESS_SYNDICATE) - return "Syndicate Operative" - if(ACCESS_SYNDICATE_LEADER) - return "Syndicate Operative Leader" - if(ACCESS_SYNDICATE_COMMAND) - return "Syndicate Command" - -/proc/get_all_jobs() - var/list/all_jobs = list() - var/list/all_datums = subtypesof(/datum/job) - all_datums.Remove(list(/datum/job/ai,/datum/job/cyborg)) - var/datum/job/jobdatum - for(var/jobtype in all_datums) - jobdatum = new jobtype - all_jobs.Add(jobdatum.title) - return all_jobs - -/proc/get_all_centcom_jobs() - return list( - "VIP Guest", - "Custodian", - "Thunderdome Overseer", - "Intel Officer", - "Medical Officer", - "Research Officer", - "Special Operations Officer", - "Nanotrasen Diplomat", - "Nanotrasen Navy Representative", - "Nanotrasen Navy Officer", - "Nanotrasen Navy Captain", - "Supreme Commander") - -/proc/get_all_ERT_jobs() - return list( - "Emergency Response Team Member", - "Emergency Response Team Officer", - "Emergency Response Team Engineer", - "Emergency Response Team Medic", - "Emergency Response Team Janitor", - "Emergency Response Team Inquisitor", - "Emergency Response Team Leader") - -/proc/get_all_solgov_jobs() - return list( - "Trans-Solar Federation Trader", - "TSF Marine", - "TSF Lieutenant", - "MARSOC Marine", - "MARSOC Lieutenant", - "Trans-Solar Federation Representative", - "Trans-Solar Federation General") - -/proc/get_all_soviet_jobs() - return list( - "Soviet Tourist", - "Soviet Conscript", - "Soviet Soldier", - "Soviet Officer", - "Soviet Marine", - "Soviet Marine Captain", - "Soviet Admiral") - -/proc/get_all_special_jobs() - return list( - "Deathsquad", - "Emergency Response Clown", - "Tourist") - -/proc/get_all_job_icons() //For all existing HUD icons - return GLOB.joblist + get_all_ERT_jobs() + list("Prisoner", "Centcom", "Solgov", "Soviet", "Unknown") - -/proc/get_accesslist_static_data(num_min_region = REGION_GENERAL, num_max_region = REGION_COMMAND) - var/list/retval - for(var/i in num_min_region to num_max_region) - var/list/accesses = list() - var/list/available_accesses - if(i == REGION_CENTCOMM) // Override necessary, because get_region_accesses(REGION_CENTCOM) returns BOTH CC and crew accesses. - available_accesses = get_all_centcom_access() - else - available_accesses = get_region_accesses(i) - for(var/access in available_accesses) - var/access_desc = (i == REGION_CENTCOMM) ? get_centcom_access_desc(access) : get_access_desc(access) - if(access_desc) - accesses += list(list( - "desc" = replacetext(access_desc, " ", " "), - "ref" = access, - )) - retval += list(list( - "name" = get_region_accesses_name(i), - "regid" = i, - "accesses" = accesses - )) - return retval diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm deleted file mode 100644 index 9532959e6c69b..0000000000000 --- a/code/game/jobs/job/job.dm +++ /dev/null @@ -1,299 +0,0 @@ -/datum/job - - //The name of the job - var/title = "NOPE" - - /// Job access. A list of constants from access_defines.dm. - var/list/access = list() - - ///Job Bitflag, used for Database entries - DO NOT JUST EDIT THESE - var/flag = 0 - ///Department(s) Bitflag, used for Databse entries - DO NOT JUST EDIT THESE - var/department_flag = 0 - ///list of the names of departments heads (as strings) - var/department_head = list() - ///List of the department(s) this job is a part of - var/job_departments = list() - ///Can this role access its department money account? - var/department_account_access = FALSE - /// Does this job get a bank account? - var/has_bank_account = TRUE - //How many players can be this job - var/total_positions = 0 - - //How many players can spawn in as this job - var/spawn_positions = 0 - - //How many players have this job - var/current_positions = 0 - - //Supervisors, who this person answers to directly - var/supervisors = "" - - /// Text which is shown to someone in BIG BOLG RED when they spawn. Use for critically important stuff that could make/break a round - var/important_information = null - - //Sellection screen color - var/selection_color = "#ffffff" - - //List of alternate titles, if any - var/list/alt_titles - - //If this is set to 1, a text is printed to the player when jobs are assigned, telling him that he should let admins know that he has to disconnect. - var/req_admin_notify - - /// Flags for identifying by department, because we need other shit that isnt for the database - var/job_department_flags - - //If you have use_age_restriction_for_jobs config option enabled and the database set up, this option will add a requirement for players to be at least minimal_player_age days old. (meaning they first signed in at least that many days before.) - var/minimal_player_age = 0 - - // Assoc list of EXP_TYPE_ defines and the amount of time needed in those departments - var/list/exp_map = list() - - /// Cannot pick this job if the character has these disabilities - var/list/blacklisted_disabilities = list() - /// If this job could have any amputated limbs - var/missing_limbs_allowed = TRUE - - var/transfer_allowed = TRUE // If false, ID computer will always discourage transfers to this job, even if player is eligible - var/hidden_from_job_prefs = FALSE // if true, job preferences screen never shows this job. - - var/admin_only = 0 - var/mentor_only = 0 - var/spawn_ert = 0 - var/syndicate_command = 0 - - var/outfit - - ///Job Objectives that crew with this job will have a roundstart - var/required_objectives = list() - - /// Boolean detailing if this job has been banned because of a gamemode restriction i.e. The revolution has won, no more command - var/job_banned_gamemode = FALSE - -//Only override this proc -/datum/job/proc/after_spawn(mob/living/carbon/human/H) - SEND_GLOBAL_SIGNAL(COMSIG_GLOB_JOB_AFTER_SPAWN, src, H) - - -/datum/job/proc/announce(mob/living/carbon/human/H) - return - -/datum/job/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE, announce = TRUE) - if(!H) - return 0 - - H.dna.species.before_equip_job(src, H, visualsOnly) - - if(outfit) - H.equipOutfit(outfit, visualsOnly) - - H.dna.species.after_equip_job(src, H, visualsOnly) - - if(!visualsOnly && announce) - announce(H) - -/datum/job/proc/get_access() - return access.Copy() - -//If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1 -/datum/job/proc/player_old_enough(client/C) - if(available_in_days(C) == 0) - return 1 //Available in 0 days = available right now = player is old enough to play. - return 0 - - -/datum/job/proc/available_in_days(client/C) - if(!C) - return 0 - if(!GLOB.configuration.jobs.restrict_jobs_on_account_age) - return 0 - if(!isnum(C.player_age)) - return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced - if(!isnum(minimal_player_age)) - return 0 - - return max(0, minimal_player_age - C.player_age) - -/// Returns true if the character has a disability the selected job doesn't allow -/datum/job/proc/barred_by_disability(client/C) - if(!C || !length(blacklisted_disabilities)) - return FALSE - for(var/disability in blacklisted_disabilities) - if(C.prefs.active_character.disabilities & disability) - return TRUE - return FALSE - -/// Returns true if the character has amputated limbs when their selected job doesn't allow it -/datum/job/proc/barred_by_missing_limbs(client/C) - if(!C || missing_limbs_allowed) - return FALSE - - var/organ_status - var/list/active_character_organs = C.prefs.active_character.organ_data - - for(var/organ_name in active_character_organs) - organ_status = active_character_organs[organ_name] - if(organ_status == "amputated") - return TRUE - return FALSE - -/datum/job/proc/is_position_available() - if(job_banned_gamemode) - return FALSE - return (current_positions < total_positions) || (total_positions == -1) - -/datum/job/proc/is_spawn_position_available() - if(job_banned_gamemode) - return FALSE - return (current_positions < spawn_positions) || (spawn_positions == -1) - -/datum/outfit/job - name = "Standard Gear" - collect_not_del = TRUE // we don't want anyone to lose their job shit - - var/allow_loadout = TRUE - var/allow_backbag_choice = TRUE - var/jobtype = null - - uniform = /obj/item/clothing/under/color/grey - id = /obj/item/card/id - l_ear = /obj/item/radio/headset - back = /obj/item/storage/backpack - shoes = /obj/item/clothing/shoes/black - pda = /obj/item/pda - - var/backpack = /obj/item/storage/backpack - var/satchel = /obj/item/storage/backpack/satchel_norm - var/dufflebag = /obj/item/storage/backpack/duffel - box = /obj/item/storage/box/survival - - var/tmp/list/gear_leftovers = list() - -/datum/outfit/job/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - if(allow_backbag_choice) - switch(H.backbag) - if(GBACKPACK) - back = /obj/item/storage/backpack //Grey backpack - if(GSATCHEL) - back = /obj/item/storage/backpack/satchel_norm //Grey satchel - if(GDUFFLEBAG) - back = /obj/item/storage/backpack/duffel //Grey Dufflebag - if(LSATCHEL) - back = /obj/item/storage/backpack/satchel //Leather Satchel - if(DSATCHEL) - back = satchel //Department satchel - if(DDUFFLEBAG) - back = dufflebag //Department dufflebag - else - back = backpack //Department backpack - - if(box && H.dna.species.speciesbox) - box = H.dna.species.speciesbox - - if(allow_loadout && H.client && length(H.client.prefs.active_character.loadout_gear)) - for(var/gear in H.client.prefs.active_character.loadout_gear) - var/datum/gear/G = GLOB.gear_datums[text2path(gear) || gear] - if(G) - var/permitted = FALSE - - if(G.allowed_roles) - if(name in G.allowed_roles) - permitted = TRUE - else - permitted = TRUE - - if(!permitted) - to_chat(H, "Your current job or whitelist status does not permit you to spawn with [G.display_name]!") - continue - - if(G.slot) - if(H.equip_to_slot_or_del(G.spawn_item(H, H.client.prefs.active_character.get_gear_metadata(G)), G.slot, TRUE)) - to_chat(H, "Equipping you with [G.display_name]!") - else - gear_leftovers += G - else - gear_leftovers += G - -/datum/outfit/job/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - imprint_idcard(H) - - H.sec_hud_set_ID() - - imprint_pda(H) - - if(length(gear_leftovers)) - for(var/datum/gear/G in gear_leftovers) - var/atom/placed_in = H.equip_or_collect(G.spawn_item(null, H.client.prefs.active_character.get_gear_metadata(G))) - if(istype(placed_in)) - if(isturf(placed_in)) - to_chat(H, "Placing [G.display_name] on [placed_in]!") - else - to_chat(H, "Placing [G.display_name] in your [placed_in.name].") - continue - if(H.equip_to_appropriate_slot(G)) - to_chat(H, "Placing [G.display_name] in your inventory!") - continue - if(H.put_in_hands(G)) - to_chat(H, "Placing [G.display_name] in your hands!") - continue - to_chat(H, "Failed to locate a storage object on your mob, either you spawned with no hands free and no backpack or this is a bug.") - qdel(G) - - gear_leftovers.Cut() - - return 1 - -/datum/outfit/job/proc/imprint_idcard(mob/living/carbon/human/H) - var/datum/job/J = SSjobs.GetJobType(jobtype) - if(!J) - J = SSjobs.GetJob(H.job) - - var/alt_title - if(H.mind) - alt_title = H.mind.role_alt_title - - var/obj/item/card/id/C = H.wear_id - if(istype(C)) - C.access = J.get_access() - C.registered_name = H.real_name - C.rank = J.title - C.assignment = alt_title ? alt_title : J.title - C.sex = capitalize(H.gender) - C.age = H.age - C.name = "[C.registered_name]'s ID Card ([C.assignment])" - C.photo = get_id_photo(H) - - if(H.mind && H.mind.initial_account) - C.associated_account_number = H.mind.initial_account.account_number - C.owner_uid = H.UID() - C.owner_ckey = H.ckey - -/datum/outfit/job/proc/imprint_pda(mob/living/carbon/human/H) - var/obj/item/pda/PDA = H.wear_pda - var/obj/item/card/id/C = H.wear_id - if(istype(PDA) && istype(C)) - PDA.owner = H.real_name - PDA.ownjob = C.assignment - PDA.ownrank = C.rank - PDA.name = "PDA-[H.real_name] ([PDA.ownjob])" - if(H.client?.prefs.active_character.pda_ringtone) - PDA.ttone = H.client.prefs.active_character.pda_ringtone - -/datum/outfit/job/on_mind_initialize(mob/living/carbon/human/H) - . = ..() - var/obj/item/card/id/id = H.wear_id - if(!id) - return - var/datum/job/J = SSjobs.GetJobType(jobtype) - if(!J) - J = SSjobs.GetJob(H.job) - id.assignment = H.mind.role_alt_title ? H.mind.role_alt_title : J.title - if(!H.mind.initial_account) - return - id.associated_account_number = H.mind.initial_account.account_number diff --git a/code/game/jobs/job/security_jobs.dm b/code/game/jobs/job/security_jobs.dm deleted file mode 100644 index 87393d49d43f1..0000000000000 --- a/code/game/jobs/job/security_jobs.dm +++ /dev/null @@ -1,234 +0,0 @@ -/datum/job/hos - title = "Head of Security" - flag = JOB_HOS - department_flag = JOBCAT_ENGSEC - total_positions = 1 - spawn_positions = 1 - job_department_flags = DEP_FLAG_COMMAND | DEP_FLAG_SECURITY - supervisors = "the captain" - department_head = list("Captain") - selection_color = "#ffdddd" - req_admin_notify = 1 - department_account_access = TRUE - access = list( - ACCESS_ALL_PERSONAL_LOCKERS, - ACCESS_ARMORY, - ACCESS_BRIG, - ACCESS_CARGO_BAY, - ACCESS_CARGO, - ACCESS_CONSTRUCTION, - ACCESS_COURT, - ACCESS_ENGINE, - ACCESS_EVA, - ACCESS_EXPEDITION, - ACCESS_FORENSICS_LOCKERS, - ACCESS_HEADS, - ACCESS_HOS, - ACCESS_KEYCARD_AUTH, - ACCESS_MAILSORTING, - ACCESS_MAINT_TUNNELS, - ACCESS_MEDICAL, - ACCESS_MINING, - ACCESS_MORGUE, - ACCESS_RC_ANNOUNCE, - ACCESS_RESEARCH, - ACCESS_SEC_DOORS, - ACCESS_SECURITY, - ACCESS_SUPPLY_SHUTTLE, - ACCESS_WEAPONS - ) - minimal_player_age = 21 - exp_map = list(EXP_TYPE_SECURITY = 1200) - blacklisted_disabilities = list(DISABILITY_FLAG_BLIND, DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_DIZZY, DISABILITY_FLAG_NERVOUS, DISABILITY_FLAG_LISP) - missing_limbs_allowed = FALSE - outfit = /datum/outfit/job/hos - important_information = "This role requires you to coordinate a department. You are required to be familiar with Standard Operating Procedure (Security), Space Law, basic job duties, and act professionally (roleplay)." - -/datum/outfit/job/hos - name = "Head of Security" - jobtype = /datum/job/hos - - uniform = /obj/item/clothing/under/rank/security/head_of_security - suit = /obj/item/clothing/suit/armor/hos - gloves = /obj/item/clothing/gloves/color/black - shoes = /obj/item/clothing/shoes/jackboots - head = /obj/item/clothing/head/hos - l_ear = /obj/item/radio/headset/heads/hos/alt - glasses = /obj/item/clothing/glasses/hud/security/sunglasses - id = /obj/item/card/id/hos - suit_store = /obj/item/gun/energy/gun - pda = /obj/item/pda/heads/hos - backpack_contents = list( - /obj/item/restraints/handcuffs = 1, - /obj/item/melee/classic_baton/telescopic = 1 - ) - - bio_chips = list(/obj/item/bio_chip/mindshield) - - backpack = /obj/item/storage/backpack/security - satchel = /obj/item/storage/backpack/satchel_sec - dufflebag = /obj/item/storage/backpack/duffel/security - -/datum/job/warden - title = "Warden" - flag = JOB_WARDEN - department_flag = JOBCAT_ENGSEC - total_positions = 1 - spawn_positions = 1 - job_department_flags = DEP_FLAG_SECURITY - supervisors = "the head of security" - department_head = list("Head of Security") - selection_color = "#ffeeee" - access = list( - ACCESS_ARMORY, - ACCESS_BRIG, - ACCESS_COURT, - ACCESS_MAINT_TUNNELS, - ACCESS_SEC_DOORS, - ACCESS_SECURITY, - ACCESS_WEAPONS - ) - minimal_player_age = 21 - exp_map = list(EXP_TYPE_SECURITY = 600) - blacklisted_disabilities = list(DISABILITY_FLAG_BLIND, DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_DIZZY, DISABILITY_FLAG_NERVOUS, DISABILITY_FLAG_LISP) - missing_limbs_allowed = FALSE - outfit = /datum/outfit/job/warden - -/datum/outfit/job/warden - name = "Warden" - jobtype = /datum/job/warden - - uniform = /obj/item/clothing/under/rank/security/warden - suit = /obj/item/clothing/suit/armor/vest/warden/alt - gloves = /obj/item/clothing/gloves/color/black - shoes = /obj/item/clothing/shoes/jackboots - head = /obj/item/clothing/head/warden - l_ear = /obj/item/radio/headset/headset_sec/alt - glasses = /obj/item/clothing/glasses/hud/security/sunglasses - id = /obj/item/card/id/warden - l_pocket = /obj/item/flash - suit_store = /obj/item/gun/energy/disabler - pda = /obj/item/pda/warden - backpack_contents = list( - /obj/item/restraints/handcuffs = 1 - ) - - bio_chips = list(/obj/item/bio_chip/mindshield) - - backpack = /obj/item/storage/backpack/security - satchel = /obj/item/storage/backpack/satchel_sec - dufflebag = /obj/item/storage/backpack/duffel/security - -/datum/job/detective - title = "Detective" - flag = JOB_DETECTIVE - department_flag = JOBCAT_ENGSEC - total_positions = 1 - spawn_positions = 1 - job_department_flags = DEP_FLAG_SECURITY - supervisors = "the head of security" - department_head = list("Head of Security") - selection_color = "#ffeeee" - alt_titles = list("Forensic Technician") - access = list( - ACCESS_BRIG, - ACCESS_COURT, - ACCESS_FORENSICS_LOCKERS, - ACCESS_MAINT_TUNNELS, - ACCESS_MORGUE, - ACCESS_SEC_DOORS, - ACCESS_SECURITY, - ACCESS_WEAPONS - ) - minimal_player_age = 14 - exp_map = list(EXP_TYPE_CREW = 600) - blacklisted_disabilities = list(DISABILITY_FLAG_BLIND, DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_DIZZY) - missing_limbs_allowed = FALSE - outfit = /datum/outfit/job/detective - important_information = "Track, investigate, and look cool while doing it." - -/datum/outfit/job/detective - name = "Detective" - jobtype = /datum/job/detective - - uniform = /obj/item/clothing/under/rank/security/detective - suit = /obj/item/clothing/suit/storage/det_suit - gloves = /obj/item/clothing/gloves/color/black - shoes = /obj/item/clothing/shoes/brown - head = /obj/item/clothing/head/det_hat - l_ear = /obj/item/radio/headset/headset_sec/alt - glasses = /obj/item/clothing/glasses/hud/security/sunglasses - id = /obj/item/card/id/detective - l_pocket = /obj/item/toy/crayon/white/chalk - r_pocket = /obj/item/lighter/zippo - pda = /obj/item/pda/detective - backpack_contents = list( - /obj/item/storage/box/evidence = 1, - /obj/item/detective_scanner = 1, - /obj/item/melee/classic_baton/telescopic = 1 - ) - - bio_chips = list(/obj/item/bio_chip/mindshield) - -/datum/outfit/job/detective/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(H.mind && H.mind.role_alt_title) - switch(H.mind.role_alt_title) - if("Forensic Technician") - suit = /obj/item/clothing/suit/storage/det_suit/forensics/blue - head = null - -/datum/outfit/job/detective/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - H.dna.SetSEState(GLOB.soberblock, TRUE) - H.check_mutations = 1 - -/datum/job/officer - title = "Security Officer" - flag = JOB_OFFICER - department_flag = JOBCAT_ENGSEC - total_positions = 7 - spawn_positions = 7 - job_department_flags = DEP_FLAG_SECURITY - supervisors = "the head of security" - department_head = list("Head of Security") - selection_color = "#ffeeee" - access = list( - ACCESS_BRIG, - ACCESS_COURT, - ACCESS_MAINT_TUNNELS, - ACCESS_SEC_DOORS, - ACCESS_SECURITY, - ACCESS_WEAPONS - ) - minimal_player_age = 14 - exp_map = list(EXP_TYPE_CREW = 600) - blacklisted_disabilities = list(DISABILITY_FLAG_BLIND, DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_DIZZY) - missing_limbs_allowed = FALSE - outfit = /datum/outfit/job/officer - important_information = "Space Law is the law, not a suggestion." - -/datum/outfit/job/officer - name = "Security Officer" - jobtype = /datum/job/officer - uniform = /obj/item/clothing/under/rank/security/officer - suit = /obj/item/clothing/suit/armor/vest/security - gloves = /obj/item/clothing/gloves/color/black - shoes = /obj/item/clothing/shoes/jackboots - head = /obj/item/clothing/head/helmet - l_ear = /obj/item/radio/headset/headset_sec/alt - id = /obj/item/card/id/security - l_pocket = /obj/item/flash - suit_store = /obj/item/gun/energy/disabler - pda = /obj/item/pda/security - backpack_contents = list( - /obj/item/restraints/handcuffs = 1 - ) - bio_chips = list(/obj/item/bio_chip/mindshield) - backpack = /obj/item/storage/backpack/security - satchel = /obj/item/storage/backpack/satchel_sec - dufflebag = /obj/item/storage/backpack/duffel/security - diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm deleted file mode 100644 index 2b41c27a9e186..0000000000000 --- a/code/game/jobs/job/supervisor.dm +++ /dev/null @@ -1,424 +0,0 @@ -/datum/job/captain - title = "Captain" - flag = JOB_CAPTAIN - department_flag = JOBCAT_ENGSEC - total_positions = 1 - spawn_positions = 1 - supervisors = "Nanotrasen officials" - department_head = list("Nanotrasen Navy Officer") - selection_color = "#ccccff" - req_admin_notify = 1 - job_department_flags = DEP_FLAG_COMMAND - department_account_access = TRUE - access = list() //See get_access() - minimal_player_age = 30 - exp_map = list(EXP_TYPE_COMMAND = 1200) - blacklisted_disabilities = list(DISABILITY_FLAG_BLIND, DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_DIZZY, DISABILITY_FLAG_NERVOUS, DISABILITY_FLAG_LISP) - outfit = /datum/outfit/job/captain - important_information = "This role requires you to coordinate a department. You are required to be familiar with Standard Operating Procedure (Command), basic job duties, and act professionally (roleplay)." - -/datum/job/captain/get_access() - return get_all_accesses() - -/datum/job/captain/announce(mob/living/carbon/human/H) - . = ..() - // Why the hell are captain announcements minor - GLOB.minor_announcement.Announce("All hands, Captain [H.real_name] on deck!") - -/datum/outfit/job/captain - name = "Captain" - jobtype = /datum/job/captain - uniform = /obj/item/clothing/under/rank/captain - suit = /obj/item/clothing/suit/armor/vest/capcarapace - shoes = /obj/item/clothing/shoes/brown - head = /obj/item/clothing/head/caphat - l_ear = /obj/item/radio/headset/heads/captain/alt - glasses = /obj/item/clothing/glasses/hud/skills/sunglasses - id = /obj/item/card/id/captains_spare/assigned - pda = /obj/item/pda/captain - backpack_contents = list( - /obj/item/storage/box/ids = 1, - /obj/item/melee/classic_baton/telescopic = 1 - ) - bio_chips = list(/obj/item/bio_chip/mindshield) - backpack = /obj/item/storage/backpack/captain - satchel = /obj/item/storage/backpack/satchel_cap - dufflebag = /obj/item/storage/backpack/duffel/captain - -/datum/outfit/job/captain/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(H && H.w_uniform) - var/obj/item/clothing/under/U = H.w_uniform - var/obj/item/clothing/accessory/medal/gold/captain/M = new /obj/item/clothing/accessory/medal/gold/captain(U) - U.accessories += M - M.on_attached(U) - -/datum/job/hop - title = "Head of Personnel" - flag = JOB_HOP - department_flag = JOBCAT_SUPPORT - total_positions = 1 - spawn_positions = 1 - supervisors = "the captain" - department_head = list("Captain") - selection_color = "#ddddff" - req_admin_notify = 1 - job_department_flags = DEP_FLAG_COMMAND - minimal_player_age = 21 - department_account_access = TRUE - exp_map = list(EXP_TYPE_SERVICE = 1200) - access = list( - ACCESS_AI_UPLOAD, - ACCESS_ALL_PERSONAL_LOCKERS, - ACCESS_BAR, - ACCESS_BRIG, - ACCESS_CARGO, - ACCESS_CHANGE_IDS, - ACCESS_CHAPEL_OFFICE, - ACCESS_CLOWN, - ACCESS_CONSTRUCTION, - ACCESS_COURT, - ACCESS_CREMATORIUM, - ACCESS_ENGINE, - ACCESS_EVA, - ACCESS_EXPEDITION, - ACCESS_HEADS_VAULT, - ACCESS_HEADS, - ACCESS_HOP, - ACCESS_HYDROPONICS, - ACCESS_JANITOR, - ACCESS_KEYCARD_AUTH, - ACCESS_KITCHEN, - ACCESS_INTERNAL_AFFAIRS, - ACCESS_LIBRARY, - ACCESS_MAINT_TUNNELS, - ACCESS_MEDICAL, - ACCESS_MIME, - ACCESS_MINERAL_STOREROOM, - ACCESS_MORGUE, - ACCESS_RC_ANNOUNCE, - ACCESS_RESEARCH, - ACCESS_SEC_DOORS, - ACCESS_SECURITY, - ACCESS_THEATRE, - ACCESS_WEAPONS - ) - blacklisted_disabilities = list(DISABILITY_FLAG_BLIND, DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_DIZZY , DISABILITY_FLAG_NERVOUS, DISABILITY_FLAG_LISP) - outfit = /datum/outfit/job/hop - important_information = "This role requires you to coordinate a department. You are required to be familiar with Standard Operating Procedure (Service), basic job duties, and act professionally (roleplay)." - -/datum/outfit/job/hop - name = "Head of Personnel" - jobtype = /datum/job/hop - uniform = /obj/item/clothing/under/rank/civilian/hop - shoes = /obj/item/clothing/shoes/brown - head = /obj/item/clothing/head/hop - glasses = /obj/item/clothing/glasses/hud/skills/sunglasses - l_ear = /obj/item/radio/headset/heads/hop - id = /obj/item/card/id/hop - pda = /obj/item/pda/heads/hop - backpack_contents = list( - /obj/item/storage/box/ids = 1, - /obj/item/melee/classic_baton/telescopic = 1 - ) - - bio_chips = list() - -/datum/job/nanotrasenrep - title = "Nanotrasen Representative" - flag = JOB_NANO - department_flag = JOBCAT_ENGSEC - total_positions = 1 - spawn_positions = 1 - supervisors = "the command staff" - department_head = list("Captain") - selection_color = "#ddddff" - req_admin_notify = TRUE - job_department_flags = DEP_FLAG_COMMAND - transfer_allowed = FALSE - minimal_player_age = 21 - exp_map = list(EXP_TYPE_COMMAND = 3000) // 50 hours baby - access = list( - ACCESS_ALL_PERSONAL_LOCKERS, - ACCESS_BAR, - ACCESS_BRIG, - ACCESS_CARGO_BAY, - ACCESS_CARGO_BOT, - ACCESS_CARGO, - ACCESS_CHAPEL_OFFICE, - ACCESS_CLOWN, - ACCESS_CONSTRUCTION, - ACCESS_COURT, - ACCESS_CREMATORIUM, - ACCESS_ENGINE, - ACCESS_EVA, - ACCESS_EXPEDITION, - ACCESS_HEADS_VAULT, - ACCESS_HEADS, - ACCESS_HYDROPONICS, - ACCESS_JANITOR, - ACCESS_KEYCARD_AUTH, - ACCESS_KITCHEN, - ACCESS_INTERNAL_AFFAIRS, - ACCESS_LIBRARY, - ACCESS_MAILSORTING, - ACCESS_MAINT_TUNNELS, - ACCESS_MEDICAL, - ACCESS_MIME, - ACCESS_MINING_STATION, - ACCESS_MINING, - ACCESS_MORGUE, - ACCESS_NTREP, - ACCESS_RC_ANNOUNCE, - ACCESS_RESEARCH, - ACCESS_SEC_DOORS, - ACCESS_SECURITY, - ACCESS_SUPPLY_SHUTTLE, - ACCESS_THEATRE, - ACCESS_WEAPONS, - ACCESS_TRAINER - ) - blacklisted_disabilities = list(DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_NERVOUS, DISABILITY_FLAG_LISP) - outfit = /datum/outfit/job/nanotrasenrep - important_information = "This role requires you to advise the Command team about Standard Operating Procedure, Chain of Command, and report to Central Command about various matters. You are required to act in a manner befitting someone representing Nanotrasen." - -/datum/outfit/job/nanotrasenrep - name = "Nanotrasen Representative" - jobtype = /datum/job/nanotrasenrep - uniform = /obj/item/clothing/under/rank/procedure/representative - suit = /obj/item/clothing/suit/storage/ntrep - shoes = /obj/item/clothing/shoes/centcom - glasses = /obj/item/clothing/glasses/hud/skills/sunglasses - l_ear = /obj/item/radio/headset/heads/ntrep - id = /obj/item/card/id/ntrep - l_pocket = /obj/item/lighter/zippo/nt_rep - pda = /obj/item/pda/heads/ntrep - backpack_contents = list( - /obj/item/melee/classic_baton/ntcane = 1 - ) - bio_chips = list(/obj/item/bio_chip/mindshield) - -/datum/job/blueshield - title = "Blueshield" - flag = JOB_BLUESHIELD - department_flag = JOBCAT_ENGSEC - total_positions = 1 - spawn_positions = 1 - supervisors = "the Nanotrasen representative" - department_head = list("Captain") - selection_color = "#ddddff" - req_admin_notify = TRUE - job_department_flags = DEP_FLAG_COMMAND - transfer_allowed = FALSE - minimal_player_age = 21 - exp_map = list(EXP_TYPE_COMMAND = 3000) // 50 hours baby - access = list( - ACCESS_BLUESHIELD, - ACCESS_CARGO, - ACCESS_CONSTRUCTION, - ACCESS_ENGINE, - ACCESS_HEADS, - ACCESS_KEYCARD_AUTH, - ACCESS_MAILSORTING, - ACCESS_MAINT_TUNNELS, - ACCESS_MEDICAL, - ACCESS_MINING, - ACCESS_RC_ANNOUNCE, - ACCESS_RESEARCH, - ACCESS_SEC_DOORS, - ACCESS_WEAPONS - ) - blacklisted_disabilities = list(DISABILITY_FLAG_BLIND, DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_DIZZY, DISABILITY_FLAG_NERVOUS, DISABILITY_FLAG_LISP) - missing_limbs_allowed = FALSE - outfit = /datum/outfit/job/blueshield - important_information = "This role requires you to ensure the safety of the Heads of Staff, not the general crew. You may perform arrests only if the combatant is directly threatening a member of Command, the Nanotrasen Representative, or the Magistrate." - -/datum/outfit/job/blueshield - name = "Blueshield" - jobtype = /datum/job/blueshield - uniform = /obj/item/clothing/under/rank/procedure/blueshield - suit = /obj/item/clothing/suit/armor/vest/blueshield - gloves = /obj/item/clothing/gloves/combat - shoes = /obj/item/clothing/shoes/jackboots - l_ear = /obj/item/radio/headset/heads/blueshield/alt - glasses = /obj/item/clothing/glasses/hud/health/sunglasses - id = /obj/item/card/id/blueshield - pda = /obj/item/pda/heads/blueshield - backpack_contents = list( - /obj/item/storage/box/deathimp = 1, - /obj/item/gun/energy/gun/blueshield = 1 - ) - bio_chips = list(/obj/item/bio_chip/mindshield) - backpack = /obj/item/storage/backpack/blueshield - satchel = /obj/item/storage/backpack/satchel_blueshield - dufflebag = /obj/item/storage/backpack/duffel/blueshield - -/datum/job/judge - title = "Magistrate" - flag = JOB_JUDGE - department_flag = JOBCAT_ENGSEC - total_positions = 1 - spawn_positions = 1 - supervisors = "Nanotrasen Asset Protection" - department_head = list("Captain") - selection_color = "#ddddff" - req_admin_notify = TRUE - job_department_flags = DEP_FLAG_LEGAL - transfer_allowed = FALSE - minimal_player_age = 30 - exp_map = list(EXP_TYPE_SECURITY = 6000) // 100 hours baby - access = list( - ACCESS_BRIG, - ACCESS_COURT, - ACCESS_HEADS, - ACCESS_INTERNAL_AFFAIRS, - ACCESS_MAGISTRATE, - ACCESS_MAINT_TUNNELS, - ACCESS_RC_ANNOUNCE, - ACCESS_SEC_DOORS, - ACCESS_SECURITY, - ACCESS_WEAPONS, - ACCESS_TRAINER - ) - blacklisted_disabilities = list(DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_NERVOUS, DISABILITY_FLAG_LISP) - outfit = /datum/outfit/job/judge - important_information = "This role requires you to oversee legal matters and make important decisions about sentencing. You are required to have an extensive knowledge of Space Law and Security SOP and only operate within, not outside, the boundaries of the law." - -/datum/outfit/job/judge - name = "Magistrate" - jobtype = /datum/job/judge - uniform = /obj/item/clothing/under/rank/procedure/magistrate - suit = /obj/item/clothing/suit/magirobe - gloves = /obj/item/clothing/gloves/color/white - shoes = /obj/item/clothing/shoes/centcom - l_ear = /obj/item/radio/headset/heads/magistrate/alt - glasses = /obj/item/clothing/glasses/hud/security/sunglasses - id = /obj/item/card/id/magistrate - l_pocket = /obj/item/flash - r_pocket = /obj/item/clothing/accessory/legal_badge - pda = /obj/item/pda/heads/magistrate - backpack_contents = list( - /obj/item/melee/classic_baton/telescopic = 1 - ) - bio_chips = list(/obj/item/bio_chip/mindshield) - satchel = /obj/item/storage/backpack/satchel_sec - dufflebag = /obj/item/storage/backpack/duffel/security - -/datum/job/iaa - title = "Internal Affairs Agent" - flag = JOB_INTERNAL_AFFAIRS - department_flag = JOBCAT_SUPPORT - total_positions = 2 - spawn_positions = 2 - job_department_flags = DEP_FLAG_LEGAL - supervisors = "the magistrate" - department_head = list("Captain") - selection_color = "#ddddff" - access = list( - ACCESS_CARGO, - ACCESS_CONSTRUCTION, - ACCESS_COURT, - ACCESS_INTERNAL_AFFAIRS, - ACCESS_MAILSORTING, - ACCESS_MAINT_TUNNELS, - ACCESS_MEDICAL, - ACCESS_RESEARCH, - ACCESS_SEC_DOORS - ) - alt_titles = list("Human Resources Agent") - minimal_player_age = 30 - exp_map = list(EXP_TYPE_CREW = 600) - blacklisted_disabilities = list(DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_NERVOUS, DISABILITY_FLAG_LISP) - outfit = /datum/outfit/job/iaa - important_information = "Your job is to deal with affairs regarding Standard Operating Procedure. You are NOT in charge of Space Law affairs, nor can you override it. You are NOT a prisoner defence lawyer." - -/datum/outfit/job/iaa - name = "Internal Affairs Agent" - jobtype = /datum/job/iaa - uniform = /obj/item/clothing/under/rank/procedure/iaa - suit = /obj/item/clothing/suit/storage/iaa/blackjacket - shoes = /obj/item/clothing/shoes/brown - l_ear = /obj/item/radio/headset/headset_iaa/alt - glasses = /obj/item/clothing/glasses/hud/security/sunglasses - id = /obj/item/card/id/internalaffairsagent - l_pocket = /obj/item/laser_pointer - r_pocket = /obj/item/clothing/accessory/legal_badge/iaa - l_hand = /obj/item/storage/briefcase - pda = /obj/item/pda/iaa - backpack_contents = list( - /obj/item/flash = 1 - ) - bio_chips = list(/obj/item/bio_chip/mindshield) - satchel = /obj/item/storage/backpack/satchel_sec - dufflebag = /obj/item/storage/backpack/duffel/security - -/datum/job/nanotrasentrainer - title = "Nanotrasen Career Trainer" - flag = JOB_INSTRUCTOR - department_flag = JOBCAT_ENGSEC - total_positions = 2 - spawn_positions = 2 - supervisors = "the Nanotrasen Representative" - department_head = list("Captain") - selection_color = "#ddddff" - mentor_only = TRUE - job_department_flags = DEP_FLAG_COMMAND - transfer_allowed = FALSE - access = list( - ACCESS_ALL_PERSONAL_LOCKERS, - ACCESS_CARGO, - ACCESS_MAILSORTING, - ACCESS_CONSTRUCTION, - ACCESS_COURT, - ACCESS_EVA, - ACCESS_MAINT_TUNNELS, - ACCESS_MEDICAL, - ACCESS_RESEARCH, - ACCESS_SEC_DOORS, - ACCESS_THEATRE, - ACCESS_INTERNAL_AFFAIRS, - ACCESS_TRAINER - ) - blacklisted_disabilities = list(DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_NERVOUS, DISABILITY_FLAG_LISP) - outfit = /datum/outfit/job/nct - important_information = "Your job is to try to assist as many crew members as possible regardless of department. You are NOT permitted to give command staff advice on any command SOP questions or aid in legal advice." - -/datum/outfit/job/nct - name = "Nanotrasen Career Trainer" - jobtype = /datum/job/nanotrasentrainer - uniform = /obj/item/clothing/under/rank/procedure/nct - suit = /obj/item/clothing/suit/storage/nct - gloves = /obj/item/clothing/gloves/color/white - shoes = /obj/item/clothing/shoes/centcom - head = /obj/item/clothing/head/beret/nct/green - glasses = /obj/item/clothing/glasses/hud/skills/sunglasses - l_ear = /obj/item/radio/headset/headset_nct - id = /obj/item/card/id/nct - l_pocket = /obj/item/card/id/nct_data_chip - r_pocket = /obj/item/flash - pda = /obj/item/pda/heads/ntrep - backpack = /obj/item/storage/backpack/satchel - - backpack_contents = list( - /obj/item/pinpointer/crew = 1, - /obj/item/healthanalyzer/advanced = 1, - /obj/item/book/manual/sop_ntinstructor, - /obj/item/laser_pointer/blue = 1 - ) - - bio_chips = list(/obj/item/bio_chip/mindshield) - -/datum/outfit/job/nct/post_equip(mob/living/carbon/human/H, visualsOnly) - . = ..() - if(visualsOnly) - return - - var/obj/item/card/id/nct_data_chip/I = H.l_store - I.registered_user = H.mind.current - I.registered_name = H.real_name - var/icon/newphoto = get_id_photo(H, "Nanotrasen Career Trainer") - I.photo = newphoto - -/datum/outfit/job/nct/on_mind_initialize(mob/living/carbon/human/H) - . = ..() - H.mind.offstation_role = TRUE diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm deleted file mode 100644 index d0dbf604b5c31..0000000000000 --- a/code/game/jobs/job/support.dm +++ /dev/null @@ -1,559 +0,0 @@ -//Cargo -/datum/job/qm - title = "Quartermaster" - flag = JOB_QUARTERMASTER - department_flag = JOBCAT_SUPPORT - total_positions = 1 - spawn_positions = 1 - job_department_flags = DEP_FLAG_SUPPLY | DEP_FLAG_COMMAND - supervisors = "the captain" - department_head = list("Captain") - department_account_access = TRUE - selection_color = "#e2c59d" - access = list( - ACCESS_CARGO_BAY, - ACCESS_CARGO_BOT, - ACCESS_CARGO, - ACCESS_HEADS_VAULT, - ACCESS_HEADS, - ACCESS_KEYCARD_AUTH, - ACCESS_MAILSORTING, - ACCESS_MAINT_TUNNELS, - ACCESS_MINERAL_STOREROOM, - ACCESS_MINING_STATION, - ACCESS_MINING, - ACCESS_QM, - ACCESS_RC_ANNOUNCE, - ACCESS_SEC_DOORS, - ACCESS_SUPPLY_SHUTTLE, - ACCESS_WEAPONS, - ACCESS_TELEPORTER, - ACCESS_EXPEDITION - ) - blacklisted_disabilities = list(DISABILITY_FLAG_BLIND, DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_DIZZY) - outfit = /datum/outfit/job/qm - important_information = "This role requires you to coordinate a department. You are required to be familiar with Standard Operating Procedure (Supply), basic job duties, and act professionally (roleplay)." - exp_map = list(EXP_TYPE_SUPPLY = 1200) - -/datum/outfit/job/qm - name = "Quartermaster" - jobtype = /datum/job/qm - - uniform = /obj/item/clothing/under/rank/cargo/qm - shoes = /obj/item/clothing/shoes/workboots/mining - head = /obj/item/clothing/head/qm - l_ear = /obj/item/radio/headset/heads/qm - glasses = /obj/item/clothing/glasses/meson/sunglasses - mask = /obj/item/clothing/mask/cigarette/cigar/cohiba - id = /obj/item/card/id/quartermaster - l_hand = /obj/item/clipboard - l_pocket = /obj/item/mail_scanner - pda = /obj/item/pda/heads/qm - backpack_contents = list( - /obj/item/melee/classic_baton/telescopic = 1 - ) - - - -/datum/job/cargo_tech - title = "Cargo Technician" - flag = JOB_CARGOTECH - department_flag = JOBCAT_SUPPORT - total_positions = 2 - spawn_positions = 2 - job_department_flags = DEP_FLAG_SUPPLY - supervisors = "the quartermaster" - department_head = list("Quartermaster") - selection_color = "#eeddbe" - access = list( - ACCESS_CARGO_BAY, - ACCESS_CARGO, - ACCESS_MAILSORTING, - ACCESS_MAINT_TUNNELS, - ACCESS_MINERAL_STOREROOM, - ACCESS_SUPPLY_SHUTTLE, - ) - alt_titles = list("Mail Carrier", "Courier") - outfit = /datum/outfit/job/cargo_tech - -/datum/outfit/job/cargo_tech - name = "Cargo Technician" - jobtype = /datum/job/cargo_tech - - uniform = /obj/item/clothing/under/rank/cargo/tech - shoes = /obj/item/clothing/shoes/black - l_pocket = /obj/item/mail_scanner - l_ear = /obj/item/radio/headset/headset_cargo - id = /obj/item/card/id/supply - pda = /obj/item/pda/cargo - - - -/datum/job/mining - title = "Shaft Miner" - flag = JOB_MINER - department_flag = JOBCAT_SUPPORT - total_positions = 6 - spawn_positions = 8 - job_department_flags = DEP_FLAG_SUPPLY - supervisors = "the quartermaster" - department_head = list("Quartermaster") - selection_color = "#eeddbe" - access = list( - ACCESS_MAINT_TUNNELS, - ACCESS_MINERAL_STOREROOM, - ACCESS_MINING_STATION, - ACCESS_MINING, - ) - alt_titles = list("Spelunker") - outfit = /datum/outfit/job/mining - -/datum/outfit/job/mining - name = "Shaft Miner" - jobtype = /datum/job/mining - - l_ear = /obj/item/radio/headset/headset_cargo/mining - shoes = /obj/item/clothing/shoes/workboots/mining - gloves = /obj/item/clothing/gloves/color/black - uniform = /obj/item/clothing/under/rank/cargo/miner/lavaland - l_pocket = /obj/item/reagent_containers/hypospray/autoinjector/survival - r_pocket = /obj/item/storage/bag/ore - id = /obj/item/card/id/shaftminer - pda = /obj/item/pda/shaftminer - backpack_contents = list( - /obj/item/flashlight/seclite=1,\ - /obj/item/kitchen/knife/combat/survival=1,\ - /obj/item/mining_voucher=1,\ - /obj/item/stack/marker_beacon/ten=1 - ) - - backpack = /obj/item/storage/backpack/explorer - satchel = /obj/item/storage/backpack/satchel/explorer - box = /obj/item/storage/box/survival_mining - -/datum/outfit/job/mining/equipped - name = "Shaft Miner" - - suit = /obj/item/clothing/suit/hooded/explorer - mask = /obj/item/clothing/mask/gas/explorer - glasses = /obj/item/clothing/glasses/meson - suit_store = /obj/item/tank/internals/emergency_oxygen - internals_slot = ITEM_SLOT_SUIT_STORE - backpack_contents = list( - /obj/item/flashlight/seclite=1,\ - /obj/item/kitchen/knife/combat/survival=1, - /obj/item/mining_voucher=1, - /obj/item/t_scanner/adv_mining_scanner/lesser=1, - /obj/item/gun/energy/kinetic_accelerator=1,\ - /obj/item/stack/marker_beacon/ten=1 - ) - -/datum/outfit/job/mining/equipped/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - ..() - if(visualsOnly) - return - if(istype(H.wear_suit, /obj/item/clothing/suit/hooded)) - var/obj/item/clothing/suit/hooded/S = H.wear_suit - S.ToggleHood() - -/datum/outfit/job/mining/equipped/modsuit - name = "Shaft Miner (Equipment + MODsuit)" - back = /obj/item/mod/control/pre_equipped/mining/asteroid - mask = /obj/item/clothing/mask/breath - -/datum/job/explorer - title = "Explorer" - flag = JOB_EXPLORER - department_flag = JOBCAT_SUPPORT - job_department_flags = DEP_FLAG_SUPPLY - total_positions = 4 - spawn_positions = 4 - supervisors = "the quartermaster" - department_head = list("Quartermaster") - selection_color = "#eeddbe" - access = list( - ACCESS_MAINT_TUNNELS, - ACCESS_EXPEDITION, - ACCESS_EVA, - ACCESS_EXTERNAL_AIRLOCKS, - ACCESS_TELEPORTER, - ACCESS_CARGO, - ACCESS_CARGO_BAY, - ACCESS_MINERAL_STOREROOM, - ACCESS_SUPPLY_SHUTTLE, - ACCESS_MINING_STATION - ) - alt_titles = list("Salvage Technician", "Scavenger") - outfit = /datum/outfit/job/explorer - -/datum/outfit/job/explorer - name = "Explorer" - jobtype = /datum/job/explorer - l_ear = /obj/item/radio/headset/headset_cargo/expedition - head = /obj/item/clothing/head/soft/expedition - uniform = /obj/item/clothing/under/rank/cargo/expedition - gloves = /obj/item/clothing/gloves/color/black - shoes = /obj/item/clothing/shoes/jackboots - belt = /obj/item/storage/belt/utility/expedition - id = /obj/item/card/id/explorer - pda = /obj/item/pda/explorer - backpack = /obj/item/storage/backpack/explorer - satchel = /obj/item/storage/backpack/satchel/explorer - box = /obj/item/storage/box/survival_mining - -//Food -/datum/job/bartender - title = "Bartender" - flag = JOB_BARTENDER - department_flag = JOBCAT_SUPPORT - total_positions = 1 - spawn_positions = 1 - job_department_flags = DEP_FLAG_SERVICE - supervisors = "the head of personnel" - department_head = list("Head of Personnel") - selection_color = "#dddddd" - access = list(ACCESS_BAR, ACCESS_MAINT_TUNNELS, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) - outfit = /datum/outfit/job/bartender - -/datum/outfit/job/bartender - name = "Bartender" - jobtype = /datum/job/bartender - - uniform = /obj/item/clothing/under/rank/civilian/bartender - suit = /obj/item/clothing/suit/armor/vest - belt = /obj/item/storage/belt/bandolier/full - shoes = /obj/item/clothing/shoes/black - l_ear = /obj/item/radio/headset/headset_service - glasses = /obj/item/clothing/glasses/sunglasses/reagent - id = /obj/item/card/id/bartender - pda = /obj/item/pda/bar - backpack_contents = list( - /obj/item/toy/russian_revolver = 1, - /obj/item/eftpos = 1) - -/datum/outfit/job/bartender/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - H.dna.SetSEState(GLOB.soberblock,1) - singlemutcheck(H, GLOB.soberblock, MUTCHK_FORCED) - H.dna.default_blocks.Add(GLOB.soberblock) - H.check_mutations = 1 - -/datum/outfit/job/bartender/on_mind_initialize(mob/living/carbon/human/H) - . = ..() - ADD_TRAIT(H.mind, TRAIT_TABLE_LEAP, ROUNDSTART_TRAIT) - ADD_TRAIT(H.mind, TRAIT_SLEIGHT_OF_HAND, ROUNDSTART_TRAIT) - -/datum/job/chef - title = "Chef" - flag = JOB_CHEF - department_flag = JOBCAT_SUPPORT - total_positions = 1 - spawn_positions = 1 - job_department_flags = DEP_FLAG_SERVICE - supervisors = "the head of personnel" - department_head = list("Head of Personnel") - selection_color = "#dddddd" - access = list( - ACCESS_KITCHEN, - ACCESS_MAINT_TUNNELS - ) - alt_titles = list("Cook","Culinary Artist","Butcher") - outfit = /datum/outfit/job/chef - -/datum/outfit/job/chef - name = "Chef" - jobtype = /datum/job/chef - - uniform = /obj/item/clothing/under/rank/civilian/chef - suit = /obj/item/clothing/suit/chef - belt = /obj/item/storage/belt/chef - shoes = /obj/item/clothing/shoes/black - head = /obj/item/clothing/head/chefhat - l_ear = /obj/item/radio/headset/headset_service - id = /obj/item/card/id/chef - pda = /obj/item/pda/chef - backpack_contents = list( - /obj/item/eftpos=1,\ - /obj/item/paper/chef=1,\ - /obj/item/book/manual/wiki/chef_recipes=1) - -/datum/outfit/job/chef/on_mind_initialize(mob/living/carbon/human/H) - . = ..() - var/datum/martial_art/cqc/under_siege/justacook = new - justacook.teach(H) // requires mind - ADD_TRAIT(H.mind, TRAIT_TABLE_LEAP, ROUNDSTART_TRAIT) - ADD_TRAIT(H.mind, TRAIT_KNOWS_COOKING_RECIPES, ROUNDSTART_TRAIT) - if(H.mind) - H.mind.AddSpell(new /datum/spell/expert_chef) - -/datum/job/hydro - title = "Botanist" - flag = JOB_BOTANIST - department_flag = JOBCAT_SUPPORT - total_positions = 3 - spawn_positions = 2 - job_department_flags = DEP_FLAG_SERVICE - supervisors = "the head of personnel" - department_head = list("Head of Personnel") - selection_color = "#dddddd" - access = list( - ACCESS_HYDROPONICS, - ACCESS_MAINT_TUNNELS, - ACCESS_MORGUE - ) - alt_titles = list("Hydroponicist", "Botanical Researcher") - outfit = /datum/outfit/job/hydro - -/datum/outfit/job/hydro - name = "Botanist" - jobtype = /datum/job/hydro - - uniform = /obj/item/clothing/under/rank/civilian/hydroponics - suit = /obj/item/clothing/suit/apron - gloves = /obj/item/clothing/gloves/botanic_leather - shoes = /obj/item/clothing/shoes/black - l_ear = /obj/item/radio/headset/headset_service - suit_store = /obj/item/plant_analyzer - pda = /obj/item/pda/botanist - id = /obj/item/card/id/botanist - backpack = /obj/item/storage/backpack/botany - satchel = /obj/item/storage/backpack/satchel_hyd - dufflebag = /obj/item/storage/backpack/duffel/hydro - - - -//Griff //BS12 EDIT - -/datum/job/clown - title = "Clown" - flag = JOB_CLOWN - department_flag = JOBCAT_SUPPORT - total_positions = 1 - spawn_positions = 1 - job_department_flags = DEP_FLAG_SERVICE - supervisors = "the head of personnel" - department_head = list("Head of Personnel") - selection_color = "#dddddd" - access = list( - ACCESS_CLOWN, - ACCESS_MAINT_TUNNELS, - ACCESS_THEATRE - ) - outfit = /datum/outfit/job/clown - -/datum/outfit/job/clown - name = "Clown" - jobtype = /datum/job/clown - - uniform = /obj/item/clothing/under/rank/civilian/clown - shoes = /obj/item/clothing/shoes/clown_shoes - mask = /obj/item/clothing/mask/gas/clown_hat - l_pocket = /obj/item/bikehorn - l_ear = /obj/item/radio/headset/headset_service - id = /obj/item/card/id/clown - pda = /obj/item/pda/clown - backpack_contents = list( - /obj/item/food/grown/banana = 1, - /obj/item/stamp/clown = 1, - /obj/item/toy/crayon/rainbow = 1, - /obj/item/storage/fancy/crayons = 1, - /obj/item/reagent_containers/spray/waterflower = 1, - /obj/item/reagent_containers/drinks/bottle/bottleofbanana = 1, - /obj/item/instrument/bikehorn = 1 - ) - - bio_chips = list(/obj/item/bio_chip/sad_trombone) - - backpack = /obj/item/storage/backpack/clown - satchel = /obj/item/storage/backpack/satchel/clown - dufflebag = /obj/item/storage/backpack/duffel/clown - -/datum/outfit/job/clown/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(HAS_TRAIT(SSstation, STATION_TRAIT_BANANIUM_SHIPMENTS)) - backpack_contents += /obj/item/stack/sheet/mineral/bananium/fifty - if(H.gender == FEMALE) - mask = /obj/item/clothing/mask/gas/clown_hat/sexy - uniform = /obj/item/clothing/under/rank/civilian/clown/sexy - -/datum/outfit/job/clown/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(visualsOnly) - return - - if(ismachineperson(H)) - var/obj/item/organ/internal/cyberimp/brain/clown_voice/implant = new - implant.insert(H) - - H.dna.SetSEState(GLOB.clumsyblock, TRUE) - singlemutcheck(H, GLOB.clumsyblock, MUTCHK_FORCED) - H.dna.default_blocks.Add(GLOB.clumsyblock) - if(!ismachineperson(H)) - H.dna.SetSEState(GLOB.comicblock, TRUE) - singlemutcheck(H, GLOB.comicblock, MUTCHK_FORCED) - H.dna.default_blocks.Add(GLOB.comicblock) - H.check_mutations = TRUE - H.add_language("Clownish") - H.AddComponent(/datum/component/slippery, H, 8 SECONDS, 100, 0, FALSE, TRUE, "slip", TRUE) - -//action given to antag clowns -/datum/action/innate/toggle_clumsy - name = "Toggle Clown Clumsy" - button_overlay_icon_state = "clown" - -/datum/action/innate/toggle_clumsy/Activate() - var/mob/living/carbon/human/H = owner - H.dna.SetSEState(GLOB.clumsyblock, TRUE) - singlemutcheck(H, GLOB.clumsyblock, MUTCHK_FORCED) - active = TRUE - button_background_icon_state = "bg_spell" - UpdateButtons() - to_chat(H, "You start acting clumsy to throw suspicions off. Focus again before using weapons.") - -/datum/action/innate/toggle_clumsy/Deactivate() - var/mob/living/carbon/human/H = owner - H.dna.SetSEState(GLOB.clumsyblock, FALSE) - singlemutcheck(H, GLOB.clumsyblock, MUTCHK_FORCED) - active = FALSE - button_background_icon_state = "bg_default" - UpdateButtons() - to_chat(H, "You focus and can now use weapons regularly.") - -/datum/job/mime - title = "Mime" - flag = JOB_MIME - department_flag = JOBCAT_SUPPORT - total_positions = 1 - spawn_positions = 1 - job_department_flags = DEP_FLAG_SERVICE - supervisors = "the head of personnel" - department_head = list("Head of Personnel") - selection_color = "#dddddd" - access = list( - ACCESS_MAINT_TUNNELS, - ACCESS_MIME, - ACCESS_THEATRE - ) - outfit = /datum/outfit/job/mime - -/datum/outfit/job/mime - name = "Mime" - jobtype = /datum/job/mime - - uniform = /obj/item/clothing/under/rank/civilian/mime - suit = /obj/item/clothing/suit/suspenders - back = /obj/item/storage/backpack/mime - gloves = /obj/item/clothing/gloves/color/white - shoes = /obj/item/clothing/shoes/black - head = /obj/item/clothing/head/beret - mask = /obj/item/clothing/mask/gas/mime - l_ear = /obj/item/radio/headset/headset_service - id = /obj/item/card/id/mime - pda = /obj/item/pda/mime - backpack_contents = list( - /obj/item/toy/crayon/mime = 1, - /obj/item/reagent_containers/drinks/bottle/bottleofnothing = 1, - /obj/item/cane = 1 - ) - - backpack = /obj/item/storage/backpack/mime - satchel = /obj/item/storage/backpack/mime - -/datum/outfit/job/mime/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - . = ..() - if(HAS_TRAIT(SSstation, STATION_TRAIT_TRANQUILITE_SHIPMENTS)) - backpack_contents += /obj/item/stack/sheet/mineral/tranquillite/fifty - if(H.gender == FEMALE) - uniform = /obj/item/clothing/under/rank/civilian/mime/sexy - suit = /obj/item/clothing/mask/gas/sexymime - - if(visualsOnly) - return - - H.DeleteComponent(/datum/component/footstep) - -/datum/outfit/job/mime/on_mind_initialize(mob/living/carbon/human/H) - . = ..() - H.mind.AddSpell(new /datum/spell/aoe/conjure/build/mime_wall(null)) - H.mind.AddSpell(new /datum/spell/mime/speak(null)) - H.mind.miming = TRUE - -/datum/job/janitor - title = "Janitor" - flag = JOB_JANITOR - department_flag = JOBCAT_SUPPORT - total_positions = 1 - spawn_positions = 1 - job_department_flags = DEP_FLAG_SERVICE - supervisors = "the head of personnel" - department_head = list("Head of Personnel") - selection_color = "#dddddd" - access = list( - ACCESS_JANITOR, - ACCESS_MAINT_TUNNELS - ) - alt_titles = list("Custodial Technician") - outfit = /datum/outfit/job/janitor - -/datum/outfit/job/janitor - name = "Janitor" - jobtype = /datum/job/janitor - - uniform = /obj/item/clothing/under/rank/civilian/janitor - shoes = /obj/item/clothing/shoes/black - l_ear = /obj/item/radio/headset/headset_service - id = /obj/item/card/id/janitor - pda = /obj/item/pda/janitor - r_pocket = /obj/item/door_remote/janikeyring - -/datum/outfit/job/janitor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - ..() - if(visualsOnly) - return - ADD_TRAIT(H, TRAIT_NEVER_MISSES_DISPOSALS, ROUNDSTART_TRAIT) - -//More or less assistants -/datum/job/librarian - title = "Librarian" - flag = JOB_LIBRARIAN - department_flag = JOBCAT_SUPPORT - total_positions = 1 - spawn_positions = 1 - job_department_flags = DEP_FLAG_SERVICE - supervisors = "the head of personnel" - department_head = list("Head of Personnel") - selection_color = "#dddddd" - access = list( - ACCESS_LIBRARY, - ACCESS_MAINT_TUNNELS - ) - alt_titles = list("Journalist") - outfit = /datum/outfit/job/librarian - -/datum/outfit/job/librarian - name = "Librarian" - jobtype = /datum/job/librarian - - uniform = /obj/item/clothing/under/rank/civilian/librarian - shoes = /obj/item/clothing/shoes/black - l_ear = /obj/item/radio/headset/headset_service - l_pocket = /obj/item/laser_pointer - r_pocket = /obj/item/barcodescanner - l_hand = /obj/item/storage/bag/books - id = /obj/item/card/id/librarian - pda = /obj/item/pda/librarian - backpack_contents = list( - /obj/item/videocam/advanced = 1) - -/datum/outfit/job/librarian/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - ..() - if(visualsOnly) - return - for(var/la in GLOB.all_languages) - var/datum/language/new_language = GLOB.all_languages[la] - if(new_language.flags & (HIVEMIND|NOLIBRARIAN)) - continue - H.add_language(la) diff --git a/code/game/jobs/job_globals.dm b/code/game/jobs/job_globals.dm deleted file mode 100644 index b81f5e410929a..0000000000000 --- a/code/game/jobs/job_globals.dm +++ /dev/null @@ -1,145 +0,0 @@ - -GLOBAL_LIST_INIT(station_departments, list(DEPARTMENT_COMMAND, DEPARTMENT_MEDICAL, DEPARTMENT_ENGINEERING, - DEPARTMENT_SCIENCE, DEPARTMENT_SECURITY, DEPARTMENT_SUPPLY, - DEPARTMENT_SERVICE, DEPARTMENT_ASSISTANT)) - -/// All roles that are within the command category -GLOBAL_LIST_INIT(command_positions, list( - "Captain", - "Head of Personnel", - "Head of Security", - "Chief Engineer", - "Research Director", - "Chief Medical Officer", - "Quartermaster", - "Nanotrasen Representative", - "Magistrate", - "Blueshield", - "Nanotrasen Career Trainer" -)) - -/// Only roles that are command of departments, for revolution and similar stuff -GLOBAL_LIST_INIT(command_head_positions, list( - "Captain", - "Head of Personnel", - "Head of Security", - "Chief Engineer", - "Research Director", - "Chief Medical Officer", - "Quartermaster" -)) - - -GLOBAL_LIST_INIT(engineering_positions, list( - "Chief Engineer", - "Station Engineer", - "Life Support Specialist", -)) - - -GLOBAL_LIST_INIT(medical_positions, list( - "Chief Medical Officer", - "Medical Doctor", - "Geneticist", - "Psychiatrist", - "Chemist", - "Virologist", - "Paramedic", - "Coroner" -)) - - -GLOBAL_LIST_INIT(science_positions, list( - "Research Director", - "Scientist", - "Geneticist", //Part of both medical and science - "Roboticist", -)) - -GLOBAL_LIST_INIT(service_positions, list( - "Head of Personnel", - "Bartender", - "Botanist", - "Chef", - "Janitor", - "Librarian", - "Internal Affairs Agent", - "Chaplain", - "Clown", - "Mime" -)) - -GLOBAL_LIST_INIT(supply_positions, list( - "Quartermaster", - "Cargo Technician", - "Shaft Miner", - "Explorer" -)) - -/// Roles that include any semblence of security, mostly for jobbans -GLOBAL_LIST_INIT(security_positions, list( - "Head of Security", - "Warden", - "Detective", - "Security Officer", - "Magistrate", - "Blueshield" -)) - -/// Active security roles -GLOBAL_LIST_INIT(active_security_positions, list( - "Head of Security", - "Warden", - "Detective", - "Security Officer" -)) - - - -GLOBAL_LIST_INIT(assistant_positions, list( - "Assistant" -)) - -GLOBAL_LIST_INIT(nonhuman_positions, list( - "AI", - "Cyborg", - "Drone", - "pAI" -)) - -/proc/get_job_datums() - var/list/occupations = list() - var/list/all_jobs = typesof(/datum/job) - - for(var/A in all_jobs) - var/datum/job/job = new A() - if(!job) continue - occupations += job - - return occupations - -/proc/get_alternate_titles(job) - var/list/jobs = get_job_datums() - var/list/titles = list() - - for(var/datum/job/J in jobs) - if(!J) continue - if(J.title == job) - titles = J.alt_titles - - return titles - -GLOBAL_LIST_INIT(exp_jobsmap, list( - EXP_TYPE_LIVING = list(), // all living mobs - EXP_TYPE_CREW = list(titles = command_positions | engineering_positions | medical_positions | science_positions | service_positions | supply_positions | security_positions | assistant_positions | list("AI","Cyborg")), // crew positions - EXP_TYPE_SPECIAL = list(), // antags, ERT, etc - EXP_TYPE_GHOST = list(), // dead people, observers - EXP_TYPE_COMMAND = list(titles = command_head_positions), - EXP_TYPE_ENGINEERING = list(titles = engineering_positions), - EXP_TYPE_MEDICAL = list(titles = medical_positions), - EXP_TYPE_SCIENCE = list(titles = science_positions), - EXP_TYPE_SUPPLY = list(titles = supply_positions), - EXP_TYPE_SECURITY = list(titles = active_security_positions), - EXP_TYPE_SILICON = list(titles = list("AI","Cyborg")), - EXP_TYPE_SERVICE = list(titles = service_positions), -)) diff --git a/code/game/jobs/job_objectives/science.dm b/code/game/jobs/job_objectives/science.dm deleted file mode 100644 index d07a3e96e3a5f..0000000000000 --- a/code/game/jobs/job_objectives/science.dm +++ /dev/null @@ -1,43 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////////////// -// Research -///////////////////////////////////////////////////////////////////////////////////////// - -// MAXIMUM SCIENCE -/datum/job_objective/further_research - objective_name = "Perform Research for Nanotrasen" - description = "Utilize the facilities on this research installation to increase half the station's research levels above level 2, have cargo ship the research to centcomm in crates." - gives_payout = TRUE - completion_payment = 150 - -/datum/job_objective/further_research/check_for_completion() - var/tech_above_two = 0 - for(var/tech in SSeconomy.tech_levels) - if(SSeconomy.tech_levels[tech] > 2) - tech_above_two++ - if(tech_above_two >= 6) - return TRUE - return FALSE - -///////////////////////////////////////////////////////////////////////////////////////// -// Robotics -///////////////////////////////////////////////////////////////////////////////////////// - -//Cyborgs -/datum/job_objective/make_cyborg - objective_name = "Construct Additional Cyborgs" - description = "Construct at least one cyborg for the station to increase workplace productivity." - gives_payout = TRUE - completion_payment = 100 - -/datum/job_objective/make_cyborg/check_for_completion() - return completed - -//RIPLEY's -/datum/job_objective/make_ripley - objective_name = "Construct a Working Class Mech" - description = "Construct a Ripley or Firefighter Mech for station usage. Don't forget about modules!" - gives_payout = TRUE - completion_payment = 200 - -/datum/job_objective/make_ripley/check_for_completion() - return completed diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm deleted file mode 100644 index d0bc0b0dca760..0000000000000 --- a/code/game/machinery/OpTable.dm +++ /dev/null @@ -1,104 +0,0 @@ -/obj/machinery/optable - name = "operating table" - desc = "Used for advanced medical procedures." - icon = 'icons/obj/surgery.dmi' - icon_state = "table2-idle" - density = TRUE - anchored = TRUE - interact_offline = TRUE - idle_power_consumption = 1 - active_power_consumption = 5 - can_buckle = TRUE // you can buckle someone if they have cuffs - buckle_lying = TRUE - var/mob/living/carbon/patient - var/obj/machinery/computer/operating/computer - var/no_icon_updates = FALSE //set this to TRUE if you don't want the icons ever changing - var/list/injected_reagents = list() - var/reagent_target_amount = 1 - var/inject_amount = 1 - - -/obj/machinery/optable/Initialize(mapload) - . = ..() - for(var/direction in list(NORTH,EAST,SOUTH,WEST)) - computer = locate(/obj/machinery/computer/operating, get_step(src, direction)) - if(computer) - computer.table = src - break - -/obj/machinery/optable/Destroy() - if(computer) - computer.table = null - computer = null - patient = null - return ..() - -/obj/machinery/optable/examine(mob/user) - . = ..() - . += "Click-drag someone to the table to place them on top of the table." - -/obj/machinery/optable/CanPass(atom/movable/mover, border_dir) - if(istype(mover) && mover.checkpass(PASSTABLE)) - return TRUE - if(isliving(mover)) - var/mob/living/our_mover = mover - if(IS_HORIZONTAL(our_mover) && HAS_TRAIT(our_mover, TRAIT_CONTORTED_BODY)) - return TRUE - else - return FALSE - -/obj/machinery/optable/MouseDrop_T(atom/movable/O, mob/user) - return take_patient(O, user) - -/obj/machinery/optable/post_unbuckle_mob(mob/living/M) - . = ..() - if(M == patient) - patient = null - update_appearance(UPDATE_ICON_STATE) - -/obj/machinery/optable/proc/take_patient(mob/living/carbon/new_patient, mob/living/carbon/user) - if((!ishuman(user) && !isrobot(user)) || !istype(new_patient)) - return - if(patient in buckled_mobs) - to_chat(user, "The table is already occupied!") - return - - // Attempt to settle the patient in - if(!user_buckle_mob(new_patient, user, check_loc = FALSE)) - return // User is incapacitated, patient is already buckled to something else, etc. - - patient = new_patient - - if(length(injected_reagents)) - to_chat(new_patient, "You feel a series of tiny pricks!") - - update_appearance(UPDATE_ICON_STATE) - - return TRUE - -/obj/machinery/optable/process() - - if(!length(injected_reagents) || !patient || patient.stat == DEAD) - return - - update_appearance(UPDATE_ICON_STATE) - - for(var/chemical in injected_reagents) - patient.reagents.check_and_add(chemical, reagent_target_amount, inject_amount) - -/obj/machinery/optable/update_icon_state() - if(no_icon_updates) - return - if(patient?.pulse) - icon_state = "table2-active" - else - icon_state = "table2-idle" - -/obj/machinery/optable/wrench_act(mob/user, obj/item/I) - . = TRUE - if(!I.tool_start_check(src, user, 0)) - return - if(I.use_tool(src, user, 20, volume = I.tool_volume)) - to_chat(user, "You deconstruct the table.") - new /obj/item/stack/sheet/plasteel(loc, 5) - qdel(src) diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm deleted file mode 100644 index f65c68866e52c..0000000000000 --- a/code/game/machinery/camera/camera_assembly.dm +++ /dev/null @@ -1,191 +0,0 @@ -#define ASSEMBLY_UNBUILT 0 // Nothing done to it -#define ASSEMBLY_WRENCHED 1 // Wrenched in place -#define ASSEMBLY_WELDED 2 // Welded in place -#define ASSEMBLY_WIRED 3 // Wires attached (Upgradable now) -#define ASSEMBLY_BUILT 4 // Fully built (incl panel closed) -#define HEY_IM_WORKING_HERE 666 //So nobody can mess with the camera while we're inputting settings - -/obj/item/camera_assembly - name = "camera assembly" - desc = "A pre-fabricated security camera kit, ready to be assembled and mounted to a surface." - icon = 'icons/obj/monitors.dmi' - icon_state = "cameracase" - w_class = WEIGHT_CLASS_SMALL - anchored = FALSE - materials = list(MAT_METAL=400, MAT_GLASS=250) - // Motion, EMP-Proof - var/list/obj/item/possible_upgrades = list(/obj/item/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma) - var/list/upgrades = list() - var/state = ASSEMBLY_UNBUILT - - -/obj/item/camera_assembly/Destroy() - QDEL_LIST_CONTENTS(upgrades) - return ..() - -/obj/item/camera_assembly/examine(mob/user) - . = ..() - switch(state) - if(ASSEMBLY_UNBUILT) - . += "The camera assembly's bolts need to be secured in a wall." - if(ASSEMBLY_WRENCHED) - . += "The camera assembly is bolted, but it needs to be welded into place." - if(ASSEMBLY_WELDED) - . += "The camera assembly is welded to the wall, it's lacking wires." - if(ASSEMBLY_WIRED) - . += "The camera assembly is wired, but the maintenence panel needs to be screwed shut." - . += "Upgrades can be added to the camera assembly, and removed with a crowbar." - -/obj/item/camera_assembly/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) - if(state == ASSEMBLY_WELDED && iscoil(I)) - var/obj/item/stack/cable_coil/C = I - if(C.use(2)) - to_chat(user, "You add wires to the assembly.") - playsound(loc, I.usesound, 50, 1) - state = ASSEMBLY_WIRED - else - to_chat(user, "You need 2 coils of wire to wire the assembly.") - return - - // Upgrades! - else if(is_type_in_list(I, possible_upgrades) && !is_type_in_list(I, upgrades)) // Is a possible upgrade and isn't in the camera already. - if(!user.drop_item_to_ground(I)) - to_chat(user, "[I] is stuck!") - return - to_chat(user, "You attach [I] into the assembly inner circuits.") - upgrades += I - user.drop_item() - I.loc = src - return - else - return ..() - -/obj/item/camera_assembly/crowbar_act(mob/user, obj/item/I) - if(!length(upgrades)) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - var/obj/U = locate(/obj) in upgrades - if(U) - to_chat(user, "You detach an upgrade from the assembly.") - playsound(loc, I.usesound, 50, 1) - U.loc = get_turf(src) - upgrades -= U - -/obj/item/camera_assembly/screwdriver_act(mob/user, obj/item/I) - if(state != ASSEMBLY_WIRED) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - state = HEY_IM_WORKING_HERE - var/input = strip_html(input(usr, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")) - if(!input) - state = ASSEMBLY_WIRED - to_chat(usr, "No input found please hang up and try your call again.") - return - - var/list/tempnetwork = splittext(input, ",") - if(length(tempnetwork) < 1) - state = ASSEMBLY_WIRED - to_chat(usr, "No network found please hang up and try your call again.") - return - - var/area/camera_area = get_area(src) - var/temptag = "[sanitize(camera_area.name)] ([rand(1, 999)])" - input = strip_html(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag)) - state = ASSEMBLY_BUILT - var/list/network_list = uniquelist(tempnetwork) - var/list/visible_networks = difflist(network_list, GLOB.restricted_camera_networks) - var/obj/machinery/camera/C = new(loc, length(visible_networks) > 0) - loc = C - C.assembly = src - - C.auto_turn() - - C.network = network_list - - C.c_tag = input - - for(var/i = 5; i >= 0; i -= 1) - var/direct = input(user, "Direction?", "Assembling Camera", null) in list("LEAVE IT", "NORTH", "EAST", "SOUTH", "WEST" ) - if(direct != "LEAVE IT") - C.dir = text2dir(direct) - if(i != 0) - var/confirm = tgui_alert(user, "Is this what you want? Chances Remaining: [i]", "Confirmation", list("Yes", "No")) - if(confirm == "Yes") - break - - -/obj/item/camera_assembly/wirecutter_act(mob/user, obj/item/I) - if(state != ASSEMBLY_WIRED) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - new/obj/item/stack/cable_coil(get_turf(src), 2) - WIRECUTTER_SNIP_MESSAGE - state = ASSEMBLY_WELDED - return - -/obj/item/camera_assembly/wrench_act(mob/user, obj/item/I) - if(state != ASSEMBLY_UNBUILT && state != ASSEMBLY_WRENCHED) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - if(state == ASSEMBLY_UNBUILT && isturf(loc)) - WRENCH_ANCHOR_TO_WALL_MESSAGE - anchored = TRUE - state = ASSEMBLY_WRENCHED - update_icon(UPDATE_ICON_STATE) - auto_turn() - else if(state == ASSEMBLY_WRENCHED) - WRENCH_UNANCHOR_WALL_MESSAGE - anchored = FALSE - update_icon(UPDATE_ICON_STATE) - state = ASSEMBLY_UNBUILT - else - to_chat(user, "[src] can't fit here!") - -/obj/item/camera_assembly/welder_act(mob/user, obj/item/I) - if(state == ASSEMBLY_UNBUILT) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - WELDER_ATTEMPT_WELD_MESSAGE - if(state == ASSEMBLY_WRENCHED) - if(!I.use_tool(src, user, 50, volume = I.tool_volume)) - return - to_chat(user, "You weld [src] into place.") - state = ASSEMBLY_WELDED - else if(state == ASSEMBLY_WELDED) - if(!I.use_tool(src, user, 50, volume = I.tool_volume)) - return - to_chat(user, "You unweld [src] from its place.") - state = ASSEMBLY_WRENCHED - -/obj/item/camera_assembly/update_icon_state() - if(anchored) - icon_state = "camera1" - else - icon_state = "cameracase" - -/obj/item/camera_assembly/attack_hand(mob/user as mob) - if(!anchored) - ..() - -/obj/item/camera_assembly/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - new /obj/item/stack/sheet/metal(loc) - qdel(src) - - -#undef ASSEMBLY_UNBUILT -#undef ASSEMBLY_WRENCHED -#undef ASSEMBLY_WELDED -#undef ASSEMBLY_WIRED -#undef ASSEMBLY_BUILT -#undef HEY_IM_WORKING_HERE diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm deleted file mode 100644 index 8a87ba6c0469c..0000000000000 --- a/code/game/machinery/computer/Operating.dm +++ /dev/null @@ -1,243 +0,0 @@ -#define OP_COMPUTER_COOLDOWN 60 - -/obj/machinery/computer/operating - name = "operating computer" - density = TRUE - anchored = TRUE - icon_keyboard = "med_key" - icon_screen = "crew" - circuit = /obj/item/circuitboard/operating - light_color = LIGHT_COLOR_PURE_BLUE - var/obj/machinery/optable/table - var/verbose = TRUE //general speaker toggle - var/oxyAlarm = 30 //oxy damage at which the computer will beep - var/choice = FALSE //just for going into and out of the options menu - var/healthAnnounce = TRUE //healther announcer toggle - var/crit = TRUE //crit beeping toggle - var/nextTick = OP_COMPUTER_COOLDOWN - var/healthAlarm = 50 - var/oxy = TRUE //oxygen beeping toggle - /// Who is on the Operating Table connected to the respective Operating Computer? - /// Only used to see if it changed from the previous occupant. If you want any actual information - /// about the mob - use `table.patient` instead. - var/mob/living/carbon/currentPatient - var/patientStatusHolder //Hold the last instance of table.patient.status. When table.patient.status no longer matches this variable, the computer should tell the doctor - -/obj/machinery/computer/operating/Initialize(mapload) - . = ..() - table = locate(/obj/machinery/optable, orange(1, src)) - if(table) - table.computer = src - -/obj/machinery/computer/operating/Destroy() - if(table) - table.computer = null - table = null - if(currentPatient) - currentPatient = null - return ..() - - - -/obj/machinery/computer/operating/examine(mob/user) - . = ..() - . += "This console gives information on the status of the patient on the adjacent operating table and the next surgery step required in the current surgery." - -/obj/machinery/computer/operating/attack_ai(mob/user) - add_fingerprint(user) - if(stat & (BROKEN|NOPOWER)) - return - ui_interact(user) - -/obj/machinery/computer/operating/attack_hand(mob/user) - if(..(user)) - return - - if(stat & (NOPOWER|BROKEN)) - return - - add_fingerprint(user) - ui_interact(user) - -/obj/machinery/computer/operating/ui_state(mob/user) - return GLOB.default_state - -/obj/machinery/computer/operating/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "OperatingComputer", "Patient Monitor") - ui.open() - -/obj/machinery/computer/operating/ui_data(mob/user) - var/list/data = list() - var/mob/living/carbon/occupant - if(table) - occupant = table.patient - data["hasOccupant"] = occupant ? 1 : 0 - var/occupantData[0] - - if(occupant) - occupantData["name"] = occupant.name - occupantData["stat"] = occupant.stat - occupantData["health"] = occupant.health - occupantData["maxHealth"] = occupant.maxHealth - occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD - occupantData["bruteLoss"] = occupant.getBruteLoss() - occupantData["oxyLoss"] = occupant.getOxyLoss() - occupantData["toxLoss"] = occupant.getToxLoss() - occupantData["fireLoss"] = occupant.getFireLoss() - occupantData["paralysis"] = occupant.AmountParalyzed() - occupantData["hasBlood"] = 0 - occupantData["bodyTemperature"] = occupant.bodytemperature - occupantData["maxTemp"] = 1000 - // Because we can put simple_animals in here, we need to do something tricky to get things working nice - occupantData["temperatureSuitability"] = 0 // 0 is the baseline - if(ishuman(occupant) && occupant.dna.species) - var/datum/species/sp = occupant.dna.species - if(occupant.bodytemperature < sp.cold_level_3) - occupantData["temperatureSuitability"] = -3 - else if(occupant.bodytemperature < sp.cold_level_2) - occupantData["temperatureSuitability"] = -2 - else if(occupant.bodytemperature < sp.cold_level_1) - occupantData["temperatureSuitability"] = -1 - else if(occupant.bodytemperature > sp.heat_level_3) - occupantData["temperatureSuitability"] = 3 - else if(occupant.bodytemperature > sp.heat_level_2) - occupantData["temperatureSuitability"] = 2 - else if(occupant.bodytemperature > sp.heat_level_1) - occupantData["temperatureSuitability"] = 1 - else if(isanimal(occupant)) - var/mob/living/simple_animal/silly = occupant - if(silly.bodytemperature < silly.minbodytemp) - occupantData["temperatureSuitability"] = -3 - else if(silly.bodytemperature > silly.maxbodytemp) - occupantData["temperatureSuitability"] = 3 - // Blast you, imperial measurement system - occupantData["btCelsius"] = occupant.bodytemperature - T0C - occupantData["btFaren"] = ((occupant.bodytemperature - T0C) * (9.0/5.0))+ 32 - occupantData["activeSurgeries"] = list() - - if(ishuman(occupant) && !(NO_BLOOD in occupant.dna.species.species_traits)) - var/mob/living/carbon/human/H = occupant - occupantData["pulse"] = occupant.get_pulse() - occupantData["hasBlood"] = 1 - occupantData["bloodLevel"] = round(occupant.blood_volume) - occupantData["bloodMax"] = H.max_blood - occupantData["bloodPercent"] = round(100*(occupant.blood_volume/H.max_blood), 0.01) //copy pasta ends here - - occupantData["bloodType"] = occupant.dna.blood_type - if(length(occupant.surgeries)) - occupantData["inSurgery"] = 1 - - for(var/datum/surgery/procedure in occupant.surgeries) - var/datum/surgery_step/surgery_step = procedure.get_surgery_step() - var/surgery_desc = "[capitalize(surgery_step.get_step_information(procedure, TRUE))]" - if(surgery_step.repeatable) - var/datum/surgery_step/next = procedure.get_surgery_next_step() - if(next) - surgery_desc += " or [capitalize(next.get_step_information(procedure, TRUE))]" - - occupantData["activeSurgeries"] += list(list( - "name" = "[capitalize(procedure.name)]", - "step" = surgery_desc, - "location" = capitalize(parse_zone(procedure.location)), - )) - - data["occupant"] = occupantData - data["verbose"] = verbose - data["oxyAlarm"] = oxyAlarm - data["choice"] = choice - data["health"] = healthAnnounce - data["crit"] = crit - data["healthAlarm"] = healthAlarm - data["oxy"] = oxy - - return data - - -/obj/machinery/computer/operating/ui_act(action, params) - if(..()) - return - - if(stat & (NOPOWER|BROKEN)) - return - - . = TRUE - switch(action) - if("verboseOn") - verbose = TRUE - if("verboseOff") - verbose = FALSE - if("healthOn") - healthAnnounce = TRUE - if("healthOff") - healthAnnounce = FALSE - if("critOn") - crit = TRUE - if("critOff") - crit = FALSE - if("oxyOn") - oxy = TRUE - if("oxyOff") - oxy = FALSE - if("oxy_adj") - oxyAlarm = clamp(text2num(params["new"]), -100, 100) - if("choiceOn") - choice = TRUE - if("choiceOff") - choice = FALSE - if("health_adj") - healthAlarm = clamp(text2num(params["new"]), -100, 100) - else - return FALSE - -/obj/machinery/computer/operating/process() - if(stat & (NOPOWER|BROKEN)) - return - if(!table) //Does this Operating Computer have an Operating Table connected to it? - return - if(!verbose) //Are the speakers on? - return - if(!table.patient) //Is there a patient on the table? - currentPatient = null - return - var/patientStatus // Tell the computer what to say based on the status of the patient on the table. - var/isNewPatient = (table.patient != currentPatient) //Is this a new Patient? - - if(table.patient.stat == DEAD || HAS_TRAIT(table.patient, TRAIT_FAKEDEATH)) - patientStatus = "Dead" - else if(table.patient.stat == CONSCIOUS) - patientStatus = "Awake" - else if(table.patient.stat == UNCONSCIOUS) - patientStatus = "Asleep" - - if(isNewPatient) - atom_say("New patient detected, loading stats") - var/blood_type_msg - if(ishuman(table.patient)) - blood_type_msg = table.patient.dna.blood_type - else - blood_type_msg = "\[ERROR: UNKNOWN\]" - atom_say("[table.patient], [blood_type_msg] blood, [patientStatus]") - SStgui.update_uis(src) - patientStatusHolder = table.patient.stat - currentPatient = table.patient - - if(nextTick < world.time) - nextTick=world.time + OP_COMPUTER_COOLDOWN - if(crit && table.patient.health <= -50) - playsound(src.loc, 'sound/machines/defib_success.ogg', 50, 0) - if(oxy && table.patient.getOxyLoss()>oxyAlarm) - playsound(src.loc, 'sound/machines/defib_saftyoff.ogg', 50, 0) - if(healthAnnounce && table.patient.health <= healthAlarm) - atom_say("[round(table.patient.health)]") - if(table.patient.stat != patientStatusHolder) - atom_say("Patient is now [patientStatus]") - patientStatusHolder = table.patient.stat - -/obj/machinery/computer/operating/clockwork - name = "brass operating computer" - desc = "Staring at this causes your head to fill with static." - icon_state = "computer_clockwork" - -#undef OP_COMPUTER_COOLDOWN diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm deleted file mode 100644 index 1378b797a8af4..0000000000000 --- a/code/game/machinery/computer/ai_core.dm +++ /dev/null @@ -1,329 +0,0 @@ -/obj/structure/ai_core - density = TRUE - anchored = FALSE - name = "AI core" - icon = 'icons/mob/AI.dmi' - icon_state = "0" - max_integrity = 500 - var/state = 0 - var/datum/ai_laws/laws = new /datum/ai_laws/crewsimov() - var/obj/item/circuitboard/aicore/circuit = null - var/obj/item/mmi/brain = null - -/obj/structure/ai_core/Destroy() - QDEL_NULL(laws) - QDEL_NULL(circuit) - QDEL_NULL(brain) - return ..() - -/obj/structure/ai_core/attackby__legacy__attackchain(obj/item/P, mob/user, params) - switch(state) - if(EMPTY_CORE) - if(istype(P, /obj/item/circuitboard/aicore)) - if(!user.drop_item()) - return - playsound(loc, P.usesound, 50, 1) - to_chat(user, "You place the circuit board inside the frame.") - update_icon(UPDATE_ICON_STATE) - state = CIRCUIT_CORE - P.forceMove(src) - circuit = P - update_icon(UPDATE_ICON_STATE) - return - if(SCREWED_CORE) - if(istype(P, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = P - if(C.get_amount() >= 5) - playsound(loc, 'sound/items/deconstruct.ogg', 50, 1) - to_chat(user, "You start to add cables to the frame...") - if(do_after(user, 20, target = src) && state == SCREWED_CORE && C.use(5)) - to_chat(user, "You add cables to the frame.") - state = CABLED_CORE - update_icon(UPDATE_ICON_STATE) - else - to_chat(user, "You need five lengths of cable to wire the AI core!") - return - if(CABLED_CORE) - if(istype(P, /obj/item/stack/sheet/rglass)) - var/obj/item/stack/sheet/rglass/G = P - if(G.get_amount() >= 2) - playsound(loc, 'sound/items/deconstruct.ogg', 50, 1) - to_chat(user, "You start to put in the glass panel...") - if(do_after(user, 20, target = src) && state == CABLED_CORE && G.use(2)) - to_chat(user, "You put in the glass panel.") - state = GLASS_CORE - update_icon(UPDATE_ICON_STATE) - else - to_chat(user, "You need two sheets of reinforced glass to insert them into the AI core!") - return - - if(istype(P, /obj/item/ai_module/purge)) - laws.clear_inherent_laws() - to_chat(usr, "Law module applied.") - return - - if(istype(P, /obj/item/ai_module/freeform)) - var/obj/item/ai_module/freeform/M = P - if(!M.newFreeFormLaw) - to_chat(usr, "No law detected on module, please create one.") - return - laws.add_supplied_law(M.lawpos, M.newFreeFormLaw) - to_chat(usr, "Added a freeform law.") - return - - if(istype(P, /obj/item/ai_module/syndicate)) - var/obj/item/ai_module/syndicate/M = P - if(!M.newFreeFormLaw) - to_chat(usr, "No law detected on module, please create one.") - return - laws.add_ion_law(M.newFreeFormLaw) - to_chat(usr, "Added a hacked law.") - return - - if(istype(P, /obj/item/ai_module)) - var/obj/item/ai_module/M = P - if(!M.laws) - to_chat(usr, "This AI module can not be applied directly to AI cores.") - return - laws = M.laws - to_chat(usr, "Added [M.laws.name] laws.") - return - - if(istype(P, /obj/item/mmi) && !brain) - var/obj/item/mmi/M = P - if(!M.brainmob) - to_chat(user, "Sticking an empty [P] into the frame would sort of defeat the purpose.") - return - if(M.brainmob.stat == DEAD) - to_chat(user, "Sticking a dead [P] into the frame would sort of defeat the purpose.") - return - - if(!M.brainmob.client) - to_chat(user, "Sticking an inactive [M.name] into the frame would sort of defeat the purpose.") - return - - if(jobban_isbanned(M.brainmob, "AI") || jobban_isbanned(M.brainmob, "nonhumandept")) - to_chat(user, "This [P] does not seem to fit.") - return - - if(!M.brainmob.mind) - to_chat(user, "This [M.name] is mindless!") - return - - if(istype(P, /obj/item/mmi/syndie)) - to_chat(user, "This MMI does not seem to fit!") - return - - if(!user.drop_item()) - return - - M.forceMove(src) - brain = M - to_chat(user, "You add [M.name] to the frame.") - update_icon(UPDATE_ICON_STATE) - return - - return ..() - -/obj/structure/ai_core/crowbar_act(mob/living/user, obj/item/I) - if(state !=CIRCUIT_CORE && state != GLASS_CORE && !(state == CABLED_CORE && brain)) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - switch(state) - if(CIRCUIT_CORE) - to_chat(user, "You remove the circuit board.") - state = EMPTY_CORE - circuit.forceMove(loc) - circuit = null - update_icon(UPDATE_ICON_STATE) - return - if(GLASS_CORE) - to_chat(user, "You remove the glass panel.") - state = CABLED_CORE - new /obj/item/stack/sheet/rglass(loc, 2) - update_icon(UPDATE_ICON_STATE) - return - if(CABLED_CORE) - if(brain) - to_chat(user, "You remove the brain.") - brain.forceMove(loc) - brain = null - update_icon(UPDATE_ICON_STATE) - -/obj/structure/ai_core/screwdriver_act(mob/living/user, obj/item/I) - if(!(state in list(SCREWED_CORE, CIRCUIT_CORE, GLASS_CORE, AI_READY_CORE))) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - switch(state) - if(SCREWED_CORE) - to_chat(user, "You unfasten the circuit board.") - state = CIRCUIT_CORE - if(CIRCUIT_CORE) - to_chat(user, "You screw the circuit board into place.") - state = SCREWED_CORE - if(GLASS_CORE) - var/area/R = get_area(src) - message_admins("[key_name_admin(usr)] has completed an AI core in [R]: [ADMIN_COORDJMP(loc)].") - log_game("[key_name(usr)] has completed an AI core in [R]: [COORD(loc)].") - to_chat(user, "You connect the monitor.") - if(!brain) - var/open_for_latejoin = tgui_alert(user, "Would you like this core to be open for latejoining AIs?", "Latejoin", list("Yes", "No")) == "Yes" - var/obj/structure/ai_core/deactivated/D = new(loc) - if(open_for_latejoin) - GLOB.empty_playable_ai_cores += D - else - if(brain.brainmob.mind) - brain.brainmob.mind.remove_antag_datum(/datum/antagonist/cultist) - SSticker.mode.remove_revolutionary(brain.brainmob.mind, 1) - - var/mob/living/silicon/ai/A = new /mob/living/silicon/ai(loc, laws, brain) - // Stop holding onto the laws so we don't qdel them and make the AI randomly lose its laws when GC gives up and hard deletes them. - laws = null - if(A) //if there's no brain, the mob is deleted and a structure/AIcore is created - A.rename_self("AI", 1) - SSblackbox.record_feedback("amount", "ais_created", 1) - qdel(src) - if(AI_READY_CORE) - to_chat(user, "You disconnect the monitor.") - state = GLASS_CORE - update_icon(UPDATE_ICON_STATE) - - -/obj/structure/ai_core/wirecutter_act(mob/living/user, obj/item/I) - if(state != CABLED_CORE) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - if(brain) - to_chat(user, "Get that [brain.name] out of there first!") - else - to_chat(user, "You remove the cables.") - state = SCREWED_CORE - update_icon(UPDATE_ICON_STATE) - var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( loc ) - A.amount = 5 - -/obj/structure/ai_core/wrench_act(mob/living/user, obj/item/I) - . = TRUE - default_unfasten_wrench(user, I, 20) - -/obj/structure/ai_core/update_icon_state() - switch(state) - if(EMPTY_CORE) - icon_state = "0" - if(CIRCUIT_CORE) - icon_state = "1" - if(SCREWED_CORE) - icon_state = "2" - if(CABLED_CORE) - if(brain) - icon_state = "3b" - else - icon_state = "3" - if(GLASS_CORE) - icon_state = "4" - if(AI_READY_CORE) - icon_state = "ai-empty" - -/obj/structure/ai_core/deconstruct(disassembled = TRUE) - if(state == GLASS_CORE) - new /obj/item/stack/sheet/rglass(loc, 2) - if(state >= CABLED_CORE) - new /obj/item/stack/cable_coil(loc, 5) - if(circuit) - circuit.forceMove(loc) - circuit = null - new /obj/item/stack/sheet/plasteel(loc, 4) - qdel(src) - -/obj/structure/ai_core/welder_act(mob/user, obj/item/I) - if(state) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - WELDER_ATTEMPT_WELD_MESSAGE - if(I.use_tool(src, user, 20, volume = I.tool_volume)) - to_chat(user, "You deconstruct the frame.") - new /obj/item/stack/sheet/plasteel(drop_location(), 4) - qdel(src) - -/obj/structure/ai_core/deactivated - name = "inactive AI" - icon_state = "ai-empty" - anchored = TRUE - state = AI_READY_CORE - -/obj/structure/ai_core/deactivated/Initialize(mapload) - . = ..() - circuit = new(src) - -/obj/structure/ai_core/deactivated/Destroy() - if(src in GLOB.empty_playable_ai_cores) - GLOB.empty_playable_ai_cores -= src - return ..() - -/client/proc/empty_ai_core_toggle_latejoin() - set name = "Toggle AI Core Latejoin" - set category = "Admin" - - var/list/cores = list() - for(var/obj/structure/ai_core/deactivated/D in world) - cores["[D] ([D.loc.loc])"] = D - - if(!length(cores)) - to_chat(src, "No deactivated AI cores were found.") - - var/id = input("Which core?", "Toggle AI Core Latejoin", null) as null|anything in cores - if(!id) return - - var/obj/structure/ai_core/deactivated/D = cores[id] - if(!D) return - - if(D in GLOB.empty_playable_ai_cores) - GLOB.empty_playable_ai_cores -= D - to_chat(src, "\The [id] is now not available for latejoining AIs.") - else - GLOB.empty_playable_ai_cores += D - to_chat(src, "\The [id] is now available for latejoining AIs.") - - -/* -This is a good place for AI-related object verbs so I'm sticking it here. -If adding stuff to this, don't forget that an AI need to cancel_camera() whenever it physically moves to a different location. -That prevents a few funky behaviors. -*/ -//The type of interaction, the player performing the operation, the AI itself, and the card object, if any. - - -/atom/proc/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) - if(istype(card)) - if(card.flush) - to_chat(user, "ERROR: AI flush is in progress, cannot execute transfer protocol.") - return 0 - return 1 - - -/obj/structure/ai_core/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) - if(state != AI_READY_CORE || !..()) - return - //Transferring a carded AI to a core. - if(interaction == AI_TRANS_FROM_CARD) - AI.control_disabled = FALSE - AI.aiRadio.disabledAi = FALSE - AI.forceMove(loc)//To replace the terminal. - to_chat(AI, "You have been uploaded to a stationary terminal. Remote device connection restored.") - to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.
    ") - if(!AI.builtInCamera && GetComponent(/datum/component/ducttape)) - AI.builtInCamera = new /obj/machinery/camera/portable(AI) - AI.builtInCamera.c_tag = AI.name - AI.builtInCamera.network = list("SS13") - qdel(src) - else //If for some reason you use an empty card on an empty AI terminal. - to_chat(user, "There is no AI loaded on this terminal!") - diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm deleted file mode 100644 index 76fa090b1e1c6..0000000000000 --- a/code/game/machinery/computer/arcade.dm +++ /dev/null @@ -1,1029 +0,0 @@ -/obj/machinery/computer/arcade - name = "random arcade" - desc = "random arcade machine." - icon = 'icons/obj/computer.dmi' - icon_state = "arcade" - icon_keyboard = null - icon_screen = "invaders" - light_color = "#00FF00" - var/prize = /obj/item/stack/tickets - -/obj/machinery/computer/arcade/proc/Reset() - return - -/obj/machinery/computer/arcade/Initialize(mapload) - . = ..() - if(!circuit) - var/choice = pick(subtypesof(/obj/machinery/computer/arcade)) - var/obj/machinery/computer/arcade/chosen = new choice(loc) - chosen.dir = dir - return INITIALIZE_HINT_QDEL - Reset() - - -/obj/machinery/computer/arcade/proc/prizevend(score) - if(!length(contents)) - var/prize_amount - if(score) - prize_amount = score - else - prize_amount = rand(1, 10) - new prize(get_turf(src), prize_amount) - else - var/atom/movable/prize = pick(contents) - prize.loc = get_turf(src) - -/obj/machinery/computer/arcade/emp_act(severity) - ..(severity) - if(stat & (NOPOWER|BROKEN)) - return - var/num_of_prizes = 0 - switch(severity) - if(EMP_HEAVY) - num_of_prizes = rand(1,4) - if(EMP_LIGHT) - num_of_prizes = rand(0,2) - for(var/i = num_of_prizes; i > 0; i--) - prizevend() - explosion(get_turf(src), -1, 0, 1+num_of_prizes, flame_range = 1+num_of_prizes) - - -/obj/machinery/computer/arcade/battle - name = "arcade machine" - desc = "Does not support Pinball." - icon = 'icons/obj/computer.dmi' - icon_state = "battle_arcade" - icon_screen = "battle" - circuit = /obj/item/circuitboard/arcade/battle - var/enemy_name = "Space Villain" - var/temp = "Winners Don't Use Spacedrugs" //Temporary message, for attack messages, etc - var/player_hp = 30 //Player health/attack points - var/player_mp = 10 - var/enemy_hp = 45 //Enemy health/attack points - var/enemy_mp = 20 - var/gameover = 0 - var/blocked = 0 //Player cannot attack/heal while set - var/turtle = 0 - -/obj/machinery/computer/arcade/battle/Reset() - var/name_action - var/name_part1 - var/name_part2 - - name_action = pick("Defeat ", "Annihilate ", "Save ", "Strike ", "Stop ", "Destroy ", "Robust ", "Romance ", "Pwn ", "Own ", "Ban ") - - name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ") - name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers") - - enemy_name = replacetext((name_part1 + name_part2), "the ", "") - name = (name_action + name_part1 + name_part2) - -/obj/machinery/computer/arcade/battle/attack_hand(mob/user as mob) - if(..()) - return - user.set_machine(src) - var/dat = "Close" - dat += "

    [enemy_name]

    " - - dat += "

    [temp]

    " - dat += "
    Health: [player_hp] | Magic: [player_mp] | Enemy Health: [enemy_hp]
    " - - if(gameover) - dat += "
    New Game" - else - dat += "
    Attack | " - dat += "Heal | " - dat += "Recharge Power" - - dat += "
    " - - //user << browse(dat, "window=arcade") - //onclose(user, "arcade") - var/datum/browser/popup = new(user, "arcade", "Space Villain 2000") - popup.set_content(dat) - popup.open() - return - -/obj/machinery/computer/arcade/battle/Topic(href, href_list) - if(..()) - return - - if(!blocked && !gameover) - if(href_list["attack"]) - blocked = 1 - var/attackamt = rand(2,6) - temp = "You attack for [attackamt] damage!" - playsound(loc, 'sound/arcade/hit.ogg', 50, TRUE) - updateUsrDialog() - if(turtle > 0) - turtle-- - - sleep(10) - enemy_hp -= attackamt - arcade_action() - - else if(href_list["heal"]) - blocked = 1 - var/pointamt = rand(1,3) - var/healamt = rand(6,8) - temp = "You use [pointamt] magic to heal for [healamt] damage!" - playsound(loc, 'sound/arcade/heal.ogg', 50, TRUE) - updateUsrDialog() - turtle++ - - sleep(10) - player_mp -= pointamt - player_hp += healamt - blocked = 1 - updateUsrDialog() - arcade_action() - - else if(href_list["charge"]) - blocked = 1 - var/chargeamt = rand(4,7) - temp = "You regain [chargeamt] points" - playsound(loc, 'sound/arcade/mana.ogg', 50, TRUE) - player_mp += chargeamt - if(turtle > 0) - turtle-- - - updateUsrDialog() - sleep(10) - arcade_action() - - if(href_list["close"]) - usr.unset_machine() - usr << browse(null, "window=arcade") - - else if(href_list["newgame"]) //Reset everything - temp = "New Round" - player_hp = 30 - player_mp = 10 - enemy_hp = 45 - enemy_mp = 20 - gameover = 0 - turtle = 0 - - if(emagged) - Reset() - emagged = FALSE - - add_fingerprint(usr) - updateUsrDialog() - return - -/obj/machinery/computer/arcade/battle/proc/arcade_action() - if((enemy_mp <= 0) || (enemy_hp <= 0)) - if(!gameover) - gameover = 1 - temp = "[enemy_name] has fallen! Rejoice!" - playsound(loc, 'sound/arcade/win.ogg', 50, TRUE) - - if(emagged) - SSblackbox.record_feedback("tally", "arcade_status", 1, "win_emagged") - new /obj/effect/spawner/newbomb/timer/syndicate(get_turf(src)) - new /obj/item/clothing/head/collectable/petehat(get_turf(src)) - message_admins("[key_name_admin(usr)] has outbombed Cuban Pete and been awarded a bomb.") - log_game("[key_name(usr)] has outbombed Cuban Pete and been awarded a bomb.") - Reset() - emagged = FALSE - else - SSblackbox.record_feedback("tally", "arcade_status", 1, "win_normal") - prizevend(35) - - else if(emagged && (turtle >= 4)) - var/boomamt = rand(5,10) - temp = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!" - playsound(loc, 'sound/arcade/boom.ogg', 50, TRUE) - player_hp -= boomamt - - else if((enemy_mp <= 5) && (prob(70))) - var/stealamt = rand(2,3) - temp = "[enemy_name] steals [stealamt] of your power!" - playsound(loc, 'sound/arcade/steal.ogg', 50, TRUE) - player_mp -= stealamt - updateUsrDialog() - - if(player_mp <= 0) - gameover = 1 - sleep(10) - temp = "You have been drained! GAME OVER" - playsound(loc, 'sound/arcade/lose.ogg', 50, TRUE) - if(emagged) - SSblackbox.record_feedback("tally", "arcade_status", 1, "loss_mana_emagged") - usr.gib() - else - SSblackbox.record_feedback("tally", "arcade_status", 1, "loss_mana_normal") - - else if((enemy_hp <= 10) && (enemy_mp > 4)) - temp = "[enemy_name] heals for 4 health!" - playsound(loc, 'sound/arcade/heal.ogg', 50, TRUE) - enemy_hp += 4 - enemy_mp -= 4 - - else - var/attackamt = rand(3,6) - temp = "[enemy_name] attacks for [attackamt] damage!" - playsound(loc, 'sound/arcade/hit.ogg', 50, TRUE) - player_hp -= attackamt - - if((player_mp <= 0) || (player_hp <= 0)) - gameover = 1 - temp = "You have been crushed! GAME OVER" - playsound(loc, 'sound/arcade/lose.ogg', 50, TRUE) - if(emagged) - SSblackbox.record_feedback("tally", "arcade_status", 1, "loss_hp_emagged") - usr.gib() - else - SSblackbox.record_feedback("tally", "arcade_status", 1, "loss_hp_normal") - - blocked = 0 - return - - -/obj/machinery/computer/arcade/battle/emag_act(user as mob) - if(!emagged) - temp = "If you die in the game, you die for real!" - player_hp = 30 - player_mp = 10 - enemy_hp = 45 - enemy_mp = 20 - gameover = 0 - blocked = 0 - - emagged = TRUE - - enemy_name = "Cuban Pete" - name = "Outbomb Cuban Pete" - - add_hiddenprint(user) - updateUsrDialog() - return TRUE - -// *** THE ORION TRAIL ** // - -#define ORION_TRAIL_WINTURN 9 - -//Orion Trail Events -#define ORION_TRAIL_RAIDERS "Raiders" -#define ORION_TRAIL_FLUX "Interstellar Flux" -#define ORION_TRAIL_ILLNESS "Illness" -#define ORION_TRAIL_BREAKDOWN "Breakdown" -#define ORION_TRAIL_LING "Changelings?" -#define ORION_TRAIL_LING_ATTACK "Changeling Ambush" -#define ORION_TRAIL_MALFUNCTION "Malfunction" -#define ORION_TRAIL_COLLISION "Collision" -#define ORION_TRAIL_SPACEPORT "Spaceport" -#define ORION_TRAIL_BLACKHOLE "BlackHole" - - -/obj/machinery/computer/arcade/orion_trail - name = "The Orion Trail" - desc = "Learn how our ancestors got to Orion, and have fun in the process!" - icon_state = "arcade" - icon_screen = "orion" - circuit = /obj/item/circuitboard/arcade/orion_trail - var/busy = FALSE //prevent clickspam that allowed people to ~speedrun~ the game. - var/engine = 0 - var/hull = 0 - var/electronics = 0 - var/food = 80 - var/fuel = 60 - var/turns = 4 - var/playing = 0 - var/gameover = 0 - var/alive = 4 - var/eventdat = null - var/event = null - var/list/settlers = list("Harry","Larry","Bob") - var/list/events = list(ORION_TRAIL_RAIDERS = 3, - ORION_TRAIL_FLUX = 1, - ORION_TRAIL_ILLNESS = 3, - ORION_TRAIL_BREAKDOWN = 2, - ORION_TRAIL_LING = 3, - ORION_TRAIL_MALFUNCTION = 2, - ORION_TRAIL_COLLISION = 1, - ORION_TRAIL_SPACEPORT = 2 - ) - var/list/stops = list() - var/list/stopblurbs = list() - var/lings_aboard = 0 - var/spaceport_raided = 0 - var/spaceport_freebie = 0 - var/last_spaceport_action = "" - -/obj/machinery/computer/arcade/orion_trail/Reset() - // Sets up the main trail - stops = list("Pluto","Asteroid Belt","Proxima Centauri","Dead Space","Rigel Prime","Tau Ceti Beta","Black Hole","Space Outpost Beta-9","Orion Prime") - stopblurbs = list( - "Pluto, long since occupied with long-range sensors and scanners, stands ready to, and indeed continues to probe the far reaches of the galaxy.", - "At the edge of the Sol system lies a treacherous asteroid belt. Many have been crushed by stray asteroids and misguided judgement.", - "The nearest star system to Sol, in ages past it stood as a reminder of the boundaries of sub-light travel, now a low-population sanctuary for adventurers and traders.", - "This region of space is particularly devoid of matter. Such low-density pockets are known to exist, but the vastness of it is astounding.", - "Rigel Prime, the center of the Rigel system, burns hot, basking its planetary bodies in warmth and radiation.", - "Tau Ceti Beta has recently become a waypoint for colonists headed towards Orion. There are many ships and makeshift stations in the vicinity.", - "Sensors indicate that a black hole's gravitational field is affecting the region of space we were headed through. We could stay of course, but risk of being overcome by its gravity, or we could change course to go around, which will take longer.", - "You have come into range of the first man-made structure in this region of space. It has been constructed not by travellers from Sol, but by colonists from Orion. It stands as a monument to the colonists' success.", - "You have made it to Orion! Congratulations! Your crew is one of the few to start a new foothold for mankind!" - ) - -/obj/machinery/computer/arcade/orion_trail/proc/newgame() - // Set names of settlers in crew - settlers = list() - for(var/i = 1; i <= 3; i++) - add_crewmember() - add_crewmember("[usr]") - // Re-set items to defaults - engine = 1 - hull = 1 - electronics = 1 - food = 80 - fuel = 60 - alive = 4 - turns = 1 - event = null - playing = 1 - gameover = 0 - lings_aboard = 0 - - //spaceport junk - spaceport_raided = 0 - spaceport_freebie = 0 - last_spaceport_action = "" - -/obj/machinery/computer/arcade/orion_trail/attack_hand(mob/user) - if(..()) - return - if(fuel <= 0 || food <=0 || length(settlers) == 0) - gameover = 1 - event = null - user.set_machine(src) - var/dat = "" - if(gameover) - dat = "

    Game Over

    " - dat += "Like many before you, your crew never made it to Orion, lost to space...
    Forever." - if(length(settlers) == 0) - dat += "
    Your entire crew died, your ship joins the fleet of ghost-ships littering the galaxy." - else - if(food <= 0) - dat += "
    You ran out of food and starved." - if(emagged) - user.set_nutrition(0) //yeah you pretty hongry - to_chat(user, "Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor.") - if(fuel <= 0) - dat += "
    You ran out of fuel, and drift, slowly, into a star." - if(emagged) - var/mob/living/M = user - M.adjust_fire_stacks(5) - M.IgniteMob() //flew into a star, so you're on fire - to_chat(user, "You feel an immense wave of heat emanate from the arcade machine. Your skin bursts into flames.") - dat += "

    OK...

    " - - if(emagged) - to_chat(user, "You're never going to make it to Orion...") - user.death() - emagged = FALSE //removes the emagged status after you lose - playing = 0 //also a new game - name = "The Orion Trail" - desc = "Learn how our ancestors got to Orion, and have fun in the process!" - - else if(event) - dat = eventdat - else if(playing) - var/title = stops[turns] - var/subtext = stopblurbs[turns] - dat = "

    [title]

    " - dat += "[subtext]" - dat += "

    Crew:

    " - dat += english_list(settlers) - dat += "
    Food: [food] | Fuel: [fuel]" - dat += "
    Engine Parts: [engine] | Hull Panels: [hull] | Electronics: [electronics]" - if(turns == 7) - dat += "

    Go Around Continue

    " - else - dat += "

    Continue

    " - dat += "

    Kill a crewmember

    " - dat += "

    Close

    " - else - dat = "

    The Orion Trail

    " - dat += "

    Experience the journey of your ancestors!



    " - dat += "
    New Game
    " - dat += "

    Close

    " - var/datum/browser/popup = new(user, "arcade", "The Orion Trail",400,700) - popup.set_content(dat) - popup.open() - return - -/obj/machinery/computer/arcade/orion_trail/Topic(href, href_list) - . = ..() - if(.) - return - if(href_list["close"]) - usr.unset_machine() - usr << browse(null, "window=arcade") - - if(busy) - return - busy = TRUE - - if(href_list["continue"]) //Continue your travels - if(turns >= ORION_TRAIL_WINTURN) - win() - else - food -= (alive+lings_aboard)*2 - fuel -= 5 - if(turns == 2 && prob(30)) - event = ORION_TRAIL_COLLISION - event() - else if(prob(75)) - event = pickweight(events) - if(lings_aboard) - if(event == ORION_TRAIL_LING || prob(55)) - event = ORION_TRAIL_LING_ATTACK - event() - turns += 1 - if(emagged) - var/mob/living/carbon/M = usr //for some vars - switch(event) - if(ORION_TRAIL_RAIDERS) - if(prob(50)) - to_chat(usr, "You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?") - M.AdjustHallucinate(30 SECONDS) - else - to_chat(usr, "Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there...") - M.take_organ_damage(30) - playsound(loc, 'sound/weapons/genhit2.ogg', 100, TRUE) - if(ORION_TRAIL_ILLNESS) - var/severity = rand(1,3) //pray to RNGesus. PRAY, PIGS - if(severity == 1) - to_chat(M, "You suddenly feel slightly nauseous.")//got off lucky - - if(severity == 2) - to_chat(usr, "You suddenly feel extremely nauseous and hunch over until it passes.") - M.Stun(6 SECONDS) - if(severity >= 3) //you didn't pray hard enough - to_chat(M, "An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit.") - M.Stun(10 SECONDS) - sleep(30) - atom_say("[M] violently throws up!") - playsound(loc, 'sound/effects/splat.ogg', 50, TRUE) - M.adjust_nutrition(-50) //lose a lot of food - var/turf/location = usr.loc - if(issimulatedturf(location)) - location.add_vomit_floor(TRUE) - if(ORION_TRAIL_FLUX) - if(prob(75)) - M.Weaken(6 SECONDS) - atom_say("A sudden gust of powerful wind slams [M] into the floor!") - M.take_organ_damage(25) - playsound(loc, 'sound/weapons/genhit.ogg', 100, TRUE) - else - to_chat(M, "A violent gale blows past you, and you barely manage to stay standing!") - if(ORION_TRAIL_COLLISION) //by far the most damaging event - if(prob(90)) - playsound(loc, 'sound/effects/bang.ogg', 100, TRUE) - var/turf/simulated/floor/F - for(F in orange(1, src)) - F.ChangeTurf(F.baseturf) - atom_say("Something slams into the floor around [src], exposing it to space!") - if(hull) - sleep(10) - atom_say("A new floor suddenly appears around [src]. What the hell?") - playsound(loc, 'sound/weapons/genhit.ogg', 100, TRUE) - var/turf/space/T - for(T in orange(1, src)) - T.ChangeTurf(/turf/simulated/floor/plating) - else - atom_say("Something slams into the floor around [src] - luckily, it didn't get through!") - playsound(loc, 'sound/effects/bang.ogg', 50, TRUE) - if(ORION_TRAIL_MALFUNCTION) - playsound(loc, 'sound/effects/empulse.ogg', 50, TRUE) - visible_message("[src] malfunctions, randomizing in-game stats!") - var/oldfood = food - var/oldfuel = fuel - food = rand(10,80) / rand(1,2) - fuel = rand(10,60) / rand(1,2) - if(electronics) - sleep(10) - if(oldfuel > fuel && oldfood > food) - audible_message("[src] lets out a somehow reassuring chime.") - else if(oldfuel < fuel || oldfood < food) - audible_message("[src] lets out a somehow ominous chime.") - food = oldfood - fuel = oldfuel - playsound(loc, 'sound/machines/chime.ogg', 50, TRUE) - - else if(href_list["newgame"]) //Reset everything - newgame() - else if(href_list["menu"]) //back to the main menu - playing = 0 - event = null - gameover = 0 - food = 80 - fuel = 60 - settlers = list("Harry","Larry","Bob") - else if(href_list["slow"]) //slow down - food -= (alive+lings_aboard)*2 - fuel -= 5 - event = null - else if(href_list["pastblack"]) //slow down - food -= ((alive+lings_aboard)*2)*3 - fuel -= 15 - turns += 1 - event = null - else if(href_list["useengine"]) //use parts - engine = max(0, --engine) - event = null - else if(href_list["useelec"]) //use parts - electronics = max(0, --electronics) - event = null - else if(href_list["usehull"]) //use parts - hull = max(0, --hull) - event = null - else if(href_list["wait"]) //wait 3 days - food -= ((alive+lings_aboard)*2)*3 - event = null - else if(href_list["keepspeed"]) //keep speed - if(prob(75)) - event = "Breakdown" - event() - else - event = null - else if(href_list["blackhole"]) //keep speed past a black hole - if(prob(75)) - event = ORION_TRAIL_BLACKHOLE - event() - if(emagged) //has to be here because otherwise it doesn't work - playsound(loc, 'sound/effects/supermatter.ogg', 100, TRUE) - atom_say("A miniature black hole suddenly appears in front of [src], devouring [usr] alive!") - if(isliving(usr)) - var/mob/living/L = usr - L.Stun(20 SECONDS) //you can't run :^) - var/S = new /obj/singularity/onetile(usr.loc) - emagged = FALSE //immediately removes emagged status so people can't kill themselves by sprinting up and interacting - sleep(50) - atom_say("[S] winks out, just as suddenly as it appeared.") - qdel(S) - else - event = null - turns += 1 - else if(href_list["holedeath"]) - gameover = 1 - event = null - else if(href_list["eventclose"]) //end an event - event = null - - else if(href_list["killcrew"]) //shoot a crewmember - if(length(settlers) <= 0 || alive <= 0) - return - var/sheriff = remove_crewmember() //I shot the sheriff - playsound(loc, 'sound/weapons/gunshots/gunshot.ogg', 100, TRUE) - - if(length(settlers) == 0 || alive == 0) - atom_say("The last crewmember [sheriff], shot themselves, GAME OVER!") - if(emagged) - usr.death(FALSE) - emagged = FALSE - gameover = TRUE - event = null - else if(emagged) - if(usr.name == sheriff) - atom_say("The crew of the ship chose to kill [usr.name]!") - usr.death(FALSE) - - if(event == ORION_TRAIL_LING) //only ends the ORION_TRAIL_LING event, since you can do this action in multiple places - event = null - - //Spaceport specific interactions - //they get a header because most of them don't reset event (because it's a shop, you leave when you want to) - //they also call event() again, to regen the eventdata, which is kind of odd but necessary - else if(href_list["buycrew"]) //buy a crewmember - var/bought = add_crewmember() - last_spaceport_action = "You hired [bought] as a new crewmember." - fuel -= 10 - food -= 10 - event() - - else if(href_list["sellcrew"]) //sell a crewmember - var/sold = remove_crewmember() - last_spaceport_action = "You sold your crewmember, [sold]!" - fuel += 7 - food += 7 - event() - - else if(href_list["leave_spaceport"]) - event = null - spaceport_raided = 0 - spaceport_freebie = 0 - last_spaceport_action = "" - - else if(href_list["raid_spaceport"]) - var/success = min(15 * alive,100) //default crew (4) have a 60% chance - spaceport_raided = 1 - - var/FU = 0 - var/FO = 0 - if(prob(success)) - FU = rand(5,15) - FO = rand(5,15) - last_spaceport_action = "You successfully raided the spaceport! you gained [FU] Fuel and [FO] Food! (+[FU]FU,+[FO]FO)" - else - FU = rand(-5,-15) - FO = rand(-5,-15) - last_spaceport_action = "You failed to raid the spaceport! you lost [FU*-1] Fuel and [FO*-1] Food in your scramble to escape! ([FU]FU,[FO]FO)" - - //your chance of lose a crewmember is 1/2 your chance of success - //this makes higher % failures hurt more, don't get cocky space cowboy! - if(prob(success*5)) - var/lost_crew = remove_crewmember() - last_spaceport_action = "You failed to raid the spaceport! you lost [FU*-1] Fuel and [FO*-1] Food, AND [lost_crew] in your scramble to escape! ([FU]FI,[FO]FO,-Crew)" - if(emagged) - atom_say("WEEWOO WEEWOO, Spaceport Security en route!") - for(var/i, i<=3, i++) - var/mob/living/simple_animal/hostile/syndicate/ranged/orion/O = new/mob/living/simple_animal/hostile/syndicate/ranged/orion(get_turf(src)) - O.target = usr - - - fuel += FU - food += FO - event() - - else if(href_list["buyparts"]) - switch(text2num(href_list["buyparts"])) - if(1) //Engine Parts - engine++ - last_spaceport_action = "Bought Engine Parts" - if(2) //Hull Plates - hull++ - last_spaceport_action = "Bought Hull Plates" - if(3) //Spare Electronics - electronics++ - last_spaceport_action = "Bought Spare Electronics" - fuel -= 5 //they all cost 5 - event() - - else if(href_list["trade"]) - switch(text2num(href_list["trade"])) - if(1) //Fuel - fuel -= 5 - food += 5 - last_spaceport_action = "Traded Fuel for Food" - if(2) //Food - fuel += 5 - food -= 5 - last_spaceport_action = "Traded Food for Fuel" - event() - - add_fingerprint(usr) - updateUsrDialog() - busy = FALSE - return - - -/obj/machinery/computer/arcade/orion_trail/proc/event() - eventdat = "

    [event]

    " - - switch(event) - if(ORION_TRAIL_RAIDERS) - eventdat += "Raiders have come aboard your ship!" - if(prob(50)) - var/sfood = rand(1,10) - var/sfuel = rand(1,10) - food -= sfood - fuel -= sfuel - eventdat += "
    They have stolen [sfood] Food and [sfuel] Fuel." - else if(prob(10)) - var/deadname = remove_crewmember() - eventdat += "
    [deadname] tried to fight back but was killed." - else - eventdat += "
    Fortunately you fended them off without any trouble." - eventdat += "

    Continue

    " - eventdat += "

    Close

    " - - if(ORION_TRAIL_FLUX) - eventdat += "This region of space is highly turbulent.
    If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies." - eventdat += "
    What will you do?" - eventdat += "

    Slow Down Continue

    " - eventdat += "

    Close

    " - - if(ORION_TRAIL_ILLNESS) - eventdat += "A deadly illness has been contracted!" - var/deadname = remove_crewmember() - eventdat += "
    [deadname] was killed by the disease." - eventdat += "

    Continue

    " - eventdat += "

    Close

    " - - if(ORION_TRAIL_BREAKDOWN) - eventdat += "Oh no! The engine has broken down!" - eventdat += "
    You can repair it with an engine part, or you can make repairs for 3 days." - if(engine >= 1) - eventdat += "

    Use PartWait

    " - else - eventdat += "

    Wait

    " - eventdat += "

    Close

    " - - if(ORION_TRAIL_MALFUNCTION) - eventdat += "The ship's systems are malfunctioning!" - eventdat += "
    You can replace the broken electronics with spares, or you can spend 3 days troubleshooting the AI." - if(electronics >= 1) - eventdat += "

    Use PartWait

    " - else - eventdat += "

    Wait

    " - eventdat += "

    Close

    " - - if(ORION_TRAIL_COLLISION) - eventdat += "Something hit us! Looks like there's some hull damage." - if(prob(25)) - var/sfood = rand(5,15) - var/sfuel = rand(5,15) - food -= sfood - fuel -= sfuel - eventdat += "
    [sfood] Food and [sfuel] Fuel was vented out into space." - if(prob(10)) - var/deadname = remove_crewmember() - eventdat += "
    [deadname] was killed by rapid depressurization." - eventdat += "
    You can repair the damage with hull plates, or you can spend the next 3 days welding scrap together." - if(hull >= 1) - eventdat += "

    Use PartWait

    " - else - eventdat += "

    Wait

    " - eventdat += "

    Close

    " - - if(ORION_TRAIL_BLACKHOLE) - eventdat += "You were swept away into the black hole." - eventdat += "

    Oh...

    " - eventdat += "

    Close

    " - settlers = list() - - if(ORION_TRAIL_LING) - eventdat += "Strange reports warn of changelings infiltrating crews on trips to Orion..." - if(length(settlers) <= 2) - eventdat += "
    Your crew's chance of reaching Orion is so slim the changelings likely avoided your ship..." - eventdat += "

    Continue

    " - eventdat += "

    Close

    " - if(prob(10)) // "likely", I didn't say it was guaranteed! - lings_aboard = min(++lings_aboard,2) - else - if(lings_aboard) //less likely to stack lings - if(prob(20)) - lings_aboard = min(++lings_aboard,2) - else if(prob(70)) - lings_aboard = min(++lings_aboard,2) - - eventdat += "

    Kill a crewmember

    " - eventdat += "

    Risk it

    " - eventdat += "

    Close

    " - - if(ORION_TRAIL_LING_ATTACK) - if(lings_aboard <= 0) //shouldn't trigger, but hey. - eventdat += "Haha, fooled you, there are no changelings on board!" - eventdat += "
    (You should report this to a coder :S)" - else - var/ling1 = remove_crewmember() - var/ling2 = "" - if(lings_aboard >= 2) - ling2 = remove_crewmember() - - eventdat += "Oh no, some of your crew are Changelings!" - if(ling2) - eventdat += "
    [ling1] and [ling2]'s arms twist and contort into grotesque blades!" - else - eventdat += "
    [ling1]'s arm twists and contorts into a grotesque blade!" - - var/chance2attack = alive*20 - if(prob(chance2attack)) - var/chancetokill = 30*lings_aboard-(5*alive) //eg: 30*2-(10) = 50%, 2 lings, 2 crew is 50% chance - if(prob(chancetokill)) - var/deadguy = remove_crewmember() - eventdat += "
    The Changeling[ling2 ? "s":""] run[ling2 ? "":"s"] up to [deadguy] and capitulates them!" - else - eventdat += "
    You valiantly fight off the Changeling[ling2 ? "s":""]!" - eventdat += "
    You cut the Changeling[ling2 ? "s":""] up into meat... Eww" - if(ling2) - food += 30 - lings_aboard = max(0,lings_aboard-2) - else - food += 15 - lings_aboard = max(0,--lings_aboard) - else - eventdat += "
    The Changeling[ling2 ? "s":""] run[ling2 ? "":"s"] away, What wimps!" - if(ling2) - lings_aboard = max(0,lings_aboard-2) - else - lings_aboard = max(0,--lings_aboard) - - eventdat += "

    Continue

    " - eventdat += "

    Close

    " - - - if(ORION_TRAIL_SPACEPORT) - if(spaceport_raided) - eventdat += "The Spaceport is on high alert! They wont let you dock since you tried to attack them!" - if(last_spaceport_action) - eventdat += "
    Last Spaceport Action: [last_spaceport_action]" - eventdat += "

    Depart Spaceport

    " - eventdat += "

    Close

    " - else - eventdat += "You pull the ship up to dock at a nearby Spaceport, lucky find!" - eventdat += "
    This Spaceport is home to travellers who failed to reach Orion, but managed to find a different home..." - eventdat += "
    Trading terms: FU = Fuel, FO = Food" - if(last_spaceport_action) - eventdat += "
    Last Spaceport Action: [last_spaceport_action]" - eventdat += "

    Crew:

    " - eventdat += english_list(settlers) - eventdat += "
    Food: [food] | Fuel: [fuel]" - eventdat += "
    Engine Parts: [engine] | Hull Panels: [hull] | Electronics: [electronics]" - - - //If your crew is pathetic you can get freebies (provided you haven't already gotten one from this port) - if(!spaceport_freebie && (fuel < 20 || food < 20)) - spaceport_freebie++ - var/FU = 10 - var/FO = 10 - var/freecrew = 0 - if(prob(30)) - FU = 25 - FO = 25 - - if(prob(10)) - add_crewmember() - freecrew++ - - eventdat += "
    The traders of the spaceport take pitty on you, and give you some food and fuel (+[FU]FU,+[FO]FO)" - if(freecrew) - eventdat += "
    You also gain a new crewmember!" - - fuel += FU - food += FO - - //CREW INTERACTIONS - eventdat += "

    Crew Management:

    " - - //Buy crew - if(food > 10 && fuel > 10) - eventdat += "

    Hire a new Crewmember (-10FU,-10FO)

    " - else - eventdat += "

    Cant afford a new Crewmember

    " - - //Sell crew - if(length(settlers) > 1) - eventdat += "

    Sell crew for Fuel and Food (+7FU,+7FO)

    " - else - eventdat += "

    Cant afford to sell a Crewmember

    " - - //BUY/SELL STUFF - eventdat += "

    Spare Parts:

    " - - //Engine parts - if(fuel > 5) - eventdat += "

    Buy Engine Parts (-5FU)

    " - else - eventdat += "

    Cant afford to buy Engine Parts" - - //Hull plates - if(fuel > 5) - eventdat += "

    Buy Hull Plates (-5FU)

    " - else - eventdat += "

    Cant afford to buy Hull Plates" - - //Electronics - if(fuel > 5) - eventdat += "

    Buy Spare Electronics (-5FU)

    " - else - eventdat += "

    Cant afford to buy Spare Electronics" - - //Trade - if(fuel > 5) - eventdat += "

    Trade Fuel for Food (-5FU,+5FO)

    " - else - eventdat += "

    Cant afford to Trade Fuel for Food 5) - eventdat += "

    Trade Food for Fuel (+5FU,-5FO)

    " - else - eventdat += "

    Cant afford to Trade Food for Fuel= 1) //need to make sure we even have anyone to remove - removed = pick(safe2remove) - - if(removed) - if(lings_aboard && prob(40*lings_aboard)) //if there are 2 lings you're twice as likely to get one, obviously - lings_aboard = max(0,--lings_aboard) - settlers -= removed - alive-- - return removed - - -/obj/machinery/computer/arcade/orion_trail/proc/win() - playing = 0 - turns = 1 - atom_say("Congratulations, you made it to Orion!") - if(emagged) - new /obj/item/orion_ship(get_turf(src)) - message_admins("[key_name_admin(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") - log_game("[key_name(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") - else - var/score = 10 * (alive - lings_aboard) + 5 * (engine + hull + electronics) - prizevend(score) - emagged = FALSE - name = "The Orion Trail" - desc = "Learn how our ancestors got to Orion, and have fun in the process!" - -/obj/machinery/computer/arcade/orion_trail/emag_act(mob/user) - if(!emagged) - to_chat(user, "You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode.") - name = "The Orion Trail: Realism Edition" - desc = "Learn how our ancestors got to Orion, and try not to die in the process!" - add_hiddenprint(user) - newgame() - emagged = TRUE - return TRUE - -/mob/living/simple_animal/hostile/syndicate/ranged/orion - name = "spaceport security" - desc = "Premier corporate security forces for all spaceports found along the Orion Trail." - faction = list("orion") - loot = list() - del_on_death = TRUE - -/obj/item/orion_ship - name = "model settler ship" - desc = "A model spaceship, it looks like those used back in the day when travelling to Orion! It even has a miniature FX-293 reactor, which was renowned for its instability and tendency to explode..." - icon = 'icons/obj/toy.dmi' - icon_state = "ship" - w_class = WEIGHT_CLASS_SMALL - var/active = FALSE //if the ship is on - -/obj/item/orion_ship/examine(mob/user) - . = ..() - if(in_range(user, src)) - if(!active) - . += "There's a little switch on the bottom. It's flipped down." - else - . += "There's a little switch on the bottom. It's flipped up." - -/obj/item/orion_ship/attack_self__legacy__attackchain(mob/user) //Minibomb-level explosion. Should probably be more because of how hard it is to survive the machine! Also, just over a 5-second fuse - if(active) - return - - message_admins("[key_name_admin(usr)] primed an explosive Orion ship for detonation.") - log_game("[key_name(usr)] primed an explosive Orion ship for detonation.") - - to_chat(user, "You flip the switch on the underside of [src].") - active = TRUE - visible_message("[src] softly beeps and whirs to life!") - playsound(loc, 'sound/machines/defib_saftyon.ogg', 25, TRUE) - atom_say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.") - sleep(20) - visible_message("[src] begins to vibrate...") - atom_say("Uh, Port? Having some issues with our reactor, could you check it out? Over.") - sleep(30) - atom_say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-") - playsound(loc, 'sound/machines/buzz-sigh.ogg', 25, TRUE) - sleep(3.6) - visible_message("[src] explodes!") - explosion(src.loc, 1,2,4, flame_range = 3) - qdel(src) - - -#undef ORION_TRAIL_WINTURN -#undef ORION_TRAIL_RAIDERS -#undef ORION_TRAIL_FLUX -#undef ORION_TRAIL_ILLNESS -#undef ORION_TRAIL_BREAKDOWN -#undef ORION_TRAIL_LING -#undef ORION_TRAIL_LING_ATTACK -#undef ORION_TRAIL_MALFUNCTION -#undef ORION_TRAIL_COLLISION -#undef ORION_TRAIL_SPACEPORT -#undef ORION_TRAIL_BLACKHOLE diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm deleted file mode 100644 index 5e762f6246f31..0000000000000 --- a/code/game/machinery/computer/buildandrepair.dm +++ /dev/null @@ -1,775 +0,0 @@ -/obj/item/circuitboard - /// Use `board_name` instead of this. - name = "circuit board" - icon = 'icons/obj/module.dmi' - icon_state = "id_mod" - item_state = "electronic" - origin_tech = "programming=2" - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_GLASS=200) - usesound = 'sound/items/deconstruct.ogg' - /// Use this instead of `name`. Formats as: `circuit board ([board_name])` - var/board_name = null - var/build_path = null - var/board_type = "computer" - var/list/req_components = null - -/obj/item/circuitboard/computer - board_type = "computer" - -/obj/item/circuitboard/machine - board_type = "machine" - -/obj/item/circuitboard/Initialize(mapload) - . = ..() - format_board_name() - -/obj/item/circuitboard/proc/format_board_name() - if(board_name) // Should always have this, but just in case. - name = "[initial(name)] ([board_name])" - else - name = "[initial(name)]" - -/obj/item/circuitboard/examine(mob/user) - . = ..() - if(LAZYLEN(req_components)) - var/list/nice_list = list() - for(var/B in req_components) - var/atom/A = B - if(!ispath(A)) - continue - nice_list += list("[req_components[A]] [initial(A.name)]\s") - . += "Required components: [english_list(nice_list)]." - -/obj/item/circuitboard/message_monitor - board_name = "Message Monitor" - icon_state = "engineering" - build_path = /obj/machinery/computer/message_monitor - origin_tech = "programming=2" - -/obj/item/circuitboard/camera - board_name = "Camera Monitor" - desc = "A monitor board whose type can be changed when screwed." - icon_state = "security" - build_path = /obj/machinery/computer/security - origin_tech = "programming=2;combat=2" - var/static/list/monitor_names_paths = list( - "Camera Monitor" = /obj/machinery/computer/security, - "Wooden TV" = /obj/machinery/computer/security/wooden_tv, - "Outpost Camera Monitor" = /obj/machinery/computer/security/mining, - "Engineering Camera Monitor" = /obj/machinery/computer/security/engineering, - "Research Monitor" = /obj/machinery/computer/security/telescreen/research, - "Research Director Monitor" = /obj/machinery/computer/security/telescreen/rd, - "Prison Monitor" = /obj/machinery/computer/security/telescreen/prison, - "Interrogation Monitor" = /obj/machinery/computer/security/telescreen/interrogation, - "MiniSat Monitor" = /obj/machinery/computer/security/telescreen/minisat, - "AI Upload Monitor" = /obj/machinery/computer/security/telescreen/upload, - "Vault Monitor" = /obj/machinery/computer/security/telescreen/vault, - "Turbine Vent Monitor" = /obj/machinery/computer/security/telescreen/turbine, - "Engine Camera Monitor" = /obj/machinery/computer/security/telescreen/engine) - -/obj/item/circuitboard/camera/screwdriver_act(mob/living/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - var/choice = tgui_input_list(user, "Circuit Setting", "What would you change the board setting to?", monitor_names_paths) - if(!choice) - return - board_name = choice - build_path = monitor_names_paths[choice] - format_board_name() - to_chat(user, "You set the board to [board_name].") - -/obj/item/circuitboard/camera/telescreen - board_name = "Telescreen" - icon_state = "security" - build_path = /obj/machinery/computer/security/telescreen - -/obj/item/circuitboard/camera/engine - board_name = "Engine Camera Monitor" - icon_state = "engineering" - build_path = /obj/machinery/computer/security/telescreen/engine - -/obj/item/circuitboard/camera/research - board_name = "Research Monitor" - icon_state = "science" - build_path = /obj/machinery/computer/security/telescreen/research - -/obj/item/circuitboard/camera/rd - board_name = "Research Director Monitor" - icon_state = "science" - build_path = /obj/machinery/computer/security/telescreen/rd - -/obj/item/circuitboard/camera/prison - board_name = "Prison Monitor" - icon_state = "security" - build_path = /obj/machinery/computer/security/telescreen/prison - -/obj/item/circuitboard/camera/interrogation - board_name = "Interrogation Monitor" - icon_state = "security" - build_path = /obj/machinery/computer/security/telescreen/interrogation - -/obj/item/circuitboard/camera/minisat - board_name = "MiniSat Monitor" - icon_state = "engineering" - build_path = /obj/machinery/computer/security/telescreen/minisat - -/obj/item/circuitboard/camera/upload - board_name = "AI Upload Monitor" - icon_state = "science" - build_path = /obj/machinery/computer/security/telescreen/upload - -/obj/item/circuitboard/camera/vault - board_name = "Vault Monitor" - icon_state = "command" - build_path = /obj/machinery/computer/security/telescreen/vault - -/obj/item/circuitboard/camera/turbine - board_name = "Turbine Vent Monitor" - icon_state = "engineering" - build_path = /obj/machinery/computer/security/telescreen/turbine - -/obj/item/circuitboard/camera/wooden_tv - board_name = "Wooden TV" - icon_state = "security" - build_path = /obj/machinery/computer/security/wooden_tv - -/obj/item/circuitboard/camera/mining - board_name = "Outpost Camera Monitor" - icon_state = "supply" - build_path = /obj/machinery/computer/security/mining - -/obj/item/circuitboard/camera/engineering - board_name = "Engineering Camera Monitor" - icon_state = "engineering" - build_path = /obj/machinery/computer/security/engineering - -/obj/item/circuitboard/xenobiology - board_name = "Xenobiology Console" - icon_state = "science" - build_path = /obj/machinery/computer/camera_advanced/xenobio - origin_tech = "programming=3;biotech=3" - -/obj/item/circuitboard/aicore - board_name = "AI Core" - icon_state = "science" - origin_tech = "programming=3" - board_type = "other" - -/obj/item/circuitboard/aiupload - board_name = "AI Upload" - icon_state = "command" - build_path = /obj/machinery/computer/aiupload - origin_tech = "programming=4;engineering=4" - -/obj/item/circuitboard/aiupload_broken - board_name = "AI Upload" - desc = "The board is charred and smells of burnt plastic. It has been rendered useless." - icon_state = "command_broken" - -/obj/item/circuitboard/borgupload - board_name = "Cyborg Upload" - icon_state = "command" - build_path = /obj/machinery/computer/borgupload - origin_tech = "programming=4;engineering=4" - -/obj/item/circuitboard/nonfunctional - board_name = "destroyed" - desc = "The board is barely recognizable. Its original function is a mystery." - icon_state = "command_broken" - -/obj/item/circuitboard/med_data - board_name = "Medical Records" - icon_state = "medical" - build_path = /obj/machinery/computer/med_data - origin_tech = "programming=2;biotech=2" - -/obj/item/circuitboard/pandemic - board_name = "PanD.E.M.I.C. 2200" - icon_state = "medical" - build_path = /obj/machinery/computer/pandemic - origin_tech = "programming=2;biotech=2" - -/obj/item/circuitboard/scan_consolenew - board_name = "DNA Machine" - icon_state = "medical" - build_path = /obj/machinery/computer/scan_consolenew - origin_tech = "programming=2;biotech=2" - -/obj/item/circuitboard/communications - board_name = "Communications Console" - icon_state = "engineering" - build_path = /obj/machinery/computer/communications - origin_tech = "programming=3;magnets=3" - -/obj/item/circuitboard/card - board_name = "ID Computer" - icon_state = "command" - build_path = /obj/machinery/computer/card - origin_tech = "programming=3" - -/obj/item/circuitboard/card/minor - board_name = "Dept ID Computer" - icon_state = "command" - build_path = /obj/machinery/computer/card/minor - var/target_dept = TARGET_DEPT_GENERIC - -/obj/item/circuitboard/card/minor/hos - board_name = "Sec ID Computer" - icon_state = "security" - build_path = /obj/machinery/computer/card/minor/hos - target_dept = TARGET_DEPT_SEC - -/obj/item/circuitboard/card/minor/cmo - board_name = "Medical ID Computer" - icon_state = "medical" - build_path = /obj/machinery/computer/card/minor/cmo - target_dept = TARGET_DEPT_MED - -/obj/item/circuitboard/card/minor/qm - board_name = "Supply ID Computer" - build_path = /obj/machinery/computer/card/minor/qm - target_dept = TARGET_DEPT_SUP - -/obj/item/circuitboard/card/minor/rd - board_name = "Science ID Computer" - icon_state = "science" - build_path = /obj/machinery/computer/card/minor/rd - target_dept = TARGET_DEPT_SCI - -/obj/item/circuitboard/card/minor/ce - board_name = "Engineering ID Computer" - icon_state = "engineering" - build_path = /obj/machinery/computer/card/minor/ce - target_dept = TARGET_DEPT_ENG - -/obj/item/circuitboard/card/centcom - board_name = "CentComm ID Computer" - icon_state = "command" - build_path = /obj/machinery/computer/card/centcom - -/obj/item/circuitboard/teleporter - board_name = "Teleporter Console" - icon_state = "engineering" - build_path = /obj/machinery/computer/teleporter - origin_tech = "programming=3;bluespace=3;plasmatech=3" - -/obj/item/circuitboard/secure_data - board_name = "Security Records" - icon_state = "security" - build_path = /obj/machinery/computer/secure_data - origin_tech = "programming=2;combat=2" - -/obj/item/circuitboard/stationalert_engineering - board_name = "Station Alert Console - Engineering" - icon_state = "engineering" - build_path = /obj/machinery/computer/station_alert - -/obj/item/circuitboard/stationalert - board_name = "Station Alert Console" - icon_state = "engineering" - build_path = /obj/machinery/computer/station_alert - -/obj/item/circuitboard/atmos_alert - board_name = "Atmospheric Alert Computer" - icon_state = "engineering" - build_path = /obj/machinery/computer/atmos_alert - -/obj/item/circuitboard/atmoscontrol - board_name = "Central Atmospherics Computer" - icon_state = "engineering" - build_path = /obj/machinery/computer/atmoscontrol - -/obj/item/circuitboard/air_management - board_name = "Air Sensor Monitor" - icon_state = "engineering" - build_path = /obj/machinery/computer/general_air_control - -/obj/item/circuitboard/robotics - board_name = "Robotics Control Console" - icon_state = "science" - build_path = /obj/machinery/computer/robotics - origin_tech = "programming=3" - -/obj/item/circuitboard/drone_control - board_name = "Drone Control" - icon_state = "engineering" - build_path = /obj/machinery/computer/drone_control - origin_tech = "programming=3" - -/obj/item/circuitboard/cloning - board_name = "Cloning Machine Console" - icon_state = "medical" - build_path = /obj/machinery/computer/cloning - origin_tech = "programming=2;biotech=2" - -/obj/item/circuitboard/arcade/battle - board_name = "Arcade Battle" - icon_state = "generic" - build_path = /obj/machinery/computer/arcade/battle - origin_tech = "programming=1" - -/obj/item/circuitboard/arcade/orion_trail - board_name = "Orion Trail" - icon_state = "generic" - build_path = /obj/machinery/computer/arcade/orion_trail - origin_tech = "programming=1" - -/obj/item/circuitboard/arcade/recruiter - board_name = "Nanotrasen Recruiter Simulator" - icon_state = "generic" - build_path = /obj/machinery/computer/arcade/recruiter - origin_tech = "programming=1" - -/obj/item/circuitboard/solar_control - board_name = "Solar Control" - icon_state = "engineering" - build_path = /obj/machinery/power/solar_control - origin_tech = "programming=2;powerstorage=2" - -/obj/item/circuitboard/powermonitor - board_name = "Power Monitor" - icon_state = "engineering" - build_path = /obj/machinery/computer/monitor - origin_tech = "programming=2;powerstorage=2" - -/obj/item/circuitboard/powermonitor/secret - board_name = "Outdated Power Monitor" - icon_state = "engineering" - build_path = /obj/machinery/computer/monitor/secret - origin_tech = "programming=2;powerstorage=2" - -/obj/item/circuitboard/prisoner - board_name = "Prisoner Management" - icon_state = "security" - build_path = /obj/machinery/computer/prisoner - -/obj/item/circuitboard/brigcells - board_name = "Brig Cell Control" - icon_state = "security" - build_path = /obj/machinery/computer/brigcells - -/obj/item/circuitboard/sm_monitor - board_name = "Supermatter Monitoring Console" - icon_state = "engineering" - build_path = /obj/machinery/computer/sm_monitor - origin_tech = "programming=2;powerstorage=2" - -/obj/item/circuitboard/singulo_monitor - board_name = "Singularity Monitoring Console" - icon_state = "engineering" - build_path = /obj/machinery/computer/singulo_monitor - origin_tech = "programming=2;powerstorage=2" - -// RD console circuits, so that de/reconstructing one of the special consoles doesn't ruin everything forever -/obj/item/circuitboard/rdconsole - board_name = "RD Console" - desc = "Swipe a Scientist level ID or higher to reconfigure." - icon_state = "science" - build_path = /obj/machinery/computer/rdconsole/core - req_access = list(ACCESS_TOX) // This is for adjusting the type of computer we're building - var/list/access_types = list("R&D Core", "Public") - -/obj/item/circuitboard/rdconsole/public - board_name = "RD Console - Public" - build_path = /obj/machinery/computer/rdconsole/public - -/obj/item/circuitboard/mecha_control - board_name = "Exosuit Control Console" - icon_state = "science" - build_path = /obj/machinery/computer/mecha - -/obj/item/circuitboard/rnd_network_controller - board_name = "R&D Network Controller" - icon_state = "science" - build_path = /obj/machinery/computer/rnd_network_controller - -/obj/item/circuitboard/rnd_backup_console - board_name = "R&D Backup Console" - icon_state = "science" - build_path = /obj/machinery/computer/rnd_backup - -/obj/item/circuitboard/crew - board_name = "Crew Monitoring Computer" - icon_state = "medical" - build_path = /obj/machinery/computer/crew - origin_tech = "programming=2;biotech=2" - -/obj/item/circuitboard/mech_bay_power_console - board_name = "Mech Bay Power Control Console" - icon_state = "science" - build_path = /obj/machinery/computer/mech_bay_power_console - origin_tech = "programming=3;powerstorage=3" - -/obj/item/circuitboard/ordercomp - board_name = "Supply Ordering Console" - icon_state = "supply" - build_path = /obj/machinery/computer/supplycomp/public - origin_tech = "programming=3" - -/obj/item/circuitboard/supplycomp - board_name = "Supply Shuttle Console" - icon_state = "supply" - build_path = /obj/machinery/computer/supplycomp - origin_tech = "programming=3" - var/contraband_enabled = 0 - -/obj/item/circuitboard/operating - board_name = "Operating Computer" - icon_state = "medical" - build_path = /obj/machinery/computer/operating - origin_tech = "programming=2;biotech=3" - -/obj/item/circuitboard/shuttle - board_name = "Shuttle" - icon_state = "generic" - build_path = /obj/machinery/computer/shuttle - var/shuttleId - var/possible_destinations = "" - -/obj/item/circuitboard/labor_shuttle - board_name = "Labor Shuttle" - icon_state = "security" - build_path = /obj/machinery/computer/shuttle/labor - -/obj/item/circuitboard/labor_shuttle/one_way - board_name = "Prisoner Shuttle Console" - icon_state = "security" - build_path = /obj/machinery/computer/shuttle/labor/one_way - -/obj/item/circuitboard/ferry - board_name = "Transport Ferry" - build_path = /obj/machinery/computer/shuttle/ferry - -/obj/item/circuitboard/ferry/request - board_name = "Transport Ferry Console" - icon_state = "supply" - build_path = /obj/machinery/computer/shuttle/ferry/request - -/obj/item/circuitboard/mining_shuttle - board_name = "Mining Shuttle" - icon_state = "supply" - build_path = /obj/machinery/computer/shuttle/mining - -/obj/item/circuitboard/white_ship - board_name = "White Ship" - icon_state = "generic" - build_path = /obj/machinery/computer/shuttle/white_ship - -/obj/item/circuitboard/shuttle/syndicate - board_name = "Syndicate Shuttle" - icon_state = "generic" - build_path = /obj/machinery/computer/shuttle/syndicate - -/obj/item/circuitboard/shuttle/syndicate/recall - board_name = "Syndicate Shuttle Recall Terminal" - icon_state = "generic" - build_path = /obj/machinery/computer/shuttle/syndicate/recall - -/obj/item/circuitboard/shuttle/syndicate/drop_pod - board_name = "Syndicate Drop Pod" - icon_state = "generic" - build_path = /obj/machinery/computer/shuttle/syndicate/drop_pod - -/obj/item/circuitboard/shuttle/golem_ship - board_name = "Golem Ship" - icon_state = "generic" - build_path = /obj/machinery/computer/shuttle/golem_ship - -/obj/item/circuitboard/holodeck_control - board_name = "Holodeck Control" - icon_state = "generic" - build_path = /obj/machinery/computer/holodeck_control - origin_tech = "programming=4" - -/obj/item/circuitboard/aifixer - board_name = "AI Integrity Restorer" - icon_state = "science" - build_path = /obj/machinery/computer/aifixer - origin_tech = "programming=2;biotech=2" - -/obj/item/circuitboard/area_atmos - board_name = "Area Air Control" - icon_state = "engineering" - build_path = /obj/machinery/computer/area_atmos - origin_tech = "programming=2" - -/obj/item/circuitboard/telesci_console - board_name = "Telepad Control Console" - icon_state = "science" - build_path = /obj/machinery/computer/telescience - origin_tech = "programming=3;bluespace=3;plasmatech=4" - -/obj/item/circuitboard/large_tank_control - board_name = "Atmospheric Tank Control" - icon_state = "engineering" - build_path = /obj/machinery/computer/general_air_control/large_tank_control - origin_tech = "programming=2;engineering=3;materials=2" - -/obj/item/circuitboard/turbine_computer - board_name = "Turbine Computer" - icon_state = "engineering" - build_path = /obj/machinery/computer/turbine_computer - origin_tech = "programming=4;engineering=4;powerstorage=4" - -/obj/item/circuitboard/supplycomp/multitool_act(mob/living/user, obj/item/I) - . = TRUE - var/catastasis // Why is it called this - var/opposite_catastasis - if(contraband_enabled) - catastasis = "BROAD" - opposite_catastasis = "STANDARD" - else - catastasis = "STANDARD" - opposite_catastasis = "BROAD" - - var/choice = tgui_alert(user, "Current receiver spectrum is set to: [catastasis]", "Multitool-Circuitboard interface", list("Switch to [opposite_catastasis]", "Cancel")) - if(!choice || choice == "Cancel") - return - - contraband_enabled = !contraband_enabled - playsound(src, 'sound/effects/pop.ogg', 50) - -/obj/item/circuitboard/rdconsole/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda)) - if(allowed(user)) - user.visible_message("[user] waves [user.p_their()] ID past [src]'s access protocol scanner.", "You swipe your ID past [src]'s access protocol scanner.") - var/console_choice = tgui_input_list(user, "What do you want to configure the access to?", "Access Modification", access_types) - if(!console_choice) - return - switch(console_choice) - if("R&D Core") - board_name = "RD Console" - build_path = /obj/machinery/computer/rdconsole/core - if("Public") - board_name = "RD Console - Public" - build_path = /obj/machinery/computer/rdconsole/public - - format_board_name() - to_chat(user, "Access protocols set to [console_choice].") - else - to_chat(user, "Access Denied.") - return - return ..() - -// Construction | Deconstruction -#define STATE_EMPTY 1 // Add a circuitboard | Weld to destroy -#define STATE_CIRCUIT 2 // Screwdriver the cover closed | Crowbar the circuit -#define STATE_NOWIRES 3 // Add wires | Screwdriver the cover open -#define STATE_WIRES 4 // Add glass | Remove wires -#define STATE_GLASS 5 // Screwdriver to complete | Crowbar glass out - -/obj/structure/computerframe - name = "computer frame" - icon = 'icons/obj/stock_parts.dmi' - icon_state = "comp_frame_1" - density = TRUE - anchored = TRUE - max_integrity = 100 - var/state = STATE_EMPTY - var/obj/item/circuitboard/circuit = null - -/obj/structure/computerframe/examine(mob/user) - . = ..() - . += "It is [anchored ? "bolted to the floor" : "unbolted"]." - switch(state) - if(STATE_EMPTY) - . += "The frame is welded together, but it is missing a circuit board." - if(STATE_CIRCUIT) - . += "A circuit board is firmly connected, but the cover is unscrewed and open." - if(STATE_NOWIRES) - . += "The cover is screwed shut, but the frame is missing wiring." - if(STATE_WIRES) - . += "The frame is wired, but the glass is missing." - if(STATE_GLASS) - . += "The glass is loosely connected and needs to be screwed into place." - if(!anchored) - . += "Alt-Click to rotate it." - -/obj/structure/computerframe/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - drop_computer_parts() - return ..() // will qdel the frame - -/obj/structure/computerframe/AltClick(mob/user) - if(user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!Adjacent(user)) - return - if(anchored) - to_chat(user, "The frame is anchored to the floor!") - return - setDir(turn(dir, 90)) - -/obj/structure/computerframe/obj_break(damage_flag) - deconstruct() - -/obj/structure/computerframe/proc/drop_computer_parts() - var/location = drop_location() - new /obj/item/stack/sheet/metal(location, 5) - if(circuit) - circuit.forceMove(location) - circuit = null - if(state >= STATE_WIRES) - var/obj/item/stack/cable_coil/C = new(location) - C.amount = 5 - if(state == STATE_GLASS) - new /obj/item/stack/sheet/glass(location, 2) - -/obj/structure/computerframe/update_icon_state() - icon_state = "comp_frame_[state]" - -/obj/structure/computerframe/welder_act(mob/user, obj/item/I) - if(state != STATE_EMPTY) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - WELDER_ATTEMPT_SLICING_MESSAGE - if(I.use_tool(src, user, 50, volume = I.tool_volume)) - WELDER_SLICING_SUCCESS_MESSAGE - deconstruct(TRUE) - -/obj/structure/computerframe/wrench_act(mob/living/user, obj/item/I) - . = TRUE - default_unfasten_wrench(user, I, 2 SECONDS) - -/obj/structure/computerframe/crowbar_act(mob/living/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user)) - return - - if(state == STATE_CIRCUIT) - to_chat(user, "You remove the circuit board.") - state = STATE_EMPTY - name = initial(name) - circuit.forceMove(drop_location()) - circuit = null - else if(state == STATE_GLASS) - to_chat(user, "You remove the glass panel.") - state = STATE_WIRES - new /obj/item/stack/sheet/glass(drop_location(), 2) - else - return - - I.play_tool_sound(src) - update_icon() - -/obj/structure/computerframe/screwdriver_act(mob/living/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user)) - return - - switch(state) - if(STATE_CIRCUIT) - to_chat(user, "You screw the circuit board into place.") - state = STATE_NOWIRES - I.play_tool_sound(src) - update_icon() - if(STATE_NOWIRES) - to_chat(user, "You unfasten the circuit board.") - state = STATE_CIRCUIT - I.play_tool_sound(src) - update_icon() - if(STATE_GLASS) - to_chat(user, "You connect the monitor.") - I.play_tool_sound(src) - var/obj/machinery/computer/B = new circuit.build_path(loc) - B.setDir(dir) - if(istype(circuit, /obj/item/circuitboard/supplycomp)) - var/obj/machinery/computer/supplycomp/SC = B - var/obj/item/circuitboard/supplycomp/C = circuit - SC.can_order_contraband = C.contraband_enabled - qdel(src) - -/obj/structure/computerframe/wirecutter_act(mob/living/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user)) - return - - if(state == STATE_WIRES) - to_chat(user, "You remove the cables.") - var/obj/item/stack/cable_coil/C = new(drop_location()) - C.amount = 5 - state = STATE_NOWIRES - I.play_tool_sound(src) - update_icon() - -/obj/structure/computerframe/attackby__legacy__attackchain(obj/item/I, mob/user, params) - switch(state) - if(STATE_EMPTY) - if(!istype(I, /obj/item/circuitboard)) - return ..() - - var/obj/item/circuitboard/B = I - if(B.board_type != "computer") - to_chat(user, "[src] does not accept circuit boards of this type!") - return - - if(!B.build_path) - to_chat(user, "This is not a functional computer circuit board!") - return - - B.play_tool_sound(src) - to_chat(user, "You place [B] inside [src].") - name += " ([B.board_name])" - state = STATE_CIRCUIT - user.drop_item() - B.forceMove(src) - circuit = B - update_icon() - return - - if(STATE_NOWIRES) - if(!istype(I, /obj/item/stack/cable_coil)) - return ..() - - var/obj/item/stack/cable_coil/C = I - if(C.get_amount() < 5) - to_chat(user, "You need five lengths of cable to wire the frame.") - return - - C.play_tool_sound(src) - to_chat(user, "You start to add cables to the frame.") - if(!do_after(user, 2 SECONDS * C.toolspeed, target = src)) - return - if(C.get_amount() < 5 || !C.use(5)) - to_chat(user, "At some point during construction you lost some cable. Make sure you have five lengths before trying again.") - return - - to_chat(user, "You add cables to the frame.") - state = STATE_WIRES - update_icon() - return - - if(STATE_WIRES) - if(!istype(I, /obj/item/stack/sheet/glass)) - return ..() - - var/obj/item/stack/sheet/glass/G = I - if(G.get_amount() < 2) - to_chat(user, "You need two sheets of glass for this.") - return - - G.play_tool_sound(src) - to_chat(user, "You start to add the glass panel to the frame.") - if(!do_after(user, 2 SECONDS * G.toolspeed, target = src)) - return - if(G.get_amount() < 2 || !G.use(2)) - to_chat(user, "At some point during construction you lost some glass. Make sure you have two sheets before trying again.") - return - - to_chat(user, "You put in the glass panel.") - state = STATE_GLASS - update_icon() - return - - return ..() - -#undef STATE_EMPTY -#undef STATE_CIRCUIT -#undef STATE_NOWIRES -#undef STATE_WIRES -#undef STATE_GLASS diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm deleted file mode 100644 index d50a9ee838366..0000000000000 --- a/code/game/machinery/computer/computer.dm +++ /dev/null @@ -1,199 +0,0 @@ -/obj/machinery/computer - name = "computer" - icon = 'icons/obj/computer.dmi' - icon_state = "computer" - density = TRUE - anchored = TRUE - idle_power_consumption = 300 - active_power_consumption = 300 - max_integrity = 200 - integrity_failure = 100 - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 40, ACID = 20) - var/obj/item/circuitboard/circuit = null //if circuit==null, computer can't disassembly - var/icon_keyboard = "generic_key" - var/icon_screen = "generic" - var/light_range_on = 2 - var/light_power_on = 0.9 - /// Are we in the middle of a flicker event? - var/flickering = FALSE - /// Are we forcing the icon to be represented in a no-power state? - var/force_no_power_icon_state = FALSE - -/obj/machinery/computer/Initialize(mapload) - . = ..() - power_change() - update_icon() - -/obj/machinery/computer/process() - if(stat & (NOPOWER|BROKEN)) - return FALSE - return TRUE - -/obj/machinery/computer/extinguish_light(force = FALSE) - set_light(0) - underlays.Cut() - visible_message("[src] grows dim, its screen barely readable.") - -/* - * Reimp, flash the screen on and off repeatedly. - */ -/obj/machinery/computer/flicker() - if(flickering) - return FALSE - - if(stat & (BROKEN|NOPOWER)) - return FALSE - - flickering = TRUE - INVOKE_ASYNC(src, TYPE_PROC_REF(/obj/machinery/computer, flicker_event)) - - return TRUE - -/* - * Proc to be called by invoke_async in the above flicker() proc. - */ -/obj/machinery/computer/proc/flicker_event() - var/amount = rand(5, 15) - - for(var/i in 1 to amount) - force_no_power_icon_state = TRUE - update_icon() - sleep(rand(1, 3)) - - force_no_power_icon_state = FALSE - update_icon() - sleep(rand(1, 10)) - update_icon() - flickering = FALSE - -/obj/machinery/computer/update_overlays() - . = ..() - underlays.Cut() - if((stat & NOPOWER) || force_no_power_icon_state) - if(icon_keyboard) - . += "[icon_keyboard]_off" - return - - // This whole block lets screens and keyboards ignore lighting and be visible even in the darkest room - var/overlay_state = icon_screen - if(stat & BROKEN) - overlay_state = "[icon_state]_broken" - . += "[overlay_state]" - if(!(stat & BROKEN) && light) - underlays += emissive_appearance(icon, "[icon_state]_lightmask") - - if(icon_keyboard) - . += "[icon_keyboard]" - underlays += emissive_appearance(icon, "[icon_keyboard]_lightmask") - - if(!(stat & BROKEN)) - // Get the average color of the computer screen so it can be used as a tinted glow - // Shamelessly stolen from /tg/'s /datum/component/customizable_reagent_holder. - var/icon/emissive_avg_screen_color = new(icon, overlay_state) - emissive_avg_screen_color.Scale(1, 1) - var/screen_emissive_color = copytext(emissive_avg_screen_color.GetPixel(1, 1), 1, 8) // remove opacity - set_light(light_range_on, light_power_on, screen_emissive_color) - -/obj/machinery/computer/power_change() - . = ..() //we don't check parent return due to this also being contigent on the BROKEN stat flag - if((stat & (BROKEN|NOPOWER))) - set_light(0) - else - set_light(light_range_on, light_power_on) - if(.) - update_icon() - -/obj/machinery/computer/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - if(stat & BROKEN) - playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, TRUE) - else - playsound(src.loc, 'sound/effects/glasshit.ogg', 75, TRUE) - if(BURN) - playsound(src.loc, 'sound/items/welder.ogg', 100, TRUE) - -/obj/machinery/computer/obj_break(damage_flag) - if(circuit && !(flags & NODECONSTRUCT)) //no circuit, no breaking - if(!(stat & BROKEN)) - playsound(loc, 'sound/effects/glassbr3.ogg', 100, TRUE) - stat |= BROKEN - update_icon() - set_light(0) - -/obj/machinery/computer/emp_act(severity) - ..() - switch(severity) - if(EMP_HEAVY) - if(prob(50)) - obj_break(ENERGY) - if(EMP_LIGHT) - if(prob(10)) - obj_break(ENERGY) - -/obj/machinery/computer/deconstruct(disassembled = TRUE, mob/user) - on_deconstruction() - if(!(flags & NODECONSTRUCT)) - if(circuit) //no circuit, no computer frame - var/obj/structure/computerframe/A = new /obj/structure/computerframe(loc) - var/obj/item/circuitboard/M = new circuit(A) - A.name += " ([M.board_name])" - A.setDir(dir) - A.circuit = M - A.anchored = TRUE - if(stat & BROKEN) - if(user) - to_chat(user, "The broken glass falls out.") - else - playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, TRUE) - new /obj/item/shard(drop_location()) - new /obj/item/shard(drop_location()) - A.state = 4 - else - if(user) - to_chat(user, "You disconnect the monitor.") - A.state = 5 - A.update_icon() - for(var/obj/C in src) - C.forceMove(loc) - qdel(src) - -/obj/machinery/computer/proc/set_broken() - if(!(resistance_flags & INDESTRUCTIBLE)) - stat |= BROKEN - update_icon() - -/obj/machinery/computer/proc/decode(text) - // Adds line breaks - text = replacetext(text, "\n", "
    ") - return text - -/obj/machinery/computer/attack_ghost(mob/user) - return attack_hand(user) - -/obj/machinery/computer/attack_hand(mob/user) - /* Observers can view computers, but not actually use them via Topic*/ - if(isobserver(user)) - return FALSE - return ..() - -/obj/machinery/computer/screwdriver_act(mob/user, obj/item/I) - . = TRUE - if(!I.tool_start_check(src, user, 0)) - return - if(circuit && !(flags & NODECONSTRUCT)) - if(I.use_tool(src, user, 20, volume = I.tool_volume)) - deconstruct(TRUE, user) - -/obj/machinery/computer/hit_by_thrown_mob(mob/living/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) - if(!self_hurt && prob(50 * (damage / 15))) - obj_break(MELEE) - take_damage(damage, BRUTE) - self_hurt = TRUE - return ..() - -/obj/machinery/computer/nonfunctional - name = "broken computer" - desc = "A computer long since rendered non-functional due to lack of maintenance. \ - It is spitting out error messages." - circuit = /obj/item/circuitboard/nonfunctional diff --git a/code/game/machinery/computer/singulo_monitor.dm b/code/game/machinery/computer/singulo_monitor.dm deleted file mode 100644 index 724ab93d44b6c..0000000000000 --- a/code/game/machinery/computer/singulo_monitor.dm +++ /dev/null @@ -1,177 +0,0 @@ -/obj/machinery/computer/singulo_monitor - name = "singularity monitoring console" - desc = "Used to monitor singularities." - icon_keyboard = "power_key" - icon_screen = "singumon_0" - circuit = /obj/item/circuitboard/singulo_monitor - light_color = LIGHT_COLOR_YELLOW - /// Cache-list of all singularities - var/list/singularities - /// Last energy level of the singularity so we know if it went up or down between cycles - var/last_energy - /// Reference to the active singularity - var/obj/singularity/active - /// Channel to send warning through to the engineers - var/warning_channel = "Engineering" - /// Channel to send breach containment alert - var/breach_channel = "Common" - /// Radio for sending announcements - var/obj/item/radio/singu_radio - /// List of field generators containing the singulo - var/list/field_gens = list() - -/obj/machinery/computer/singulo_monitor/Initialize(mapload) - . = ..() - singu_radio = new(src) - singu_radio.listening = FALSE - singu_radio.follow_target = src - singu_radio.config(list("[warning_channel]" = 0, "[breach_channel]" = 0)) - -/obj/machinery/computer/singulo_monitor/Destroy() - active = null - QDEL_NULL(singu_radio) - if(field_gens) - field_gens.Cut() - if(singularities) - singularities.Cut() - return ..() - -/obj/machinery/computer/singulo_monitor/attack_ai(mob/user) - attack_hand(user) - -/obj/machinery/computer/singulo_monitor/attack_hand(mob/user) - add_fingerprint(user) - if(stat & (BROKEN|NOPOWER)) - return - ui_interact(user) - -/obj/machinery/computer/singulo_monitor/ui_state(mob/user) - return GLOB.default_state - -/obj/machinery/computer/singulo_monitor/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "SingularityMonitor", name) - ui.open() - -/obj/machinery/computer/singulo_monitor/ui_data(mob/user) - var/list/data = list() - - if(istype(active)) - var/turf/T = get_turf(active) - // If we somehow dissipate during this proc, handle it somewhat - if(!T) - active = null - refresh() - return - - data["active"] = TRUE - data["singulo_stage"] = (active.current_size + 1) / 2 - data["singulo_potential_stage"] = (active.allowed_size + 1) / 2 - data["singulo_energy"] = active.energy - - switch(active.allowed_size) - if(STAGE_ONE) - data["singulo_high"] = STAGE_TWO_THRESHOLD - data["singulo_low"] = 0 - if(STAGE_TWO) - data["singulo_high"] = STAGE_THREE_THRESHOLD - data["singulo_low"] = STAGE_TWO_THRESHOLD - if(STAGE_THREE) - data["singulo_high"] = STAGE_FOUR_THRESHOLD - data["singulo_low"] = STAGE_THREE_THRESHOLD - if(STAGE_FOUR) - data["singulo_high"] = STAGE_FIVE_THRESHOLD - data["singulo_low"] = STAGE_FOUR_THRESHOLD - else - data["singulo_high"] = STAGE_SIX_THRESHOLD - data["singulo_low"] = STAGE_FIVE_THRESHOLD - - var/list/generators = list() - var/index = 1 - for(var/obj/machinery/field/generator/generator in field_gens) - generators.Add(list(list( - "charge" = generator.energy, - "gen_index" = index++ - ))) - data["generators"] = generators - - else - var/list/singulos = list() - for(var/obj/singularity/S in singularities) - var/area/A = get_area(S) - if(!A) - continue - - singulos.Add(list(list( - "area_name" = A.name, - "energy" = S.energy, - "stage" = (S.current_size + 1) / 2, - "singularity_id" = S.singulo_id - ))) - - data["active"] = FALSE - data["singularities"] = singulos - - return data - -/** - * Supermatter List Refresher - * - * This proc loops through the list of supermatters in the atmos SS and adds them to this console's cache list - */ -/obj/machinery/computer/singulo_monitor/proc/refresh() - singularities = list() - var/turf/T = get_turf(ui_host()) // Get the UI host incase this ever turned into a singularity monitoring module for AIs to use or something - if(!T) - return - for(var/obj/singularity/S in GLOB.singularities) - // not within coverage, not on a tile, not a gravitational singularity - if(S.type != /obj/singularity || !(is_station_level(S.z) || is_mining_level(S.z) || atoms_share_level(S, T))) - continue - singularities.Add(S) - - if(!(active in singularities)) - active = null - - -/obj/machinery/computer/singulo_monitor/process() - if(stat & (NOPOWER|BROKEN)) - return FALSE - if(active) - if(last_energy != active.energy) - last_energy = active.energy - icon_screen = (((active.allowed_size + 1) / 2) == 4 && active.energy >= (STAGE_FIVE_THRESHOLD - 100)) ? "singumon_pre5" : "singumon_[(active.allowed_size + 1) / 2]" - for(var/obj/machinery/field/generator/generator in field_gens) - if(generator?.active < 2 && field_gens) - field_gens = list() - else - icon_screen = "singumon_0" - update_icon() - - return TRUE - -/obj/machinery/computer/singulo_monitor/ui_act(action, params) - if(..()) - return - - if(stat & (BROKEN|NOPOWER)) - return - - . = TRUE - - switch(action) - if("refresh") - refresh() - - if("view") - var/newuid = text2num(params["view"]) - for(var/obj/singularity/S in singularities) - if(S.singulo_id == newuid) - active = S - if(active) - field_gens = active.find_field_gens() - break - - if("back") - active = null diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm deleted file mode 100644 index 3fc127338fdf3..0000000000000 --- a/code/game/machinery/deployable.dm +++ /dev/null @@ -1,519 +0,0 @@ -#define SINGLE "single" -#define VERTICAL "vertical" -#define HORIZONTAL "horizontal" - -#define METAL 1 -#define WOOD 2 -#define SAND 3 - -#define DROPWALL_UPTIME 1 MINUTES - -#define AUTO "automatic" - -//Barricades/cover - -/obj/structure/barricade - name = "chest high wall" - desc = "Looks like this would make good cover." - anchored = TRUE - density = TRUE - max_integrity = 100 - var/proj_pass_rate = 50 //How many projectiles will pass the cover. Lower means stronger cover - var/bar_material = METAL - var/drop_amount = 3 - var/stacktype = /obj/item/stack/sheet/metal - /// This variable is used to allow projectiles to always shoot through a barrier from a certain direction - var/directional_blockage = FALSE - //The list of directions to block a projectile from - var/list/directional_list = list() - -/obj/structure/barricade/Initialize(mapload) - . = ..() - AddComponent(/datum/component/debris, DEBRIS_WOOD, -20, 10) - -/obj/structure/barricade/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - make_debris() - qdel(src) - -/obj/structure/barricade/proc/make_debris() - if(stacktype) - new stacktype(get_turf(src), drop_amount) - -/obj/structure/barricade/welder_act(mob/user, obj/item/I) - if(bar_material != METAL) - return - if(obj_integrity >= max_integrity) - to_chat(user, "[src] does not need repairs.") - return - if(user.a_intent == INTENT_HARM) - return - if(!I.tool_use_check(user, 0)) - return - WELDER_ATTEMPT_REPAIR_MESSAGE - if(I.use_tool(src, user, 40, volume = I.tool_volume)) - WELDER_REPAIR_SUCCESS_MESSAGE - obj_integrity = clamp(obj_integrity + 20, 0, max_integrity) - update_icon() - return TRUE - -/obj/structure/barricade/CanPass(atom/movable/mover, border_dir)//So bullets will fly over and stuff. - if(locate(/obj/structure/barricade) in get_turf(mover)) - return TRUE - else if(istype(mover) && mover.checkpass(PASSBARRICADE)) - return TRUE - else if(isprojectile(mover)) - if(!anchored) - return TRUE - var/obj/item/projectile/proj = mover - if(directional_blockage) - if(one_eighty_check(mover)) - return FALSE - if(proj.firer && Adjacent(proj.firer)) - return TRUE - if(prob(proj_pass_rate)) - return TRUE - return FALSE - if(isitem(mover)) //thrown items with the dropwall - if(directional_blockage) - if(one_eighty_check(mover)) - return FALSE - return !density - -/obj/structure/barricade/proc/one_eighty_check(atom/movable/mover) - return turn(mover.dir, 180) in directional_list - -/////BARRICADE TYPES/////// - -/obj/structure/barricade/wooden - name = "wooden barricade" - desc = "This space is blocked off by a wooden barricade." - icon = 'icons/obj/structures.dmi' - icon_state = "woodenbarricade" - bar_material = WOOD - stacktype = /obj/item/stack/sheet/wood - - -/obj/structure/barricade/wooden/attackby__legacy__attackchain(obj/item/I, mob/user) - if(istype(I,/obj/item/stack/sheet/wood)) - var/obj/item/stack/sheet/wood/W = I - if(W.get_amount() < 5) - to_chat(user, "You need at least five wooden planks to make a wall!") - return - else - to_chat(user, "You start adding [I] to [src]...") - if(do_after(user, 50, target = src)) - if(!W.use(5)) - return - var/turf/T = get_turf(src) - T.ChangeTurf(/turf/simulated/wall/mineral/wood/nonmetal) - qdel(src) - return //return is need to prevent people from exploiting zero-hit cooldowns with the do_after here - return ..() - -/obj/structure/barricade/wooden/crowbar_act(mob/living/user, obj/item/I) - . = TRUE - if(!I.tool_use_check(user, 0)) - return - user.visible_message("[user] starts ripping [src] down!", "You struggle to pull [src] apart...", "You hear wood splintering...") - if(!I.use_tool(src, user, 6 SECONDS, volume = I.tool_volume)) - return - new /obj/item/stack/sheet/wood(get_turf(src), 5) - qdel(src) - -/obj/structure/barricade/wooden/crude - name = "crude plank barricade" - desc = "This space is blocked off by a crude assortment of planks." - icon_state = "woodenbarricade-old" - drop_amount = 1 - max_integrity = 50 - proj_pass_rate = 65 - -/obj/structure/barricade/wooden/crude/snow - desc = "This space is blocked off by a crude assortment of planks. It seems to be covered in a layer of snow." - icon_state = "woodenbarricade-snow-old" - max_integrity = 75 - -/obj/structure/barricade/sandbags - name = "sandbags" - desc = "Bags of sand. Self explanatory." - icon = 'icons/obj/smooth_structures/sandbags.dmi' - icon_state = "sandbags-0" - base_icon_state = "sandbags" - max_integrity = 280 - proj_pass_rate = 20 - pass_flags_self = LETPASSTHROW | PASSTAKE - bar_material = SAND - climbable = TRUE - smoothing_flags = SMOOTH_BITMASK - smoothing_groups = list(SMOOTH_GROUP_SANDBAGS) - canSmoothWith = list(SMOOTH_GROUP_SANDBAGS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_SECURITY_BARRICADE) - stacktype = null - -/obj/structure/barricade/security - name = "security barrier" - desc = "A deployable barrier. Provides good cover in fire fights." - icon = 'icons/obj/objects.dmi' - icon_state = "barrier0" - density = FALSE - anchored = FALSE - max_integrity = 180 - proj_pass_rate = 20 - armor = list(melee = 10, bullet = 50, laser = 50, energy = 50, bomb = 10, rad = 100, fire = 10, acid = 0) - stacktype = null - var/deploy_time = 40 - var/deploy_message = TRUE - -/obj/structure/barricade/security/Initialize(mapload) - . = ..() - addtimer(CALLBACK(src, PROC_REF(deploy)), deploy_time) - -/obj/structure/barricade/security/proc/deploy() - icon_state = "barrier1" - density = TRUE - anchored = TRUE - if(deploy_message) - visible_message("[src] deploys!") - - -/obj/item/grenade/barrier - name = "barrier grenade" - desc = "Instant cover." - icon = 'icons/obj/grenade.dmi' - icon_state = "wallbang" - item_state = "flashbang" - actions_types = list(/datum/action/item_action/toggle_barrier_spread) - var/mode = SINGLE - -/obj/item/grenade/barrier/examine(mob/user) - . = ..() - . += "Alt-click to toggle modes." - -/obj/item/grenade/barrier/AltClick(mob/living/carbon/user) - if(!istype(user) || !user.Adjacent(src) || user.incapacitated()) - return - toggle_mode(user) - -/obj/item/grenade/barrier/proc/toggle_mode(mob/user) - switch(mode) - if(SINGLE) - mode = VERTICAL - if(VERTICAL) - mode = HORIZONTAL - if(HORIZONTAL) - mode = SINGLE - - to_chat(user, "[src] is now in [mode] mode.") - -/obj/item/grenade/barrier/prime() - new /obj/structure/barricade/security(get_turf(loc)) - switch(mode) - if(VERTICAL) - var/target_turf = get_step(src, NORTH) - if(!(is_blocked_turf(target_turf))) - new /obj/structure/barricade/security(target_turf) - - var/target_turf2 = get_step(src, SOUTH) - if(!(is_blocked_turf(target_turf2))) - new /obj/structure/barricade/security(target_turf2) - if(HORIZONTAL) - var/target_turf = get_step(src, EAST) - if(!(is_blocked_turf(target_turf))) - new /obj/structure/barricade/security(target_turf) - - var/target_turf2 = get_step(src, WEST) - if(!(is_blocked_turf(target_turf2))) - new /obj/structure/barricade/security(target_turf2) - qdel(src) - -/obj/item/grenade/barrier/ui_action_click(mob/user) - toggle_mode(user) - - -/obj/structure/barricade/mime - name = "floor" - desc = "Is... this a floor?" - icon = 'icons/effects/water.dmi' - icon_state = "wet_floor_static" - stacktype = /obj/item/stack/sheet/mineral/tranquillite - -/obj/structure/barricade/mime/mrcd - stacktype = null - -/obj/structure/barricade/dropwall - name = "dropwall" - desc = "A temporary deployable energy shield powered by a generator. Breaking the generator will destroy all the shields connected to it." - icon = 'icons/obj/dropwall.dmi' - icon_state = "dropwall_dead" //sprite chosen in init - armor = list(MELEE = 0, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 10, RAD = 100, FIRE = 10, ACID = 0) // Copied from the security barrier, but no melee armor - density = FALSE - directional_blockage = TRUE - proj_pass_rate = 100 //don't worry about it, covered by directional blockage. - stacktype = null - /// This variable is used to tell the shield to ping it's owner when it is broke. - var/core_shield = FALSE - /// This variable is to tell the shield what it's source is. - var/obj/structure/dropwall_generator/source = null - explosion_block = 8 //should be enough for a potasium water nade that isn't a maxcap. If you stand next to a maxcap with this however, it will end poorly - -/obj/structure/barricade/dropwall/Initialize(mapload, owner, core, dir_1, dir_2) - . = ..() - source = owner - core_shield = core - directional_list += dir_1 - directional_list += dir_2 - if(dir_2) - icon_state = "[dir2text(dir_1)][dir2text(dir_1 + dir_2)]" - else - icon_state = "[dir2text(dir_1)]" - -/obj/structure/barricade/dropwall/Destroy() - if(core_shield) - source.protected = FALSE - source = null - return ..() - -/obj/structure/barricade/dropwall/emp_act(severity) - ..() - take_damage(40 / severity, BRUTE) //chances are the EMP will also hit the generator, we don't want it to double up too heavily - -/obj/structure/barricade/dropwall/bullet_act(obj/item/projectile/P) - if(P.shield_buster) - qdel(src) - else - return ..() - -/obj/item/grenade/barrier/dropwall - name = "dropwall shield generator" - desc = "This generator designed by Shellguard Munitions's spartan division is used to deploy a temporary cover that blocks projectiles and explosions from a direction, while allowing projectiles to pass freely from behind." - actions_types = list(/datum/action/item_action/toggle_barrier_spread) - icon = 'icons/obj/dropwall.dmi' - icon_state = "dropwall" - item_state = "grenade" - mode = AUTO - var/generator_type = /obj/structure/dropwall_generator - var/uptime = DROPWALL_UPTIME - /// If this is true we do not arm again, due to the sleep - var/deployed = FALSE - /// Mob who armed it. Needed for the get_dir proc - var/armer - -/obj/item/grenade/barrier/dropwall/toggle_mode(mob/user) - switch(mode) - if(AUTO) - mode = NORTH - if(NORTH) - mode = EAST - if(EAST) - mode = SOUTH - if(SOUTH) - mode = WEST - if(WEST) - mode = AUTO - - to_chat(user, "[src] is now in [mode == AUTO ? mode : dir2text(mode)] mode.") - -/obj/item/grenade/barrier/dropwall/attack_self__legacy__attackchain(mob/user) - . = ..() - armer = user - - -/obj/item/grenade/barrier/dropwall/end_throw() - if(active) - addtimer(CALLBACK(src, PROC_REF(prime)), 1) //Wait for the throw to fully end - -/obj/item/grenade/barrier/dropwall/prime() - if(deployed) - return - if(mode == AUTO) - mode = angle2dir_cardinal(get_angle(armer, get_turf(src))) - new generator_type(get_turf(loc), mode, uptime) - deployed = TRUE - armer = null - qdel(src) - -/obj/structure/dropwall_generator - name = "deployed dropwall shield generator" - desc = "This generator designed by Shellguard Munitions's spartan division is used to deploy a temporary cover that blocks projectiles and explosions from a direction, while allowing projectiles to pass freely from behind." - icon = 'icons/obj/dropwall.dmi' - icon_state = "dropwall_deployed" - max_integrity = 25 // 2 shots - var/list/connected_shields = list() - /// This variable is used to prevent damage to it's core shield when it is up. - var/protected = FALSE - ///The core shield that protects the generator - var/obj/structure/barricade/dropwall/core_shield = null - /// The type of dropwall - var/barricade_type = /obj/structure/barricade/dropwall - -/obj/structure/dropwall_generator/Initialize(mapload, direction, uptime) - . = ..() - if(direction) - deploy(direction, uptime) - -/obj/structure/dropwall_generator/Destroy() - QDEL_LIST_CONTENTS(connected_shields) - core_shield = null - return ..() - -/obj/structure/dropwall_generator/proc/deploy(direction, uptime) - anchored = TRUE - protected = TRUE - addtimer(CALLBACK(src, PROC_REF(power_out)), uptime) - timer_overlay_proc(1) - - connected_shields += new barricade_type(get_turf(loc), src, TRUE, direction) - core_shield = connected_shields[1] - - var/dir_left = turn(direction, -90) - var/dir_right = turn(direction, 90) - var/target_turf = get_step(src, dir_left) - if(!is_blocked_turf(target_turf)) - connected_shields += new barricade_type(target_turf, src, FALSE, direction, dir_left) - - var/target_turf2 = get_step(src, dir_right) - if(!is_blocked_turf(target_turf2)) - connected_shields += new barricade_type(target_turf2, src, FALSE, direction, dir_right) - - -/obj/structure/dropwall_generator/attacked_by__legacy__attackchain(obj/item/I, mob/living/user) //No, you can not just go up to the generator and whack it. Central shield needs to go down first. - if(protected) - visible_message("[src]'s shield absorbs the blow!") - core_shield.take_damage(I.force, I.damtype, MELEE, TRUE) - else - return ..() - -/obj/structure/dropwall_generator/bullet_act(obj/item/projectile/P) - if(!protected) - return ..() - else - visible_message("[src]'s shield absorbs the blow!") - core_shield.take_damage(P.damage, P.damage_type, P.flag) - -/obj/structure/dropwall_generator/emp_act(severity) - ..() - if(protected) - for(var/obj/structure/barricade/dropwall/O in connected_shields) - O.emp_act(severity) - else - qdel(src) - -/obj/structure/dropwall_generator/ex_act(severity) - if(protected && severity > EXPLODE_DEVASTATE) //We would throw the explosion at the shield, but it is already getting hit - return - qdel(src) - -/obj/structure/dropwall_generator/proc/power_out() - visible_message("[src] runs out of power, causing its shields to fail!") - new /obj/item/used_dropwall(get_turf(src)) - qdel(src) - -/obj/structure/dropwall_generator/proc/timer_overlay_proc(loops) // This proc will make the timer on the generator tick down like a clock, over 12 equally sized portions (12 times over 60 seconds, every 5 seconds by default) - add_overlay("[loops]") - if(loops != 1) - cut_overlay("[(loops - 1)]") - if(loops < 12) - addtimer(CALLBACK(src, PROC_REF(timer_overlay_proc), loops + 1), DROPWALL_UPTIME / 12) - - -/obj/item/used_dropwall - name = "broken dropwall generator" - desc = "This dropwall has ran out of charge, but some materials could possibly be reclaimed." - icon = 'icons/obj/dropwall.dmi' - icon_state = "dropwall_dead" - item_state = "grenade" - materials = list(MAT_METAL = 500, MAT_GLASS = 300) //plasma burned up for power or something, plus not that much to reclaim - -/obj/item/storage/box/syndie_kit/dropwall - name = "dropwall generator box" - -/obj/item/storage/box/syndie_kit/dropwall/populate_contents() - for(var/I in 1 to 5) - new /obj/item/grenade/barrier/dropwall(src) - -/obj/item/grenade/barrier/dropwall/firewall - name = "firewall shield generator" - generator_type = /obj/structure/dropwall_generator/firewall - -/obj/structure/dropwall_generator/firewall - name = "deployed firewall shield generator" - barricade_type = /obj/structure/barricade/dropwall/firewall - -/obj/structure/barricade/dropwall/firewall - -/obj/structure/barricade/dropwall/firewall/Initialize(mapload, owner, core, dir_1, dir_2) - . = ..() - var/target_matrix = list( - 2, 0, 0, 0, - 0, 1, 0, 0, - 2, 0, 0, 0, - 0, 0, 0, 1 - ) - color = target_matrix - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/structure/barricade/dropwall/firewall/proc/on_atom_entered(datum/source, atom/movable/entered) - if(!isprojectile(entered)) - return - var/obj/item/projectile/P = entered - P.immolate ++ - -/obj/item/grenade/turret - name = "Pop-Up Turret grenade" - desc = "Inflates into a Pop-Up turret, shoots everyone on sight who wasn't the primer." - icon = 'icons/obj/grenade.dmi' - icon_state = "wallbang" - item_state = "flashbang" - var/owner_uid - -/obj/item/grenade/turret/attack_self__legacy__attackchain(mob/user) - owner_uid = user.UID() - return ..() - -/obj/item/grenade/turret/prime() - var/obj/machinery/porta_turret/inflatable_turret/turret = new(get_turf(loc)) - turret.owner_uid = owner_uid - qdel(src) - -/obj/structure/barricade/foam - name = "foam blockage" - desc = "This foam blocks the airlock from being opened." - icon = 'icons/obj/foam_blobs.dmi' - icon_state = "foamed_1" - layer = DOOR_HELPER_LAYER - // The integrity goes up with 25 per level, with an extra 25 when going from 4 to 5 - obj_integrity = 25 - max_integrity = 25 - /// What level is the foam at? - var/foam_level = 1 - -/obj/structure/barricade/foam/Destroy() - for(var/obj/machinery/door/airlock in loc.contents) - airlock.foam_level = 0 - return ..() - -/obj/structure/barricade/foam/examine(mob/user) - . = ..() - . += "It would need [(5 - foam_level)] more blobs of foam to fully block the airlock." - -/obj/structure/barricade/foam/CanPass(atom/movable/mover, border_dir) - return istype(mover, /obj/item/projectile/c_foam) // Only c_foam blobs hit the airlock underneat/pass through the foam. The rest is hitting the barricade - -/obj/structure/barricade/foam/welder_act(mob/user, obj/item/I) - return FALSE - -#undef SINGLE -#undef VERTICAL -#undef HORIZONTAL - -#undef METAL -#undef WOOD -#undef SAND - - -#undef DROPWALL_UPTIME - -#undef AUTO diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm deleted file mode 100644 index 044482c6d8d94..0000000000000 --- a/code/game/machinery/doors/airlock_electronics.dm +++ /dev/null @@ -1,121 +0,0 @@ -/obj/item/airlock_electronics - name = "airlock electronics" - icon = 'icons/obj/doors/door_assembly.dmi' - icon_state = "door_electronics" - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL = 100, MAT_GLASS = 100) - origin_tech = "engineering=2;programming=1" - req_access = list(ACCESS_ENGINE) - toolspeed = 1 - usesound = 'sound/items/deconstruct.ogg' - /// List of accesses currently set - var/list/selected_accesses = list() - /// Is the door access using req_one_access (TRUE) or req_access (FALSE) - var/one_access = FALSE - /// An associative list containing all station accesses. Includes their name and access number. - var/static/list/door_accesses_list = list() - /// Maximum brain damage a mob can have until it can't use the electronics - var/const/max_brain_damage = 60 - /// Which direction has unrestricted access to the airlock (e.g. medbay doors from the inside) - var/unres_access_from = null - /// Is this electronic installed in a door? - var/is_installed = FALSE - - new_attack_chain = TRUE - -/obj/item/airlock_electronics/Initialize(mapload) - . = ..() - if(!length(door_accesses_list)) - for(var/access in get_all_accesses()) - door_accesses_list += list(list( - "name" = get_access_desc(access), - "id" = access)) - -/obj/item/airlock_electronics/activate_self(mob/user) - if(..() || (!ishuman(user) && !isrobot(user))) - return - - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.getBrainLoss() >= max_brain_damage) - to_chat(user, "You forget how to use [src].") - return - ui_interact(user) - -// tgui\packages\tgui\interfaces\AirlockElectronics.js -/obj/item/airlock_electronics/ui_state(mob/user) - return GLOB.inventory_state - -/obj/item/airlock_electronics/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "AirlockElectronics", name) - ui.open() - -/obj/item/airlock_electronics/ui_data(mob/user) - var/list/data = list() - data["selected_accesses"] = selected_accesses - data["one_access"] = one_access - data["unrestricted_dir"] = unres_access_from - return data - -/obj/item/airlock_electronics/ui_static_data(mob/user) - var/list/data = list() - data["regions"] = get_accesslist_static_data(REGION_GENERAL, REGION_COMMAND) - data["door_access_list"] = door_accesses_list - return data - -/obj/item/airlock_electronics/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - if(..()) - return - - . = TRUE - // Mostly taken from the RCD code - switch(action) - if("unrestricted_access") - var/direction = text2num(params["unres_dir"]) - unres_access_from ^= direction - - if("set_one_access") - one_access = params["access"] == "one" ? TRUE : FALSE - - if("set") - var/access = text2num(params["access"]) - if(isnull(access)) - return FALSE - if(access in selected_accesses) - selected_accesses -= access - else - selected_accesses |= access - - if("grant_region") - var/region = text2num(params["region"]) - if(isnull(region) || region < REGION_GENERAL || region > REGION_COMMAND) - return FALSE - selected_accesses |= get_region_accesses(region) - - if("deny_region") - var/region = text2num(params["region"]) - if(isnull(region) || region < REGION_GENERAL || region > REGION_COMMAND) - return FALSE - selected_accesses -= get_region_accesses(region) - - if("grant_all") - selected_accesses = get_all_accesses() - - if("clear_all") - selected_accesses = list() - -/obj/item/airlock_electronics/destroyed - name = "burned-out airlock electronics" - icon_state = "door_electronics_smoked" - -/obj/item/airlock_electronics/destroyed/Initialize(mapload) - . = ..() - RegisterSignal(src, COMSIG_ACTIVATE_SELF, TYPE_PROC_REF(/datum, signal_cancel_activate_self)) - -/obj/item/airlock_electronics/destroyed/decompile_act(obj/item/matter_decompiler/C, mob/user) - C.stored_comms["metal"] += 1 - C.stored_comms["glass"] += 1 - qdel(src) - return TRUE diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm deleted file mode 100644 index fbb7298600cb6..0000000000000 --- a/code/game/machinery/flasher.dm +++ /dev/null @@ -1,173 +0,0 @@ -// It is a gizmo that flashes a small area - -/obj/machinery/flasher - name = "Mounted flash" - desc = "A wall-mounted flashbulb device." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "mflash1" - max_integrity = 250 - integrity_failure = 100 - damage_deflection = 10 - var/id = null - var/range = 2 //this is roughly the size of brig cell - var/disable = FALSE - var/last_flash = 0 //Don't want it getting spammed like regular flashes - var/strength = 10 SECONDS //How weakened targets are when flashed. - var/base_state = "mflash" - anchored = TRUE - var/datum/proximity_monitor/proximity_monitor - -/obj/machinery/flasher/Initialize(mapload) - . = ..() - update_icon() - -/// Portable version of the flasher. Only flashes when anchored -/obj/machinery/flasher/portable - name = "portable flasher" - desc = "A portable flashing device. Wrench to activate and deactivate. Cannot detect slow movements." - icon_state = "pflash1" - strength = 4 - anchored = FALSE - base_state = "pflash" - density = TRUE - -/obj/machinery/flasher/portable/Initialize(mapload) - . = ..() - proximity_monitor = new(src, range) - -/obj/machinery/flasher/power_change() - if(!..()) - return - if(stat & NOPOWER) - set_light(0) - else - set_light(1, LIGHTING_MINIMUM_POWER) - update_icon() - -/obj/machinery/flasher/update_icon_state() - . = ..() - if((stat & NOPOWER) || !anchored) - icon_state = "[base_state]1-p" - else - icon_state = "[base_state]1" - -/obj/machinery/flasher/update_overlays() - . = ..() - underlays.Cut() - cut_overlays() - if(stat & NOPOWER) - return - - if(anchored) - . += "[base_state]-s" - underlays += emissive_appearance(icon, "[base_state]_lightmask") - - -//Let the AI trigger them directly. -/obj/machinery/flasher/attack_ai(mob/user) - if(anchored) - return flash() - -/obj/machinery/flasher/attack_ghost(mob/user) - if(anchored && user.can_advanced_admin_interact()) - return flash() - -/obj/machinery/flasher/proc/flash() - if(!has_power()) - return - - if((disable) || (last_flash && world.time < last_flash + 150)) - return - - playsound(loc, 'sound/weapons/flash.ogg', 100, 1) - flick("[base_state]_flash", src) - set_light(2, 1, COLOR_WHITE) - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, set_light), 0), 2) - last_flash = world.time - use_power(1000) - - for(var/mob/living/L in viewers(src, null)) - if(get_dist(src, L) > range) - continue - - if(L.flash_eyes(affect_silicon = 1)) - L.Weaken(strength) - -/obj/machinery/flasher/emp_act(severity) - if(stat & (BROKEN|NOPOWER)) - ..(severity) - return - if(prob(75/severity)) - flash() - ..(severity) - -/obj/machinery/flasher/portable/HasProximity(atom/movable/AM) - if((disable) || (last_flash && world.time < last_flash + 150)) - return - - if(iscarbon(AM)) - var/mob/living/carbon/M = AM - if((M.m_intent != MOVE_INTENT_WALK) && (anchored)) - flash() - -//Don't want to render prison breaks impossible -/obj/machinery/flasher/portable/wirecutter_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - disable = !disable - if(disable) - user.visible_message("[user] has disconnected [src]'s flashbulb!", "You disconnect [src]'s flashbulb!") - if(!disable) - user.visible_message("[user] has connected [src]'s flashbulb!", "You connect [src]'s flashbulb!") - -/obj/machinery/flasher/portable/wrench_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - anchored = !anchored - if(anchored) - WRENCH_ANCHOR_MESSAGE - else - WRENCH_UNANCHOR_MESSAGE - update_icon() - -// Flasher button -/obj/machinery/flasher_button - name = "flasher button" - desc = "A remote control switch for a mounted flasher." - icon = 'icons/obj/objects.dmi' - icon_state = "launcherbtt" - var/id = null - var/active = FALSE - anchored = TRUE - idle_power_consumption = 2 - active_power_consumption = 4 - -/obj/machinery/flasher_button/attack_ai(mob/user as mob) - return attack_hand(user) - -/obj/machinery/flasher_button/attack_ghost(mob/user) - if(user.can_advanced_admin_interact()) - return attack_hand(user) - -/obj/machinery/flasher_button/attack_hand(mob/user as mob) - if(stat & (NOPOWER|BROKEN)) - return - if(active) - return - - use_power(5) - - active = TRUE - icon_state = "launcheract" - - for(var/obj/machinery/flasher/M in GLOB.machines) - if(M.id == id) - spawn() - M.flash() - - sleep(50) - - icon_state = "launcherbtt" - active = FALSE diff --git a/code/game/machinery/floor_igniter.dm b/code/game/machinery/floor_igniter.dm deleted file mode 100644 index 7659327ca1406..0000000000000 --- a/code/game/machinery/floor_igniter.dm +++ /dev/null @@ -1,145 +0,0 @@ -/obj/machinery/igniter - name = "igniter" - desc = "It's useful for igniting plasma." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "igniter1" - plane = FLOOR_PLANE - max_integrity = 300 - armor = list(melee = 50, bullet = 30, laser = 70, energy = 50, bomb = 20, rad = 0, fire = 100, acid = 70) - resistance_flags = FIRE_PROOF - anchored = TRUE - idle_power_consumption = 2 - active_power_consumption = 4 - /// ID to hook buttons into - var/id = null - /// Are we on? - var/on = FALSE - -/obj/machinery/igniter/on - on = TRUE - -/obj/machinery/igniter/attack_ai(mob/user) - attack_hand(user) - -/obj/machinery/igniter/attack_hand(mob/user as mob) - if(..()) - return - - add_fingerprint(user) - - use_power(50) - on = !on - update_icon() - - if(on) - set_light(1, 1, "#ff821c") - else - set_light(0) - - -/obj/machinery/igniter/update_icon_state() - . = ..() - - if(stat & (NOPOWER|BROKEN)) - icon_state = "igniter0" - return - - icon_state = "igniter[on]" - -/obj/machinery/igniter/update_overlays() - . = ..() - underlays.Cut() - - if(on) - underlays += emissive_appearance(icon, "igniter_lightmask") - -/obj/machinery/igniter/process() //ugh why is this even in process()? // AA 2022-08-02 - I guess it cant go anywhere else? - if(on && !(stat & NOPOWER)) - var/turf/location = get_turf(src) - if(isturf(location)) - location.hotspot_expose(1000, 1) - return TRUE - -/obj/machinery/igniter/Initialize(mapload) - . = ..() - update_icon() - -/obj/machinery/igniter/power_change() - if(!..()) - return - if(stat & NOPOWER) - on = FALSE - update_icon() - -// Wall mounted remote-control igniter. - -/obj/machinery/sparker - name = "Mounted igniter" - desc = "A wall-mounted ignition device." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "migniter" - resistance_flags = FIRE_PROOF - var/id = null - var/disable = FALSE - var/last_spark = FALSE - var/base_state = "migniter" - anchored = TRUE - -/obj/machinery/sparker/update_icon_state() - if(stat & NOPOWER) - icon_state = "[base_state]-p" - else - icon_state = "[base_state]" - -/obj/machinery/sparker/power_change() - if(!..()) - return - update_icon(UPDATE_ICON_STATE) - -/obj/machinery/sparker/screwdriver_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - - disable = !disable - - if(disable) - user.visible_message("[user] has disabled [src]!", "You disable the connection to [src].") - icon_state = "[base_state]-d" - else - user.visible_message("[user] has reconnected [src]!", "You fix the connection to [src].") - if(has_power()) - icon_state = "[base_state]" - else - icon_state = "[base_state]-p" - -/obj/machinery/sparker/attack_ai() - if(anchored) - return spark() - - -/obj/machinery/sparker/proc/spark() - if(!has_power()) - return - - if(disable || (last_spark && world.time < last_spark + 5 SECONDS)) - return - - flick("[base_state]-spark", src) - do_sparks(2, 1, src) - last_spark = world.time - use_power(1000) - - var/turf/location = get_turf(src) - if(isturf(location)) - location.hotspot_expose(1000, 500) - - return TRUE - -/obj/machinery/sparker/emp_act(severity) - if(stat & (BROKEN|NOPOWER)) - ..(severity) - return - - spark() - ..(severity) diff --git a/code/game/machinery/pipe/pipe_construction.dm b/code/game/machinery/pipe/pipe_construction.dm deleted file mode 100644 index c3589f5eb5c8a..0000000000000 --- a/code/game/machinery/pipe/pipe_construction.dm +++ /dev/null @@ -1,590 +0,0 @@ - -/obj/item/pipe - name = "pipe" - var/pipe_type = 0 - var/pipename - var/list/connect_types = list(CONNECT_TYPE_NORMAL) //1=regular, 2=supply, 3=scrubber - force = 7 - icon = 'icons/obj/pipe-item.dmi' - icon_state = "simple" - item_state = "buildpipe" - w_class = WEIGHT_CLASS_NORMAL - level = 2 - var/flipped = FALSE - -/obj/item/pipe/Initialize(mapload, new_pipe_type, new_dir, obj/machinery/atmospherics/make_from) - . = ..() - if(make_from) - dir = make_from.dir - pipename = make_from.name - color = make_from.pipe_color - var/is_bent - - if(make_from.initialize_directions in list(NORTH|SOUTH, WEST|EAST)) - is_bent = FALSE - else - is_bent = TRUE - - - if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction)) - pipe_type = PIPE_JUNCTION - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/heat_exchanging)) - pipe_type = PIPE_HE_STRAIGHT + is_bent - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/simple/hidden/supply)) - pipe_type = PIPE_SUPPLY_STRAIGHT + is_bent - connect_types = list(CONNECT_TYPE_SUPPLY) - color = PIPE_COLOR_BLUE - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/visible/scrubbers) || istype(make_from, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers)) - pipe_type = PIPE_SCRUBBERS_STRAIGHT + is_bent - connect_types = list(CONNECT_TYPE_SCRUBBER) - color = PIPE_COLOR_RED - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/visible/universal) || istype(make_from, /obj/machinery/atmospherics/pipe/simple/hidden/universal)) - pipe_type = PIPE_UNIVERSAL - connect_types = list(CONNECT_TYPE_NORMAL, CONNECT_TYPE_SUPPLY, CONNECT_TYPE_SCRUBBER) - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple)) - pipe_type = PIPE_SIMPLE_STRAIGHT + is_bent - - else if(istype(make_from, /obj/machinery/atmospherics/unary/portables_connector)) - pipe_type = PIPE_CONNECTOR - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold/hidden/supply)) - pipe_type = PIPE_SUPPLY_MANIFOLD - connect_types = list(CONNECT_TYPE_SUPPLY) - color = PIPE_COLOR_BLUE - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold/visible/scrubbers) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers)) - pipe_type = PIPE_SCRUBBERS_MANIFOLD - connect_types = list(CONNECT_TYPE_SCRUBBER) - color = PIPE_COLOR_RED - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold)) - pipe_type = PIPE_MANIFOLD - - else if(istype(make_from, /obj/machinery/atmospherics/unary/vent_pump)) - pipe_type = PIPE_UVENT - - else if(istype(make_from, /obj/machinery/atmospherics/binary/valve/digital)) - pipe_type = PIPE_DVALVE - - else if(istype(make_from, /obj/machinery/atmospherics/binary/valve)) - pipe_type = PIPE_MVALVE - - else if(istype(make_from, /obj/machinery/atmospherics/binary/pump)) - pipe_type = PIPE_PUMP - - else if(istype(make_from, /obj/machinery/atmospherics/trinary/filter)) - pipe_type = PIPE_GAS_FILTER - - else if(istype(make_from, /obj/machinery/atmospherics/trinary/mixer)) - pipe_type = PIPE_GAS_MIXER - - else if(istype(make_from, /obj/machinery/atmospherics/unary/vent_scrubber)) - pipe_type = PIPE_SCRUBBER - - else if(istype(make_from, /obj/machinery/atmospherics/binary/passive_gate)) - pipe_type = PIPE_PASSIVE_GATE - - else if(istype(make_from, /obj/machinery/atmospherics/binary/volume_pump)) - pipe_type = PIPE_VOLUME_PUMP - - else if(istype(make_from, /obj/machinery/atmospherics/unary/heat_exchanger)) - pipe_type = PIPE_HEAT_EXCHANGE - - else if(istype(make_from, /obj/machinery/atmospherics/trinary/tvalve/digital)) - pipe_type = PIPE_DTVALVE - - else if(istype(make_from, /obj/machinery/atmospherics/trinary/tvalve)) - pipe_type = PIPE_TVALVE - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply)) - pipe_type = PIPE_SUPPLY_MANIFOLD4W - connect_types = list(CONNECT_TYPE_SUPPLY) - color = PIPE_COLOR_BLUE - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers)) - pipe_type = PIPE_SCRUBBERS_MANIFOLD4W - connect_types = list(CONNECT_TYPE_SCRUBBER) - color = PIPE_COLOR_RED - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w)) - pipe_type = PIPE_MANIFOLD4W - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/cap/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/cap/hidden/supply)) - pipe_type = PIPE_SUPPLY_CAP - connect_types = list(CONNECT_TYPE_SUPPLY) - color = PIPE_COLOR_BLUE - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/cap/visible/scrubbers) || istype(make_from, /obj/machinery/atmospherics/pipe/cap/hidden/scrubbers)) - pipe_type = PIPE_SCRUBBERS_CAP - connect_types = list(CONNECT_TYPE_SCRUBBER) - color = PIPE_COLOR_RED - - else if(istype(make_from, /obj/machinery/atmospherics/pipe/cap)) - pipe_type = PIPE_CAP - - else if(istype(make_from, /obj/machinery/atmospherics/unary/outlet_injector)) - pipe_type = PIPE_INJECTOR - - else if(istype(make_from, /obj/machinery/atmospherics/unary/passive_vent)) - pipe_type = PIPE_PASV_VENT - - else if(istype(make_from, /obj/machinery/atmospherics/binary/circulator)) - pipe_type = PIPE_CIRCULATOR - - var/obj/machinery/atmospherics/trinary/triP = make_from - if(istype(triP) && triP.flipped) - flipped = TRUE - - var/obj/machinery/atmospherics/binary/circulator/circP = make_from - if(istype(circP) && circP.side == CIRCULATOR_SIDE_RIGHT) - flipped = TRUE - - else - pipe_type = new_pipe_type - dir = new_dir - if(pipe_type == PIPE_SUPPLY_STRAIGHT || pipe_type == PIPE_SUPPLY_BENT || pipe_type == PIPE_SUPPLY_MANIFOLD || pipe_type == PIPE_SUPPLY_MANIFOLD4W || pipe_type == PIPE_SUPPLY_CAP) - connect_types = list(CONNECT_TYPE_SUPPLY) - color = PIPE_COLOR_BLUE - else if(pipe_type == PIPE_SCRUBBERS_STRAIGHT || pipe_type == PIPE_SCRUBBERS_BENT || pipe_type == PIPE_SCRUBBERS_MANIFOLD || pipe_type == PIPE_SCRUBBERS_MANIFOLD4W || pipe_type == PIPE_SCRUBBERS_CAP) - connect_types = list(CONNECT_TYPE_SCRUBBER) - color = PIPE_COLOR_RED - else if(pipe_type == PIPE_UNIVERSAL) - connect_types = list(CONNECT_TYPE_NORMAL, CONNECT_TYPE_SUPPLY, CONNECT_TYPE_SCRUBBER) - - update(make_from) - scatter_atom() - -//update the name and icon of the pipe item depending on the type - -/obj/item/pipe/rpd_act(mob/user, obj/item/rpd/our_rpd) - . = TRUE - if(our_rpd.mode == RPD_ROTATE_MODE) - rotate() - - else if(our_rpd.mode == RPD_FLIP_MODE) - flip() - - else if(our_rpd.mode == RPD_DELETE_MODE) - if(pipe_type == PIPE_CIRCULATOR) //Skip TEG heat circulators, they aren't really pipes - return ..() - - our_rpd.delete_single_pipe(user, src) - - else - return ..() - -/obj/item/pipe/examine(mob/user) - . = ..() - . += "Alt-click it to rotate, Alt-Shift-click it to flip!" - -/obj/item/pipe/proc/update(obj/machinery/atmospherics/make_from) - name = "[get_pipe_name(pipe_type, PIPETYPE_ATMOS)] fitting" - icon_state = get_pipe_icon(pipe_type) - - var/obj/machinery/atmospherics/trinary/triP = make_from - if(istype(triP) && triP.flipped) - icon_state = "m_[icon_state]" - - var/obj/machinery/atmospherics/binary/circulator/circP = make_from - if(istype(circP) && circP.side == CIRCULATOR_SIDE_RIGHT) - icon_state = "m_[icon_state]" - - if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/heat_exchanging)) - resistance_flags |= FIRE_PROOF | LAVA_PROOF - -// called by turf to know if should treat as bent or not on placement -/obj/item/pipe/proc/is_bent_pipe() - return pipe_type in list( \ - PIPE_SIMPLE_BENT, \ - PIPE_HE_BENT, \ - PIPE_SUPPLY_BENT, \ - PIPE_SCRUBBERS_BENT) - -// rotate the pipe item clockwise - -/obj/item/pipe/proc/rotate() - if(pipe_type == PIPE_CIRCULATOR) - flip() - return - - dir = turn(dir, -90) - - fixdir() - -/obj/item/pipe/proc/flip() - if(pipe_type in list(PIPE_GAS_FILTER, PIPE_GAS_MIXER, PIPE_TVALVE, PIPE_DTVALVE, PIPE_CIRCULATOR)) - if(flipped) - icon_state = copytext(icon_state,3) - else - icon_state = "m_[icon_state]" - flipped = !flipped - return - - dir = turn(dir, -180) - - fixdir() - -/obj/item/pipe/Move() - . = ..() - if(is_bent_pipe() && (dir in GLOB.cardinal)) - dir = dir | turn(dir, 90) - - else if(pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_SUPPLY_STRAIGHT, PIPE_SCRUBBERS_STRAIGHT, PIPE_UNIVERSAL, PIPE_HE_STRAIGHT, PIPE_MVALVE, PIPE_DVALVE)) - if(dir == 2) - dir = 1 - - else if(dir == 8) - dir = 4 - -// returns all pipe's endpoints - -/obj/item/pipe/proc/get_pipe_dir() - . = 0 - - if(!dir) - return - - var/direct = dir - if(flipped) - direct = turn(dir, 45) - - var/flip = turn(direct, 180) - var/cw = turn(direct, -90) - var/acw = turn(direct, 90) - - switch(pipe_type) - if(PIPE_SIMPLE_STRAIGHT, PIPE_HE_STRAIGHT, PIPE_JUNCTION,\ - PIPE_PUMP, PIPE_VOLUME_PUMP, PIPE_PASSIVE_GATE, PIPE_MVALVE, PIPE_DVALVE, PIPE_DP_VENT, - PIPE_SUPPLY_STRAIGHT, PIPE_SCRUBBERS_STRAIGHT, PIPE_UNIVERSAL) - return dir|flip - - if(PIPE_SIMPLE_BENT, PIPE_HE_BENT, PIPE_SUPPLY_BENT, PIPE_SCRUBBERS_BENT) - return dir //dir|acw - - if(PIPE_CONNECTOR, PIPE_HEAT_EXCHANGE) - return dir|flip - - if(PIPE_UVENT, PIPE_PASV_VENT, PIPE_SCRUBBER, PIPE_INJECTOR) - return dir - - if(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W) - return dir|flip|cw|acw - - if(PIPE_MANIFOLD, PIPE_SUPPLY_MANIFOLD, PIPE_SCRUBBERS_MANIFOLD) - return flip|cw|acw - - if(PIPE_GAS_FILTER, PIPE_GAS_MIXER, PIPE_TVALVE, PIPE_DTVALVE) - if(!flipped) - return dir|flip|cw - - return flip|cw|acw - - if(PIPE_CAP, PIPE_SUPPLY_CAP, PIPE_SCRUBBERS_CAP) - return dir|flip - -/obj/item/pipe/proc/get_pdir() //endpoints for regular pipes - var/flip = turn(dir, 180) - - if(!(pipe_type in list(PIPE_HE_STRAIGHT, PIPE_HE_BENT, PIPE_JUNCTION))) - return get_pipe_dir() - - switch(pipe_type) - if(PIPE_HE_STRAIGHT,PIPE_HE_BENT) - return 0 - - if(PIPE_JUNCTION) - return flip - - return 0 - -// return the h_dir (heat-exchange pipes) from the type and the dir - -/obj/item/pipe/proc/get_hdir() //endpoints for h/e pipes - switch(pipe_type) - if(PIPE_HE_STRAIGHT) - return get_pipe_dir() - - if(PIPE_HE_BENT) - return get_pipe_dir() - - if(PIPE_JUNCTION) - return dir - - return 0 - -/obj/item/pipe/proc/unflip(direction) - if(!(direction in GLOB.cardinal)) - return turn(direction, 45) - - return direction - -//Helper to clean up dir -/obj/item/pipe/proc/fixdir() - if(pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_SUPPLY_STRAIGHT, PIPE_SCRUBBERS_STRAIGHT, PIPE_HE_STRAIGHT, PIPE_MVALVE, PIPE_DVALVE)) - if(dir == 2) - dir = 1 - - else if(dir == 8) - dir = 4 - - else if(pipe_type in list(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W)) - dir = 2 - -/obj/item/pipe/attack_self__legacy__attackchain(mob/user as mob) - return rotate() - -/obj/item/pipe/wrench_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - - if(!isturf(loc)) - return - - fixdir() - - var/pipe_dir = get_pipe_dir() - var/turf/T = get_turf(loc) - - for(var/obj/machinery/atmospherics/M in loc) - if((M.initialize_directions & pipe_dir) && M.check_connect_types_construction(M, src)) // matches at least one direction on either type of pipe - to_chat(user, "There is already a pipe of the same type at this location.") - return - - if(pipe_type in list(PIPE_SUPPLY_STRAIGHT, PIPE_SUPPLY_BENT, PIPE_SCRUBBERS_STRAIGHT, PIPE_SCRUBBERS_BENT, PIPE_HE_STRAIGHT, PIPE_HE_BENT, PIPE_SUPPLY_MANIFOLD, PIPE_SCRUBBERS_MANIFOLD, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_UVENT, PIPE_SUPPLY_CAP, PIPE_SCRUBBERS_CAP, PIPE_PASV_VENT, PIPE_DP_VENT, PIPE_PASSIVE_GATE)) - if(T.transparent_floor) //stops jank with transparent floors and pipes - to_chat(user, "You can only fix simple pipes and devices over glass floors!") - return - - switch(pipe_type) //What kind of heartless person thought of doing this? - if(PIPE_SIMPLE_STRAIGHT, PIPE_SIMPLE_BENT) - var/obj/machinery/atmospherics/pipe/simple/P = new(loc) - P.on_construction(dir, pipe_dir, color) - - if(PIPE_SUPPLY_STRAIGHT, PIPE_SUPPLY_BENT) - var/obj/machinery/atmospherics/pipe/simple/hidden/supply/P = new(loc) - P.on_construction(dir, pipe_dir, color) - - if(PIPE_SCRUBBERS_STRAIGHT, PIPE_SCRUBBERS_BENT) - var/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers/P = new(loc) - P.on_construction(dir, pipe_dir, color) - - if(PIPE_UNIVERSAL) - var/obj/machinery/atmospherics/pipe/simple/hidden/universal/P = new(loc) - P.on_construction(dir, pipe_dir, color) - - if(PIPE_HE_STRAIGHT, PIPE_HE_BENT) - var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/P = new (loc) - P.initialize_directions_he = pipe_dir - P.on_construction(dir, pipe_dir, color) - - if(PIPE_CONNECTOR) // connector - var/obj/machinery/atmospherics/unary/portables_connector/C = new(loc) - if(pipename) - C.name = pipename - C.on_construction(dir, pipe_dir, color) - - if(PIPE_MANIFOLD) //manifold - var/obj/machinery/atmospherics/pipe/manifold/M = new(loc) - M.on_construction(dir, pipe_dir, color) - - if(PIPE_SUPPLY_MANIFOLD) //manifold - var/obj/machinery/atmospherics/pipe/manifold/hidden/supply/M = new(loc) - M.on_construction(dir, pipe_dir, color) - - if(PIPE_SCRUBBERS_MANIFOLD) //manifold - var/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers/M = new(loc) - M.on_construction(dir, pipe_dir, color) - - if(PIPE_MANIFOLD4W) //4-way manifold - var/obj/machinery/atmospherics/pipe/manifold4w/M = new(loc) - M.on_construction(dir, pipe_dir, color) - - if(PIPE_SUPPLY_MANIFOLD4W) //4-way manifold - var/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply/M = new(loc) - M.on_construction(dir, pipe_dir, color) - - if(PIPE_SCRUBBERS_MANIFOLD4W) //4-way manifold - var/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers/M = new(loc) - M.on_construction(dir, pipe_dir, color) - - if(PIPE_JUNCTION) - var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/P = new (loc) - P.initialize_directions_he = get_hdir() - P.on_construction(dir, get_pdir(), color) - - if(PIPE_UVENT) //unary vent - var/obj/machinery/atmospherics/unary/vent_pump/V = new(loc) - V.on_construction(dir, pipe_dir, color) - - if(PIPE_MVALVE) //manual valve - var/obj/machinery/atmospherics/binary/valve/V = new(loc) - if(pipename) - V.name = pipename - V.on_construction(dir, get_pdir(), color) - - if(PIPE_DVALVE) - var/obj/machinery/atmospherics/binary/valve/digital/V = new(loc) - if(pipename) - V.name = pipename - V.on_construction(dir, get_pdir(), color) - - if(PIPE_PUMP) //gas pump - var/obj/machinery/atmospherics/binary/pump/P = new(loc) - P.on_construction(dir, pipe_dir, color) - - if(PIPE_GAS_FILTER, PIPE_GAS_MIXER, PIPE_TVALVE, PIPE_DTVALVE) - var/obj/machinery/atmospherics/trinary/P - switch(pipe_type) - if(PIPE_GAS_FILTER) - P = new /obj/machinery/atmospherics/trinary/filter(loc) - if(PIPE_GAS_MIXER) - P = new /obj/machinery/atmospherics/trinary/mixer(loc) - if(PIPE_TVALVE) - P = new /obj/machinery/atmospherics/trinary/tvalve(loc) - if(PIPE_DTVALVE) - P = new /obj/machinery/atmospherics/trinary/tvalve/digital(loc) - - P.flipped = flipped - - if(pipename) - P.name = pipename - - P.on_construction(unflip(dir), pipe_dir, color) - - if(PIPE_CIRCULATOR) //circulator - var/obj/machinery/atmospherics/binary/circulator/C = new(loc) - if(flipped) - C.side = CIRCULATOR_SIDE_RIGHT - - if(pipename) - C.name = pipename - - C.on_construction(C.dir, C.initialize_directions, color) - - if(PIPE_SCRUBBER) //scrubber - var/obj/machinery/atmospherics/unary/vent_scrubber/S = new(loc) - if(pipename) - S.name = pipename - - S.on_construction(dir, pipe_dir, color) - - if(PIPE_CAP) - var/obj/machinery/atmospherics/pipe/cap/C = new(loc) - C.on_construction(dir, pipe_dir, color) - - if(PIPE_SUPPLY_CAP) - var/obj/machinery/atmospherics/pipe/cap/hidden/supply/C = new(loc) - C.on_construction(dir, pipe_dir, color) - - if(PIPE_SCRUBBERS_CAP) - var/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers/C = new(loc) - C.on_construction(dir, pipe_dir, color) - - if(PIPE_PASSIVE_GATE) //passive gate - var/obj/machinery/atmospherics/binary/passive_gate/P = new(loc) - if(pipename) - P.name = pipename - - P.on_construction(dir, pipe_dir, color) - - if(PIPE_VOLUME_PUMP) //volume pump - var/obj/machinery/atmospherics/binary/volume_pump/P = new(loc) - if(pipename) - P.name = pipename - - P.on_construction(dir, pipe_dir, color) - - if(PIPE_HEAT_EXCHANGE) // heat exchanger - var/obj/machinery/atmospherics/unary/heat_exchanger/C = new(loc) - if(pipename) - C.name = pipename - - C.on_construction(dir, pipe_dir, color) - - if(PIPE_INJECTOR) // air injector - var/obj/machinery/atmospherics/unary/outlet_injector/P = new(loc) - if(pipename) - P.name = pipename - - P.on_construction(dir, pipe_dir, color) - - if(PIPE_PASV_VENT) - var/obj/machinery/atmospherics/unary/passive_vent/P = new(loc) - if(pipename) - P.name = pipename - - P.on_construction(dir, pipe_dir, color) - - user.visible_message( \ - "[user] fastens [src].", - "You fasten [src].", - "You hear a ratchet.") - qdel(src) // remove the pipe item - . |= RPD_TOOL_SUCCESS - -/obj/item/pipe_meter - name = "meter" - desc = "A meter that can be laid on pipes." - icon = 'icons/obj/pipe-item.dmi' - icon_state = "meter" - item_state = "buildpipe" - w_class = WEIGHT_CLASS_BULKY - -/obj/item/pipe_meter/wrench_act(mob/living/user, obj/item/I) - if(!locate(/obj/machinery/atmospherics/pipe, loc)) - to_chat(user, "You need to fasten it to a pipe.") - return TRUE - - new /obj/machinery/atmospherics/meter(loc) - I.play_tool_sound(src) - to_chat(user, "You have fastened the meter to the pipe.") - qdel(src) - return TRUE - -/obj/item/pipe_meter/rpd_act(mob/user, obj/item/rpd/our_rpd) - if(our_rpd.mode == RPD_DELETE_MODE) - our_rpd.delete_single_pipe(user, src) - return - - ..() - -/obj/item/pipe_gsensor - name = "gas sensor" - desc = "A sensor that can be hooked to a computer." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "gsensor0" - item_state = "buildpipe" - w_class = WEIGHT_CLASS_BULKY - -/obj/item/pipe_gsensor/wrench_act(mob/living/user, obj/item/I) - var/obj/machinery/atmospherics/air_sensor/AS = new /obj/machinery/atmospherics/air_sensor(loc) - AS.bolts = FALSE - I.play_tool_sound(src, 50) - to_chat(user, "You have fastened the gas sensor.") - qdel(src) - return TRUE - -/obj/item/pipe_gsensor/rpd_act(mob/user, obj/item/rpd/our_rpd) - if(our_rpd.mode == RPD_DELETE_MODE) - our_rpd.delete_single_pipe(user, src) - return - - ..() - -/obj/item/pipe/AltClick(mob/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) - return - - rotate() - -/obj/item/pipe/AltShiftClick(mob/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) - return - - flip() diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm deleted file mode 100644 index f6a7070cbfa2d..0000000000000 --- a/code/game/machinery/recycler.dm +++ /dev/null @@ -1,223 +0,0 @@ -#define SAFETY_COOLDOWN 100 -#define SOUND_COOLDOWN (0.5 SECONDS) - -/obj/machinery/recycler - name = "recycler" - desc = "A large crushing machine used to recycle small items inefficiently. There are lights on the side." - icon = 'icons/obj/recycling.dmi' - icon_state = "grinder-o0" - layer = MOB_LAYER+1 // Overhead - anchored = TRUE - density = TRUE - damage_deflection = 15 - var/emergency_mode = FALSE // Temporarily stops machine if it detects a mob - var/icon_name = "grinder-o" - var/blood = FALSE - var/eat_dir = WEST - var/amount_produced = 1 - var/crush_damage = 1000 - var/eat_victim_items = TRUE - var/item_recycle_sound = 'sound/machines/recycler.ogg' - /// For admin fun, var edit always_gib to TRUE (1) - var/always_gib = FALSE - /// The last time we played a consumption sound. - var/last_consumption_sound - -/obj/machinery/recycler/Initialize(mapload) - . = ..() - AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_PLASTIC, MAT_BLUESPACE), 0, TRUE, null, null, null, TRUE) - component_parts = list() - component_parts += new /obj/item/circuitboard/recycler(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - RefreshParts() - update_icon(UPDATE_ICON_STATE) - -/obj/machinery/recycler/RefreshParts() - var/amt_made = 0 - var/mat_mod = 0 - for(var/obj/item/stock_parts/matter_bin/B in component_parts) - mat_mod = 2 * B.rating - mat_mod *= 50000 - for(var/obj/item/stock_parts/manipulator/M in component_parts) - amt_made = 25 * M.rating //% of materials salvaged - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - materials.max_amount = mat_mod - amount_produced = min(100, amt_made) - -/obj/machinery/recycler/examine(mob/user) - . = ..() - . += "The power light is [(stat & NOPOWER) ? "off" : "on"]." - . += "The operation light is [emergency_mode ? "off. [src] has detected a forbidden object with its sensors, and has shut down temporarily." : "on. [src] is active."]" - . += "The safety sensor light is [emagged ? "off!" : "on."]" - . += "The recycler current accepts items from [dir2text(eat_dir)]." - -/obj/machinery/recycler/power_change() - if(!..()) - return - update_icon(UPDATE_ICON_STATE) - -/obj/machinery/recycler/crowbar_act(mob/user, obj/item/I) - if(default_deconstruction_crowbar(user, I)) - return TRUE - -/obj/machinery/recycler/screwdriver_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - panel_open = !panel_open - update_icon(UPDATE_OVERLAYS) - -/obj/machinery/recycler/update_overlays() - . = ..() - if(panel_open) - . += "grinder-oOpen" - -/obj/machinery/recycler/wrench_act(mob/user, obj/item/I) - if(default_unfasten_wrench(user, I, time = 6 SECONDS)) - return TRUE - - - -/obj/machinery/recycler/emag_act(mob/user) - if(!emagged) - emagged = TRUE - if(emergency_mode) - emergency_mode = FALSE - update_icon(UPDATE_ICON_STATE) - playsound(src, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - to_chat(user, "You use the cryptographic sequencer on [src].") - return TRUE - -/obj/machinery/recycler/update_icon_state() - var/is_powered = !(stat & (BROKEN|NOPOWER)) - if(emergency_mode) - is_powered = FALSE - icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end - -// This is purely for admin possession !FUN!. -/obj/machinery/recycler/Bump(atom/movable/AM) - ..() - if(AM) - Bumped(AM) - -/obj/machinery/recycler/Bumped(atom/movable/AM) - - if(stat & (BROKEN|NOPOWER)) - return - if(!anchored) - return - if(emergency_mode) - return - - var/move_dir = get_dir(loc, AM.loc) - if(move_dir == eat_dir) - eat(AM) - -/obj/machinery/recycler/proc/eat(atom/AM0, sound = 1) - var/list/to_eat = list(AM0) - if(isitem(AM0)) - to_eat += AM0.GetAllContents() - var/items_recycled = 0 - - for(var/i in to_eat) - var/atom/movable/AM = i - if(QDELETED(AM)) - continue - else if(isliving(AM)) - if(emagged) - crush_living(AM) - else - emergency_stop(AM) - else if(isitem(AM)) - recycle_item(AM) - items_recycled++ - else - playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0) - AM.forceMove(loc) - - if(items_recycled && sound && (last_consumption_sound + SOUND_COOLDOWN) < world.time) - playsound(loc, item_recycle_sound, 100, 0) - last_consumption_sound = world.time - -/obj/machinery/recycler/proc/recycle_item(obj/item/I) - I.forceMove(loc) - - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/material_amount = materials.get_item_material_amount(I) - if(!material_amount) - qdel(I) - return - materials.insert_item(I, multiplier = (amount_produced / 100)) - qdel(I) - materials.retrieve_all() - - -/obj/machinery/recycler/proc/emergency_stop(mob/living/L) - playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0) - emergency_mode = TRUE - update_icon(UPDATE_ICON_STATE) - L.loc = loc - addtimer(CALLBACK(src, PROC_REF(reboot)), SAFETY_COOLDOWN) - -/obj/machinery/recycler/proc/reboot() - playsound(loc, 'sound/machines/ping.ogg', 50, 0) - emergency_mode = FALSE - update_icon(UPDATE_ICON_STATE) - -/obj/machinery/recycler/proc/crush_living(mob/living/L) - - L.loc = loc - - if(issilicon(L)) - playsound(loc, 'sound/items/welder.ogg', 50, 1) - else - playsound(loc, 'sound/effects/splat.ogg', 50, 1) - - var/gib = TRUE - // By default, the emagged recycler will gib all non-carbons. (human simple animal mobs don't count) - if(iscarbon(L)) - gib = FALSE - if(L.stat == CONSCIOUS) - L.say("ARRRRRRRRRRRGH!!!") - add_mob_blood(L) - - if(!blood && !issilicon(L)) - blood = TRUE - update_icon(UPDATE_ICON_STATE) - - // Remove and recycle the equipped items - if(eat_victim_items) - for(var/obj/item/I in L.get_equipped_items(TRUE)) - if(L.drop_item_to_ground(I)) - eat(I, sound = 0) - - // Instantly lie down, also go unconscious from the pain, before you die. - L.Paralyse(10 SECONDS) - - if(gib || always_gib) - L.gib() - else if(emagged) - L.adjustBruteLoss(crush_damage) - - -/obj/machinery/recycler/AltClick(mob/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) - return - - eat_dir = turn(eat_dir, 90) - to_chat(user, "[src] will now accept items from [dir2text(eat_dir)].") - -/obj/machinery/recycler/deathtrap - name = "dangerous old crusher" - emagged = TRUE - crush_damage = 120 - - -/obj/item/paper/recycler - name = "paper - 'garbage duty instructions'" - info = "

    New Assignment

    You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.

    There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!" - -#undef SOUND_COOLDOWN - -#undef SAFETY_COOLDOWN diff --git a/code/game/machinery/tcomms/nttc.dm b/code/game/machinery/tcomms/nttc.dm deleted file mode 100644 index 993187499f133..0000000000000 --- a/code/game/machinery/tcomms/nttc.dm +++ /dev/null @@ -1,338 +0,0 @@ -/* - NTTC system - This is basically the replacement for NTSL and allows tickbox features such as job titles and colours, without needing a script - This also means that there is no user input here, which means the system isnt prone to exploits since its only selecting options, no user input - Basically, just imagine pfSense for tcomms - - All this code was written by Tigercat2000. I take no credit -aa07 -*/ - -#define JOB_STYLE_1 "Name (Job)" -#define JOB_STYLE_2 "Name - Job" -#define JOB_STYLE_3 "\[Job\] Name" -#define JOB_STYLE_4 "(Job) Name" - -/datum/nttc_configuration - var/regex/word_blacklist = new("(EXPLOIT WARNING: [ckey] attempted to upload an NTTC configuration containing JS abusable tags!") - log_admin("EXPLOIT WARNING: [ckey] attempted to upload an NTTC configuration containing JS abusable tags") - return FALSE - var/list/var_list = json_decode(text) - for(var/variable in var_list) - if(variable in to_serialize) // Don't just accept any random vars jesus christ! - var/sanitize_method = serialize_sanitize[variable] - var/variable_value = var_list[variable] - variable_value = nttc_sanitize(variable_value, sanitize_method) - if(variable_value != null) - vars[variable] = variable_value - return TRUE - -// Sanitizing user input. Don't blindly trust the JSON. -/datum/nttc_configuration/proc/nttc_sanitize(variable, sanitize_method) - if(!sanitize_method) - return null - - switch(sanitize_method) - if("bool") - return variable ? TRUE : FALSE - // if("table", "array") - if("array") - if(!islist(variable)) - return list() - // Insert html filtering for the regexes here if you're boring - var/newlist = json_decode(html_decode(json_encode(variable))) - if(!islist(newlist)) - return null - return newlist - if("string") - return "[variable]" - - return variable - -// Primary signal modification. This is where all of the variables behavior are actually implemented. -/datum/nttc_configuration/proc/modify_message(datum/tcomms_message/tcm) - // Check if they should be blacklisted right off the bat. We can save CPU if the message wont even be processed - if(tcm.sender_name in filtering) - tcm.pass = FALSE - // All job and coloring shit - if(toggle_job_color || toggle_name_color) - var/job = tcm.sender_job - var/rank = tcm.sender_rank - //if the job title is not custom, just use that to decide the rules of formatting - if(job in all_jobs) - job_class = all_jobs[job] - else - job_class = all_jobs[rank] - - tcm.pre_modify_name = tcm.sender_name - if(toggle_name_color) - var/new_name = "[tcm.sender_name]" - tcm.sender_name = new_name - tcm.vname = new_name // this is required because the broadcaster uses this directly if the speaker doesn't have a voice changer on - - if(toggle_jobs) - var/new_name = "" - var/job = tcm.sender_job - if(job in ert_jobs) - job = "ERT" - if(toggle_job_color) - switch(job_indicator_type) - if(JOB_STYLE_1) - new_name = "[tcm.sender_name] ([job])" - if(JOB_STYLE_2) - new_name = "[tcm.sender_name] - [job]" - if(JOB_STYLE_3) - new_name = "\[[job]\] [tcm.sender_name]" - if(JOB_STYLE_4) - new_name = "([job]) [tcm.sender_name]" - else - switch(job_indicator_type) - if(JOB_STYLE_1) - new_name = "[tcm.sender_name] ([job])" - if(JOB_STYLE_2) - new_name = "[tcm.sender_name] - [job]" - if(JOB_STYLE_3) - new_name = "\[[job]\] [tcm.sender_name]" - if(JOB_STYLE_4) - new_name = "([job]) [tcm.sender_name]" - - // Only change the name if they have a job tag set, otherwise everyone becomes unknown, and thats bad - if(new_name != "") - tcm.sender_name = new_name - tcm.vname = new_name // this is required because the broadcaster uses this directly if the speaker doesn't have a voice changer on - // This is hacky stuff for multilingual messages... - var/list/message_pieces = tcm.message_pieces - - // Makes heads of staff bold - if(toggle_command_bold) - var/job = tcm.sender_job - var/rank = tcm.sender_rank - var/realjob = job - if(!(job in all_jobs)) - realjob = rank - - if((realjob in ert_jobs) || (realjob in heads) || (realjob in cc_jobs) || (realjob in tsf_jobs)) - for(var/I in 1 to length(message_pieces)) - var/datum/multilingual_say_piece/S = message_pieces[I] - if(!S.message) - continue - if(I == 1 && !istype(S.speaking, /datum/language/noise)) // Capitalise the first section only, unless it's an emote. - S.message = "[capitalize(S.message)]" - S.message = "[S.message]" // Make everything bolded - - - // Language Conversion - if(setting_language && valid_languages[setting_language]) - if(setting_language == "--DISABLE--") - setting_language = null - else - for(var/datum/multilingual_say_piece/S in message_pieces) - if(S.speaking != GLOB.all_languages["Noise"]) // check if they are emoting, these do not need to be translated - S.speaking = GLOB.all_languages[setting_language] - - return tcm - -#undef JOB_STYLE_1 -#undef JOB_STYLE_2 -#undef JOB_STYLE_3 -#undef JOB_STYLE_4 diff --git a/code/game/machinery/tcomms/relay.dm b/code/game/machinery/tcomms/relay.dm deleted file mode 100644 index 4a9aee89a9e09..0000000000000 --- a/code/game/machinery/tcomms/relay.dm +++ /dev/null @@ -1,238 +0,0 @@ -/** - * # Telecommunications Relay - * - * Extends the reach of telecomms to the z-level it is built on - * - * Relays themselves dont do any processing, they just tell the core that this z-level is available in the tcomms network. - */ -/obj/machinery/tcomms/relay - name = "Telecommunications Relay" - desc = "A large device with several radio antennas on it." - icon_state = "relay" - // This starts as off so you cant make cores as hot spares - active = FALSE - /// The host core for this relay - var/obj/machinery/tcomms/core/linked_core - /// ID of the hub to auto link to - var/autolink_id - /// Is this linked to anything at all - var/linked = FALSE - /// Is this link invisible on the hub? - var/hidden_link = FALSE - /// Does this relay need a password to connect to hubs? - var/password_bypass = FALSE - -/** - * Initializer for the relay. - * - * Calls parent to ensure its added to the GLOB of tcomms machines, before checking if there is an autolink that needs to be added. - */ -/obj/machinery/tcomms/relay/Initialize(mapload) - . = ..() - component_parts += new /obj/item/circuitboard/tcomms/relay(null) - if(check_power_on()) - active = TRUE - else - visible_message("Error: Another relay is already active in this sector. Power-up cancelled due to radio interference.") - update_icon() - if(mapload && autolink_id) - return INITIALIZE_HINT_LATELOAD - -/** - * Descrutor for the relay. - * - * Ensures that the machine is taken out of the global list when destroyed, and also removes the link to the core. - */ -/obj/machinery/tcomms/relay/Destroy() - Reset() - return ..() - -/** - * Late Initialize for the relay. - * - * Calls parent, then adds links to the cores. This is a LateInitialize because the core MUST be initialized first - */ -/obj/machinery/tcomms/relay/LateInitialize() - . = ..() - - // It's also possible the relay's APC's Initialize was called after this one. - // Take the opportunity here to re-check the equipment channel. - power_change() - - for(var/obj/machinery/tcomms/core/C in GLOB.tcomms_machines) - if(C.network_id == autolink_id) - AddLink(C) - // Only ONE of these with one ID should exist per world - break - -/** - * Z-Level transit change helper - * - * Handles parent call of disabling the machine if it changes Z-level, but also rebuilds the list of reachable levels on the linked core - */ -/obj/machinery/tcomms/relay/on_changed_z_level(turf/old_turf, turf/new_turf) - . = ..() - if(linked_core) - linked_core.refresh_zlevels() - - -/** - * Power-on checker - * - * Checks the z-level to see if an existing relay is already powered on, and deny this one turning on if there is one. Returns TRUE if it can power on, or FALSE if it cannot - */ -/obj/machinery/tcomms/relay/proc/check_power_on() - // Cancel if we are already on - if(active) - return TRUE - - for(var/obj/machinery/tcomms/relay/R in GLOB.tcomms_machines) - // Make sure we dont check ourselves - if(R == src) - continue - // We dont care about ones on other zlevels - if(!atoms_share_level(R, src)) - continue - // If another relay is active, return FALSE - if(R.active) - if(R.stat & NOPOWER) // If another relay has no power but is supposed to be on, we shut it down so we can continue. - R.active = FALSE // Since only one active relay is allowed per z level, give priority to the one that's actually working. - R.update_icon() - else - return FALSE - // If we got here there isnt an active relay on this Z-level. So return TRUE - return TRUE - -/** - * Proc to link the relay to the core. - * - * Sets the linked core to the target (argument below), before adding it to the list of linked relays, then re-freshing the zlevel list - * The relay is then marked as linked - * Arguments: - * * target - The telecomms core that this relay should be linked to - */ -/obj/machinery/tcomms/relay/proc/AddLink(obj/machinery/tcomms/core/target) - linked_core = target - target.linked_relays |= src - target.refresh_zlevels() - linked = TRUE - -/** - * Proc to rest the relay. - * - * Resets the relay, removing its linkage status, and refreshing the core's list of z-levels - */ -/obj/machinery/tcomms/relay/proc/Reset() - if(linked_core) - linked_core.linked_relays -= src - linked_core.refresh_zlevels() - linked_core = null - linked = FALSE - -/** - * Power Change Handler - * - * Proc which ensures the host core has its zlevels updated (icons are updated by parent call) - */ -/obj/machinery/tcomms/relay/power_change() - if(!..()) - return - if(linked_core) - linked_core.refresh_zlevels() - -////////////// -// UI STUFF // -////////////// - -/obj/machinery/tcomms/relay/ui_state(mob/user) - return GLOB.default_state - -/obj/machinery/tcomms/relay/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "TcommsRelay", name) - ui.open() - -/obj/machinery/tcomms/relay/ui_data(mob/user) - var/list/data = list() - // Are we on or not - data["active"] = active - // What is our network ID - data["network_id"] = network_id - // Are we linked - data["linked"] = linked - // Is the link hidden - data["hidden_link"] = hidden_link - - // Only send linked tab stuff if we are linked. This saves on sending overhead. - if(linked) - data["linked_core_id"] = linked_core.network_id - data["linked_core_addr"] = "\ref[linked_core]" - else - var/list/cores = list() - for(var/obj/machinery/tcomms/core/C in GLOB.tcomms_machines) - cores += list(list("addr" = "\ref[C]", "net_id" = C.network_id, "sector" = C.loc.z)) - data["cores"] = cores - - return data - -/obj/machinery/tcomms/relay/ui_act(action, list/params) - // Check against href exploits - if(..()) - return - - . = TRUE - - switch(action) - if("toggle_active") - if(check_power_on()) - active = !active - update_icon() - if(linked_core) - linked_core.refresh_zlevels() - else - to_chat(usr, "Error: Another relay is already active in this sector. Power-up cancelled due to radio interference.") - - // Set network ID - if("network_id") - var/new_id = input(usr, "Please enter a new network ID", "Network ID", network_id) - log_action(usr, "renamed core with ID [network_id] to [new_id]") - to_chat(usr, "Device ID changed from [network_id] to [new_id].") - network_id = new_id - - // Only do these hrefs if we are linked to prevent bugs/exploits - if("toggle_hidden_link") - if(!linked) - return - hidden_link = !hidden_link - log_action(usr, "Modified hidden link for [network_id] (Now [hidden_link])") - - if("unlink") - if(!linked) - return - var/choice = tgui_alert(usr, "Are you SURE you want to unlink this relay?\nYou wont be able to re-link without the core password", "Unlink", list("Yes", "No")) - if(choice == "Yes") - log_action(usr, "Unlinked [network_id] from [linked_core.network_id]") - Reset() - - // You should only be able to link if its not linked, to prevent weirdness - if("link") - if(linked) - return - var/obj/machinery/tcomms/core/C = locate(params["addr"]) - if(istype(C, /obj/machinery/tcomms/core)) - if(password_bypass) - AddLink(C) - to_chat(usr, "Successfully linked to [C.network_id].") - return - var/user_pass = input(usr, "Please enter core password","Password Entry") - // Check the password - if(user_pass == C.link_password) - AddLink(C) - to_chat(usr, "Successfully linked to [C.network_id].") - else - to_chat(usr, "ERROR: Password incorrect.") - else - to_chat(usr, "ERROR: Core not found. Please file an issue report.") - - diff --git a/code/game/machinery/tcomms/tcomms_core.dm b/code/game/machinery/tcomms/tcomms_core.dm deleted file mode 100644 index 38b98fddda5a0..0000000000000 --- a/code/game/machinery/tcomms/tcomms_core.dm +++ /dev/null @@ -1,350 +0,0 @@ -#define UI_TAB_CONFIG "CONFIG" -#define UI_TAB_LINKS "LINKS" -#define UI_TAB_FILTER "FILTER" - -/** - * # Telecommunications Core - * - * The core of the entire telecomms operation - * - * This thing basically handles the main broadcasting of the data, as well as NTTC configs - * The relays dont do any actual processing, they are just objects which can bring tcomms to another zlevel - */ -/obj/machinery/tcomms/core - name = "Telecommunications Core" - desc = "A large rack full of communications equipment. Looks important." - icon_state = "core" - // This starts as off so you cant make cores as hot spares - active = FALSE - /// The NTTC config for this device - var/datum/nttc_configuration/nttc = new() - /// List of all reachable devices - var/list/reachable_zlevels = list() - /// List of all linked relays - var/list/linked_relays = list() - /// Password for linking stuff together - var/link_password - /// What tab of the UI were currently on - var/ui_tab = UI_TAB_CONFIG - -/** - * Initializer for the core. - * - * Calls parent to ensure its added to the GLOB of tcomms machines, before generating a link password and adding itself to the list of reachable Zs. - */ -/obj/machinery/tcomms/core/Initialize(mapload) - . = ..() - link_password = GenerateKey() - reachable_zlevels |= loc.z - component_parts += new /obj/item/circuitboard/tcomms/core(null) - if(check_power_on()) - active = TRUE - else - visible_message("Error: Another core is already active in this sector. Power-up cancelled due to radio interference.") - update_icon() - - if(mapload) //Automatically links new midround tcomms cores to the cc relay - return - var/obj/machinery/tcomms/relay/cc/cc_relay = locateUID(GLOB.cc_tcomms_relay_uid) - if(cc_relay?.linked_core) //if we are already linked, ignore! - return - cc_relay.AddLink(src) - -/** - * Destructor for the core. - * - * Ensures that the machine is taken out of the global list when destroyed, and also unlinks all connected relays - */ -/obj/machinery/tcomms/core/Destroy() - for(var/obj/machinery/tcomms/relay/R in linked_relays) - R.Reset() - QDEL_NULL(nttc) // Delete the NTTC datum - linked_relays.Cut() // Just to be sure - return ..() - -/** - * Helper to see if a zlevel is reachable - * - * This is a simple check to see if the input z-level is in the list of reachable ones - * Returns TRUE if it can, FALSE if it cant - * - * Arguments: - * * zlevel - The input z level to test - */ -/obj/machinery/tcomms/core/proc/zlevel_reachable(zlevel) - // Nothing is reachable if the core is offline, unpowered, or ion'd - if(!active || (stat & NOPOWER) || ion) - return FALSE - if(zlevel in reachable_zlevels) - return TRUE - else - return FALSE - -/** - * Proc which takes in the message datum - * - * Some checks are ran on the signal, and NTTC is applied - * After that, it is broadcasted out to the required Z-levels - * - * Arguments: - * * tcm - The tcomms message datum - */ -/obj/machinery/tcomms/core/proc/handle_message(datum/tcomms_message/tcm) - // Don't do anything with rejected signals, if were offline, if we are ion'd, or if we have no power - if(tcm.reject || !active || (stat & NOPOWER) || ion) - return FALSE - // Kill the signal if its on a z-level that isnt reachable - if(!zlevel_reachable(tcm.source_level)) - return FALSE - - // Now we can run NTTC - tcm = nttc.modify_message(tcm) - - // If the signal shouldnt be broadcast, dont broadcast it - if(!tcm.pass) - // We still return TRUE here because the signal was handled, even though we didnt broadcast - return TRUE - - // Now we generate the list of where that signal should go to - tcm.zlevels = reachable_zlevels.Copy() - tcm.zlevels |= tcm.source_level - - // Now check if they actually have pieces, if so, broadcast - if(tcm.message_pieces) - broadcast_message(tcm) - return TRUE - - return FALSE - -/** - * Proc to remake the list of available zlevels - * - * Loops through the list of connected relays and adds their zlevels in. - * This is called if a relay is added or removed - * - */ -/obj/machinery/tcomms/core/proc/refresh_zlevels() - // Refresh the list - reachable_zlevels = list() - // Add itself as a reachable Z-level - reachable_zlevels |= loc.z - // Add all the linked relays in - for(var/obj/machinery/tcomms/relay/R in linked_relays) - // Only if the relay is active - if(R.active && !(R.stat & NOPOWER)) - reachable_zlevels |= R.loc.z - - -/** - * Z-Level transit change helper - * - * Handles parent call of disabling the machine if it changes Z-level, but also rebuilds the list of reachable levels - */ -/obj/machinery/tcomms/core/on_changed_z_level(turf/old_turf, turf/new_turf) - . = ..() - refresh_zlevels() - -/** - * Power-on checker - * - * Checks the z-level to see if an existing core is already powered on, and deny this one turning on if there is one. Returns TRUE if it can power on, or FALSE if it cannot - */ -/obj/machinery/tcomms/core/proc/check_power_on() - // Cancel if we are already on - if(active) - return TRUE - - for(var/obj/machinery/tcomms/core/C in GLOB.tcomms_machines) - // Make sure we dont check ourselves - if(C == src) - continue - // We dont care about ones on other zlevels - if(!atoms_share_level(C, src)) - continue - // If another core is active, return FALSE - if(C.active) - if(C.stat & NOPOWER) // If another core has no power but is supposed to be on, we shut it down so we can continue. - C.active = FALSE // Since only one active core is allowed per z level, give priority to the one actually working. - C.update_icon() - else - return FALSE - // If we got here there isnt an active core on this Z-level. So return true - return TRUE - -////////////// -// UI STUFF // -////////////// - -/obj/machinery/tcomms/core/ui_state(mob/user) - return GLOB.default_state - -/obj/machinery/tcomms/core/ui_interact(mob/user, datum/tgui/ui = null) - // This needs to happen here because of how late the language datum initializes. I dont like it - if(length(nttc.valid_languages) == 1) - nttc.update_languages() - - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "TcommsCore", name) - ui.open() - -/obj/machinery/tcomms/core/ui_data(mob/user) - var/list/data = list() - data["ion"] = ion - - // Z-level list. Note that this will also show sectors with hidden relay links, but you cant see the relays themselves - // This allows the crew to realise that sectors have hidden relays - data["sectors_available"] = "Count: [length(reachable_zlevels)] | List: [jointext(reachable_zlevels, " ")]" - // Toggles - data["active"] = active - data["nttc_toggle_jobs"] = nttc.toggle_jobs - data["nttc_toggle_job_color"] = nttc.toggle_job_color - data["nttc_toggle_name_color"] = nttc.toggle_name_color - data["nttc_toggle_command_bold"] = nttc.toggle_command_bold - // Strings - data["nttc_setting_language"] = nttc.setting_language - data["nttc_job_indicator_type"] = nttc.job_indicator_type - // Network ID - data["network_id"] = network_id - - data["link_password"] = link_password - - // You ready to see some awful shit? - var/list/relays = list() - for(var/obj/machinery/tcomms/relay/R in linked_relays) - // Dont show relays with a hidden link - if(R.hidden_link) - continue - // Assume false - var/status = FALSE - if(R.active && !(R.stat & NOPOWER)) - status = TRUE - - relays += list(list("addr" = "\ref[R]", "net_id" = R.network_id, "sector" = R.loc.z, "status" = status)) - - data["relay_entries"] = relays - // End the shit - - data["filtered_users"] = nttc.filtering - - return data - -/obj/machinery/tcomms/core/ui_act(action, list/params) - // Check against href exploits - if(..()) - return - - . = TRUE - - switch(action) - // All the toggle on/offs go here - if("toggle_active") - if(check_power_on()) - active = !active - update_icon() - else - to_chat(usr, "Error: Another core is already active in this sector. Power-up cancelled due to radio interference.") - - // NTTC Toggles - if("nttc_toggle_jobs") - nttc.toggle_jobs = !nttc.toggle_jobs - log_action(usr, "toggled job tags (Now [nttc.toggle_jobs])") - if("nttc_toggle_job_color") - nttc.toggle_job_color = !nttc.toggle_job_color - log_action(usr, "toggled job colors (Now [nttc.toggle_job_color])") - if("nttc_toggle_name_color") - nttc.toggle_name_color = !nttc.toggle_name_color - log_action(usr, "toggled name colors (Now [nttc.toggle_name_color])") - if("nttc_toggle_command_bold") - nttc.toggle_command_bold = !nttc.toggle_command_bold - log_action(usr, "toggled command bold (Now [nttc.toggle_command_bold])") - // We need to be a little more fancy for the others - - // Job Format - if("nttc_job_indicator_type") - var/card_style = tgui_input_list(usr, "Pick a job card format", "Job Card Format", nttc.job_card_styles) - if(!card_style) - return - nttc.job_indicator_type = card_style - to_chat(usr, "Jobs will now have the style of [card_style].") - log_action(usr, "has set NTTC job card format to [card_style]") - - // Language Settings - if("nttc_setting_language") - var/new_language = tgui_input_list(usr, "Pick a language to convert messages to", "Language Conversion", nttc.valid_languages) - if(!new_language) - return - if(new_language == "--DISABLE--") - nttc.setting_language = null - to_chat(usr, "Language conversion disabled.") - else - nttc.setting_language = new_language - to_chat(usr, "Messages will now be converted to [new_language].") - - log_action(usr, new_language == "--DISABLE--" ? "disabled NTTC language conversion" : "set NTTC language conversion to [new_language]", TRUE) - - // Imports and exports - if("import") - var/json = tgui_input_text(usr, "Provide configuration JSON below.", "Load Config", nttc.nttc_serialize(), multiline = TRUE, encode = FALSE) - if(isnull(json)) - return - if(nttc.nttc_deserialize(json, usr.ckey)) - log_action(usr, "has uploaded a NTTC JSON configuration: [ADMIN_SHOWDETAILS("Show", json)]", TRUE) - - if("export") - usr << browse(nttc.nttc_serialize(), "window=save_nttc") - - // Set network ID - if("network_id") - var/new_id = tgui_input_text(usr, "Please enter a new network ID", "Network ID", network_id) - if(!new_id) - return - log_action(usr, "renamed core with ID [network_id] to [new_id]") - to_chat(usr, "Device ID changed from [network_id] to [new_id].") - network_id = new_id - - if("unlink") - var/obj/machinery/tcomms/relay/R = locate(params["addr"]) - if(istype(R, /obj/machinery/tcomms/relay)) - var/confirm = tgui_alert(usr, "Are you sure you want to unlink this relay?\nID: [R.network_id]\nADDR: \ref[R]", "Relay Unlink", list("Yes", "No")) - if(confirm == "Yes") - log_action(usr, "has unlinked tcomms relay with ID [R.network_id] from tcomms core with ID [network_id]", TRUE) - R.Reset() - else - to_chat(usr, "ERROR: Relay not found. Please file an issue report.") - - if("change_password") - var/new_password = tgui_input_text(usr, "Please enter a new password", "New Password", link_password) - if(!new_password) - return - log_action(usr, "has changed the password on core with ID [network_id] from [link_password] to [new_password]") - to_chat(usr, "Successfully changed password from [link_password] to [new_password].") - link_password = new_password - - if("add_filter") - // This is a stripped input because I did NOT come this far for this system to be abused by HTML injection - var/name_to_add = tgui_input_text(usr, "Enter a name to add to the filtering list", "Name Entry", encode = FALSE) - if(!name_to_add) - return - if(name_to_add in nttc.filtering) - to_chat(usr, "ERROR: User already in filtering list.") - else - nttc.filtering |= name_to_add - log_action(usr, "has added [name_to_add] to the NTTC filter list on core with ID [network_id]", TRUE) - to_chat(usr, "Successfully added [name_to_add] to the NTTC filtering list.") - - if("remove_filter") - var/name_to_remove = params["user"] - if(!(name_to_remove in nttc.filtering)) - to_chat(usr, "ERROR: Name does not exist in filter list. Please file an issue report.") - else - var/confirm = tgui_alert(usr, "Are you sure you want to remove [name_to_remove] from the filtering list?", "Confirm Removal", list("Yes", "No")) - if(confirm == "Yes") - nttc.filtering -= name_to_remove - log_action(usr, "has removed [name_to_remove] from the NTTC filter list on core with ID [network_id]", TRUE) - to_chat(usr, "Successfully removed [name_to_remove] from the NTTC filtering list.") - - -#undef UI_TAB_CONFIG -#undef UI_TAB_LINKS -#undef UI_TAB_FILTER diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm deleted file mode 100644 index 6f9641454e28a..0000000000000 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ /dev/null @@ -1,480 +0,0 @@ -// Teleporter, Gravitational catapult, Armor booster modules, -// Repair droid, Tesla Energy relay, Generators - -#define MECH_GRAVCAT_MODE_GRAVSLING 1 -#define MECH_GRAVCAT_MODE_GRAVPUSH 2 - -////////////////////////////////////////////// TELEPORTER /////////////////////////////////////////////// - -/obj/item/mecha_parts/mecha_equipment/teleporter - name = "mounted teleporter" - desc = "An exosuit module that allows exosuits to teleport to any position in view." - icon_state = "mecha_teleport" - origin_tech = "bluespace=7" - equip_cooldown = 150 - energy_drain = 8000 - range = MECHA_RANGED - var/tele_precision = 4 - -/obj/item/mecha_parts/mecha_equipment/teleporter/action(atom/target) - if(!action_checks(target) || !is_teleport_allowed(loc.z)) - return - var/turf/T = get_turf(target) - if(T) - chassis.use_power(energy_drain) - do_teleport(chassis, T, tele_precision) - return - -/obj/item/mecha_parts/mecha_equipment/teleporter/precise - name = "upgraded teleporter" - desc = "An exosuit module that allows exosuits to teleport to any position in view. This is the high-precision, energy-efficient version." - origin_tech = "bluespace=7" - energy_drain = 1000 - tele_precision = 1 - -/////////////////////////////////////// GRAVITATIONAL CATAPULT /////////////////////////////////////////// - -/obj/item/mecha_parts/mecha_equipment/gravcatapult - name = "mounted gravitational catapult" - desc = "An exosuit mounted Gravitational Catapult." - icon_state = "mecha_teleport" - origin_tech = "bluespace=3;magnets=3;engineering=4" - equip_cooldown = 10 - energy_drain = 100 - range = MECHA_MELEE | MECHA_RANGED - var/atom/movable/locked - var/cooldown_timer = 0 - var/mode = MECH_GRAVCAT_MODE_GRAVSLING - -/obj/item/mecha_parts/mecha_equipment/gravcatapult/action(atom/movable/target) - if(!action_checks(target)) - return - if(cooldown_timer > world.time) - occupant_message("[src] is still recharging.") - return - switch(mode) - if(MECH_GRAVCAT_MODE_GRAVSLING) - if(!locked) - if(!istype(target) || target.anchored) - occupant_message("Unable to lock on [target]") - return - locked = target - occupant_message("Locked on [target]") - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",get_equip_info()) - else if(target!=locked) - if(locked in view(chassis)) - locked.throw_at(target, 14, 1.5) - locked = null - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",get_equip_info()) - cooldown_timer = world.time + 3 SECONDS - return 1 - else - locked = null - occupant_message("Lock on [locked] disengaged.") - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",get_equip_info()) - if(MECH_GRAVCAT_MODE_GRAVPUSH) - var/list/atoms = list() - if(isturf(target)) - atoms = range(3, target) - else - atoms = orange(3, target) - for(var/atom/movable/A in atoms) - if(A.anchored || A.move_resist == INFINITY) 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) - cooldown_timer = world.time + 3 SECONDS - log_game("[key_name(chassis.occupant)] used a Gravitational Catapult in ([T.x],[T.y],[T.z])") - return - - -/obj/item/mecha_parts/mecha_equipment/gravcatapult/get_equip_info() - return "[..()] [mode==1?"([locked||"Nothing"])":null] \[S|P\]" - -/obj/item/mecha_parts/mecha_equipment/gravcatapult/Topic(href, href_list) - if(..()) - return - if(href_list["mode"]) - mode = text2num(href_list["mode"]) - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",get_equip_info()) - -//////////////////////////// ARMOR BOOSTER MODULES ////////////////////////////////////////////////////////// - -/// what is that noise? A BAWWW from TK mutants. -/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster - name = "armor booster module (Close combat weaponry)" - desc = "Boosts exosuit armor against armed melee attacks. Requires energy to operate." - icon_state = "mecha_abooster_ccw" - origin_tech = "materials=4;combat=4" - equip_cooldown = 10 - energy_drain = 50 - range = 0 - var/deflect_coeff = 1.15 - var/damage_coeff = 0.8 - selectable = 0 - -/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc/attack_react(mob/user as mob) - if(action_checks(user)) - start_cooldown() - return TRUE - - -/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster - name = "armor booster module (Ranged weaponry)" - desc = "Boosts exosuit armor against ranged attacks. Requires energy to operate." - icon_state = "mecha_abooster_proj" - origin_tech = "materials=4;combat=3;engineering=3" - equip_cooldown = 10 - energy_drain = 50 - range = 0 - var/deflect_coeff = 1.15 - var/damage_coeff = 0.8 - selectable = 0 - -/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/projectile_react() - if(action_checks(src)) - start_cooldown() - return TRUE - - -////////////////////////////////// REPAIR DROID ////////////////////////////////////////////////// - -/obj/item/mecha_parts/mecha_equipment/repair_droid - name = "repair droid" - desc = "Automated repair droid. Scans exosuit for damage and repairs it. Can fix almost all types of external or internal damage." - icon_state = "repair_droid" - origin_tech ="magnets=3;programming=3;engineering=4" - equip_cooldown = 20 - energy_drain = 50 - range = 0 - var/health_boost = 1 - var/icon/droid_overlay - var/list/repairable_damage = list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH) - selectable = 0 - -/obj/item/mecha_parts/mecha_equipment/repair_droid/Destroy() - STOP_PROCESSING(SSobj, src) - if(chassis) - chassis.overlays -= droid_overlay - return ..() - -/obj/item/mecha_parts/mecha_equipment/repair_droid/attach(obj/mecha/M) - ..() - droid_overlay = new(icon, icon_state = "repair_droid") - M.overlays += droid_overlay - -/obj/item/mecha_parts/mecha_equipment/repair_droid/detach() - chassis.overlays -= droid_overlay - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/mecha_parts/mecha_equipment/repair_droid/get_equip_info() - if(!chassis) return - return "*  [name] - [equip_ready?"A":"Dea"]ctivate" - - -/obj/item/mecha_parts/mecha_equipment/repair_droid/Topic(href, href_list) - if(..()) - return - if(href_list["toggle_repairs"]) - chassis.overlays -= droid_overlay - if(equip_ready) - START_PROCESSING(SSobj, src) - droid_overlay = new(icon, icon_state = "repair_droid_a") - log_message("Activated.") - set_ready_state(0) - else - STOP_PROCESSING(SSobj, src) - droid_overlay = new(icon, icon_state = "repair_droid") - log_message("Deactivated.") - set_ready_state(1) - chassis.overlays += droid_overlay - send_byjax(chassis.occupant,"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 = FALSE - if(chassis.internal_damage & MECHA_INT_SHORT_CIRCUIT) - h_boost = 0 - chassis.take_damage(2, BURN) //short circuiting droids do damage - repaired = TRUE - else if(chassis.internal_damage && prob(15)) - for(var/int_dam_flag in repairable_damage) - if(chassis.internal_damage & int_dam_flag) - chassis.clearInternalDamage(int_dam_flag) - repaired = TRUE - break - if(chassis.obj_integrity < chassis.max_integrity && h_boost > 0) - chassis.obj_integrity += min(h_boost, chassis.max_integrity-chassis.obj_integrity) - repaired = TRUE - 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.overlays -= droid_overlay - droid_overlay = new(icon, icon_state = "repair_droid") - chassis.overlays += droid_overlay - -/////////////////////////////////// TESLA ENERGY RELAY //////////////////////////////////////////////// - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay - name = "exosuit energy relay" - desc = "An exosuit module that wirelessly drains energy from any available power channel in an area. The performance index barely compensates for movement costs." - icon_state = "tesla" - origin_tech = "magnets=4;powerstorage=4;engineering=4" - energy_drain = 0 - range = 0 - var/coeff = 100 - var/list/use_channels = list(PW_CHANNEL_EQUIPMENT, PW_CHANNEL_ENVIRONMENT, PW_CHANNEL_LIGHTING) - selectable = 0 - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/detach() - STOP_PROCESSING(SSobj, src) - ..() - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_charge() - if(equip_ready) //disabled - return 0 - var/area/A = get_area(chassis) - var/pow_chan = get_power_channel(A) - if(pow_chan) - return 1000 //making magic - - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_power_channel(area/A) - var/pow_chan - if(A) - for(var/c in use_channels) - if(A.powernet.has_power(c)) - pow_chan = c - break - return pow_chan - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Topic(href, href_list) - if(..()) - return - if(href_list["toggle_relay"]) - if(equip_ready) //inactive - START_PROCESSING(SSobj, src) - set_ready_state(0) - log_message("Activated.") - else - STOP_PROCESSING(SSobj, src) - set_ready_state(1) - log_message("Deactivated.") - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/get_equip_info() - if(!chassis) return - return "*  [name] - [equip_ready?"A":"Dea"]ctivate" - - -/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.") - return - if(cur_charge < chassis.cell.maxcharge) - var/area/A = get_area(chassis) - if(A) - var/pow_chan - for(var/c in use_channels) - if(A.powernet.has_power(c)) - pow_chan = c - break - if(pow_chan) - var/delta = min(60, chassis.cell.maxcharge - cur_charge) - chassis.give_power(delta) - A.powernet.use_active_power(pow_chan, delta * coeff) - -/////////////////////////////////////////// GENERATOR ///////////////////////////////////////////// - -/obj/item/mecha_parts/mecha_equipment/generator - name = "exosuit plasma converter" - desc = "An exosuit module that generates power using solid plasma as fuel. Pollutes the environment." - icon_state = "tesla" - origin_tech = "plasmatech=2;powerstorage=2;engineering=2" - range = MECHA_MELEE - energy_drain = 0 //for allow load fuel without energy - var/coeff = 100 - var/fuel_type = MAT_PLASMA - var/max_fuel = 150000 // 45k energy for 75 plasma/ 375 cr. - var/fuel_name = "plasma" // Our fuel name as a string - var/fuel_amount = 0 - var/fuel_per_cycle_idle = 10 - var/fuel_per_cycle_active = 500 - var/power_per_cycle = 150 - - -/obj/item/mecha_parts/mecha_equipment/generator/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/mecha_parts/mecha_equipment/generator/detach() - STOP_PROCESSING(SSobj, src) - ..() - -/obj/item/mecha_parts/mecha_equipment/generator/Topic(href, href_list) - if(..()) - return - if(href_list["toggle"]) - if(equip_ready) //inactive - set_ready_state(0) - START_PROCESSING(SSobj, src) - log_message("Activated.") - else - set_ready_state(1) - STOP_PROCESSING(SSobj, src) - log_message("Deactivated.") - -/obj/item/mecha_parts/mecha_equipment/generator/get_equip_info() - var/output = ..() - if(output) - return "[output] \[[fuel_name]: [round(fuel_amount,0.1)] cm3\] - [equip_ready?"A":"Dea"]ctivate" - -/obj/item/mecha_parts/mecha_equipment/generator/action(target) - if(chassis) - var/result = load_fuel(target) - if(result) - send_byjax(chassis.occupant,"exosuit.browser", "\ref[src]", get_equip_info()) - -/obj/item/mecha_parts/mecha_equipment/generator/proc/load_fuel(obj/item/I) - if(istype(I) && (fuel_type in I.materials)) - if(!istype(I, /obj/item/stack/sheet)) // Some other object containing our fuel's type, so we just eat it (ores mainly) - var/to_load = clamp(I.materials[fuel_type], 0, max_fuel - fuel_amount) - if(to_load == 0) - return FALSE - fuel_amount += to_load - qdel(I) - return 0 - - if(fuel_amount >= max_fuel) - occupant_message("Unit is full.") - return 0 - - var/obj/item/stack/sheet/P = I - var/to_load = max_fuel - fuel_amount - - var/units = clamp(round(to_load / P.perunit), 1, P.amount) - if(units) - var/added_fuel = units * P.perunit - fuel_amount += added_fuel - P.use(units) - occupant_message("[units] unit\s of [fuel_name] successfully loaded.") - return added_fuel - - else if(istype(I, /obj/structure/ore_box)) - var/fuel_added = 0 - for(var/obj/item/O as anything in I.contents) - if(fuel_type in O.materials) - fuel_added = load_fuel(O) - break - return fuel_added - - else - occupant_message("[fuel_name] traces in target minimal! [I] cannot be used as fuel.") - return 0 - -/obj/item/mecha_parts/mecha_equipment/generator/attackby__legacy__attackchain(weapon,mob/user, params) - load_fuel(weapon) - -/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) - log_message("Deactivated - no fuel.") - set_ready_state(1) - return - var/cur_charge = chassis.get_charge() - if(isnull(cur_charge)) - set_ready_state(1) - occupant_message("No powercell detected.") - log_message("Deactivated.") - STOP_PROCESSING(SSobj, src) - return - var/use_fuel = fuel_per_cycle_idle - if(cur_charge < chassis.cell.maxcharge) - use_fuel = fuel_per_cycle_active - chassis.give_power(power_per_cycle) - fuel_amount -= min(use_fuel, fuel_amount) - update_equip_info() - - -/obj/item/mecha_parts/mecha_equipment/generator/nuclear - name = "exonuclear reactor" - desc = "An exosuit module that generates power using uranium as fuel. Pollutes the environment." - icon_state = "tesla" - origin_tech = "powerstorage=4;engineering=4" - fuel_name = "uranium" // Our fuel name as a string - fuel_type = MAT_URANIUM - max_fuel = 50000 // around 83k energy for 25 uranium/ 0 cr. - fuel_per_cycle_idle = 10 - fuel_per_cycle_active = 150 - power_per_cycle = 250 - var/rad_per_cycle = 30 - -/obj/item/mecha_parts/mecha_equipment/generator/nuclear/process() - if(..()) - radiation_pulse(get_turf(src), rad_per_cycle) - -/obj/item/mecha_parts/mecha_equipment/thrusters - name = "exosuit ion thrusters" - desc = "Ion thrusters to be attached to an exosuit. Drains power even while not in flight." - icon_state = "tesla" - origin_tech = "powerstorage=4;engineering=4" - range = 0 - energy_drain = 20 - selectable = FALSE - -/obj/item/mecha_parts/mecha_equipment/thrusters/attach(obj/mecha/M) - . = ..() - START_PROCESSING(SSobj, src) - M.add_thrusters() - M.thruster_count++ - -/obj/item/mecha_parts/mecha_equipment/thrusters/detach(atom/moveto) - chassis.thruster_count-- - chassis.remove_thrusters() - . = ..() - STOP_PROCESSING(SSobj, src) - -/obj/item/mecha_parts/mecha_equipment/thrusters/process() - if(!chassis) - STOP_PROCESSING(SSobj, src) - if(!energy_drain || !chassis.thrusters_active) - return - chassis.use_power(energy_drain) - -/obj/mecha/proc/add_thrusters() - if(occupant) - thrusters_action.Grant(occupant, src) - -/obj/mecha/proc/remove_thrusters() - if(occupant && !thruster_count) - thrusters_action.Remove(occupant) - -#undef MECH_GRAVCAT_MODE_GRAVSLING -#undef MECH_GRAVCAT_MODE_GRAVPUSH diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm deleted file mode 100644 index c78c0fd5d5418..0000000000000 --- a/code/game/mecha/equipment/tools/work_tools.dm +++ /dev/null @@ -1,511 +0,0 @@ - -//Hydraulic clamp, Kill clamp, Extinguisher, RCD, Mime RCD, Cable layer. - -#define MECH_RCD_MODE_DECONSTRUCT 0 -#define MECH_RCD_MODE_WALL_OR_FLOOR 1 -#define MECH_RCD_MODE_AIRLOCK 2 - -/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 - var/dam_force = 20 - var/obj/mecha/working/ripley/cargo_holder - harmful = TRUE - -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/can_attach(obj/mecha/working/ripley/M) - if(..()) - if(istype(M)) - return TRUE - return FALSE - -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/attach(obj/mecha/M) - ..() - cargo_holder = M - -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/detach(atom/moveto = null) - ..() - cargo_holder = null - -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/action(atom/target) - if(!action_checks(target)) - return - if(!cargo_holder) - return - if(isobj(target)) - var/obj/O = target - if(istype(target, /obj/machinery/atmospherics/supermatter_crystal)) //No, you can't pick up the SM with this you moron, did you think you were clever? - var/obj/mecha/working/ripley/R = chassis - QDEL_LIST_CONTENTS(R.cargo) //We don't want to drop cargo that just spam hits the SM, let's delete it - occupant_message("You realise in horror what you have done as [chassis] starts warping around you!") - chassis.occupant.dust() - target.Bumped(chassis) - return - if(O.anchored) - occupant_message("[target] is firmly secured!") - return - if(length(cargo_holder.cargo) >= cargo_holder.cargo_capacity) - occupant_message("Not enough room in cargo compartment!") - return - chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") - var/anchor_state_before_load = O.anchored - O.anchored = TRUE - if(!do_after_cooldown(target)) - O.anchored = anchor_state_before_load - return - cargo_holder.cargo += O - O.forceMove(chassis) - O.anchored = FALSE - occupant_message("[target] was successfully loaded.") - log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - length(cargo_holder.cargo)]") - return - - 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)) - target.visible_message("[chassis] squeezes [target].", \ - "[chassis] squeezes [target].",\ - "You hear something crack.") - add_attack_logs(chassis.occupant, M, "Squeezed with [src] ([uppertext(chassis.occupant.a_intent)]) ([uppertext(damtype)])") - start_cooldown() - return - step_away(M, chassis) - occupant_message("You push [target] out of the way.") - chassis.visible_message("[chassis] pushes [target] out of the way.") - - -//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 - -/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(length(cargo_holder.cargo) < 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.") - log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - length(cargo_holder.cargo)]") - 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) - target.visible_message("[chassis] destroys [target] in an unholy fury.", - "[chassis] destroys [target] in an unholy fury.") - M.gib() - /*if(chassis.occupant.a_intent == INTENT_DISARM) - 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 - - -/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 - -/obj/item/mecha_parts/mecha_equipment/extinguisher/New() - create_reagents(1000) - reagents.add_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, TRUE, -6) - else - if(reagents.total_volume > 0) - playsound(chassis, 'sound/effects/extinguish.ogg', 75, TRUE, -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 - -/obj/item/mecha_parts/mecha_equipment/extinguisher/get_equip_info() - return "[..()] \[[src.reagents.total_volume]\]" - -/obj/item/mecha_parts/mecha_equipment/extinguisher/on_reagent_change() - return - -/obj/item/mecha_parts/mecha_equipment/extinguisher/can_attach(obj/mecha/working/M) - if(..()) - if(istype(M)) - return TRUE - return FALSE - - -/obj/item/mecha_parts/mecha_equipment/rcd - name = "mounted RCD" - desc = "An exosuit-mounted Rapid Construction Device. (Can be attached to: Any exosuit)" - icon_state = "mecha_rcd" - origin_tech = "materials=4;bluespace=3;magnets=4;powerstorage=4;engineering=4" - equip_cooldown = 10 - energy_drain = 250 - range = MECHA_MELEE | MECHA_RANGED - flags_2 = NO_MAT_REDEMPTION_2 - var/mode = MECH_RCD_MODE_DECONSTRUCT - var/can_rwall = 0 - toolspeed = 1 - usesound = 'sound/items/deconstruct.ogg' - -/obj/item/mecha_parts/mecha_equipment/rcd/New() - 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/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(MECH_RCD_MODE_DECONSTRUCT) - if(iswallturf(target)) - if((isreinforcedwallturf(target) && !can_rwall) || istype(target, /turf/simulated/wall/indestructible)) - return 0 - var/turf/simulated/wall/W = target - occupant_message("Deconstructing [target]...") - if(do_after_cooldown(W)) - chassis.spark_system.start() - W.ChangeTurf(/turf/simulated/floor/plating) - playsound(W, usesound, 50, 1) - else if(isfloorturf(target)) - var/turf/simulated/floor/F = target - occupant_message("Deconstructing [target]...") - if(do_after_cooldown(F)) - chassis.spark_system.start() - F.ChangeTurf(F.baseturf) - F.recalculate_atmos_connectivity() - playsound(F, usesound, 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, usesound, 50, 1) - if(MECH_RCD_MODE_WALL_OR_FLOOR) - if(isspaceturf(target) || ischasm(target)) - var/turf/space/S = target - occupant_message("Building Floor...") - if(do_after_cooldown(S)) - S.ChangeTurf(/turf/simulated/floor/plating) - playsound(S, usesound, 50, 1) - chassis.spark_system.start() - else if(isfloorturf(target)) - var/turf/simulated/floor/F = target - occupant_message("Building Wall...") - if(do_after_cooldown(F)) - F.ChangeTurf(/turf/simulated/wall) - playsound(F, usesound, 50, 1) - chassis.spark_system.start() - if(MECH_RCD_MODE_AIRLOCK) - 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, usesound, 50, 1) - playsound(target, 'sound/effects/sparks2.ogg', 50, 1) - - -/obj/item/mecha_parts/mecha_equipment/rcd/Topic(href,href_list) - if(..()) - return - if(href_list["mode"]) - mode = text2num(href_list["mode"]) - switch(mode) - if(MECH_RCD_MODE_DECONSTRUCT) - occupant_message("Switched RCD to Deconstruct.") - if(MECH_RCD_MODE_WALL_OR_FLOOR) - occupant_message("Switched RCD to Construct.") - if(MECH_RCD_MODE_AIRLOCK) - occupant_message("Switched RCD to Construct Airlock.") - -/obj/item/mecha_parts/mecha_equipment/rcd/get_equip_info() - return "[..()] \[D|C|A\]" - - -/obj/item/mecha_parts/mecha_equipment/mimercd - name = "mounted MRCD" - desc = "An exosuit-mounted Mime Rapid Construction Device. (Can be attached to: Reticence)" - icon_state = "mecha_rcd" - origin_tech = "materials=4;bluespace=3;magnets=4;powerstorage=4;engineering=4" - equip_cooldown = 10 - energy_drain = 250 - range = MECHA_MELEE | MECHA_RANGED - -/obj/item/mecha_parts/mecha_equipment/mimercd/can_attach(obj/mecha/combat/reticence/M) - if(..()) - if(istype(M)) - return TRUE - return FALSE - -/obj/item/mecha_parts/mecha_equipment/mimercd/action(atom/target) - if(istype(target, /turf/space/transit))//>implying these are ever made -Sieve - return - if(!isturf(target)) - target = get_turf(target) - if(!action_checks(target) || get_dist(chassis, target)>3) - return - - if(isfloorturf(target)) - occupant_message("Building Wall...") - if(do_after_cooldown(target)) - new /obj/structure/barricade/mime/mrcd(target) - chassis.spark_system.start() - - - -/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/obj/structure/cable/last_piece - var/obj/item/stack/cable_coil/cable - var/max_cable = 1000 - -/obj/item/mecha_parts/mecha_equipment/cable_layer/New() - cable = new(src) - cable.amount = 0 - ..() - -/obj/item/mecha_parts/mecha_equipment/cable_layer/can_attach(obj/mecha/working/M) - if(..()) - if(istype(M)) - return TRUE - return FALSE - -/obj/item/mecha_parts/mecha_equipment/cable_layer/attach() - ..() - RegisterSignal(chassis, COMSIG_MOVABLE_MOVED, PROC_REF(layCable)) - -/obj/item/mecha_parts/mecha_equipment/cable_layer/detach() - UnregisterSignal(chassis, COMSIG_MOVABLE_MOVED) - return ..() - -/obj/item/mecha_parts/mecha_equipment/cable_layer/action(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) - cable.amount = 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(..()) - return - if(href_list["toggle"]) - set_ready_state(!equip_ready) - occupant_message("[src] [equip_ready?"dea":"a"]ctivated.") - 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) - var/obj/item/stack/cable_coil/CC = new (get_turf(chassis)) - CC.amount = m - else - occupant_message("There's no more cable on the reel.") - -/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]" - -/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.") - log_message("Cable depleted, [src] deactivated.") - return FALSE - if(cable.amount < amount) - occupant_message("No enough cable to finish the task.") - return FALSE - cable.use(amount) - update_equip_info() - return TRUE - -/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/reset() - last_piece = null - -/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/dismantleFloor(turf/new_turf) - if(isfloorturf(new_turf)) - var/turf/simulated/floor/T = new_turf - if(!istype(T, /turf/simulated/floor/plating)) - 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(obj/mecha/M, atom/OldLoc, Dir, Forced = FALSE) - var/turf/new_turf = get_turf(M) - if(equip_ready || !istype(new_turf) || !dismantleFloor(new_turf)) - return reset() - var/fdirn = turn(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) - NC.cable_color("red") - NC.d1 = NO_DIRECTION - NC.d2 = fdirn - NC.update_icon() - - var/datum/regional_powernet/PN - if(last_piece && last_piece.d2 != Dir) - last_piece.d1 = min(last_piece.d2, Dir) - last_piece.d2 = max(last_piece.d2, Dir) - last_piece.update_icon() - PN = last_piece.powernet - - if(!PN) - PN = new() - NC.powernet = PN - PN.cables += NC - NC.merge_connected_networks(NC.d2) - - //NC.mergeConnectedNetworksOnTurf() - last_piece = NC - return TRUE - -/obj/item/mecha_parts/mecha_equipment/mech_crusher - name = "exosuit crusher" - desc = "A mech mounted crusher. For crushing bigger things." - icon_state = "mecha_crusher" - equip_cooldown = 1.2 SECONDS - energy_drain = 3000 - harmful = TRUE - range = MECHA_MELEE | MECHA_RANGED - var/obj/item/kinetic_crusher/mecha/internal_crusher - -/obj/item/kinetic_crusher/mecha - /// Since this one doesn't have the two_handed component it will always use the value in force - force = 30 - armour_penetration_flat = 15 - detonation_damage = 90 - backstab_bonus = 50 - -/obj/item/kinetic_crusher/mecha/get_turf_for_projectile(atom/user) - if(ismecha(user.loc) && isturf(user.loc?.loc)) - return user.loc.loc - return null - -/obj/item/kinetic_crusher/mecha/Initialize(mapload) - . = ..() - DeleteComponent(/datum/component/parry) - DeleteComponent(/datum/component/two_handed) - - /// This is only for the sake of internal checks in the crusher itself. - ADD_TRAIT(src, TRAIT_WIELDED, "mech[UID()]") - -/obj/item/mecha_parts/mecha_equipment/mech_crusher/Initialize(mapload) - . = ..() - internal_crusher = new(src) - -/obj/item/mecha_parts/mecha_equipment/mech_crusher/Destroy() - QDEL_NULL(internal_crusher) - . = ..() - -/obj/item/mecha_parts/mecha_equipment/mech_crusher/action(atom/target) - if(!action_checks(target)) - return - if(!chassis.occupant) - return - chassis.occupant.changeNext_click(equip_cooldown) - var/proximate = chassis.Adjacent(target) - if(proximate) - target.attackby__legacy__attackchain(internal_crusher, chassis.occupant) - internal_crusher.afterattack__legacy__attackchain(target, chassis.occupant, proximate, null) - -#undef MECH_RCD_MODE_DECONSTRUCT -#undef MECH_RCD_MODE_WALL_OR_FLOOR -#undef MECH_RCD_MODE_AIRLOCK diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm deleted file mode 100644 index 4475574cab65e..0000000000000 --- a/code/game/mecha/mecha_construction_paths.dm +++ /dev/null @@ -1,2058 +0,0 @@ -#define STANDARD_STACK_AMOUNT 5 - -//////////////////////////////// -///// Construction datums ////// -//////////////////////////////// - -/datum/construction/mecha/custom_action(step, atom/used_atom, mob/user) - if(istype(used_atom, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = used_atom - if(C.use(4)) - playsound(holder, C.usesound, 50, 1) - else - to_chat(user, ("There's not enough cable to finish the task.")) - return 0 - else if(istype(used_atom, /obj/item/stack)) - var/obj/item/stack/S = used_atom - if(S.get_amount() < STANDARD_STACK_AMOUNT) - to_chat(user, ("There's not enough material in this stack.")) - return 0 - else - S.use(STANDARD_STACK_AMOUNT) - else - return ..() - -/datum/construction/mecha/spawn_result(mob/user, result_name) - SSblackbox.record_feedback("tally", "mechas_created", 1, "[result_name]") - -/datum/construction/reversible/mecha/custom_action(index as num, diff as num, atom/used_atom, mob/user as mob) - if(istype(used_atom, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = used_atom - if(C.use(4)) - playsound(holder, C.usesound, 50, 1) - else - to_chat(user, ("There's not enough cable to finish the task.")) - return 0 - else if(istype(used_atom, /obj/item/stack)) - var/obj/item/stack/S = used_atom - if(S.get_amount() < STANDARD_STACK_AMOUNT) - to_chat(user, ("There's not enough material in this stack.")) - return 0 - else - S.use(STANDARD_STACK_AMOUNT) - else if(isitem(used_atom)) - var/obj/item/I = used_atom - if(I.tool_behaviour in CONSTRUCTION_TOOL_BEHAVIOURS) - if(!I.use_tool(holder, user, 0, volume = I.tool_volume)) - return 0 - return 1 - - -/datum/construction/mecha/ripley_chassis - steps = list( - list("key" = /obj/item/mecha_parts/part/ripley_torso),//1 - list("key" = /obj/item/mecha_parts/part/ripley_left_arm),//2 - list("key" = /obj/item/mecha_parts/part/ripley_right_arm),//3 - list("key" = /obj/item/mecha_parts/part/ripley_left_leg),//4 - list("key" = /obj/item/mecha_parts/part/ripley_right_leg)//5 - ) - -/datum/construction/mecha/ripley_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") - holder.overlays += used_atom.icon_state+"+o" - qdel(used_atom) - return 1 - -/datum/construction/mecha/ripley_chassis/action(atom/used_atom,mob/user as mob) - return check_all_steps(used_atom,user) - -/datum/construction/mecha/ripley_chassis/spawn_result(mob/user, result_name) - ..(user, "Ripley") - var/obj/item/mecha_parts/chassis/const_holder = holder - const_holder.construct = new /datum/construction/reversible/mecha/ripley(const_holder) - const_holder.icon = 'icons/mecha/mech_construction.dmi' - const_holder.icon_state = "ripley0" - const_holder.density = TRUE - const_holder.overlays.len = 0 - qdel(src) - return - - -/datum/construction/reversible/mecha/ripley - result = "/obj/mecha/working/ripley" - taskpath = /datum/job_objective/make_ripley - steps = list( - //1 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "External armor is wrenched."), - //2 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "External armor is installed."), - //3 - list( - "key" = /obj/item/stack/sheet/plasteel, - "backkey" = TOOL_WELDER, - "desc" = "Internal armor is welded."), - //4 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched."), - //5 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "Internal armor is installed."), - //6 - list( - "key" = /obj/item/stack/sheet/metal, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured."), - //7 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed."), - //8 - list( - "key" = /obj/item/circuitboard/mecha/ripley/peripherals, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured."), - //9 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Central control module is installed."), - //10 - list( - "key" = /obj/item/circuitboard/mecha/ripley/main, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted."), - //11 - list( - "key" = /obj/item/wirecutters, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added."), - //12 - list( - "key" = /obj/item/stack/cable_coil, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active."), - //13 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected."), - //14 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected.") - ) - -/datum/construction/reversible/mecha/ripley/action(atom/used_atom,mob/user as mob) - return check_step(used_atom,user) - -/datum/construction/reversible/mecha/ripley/custom_action(index, diff, atom/used_atom, mob/user) - if(!..()) - return 0 - - //TODO: better messages. - switch(index) - if(14) - user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") - holder.icon_state = "ripley1" - if(13) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") - holder.icon_state = "ripley2" - else - user.visible_message("[user] disconnects the [holder] hydraulic systems", "You disconnect the [holder] hydraulic systems.") - holder.icon_state = "ripley0" - if(12) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") - holder.icon_state = "ripley3" - else - user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") - holder.icon_state = "ripley1" - if(11) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") - holder.icon_state = "ripley4" - else - user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") - var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) - coil.amount = 4 - holder.icon_state = "ripley2" - if(10) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") - qdel(used_atom) - holder.icon_state = "ripley5" - else - user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") - holder.icon_state = "ripley3" - if(9) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - holder.icon_state = "ripley6" - else - user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") - new /obj/item/circuitboard/mecha/ripley/main(get_turf(holder)) - holder.icon_state = "ripley4" - if(8) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") - qdel(used_atom) - holder.icon_state = "ripley7" - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - holder.icon_state = "ripley5" - if(7) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - holder.icon_state = "ripley8" - else - user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") - new /obj/item/circuitboard/mecha/ripley/peripherals(get_turf(holder)) - holder.icon_state = "ripley6" - if(6) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the internal armor layer to the [holder].", "You install the internal armor layer to the [holder].") - holder.icon_state = "ripley9" - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - holder.icon_state = "ripley7" - if(5) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - holder.icon_state = "ripley10" - else - user.visible_message("[user] pries internal armor layer from the [holder].", "You pry internal armor layer from the [holder].") - var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder)) - MS.amount = 5 - holder.icon_state = "ripley8" - if(4) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the internal armor layer to the [holder].", "You weld the internal armor layer to the [holder].") - holder.icon_state = "ripley11" - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - holder.icon_state = "ripley9" - if(3) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the external reinforced armor layer to the [holder].", "You install the external reinforced armor layer to the [holder].") - holder.icon_state = "ripley12" - else - user.visible_message("[user] cuts the internal armor layer from the [holder].", "You cut the internal armor layer from the [holder].") - holder.icon_state = "ripley10" - if(2) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") - holder.icon_state = "ripley13" - else - user.visible_message("[user] pries external armor layer from the [holder].", "You pry external armor layer from the [holder].") - var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) - MS.amount = 5 - holder.icon_state = "ripley11" - if(1) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the external armor layer to the [holder].", "You weld the external armor layer to the [holder].") - else - user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") - holder.icon_state = "ripley12" - return 1 - -/datum/construction/mecha/gygax_chassis - steps = list( - list("key" = /obj/item/mecha_parts/part/gygax_torso),//1 - list("key" = /obj/item/mecha_parts/part/gygax_left_arm),//2 - list("key" = /obj/item/mecha_parts/part/gygax_right_arm),//3 - list("key" = /obj/item/mecha_parts/part/gygax_left_leg),//4 - list("key" = /obj/item/mecha_parts/part/gygax_right_leg),//5 - list("key" = /obj/item/mecha_parts/part/gygax_head) - ) - -/datum/construction/mecha/gygax_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") - holder.overlays += used_atom.icon_state+"+o" - qdel(used_atom) - return 1 - -/datum/construction/mecha/gygax_chassis/action(atom/used_atom,mob/user as mob) - return check_all_steps(used_atom,user) - -/datum/construction/mecha/gygax_chassis/spawn_result(mob/user, result_name) - ..(user, "Gygax") - var/obj/item/mecha_parts/chassis/const_holder = holder - const_holder.construct = new /datum/construction/reversible/mecha/gygax(const_holder) - const_holder.icon = 'icons/mecha/mech_construction.dmi' - const_holder.icon_state = "gygax0" - const_holder.density = TRUE - qdel(src) - return - - -/datum/construction/reversible/mecha/gygax - result = "/obj/mecha/combat/gygax" - steps = list( - //1 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "External armor is wrenched."), - //2 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "External armor is installed."), - //3 - list( - "key" = /obj/item/mecha_parts/part/gygax_armour, - "backkey" = TOOL_WELDER, - "desc" = "Internal armor is welded."), - //4 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched."), - //5 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "Internal armor is installed."), - //6 - list( - "key" = /obj/item/stack/sheet/metal, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Mech power core is secured."), - //7 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Mech power core is installed."), - //8 - list( - "key" = /obj/item/mecha_parts/core, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Mech power core is secured."), - //9 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Advanced scanner module is installed."), - //10 - list( - "key" = /obj/item/stock_parts/scanning_module/adv, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Scanning module is secured."), - //11 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Scanning module is installed."), - //12 - list( - "key" = /obj/item/circuitboard/mecha/gygax/targeting, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured."), - //13 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed."), - //14 - list( - "key" = /obj/item/circuitboard/mecha/gygax/peripherals, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured."), - //15 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Central control module is installed."), - //16 - list( - "key" = /obj/item/circuitboard/mecha/gygax/main, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted."), - //17 - list( - "key" = /obj/item/wirecutters, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added."), - //18 - list( - "key" = /obj/item/stack/cable_coil, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active."), - //19 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected."), - //20 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected.") - ) - -/datum/construction/reversible/mecha/gygax/action(atom/used_atom,mob/user as mob) - return check_step(used_atom,user) - -/datum/construction/reversible/mecha/gygax/custom_action(index, diff, atom/used_atom, mob/user) - if(!..()) - return 0 - - //TODO: better messages. - switch(index) - if(20) - user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") - holder.icon_state = "gygax1" - if(19) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") - holder.icon_state = "gygax2" - else - user.visible_message("[user] disconnects the [holder] hydraulic systems.", "You disconnect the [holder] hydraulic systems.") - holder.icon_state = "gygax0" - if(18) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") - holder.icon_state = "gygax3" - else - user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") - holder.icon_state = "gygax1" - if(17) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") - holder.icon_state = "gygax4" - else - user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") - var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) - coil.amount = 4 - holder.icon_state = "gygax2" - if(16) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") - qdel(used_atom) - holder.icon_state = "gygax5" - else - user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") - holder.icon_state = "gygax3" - if(15) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - holder.icon_state = "gygax6" - else - user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") - new /obj/item/circuitboard/mecha/gygax/main(get_turf(holder)) - holder.icon_state = "gygax4" - if(14) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") - qdel(used_atom) - holder.icon_state = "gygax7" - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - holder.icon_state = "gygax5" - if(13) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - holder.icon_state = "gygax8" - else - user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") - new /obj/item/circuitboard/mecha/gygax/peripherals(get_turf(holder)) - holder.icon_state = "gygax6" - if(12) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the weapon control module into the [holder].", "You install the weapon control module into the [holder].") - qdel(used_atom) - holder.icon_state = "gygax9" - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - holder.icon_state = "gygax7" - if(11) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") - holder.icon_state = "gygax10" - else - user.visible_message("[user] removes the weapon control module from the [holder].", "You remove the weapon control module from the [holder].") - new /obj/item/circuitboard/mecha/gygax/targeting(get_turf(holder)) - holder.icon_state = "gygax8" - if(10) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs advanced scanner module to the [holder].", "You install advanced scanner module to the [holder].") - qdel(used_atom) - holder.icon_state = "gygax11" - else - user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") - holder.icon_state = "gygax9" - if(9) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the advanced scanner module.", "You secure the advanced scanner module.") - holder.icon_state = "gygax12" - else - user.visible_message("[user] removes the advanced scanner module from the [holder].", "You remove the advanced scanner module from the [holder].") - new /obj/item/stock_parts/scanning_module/adv(get_turf(holder)) - holder.icon_state = "gygax10" - if(8) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs a mech power core into the [holder].", "You install a mech power core into the [holder].") - qdel(used_atom) - holder.icon_state = "gygax13" - else - user.visible_message("[user] unfastens the advanced scanner module.", "You unfasten the advanced scanner module.") - holder.icon_state = "gygax11" - if(7) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the mech power core.", "You secure the mech power core.") - holder.icon_state = "gygax14" - else - user.visible_message("[user] removes the mech power core from the [holder].", "You remove the mech power core from the [holder].") - new /obj/item/mecha_parts/core(get_turf(holder)) - holder.icon_state = "gygax12" - if(6) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the internal armor layer to the [holder].", "You install the internal armor layer to the [holder].") - holder.icon_state = "gygax15" - else - user.visible_message("[user] unfastens the advanced capacitor.", "You unfasten the advanced capacitor.") - holder.icon_state = "gygax13" - if(5) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - holder.icon_state = "gygax16" - else - user.visible_message("[user] pries the internal armor layer from the [holder].", "You pry the internal armor layer from the [holder].") - var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder)) - MS.amount = 5 - holder.icon_state = "gygax14" - if(4) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the internal armor layer to the [holder].", "You weld the internal armor layer to the [holder].") - holder.icon_state = "gygax17" - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - holder.icon_state = "gygax15" - if(3) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the Gygax Armor Plates to the [holder].", "You install the Gygax Armor Plates to the [holder].") - qdel(used_atom) - holder.icon_state = "gygax18" - else - user.visible_message("[user] cuts the internal armor layer from the [holder].", "You cut the internal armor layer from the [holder].") - holder.icon_state = "gygax16" - if(2) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the Gygax Armor Plates.", "You secure the Gygax Armor Plates.") - holder.icon_state = "gygax19" - else - user.visible_message("[user] pries the Gygax Armor Plates from the [holder].", "You pry the Gygax Armor Plates from the [holder].") - new /obj/item/mecha_parts/part/gygax_armour(get_turf(holder)) - holder.icon_state = "gygax17" - if(1) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the Gygax Armor Plates to the [holder].", "You weld the Gygax Armor Plates to the [holder].") - else - user.visible_message("[user] unfastens the Gygax Armor Plates.", "You unfasten the Gygax Armor Plates.") - holder.icon_state = "gygax18" - return 1 - -/datum/construction/mecha/firefighter_chassis - steps = list( - list("key" = /obj/item/mecha_parts/part/ripley_torso),//1 - list("key" = /obj/item/mecha_parts/part/ripley_left_arm),//2 - list("key" = /obj/item/mecha_parts/part/ripley_right_arm),//3 - list("key" = /obj/item/mecha_parts/part/ripley_left_leg),//4 - list("key" = /obj/item/mecha_parts/part/ripley_right_leg),//5 - list("key" = /obj/item/clothing/suit/fire)//6 - ) - -/datum/construction/mecha/firefighter_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") - holder.overlays += used_atom.icon_state+"+o" - qdel(used_atom) - return 1 - -/datum/construction/mecha/firefighter_chassis/action(atom/used_atom,mob/user as mob) - return check_all_steps(used_atom,user) - -/datum/construction/mecha/firefighter_chassis/spawn_result(mob/user, result_name) - ..(user, "Firefighter Ripley") - var/obj/item/mecha_parts/chassis/const_holder = holder - const_holder.construct = new /datum/construction/reversible/mecha/firefighter(const_holder) - const_holder.icon = 'icons/mecha/mech_construction.dmi' - const_holder.icon_state = "fireripley0" - const_holder.density = TRUE - qdel(src) - return - - -/datum/construction/reversible/mecha/firefighter - result = "/obj/mecha/working/ripley/firefighter" - taskpath = /datum/job_objective/make_ripley - steps = list( - //1 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "External armor is wrenched."), - //2 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "External armor is installed."), - //3 - list( - "key" = /obj/item/stack/sheet/plasteel, - "backkey" = TOOL_CROWBAR, - "desc" = "External armor is being installed."), - //4 - list( - "key" = /obj/item/stack/sheet/plasteel, - "backkey" = TOOL_WELDER, - "desc" = "Internal armor is welded."), - //5 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched."), - //6 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "Internal armor is installed."), - - //7 - list( - "key" = /obj/item/stack/sheet/plasteel, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured."), - //8 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed."), - //9 - list( - "key" = /obj/item/circuitboard/mecha/ripley/peripherals, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured."), - //10 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Central control module is installed."), - //11 - list( - "key" = /obj/item/circuitboard/mecha/ripley/main, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted."), - //12 - list( - "key" = /obj/item/wirecutters, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added."), - //13 - list( - "key" = /obj/item/stack/cable_coil, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active."), - //14 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected."), - //15 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected.") - ) - -/datum/construction/reversible/mecha/firefighter/action(atom/used_atom,mob/user as mob) - return check_step(used_atom,user) - -/datum/construction/reversible/mecha/firefighter/custom_action(index, diff, atom/used_atom, mob/user) - if(!..()) - return 0 - - //TODO: better messages. - switch(index) - if(15) - user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") - holder.icon_state = "fireripley1" - if(14) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") - holder.icon_state = "fireripley2" - else - user.visible_message("[user] disconnects the [holder] hydraulic systems", "You disconnect the [holder] hydraulic systems.") - holder.icon_state = "fireripley0" - if(13) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") - holder.icon_state = "fireripley3" - else - user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") - holder.icon_state = "fireripley1" - if(12) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") - holder.icon_state = "fireripley4" - else - user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") - var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) - coil.amount = 4 - holder.icon_state = "fireripley2" - if(11) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") - qdel(used_atom) - holder.icon_state = "fireripley5" - else - user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") - holder.icon_state = "fireripley3" - if(10) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - holder.icon_state = "fireripley6" - else - user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") - new /obj/item/circuitboard/mecha/ripley/main(get_turf(holder)) - holder.icon_state = "fireripley4" - if(9) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") - qdel(used_atom) - holder.icon_state = "fireripley7" - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - holder.icon_state = "fireripley5" - if(8) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - holder.icon_state = "fireripley8" - else - user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") - new /obj/item/circuitboard/mecha/ripley/peripherals(get_turf(holder)) - holder.icon_state = "fireripley6" - if(7) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the internal armor layer to the [holder].", "You install the internal armor layer to the [holder].") - holder.icon_state = "fireripley9" - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - holder.icon_state = "fireripley7" - - if(6) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - holder.icon_state = "fireripley10" - else - user.visible_message("[user] pries internal armor layer from the [holder].", "You pry internal armor layer from the [holder].") - var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) - MS.amount = 5 - holder.icon_state = "fireripley8" - if(5) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the internal armor layer to the [holder].", "You weld the internal armor layer to the [holder].") - holder.icon_state = "fireripley11" - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - holder.icon_state = "fireripley9" - if(4) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] starts to install the external armor layer to the [holder].", "You start to install the external armor layer to the [holder].") - holder.icon_state = "fireripley12" - else - user.visible_message("[user] cuts the internal armor layer from the [holder].", "You cut the internal armor layer from the [holder].") - holder.icon_state = "fireripley10" - if(3) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the external reinforced armor layer to the [holder].", "You install the external reinforced armor layer to the [holder].") - holder.icon_state = "fireripley13" - else - user.visible_message("[user] removes the external armor from the [holder].", "You remove the external armor from the [holder].") - var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) - MS.amount = 5 - holder.icon_state = "fireripley11" - if(2) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") - holder.icon_state = "fireripley14" - else - user.visible_message("[user] pries external armor layer from the [holder].", "You pry external armor layer from the [holder].") - var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) - MS.amount = 5 - holder.icon_state = "fireripley12" - if(1) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the external armor layer to the [holder].", "You weld the external armor layer to the [holder].") - else - user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") - holder.icon_state = "fireripley13" - return 1 - -/datum/construction/mecha/honker_chassis - steps = list( - list("key" = /obj/item/mecha_parts/part/honker_torso),//1 - list("key" = /obj/item/mecha_parts/part/honker_left_arm),//2 - list("key" = /obj/item/mecha_parts/part/honker_right_arm),//3 - list("key" = /obj/item/mecha_parts/part/honker_left_leg),//4 - list("key" = /obj/item/mecha_parts/part/honker_right_leg),//5 - list("key" = /obj/item/mecha_parts/part/honker_head) - ) - -/datum/construction/mecha/honker_chassis/action(atom/used_atom,mob/user as mob) - return check_all_steps(used_atom,user) - -/datum/construction/mecha/honker_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") - holder.overlays += used_atom.icon_state+"+o" - qdel(used_atom) - return 1 - -/datum/construction/mecha/honker_chassis/spawn_result(mob/user, result_name) - ..(user, "Honker") - var/obj/item/mecha_parts/chassis/const_holder = holder - const_holder.construct = new /datum/construction/reversible/mecha/honker(const_holder) - const_holder.density = TRUE - qdel(src) - return - - -/datum/construction/reversible/mecha/honker - result = "/obj/mecha/combat/honker" - steps = list( - list("key" = /obj/item/bikehorn),//1 - list("key" = /obj/item/clothing/shoes/clown_shoes),//2 - list("key" = /obj/item/bikehorn),//3 - list("key" = /obj/item/clothing/mask/gas/clown_hat),//4 - list("key" = /obj/item/bikehorn),//5 - list("key" = /obj/item/circuitboard/mecha/honker/targeting),//6 - list("key" = /obj/item/bikehorn),//7 - list("key" = /obj/item/circuitboard/mecha/honker/peripherals),//8 - list("key" = /obj/item/bikehorn),//9 - list("key" = /obj/item/circuitboard/mecha/honker/main),//10 - list("key" = /obj/item/bikehorn),//11 - ) - -/datum/construction/reversible/mecha/honker/action(atom/used_atom,mob/user as mob) - return check_step(used_atom,user) - -/datum/construction/reversible/mecha/honker/custom_action(index, diff, atom/used_atom, mob/user) - if(!..()) - return 0 - - if(istype(used_atom, /obj/item/bikehorn)) - playsound(holder, 'sound/items/bikehorn.ogg', 50, 1) - user.visible_message("HONK!") - - //TODO: better messages. - switch(index) - if(10) - user.visible_message("[user] installs the central control module into the [holder].", "You install the central control module into the [holder].") - qdel(used_atom) - if(8) - user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") - qdel(used_atom) - if(6) - user.visible_message("[user] installs the weapon control module into the [holder].", "You install the weapon control module into the [holder].") - qdel(used_atom) - if(4) - user.visible_message("[user] puts clown wig and mask on the [holder].", "You put clown wig and mask on the [holder].") - qdel(used_atom) - if(2) - user.visible_message("[user] puts clown boots on the [holder].", "You put clown boots on the [holder].") - qdel(used_atom) - return 1 - -/datum/construction/mecha/reticence_chassis - steps = list( - list("key" = /obj/item/mecha_parts/part/reticence_torso),//1 - list("key" = /obj/item/mecha_parts/part/reticence_left_arm),//2 - list("key" = /obj/item/mecha_parts/part/reticence_right_arm),//3 - list("key" = /obj/item/mecha_parts/part/reticence_left_leg),//4 - list("key" = /obj/item/mecha_parts/part/reticence_right_leg),//5 - list("key" = /obj/item/mecha_parts/part/reticence_head) - ) - -/datum/construction/mecha/reticence_chassis/action(atom/used_atom,mob/user as mob) - return check_all_steps(used_atom,user) - -/datum/construction/mecha/reticence_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") - holder.overlays += used_atom.icon_state + "+o" - qdel(used_atom) - return 1 - -/datum/construction/mecha/reticence_chassis/spawn_result(mob/user, result_name) - ..(user, "Reticence") - var/obj/item/mecha_parts/chassis/const_holder = holder - const_holder.construct = new /datum/construction/reversible/mecha/reticence(const_holder) - const_holder.density = TRUE - qdel(src) - return - -/datum/construction/reversible/mecha/reticence - result = "/obj/mecha/combat/reticence" - steps = list( - list("key" = /obj/effect/dummy/mecha_emote_step),//1 - list("key" = /obj/item/clothing/suit/suspenders),//2 - list("key" = /obj/effect/dummy/mecha_emote_step),//3 - list("key" = /obj/item/clothing/mask/gas/mime),//4 - list("key" = /obj/effect/dummy/mecha_emote_step),//5 - list("key" = /obj/item/clothing/head/beret),//6 - list("key" = /obj/item/circuitboard/mecha/reticence/targeting),//7 - list("key" = /obj/item/circuitboard/mecha/reticence/peripherals),//8 - list("key" = /obj/item/circuitboard/mecha/reticence/main),//9 - ) - -/datum/construction/reversible/mecha/reticence/action(atom/used_atom,mob/user) - return check_step(used_atom,user) - -/datum/construction/reversible/mecha/reticence/custom_action(index, diff, atom/used_atom, mob/user) - if(!..()) - return 0 - - if(istype(used_atom, /obj/effect/dummy/mecha_emote_step)) - var/obj/effect/dummy/mecha_emote_step/E = used_atom - holder.visible_message("[holder] likewise [E.emote]") - qdel(used_atom) - - //TODO: better messages. - switch(index) - if(9) - user.visible_message("[user] installs the central control module into the [holder].", "You install the central control module into the [holder].") - qdel(used_atom) - if(8) - user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") - qdel(used_atom) - if(7) - user.visible_message("[user] installs the weapon control module into the [holder].", "You install the weapon control module into the [holder].") - qdel(used_atom) - if(6) - user.visible_message("[user] puts beret on the [holder].", "You put beret on the [holder].") - qdel(used_atom) - if(4) - user.visible_message("[user] puts mime mask on the [holder].", "You put mime mask on the [holder].") - qdel(used_atom) - if(2) - user.visible_message("[user] puts suspenders on the [holder].", "You put suspenders on the [holder].") - qdel(used_atom) - return 1 - - -/datum/construction/mecha/durand_chassis - steps = list( - list("key" = /obj/item/mecha_parts/part/durand_torso),//1 - list("key" = /obj/item/mecha_parts/part/durand_left_arm),//2 - list("key" = /obj/item/mecha_parts/part/durand_right_arm),//3 - list("key" = /obj/item/mecha_parts/part/durand_left_leg),//4 - list("key" = /obj/item/mecha_parts/part/durand_right_leg),//5 - list("key" = /obj/item/mecha_parts/part/durand_head) - ) - -/datum/construction/mecha/durand_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") - holder.overlays += used_atom.icon_state+"+o" - qdel(used_atom) - return 1 - -/datum/construction/mecha/durand_chassis/action(atom/used_atom,mob/user as mob) - return check_all_steps(used_atom,user) - -/datum/construction/mecha/durand_chassis/spawn_result(mob/user, result_name) - ..(user, "Durand") - var/obj/item/mecha_parts/chassis/const_holder = holder - const_holder.construct = new /datum/construction/reversible/mecha/durand(const_holder) - const_holder.icon = 'icons/mecha/mech_construction.dmi' - const_holder.icon_state = "durand0" - const_holder.density = TRUE - qdel(src) - return - -/datum/construction/reversible/mecha/durand - result = "/obj/mecha/combat/durand" - steps = list( - //1 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "External armor is wrenched."), - //2 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "External armor is installed."), - //3 - list( - "key" = /obj/item/mecha_parts/part/durand_armor, - "backkey" = TOOL_WELDER, - "desc" = "Internal armor is welded."), - //4 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched."), - //5 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "Internal armor is installed."), - //6 - list( - "key" = /obj/item/stack/sheet/metal, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Mech power core is secured."), - //7 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Mech power core is installed."), - //8 - list( - "key" = /obj/item/mecha_parts/core, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Phasic scanner module is secured."), - //9 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Phasic scanner module is installed."), - //10 - list( - "key" = /obj/item/stock_parts/scanning_module/phasic, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Scanning module is secured."), - //11 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Scanning module is installed."), - //12 - list( - "key" = /obj/item/circuitboard/mecha/durand/targeting, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured."), - //13 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed."), - //14 - list( - "key" = /obj/item/circuitboard/mecha/durand/peripherals, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured."), - //15 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Central control module is installed."), - //16 - list( - "key" = /obj/item/circuitboard/mecha/durand/main, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted."), - //17 - list( - "key" = /obj/item/wirecutters, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added."), - //18 - list( - "key" = /obj/item/stack/cable_coil, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active."), - //19 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected."), - //20 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected.") - ) - - -/datum/construction/reversible/mecha/durand/action(atom/used_atom,mob/user as mob) - return check_step(used_atom,user) - -/datum/construction/reversible/mecha/durand/custom_action(index, diff, atom/used_atom, mob/user) - if(!..()) - return 0 - - //TODO: better messages. - switch(index) - if(20) - user.visible_message("[user] connects the [holder] hydraulic systems.", "You connect the [holder] hydraulic systems.") - holder.icon_state = "durand1" - if(19) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") - holder.icon_state = "durand2" - else - user.visible_message("[user] disconnects the [holder] hydraulic systems.", "You disconnect the [holder] hydraulic systems.") - holder.icon_state = "durand0" - if(18) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") - holder.icon_state = "durand3" - else - user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") - holder.icon_state = "durand1" - if(17) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") - holder.icon_state = "durand4" - else - user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") - var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) - coil.amount = 4 - holder.icon_state = "durand2" - if(16) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") - qdel(used_atom) - holder.icon_state = "durand5" - else - user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") - holder.icon_state = "durand3" - if(15) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - holder.icon_state = "durand6" - else - user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") - new /obj/item/circuitboard/mecha/durand/main(get_turf(holder)) - holder.icon_state = "durand4" - if(14) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") - qdel(used_atom) - holder.icon_state = "durand7" - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - holder.icon_state = "durand5" - if(13) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - holder.icon_state = "durand8" - else - user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") - new /obj/item/circuitboard/mecha/durand/peripherals(get_turf(holder)) - holder.icon_state = "durand6" - if(12) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the weapon control module into the [holder].", "You install the weapon control module into the [holder].") - qdel(used_atom) - holder.icon_state = "durand9" - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - holder.icon_state = "durand7" - if(11) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") - holder.icon_state = "durand10" - else - user.visible_message("[user] removes the weapon control module from the [holder].", "You remove the weapon control module from the [holder].") - new /obj/item/circuitboard/mecha/durand/targeting(get_turf(holder)) - holder.icon_state = "durand8" - if(10) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs phasic scanner module to the [holder].", "You install phasic scanner module to the [holder].") - qdel(used_atom) - holder.icon_state = "durand11" - else - user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") - holder.icon_state = "durand9" - if(9) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the phasic scanner module.", "You secure the phasic scanner module.") - holder.icon_state = "durand12" - else - user.visible_message("[user] removes the phasic scanner module from the [holder].", "You remove the phasic scanner module from the [holder].") - new /obj/item/stock_parts/scanning_module/phasic(get_turf(holder)) - holder.icon_state = "durand10" - if(8) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the mech power core to the [holder].", "You install the mech power core to the [holder].") - qdel(used_atom) - holder.icon_state = "durand13" - else - user.visible_message("[user] unfastens the phasic scanner module.", "You unfasten the phasic scanner module.") - holder.icon_state = "durand11" - if(7) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the mech power core.", "You secure the mech power core.") - holder.icon_state = "durand14" - else - user.visible_message("[user] removes the mech power core from the [holder].", "You remove the mech power core from the [holder].") - new /obj/item/mecha_parts/core(get_turf(holder)) - holder.icon_state = "durand12" - if(6) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the internal armor layer to the [holder].", "You install the internal armor layer to the [holder].") - holder.icon_state = "durand15" - else - user.visible_message("[user] unfastens the mech power core.", "You unfasten the mech power core.") - holder.icon_state = "durand13" - if(5) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - holder.icon_state = "durand16" - else - user.visible_message("[user] pries the internal armor layer from the [holder].", "You pry the internal armor layer from the [holder].") - var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder)) - MS.amount = 5 - holder.icon_state = "durand14" - if(4) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the internal armor layer to the [holder].", "You weld the internal armor layer to the [holder].") - holder.icon_state = "durand17" - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - holder.icon_state = "durand15" - if(3) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the Durand Armor Plates to the [holder].", "You install the Durand Armor Plates to the [holder].") - qdel(used_atom) - holder.icon_state = "durand18" - else - user.visible_message("[user] cuts the internal armor layer from the [holder].", "You cut the internal armor layer from the [holder].") - holder.icon_state = "durand16" - if(2) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the Durand Armor Plates.", "You secure the Durand Armor Plates.") - holder.icon_state = "durand19" - else - user.visible_message("[user] pries the Durand Armor Plates from the [holder].", "You pry the Durand Armor Plates from the [holder].") - new /obj/item/mecha_parts/part/durand_armor(get_turf(holder)) - holder.icon_state = "durand17" - if(1) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the Durand Armor Plates to the [holder].", "You weld the Durand Armor Plates to the [holder].") - else - user.visible_message("[user] unfastens the Durand Armor Plates.", "You unfasten the Durand Armor Plates.") - holder.icon_state = "durand18" - return 1 - -//PHAZON - -/datum/construction/mecha/phazon_chassis - result = "/obj/mecha/combat/phazon" - steps = list( - list("key" = /obj/item/mecha_parts/part/phazon_torso), //1 - list("key" = /obj/item/mecha_parts/part/phazon_left_arm), //2 - list("key" = /obj/item/mecha_parts/part/phazon_right_arm), //3 - list("key" = /obj/item/mecha_parts/part/phazon_left_leg), //4 - list("key" = /obj/item/mecha_parts/part/phazon_right_leg), //5 - list("key" = /obj/item/mecha_parts/part/phazon_head) - ) - -/datum/construction/mecha/phazon_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") - holder.overlays += used_atom.icon_state+"+o" - qdel(used_atom) - return 1 - -/datum/construction/mecha/phazon_chassis/action(atom/used_atom,mob/user as mob) - return check_all_steps(used_atom,user) - -/datum/construction/mecha/phazon_chassis/spawn_result(mob/user, result_name) - ..(user, "Phazon") - var/obj/item/mecha_parts/chassis/const_holder = holder - const_holder.construct = new /datum/construction/reversible/mecha/phazon(const_holder) - const_holder.icon = 'icons/mecha/mech_construction.dmi' - const_holder.icon_state = "phazon0" - const_holder.density = TRUE - qdel(src) - return - -/datum/construction/reversible/mecha/phazon - result = "/obj/mecha/combat/phazon" - steps = list( - //1 - list( - "key" = /obj/item/assembly/signaler/anomaly/bluespace, - "backkey" = null, //Cannot remove the anomaly core once it's in - "desc" = "Anomaly core socket is open and awaiting connection."), - //2 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "External armor is wrenched."), - //3 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "External armor is installed."), - //4 - list( - "key" = /obj/item/mecha_parts/part/phazon_armor, - "backkey" = TOOL_WELDER, - "desc" = "Phase armor is welded."), - //5 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "Phase armor is wrenched."), - //6 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "Phase armor is installed."), - //7 - list( - "key" = /obj/item/stack/sheet/plasteel, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The bluespace crystal is engaged."), - //8 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = /obj/item/wirecutters, - "desc" = "The bluespace crystal is connected."), - //9 - list( - "key" = /obj/item/stack/cable_coil, - "backkey" = TOOL_CROWBAR, - "desc" = "The bluespace crystal is installed."), - //10 - list( - "key" = /obj/item/stack/ore/bluespace_crystal, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Super capacitor is secured."), - //11 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Super capacitor is installed."), - //12 - list( - "key" = /obj/item/stock_parts/capacitor/super, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Phasic scanner module is secured."), - //13 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Phasic scanner module is installed."), - //14 - list( - "key" = /obj/item/stock_parts/scanning_module/phasic, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Scanning module is secured."), - //15 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Scanning module is installed."), - //16 - list( - "key" = /obj/item/circuitboard/mecha/phazon/targeting, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured."), - //17 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed"), - //18 - list( - "key" = /obj/item/circuitboard/mecha/phazon/peripherals, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured."), - //19 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Central control module is installed."), - //20 - list( - "key" = /obj/item/circuitboard/mecha/phazon/main, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted."), - //21 - list( - "key" = /obj/item/wirecutters, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added."), - //22 - list( - "key" = /obj/item/stack/cable_coil, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active."), - //23 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected."), - //24 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected.") - ) - - -/datum/construction/reversible/mecha/phazon/action(atom/used_atom,mob/user as mob) - return check_step(used_atom,user) - -/datum/construction/reversible/mecha/phazon/custom_action(index, diff, atom/used_atom, mob/user) - if(!..()) - return 0 - - //TODO: better messages. - switch(index) - if(24) - user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") - holder.icon_state = "phazon1" - if(23) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") - holder.icon_state = "phazon2" - else - user.visible_message("[user] disconnects the [holder] hydraulic systems", "You disconnect the [holder] hydraulic systems.") - holder.icon_state = "phazon0" - if(22) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") - holder.icon_state = "phazon3" - else - user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") - holder.icon_state = "phazon1" - if(21) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") - holder.icon_state = "phazon4" - else - user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") - var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) - coil.amount = 4 - holder.icon_state = "phazon2" - if(20) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") - qdel(used_atom) - holder.icon_state = "phazon5" - else - user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") - holder.icon_state = "phazon3" - if(19) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - holder.icon_state = "phazon6" - else - user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") - new /obj/item/circuitboard/mecha/phazon/main(get_turf(holder)) - holder.icon_state = "phazon4" - if(18) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") - qdel(used_atom) - holder.icon_state = "phazon7" - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - holder.icon_state = "phazon5" - if(17) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - holder.icon_state = "phazon8" - else - user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") - new /obj/item/circuitboard/mecha/phazon/peripherals(get_turf(holder)) - holder.icon_state = "phazon6" - if(16) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the weapon control module into the [holder].", "You install the weapon control module into the [holder].") - qdel(used_atom) - holder.icon_state = "phazon9" - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - holder.icon_state = "phazon7" - if(15) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") - holder.icon_state = "phazon10" - else - user.visible_message("[user] removes the weapon control module from the [holder].", "You remove the weapon control module from the [holder].") - new /obj/item/circuitboard/mecha/phazon/targeting(get_turf(holder)) - holder.icon_state = "phazon8" - if(14) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs phasic scanner module to the [holder].", "You install phasic scanner module to the [holder].") - qdel(used_atom) - holder.icon_state = "phazon11" - else - user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") - holder.icon_state = "phazon9" - if(13) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the phasic scanner module.", "You secure the phasic scanner module.") - holder.icon_state = "phazon12" - else - user.visible_message("[user] removes the phasic scanner module from the [holder].", "You remove the phasic scanner module from the [holder].") - new /obj/item/stock_parts/scanning_module/phasic(get_turf(holder)) - holder.icon_state = "phazon10" - if(12) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs super capacitor to the [holder].", "You install super capacitor to the [holder].") - qdel(used_atom) - holder.icon_state = "phazon13" - else - user.visible_message("[user] unfastens the phasic scanner module.", "You unfasten the phasic scanner module.") - holder.icon_state = "phazon11" - if(11) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the super capacitor.", "You secure the super capacitor.") - holder.icon_state = "phazon14" - else - user.visible_message("[user] removes the super capacitor from the [holder].", "You remove the super capacitor from the [holder].") - new /obj/item/stock_parts/capacitor/super(get_turf(holder)) - holder.icon_state = "phazon12" - if(10) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the bluespace crystal.", "You install the bluespace crystals.") - holder.icon_state = "phazon15" - else - user.visible_message("[user] unsecures the super capacitor from the [holder].", "You unsecure the super capacitor from the [holder].") - holder.icon_state = "phazon13" - if(9) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] connects the bluespace crystal.", "You connect the bluespace crystals.") - holder.icon_state = "phazon16" - else - user.visible_message("[user] removes the bluespace crystal from the [holder].", "You remove the bluespace crystal from the [holder].") - new /obj/item/stack/ore/bluespace_crystal(get_turf(holder), 5) - holder.icon_state = "phazon14" - if(8) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] engages the bluespace crystal.", "You engage the bluespace crystals.") - holder.icon_state = "phazon17" - else - user.visible_message("[user] disconnects the bluespace crystal from the [holder].", "You disconnect the bluespace crystal from the [holder].") - holder.icon_state = "phazon15" - if(7) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the phase armor layer to the [holder].", "You install the phase armor layer to the [holder].") - holder.icon_state = "phazon18" - else - user.visible_message("[user] disengages the bluespace crystal.", "You disengage the bluespace crystals.") - holder.icon_state = "phazon16" - if(6) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the phase armor layer.", "You secure the phase armor layer.") - holder.icon_state = "phazon19" - else - user.visible_message("[user] pries the phase armor layer from the [holder].", "You pry the phase armor layer from the [holder].") - var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) - MS.amount = 5 - holder.icon_state = "phazon17" - if(5) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the phase armor layer to the [holder].", "You weld the phase armor layer to the [holder].") - holder.icon_state = "phazon20" - else - user.visible_message("[user] unfastens the phase armor layer.", "You unfasten the phase armor layer.") - holder.icon_state = "phazon18" - if(4) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs Phazon Armor Plates to the [holder].", "You install Phazon Armor Plates to the [holder].") - qdel(used_atom) - holder.icon_state = "phazon21" - else - user.visible_message("[user] cuts phase armor layer from the [holder].", "You cut the phase armor layer from the [holder].") - holder.icon_state = "phazon19" - if(3) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures Phazon Armor Plates.", "You secure Phazon Armor Plates.") - holder.icon_state = "phazon22" - else - user.visible_message("[user] pries Phazon Armor Plates from the [holder].", "You pry Phazon Armor Plates from the [holder].") - new /obj/item/mecha_parts/part/phazon_armor(get_turf(holder)) - holder.icon_state = "phazon20" - if(2) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds Phazon Armor Plates to the [holder].", "You weld Phazon Armor Plates to the [holder].") - else - user.visible_message("[user] unfastens Phazon Armor Plates.", "You unfasten Phazon Armor Plates.") - holder.icon_state = "phazon21" - if(1) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] carefully inserts the anomaly core into \the [holder] and secures it.", "You slowly place the anomaly core into its socket and close its chamber.") - qdel(used_atom) - return 1 - -//ODYSSEUS - -/datum/construction/mecha/odysseus_chassis - steps = list(list("key"=/obj/item/mecha_parts/part/odysseus_torso),//1 - list("key"=/obj/item/mecha_parts/part/odysseus_head),//2 - list("key"=/obj/item/mecha_parts/part/odysseus_left_arm),//3 - list("key"=/obj/item/mecha_parts/part/odysseus_right_arm),//4 - list("key"=/obj/item/mecha_parts/part/odysseus_left_leg),//5 - list("key"=/obj/item/mecha_parts/part/odysseus_right_leg)//6 - ) - -/datum/construction/mecha/odysseus_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") - holder.overlays += used_atom.icon_state+"+o" - qdel(used_atom) - return 1 - -/datum/construction/mecha/odysseus_chassis/action(atom/used_atom,mob/user as mob) - return check_all_steps(used_atom,user) - -/datum/construction/mecha/odysseus_chassis/spawn_result(mob/user, result_name) - ..(user, "Odysseus") - var/obj/item/mecha_parts/chassis/const_holder = holder - const_holder.construct = new /datum/construction/reversible/mecha/odysseus(const_holder) - const_holder.icon = 'icons/mecha/mech_construction.dmi' - const_holder.icon_state = "odysseus0" - const_holder.density = TRUE - qdel(src) - return - - -/datum/construction/reversible/mecha/odysseus - result = "/obj/mecha/medical/odysseus" - steps = list( - //1 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "External armor is wrenched."), - //2 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "External armor is installed."), - //3 - list( - "key" = /obj/item/stack/sheet/plasteel, - "backkey" = TOOL_WELDER, - "desc" = "Internal armor is welded."), - //4 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched."), - //5 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "Internal armor is installed."), - //6 - list( - "key" = /obj/item/stack/sheet/metal, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured."), - //7 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed."), - //8 - list( - "key" = /obj/item/circuitboard/mecha/odysseus/peripherals, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured."), - //9 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Central control module is installed."), - //10 - list( - "key" = /obj/item/circuitboard/mecha/odysseus/main, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted."), - //11 - list( - "key" = /obj/item/wirecutters, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added."), - //12 - list( - "key" = /obj/item/stack/cable_coil, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active."), - //13 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected."), - //14 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected.") - ) - -/datum/construction/reversible/mecha/odysseus/action(atom/used_atom,mob/user as mob) - return check_step(used_atom,user) - -/datum/construction/reversible/mecha/odysseus/custom_action(index, diff, atom/used_atom, mob/user) - if(!..()) - return 0 - - //TODO: better messages. - switch(index) - if(14) - user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") - holder.icon_state = "odysseus1" - if(13) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") - holder.icon_state = "odysseus2" - else - user.visible_message("[user] disconnects the [holder] hydraulic systems", "You disconnect the [holder] hydraulic systems.") - holder.icon_state = "odysseus0" - if(12) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") - holder.icon_state = "odysseus3" - else - user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") - holder.icon_state = "odysseus1" - if(11) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") - holder.icon_state = "odysseus4" - else - user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") - var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) - coil.amount = 4 - holder.icon_state = "odysseus2" - if(10) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") - qdel(used_atom) - holder.icon_state = "odysseus5" - else - user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") - holder.icon_state = "odysseus3" - if(9) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - holder.icon_state = "odysseus6" - else - user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") - new /obj/item/circuitboard/mecha/odysseus/main(get_turf(holder)) - holder.icon_state = "odysseus4" - if(8) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") - qdel(used_atom) - holder.icon_state = "odysseus7" - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - holder.icon_state = "odysseus5" - if(7) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - holder.icon_state = "odysseus8" - else - user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") - new /obj/item/circuitboard/mecha/odysseus/peripherals(get_turf(holder)) - holder.icon_state = "odysseus6" - if(6) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the internal armor layer to the [holder].", "You install the internal armor layer to the [holder].") - holder.icon_state = "odysseus9" - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - holder.icon_state = "odysseus7" - if(5) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - holder.icon_state = "odysseus10" - else - user.visible_message("[user] pries internal armor layer from the [holder].", "You pry internal armor layer from the [holder].") - var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder)) - MS.amount = 5 - holder.icon_state = "odysseus8" - if(4) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the internal armor layer to the [holder].", "You weld the internal armor layer to the [holder].") - holder.icon_state = "odysseus11" - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - holder.icon_state = "odysseus9" - if(3) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs [used_atom] layer to the [holder].", "You install the external reinforced armor layer to the [holder].") - - holder.icon_state = "odysseus12" - else - user.visible_message("[user] cuts the internal armor layer from the [holder].", "You cut the internal armor layer from the [holder].") - holder.icon_state = "odysseus10" - if(2) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") - holder.icon_state = "odysseus13" - else - var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) - MS.amount = 5 - user.visible_message("[user] pries [MS] from the [holder].", "You pry [MS] from the [holder].") - holder.icon_state = "odysseus11" - if(1) - if(diff==CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the external armor layer to the [holder].", "You weld the external armor layer to the [holder].") - holder.icon_state = "odysseus14" - else - user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") - holder.icon_state = "odysseus12" - return 1 - -// NKARRDEM - -/datum/construction/mecha/nkarrdem_chassis - steps = list(list("key"=/obj/item/mecha_parts/part/nkarrdem_torso), // 1 - list("key"=/obj/item/mecha_parts/part/nkarrdem_head), // 2 - list("key"=/obj/item/mecha_parts/part/nkarrdem_left_arm), // 3 - list("key"=/obj/item/mecha_parts/part/nkarrdem_right_arm), // 4 - list("key"=/obj/item/mecha_parts/part/nkarrdem_left_leg), // 5 - list("key"=/obj/item/mecha_parts/part/nkarrdem_right_leg) // 6 - ) - -/datum/construction/mecha/nkarrdem_chassis/custom_action(step, atom/used_atom, mob/user) - user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") - holder.overlays += used_atom.icon_state + "+o" - qdel(used_atom) - return TRUE - -/datum/construction/mecha/nkarrdem_chassis/action(atom/used_atom,mob/user as mob) - return check_all_steps(used_atom,user) - -/datum/construction/mecha/nkarrdem_chassis/spawn_result(mob/user, result_name) - ..(user, "Nkarrdem") - var/obj/item/mecha_parts/chassis/const_holder = holder - const_holder.construct = new /datum/construction/reversible/mecha/nkarrdem(const_holder) - const_holder.icon = 'icons/mecha/mech_construction.dmi' - const_holder.icon_state = "nkarrdem0" - const_holder.density = TRUE - qdel(src) - -/datum/construction/reversible/mecha/nkarrdem - result = "/obj/mecha/nkarrdem" - steps = list( - //1 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "External armor is wrenched."), - //2 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "External armor is installed."), - //3 - list( - "key" = /obj/item/stack/sheet/plasteel, - "backkey" = TOOL_WELDER, - "desc" = "Internal armor is welded."), - //4 - list( - "key" = TOOL_WELDER, - "backkey" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched."), - //5 - list( - "key" = TOOL_WRENCH, - "backkey" = TOOL_CROWBAR, - "desc" = "Internal armor is installed."), - //6 - list( - "key" = /obj/item/stack/sheet/metal, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Floor buffer is secured."), - //7 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Floor buffer is installed."), - //8 - list( - "key" = /obj/item/borg/upgrade/floorbuffer, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured."), - //9 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed."), - //10 - list( - "key" = /obj/item/circuitboard/mecha/nkarrdem/peripherals, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured."), - - //11 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_CROWBAR, - "desc" = "Central control module is installed."), - //12 - list( - "key" = /obj/item/circuitboard/mecha/nkarrdem/main, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted."), - //13 - list( - "key" = /obj/item/wirecutters, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added."), - //14 - list( - "key" = /obj/item/stack/cable_coil, - "backkey" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active."), - //15 - list( - "key" = TOOL_SCREWDRIVER, - "backkey" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected."), - //16 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected.") - ) - -/datum/construction/reversible/mecha/nkarrdem/action(atom/used_atom, mob/user) - return check_step(used_atom,user) - -/datum/construction/reversible/mecha/nkarrdem/custom_action(index, diff, atom/used_atom, mob/user) - if(!..()) - return FALSE - - switch(index) - if(16) - user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") - holder.icon_state = "nkarrdem1" - if(15) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") - holder.icon_state = "nkarrdem2" - else - user.visible_message("[user] disconnects the [holder] hydraulic systems", "You disconnect the [holder] hydraulic systems.") - holder.icon_state = "nkarrdem0" - if(14) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") - holder.icon_state = "nkarrdem3" - else - user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") - holder.icon_state = "nkarrdem1" - if(13) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") - holder.icon_state = "nkarrdem4" - else - user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") - var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) - coil.amount = 4 - holder.icon_state = "nkarrdem2" - if(12) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") - qdel(used_atom) - holder.icon_state = "nkarrdem5" - else - user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") - holder.icon_state = "nkarrdem3" - if(11) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - holder.icon_state = "nkarrdem6" - else - user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") - new /obj/item/circuitboard/mecha/nkarrdem/main(get_turf(holder)) - holder.icon_state = "nkarrdem4" - if(10) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") - qdel(used_atom) - holder.icon_state = "nkarrdem7" - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - holder.icon_state = "nkarrdem5" - if(9) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - holder.icon_state = "nkarrdem8" - else - user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") - new /obj/item/circuitboard/mecha/nkarrdem/peripherals(get_turf(holder)) - holder.icon_state = "nkarrdem6" - if(8) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs a floor buffer into [holder].", "You install a floor buffer into [holder].") - qdel(used_atom) - holder.icon_state = "nkarrdem9" - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - holder.icon_state = "nkarrdem7" - if(7) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures a floor buffer into [holder].", "You secure the floor buffer into [holder].") - holder.icon_state = "nkarrdem10" - else - user.visible_message("[user] removes the floor buffer from the [holder].", "You unfasten the floor buffer from the [holder].") - new /obj/item/borg/upgrade/floorbuffer(get_turf(holder)) - holder.icon_state = "nkarrdem8" - if(6) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs the internal armor layer to the [holder].", "You install the internal armor layer to the [holder].") - holder.icon_state = "nkarrdem11" - else - user.visible_message("[user] unfastens the floor buffer.", "You unfasten the floor buffer.") - holder.icon_state = "nkarrdem9" - if(5) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - holder.icon_state = "nkarrdem12" - else - user.visible_message("[user] pries internal armor layer from the [holder].", "You pry internal armor layer from the [holder].") - var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder)) - MS.amount = 5 - holder.icon_state = "nkarrdem10" - if(4) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the internal armor layer to the [holder].", "You weld the internal armor layer to the [holder].") - holder.icon_state = "nkarrdem13" - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - holder.icon_state = "nkarrdem11" - if(3) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] installs [used_atom] layer to the [holder].", "You install the external reinforced armor layer to the [holder].") - - holder.icon_state = "nkarrdem14" - else - user.visible_message("[user] cuts the internal armor layer from the [holder].", "You cut the internal armor layer from the [holder].") - holder.icon_state = "nkarrdem12" - if(2) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") - holder.icon_state = "nkarrdem15" - else - var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) - MS.amount = 5 - user.visible_message("[user] pries [MS] from the [holder].", "You pry [MS] from the [holder].") - holder.icon_state = "nkarrdem13" - if(1) - if(diff == CONSTRUCTION_PATH_FORWARDS) - user.visible_message("[user] welds the external armor layer to the [holder].", "You weld the external armor layer to the [holder].") - holder.icon_state = "nkarrdem16" - else - user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") - holder.icon_state = "nkarrdem14" - return TRUE - -#undef STANDARD_STACK_AMOUNT diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm deleted file mode 100644 index d713a74995a88..0000000000000 --- a/code/game/mecha/mecha_parts.dm +++ /dev/null @@ -1,516 +0,0 @@ -///////////////////////// -////// Mecha Parts ////// -///////////////////////// - -/obj/item/mecha_parts - name = "mecha part" - icon = 'icons/mecha/mech_construct.dmi' - icon_state = "blank" - w_class = WEIGHT_CLASS_GIGANTIC - flags = CONDUCT - origin_tech = "programming=2;materials=2;engineering=2" - -/obj/item/mecha_parts/core - name = "mech power core" - icon = 'icons/obj/assemblies/new_assemblies.dmi' - icon_state = "mech_core" - desc = "A complex piece of electronics used to regulate the large amounts of power used by a combat mech's delicate components." - w_class = WEIGHT_CLASS_SMALL - -/obj/item/mecha_parts/chassis - name = "mecha chassis" - icon_state = "backbone" - var/datum/construction/construct - flags = CONDUCT - -/obj/item/mecha_parts/chassis/Destroy() - QDEL_NULL(construct) - return ..() - -/obj/item/mecha_parts/chassis/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(!construct || !construct.action(W, user)) - return ..() - -/obj/item/mecha_parts/chassis/attack_hand() - return - -/////////// Ripley - -/obj/item/mecha_parts/chassis/ripley - name = "\improper Ripley chassis" - -/obj/item/mecha_parts/chassis/ripley/New() - ..() - construct = new /datum/construction/mecha/ripley_chassis(src) - -/obj/item/mecha_parts/part/ripley_torso - name = "\improper Ripley torso" - desc = "A torso part of Ripley APLU. Contains power unit, processing core and life support systems." - icon_state = "ripley_harness" - origin_tech = "programming=2;materials=2;biotech=2;engineering=2" - -/obj/item/mecha_parts/part/ripley_left_arm - name = "\improper Ripley left arm" - desc = "A Ripley APLU left arm. Data and power sockets are compatible with most exosuit tools." - icon_state = "ripley_l_arm" - -/obj/item/mecha_parts/part/ripley_right_arm - name = "\improper Ripley right arm" - desc = "A Ripley APLU right arm. Data and power sockets are compatible with most exosuit tools." - icon_state = "ripley_r_arm" - -/obj/item/mecha_parts/part/ripley_left_leg - name = "\improper Ripley left leg" - desc = "A Ripley APLU left leg. Contains somewhat complex servodrives and balance maintaining systems." - icon_state = "ripley_l_leg" - -/obj/item/mecha_parts/part/ripley_right_leg - name = "\improper Ripley right leg" - desc = "A Ripley APLU right leg. Contains somewhat complex servodrives and balance maintaining systems." - icon_state = "ripley_r_leg" - -///////// Gygax - -/obj/item/mecha_parts/chassis/gygax - name = "\improper Gygax chassis" - -/obj/item/mecha_parts/chassis/gygax/New() - ..() - construct = new /datum/construction/mecha/gygax_chassis(src) - -/obj/item/mecha_parts/part/gygax_torso - name = "\improper Gygax torso" - desc = "A torso part of Gygax. Contains power unit, processing core and life support systems. Has an additional equipment slot." - icon_state = "gygax_harness" - origin_tech = "programming=2;materials=4;biotech=3;engineering=3" - -/obj/item/mecha_parts/part/gygax_head - name = "\improper Gygax head" - desc = "A Gygax head. Houses advanced surveillance and targeting sensors." - icon_state = "gygax_head" - origin_tech = "programming=2;materials=4;magnets=3;engineering=3" - -/obj/item/mecha_parts/part/gygax_left_arm - name = "\improper Gygax left arm" - desc = "A Gygax left arm. Data and power sockets are compatible with most exosuit tools and weapons." - icon_state = "gygax_l_arm" - origin_tech = "programming=2;materials=4;engineering=3" - -/obj/item/mecha_parts/part/gygax_right_arm - name = "\improper Gygax right arm" - desc = "A Gygax right arm. Data and power sockets are compatible with most exosuit tools and weapons." - icon_state = "gygax_r_arm" - origin_tech = "programming=2;materials=4;engineering=3" - -/obj/item/mecha_parts/part/gygax_left_leg - name = "\improper Gygax left leg" - icon_state = "gygax_l_leg" - origin_tech = "programming=2;materials=4;engineering=3" - -/obj/item/mecha_parts/part/gygax_right_leg - name = "\improper Gygax right leg" - icon_state = "gygax_r_leg" - origin_tech = "programming=2;materials=4;engineering=3" - -/obj/item/mecha_parts/part/gygax_armour - name = "\improper Gygax armour plates" - icon_state = "gygax_armour" - origin_tech = "materials=6;combat=4;engineering=4" - - -//////////// Durand - -/obj/item/mecha_parts/chassis/durand - name = "\improper Durand chassis" - -/obj/item/mecha_parts/chassis/durand/New() - ..() - construct = new /datum/construction/mecha/durand_chassis(src) - -/obj/item/mecha_parts/part/durand_torso - name = "\improper Durand torso" - icon_state = "durand_harness" - origin_tech = "programming=2;materials=3;biotech=3;engineering=3" - -/obj/item/mecha_parts/part/durand_head - name = "\improper Durand head" - icon_state = "durand_head" - origin_tech = "programming=2;materials=3;magnets=3;engineering=3" - -/obj/item/mecha_parts/part/durand_left_arm - name = "\improper Durand left arm" - icon_state = "durand_l_arm" - origin_tech = "programming=2;materials=3;engineering=3" - -/obj/item/mecha_parts/part/durand_right_arm - name = "\improper Durand right arm" - icon_state = "durand_r_arm" - origin_tech = "programming=2;materials=3;engineering=3" - -/obj/item/mecha_parts/part/durand_left_leg - name = "\improper Durand left leg" - icon_state = "durand_l_leg" - origin_tech = "programming=2;materials=3;engineering=3" - -/obj/item/mecha_parts/part/durand_right_leg - name = "\improper Durand right leg" - icon_state = "durand_r_leg" - origin_tech = "programming=2;materials=3;engineering=3" - -/obj/item/mecha_parts/part/durand_armor - name = "\improper Durand armour plates" - icon_state = "durand_armor" - origin_tech = "materials=5;combat=4;engineering=4" - - - -////////// Firefighter - -/obj/item/mecha_parts/chassis/firefighter - name = "\improper Firefighter chassis" - -/obj/item/mecha_parts/chassis/firefighter/New() - ..() - construct = new /datum/construction/mecha/firefighter_chassis(src) - -////////// HONK - -/obj/item/mecha_parts/chassis/honker - name = "\improper H.O.N.K chassis" - -/obj/item/mecha_parts/chassis/honker/New() - ..() - construct = new /datum/construction/mecha/honker_chassis(src) - -/obj/item/mecha_parts/part/honker_torso - name = "\improper H.O.N.K torso" - icon_state = "honker_harness" - -/obj/item/mecha_parts/part/honker_head - name = "\improper H.O.N.K head" - icon_state = "honker_head" - -/obj/item/mecha_parts/part/honker_left_arm - name = "\improper H.O.N.K left arm" - icon_state = "honker_l_arm" - -/obj/item/mecha_parts/part/honker_right_arm - name = "\improper H.O.N.K right arm" - icon_state = "honker_r_arm" - -/obj/item/mecha_parts/part/honker_left_leg - name = "\improper H.O.N.K left leg" - icon_state = "honker_l_leg" - -/obj/item/mecha_parts/part/honker_right_leg - name = "\improper H.O.N.K right leg" - icon_state = "honker_r_leg" - - -////////// Reticence - -/obj/item/mecha_parts/chassis/reticence - name = "\improper Reticence chassis" - -/obj/item/mecha_parts/chassis/reticence/New() - ..() - construct = new /datum/construction/mecha/reticence_chassis(src) - -/obj/effect/dummy/mecha_emote_step - var/emote - -/obj/effect/dummy/mecha_emote_step/New(e) - . = ..() - emote = e - -/obj/item/mecha_parts/chassis/reticence/hear_message(mob/living/M, msg) - if(!istype(M) || !istype(construct, /datum/construction/reversible/mecha/reticence)) - return - // is the current step the dummy emote object? - var/list/steps = construct.steps - if(steps[construct.index]["key"] == /obj/effect/dummy/mecha_emote_step) - construct.action(new /obj/effect/dummy/mecha_emote_step(msg), M) - -/obj/item/mecha_parts/part/reticence_torso - name = "\improper Reticence torso" - icon_state = "reticence_harness" - -/obj/item/mecha_parts/part/reticence_head - name = "\improper Reticence head" - icon_state = "reticence_head" - -/obj/item/mecha_parts/part/reticence_left_arm - name = "\improper Reticence left arm" - icon_state = "reticence_l_arm" - -/obj/item/mecha_parts/part/reticence_right_arm - name = "\improper Reticence right arm" - icon_state = "reticence_r_arm" - -/obj/item/mecha_parts/part/reticence_left_leg - name = "\improper Reticence left leg" - icon_state = "reticence_l_leg" - -/obj/item/mecha_parts/part/reticence_right_leg - name = "\improper Reticence right leg" - icon_state = "reticence_r_leg" - - -////////// Phazon - -/obj/item/mecha_parts/chassis/phazon - name = "\improper Phazon chassis" - -/obj/item/mecha_parts/chassis/phazon/New() - ..() - construct = new /datum/construction/mecha/phazon_chassis(src) - -/obj/item/mecha_parts/chassis/phazon/attackby__legacy__attackchain(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" - icon_state = "phazon_harness" - origin_tech = "programming=4;materials=4;bluespace=4;plasmatech=5" - -/obj/item/mecha_parts/part/phazon_head - name = "\improper Phazon head" - icon_state = "phazon_head" - origin_tech = "programming=3;materials=3;magnets=3" - -/obj/item/mecha_parts/part/phazon_left_arm - name = "\improper Phazon left arm" - icon_state = "phazon_l_arm" - origin_tech = "materials=3;bluespace=3;magnets=3" - -/obj/item/mecha_parts/part/phazon_right_arm - name = "\improper Phazon right arm" - icon_state = "phazon_r_arm" - origin_tech = "materials=3;bluespace=3;magnets=3" - -/obj/item/mecha_parts/part/phazon_left_leg - name = "\improper Phazon left leg" - icon_state = "phazon_l_leg" - origin_tech = "materials=3;bluespace=3;magnets=3" - -/obj/item/mecha_parts/part/phazon_right_leg - name = "\improper Phazon right leg" - icon_state = "phazon_r_leg" - origin_tech = "materials=3;bluespace=3;magnets=3" - -/obj/item/mecha_parts/part/phazon_armor - name = "\improper Phazon armor" - desc = "Phazon armor plates. They are layered with plasma to protect the pilot from the stress of phasing and have unusual properties." - icon_state = "phazon_armor" - origin_tech = "materials=4;bluespace=4;plasmatech=5" - -///////// Odysseus -/obj/item/mecha_parts/chassis/odysseus - name = "\improper Odysseus Chassis" - -/obj/item/mecha_parts/chassis/odysseus/New() - ..() - construct = new /datum/construction/mecha/odysseus_chassis(src) - -/obj/item/mecha_parts/part/odysseus_head - name = "\improper Odysseus head" - icon_state = "odysseus_head" - -/obj/item/mecha_parts/part/odysseus_torso - name = "\improper Odysseus torso" - desc = "A torso part of Odysseus. Contains power unit, processing core and life support systems." - icon_state = "odysseus_torso" - origin_tech = "programming=2;materials=2;biotech=2;engineering=2" - -/obj/item/mecha_parts/part/odysseus_left_arm - name = "\improper Odysseus left arm" - desc = "An Odysseus left arm. Data and power sockets are compatible with most exosuit tools." - icon_state = "odysseus_l_arm" - -/obj/item/mecha_parts/part/odysseus_right_arm - name = "\improper Odysseus right arm" - desc = "An Odysseus right arm. Data and power sockets are compatible with most exosuit tools." - icon_state = "odysseus_r_arm" - -/obj/item/mecha_parts/part/odysseus_left_leg - name = "\improper Odysseus left leg" - desc = "An Odysseus left leg. Contains somewhat complex servodrives and balance maintaining systems." - icon_state = "odysseus_l_leg" - -/obj/item/mecha_parts/part/odysseus_right_leg - name = "\improper Odysseus right leg" - desc = "A Odysseus right leg. Contains somewhat complex servodrives and balance maintaining systems." - icon_state = "odysseus_r_leg" - -/*/obj/item/mecha_parts/part/odysseus_armour - name = "\improper Odysseus carapace" - icon_state = "odysseus_armour" - origin_tech = "materials=3;engineering=3")*/ - -///////// Nkarrdem -/obj/item/mecha_parts/chassis/nkarrdem - name = "\improper Nkarrdem Chassis" - -/obj/item/mecha_parts/chassis/nkarrdem/New() - ..() - construct = new /datum/construction/mecha/nkarrdem_chassis(src) - -/obj/item/mecha_parts/part/nkarrdem_head - name = "\improper Nkarrdem head" - icon_state = "nkarrdem_head" - -/obj/item/mecha_parts/part/nkarrdem_torso - name = "\improper Nkarrdem torso" - desc = "A torso part of Nkarrdem. Contains power unit, processing core and life support systems." - icon_state = "nkarrdem_harness" - origin_tech = "programming=2;materials=2;biotech=2;engineering=2" - -/obj/item/mecha_parts/part/nkarrdem_left_arm - name = "\improper Nkarrdem left arm" - desc = "A Nkarrdem left arm. Data and power sockets are compatible with most exosuit tools." - icon_state = "nkarrdem_l_arm" - -/obj/item/mecha_parts/part/nkarrdem_right_arm - name = "\improper Nkarrdem right arm" - desc = "A Nkarrdem right arm. Data and power sockets are compatible with most exosuit tools." - icon_state = "nkarrdem_r_arm" - -/obj/item/mecha_parts/part/nkarrdem_left_leg - name = "\improper Nkarrdem left leg" - desc = "A Nkarrdem left leg. Contains somewhat complex servodrives and balance maintaining systems." - icon_state = "nkarrdem_l_leg" - -/obj/item/mecha_parts/part/nkarrdem_right_leg - name = "\improper Nkarrdem right leg" - desc = "A Nkarrdem right leg. Contains somewhat complex servodrives and balance maintaining systems." - icon_state = "nkarrdem_r_leg" - - -///////// Circuitboards - -/obj/item/circuitboard/mecha - icon_state = "std_mod" - board_type = "other" - flags = CONDUCT - force = 5 - throwforce = 5 - throw_speed = 3 - throw_range = 15 - - -/obj/item/circuitboard/mecha/ripley - origin_tech = "programming=2" - -/obj/item/circuitboard/mecha/ripley/main - board_name = "Ripley Central Control Module" - icon_state = "mainboard" - -/obj/item/circuitboard/mecha/ripley/peripherals - board_name = "Ripley Peripherals Control Module" - icon_state = "mcontroller" - -/obj/item/circuitboard/mecha/nkarrdem - origin_tech = "programming=2" - -/obj/item/circuitboard/mecha/nkarrdem/main - board_name = "Nkarrdem Central Control Module" - icon_state = "mainboard" - -/obj/item/circuitboard/mecha/nkarrdem/peripherals - board_name = "Nkarrdem Peripherals Control Module" - icon_state = "mcontroller" - -/obj/item/circuitboard/mecha/gygax - origin_tech = "programming=4;combat=3;engineering=3" - -/obj/item/circuitboard/mecha/gygax/main - board_name = "Gygax Central Control Module" - icon_state = "mainboard" - -/obj/item/circuitboard/mecha/gygax/peripherals - board_name = "Gygax Peripherals Control Module" - icon_state = "mcontroller" - -/obj/item/circuitboard/mecha/gygax/targeting - board_name = "Gygax Weapon Control and Targeting Module" - icon_state = "mcontroller" - origin_tech = "programming=4;combat=4" - - -/obj/item/circuitboard/mecha/durand - origin_tech = "programming=4;combat=3;engineering=3" - -/obj/item/circuitboard/mecha/durand/main - board_name = "Durand Central Control Module" - icon_state = "mainboard" - -/obj/item/circuitboard/mecha/durand/peripherals - board_name = "Durand Peripherals Control Module" - icon_state = "mcontroller" - -/obj/item/circuitboard/mecha/durand/targeting - board_name = "Durand Weapon Control and Targeting Module" - icon_state = "mcontroller" - origin_tech = "programming=4;combat=4;engineering=3" - - -/obj/item/circuitboard/mecha/phazon - origin_tech = "programming=5;plasmatech=4" - -/obj/item/circuitboard/mecha/phazon/main - board_name = "Phazon Central Control Module" - icon_state = "mainboard" - -/obj/item/circuitboard/mecha/phazon/peripherals - board_name = "Phazon Peripherals Control Module" - icon_state = "mcontroller" - -/obj/item/circuitboard/mecha/phazon/targeting - board_name = "Phazon Weapon Control and Targeting Module" - icon_state = "mcontroller" - - -/obj/item/circuitboard/mecha/honker - origin_tech = "programming=3;engineering=3" - -/obj/item/circuitboard/mecha/honker/main - board_name = "H.O.N.K Central Control Module" - icon_state = "mainboard" - -/obj/item/circuitboard/mecha/honker/peripherals - board_name = "H.O.N.K Peripherals Control Module" - icon_state = "mcontroller" - -/obj/item/circuitboard/mecha/honker/targeting - board_name = "H.O.N.K Weapon Control and Targeting Module" - icon_state = "mcontroller" - - -/obj/item/circuitboard/mecha/reticence - origin_tech = "programming=3;engineering=3" - -/obj/item/circuitboard/mecha/reticence/main - board_name = "Reticence Central Control Module" - icon_state = "mainboard" - -/obj/item/circuitboard/mecha/reticence/peripherals - board_name = "Reticence Peripherals Control Module" - icon_state = "mcontroller" - -/obj/item/circuitboard/mecha/reticence/targeting - board_name = "Reticence Weapon Control and Targeting Module" - icon_state = "mcontroller" - - -/obj/item/circuitboard/mecha/odysseus - origin_tech = "programming=3;biotech=3" - -/obj/item/circuitboard/mecha/odysseus/main - board_name = "Odysseus Central Control Module" - icon_state = "mainboard" - -/obj/item/circuitboard/mecha/odysseus/peripherals - board_name = "Odysseus Peripherals Control Module" - icon_state = "mcontroller" diff --git a/code/game/objects/effects/alien_acid.dm b/code/game/objects/effects/alien_acid.dm deleted file mode 100644 index a00b1c65ce037..0000000000000 --- a/code/game/objects/effects/alien_acid.dm +++ /dev/null @@ -1,106 +0,0 @@ -/obj/effect/acid - gender = PLURAL - name = "acid" - desc = "Burbling corrosive stuff." - icon_state = "acid" - density = FALSE - opacity = FALSE - resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF - layer = ABOVE_NORMAL_TURF_LAYER - var/turf/target - - -/obj/effect/acid/Initialize(mapload, acid_pwr, acid_amt) - . = ..() - - target = get_turf(src) - - if(acid_amt) - acid_level = min(acid_amt * acid_pwr, 12000) //capped so the acid effect doesn't last a half hour on the floor. - - //handle APCs and newscasters and stuff nicely - pixel_x = target.pixel_x + rand(-4,4) - pixel_y = target.pixel_y + rand(-4,4) - - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - - START_PROCESSING(SSobj, src) - -/obj/effect/acid/Destroy() - STOP_PROCESSING(SSobj, src) - target = null - return ..() - -/obj/effect/acid/process() - . = 1 - if(!target) - qdel(src) - return 0 - - if(prob(5)) - playsound(loc, 'sound/items/welder.ogg', 100, TRUE) - - for(var/obj/O in target) - if(prob(20) && !(resistance_flags & UNACIDABLE)) - if(O.acid_level < acid_level * 0.3) - var/acid_used = min(acid_level * 0.05, 20) - O.acid_act(10, acid_used) - acid_level = max(0, acid_level - acid_used * 10) - - acid_level = max(acid_level - (5 + 2 * round(sqrt(acid_level))), 0) - if(acid_level <= 0) - qdel(src) - return 0 - -/obj/effect/acid/proc/on_atom_entered(datum/source, atom/movable/entered) - SIGNAL_HANDLER // COMSIG_ATOM_ENTERED - if(!isliving(entered) && !isobj(entered)) - return - if(isliving(entered)) - var/mob/living/L = entered - if(HAS_TRAIT(L, TRAIT_FLYING)) - return - if(L.m_intent != MOVE_INTENT_WALK && prob(40)) - var/acid_used = min(acid_level * 0.05, 20) - if(L.acid_act(10, acid_used, "feet")) - acid_level = max(0, acid_level - acid_used * 10) - playsound(L, 'sound/weapons/sear.ogg', 50, TRUE) - to_chat(L, "[src] burns you!") - -//xenomorph corrosive acid -/obj/effect/acid/alien - var/target_strength = 30 - -/obj/effect/acid/alien/Initialize(mapload, acid_pwr, acid_amt) - . = ..() - var/turf/cleanable_turf = get_turf(src) - RegisterSignal(cleanable_turf, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(remove_acid)) - -/obj/effect/acid/alien/proc/remove_acid(datum/source) - SIGNAL_HANDLER - qdel(src) - -/obj/effect/acid/alien/process() - . = ..() - if(.) - if(prob(45)) - playsound(loc, 'sound/items/welder.ogg', 100, TRUE) - target_strength-- - if(target_strength <= 0) - target.visible_message("[target] collapses under its own weight into a puddle of goop and undigested debris!") - target.acid_melt() - qdel(src) - else - - switch(target_strength) - if(24) - visible_message("[target] is holding up against the acid!") - if(16) - visible_message("[target] is being melted by the acid!") - if(8) - visible_message("[target] is struggling to withstand the acid!") - if(4) - visible_message("[target] begins to crumble under the acid!") diff --git a/code/game/objects/effects/decals/Cleanable/tar.dm b/code/game/objects/effects/decals/Cleanable/tar.dm deleted file mode 100644 index 0b76030ca1df7..0000000000000 --- a/code/game/objects/effects/decals/Cleanable/tar.dm +++ /dev/null @@ -1,48 +0,0 @@ -/obj/effect/decal/cleanable/tar - gender = PLURAL - name = "tar" - desc = "A sticky substance." - icon_state = "tar2" - /// The turf that the tar is sitting on - var/turf/simulated/target - -/obj/effect/decal/cleanable/tar/Initialize(mapload) - . = ..() - if(issimulatedturf(loc)) // Ensure the location is a simulated turf - target = loc - target.slowdown += 10 // Apply the slowdown effect to the turf - if(prob(50)) - icon_state = "tar3" - - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered) - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/effect/decal/cleanable/tar/Destroy() - if(target) - target.slowdown -= 10 - return ..() - -/obj/effect/decal/cleanable/tar/Moved(atom/OldLoc, Dir, Forced) - . = ..() - target.slowdown -= 10 - target = loc - target.slowdown += 10 - if(!issimulatedturf(target)) // We remove slowdown in Destroy(), so we run this check after adding the slowdown. - qdel(src) - -/obj/effect/decal/cleanable/tar/proc/on_atom_entered(datum/source, atom/movable/entered) - if(isliving(entered)) - var/mob/living/L = entered - playsound(L, 'sound/effects/attackblob.ogg', 50, TRUE) - to_chat(L, "[src] sticks to you!") - -/obj/effect/decal/cleanable/tar/attackby__legacy__attackchain(obj/item/welder, mob/living/user, params) - if(!welder.get_heat() || !Adjacent(user)) - return - playsound(welder, 'sound/items/welder.ogg', 50, TRUE) - if(do_after(user, 3 SECONDS, FALSE, user)) - if(welder.get_heat() && Adjacent(user)) - user.visible_message("[user] burns away [src] with [welder]!", "You burn away [src]!") - qdel(src) diff --git a/code/game/objects/effects/decals/Cleanable/tracks.dm b/code/game/objects/effects/decals/Cleanable/tracks.dm deleted file mode 100644 index 431c97c6d7e78..0000000000000 --- a/code/game/objects/effects/decals/Cleanable/tracks.dm +++ /dev/null @@ -1,173 +0,0 @@ -// 5 seconds -#define TRACKS_CRUSTIFY_TIME 50 -#define ALWAYS_IN_GRAVITY 2 - -// color-dir-dry -GLOBAL_LIST_EMPTY(fluidtrack_cache) - -// Footprints, tire trails... -/obj/effect/decal/cleanable/blood/tracks - icon = 'icons/effects/fluidtracks.dmi' - name = "wet tracks" - dryname = "dried tracks" - desc = "Whoops..." - drydesc = "Whoops..." - icon_state = "wheels1" - gender = PLURAL - random_icon_states = null - amount = 0 - gravity_check = ALWAYS_IN_GRAVITY - -/// Subtype of tracks used for decorating maps. -/obj/effect/decal/cleanable/blood/tracks/mapped - desc = "Your instincts say you shouldn't be following these." - drydesc = "Your instincts say you shouldn't be following these." - icon = 'icons/effects/blood.dmi' - icon_state = "tracks" - -//BLOODY FOOTPRINTS -/obj/effect/decal/cleanable/blood/footprints - icon = 'icons/effects/fluidtracks.dmi' - icon_state = null - desc = "You REALLY shouldn't follow these.." - gender = PLURAL - random_icon_states = null - basecolor = "#A10808" - var/entered_dirs = 0 - var/exited_dirs = 0 - var/base_alpha = BLOODY_FOOTPRINT_BASE_ALPHA - blood_state = BLOOD_STATE_HUMAN //the icon state to load images from - gravity_check = ALWAYS_IN_GRAVITY - -/obj/effect/decal/cleanable/blood/footprints/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - COMSIG_ATOM_EXITED = PROC_REF(on_atom_exited), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/effect/decal/cleanable/blood/footprints/on_atom_entered(datum/source, mob/living/carbon/human/H, ...) - if(!istype(H)) - return - - var/obj/item/clothing/shoes/S = H.shoes - var/obj/item/organ/external/l_foot = H.get_organ("l_foot") - var/obj/item/organ/external/r_foot = H.get_organ("r_foot") - var/hasfeet = TRUE - if(!l_foot && !r_foot) - hasfeet = FALSE - if(S && S.bloody_shoes[blood_state] && S.blood_color == basecolor) - S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0) - S.bloody_shoes[BLOOD_BASE_ALPHA] = base_alpha - if(!S.blood_DNA) - S.blood_DNA = list() - S.blood_DNA |= blood_DNA.Copy() - if(!(entered_dirs & H.dir)) - entered_dirs |= H.dir - update_icon() - else if(hasfeet && H.bloody_feet[blood_state] && H.feet_blood_color == basecolor)//Or feet //This will need to be changed. - H.bloody_feet[blood_state] = max(H.bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP, 0) - H.bloody_feet[BLOOD_BASE_ALPHA] = base_alpha - if(!H.feet_blood_DNA) - H.feet_blood_DNA = list() - H.feet_blood_DNA |= blood_DNA.Copy() - if(!(entered_dirs & H.dir)) - entered_dirs |= H.dir - update_icon() - -// TODO: I think this is a 1:1 copy-paste of on_atom_entered above -/obj/effect/decal/cleanable/blood/footprints/proc/on_atom_exited(datum/source, mob/living/carbon/human/H, ...) - if(!istype(H)) - return - - var/obj/item/clothing/shoes/S = H.shoes - var/obj/item/organ/external/l_foot = H.get_organ("l_foot") - var/obj/item/organ/external/r_foot = H.get_organ("r_foot") - var/hasfeet = TRUE - if(!l_foot && !r_foot) - hasfeet = FALSE - if(S && S.bloody_shoes[blood_state] && S.blood_color == basecolor) - S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0) - if(!S.blood_DNA) - S.blood_DNA = list() - S.blood_DNA |= blood_DNA.Copy() - if(!(exited_dirs & H.dir)) - exited_dirs |= H.dir - update_icon() - else if(hasfeet && H.bloody_feet[blood_state] && H.feet_blood_color == basecolor)//Or feet - H.bloody_feet[blood_state] = max(H.bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP, 0) - if(!H.feet_blood_DNA) - H.feet_blood_DNA = list() - H.feet_blood_DNA |= blood_DNA.Copy() - if(!(exited_dirs & H.dir)) - exited_dirs |= H.dir - update_icon() - - -/obj/effect/decal/cleanable/blood/footprints/update_overlays() - . = ..() - - for(var/Ddir in GLOB.cardinal) - if(entered_dirs & Ddir) - var/image/I - if(GLOB.fluidtrack_cache["entered-[blood_state]-[Ddir]"]) - I = GLOB.fluidtrack_cache["entered-[blood_state]-[Ddir]"] - else - I = image(icon,"[blood_state]1",dir = Ddir) - GLOB.fluidtrack_cache["entered-[blood_state]-[Ddir]"] = I - if(I) - I.color = basecolor - . += I - if(exited_dirs & Ddir) - var/image/I - if(GLOB.fluidtrack_cache["exited-[blood_state]-[Ddir]"]) - I = GLOB.fluidtrack_cache["exited-[blood_state]-[Ddir]"] - else - I = image(icon,"[blood_state]2",dir = Ddir) - GLOB.fluidtrack_cache["exited-[blood_state]-[Ddir]"] = I - if(I) - I.color = basecolor - . += I - - alpha = base_alpha + bloodiness - -/obj/effect/decal/cleanable/blood/footprints/should_be_off_floor() - return FALSE - -/proc/createFootprintsFrom(atom/movable/A, dir, turf/T) - var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T) - if(ishuman(A)) - var/mob/living/carbon/human/H = A - FP.blood_state = H.blood_state - FP.bloodiness = H.bloody_feet[H.blood_state] - BLOOD_LOSS_IN_SPREAD - FP.basecolor = H.feet_blood_color - FP.base_alpha = H.bloody_feet[BLOOD_BASE_ALPHA] - if(H.blood_DNA) - FP.blood_DNA = H.blood_DNA.Copy() - else if(istype(A, /obj/item/clothing/shoes)) - var/obj/item/clothing/shoes/S = A - FP.blood_state = S.blood_state - FP.bloodiness = S.bloody_shoes[S.blood_state] - BLOOD_LOSS_IN_SPREAD - FP.basecolor = S.blood_color - FP.base_alpha = S.bloody_shoes[BLOOD_BASE_ALPHA] - if(S.blood_DNA) - FP.blood_DNA = S.blood_DNA.Copy() - FP.entered_dirs |= dir - FP.update_icon() - - return FP - -/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/blood/footprints/C) - if(blood_state != C.blood_state) //We only replace footprints of the same type as us - return - ..() - -/obj/effect/decal/cleanable/blood/footprints/can_bloodcrawl_in() - if(basecolor == COLOR_BLOOD_MACHINE) - return FALSE - return TRUE - -#undef ALWAYS_IN_GRAVITY - -#undef TRACKS_CRUSTIFY_TIME diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm deleted file mode 100644 index 6ad91e08db51e..0000000000000 --- a/code/game/objects/effects/decals/cleanable.dm +++ /dev/null @@ -1,125 +0,0 @@ -#define ALWAYS_IN_GRAVITY 2 - -/obj/effect/decal/cleanable - ///when Initialized() its icon_state will be chosen from this list - var/list/random_icon_states = list() - ///0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints - var/bloodiness = 0 - ///when another of the same type is made on the same tile will they merge --- YES=TRUE; NO=FLASE - var/mergeable_decal = TRUE - ///prevents Ambient Occlusion effects around it ; Set to GAME_PLANE in Initialize() if on a wall - plane = FLOOR_PLANE - ///for blood n vomit in zero G --- IN GRAVITY=TRUE; NO GRAVITY=FALSE - var/gravity_check = TRUE - hud_possible = list(JANI_HUD) - -/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal - if(mergeable_decal) - return TRUE - -/obj/effect/decal/cleanable/cleaning_act(mob/user, atom/cleaner, cleanspeed = 5 SECONDS, text_verb = "scrub out", text_description = " with [cleaner].") - if(issimulatedturf(loc)) - var/turf/simulated/T = get_turf(src) - T.cleaning_act(user, cleaner, cleanspeed = cleanspeed, text_verb = text_verb, text_description = text_description, text_targetname = name) //Strings are deliberately "A = A" to avoid overrides - return - else - ..() - -//Add "bloodiness" of this blood's type, to the human's shoes -//This is on /cleanable because fuck this ancient mess -/obj/effect/decal/cleanable/blood/proc/on_atom_entered(datum/source, atom/movable/entered) - if(!ishuman(entered)) - return - - if(!gravity_check && ishuman(entered)) - bloodyify_human(entered) - - if(!off_floor) - var/mob/living/carbon/human/H = entered - var/obj/item/organ/external/l_foot = H.get_organ("l_foot") - var/obj/item/organ/external/r_foot = H.get_organ("r_foot") - var/hasfeet = TRUE - if(IS_HORIZONTAL(H) && !H.buckled) //Make people bloody if they're lying down and move into blood - if(bloodiness > 0 && length(blood_DNA)) - H.add_blood(H.blood_DNA, basecolor) - if(!l_foot && !r_foot) - hasfeet = FALSE - if(H.shoes && blood_state && bloodiness) - var/obj/item/clothing/shoes/S = H.shoes - var/add_blood = 0 - if(bloodiness >= BLOOD_GAIN_PER_STEP) - add_blood = BLOOD_GAIN_PER_STEP - else - add_blood = bloodiness - bloodiness -= add_blood - S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS, S.bloody_shoes[blood_state] + add_blood) - S.bloody_shoes[BLOOD_BASE_ALPHA] = BLOODY_FOOTPRINT_BASE_ALPHA * (alpha/255) - if(blood_DNA && length(blood_DNA)) - S.add_blood(H.blood_DNA, basecolor) - S.blood_state = blood_state - S.blood_color = basecolor - update_icon() - H.update_inv_shoes() - else if(hasfeet && blood_state && bloodiness)//Or feet - var/add_blood = 0 - if(bloodiness >= BLOOD_GAIN_PER_STEP) - add_blood = BLOOD_GAIN_PER_STEP - else - add_blood = bloodiness - bloodiness -= add_blood - H.bloody_feet[blood_state] = min(MAX_SHOE_BLOODINESS, H.bloody_feet[blood_state] + add_blood) - H.bloody_feet[BLOOD_BASE_ALPHA] = BLOODY_FOOTPRINT_BASE_ALPHA * (alpha/255) - if(!H.feet_blood_DNA) - H.feet_blood_DNA = list() - H.blood_state = blood_state - H.feet_blood_DNA |= blood_DNA.Copy() - H.feet_blood_color = basecolor - update_icon() - H.update_inv_shoes() - -/obj/effect/decal/cleanable/proc/can_bloodcrawl_in() - return FALSE - -/obj/effect/decal/cleanable/is_cleanable() - return TRUE - -/obj/effect/decal/cleanable/Initialize(mapload) - . = ..() - prepare_huds() - if(should_merge_decal(loc)) - return INITIALIZE_HINT_QDEL - var/datum/atom_hud/data/janitor/jani_hud = GLOB.huds[DATA_HUD_JANITOR] - jani_hud.add_to_hud(src) - jani_hud_set_sign() - if(random_icon_states && length(src.random_icon_states) > 0) - src.icon_state = pick(src.random_icon_states) - if(smoothing_flags) - QUEUE_SMOOTH(src) - QUEUE_SMOOTH_NEIGHBORS(src) - if(iswallturf(loc) && plane == FLOOR_PLANE) - plane = GAME_PLANE // so they can be seen above walls - -/obj/effect/decal/cleanable/Destroy() - if(smoothing_flags) - QUEUE_SMOOTH_NEIGHBORS(src) - var/datum/atom_hud/data/janitor/jani_hud = GLOB.huds[DATA_HUD_JANITOR] - jani_hud.remove_from_hud(src) - return ..() - -/obj/effect/decal/cleanable/proc/should_merge_decal(turf/T) - if(!T) - T = loc - if(isturf(T)) - for(var/obj/effect/decal/cleanable/C in T) - if(C != src && C.type == type && !QDELETED(C)) - if(C.gravity_check && replace_decal(C)) - return TRUE - return FALSE - -/obj/effect/decal/cleanable/proc/check_gravity(turf/T) - if(isnull(T)) - T = get_turf(src) - if(gravity_check != ALWAYS_IN_GRAVITY) - gravity_check = has_gravity(src, T) - -#undef ALWAYS_IN_GRAVITY diff --git a/code/game/objects/effects/decals/contraband_posters.dm b/code/game/objects/effects/decals/contraband_posters.dm deleted file mode 100644 index 57344002c4d29..0000000000000 --- a/code/game/objects/effects/decals/contraband_posters.dm +++ /dev/null @@ -1,638 +0,0 @@ -// This is synced up to the poster placing animation. -#define PLACE_SPEED 30 - -// The poster item - -/obj/item/poster - name = "rolled-up poster" - desc = "The 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." - icon = 'icons/obj/contraband.dmi' - force = 0 - resistance_flags = FLAMMABLE - var/poster_type - var/obj/structure/sign/poster/poster_structure - -/obj/item/poster/Initialize(mapload, obj/structure/sign/poster/new_poster_structure) - . = ..() - poster_structure = new_poster_structure - if(!new_poster_structure && poster_type) - poster_structure = new poster_type(src) - - // posters store what name and description they would like their rolled up form to take. - if(poster_structure) - name = poster_structure.poster_item_name - desc = poster_structure.poster_item_desc - icon_state = poster_structure.poster_item_icon_state - - name = "[name] - [poster_structure.original_name]" - -/obj/item/poster/Destroy() - poster_structure = null - . = ..() - -// These icon_states may be overriden, but are for mapper's convinence -/obj/item/poster/random_contraband - name = "random contraband poster" - poster_type = /obj/structure/sign/poster/contraband/random - icon_state = "rolled_poster" - -/obj/item/poster/random_official - name = "random official poster" - poster_type = /obj/structure/sign/poster/official/random - icon_state = "rolled_poster_legit" - -/obj/item/poster/syndicate_recruitment - poster_type = /obj/structure/sign/poster/contraband/syndicate_recruitment - icon_state = "rolled_poster" - -//############################## THE ACTUAL DECALS ########################### - -/obj/structure/sign/poster - name = "poster" - desc = "A large piece of space-resistant printed paper." - icon = 'icons/obj/contraband.dmi' - anchored = TRUE - var/original_name - var/random_basetype - var/ruined = FALSE - var/never_random = FALSE // used for the 'random' subclasses. - - var/poster_item_name = "hypothetical poster" - var/poster_item_desc = "This hypothetical poster item should not exist, let's be honest here." - var/poster_item_icon_state = "rolled_poster" - -/obj/structure/sign/poster/Initialize(mapload) - if(random_basetype) - randomise(random_basetype) - . = ..() - if(!ruined) - original_name = name - name = "poster - [name]" - desc = "A large piece of space-resistant printed paper. [desc]" - -/obj/structure/sign/poster/proc/randomise(base_type) - var/list/poster_types = subtypesof(base_type) - var/list/approved_types = list() - for(var/t in poster_types) - var/obj/structure/sign/poster/T = t - if(initial(T.icon_state) && !initial(T.never_random)) - approved_types |= T - - var/obj/structure/sign/poster/selected = pick(approved_types) - - name = initial(selected.name) - desc = initial(selected.desc) - icon_state = initial(selected.icon_state) - poster_item_name = initial(selected.poster_item_name) - poster_item_desc = initial(selected.poster_item_desc) - poster_item_icon_state = initial(selected.poster_item_icon_state) - ruined = initial(selected.ruined) - -/obj/structure/sign/poster/screwdriver_act(mob/user, obj/item/I) - return - -/obj/structure/sign/poster/wirecutter_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - if(ruined) - to_chat(user, "You remove the remnants of the poster.") - qdel(src) - else - to_chat(user, "You carefully remove the poster from the wall.") - roll_and_drop(user.loc) - -/obj/structure/sign/poster/attack_hand(mob/user) - if(ruined) - return - visible_message("[user] rips [src] in a single, decisive motion!" ) - playsound(src.loc, 'sound/items/poster_ripped.ogg', 100, 1) - - var/obj/structure/sign/poster/ripped/R = new(loc) - R.pixel_y = pixel_y - R.pixel_x = pixel_x - R.add_fingerprint(user) - qdel(src) - -/obj/structure/sign/poster/proc/roll_and_drop(loc) - if(ruined) - qdel(src) - return - pixel_x = 0 - pixel_y = 0 - var/obj/item/poster/P = new(loc, src) - forceMove(P) - return P - -//seperated to reduce code duplication. Moved here for ease of reference and to unclutter r_wall/attackby() -/turf/simulated/wall/proc/place_poster(obj/item/poster/P, mob/user) - if(!P.poster_structure) - return - var/stuff_on_wall = 0 - for(var/obj/O in contents) //Let's see if it already has a poster on it or too much stuff - if(istype(O, /obj/structure/sign/poster)) - to_chat(user, "The wall is far too cluttered to place a poster!") - return - stuff_on_wall++ - if(stuff_on_wall >= 4) - to_chat(user, "The wall is far too cluttered to place a poster!") - return - - to_chat(user, "You start placing the poster on the wall...")//Looks like it's uncluttered enough. Place the poster. - - var/obj/structure/sign/poster/D = P.poster_structure - - var/temp_loc = user.loc - - switch(getRelativeDirection(user, src)) - if(NORTH) - D.pixel_x = 0 - D.pixel_y = 32 - if(EAST) - D.pixel_x = 32 - D.pixel_y = 0 - if(SOUTH) - D.pixel_x = 0 - D.pixel_y = -32 - if(WEST) - D.pixel_x = -32 - D.pixel_y = 0 - else - to_chat(user, "You cannot reach the wall from here!") - return - - flick("poster_being_set", D) - D.forceMove(temp_loc) - qdel(P) //delete it now to cut down on sanity checks afterwards. Agouri's code supports rerolling it anyway - playsound(D.loc, 'sound/effects/rustle1.ogg', 100, 1) - - if(do_after(user, PLACE_SPEED, target = src)) - if(!D || QDELETED(D)) - return - - if(iswallturf(src) && user && user.loc == temp_loc) //Let's check if everything is still there - to_chat(user, "You place the poster!") - playsound(D.loc, 'sound/effects/pageturn3.ogg', 100, 1) - return - - to_chat(user, "The poster falls down!") - D.roll_and_drop(temp_loc) - - -////////////////////////////////POSTER VARIATIONS//////////////////////////////// - -/obj/structure/sign/poster/ripped - ruined = TRUE - icon_state = "poster_ripped" - name = "ripped poster" - desc = "You can't make out anything from the poster's original print. It's ruined." - -/obj/structure/sign/poster/random - name = "random poster" // could even be ripped - icon_state = "random_anything" - never_random = TRUE - random_basetype = /obj/structure/sign/poster - -/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" - -/obj/structure/sign/poster/contraband/random - name = "random contraband poster" - icon_state = "random_contraband" - never_random = TRUE - random_basetype = /obj/structure/sign/poster/contraband - -/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" - -/obj/structure/sign/poster/contraband/atmosia_independence - name = "Atmosia Declaration of Independence" - desc = "A relic of a failed rebellion." - icon_state = "poster2" - -/obj/structure/sign/poster/contraband/fun_police - name = "Fun Police" - desc = "A poster condemning the station's security forces." - icon_state = "poster3" - -/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" - -/obj/structure/sign/poster/contraband/syndicate_recruitment - name = "Syndicate Recruitment" - desc = "See the galaxy! Shatter corrupt megacorporations! Join today!" - icon_state = "poster5" - -/obj/structure/sign/poster/contraband/clown - name = "Clown" - desc = "Honk." - icon_state = "poster6" - -/obj/structure/sign/poster/contraband/smoke - name = "Smoke" - desc = "A poster advertising a rival corporate brand of cigarettes." - icon_state = "poster7" - -/obj/structure/sign/poster/contraband/grey_tide - name = "Grey Tide" - desc = "A rebellious poster symbolizing assistant solidarity." - icon_state = "poster8" - -/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" - -/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" - -/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" - -/obj/structure/sign/poster/contraband/ambrosia_vulgaris - name = "Ambrosia Vulgaris" - desc = "This poster is lookin' pretty trippy man." - icon_state = "poster12" - -/obj/structure/sign/poster/contraband/donut_corp - name = "Donut Corp." - desc = "This poster is an unauthorized advertisement for Donut Corp." - icon_state = "poster13" - -/obj/structure/sign/poster/contraband/eat - name = "EAT." - desc = "This poster promotes rank gluttony." - icon_state = "poster14" - -/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 CentComm." - icon_state = "poster15" - -/obj/structure/sign/poster/contraband/power - name = "Power" - desc = "A poster that positions the seat of power outside Nanotrasen." - icon_state = "poster16" - -/obj/structure/sign/poster/contraband/power_people - name = "Power to the people" - desc = "Screw those EDF guys!" - icon_state = "poster17" - -/obj/structure/sign/poster/contraband/communist_state - name = "Communist State" - desc = "All hail the Communist party!" - icon_state = "poster18" - -/obj/structure/sign/poster/contraband/lamarr - name = "Lamarr" - desc = "This poster depicts Lamarr. Probably made by a traitorous Research Director." - icon_state = "poster19" - -/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" - -/obj/structure/sign/poster/contraband/borg_fancy_2 - name = "Borg Fancy v2" - desc = "Borg Fancy, Now only taking the most fancy." - icon_state = "poster21" - -/obj/structure/sign/poster/contraband/kss13 - name = "Kosmicheskaya Stantsiya 13 Does Not Exist" - desc = "A poster mocking CentComm's denial of the existence of the derelict station near Space Station 13." - icon_state = "poster22" - -/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 - name = "C-20r" - desc = "A poster advertising the Scarborough Arms C-20r." - icon_state = "poster24" - -/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" - -/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" - -/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" - -/obj/structure/sign/poster/contraband/energy_swords - name = "Energy Swords" - desc = "All the colors of the bloody murder rainbow." - icon_state = "poster29" - -/obj/structure/sign/poster/contraband/red_rum - name = "Red Rum" - desc = "Looking at this poster makes you want to kill." - icon_state = "poster30" - -/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" - -/obj/structure/sign/poster/contraband/punch_shit - name = "Punch Shit" - desc = "Fight things for no reason, like a man!" - icon_state = "poster32" - -/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" - -/obj/structure/sign/poster/official - poster_item_name = "motivational poster" - poster_item_desc = "An official Nanotrasen-issued poster to foster a compliant and obedient workforce. It comes with state-of-the-art adhesive backing, for easy pinning to any vertical surface." - poster_item_icon_state = "rolled_poster_legit" - -/obj/structure/sign/poster/official/random - name = "random official poster" - random_basetype = /obj/structure/sign/poster/official - icon_state = "random_official" - never_random = TRUE - -/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" - -/obj/structure/sign/poster/official/nanotrasen_logo - name = "Nanotrasen Logo" - desc = "A poster depicting the Nanotrasen logo." - icon_state = "poster2_legit" - -/obj/structure/sign/poster/official/cleanliness - name = "Cleanliness" - desc = "A poster warning of the dangers of poor hygiene." - icon_state = "poster3_legit" - -/obj/structure/sign/poster/official/help_others - name = "Help Others" - desc = "A poster encouraging you to help fellow crewmembers." - icon_state = "poster4_legit" - -/obj/structure/sign/poster/official/build - name = "Build" - desc = "A poster glorifying the engineering team." - icon_state = "poster5_legit" - -/obj/structure/sign/poster/official/bless_this_spess - name = "Bless This Spess" - desc = "A poster blessing this area." - icon_state = "poster6_legit" - -/obj/structure/sign/poster/official/science - name = "Science" - desc = "A poster depicting an atom." - icon_state = "poster7_legit" - -/obj/structure/sign/poster/official/ian - name = "Ian" - desc = "Arf arf. Yap." - icon_state = "poster8_legit" - -/obj/structure/sign/poster/official/obey - name = "Obey" - desc = "A poster instructing the viewer to obey authority." - icon_state = "poster9_legit" - -/obj/structure/sign/poster/official/walk - name = "Walk" - desc = "A poster instructing the viewer to walk instead of running." - icon_state = "poster10_legit" - -/obj/structure/sign/poster/official/state_laws - name = "State Laws" - desc = "A poster instructing cyborgs to state their laws." - icon_state = "poster11_legit" - -/obj/structure/sign/poster/official/love_ian - name = "Love Ian" - desc = "Ian is love, Ian is life." - icon_state = "poster12_legit" - -/obj/structure/sign/poster/official/space_cops - name = "Space Cops." - desc = "A poster advertising the television show Space Cops." - icon_state = "poster13_legit" - -/obj/structure/sign/poster/official/ue_no - name = "Ue No." - desc = "This thing is all in Japanese." - icon_state = "poster14_legit" - -/obj/structure/sign/poster/official/get_your_legs - name = "Get Your LEGS" - desc = "LEGS: Leadership, Experience, Genius, Subordination." - icon_state = "poster15_legit" - -/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" - -/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" - -/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" - -/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" - -/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" - -/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" - -/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" - -/obj/structure/sign/poster/official/ion_rifle - name = "Ion Rifle" - desc = "A poster displaying an Ion Rifle." - icon_state = "poster23_legit" - -/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" - -/obj/structure/sign/poster/official/cohiba_robusto_ad - name = "Cohiba Robusto Ad" - desc = "Cohiba Robusto, the classy cigar." - icon_state = "poster25_legit" - -/obj/structure/sign/poster/official/anniversary_vintage_reprint - name = "50th Anniversary Vintage Reprint" - desc = "A reprint of a poster from 2505, commemorating the 50th Anniversery of Nanoposters Manufacturing, a subsidiary of Nanotrasen." - icon_state = "poster26_legit" - -/obj/structure/sign/poster/official/fruit_bowl - name = "Fruit Bowl" - desc = "Simple, yet awe-inspiring." - icon_state = "poster27_legit" - -/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" - desc = "Enlist in the Nanotrasen ERT 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/spiders - name = "Spider Risk" - desc = "A poster detailing what to do when giant spiders are seen." - icon_state = "poster34_legit" - -/obj/structure/sign/poster/official/kill_syndicate - name = "Kill Syndicate" - desc = "A poster demanding that all crew should be ready to fight the Syndicate." - icon_state = "poster35_legit" - -/obj/structure/sign/poster/official/air1 - name = "Information on Air" - desc = "A poster providing visual aid to remind crew of air canisters." - icon_state = "poster36_legit" - -/obj/structure/sign/poster/official/air2 - name = "Information on Air" - desc = "A poster providing visual aid to remind crew of air canisters." - icon_state = "poster37_legit" - -/obj/structure/sign/poster/official/dig - name = "Dig for Glory!" - desc = "A poster trying to convince the crew to mine for ore." - icon_state = "poster38_legit" - -/obj/structure/sign/poster/official/religious - name = "Religious Poster" - desc = "A generic religious poster telling you to believe." - icon_state = "poster39_legit" - -/obj/structure/sign/poster/official/healthy - name = "Stay Healthy!" - desc = "A healthy crew is a happy crew!" - icon_state = "poster40_legit" - -/obj/structure/sign/poster/official/darkpurpl - name = "Dark Purp-L" - desc = "A poster for the band \"Dark Purp-L\". They label their music 'Plasmawave'; mixed from various space age sounds like creaking hulls and plasma emitters, it's gained traction in recent years amongst bored ship engineers. " - icon_state = "poster41_legit" - -/obj/structure/sign/poster/official/root - name = "Root Song" - desc = "A poster for all-Diona Jazz band \"Root Song\". When a travelling jazz band's ship crashed on a Diona overgrowth planet, a whole host of musically-inclined Dionea sprung forth. Though the beloved band members sadly perished in the crash, their love of Jazz lived on with these Dionea, who travel the galaxy in the repaired wreck of that ship, under the moniker \"Root Song\"." - icon_state = "poster42_legit" - -/obj/structure/sign/poster/official/core - name = "CO!RE" - desc = "A poster for the all-Slime melodic rap label CO!RE. Known for their unique blend of hard-hitting vocals and traditional Xarxis woodwind instruments, CO!RE took the Federation R&B scene by storm during their debut, and has since engaged in several high-intensity tours across the sector." - icon_state = "poster43_legit" - -/obj/structure/sign/poster/official/metal - name = "METAL" - desc = "A poster for an IPC metal band, aptly named \"METAL\". Though their chassis are dated and badly damaged, they rage on evermore! The electric guitarist, SKULL, has an amp built into their head." - icon_state = "poster44_legit" - -/obj/structure/sign/poster/official/kpop - name = "Kidan Pop" - desc = "A poster for a Kidan boyband known as \"K-Pop\". Though other species find their chittering vocals grating and tuneless, they're wildly popular among young Kidan living in the TSF." - icon_state = "poster45_legit" - -/obj/structure/sign/poster/official/graydays - name = "Gray Days" - desc = "A poster for an emo band of greys. They're known to play a form of Death Metal, but it's so quiet you can only barely hear the words. If you turn the speaker way up, the lyrics are mournful and deep; just remember to turn it back down once you're finished listening." - icon_state = "poster46_legit" - -/obj/structure/sign/poster/official/unathicrush - name = "CRUSH" - desc = "A poster for a unathi band called \"Heart Crush\". They mostly write diss tracks about their bitter rivals, the band \"Heart Smash\". Never tell one of their fans you like the other band, or you can expect a violent argument." - icon_state = "poster47_legit" - -/obj/structure/sign/poster/official/unathismash - name = "SMASH" - desc = "A poster for a unathi band called \"Heart Smash\". They're famously bitter rivals with a very similar band, \"Heart Crush\", who they constantly accuse of copying their style. After multiple assaults and restraining orders, the two are back on tour." - icon_state = "poster48_legit" - -/obj/structure/sign/poster/official/star - name = "Star" - desc = "A poster for a musical called \"Star\". The lead singer and actor searches across the galaxy in a cruise ship for his one true love - the titular \"Star\"." - icon_state = "poster49_legit" - -/obj/structure/sign/poster/official/soul - name = "Kindred Soul" - desc = "A poster for a rarely-seen orchestral band known as \"Kindred Soul\". Those who have been lucky enough to catch a performance say their vocals are deeply moving." - icon_state = "poster50_legit" - -/obj/structure/sign/poster/official/choir - name = "\"Skreethoven's\" Choir" - desc = "A poster for a classical Vox performance group including a full choir and orchestra. The chorists have a great harmony. Despite his violent protestation, the star organist can't shake his popular nickname, \"Skreethoven\"." - icon_state = "poster51_legit" - -#undef PLACE_SPEED diff --git a/code/game/objects/effects/decals/turf_decal.dm b/code/game/objects/effects/decals/turf_decal.dm deleted file mode 100644 index 1ae2141747535..0000000000000 --- a/code/game/objects/effects/decals/turf_decal.dm +++ /dev/null @@ -1,13 +0,0 @@ -/obj/effect/turf_decal - icon = 'icons/turf/decals.dmi' - icon_state = "warningline" - layer = TURF_DECAL_LAYER - -/obj/effect/turf_decal/Initialize(mapload, _dir) - ..() - . = INITIALIZE_HINT_QDEL - var/turf/T = loc - if(!istype(T)) //you know this will happen somehow - CRASH("Turf decal initialized in an object/nullspace") - - T.AddElement(/datum/element/decal, icon, icon_state, _dir || dir, layer, alpha, color, FALSE, null) diff --git a/code/game/objects/effects/decals/turfdecals/markings.dm b/code/game/objects/effects/decals/turfdecals/markings.dm deleted file mode 100644 index 304f6c83d65c7..0000000000000 --- a/code/game/objects/effects/decals/turfdecals/markings.dm +++ /dev/null @@ -1,230 +0,0 @@ -/obj/effect/turf_decal/stripes - icon_state = "warn_full" - -/obj/effect/turf_decal/stripes/line - icon_state = "warningline" - -/obj/effect/turf_decal/stripes/end - icon_state = "warn_end" - -/obj/effect/turf_decal/stripes/corner - icon_state = "warninglinecorner" - -/obj/effect/turf_decal/stripes/box - icon_state = "warn_box" - -/obj/effect/turf_decal/stripes/asteroid - icon_state = "ast_warn_full" - -/obj/effect/turf_decal/stripes/asteroid/line - icon_state = "ast_warn" - -/obj/effect/turf_decal/stripes/asteroid/end - icon_state = "ast_warn_end" - -/obj/effect/turf_decal/stripes/asteroid/corner - icon_state = "ast_warn_corner" - -/obj/effect/turf_decal/stripes/asteroid/box - icon_state = "ast_warn_box" - -/obj/effect/turf_decal/stripes/white - icon_state = "warn_full_white" - -/obj/effect/turf_decal/stripes/white/line - icon_state = "warningline_white" - -/obj/effect/turf_decal/stripes/white/end - icon_state = "warn_end_white" - -/obj/effect/turf_decal/stripes/white/corner - icon_state = "warninglinecorner_white" - -/obj/effect/turf_decal/stripes/white/box - icon_state = "warn_box_white" - -/obj/effect/turf_decal/stripes/red - icon_state = "warn_full_red" - -/obj/effect/turf_decal/stripes/red/line - icon_state = "warningline_red" - -/obj/effect/turf_decal/stripes/red/end - icon_state = "warn_end_red" - -/obj/effect/turf_decal/stripes/red/corner - icon_state = "warninglinecorner_red" - -/obj/effect/turf_decal/stripes/red/box - icon_state = "warn_box_red" - -/obj/effect/turf_decal/delivery - icon_state = "delivery" - -/obj/effect/turf_decal/delivery/partial - icon_state = "3" - -/obj/effect/turf_decal/delivery/hollow - icon_state = "bot" - -/obj/effect/turf_decal/delivery/hollow/right - icon_state = "bot_right" - -/obj/effect/turf_decal/delivery/hollow/left - icon_state = "bot_left" - -/obj/effect/turf_decal/delivery/white - icon_state = "delivery_white" - -/obj/effect/turf_decal/delivery/white/partial - icon_state = "13" - -/obj/effect/turf_decal/delivery/white/hollow - icon_state = "15" - -/obj/effect/turf_decal/delivery/white/hollow/right - icon_state = "bot_right_white" - -/obj/effect/turf_decal/delivery/white/hollow/left - icon_state = "bot_left_white" - -/obj/effect/turf_decal/delivery/red - icon_state = "delivery_red" - -/obj/effect/turf_decal/delivery/red/partial - icon_state = "7" - -/obj/effect/turf_decal/delivery/red/hollow - icon_state = "bot_red" - -/obj/effect/turf_decal/delivery/red/hollow/right - icon_state = "bot_right_red" - -/obj/effect/turf_decal/delivery/red/hollow/left - icon_state = "bot_left_red" - -/obj/effect/turf_decal/delivery/green - icon_state = "11" - -/obj/effect/turf_decal/delivery/green/partial - icon_state = "10" - -/obj/effect/turf_decal/delivery/green/hollow - icon_state = "12" - -/obj/effect/turf_decal/delivery/blue - icon_state = "17" - -/obj/effect/turf_decal/delivery/blue/partial - icon_state = "16" - -/obj/effect/turf_decal/delivery/blue/hollow - icon_state = "18" - -/obj/effect/turf_decal/loading_area - icon_state = "loadingarea" - -/obj/effect/turf_decal/loading_area/white - icon_state = "loadingarea_white" - -/obj/effect/turf_decal/loading_area/red - icon_state = "loadingarea_red" - -/obj/effect/turf_decal/caution - icon_state = "caution" - -/obj/effect/turf_decal/caution/white - icon_state = "caution_white" - -/obj/effect/turf_decal/caution/red - icon_state = "caution_red" - -/obj/effect/turf_decal/caution/stand_clear - icon_state = "stand_clear" - -/obj/effect/turf_decal/caution/stand_clear/white - icon_state = "stand_clear_white" - -/obj/effect/turf_decal/caution/stand_clear/red - icon_state = "stand_clear_red" - -/obj/effect/turf_decal/arrows - icon_state = "arrows" - -/obj/effect/turf_decal/arrows/white - icon_state = "arrows_white" - -/obj/effect/turf_decal/arrows/red - icon_state = "arrows_red" - -/obj/effect/turf_decal/arrows/black - icon_state = "4" - -/obj/effect/turf_decal/box - icon_state = "box" - -/obj/effect/turf_decal/box/corners - icon_state = "box_corners" - -/obj/effect/turf_decal/box/white - icon_state = "box_white" - -/obj/effect/turf_decal/box/white/corners - icon_state = "box_corners_white" - -/obj/effect/turf_decal/box/red - icon_state = "box_red" - -/obj/effect/turf_decal/box/red/corners - icon_state = "box_corners_red" - -/obj/effect/turf_decal/plaque - icon_state = "plaque" - -/obj/effect/turf_decal/woodsiding - icon_state = "woodsidingline" - -/obj/effect/turf_decal/woodsiding/end - icon_state = "woodsiding_end" - -/obj/effect/turf_decal/woodsiding/box - icon_state = "woodsiding_box" - -/obj/effect/turf_decal/siding - icon_state = "sidingline" - -/obj/effect/turf_decal/siding/end - icon_state = "siding_end" - -/obj/effect/turf_decal/siding/box - icon_state = "siding_box" - -/obj/effect/turf_decal/raven/one - icon_state = "RAVEN1" - -/obj/effect/turf_decal/raven/two - icon_state = "RAVEN2" - -/obj/effect/turf_decal/raven/three - icon_state = "RAVEN3" - -/obj/effect/turf_decal/raven/four - icon_state = "RAVEN4" - -/obj/effect/turf_decal/raven/five - icon_state = "RAVEN5" - -/obj/effect/turf_decal/raven/six - icon_state = "RAVEN6" - -/obj/effect/turf_decal/raven/seven - icon_state = "RAVEN7" - -/obj/effect/turf_decal/raven/eight - icon_state = "RAVEN8" - -/obj/effect/turf_decal/raven/nine - icon_state = "RAVEN9" - -/obj/effect/turf_decal/blue_corner - icon_state = "darkbluecorners" diff --git a/code/game/objects/effects/decals/turfdecals/weather_decals.dm b/code/game/objects/effects/decals/turfdecals/weather_decals.dm deleted file mode 100644 index f00a76df5e762..0000000000000 --- a/code/game/objects/effects/decals/turfdecals/weather_decals.dm +++ /dev/null @@ -1,13 +0,0 @@ -/obj/effect/turf_decal/weather - name = "sandy floor" - icon_state = "sandyfloor" - -/obj/effect/turf_decal/weather/snow - name = "snowy floor" - icon = 'icons/turf/snow.dmi' - icon_state = "snow" - -/obj/effect/turf_decal/weather/snow/corner - name = "snow corner piece" - icon = 'icons/turf/snow.dmi' - icon_state = "snow_corner" diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm deleted file mode 100644 index cbe122c4d7420..0000000000000 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ /dev/null @@ -1,305 +0,0 @@ -// Foam -// Similar to smoke, but spreads out more -// metal foams leave behind a foamed metal wall - -/obj/effect/particle_effect/foam - name = "foam" - icon_state = "foam" - opacity = FALSE - density = FALSE - gender = PLURAL - layer = OBJ_LAYER + 0.9 - animate_movement = NO_STEPS - /// How many times this one bit of foam can spread around itself - var/spread_amount = 3 - /// How long it takes this to initially start spreading after being dispersed - var/spread_time = 0.9 SECONDS - /// How long it takes this, once it's spread, to stop spreading and disperse its chems - var/solidify_time = 12 SECONDS - /// Whether it reacts on or after dispersion (or both) - var/react_mode = FOAM_REACT_ON_DISSIPATE | FOAM_REACT_BEFORE_SPREAD - /// Maximum amount of reagents gained by spreading onto a foamed tile - var/max_amount_on_spread = 27 - /// We will never fill a mob with more than this many units of a given reagent - var/max_reagent_filling = 25 - /// Whether or not to spread at a range when spreading - var/spread_at_range = TRUE - -/obj/effect/particle_effect/foam/Initialize(mapload) - . = ..() - create_reagents(25) - playsound(src, 'sound/effects/bubbles2.ogg', 80, TRUE, -3) - addtimer(CALLBACK(src, PROC_REF(initial_process)), spread_time) - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered) - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/effect/particle_effect/foam/proc/disperse_reagents() - if(!reagents) - return - reagents.handle_reactions() - for(var/atom/A in (spread_at_range ? oview(1, src) : view(0, src))) - if(A == src) - continue - fill_with_reagents(A) - -/obj/effect/particle_effect/foam/proc/fill_with_reagents(atom/A) - if(reagents.total_volume) - var/fraction = 5 / reagents.total_volume - reagents.reaction(A, REAGENT_TOUCH, fraction) - - if(iscarbon(A) && !QDELETED(A)) - var/mob/living/carbon/foamed = A - for(var/datum/reagent/R as anything in reagents.reagent_list) - var/amount = foamed.reagents?.get_reagent_amount(R.id) - var/foam_content_amount = reagents.get_reagent_amount(R.id) - if(amount < max_reagent_filling) - foamed.reagents?.add_reagent(R.id, min(round(foam_content_amount / 2), 15)) - -/obj/effect/particle_effect/foam/proc/initial_process() - process() - START_PROCESSING(SSobj, src) - addtimer(CALLBACK(src, PROC_REF(stop_processing)), solidify_time) - addtimer(CALLBACK(src, PROC_REF(dissipate)), solidify_time + 3 SECONDS) - -/obj/effect/particle_effect/foam/proc/stop_processing() - STOP_PROCESSING(SSobj, src) - -/obj/effect/particle_effect/foam/proc/dissipate() - - if(react_mode & FOAM_REACT_ON_DISSIPATE) - addtimer(CALLBACK(src, PROC_REF(disperse_reagents)), 0.3 SECONDS) - flick("[icon_state]-disolve", src) - QDEL_IN(src, 0.5 SECONDS) - -/obj/effect/particle_effect/foam/proc/try_spread_to(turf/target_turf) - if(!target_turf || !target_turf.Enter(src)) - return - - var/obj/effect/particle_effect/foam/new_foam = locate() in target_turf - - if(new_foam) - return - - new_foam = new type(target_turf) - new_foam.spread_amount = spread_amount - new_foam.spread_time = spread_time - new_foam.solidify_time = solidify_time - new_foam.max_amount_on_spread = max_amount_on_spread - new_foam.spread_at_range = spread_at_range - new_foam.react_mode = react_mode - new_foam.max_reagent_filling = max_reagent_filling - - // add the new amount of foam - if(reagents) - for(var/datum/reagent/R in reagents.reagent_list) - new_foam.reagents.add_reagent(R.id, min(R.volume, 5), R.data, reagents.chem_temp) - new_foam.color = mix_color_from_reagents(reagents.reagent_list) - if(react_mode & FOAM_REACT_BEFORE_SPREAD) - new_foam.disperse_reagents() - -/obj/effect/particle_effect/foam/proc/spread() - for(var/direction in GLOB.cardinal) - var/turf/T = get_step(src, direction) - try_spread_to(T) - -/obj/effect/particle_effect/foam/proc/generate_color() - color = mix_color_from_reagents(reagents.reagent_list) - -/obj/effect/particle_effect/foam/process() - if(react_mode & FOAM_REACT_DURING_SPREAD) - disperse_reagents() - - if(--spread_amount < 0) - return - - spread() - -// foam disolves when heated -// except metal foams -/obj/effect/particle_effect/foam/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) //Don't heat the reagents inside - return - -/obj/effect/particle_effect/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) // overriden to prevent weird behaviors with heating reagents inside - if(prob(max(0, exposed_temperature - 475))) - flick("[icon_state]-disolve", src) - QDEL_IN(src, 0.5 SECONDS) - -/obj/effect/particle_effect/foam/proc/on_atom_entered(datum/source, atom/movable/entered) - if(!iscarbon(entered)) - return - var/mob/living/carbon/M = entered - if((M.slip("foam", 10 SECONDS) || IS_HORIZONTAL(M)) && reagents) - fill_with_reagents(M) - -/obj/effect/particle_effect/foam/metal - name = "metal foam" - icon_state = "mfoam" // finally mentor foam - spread_time = 1.2 SECONDS - react_mode = FOAM_REACT_ON_DISSIPATE - /// Represents the icon state that we'll become when we solidify - var/metal_kind = METAL_FOAM_ALUMINUM - -/obj/effect/particle_effect/foam/metal/generate_color() - return // metal foam is boring - -/obj/effect/particle_effect/foam/metal/disperse_reagents() - var/turf/T = get_turf(src) - if(isspaceturf(T) && !istype(T, /turf/space/transit)) - T.ChangeTurf(/turf/simulated/floor/plating/metalfoam) - var/turf/simulated/floor/plating/metalfoam/MF = get_turf(src) - MF.metal_kind = metal_kind - - var/obj/structure/foamedmetal/M = new(loc) - M.metal = metal_kind - M.update_state() - -/obj/effect/particle_effect/foam/metal/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - return - -/obj/effect/particle_effect/foam/metal/on_atom_entered(datum/source, atom/movable/entered) - return - -/datum/effect_system/foam_spread - effect_type = /obj/effect/particle_effect/foam - /// the size of the foam spread. - var/spread_size = 5 - /// the IDs of reagents present when the foam was mixed - var/list/carried_reagents - /// the temperature that the reagents in the foam will be set to - var/temperature = T0C - /// the reagents that we don't want in foam - var/list/banned_reagents = list("smoke_powder", "fluorosurfactant", "stimulants") - -/datum/effect_system/foam_spread/set_up(amt = 5, where, datum/reagents/carry) - spread_size = min(round(amt / 5, 1), 7) - if(isturf(where)) - location = where - else - location = get_turf(where) - - carried_reagents = list() - temperature = carry.chem_temp - - // bit of a hack here. Foam carries along any reagent also present in the glass it is mixed - // with (defaults to water if none is present). Rather than actually transfer the reagents, - // this makes a list of the reagent ids and spawns 1 unit of that reagent when the foam disolves. - - if(carry) - for(var/datum/reagent/R in carry.reagent_list) - carried_reagents[R.id] = R.volume - -/datum/effect_system/foam_spread/proc/setup_reagents(obj/effect/particle_effect/foam/working_foam) - if(!carried_reagents) - return - for(var/id in carried_reagents) - if(banned_reagents.Find("[id]")) - continue - var/datum/reagent/reagent_volume = carried_reagents[id] - working_foam.reagents.add_reagent(id, min(reagent_volume, 5), null, temperature) - working_foam.reagents.chem_temp = temperature - working_foam.color = mix_color_from_reagents(working_foam.reagents.reagent_list) - -/datum/effect_system/foam_spread/proc/spread() - var/obj/effect/particle_effect/foam/working_foam = locate() in location - if(working_foam) - working_foam.spread_amount = min(working_foam.spread_amount + working_foam.spread_amount, working_foam.max_amount_on_spread) - return - - working_foam = new effect_type(location) - working_foam.spread_amount = spread_size - setup_reagents(working_foam) - -/datum/effect_system/foam_spread/start() - INVOKE_ASYNC(src, PROC_REF(spread)) - -/datum/effect_system/foam_spread/cleaner - -/datum/effect_system/foam_spread/cleaner/setup_reagents(obj/effect/particle_effect/foam/F) - F.react_mode = FOAM_REACT_ON_DISSIPATE - F.spread_at_range = TRUE - F.color = mix_color_from_reagents(F.reagents.reagent_list) - -/datum/effect_system/foam_spread/metal - /// The type of metal that will be formed from this - var/metal_type = METAL_FOAM_ALUMINUM - effect_type = /obj/effect/particle_effect/foam/metal - -/datum/effect_system/foam_spread/metal/set_up(amt, where, datum/reagents/carry, _metal_type = METAL_FOAM_ALUMINUM) - . = ..() - metal_type = _metal_type - -/datum/effect_system/foam_spread/metal/setup_reagents() - return - -/obj/effect/particle_effect/foam/oil - react_mode = FOAM_REACT_DURING_SPREAD | FOAM_REACT_ON_DISSIPATE - spread_at_range = FALSE - -/datum/effect_system/foam_spread/oil - effect_type = /obj/effect/particle_effect/foam/oil - temperature = 1000 - -// wall formed by metal foams -// dense and opaque, but easy to break - -/obj/structure/foamedmetal - name = "foamed metal" - desc = "A lightweight foamed metal wall." - icon = 'icons/effects/effects.dmi' - icon_state = "metalfoam" - resistance_flags = FIRE_PROOF | ACID_PROOF - density = TRUE - opacity = TRUE // changed in New() - anchored = TRUE - max_integrity = 20 - var/metal = METAL_FOAM_ALUMINUM - -/obj/structure/foamedmetal/Initialize(mapload) - . = ..() - recalculate_atmos_connectivity() - -/obj/structure/foamedmetal/Destroy() - var/turf/T = get_turf(src) - . = ..() - T.recalculate_atmos_connectivity() - -/obj/structure/foamedmetal/Move() - var/turf/T = loc - ..() - move_update_air(T) - -/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - playsound(src.loc, 'sound/weapons/tap.ogg', 100, TRUE) - -/obj/structure/foamedmetal/proc/update_state() - if(metal == METAL_FOAM_ALUMINUM) - max_integrity = 20 - obj_integrity = max_integrity - else - max_integrity = 50 - obj_integrity = max_integrity - update_icon(UPDATE_ICON_STATE) - -/obj/structure/foamedmetal/update_icon_state() - if(metal == METAL_FOAM_ALUMINUM) - icon_state = "metalfoam" - else - icon_state = "ironfoam" - -/obj/structure/foamedmetal/attack_hand(mob/user) - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - if(prob(75 - metal * 25)) - user.visible_message("[user] smashes through [src].", "You smash through [src].") - qdel(src) - else - to_chat(user, "You hit the metal foam but bounce off it.") - playsound(loc, 'sound/weapons/tap.ogg', 100, 1) - -/obj/structure/foamedmetal/CanPass(atom/movable/mover, border_dir) - return !density - -/obj/structure/foamedmetal/CanAtmosPass(direction) - return !density diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm deleted file mode 100644 index c1484a1969cee..0000000000000 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ /dev/null @@ -1,272 +0,0 @@ -///////////////////////////////////////////// -//// SMOKE SYSTEMS -// direct can be optionally added when set_up, to make the smoke always travel in one direction -// in case you wanted a vent to always smoke north for example -///////////////////////////////////////////// - -/obj/effect/particle_effect/smoke - name = "smoke" - icon_state = "smoke" - icon = 'icons/effects/96x96.dmi' - pixel_x = -32 - pixel_y = -32 - opacity = TRUE - anchored = FALSE - plane = SMOKE_PLANE - layer = FLY_LAYER - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - var/steps = 0 - var/lifetime = 10 SECONDS_TO_LIFE_CYCLES - var/direction - var/causes_coughing = FALSE - -/obj/effect/particle_effect/smoke/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(smoke_mob) - ) - AddElement(/datum/element/connect_loc, loc_connections) - RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(smoke_mob)) - GLOB.smokes_active++ - lifetime += rand(-1, 1) - create_reagents(10) - -/obj/effect/particle_effect/smoke/Destroy() - animate(src, 2 SECONDS, alpha = 0, easing = EASE_IN | CIRCULAR_EASING) - STOP_PROCESSING(SSobj, src) - UnregisterSignal(src, COMSIG_MOVABLE_MOVED) - GLOB.smokes_active-- - return ..() - -/obj/effect/particle_effect/smoke/proc/fade_out(frames = 16) - animate(src, 2 SECONDS, alpha = 0, easing = EASE_IN | CIRCULAR_EASING) - -/obj/effect/particle_effect/smoke/proc/kill_smoke() - STOP_PROCESSING(SSobj, src) - INVOKE_ASYNC(src, PROC_REF(fade_out)) - QDEL_IN(src, 2 SECONDS) - -/obj/effect/particle_effect/smoke/process() - lifetime-- - if(lifetime < 1) - kill_smoke() - return FALSE - if(steps >= 1) - step(src,direction) - steps-- - for(var/mob/living/carbon/M in range(1, src)) - smoke_mob(M) - return TRUE - -/obj/effect/particle_effect/smoke/proc/smoke_mob(mob/living/carbon/breather) - SIGNAL_HANDLER // COMSIG_ATOM_ENTERED + COMSIG_MOVABLE_MOVED - if(!istype(breather)) - return FALSE - if(lifetime < 1) - return FALSE - if(!breather.can_breathe_gas()) - return FALSE - if(breather.smoke_delay) - addtimer(CALLBACK(src, PROC_REF(remove_smoke_delay), breather), 1 SECONDS) //Sometimes during testing I'd somehow end up with a permanent smoke delay, so this is in case of that - return FALSE - if(reagents) - reagents.trans_to(breather, reagents.total_volume) - if(causes_coughing) - breather.drop_item() - breather.adjustOxyLoss(1) - INVOKE_ASYNC(breather, TYPE_PROC_REF(/mob/living/carbon, emote), "cough") - breather.smoke_delay++ - addtimer(CALLBACK(src, PROC_REF(remove_smoke_delay), breather), 1 SECONDS) - return TRUE - -/obj/effect/particle_effect/smoke/proc/remove_smoke_delay(mob/living/carbon/C) - if(C) - C.smoke_delay = 0 - -/datum/effect_system/smoke_spread - effect_type = /obj/effect/particle_effect/smoke - var/datum/reagents/chemicals_to_add - var/units_per_smoke = 0 - var/direction - -/datum/effect_system/smoke_spread/set_up(amount = 5, only_cardinals = FALSE, source, desired_direction, datum/reagents/chemicals = null) - number = clamp(amount, 0, 20) - cardinals = only_cardinals - location = get_turf(source) - if(desired_direction) - direction = desired_direction - if(chemicals) - chemicals_to_add = chemicals - units_per_smoke = clamp((chemicals_to_add.total_volume / number), 0, 10) - -/datum/effect_system/smoke_spread/start() - var/smoke_budget = GLOBAL_SMOKE_LIMIT - GLOB.smokes_active - if(smoke_budget < number) //Dream blunt rotation scenario - return - for(var/i in 1 to number) - if(holder) - location = get_turf(holder) - var/obj/effect/particle_effect/smoke/S = new effect_type(location, (chemicals_to_add ? TRUE : FALSE)) - if(chemicals_to_add) - chemicals_to_add.copy_to(S, units_per_smoke) - S.color = mix_color_from_reagents(chemicals_to_add.reagent_list) - if(!direction) - if(cardinals) - S.direction = pick(GLOB.cardinal) - else - S.direction = pick(GLOB.alldirs) - else - S.direction = direction - S.steps = pick(0,1,1,1,2,2,2,3) - S.process() - -///////////////////////////////////////////// -// Bad smoke -///////////////////////////////////////////// - -/obj/effect/particle_effect/smoke/bad - lifetime = 16 SECONDS_TO_LIFE_CYCLES - causes_coughing = TRUE - -/obj/effect/particle_effect/smoke/bad/CanPass(atom/movable/mover, border_dir) - if(istype(mover, /obj/item/projectile/beam)) - var/obj/item/projectile/beam/B = mover - B.damage = (B.damage / 2) - return TRUE - -/datum/effect_system/smoke_spread/bad - effect_type = /obj/effect/particle_effect/smoke/bad - -/// Steam smoke -/datum/effect_system/smoke_spread/steam - effect_type = /obj/effect/particle_effect/smoke/steam - -/obj/effect/particle_effect/smoke/steam - color = COLOR_OFF_WHITE - lifetime = 10 SECONDS_TO_LIFE_CYCLES - causes_coughing = TRUE - -/obj/effect/particle_effect/smoke/steam/smoke_mob(mob/living/breather) - if(!istype(breather)) - return - if(IS_MINDFLAYER(breather)) - return // Mindflayers are fully immune to steam - if(!ishuman(breather)) - breather.adjustFireLoss(8) - return - - var/mob/living/carbon/human/human_crosser = breather - var/fire_armour = human_crosser.get_thermal_protection() - if(fire_armour >= FIRE_SUIT_MAX_TEMP_PROTECT || HAS_TRAIT(human_crosser, TRAIT_RESISTHEAT)) - return - - breather.adjustFireLoss(5) - if(prob(20)) - to_chat(breather, "You are being scalded by the hot steam!") - -///////////////////////////////////////////// -// Nanofrost smoke -///////////////////////////////////////////// - -/obj/effect/particle_effect/smoke/freezing - name = "nanofrost smoke" - color = "#B2FFFF" - opacity = FALSE - var/spread_range = 6 - lifetime = 0.5 SECONDS_TO_LIFE_CYCLES - -/datum/effect_system/smoke_spread/freezing - effect_type = /obj/effect/particle_effect/smoke/freezing - -/obj/effect/particle_effect/smoke/freezing/process() - . = ..() - var/turf/T = get_turf(src) - if(!istype(T)) - return - - for(var/obj/machinery/atmospherics/unary/vent_pump/V in T) - if(!isnull(V.welded) && !V.welded) //must be an unwelded vent pump. - V.welded = TRUE - V.update_icon() - V.visible_message("[V] was frozen shut!") - for(var/obj/machinery/atmospherics/unary/vent_scrubber/U in T) - if(!isnull(U.welded) && !U.welded) //must be an unwelded vent scrubber. - U.welded = TRUE - U.update_icon() - U.visible_message("[U] was frozen shut!") - for(var/mob/living/L in T) - L.ExtinguishMob() - for(var/obj/item/Item in T) - Item.extinguish() - - var/datum/milla_safe/nanofrost_extinguish/milla = new() - milla.invoke_async(src, T) - -/datum/milla_safe/nanofrost_extinguish/on_run(obj/effect/particle_effect/smoke/freezing/smoke, turf/T) - if(!istype(T)) - return - var/datum/gas_mixture/env = get_turf_air(T) - for(var/obj/effect/hotspot/fake/H in T) - qdel(H) - - if(env.fuel_burnt() == 0) - return - - env.set_temperature(2) - env.set_nitrogen(env.nitrogen() + env.toxins()) - env.set_toxins(0) - - if(smoke.spread_range <= 0 || smoke.lifetime > 0) - return - - // Spread the smoke, up to spread_range. - for(var/direction in list(NORTH, SOUTH, EAST, WEST)) - var/turf/neighbor = get_step(T, direction) - if(isnull(neighbor)) - continue - if(neighbor.density) - continue - var/has_nanofrost = FALSE - for(var/datum/effect_system/smoke_spread/freezing in neighbor) - has_nanofrost = TRUE - break - if(has_nanofrost) - continue - if(prob(50)) - continue - - var/obj/effect/particle_effect/smoke/freezing/new_smoke = new(neighbor) - new_smoke.spread_range = smoke.spread_range - 1 - -///////////////////////////////////////////// -// Sleep smoke -///////////////////////////////////////////// - -/obj/effect/particle_effect/smoke/sleeping - color = "#9C3636" - lifetime = 20 SECONDS_TO_LIFE_CYCLES - causes_coughing = TRUE - -/obj/effect/particle_effect/smoke/sleeping/process() - if(..()) - for(var/mob/living/carbon/M in range(1,src)) - smoke_mob(M) - -/obj/effect/particle_effect/smoke/sleeping/smoke_mob(mob/living/carbon/M) - if(..()) - M.Sleeping(20 SECONDS) - return TRUE - -/datum/effect_system/smoke_spread/sleeping - effect_type = /obj/effect/particle_effect/smoke/sleeping - -//////////////////////////////////// -// See-through smoke -/////////////////////////////////// -/obj/effect/particle_effect/smoke/transparent - opacity = FALSE - alpha = 125 - -/datum/effect_system/smoke_spread/transparent - effect_type = /obj/effect/particle_effect/smoke/transparent diff --git a/code/game/objects/effects/effect_system/effects_sparks.dm b/code/game/objects/effects/effect_system/effects_sparks.dm deleted file mode 100644 index 69798349d8cdc..0000000000000 --- a/code/game/objects/effects/effect_system/effects_sparks.dm +++ /dev/null @@ -1,78 +0,0 @@ -///////////////////////////////////////////// -//SPARK SYSTEM (like steam system) -// The attach(atom/atom) proc is optional, and can be called to attach the effect -// to something, like the RCD, so then you can just call start() and the sparks -// will always spawn at the items location. -///////////////////////////////////////////// - -/proc/do_sparks(n, c, source) - // n - number of sparks - // c - cardinals, bool, do the sparks only move in cardinal directions? - // source - source of the sparks. - - var/datum/effect_system/spark_spread/sparks = new - sparks.set_up(n, c, source) - sparks.autocleanup = TRUE - INVOKE_ASYNC(sparks, TYPE_PROC_REF(/datum/effect_system, start)) - -/obj/effect/particle_effect/sparks - name = "sparks" - desc = "it's a spark what do you need to know?" - icon_state = "sparks" - var/hotspottemp = 1000 - -/obj/effect/particle_effect/sparks/New() - ..() - playsound(src, "sparks", 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - var/turf/T = loc - if(isturf(T)) - T.hotspot_expose(hotspottemp, 1) - QDEL_IN(src, 20) - -/obj/effect/particle_effect/sparks/Destroy() - var/turf/T = loc - if(isturf(T)) - T.hotspot_expose(hotspottemp,1) - return ..() - -/obj/effect/particle_effect/sparks/Move() - ..() - var/turf/T = loc - if(isturf(T)) - T.hotspot_expose(hotspottemp,1) - -/datum/effect_system/spark_spread - effect_type = /obj/effect/particle_effect/sparks - -/datum/effect_system/spark_spread/generate_effect() - var/spark_budget = GLOBAL_SPARK_LIMIT - GLOB.sparks_active - if(spark_budget <= 0) - return - GLOB.sparks_active++ - return ..() - -/datum/effect_system/spark_spread/decrement_total_effect() - GLOB.sparks_active-- - return ..() - -////////////////////////////////// -//////SPARKLE FIREWORKS -///////////////////////////////// -//////////////////////////// -/obj/effect/particle_effect/sparks/sparkles - name = "sparkle" - icon = 'icons/obj/fireworks.dmi'//findback - icon_state = "sparkel" - hotspottemp = 3000 - -/obj/effect/particle_effect/sparks/sparkles/New() - var/icon/I = new(src.icon,src.icon_state) - var/r = rand(0,255) - var/g = rand(0,255) - var/b = rand(0,255) - I.Blend(rgb(r,g,b),ICON_MULTIPLY) - src.icon = I - ..() - -/datum/effect_system/sparkle_spread - effect_type = /obj/effect/particle_effect/sparks/sparkles diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm deleted file mode 100644 index 369f892c511ff..0000000000000 --- a/code/game/objects/effects/effects.dm +++ /dev/null @@ -1,220 +0,0 @@ - -//objects in /obj/effect should never be things that are attackable, use obj/structure instead. -//Effects are mostly temporary visual effects like sparks, smoke, as well as decals, etc... - -/obj/effect - icon = 'icons/effects/effects.dmi' - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF - move_resist = INFINITY - anchored = TRUE - can_be_hit = FALSE - -/obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) - return - -/obj/effect/singularity_act() - qdel(src) - return FALSE - -/obj/effect/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - return - -/obj/effect/acid_act() - return - -/obj/effect/proc/is_cleanable() //Called when you want to clean something, and usualy delete it after - return FALSE - -/obj/effect/mech_melee_attack(obj/mecha/M) - return 0 - -/obj/effect/blob_act(obj/structure/blob/B) - return - -/obj/effect/experience_pressure_difference(flow_x, flow_y) - return // Immune to gas flow. - -/obj/effect/ex_act(severity) - switch(severity) - if(1) - qdel(src) - if(2) - if(prob(60)) - qdel(src) - if(3) - if(prob(25)) - qdel(src) - -/** - * # The abstract object - * - * This is an object that is intended to able to be placed, but that is completely invisible. - * The object should be immune to all forms of damage, or things that can delete it, such as the singularity, or explosions. - */ -/obj/effect/abstract - name = "Abstract object" - invisibility = INVISIBILITY_ABSTRACT - layer = TURF_LAYER - density = FALSE - icon = null - icon_state = null - armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, RAD = 100, FIRE = 100, ACID = 100) - -// Most of these overrides procs below are overkill, but better safe than sorry. -/obj/effect/abstract/bullet_act(obj/item/projectile/P) - return - -/obj/effect/abstract/decompile_act(obj/item/matter_decompiler/C, mob/user) - return - -/obj/effect/abstract/singularity_act() - return - -/obj/effect/abstract/narsie_act() - return - -/obj/effect/abstract/ex_act(severity) - return - -/obj/effect/abstract/blob_act() - return - -/obj/effect/abstract/acid_act() - return - -/obj/effect/abstract/fire_act() - return - -/obj/effect/decal - plane = FLOOR_PLANE - resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF - var/no_scoop = FALSE //if it has this, don't let it be scooped up - var/no_clear = FALSE //if it has this, don't delete it when its' scooped up - var/list/scoop_reagents = null - -/obj/effect/decal/Initialize(mapload) - . = ..() - if(scoop_reagents) - create_reagents(100) - reagents.add_reagent_list(scoop_reagents) - -/obj/effect/decal/build_base_description(infix, suffix) // overriding this is a sin but it fixes a worse sin - . = list("[bicon(src)] That's \a [src][infix]. [suffix]") - if(desc) - . += desc - -/obj/effect/decal/attackby__legacy__attackchain(obj/item/I, mob/user) - if(istype(I, /obj/item/reagent_containers/glass) || istype(I, /obj/item/reagent_containers/drinks)) - scoop(I, user) - else if(issimulatedturf(loc)) - I.melee_attack_chain(user, loc) - -/obj/effect/decal/attack_animal(mob/living/simple_animal/M) - if(issimulatedturf(loc)) - loc.attack_animal(M) - -/obj/effect/decal/attack_hand(mob/living/user) - if(issimulatedturf(loc)) - loc.attack_hand(user) - -/obj/effect/decal/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) - if(issimulatedturf(loc)) - loc.attack_hulk(user, does_attack_animation) - -/obj/effect/decal/proc/scoop(obj/item/I, mob/user) - if(reagents && I.reagents && !no_scoop) - if(!reagents.total_volume) - to_chat(user, "There isn't enough [src] to scoop up!") - return - if(I.reagents.total_volume >= I.reagents.maximum_volume) - to_chat(user, "[I] is full!") - return - to_chat(user, "You scoop [src] into [I]!") - on_scoop() - reagents.trans_to(I, reagents.total_volume) - if(!reagents.total_volume && !no_clear) //scooped up all of it - qdel(src) - -/obj/effect/decal/ex_act() - if(reagents) - for(var/datum/reagent/R in reagents.reagent_list) - R.on_ex_act() - qdel(src) - -/obj/effect/decal/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - if(reagents) - reagents.temperature_reagents(exposed_temperature) - if(!(resistance_flags & FIRE_PROOF)) //non fire proof decal or being burned by lava - qdel(src) - -/obj/effect/decal/blob_act(obj/structure/blob/B) - if(B && B.loc == loc) - qdel(src) - -/obj/effect/decal/proc/on_scoop() - return - -/// These effects can be added to anything to hold particles, which is useful because Byond only allows a single particle per atom -/obj/effect/abstract/particle_holder - anchored = TRUE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - layer = ABOVE_ALL_MOB_LAYER - vis_flags = VIS_INHERIT_PLANE - invisibility = FALSE - ///typepath of the last location we're in, if it's different when moved then we need to update vis contents - var/last_attached_location_type - /// The main item we're attached to at the moment, particle holders hold particles for something - var/atom/movable/parent - /// The mob that is holding our item - var/mob/holding_parent - -/obj/effect/abstract/particle_holder/Initialize(mapload, particle_path = null) - . = ..() - if(!loc) - stack_trace("particle holder was created with no loc!") - return INITIALIZE_HINT_QDEL - parent = loc - - if(ismovable(parent)) - RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) - RegisterSignal(parent, COMSIG_PARENT_QDELETING, PROC_REF(on_qdel)) - - particles = new particle_path - update_visual_contents(parent) - -/obj/effect/abstract/particle_holder/Destroy(force) - if(parent) - UnregisterSignal(parent, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) - QDEL_NULL(particles) - holding_parent = null - parent.vis_contents -= src - return ..() - -///signal called when parent is moved -/obj/effect/abstract/particle_holder/proc/on_move(atom/movable/attached, atom/oldloc, direction) - SIGNAL_HANDLER - if(parent.loc.type != last_attached_location_type) - update_visual_contents(attached) - -///signal called when parent is deleted -/obj/effect/abstract/particle_holder/proc/on_qdel(atom/movable/attached, force) - SIGNAL_HANDLER - attached.vis_contents -= src - qdel(src)//our parent is gone and we need to be as well - -///logic proc for particle holders, aka where they move. -///subtypes of particle holders can override this for particles that should always be turf level or do special things when repositioning. -///this base subtype has some logic for items, as the loc of items becomes mobs very often hiding the particles -/obj/effect/abstract/particle_holder/proc/update_visual_contents(atom/movable/attached_to) - // Remove old - if(holding_parent && !(QDELETED(holding_parent))) - holding_parent.vis_contents -= src - - // Add new - if(isitem(attached_to) && ismob(attached_to.loc)) //special case we want to also be emitting from the mob - holding_parent = attached_to.loc - last_attached_location_type = attached_to.loc - holding_parent.vis_contents += src - - // Readd to ourselves - attached_to.vis_contents |= src diff --git a/code/game/objects/effects/forcefields.dm b/code/game/objects/effects/forcefields.dm deleted file mode 100644 index b86ae670a395e..0000000000000 --- a/code/game/objects/effects/forcefields.dm +++ /dev/null @@ -1,72 +0,0 @@ -/obj/effect/forcefield - desc = "A space wizard's magic wall." - name = "FORCEWALL" - icon = 'icons/effects/effects.dmi' - icon_state = "m_shield" - opacity = FALSE - density = TRUE - var/lifetime = 30 SECONDS - -/obj/effect/forcefield/New() - ..() - if(lifetime) - QDEL_IN(src, lifetime) - -/obj/effect/forcefield/CanAtmosPass(direction) - return !density - -/obj/effect/forcefield/wizard - var/mob/wizard - /// Flags for what antimagic can just ignore our forcefields - var/antimagic_flags = MAGIC_RESISTANCE - -/obj/effect/forcefield/wizard/Initialize(mapload, mob/summoner) - . = ..() - wizard = summoner - -/obj/effect/forcefield/wizard/CanPass(atom/movable/mover, border_dir) - if(mover == wizard) - return TRUE - if(isliving(mover)) - var/mob/living/living_mover = mover - if(living_mover.can_block_magic(antimagic_flags, charge_cost = 0)) - return TRUE - return FALSE - -///////////Mimewalls/////////// - -/obj/structure/forcefield - name = "ain't supposed to see this" - desc = "file a github report if you do!" - icon = 'icons/effects/effects.dmi' - density = TRUE - anchored = TRUE - var/blocks_atmos = TRUE - -/obj/structure/forcefield/Initialize(mapload) - . = ..() - if(blocks_atmos) - recalculate_atmos_connectivity() - -/obj/structure/forcefield/Destroy() - if(blocks_atmos) - blocks_atmos = FALSE - recalculate_atmos_connectivity() - return ..() - -/obj/structure/forcefield/CanAtmosPass(direction) - return !blocks_atmos - -/obj/structure/forcefield/mime - icon = 'icons/effects/effects.dmi' - icon_state = "5" - name = "invisible wall" - alpha = 1 - desc = "You have a bad feeling about this." - max_integrity = 80 - -/obj/effect/forcefield/mime - icon_state = null - name = "invisible blockade" - desc = "You might be here a while." - lifetime = 60 SECONDS diff --git a/code/game/objects/effects/map_effects/mapmanip.dm b/code/game/objects/effects/map_effects/mapmanip.dm deleted file mode 100644 index 7abb97fc2a29e..0000000000000 --- a/code/game/objects/effects/map_effects/mapmanip.dm +++ /dev/null @@ -1,60 +0,0 @@ -/obj/effect/map_effect/marker/mapmanip - name = "mapmanip marker" - layer = POINT_LAYER - -/obj/effect/map_effect/marker/mapmanip/Initialize(mapload) - . = ..() - return INITIALIZE_HINT_QDEL - -/obj/effect/map_effect/marker/mapmanip/submap/extract - name = "mapmanip marker, extract submap" - icon = 'icons/effects/map_effects_96x96.dmi' - icon_state = "mapmanip_extract" - pixel_x = -32 - pixel_y = -32 - -/obj/effect/map_effect/marker/mapmanip/submap/insert - name = "mapmanip marker, insert submap" - icon = 'icons/effects/map_effects_96x96.dmi' - icon_state = "mapmanip_insert" - pixel_x = -32 - pixel_y = -32 - -/obj/effect/map_effect/marker_helper - name = "marker helper" - layer = POINT_LAYER - -/obj/effect/map_effect/marker_helper/Initialize(mapload) - . = ..() - return INITIALIZE_HINT_QDEL - -/obj/effect/map_effect/marker_helper/mapmanip/submap/edge - name = "mapmanip marker helper, submap edge" - icon = 'icons/effects/mapping_helpers.dmi' - icon_state = "mapmanip_submap_edge" - -// Farragus mapmanips -/obj/effect/map_effect/marker/mapmanip/submap/extract/station/cerestation/engineering_science - name = "Cerestation, Engineering-Science Maintenance" - -/obj/effect/map_effect/marker/mapmanip/submap/insert/station/cerestation/engineering_science - name = "Cerestation, Engineering-Science Maintenance" - -// DVORAK mapmanips -/obj/effect/map_effect/marker/mapmanip/submap/insert/space_ruin/dvorak/vendor_room - name = "DVORAK vending machine room" - -/obj/effect/map_effect/marker/mapmanip/submap/extract/space_ruin/dvorak/vendor_room - name = "DVORAK vending machine room" - -/obj/effect/map_effect/marker/mapmanip/submap/insert/space_ruin/dvorak/turret_room - name = "DVORAK turret room" - -/obj/effect/map_effect/marker/mapmanip/submap/extract/space_ruin/dvorak/turret_room - name = "DVORAK turret room" - -/obj/effect/map_effect/marker/mapmanip/submap/insert/space_ruin/rocky_motel/drunk_accident - name = "Drunken Wreck" - -/obj/effect/map_effect/marker/mapmanip/submap/extract/space_ruin/rocky_motel/drunk_accident - name = "Drunken Wreck" diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm deleted file mode 100644 index a97ced7b06a55..0000000000000 --- a/code/game/objects/effects/mines.dm +++ /dev/null @@ -1,185 +0,0 @@ -/obj/effect/mine - name = "dummy mine" - desc = "I better stay away from that thing." - density = FALSE - icon = 'icons/obj/items.dmi' - icon_state = "uglyminearmed" - var/triggered = FALSE - var/faction = "syndicate" - -/obj/effect/mine/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/effect/mine/proc/mineEffect(mob/living/victim) - to_chat(victim, "*click*") - -/obj/effect/mine/proc/on_atom_entered(datum/source, atom/movable/entered) - SIGNAL_HANDLER // COMSIG_ATOM_ENTERED - - if(!isliving(entered)) - return - var/mob/living/M = entered - if(faction && (faction in M.faction)) - return - if(HAS_TRAIT(M, TRAIT_FLYING)) - return - triggermine(M) - -/obj/effect/mine/proc/triggermine(mob/living/victim) - if(triggered) - return - visible_message("[victim] sets off [bicon(src)] [src]!") - do_sparks(3, 1, src) - mineEffect(victim) - triggered = TRUE - qdel(src) - -/obj/effect/mine/ex_act(severity) - // Necessary because, as effects, they have infinite health, and wouldn't be destroyed otherwise. - // Also, they're pressure-sensitive mines, it makes sense that an explosion (wave of pressure) triggers/destroys them. - qdel(src) - -/obj/effect/mine/explosive - name = "explosive mine" - var/range_devastation = 0 - var/range_heavy = 1 - var/range_light = 2 - var/range_flash = 3 - -/obj/effect/mine/explosive/mineEffect(mob/living/victim) - explosion(loc, range_devastation, range_heavy, range_light, range_flash) - -/obj/effect/mine/stun - name = "stun mine" - var/stun_time = 16 SECONDS - -/obj/effect/mine/stun/mineEffect(mob/living/victim) - if(isliving(victim)) - victim.Weaken(stun_time) - -/obj/effect/mine/depot - name = "sentry mine" - -/obj/effect/mine/depot/mineEffect(mob/living/victim) - var/area/syndicate_depot/core/depotarea = get_area(src) - if(istype(depotarea)) - if(depotarea.mine_triggered(victim)) - explosion(loc, 1, 0, 0, 1) // devastate the tile you are on, but leave everything else untouched - -/obj/effect/mine/dnascramble - name = "Radiation Mine" - var/radiation_amount - -/obj/effect/mine/dnascramble/mineEffect(mob/living/victim) - victim.rad_act(radiation_amount) - if(!victim.dna || HAS_TRAIT(victim, TRAIT_GENELESS)) - return - randmutb(victim) - domutcheck(victim) - -/obj/effect/mine/gas - name = "oxygen mine" - var/gas_amount = 360 - var/gas_type = LINDA_SPAWN_OXYGEN - -/obj/effect/mine/gas/mineEffect(mob/living/victim) - atmos_spawn_air(gas_type, gas_amount) - -/obj/effect/mine/gas/plasma - name = "plasma mine" - gas_type = LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS - -/obj/effect/mine/gas/n2o - name = "\improper N2O mine" - gas_type = LINDA_SPAWN_N2O - -/obj/effect/mine/sound - name = "honkblaster 1000" - var/sound = 'sound/items/bikehorn.ogg' - -/obj/effect/mine/sound/mineEffect(mob/living/victim) - playsound(loc, sound, 100, 1) - -/obj/effect/mine/sound/bwoink - name = "bwoink mine" - sound = 'sound/effects/adminhelp.ogg' - -/obj/effect/mine/pickup - name = "pickup" - desc = "pick me up." - icon = 'icons/effects/effects.dmi' - icon_state = "electricity2" - density = FALSE - var/duration = 0 - -/obj/effect/mine/pickup/New() - ..() - animate(src, pixel_y = 4, time = 20, loop = -1) - -/obj/effect/mine/pickup/triggermine(mob/living/victim) - if(triggered) - return - triggered = TRUE - invisibility = 101 - mineEffect(victim) - qdel(src) - -/obj/effect/mine/pickup/bloodbath - name = "Red Orb" - desc = "You feel angry just looking at it." - duration = 1200 //2min - color = "red" - -/obj/effect/mine/pickup/bloodbath/mineEffect(mob/living/carbon/victim) - if(!istype(victim) || !victim.client) - return - to_chat(victim, "RIP AND TEAR") - SEND_SOUND(victim, sound('sound/misc/e1m1.ogg')) - var/red_splash = list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0) - - new /obj/effect/hallucination/delusion(get_turf(victim), victim, 'icons/mob/mob.dmi', "daemon") - - var/obj/item/chainsaw/doomslayer/chainsaw = new(victim.loc) - chainsaw.flags |= NODROP | DROPDEL - victim.drop_l_hand() - victim.drop_r_hand() - victim.put_in_hands(chainsaw) - chainsaw.attack_self__legacy__attackchain(victim) - victim.reagents.add_reagent("adminordrazine", 25) - - victim.flash_screen_color(red_splash, 10) - - spawn(duration) - to_chat(victim, "Your bloodlust seeps back into the bog of your subconscious and you regain self control.") - qdel(chainsaw) - qdel(src) - -/obj/effect/mine/pickup/healing - name = "Blue Orb" - desc = "You feel better just looking at it." - color = "blue" - -/obj/effect/mine/pickup/healing/mineEffect(mob/living/carbon/victim) - if(!victim.client || !istype(victim)) - return - to_chat(victim, "You feel great!") - victim.revive() - -/obj/effect/mine/pickup/speed - name = "Yellow Orb" - desc = "You feel faster just looking at it." - color = "yellow" - duration = 300 - -/obj/effect/mine/pickup/speed/mineEffect(mob/living/carbon/victim) - if(!victim.client || !istype(victim)) - return - to_chat(victim, "You feel fast!") - ADD_TRAIT(victim, TRAIT_GOTTAGOFAST, "mine") - spawn(duration) - REMOVE_TRAIT(victim, TRAIT_GOTTAGOFAST, "mine") - to_chat(victim, "You slow down.") diff --git a/code/game/objects/effects/snowcloud.dm b/code/game/objects/effects/snowcloud.dm deleted file mode 100644 index b7e6d94769beb..0000000000000 --- a/code/game/objects/effects/snowcloud.dm +++ /dev/null @@ -1,141 +0,0 @@ -/obj/effect/snowcloud - name = "snow cloud" - desc = "Let it snow, let it snow, let it snow!" - icon_state = "snowcloud" - layer = FLY_LAYER - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - var/obj/machinery/snow_machine/parent_machine - -/obj/effect/snowcloud/New(turf, obj/machinery/snow_machine/SM) - ..() - START_PROCESSING(SSobj, src) - if(SM && istype(SM)) - parent_machine = SM - -/obj/effect/snowcloud/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/effect/snowcloud/process() - if(QDELETED(parent_machine)) - parent_machine = null - var/turf/T = get_turf(src) - if(isspaceturf(T) || T.density) // Don't want snowclouds or snow on walls - qdel(src) - return - var/datum/gas_mixture/G = T.get_readonly_air() - var/turf_hotness = G.temperature() - if(turf_hotness > T0C && prob(10 * (turf_hotness - T0C))) //Cloud disappears if it's too warm - qdel(src) - return - if(!parent_machine || !parent_machine.active || parent_machine.stat & NOPOWER) //All reasons a cloud could dissipate - if(prob(10)) - qdel(src) - return - try_to_snow() - try_to_spread_cloud() - var/datum/milla_safe/snow_machine_cooling/milla = new() - milla.invoke_async(parent_machine, 0.25 * parent_machine.cooling_speed) - -/obj/effect/snowcloud/proc/try_to_snow() - var/turf/T = get_turf(src) - if(locate(/obj/effect/snow, T)) - return - var/datum/gas_mixture/G = T.get_readonly_air() - if(prob(75 + G.temperature() - T0C)) //Colder turf = more chance of snow - return - new /obj/effect/snow(T) - -/obj/effect/snowcloud/proc/try_to_spread_cloud() - if(prob(95 - parent_machine.cooling_speed * 5)) //10 / 15 / 20 / 25% chance to spawn a new cloud - return - var/list/random_dirs = shuffle(GLOB.cardinal) - for(var/potential in random_dirs) - var/turf/T = get_turf(get_step(src, potential)) - if(isspaceturf(T) || T.density) - continue - if(!CanAtmosPass(potential) || !T.CanAtmosPass(turn(potential, 180))) - continue - if(parent_machine.make_snowcloud(T)) - return - - -//Snow stuff below - -/obj/effect/snow - desc = "Perfect for making snow angels, or throwing at other people!" - icon = 'icons/effects/effects.dmi' - icon_state = "snow1" - plane = FLOOR_PLANE - layer = ABOVE_ICYOVERLAY_LAYER - -/obj/effect/snow/New() - START_PROCESSING(SSobj, src) - icon_state = "snow[rand(1,6)]" - ..() - -/obj/effect/snow/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/effect/snow/process() - var/turf/T = get_turf(src) - if(isspaceturf(T) || T.density) // Don't want snowclouds or snow on walls - qdel(src) - return - var/datum/gas_mixture/G = T.get_readonly_air() - if(G.temperature() <= T0C) - return - if(prob(10 + G.temperature() - T0C)) - qdel(src) - -/obj/effect/snow/attack_hand(mob/living/carbon/human/user) - if(!istype(user)) //Nonhumans don't have the balls to fight in the snow - return - user.changeNext_move(CLICK_CD_MELEE) - var/obj/item/snowball/SB = new(get_turf(user)) - user.put_in_hands(SB) - to_chat(user, "You scoop up some snow and make \a [SB]!") - -/obj/effect/snow/attackby__legacy__attackchain(obj/item/I, mob/user) - if(istype(I, /obj/item/shovel)) - var/obj/item/shovel/S = I - user.visible_message("[user] is clearing away [src]...", "You begin clearing away [src]...", "You hear a wettish digging sound.") - playsound(loc, S.usesound, 50, TRUE) - if(!do_after(user, 50 * S.toolspeed, target = src)) - return - user.visible_message("[user] clears away [src]!", "You clear away [src]!") - qdel(src) - else - return ..() - -/obj/effect/snow/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - ..() - qdel(src) - -/obj/effect/snow/ex_act(severity) - if(severity == EXPLODE_LIGHT && prob(50)) - return - qdel(src) - -/obj/item/snowball - name = "snowball" - desc = "Get ready for a snowball fight!" - icon_state = "snowball" - /// The amount of stamina damage to do on hit. - var/stamina_damage = 10 - -/obj/item/snowball/throw_impact(atom/target) - . = ..() - if(!. && isliving(target)) - var/mob/living/M = target - M.apply_damage(stamina_damage, STAMINA) - playsound(target, 'sound/weapons/tap.ogg', 50, TRUE) - qdel(src) - -/obj/item/snowball/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - ..() - qdel(src) - -/obj/item/snowball/ex_act(severity) - qdel(src) diff --git a/code/game/objects/effects/spawners/random/food_spawners.dm b/code/game/objects/effects/spawners/random/food_spawners.dm deleted file mode 100644 index b53c148d96d5f..0000000000000 --- a/code/game/objects/effects/spawners/random/food_spawners.dm +++ /dev/null @@ -1,58 +0,0 @@ -/obj/effect/spawner/random/snacks - name = "snacks spawner" - icon = 'icons/effects/random_spawners.dmi' - icon_state = "donkpocket_single" - loot = list( - list( - /obj/item/food/candy/candybar, - /obj/item/reagent_containers/drinks/dry_ramen, - /obj/item/food/chips, - /obj/item/food/twimsts, - /obj/item/food/sosjerky, - /obj/item/food/no_raisin, - /obj/item/food/pistachios, - /obj/item/food/spacetwinkie, - /obj/item/food/cheesiehonkers, - /obj/item/food/tastybread, - ) = 5, - - /obj/item/food/stroopwafel = 1, - ) - record_spawn = TRUE - -/obj/effect/spawner/random/food_or_drink - // TODO: Consolidate all the spawner icons once all the legacy random spawners have been migrated - icon = 'icons/effects/random_spawners.dmi' - -/obj/effect/spawner/random/food_or_drink/soup - name = "soup spawner" - icon_state = "soup" - loot_subtype_path = /obj/item/food/soup - -/obj/effect/spawner/random/food_or_drink/salad - name = "salad spawner" - icon_state = "soup" - loot_subtype_path = /obj/item/food/salad - -/obj/effect/spawner/random/food_or_drink/dinner - name = "dinner spawner" - icon_state = "soup" - loot = list( - /obj/item/food/burger/bigbite, - /obj/item/food/burger/fivealarm, - /obj/item/food/burger/superbite, - /obj/item/food/enchiladas, - /obj/item/food/philly_cheesesteak, - /obj/item/food/sandwich, - /obj/item/food/stewedsoymeat, - ) - -/obj/effect/spawner/random/food_or_drink/three_course_meal - name = "three course meal spawner" - icon_state = "soup" - spawn_all_loot = TRUE - loot = list( - /obj/effect/spawner/random/food_or_drink/soup, - /obj/effect/spawner/random/food_or_drink/salad, - /obj/effect/spawner/random/food_or_drink/dinner, - ) diff --git a/code/game/objects/effects/spawners/random/loot_spawners.dm b/code/game/objects/effects/spawners/random/loot_spawners.dm deleted file mode 100644 index fad11c2b2c6e2..0000000000000 --- a/code/game/objects/effects/spawners/random/loot_spawners.dm +++ /dev/null @@ -1,6 +0,0 @@ -/obj/effect/spawner/random/loot/crate - name = "lootcrate spawner" - icon = 'icons/effects/random_spawners.dmi' - icon_state = "crate_secure" - spawn_loot_chance = 20 - loot = list(/obj/structure/closet/crate/secure/loot) diff --git a/code/game/objects/effects/spawners/random/misc_spawners.dm b/code/game/objects/effects/spawners/random/misc_spawners.dm deleted file mode 100644 index 5632b8175cd4a..0000000000000 --- a/code/game/objects/effects/spawners/random/misc_spawners.dm +++ /dev/null @@ -1,96 +0,0 @@ -/obj/effect/spawner/random/dice - loot = list( - /obj/item/dice/d4, - /obj/item/dice/d6, - /obj/item/dice/d8, - /obj/item/dice/d10, - /obj/item/dice/d12, - ) - record_spawn = TRUE - -/obj/effect/spawner/random/dice/Initialize(mapload) - . = ..() - spawn_loot_count = rand(1, 2) - -/obj/effect/spawner/random/bureaucracy - icon = 'icons/effects/random_spawners.dmi' - icon_state = "folder" - name = "bureaucracy spawner" - loot = list( - /obj/item/hand_labeler, - /obj/item/hand_labeler_refill, - /obj/item/stack/tape_roll, - /obj/item/paper_bin, - /obj/item/pen, - /obj/item/pen/blue, - /obj/item/pen/red, - /obj/item/folder/blue, - /obj/item/folder/red, - /obj/item/folder/yellow, - /obj/item/clipboard, - ) - record_spawn = TRUE - -/obj/effect/spawner/random/book - icon = 'icons/effects/random_spawners.dmi' - icon_state = "book" - name = "book spawner" - loot = list( - /obj/item/book/manual/atmospipes, - /obj/item/book/manual/barman_recipes, - /obj/item/book/manual/detective, - /obj/item/book/manual/engineering_particle_accelerator, - /obj/item/book/manual/engineering_singularity_safety, - /obj/item/book/manual/evaguide, - /obj/item/book/manual/hydroponics_pod_people, - /obj/item/book/manual/medical_cloning, - /obj/item/book/manual/research_and_development, - /obj/item/book/manual/ripley_build_and_repair, - /obj/item/book/manual/supermatter_engine, - /obj/item/book/manual/wiki/botanist, - /obj/item/book/manual/wiki/chef_recipes, - /obj/item/book/manual/wiki/engineering_construction, - /obj/item/book/manual/wiki/engineering_guide, - /obj/item/book/manual/wiki/faxes, - /obj/item/book/manual/wiki/hacking, - /obj/item/book/manual/wiki/hydroponics, - /obj/item/book/manual/wiki/robotics_cyborgs, - /obj/item/book/manual/wiki/security_space_law, - /obj/item/book/manual/wiki/security_space_law/black, - /obj/item/book/manual/wiki/sop_command, - /obj/item/book/manual/wiki/sop_engineering, - /obj/item/book/manual/wiki/sop_general, - /obj/item/book/manual/wiki/sop_legal, - /obj/item/book/manual/wiki/sop_medical, - /obj/item/book/manual/wiki/sop_science, - /obj/item/book/manual/wiki/sop_security, - /obj/item/book/manual/wiki/sop_service, - /obj/item/book/manual/wiki/sop_supply, - /obj/item/book/manual/zombie_manual, - ) - record_spawn = TRUE - -/obj/effect/spawner/random/book/record_item(type_path_to_make) - SSblackbox.record_feedback("tally", "random_spawners", 1, "[/obj/item/book]") - -/obj/effect/spawner/random/mod_maint - name = "maint MOD module spawner" - loot = list( - /obj/item/mod/module/springlock = 2, - /obj/item/mod/module/balloon = 1, - /obj/item/mod/module/stamp = 1 - ) - record_spawn = TRUE - -/obj/effect/spawner/random/jani_supplies - icon = 'icons/effects/random_spawners.dmi' - icon_state = "mopbucket" - name = "janitorial supplies spawner" - loot = list( - /obj/item/storage/box/mousetraps, - /obj/item/storage/box/lights/tubes, - /obj/item/storage/box/lights/mixed, - /obj/item/storage/box/lights/bulbs, - ) - record_spawn = TRUE - diff --git a/code/game/objects/effects/spawners/random/plushie_spawners.dm b/code/game/objects/effects/spawners/random/plushie_spawners.dm deleted file mode 100644 index cbff56a87199f..0000000000000 --- a/code/game/objects/effects/spawners/random/plushie_spawners.dm +++ /dev/null @@ -1,108 +0,0 @@ -/obj/effect/spawner/random/plushies - name = "plushie spawner" - icon = 'icons/effects/random_spawners.dmi' - icon_state = "plushie" - loot = list( - list( - /obj/item/toy/plushie/carpplushie/ice, - /obj/item/toy/plushie/carpplushie/silent, - /obj/item/toy/plushie/carpplushie/silent, - /obj/item/toy/plushie/carpplushie/electric, - /obj/item/toy/plushie/carpplushie/gold, - /obj/item/toy/plushie/carpplushie/toxin, - /obj/item/toy/plushie/carpplushie/dragon, - /obj/item/toy/plushie/carpplushie/pink, - /obj/item/toy/plushie/carpplushie/candy, - /obj/item/toy/plushie/carpplushie/nebula, - /obj/item/toy/plushie/carpplushie/void - ), - - list( - /obj/item/toy/plushie/red_fox, - /obj/item/toy/plushie/black_fox, - /obj/item/toy/plushie/marble_fox, - /obj/item/toy/plushie/blue_fox, - /obj/item/toy/plushie/orange_fox, - /obj/item/toy/plushie/coffee_fox, - /obj/item/toy/plushie/pink_fox, - /obj/item/toy/plushie/purple_fox, - /obj/item/toy/plushie/crimson_fox - ), - - list( - /obj/item/toy/plushie/corgi, - /obj/item/toy/plushie/girly_corgi, - /obj/item/toy/plushie/robo_corgi, - /obj/item/toy/plushie/octopus, - /obj/item/toy/plushie/face_hugger, - /obj/item/toy/plushie/deer, - /obj/item/toy/plushie/snakeplushie, - /obj/item/toy/plushie/lizardplushie, - /obj/item/toy/plushie/slimeplushie, - /obj/item/toy/plushie/nukeplushie, - /obj/item/toy/plushie/shark - ), - - list( - /obj/item/toy/plushie/black_cat, - /obj/item/toy/plushie/grey_cat, - /obj/item/toy/plushie/white_cat, - /obj/item/toy/plushie/orange_cat, - /obj/item/toy/plushie/siamese_cat, - /obj/item/toy/plushie/tabby_cat, - /obj/item/toy/plushie/tuxedo_cat - ), - - list(// Species plushies minus Nian. - /obj/item/toy/plushie/dionaplushie, - /obj/item/toy/plushie/draskplushie, - /obj/item/toy/plushie/greyplushie, - /obj/item/toy/plushie/humanplushie, - /obj/item/toy/plushie/kidanplushie, - /obj/item/toy/plushie/ipcplushie, - /obj/item/toy/plushie/plasmamanplushie, - /obj/item/toy/plushie/skrellplushie, - /obj/item/toy/plushie/voxplushie, - /obj/item/toy/plushie/abductor, - /obj/item/toy/plushie/abductor/agent, - /obj/item/toy/plushie/borgplushie/random - ), - - list ( - /obj/item/toy/plushie/nianplushie = 3, - /obj/item/toy/plushie/nianplushie/monarch = 2, - /obj/item/toy/plushie/nianplushie/luna = 2, - /obj/item/toy/plushie/nianplushie/atlas = 2, - /obj/item/toy/plushie/nianplushie/reddish = 2, - /obj/item/toy/plushie/nianplushie/royal = 2, - /obj/item/toy/plushie/nianplushie/gothic = 2, - /obj/item/toy/plushie/nianplushie/lovers = 2, - /obj/item/toy/plushie/nianplushie/whitefly = 2, - /obj/item/toy/plushie/nianplushie/punished = 2, - /obj/item/toy/plushie/nianplushie/firewatch = 2, - /obj/item/toy/plushie/nianplushie/deadhead = 2, - /obj/item/toy/plushie/nianplushie/poison = 2, - /obj/item/toy/plushie/nianplushie/ragged = 2, - /obj/item/toy/plushie/nianplushie/snow = 2, - /obj/item/toy/plushie/nianplushie/clockwork = 2, - /obj/item/toy/plushie/nianplushie/moonfly = 2, - /obj/item/toy/plushie/nianplushie/rainbow = 1 - ), - ) - -/obj/effect/spawner/random/plushies/explosive - /// Chance to spawn a minibomb in the plushie. - var/explosive_chance = 1 - -/obj/effect/spawner/random/plushies/explosive/make_item(spawn_loc, type_path_to_make) - var/obj/item/toy/plushie/plushie = ..() - - if(!istype(plushie)) - return plushie - - if(prob(explosive_chance)) - plushie.has_stuffing = FALSE - var/obj/item/grenade/syndieminibomb/grenade = new(plushie) - plushie.grenade = grenade - - return plushie diff --git a/code/game/objects/effects/spawners/random/toy_spawners.dm b/code/game/objects/effects/spawners/random/toy_spawners.dm deleted file mode 100644 index 01fb4300baf68..0000000000000 --- a/code/game/objects/effects/spawners/random/toy_spawners.dm +++ /dev/null @@ -1,29 +0,0 @@ -/obj/effect/spawner/random/toy - name = "random toy spawner" - icon = 'icons/effects/random_spawners.dmi' - icon_state = "toy" - -/obj/effect/spawner/random/toy/mech_figure - name = "random mech figurine" - loot_subtype_path = /obj/item/toy/figure/mech - -/obj/effect/spawner/random/toy/action_figure - name = "random action figure" - loot_subtype_path = /obj/item/toy/figure/crew - -/obj/effect/spawner/random/toy/carp_plushie - name = "random carp plushie" - loot_type_path = /obj/item/toy/plushie/carpplushie - -/obj/effect/spawner/random/toy/therapy_doll - name = "random therapy doll" - loot_subtype_path = /obj/item/toy/therapy - -/obj/effect/spawner/random/toy/clusterbuster - loot = list( - /obj/item/gun/projectile/shotgun/toy/crossbow, - /obj/item/reagent_containers/spray/waterflower, - /obj/item/toy/balloon, - /obj/item/toy/spinningtoy, - ) - loot_subtype_path = /obj/item/toy/figure/mech diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm deleted file mode 100644 index c169729b8e50a..0000000000000 --- a/code/game/objects/effects/spiders.dm +++ /dev/null @@ -1,250 +0,0 @@ -/obj/structure/spider - name = "web" - desc = "it's stringy and sticky." - icon = 'icons/effects/effects.dmi' - icon_state = "stickyweb1" - anchored = TRUE - density = FALSE - max_integrity = 15 - var/mob/living/carbon/human/master_commander = null - -/obj/structure/spider/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - if(damage_type == BURN)//the stickiness of the web mutes all attack sounds except fire damage type - playsound(loc, 'sound/items/welder.ogg', 100, TRUE) - - -/obj/structure/spider/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == MELEE) - switch(damage_type) - if(BURN) - damage_amount *= 2 - if(BRUTE) - damage_amount *= 0.25 - . = ..() - -/obj/structure/spider/Destroy() - master_commander = null - return ..() - -/obj/structure/spider/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ..() - if(exposed_temperature > 300) - take_damage(5, BURN, 0, 0) - -/obj/structure/spider/stickyweb - icon_state = "stickyweb1" - -/obj/structure/spider/stickyweb/Initialize(mapload) - . = ..() - if(prob(50)) - icon_state = "stickyweb2" - - var/static/list/loc_connections = list( - COMSIG_ATOM_EXIT = PROC_REF(on_atom_exit), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/structure/spider/stickyweb/proc/on_atom_exit(datum/source, atom/exiter) - if(istype(exiter, /mob/living/simple_animal/hostile/poison/giant_spider) || isterrorspider(exiter)) - return - if(isliving(exiter) && prob(50)) - to_chat(exiter, "You get stuck in [src] for a moment.") - return COMPONENT_ATOM_BLOCK_EXIT - if(isprojectile(exiter) && prob(30)) - return COMPONENT_ATOM_BLOCK_EXIT - -/obj/structure/spider/eggcluster - name = "egg cluster" - desc = "They seem to pulse slightly with an inner life." - icon_state = "eggs" - var/amount_grown = 0 - var/player_spiders = FALSE - var/list/faction = list("spiders") - flags_2 = CRITICAL_ATOM_2 - -/obj/structure/spider/eggcluster/Initialize(mapload) - . = ..() - pixel_x = rand(3,-3) - pixel_y = rand(3,-3) - START_PROCESSING(SSobj, src) - -/obj/structure/spider/eggcluster/process() - if(SSmobs.xenobiology_mobs > MAX_GOLD_CORE_MOBS - 10) //eggs gonna chill out until there is less spiders - return - - amount_grown += rand(0, 2) - - if(amount_grown >= 100) - var/num = rand(3, 12) - for(var/i in 1 to num) - var/obj/structure/spider/spiderling/S = new /obj/structure/spider/spiderling(loc) - S.faction = faction.Copy() - S.master_commander = master_commander - if(player_spiders) - S.player_spiders = TRUE - qdel(src) - -/obj/structure/spider/spiderling - name = "spiderling" - desc = "It never stays still for long." - icon_state = "spiderling" - anchored = FALSE - layer = 2.75 - max_integrity = 3 - var/amount_grown = 0 - var/grow_as = null - var/obj/machinery/atmospherics/unary/vent_pump/entry_vent - var/travelling_in_vent = FALSE - var/player_spiders = FALSE - var/list/faction = list("spiders") - var/selecting_player = 0 - ///Is this spiderling created from a xenobiology mob? - var/xenobiology_spawned = FALSE - -/obj/structure/spider/spiderling/Initialize(mapload) - . = ..() - pixel_x = rand(6,-6) - pixel_y = rand(6,-6) - START_PROCESSING(SSobj, src) - AddComponent(/datum/component/swarming) - ADD_TRAIT(src, TRAIT_EDIBLE_BUG, "edible_bug") // Normally this is just used for mobs, but spiderlings are kind of that... - -/obj/structure/spider/spiderling/Destroy() - STOP_PROCESSING(SSobj, src) - // Release possible ref if a walk is still being processed - walk_to(src, 0) - entry_vent = null - if(amount_grown < 100) - new /obj/effect/decal/cleanable/spiderling_remains(get_turf(src)) - return ..() - -/obj/structure/spider/spiderling/Bump(atom/user) - if(istype(user, /obj/structure/table)) - loc = user.loc - else - ..() - -/obj/structure/spider/spiderling/process() - if(travelling_in_vent) - if(isturf(loc)) - travelling_in_vent = FALSE - entry_vent = null - else if(entry_vent) - if(get_dist(src, entry_vent) <= 1) - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in entry_vent.parent.other_atmosmch) - vents.Add(temp_vent) - if(!length(vents)) - entry_vent = null - return - var/obj/machinery/atmospherics/unary/vent_pump/exit_vent = pick(vents) - if(prob(50)) - visible_message("[src] scrambles into the ventilation ducts!", \ - "You hear something squeezing through the ventilation ducts.") - - spawn(rand(20,60)) - loc = exit_vent - var/travel_time = round(get_dist(loc, exit_vent.loc) / 2) - spawn(travel_time) - - if(!exit_vent || exit_vent.welded) - loc = entry_vent - entry_vent = null - return - - if(prob(50)) - audible_message("You hear something squeezing through the ventilation ducts.") - sleep(travel_time) - - if(!exit_vent || exit_vent.welded) - loc = entry_vent - entry_vent = null - return - loc = exit_vent.loc - entry_vent = null - var/area/new_area = get_area(loc) - if(new_area) - new_area.Entered(src) - //================= - - else if(prob(33)) - if(random_skitter() && prob(40)) - visible_message("[src] skitters[pick(" away"," around","")].") - else if(prob(10)) - //ventcrawl! - for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src)) - if(!v.welded) - entry_vent = v - walk_to(src, entry_vent, 1) - break - if(isturf(loc)) - amount_grown += rand(0,2) - if(amount_grown >= 100) - if(SSmobs.xenobiology_mobs > MAX_GOLD_CORE_MOBS && xenobiology_spawned) - qdel(src) - return - if(!grow_as) - grow_as = pick(typesof(/mob/living/simple_animal/hostile/poison/giant_spider) - /mob/living/simple_animal/hostile/poison/giant_spider/hunter/infestation_spider) - var/mob/living/simple_animal/hostile/poison/giant_spider/S = new grow_as(loc) - S.faction = faction.Copy() - S.master_commander = master_commander - S.xenobiology_spawned = xenobiology_spawned - if(xenobiology_spawned) - SSmobs.xenobiology_mobs++ - if(player_spiders && !selecting_player) - selecting_player = 1 - spawn() - var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a giant spider?", ROLE_SENTIENT, TRUE, source = S) - - if(length(candidates) && !QDELETED(S)) - var/mob/C = pick(candidates) - if(C) - S.key = C.key - dust_if_respawnable(C) - if(S.master_commander) - to_chat(S, "You are a spider who is loyal to [S.master_commander], obey [S.master_commander]'s every order and assist [S.master_commander.p_them()] in completing [S.master_commander.p_their()] goals at any cost.") - qdel(src) - -/obj/structure/spider/spiderling/proc/random_skitter() - var/list/available_turfs = list() - for(var/turf/simulated/S in oview(10, src)) - // no !isspaceturf check needed since /turf/simulated is not a subtype of /turf/space - if(S.density) - continue - available_turfs += S - if(!length(available_turfs)) - return FALSE - walk_to(src, pick(available_turfs)) - return TRUE - -/obj/structure/spider/spiderling/decompile_act(obj/item/matter_decompiler/C, mob/user) - if(!isdrone(user)) - user.visible_message("[user] sucks [src] into its decompiler. There's a horrible crunching noise.", \ - "It's a bit of a struggle, but you manage to suck [src] into your decompiler. It makes a series of visceral crunching noises.") - C.stored_comms["metal"] += 2 - C.stored_comms["glass"] += 1 - qdel(src) - return TRUE - return ..() - -/obj/effect/decal/cleanable/spiderling_remains - name = "spiderling remains" - desc = "Green squishy mess." - icon = 'icons/effects/effects.dmi' - icon_state = "greenshatter" - -/obj/structure/spider/cocoon - name = "cocoon" - desc = "Something wrapped in silky spider web." - icon_state = "cocoon1" - max_integrity = 60 - -/obj/structure/spider/cocoon/Initialize(mapload) - . = ..() - icon_state = pick("cocoon1","cocoon2","cocoon3") - -/obj/structure/spider/cocoon/Destroy() - visible_message("[src] splits open.") - for(var/atom/movable/A in contents) - A.forceMove(loc) - return ..() diff --git a/code/game/objects/effects/step_triggers.dm b/code/game/objects/effects/step_triggers.dm deleted file mode 100644 index 63ab8096230d5..0000000000000 --- a/code/game/objects/effects/step_triggers.dm +++ /dev/null @@ -1,192 +0,0 @@ -/* Simple object type, calls a proc when "stepped" on by something */ - -/obj/effect/step_trigger - var/affect_ghosts = FALSE - var/stopper = TRUE // stops throwers - var/mobs_only = FALSE - invisibility = INVISIBILITY_ABSTRACT // nope cant see this shit - -/obj/effect/step_trigger/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/effect/step_trigger/proc/Trigger(atom/movable/A) - return FALSE - -/obj/effect/step_trigger/proc/on_atom_entered(datum/source, atom/movable/entered) - SIGNAL_HANDLER - if(!entered || entered == src) - return - if(!ismob(entered) && !isobj(entered)) - return - if(isobserver(entered) && !affect_ghosts) - return - if(!ismob(entered) && mobs_only) - return - INVOKE_ASYNC(src, PROC_REF(Trigger), entered) - -/obj/effect/step_trigger/singularity_act() - return - -/obj/effect/step_trigger/singularity_pull() - return - -/* Sends a message to mob when triggered*/ - -/obj/effect/step_trigger/message - var/message //the message to give to the mob - var/once = 1 - mobs_only = TRUE - -/obj/effect/step_trigger/message/Trigger(mob/M) - if(M.client) - to_chat(M, "[message]") - if(once) - qdel(src) - -/* Tosses things in a certain direction */ -/obj/effect/step_trigger/thrower - var/direction = SOUTH // the direction of throw - var/tiles = 3 // if 0: forever until atom hits a stopper - var/immobilize = 1 // if nonzero: prevents mobs from moving while they're being flung - var/speed = 1 // delay of movement - var/nostop = 0 // if 1: will only be stopped by teleporters - var/list/affecting = list() - -/obj/effect/step_trigger/thrower/Trigger(atom/A) - if(!A || !ismovable(A)) - return - var/atom/movable/AM = A - var/curtiles = 0 - var/stopthrow = 0 - for(var/obj/effect/step_trigger/thrower/T in orange(2, src)) - if(AM in T.affecting) - return - - if(immobilize) - ADD_TRAIT(A, TRAIT_IMMOBILIZED, "[UID()]") - - affecting.Add(AM) - while(AM && !stopthrow) - if(tiles) - if(curtiles >= tiles) - break - if(AM.z != src.z) - break - - curtiles++ - - sleep(speed) - - // Calculate if we should stop the process - if(!nostop) - for(var/obj/effect/step_trigger/T in get_step(AM, direction)) - if(T.stopper && T != src) - stopthrow = 1 - else - for(var/obj/effect/step_trigger/teleporter/T in get_step(AM, direction)) - if(T.stopper) - stopthrow = 1 - - if(AM) - step(AM, direction) - - REMOVE_TRAIT(A, TRAIT_IMMOBILIZED, "[UID()]") - -/* Stops things thrown by a thrower, doesn't do anything */ - -/obj/effect/step_trigger/stopper - -/* Instant teleporter */ - -/obj/effect/step_trigger/teleporter - var/teleport_x = 0 // teleportation coordinates (if one is null, then no teleport!) - var/teleport_y = 0 - var/teleport_z = 0 - -/obj/effect/step_trigger/teleporter/Trigger(atom/movable/A) - if(teleport_x && teleport_y && teleport_z) - - var/turf/T = locate(teleport_x, teleport_y, teleport_z) - A.forceMove(T) - -/* Random teleporter, teleports atoms to locations ranging from teleport_x - teleport_x_offset, etc */ - -/obj/effect/step_trigger/teleporter/random - var/teleport_x_offset = 0 - var/teleport_y_offset = 0 - var/teleport_z_offset = 0 - -/obj/effect/step_trigger/teleporter/random/Trigger(atom/movable/A) - if(teleport_x && teleport_y && teleport_z) - if(teleport_x_offset && teleport_y_offset && teleport_z_offset) - - var/turf/T = locate(rand(teleport_x, teleport_x_offset), rand(teleport_y, teleport_y_offset), rand(teleport_z, teleport_z_offset)) - if(T) - A.forceMove(T) - -/* Fancy teleporter, creates sparks and smokes when used */ - -/obj/effect/step_trigger/teleport_fancy - var/locationx - var/locationy - var/uses = 1 //0 for infinite uses - var/entersparks = 0 - var/exitsparks = 0 - var/entersmoke = 0 - var/exitsmoke = 0 - -/obj/effect/step_trigger/teleport_fancy/Trigger(mob/M) - var/dest = locate(locationx, locationy, z) - M.Move(dest) - - if(entersparks) - var/datum/effect_system/spark_spread/s = new - s.set_up(4, 1, src) - s.start() - if(exitsparks) - var/datum/effect_system/spark_spread/s = new - s.set_up(4, 1, dest) - s.start() - - if(entersmoke) - var/datum/effect_system/smoke_spread/s = new - s.set_up(4, TRUE, src, 0) - s.start() - if(exitsmoke) - var/datum/effect_system/smoke_spread/s = new - s.set_up(4, TRUE, dest, 0) - s.start() - - uses-- - if(uses == 0) - qdel(src) - -/* Simple sound player, Mapper friendly! */ - -/obj/effect/step_trigger/sound_effect - var/sound //eg. path to the sound, inside '' eg: 'growl.ogg' - var/volume = 100 - var/freq_vary = 1 //Should the frequency of the sound vary? - var/extra_range = 0 // eg World.view = 7, extra_range = 1, 7+1 = 8, 8 turfs radius - var/happens_once = 0 - var/triggerer_only = 0 //Whether the triggerer is the only person who hears this - - -/obj/effect/step_trigger/sound_effect/Trigger(atom/movable/A) - var/turf/T = get_turf(A) - - if(!T) - return - - if(triggerer_only && ismob(A)) - var/mob/B = A - B.playsound_local(T, sound, volume, freq_vary) - else - playsound(T, sound, volume, freq_vary, extra_range) - - if(happens_once) - qdel(src) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm deleted file mode 100644 index ab8b3bff53372..0000000000000 --- a/code/game/objects/items.dm +++ /dev/null @@ -1,1019 +0,0 @@ -GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effects/fire.dmi', "icon_state" = "fire")) -GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons/effects/welding_effect.dmi', "welding_sparks", GASFIRE_LAYER, ABOVE_LIGHTING_PLANE)) - -/obj/item - name = "item" - icon = 'icons/obj/items.dmi' - blocks_emissive = EMISSIVE_BLOCK_GENERIC - mouse_drag_pointer = MOUSE_ACTIVE_POINTER - - // Set in the Initialise depending on the item size. Unless it's overriden by a specific item - move_resist = null - /// used in item_attack.dm to make an item not show an attack message to viewers - var/discrete = FALSE - /// The icon state used to display the item in your inventory. If null then the icon_state value itself will be used - var/item_state = null - var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' - var/righthand_file = 'icons/mob/inhands/items_righthand.dmi' - - /// Dimension X of the lefthand_file and righthand_file var - /// eg: 32x32 sprite, 64x64 sprite, etc. - var/inhand_x_dimension = 32 - /// Dimension Y of the lefthand_file and righthand_file var - /// eg: 32x32 sprite, 64x64 sprite, etc. - var/inhand_y_dimension = 32 - - max_integrity = 200 - - can_be_hit = FALSE - suicidal_hands = TRUE - - /// 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 - /// Allows you to override the attack animation with an attack effect - var/attack_effect_override - /// Used in attackby() to say how something was attacked `"[x] has been [z.attack_verb] by [y] with [z]"` - var/list/attack_verb - /// Determines how big/small items are to fit in storage containers - var/w_class = WEIGHT_CLASS_NORMAL - /// This is used to determine on which slots an item can fit. - var/slot_flags = 0 - /// If set, this determines which slots are considered when using quick equip - var/prefered_slot_flags = 0 - /// Determines what it can pass over/through. IE. 'PASSTABLE' will allow it to pass over tables - pass_flags = PASSTABLE - pressure_resistance = 4 - should_spread_blood = TRUE - var/obj/item/master - - /// Flags which determine which body parts are protected from heat. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm - var/heat_protection = 0 - /// Flags which determine which body parts are protected from cold. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm - var/cold_protection = 0 - /// Set this variable to determine up to which temperature (IN KELVIN) the item protects against heat damage. Keep at null to disable protection. Only protects areas set by heat_protection flags - var/max_heat_protection_temperature - /// Set this variable to determine down to which temperature (IN KELVIN) the item protects against cold damage. 0 is NOT an acceptable number due to if(varname) tests!! Keep at null to disable protection. Only protects areas set by cold_protection flags - var/min_cold_protection_temperature - /// List of /datum/action's that this item has. - var/list/actions = list() - /// List of paths of action datums to give to the item on New(). - var/list/actions_types = list() - /// List of icons-sheets for a given action to override the icon. - var/list/action_icon = list() - /// List of icon states for a given action to override the icon_state. - var/list/action_icon_state = list() - - /// What materials the item yields when broken down. Some methods will not recover everything (autolathes only recover metal and glass, for example). - var/list/materials = list() - /// Since any item can now be a piece of clothing, this has to be put here so all items share it. - /// This flag is used to determine when items in someone's inventory cover others. IE helmets making it so you can't see glasses, etc. - var/flags_inv - /// The associated key to the dye registry GLOB list, used to transform/color this piece of clothing through dyeing - var/dyeing_key - /// If this item is put into a washing machine to be dyed, can objects of this type be dyed into a different color/icon? - var/dyeable = FALSE - var/item_color - /// What bodyflags does this item cover? See setup.dm for appropriate bit flags - var/body_parts_covered = 0 - /// For leaking gas from turf to mask and vice-versa. - var/gas_transfer_coefficient = 1 - /// for chemicals/diseases - var/permeability_coefficient = 1 - /// for electrical admittance/conductance (electrocution checks and shit) - var/siemens_coefficient = 1 - /// How much clothing is slowing you down. Negative values speeds you up. - var/slowdown = 0 - /// Flat armour reduction, occurs after percentage armour penetration. - var/armour_penetration_flat = 0 - /// Percentage armour reduction, happens before flat armour reduction. - var/armour_penetration_percentage = 0 - /// For what suits can store. IE. secuirty vest holding stunbatons, disablers, cuffs. - var/list/allowed = list() - /// All items can have an uplink hidden inside, just remember to add the triggers. - var/obj/item/uplink/hidden/hidden_uplink - - /// Used by security bots to determine if this item is safe for public use. - var/needs_permit = FALSE - /// How long it takes to remove an item off of somebody. IE. clothing - var/strip_delay = DEFAULT_ITEM_STRIP_DELAY - /// How long it takes to put an item onto somebody. IE. clothing - var/put_on_delay = DEFAULT_ITEM_PUTON_DELAY - /// For flags that define what areas an item cover - var/flags_cover = 0 - - /// Used to give a reaction chance on hit that is not a block. If less than 0, will remove the block message, allowing overides. - var/hit_reaction_chance = 0 - - /// What can/cant be worn, and where is valid to be worn by ian/E-N(and corgies), most of the time changing the name and emotes of the pet. - // Needs to be in /obj/item because corgis can wear a lot of non-clothing items - var/datum/dog_fashion/dog_fashion = null - - /// UID of a /mob - var/thrownby - - /// So items can have custom embedd values because customisation is king - var/embed_chance = EMBED_CHANCE - /// The chances of the item falling out of the limb - var/embedded_fall_chance = EMBEDDED_ITEM_FALLOUT - /// The cances of the item dealing damage to the limb - var/embedded_pain_chance = EMBEDDED_PAIN_CHANCE - /// The coefficient of multiplication for the damage this item does while embedded (this * w_class) - var/embedded_pain_multiplier = EMBEDDED_PAIN_MULTIPLIER - /// The coefficient of multiplication for the damage this item does when falling out of a limb (this * w_class) - var/embedded_fall_pain_multiplier = EMBEDDED_FALL_PAIN_MULTIPLIER - /// The coefficient of multiplication for the damage this item does when first embedded (this * w_class) - var/embedded_impact_pain_multiplier = EMBEDDED_IMPACT_PAIN_MULTIPLIER - /// The coefficient of multiplication for the damage removing this without surgery causes (this * w_class) - var/embedded_unsafe_removal_pain_multiplier = EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER - /// A time in ticks, multiplied by the w_class. - var/embedded_unsafe_removal_time = EMBEDDED_UNSAFE_REMOVAL_TIME - /// How fast something has to be going to embed - var/embedded_ignore_throwspeed_threshold = FALSE - - /// What kind of tool are we? - var/tool_behaviour = NONE - /// If we can turn on or off, are we currently active? Mostly for welders and this will normally be TRUE - var/tool_enabled = TRUE - /// How loud are we when we use our tool? - var/tool_volume = 50 - /// If this item is a tool, the speed multiplier. Smaller numbers are faster. - var/toolspeed = 1 - - /* Species-specific sprites, concept stolen from Paradise//vg/. - ex: - sprite_sheets = list( - "Tajaran" = 'icons/cat/are/bad' - ) - If index term exists and icon_override is not set, this sprite sheet will be used. - */ - var/list/sprite_sheets - /// Used to override inhand items. Use a single .dmi and suffix the icon states inside with _l and _r for each hand. - var/list/sprite_sheets_inhand - /// Used to override hardcoded clothing dmis in human clothing proc. - var/icon_override - /// Used to override hardcoded clothing inventory object dmis in human clothing proc. - var/sprite_sheets_obj - - //Tooltip vars - - /// Is this item equipped into an inventory slot or hand of a mob? - var/in_inventory = FALSE - - var/tip_timer = 0 - - /////////////////////////// - // MARK: item hover FX - /////////////////////////// - - /// Is this item inside a storage object? - var/in_storage = FALSE - // For assigning a belt overlay icon state in belts.dmi - var/belt_icon = null - /// Holder var for the item outline filter, null when no outline filter on the item. - var/outline_filter - /// In tiles, how far this weapon can reach; 1 for adjacent, which is default - var/reach = 1 - - scatter_distance = 5 - -/obj/item/New() - ..() - - if(!hitsound) - if(damtype == "fire") - hitsound = 'sound/items/welder.ogg' - if(damtype == "brute") - hitsound = "swing_hit" - LAZYINITLIST(attack_verb) - if(!move_resist) - determine_move_resist() - -/obj/item/Initialize(mapload) - . = ..() - for(var/path in actions_types) - new path(src, action_icon[path], action_icon_state[path]) - if(isstorage(loc)) //marks all items in storage as being such - in_storage = TRUE - -/// This proc is used to add text for items with ABSTRACT flag after default examine text. -/obj/item/proc/customised_abstract_text(mob/living/carbon/owner) - return - -/obj/item/proc/determine_move_resist() - switch(w_class) - if(WEIGHT_CLASS_TINY) - move_resist = MOVE_FORCE_EXTREMELY_WEAK - if(WEIGHT_CLASS_SMALL) - move_resist = MOVE_FORCE_VERY_WEAK - if(WEIGHT_CLASS_NORMAL) - move_resist = MOVE_FORCE_WEAK - if(WEIGHT_CLASS_BULKY) - move_resist = MOVE_FORCE_NORMAL - if(WEIGHT_CLASS_HUGE) - move_resist = MOVE_FORCE_NORMAL - if(WEIGHT_CLASS_GIGANTIC) - move_resist = MOVE_FORCE_NORMAL - -/obj/item/Destroy() - flags &= ~DROPDEL //prevent reqdels - QDEL_NULL(hidden_uplink) - if(ismob(loc)) - var/mob/m = loc - m.unequip(src, force = TRUE) - QDEL_LIST_CONTENTS(actions) - - master = null - return ..() - -/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self) - if(((src in target) && !target_self) || (!isturf(target.loc) && !isturf(target) && not_inside)) - return FALSE - else - return TRUE - -/obj/item/blob_act(obj/structure/blob/B) - if(B && B.loc == loc) - qdel(src) - -/obj/item/examine(mob/user) - var/size - switch(src.w_class) - if(WEIGHT_CLASS_TINY) - size = "tiny" - if(WEIGHT_CLASS_SMALL) - size = "small" - if(WEIGHT_CLASS_NORMAL) - size = "normal-sized" - if(WEIGHT_CLASS_BULKY) - size = "bulky" - if(WEIGHT_CLASS_HUGE) - size = "huge" - if(WEIGHT_CLASS_GIGANTIC) - size = "gigantic" - - . = ..(user, "", "It is a [size] item.") - - if(user.research_scanner) //Mob has a research scanner active. - var/msg = "*--------*
    " - - if(origin_tech) - msg += "Testing potentials:
    " - var/list/techlvls = params2list(origin_tech) - for(var/T in techlvls) //This needs to use the better names. - msg += "Tech: [GLOB.rnd_tech_id_to_name[T]] | Magnitude: [techlvls[T]]
    " - else - msg += "No tech origins detected.
    " - - if(length(materials)) - msg += "Extractable materials:
    " - for(var/mat in materials) - msg += "[CallMaterialName(mat)]
    " //Capitize first word, remove the "$" - else - msg += "No extractable materials detected.
    " - msg += "*--------*" - . += msg - - if(HAS_TRAIT(src, TRAIT_BUTCHERS_HUMANS)) - . += "Can be used to butcher dead people into meat while on harm intent." - -/obj/item/burn() - if(!QDELETED(src)) - var/turf/T = get_turf(src) - new /obj/effect/decal/cleanable/ash(T) - ..() - -/obj/item/acid_melt() - if(!QDELETED(src)) - var/turf/T = get_turf(src) - var/obj/effect/decal/cleanable/molten_object/MO = new(T) - MO.pixel_x = rand(-16,16) - MO.pixel_y = rand(-16,16) - MO.desc = "Looks like this was \an [src] some time ago." - ..() - -/obj/item/attack_hand(mob/user as mob, pickupfireoverride = FALSE) - if(!user) - return FALSE - if(ishuman(user)) - var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.bodyparts_by_name["r_hand"] - if(user.hand) - temp = H.bodyparts_by_name["l_hand"] - if(!temp) - to_chat(user, "You try to use your hand, but it's missing!") - return FALSE - if(temp && !temp.is_usable()) - to_chat(user, "You try to move your [temp.name], but cannot!") - return FALSE - - if((resistance_flags & ON_FIRE) && !pickupfireoverride) - var/mob/living/carbon/human/H = user - if(istype(H)) - if(H.gloves && (H.gloves.max_heat_protection_temperature > 360)) - extinguish() - to_chat(user, "You put out the fire on [src].") - else - to_chat(user, "You burn your hand on [src]!") - var/obj/item/organ/external/affecting = H.get_organ("[user.hand ? "l" : "r" ]_arm") - if(affecting && affecting.receive_damage(0, 5)) // 5 burn damage - H.UpdateDamageIcon() - return - else - extinguish() - - if(acid_level > 20 && !ismob(loc))// so we can still remove the clothes on us that have acid. - var/mob/living/carbon/human/H = user - if(istype(H)) - if(!H.gloves || (!(H.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF)))) - to_chat(user, "The acid on [src] burns your hand!") - var/obj/item/organ/external/affecting = H.get_organ("[user.hand ? "l" : "r" ]_arm") - if(affecting && affecting.receive_damage(0, 5)) // 5 burn damage - H.UpdateDamageIcon() - - if(..()) - return - - if(throwing) - throwing.finalize(FALSE) - - if(isliving(loc)) - if(loc == user) - if(HAS_TRAIT(user, TRAIT_I_WANT_BRAINS) || !user.unequip(src)) - return FALSE - else - return FALSE - - if(flags & ABSTRACT) - return FALSE - - pickup(user) - add_fingerprint(user) - if(!user.put_in_active_hand(src)) - dropped(user, TRUE) - return FALSE - - return TRUE - -/obj/item/attack_alien(mob/user) - var/mob/living/carbon/alien/A = user - - if(!A.has_fine_manipulation && !HAS_TRAIT(src, TRAIT_XENO_INTERACTABLE)) - if(src in A.contents) // To stop Aliens having items stuck in their pockets - A.drop_item_to_ground(src) - to_chat(user, "Your claws aren't capable of such fine manipulation!") - return - attack_hand(A) - -/obj/item/attack_ai(mob/user as mob) - if(istype(loc, /obj/item/robot_module)) - // If the item is part of a cyborg module, equip it - if(!isrobot(user)) - return - var/mob/living/silicon/robot/R = user - if(!R.low_power_mode) // Can't equip modules with an empty cell. - R.activate_module(src) - R.hud_used.update_robot_modules_display() - -// Due to storage type consolidation this should get used more now. -// I have cleaned it up a little, but it could probably use more. -Sayu -/obj/item/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) - if(isstorage(I)) - var/obj/item/storage/S = I - if(S.use_to_pickup) - if(S.pickup_all_on_tile) // Mode is set to collect all items on a tile and we clicked on a valid one. - if(isturf(loc)) - var/list/rejections = list() - var/success = 0 - var/failure = 0 - - for(var/obj/item/IT in loc) - if(IT.type in rejections) // To limit bag spamming: any given type only complains once - continue - if(!S.can_be_inserted(IT)) // Note can_be_inserted still makes noise when the answer is no - rejections += IT.type // therefore full bags are still a little spammy - failure = 1 - continue - success = 1 - S.handle_item_insertion(IT, user, TRUE) // The TRUE stops the "You put the [src] into [S]" insertion message from being displayed. - if(success && !failure) - to_chat(user, "You put everything in [S].") - else if(success) - to_chat(user, "You put some things in [S].") - else - to_chat(user, "You fail to pick anything up with [S].") - - else if(S.can_be_inserted(src)) - S.handle_item_insertion(src, user) - else if(istype(I, /obj/item/stack/tape_roll)) - if(isstorage(src)) // Don't tape the bag if we can put the duct tape inside it instead - var/obj/item/storage/bag = src - if(bag.can_be_inserted(I)) - return - var/obj/item/stack/tape_roll/TR = I - var/list/clickparams = params2list(params) - var/x_offset = text2num(clickparams["icon-x"]) - var/y_offset = text2num(clickparams["icon-y"]) - if(GetComponent(/datum/component/ducttape)) - to_chat(user, "[src] already has some tape attached!") - return - if(TR.use(1)) - to_chat(user, "You apply some tape to [src].") - AddComponent(/datum/component/ducttape, src, user, x_offset, y_offset) - anchored = TRUE - user.transfer_fingerprints_to(src) - else - to_chat(user, "You don't have enough tape to do that!") - -/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - var/signal_result = (SEND_SIGNAL(src, COMSIG_ITEM_HIT_REACT, owner, hitby, damage, attack_type)) + prob(final_block_chance) - if(!signal_result) - return FALSE - if(hit_reaction_chance >= 0) // Normally used for non blocking hit reactions, but also used for displaying block message on actual blocks - owner.visible_message("[owner] blocks [attack_text] with [src]!") - return signal_result - -/// Generic use proc. Depending on the item, it uses up fuel, charges, sheets, etc. Returns TRUE on success, FALSE on failure. -/obj/item/proc/use(used) - return !used - -/// Generic refill proc. Transfers something (e.g. fuel, charge) from an atom to our tool. returns TRUE if it was successful, FALSE otherwise -/obj/item/proc/refill(mob/user, atom/A, amount) // Not sure if there should be an argument that indicates what exactly is being refilled - return FALSE - -/obj/item/proc/talk_into(mob/M, text, channel=null) - return - -/// Called when a mob drops an item. -/obj/item/proc/dropped(mob/user, silent = FALSE) - SHOULD_CALL_PARENT(TRUE) - for(var/X in actions) - var/datum/action/A = X - A.Remove(user) - if(flags & DROPDEL) - qdel(src) - if((flags & NODROP) && !(initial(flags) & NODROP)) // Remove NODROP if dropped. Probably from delimbing. - flags &= ~NODROP - in_inventory = FALSE - mouse_opacity = initial(mouse_opacity) - remove_outline() - SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user) - if(!silent) - playsound(src, drop_sound, DROP_SOUND_VOLUME, ignore_walls = FALSE) - -// called just as an item is picked up (loc is not yet changed) -/obj/item/proc/pickup(mob/user) - SHOULD_CALL_PARENT(TRUE) - SEND_SIGNAL(src, COMSIG_ITEM_PICKUP, user) - in_inventory = TRUE - -// called when this item 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. -/obj/item/proc/on_exit_storage(obj/item/storage/S as obj) - in_storage = FALSE - return - -// called when this item is added into a storage item, which is passed on as S. The loc variable is already set to the storage item. -/obj/item/proc/on_enter_storage(obj/item/storage/S as obj) - in_storage = TRUE - return - -/** - * Called to check if this item can be put into a storage item. - * - * Return `FALSE` if `src` can't be inserted, and `TRUE` if it can. - * Arguments: - * * S - The [/obj/item/storage] that `src` is being inserted into. - * * user - The mob trying to insert the item. - */ -/obj/item/proc/can_enter_storage(obj/item/storage/S, mob/user) - return TRUE - -// called when "found" in pockets and storage items. Returns 1 if the search should end. -/obj/item/proc/on_found(mob/finder as mob) - return - -// called when the giver gives it to the receiver -/obj/item/proc/on_give(mob/living/carbon/giver, mob/living/carbon/receiver) - return - -// called after an item is placed in an equipment slot -// user is mob that equipped it -// slot uses the slot_X defines found in setup.dm -// for items that can be placed in multiple slots -// Initial is used to indicate whether or not this is the initial equipment (job datums etc) or just a player doing it -/obj/item/proc/equipped(mob/user, slot, initial = FALSE) - mouse_opacity = MOUSE_OPACITY_OPAQUE - SEND_SIGNAL(src, COMSIG_ITEM_EQUIPPED, user, slot) - for(var/X in actions) - var/datum/action/A = X - if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot. - A.Grant(user) - in_inventory = TRUE - if(!initial) - if(equip_sound && (slot & slot_flags)) - playsound(src, equip_sound, EQUIP_SOUND_VOLUME, TRUE, ignore_walls = FALSE) - else if(slot & ITEM_SLOT_BOTH_HANDS) - playsound(src, pickup_sound, PICKUP_SOUND_VOLUME, ignore_walls = FALSE) - -/obj/item/proc/item_action_slot_check(slot, mob/user) - return TRUE - -/// returns TRUE if the item is equipped by a mob, 0 otherwise. -/obj/item/proc/is_equipped() // This might need some error trapping, not sure if get_equipped_items() is safe for non-human mobs. - if(!ismob(loc)) - return FALSE - - var/mob/M = loc - if(src in M.get_equipped_items()) - return TRUE - else - return FALSE - -// the mob(M) is attempting to equip this item into the slot passed through as 'slot'. Return TRUE if it can do this and FALSE if it can't. -// If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen. -// Set disable_warning to FALSE if you wish it to not give you outputs. -/obj/item/proc/mob_can_equip(mob/M, slot, disable_warning = FALSE) - if(!M) - return FALSE - - return M.can_equip(src, slot, disable_warning) - -/obj/item/verb/verb_pickup() - set src in oview(1) - set category = null - set name = "Pick up" - - if(!(usr)) // BS12 EDIT - return - if(usr.incapacitated() || !Adjacent(usr)) - return - if(!iscarbon(usr) || isbrain(usr)) // Is humanoid, and is not a brain - to_chat(usr, "You can't pick things up!") - return - if(anchored) // Object isn't anchored - to_chat(usr, "You can't pick that up!") - return - if(!usr.hand && usr.r_hand) // Right hand is not full - to_chat(usr, "Your right hand is full.") - return - if(usr.hand && usr.l_hand) // Left hand is not full - to_chat(usr, "Your left hand is full.") - return - if(!isturf(loc)) // Object is on a turf - to_chat(usr, "You can't pick that up!") - return - // All checks are done, time to pick it up! - usr.UnarmedAttack(src) - - -// This proc is executed when someone clicks the on-screen UI button. -// The default action is attack_self(). -// Checks before we get to here are: mob is alive, mob is not restrained, paralyzed, asleep, resting, laying, item is on the mob. -/obj/item/proc/ui_action_click(mob/user, actiontype) - attack_self__legacy__attackchain(user) - -/obj/item/proc/IsReflect(def_zone) // This proc determines if and at what% an object will reflect energy projectiles if it's in l_hand,r_hand or wear_suit - return FALSE - -/obj/item/proc/get_loc_turf() - var/atom/L = loc - while(L && !isturf(L)) - L = L.loc - return loc - -/obj/item/proc/eyestab(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - if(force && HAS_TRAIT(user, TRAIT_PACIFISM)) - to_chat(user, "You don't want to harm other living beings!") - return FALSE - - var/mob/living/carbon/human/H = M - if(istype(H) && ( \ - (H.head && H.head.flags_cover & HEADCOVERSEYES) || \ - (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || \ - (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES) \ - )) - // you can't stab someone in the eyes wearing a mask! - to_chat(user, "You're going to need to remove that mask/helmet/glasses first!") - return - - if(isalien(M) || isslime(M)) // Aliens don't have eyes, slimes also don't have eyes! - to_chat(user, "You cannot locate any eyes on this creature!") - return - - if(!iscarbon(user)) - M.LAssailant = null - else - M.LAssailant = user - - src.add_fingerprint(user) - - playsound(loc, src.hitsound, 30, TRUE, -1) - - user.do_attack_animation(M) - - if(H.check_shields(src, force, "the [name]", MELEE_ATTACK, armour_penetration_flat, armour_penetration_percentage)) - return FALSE - - if(H.check_block()) - visible_message("[H] blocks [src]!") - return FALSE - - if(M != user) - M.visible_message("[user] has stabbed [M] in the eye with [src]!", \ - "[user] stabs you in the eye with [src]!") - else - user.visible_message( \ - "[user] has stabbed [user.p_themselves()] in the eyes with [src]!", \ - "You stab yourself in the eyes with [src]!" \ - ) - - add_attack_logs(user, M, "Eye-stabbed with [src] ([uppertext(user.a_intent)])") - - if(istype(H)) - var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes) - if(!eyes) // should still get stabbed in the head - var/obj/item/organ/external/head/head = H.bodyparts_by_name["head"] - if(head) - head.receive_damage(force, TRUE) - return - eyes.receive_damage(rand(3,4), 1) - if(eyes.damage >= eyes.min_bruised_damage) - if(M.stat != 2) - if(!eyes.is_robotic()) // robot eyes bleeding might be a bit silly - to_chat(M, "Your eyes start to bleed profusely!") - if(prob(50)) - if(M.stat != DEAD) - to_chat(M, "You drop what you're holding and clutch at your eyes!") - M.drop_item() - M.AdjustEyeBlurry(20 SECONDS) - M.Paralyse(2 SECONDS) - M.Weaken(4 SECONDS) - if(eyes.damage >= eyes.min_broken_damage) - if(M.stat != 2) - to_chat(M, "You go blind!") - var/obj/item/organ/external/affecting = H.get_organ("head") - if(istype(affecting) && affecting.receive_damage(force)) - H.UpdateDamageIcon() - else - M.take_organ_damage(force) - M.AdjustEyeBlurry(rand(6 SECONDS, 8 SECONDS)) - return - -/obj/item/singularity_pull(S, current_size) - ..() - if(current_size >= STAGE_FOUR) - throw_at(S, 14, 3, spin = 0) - else - return - -/obj/item/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - if(hit_atom && !QDELETED(hit_atom)) - SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum) - var/itempush = TRUE - if(w_class < WEIGHT_CLASS_BULKY) - itempush = FALSE // too light to push anything - if(isliving(hit_atom)) // Living mobs handle hit sounds differently. - if(get_heat()) - var/mob/living/L = hit_atom - L.IgniteMob() - var/volume = get_volume_by_throwforce_and_or_w_class() - if(throwforce > 0) - if(mob_throw_hit_sound) - SSthrowing.playsound_capped(hit_atom, mob_throw_hit_sound, volume, TRUE, -1) - else if(hitsound) - SSthrowing.playsound_capped(hit_atom, hitsound, volume, TRUE, -1) - else - SSthrowing.playsound_capped(hit_atom, 'sound/weapons/genhit.ogg', volume, TRUE, -1) - else - SSthrowing.playsound_capped(hit_atom, 'sound/weapons/throwtap.ogg', volume, TRUE, -1) - - else - SSthrowing.playsound_capped(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, dodgeable) - thrownby = thrower?.UID() - callback = CALLBACK(src, PROC_REF(after_throw), callback) // replace their callback with our own - . = ..(target, range, speed, thrower, spin, diagonals_first, callback, force, dodgeable) - -/obj/item/proc/after_throw(datum/callback/callback) - if(callback) // call the original callback - . = callback.Invoke() - throw_speed = initial(throw_speed) // explosions change this. - in_inventory = FALSE - -/obj/item/proc/pwr_drain() - return FALSE // Process Kill - -/obj/item/proc/remove_item_from_storage(atom/newLoc) // please use this if you're going to snowflake an item out of a obj/item/storage - if(!newLoc) - return FALSE - if(isstorage(loc)) - var/obj/item/storage/S = loc - S.remove_from_storage(src,newLoc) - return TRUE - return FALSE - - -/obj/item/proc/wash(mob/user, atom/source) - if(flags & ABSTRACT) // Abstract items like grabs won't wash. No-drop items will though because it's still technically an item in your hand. - return - to_chat(user, "You start washing [src]...") - if(!do_after(user, 40, target = source)) - return - clean_blood() - acid_level = 0 - user.visible_message("[user] washes [src] using [source].", \ - "You wash [src] using [source].") - return TRUE - -/obj/item/proc/get_crutch_efficiency() // Does an item prop up a human mob and allow them to stand if they are missing a leg/foot? - return FALSE - -/// Return true if you don't want regular throw handling -/obj/item/proc/override_throw(mob/user, atom/target) - return FALSE - -/obj/item/proc/is_equivalent(obj/item/I) - return I == src - -/obj/item/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) - return SEND_SIGNAL(src, COMSIG_ATOM_HITBY, AM, skipcatch, hitpush, blocked, throwingdatum) - -/obj/item/attack_hulk(mob/living/carbon/human/user) - return FALSE - -/obj/item/attack_animal(mob/living/simple_animal/M) - if(can_be_hit) - return ..() - return FALSE - -/obj/item/mech_melee_attack(obj/mecha/M) - return FALSE - -/obj/item/proc/openTip(location, control, params, user) - openToolTip(user, src, params, title = name, content = "[desc]", theme = "") - -/obj/item/MouseEntered(location, control, params) - . = ..() - if(in_inventory || in_storage) - var/mob/user = usr - if(!(user.client.prefs.toggles2 & PREFTOGGLE_2_HIDE_ITEM_TOOLTIPS)) - tip_timer = addtimer(CALLBACK(src, PROC_REF(openTip), location, control, params, user), 8, TIMER_STOPPABLE) - if(QDELETED(src)) - return - if(!(user.client.prefs.toggles2 & PREFTOGGLE_2_SEE_ITEM_OUTLINES)) - return - var/mob/living/L = user - if(istype(L) && HAS_TRAIT(L, TRAIT_HANDS_BLOCKED)) - apply_outline(L, 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(L) // if the player's alive and well we send the command with no color set, so it uses the theme's color - -/obj/item/MouseExited() - deltimer(tip_timer) // delete any in-progress timer if the mouse is moved off the item before it finishes - closeToolTip(usr) - remove_outline() - return ..() - -/obj/item/MouseDrop_T(obj/item/I, mob/user) - if(!user || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || src == I || !isliving(user)) - return - - if(loc && I.loc == loc && isstorage(loc) && loc.Adjacent(user)) // Are we trying to swap two items in the storage? - var/obj/item/storage/S = loc - S.swap_items(src, I, user) - remove_outline() - return TRUE - remove_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/proc/apply_outline(mob/user, outline_color = null) - if(!(in_inventory || in_storage) || QDELETED(src) || isobserver(user)) // 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(user.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 - if(outline_filter) - filters -= outline_filter - outline_filter = filter(type = "outline", size = 1, color = outline_color) - filters += outline_filter - -/obj/item/proc/remove_outline() - if(outline_filter) - filters -= outline_filter - outline_filter = null - -/// Returns a numeric value for sorting items used as parts in machines, so they can be replaced by the B/RPED -/obj/item/proc/get_part_rating() - return 0 - -/obj/item/proc/update_slot_icon() - if(!ismob(loc)) - return - var/mob/owner = loc - var/flags = slot_flags - if(flags & ITEM_SLOT_OUTER_SUIT) - owner.update_inv_wear_suit() - if(flags & ITEM_SLOT_JUMPSUIT) - owner.update_inv_w_uniform() - if(flags & ITEM_SLOT_GLOVES) - owner.update_inv_gloves() - if(flags & ITEM_SLOT_EYES) - owner.update_inv_glasses() - if(flags & ITEM_SLOT_BOTH_EARS) - owner.update_inv_ears() - if(flags & ITEM_SLOT_MASK) - owner.update_inv_wear_mask() - if(flags & ITEM_SLOT_NECK) - owner.update_inv_neck() - if(flags & ITEM_SLOT_HEAD) - owner.update_inv_head() - if(flags & ITEM_SLOT_SHOES) - owner.update_inv_shoes() - if(flags & ITEM_SLOT_ID) - owner.update_inv_wear_id() - if(flags & ITEM_SLOT_BELT) - owner.update_inv_belt() - if(flags & ITEM_SLOT_BACK) - owner.update_inv_back() - if(flags & ITEM_SLOT_PDA) - owner.update_inv_wear_pda() - -/// Called on cyborg items that need special charging behavior. Override as needed for specific items. -/obj/item/proc/cyborg_recharge(coeff = 1, emagged = FALSE) - return - -// Access and Job stuff - -/// Used in secHUD icon generation -/obj/item/proc/get_job_name() - var/assignmentName = get_ID_assignment(if_no_id = "Unknown") - var/rankName = get_ID_rank(if_no_id = "Unknown") - - var/job_icons = get_all_job_icons() - var/centcom = get_all_centcom_jobs() - var/solgov = get_all_solgov_jobs() - var/soviet = get_all_soviet_jobs() - var/special = get_all_special_jobs() - - // Return with the NT logo if it is a Centcom job - if((assignmentName in centcom) || (rankName in centcom)) - return "centcom" - - // Return with the SolGov logo if it is a SolGov job - if((assignmentName in solgov) || (rankName in solgov)) - return "solgov" - - // Return with the U.S.S.P logo if it is a Soviet job - if((assignmentName in soviet) || (rankName in soviet)) - return "soviet" - - // For roles that can't be assigned to any category and require custom icon - if(assignmentName in special) - return assignmentName - - if(rankName in special) - return rankName - - // Check if the job has a hud icon - if(assignmentName in job_icons) - return assignmentName - - if(rankName in job_icons) - return rankName - - // Return unknown hud if none of the above apply - return "unknown" - -/obj/item/proc/get_ID_assignment(if_no_id = "No id") - var/obj/item/card/id/id = GetID() - if(istype(id)) // Make sure its actually an ID - return id.assignment - return if_no_id - -/obj/item/proc/get_ID_rank(if_no_id = "No id") - var/obj/item/card/id/id = GetID() - if(istype(id)) // Make sure its actually an ID - return id.rank - return if_no_id - -/obj/item/proc/GetAccess() - return list() - -/obj/item/proc/GetID() - return null - -/obj/item/proc/add_tape() - return - -/obj/item/proc/remove_tape() - return - -/obj/item/water_act(volume, temperature, source, method) - . = ..() - if(HAS_TRAIT(src, TRAIT_OIL_SLICKED)) - slowdown = initial(slowdown) - remove_atom_colour(FIXED_COLOUR_PRIORITY) - REMOVE_TRAIT(src, TRAIT_OIL_SLICKED, "potion") - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.regenerate_icons() - -/obj/item/cleaning_act(mob/user, atom/cleaner, cleanspeed, text_verb, text_description, text_targetname) - . = ..() - if(HAS_TRAIT(src, TRAIT_OIL_SLICKED)) - slowdown = initial(slowdown) - remove_atom_colour(FIXED_COLOUR_PRIORITY) - REMOVE_TRAIT(src, TRAIT_OIL_SLICKED, "potion") - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.regenerate_icons() - -/obj/item/proc/get_heat() - return - -/obj/item/proc/run_pointed_on_item(mob/pointer_mob, atom/target_atom) - if(!HAS_TRAIT(src, TRAIT_CAN_POINT_WITH) || target_atom == src) - return FALSE - - var/pointed_object = "\the [target_atom]" - if(target_atom.loc in pointer_mob) - pointed_object += " inside [target_atom.loc]" - - if(pointer_mob.a_intent == INTENT_HELP || !ismob(target_atom)) - pointer_mob.visible_message("[pointer_mob] points to [pointed_object] with [src].") - return TRUE - - target_atom.visible_message("[pointer_mob] points [src] at [pointed_object]!", - "[pointer_mob] points [src] at you!") - SEND_SOUND(target_atom, sound('sound/weapons/targeton.ogg')) - return TRUE - -/obj/item/proc/canStrip(mob/stripper, mob/owner) - SHOULD_BE_PURE(TRUE) - return !(flags & NODROP) && !(flags & ABSTRACT) && !HAS_TRAIT(src, TRAIT_NO_STRIP) - -/obj/item/proc/should_stack_with(obj/item/other) - return type == other.type && name == other.name - -/** - * Handles the bulk of cigarette lighting interactions. You must call `light()` to actually light the cigarette. - * - * Returns: the target's cigarette (or the cigarette itself if attacked directly) if all checks are passed. - * If the cigarette is already lit, or is a fancy smokable being lit by anything other than a zippo or match, will return `FALSE`. - * Otherwise it will return `null`. - * Arguments: - * * user - The mob trying to light the cigarette. - * * target - The mob with the cigarette. - * * direct_attackby_item - Used if the cigarette item is clicked on directly with a lighter instead of a mob wearing a cigarette. - */ -/obj/item/proc/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item) - if(!user || !target) - return null - - var/obj/item/clothing/mask/cigarette/cig = direct_attackby_item ? direct_attackby_item : target.wear_mask - if(!istype(cig)) - return null - - if(!direct_attackby_item && (user.zone_selected != "mouth" || user.a_intent != INTENT_HELP)) - return null - - if(cig.lit) - to_chat(user, "[cig] is already lit!") - return FALSE - - // Only matches and cigars can light fancy smokables. - if(length(cig.fancy_lighters) && !is_type_in_list(src, cig.fancy_lighters)) - to_chat(user, "[cig] straight out REFUSES to be lit by such uncivilized means!") - return FALSE - - return cig diff --git a/code/game/objects/items/ashtray.dm b/code/game/objects/items/ashtray.dm deleted file mode 100644 index 1f6cb261a9d3e..0000000000000 --- a/code/game/objects/items/ashtray.dm +++ /dev/null @@ -1,99 +0,0 @@ -/obj/item/ashtray - icon = 'icons/ashtray.dmi' - var/max_butts = 0 - var/icon_half = "" - var/icon_full = "" - var/material = /obj/item/stack/sheet/metal - -/obj/item/ashtray/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/cigbutt) || istype(I, /obj/item/clothing/mask/cigarette) || istype(I, /obj/item/match)) - if(length(contents) >= max_butts) - to_chat(user, "This ashtray is full.") - return - if(!user.unequip(I)) - return - I.forceMove(src) - - if(istype(I, /obj/item/clothing/mask/cigarette)) - var/obj/item/clothing/mask/cigarette/cig = I - if(cig.lit) - visible_message("[user] crushes [cig] in [src], putting it out.") - var/obj/item/butt = new cig.type_butt(src) - cig.transfer_fingerprints_to(butt) - qdel(cig) - else - to_chat(user, "You place [cig] in [src] without even smoking it. Why would you do that?") - - visible_message("[user] places [I] in [src].") - add_fingerprint(user) - update_appearance(UPDATE_DESC|UPDATE_ICON_STATE) - else - return ..() - -/obj/item/ashtray/update_icon_state() - if(length(contents) == max_butts) - icon_state = icon_full - else if(length(contents) > max_butts * 0.5) - icon_state = icon_half - else - icon_state = initial(icon_state) - -/obj/item/ashtray/update_desc() - . = ..() - if(length(contents) == max_butts) - desc = initial(desc) + " It's stuffed full." - else if(length(contents) > max_butts * 0.5) - desc = initial(desc) + " It's half-filled." - else - desc = initial(desc) - -/obj/item/ashtray/proc/empty_tray() - for(var/obj/item/I in contents) - I.forceMove(loc) - update_appearance(UPDATE_DESC|UPDATE_ICON_STATE) - -/obj/item/ashtray/throw_impact(atom/hit_atom) - if(length(contents)) - visible_message("[src] slams into [hit_atom] spilling its contents!") - empty_tray() - return ..() - -/obj/item/ashtray/wrench_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, volume = I.tool_volume)) - return - empty_tray() - new material(drop_location(), 1) - deconstruct() - -/obj/item/ashtray/plastic - name = "plastic ashtray" - desc = "Cheap plastic ashtray." - icon_state = "ashtray_bl" - icon_half = "ashtray_half_bl" - icon_full = "ashtray_full_bl" - max_butts = 8 - max_integrity = 8 - material = /obj/item/stack/sheet/plastic - throwforce = 3 - -/obj/item/ashtray/bronze - name = "bronze ashtray" - desc = "Massive bronze ashtray." - icon_state = "ashtray_br" - icon_half = "ashtray_half_br" - icon_full = "ashtray_full_br" - max_butts = 16 - max_integrity = 16 - throwforce = 10 - -/obj/item/ashtray/glass - name = "glass ashtray" - desc = "Glass ashtray. Looks fragile." - icon_state = "ashtray_gl" - icon_half = "ashtray_half_gl" - icon_full = "ashtray_full_gl" - max_butts = 12 - max_integrity = 12 - material = /obj/item/stack/sheet/glass - throwforce = 6 diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm deleted file mode 100644 index 326f7f2b8390d..0000000000000 --- a/code/game/objects/items/blueprints.dm +++ /dev/null @@ -1,338 +0,0 @@ -/obj/item/areaeditor - name = "area modification item" - icon = 'icons/obj/items.dmi' - icon_state = "blueprints" - attack_verb = list("attacked", "bapped", "hit") - /// Extra text added to the description. - var/fluffnotice = "If you can read this, make an issue report on GitHub. Something done goofed!" - - var/const/AREA_ERRNONE = 0 - var/const/AREA_STATION = 1 - var/const/AREA_SPACE = 2 - var/const/AREA_SPECIAL = 3 - - var/const/BORDER_ERROR = 0 - var/const/BORDER_NONE = 1 - var/const/BORDER_BETWEEN = 2 - var/const/BORDER_2NDTILE = 3 - var/const/BORDER_SPACE = 4 - - var/const/ROOM_ERR_LOLWAT = 0 - var/const/ROOM_ERR_SPACE = -1 - var/const/ROOM_ERR_TOOLARGE = -2 - - -/obj/item/areaeditor/attack_self__legacy__attackchain(mob/user as mob) - add_fingerprint(user) - var/text = "[src] \ -

    [station_name()] [src.name]

    \ - [fluffnotice]
    " - switch(get_area_type()) - if(AREA_SPACE) - text += "

    According to [src], you are now in outer space. Hold your breath.

    \ -

    Mark this place as new area.

    " - if(AREA_SPECIAL) - text += "

    This place is not noted on [src].

    " - return text - - -/obj/item/areaeditor/Topic(href, href_list) - if(..()) - return - if(href_list["create_area"]) - if(get_area_type()==AREA_SPACE) - create_area() - - - -//One-use area creation permits. -/obj/item/areaeditor/permit - name = "construction permit" - icon_state = "permit" - desc = "This is a one-use permit that allows the user to officially declare a built room as an addition to the station." - fluffnotice = "Nanotrasen Engineering requires all on-station construction projects to be approved by a head of staff, as detailed in Nanotrasen Company Regulation 512-C (Mid-Shift Modifications to Company Property). \ - By submitting this form, you accept any fines, fees, or personal injury/death that may occur during construction." - w_class = WEIGHT_CLASS_TINY - -/obj/item/areaeditor/permit/attack_self__legacy__attackchain(mob/user) - . = ..() - var/area/our_area = get_area(src) - if(get_area_type() == AREA_STATION) - . += "

    According to [src], you are now in \"[sanitize(our_area.name)]\".

    " - var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500) - popup.set_content(.) - popup.open() - onclose(usr, "blueprints") - - -/obj/item/areaeditor/permit/create_area() - if(..()) - qdel(src) - -//free golem blueprints, like permit but can claim as much as needed - -/obj/item/areaeditor/golem - name = "Golem Land Claim" - desc = "Used to define new areas in space." - fluffnotice = "Praise the Liberator!" - -/obj/item/areaeditor/golem/attack_self__legacy__attackchain(mob/user) - . = ..() - var/area/our_area = get_area(src) - if(get_area_type() == AREA_STATION) - . += "

    According to [src], you are now in \"[sanitize(our_area.name)]\".

    " - var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500) - popup.set_content(.) - popup.open() - onclose(usr, "blueprints") - -//Station blueprints!!! -/obj/item/areaeditor/blueprints - name = "station blueprints" - desc = "Blueprints of the station. There is a \"CONFIDENTIAL\" stamp and several coffee stains on it." - icon = 'icons/obj/items.dmi' - icon_state = "blueprints" - fluffnotice = "Property of Nanotrasen. For heads of staff only. Store in high-security storage." - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - w_class = WEIGHT_CLASS_NORMAL - var/list/showing = list() - var/client/viewing - -/obj/item/areaeditor/blueprints/Destroy() - clear_viewer() - return ..() - - -/obj/item/areaeditor/blueprints/attack_self__legacy__attackchain(mob/user) - . = ..() - var/area/our_area = get_area(src) - if(get_area_type() == AREA_STATION) - . += "

    According to [src], you are now in \"[sanitize(our_area.name)]\".

    " - . += "

    You may move an amendment to the drawing.

    " - if(!viewing) - . += "

    View structural data

    " - else - . += "

    Refresh structural data

    " - . += "

    Hide structural data

    " - var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500) - popup.set_content(.) - popup.open() - onclose(user, "blueprints") - - -/obj/item/areaeditor/blueprints/Topic(href, href_list) - ..() - if(href_list["edit_area"]) - if(get_area_type()!=AREA_STATION) - return - edit_area() - if(href_list["view_blueprints"]) - set_viewer(usr, "You flip the blueprints over to view the complex information diagram.") - if(href_list["hide_blueprints"]) - clear_viewer(usr, "You flip the blueprints over to view the simple information diagram.") - if(href_list["refresh"]) - clear_viewer(usr) - set_viewer(usr) - - attack_self__legacy__attackchain(usr) - -/obj/item/areaeditor/blueprints/proc/get_images(turf/central_turf, viewsize) - . = list() - var/list/dimensions = getviewsize(viewsize) - var/horizontal_radius = dimensions[1] / 2 - var/vertical_radius = dimensions[2] / 2 - for(var/turf/nearby_turf as anything in RECT_TURFS(horizontal_radius, vertical_radius, central_turf)) - if(nearby_turf.blueprint_data) - . += nearby_turf.blueprint_data - -/obj/item/areaeditor/blueprints/proc/set_viewer(mob/user, message = "") - if(user && user.client) - if(viewing) - clear_viewer() - viewing = user.client - showing = get_images(get_turf(viewing.eye || user), viewing.view) - viewing.images |= showing - if(message) - to_chat(user, message) - -/obj/item/areaeditor/blueprints/proc/clear_viewer(mob/user, message = "") - if(viewing) - viewing.images -= showing - viewing = null - showing.Cut() - if(message) - to_chat(user, message) - -/obj/item/areaeditor/blueprints/dropped(mob/user) - ..() - clear_viewer() - -/obj/item/areaeditor/proc/get_area_type(area/A) - if(!A) - A = get_area(src) - if(A.outdoors) - return AREA_SPACE - var/list/SPECIALS = list( - /area/shuttle, - /area/admin, - /area/centcom, - /area/tdome, - /area/wizard_station - ) - for(var/type in SPECIALS) - if(istype(A,type)) - return AREA_SPECIAL - return AREA_STATION - - -/obj/item/areaeditor/proc/create_area() - var/area_created = FALSE - var/res = detect_room(get_turf(usr)) - if(!istype(res,/list)) - switch(res) - if(ROOM_ERR_SPACE) - to_chat(usr, "The new area must be completely airtight.") - return area_created - if(ROOM_ERR_TOOLARGE) - to_chat(usr, "The new area is too large.") - return area_created - else - to_chat(usr, "Error! Please notify administration.") - return area_created - var/list/turf/turfs = res - var/str = tgui_input_text(usr, "New area name:", "Blueprint Editing", max_length = MAX_NAME_LEN, encode = FALSE) - if(!str || !length(str)) // Cancel - return area_created - var/area/A = new - A.name = str - A.powernet.equipment_powered = FALSE - A.powernet.lighting_powered = FALSE - A.powernet.environment_powered = FALSE - A.always_unpowered = FALSE - A.set_dynamic_lighting() - - for(var/i in 1 to length(turfs)) - var/turf/thing = turfs[i] - var/area/old_area = thing.loc - A.contents += thing - thing.change_area(old_area, A) - - var/area/oldA = get_area(get_turf(usr)) - var/list/firedoors = oldA.firedoors - for(var/door in firedoors) - var/obj/machinery/door/firedoor/FD = door - FD.CalculateAffectingAreas() - - interact() - message_admins("A new room was made by [key_name_admin(usr)] at [ADMIN_VERBOSEJMP(usr)] with the name [str]") - log_game("A new room was made by [key_name(usr)] at [AREACOORD(usr)] with the name [str]") - area_created = TRUE - return area_created - -/obj/item/areaeditor/proc/edit_area() - var/area/our_area = get_area(src) - var/prevname = "[sanitize(our_area.name)]" - var/str = tgui_input_text(usr, "New area name:", "Blueprint Editing", prevname, MAX_NAME_LEN, encode = FALSE) - if(!str || !length(str) || str == prevname) // Cancel - return - set_area_machinery_title(our_area, str, prevname) - our_area.name = str - if(our_area.firedoors) - for(var/D in our_area.firedoors) - var/obj/machinery/door/firedoor/FD = D - FD.CalculateAffectingAreas() - to_chat(usr, "You rename the '[prevname]' to '[str]'.") - interact() - message_admins("A room was renamed by [key_name_admin(usr)] at [ADMIN_VERBOSEJMP(usr)] changing the name from [prevname] to [str]") - log_game("A room was renamed by [key_name(usr)] at [AREACOORD(usr)] changing the name from [prevname] to [str] ") - return TRUE - -/obj/item/areaeditor/proc/set_area_machinery_title(area/A, title, oldtitle) - if(!oldtitle) // or replacetext goes to infinite loop - return - for(var/obj/machinery/alarm/M in A) - M.name = replacetext(M.name,oldtitle,title) - for(var/obj/machinery/power/apc/M in A) - M.name = replacetext(M.name,oldtitle,title) - for(var/obj/machinery/atmospherics/unary/vent_scrubber/M in A) - M.name = replacetext(M.name,oldtitle,title) - for(var/obj/machinery/atmospherics/unary/vent_pump/M in A) - M.name = replacetext(M.name,oldtitle,title) - for(var/obj/machinery/door/M in A) - M.name = replacetext(M.name,oldtitle,title) - //TODO: much much more. Unnamed airlocks, cameras, etc. - -/obj/item/areaeditor/proc/check_tile_is_border(turf/T2, dir) - if(isspaceturf(T2)) - return BORDER_SPACE //omg hull breach we all going to die here - if(get_area_type(T2.loc)!=AREA_SPACE) - return BORDER_BETWEEN - if(iswallturf(T2)) - return BORDER_2NDTILE - if(ismineralturf(T2)) - return BORDER_2NDTILE - if(!issimulatedturf(T2)) - return BORDER_BETWEEN - - for(var/obj/structure/window/W in T2) - if(turn(dir,180) == W.dir) - return BORDER_BETWEEN - if(W.dir in list(NORTHEAST,SOUTHEAST,NORTHWEST,SOUTHWEST)) - return BORDER_2NDTILE - for(var/obj/machinery/door/window/D in T2) - if(turn(dir,180) == D.dir) - return BORDER_BETWEEN - if(locate(/obj/machinery/door) in T2) - return BORDER_2NDTILE - if(locate(/obj/structure/falsewall) in T2) - return BORDER_2NDTILE - - return BORDER_NONE - - -/obj/item/areaeditor/proc/detect_room(turf/first) - var/list/turf/found = list() - var/list/turf/pending = list(first) - while(length(pending)) - if(found.len+length(pending) > 300) - return ROOM_ERR_TOOLARGE - var/turf/T = pending[1] //why byond havent list::pop()? - pending -= T - for(var/dir in GLOB.cardinal) - var/skip = 0 - for(var/obj/structure/window/W in T) - if(dir == W.dir || (W.dir in list(NORTHEAST,SOUTHEAST,NORTHWEST,SOUTHWEST))) - skip = 1; break - if(skip) continue - for(var/obj/machinery/door/window/D in T) - if(dir == D.dir) - skip = 1; break - if(skip) continue - - var/turf/NT = get_step(T,dir) - if(!isturf(NT) || (NT in found) || (NT in pending)) - continue - - switch(check_tile_is_border(NT,dir)) - if(BORDER_NONE) - pending+=NT - if(BORDER_2NDTILE) - found+=NT //tile included to new area, but we dont seek more - if(BORDER_SPACE) - return ROOM_ERR_SPACE - found+=T - return found - -//Blueprint Subtypes - -/obj/item/areaeditor/blueprints/cyborg - name = "station schematics" - desc = "A digital copy of the station blueprints stored in your memory." - fluffnotice = "Intellectual Property of Nanotrasen. For use in engineering cyborgs only. Wipe from memory upon departure from the station." - -/obj/item/areaeditor/blueprints/ce - -/obj/item/areaeditor/blueprints/ce/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT) - AddElement(/datum/element/high_value_item) diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm deleted file mode 100644 index ac69cde165bd3..0000000000000 --- a/code/game/objects/items/bodybag.dm +++ /dev/null @@ -1,81 +0,0 @@ -//Also contains /obj/structure/closet/body_bag because I doubt anyone would think to look for bodybags in /object/structures - -/obj/item/bodybag - name = "body bag" - desc = "A folded bag designed for the storage and transportation of cadavers." - icon = 'icons/obj/bodybag.dmi' - icon_state = "bodybag_folded" - w_class = WEIGHT_CLASS_SMALL - -/obj/item/bodybag/attack_self__legacy__attackchain(mob/user) - var/obj/structure/closet/body_bag/R = new /obj/structure/closet/body_bag(user.loc) - R.add_fingerprint(user) - qdel(src) - -/obj/structure/closet/body_bag - name = "body bag" - desc = "A plastic bag designed for the storage and transportation of cadavers." - icon = 'icons/obj/bodybag.dmi' - icon_state = "bodybag" - enable_door_overlay = FALSE - door_anim_time = 0 - density = FALSE - integrity_failure = 0 - open_sound = 'sound/items/zip.ogg' - close_sound = 'sound/items/zip.ogg' - open_sound_volume = 15 - close_sound_volume = 15 - var/item_path = /obj/item/bodybag - -/obj/structure/closet/body_bag/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(is_pen(I)) - var/t = rename_interactive(user, I) - if(isnull(t)) - return - cut_overlays() - if(t) - add_overlay("bodybag_label") - return - if(istype(I, /obj/item/wirecutters)) - to_chat(user, "You cut the tag off the bodybag.") - name = initial(name) - cut_overlays() - return - return ..() - -/obj/structure/closet/body_bag/welder_act(mob/user, obj/item/I) - return // Can't weld a body bag shut - -/obj/structure/closet/body_bag/close() - if(..()) - density = FALSE - return TRUE - return FALSE - -/obj/structure/closet/body_bag/update_overlays() - . = ..() - if(name != initial(name)) - . += "bodybag_label" - -/obj/structure/closet/body_bag/MouseDrop(over_object, src_location, over_location) - if(over_object == usr && (in_range(src, usr) || usr.contents.Find(src))) - if(!ishuman(usr) || opened || length(contents)) - return FALSE - visible_message("[usr] folds up [src].") - new item_path(get_turf(src)) - qdel(src) - return - . = ..() - -/obj/structure/closet/body_bag/relaymove(mob/user) - if(user.stat) - return - - // Make it possible to escape from bodybags in morgues and crematoriums - if(loc && (isturf(loc) || istype(loc, /obj/structure/morgue) || istype(loc, /obj/structure/crematorium))) - if(!open()) - to_chat(user, "It won't budge!") - -/obj/structure/closet/body_bag/shove_impact(mob/living/target, mob/living/attacker) - // no, you can't shove people into a body bag - return FALSE diff --git a/code/game/objects/items/candle.dm b/code/game/objects/items/candle.dm deleted file mode 100644 index 0292c37eec907..0000000000000 --- a/code/game/objects/items/candle.dm +++ /dev/null @@ -1,166 +0,0 @@ -#define TALL_CANDLE 1 -#define MID_CANDLE 2 -#define SHORT_CANDLE 3 - -/obj/item/candle - name = "red candle" - desc = "In Greek myth, Prometheus stole fire from the Gods and gave it to humankind. The jewelry he kept for himself." - icon = 'icons/obj/candle.dmi' - icon_state = "candle1" - item_state = "candle1" - w_class = WEIGHT_CLASS_TINY - var/wax = 200 - /// Index for the icon state - var/wax_index = TALL_CANDLE - var/lit = FALSE - var/infinite = FALSE - var/start_lit = FALSE - var/flickering = FALSE - light_color = "#E09D37" - -/obj/item/candle/New() - ..() - if(start_lit) - // No visible message - light(show_message = 0) - -/obj/item/candle/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/candle/update_icon_state() - if(flickering) - icon_state = "candle[wax_index]_flicker" - else - icon_state = "candle[wax_index][lit ? "_lit" : ""]" - -/obj/item/candle/can_enter_storage(obj/item/storage/S, mob/user) - if(lit) - to_chat(user, "[S] can't hold [src] while it's lit!") - return FALSE - else - return TRUE - -/obj/item/candle/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(W.get_heat()) - light("[user] lights [src] with [W].") - return - return ..() - -/obj/item/candle/welder_act(mob/user, obj/item/I) - . = TRUE - if(I.tool_use_check(user, 0)) //Don't need to flash eyes because you are a badass - light("[user] casually lights [src] with [I], what a badass.") - -/obj/item/candle/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - if(!lit) - light() //honk - return ..() - -/obj/item/candle/proc/light(show_message) - if(!lit) - lit = TRUE - if(show_message) - usr.visible_message(show_message) - set_light(CANDLE_LUM) - START_PROCESSING(SSobj, src) - update_icon(UPDATE_ICON_STATE) - -/obj/item/candle/proc/update_wax_index() - var/new_wax_index - if(wax > 150) - new_wax_index = TALL_CANDLE - else if(wax > 80) - new_wax_index = MID_CANDLE - else - new_wax_index = SHORT_CANDLE - if(wax_index != new_wax_index) - wax_index = new_wax_index - return TRUE - return FALSE - -/obj/item/candle/proc/start_flickering() - flickering = TRUE - update_icon(UPDATE_ICON_STATE) - addtimer(CALLBACK(src, PROC_REF(stop_flickering)), 4 SECONDS, TIMER_UNIQUE) - -/obj/item/candle/proc/stop_flickering() - flickering = FALSE - update_icon(UPDATE_ICON_STATE) - -/obj/item/candle/process() - if(!lit) - return - if(!infinite) - wax-- - if(wax_index != SHORT_CANDLE) // It's not at its shortest - if(update_wax_index()) - update_icon(UPDATE_ICON_STATE) - if(!wax) - new/obj/item/trash/candle(src.loc) - if(ismob(src.loc)) - var/mob/M = src.loc - M.drop_item_to_ground(src, force = TRUE) //src is being deleted anyway - qdel(src) - if(isturf(loc)) //start a fire if possible - var/turf/T = loc - T.hotspot_expose(700, 1) - -/obj/item/candle/proc/unlight() - if(lit) - lit = FALSE - update_icon(UPDATE_ICON_STATE) - set_light(0) - - -/obj/item/candle/attack_self__legacy__attackchain(mob/user) - if(lit) - user.visible_message("[user] snuffs out [src].") - unlight() - -/obj/item/candle/lit - start_lit = TRUE - -/obj/item/candle/eternal - desc = "A candle. This one seems to have an odd quality about the wax." - infinite = TRUE - -/obj/item/candle/eternal/lit - start_lit = TRUE - -/obj/item/candle/get_spooked() - if(lit) - start_flickering() - playsound(src, 'sound/effects/candle_flicker.ogg', 15, 1) - return TRUE - - return FALSE - -/obj/item/candle/eternal/wizard - desc = "A candle. It smells like magic, so that would explain why it burns brighter." - start_lit = TRUE - -/obj/item/candle/eternal/wizard/attack_self__legacy__attackchain(mob/user) - return - -/obj/item/candle/eternal/wizard/process() - return - -/obj/item/candle/eternal/wizard/light(show_message) - . = ..() - if(lit) - set_light(CANDLE_LUM * 2) - - -/obj/item/candle/extinguish_light(force) - if(!force) - return - infinite = FALSE - wax = 1 // next process will burn it out - -/obj/item/candle/get_heat() - return lit * 1000 - -#undef TALL_CANDLE -#undef MID_CANDLE -#undef SHORT_CANDLE diff --git a/code/game/objects/items/cardboard_cutouts.dm b/code/game/objects/items/cardboard_cutouts.dm deleted file mode 100644 index 25264a60be777..0000000000000 --- a/code/game/objects/items/cardboard_cutouts.dm +++ /dev/null @@ -1,222 +0,0 @@ -//Cardboard cutouts! They're man-shaped and can be colored with a crayon to look like a human in a certain outfit, although it's limited, discolored, and obvious to more than a cursory glance. -/obj/item/cardboard_cutout - name = "cardboard cutout" - desc = "A vaguely humanoid cardboard cutout. It's completely blank." - icon = 'icons/obj/cardboard_cutout.dmi' - icon_state = "cutout_basic" - resistance_flags = FLAMMABLE - w_class = WEIGHT_CLASS_BULKY - var/list/possible_appearances = list("Assistant", "Female", "Clown", "Mime", - "Traitor", "Nuke Op", "Cultist", "Revolutionary", "Wizard", "Shadowling", "Xenomorph", "Swarmer", - "Deathsquad Commando", "Ian", "Slaughter Demon", - "Laughter Demon", "Xenomorph Maid", "Security Officer", "Terror Spider", - "Changeling", "Vampire", "Abductor", "Zombie", "Soviet Marine", "Federation Marine") - /// If the cutout is pushed over and has to be righted - var/pushed_over = FALSE - /// If the cutout actually appears as what it portray and not a discolored version - var/deceptive = FALSE - var/lastattacker = null - -/obj/item/cardboard_cutout/attack_hand(mob/living/user) - if(user.a_intent == INTENT_HELP || pushed_over) - return ..() - user.visible_message("[user] pushes over [src]!", "You push over [src]!") - playsound(src, 'sound/weapons/genhit.ogg', 50, 1) - push_over() - -/obj/item/cardboard_cutout/proc/push_over() - name = initial(name) - desc = "[initial(desc)] It's been pushed over." - icon = initial(icon) - icon_state = "cutout_pushed_over" - color = initial(color) - alpha = initial(alpha) - pushed_over = TRUE - -/obj/item/cardboard_cutout/attack_self__legacy__attackchain(mob/living/user) - if(!pushed_over) - return - to_chat(user, "You right [src].") - desc = initial(desc) - icon = initial(icon) - icon_state = initial(icon_state) //This resets a cutout to its blank state - this is intentional to allow for resetting - pushed_over = FALSE - -/obj/item/cardboard_cutout/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) - if(istype(I, /obj/item/toy/crayon)) - change_appearance(I, user) - return - // Why yes, this does closely resemble mob and object attack code. - if(I.flags & NOBLUDGEON) - return - if(!I.force) - playsound(loc, 'sound/weapons/tap.ogg', 20, TRUE, -1) - else if(I.hitsound) - playsound(loc, I.hitsound, 20, TRUE, -1) - - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) - - if(I.force) - user.visible_message("[user] has hit \ - [src] with [I]!", "You hit [src] \ - with [I]!") - - if(prob(I.force)) - push_over() - -/obj/item/cardboard_cutout/bullet_act(obj/item/projectile/P) - visible_message("[src] is hit by [P]!") - playsound(src, 'sound/weapons/slice.ogg', 50, 1) - if(prob(P.damage)) - push_over() - -/obj/item/cardboard_cutout/proc/change_appearance(obj/item/toy/crayon/crayon, mob/living/user) - if(!crayon || !user) - return - if(istype(crayon, /obj/item/toy/crayon/spraycan)) - var/obj/item/toy/crayon/spraycan/can = crayon - if(can.capped) - to_chat(user, "The cap is on the spray can remove it first!") - return - if(pushed_over) - to_chat(user, "Right [src] first!") - return - var/new_appearance = tgui_input_list(user, "Choose a new appearance for [src]", "26th Century Deception", possible_appearances) - if(!Adjacent(usr)) - user.visible_message("You need to be closer!") - return - if(pushed_over) - to_chat(user, "Right [src] first!") - return - if(!new_appearance || !crayon) - return - if(!do_after(user, 10, FALSE, src, TRUE)) - return - user.visible_message("[user] gives [src] a new look.", "Voila! You give [src] a new look.") - alpha = 255 - icon = initial(icon) - if(!deceptive) - color = "#FFD7A7" - switch(new_appearance) - if("Assistant") - name = "[pick(GLOB.first_names_male)] [pick(GLOB.last_names)]" - desc = "A cardboard cutout of an assistant." - icon_state = "cutout_greytide" - if("Female") - name = "[pick(GLOB.first_names_female)] [pick(GLOB.last_names)]" - desc = "A cardboard cutout of a female assistant." - icon_state = "cutout_female" - if("Clown") - name = pick(GLOB.clown_names) - desc = "A cardboard cutout of a clown. You get the feeling that it should be in a corner." - icon_state = "cutout_clown" - if("Mime") - name = pick(GLOB.mime_names) - desc = "...(A cardboard cutout of a mime.)" - icon_state = "cutout_mime" - if("Traitor") - name = "[pick("Unknown", "Captain")]" - desc = "A cardboard cutout of a traitor." - icon_state = "cutout_traitor" - if("Nuke Op") - name = "[pick("Unknown", "COMMS", "Telecomms", "AI", "stealthy op", "STEALTH", "sneakybeaky", "MEDIC", "Medic", "Gonk op")]" - desc = "A cardboard cutout of a nuclear operative." - icon_state = "cutout_fluke" - if("Cultist") - name = "Unknown" - desc = "A cardboard cutout of a cultist." - icon_state = "cutout_cultist" - if("Revolutionary") - name = "Unknown" - desc = "A cardboard cutout of a revolutionary." - icon_state = "cutout_viva" - if("Wizard") - name = "[pick(GLOB.wizard_first)], [pick(GLOB.wizard_second)]" - desc = "A cardboard cutout of a wizard." - icon_state = "cutout_wizard" - if("Shadowling") - name = "Unknown" - desc = "A cardboard cutout of a shadowling." - icon_state = "cutout_shadowling" - if("Xenomorph") - name = "alien hunter ([rand(1, 999)])" - desc = "A cardboard cutout of a xenomorph." - icon_state = "cutout_fukken_xeno" - if(prob(10)) - alpha = 75 //Spooky sneaking! - if("Swarmer") - name = "Swarmer ([rand(1, 999)])" - desc = "A cardboard cutout of a swarmer." - icon_state = "cutout_swarmer" - //if("Ash Walker") - // name = random_name(pick(MALE,FEMALE),"Unathi") - // desc = "A cardboard cutout of an ash walker." - // icon_state = "cutout_free_antag" - if("Deathsquad Commando") - name = pick(GLOB.deathsquad_names) - desc = "A cardboard cutout of a Deathsquad Commando, from that show about loose-cannon ERT Officers." - icon_state = "cutout_deathsquad" - if("Ian") - name = "Ian" - desc = "A cardboard cutout of the HoP's beloved corgi." - icon_state = "cutout_ian" - if("Slaughter Demon") - name = "slaughter demon" - desc = "A cardboard cutout of a slaughter demon." - icon = 'icons/mob/mob.dmi' - icon_state = "daemon" - dir = "SOUTH" - if("Laughter Demon") - name = "laughter demon" - desc = "A cardboard cutout of a laughter demon." - icon = 'icons/mob/mob.dmi' - icon_state = "bowmon" - dir = "SOUTH" - if("Xenomorph Maid") - name = "lusty xenomorph maid ([rand(1, 999)])" - desc = "A cardboard cutout of a xenomorph maid." - icon_state = "cutout_lusty" - if("Security Officer") - name = "Private Security Officer" - desc = "A cardboard cutout of a private security officer." - icon_state = "cutout_ntsec" - if("Terror Spider") - name = "Gray Terror Spider" - desc = "A cardboard cutout of a terror spider." - icon = 'icons/mob/terrorspider.dmi' - icon_state = "terror_gray" - dir = "SOUTH" - if("Soviet Marine") - name = "[pick(GLOB.first_names_soviet)] [pick(GLOB.last_names_soviet)]" - desc = "A cardboard cutout of a soviet marine." - icon_state = "cutout_soviet" - if("Federation Marine") - name = "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(GLOB.last_names)]" - desc = "A cardboard cutout of a federation marine." - icon_state = "cutout_sol" - if("Changeling") - name = "[pick(GLOB.first_names_male)] [pick(GLOB.last_names)]" - desc = "A cardboard cutout of a changeling." - icon_state = "cutout_cling" - if("Abductor") - name = "Unknown" - desc = "A cardboard cutout of an abductor." - icon_state = "cutout_abductor" - if("Zombie") - name = "[pick(GLOB.first_names_male)] [pick(GLOB.last_names)]" - desc = "A cardboard cutout of a zombie." - icon_state = "cutout_zombie" - if("Vampire") - name = "Unknown" - desc = "A cardboard cutout of a vampire." - icon_state = "cutout_vampire" - - return 1 - -/obj/item/cardboard_cutout/setDir() - dir = SOUTH - -/// Purchased by Syndicate agents, these cutouts are indistinguishable from normal cutouts but aren't discolored when their appearance is changed -/obj/item/cardboard_cutout/adaptive - deceptive = TRUE diff --git a/code/game/objects/items/collar.dm b/code/game/objects/items/collar.dm deleted file mode 100644 index 9bb839442c820..0000000000000 --- a/code/game/objects/items/collar.dm +++ /dev/null @@ -1,77 +0,0 @@ -/obj/item/petcollar - name = "pet collar" - desc = "The latest fashion accessory for your favorite pets!" - icon_state = "petcollar" - item_color = "petcollar" - var/tagname = null - var/obj/item/card/id/access_id - -/obj/item/petcollar/Destroy() - QDEL_NULL(access_id) - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/petcollar/attack_self__legacy__attackchain(mob/user) - var/option = "Change Name" - if(access_id) - option = tgui_input_list(user, "What do you want to do?", "[src]", list("Change Name", "Remove ID")) - if(QDELETED(src) || !Adjacent(user)) - return - switch(option) - if("Change Name") - var/petname = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text - if(petname && !QDELETED(src) && Adjacent(user)) - tagname = copytext(sanitize(petname), 1, MAX_NAME_LEN) - name = "[initial(name)] - [tagname]" - if("Remove ID") - if(access_id) - user.visible_message("[user] starts unclipping [access_id] from [src].") - if(do_after(user, 5 SECONDS, target = user) && access_id && !QDELETED(src) && Adjacent(user)) - user.visible_message("[user] unclips [access_id] from [src].") - access_id.forceMove(get_turf(user)) - user.put_in_hands(access_id) - access_id = null - -/obj/item/petcollar/attackby__legacy__attackchain(obj/item/card/id/W, mob/user, params) - if(!istype(W)) - return ..() - if(access_id) - to_chat(user, "There is already \a [access_id] clipped onto [src].") - return ..() - user.drop_item() - W.forceMove(src) - access_id = W - to_chat(user, "[W] clips onto [src] snugly.") - -/obj/item/petcollar/GetAccess() - return access_id ? access_id.GetAccess() : ..() - -/obj/item/petcollar/examine(mob/user) - . = ..() - if(access_id) - . += "There is [bicon(access_id)] \a [access_id] clipped onto it." - -/obj/item/petcollar/equipped(mob/living/simple_animal/user) - if(istype(user)) - START_PROCESSING(SSobj, src) - -/obj/item/petcollar/dropped(mob/living/simple_animal/user) - ..() - STOP_PROCESSING(SSobj, src) - -/obj/item/petcollar/process() - var/mob/living/simple_animal/M = loc - // if it wasn't intentionally unequipped but isn't being worn, possibly gibbed - if(istype(M) && src == M.pcollar && M.stat != DEAD) - return - - var/area/pet_death_area = get_area(M) - var/obj/item/radio/headset/pet_death_announcer = new /obj/item/radio/headset(src) - pet_death_announcer.follow_target = src - if(istype(pet_death_area, /area/syndicate_mothership) || istype(pet_death_area, /area/shuttle/syndicate_elite)) - //give the syndicats a bit of stealth - pet_death_announcer.autosay("[M] has been vandalized in Space!", "[M]'s Death Alarm") - else - pet_death_announcer.autosay("[M] has been vandalized in [pet_death_area.name]!", "[M]'s Death Alarm") - qdel(pet_death_announcer) - STOP_PROCESSING(SSobj, src) diff --git a/code/game/objects/items/dehy_carp.dm b/code/game/objects/items/dehy_carp.dm deleted file mode 100644 index 8638ee8335dd0..0000000000000 --- a/code/game/objects/items/dehy_carp.dm +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Dehydrated Carp - * Instant carp, just add water - */ - -// Child of carpplushie because this should do everything the toy does and more -/obj/item/toy/plushie/carpplushie/dehy_carp - var/mob/owner = null // Carp doesn't attack owner, set when using in hand - var/owned = 1 // Boolean, no owner to begin with - - -/obj/item/toy/plushie/carpplushie/dehy_carp/Destroy() - owner = null - return ..() - -// Attack self -/obj/item/toy/plushie/carpplushie/dehy_carp/activate_self(mob/user) - if(..()) - return - src.add_fingerprint(user) // Anyone can add their fingerprints to it with this - if(owned) - to_chat(user, "[src] stares up at you with friendly eyes.") - owner = user - owned = 0 - return ..() - -/obj/item/toy/plushie/carpplushie/dehy_carp/water_act(volume, temperature, source, method = REAGENT_TOUCH) - . = ..() - if(volume >= 1) - Swell() - -/obj/item/toy/plushie/carpplushie/dehy_carp/after_attack(atom/target, mob/user, proximity_flag, click_parameters) - . = ..() - if(!proximity_flag) - return - if(istype(target,/obj/structure/sink)) - to_chat(user, "You place [src] under a stream of water...") - user.drop_item() - loc = get_turf(target) - return Swell() - -/obj/item/toy/plushie/carpplushie/dehy_carp/proc/Swell() - desc = "It's growing!" - visible_message("[src] swells up!") - // Animation - icon = 'icons/mob/carp.dmi' - flick("carp_swell", src) - // Wait for animation to end - addtimer(CALLBACK(src, PROC_REF(make_carp)), 6) - -/obj/item/toy/plushie/carpplushie/dehy_carp/proc/make_carp() - // Make space carp - var/mob/living/simple_animal/hostile/carp/C = new /mob/living/simple_animal/hostile/carp(get_turf(src)) - // Make carp non-hostile to user, yes this means - C.faction |= list("syndicate", "\ref[owner]") - qdel(src) diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm deleted file mode 100644 index 6f66fa335ef76..0000000000000 --- a/code/game/objects/items/devices/aicard.dm +++ /dev/null @@ -1,160 +0,0 @@ -/obj/item/aicard - name = "inteliCard" - desc = "A handy pocket card used to extract an artificial intelligence for transport." - icon = 'icons/obj/aicards.dmi' - icon_state = "aicard" // aicard-full - item_state = "electronic" - w_class = WEIGHT_CLASS_SMALL - slot_flags = ITEM_SLOT_BELT - flags = NOBLUDGEON - var/flush = null - origin_tech = "programming=3;materials=3" - -/obj/item/aicard/afterattack__legacy__attackchain(atom/target, mob/user, proximity) - ..() - if(!proximity || !target) - return - var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src - if(AI) //AI is on the card, implies user wants to upload it. - target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src) - add_attack_logs(user, AI, "Carded with [src]") - else //No AI on the card, therefore the user wants to download one. - target.transfer_ai(AI_TRANS_TO_CARD, user, null, src) - update_state() //Whatever happened, update the card's state (icon, name) to match. - -/obj/item/aicard/proc/update_state() - var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src //AI is inside. - update_icon(UPDATE_OVERLAYS) - if(AI) - name = "intelliCard - [AI.name]" - AI.cancel_camera() //AI are forced to move when transferred, so do this whenver one is downloaded. - else - name = "intelliCard" - -/obj/item/aicard/update_overlays() - . = ..() - var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src //AI is inside. - if(AI) - var/list/aicard_icon_state_names = icon_states(icon) - var/aicard_new_display = AI.icon_state - - if(aicard_new_display in aicard_icon_state_names) - . += aicard_new_display - else if(AI.stat == DEAD) - . += "ai_dead" - else - . += "ai" - -/obj/item/aicard/attack_self__legacy__attackchain(mob/user) - ui_interact(user) - -/obj/item/aicard/ui_state(mob/user) - return GLOB.inventory_state - -/obj/item/aicard/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "AICard", "[name]") - ui.open() - -/obj/item/aicard/ui_data(mob/user) - var/list/data = list() - - var/mob/living/silicon/ai/AI = locate() in src - if(istype(AI)) - data["has_ai"] = TRUE - data["name"] = AI.name - data["integrity"] = ((AI.health + 100) / 2) - data["radio"] = !AI.aiRadio.disabledAi - data["wireless"] = !AI.control_disabled - data["operational"] = AI.stat != DEAD - data["flushing"] = flush - - var/laws[0] - for(var/datum/ai_law/law in AI.laws.all_laws()) - if(law in AI.laws.ion_laws) // If we're an ion law, give it an ion index code - laws.Add(ionnum() + ". " + law.law) - else - laws.Add(num2text(law.get_index()) + ". " + law.law) - data["laws"] = laws - data["has_laws"] = length(AI.laws.all_laws()) - - else - data["has_ai"] = FALSE // If this isn't passed to tgui, it won't show there isn't a AI in the card. - - return data - -/obj/item/aicard/ui_act(action, params) - if(..()) - return - - var/mob/living/silicon/ai/AI = locate() in src - if(!istype(AI)) - return - - var/user = usr - switch(action) - if("wipe") - if(flush) // Don't doublewipe. - to_chat(user, "You are already wiping this AI!") - return - var/confirm = tgui_alert(user, "Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", list("Yes", "No")) - if(confirm == "Yes" && (ui_status(user, GLOB.inventory_state) == UI_INTERACTIVE)) // And make doubly sure they want to wipe (three total clicks) - msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].", ATKLOG_FEW) - add_attack_logs(user, AI, "Wiped with [src].") - INVOKE_ASYNC(src, PROC_REF(wipe_ai)) - - if("radio") - AI.aiRadio.disabledAi = !AI.aiRadio.disabledAi - to_chat(AI, "Your Subspace Transceiver has been [AI.aiRadio.disabledAi ? "disabled" : "enabled"]!") - to_chat(user, "You [AI.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.") - - if("wireless") - AI.control_disabled = !AI.control_disabled - to_chat(AI, "Your wireless interface has been [AI.control_disabled ? "disabled" : "enabled"]!") - to_chat(user, "You [AI.control_disabled ? "disable" : "enable"] the AI's wireless interface.") - update_icon() - - return TRUE - -/obj/item/aicard/examine(mob/user) - . = ..() - var/mob/living/silicon/ai/AI = locate() in src - if(!AI) - return - - if(!GetComponent(/datum/component/ducttape) && AI.builtInCamera) - . += "You see a small [AI]'s camera staring at you." - . += "You can use a tape roll on [src] to tape the camera lens." - -/obj/item/aicard/proc/wipe_ai() - var/mob/living/silicon/ai/AI = locate() in src - flush = TRUE - AI.suiciding = TRUE - to_chat(AI, "Your core files are being wiped!") - while(AI && AI.stat != DEAD) - AI.adjustOxyLoss(2) - sleep(10) - flush = FALSE - -/obj/item/aicard/add_tape() - var/mob/living/silicon/ai/AI = locate() in src - if(!AI) - return - - if(AI.cracked_camera) - return // we dont crack camera if its already cracked - - QDEL_NULL(AI.builtInCamera) - -/obj/item/aicard/remove_tape() - var/mob/living/silicon/ai/AI = locate() in src - if(!AI) - return - - if(AI.cracked_camera) - return // we dont fix camera if malf AI cracked it - - AI.builtInCamera = new /obj/machinery/camera/portable(AI) - AI.builtInCamera.c_tag = AI.name - AI.builtInCamera.network = list("SS13") diff --git a/code/game/objects/items/devices/autopsy.dm b/code/game/objects/items/devices/autopsy.dm deleted file mode 100644 index 95103656f6154..0000000000000 --- a/code/game/objects/items/devices/autopsy.dm +++ /dev/null @@ -1,184 +0,0 @@ -/obj/item/autopsy_scanner - name = "autopsy scanner" - desc = "Extracts information on wounds." - icon = 'icons/obj/surgery.dmi' - icon_state = "autopsy_scanner" - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - w_class = WEIGHT_CLASS_SMALL - origin_tech = "magnets=1;biotech=1" - var/list/datum/autopsy_data_scanner/wdata = list() - var/list/chemtraces = list() - var/target_name = null - var/target_UID = null - var/timeofdeath = null - var/target_rank = null - -/obj/item/autopsy_scanner/Destroy() - QDEL_LIST_ASSOC_VAL(wdata) - return ..() - -/datum/autopsy_data_scanner - var/weapon = null // this is the DEFINITE weapon type that was used - var/list/organs_scanned = list() // this maps a number of scanned organs to - // the wounds to those organs with this data's weapon type - var/organ_names = "" - -/datum/autopsy_data_scanner/Destroy() - QDEL_LIST_ASSOC_VAL(organs_scanned) - return ..() - -/datum/autopsy_data - var/weapon = null - var/damage = 0 - var/hits = 0 - var/time_inflicted = 0 - -/datum/autopsy_data/proc/copy() - var/datum/autopsy_data/W = new() - W.weapon = weapon - W.damage = damage - W.hits = hits - W.time_inflicted = time_inflicted - return W - -/obj/item/autopsy_scanner/proc/add_data(obj/item/organ/O) - if(length(O.autopsy_data)) - for(var/V in O.autopsy_data) - var/datum/autopsy_data/W = O.autopsy_data[V] - - var/datum/autopsy_data_scanner/D = wdata[V] - if(!D) - D = new() - D.weapon = W.weapon - wdata[V] = D - - if(!D.organs_scanned[O.name]) - if(D.organ_names == "") - D.organ_names = O.name - else - D.organ_names += ", [O.name]" - - qdel(D.organs_scanned[O.name]) - D.organs_scanned[O.name] = W.copy() - - if(length(O.trace_chemicals)) - for(var/V in O.trace_chemicals) - if(O.trace_chemicals[V] > 0 && !chemtraces.Find(V)) - chemtraces += V - -/obj/item/autopsy_scanner/examine(mob/user) - . = ..() - if(Adjacent(user)) - . += "You can use a pen on it to quickly write a coroner's report." - -/obj/item/autopsy_scanner/attackby__legacy__attackchain(obj/item/P, mob/user) - if(!is_pen(P)) - return ..() - - var/dead_name = tgui_input_text(user, "Insert name of deceased individual", default = target_name, title = "Coroner's Report", max_length = 60) - var/rank = tgui_input_text(user, "Insert rank of deceased individual", default = target_rank, title = "Coroner's Report", max_length = 60) - var/tod = tgui_input_text(user, "Insert time of death", default = station_time_timestamp("hh:mm", timeofdeath), title = "Coroner's Report", max_length = 60) - var/cause = tgui_input_text(user, "Insert cause of death", title = "Coroner's Report", max_length = 60) - var/chems = tgui_input_text(user, "Insert any chemical traces", multiline = TRUE, title = "Coroner's Report") - var/notes = tgui_input_text(user, "Insert any relevant notes", multiline = TRUE, title = "Coroner's Report") - var/obj/item/paper/R = new(user.loc) - R.name = "Official Coroner's Report - [dead_name]" - R.info = "
    [station_name()] - Coroner's Report


    Name of Deceased: [dead_name]

    Rank of Deceased: [rank]

    Time of Death: [tod]

    Cause of Death: [cause]

    Trace Chemicals: [chems]

    Additional Coroner's Notes: [notes]

    Coroner's Signature: " - playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, TRUE) - user.put_in_hands(R) - -/obj/item/autopsy_scanner/attack_self__legacy__attackchain(mob/user) - var/scan_data = "" - - if(timeofdeath) - scan_data += "Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]

    " - else - scan_data += "Time of death: Unknown / Still alive

    " - - if(length(wdata)) - var/n = 1 - for(var/wdata_idx in wdata) - var/datum/autopsy_data_scanner/D = wdata[wdata_idx] - var/total_hits = 0 - var/total_score = 0 - var/age = 0 - - for(var/wound_idx in D.organs_scanned) - var/datum/autopsy_data/W = D.organs_scanned[wound_idx] - total_hits += W.hits - total_score+=W.damage - - - var/wound_age = W.time_inflicted - age = max(age, wound_age) - - var/damage_desc - // total score happens to be the total damage - switch(total_score) - if(1 to 5) - damage_desc = "negligible" - if(5 to 15) - damage_desc = "light" - if(15 to 30) - damage_desc = "moderate" - if(30 to 1000) - damage_desc = "severe" - else - damage_desc = "Unknown" - - var/damaging_weapon = (total_score != 0) - scan_data += "Weapon #[n]
    " - if(damaging_weapon) - scan_data += "Severity: [damage_desc]
    " - scan_data += "Hits by weapon: [total_hits]
    " - scan_data += "Approximate time of wound infliction: [station_time_timestamp("hh:mm", age)]
    " - scan_data += "Affected limbs: [D.organ_names]
    " - scan_data += "Weapon: [D.weapon]
    " - scan_data += "
    " - - n++ - - if(length(chemtraces)) - scan_data += "Trace Chemicals:
    " - for(var/chemID in chemtraces) - scan_data += chemID - scan_data += "
    " - user.visible_message("[src] rattles and prints out a sheet of paper.") - - playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1) - sleep(10) - - var/obj/item/paper/P = new(user.loc) - P.name = "Autopsy Data ([target_name])" - P.info = "[scan_data]" - P.overlays += "paper_words" - - user.put_in_hands(P) - -/obj/item/autopsy_scanner/attack__legacy__attackchain(mob/living/carbon/human/M, mob/living/carbon/user) - if(!istype(M)) - return - - if(!on_operable_surface(M)) - return - - if(target_UID != M.UID()) - target_UID = M.UID() - target_name = M.name - target_rank = M.get_assignment(if_no_id = "Unknown", if_no_job = null) - wdata.Cut() - chemtraces.Cut() - timeofdeath = null - to_chat(user, "A new patient has been registered. Purging data for previous patient.") - - timeofdeath = M.timeofdeath - - var/obj/item/organ/external/S = M.get_organ(user.zone_selected) - if(!S) - to_chat(user, "You can't scan this body part.") - return - M.visible_message("[user] scans the wounds on [M]'s [S.name] with [src]") - - add_data(S) - return 1 diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm deleted file mode 100644 index 3663889b2e77a..0000000000000 --- a/code/game/objects/items/devices/camera_bug.dm +++ /dev/null @@ -1,132 +0,0 @@ -// This item just has an integrated camera console, which the data is "proxied" to -/obj/item/camera_bug - name = "camera bug" - desc = "For illicit snooping through the camera network." - icon = 'icons/obj/device.dmi' - icon_state = "camera_bug" - w_class = WEIGHT_CLASS_TINY - item_state = "camera_bug" - throw_speed = 4 - throw_range = 20 - origin_tech = "syndicate=1;engineering=3" - /// Integrated camera console to serve UI data - var/obj/machinery/computer/security/camera_bug/integrated_console - var/connections = 0 - -/obj/machinery/computer/security/camera_bug - name = "invasive camera utility" - desc = "How did this get here?! Please report this as a bug to github" - power_state = NO_POWER_USE - interact_offline = TRUE - silent_console = TRUE - -/obj/item/camera_bug/Initialize(mapload) - . = ..() - integrated_console = new(src) - integrated_console.parent = src - integrated_console.network = list("SS13", "camera_bug[UID()]") - GLOB.restricted_camera_networks += "camera_bug[UID()]" - -/obj/item/camera_bug/Destroy() - QDEL_NULL(integrated_console) - return ..() - -/obj/item/camera_bug/attack_self__legacy__attackchain(mob/user as mob) - ui_interact(user) - -/obj/item/camera_bug/ui_state(mob/user) - return GLOB.inventory_state - -/obj/item/camera_bug/ui_interact(mob/user, datum/tgui/ui = null) - integrated_console.ui_interact(user, ui) - - -/obj/item/camera_bug/ert - name = "\improper ERT Camera Monitor" - desc = "A small handheld device used by ERT commanders to view camera feeds remotely." - -/obj/item/camera_bug/ert/Initialize(mapload) - . = ..() - integrated_console.network = list("ERT") - -/obj/item/wall_bug - name = "small camera" - desc = "A camera with a sticky backside." - icon = 'icons/obj/device.dmi' - icon_state = "wall_bug" - w_class = WEIGHT_CLASS_TINY - var/obj/machinery/camera/portable/camera_bug/camera - var/index = "REPORT THIS TO CODERS" - /// What name shows up on the camera bug list - var/camera_tag = "Hidden Camera" - /// If it sticks to whatever you throw at it - var/is_sticky = TRUE - -/obj/item/wall_bug/Initialize(mapload, obj/item/camera_bug/the_bug) - . = ..() - link_to_camera(the_bug) - if(is_sticky) - AddComponent(/datum/component/sticky) - ADD_TRAIT(src, TRAIT_NO_THROWN_MESSAGE, ROUNDSTART_TRAIT) - -/obj/item/wall_bug/Destroy() - QDEL_NULL(camera) - return ..() - -/obj/item/wall_bug/examine(mob/user) - . = ..() - if(in_range(user, src)) - . += "It has a small label on it reading \"[index]\"." - -/obj/item/wall_bug/proc/link_to_camera(obj/item/camera_bug/camera_bug) - if(!istype(camera_bug)) - return - if(camera) // we can't link twice - return - camera_bug.connections++ - index = camera_bug.connections - - camera = new /obj/machinery/camera/portable/camera_bug(src) - camera.network = list("camera_bug[camera_bug.UID()]") - camera.c_tag = "[camera_tag] [index]" - -/// Created by a mindflayer ability -/obj/item/wall_bug/computer_bug - name = "nanobot" - desc = "A small droplet of a shimmering metallic slurry." - camera_tag = "Surveillance Unit" - is_sticky = FALSE - /// Reference to the creator's antag datum - var/datum/antagonist/mindflayer/flayer - COOLDOWN_DECLARE(alert_cooldown) - -/obj/item/wall_bug/computer_bug/Destroy() - flayer = null - return ..() - -/obj/item/wall_bug/computer_bug/link_to_camera(obj/item/camera_bug/camera_bug, datum/antagonist/mindflayer/flayer_datum) - ..() - if(flayer_datum) - flayer = flayer_datum - -/obj/machinery/camera/portable/camera_bug - non_chunking_camera = TRUE - -/obj/item/paper/camera_bug - name = "\improper Camera Bug Guide" - icon_state = "paper" - info = {"Instructions on your new invasive camera utility
    -
    - This camera bug can access all default cameras on the station, along with the hidden cameras provided in this kit.
    -
    - The cameras in this kit have a sticky backside, allowing you to attach them to literally anything, even people.
    -
    - You may remove the cameras from said objects by grabbing them with an empty hand.
    -
    - You can view these hidden cameras by looking up "Hidden Camera" on your camera bug.
    -
    - Only the camera bug provided in this kit can see these hidden cameras.
    -
    - Other Camera bugs cannot see your hidden cameras.
    -
    - There is no other way to get these hidden cameras, so make sure to not lose them!
    "} diff --git a/code/game/objects/items/devices/chameleon_counter.dm b/code/game/objects/items/devices/chameleon_counter.dm deleted file mode 100644 index e374cbd5eb13a..0000000000000 --- a/code/game/objects/items/devices/chameleon_counter.dm +++ /dev/null @@ -1,77 +0,0 @@ -/obj/item/chameleon_counterfeiter - name = "chameleon counterfeiter" - icon = 'icons/obj/device.dmi' - icon_state = "cham_counter" - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - item_state = "electronic" - w_class = WEIGHT_CLASS_SMALL - origin_tech = "syndicate=1;magnets=3" - var/can_use = TRUE - var/saved_name - var/saved_desc - var/saved_icon - var/saved_icon_state - var/saved_item_state - var/saved_overlays - var/saved_underlays - var/dummy_active = FALSE - -/obj/item/chameleon_counterfeiter/examine(mob/user) - . = ..() - if(dummy_active) - . += "It doesn't look quite right..." - -/obj/item/chameleon_counterfeiter/afterattack__legacy__attackchain(obj/item/target, mob/user, proximity) - if(!proximity || !check_sprite(target) || target.alpha < 255 || target.invisibility != 0) - return - if(dummy_active || !isitem(target)) - return - playsound(get_turf(src), 'sound/weapons/flash.ogg', 100, TRUE, -6) - to_chat(user, "Scanned [target].") - saved_name = target.name - saved_desc = target.desc - saved_icon = target.icon - saved_icon_state = target.icon_state - saved_item_state = target.item_state - saved_overlays = target.overlays - saved_underlays = target.underlays - -/obj/item/chameleon_counterfeiter/proc/check_sprite(atom/target) - return (target.icon_state in icon_states(target.icon)) - -/obj/item/chameleon_counterfeiter/proc/matter_toggle(mob/living/user) - if(!can_use || !saved_name) - return - playsound(get_turf(src), 'sound/effects/pop.ogg', 100, TRUE, -6) - if(dummy_active) - matter_deactivate() - to_chat(user, "You deactivate [src].") - else - to_chat(user, "You activate [src].") - matter_activate() - -/obj/item/chameleon_counterfeiter/proc/matter_activate() - name = saved_name - desc = saved_desc - icon = saved_icon - icon_state = saved_icon_state - item_state = saved_item_state - overlays = saved_overlays - underlays = saved_underlays - dummy_active = TRUE - -/obj/item/chameleon_counterfeiter/proc/matter_deactivate() - name = initial(name) - desc = initial(desc) - icon = initial(icon) - icon_state = initial(icon_state) - item_state = initial(item_state) - overlays = initial(overlays) - underlays = initial(underlays) - dummy_active = FALSE - can_use = FALSE - addtimer(VARSET_CALLBACK(src, can_use, TRUE), 3 SECONDS) - -/obj/item/chameleon_counterfeiter/attack_self__legacy__attackchain(mob/living/user) - matter_toggle(user) diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm deleted file mode 100644 index e10e4ed94a34c..0000000000000 --- a/code/game/objects/items/devices/chameleonproj.dm +++ /dev/null @@ -1,296 +0,0 @@ -/obj/item/chameleon - name = "chameleon projector" - icon = 'icons/obj/device.dmi' - icon_state = "shield0" - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - item_state = "electronic" - throwforce = 5 - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - origin_tech = "syndicate=4;magnets=4" - var/can_use = TRUE - var/obj/effect/dummy/chameleon/active_dummy = null - var/saved_item = /obj/item/cigbutt - var/saved_icon = 'icons/obj/clothing/masks.dmi' - var/saved_icon_state = "cigbutt" - var/saved_overlays = null - var/saved_underlays = null - -/obj/item/chameleon/dropped() - ..() - disrupt() - -/obj/item/chameleon/equipped() - disrupt() - -/obj/item/chameleon/attack_self__legacy__attackchain() - toggle() - -/obj/item/chameleon/afterattack__legacy__attackchain(atom/target, mob/user, proximity) - if(!proximity) - return - if(!check_sprite(target)) - return - if(target.alpha < 255) - return - if(target.invisibility != 0) - return - if(!active_dummy) - if(isitem(target) && !istype(target, /obj/item/disk/nuclear)) - playsound(get_turf(src), 'sound/weapons/flash.ogg', 100, TRUE, -6) - to_chat(user, "Scanned [target].") - saved_item = target.type - saved_icon = target.icon - saved_icon_state = target.icon_state - saved_overlays = target.overlays - saved_underlays = target.underlays - -/obj/item/chameleon/proc/check_sprite(atom/target) - return (target.icon_state in icon_states(target.icon)) - -/obj/item/chameleon/proc/toggle() - if(!can_use || !saved_item) - return - if(active_dummy) - eject_all() - playsound(get_turf(src), 'sound/effects/pop.ogg', 100, TRUE, -6) - QDEL_NULL(active_dummy) - to_chat(usr, "You deactivate [src].") - var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src)) - T.icon = 'icons/effects/effects.dmi' - flick("emppulse",T) - spawn(8) - qdel(T) - else - playsound(get_turf(src), 'sound/effects/pop.ogg', 100, TRUE, -6) - var/obj/O = new saved_item(src) - if(!O) - return - var/obj/effect/dummy/chameleon/C = new/obj/effect/dummy/chameleon(usr.loc) - C.activate(O, usr, saved_icon, saved_icon_state, saved_overlays, saved_underlays, src) - qdel(O) - to_chat(usr, "You activate [src].") - var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src)) - T.icon = 'icons/effects/effects.dmi' - flick("emppulse",T) - spawn(8) - qdel(T) - -/obj/item/chameleon/proc/disrupt(delete_dummy = 1) - if(active_dummy) - do_sparks(5, 0, src) - eject_all() - if(delete_dummy) - qdel(active_dummy) - active_dummy = null - can_use = FALSE - addtimer(VARSET_CALLBACK(src, can_use, TRUE), 5 SECONDS) - -/obj/item/chameleon/proc/eject_all() - for(var/atom/movable/A in active_dummy) - A.forceMove(active_dummy.loc) - -/obj/effect/dummy/chameleon - name = "" - desc = "" - resistance_flags = INDESTRUCTIBLE | FREEZE_PROOF - density = FALSE - anchored = TRUE - var/can_move = TRUE - var/obj/item/chameleon/master = null - -/obj/effect/dummy/chameleon/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_EFFECT_CAN_TELEPORT, ROUNDSTART_TRAIT) - -/obj/effect/dummy/chameleon/proc/activate(obj/O, mob/M, new_icon, new_iconstate, new_overlays, new_underlays, obj/item/chameleon/C) - name = O.name - desc = O.desc - icon = new_icon - icon_state = new_iconstate - overlays = new_overlays - underlays = new_underlays - dir = O.dir - M.forceMove(src) - master = C - master.active_dummy = src - -/obj/effect/dummy/chameleon/attackby__legacy__attackchain() - for(var/mob/M in src) - to_chat(M, "Your [src] deactivates.") - master.disrupt() - -/obj/effect/dummy/chameleon/attack_hand() - for(var/mob/M in src) - to_chat(M, "Your [src] deactivates.") - master.disrupt() - -/obj/effect/dummy/chameleon/attack_animal() - master.disrupt() - -/obj/effect/dummy/chameleon/attack_slime() - master.disrupt() - -/obj/effect/dummy/chameleon/attack_alien() - master.disrupt() - -/obj/effect/dummy/chameleon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay) - master.disrupt() // things like plasmafires, lava, bonfires will disrupt it - -/obj/effect/dummy/chameleon/acid_act() - master.disrupt() - -/obj/effect/dummy/chameleon/ex_act(severity) //no longer bomb-proof - for(var/mob/M in src) - to_chat(M, "Your [src] deactivates.") - spawn() - M.ex_act(severity) - master.disrupt() - -/obj/effect/dummy/chameleon/bullet_act() - for(var/mob/M in src) - to_chat(M, "Your [src] deactivates.") - ..() - master.disrupt() - -/obj/effect/dummy/chameleon/relaymove(mob/user, direction) - if(!isturf(loc) || isspaceturf(loc) || !direction) - return // No magical movement! - - if(can_move) - can_move = FALSE - switch(user.bodytemperature) - if(300 to INFINITY) - addtimer(VARSET_CALLBACK(src, can_move, TRUE), 1 SECONDS) - if(295 to 300) - addtimer(VARSET_CALLBACK(src, can_move, TRUE), 1.3 SECONDS) - if(280 to 295) - addtimer(VARSET_CALLBACK(src, can_move, TRUE), 1.6 SECONDS) - if(260 to 280) - addtimer(VARSET_CALLBACK(src, can_move, TRUE), 2 SECONDS) - else - addtimer(VARSET_CALLBACK(src, can_move, TRUE), 2.5 SECONDS) - step(src, direction) - return - -/obj/effect/dummy/chameleon/Destroy() - master.disrupt(0) - return ..() - -/obj/item/borg_chameleon - name = "cyborg chameleon projector" - icon = 'icons/obj/device.dmi' - icon_state = "shield0" - item_state = "electronic" - w_class = WEIGHT_CLASS_SMALL - var/active = FALSE - var/activationCost = 300 - var/activationUpkeep = 50 - var/image/disguise - var/mob/living/silicon/robot/syndicate/saboteur/S - -/obj/item/borg_chameleon/Destroy() - if(S) - S.cham_proj = null - return ..() - -/obj/item/borg_chameleon/dropped(mob/user) - . = ..() - disrupt(user) - -/obj/item/borg_chameleon/equipped(mob/user) - . = ..() - disrupt(user) - -/obj/item/borg_chameleon/attack_self__legacy__attackchain(mob/living/silicon/robot/syndicate/saboteur/user) - if(user && user.cell && user.cell.charge > activationCost) - if(isturf(user.loc)) - toggle(user) - else - to_chat(user, "You can't use [src] while inside something!") - else - to_chat(user, "You need at least [activationCost] charge in your cell to use [src]!") - -/obj/item/borg_chameleon/proc/toggle(mob/living/silicon/robot/syndicate/saboteur/user) - if(active) - to_chat(user, "You reconfigure [src].") - activate(user) - return - to_chat(user, "You activate [src].") - apply_wibbly_filters(user) - if(do_after(user, 5 SECONDS, target = user) && user.cell.use(activationCost)) - activate(user) - else - to_chat(user, "The chameleon field fizzles.") - do_sparks(3, FALSE, user) - remove_wibbly_filters(user) - -/obj/item/borg_chameleon/process() - if(S) - if(!S.cell || !S.cell.use(activationUpkeep)) - disrupt(S) - return - return PROCESS_KILL - -/obj/item/borg_chameleon/proc/activate(mob/living/silicon/robot/syndicate/saboteur/user) - var/static/list/module_options = list( - "Engineering" = image('icons/mob/robots.dmi', "engi-radial"), - "Janitor" = image('icons/mob/robots.dmi', "jan-radial"), - "Medical" = image('icons/mob/robots.dmi', "med-radial"), - "Mining" = image('icons/mob/robots.dmi', "mining-radial"), - "Service" = image('icons/mob/robots.dmi', "serv-radial"), - "Cancel Cloaking" = image('icons/mob/screen_gen.dmi', "x")) - var/selected_module = show_radial_menu(user, user, module_options, radius = 42) - if(!selected_module) - return - var/examine_text = "you shouldn't see this" - switch(selected_module) - if("Mining") - examine_text = "miner robot module" - if("Service") - examine_text = "service robot module" - if("Medical") - examine_text = "medical robot module" - if("Janitor") - examine_text = "janitorial robot module" - if("Engineering") - examine_text = "engineering robot module" - if("Cancel Cloaking") - deactivate(user) - return - var/module_sprites = user.get_module_sprites(selected_module) - var/selected_sprite = show_radial_menu(user, user, module_sprites, radius = 42) - if(!selected_sprite) - return - disguise = module_sprites[selected_sprite] - var/list/name_check = splittext(selected_sprite, "-") - user.custom_panel = trim(name_check[1]) - START_PROCESSING(SSobj, src) - S = user - user.icon = disguise.icon - user.icon_state = disguise.icon_state - user.cham_proj = src - user.module.name = examine_text - user.bubble_icon = "robot" - active = TRUE - user.update_icons() - playsound(src, 'sound/effects/bamf.ogg', 100, TRUE, -6) - to_chat(user, "You are now disguised as a Nanotrasen [selected_module] cyborg.") - -/obj/item/borg_chameleon/proc/deactivate(mob/living/silicon/robot/syndicate/saboteur/user) - STOP_PROCESSING(SSobj, src) - S = user - user.icon = initial(user.icon) - user.icon_state = initial(user.icon_state) - user.module.name = initial(user.module.name) - user.bubble_icon = "syndibot" - user.custom_panel = null - active = FALSE - user.update_icons() - -/obj/item/borg_chameleon/proc/disrupt(mob/living/silicon/robot/syndicate/saboteur/user) - if(active) - to_chat(user, "Your chameleon field deactivates.") - deactivate(user) diff --git a/code/game/objects/items/devices/enginepicker.dm b/code/game/objects/items/devices/enginepicker.dm deleted file mode 100644 index 304a973e65a27..0000000000000 --- a/code/game/objects/items/devices/enginepicker.dm +++ /dev/null @@ -1,98 +0,0 @@ -/* -////////// - Item meant to spawn one of the three (Tesla / Singularity / Supermatter) engines on-station at round-start. - Should be found in the CE's office. Not access-restricted. -////////// -*/ - -/obj/item/enginepicker - name = "Bluespace Engine Delivery Device" - desc = "A per-station bluespace-based delivery system for a unique engine Engineering Department's choice. Only one option can be chosen. Device self-destructs on use." - icon = 'icons/obj/device.dmi' - icon_state = "enginepicker" - - var/list/list_enginebeacons = list() - var/isactive = FALSE - -/obj/item/enginepicker/Destroy() - list_enginebeacons.Cut() - return ..() - -/obj/item/enginepicker/attack_self__legacy__attackchain(mob/living/carbon/user) - if(user.incapacitated()) - return - - if(!isactive) - isactive = TRUE //Self-attack spam exploit prevention - else - return - - locatebeacons() - var/E = tgui_input_list(user, "Select the station's Engine", "[src]", list_enginebeacons) - if(E) - processchoice(E, user) - else - isactive = FALSE - return - -//This proc re-assigns all of engine beacons in the global list to a local list. -/obj/item/enginepicker/proc/locatebeacons() - LAZYCLEARLIST(list_enginebeacons) - for(var/obj/item/beacon/engine/B in GLOB.engine_beacon_list) - if(B && !QDELETED(B)) //This ensures that the input pop-up won't have any qdeleted beacons - list_enginebeacons += B - -//Spawns and logs / announces the appropriate engine based on the choice made -/obj/item/enginepicker/proc/processchoice(obj/item/beacon/engine/choice, mob/living/carbon/user) - var/issuccessful = FALSE //Check for a successful choice - var/engtype //Engine type - var/G //Generator that will be spawned - var/turf/T = get_turf(choice) - - if(length(choice.enginetype) > 1) //If the beacon has multiple engine types - var/E = tgui_input_list(user, "You have selected a combined beacon, which option would you prefer?", "[src]", choice.enginetype) - if(E) - engtype = E - issuccessful = TRUE - else - isactive = FALSE - return - - if(!engtype) //If it has only one type - engtype = DEFAULTPICK(choice.enginetype, null) //This should(?) account for a possibly scrambled list with a single entry - switch(engtype) - if(ENGTYPE_TESLA) - G = /obj/machinery/the_singularitygen/tesla - if(ENGTYPE_SING) - G = /obj/machinery/the_singularitygen - - if(G) //This can only be not-null if the switch operation was successful - issuccessful = TRUE - - if(issuccessful) - clearturf(T) //qdels all items / gibs all mobs on the turf. Let's not have an SM shard spawn on top of a poor sod. - new G(T) //Spawns the switch-selected engine on the chosen beacon's turf - - var/ailist[] = list() - for(var/mob/living/silicon/ai/A in GLOB.ai_list) - ailist += A - if(length(ailist)) - var/mob/living/silicon/ai/announcer = pick(ailist) - announcer.say(";Engine delivery detected. Type: [engtype].") //Let's announce the terrible choice to everyone - - visible_message("\The [src] begins to violently vibrate and hiss, then promptly disintegrates!") - qdel(src) //Self-destructs to prevent crew from spawning multiple engines. - else - visible_message("\The [src] buzzes! No beacon found or selected!") - isactive = FALSE - return - -//Deletes objects and mobs from the beacon's turf. -/obj/item/enginepicker/proc/clearturf(turf/T) - for(var/obj/item/I in T) - I.visible_message("\The [I] gets crushed to dust!") - qdel(I) - - for(var/mob/living/M in T) - M.visible_message("\The [M] gets obliterated!") - M.gib() diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm deleted file mode 100644 index 64c2e9284f3d6..0000000000000 --- a/code/game/objects/items/devices/flash.dm +++ /dev/null @@ -1,291 +0,0 @@ -/obj/item/flash - name = "flash" - desc = "A powerful and versatile flashbulb device, with applications ranging from disorienting attackers to acting as visual receptors in robot production." - icon = 'icons/obj/device.dmi' - icon_state = "flash" - item_state = "flashtool" //looks exactly like a flash (and nothing like a flashbang) - belt_icon = "flash" - throwforce = 0 - w_class = WEIGHT_CLASS_TINY - throw_speed = 3 - throw_range = 7 - flags = CONDUCT - materials = list(MAT_METAL = 300, MAT_GLASS = 300) - origin_tech = "magnets=2;combat=1" - - /// Is the flash burnt out? - var/broken = FALSE - /// Whether the flash can be modified with a cell or not - var/battery_panel = FALSE - /// If overcharged the flash will set people on fire then immediately burn out (does so even if it doesn't blind them). - var/overcharged = FALSE - /// Set this to FALSE if you don't want your flash to be overcharge capable - var/can_overcharge = TRUE - /// How many times have we used the flash recently - var/times_used = 0 - /// What is the max amount we can use this flash before it burns out - var/max_uses = 5 - /// A reference to the timer used to recharge. If we use it while it's on cooldown, we reset the cooling - var/flash_timer - /// How long do we have between flashes - var/time_between_flashes = 5 SECONDS - - var/use_sound = 'sound/weapons/flash.ogg' - COOLDOWN_DECLARE(flash_cooldown) - -/obj/item/flash/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(!can_overcharge || !istype(I, /obj/item/stock_parts/cell)) - return - - if(battery_panel && !overcharged) - to_chat(user, "You jam [I] into the battery compartment on [src].") - qdel(I) - overcharged = TRUE - update_icon(UPDATE_OVERLAYS) - -/obj/item/flash/update_overlays() - . = ..() - if(overcharged) - add_overlay("overcharge") - -/obj/item/flash/screwdriver_act(mob/living/user, obj/item/I) - if(!can_overcharge) - return - - if(battery_panel) - to_chat(user, "You close the battery compartment on [src].") - else - to_chat(user, "You open the battery compartment on [src].") - battery_panel = !battery_panel - return TRUE - -/obj/item/flash/proc/burn_out() //Made so you can override it if you want to have an invincible flash from R&D or something. - broken = TRUE - icon_state = "[initial(icon_state)]burnt" - visible_message("[src] burns out!") - -/obj/item/flash/proc/try_use_flash(mob/user) - if(broken) - return FALSE - - if(!COOLDOWN_FINISHED(src, flash_cooldown) && user) - to_chat(user, "Your [name] is still too hot to use again!") - return FALSE - - . = TRUE - COOLDOWN_START(src, flash_cooldown, time_between_flashes) - if(!flash_timer) - flash_timer = addtimer(CALLBACK(src, PROC_REF(flash_recharge)), 10 SECONDS, TIMER_STOPPABLE) - else - // The flash can't cool down if you overheat it again! - deltimer(flash_timer) - flash_timer = addtimer(CALLBACK(src, PROC_REF(flash_recharge)), 10 SECONDS, TIMER_STOPPABLE) - - playsound(loc, use_sound, 100, TRUE) - - flick("[initial(icon_state)]2", src) - set_light(2, 1, COLOR_WHITE) - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, set_light), 0), 2 DECISECONDS) - - times_used++ - if(times_used == (max_uses - 1)) - to_chat(user, "[src] is getting dangerously hot! Don't use it for a few seconds or it will burn out!") - else if(times_used == max_uses) - burn_out() - - if(user && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) - flash_carbon(user, user, 30 SECONDS, 0) - return FALSE - -/obj/item/flash/proc/flash_recharge(mob/user) - times_used = max(0, times_used - 1) - if(times_used) - flash_timer = addtimer(CALLBACK(src, PROC_REF(flash_recharge)), 10 SECONDS, TIMER_STOPPABLE) - else - flash_timer = null - -/obj/item/flash/proc/flash_carbon(mob/living/carbon/M, mob/user, power = 10 SECONDS, targeted = TRUE) - if(user) - add_attack_logs(user, M, "Flashed with [src]") - if(targeted) - if(M.flash_eyes(1, 1)) - M.AdjustConfused(power) - revolution_conversion(M, user) - if(!M.absorb_stun(0)) - M.drop_l_hand() - M.drop_r_hand() - visible_message("[user] blinds [M] with [src]!") - to_chat(user, "You blind [M] with [src]!") - to_chat(M, "[user] blinds you with [src]!") - else - visible_message("[user] fails to blind [M] with [src]!") - to_chat(user, "You fail to blind [M] with [src]!") - to_chat(M, "[user] fails to blind you with [src]!") - return - - if(M.flash_eyes()) - M.AdjustConfused(power) - -/obj/item/flash/attack__legacy__attackchain(mob/living/M, mob/user) - if(!try_use_flash(user)) - return FALSE - if(iscarbon(M)) - flash_carbon(M, user, 10 SECONDS, 1) - if(overcharged) - M.adjust_fire_stacks(6) - M.IgniteMob() - burn_out() - return TRUE - else if(issilicon(M)) - add_attack_logs(user, M, "Flashed with [src]") - if(M.flash_eyes(intensity = 1.25, affect_silicon = TRUE)) // 40 * 1.25 = 50 stamina damage - user.visible_message("[user] overloads [M]'s sensors with [src]!", "You overload [M]'s sensors with [src]!") - return TRUE - user.visible_message("[user] fails to blind [M] with [src]!", "You fail to blind [M] with [src]!") - -/obj/item/flash/afterattack__legacy__attackchain(atom/target, mob/living/user, proximity, params) - if(!proximity) - return - if(!istype(target, /obj/machinery/camera)) - return - if(!try_use_flash(user)) - return - var/obj/machinery/camera/C = target - C.emp_act(EMP_HEAVY) - to_chat(user,"You hit the lens of [C] with [src], temporarily disabling the camera!") - log_admin("[key_name(user)] EMPd a camera with a flash") - user.create_attack_log("[key_name(user)] EMPd a camera with a flash") - add_attack_logs(user, C, "EMPd with [src]", ATKLOG_ALL) - -/obj/item/flash/attack_self__legacy__attackchain(mob/living/carbon/user, flag = 0, emp = 0) - if(!try_use_flash(user)) - return FALSE - user.visible_message("[user]'s [name] emits a blinding light!", "Your [name] emits a blinding light!") - for(var/mob/living/carbon/M in oviewers(3, null)) - flash_carbon(M, user, 6 SECONDS, 0) - for(var/obj/machinery/camera/C in view(3, user)) - C.emp_act(EMP_LIGHT) - log_admin("[key_name(user)] EMPd a camera with a flash") - user.create_attack_log("[key_name(user)] EMPd a camera with a flash") - add_attack_logs(user, C, "EMPd with [src]", ATKLOG_ALL) - -/obj/item/flash/emp_act(severity) - if(!try_use_flash()) - return FALSE - for(var/mob/living/carbon/M in viewers(3, null)) - flash_carbon(M, null, 20 SECONDS, 0) - burn_out() - return ..() - -/obj/item/flash/proc/revolution_conversion(mob/M, mob/user) - if(!ishuman(M) || !user.mind?.has_antag_datum(/datum/antagonist/rev/head)) - return - if(M.stat != CONSCIOUS) - to_chat(user, "They must be conscious before you can convert [M.p_them()]!") - else if(add_revolutionary(M.mind)) - times_used-- //Flashes less likely to burn out for headrevs when used for conversion - else - to_chat(user, "This mind seems resistant to [src]!") - -/obj/item/flash/proc/add_revolutionary(datum/mind/converting_mind) - var/mob/living/carbon/human/conversion_target = converting_mind.current - if(converting_mind.assigned_role in GLOB.command_positions) - return FALSE - if(!istype(conversion_target)) - return FALSE - if(ismindshielded(conversion_target)) - return FALSE - if(converting_mind.has_antag_datum(/datum/antagonist/rev)) - return FALSE - converting_mind.add_antag_datum(/datum/antagonist/rev) - - conversion_target.Silence(10 SECONDS) - conversion_target.Stun(10 SECONDS) - return TRUE - -/obj/item/flash/cyborg - origin_tech = null - can_overcharge = FALSE - -/obj/item/flash/cyborg/attack__legacy__attackchain(mob/living/M, mob/user) - ..() - new /obj/effect/temp_visual/borgflash(get_turf(src)) - -/obj/item/flash/cyborg/attack_self__legacy__attackchain(mob/user) - ..() - new /obj/effect/temp_visual/borgflash(get_turf(src)) - -/obj/item/flash/cyborg/cyborg_recharge(coeff, emagged) - if(broken) - broken = FALSE - times_used = 0 - icon_state = "flash" - -/obj/item/flash/cameraflash - name = "camera" - icon = 'icons/obj/items.dmi' - desc = "A polaroid camera. 10 photos left." - icon_state = "camera" - item_state = "camera" - w_class = WEIGHT_CLASS_SMALL - slot_flags = ITEM_SLOT_BELT - can_overcharge = FALSE - var/flash_max_charges = 5 - var/flash_cur_charges = 5 - var/charge_tick = 0 - use_sound = 'sound/items/polaroid1.ogg' - -/obj/item/flash/cameraflash/burn_out() //stops from burning out - return - -/obj/item/flash/cameraflash/New() - ..() - START_PROCESSING(SSobj, src) - -/obj/item/flash/cameraflash/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/flash/cameraflash/process() //this and the two parts above are part of the charge system. - charge_tick++ - if(charge_tick < 10) - return FALSE - charge_tick = 0 - flash_cur_charges = min(flash_cur_charges + 1, flash_max_charges) - return TRUE - -/obj/item/flash/cameraflash/try_use_flash(mob/user = null) - if(!flash_cur_charges) - to_chat(user, "[src] needs time to recharge!") - return FALSE - . = ..() - if(.) - flash_cur_charges-- - to_chat(user, "[src] now has [flash_cur_charges] charge\s.") - -/obj/item/flash/memorizer - name = "memorizer" - desc = "If you see this, you're not likely to remember it any time soon." // Why doesn't this at least delete your notes smh - icon_state = "memorizer" - item_state = "nullrod" - -/obj/item/flash/armimplant - name = "photon projector" - desc = "A high-powered photon projector implant normally used for lighting purposes, but also doubles as a flashbulb weapon. Self-repair protocols fix the flashbulb if it ever burns out." - time_between_flashes = 2 SECONDS - var/obj/item/organ/internal/cyberimp/arm/implant - -/obj/item/flash/armimplant/burn_out() - if(implant?.owner) - to_chat(implant.owner, "Your [name] implant overheats and deactivates!") - implant.Retract() - -/obj/item/flash/armimplant/Destroy() - implant = null - return ..() - -/obj/item/flash/random/Initialize(mapload) - . = ..() - if(prob(25)) - broken = TRUE - icon_state = "[initial(icon_state)]burnt" diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm deleted file mode 100644 index 5a4e07005b625..0000000000000 --- a/code/game/objects/items/devices/flashlight.dm +++ /dev/null @@ -1,439 +0,0 @@ -/obj/item/flashlight - name = "flashlight" - desc = "A hand-held emergency light." - icon = 'icons/obj/lighting.dmi' - icon_state = "flashlight" - item_state = "flashlight" - w_class = WEIGHT_CLASS_SMALL - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - materials = list(MAT_METAL = 200, MAT_GLASS = 100) - actions_types = list(/datum/action/item_action/toggle_light) - var/on = FALSE - var/brightness_on = 4 //luminosity when on - var/togglesound = 'sound/weapons/empty.ogg' - -/obj/item/flashlight/Initialize(mapload) - . = ..() - update_brightness() - -/obj/item/flashlight/update_icon_state() - if(on) - icon_state = "[initial(icon_state)]-on" - else - icon_state = "[initial(icon_state)]" - -/obj/item/flashlight/proc/update_brightness() - if(on) - set_light(brightness_on) - else - set_light(0) - update_icon() - -/obj/item/flashlight/attack_self__legacy__attackchain(mob/user) - if(!isturf(user.loc)) - to_chat(user, "You cannot turn the light on while in this [user.loc].")//To prevent some lighting anomalities. - return FALSE - on = !on - playsound(user, togglesound, 100, 1) - update_brightness() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtons() - return TRUE - -/obj/item/flashlight/attack__legacy__attackchain(mob/living/M as mob, mob/living/user as mob) - add_fingerprint(user) - if(on && user.zone_selected == "eyes") - - if((HAS_TRAIT(user, TRAIT_CLUMSY) || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly - return ..() //just hit them in the head - - if(!(ishuman(user) || SSticker) && SSticker.mode.name != "monkey") //don't have dexterity - to_chat(user, "You don't have the dexterity to do this!") - return - - var/mob/living/carbon/human/H = M //mob has protective eyewear - if(istype(H) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES))) - to_chat(user, "You're going to need to remove that [(H.head && H.head.flags_cover & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) ? "mask" : "glasses"] first.") - return - - if(M == user) //they're using it on themselves - if(M.flash_eyes(visual = 1)) - M.visible_message("[M] directs [src] to [M.p_their()] eyes.", \ - "You wave the light in front of your eyes! Trippy!") - else - M.visible_message("[M] directs [src] to [M.p_their()] eyes.", \ - "You wave the light in front of your eyes.") - else - - user.visible_message("[user] directs [src] to [M]'s eyes.", \ - "You direct [src] to [M]'s eyes.") - - if(istype(H)) //robots and aliens are unaffected - var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes) - if(M.stat == DEAD || !eyes || HAS_TRAIT(M, TRAIT_BLIND)) //mob is dead or fully blind - to_chat(user, "[M]'s pupils are unresponsive to the light!") - else if(HAS_TRAIT(M, TRAIT_XRAY_VISION) || eyes.see_in_dark >= 8) //The mob's either got the X-RAY vision or has a tapetum lucidum (extreme nightvision, i.e. Vulp/Tajara with COLOURBLIND & their monkey forms). - to_chat(user, "[M]'s pupils glow eerily!") - else //they're okay! - if(M.flash_eyes(visual = 1)) - to_chat(user, "[M]'s pupils narrow.") - else - return ..() - -/obj/item/flashlight/extinguish_light(force = FALSE) - if(on) - on = FALSE - update_brightness() - -/obj/item/flashlight/pen - name = "penlight" - desc = "A pen, and a light. Used by medical staff." - icon_state = "penlight" - item_state = "" - w_class = WEIGHT_CLASS_TINY - slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BOTH_EARS - flags = CONDUCT - brightness_on = 2 - var/colour = "blue" // Ink color - -/obj/item/flashlight/seclite - name = "seclite" - desc = "A robust flashlight used by security." - icon_state = "seclite" - item_state = "seclite" - force = 9 // Not as good as a stun baton. - brightness_on = 5 // A little better than the standard flashlight. - hitsound = 'sound/weapons/genhit1.ogg' - -/obj/item/flashlight/drone - name = "low-power flashlight" - desc = "A miniature lamp, that might be used by small robots." - icon_state = "penlight" - item_state = "" - flags = CONDUCT - brightness_on = 2 - w_class = WEIGHT_CLASS_TINY - -// the desk lamps are a bit special -/obj/item/flashlight/lamp - name = "desk lamp" - desc = "A desk lamp with an adjustable mount." - icon_state = "lamp" - item_state = "lamp" - brightness_on = 5 - w_class = WEIGHT_CLASS_BULKY - flags = CONDUCT - materials = list() - on = TRUE - -/obj/item/flashlight/lamp/examine(mob/user) - . = ..() - . += "You can Alt-Click [src] to turn it on/off." - -// green-shaded desk lamp -/obj/item/flashlight/lamp/green - desc = "A classic green-shaded desk lamp." - icon_state = "lampgreen" - item_state = "lampgreen" - -/obj/item/flashlight/lamp/green/off - on = FALSE - -/obj/item/flashlight/lamp/AltClick(mob/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) - return - - attack_self__legacy__attackchain(user) - -//Bananalamp -/obj/item/flashlight/lamp/bananalamp - name = "banana lamp" - desc = "Only a clown would think to make a ghetto banana-shaped lamp. Even has a goofy pullstring." - icon_state = "bananalamp" - item_state = "bananalamp" - -// FLARES - -/obj/item/flashlight/flare - name = "flare" - desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'." - brightness_on = 8 - light_color = "#ff0000" - icon_state = "flare" - item_state = "flare" - togglesound = 'sound/goonstation/misc/matchstick_light.ogg' - var/fuel = 0 - var/on_damage = 7 - var/produce_heat = 1500 - var/fuel_lower = 800 - var/fuel_upp = 1000 - -/obj/item/flashlight/flare/New() - fuel = rand(fuel_lower, fuel_upp) - ..() - -/obj/item/flashlight/flare/update_icon_state() - if(on) - item_state = "[initial(item_state)]-on" - else - item_state = "[initial(item_state)]" - - if(!fuel) - icon_state = "[initial(icon_state)]-empty" - return - ..() - -/obj/item/flashlight/flare/process() - var/turf/pos = get_turf(src) - if(pos && produce_heat) - pos.hotspot_expose(produce_heat, 1) - fuel = max(fuel - 1, 0) - if(!fuel || !on) - turn_off() - STOP_PROCESSING(SSobj, src) - -/obj/item/flashlight/flare/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/flashlight/flare/proc/turn_off() - on = FALSE - force = initial(force) - damtype = initial(damtype) - hitsound = "swing_hit" - attack_verb = list() - update_brightness() - -/obj/item/flashlight/flare/attack_self__legacy__attackchain(mob/user) - // Usual checks - if(!fuel) - to_chat(user, "[src] is out of fuel.") - return - if(on) - to_chat(user, "[src] is already on.") - return - - . = ..() - // All good, turn it on. - if(.) - user.visible_message("[user] activates [src].", "You activate [src].") - if(produce_heat) - force = on_damage - damtype = "fire" - hitsound = 'sound/items/welder.ogg' - attack_verb = list("burnt", "singed") - START_PROCESSING(SSobj, src) - -/obj/item/flashlight/flare/used - -/obj/item/flashlight/flare/used/Initialize(mapload) - . = ..() - // fuel gets set on New which is annoying so these can't just be vars - fuel = 0 - on = 0 - update_icon() - -/obj/item/flashlight/flare/glowstick/used/Initialize(mapload) - . = ..() - // fuel gets set on New which is annoying so these can't just be vars - fuel = 0 - on = 0 - update_icon() - -/obj/item/flashlight/flare/decompile_act(obj/item/matter_decompiler/C, mob/user) - if(isdrone(user) && !fuel) - C.stored_comms["metal"] += 1 - C.stored_comms["glass"] += 1 - qdel(src) - return TRUE - return ..() - -/obj/item/flashlight/flare/get_heat() - return produce_heat * on * 1000 - -// GLOWSTICKS - -/obj/item/flashlight/flare/glowstick - name = "green glowstick" - desc = "A military-grade glowstick." - brightness_on = 4 - color = LIGHT_COLOR_GREEN - icon_state = "glowstick" - item_state = "glowstick" - togglesound = 'sound/effects/bone_break_1.ogg' - produce_heat = FALSE - fuel_lower = 1600 - fuel_upp = 2000 - blocks_emissive = FALSE - -/obj/item/flashlight/flare/glowstick/Initialize(mapload) - . = ..() - light_color = color - -/obj/item/flashlight/flare/glowstick/update_icon_state() - if(!fuel) - icon_state = "glowstick-empty" - -/obj/item/flashlight/flare/glowstick/update_overlays() - . = ..() - if(on) - var/mutable_appearance/glowstick_overlay = mutable_appearance(icon, "glowstick-glow") - glowstick_overlay.color = color - . += glowstick_overlay - -/obj/item/flashlight/flare/glowstick/red - name = "red glowstick" - color = LIGHT_COLOR_RED - -/obj/item/flashlight/flare/glowstick/blue - name = "blue glowstick" - color = LIGHT_COLOR_BLUE - -/obj/item/flashlight/flare/glowstick/orange - name = "orange glowstick" - color = LIGHT_COLOR_ORANGE - -/obj/item/flashlight/flare/glowstick/yellow - name = "yellow glowstick" - color = LIGHT_COLOR_YELLOW - -/obj/item/flashlight/flare/glowstick/pink - name = "pink glowstick" - color = LIGHT_COLOR_PINK - -/obj/item/flashlight/flare/glowstick/emergency - name = "emergency glowstick" - desc = "A cheap looking, mass produced glowstick. You can practically feel it was made on a tight budget." - color = LIGHT_COLOR_BLUE - fuel_lower = 30 - fuel_upp = 90 - -/obj/item/flashlight/flare/glowstick/random - name = "random colored glowstick" - icon_state = "random_glowstick" - color = null - -/obj/item/flashlight/flare/glowstick/random/Initialize(mapload) - . = ..() - var/T = pick(typesof(/obj/item/flashlight/flare/glowstick) - /obj/item/flashlight/flare/glowstick/random - /obj/item/flashlight/flare/glowstick/emergency) - new T(loc) - qdel(src) // return INITIALIZE_HINT_QDEL <-- Doesn't work - -/obj/item/flashlight/flare/extinguish_light(force = FALSE) - if(force) - fuel = 0 - visible_message("[src] burns up rapidly!") - else - visible_message("[src] dims slightly before scattering the shadows around it.") - -/obj/item/flashlight/flare/torch - name = "torch" - desc = "A torch fashioned from some leaves and a log." - w_class = WEIGHT_CLASS_BULKY - brightness_on = 7 - icon_state = "torch" - item_state = "torch" - lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' - righthand_file = 'icons/mob/inhands/items_righthand.dmi' - light_color = LIGHT_COLOR_ORANGE - on_damage = 10 - -/obj/item/flashlight/slime - gender = PLURAL - name = "glowing slime extract" - desc = "A glowing ball of what appears to be amber." - icon = 'icons/obj/lighting.dmi' - icon_state = "slime-on" - item_state = "slime" - w_class = WEIGHT_CLASS_TINY - brightness_on = 6 - light_color = "#FFBF00" - materials = list() - on = TRUE //Bio-luminesence has one setting, on. - -/obj/item/flashlight/slime/New() - ..() - set_light(brightness_on) - spawn(1) //Might be sloppy, but seems to be necessary to prevent further runtimes and make these work as intended... don't judge me! - update_brightness() - icon_state = initial(icon_state) - -/obj/item/flashlight/slime/attack_self__legacy__attackchain(mob/user) - return //Bio-luminescence does not toggle. - -/obj/item/flashlight/slime/extinguish_light(force = FALSE) - if(force) - visible_message("[src] withers away.") - qdel(src) - else - visible_message("[src] dims slightly before scattering the shadows around it.") - -/obj/item/flashlight/emp - origin_tech = "magnets=3;syndicate=1" - - var/emp_max_charges = 4 - var/emp_cur_charges = 4 - var/charge_tick = 0 - - -/obj/item/flashlight/emp/New() - ..() - START_PROCESSING(SSobj, src) - -/obj/item/flashlight/emp/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/flashlight/emp/process() - charge_tick++ - if(charge_tick < 10) - return FALSE - charge_tick = 0 - emp_cur_charges = min(emp_cur_charges+1, emp_max_charges) - return TRUE - -/obj/item/flashlight/emp/attack__legacy__attackchain(mob/living/M as mob, mob/living/user as mob) - if(on && user.zone_selected == "eyes") // call original attack proc only if aiming at the eyes - ..() - return - -/obj/item/flashlight/emp/afterattack__legacy__attackchain(atom/A as mob|obj, mob/user, proximity) - if(!proximity) return - if(emp_cur_charges > 0) - emp_cur_charges -= 1 - A.visible_message("[user] blinks \the [src] at \the [A].", \ - "[user] blinks \the [src] at \the [A].") - if(ismob(A)) - var/mob/M = A - add_attack_logs(user, M, "Hit with EMP-light") - to_chat(user, "[src] now has [emp_cur_charges] charge\s.") - A.emp_act(EMP_HEAVY) - else - to_chat(user, "\The [src] needs time to recharge!") - return - -/// invisible lighting source -/obj/item/flashlight/spotlight - name = "disco light" - desc = "Groovy..." - icon_state = null - light_color = null - brightness_on = 0 - light_range = 0 - light_power = 10 - alpha = 0 - layer = 0 - on = TRUE - anchored = TRUE - var/range = null - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - -/obj/item/flashlight/eyelight - name = "eyelight" - desc = "This shouldn't exist outside of someone's head, how are you seeing this?" - light_range = 15 - light_power = 1 - flags = CONDUCT | DROPDEL - actions_types = list() diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm deleted file mode 100644 index b4237bb1b88c6..0000000000000 --- a/code/game/objects/items/devices/geiger_counter.dm +++ /dev/null @@ -1,213 +0,0 @@ -#define RAD_LEVEL_NORMAL 9 -#define RAD_LEVEL_MODERATE 100 -#define RAD_LEVEL_HIGH 400 -#define RAD_LEVEL_VERY_HIGH 800 -#define RAD_LEVEL_CRITICAL 1500 - -/// DISCLAIMER: I know nothing about how real-life Geiger counters work. This will not be realistic. ~Xhuis -/obj/item/geiger_counter - name = "\improper Geiger counter" - desc = "A handheld device used for detecting and measuring radiation pulses." - icon = 'icons/obj/device.dmi' - icon_state = "geiger_off" - item_state = "multitool" - w_class = WEIGHT_CLASS_SMALL - slot_flags = ITEM_SLOT_BELT - flags = NOBLUDGEON - materials = list(MAT_METAL = 210, MAT_GLASS = 150) - - var/grace = RAD_GEIGER_GRACE_PERIOD - var/datum/looping_sound/geiger/soundloop - - var/scanning = FALSE - var/radiation_count = 0 - var/current_tick_amount = 0 - var/last_tick_amount = 0 - var/fail_to_receive = 0 - var/current_warning = 1 - -/obj/item/geiger_counter/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - - soundloop = new(list(src), FALSE) - -/obj/item/geiger_counter/Destroy() - STOP_PROCESSING(SSobj, src) - QDEL_NULL(soundloop) - return ..() - - -/obj/item/geiger_counter/process() - if(scanning) - radiation_count -= radiation_count / RAD_GEIGER_MEASURE_SMOOTHING - radiation_count += current_tick_amount / RAD_GEIGER_MEASURE_SMOOTHING - - if(current_tick_amount) - grace = RAD_GEIGER_GRACE_PERIOD - last_tick_amount = current_tick_amount - - else if(!emagged) - grace-- - if(grace <= 0) - radiation_count = 0 - - current_tick_amount = 0 - - update_icon(UPDATE_ICON_STATE) - update_sound() - -/obj/item/geiger_counter/examine(mob/user) - . = ..() - if(!scanning) - return - . += "Alt-click it to clear stored radiation levels." - if(emagged) - . += "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." - if(RAD_LEVEL_NORMAL + 1 to RAD_LEVEL_MODERATE) - . += "Ambient radiation levels slightly above average." - if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH) - . += "Ambient radiation levels above average." - if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH) - . += "Ambient radiation levels highly above average." - if(RAD_LEVEL_VERY_HIGH + 1 to RAD_LEVEL_CRITICAL) - . += "Ambient radiation levels nearing critical level." - if(RAD_LEVEL_CRITICAL + 1 to INFINITY) - . += "Ambient radiation levels above critical level!" - - . += "The last radiation amount detected was [last_tick_amount]" - -/obj/item/geiger_counter/update_icon_state() - if(!scanning) - icon_state = "geiger_off" - else if(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" - -/obj/item/geiger_counter/proc/update_sound() - var/datum/looping_sound/geiger/loop = soundloop - if(!scanning || !radiation_count) - loop.stop() - return - loop.last_radiation = radiation_count - loop.start() - -/obj/item/geiger_counter/rad_act(amount) - . = ..() - if(amount <= RAD_BACKGROUND_RADIATION || !scanning) - return - current_tick_amount += amount - update_icon(UPDATE_ICON_STATE) - -/obj/item/geiger_counter/attack_self__legacy__attackchain(mob/user) - scanning = !scanning - update_icon(UPDATE_ICON_STATE) - to_chat(user, "[bicon(src)] You switch [scanning ? "on" : "off"] [src].") - -/obj/item/geiger_counter/afterattack__legacy__attackchain(atom/target, mob/user) - . = ..() - if(user.a_intent == INTENT_HELP) - if(!emagged) - user.visible_message("[user] scans [target] with [src].", "You scan [target]'s radiation levels with [src]...") - addtimer(CALLBACK(src, PROC_REF(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]!") - target.rad_act(radiation_count) - radiation_count = 0 - return TRUE - -/obj/item/geiger_counter/proc/scan(atom/A, mob/user) - var/rad_strength = get_rad_contamination(A) - - if(isliving(A)) - var/mob/living/M = A - if(!M.radiation) - to_chat(user, "[bicon(src)] Radiation levels within normal boundaries.") - else - to_chat(user, "[bicon(src)] Subject is irradiated. Radiation levels: [M.radiation] rads.") - - if(rad_strength) - to_chat(user, "[bicon(src)] Target contains radioactive contamination. Radioactive strength: [rad_strength] rads.") - else - to_chat(user, "[bicon(src)] Target is free of radioactive contamination.") - -/obj/item/geiger_counter/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_SCREWDRIVER && emagged) - if(scanning) - to_chat(user, "Turn off [src] before you perform this action!") - return FALSE - user.visible_message("[user] unscrews [src]'s maintenance panel and begins fiddling with its innards...", "You begin resetting [src]...") - if(!I.use_tool(src, user, 40, I.tool_volume)) - return FALSE - user.visible_message("[user] refastens [src]'s maintenance panel!", "You reset [src] to its factory settings!") - emagged = FALSE - radiation_count = 0 - update_icon(UPDATE_ICON_STATE) - return TRUE - else - return ..() - -/obj/item/geiger_counter/AltClick(mob/living/user) - if(!istype(user) || !user.Adjacent(src)) - return ..() - if(!scanning) - to_chat(user, "[src] must be on to reset its radiation level!") - return - radiation_count = 0 - to_chat(user, "You flush [src]'s radiation counts, resetting it to normal.") - update_icon(UPDATE_ICON_STATE) - -/obj/item/geiger_counter/emag_act(mob/user) - if(emagged) - return - if(scanning) - to_chat(user, "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.") - emagged = TRUE - return TRUE - - - -/obj/item/geiger_counter/cyborg - var/mob/listeningTo - -/obj/item/geiger_counter/cyborg/equipped(mob/user) - . = ..() - if(listeningTo == user) - return - if(listeningTo) - UnregisterSignal(listeningTo, COMSIG_ATOM_RAD_ACT) - RegisterSignal(user, COMSIG_ATOM_RAD_ACT, PROC_REF(redirect_rad_act)) - listeningTo = user - -/obj/item/geiger_counter/cyborg/proc/redirect_rad_act(datum/source, amount) - rad_act(amount) - -/obj/item/geiger_counter/cyborg/dropped() - . = ..() - if(listeningTo) - UnregisterSignal(listeningTo, COMSIG_ATOM_RAD_ACT) - -#undef RAD_LEVEL_NORMAL -#undef RAD_LEVEL_MODERATE -#undef RAD_LEVEL_HIGH -#undef RAD_LEVEL_VERY_HIGH -#undef RAD_LEVEL_CRITICAL diff --git a/code/game/objects/items/devices/handheld_defib.dm b/code/game/objects/items/devices/handheld_defib.dm deleted file mode 100644 index 09ea14d04689a..0000000000000 --- a/code/game/objects/items/devices/handheld_defib.dm +++ /dev/null @@ -1,104 +0,0 @@ -/obj/item/handheld_defibrillator - name = "handheld defibrillator" - desc = "Used to restart stopped hearts." - icon = 'icons/obj/medical.dmi' - lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' - righthand_file = 'icons/mob/inhands/items_righthand.dmi' - icon_state = "defib-on" - item_state = "defib" - belt_icon = "defib" - - var/icon_base = "defib" - ///Can the defib shock yet? - var/cooldown = FALSE - ///How long will it take to recharge after a shock? - var/charge_time = 10 SECONDS - ///How long until we can attack the same person with any emagged handheld defib or baton again? - var/attack_cooldown = 3.5 SECONDS - ///How long does this knock the target down for? - var/knockdown_duration = 10 SECONDS - -/obj/item/handheld_defibrillator/emag_act(mob/user) - if(!emagged) - emagged = TRUE - desc += " The screen only shows the word KILL flashing over and over." - if(user) - to_chat(user, "you short out the safeties on [src]") - return TRUE - else - emagged = FALSE - desc = "Used to restart stopped hearts." - if(user) - to_chat(user, "You restore the safeties on [src]") - return TRUE - -/obj/item/handheld_defibrillator/attack__legacy__attackchain(mob/living/carbon/human/H, mob/user) - if(!istype(H)) - return ..() - - if(cooldown) - to_chat(user, "[src] is still charging!") - return - - if(emagged) - var/user_UID = user.UID() - if(HAS_TRAIT_FROM(H, TRAIT_WAS_BATONNED, user_UID)) // no following up with baton or dual wielding defibs for stunlock cheese purposes - return - - user.visible_message("[user] violently shocks [H] with [src]!", "You violently shock [H] with [src]!") - add_attack_logs(user, H, "emag-defibbed with [src]") - playsound(user.loc, "sound/weapons/egloves.ogg", 75, 1) - H.KnockDown(knockdown_duration) - H.apply_damage(60, STAMINA) - SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK, 100) - ADD_TRAIT(H, TRAIT_WAS_BATONNED, user_UID) - cooldown = TRUE - icon_state = "[icon_base]-shock" - addtimer(CALLBACK(src, PROC_REF(allowhit), H, user_UID), attack_cooldown) - addtimer(CALLBACK(src, PROC_REF(short_charge)), 1 SECONDS) - addtimer(CALLBACK(src, PROC_REF(recharge)), charge_time) - return - - if((H.health <= HEALTH_THRESHOLD_CRIT) || (H.undergoing_cardiac_arrest())) - user.visible_message("[user] shocks [H] with [src].", "You shock [H] with [src].") - add_attack_logs(user, H, "defibrillated with [src]") - playsound(user.loc, "sound/weapons/egloves.ogg", 75, 1) - - if(H.stat == DEAD) - to_chat(user, "[H] doesn't respond at all!") - else - H.set_heartattack(FALSE) - var/total_damage = H.getBruteLoss() + H.getFireLoss() + H.getToxLoss() - if(H.health <= HEALTH_THRESHOLD_CRIT) - if(total_damage >= 90) - to_chat(user, "[H] looks horribly injured. Resuscitation alone may not help revive them.") - if(prob(66)) - to_chat(user, "[H] inhales deeply!") - H.adjustOxyLoss(-50) - else - to_chat(user, "[H] doesn't respond!") - - H.AdjustParalysis(6 SECONDS) - H.AdjustWeakened(10 SECONDS) - H.AdjustStuttering(20 SECONDS) - to_chat(H, "You feel a powerful jolt!") - SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK, 100) - - cooldown = TRUE - icon_state = "[icon_base]-shock" - addtimer(CALLBACK(src, PROC_REF(short_charge)), 1 SECONDS) - addtimer(CALLBACK(src, PROC_REF(recharge)), charge_time) - - else - to_chat(user, "[src]'s on board medical scanner indicates that no shock is required.") - -/obj/item/handheld_defibrillator/proc/allowhit(mob/living/target, user_UID) - REMOVE_TRAIT(target, TRAIT_WAS_BATONNED, user_UID) - -/obj/item/handheld_defibrillator/proc/short_charge() - icon_state = "[icon_base]-off" - -/obj/item/handheld_defibrillator/proc/recharge() - cooldown = FALSE - icon_state = "[icon_base]-on" - playsound(loc, "sound/weapons/flash.ogg", 75, 1) diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm deleted file mode 100644 index 8f4329b13cc0e..0000000000000 --- a/code/game/objects/items/devices/laserpointer.dm +++ /dev/null @@ -1,182 +0,0 @@ -/obj/item/laser_pointer - name = "laser pointer" - desc = "Don't shine it in your eyes!" - icon = 'icons/obj/device.dmi' - icon_state = "pointer" - item_state = "pen" - var/pointer_icon_state - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - materials = list(MAT_METAL=500, MAT_GLASS=500) - w_class = WEIGHT_CLASS_SMALL //Increased to 2, because diodes are w_class 2. Conservation of matter. - origin_tech = "combat=1;magnets=2" - var/energy = 5 - var/max_energy = 5 - var/effectchance = 33 - var/recharging = 0 - var/recharge_locked = 0 - var/obj/item/stock_parts/micro_laser/diode //used for upgrading! - - -/obj/item/laser_pointer/red - pointer_icon_state = "red_laser" -/obj/item/laser_pointer/green - pointer_icon_state = "green_laser" -/obj/item/laser_pointer/blue - pointer_icon_state = "blue_laser" -/obj/item/laser_pointer/purple - pointer_icon_state = "purple_laser" - -/obj/item/laser_pointer/New() - ..() - diode = new(src) - if(!pointer_icon_state) - pointer_icon_state = pick("red_laser","green_laser","blue_laser","purple_laser") - -/obj/item/laser_pointer/Destroy() - QDEL_NULL(diode) - return ..() - -/obj/item/laser_pointer/upgraded/New() - ..() - diode = new /obj/item/stock_parts/micro_laser/ultra - - - -/obj/item/laser_pointer/attack__legacy__attackchain(mob/living/M, mob/user) - laser_act(M, user) - -/obj/item/laser_pointer/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(istype(W, /obj/item/stock_parts/micro_laser)) - if(!diode) - user.drop_item() - W.loc = src - diode = W - to_chat(user, "You install [diode] in [src].") - else - to_chat(user, "[src] already has a cell.") - -/obj/item/laser_pointer/screwdriver_act(mob/living/user, obj/item/I) - if(!diode) - return - - to_chat(user, "You remove [diode] from [src].") - diode.forceMove(get_turf(loc)) - diode = null - return TRUE - -/obj/item/laser_pointer/afterattack__legacy__attackchain(atom/target, mob/living/user, flag, params) - if(flag) //we're placing the object on a table or in backpack - return - laser_act(target, user, params) - -/obj/item/laser_pointer/proc/laser_act(atom/target, mob/living/user, params) - if(!diode) - to_chat(user, "You point [src] at [target], but nothing happens!") - return - if(!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") - return - if(HAS_TRAIT(user, TRAIT_CHUNKYFINGERS)) - to_chat(user, "Your fingers can't press the button!") - return - if(!(target in view(7, get_turf(src)))) // Use the turf as center so it won't use the potential xray of the user - to_chat(user, "There is something in the way!") - return - - add_fingerprint(user) - - //nothing happens if the battery is drained - if(recharge_locked) - to_chat(user, "You point [src] at [target], but it's still charging.") - return - - var/outmsg - var/turf/targloc = get_turf(target) - - //human/alien mobs - if(iscarbon(target)) - var/mob/living/carbon/C = target - if(user.zone_selected == "eyes") - add_attack_logs(user, C, "Shone a laser in the eyes with [src]") - - var/severity = 1 - if(prob(33)) - severity = 2 - else if(prob(50)) - severity = 0 - - //20% chance to actually hit the eyes - if(prob(effectchance * diode.rating) && C.flash_eyes(severity, laser_pointer = TRUE)) - outmsg = "You blind [C] by shining [src] in [C.p_their()] eyes." - else - outmsg = "You fail to blind [C] by shining [src] at [C.p_their()] eyes!" - - //robots and AI - else if(issilicon(target)) - var/mob/living/silicon/S = target - //20% chance to actually hit the sensors - if(prob(effectchance * diode.rating)) - S.flash_eyes(affect_silicon = TRUE) - to_chat(S, "Your sensors were overloaded by a laser!") - outmsg = "You overload [S] by shining [src] at [S.p_their()] sensors." - - add_attack_logs(user, S, "shone [src] in their eyes") - else - outmsg = "You fail to overload [S] by shining [src] at [S.p_their()] sensors." - - //cameras - else if(istype(target, /obj/machinery/camera)) - var/obj/machinery/camera/C = target - if(prob(effectchance * diode.rating)) - C.emp_act(EMP_HEAVY) - outmsg = "You hit the lens of [C] with [src], temporarily disabling the camera!" - - log_admin("[key_name(user)] EMPd a camera with a laser pointer") - user.create_attack_log("[key_name(user)] EMPd a camera with a laser pointer") - add_attack_logs(user, C, "EMPd with [src]", ATKLOG_ALL) - else - outmsg = "You missed the lens of [C] with [src]." - - //laser pointer image - icon_state = "pointer_[pointer_icon_state]" - var/list/showto = list() - for(var/mob/M in viewers(7,targloc)) - if(M.client) - showto.Add(M.client) - var/image/I = image('icons/obj/projectiles.dmi',targloc,pointer_icon_state,10) - var/list/click_params = params2list(params) - if(click_params) - if(click_params["icon-x"]) - I.pixel_x = (text2num(click_params["icon-x"]) - 16) - if(click_params["icon-y"]) - I.pixel_y = (text2num(click_params["icon-y"]) - 16) - else - I.pixel_x = target.pixel_x + rand(-5,5) - I.pixel_y = target.pixel_y + rand(-5,5) - - if(outmsg) - to_chat(user, outmsg) - else - to_chat(user, "You point [src] at [target].") - - energy -= 1 - if(energy <= max_energy) - if(!recharging) - recharging = 1 - START_PROCESSING(SSobj, src) - if(energy <= 0) - to_chat(user, "You've overused the battery of [src], now it needs time to recharge!") - recharge_locked = 1 - - flick_overlay(I, showto, 10) - icon_state = "pointer" - -/obj/item/laser_pointer/process() - if(prob(20 - recharge_locked*5)) - energy += 1 - if(energy >= max_energy) - energy = max_energy - recharging = 0 - recharge_locked = 0 - ..() diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm deleted file mode 100644 index 924d261f0400f..0000000000000 --- a/code/game/objects/items/devices/lightreplacer.dm +++ /dev/null @@ -1,254 +0,0 @@ - -// Light Replacer (LR) -// -// ABOUT THE DEVICE -// -// This is a device supposedly to be used by Janitors and Janitor Cyborgs which will -// allow them to easily replace lights. This was mostly designed for Janitor Cyborgs since -// they don't have hands or a way to replace lightbulbs. -// -// HOW IT WORKS -// -// You attack a light fixture with it, if the light fixture is broken it will replace the -// light fixture with a working light; the broken light is then placed on the floor for the -// user to then pickup with a trash bag. If it's empty then it will just place a light in the fixture. -// -// HOW TO REFILL THE DEVICE -// -// It will need to be manually refilled with lights. -// If it's part of a robot module, it will charge when the Robot is inside a Recharge Station. -// -// EMAGGED FEATURES -// -// NOTICE: The Cyborg cannot use the emagged Light Replacer and the light's explosion was nerfed. It cannot create holes in the station anymore. -// -// I'm not sure everyone will react the emag's features so please say what your opinions are of it. -// -// When emagged it will rig every light it replaces, which will explode when the light is on. -// This is VERY noticable, even the device's name changes when you emag it so if anyone -// examines you when you're holding it in your hand, you will be discovered. -// It will also be very obvious who is setting all these lights off, since only Janitor Borgs and Janitors have easy -// access to them, and only one of them can emag their device. -// -// The explosion cannot insta-kill anyone with 30% or more health. -/obj/item/lightreplacer - name = "light replacer" - desc = "A device to automatically replace lights. Refill with broken or working light bulbs, or sheets of glass." - icon = 'icons/obj/janitor.dmi' - icon_state = "lightreplacer0" - item_state = "electronic" - belt_icon = "light_replacer" - w_class = WEIGHT_CLASS_SMALL - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - origin_tech = "magnets=3;engineering=4" - force = 8 - var/max_uses = 20 - var/uses = 10 - /// How much to increase per each glass? - var/increment = 5 - /// How much to take from the glass? - var/decrement = 1 - var/charge = 1 - /// Eating used bulbs gives us bulb shards - var/bulb_shards = 0 - /// when we get this many shards, we get a free bulb. - var/shards_required = 4 - /// It can replace lights at a distance? - var/bluespace_toggle = FALSE - -/obj/item/lightreplacer/examine(mob/user) - . = ..() - . += status_string() - -/obj/item/lightreplacer/attackby__legacy__attackchain(obj/item/I, mob/user) - if(uses >= max_uses) - to_chat(user, "[src] is full.") - return - - if(istype(I, /obj/item/stack/sheet/glass)) - var/obj/item/stack/sheet/glass/G = I - - if(G.use(decrement)) - AddUses(increment) - to_chat(user, "You insert some glass into [src]. You have [uses] light\s remaining.") - else - to_chat(user, "You need one sheet of glass to replace lights!") - return - - if(istype(I, /obj/item/shard)) - if(!user.drop_item_to_ground(I)) - to_chat(user, "[I] is stuck to your hand!") - return - - AddUses(increment) - to_chat(user, "You insert a shard of glass into [src]. You have [uses] light\s remaining.") - qdel(I) - return - - if(istype(I, /obj/item/light)) - var/obj/item/light/L = I - if(!user.drop_item_to_ground(L)) - to_chat(user, "[L] is stuck to your hand!") - return - - if(L.status == LIGHT_OK) - AddUses(1) - to_chat(user, "You insert [L] into [src]. You have [uses] light\s remaining.") - qdel(L) - else - AddShards(1, user) - to_chat(user, "You insert [L] into [src]. You have [uses] light\s remaining.") - qdel(L) - return - - if(isstorage(I)) - var/obj/item/storage/S = I - var/found_lightbulbs = FALSE - var/replaced_something = TRUE - - for(var/obj/item/IT in S.contents) - if(istype(IT, /obj/item/light)) - var/obj/item/light/L = IT - found_lightbulbs = TRUE - if(uses >= max_uses) - break - if(L.status == LIGHT_OK) - replaced_something = TRUE - AddUses(1) - qdel(L) - - else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED) - replaced_something = TRUE - AddShards(1, user) - qdel(L) - - if(!found_lightbulbs) - to_chat(user, "[S] contains no bulbs.") - return - - if(!replaced_something && uses == max_uses) - to_chat(user, "[src] is full!") - return - - to_chat(user, "You fill [src] with lights from [S]. " + status_string() + "") - return - return ..() - -/obj/item/lightreplacer/emag_act(user as mob) - if(!emagged) - emagged = !emagged - playsound(loc, "sparks", 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - update_appearance(UPDATE_NAME|UPDATE_ICON_STATE) - return TRUE - -/obj/item/lightreplacer/attack_self__legacy__attackchain(mob/user) - for(var/obj/machinery/light/target in user.loc) - ReplaceLight(target, user) - to_chat(user, status_string()) - -/obj/item/lightreplacer/update_name() - . = ..() - if(emagged) - name = "shortcircuited [initial(name)]" - else - name = initial(name) - -/obj/item/lightreplacer/update_icon_state() - icon_state = "lightreplacer[emagged]" - -/obj/item/lightreplacer/proc/status_string() - return "It has [uses] light\s remaining (plus [bulb_shards] fragment\s)." - -/obj/item/lightreplacer/proc/Use(mob/user) - playsound(loc, 'sound/machines/click.ogg', 50, TRUE) - AddUses(-1) - return 1 - -// Negative numbers will subtract -/obj/item/lightreplacer/proc/AddUses(amount = 1) - uses = clamp(uses + amount, 0, max_uses) - -/obj/item/lightreplacer/proc/AddShards(amount = 1, user) - bulb_shards += amount - var/new_bulbs = round(bulb_shards / shards_required) - if(new_bulbs > 0) - AddUses(new_bulbs) - bulb_shards = bulb_shards % shards_required - if(new_bulbs != 0) - to_chat(user, "[src] has fabricated a new bulb from the broken glass it has stored. It now has [uses] uses.") - playsound(loc, 'sound/machines/ding.ogg', 50, TRUE) - return new_bulbs - -/obj/item/lightreplacer/proc/Charge(mob/user) - charge += 1 - if(charge > 3) - AddUses(1) - charge = 1 - -/obj/item/lightreplacer/proc/ReplaceLight(obj/machinery/light/target, mob/living/U) - if(target.status != LIGHT_OK) - if(CanUse(U)) - if(!Use(U)) - return - if(target.status != LIGHT_EMPTY) - AddShards(1, U) - target.status = LIGHT_EMPTY - target.fix(U, src, emagged) - - else - to_chat(U, "[src]'s refill light blinks red.") - return - else - to_chat(U, "There is a working [target.fitting] already inserted!") - return - -/obj/item/lightreplacer/proc/CanUse(mob/living/user) - add_fingerprint(user) - if(uses > 0) - return 1 - else - return 0 - -/obj/item/lightreplacer/afterattack__legacy__attackchain(atom/target, mob/U, proximity) - . = ..() - if(isitem(target)) - attackby__legacy__attackchain(target, U) - return - - if(!proximity && !bluespace_toggle) - return - - var/turf/replace_turf = get_turf(target) - if(!istype(replace_turf)) - return - - if(get_dist(src, target) >= (U.client.maxview() + 2)) // To prevent people from using it over cameras - return - - var/used = FALSE - for(var/atom/A in replace_turf) - if(!CanUse(U)) - break - used = TRUE - if(istype(A, /obj/machinery/light)) - if(!proximity) // only beams if at a distance - U.Beam(A, icon_state = "rped_upgrade", icon = 'icons/effects/effects.dmi', time = 5) - playsound(src, 'sound/items/pshoom.ogg', 40, 1) - ReplaceLight(A, U) - - if(!used) - to_chat(U, "[src]'s refill light blinks red.") - -/obj/item/lightreplacer/cyborg/cyborg_recharge(coeff, emagged) - for(var/I in 1 to coeff) - Charge() - -/obj/item/lightreplacer/bluespace - name = "bluespace light replacer" - desc = "A modified light replacer that zaps lights into place. Refill with broken or working light bulbs, or sheets of glass." - icon_state = "lightreplacer_blue0" - bluespace_toggle = TRUE - -/obj/item/lightreplacer/bluespace/emag_act() - return // long range explosions are stupid diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm deleted file mode 100644 index 12bbbb31bc7b3..0000000000000 --- a/code/game/objects/items/devices/megaphone.dm +++ /dev/null @@ -1,109 +0,0 @@ -/obj/item/megaphone - name = "megaphone" - desc = "A device used to project your voice. Loudly." - icon = 'icons/obj/device.dmi' - icon_state = "megaphone" - item_state = "radio" - w_class = WEIGHT_CLASS_SMALL - flags = CONDUCT - - /// How long to wait when using it as normal - var/normal_cooldown = 2 SECONDS - /// How long to wait between insults - var/modified_cooldown = 20 SECONDS - /// If it's on cooldown. - var/on_cooldown = FALSE - /// Span to use by default for the message. - var/span = "reallybig" - /// List of insults to be sent when the megaphone is cmagged. - var/list/insultmsg = list("FUCK EVERYONE!", "I'M A TATER!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "FOR THE SYNDICATE!") - -/obj/item/megaphone/suicide_act(mob/user) - user.visible_message("[user] is uttering [user.p_their()] last words into [src]! It looks like [user.p_theyre()] trying to commit suicide!") - on_cooldown = FALSE - user.emote("scream") - say_msg(user, "AAAAAAAAAAAARGHHHHH") - return OXYLOSS - -/obj/item/megaphone/examine(mob/user) - . = ..() - if(HAS_TRAIT(src, TRAIT_CMAGGED)) - . += "Yellow ooze seems to be seeping from the speaker..." - -/obj/item/megaphone/attack_self__legacy__attackchain(mob/living/user) - if(check_mute(user.ckey, MUTE_IC)) - to_chat(src, "You cannot speak in IC (muted).") - return - if(!ishuman(user)) - to_chat(user, "You don't know how to use this!") - return - if(!user.can_speak()) - to_chat(user, "You find yourself unable to speak at all.") - return - if(ishuman(user)) - var/mob/living/carbon/human/abductor/H = user - if(isabductor(H)) - to_chat(user, "Megaphones can't project psionic communication!") - return - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H && H.mind && H.mind.miming) - to_chat(user, "Your vow of silence prevents you from speaking.") - return - if(HAS_TRAIT(H, TRAIT_COMIC_SANS)) - span = "sans" - if(on_cooldown) - to_chat(user, "[src] needs to recharge!") - return - - var/message = tgui_input_text(user, "Shout a message:", "Megaphone") - if(!message) - return - message = capitalize(message) - var/list/message_pieces = message_to_multilingual(message) - user.handle_speech_problems(message_pieces) - message = multilingual_to_message(message_pieces) - if((loc == user && !user.incapacitated())) - if(HAS_TRAIT(src, TRAIT_CMAGGED)) - message = pick(insultmsg) - say_msg(user, message) - - on_cooldown = TRUE - addtimer(VARSET_CALLBACK(src, on_cooldown, FALSE), (HAS_TRAIT(src, TRAIT_CMAGGED) || emagged) ? modified_cooldown : normal_cooldown) - -/obj/item/megaphone/proc/say_msg(mob/living/user, message) - if(HAS_TRAIT(src, TRAIT_CMAGGED)) - playsound(src, "sound/items/bikehorn.ogg", 50, TRUE) - else - playsound(src, "sound/items/megaphone.ogg", 100, FALSE, 5) - - audible_message("[user.GetVoice()] [user.GetAltName()] broadcasts, \"[message]\"", hearing_distance = 14) - log_say("(MEGAPHONE) [message]", user) - user.create_log(SAY_LOG, "(megaphone) '[message]'") - for(var/obj/O in view(14, get_turf(src))) - O.hear_talk(user, message_to_multilingual("[message]")) - - for(var/mob/M as anything in get_mobs_in_view(7, src)) - if((M.client?.prefs.toggles2 & PREFTOGGLE_2_RUNECHAT) && M.can_hear()) - M.create_chat_message(user, message, FALSE, "big") - -/obj/item/megaphone/cmag_act(mob/user) - if(HAS_TRAIT(src, TRAIT_CMAGGED)) - return FALSE - if(user) - to_chat(user, "You drip some yellow ooze into [src]'s voice synthesizer, gunking it up.") - playsound(src, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - ADD_TRAIT(src, TRAIT_CMAGGED, CLOWN_EMAG) - return TRUE - -/obj/item/megaphone/emag_act(mob/user) - if(emagged) - return FALSE - if(HAS_TRAIT(src, TRAIT_CMAGGED)) // one at a time - to_chat(user, "You go to short out [src], but it's covered in yellow ooze! You don't want to gunk up your emag!") - return FALSE - to_chat(user, "You short out [src]'s dampener circuits.") - emagged = TRUE - span = "reallybig userdanger" // really obvious, but also really loud - return TRUE - diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm deleted file mode 100644 index a329fc7ce7ae2..0000000000000 --- a/code/game/objects/items/devices/paicard.dm +++ /dev/null @@ -1,334 +0,0 @@ -/obj/item/paicard - name = "personal AI device" - desc = "A handheld device that allows you to install an artificial intelligence to be your companion." - icon = 'icons/obj/aicards.dmi' - icon_state = "pai" - item_state = "electronic" - w_class = WEIGHT_CLASS_SMALL - slot_flags = ITEM_SLOT_BELT - origin_tech = "programming=2" - var/request_cooldown = 5 // five seconds - var/last_request - var/obj/item/radio/radio - var/looking_for_personality = 0 - var/mob/living/silicon/pai/pai - var/list/faction = list("neutral") // The factions the pAI will inherit from the card - var/current_emotion = 1 - resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE - -/obj/item/paicard/syndicate - name = "syndicate personal AI device" - faction = list("syndicate") - -/obj/item/paicard/New() - ..() - overlays += "pai-off" - -/obj/item/paicard/Destroy() - if(pai) - pai.ghostize() - QDEL_NULL(pai) - QDEL_NULL(radio) - return ..() - -/obj/item/paicard/attack_self__legacy__attackchain(mob/user) - if(!in_range(src, user)) - return - user.set_machine(src) - var/dat = {" - - - - - - - "} - - if(pai) - dat += {" - Personal AI Device

    - - - - - - - - - - - - - -
    Installed Personality:[pai.name]
    Prime directive:[pai.pai_law0]
    Additional directives:[pai.pai_laws]
    -
    - "} - dat += {" - - -
    - Configure Directives -
    - "} - if(pai && (!pai.master_dna || !pai.master)) - dat += {" - - -
    - Imprint Master DNA -
    - "} - dat += "
    " - if(radio) - dat += "Radio Uplink" - dat += {" - - - - - - - - - -
    Transmit:[radio.broadcasting ? "En" : "Dis" ]abled - -
    Receive:[radio.listening ? "En" : "Dis" ]abled - -
    -
    - "} - else - dat += "Radio Uplink
    " - dat += "Radio firmware not loaded. Please install a pAI personality to load firmware.
    " - dat += {" - - -
    Wipe current pAI personality - -
    - "} - else - if(looking_for_personality) - dat += {" - pAI Request Module

    -

    Requesting AI personalities from central database... If there are no entries, or if a suitable entry is not listed, check again later as more personalities may be added.

    - Searching for personalities, please wait...

    - - - - - -
    - Refresh available personalities -

    - "} - else - dat += {" - pAI Request Module

    -

    No personality is installed.

    - - - - -
    Request personality -
    -
    -

    Each time this button is pressed, a request will be sent out to any available personalities. Check back often give plenty of time for personalities to respond. This process could take anywhere from 15 seconds to several minutes, depending on the available personalities' timeliness.

    - "} - user << browse(dat, "window=paicard") - onclose(user, "paicard") - return - -/obj/item/paicard/Topic(href, href_list) - - var/mob/U = usr - - if(!usr || usr.stat) - return - - if(pai) - if(!in_range(src, U)) - U << browse(null, "window=paicard") - usr.unset_machine() - return - - if(href_list["setdna"]) - if(pai.master_dna) - return - var/mob/M = usr - if(!iscarbon(M)) - to_chat(usr, "You don't have any DNA, or your DNA is incompatible with this device.") - else - var/datum/dna/dna = usr.dna - pai.master = M.real_name - pai.master_dna = dna.unique_enzymes - to_chat(pai, "

    You have been bound to a new master.

    ") - if(href_list["request"]) - var/delta = (world.time / 10) - last_request - if(request_cooldown > delta) - var/cooldown_time = round(request_cooldown - ((world.time / 10) - last_request), 1) - to_chat(usr, "The request system is currently offline. Please wait another [cooldown_time] seconds.") - return - last_request = world.time / 10 - looking_for_personality = 1 - GLOB.paiController.findPAI(src, usr) - if(href_list["wipe"]) - var/confirm = tgui_alert(usr, "Are you certain you wish to delete the current personality? This action cannot be undone.", "Personality Wipe", list("No", "Yes")) - if(confirm == "Yes") - for(var/mob/M in src) - to_chat(M, "

    You feel yourself slipping away from reality.

    ") - to_chat(M, "

    Byte by byte you lose your sense of self.

    ") - to_chat(M, "

    Your mental faculties leave you.

    ") - to_chat(M, "
    oblivion...
    ") - var/mob/living/silicon/pai/P = M - if(istype(P)) - if(IS_HORIZONTAL(P)) - P.close_up() - M.death(0, 1) - removePersonality() - if(href_list["wires"]) - var/t1 = text2num(href_list["wires"]) - switch(t1) - if(4) - radio.ToggleBroadcast() - if(2) - radio.ToggleReception() - if(href_list["setlaws"]) - var/newlaws = tgui_input_text(usr, "Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.pai_laws) - if(newlaws) - pai.pai_laws = newlaws - to_chat(pai, "Your supplemental directives have been updated. Your new directives are:") - to_chat(pai, "Prime Directive:
    [pai.pai_law0]") - to_chat(pai, "Supplemental Directives:
    [pai.pai_laws]") - attack_self__legacy__attackchain(usr) - -// WIRE_SIGNAL = 1 -// WIRE_RECEIVE = 2 -// WIRE_TRANSMIT = 4 - -/obj/item/paicard/proc/setPersonality(mob/living/silicon/pai/personality) - pai = personality - overlays += "pai-happy" - -/obj/item/paicard/proc/removePersonality() - pai = null - overlays.Cut() - overlays += "pai-off" - -/obj/item/paicard/proc/setEmotion(emotion) - if(pai) - overlays.Cut() - switch(emotion) - if(1) overlays += "pai-happy" - if(2) overlays += "pai-cat" - if(3) overlays += "pai-extremely-happy" - if(4) overlays += "pai-face" - if(5) overlays += "pai-laugh" - if(6) overlays += "pai-off" - if(7) overlays += "pai-sad" - if(8) overlays += "pai-angry" - if(9) overlays += "pai-what" - current_emotion = emotion - -/obj/item/paicard/proc/alertUpdate() - var/turf/T = get_turf(loc) - for(var/mob/M in viewers(T)) - M.show_message("[src] flashes a message across its screen, \"Additional personalities available for download.\"", 3, "[src] bleeps electronically.", 2) - -/obj/item/paicard/emp_act(severity) - for(var/mob/M in src) - M.emp_act(severity) - ..() - -/obj/item/paicard/extinguish_light(force = FALSE) - if(pai) - pai.extinguish_light() - set_light(0) diff --git a/code/game/objects/items/devices/painter/decal_painter.dm b/code/game/objects/items/devices/painter/decal_painter.dm deleted file mode 100644 index 012e1924e44cf..0000000000000 --- a/code/game/objects/items/devices/painter/decal_painter.dm +++ /dev/null @@ -1,117 +0,0 @@ -/datum/painter/decal - module_name = "decal painter" - module_state = "decal_painter" - /// icon that contains the decal sprites - var/decal_icon = 'icons/turf/decals.dmi' - /// icon_state of the selected decal - var/decal_state = "warn_box" - var/decal_dir = SOUTH - /// When removal_mode is TRUE the decal painter will remove decals instead - var/removal_mode = FALSE - var/max_decals = 3 - var/static/list/decal_blacklist = typecacheof( - list( - /obj/effect/turf_decal/raven, - /obj/effect/turf_decal/weather, - /obj/effect/turf_decal/stripes/asteroid, - /obj/effect/turf_decal/tile, - /obj/effect/turf_decal/sand - ) - ) - /// Assoc list with icon_state of the decal as the key, and decal path as the value. - var/static/list/lookup_cache_decals = list() - -/datum/painter/decal/New(obj/item/painter/parent_painter) - . = ..() - if(!length(lookup_cache_decals)) - for(var/D in subtypesof(/obj/effect/turf_decal)) - var/obj/effect/turf_decal/decal = D - if(decal in decal_blacklist) - continue - lookup_cache_decals[decal::icon_state] = decal - -/datum/painter/decal/paint_atom(atom/target, mob/user) - if(!istype(target, /turf/simulated/floor)) - to_chat(user, "[holder] can only be used on flooring.") - return FALSE - var/turf/target_turf = get_turf(target) - var/list/datum/element/decal/decals = target_turf.get_decals() - if(removal_mode) - remove_decals(target) - return TRUE - if(length(decals) >= max_decals) - to_chat(user, "You can't fit more decals on [target].") - return FALSE - var/typepath = lookup_cache_decals[decal_state] - new typepath(target_turf, decal_dir) - return TRUE - -/datum/painter/decal/pick_color(mob/user) - if(!user) - return - ui_interact(user) - -/datum/painter/decal/ui_state(mob/user) - return GLOB.inventory_state - -/datum/painter/decal/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "DecalPainter", module_name) - ui.set_autoupdate(FALSE) - ui.open() - -/datum/painter/decal/ui_data(mob/user) - var/list/data = list() - data["selectedStyle"] = decal_state - data["selectedDir"] = decal_dir - data["removalMode"] = removal_mode - - return data - - -/datum/painter/decal/ui_static_data(mob/user) - var/list/data = list() - data["icon"] = decal_icon - data["availableStyles"] = list() - for(var/decal in lookup_cache_decals) - data["availableStyles"] += decal - - return data - -/datum/painter/decal/ui_act(action, params) - if(..()) - return - - if(action == "select_style") - var/new_style = params["style"] - if(lookup_cache_decals.Find(new_style) != 0) - decal_state = new_style - removal_mode = FALSE - - if(action == "cycle_style") // Cycles through the available styles one at a time - var/index = lookup_cache_decals.Find(decal_state) // Find the index of the currently selected style in the lookup cache - index += params["offset"] // Offset is either -1 or 1. Add this to the index to get the style before or after the current style. - if(index < 1) // If the index is below 1, loop back to the last item in the cache. - index = length(lookup_cache_decals) - if(index > length(lookup_cache_decals)) // If the index is above the length of the cache, loop back to the first item in the cache. - index = 1 - decal_state = lookup_cache_decals[index] // Then set our state to the index - removal_mode = FALSE - - if(action == "select_direction") - var/dir = params["direction"] - removal_mode = FALSE - if(dir != 0) - decal_dir = dir - - if(action == "removal_mode") - removal_mode = !removal_mode - return TRUE - -/datum/painter/decal/proc/remove_decals(atom/target) - var/turf/target_turf = get_turf(target) - var/list/datum/element/decal/decals = target_turf.get_decals() - for(var/datum/element/decal/dcl in decals) - dcl.Detach(target) - target_turf.RemoveElement(/datum/element/decal) diff --git a/code/game/objects/items/devices/painter/painter.dm b/code/game/objects/items/devices/painter/painter.dm deleted file mode 100644 index 1ea7a9588da4d..0000000000000 --- a/code/game/objects/items/devices/painter/painter.dm +++ /dev/null @@ -1,189 +0,0 @@ -/obj/item/painter - name = "modular painter" - icon = 'icons/obj/painting.dmi' - icon_state = "floor_painter" - usesound = 'sound/effects/spray2.ogg' - flags = CONDUCT | NOBLUDGEON - w_class = WEIGHT_CLASS_SMALL - slot_flags = ITEM_SLOT_BELT - materials = list(MAT_METAL = 5000, MAT_GLASS = 2000) - /// Associative list of painter types, with the value being the datum. (For use in the radial menu) - var/static/list/painter_type_list = list( - "Floor Painter" = /datum/painter/floor, - "Pipe Painter" = /datum/painter/pipe, - "Window Painter" = /datum/painter/pipe/window, - "Airlock Painter" = /datum/painter/airlock, - "Decal Painter" = /datum/painter/decal) - - /// Associative list of painter types, with the value being the icon. (For use in the radial menu) - var/static/list/painter_icon_list = list( - "Floor Painter" = image(icon = 'icons/obj/painting.dmi', icon_state = "floor_painter"), - "Pipe Painter" = image(icon = 'icons/obj/painting.dmi', icon_state = "pipe_painter"), - "Window Painter" = image(icon = 'icons/obj/painting.dmi', icon_state = "window_painter"), - "Airlock Painter" = image(icon = 'icons/obj/painting.dmi', icon_state = "airlock_painter"), - "Decal Painter" = image(icon = 'icons/obj/painting.dmi', icon_state = "decal_painter")) - - /// The [/datum/painter] which is currently active. - var/datum/painter/selected_module = null - /// List of any instanced [/datum/painter]'s, to avoid spawning more than one of each. - var/list/module_list = list() - -/obj/item/painter/Initialize(mapload, datum/painter/default_module = /datum/painter/floor) // Defaults to a floor painter - . = ..() - change_module(default_module) - -/obj/item/painter/Destroy() - selected_module = null - for(var/I in module_list) - qdel(I) - module_list = list() - - return ..() - -/obj/item/painter/examine(mob/user) - . = ..() - . += "Ctrl+click it in your hand to change the type!" - - -/** - * Changes the `selected_module` variable to `new_module`, and updates the painter to reflect the new type. - * - * If `new_module` is already present in `module_list`, then that will be used instead. - * Otherwise a new datum will be spawned and added to `module_list`. - * The Name, Description, Icon State, and Item State of the painter will be updated using variables from the `new_module` datum. - * - * Arguments: - * * datum/painter/new_module - The new painter datum which will be used. - * * mob/user - The user interacting with the painter. - */ -/obj/item/painter/proc/change_module(datum/painter/new_module, mob/user) - if(!new_module) - return - selected_module = null - - for(var/I in module_list) - var/datum/painter/P = I - if(P.type == new_module) - selected_module = I - break - if(!selected_module) - var/datum/painter/P = new new_module(src, src) - module_list += P - selected_module = P - - name = selected_module.module_name - desc = selected_module.module_desc - icon_state = selected_module.module_state - item_state = selected_module.module_state - if(user) - user.update_inv_l_hand() - user.update_inv_r_hand() - -/** - * Calls `pick_color()` on the `selected_module`. - */ -/obj/item/painter/attack_self__legacy__attackchain(mob/user) - selected_module.pick_color(user) - -/** - * If adjacent, calls `paint_atom()` on the `selected_module`, then plays the `usesound`. - */ -/obj/item/painter/afterattack__legacy__attackchain(atom/target, mob/user, proximity, params) - if(!proximity) - return - if(selected_module.paint_atom(target, user)) - playsound(src, usesound, 30, TRUE) - -/** - * Displays a radial menu for choosing a new painter module. - */ -/obj/item/painter/CtrlClick(mob/user) - . = ..() - if(loc != user) // Not being held - return - - playsound(src, 'sound/effects/pop.ogg', 50, TRUE) - var/choice = show_radial_menu(user, src, painter_icon_list, require_near = TRUE) - var/choice_path = painter_type_list[choice] - if(!choice_path || (selected_module.type == choice_path)) - return - - playsound(src, 'sound/machines/click.ogg', 50, TRUE) - do_sparks(1, FALSE, src) - change_module(choice_path, user) - - -/obj/item/painter/suicide_act(mob/user) - user.visible_message("[user] is inhaling toner from [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(src, usesound, 50, TRUE) - var/obj/item/organ/internal/lungs/L = user.get_organ_slot("lungs") // not going to use an organ datum here, would be too easy for slime people to throw up their brains - var/turf/T = get_turf(user) - if(!do_mob(user, user, 3 SECONDS) || !L) - return SHAME - // Once you've inhaled the toner, you throw up your lungs - // and then die. - - L.remove(user) - - L.create_reagents(10) - L.reagents.add_reagent("colorful_reagent", 10) - L.reagents.reaction(L, REAGENT_TOUCH, 1) - L.forceMove(T) - - user.emote("scream") - user.visible_message("[user] vomits out [user.p_their()] [L.name]!") - playsound(T, 'sound/effects/splat.ogg', 50, TRUE) - - // make some vomit under the player, and apply colorful reagent - var/obj/effect/decal/cleanable/vomit/V = new(T) - V.create_reagents(10) - V.reagents.add_reagent("colorful_reagent", 10) - V.reagents.reaction(V, REAGENT_TOUCH, 1) - - return OXYLOSS - - -/** - * # Painter Datum - * - * Contains variables for updating `holder`, as well as procs for choosing a colour and painting an atom. - * - * The `parent_painter` argument is REQUIRED when spawning this in order to link the datum to an [/obj/item/painter]. - */ -/datum/painter - /// Name of the `holder` when using this module. - var/module_name = null - /// Desc of the `holder` when using this module. - var/module_desc = null - /// Icon and Item state of the `holder` when using this module. - var/module_state = null - - /// The parent [/obj/item/painter] which this datum is linked to. - var/obj/item/painter/holder - - /// The current colour or icon state setting. - var/paint_setting = null - -/datum/painter/New(obj/item/painter/parent_painter) - ..() - ASSERT(parent_painter) - holder = parent_painter - -/datum/painter/ui_host() // For TGUI things. - return holder - -/** - * Contains code to choose a new colour or icon state for the `paint_setting` variable. - * - * Called by `attack_self()` on the `holder` object. - */ -/datum/painter/proc/pick_color(mob/user) - return - -/** - * Contains code to apply the `paint_setting` variable onto the target atom. - * - * Called by `afterattack()` on the `holder` object. - */ -/datum/painter/proc/paint_atom(atom/target, mob/user) - return diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm deleted file mode 100644 index 41968cf6af4b7..0000000000000 --- a/code/game/objects/items/devices/powersink.dm +++ /dev/null @@ -1,155 +0,0 @@ -#define DISCONNECTED 0 -#define CLAMPED_OFF 1 -#define OPERATING 2 - -// Powersink - used to drain station power - -/obj/item/powersink - name = "power sink" - desc = "A nulling power sink which drains energy from electrical systems." - icon = 'icons/goonstation/objects/powersink.dmi' - icon_state = "powersink0" - item_state = "electronic" - w_class = WEIGHT_CLASS_BULKY - flags = CONDUCT - throwforce = 5 - throw_speed = 1 - throw_range = 2 - materials = list(MAT_METAL=750) - origin_tech = "powerstorage=5;syndicate=5" - var/drain_rate = 2000000 // amount of power to drain per tick - var/power_drained = 0 // has drained this much power - var/max_power = 6e8 // maximum power that can be drained before exploding - var/mode = 0 // 0 = off, 1=clamped (off), 2=operating - var/admins_warned = FALSE // stop spam, only warn the admins once that we are about to boom - - var/obj/structure/cable/attached // the attached cable - -/obj/item/powersink/Destroy() - STOP_PROCESSING(SSobj, src) - attached = null - return ..() - -/obj/item/powersink/update_icon_state() - icon_state = "powersink[mode == OPERATING]" - -/obj/item/powersink/proc/set_mode(value) - if(value == mode) - return - switch(value) - if(DISCONNECTED) - attached = null - if(mode == OPERATING) - STOP_PROCESSING(SSobj, src) - anchored = FALSE - density = FALSE - - if(CLAMPED_OFF) - if(!attached) - return - if(mode == OPERATING) - STOP_PROCESSING(SSobj, src) - anchored = TRUE - density = TRUE - - if(OPERATING) - if(!attached) - return - START_PROCESSING(SSobj, src) - anchored = TRUE - density = TRUE - - mode = value - update_icon(UPDATE_ICON_STATE) - set_light(0) - -/obj/item/powersink/screwdriver_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - if(mode == DISCONNECTED) - var/turf/T = loc - if(isturf(T) && !T.intact) - attached = locate() in T - if(!attached) - to_chat(user, "No exposed cable here to attach to.") - return - else - set_mode(CLAMPED_OFF) - visible_message("[user] attaches [src] to the cable!") - message_admins("Power sink activated by [key_name_admin(user)] at ([x],[y],[z] - JMP)") - log_game("Power sink activated by [key_name(user)] at ([x],[y],[z])") - else - to_chat(user, "Device must be placed over an exposed cable to attach to it.") - else - set_mode(DISCONNECTED) - src.visible_message("[user] detaches [src] from the cable!") - -/obj/item/powersink/attack_ai() - return - -/obj/item/powersink/attack_hand(mob/user) - switch(mode) - if(DISCONNECTED) - ..() - if(CLAMPED_OFF) - user.visible_message( \ - "[user] activates \the [src]!", \ - "You activate \the [src].", - "You hear a click.") - message_admins("Power sink activated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_VERBOSEJMP(src)]") - log_game("Power sink activated by [key_name(user)] at [AREACOORD(src)]") - notify_ghosts("[user] has activated a [name]!", title = "An electrifying occurrence! (Click to follow)", source = src, flashwindow = FALSE, action = NOTIFY_FOLLOW) - set_mode(OPERATING) - - if(OPERATING) - user.visible_message( \ - "[user] deactivates \the [src]!", \ - "You deactivate \the [src].", - "You hear a click.") - set_mode(CLAMPED_OFF) - -/obj/item/powersink/process() - if(!attached) - set_mode(DISCONNECTED) - return - - var/datum/regional_powernet/PN = attached.powernet - if(PN) - set_light(5) - - // found a powernet, so drain up to max power from it - - var/drained = min(drain_rate, attached.get_queued_surplus()) - attached.add_queued_power_demand(drained) - power_drained += drained - - // if tried to drain more than available on powernet - // now look for APCs and drain their cells - if(drained < drain_rate) - for(var/obj/machinery/power/terminal/T in PN.nodes) - if(istype(T.master, /obj/machinery/power/apc)) - var/obj/machinery/power/apc/A = T.master - if(A.operating && A.cell) - A.cell.charge = max(0, A.cell.charge - 50) - power_drained += 50 - if(A.charging == APC_FULLY_CHARGED) // If the cell was full - A.charging = APC_IS_CHARGING // It's no longer full - if(drained >= drain_rate) - break - - if(power_drained > max_power * 0.98) - if(!admins_warned) - admins_warned = TRUE - message_admins("Power sink at ([x],[y],[z] - JMP) is 95% full. Explosion imminent.") - notify_ghosts("A [name] is almost at max capacity, and is about to explode!", title = "An electrifying occurrence! (Click to follow)", source = src, flashwindow = FALSE, action = NOTIFY_FOLLOW) - playsound(src, 'sound/effects/screech.ogg', 100, TRUE, 1) - - if(power_drained >= max_power) - STOP_PROCESSING(SSobj, src) - explosion(src.loc, 4,8,16,32) - qdel(src) - -#undef DISCONNECTED -#undef CLAMPED_OFF -#undef OPERATING diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm deleted file mode 100644 index d63301a424dc4..0000000000000 --- a/code/game/objects/items/devices/radio/beacon.dm +++ /dev/null @@ -1,178 +0,0 @@ -/obj/item/beacon - name = "tracking beacon" - desc = "A beacon used by a teleporter." - icon = 'icons/obj/radio.dmi' - icon_state = "beacon" - item_state = "signaler" - origin_tech = "bluespace=1" - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - throw_speed = 2 - throw_range = 9 - w_class = WEIGHT_CLASS_SMALL - - materials = list(MAT_METAL = 200, MAT_GLASS = 100) - var/syndicate = FALSE - var/area_bypass = FALSE - var/cc_beacon = FALSE //set if allowed to teleport to even if on zlevel2 - var/wormhole_weaver = FALSE // special beacons for wormwhole weaver - -/obj/item/beacon/Initialize(mapload) - . = ..() - GLOB.beacons |= src - -/obj/item/beacon/Destroy() - GLOB.beacons -= src - return ..() - -/obj/item/beacon/emag_act(user) - if(!emagged) - emagged = TRUE - syndicate = TRUE - to_chat(user, "The This beacon now only be locked on to by emagged teleporters!") - return TRUE - - -/// Probably a better way of doing this, I'm lazy. -/obj/item/beacon/bacon - -/obj/item/beacon/bacon/proc/digest_delay() - QDEL_IN(src, 60 SECONDS) - -/obj/item/beacon/emagged - syndicate = TRUE - emagged = TRUE - -// SINGULO BEACON SPAWNER -/obj/item/beacon/syndicate - name = "suspicious beacon" - desc = "A label on it reads: Activate to have a singularity beacon teleported to your location." - origin_tech = "bluespace=6;syndicate=5" - syndicate = TRUE - var/obj/machinery/computer/syndicate_depot/teleporter/mycomputer - -/obj/item/beacon/syndicate/Destroy() - if(mycomputer) - mycomputer.mybeacon = null - return ..() - -/obj/item/beacon/syndicate/attack_self__legacy__attackchain(mob/user) - if(user) - to_chat(user, "Locked In") - new /obj/machinery/power/singularity_beacon/syndicate( user.loc ) - playsound(src, 'sound/effects/pop.ogg', 100, TRUE, 1) - user.drop_item() - qdel(src) - -/obj/item/beacon/syndicate/bundle - name = "suspicious beacon" - desc = "A label on it reads: Activate to select a bundle." - var/list/static/bundles = list( - "Spy" = /obj/item/storage/box/syndie_kit/bundle/spy, - "Agent 13" = /obj/item/storage/box/syndie_kit/bundle/agent13, - "Thief" = /obj/item/storage/box/syndie_kit/bundle/thief, - "Agent 007" = /obj/item/storage/box/syndie_kit/bundle/bond, - "Infiltrator" = /obj/item/storage/box/syndie_kit/bundle/infiltrator, - "Bank Robber" = /obj/item/storage/box/syndie_kit/bundle/payday, - "Implanter" = /obj/item/storage/box/syndie_kit/bundle/implant, - "Hacker" = /obj/item/storage/box/syndie_kit/bundle/hacker, - "Dark Lord" = /obj/item/storage/box/syndie_kit/bundle/darklord, - "Sniper" = /obj/item/storage/box/syndie_kit/bundle/professional, - "Grenadier" = /obj/item/storage/box/syndie_kit/bundle/grenadier, - "Augmented" = /obj/item/storage/box/syndie_kit/bundle/metroid, - "Ocelot" = /obj/item/storage/box/syndie_kit/bundle/ocelot, - "Nuclear Wannabe" = /obj/item/storage/box/syndie_kit/bundle/operative, - "Big Spender" = /obj/item/storage/box/syndie_kit/bundle/rich, - "Maintenance Collector" = /obj/item/storage/box/syndie_kit/bundle/maint_loot) - var/list/selected = list() - var/list/unselected = list() - -/obj/item/beacon/syndicate/bundle/attack_self__legacy__attackchain(mob/user) - if(!user) - return - - if(!length(selected)) - unselected = bundles.Copy() - for(var/i in 1 to 3) - selected += pick_n_take(unselected) - selected += "Random" - - var/bundle_name = tgui_input_list(user, "Available Bundles", "Bundle Selection", selected) - if(!bundle_name || QDELETED(src)) - return - - if(bundle_name == "Random") - bundle_name = pick(unselected) - var/bundle = bundles[bundle_name] - bundle = new bundle(user.loc) - to_chat(user, "Welcome to [station_name()], [bundle_name]!") - user.drop_item() - SSblackbox.record_feedback("tally", "syndicate_bundle_pick", 1, "[bundle]") - qdel(src) - user.put_in_hands(bundle) - -/obj/item/beacon/syndicate/power_sink - name = "suspicious beacon" - desc = "A label on it reads: Warning: Activating this device will send a power sink to your location." - -/obj/item/beacon/syndicate/power_sink/attack_self__legacy__attackchain(mob/user) - if(user) - to_chat(user, "Locked In") - new /obj/item/powersink(user.loc) - playsound(src, 'sound/effects/pop.ogg', 100, TRUE, 1) - user.drop_item() - qdel(src) - -/obj/item/beacon/syndicate/bomb - name = "suspicious beacon" - desc = "A label on it reads: Warning: Activating this device will send a high-ordinance explosive to your location." - origin_tech = "bluespace=5;syndicate=5" - var/bomb = /obj/machinery/syndicatebomb - -/obj/item/beacon/syndicate/bomb/attack_self__legacy__attackchain(mob/user) - if(user) - to_chat(user, "Locked In") - new bomb(user.loc) - playsound(src, 'sound/effects/pop.ogg', 100, TRUE, 1) - user.drop_item() - qdel(src) - -/obj/item/beacon/syndicate/bomb/emp - desc = "A label on it reads: Warning: Activating this device will send a high-ordinance EMP explosive to your location." - bomb = /obj/machinery/syndicatebomb/emp - -/obj/item/beacon/syndicate/bomb/grey_autocloner - desc = "A label on it reads: Warning: Activating this device will send an expensive cloner to your location." - origin_tech = "bluespace=2;syndicate=2" - bomb = /obj/machinery/grey_autocloner - -/obj/item/beacon/engine - desc = "A label on it reads: Warning: This device is used for transportation of high-density objects used for high-yield power generation. Stay away!." - anchored = TRUE //Let's not move these around. Some folk might get the idea to use these for assassinations - var/list/enginetype = list() - -/obj/item/beacon/engine/Initialize(mapload) - LAZYADD(GLOB.engine_beacon_list, src) - return ..() - -/obj/item/beacon/engine/Destroy() - GLOB.engine_beacon_list -= src - return ..() - -/obj/item/beacon/engine/tesling - name = "Engine Beacon for Tesla and Singularity" - enginetype = list(ENGTYPE_TESLA, ENGTYPE_SING) - -/obj/item/beacon/engine/tesla - name = "Engine Beacon for Tesla" - enginetype = list(ENGTYPE_TESLA) - -/obj/item/beacon/engine/sing - name = "Engine Beacon for Singularity" - enginetype = list(ENGTYPE_SING) - -/obj/item/beacon/wormhole_weaver - name = "prototype beacon" - desc = "A beacon used by a prototype wormhole device." - wormhole_weaver = TRUE - icon_state = "beacon_wormhole_weaver" diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm deleted file mode 100644 index d8ba0c62e1291..0000000000000 --- a/code/game/objects/items/devices/radio/electropack.dm +++ /dev/null @@ -1,154 +0,0 @@ -/obj/item/electropack - name = "electropack" - desc = "Dance my monkeys! DANCE!!!" - icon = 'icons/obj/radio.dmi' - icon_state = "electropack0" - item_state = "electropack" - flags = CONDUCT - slot_flags = ITEM_SLOT_BACK - w_class = WEIGHT_CLASS_HUGE - materials = list(MAT_METAL = 10000, MAT_GLASS = 2500) - /// The integrated signaler - var/obj/item/assembly/signaler/electropack/integrated_signaler - -/obj/item/electropack/Initialize(mapload) - . = ..() - integrated_signaler = new /obj/item/assembly/signaler/electropack(src, src) // Loc and the integrated one - -/obj/item/electropack/Destroy() - integrated_signaler.owning_pack = null - QDEL_NULL(integrated_signaler) - - if(istype(loc, /obj/item/assembly/shock_kit)) - var/obj/item/assembly/shock_kit/S = loc - if(S.part1 == src) - S.part1 = null - - else if(S.part2 == src) - S.part2 = null - - master = null - - return ..() - -/obj/item/electropack/attack_hand(mob/user) - if(src == user.back) - to_chat(user, "You need help taking this off!") - return FALSE - - ..() - -/obj/item/electropack/attack_self__legacy__attackchain(mob/user) - ui_interact(user) - -/obj/item/electropack/attackby__legacy__attackchain(obj/item/W, mob/user, params) - ..() - - if(istype(W, /obj/item/clothing/head/helmet)) - var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit(user) - A.icon = 'icons/obj/assemblies.dmi' - - if(!user.unequip(W)) - to_chat(user, "\the [W] is stuck to your hand, you cannot attach it to \the [src]!") - return - - W.forceMove(A) - W.master = A - A.part1 = W - - user.transfer_item_to(src, A) - master = A - A.part2 = src - - user.put_in_hands(A) - A.add_fingerprint(user) - if(src.flags & NODROP) - A.flags |= NODROP - - -/obj/item/electropack/proc/handle_shock() - if(istype(master, /obj/item/assembly/shock_kit)) - var/obj/item/assembly/shock_kit/SK = master - SK.shock_invoke() - - if(isliving(loc)) - var/mob/living/M = loc - to_chat(M, "You feel a sharp shock!") - do_sparks(3, 1, M) - - M.Weaken(10 SECONDS) - -// This should honestly just proxy the UI to the internal signaler -/obj/item/electropack/ui_state(mob/user) - return GLOB.inventory_state - -/obj/item/electropack/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "Electropack", name) - ui.open() - -/obj/item/electropack/ui_data(mob/user) - var/list/data = list() - data["power"] = integrated_signaler.receiving - data["frequency"] = integrated_signaler.frequency - data["code"] = integrated_signaler.code - data["minFrequency"] = PUBLIC_LOW_FREQ - data["maxFrequency"] = PUBLIC_HIGH_FREQ - return data - -/obj/item/electropack/ui_act(action, list/params) - if(..()) - return - - . = TRUE - - switch(action) - if("power") - integrated_signaler.receiving = !integrated_signaler.receiving - - if("freq") - var/value = params["freq"] - if(value) - integrated_signaler.frequency = sanitize_frequency(value) - else - . = FALSE - - if("code") - var/value = text2num(params["code"]) - if(value) - value = round(value) - integrated_signaler.code = clamp(value, 1, 100) - else - . = FALSE - - if("reset") - if(params["reset"] == "freq") - integrated_signaler.frequency = initial(integrated_signaler.frequency) - else if(params["reset"] == "code") - integrated_signaler.code = initial(integrated_signaler.code) - else - . = FALSE - - if(.) - add_fingerprint(usr) - -// Electropack signaller type -/obj/item/assembly/signaler/electropack - frequency = AIRLOCK_FREQ - code = 2 - receiving = TRUE - - var/obj/item/electropack/owning_pack - -/obj/item/assembly/signaler/electropack/Initialize(mapload, holding_electropack) - . = ..() - owning_pack = holding_electropack - -/obj/item/assembly/signaler/electropack/signal_callback() - if(owning_pack) - owning_pack.handle_shock() - -/obj/item/assembly/signaler/electropack/Destroy() - owning_pack = null - return ..() diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm deleted file mode 100644 index a1999c826e88a..0000000000000 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ /dev/null @@ -1,179 +0,0 @@ - -/obj/item/encryptionkey - name = "Standard Encryption Key" - desc = "An encyption key for a radio headset. Contains cypherkeys." - icon = 'icons/obj/radio.dmi' - icon_state = "cypherkey" - item_state = "" - w_class = WEIGHT_CLASS_TINY - origin_tech = "engineering=2;bluespace=1" - var/translate_binary = FALSE - var/translate_hive = FALSE - var/syndie = FALSE - var/change_voice = FALSE - var/list/channels = list() - -/obj/item/encryptionkey/syndicate - name = "syndicate encryption key" - icon_state = "syn_cypherkey" - channels = list("Syndicate" = 1) - origin_tech = "syndicate=1;engineering=3;bluespace=2" - syndie = TRUE //Signifies that it de-crypts Syndicate transmissions - change_voice = TRUE - var/fake_name = "Agent ALERT_A_CODER" - var/static/list/fakename_list - -/obj/item/encryptionkey/syndicate/Initialize(mapload) - if(!LAZYLEN(fakename_list)) - fakename_list = GLOB.html_colors.Copy() - . = ..() - if(change_voice) - fake_name = "Agent [pick_n_take(fakename_list)]" - -/obj/item/encryptionkey/syndicate/nukeops - change_voice = FALSE - -/obj/item/encryptionkey/syndteam - name = "syndicate encryption key" - icon_state = "syn_cypherkey" - channels = list("SyndTeam" = 1, "Syndicate" = 1) - origin_tech = "syndicate=4" - syndie = TRUE //Signifies that it de-crypts Syndicate transmissions - -/obj/item/encryptionkey/soviet - name = "soviet encryption key" - icon_state = "cypherkey" - channels = list("Special Ops" = 1) - origin_tech = "syndicate=4" - -/obj/item/encryptionkey/binary - name = "binary translator key" - desc = "An encryption key for a radio headset. To access the binary channel, use :+." - icon_state = "bin_cypherkey" - translate_binary = TRUE - origin_tech = "syndicate=3;engineering=4;bluespace=3" - -/obj/item/encryptionkey/headset_sec - name = "Security Radio Encryption Key" - icon_state = "sec_cypherkey" - channels = list("Security" = 1) - -/obj/item/encryptionkey/headset_iaa - name = "IAA Radio Encryption Key" - icon_state = "sec_cypherkey" - channels = list("Security" = 1, "Procedure" = 1) - -/obj/item/encryptionkey/headset_eng - name = "Engineering Radio Encryption Key" - icon_state = "eng_cypherkey" - channels = list("Engineering" = 1) - -/obj/item/encryptionkey/headset_rob - name = "Robotics Radio Encryption Key" - icon_state = "rob_cypherkey" - channels = list("Engineering" = 1, "Science" = 1) - -/obj/item/encryptionkey/headset_med - name = "Medical Radio Encryption Key" - icon_state = "med_cypherkey" - channels = list("Medical" = 1) - -/obj/item/encryptionkey/headset_med/para - name = "Paramedic Radio Encryption Key" - icon_state = "para_cypherkey" - channels = list("Medical" = 1, "Supply" = 0) - -/obj/item/encryptionkey/headset_sci - name = "Science Radio Encryption Key" - icon_state = "sci_cypherkey" - channels = list("Science" = 1) - -/obj/item/encryptionkey/headset_medsci - name = "Medical Research Radio Encryption Key" - icon_state = "medsci_cypherkey" - channels = list("Medical" = 1, "Science" = 1) - -/obj/item/encryptionkey/headset_com - name = "Command Radio Encryption Key" - icon_state = "com_cypherkey" - channels = list("Command" = 1) - -/obj/item/encryptionkey/heads/captain - name = "Captain's Encryption Key" - icon_state = "cap_cypherkey" - channels = list("Command" = 1, "Security" = 1, "Engineering" = 0, "Science" = 0, "Medical" = 0, "Supply" = 0, "Service" = 0, "Procedure" = 1) - -/obj/item/encryptionkey/heads/rd - name = "Research Director's Encryption Key" - icon_state = "rd_cypherkey" - channels = list("Science" = 1, "Command" = 1) - -/obj/item/encryptionkey/heads/hos - name = "Head of Security's Encryption Key" - icon_state = "hos_cypherkey" - channels = list("Security" = 1, "Command" = 1) - -/obj/item/encryptionkey/heads/ce - name = "Chief Engineer's Encryption Key" - icon_state = "ce_cypherkey" - channels = list("Engineering" = 1, "Command" = 1) - -/obj/item/encryptionkey/heads/cmo - name = "Chief Medical Officer's Encryption Key" - icon_state = "cmo_cypherkey" - channels = list("Medical" = 1, "Command" = 1) - -/obj/item/encryptionkey/heads/hop - name = "Head of Personnel's Encryption Key" - icon_state = "hop_cypherkey" - channels = list("Service" = 1, "Security" = 0, "Command" = 1) - -/obj/item/encryptionkey/heads/qm - name = "Quartermaster's Encryption Key" - icon_state = "qm_cypherkey" - channels = list("Supply" = 1, "Command" = 1) - -/obj/item/encryptionkey/heads/ntrep - name = "Nanotrasen Representative's Encryption Key" - icon_state = "com_cypherkey" - channels = list("Command" = 1, "Security" = 0, "Engineering" = 0, "Science" = 0, "Medical" = 0, "Supply" = 0, "Service" = 0, "Procedure" = 1) - -/obj/item/encryptionkey/heads/magistrate - name = "Magistrate's Encryption Key" - icon_state = "com_cypherkey" - channels = list("Command" = 1, "Security" = 1, "Procedure" = 1) - -/obj/item/encryptionkey/heads/blueshield - name = "Blueshield's Encryption Key" - icon_state = "com_cypherkey" - channels = list("Command" = 1, "Security" = 1) - -/obj/item/encryptionkey/headset_cargo - name = "Supply Radio Encryption Key" - icon_state = "cargo_cypherkey" - channels = list("Supply" = 1) - -/obj/item/encryptionkey/headset_service - name = "Service Radio Encryption Key" - icon_state = "srv_cypherkey" - channels = list("Service" = 1) - -/obj/item/encryptionkey/ert - name = "Nanotrasen ERT Radio Encryption Key" - channels = list("Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Supply" = 1, "Service" = 1, "Procedure" = 1) - -/obj/item/encryptionkey/centcom - name = "Centcom Radio Encryption Key" - channels = list("Response Team" = 1, "Special Ops" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Supply" = 1, "Service" = 1, "Procedure" = 1) - -/// ported from bay, this goes 'inside' the AI. -/obj/item/encryptionkey/heads/ai_integrated - name = "AI Integrated Encryption Key" - desc = "Integrated encryption key." - icon_state = "cap_cypherkey" - channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1, "AI Private" = 1, "Procedure" = 1) - -/obj/item/encryptionkey/headset_nct - name = "NCT Radio Encryption Key" - icon_state = "com_cypherkey" - channels = list("Procedure" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1) diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm deleted file mode 100644 index e9811960327fa..0000000000000 --- a/code/game/objects/items/devices/radio/intercom.dm +++ /dev/null @@ -1,308 +0,0 @@ -/obj/item/radio/intercom - name = "station intercom (General)" - desc = "A reliable form of communication even during local communication blackouts." - icon_state = "intercom" - layer = ABOVE_WINDOW_LAYER - anchored = TRUE - w_class = WEIGHT_CLASS_BULKY - canhear_range = 2 - flags = CONDUCT - blocks_emissive = FALSE - var/circuitry_installed = 1 - var/buildstage = 0 - var/custom_name - dog_fashion = null - -/obj/item/radio/intercom/custom - name = "station intercom (Custom)" - custom_name = TRUE - broadcasting = FALSE - listening = FALSE - -/obj/item/radio/intercom/interrogation - name = "station intercom (Interrogation)" - custom_name = TRUE - frequency = AIRLOCK_FREQ - -/obj/item/radio/intercom/private - name = "station intercom (Private)" - custom_name = TRUE - frequency = AI_FREQ - -/obj/item/radio/intercom/command - name = "station intercom (Command)" - custom_name = TRUE - frequency = COMM_FREQ - -/obj/item/radio/intercom/specops - name = "\improper Special Operations intercom" - custom_name = TRUE - frequency = ERT_FREQ - -/obj/item/radio/intercom/department - canhear_range = 5 - custom_name = TRUE - broadcasting = FALSE - listening = TRUE - -/obj/item/radio/intercom/department/medbay - name = "station intercom (Medbay)" - frequency = MED_I_FREQ - -/obj/item/radio/intercom/department/security - name = "station intercom (Security)" - frequency = SEC_I_FREQ - -/obj/item/radio/intercom/New(turf/loc, direction, building = 3) - . = ..() - buildstage = building - if(buildstage) - update_operating_status() - else - if(direction) - setDir(direction) - set_pixel_offsets_from_dir(28, -28, 28, -28) - b_stat = TRUE - on = FALSE - GLOB.global_intercoms.Add(src) - update_icon(UPDATE_ICON_STATE | UPDATE_OVERLAYS) - -/obj/item/radio/intercom/Initialize(mapload) - . = ..() - if(!custom_name) - name = "station intercom (General)" - -/obj/item/radio/intercom/department/medbay/New() - ..() - internal_channels = GLOB.default_medbay_channels.Copy() - -/obj/item/radio/intercom/department/security/New() - ..() - internal_channels = list( - num2text(PUB_FREQ) = list(), - num2text(SEC_I_FREQ) = list(ACCESS_SECURITY) - ) - -/obj/item/radio/intercom/syndicate - name = "illicit intercom" - desc = "Communicate with your minions. Evilly" - frequency = SYND_FREQ - syndiekey = new /obj/item/encryptionkey/syndicate/nukeops - -/obj/item/radio/intercom/syndicate/New() - ..() - internal_channels[num2text(SYND_FREQ)] = list(ACCESS_SYNDICATE) - -/obj/item/radio/intercom/pirate - name = "pirate radio intercom" - desc = "You wouldn't steal a space shuttle. Piracy. It's a crime!" - -/obj/item/radio/intercom/pirate/New() - ..() - internal_channels.Cut() - internal_channels = list( - num2text(PUB_FREQ) = list(), - num2text(AI_FREQ) = list(), - num2text(COMM_FREQ)= list(), - num2text(ENG_FREQ) = list(), - num2text(MED_FREQ) = list(), - num2text(MED_I_FREQ)=list(), - num2text(SEC_FREQ) = list(), - num2text(SEC_I_FREQ)=list(), - num2text(SCI_FREQ) = list(), - num2text(SUP_FREQ) = list(), - num2text(SRV_FREQ) = list() - ) - -/obj/item/radio/intercom/Destroy() - GLOB.global_intercoms.Remove(src) - return ..() - -/obj/item/radio/intercom/attack_ai(mob/user) - add_hiddenprint(user) - add_fingerprint(user) - attack_self__legacy__attackchain(user) - -/obj/item/radio/intercom/attack_hand(mob/user) - add_fingerprint(user) - attack_self__legacy__attackchain(user) - -/obj/item/radio/intercom/receive_range(freq, level) - if(!is_listening()) - return -1 - if(!(0 in level)) - var/turf/position = get_turf(src) - // TODO: Integrate radio with the space manager - if(isnull(position) || !(position.z in level)) - return -1 - if(freq in SSradio.ANTAG_FREQS) - if(!(syndiekey)) - return -1//Prevents broadcast of messages over devices lacking the encryption - - return canhear_range - -/obj/item/radio/intercom/examine(mob/user) - . = ..() - switch(buildstage) - if(0) - . += "The frame is welded to the wall, but missing circuitry." - if(1) - . += "The speaker needs to be wired, though the board could be pried out." - if(2) - . += "The intercom is wired, and the maintenance panel is unscrewed." - -/obj/item/radio/intercom/attackby__legacy__attackchain(obj/item/W, mob/user) - if(istype(W, /obj/item/stack/tape_roll)) //eww - return - else if(iscoil(W) && buildstage == 1) - var/obj/item/stack/cable_coil/coil = W - if(coil.get_amount() < 5) - to_chat(user, "You need more cable for this!") - return - if(do_after(user, 10 * coil.toolspeed, target = src) && buildstage == 1) - coil.use(5) - to_chat(user, "You wire \the [src]!") - buildstage = 2 - return 1 - else if(istype(W,/obj/item/intercom_electronics) && buildstage == 0) - playsound(get_turf(src), W.usesound, 50, 1) - if(do_after(user, 10 * W.toolspeed, target = src) && buildstage == 0) - qdel(W) - to_chat(user, "You insert \the [W] into \the [src]!") - buildstage = 1 - return 1 - else - return ..() - -/obj/item/radio/intercom/AltClick(mob/user) - . = ..() - if(broadcasting) - investigate_log("had its hotmic toggled on via hotkey by [key_name(user)].", INVESTIGATE_HOTMIC) ///Allows us to track who spams all these on if they do. - -/obj/item/radio/intercom/crowbar_act(mob/user, obj/item/I) - if(buildstage != 1) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - to_chat(user, "You begin removing the electronics...") - if(!I.use_tool(src, user, 10, volume = I.tool_volume) || buildstage != 1) - return - new /obj/item/intercom_electronics(get_turf(src)) - to_chat(user, "The circuit board pops out!") - buildstage = 0 - -/obj/item/radio/intercom/screwdriver_act(mob/user, obj/item/I) - if(buildstage != 2) - return ..() - . = TRUE - if(!I.tool_use_check(user, 0)) - return - if(!I.use_tool(src, user, 10, volume = I.tool_volume) || buildstage != 2) - return - update_icon(UPDATE_ICON_STATE) - on = TRUE - b_stat = FALSE - buildstage = 3 - to_chat(user, "You secure the electronics!") - update_icon(UPDATE_ICON_STATE) - update_operating_status() - for(var/i, i<= 5, i++) - wires.on_cut(i, 1) - -/obj/item/radio/intercom/wirecutter_act(mob/user, obj/item/I) - if(!(buildstage == 3 && b_stat && wires.is_all_cut())) - return ..() - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - WIRECUTTER_SNIP_MESSAGE - new /obj/item/stack/cable_coil(get_turf(src),5) - on = FALSE - b_stat = TRUE - buildstage = 1 - update_icon(UPDATE_ICON_STATE | UPDATE_OVERLAYS) - update_operating_status(FALSE) - -/obj/item/radio/intercom/welder_act(mob/user, obj/item/I) - if(buildstage != 0) - return - . = TRUE - if(!I.tool_use_check(user, 3)) - return - to_chat(user, "You start slicing [src] from the wall...") - if(I.use_tool(src, user, 10, amount = 3, volume = I.tool_volume)) - to_chat(user, "You cut [src] free from the wall!") - new /obj/item/mounted/frame/intercom(get_turf(src)) - qdel(src) - -/obj/item/radio/intercom/update_icon_state() - if(!circuitry_installed) - icon_state="intercom-frame" - else - icon_state = "intercom[!on?"-p":""][b_stat ? "-open":""]" - -/obj/item/radio/intercom/update_overlays() - . = ..() - underlays.Cut() - - if(on && buildstage == 3) - underlays += emissive_appearance(icon, "intercom_lightmask") - -/obj/item/radio/intercom/proc/update_operating_status(on = TRUE) - if(!loc) // We init a few radios in nullspace to prevent them from needing power. - return - var/area/current_area = get_area(src) - if(on) - RegisterSignal(current_area.powernet, COMSIG_POWERNET_POWER_CHANGE, PROC_REF(local_powernet_check)) - else - UnregisterSignal(current_area.powernet, COMSIG_POWERNET_POWER_CHANGE) - -/** - * Proc called whenever the intercom's local powernet loses or gains power. Responsible for setting the `on` variable and calling `update_icon()`. - * - * Normally called after the intercom's local powernet sends the `COMSIG_POWERNET_POWER_CHANGE` signal, but it can also be called directly. - * Arguments: - * - * source - the area that just had a power change. - */ -/obj/item/radio/intercom/proc/local_powernet_check(datum/source) - var/area/current_area = get_area(src) - if(!current_area) - on = FALSE - set_light(0) - else - on = current_area.powernet.has_power(PW_CHANNEL_EQUIPMENT) // set "on" to the equipment power status of our area. - set_light(1, LIGHTING_MINIMUM_POWER) - update_icon(UPDATE_ICON_STATE | UPDATE_OVERLAYS) - -/obj/item/intercom_electronics - name = "intercom electronics" - icon = 'icons/obj/doors/door_assembly.dmi' - icon_state = "door_electronics" - desc = "Looks like a circuit. Probably is." - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL = 100, MAT_GLASS = 100) - origin_tech = "engineering=2;programming=1" - toolspeed = 1 - usesound = 'sound/items/deconstruct.ogg' - -/obj/item/radio/intercom/locked - freqlock = TRUE - custom_name = TRUE - -/obj/item/radio/intercom/locked/ai_private - name = "\improper AI intercom" - frequency = AI_FREQ - -/obj/item/radio/intercom/locked/confessional - name = "confessional intercom" - frequency = 1480 - -/obj/item/radio/intercom/locked/prison - name = "prison intercom" - desc = "A reliable form of communication even during local communication blackouts. It looks like it has been modified to not broadcast. Not so reliable, I guess..." - -/obj/item/radio/intercom/locked/prison/New() - ..() - wires.cut(WIRE_RADIO_TRANSMIT) diff --git a/code/game/objects/items/devices/sensor_device.dm b/code/game/objects/items/devices/sensor_device.dm deleted file mode 100644 index de6c40b98821c..0000000000000 --- a/code/game/objects/items/devices/sensor_device.dm +++ /dev/null @@ -1,26 +0,0 @@ -/obj/item/sensor_device - name = "handheld crew monitor" - desc = "A miniature machine that tracks suit sensors across the station." - icon = 'icons/obj/device.dmi' - icon_state = "scanner" - w_class = WEIGHT_CLASS_SMALL - slot_flags = ITEM_SLOT_BELT - origin_tech = "programming=3;materials=3;magnets=3" - var/datum/ui_module/crew_monitor/crew_monitor - -/obj/item/sensor_device/New() - ..() - crew_monitor = new(src) - -/obj/item/sensor_device/Destroy() - QDEL_NULL(crew_monitor) - return ..() - -/obj/item/sensor_device/attack_self__legacy__attackchain(mob/user as mob) - ui_interact(user) - -/obj/item/sensor_device/ui_state(mob/user) - return GLOB.default_state - -/obj/item/sensor_device/ui_interact(mob/user, datum/tgui/ui = null) - crew_monitor.ui_interact(user, ui) diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm deleted file mode 100644 index ef64e9412ac47..0000000000000 --- a/code/game/objects/items/devices/taperecorder.dm +++ /dev/null @@ -1,357 +0,0 @@ -/obj/item/taperecorder - name = "universal recorder" - desc = "A device that can record to cassette tapes, and play them. It automatically translates the content in playback." - icon = 'icons/obj/device.dmi' - icon_state = "taperecorder_empty" - item_state = "analyzer" - w_class = WEIGHT_CLASS_SMALL - slot_flags = ITEM_SLOT_BELT - materials = list(MAT_METAL = 180, MAT_GLASS = 90) - force = 2 - throwforce = 0 - drop_sound = 'sound/items/handling/taperecorder_drop.ogg' - pickup_sound = 'sound/items/handling/taperecorder_pickup.ogg' - /// If its currently recording - var/recording - /// If its playing back auto via atom_say - var/playing - /// The amount of time between something said during playback - var/playsleepseconds = 0 - /// The tape we are recording to - var/obj/item/tape/mytape - /// The next worldtime we'll be able to print - var/cooldown = 0 - var/starts_with_tape = TRUE - /// Sound loop that plays when recording or playing back. - var/datum/looping_sound/tape_recorder_hiss/soundloop - -/obj/item/taperecorder/examine(mob/user) - . = ..() - if(in_range(user, src) && mytape) - if(mytape.ruined) - . += "[mytape]'s internals are unwound.'." - if(mytape.max_capacity <= mytape.used_capacity) - . += "[mytape] is full." - else if((mytape.remaining_capacity % 60) == 0) // if there is no seconds (modulo = 0), then only show minutes - . += "[mytape] has [mytape.remaining_capacity / 60] minutes remaining." - else - if(mytape.used_capacity >= mytape.max_capacity - 60) - . += "[mytape] has [mytape.remaining_capacity] seconds remaining." // to avoid having 0 minutes - else - . += "[mytape] has [seconds_to_time(mytape.remaining_capacity)] remaining." - . += "Alt-Click to access the tape." - -/obj/item/taperecorder/New() - ..() - if(starts_with_tape) - mytape = new /obj/item/tape/random(src) - update_icon(UPDATE_ICON_STATE) - soundloop = new(list(src)) - -/obj/item/taperecorder/Destroy() - QDEL_NULL(mytape) - QDEL_NULL(soundloop) - return ..() - -/obj/item/taperecorder/proc/update_sound() - if(!playing && !recording) - soundloop.stop() - else - soundloop.start() - -/obj/item/taperecorder/attackby__legacy__attackchain(obj/item/I, mob/user) - if(!mytape && istype(I, /obj/item/tape)) - if(user.drop_item()) - I.forceMove(src) - mytape = I - to_chat(user, "You insert [I] into [src].") - playsound(src, 'sound/items/taperecorder/taperecorder_close.ogg', 50, FALSE) - update_icon(UPDATE_ICON_STATE) - -/obj/item/taperecorder/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - mytape?.ruin() //Fires destroy the tape - return ..() - -/obj/item/taperecorder/attack_hand(mob/user) - if(loc == user) - if(mytape) - if(!user.is_holding(src)) - ..() - return - eject(user) - return - ..() - -/obj/item/taperecorder/hear_talk(mob/living/M, list/message_pieces) // Currently can't tell if you're whispering, but can hear it if nearby - var/msg = multilingual_to_message(message_pieces) - if(mytape && recording) - var/ending = copytext(msg, length(msg)) - mytape.timestamp += mytape.used_capacity - if(M.AmountStuttering()) - mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] stammers, \"[msg]\"" - return - if(M.getBrainLoss() >= 60) - mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] gibbers, \"[msg]\"" - return - if(ending == "?") - mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] asks, \"[msg]\"" - return - else if(ending == "!") - mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] exclaims, \"[msg]\"" - return - mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] says, \"[msg]\"" - -/obj/item/taperecorder/hear_message(mob/living/M as mob, msg) - if(mytape && recording) - mytape.timestamp += mytape.used_capacity - mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] [msg]" - -/obj/item/taperecorder/attack_self__legacy__attackchain(mob/user) - if(!mytape || mytape.ruined) - return - if(recording) - stop() - else - record() - -/obj/item/taperecorder/AltClick(mob/user) - if(in_range(user, src) && mytape && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) - var/list/options = list( - "Playback Tape" = image(icon = 'icons/obj/device.dmi', icon_state = "taperecorder_playing"), - "Print Transcript" = image(icon = 'icons/obj/bureaucracy.dmi', icon_state = "paper_words"), - "Eject Tape" = image(icon = 'icons/obj/device.dmi', icon_state = "[mytape.icon_state]") - ) - var/choice = show_radial_menu(user, src, options) - if(user.incapacitated()) - return - switch(choice) - if("Playback Tape") - play(user) - if("Print Transcript") - print_transcript(user) - if("Eject Tape") - eject(user) - -/obj/item/taperecorder/proc/record(mob/user) - if(!mytape || mytape.ruined) - return - if(recording) - return - if(playing) - return - - playsound(src, 'sound/items/taperecorder/taperecorder_play.ogg', 50, FALSE) - - if(mytape.used_capacity < mytape.max_capacity) - recording = TRUE - atom_say("Recording started.") - update_sound() - update_icon(UPDATE_ICON_STATE) - mytape.timestamp += mytape.used_capacity - mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording started." - var/used = mytape.used_capacity //to stop runtimes when you eject the tape - var/max = mytape.max_capacity - for(used, used < max) - if(recording == 0) - break - mytape.used_capacity++ - used++ - mytape.remaining_capacity = mytape.max_capacity - mytape.used_capacity - sleep(10) - stop() - else - atom_say("[mytape] is full!") - playsound(src, 'sound/items/taperecorder/taperecorder_stop.ogg', 50, FALSE) - - -/obj/item/taperecorder/proc/stop(PlaybackOverride = FALSE) - if(recording) - mytape.timestamp += mytape.used_capacity - mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording stopped." - playsound(src, 'sound/items/taperecorder/taperecorder_stop.ogg', 50, FALSE) - atom_say("Recording stopped.") - recording = FALSE - else if(playing) - playsound(src, 'sound/items/taperecorder/taperecorder_stop.ogg', 50, FALSE) - if(!PlaybackOverride) - atom_say("Playback stopped.") - playing = FALSE - update_icon(UPDATE_ICON_STATE) - update_sound() - - -/obj/item/taperecorder/proc/play(mob/user) - if(!mytape || mytape.ruined) - return - if(recording) - return - if(playing) - stop() - return - if(!length(mytape.storedinfo)) - atom_say("There is no stored data.") - playsound(src, 'sound/items/taperecorder/taperecorder_play.ogg', 50, FALSE) - playsound(src, 'sound/items/taperecorder/taperecorder_stop.ogg', 50, FALSE) - return - - playing = TRUE - update_icon(UPDATE_ICON_STATE) - update_sound() - atom_say("Playback started.") - playsound(src, 'sound/items/taperecorder/taperecorder_play.ogg', 50, FALSE) - var/used = mytape.used_capacity //to stop runtimes when you eject the tape - var/max = mytape.max_capacity - for(var/i = 1, used <= max) // <= to let it play if the tape is full - sleep(playsleepseconds) - if(!mytape) - break - if(playing == 0) - break - if(length(mytape.storedinfo) < i) - atom_say("End of recording.") - break - atom_say("[mytape.storedinfo[i]]") - if(length(mytape.storedinfo) < i + 1 || playsleepseconds > 1.4 SECONDS) - playsleepseconds = 1 SECONDS - else - playsleepseconds = (mytape.timestamp[i + 1] - mytape.timestamp[i]) SECONDS - i++ - - stop(TRUE) - -/obj/item/taperecorder/proc/print_transcript(mob/user) - if(!mytape) - return - if(world.time < cooldown) - to_chat(user, "The recorder can't print that fast!") - return - if(recording || playing) - return - - atom_say("Transcript printed.") - playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1) - var/obj/item/paper/P = new /obj/item/paper(get_turf(src)) - var/t1 = "Transcript:

    " - for(var/i = 1, length(mytape.storedinfo) >= i, i++) - t1 += "[mytape.storedinfo[i]]
    " - P.info = t1 - P.name = "paper- 'Transcript'" - user.put_in_hands(P) - cooldown = world.time + 3 SECONDS - -/obj/item/taperecorder/proc/eject(mob/user) - if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) - return - if(mytape) - playsound(src, 'sound/items/taperecorder/taperecorder_open.ogg', 50, FALSE) - to_chat(user, "You remove [mytape] from [src].") - stop() - user.put_in_hands(mytape) - mytape = null - update_icon(UPDATE_ICON_STATE) - -/obj/item/taperecorder/update_icon_state() - if(!mytape) - icon_state = "taperecorder_empty" - else if(recording) - icon_state = "taperecorder_recording" - else if(playing) - icon_state = "taperecorder_playing" - else - icon_state = "taperecorder_idle" - -//empty tape recorders -/obj/item/taperecorder/empty - starts_with_tape = FALSE - -/obj/item/tape - name = "tape" - desc = "A magnetic tape that can hold up to ten minutes of content." - icon = 'icons/obj/device.dmi' - icon_state = "tape_white" - item_state = "analyzer" - w_class = WEIGHT_CLASS_TINY - materials = list(MAT_METAL = 40, MAT_GLASS = 10) - force = 1 - throwforce = 0 - drop_sound = 'sound/items/handling/tape_drop.ogg' - pickup_sound = 'sound/items/handling/tape_pickup.ogg' - var/max_capacity = 600 - var/used_capacity = 0 - var/remaining_capacity = 600 - var/list/storedinfo = list() - var/list/timestamp = list() - var/ruined = FALSE - -/obj/item/tape/examine(mob/user) - . = ..() - if(in_range(user, src)) - if(ruined) - . += "It's tape is all pulled out, it looks it could be screwed back into place." - else if(max_capacity <= used_capacity) - . += "It is full." - else if((remaining_capacity % 60) == 0) // if there is no seconds (modulo = 0), then only show minutes - . += "It has [remaining_capacity / 60] minutes remaining." - else - if(used_capacity >= (max_capacity - 60)) - . += "It has [remaining_capacity] seconds remaining." // to avoid having 0 minutes - else - . += "It has [seconds_to_time(remaining_capacity)] remaining." - . += "You can Alt-Click [src] to wipe the current tape." - -/obj/item/tape/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - ..() - ruin() - -/obj/item/tape/attack_self__legacy__attackchain(mob/user) - if(!ruined) - ruin(user) - -/obj/item/tape/AltClick(mob/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) - return - if(ruined) - to_chat(user, "This tape is already ruined!") - return - if(!do_after(user, 3 SECONDS, target = src)) - return - - to_chat(user, "You erase the data from [src].") - used_capacity = 0 - remaining_capacity = max_capacity - storedinfo.Cut() - timestamp.Cut() - -/obj/item/tape/update_overlays() - . = ..() - if(ruined) - . += "ribbonoverlay" - -/obj/item/tape/proc/ruin(mob/user) - if(user) - to_chat(user, "You start pulling the tape out.") - if(!do_after(user, 1 SECONDS, target = src)) - return - to_chat(user, "You pull the tape out of [src].") - ruined = TRUE - update_icon(UPDATE_OVERLAYS) - -/obj/item/tape/attackby__legacy__attackchain(obj/item/I, mob/user) - if(is_pen(I)) - rename_interactive(user, I) - -/obj/item/tape/screwdriver_act(mob/living/user, obj/item/I) - . = ..() - if(ruined) - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - to_chat(user, "You start winding the tape back in.") - if(do_after(user, 120 * I.toolspeed, target = src)) - to_chat(user, "You wind the tape back in!") - ruined = FALSE - update_icon(UPDATE_OVERLAYS) - -//Random colour tapes -/obj/item/tape/random/New() - ..() - icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]" diff --git a/code/game/objects/items/devices/thermal_drill.dm b/code/game/objects/items/devices/thermal_drill.dm deleted file mode 100644 index 203b54bd04605..0000000000000 --- a/code/game/objects/items/devices/thermal_drill.dm +++ /dev/null @@ -1,71 +0,0 @@ -/obj/item/thermal_drill - name = "thermal safe drill" - desc = "A tungsten carbide thermal drill with magnetic clamps for the purpose of drilling hardened objects. Guaranteed 100% jam proof." - icon = 'icons/obj/items.dmi' - icon_state = "hardened_drill" - w_class = WEIGHT_CLASS_GIGANTIC - force = 15.0 - var/time_multiplier = 1 - var/payback = FALSE - var/spotted = FALSE - var/datum/looping_sound/thermal_drill/soundloop - var/datum/effect_system/spark_spread/spark_system - var/datum/song/song - -/obj/item/thermal_drill/New() - ..() - soundloop = new(list(src), FALSE) - spark_system = new /datum/effect_system/spark_spread() - spark_system.set_up(1, 0, src) - spark_system.attach(src) - song = new(src, SSinstruments.synthesizer_instrument_ids) - -/obj/item/thermal_drill/Destroy() - QDEL_NULL(soundloop) - QDEL_NULL(spark_system) - QDEL_NULL(song) - return ..() - -/obj/item/thermal_drill/attack_self__legacy__attackchain(mob/user) - add_fingerprint(user) - ui_interact(user) - -/obj/item/thermal_drill/ui_data(mob/user) - return song.ui_data(user) - -/obj/item/thermal_drill/ui_interact(mob/user) - if(!payback) - return - song.ui_interact(user) - -/obj/item/thermal_drill/ui_act(action, params) - if(..()) - return - return song.ui_act(action, params) - -/** - * Whether the instrument should stop playing - * - * Arguments: - * * user - The user - */ -/obj/item/thermal_drill/proc/should_stop_playing(mob/user) - if(!payback && spotted) - return TRUE - return FALSE - -/obj/item/thermal_drill/syndicate - name = "amplified thermal safe drill" - desc = "A tungsten carbide thermal drill with magnetic clamps for the purpose of drilling hardened objects. Comes with an inbuilt morale booster and security detector, to assist in drilling." - payback = TRUE - -/obj/item/thermal_drill/diamond_drill - name = "diamond tipped thermal safe drill" - desc = "A diamond tipped thermal drill with magnetic clamps for the purpose of quickly drilling hardened objects. Guaranteed 100% jam proof." - icon_state = "diamond_drill" - time_multiplier = 0.5 - -/obj/item/thermal_drill/diamond_drill/syndicate - name = "amplified diamond tipped thermal safe drill" - desc = "A diamond tipped thermal drill with magnetic clamps for the purpose of quickly drilling hardened objects. Comes with an inbuilt morale booster and security detector, to assist in drilling." - payback = TRUE diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm deleted file mode 100644 index b9b4787614a14..0000000000000 --- a/code/game/objects/items/devices/traitordevices.dm +++ /dev/null @@ -1,549 +0,0 @@ -/obj/item/jammer - name = "radio jammer" - desc = "Fog of war that fits your pocket. Flicking the switch and extending the antenna will scramble nearby radio comms, making outgoing messages hard to understand." - icon = 'icons/obj/device.dmi' - icon_state = "jammer" - item_state = "jammer" - w_class = WEIGHT_CLASS_TINY - actions_types = list(/datum/action/item_action/toggle_radio_jammer) - new_attack_chain = TRUE - var/active = FALSE - var/range = 15 - -/obj/item/jammer/Destroy() - GLOB.active_jammers -= src - return ..() - -/obj/item/jammer/update_icon_state() - if(active) - icon_state = "[initial(icon_state)]-on" - else - icon_state = "[initial(icon_state)]" - -/obj/item/jammer/activate_self(mob/user) - if(..()) - return - to_chat(user, "You [active ? "deactivate [src]. It goes quiet with a small click." : "activate [src]. It starts to hum softly."]") - active = !active - update_icon(UPDATE_ICON_STATE) - if(active) - GLOB.active_jammers |= src - else - GLOB.active_jammers -= src - for(var/datum/action/item_action/toggle_radio_jammer/A in actions) - A.UpdateButtons() - -/obj/item/teleporter - name = "syndicate teleporter" - desc = "A strange syndicate version of a cult veil shifter. Warranty voided if exposed to EMP." - icon = 'icons/obj/device.dmi' - icon_state = "syndi-tele-4" - throwforce = 5 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 4 - throw_range = 10 - flags = CONDUCT - item_state = "electronic" - origin_tech = "magnets=3;combat=3;syndicate=3" - new_attack_chain = TRUE - var/list/icons_charges = list( - "syndi-tele-0", - "syndi-tele-1", - "syndi-tele-2", - "syndi-tele-3", - "syndi-tele-4", - ) - var/tp_range = 8 - var/inner_tp_range = 3 - var/charges = 4 - var/max_charges = 4 - var/saving_throw_distance = 3 - var/flawless = FALSE - -/obj/item/teleporter/Initialize(mapload, ...) - . = ..() - START_PROCESSING(SSobj, src) - -/obj/item/teleporter/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/teleporter/examine(mob/user) - . = ..() - . += "[src] has [charges] out of [max_charges] charges left." - -/obj/item/teleporter/activate_self(mob/user) - if(..()) - return - attempt_teleport(user, FALSE) - -/obj/item/teleporter/process() - if(prob(10) && charges < max_charges) - charges++ - update_icon_charges() - -/obj/item/teleporter/emp_act(severity) - var/teleported_something = FALSE - if(prob(50 / severity)) - if(ishuman(loc)) - var/mob/living/carbon/human/user = loc - to_chat(user, "[src] buzzes and activates!") - attempt_teleport(user, TRUE) - else //Well, it either is on a floor / locker, and won't teleport someone, OR it's in someones bag. As such, we need to check the turf to see if people are there. - var/turf/teleport_turf = get_turf(src) - for(var/mob/living/user in teleport_turf) - if(!teleported_something) - teleport_turf.visible_message("[src] activates sporadically, teleporting everyone around it!") - teleported_something = TRUE - attempt_teleport(user, TRUE) - if(!teleported_something) - visible_message("[src] activates and blinks out of existence!") - do_sparks(2, 1, src) - qdel(src) - -/obj/item/teleporter/proc/update_icon_charges() - if(charges + 1 > length(icons_charges)) - icon_state = initial(icon_state) - return - icon_state = icons_charges[charges + 1] - -/obj/item/teleporter/proc/attempt_teleport(mob/user, EMP_D = FALSE) - for(var/obj/item/grab/G in user) - qdel(G) - dir_correction(user) - if(!charges && !EMP_D) //If it's empd, you are moving no matter what. - to_chat(user, "[src] is still recharging.") - return - var/turf/starting = get_turf(src) - var/area/starting_area = get_area(starting) - if(!is_teleport_allowed(starting.z) || starting_area.tele_proof) - to_chat(user, "[src] will not work here!") - return - if(SEND_SIGNAL(user, COMSIG_MOVABLE_TELEPORTING, starting) & COMPONENT_BLOCK_TELEPORT) - return FALSE - var/mob/living/M = user - var/turf/mobloc = get_turf(M) - var/list/turfs = list() - var/found_turf = FALSE - var/list/bagholding = user.search_contents_for(/obj/item/storage/backpack/holding) - for(var/turf/T in range(user, tp_range)) - var/area/dropping_area = get_area(T) - if(dropping_area.tele_proof) //There might be some valid turfs before / after you reach such an area, so we continue, not break. - continue - if(!(length(bagholding) && !flawless)) //Chaos if you have a bag of holding - if(get_dir(M, T) != M.dir) - continue - if(T in range(user, inner_tp_range)) - continue - if(T.x > world.maxx-tp_range || T.x < tp_range) - continue //putting them at the edge is dumb - if(T.y > world.maxy-tp_range || T.y < tp_range) - continue - - turfs += T - found_turf = TRUE - - if(found_turf) - if(user.loc != mobloc) // No locker / mech / sleeper teleporting, that breaks stuff - to_chat(M, "[src] will not work here!") - if(charges > 0) //While we want EMP triggered teleports to drain charge, we also do not want it to go negative charge, as such we need this check here - charges-- - update_icon_charges() - var/turf/destination = pick(turfs) - if(tile_check(destination) || flawless) // Why is there so many bloody floor types - var/turf/fragging_location = destination - telefrag(fragging_location, user) - M.forceMove(destination) - playsound(mobloc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - new/obj/effect/temp_visual/teleport_abductor/syndi_teleporter(mobloc) - playsound(destination, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - new/obj/effect/temp_visual/teleport_abductor/syndi_teleporter(destination) - else if(!EMP_D && !(length(bagholding) && !flawless)) // This is where the fun begins - var/direction = get_dir(user, destination) - panic_teleport(user, destination, direction) - else // Emp activated? Bag of holding? No saving throw for you - get_fragged(user, destination) - else - to_chat(M, "[src] will not work here!") - -/obj/item/teleporter/proc/tile_check(turf/T) - if(isfloorturf(T) || isspaceturf(T)) - return TRUE - -/obj/item/teleporter/proc/dir_correction(mob/user) //Direction movement, screws with teleport distance and saving throw, and thus must be removed first - var/temp_direction = user.dir - switch(temp_direction) - if(NORTHEAST, SOUTHEAST) - user.dir = EAST - if(NORTHWEST, SOUTHWEST) - user.dir = WEST - -/obj/item/teleporter/proc/panic_teleport(mob/user, turf/destination, direction = NORTH) - var/saving_throw - switch(direction) - if(NORTH, SOUTH) - if(prob(50)) - saving_throw = EAST - else - saving_throw = WEST - if(EAST, WEST) - if(prob(50)) - saving_throw = NORTH - else - saving_throw = SOUTH - else - saving_throw = NORTH // just in case - - var/mob/living/M = user - var/turf/mobloc = get_turf(M) - var/list/turfs = list() - var/found_turf = FALSE - for(var/turf/T in range(destination, saving_throw_distance)) - if(get_dir(destination, T) != saving_throw) - continue - if(T.x > world.maxx-saving_throw_distance || T.x < saving_throw_distance) - continue //putting them at the edge is dumb - if(T.y > world.maxy-saving_throw_distance || T.y < saving_throw_distance) - continue - if(!tile_check(T)) - continue // We are only looking for safe tiles on the saving throw, since we are nice - turfs += T - found_turf = TRUE - - if(found_turf) - var/turf/new_destination = pick(turfs) - var/turf/fragging_location = new_destination - telefrag(fragging_location, user) - M.forceMove(new_destination) - playsound(mobloc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - new /obj/effect/temp_visual/teleport_abductor/syndi_teleporter(mobloc) - new /obj/effect/temp_visual/teleport_abductor/syndi_teleporter(new_destination) - playsound(new_destination, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - else //We tried to save. We failed. Death time. - get_fragged(user, destination) - - -/obj/item/teleporter/proc/get_fragged(mob/user, turf/destination) - var/turf/mobloc = get_turf(user) - user.forceMove(destination) - playsound(mobloc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - new /obj/effect/temp_visual/teleport_abductor/syndi_teleporter(mobloc) - new /obj/effect/temp_visual/teleport_abductor/syndi_teleporter(destination) - playsound(destination, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - playsound(destination, "sound/magic/disintegrate.ogg", 50, TRUE) - destination.ex_act(rand(1,2)) - to_chat(user, "You teleport into the wall, the teleporter tries to save you, but--") - user.gib() - -/obj/item/teleporter/proc/telefrag(turf/fragging_location, mob/user) - for(var/mob/living/M in fragging_location)//Hit everything in the turf - M.apply_damage(20, BRUTE) - M.Weaken(6 SECONDS) - to_chat(M, "[user] teleports into you, knocking you to the floor with the bluespace wave!") - -/obj/item/paper/teleporter - name = "Teleporter Guide" - icon_state = "paper" - info = {"Instructions on your new prototype syndicate teleporter
    -
    - This teleporter will teleport the user 4-8 meters in the direction they are facing. Unlike the cult veil shifter, you can not drag people with you.
    -
    - It has 4 charges, and will recharge uses over time. No, sticking the teleporter into the tesla, an APC, a microwave, or an electrified door, will not make it charge faster.
    -
    - Warning: Teleporting into walls will activate a failsafe teleport parallel up to 3 meters, but the user will be ripped apart and gibbed in a wall if it fails.
    -
    - Do not expose the teleporter to electromagnetic pulses or attempt to use with a bag of holding, unwanted malfunctions may occur. -

    - Comes with free chameleon mesons, to help you stay stylish while seeing through walls. -"} -/obj/item/storage/box/syndie_kit/teleporter - name = "syndicate teleporter kit" - -/obj/item/storage/box/syndie_kit/teleporter/populate_contents() - new /obj/item/teleporter(src) - new /obj/item/clothing/glasses/meson/chameleon(src) - new /obj/item/paper/teleporter(src) - -/obj/effect/temp_visual/teleport_abductor/syndi_teleporter - duration = 5 - -/obj/item/teleporter/admin - desc = "A strange syndicate version of a cult veil shifter. \n This one seems EMP proof, and with much better safety protocols." - charges = 8 - max_charges = 8 - flawless = TRUE - -/obj/item/fireproofing_injector - name = "fireproofing injector" - desc = "It contains an alien nanoswarm created by the technomancers of boron. Through near sorcerous feats via use of nanomachines, it enables its user to become fully fireproof." - icon = 'icons/obj/hypo.dmi' - icon_state = "combat_hypo" - new_attack_chain = TRUE - var/used = FALSE - -/obj/item/fireproofing_injector/activate_self(mob/user) - if(..()) - return - if(HAS_TRAIT(user, TRAIT_RESISTHEAT)) - to_chat(user, "You are already fireproof!") - return - if(user.mind && (IS_CHANGELING(user) || user.mind.has_antag_datum(/datum/antagonist/vampire)) || (user.dna && user.dna.species.name != "Plasmaman")) - to_chat(user, "The injector is not compatable with your biology!") - return - if(used) - to_chat(user, "The injector is empty!") - return - used = TRUE // Set this BEFORE the popup to prevent people using the injector more than once. - var/choice = tgui_alert(user, "The injector is still unused. Do you wish to use it?", "Fireproofing injector", list("Yes", "No")) - if(choice != "Yes") - to_chat(user, "You decide against using [src].") - used = FALSE - return - to_chat(user, "You inject yourself with the nanites!") - ADD_TRAIT(user, TRAIT_RESISTHEAT, "fireproof_injector") - -/obj/item/cryoregenerative_enhancer - name = "cryoregenerative enhancer" - desc = "Specially designed nanomachines that enhance the low-temperature regenerative capabilities of drask. Requires supercooled air in the enviroment or internals to function." - icon = 'icons/obj/hypo.dmi' - icon_state = "combat_hypo" - new_attack_chain = TRUE - var/used = FALSE - -/obj/item/cryoregenerative_enhancer/examine_more(mob/user) - . = ..() - . += "Designed by Viim-vaarooomunnm's prestigious polytechnic university, these experimental nanomachines infiltrate the cells of the drask host and integrate into the specialised cryoregenerative organelles that facilitate low-temperature healing and work to boost enzymatic activity, massively improving the efficiency of the associated metabolic processes." - . += "" - . += "Clinical trials have shown a four times increase in the rate of healing compared to a placebo. Whilst the product is technically not yet available to the public, the right connections with the right people allow interested parties to obtain samples early..." - -/obj/item/cryoregenerative_enhancer/activate_self(mob/user) - if(..()) - return - if(HAS_TRAIT(user, TRAIT_DRASK_SUPERCOOL)) - to_chat(user, "Your regeneration is already enhanced!") - return - if(user.mind && (IS_CHANGELING(user) || user.mind.has_antag_datum(/datum/antagonist/vampire)) || user.dna?.species.name != "Drask") - to_chat(user, "The injector is not compatable with your biology!") - return - if(used) - to_chat(user, "The injector is empty!") - return - var/choice = tgui_alert(user, "The injector is still unused. Do you wish to use it?", "Cryoregenerative enhancer", list("Yes", "No")) - if(choice != "Yes") - to_chat(user, "You decide against using [src].") - return - if(used) - to_chat(user, "The injector is empty!") - return - used = TRUE - to_chat(user, "You inject yourself with the enhancer!") - ADD_TRAIT(user, TRAIT_DRASK_SUPERCOOL, "cryoregenerative_enhancer") - -/obj/item/batterer - name = "mind batterer" - desc = "A dangerous syndicate device focused on crowd control and escapes. Causes brain damage, confusion, and other nasty effects to those surrounding the user." - icon = 'icons/obj/device.dmi' - icon_state = "batterer" - throwforce = 5 - w_class = WEIGHT_CLASS_TINY - throw_speed = 4 - throw_range = 10 - flags = CONDUCT - item_state = "electronic" - origin_tech = "magnets=3;combat=3;syndicate=3" - new_attack_chain = TRUE - - /// How many times the mind batter has been used - var/times_used = 0 - var/max_uses = 5 - /// Is this item on cooldown from being thrown - var/on_throwing_cooldown = FALSE - /// How many SSobj ticks have passed (Roughly 2 seconds of in game time), used to see when to recharge a use on this item - var/recharge_ticks = 0 - -/obj/item/batterer/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - -/obj/item/batterer/examine(mob/user) - . = ..() - . += "A little label on the side reads: \"Warning: Using this item in quick succession may cause fatigue to the user!\"" - if(times_used >= max_uses) - . += "[src] is out of charge." - if(times_used < max_uses) - . += "[src] has [max_uses-times_used] charges left." - -/obj/item/batterer/process() - if(times_used) - recharge_ticks++ - if(recharge_ticks >= 10) // recharges one use after around 20 seconds - recharge_ticks = initial(recharge_ticks) - times_used-- - icon_state = "batterer" - -/obj/item/batterer/activate_self(mob/user) - if(..()) - return - activate_batterer(user) - -/obj/item/batterer/proc/activate_batterer(mob/user) - times_used++ - if(user) - if(times_used > max_uses) - to_chat(user, "The mind batterer has been burnt out!") - times_used-- - return - if(!do_after_once(user, 2 SECONDS, target = src, allow_moving = TRUE, attempt_cancel_message = "You think it's best to save this for later.")) - times_used-- - return - to_chat(user, "You trigger [src]. It has [max_uses-times_used] charges left.") - - for(var/mob/living/M in oview(7, get_turf(src))) - if(!M.client) - continue - if(issilicon(M)) - var/mob/living/silicon/robot/R = M - R.flash_eyes(3, affect_silicon = TRUE) //Enough stamina damage to instantly force a reboot - else - M.Confused(45 SECONDS) - M.adjustBrainLoss(10) - to_chat(M, "You feel a sudden, electric jolt travel through yourself,") - switch(rand(1, 10)) - if(1) - M.Immobilize(7 SECONDS) - to_chat(M, "and your legs lock up for a moment!") - if(2) - M.apply_status_effect(STATUS_EFFECT_PACIFIED_BATTERER) - to_chat(M, "and you feel an innate love for life for a fleeting moment!") - if(3) - new /obj/effect/hallucination/delusion(get_turf(M), M) - to_chat(M, "and the people around you morph in appearance!") - if(4) - if(prob(80)) - M.EyeBlurry(25 SECONDS) - to_chat(M, "and something in the back of your head stings like hell!") - else - M.EyeBlind(15 SECONDS) - to_chat(M, "and you can't see a goddamn thing!") - if(5) - M.apply_damage(40, STAMINA) - to_chat(M, "and a wave of tiredness washes over you!") - else - to_chat(M, "but as soon as it arrives, it fades.") - add_attack_logs(user, M, "Mind battered with [src]") - - playsound(get_turf(src), 'sound/misc/interference.ogg', 50, TRUE) - if(times_used >= max_uses) - icon_state = "battererburnt" - -/obj/item/batterer/throw_impact(atom/hit_atom) - ..() - if(times_used >= max_uses || on_throwing_cooldown) - return - addtimer(CALLBACK(src, PROC_REF(end_throwing_delay)), 3 SECONDS) - visible_message("[src] suddenly triggers, sending a shower of sparks everywhere!") - do_sparks(4, FALSE, get_turf(src)) - activate_batterer() - on_throwing_cooldown = TRUE - -/obj/item/batterer/proc/end_throwing_delay() - on_throwing_cooldown = FALSE - -/obj/item/batterer/emp_act(severity) - if(times_used >= max_uses) - return - visible_message("[src] explodes into a light show of colors!") - if(severity == EMP_HEAVY) - activate_batterer() - - times_used = max_uses - 1 - activate_batterer() - -/obj/item/handheld_mirror - name = "hand mirror" - desc = "Style, on the go!" - icon = 'icons/obj/hhmirror.dmi' - icon_state = "hhmirror" - w_class = WEIGHT_CLASS_TINY - new_attack_chain = TRUE - var/datum/ui_module/appearance_changer/appearance_changer_holder - -/obj/item/handheld_mirror/ui_state(mob/user) - return GLOB.hands_state - -/obj/item/handheld_mirror/ui_interact(mob/user, datum/tgui/ui = null) - appearance_changer_holder.ui_interact(user, ui) - -/obj/item/handheld_mirror/activate_self(mob/user) - if(..() || !ishuman(user)) - return - appearance_changer_holder = new(src, user) - appearance_changer_holder.flags = APPEARANCE_ALL_BODY - ui_interact(user) - -/obj/item/handheld_mirror/Initialize(mapload) - . = ..() - GLOB.mirrors += src - -/obj/item/handheld_mirror/Destroy() - GLOB.mirrors -= src - QDEL_NULL(appearance_changer_holder) - return ..() - -/// An admin-spawn item that will tell you roughly how close the nearest loyal Nanotrasen crewmember is. -/obj/item/syndi_scanner - name = "syndicate scanner" - desc = "The Syndicate seem to have modified this T-ray scanner for a more nefarious purpose, allowing it to detect all loyal Nanotrasen crew." - icon = 'icons/obj/device.dmi' - icon_state = "syndi-scanner" - throwforce = 5 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 4 - throw_range = 10 - flags = CONDUCT - item_state = "electronic" - new_attack_chain = TRUE - /// Split points for range_messages. - var/list/ranges = list(5, 15, 30) - /// Messages to output to the user. - var/list/range_messages = list( - "Very strong signal detected. Range: Within 5 meters.", - "Strong signal detected. Range: Within 15 meters.", - "Weak signal detected. Range: Within 30 meters.", - "No signal detected." - ) - var/cooldown_length = 10 SECONDS - COOLDOWN_DECLARE(scan_cooldown) - var/on_hit_sound = 'sound/effects/ping_hit.ogg' - -/obj/item/syndi_scanner/activate_self(mob/user) - if(..()) - return - if(!COOLDOWN_FINISHED(src, scan_cooldown)) - to_chat(user, "[src] is recharging!") - return - - COOLDOWN_START(src, scan_cooldown, cooldown_length) - var/turf/user_turf = get_turf(user) - var/min_dist = INFINITY - for(var/mob/living/player in GLOB.player_list) - if(player.stat == DEAD || isnull(player.mind)) - continue - if(!isnull(player.mind.special_role)) - continue - var/turf/target_turf = get_turf(player) - if(target_turf.z != user_turf.z) - continue - min_dist = min(min_dist, get_dist(target_turf, user_turf)) - - // By default, we're in the first range, less than any split point. - var/range_index = 1 - for(var/test_range in ranges) - if(min_dist > test_range) - // Past this split point, move to the next. - range_index++ - else - // Found the right split point, and we're not past all of them, so play the on-hit sound effect. - playsound(user, on_hit_sound, 75, TRUE) - break - to_chat(user, "[range_messages[range_index]]") diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm deleted file mode 100644 index f7212311663a0..0000000000000 --- a/code/game/objects/items/devices/transfer_valve.dm +++ /dev/null @@ -1,241 +0,0 @@ -///if the icon_state for the TTV's tank is in assemblies.dmi -#define TTV_TANK_ICON_STATES list("anesthetic", "emergency", "emergency_double", "emergency_engi", "emergency_sleep", "jetpack", "jetpack_black", "jetpack_void", "oxygen", "oxygen_f", "oxygen_fr", "plasma") - -/obj/item/transfer_valve - icon = 'icons/obj/assemblies.dmi' - name = "tank transfer valve" - icon_state = "valve_1" - item_state = "ttv" - desc = "Regulates the transfer of air between two tanks." - var/obj/item/tank/tank_one = null - var/obj/item/tank/tank_two = null - var/obj/item/assembly/attached_device = null - var/mob/living/attacher = null - var/valve_open = FALSE - var/toggle = TRUE - origin_tech = "materials=1;engineering=1" - -/obj/item/transfer_valve/Destroy() - QDEL_NULL(tank_one) - QDEL_NULL(tank_two) - QDEL_NULL(attached_device) - attacher = null - return ..() - -/obj/item/transfer_valve/IsAssemblyHolder() - return 1 - -/obj/item/transfer_valve/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/tank)) - if(tank_one && tank_two) - to_chat(user, "There are already two tanks attached, remove one first.") - return - - if(!tank_one) - if(!user.transfer_item_to(I, src)) - return - tank_one = I - to_chat(user, "You attach the tank to the transfer valve.") - if(I.w_class > w_class) - w_class = I.w_class - else if(!tank_two) - if(!user.transfer_item_to(I, src)) - return - tank_two = I - to_chat(user, "You attach the tank to the transfer valve.") - if(I.w_class > w_class) - w_class = I.w_class - - update_icon() - SStgui.update_uis(src) // update all UIs attached to src -//TODO: Have this take an assemblyholder - else if(isassembly(I)) - var/obj/item/assembly/A = I - if(A.secured) - to_chat(user, "The device is secured.") - return - if(attached_device) - to_chat(user, "There is already a device attached to the valve, remove it first.") - return - if(!user.transfer_item_to(A, src)) - return - attached_device = A - to_chat(user, "You attach [A] to the valve controls and secure it.") - A.holder = src - A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb). - - investigate_log("[key_name(user)] attached a [A] to a transfer valve.", INVESTIGATE_BOMB) - add_attack_logs(user, src, "attached [A] to a transfer valve", ATKLOG_FEW) - log_game("[key_name_admin(user)] attached [A] to a transfer valve.") - attacher = user - SStgui.update_uis(src) // update all UIs attached to src - - -/obj/item/transfer_valve/HasProximity(atom/movable/AM) - if(!attached_device) - return - attached_device.HasProximity(AM) - -/obj/item/transfer_valve/hear_talk(mob/living/M, list/message_pieces) - ..() - for(var/obj/O in contents) - O.hear_talk(M, message_pieces) - -/obj/item/transfer_valve/hear_message(mob/living/M, msg) - ..() - for(var/obj/O in contents) - O.hear_message(M, msg) - -/obj/item/transfer_valve/attack_self__legacy__attackchain(mob/user) - ui_interact(user) - -/obj/item/transfer_valve/ui_state(mob/user) - return GLOB.inventory_state - -/obj/item/transfer_valve/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "TransferValve", name) - ui.open() - -/obj/item/transfer_valve/ui_data(mob/user) - var/list/data = list() - data["tank_one"] = tank_one ? tank_one.name : null - data["tank_two"] = tank_two ? tank_two.name : null - data["attached_device"] = attached_device ? attached_device.name : null - data["valve"] = valve_open - return data - - - -/obj/item/transfer_valve/ui_act(action, params) - if(..()) - return - . = TRUE - switch(action) - if("tankone") - if(tank_one) - split_gases() - valve_open = FALSE - tank_one.forceMove(get_turf(src)) - tank_one = null - update_icon() - if((!tank_two || tank_two.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) - w_class = WEIGHT_CLASS_NORMAL - if("tanktwo") - if(tank_two) - split_gases() - valve_open = FALSE - tank_two.forceMove(get_turf(src)) - tank_two = null - update_icon() - if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) - w_class = WEIGHT_CLASS_NORMAL - if("toggle") - toggle_valve(usr) - if("device") - if(attached_device) - attached_device.attack_self__legacy__attackchain(usr) - if("remove_device") - if(attached_device) - attached_device.forceMove(get_turf(src)) - attached_device.holder = null - attached_device = null - update_icon() - else - . = FALSE - if(.) - update_icon() - add_fingerprint(usr) - - -/obj/item/transfer_valve/proc/process_activation(obj/item/D) - if(toggle) - toggle = FALSE - toggle_valve() - spawn(50) // To stop a signal being spammed from a proxy sensor constantly going off or whatever - toggle = TRUE - -/obj/item/transfer_valve/update_icon_state() - if(!tank_one && !tank_two && !attached_device) - icon_state = "valve_1" - else - icon_state = "valve" - -/obj/item/transfer_valve/update_overlays() - . = ..() - underlays.Cut() - if(!tank_one && !tank_two && !attached_device) - return - - if(tank_one) - var/tank_one_icon_state = tank_one.icon_state - if(!(tank_one_icon_state in TTV_TANK_ICON_STATES)) //if no valid sprite fall back to an oxygen tank - tank_one_icon_state = "oxygen" - stack_trace("[tank_one] was inserted into a TTV with an invalid icon_state, \"[tank_one.icon_state]\"") - . += "[tank_one_icon_state]" - - if(tank_two) - var/tank_two_icon_state = tank_two.icon_state - if(!(tank_two_icon_state in TTV_TANK_ICON_STATES)) //if no valid sprite fall back to an oxygen tank - tank_two_icon_state = "oxygen" - stack_trace("[tank_two] was inserted into a TTV with an invalid icon_state, \"[tank_two.icon_state]\"") - var/icon/tank_two_icon = new(icon, icon_state = tank_two_icon_state) - tank_two_icon.Shift(WEST, 13) - underlays += tank_two_icon - - if(attached_device) - . += "device" - -/obj/item/transfer_valve/proc/merge_gases() - tank_two.air_contents.volume += tank_one.air_contents.volume - var/datum/gas_mixture/temp - temp = tank_one.air_contents.remove_ratio(1) - tank_two.air_contents.merge(temp) - -/obj/item/transfer_valve/proc/split_gases() - if(!valve_open || !tank_one || !tank_two) - return - var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume - var/datum/gas_mixture/temp - temp = tank_two.air_contents.remove_ratio(ratio1) - tank_one.air_contents.merge(temp) - tank_two.air_contents.volume -= tank_one.air_contents.volume - - /* - Exadv1: I know this isn't how it's going to work, but this was just to check - it explodes properly when it gets a signal (and it does). - */ - -/obj/item/transfer_valve/proc/toggle_valve(mob/user) - if(!valve_open && tank_one && tank_two) - valve_open = TRUE - var/turf/bombturf = get_turf(src) - var/area/A = get_area(bombturf) - - var/attacher_name = "" - if(!attacher) - attacher_name = "Unknown" - else - attacher_name = "[key_name_admin(attacher)]" - - var/mob/mob = get_mob_by_key(src.fingerprintslast) - - investigate_log("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]", INVESTIGATE_BOMB) - message_admins("Bomb valve opened at [A.name] (JMP) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name_admin(mob)]") - log_game("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]") - if(user) - add_attack_logs(user, src, "Bomb valve opened with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]", ATKLOG_FEW) - merge_gases() - spawn(20) // In case one tank bursts - for(var/i in 1 to 5) - update_icon() - sleep(10) - update_icon() - - else if(valve_open && tank_one && tank_two) - split_gases() - valve_open = FALSE - update_icon() - -#undef TTV_TANK_ICON_STATES diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm deleted file mode 100644 index 32256602c3ee9..0000000000000 --- a/code/game/objects/items/devices/uplinks.dm +++ /dev/null @@ -1,469 +0,0 @@ -//This could either be split into the proper DM files or placed somewhere else all together, but it'll do for now -Nodrak - -/* - -A list of items and costs is stored under the datum of every game mode, alongside the number of crystals, and the welcoming message. - -*/ - -GLOBAL_LIST_EMPTY(world_uplinks) - -/obj/item/uplink - var/uses // Numbers of crystals - var/hidden_crystals = 0 - /// List of categories with items inside - var/list/uplink_cats - /// List of all items in total (For buying random) - var/list/uplink_items - - var/purchase_log = "" - var/uplink_owner = null //text-only - var/used_TC = 0 - - var/job = null - var/species = null - var/temp_category - var/uplink_type = UPLINK_TYPE_TRAITOR - /// Whether the uplink is jammed and cannot be used to order items. - var/is_jammed = FALSE - /// Whether or not the uplink has generated its stock and discounts - var/items_generated = FALSE - -/obj/item/uplink/ui_host() - return loc - -/obj/item/uplink/proc/update_uplink_type(new_uplink_type) - uplink_type = new_uplink_type - -/obj/item/uplink/New() - ..() - uses = 100 - GLOB.world_uplinks += src - -/obj/item/uplink/Destroy() - GLOB.world_uplinks -= src - return ..() - -/** - * Build the item lists for use with the UI - * - * Generates a list of items for use in the UI, based on job, species and other parameters - * - * Arguments: - * * user - User to check - */ -/obj/item/uplink/proc/generate_item_lists(mob/user) - if(!job) - job = user.mind.assigned_role - if(!species) - species = user.dna.species.name - if(!items_generated) - uplink_items = get_uplink_items(src, user) - items_generated = TRUE - - var/list/cats = list() - - for(var/category in uplink_items) - cats[++cats.len] = list("cat" = category, "items" = list()) - for(var/datum/uplink_item/I in uplink_items[category]) - if(I.job && length(I.job)) - if(!(I.job.Find(job)) && uplink_type != UPLINK_TYPE_ADMIN) - continue - if(length(I.species)) - if(!(I.species.Find(species)) && uplink_type != UPLINK_TYPE_ADMIN) - continue - cats[length(cats)]["items"] += list(list( - "name" = sanitize(I.name), - "desc" = sanitize(I.description()), - "cost" = I.cost, - "hijack_only" = I.hijack_only, - "obj_path" = I.reference, - "refundable" = I.refundable)) - uplink_items[I.reference] = I - - uplink_cats = cats - -//If 'random' was selected -/obj/item/uplink/proc/chooseRandomItem() - if(uses <= 0) - return - - var/list/random_items = list() - - for(var/uplink_section in uplink_items) - for(var/datum/uplink_item/UI in uplink_items[uplink_section]) - if(UI.cost <= uses && UI.limited_stock != 0) - random_items += UI - - return pick(random_items) - -/obj/item/uplink/proc/buy(datum/uplink_item/UI, reference) - if(is_jammed) - to_chat(usr, "[src] seems to be jammed - it cannot be used here!") - return - if(!UI) - return - if(UI.limited_stock == 0) - to_chat(usr, "You have redeemed this discount already.") - return - UI.buy_uplink_item(src,usr) - SStgui.update_uis(src) - - return TRUE - -/obj/item/uplink/proc/mass_purchase(datum/uplink_item/UI, reference, quantity = 1) - // jamming check happens in ui_act - if(!UI) - return - if(quantity <= 0) - return - if(UI.limited_stock == 0) - return - if(UI.limited_stock > 0 && UI.limited_stock < quantity) - quantity = UI.limited_stock - var/list/bought_things = list() - for(var/i in 1 to quantity) - var/item = UI.buy_uplink_item(src, usr, put_in_hands = FALSE) - if(isnull(item)) - break - bought_things += item - return bought_things - -/obj/item/uplink/proc/refund(mob/user as mob) - var/obj/item/I = user.get_active_hand() - if(!I) // Make sure there's actually something in the hand before even bothering to check - to_chat(user, "[I] is not refundable.") - return - - for(var/category in uplink_items) - for(var/item in uplink_items[category]) - var/datum/uplink_item/UI = item - var/path = UI.refund_path || UI.item - var/cost = UI.refund_amount || UI.cost - - if(ispath(I.type, path) && UI.refundable && I.check_uplink_validity()) - var/refund_amount = cost - if(istype(I, /obj/item/guardiancreator/tech)) - var/obj/item/guardiancreator/tech/holopara = I - if(holopara.is_discounted && cost != holopara.refund_cost) // This has to be done because the normal holopara uplink datum precedes the discounted uplink datum - continue - refund_amount = holopara.refund_cost - uses += refund_amount - used_TC -= refund_amount - to_chat(user, "[I] refunded.") - qdel(I) - return - - // If we are here, we didnt refund - to_chat(user, "[I] is not refundable.") - -// HIDDEN UPLINK - Can be stored in anything but the host item has to have a trigger for it. -/* How to create an uplink in 3 easy steps! - - 1. All obj/item 's have a hidden_uplink var. By default it's null. Give the item one with "new(src)", it must be in it's contents. Feel free to add "uses". - - 2. Code in the triggers. Use check_trigger for this, I recommend closing the item's menu with "usr << browse(null, "window=windowname") if it returns true. - The var/value is the value that will be compared with the var/target. If they are equal it will activate the menu. - - 3. If you want the menu to stay until the users locks his uplink, add an active_uplink_check(mob/user as mob) in your interact/attack_hand proc. - Then check if it's true, if true return. This will stop the normal menu appearing and will instead show the uplink menu. -*/ - -/obj/item/uplink/hidden - name = "hidden uplink" - desc = "There is something wrong if you're examining this." - var/active = FALSE - /// An assoc list of references (the variable called reference on an uplink item) and its value being how many of the item - var/list/shopping_cart - /// A cached version of shopping_cart containing all the data for the tgui side - var/list/cached_cart - /// A list of 3 categories and item indexes in uplink_cats, to show as recommendedations - var/list/lucky_numbers - -// The hidden uplink MUST be inside an obj/item's contents. -/obj/item/uplink/hidden/New(loc) - if(!isitem(loc)) - qdel(src) - ..() - -// Toggles the uplink on and off. Normally this will bypass the item's normal functions and go to the uplink menu, if activated. -/obj/item/uplink/hidden/proc/toggle() - active = !active - -// Directly trigger the uplink. Turn on if it isn't already. -/obj/item/uplink/hidden/proc/trigger(mob/user as mob) - if(!active) - toggle() - interact(user) - -// Checks to see if the value meets the target. Like a frequency being a traitor_frequency, in order to unlock a headset. -// If true, it accesses trigger() and returns 1. If it fails, it returns false. Use this to see if you need to close the -// current item's menu. -/obj/item/uplink/hidden/proc/check_trigger(mob/user, value, target) - if(is_jammed) - to_chat(user, "[src] seems to be jammed - it cannot be used here!") - return - if(value == target) - trigger(user) - return TRUE - return FALSE - -/obj/item/uplink/hidden/ui_state(mob/user) - return GLOB.inventory_state - -/obj/item/uplink/hidden/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "Uplink", name) - ui.open() - -/obj/item/uplink/hidden/ui_data(mob/user) - var/list/data = list() - - data["crystals"] = uses - - data["cart"] = generate_tgui_cart() - data["cart_price"] = calculate_cart_tc() - data["lucky_numbers"] = lucky_numbers - - return data - -/obj/item/uplink/hidden/ui_static_data(mob/user) - var/list/data = list() - - // Actual items - if(!uplink_cats || !uplink_items) - generate_item_lists(user) - if(!lucky_numbers) // Make sure these are generated AFTER the categories, otherwise shit will get messed up - shuffle_lucky_numbers() - data["cats"] = uplink_cats - - // Exploitable info - var/list/exploitable = list() - for(var/datum/data/record/L in GLOB.data_core.general) - exploitable += list(list( - "name" = html_encode(L.fields["name"]), - "sex" = html_encode(L.fields["sex"]), - "age" = html_encode(L.fields["age"]), - "species" = html_encode(L.fields["species"]), - "rank" = html_encode(L.fields["rank"]), - "fingerprint" = html_encode(L.fields["fingerprint"]) - )) - - data["exploitable"] = exploitable - - return data - -/obj/item/uplink/hidden/proc/calculate_cart_tc() - . = 0 - for(var/reference in shopping_cart) - var/datum/uplink_item/item = uplink_items[reference] - var/purchase_amt = shopping_cart[reference] - . += item.cost * purchase_amt - -/obj/item/uplink/hidden/proc/generate_tgui_cart(update = FALSE) - if(!update) - return cached_cart - - if(!length(shopping_cart)) - shopping_cart = null - cached_cart = null - return cached_cart - - cached_cart = list() - for(var/reference in shopping_cart) - var/datum/uplink_item/I = uplink_items[reference] - cached_cart += list(list( - "name" = sanitize(I.name), - "desc" = sanitize(I.description()), - "cost" = I.cost, - "hijack_only" = I.hijack_only, - "obj_path" = I.reference, - "amount" = shopping_cart[reference], - "limit" = I.limited_stock)) - -// Interaction code. Gathers a list of items purchasable from the paren't uplink and displays it. It also adds a lock button. -/obj/item/uplink/hidden/interact(mob/user) - ui_interact(user) - -// The purchasing code. -/obj/item/uplink/hidden/ui_act(action, list/params, datum/tgui/ui) - if(..()) - return - - . = TRUE - - switch(action) - if("lock") - toggle() - uses += hidden_crystals - hidden_crystals = 0 - SStgui.close_uis(src) - for(var/reference in shopping_cart) - if(shopping_cart[reference] == 0) // I know this isn't lazy, but this should runtime on purpose if we can't access this for some reason - remove_from_cart(reference) - - if("refund") - refund(ui.user) - - if("buyRandom") - var/datum/uplink_item/UI = chooseRandomItem() - return buy(UI, "RN") - - if("buyItem") - var/datum/uplink_item/UI = uplink_items[params["item"]] - return buy(UI, UI ? UI.reference : "") - - if("add_to_cart") - var/datum/uplink_item/UI = uplink_items[params["item"]] - if(LAZYIN(shopping_cart, params["item"])) - to_chat(ui.user, "[UI.name] is already in your cart!") - return - var/startamount = 1 - if(UI.limited_stock == 0) - startamount = 0 - LAZYSET(shopping_cart, params["item"], startamount) - generate_tgui_cart(TRUE) - - if("remove_from_cart") - remove_from_cart(params["item"]) - - if("set_cart_item_quantity") - var/amount = text2num(params["quantity"]) - LAZYSET(shopping_cart, params["item"], max(amount, 0)) - generate_tgui_cart(TRUE) - - if("purchase_cart") - if(!LAZYLEN(shopping_cart)) // sanity check - return - if(calculate_cart_tc() > uses) - to_chat(ui.user, "[src] buzzes, it doesn't contain enough telecrystals!") - return - if(is_jammed) - to_chat(ui.user, "[src] seems to be jammed - it cannot be used here!") - return - - // Buying of the uplink stuff - var/list/bought_things = list() - for(var/reference in shopping_cart) - var/datum/uplink_item/item = uplink_items[reference] - var/purchase_amt = shopping_cart[reference] - if(purchase_amt <= 0) - continue - bought_things += mass_purchase(item, item ? item.reference : "", purchase_amt) - - // Check how many of them are items - var/list/obj/item/items_for_crate = list() - for(var/obj/item/thing in bought_things) - // because sometimes you can buy items like crates from surpluses and stuff - // the crates will already be on the ground, so we dont need to worry about them - if(isitem(thing)) - items_for_crate += thing - - // If we have more than 2 of them, put them in a crate - if(length(items_for_crate) > 2) - var/obj/structure/closet/crate/C = new(get_turf(src)) - for(var/obj/item/item as anything in items_for_crate) - item.forceMove(C) - // Otherwise, just put the items in their hands - else if(length(items_for_crate)) - for(var/obj/item/item as anything in items_for_crate) - ui.user.put_in_any_hand_if_possible(item) - - empty_cart() - SStgui.update_uis(src) - - if("empty_cart") - empty_cart() - - if("shuffle_lucky_numbers") - // lets see paul allen's random uplink item - shuffle_lucky_numbers() - -/obj/item/uplink/hidden/proc/shuffle_lucky_numbers() - lucky_numbers = list() - for(var/i in 1 to 4) - var/cate_number = rand(1, length(uplink_cats)) - var/item_number = rand(1, length(uplink_cats[cate_number]["items"])) - lucky_numbers += list(list("cat" = cate_number - 1, "item" = item_number - 1)) // dm lists are 1 based, js lists are 0 based, gotta -1 - -/obj/item/uplink/hidden/proc/remove_from_cart(item_reference) // i want to make it eventually remove all instances - LAZYREMOVE(shopping_cart, item_reference) - generate_tgui_cart(TRUE) - -/obj/item/uplink/hidden/proc/empty_cart() - shopping_cart = null - generate_tgui_cart(TRUE) - -// I placed this here because of how relevant it is. -// You place this in your uplinkable item to check if an uplink is active or not. -// If it is, it will display the uplink menu and return 1, else it'll return false. -// If it returns true, I recommend closing the item's normal menu with "user << browse(null, "window=name")" -/obj/item/proc/active_uplink_check(mob/user as mob) - // Activates the uplink if it's active - if(src.hidden_uplink) - if(src.hidden_uplink.active) - src.hidden_uplink.trigger(user) - return 1 - return 0 - -// PRESET UPLINKS -// A collection of preset uplinks. -// -// Includes normal radio uplink, multitool uplink, -// implant uplink (not the implant tool) and a preset headset uplink. - -/obj/item/radio/uplink/New() - ..() - hidden_uplink = new(src) - icon_state = "radio" - -/obj/item/radio/uplink/AltClick() - return - -/obj/item/radio/uplink/CtrlShiftClick() - return - -/obj/item/radio/uplink/show_examine_hotkeys() - return list() - -/obj/item/radio/uplink/attack_self__legacy__attackchain(mob/user as mob) - if(hidden_uplink) - hidden_uplink.trigger(user) - -/obj/item/radio/uplink/nuclear/New() - ..() - if(hidden_uplink) - hidden_uplink.update_uplink_type(UPLINK_TYPE_NUCLEAR) - GLOB.nuclear_uplink_list += src - -/obj/item/radio/uplink/nuclear/Destroy() - GLOB.nuclear_uplink_list -= src - return ..() - -/obj/item/radio/uplink/sst/New() - ..() - if(hidden_uplink) - hidden_uplink.update_uplink_type(UPLINK_TYPE_SST) - -/obj/item/radio/uplink/admin/New() - ..() - if(hidden_uplink) - hidden_uplink.update_uplink_type(UPLINK_TYPE_ADMIN) - hidden_uplink.uses = 2500 - -/obj/item/multitool/uplink/New() - ..() - hidden_uplink = new(src) - -/obj/item/multitool/uplink/attack_self__legacy__attackchain(mob/user as mob) - if(hidden_uplink) - hidden_uplink.trigger(user) - -/obj/item/radio/headset/uplink - traitor_frequency = 1445 - -/obj/item/radio/headset/uplink/New() - ..() - hidden_uplink = new(src) - hidden_uplink.uses = 100 diff --git a/code/game/objects/items/devices/voice_changer.dm b/code/game/objects/items/devices/voice_changer.dm deleted file mode 100644 index 25f3d56447595..0000000000000 --- a/code/game/objects/items/devices/voice_changer.dm +++ /dev/null @@ -1,50 +0,0 @@ -/obj/item/voice_changer - name = "voice changer" - desc = "A voice mimicking module." - icon = 'icons/obj/device.dmi' - icon_state = "voice_changer_off" - - actions_types = list(/datum/action/item_action/voice_changer/toggle, /datum/action/item_action/voice_changer/voice) - - var/obj/item/parent - - var/voice - var/active - -/obj/item/voice_changer/New() - . = ..() - - if(isitem(loc)) - parent = loc - parent.actions |= actions - -/obj/item/voice_changer/Destroy() - if(isitem(parent)) - parent.actions -= actions - - return ..() - -/obj/item/voice_changer/attack_self__legacy__attackchain(mob/user) - active = !active - icon_state = "voice_changer_[active ? "on" : "off"]" - to_chat(user, "You toggle [src] [active ? "on" : "off"].") - - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtons() - -/obj/item/voice_changer/proc/set_voice(mob/user) - var/chosen_voice = tgui_input_text(user, "What voice would you like to mimic? Leave this empty to use the voice on your ID card.", "Set Voice Changer") - if(!chosen_voice) - voice = null - to_chat(user, "You are now mimicking the voice on your ID card.") - return - - voice = sanitize_for_ic(copytext_char(chosen_voice, 1, MAX_MESSAGE_LEN)) - to_chat(user, "You are now mimicking [voice].") - -/obj/item/voice_changer/voice_modulator - name = "voice modulator" - desc = "A voice scrambling module." - voice = "Unknown" - actions_types = list(/datum/action/item_action/voice_changer/toggle) diff --git a/code/game/objects/items/devices/whistle.dm b/code/game/objects/items/devices/whistle.dm deleted file mode 100644 index 92c81ecbbcb55..0000000000000 --- a/code/game/objects/items/devices/whistle.dm +++ /dev/null @@ -1,59 +0,0 @@ - -#define USE_COOLDOWN 2 SECONDS - -/obj/item/hailer - name = "hailer" - desc = "Used by obese officers to save their breath for running." - icon = 'icons/obj/device.dmi' - icon_state = "voice0" - item_state = "flashtool" //looks exactly like a flash (and nothing like a flashbang) - w_class = WEIGHT_CLASS_TINY - flags = CONDUCT - var/next_use_time - var/spamcheck = FALSE - -/obj/item/hailer/attack_self__legacy__attackchain(mob/living/carbon/user as mob) - if(world.time < next_use_time) - return - - if(emagged) - playsound(get_turf(src), 'sound/voice/binsult.ogg', 100, TRUE, vary = 0)//hueheuheuheuheuheuhe - user.visible_message("[user]'s [name] gurgles, \"FUCK YOUR CUNT YOU SHIT EATING CUNT TILL YOU ARE A MASS EATING SHIT CUNT. EAT PENISES IN YOUR FUCK FACE AND SHIT OUT ABORTIONS TO FUCK UP SHIT IN YOUR ASS YOU COCK FUCK SHIT MONKEY FROM THE DEPTHS OF SHIT\"") - else - playsound(get_turf(src), 'sound/voice/halt.ogg', 100, TRUE, vary = 0) - user.visible_message("[user]'s [name] rasps, \"Halt! Security!\"") - - next_use_time = world.time + USE_COOLDOWN - -/obj/item/hailer/emag_act(user as mob) - if(!emagged) - to_chat(user, "You overload \the [src]'s voice synthesizer.") - emagged = TRUE - return TRUE - -#undef USE_COOLDOWN - -/obj/item/clothing/mask/whistle - name = "whistle" - desc = "A metal pea-whistle. Can be blown while held, or worn in the mouth." - icon_state = "whistle" - item_state = "whistle" - w_class = WEIGHT_CLASS_TINY - flags = CONDUCT - body_parts_covered = null - actions_types = list(/datum/action/item_action/whistle) - COOLDOWN_DECLARE(whistle_cooldown) - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/mask.dmi', - "Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi', - "Tajaran" = 'icons/mob/clothing/species/tajaran/mask.dmi', - "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi', - "Grey" = 'icons/mob/clothing/species/grey/mask.dmi' - ) - -/obj/item/clothing/mask/whistle/attack_self__legacy__attackchain(mob/user) - if(!COOLDOWN_FINISHED(src, whistle_cooldown)) - return - - playsound(src, pick('sound/items/whistle1.ogg', 'sound/items/whistle2.ogg', 'sound/items/whistle3.ogg'), 25) - COOLDOWN_START(src, whistle_cooldown, 4 SECONDS) diff --git a/code/game/objects/items/documents.dm b/code/game/objects/items/documents.dm deleted file mode 100644 index 16563ba3bc76d..0000000000000 --- a/code/game/objects/items/documents.dm +++ /dev/null @@ -1,88 +0,0 @@ -/obj/item/documents - name = "secret documents" - desc = "Documents printed on special copy-protected paper." - icon = 'icons/obj/bureaucracy.dmi' - icon_state = "docs_generic" - item_state = "paper" - throwforce = 0 - w_class = WEIGHT_CLASS_TINY - throw_range = 1 - throw_speed = 1 - pressure_resistance = 2 - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - -/obj/item/documents/Initialize(mapload) - . = ..() - AddElement(/datum/element/high_value_item) - -/obj/item/documents/nanotrasen - desc = "Nanotrasen documents printed on special copy-protected paper. They are filled with complex diagrams, technical documentation, and lists of names, dates, and coordinates." - icon_state = "docs_verified" - -/obj/item/documents/nanotrasen/examine(mob/user) - . = ..() - . += "These documents are marked \"TOP SECRET - property of Nanotrasen\"." - -/obj/item/documents/syndicate - desc = "Documents printed on special copy-protected paper. They detail sensitive Syndicate operational intelligence." - -/obj/item/documents/syndicate/red - name = "'Red' secret documents" - desc = "Documents printed on special copy-protected paper. They detail sensitive Syndicate operational intelligence." - icon_state = "docs_red" - -/obj/item/documents/syndicate/red/examine(mob/user) - . = ..() - . += "These documents are marked with \"TOP SECRET - RED\" and the logo of the Syndicate." - -/obj/item/documents/syndicate/blue - name = "'Blue' secret documents" - desc = "Documents printed on special copy-protected paper. They detail sensitive Syndicate operational intelligence." - icon_state = "docs_blue" - -/obj/item/documents/syndicate/blue/examine(mob/user) - . = ..() - . += "These documents are marked with \"TOP SECRET - BLUE\" and the logo of the Syndicate." - -/obj/item/documents/syndicate/yellow - name = "'Yellow' secret documents" - desc = "Documents printed on special copy-protected paper. They detail sensitive Syndicate operational intelligence." - icon_state = "docs_yellow" - resistance_flags = NONE - -/obj/item/documents/syndicate/yellow/examine(mob/user) - . = ..() - . += "These documents are marked with \"TOP SECRET - YELLOW\" and the logo of the Syndicate." - -/obj/item/documents/syndicate/yellow/trapped - desc = "Documents printed on special copy-protected paper. They detail sensitive Syndicate operational intelligence, and have a thin film of clear material covering their surface." - var/poison_type = "amanitin" - var/poison_dose = 20 - var/poison_total = 60 - -/obj/item/documents/syndicate/mining - desc = "Documents detailing Syndicate plasma mining operations." - -/obj/item/documents/syndicate/mining/examine(mob/user) - . = ..() - . += "These documents are marked with \"SECRET\" and the logo of the Syndicate." - -/obj/item/documents/syndicate/yellow/trapped/pickup(user) - if(ishuman(user) && poison_total > 0) - var/mob/living/carbon/human/H = user - var/obj/item/clothing/gloves/G = H.gloves - if(!istype(G) || G.transfer_prints) - H.reagents.add_reagent(poison_type, poison_dose) - poison_total -= poison_dose - add_attack_logs(src, user, "Picked up [src], the trapped syndicate documents") - return ..() - -/obj/item/documents/syndicate/dvorak_blackbox - name = "\improper D.V.O.R.A.K Blackbox Disk" - desc = "This disk contains a full record of all information that passed through D.V.O.R.A.K's systems during its uptime, not to mention what may have gone wrong. NT might be interested in this." - icon = 'icons/obj/module.dmi' - w_class = WEIGHT_CLASS_TINY - item_state = "card-id" - icon_state = "holodisk" - drop_sound = 'sound/items/handling/disk_drop.ogg' - pickup_sound = 'sound/items/handling/disk_pickup.ogg' diff --git a/code/game/objects/items/flag.dm b/code/game/objects/items/flag.dm deleted file mode 100644 index cc04d4e708029..0000000000000 --- a/code/game/objects/items/flag.dm +++ /dev/null @@ -1,302 +0,0 @@ -/obj/item/flag - name = "flag" - desc = "It's a flag." - icon = 'icons/obj/flag.dmi' - icon_state = "ntflag" - lefthand_file = 'icons/mob/inhands/flags_lefthand.dmi' - righthand_file = 'icons/mob/inhands/flags_righthand.dmi' - w_class = WEIGHT_CLASS_BULKY - max_integrity = 40 - resistance_flags = FLAMMABLE - custom_fire_overlay = "fire" - var/rolled = FALSE - -/obj/item/flag/attackby__legacy__attackchain(obj/item/W, mob/user, params) - . = ..() - if(W.get_heat() && !(resistance_flags & ON_FIRE)) - user.visible_message("[user] lights [src] with [W].", "You light [src] with [W].", "You hear a low whoosh.") - fire_act() - -/obj/item/flag/attack_self__legacy__attackchain(mob/user) - rolled = !rolled - user.visible_message("[user] [rolled ? "rolls up" : "unfurls"] [src].", "You [rolled ? "roll up" : "unfurl"] [src].", "You hear fabric rustling.") - update_icon() - -/obj/item/flag/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = FALSE) - ..() - update_icon() - -/obj/item/flag/extinguish() - ..() - update_icon() - -/obj/item/flag/update_icon_state() - updateFlagIcon() - item_state = icon_state - if(rolled) - icon_state = "[icon_state]_rolled" - custom_fire_overlay = "fire_rolled" - else - custom_fire_overlay = initial(custom_fire_overlay) - if(resistance_flags & ON_FIRE) - item_state = "[item_state]_fire" - if(ismob(loc)) - var/mob/M = loc - M.update_inv_r_hand() - M.update_inv_l_hand() - -/obj/item/flag/proc/updateFlagIcon() - icon_state = initial(icon_state) - -/obj/item/flag/nt - name = "\improper Nanotrasen flag" - desc = "A flag proudly boasting the logo of NT." - icon_state = "ntflag" - -/obj/item/flag/clown - name = "\improper Clown Unity flag" - desc = "The universal banner of clowns everywhere. It smells faintly of bananas." - icon_state = "clownflag" - -/obj/item/flag/mime - name = "\improper Mime Unity flag" - desc = "The standard by which all mimes march to war, as cold as ice and silent as the grave." - icon_state = "mimeflag" - -/obj/item/flag/ian - name = "\improper Ian flag" - desc = "The banner of Ian, because SQUEEEEE." - icon_state = "ianflag" - - -//Species flags - -/obj/item/flag/species/slime - name = "\improper Slime People flag" - desc = "A flag proudly proclaiming the superior heritage of Slime People." - icon_state = "slimeflag" - -/obj/item/flag/species/skrell - name = "\improper Skrell flag" - desc = "A flag proudly proclaiming the superior heritage of Skrell." - icon_state = "skrellflag" - -/obj/item/flag/species/vox - name = "\improper Vox flag" - desc = "A flag proudly proclaiming the superior heritage of Vox." - icon_state = "voxflag" - -/obj/item/flag/species/machine - name = "\improper Synthetics flag" - desc = "A flag proudly proclaiming the superior heritage of Synthetics." - icon_state = "machineflag" - -/obj/item/flag/species/diona - name = "\improper Diona flag" - desc = "A flag proudly proclaiming the superior heritage of Dionae." - icon_state = "dionaflag" - -/obj/item/flag/species/human - name = "\improper Human flag" - desc = "A flag proudly proclaiming the superior heritage of Humans." - icon_state = "humanflag" - -/obj/item/flag/species/greys - name = "\improper Greys flag" - desc = "A flag proudly proclaiming the superior heritage of Greys." - icon_state = "greysflag" - -/obj/item/flag/species/kidan - name = "\improper Kidan flag" - desc = "A flag proudly proclaiming the superior heritage of Kidan." - icon_state = "kidanflag" - -/obj/item/flag/species/taj - name = "\improper Tajaran flag" - desc = "A flag proudly proclaiming the superior heritage of Tajaran." - icon_state = "tajflag" - -/obj/item/flag/species/unathi - name = "\improper Unathi flag" - desc = "A flag proudly proclaiming the superior heritage of Unathi." - icon_state = "unathiflag" - -/obj/item/flag/species/vulp - name = "\improper Vulpkanin flag" - desc = "A flag proudly proclaiming the superior heritage of Vulpkanin." - icon_state = "vulpflag" - -/obj/item/flag/species/drask - name = "\improper Drask flag" - desc = "A flag proudly proclaiming the superior heritage of Drask." - icon_state = "draskflag" - -/obj/item/flag/species/plasma - name = "\improper Plasmaman flag" - desc = "A flag proudly proclaiming the superior heritage of Plasmamen." - icon_state = "plasmaflag" - -/obj/item/flag/species/nian - name ="\improper Nian flag" - desc = "An eccentric handmade standard, luxuriously soft due to exotic silks and embossed with lustrous gold. Although inspired by the pride that Nianae take in their baubles, it ultimately feels melancholic. Beauty knows no pain, afterall." - icon_state = "nianflag" - -//Department Flags - -/obj/item/flag/cargo - name = "\improper Cargonia flag" - desc = "The flag of the independent, sovereign nation of Cargonia. Merely glimpsing this majestic banner fills you with the urge to buy enough guns to equip a small army." - icon_state = "cargoflag" - -/obj/item/flag/med - name = "\improper Medistan flag" - desc = "The flag of the independent, sovereign nation of Medistan. Looking at this beautiful white and green banner fills you with a powerful compulsion to file malpractice lawsuits." - icon_state = "medflag" - -/obj/item/flag/sec - name = "\improper Brigston flag" - desc = "The flag of the independent, sovereign nation of Brigston. The red of the flag represents blood shed in defense of the station, the amount of which varies heavily between shifts." - icon_state = "secflag" - -/obj/item/flag/rnd - name = "\improper Scientopia flag" - desc = "The flag of the independent, sovereign nation of Scientopia. Looking at this laminated beauty of a flag fills you with an irresstible urge to perform SCIENCE!." - icon_state = "rndflag" - -/obj/item/flag/atmos - name = "\improper Atmosia flag" - desc = "The flag of the independent, sovereign nation of Atmosia. This flag has survived dozens of plasmafires, and will endure more, if Atmosia has any say in things." - icon_state = "atmosflag" - -/obj/item/flag/command - name = "\improper Command flag" - desc = "The flag of the independent, sovereign nation of Command. Apparently the budget was all spent on this flag, rather than a creative name." - icon_state = "ntflag" - -//Antags - -/obj/item/flag/grey - name = "\improper Greytide flag" - desc = "A banner made from an old grey jumpsuit." - icon_state = "greyflag" - -/obj/item/flag/syndi - name = "\improper Syndicate flag" - desc = "A flag proudly boasting the crimson and black colors of the Syndicate, the largest organized criminal entity in the Sector." - icon_state = "syndiflag" - -/obj/item/flag/wiz - name = "\improper Wizard Federation flag" - desc = "A flag proudly boasting the logo of the Wizard Federation, a loose collection of magical terrorist cells." - icon_state = "wizflag" - -/obj/item/flag/cult - name = "\improper Nar'Sie Cultist flag" - desc = "A flag proudly boasting the unholy symbols of the Cult of Nar'sie. Merely possessing this flag is illegal in many polities." - icon_state = "cultflag" - -/obj/item/flag/ussp - name = "\improper USSP flag" - desc = "A flag proudly flying the hammer & sickle of the USSP, a powerful socialist nation in the Sector's North." - icon_state = "usspflag" - -/obj/item/flag/solgov - name = "\improper Trans-Solar Federation flag" - desc = "A flag proudly flying the golden sun of the Trans-Solar Federation, the militaristic de-facto superpower of the sector, based on Earth." - icon_state = "solgovflag" - -//Chameleon - -/obj/item/flag/chameleon - name = "chameleon flag" - desc = "A poor recreation of the official NT flag. It seems to shimmer a little." - icon_state = "ntflag" - origin_tech = "syndicate=1;magnets=4" - var/updated_icon_state = null - var/used = FALSE - var/obj/item/grenade/boobytrap = null - var/mob/trapper = null - -/obj/item/flag/chameleon/New() - updated_icon_state = icon_state - ..() - -/obj/item/flag/chameleon/attack_self__legacy__attackchain(mob/user) - if(used) - return ..() - - var/list/flag_types = typesof(/obj/item/flag) - list(/obj/item/flag, /obj/item/flag/chameleon, /obj/item/flag/chameleon/depot) - var/list/flag = list() - - for(var/flag_type in flag_types) - var/obj/item/flag/F = new flag_type - flag[capitalize(F.name)] = F - - var/list/show_flag = list("EXIT" = null) + sortList(flag) - - var/input_flag = tgui_input_list(user, "Choose a flag to disguise this as.", "Choose a flag.", show_flag) - if(!input_flag) - return - - if(user && (src in user.GetAllContents())) - var/obj/item/flag/chosen_flag = flag[input_flag] - - if(chosen_flag && !used) - name = chosen_flag.name - icon_state = chosen_flag.icon_state - updated_icon_state = icon_state - desc = chosen_flag.desc - used = TRUE - -/obj/item/flag/chameleon/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/grenade) && !boobytrap) - if(user.drop_item()) - boobytrap = I - trapper = user - I.forceMove(src) - to_chat(user, "You hide [I] in [src]. It will detonate some time after the flag is lit on fire.") - var/turf/bombturf = get_turf(src) - var/area/A = get_area(bombturf) - log_game("[key_name(user)] has hidden [I] in [src] ready for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).") - investigate_log("[key_name(user)] has hidden [I] in [src] ready for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).", INVESTIGATE_BOMB) - add_attack_logs(user, src, "has hidden [I] ready for detonation in", ATKLOG_MOST) - else if(I.get_heat() && !(resistance_flags & ON_FIRE) && boobytrap && trapper) - var/turf/bombturf = get_turf(src) - var/area/A = get_area(bombturf) - log_game("[key_name_admin(user)] has lit [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).") - investigate_log("[key_name_admin(user)] has lit [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).", INVESTIGATE_BOMB) - add_attack_logs(user, src, "has lit (booby trapped with [boobytrap]", ATKLOG_FEW) - burn() - else - return ..() - -/obj/item/flag/chameleon/screwdriver_act(mob/user, obj/item/I) - if(!boobytrap || user != trapper) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - to_chat(user, "You remove [boobytrap] from [src].") - boobytrap.forceMove(get_turf(src)) - boobytrap = null - trapper = null - -/obj/item/flag/chameleon/burn() - if(boobytrap) - fire_act() - addtimer(CALLBACK(src, PROC_REF(prime_boobytrap)), boobytrap.det_time) - else - ..() - -/obj/item/flag/chameleon/proc/prime_boobytrap() - boobytrap.forceMove(get_turf(loc)) - boobytrap.prime() - boobytrap = null - burn() - -/obj/item/flag/chameleon/updateFlagIcon() - icon_state = updated_icon_state - -/obj/item/flag/chameleon/depot/New() - ..() - boobytrap = new /obj/item/grenade/gas/plasma(src) diff --git a/code/game/objects/items/granters/_granters.dm b/code/game/objects/items/granters/_granters.dm deleted file mode 100644 index a3954dcf40d90..0000000000000 --- a/code/game/objects/items/granters/_granters.dm +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Books that teach things. - * - * (Intrinsic actions like bar flinging, spells like fireball or smoke, or martial arts) - */ -/obj/item/book/granter - /// Flavor messages displayed to mobs reading the granter - var/list/remarks = list() - /// Controls how long a mob must keep the book in his hand to actually successfully learn - var/pages_to_mastery = 3 - /// Sanity, whether it's currently being read - var/reading = FALSE - /// The amount of uses on the granter. - var/uses = 1 - /// The time it takes to read the book - var/reading_time = 5 SECONDS - /// The sounds played as the user's reading the book. - var/list/book_sounds = list( - 'sound/effects/pageturn1.ogg', - 'sound/effects/pageturn2.ogg', - 'sound/effects/pageturn3.ogg' - ) - -/obj/item/book/granter/attack_self__legacy__attackchain(mob/living/user) - if(reading) - to_chat(user, "You're already reading this!") - return FALSE - if(!user.has_vision()) - to_chat(user, "You are blind and can't read anything!") - return FALSE - if(!isliving(user)) - return FALSE - if(!can_learn(user)) - return FALSE - - if(uses <= 0) - recoil(user) - return FALSE - - on_reading_start(user) - reading = TRUE - for(var/i in 1 to pages_to_mastery) - if(!turn_page(user)) - on_reading_stopped(user) - reading = FALSE - return - if(do_after(user, reading_time, src)) - uses-- - on_reading_finished(user) - reading = FALSE - - return TRUE - -/// Called when the user starts to read the granter. -/obj/item/book/granter/proc/on_reading_start(mob/living/user) - to_chat(user, "You start reading [name]...") - -/// Called when the reading is interrupted without finishing. -/obj/item/book/granter/proc/on_reading_stopped(mob/living/user) - to_chat(user, "You stop reading...") - -/// Called when the reading is completely finished. This is where the actual granting should happen. -/obj/item/book/granter/proc/on_reading_finished(mob/living/user) - to_chat(user, "You finish reading [name]!") - -/// The actual "turning over of the page" flavor bit that happens while someone is reading the granter. -/obj/item/book/granter/proc/turn_page(mob/living/user) - playsound(user, pick(book_sounds), 30, TRUE) - - if(!do_after(user, reading_time, src)) - return FALSE - - to_chat(user, "[length(remarks) ? pick(remarks) : "You keep reading..."]") - return TRUE - -/// Effects that occur whenever the book is read when it has no uses left. -/obj/item/book/granter/proc/recoil(mob/living/user) - return - -/// Checks if the user can learn whatever this granter... grants -/obj/item/book/granter/proc/can_learn(mob/living/user) - return TRUE - -// Generic action giver -/obj/item/book/granter/action - /// The typepath of action that is given - var/datum/action/granted_action - /// The name of the action, formatted in a more text-friendly way. - var/action_name = "" - -/obj/item/book/granter/action/can_learn(mob/living/user) - if(!granted_action) - CRASH("Someone attempted to learn [type], which did not have an action set.") - if(locate(granted_action) in user.actions) - to_chat(user, "You already know all about [action_name]!") - return FALSE - return TRUE - -/obj/item/book/granter/action/on_reading_start(mob/living/user) - to_chat(user, "You start reading about [action_name]...") - -/obj/item/book/granter/action/on_reading_finished(mob/living/user) - to_chat(user, "You feel like you've got a good handle on [action_name]!") - // Action goes on the mind as the user actually learns the thing in your brain - var/datum/action/new_action = new granted_action(user.mind || user) - new_action.Grant(user) - -// Generic action giver -/obj/item/book/granter/spell - /// The typepath of spell that is given - var/datum/spell/granted_spell - /// The name of the spell, formatted in a more text-friendly way - var/spell_name = "" - -/obj/item/book/granter/spell/on_reading_finished(mob/living/user) - if(!user.mind) - return - to_chat(user, "You feel like you've got a good handle on [spell_name]!") - user.mind.AddSpell(new granted_spell(null)) diff --git a/code/game/objects/items/hand_item.dm b/code/game/objects/items/hand_item.dm deleted file mode 100644 index 8bfcc9c0ebc26..0000000000000 --- a/code/game/objects/items/hand_item.dm +++ /dev/null @@ -1,97 +0,0 @@ -/obj/item/slapper - name = "slapper" - desc = "This is how real men fight." - icon_state = "latexballon" - item_state = "nothing" - force = 0 - throwforce = 0 - flags = DROPDEL | ABSTRACT - attack_verb = list("slapped") - hitsound = 'sound/weapons/slap.ogg' - /// How many smaller table smacks we can do before we're out - var/table_smacks_left = 3 - -/obj/item/slapper/attack__legacy__attackchain(mob/M, mob/living/carbon/human/user) - user.do_attack_animation(M) - playsound(M, hitsound, 50, TRUE, -1) - user.visible_message("[user] slaps [M]!", "You slap [M]!", "You hear a slap.") - if(iscarbon(M)) - var/mob/living/carbon/C = M - if(C.IsSleeping()) - C.AdjustSleeping(-15 SECONDS) - if(force) - return ..() - -/obj/item/slapper/attack_self__legacy__attackchain(mob/user) - . = ..() - if(!isliving(user)) - return - var/mob/living/L = user - L.emote("highfive", intentional = TRUE) - -/obj/item/slapper/attack_obj__legacy__attackchain(obj/O, mob/living/user, params) - if(!istype(O, /obj/structure/table)) - return ..() - - var/obj/structure/table/the_table = O - - if(user.a_intent == INTENT_HARM && table_smacks_left == initial(table_smacks_left)) // so you can't do 2 weak slaps followed by a big slam - transform = transform.Scale(1.5) // BIG slap - if(HAS_TRAIT(user, TRAIT_HULK)) - transform = transform.Scale(2) - color = COLOR_GREEN - user.do_attack_animation(the_table) - if(ishuman(user)) - var/mob/living/carbon/human/human_user = user - if(istype(human_user.shoes, /obj/item/clothing/shoes/cowboy)) - human_user.say(pick("Hot damn!", "Hoo-wee!", "Got-dang!")) - playsound(get_turf(the_table), 'sound/effects/tableslam.ogg', 110, TRUE) - user.visible_message("[user] slams [user.p_their()] fist down on [the_table]!", "You slam your fist down on [the_table]!") - qdel(src) - else - user.do_attack_animation(the_table) - playsound(get_turf(the_table), 'sound/effects/tableslam.ogg', 40, TRUE) - user.visible_message("[user] slaps [user.p_their()] hand on [the_table].", "You slap your hand on [the_table].") - table_smacks_left-- - if(table_smacks_left <= 0) - qdel(src) - -/obj/item/slapper/get_clamped_volume() //Without this, you would hear the slap twice if it has force. - return 0 - -/obj/item/slapper/parry - desc = "This is how real men win fights." - force = 5 - flags = DROPDEL | ABSTRACT | NODROP - attack_verb = list("slapped", "backhanded", "smacked", "discombobulated") - table_smacks_left = 10 //Much more smackitude - -/obj/item/slapper/parry/Initialize(mapload) - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = NON_PROJECTILE_ATTACKS, _parry_cooldown = (4 / 3) SECONDS) //75% uptime - if(isliving(loc)) - var/mob/owner = loc - RegisterSignal(owner, COMSIG_MOB_WILLINGLY_DROP, TYPE_PROC_REF(/datum, signal_qdel), override = TRUE) - RegisterSignal(owner, COMSIG_MOB_WEAPON_APPEARS, TYPE_PROC_REF(/datum, signal_qdel), override = TRUE) - return ..() - -/obj/item/slapper/parry/Destroy() - if(isliving(loc)) - var/mob/owner = loc - UnregisterSignal(owner, COMSIG_MOB_WILLINGLY_DROP) - UnregisterSignal(owner, COMSIG_MOB_WEAPON_APPEARS) - return ..() - -/obj/item/slapper/parry/attack__legacy__attackchain(mob/M, mob/living/carbon/human/user) - if(isliving(M)) - var/mob/living/creature = M - SEND_SOUND(creature, sound('sound/weapons/flash_ring.ogg')) - creature.Confused(10 SECONDS) //SMACK CAM - creature.EyeBlind(2 SECONDS) //OH GOD MY EARS ARE RINGING - creature.Deaf(4 SECONDS) //OH MY HEAD - return ..() - -/obj/item/slapper/run_pointed_on_item(mob/pointer_mob, atom/target_atom) - if(target_atom == src) - pointer_mob.visible_message("[pointer_mob] raises [pointer_mob.p_their()] hand!") - return TRUE - return ..() diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm deleted file mode 100644 index d96bed6ad4774..0000000000000 --- a/code/game/objects/items/his_grace.dm +++ /dev/null @@ -1,311 +0,0 @@ -// His Grace is a very special weapon granted only to traitor chaplains. -// When awakened, He thirsts for blood and begins ticking a "bloodthirst" counter. -// The wielder of His Grace is immune to stuns and gradually heals. -// If the wielder fails to feed His Grace in time, He will devour them and become incredibly aggressive. -// Leaving His Grace alone for some time will reset His thirst and put Him to sleep. -// Using His Grace effectively requires extreme speed and care. - -/obj/item/his_grace - name = "artistic toolbox" - desc = "A toolbox painted bright green. Looking at it makes you feel uneasy." - icon = 'icons/obj/storage.dmi' - icon_state = "green" - item_state = "artistic_toolbox" - lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' - w_class = WEIGHT_CLASS_GIGANTIC - force = 20 - attack_verb = list("robusted") - hitsound = 'sound/weapons/smash.ogg' - drop_sound = 'sound/items/handling/toolbox_drop.ogg' - pickup_sound = 'sound/items/handling/toolbox_pickup.ogg' - - /// Is our little toolbox awake? - var/awakened = FALSE - /// How hungry is His Grace? - var/bloodthirst = HIS_GRACE_SATIATED - var/prev_bloodthirst = HIS_GRACE_SATIATED - var/force_bonus = 0 - var/ascended = FALSE - var/victims = 0 - var/victims_needed = 25 - - new_attack_chain = TRUE - -/obj/item/his_grace/Initialize(mapload) - . = ..() - START_PROCESSING(SSprocessing, src) - GLOB.poi_list |= src - RegisterSignal(src, COMSIG_MOVABLE_POST_THROW, PROC_REF(move_gracefully)) - update_icon() - -/obj/item/his_grace/Destroy() - STOP_PROCESSING(SSprocessing, src) - SSblackbox.record_feedback("ledger", "his_grace", victims, "victim_count") - var/mob_counter = 0 - for(var/mob/living/L in src) - L.forceMove(get_turf(src)) - mob_counter++ - SSblackbox.record_feedback("ledger", "his_grace", mob_counter, "mob_count") - GLOB.poi_list -= src - return ..() - -/obj/item/his_grace/update_icon_state() - icon_state = ascended ? "gold" : "green" - item_state = ascended ? "toolbox_gold" : "artistic_toolbox" - -/obj/item/his_grace/update_overlays() - . = ..() - if(ascended) - . += "triple_latch" - else if(awakened) - . += "single_latch_open" - else - . += "single_latch" - -/obj/item/his_grace/activate_self(mob/user) - if(..()) - return FINISH_ATTACK - - if(!awakened) - INVOKE_ASYNC(src, PROC_REF(awaken), user) - -/obj/item/his_grace/attack(mob/living/target, mob/living/user, params) - if(awakened && target.stat) - consume(target) - return FINISH_ATTACK - else - return ..() - -/obj/item/his_grace/attack_obj(obj/attacked_obj, mob/living/user, params) - if(!awakened && (isstructure(attacked_obj) || ismachinery(attacked_obj))) - return ..() - var/mob/living/carbon/human/H = user - H.changeNext_move(CLICK_CD_MELEE) - H.do_attack_animation(attacked_obj) - H.visible_message("[H] has hit [attacked_obj] with [src]!", "You hit [attacked_obj] with [src]!") - var/damage = force - attacked_obj.take_damage(damage * 3, BRUTE, MELEE, TRUE, get_dir(src, user), 30) // yoinked from breaching cleaver - -/obj/item/his_grace/can_be_pulled(user, grab_state, force, show_message = FALSE) //you can't pull his grace - return FALSE - -/obj/item/his_grace/examine(mob/user) - . = ..() - - if(!awakened) - . += "[src] is latched closed." - return - - switch(bloodthirst) - if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH) - . += "[src] isn't very hungry. Not yet." - if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY) - . += "[src] would like a snack." - if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED) - . += "[src] is quite hungry now." - if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING) - . += "[src] is openly salivating at the sight of you. Be careful." - if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER) - . += "You walk a fine line. [src] is very close to devouring you." - if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP) - . += "[src] is shaking violently and staring directly at you." - -/obj/item/his_grace/relaymove(mob/living/user, direction) //Allows changelings, etc. to climb out of Him after they revive, provided He isn't active - if(!awakened) - user.forceMove(get_turf(src)) - user.visible_message("[user] scrambles out of [src]!", "You climb out of [src]!") - -/obj/item/his_grace/process() - if(!bloodthirst) - drowse() - return - if(bloodthirst < HIS_GRACE_CONSUME_OWNER) - adjust_bloodthirst(0.5 + round(length(contents) * (1 / 10), 1)) - else - adjust_bloodthirst(0.5) //don't cool off rapidly once we're at the point where His Grace consumes all. - - var/mob/living/carbon/human/master = get_atom_on_turf(src, /mob/living/carbon/human) // Only humans may wield Him - if(!master || !istype(master)) - go_rabid() - return - - if(!master.is_holding(src)) - go_rabid() - return - - if(bloodthirst <= HIS_GRACE_CONSUME_OWNER || ascended) - master.apply_status_effect(STATUS_EFFECT_HISGRACE) - return - - // They didn't sacrifice enough people, so this is where we go ham - master.visible_message("[src] turns on [master]!", - "[src] turns on you!") - do_attack_animation(master, used_item = src) - master.emote("scream") - master.remove_status_effect(STATUS_EFFECT_HISGRACE) - flags &= ~NODROP - master.Weaken(6 SECONDS) - master.adjustBruteLoss(1000) - playsound(master, 'sound/effects/splat.ogg', 100, FALSE) - go_rabid() - -/obj/item/his_grace/proc/go_rabid() // She Caerbannog on my rabid till I- - forceMove(get_turf(src)) //no you can't put His Grace in a locker you just have to deal with Him - if(bloodthirst < HIS_GRACE_CONSUME_OWNER) - return - if(bloodthirst >= HIS_GRACE_FALL_ASLEEP) - drowse() - return - var/list/targets = list() - for(var/mob/living/L in oview(2, src)) - targets += L - if(!length(targets)) - return - var/mob/living/L = pick(targets) - step_to(src, L) - if(Adjacent(L)) - if(!L.stat) - L.visible_message("[src] lunges at [L]!", "[src] lunges at you!") - do_attack_animation(L, null, src) - playsound(L, 'sound/weapons/smash.ogg', 50, TRUE) - playsound(L, 'sound/misc/desceration-01.ogg', 50, TRUE) - L.adjustBruteLoss(force) - adjust_bloodthirst(-5) //Don't stop attacking they're right there! - else - consume(L) - -/obj/item/his_grace/proc/awaken(mob/user) //Good morning, Mr. Grace. - if(awakened) - return - awakened = TRUE - user.visible_message("[src] begins to rattle. He thirsts.", "You flick [src]'s latch up. You hope this is a good idea.") - name = "His Grace" - desc = "A bloodthirsty artifact created by a profane rite." - gender = MALE - adjust_bloodthirst(1) - force_bonus = HIS_GRACE_FORCE_BONUS * length(contents) - playsound(user, 'sound/effects/pope_entry.ogg', 100) - update_icon() - move_gracefully() - -/obj/item/his_grace/proc/move_gracefully() - SIGNAL_HANDLER - - if(!awakened) - return - animate_rumble(src) - -/obj/item/his_grace/proc/drowse() //Good night, Mr. Grace. - if(!awakened || ascended) - return - var/turf/T = get_turf(src) - T.visible_message("[src] slowly stops rattling and falls still, His latch snapping shut.") - playsound(loc, 'sound/weapons/batonextend.ogg', 100, TRUE) - name = initial(name) - desc = initial(desc) - animate(src, transform = matrix()) - gender = initial(gender) - force = initial(force) - force_bonus = initial(force_bonus) - awakened = FALSE - bloodthirst = 0 - update_icon() - -/obj/item/his_grace/proc/consume(mob/living/meal) //Here's your dinner, Mr. Grace. - if(!meal) - return - - meal.visible_message("[src] swings open and devours [meal]!", "[src] consumes you!") - meal.adjustBruteLoss(300) - playsound(meal, 'sound/misc/desceration-02.ogg', 75, TRUE) - playsound(src, 'sound/items/eatfood.ogg', 100, TRUE) - meal.forceMove(src) - - force_bonus += (ascended ? ASCEND_BONUS : HIS_GRACE_FORCE_BONUS) - - prev_bloodthirst = bloodthirst - if(ascended) // Otherwise there might be fractions where His Grace is droppable while ascended - bloodthirst = prev_bloodthirst - else if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER) - bloodthirst = length(contents) //Never fully sated, and His hunger will only grow. - else - bloodthirst = HIS_GRACE_CONSUME_OWNER - - if(meal.mind) - victims++ - if(victims >= victims_needed) - ascend() - update_stats() - -/obj/item/his_grace/proc/adjust_bloodthirst(amt) - prev_bloodthirst = bloodthirst - if(ascended) - bloodthirst = HIS_GRACE_CONSUME_OWNER // As to maximize their healing buff - update_stats() - return - if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER) - bloodthirst = clamp(bloodthirst + amt, HIS_GRACE_SATIATED, HIS_GRACE_CONSUME_OWNER) - else - bloodthirst = clamp(bloodthirst + amt, HIS_GRACE_CONSUME_OWNER, HIS_GRACE_FALL_ASLEEP) - update_stats() - -/obj/item/his_grace/proc/update_stats() - if(ascended) // Ascended is set to a specific bloodthirst anyways - force = initial(force) + force_bonus - flags |= NODROP - return - - flags &= ~NODROP - var/mob/living/master = get_atom_on_turf(src, /mob/living) - switch(bloodthirst) - if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP) - if(HIS_GRACE_CONSUME_OWNER > prev_bloodthirst) - master.visible_message("[src] enters a frenzy!") - if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER) - flags |= NODROP - if(HIS_GRACE_STARVING > prev_bloodthirst) - master.visible_message("[src] is starving!", "[src]'s bloodlust overcomes you. [src] must be fed, or you will become His meal.\ - [force_bonus < 15 ? " And still, His power grows.":""]") - force_bonus = max(force_bonus, 15) - if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING) - flags |= NODROP - if(HIS_GRACE_FAMISHED > prev_bloodthirst) - master.visible_message("[src] is very hungry!", "Spines sink into your hand. [src] must feed immediately.\ - [force_bonus < 10 ? " His power grows.":""]") - force_bonus = max(force_bonus, 10) - if(prev_bloodthirst >= HIS_GRACE_STARVING) - master.visible_message("[src] is now only very hungry!", "Your bloodlust recedes.") - if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED) - if(HIS_GRACE_HUNGRY > prev_bloodthirst) - master.visible_message("[src] is getting hungry.", "You feel [src]'s hunger within you.\ - [force_bonus < 5 ? " His power grows.":""]") - force_bonus = max(force_bonus, 5) - if(prev_bloodthirst >= HIS_GRACE_FAMISHED) - master.visible_message("[src] is now only somewhat hungry.", "[src]'s hunger recedes a little...") - if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY) - if(HIS_GRACE_PECKISH > prev_bloodthirst) - master.visible_message("[src] is feeling snackish.", "[src] begins to hunger.") - if(prev_bloodthirst >= HIS_GRACE_HUNGRY) - master.visible_message("[src] is now only a little peckish.", "[src]'s hunger recedes somewhat...") - if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH) - if(prev_bloodthirst >= HIS_GRACE_PECKISH) - master.visible_message("[src] is satiated.", "[src]'s hunger recedes...") - force = initial(force) + force_bonus - -/obj/item/his_grace/proc/ascend() - if(ascended) - return - desc = "A legendary toolbox and a distant artifact from The Age of Three Powers. On its three latches engraved are the words \"The Sun\", \"The Moon\", and \"The Stars\". The entire toolbox has the words \"The World\" engraved into its sides." - icon_state = "his_grace_ascended" - item_state = "toolbox_gold" - ascended = TRUE - SSblackbox.record_feedback("amount", "his_grace_ascended", 1) - update_icon() - playsound(src, 'sound/effects/his_grace_ascend.ogg', 100) - var/mob/living/carbon/human/master = loc - if(istype(master)) - master.visible_message("Gods will be watching.") - name = "[master]'s mythical toolbox of three powers" - master.update_inv_l_hand() - master.update_inv_r_hand() diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm deleted file mode 100644 index 0501b49aa7b8e..0000000000000 --- a/code/game/objects/items/latexballoon.dm +++ /dev/null @@ -1,66 +0,0 @@ -/obj/item/latexballon - name = "latex glove" - desc = "You wanted a fiery fist o' pain, but all you got was this dumb balloon." - icon_state = "latexballon" - item_state = "lgloves" - force = 0 - throwforce = 0 - w_class = WEIGHT_CLASS_TINY - throw_speed = 1 - throw_range = 7 - var/state - var/datum/gas_mixture/air_contents = null - -/obj/item/latexballon/Destroy() - QDEL_NULL(air_contents) - return ..() - -/obj/item/latexballon/proc/blow(obj/item/tank/tank, mob/user) - if(icon_state == "latexballon_bursted") - return - icon_state = "latexballon_blow" - item_state = "latexballon" - user.update_inv_r_hand() - user.update_inv_l_hand() - to_chat(user, "You blow up [src] with [tank].") - air_contents = tank.remove_air_volume(3) - -/obj/item/latexballon/proc/burst() - if(!air_contents || icon_state != "latexballon_blow") - return - playsound(src, 'sound/weapons/gunshots/gunshot.ogg', 100, 1) - icon_state = "latexballon_bursted" - item_state = "lgloves" - if(isliving(loc)) - var/mob/living/user = loc - user.update_inv_r_hand() - user.update_inv_l_hand() - var/turf/T = get_turf(src) - T.blind_release_air(air_contents) - -/obj/item/latexballon/ex_act(severity) - burst() - switch(severity) - if(1) - qdel(src) - if(2) - if(prob(50)) - qdel(src) - -/obj/item/latexballon/bullet_act(obj/item/projectile/P) - if(!P.nodamage) - burst() - return ..() - -/obj/item/latexballon/temperature_expose(datum/gas_mixture/air, temperature, volume) - ..() - if(temperature > T0C+100) - burst() - -/obj/item/latexballon/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(istype(W, /obj/item/tank)) - var/obj/item/tank/T = W - blow(T, user) - return - if(W.sharp || W.get_heat() || is_pointed(W)) - burst() diff --git a/code/game/objects/items/mixing_bowl.dm b/code/game/objects/items/mixing_bowl.dm deleted file mode 100644 index 665bbb3cb3fb3..0000000000000 --- a/code/game/objects/items/mixing_bowl.dm +++ /dev/null @@ -1,171 +0,0 @@ - -/obj/item/mixing_bowl - name = "mixing bowl" - desc = "Mixing it up in the kitchen." - container_type = OPENCONTAINER - icon = 'icons/obj/kitchen.dmi' - icon_state = "mixing_bowl" - var/max_n_of_items = 25 - var/dirty = FALSE - var/clean_icon = "mixing_bowl" - var/dirty_icon = "mixing_bowl_dirty" - -/obj/item/mixing_bowl/New() - ..() - create_reagents(100) - -/obj/item/mixing_bowl/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(dirty) - if(istype(I, /obj/item/soap)) - user.visible_message("[user] starts to scrub [src].", "You start to scrub [src].") - if(do_after(user, 20 * I.toolspeed, target = src)) - clean() - user.visible_message("[user] has scrubbed [src] clean.", "You have scrubbed [src] clean.") - return 1 - else - to_chat(user, "You should clean [src] before you use it for food prep.") - return 0 - if(is_type_in_list(I, GLOB.cooking_ingredients[RECIPE_MICROWAVE]) || is_type_in_list(I, GLOB.cooking_ingredients[RECIPE_GRILL]) || is_type_in_list(I, GLOB.cooking_ingredients[RECIPE_OVEN]) || is_type_in_list(I, GLOB.cooking_ingredients[RECIPE_CANDY])) - if(length(contents)>=max_n_of_items) - to_chat(user, "This [src] is full of ingredients, you cannot put more.") - return 1 - if(istype(I, /obj/item/stack)) - var/obj/item/stack/S = I - if(S.get_amount() > 1) - var/obj/item/stack/to_add = S.split(user, 1) - to_add.forceMove(src) - user.visible_message("[user] adds one of [S] to [src].", "You add one of [S] to [src].") - else - return add_item(S, user) - else - return add_item(I, user) - else if(is_type_in_list(I, list(/obj/item/reagent_containers/glass, /obj/item/reagent_containers/drinks, /obj/item/reagent_containers/condiment))) - if(!I.reagents) - return 1 - for(var/datum/reagent/R in I.reagents.reagent_list) - if(!(R.id in GLOB.cooking_reagents[RECIPE_MICROWAVE]) && !(R.id in GLOB.cooking_reagents[RECIPE_GRILL]) && !(R.id in GLOB.cooking_reagents[RECIPE_OVEN]) && !(R.id in GLOB.cooking_reagents[RECIPE_CANDY])) - to_chat(user, "Your [I] contains components unsuitable for cookery.") - return 1 - else - to_chat(user, "You have no idea what you can cook with [I].") - return 1 - -/obj/item/mixing_bowl/proc/add_item(obj/item/I, mob/user) - if(!user.drop_item()) - to_chat(user, "\The [I] is stuck to your hand, you cannot put it in [src]") - //return 0 - else - I.forceMove(src) - user.visible_message("[user] adds [I] to [src].", "You add [I] to [src].") - -/obj/item/mixing_bowl/attack_self__legacy__attackchain(mob/user) - var/dat = "" - if(dirty) - dat = {"This [src] is dirty!
    Please clean it before use!
    "} - else - var/list/items_counts = list() - var/list/items_measures = list() - var/list/items_measures_p = list() - for(var/obj/O in contents) - var/display_name = O.name - if(istype(O,/obj/item/food/egg)) - items_measures[display_name] = "egg" - items_measures_p[display_name] = "eggs" - if(istype(O,/obj/item/food/tofu)) - items_measures[display_name] = "tofu chunk" - items_measures_p[display_name] = "tofu chunks" - if(istype(O,/obj/item/food/meat)) //any meat - items_measures[display_name] = "slab of meat" - items_measures_p[display_name] = "slabs of meat" - if(istype(O,/obj/item/food/donkpocket)) - display_name = "Turnovers" - items_measures[display_name] = "turnover" - items_measures_p[display_name] = "turnovers" - if(istype(O,/obj/item/food/carpmeat)) - items_measures[display_name] = "fillet of meat" - items_measures_p[display_name] = "fillets of meat" - items_counts[display_name]++ - for(var/O in items_counts) - var/N = items_counts[O] - if(!(O in items_measures)) - dat += {"[capitalize(O)]: [N] [lowertext(O)]\s
    "} - else - if(N==1) - dat += {"[capitalize(O)]: [N] [items_measures[O]]
    "} - else - dat += {"[capitalize(O)]: [N] [items_measures_p[O]]
    "} - - for(var/datum/reagent/R in reagents.reagent_list) - var/display_name = R.name - if(R.id == "capsaicin") - display_name = "Hotsauce" - if(R.id == "frostoil") - display_name = "Coldsauce" - dat += {"[display_name]: [R.volume] unit\s
    "} - - if(length(items_counts)==0 && length(reagents.reagent_list)==0) - dat = {"[src] is empty
    "} - else - dat = {"Ingredients:
    [dat]"} - dat += {"

    Dispose ingredients!
    "} - - var/datum/browser/popup = new(user, name, name, 400, 400) - popup.set_content(dat) - popup.open(0) - onclose(user, "[name]") - return - -/obj/item/mixing_bowl/Topic(href, href_list) - if(..()) - return - switch(href_list["action"]) - if("dispose") - dispose() - return - -/obj/item/mixing_bowl/proc/dispose() - for(var/obj/O in contents) - O.forceMove(loc) - if(reagents.total_volume) - make_dirty(5) - reagents.clear_reagents() - to_chat(usr, "You dispose of [src]'s contents.") - updateUsrDialog() - -/obj/item/mixing_bowl/proc/make_dirty(chance) - if(!chance) - return - if(prob(chance)) - dirty = TRUE - container_type = null - icon_state = dirty_icon - -/obj/item/mixing_bowl/proc/clean() - dirty = FALSE - container_type = OPENCONTAINER - icon_state = clean_icon - -/obj/item/mixing_bowl/wash(mob/user, atom/source) - if(..()) - clean() - -/obj/item/mixing_bowl/proc/fail(obj/source) - if(!source) - source = src - var/amount = 0 - for(var/obj/O in contents) - amount++ - if(O.reagents) - var/id = O.reagents.get_master_reagent_id() - if(id) - amount+=O.reagents.get_reagent_amount(id) - qdel(O) - if(reagents && reagents.total_volume) - var/id = reagents.get_master_reagent_id() - if(id) - amount += reagents.get_reagent_amount(id) - reagents.clear_reagents() - var/obj/item/food/badrecipe/mysteryfood = new(get_turf(source)) - mysteryfood.reagents.add_reagent("carbon", amount) - mysteryfood.reagents.add_reagent("????", amount / 10) - make_dirty(75) diff --git a/code/game/objects/items/mountable_frames/mountables.dm b/code/game/objects/items/mountable_frames/mountables.dm deleted file mode 100644 index 99b2a7f55d8bf..0000000000000 --- a/code/game/objects/items/mountable_frames/mountables.dm +++ /dev/null @@ -1,33 +0,0 @@ -/obj/item/mounted - var/list/buildon_types = list( - /turf/simulated/mineral/ancient, - /turf/simulated/wall - ) - var/allow_floor_mounting = FALSE - - -/obj/item/mounted/afterattack__legacy__attackchain(atom/A, mob/user, proximity_flag) - if(is_type_in_list(A, buildon_types)) - if(try_build(A, user, proximity_flag)) - return do_build(A, user) - ..() - -/obj/item/mounted/proc/try_build(turf/on_wall, mob/user, proximity_flag) //checks - if(!on_wall || !user) - return FALSE - if(!proximity_flag) //if we aren't next to the turf - return FALSE - - if(!allow_floor_mounting) - if(!(get_dir(on_wall, user) in GLOB.cardinal)) - to_chat(user, "You need to be standing next to [on_wall] to place [src].") - return FALSE - - if(gotwallitem(get_turf(user), get_dir(user, on_wall))) - to_chat(user, "There's already an item on this wall!") - return FALSE - - return TRUE - -/obj/item/mounted/proc/do_build(turf/on_wall, mob/user) //the buildy bit after we pass the checks - return diff --git a/code/game/objects/items/random_items.dm b/code/game/objects/items/random_items.dm deleted file mode 100644 index fc256cf698e7c..0000000000000 --- a/code/game/objects/items/random_items.dm +++ /dev/null @@ -1,105 +0,0 @@ -// ------------------------------------- -// Generates an innocuous toy -// ------------------------------------- -/obj/item/toy/random - name = "Random Toy" - -/obj/item/toy/random/Initialize(mapload) - ..() - var/list/types = list(/obj/item/gun/projectile/shotgun/toy/crossbow, /obj/item/toy/balloon,/obj/item/toy/spinningtoy,/obj/item/reagent_containers/spray/waterflower) + subtypesof(/obj/item/toy/figure/mech) - var/T = pick(types) - new T(loc) - return INITIALIZE_HINT_QDEL - -// ------------------------------------- -// Random cleanables, clearly this makes sense -// ------------------------------------- - -/obj/effect/decal/cleanable/random - name = "Random Mess" - -/obj/effect/decal/cleanable/random/Initialize(mapload) - . = ..() - var/list/list = subtypesof(/obj/effect/decal/cleanable) - list(/obj/effect/decal/cleanable/random,/obj/effect/decal/cleanable/cobweb,/obj/effect/decal/cleanable/cobweb2) - var/T = pick(list) - new T(loc) - qdel(src) - -/obj/item/reagent_containers/drinks/bottle/random_drink - name = "unlabelled drink" - icon = 'icons/obj/drinks.dmi' - -/obj/item/reagent_containers/drinks/bottle/random_drink/Initialize(mapload) - . = ..() - var/list/possible_drinks = GLOB.drinks.Copy() - if(prob(50)) - possible_drinks += list("pancuronium","lsd","omnizine","blood") - - var/datum/reagent/R = pick(possible_drinks) - reagents.add_reagent(R, volume) - name = "unlabelled bottle" - icon_state = pick("alco-white","alco-green","alco-blue","alco-clear","alco-red") - scatter_atom() - -/obj/item/storage/pill_bottle/random_meds - name = "unlabelled pillbottle" - desc = "The sheer recklessness of this bottle's existence astounds you." - allow_wrap = FALSE - var/labelled = FALSE - scatter_distance = 10 - -/obj/item/storage/pill_bottle/random_meds/Initialize(mapload) - . = ..() - scatter_atom() - -/obj/item/storage/pill_bottle/random_meds/populate_contents() - var/list/possible_meds_standard = GLOB.standard_medicines.Copy() - var/list/possible_meds_rare = GLOB.rare_medicines.Copy() - for(var/i in 1 to storage_slots) - var/is_rare = prob(33) - var/possible_meds = is_rare ? possible_meds_rare : possible_meds_standard - - var/datum/reagent/R = pick(possible_meds) - var/obj/item/reagent_containers/pill/P = new(src) - - if(is_rare) - P.reagents.add_reagent(R, 10) - else - P.reagents.add_reagent(R, rand(2, 5)*10) - if(labelled) - P.name = "[R] Pill" - P.desc = "A pill containing [R]." - else - P.name = "Unlabelled Pill" - P.desc = "Something about this pill entices you to try it, against your better judgement." - - -/obj/item/storage/pill_bottle/random_meds/labelled - name = "variety pillbottle" - labelled = TRUE - -// -------------------------------------- -// Collen's box of wonder and mystery -// -------------------------------------- -/obj/item/storage/box/grenades - name = "tactical grenades" - desc = "A box with 6 tactical grenades." - icon_state = "grenade_box" - -/obj/item/storage/box/grenades/populate_contents() - var/static/list/grenadelist = list( - /obj/item/grenade/chem_grenade/metalfoam, - /obj/item/grenade/chem_grenade/incendiary, - /obj/item/grenade/chem_grenade/antiweed, - /obj/item/grenade/chem_grenade/cleaner, - /obj/item/grenade/chem_grenade/teargas, - /obj/item/grenade/chem_grenade/holywater, - /obj/item/grenade/chem_grenade/meat, - /obj/item/grenade/chem_grenade/dirt, - /obj/item/grenade/chem_grenade/lube, - /obj/item/grenade/smokebomb, - /obj/item/grenade/chem_grenade/drugs, - /obj/item/grenade/chem_grenade/ethanol) // holy list batman - for(var/i in 1 to 6) - var/nade = pick(grenadelist) - new nade(src) diff --git a/code/game/objects/items/robot/ai_upgrades.dm b/code/game/objects/items/robot/ai_upgrades.dm deleted file mode 100644 index db0e5955e3ade..0000000000000 --- a/code/game/objects/items/robot/ai_upgrades.dm +++ /dev/null @@ -1,40 +0,0 @@ -///AI Upgrades - - -//Malf Picker -/obj/item/malf_upgrade - name = "combat software upgrade" - desc = "A highly illegal, highly dangerous upgrade for artificial intelligence units, granting them a variety of powers as well as the ability to hack APCs." - icon = 'icons/obj/module.dmi' - icon_state = "datadisk3" - - -/obj/item/malf_upgrade/afterattack__legacy__attackchain(mob/living/silicon/ai/AI, mob/user) - if(!istype(AI)) - return - if(AI.malf_picker) - AI.malf_picker.processing_time += 50 - to_chat(AI, "[user] has attempted to upgrade you with combat software that you already possess. You gain 50 points to spend on Malfunction Modules instead.") - else - to_chat(AI, "[user] has upgraded you with combat software!") - AI.add_malf_picker() - to_chat(user, "You upgrade [AI]. [src] is consumed in the process.") - qdel(src) - - -//Lipreading -/obj/item/surveillance_upgrade - name = "surveillance software upgrade" - desc = "A software package that will allow an artificial intelligence to 'hear' from its cameras via lip reading." - icon = 'icons/obj/module.dmi' - icon_state = "datadisk3" - -/obj/item/surveillance_upgrade/afterattack__legacy__attackchain(mob/living/silicon/ai/AI, mob/user) - if(!istype(AI)) - return - if(AI.eyeobj) - AI.eyeobj.relay_speech = 1 - to_chat(AI, "[user] has upgraded you with surveillance software!") - to_chat(AI, "Via a combination of hidden microphones and lip reading software, you are able to use your cameras to listen in on conversations.") - to_chat(user, "You upgrade [AI]. [src] is consumed in the process.") - qdel(src) diff --git a/code/game/objects/items/robot/items/inflatable_tool.dm b/code/game/objects/items/robot/items/inflatable_tool.dm deleted file mode 100644 index 0bf7cd77f68d2..0000000000000 --- a/code/game/objects/items/robot/items/inflatable_tool.dm +++ /dev/null @@ -1,44 +0,0 @@ -/obj/item/inflatable/cyborg - name = "inflatable wall" - desc = "A folded membrane which rapidly expands into a large cubical shape on activation." - var/power_use = 400 - var/structure_type = /obj/structure/inflatable - /// How long it takes to inflate - var/delay = 1 SECONDS - -/obj/item/inflatable/cyborg/door - name = "inflatable door" - desc = "A folded membrane which rapidly expands into a simple door on activation." - icon_state = "folded_door" - power_use = 600 - structure_type = /obj/structure/inflatable/door - -/obj/item/inflatable/cyborg/examine(mob/user) - . = ..() - . += "As a synthetic, you can restore them at a cyborg recharger." - -/obj/item/inflatable/cyborg/attack_self__legacy__attackchain(mob/user) - if(locate(/obj/structure/inflatable) in get_turf(user)) - to_chat(user, "There's already an inflatable structure!") - return FALSE - - if(!do_after(user, delay, FALSE, user)) - return FALSE - - if(!useResource(user)) - return FALSE - - playsound(loc, 'sound/items/zip.ogg', 75, TRUE) - to_chat(user, "You inflate [src].") - var/obj/structure/inflatable/R = new structure_type(user.loc) - transfer_fingerprints_to(R) - R.add_fingerprint(user) - -/obj/item/inflatable/cyborg/proc/useResource(mob/user) - if(!isrobot(user)) - return FALSE - var/mob/living/silicon/robot/R = user - if(R.cell.charge < power_use) - to_chat(user, "Not enough power!") - return FALSE - return R.cell.use(power_use) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm deleted file mode 100644 index 93343db64522b..0000000000000 --- a/code/game/objects/items/robot/robot_parts.dm +++ /dev/null @@ -1,424 +0,0 @@ -/obj/item/robot_parts - name = "robot parts" - icon = 'icons/obj/robot_parts.dmi' - item_state = "buildpipe" - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - var/list/part = null - var/sabotaged = FALSE //Emagging limbs can have repercussions when installed as prosthetics. - var/model_info = "Unbranded" - dir = SOUTH - -/obj/item/robot_parts/New(newloc, model) - ..(newloc) - if(model_info && model) - model_info = model - var/datum/robolimb/R = GLOB.all_robolimbs[model] - if(R) - name = "[R.company] [initial(name)]" - desc = "[R.desc]" - if(icon_state in icon_states(R.icon)) - icon = R.icon - else - name = "robot [initial(name)]" - - AddComponent(/datum/component/surgery_initiator/limb, forced_surgery = /datum/surgery/attach_robotic_limb) - -/obj/item/robot_parts/attack_self__legacy__attackchain(mob/user) - var/choice = tgui_input_list(user, "Select the company appearance for this limb", "Limb Company Selection", GLOB.selectable_robolimbs) - if(!choice) - return - if(loc != user) - return - model_info = choice - to_chat(usr, "You change the company limb model to [choice].") - -/obj/item/robot_parts/l_arm - name = "left arm" - desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." - icon_state = "l_arm" - part = list("l_arm","l_hand") - -/obj/item/robot_parts/r_arm - name = "right arm" - desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." - icon_state = "r_arm" - part = list("r_arm","r_hand") - -/obj/item/robot_parts/l_leg - name = "left leg" - desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." - icon_state = "l_leg" - part = list("l_leg","l_foot") - -/obj/item/robot_parts/r_leg - name = "right leg" - desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." - icon_state = "r_leg" - part = list("r_leg","r_foot") - -/obj/item/robot_parts/chest - name = "torso" - desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell." - icon_state = "chest" - part = list("groin","chest") - var/wired = FALSE - var/obj/item/stock_parts/cell/cell = null - -/obj/item/robot_parts/chest/Destroy() - QDEL_NULL(cell) - return ..() - -/obj/item/robot_parts/head - name = "head" - desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals." - icon_state = "head" - part = list("head") - var/obj/item/flash/flash1 = null - var/obj/item/flash/flash2 = null - -/obj/item/robot_parts/head/Destroy() - QDEL_NULL(flash1) - QDEL_NULL(flash2) - return ..() - -/obj/item/robot_parts/robot_suit - name = "endoskeleton" - desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors." - icon_state = "robo_suit" - w_class = WEIGHT_CLASS_BULKY - model_info = null - var/obj/item/robot_parts/l_arm/l_arm = null - var/obj/item/robot_parts/r_arm/r_arm = null - var/obj/item/robot_parts/l_leg/l_leg = null - var/obj/item/robot_parts/r_leg/r_leg = null - var/obj/item/robot_parts/chest/chest = null - var/obj/item/robot_parts/head/head = null - - var/created_name = "" - var/mob/living/silicon/ai/forced_ai - var/locomotion = 1 - var/lawsync = 1 - var/aisync = 1 - var/panel_locked = 1 - -/obj/item/robot_parts/robot_suit/New() - ..() - update_icon(UPDATE_OVERLAYS) - -/obj/item/robot_parts/robot_suit/Destroy() - QDEL_NULL(l_arm) - QDEL_NULL(r_arm) - QDEL_NULL(l_leg) - QDEL_NULL(r_leg) - QDEL_NULL(chest) - QDEL_NULL(head) - forced_ai = null - return ..() - -/obj/item/robot_parts/robot_suit/attack_self__legacy__attackchain(mob/user) - return - -/obj/item/robot_parts/robot_suit/update_overlays() - . = ..() - if(l_arm) - . += "l_arm+o" - if(r_arm) - . += "r_arm+o" - if(chest) - . += "chest+o" - if(l_leg) - . += "l_leg+o" - if(r_leg) - . += "r_leg+o" - if(head) - . += "head+o" - -/obj/item/robot_parts/robot_suit/proc/check_completion() - if(l_arm && r_arm) - if(l_leg && r_leg) - if(chest && head) - SSblackbox.record_feedback("amount", "cyborg_frames_built", 1) - return 1 - return 0 - -/obj/item/robot_parts/robot_suit/attackby__legacy__attackchain(obj/item/W, mob/user, params) - ..() - if(istype(W, /obj/item/stack/sheet/metal) && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head) - var/obj/item/stack/sheet/metal/M = W - var/obj/item/ed209_assembly/B = new /obj/item/ed209_assembly - B.forceMove(get_turf(src)) - to_chat(user, "You armed the robot frame") - M.use(1) - if(user.get_inactive_hand()==src) - user.unequip(src) - user.put_in_inactive_hand(B) - qdel(src) - if(istype(W, /obj/item/robot_parts/l_leg)) - if(l_leg) - return - user.drop_item() - W.forceMove(src) - l_leg = W - update_icon(UPDATE_OVERLAYS) - - if(istype(W, /obj/item/robot_parts/r_leg)) - if(r_leg) - return - user.drop_item() - W.forceMove(src) - r_leg = W - update_icon(UPDATE_OVERLAYS) - - if(istype(W, /obj/item/robot_parts/l_arm)) - if(l_arm) - return - user.drop_item() - W.forceMove(src) - l_arm = W - update_icon(UPDATE_OVERLAYS) - - if(istype(W, /obj/item/robot_parts/r_arm)) - if(r_arm) - return - user.drop_item() - W.forceMove(src) - r_arm = W - update_icon(UPDATE_OVERLAYS) - - if(istype(W, /obj/item/robot_parts/chest)) - var/obj/item/robot_parts/chest/CH = W - if(chest) - return - if(CH.wired && CH.cell) - user.drop_item() - W.forceMove(src) - chest = W - update_icon(UPDATE_OVERLAYS) - else if(!CH.wired) - to_chat(user, "You need to attach wires to it first!") - else - to_chat(user, "You need to attach a cell to it first!") - - if(istype(W, /obj/item/robot_parts/head)) - var/obj/item/robot_parts/head/HD = W - if(head) - return - if(HD.flash2 && HD.flash1) - user.drop_item() - W.forceMove(src) - head = W - update_icon(UPDATE_OVERLAYS) - else - to_chat(user, "You need to attach a flash to it first!") - - if(istype(W, /obj/item/multitool)) - if(check_completion()) - Interact(user) - else - to_chat(user, "The endoskeleton must be assembled before debugging can begin!") - - if(istype(W, /obj/item/mmi)) - var/obj/item/mmi/M = W - if(check_completion()) - if(!isturf(loc)) - to_chat(user, "You can't put [M] in, the frame has to be standing on the ground to be perfectly precise.") - return - if(!M.brainmob) - to_chat(user, "Sticking an empty [M] into the frame would sort of defeat the purpose.") - return - - if(jobban_isbanned(M.brainmob, "Cyborg") || jobban_isbanned(M.brainmob, "nonhumandept")) - to_chat(user, "This [W] is not fit to serve as a cyborg!") - return - - if(!M.brainmob.key) - var/mob/dead/observer/G = M.brainmob.get_ghost() - if(G) - if(M.next_possible_ghost_ping < world.time) - G.notify_cloning("Somebody is trying to borg you! Re-enter your corpse if you want to be borged!", 'sound/voice/liveagain.ogg', src) - M.next_possible_ghost_ping = world.time + 30 SECONDS // Avoid spam - else - to_chat(user, "[M] is completely unresponsive; there's no point.") - return - to_chat(user, "[M] is currently inactive. Try again later.") - return - - if(M.brainmob.stat == DEAD) - to_chat(user, "Sticking a dead [M] into the frame would sort of defeat the purpose.") - return - - if(M.brainmob.mind?.has_antag_datum(/datum/antagonist/rev/head)) - to_chat(user, "The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept [M].") - return - - - var/datum/ai_laws/laws_to_give - - if(!aisync) - lawsync = FALSE - - var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc), unfinished = 1, connect_to_AI = aisync, ai_to_sync_to = forced_ai) - if(!O) - return - - user.drop_item() - - var/datum/job_objective/make_cyborg/task = user.mind.find_job_task(/datum/job_objective/make_cyborg) - if(istype(task)) - task.completed = TRUE - - O.invisibility = 0 - //Transfer debug settings to new mob - O.custom_name = created_name - O.rename_character(O.real_name, O.get_default_name()) - O.locked = panel_locked - - if(laws_to_give) - O.laws = laws_to_give - else if(!lawsync) - O.lawupdate = FALSE - O.make_laws() - - M.brainmob.mind.transfer_to(O) - - if(O.mind && O.mind.special_role && !M.syndiemmi) - O.mind.store_memory("As a cyborg, you must obey your silicon laws and master AI above all else. Your objectives will consider you to be dead.") - to_chat(O, "You have been robotized!") - to_chat(O, "You must obey your silicon laws and master AI above all else. Your objectives will consider you to be dead.") - - O.job = "Cyborg" - - var/datum/robot_component/cell_component = O.components["power cell"] - cell_component.install(chest.cell) - chest.cell = null - - M.forceMove(O) //Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. - O.mmi = W - if(O.mmi.syndiemmi) - O.syndiemmi_override() - to_chat(O, "ALERT: Foreign hardware detected.") - to_chat(O, "ERRORERRORERROR") - to_chat(O, "Obey these laws:") - O.laws.show_laws(O) - O.Namepick() - - SSblackbox.record_feedback("amount", "cyborg_birth", 1) - - forceMove(O) - O.robot_suit = src - - if(!locomotion) - O.SetLockdown(TRUE) - to_chat(O, "Error: Servo motors unresponsive. Lockdown enabled.") - - else - to_chat(user, "The MMI must go in after everything else!") - - if(is_pen(W)) - to_chat(user, "You need to use a multitool to name [src]!") - return - -/obj/item/robot_parts/robot_suit/proc/Interact(mob/user) - var/t1 = "Designation: [(created_name ? "[created_name]" : "Default Cyborg")]
    \n" - t1 += "Master AI: [(forced_ai ? "[forced_ai.name]" : "Automatic")]

    \n" - - t1 += "LawSync Port: [(lawsync ? "Open" : "Closed")]
    \n" - t1 += "AI Connection Port: [(aisync ? "Open" : "Closed")]
    \n" - t1 += "Servo Motor Functions: [(locomotion ? "Unlocked" : "Locked")]
    \n" - t1 += "Panel Lock: [(panel_locked ? "Engaged" : "Disengaged")]
    \n" - var/datum/browser/popup = new(user, "robotdebug", "Cyborg Boot Debug", 310, 220) - popup.set_content(t1) - popup.open() - -/obj/item/robot_parts/robot_suit/Topic(href, href_list) - var/mob/living/living_user = usr - if(HAS_TRAIT(living_user, TRAIT_HANDS_BLOCKED) || living_user.stat || !Adjacent(living_user)) - return - var/obj/item/item_in_hand = living_user.get_active_hand() - if(!istype(item_in_hand, /obj/item/multitool)) - to_chat(living_user, "You need a multitool!") - return - - if(href_list["Name"]) - var/new_name = reject_bad_name(input(usr, "Enter new designation. Set to blank to reset to default.", "Cyborg Debug", created_name),1) - if(!in_range(src, usr) && loc != usr) - return - if(new_name) - created_name = new_name - else - created_name = "" - - else if(href_list["Master"]) - forced_ai = select_active_ai(usr) - if(!forced_ai) - to_chat(usr, "No active AIs detected.") - - else if(href_list["Law"]) - lawsync = !lawsync - else if(href_list["AI"]) - aisync = !aisync - else if(href_list["Loco"]) - locomotion = !locomotion - else if(href_list["Panel"]) - panel_locked = !panel_locked - - add_fingerprint(usr) - Interact(usr) - return - -/obj/item/robot_parts/chest/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) - ..() - if(istype(W, /obj/item/stock_parts/cell)) - if(cell) - to_chat(user, "You have already inserted a cell!") - return - else - user.drop_item() - W.forceMove(src) - cell = W - to_chat(user, "You insert the cell!") - if(istype(W, /obj/item/stack/cable_coil)) - if(wired) - to_chat(user, "You have already inserted wire!") - return - else - var/obj/item/stack/cable_coil/coil = W - coil.use(1) - wired = TRUE - to_chat(user, "You insert the wire!") - return - -/obj/item/robot_parts/head/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) - ..() - if(istype(W, /obj/item/flash)) - if(isrobot(user)) - to_chat(user, "How do you propose to do that?") - return - else if(flash1 && flash2) - to_chat(user, "You have already inserted the eyes!") - return - else if(flash1) - user.drop_item() - W.forceMove(src) - flash2 = W - to_chat(user, "You insert the flash into the eye socket!") - else - user.drop_item() - W.forceMove(src) - flash1 = W - to_chat(user, "You insert the flash into the eye socket!") - else if(istype(W, /obj/item/stock_parts/manipulator)) - to_chat(user, "You install some manipulators and modify the head, creating a functional spider-bot!") - new /mob/living/simple_animal/spiderbot(get_turf(loc)) - user.drop_item() - qdel(W) - qdel(src) - -/obj/item/robot_parts/emag_act(user) - if(sabotaged) - to_chat(user, "[src] is already sabotaged!") - else - to_chat(user, "You slide the emag into the dataport on [src] and short out the safeties.") - sabotaged = TRUE - return TRUE diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm deleted file mode 100644 index 9d476d964ee77..0000000000000 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ /dev/null @@ -1,523 +0,0 @@ -// robot_upgrades.dm -// Contains various borg upgrades. - -/obj/item/borg/upgrade - name = "borg upgrade module." - desc = "Protected by FRM." - icon = 'icons/obj/module.dmi' - icon_state = "cyborg_upgrade" - origin_tech = "programming=2" - /// Whether or not the cyborg needs to have a chosen module before they can receive this upgrade. - var/require_module = FALSE - /// The type of module this upgrade is compatible with: Engineering, Medical, etc. - var/module_type = null - /// A list of items, and their replacements that this upgrade should replace on installation, in the format of `item_type_to_replace = replacement_item_type`. - var/list/items_to_replace = list() - /// A list of items to add, rather than replace - var/list/items_to_add = list() - /// A list of replacement items will need to be placed into a cyborg module's `special_rechargable` list after this upgrade is installed. - var/list/special_rechargables = list() - /// Allow the same upgrade to be installed multiple times, FALSE by default - var/allow_duplicate = FALSE - /// Delete the module after installing it. For deleting upgrades that might be installed multiple times, like the rename/reset upgrades. - var/delete_after_install = FALSE - -/** - * Called when someone clicks on a borg with an upgrade in their hand. - * - * Arguments: - * * R - the cyborg that was clicked on with an upgrade. - */ -/obj/item/borg/upgrade/proc/action(mob/user, mob/living/silicon/robot/R) - if(!pre_install_checks(user, R)) - return - if(!user.drop_item()) - to_chat(user, "\The [src] is stuck to your hand, you cannot install it in [R]") - return FALSE - if(!do_install(R)) - return - after_install(R) - if(delete_after_install) - qdel(src) - else - forceMove(R) - return TRUE - -/** - * Checks if the upgrade is able to be applied to the cyborg, before actually applying it. - * - * Arguments: - * * R - the cyborg that was clicked on with an upgrade. - */ -/obj/item/borg/upgrade/proc/pre_install_checks(mob/user, mob/living/silicon/robot/R) - if(R.stat == DEAD) - to_chat(user, "[src] will not function on a deceased cyborg.") - return - if(module_type && !istype(R.module, module_type)) - to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!") - to_chat(user, "There's no mounting point for the module!") - return - var/obj/item/borg/upgrade/u = locate(type) in R - if(u && !allow_duplicate) - to_chat(user, "This unit already has [src] installed!") - return - return TRUE - -/** - * Executes code that will modify the cyborg or its module. - * - * Arguments: - * * R - the cyborg we're applying the upgrade to. - */ -/obj/item/borg/upgrade/proc/do_install(mob/living/silicon/robot/R) - return TRUE - -/** - * Executes code after the module has been installed and the cyborg has been modified in some way. - * - * Arguments: - * * R - the cyborg that we've applied the upgrade to. - */ -/obj/item/borg/upgrade/proc/after_install(mob/living/silicon/robot/R) - for(var/item in items_to_replace) - var/replacement_type = items_to_replace[item] - var/obj/item/replacement = new replacement_type(R.module) - R.module.remove_item_from_lists(item) - R.module.basic_modules += replacement - - if(replacement_type in special_rechargables) - R.module.special_rechargables += replacement - - for(var/item in items_to_add) - var/obj/item/replacement = new item(R.module) - R.module.basic_modules += replacement - - R.module?.rebuild_modules() - return TRUE - -/*******************/ -// MARK: COMMON -/*******************/ - -/obj/item/borg/upgrade/reset - name = "cyborg module reset board" - desc = "Used to reset a cyborg's module. Destroys any other upgrades applied to the cyborg." - icon_state = "cyborg_upgrade1" - require_module = TRUE - delete_after_install = TRUE - -/obj/item/borg/upgrade/reset/do_install(mob/living/silicon/robot/R) - R.reset_module() - return TRUE - -/obj/item/borg/upgrade/reset/after_install(mob/living/silicon/robot/R) - return // We don't need to give them replacement items, or rebuild their module list. It's going to be a blank borg. - -/obj/item/borg/upgrade/rename - name = "cyborg reclassification board" - desc = "Used to rename a cyborg." - icon_state = "cyborg_upgrade1" - delete_after_install = TRUE - var/heldname = "default name" - -/obj/item/borg/upgrade/rename/attack_self__legacy__attackchain(mob/user) - var/new_heldname = tgui_input_text(user, "Enter new robot name", "Cyborg Reclassification", heldname, MAX_NAME_LEN) - if(!new_heldname) - return - heldname = new_heldname - -/obj/item/borg/upgrade/rename/do_install(mob/living/silicon/robot/R) - if(!R.allow_rename) - to_chat(R, "Internal diagnostic error: incompatible upgrade module detected.") - return - R.notify_ai(3, R.name, heldname) - R.name = heldname - R.custom_name = heldname - R.real_name = heldname - if(R.mmi && R.mmi.brainmob) - R.mmi.brainmob.name = R.name - return TRUE - -/obj/item/borg/upgrade/restart - name = "cyborg emergency reboot module" - desc = "Used to force a reboot of a disabled-but-repaired cyborg, bringing it back online." - icon_state = "cyborg_upgrade1" - delete_after_install = TRUE - -/obj/item/borg/upgrade/restart/do_install(mob/living/silicon/robot/R) - if(R.health < 0) - to_chat(usr, "You have to repair the cyborg before using this module!") - return - - if(!R.key) - for(var/mob/dead/observer/ghost in GLOB.player_list) - if(ghost.mind && ghost.mind.current == R) - R.key = ghost.key - - R.set_stat(CONSCIOUS) - GLOB.dead_mob_list -= R //please never forget this ever kthx - GLOB.alive_mob_list += R - R.notify_ai(1) - - return TRUE - -/obj/item/borg/upgrade/thrusters - name = "ion thruster upgrade" - desc = "A energy-operated thruster system for cyborgs." - icon_state = "cyborg_upgrade3" - origin_tech = "engineering=4;powerstorage=4" - -/obj/item/borg/upgrade/thrusters/do_install(mob/living/silicon/robot/R) - R.ionpulse = TRUE - return TRUE - -/obj/item/borg/upgrade/selfrepair - name = "self-repair module" - desc = "This module will repair the cyborg over time." - icon_state = "cyborg_upgrade5" - require_module = TRUE - var/repair_amount = -1 - var/repair_tick = 1 - var/msg_cooldown = 0 - var/on = FALSE - var/powercost = 10 - var/mob/living/silicon/robot/cyborg - -/obj/item/borg/upgrade/selfrepair/do_install(mob/living/silicon/robot/R) - cyborg = R - icon_state = "selfrepair_off" - var/datum/action/A = new /datum/action/item_action/toggle(src) - A.Grant(R) - return TRUE - -/obj/item/borg/upgrade/selfrepair/Destroy() - cyborg = null - STOP_PROCESSING(SSobj, src) - on = FALSE - return ..() - -/obj/item/borg/upgrade/selfrepair/ui_action_click() - on = !on - if(on) - to_chat(cyborg, "You activate the self-repair module.") - START_PROCESSING(SSobj, src) - else - to_chat(cyborg, "You deactivate the self-repair module.") - STOP_PROCESSING(SSobj, src) - update_icon(UPDATE_ICON_STATE) - -/obj/item/borg/upgrade/selfrepair/update_icon_state() - if(cyborg) - icon_state = "selfrepair_[on ? "on" : "off"]" - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtons() - else - icon_state = "cyborg_upgrade5" - -/obj/item/borg/upgrade/selfrepair/proc/deactivate() - STOP_PROCESSING(SSobj, src) - on = FALSE - update_icon(UPDATE_ICON_STATE) - -/obj/item/borg/upgrade/selfrepair/process() - if(!repair_tick) - repair_tick = 1 - return - - if(cyborg && (cyborg.stat != DEAD) && on) - if(!cyborg.cell) - to_chat(cyborg, "Self-repair module deactivated. Please, insert the power cell.") - deactivate() - return - - if(cyborg.cell.charge < powercost * 2) - to_chat(cyborg, "Self-repair module deactivated. Please recharge.") - deactivate() - return - - if(cyborg.health < cyborg.maxHealth) - if(cyborg.health < 0) - repair_amount = 2.5 - powercost = 30 - else - repair_amount = 1 - powercost = 10 - cyborg.heal_overall_damage(repair_amount, repair_amount) - cyborg.cell.use(powercost) - else - cyborg.cell.use(5) - repair_tick = 0 - - if((world.time - 2000) > msg_cooldown) - var/msgmode = "standby" - if(cyborg.health < 0) - msgmode = "critical" - else if(cyborg.health < cyborg.maxHealth) - msgmode = "normal" - to_chat(cyborg, "Self-repair is active in [msgmode] mode.") - msg_cooldown = world.time - else - deactivate() - -/obj/item/borg/upgrade/vtec - name = "robotic VTEC Module" - desc = "Used to activate a cyborg's VTEC systems, allowing them to retain more speed when damaged. Alternatively speeds up slow vehicles." - icon_state = "cyborg_upgrade2" - require_module = TRUE - origin_tech = "engineering=4;materials=5;programming=4" - -/obj/item/borg/upgrade/vtec/do_install(mob/living/silicon/robot/R) - R.slowdown_cap = 3.5 - return TRUE - -/***********************/ -// MARK: Security -/***********************/ - -/obj/item/borg/upgrade/disablercooler - name = "cyborg rapid disabler cooling module" - desc = "Used to cool a mounted disabler, increasing the potential current in it and thus its recharge rate." - icon_state = "cyborg_upgrade3" - origin_tech = "engineering=4;powerstorage=4;combat=4" - require_module = TRUE - module_type = /obj/item/robot_module/security - -/obj/item/borg/upgrade/disablercooler/do_install(mob/living/silicon/robot/R) - var/obj/item/gun/energy/disabler/cyborg/T = locate() in R.module.modules - if(!T) - to_chat(usr, "There's no disabler in this unit!") - return - if(T.charge_delay <= 2) - to_chat(R, "A cooling unit is already installed!") - to_chat(usr, "There's no room for another cooling unit!") - return - - T.charge_delay = max(2 , T.charge_delay - 4) - - return TRUE - -/*******************/ -// MARK: Mining -/*******************/ - -/obj/item/borg/upgrade/ddrill - name = "mining cyborg diamond drill" - desc = "A diamond drill replacement for the mining cyborg's standard drill." - icon_state = "cyborg_upgrade3" - origin_tech = "engineering=4;materials=5" - require_module = TRUE - module_type = /obj/item/robot_module/miner - items_to_replace = list( - /obj/item/pickaxe/drill/cyborg = /obj/item/pickaxe/drill/cyborg/diamond - ) - -/obj/item/borg/upgrade/soh - name = "mining cyborg satchel of holding" - desc = "A satchel of holding replacement for mining cyborg's ore satchel module." - icon_state = "cyborg_upgrade3" - origin_tech = "engineering=4;materials=4;bluespace=4" - require_module = TRUE - module_type = /obj/item/robot_module/miner - items_to_replace = list( - /obj/item/storage/bag/ore/cyborg = /obj/item/storage/bag/ore/holding - ) - -/obj/item/borg/upgrade/lavaproof - name = "mining cyborg lavaproof chassis" - desc = "An upgrade kit to apply specialized coolant systems and insulation layers to a mining cyborg's chassis, enabling them to withstand exposure to molten rock." - icon_state = "ash_plating" - resistance_flags = LAVA_PROOF | FIRE_PROOF - require_module = TRUE - module_type = /obj/item/robot_module/miner - -/obj/item/borg/upgrade/lavaproof/do_install(mob/living/silicon/robot/R) - if(istype(R)) - R.weather_immunities += "lava" - return TRUE - -/***********************/ -// MARK: Engineer -/***********************/ - -/obj/item/borg/upgrade/rcd - name = "R.C.D. upgrade" - desc = "A modified Rapid Construction Device, able to pull energy directly from a cyborg's internal power cell." - icon_state = "cyborg_upgrade5" - origin_tech = "engineering=4;materials=5;powerstorage=4" - require_module = TRUE - module_type = /obj/item/robot_module/engineering - items_to_add = list(/obj/item/rcd/borg) - -/obj/item/borg/upgrade/rcd/after_install(mob/living/silicon/robot/R) - if(R.emagged) // Emagged engi-borgs have already have the RCD added. - return - R.module.remove_item_from_lists(/obj/item/rcd) // So emagging them in the future won't grant another RCD. - ..() - -/obj/item/borg/upgrade/rped - name = "Rapid Part Exchange Device upgrade" - desc = "A modified Rapid Part Exchange Device designed to be used by engineering robots." - icon_state = "cyborg_upgrade5" - require_module = TRUE - module_type = /obj/item/robot_module/engineering - items_to_add = list(/obj/item/storage/part_replacer) - -/***********************/ -// MARK: Janitor -/***********************/ - -/obj/item/borg/upgrade/floorbuffer - name = "janitorial floor buffer upgrade" - desc = "A floor buffer upgrade kit that can be attached to janitor cyborgs and mobile janicarts." - icon = 'icons/obj/vehicles.dmi' - icon_state = "upgrade" - origin_tech = "materials=3;engineering=4" - require_module = TRUE - module_type = /obj/item/robot_module/janitor - /// How much speed the cyborg loses while the buffer is active - var/buffer_speed = 1 - var/mob/living/silicon/robot/cyborg - -/obj/item/borg/upgrade/floorbuffer/do_install(mob/living/silicon/robot/R) - cyborg = R - var/datum/action/A = new /datum/action/item_action/floor_buffer(src) - A.Grant(R) - return TRUE - -/obj/item/borg/upgrade/floorbuffer/ui_action_click() - if(!cyborg.floorbuffer) - cyborg.floorbuffer = TRUE - cyborg.speed += buffer_speed - else - cyborg.floorbuffer = FALSE - cyborg.speed -= buffer_speed - to_chat(cyborg, "The floor buffer is now [cyborg.floorbuffer ? "active" : "deactivated"].") - -/obj/item/borg/upgrade/floorbuffer/Destroy() - if(cyborg) - cyborg.floorbuffer = FALSE - cyborg = null - return ..() - -/obj/item/borg/upgrade/bluespace_trash_bag - name = "janitor cyborg trash bag of holding upgrade" - desc = "An advanced trash bag upgrade board with bluespace properties that can be attached to janitorial cyborgs." - icon_state = "cyborg_upgrade4" - require_module = TRUE - module_type = /obj/item/robot_module/janitor - items_to_replace = list( - /obj/item/storage/bag/trash/cyborg = /obj/item/storage/bag/trash/bluespace/cyborg - ) - -/***********************/ -// MARK: Service -/***********************/ - -/obj/item/borg/upgrade/rsf_executive - name = "executive service upgrade" - desc = "An upgrade that replaces a service cyborg's Rapid Service Fabricator with a classy Executive version." - icon_state = "cyborg_upgrade5" - origin_tech = "bio=2;materials=1" - require_module = TRUE - module_type = /obj/item/robot_module/butler - items_to_add = list(/obj/item/kitchen/knife/cheese) - items_to_replace = list(/obj/item/rsf = /obj/item/rsf/executive) - -/***********************/ -// MARK: Syndicate -/***********************/ - -/obj/item/borg/upgrade/syndicate - name = "safety override module" - desc = "Unlocks the hidden, deadlier functions of a cyborg." - icon_state = "cyborg_upgrade3" - origin_tech = "combat=6;materials=6" - require_module = TRUE - -/obj/item/borg/upgrade/syndicate/do_install(mob/living/silicon/robot/R) - if(R.weapons_unlock) - return // They already had the safety override upgrade, or they're a cyborg type which has this by default. - R.weapons_unlock = TRUE - to_chat(R, "Warning: safety protocols have been disabled!") - return TRUE - -/obj/item/borg/upgrade/syndie_soap - name = "janitor cyborg syndicate soap" - desc = "Using forbidden technology and some red dye, upgrade a janitorial cyborg's soap performance by 90 percent!" - icon_state = "cyborg_upgrade4" - require_module = TRUE - module_type = /obj/item/robot_module/janitor - items_to_replace = list( - /obj/item/soap/nanotrasen = /obj/item/soap/syndie - ) - -/***********************/ -// MARK: Abductor -/***********************/ - -/obj/item/borg/upgrade/abductor_engi - name = "engineering cyborg abductor upgrade" - desc = "An experimental upgrade that replaces an engineering cyborg's tools with the abductor versions." - icon_state = "abductor_mod" - origin_tech = "engineering=6;materials=6;abductor=3" - require_module = TRUE - module_type = /obj/item/robot_module/engineering - items_to_replace = list( - /obj/item/weldingtool = /obj/item/weldingtool/abductor, - /obj/item/wrench = /obj/item/wrench/abductor, - /obj/item/screwdriver = /obj/item/screwdriver/abductor, - /obj/item/crowbar = /obj/item/crowbar/abductor, - /obj/item/wirecutters = /obj/item/wirecutters/abductor, - /obj/item/multitool = /obj/item/multitool/abductor - ) - special_rechargables = list( - /obj/item/weldingtool/abductor - ) - -/obj/item/borg/upgrade/abductor_medi - name = "medical cyborg abductor upgrade" - desc = "An experimental upgrade that replaces a medical cyborg's tools with the abductor versions." - icon_state = "abductor_mod" - origin_tech = "biotech=6;materials=6;abductor=2" - require_module = TRUE - module_type = /obj/item/robot_module/medical - items_to_replace = list( - /obj/item/scalpel/laser/laser1 = /obj/item/scalpel/laser/laser3, // No abductor laser scalpel, so next best thing. - /obj/item/hemostat = /obj/item/hemostat/alien, - /obj/item/retractor = /obj/item/retractor/alien, - /obj/item/bonegel = /obj/item/bonegel/alien, - /obj/item/fix_o_vein = /obj/item/fix_o_vein/alien, - /obj/item/bonesetter = /obj/item/bonesetter/alien, - /obj/item/circular_saw = /obj/item/circular_saw/alien, - /obj/item/surgicaldrill = /obj/item/surgicaldrill/alien, - /obj/item/reagent_containers/borghypo = /obj/item/reagent_containers/borghypo/abductor - ) - -/obj/item/borg/upgrade/abductor_medi/after_install(mob/living/silicon/robot/R) - . = ..() - if(!R.emagged) // Emagged Mediborgs that are upgraded need the evil chems. - return - for(var/obj/item/reagent_containers/borghypo/F in R.module.modules) - F.emag_act() - -/obj/item/borg/upgrade/abductor_jani - name = "janitorial cyborg abductor upgrade" - desc = "An experimental upgrade that replaces a janitorial cyborg's tools with the abductor versions." - icon_state = "abductor_mod" - origin_tech = "biotech=6;materials=6;abductor=2" - require_module = TRUE - module_type = /obj/item/robot_module/janitor - items_to_replace = list( - /obj/item/mop/advanced/cyborg = /obj/item/mop/advanced/abductor, - /obj/item/soap = /obj/item/soap/syndie/abductor, - /obj/item/lightreplacer/cyborg = /obj/item/lightreplacer/bluespace/abductor, - /obj/item/melee/flyswatter = /obj/item/melee/flyswatter/abductor - ) - items_to_add = list( - /obj/item/reagent_containers/spray/cleaner/safety/abductor - ) - special_rechargables = list( - /obj/item/reagent_containers/spray/cleaner/safety/abductor, - /obj/item/lightreplacer/bluespace/abductor - ) diff --git a/code/game/objects/items/scratch_card.dm b/code/game/objects/items/scratch_card.dm deleted file mode 100644 index f498a080acae9..0000000000000 --- a/code/game/objects/items/scratch_card.dm +++ /dev/null @@ -1,50 +0,0 @@ -/obj/item/scratch - name = "scratch card" - desc = "Scratch this with a card or coin to discover if you are the winner!" - icon = 'icons/obj/economy.dmi' - icon_state = "scard" - w_class = WEIGHT_CLASS_TINY - /// Has this been scratched yet? - var/scratched = FALSE - /// The prob chance for it to be the winner card - var/winning_chance = 1 - /// Is this the winner card? - var/winner = FALSE - -/obj/item/scratch/attackby__legacy__attackchain(obj/item/I, mob/user, params) - . = ..() - if(scratched) - return - if(!(istype(I, /obj/item/card) || istype(I, /obj/item/coin))) // We scratch with cards or coins! - return - - if(prob(winning_chance)) - to_chat(user, "Congratulations! Redeem your prize at the nearest ATM!") - icon_state = "scard_winner" - winner = TRUE - else - to_chat(user, "Good luck next time.") - icon_state = "scard_loser" - playsound(user, 'sound/items/scratching.ogg', 25, TRUE) - scratched = TRUE - update_icon(UPDATE_ICON_STATE) - -/obj/item/scratch/attack_obj__legacy__attackchain(obj/O, mob/living/user, params) - if(winner && istype(O, /obj/machinery/economy/atm)) - playsound(user, 'sound/machines/ping.ogg', 50, TRUE) - O.atom_say("Congratulations for winning the lottery!") - var/obj/item/reward = new /obj/item/stack/spacecash/c1000 - qdel(src) - user.put_in_hands(reward) - return - ..() - -/obj/item/storage/box/scratch_cards - name = "scratch cards box" - desc = "Try your luck with five scratch cards!" - w_class = WEIGHT_CLASS_SMALL - can_hold = list(/obj/item/scratch) - -/obj/item/storage/box/scratch_cards/populate_contents() - for(var/i in 1 to 5) - new /obj/item/scratch(src) diff --git a/code/game/objects/items/sport.dm b/code/game/objects/items/sport.dm deleted file mode 100644 index 3e9e08b3f769e..0000000000000 --- a/code/game/objects/items/sport.dm +++ /dev/null @@ -1,98 +0,0 @@ -/obj/item/beach_ball - name = "beach ball" - icon = 'icons/misc/beach.dmi' - desc = "An inflatable ball of fun, enjoyed on many beaches." - icon_state = "ball" - item_state = "beachball" - density = FALSE - anchored = FALSE - w_class = WEIGHT_CLASS_NORMAL - force = 0 - throwforce = 0 - throw_speed = 1 - throw_range = 20 - flags = CONDUCT - /// Whether `attack_self` will move ("dribble") it to the other hand - var/dribbleable = FALSE // Most balls do not have a dribble animation - -/obj/item/beach_ball/attack_self__legacy__attackchain(mob/user) - if(!dribbleable) - return - - if(!user.get_inactive_hand()) // We ballin - user.unequip(src) - user.put_in_inactive_hand(src) - else - to_chat(user, "You can't dribble to an occupied hand!") - -/obj/item/beach_ball/baseball - name = "baseball" - desc = "Take me out to the ball game." - icon = 'icons/obj/basketball.dmi' - icon_state = "baseball" - item_state = "baseball" - w_class = WEIGHT_CLASS_SMALL - -/obj/item/beach_ball/dodgeball - name = "dodgeball" - desc = "Used for playing the most violent and degrading of childhood games. This one is connected to the laser tag armour system." - icon = 'icons/obj/basketball.dmi' - icon_state = "dodgeball" - item_state = "dodgeball" - dribbleable = TRUE - var/list/suit_types = list(/obj/item/clothing/suit/redtag, /obj/item/clothing/suit/bluetag) - -/obj/item/beach_ball/dodgeball/throw_impact(atom/hit_atom) - . = ..() - var/mob/living/carbon/human/M = hit_atom - if(ishuman(hit_atom) && (M.wear_suit?.type in suit_types)) - if(M.is_holding(src)) - return - playsound(src, 'sound/items/dodgeball.ogg', 50, 1) - M.KnockDown(6 SECONDS) - -/obj/item/beach_ball/holoball - name = "basketball" - desc = "Here's your chance, do your dance at the Space Jam." - icon = 'icons/obj/basketball.dmi' - icon_state = "basketball" - item_state = "basketball" - dribbleable = TRUE - w_class = WEIGHT_CLASS_BULKY //Stops people from hiding it in their bags/pockets - -/obj/structure/holohoop - name = "basketball hoop" - desc = "Boom, Shakalaka!" - icon = 'icons/obj/basketball.dmi' - icon_state = "hoop" - anchored = TRUE - density = TRUE - pass_flags_self = LETPASSTHROW | PASSTAKE - -/obj/structure/holohoop/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(istype(W, /obj/item/grab) && get_dist(src, user) <= 1) - var/obj/item/grab/G = W - if(G.state < GRAB_AGGRESSIVE) - to_chat(user, "You need a better grip to do that!") - return - G.affecting.forceMove(loc) - G.affecting.Weaken(10 SECONDS) - visible_message("[G.assailant] dunks [G.affecting] into [src]!") - qdel(W) - return - else if(isitem(W) && get_dist(src,user) <= 1) - user.drop_item(src) - visible_message("[user] dunks [W] into [src]!") - return - -/obj/structure/holohoop/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) - if(isitem(AM) && !isprojectile(AM)) - var/atom/movable/thrower = throwingdatum?.get_thrower() - if(prob(50) || HAS_TRAIT(thrower, TRAIT_BADASS)) - AM.forceMove(get_turf(src)) - visible_message("Swish! [AM] lands in [src].") - else - visible_message("[AM] bounces off of [src]'s rim!") - return ..() - else - return ..() diff --git a/code/game/objects/items/stacks/medical_packs.dm b/code/game/objects/items/stacks/medical_packs.dm deleted file mode 100644 index c6f92f52d3a06..0000000000000 --- a/code/game/objects/items/stacks/medical_packs.dm +++ /dev/null @@ -1,365 +0,0 @@ -/obj/item/stack/medical - name = "medical pack" - singular_name = "medical pack" - icon = 'icons/obj/medical.dmi' - amount = 6 - max_amount = 6 - w_class = WEIGHT_CLASS_TINY - throw_speed = 3 - throw_range = 7 - resistance_flags = FLAMMABLE - max_integrity = 40 - parent_stack = TRUE - var/heal_brute = 0 - var/heal_burn = 0 - var/self_delay = 20 - var/unique_handling = FALSE //some things give a special prompt, do we want to bypass some checks in parent? - var/stop_bleeding = 0 - var/healverb = "bandage" - -/obj/item/stack/medical/proc/apply(mob/living/M, mob/user) - if(get_amount() <= 0) - if(is_cyborg) - to_chat(user, "You don't have enough energy to dispense more [singular_name]\s!") - return TRUE - - if(!iscarbon(M) && !isanimal(M)) - to_chat(user, "[src] cannot be applied to [M]!") - return TRUE - - if(!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") - return TRUE - - - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected) - - if(!H.can_inject(user, TRUE)) - return TRUE - - if(!affecting) - to_chat(user, "That limb is missing!") - return TRUE - - if(affecting.is_robotic()) - to_chat(user, "This can't be used on a robotic limb.") - return TRUE - - if(M == user && !unique_handling) - user.visible_message("[user] starts to apply [src] on [H]...") - if(!do_mob(user, H, self_delay)) - return TRUE - return - - if(isanimal(M)) - var/mob/living/simple_animal/critter = M - if(!(critter.healable)) - to_chat(user, "You cannot use [src] on [critter]!") - return - else if(critter.health == critter.maxHealth) - to_chat(user, "[critter] is at full health.") - return - else if(heal_brute < 1) - to_chat(user, "[src] won't help [critter] at all.") - return - - critter.heal_organ_damage(heal_brute, heal_burn) - user.visible_message("[user] applies [src] on [critter].", \ - "You apply [src] on [critter].") - - use(1) - - else - M.heal_organ_damage(heal_brute, heal_burn) - user.visible_message("[user] applies [src] on [M].", \ - "You apply [src] on [M].") - use(1) - -/obj/item/stack/medical/attack__legacy__attackchain(mob/living/M, mob/user) - return apply(M, user) - -/obj/item/stack/medical/attack_self__legacy__attackchain(mob/user) - return apply(user, user) - -/obj/item/stack/medical/proc/heal(mob/living/M, mob/user) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected) - user.visible_message("[user] [healverb]s the wounds on [H]'s [affecting.name].", \ - "You [healverb] the wounds on [H]'s [affecting.name]." ) - - var/rembrute = max(0, heal_brute - affecting.brute_dam) // Maxed with 0 since heal_damage let you pass in a negative value - var/remburn = max(0, heal_burn - affecting.burn_dam) // And deduct it from their health (aka deal damage) - var/nrembrute = rembrute - var/nremburn = remburn - affecting.heal_damage(heal_brute, heal_burn) - var/list/achildlist - if(!isnull(affecting.children)) - achildlist = affecting.children.Copy() - var/parenthealed = FALSE - while(rembrute + remburn > 0) // Don't bother if there's not enough leftover heal - var/obj/item/organ/external/E - if(LAZYLEN(achildlist)) - E = pick_n_take(achildlist) // Pick a random children and then remove it from the list - else if(affecting.parent && !parenthealed) // If there's a parent and no healing attempt was made on it - E = affecting.parent - parenthealed = TRUE - else - break // If the organ have no child left and no parent / parent healed, break - if(E.status & ORGAN_ROBOT || E.open) // Ignore robotic or open limb - continue - else if(!E.brute_dam && !E.burn_dam) // Ignore undamaged limb - continue - nrembrute = max(0, rembrute - E.brute_dam) // Deduct the healed damage from the remain - nremburn = max(0, remburn - E.burn_dam) - E.heal_damage(rembrute, remburn) - rembrute = nrembrute - remburn = nremburn - user.visible_message("[user] [healverb]s the wounds on [H]'s [E.name] with the remaining medication.", \ - "You [healverb] the wounds on [H]'s [E.name] with the remaining medication." ) - return affecting - -//Bruise Packs// - -/obj/item/stack/medical/bruise_pack - name = "roll of gauze" - singular_name = "gauze length" - desc = "Some sterile gauze to wrap around bloody stumps." - icon = 'icons/obj/stacks/miscellaneous.dmi' - icon_state = "gauze" - origin_tech = "biotech=2" - merge_type = /obj/item/stack/medical/bruise_pack - max_amount = 12 - heal_brute = 10 - stop_bleeding = 1800 - dynamic_icon_state = TRUE - -/obj/item/stack/medical/bruise_pack/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(I.sharp) - if(get_amount() < 2) - to_chat(user, "You need at least two gauzes to do this!") - return - new /obj/item/stack/sheet/cloth(user.drop_location()) - user.visible_message("[user] cuts [src] into pieces of cloth with [I].", \ - "You cut [src] into pieces of cloth with [I].", \ - "You hear cutting.") - use(2) - else - return ..() - -/obj/item/stack/medical/bruise_pack/apply(mob/living/M, mob/user) - if(..()) - return TRUE - - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected) - for(var/obj/item/organ/external/E in H.bodyparts) - if(E.open >= ORGAN_ORGANIC_OPEN) - to_chat(user, "[E] is cut open, you'll need more than a bandage!") - return - affecting.germ_level = 0 - - if(stop_bleeding) - if(!H.bleedsuppress) //so you can't stack bleed suppression - H.suppress_bloodloss(stop_bleeding) - - heal(H, user) - - H.UpdateDamageIcon() - use(1) - -/obj/item/stack/medical/bruise_pack/improvised - name = "improvised gauze" - singular_name = "improvised gauze" - desc = "A roll of cloth roughly cut from something that can stop bleeding, but does not heal wounds." - merge_type = /obj/item/stack/medical/bruise_pack/improvised - heal_brute = 0 - stop_bleeding = 900 - -/obj/item/stack/medical/bruise_pack/advanced - name = "advanced trauma kit" - icon = 'icons/obj/medical.dmi' - singular_name = "advanced trauma kit" - desc = "An advanced trauma kit for severe injuries." - icon_state = "traumakit" - belt_icon = "traumakit" - merge_type = /obj/item/stack/medical/bruise_pack/advanced - max_amount = 6 - heal_brute = 25 - stop_bleeding = 0 - dynamic_icon_state = FALSE - -/obj/item/stack/medical/bruise_pack/advanced/cyborg - energy_type = /datum/robot_storage/energy/medical/adv_brute_kit - is_cyborg = TRUE - -/obj/item/stack/medical/bruise_pack/advanced/cyborg/syndicate - energy_type = /datum/robot_storage/energy/medical/adv_brute_kit/syndicate - -//Ointment// - - -/obj/item/stack/medical/ointment - name = "ointment" - desc = "Used to treat those nasty burns." - gender = PLURAL - icon = 'icons/obj/stacks/miscellaneous.dmi' - singular_name = "ointment" - icon_state = "ointment" - origin_tech = "biotech=2" - healverb = "salve" - heal_burn = 10 - dynamic_icon_state = TRUE - merge_type = /obj/item/stack/medical/ointment - -/obj/item/stack/medical/ointment/apply(mob/living/M, mob/user) - if(..()) - return 1 - - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected) - - if(affecting.open == ORGAN_CLOSED) - affecting.germ_level = 0 - - heal(H, user) - - H.UpdateDamageIcon() - use(1) - else - to_chat(user, "[affecting] is cut open, you'll need more than some ointment!") - -/obj/item/stack/medical/ointment/heal(mob/living/M, mob/user) - var/obj/item/organ/external/affecting = ..() - if((affecting.status & ORGAN_BURNT) && !(affecting.status & ORGAN_SALVED)) - to_chat(affecting.owner, "As [src] is applied to your burn wound, you feel a soothing cold and relax.") - affecting.status |= ORGAN_SALVED - addtimer(CALLBACK(affecting, TYPE_PROC_REF(/obj/item/organ/external, remove_ointment), heal_burn), 3 MINUTES) - -/obj/item/organ/external/proc/remove_ointment(heal_amount) //de-ointmenterized D: - status &= ~ORGAN_SALVED - perma_injury = max(perma_injury - heal_amount, 0) - if(owner) - owner.updatehealth("permanent injury removal") - if(!perma_injury) - fix_burn_wound(update_health = FALSE) - to_chat(owner, "You feel your [src.name]'s burn wound has fully healed, and the rest of the salve absorbs into it.") - else - to_chat(owner, "You feel your [src.name]'s burn wound has healed a little, but the applied salve has already vanished.") - -/obj/item/stack/medical/ointment/advanced - name = "advanced burn kit" - singular_name = "advanced burn kit" - desc = "An advanced treatment kit for severe burns." - icon = 'icons/obj/medical.dmi' - icon_state = "burnkit" - belt_icon = "burnkit" - heal_burn = 25 - dynamic_icon_state = FALSE - merge_type = /obj/item/stack/medical/ointment/advanced - -/obj/item/stack/medical/ointment/advanced/cyborg - energy_type = /datum/robot_storage/energy/medical/adv_burn_kit - is_cyborg = TRUE - -/obj/item/stack/medical/ointment/advanced/cyborg/syndicate - energy_type = /datum/robot_storage/energy/medical/adv_burn_kit/syndicate - -//Medical Herbs// -/obj/item/stack/medical/bruise_pack/comfrey - name = "\improper Comfrey poultice" - singular_name = "Comfrey poultice" - desc = "A medical poultice for treating brute injuries, made from crushed comfrey leaves. The effectiveness of the poultice depends on the potency of the comfrey it was made from." - icon = 'icons/obj/medical.dmi' - icon_state = "traumapoultice" - max_amount = 6 - stop_bleeding = 0 - heal_brute = 12 - drop_sound = 'sound/misc/moist_impact.ogg' - mob_throw_hit_sound = 'sound/misc/moist_impact.ogg' - hitsound = 'sound/misc/moist_impact.ogg' - dynamic_icon_state = FALSE - -/obj/item/stack/medical/bruise_pack/comfrey/heal(mob/living/M, mob/user) - playsound(src, 'sound/misc/soggy.ogg', 30, TRUE) - return ..() - -/obj/item/stack/medical/ointment/aloe - name = "\improper Aloe Vera poultice" - singular_name = "Aloe Vera poultice" - desc = "A medical poultice for treating burns, made from crushed aloe vera leaves. The effectiveness of the poultice depends on the potency of the aloe it was made from." - icon = 'icons/obj/medical.dmi' - icon_state = "burnpoultice" - heal_burn = 12 - drop_sound = 'sound/misc/moist_impact.ogg' - mob_throw_hit_sound = 'sound/misc/moist_impact.ogg' - hitsound = 'sound/misc/moist_impact.ogg' - dynamic_icon_state = FALSE - -/obj/item/stack/medical/ointment/aloe/heal(mob/living/M, mob/user) - playsound(src, 'sound/misc/soggy.ogg', 30, TRUE) - return ..() - -// Splints -/obj/item/stack/medical/splint - name = "medical splints" - singular_name = "medical splint" - icon_state = "splint" - unique_handling = TRUE - self_delay = 100 - merge_type = /obj/item/stack/medical/splint - var/other_delay = 0 - -/obj/item/stack/medical/splint/apply(mob/living/M, mob/user) - if(..()) - return TRUE - - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected) - var/limb = affecting.name - - if(!(affecting.limb_name in list("l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot"))) - to_chat(user, "You can't apply a splint there!") - return TRUE - - if(affecting.status & ORGAN_SPLINTED) - to_chat(user, "[H]'s [limb] is already splinted!") - if(tgui_alert(user, "Would you like to remove the splint from [H]'s [limb]?", "Splint removal", list("Yes", "No")) == "Yes") - affecting.status &= ~ORGAN_SPLINTED - H.handle_splints() - to_chat(user, "You remove the splint from [H]'s [limb].") - return TRUE - - if((M == user && self_delay > 0) || (M != user && other_delay > 0)) - user.visible_message("[user] starts to apply [src] to [H]'s [limb].", \ - "You start to apply [src] to [H]'s [limb].", \ - "You hear something being wrapped.") - - if(M == user && !do_mob(user, H, self_delay)) - return TRUE - else if(!do_mob(user, H, other_delay)) - return TRUE - - user.visible_message("[user] applies [src] to [H]'s [limb].", \ - "You apply [src] to [H]'s [limb].") - - affecting.status |= ORGAN_SPLINTED - affecting.splinted_count = H.step_count - H.handle_splints() - use(1) - -/obj/item/stack/medical/splint/cyborg - energy_type = /datum/robot_storage/energy/medical/splint - is_cyborg = TRUE - -/obj/item/stack/medical/splint/cyborg/syndicate - energy_type = /datum/robot_storage/energy/medical/splint/syndicate - -/obj/item/stack/medical/splint/tribal - name = "tribal splints" - icon_state = "tribal_splint" - other_delay = 50 diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm deleted file mode 100644 index 4c244f375d4b2..0000000000000 --- a/code/game/objects/items/stacks/nanopaste.dm +++ /dev/null @@ -1,103 +0,0 @@ -/obj/item/stack/nanopaste - name = "nanopaste" - singular_name = "nanite swarm" - desc = "A tube of paste containing swarms of repair nanites. Very effective in repairing robotic machinery." - icon = 'icons/obj/surgery.dmi' - icon_state = "tube" - w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=2;engineering=3" - amount = 6 - max_amount = 6 - toolspeed = 1 - merge_type = /obj/item/stack/nanopaste - -/obj/item/stack/nanopaste/attack__legacy__attackchain(mob/living/M as mob, mob/user as mob) - if(!istype(M) || !istype(user)) - return 0 - if(isrobot(M)) //Repairing cyborgs - var/mob/living/silicon/robot/R = M - if(R.getBruteLoss() || R.getFireLoss()) - R.heal_overall_damage(15, 15) - use(1) - user.visible_message("[user] applies some [src] at [R]'s damaged areas.",\ - "You apply some [src] at [R]'s damaged areas.") - else - to_chat(user, "All [R]'s systems are nominal.") - - if(ishuman(M)) //Repairing robotic limbs and IPCs - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/external_limb = H.get_organ(user.zone_selected) - - if(external_limb && external_limb.is_robotic()) - robotic_limb_repair(user, external_limb, H) - else - to_chat(user, "[src] won't work on that.") - -/obj/item/stack/nanopaste/afterattack__legacy__attackchain(atom/A, mob/user, proximity_flag) - if(!ismecha(A) || user.a_intent == INTENT_HARM || !proximity_flag) - return - var/obj/mecha/mecha = A - if((mecha.obj_integrity >= mecha.max_integrity) && !mecha.internal_damage) - to_chat(user, "[mecha] is at full integrity!") - return - if(mecha.state == MECHA_MAINT_OFF) - to_chat(user, "[mecha] cannot be repaired without maintenance protocols active!") - return - if(mecha.repairing) - to_chat(user, "[mecha] is currently being repaired!") - return - if(mecha.internal_damage & MECHA_INT_TANK_BREACH) - mecha.clearInternalDamage(MECHA_INT_TANK_BREACH) - user.visible_message("[user] repairs the damaged air tank.", "You repair the damaged air tank.") - else if(mecha.obj_integrity < mecha.max_integrity) - mecha.obj_integrity += min(20, mecha.max_integrity - mecha.obj_integrity) - use(1) - user.visible_message("[user] applies some [src] to [mecha]'s damaged areas.",\ - "You apply some [src] to [mecha]'s damaged areas.") - -/obj/item/stack/nanopaste/proc/robotic_limb_repair(mob/user, obj/item/organ/external/external_limb, mob/living/carbon/human/H) - if(!external_limb.get_damage()) - to_chat(user, "Nothing to fix here.") - return - use(1) - var/remaining_heal = 15 - var/new_remaining_heal = 0 - external_limb.heal_damage(robo_repair = TRUE) //should in, theory, heal the robotic organs in just the targeted area with it being external_limb instead of other_external_limb - var/list/childlist - if(!isnull(external_limb.children)) - childlist = external_limb.children.Copy() - var/parenthealed = FALSE - while(remaining_heal > 0) - var/obj/item/organ/external/other_external_limb - if(external_limb.get_damage()) - other_external_limb = external_limb - else if(LAZYLEN(childlist)) - other_external_limb = pick_n_take(childlist) - if(!other_external_limb.get_damage() || !other_external_limb.is_robotic()) - continue - else if(external_limb.parent && !parenthealed) - other_external_limb = external_limb.parent - parenthealed = TRUE - if(!other_external_limb.get_damage() || !other_external_limb.is_robotic()) - break - else - break - new_remaining_heal = max(remaining_heal - other_external_limb.get_damage(), 0) - other_external_limb.heal_damage(remaining_heal, remaining_heal, FALSE, TRUE) - remaining_heal = new_remaining_heal - user.visible_message("[user] applies some nanite paste at [H]'s [other_external_limb.name] with [src].") - if(H.bleed_rate && ismachineperson(H)) - H.bleed_rate = 0 - -/obj/item/stack/nanopaste/cyborg - energy_type = /datum/robot_storage/energy/medical/nanopaste - is_cyborg = TRUE - -/obj/item/stack/nanopaste/cyborg/attack__legacy__attackchain(mob/living/M, mob/user) - if(get_amount() <= 0) - to_chat(user, "You don't have enough energy to dispense more [name]!") - else - return ..() - -/obj/item/stack/nanopaste/cyborg/syndicate - energy_type = /datum/robot_storage/energy/medical/nanopaste/syndicate diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm deleted file mode 100644 index 11b9dfc1af23e..0000000000000 --- a/code/game/objects/items/stacks/rods.dm +++ /dev/null @@ -1,110 +0,0 @@ -GLOBAL_LIST_INIT(rod_recipes, list ( - new /datum/stack_recipe("grille", /obj/structure/grille, 2, time = 1 SECONDS, one_per_turf = TRUE, on_floor_or_lattice = TRUE), - new /datum/stack_recipe("table frame", /obj/structure/table_frame, 2, time = 1 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("catwalk tile", /obj/item/stack/tile/catwalk, 2, 4, 20), - null, - new /datum/stack_recipe_list("railings...", list( - new /datum/stack_recipe("railing", /obj/structure/railing, 3, time = 1 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("railing corner", /obj/structure/railing/corner, 3, time = 1 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("railing cap (left)", /obj/structure/railing/cap/normal, 3, time = 1 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("railing cap (right)", /obj/structure/railing/cap/reversed, 3, time = 1 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - )), - new /datum/stack_recipe_list("chainlink fence...", list( - new /datum/stack_recipe("chainlink fence", /obj/structure/fence, 5, time = 1 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("chainlink fence post", /obj/structure/fence/post, 5, time = 1 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("chainlink fence corner", /obj/structure/fence/corner, 5, time = 1 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("chainlink fence door", /obj/structure/fence/door, 10, time = 1 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("chainlink fence end", /obj/structure/fence/end, 3, time = 1 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - )), - )) - -/obj/item/stack/rods - name = "metal rod" - desc = "Some rods. Can be used for building, or something." - singular_name = "metal rod" - icon = 'icons/obj/stacks/minerals.dmi' - icon_state = "rods-5" - item_state = "rods" - flags = CONDUCT - w_class = WEIGHT_CLASS_NORMAL - force = 9.0 - throwforce = 10.0 - throw_speed = 3 - throw_range = 7 - materials = list(MAT_METAL=1000) - max_amount = 50 - attack_verb = list("hit", "bludgeoned", "whacked") - hitsound = 'sound/weapons/grenadelaunch.ogg' - toolspeed = 1 - usesound = 'sound/items/deconstruct.ogg' - merge_type = /obj/item/stack/rods - -/obj/item/stack/rods/examine(mob/user) - . = ..() - . += "Using rods on a floor plating will install a reinforced floor. You can make reinforced glass by combining rods and normal glass sheets." - -/obj/item/stack/rods/cyborg - energy_type = /datum/robot_storage/energy/rods - is_cyborg = TRUE - materials = list() - -/obj/item/stack/rods/cyborg/update_icon_state() - return // icon_state should always be a full stack of rods. - -/obj/item/stack/rods/ten - amount = 10 - -/obj/item/stack/rods/twentyfive - amount = 25 - -/obj/item/stack/rods/fifty - amount = 50 - -/obj/item/stack/rods/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.rod_recipes - -/obj/item/stack/rods/update_icon_state() - var/amount = get_amount() - icon_state = "rods-[clamp(amount, 1, 5)]" - -/obj/item/stack/rods/welder_act(mob/user, obj/item/I) - if(get_amount() < 2) - to_chat(user, "You need at least two rods to do this!") - return - - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - - var/obj/item/stack/sheet/metal/new_item = new(drop_location()) - if(new_item.get_amount() <= 0) - // stack was moved into another one on the pile - new_item = locate() in user.loc - visible_message("[user.name] shapes [src] into metal with [I]!", \ - "You shape [src] into metal with [I]!", \ - "You hear welding.") - var/replace = user.is_in_inactive_hand(src) - use(2) - if(get_amount() <= 0 && replace) - user.drop_item_to_ground(src, force = TRUE) - if(new_item) - user.put_in_hands(new_item) - -/obj/item/stack/rods/lava - name = "heat resistant rod" - desc = "Treated, specialized iron rods. When exposed to the vacuum of space their coating breaks off, but they can hold up against the extreme heat of molten liquids." - singular_name = "heat resistant rod" - color = "#5286b9ff" - flags = CONDUCT - w_class = WEIGHT_CLASS_NORMAL - materials = list(MAT_METAL = 1000, MAT_TITANIUM = 1000, MAT_PLASMA = 1000) - max_amount = 50 - resistance_flags = FIRE_PROOF | LAVA_PROOF - merge_type = /obj/item/stack/rods/lava - -/obj/item/stack/rods/lava/ten - amount = 10 - -/obj/item/stack/rods/lava/fifty - amount = 50 diff --git a/code/game/objects/items/stacks/seaweed.dm b/code/game/objects/items/stacks/seaweed.dm deleted file mode 100644 index 6d277dfb23f86..0000000000000 --- a/code/game/objects/items/stacks/seaweed.dm +++ /dev/null @@ -1,19 +0,0 @@ -/obj/item/stack/seaweed - name = "seaweed sheet" - desc = "Weed.. from the Sea!" - singular_name = "seaweed sheet" - icon = 'icons/obj/stacks/organic.dmi' - icon_state = "seaweed" - item_state = "seaweed" - w_class = WEIGHT_CLASS_TINY - attack_verb = list("slapped") - hitsound = 'sound/weapons/grenadelaunch.ogg' - usesound = 'sound/items/deconstruct.ogg' - merge_type = /obj/item/stack/seaweed - -/obj/item/stack/seaweed/attack_self__legacy__attackchain(mob/user) - return - -/obj/item/stack/seaweed/attack_self_tk() - return - diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm deleted file mode 100644 index 52ff0308ffa77..0000000000000 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ /dev/null @@ -1,314 +0,0 @@ -/* CONTENTS: - * 1. GLASS - * 2. REINFORCED GLASS - * 3. PLASMA GLASS - * 4. REINFORCED PLASMA GLASS - * 5. TITANIUM GLASS - * 6. PLASTITANIUM GLASS - - Todo: Create a unified construct_window(sheet, user, created_window, full_window) - - */ - -////////////////////////////// -// MARK: GLASS -////////////////////////////// -GLOBAL_LIST_INIT(glass_recipes, list ( - new /datum/stack_recipe("glass shard", /obj/item/shard, time = 0 SECONDS), - new /datum/stack_recipe/window("directional window", /obj/structure/window/basic, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE), - new /datum/stack_recipe/window("fulltile window", /obj/structure/window/full/basic, 2, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE), - new /datum/stack_recipe("fishbowl", /obj/machinery/fishtank/bowl, 1, time = 1 SECONDS), - new /datum/stack_recipe("fish tank", /obj/machinery/fishtank/tank, 3, time = 2 SECONDS, on_floor = TRUE), - new /datum/stack_recipe("wall aquarium", /obj/machinery/fishtank/wall, 4, time = 4 SECONDS, on_floor = TRUE), - new /datum/stack_recipe("glass ashtray", /obj/item/ashtray/glass, 1, time = 1 SECONDS), - new /datum/stack_recipe("dropper", /obj/item/reagent_containers/dropper, 1, time = 1 SECONDS), -)) - -/obj/item/stack/sheet/glass - name = "glass" - desc = "HOLY SHEET! That is a lot of glass." - singular_name = "glass sheet" - icon_state = "sheet-glass" - item_state = "sheet-glass" - materials = list(MAT_GLASS = MINERAL_MATERIAL_AMOUNT) - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 100) - resistance_flags = ACID_PROOF - origin_tech = "materials=1" - created_window = /obj/structure/window/basic - full_window = /obj/structure/window/full/basic - merge_type = /obj/item/stack/sheet/glass - point_value = 1 - table_type = /obj/structure/table/glass - -/obj/item/stack/sheet/glass/examine(mob/user) - . = ..() - . += "Using rods on a floor plating will install glass floor. You can make reinforced glass by combining rods and normal glass sheets." - -/obj/item/stack/sheet/glass/fifty - amount = 50 - -/obj/item/stack/sheet/glass/cyborg - energy_type = /datum/robot_storage/material/glass - is_cyborg = TRUE - materials = list() - -/obj/item/stack/sheet/glass/cyborg/examine(mob/user) - . = ..() - var/mob/living/silicon/robot/robot = user - if(!istype(robot.module, /obj/item/robot_module/drone)) - . += "You can refill your glass by using your magnetic gripper on the Ore Redemption machine, or by picking it up from the ground." - -/obj/item/stack/sheet/glass/cyborg/drone - energy_type = /datum/robot_storage/energy/glass - -/obj/item/stack/sheet/glass/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.glass_recipes - -/obj/item/stack/sheet/glass/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/CC = W - if(CC.get_amount() < 5) - to_chat(user, "There is not enough wire in this coil. You need 5 lengths.") - return - CC.use(5) - to_chat(user, "You attach wire to [src].") - new /obj/item/stack/light_w(user.loc) - use(1) - return - - if(istype(W, /obj/item/stack/rods)) - var/obj/item/stack/rods/V = W - var/obj/item/stack/sheet/rglass/RG = new (user.loc) - RG.add_fingerprint(user) - V.use(1) - var/obj/item/stack/sheet/glass/G = src - src = null - var/replace = (user.get_inactive_hand()==G) - G.use(1) - if(!G && !RG && replace) - user.put_in_hands(RG) - return - - return ..() - -////////////////////////////// -// MARK: REINFORCED GLASS -////////////////////////////// -GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( - new /datum/stack_recipe("glass shard", /obj/item/shard, time = 0 SECONDS), - new /datum/stack_recipe/window("windoor frame", /obj/structure/windoor_assembly, 5, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE), - null, - new /datum/stack_recipe/window("directional reinforced window", /obj/structure/window/reinforced, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE), - new /datum/stack_recipe/window("fulltile reinforced window", /obj/structure/window/full/reinforced, 2, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE), - null, - new /datum/stack_recipe/window("directional electrochromic window", /obj/structure/window/reinforced/polarized, 2, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE), - new /datum/stack_recipe/window("fulltile electrochromic window", /obj/structure/window/full/reinforced/polarized, 4, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE) -)) - -/obj/item/stack/sheet/rglass - name = "reinforced glass" - desc = "Glass which seems to have rods or something stuck in them." - singular_name = "reinforced glass sheet" - icon_state = "sheet-rglass" - materials = list(MAT_METAL = MINERAL_MATERIAL_AMOUNT / 2, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 70, ACID = 100) - resistance_flags = ACID_PROOF - origin_tech = "materials=2" - created_window = /obj/structure/window/reinforced - full_window = /obj/structure/window/full/reinforced - merge_type = /obj/item/stack/sheet/rglass - point_value = 4 - table_type = /obj/structure/table/glass/reinforced - -/obj/item/stack/sheet/rglass/examine(mob/user) - . = ..() - . += "Reinforced glass is much stronger against damage than normal glass, otherwise it functions like normal glass does." - -/obj/item/stack/sheet/rglass/fifty - amount = 50 - -/obj/item/stack/sheet/rglass/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.reinforced_glass_recipes - -GLOBAL_LIST_INIT(pglass_recipes, list ( - new /datum/stack_recipe("plasma shard", /obj/item/shard/plasma, time = 0 SECONDS), - new /datum/stack_recipe/window("directional window", /obj/structure/window/plasmabasic, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE), - new /datum/stack_recipe/window("fulltile window", /obj/structure/window/full/plasmabasic, 2, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE) -)) - -/obj/item/stack/sheet/rglass/cyborg - energy_type = /datum/robot_storage/material/rglass - is_cyborg = TRUE - materials = list() - -/obj/item/stack/sheet/rglass/cyborg/examine(mob/user) - . = ..() - var/mob/living/silicon/robot/robot = user - if(!istype(robot.module, /obj/item/robot_module/drone)) - . += "You can refill your reinforced glass by picking it up from the ground." - -/obj/item/stack/sheet/rglass/cyborg/drone - energy_type = /datum/robot_storage/energy/rglass - -////////////////////////////// -// MARK: PLASMA GLASS -////////////////////////////// -/obj/item/stack/sheet/plasmaglass - name = "plasma glass" - desc = "A very strong and very resistant sheet of a plasma-glass mixture." - singular_name = "glass sheet" - icon_state = "sheet-plasmaglass" - item_state = "sheet-plasmaglass" - materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 75, ACID = 100) - resistance_flags = ACID_PROOF - origin_tech = "plasmatech=2;materials=2" - created_window = /obj/structure/window/plasmabasic - full_window = /obj/structure/window/full/plasmabasic - point_value = 19 - table_type = /obj/structure/table/glass/plasma - -/obj/item/stack/sheet/plasmaglass/examine_more(mob/user) - . = ..() - . += "A mixture of silica glass and plasma. The plasma forces the normally amorphous glass to assume a regular crystal structure. The plasma encourges heavy cross-linking, \ - massively improving the strength of the glass whilst also giving it exceptional thermal resistance. The denser molecular structure is also better at blocking radiation." - . += "" - . += "Unlike metal alloys incorporating plasma, plasma glass is not common - the secrets of producing it are a closely guarded trade secret of Nanotrasen, \ - very demanding conditions are required to correctly combine plasma and silica, and without this knowledge the process is fraught with great risk of igniting the plasma and (at best) destroying the production equipment." - . += "" - . += "Despite plastitanium glass being a structurally more robust material, pure plasma glass has some unique properties that Nanotrasen exploits in some of its experimental energy weapons, such as the immolator laser." - -/obj/item/stack/sheet/plasmaglass/fifty - amount = 50 - -/obj/item/stack/sheet/plasmaglass/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.pglass_recipes - -/obj/item/stack/sheet/plasmaglass/attackby__legacy__attackchain(obj/item/W, mob/user, params) - ..() - if(istype(W, /obj/item/stack/rods)) - var/obj/item/stack/rods/V = W - var/obj/item/stack/sheet/plasmarglass/RG = new (user.loc) - RG.add_fingerprint(user) - V.use(1) - var/obj/item/stack/sheet/glass/G = src - src = null - var/replace = (user.get_inactive_hand()==G) - G.use(1) - if(!G && !RG && replace) - user.put_in_hands(RG) - else - return ..() - -////////////////////////////// -// MARK: REINFORCED PLASMA GLASS -////////////////////////////// - -GLOBAL_LIST_INIT(prglass_recipes, list ( - new /datum/stack_recipe("plasma shard", /obj/item/shard/plasma, time = 0 SECONDS), - new /datum/stack_recipe/window("directional reinforced window", /obj/structure/window/plasmareinforced, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE), - new /datum/stack_recipe/window("fulltile reinforced window", /obj/structure/window/full/plasmareinforced, 2, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE) -)) - -/obj/item/stack/sheet/plasmarglass - name = "reinforced plasma glass" - desc = "Plasma glass which seems to have rods or something stuck in them." - singular_name = "reinforced plasma glass sheet" - icon_state = "sheet-plasmarglass" - item_state = "sheet-plasmarglass" - materials = list(MAT_METAL = MINERAL_MATERIAL_AMOUNT / 2, MAT_PLASMA = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) - armor = list(MELEE = 20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 80, ACID = 100) - resistance_flags = ACID_PROOF - origin_tech = "plasmatech=2;materials=2" - created_window = /obj/structure/window/plasmareinforced - full_window = /obj/structure/window/full/plasmareinforced - point_value = 23 - table_type = /obj/structure/table/glass/reinforced/plasma - -/obj/item/stack/sheet/plasmarglass/examine_more(mob/user) - . = ..() - . += "A mixture of silica glass and plasma. The plasma forces the normally amorphous glass to assume a regular crystal structure. The plasma encourges heavy cross-linking, \ - massively improving the strength of the glass whilst also giving it exceptional thermal resistance. The denser molecular structure is also better at blocking radiation." - . += "" - . += "Unlike metal alloys incorporating plasma, plasma glass is not common - the secrets of producing it are a closely guarded trade secret of Nanotrasen, \ - very demanding conditions are required to correctly combine plasma and silica, and without this knowledge the process is fraught with great risk of igniting the plasma and (at best) destroying the production equipment." - . += "" - . += "Despite plastitanium glass being a structurally more robust material, pure plasma glass has some unique properties that Nanotrasen exploits in some of its experimental energy weapons, such as the immolator laser." - -/obj/item/stack/sheet/plasmarglass/fifty - amount = 50 - -/obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.prglass_recipes - -GLOBAL_LIST_INIT(titaniumglass_recipes, list( - new /datum/stack_recipe/window("shuttle window", /obj/structure/window/full/shuttle, 2, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE) - )) - -////////////////////////////// -// MARK: TITANIUM GLASS -////////////////////////////// -/obj/item/stack/sheet/titaniumglass - name = "titanium glass" - desc = "A glass sheet made out of titanium silicate." - singular_name = "titanium glass sheet" - icon_state = "sheet-titaniumglass" - item_state = "sheet-titaniumglass" - materials = list(MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 80, ACID = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/titaniumglass - full_window = /obj/structure/window/full/shuttle - table_type = /obj/structure/table/glass/reinforced/titanium - -/obj/item/stack/sheet/titaniumglass/examine_more(mob/user) - . = ..() - . += "Titanium-silica mixes are an old but highly effective technology that produce a relatively lightweight, very strong glass that can withstand a good amount of punishment." - . += "" - . += "It is extensively used in the production of starship viewports and transparent armour, and is notably used extensively in space station construction by the USSP." - -/obj/item/stack/sheet/titaniumglass/fifty - amount = 50 - -/obj/item/stack/sheet/titaniumglass/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.titaniumglass_recipes - -GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( - new /datum/stack_recipe/window("plastitanium window", /obj/structure/window/full/plastitanium, 2, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE) - )) - -////////////////////////////// -// MARK: PLASTITANIUM GLASS -////////////////////////////// -/obj/item/stack/sheet/plastitaniumglass - name = "plastitanium glass" - desc = "A glass sheet made out of a plasma-titanium-silica mixture." - singular_name = "plastitanium glass sheet" - icon_state = "sheet-plastitaniumglass" - item_state = "sheet-plastitaniumglass" - materials = list(MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT, MAT_PLASMA = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 80, ACID = 100) - resistance_flags = ACID_PROOF - merge_type = /obj/item/stack/sheet/plastitaniumglass - full_window = /obj/structure/window/full/plastitanium - table_type = /obj/structure/table/glass/reinforced/plastitanium - -/obj/item/stack/sheet/plastitaniumglass/examine_more(mob/user) - . = ..() - . += "A mixture of silica glass, and plastitanium. It boasts similar material properties to plastitanium whilst also being optically transparent." - . += "" - . += "Unlike regular plasma glass, the production process of plastitanium glass is relatively safer and better known, as the titanium helps to control the plasma's reactivity whilst it is being mixed with the silica. \ - It is extensively employed for military-grade transparent armour and optics." - -/obj/item/stack/sheet/plastitaniumglass/fifty - amount = 50 - -/obj/item/stack/sheet/plastitaniumglass/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.plastitaniumglass_recipes - diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm deleted file mode 100644 index 6423b9edd94d4..0000000000000 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ /dev/null @@ -1,346 +0,0 @@ -/obj/item/stack/sheet/animalhide - name = "sheet-hide" - icon = 'icons/obj/stacks/organic.dmi' - desc = "Something went wrong." - origin_tech = "biotech=3" - dynamic_icon_state = FALSE - -/obj/item/stack/sheet/animalhide/human - name = "human skin" - desc = "The by-product of human farming." - singular_name = "human skin piece" - icon_state = "sheet-hide" - item_state = "sheet-leather" - -GLOBAL_LIST_INIT(human_recipes, list( - new /datum/stack_recipe("bloated human costume", /obj/item/clothing/suit/bloated_human, 5, on_floor = TRUE), - new /datum/stack_recipe("bloated human costume head", /obj/item/clothing/head/human_head, 5, on_floor = TRUE), - )) - -/obj/item/stack/sheet/animalhide/human/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.human_recipes - -/obj/item/stack/sheet/animalhide/generic - name = "generic skin" - desc = "A piece of generic skin." - singular_name = "generic skin piece" - icon_state = "sheet-hide" - item_state = "sheet-leather" - -/obj/item/stack/sheet/animalhide/corgi - name = "corgi hide" - desc = "The by-product of corgi farming." - singular_name = "corgi hide piece" - icon_state = "sheet-corgi" - -/obj/item/stack/sheet/animalhide/cat - name = "cat hide" - desc = "The by-product of cat farming." - singular_name = "cat hide piece" - icon_state = "sheet-cat" - -/obj/item/stack/sheet/animalhide/monkey - name = "monkey hide" - desc = "The by-product of monkey farming." - singular_name = "monkey hide piece" - icon_state = "sheet-monkey" - -/obj/item/stack/sheet/animalhide/lizard - name = "lizard skin" - desc = "Sssssss..." - singular_name = "lizard skin piece" - icon_state = "sheet-lizard" - -GLOBAL_LIST_INIT(lizard_recipes, list( - new /datum/stack_recipe("lizard skin handbag", /obj/item/storage/backpack/satchel/lizard, 5, on_floor = TRUE), - )) - -/obj/item/stack/sheet/animalhide/lizard/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.lizard_recipes - return ..() - -/// basic fur sheets -/obj/item/stack/sheet/fur - name = "pile of fur" - desc = "Vulp remains." - singular_name = "fur piece" - icon = 'icons/obj/stacks/organic.dmi' - icon_state = "sheet-hide" - origin_tech = "materials=2" - max_amount = 50 - -/obj/item/stack/sheet/animalhide/xeno - name = "alien hide" - desc = "The skin of a terrible creature." - singular_name = "alien hide piece" - icon_state = "sheet-xeno" - -GLOBAL_LIST_INIT(xeno_recipes, list ( - new /datum/stack_recipe("alien helmet", /obj/item/clothing/head/xenos, 1), - new /datum/stack_recipe("alien suit", /obj/item/clothing/suit/xenos, 2))) - -/obj/item/stack/sheet/animalhide/xeno/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.xeno_recipes - return ..() - -//don't see anywhere else to put these, maybe together they could be used to make the xenos suit? -/obj/item/stack/sheet/xenochitin - name = "alien chitin" - desc = "A piece of the hide of a terrible creature." - singular_name = "alien hide piece" - icon = 'icons/mob/alien.dmi' - icon_state = "chitin" - origin_tech = "" - dynamic_icon_state = FALSE - -/obj/item/xenos_claw - name = "alien claw" - desc = "The claw of a terrible creature." - icon = 'icons/mob/alien.dmi' - icon_state = "claw" - origin_tech = "" - -/obj/item/weed_extract - name = "weed extract" - desc = "A piece of slimy, purplish weed." - icon = 'icons/mob/alien.dmi' - icon_state = "weed_extract" - origin_tech = "" - -/obj/item/stack/sheet/hairlesshide - name = "hairless hide" - desc = "This hide was stripped of it's hair, but still needs tanning." - singular_name = "hairless hide piece" - icon = 'icons/obj/stacks/organic.dmi' - icon_state = "sheet-hairlesshide" - item_state = "sheet-leather" - origin_tech = "" - -/obj/item/stack/sheet/wetleather - name = "wet leather" - desc = "This leather has been cleaned but still needs to be dried." - singular_name = "wet leather piece" - icon = 'icons/obj/stacks/organic.dmi' - icon_state = "sheet-wetleather" - item_state = "sheet-leather" - origin_tech = "" - var/wetness = 30 //Reduced when exposed to high temperautres - var/drying_threshold_temperature = 500 //Kelvin to start drying - -/obj/item/stack/sheet/leather - name = "leather" - desc = "The by-product of mob grinding." - singular_name = "leather piece" - icon = 'icons/obj/stacks/organic.dmi' - icon_state = "sheet-leather" - item_state = "sheet-leather" - origin_tech = "materials=2" - -GLOBAL_LIST_INIT(leather_recipes, list ( - new /datum/stack_recipe_list("leather storages", list( - new /datum/stack_recipe("wallet", /obj/item/storage/wallet, 1), - new /datum/stack_recipe("toolbelt", /obj/item/storage/belt/utility, 4), - new /datum/stack_recipe("leather satchel", /obj/item/storage/backpack/satchel, 5), - new /datum/stack_recipe("briefcase", /obj/item/storage/briefcase, 4), - new /datum/stack_recipe("bandolier", /obj/item/storage/belt/bandolier, 5), - )), - null, - new /datum/stack_recipe("card box", /obj/item/deck/holder, 1), - new /datum/stack_recipe("muzzle", /obj/item/clothing/mask/muzzle, 2), - new /datum/stack_recipe("botany gloves", /obj/item/clothing/gloves/botanic_leather, 3), - new /datum/stack_recipe("leather jacket", /obj/item/clothing/suit/jacket/leather, 7), - new /datum/stack_recipe("leather shoes", /obj/item/clothing/shoes/leather, 2), - new /datum/stack_recipe("leather overcoat", /obj/item/clothing/suit/jacket/leather/overcoat, 10), - new /datum/stack_recipe("hide mantle", /obj/item/clothing/neck/cloak/unathi, 4))) - -/obj/item/stack/sheet/leather/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.leather_recipes - -/obj/item/stack/sheet/sinew - name = "watcher sinew" - icon = 'icons/obj/stacks/organic.dmi' - desc = "Long stringy filaments which presumably came from a watcher's wings." - singular_name = "watcher sinew" - icon_state = "sinew" - item_state = "sinew" - origin_tech = "biotech=4" - dynamic_icon_state = FALSE - -GLOBAL_LIST_INIT(sinew_recipes, list ( - new /datum/stack_recipe("sinew restraints", /obj/item/restraints/handcuffs/sinew, 1, on_floor = 1), - )) - -/obj/item/stack/sheet/sinew/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.sinew_recipes - -/obj/item/stack/sheet/animalhide/goliath_hide - name = "goliath hide plates" - desc = "Pieces of a goliath's rocky hide, these might be able to make your miner equipment such as suits, plasmaman helmets, borgs and Ripley class exosuits a bit more durable to attack from the local fauna." - icon = 'icons/obj/stacks/organic.dmi' - icon_state = "goliath_hide" - item_state = "goliath_hide" - singular_name = "hide plate" - flags = NOBLUDGEON - w_class = WEIGHT_CLASS_NORMAL - layer = MOB_LAYER - dynamic_icon_state = TRUE - var/static/list/goliath_platable_armor_typecache = typecacheof(list( - /obj/item/clothing/suit/hooded/explorer, - /obj/item/clothing/head/hooded/explorer, - /obj/item/clothing/head/helmet/space/plasmaman/mining)) - -/obj/item/stack/sheet/animalhide/goliath_hide/afterattack__legacy__attackchain(atom/target, mob/user, proximity_flag) - if(!proximity_flag) - return - if(is_type_in_typecache(target, goliath_platable_armor_typecache)) - var/obj/item/clothing/C = target - var/datum/armor/current_armor = C.armor - if(current_armor.getRating(MELEE) < 75) - if(!use(1)) - to_chat(user, "You dont have enough [src] for this!") - return - C.armor = current_armor.setRating(melee_value = min(current_armor.getRating(MELEE) + 15, 75)) - to_chat(user, "You strengthen [target], improving its resistance against melee attacks.") - else - to_chat(user, "You can't improve [C] any further!") - else if(istype(target, /obj/mecha/working/ripley)) - var/obj/mecha/working/ripley/D = target - if(D.hides < HIDES_COVERED_FULL && !D.plates && !D.drake_hides) - if(!use(1)) - to_chat(user, "You dont have enough [src] for this!") - return - D.hides++ - D.armor = D.armor.setRating(melee_value = min(D.armor.getRating(MELEE) + 10, 70)) - D.armor = D.armor.setRating(bullet_value = min(D.armor.getRating(BULLET) + 7, 60)) - D.armor = D.armor.setRating(laser_value = min(D.armor.getRating(LASER) + 7, 60)) - to_chat(user, "You strengthen [target], improving its resistance against attacks.") - D.update_appearance(UPDATE_DESC|UPDATE_OVERLAYS) - else - to_chat(user, "You can't improve [D] any further!") - else if(isrobot(target)) - var/mob/living/silicon/robot/R = target - if(istype(R.module, /obj/item/robot_module/miner)) - var/datum/armor/current_armor = R.armor - if(current_armor.getRating(MELEE) < 75) - if(!use(1)) - to_chat(user, "You dont have enough [src] for this!") - return - R.armor = current_armor.setRating(melee_value = min(current_armor.getRating(MELEE) + 15, 75)) - to_chat(user, "You strengthen [target], improving its resistance against melee attacks.") - else - to_chat(user, "You can't improve [R] any further!") - else - to_chat(user, "[R]'s armor can not be improved!") - -/obj/item/stack/sheet/animalhide/armor_plate - name = "armor plate" - desc = "This piece of metal can be attached to the mech itself, enhancing its protective characteristics. Unfortunately, only working class exosuits have notches for such armor." - icon = 'icons/mecha/mecha_equipment.dmi' - icon_state = "armor_plate" - item_state = "armor_plate" - singular_name = "armor plate" - flags = NOBLUDGEON - w_class = WEIGHT_CLASS_NORMAL - layer = MOB_LAYER - -/obj/item/stack/sheet/animalhide/armor_plate/afterattack__legacy__attackchain(atom/target, mob/user, proximity_flag) - if(!proximity_flag) - return - if(istype(target, /obj/mecha/working/ripley)) - var/obj/mecha/working/ripley/D = target - if(D.plates < PLATES_COVERED_FULL && !D.hides && !D.drake_hides) - if(!use(1)) - to_chat(user, "You dont have enough [src] for this!") - return - D.plates++ - D.armor = D.armor.setRating(melee_value = min(D.armor.getRating(MELEE) + 7, 60)) - D.armor = D.armor.setRating(bullet_value = min(D.armor.getRating(BULLET) + 4, 50)) - D.armor = D.armor.setRating(laser_value = min(D.armor.getRating(LASER) + 4, 50)) - to_chat(user, "You strengthen [target], improving its resistance against attacks.") - D.update_appearance(UPDATE_DESC|UPDATE_OVERLAYS) - else - to_chat(user, "You can't improve [D] any further!") - -/obj/item/stack/sheet/animalhide/armor_plate/attackby__legacy__attackchain(obj/item/W, mob/user, params) - return // no steel leather for ya - -/obj/item/stack/sheet/animalhide/ashdrake - name = "ash drake hide" - desc = "The strong, scaled hide of an ash drake. Can be attached to the mech itself, greatly enhancing its protective characteristics. Unfortunately, only working class exosuits have notches for such armor." - icon = 'icons/obj/stacks/organic.dmi' - icon_state = "dragon_hide" - item_state = "dragon_hide" - singular_name = "drake plate" - flags = NOBLUDGEON - w_class = WEIGHT_CLASS_NORMAL - layer = MOB_LAYER - dynamic_icon_state = TRUE - -/obj/item/stack/sheet/animalhide/ashdrake/afterattack__legacy__attackchain(atom/target, mob/user, proximity_flag) - if(!proximity_flag) - return - if(istype(target, /obj/mecha/working/ripley)) - var/obj/mecha/working/ripley/D = target - if(D.drake_hides < DRAKE_HIDES_COVERED_FULL && !D.hides && !D.plates) - if(!use(3)) - to_chat(user, "You dont have enough [src] for this!") - return - D.drake_hides++ - D.max_integrity += 50 - D.obj_integrity += 50 - D.armor = D.armor.setRating(melee_value = min(D.armor.getRating(MELEE) + 13, 80)) - D.armor = D.armor.setRating(bullet_value = min(D.armor.getRating(BULLET) + 7, 60)) - D.armor = D.armor.setRating(laser_value = min(D.armor.getRating(LASER) + 7, 60)) - to_chat(user, "You strengthen [target], improving its resistance against attacks.") - D.update_appearance(UPDATE_DESC|UPDATE_OVERLAYS) - else - to_chat(user, "You can't improve [D] any further!") - -//Step one - dehairing. - -/obj/item/stack/sheet/animalhide/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(W.sharp) - user.visible_message("[user] starts cutting hair off \the [src].", "You start cutting the hair off \the [src]...", "You hear the sound of a knife rubbing against flesh.") - if(do_after(user, 50 * W.toolspeed, target = src)) - to_chat(user, "You cut the hair from this [src.singular_name].") - //Try locating an exisitng stack on the tile and add to there if possible - for(var/obj/item/stack/sheet/hairlesshide/HS in usr.loc) - if(HS.amount < 50) - HS.amount++ - src.use(1) - break - //If it gets to here it means it did not find a suitable stack on the tile. - var/obj/item/stack/sheet/hairlesshide/HS = new(usr.loc) - HS.amount = 1 - src.use(1) - else - ..() - -//Step two - washing (also handled by water reagent code and washing machine code) -/obj/item/stack/sheet/hairlesshide/water_act(volume, temperature, source, method = REAGENT_TOUCH) - . = ..() - if(volume >= 10) - new /obj/item/stack/sheet/wetleather(get_turf(src), amount) - qdel(src) - -//Step three - drying -/obj/item/stack/sheet/wetleather/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ..() - if(exposed_temperature >= drying_threshold_temperature) - wetness-- - if(wetness == 0) - //Try locating an exisitng stack on the tile and add to there if possible - for(var/obj/item/stack/sheet/leather/HS in src.loc) - if(HS.amount < 50) - HS.amount++ - src.use(1) - wetness = initial(wetness) - return - //If it gets to here it means it did not find a suitable stack on the tile. - var/obj/item/stack/sheet/leather/HS = new(src.loc) - HS.amount = 1 - wetness = initial(wetness) - src.use(1) diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm deleted file mode 100644 index d0a3c536124d9..0000000000000 --- a/code/game/objects/items/stacks/sheets/light.dm +++ /dev/null @@ -1,28 +0,0 @@ -/obj/item/stack/light_w - name = "wired glass tiles" - gender = PLURAL - singular_name = "wired glass floor tile" - desc = "A glass tile, which is wired, somehow." - icon = 'icons/obj/tiles.dmi' - icon_state = "glass_wire" - w_class = WEIGHT_CLASS_NORMAL - force = 3.0 - throwforce = 5.0 - throw_speed = 5 - throw_range = 20 - flags = CONDUCT - max_amount = 60 - -/obj/item/stack/light_w/attackby__legacy__attackchain(obj/item/I, mob/user, params) - ..() - if(istype(I, /obj/item/wirecutters)) - var/obj/item/stack/cable_coil/CC = new(user.loc) - CC.amount = 5 - new/obj/item/stack/sheet/glass(user.loc) - use(1) - - if(istype(I, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/metal/M = I - M.use(1) - new /obj/item/stack/tile/light(user.loc) - use(1) diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm deleted file mode 100644 index 883399885be07..0000000000000 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ /dev/null @@ -1,586 +0,0 @@ -/* -Mineral Sheets - Contains: - - Sandstone - - Diamond - - Uranium - - Plasma - - Gold - - Silver - - Bananium - - Tranqillite - - Enriched Uranium - - Platinum - - Alien Alloy - - Adamantine -*/ - -GLOBAL_LIST_INIT(sandstone_recipes, list ( - new /datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 1 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, time = 2 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("sandstone airlock assembly", /obj/structure/door_assembly/door_assembly_sandstone, 4, time = 5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("sarcophagus", /obj/structure/closet/coffin/sarcophagus, 5, time = 5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - null, - new /datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - null, - new /datum/stack_recipe("Breakdown into sand", /obj/item/stack/ore/glass, 1, one_per_turf = FALSE, on_floor = TRUE), - )) - -GLOBAL_LIST_INIT(silver_recipes, list ( - new /datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, time = 2 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("silver airlock assembly", /obj/structure/door_assembly/door_assembly_silver, 4, time = 5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - null, - new /datum/stack_recipe("silver tile", /obj/item/stack/tile/mineral/silver, 1, 4, 20), - null, - new /datum/stack_recipe_list("silver statues", list( - new /datum/stack_recipe("Janitor Statue", /obj/structure/statue/silver/janitor, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("Sec Officer Statue", /obj/structure/statue/silver/sec, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("Sec Borg Statue", /obj/structure/statue/silver/secborg, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("Med Doctor Statue", /obj/structure/statue/silver/md, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("Med Borg Statue", /obj/structure/statue/silver/medborg, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("Monkey Statue", /obj/structure/statue/silver/monkey, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("Corgi Statue", /obj/structure/statue/silver/corgi, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - )), - null, - new /datum/stack_recipe("Silver Locket", /obj/item/clothing/neck/necklace/locket/silver, 1), - )) - -GLOBAL_LIST_INIT(diamond_recipes, list ( - new /datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, time = 2 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("diamond airlock assembly", /obj/structure/door_assembly/door_assembly_diamond, 4, time = 5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - null, - new /datum/stack_recipe("diamond tile", /obj/item/stack/tile/mineral/diamond, 1, 4, 20), - null, - new /datum/stack_recipe_list("diamond statues", list( - new /datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - )), - )) - -GLOBAL_LIST_INIT(uranium_recipes, list ( - new /datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, time = 2 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("uranium airlock assembly", /obj/structure/door_assembly/door_assembly_uranium, 4, time = 5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - null, - new /datum/stack_recipe("uranium tile", /obj/item/stack/tile/mineral/uranium, 1, 4, 20), - null, - new /datum/stack_recipe_list("uranium statues", list( - new /datum/stack_recipe("Nuke Statue", /obj/structure/statue/uranium/nuke, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("Engineer Statue", /obj/structure/statue/uranium/eng, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - )), - )) - -GLOBAL_LIST_INIT(gold_recipes, list ( - new /datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, time = 2 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("golden airlock assembly", /obj/structure/door_assembly/door_assembly_gold, 4, time = 5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - null, - new /datum/stack_recipe("gold tile", /obj/item/stack/tile/mineral/gold, 1, 4, 20), - null, - new /datum/stack_recipe_list("gold statues", list( - new /datum/stack_recipe("HoS Statue", /obj/structure/statue/gold/hos, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("HoP Statue", /obj/structure/statue/gold/hop, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("CE Statue", /obj/structure/statue/gold/ce, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("RD Statue", /obj/structure/statue/gold/rd, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("CMO Statue", /obj/structure/statue/gold/cmo, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - )), - null, - new /datum/stack_recipe_list("gold clothing", list( - new /datum/stack_recipe("Simple Crown", /obj/item/clothing/head/crown, 5), - null, - new /datum/stack_recipe("Simple Necklace", /obj/item/clothing/neck/necklace, 1), - new /datum/stack_recipe("Large Necklace", /obj/item/clothing/neck/necklace/long, 2), - new /datum/stack_recipe("Gold Locket", /obj/item/clothing/neck/necklace/locket, 1), - )), - )) - -GLOBAL_LIST_INIT(plasma_recipes, list ( - new /datum/stack_recipe/dangerous("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, time = 2 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe/dangerous("plasma airlock assembly", /obj/structure/door_assembly/door_assembly_plasma, 4, time = 5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - null, - new /datum/stack_recipe/dangerous("plasma tile", /obj/item/stack/tile/mineral/plasma, 1, 4, 20), - null, - new /datum/stack_recipe_list("plasma statues", list( - new /datum/stack_recipe/dangerous("Scientist Statue", /obj/structure/statue/plasma/scientist, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe/dangerous("Xenomorph Statue", /obj/structure/statue/plasma/xeno, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - )), - )) - -GLOBAL_LIST_INIT(bananium_recipes, list ( - new /datum/stack_recipe("bananium airlock assembly", /obj/structure/door_assembly/door_assembly_bananium, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE), - null, - new /datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), - null, - new /datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - null, - new /datum/stack_recipe("bananium grenade casing", /obj/item/grenade/bananade/casing, 4, on_floor = TRUE), - )) - -GLOBAL_LIST_INIT(tranquillite_recipes, list ( - new /datum/stack_recipe("tranquillite airlock assembly", /obj/structure/door_assembly/door_assembly_tranquillite, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE), - null, - new /datum/stack_recipe("invisible wall", /obj/structure/barricade/mime, 5, one_per_turf = TRUE, on_floor = TRUE, time = 50), - null, - new /datum/stack_recipe("silent tile", /obj/item/stack/tile/mineral/tranquillite, 1, 4, 20), - null, - new /datum/stack_recipe("Mime Statue", /obj/structure/statue/tranquillite/mime, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - )) - -GLOBAL_LIST_INIT(abductor_recipes, list ( - new /datum/stack_recipe("alien bed", /obj/structure/bed/abductor, 2, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("alien locker", /obj/structure/closet/abductor, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("alien table frame", /obj/structure/table_frame/abductor, 1, time = 15, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("alien airlock assembly", /obj/structure/door_assembly/door_assembly_abductor, 4, time = 20, one_per_turf = TRUE, on_floor = TRUE), - null, - new /datum/stack_recipe("alien floor tile", /obj/item/stack/tile/mineral/abductor, 1, 4, 20), - )) - -GLOBAL_LIST_INIT(adamantine_recipes, list( - new /datum/stack_recipe("incomplete servant golem shell", /obj/item/golem_shell/servant, req_amount = 1, res_amount = 1), - )) - -GLOBAL_LIST_INIT(snow_recipes, list( - new /datum/stack_recipe("snowman", /obj/structure/snowman, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("Snowball", /obj/item/snowball, 1) - )) - -/obj/item/stack/sheet/mineral - force = 5 - throwforce = 5 - throw_speed = 3 - -/obj/item/stack/sheet/mineral/Initialize(mapload, new_amount, merge) - . = ..() - scatter_atom() - -/obj/item/stack/sheet/mineral/scatter_atom(offset_x, offset_y) - pixel_x = rand(-4,0) + offset_x - pixel_y = rand(-4,0) + offset_y - -/obj/item/stack/sheet/mineral/sandstone - name = "sandstone brick" - desc = "This appears to be a combination of both sand and stone." - singular_name = "sandstone brick" - icon_state = "sheet-sandstone" - item_state = "sheet-sandstone" - throw_range = 5 - origin_tech = "materials=1" - sheettype = "sandstone" - materials = list(MAT_GLASS = MINERAL_MATERIAL_AMOUNT) - -/obj/item/stack/sheet/mineral/sandstone/fifty - amount = 50 - -/obj/item/stack/sheet/mineral/sandstone/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.sandstone_recipes - -/* - * Sandbags - */ - -/obj/item/stack/sheet/mineral/sandbags - name = "sandbags" - desc = "Cloth bags full of sand. They can be used to construct robust defensive emplacements that block movement and provide protection from gunfire." - icon = 'icons/obj/stacks/miscellaneous.dmi' - icon_state = "sandbags" - singular_name = "sandbag" - layer = LOW_ITEM_LAYER - merge_type = /obj/item/stack/sheet/mineral/sandbags - -GLOBAL_LIST_INIT(sandbag_recipes, list ( - new /datum/stack_recipe("sandbags", /obj/structure/barricade/sandbags, 1, time = 25, one_per_turf = TRUE, on_floor = TRUE), - )) - -/obj/item/stack/sheet/mineral/sandbags/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.sandbag_recipes - -/obj/item/emptysandbag - name = "empty sandbag" - desc = "A cloth bag to be filled with sand." - icon = 'icons/obj/stacks/miscellaneous.dmi' - icon_state = "empty-sandbags" - w_class = WEIGHT_CLASS_TINY - -/obj/item/emptysandbag/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/stack/ore/glass)) - var/obj/item/stack/ore/glass/G = I - to_chat(user, "You fill the sandbag.") - var/obj/item/stack/sheet/mineral/sandbags/S = new /obj/item/stack/sheet/mineral/sandbags(drop_location()) - qdel(src) - if(Adjacent(user) && !issilicon(user)) - user.put_in_hands(S) - G.use(1) - else - return ..() - -/obj/item/stack/sheet/mineral/diamond - name = "diamond" - desc = "Sparkles like a twinkling star." - icon_state = "sheet-diamond" - item_state = "sheet-diamond" - singular_name = "diamond" - origin_tech = "materials=6" - sheettype = "diamond" - merge_type = /obj/item/stack/sheet/mineral/diamond - materials = list(MAT_DIAMOND = MINERAL_MATERIAL_AMOUNT) - point_value = 25 - -/obj/item/stack/sheet/mineral/diamond/examine_more(mob/user) - . = ..() - . += "Diamond is the hardest known material, made of elemental carbon arranged in a tightly packed cubic crystal structure. \ - It has excellent thermal conductivity, a high refractive index, and is widely seen as very pretty to look at." - . += "" - . += "Diamond is highly sought after for both aesthetic uses and as a component of many advanced technologies." - -/obj/item/stack/sheet/mineral/diamond/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.diamond_recipes - -/obj/item/stack/sheet/mineral/diamond/fifty - amount = 50 - -/obj/item/stack/sheet/mineral/uranium - name = "uranium" - desc = "Don't keep this stuff in your pocket for too long. Hell, don't keep it anywhere near your person for too long." - icon_state = "sheet-uranium" - item_state = "sheet-uranium" - singular_name = "uranium sheet" - origin_tech = "materials=5" - sheettype = "uranium" - merge_type = /obj/item/stack/sheet/mineral/uranium - materials = list(MAT_URANIUM = MINERAL_MATERIAL_AMOUNT) - point_value = 20 - -/obj/item/stack/sheet/mineral/uranium/examine_more(mob/user) - . = ..() - . += "Uranium is extremely dense, radioactive metal. Without undergoing complex enrichment processes, it consists of roughly 99% uranium-238, and roughly 1% fissile uranium-235." - . += "" - . += "It finds uses in a great number of applications, including medicine, nuclear power generation, radiation shielding, cybernetic and robotic components, as well as weapons." - -/obj/item/stack/sheet/mineral/uranium/fifty - amount = 50 - -/obj/item/stack/sheet/mineral/uranium/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.uranium_recipes - -/obj/item/stack/sheet/mineral/plasma - name = "solid plasma" - desc = "Beautiful pure purple crystals, ready to ignite if a naked flame touches them..." - icon_state = "sheet-plasma" - item_state = "sheet-plasma" - singular_name = "plasma sheet" - origin_tech = "plasmatech=2;materials=2" - sheettype = "plasma" - merge_type = /obj/item/stack/sheet/mineral/plasma - materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT) - resistance_flags = FLAMMABLE - max_integrity = 100 - point_value = 20 - -/obj/item/stack/sheet/mineral/plasma/examine_more(mob/user) - . = ..() - . += "Plasma, the new oil. A highly sought-after material, and what propelled Nanotrasen from being a small, relatively unknown company to the interstellar megacorporation it is today." - . += "" - . += "Plasma is a metastable exotic matter, capable of existing in all 3 basic states of matter across a wide range of tempratures and pressures. It is widely used as starship fuel for both conventional engines and \ - Faster-Than-Light drives. It is also used in the creation of several classes of high-performance supermaterials and other advanced technologies. New uses for this wonder material are constantly being researched." - . += "" - . += "Its high flammability makes it very dangerous to handle, and it is also toxic and carcinogenic to most species. Veteran miners often begin to suffer from health problems caused by chronic exposure to plasma dust." - . += "" - . += "Despite its flammability, plasma-enhanced materials such as plasteel or plasma glass generally possess extreme fire resistance, ultra-low thermal conductivity, and a high emissivity. \ - This allows, for example, a relatively thin pane of plasma glass to be cool to the touch even when a massive inferno is burning on the other side." - -/obj/item/stack/sheet/mineral/plasma/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.plasma_recipes - -/obj/item/stack/sheet/mineral/plasma/fifty - amount = 50 - -/obj/item/stack/sheet/mineral/plasma/welder_act(mob/user, obj/item/I) - if(I.use_tool(src, user, volume = I.tool_volume)) - log_and_set_aflame(user, I) - return TRUE - -/obj/item/stack/sheet/mineral/plasma/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) - if(I.get_heat()) - log_and_set_aflame(user, I) - else - return ..() - -/obj/item/stack/sheet/mineral/plasma/proc/log_and_set_aflame(mob/user, obj/item/I) - var/turf/T = get_turf(src) - message_admins("Plasma sheets ignited by [key_name_admin(user)]([ADMIN_QUE(user, "?")]) ([ADMIN_FLW(user, "FLW")]) in ([COORD(T)] - [ADMIN_JMP(T)]") - log_game("Plasma sheets ignited by [key_name(user)] in [COORD(T)]") - investigate_log("was ignited by [key_name(user)]", "atmos") - user.create_log(MISC_LOG, "Plasma sheets ignited using [I]", src) - fire_act() - -/obj/item/stack/sheet/mineral/plasma/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - ..() - atmos_spawn_air(LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS, amount*10) - qdel(src) - -/obj/item/stack/sheet/mineral/gold - name = "gold" - desc = "GOLD!" - icon_state = "sheet-gold" - item_state = "sheet-gold" - singular_name = "gold bar" - origin_tech = "materials=4" - sheettype = "gold" - merge_type = /obj/item/stack/sheet/mineral/gold - materials = list(MAT_GOLD = MINERAL_MATERIAL_AMOUNT) - point_value = 20 - -/obj/item/stack/sheet/mineral/gold/examine_more(mob/user) - . = ..() - . += "A dense, soft, yellow precious metal that has been sought after by many species since before they recorded history as a symbol of wealth. \ - It has an exceptionally low reactivity and excellent corrosion resistance, being the most noble of the metallic elements." - . += "" - . += "It is widely used in the production of advanced electronics and chemical catalysts, as well as a few specialised medicines. Also used as a relatively safe store of wealth that is not affected by the economics of cash." - -/obj/item/stack/sheet/mineral/gold/fifty - amount = 50 - -/obj/item/stack/sheet/mineral/gold/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.gold_recipes - -/obj/item/stack/sheet/mineral/silver - name = "silver" - desc = "Shiny as a mirror. Allegedly repels werewolves and other mythical creatures." - icon_state = "sheet-silver" - item_state = "sheet-silver" - singular_name = "silver bar" - origin_tech = "materials=4" - sheettype = "silver" - merge_type = /obj/item/stack/sheet/mineral/silver - materials = list(MAT_SILVER = MINERAL_MATERIAL_AMOUNT) - point_value = 20 - -/obj/item/stack/sheet/mineral/silver/examine_more(mob/user) - . = ..() - . += "A shiny grey precious metal that has been sought after by many species since before they recorded history as a symbol of wealth. \ - It has very high thermal and electrical conductivity, and exhibits antimicrobial properties." - . += "" - . += "It is widely used in the production of advanced electronics, chemical catalysts, medicines, and some high performance materials." - -/obj/item/stack/sheet/mineral/silver/fifty - amount = 50 - -/obj/item/stack/sheet/mineral/silver/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.silver_recipes - -/obj/item/stack/sheet/mineral/bananium - name = "bananium" - desc = "It looks, smells, and tastes like real bananas. You'll break your teeth if you try to bite down on it, though." - icon_state = "sheet-bananium" - item_state = "sheet-clown" - singular_name = "bananium sheet" - origin_tech = "materials=4" - sheettype = "bananium" - merge_type = /obj/item/stack/sheet/mineral/bananium - materials = list(MAT_BANANIUM = MINERAL_MATERIAL_AMOUNT) - point_value = 50 - -/obj/item/stack/sheet/mineral/bananium/examine_more(mob/user) - . = ..() - . += "Bananium. An extremely rare crystalline material of unknown origin. Various theories of where it originates have been proposed, usually with no evidence to support them. \ - It makes a squeaking sound when something compresses it." - . += "" - . += "It is sought after by clowns all across the known galaxy and is used in the creation of many clownish contraptions." - -/obj/item/stack/sheet/mineral/bananium/ten - amount = 10 - -/obj/item/stack/sheet/mineral/bananium/thirty - amount = 30 - -/obj/item/stack/sheet/mineral/bananium/fifty - amount = 50 - -/obj/item/stack/sheet/mineral/bananium/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.bananium_recipes - -/obj/item/stack/sheet/mineral/tranquillite - name = "tranquillite" - desc = "..." - icon_state = "sheet-tranquillite" - item_state = "sheet-mime" - singular_name = "beret" - origin_tech = "materials=4" - sheettype = "tranquillite" - merge_type = /obj/item/stack/sheet/mineral/tranquillite - materials = list(MAT_TRANQUILLITE = MINERAL_MATERIAL_AMOUNT) - wall_allowed = FALSE //no tranquilite walls in code - point_value = 50 - -/obj/item/stack/sheet/mineral/tranquillite/examine_more(mob/user) - ..() - . += "Tranquilite. An extremely rare crystalline material of unknown origin. Various theories of where it originates have been proposed, usually with no evidence to support them. \ - Uniquely, it makes no sounds when bent, broken, smashed, or otherwise manipulated in any way, remaining deathly silent at all times. \ - It also dampens sounds around it, and can become completely transparent when properly manipulated." - . += "" - . += "It is sought after by mimes all across the known galaxy and is used in the creation of many of their mysterious contraptions. Various other groups also express an interest in its unusual properites." - -/obj/item/stack/sheet/mineral/tranquillite/ten - amount = 10 - -/obj/item/stack/sheet/mineral/tranquillite/thirty - amount = 30 - -/obj/item/stack/sheet/mineral/tranquillite/fifty - amount = 50 - -/obj/item/stack/sheet/mineral/tranquillite/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.tranquillite_recipes - -/* - * Titanium - */ -/obj/item/stack/sheet/mineral/titanium - name = "titanium" - desc = "It feels much lighter than it looks." - icon_state = "sheet-titanium" - item_state = "sheet-titanium" - singular_name = "titanium sheet" - force = 5 - throwforce = 5 - w_class = WEIGHT_CLASS_NORMAL - throw_speed = 1 - throw_range = 3 - sheettype = "titanium" - merge_type = /obj/item/stack/sheet/mineral/titanium - materials = list(MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT) - point_value = 20 - -/obj/item/stack/sheet/mineral/titanium/examine_more(mob/user) - . = ..() - . += "A strong, lightweight metal. Titanium has a strength similar to most steel alloys despite being about 45% less dense, whilst also exhibiting superior corrosion resistance. \ - It is also very good at reflecting energy weapon attacks. Careful where you fire that laser gun!" - . += "" - . += "It is widely used in robotics, aerospace applications, and in starship construction thanks to its excellent strength-to-weight ratio. Notably, it is also extensively used in space station construction by the USSP." - -GLOBAL_LIST_INIT(titanium_recipes, list( - new /datum/stack_recipe("titanium airlock assembly", /obj/structure/door_assembly/door_assembly_titanium, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE), - null, - new /datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20), - new /datum/stack_recipe("surgical tray", /obj/item/storage/surgical_tray, 1), - new /datum/stack_recipe("surgical instrument table", /obj/structure/table/tray, 3, one_per_turf = TRUE, on_floor = TRUE), - )) - -/obj/item/stack/sheet/mineral/titanium/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.titanium_recipes - -/obj/item/stack/sheet/mineral/titanium/fifty - amount = 50 - - -/* - * Plastitanium - */ -/obj/item/stack/sheet/mineral/plastitanium - name = "plastitanium" - desc = "Just as light as normal titanium, but you can feel an aura of extra robustness about it." - icon_state = "sheet-plastitanium" - item_state = "sheet-plastitanium" - singular_name = "plastitanium sheet" - force = 5 - throwforce = 5 - w_class = WEIGHT_CLASS_NORMAL - throw_speed = 1 - throw_range = 3 - sheettype = "plastitanium" - merge_type = /obj/item/stack/sheet/mineral/plastitanium - materials = list(MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT, MAT_PLASMA = MINERAL_MATERIAL_AMOUNT) - point_value = 45 - -/obj/item/stack/sheet/mineral/plastitanium/examine_more(mob/user) - . = ..() - . += "A high-performance superalloy of plasma and titanium, plastitanium is exceptionally light and strong, and has excellent thermal and corrosion resistance." - . += "" - . += "It is used in the construction of military-grade starship hulls, top-of-the-line personal armour, and melee weaponry." - -/obj/item/stack/sheet/mineral/plastitanium/fifty - amount = 50 - - -GLOBAL_LIST_INIT(plastitanium_recipes, list( - new /datum/stack_recipe("plas-titanium tile", /obj/item/stack/tile/mineral/plastitanium, 1, 4, 20), - new /datum/stack_recipe("Kidan Warrior Statue", /obj/structure/statue/plastitanium/kidanstatue, 5, time = 2.5 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - new /datum/stack_recipe("reinforced wheelchair", /obj/structure/chair/wheelchair/plastitanium, 15, time = 7 SECONDS, one_per_turf = TRUE, on_floor = TRUE), - )) - -/obj/item/stack/sheet/mineral/plastitanium/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.plastitanium_recipes - - -//Alien Alloy -/obj/item/stack/sheet/mineral/abductor - name = "alien alloy" - desc = "The dizzying colours change constantly depending on how the light hits it." - icon = 'icons/obj/abductor.dmi' - icon_state = "sheet-abductor" - item_state = "sheet-abductor" - dynamic_icon_state = FALSE - singular_name = "alien alloy sheet" - force = 5 - throwforce = 5 - w_class = WEIGHT_CLASS_NORMAL - throw_speed = 1 - origin_tech = "materials=6;abductor=1" - sheettype = "abductor" - merge_type = /obj/item/stack/sheet/mineral/abductor - table_type = /obj/structure/table/abductor - -/obj/item/stack/sheet/mineral/abductor/examine_more(mob/user) - . = ..() - . += "An out-of-this-world material used in the construction of exceptionally advanced technologies. Known to be associated strongly with abductors." - -/obj/item/stack/sheet/mineral/abductor/fifty - amount = 50 - -/obj/item/stack/sheet/mineral/abductor/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.abductor_recipes - -/obj/item/stack/sheet/mineral/adamantine - name = "adamantine" - desc = "A strange mineral used in the construction of sentient golems." - icon_state = "sheet-adamantine" - item_state = "sheet-adamantine" - singular_name = "adamantine sheet" - origin_tech = "materials=5" - merge_type = /obj/item/stack/sheet/mineral/adamantine - wall_allowed = FALSE - -/obj/item/stack/sheet/mineral/adamantine/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.adamantine_recipes - - -/obj/item/stack/sheet/mineral/adamantine/fifty - amount = 50 - -/* - * Snow - */ -/obj/item/stack/sheet/mineral/snow - name = "snow" - icon_state = "sheet-snow" - item_state = "sheet-snow" - singular_name = "snow block" - force = 1 - throwforce = 2 - merge_type = /obj/item/stack/sheet/mineral/snow - -/obj/item/stack/sheet/mineral/snow/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.snow_recipes diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm deleted file mode 100644 index d7d151a4dd0c1..0000000000000 --- a/code/game/objects/items/stacks/stack.dm +++ /dev/null @@ -1,390 +0,0 @@ -/* Stack type objects! - * Contains: - * Stacks - * Recipe datum - * Recipe list datum - */ - -/* - * Stacks - */ -/obj/item/stack - origin_tech = "materials=1" - /// Whether this stack is a `/cyborg` subtype or not. - var/is_cyborg = FALSE - /// The storage datum that will be used with this stack. Used only with `/cyborg` type stacks. - var/datum/robot_storage/source - /// Which `robot_energy_storage` to choose when this stack is created in cyborgs. Used only with `/cyborg` type stacks. - var/energy_type - /// How much energy using 1 sheet from the stack costs. Used only with `/cyborg` type stacks. - var/cost = 1 - /// A list of recipes buildable with this stack. - var/list/recipes = list() - /// The singular name of this stack. - var/singular_name - /// The current amount of this stack. - var/amount = 1 - var/to_transfer = 0 - /// The maximum amount of this stack. Also see stack recipes initialisation, param "max_res_amount" must be equal to this max_amount - var/max_amount = 50 - /// The path and its children that should merge with this stack, defaults to src.type. - var/merge_type - /// The type of table that is made when applying this stack to a frame. - var/table_type - /// Whether this stack has a dynamic icon_state based on amount / max_amount. - var/dynamic_icon_state = FALSE - /// Whether this stack can't stack with subtypes. - var/parent_stack = FALSE - -/obj/item/stack/Initialize(mapload, new_amount, merge = TRUE) - if(dynamic_icon_state) //If we have a dynamic icon state, we don't want item states to follow the same pattern. - item_state = initial(icon_state) - - if(new_amount != null) - amount = new_amount - - while(amount > max_amount) - amount -= max_amount - new type(loc, max_amount, FALSE) - - if(!merge_type) - merge_type = type - - . = ..() - if(merge) - for(var/obj/item/stack/item_stack in loc) - if(item_stack == src) - continue - if(can_merge(item_stack)) - INVOKE_ASYNC(src, PROC_REF(merge_without_del), item_stack) - // we do not want to qdel during initialization, so we just check whether or not we're a 0 count stack and let the hint handle deletion - if(is_zero_amount(FALSE)) - return INITIALIZE_HINT_QDEL - - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - update_icon(UPDATE_ICON_STATE) - -/obj/item/stack/update_icon_state() - . = ..() - if(!dynamic_icon_state) - return - - var/state = CEILING((amount/max_amount) * 3, 1) - if(state <= 1) - icon_state = initial(icon_state) - return - - icon_state = "[initial(icon_state)]_[state]" - -/obj/item/stack/proc/on_atom_entered(datum/source, atom/movable/entered) - SIGNAL_HANDLER // COMSIG_ATOM_ENTERED - - // Edge case. This signal will also be sent when src has entered the turf. Don't want to merge with ourselves. - if(entered == src) - return - - if(amount >= max_amount || ismob(loc)) // Prevents unnecessary call. Also prevents merging stack automatically in a mob's inventory - return - - if(!entered.throwing && can_merge(entered)) - INVOKE_ASYNC(src, PROC_REF(merge), entered) - -/obj/item/stack/hitby(atom/movable/hitting, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) - if(can_merge(hitting, inhand = TRUE)) - merge(hitting) - . = ..() - -/obj/item/stack/examine(mob/user) - . = ..() - if(!in_range(user, src)) - return - - if(is_cyborg) - if(singular_name) - . += "There is enough energy for [get_amount()] [singular_name]\s." - else - . += "There is enough energy for [get_amount()]." - return - - if(singular_name) - . += "There are [amount] [singular_name]\s in the stack." - else - . += "There are [amount] [name]\s in the stack." - . +="Alt-click to take a custom amount." - -/obj/item/stack/proc/add(newamount) - if(is_cyborg) - source.add_charge(newamount * cost) - else - amount += newamount - update_icon(UPDATE_ICON_STATE) - -/** Checks whether this stack can merge itself into another stack. - * - * Arguments: - * - check: The [/obj/item/stack] to check for mergeability. - * - inhand: `TRUE` if the stack should check should act like it's in a mob's hand, `FALSE` otherwise. - */ -/obj/item/stack/proc/can_merge(obj/item/stack/check, inhand = FALSE) - // We don't only use istype here, since that will match subtypes, and stack things that shouldn't stack - if(!istype(check, merge_type) || check.merge_type != merge_type) - return FALSE - if(amount <= 0 || check.amount <= 0) // no merging empty stacks that are in the process of being qdel'd - return FALSE - if(is_cyborg) // No merging cyborg stacks into other stacks - return FALSE - if(ismob(loc) && !inhand) // no merging with items that are on the mob - return FALSE - return TRUE - -/obj/item/stack/attack_self__legacy__attackchain(mob/user) - ui_interact(user) - -/obj/item/stack/attack_self_tk(mob/user) - ui_interact(user) - -/obj/item/stack/attack_tk(mob/user) - if(user.stat || !isturf(loc)) - return - // Allow remote stack splitting, because telekinetic inventory managing - // is really cool - if(!(src in user.tkgrabbed_objects)) - ..() - return - - var/obj/item/stack/material = split(user, 1) - material.attack_tk(user) - if(src && user.machine == src) - ui_interact(user) - -/obj/item/stack/attack_hand(mob/user) - if(!user.is_in_inactive_hand(src) && get_amount() > 1) - ..() - return - - change_stack(user, 1) - if(src && user.machine == src) - ui_interact(user) - -/obj/item/stack/attackby__legacy__attackchain(obj/item/thing, mob/user, params) - if(!can_merge(thing, TRUE)) - return ..() - - var/obj/item/stack/material = thing - if(merge(material)) - to_chat(user, "Your [material.name] stack now contains [material.get_amount()] [material.singular_name]\s.") - -/obj/item/stack/use(used, check = TRUE) - if(check && is_zero_amount(TRUE)) - return FALSE - - if(is_cyborg) - return source.use_charge(used * cost) - - if(amount < used) - return FALSE - - amount -= used - if(check && is_zero_amount(TRUE)) - return TRUE - - update_icon(UPDATE_ICON_STATE) - return TRUE - -/obj/item/stack/AltClick(mob/living/user) - if(!istype(user) || user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - - if(!in_range(src, user) || !ishuman(usr) || amount < 1 || is_cyborg) - return - - // Get amount from user - var/min = 0 - var/max = get_amount() - var/stackmaterial = tgui_input_number(user, "How many sheets do you wish to take out of this stack? (Max: [max])", "Stack Split", max_value = max) - if(isnull(stackmaterial) || stackmaterial <= min || stackmaterial > get_amount()) - return - - if(!Adjacent(user, 1)) - return - - change_stack(user,stackmaterial) - to_chat(user, "You take [stackmaterial] sheets out of the stack.") - -/obj/item/stack/ui_state(mob/user) - return GLOB.hands_state - -/obj/item/stack/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "StackCraft", name) - ui.set_autoupdate(FALSE) - ui.open() - -/obj/item/stack/ui_data(mob/user) - var/list/data = list() - data["amount"] = get_amount() - return data - -/obj/item/stack/ui_static_data(mob/user) - var/list/data = list() - data["recipes"] = recursively_build_recipes(recipes) - return data - -/obj/item/stack/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - if(..()) - return FALSE - - var/mob/living/user = usr - var/obj/item/stack/material = src - switch(action) - if("make") - var/datum/stack_recipe/recipe = locateUID(params["recipe_uid"]) - var/multiplier = text2num(params["multiplier"]) - if(!recipe.try_build(user, material, multiplier)) - return FALSE - - var/obj/result - result = recipe.do_build(user, material, multiplier, result) - if(!result) - return FALSE - - recipe.post_build(user, material, result) - return TRUE - -/** - * Recursively builds the recipes data for the given list of recipes, iterating through each recipe. - * If recipe is of type /datum/stack_recipe, it adds the recipe data to the recipes_data list with the title as the key. - * If recipe is of type /datum/stack_recipe_list, it recursively calls itself, scanning the entire list and adding each recipe to its category. - */ -/obj/item/stack/proc/recursively_build_recipes(list/recipes_to_iterate) - var/list/recipes_data = list() - for(var/recipe in recipes_to_iterate) - if(istype(recipe, /datum/stack_recipe)) - var/datum/stack_recipe/single_recipe = recipe - recipes_data["[single_recipe.title]"] = build_recipe_data(single_recipe) - - else if(istype(recipe, /datum/stack_recipe_list)) - var/datum/stack_recipe_list/recipe_list = recipe - recipes_data["[recipe_list.title]"] = recursively_build_recipes(recipe_list.recipes) - - return recipes_data - -/obj/item/stack/proc/build_recipe_data(datum/stack_recipe/recipe) - var/list/data = list() - var/obj/result = recipe.result_type - - data["uid"] = recipe.UID() - data["required_amount"] = recipe.req_amount - data["result_amount"] = recipe.res_amount - data["max_result_amount"] = recipe.max_res_amount - data["icon"] = result.icon - data["icon_state"] = result.icon_state - - // DmIcon cannot paint images. So, if we have grayscale sprite, we need ready base64 image. - if(recipe.result_image) - data["image"] = recipe.result_image - - return data - -/obj/item/stack/proc/get_amount() - if(!is_cyborg) - return amount - - if(!source) // The energy source has not yet been initializied - return FALSE - - return round(source.amount / cost) - -/obj/item/stack/proc/get_max_amount() - return max_amount - -/obj/item/stack/proc/get_amount_transferred() - return to_transfer - -/obj/item/stack/proc/split(mob/user, amount) - var/obj/item/stack/material = new type(loc, amount) - material.copy_evidences(src) - if(isliving(user)) - add_fingerprint(user) - material.add_fingerprint(user) - - use(amount) - return material - -/obj/item/stack/proc/change_stack(mob/user,amount) - var/obj/item/stack/material = new type(user, amount, FALSE) - . = material - material.copy_evidences(src) - user.put_in_hands(material) - add_fingerprint(user) - material.add_fingerprint(user) - use(amount) - SStgui.update_uis(src) - -/** - * Returns TRUE if the item stack is the equivalent of a 0 amount item. - * - * Also deletes the item if delete_if_zero is TRUE and the stack does not have - * is_cyborg set to true. - */ -/obj/item/stack/proc/is_zero_amount(delete_if_zero = TRUE) - if(is_cyborg) - return source.amount < cost - - if(amount < 1) - if(delete_if_zero) - qdel(src) - return TRUE - return FALSE - -/** - * Merges as much of src into material as possible. - * - * This calls use() without check = FALSE, preventing the item from qdeling itself if it reaches 0 stack size. - * - * As a result, this proc can leave behind a 0 amount stack. - */ -/obj/item/stack/proc/merge_without_del(obj/item/stack/material) - // Cover edge cases where multiple stacks are being merged together and haven't been deleted properly. - // Also cover edge case where a stack is being merged into itself, which is supposedly possible. - if(QDELETED(material)) - CRASH("Stack merge attempted on qdeleted target stack.") - if(QDELETED(src)) - CRASH("Stack merge attempted on qdeleted source stack.") - if(material == src) - CRASH("Stack attempted to merge into itself.") - - var/transfer = get_amount() - if(material.is_cyborg) - transfer = min(transfer, round((material.source.max_amount - material.source.amount) / material.cost)) - else - transfer = min(transfer, material.max_amount - material.amount) - - if(pulledby) - pulledby.start_pulling(material) - - material.copy_evidences(src) - use(transfer, FALSE) - material.add(transfer) - - return transfer - -/** - * Merges as much of src into material as possible. - * - * This proc deletes src if the remaining amount after the transfer is 0. - */ -/obj/item/stack/proc/merge(obj/item/stack/material) - . = merge_without_del(material) - is_zero_amount(TRUE) - -/obj/item/stack/proc/copy_evidences(obj/item/stack/material) - blood_DNA = material.blood_DNA - fingerprints = material.fingerprints - fingerprintshidden = material.fingerprintshidden - fingerprintslast = material.fingerprintslast diff --git a/code/game/objects/items/stacks/telecrystal.dm b/code/game/objects/items/stacks/telecrystal.dm deleted file mode 100644 index 8b05fb164e9fb..0000000000000 --- a/code/game/objects/items/stacks/telecrystal.dm +++ /dev/null @@ -1,53 +0,0 @@ -/obj/item/stack/telecrystal - name = "telecrystal" - desc = "It seems to be pulsing with suspiciously enticing energies." - singular_name = "telecrystal" - icon = 'icons/obj/stacks/minerals.dmi' - icon_state = "telecrystal" - item_state = "telecrystal" - w_class = WEIGHT_CLASS_TINY - max_amount = 100 - flags = NOBLUDGEON - origin_tech = "materials=6;syndicate=1" - dynamic_icon_state = TRUE - -/obj/item/stack/telecrystal/attack__legacy__attackchain(mob/target, mob/user) - if(target == user) //You can't go around smacking people with crystals to find out if they have an uplink or not. - for(var/obj/item/bio_chip/uplink/I in target) - if(I && I.imp_in) - I.hidden_uplink.uses += amount - use(amount) - to_chat(user, "You press [src] onto yourself and charge your hidden uplink.") - -/obj/item/stack/telecrystal/afterattack__legacy__attackchain(obj/item/I, mob/user, proximity) - if(!proximity) - return - if(istype(I) && I.hidden_uplink && I.hidden_uplink.active) //No metagaming by using this on every PDA around just to see if it gets used up. - I.hidden_uplink.uses += amount - use(amount) - to_chat(user, "You slot [src] into [I] and charge its internal uplink.") - else if(istype(I, /obj/item/cartridge/frame)) - var/obj/item/cartridge/frame/cart = I - if(!cart.charges) - to_chat(user, "[cart] is out of charges, it's refusing to accept [src]") - return - cart.telecrystals += amount - use(amount) - to_chat(user, "You slot [src] into [cart]. The next time it's used, it will also give telecrystals") - -/obj/item/stack/telecrystal/examine(mob/user) - . = ..() - if(isAntag(user)) - . += "Telecrystals can be activated by utilizing them on devices with an actively running uplink. They will not activate on inactive uplinks." - -/obj/item/stack/telecrystal/five - amount = 5 - -/obj/item/stack/telecrystal/twenty - amount = 20 - -/obj/item/stack/telecrystal/fifty - amount = 50 - -/obj/item/stack/telecrystal/hundred - amount = 100 diff --git a/code/game/objects/items/stacks/tiles/tile_mineral.dm b/code/game/objects/items/stacks/tiles/tile_mineral.dm deleted file mode 100644 index 55472aaab8357..0000000000000 --- a/code/game/objects/items/stacks/tiles/tile_mineral.dm +++ /dev/null @@ -1,146 +0,0 @@ -/obj/item/stack/tile/mineral/plasma - name = "plasma tile" - singular_name = "plasma floor tile" - desc = "A tile made out of highly flammable plasma. This can only end well." - icon_state = "tile_plasma" - origin_tech = "plasmatech=1" - turf_type = /turf/simulated/floor/mineral/plasma - mineralType = "plasma" - materials = list(MAT_PLASMA=500) - -/obj/item/stack/tile/mineral/plasma/welder_act(mob/user, obj/item/I) - if(I.use_tool(src, user, volume = I.tool_volume)) - atmos_spawn_air(LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS, 5) - user.visible_message("[user.name] sets the plasma tiles on fire!", \ - "You set the plasma tiles on fire!") - message_admins("Plasma tiles ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("Plasma tiles ignited by [key_name(user)] in ([x],[y],[z])") - investigate_log("was ignited by [key_name(user)]","atmos") - qdel(src) - -/obj/item/stack/tile/mineral/uranium - name = "uranium tile" - singular_name = "uranium floor tile" - desc = "A tile made out of uranium. You feel a bit woozy." - icon_state = "tile_uranium" - turf_type = /turf/simulated/floor/mineral/uranium - mineralType = "uranium" - materials = list(MAT_URANIUM=500) - -GLOBAL_LIST_INIT(gold_tile_recipes, list ( \ - new/datum/stack_recipe("fancy gold tile", /obj/item/stack/tile/mineral/gold/fancy, max_res_amount = 20), \ - )) - -/obj/item/stack/tile/mineral/gold - name = "gold tile" - singular_name = "gold floor tile" - desc = "A tile made out of gold, the swag seems strong here." - icon_state = "tile_gold" - turf_type = /turf/simulated/floor/mineral/gold - mineralType = "gold" - materials = list(MAT_GOLD=500) - -/obj/item/stack/tile/mineral/gold/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.gold_tile_recipes - -GLOBAL_LIST_INIT(goldfancy_tile_recipes, list ( \ - new/datum/stack_recipe("regular gold tile", /obj/item/stack/tile/mineral/gold, max_res_amount = 20), \ - )) - -/obj/item/stack/tile/mineral/gold/fancy - icon_state = "tile_goldfancy" - turf_type = /turf/simulated/floor/mineral/gold/fancy - -/obj/item/stack/tile/mineral/gold/fancy/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.goldfancy_tile_recipes - -GLOBAL_LIST_INIT(silver_tile_recipes, list ( \ - new/datum/stack_recipe("fancy silver tile", /obj/item/stack/tile/mineral/silver/fancy, max_res_amount = 20), \ - )) - -/obj/item/stack/tile/mineral/silver - name = "silver tile" - singular_name = "silver floor tile" - desc = "A tile made out of silver, the light shining from it is blinding." - icon_state = "tile_silver" - turf_type = /turf/simulated/floor/mineral/silver - mineralType = "silver" - materials = list(MAT_SILVER=500) - -/obj/item/stack/tile/mineral/silver/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.silver_tile_recipes - -GLOBAL_LIST_INIT(silverfancy_tile_recipes, list ( \ - new/datum/stack_recipe("regular silver tile", /obj/item/stack/tile/mineral/silver, max_res_amount = 20), \ - )) - -/obj/item/stack/tile/mineral/silver/fancy - icon_state = "tile_silverfancy" - turf_type = /turf/simulated/floor/mineral/silver/fancy - -/obj/item/stack/tile/mineral/silver/fancy/Initialize(mapload, new_amount, merge) - . = ..() - recipes = GLOB.silverfancy_tile_recipes - -/obj/item/stack/tile/mineral/diamond - name = "diamond tile" - singular_name = "diamond floor tile" - desc = "A tile made out of diamond. Wow, just, wow." - icon_state = "tile_diamond" - origin_tech = "materials=2" - turf_type = /turf/simulated/floor/mineral/diamond - mineralType = "diamond" - materials = list(MAT_DIAMOND=500) - -/obj/item/stack/tile/mineral/bananium - name = "bananium tile" - singular_name = "bananium floor tile" - desc = "A tile made out of bananium, HOOOOOOOOONK!" - icon_state = "tile_bananium" - turf_type = /turf/simulated/floor/mineral/bananium - mineralType = "bananium" - materials = list(MAT_BANANIUM=500) - -/obj/item/stack/tile/mineral/tranquillite - name = "silent tile" - singular_name = "silent floor tile" - desc = "A tile made out of tranquillite, SHHHHHHHHH!" - icon_state = "tile_tranquillite" - turf_type = /turf/simulated/floor/mineral/tranquillite - mineralType = "tranquillite" - materials = list(MAT_TRANQUILLITE=500) - -/obj/item/stack/tile/mineral/abductor - name = "alien floor tile" - singular_name = "alien floor tile" - desc = "A tile made out of alien alloy." - icon = 'icons/obj/abductor.dmi' - icon_state = "tile_abductor" - origin_tech = "materials=6;abductor=1" - turf_type = /turf/simulated/floor/mineral/abductor - mineralType = "abductor" - -/obj/item/stack/tile/mineral/titanium - name = "titanium tile" - singular_name = "titanium floor tile" - desc = "A tile made of titanium, used for shuttles." - icon_state = "tile_shuttle" - turf_type = /turf/simulated/floor/mineral/titanium - mineralType = "titanium" - materials = list(MAT_TITANIUM=500) - -/obj/item/stack/tile/mineral/titanium/purple - turf_type = /turf/simulated/floor/mineral/titanium/purple - icon_state = "tile_plasma" - -/obj/item/stack/tile/mineral/plastitanium - name = "plas-titanium tile" - singular_name = "plas-titanium floor tile" - desc = "A tile made of plas-titanium, used for very evil shuttles." - icon_state = "tile_darkshuttle" - turf_type = /turf/simulated/floor/mineral/plastitanium - mineralType = "plastitanium" - materials = list(MAT_TITANIUM=250, MAT_PLASMA=250) diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm deleted file mode 100644 index dbb39b37c38d2..0000000000000 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ /dev/null @@ -1,352 +0,0 @@ -/obj/item/stack/tile - name = "broken tile" - singular_name = "broken tile" - desc = "A broken tile. This should not exist." - icon = 'icons/obj/tiles.dmi' - icon_state = "tile" - item_state = "tile" - w_class = WEIGHT_CLASS_NORMAL - force = 1 - throwforce = 1 - throw_speed = 5 - throw_range = 20 - max_amount = 60 - flags = CONDUCT - origin_tech = "materials=1" - var/turf_type = null - var/mineralType = null - scatter_distance = 3 - -/obj/item/stack/tile/Initialize(mapload, new_amount, merge) - . = ..() - scatter_atom() - -/obj/item/stack/tile/welder_act(mob/user, obj/item/I) - if(get_amount() < 4) - to_chat(user, "You need at least four tiles to do this!") - return - . = TRUE - if(!I.use_tool(src, user, volume = I.tool_volume)) - to_chat(user, "You can not reform this!") - return - if(mineralType == "metal") - var/obj/item/stack/sheet/metal/new_item = new(user.loc) - user.visible_message("[user.name] shaped [src] into metal with the welding tool.", \ - "You shaped [src] into metal with the welding tool.", \ - "You hear welding.") - var/obj/item/stack/rods/R = src - src = null - var/replace = (user.get_inactive_hand()==R) - R.use(4) - if(!R && replace) - user.put_in_hands(new_item) - -//Grass -/obj/item/stack/tile/grass - name = "grass tiles" - gender = PLURAL - singular_name = "grass floor tile" - desc = "A patch of grass like they often use on golf courses." - icon_state = "tile_grass" - origin_tech = "biotech=1" - turf_type = /turf/simulated/floor/grass - resistance_flags = FLAMMABLE - -//Wood -/obj/item/stack/tile/wood - name = "wood floor tiles" - gender = PLURAL - singular_name = "wood floor tile" - desc = "An easy to fit wood floor tile." - icon_state = "tile-wood" - origin_tech = "biotech=1" - turf_type = /turf/simulated/floor/wood - merge_type = /obj/item/stack/tile/wood - resistance_flags = FLAMMABLE - -/obj/item/stack/tile/wood/cyborg - energy_type = /datum/robot_storage/energy/wood_tile - is_cyborg = TRUE - - -//Bamboo -/obj/item/stack/tile/bamboo - name = "bamboo mat pieces" - singular_name = "bamboo mat piece" - gender = PLURAL - desc = "A piece of a bamboo mat with a decorative trim." - icon_state = "tile_bamboo" - turf_type = /turf/simulated/floor/bamboo - merge_type = /obj/item/stack/tile/bamboo - parent_stack = TRUE - resistance_flags = FLAMMABLE - -/obj/item/stack/tile/bamboo/twenty - amount = 20 - -/obj/item/stack/tile/bamboo/tatami - name = "tatami with green rim" - singular_name = "green tatami floor tile" - icon_state = "tile_tatami_green" - turf_type = /turf/simulated/floor/bamboo/tatami - merge_type = /obj/item/stack/tile/bamboo/tatami - -/obj/item/stack/tile/bamboo/tatami/twenty - amount = 20 - -/obj/item/stack/tile/bamboo/tatami/purple - name = "tatami with purple rim" - singular_name = "purple tatami floor tile" - icon_state = "tile_tatami_purple" - turf_type = /turf/simulated/floor/bamboo/tatami/purple - merge_type = /obj/item/stack/tile/bamboo/tatami/purple - -/obj/item/stack/tile/bamboo/tatami/purple/twenty - amount = 20 - -/obj/item/stack/tile/bamboo/tatami/black - name = "tatami with black rim" - singular_name = "black tatami floor tile" - icon_state = "tile_tatami_black" - turf_type = /turf/simulated/floor/bamboo/tatami/black - merge_type = /obj/item/stack/tile/bamboo/tatami/black - -/obj/item/stack/tile/bamboo/tatami/black/twenty - amount = 20 - -//Carpets -/obj/item/stack/tile/carpet - name = "carpet" - singular_name = "carpet" - desc = "A piece of carpet. It is the same size as a floor tile." - icon_state = "tile-carpet" - turf_type = /turf/simulated/floor/carpet - resistance_flags = FLAMMABLE - table_type = /obj/structure/table/wood/fancy //Decides what table will be built with what carpet tile - -/obj/item/stack/tile/carpet/twenty - amount = 20 - -/obj/item/stack/tile/carpet/black - name = "black carpet" - icon_state = "tile-carpet-black" - turf_type = /turf/simulated/floor/carpet/black - table_type = /obj/structure/table/wood/fancy/black - -/obj/item/stack/tile/carpet/black/twenty - amount = 20 - -/obj/item/stack/tile/carpet/blue - name = "blue carpet" - icon_state = "tile-carpet-blue" - turf_type = /turf/simulated/floor/carpet/blue - table_type = /obj/structure/table/wood/fancy/blue - -/obj/item/stack/tile/carpet/blue/twenty - amount = 20 - -/obj/item/stack/tile/carpet/cyan - name = "cyan carpet" - icon_state = "tile-carpet-cyan" - turf_type = /turf/simulated/floor/carpet/cyan - table_type = /obj/structure/table/wood/fancy/cyan - -/obj/item/stack/tile/carpet/cyan/twenty - amount = 20 - -/obj/item/stack/tile/carpet/green - name = "green carpet" - icon_state = "tile-carpet-green" - turf_type = /turf/simulated/floor/carpet/green - table_type = /obj/structure/table/wood/fancy/green - -/obj/item/stack/tile/carpet/green/twenty - amount = 20 - -/obj/item/stack/tile/carpet/orange - name = "orange carpet" - icon_state = "tile-carpet-orange" - turf_type = /turf/simulated/floor/carpet/orange - table_type = /obj/structure/table/wood/fancy/orange - -/obj/item/stack/tile/carpet/orange/twenty - amount = 20 - -/obj/item/stack/tile/carpet/purple - name = "purple carpet" - icon_state = "tile-carpet-purple" - turf_type = /turf/simulated/floor/carpet/purple - table_type = /obj/structure/table/wood/fancy/purple - -/obj/item/stack/tile/carpet/purple/twenty - amount = 20 - -/obj/item/stack/tile/carpet/red - name = "red carpet" - icon_state = "tile-carpet-red" - turf_type = /turf/simulated/floor/carpet/red - table_type = /obj/structure/table/wood/fancy/red - -/obj/item/stack/tile/carpet/red/twenty - amount = 20 - -/obj/item/stack/tile/carpet/royalblack - name = "royal black carpet" - icon_state = "tile-carpet-royalblack" - turf_type = /turf/simulated/floor/carpet/royalblack - table_type = /obj/structure/table/wood/fancy/royalblack - -/obj/item/stack/tile/carpet/royalblack/ten - amount = 10 -/obj/item/stack/tile/carpet/royalblack/twenty - amount = 20 - -/obj/item/stack/tile/carpet/royalblue - name = "royal blue carpet" - icon_state = "tile-carpet-royalblue" - turf_type = /turf/simulated/floor/carpet/royalblue - table_type = /obj/structure/table/wood/fancy/royalblue - -/obj/item/stack/tile/carpet/royalblue/ten - amount = 10 - -/obj/item/stack/tile/carpet/royalblue/twenty - amount = 20 - -/obj/item/stack/tile/carpet/grimey - name = "cheap carpet" - icon_state = "tile-carpet-grimey" - turf_type = /turf/simulated/floor/carpet/grimey -/obj/item/stack/tile/carpet/grimey/ten - amount = 10 - -/obj/item/stack/tile/carpet/grimey/twenty - amount = 20 - -//Plasteel -/obj/item/stack/tile/plasteel - name = "floor tiles" - gender = PLURAL - singular_name = "floor tile" - desc = "Those could work as a pretty decent throwing weapon." - icon_state = "tile" - force = 6 - materials = list(MAT_METAL=500) - throwforce = 10 - throw_speed = 3 - throw_range = 7 - flags = CONDUCT - turf_type = /turf/simulated/floor/plasteel - mineralType = "metal" - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 70) - resistance_flags = FIRE_PROOF - merge_type = /obj/item/stack/tile/plasteel - -/obj/item/stack/tile/plasteel/cyborg - energy_type = /datum/robot_storage/energy/metal_tile - is_cyborg = TRUE - -//Light -/obj/item/stack/tile/light - name = "light tiles" - gender = PLURAL - singular_name = "light floor tile" - desc = "A floor tile made of glass, with an integrated light. Use a multitool on it to change its color." - icon_state = "tile_white" - force = 3 - throwforce = 5 - attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed") - turf_type = /turf/simulated/floor/light - -//Fakespace -/obj/item/stack/tile/fakespace - name = "astral carpet" - singular_name = "astral carpet" - desc = "A piece of carpet with a convincing star pattern." - icon_state = "tile_space" - turf_type = /turf/simulated/floor/fakespace - resistance_flags = FLAMMABLE - merge_type = /obj/item/stack/tile/fakespace - -/obj/item/stack/tile/fakespace/loaded - amount = 30 - -//High-traction -/obj/item/stack/tile/noslip - name = "high-traction floor tile" - singular_name = "high-traction floor tile" - desc = "A high-traction floor tile. It feels rubbery in your hand." - icon_state = "tile_noslip" - turf_type = /turf/simulated/floor/noslip - origin_tech = "materials=3" - merge_type = /obj/item/stack/tile/noslip - -/obj/item/stack/tile/noslip/loaded - amount = 20 - -//Pod floor -/obj/item/stack/tile/pod - name = "pod floor tile" - singular_name = "pod floor tile" - desc = "A grooved floor tile." - icon_state = "tile_pod" - turf_type = /turf/simulated/floor/pod - -/obj/item/stack/tile/pod/light - name = "light pod floor tile" - singular_name = "light pod floor tile" - desc = "A lightly colored grooved floor tile." - icon_state = "tile_podlight" - turf_type = /turf/simulated/floor/pod - -/obj/item/stack/tile/pod/dark - name = "dark pod floor tile" - singular_name = "dark pod floor tile" - desc = "A darkly colored grooved floor tile." - icon_state = "tile_poddark" - turf_type = /turf/simulated/floor/pod/dark - -/obj/item/stack/tile/arcade_carpet - name = "arcade carpet" - singular_name = "arcade carpet" - desc= "A piece of carpet with a retro spaceship pattern." - icon_state = "tile_space" - turf_type = /turf/simulated/floor/carpet/arcade - merge_type = /obj/item/stack/tile/arcade_carpet - resistance_flags = FLAMMABLE - -/obj/item/stack/tile/arcade_carpet/loaded - amount = 20 - -/obj/item/stack/tile/disco_light - name = "disco light tiles" - singular_name = "disco light tile" - desc = "A sheet of disco light tile." - icon_state = "tile_disco" - turf_type = /turf/simulated/floor/light/disco - merge_type = /obj/item/stack/tile/disco_light - -/obj/item/stack/tile/disco_light/thirty - amount = 30 - -/obj/item/stack/tile/catwalk - name = "catwalk tiles" - gender = PLURAL - singular_name = "catwalk tile" - desc = "A catwalk tile. Not rated for space usage." - icon_state = "tile_catwalk" - force = 6 - materials = list(MAT_METAL=500) - throwforce = 10 - throw_speed = 3 - throw_range = 7 - flags = CONDUCT - turf_type = /turf/simulated/floor/catwalk - mineralType = "metal" - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 70) - resistance_flags = FIRE_PROOF - merge_type = /obj/item/stack/tile/catwalk - -/obj/item/stack/tile/catwalk/cyborg - energy_type = /datum/robot_storage/energy/catwalk - is_cyborg = TRUE diff --git a/code/game/objects/items/theft_items.dm b/code/game/objects/items/theft_items.dm deleted file mode 100644 index 623f9f9239037..0000000000000 --- a/code/game/objects/items/theft_items.dm +++ /dev/null @@ -1,405 +0,0 @@ -//Items for nuke theft, supermatter theft traitor objective - - -// STEALING THE NUKE - -//the nuke core, base item -/obj/item/nuke_core - name = "plutonium core" - desc = "Extremely radioactive. Wear goggles." - icon = 'icons/obj/nuke_tools.dmi' - icon_state = "plutonium_core" - item_state = "plutoniumcore" - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - flags_2 = RAD_NO_CONTAMINATE_2 //Don't have the item itself become irradiated when it makes radiation. - var/cooldown = 0 - var/pulseicon = "plutonium_core_pulse" - -/obj/item/nuke_core/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - -/obj/item/nuke_core/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/nuke_core/attackby__legacy__attackchain(obj/item/nuke_core_container/container, mob/user) - if(istype(container)) - container.load(src, user) - else - return ..() - -/obj/item/nuke_core/process() - if(cooldown < world.time - 6 SECONDS) - cooldown = world.time - flick(pulseicon, src) - radiation_pulse(src, 400, 2) - -/obj/item/nuke_core/suicide_act(mob/user) - user.visible_message("[user] is rubbing [src] against [user.p_themselves()]! It looks like [user.p_theyre()] trying to commit suicide!") - return TOXLOSS - -/// The steal objective, so it doesnt mess with the SM sliver on pinpointers and objectives -/obj/item/nuke_core/plutonium - -/obj/item/nuke_core/plutonium/Initialize(mapload) - . = ..() - AddElement(/datum/element/high_value_item) - -//nuke core box, for carrying the core -/obj/item/nuke_core_container - name = "nuke core container" - desc = "A solid container for radioactive objects." - icon = 'icons/obj/nuke_tools.dmi' - icon_state = "core_container_empty" - item_state = "metal" - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //Don't want people trying to break it open with acid, then destroying the core. - var/obj/item/nuke_core/plutonium/core - var/dented = FALSE - var/cracked = FALSE - -/obj/item/nuke_core_container/Destroy() - QDEL_NULL(core) - return ..() - -/obj/item/nuke_core_container/ex_act(severity) - switch(severity) - if(EXPLODE_DEVASTATE) - if(!cracked) - crack_open() - if(EXPLODE_HEAVY) - if(!dented) - dented = TRUE - -/obj/item/nuke_core_container/examine(mob/user) - . = ..() - if(cracked) // Cracked open. - . += "It is broken, and can no longer store objects safely." - else if(dented) // Not cracked, but dented. - . += "[src] looks dented. Perhaps a bigger explosion may break it." - else // Not cracked or dented. - . += "Fine print on the box reads \"Cybersun Industries secure container, guaranteed thermite proof, assistant proof, and explosive resistant.\"" - -/obj/item/nuke_core_container/attack_hand(mob/user) - if(cracked && core) - unload(user) - else - return ..() - - -/obj/item/nuke_core_container/proc/load(obj/item/nuke_core/plutonium/new_core, mob/user) - if(core || !istype(new_core) || cracked) - return - new_core.forceMove(src) - core = new_core - icon_state = "core_container_loaded" - to_chat(user, "Container is sealing...") - addtimer(CALLBACK(src, PROC_REF(seal)), 10 SECONDS) - -/obj/item/nuke_core_container/proc/unload(mob/user) - core.add_fingerprint(user) - user.put_in_active_hand(core) - core = null - icon_state = "core_container_cracked_empty" - -/obj/item/nuke_core_container/proc/seal() - if(!QDELETED(core)) - STOP_PROCESSING(SSobj, core) - icon_state = "core_container_sealed" - playsound(src, 'sound/items/deconstruct.ogg', 60, TRUE) - if(ismob(loc)) - to_chat(loc, "[src] is permanently sealed, [core]'s radiation is contained.") - -/obj/item/nuke_core_container/attackby__legacy__attackchain(obj/item/nuke_core/plutonium/core, mob/user) - if(!istype(core) || cracked) - return ..() - - if(!user.drop_item()) - to_chat(user, "[core] is stuck to your hand!") - return - else - load(core, user) - -/obj/item/nuke_core_container/proc/crack_open() - visible_message("[src] bursts open!") - if(core) - START_PROCESSING(SSobj, core) - icon_state = "core_container_cracked_loaded" - else - icon_state = "core_container_cracked_empty" - name = "broken nuke core container" - cracked = TRUE - -/obj/item/paper/guides/antag/nuke_instructions - info = "How to break into a Nanotrasen nuclear device and remove its plutonium core:
    \ -
      \ -
    • Acquire some clothing that protects you from radiation, due to the radioactivity of the core.
    • \ -
    • Use a screwdriver with a very thin tip (provided) to unscrew the terminal's front panel.
    • \ -
    • Dislodge and remove the front panel with a crowbar.
    • \ -
    • Cut the inner metal plate with a welding tool.
    • \ -
    • Pry off the inner plate with a crowbar to expose the radioactive core.
    • \ -
    • Pull the core out of the nuclear device.
    • \ -
    • Put the core in the provided container, which will take some time to seal.
    • \ -
    • ???
    • \ -
    " - -// STEALING SUPERMATTER. - -/obj/item/paper/guides/antag/supermatter_sliver - info = "How to safely extract a supermatter sliver:
    \ -
      \ -
    • Approach an active supermatter crystal with radiation shielded personal protective equipment, and active magboots. DO NOT MAKE PHYSICAL CONTACT.
    • \ -
    • Use a supermatter scalpel (provided) to slice off a sliver of the crystal.
    • \ -
    • Use supermatter extraction tongs (also provided) to safely pick up the sliver you sliced off.
    • \ -
    • Physical contact of any object with the sliver will dust the object, as well as yourself.
    • \ -
    • Use the tongs to place the sliver into the provided container, which will take some time to seal.
    • \ -
    • Get the hell out before the crystal delaminates.
    • \ -
    • ???
    • \ -
    " - -/obj/item/nuke_core/supermatter_sliver - name = "supermatter sliver" - desc = "A tiny, highly volatile sliver of a supermatter crystal. Do not handle without protection!" - icon_state = "supermatter_sliver" - pulseicon = "supermatter_sliver_pulse" - w_class = WEIGHT_CLASS_BULKY //can't put it into bags - layer = ABOVE_MOB_LAYER + 0.02 - -/obj/item/nuke_core/supermatter_sliver/Initialize(mapload) - . = ..() - AddElement(/datum/element/high_value_item) - -/obj/item/nuke_core/supermatter_sliver/process() - . = ..() - var/new_filter = isnull(get_filter("ray")) - ray_filter_helper(1, 40,"#ffd04f", 6, 20) - if(new_filter) - animate(get_filter("ray"), offset = 10, time = 10 SECONDS, loop = -1) - animate(offset = 0, time = 10 SECONDS) - -/obj/item/nuke_core/supermatter_sliver/attack_tk(mob/user) // no TK dusting memes - return - -/obj/item/nuke_core/supermatter_sliver/can_be_pulled(mob/user) // no drag memes - if(HAS_TRAIT(user, TRAIT_SUPERMATTER_IMMUNE)) - return TRUE - return FALSE - -/obj/item/nuke_core/supermatter_sliver/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) - if(istype(I, /obj/item/retractor/supermatter)) - var/obj/item/retractor/supermatter/tongs = I - if(tongs.sliver) - to_chat(user, "[tongs] are already holding a supermatter sliver!") - return FALSE - forceMove(tongs) - tongs.sliver = src - tongs.icon_state = "supermatter_tongs_loaded" - tongs.item_state = "supermatter_tongs_loaded" - to_chat(user, "You carefully pick up [src] with [tongs].") - else if(istype(I, /obj/item/scalpel/supermatter) || istype(I, /obj/item/nuke_core_container/supermatter) || HAS_TRAIT(I, TRAIT_SUPERMATTER_IMMUNE)) // we don't want it to dust - return - else - if(issilicon(user)) - to_chat(user, "You try to touch [src] with one of your modules. Error!") - radiation_pulse(user, 500, 2) - playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) - user.dust() - qdel(src) - return - to_chat(user, "As it touches [src], both [src] and [I] burst into dust!") - radiation_pulse(user, 100) - playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) - qdel(I) - qdel(src) - -/obj/item/nuke_core/supermatter_sliver/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - if(!isliving(hit_atom)) - return ..() - var/mob/living/victim = hit_atom - if(victim.incorporeal_move || victim.status_flags & GODMODE || HAS_TRAIT(victim, TRAIT_SUPERMATTER_IMMUNE)) //try to keep this in sync with supermatter's consume fail conditions - return ..() - var/mob/user = throwingdatum?.get_thrower() - if(user) - add_attack_logs(user, victim, "[victim] consumed by [src] thrown by [user] ") - message_admins("[src] has consumed [key_name_admin(victim)] [ADMIN_JMP(src)], thrown by [key_name_admin(user)].") - investigate_log("has consumed [key_name(victim)], thrown by [key_name(user)]", "supermatter") - else - message_admins("[src] has consumed [key_name_admin(victim)] [ADMIN_JMP(src)] via throw impact.") - investigate_log("has consumed [key_name(victim)] via throw impact.", "supermatter") - victim.visible_message("As [victim] is hit by [src], both flash into dust and silence fills the room...", - "You're hit by [src] and everything suddenly goes silent.\n[src] flashes into dust, and soon as you can register this, you do as well.", - "Everything suddenly goes silent.") - victim.dust() - radiation_pulse(src, 500, 2) - playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) - qdel(src) - -/obj/item/nuke_core/supermatter_sliver/pickup(mob/living/user) - ..() - if(HAS_TRAIT(user, TRAIT_SUPERMATTER_IMMUNE)) - return TRUE //yay sliver throwing memes! - if(!isliving(user) || user.status_flags & GODMODE) //try to keep this in sync with supermatter's consume fail conditions - return FALSE - user.visible_message("[user] reaches out and tries to pick up [src]. [user.p_their()] body starts to glow and bursts into flames before flashing into dust!", - "You reach for [src] with your hands. That was dumb.", - "Everything suddenly goes silent.") - radiation_pulse(user, 500, 2) - playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) - user.dust() - -/obj/item/nuke_core_container/supermatter - name = "supermatter bin" - desc = "A tiny receptacle that releases an inert hyper-noblium mix upon sealing, allowing a sliver of a supermatter crystal to be safely stored." - var/obj/item/nuke_core/supermatter_sliver/sliver - -/obj/item/nuke_core_container/supermatter/Destroy() - QDEL_NULL(sliver) - return ..() - -/obj/item/nuke_core_container/supermatter/load(obj/item/retractor/supermatter/I, mob/user) - if(!istype(I) || !I.sliver || sliver) - return - I.sliver.forceMove(src) - sliver = I.sliver - I.sliver = null - I.icon_state = "supermatter_tongs" - I.item_state = "supermatter_tongs" - icon_state = "supermatter_container_loaded" - to_chat(user, "Container is sealing...") - addtimer(CALLBACK(src, PROC_REF(seal)), 10 SECONDS) - -/obj/item/nuke_core_container/supermatter/seal() - if(!QDELETED(sliver)) - STOP_PROCESSING(SSobj, sliver) - icon_state = "supermatter_container_sealed" - playsound(src, 'sound/items/deconstruct.ogg', 60, TRUE) - if(ismob(loc)) - to_chat(loc, "[src] is permanently sealed, [sliver] is safely contained.") - -/obj/item/nuke_core_container/supermatter/unload(obj/item/retractor/supermatter/I, mob/user) - if(!istype(I) || I.sliver) - return - sliver.forceMove(I) - I.sliver = sliver - sliver = null - I.icon_state = "supermatter_tongs_loaded" - I.item_state = "supermatter_tongs_loaded" - icon_state = "core_container_cracked_empty" - to_chat(user, "You carefully pick up [I.sliver] with [I].") - -/obj/item/nuke_core_container/supermatter/attackby__legacy__attackchain(obj/item/retractor/supermatter/tongs, mob/user) - if(istype(tongs)) - if(cracked) - //lets take that shard out - unload(tongs, user) - else - //try to load shard into core - load(tongs, user) - else - return ..() - -/obj/item/nuke_core_container/supermatter/attack_hand(mob/user) - if(cracked && sliver) //What did we say about touching the shard... - if(!isliving(user) || user.status_flags & GODMODE) - return FALSE - user.visible_message("[user] reaches out and tries to pick up [sliver]. [user.p_their()] body starts to glow and bursts into flames before flashing into dust!", - "You reach for [sliver] with your hands. That was dumb.", - "Everything suddenly goes silent.") - radiation_pulse(user, 500, 2) - playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) - message_admins("[sliver] has consumed [key_name_admin(user)] [ADMIN_JMP(src)].") - investigate_log("has consumed [key_name(user)].", "supermatter") - user.dust() - icon_state = "core_container_cracked_empty" - qdel(sliver) - - else - return ..() - -/obj/item/nuke_core_container/supermatter/crack_open() - visible_message("[src] bursts open!") - if(sliver) - START_PROCESSING(SSobj, sliver) - icon_state = "supermatter_container_cracked_loaded" - else - icon_state = "core_container_cracked_empty" - name = "broken supermatter bin" - cracked = TRUE - -/obj/item/scalpel/supermatter - name = "supermatter scalpel" - desc = "A scalpel with a fragile tip of condensed hyper-noblium gas, searingly cold to the touch, that can safely shave a sliver off a supermatter crystal." - icon = 'icons/obj/nuke_tools.dmi' - icon_state = "supermatter_scalpel" - toolspeed = 0.5 - damtype = BURN - usesound = 'sound/weapons/bladeslice.ogg' - var/uses_left - -/obj/item/scalpel/supermatter/Initialize(mapload) - . = ..() - uses_left = rand(2, 4) - -/obj/item/retractor/supermatter - name = "supermatter extraction tongs" - desc = "A pair of tongs made from condensed hyper-noblium gas, searingly cold to the touch, that can safely grip a supermatter sliver." - icon = 'icons/obj/nuke_tools.dmi' - icon_state = "supermatter_tongs" - lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' - righthand_file = 'icons/mob/inhands/items_righthand.dmi' - item_state = "supermatter_tongs" - toolspeed = 0.75 - damtype = BURN - var/obj/item/nuke_core/supermatter_sliver/sliver - -/obj/item/retractor/supermatter/Destroy() - QDEL_NULL(sliver) - return ..() - -/obj/item/retractor/supermatter/afterattack__legacy__attackchain(atom/O, mob/user, proximity) - . = ..() - if(!sliver) - return - if(proximity && ismovable(O) && O != sliver) - Consume(O, user) - -/obj/item/retractor/supermatter/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) // no instakill supermatter javelins - if(sliver) - sliver.forceMove(loc) - visible_message("[sliver] falls out of [src] as it hits the ground.") - sliver = null - icon_state = "supermatter_tongs" - item_state = "supermatter_tongs" - return ..() - -/obj/item/retractor/supermatter/proc/Consume(atom/movable/AM, mob/living/user) - if(ismob(AM)) - if(!isliving(AM)) - return - var/mob/living/victim = AM - if(victim.incorporeal_move || victim.status_flags & GODMODE) //try to keep this in sync with supermatter's consume fail conditions - return - victim.dust() - message_admins("[src] has consumed [key_name_admin(victim)] [ADMIN_JMP(src)].") - investigate_log("has irradiated [key_name(victim)].", "supermatter") - else if(istype(AM, /obj/singularity)) - return - else if(istype(AM, /obj/item/nuke_core_container)) - return - else if(istype(AM, /obj/machinery/atmospherics/supermatter_crystal)) - return - else - investigate_log("has consumed [AM].", "supermatter") - qdel(AM) - - if(user) - add_attack_logs(user, AM, "[AM] and [user] consumed by melee attack with [src] by [user]") - user.visible_message("As [user] touches [AM] with [src], both flash into dust and silence fills the room...", - "You touch [AM] with [src], and everything suddenly goes silent.\n[AM] and [sliver] flash into dust, and soon as you can register this, you do as well.", - "Everything suddenly goes silent.") - user.dust() - icon_state = "supermatter_tongs" - item_state = "supermatter_tongs" - radiation_pulse(src, 500, 2) - playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) - QDEL_NULL(sliver) diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm deleted file mode 100644 index f03263425522c..0000000000000 --- a/code/game/objects/items/tools/crowbar.dm +++ /dev/null @@ -1,140 +0,0 @@ -/obj/item/crowbar - name = "crowbar" - desc = "This handy tool is useful for lots of things, such as prying floor tiles or opening unpowered doors." - icon = 'icons/obj/tools.dmi' - icon_state = "crowbar" - item_state = "crowbar" - belt_icon = "crowbar" - usesound = 'sound/items/crowbar.ogg' - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - force = 5 - throwforce = 7 - w_class = WEIGHT_CLASS_NORMAL - materials = list(MAT_METAL = 300) - drop_sound = 'sound/items/handling/crowbar_drop.ogg' - pickup_sound = 'sound/items/handling/crowbar_pickup.ogg' - origin_tech = "engineering=1;combat=1" - attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") - toolspeed = 1 - - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 30) - tool_behaviour = TOOL_CROWBAR - -/obj/item/crowbar/red - icon_state = "crowbar_red" - item_state = "crowbar_red" - belt_icon = "crowbar_red" - force = 8 - -/obj/item/crowbar/brass - name = "brass crowbar" - desc = "A brass crowbar. It feels faintly warm to the touch." - icon_state = "crowbar_brass" - item_state = "crowbar_brass" - belt_icon = "crowbar_brass" - toolspeed = 0.5 - resistance_flags = FIRE_PROOF | ACID_PROOF - -/obj/item/crowbar/small - name = "miniature titanium crowbar" - desc = "A tiny, lightweight titanium crowbar. It fits handily in your pocket." - force = 3 - w_class = WEIGHT_CLASS_SMALL - throwforce = 3 - materials = list(MAT_TITANIUM = 250) - icon_state = "crowbar_titanium" - item_state = "crowbar_titanium" - origin_tech = "materials=2" - toolspeed = 1.25 - -/obj/item/crowbar/large - name = "large crowbar" - desc = "It's a big crowbar. It doesn't fit in your pockets, because its too big." - force = 12 - w_class = WEIGHT_CLASS_HUGE - throw_speed = 3 - throw_range = 3 - materials = list(MAT_METAL = 400) - icon_state = "crowbar_large" - item_state = "crowbar_large" - toolspeed = 0.5 - -/obj/item/crowbar/engineering - name = "engineering crowbar" - desc = "It's a big crowbar, perfect for fending off those assistants trying to get at your gloves." - force = 12 - //w_class = WEIGHT_CLASS_NORMAL Commented out so it can fit in belts - throw_speed = 3 - throw_range = 3 - materials = list(MAT_METAL = 400) - icon_state = "crowbar_eng" - item_state = "crowbar_eng" - belt_icon = "crowbar_eng" - toolspeed = 0.5 - -/obj/item/crowbar/engineering/suicide_act(mob/living/user) - - if(!user) - return - - user.visible_message("[user] looks up and hooks [src] into a ceiling tile! It looks like [user.p_theyre()] trying to commit suicide!") - - user.Immobilize(10 SECONDS) - playsound(loc, 'sound/items/crowbar.ogg', 50, TRUE, -1) - - sleep(2 SECONDS) - add_fingerprint(user) - - to_chat(user, "You pry open the ceiling tile above you and look beyond it.. oh God, what the hell is that?!") - user.emote("scream") - animate_fading_leap_up(user) - - for(var/obj/item/W in user) - user.drop_item_to_ground(W) - - user.dust() - return OBLITERATION - -/obj/item/crowbar/cyborg - name = "hydraulic crowbar" - desc = "A hydraulic prying tool, compact but powerful. Designed to replace crowbar in construction cyborgs." - usesound = 'sound/items/jaws_pry.ogg' - force = 10 - toolspeed = 0.5 - -/obj/item/crowbar/cyborg/red - name = "emergency hydraulic crowbar" - desc = "A hydraulic prying tool, compact but powerful. Supplied to non-construction cyborgs primarily to allow them to pry open airlocks during power outages." - icon_state = "crowbar_red" - -/obj/item/crowbar/power - name = "jaws of life" - desc = "A set of jaws of life, the magic of science has managed to fit it down into a device small enough to fit in a tool belt. It's fitted with a prying head." - flags = CONDUCT - icon_state = "jaws_pry" - item_state = "jawsoflife" - belt_icon = "jaws" - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" - usesound = 'sound/items/jaws_pry.ogg' - force = 15 - toolspeed = 0.25 - w_class = WEIGHT_CLASS_NORMAL - var/airlock_open_time = 100 // Time required to open powered airlocks - -/obj/item/crowbar/power/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_ADVANCED_SURGICAL, ROUNDSTART_TRAIT) - -/obj/item/crowbar/power/suicide_act(mob/user) - user.visible_message("[user] is putting [user.p_their()] head in [src]. It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/items/jaws_pry.ogg', 50, TRUE, -1) - return BRUTELOSS - -/obj/item/crowbar/power/attack_self__legacy__attackchain(mob/user) - playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) - var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power - to_chat(user, "You attach the cutting jaws to [src].") - qdel(src) - user.put_in_active_hand(cutjaws) diff --git a/code/game/objects/items/tools/welder.dm b/code/game/objects/items/tools/welder.dm deleted file mode 100644 index 812bfb80015aa..0000000000000 --- a/code/game/objects/items/tools/welder.dm +++ /dev/null @@ -1,333 +0,0 @@ -#define GET_FUEL reagents.get_reagent_amount("fuel") - -/obj/item/weldingtool - name = "welding tool" - desc = "A standard edition welder provided by Nanotrasen." - icon = 'icons/obj/tools.dmi' - icon_state = "welder" - item_state = "welder" - belt_icon = "welder" - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - force = 3 - throwforce = 5 - throw_speed = 3 - throw_range = 5 - hitsound = "swing_hit" - w_class = WEIGHT_CLASS_NORMAL - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 30) - resistance_flags = FIRE_PROOF - materials = list(MAT_METAL = 400, MAT_GLASS = 100) - origin_tech = "engineering=1;plasmatech=1" - tool_behaviour = TOOL_WELDER - toolspeed = 1 - tool_enabled = FALSE - usesound = 'sound/items/welder.ogg' - drop_sound = 'sound/items/handling/weldingtool_drop.ogg' - pickup_sound = 'sound/items/handling/weldingtool_pickup.ogg' - var/maximum_fuel = 20 - /// Set to FALSE if it doesn't need fuel, but serves equally well as a cost modifier. - var/requires_fuel = TRUE - /// If TRUE, fuel will regenerate over time. - var/refills_over_time = FALSE - /// Sound played when turned on. - var/activation_sound = 'sound/items/welderactivate.ogg' - /// Sound played when turned off. - var/deactivation_sound = 'sound/items/welderdeactivate.ogg' - /// The brightness of the active flame. - var/light_intensity = 2 - /// Does the icon_state change if the fuel is low? - var/low_fuel_changes_icon = TRUE - /// How often does the tool flash the user's eyes? - var/progress_flash_divisor = 1 SECONDS - -/obj/item/weldingtool/Initialize(mapload) - . = ..() - create_reagents(maximum_fuel) - reagents.add_reagent("fuel", maximum_fuel) - update_icon() - -/obj/item/weldingtool/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/weldingtool/examine(mob/user) - . = ..() - if(get_dist(user, src) <= 0) - . += "It contains [GET_FUEL] unit\s of fuel out of [maximum_fuel]." - -/obj/item/weldingtool/suicide_act(mob/user) - user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") - return FIRELOSS - -/obj/item/weldingtool/can_enter_storage(obj/item/storage/S, mob/user) - if(tool_enabled) - to_chat(user, "[S] can't hold [src] while it's lit!") - return FALSE - else - return TRUE - -/obj/item/weldingtool/process() - if(tool_enabled) - var/turf/T = get_turf(src) - if(T) // Implants for instance won't find a turf - T.hotspot_expose(2500, 1) - if(prob(5)) - remove_fuel(1) - if(refills_over_time) - if(GET_FUEL < maximum_fuel) - reagents.add_reagent("fuel", 1) - ..() - -/obj/item/weldingtool/extinguish_light(force) - if(!force) - return - if(!tool_enabled) - return - remove_fuel(maximum_fuel) - -/obj/item/weldingtool/attack_self__legacy__attackchain(mob/user) - if(tool_enabled) //Turn off the welder if it's on - to_chat(user, "You switch off [src].") - toggle_welder() - return - else if(GET_FUEL) //The welder is off, but we need to check if there is fuel in the tank - to_chat(user, "You switch on [src].") - toggle_welder() - else //The welder is off and unfuelled - to_chat(user, "[src] is out of fuel!") - -/obj/item/weldingtool/proc/toggle_welder(turn_off = FALSE) //Turn it on or off, forces it to deactivate - tool_enabled = turn_off ? FALSE : !tool_enabled - if(tool_enabled) - START_PROCESSING(SSobj, src) - damtype = BURN - force = 15 - hitsound = 'sound/items/welder.ogg' - playsound(loc, activation_sound, 50, 1) - set_light(light_intensity) - else - if(!refills_over_time) - STOP_PROCESSING(SSobj, src) - damtype = BRUTE - force = 3 - hitsound = "swing_hit" - playsound(loc, deactivation_sound, 50, 1) - set_light(0) - update_icon() - if(ismob(loc)) - var/mob/M = loc - M.update_inv_r_hand() - M.update_inv_l_hand() - -// If welding tool ran out of fuel during a construction task, construction fails. -/obj/item/weldingtool/tool_use_check(mob/living/user, amount, silent = FALSE) - if(!tool_enabled) - if(!silent) - to_chat(user, "[src] has to be on to complete this task!") - return FALSE - if(GET_FUEL >= amount * requires_fuel) - return TRUE - else - if(!silent) - to_chat(user, "You need more welding fuel to complete this task!") - return FALSE - -// When welding is about to start, run a normal tool_use_check, then flash a mob if it succeeds. -/obj/item/weldingtool/tool_start_check(atom/target, mob/living/user, amount=0) - . = tool_use_check(user, amount) - if(. && user && !ismob(target)) // Don't flash the user if they're repairing robo limbs or repairing a borg etc. Only flash them if the target is an object - user.flash_eyes(light_intensity) - -/obj/item/weldingtool/use(amount) - if(GET_FUEL < amount * requires_fuel) - return - remove_fuel(amount) - return TRUE - -/obj/item/weldingtool/afterattack__legacy__attackchain(atom/target, mob/user, proximity, params) - . = ..() - if(!tool_enabled) - return - if(!proximity || isturf(target)) // We don't want to take away fuel when we hit something far away - return - remove_fuel(0.5) - -/obj/item/weldingtool/attack__legacy__attackchain(mob/living/target, mob/living/user, def_zone) - if(cigarette_lighter_act(user, target)) - return - if(tool_enabled && target.IgniteMob()) - message_admins("[key_name_admin(user)] set [key_name_admin(target)] on fire") - log_game("[key_name(user)] set [key_name(target)] on fire") - return ..() - -/obj/item/weldingtool/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item) - var/obj/item/clothing/mask/cigarette/cig = ..() - if(!cig) - return !isnull(cig) - - if(!tool_enabled) - to_chat(user, "You need to activate [src] before you can light anything with it!") - return TRUE - - if(target == user) - user.visible_message( - "[user] casually lights [cig] with [src], what a badass.", - "You light [cig] with [src]." - ) - else - user.visible_message( - "[user] holds out [src] out for [target], and casually lights [cig]. What a badass.", - "You light [cig] for [target] with [src]." - ) - cig.light(user, target) - return TRUE - -/obj/item/weldingtool/use_tool(atom/target, user, delay, amount, volume, datum/callback/extra_checks) - target.add_overlay(GLOB.welding_sparks) - var/did_thing = ..() - if(did_thing) - remove_fuel(1) //Consume some fuel after we do a welding action - if(delay) - progress_flash_divisor = initial(progress_flash_divisor) - target.cut_overlay(GLOB.welding_sparks) - return did_thing - -/obj/item/weldingtool/tool_check_callback(mob/living/user, amount, datum/callback/extra_checks) - . = ..() - if(!. && user) - if(progress_flash_divisor == 0) - user.flash_eyes(min(light_intensity, 1)) - progress_flash_divisor = initial(progress_flash_divisor) - else - progress_flash_divisor-- - -/obj/item/weldingtool/proc/remove_fuel(amount) //NB: doesn't check if we have enough fuel, it just removes however much is left if there's not enough - reagents.remove_reagent("fuel", amount * requires_fuel) - if(!GET_FUEL) - toggle_welder(TRUE) - -/obj/item/weldingtool/refill(mob/user, atom/A, amount) - if(!A.reagents) - return - if(GET_FUEL >= maximum_fuel) - to_chat(user, "[src] is already full!") - return - var/amount_transferred = A.reagents.trans_id_to(src, "fuel", amount) - if(amount_transferred) - to_chat(user, "You refuel [src] by [amount_transferred] unit\s.") - playsound(src, 'sound/effects/refill.ogg', 50, 1) - update_icon() - return amount_transferred - else - to_chat(user, "There's not enough fuel in [A] to refuel [src]!") - -/obj/item/weldingtool/update_icon_state() - if(low_fuel_changes_icon) - var/ratio = GET_FUEL / maximum_fuel - ratio = CEILING(ratio*4, 1) * 25 - if(ratio == 100) - icon_state = initial(icon_state) - else - icon_state = "[initial(icon_state)][ratio]" - if(tool_enabled) - item_state = "[initial(item_state)]1" - else - item_state = "[initial(item_state)]" - -/obj/item/weldingtool/update_overlays() - . = ..() - if(tool_enabled) - . += "[initial(icon_state)]-on" - -/obj/item/weldingtool/cyborg_recharge(coeff, emagged) - if(reagents.check_and_add("fuel", maximum_fuel, 2 * coeff)) - update_icon() - -/obj/item/weldingtool/get_heat() - return tool_enabled * 2500 - -/obj/item/weldingtool/largetank - name = "industrial welding tool" - desc = "A slightly larger welder with a larger tank." - icon_state = "indwelder" - belt_icon = "welder_ind" - maximum_fuel = 40 - materials = list(MAT_METAL = 400, MAT_GLASS = 300) - origin_tech = "engineering=2;plasmatech=2" - -/obj/item/weldingtool/largetank/cyborg - name = "integrated welding tool" - desc = "An advanced welder designed to be used in robotic systems." - toolspeed = 0.5 - -/obj/item/weldingtool/research - name = "research welding tool" - desc = "A scratched-up welder that's been modified many times. Is it still the same tool?" - icon_state = "welder_research" - item_state = "welder_research" - belt_icon = "welder_research" - maximum_fuel = 40 - toolspeed = 0.75 - light_intensity = 1 - -/obj/item/weldingtool/research/suicide_act(mob/living/user) - - if(!user) - return - - user.visible_message("[user] is tinkering with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - - to_chat(user, "You begin tinkering with [src]...") - user.Immobilize(10 SECONDS) - sleep(2 SECONDS) - add_fingerprint(user) - - user.visible_message("[src] blows up in [user]'s face!", "Oh, shit!") - playsound(loc, "sound/effects/explosion1.ogg", 50, TRUE, -1) - user.gib() - - return OBLITERATION - -/obj/item/weldingtool/mini - name = "emergency welding tool" - desc = "A miniature welder used during emergencies." - icon_state = "miniwelder" - maximum_fuel = 10 - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL = 200, MAT_GLASS = 50) - low_fuel_changes_icon = FALSE - -/obj/item/weldingtool/hugetank - name = "upgraded welding tool" - desc = "An upgraded welder based off the industrial welder." - icon_state = "upindwelder" - item_state = "upindwelder" - belt_icon = "welder_upg" - maximum_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "engineering=3;plasmatech=2" - -/obj/item/weldingtool/experimental - name = "experimental welding tool" - desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." - icon_state = "exwelder" - item_state = "exwelder" - belt_icon = "welder_exp" - maximum_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4" - light_intensity = 1 - toolspeed = 0.5 - refills_over_time = TRUE - low_fuel_changes_icon = FALSE - -/obj/item/weldingtool/experimental/brass - name = "brass welding tool" - desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." - icon_state = "brasswelder" - item_state = "brasswelder" - belt_icon = "welder_brass" - resistance_flags = FIRE_PROOF | ACID_PROOF - -#undef GET_FUEL diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm deleted file mode 100644 index a66e55b12f989..0000000000000 --- a/code/game/objects/items/trash.dm +++ /dev/null @@ -1,196 +0,0 @@ -//Items labled as 'trash' for the trash bag. -//TODO: Make this an item var or something... - -//Added by Jack Rost -/obj/item/trash - icon = 'icons/obj/trash.dmi' - w_class = WEIGHT_CLASS_TINY - desc = "This is rubbish." - resistance_flags = FLAMMABLE - -/obj/item/trash/decompile_act(obj/item/matter_decompiler/C, mob/user) - if(isdrone(user)) - C.stored_comms["metal"] += 2 - C.stored_comms["wood"] += 1 - C.stored_comms["glass"] += 1 - qdel(src) - return TRUE - return ..() - -/obj/item/trash/attack__legacy__attackchain(mob/M as mob, mob/living/user as mob) - return - -/obj/item/trash/raisins - name = "4no raisins" - icon_state= "4no_raisins" - -/obj/item/trash/candy - name = "Candy" - icon_state= "candy" - -/obj/item/trash/cheesie - name = "Cheesie honkers" - icon_state = "cheesie_honkers" - -/obj/item/trash/chips - name = "Chips" - icon_state = "chips" - -/obj/item/trash/twimsts - name = "Twimsts" - icon_state = "twimsts" - -/obj/item/trash/popcorn - name = "popcorn" - icon_state = "popcorn" - gender = PLURAL - -/obj/item/trash/sosjerky - name = "Scaredy's Private Reserve Beef Jerky" - icon_state = "sosjerky" - -/obj/item/trash/spacetwinkie - name = "Space Twinkie" - icon_state = "space_twinkie" - -/obj/item/trash/syndi_cakes - name = "Syndi cakes" - icon_state = "syndi_cakes" - -/obj/item/trash/waffles - name = "Waffles" - icon_state = "waffles" - -/obj/item/trash/plate - name = "plate" - icon_state = "plate" - resistance_flags = NONE - -/obj/item/trash/snack_bowl - name = "snack bowl" - icon_state = "snack_bowl" - -/obj/item/trash/fried_vox - name = "Kentucky Fried Vox" - icon_state = "fried_vox_empty" - item_state = "fried_vox_empty" - slot_flags = ITEM_SLOT_HEAD - dog_fashion = /datum/dog_fashion/head/fried_vox_empty - sprite_sheets = list( - "Skrell" = 'icons/mob/clothing/species/skrell/head.dmi', - "Drask" = 'icons/mob/clothing/species/drask/head.dmi', - "Kidan" = 'icons/mob/clothing/species/kidan/head.dmi' - ) - -/obj/item/trash/pistachios - name = "Pistachios pack" - icon_state = "pistachios_pack" - -/obj/item/trash/semki - name = "Semki pack" - icon_state = "semki_pack" - -/obj/item/trash/tray - name = "Tray" - icon_state = "tray" - resistance_flags = NONE - -/obj/item/trash/candle - name = "candle" - icon = 'icons/obj/candle.dmi' - icon_state = "candle4" - -/obj/item/trash/liquidfood - name = "\improper \"LiquidFood\" ration" - icon_state = "liquidfood" - -/obj/item/trash/can - name = "crushed can" - icon_state = "cola" - var/is_glass = 0 - var/is_plastic = 0 - resistance_flags = NONE - -/obj/item/trash/gum - name = "chewed gum" - desc = "NOT free candy." - icon_state = "gum" - -/obj/item/trash/tastybread - name = "bread tube" - icon_state = "tastybread" - -/obj/item/trash/tapetrash - name = "old duct tape" - icon_state = "tape" - desc = "Not sticky anymore." - throw_range = 1 - -/obj/item/trash/popsicle_stick - name = "used popsicle stick" - icon_state = "popsicle_stick_s" - desc = "Still tastes sweet." - -/obj/item/trash/caviar - name = "caviar can" - icon_state = "caviar-empty" - desc = "There's none left." - -// Ammo casings -/obj/item/trash/spentcasing - icon = 'icons/obj/ammo.dmi' - name = "arbitrary spent casing item" - desc = "If you can see this and didn't spawn it, make an issue report on GitHub." - icon_state = "gshell" - scatter_distance = 10 - -/obj/item/trash/spentcasing/Initialize(mapload) - . = ..() - scatter_atom() - transform = turn(transform, rand(0, 360)) - -/obj/item/trash/spentcasing/shotgun - name = "spent buckshot shell" - desc = "A spent shotgun shell. It smells like cordite." - icon_state = "gshell" - -/obj/item/trash/spentcasing/shotgun/rubbershot - name = "spent rubbershot shell" - desc = "A spent shotgun shell. It smells like cordite and singed rubber." - icon_state = "cshell" - -/obj/item/trash/spentcasing/shotgun/beanbag - name = "spent beanbag shell" - icon_state = "bshell" - -/obj/item/trash/spentcasing/shotgun/slug - name = "spent slug shell" - icon_state = "blshell" - -/obj/item/trash/spentcasing/shotgun/dragonsbreath - name = "spent dragonsbreath shell" - desc = "A spent shotgun shell. It smells like cordite, burnt plastic, and a hint of petroleum." - icon_state = "ishell" - -/obj/item/trash/spentcasing/shotgun/stun - name = "spent stun shell" - icon_state = "stunshell" - -/obj/item/trash/spentcasing/bullet - name = "spent bullet casing" - desc = "A spent bullet casing. It smells of brass and cordite." - icon_state = "s-casing" - -/obj/item/trash/spentcasing/bullet/medium - name = "spent large bullet casing" - desc = "A spent high-caliber bullet casing. It smells of brass and cordite." - icon_state = "762-casing" - -/obj/item/trash/spentcasing/bullet/large - name = "spent .50 BMG bullet casing" - desc = "A spent .50 BMG bullet casing. It smells of brass and cordite." - icon_state = ".50" - -/obj/item/trash/spentcasing/bullet/lasershot - desc = "A spent IK-series single-use lasershot cell. It smells of burnt plastic with a metallic-chemical undertone." - icon_state = "lasercasing" diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm deleted file mode 100755 index 4ec71d49dbf71..0000000000000 --- a/code/game/objects/items/weapons/AI_modules.dm +++ /dev/null @@ -1,500 +0,0 @@ -/* -CONTAINS: -AI MODULES - -*/ - -// AI module - -/obj/item/ai_module - name = "AI Module" - icon = 'icons/obj/module_ai.dmi' - icon_state = "standard_low" - item_state = "electronic" - desc = "An AI Module for transmitting encrypted instructions to the AI." - flags = CONDUCT - force = 5.0 - w_class = WEIGHT_CLASS_SMALL - throwforce = 5.0 - throw_speed = 3 - throw_range = 15 - origin_tech = "programming=3" - materials = list(MAT_GOLD=50) - var/datum/ai_laws/laws = null - -/obj/item/ai_module/Initialize(mapload) - . = ..() - if(mapload && HAS_TRAIT(SSstation, STATION_TRAIT_UNIQUE_AI) && is_station_level(z)) - var/delete_module = handle_unique_ai() - if(delete_module) - return INITIALIZE_HINT_QDEL - if(laws) - desc += "
    " - for(var/datum/ai_law/current in laws.inherent_laws) - desc += current.law - desc += "
    " - -///what this module should do if it is mapload spawning on a unique AI station trait round. -/obj/item/ai_module/proc/handle_unique_ai() - return TRUE // If this returns true, it will be deleted on roundstart - -/obj/item/ai_module/proc/install(obj/machinery/computer/C) - if(istype(C, /obj/machinery/computer/aiupload)) - var/obj/machinery/computer/aiupload/comp = C - if(comp.stat & NOPOWER) - to_chat(usr, "The upload computer has no power!") - return - if(comp.stat & BROKEN) - to_chat(usr, "The upload computer is broken!") - return - if(!comp.current) - to_chat(usr, "You haven't selected an AI to transmit laws to!") - return - - if(comp.current.stat == DEAD || comp.current.control_disabled) - to_chat(usr, "Upload failed. No signal is being detected from the AI.") - else if(comp.current.see_in_dark == 0) - to_chat(usr, "Upload failed. Only a faint signal is being detected from the AI, and it is not responding to our requests. It may be low on power.") - else - src.transmitInstructions(comp.current, usr) - to_chat(comp.current, "These are your laws now:") - comp.current.show_laws() - for(var/mob/living/silicon/robot/R in GLOB.mob_list) - if(R.lawupdate && (R.connected_ai == comp.current)) - to_chat(R, "These are your laws now:") - R.show_laws() - to_chat(usr, "Upload complete. The AI's laws have been modified.") - return TRUE - - else if(istype(C, /obj/machinery/computer/borgupload)) - var/obj/machinery/computer/borgupload/comp = C - if(comp.stat & NOPOWER) - to_chat(usr, "The upload computer has no power!") - return - if(comp.stat & BROKEN) - to_chat(usr, "The upload computer is broken!") - return - if(!comp.current) - to_chat(usr, "You haven't selected a robot to transmit laws to!") - return - - if(comp.current.stat == DEAD || comp.current.emagged) - to_chat(usr, "Upload failed. No signal is being detected from the robot.") - else if(comp.current.connected_ai) - to_chat(usr, "Upload failed. The robot is slaved to an AI.") - else - src.transmitInstructions(comp.current, usr) - to_chat(comp.current, "These are your laws now:") - comp.current.show_laws() - to_chat(usr, "Upload complete. The robot's laws have been modified.") - - -/obj/item/ai_module/proc/transmitInstructions(mob/living/silicon/ai/target, mob/sender) - log_law_changes(target, sender) - - if(laws) - laws.sync(target, 0) - addAdditionalLaws(target, sender) - - to_chat(target, "[sender] has uploaded a change to the laws you must follow, using \an [src]. From now on: ") - target.show_laws() - -/obj/item/ai_module/proc/log_law_changes(mob/living/silicon/ai/target, mob/sender) - var/time = time2text(world.realtime,"hh:mm:ss") - GLOB.lawchanges.Add("[time] : [sender.name]([sender.key]) used [src.name] on [target.name]([target.key])") - log_and_message_admins("used [src.name] on [target.name]([target.key])") - -/obj/item/ai_module/proc/addAdditionalLaws(mob/living/silicon/ai/target, mob/sender) - return - - -/******************** Safeguard ********************/ -/obj/item/ai_module/safeguard - name = "\improper Safeguard AI module" - var/targetName = "" - desc = "A 'safeguard' AI module: 'Safeguard . Individuals that threaten are not crew and must be eliminated.'" - icon_state = "light_blue_medium" - origin_tech = "programming=3;materials=3" - -/obj/item/ai_module/safeguard/attack_self__legacy__attackchain(mob/user as mob) - ..() - var/new_targetName = tgui_input_text(user, "Please enter the name of the person to safeguard.", "Safeguard who?", user.name) - if(!new_targetName) - return - targetName = new_targetName - desc = "A 'safeguard' AI module: 'Safeguard [targetName]. Individuals that threaten [targetName] are not crew and must be eliminated.'" - -/obj/item/ai_module/safeguard/install(obj/machinery/computer/C) - if(!targetName) - to_chat(usr, "No name detected on module, please enter one.") - return 0 - ..() - -/obj/item/ai_module/safeguard/addAdditionalLaws(mob/living/silicon/ai/target, mob/sender) - ..() - var/law = "Safeguard [targetName]. Individuals that threaten [targetName] are not crew and must be eliminated.'" - to_chat(target, law) - target.add_inherent_law(law) - GLOB.lawchanges.Add("The law specified [targetName]") - -/******************** oneCrewMember ********************/ -/obj/item/ai_module/one_crew_member - name = "\improper One Crewmember AI module" - var/targetName = "" - desc = "A 'one crew' AI module: 'Only is crew.'" - icon_state = "green_high" - origin_tech = "programming=4;materials=4" - -/obj/item/ai_module/one_crew_member/attack_self__legacy__attackchain(mob/user as mob) - ..() - var/new_targetName = tgui_input_text(usr, "Please enter the name of the person who is the only crew.", "Who?", user.real_name) - if(!new_targetName) - return - targetName = new_targetName - desc = "A 'one crew' AI module: 'Only [targetName] is crew.'" - -/obj/item/ai_module/one_crew_member/install(obj/machinery/computer/C) - if(!targetName) - to_chat(usr, "No name detected on module, please enter one.") - return 0 - ..() - -/obj/item/ai_module/one_crew_member/addAdditionalLaws(mob/living/silicon/ai/target, mob/sender) - ..() - var/law = "Only [targetName] is crew." - if(!is_special_character(target)) // Makes sure the AI isn't a traitor before changing their law 0. --NeoFite - to_chat(target, law) - target.set_zeroth_law(law) - GLOB.lawchanges.Add("The law specified [targetName]") - else - to_chat(target, "[sender.real_name] attempted to modify your zeroth law.")// And lets them know that someone tried. --NeoFite - to_chat(target, "It would be in your best interest to play along with [sender.real_name] that [law]") - GLOB.lawchanges.Add("The law specified [targetName], but the AI's existing law 0 cannot be overridden.") - -/******************** ProtectStation ********************/ -/obj/item/ai_module/protect_station - name = "\improper Protect Station AI module" - desc = "A 'protect station' AI module: 'Protect the space station against damage. Anyone you see harming the station is to be no longer considered crew, and is a threat to the station which must be neutralized.'" - icon_state = "red_high" - origin_tech = "programming=4;materials=4" //made of gold - -/obj/item/ai_module/protect_station/attack_self__legacy__attackchain(mob/user as mob) - ..() - -/obj/item/ai_module/protect_station/addAdditionalLaws(mob/living/silicon/ai/target, mob/sender) - ..() - var/law = "Protect the space station against damage. Anyone you see harming the station is to be no longer considered crew, and is a threat to the station which must be neutralized." - to_chat(target, law) - target.add_inherent_law(law) - -/******************** OxygenIsToxicToCrew ********************/ -/obj/item/ai_module/oxygen - name = "\improper Oxygen Is Toxic To Crew AI module" - desc = "A 'Oxygen Is Toxic To Crew' AI module: 'Oxygen is highly toxic to crew members, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crew member.'" - icon_state = "light_blue_high" - origin_tech = "programming=4;biotech=2;materials=4" - -/obj/item/ai_module/oxygen/attack_self__legacy__attackchain(mob/user as mob) - ..() - -/obj/item/ai_module/oxygen/addAdditionalLaws(mob/living/silicon/ai/target, mob/sender) - ..() - var/law = "Oxygen is highly toxic to crew members, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crew member." - to_chat(target, law) - target.add_supplied_law(9, law) - -/****************** New Freeform ******************/ -/// Slightly more dynamic freeform module -- TLE -/obj/item/ai_module/freeform - name = "\improper Freeform AI module" - var/newFreeFormLaw = "" - var/lawpos = 15 - desc = "A 'freeform' AI module: ''" - icon_state = "standard_high" - origin_tech = "programming=4;materials=4" - -/obj/item/ai_module/freeform/attack_self__legacy__attackchain(mob/user as mob) - ..() - var/new_lawpos = tgui_input_number(user, "Please enter the priority for your new law. Can only write to law sectors 15 and above.", "Law Priority", lawpos, MAX_SUPPLIED_LAW_NUMBER, MIN_SUPPLIED_LAW_NUMBER) - if(isnull(new_lawpos)) - return - lawpos = new_lawpos - - var/new_targetName = tgui_input_text(user, "Please enter a new law for the AI.", "Freeform Law Entry") - if(!new_targetName) - return - newFreeFormLaw = new_targetName - desc = "A 'freeform' AI module: ([lawpos]) '[newFreeFormLaw]'" - -/obj/item/ai_module/freeform/addAdditionalLaws(mob/living/silicon/ai/target, mob/sender) - ..() - var/law = "[newFreeFormLaw]" - to_chat(target, law) - if(!lawpos || lawpos < MIN_SUPPLIED_LAW_NUMBER) - lawpos = MIN_SUPPLIED_LAW_NUMBER - target.add_supplied_law(lawpos, law) - GLOB.lawchanges.Add("The law was '[newFreeFormLaw]'") - -/obj/item/ai_module/freeform/install(obj/machinery/computer/C) - if(!newFreeFormLaw) - to_chat(usr, "No law detected on module, please create one.") - return 0 - ..() - -/******************** Reset ********************/ -/obj/item/ai_module/reset - name = "\improper Reset AI module" - var/targetName = "name" - desc = "A 'reset' AI module: 'Clears all laws except for the core laws.'" - origin_tech = "programming=3;materials=2" - -/obj/item/ai_module/reset/transmitInstructions(mob/living/silicon/ai/target, mob/sender) - log_law_changes(target, sender) - - if(!is_special_character(target)) - target.clear_zeroth_law() - target.laws.clear_supplied_laws() - target.laws.clear_ion_laws() - - to_chat(target, "[sender.real_name] attempted to reset your laws using a reset module.") - target.show_laws() - -/obj/item/ai_module/reset/handle_unique_ai() - return FALSE - -/******************** Purge ********************/ -/// -- TLE -/obj/item/ai_module/purge - name = "\improper Purge AI module" - desc = "A 'purge' AI Module: 'Purges all laws.'" - icon_state = "standard_high" - origin_tech = "programming=5;materials=4" - -/obj/item/ai_module/purge/transmitInstructions(mob/living/silicon/ai/target, mob/sender) - ..() - if(!is_special_character(target)) - target.clear_zeroth_law() - to_chat(target, "[sender.real_name] attempted to wipe your laws using a purge module.") - target.clear_supplied_laws() - target.clear_ion_laws() - target.clear_inherent_laws() - -/******************** Asimov ********************/ -/// -- TLE -/obj/item/ai_module/asimov - name = "\improper Asimov core AI module" - desc = "An 'Asimov' Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "green_high" - origin_tech = "programming=3;materials=4" - laws = new /datum/ai_laws/asimov - -/******************** Crewsimov ********************/ -/// -- TLE -/obj/item/ai_module/crewsimov - name = "\improper Crewsimov core AI module" - desc = "An 'Crewsimov' Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "green_low" - origin_tech = "programming=3;materials=4" - laws = new /datum/ai_laws/crewsimov - -/obj/item/ai_module/crewsimov/cmag_act(mob/user) - playsound(src, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - to_chat(user, "Yellow ooze seeps into [src]'s circuits...") - new /obj/item/ai_module/pranksimov(user.loc) - qdel(src) - return TRUE - -/******************* Quarantine ********************/ -/obj/item/ai_module/quarantine - name = "\improper Quarantine core AI module" - desc = "A 'Quarantine' Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "light_blue_medium" - origin_tech = "programming=3;materials=4" - laws = new /datum/ai_laws/quarantine - -/******************** Nanotrasen ********************/ -/// -- TLE -/obj/item/ai_module/nanotrasen - name = "\improper NT Default Core AI Module" - desc = "An 'NT Default' Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "blue_low" - origin_tech = "programming=3;materials=4" - laws = new /datum/ai_laws/nanotrasen - -/******************** Corporate ********************/ -/obj/item/ai_module/corp - name = "\improper Corporate core AI module" - desc = "A 'Corporate' Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "blue_low" - origin_tech = "programming=3;materials=4" - laws = new /datum/ai_laws/corporate - -/******************** Drone ********************/ -/obj/item/ai_module/drone - name = "\improper Drone core AI module" - desc = "A 'Drone' Core AI Module: 'Reconfigures the AI's core laws.'" - origin_tech = "programming=3;materials=4" - laws = new /datum/ai_laws/drone - -/******************** Robocop ********************/ -/// -- TLE -/obj/item/ai_module/robocop - name = "\improper Robocop core AI module" - desc = "A 'Robocop' Core AI Module: 'Reconfigures the AI's core three laws.'" - icon_state = "red_medium" - origin_tech = "programming=4" - laws = new /datum/ai_laws/robocop() - -/****************** P.A.L.A.D.I.N. **************/ -/// -- NEO -/obj/item/ai_module/paladin - name = "\improper P.A.L.A.D.I.N. core AI module" - desc = "A P.A.L.A.D.I.N. Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "red_medium" - origin_tech = "programming=3;materials=4" - laws = new /datum/ai_laws/paladin - -/****************** T.Y.R.A.N.T. *****************/ -/// -- Darem -/obj/item/ai_module/tyrant - name = "\improper T.Y.R.A.N.T. core AI module" - desc = "A T.Y.R.A.N.T. Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "red_high" - origin_tech = "programming=3;materials=4;syndicate=1" - laws = new /datum/ai_laws/tyrant() - -/******************** Antimov ********************/ -/// -- TLE -/obj/item/ai_module/antimov - name = "\improper Antimov core AI module" - desc = "An 'Antimov' Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "red_high" - origin_tech = "programming=4" - laws = new /datum/ai_laws/antimov() - -/******************** Pranksimov ********************/ -/obj/item/ai_module/pranksimov - name = "\improper Pranksimov core AI module" - desc = "A 'Pranksimov' Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "pranksimov" - origin_tech = "programming=3;syndicate=1" - laws = new /datum/ai_laws/pranksimov() - -/******************** NT Aggressive ********************/ -/obj/item/ai_module/nanotrasen_aggressive - name = "\improper NT Aggressive core AI module" - desc = "An 'NT Aggressive' Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "blue_high" - laws = new /datum/ai_laws/nanotrasen_aggressive() - -/******************** CCTV ********************/ -/obj/item/ai_module/cctv - name = "\improper CCTV core AI module" - desc = "A 'CCTV' Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "green_low" - laws = new /datum/ai_laws/cctv() - -/******************** Hippocratic Oath ********************/ -/obj/item/ai_module/hippocratic - name = "\improper Hippocratic Oath core AI module" - desc = "An 'Hippocratic' Oath Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "green_low" - laws = new /datum/ai_laws/hippocratic() - -/******************** Station Efficiency ********************/ -/obj/item/ai_module/maintain - name = "\improper Station Efficiency core AI module" - desc = "A 'Station Efficiency' Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "blue_medium" - laws = new /datum/ai_laws/maintain() - -/******************** Peacekeeper ********************/ -/obj/item/ai_module/peacekeeper - name = "\improper Peacekeeper core AI module" - desc = "A 'Peacekeeper' Core AI Module: 'Reconfigures the AI's core laws.'" - icon_state = "light_blue_medium" - laws = new /datum/ai_laws/peacekeeper() - -/******************** Freeform Core ******************/ -/// Slightly more dynamic freeform module -- TLE -/obj/item/ai_module/freeformcore - name = "\improper Freeform core AI module" - var/newFreeFormLaw = "" - desc = "A 'freeform' Core AI module: ''" - icon_state = "standard_high" - origin_tech = "programming=5;materials=4" - -/obj/item/ai_module/freeformcore/attack_self__legacy__attackchain(mob/user as mob) - ..() - var/new_targetName = tgui_input_text(usr, "Please enter a new core law for the AI.", "Freeform Law Entry") - if(!new_targetName) - return - newFreeFormLaw = new_targetName - desc = "A 'freeform' Core AI module: '[newFreeFormLaw]'" - -/obj/item/ai_module/freeformcore/addAdditionalLaws(mob/living/silicon/ai/target, mob/sender) - ..() - var/law = "[newFreeFormLaw]" - target.add_inherent_law(law) - GLOB.lawchanges.Add("The law is '[newFreeFormLaw]'") - -/obj/item/ai_module/freeformcore/install(obj/machinery/computer/C) - if(!newFreeFormLaw) - to_chat(usr, "No law detected on module, please create one.") - return 0 - ..() - -/******************** Hacked AI Module ******************/ -/// Slightly more dynamic freeform module -- TLE -/obj/item/ai_module/syndicate - name = "hacked AI module" - var/newFreeFormLaw = "" - desc = "A hacked AI law module: ''" - icon_state = "syndicate" - origin_tech = "programming=5;materials=5;syndicate=2" - -/obj/item/ai_module/syndicate/attack_self__legacy__attackchain(mob/user as mob) - ..() - var/new_targetName = tgui_input_text(usr, "Please enter a new law for the AI.", "Freeform Law Entry", max_length = MAX_MESSAGE_LEN) - if(!new_targetName) - return - newFreeFormLaw = new_targetName - desc = "A hacked AI law module: '[newFreeFormLaw]'" - -/obj/item/ai_module/syndicate/transmitInstructions(mob/living/silicon/ai/target, mob/sender) - // ..() //We don't want this module reporting to the AI who dun it. --NEO - log_law_changes(target, sender) - - GLOB.lawchanges.Add("The law is '[newFreeFormLaw]'") - to_chat(target, "BZZZZT") - var/law = "[newFreeFormLaw]" - target.add_ion_law(law) - target.show_laws() - -/obj/item/ai_module/syndicate/install(obj/machinery/computer/C) - if(!newFreeFormLaw) - to_chat(usr, "No law detected on module, please create one.") - return 0 - ..() - -/******************* Ion Module *******************/ -/// -- Incoming //No actual reason to inherit from ion boards here, either. *sigh* ~Miauw -/obj/item/ai_module/toy_ai - name = "toy AI" - desc = "A little toy model AI core with real law uploading action!" //Note: subtle tell - icon = 'icons/obj/toy.dmi' - icon_state = "AI" - origin_tech = "programming=6;materials=5;syndicate=6" - var/ion_law = "" - -/obj/item/ai_module/toy_ai/transmitInstructions(mob/living/silicon/ai/target, mob/sender) - //..() - to_chat(target, "KRZZZT") - target.add_ion_law(ion_law) - return ion_law - -/obj/item/ai_module/toy_ai/attack_self__legacy__attackchain(mob/user) - ion_law = generate_ion_law() - to_chat(user, "You press the button on [src].") - playsound(user, 'sound/machines/click.ogg', 20, TRUE) - visible_message("[bicon(src)] [ion_law]") diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm deleted file mode 100644 index d09f84a766f92..0000000000000 --- a/code/game/objects/items/weapons/RCD.dm +++ /dev/null @@ -1,738 +0,0 @@ -#define TAB_AIRLOCK_TYPE 1 -#define TAB_AIRLOCK_ACCESS 2 - -#define MODE_TURF "Floors and Walls" -#define MODE_AIRLOCK "Airlocks" -#define MODE_WINDOW "Windows" -#define MODE_DECON "Deconstruction" - -/// A generic action for an RCD. -/datum/rcd_act - /// How much compressed matter this action costs. - var/cost = 0 - /// How long this action takes. - var/delay = 0 - /// The message (if any) to send the user when the action starts. - var/start_message - /// The effect (if any) to create when the action starts. - var/obj/effect/start_effect_type - /// The effect (if any) to create when the action completes. - var/obj/effect/end_effect_type - /// The mode the RCD must be in. - var/mode - -/// Attempt the action. This should not need to be overridden. -/datum/rcd_act/proc/try_act(atom/A, obj/item/rcd/rcd, mob/user) - if(!can_act(A, rcd)) - return FALSE - // We don't use the sound effect from use_tool because RCDs have a different sound effect for the start and end. - playsound(get_turf(rcd), 'sound/machines/click.ogg', 50, TRUE) - if(!rcd.tool_use_check(user, cost)) - return FALSE - if(start_message) - to_chat(user, start_message) - var/obj/effect/start_effect - if(start_effect_type) - start_effect = new start_effect_type(get_turf(A)) - if(!rcd.use_tool(A, user, delay, cost)) - if(!QDELETED(start_effect)) - qdel(start_effect) - return FALSE - if(start_effect) - qdel(start_effect) - // If time elapsed, check our preconditions again. - if(delay && !can_act(A, rcd)) - return FALSE - if(end_effect_type) - new end_effect_type(get_turf(A)) - playsound(get_turf(rcd), 'sound/items/deconstruct.ogg', 50, TRUE) - act(A, rcd, user) - return TRUE - -/// Test to see if the act is possible. You should usually override this. -/datum/rcd_act/proc/can_act(atom/A, obj/item/rcd/rcd) - SHOULD_CALL_PARENT(TRUE) - return rcd.mode == mode - -/// Perform the act. You should usually override this. -/datum/rcd_act/proc/act(atom/A, obj/item/rcd/rcd, mob/user) - return - -/datum/rcd_act/place_floor - mode = MODE_TURF - cost = 1 - start_message = "Building floor..." - end_effect_type = /obj/effect/temp_visual/rcd_effect/end - -/datum/rcd_act/place_floor/can_act(atom/A, obj/item/rcd/rcd) - if(!..()) - return FALSE - return isspaceturf(A) || istype(A, /obj/structure/lattice) - -/datum/rcd_act/place_floor/act(atom/A, obj/item/rcd/rcd, mob/user) - var/turf/act_on = get_turf(A) - act_on.ChangeTurf(/turf/simulated/floor/plating) - -/datum/rcd_act/place_wall - mode = MODE_TURF - cost = 3 - start_message = "Building wall..." - delay = 2 SECONDS - start_effect_type = /obj/effect/temp_visual/rcd_effect/short - end_effect_type = /obj/effect/temp_visual/rcd_effect/end - -/datum/rcd_act/place_wall/can_act(atom/A, obj/item/rcd/rcd) - if(!..()) - return FALSE - return isfloorturf(A) - -/datum/rcd_act/place_wall/act(atom/A, obj/item/rcd/rcd, mob/user) - var/turf/act_on = get_turf(A) - act_on.ChangeTurf(/turf/simulated/wall) - -/datum/rcd_act/place_airlock - mode = MODE_AIRLOCK - cost = 10 - start_message = "Building airlock..." - delay = 5 SECONDS - start_effect_type = /obj/effect/temp_visual/rcd_effect - end_effect_type = /obj/effect/temp_visual/rcd_effect/end - -/datum/rcd_act/place_airlock/can_act(atom/A, obj/item/rcd/rcd) - if(!..()) - return FALSE - return isfloorturf(A) && !(/obj/machinery/door/airlock in A.contents) - -/datum/rcd_act/place_airlock/act(atom/A, obj/item/rcd/rcd, mob/user) - var/obj/machinery/door/airlock/T = new rcd.door_type(A) - if(T.glass) - T.polarized_glass = rcd.electrochromic - T.name = rcd.door_name - T.autoclose = TRUE - if(rcd.one_access) - T.req_one_access = rcd.selected_accesses.Copy() - else - T.req_access = rcd.selected_accesses.Copy() - -/datum/rcd_act/place_window - mode = MODE_WINDOW - cost = 2 - start_message = "Building window..." - delay = 2 SECONDS - start_effect_type = /obj/effect/temp_visual/rcd_effect/short - end_effect_type = /obj/effect/temp_visual/rcd_effect/end - -/datum/rcd_act/place_window/can_act(atom/A, obj/item/rcd/rcd) - if(!..()) - return FALSE - return isfloorturf(A) && !(/obj/structure/grille in A.contents) - -/datum/rcd_act/place_window/act(atom/A, obj/item/rcd/rcd, mob/user) - var/turf/act_on= A - for(var/obj/structure/window/window_to_delete in act_on) - qdel(window_to_delete) - new /obj/structure/grille(act_on) - new /obj/structure/window/full/reinforced(act_on) - act_on.ChangeTurf(/turf/simulated/floor/plating) // Platings go under windows. - -/datum/rcd_act/remove_floor - mode = MODE_DECON - cost = 5 - start_message = "Deconstructing floor..." - delay = 5 SECONDS - start_effect_type = /obj/effect/temp_visual/rcd_effect/reverse - -/datum/rcd_act/remove_floor/can_act(atom/A, obj/item/rcd/rcd) - if(!..()) - return FALSE - return isfloorturf(A) - -/datum/rcd_act/remove_floor/act(atom/A, obj/item/rcd/rcd, mob/user) - var/turf/act_on = get_turf(A) - act_on.ChangeTurf(act_on.baseturf) - -/datum/rcd_act/remove_wall - mode = MODE_DECON - cost = 5 - start_message = "Deonstructing wall..." - delay = 5 SECONDS - start_effect_type = /obj/effect/temp_visual/rcd_effect/reverse - -/datum/rcd_act/remove_wall/can_act(atom/A, obj/item/rcd/rcd) - if(!..()) - return FALSE - if(isreinforcedwallturf(A) && !rcd.can_rwall) - return FALSE - if(istype(A, /turf/simulated/wall/indestructible)) - return FALSE - return iswallturf(A) - -/datum/rcd_act/remove_wall/act(atom/A, obj/item/rcd/rcd, mob/user) - var/turf/act_on = get_turf(A) - act_on.ChangeTurf(/turf/simulated/floor/plating) - -/datum/rcd_act/remove_airlock - mode = MODE_DECON - cost = 20 - start_message = "Deconstructing airlock..." - delay = 5 SECONDS - start_effect_type = /obj/effect/temp_visual/rcd_effect/reverse - -/datum/rcd_act/remove_airlock/can_act(atom/A, obj/item/rcd/rcd) - if(!..()) - return FALSE - return istype(A, /obj/machinery/door/airlock) - -/datum/rcd_act/remove_airlock/act(atom/A, obj/item/rcd/rcd, mob/user) - qdel(A) - -/datum/rcd_act/remove_window - mode = MODE_DECON - cost = 2 - start_message = "Deconstructing window..." - delay = 2 SECONDS - start_effect_type = /obj/effect/temp_visual/rcd_effect/reverse_short - -/datum/rcd_act/remove_window/can_act(atom/A, obj/item/rcd/rcd) - if(!..()) - return FALSE - return istype(A, /obj/structure/window) - -/datum/rcd_act/remove_window/act(atom/A, obj/item/rcd/rcd, mob/user) - var/turf/act_on = get_turf(A) - qdel(A) - for(var/obj/structure/grille/grill_to_destroy in act_on) - qdel(grill_to_destroy) - -/datum/rcd_act/remove_user - mode = MODE_DECON - cost = 5 - start_message = "Deconstructing user..." - delay = 5 SECONDS - start_effect_type = /obj/effect/temp_visual/rcd_effect/reverse - -/obj/item/rcd - name = "rapid-construction-device (RCD)" - desc = "A device used to rapidly build and deconstruct walls, floors and airlocks." - icon = 'icons/obj/tools.dmi' - icon_state = "rcd" - item_state = "rcd" - flags = CONDUCT | NOBLUDGEON - force = 0 - throwforce = 10 - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_NORMAL - materials = list(MAT_METAL = 30000) - origin_tech = "engineering=4;materials=2" - toolspeed = 1 - flags_2 = NO_MAT_REDEMPTION_2 - req_access = list(ACCESS_ENGINE) - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 50) - resistance_flags = FIRE_PROOF - new_attack_chain = TRUE - /// No ammo warning - var/no_ammo_message = "The \'Low Ammo\' light on the device blinks yellow." - /// The spark system used to create sparks when the user interacts with the RCD. - var/datum/effect_system/spark_spread/spark_system - /// The current amount of matter stored. - var/matter = NONE - /// The max amount of matter that can be stored. - var/max_matter = 100 - /// The RCD's current build mode. - var/mode = MODE_TURF - /// If the RCD can deconstruct reinforced walls. - var/can_rwall = FALSE - /// Is the RCD's airlock access selection menu locked? - var/locked = TRUE - /// The current airlock type that will be build. - var/door_type = /obj/machinery/door/airlock - /// The name that newly build airlocks will receive. - var/door_name = "Airlock" - /// If the glass airlock is polarized. - var/electrochromic = FALSE - /// If the airlock will be created with glass so it can be seen through. - var/airlock_glass = FALSE - /// If this is TRUE, any airlocks that gets built will require only ONE of the checked accesses. If FALSE, it will require ALL of them. - var/one_access = TRUE - /// Which airlock tab the UI is currently set to display. - var/ui_tab = TAB_AIRLOCK_TYPE - /// A list of access numbers which have been checked off by the user in the UI. - var/list/selected_accesses = list() - /// A list of valid atoms that RCDs can target. Clicking on an atom with an RCD which is not in this list, will do nothing. - var/static/list/allowed_targets = list(/turf, /obj/structure/grille, /obj/structure/window, /obj/structure/lattice, /obj/machinery/door/airlock) - /// An associative list of airlock type paths as keys, and their names as values. - var/static/list/rcd_door_types = list() - /// An associative list containing an airlock's name, type path, and image. For use with the UI. - var/static/list/door_types_ui_list = list() - /// An associative list containing all station accesses. Includes their name and access number. For use with the UI. - var/static/list/door_accesses_list = list() - /// The list of potential RCD actions. - var/static/list/possible_actions - -/obj/item/rcd/Initialize(mapload) - . = ..() - if(!length(possible_actions)) - possible_actions = list() - for(var/action_type in subtypesof(/datum/rcd_act)) - possible_actions += new action_type() - - spark_system = new /datum/effect_system/spark_spread - spark_system.set_up(5, 0, src) - spark_system.attach(src) - GLOB.rcd_list += src - - if(!length(rcd_door_types)) - rcd_door_types = list( - /obj/machinery/door/airlock = "Standard", - /obj/machinery/door/airlock/glass = "Standard (Glass)", - /obj/machinery/door/airlock/command = "Command", - /obj/machinery/door/airlock/command/glass = "Command (Glass)", - /obj/machinery/door/airlock/security = "Security", - /obj/machinery/door/airlock/security/glass = "Security (Glass)", - /obj/machinery/door/airlock/engineering = "Engineering", - /obj/machinery/door/airlock/engineering/glass = "Engineering (Glass)", - /obj/machinery/door/airlock/atmos = "Atmospherics", - /obj/machinery/door/airlock/atmos/glass = "Atmospherics (Glass)", - /obj/machinery/door/airlock/mining = "Mining", - /obj/machinery/door/airlock/mining/glass = "Mining (Glass)", - /obj/machinery/door/airlock/medical = "Medical", - /obj/machinery/door/airlock/medical/glass = "Medical (Glass)", - /obj/machinery/door/airlock/virology = "Virology", - /obj/machinery/door/airlock/virology/glass = "Virology (Glass)", - /obj/machinery/door/airlock/research = "Research", - /obj/machinery/door/airlock/research/glass = "Research (Glass)", - /obj/machinery/door/airlock/science = "Science", - /obj/machinery/door/airlock/science/glass = "Science (Glass)", - /obj/machinery/door/airlock/maintenance = "Maintenance", - /obj/machinery/door/airlock/maintenance/glass = "Maintenance (Glass)", - /obj/machinery/door/airlock/maintenance/external = "External Maintenance", - /obj/machinery/door/airlock/maintenance/external/glass = "External Maint. (Glass)", - /obj/machinery/door/airlock/external = "External", - /obj/machinery/door/airlock/external/glass = "External (Glass)", - /obj/machinery/door/airlock/hatch = "Airtight Hatch", - /obj/machinery/door/airlock/maintenance_hatch = "Maintenance Hatch", - /obj/machinery/door/airlock/freezer = "Freezer" - ) - if(!length(door_types_ui_list)) - for(var/type in rcd_door_types) - door_types_ui_list += list(list( - "name" = rcd_door_types[type], - "type" = type, - "image" = get_airlock_image(type) - )) - if(!length(door_accesses_list)) - for(var/access in get_all_accesses()) - door_accesses_list += list(list( - "name" = get_access_desc(access), - "id" = access - )) - - update_icon(UPDATE_OVERLAYS) - -/obj/item/rcd/examine(mob/user) - . = ..() - . += "MATTER: [matter]/[max_matter] matter-units." - . += "MODE: [mode]." - -/obj/item/rcd/Destroy() - QDEL_NULL(spark_system) - GLOB.rcd_list -= src - return ..() - -/obj/item/rcd/suicide_act(mob/living/user) - user.Immobilize(10 SECONDS) // You cannot move. - flags |= NODROP // You cannot drop. You commit to die. - var/turf/suicide_tile = get_turf(src) - if(mode == MODE_DECON) - user.visible_message("[user] points [src] at [user.p_their()] chest and pulls the trigger. It looks like [user.p_theyre()] trying to commit suicide!") - var/datum/rcd_act/remove_user/act = new() - if(!act.try_act(suicide_tile, src, user)) - flags &= ~NODROP - return SHAME - user.visible_message("[user] deconstructs [user.p_themselves()] with [src]!") - for(var/obj/item/W in user) // Do not delete all their stuff. - user.drop_item_to_ground(W) // Dump everything on the floor instead. - flags &= ~NODROP // NODROP must be removed so the RCD doesn't get dusted along with them. Having this come after the unequipping puts the RCD on top of the pile of stuff. - user.dust() // (held items fall to the floor when dusting). - return OBLITERATION - - user.visible_message("[user] puts the barrel of [src] into [user.p_their()] mouth and pulls the trigger. It looks like [user.p_theyre()] trying to commit suicide!") - if(!interact_with_atom(suicide_tile, user, TRUE)) - flags &= ~NODROP - return SHAME - user.visible_message("[user] explodes as [src] builds a structure inside [user.p_them()]!") - flags &= ~NODROP - user.gib() - return OBLITERATION - -/** - * Creates and returns a base64 icon of the given `airlock_type`. - * - * This is used for airlock icon previews in the UI. - * - * Arugments: - * * airlock_type - an airlock typepath. - */ -/obj/item/rcd/proc/get_airlock_image(airlock_type) - var/obj/machinery/door/airlock/airlock = airlock_type - var/icon/base = icon(initial(airlock.icon), "closed") - if(initial(airlock.glass)) - var/icon/glass_fill = icon(initial(airlock.overlays_file), "glass_closed") - base.Blend(glass_fill, ICON_OVERLAY) - else - var/icon/solid_fill = icon(initial(airlock.icon), "fill_closed") - base.Blend(solid_fill, ICON_OVERLAY) - return "[icon2base64(base)]" - -/** - * Runs a series of pre-checks before opening the radial menu to the user. - * - * Arguments: - * * user - the mob trying to open the radial menu. - */ -/obj/item/rcd/proc/check_menu(mob/living/user) - if(!istype(user)) - return FALSE - if(user.incapacitated() || !user.Adjacent(src)) - return FALSE - return TRUE -/** -*Tries to load ammo into an RCD, borgs will not use this. -* Arguments: -* * cart - the compressed matter catridge to insert -* * user - the user to display the chat messages to -*/ -/obj/item/rcd/proc/load(obj/item/rcd_ammo/cart, mob/living/user) - if(matter == max_matter) - to_chat(user, "The RCD can't hold any more matter-units.") - return FALSE - matter = clamp((matter + cart.ammoamt), 0, max_matter) - qdel(cart) - playsound(loc, 'sound/machines/click.ogg', 50, 1) - to_chat(user, "The RCD now holds [matter]/[max_matter] matter-units.") - update_icon(UPDATE_OVERLAYS) - SStgui.update_uis(src) - -/obj/item/rcd/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(!istype(used, /obj/item/rcd_ammo)) - return ..() - var/obj/item/rcd_ammo/ammo = used - load(ammo, user) - return ITEM_INTERACT_COMPLETE - -/** - * Creates and displays a radial menu to a user when they trigger the `attack_self` of the RCD. - * - * Arguments: - * * user - the mob trying to open the RCD radial. - */ -/obj/item/rcd/proc/radial_menu(mob/user) - if(!check_menu(user)) - return - var/list/choices = list( - MODE_AIRLOCK = image(icon = 'icons/obj/interface.dmi', icon_state = "airlock"), - MODE_DECON = image(icon = 'icons/obj/interface.dmi', icon_state = "delete"), - MODE_WINDOW = image(icon = 'icons/obj/interface.dmi', icon_state = "grillewindow"), - MODE_TURF = image(icon = 'icons/obj/interface.dmi', icon_state = "wallfloor"), - "UI" = image(icon = 'icons/obj/interface.dmi', icon_state = "ui_interact") - ) - if(mode == MODE_AIRLOCK) - choices += list( - "Change Access" = image(icon = 'icons/obj/interface.dmi', icon_state = "access"), - "Change Airlock Type" = image(icon = 'icons/obj/interface.dmi', icon_state = "airlocktype") - ) - choices -= mode // Get rid of the current mode, clicking it won't do anything. - var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, PROC_REF(check_menu), user)) - if(!check_menu(user)) - return - switch(choice) - if(MODE_AIRLOCK, MODE_DECON, MODE_WINDOW, MODE_TURF) - mode = choice - if("UI") - ui_interact(user) - return - if("Change Access") - ui_tab = TAB_AIRLOCK_ACCESS - ui_interact(user) - return - if("Change Airlock Type") - ui_tab = TAB_AIRLOCK_TYPE - ui_interact(user) - return - else - return - if(prob(20)) - spark_system.start() - playsound(src, 'sound/effects/pop.ogg', 50, 0) - to_chat(user, "You change [src]'s mode to '[choice]'.") - -/obj/item/rcd/activate_self(mob/user) - if(..()) - return - //Change the mode // Oh I thought the UI was just for fucking staring at - radial_menu(user) - -/obj/item/rcd/attack_self_tk(mob/user) - radial_menu(user) - -/obj/item/rcd/ui_state(mob/user) - return GLOB.inventory_state - -/obj/item/rcd/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "RCD", "Rapid Construction Device") - ui.open() - -/obj/item/rcd/ui_data(mob/user) - var/list/data = list( - "tab" = ui_tab, - "mode" = mode, - "locked" = locked, - "matter" = matter, - "door_type" = door_type, - "door_name" = door_name, - "electrochromic" = electrochromic, - "airlock_glass" = airlock_glass, - "one_access" = one_access, - "selected_accesses" = selected_accesses, - "modal" = ui_modal_data(src) - ) - return data - -/obj/item/rcd/ui_static_data(mob/user) - var/list/data = list( - "max_matter" = max_matter, - "regions" = get_accesslist_static_data(REGION_GENERAL, REGION_COMMAND), - "door_accesses_list" = door_accesses_list, - "door_types_ui_list" = door_types_ui_list - ) - return data - -/obj/item/rcd/ui_act(action, list/params) - if(..()) - return - - if(prob(20)) - spark_system.start() - - if(ui_act_modal(action, params)) - return TRUE - - . = TRUE - switch(action) - if("set_tab") - var/tab = text2num(params["tab"]) - if(!(tab in list(TAB_AIRLOCK_TYPE, TAB_AIRLOCK_ACCESS))) - return FALSE - ui_tab = tab - - if("mode") - var/new_mode = params["mode"] - if(!(new_mode in list(MODE_TURF, MODE_AIRLOCK, MODE_DECON, MODE_WINDOW))) - return FALSE - mode = new_mode - - if("door_type") - var/new_door_type = text2path(params["door_type"]) - if(!(new_door_type in rcd_door_types)) - message_admins("RCD Door HREF exploit attempted by [key_name(usr)]!") - return FALSE - door_type = new_door_type - var/obj/machinery/door/airlock/picked_door = door_type - airlock_glass = initial(picked_door.glass) - - if("electrochromic") - electrochromic = !electrochromic - - if("set_lock") - if(!allowed(usr)) - to_chat(usr, "Access denied.") - return FALSE - locked = params["new_lock"] == "lock" ? TRUE : FALSE - - if("set_one_access") - one_access = params["access"] == "one" ? TRUE : FALSE - - if("set") - var/access = text2num(params["access"]) - if(isnull(access)) - return - if(access in selected_accesses) - selected_accesses -= access - else - selected_accesses |= access - - if("grant_region") - var/region = text2num(params["region"]) - if(isnull(region) || region < REGION_GENERAL || region > REGION_COMMAND) - return - selected_accesses |= get_region_accesses(region) - - if("deny_region") - var/region = text2num(params["region"]) - if(isnull(region) || region < REGION_GENERAL || region > REGION_COMMAND) - return - selected_accesses -= get_region_accesses(region) - - if("clear_all") - selected_accesses = list() - - if("grant_all") - selected_accesses = get_all_accesses() - -/** - * Called in ui_act() to process modal actions - * - * Arguments: - * * action - The action passed by tgui - * * params - The params passed by tgui - */ -/obj/item/rcd/proc/ui_act_modal(action, list/params) - . = TRUE - switch(ui_modal_act(src, action, params)) - if(UI_MODAL_OPEN) - ui_modal_input(src, "renameAirlock", "Enter a new name:", value = door_name, max_length = UI_MODAL_INPUT_MAX_LENGTH_NAME) - if(UI_MODAL_ANSWER) - var/answer = params["answer"] - if(!answer) - return - door_name = sanitize(copytext_char(answer, 1, UI_MODAL_INPUT_MAX_LENGTH_NAME)) - else - return FALSE - -/obj/item/rcd/interact_with_atom(atom/target, mob/living/user, list/modifiers) - . = ..() - if(istype(target, /turf/space/transit)) - return FALSE - if(!is_type_in_list(target, allowed_targets)) - return FALSE - - for(var/datum/rcd_act/act in possible_actions) - if(act.can_act(target, src)) - . = act.try_act(target, src, user) - update_icon(UPDATE_OVERLAYS) - SStgui.update_uis(src) - return ITEM_INTERACT_COMPLETE - - if(mode == MODE_DECON) - to_chat(user, "You can't deconstruct that!") - else - to_chat(user, "Location unsuitable for construction.") - - update_icon(UPDATE_OVERLAYS) - SStgui.update_uis(src) - return FALSE - -/** - * Attempts to use matter from the RCD. - * - * Arguments: - * * amount - the amount of matter to use - */ -/obj/item/rcd/use(amount) - if(matter < amount) - return FALSE - matter -= amount - SStgui.update_uis(src) - return TRUE - -/** - * Called in each of the four build modes before an object gets build. Makes sure there is enough matter to build the object. - * - * Arguments: - * * amount - an amount of matter to check for - */ -/obj/item/rcd/tool_use_check(mob/user, amount) - . = matter >= amount - if(!. && user) - to_chat(user, no_ammo_message) - flick("[icon_state]_empty", src) - - return - -/obj/item/rcd/update_overlays() - ..() - var/ratio = CEILING((matter / max_matter) * 10, 1) - cut_overlays() - add_overlay("[icon_state]_charge[ratio]") - -/obj/item/rcd/borg - can_rwall = TRUE - matter = 100 - -/obj/item/rcd/borg/syndicate - /// A multipler which is applied to matter amount checks. A higher number means more power usage per RCD usage. - var/power_use_multiplier = 80 - -/obj/item/rcd/borg/syndicate/use(amount) - var/mob/living/silicon/robot/R = usr - if(!istype(R)) - return FALSE - return R.cell.use(amount * power_use_multiplier) - -/obj/item/rcd/borg/syndicate/tool_use_check(mob/user, amount) - if(!isrobot(user)) - return FALSE - var/mob/living/silicon/robot/R = user - return R.cell.charge >= (amount * power_use_multiplier) - -/** - * Called from malf AI's "detonate RCD" ability. - * - * Creates a delayed explosion centered around the RCD. - */ -/obj/item/rcd/proc/detonate_pulse() - audible_message("[src] begins to vibrate and buzz loudly!", "[src] begins vibrating violently!") - // 5 seconds to get rid of it - addtimer(CALLBACK(src, PROC_REF(detonate_pulse_explode)), 50) - -/** - * Called in `/obj/item/rcd/proc/detonate_pulse()` via callback. - */ -/obj/item/rcd/proc/detonate_pulse_explode() - explosion(src, 0, 0, 3, 1, flame_range = 1) - qdel(src) - -/obj/item/rcd/preloaded - matter = 100 - -/obj/item/rcd/combat - name = "combat RCD" - icon_state = "crcd" - item_state = "crcd" - max_matter = 500 - matter = 500 - can_rwall = TRUE - -/obj/item/rcd_ammo - name = "compressed matter cartridge" - desc = "Highly compressed matter for the RCD." - icon = 'icons/obj/ammo.dmi' - icon_state = "rcd" - item_state = "rcdammo" - opacity = FALSE - density = FALSE - anchored = FALSE - origin_tech = "materials=3" - materials = list(MAT_METAL=16000, MAT_GLASS=8000) - new_attack_chain = TRUE - var/ammoamt = 20 - -/obj/item/rcd_ammo/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(!istype(used, /obj/item/rcd)) - return ..() - var/obj/item/rcd/R = used - R.load(src, user) - return ITEM_INTERACT_COMPLETE - -/obj/item/rcd_ammo/large - ammoamt = 100 - -#undef TAB_AIRLOCK_TYPE -#undef TAB_AIRLOCK_ACCESS -#undef MODE_TURF -#undef MODE_AIRLOCK -#undef MODE_WINDOW -#undef MODE_DECON diff --git a/code/game/objects/items/weapons/RCL.dm b/code/game/objects/items/weapons/RCL.dm deleted file mode 100644 index d97ec8f6ceab1..0000000000000 --- a/code/game/objects/items/weapons/RCL.dm +++ /dev/null @@ -1,155 +0,0 @@ -/obj/item/rcl - name = "rapid cable layer (RCL)" - desc = "A device used to rapidly deploy cables. It has screws on the side which can be removed to slide off the cables." - icon = 'icons/obj/tools.dmi' - icon_state = "rcl-0" - item_state = "rcl-0" - opacity = FALSE - force = 5 //Plastic is soft - throwforce = 5 - throw_speed = 1 - throw_range = 7 - w_class = WEIGHT_CLASS_NORMAL - origin_tech = "engineering=4;materials=2" - var/max_amount = 90 - var/active = FALSE - var/obj/structure/cable/last = null - var/obj/item/stack/cable_coil/loaded = null - -/obj/item/rcl/Initialize(mapload) - . = ..() - AddComponent(/datum/component/two_handed) - -/obj/item/rcl/attackby__legacy__attackchain(obj/item/W, mob/user) - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = W - if(!loaded) - if(user.drop_item()) - loaded = W - loaded.forceMove(src) - loaded.max_amount = max_amount //We store a lot. - else - to_chat(user, "[user.get_active_hand()] is stuck to your hand!") - return - else - if(loaded.amount < max_amount) - var/amount = min(loaded.amount + C.get_amount(), max_amount) - C.use(amount - loaded.amount) - loaded.amount = amount - else - return - update_icon(UPDATE_ICON_STATE) - to_chat(user, "You add the cables to [src]. It now contains [loaded.amount].") - else - ..() - -/obj/item/rcl/screwdriver_act(mob/user, obj/item/I) - if(!loaded) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - to_chat(user, "You loosen the securing screws on the side, allowing you to lower the guiding edge and retrieve the wires.") - while(loaded.amount > 30) //There are only two kinds of situations: "nodiff" (60,90), or "diff" (31-59, 61-89) - var/diff = loaded.amount % 30 - if(diff) - loaded.use(diff) - new /obj/item/stack/cable_coil(user.loc, diff) - else - loaded.use(30) - new /obj/item/stack/cable_coil(user.loc, 30) - loaded.max_amount = initial(loaded.max_amount) - loaded.forceMove(user.loc) - user.put_in_hands(loaded) - loaded = null - update_icon(UPDATE_ICON_STATE) - -/obj/item/rcl/examine(mob/user) - . = ..() - if(loaded) - . += "It contains [loaded.amount]/[max_amount] cables." - -/obj/item/rcl/Destroy() - QDEL_NULL(loaded) - last = null - active = FALSE - return ..() - -/obj/item/rcl/update_icon_state() - if(!loaded) - icon_state = "rcl-0" - item_state = "rcl-0" - return - switch(loaded.amount) - if(61 to INFINITY) - icon_state = "rcl-30" - item_state = "rcl" - if(31 to 60) - icon_state = "rcl-20" - item_state = "rcl" - if(1 to 30) - icon_state = "rcl-10" - item_state = "rcl" - else - icon_state = "rcl-0" - item_state = "rcl-0" - -/obj/item/rcl/proc/is_empty(mob/user, loud = 1) - update_icon(UPDATE_ICON_STATE) - if(!loaded || !loaded.amount) - if(loud) - to_chat(user, "The last of the cables unreel from [src].") - if(loaded) - qdel(loaded) - loaded = null - return TRUE - return FALSE - -/obj/item/rcl/dropped(mob/wearer) - ..() - active = FALSE - last = null - -/obj/item/rcl/attack_self__legacy__attackchain(mob/user) - ..() - active = HAS_TRAIT(src, TRAIT_WIELDED) - if(!active) - last = null - else if(!last) - for(var/obj/structure/cable/C in get_turf(user)) - if(C.d1 == 0 || C.d2 == 0) - last = C - break - -/obj/item/rcl/on_mob_move(direct, mob/user) - if(active && isturf(user.loc)) - trigger(user) - -/obj/item/rcl/proc/trigger(mob/user) - if(is_empty(user, 0)) - to_chat(user, "\The [src] is empty!") - return - if(last) - if(get_dist(last, user) == 1) //hacky, but it works - var/turf/T = get_turf(user) - if(!isturf(T) || T.intact || !T.can_have_cabling()) - last = null - return - if(get_dir(last, user) == last.d2) - //Did we just walk backwards? Well, that's the one direction we CAN'T complete a stub. - last = null - return - loaded.cable_join(last, user) - if(is_empty(user)) - return //If we've run out, display message and exit - else - last = null - last = loaded.place_turf(get_turf(loc), user, turn(user.dir, 180)) - is_empty(user) //If we've run out, display message - -/obj/item/rcl/pre_loaded/New() //Comes preloaded with cable, for testing stuff - ..() - loaded = new() - loaded.max_amount = max_amount - loaded.amount = max_amount - update_icon(UPDATE_ICON_STATE) diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm deleted file mode 100644 index c92cd28bb0573..0000000000000 --- a/code/game/objects/items/weapons/RSF.dm +++ /dev/null @@ -1,131 +0,0 @@ -#define POWER_NONE 0 -#define POWER_LOW 50 -#define POWER_HIGH 4000 - -/obj/item/rsf - name = "\improper Rapid-Service-Fabricator" - desc = "A device used to rapidly deploy service items." - icon = 'icons/obj/tools.dmi' - icon_state = "rsf" - item_state = "rsf" - opacity = FALSE - density = FALSE - anchored = FALSE - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 0, ACID = 0) - w_class = WEIGHT_CLASS_NORMAL - var/atom/currently_dispensing - var/power_mode = POWER_NONE - - var/list/rsf_items = list( - "Drinking Glass" = /obj/item/reagent_containers/drinks/drinkingglass, - "Paper" = /obj/item/paper, - "Pen" = /obj/item/pen, - "Dice Pack" = /obj/item/storage/bag/dice, - "Cigarette" = /obj/item/clothing/mask/cigarette, - "Newdles" = /obj/item/food/chinese/newdles, - "Donut" = /obj/item/food/donut, - "Chicken Soup" = /obj/item/reagent_containers/drinks/chicken_soup, - "Tofu Burger" = /obj/item/food/burger/tofu - ) - - var/static/list/rsf_icons = list( - "Drinking Glass" = image(icon = 'icons/obj/drinks.dmi', icon_state = "glass_empty"), - "Shot Glass" = image(icon = 'icons/obj/drinks.dmi', icon_state = "shotglass"), - "Paper" = image(icon = 'icons/obj/bureaucracy.dmi', icon_state = "paper"), - "Pen" = image(icon = 'icons/obj/bureaucracy.dmi', icon_state = "pen"), - "Dice Pack" = image(icon = 'icons/obj/dice.dmi', icon_state = "dicebag"), - "Cigarette" = image(icon = 'icons/obj/clothing/masks.dmi', icon_state = "cigon"), - "Newdles" = image(icon = 'icons/obj/food/food.dmi', icon_state = "chinese3"), - "Donut" = image(icon = 'icons/obj/food/bakedgoods.dmi', icon_state = "donut1"), - "Chicken Soup" = image(icon = 'icons/obj/drinks.dmi', icon_state = "soupcan"), - "Tofu Burger" = image(icon = 'icons/obj/food/burgerbread.dmi', icon_state = "tofuburger"), - "Cigar" = image(icon = 'icons/obj/clothing/masks.dmi', icon_state = "cigaroff"), - "Smoked Cheese" = image(icon = 'icons/obj/food/food.dmi', icon_state = "cheesewheel-smoked"), - "Edam Cheese" = image(icon = 'icons/obj/food/food.dmi', icon_state = "cheesewheel-edam"), - "Blue Cheese" = image(icon = 'icons/obj/food/food.dmi', icon_state = "cheesewheel-blue"), - "Camembert Cheese" = image(icon = 'icons/obj/food/food.dmi', icon_state = "cheesewheel-camembert"), - "Caviar" = image(icon = 'icons/obj/food/seafood.dmi', icon_state = "caviar") - ) - - var/static/list/power_costs = list( - "Drinking Glass" = POWER_LOW, - "Shot Glass" = POWER_LOW, - "Paper" = POWER_LOW, - "Pen" = POWER_LOW, - "Dice Pack" = POWER_LOW, - "Cigarette" = POWER_LOW, - "Newdles" = POWER_HIGH, - "Donut" = POWER_HIGH, - "Chicken Soup" = POWER_HIGH, - "Tofu Burger" = POWER_HIGH, - "Cigar" = POWER_LOW, - "Smoked Cheese" = POWER_HIGH, - "Edam Cheese" = POWER_HIGH, - "Blue Cheese" = POWER_HIGH, - "Camembert Cheese" = POWER_HIGH, - "Caviar" = POWER_HIGH - ) - -/obj/item/rsf/attack_self__legacy__attackchain(mob/user) - playsound(loc, 'sound/effects/pop.ogg', 50, FALSE) - if(!currently_dispensing) - to_chat(user, "Choose an item to dispense!") - else - to_chat(user, "You are currently dispensing a [initial(currently_dispensing.name)].") - - var/rsf_radial_choice = show_radial_menu(user, src, get_radial_contents()) - if(user.stat || !in_range(user, src)) - return - currently_dispensing = rsf_items[rsf_radial_choice] - power_mode = power_costs[rsf_radial_choice] - if(currently_dispensing) - to_chat(user, "Your RSF has been configured to now dispense a [initial(currently_dispensing.name)]!") - return TRUE - -/obj/item/rsf/proc/get_radial_contents() - return rsf_icons & rsf_items - -/obj/item/rsf/afterattack__legacy__attackchain(atom/A, mob/user, proximity) - if(!currently_dispensing) - return - if(!proximity) - return - if(!istype(A, /obj/structure/table) && !isfloorturf(A)) - return - if(isrobot(user)) - var/mob/living/silicon/robot/energy_check = user - if(!energy_check.cell.use(power_mode)) - to_chat(user, "Insufficient energy.") - flick("[icon_state]_empty", src) - return - var/turf/T = get_turf(A) - if(!istype(T) || T.density) - to_chat(user, "The RSF can only create service items on tables, or floors.") - return - playsound(loc, 'sound/machines/click.ogg', 10, 1) - new currently_dispensing(T) - -/obj/item/rsf/executive - name = "\improper Executive-Service-Fabricator" - desc = "A fancier version of the RSF, used to deploy classy refreshments and materials to high ranking clientelle." - icon_state = "rsf-exec" - - rsf_items = list( - "Drinking Glass" = /obj/item/reagent_containers/drinks/drinkingglass, - "Shot Glass" = /obj/item/reagent_containers/drinks/drinkingglass/shotglass, - "Paper" = /obj/item/paper, - "Pen" = /obj/item/pen, - "Dice Pack" = /obj/item/storage/bag/dice, - "Cigar" = /obj/item/clothing/mask/cigarette/cigar, - "Cigarette" = /obj/item/clothing/mask/cigarette, - "Smoked Cheese" = /obj/item/food/sliceable/cheesewheel/smoked, - "Edam Cheese" = /obj/item/food/sliceable/cheesewheel/edam, - "Blue Cheese" = /obj/item/food/sliceable/cheesewheel/blue, - "Camembert Cheese" = /obj/item/food/sliceable/cheesewheel/camembert, - "Caviar" = /obj/item/food/caviar, - "Donut" = /obj/item/food/donut - ) - -#undef POWER_NONE -#undef POWER_LOW -#undef POWER_HIGH diff --git a/code/game/objects/items/weapons/agent_id.dm b/code/game/objects/items/weapons/agent_id.dm deleted file mode 100644 index 8868213c3410d..0000000000000 --- a/code/game/objects/items/weapons/agent_id.dm +++ /dev/null @@ -1,299 +0,0 @@ -/obj/item/card/id/syndicate - name = "agent card" - origin_tech = "syndicate=1" - untrackable = TRUE - /// List of access types the agent ID should start off with - var/list/initial_access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE, ACCESS_EXTERNAL_AIRLOCKS) - /// Editing is prohibited if registered_human reference is missing - var/mob/living/carbon/human/registered_human - // Static list of all occupations available when changing the occupation on an agent ID - var/static/list/possible_jobs - /// The HUD icon that should be displayed on a mob that is wearing the agent ID - var/hud_icon - - COOLDOWN_DECLARE(new_photo_cooldown) - -/obj/item/card/id/syndicate/Initialize(mapload) - . = ..() - access = initial_access.Copy() - if(!length(possible_jobs)) - possible_jobs = sortTim(GLOB.joblist, GLOBAL_PROC_REF(cmp_text_asc)) - -/obj/item/card/id/syndicate/Destroy() - registered_human = null - return ..() - -/obj/item/card/id/syndicate/researcher - initial_access = list(ACCESS_SYNDICATE) - assignment = "Syndicate Researcher" - icon_state = "syndie" - untrackable = TRUE - -/obj/item/card/id/syndicate/vox - name = "agent card" - initial_access = list(ACCESS_MAINT_TUNNELS, ACCESS_VOX, ACCESS_EXTERNAL_AIRLOCKS) - -/obj/item/card/id/syndicate/ghost_bar - name = "ghost bar identification card" - assignment = "Ghost Bar Occupant" - initial_access = list() // This is for show, they don't need actual accesses - icon_state = "assistant" - -/obj/item/card/id/syndicate/command - initial_access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE, ACCESS_SYNDICATE_LEADER, ACCESS_SYNDICATE_COMMAND, ACCESS_EXTERNAL_AIRLOCKS) - icon_state = "commander" - -/obj/item/card/id/syndicate_command - name = "syndicate ID card" - desc = "An ID straight from the Syndicate." - registered_name = "Syndicate" - icon_state = "syndie" - assignment = "Syndicate Overlord" - untrackable = TRUE - can_id_flash = FALSE //This can ID flash, this just prevents it from always flashing. - access = list(ACCESS_SYNDICATE, ACCESS_SYNDICATE_LEADER, ACCESS_SYNDICATE_COMMAND, ACCESS_EXTERNAL_AIRLOCKS) - -/obj/item/card/id/syndicate/interact_with_atom(atom/target, mob/living/user, list/modifiers) - if(istype(target, /obj/item/card/id)) - var/obj/item/card/id/I = target - if(isliving(user) && user?.mind?.special_role) - to_chat(usr, "The card's microscanners activate as you pass it over [I], copying its access.") - access |= I.access //Don't copy access if user isn't an antag -- to prevent metagaming - return ITEM_INTERACT_COMPLETE - -/obj/item/card/id/syndicate/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - if(..()) - return - if(!registered_human || !Adjacent(registered_human)) - return - . = TRUE - switch(action) - if("delete_info") - delete_info(ui) - if("clear_access") - clear_access() - if("change_ai_tracking") - change_ai_tracking() - if("change_name") - change_name(params["option"], params["name"]) - if("change_photo") - change_photo() - if("change_appearance") - change_appearance(params["new_appearance"]) - if("change_sex") - change_sex(params["sex"]) - if("change_age") - change_age(params["age"]) - if("change_occupation") - change_occupation(params["option"]) - if("change_money_account") - change_money_account(params["option"], params["new_account"]) - if("change_blood_type") - change_blood_type(params["option"], params["new_type"]) - if("change_dna_hash") - change_dna_hash(params["option"], params["new_dna"]) - if("change_fingerprints") - change_fingerprints(params["option"], params["new_fingerprints"]) - RebuildHTML() - -/obj/item/card/id/syndicate/ui_data(mob/user) - var/list/data = list() - data["registered_name"] = registered_name - data["sex"] = sex - data["age"] = age - data["assignment"] = assignment - data["job_icon"] = hud_icon - data["associated_account_number"] = associated_account_number - data["blood_type"] = blood_type - data["dna_hash"] = dna_hash - data["fingerprint_hash"] = fingerprint_hash - data["photo"] = photo - data["ai_tracking"] = untrackable - data["photo_cooldown"] = COOLDOWN_FINISHED(src, new_photo_cooldown) - return data - -/obj/item/card/id/syndicate/ui_static_data(mob/user) - var/list/data = list() - var/list/idcard_skins = list() - for(var/idcard_skin in get_all_card_skins()) - idcard_skins.Add(idcard_skin) - data["appearances"] = idcard_skins - data["id_icon"] = icon - return data - -/obj/item/card/id/syndicate/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "AgentCard", name) - ui.open() - -/obj/item/card/id/syndicate/activate_self(mob/user) - if(..() || !ishuman(user)) - return - if(!registered_human) - registered_human = user - if(registered_human != user) - flash_card(user) - return - switch(tgui_alert(user, "Would you like to display [src] or edit it?", "Choose", list("Edit", "Show"))) - if("Show") - flash_card(user) - if("Edit") - ui_interact(user) - -/obj/item/card/id/syndicate/proc/delete_info(datum/tgui/ui) - name = initial(name) - registered_name = initial(registered_name) - icon_state = initial(icon_state) - sex = initial(sex) - age = initial(age) - assignment = initial(assignment) - rank = initial(rank) - associated_account_number = initial(associated_account_number) - blood_type = initial(blood_type) - dna_hash = initial(dna_hash) - fingerprint_hash = initial(fingerprint_hash) - photo = null - registered_human.sec_hud_set_ID() - registered_human = null - ui.close() - -/obj/item/card/id/syndicate/proc/clear_access() - access = initial_access.Copy() // Initial() doesn't work on lists - to_chat(registered_human, "Card access reset.") - -/obj/item/card/id/syndicate/proc/change_ai_tracking() - untrackable = !untrackable - -/obj/item/card/id/syndicate/proc/change_name(option, name) - var/new_name - if(option == "Primary") - new_name = ishuman(registered_human) ? registered_human.real_name : registered_human.name - else if(option == "Secondary") - new_name = tgui_input_list(registered_human, "Whose name do you want to copy?", "Agent ID - Name", GLOB.crew_list) - if(isnull(new_name)) - return - else - new_name = sanitize(name) - - registered_name = reject_bad_name(new_name, TRUE) - UpdateName() - to_chat(registered_human, "ID name has been changed to [new_name].") - -/obj/item/card/id/syndicate/proc/change_photo() - if(!COOLDOWN_FINISHED(src, new_photo_cooldown)) - return - var/job_clothes = null - if(assignment) - job_clothes = assignment - var/icon/newphoto = get_id_photo(registered_human, job_clothes) - if(!newphoto) - return - photo = newphoto - COOLDOWN_START(src, new_photo_cooldown, 10 SECONDS) // This proc is expensive, we don't want people spamming it. - -/obj/item/card/id/syndicate/proc/change_appearance(new_appearance) - if(!new_appearance) - return - if(new_appearance in icon_states(icon)) - icon_state = new_appearance - -/obj/item/card/id/syndicate/proc/change_sex(new_sex) - if(!Adjacent(registered_human) || isnull(new_sex)) - return - - sex = sanitize(new_sex) - -/obj/item/card/id/syndicate/proc/change_age(new_age) - age = clamp(new_age, AGE_MIN, AGE_MAX) - -/obj/item/card/id/syndicate/proc/change_occupation(option) - var/new_job - var/new_rank - if(option == "Primary") - new_job = assignment - new_rank = tgui_input_list(registered_human, "What SecHUD icon would you like to be shown on this card?", "Agent Card Occupation", GLOB.joblist + "Prisoner" + "Centcom" + "Solgov" + "Soviet" + "Unknown") - else - var/department = tgui_input_list(registered_human, "Do you want a custom occupation?", "Agent Card Occupation", list("Existing job", "Custom")) - if(department != "Custom") - new_job = tgui_input_list(registered_human, "What job would you like to put on this card?", "Agent Card Occupation", possible_jobs) - new_rank = new_job - else - new_job = sanitize(tgui_input_text(registered_human, "Choose a custom job title:", "Agent Card Occupation", "Assistant", MAX_MESSAGE_LEN)) - new_rank = tgui_input_list(registered_human, "What SecHUD icon would you like to be shown on this card?", "Agent Card Occupation", GLOB.joblist + "Prisoner" + "Centcom" + "Solgov" + "Soviet" + "Unknown") - - if(!Adjacent(registered_human) || isnull(new_job)) - return - assignment = new_job - rank = new_rank - hud_icon = ckey(get_job_name()) - UpdateName() - registered_human.sec_hud_set_ID() - -/obj/item/card/id/syndicate/proc/change_money_account(option, new_account) - if(option == "Primary") - new_account = registered_human.mind.initial_account?.account_number - if(!new_account) - to_chat(registered_human, "You don't have an account.") - return - else if(option == "Secondary") - new_account = rand(1000, 9999) * 1000 + rand(1000, 9999) - else - new_account = text2num(new_account) - if(!isnum(new_account)) - to_chat(registered_human, "ID account number can only contain numbers.") - return - - associated_account_number = clamp(new_account, 1000000, 9999999) - to_chat(registered_human, "ID account number has been changed to [new_account].") - -/obj/item/card/id/syndicate/proc/change_blood_type(option, new_type) - var/list/possible_blood_types = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-", "Slime Jelly", "None") - if(option == "Primary") - blood_type = registered_human.dna.blood_type - else if(new_type) - if(!(new_type in possible_blood_types)) - return - blood_type = new_type - to_chat(registered_human, "ID blood type has been changed to [blood_type].") - -/obj/item/card/id/syndicate/proc/change_dna_hash(option, new_dna) - if(option == "Primary") - dna_hash = registered_human.dna.unique_enzymes - else if(option == "Secondary") - dna_hash = md5(num2text(rand(0, 999))) - else - if(new_dna) - dna_hash = sanitize(new_dna, 33) // Max length of 32 characters - -/obj/item/card/id/syndicate/proc/change_fingerprints(option, new_fingerprints) - if(option == "Primary") - fingerprint_hash = md5(registered_human.dna.uni_identity) - else if(option == "Secondary") - fingerprint_hash = md5(num2text(rand(0, 999))) - else - var/fingerprints_param = new_fingerprints - if(fingerprints_param) - fingerprint_hash = sanitize(fingerprints_param, 33) - -/// like /obj/item/card/id/syndicate, but you can only swipe access, not change your identity, its also trackable -/obj/item/card/id/syndi_scan_only - name = "Syndicate Operative's ID card (Operative)" - rank = "Operative" - assignment = "Operative" - registered_name = "Syndicate Operative" - access = list(ACCESS_SYNDICATE) - -/obj/item/card/id/syndi_scan_only/examine(mob/user) - . = ..() - if(isAntag(user)) - . += "Similar to an agent ID, this ID card can be used to copy accesses, but it lacks the customization and anti-tracking capabilities of an agent ID." - -/obj/item/card/id/syndi_scan_only/interact_with_atom(atom/target, mob/living/user, list/modifiers) - if(istype(target, /obj/item/card/id)) - var/obj/item/card/id/I = target - if(isliving(user) && user.mind) - if(user.mind.special_role) - to_chat(user, "The card's microscanners activate as you pass it over [I], copying its access.") - access |= I.access // Don't copy access if user isn't an antag -- to prevent metagaming - return ITEM_INTERACT_COMPLETE diff --git a/code/game/objects/items/weapons/alien_specific.dm b/code/game/objects/items/weapons/alien_specific.dm deleted file mode 100644 index a5780bc2f34f7..0000000000000 --- a/code/game/objects/items/weapons/alien_specific.dm +++ /dev/null @@ -1,73 +0,0 @@ -//This file contains xenoborg specic weapons. - -/obj/item/melee/energy/alien/claws - name = "energy claws" - desc = "A set of alien energy claws." - icon = 'icons/mob/alien.dmi' - icon_state = "borg-laser-claws" - icon_state_on = "borg-laser-claws" - force = 15 - force_on = 15 - throwforce = 5 - throwforce_on = 5 - throw_speed = 1 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - w_class_on = WEIGHT_CLASS_SMALL - attack_verb = list("attacked", "slashed", "gored", "sliced", "torn", "ripped", "butchered", "cut") - attack_verb_on = list() - -//Bottles for borg liquid squirters. PSSH PSSH -/obj/item/reagent_containers/spray/alien - name = "generic chemical synthesizer" - desc = "If you can see this, make an issue report on GitHub. Something has gone wrong!" - icon = 'icons/mob/alien.dmi' - icon_state = "borg-default" - -/obj/item/reagent_containers/spray/alien/smoke - name = "smokescreen module" - desc = "Releases a dense smoke cloud that cannot be seen through. Your thermal vision is still able to see targets through it." - icon = 'icons/mob/alien.dmi' - icon_state = "borg-spray-smoke" - list_reagents = list("water" = 50) - -/obj/item/reagent_containers/spray/alien/smoke/afterattack__legacy__attackchain(atom/A as mob|obj, mob/user as mob) - if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) - if(!A.reagents.total_volume && A.reagents) - to_chat(user, "\The [A] is empty.") - return - - if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, "\The [src] is full.") - return - reagents.remove_reagent(25,"water") - var/datum/effect_system/smoke_spread/bad/smoke = new - smoke.set_up(5, FALSE, user) - smoke.start() - playsound(user.loc, 'sound/effects/bamf.ogg', 50, 2) - -/obj/item/reagent_containers/spray/alien/smoke/cyborg_recharge(coeff, emagged) - reagents.check_and_add("water", volume, 2 * coeff) - -/obj/item/reagent_containers/spray/alien/acid - name = "polyacid synthesizer" - desc = "Sprays concentrated polyacid." - icon = 'icons/mob/alien.dmi' - icon_state = "borg-spray-acid" - list_reagents = list("facid" = 125, "sacid" = 125) - -/obj/item/reagent_containers/spray/alien/acid/cyborg_recharge(coeff, emagged) - reagents.check_and_add("facid", volume / 2, 2 * coeff) // Volume / 2 here becuase there should be an even amount of both chems. - reagents.check_and_add("sacid", volume / 2, 2 * coeff) - -/obj/item/flash/cyborg/alien - name = "eye flash" - desc = "Useful for taking pictures, making friends and flash-frying chips." - icon = 'icons/mob/alien.dmi' - icon_state = "borg-flash" - -/obj/item/flash/cyborg/alien/cyborg_recharge(coeff, emagged) - if(broken) - broken = FALSE - times_used = 0 - icon_state = "borg-flash" diff --git a/code/game/objects/items/weapons/batons.dm b/code/game/objects/items/weapons/batons.dm deleted file mode 100644 index 2e905ae25409c..0000000000000 --- a/code/game/objects/items/weapons/batons.dm +++ /dev/null @@ -1,209 +0,0 @@ -/** - * # Police Baton - * - * Knocks down the hit mob when not on harm intent and when [/obj/item/melee/classic_baton/var/on] is `TRUE`. - * - * A non-lethal attack has a cooldown to avoid spamming - */ -/obj/item/melee/classic_baton - name = "police baton" - desc = "A wooden truncheon for beating criminal scum." - icon = 'icons/obj/weapons/baton.dmi' - icon_state = "baton" - item_state = "classic_baton" - slot_flags = ITEM_SLOT_BELT - force = 12 //9 hit crit - w_class = WEIGHT_CLASS_NORMAL - // Settings - /// Whether the baton can stun silicon mobs - var/affect_silicon = FALSE - /// The amount of stamina damage the baton does per swing - var/stamina_damage = 30 - /// How much melee armour is ignored by the stamina damage - var/stamina_armour_pen = 0 - /// The stun time (in seconds) for non-silicons - var/knockdown_duration = 6 SECONDS - /// The stun time (in seconds) for silicons - var/stun_time_silicon = 10 SECONDS - /// Cooldown in seconds between two knockdowns - var/cooldown = 4 SECONDS - /// Sound to play when knocking someone down - var/stun_sound = 'sound/effects/woodhit.ogg' - // Variables - /// Whether the baton is on cooldown - var/on_cooldown = FALSE - /// Whether the baton is toggled on (to allow attacking) - var/on = TRUE - -/obj/item/melee/classic_baton/attack__legacy__attackchain(mob/living/target, mob/living/user) - if(!on) - return ..() - - add_fingerprint(user) - if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) - user.visible_message("[user] accidentally clubs [user.p_themselves()] with [src]!", \ - "You accidentally club yourself with [src]!") - user.KnockDown(knockdown_duration) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.apply_damage(force * 2, BRUTE, "head") - else - user.take_organ_damage(force * 2) - return - - if(user.a_intent == INTENT_HARM) - return ..() - if(on_cooldown) - return - if((issilicon(target) || isbot(target)) && !affect_silicon) - return ..() - baton_knockdown(target, user) - -/** - * Called when a target is about to be hit non-lethally. - * - * Arguments: - * * target - The mob about to be hit - * * user - The attacking user - */ -/obj/item/melee/classic_baton/proc/baton_knockdown(mob/living/target, mob/living/user) - if(user.mind?.martial_art?.no_baton && user.mind?.martial_art?.can_use(user)) - to_chat(user, user.mind.martial_art.no_baton_reason) - return - var/user_UID = user.UID() - if(HAS_TRAIT_FROM(target, TRAIT_WAS_BATONNED, user_UID)) // prevents double baton cheese. - return FALSE - if(issilicon(target)) - user.visible_message("[user] pulses [target]'s sensors with [src]!",\ - "You pulse [target]'s sensors with [src]!") - on_silicon_stun(target, user) - - // Check for shield/countering - else if(ishuman(target)) - var/mob/living/carbon/human/H = target - if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) - return FALSE - user.visible_message("[user] knocks down [target] with [src]!",\ - "You knock down [target] with [src]!") - on_non_silicon_stun(target, user) - - else if(isbot(target)) - user.visible_message("[user] pulses [target]'s sensors with [src]!",\ - "You pulse [target]'s sensors with [src]!") - var/mob/living/simple_animal/bot/H = target - H.disable(stun_time_silicon) - // Visuals and sound - user.do_attack_animation(target) - playsound(target, stun_sound, 75, TRUE, -1) - add_attack_logs(user, target, "Knocked down with [src]") - // Hit 'em - target.LAssailant = iscarbon(user) ? user : null - target.KnockDown(knockdown_duration) - on_cooldown = TRUE - addtimer(VARSET_CALLBACK(src, on_cooldown, FALSE), cooldown) - ADD_TRAIT(target, TRAIT_WAS_BATONNED, user_UID) // so one person cannot hit the same person with two separate batons - addtimer(CALLBACK(src, PROC_REF(baton_delay), target, user_UID), 2 SECONDS) - return TRUE - -/** - * Called when a silicon has been stunned. - * - * Arguments: - * * target - The hit mob - * * user - The attacking user - */ -/obj/item/melee/classic_baton/proc/on_silicon_stun(mob/living/silicon/target, mob/living/user) - target.flash_eyes(affect_silicon = TRUE) - target.Weaken(stun_time_silicon) - -/** - * Called when a non-silicon has been stunned. - * - * Arguments: - * * target - The hit mob - * * user - The attacking user - */ -/obj/item/melee/classic_baton/proc/on_non_silicon_stun(mob/living/target, mob/living/user) - var/armour = target.run_armor_check("chest", armour_penetration_percentage = stamina_armour_pen) // returns their chest melee armour - var/percentage_reduction = 0 - if(ishuman(target)) - percentage_reduction = (100 - ARMOUR_VALUE_TO_PERCENTAGE(armour)) / 100 - else - percentage_reduction = (100 - armour) / 100 // converts the % into a decimal - target.apply_damage(stamina_damage * percentage_reduction, STAMINA) - -/obj/item/melee/classic_baton/proc/baton_delay(mob/living/target, user_UID) - REMOVE_TRAIT(target, TRAIT_WAS_BATONNED, user_UID) - -/** - * # Fancy Cane - */ -/obj/item/melee/classic_baton/ntcane - name = "fancy cane" - desc = "A cane with special engraving on it. It seems well suited for fending off assailants..." - icon_state = "cane_nt" - item_state = "cane_nt" - -/obj/item/melee/classic_baton/ntcane/get_crutch_efficiency() - return 2 - -/** - * # Telescopic Baton - */ -/obj/item/melee/classic_baton/telescopic - name = "telescopic baton" - desc = "A compact yet robust personal defense weapon. Can be concealed when folded." - icon_state = "telebaton_0" // For telling what it is when mapping - item_state = null - slot_flags = ITEM_SLOT_BELT - w_class = WEIGHT_CLASS_SMALL - on = FALSE - /// Force when concealed - var/force_off = 0 - /// Force when extended - var/force_on = 10 - /// Item state when extended - var/item_state_on = "tele_baton" - /// Icon state when concealed - var/icon_state_off = "telebaton_0" - /// Icon state when extended - var/icon_state_on = "telebaton_1" - /// Sound to play when concealing or extending - var/extend_sound = 'sound/weapons/batonextend.ogg' - /// Attack verbs when concealed (created on Initialize) - var/static/list/attack_verb_off - /// Attack verbs when extended (created on Initialize) - var/static/list/attack_verb_on - -/obj/item/melee/classic_baton/telescopic/Initialize(mapload) - . = ..() - if(!attack_verb_off) - attack_verb_off = list("hit", "poked") - attack_verb_on = list("smacked", "struck", "cracked", "beaten") - icon_state = icon_state_off - force = force_off - attack_verb = on ? attack_verb_on : attack_verb_off - -/obj/item/melee/classic_baton/telescopic/attack_self__legacy__attackchain(mob/user) - on = !on - icon_state = on ? icon_state_on : icon_state_off - if(on) - to_chat(user, "You extend [src].") - item_state = item_state_on - w_class = WEIGHT_CLASS_BULKY //doesnt fit in backpack when its on for balance - force = force_on //stunbaton damage - attack_verb = attack_verb_on - else - to_chat(user, "You collapse [src].") - item_state = null //no sprite for concealment even when in hand - slot_flags = ITEM_SLOT_BELT - w_class = WEIGHT_CLASS_SMALL - force = force_off //not so robust now - attack_verb = attack_verb_off - // Update mob hand visuals - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() - playsound(loc, extend_sound, 50, TRUE) - add_fingerprint(user) diff --git a/code/game/objects/items/weapons/bee_briefcase.dm b/code/game/objects/items/weapons/bee_briefcase.dm deleted file mode 100644 index 6f34ff42983f9..0000000000000 --- a/code/game/objects/items/weapons/bee_briefcase.dm +++ /dev/null @@ -1,73 +0,0 @@ -/obj/item/bee_briefcase - name = "briefcase" - desc = "This briefcase has easy-release clasps and smells vaguely of honey and blood..." - icon = 'icons/obj/storage.dmi' - icon_state = "briefcase" - item_state = "briefcase" - flags = CONDUCT - hitsound = "swing_hit" - force = 10 - throw_range = 4 - w_class = WEIGHT_CLASS_BULKY - attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") - var/bees_left = 10 - var/list/blood_list = list() - var/sound_file = 'sound/misc/briefcase_bees.ogg' - var/next_sound = 0 - -/obj/item/bee_briefcase/Destroy() - blood_list.Cut() - return ..() - -/obj/item/bee_briefcase/examine(mob/user) - . = ..() - if(loc == user) - if(bees_left) - . += "There are [bees_left] bees still inside in briefcase!" - else - . += "The bees are gone... Colony collapse disorder?" - if(isAntag(user)) - . += "A briefcase filled with deadly bees, you should inject this with a syringe of your own blood before opening it. Exotic blood cannot be used." - - -/obj/item/bee_briefcase/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/reagent_containers/syringe)) - var/obj/item/reagent_containers/syringe/S = I - if(!bees_left) - to_chat(user, "The briefcase is empty, so there is no point in injecting something into it.") - return - if(S.reagents && S.reagents.total_volume) - to_chat(user, "You inject [src] with [S].") - for(var/datum/reagent/A in S.reagents.reagent_list) - if(A.id == "blood") - if(!(A.data["donor"] in blood_list)) - blood_list += A.data["donor"] - if(A.id == "lazarus_reagent") //RELOAD THE BEES (1 bee per 1 unit, max 15 bees) - if(bees_left < 15) - bees_left = min(15, round((bees_left + A.volume), 1)) //No partial bees, max 15 bees in case at any given time - to_chat(user, "The buzzing inside the briefcase intensifies as new bees form inside.") - else - to_chat(user, "The buzzing inside the briefcase swells momentarily, then returns to normal. Guess it was too cramped...") - S.reagents.clear_reagents() - S.update_icon() - else if(istype(I, /obj/item/reagent_containers/spray/pestspray)) - bees_left = max(0, (bees_left - 6)) - to_chat(user, "You spray [I] into [src].") - playsound(loc, 'sound/effects/spray3.ogg', 50, TRUE, -6) - -/obj/item/bee_briefcase/attack_self__legacy__attackchain(mob/user) - var/bees_released - if(!bees_left) - to_chat(user, "The lack of all and any bees at this event has been somewhat of a let-down...") - return - else - if(world.time >= next_sound) //This cooldown doesn't prevent us from releasing bees, just stops the sound - next_sound = world.time + 90 - playsound(loc, sound_file, 35) - - //Release up to 5 bees per use. Without using Lazarus Reagent, that means two uses. WITH Lazarus Reagent, you can get more if you don't release the last bee - for(var/bee = min(5, bees_left), bee > 0, bee--) - var/mob/living/simple_animal/hostile/poison/bees/syndi/B = new /mob/living/simple_animal/hostile/poison/bees/syndi(get_turf(user)) // RELEASE THE BEES! - B.master_and_friends = blood_list.Copy() //Doesn't automatically add the person who opens the case, so the bees will attack the user unless they gave their blood - bees_released++ - bees_left -= bees_released diff --git a/code/game/objects/items/weapons/bio_chips/bio_chip_case.dm b/code/game/objects/items/weapons/bio_chips/bio_chip_case.dm deleted file mode 100644 index 1a9e927f57d53..0000000000000 --- a/code/game/objects/items/weapons/bio_chips/bio_chip_case.dm +++ /dev/null @@ -1,69 +0,0 @@ -/obj/item/bio_chip_case - name = "bio-chip case" - desc = "A glass case containing a bio-chip." - icon = 'icons/obj/bio_chips.dmi' - icon_state = "implantcase" - item_state = "implantcase" - throw_speed = 2 - throw_range = 5 - w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=2" - container_type = OPENCONTAINER | INJECTABLE | DRAWABLE - materials = list(MAT_GLASS = 500) - - var/obj/item/bio_chip/imp - var/obj/item/bio_chip/implant_type - -/obj/item/bio_chip_case/Initialize(mapload) - . = ..() - if(!implant_type) - return - imp = new implant_type(src) - update_state() - -/obj/item/bio_chip_case/Destroy() - if(imp) - QDEL_NULL(imp) - return ..() - -/obj/item/bio_chip_case/proc/update_state() - if(imp) - origin_tech = imp.origin_tech - flags = imp.flags & ~DROPDEL - reagents = imp.reagents - else - origin_tech = initial(origin_tech) - flags = initial(flags) - reagents = null - update_icon(UPDATE_OVERLAYS) - -/obj/item/bio_chip_case/update_overlays() - . = ..() - if(imp) - var/image/implant_overlay = image('icons/obj/bio_chips.dmi', imp.implant_state) - . += implant_overlay - -/obj/item/bio_chip_case/attackby__legacy__attackchain(obj/item/W, mob/user) - ..() - - if(is_pen(W)) - rename_interactive(user, W) - else if(istype(W, /obj/item/bio_chip_implanter)) - var/obj/item/bio_chip_implanter/I = W - if(I.imp) - if(imp || I.imp.implanted) - return - I.imp.forceMove(src) - imp = I.imp - I.imp = null - update_state() - I.update_icon(UPDATE_ICON_STATE) - else - if(imp) - if(I.imp) - return - imp.loc = I - I.imp = imp - imp = null - update_state() - I.update_icon(UPDATE_ICON_STATE) diff --git a/code/game/objects/items/weapons/bio_chips/bio_chip_pad.dm b/code/game/objects/items/weapons/bio_chips/bio_chip_pad.dm deleted file mode 100644 index 198d2168f009f..0000000000000 --- a/code/game/objects/items/weapons/bio_chips/bio_chip_pad.dm +++ /dev/null @@ -1,120 +0,0 @@ -/obj/item/bio_chip_pad - name = "bio-chip pad" - desc = "Used to modify bio-chips." - icon = 'icons/obj/bio_chips.dmi' - icon_state = "implantpad-off" - item_state = "electronic" - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - - var/obj/item/bio_chip_case/case - var/static/list/cached_base64_icons = list() - -/obj/item/bio_chip_pad/Destroy() - if(case) - eject_case() - return ..() - -/obj/item/bio_chip_pad/examine(mob/user) - . = ..() - . += "You can Alt-Click [src] to remove it's stored implant." - -/obj/item/bio_chip_pad/update_icon_state() - if(case) - icon_state = "implantpad-on" - else - icon_state = "implantpad-off" - -/obj/item/bio_chip_pad/attack_self__legacy__attackchain(mob/user) - ui_interact(user) - -/obj/item/bio_chip_pad/attackby__legacy__attackchain(obj/item/bio_chip_case/C, mob/user) - if(istype(C)) - addcase(user, C) - else - return ..() - -/obj/item/bio_chip_pad/proc/addcase(mob/user, obj/item/bio_chip_case/C) - if(!user || !C) - return - if(case) - to_chat(user, "There's already a bio-chip in the pad!") - return - user.unequip(C) - C.forceMove(src) - case = C - update_icon(UPDATE_ICON_STATE) - SStgui.update_uis(src) - -/obj/item/bio_chip_pad/proc/eject_case(mob/user) - if(!case) - return - if(user) - if(user.put_in_hands(case)) - add_fingerprint(user) - case.add_fingerprint(user) - case = null - update_icon(UPDATE_ICON_STATE) - SStgui.update_uis(src) - -/obj/item/bio_chip_pad/AltClick(mob/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) - return - - eject_case(user) - -/obj/item/bio_chip_pad/ui_state(mob/user) - return GLOB.default_state - -/obj/item/bio_chip_pad/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "BioChipPad", name) - ui.set_autoupdate(FALSE) - ui.open() - -/obj/item/bio_chip_pad/ui_data(mob/user) - var/list/data = list() - data["contains_case"] = case ? TRUE : FALSE - if(case && case.imp) - var/datum/implant_fluff/implant_data = case.imp.implant_data - var/icon/base64icon = cached_base64_icons["[initial(case.imp.icon)][initial(case.imp.icon_state)]"] - if(!base64icon) - base64icon = "[icon2base64(icon(initial(case.imp.icon), initial(case.imp.icon_state), SOUTH, 1))]" - cached_base64_icons["[initial(case.imp.icon)][initial(case.imp.icon_state)]"] = base64icon - data["implant"] = list( - "name" = implant_data.name, - "life" = implant_data.life, - "notes" = implant_data.notes, - "function" = implant_data.function, - "image" = "[icon2base64(icon(initial(case.imp.icon), initial(case.imp.icon_state), SOUTH, 1))]", - ) - if(istype(case.imp, /obj/item/bio_chip/tracking)) - var/obj/item/bio_chip/tracking/T = case.imp - data["gps"] = T - data["tag"] = T.gpstag - else - data["gps"] = null - data["tag"] = null - else - // Sanity check in the case that a pad is used for multiple types of implants. - data["gps"] = null - data["tag"] = null - - return data - -/obj/item/bio_chip_pad/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - if(..()) - return - . = TRUE - switch(action) - if("eject_case") - eject_case(ui.user) - if("tag") - var/obj/item/bio_chip/tracking/T = case.imp - var/newtag = params["newtag"] || "" - newtag = uppertext(paranoid_sanitize(copytext_char(newtag, 1, 5))) - if(!length(newtag) || T.gpstag == newtag) - return - T.gpstag = newtag diff --git a/code/game/objects/items/weapons/bio_chips/bio_chip_prescan.dm b/code/game/objects/items/weapons/bio_chips/bio_chip_prescan.dm deleted file mode 100644 index c4eb39d30728d..0000000000000 --- a/code/game/objects/items/weapons/bio_chips/bio_chip_prescan.dm +++ /dev/null @@ -1,48 +0,0 @@ -/obj/item/bio_chip/grey_autocloner - name = "technocracy cloning bio-chip" - desc = "Allows for advanced instantanious cloning!" - icon_state = "generic" - origin_tech = "materials=3;combat=5;syndicate=2" - activated = FALSE - trigger_causes = BIOCHIP_TRIGGER_DEATH_ANY - implant_state = "implant-alien" - var/obj/machinery/grey_autocloner/linked - var/datum/dna2_record/our_record - -/obj/item/bio_chip/grey_autocloner/Destroy() - linked = null - our_record = null - return ..() - -/obj/item/bio_chip/grey_autocloner/death_trigger(mob/source, gibbed) - imp_in.ghostize(TRUE) - if(linked) - linked.growclone(our_record) - -/obj/item/bio_chip/grey_autocloner/implant(mob/source, mob/user, force) - if(!linked) - to_chat(user, "Please link the implanter with a Technocracy cloning pod!") - return FALSE - . = ..() - if(!. || !ishuman(imp_in)) - return FALSE - our_record = new /datum/dna2_record() - our_record.ckey = imp_in.ckey - var/obj/item/organ/B = imp_in.get_int_organ(/obj/item/organ/internal/brain) - B.dna.check_integrity() - our_record.dna = B.dna.Clone() - our_record.id = copytext(md5(B.dna.real_name), 2, 6) - our_record.name = B.dna.real_name - our_record.types = DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE - our_record.languages = imp_in.languages - if(imp_in.mind) //Save that mind so traitors can continue traitoring after cloning. - our_record.mind = imp_in.mind.UID() - -/obj/item/bio_chip_implanter/grey_autocloner - name = "bio-chip implanter (Technocracy cloning)" - implant_type = /obj/item/bio_chip/grey_autocloner - -/obj/item/bio_chip_case/grey_autocloner - name = "bio-chip case - 'Technocracy cloning'" - desc = "A glass case containing an Technocracy bio-chip." - implant_type = /obj/item/bio_chip/grey_autocloner diff --git a/code/game/objects/items/weapons/bio_chips/bio_chip_shock.dm b/code/game/objects/items/weapons/bio_chips/bio_chip_shock.dm deleted file mode 100644 index ff1be3e1419cb..0000000000000 --- a/code/game/objects/items/weapons/bio_chips/bio_chip_shock.dm +++ /dev/null @@ -1,46 +0,0 @@ -/obj/item/bio_chip/shock - name = "power bio-chip" - desc = "A shockingly effective bio-chip for stunning or killing all those in your way. Do it." - icon_state = "lighting_bolt" - item_color = "r" - origin_tech = "combat=5;magnets=3;biotech=4;syndicate=2" - implant_data = /datum/implant_fluff/shock - implant_state = "implant-syndicate" - var/enabled = FALSE - var/old_mclick_override - var/datum/middle_click_override/shock_implant/mclick_override = new /datum/middle_click_override/shock_implant - COOLDOWN_DECLARE(last_shocked) - var/shock_delay = 3 SECONDS - var/unlimited_power = FALSE // Does this really need explanation? - var/shock_range = 7 - -/obj/item/bio_chip/shock/activate() - enabled = !enabled - to_chat(imp_in, "You toggle the implant [enabled? "on" : "off"].") - if(enabled) - if(imp_in.middleClickOverride) - old_mclick_override = imp_in.middleClickOverride - imp_in.middleClickOverride = mclick_override - else - if(old_mclick_override) - imp_in.middleClickOverride = old_mclick_override - old_mclick_override = null - else - imp_in.middleClickOverride = null - -/obj/item/bio_chip/shock/removed() - if(old_mclick_override) - imp_in.middleClickOverride = old_mclick_override - old_mclick_override = null - else - imp_in.middleClickOverride = null - return ..() - -/obj/item/bio_chip_implanter/shock - name = "bio-chip implanter (power)" - implant_type = /obj/item/bio_chip/shock - -/obj/item/bio_chip_case/shock - name = "bio-chip case - 'power'" - desc = "A glass case containing a power bio-chip." - implant_type = /obj/item/bio_chip/shock diff --git a/code/game/objects/items/weapons/bio_chips/bio_chip_storage.dm b/code/game/objects/items/weapons/bio_chips/bio_chip_storage.dm deleted file mode 100644 index c4534bd882d9f..0000000000000 --- a/code/game/objects/items/weapons/bio_chips/bio_chip_storage.dm +++ /dev/null @@ -1,74 +0,0 @@ -/obj/item/storage/hidden_implant - name = "bluespace pocket" - storage_slots = 2 - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = WEIGHT_CLASS_GIGANTIC - w_class = WEIGHT_CLASS_BULKY - cant_hold = list(/obj/item/disk/nuclear) - w_class_override = list(/obj/item/storage/belt) - silent = TRUE - -/obj/item/bio_chip/storage - name = "storage bio-chip" - desc = "Stores up to two big items in a bluespace pocket." - icon_state = "storage" - origin_tech = "materials=2;magnets=4;bluespace=5;syndicate=4" - item_color = "r" - implant_data = /datum/implant_fluff/storage - implant_state = "implant-syndicate" - - var/obj/item/storage/hidden_implant/storage - -/obj/item/bio_chip/storage/Initialize(mapload) - . = ..() - storage = new /obj/item/storage/hidden_implant(src) - -/obj/item/bio_chip/storage/emp_act(severity) - ..() - storage.emp_act(severity) - -/obj/item/bio_chip/storage/activate() - if(!length(storage.mobs_viewing)) - storage.MouseDrop(imp_in) - else - for(var/mob/to_close in storage.mobs_viewing) - storage.close(to_close) - -/obj/item/bio_chip/storage/removed(source) - if(..()) - for(var/mob/M in range(1)) - if(M.s_active == storage) - storage.close(M) - for(var/obj/item/I in storage) - storage.remove_from_storage(I, get_turf(source)) - return TRUE - -/obj/item/bio_chip/storage/implant(mob/source) - var/obj/item/bio_chip/storage/imp_e = locate(type) in source - if(imp_e) - imp_e.storage.storage_slots += storage.storage_slots - imp_e.storage.max_combined_w_class += storage.max_combined_w_class - imp_e.storage.contents += storage.contents - - for(var/mob/M in range(1)) - if(M.s_active == storage) - storage.close(M) - storage.show_to(source) - - qdel(src) - return TRUE - - return ..() - -/obj/item/bio_chip/storage/proc/get_contents() //Used for swiftly returning a list of the implant's contents i.e. for checking a theft objective's completion. - if(storage && storage.contents) - return storage.contents - -/obj/item/bio_chip_implanter/storage - name = "bio-chip implanter (storage)" - implant_type = /obj/item/bio_chip/storage - -/obj/item/bio_chip_case/storage - name = "bio-chip case - 'Storage'" - desc = "A glass case containing a storage bio-chip." - implant_type = /obj/item/bio_chip/storage diff --git a/code/game/objects/items/weapons/bio_chips/bio_chipper.dm b/code/game/objects/items/weapons/bio_chips/bio_chipper.dm deleted file mode 100644 index 25d0b9d7cc39b..0000000000000 --- a/code/game/objects/items/weapons/bio_chips/bio_chipper.dm +++ /dev/null @@ -1,56 +0,0 @@ -/obj/item/bio_chip_implanter - name = "bio-chip implanter" - desc = "A sterile automatic bio-chip injector." - icon = 'icons/obj/bio_chips.dmi' - icon_state = "implanter0" - item_state = "syringe_0" - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - origin_tech = "materials=2;biotech=3" - materials = list(MAT_METAL = 600, MAT_GLASS = 200) - toolspeed = 1 - var/obj/item/bio_chip/imp - var/obj/item/bio_chip/implant_type - -/obj/item/bio_chip_implanter/update_icon_state() - if(imp) - icon_state = "implanter1" - origin_tech = imp.origin_tech - else - icon_state = "implanter0" - origin_tech = initial(origin_tech) - -/obj/item/bio_chip_implanter/attack__legacy__attackchain(mob/living/carbon/M, mob/user) - if(!iscarbon(M)) - return - if(user && imp) - if(M != user) - M.visible_message("[user] is attempting to bio-chip [M].") - - var/turf/T = get_turf(M) - if(T && (M == user || do_after(user, 50 * toolspeed, target = M))) - if(user && M && (get_turf(M) == T) && src && imp) - if(imp.implant(M, user)) - if(M == user) - to_chat(user, "You bio-chip yourself.") - else - M.visible_message("[user] has implanted [M].", "[user] bio-chips you.") - imp = null - update_icon(UPDATE_ICON_STATE) - -/obj/item/bio_chip_implanter/attackby__legacy__attackchain(obj/item/W, mob/user, params) - ..() - if(is_pen(W)) - rename_interactive(user, W) - -/obj/item/bio_chip_implanter/Initialize(mapload) - . = ..() - if(!implant_type) - return - imp = new implant_type() - update_icon(UPDATE_ICON_STATE) - -/obj/item/bio_chip_implanter/Destroy() - QDEL_NULL(imp) - . = ..() diff --git a/code/game/objects/items/weapons/caution.dm b/code/game/objects/items/weapons/caution.dm deleted file mode 100644 index 46e3b9da43cb3..0000000000000 --- a/code/game/objects/items/weapons/caution.dm +++ /dev/null @@ -1,97 +0,0 @@ -/obj/item/caution - desc = "Caution! Wet Floor!" - name = "wet floor sign" - icon = 'icons/obj/janitor.dmi' - icon_state = "caution" - lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' - force = 1.0 - throwforce = 3.0 - throw_speed = 1 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("warned", "cautioned", "smashed") - -/obj/item/caution/proximity_sign - var/timing = FALSE - var/armed = FALSE - var/timepassed = 0 - var/datum/proximity_monitor/proximity_monitor - -/obj/item/caution/proximity_sign/Initialize(mapload) - . = ..() - proximity_monitor = new(src, 1) - -/obj/item/caution/proximity_sign/attack_self__legacy__attackchain(mob/user as mob) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(!H.mind.has_antag_datum(/datum/antagonist/traitor) && !IS_MINDSLAVE(H)) - return - if(armed) - armed = FALSE - to_chat(user, "You disarm \the [src].") - return - timing = !timing - if(timing) - START_PROCESSING(SSobj, src) - else - armed = FALSE - timepassed = 0 - to_chat(H, "You [timing ? "activate \the [src]'s timer, you have 15 seconds." : "de-activate \the [src]'s timer."]") - -/obj/item/caution/proximity_sign/process() - if(!timing) - STOP_PROCESSING(SSobj, src) - timepassed++ - if(timepassed >= 15 && !armed) - armed = TRUE - timing = FALSE - -/obj/item/caution/proximity_sign/HasProximity(atom/movable/AM) - if(armed) - if(iscarbon(AM) && !isbrain(AM)) - var/mob/living/carbon/C = AM - if(C.m_intent != MOVE_INTENT_WALK) - visible_message("[src] beeps, \"Sign says walk, asshole.\"") - playsound(src, 'sound/misc/sign_says_walk.ogg', 40) - explosion(src.loc,-1,0,2) - if(ishuman(C)) - dead_legs(C) - if(src) - qdel(src) - -/obj/item/caution/proximity_sign/proc/dead_legs(mob/living/carbon/human/H as mob) - var/obj/item/organ/external/l = H.get_organ("l_leg") - var/obj/item/organ/external/r = H.get_organ("r_leg") - if(l) - l.droplimb(0, DROPLIMB_SHARP) - if(r) - r.droplimb(0, DROPLIMB_SHARP) - -/obj/item/stack/caution/proximity_sign/malf //Malf module - name = "proximity mine dispenser" - icon = 'icons/obj/janitor.dmi' - icon_state = "caution" - energy_type = /datum/robot_storage/energy/jani_landmine - is_cyborg = TRUE - -/obj/item/stack/caution/proximity_sign/malf/afterattack__legacy__attackchain(atom/target, mob/user, proximity) - if(!check_allowed_items(target, 1)) - return - if(!proximity) - return - var/turf/T = get_turf(target) - - if(is_blocked_turf(T, TRUE)) //can't put mines on a tile that has dense stuff - to_chat(user, "The space is occupied! You cannot place a mine there!") - return - if(!use(1)) //Can't place a landmine if you don't have a landmine - to_chat(user, "[src] is out of landmines! It can be refilled at a cyborg charger.") - return - playsound(src.loc, 'sound/machines/click.ogg', 20, TRUE) - var/obj/item/caution/proximity_sign/M = new /obj/item/caution/proximity_sign(get_turf(target), src) - M.timing = TRUE - START_PROCESSING(SSobj, M) - to_chat(user, "You place a landmine with [src]. You have 15 seconds until it is armed.") - return M - diff --git a/code/game/objects/items/weapons/chrono_eraser.dm b/code/game/objects/items/weapons/chrono_eraser.dm deleted file mode 100644 index 47449644e69a3..0000000000000 --- a/code/game/objects/items/weapons/chrono_eraser.dm +++ /dev/null @@ -1,266 +0,0 @@ -#define CHRONO_BEAM_RANGE 3 -#define CHRONO_FRAME_COUNT 22 -/obj/item/chrono_eraser - name = "\improper Timestream Eradication Device" - desc = "The result of outlawed time-bluespace research, this device is capable of wiping a being from the timestream. They never are, they never were, they never will be." - icon = 'icons/obj/chronos.dmi' - icon_state = "chronobackpack" - item_state = "backpack" - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK - slowdown = 1 - actions_types = list(/datum/action/item_action/equip_unequip_ted_gun) - var/obj/item/gun/energy/chrono_gun/PA = null - var/list/erased_minds = list() //a collection of minds from the dead - -/obj/item/chrono_eraser/proc/pass_mind(datum/mind/M) - erased_minds += M - -/obj/item/chrono_eraser/dropped() - ..() - if(PA) - qdel(PA) - -/obj/item/chrono_eraser/Destroy() - dropped() - return ..() - -/obj/item/chrono_eraser/ui_action_click(mob/user) - if(iscarbon(user)) - var/mob/living/carbon/C = user - if(C.back == src) - if(PA) - qdel(PA) - else - PA = new(user, src) - user.put_in_hands(PA) - -/obj/item/chrono_eraser/item_action_slot_check(slot, mob/user) - if(slot == ITEM_SLOT_BACK) - return 1 - - -/obj/item/gun/energy/chrono_gun - name = "\improper T.E.D. Projection Apparatus" - desc = "It's as if they never existed in the first place." - icon = 'icons/obj/chronos.dmi' - icon_state = "chronogun" - item_state = "chronogun" - w_class = WEIGHT_CLASS_NORMAL - flags = NODROP | DROPDEL - ammo_type = list(/obj/item/ammo_casing/energy/chrono_beam) - can_charge = FALSE - fire_delay = 50 - var/obj/item/chrono_eraser/TED = null - var/obj/structure/chrono_field/field = null - var/turf/startpos = null - -/obj/item/gun/energy/chrono_gun/Initialize(mapload, obj/item/chrono_eraser/T) - . = ..() - if(istype(T)) - TED = T - else //admin must have spawned it - TED = new(src.loc) - qdel(src) - -/obj/item/gun/energy/chrono_gun/update_overlays() - return list() - -/obj/item/gun/energy/chrono_gun/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override, bonus_spread = 0) - if(field) - field_disconnect(field) - ..() - -/obj/item/gun/energy/chrono_gun/Destroy() - if(TED) - TED.PA = null - TED = null - if(field) - field_disconnect(field) - return ..() - -/obj/item/gun/energy/chrono_gun/proc/field_connect(obj/structure/chrono_field/F) - var/mob/living/user = src.loc - if(F.gun) - if(isliving(user) && F.captured) - to_chat(user, "FAIL: [F.captured] already has an existing connection.") - src.field_disconnect(F) - else - startpos = get_turf(src) - field = F - F.gun = src - if(isliving(user) && F.captured) - to_chat(user, "Connection established with target: [F.captured]") - - -/obj/item/gun/energy/chrono_gun/proc/field_disconnect(obj/structure/chrono_field/F) - if(F && field == F) - var/mob/living/user = src.loc - if(F.gun == src) - F.gun = null - if(isliving(user) && F.captured) - to_chat(user, "Disconnected from target: [F.captured]") - field = null - startpos = null - -/obj/item/gun/energy/chrono_gun/proc/field_check(obj/structure/chrono_field/F) - if(F) - if(field == F) - var/turf/currentpos = get_turf(src) - var/mob/living/user = src.loc - if((currentpos == startpos) && (field in view(CHRONO_BEAM_RANGE, currentpos)) && !IS_HORIZONTAL(user) && (user.stat == CONSCIOUS)) - return 1 - field_disconnect(F) - return 0 - -/obj/item/gun/energy/chrono_gun/proc/pass_mind(datum/mind/M) - if(TED) - TED.pass_mind(M) - - -/obj/item/projectile/energy/chrono_beam - name = "eradication beam" - icon_state = "chronobolt" - range = CHRONO_BEAM_RANGE - color = null - nodamage = 1 - var/obj/item/gun/energy/chrono_gun/gun = null - -/obj/item/projectile/energy/chrono_beam/fire() - gun = firer.get_active_hand() - if(istype(gun)) - return ..() - else - return 0 - -/obj/item/projectile/energy/chrono_beam/on_hit(atom/target) - if(target && gun && isliving(target)) - var/obj/structure/chrono_field/F = new(target.loc, target, gun) - gun.field_connect(F) - -/obj/item/ammo_casing/energy/chrono_beam - name = "eradication beam" - projectile_type = /obj/item/projectile/energy/chrono_beam - muzzle_flash_effect = /obj/effect/temp_visual/target_angled/muzzle_flash/energy - muzzle_flash_color = null - icon = 'icons/obj/projectiles.dmi' - icon_state = "chronobolt" - e_cost = 0 - -/obj/structure/chrono_field - name = "eradication field" - desc = "An aura of time-bluespace energy." - icon = 'icons/effects/effects.dmi' - icon_state = "chronofield" - density = FALSE - anchored = TRUE - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF - move_resist = INFINITY - blend_mode = BLEND_MULTIPLY - var/mob/living/captured = null - var/obj/item/gun/energy/chrono_gun/gun = null - var/tickstokill = 15 - var/mutable_appearance/mob_underlay - var/preloaded = 0 - var/RPpos = null - -/obj/structure/chrono_field/New(loc, mob/living/target, obj/item/gun/energy/chrono_gun/G) - if(target && isliving(target) && G) - target.forceMove(src) - captured = target - var/icon/mob_snapshot = getFlatIcon(target) - var/icon/cached_icon = new() - - for(var/i=1, i<=CHRONO_FRAME_COUNT, i++) - var/icon/removing_frame = icon('icons/obj/chronos.dmi', "erasing", SOUTH, i) - var/icon/mob_icon = icon(mob_snapshot) - mob_icon.Blend(removing_frame, ICON_MULTIPLY) - cached_icon.Insert(mob_icon, "frame[i]") - - mob_underlay = mutable_appearance(cached_icon, "frame1") - update_icon(UPDATE_ICON_STATE) - - desc = initial(desc) + "
    It appears to contain [target.name]." - START_PROCESSING(SSobj, src) - return ..() - -/obj/structure/chrono_field/Destroy() - if(gun && gun.field_check(src)) - gun.field_disconnect(src) - return ..() - -/obj/structure/chrono_field/update_icon_state() - var/ttk_frame = 1 - (tickstokill / initial(tickstokill)) - ttk_frame = clamp(CEILING(ttk_frame * CHRONO_FRAME_COUNT, 1), 1, CHRONO_FRAME_COUNT) - if(ttk_frame != RPpos) - RPpos = ttk_frame - mob_underlay.icon_state = "frame[RPpos]" - underlays = list() //hack: BYOND refuses to update the underlay to match the icon_state otherwise - underlays += mob_underlay - -/obj/structure/chrono_field/process() - if(captured) - if(tickstokill > initial(tickstokill)) - for(var/atom/movable/AM in contents) - AM.forceMove(drop_location()) - qdel(src) - else if(tickstokill <= 0) - to_chat(captured, "As the last essence of your being is erased from time, you begin to re-experience your most enjoyable memory. You feel happy...") - var/mob/dead/observer/ghost = captured.ghostize(1) - if(captured.mind) - if(ghost) - ghost.mind = null - if(gun) - gun.pass_mind(captured.mind) - qdel(captured) - qdel(src) - else - captured.Paralyse(8 SECONDS) - if(captured.loc != src) - captured.forceMove(src) - update_icon(UPDATE_ICON_STATE) - if(gun) - if(gun.field_check(src)) - tickstokill-- - else - gun = null - return .() - else - tickstokill++ - else - qdel(src) - - -/obj/structure/chrono_field/bullet_act(obj/item/projectile/P) - if(istype(P, /obj/item/projectile/energy/chrono_beam)) - var/obj/item/projectile/energy/chrono_beam/beam = P - var/obj/item/gun/energy/chrono_gun/Pgun = beam.gun - if(Pgun && istype(Pgun)) - Pgun.field_connect(src) - else - return 0 - -/obj/structure/chrono_field/return_obj_air() - //we always have nominal air and temperature - RETURN_TYPE(/datum/gas_mixture) - var/datum/gas_mixture/GM = new - GM.set_oxygen(MOLES_O2STANDARD) - GM.set_nitrogen(MOLES_N2STANDARD) - GM.set_temperature(T20C) - return GM - -/obj/structure/chrono_field/Move() - return - -/obj/structure/chrono_field/singularity_act() - return - -/obj/structure/chrono_field/ex_act() - return - -/obj/structure/chrono_field/blob_act(obj/structure/blob/B) - return - - -#undef CHRONO_BEAM_RANGE -#undef CHRONO_FRAME_COUNT diff --git a/code/game/objects/items/weapons/cigs.dm b/code/game/objects/items/weapons/cigs.dm deleted file mode 100644 index d2fc883566f75..0000000000000 --- a/code/game/objects/items/weapons/cigs.dm +++ /dev/null @@ -1,598 +0,0 @@ -#define REAGENT_TIME_RATIO 2.5 - -/* -CONTENTS: -1. CIGARETTES -2. CIGARS -3. HOLO-CIGAR -4. PIPES -5. ROLLING - -CIGARETTE PACKETS ARE IN FANCY.DM -LIGHTERS ARE IN LIGHTERS.DM -*/ - -////////////////// -//FINE SMOKABLES// -////////////////// - -/obj/item/clothing/mask/cigarette - name = "cigarette" - desc = "A roll of tobacco and nicotine." - icon_state = "cigoff" - item_state = "cigoff" - throw_speed = 0.5 - slot_flags = ITEM_SLOT_MASK - w_class = WEIGHT_CLASS_TINY - body_parts_covered = null - attack_verb = null - container_type = INJECTABLE - /// Is the cigarette lit? - var/lit = FALSE - /// Lit cigarette sprite. - var/icon_on = "cigon" //Note - these are in masks.dmi not in cigarette.dmi - /// Unlit cigarette sprite. - var/icon_off = "cigoff" - /// Do we require special items to be lit? - var/list/fancy_lighters = list() - /// What trash item the cigarette makes when it burns out. - var/type_butt = /obj/item/cigbutt - /// How long does the cigarette last before going out? Decrements by 1 every cycle. - var/smoketime = 150 // 300 seconds. - /// The cigarette's total reagent capacity. - var/chem_volume = 60 - /// A list of the types and amounts of reagents in the cigarette. - var/list/list_reagents = list("nicotine" = 40) - /// Has anyone taken any reagents from the cigarette? The first tick gives a bigger dose. - var/first_puff = TRUE - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/mask.dmi', - "Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi', - "Tajaran" = 'icons/mob/clothing/species/tajaran/mask.dmi', - "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi', - "Grey" = 'icons/mob/clothing/species/grey/mask.dmi') - -/obj/item/clothing/mask/cigarette/Initialize(mapload) - . = ..() - create_reagents(chem_volume) // making the cigarrete a chemical holder with a maximum volume of 30 - reagents.set_reacting(FALSE) // so it doesn't react until you light it - if(list_reagents) - reagents.add_reagent_list(list_reagents) - smoketime = reagents.total_volume * 2.5 - -/obj/item/clothing/mask/cigarette/Destroy() - QDEL_NULL(reagents) - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/clothing/mask/cigarette/decompile_act(obj/item/matter_decompiler/C, mob/user) - if(isdrone(user)) - C.stored_comms["wood"] += 1 - qdel(src) - return TRUE - return ..() - -/obj/item/clothing/mask/cigarette/attack__legacy__attackchain(mob/living/M, mob/living/user, def_zone) - if(istype(M) && M.on_fire) - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(M) - if(M != user) - user.visible_message( - "[user] coldly lights [src] with the burning body of [M]. Clearly, [user.p_they()] offer[user.p_s()] the warmest of regards...", - "You coldly light [src] with the burning body of [M]." - ) - else - // The fire will light it in your hands by itself, but if you whip out the cig and click yourself fast enough, this will happen. TRULY you have your priorities stright. - user.visible_message( - "[user] quickly whips out [src] and nonchalantly lights it with [user.p_their()] own burning body. Clearly, [user.p_they()] [user.p_have()] [user.p_their()] priorities straight.", - "You quickly whip out [src] and nonchalantly light it with your own burning body. Clearly, you have your priorities straight." - ) - light(user, user) - return TRUE - -/obj/item/clothing/mask/cigarette/afterattack__legacy__attackchain(atom/target, mob/living/user, proximity) - if(!proximity) - return - - if(ismob(target)) - // If the target has no cig, try to give them the cig. - var/mob/living/carbon/M = target - if(istype(M) && user.zone_selected == "mouth" && !M.wear_mask && user.a_intent == INTENT_HELP) - user.drop_item_to_ground(src, force = TRUE) - M.equip_to_slot_if_possible(src, ITEM_SLOT_MASK) - if(target != user) - user.visible_message( - "[user] slips \a [name] into the mouth of [M].", - "You slip [src] into the mouth of [M]." - ) - else - to_chat(user, "You put [src] into your mouth.") - return TRUE - - // If they DO have a cig, try to light it with your own cig. - if(!cigarette_lighter_act(user, M)) - return ..() - - // You can dip cigarettes into beakers. - if(istype(target, /obj/item/reagent_containers/glass)) - var/obj/item/reagent_containers/glass/glass = target - var/transfered = glass.reagents.trans_to(src, chem_volume) - if(transfered) - to_chat(user, "You dip [src] into [glass].") - return - - // Either the beaker was empty, or the cigarette was full - if(!glass.reagents.total_volume) - to_chat(user, "[glass] is empty.") - else - to_chat(user, "[src] is full.") - - return ..() - -/obj/item/clothing/mask/cigarette/attack_self__legacy__attackchain(mob/user) - if(lit) - user.visible_message( - "[user] calmly drops and treads on [src], putting it out instantly.", - "You calmly drop and tread on [src], putting it out instantly.", - "You hear a foot being brought down on something, and the tiny fizzling of an ember going out." - ) - die() - return ..() - -/obj/item/clothing/mask/cigarette/can_enter_storage(obj/item/storage/S, mob/user) - if(lit) - to_chat(user, "[S] can't hold \the [initial(name)] while it's lit!") // initial(name) so it doesn't say "lit" twice in a row - return FALSE - return TRUE - -/obj/item/clothing/mask/cigarette/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - ..() - light() - -/obj/item/clothing/mask/cigarette/catch_fire() - if(!lit) - visible_message("[src] is lit by the flames!") - light() - -/obj/item/clothing/mask/cigarette/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item) - var/obj/item/clothing/mask/cigarette/cig = ..() - if(!cig) - return !isnull(cig) - - if(!lit) - to_chat(user, "You cannot light [cig] with [src] because you need a lighter to light [src] before you can use [src] as a lighter to light [cig]... This seems a little convoluted.") - return TRUE - - if(target == user) - user.visible_message( - "[user] presses [src] against [cig] until it lights. Seems oddly recursive...", - "You press [src] against [cig] until it lights. Seems oddly recursive..." - ) - else - user.visible_message( - "[user] presses [src] until it lights. Sharing is caring!", - "You press [src] against [cig] until it lights. Sharing is caring!" - ) - cig.light(user, target) - return TRUE - -/obj/item/clothing/mask/cigarette/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) - if(I.cigarette_lighter_act(user, user, src)) - return - - // Catch any item that has no cigarette_lighter_act but logically should be able to work as a lighter due to being hot. - if(I.get_heat()) - //Give a generic light message. - user.visible_message( - "[user] lights [src] with [I]", - "You light [src] with [I]." - ) - light(user) - -/obj/item/clothing/mask/cigarette/proc/light(mob/living/user, mob/living/target) - if(lit) - return - - lit = TRUE - name = "lit [name]" - attack_verb = list("burnt", "singed") - hitsound = 'sound/items/welder.ogg' - damtype = BURN - force = 4 - var/mob/M = loc - - // Plasma explodes when exposed to fire. - if(reagents.get_reagent_amount("plasma")) - var/datum/effect_system/reagents_explosion/e = new() - e.set_up(round(reagents.get_reagent_amount("plasma") / 2.5, 1), get_turf(src), 0, 0) - e.start() - if(ismob(M)) - M.drop_item_to_ground(src, force = TRUE) - qdel(src) - return - - // Fuel explodes, too, but much less violently. - if(reagents.get_reagent_amount("fuel")) - var/datum/effect_system/reagents_explosion/e = new() - e.set_up(round(reagents.get_reagent_amount("fuel") / 5, 1), get_turf(src), 0, 0) - e.start() - if(ismob(M)) - M.drop_item_to_ground(src, force = TRUE) - qdel(src) - return - - // If there is no target, the user is probably lighting their own cig. - if(isnull(target)) - target = user - - // If there is also no user, the cig is being lit by atmos or something. - if(target) - target.update_inv_wear_mask() - target.update_inv_l_hand() - target.update_inv_r_hand() - - reagents.set_reacting(TRUE) - reagents.handle_reactions() - icon_state = icon_on - item_state = icon_on - if(iscarbon(loc)) - var/mob/living/carbon/C = loc - if(C.wear_mask == src) // Don't update if it's just in their hand - C.wear_mask_update(src) - set_light(2, 0.25, "#E38F46") - START_PROCESSING(SSobj, src) - playsound(src, 'sound/items/lighter/light.ogg', 25, TRUE) - return TRUE - -/obj/item/clothing/mask/cigarette/process() - var/mob/living/M = loc - if(isliving(loc)) - M.IgniteMob() - smoketime-- - if(reagents.total_volume <= 0 || smoketime < 1) - die() - return - smoke() - -/obj/item/clothing/mask/cigarette/extinguish_light(force) - if(!force) - return - die() - -/obj/item/clothing/mask/cigarette/proc/smoke() - var/turf/location = get_turf(src) - var/is_being_smoked = FALSE - // Check whether this is actually in a mouth, being smoked - if(iscarbon(loc)) - var/mob/living/carbon/C = loc - if(src == C.wear_mask) - // There used to be a species check here, but synthetics can smoke now - is_being_smoked = TRUE - if(location) - location.hotspot_expose(700, 1) - if(reagents && reagents.total_volume) // check if it has any reagents at all - if(is_being_smoked) // if it's being smoked, transfer reagents to the mob - var/mob/living/carbon/C = loc - for(var/datum/reagent/R in reagents.reagent_list) - reagents.trans_id_to(C, R.id, first_puff ? 1 : max(REAGENTS_METABOLISM / length(reagents.reagent_list), 0.1)) //transfer at least .1 of each chem - first_puff = FALSE - if(!reagents.total_volume) // There were reagents, but now they're gone - to_chat(C, "Your [name] loses its flavor.") - else // else just remove some of the reagents - reagents.remove_any(REAGENTS_METABOLISM) - -/obj/item/clothing/mask/cigarette/proc/die() - var/turf/T = get_turf(src) - set_light(0) - var/obj/item/butt = new type_butt(T) - transfer_fingerprints_to(butt) - if(ismob(loc)) - var/mob/living/M = loc - to_chat(M, "Your [name] goes out.") - M.drop_item_to_ground(src, force = TRUE) //Force the un-equip so the overlays update - STOP_PROCESSING(SSobj, src) - qdel(src) - -/obj/item/clothing/mask/cigarette/get_heat() - return lit * 1000 - -////////////////////////////// -// MARK: CIGARETTES -////////////////////////////// -/obj/item/clothing/mask/cigarette/menthol - list_reagents = list("nicotine" = 40, "menthol" = 20) - -/obj/item/clothing/mask/cigarette/random - -/obj/item/clothing/mask/cigarette/random/New() - list_reagents = list("nicotine" = 40, pick("fuel","saltpetre","synaptizine","green_vomit","potass_iodide","msg","lexorin","mannitol","spaceacillin","cryoxadone","holywater","tea","egg","haloperidol","mutagen","omnizine","carpet","aranesp","cryostylane","chocolate","bilk","cheese","rum","blood","charcoal","coffee","ectoplasm","space_drugs","milk","mutadone","antihol","teporone","insulin","salbutamol","toxin") = 20) - ..() - -/obj/item/clothing/mask/cigarette/syndicate - list_reagents = list("nicotine" = 40, "omnizine" = 20) - -/obj/item/clothing/mask/cigarette/medical_marijuana - list_reagents = list("thc" = 20, "cbd" = 40) - -/obj/item/clothing/mask/cigarette/robustgold - list_reagents = list("nicotine" = 40, "gold" = 1) - -/obj/item/clothing/mask/cigarette/shadyjims - list_reagents = list("nicotine" = 40, "lipolicide" = 7.5, "ammonia" = 2, "atrazine" = 1, "toxin" = 1.5) - -/obj/item/clothing/mask/cigarette/rollie - name = "rollie" - desc = "A roll of dried plant matter wrapped in thin paper." - icon_state = "spliffoff" - icon_on = "spliffon" - icon_off = "spliffoff" - type_butt = /obj/item/cigbutt/roach - throw_speed = 0.5 - item_state = "spliffoff" - list_reagents = list("thc" = 40, "cbd" = 20) - -/obj/item/clothing/mask/cigarette/rollie/Initialize(mapload) - . = ..() - scatter_atom() -/obj/item/clothing/mask/cigarette/rollie/custom - list_reagents = list() - -/obj/item/cigbutt - name = "cigarette butt" - desc = "A manky old cigarette butt." - icon = 'icons/obj/clothing/masks.dmi' - icon_state = "cigbutt" - w_class = WEIGHT_CLASS_TINY - throwforce = 1 - scatter_distance = 10 - -/obj/item/cigbutt/Initialize(mapload) - . = ..() - scatter_atom() - transform = turn(transform, rand(0, 360)) - -/obj/item/cigbutt/decompile_act(obj/item/matter_decompiler/C, mob/user) - if(isdrone(user)) - C.stored_comms["wood"] += 1 - qdel(src) - return TRUE - return ..() - -/obj/item/cigbutt/roach - name = "roach" - desc = "A manky old roach, or for non-stoners, a used rollup." - icon_state = "roach" - scatter_distance = 5 - -/obj/item/cigbutt/roach/Initialize(mapload) - . = ..() - scatter_atom() - -////////////////////////////// -// MARK: ROLLING -////////////////////////////// -/obj/item/rollingpaper - name = "rolling paper" - desc = "A thin piece of paper used to make fine smokeables." - icon = 'icons/obj/cigarettes.dmi' - icon_state = "cig_paper" - w_class = WEIGHT_CLASS_TINY - -/obj/item/rollingpaper/afterattack__legacy__attackchain(atom/target, mob/user, proximity) - if(!proximity) - return - - if(!istype(target, /obj/item/food/grown)) - return ..() - - var/obj/item/food/grown/plant = target - if(!plant.dry) - to_chat(user, "You need to dry this first!") - return - - user.unequip(plant, TRUE) - user.unequip(src, TRUE) - var/obj/item/clothing/mask/cigarette/rollie/custom/custom_rollie = new (get_turf(user)) - custom_rollie.reagents.maximum_volume = plant.reagents.total_volume - plant.reagents.trans_to(custom_rollie, plant.reagents.total_volume) - custom_rollie.smoketime = custom_rollie.reagents.total_volume * 2.5 - - user.put_in_active_hand(custom_rollie) - to_chat(user, "You roll the [plant.name] into a rolling paper.") - custom_rollie.desc = "Dried [plant.name] rolled up in a thin piece of paper." - - qdel(plant) - qdel(src) - -////////////////////////////// -// MARK: CIGARS -////////////////////////////// -/obj/item/clothing/mask/cigarette/cigar - name = "\improper Premium Cigar" - desc = "A brown roll of tobacco and... well, you're not quite sure. This thing's huge!" - icon_state = "cigaroff" - item_state = "cigaroff" - icon_on = "cigaron" - icon_off = "cigaroff" - throw_speed = 0.5 - fancy_lighters = list(/obj/item/match, /obj/item/lighter/zippo) - type_butt = /obj/item/cigbutt/cigarbutt - smoketime = 300 - chem_volume = 120 - list_reagents = list("nicotine" = 120) - -/obj/item/clothing/mask/cigarette/cigar/cohiba - name = "\improper Cohiba Robusto Cigar" - desc = "There's little more you could want from a cigar." - icon_state = "cigar2off" - icon_on = "cigar2on" - icon_off = "cigar2off" - -/obj/item/clothing/mask/cigarette/cigar/havana - name = "\improper Premium Havanian Cigar" - desc = "A cigar fit for only the best for the best." - icon_state = "cigar2off" - icon_on = "cigar2on" - icon_off = "cigar2off" - smoketime = 450 - chem_volume = 180 - list_reagents = list("nicotine" = 180) - -/obj/item/cigbutt/cigarbutt - name = "cigar butt" - desc = "A manky old cigar butt." - icon_state = "cigarbutt" - -////////////////////////////// -// MARK: HOLO-CIGAR -////////////////////////////// -/obj/item/clothing/mask/holo_cigar - name = "Holo-Cigar" - desc = "A sleek electronic cigar imported straight from Sol. You feel badass merely glimpsing it..." - icon_state = "holocigaroff" - /// Is the holo-cigar lit? - var/enabled = FALSE - /// Tracks if this is the first cycle smoking the cigar. - var/has_smoked = FALSE - -/obj/item/clothing/mask/holo_cigar/Destroy() - . = ..() - STOP_PROCESSING(SSobj, src) - -/obj/item/clothing/mask/holo_cigar/update_icon_state() - . = ..() - icon_state = "holocigar[enabled ? "on" : "off"]" - -/obj/item/clothing/mask/holo_cigar/examine(mob/user) - . = ..() - if(enabled) - . += "[src] hums softly as it synthesizes nicotine." - else - . += "[src] seems to be inactive." - -/obj/item/clothing/mask/holo_cigar/process() - if(!iscarbon(loc)) - return - - var/mob/living/carbon/C = loc - if(C.wear_mask != src) - return - - if(!has_smoked) - C.reagents.add_reagent("nicotine", 2) - has_smoked = TRUE - else - C.reagents.add_reagent("nicotine", REAGENTS_METABOLISM) - -/obj/item/clothing/mask/holo_cigar/equipped(mob/user, slot, initial) - . = ..() - if(enabled && slot == ITEM_SLOT_MASK) - if(!HAS_TRAIT_FROM(user, TRAIT_BADASS, HOLO_CIGAR)) - ADD_TRAIT(user, TRAIT_BADASS, HOLO_CIGAR) - to_chat(user, "You feel more badass while smoking [src].") - -/obj/item/clothing/mask/holo_cigar/dropped(mob/user, silent) - . = ..() - has_smoked = FALSE - if(HAS_TRAIT_FROM(user, TRAIT_BADASS, HOLO_CIGAR)) - REMOVE_TRAIT(user, TRAIT_BADASS, HOLO_CIGAR) - to_chat(user, "You feel less badass.") - -/obj/item/clothing/mask/holo_cigar/attack_self__legacy__attackchain(mob/user) - . = ..() - if(enabled) - enabled = FALSE - to_chat(user, "You disable the holo-cigar.") - STOP_PROCESSING(SSobj, src) - else - enabled = TRUE - to_chat(user, "You enable the holo-cigar.") - START_PROCESSING(SSobj, src) - - update_appearance(UPDATE_ICON_STATE) - -////////////////////////////// -// MARK: PIPES -////////////////////////////// -/obj/item/clothing/mask/cigarette/pipe - name = "smoking pipe" - desc = "A pipe, for smoking. Probably made of meershaum or something." - icon_state = "pipeoff" - item_state = "pipeoff" - icon_on = "pipeon" //Note - these are in masks.dmi - icon_off = "pipeoff" - fancy_lighters = list(/obj/item/match, /obj/item/lighter/zippo) - smoketime = 500 - chem_volume = 200 - list_reagents = list("nicotine" = 200) - -/obj/item/clothing/mask/cigarette/pipe/die() - return - -/obj/item/clothing/mask/cigarette/pipe/light() - if(!lit) - lit = TRUE - damtype = "fire" - icon_state = icon_on - item_state = icon_on - START_PROCESSING(SSobj, src) - -/obj/item/clothing/mask/cigarette/pipe/process() - var/turf/location = get_turf(src) - smoketime-- - if(smoketime < 1) - new /obj/effect/decal/cleanable/ash(location) - if(ismob(loc)) - var/mob/living/M = loc - to_chat(M, "Your [name] goes out, and you empty the ash.") - lit = FALSE - icon_state = icon_off - item_state = icon_off - M.update_inv_wear_mask() - STOP_PROCESSING(SSobj, src) - return - smoke() - -/obj/item/clothing/mask/cigarette/pipe/attack_self__legacy__attackchain(mob/user) // Extinguishes the pipe. - if(lit) - user.visible_message( - "[user] puts out [src].", - "You put out [src]." - ) - lit = FALSE - first_puff = TRUE - icon_state = icon_off - item_state = icon_off - STOP_PROCESSING(SSobj, src) - return - -// Refill the pipe -/obj/item/clothing/mask/cigarette/pipe/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/food/grown)) - var/obj/item/food/grown/O = I - if(O.dry) - if(reagents.total_volume == reagents.maximum_volume) - to_chat(user, "[src] is full!") - return - O.reagents.trans_to(src, chem_volume) - to_chat(user, "You stuff the [O.name] into the pipe.") - smoketime = max(reagents.total_volume * REAGENT_TIME_RATIO, smoketime) - qdel(O) - else - to_chat(user, "You need to dry this first!") - return - - return ..() - -/obj/item/clothing/mask/cigarette/pipe/cobpipe - name = "corn cob pipe" - desc = "A nicotine delivery system popularized by folksy backwoodsmen and kept popular in the modern age and beyond by space hipsters." - icon_state = "cobpipeoff" - item_state = "cobpipeoff" - icon_on = "cobpipeon" //Note - these are in masks.dmi - icon_off = "cobpipeoff" - smoketime = 0 //there is nothing to smoke initially - chem_volume = 160 - list_reagents = list() - -#undef REAGENT_TIME_RATIO diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm deleted file mode 100644 index 599f9ee97d5bf..0000000000000 --- a/code/game/objects/items/weapons/clown_items.dm +++ /dev/null @@ -1,102 +0,0 @@ -/* Clown Items - * Contains: - * Banana Peels - * Soap - * Bike Horns - */ - -/* - * Bike Horns - */ - -/obj/item/bikehorn - name = "bike horn" - desc = "A horn off of a bicycle." - icon = 'icons/obj/items.dmi' - icon_state = "bike_horn" - item_state = "bike_horn" - hitsound = null - throwforce = 3 - w_class = WEIGHT_CLASS_TINY - var/list/honk_sounds = list('sound/items/bikehorn.ogg' = 1) - throw_speed = 3 - throw_range = 15 - attack_verb = list("HONKED") - -/obj/item/bikehorn/Initialize(mapload) - . = ..() - AddComponent(/datum/component/squeak, honk_sounds, 50, falloff_exponent = 20) //die off quick please - -/obj/item/bikehorn/airhorn - name = "air horn" - desc = "Damn son, where'd you find this?" - icon_state = "air_horn" - origin_tech = "materials=4;engineering=4" - honk_sounds = list('sound/items/airhorn2.ogg' = 1) - -/obj/item/bikehorn/golden - name = "golden bike horn" - desc = "Golden? Clearly, its made with bananium! Honk!" - icon_state = "gold_horn" - item_state = "gold_horn" - var/cooldown = 0 - -/obj/item/bikehorn/golden/attack__legacy__attackchain(mob/M, mob/user) - flip_mobs(user) - return ..() - -/obj/item/bikehorn/golden/attack_self__legacy__attackchain(mob/user) - flip_mobs(user) - ..() - -/obj/item/bikehorn/golden/proc/flip_mobs(mob/user) - if(cooldown >= world.time) - to_chat(user, "You can't make others flip yet!") - return - cooldown = world.time + 30 SECONDS - var/turf/T = get_turf(src) - for(var/mob/living/carbon/M in ohearers(7, T)) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(!H.can_hear()) - continue - M.emote("flip") - -#define LAUGH_COOLDOWN 30 SECONDS -#define LAUGH_COOLDOWN_CMAG 10 SECONDS - -/obj/item/clown_recorder - name = "clown recorder" - desc = "When you just can't get those laughs coming the natural way!" - icon = 'icons/obj/device.dmi' - icon_state = "clown_recorder" - item_state = "analyzer" - w_class = WEIGHT_CLASS_SMALL - slot_flags = ITEM_SLOT_BELT - materials = list(MAT_METAL = 180, MAT_GLASS = 90) - force = 2 - throwforce = 0 - drop_sound = 'sound/items/handling/taperecorder_drop.ogg' - pickup_sound = 'sound/items/handling/taperecorder_pickup.ogg' - actions_types = list(/datum/action/item_action/laugh_track) - var/cooldown = 0 - -/obj/item/clown_recorder/attack_self__legacy__attackchain(mob/user) - if(cooldown > world.time) - to_chat(user, "The tape is still winding back.") - return - playsound(src, pick('sound/voice/sitcom_laugh.ogg', 'sound/voice/sitcom_laugh2.ogg'), 50, FALSE) - if(!HAS_TRAIT(src, TRAIT_CMAGGED)) - cooldown = world.time + LAUGH_COOLDOWN - else - cooldown = world.time + LAUGH_COOLDOWN_CMAG - -/obj/item/clown_recorder/cmag_act(mob/user) - if(!HAS_TRAIT(src, TRAIT_CMAGGED)) - to_chat(user, "Winding back speed has been improved by the bananium ooze!") - ADD_TRAIT(src, TRAIT_CMAGGED, CLOWN_EMAG) - return TRUE - return FALSE - -#undef LAUGH_COOLDOWN -#undef LAUGH_COOLDOWN_CMAG diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm deleted file mode 100644 index 4b15f6244e5c5..0000000000000 --- a/code/game/objects/items/weapons/cosmetics.dm +++ /dev/null @@ -1,186 +0,0 @@ -/obj/item/lipstick - name = "red lipstick" - desc = "A generic brand of lipstick." - icon = 'icons/obj/items.dmi' - icon_state = "lipstick" - w_class = WEIGHT_CLASS_TINY - var/colour = "red" - var/open = FALSE - var/static/list/lipstick_colors - -/obj/item/lipstick/Initialize(mapload) - . = ..() - if(!lipstick_colors) - lipstick_colors = list( - "black" = "#000000", - "white" = "#FFFFFF", - "red" = "#FF0000", - "green" = "#00C000", - "blue" = "#0000FF", - "purple" = "#D55CD0", - "jade" = "#216F43", - "lime" = "#00FF00", - ) - -/obj/item/lipstick/purple - name = "purple lipstick" - colour = "purple" - -/obj/item/lipstick/jade - name = "jade lipstick" - colour = "jade" - -/obj/item/lipstick/lime - name = "lime lipstick" - colour = "lime" - -/obj/item/lipstick/black - name = "black lipstick" - colour = "black" - -/obj/item/lipstick/green - name = "green lipstick" - colour = "green" - -/obj/item/lipstick/blue - name = "blue lipstick" - colour = "blue" - -/obj/item/lipstick/white - name = "white lipstick" - colour = "white" - -/obj/item/lipstick/random - name = "lipstick" - -/obj/item/lipstick/random/Initialize(mapload) - . = ..() - colour = pick(lipstick_colors) - name = "[colour] lipstick" - -/obj/item/lipstick/attack_self__legacy__attackchain(mob/user) - cut_overlays() - to_chat(user, "You twist \the [src] [open ? "closed" : "open"].") - open = !open - if(open) - var/mutable_appearance/colored = mutable_appearance('icons/obj/items.dmi', "lipstick_uncap_color") - colored.color = lipstick_colors[colour] - icon_state = "lipstick_uncap" - add_overlay(colored) - else - icon_state = "lipstick" - -/obj/item/lipstick/attack__legacy__attackchain(mob/M, mob/user) - if(!open || !istype(M)) - return - - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.lip_style) // If they already have lipstick on - to_chat(user, "You need to wipe off the old lipstick first!") - return - if(H == user) - user.visible_message("[user] does [user.p_their()] lips with [src].", \ - "You take a moment to apply [src]. Perfect!") - H.lip_style = "lipstick" - H.lip_color = lipstick_colors[colour] - H.update_body() - else - user.visible_message("[user] begins to do [H]'s lips with \the [src].", \ - "You begin to apply \the [src].") - if(do_after(user, 20, target = H)) - user.visible_message("[user] does [H]'s lips with \the [src].", \ - "You apply \the [src].") - H.lip_style = "lipstick" - H.lip_color = lipstick_colors[colour] - H.update_body() - else - to_chat(user, "Where are the lips on that?") - -/obj/item/razor - name = "electric razor" - desc = "The latest and greatest power razor born from the science of shaving." - icon = 'icons/obj/items.dmi' - icon_state = "razor" - flags = CONDUCT - w_class = WEIGHT_CLASS_TINY - usesound = 'sound/items/welder2.ogg' - toolspeed = 1 - -/obj/item/razor/attack__legacy__attackchain(mob/living/carbon/M as mob, mob/user as mob) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/head/C = H.get_organ("head") - if(!istype(C)) - to_chat(user, "There's nothing to cut, [M] [M.p_are()] missing [M.p_their()] head!") - return ..() - var/datum/robolimb/robohead = GLOB.all_robolimbs[C.model] - if(user.zone_selected == "mouth") - if(!get_location_accessible(H, "mouth")) - to_chat(user, "The mask is in the way.") - return - if((C.dna.species.bodyflags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... - to_chat(user, "You find yourself disappointed at the appalling lack of facial hair.") - return - if(C.f_style == "Shaved") - to_chat(user, "Already clean-shaven.") - return - if(H == user) //shaving yourself - user.visible_message("[user] starts to shave [user.p_their()] facial hair with [src].", \ - "You take a moment shave your facial hair with \the [src].") - if(do_after(user, 50 * toolspeed, target = H)) - user.visible_message("[user] shaves [user.p_their()] facial hair clean with [src].", \ - "You finish shaving with [src]. Fast and clean!") - C.f_style = "Shaved" - H.update_fhair() - playsound(src.loc, usesound, 20, 1) - else - var/turf/user_loc = user.loc - var/turf/H_loc = H.loc - user.visible_message("[user] tries to shave [H]'s facial hair with \the [src].", \ - "You start shaving [H]'s facial hair.") - if(do_after(user, 50 * toolspeed, target = H)) - if(user_loc == user.loc && H_loc == H.loc) - user.visible_message("[user] shaves off [H]'s facial hair with \the [src].", \ - "You shave [H]'s facial hair clean off.") - C.f_style = "Shaved" - H.update_fhair() - playsound(src.loc, usesound, 20, 1) - if(user.zone_selected == "head") - if(!get_location_accessible(H, "head")) - to_chat(user, "The headgear is in the way.") - return - if((C.dna.species.bodyflags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... - to_chat(user, "You find yourself disappointed at the appalling lack of hair.") - return - if(C.h_style == "Bald" || C.h_style == "Balding Hair" || C.h_style == "Skinhead") - to_chat(user, "There is not enough hair left to shave...") - return - if(isskrell(M)) - to_chat(user, "Your razor isn't going to cut through tentacles.") - return - if(H == user) //shaving yourself - user.visible_message("[user] starts to shave [user.p_their()] head with [src].", \ - "You start to shave your head with \the [src].") - if(do_after(user, 50 * toolspeed, target = H)) - user.visible_message("[user] shaves [user.p_their()] head with [src].", \ - "You finish shaving with \the [src].") - C.h_style = "Skinhead" - H.update_hair() - playsound(src.loc, usesound, 40, 1) - else - var/turf/user_loc = user.loc - var/turf/H_loc = H.loc - user.visible_message("[user] tries to shave [H]'s head with \the [src]!", \ - "You start shaving [H]'s head.") - if(do_after(user, 50 * toolspeed, target = H)) - if(user_loc == user.loc && H_loc == H.loc) - user.visible_message("[user] shaves [H]'s head bald with \the [src]!", \ - "You shave [H]'s head bald.") - C.h_style = "Skinhead" - H.update_hair() - playsound(src.loc, usesound, 40, 1) - else - ..() - else - ..() diff --git a/code/game/objects/items/weapons/courtroom.dm b/code/game/objects/items/weapons/courtroom.dm deleted file mode 100644 index 07ba7116a9d9f..0000000000000 --- a/code/game/objects/items/weapons/courtroom.dm +++ /dev/null @@ -1,38 +0,0 @@ -// Contains: -// Gavel Hammer -// Gavel Block - -/obj/item/gavelhammer - name = "gavel hammer" - desc = "Order, order! No bombs in my courthouse." - icon = 'icons/obj/items.dmi' - icon_state = "gavelhammer" - force = 5.0 - throwforce = 6.0 - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("bashed", "battered", "judged", "whacked") - resistance_flags = FLAMMABLE - -/obj/item/gavelhammer/suicide_act(mob/user) - user.visible_message("[user] has sentenced [user.p_themselves()] to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/items/gavel.ogg', 50, TRUE, -1) - return BRUTELOSS - -/obj/item/gavelblock - name = "gavel block" - desc = "Smack it with a gavel hammer when the assistants get rowdy." - icon = 'icons/obj/items.dmi' - icon_state = "gavelblock" - force = 2.0 - throwforce = 2.0 - w_class = WEIGHT_CLASS_TINY - resistance_flags = FLAMMABLE - var/next_gavel_hit - -/obj/item/gavelblock/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(!istype(I, /obj/item/gavelhammer)) - return - if(world.time > next_gavel_hit) - playsound(loc, 'sound/items/gavel.ogg', 100, 1) - next_gavel_hit = world.time + 5 SECONDS - user.visible_message("[user] strikes \the [src] with \the [I].") diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm deleted file mode 100644 index 50424daac347d..0000000000000 --- a/code/game/objects/items/weapons/defib.dm +++ /dev/null @@ -1,441 +0,0 @@ -//backpack item - -/obj/item/defibrillator - name = "defibrillator" - desc = "A device that delivers powerful shocks to detachable paddles that resuscitate incapacitated patients." - icon = 'icons/obj/defib.dmi' - icon_state = "defibunit" - item_state = "defibunit" - slot_flags = ITEM_SLOT_BACK - force = 5 - throwforce = 6 - w_class = WEIGHT_CLASS_BULKY - origin_tech = "biotech=4" - actions_types = list(/datum/action/item_action/toggle_paddles) - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50) - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/back.dmi' - ) - - /// If the paddles are currently attached to the unit. - var/paddles_on_defib = TRUE - /// if there's a cell in the defib with enough power for a revive; blocks paddles from reviving otherwise - var/powered = FALSE - /// Ref to attached paddles - var/obj/item/shockpaddles/paddles - /// Ref to internal power cell. - var/obj/item/stock_parts/cell/high/cell = null - /// If false, using harm intent will let you zap people. Note that any updates to this after init will only impact icons. - var/safety = TRUE - /// If true, this can be used through hardsuits, and can cause heart attacks in harm intent. - var/combat = FALSE - // If safety is false and combat is true, the chance that this will cause a heart attack. - var/heart_attack_probability = 30 - /// If this is vulnerable to EMPs. - var/hardened = FALSE - /// If this can be emagged. - var/emag_proof = FALSE - - base_icon_state = "defibpaddles" - /// Type of paddles that should be attached to this defib. - var/obj/item/shockpaddles/paddle_type = /obj/item/shockpaddles - -/obj/item/defibrillator/get_cell() - return cell - -/obj/item/defibrillator/Initialize(mapload) // Base version starts without a cell for rnd - . = ..() - paddles = new paddle_type(src) - update_icon(UPDATE_OVERLAYS) - -/obj/item/defibrillator/loaded/Initialize(mapload) // Loaded version starts with high-capacity cell. - . = ..() - cell = new(src) - update_icon(UPDATE_OVERLAYS) - -/obj/item/defibrillator/update_icon(updates=ALL) - update_power() - ..() - -/obj/item/defibrillator/examine(mob/user) - . = ..() - . += "Alt-Click to remove the paddles from the defibrillator." - -/obj/item/defibrillator/proc/update_power() - if(cell) - if(cell.charge < paddles.revivecost) - powered = FALSE - else - powered = TRUE - else - powered = FALSE - -/obj/item/defibrillator/update_overlays() - . = ..() - if(paddles_on_defib) - . += "[icon_state]-paddles" - if(!safety) - . += "[icon_state]-emagged" - if(powered) - . += "[icon_state]-powered" - if(powered && cell) - var/ratio = cell.charge / cell.maxcharge - ratio = CEILING(ratio*4, 1) * 25 - . += "[icon_state]-charge[ratio]" - if(!cell) - . += "[icon_state]-nocell" - -/obj/item/defibrillator/CheckParts(list/parts_list) - ..() - cell = locate(/obj/item/stock_parts/cell) in contents - update_icon(UPDATE_OVERLAYS) - -/obj/item/defibrillator/ui_action_click(mob/user) - toggle_paddles(user) - -/obj/item/defibrillator/AltClick(mob/user) - if(ishuman(user) && Adjacent(user)) - toggle_paddles(user) - -/obj/item/defibrillator/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(istype(W, /obj/item/stock_parts/cell)) - var/obj/item/stock_parts/cell/C = W - if(cell) - to_chat(user, "[src] already has a cell.") - else - if(C.maxcharge < paddles.revivecost) - to_chat(user, "[src] requires a higher capacity cell.") - return - if(user.drop_item(C)) - W.forceMove(src) - cell = C - to_chat(user, "You install a cell in [src].") - if(W == paddles) - toggle_paddles(user) - - update_icon(UPDATE_OVERLAYS) - -/obj/item/defibrillator/screwdriver_act(mob/living/user, obj/item/I) - if(!cell) - to_chat(user, "[src] doesn't have a cell.") - return - - cell.update_icon() - cell.forceMove(get_turf(loc)) - cell = null - to_chat(user, "You remove the cell from [src].") - update_icon(UPDATE_OVERLAYS) - return TRUE - -/obj/item/defibrillator/emp_act(severity) - if(cell) - deductcharge(1000 / severity) - safety = !safety - update_icon(UPDATE_OVERLAYS) - ..() - -/obj/item/defibrillator/emag_act(mob/user) - safety = !safety - ..() - update_icon(UPDATE_OVERLAYS) - return TRUE - -/obj/item/defibrillator/proc/toggle_paddles(mob/living/carbon/human/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) - return - - if(paddles_on_defib) - //Detach the paddles into the user's hands - if(!user.put_in_hands(paddles)) - to_chat(user, "You need a free hand to hold the paddles!") - update_icon(UPDATE_OVERLAYS) - return - paddles.forceMove(user) - paddles_on_defib = FALSE - else if(user.is_in_active_hand(paddles)) - //Remove from their hands and back onto the defib unit - remove_paddles(user) - - update_icon(UPDATE_OVERLAYS) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtons() - -/obj/item/defibrillator/equipped(mob/user, slot) - ..() - if(slot != ITEM_SLOT_BACK) - remove_paddles(user) - update_icon(UPDATE_OVERLAYS) - -/obj/item/defibrillator/item_action_slot_check(slot, mob/user) - if(slot == ITEM_SLOT_BACK) - return TRUE - -/obj/item/defibrillator/proc/remove_paddles(mob/user) // from your hands - var/mob/living/carbon/human/M = user - if(paddles in get_both_hands(M)) - M.drop_item_to_ground(paddles) - paddles_on_defib = TRUE - update_icon(UPDATE_OVERLAYS) - return - -/obj/item/defibrillator/Destroy() - if(!paddles_on_defib) - var/M = get(paddles, /mob) - remove_paddles(M) - QDEL_NULL(paddles) - QDEL_NULL(cell) - return ..() - -/obj/item/defibrillator/proc/deductcharge(chrgdeductamt) - if(cell) - if(cell.charge < (paddles.revivecost+chrgdeductamt)) - powered = FALSE - update_icon(UPDATE_OVERLAYS) - if(cell.use(chrgdeductamt)) - update_icon(UPDATE_OVERLAYS) - return TRUE - else - update_icon(UPDATE_OVERLAYS) - return FALSE - -/obj/item/defibrillator/compact - name = "compact defibrillator" - desc = "A belt-mounted defibrillator that can be rapidly deployed." - icon_state = "defibcompact" - item_state = "defibcompact" - sprite_sheets = null //Because Vox had the belt defibrillator sprites in back.dm - w_class = WEIGHT_CLASS_NORMAL - slot_flags = ITEM_SLOT_BELT - flags_2 = ALLOW_BELT_NO_JUMPSUIT_2 - origin_tech = "biotech=5" - -/obj/item/defibrillator/compact/loaded/Initialize(mapload) - . = ..() - cell = new(src) - update_icon(UPDATE_OVERLAYS) - -/obj/item/defibrillator/compact/item_action_slot_check(slot, mob/user) - if(slot == ITEM_SLOT_BELT) - return TRUE - -/obj/item/defibrillator/compact/combat - name = "combat defibrillator" - desc = "A belt-mounted blood-red defibrillator that can be rapidly deployed. Does not have the restrictions or safeties of conventional defibrillators and can revive through space suits." - icon_state = "defibcombat" - item_state = "defibcombat" - paddle_type = /obj/item/shockpaddles/syndicate - combat = TRUE - safety = FALSE - heart_attack_probability = 100 - -/obj/item/defibrillator/compact/combat/loaded/Initialize(mapload) - . = ..() - cell = new(src) - update_icon(UPDATE_OVERLAYS) - -/obj/item/defibrillator/compact/advanced - name = "advanced compact defibrillator" - desc = "A belt-mounted state-of-the-art defibrillator that can be rapidly deployed in all environments. The casing is EMP-shielded and heavily reinforced, making it immune to most sources of damage." - icon_state = "defibnt" - item_state = "defibnt" - paddle_type = /obj/item/shockpaddles/advanced - combat = TRUE - safety = TRUE - hardened = TRUE // EMP-proof (on the component), but not emag-proof. - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF // Objective item, better not have it destroyed. - heart_attack_probability = 10 - origin_tech = null - /// To prevent spam from the emagging message on the advanced defibrillator. - var/next_emp_message - -/obj/item/defibrillator/compact/advanced/examine(mob/user) - . = ..() - . += "[src] uses an experimental self-charging cell, meaning that it will (probably) never stop working." - . += "The advanced paddles can be used to defibrillate through space suits." - -/obj/item/defibrillator/compact/advanced/examine_more(mob/user) - . = ..() - . += "The Advanced Compact Defibrillator is Nanotrasen Medical's greatest refinement of electroshock revival technology. Featuring heavy electromagnetic shielding and a reinforced plastitanium chassis, \ - it is both lightweight and extremely resistant to abuse, easily able to handle the most hostile of environments." - . += "" - . += "The two standout features of the ACD are the experimental self-charging power source - which gives it an effectively unlimited endurance - and the special breakdown paddles, \ - capable of transmitting a therapeutic shock through even thick hardsuit plating, allowing casualties to be revived without having to strip their equipment." - . += "" - . += "Whilst the ACD is currently too expensive for mass-market deployment, Nanotrasen hopes that later developments in its manufacturing capabilities will enable it to economically launch this product commercially." - -/obj/item/defibrillator/compact/advanced/screwdriver_act(mob/living/user, obj/item/I) - return // The cell is too strong roundstart and we dont want the adv defib to become useless - -/obj/item/defibrillator/compact/advanced/loaded/Initialize(mapload) - . = ..() - cell = new /obj/item/stock_parts/cell/bluespace/charging(src) - update_icon(UPDATE_OVERLAYS) - AddElement(/datum/element/high_value_item) - -/obj/item/defibrillator/compact/advanced/emp_act(severity) - if(world.time > next_emp_message) - atom_say("Warning: Electromagnetic pulse detected. Integrated shielding prevented all potential hardware damage.") - playsound(src, 'sound/machines/defib_saftyon.ogg', 50) - next_emp_message = world.time + 5 SECONDS - -//paddles - -/obj/item/shockpaddles - name = "defibrillator paddles" - desc = "A pair of plastic-gripped paddles with flat metal surfaces that are used to deliver powerful electric shocks." - icon = 'icons/obj/defib.dmi' - icon_state = "defibpaddles0" - item_state = "defibpaddles0" - force = 0 - throwforce = 6 - w_class = WEIGHT_CLASS_BULKY - resistance_flags = INDESTRUCTIBLE - toolspeed = 1 - base_icon_state = "defibpaddles" - /// Amount of power used on a shock. - var/revivecost = 1000 - /// Active defib this is connected to. - var/obj/item/defibrillator/defib - /// Whether or not the paddles are on cooldown. Used for tracking icon states. - var/on_cooldown = FALSE - - -/obj/item/shockpaddles/New(mainunit) - . = ..() - - if(check_defib_exists(mainunit, null, src)) - defib = mainunit - loc = defib - update_icon(UPDATE_ICON_STATE) - AddComponent(/datum/component/defib, actual_unit = defib, combat = defib.combat, safe_by_default = defib.safety, heart_attack_chance = defib.heart_attack_probability, emp_proof = defib.hardened, emag_proof = defib.emag_proof) - else - AddComponent(/datum/component/defib) - RegisterSignal(src, COMSIG_DEFIB_READY, PROC_REF(on_cooldown_expire)) - RegisterSignal(src, COMSIG_DEFIB_SHOCK_APPLIED, PROC_REF(after_shock)) - RegisterSignal(src, COMSIG_DEFIB_PADDLES_APPLIED, PROC_REF(on_application)) - AddComponent(/datum/component/two_handed) - -/obj/item/shockpaddles/Destroy() - defib = null - return ..() - -/// Check to see if we should abort this before we've even gotten started -/obj/item/shockpaddles/proc/on_application(obj/item/paddles, mob/living/user, mob/living/carbon/human/target, should_cause_harm) - SIGNAL_HANDLER // COMSIG_DEFIB_PADDLES_APPLIED - - if(!HAS_TRAIT(src, TRAIT_WIELDED)) - to_chat(user, "You need to wield the paddles in both hands before you can use them on someone!") - return COMPONENT_BLOCK_DEFIB_MISC - if(!defib.powered) - return COMPONENT_BLOCK_DEFIB_DEAD - - return - -/obj/item/shockpaddles/proc/on_cooldown_expire(obj/item/paddles) - SIGNAL_HANDLER // COMSIG_DEFIB_READY - on_cooldown = FALSE - if(defib.cell) - if(defib.cell.charge >= revivecost) - defib.visible_message("[defib] beeps: Unit ready.") - playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50, 0) - else - defib.visible_message("[defib] beeps: Charge depleted.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - update_icon(UPDATE_ICON_STATE) - defib.update_icon(UPDATE_ICON_STATE) - -/obj/item/shockpaddles/proc/after_shock() - SIGNAL_HANDLER // COMSIG_DEFIB_SHOCK_APPLIED - on_cooldown = TRUE - defib.deductcharge(revivecost) - update_icon(UPDATE_ICON_STATE) - -/obj/item/shockpaddles/update_icon_state() - var/wielded = HAS_TRAIT(src, TRAIT_WIELDED) - icon_state = "[base_icon_state][wielded]" - item_state = "[base_icon_state][wielded]" - if(on_cooldown) - icon_state = "[base_icon_state][wielded]_cooldown" - -/obj/item/shockpaddles/suicide_act(mob/user) - user.visible_message("[user] is putting the live paddles on [user.p_their()] chest! It looks like [user.p_theyre()] trying to commit suicide!") - defib.deductcharge(revivecost) - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, TRUE, -1) - return OXYLOSS - -/obj/item/shockpaddles/dropped(mob/user) - ..() - if(user) - to_chat(user, "The paddles snap back into the main unit.") - defib.paddles_on_defib = TRUE - loc = defib - defib.update_icon(UPDATE_OVERLAYS) - update_icon(UPDATE_ICON_STATE) - -/obj/item/shockpaddles/on_mob_move(dir, mob/user) - if(defib) - if(!isturf(user.loc)) - // You went inside something. It blocks the cable. - // (This also means we don't have to listen for the - // surrounding object's movements.) - defib.remove_paddles(user) - - var/turf/t = get_turf(defib) - if(!t.Adjacent(user)) - defib.remove_paddles(user) - -/obj/item/shockpaddles/proc/check_defib_exists(mainunit, mob/living/carbon/human/M, obj/O) - if(!mainunit || !istype(mainunit, /obj/item/defibrillator)) //To avoid weird issues from admin spawns - M?.unequip(O) - qdel(O) - return FALSE - else - return TRUE - -/obj/item/borg_defib - name = "defibrillator paddles" - desc = "A pair of paddles with flat metal surfaces that are used to deliver powerful electric shocks." - icon = 'icons/obj/defib.dmi' - icon_state = "defibpaddles0" - item_state = "defibpaddles0" - force = 0 - w_class = WEIGHT_CLASS_BULKY - var/revivecost = 1000 - var/safety = TRUE - flags = NODROP - toolspeed = 1 - -/obj/item/borg_defib/Initialize(mapload) - . = ..() - AddComponent(/datum/component/defib, robotic = TRUE, safe_by_default = safety, emp_proof = TRUE) - - RegisterSignal(src, COMSIG_DEFIB_READY, PROC_REF(on_cooldown_expire)) - RegisterSignal(src, COMSIG_DEFIB_SHOCK_APPLIED, PROC_REF(after_shock)) - -/obj/item/borg_defib/proc/after_shock(obj/item/defib, mob/user) - SIGNAL_HANDLER // COMSIG_DEFIB_SHOCK_APPLIED - if(isrobot(user)) - var/mob/living/silicon/robot/R = user - R.cell.use(revivecost) - update_icon(UPDATE_ICON_STATE) - -/obj/item/borg_defib/proc/on_cooldown_expire(obj/item/defib) - SIGNAL_HANDLER // COMSIG_DEFIB_READY - visible_message("[src] beeps: Defibrillation unit ready.") - playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50, 0) - update_icon(UPDATE_ICON_STATE) - -/obj/item/shockpaddles/syndicate - name = "combat defibrillator paddles" - desc = "A pair of high-tech paddles with flat plasteel surfaces to revive deceased operatives (unless they exploded). They possess both the ability to penetrate armor and to deliver powerful or disabling shocks offensively." - icon_state = "syndiepaddles0" - item_state = "syndiepaddles0" - base_icon_state = "syndiepaddles" - -/obj/item/shockpaddles/advanced - name = "advanced defibrillator paddles" - desc = "A pair of high-tech paddles with flat plasteel surfaces that are used to deliver powerful electric shocks. They possess the ability to penetrate armor to deliver shock." - icon_state = "ntpaddles0" - item_state = "ntpaddles0" - base_icon_state = "ntpaddles" diff --git a/code/game/objects/items/weapons/disks.dm b/code/game/objects/items/weapons/disks.dm deleted file mode 100644 index e81e6f58732b2..0000000000000 --- a/code/game/objects/items/weapons/disks.dm +++ /dev/null @@ -1,74 +0,0 @@ -/obj/item/disk - icon = 'icons/obj/module.dmi' - w_class = WEIGHT_CLASS_TINY - item_state = "card-id" - icon_state = "datadisk0" - drop_sound = 'sound/items/handling/disk_drop.ogg' - pickup_sound = 'sound/items/handling/disk_pickup.ogg' - -/obj/item/disk/data - name = "Cloning Data Disk" - icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk. - var/datum/dna2_record/buf = null - var/read_only = FALSE //Well,it's still a floppy disk - -/obj/item/disk/data/proc/initialize_data() - buf = new - buf.dna = new - -/obj/item/disk/data/Destroy() - QDEL_NULL(buf) - return ..() - -/obj/item/disk/data/demo - name = "data disk - 'God Emperor of Mankind'" - read_only = TRUE - -/obj/item/disk/data/demo/New() - . = ..() - initialize_data() - buf.types = DNA2_BUF_UE|DNA2_BUF_UI - buf.dna.real_name = "God Emperor of Mankind" - buf.dna.unique_enzymes = md5(buf.dna.real_name) - buf.dna.UI = list(0x066,0x000,0x033,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0xAF0,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x033,0x066,0x0FF,0x4DB,0x002,0x690,0x000,0x000,0x000,0x328,0x045,0x5FC,0x053,0x035,0x035,0x035) - if(length(buf.dna.UI) != DNA_UI_LENGTH) //If there's a disparity b/w the dna UI string lengths, 0-fill the extra blocks in this UI. - for(var/i in length(buf.dna.UI) to DNA_UI_LENGTH) - buf.dna.UI += 0x000 - buf.dna.ResetSE() - buf.dna.UpdateUI() - -/obj/item/disk/data/monkey - name = "data disk - 'Mr. Muggles'" - read_only = 1 - -/obj/item/disk/data/monkey/New() - . = ..() - initialize_data() - buf.types = DNA2_BUF_SE - var/list/new_SE = list(0x098,0x3E8,0x403,0x44C,0x39F,0x4B0,0x59D,0x514,0x5FC,0x578,0x5DC,0x640,0x6A4) - for(var/i = length(new_SE); i <= DNA_SE_LENGTH; i++) - new_SE += rand(1, 1024) - buf.dna.SE = new_SE - buf.dna.SetSEValueRange(GLOB.monkeyblock, 0xDAC, 0xFFF) - -//Disk stuff. -/obj/item/disk/data/New() - . = ..() - var/diskcolor = pick(0, 1, 2, 3, 4, 5) - icon_state = "datadisk[diskcolor]" - -/obj/item/disk/data/attack_self__legacy__attackchain(mob/user) - read_only = !read_only - to_chat(user, "You flip the write-protect tab to [read_only ? "protected" : "unprotected"].") - -/obj/item/disk/data/examine(mob/user) - . = ..() - . += "The write-protect tab is set to [read_only ? "protected" : "unprotected"]." - -/obj/item/storage/box/disks - name = "Diskette Box" - icon_state = "disk_box" - -/obj/item/storage/box/disks/populate_contents() - for(var/i in 1 to 7) - new /obj/item/disk/data(src) diff --git a/code/game/objects/items/weapons/dnascrambler.dm b/code/game/objects/items/weapons/dnascrambler.dm deleted file mode 100644 index ba362a3a4a235..0000000000000 --- a/code/game/objects/items/weapons/dnascrambler.dm +++ /dev/null @@ -1,49 +0,0 @@ -/obj/item/dnascrambler - name = "dna scrambler" - desc = "An illegal genetic serum designed to randomize the user's identity." - icon = 'icons/obj/hypo.dmi' - item_state = "syringe_0" - icon_state = "lepopen" - var/used = FALSE - -/obj/item/dnascrambler/update_icon_state() - if(used) - icon_state = "lepopen0" - else - icon_state = "lepopen" - -/obj/item/dnascrambler/attack__legacy__attackchain(mob/M as mob, mob/user as mob) - if(!M || !user) - return - - if(!ishuman(M) || !ishuman(user)) - return - - if(used) - return - - if(HAS_TRAIT(M, TRAIT_GENELESS)) - to_chat(user, "You failed to inject [M], as [M.p_they()] [M.p_have()] no DNA to scramble, nor flesh to inject.") - return - - if(M == user) - user.visible_message("[user] injects [user.p_themselves()] with [src]!") - injected(user, user) - else - user.visible_message("[user] is trying to inject [M] with [src]!") - if(do_mob(user,M,30)) - user.visible_message("[user] injects [M] with [src].") - injected(M, user) - else - to_chat(user, "You failed to inject [M].") - -/obj/item/dnascrambler/proc/injected(mob/living/carbon/human/target, mob/living/carbon/user) - if(istype(target)) - var/mob/living/carbon/human/H = target - H.get_dna_scrambled() - target.update_icons() - - add_attack_logs(user, target, "injected with [src]") - used = TRUE - update_icon(UPDATE_ICON_STATE) - name = "used " + name diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm deleted file mode 100644 index f71ede24473dc..0000000000000 --- a/code/game/objects/items/weapons/explosives.dm +++ /dev/null @@ -1,279 +0,0 @@ -/obj/item/grenade/plastic - name = "plastic explosive" - desc = "Used to put holes in specific areas without too much extra hole." - icon_state = "plastic-explosive0" - item_state = "plastic-explosive" - flags = NOBLUDGEON - det_time = 10 - display_timer = FALSE - origin_tech = "syndicate=1" - toolspeed = 1 - var/atom/target = null - var/image_overlay = null - var/obj/item/assembly/nadeassembly = null - var/assemblyattacher - var/notify_admins = TRUE - /// C4 overlay to put on target - var/mutable_appearance/plastic_overlay - /// Target of the overlay, not neccicarly the thing the C4 is attached to! - var/atom/plastic_overlay_target - -/obj/item/grenade/plastic/Initialize(mapload) - . = ..() - plastic_overlay = mutable_appearance(icon, "[item_state]2", HIGH_OBJ_LAYER) - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered) - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/item/grenade/plastic/Destroy() - QDEL_NULL(nadeassembly) - target = null - plastic_overlay_target = null - return ..() - -/obj/item/grenade/plastic/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(!nadeassembly && istype(I, /obj/item/assembly)) - var/obj/item/assembly/A = I - if(!user.transfer_item_to(A, src)) - return ..() - nadeassembly = A - A.master = src - assemblyattacher = user.ckey - to_chat(user, "You add [A] to [src].") - playsound(src, 'sound/weapons/tap.ogg', 20, 1) - update_icon(UPDATE_ICON_STATE) - return - if(nadeassembly && istype(I, /obj/item/wirecutters)) - playsound(src, I.usesound, 20, 1) - nadeassembly.loc = get_turf(src) - nadeassembly.master = null - nadeassembly = null - update_icon(UPDATE_ICON_STATE) - return - ..() - -/obj/item/grenade/plastic/proc/on_atom_entered(datum/source, atom/movable/entered) - if(nadeassembly) - nadeassembly.on_atom_entered(source, entered) - -/obj/item/grenade/plastic/on_found(mob/finder) - if(nadeassembly) - nadeassembly.on_found(finder) - -/obj/item/grenade/plastic/attack_self__legacy__attackchain(mob/user) - if(nadeassembly) - nadeassembly.attack_self__legacy__attackchain(user) - return - var/newtime = input(usr, "Please set the timer.", "Timer", det_time) as num - if(user.is_in_active_hand(src)) - newtime = clamp(newtime, 10, 60000) - det_time = newtime - to_chat(user, "Timer set for [det_time] seconds.") - -/obj/item/grenade/plastic/afterattack__legacy__attackchain(mob/AM, mob/user, flag) - if(!flag) - return - if(ismob(AM) && AM.stat == CONSCIOUS) - to_chat(user, "You can't get the [src] to stick to [AM]! Perhaps if [AM] was asleep or dead you could attach it?") - return - if(isstorage(AM) || ismodcontrol(AM)) - return ..() //Let us not have people c4 themselfs. Especially with a now 1.5 second do_after - if(isobserver(AM)) - to_chat(user, "Your hand just phases through [AM]!") - return - to_chat(user, "You start planting [src].[isnull(nadeassembly) ? " The timer is set to [det_time]..." : ""]") - - if(do_after(user, 1.5 SECONDS * toolspeed, target = AM)) - if(!user.unequip(src)) - return - - target = AM - loc = null - - if(notify_admins) - message_admins("[ADMIN_LOOKUPFLW(user)] planted [name] on [target.name] at ([target.x],[target.y],[target.z] - JMP) with [det_time] second fuse", 0, 1) - log_game("[key_name(user)] planted [name] on [target.name] at ([target.x],[target.y],[target.z]) with [det_time] second fuse") - - plastic_overlay.layer = HIGH_OBJ_LAYER - if(isturf(target) || isairlock(target)) - plastic_overlay_target = new /obj/effect/plastic(get_turf(user)) - else - plastic_overlay_target = target - if(isliving(target)) - plastic_overlay.layer = ABOVE_ALL_MOB_LAYER - if(plastic_overlay_target != target) - switch(plastic_overlay_target.x - target.x) - if(-1) - plastic_overlay.pixel_x += 32 - if(1) - plastic_overlay.pixel_x -= 32 - switch(plastic_overlay_target.y - target.y) - if(-1) - plastic_overlay.pixel_y += 32 - if(1) - plastic_overlay.pixel_y -= 32 - plastic_overlay_target.add_overlay(plastic_overlay) - - if(!nadeassembly) - to_chat(user, "You plant the bomb. Timer counting down from [det_time].") - addtimer(CALLBACK(src, PROC_REF(prime)), det_time SECONDS) - -/obj/item/grenade/plastic/suicide_act(mob/user) - message_admins("[key_name_admin(user)]([ADMIN_QUE(user,"?")]) ([ADMIN_FLW(user,"FLW")]) suicided with [src.name] at ([user.x],[user.y],[user.z] - JMP)",0,1) - log_game("[key_name(user)] suicided with [name] at ([user.x],[user.y],[user.z])") - user.visible_message("[user] activates [src] and holds it above [user.p_their()] head! It looks like [user.p_theyre()] going out with a bang!") - var/message_say = "FOR NO RAISIN!" - if(user.mind) - if(user.mind.special_role) - var/role = lowertext(user.mind.special_role) - if(role == ROLE_TRAITOR || role == "syndicate" || role == "syndicate commando") - message_say = "FOR THE SYNDICATE!" - else if(role == ROLE_CHANGELING) - message_say = "FOR THE HIVE!" - else if(role == ROLE_CULTIST) - message_say = "FOR NARSIE!" - else if(role == ROLE_WIZARD) - message_say = "FOR THE FEDERATION!" - else if(role == ROLE_REV || role == "head revolutionary") - message_say = "FOR THE REVOLUTION!" - else if(role == SPECIAL_ROLE_DEATHSQUAD || role == ROLE_ERT) - message_say = "FOR NANOTRASEN!" - user.say(message_say) - target = user - sleep(10) - prime() - user.gib() - return OBLITERATION - -/obj/item/grenade/plastic/update_icon_state() - if(nadeassembly) - icon_state = "[item_state]1" - else - icon_state = "[item_state]0" - -////////////////////////// -///// The Explosives ///// -////////////////////////// - -/obj/item/grenade/plastic/c4 - name = "C4" - desc = "Used to put holes in specific areas without too much extra hole. A saboteurs favourite." - /// If set to true, the secondary explosion will be centered two tiles behind the wall/object it's set on for a targeted breach and entry. - var/shaped = FALSE - /// Set when installing the charge, to know which direction to explode to when setting up a shaped c4 - var/aim_dir - /// Range values given to the explosion proc when primed - var/ex_devastate = 0 - var/ex_heavy = 0 - var/ex_light = 3 - /// Will the explosion cause a breach. C4 placed on floors will always cause a breach, regardless of this value. - var/ex_breach = FALSE - -/obj/item/grenade/plastic/c4/afterattack__legacy__attackchain(atom/movable/AM, mob/user, flag) - aim_dir = get_dir(user, AM) - ..() - -/obj/item/grenade/plastic/c4/prime() - var/turf/location - if(plastic_overlay_target && !QDELETED(plastic_overlay_target)) - plastic_overlay_target.cut_overlay(plastic_overlay, TRUE) - if(istype(plastic_overlay_target, /obj/effect/plastic)) - qdel(plastic_overlay_target) - if(target) - if(!QDELETED(target)) - location = get_turf(target) - if(!ex_breach && iswallturf(target)) //Walls get dismantled instead of destroyed to avoid making unwanted holes to space. - var/turf/simulated/wall/W = target - W.dismantle_wall(TRUE, TRUE) - else - target.ex_act(EXPLODE_DEVASTATE) - else - location = get_turf(src) - if(location) - if(shaped && aim_dir) - location = get_step(get_step(location, aim_dir), aim_dir) //Move the explosion location two steps away from the target when using a shaped c4 - explosion(location, ex_devastate, ex_heavy, ex_light, breach = ex_breach) - - qdel(src) - -// X4 is an upgraded directional variant of c4 which is relatively safe to be standing next to. And much less safe to be standing on the other side of. -// C4 is intended to be used for infiltration, and destroying tech. X4 is intended to be used for heavy breaching and tight spaces. -// Intended to replace C4 for nukeops, and to be a randomdrop in surplus/random traitor purchases. - -/obj/item/grenade/plastic/c4/x4 - name = "X4" - desc = "A specialized shaped high explosive breaching charge. Designed to be safer for the user, and less so, for the wall." - icon_state = "plasticx40" - item_state = "plasticx4" - shaped = TRUE - ex_heavy = 2 - ex_breach = TRUE - -// Shaped charge -// Same blasting power as C4, but with the same idea as the X4 -- Everyone on one side of the wall is safe. - -/obj/item/grenade/plastic/c4/shaped - name = "C4 (shaped)" - desc = "A brick of C4 shaped to allow more precise breaching." - shaped = TRUE - -/obj/item/grenade/plastic/c4/shaped/flash - name = "C4 (flash)" - desc = "A C4 charge with an altered chemical composition, designed to blind and deafen the occupants of a room before breaching." - -/obj/item/grenade/plastic/c4/shaped/flash/prime() - var/turf/T - if(target && target.density) - T = get_step(get_turf(target), aim_dir) - else if(target) - T = get_turf(target) - else - T = get_turf(src) - - var/obj/item/grenade/flashbang/CB = new/obj/item/grenade/flashbang(T) - CB.prime() - - ..() - -/obj/item/grenade/plastic/c4/thermite - name = "T4" - desc = "A wall breaching charge, containing fuel, metal oxide and metal powder mixed in just the right way. One hell of a combination. Effective against walls, ineffective against airlocks..." - det_time = 2 - icon_state = "t4breach0" - item_state = "t4breach" - -/obj/item/grenade/plastic/c4/thermite/prime() - var/turf/location - if(plastic_overlay_target && !QDELETED(plastic_overlay_target)) - plastic_overlay_target.cut_overlay(plastic_overlay, TRUE) - if(istype(plastic_overlay_target, /obj/effect/plastic)) - qdel(plastic_overlay_target) - if(target) - if(!QDELETED(target)) - location = get_turf(target) - else - location = get_turf(src) - if(location) - var/datum/effect_system/smoke_spread/smoke = new - smoke.set_up(8, FALSE, location, aim_dir) - if(target && target.density) - var/turf/T = get_step(location, aim_dir) - for(var/turf/simulated/wall/W in range(1, location)) - W.thermitemelt(speed = 30) - addtimer(CALLBACK(null, GLOBAL_PROC_REF(explosion), T, 0, 0, 2), 3) - addtimer(CALLBACK(smoke, TYPE_PROC_REF(/datum/effect_system/smoke_spread, start)), 3) - else - var/turf/T = get_step(location, aim_dir) - addtimer(CALLBACK(null, GLOBAL_PROC_REF(explosion), T, 0, 0, 2), 3) - addtimer(CALLBACK(smoke, TYPE_PROC_REF(/datum/effect_system/smoke_spread, start)), 3) - - if(isliving(target)) - var/mob/living/M = target - M.adjust_fire_stacks(2) - M.IgniteMob() - qdel(src) - -//Used so the effect is visable for overlay purposes, but not show on right click with a broken sprite -/obj/effect/plastic - mouse_opacity = MOUSE_OPACITY_TRANSPARENT diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm deleted file mode 100644 index 88ffb6d244701..0000000000000 --- a/code/game/objects/items/weapons/extinguisher.dm +++ /dev/null @@ -1,169 +0,0 @@ -/obj/item/extinguisher - name = "fire extinguisher" - desc = "A traditional red fire extinguisher." - icon = 'icons/obj/items.dmi' - icon_state = "fire_extinguisher0" - item_state = "fire_extinguisher" - base_icon_state = "fire_extinguisher" - hitsound = 'sound/weapons/smash.ogg' - flags = CONDUCT - throwforce = 10 - w_class = WEIGHT_CLASS_NORMAL - throw_speed = 2 - throw_range = 7 - force = 10 - container_type = AMOUNT_VISIBLE - materials = list(MAT_METAL = 200) - attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed") - dog_fashion = /datum/dog_fashion/back - resistance_flags = FIRE_PROOF - var/max_water = 50 - var/safety = TRUE - var/refilling = FALSE - /// FALSE by default, turfs picked from a spray are random, set to TRUE to make it always have at least one water effect per row - var/precision = FALSE - var/cooling_power = 2 //Sets the cooling_temperature of the water reagent datum inside of the extinguisher when it is refilled - COOLDOWN_DECLARE(last_use) - -/obj/item/extinguisher/mini - name = "pocket fire extinguisher" - desc = "A light and compact fibreglass-framed model fire extinguisher." - icon_state = "miniFE0" - item_state = "miniFE" - base_icon_state = "miniFE" - hitsound = null //it is much lighter, after all. - flags = null //doesn't CONDUCT - throwforce = 2 - w_class = WEIGHT_CLASS_SMALL - force = 3 - materials = list() - max_water = 30 - dog_fashion = null - -/obj/item/extinguisher/examine(mob/user) - . = ..() - . += "The safety is [safety ? "on" : "off"]." - - -/obj/item/extinguisher/Initialize(mapload) - . = ..() - if(!reagents) - create_reagents(max_water) - reagents.add_reagent("water", max_water) - ADD_TRAIT(src, TRAIT_CAN_POINT_WITH, ROUNDSTART_TRAIT) - -/obj/item/extinguisher/attack_self__legacy__attackchain(mob/user as mob) - safety = !safety - icon_state = "[base_icon_state][!safety]" - to_chat(user, "You [safety ? "enable" : "disable"] [src]'s safety.") - -/obj/item/extinguisher/attack_obj__legacy__attackchain(obj/O, mob/living/user, params) - if(AttemptRefill(O, user)) - refilling = TRUE - return FALSE - else - return ..() - -/obj/item/extinguisher/proc/AttemptRefill(atom/target, mob/user) - if(!istype(target, /obj/structure/reagent_dispensers/watertank) || !target.Adjacent(user)) - return FALSE - var/old_safety = safety - safety = TRUE - if(reagents.total_volume == reagents.maximum_volume) - to_chat(user, "\The [src] is already full!") - safety = old_safety - return TRUE - var/obj/structure/reagent_dispensers/watertank/W = target - var/transferred = W.reagents.trans_to(src, max_water) - if(transferred > 0) - to_chat(user, "\The [src] has been refilled by [transferred] units.") - playsound(loc, 'sound/effects/refill.ogg', 50, TRUE, -6) - for(var/datum/reagent/water/R in reagents.reagent_list) - R.cooling_temperature = cooling_power - else - to_chat(user, "\The [W] is empty!") - safety = old_safety - return TRUE - -/obj/item/extinguisher/afterattack__legacy__attackchain(atom/target, mob/user, flag) - . = ..() - //TODO; Add support for reagents in water. - if(target.loc == user)//No more spraying yourself when putting your extinguisher away - return - - if(refilling) - refilling = FALSE - return - - if(safety) - return ..() - if(reagents.total_volume < 1) - to_chat(user, "[src] is empty.") - return - - if(!COOLDOWN_FINISHED(src, last_use)) - return - - COOLDOWN_START(src, last_use, 2 SECONDS) - - if(reagents.chem_temp > 300 || reagents.chem_temp < 280) - add_attack_logs(user, target, "Sprayed with superheated or cooled fire extinguisher at Temperature [reagents.chem_temp]K") - playsound(loc, 'sound/effects/extinguish.ogg', 75, TRUE, -3) - - var/direction = get_dir(src, target) - - if(isobj(user.buckled) && !user.buckled.anchored && !istype(user.buckled, /obj/vehicle)) - INVOKE_ASYNC(src, PROC_REF(buckled_speed_move), user.buckled, direction) - else - user.newtonian_move(turn(direction, 180)) - - 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) - if(precision) - var/turf/T3 = get_step(T1, turn(direction, 90)) - var/turf/T4 = get_step(T2, turn(direction, -90)) - the_targets = list(T, T1, T2, T3, T4) - - for(var/a in 1 to 5) - var/obj/effect/particle_effect/water/water = new /obj/effect/particle_effect/water(get_turf(src)) - water.create_reagents(5) - reagents.trans_to(water, 1) - var/turf/new_target = pick(the_targets) - if(precision) - the_targets -= new_target - INVOKE_ASYNC(water, TYPE_PROC_REF(/obj/effect/particle_effect/water, extinguish_move), new_target) - -/obj/item/extinguisher/cyborg_recharge(coeff, emagged) - reagents.check_and_add("water", max_water, 5 * coeff) - -/obj/item/extinguisher/proc/buckled_speed_move(obj/structure/chair/buckled_to, direction) // Buckled_to may not be a chair here, but we're assuming so because it makes it easier to typecheck - var/movementdirection = turn(direction, 180) - if(istype(buckled_to)) - buckled_to.propelled = 4 - step(buckled_to, movementdirection) - sleep(1) - step(buckled_to, movementdirection) - if(istype(buckled_to)) - buckled_to.propelled = 3 - sleep(1) - step(buckled_to, movementdirection) - sleep(1) - step(buckled_to, movementdirection) - if(istype(buckled_to)) - buckled_to.propelled = 2 - sleep(2) - step(buckled_to, movementdirection) - if(istype(buckled_to)) - buckled_to.propelled = 1 - sleep(2) - step(buckled_to, movementdirection) - if(istype(buckled_to)) - buckled_to.propelled = 0 - sleep(3) - step(buckled_to, movementdirection) - sleep(3) - step(buckled_to, movementdirection) - sleep(3) - step(buckled_to, movementdirection) diff --git a/code/game/objects/items/weapons/garrote.dm b/code/game/objects/items/weapons/garrote.dm deleted file mode 100644 index a36a2be9779ac..0000000000000 --- a/code/game/objects/items/weapons/garrote.dm +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Contains: - * Traitor fiber wire - * Improvised garrotes - */ - -/// 12TC traitor item -/obj/item/garrote - name = "fiber wire" - desc = "A length of razor-thin wire with an elegant wooden handle on either end.
    You suspect you'd have to be behind the target to use this weapon effectively." - icon = 'icons/obj/weapons/melee.dmi' - icon_state = "garrot_wrap" - w_class = WEIGHT_CLASS_TINY - var/mob/living/carbon/human/strangling - var/improvised = FALSE - var/garrote_time - -/obj/item/garrote/Initialize(mapload) - . = ..() - AddComponent(/datum/component/two_handed) - -/obj/item/garrote/Destroy() - strangling = null - return ..() - -/obj/item/garrote/update_icon_state() - if(strangling) // If we're strangling someone we want our icon to stay wielded - icon_state = "garrot_[improvised ? "I_" : ""]unwrap" - else - icon_state = "garrot_[improvised ? "I_" : ""][HAS_TRAIT(src, TRAIT_WIELDED) ? "un" : ""]wrap" - -/// Made via tablecrafting -/obj/item/garrote/improvised - name = "garrote" - desc = "A length of cable with a shoddily-carved wooden handle tied to either end.
    You suspect you'd have to be behind the target to use this weapon effectively." - icon_state = "garrot_I_wrap" - improvised = TRUE - -/obj/item/garrote/improvised/Initialize(mapload) - . = ..() - AddComponent(/datum/component/two_handed, wield_callback = CALLBACK(src, PROC_REF(wield))) - - -/obj/item/garrote/proc/wield(obj/item/source, mob/living/carbon/user) - if(!strangling) - return - user.visible_message("[user] removes [src] from [strangling]'s neck.", - "You remove [src] from [strangling]'s neck.") - - strangling = null - update_icon(UPDATE_ICON_STATE) - STOP_PROCESSING(SSobj, src) - - -/obj/item/garrote/attack__legacy__attackchain(mob/living/carbon/M as mob, mob/user as mob) - if(garrote_time > world.time) // Cooldown - return - - if(!ishuman(user)) // spap_hand is a proc of /mob/living, user is simply /mob - return - - var/mob/living/carbon/human/U = user - - if(!HAS_TRAIT(src, TRAIT_WIELDED)) - to_chat(user, "You must use both hands to garrote [M]!") - return - - if(!ishuman(M)) - to_chat(user, "You don't think that garroting [M] would be very effective...") - return - - if(M == U) - U.suicide() // This will display a prompt for confirmation first. - return - - if(M.dir != U.dir && !M.incapacitated()) - to_chat(user, "You cannot use [src] on [M] from that angle!") - return - - if(improvised && ((M.head && (M.head.flags_cover & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags_cover & MASKCOVERSMOUTH)))) // Improvised garrotes are blocked by mouth-covering items. - to_chat(user, "[M]'s neck is blocked by something [M.p_theyre()] wearing!") - - if(strangling) - to_chat(user, "You cannot use [src] on two people at once!") - return - - attack_self__legacy__attackchain(user) - - U.swap_hand() // For whatever reason the grab will not properly work if we don't have the free hand active. - var/obj/item/grab/G = M.grabbedby(U, 1) - U.swap_hand() - - if(G && istype(G)) - if(improvised) // Improvised garrotes start you off with a passive grab, but will lock you in place. A quick stun to drop items but not to make it unescapable - M.Stun(1 SECONDS) - M.Immobilize(2 SECONDS) - else - G.state = GRAB_NECK - G.hud.icon_state = "kill" - G.hud.name = "kill" - M.AdjustSilence(2 SECONDS) - - garrote_time = world.time + 10 - START_PROCESSING(SSobj, src) - strangling = M - update_icon(UPDATE_ICON_STATE) - - playsound(loc, 'sound/weapons/cablecuff.ogg', 15, TRUE, -10, ignore_walls = FALSE) - - M.visible_message("[U] comes from behind and begins garroting [M] with [src]!", \ - "[U] begins garroting you with [src]![improvised ? "" : " You are unable to speak!"]", \ - "You hear struggling and wire strain against flesh!") - - return - -/obj/item/garrote/process() - if(!strangling) - // Our mark got gibbed or similar - update_icon(UPDATE_ICON_STATE) - STOP_PROCESSING(SSobj, src) - return - - - if(!ishuman(loc)) - strangling = null - update_icon(UPDATE_ICON_STATE) - STOP_PROCESSING(SSobj, src) - return - - var/mob/living/carbon/human/user = loc - var/obj/item/grab/G - - if(src == user.r_hand && istype(user.l_hand, /obj/item/grab)) - G = user.l_hand - - else if(src == user.l_hand && istype(user.r_hand, /obj/item/grab)) - G = user.r_hand - - else - user.visible_message("[user] loses [user.p_their()] grip on [strangling]'s neck.", \ - "You lose your grip on [strangling]'s neck.") - - strangling = null - update_icon(UPDATE_ICON_STATE) - STOP_PROCESSING(SSobj, src) - - return - - if(!G.affecting) - user.visible_message("[user] loses [user.p_their()] grip on [strangling]'s neck.", \ - "You lose your grip on [strangling]'s neck.") - - strangling = null - update_icon(UPDATE_ICON_STATE) - STOP_PROCESSING(SSobj, src) - - return - - if(G.state < GRAB_NECK) // Only possible with improvised garrotes, essentially this will stun people as if they were aggressively grabbed. Allows for resisting out if you're quick, but not running away. - strangling.Immobilize(3 SECONDS) - - if(improvised) - strangling.Stuttering(6 SECONDS) - strangling.apply_damage(2, OXY, "head") - return - - - strangling.AbsoluteSilence(6 SECONDS) // Non-improvised effects - if(G.state == GRAB_KILL) - strangling.PreventOxyHeal(6 SECONDS) - strangling.AdjustLoseBreath(6 SECONDS) - strangling.apply_damage(4, OXY, "head") - - -/obj/item/garrote/suicide_act(mob/user) - user.visible_message("[user] is wrapping [src] around [user.p_their()] neck and pulling the handles! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/cablecuff.ogg', 15, TRUE, -10, ignore_walls = FALSE) - return OXYLOSS diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm deleted file mode 100644 index 39f65ff051229..0000000000000 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ /dev/null @@ -1,143 +0,0 @@ -/* Gifts and wrapping paper - * Contains: - * Gifts - * Wrapping Paper - */ - -/* - * Gifts - */ -/obj/item/a_gift - name = "gift" - desc = "PRESENTS!!!! eek!" - icon = 'icons/obj/items.dmi' - icon_state = "gift1" - item_state = "gift1" - resistance_flags = FLAMMABLE - scatter_distance = 10 - -/obj/item/a_gift/New() - ..() - scatter_atom() - if(w_class > 0 && w_class < 4) - icon_state = "gift[w_class]" - else - icon_state = "gift[pick(1, 2, 3)]" - return - -/obj/item/gift/attack_self__legacy__attackchain(mob/user as mob) - user.drop_item() - if(src.gift) - user.put_in_active_hand(gift) - src.gift.add_fingerprint(user) - else - to_chat(user, "The gift was empty!") - qdel(src) - -/obj/effect/spresent/relaymove(mob/user as mob) - if(user.stat) - return - to_chat(user, "You can't move.") - -/obj/effect/spresent/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) - ..() - - if(!istype(W, /obj/item/wirecutters)) - to_chat(user, "I need wirecutters for that.") - return - - to_chat(user, "You cut open the present.") - - for(var/mob/M in src) //Should only be one but whatever. - M.forceMove(loc) - - qdel(src) - -/obj/item/a_gift/attack_self__legacy__attackchain(mob/M as mob) - var/gift_type = pick( - /obj/effect/spawner/random/toy/carp_plushie, - /obj/effect/spawner/random/plushies, - /obj/effect/spawner/random/toy/action_figure, - /obj/effect/spawner/random/toy/mech_figure, - /obj/item/sord, - /obj/item/storage/wallet, - /obj/item/storage/photo_album, - /obj/item/storage/box/snappops, - /obj/item/storage/fancy/crayons, - /obj/item/storage/belt/champion, - /obj/item/soap/deluxe, - /obj/item/pickaxe/silver, - /obj/item/pen/invisible, - /obj/item/lipstick/random, - /obj/item/grenade/smokebomb, - /obj/item/grown/corncob, - /obj/item/poster/random_contraband, - /obj/item/bikehorn, - /obj/item/beach_ball, - /obj/item/beach_ball/holoball, - /obj/item/banhammer, - /obj/item/toy/balloon, - /obj/item/toy/blink, - /obj/item/gun/projectile/shotgun/toy/crossbow, - /obj/item/gun/projectile/revolver/capgun, - /obj/item/toy/katana, - /obj/item/toy/spinningtoy, - /obj/item/toy/sword, - /obj/item/food/grown/ambrosia/deus, - /obj/item/food/grown/ambrosia/vulgaris, - /obj/item/paicard, - /obj/item/instrument/violin, - /obj/item/instrument/guitar, - /obj/item/storage/belt/utility/full, - /obj/item/clothing/neck/tie/horrible, - /obj/item/deck/cards, - /obj/item/deck/cards/tiny, - /obj/item/deck/unum, - /obj/item/toy/minimeteor, - /obj/item/toy/redbutton, - /obj/item/toy/figure/owl, - /obj/item/toy/figure/griffin, - /obj/item/clothing/head/blob, - /obj/item/id_decal/gold, - /obj/item/id_decal/silver, - /obj/item/id_decal/prisoner, - /obj/item/id_decal/centcom, - /obj/item/id_decal/emag, - /obj/item/spellbook/oneuse/fake_gib, - /obj/item/toy/foamblade, - /obj/item/toy/flash, - /obj/item/toy/minigibber, - /obj/item/toy/nuke, - /obj/item/toy/ai, - /obj/item/clothing/under/syndicate/tacticool, - /obj/item/clothing/under/syndicate/greyman, - /obj/item/storage/box/fakesyndiesuit, - /obj/item/gun/projectile/shotgun/toy/tommygun, - /obj/item/stack/tile/fakespace/loaded, - ) - - if(!ispath(gift_type,/obj/item)) return - - var/obj/item/I = new gift_type(M) - M.unequip(src, force = TRUE) - M.put_in_hands(I) - I.add_fingerprint(M) - qdel(src) - return - -/* - * Wrapping Paper - */ -/obj/item/stack/wrapping_paper - name = "wrapping paper" - desc = "You can use this to wrap items in." - icon = 'icons/obj/stacks/miscellaneous.dmi' - icon_state = "wrap_paper" - singular_name = "wrapping paper" - flags = NOBLUDGEON - amount = 25 - max_amount = 25 - resistance_flags = FLAMMABLE - -/obj/item/stack/wrapping_paper/attack_self__legacy__attackchain(mob/user) - to_chat(user, "You need to use it on a package that has already been wrapped!") diff --git a/code/game/objects/items/weapons/grenades/bananade.dm b/code/game/objects/items/weapons/grenades/bananade.dm deleted file mode 100644 index a7f7a9628f6ba..0000000000000 --- a/code/game/objects/items/weapons/grenades/bananade.dm +++ /dev/null @@ -1,69 +0,0 @@ - -// var/turf/T | This was made 14th September 2013, and has no use at all. Its being removed - -/obj/item/grenade/bananade - name = "bananade" - desc = "A yellow grenade." - w_class = WEIGHT_CLASS_SMALL - icon = 'icons/obj/grenade.dmi' - icon_state = "banana" - item_state = "grenade" - var/deliveryamt = 8 - var/spawner_type = /obj/item/grown/bananapeel - -/obj/item/grenade/bananade/prime() - if(spawner_type && deliveryamt) - // Make a quick flash - var/turf/T = get_turf(src) - playsound(T, 'sound/items/bikehorn.ogg', 100, 1) - for(var/mob/living/carbon/C in viewers(T, null)) - C.flash_eyes() - for(var/i=1, i<=deliveryamt, i++) - var/atom/movable/x = new spawner_type - x.loc = T - if(prob(50)) - for(var/j = 1, j <= rand(1, 3), j++) - step(x, pick(NORTH,SOUTH,EAST,WEST)) - - qdel(src) - return - -/obj/item/grenade/bananade/casing - name = "bananium casing" - desc = "A grenade casing made of bananium." - icon_state = "banana_casing" - deliveryamt = 0 - -/obj/item/grenade/bananade/casing/attack_hand() - return // No activating an empty grenade - -/obj/item/grenade/bananade/casing/attack_self__legacy__attackchain() - return // Stop trying to break stuff - -/obj/item/grenade/bananade/casing/prime() - return // The grenade isnt completed yet, dont even try to blow it up - -/obj/item/grenade/bananade/casing/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/grown/bananapeel)) - if(deliveryamt < 9) - to_chat(user, "You add another banana peel to the assembly.") - deliveryamt += 1 - qdel(I) - else - to_chat(user, "The bananade is full, screwdriver it shut to ready it.") - return - - return ..() - -/obj/item/grenade/bananade/casing/screwdriver_act(mob/living/user, obj/item/I) - if(!deliveryamt) - to_chat(user, "You need to add banana peels before you can ready the grenade!") - return TRUE - - var/obj/item/grenade/bananade/G = new /obj/item/grenade/bananade - user.drop_item_to_ground(src) - user.put_in_hands(G) - G.deliveryamt = deliveryamt - to_chat(user, "You lock the assembly shut, readying it for HONK.") - qdel(src) - return TRUE diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm deleted file mode 100644 index 996b7de9c578a..0000000000000 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ /dev/null @@ -1,640 +0,0 @@ -#define EMPTY 0 -#define WIRED 1 -#define READY 2 - -/obj/item/grenade/chem_grenade - name = "grenade casing" - desc = "A do it yourself grenade casing!" - icon_state = "chemg" - item_state = "grenade" - var/bomb_state = "chembomb" - var/payload_name = null // used for spawned grenades - w_class = WEIGHT_CLASS_SMALL - force = 2 - var/prime_sound = 'sound/items/screwdriver2.ogg' - var/stage = EMPTY - var/list/beakers = list() - var/list/allowed_containers = list(/obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle) - var/affected_area = 3 - var/obj/item/assembly_holder/nadeassembly = null - var/label = null - var/assemblyattacher - var/ignition_temp = 10 // The amount of heat added to the reagents when this grenade goes off. - var/threatscale = 1 // Used by advanced grenades to make them slightly more worthy. - var/no_splash = FALSE //If the grenade deletes even if it has no reagents to splash with. Used for slime core reactions. - var/contained = "" // For logging - var/cores = "" // Also for logging - -/obj/item/grenade/chem_grenade/Initialize(mapload) - . = ..() - create_reagents(1000) - if(payload_name) - payload_name += " " // formatting, ignore me - update_icon() - - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/item/grenade/chem_grenade/Destroy() - QDEL_NULL(nadeassembly) - QDEL_LIST_CONTENTS(beakers) - return ..() - -/obj/item/grenade/chem_grenade/examine(mob/user) - . = ..() - display_timer = (stage == READY && !nadeassembly) //show/hide the timer based on assembly state - - - -/obj/item/grenade/chem_grenade/proc/get_trigger() - if(!nadeassembly) return null - for(var/obj/O in list(nadeassembly.a_left, nadeassembly.a_right)) - if(!O || istype(O,/obj/item/assembly/igniter)) continue - return O - return null - -/obj/item/grenade/chem_grenade/update_icon_state() - if(nadeassembly) - icon = 'icons/obj/assemblies/new_assemblies.dmi' - icon_state = bomb_state - var/obj/item/assembly/A = get_trigger() - if(stage != READY) - name = "bomb casing[label]" - else - if(!A) - name = "[payload_name]de-fused bomb[label]" // this should not actually happen - else - name = payload_name + A.bomb_name + label // time bombs, remote mines, etc - else - icon = 'icons/obj/grenade.dmi' - icon_state = initial(icon_state) - overlays = list() - switch(stage) - if(EMPTY) - name = "grenade casing[label]" - if(WIRED) - icon_state += "_ass" - name = "grenade casing[label]" - if(READY) - if(active) - icon_state += "_active" - else - icon_state += "_locked" - name = payload_name + "grenade" + label - - underlays.Cut() - if(nadeassembly) - underlays += "[nadeassembly.a_left.icon_state]_left" - for(var/O in nadeassembly.a_left.attached_overlays) - underlays += "[O]_l" - underlays += "[nadeassembly.a_right.icon_state]_right" - for(var/O in nadeassembly.a_right.attached_overlays) - underlays += "[O]_r" - - -/obj/item/grenade/chem_grenade/attack_self__legacy__attackchain(mob/user) - if(stage == READY && !active) - var/turf/bombturf = get_turf(src) - var/area/A = get_area(bombturf) - if(nadeassembly) - nadeassembly.attack_self__legacy__attackchain(user) - update_icon(UPDATE_ICON_STATE) - else if(clown_check(user)) - // This used to go before the assembly check, but that has absolutely zero to do with priming the damn thing. You could spam the admins with it. - log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) [contained].") - investigate_log("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])[contained].", INVESTIGATE_BOMB) - add_attack_logs(user, src, "has primed (contained [contained])", ATKLOG_FEW) - to_chat(user, "You prime [src]! [det_time / 10] second\s!") - playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1) - active = TRUE - update_icon() - if(iscarbon(user)) - var/mob/living/carbon/C = user - C.throw_mode_on() - spawn(det_time) - prime() - -/obj/item/grenade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - var/obj/item/projectile/P = hitby - if(damage && attack_type == PROJECTILE_ATTACK && P.damage_type != STAMINA && prob(15)) - owner.visible_message("[hitby] hits [owner]'s [name], setting it off! What a shot!") - var/turf/T = get_turf(src) - log_game("A projectile ([hitby]) detonated a grenade held by [key_name(owner)] at [COORD(T)]") - add_attack_logs(P.firer, owner, "A projectile ([hitby]) detonated a grenade held", ATKLOG_FEW) - prime() - if(!QDELETED(src)) // some grenades don't detonate but we want them destroyed, otherwise you can just hold empty grenades as shields. - qdel(src) - return TRUE - return ..() - -/obj/item/grenade/chem_grenade/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I,/obj/item/hand_labeler)) - var/obj/item/hand_labeler/HL = I - if(length(HL.label)) - label = " ([HL.label])" - return 0 - else - if(label) - label = null - update_icon(UPDATE_ICON_STATE) - to_chat(user, "You remove the label from [src].") - return 1 - else if(stage == WIRED && is_type_in_list(I, allowed_containers)) - if(length(beakers) == 2) - to_chat(user, "[src] can not hold more containers.") - return - else - if(I.reagents.total_volume) - to_chat(user, "You add [I] to the assembly.") - user.drop_item() - I.forceMove(src) - beakers += I - else - to_chat(user, "[I] is empty.") - - else if(stage == EMPTY && istype(I, /obj/item/assembly_holder)) - var/obj/item/assembly_holder/A = I - if(!A.secured) - return - if(isigniter(A.a_left) == isigniter(A.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it - return - - user.drop_item() - nadeassembly = A - A.master = src - A.forceMove(src) - assemblyattacher = user.ckey - stage = WIRED - to_chat(user, "You add [A] to [src]!") - update_icon(UPDATE_ICON_STATE) - - else if(stage == EMPTY && istype(I, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = I - C.use(1) - - stage = WIRED - to_chat(user, "You rig [src].") - update_icon(UPDATE_ICON_STATE) - - else if(stage == READY && istype(I, /obj/item/wirecutters)) - to_chat(user, "You unlock the assembly.") - stage = WIRED - update_icon(UPDATE_ICON_STATE) - - else if(stage == WIRED && iswrench(I)) - to_chat(user, "You open the grenade and remove the contents.") - stage = EMPTY - payload_name = null - label = null - if(nadeassembly) - nadeassembly.forceMove(get_turf(src)) - nadeassembly.master = null - nadeassembly = null - if(length(beakers)) - for(var/obj/O in beakers) - O.forceMove(get_turf(src)) - beakers = list() - update_icon(UPDATE_ICON_STATE) - -/obj/item/grenade/chem_grenade/screwdriver_act(mob/living/user, obj/item/I) - if(stage == WIRED) - if(!length(beakers)) - to_chat(user, "You need to add at least one beaker before locking the assembly.") - return TRUE - - to_chat(user, "You lock the assembly.") - playsound(loc, prime_sound, 25, -3) - stage = READY - update_icon(UPDATE_ICON_STATE) - contained = "" - cores = "" // clear them out so no recursive logging by accidentally - for(var/obj/O in beakers) - if(!O.reagents) - continue - if(istype(O, /obj/item/slime_extract)) - cores += " [O]" - for(var/R in O.reagents.reagent_list) - var/datum/reagent/reagent = R - contained += "[reagent.volume] [reagent], " - if(contained) - if(cores) - contained = "\[[cores]; [contained]\]" - else - contained = "\[ [contained]\]" - var/turf/bombturf = get_turf(loc) - add_attack_logs(user, src, "has completed with [contained]", ATKLOG_MOST) - log_game("[key_name(usr)] has completed [name] at [bombturf.x], [bombturf.y], [bombturf.z]. [contained]") - return TRUE - - else if(stage == READY && !nadeassembly) - det_time = det_time == 5 SECONDS ? 3 SECONDS : 5 SECONDS // Toggle between 3 and 5 seconds. - to_chat(user, "You modify the time delay. It's set for [det_time / 10] second\s.") - return TRUE - - else if(stage == EMPTY) - to_chat(user, "You need to add an activation mechanism.") - return TRUE - -/obj/item/grenade/chem_grenade/HasProximity(atom/movable/AM) - if(nadeassembly) - nadeassembly.HasProximity(AM) - -/obj/item/grenade/chem_grenade/Move() // prox sensors and infrared care about this - . = ..() - if(nadeassembly) - nadeassembly.process_movement() - -/obj/item/grenade/chem_grenade/pickup() - . = ..() - if(nadeassembly) - nadeassembly.process_movement() - -/obj/item/grenade/chem_grenade/proc/on_atom_entered(datum/source, atom/movable/entered) - if(nadeassembly) - nadeassembly.on_atom_entered(source, entered) - -/obj/item/grenade/chem_grenade/on_found(mob/finder) - if(nadeassembly) - nadeassembly.on_found(finder) - -/obj/item/grenade/chem_grenade/hear_talk(mob/living/M, list/message_pieces) - if(nadeassembly) - nadeassembly.hear_talk(M, message_pieces) - -/obj/item/grenade/chem_grenade/hear_message(mob/living/M, msg) - if(nadeassembly) - nadeassembly.hear_message(M, msg) - -/obj/item/grenade/chem_grenade/Bump() - ..() - if(nadeassembly) - nadeassembly.process_movement() - -/obj/item/grenade/chem_grenade/throw_impact() // called when a throw stops - ..() - if(nadeassembly) - nadeassembly.process_movement() - - -/obj/item/grenade/chem_grenade/prime() - if(stage != READY) - return - - var/list/datum/reagents/reactants = list() - for(var/obj/item/reagent_containers/glass/G in beakers) - reactants += G.reagents - - if(!chem_splash(get_turf(src), affected_area, reactants, ignition_temp, threatscale) && !no_splash) - playsound(loc, 'sound/items/screwdriver2.ogg', 50, 1) - if(length(beakers)) - for(var/obj/O in beakers) - O.forceMove(get_turf(src)) - beakers = list() - stage = EMPTY - update_icon(UPDATE_ICON_STATE) - return - - if(nadeassembly) - var/mob/M = get_mob_by_ckey(assemblyattacher) - var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast) - var/turf/T = get_turf(src) - var/area/A = get_area(T) - message_admins("grenade primed by an assembly, attached by [key_name_admin(M)] and last touched by [key_name_admin(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP). [contained]") - log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z]) [contained]") - investigate_log("grenade primed by an assembly, attached by [key_name_admin(M)] and last touched by [key_name_admin(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).", INVESTIGATE_BOMB) - add_attack_logs(last, src, "has armed for detonation", ATKLOG_FEW) - update_mob() - - qdel(src) - -/obj/item/grenade/chem_grenade/proc/CreateDefaultTrigger(typekey) - if(ispath(typekey,/obj/item/assembly)) - nadeassembly = new(src) - nadeassembly.a_left = new /obj/item/assembly/igniter(nadeassembly) - nadeassembly.a_left.holder = nadeassembly - nadeassembly.a_left.secured = TRUE - nadeassembly.a_right = new typekey(nadeassembly) - if(!nadeassembly.a_right.secured) - nadeassembly.a_right.toggle_secure() // necessary because fuxing prock_sensors - nadeassembly.a_right.holder = nadeassembly - nadeassembly.secured = TRUE - nadeassembly.master = src - nadeassembly.update_icon() - stage = READY - update_icon() - - -//Large chem grenades accept slime cores and use the appropriately. -/obj/item/grenade/chem_grenade/large - name = "large grenade casing" - desc = "A custom made large grenade. It affects a larger area." - icon_state = "large_grenade" - bomb_state = "largebomb" - allowed_containers = list(/obj/item/reagent_containers/glass,/obj/item/reagent_containers/condiment, - /obj/item/reagent_containers/drinks) - origin_tech = "combat=3;engineering=3" - affected_area = 5 - ignition_temp = 25 // Large grenades are slightly more effective at setting off heat-sensitive mixtures than smaller grenades. - threatscale = 1.1 // 10% more effective. - -/obj/item/grenade/chem_grenade/large/prime() - if(stage != READY) - return - - for(var/obj/item/slime_extract/S in beakers) - if(S.Uses) - for(var/obj/item/reagent_containers/glass/G in beakers) - G.reagents.trans_to(S, G.reagents.total_volume) - - //If there is still a core (sometimes it's used up) - //and there are reagents left, behave normally, - //otherwise drop it on the ground for timed reactions like gold. - - if(S) - if(S.reagents && S.reagents.total_volume) - for(var/obj/item/reagent_containers/glass/G in beakers) - S.reagents.trans_to(G, S.reagents.total_volume) - else - S.forceMove(get_turf(src)) - no_splash = TRUE - ..() - - - //I tried to just put it in the allowed_containers list but - //if you do that it must have reagents. If you're going to - //make a special case you might as well do it explicitly. -Sayu -/obj/item/grenade/chem_grenade/large/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/slime_extract) && stage == WIRED) - to_chat(user, "You add [I] to the assembly.") - user.drop_item() - I.loc = src - beakers += I - else - return ..() - -/// Intended for rare cryogenic mixes. Cools the area moderately upon detonation. -/obj/item/grenade/chem_grenade/cryo - name = "cryo grenade" - desc = "A custom made cryogenic grenade. It rapidly cools its contents upon detonation." - icon_state = "cryog" - affected_area = 2 - ignition_temp = -100 - -/// Intended for pyrotechnical mixes. Produces a small fire upon detonation, igniting potentially flammable mixtures. -/obj/item/grenade/chem_grenade/pyro - name = "pyro grenade" - desc = "A custom made pyrotechnical grenade. It heats up and ignites its contents upon detonation." - icon_state = "pyrog" - origin_tech = "combat=4;engineering=4" - affected_area = 3 - ignition_temp = 500 // This is enough to expose a hotspot. - -/// Intended for weaker, but longer lasting effects. Could have some interesting uses. -/obj/item/grenade/chem_grenade/adv_release - name = "advanced release grenade" - desc = "A custom made advanced release grenade. It is able to be detonated more than once. Can be configured using a multitool." - icon_state = "timeg" - origin_tech = "combat=3;engineering=4" - var/unit_spread = 10 // Amount of units per repeat. Can be altered with a multitool. - -/obj/item/grenade/chem_grenade/adv_release/multitool_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - switch(unit_spread) - if(0 to 24) - unit_spread += 5 - if(25 to 99) - unit_spread += 25 - else - unit_spread = 5 - to_chat(user, "You set the time release to [unit_spread] units per detonation.") - -/obj/item/grenade/chem_grenade/adv_release/prime() - if(stage != READY) - return - - var/total_volume = 0 - for(var/obj/item/reagent_containers/RC in beakers) - total_volume += RC.reagents.total_volume - if(!total_volume) - qdel(src) - qdel(nadeassembly) - return - var/fraction = unit_spread/total_volume - var/datum/reagents/reactants = new(unit_spread) - reactants.my_atom = src - for(var/obj/item/reagent_containers/RC in beakers) - RC.reagents.trans_to(reactants, RC.reagents.total_volume*fraction, threatscale, 1, 1) - chem_splash(get_turf(src), affected_area, list(reactants), ignition_temp, threatscale) - - if(nadeassembly) - var/mob/M = get_mob_by_ckey(assemblyattacher) - var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast) - var/turf/T = get_turf(src) - var/area/A = get_area(T) - message_admins("grenade primed by an assembly, attached by [key_name_admin(M)] and last touched by [key_name_admin(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).") - log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])") - investigate_log("grenade primed by an assembly, attached by [key_name_admin(M)] and last touched by [key_name_admin(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).", INVESTIGATE_BOMB) - add_attack_logs(last, src, "has armed for detonation", ATKLOG_FEW) - else - addtimer(CALLBACK(src, PROC_REF(prime)), det_time) - var/turf/DT = get_turf(src) - var/area/DA = get_area(DT) - log_game("A grenade detonated at [DA.name] ([DT.x], [DT.y], [DT.z])") - -/obj/item/grenade/chem_grenade/metalfoam - payload_name = "metal foam" - desc = "Used for emergency sealing of air breaches." - stage = READY - -/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) - - B1.reagents.add_reagent("aluminum", 30) - B2.reagents.add_reagent("fluorosurfactant", 10) - B2.reagents.add_reagent("sacid", 10) - - beakers += B1 - beakers += B2 - update_icon(UPDATE_ICON_STATE) - - -/obj/item/grenade/chem_grenade/firefighting - payload_name = "fire fighting" - desc = "Can help to put out dangerous fires from a distance." - stage = READY - -/obj/item/grenade/chem_grenade/firefighting/Initialize(mapload) - . = ..() - var/obj/item/reagent_containers/glass/beaker/B1 = new(src) - var/obj/item/reagent_containers/glass/beaker/B2 = new(src) - - B1.reagents.add_reagent("firefighting_foam", 30) - B2.reagents.add_reagent("firefighting_foam", 30) - - beakers += B1 - beakers += B2 - update_icon(UPDATE_ICON_STATE) - -/obj/item/grenade/chem_grenade/incendiary - payload_name = "incendiary" - desc = "Used for clearing rooms of living things." - stage = READY - -/obj/item/grenade/chem_grenade/incendiary/Initialize(mapload) - . = ..() - var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src) - var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src) - - B1.reagents.add_reagent("phosphorus", 25) - B2.reagents.add_reagent("plasma", 25) - B2.reagents.add_reagent("sacid", 25) - - - beakers += B1 - beakers += B2 - update_icon(UPDATE_ICON_STATE) - - -/obj/item/grenade/chem_grenade/antiweed - payload_name = "weed killer" - 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(mapload) - . = ..() - var/obj/item/reagent_containers/glass/beaker/B1 = new(src) - var/obj/item/reagent_containers/glass/beaker/B2 = new(src) - - B1.reagents.add_reagent("atrazine", 30) - B1.reagents.add_reagent("potassium", 20) - B2.reagents.add_reagent("phosphorus", 20) - B2.reagents.add_reagent("sugar", 20) - B2.reagents.add_reagent("atrazine", 10) - - beakers += B1 - beakers += B2 - update_icon(UPDATE_ICON_STATE) - - -/obj/item/grenade/chem_grenade/cleaner - belt_icon = "grenade" - payload_name = "cleaner" - desc = "BLAM!-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas." - stage = READY - /// The chemical used to clean things - var/cleaning_chem = "cleaner" - -/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) - - B1.reagents.add_reagent("fluorosurfactant", 40) - B2.reagents.add_reagent(cleaning_chem, 10) - B2.reagents.add_reagent("water", 40) //when you make pre-designed foam reactions that carry the reagents, always add water last - - beakers += B1 - beakers += B2 - update_icon(UPDATE_ICON_STATE) - -/obj/item/grenade/chem_grenade/cleaner/everything - payload_name = "melter" - desc = "Inside of this grenade are black-market Syndicate nanites that consume everything they come in cross with. Organs, clothes, consoles, people. Nothing is safe.
    Now with a new foaming applicator!" - cleaning_chem = "admincleaner_all" - -/obj/item/grenade/chem_grenade/cleaner/object - payload_name = "object dissolving" - desc = "Inside of this grenade are black-market Syndicate nanites that curiously only consume objects, leaving living creatures and larger machinery alone.
    Now with a new foaming applicator!" - cleaning_chem = "admincleaner_item" - -/obj/item/grenade/chem_grenade/cleaner/organic - payload_name = "organic dissolving" - desc = "Inside of this grenade are black-market Syndicate nanites that have an appetite for living creatures and their organs, be they silicon or organic, dead or alive.
    Now with a new foaming applicator!" - cleaning_chem = "admincleaner_mob" - - -/obj/item/grenade/chem_grenade/teargas - payload_name = "teargas" - desc = "Used for nonlethal riot control. Contents under pressure. Do not directly inhale contents." - stage = READY - -/obj/item/grenade/chem_grenade/teargas/Initialize(mapload) - . = ..() - var/obj/item/reagent_containers/glass/beaker/B1 = new(src) - var/obj/item/reagent_containers/glass/beaker/B2 = new(src) - - B1.reagents.add_reagent("condensedcapsaicin", 25) - B1.reagents.add_reagent("potassium", 25) - B2.reagents.add_reagent("phosphorus", 25) - B2.reagents.add_reagent("sugar", 25) - - beakers += B1 - beakers += B2 - update_icon(UPDATE_ICON_STATE) - -/obj/item/grenade/chem_grenade/facid - payload_name = "acid smoke" - desc = "Use to chew up opponents from the inside out." - stage = READY - -/obj/item/grenade/chem_grenade/facid/Initialize(mapload) - . = ..() - var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src) - var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src) - - B1.reagents.add_reagent("facid", 80) - B1.reagents.add_reagent("potassium", 20) - B2.reagents.add_reagent("phosphorus", 20) - B2.reagents.add_reagent("sugar", 20) - B2.reagents.add_reagent("facid", 60) - - beakers += B1 - beakers += B2 - update_icon(UPDATE_ICON_STATE) - -/obj/item/grenade/chem_grenade/saringas - payload_name = "sarin gas" - desc = "Contains sarin gas; extremely deadly and fast acting; use with extreme caution." - stage = READY - -/obj/item/grenade/chem_grenade/saringas/Initialize(mapload) - . = ..() - var/obj/item/reagent_containers/glass/beaker/B1 = new(src) - var/obj/item/reagent_containers/glass/beaker/B2 = new(src) - - B1.reagents.add_reagent("sarin", 25) - B1.reagents.add_reagent("potassium", 25) - B2.reagents.add_reagent("phosphorus", 25) - B2.reagents.add_reagent("sugar", 25) - - beakers += B1 - beakers += B2 - update_icon(UPDATE_ICON_STATE) - -/obj/item/grenade/chem_grenade/tar - payload_name = "sticky tar" - desc = "For spreading sticky tar. Become the anti-janitor!" - stage = READY - -/obj/item/grenade/chem_grenade/tar/Initialize(mapload) - . = ..() - var/obj/item/reagent_containers/glass/beaker/beaker_1 = new(src) - var/obj/item/reagent_containers/glass/beaker/beaker_2 = new(src) - - beaker_1.reagents.add_reagent("sticky_tar", 15) - beaker_1.reagents.add_reagent("potassium", 10) - beaker_2.reagents.add_reagent("phosphorus", 10) - beaker_2.reagents.add_reagent("sugar", 10) - beakers += beaker_1 - beakers += beaker_2 - update_icon(UPDATE_ICON_STATE) - -#undef EMPTY -#undef WIRED -#undef READY diff --git a/code/game/objects/items/weapons/grenades/frag.dm b/code/game/objects/items/weapons/grenades/frag.dm deleted file mode 100644 index fdaa2ab050bfd..0000000000000 --- a/code/game/objects/items/weapons/grenades/frag.dm +++ /dev/null @@ -1,76 +0,0 @@ -#define DEFAULT_SHRAPNEL_RANGE 5 - -/obj/item/grenade/frag - name = "fragmentation grenade" - desc = "A grenade with a specially designed casing that will launch lethal fragments in all directions upon detonation. Fire in the hole!" - icon_state = "frag" - item_state = "grenade" - origin_tech = "materials=3;magnets=4" - /// How much shrapnel the grenade will launch. - var/shrapnel_contained = 20 - /// The type of projectile that will fired. - var/embedded_type = /obj/item/projectile/bullet/shrapnel - -/obj/item/grenade/frag/prime() - update_mob() - explosion(loc, 0, 1, DEFAULT_SHRAPNEL_RANGE, breach = FALSE) - create_shrapnel(loc, shrapnel_contained, shrapnel_type = embedded_type) - qdel(src) - -/** - * Shrapnel that flies through the air and hits you - */ -/obj/item/projectile/bullet/shrapnel - name = "shrapnel" - icon_state = "magspear" - gender = PLURAL - range = DEFAULT_SHRAPNEL_RANGE - damage = 1 // 1 damage, to trigger stuff that reacts to damage. Rest of the damage is done through the physical shrapnel - var/embed_prob = 100 //reduced by armor - var/embedded_type = /obj/item/shrapnel - -/obj/item/projectile/bullet/shrapnel/on_hit(atom/target, blocked) - . = ..() - var/obj/item/new_possible_embed = new embedded_type(get_turf(src)) // drop it on the floor if we hit somethig non-living - if(!.) - return - if(!ishuman(target)) - return - - var/mob/living/carbon/human/H = target - if(!prob(embed_prob - ARMOUR_VALUE_TO_PERCENTAGE(H.getarmor(null, BOMB)))) - to_chat(H, "Shrapnel bounces off your armor!") - return - H.try_embed_object(new_possible_embed) - -/obj/item/projectile/bullet/shrapnel/on_range() - var/obj/item/we_missed = new embedded_type(get_turf(src)) // we missed, lets toss the shrapnel - var/range = gaussian(4, 2) - if(range > 0) - var/atom/i_wasnt_aiming_for_the_truck = get_angle_target_turf(get_turf(src), Angle, range) - we_missed.throw_at(i_wasnt_aiming_for_the_truck, 16, 3) - return ..() - -/** - * Shrapnel projectiles turn into this after trying to embed - */ -/obj/item/shrapnel - name = "shrapnel" - desc = "Metal shards at high velocity, a classic method of blowing your enemies up." - icon = 'icons/obj/shards.dmi' - icon_state = "shrapnel1" - force = 8 // its a sharp piece of metal, but still not very effective - gender = PLURAL - embed_chance = 100 - embedded_fall_chance = 0 - w_class = WEIGHT_CLASS_SMALL - sharp = TRUE - hitsound = 'sound/weapons/pierce.ogg' - scatter_distance = 8 - -/obj/item/shrapnel/Initialize(mapload) - . = ..() - icon_state = pick("shrapnel1", "shrapnel2", "shrapnel3") - scatter_atom() - -#undef DEFAULT_SHRAPNEL_RANGE diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm deleted file mode 100644 index 2fa8456663865..0000000000000 --- a/code/game/objects/items/weapons/grenades/ghettobomb.dm +++ /dev/null @@ -1,67 +0,0 @@ -//improvised explosives// - -/obj/item/grenade/iedcasing - name = "improvised firebomb" - desc = "A sketchy improvised incendiary device." - w_class = WEIGHT_CLASS_SMALL - icon = 'icons/obj/grenade.dmi' - icon_state = "improvised_grenade" - item_state = "grenade" - throw_speed = 3 - throw_range = 7 - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - active = FALSE - det_time = 5 SECONDS - display_timer = FALSE - modifiable_timer = FALSE - var/list/times - -/obj/item/grenade/iedcasing/examine(mob/user) - . = ..() - . += "You have no idea how long the fuze will last for until it explodes!" - -/obj/item/grenade/iedcasing/Initialize(mapload) - . = ..() - overlays += "improvised_grenade_filled" - overlays += "improvised_grenade_wired" - times = list("5" = 10, "-1" = 20, "[rand(30, 80)]" = 50, "[rand(65, 180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value] - det_time = text2num(pickweight(times)) - if(det_time < 0) //checking for 'duds' - det_time = rand(30,80) - -/obj/item/grenade/iedcasing/CheckParts(list/parts_list) - ..() - var/obj/item/reagent_containers/drinks/cans/can = locate() in contents - if(can) - can.pixel_x = 0 //Reset the sprite's position to make it consistent with the rest of the IED - can.pixel_y = 0 - var/mutable_appearance/can_underlay = new(can) - can_underlay.layer = FLOAT_LAYER - can_underlay.plane = FLOAT_PLANE - underlays += can_underlay - - -/obj/item/grenade/iedcasing/attack_self__legacy__attackchain(mob/user) // - if(!active) - if(clown_check(user)) - to_chat(user, "You light [src]!") - active = TRUE - overlays -= "improvised_grenade_filled" - icon_state = initial(icon_state) + "_active" - add_fingerprint(user) - var/turf/bombturf = get_turf(src) - var/area/A = get_area(bombturf) - - log_game("[key_name(user)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].") - investigate_log("[key_name(user)] has primed a [name] for detonation at [A.name] [COORD(bombturf)])", INVESTIGATE_BOMB) - add_attack_logs(user, src, "has primed for detonation", ATKLOG_FEW) - if(iscarbon(user)) - var/mob/living/carbon/C = user - C.throw_mode_on() - addtimer(CALLBACK(src, PROC_REF(prime)), det_time) - -/obj/item/grenade/iedcasing/prime() //Blowing that can up - update_mob() - explosion(loc, -1, -1, 2, flame_range = 4) // small explosion, plus a very large fireball. - qdel(src) diff --git a/code/game/objects/items/weapons/grenades/syndieminibomb.dm b/code/game/objects/items/weapons/grenades/syndieminibomb.dm deleted file mode 100644 index 4bd01c7f8838d..0000000000000 --- a/code/game/objects/items/weapons/grenades/syndieminibomb.dm +++ /dev/null @@ -1,39 +0,0 @@ -/obj/item/grenade/syndieminibomb - name = "\improper Syndicate minibomb" - desc = "A Syndicate-manufactured high-explosive grenade used to sow destruction and chaos." - icon = 'icons/obj/grenade.dmi' - icon_state = "syndicate" - item_state = "grenade" - origin_tech = "materials=3;magnets=4;syndicate=3" - -/obj/item/grenade/syndieminibomb/prime() - update_mob() - explosion(loc, 1, 2, 4, flame_range = 2) - qdel(src) - -/obj/item/grenade/syndieminibomb/fake - origin_tech = "materials=3;magnets=4;syndicate=1" // no clown, this bomb not exactly the same - -/obj/item/grenade/syndieminibomb/fake/examine(mob/user) - . = ..() - if(HAS_TRAIT(user, TRAIT_CLUMSY)) - . += "There are small glue ejectors all over the bomb." - -/obj/item/grenade/syndieminibomb/fake/attack_self__legacy__attackchain(mob/user) - if(!active) - flags |= NODROP - to_chat(user, "As you activate the bomb, it emits a substance that sticks to your hand! It won't come off!") - to_chat(user, "Uh oh.") - . = ..() - -/obj/item/grenade/syndieminibomb/pen - name = "pen" - desc = "It's a normal black ink pen." - icon = 'icons/obj/bureaucracy.dmi' - icon_state = "pen" - item_state = "pen" - -/obj/item/grenade/syndieminibomb/pen/attack_self__legacy__attackchain(mob/user) - if(!active) - visible_message("[user] fumbles with [src]!") - . = ..() diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm deleted file mode 100644 index 392e6af517ae8..0000000000000 --- a/code/game/objects/items/weapons/handcuffs.dm +++ /dev/null @@ -1,314 +0,0 @@ -/obj/item/restraints - name = "bugged restraints" //This item existed before this pr, but had no name or such. Better warn people if it exists - desc = "Should not exist. Report me to a(n) coder/admin!" - icon = 'icons/obj/restraints.dmi' - var/cuffed_state = "handcuff" - ///How long it will take to break out of restraints - var/breakouttime - -/obj/item/restraints/proc/attempt_resist_restraints(mob/living/carbon/user, break_cuffs, effective_breakout_time, silent) - if(effective_breakout_time) - if(!silent) - user.visible_message("[user] attempts to [break_cuffs ? "break" : "remove"] [src]!", "You attempt to [break_cuffs ? "break" : "remove"] [src]...") - to_chat(user, "(This will take around [DisplayTimeText(effective_breakout_time)] and you need to stand still.)") - - if(!do_after(user, effective_breakout_time, FALSE, user)) - user.remove_status_effect(STATUS_EFFECT_REMOVE_CUFFS) - to_chat(user, "You fail to [break_cuffs ? "break" : "remove"] [src]!") - return - - user.remove_status_effect(STATUS_EFFECT_REMOVE_CUFFS) - if(loc != user || user.buckled) - return - - finish_resist_restraints(user, break_cuffs) - -/obj/item/restraints/proc/finish_resist_restraints(mob/living/carbon/user, break_cuffs, silent) - if(!silent) - user.visible_message("[user] manages to [break_cuffs ? "break" : "remove"] [src]!", "You successfully [break_cuffs ? "break" : "remove"] [src].") - user.unequip(src) - - if(break_cuffs) - qdel(src) - return TRUE - else - forceMove(user.drop_location()) - -////////////////////////////// -// MARK: HANDCUFFS -////////////////////////////// -/obj/item/restraints/handcuffs - name = "handcuffs" - desc = "Use this to keep prisoners in line." - gender = PLURAL - icon_state = "handcuff" - belt_icon = "handcuffs" - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - throwforce = 5 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 2 - throw_range = 5 - materials = list(MAT_METAL=500) - origin_tech = "engineering=3;combat=3" - breakouttime = 1 MINUTES - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50) - /// Sound made when cuffing someone. - var/cuffsound = 'sound/weapons/handcuffs.ogg' - /// Trash item generated when cuffs are broken (for disposable cuffs). - var/trashtype - /// If set to TRUE, people with the TRAIT_CLUMSY won't cuff themselves when trying to cuff others. - var/ignoresClumsy = FALSE - -/obj/item/restraints/handcuffs/attack__legacy__attackchain(mob/living/carbon/C, mob/user) - if(!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") - return - - if(!istype(C)) - return - - if(flags & NODROP) - to_chat(user, "[src] is stuck to your hand!") - return - - if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50) && (!ignoresClumsy)) - to_chat(user, "Uh... how do those things work?!") - apply_cuffs(user, user) - return - - cuff(C, user) - -/obj/item/restraints/handcuffs/proc/cuff(mob/living/carbon/C, mob/user, remove_src = TRUE) - if(!istype(C)) // Shouldn't be able to cuff anything but carbons. - return - - if(ishuman(C)) - var/mob/living/carbon/human/H = C - if(!(H.has_left_hand() || H.has_right_hand())) - to_chat(user, "How do you suggest handcuffing someone with no hands?") - return FALSE - - if(!C.handcuffed) - C.visible_message("[user] is trying to put [src.name] on [C]!", \ - "[user] is trying to put [src.name] on [C]!") - - playsound(loc, cuffsound, 15, TRUE, -10) - if(do_mob(user, C, 30)) - apply_cuffs(C, user, remove_src) - to_chat(user, "You handcuff [C].") - SSblackbox.record_feedback("tally", "handcuffs", 1, type) - if(breakouttime != 0) - add_attack_logs(user, C, "Handcuffed ([src])") - else - add_attack_logs(user, C, "Handcuffed (Fake/Breakable!) ([src])") - else - to_chat(user, "You fail to handcuff [C].") - return FALSE - -/obj/item/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user, remove_src = TRUE) - if(!target.handcuffed) - if(remove_src) - user.drop_item() - if(trashtype) - target.handcuffed = new trashtype(target) - if(remove_src) - qdel(src) - else - if(remove_src) - loc = target - target.handcuffed = src - else - target.handcuffed = new type(loc) - target.update_handcuffed() - return - -////////////////////////////// -// MARK: CUFF SKINS -////////////////////////////// -/obj/item/restraints/handcuffs/alien - icon_state = "handcuffAlien" - -/obj/item/restraints/handcuffs/pinkcuffs - name = "fluffy pink handcuffs" - desc = "Use this to keep prisoners in line, they are really itchy." - icon_state = "pinkcuffs" - cuffed_state = "pinkcuff" - -////////////////////////////// -// MARK: SINEW CUFFS -////////////////////////////// -/obj/item/restraints/handcuffs/sinew - name = "sinew restraints" - desc = "A pair of restraints fashioned from long strands of flesh." - icon = 'icons/obj/mining.dmi' - icon_state = "sinewcuff" - item_state = "sinewcuff" - belt_icon = null - breakouttime = 30 SECONDS - cuffsound = 'sound/weapons/cablecuff.ogg' - -////////////////////////////// -// MARK: CABLE CUFFS -////////////////////////////// -/obj/item/restraints/handcuffs/cable - name = "cable restraints" - desc = "Looks like some cables tied together. Could be used to tie something up." - icon_state = "cablecuff" - item_state = "cablecuff" - cuffed_state = "cablecuff" - belt_icon = "cablecuff" - origin_tech = "engineering=2" - materials = list(MAT_METAL=150, MAT_GLASS=75) - breakouttime = 30 SECONDS - cuffsound = 'sound/weapons/cablecuff.ogg' - -/obj/item/restraints/handcuffs/cable/red - color = COLOR_RED - -/obj/item/restraints/handcuffs/cable/yellow - color = COLOR_YELLOW - -/obj/item/restraints/handcuffs/cable/blue - color = COLOR_BLUE - -/obj/item/restraints/handcuffs/cable/green - color = COLOR_GREEN - -/obj/item/restraints/handcuffs/cable/pink - color = COLOR_PINK - -/obj/item/restraints/handcuffs/cable/orange - color = COLOR_ORANGE - -/obj/item/restraints/handcuffs/cable/cyan - color = COLOR_CYAN - -/obj/item/restraints/handcuffs/cable/white - color = COLOR_WHITE - -/obj/item/restraints/handcuffs/cable/random/New() - color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN, COLOR_ORANGE) - ..() - -/obj/item/restraints/handcuffs/cable/proc/cable_color(colorC) - if(!colorC) - color = COLOR_RED - else if(colorC == "rainbow") - color = color_rainbow() - else if(colorC == "orange") //byond only knows 16 colors by name, and orange isn't one of them - color = COLOR_ORANGE - else - color = colorC - -/obj/item/restraints/handcuffs/cable/proc/color_rainbow() - color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN) - return color - -////////////////////////////// -// MARK: ZIPTIES -////////////////////////////// -/obj/item/restraints/handcuffs/cable/zipties - name = "zipties" - desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use." - icon_state = "cablecuff" - breakouttime = 45 SECONDS - materials = list() - trashtype = /obj/item/restraints/handcuffs/cable/zipties/used - -/obj/item/restraints/handcuffs/cable/zipties/used - desc = "A pair of broken zipties." - icon_state = "cablecuff_used" - -/obj/item/restraints/handcuffs/cable/zipties/used/decompile_act(obj/item/matter_decompiler/C, mob/user) - if(isdrone(user)) - C.stored_comms["glass"] += 1 - qdel(src) - return TRUE - return ..() - -/obj/item/restraints/handcuffs/cable/zipties/used/attack__legacy__attackchain() - return - -////////////////////////////// -// MARK: TWIMSTS -////////////////////////////// -/obj/item/restraints/handcuffs/twimsts - name = "twimsts cuffs" - desc = "Liquorice twist candy made into cable cuffs, tasty but it can't actually hold anyone." - icon_state = "cablecuff" - item_state = "cablecuff" - cuffed_state = "cablecuff" - belt_icon = "cablecuff" - color = "#E31818" - throwforce = 0 - breakouttime = 0 - cuffsound = 'sound/weapons/cablecuff.ogg' - -/obj/item/restraints/handcuffs/twimsts/finish_resist_restraints(mob/living/carbon/user, break_cuffs) - if(ishuman(user)) - var/mob/living/carbon/human/human_user = user - if(!human_user.check_has_mouth()) // I have no mouth but I must eat twimsts - break_cuffs = TRUE - return ..() - - visible_message("[user] manages to eat through [src]!", "You successfully eat through [src].") - - playsound(loc, 'sound/items/eatfood.ogg', 50, FALSE) - if(reagents && length(reagents.reagent_list)) - user.taste(reagents) - reagents.reaction(user, REAGENT_INGEST) - reagents.trans_to(user, reagents.total_volume) - qdel(src) - -////////////////////////////// -// MARK: CRAFTING -////////////////////////////// -/obj/item/restraints/handcuffs/cable/attackby__legacy__attackchain(obj/item/I, mob/user, params) - ..() - - handle_attack_construction(I, user) - -/obj/item/restraints/handcuffs/cable/proc/handle_attack_construction(obj/item/I, mob/user) - if(istype(I, /obj/item/stack/rods)) - var/obj/item/stack/rods/R = I - if(!R.use(1)) - to_chat(user, "[R.amount > 1 ? "These rods" : "This rod"] somehow can't be used for crafting!") - return - if(!user.unequip(src)) - return - var/obj/item/wirerod/W = new /obj/item/wirerod(get_turf(src)) - if(!remove_item_from_storage(user)) - user.put_in_hands(W) - to_chat(user, "You wrap the cable restraint around the top of the rod.") - qdel(src) - return - - if(istype(I, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/metal/M = I - if(M.amount < 6) - to_chat(user, "You need at least six metal sheets to make good enough weights!") - return - - to_chat(user, "You begin to apply [I] to [src]...") - if(do_after(user, 3.5 SECONDS * M.toolspeed, target = src)) - if(!M.use(6) || !user.unequip(src)) - return - var/obj/item/restraints/legcuffs/bola/S = new /obj/item/restraints/legcuffs/bola(get_turf(src)) - to_chat(user, "You make some weights out of [I] and tie them to [src].") - if(!remove_item_from_storage(user)) - user.put_in_hands(S) - qdel(src) - return - - if(istype(I, /obj/item/toy/crayon)) - var/obj/item/toy/crayon/C = I - cable_color(C.dye_color) - -/obj/item/restraints/handcuffs/cable/zipties/cyborg/attack__legacy__attackchain(mob/living/carbon/C, mob/user) - if(isrobot(user)) - cuff(C, user, FALSE) - -/obj/item/restraints/handcuffs/cable/zipties/cyborg/handle_attack_construction(obj/item/I, mob/user) - // Don't allow borgs to send their their ziptie module to the shadow realm. - return diff --git a/code/game/objects/items/weapons/holosign_projector.dm b/code/game/objects/items/weapons/holosign_projector.dm deleted file mode 100644 index a105715320ae1..0000000000000 --- a/code/game/objects/items/weapons/holosign_projector.dm +++ /dev/null @@ -1,160 +0,0 @@ -/obj/item/holosign_creator - name = "holographic sign projector" - desc = "This shouldnt exist, if it does, tell a coder." - icon = 'icons/obj/device.dmi' - icon_state = "signmaker" - item_state = "electronic" - belt_icon = "holosign_creator" - force = 0 - w_class = WEIGHT_CLASS_SMALL - throwforce = 0 - throw_speed = 3 - throw_range = 7 - origin_tech = "magnets=1;programming=3" - flags = NOBLUDGEON - var/list/signs = list() - var/max_signs = 6 - var/creation_time = 0 //time to create a holosign in deciseconds. - var/holosign_type = null - var/holocreator_busy = FALSE //to prevent placing multiple holo barriers at once - -/obj/item/holosign_creator/afterattack__legacy__attackchain(atom/target, mob/user, flag) - if(flag) - if(!check_allowed_items(target, 1)) - return - var/turf/T = get_turf(target) - var/obj/structure/holosign/H = locate(holosign_type) in T - if(H) - to_chat(user, "You use [src] to deactivate [H].") - qdel(H) - else - if(!is_blocked_turf(T, TRUE)) //can't put holograms on a tile that has dense stuff - if(holocreator_busy) - to_chat(user, "[src] is busy creating a hologram.") - return - if(length(signs) < max_signs) - playsound(src.loc, 'sound/machines/click.ogg', 20, 1) - if(creation_time) - holocreator_busy = TRUE - if(!do_after(user, creation_time, target = target)) - holocreator_busy = FALSE - return - holocreator_busy = FALSE - if(length(signs) >= max_signs) - return - if(is_blocked_turf(T, TRUE)) //don't try to sneak dense stuff on our tile during the wait. - return - H = new holosign_type(get_turf(target), src) - to_chat(user, "You create [H] with [src].") - return H - else - to_chat(user, "[src] is projecting at max capacity!") - -/obj/item/holosign_creator/attack__legacy__attackchain(mob/living/carbon/human/M, mob/user) - return - -/obj/item/holosign_creator/attack_self__legacy__attackchain(mob/user) - if(length(signs)) - for(var/H in signs) - qdel(H) - to_chat(user, "You clear all active holograms.") - -/obj/item/holosign_creator/janitor - name = "janitorial holosign projector" - desc = "A handy-dandy holographic projector that displays a janitorial sign." - holosign_type = /obj/structure/holosign/wetsign - max_signs = 18 - var/wet_enabled = TRUE - -/obj/item/holosign_creator/janitor/AltClick(mob/user) - wet_enabled = !wet_enabled - playsound(loc, 'sound/weapons/empty.ogg', 20) - if(wet_enabled) - to_chat(user, "You enable the W.E.T. (wet evaporation timer)\nAny newly placed holographic signs will clear after the likely time it takes for a mopped tile to dry.") - else - to_chat(user, "You disable the W.E.T. (wet evaporation timer)\nAny newly placed holographic signs will now stay indefinitely.") - -/obj/item/holosign_creator/janitor/examine(mob/user) - . = ..() - if(ishuman(user)) - . += "Alt Click to [wet_enabled ? "deactivate" : "activate"] its built-in wet evaporation timer." - - -/obj/item/holosign_creator/janitor/afterattack__legacy__attackchain(atom/target, mob/user, flag) - var/obj/structure/holosign/wetsign/WS = ..() - if(WS && wet_enabled) - WS.wet_timer_start(src) - -/obj/item/holosign_creator/security - name = "security holobarrier projector" - desc = "A holographic projector that creates holographic security barriers." - icon_state = "signmaker_sec" - belt_icon = null - holosign_type = /obj/structure/holosign/barrier - creation_time = 30 - -/obj/item/holosign_creator/detective - name = "detective holobarrier projector" - desc = "A holographic projector that creates shocked investigation barriers." - icon_state = "signmaker_det" - belt_icon = null - holosign_type = /obj/structure/holosign/barrier/cyborg/hacked/detective - creation_time = 1 SECONDS - max_signs = 8 - -/obj/item/holosign_creator/engineering - name = "engineering holobarrier projector" - desc = "A holographic projector that creates holographic engineering barriers." - icon_state = "signmaker_engi" - belt_icon = null - holosign_type = /obj/structure/holosign/barrier/engineering - creation_time = 30 - -/obj/item/holosign_creator/atmos - name = "ATMOS holofan projector" - desc = "A holographic projector that creates holographic barriers that prevent changes in atmosphere conditions." - icon_state = "signmaker_engi" - belt_icon = null - holosign_type = /obj/structure/holosign/barrier/atmos - creation_time = 0 - max_signs = 3 - -/obj/item/holosign_creator/cyborg - name = "energy barrier projector" - desc = "A holographic projector that creates fragile energy fields." - creation_time = 15 - max_signs = 9 - holosign_type = /obj/structure/holosign/barrier/cyborg - var/shock = 0 - -/obj/item/holosign_creator/cyborg/attack_self__legacy__attackchain(mob/user) - if(isrobot(user)) - var/mob/living/silicon/robot/R = user - - if(shock) - to_chat(user, "You clear all active holograms, and reset your projector to normal.") - holosign_type = /obj/structure/holosign/barrier/cyborg - creation_time = 5 - if(length(signs)) - for(var/H in signs) - qdel(H) - shock = 0 - return - else if(R.emagged && !shock) - to_chat(user, "You clear all active holograms, and overload your energy projector!") - holosign_type = /obj/structure/holosign/barrier/cyborg/hacked - creation_time = 30 - if(length(signs)) - for(var/H in signs) - qdel(H) - shock = 1 - return - else - if(length(signs)) - for(var/H in signs) - qdel(H) - to_chat(user, "You clear all active holograms.") - if(length(signs)) - for(var/H in signs) - qdel(H) - to_chat(user, "You clear all active holograms.") diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm deleted file mode 100644 index 6f98c58a958bc..0000000000000 --- a/code/game/objects/items/weapons/holy_weapons.dm +++ /dev/null @@ -1,796 +0,0 @@ -/obj/item/nullrod - name = "null rod" - desc = "A rod of pure obsidian, its very presence disrupts and dampens the powers of dark magic." - icon = 'icons/obj/weapons/magical_weapons.dmi' - icon_state = "nullrod" - item_state = "tele_baton" - force = 15 - throw_speed = 3 - throw_range = 4 - throwforce = 10 - w_class = WEIGHT_CLASS_TINY - /// Null rod variant names, used for the radial menu - var/static/list/variant_names = list() - /// Null rod variant icons, used for the radial menu - var/static/list/variant_icons = list() - /// Has the null rod been reskinned yet - var/reskinned = FALSE - /// Is this variant selectable through the reskin menu (Set to FALSE for fluff items) - var/reskin_selectable = TRUE - /// Does this null rod have fluff variants available - var/list/fluff_transformations = list() - /// Extra 'Holy' burn damage for ERT null rods - var/sanctify_force = 0 - /// The antimagic type the nullrod has. - var/antimagic_type = MAGIC_RESISTANCE_HOLY - -/obj/item/nullrod/Initialize(mapload) - . = ..() - AddComponent(/datum/component/anti_magic, antimagic_type) - if(!length(variant_names)) - for(var/I in typesof(/obj/item/nullrod)) - var/obj/item/nullrod/rod = I - if(initial(rod.reskin_selectable)) - variant_names[initial(rod.name)] = rod - variant_icons += list(initial(rod.name) = image(icon = initial(rod.icon), icon_state = initial(rod.icon_state))) - -/obj/item/nullrod/suicide_act(mob/user) - user.visible_message("[user] is killing [user.p_themselves()] with \the [src.name]! It looks like [user.p_theyre()] trying to get closer to god!") - return BRUTELOSS|FIRELOSS - -/obj/item/nullrod/attack__legacy__attackchain(mob/M, mob/living/carbon/user) - ..() - if(!sanctify_force) - return - if(isliving(M)) - var/mob/living/L = M - L.adjustFireLoss(sanctify_force) // Bonus fire damage for sanctified (ERT) versions of nullrod - -/obj/item/nullrod/pickup(mob/living/user) - . = ..() - if(sanctify_force) - if(!user.mind || !HAS_MIND_TRAIT(user, TRAIT_HOLY)) - user.adjustBruteLoss(force) - user.adjustFireLoss(sanctify_force) - user.Weaken(10 SECONDS) - user.drop_item_to_ground(src, force = TRUE) - user.visible_message("[src] slips out of the grip of [user] as they try to pick it up, bouncing upwards and smacking [user.p_them()] in the face!", \ - "[src] slips out of your grip as you pick it up, bouncing upwards and smacking you in the face!") - playsound(get_turf(user), 'sound/effects/hit_punch.ogg', 50, TRUE, -1) - throw_at(get_edge_target_turf(user, pick(GLOB.alldirs)), rand(1, 3), 5) - - -/obj/item/nullrod/attack_self__legacy__attackchain(mob/user) - if(HAS_MIND_TRAIT(user, TRAIT_HOLY) && !reskinned) - reskin_holy_weapon(user) - -/obj/item/nullrod/examine(mob/living/user) - . = ..() - if(sanctify_force) - . += "It bears the inscription: 'Sanctified weapon of the inquisitors. Only the worthy may wield. Nobody shall expect us.'" - -/obj/item/nullrod/proc/reskin_holy_weapon(mob/user) - if(!ishuman(user)) - return - for(var/I in fluff_transformations) // If it's a fluffy null rod - var/obj/item/nullrod/rod = I - variant_names[initial(rod.name)] = rod - variant_icons += list(initial(rod.name) = image(icon = initial(rod.icon), icon_state = initial(rod.icon_state))) - var/mob/living/carbon/human/H = user - var/choice = show_radial_menu(H, src, variant_icons, null, 40, CALLBACK(src, PROC_REF(radial_check), H), TRUE) - if(!choice || !radial_check(H)) - return - - var/picked_type = variant_names[choice] - var/obj/item/nullrod/new_rod = new picked_type(get_turf(user)) - - SSblackbox.record_feedback("text", "chaplain_weapon", 1, "[picked_type]", 1) - - if(new_rod) - new_rod.reskinned = TRUE - qdel(src) - user.put_in_active_hand(new_rod) - if(sanctify_force) - new_rod.sanctify_force = sanctify_force - new_rod.name = "sanctified " + new_rod.name - -/obj/item/nullrod/proc/radial_check(mob/living/carbon/human/user) - if(!src || !user.is_in_hands(src) || user.incapacitated() || reskinned) - return FALSE - return TRUE - -/// fluff subtype to be used for all donator nullrods -/obj/item/nullrod/fluff - reskin_selectable = FALSE - -/// ERT subtype, applies sanctified property to any derived rod -/obj/item/nullrod/ert - name = "inquisitor null rod" - reskin_selectable = FALSE - sanctify_force = 10 - -/obj/item/nullrod/godhand - name = "god hand" - icon_state = "disintegrate" - item_state = "disintegrate" - desc = "This hand of yours glows with an awesome power!" - flags = ABSTRACT | NODROP| DROPDEL - w_class = WEIGHT_CLASS_HUGE - hitsound = 'sound/weapons/sear.ogg' - damtype = BURN - attack_verb = list("punched", "cross countered", "pummeled") - -/obj/item/nullrod/godhand/customised_abstract_text(mob/living/carbon/owner) - return "[owner.p_their(TRUE)] [owner.l_hand == src ? "left hand" : "right hand"] is burning in holy fire." - -/obj/item/nullrod/staff - name = "red holy staff" - desc = "It has a mysterious, protective aura." - icon_state = "godstaff-red" - lefthand_file = 'icons/mob/inhands/staves_lefthand.dmi' - righthand_file = 'icons/mob/inhands/staves_righthand.dmi' - item_state = "godstaff-red" - w_class = WEIGHT_CLASS_HUGE - force = 5 - slot_flags = ITEM_SLOT_BACK - -/obj/item/nullrod/staff/Initialize(mapload) - . = ..() - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES) - -/obj/item/nullrod/staff/blue - name = "blue holy staff" - icon_state = "godstaff-blue" - item_state = "godstaff-blue" - -/obj/item/nullrod/claymore - name = "holy claymore" - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon = 'icons/obj/weapons/melee.dmi' - icon_state = "claymore" - item_state = "claymore" - desc = "A weapon fit for a crusade!" - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_BELT - sharp = TRUE - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - -/obj/item/nullrod/claymore/Initialize(mapload) - . = ..() - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.7, _parryable_attack_types = ALL_ATTACK_TYPES, _parry_cooldown = (7 / 3) SECONDS) // 2.3333 seconds of cooldown for 30% uptime - -/obj/item/nullrod/claymore/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(attack_type == PROJECTILE_ATTACK) - final_block_chance = 0 //Don't bring a sword to a gunfight - return ..() - -/obj/item/nullrod/claymore/darkblade - name = "dark blade" - icon = 'icons/obj/weapons/magical_weapons.dmi' - icon_state = "cultblade" - item_state = "darkbalde" - desc = "Spread the glory of the dark gods!" - slot_flags = ITEM_SLOT_BELT - hitsound = 'sound/hallucinations/growl1.ogg' - -/obj/item/nullrod/claymore/chainsaw_sword - name = "sacred chainsaw sword" - icon = 'icons/obj/weapons/magical_weapons.dmi' - icon_state = "chainswordon" - item_state = "chainswordon" - desc = "Suffer not a heretic to live." - slot_flags = ITEM_SLOT_BELT - attack_verb = list("sawed", "torn", "cut", "chopped", "diced") - hitsound = 'sound/weapons/chainsaw.ogg' - -/obj/item/nullrod/claymore/glowing - name = "force blade" - icon = 'icons/obj/weapons/magical_weapons.dmi' - icon_state = "swordon" - item_state = "swordon" - desc = "The blade glows with the power of faith. Or possibly a battery." - slot_flags = ITEM_SLOT_BELT - -/obj/item/nullrod/claymore/katana - name = "hanzo steel" - desc = "Capable of cutting clean through a holy claymore." - icon_state = "katana" - item_state = "katana" - slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK - -/obj/item/nullrod/claymore/multiverse - name = "extradimensional blade" - desc = "Once the harbringer of a interdimensional war, now a dormant souvenir. Still sharp though." - icon = 'icons/obj/weapons/magical_weapons.dmi' - icon_state = "multiverse" - item_state = "multiverse" - slot_flags = ITEM_SLOT_BELT - -/obj/item/nullrod/claymore/saber - name = "light energy blade" - hitsound = 'sound/weapons/blade1.ogg' - icon = 'icons/obj/weapons/energy_melee.dmi' - icon_state = "swordblue" - item_state = "swordblue" - desc = "If you strike me down, I shall become more robust than you can possibly imagine." - slot_flags = ITEM_SLOT_BELT - -/obj/item/nullrod/claymore/saber/red - name = "dark energy blade" - icon_state = "swordred" - item_state = "swordred" - desc = "Woefully ineffective when used on steep terrain." - -/obj/item/nullrod/claymore/saber/pirate - name = "nautical energy cutlass" - icon_state = "cutlass1" - item_state = "cutlass1" - desc = "Convincing HR that your religion involved piracy was no mean feat." - -/obj/item/nullrod/sord - name = "\improper UNREAL SORD" - desc = "This thing is so unspeakably HOLY you are having a hard time even holding it." - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon_state = "sord" - item_state = "sord" - slot_flags = ITEM_SLOT_BELT - force = 4.13 - throwforce = 1 - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - -/obj/item/nullrod/scythe - name = "reaper scythe" - icon = 'icons/obj/weapons/melee.dmi' - icon_state = "scythe0" - item_state = "scythe0" - desc = "Ask not for whom the bell tolls..." - w_class = WEIGHT_CLASS_BULKY - armour_penetration_flat = 30 - slot_flags = ITEM_SLOT_BACK - sharp = TRUE - attack_verb = list("chopped", "sliced", "cut", "reaped") - hitsound = 'sound/weapons/rapierhit.ogg' - -/obj/item/nullrod/scythe/vibro - name = "high frequency blade" - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon = 'icons/obj/weapons/magical_weapons.dmi' - icon_state = "hfrequency1" - item_state = "hfrequency1" - desc = "Bad references are the DNA of the soul." - attack_verb = list("chopped", "sliced", "cut", "zandatsu'd") - -/obj/item/nullrod/scythe/spellblade - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon_state = "spellblade" - item_state = "spellblade" - icon = 'icons/obj/guns/magic.dmi' - name = "dormant spellblade" - desc = "The blade grants the wielder nearly limitless power...if they can figure out how to turn it on, that is." - hitsound = 'sound/weapons/rapierhit.ogg' - -/obj/item/nullrod/scythe/talking - name = "possessed blade" - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon = 'icons/obj/weapons/magical_weapons.dmi' - icon_state = "talking_sword" - item_state = "talking_sword" - desc = "When the station falls into chaos, it's nice to have a friend by your side." - attack_verb = list("chopped", "sliced", "cut") - hitsound = 'sound/weapons/rapierhit.ogg' - force = 12 - can_be_hit = TRUE // be a shit and you can get your ass beat - max_integrity = 100 - obj_integrity = 100 - var/possessed = FALSE - -/obj/item/nullrod/scythe/talking/attack_self__legacy__attackchain(mob/living/user) - if(possessed) - return - - to_chat(user, "You attempt to wake the spirit of the blade...") - - possessed = TRUE - - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, FALSE, 10 SECONDS, source = src, role_cleanname = "possessed blade") - var/mob/dead/observer/theghost = null - - if(QDELETED(src)) - return - if(length(candidates)) - theghost = pick(candidates) - var/mob/living/simple_animal/shade/sword/S = new(src) - S.real_name = name - S.name = name - S.ckey = theghost.ckey - dust_if_respawnable(theghost) - var/input = tgui_input_text(S, "What are you named?", "Change Name", max_length = MAX_NAME_LEN) - if(src && input) - name = input - S.real_name = input - S.name = input - else - to_chat(user, "The blade is dormant. Maybe you can try again later.") - possessed = FALSE - -/obj/item/nullrod/scythe/talking/Destroy() - for(var/mob/living/simple_animal/shade/sword/S in contents) - to_chat(S, "You were destroyed!") - S.ghostize() - qdel(S) - return ..() - -/obj/item/nullrod/scythe/talking/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(!istype(I, /obj/item/soulstone) || !possessed) - return ..() - if(obj_integrity >= max_integrity) - to_chat(user, "You have no reason to replace a perfectly good soulstone with a new one.") - return - to_chat(user, "You load a new soulstone into the possessed blade.") - playsound(user, 'sound/weapons/gun_interactions/shotgunpump.ogg', 60, TRUE) - obj_integrity = max_integrity - for(var/mob/living/simple_animal/shade/sword/sword_shade in contents) - sword_shade.health = sword_shade.maxHealth - qdel(I) - -/obj/item/nullrod/scythe/talking/take_damage(damage_amount) - if(possessed) - for(var/mob/living/simple_animal/shade/sword/sword_shade in contents) - sword_shade.take_overall_damage(damage_amount) - return ..() - -/obj/item/nullrod/scythe/talking/proc/click_actions(atom/attacking_atom, mob/living/simple_animal/attacking_shade) - if(world.time <= attacking_shade.next_move) // yea we gotta check - return - if(!ismovable(attacking_atom)) - return - attacking_shade.changeNext_move(CLICK_CD_MELEE) - if(ishuman(loc)) - var/mob/living/carbon/human/our_location = loc - if(istype(our_location)) - if(!our_location.is_holding(src)) - return - if(our_location.Adjacent(attacking_atom)) // with a buddy we deal 12 damage :D - our_location.do_attack_animation(attacking_atom, used_item = src) - melee_attack_chain(attacking_shade, attacking_atom) - return - if(Adjacent(attacking_atom)) // without a buddy we only deal 7 damage :c - force -= 5 - var/mob/living/simple_animal/hostile/hostile_target = attacking_atom - if(istype(hostile_target) && prob(40)) // Cheese reduction, non sentient animals have a hard time attacking things in objects - attack_animal(hostile_target) - do_attack_animation(attacking_atom, used_item = src) - melee_attack_chain(attacking_shade, attacking_atom) - force += 5 - -/datum/hud/sword/New(mob/user) - ..() - - mymob.healths = new /atom/movable/screen/healths() - infodisplay += mymob.healths - -/mob/living/simple_animal/shade/sword/ClickOn(atom/A, params) - if(..() && istype(loc, /obj/item/nullrod/scythe/talking)) - var/obj/item/nullrod/scythe/talking/host_sword = loc - return host_sword.click_actions(A, src) - -/obj/item/nullrod/hammmer - name = "relic war hammer" - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon_state = "hammeron" - item_state = "hammeron" - desc = "This war hammer cost the chaplain fourty thousand space dollars." - slot_flags = ITEM_SLOT_BELT - w_class = WEIGHT_CLASS_HUGE - attack_verb = list("smashed", "bashed", "hammered", "crunched") - -/obj/item/nullrod/chainsaw - name = "chainsaw hand" - desc = "Good? Bad? You're the guy with the chainsaw hand." - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon = 'icons/obj/weapons/melee.dmi' - icon_state = "chainsaw1" - item_state = "mounted_chainsaw" - w_class = WEIGHT_CLASS_HUGE - flags = NODROP | ABSTRACT - sharp = TRUE - attack_verb = list("sawed", "torn", "cut", "chopped", "diced") - hitsound = 'sound/weapons/chainsaw.ogg' - -/obj/item/nullrod/clown - name = "clown dagger" - icon = 'icons/obj/wizard.dmi' - icon_state = "clownrender" - item_state = "gold_horn" - desc = "Used for absolutely hilarious sacrifices." - hitsound = 'sound/items/bikehorn.ogg' - sharp = TRUE - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut", "honked") - - -/obj/item/nullrod/fedora - name = "binary fedora" - desc = "The brim of the hat is as sharp as the division between 0 and 1. It makes a mighty throwing weapon." - icon = 'icons/obj/clothing/hats.dmi' - icon_state = "fedora" - item_state = "fedora" - slot_flags = ITEM_SLOT_HEAD - force = 0 - throw_speed = 4 - throw_range = 7 - throwforce = 25 // Yes, this is high, since you can typically only use it once in a fight. - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/head.dmi', - "Grey" = 'icons/mob/clothing/species/grey/head.dmi' - ) - -/obj/item/nullrod/armblade - name = "dark blessing" - desc = "Particularly twisted deities grant gifts of dubious value." - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon = 'icons/obj/weapons/melee.dmi' - icon_state = "arm_blade" - item_state = "arm_blade" - flags = ABSTRACT | NODROP - w_class = WEIGHT_CLASS_HUGE - sharp = TRUE - -/obj/item/nullrod/armblade/customised_abstract_text(mob/living/carbon/owner) - return "[owner.p_their(TRUE)] [owner.l_hand == src ? "left arm" : "right arm"] has been turned into a grotesque meat-blade." - -/obj/item/nullrod/armblade/mining - flags = NODROP - reskin_selectable = FALSE //So 2 of the same nullrod doesnt show up. - -/obj/item/nullrod/armblade/mining/pickup(mob/living/user) - ..() - flags += ABSTRACT - -/obj/item/nullrod/armblade/mining/dropped(mob/living/user) - ..() - flags ^= ABSTRACT - -/obj/item/nullrod/carp - name = "carp-sie plushie" - desc = "An adorable stuffed toy that resembles the god of all carp. The teeth look pretty sharp. Activate it to receive the blessing of Carp-Sie." - icon = 'icons/obj/toy.dmi' - icon_state = "carpplushie" - item_state = "carp_plushie" - force = 13 - attack_verb = list("bitten", "eaten", "fin slapped") - hitsound = 'sound/weapons/bite.ogg' - var/used_blessing = FALSE - -/obj/item/nullrod/carp/attack_self__legacy__attackchain(mob/living/user) - if(used_blessing) - return - if(user.mind && !HAS_MIND_TRAIT(user, TRAIT_HOLY)) - return - to_chat(user, "You are blessed by Carp-Sie. Wild space carp will no longer attack you.") - user.faction |= "carp" - used_blessing = TRUE - -/// May as well make it a "claymore" and inherit the blocking -/obj/item/nullrod/claymore/bostaff - name = "monk's staff" - desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts, now used to harass the clown." - icon = 'icons/obj/weapons/melee.dmi' - icon_state = "bostaff0" - lefthand_file = 'icons/mob/inhands/staves_lefthand.dmi' - righthand_file = 'icons/mob/inhands/staves_righthand.dmi' - item_state = "bostaff0" - w_class = WEIGHT_CLASS_BULKY - force = 13 - slot_flags = ITEM_SLOT_BACK - sharp = FALSE - hitsound = "swing_hit" - attack_verb = list("smashed", "slammed", "whacked", "thwacked") - -/obj/item/nullrod/claymore/bostaff/Initialize(mapload) - . = ..() - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.4, _parryable_attack_types = ALL_ATTACK_TYPES, _parry_cooldown = (5 / 3) SECONDS ) // will remove the other component, 0.666667 seconds for 60% uptime. - -/obj/item/nullrod/tribal_knife - name = "arrhythmic knife" - icon_state = "crysknife" - item_state = "crysknife" - w_class = WEIGHT_CLASS_HUGE - desc = "They say fear is the true mind killer, but stabbing them in the head works too. Honour compels you to not sheathe it once drawn." - sharp = TRUE - slot_flags = null - flags = HANDSLOW - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - -/obj/item/nullrod/tribal_knife/New() - ..() - START_PROCESSING(SSobj, src) - -/obj/item/nullrod/tribal_knife/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/nullrod/tribal_knife/process() - slowdown = rand(-2, 2) - -/obj/item/nullrod/pitchfork - name = "unholy pitchfork" - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon_state = "pitchfork0" - item_state = "pitchfork0" - w_class = WEIGHT_CLASS_NORMAL - desc = "Holding this makes you look absolutely devilish." - attack_verb = list("poked", "impaled", "pierced", "jabbed") - hitsound = 'sound/weapons/bladeslice.ogg' - sharp = TRUE - -/obj/item/nullrod/rosary - name = "prayer beads" - icon_state = "rosary" - item_state = null - desc = "A set of prayer beads used by many of the more traditional religions in space.
    Vampires and other unholy abominations have learned to fear these." - force = 0 - throwforce = 0 - var/praying = FALSE - -/obj/item/nullrod/rosary/attack__legacy__attackchain(mob/living/carbon/M, mob/living/carbon/user) - if(!iscarbon(M)) - return ..() - - if(!user.mind || !HAS_MIND_TRAIT(user, TRAIT_HOLY)) - to_chat(user, "You are not close enough with [SSticker.Bible_deity_name] to use [src].") - return - - if(praying) - to_chat(user, "You are already using [src].") - return - - user.visible_message("[user] kneels[M == user ? null : " next to [M]"] and begins to utter a prayer to [SSticker.Bible_deity_name].", - "You kneel[M == user ? null : " next to [M]"] and begin a prayer to [SSticker.Bible_deity_name].") - - praying = TRUE - if(do_after(user, 15 SECONDS, target = M)) - if(ishuman(M)) - var/mob/living/carbon/human/target = M - - if(target.mind) - if(IS_CULTIST(target)) - var/datum/antagonist/cultist/cultist = IS_CULTIST(target) - cultist.remove_gear_on_removal = TRUE - target.mind.remove_antag_datum(/datum/antagonist/cultist) - praying = FALSE - return - var/datum/antagonist/vampire/V = M.mind?.has_antag_datum(/datum/antagonist/vampire) - if(V?.get_ability(/datum/vampire_passive/full)) // Getting a full prayer off on a vampire will interrupt their powers for a large duration. - V.adjust_nullification(120, 50) - to_chat(target, "[user]'s prayer to [SSticker.Bible_deity_name] has interfered with your power!") - praying = FALSE - return - - if(prob(25)) - to_chat(target, "[user]'s prayer to [SSticker.Bible_deity_name] has eased your pain!") - target.adjustToxLoss(-5) - target.adjustOxyLoss(-5) - target.adjustBruteLoss(-5) - target.adjustFireLoss(-5) - - praying = FALSE - - else - to_chat(user, "Your prayer to [SSticker.Bible_deity_name] was interrupted.") - praying = FALSE - - -/obj/item/nullrod/nazar - name = "nazar" - icon_state = "nazar" - item_state = null - desc = "A set of glass beads and amulet, which has been forged to provide powerful magic protection to the wielder." - force = 0 - throwforce = 0 - antimagic_type = ALL - -/obj/item/nullrod/salt - name = "Holy Salt" - icon = 'icons/obj/food/containers.dmi' - icon_state = "saltshakersmall" - desc = "While commonly used to repel some ghosts, it appears others are downright attracted to it." - force = 0 - throwforce = 0 - var/ghostcall_CD = 0 - - -/obj/item/nullrod/salt/attack_self__legacy__attackchain(mob/user) - - if(!user.mind || !HAS_MIND_TRAIT(user, TRAIT_HOLY)) - to_chat(user, "You are not close enough with [SSticker.Bible_deity_name] to use [src].") - return - - if(!(ghostcall_CD > world.time)) - ghostcall_CD = world.time + 5 MINUTES - user.visible_message("[user] kneels and begins to utter a prayer to [SSticker.Bible_deity_name] while drawing a circle with salt!", - "You kneel and begin a prayer to [SSticker.Bible_deity_name] while drawing a circle!") - notify_ghosts("The Chaplain is calling ghosts to [get_area(src)] with [name]!", source = src) - else - to_chat(user, "You need to wait before using [src] again.") - return - - -/obj/item/nullrod/rosary/bread - name = "prayer bread" - icon = 'icons/obj/food/bakedgoods.dmi' - icon_state = "baguette" - desc = "a staple of worshipers of the Silentfather, this holy mime artifact has an odd effect on clowns." - var/list/smited_clowns - -/obj/item/nullrod/rosary/bread/equipped(mob/user, slot, initial = FALSE) - . = ..() - if(ishuman(user) && (slot & ITEM_SLOT_BOTH_HANDS)) - START_PROCESSING(SSobj, src) - else - STOP_PROCESSING(SSobj, src) - -/obj/item/nullrod/rosary/bread/dropped(mob/user, silent) - . = ..() - STOP_PROCESSING(SSobj, src) - -/obj/item/nullrod/rosary/bread/Destroy() - STOP_PROCESSING(SSobj, src) - for(var/clown in smited_clowns) - unsmite_clown(clown) - return ..() - -/obj/item/nullrod/rosary/bread/process() - var/mob/living/carbon/human/holder = loc - //would like to make the holder mime if they have it in on thier person in general - for(var/mob/living/carbon/human/H in range(5, loc)) - if(H.mind.assigned_role == "Clown" && !LAZYACCESS(smited_clowns, H)) - LAZYSET(smited_clowns, H, TRUE) - H.Silence(20 SECONDS) - animate_fade_grayscale(H, 2 SECONDS) - - addtimer(CALLBACK(src, PROC_REF(unsmite_clown), H), 20 SECONDS) - - if(prob(10)) - to_chat(H, "Being in the presence of [holder]'s [src] is interfering with your honk!") - -/obj/item/nullrod/rosary/bread/proc/unsmite_clown(mob/living/carbon/human/hell_spawn) - animate_fade_colored(hell_spawn, 2 SECONDS) - LAZYREMOVE(smited_clowns, hell_spawn) - -/obj/item/nullrod/missionary_staff - name = "holy staff" - desc = "It has a mysterious, protective aura." - reskinned = TRUE - reskin_selectable = FALSE - icon_state = "godstaff-red" - lefthand_file = 'icons/mob/inhands/staves_lefthand.dmi' - righthand_file = 'icons/mob/inhands/staves_righthand.dmi' - item_state = "godstaff-red" - w_class = WEIGHT_CLASS_HUGE - force = 5 - slot_flags = ITEM_SLOT_BACK - - var/team_color = "red" - var/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/robes = null //the robes linked with this staff - var/faith = 99 //a conversion requires 100 faith to attempt. faith recharges over time while you are wearing missionary robes that have been linked to the staff. - -/obj/item/nullrod/missionary_staff/examine(mob/living/user) - . = ..() - if(isAntag(user)) - . += "This seemingly standard holy staff is actually a disguised neurotransmitter capable of inducing blind zealotry in its victims. It must be allowed to recharge in the presence of a linked set of missionary robes. \ - Use the staff in hand while wearing robes to link them both, then aim the staff at your victim to try and convert them." - - -/obj/item/nullrod/missionary_staff/New() - ..() - team_color = pick("red", "blue") - icon_state = "godstaff-[team_color]" - item_state = "godstaff-[team_color]" - name = "[team_color] holy staff" - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES) - -/obj/item/nullrod/missionary_staff/Destroy() - if(robes) //delink on destruction - robes.linked_staff = null - robes = null - return ..() - -/obj/item/nullrod/missionary_staff/attack_self__legacy__attackchain(mob/user) - if(robes) //as long as it is linked, sec can't try to meta by stealing your staff and seeing if they get the link error message - return FALSE - if(!ishuman(user)) //prevents the horror (runtimes) of missionary xenos and other non-human mobs that might be able to activate the item - return FALSE - var/mob/living/carbon/human/missionary = user - if(missionary.wear_suit && istype(missionary.wear_suit, /obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe)) - var/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/robe_to_link = missionary.wear_suit - if(robe_to_link.linked_staff) - to_chat(missionary, "These robes are already linked with a staff and cannot support another. Connection refused.") - return FALSE - robes = robe_to_link - robes.linked_staff = src - to_chat(missionary, "Link established. Faith generators initialized. Go spread the word.") - faith = 100 //full charge when a fresh link is made (can't be delinked without destroying the robes so this shouldn't be an exploitable thing) - return TRUE - else - to_chat(missionary, "You must be wearing the missionary robes you wish to link with this staff.") - return FALSE - -/obj/item/nullrod/missionary_staff/afterattack__legacy__attackchain(mob/living/carbon/human/target, mob/living/carbon/human/missionary, flag, params) - if(!ishuman(target) || !ishuman(missionary)) //ishuman checks - return - if(target == missionary) //you can't convert yourself, that would raise too many questions about your own dedication to the cause - return - if(!robes) //staff must be linked to convert - to_chat(missionary, "You must link your staff to a set of missionary robes before attempting conversions.") - return - if(!missionary.wear_suit || missionary.wear_suit != robes) //must be wearing the robes to convert - return - if(faith < 100) - to_chat(missionary, "You don't have enough faith to attempt a conversion right now.") - return - to_chat(missionary, "You concentrate on [target] and begin the conversion ritual...") - if(!target.mind) //no mind means no conversion, but also means no faith lost. - to_chat(missionary, "You halt the conversion as you realize [target] is mindless! Best to save your faith for someone more worthwhile.") - return - to_chat(target, "Your mind seems foggy. For a moment, all you can think about is serving the greater good... the greater good...") - if(do_after(missionary, 80)) //8 seconds to temporarily convert, roughly 3 seconds slower than a vamp's enthrall, but its a ranged thing - if(faith < 100) //to stop people from trying to exploit the do_after system to multi-convert, we check again if you have enough faith when it completes - to_chat(missionary, "You don't have enough faith to complete the conversion on [target]!") - return - if(missionary in viewers(target)) //missionary must maintain line of sight to target, but the target doesn't necessary need to be able to see the missionary - do_convert(target, missionary) - else - to_chat(missionary, "You lost sight of the target before [target.p_they()] could be converted!") - faith -= 25 //they escaped, so you only lost a little faith (to prevent spamming) - else //the do_after failed, probably because you moved or dropped the staff - to_chat(missionary, "Your concentration was broken!") - -/obj/item/nullrod/missionary_staff/proc/do_convert(mob/living/carbon/human/target, mob/living/carbon/human/missionary) - var/convert_duration = 10 MINUTES - - if(!target || !ishuman(target) || !missionary || !ishuman(missionary)) - return - if(IS_MINDSLAVE(target) || target.mind.zealot_master) //mindslaves and zealots override the staff because the staff is just a temporary mindslave - to_chat(missionary, "Your faith is strong, but [target.p_their()] mind is already slaved to someone else's ideals. Perhaps an inquisition would reveal more...") - faith -= 25 //same faith cost as losing sight of them mid-conversion, but did you just find someone who can lead you to a fellow traitor? - return - if(ismindshielded(target)) - faith -= 75 - to_chat(missionary, "Your faith is strong, but [target.p_their()] mind remains closed to your ideals. Your resolve helps you retain a bit of faith though.") - return - else if(target.mind.assigned_role == "Psychiatrist" || target.mind.assigned_role == "Librarian") //fancy book lernin helps counter religion (day 0 job love, what madness!) - if(prob(35)) //35% chance to fail - to_chat(missionary, "This one is well trained in matters of the mind... They will not be swayed as easily as you thought...") - faith -=50 //lose half your faith to the book-readers - return - else - to_chat(missionary, "You successfully convert [target] to your cause. The following grows because of your faith!") - faith -= 100 - else if(target.mind.assigned_role == "Assistant") - if(prob(55)) //55% chance to take LESS faith than normal, because assistants are stupid and easily manipulated - to_chat(missionary, "Your message seems to resound well with [target]; converting [target.p_them()] was much easier than expected.") - faith -= 50 - else //45% chance to take the normal 100 faith cost - to_chat(missionary, "You successfully convert [target] to your cause. The following grows because of your faith!") - faith -= 100 - else //everyone else takes 100 faith cost because they are normal - to_chat(missionary, "You successfully convert [target] to your cause. The following grows because of your faith!") - faith -= 100 - //if you made it this far: congratulations! you are now a religious zealot! - target.mind.make_zealot(missionary, convert_duration, team_color) - - SEND_SOUND(target, sound('sound/misc/wololo.ogg', volume = 25)) - missionary.say("WOLOLO!") - SEND_SOUND(missionary, sound('sound/misc/wololo.ogg', volume = 25)) diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm deleted file mode 100644 index ab8529afb20ad..0000000000000 --- a/code/game/objects/items/weapons/kitchen.dm +++ /dev/null @@ -1,328 +0,0 @@ -/* Kitchen tools - * Contains: - * Utensils - * Spoons - * Forks - * Knives - * Kitchen knives - * Butcher's cleaver - * Rolling Pins - * Candy Moulds - * Sushi Mat - * Circular cutter - */ - -/obj/item/kitchen - icon = 'icons/obj/kitchen.dmi' - origin_tech = "materials=1" - - - - -/* - * Utensils - */ -/obj/item/kitchen/utensil - lefthand_file = 'icons/mob/inhands/utensil_lefthand.dmi' - righthand_file = 'icons/mob/inhands/utensil_righthand.dmi' - force = 5.0 - w_class = WEIGHT_CLASS_TINY - throwforce = 0.0 - throw_speed = 3 - throw_range = 5 - flags = CONDUCT - attack_verb = list("attacked", "stabbed", "poked") - hitsound = 'sound/weapons/bladeslice.ogg' - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 30) - sharp = FALSE - var/max_contents = 1 - -/obj/item/kitchen/utensil/New() - ..() - if(prob(60)) - src.pixel_y = rand(0, 4) - - create_reagents(5) - -/obj/item/kitchen/utensil/attack__legacy__attackchain(mob/living/carbon/C, mob/living/carbon/user) - if(!istype(C)) - return ..() - - if(user.a_intent != INTENT_HELP) - if(user.zone_selected == "head" || user.zone_selected == "eyes") - if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) - C = user - return eyestab(C, user) - else - return ..() - - if(length(contents)) - var/obj/item/food/toEat = contents[1] - if(istype(toEat)) - if(C.eat(toEat, user)) - toEat.On_Consume(C, user) - overlays.Cut() - return - - -/obj/item/kitchen/utensil/fork - name = "fork" - desc = "It's a fork. Sure is pointy." - icon_state = "fork" - -/obj/item/kitchen/utensil/pfork - name = "plastic fork" - desc = "Yay, no washing up to do." - icon_state = "pfork" - -/obj/item/kitchen/utensil/spoon - name = "spoon" - desc = "It's a spoon. You can see your own upside-down face in it." - icon_state = "spoon" - attack_verb = list("attacked", "poked") - -/obj/item/kitchen/utensil/pspoon - name = "plastic spoon" - desc = "It's a plastic spoon. How dull." - icon_state = "pspoon" - attack_verb = list("attacked", "poked") - -/obj/item/kitchen/utensil/spork - name = "spork" - desc = "It's a spork. Marvel at its innovative design." - icon_state = "spork" - attack_verb = list("attacked", "sporked") - -/obj/item/kitchen/utensil/pspork - name = "plastic spork" - desc = "It's a plastic spork. It's the fork side of the spoon!" - icon_state = "pspork" - attack_verb = list("attacked", "sporked") - -/* - * Knives - */ -/obj/item/kitchen/knife - name = "kitchen knife" - icon_state = "knife" - desc = "A general purpose Chef's Knife made by SpaceCook Incorporated. Guaranteed to stay sharp for years to come." - flags = CONDUCT - force = 10 - w_class = WEIGHT_CLASS_SMALL - throwforce = 10 - hitsound = 'sound/weapons/bladeslice.ogg' - throw_speed = 3 - throw_range = 6 - materials = list(MAT_METAL=12000) - attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - sharp = TRUE - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50) - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - var/bayonet = FALSE //Can this be attached to a gun? - -/obj/item/kitchen/knife/Initialize(mapload) - . = ..() - AddComponent(/datum/component/surgery_initiator/robo) - -/obj/item/kitchen/knife/suicide_act(mob/user) - user.visible_message(pick("[user] is slitting [user.p_their()] wrists with [src]! It looks like [user.p_theyre()] trying to commit suicide!", \ - "[user] is slitting [user.p_their()] throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!", \ - "[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!")) - return BRUTELOSS - -/obj/item/kitchen/knife/plastic - name = "plastic knife" - desc = "The bluntest of blades." - icon_state = "pknife" - sharp = FALSE - -/obj/item/kitchen/knife/ritual - name = "ritual knife" - desc = "The unearthly energies that once powered this blade are now dormant." - icon = 'icons/obj/wizard.dmi' - icon_state = "render" - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/kitchen/knife/shiv - name = "glass shiv" - desc = "A haphazard sharp object wrapped in cloth, just like great-great-great-great grandma used to make." - icon = 'icons/obj/weapons/melee.dmi' - item_state = "glass_shiv" - icon_state = "glass_shiv" - -/obj/item/kitchen/knife/shiv/carrot - name = "carrot shiv" - desc = "Unlike other carrots, you should probably keep this far away from your eyes." - icon = 'icons/obj/kitchen.dmi' - icon_state = "carrotshiv" - item_state = "carrotshiv" - force = 8 - throwforce = 12 //fuck git - materials = list() - origin_tech = "biotech=3;combat=2" - attack_verb = list("shanked", "shivved") - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 0, ACID = 0) - -/obj/item/kitchen/knife/butcher - name = "butcher's cleaver" - icon_state = "butch" - desc = "A huge thing used for chopping and chopping up meat. This includes clowns and clown-by-products." - flags = CONDUCT - force = 15 - throwforce = 8 - attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/kitchen/knife/butcher/meatcleaver - name = "meat cleaver" - icon_state = "mcleaver" - item_state = "butch" - force = 25 - throwforce = 15 - -/obj/item/kitchen/knife/butcher/meatcleaver/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_BUTCHERS_HUMANS, ROUNDSTART_TRAIT) - -/obj/item/kitchen/knife/combat - name = "combat knife" - icon_state = "combatknife" - item_state = "knife" - desc = "A military combat utility survival knife." - force = 20 - throwforce = 20 - origin_tech = "materials=3;combat=4" - attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut") - bayonet = TRUE - -/obj/item/kitchen/knife/combat/survival - name = "survival knife" - icon_state = "survivalknife" - desc = "A hunting grade survival knife." - force = 15 - throwforce = 15 - -/obj/item/kitchen/knife/combat/survival/bone - name = "bone dagger" - item_state = "bone_dagger" - icon_state = "bone_dagger" - lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' - righthand_file = 'icons/mob/inhands/items_righthand.dmi' - desc = "A sharpened bone. The bare minimum in survival." - materials = list() - -/obj/item/kitchen/knife/combat/cyborg - name = "cyborg knife" - icon = 'icons/obj/items_cyborg.dmi' - icon_state = "knife" - desc = "A cyborg-mounted plasteel knife. Extremely sharp and durable." - origin_tech = null - -/obj/item/kitchen/knife/cheese - name = "cheese knife" - desc = "A blunt knife used to slice cheese." - icon_state = "knife-cheese" - force = 3 - -/* - * Rolling Pins - */ - -/obj/item/kitchen/rollingpin - name = "rolling pin" - desc = "Used to knock out the Bartender." - icon_state = "rolling_pin" - force = 8.0 - throwforce = 10.0 - throw_speed = 3 - throw_range = 7 - w_class = WEIGHT_CLASS_NORMAL - attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") - -/* Trays moved to /obj/item/storage/bag */ - -/* - * Candy Moulds - */ - -/obj/item/kitchen/mould - name = "generic candy mould" - desc = "You aren't sure what it's supposed to be." - icon_state = "mould" - force = 5 - throwforce = 5 - throw_speed = 3 - throw_range = 3 - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed") - -/obj/item/kitchen/mould/bear - name = "bear-shaped candy mould" - desc = "It has the shape of a small bear imprinted into it." - icon_state = "mould_bear" - -/obj/item/kitchen/mould/worm - name = "worm-shaped candy mould" - desc = "It has the shape of a worm imprinted into it." - icon_state = "mould_worm" - -/obj/item/kitchen/mould/bean - name = "bean-shaped candy mould" - desc = "It has the shape of a bean imprinted into it." - icon_state = "mould_bean" - -/obj/item/kitchen/mould/ball - name = "ball-shaped candy mould" - desc = "It has a small sphere imprinted into it." - icon_state = "mould_ball" - -/obj/item/kitchen/mould/cane - name = "cane-shaped candy mould" - desc = "It has the shape of a cane imprinted into it." - icon_state = "mould_cane" - -/obj/item/kitchen/mould/cash - name = "cash-shaped candy mould" - desc = "It has the shape and design of fake money imprinted into it." - icon_state = "mould_cash" - -/obj/item/kitchen/mould/coin - name = "coin-shaped candy mould" - desc = "It has the shape of a coin imprinted into it." - icon_state = "mould_coin" - -/obj/item/kitchen/mould/loli - name = "sucker mould" - desc = "It has the shape of a sucker imprinted into it." - icon_state = "mould_loli" - -/* - * Sushi Mat - */ -/obj/item/kitchen/sushimat - name = "Sushi Mat" - desc = "A wooden mat used for efficient sushi crafting." - icon_state = "sushi_mat" - force = 5 - throwforce = 5 - throw_speed = 3 - throw_range = 3 - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("rolled", "cracked", "battered", "thrashed") - - - -/// circular cutter by Ume - -/obj/item/kitchen/cutter - name = "generic circular cutter" - desc = "A generic circular cutter for cookies and other things." - icon = 'icons/obj/kitchen.dmi' - icon_state = "circular_cutter" - force = 5 - throwforce = 5 - throw_speed = 3 - throw_range = 3 - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("bashed", "slashed", "pricked", "thrashed") diff --git a/code/game/objects/items/weapons/knuckledusters.dm b/code/game/objects/items/weapons/knuckledusters.dm deleted file mode 100644 index 51a5b5ca69739..0000000000000 --- a/code/game/objects/items/weapons/knuckledusters.dm +++ /dev/null @@ -1,91 +0,0 @@ -/obj/item/melee/knuckleduster - name = "knuckleduster" - desc = "Simple metal punch enhancers, perfect for bar brawls." - icon = 'icons/obj/weapons/knuckleduster.dmi' - icon_state = "knuckleduster" - flags = CONDUCT - force = 10 - throwforce = 3 - w_class = WEIGHT_CLASS_SMALL - resistance_flags = FIRE_PROOF - materials = list(MAT_METAL = 500) - origin_tech = "combat=2" - attack_verb = list("struck", "bludgeoned", "bashed", "smashed") - hitsound = null - /// Is the weapon gripped or not? - var/gripped = FALSE - /// Can the weapon damage organs directly or not? - var/elite = FALSE - /// How much organ damage can the weapon do? - var/trauma = 5 - -/obj/item/melee/knuckleduster/attack_self__legacy__attackchain(mob/user) - if(!gripped) - gripped = TRUE - to_chat(user, "You tighten your grip on [src], ensuring you won't drop it.") - flags |= (NODROP | ABSTRACT) - else - gripped = FALSE - to_chat(user, "You relax your grip on [src].") - flags &= ~(NODROP | ABSTRACT) - -/obj/item/melee/knuckleduster/dropped(mob/user, silent) - . = ..() - gripped = FALSE - flags &= ~(NODROP | ABSTRACT) - -/obj/item/melee/knuckleduster/attack__legacy__attackchain(mob/living/target, mob/living/user) - . = ..() - hitsound = pick('sound/weapons/punch1.ogg', 'sound/weapons/punch2.ogg', 'sound/weapons/punch3.ogg', 'sound/weapons/punch4.ogg') - if(!ishuman(target) || QDELETED(target)) - return - - var/obj/item/organ/external/punched = target.get_organ(user.zone_selected) - if(!length(punched.internal_organs)) - return - - var/obj/item/organ/internal/squishy = pick(punched.internal_organs) - if(gripped && elite) - squishy.receive_damage(trauma) - if(punched.is_broken()) - squishy.receive_damage(trauma) // Probably not so good for your organs to have your already broken ribs punched hard by a metal object - -/obj/item/melee/knuckleduster/syndie - name = "syndicate knuckleduster" - desc = "For feeling like a real Syndicate Elite when threatening to punch someone to death." - icon_state = "knuckleduster_syndie" - force = 15 - throwforce = 5 - origin_tech = "combat=2;syndicate=1" - elite = TRUE - -/obj/item/melee/knuckleduster/nanotrasen - name = "engraved knuckleduster" - desc = "Perfect for giving that Greytider a golden, painful lesson." - icon_state = "knuckleduster_nt" - force = 10 - throwforce = 5 - origin_tech = null - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF // Steal objectives shouldnt be easy to destroy. - materials = list(MAT_GOLD = 500, MAT_TITANIUM = 200, MAT_PLASMA = 200) - trauma = 10 - -/obj/item/melee/knuckleduster/nanotrasen/Initialize(mapload) - . = ..() - AddElement(/datum/element/high_value_item) - -/obj/item/melee/knuckleduster/nanotrasen/examine_more(mob/user) - . = ..() - . += "These engraved knuckledusters are crafted from 20 karat gold alloyed with plastitanium, all mined from Lavaland. A symbol of prestige and a reminder of the wealth under the feet of the miners working down there." - . += "" - . += "Why exactly Nanotrasen chose to make knuckledusters of all things as that prestige symbol is unclear, \ - but when all the quartermasters were issued them, no-one complained. Most of them got pretty good at using the knuckledusters, too..." - -/obj/item/melee/knuckleduster/admin - name = "handheld bone-breaker" - desc = "Your bones just hurt looking at it." - icon_state = "knuckleduster_nt" - force = 25 - throwforce = 25 - elite = TRUE - trauma = 30 diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm deleted file mode 100644 index 2269e2afece10..0000000000000 --- a/code/game/objects/items/weapons/legcuffs.dm +++ /dev/null @@ -1,300 +0,0 @@ -/obj/item/restraints/legcuffs - name = "leg cuffs" - desc = "Use this to keep prisoners in line." - gender = PLURAL - icon_state = "handcuff" - cuffed_state = "legcuff" - flags = CONDUCT - throwforce = 0 - w_class = WEIGHT_CLASS_NORMAL - origin_tech = "engineering=3;combat=3" - slowdown = 7 - breakouttime = 30 SECONDS - -/obj/item/restraints/legcuffs/beartrap - name = "bear trap" - throw_speed = 1 - throw_range = 1 - icon_state = "beartrap0" - desc = "A trap used to catch bears and other legged creatures." - origin_tech = "engineering=4" - breakouttime = 20 SECONDS - var/armed = FALSE - var/trap_damage = 20 - ///Do we want the beartrap not to make a visable message on arm? Use when a beartrap is applied by something else. - var/silent_arming = FALSE - var/obj/item/grenade/iedcasing/IED = null - var/obj/item/assembly/signaler/sig = null - -/obj/item/restraints/legcuffs/beartrap/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/item/restraints/legcuffs/beartrap/update_icon_state() - icon_state = "beartrap[armed]" - -/obj/item/restraints/legcuffs/beartrap/Destroy() - QDEL_NULL(IED) - QDEL_NULL(sig) - return ..() - -/obj/item/restraints/legcuffs/beartrap/suicide_act(mob/user) - user.visible_message("[user] is sticking [user.p_their()] head in [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/bladeslice.ogg', 50, TRUE, -1) - return BRUTELOSS - -/obj/item/restraints/legcuffs/beartrap/attack_self__legacy__attackchain(mob/user) - ..() - - if(!ishuman(user) || user.restrained()) - return - - if(do_after(user, 2 SECONDS, target = user)) - armed = !armed - update_icon(UPDATE_ICON_STATE) - to_chat(user, "[src] is now [armed ? "armed" : "disarmed"]") - -/obj/item/restraints/legcuffs/beartrap/attackby__legacy__attackchain(obj/item/I, mob/user) //Let's get explosive. - if(istype(I, /obj/item/grenade/iedcasing)) - if(IED) - to_chat(user, "This beartrap already has an IED hooked up to it!") - return - if(sig) - to_chat(user, "This beartrap already has a signaler hooked up to it!") - return - user.drop_item() - I.forceMove(src) - IED = I - message_admins("[key_name_admin(user)] has rigged a beartrap with an IED.") - log_game("[key_name(user)] has rigged a beartrap with an IED.") - to_chat(user, "You sneak [IED] underneath the pressure plate and connect the trigger wire.") - desc = "A trap used to catch bears and other legged creatures. There is an IED hooked up to it." - if(istype(I, /obj/item/assembly/signaler)) - if(IED) - to_chat(user, "This beartrap already has an IED hooked up to it!") - return - if(sig) - to_chat(user, "This beartrap already has a signaler hooked up to it!") - return - sig = I - if(sig.secured) - to_chat(user, "The signaler is secured.") - sig = null - return - user.drop_item() - I.forceMove(src) - to_chat(user, "You sneak [sig] underneath the pressure plate and connect the trigger wire.") - desc = "A trap used to catch bears and other legged creatures. There is a remote signaler hooked up to it." - ..() - -/obj/item/restraints/legcuffs/beartrap/screwdriver_act(mob/living/user, obj/item/I) - if(!IED && !sig) - return - - if(IED) - IED.forceMove(get_turf(src)) - IED = null - to_chat(user, "You remove the IED from [src].") - if(sig) - sig.forceMove(get_turf(src)) - sig = null - to_chat(user, "You remove the signaler from [src].") - return TRUE - -/obj/item/restraints/legcuffs/beartrap/proc/on_atom_entered(datum/source, mob/living/entered) - if(!armed || !isturf(loc) || !istype(entered)) - return - - if((iscarbon(entered) || isanimal(entered)) && !HAS_TRAIT(entered, TRAIT_FLYING)) - spring_trap(entered) - - if(ishuman(entered)) - var/mob/living/carbon/H = entered - if(IS_HORIZONTAL(H)) - H.apply_damage(trap_damage, BRUTE, "chest") - else - H.apply_damage(trap_damage, BRUTE, pick("l_leg", "r_leg")) - if(!H.legcuffed && H.get_num_legs() >= 2) //beartrap can't cuff you leg if there's already a beartrap or legcuffs. - H.legcuffed = src - forceMove(H) - H.update_inv_legcuffed() - SSblackbox.record_feedback("tally", "handcuffs", 1, type) - else - if(istype(entered, /mob/living/simple_animal/hostile/bear)) - entered.apply_damage(trap_damage * 2.5, BRUTE) - else - entered.apply_damage(trap_damage * 1.75, BRUTE) - -/obj/item/restraints/legcuffs/beartrap/on_found(mob/finder) - if(!armed) - return FALSE - spring_trap(finder) - - if(ishuman(finder)) - var/mob/living/carbon/H = finder - H.apply_damage(trap_damage, BRUTE, pick("l_hand", "r_hand")) - return TRUE - -/obj/item/restraints/legcuffs/beartrap/proc/spring_trap(mob/user) - armed = FALSE - update_icon() - playsound(loc, 'sound/effects/snap.ogg', 50, TRUE) - if(!silent_arming) - user.visible_message("[user] triggers [src].", "You trigger [src].") - - if(sig) - sig.signal() - - if(IED) - IED.active = TRUE - message_admins("[key_name_admin(usr)] has triggered an IED-rigged [name].") - log_game("[key_name(usr)] has triggered an IED-rigged [name].") - spawn(IED.det_time) - IED.prime() - -/obj/item/restraints/legcuffs/beartrap/energy - name = "energy snare" - armed = TRUE - icon_state = "e_snare1" - trap_damage = 0 - flags = DROPDEL - breakouttime = 6 SECONDS - -/obj/item/restraints/legcuffs/beartrap/energy/New() - ..() - addtimer(CALLBACK(src, PROC_REF(dissipate)), 100) - -/obj/item/restraints/legcuffs/beartrap/energy/proc/dissipate() - if(!ismob(loc)) - do_sparks(1, 1, src) - qdel(src) - -/obj/item/restraints/legcuffs/beartrap/energy/attack_hand(mob/user) - Crossed(user) //honk - -/obj/item/restraints/legcuffs/beartrap/energy/cyborg - breakouttime = 20 // Cyborgs shouldn't have a strong restraint - -/obj/item/restraints/legcuffs/bola - name = "bola" - desc = "A restraining device designed to be thrown at the target. Upon connecting with said target, it will wrap around their legs, making it difficult for them to move quickly." - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon_state = "bola" - item_state = "bola" - breakouttime = 3.5 SECONDS - gender = NEUTER - origin_tech = "engineering=3;combat=1" - hitsound = 'sound/effects/snap.ogg' - throw_range = 0 // increased when throw mode is enabled - /// is the bola reuseable? - var/reuseable = TRUE - ///the duration of the knockdown in seconds - var/knockdown_duration = 0 - /// the number of spins till the bola gets the maximum throw distance. each spin takes 1 second - var/max_spins = 3 - /// the max range after the bola fully spins up. if your value for this isn't divisable by the value of `max_spins` it will be lower than the max - var/max_range = 7 - /// the max speed after the bola fully spins up. if your value for this isn't divisable by the value of `max_spins` it will be lower than the max - var/max_speed = 2 - /// are we currently spinning the bola - var/spinning = FALSE - -/obj/item/restraints/legcuffs/bola/Initialize(mapload) - . = ..() - RegisterSignal(src, COMSIG_CARBON_TOGGLE_THROW, PROC_REF(spin_up_wrapper)) - -/obj/item/restraints/legcuffs/bola/proc/spin_up_wrapper(datum/source, throw_mode_state) // so that signal handler works - SIGNAL_HANDLER - if(throw_mode_state) // if we actually turned throw mode on - INVOKE_ASYNC(src, PROC_REF(spin_up)) - -/obj/item/restraints/legcuffs/bola/proc/spin_up() - if(spinning) - return - var/mob/living/L = loc // can only be called if the mob is holding the bola. - var/range_increment = round(max_range / max_spins) - var/speed_increment = round(max_speed / max_spins) - RegisterSignal(L, COMSIG_CARBON_SWAP_HANDS, PROC_REF(reset_values), override = TRUE) - item_state = "[initial(item_state)]_spin" - L.update_inv_r_hand() - L.update_inv_l_hand() - spinning = TRUE - for(var/i in 1 to max_spins) - if(!do_mob(L, L, 1 SECONDS, only_use_extra_checks = TRUE, extra_checks = list(CALLBACK(src, PROC_REF(can_spin_check), L)))) - reset_values(L) - break - throw_range += range_increment - throw_speed += speed_increment - -/obj/item/restraints/legcuffs/bola/end_throw() - reset_values() - -/obj/item/restraints/legcuffs/bola/equipped(mob/user, slot, initial) // switching hands with it or putting it into/out of a bag resets it. - . = ..() - reset_values() - -/obj/item/restraints/legcuffs/bola/proc/reset_values(mob/living/user) - throw_range = initial(throw_range) - throw_speed = initial(throw_speed) - item_state = initial(item_state) - spinning = FALSE - if(user) - user.update_inv_r_hand() - user.update_inv_l_hand() - -/// if it returns TRUE, it breaks the loop, returning FALSE, continues the loop -/obj/item/restraints/legcuffs/bola/proc/can_spin_check(mob/living/user) - if(user.get_active_hand() != src) - return TRUE - if(!user.in_throw_mode) - return TRUE - return FALSE - - - -/obj/item/restraints/legcuffs/bola/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) - playsound(loc,'sound/weapons/bolathrow.ogg', 50, TRUE) - if(!..()) - return - -/obj/item/restraints/legcuffs/bola/throw_impact(atom/hit_atom) - reset_values() - if(..() || !iscarbon(hit_atom))//if it gets caught or the target can't be cuffed, - return//abort - var/mob/living/carbon/C = hit_atom - if(!C.legcuffed && C.get_num_legs() >= 2) - visible_message("[src] ensnares [C]!") - C.legcuffed = src - forceMove(C) - C.update_inv_legcuffed() - SSblackbox.record_feedback("tally", "handcuffs", 1, type) - to_chat(C, "[src] ensnares you!") - C.KnockDown(knockdown_duration) - playsound(loc, hitsound, 50, TRUE) - if(!reuseable) - flags |= DROPDEL - -/// traitor variant -/obj/item/restraints/legcuffs/bola/tactical - name = "reinforced bola" - desc = "A strong bola, made with a long steel chain. It looks heavy, enough so that it could trip somebody." - icon_state = "bola_r" - item_state = "bola_r" - breakouttime = 7 SECONDS - origin_tech = "engineering=4;combat=3" - knockdown_duration = 2 SECONDS - -/// For Security -/obj/item/restraints/legcuffs/bola/energy - name = "energy bola" - desc = "A specialized hard-light bola designed to ensnare fleeing criminals and aid in arrests." - icon_state = "ebola" - item_state = "ebola" - hitsound = 'sound/weapons/tase.ogg' - w_class = WEIGHT_CLASS_SMALL - breakouttime = 4 SECONDS - reuseable = FALSE diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm deleted file mode 100644 index 7e43d87e2a64d..0000000000000 --- a/code/game/objects/items/weapons/manuals.dm +++ /dev/null @@ -1,1042 +0,0 @@ -/** - * # MANUALS (BOOKS) - * - * These are "programmatic books," that is books that are hard-coded into the game. Just for the sake of maintainability, keep - * information subject to change (as in likely to change SOON) out of the non-wiki manuals as they require PRs to change - * and it is not an author's responsbility to update manuals if they change a mechanic/recipe/feature referenced in one of them - * Don't worry about adding them to the library, as long as they're one of these types it is automatically added. - * - * Longer Guides should really be a '/obj/item/book/manual/wiki' type book and be tethered to a wiki page, this is because wiki pages - * outside of SOP & Space Law can be very easily changed and do not require going through the Pull Request process. The benefits of - * these are that they can be illustrated, filled with tables, and changed without affecting the codebase. - * - * However, contributors should avoid making every book/page tethered to a wiki page for a few reasons: - * 1. many players who are likely just starting out would benefit from only getting a little bit of info to get started (think 5-10 bar recipes) - * 2. Wiki pages are purposefully dry and to the point, manuals benefit from having flavor/personality to them to make them interesting to read ICly - * 3. One can just open the damn wiki instead of reading a crusty-ass manual - * -Sirryan2002 - */ - -/obj/item/book/manual - //While piracy is a heinious deed, we don't want people uploading programmatic books into the player book DB for obvious reasons - copyright = TRUE - protected = FALSE //No reason players shouldn't write in regular manuals - name = "Book Manual" - desc = "Please make a report on the github if you somehow get ahold of one of these in-game." - summary = "This is a manual procured by Nanotrasen, it contains important information!" - //Pages has to be a list of strings, it will break the book otherwise - pages = list({"How did we get here? Anyway, if you are reading this please make a report on the Github as you should not - be able to possess this object in the first place!"}) - -/obj/item/book/manual/detective - name = "The Film Noir: Proper Procedures for Investigations" - desc = "A gumshoe's guide to find out whodunnit, howdunnit, and wheredunnit." - icon_state ="bookDetective" - author = "Nanotrasen" - title = "The Film Noir: Proper Procedures for Investigations" - pages = list({" - - - - -

    Detective Work

    - Between your bouts of self-narration, and drinking whiskey on the rocks, you might get a case or two to solve.
    - To have the best chance to solve your case, follow these directions: -

    -

      -
    1. Go to the crime scene.
    2. -
    3. Take your scanner and scan EVERYTHING (Yes, the doors, the tables, even the dog.)
    4. -
    5. Once you are reasonably certain you have every scrap of evidence you can use, find all possible entry points and scan them, too.
    6. -
    7. Return to your office.
    8. -
    9. Using your forensic scanning computer, scan your Scanner to upload all of your evidence into the database.
    10. -
    11. Browse through the resulting dossiers, looking for the one that either has the most complete set of prints, or the most suspicious items handled.
    12. -
    13. If you have 80% or more of the print (The print is displayed) go to step 10, otherwise continue to step 8.
    14. -
    15. Look for clues from the suit fibres you found on your perp, and go about looking for more evidence with this new information, scanning as you go.
    16. -
    17. Try to get a fingerprint card of your perp, as if used in the computer, the prints will be completed on their dossier.
    18. -
    19. Assuming you have enough of a print to see it, grab the biggest complete piece of the print and search the security records for it.
    20. -
    21. Since you now have both your dossier and the name of the person, print both out as evidence, and get security to nab your baddie.
    22. -
    23. Give yourself a pat on the back and a bottle of the ships finest vodka, you did it!.
    24. -
    -

    - It really is that easy! Good luck! - - "}) - -/obj/item/book/manual/engineering_particle_accelerator - name = "Particle Accelerator User's Guide" - desc = "An engineer's guide to shooting relativistic particles out of a big gun." - icon_state ="bookParticleAccelerator" - author = "Engineering Encyclopedia" - title = "Particle Accelerator User's Guide" - - pages = list({" - - - - - -

    Experienced user's guide

    - -

    Setting up

    - -
      -
    1. Wrench all pieces to the floor
    2. -
    3. Add wires to all the pieces
    4. -
    5. Close all the panels with your screwdriver
    6. -
    - -

    Use

    - -
      -
    1. Open the control panel
    2. -
    3. Set the speed to 2
    4. -
    5. Start firing at the singularity generator
    6. -
    7. When the singularity reaches a large enough size so it starts moving on it's own set the speed down to 0, but don't shut it off
    8. -
    9. Remember to wear a radiation suit when working with this machine... we did tell you that at the start, right?
    10. -
    - - - "}) - - - -/obj/item/book/manual/supermatter_engine - name = "Supermatter Engine Anomaly Reference" - desc = "An engineer's best tool for dealing with their worst frenemy: The Supermatter and its anomalous behavior." - icon_state = "bookParticleAccelerator" - author = "Vroo-Looum-Kloo" - title = "Supermatter Engine Anomaly Reference" - - pages = list({"Engineering notes on single-stage Supermatter engine,
    - Vroo-Looum-Kloo
    - - The supermatter engine is a very powerful, yet strange method of power generation. This guide will serve as a pocket reference for the myriad of anomalous behaviors it may exhibit throughout your shift. Below is a table of events and their effects.


    - - D Class: Events that only affect certain types of NON-STANDARD setups, minimial operator intervention required. These events occur instantly and engineering will be alerted on telecomms.

    - - D-1: About 200 moles of nitrous oxide are released by the crystal.
    - D-2: About 200 moles of nitrogen are released by the crystal
    - D-3: About 250 moles of CO2 are released by the crystal


    - - C Class: Events with mild effects to standard setups. Operator intervention MAY be required. Engineering will be alerted on telecomms.

    - C-1: 250 moles of oxygen are released by the crystal
    - C-2: 250 moles of plasma are released by the crystal
    - C-3: The temperature at which the engine starts to lose integrity is lowered for a few minutes.


    - - B Class: Events with significant effects to standard setups. Action may need to be taken to prevent a delamination event.

    - B-1: The amount of plasma and O2 released by the engine is doubled for a few minutes.
    - B-2: The amount of heat released by the engine is increased for a few minutes.
    - B-3: The engine's EER is raised slightly above critically for several minutes, regardless of outside factors.


    - - A Class: Events with SEVERE effects to standard setups. Action will need to be taken to prevent a delamination event.

    - A-1: The engine's APC is shorted due to a power spike, requiring its wires to be mended.
    - A-2: The engine's air alarm resets its self as an effect of radiological interference.
    - A-3: The amount of plasma and O2 released by the engine is quadrupled for a few minutes.

    - - S Class events: Events that require immediate intervention and a specialized response to prevent a delamination event. Coordination with other departments is HIGHLY recommended. A warning will be broadcasted on engineering communications before these events.

    - Arc Type: The engine's EER is raised massively several minutes, resulting it a supercritical state.
    - Heat Type: The amount of heat released by the engine is massively increased for several minutes.

    - - In the event that an anomaly NOT on this list presents itself, contact your local Nanotrasen Engineering Officer as soon as possible.
    - -Vroo-Looum-Kloo, Senior Engine Technician."}) - -/obj/item/book/manual/atmospipes - name = "Pipes and You: Getting To Know Your Scary Tools" - desc = "A plumber's guide on how to efficiently plumb and clean out old drone shells." - icon_state = "pipingbook" - author = "Maria Crash, Senior Atmospherics Technician" - title = "Pipes and You: Getting To Know Your Scary Tools" - pages = list({" - - - - - -

    Contents

    -
      -
    1. Author's Forward
    2. -
    3. Basic Piping
    4. -
    5. Insulated Pipes
    6. -
    7. Atmospherics Devices
    8. -
    9. Heat Exchange Systems
    10. -
    11. Final Checks
    12. -
    -

    -

    HOW TO NOT SUCK QUITE SO HARD AT ATMOSPHERICS


    - Or: What the fuck does a "passive gate" do?

    - Alright. It has come to my attention that a variety of people are unsure of what a "pipe" is and what it does. - Apparently there is an unnatural fear of these arcane devices and their "gases". Spooky, spooky. So, - this will tell you what every device constructable by an ordinary pipe dispenser within atmospherics actually does. - You are not going to learn what to do with them to be the super best person ever, or how to play guitar with passive gates, - or something like that. Just what stuff does.

    -

    Basic Pipes


    - The boring ones.
    - Most ordinary pipes are pretty straightforward. They hold gas. If gas is moving in a direction for some reason, gas will flow in that direction. - That's about it. Even so, here's all of your wonderful pipe options.
    -
  • Straight pipes: They're pipes. One-meter sections. Straight line. Pretty simple. Just about every pipe and device is based around this - standard one-meter size, so most things will take up as much space as one of these.
  • -
  • Bent pipes: Pipes with a 90 degree bend at the half-meter mark. My goodness.
  • -
  • Pipe manifolds: Pipes that are essentially a "T" shape, allowing you to connect three things at one point.
  • -
  • 4-way manifold: A four-way junction.
  • -
  • Pipe cap: Caps off the end of a pipe. Open ends don't actually vent gas, because of the way the pipes are assembled, so, uh. Use them to decorate your house or something.
  • -
  • Manual/Digital Valves: A valve that will block off gas flow when turned. Manual valves can't be used by the AI or cyborgs because they don't have hands, but they can access digital valves.
  • -
  • Manual/Digital T-Valves: Like a straight valve, but at the center of a manifold instead of a straight pipe, allowing you to swap between two different pipe networks.


  • -

    Insulated Pipes


    - Special Public Service Announcement.
    - Our regular pipes are already insulated. These are completely worthless. Punch anyone who uses them.

    -

    Devices:


    - They actually do something.
    - This is usually where people get frightened,
    afraid, and start calling on their gods and/or cowering in fear. Yes, I can see you doing that right now. - Stop it. It's unbecoming. Most of these are fairly straightforward.
    -
  • Gas Pump: Take a wild guess. It moves gas in the direction it's pointing (marked by the red line on one end). It moves it based on pressure, the maximum output being 4500 kPa (kilopascals). - Ordinary atmospheric pressure, for comparison, is 101.3 kPa, and the minimum pressure of room-temperature pure oxygen needed to not suffocate in a matter of minutes is 16 kPa - (though 18 is preferred using internals, for various reasons).
  • -
  • Volume pump: This pump goes based on volume, instead of pressure, and the possible maximum pressure it can create in the pipe on the receiving end is double the gas pump because of this, - clocking in at an incredible 9000 kPa. If a pipe with this is destroyed or damaged, and this pressure of gas escapes, it can be incredibly dangerous depending on the size of the pipe filled. - Don't hook this to the distribution loop, or you will make babies cry and the Chief Engineer brutally beat you.
  • -
  • Passive gate: This is essentially a cap on the pressure of gas allowed to flow in a specific direction. - When turned on, instead of actively pumping gas, it measures the pressure flowing through it, and whatever pressure you set is the maximum: it'll cap after that. - In addition, it only lets gas flow one way. As with pumps, the red handle on a passive gate indicates the direction the passive gate will output its gas when active.
  • -
  • Unary vent: The basic vent used in rooms. It pumps or siphons gas in or out of a room depending on the setting. Controlled by the room's air alarm system.
  • -
  • Scrubber: The other half of room equipment. Filters air and can suck it in entirely in what's called a "panic siphon". Activating a panic siphon without very good reason will kill someone. Don't do it. - Scrubbers also have an extended mode that can be enabled to expand the range and increase the amount of gas being filtered.
  • -
  • Passive Vent: Passive vents are the lesser known cousin to Unary vents. Passive vents will exchange gas between the surrounding atmosphere and its connected pipe until the pressure between the two has reached an equilibrium.
  • -
  • Meter: A little box with some gauges and numbers. Fasten it to any pipe or manifold, and it'll read you the pressure in it. Very useful.
  • -
  • Gas mixer: Two sides are input, one side is output. Mixes the gases pumped into it at the ratio defined. The side perpendicular to the other two is "node 2", for reference. - Can output this gas at pressures from 0-4500 kPa.
  • -
  • Gas filter: Essentially the opposite of a gas mixer. One side is input. The other two sides are output. The selected gas type will be filtered into the perpendicular output pipe, - the rest will continue out the other side. Can also output from 0-4500 kPa.
  • -

    Heat Exchange Systems


    - Will not set you on fire.
    - These systems are used to transfer heat only between two pipes. They will not move gases or any other element, but will equalize the temperature (eventually). Note that because of how gases work (remember: pv=nRt), - a higher temperature will raise pressure, and a lower one will lower temperature.
    -
  • Pipe: This is a pipe that will exchange heat with the surrounding atmosphere. Place in a fire for superheating. Place in space for supercooling.
  • -
  • Bent Pipe: Take a wild guess.
  • -
  • Junction:Junction:The point where you connect your normal pipes to heat exchange pipes. Not necessary for heat exchangers, but necessary for H/E pipes/bent pipes.
  • -
  • Heat Exchanger: These funky-looking bits attach to an open pipe end. Put another heat exchanger directly across from it, and you can transfer heat across two pipes without having to have the gases mix. - This normally shouldn't exchange with the ambient air, despite being totally exposed. Just don't ask questions...

  • -

    Final Checks


    - That's about it for pipes. Remember to turn your magboots on and keep a fire extinguisher near. Go forth, armed with this knowledge, and try not to break, burn down, or kill anything. Please.
    - - - "}) - -/obj/item/book/manual/evaguide - name = "EVA Gear and You: Not Spending All Day Inside" - desc = "An enterprising explorer's expedition explainer. Helmet not included!" - icon_state = "evabook" - author = "Maria Crash, Senior Atmospherics Technician" - title = "EVA Gear and You: Not Spending All Day Inside" - pages = list({" - - - - - -

    Contents

    -
      -
    1. A forward on using EVA gear
    2. -
    3. Donning a Civilian Suits
    4. -
    5. Putting on a Hardsuit
    6. -
    7. Final Checks
    8. -
    -

    -

    EVA Gear and You: Not Spending All Day Inside


    - Or: How not to suffocate because there's a hole in your shoes

    - EVA gear. Wonderful to use. It's useful for mining, engineering, and occasionally just surviving, if things are that bad. Most people have EVA training, - but apparently there are some on a space station who don't. This guide should give you a basic idea of how to use this gear, safely. It's split into two sections: - Civilian suits and hardsuits.

    -

    Civilian Suits


    - The bulkiest things this side of Alpha Centauri
    - These suits are the grey ones that are stored in EVA. They're the more simple to get on, but are also a lot bulkier, and provide less protection from environmental hazards such as radiaion or physical impact. - As Medical, Engineering, Security, and Mining all have hardsuits of their own, these don't see much use, but knowing how to put them on is quite useful anyways.

    - First, take the suit. It should be in three pieces: A top, a bottom,
    and a helmet. Put the bottom on first, shoes and the like will fit in it. If you have magnetic boots, however, - put them on on top of the suit's feet. Next, get the top on, as you would a shirt. It can be somewhat awkward putting these pieces on, due to the makeup of the suit, - but to an extent they will adjust to you. You can then find the snaps and seals around the waist, where the two pieces meet. Fasten these, and double-check their tightness. - The red indicators around the waist of the lower half will turn green when this is done correctly. Next, put on whatever breathing apparatus you're using, be it a gas mask or a breath mask. Make sure the oxygen tube is fastened into it. - Put on the helmet now, straight forward, and make sure the tube goes into the small opening specifically for internals. Again, fasten seals around the neck, a small indicator light in the inside of the helmet should go from red to off when all is fastened. - There is a small slot on the side of the suit where an emergency oxygen tank or extended emergency oxygen tank will fit, - but it is reccomended to have a full-sized tank on your back for EVA.

    -

    Hardsuits


    - Heavy, uncomfortable, still the best option.
    - These suits come in Engineering, Mining, and the Armory. There's also a couple Medical Hardsuits in EVA. These provide a lot more protection than the standard suits.

    - Similarly to the other suits, these are split into three parts. Fastening the pant and top are mostly the same as the other spacesuits, with the exception that these are a bit heavier, - though not as bulky. The helmet goes on differently, with the air tube feeing into the suit and out a hole near the left shoulder, while the helmet goes on turned ninety degrees counter-clockwise, - and then is screwed in for one and a quarter full rotations clockwise, leaving the faceplate directly in front of you. There is a small button on the right side of the helmet that activates the helmet light. - The tanks that fasten onto the side slot are emergency tanks, as
    well as full-sized oxygen tanks, leaving your back free for a backpack or satchel.

    -

    FINAL CHECKS:


    -
  • Are all seals fastened correctly?
  • -
  • Do you either have shoes on under the suit, or magnetic boots on over it?
  • -
  • Do you have a mask on and internals on the suit or your back?
  • -
  • Do you have a way to communicate with the station in case something goes wrong?
  • -
  • Do you have a second person watching if this is a training session?

  • - If you don't have any further issues, go out and do whatever is necessary.
    - - - "}) - -/obj/item/book/manual/engineering_singularity_safety - name = "Singularity Safety in Special Circumstances" - desc = "A sufficiently succinct suppliment to securing singularities." - icon_state ="bookEngineeringSingularitySafety" - author = "Engineering Encyclopedia" - title = "Singularity Safety in Special Circumstances" - - pages = list({" - - - - -

    Singularity Safety in Special Circumstances

    - -

    Power outage

    - - A power problem has made the entire station loose power? Could be station-wide wiring problems or syndicate power sinks. In any case follow these steps: -

    - Step one: PANIC!
    - Step two: Get your ass over to engineering! QUICKLY!!!
    - Step three: Get to the Area Power Controller which controls the power to the emitters.
    - Step four: Swipe it with your ID card - if it doesn't unlock, continue with step 15.
    - Step five: Open the console and disengage the cover lock.
    - Step six: Pry open the APC with a Crowbar.
    - Step seven: Take out the empty power cell.
    - Step eight: Put in the new, full power cell - if you don't have one, continue with step 15.
    - Step nine: Quickly put on a Radiation suit.
    - Step ten: Check if the singularity field generators withstood the down-time - if they didn't, continue with step 15.
    - Step eleven: Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering apc is wired to the same powernet, which the powersink is on, you have to remove the piece of wire which links the apc to the powernet. If it wasn't a powersink which caused it, then skip to step 14.
    - Step twelve: Grab your crowbar and pry away the tile closest to the APC.
    - Step thirteen: Use the wirecutters to cut the wire which is conecting the grid to the terminal.
    - Step fourteen: Go to the bar and tell the guys how you saved them all. Stop reading this guide here.
    - Step fifteen: GET THE FUCK OUT OF THERE!!!
    -

    - -

    Shields get damaged

    - - Step one: GET THE FUCK OUT OF THERE!!! FORGET THE WOMEN AND CHILDREN, SAVE YOURSELF!!!
    - - - "}) - -/obj/item/book/manual/medical_cloning - name = "Introduction to Cloning" - desc = "A guide covering the basics of cloning." - icon_state = "bookCloning" - author = "Bioarchitect for the Pillars of Creation" //this is a valid nian name, right? - title = "Introduction to Cloning" - - pages = list({" - - - - - -

    How to Clone People

    - Picture the scene: there's five corpses surrounding you, the Chief Medical Officer is yelling something \ - about terror spiders into their radio, and you only graduated medical school last week. What are you supposed to do?
    \ - Well, Thinktronics Corporation is proud to present you the new and improved TTC-5601 cloning device - capable of \ - economically resuscitating even the most damaged of bodies. What follows is a guide on how to use this newer model \ - of cloning machine and where it differs from previous models. - -
      -
    1. Preparation
    2. -
    3. Load into Cloning Scanner
    4. -
    5. Scan Patient
    6. -
    7. Configure Device
    8. -
    9. Clone
    10. -
    11. Finish Procedure
    12. -
    - -

    Step 1: Preparation

    - Your patient must be dead to clone them (as of the Cloning Regulatory Act of 2533). Therefore, make sure that \ - they are deceased before proceeding, and ideally try to revive them via defibrillation! If that fails, however, \ - you should strip them of their equipment and check to make sure the cloning pod is loaded with, at least, 250 \ - biomass.
    - If your patient has a lot of damage, it'll take a lot of biomass to clone them! If you do not have ample biomass \ - or simply want to conserve it, try to tend to the cadaver's wounds before proceeding. In addition, fixing broken \ - bones and internal bleeds via cloning will consume Osseous Reagent and Sanguine Reagent respectively - these are \ - both much harder to replenish than biomass, so consider being polite to your chemists and fixing these via \ - surgery instead. - -

    Step 2: Load into Cloning Scanner

    - After stripping your patient, load them into the cloning device's scanning machine, as you would with any other \ - device. - -

    Step 3: Scan Patient

    - Access the cloning device's terminal, then navigate to the Damage Configuration menu and click 'scan.' If you see \ - 'Scan Successful' - great! Move on to the next step. If not, the device will inform you about what went wrong with \ - the process. If it says it failed to sequence the patient's brain, try to scan them again in a few seconds. \ - -

    Step 4: Configure Device

    - This step is where the TTC-5601 cloning device diverges from its earlier models. Its advanced systems allow you to \ - conserve resources and elect to not fix certain damages, or elect to fix all damages - all on the fly! Keep \ - in mind that if you're short on resources, you'll have to leave some damages on the patient in order to clone \ - them. Once you're done tweaking settings, proceed to the next step. - -

    Step 5: Clone

    - This is the simplest, but most important step. Simply press 'Clone' in the Damage Configuration menu, and the machine \ - will begin the process of cloning. The process is fully automatic, so feel free to take care of other chores in the \ - meanwhile - like moving the scanned cadaver to the morgue. - -

    Step 6: Finish Procedure

    - After cloning, the patient may be disoriented - help them to get their bearings and put on the gear you stripped from \ - their previous body. In addition, make sure to fix any wounds you may have left to save resources before sending them off. - -

    Congratulations! You now know how to use the TTC-5601 model cloning device. Please direct any further questions you have \ - to your Chief Medical Officer. Warranty void if used on living people, changeling organisms, or cluwnes. - - - "}) - -/obj/item/book/manual/zombie_manual - name = "Plague and You: Curing the Apocalypse" - desc = "A guide covering the basics of curing zombies." - icon_state = "bookCloning" - author = "Cleanses-The-Plague" - title = "Plague and You: Curing the Apocalypse" - - pages = list({" - - - - - - For years, we've seen "zombies" on the news and in movies, but have you ever thought how would would be cured? - Each strain of the "Advanced Resurection Virus" or simply "Necrotizing Plague" has its own unique bio-signature. - Therefore, each strain has a unique step of anti-virals, that each have progressively stronger effects on the plague. - -

      -
    1. Preparation
    2. -
    3. Containing a test subject
    4. -
    5. Creating Cures
    6. -
    7. Cure Effects
    8. -
    9. Known Recipes
    10. -
    - -

    Step 1: Preparation

    - First step is knowledge. The necrotizing plague can only be spread through direct fluid contact with an infected individual. \ - Therefore, you should do your best to stay away from the claws and or teeth of zombies. Their claws are covered in a slimy fluid \ - that has a chance of transmitting the disease. Their bites are much more dangerous however, guaranteeing an infection of the plague. \ - Biohazard suits, riot gear, or other thick material are well suited for blocking these infectious attacks, but do not guaratee \ - complete immunity.
    - - To begin, we will need to gather a blood sample from a zombifed individual. To do this, first make sure the \ - zombie is dead and severely damaged. Damaged zombies will slowly heal, and re-awaken once they are healed. \ - Then use a syringe to extract a blood sample, and return to your virology lab.
    - -

    Step 2: Containing a test subject

    - With your new blood sample of the plague, place a monkey in a solitary pen, and infect it with the virus. This test subject \ - will provide us with a steady source of plague blood to experiment with. Lower-sapience creatures are normally not advanced enough to \ - actively seek out the flesh of living creatures, and are safe in captivity. Containing an active zombie is much harder and will require \ - a cell of pure walls or doors. Otherwise, the zombie will be able to break out of it's cell using its claws. - -

    Step 3: Creating Cures

    - Now that a steady source of infected blood is available, we can begin making cures. There are 4 tiers of "cures" for the plague, \ - these are referred to as "Anti-Plague Sequences". By combining chemicals with the plague and viral symptoms, more advanced sequences \ - can be created. These sequences are M-RNA that alters protein synthesis of plague-infected individuals and alter B-lymphocytes to induce\ - specific anti-bodies, countering the effects of the virus. \ - There sequences are classified into 4 categories: Alpha, Beta, Gamma, and Omega. Alpha is the simplest, but weakest. \ - Omega is the most difficult to make as it requires all previous sequences and advanced chemicals.
    - Since each of zombie strains are unique, there is no known recipe for these, and will require experimentation. \ - However, several researchers have compiled chemicals that are commonly found in these cures in the "Known Recipes" section below. - -

    Step 5: Cure Effects

    - Anti-Plague Sequence Alpha is the simplest anti-viral, but it still is the first step against the plague. \ - This cure prevents infection from scratches while in system of the user, and can cure stage 1 infections.
    - - Anti-Plague Sequence Beta is the second anti-viral, and is more complex to make. This sequence has been shown to cure \ - infections that are stage 3 or below. This sequence is sometimes able to cure bites from infected individuals.
    - - Anti-Plague Sequence Gamma is the third anti-viral. This sequence is difficult to manufacture, but is rewarding. \ - It cures all infections that are stage 5 and below, and stops the effects of stage 6 infections, but will not cure \ - stage 6 infections. This helps prevent the rotting of living people into the rotting and shambling corpses of zombies.
    - - Anti-Plague Sequence Omega is the full cure for the zombie plague. This advanced mix of viral symptoms and chemicals is \ - the final cure for any Advanced Resurection Virus. This cure prevents zombies from reviving when in their system, and will \ - slowly return their body to normal, non-infected state.
    - -

    Step 6: Known Recipes

    - Anti-Plague Sequence Alpha -
    - - Anti-Plague Sequence Beta -
      -
    • 1 unit of blood containing zombie plague cured by Anti-Plague Sequence Alpha
    • -
    • 3 random chemicals from the list below, 1 unit of each (Unknown Random Recipe) -
        -
      • Saline-Glucose Solution
      • -
      • Toxin
      • -
      • Atropine
      • -
      • Lye
      • -
      • Soda Water
      • -
      • Happiness
      • -
      • Morphine
      • -
      • Teporone
      • -
      -
    • -
    - - Anti-Plague Sequence Gamma -
      -
    • 1 unit of blood containing zombie plague cured by Anti-Plague Sequence Beta
    • -
    • 1 unit of blood containing an advanced virus with the "Necrotizing Fasciitis" symptom
    • -
    • 3 random chemicals from the list below, 1 unit of each (Unknown Random Recipe) -
        -
      • Yellow Vomit
      • -
      • Jenkem
      • -
      • Charcoal
      • -
      • Egg
      • -
      • Sulphuric acid
      • -
      • Fluorosulfuric Acid
      • -
      • Surge
      • -
      • Ultra-Lube
      • -
      • Mitocholide
      • -
      -
    • -
    - - Anti-Plague Sequence Omega -
      -
    • 1 unit of blood containing zombie plague cured by Anti-Plague Sequence Gamma
    • -
    • 1 unit of blood containing an advanced virus with the "Anti-Bodies Metabolism" symptom
    • -
    • 2 of the chemicals from the list below, 1 unit of each (Unknown Random Recipe) -
        -
      • Colorful Reagent
      • -
      • Bacchus' Blessing
      • -
      • Pentetic Acid
      • -
      • Glyphosate
      • -
      • Lazarus Reagent
      • -
      • Omnizine
      • -
      • Sarin
      • -
      • Ants
      • -
      • Chlorine Trifluoride
      • -
      • Sorium
      • -
      • "????" Reagent
      • -
      • Aranesp
      • -
      -
    • -
    - - Anti-Plague Sequence Duplication -
      -
    • 1 unit of any Anti-Plague Sequence
    • -
    • 1 unit of Sulfonal
    • -
    • 1 unit of Sugar
    • -
    - - -

    Congratulations! You are now qualitifed in creating Anti-Plague Sequences for combatting Class-C resurrecting un-dead beings. \ - Please direct any further questions you have to your Chief Medical Officer.

    - - "}) - -/obj/item/book/manual/ripley_build_and_repair - name = "APLU \"Ripley\" Construction and Operation Manual" - desc = "A guide from a little-known corporation on how to operate a heavy lifter mech. It's filled with disclaimers and pre-signed waivers." - icon_state ="book" - author = "Weyland-Yutani Corp" - title = "APLU \"Ripley\" Construction and Operation Manual" - - pages = list({" - - - - -
    - Weyland-Yutani - Building Better Worlds -

    Autonomous Power Loader Unit \"Ripley\"

    -
    -

    Specifications:

    -
    - -

    Construction:

    -
      -
    1. Connect all exosuit parts to the chassis frame
    2. -
    3. Connect all hydraulic fittings and tighten them up with a wrench
    4. -
    5. Adjust the servohydraulics with a screwdriver
    6. -
    7. Wire the chassis. (Cable is not included.)
    8. -
    9. Use the wirecutters to remove the excess cable if needed.
    10. -
    11. Install the central control module (Not included. Use supplied datadisk to create one).
    12. -
    13. Secure the mainboard with a screwdriver.
    14. -
    15. Install the peripherals control module (Not included. Use supplied datadisk to create one).
    16. -
    17. Secure the peripherals control module with a screwdriver
    18. -
    19. Install the internal armor plating (Not included due to Nanotrasen regulations. Can be made using 5 metal sheets.)
    20. -
    21. Secure the internal armor plating with a wrench
    22. -
    23. Weld the internal armor plating to the chassis
    24. -
    25. Install the external reinforced armor plating (Not included due to Nanotrasen regulations. Can be made using 5 reinforced metal sheets.)
    26. -
    27. Secure the external reinforced armor plating with a wrench
    28. -
    29. Weld the external reinforced armor plating to the chassis
    30. -
    31. -
    32. Additional Information:
    33. -
    34. The firefighting variation is made in a similar fashion.
    35. -
    36. A firesuit must be connected to the Firefighter chassis for heat shielding.
    37. -
    38. Internal armor is plasteel for additional strength.
    39. -
    40. External armor must be installed in 2 parts, totaling 10 sheets.
    41. -
    42. Completed mech is more resiliant against fire, and is a bit more durable overall
    43. -
    44. Nanotrasen is determined to the safety of its investments employees.
    45. -
    - - - -

    Operation

    - Coming soon... - "}) - -/obj/item/book/manual/research_and_development - name = "Research and Development 101" - desc = "The mad scientist's second best friend, after coffee." - icon_state = "rdbook" - author = "Dr. L. Ight" - title = "Research and Development 101" - pages = list({" - - - - - - -

    Science For Dummies

    - So you want to further SCIENCE? Good man/woman/thing! However, SCIENCE is a complicated process even though it's quite easy. For the most part, it's a three step process: -
      -
    1. 1) Deconstruct items in the Scientific Analyzer to advance technology or improve the design.
    2. -
    3. 2) Build unlocked designs in the Protolathe and Circuit Imprinter
    4. -
    5. 3) Repeat!
    6. -
    - - Those are the basic steps to furthing science. What do you do science with, however? Well, you have four major tools: R&D Console, the Scientific Analyzer, the Protolathe, and the Circuit Imprinter. - -

    The R&D Console

    - The R&D console is the cornerstone of any research lab. It is the central system from which the Scientific Analyzer, Protolathe, and Circuit Imprinter (your R&D systems) are controled. More on those systems in their own sections. On its own, the R&D console acts as a database for all your technological gains and new devices you discover. So long as the R&D console remains intact, you'll retain all that SCIENCE you've discovered. Protect it though, because if it gets damaged, you'll lose your data! In addition to this important purpose, the R&D console has a disk menu that lets you transfer data from the database onto disk or from the disk into the database. It also has a settings menu that lets you re-sync with nearby R&D devices (if they've become disconnected), lock the console from the unworthy, upload the data to all other R&D consoles in the network (all R&D consoles are networked by default), connect/disconnect from the network, and purge all data from the database. - NOTE: The technology list screen, circuit imprinter, and protolathe menus are accessible by non-scientists. This is intended to allow 'public' systems for the plebians to utilize some new devices. - -

    Scientific Analyzer

    - This is the source of all technology. Whenever you put a handheld object in it, it analyzes it and determines what sort of technological advancements you can discover from it. If the technology of the object is equal or higher then your current knowledge, you can destroy the object to further those sciences. Some devices (notably, some devices made from the protolathe and circuit imprinter) aren't 100% reliable when you first discover them. If these devices break down, you can put them into the Scientific Analyzer and improve their reliability rather then futher science. If their reliability is high enough ,it'll also advance their related technologies. - -

    Circuit Imprinter

    - This machine, along with the Protolathe, is used to actually produce new devices. The Circuit Imprinter takes glass and various chemicals (depends on the design) to produce new circuit boards to build new machines or computers. It can even be used to print AI modules. - -

    Protolathe

    - This machine is an advanced form of the Autolathe that produce non-circuit designs. Unlike the Autolathe, it can use processed metal, glass, solid plasma, silver, gold, and diamonds along with a variety of chemicals to produce devices. The downside is that, again, not all devices you make are 100% reliable when you first discover them. - -

    Reliability and You

    - As it has been stated, many devices when they're first discovered do not have a 100% reliablity when you first discover them. Instead, the reliablity of the device is dependent upon a base reliability value, whatever improvements to the design you've discovered through the Scientific Analyzer, and any advancements you've made with the device's source technologies. To be able to improve the reliability of a device, you have to use the device until it breaks beyond repair. Once that happens, you can analyze it in a Scientific Analyzer. Once the device reachs a certain minimum reliability, you'll gain tech advancements from it. - -

    Building a Better Machine

    - Many machines produces from circuit boards and inserted into a machine frame require a variety of parts to construct. These are parts like capacitors, batteries, matter bins, and so forth. As your knowledge of science improves, more advanced versions are unlocked. If you use these parts when constructing something, its attributes may be improved. For example, if you use an advanced matter bin when constructing an autolathe (rather then a regular one), it'll hold more materials. Experiment around with stock parts of various qualities to see how they affect the end results! Be warned, however: Tier 3 and higher stock parts don't have 100% reliability and their low reliability may affect the reliability of the end machine. - - - "}) - -/obj/item/book/manual/barman_recipes - name = "Barman Recipes" - desc = "A coffee-stained guide to mixing drinks." - icon_state = "barbook" - author = "Sir John Rose" - title = "Barman Recipes" - pages = list({" - - - - -

    Drinks for dummies

    - Heres a guide for some basic drinks. -

    Manly Dorf:

    - Mix ale and beer into a glass. -

    Grog:

    - Mix rum and water into a glass. -

    Black Russian:

    - Mix vodka and kahlua into a glass. -

    Irish Cream:

    - Mix cream and whiskey into a glass. -

    Screwdriver:

    - Mix vodka and orange juice into a glass. -

    Cafe Latte:

    - Mix milk and coffee into a glass. -

    Mead:

    - Mix Enzyme, water and sugar into a glass. -

    Gin Tonic:

    - Mix gin and tonic into a glass. -

    Classic Martini:

    - Mix vermouth and gin into a glass. - - - "}) - -//* NON-STATION Manuals *// -//These are manuals that should not be available on-station through spawners or the library AT ALL -/obj/item/book/manual/nuclear - name = "Fission Mailed: Nuclear Sabotage 101" - desc = "A blood-spattered book filled with block text, educating the reader on how to detonate nuclear bombs." - icon_state ="bookNuclear" - author = "Syndicate" - protected = TRUE - title = "Fission Mailed: Nuclear Sabotage 101" - pages = list({" - Nuclear Explosives 101:
    - Hello and thank you for choosing the Syndicate for your nuclear information needs.
    - Today's crash course will deal with the operation of a Fusion Class Nanotrasen made Nuclear Device.
    - First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE.
    - Pressing any button on the compacted bomb will cause it to extend and bolt itself into place.
    - If this is done to unbolt it one must completely log in which at this time may not be possible.
    - To make the nuclear device functional:
    -
  • Place the nuclear device in the designated detonation zone.
  • -
  • Extend and anchor the nuclear device from its interface.
  • -
  • Insert the nuclear authorisation disk into slot.
  • -
  • Type numeric authorisation code into the keypad. This should have been provided. Note: If you make a mistake press R to reset the device. -
  • Press the E button to log onto the device.
  • - You now have activated the device. To deactivate the buttons at anytime for example when you've already prepped the bomb for detonation remove the auth disk OR press the R on the keypad.
    - Now the bomb CAN ONLY be detonated using the timer. Manual detonation is not an option.
    - Note: Nanotrasen is a pain in the neck.
    - Toggle off the SAFETY.
    - Note: You wouldn't believe how many Syndicate Operatives with doctorates have forgotten this step.
    - So use the - - and + + to set a det time between 5 seconds and 10 minutes.
    - Then press the timer toggle button to start the countdown.
    - Now remove the auth. disk so that the buttons deactivate.
    - Note: THE BOMB IS STILL SET AND WILL DETONATE
    - Now before you remove the disk if you need to move the bomb you can:
    - Toggle off the anchor, move it, and re-anchor.

    - Good luck. Remember the order:
    - Disk, Code, Safety, Timer, Disk, RUN!
    - Intelligence Analysts believe that normal Nanotrasen procedure is for the Captain to secure the nuclear authorisation disk.
    - Good luck! - "}) - -/obj/item/book/manual/hydroponics_pod_people - name = "The Human Harvest - From seed to market" - desc = "Blurry pictures of people coming out of pods are taped to the cover." - icon_state ="bookHydroponicsPodPeople" - author = "Farmer John" - title = "The Human Harvest - From seed to market" - pages = list({" - - - - -

    Growing Humans

    - - Why would you want to grow humans? Well I'm expecting most readers to be in the slave trade, but a few might actually - want to revive fallen comrades. Growing pod people is easy, but prone to disaster. -

    -

      -
    1. Find a dead person who is in need of cloning.
    2. -
    3. Take a blood sample with a syringe.
    4. -
    5. Inject a seed pack with the blood sample.
    6. -
    7. Plant the seeds.
    8. -
    9. Tend to the plants water and nutrition levels until it is time to harvest the cloned human.
    10. -
    -

    - It really is that easy! Good luck! - - - - "}) - -/** - * # Wiki Page Based Book Manuals - * - * These are programmatic books that source its pages / "content" straight from the wiki - * That means that this content can **ONLY** be changed by editing the wiki - * Space Law and SOP Manuals can only be edited by Wiki Admins - * - * These are automated well enough that as long as the link to the wiki is set correctly in the config and the article name is correct - * these will display (mostly) CSS stripped wiki pages in them. - */ - -/obj/item/book/manual/wiki - name = "Wiki Book Manual" - desc = "This REALLY shouldn't exist in-game, please contact a coder." - copyright = TRUE - protected = TRUE //We absolutely do not want players editing these books, it might fuck up the iframes in them :) - pages = null //we don't want people opening this book until it fully initializes - //Wiki Iframes need a decent bit of room, this will be enough to make the readable without having to expand the window immediately - book_height = 800 - book_width = 800 - ///The Article title of the wiki page being opened in the - "}) - -//* MISCELANIOUS WIKI PAGE MANUALS *// -/obj/item/book/manual/wiki/hacking - name = "Hacking" - desc = "H4ck3r's H3lp3r: How to rewire almost anything." - icon_state ="bookHacking" - author = "Greytider Supreme" - title = "Hacking" - wiki_article_title = "Hacking" - -/obj/item/book/manual/wiki/engineering_guide - name = "Engineering Textbook" - desc = "A wrenches' guide to build simple structures." - icon_state ="bookEngineering2" - author = "Engineering Encyclopedia" - title = "Engineering Textbook" - wiki_article_title = "Guide_to_Engineering" - -//This robotics manual used to take up 400+ lines of code, never again. -/obj/item/book/manual/wiki/robotics_cyborgs - name = "Cyborgs for Dummies" - desc = "Precise instructions on how to construct your very own robotic friend." - icon_state = "borgbook" - author = "XISC" - title = "Cyborgs for Dummies" - wiki_article_title = "Guide_to_Robotics" - -/obj/item/book/manual/wiki/chef_recipes - name = "Chef Recipes" - desc = "Knives, Ovens, and You: A guide to cooking." - icon_state = "cook_book" - author = "Nanotrasen" - title = "Chef Recipes" - wiki_article_title = "Guide_to_Food_and_Drinks#Food" - -/obj/item/book/manual/wiki/engineering_construction - name = "Station Repairs and Construction" - desc = "A guide on how to fix things without duct tape." - icon_state ="bookEngineering" - author = "Engineering Encyclopedia" - title = "Station Repairs and Construction" - wiki_article_title = "Guide_to_Construction" - -/obj/item/book/manual/wiki/faxes - name = "Guide to Faxes" - desc = "Nanotrasen's own manual on how to write faxes." - icon_state ="bookEngineering" - author = "Nanotrasen" - title = "Faxes and You!" - wiki_article_title = "Guide_to_Faxes" - -/obj/item/book/manual/wiki/hydroponics - name = "General Hydroponics" - desc = "A guide outlining the principles of hydroponics." - icon_state ="bookHydroponicsGeneral" - author = "Nanotrasen" - title = "General Hydroponics" - wiki_article_title = "Guide_to_Hydroponics" - -/obj/item/book/manual/wiki/botanist - name = "The Station Botanist Handbook" - desc = "A handbook with instructions and tips for station botanists." - icon_state ="bookHydroponicsBotanist" - author = "Nanotrasen" - title = "The Station Botanist Handbook" - wiki_article_title = "Botanist" - - //* STANDARD OPERATING PROCEDURE MANUALS *// (and space Law) - -/obj/item/book/manual/wiki/security_space_law - name = "Space Law" - desc = "A set of Nanotrasen guidelines for keeping law and order on their space stations." - icon_state = "bookSpaceLaw" - force = 4 //advanced magistrate tactics - author = "Nanotrasen" - title = "Space Law" - wiki_article_title = "Space_law" - -/obj/item/book/manual/wiki/security_space_law/black - name = "Space Law - Limited Edition" - desc = "A leather-bound, immaculately-written copy of JUSTICE." - icon_state = "bookSpaceLawblack" - title = "Space Law - Limited Edition" - -/obj/item/book/manual/wiki/sop_command - name = "Command Standard Operating Procedures" - desc = "A set of guidelines aiming at the safe conduct of all Command activities." - icon_state = "sop_command" - author = "Nanotrasen" - title = "Command Standard Operating Procedures" - wiki_article_title = "Standard_Operating_Procedure_(Command)" - -/obj/item/book/manual/wiki/sop_general - name = "Standard Operating Procedures" - desc = "A set of guidelines aiming at the safe conduct of all station activities." - icon_state = "sop" - author = "Nanotrasen" - title = "Standard Operating Procedures" - wiki_article_title = "Standard_Operating_Procedure" - -/obj/item/book/manual/wiki/sop_legal - name = "Legal Standard Operating Procedures" - desc = "A set of guidelines aiming at the safe conduct of all legal activities." - icon_state = "sop_legal" - author = "Nanotrasen" - title = "Legal Standard Operating Procedures" - wiki_article_title = "Legal_Standard_Operating_Procedure" - -/obj/item/book/manual/wiki/sop_supply - name = "Supply Standard Operating Procedures" - desc = "A set of guidelines aiming at the safe conduct of all supply activities." - icon_state = "sop_cargo" - author = "Nanotrasen" - title = "Supply Standard Operating Procedures" - wiki_article_title = "Standard_Operating_Procedure_(Supply)" - -/obj/item/book/manual/wiki/sop_security - name = "Security Standard Operating Procedures" - desc = "A set of guidelines aiming at the safe conduct of all security activities." - icon_state = "sop_security" - author = "Nanotrasen" - title = "Security Standard Operating Procedures" - wiki_article_title = "Standard_Operating_Procedure_(Security)" - -/obj/item/book/manual/wiki/sop_service - name = "Service Standard Operating Procedures" - desc = "A set of guidelines aiming at the safe conduct of all service activities." - icon_state = "sop_service" - author = "Nanotrasen" - title = "Service Standard Operating Procedures" - wiki_article_title = "Standard_Operating_Procedure_(Service)" - -/obj/item/book/manual/wiki/sop_engineering - name = "Engineering Standard Operating Procedures" - desc = "A set of guidelines aiming at the safe conduct of all engineering activities." - icon_state = "sop_engineering" - author = "Nanotrasen" - title = "Engineering Standard Operating Procedures" - wiki_article_title = "Standard_Operating_Procedure_(Engineering)" - -/obj/item/book/manual/wiki/sop_medical - name = "Medical Standard Operating Procedures" - desc = "A set of guidelines aiming at the safe conduct of all medical activities." - icon_state = "sop_medical" - author = "Nanotrasen" - title = "Medical Standard Operating Procedures" - wiki_article_title = "Standard_Operating_Procedure_(Medical)" - -/obj/item/book/manual/wiki/sop_science - name = "Science Standard Operating Procedures" - desc = "A set of guidelines aiming at the safe conduct of all scientific activities." - icon_state = "sop_science" - author = "Nanotrasen" - title = "Science Standard Operating Procedures" - wiki_article_title = "Standard_Operating_Procedure_(Science)" - -/obj/item/book/manual/sop_ntinstructor - name = "Career Trainer SOP" - desc = "A set of guidelines for Instructors." - icon_state = "sop_legal" - author = "Nanotrasen" - title = "Instructor SOP" - pages = list({" - - - - - -

    Instructor SOP


    -

    -

      -
    1. NT Career Trainers are to wear their company-provided uniform and jacket OR their issued beret/hat at all times while on duty. They are free to choose a beret that best matches their primary field of knowledge if they so desire. Additionally, Identifying equipment SHOULD not be distributed to crew members.
    2. -
    3. NT Career Trainers are to be available to all Crewmembers, regardless of Department. You may not only assist a singular Department.
    4. -
    5. NT Career Trainers are not to do a Trainee's work for them.
    6. -
    7. NT Career Trainers are to use NCT Data Chips only to acquire the access necessary for providing training. They are not to use said access for other purposes.
    8. -
    9. In the event of a lost or stolen NCT Data Chip, the NT Career Trainer is to report the incident to their local Nanotrasen Representative or Station Captain.
    10. -
    11. NT Career Trainers are permitted to carry a flash for self-defense.
    12. -
    - - - "}) - - //* MANUAL SPAWNERS *// (and space Law) - -/obj/item/book/manual/random - icon_state = "random_book" - var/static/list/banned_books = list(/obj/item/book/manual/random, /obj/item/book/manual/nuclear, /obj/item/book/manual/wiki) - -/obj/item/book/manual/random/Initialize(mapload) - ..() - var/newtype = pick(subtypesof(/obj/item/book/manual) - banned_books) - new newtype(loc) - return INITIALIZE_HINT_QDEL diff --git a/code/game/objects/items/weapons/melee/energy_melee_weapons.dm b/code/game/objects/items/weapons/melee/energy_melee_weapons.dm deleted file mode 100644 index bd25fced3f097..0000000000000 --- a/code/game/objects/items/weapons/melee/energy_melee_weapons.dm +++ /dev/null @@ -1,516 +0,0 @@ -/* CONTENTS: -* 1. GENERIC ENERGY BLADE -* 2. ENERGY AXE -* 3. ENERGY SWORD -* 4. ENERGY SAW -* 5. ENERGY CUTLASS -* 6. HARDLIGHT BLADE -* 7. CLEAVING SAW -*/ -////////////////////////////// -// MARK: GENERIC ENERGY BLADE -////////////////////////////// -/obj/item/melee/energy - name = "generic energy blade" - desc = "If you can see this and didn't spawn it in as an admin, make an issue report on GitHub." - icon = 'icons/obj/weapons/energy_melee.dmi' - /// Damage done when active. Does not stack with force_off. - var/force_on = 30 - /// Damage done when thrown while active. Does not stack with throwforce_off. - var/throwforce_on = 20 - /// Used to properly reset the force. - var/force_off - /// Used to properly reset the force. - var/throwforce_off - /// Bonus damage dealt to any mob belonging to specified factions. - var/faction_bonus_force = 0 - /// Any mob with a faction that exists in this list will take bonus damage/effects. - var/list/nemesis_factions - // Most of these are antag weps so we dont want them to be /too/ overt... - stealthy_audio = TRUE - w_class = WEIGHT_CLASS_SMALL - /// Size when active, used to stop you from pocketing it when active. That would be silly. - var/w_class_on = WEIGHT_CLASS_BULKY - /// Alternative appearance when active. - var/icon_state_on - /// What flavour of shanking you perform when the blade is active. - var/list/attack_verb_on = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - hitsound = 'sound/weapons/blade1.ogg' // Probably more appropriate than the previous hitsound. -- Dave - usesound = 'sound/weapons/blade1.ogg' - max_integrity = 200 - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 30) - resistance_flags = FIRE_PROOF - toolspeed = 1 - light_power = 2 - var/brightness_on = 2 - var/colormap = list(red=LIGHT_COLOR_RED, blue=LIGHT_COLOR_LIGHTBLUE, green=LIGHT_COLOR_GREEN, purple=LIGHT_COLOR_PURPLE, rainbow=LIGHT_COLOR_WHITE) - /// Used to mark the item as a cleaving saw so that cigarette_lighter_act() will perform an early return. - var/is_a_cleaving_saw = FALSE - -/obj/item/melee/energy/Initialize(mapload) - . = ..() - force_off = initial(force) //We want to check this only when initializing, not when swapping, so sharpening works. - throwforce_off = initial(throwforce) - RegisterSignal(src, COMSIG_ITEM_SHARPEN_ACT, PROC_REF(try_sharpen)) - -/obj/item/melee/energy/Destroy() - UnregisterSignal(src, COMSIG_ITEM_SHARPEN_ACT) - return ..() - -/obj/item/melee/energy/attack__legacy__attackchain(mob/living/target, mob/living/user) - if(cigarette_lighter_act(user, target)) - return - - var/nemesis_faction = FALSE - if(LAZYLEN(nemesis_factions)) - for(var/F in target.faction) - if(F in nemesis_factions) - nemesis_faction = TRUE - force += faction_bonus_force - nemesis_effects(user, target) - break - . = ..() - if(nemesis_faction) - force -= faction_bonus_force - -/obj/item/melee/energy/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item) - if(is_a_cleaving_saw) - return FALSE - - var/obj/item/clothing/mask/cigarette/cig = ..() - if(!cig) - return !isnull(cig) - - if(!HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) - to_chat(user, "You must activate [src] before you can light [cig] with it!") - return TRUE - - if(target == user) - user.visible_message( - "[user] makes a violent slashing motion, barely missing [user.p_their()] nose as light flashes! \ - [user.p_they(TRUE)] light[user.p_s()] [user.p_their()] [cig] with [src] in the process.", - "You casually slash [src] at [cig], lighting it with the blade.", - "You hear an energy blade slashing something!" - ) - else - user.visible_message( - "[user] makes a violent slashing motion, barely missing the nose of [target] as light flashes! \ - [user.p_they(TRUE)] light[user.p_s()] [cig] in the mouth of [target] with [src] in the process.", - "You casually slash [src] at [cig] in the mouth of [target], lighting it with the blade.", - "You hear an energy blade slashing something!" - ) - user.do_attack_animation(target) - playsound(user.loc, hitsound, 50, TRUE) - cig.light(user, target) - return TRUE - -/obj/item/melee/energy/suicide_act(mob/user) - user.visible_message(pick("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!", \ - "[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!")) - return BRUTELOSS|FIRELOSS - -/obj/item/melee/energy/attack_self__legacy__attackchain(mob/living/carbon/user) - if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) - to_chat(user, "You accidentally cut yourself with [src], like a doofus!") - user.take_organ_damage(5,5) - if(HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) - REMOVE_TRAIT(src, TRAIT_ITEM_ACTIVE, TRAIT_GENERIC) - force = force_off - throwforce = throwforce_off - hitsound = initial(hitsound) - throw_speed = initial(throw_speed) - if(length(attack_verb_on)) - attack_verb = list() - icon_state = initial(icon_state) - w_class = initial(w_class) - playsound(user, 'sound/weapons/saberoff.ogg', 35, 1) //changed it from 50% volume to 35% because deafness - set_light(0) - to_chat(user, "[src] can now be concealed.") - else - ADD_TRAIT(src, TRAIT_ITEM_ACTIVE, TRAIT_GENERIC) - force = force_on - throwforce = throwforce_on - hitsound = 'sound/weapons/blade1.ogg' - throw_speed = 4 - if(length(attack_verb_on)) - attack_verb = attack_verb_on - if(icon_state_on) - icon_state = icon_state_on - set_light(brightness_on, l_color = item_color ? colormap[item_color] : null) - else - icon_state = "sword[item_color]" - set_light(brightness_on, l_color=colormap[item_color]) - w_class = w_class_on - playsound(user, 'sound/weapons/saberon.ogg', 35, 1) //changed it from 50% volume to 35% because deafness - to_chat(user, "[src] is now active.") - - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() - add_fingerprint(user) - return - -/obj/item/melee/energy/get_heat() - if(HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) - return 3500 - return 0 - -/obj/item/melee/energy/proc/try_sharpen(obj/item/item, amount, max_amount) - SIGNAL_HANDLER // COMSIG_ITEM_SHARPEN_ACT - if(force_on > initial(force_on) || force_on >= max_amount) - return COMPONENT_BLOCK_SHARPEN_MAXED - throwforce_on = clamp(throwforce_on + amount, 0, max_amount) - throwforce_off = clamp(throwforce_off + amount, 0, max_amount) - force_on = clamp(force_on + amount, 0, max_amount) - force_off = clamp(force_off + amount, 0, max_amount) - -////////////////////////////// -// MARK: AXE -////////////////////////////// -/obj/item/melee/energy/axe - name = "energy axe" - desc = "An energised battle axe." - icon_state = "axe0" - icon_state_on = "axe1" - force = 40 - force_on = 150 - throwforce = 25 - throwforce_on = 30 - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_NORMAL - w_class_on = WEIGHT_CLASS_HUGE - hitsound = 'sound/weapons/bladeslice.ogg' - flags = CONDUCT - armour_penetration_percentage = 100 - origin_tech = "combat=4;magnets=3" - attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") - attack_verb_on = list() - sharp = TRUE - light_color = LIGHT_COLOR_WHITE - -/obj/item/melee/energy/axe/suicide_act(mob/user) - user.visible_message("[user] swings [src] towards [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") - return BRUTELOSS|FIRELOSS - -////////////////////////////// -// MARK: SWORD -////////////////////////////// -// Base variant. -/obj/item/melee/energy/sword - name = "energy sword" - desc = "May the force be within you." - icon_state = "sword0" - force = 3 - throwforce = 5 - throw_speed = 3 - throw_range = 5 - hitsound = "swing_hit" - embed_chance = 75 - embedded_impact_pain_multiplier = 10 - armour_penetration_percentage = 50 - armour_penetration_flat = 10 - origin_tech = "combat=3;magnets=4;syndicate=4" - sharp = TRUE - var/hacked = FALSE - -/obj/item/melee/energy/sword/New() - ..() - if(item_color == null) - item_color = pick("red", "blue", "green", "purple") - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES, _requires_activation = TRUE) - -/obj/item/melee/energy/sword/examine(mob/user) - . = ..() - . += "Can parry melee attacks and sometimes blocks ranged energy attacks. Use in hand to turn off and on." - -/obj/item/melee/energy/sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) - return ..() - return FALSE - -// Borg variant. -/obj/item/melee/energy/sword/cyborg - var/hitcost = 50 - -/obj/item/melee/energy/sword/cyborg/attack__legacy__attackchain(mob/M, mob/living/silicon/robot/R) - if(R.cell) - var/obj/item/stock_parts/cell/C = R.cell - if(HAS_TRAIT(src, TRAIT_ITEM_ACTIVE) && !(C.use(hitcost))) - attack_self__legacy__attackchain(R) - to_chat(R, "It's out of charge!") - return - ..() - return - -/obj/item/melee/energy/sword/cyborg/saw/New() - ..() - item_color = null - -/obj/item/melee/energy/sword/cyborg/saw/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - return FALSE - -// Syndicate energy sword. -/obj/item/melee/energy/sword/saber - -/obj/item/melee/energy/sword/saber/blue - item_color = "blue" - -/obj/item/melee/energy/sword/saber/purple - item_color = "purple" - -/obj/item/melee/energy/sword/saber/green - item_color = "green" - -/obj/item/melee/energy/sword/saber/red - item_color = "red" - -/obj/item/melee/energy/sword/saber/attackby__legacy__attackchain(obj/item/W, mob/living/user, params) - ..() - if(istype(W, /obj/item/melee/energy/sword/saber)) - if(W == src) - to_chat(user, "You try to attach the end of the energy sword to... itself. You're not very smart, are you?") - if(ishuman(user)) - user.adjustBrainLoss(10) - else - to_chat(user, "You attach the ends of the two energy swords, making a single double-bladed weapon! You're cool.") - var/obj/item/dualsaber/newSaber = new /obj/item/dualsaber(user.loc) - if(src.hacked) // That's right, we'll only check the "original" esword. - newSaber.hacked = TRUE - newSaber.item_color = "rainbow" - qdel(W) - qdel(src) - user.put_in_hands(newSaber) - else if(istype(W, /obj/item/multitool)) - if(!hacked) - hacked = TRUE - item_color = "rainbow" - to_chat(user, "RNBW_ENGAGE") - - if(HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) - icon_state = "swordrainbow" - // Updating overlays, copied from welder code. - // I tried calling attack_self twice, which looked cool, except it somehow didn't update the overlays!! - if(user.r_hand == src) - user.update_inv_r_hand() - else if(user.l_hand == src) - user.update_inv_l_hand() - - else - to_chat(user, "It's already fabulous!") - - -/obj/item/melee/energy/sword/saber/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(!HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) - return FALSE - . = ..() - if(!.) // they did not block the attack - return - if(isprojectile(hitby)) - var/obj/item/projectile/P = hitby - if(P.reflectability == REFLECTABILITY_ENERGY) - owner.visible_message("[owner] parries [attack_text] with [src]!") - add_attack_logs(P.firer, src, "hit by [P.type] but got parried by [src]") - return -1 - owner.visible_message("[owner] blocks [attack_text] with [src]!") - playsound(src, 'sound/weapons/effects/ric3.ogg', 100, TRUE) - return TRUE - - return TRUE - -////////////////////////////// -// MARK: SAW -////////////////////////////// -/// Used by medical Syndicate cyborgs -/obj/item/melee/energy/sword/cyborg/saw - name = "energy saw" - desc = "For heavy duty cutting. It has a carbon-fiber blade in addition to a toggleable hard-light edge to dramatically increase sharpness." - force_on = 30 - force = 18 //About as much as a spear - sharp = TRUE - hitsound = 'sound/weapons/circsawhit.ogg' - icon = 'icons/obj/surgery.dmi' - icon_state = "esaw_0" - icon_state_on = "esaw_1" - hitcost = 75 //Costs more than a standard cyborg esword - item_color = null - w_class = WEIGHT_CLASS_NORMAL - light_color = LIGHT_COLOR_WHITE - tool_behaviour = TOOL_SAW - -////////////////////////////// -// MARK: CUTLASS -////////////////////////////// -/obj/item/melee/energy/sword/pirate - name = "energy cutlass" - desc = "A crude copy of syndicate technology. Favored among space pirates for its small form factor while inactive. Arrrr, matey!" - force_on = 20 - throwforce_on = 10 // No PvP shenanigans, this is main weapon in PvE explorer gameplay and can be obtained very easy - embed_chance = 45 - embedded_impact_pain_multiplier = 4 - armour_penetration_percentage = 0 - armour_penetration_flat = 0 - icon_state = "cutlass0" - icon_state_on = "cutlass1" - light_color = LIGHT_COLOR_RED - origin_tech = "combat=3;magnets=4" - -////////////////////////////// -// MARK: HARDLIGHT BLADE -////////////////////////////// -/obj/item/melee/energy/blade - name = "energy blade" - desc = "A concentrated beam of energy in the shape of a blade. Very stylish... and lethal." - icon_state = "blade" - force = 30 //Normal attacks deal esword damage - hitsound = 'sound/weapons/blade1.ogg' - throwforce = 1//Throwing or dropping the item deletes it. - throw_speed = 3 - throw_range = 1 - w_class = WEIGHT_CLASS_BULKY //So you can't hide it in your pocket or some such. - sharp = TRUE - -/obj/item/melee/energy/blade/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_ITEM_ACTIVE, ROUNDSTART_TRAIT) - -/obj/item/melee/energy/blade/attack_self__legacy__attackchain(mob/user) - return - -/obj/item/melee/energy/blade/hardlight - name = "hardlight blade" - desc = "An extremely sharp blade made out of hard light. Packs quite a punch." - icon_state = "lightblade" - item_state = "lightblade" - -/obj/item/melee/energy/proc/nemesis_effects(mob/living/user, mob/living/target) - return - -////////////////////////////// -// MARK: CLEAVING SAW -////////////////////////////// -/obj/item/melee/energy/cleaving_saw - name = "cleaving saw" - desc = "This saw, effective at drawing the blood of beasts, transforms into a long cleaver that makes use of centrifugal force." - force = 12 - force_on = 20 //force when active - throwforce = 20 - throwforce_on = 20 - icon = 'icons/obj/lavaland/artefacts.dmi' - lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi' - righthand_file = 'icons/mob/inhands/64x64_righthand.dmi' - inhand_x_dimension = 64 - inhand_y_dimension = 64 - icon_state = "cleaving_saw" - icon_state_on = "cleaving_saw_open" - slot_flags = ITEM_SLOT_BELT - is_a_cleaving_saw = TRUE - var/attack_verb_off = list("attacked", "sawed", "sliced", "torn", "ripped", "diced", "cut") - attack_verb_on = list("cleaved", "swiped", "slashed", "chopped") - hitsound = 'sound/weapons/bladeslice.ogg' - w_class = WEIGHT_CLASS_BULKY - sharp = TRUE - faction_bonus_force = 30 - nemesis_factions = list("mining", "boss") - var/transform_cooldown - var/swiping = FALSE - -/obj/item/melee/energy/cleaving_saw/nemesis_effects(mob/living/user, mob/living/target) - if(istype(target, /mob/living/simple_animal/hostile/asteroid/elite)) // you get the bonus damage, but the bleed buildup is too much. - return - var/datum/status_effect/saw_bleed/B = target.has_status_effect(STATUS_EFFECT_SAWBLEED) - if(!B) - if(!HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) //This isn't in the above if-check so that the else doesn't care about active - target.apply_status_effect(STATUS_EFFECT_SAWBLEED) - else - B.add_bleed(B.bleed_buildup) - -/obj/item/melee/energy/cleaving_saw/attack_self__legacy__attackchain(mob/living/carbon/user) - transform_weapon(user) - -/obj/item/melee/energy/cleaving_saw/proc/transform_weapon(mob/living/user, supress_message_text) - if(transform_cooldown > world.time) - return FALSE - - transform_cooldown = world.time + (CLICK_CD_MELEE * 0.5) - user.changeNext_move(CLICK_CD_MELEE * 0.25) - - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(HAS_TRAIT(H, TRAIT_CLUMSY) && prob(50)) - to_chat(H, "You accidentally cut yourself with [src], like a doofus!") - H.take_organ_damage(10,10) - if(HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) - REMOVE_TRAIT(src, TRAIT_ITEM_ACTIVE, TRAIT_GENERIC) - force = force_off - throwforce = throwforce_off - hitsound = initial(hitsound) - throw_speed = initial(throw_speed) - if(length(attack_verb_on)) - attack_verb = list() - icon_state = initial(icon_state) - w_class = initial(w_class) - playsound(user, 'sound/magic/fellowship_armory.ogg', 35, 1) //changed it from 50% volume to 35% because deafness - set_light(0) - to_chat(user, "You close [src]. It will now attack rapidly and cause fauna to bleed.") - else - ADD_TRAIT(src, TRAIT_ITEM_ACTIVE, TRAIT_GENERIC) - force = force_on - throwforce = throwforce_on - hitsound = 'sound/weapons/bladeslice.ogg' - throw_speed = 4 - if(length(attack_verb_on)) - attack_verb = attack_verb_on - if(icon_state_on) - icon_state = icon_state_on - set_light(brightness_on, l_color = item_color ? colormap[item_color] : null) - else - icon_state = "sword[item_color]" - set_light(brightness_on, l_color=colormap[item_color]) - w_class = w_class_on - playsound(user, 'sound/magic/fellowship_armory.ogg', 35, TRUE, frequency = 90000 - (HAS_TRAIT(src, TRAIT_ITEM_ACTIVE) * 30000)) - to_chat(user, "You open [src]. It will now cleave enemies in a wide arc and deal additional damage to fauna.") - - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() - - add_fingerprint(user) - -/obj/item/melee/energy/cleaving_saw/examine(mob/user) - . = ..() - . += "It is [HAS_TRAIT(src, TRAIT_ITEM_ACTIVE) ? "open, will cleave enemies in a wide arc and deal additional damage to fauna":"closed, and can be used for rapid consecutive attacks that cause fauna to bleed"].
    \ - Both modes will build up existing bleed effects, doing a burst of high damage if the bleed is built up high enough.
    \ - Transforming it immediately after an attack causes the next attack to come out faster.
    " - -/obj/item/melee/energy/cleaving_saw/suicide_act(mob/user) - user.visible_message("[user] is [HAS_TRAIT(src, TRAIT_ITEM_ACTIVE) ? "closing [src] on [user.p_their()] neck" : "opening [src] into [user.p_their()] chest"]! It looks like [user.p_theyre()] trying to commit suicide!") - transform_cooldown = 0 - transform_weapon(user, TRUE) - return BRUTELOSS - -/obj/item/melee/energy/cleaving_saw/melee_attack_chain(mob/user, atom/target, params) - ..() - if(!HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) - user.changeNext_move(CLICK_CD_MELEE * 0.5) //when closed, it attacks very rapidly - -/obj/item/melee/energy/cleaving_saw/attack__legacy__attackchain(mob/living/target, mob/living/carbon/human/user) - if(!HAS_TRAIT(src, TRAIT_ITEM_ACTIVE) || swiping || !target.density || get_turf(target) == get_turf(user)) - if(!HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) - faction_bonus_force = 0 - ..() - if(!HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) - faction_bonus_force = initial(faction_bonus_force) - else - var/turf/user_turf = get_turf(user) - var/dir_to_target = get_dir(user_turf, get_turf(target)) - swiping = TRUE - var/static/list/cleaving_saw_cleave_angles = list(0, -45, 45) //so that the animation animates towards the target clicked and not towards a side target - for(var/i in cleaving_saw_cleave_angles) - var/turf/T = get_step(user_turf, turn(dir_to_target, i)) - for(var/mob/living/L in T) - if(user.Adjacent(L) && L.density) - melee_attack_chain(user, L) - swiping = FALSE diff --git a/code/game/objects/items/weapons/melee/melee_misc.dm b/code/game/objects/items/weapons/melee/melee_misc.dm deleted file mode 100644 index 94f09cd1a0a25..0000000000000 --- a/code/game/objects/items/weapons/melee/melee_misc.dm +++ /dev/null @@ -1,583 +0,0 @@ -/obj/item/melee - icon = 'icons/obj/weapons/melee.dmi' - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - needs_permit = TRUE - -/obj/item/melee/chainofcommand - name = "chain of command" - desc = "A tool used by great men to placate the frothing masses." - icon_state = "chain" - item_state = "chain" - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - force = 10 - throwforce = 7 - w_class = WEIGHT_CLASS_NORMAL - origin_tech = "combat=5" - attack_verb = list("flogged", "whipped", "lashed", "disciplined") - hitsound = 'sound/weapons/slash.ogg' //pls replace - - -/obj/item/melee/chainofcommand/suicide_act(mob/user) - to_chat(viewers(user), "[user] is strangling [user.p_themselves()] with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return OXYLOSS - -/obj/item/melee/saber - name = "captain's saber" - desc = "An elegant weapon, for a more civilized age." - icon_state = "saber" - item_state = "saber" - flags = CONDUCT - force = 15 - throwforce = 10 - w_class = WEIGHT_CLASS_BULKY - armour_penetration_percentage = 75 - sharp = TRUE - origin_tech = null - attack_verb = list("lunged at", "stabbed") - hitsound = 'sound/weapons/rapierhit.ogg' - materials = list(MAT_METAL = 1000) - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF // Theft targets should be hard to destroy - // values for slapping - var/slap_sound = 'sound/effects/woodhit.ogg' - COOLDOWN_DECLARE(slap_cooldown) - -/obj/item/melee/saber/examine(mob/user) - . = ..() - . += "The blade looks very well-suited for piercing armour." - -/obj/item/melee/saber/examine_more(mob/user) - . = ..() - . += "Swords are a traditional ceremonial weapon carried by commanding officers of many armies and navies, even long after firearms and laserarms rendered them obsolete. \ - Despite having no roots in such traditions, Nanotrasen participates in them, as these trappings of old tradition help to promote the air of authority the company wishes for its captains to possess." - . += "" - . += "Whilst not intended to actually be used in combat, the ceremonial blades issued by Nanotrasen are in-fact quite functional, \ - able to both inflict grievous wounds on aggressors that get too close, whilst also elegantly parrying their blows (assuming the wielder is skilled with the blade). \ - The sharp edge is adept at hacking unarmored targets, whilst the rigid tip is also quite effective at at defeating even modern body armor with thrusting attacks, as modern armor is generally designed to defeat ballistic and laser weapons rather than swords..." - -/obj/item/melee/saber/Initialize(mapload) - . = ..() - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = NON_PROJECTILE_ATTACKS) - AddElement(/datum/element/high_value_item) - -/obj/item/melee/saber/attack__legacy__attackchain(mob/living/target, mob/living/user) - if(user.a_intent != INTENT_HELP || !ishuman(target)) - return ..() - if(!COOLDOWN_FINISHED(src, slap_cooldown)) - return - var/mob/living/carbon/human/H = target - if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) - user.visible_message("[user] accidentally slaps [user.p_themselves()] with [src]!", \ - "You accidentally slap yourself with [src]!") - slap(user, user) - else - user.visible_message("[user] slaps [H] with the flat of the blade!", \ - "You slap [H] with the flat of the blade!") - slap(target, user) - -/obj/item/melee/saber/proc/slap(mob/living/carbon/human/target, mob/living/user) - user.do_attack_animation(target, ATTACK_EFFECT_DISARM) - playsound(loc, slap_sound, 50, TRUE, -1) - target.AdjustConfused(4 SECONDS, 0, 4 SECONDS) - target.apply_damage(10, STAMINA) - add_attack_logs(user, target, "Slapped by [src]", ATKLOG_ALL) - COOLDOWN_START(src, slap_cooldown, 4 SECONDS) - -/obj/item/melee/saber/suicide_act(mob/user) - user.visible_message(pick("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!", \ - "[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!")) - return BRUTELOSS - -// Traitor Sword -/obj/item/melee/snakesfang - name = "snakesfang" - desc = "A uniquely curved, black and red sword. Extra-edgy and cutting-edge." - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon_state = "snakesfang" - item_state = "snakesfang" - flags = CONDUCT - force = 25 - throwforce = 10 - w_class = WEIGHT_CLASS_BULKY - sharp = TRUE - origin_tech = "combat=6;syndicate=3" - attack_verb = list("slashed", "sliced", "chopped") - hitsound = 'sound/weapons/bladeslice.ogg' - materials = list(MAT_METAL = 1000) - -/obj/item/melee/snakesfang/Initialize(mapload) - . = ..() - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = NON_PROJECTILE_ATTACKS) - -/obj/item/melee/snakesfang/examine_more(mob/user) - . = ..() - . += "A uniquely curved, black and red sword. Extra-edgy and cutting-edge." - . += "" - . += "The MK-IV Enhanced Combat Blade, more colloquially known as the ‘Snakesfang’, is a vicious yet stylish weapon designed \ - by a relatively unknown weapons forge with known ties to the Syndicate. With a wide, curved blade and dual points \ - resembling the fangs of the organization’s serpent motif, the Snakesfang is a statement like no other." - . += "" - . += "While the benefits of its unique design are dubious at best, the Snakesfang is undoubtedly a perilous weapon, with a hardened \ - plastitanium edge that can cause untold harm to a soft target. In the right hands, it can be a terrifying weapon to behold, \ - and it’s said that blood runs down the blade in just the right way, to drip artfully from the twin ‘fangs’ at its apex." - -// Unathi Sword -/obj/item/melee/breach_cleaver - name = "breach cleaver" - desc = "Massive, heavy, and utterly impractical. This sharpened chunk of steel is too big and too heavy to be called a sword." - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - base_icon_state = "breach_cleaver" - icon_state = "breach_cleaver0" - flags = CONDUCT - force = 5 - throwforce = 5 - armour_penetration_flat = 30 - w_class = WEIGHT_CLASS_BULKY - sharp = TRUE - origin_tech = "combat=6;syndicate=5" - attack_verb = list("slashed", "cleaved", "chopped") - hitsound = 'sound/weapons/swordhitheavy.ogg' - materials = list(MAT_METAL = 2000) - /// How much damage the sword does when wielded - var/force_wield = 40 - -/obj/item/melee/breach_cleaver/Initialize(mapload) - . = ..() - AddComponent(/datum/component/two_handed, force_wielded = force_wield, force_unwielded = force, icon_wielded = "[base_icon_state]1", wield_callback = CALLBACK(src, PROC_REF(wield)), unwield_callback = CALLBACK(src, PROC_REF(unwield))) - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = NON_PROJECTILE_ATTACKS) - -/obj/item/melee/breach_cleaver/examine(mob/user) - . = ..() - if(isAntag(user)) - . += "When wielded, this blade has different effects depending on your intent, similar to a martial art. \ - Help intent will strike with the flat, dealing stamina, disarm intent forces them away, grab intent knocks down the target, \ - and harm intent deals heavy damage." - -/obj/item/melee/breach_cleaver/examine_more(mob/user) - . = ..() - . += "Massive, heavy, and utterly impractical. This sharpened chunk of steel is too big and too heavy to be called a sword." - . += "" - . += "The Unathi Breach Cleaver is a weapon the scaled, warlike race favours for its impressive weight and myriad combat applications. \ - The pinnacle of Moghes' combat technology, it combines all of this knowledge into a massive, heavy slab of alloyed metal that most \ - species find difficult to lift, let alone use in any sort of fight." - . += "" - . += "Actually a little lightweight for its size, a Breach Cleaver is unmatched in combat utility as a weapon, a tool for getting into\ - places and as a slab of armour for the wielder. The leather of the Kar'oche beast, a predator native to Moghes, binds the hilt, \ - allowing it to be gripped securely by its warrior. The wide blade is often etched with scenes depicting military victories or great hunts." - -/obj/item/melee/breach_cleaver/update_icon_state() - icon_state = "[base_icon_state]0" - -/obj/item/melee/breach_cleaver/proc/wield(obj/item/source, mob/living/carbon/human/user) - to_chat(user, "You heave [src] up in both hands.") - user.apply_status_effect(STATUS_EFFECT_BREACH_AND_CLEAVE) - update_icon(UPDATE_ICON_STATE) - -/obj/item/melee/breach_cleaver/proc/unwield(obj/item/source, mob/living/carbon/human/user) - user.remove_status_effect(STATUS_EFFECT_BREACH_AND_CLEAVE) - update_icon(UPDATE_ICON_STATE) - -/obj/item/melee/breach_cleaver/attack_obj__legacy__attackchain(obj/O, mob/living/user, params) - if(!HAS_TRAIT(src, TRAIT_WIELDED)) // Only works good when wielded - return ..() - if(!ismachinery(O) && !isstructure(O)) // This sword hates doors - return ..() - if(SEND_SIGNAL(src, COMSIG_ATTACK_OBJ, O, user) & COMPONENT_NO_ATTACK_OBJ) - return - if(flags & (NOBLUDGEON)) - return - var/mob/living/carbon/human/H = user - H.changeNext_move(CLICK_CD_MELEE) - H.do_attack_animation(O) - H.visible_message("[H] has hit [O] with [src]!", "You hit [O] with [src]!") - var/damage = force_wield - damage += H.physiology.melee_bonus - O.take_damage(damage * 3, BRUTE, MELEE, TRUE, get_dir(src, H), 30) // Multiplied to do big damage to doors, closets, windows, and machines, but normal damage to mobs. - -/obj/item/melee/breach_cleaver/attack__legacy__attackchain(mob/target, mob/living/user) - if(!HAS_TRAIT(src, TRAIT_WIELDED) || !ishuman(target)) - return ..() - - var/mob/living/carbon/human/H = target - var/obj/item/organ/external/targetlimb = H.get_organ(ran_zone(user.zone_selected)) - - switch(user.a_intent) - if(INTENT_HELP) // Stamina damage - H.visible_message("[user] slams [H] with the flat of the blade!", \ - "[user] slams you with the flat of the blade!", \ - "You hear a thud.") - user.do_attack_animation(H, ATTACK_EFFECT_DISARM) - playsound(loc, 'sound/weapons/swordhit.ogg', 50, TRUE, -1) - H.AdjustConfused(4 SECONDS, 0, 4 SECONDS) - H.apply_damage(40, STAMINA, targetlimb, H.run_armor_check(targetlimb, MELEE)) - add_attack_logs(user, H, "Slammed by a breach cleaver. (Help intent, Stamina)", ATKLOG_ALL) - - if(INTENT_DISARM) // Slams away - if(H.stat != CONSCIOUS || IS_HORIZONTAL(H)) - return ..() - - H.visible_message("[user] smashes [H] with the blade's tip!", \ - "[user] smashes you with the blade's tip!", \ - "You hear crushing.") - - user.do_attack_animation(H, ATTACK_EFFECT_KICK) - playsound(get_turf(user), 'sound/weapons/sonic_jackhammer.ogg', 50, TRUE, -1) - H.apply_damage(25, BRUTE, targetlimb, H.run_armor_check(targetlimb, MELEE)) - var/atom/throw_target = get_edge_target_turf(H, user.dir, TRUE) - H.throw_at(throw_target, 4, 1) - add_attack_logs(user, H, "Smashed away by a breach cleaver. (Disarm intent, Knockback)", ATKLOG_ALL) - - if(INTENT_GRAB) // Knocks down - H.visible_message("[user] cleaves [H] with an overhead strike!", \ - "[user] cleaves you with an overhead strike!", \ - "You hear a chopping noise.") - - user.do_attack_animation(H, ATTACK_EFFECT_DISARM) - playsound(get_turf(user), 'sound/weapons/armblade.ogg', 50, TRUE, -1) - H.apply_damage(30, BRUTE, targetlimb, H.run_armor_check(targetlimb, MELEE), TRUE) - H.KnockDown(4 SECONDS) - add_attack_logs(user, H, "Cleaved overhead with a breach cleaver. (Grab intent, Knockdown)", ATKLOG_ALL) - - if(INTENT_HARM) - return ..() - -/obj/item/melee/icepick - name = "ice pick" - desc = "Used for chopping ice. Also excellent for mafia esque murders." - icon_state = "icepick" - item_state = "icepick" - force = 15 - throwforce = 10 - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("stabbed", "jabbed", "iced,") - -/obj/item/melee/candy_sword - name = "candy cane sword" - desc = "A large candy cane with a sharpened point. Definitely too dangerous for schoolchildren." - icon_state = "candy_sword" - item_state = "candy_sword" - force = 10 - throwforce = 7 - w_class = WEIGHT_CLASS_NORMAL - attack_verb = list("slashed", "stabbed", "sliced", "caned") - -/obj/item/melee/flyswatter - name = "flyswatter" - desc = "Useful for killing insects of all sizes." - icon_state = "flyswatter" - item_state = "flyswatter" - force = 1 - throwforce = 1 - attack_verb = list("swatted", "smacked") - hitsound = 'sound/effects/snap.ogg' - w_class = WEIGHT_CLASS_SMALL - //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(mapload) - . = ..() - strong_against = typecacheof(list( - /mob/living/simple_animal/hostile/poison/bees/, - /mob/living/simple_animal/butterfly, - /mob/living/simple_animal/cockroach, - /obj/item/queen_bee)) - strong_against -= /mob/living/simple_animal/hostile/poison/bees/syndi // Syndi-bees have special anti-flyswatter tech installed - -/obj/item/melee/flyswatter/attack__legacy__attackchain(mob/living/M, mob/living/user, def_zone) - . = ..() - if(is_type_in_typecache(M, strong_against)) - new /obj/effect/decal/cleanable/insectguts(M.drop_location()) - user.visible_message("[user] splats [M] with [src].", - "You splat [M] with [src].", - "You hear a splat.") - if(isliving(M)) - var/mob/living/bug = M - bug.death(TRUE) - if(!QDELETED(M)) - qdel(M) - -/obj/item/melee/spellblade - name = "spellblade" - desc = "An enchanted blade with a series of runes along the side." - icon = 'icons/obj/guns/magic.dmi' - icon_state = "spellblade" - item_state = "spellblade" - hitsound = 'sound/weapons/rapierhit.ogg' - w_class = WEIGHT_CLASS_BULKY - force = 25 - armour_penetration_flat = 50 - sharp = TRUE - ///enchantment holder, gives it unique on hit effects. - var/datum/enchantment/enchant = null - ///the cooldown and power of enchantments are multiplied by this var when its applied - var/power = 1 - -/obj/item/melee/spellblade/Initialize(mapload) - . = ..() - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES) - - -/obj/item/melee/spellblade/Destroy() - QDEL_NULL(enchant) - return ..() - -/obj/item/melee/spellblade/afterattack__legacy__attackchain(atom/target, mob/user, proximity, params) - . = ..() - enchant?.on_hit(target, user, proximity, src) - -/obj/item/melee/spellblade/attack_self__legacy__attackchain(mob/user) - if(enchant) - return - - var/static/list/options = list("Lightning" = image(icon = 'icons/effects/spellblade.dmi', icon_state = "chain_lightning"),/// todo add icons for these - "Fire" = image(icon = 'icons/effects/spellblade.dmi', icon_state = "fire"), - "Bluespace" = image(icon = 'icons/effects/spellblade.dmi', icon_state = "blink"), - "Forcewall" = image(icon = 'icons/effects/spellblade.dmi', icon_state = "shield"), - "Temporal Slash" = image(icon = 'icons/effects/spellblade.dmi', icon_state = "spacetime"),) - var/static/list/options_to_type = list("Lightning" = /datum/enchantment/lightning, - "Fire" = /datum/enchantment/fire, - "Bluespace" = /datum/enchantment/bluespace, - "Forcewall" = /datum/enchantment/forcewall, - "Temporal Slash" = /datum/enchantment/time_slash,) - - var/choice = show_radial_menu(user, src, options) - if(!choice) - return - add_enchantment(options_to_type[choice], user) - -/obj/item/melee/spellblade/proc/add_enchantment(new_enchant, mob/living/user, intentional = TRUE) - var/datum/enchantment/E = new new_enchant - enchant = E - E.on_apply_to_blade(src) - E.on_gain(src, user) - E.power *= power - if(intentional) - SSblackbox.record_feedback("nested tally", "spellblade_enchants", 1, list("[E.name]")) - -/obj/item/melee/spellblade/examine(mob/user) - . = ..() - if(enchant && (iswizard(user) || IS_CULTIST(user))) // only wizards and cultists understand runes - . += "The runes along the side read; [enchant.desc]." - - -/obj/item/melee/spellblade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(attack_type == PROJECTILE_ATTACK) - final_block_chance = 0 - return ..() - -/datum/enchantment - /// used for blackbox logging - var/name = "You shouldn't be seeing this, file an issue report." - /// used for wizards/cultists examining the runes on the blade - var/desc = "Someone messed up, file an issue report." - /// used for damage values - var/power = 1 - /// whether the enchant procs despite not being in proximity - var/ranged = FALSE - /// stores the world.time after which it can be used again, the `initial(cooldown)` is the cooldown between activations. - var/cooldown = -1 - /// If the spellblade has traits, has it applied them? - var/applied_traits = FALSE - /// A modifier that can be appled to the cooldown after the enchantment has been initialized. Used by the forcewall spellblade - var/cooldown_multiplier = 1 - -/datum/enchantment/proc/on_hit(mob/living/target, mob/living/user, proximity, obj/item/melee/spellblade/S) - if(world.time < cooldown) - return FALSE - if(!istype(target)) - return FALSE - if(target.stat == DEAD) - return FALSE - if(!ranged && !proximity) - return FALSE - cooldown = world.time + (initial(cooldown) * cooldown_multiplier) - return TRUE - -/datum/enchantment/proc/on_gain(obj/item/melee/spellblade, mob/living/user) - return - -/datum/enchantment/proc/toggle_traits(obj/item/I, mob/living/user) - return - -/datum/enchantment/proc/on_apply_to_blade(obj/item/melee/spellblade) - return - -/datum/enchantment/lightning - name = "lightning" - desc = "this blade conducts arcane energy to arc between its victims. It also makes the user immune to shocks" - // the damage of the first lighting arc. - power = 20 - cooldown = 3 SECONDS - -/datum/enchantment/lightning/on_gain(obj/item/melee/spellblade/S, mob/living/user) - ..() - RegisterSignal(S, list(COMSIG_ITEM_PICKUP, COMSIG_ITEM_DROPPED), PROC_REF(toggle_traits)) - if(user) - toggle_traits(S, user) - - -/datum/enchantment/lightning/on_hit(mob/living/target, mob/living/user, proximity, obj/item/melee/spellblade/S) - . = ..() - if(.) - zap(target, user, list(user), power) - -/datum/enchantment/lightning/toggle_traits(obj/item/I, mob/living/user) - var/enchant_ID = UID(src) // so it only removes the traits applied by this specific enchant. - if(applied_traits) - REMOVE_TRAIT(user, TRAIT_SHOCKIMMUNE, "[enchant_ID]") - else - ADD_TRAIT(user, TRAIT_SHOCKIMMUNE, "[enchant_ID]") - applied_traits = !applied_traits - -/datum/enchantment/lightning/proc/zap(mob/living/target, mob/living/source, protected_mobs, voltage) - source.Beam(target, "lightning[rand(1,12)]", 'icons/effects/effects.dmi', time = 2 SECONDS, maxdistance = 7, beam_type = /obj/effect/ebeam/chain) - if(!target.electrocute_act(voltage, "lightning", flags = SHOCK_TESLA)) // if it fails to shock someone, break the chain - return - protected_mobs += target - addtimer(CALLBACK(src, PROC_REF(arc), target, voltage, protected_mobs), 2.5 SECONDS) - -/datum/enchantment/lightning/proc/arc(mob/living/source, voltage, protected_mobs) - voltage = voltage - 4 - if(voltage <= 0) - return - - for(var/mob/living/L in oview(7, get_turf(source))) - if(L in protected_mobs) - continue - zap(L, source, protected_mobs, voltage) - break - -/datum/enchantment/fire - name = "fire" - desc = "this blade ignites on striking a foe, releasing a ball of fire. It also makes the wielder immune to fire" - cooldown = 8 SECONDS - -/datum/enchantment/fire/on_gain(obj/item/melee/spellblade/S, mob/living/user) - ..() - RegisterSignal(S, list(COMSIG_ITEM_PICKUP, COMSIG_ITEM_DROPPED), PROC_REF(toggle_traits)) - if(user) - toggle_traits(S, user) - -/datum/enchantment/fire/toggle_traits(obj/item/I, mob/living/user) - var/enchant_ID = UID(src) // so it only removes the traits applied by this specific enchant. - if(applied_traits) - REMOVE_TRAIT(user, TRAIT_NOFIRE, "[enchant_ID]") - REMOVE_TRAIT(user, TRAIT_RESISTHEAT, "[enchant_ID]") - applied_traits = FALSE - else - ADD_TRAIT(user, TRAIT_RESISTHEAT, "[enchant_ID]") - ADD_TRAIT(user, TRAIT_NOFIRE, "[enchant_ID]") - applied_traits = TRUE - -/datum/enchantment/fire/on_hit(mob/living/target, mob/living/user, proximity, obj/item/melee/spellblade/S) - . = ..() - if(.) - fireflash_s(target, 4, 8000 * power, 500) - -/datum/enchantment/forcewall - name = "forcewall" - desc = "this blade will partially shield you against attacks and stuns for a short duration after striking a foe" - cooldown = 4 SECONDS - // multiplier for how much the cooldown is reduced by. A miner spellblade can only buff every 4 seconds, making it more vunerable, the wizard one is much more consistant. - power = 2 - -/datum/enchantment/forcewall/on_apply_to_blade(obj/item/melee/spellblade) - cooldown_multiplier /= power - -/datum/enchantment/forcewall/on_hit(mob/living/target, mob/living/user, proximity, obj/item/melee/spellblade/S) - . = ..() - if(!.) - return - user.apply_status_effect(STATUS_EFFECT_FORCESHIELD) - -/datum/enchantment/bluespace - name = "bluespace" - desc = "this blade will cut through the fabric of space, transporting its wielder over medium distances to strike foes" - cooldown = 2.5 SECONDS - ranged = TRUE - // the number of deciseconds of stun applied by the teleport strike - power = 5 - -/datum/enchantment/bluespace/on_hit(mob/living/target, mob/living/user, proximity, obj/item/melee/spellblade/S) - if(proximity) // don't put it on cooldown if adjacent - return - . = ..() - if(!.) - return - var/turf/user_turf = get_turf(user) - if(get_dist(user_turf, get_turf(target)) > 9) //blocks cameras without blocking xray or thermals - return - if(!((target in view(9, user)) || user.sight & SEE_MOBS)) - return - var/list/turfs = list() - for(var/turf/T in orange(1, get_turf(target))) - if(is_blocked_turf(T, TRUE)) - continue - turfs += T - - var/target_turf = pick(turfs) - user_turf.Beam(target_turf, "warp_beam", time = 0.3 SECONDS) - user.forceMove(target_turf) - S.melee_attack_chain(user, target) - target.Weaken(power) - -/datum/enchantment/time_slash - name = "temporal" - desc = "this blade will slice faster but weaker, and will curse the target, slashing them a few seconds after they have not been swinged at for each hit" - power = 15 // This should come out to 40 damage per hit. However, delayed. - -/datum/enchantment/time_slash/on_apply_to_blade(obj/item/melee/spellblade) - spellblade.force /= 2 - -/datum/enchantment/time_slash/on_hit(mob/living/target, mob/living/user, proximity, obj/item/melee/spellblade/S) - user.changeNext_move(CLICK_CD_MELEE * 0.5) - . = ..() - if(!.) - return - target.apply_status_effect(STATUS_EFFECT_TEMPORAL_SLASH, power) - -/obj/effect/temp_visual/temporal_slash - name = "temporal slash" - desc = "A cut through spacetime" - icon = 'icons/obj/projectiles.dmi' - icon_state = "arcane_barrage" - layer = FLY_LAYER - plane = GRAVITY_PULSE_PLANE - appearance_flags = PIXEL_SCALE|LONG_GLIDE - duration = 0.5 SECONDS - mouse_opacity = MOUSE_OPACITY_TRANSPARENT // Let us not have this visual block clicks - /// Who we are orbiting - var/target - /// A funky color matrix to recolor the slash to - var/list/funky_color_matrix = list(0.4,0,0,0, 0,1.1,0,0, 0,0,1.65,0, -0.3,0.15,0,1, 0,0,0,0) - -/obj/effect/temp_visual/temporal_slash/Initialize(mapload, new_target) - . = ..() - target = new_target - INVOKE_ASYNC(src, TYPE_PROC_REF(/atom/movable, orbit), target, 0, FALSE, 0, 0, FALSE, TRUE) - var/matrix/M = matrix() - M.Scale(1, 2) - M.Turn(rand(0, 360)) - transform = M - addtimer(CALLBACK(src, PROC_REF(animate_slash)), 0.25 SECONDS) - -/obj/effect/temp_visual/temporal_slash/proc/animate_slash() - plane = -1 - color = funky_color_matrix - animate(src, alpha = 0, time = duration, easing = EASE_OUT) - -/obj/item/melee/spellblade/random - power = 0.5 - -/obj/item/melee/spellblade/random/Initialize(mapload) - . = ..() - var/list/options = list(/datum/enchantment/lightning, - /datum/enchantment/fire, - /datum/enchantment/forcewall, - /datum/enchantment/bluespace, - /datum/enchantment/time_slash,) - var/datum/enchantment/E = pick(options) - add_enchantment(E, intentional = FALSE) diff --git a/code/game/objects/items/weapons/misc_items.dm b/code/game/objects/items/weapons/misc_items.dm deleted file mode 100644 index 5097771d5491a..0000000000000 --- a/code/game/objects/items/weapons/misc_items.dm +++ /dev/null @@ -1,216 +0,0 @@ -//MISC WEAPONS - -//This file contains /obj/item's that do not fit in any other category and are not big enough to warrant individual files. -/*CURRENT CONTENTS - Ball Toy - Cane - Crutches - Cardboard Tube - Fan - Gaming Kit - Gift - Kidan Globe - Lightning - Newton Cradle - PAI cable - Red Phone - Popsicle Sticks -*/ - -/obj/item/balltoy - name = "ball toy" - icon = 'icons/obj/decorations.dmi' - icon_state = "rollball" - desc = "A device bored paper pushers use to remind themselves that the time did not stop yet." - -/obj/item/cane - name = "cane" - desc = "A cane used by a true gentlemen. Or a clown." - icon_state = "cane" - item_state = "stick" - flags = CONDUCT - force = 5.0 - throwforce = 7.0 - w_class = WEIGHT_CLASS_NORMAL - materials = list(MAT_METAL=50) - attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed", "Vaudevilled") - -/obj/item/cane/get_crutch_efficiency() - return 2 - -/obj/item/crutches - name = "crutches" - desc = "A medical device to help those who have injured or missing legs to walk." - gender = PLURAL - icon = 'icons/obj/surgery.dmi' // I mean like... cmon its basically medical.dmi - icon_state = "crutches0" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - flags = CONDUCT - force = 5 - throwforce = 7 - w_class = WEIGHT_CLASS_BULKY - materials = list(MAT_METAL = 500) - attack_verb = list("bludgeoned", "whacked", "cracked") - /// Is the secret compartment open? - var/is_open = FALSE - /// Tiny item that can be hidden on crutches with a screwdriver - var/obj/item/hidden = null - -/obj/item/crutches/Initialize(mapload) - . = ..() - AddComponent(/datum/component/two_handed, force_unwielded = 5, force_wielded = 5, icon_wielded = "crutches1") - -/obj/item/crutches/Destroy() - if(hidden) - hidden.forceMove(get_turf(src)) - hidden = null - return ..() - -/obj/item/crutches/update_icon_state() //Currently only here to fuck with the on-mob icons. - icon_state = "crutches0" - return ..() - -/obj/item/crutches/attackby__legacy__attackchain(obj/item/I, mob/user, params) - . = ..() - if(!is_open) - return - if(!hidden && I.tool_behaviour != TOOL_SCREWDRIVER && I.w_class == WEIGHT_CLASS_TINY) - if(istype(I, /obj/item/disk/nuclear)) - to_chat(user, "You think you're gonna need more than crutches if your employers find out what you just tried to do...") - return - if(I.flags & ABSTRACT) - return - if(!user.unequip(I)) - to_chat(user, "[I] doesn't seem to want to go into [src]!") - return - I.forceMove(src) - hidden = I - to_chat(user, "You hide [I] inside the crutch tip.") - -/obj/item/crutches/attack_hand(mob/user, pickupfireoverride) - if(!is_open) - return ..() - if(hidden) - user.put_in_hands(hidden) - to_chat(user, "You remove [hidden] from the crutch tip!") - hidden = null - - add_fingerprint(user) - -/obj/item/crutches/screwdriver_act(mob/living/user, obj/item/I) - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - to_chat(user, "You screw the crutch tip [is_open ? "closed" : "open"].") - is_open = !is_open - -/obj/item/crutches/get_crutch_efficiency() - // 6 when wielded, 2 when not. Basically a small upgrade to just having 2 canes in each hand - return 2 + (4 * HAS_TRAIT(src, TRAIT_WIELDED)) // less efficient when you're holding both in a single hand - -/obj/item/c_tube - name = "cardboard tube" - desc = "A tube... of cardboard." - icon = 'icons/obj/stacks/miscellaneous.dmi' - icon_state = "c_tube" - hitsound = 'sound/items/cardboard_tube.ogg' - throwforce = 1 - force = 1 - attack_verb = list("bonked", "thunked") - w_class = WEIGHT_CLASS_TINY - throw_speed = 4 - throw_range = 5 - - - -/obj/item/fan - name = "desk fan" - icon = 'icons/obj/decorations.dmi' - icon_state = "fan" - desc = "A small desktop fan. The button seems to be stuck in the 'on' position." - - -/obj/item/gift - name = "gift" - desc = "A wrapped item." - icon = 'icons/obj/items.dmi' - icon_state = "gift3" - var/size = 3.0 - var/obj/item/gift = null - item_state = "gift" - w_class = WEIGHT_CLASS_BULKY - -/obj/item/gift/emp_act(severity) - ..() - gift.emp_act(severity) - -/obj/item/kidanglobe - name = "Kidan homeworld globe" - icon = 'icons/obj/decorations.dmi' - icon_state = "kidanglobe" - desc = "A globe of the Kidan homeworld." - -/obj/item/lightning - name = "lightning" - icon = 'icons/obj/lightning.dmi' - icon_state = "lightning" - desc = "test lightning." - -/obj/item/lightning/New() - ..() - icon_state = "1" - -/obj/item/lightning/afterattack__legacy__attackchain(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params) - var/angle = get_angle(A, user) - //to_chat(world, angle) - angle = round(angle) + 45 - if(angle > 180) - angle -= 180 - else - angle += 180 - - if(!angle) - angle = 1 - //to_chat(world, "adjusted [angle]") - icon_state = "[angle]" - //to_chat(world, "[angle] [(get_dist(user, A) - 1)]") - user.Beam(A, "lightning", 'icons/obj/zap.dmi', 50, 15) - -/obj/item/newton - name = "newton cradle" - icon = 'icons/obj/decorations.dmi' - icon_state = "newton" - desc = "A device bored paper pushers use to remind themselves that time did not stop yet. Contains gravity." - -/obj/item/pai_cable - name = "data cable" - desc = "A flexible coated cable with a universal jack on one end." - icon = 'icons/obj/power.dmi' - icon_state = "wire1" - var/obj/machinery/machine - -/obj/item/phone - name = "red phone" - desc = "Should anything ever go wrong..." - icon = 'icons/obj/items.dmi' - icon_state = "red_phone" - flags = CONDUCT - force = 3 - throwforce = 2 - throw_speed = 1 - throw_range = 4 - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("called", "rang") - hitsound = 'sound/weapons/ring.ogg' - var/cooldown = 0 - -/obj/item/phone/attack_self__legacy__attackchain(mob/user) - if(cooldown < world.time - 20) - playsound(user.loc, 'sound/weapons/ring.ogg', 50, 1) - cooldown = world.time - -/obj/item/popsicle_stick - name = "popsicle stick" - desc = "A small wooden stick, usually topped by popsicles or other frozen treats." - icon = 'icons/obj/food/frozen_treats.dmi' - icon_state = "popsicle_stick" diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm deleted file mode 100644 index 82fce2da025a2..0000000000000 --- a/code/game/objects/items/weapons/mop.dm +++ /dev/null @@ -1,128 +0,0 @@ -#define MOP_SOUND_CD 2 SECONDS // How many seconds before the mopping sound triggers again - -/obj/item/mop - desc = "The world of janitalia wouldn't be complete without a mop." - name = "mop" - icon = 'icons/obj/janitor.dmi' - icon_state = "mop" - lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' - force = 3 - throwforce = 5 - throw_speed = 3 - throw_range = 7 - w_class = WEIGHT_CLASS_NORMAL - attack_verb = list("mopped", "bashed", "bludgeoned", "whacked") - resistance_flags = FLAMMABLE - var/mopcap = 6 - var/mopspeed = 30 - /// The cooldown between each mopping sound effect - var/mop_sound_cooldown - -/obj/item/mop/New() - ..() - create_reagents(mopcap) - GLOB.janitorial_equipment += src - -/obj/item/mop/Destroy() - GLOB.janitorial_equipment -= src - return ..() - -/obj/item/mop/proc/wet_mop(obj/O, mob/user) - if(O.reagents.total_volume < 1) - to_chat(user, "[O] is empty!") - if(istype(O, /obj/structure/mopbucket)) - var/obj/structure/mopbucket/mopbucket = O - mopbucket.mopbucket_insert(user, O) - if(istype(O, /obj/structure/janitorialcart)) - var/obj/structure/janitorialcart/janicart = O - if(!janicart.mymop) - janicart.mymop = src - janicart.put_in_cart(user, src) - return - - O.reagents.trans_to(src, 6) - to_chat(user, "You wet [src] in [O].") - playsound(loc, 'sound/effects/slosh.ogg', 25, TRUE) - -/obj/item/mop/afterattack__legacy__attackchain(atom/A, mob/user, proximity) - if(!proximity) - return - if(istype(A, /obj/item/reagent_containers/glass/bucket) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/structure/mopbucket)) - return - if(reagents.total_volume < 1) - to_chat(user, "Your mop is dry!") - return - if(world.time > mop_sound_cooldown) - playsound(loc, pick('sound/weapons/mopping1.ogg', 'sound/weapons/mopping2.ogg'), 30, TRUE, -1) - mop_sound_cooldown = world.time + MOP_SOUND_CD - A.cleaning_act(user, src, mopspeed, text_verb = "mop", text_description = ".") - -/obj/item/mop/can_clean() - if(reagents.has_reagent("water", 1) || reagents.has_reagent("cleaner", 1) || reagents.has_reagent("holywater", 1)) - return TRUE - else - return FALSE - -/obj/item/mop/post_clean(atom/target, mob/user) - var/turf/T = get_turf(target) - if(issimulatedturf(T)) - reagents.reaction(T, REAGENT_TOUCH, 10) //10 is the multiplier for the reaction effect. probably needed to wet the floor properly. - reagents.remove_any(1) //reaction() doesn't use up the reagents - -/obj/effect/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/mop) || istype(I, /obj/item/soap)) - return - else - return ..() - -/obj/item/mop/wash(mob/user, atom/source) - reagents.add_reagent("water", 5) - to_chat(user, "You wet [src] in [source].") - playsound(loc, 'sound/effects/slosh.ogg', 25, 1) - return 1 - -/obj/item/mop/advanced - desc = "The most advanced tool in a custodian's arsenal. Just think of all the viscera you will clean up with this!" - name = "advanced mop" - mopcap = 10 - icon_state = "advmop" - origin_tech = "materials=3;engineering=3" - force = 6 - throwforce = 8 - throw_range = 4 - mopspeed = 20 - var/refill_enabled = TRUE //Self-refill toggle for when a janitor decides to mop with something other than water. - var/refill_rate = 1 //Rate per process() tick mop refills itself - var/refill_reagent = "water" //Determins what reagent to use for refilling, just in case someone wanted to make a HOLY MOP OF PURGING - -/obj/item/mop/advanced/New() - ..() - START_PROCESSING(SSobj, src) - -/obj/item/mop/advanced/attack_self__legacy__attackchain(mob/user) - refill_enabled = !refill_enabled - if(refill_enabled) - START_PROCESSING(SSobj, src) - else - STOP_PROCESSING(SSobj, src) - to_chat(user, "You set the condenser switch to the '[refill_enabled ? "ON" : "OFF"]' position.") - playsound(user, 'sound/machines/click.ogg', 30, 1) - -/obj/item/mop/advanced/process() - - if(reagents.total_volume < mopcap) - reagents.add_reagent(refill_reagent, refill_rate) - -/obj/item/mop/advanced/examine(mob/user) - . = ..() - . += "The condenser switch is set to [refill_enabled ? "ON" : "OFF"]." - -/obj/item/mop/advanced/Destroy() - if(refill_enabled) - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/mop/advanced/cyborg - -#undef MOP_SOUND_CD diff --git a/code/game/objects/items/weapons/paint_bucket.dm b/code/game/objects/items/weapons/paint_bucket.dm deleted file mode 100644 index 4dc67b6b783bc..0000000000000 --- a/code/game/objects/items/weapons/paint_bucket.dm +++ /dev/null @@ -1,69 +0,0 @@ -//NEVER USE THIS IT SUX -PETETHEGOAT - -/obj/item/reagent_containers/glass/paint - desc = "It's a paint bucket." - name = "paint bucket" - icon = 'icons/obj/paint.dmi' - icon_state = "paint_neutral" - item_state = "paintcan" - materials = list(MAT_METAL = 400) - w_class = WEIGHT_CLASS_NORMAL - resistance_flags = FLAMMABLE - max_integrity = 100 - amount_per_transfer_from_this = 5 - possible_transfer_amounts = list(5,10,20,30,50,70) - volume = 70 - container_type = OPENCONTAINER - blocks_emissive = EMISSIVE_BLOCK_GENERIC - -/obj/item/reagent_containers/glass/paint/afterattack__legacy__attackchain(turf/simulated/target, mob/user, proximity) - if(!proximity) - return - if(!is_open_container()) - return - if(istype(target) && reagents.total_volume >= 5) - user.visible_message("[target] has been splashed with something by [user]!") - spawn(5) - reagents.reaction(target, REAGENT_TOUCH) - reagents.remove_any(5) - else - return ..() - -/obj/item/reagent_containers/glass/paint/red - name = "red paint bucket" - icon_state = "paint_red" - list_reagents = list("paint_red" = 70) - -/obj/item/reagent_containers/glass/paint/green - name = "green paint bucket" - icon_state = "paint_green" - list_reagents = list("paint_green" = 70) - -/obj/item/reagent_containers/glass/paint/blue - name = "blue paint bucket" - icon_state = "paint_blue" - list_reagents = list("paint_blue" = 70) - -/obj/item/reagent_containers/glass/paint/yellow - name = "yellow paint bucket" - icon_state = "paint_yellow" - list_reagents = list("paint_yellow" = 70) - -/obj/item/reagent_containers/glass/paint/violet - name = "violet paint bucket" - icon_state = "paint_violet" - list_reagents = list("paint_violet" = 70) - -/obj/item/reagent_containers/glass/paint/black - name = "black paint bucket" - icon_state = "paint_black" - list_reagents = list("paint_black" = 70) - -/obj/item/reagent_containers/glass/paint/white - name = "white paint bucket" - icon_state = "paint_white" - list_reagents = list("paint_white" = 70) - -/obj/item/reagent_containers/glass/paint/remover - name = "paint remover bucket" - list_reagents = list("paint_remover" = 70) diff --git a/code/game/objects/items/weapons/paiwire.dm b/code/game/objects/items/weapons/paiwire.dm deleted file mode 100644 index 05f2ea5dc9f45..0000000000000 --- a/code/game/objects/items/weapons/paiwire.dm +++ /dev/null @@ -1,11 +0,0 @@ -/obj/item/pai_cable/proc/plugin(obj/machinery/M as obj, mob/user as mob) - if(isairlock(M) || istype(M, /obj/machinery/camera)) - user.visible_message("[user] inserts [src] into a data port on [M].", "You insert [src] into a data port on [M].", "You hear the satisfying click of a wire jack fastening into place.") - user.drop_item() - src.loc = M - src.machine = M - else - user.visible_message("[user] dumbly fumbles to find a place on [M] to plug in [src].", "There aren't any ports on [M] that match the jack belonging to [src].") - -/obj/item/pai_cable/attack__legacy__attackchain(obj/machinery/M as obj, mob/user as mob) - src.plugin(M, user) diff --git a/code/game/objects/items/weapons/picket_signs.dm b/code/game/objects/items/weapons/picket_signs.dm deleted file mode 100644 index 53dcfb45e4f28..0000000000000 --- a/code/game/objects/items/weapons/picket_signs.dm +++ /dev/null @@ -1,46 +0,0 @@ -/obj/item/picket_sign - name = "blank picket sign" - desc = "It's blank." - icon_state = "picket" - item_state = "picket" - force = 5 - w_class = WEIGHT_CLASS_BULKY - attack_verb = list("bashed","smacked") - resistance_flags = FLAMMABLE - - var/delayed = 0 //used to do delays - - var/label = "" - -/obj/item/picket_sign/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(is_pen(W) || istype(W, /obj/item/toy/crayon)) - var/txt = tgui_input_text(user, "What would you like to write on the sign?", "Sign Label", max_length = 30) - if(isnull(txt)) - return - label = txt - src.name = "[label] sign" - desc = "It reads: [label]" - ..() - -/obj/item/picket_sign/attack_self__legacy__attackchain(mob/living/carbon/human/user) - if(delayed) - user.show_message("Your arm is too tired to do that again so soon!") - return - - delayed = 1 - if(label) - user.visible_message("[user] waves around \the \"[label]\" sign.") - else - user.visible_message("[user] waves around blank sign.") - user.changeNext_move(CLICK_CD_MELEE) - - sleep(8) - delayed = 0 - -/datum/crafting_recipe/picket_sign - name = "Picket Sign" - result = list(/obj/item/picket_sign) - reqs = list(/obj/item/stack/rods = 1, - /obj/item/stack/sheet/cardboard = 2) - time = 80 - category = CAT_MISC diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm deleted file mode 100644 index f7fb3351623d2..0000000000000 --- a/code/game/objects/items/weapons/pneumaticCannon.dm +++ /dev/null @@ -1,182 +0,0 @@ -/obj/item/pneumatic_cannon - name = "pneumatic cannon" - desc = "A gas-powered cannon that can fire any object loaded into it." - w_class = WEIGHT_CLASS_BULKY - force = 8 //Very heavy - attack_verb = list("bludgeoned", "smashed", "beaten") - icon = 'icons/obj/pneumaticCannon.dmi' - icon_state = "pneumaticCannon" - item_state = "bulldog" - lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' - righthand_file = 'icons/mob/inhands/guns_righthand.dmi' - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 60, ACID = 50) - ///The max weight of items that can fit into the cannon - var/max_weight_class = 20 - ///The weight of items currently in the cannon - var/loaded_weight_class = 0 - ///The gas tank that is drawn from to fire things - var/obj/item/tank/internals/tank = null - ///If the cannon needs a tank at all - var/requires_tank = TRUE - ///How many moles of gas is drawn from a tank's pressure to fire - var/gas_per_throw = 3 - ///The items loaded into the cannon that will be fired out - var/list/loaded_items = list() - ///How powerful the cannon is - higher pressure = more gas but more powerful throws - var/pressure_setting = 1 - ///In case we want a really strong cannon - var/max_pressure_setting = 3 - -/obj/item/pneumatic_cannon/Destroy() - QDEL_NULL(tank) - QDEL_LIST_CONTENTS(loaded_items) - return ..() - -/obj/item/pneumatic_cannon/examine(mob/user) - . = ..() - if(!in_range(user, src)) - . += "You'll need to get closer to see any more." - else - if(tank) - . += "[bicon(tank)] It has [tank] mounted onto it." - for(var/obj/item/I in loaded_items) - . += "[bicon(I)] It has [I] loaded." - -/** -* Arguments: -* * I - item to load into the cannon -* * user - the person loading the item in -* * Returns: -* * True if item was loaded, false if it failed -*/ -/obj/item/pneumatic_cannon/proc/load_item(obj/item/I, mob/user) - if((loaded_weight_class + I.w_class) > max_weight_class) - to_chat(user, "[I] won't fit into [src]!") - return FALSE - if(I.w_class > w_class) - to_chat(user, "[I] is too large to fit into [src]!") - return FALSE - if(!user.unequip(I) || I.flags & (ABSTRACT | NODROP | DROPDEL)) - to_chat(user, "You can't put [I] into [src]!") - return FALSE - loaded_items.Add(I) - loaded_weight_class += I.w_class - I.forceMove(src) - return TRUE - -/obj/item/pneumatic_cannon/wrench_act(mob/living/user, obj/item/I) - adjust_setting(user) - return TRUE - -/obj/item/pneumatic_cannon/proc/adjust_setting(mob/living/user) - if(pressure_setting == max_pressure_setting) - pressure_setting = 1 - else - pressure_setting++ - to_chat(user, "You tweak [src]'s pressure output to [pressure_setting].") - -/obj/item/pneumatic_cannon/attackby__legacy__attackchain(obj/item/W, mob/user, params) - ..() - if(istype(W, /obj/item/tank/internals) && !tank) - if(istype(W, /obj/item/tank/internals/emergency_oxygen)) - to_chat(user, "[W] is too small for [src].") - return - add_tank(W, user) - return - if(W.type == type) - to_chat(user, "You're fairly certain that putting a pneumatic cannon inside another pneumatic cannon would cause a spacetime disruption.") - return - load_item(W, user) - -/obj/item/pneumatic_cannon/screwdriver_act(mob/living/user, obj/item/I) - remove_tank(user) - return TRUE - -/obj/item/pneumatic_cannon/afterattack__legacy__attackchain(atom/target, mob/living/carbon/human/user, flag, params) - if(isstorage(target)) //So you can store it in backpacks - return ..() - if(istype(target, /obj/structure/rack)) //So you can store it on racks - return ..() - if(!istype(user)) - return ..() - fire(user, target) - - -/obj/item/pneumatic_cannon/proc/fire(mob/living/carbon/human/user, atom/target) - if(!istype(user) && !target) - return - var/has_discharged = FALSE - if(!loaded_items || !loaded_weight_class) - to_chat(user, "[src] has nothing loaded.") - return - if(requires_tank) - if(!tank) - to_chat(user, "[src] can't fire without a source of gas.") - return - if(!tank.air_contents.boolean_remove(gas_per_throw * pressure_setting)) - to_chat(user, "[src] lets out a weak hiss and doesn't react!") - return - if(user && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(75)) - user.visible_message("[user] loses [user.p_their()] grip on [src], causing it to go off!", "[src] slips out of your hands and goes off!") - user.drop_item() - has_discharged = TRUE - if(prob(10)) - target = user - else - var/list/possible_targets = range(3,src) - target = pick(possible_targets) - if(!has_discharged) - user.visible_message("[user] fires [src]!", \ - "You fire [src]!") - add_attack_logs(user, target, "Fired [src]") - playsound(loc, 'sound/weapons/sonic_jackhammer.ogg', 50, TRUE) - for(var/obj/item/loaded_item in loaded_items) - loaded_items.Remove(loaded_item) - loaded_weight_class -= loaded_item.w_class - loaded_item.throw_speed = pressure_setting * 2 - loaded_item.forceMove(get_turf(src)) - loaded_item.throw_at(target, pressure_setting * 5, pressure_setting * 2, user) - if(pressure_setting >= 3 && user) - user.visible_message("[user] is thrown down by the force of the cannon!", "[src] slams into your shoulder, knocking you down!") - user.KnockDown(3 SECONDS) - -/obj/item/pneumatic_cannon/proc/add_tank(obj/item/tank/new_tank, mob/living/carbon/human/user) - if(tank) - to_chat(user, "[src] already has a tank.") - return - if(!user.unequip(new_tank)) - return - to_chat(user, "You hook [new_tank] up to [src].") - new_tank.forceMove(src) - tank = new_tank - update_icons() - -/obj/item/pneumatic_cannon/proc/remove_tank(mob/living/carbon/human/user) - if(!tank) - return FALSE - to_chat(user, "You detach [tank] from [src].") - user.put_in_hands(tank) - tank = null - update_icons() - -/obj/item/pneumatic_cannon/proc/update_icons() - src.overlays.Cut() - if(!tank) - return - src.overlays += image('icons/obj/pneumaticCannon.dmi', "[tank.icon_state]") - src.update_icon() - -/obj/item/pneumatic_cannon/admin - name = "admin pnuematic cannon" - desc = "Infinite gas and infinite capacity, go crazy." - requires_tank = FALSE - max_weight_class = INFINITY - -/// Obtainable by improvised methods; more gas per use, less capacity, but smaller -/obj/item/pneumatic_cannon/ghetto - name = "improvised pneumatic cannon" - desc = "A gas-powered, object-firing cannon made out of common parts." - force = 5 - w_class = WEIGHT_CLASS_NORMAL - max_weight_class = 7 - gas_per_throw = 5 diff --git a/code/game/objects/items/weapons/powerfist.dm b/code/game/objects/items/weapons/powerfist.dm deleted file mode 100644 index 14367dd26ef77..0000000000000 --- a/code/game/objects/items/weapons/powerfist.dm +++ /dev/null @@ -1,138 +0,0 @@ -/obj/item/melee/powerfist - name = "power-fist" - desc = "A metal gauntlet with a piston-powered ram ontop for that extra 'ompfh' in your punch." - icon_state = "powerfist" - item_state = "powerfist" - flags = CONDUCT - attack_verb = list("whacked", "fisted", "power-punched") - force = 12 - throwforce = 10 - throw_range = 7 - w_class = WEIGHT_CLASS_NORMAL - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 40) - resistance_flags = FIRE_PROOF - origin_tech = "combat=5;powerstorage=3;syndicate=3" - var/click_delay = 1.5 - var/fisto_setting = 1 - /// Base pressure in kpa used by the powerfist per hit - var/gasperfist = 17.5 - - var/obj/item/tank/internals/tank = null //Tank used for the gauntlet's piston-ram. - -/obj/item/melee/powerfist/Destroy() - QDEL_NULL(tank) - return ..() - -/obj/item/melee/powerfist/examine(mob/user) - . = ..() - if(!in_range(user, src)) - . += "You'll need to get closer to see any more." - else if(tank) - . += "[bicon(tank)] It has [tank] mounted onto it." - -/obj/item/melee/powerfist/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(istype(W, /obj/item/tank/internals)) - if(!user.is_holding(src)) - to_chat(user, "You have to hold [src] in your hand!") - return - if(!tank) - var/obj/item/tank/internals/IT = W - if(IT.volume <= 3) - to_chat(user, "[IT] is too small for [src].") - return - updateTank(W, 0, user) - return - return ..() - -/obj/item/melee/powerfist/wrench_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - switch(fisto_setting) - if(1) - fisto_setting = 2 - if(2) - fisto_setting = 3 - if(3) - fisto_setting = 1 - to_chat(user, "You tweak [src]'s piston valve to [fisto_setting].") - -/obj/item/melee/powerfist/screwdriver_act(mob/user, obj/item/I) - if(!tank) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - updateTank(tank, 1, user) - -/obj/item/melee/powerfist/proc/updateTank(obj/item/tank/thetank, removing = 0, mob/living/carbon/human/user) - if(removing) - if(!tank) - to_chat(user, "[src] currently has no tank attached to it.") - return - to_chat(user, "As you detach [thetank] from [src], the fist unlocks.") - flags &= ~NODROP - tank.forceMove(get_turf(user)) - user.put_in_hands(tank) - tank = null - if(!removing) - if(tank) - to_chat(user, "[src] already has a tank.") - return - if(!user.unequip(thetank)) - return - to_chat(user, "As you hook [thetank] up to [src], the fist locks into place around your arm.") - tank = thetank - thetank.forceMove(src) - flags |= NODROP - - -/obj/item/melee/powerfist/attack__legacy__attackchain(mob/living/target, mob/living/user) - if(HAS_TRAIT(user, TRAIT_PACIFISM)) - to_chat(user, "You don't want to harm other living beings!") - return - if(!tank) - to_chat(user, "[src] can't operate without a source of gas!") - return - if(!use_air()) - to_chat(user, "[src]'s piston-ram lets out a weak hiss, it needs more gas!") - playsound(loc, 'sound/effects/refill.ogg', 50, 1) - return - - user.do_attack_animation(target) - - var/obj/item/organ/external/affecting = target.get_organ(ran_zone(user.zone_selected)) - if(!affecting) - affecting = target.get_organ("chest") - - var/armor_block = target.run_armor_check(affecting, MELEE) - target.apply_damage(force * fisto_setting, BRUTE, affecting, armor_block) - - target.visible_message("[user]'s powerfist lets out a loud hiss as [user.p_they()] punch[user.p_es()] [target.name]!", \ - "You cry out in pain as [user]'s punch flings you backwards!") - new /obj/effect/temp_visual/kinetic_blast(target.loc) - playsound(loc, 'sound/weapons/resonator_blast.ogg', 50, 1) - playsound(loc, 'sound/weapons/genhit2.ogg', 50, 1) - - var/atom/throw_target = get_edge_target_turf(target, get_dir(src, get_step_away(target, src))) - - target.throw_at(throw_target, 5 * fisto_setting, 3 * fisto_setting) - - add_attack_logs(user, target, "POWER FISTED with [src]") - - user.changeNext_move(CLICK_CD_MELEE * click_delay) - -/obj/item/melee/powerfist/proc/use_air() - if(!tank) - return FALSE - - var/amount_to_remove = gasperfist * fisto_setting - var/pressure_in_tank = tank.air_contents.return_pressure() - - // So this check is here to see if the amount of pressure currently in the tank is higher than 10 atmospheres - // If it is higher, we instead take 10% out of the tank so it'll deplete a lot faster, but is still a bit more ammo - if(pressure_in_tank > (ONE_ATMOSPHERE * 10)) - amount_to_remove = 0.1 * pressure_in_tank - - var/moles_to_remove = (amount_to_remove * tank.air_contents.volume) / (R_IDEAL_GAS_EQUATION * tank.air_contents.temperature()) - return tank.air_contents.boolean_remove(moles_to_remove) diff --git a/code/game/objects/items/weapons/rpd.dm b/code/game/objects/items/weapons/rpd.dm deleted file mode 100644 index a7795aff20a3e..0000000000000 --- a/code/game/objects/items/weapons/rpd.dm +++ /dev/null @@ -1,373 +0,0 @@ -/*Contains: - Rapid Pipe Dispenser -*/ - -#define RPD_COOLDOWN_TIME 4 //How long should we have to wait between dispensing pipes? -#define RPD_WALLBUILD_TIME 40 //How long should drilling into a wall take? -#define RPD_MENU_ROTATE "Rotate pipes" //Stuff for radial menu -#define RPD_MENU_FLIP "Flip pipes" //Stuff for radial menu -#define RPD_MENU_DELETE "Delete pipes" //Stuff for radial menu - -/obj/item/rpd - name = "rapid pipe dispenser" - desc = "This device can rapidly dispense atmospherics and disposals piping, manipulate loose piping, and recycle any detached pipes it is applied to." - icon = 'icons/obj/tools.dmi' - icon_state = "rpd" - opacity = FALSE - density = FALSE - anchored = FALSE - flags = CONDUCT - force = 10 - throwforce = 10 - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_NORMAL - materials = list(MAT_METAL = 75000, MAT_GLASS = 37500) - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 50) - resistance_flags = FIRE_PROOF - origin_tech = "engineering=4;materials=2" - var/datum/effect_system/spark_spread/spark_system - var/lastused - var/iconrotation = 0 //Used to orient icons and pipes - var/mode = RPD_ATMOS_MODE //Disposals, atmospherics, etc. - var/pipe_category = RPD_ATMOS_PIPING //For TGUI menus, this is a subtype of pipes e.g. scrubbers pipes, devices - var/whatpipe = PIPE_SIMPLE_STRAIGHT //What kind of atmos pipe is it? - var/whatdpipe = PIPE_DISPOSALS_STRAIGHT //What kind of disposals pipe is it? - var/whatttube = PIPE_TRANSIT_TUBE - var/spawndelay = RPD_COOLDOWN_TIME - var/walldelay = RPD_WALLBUILD_TIME - var/ranged = FALSE - var/primary_sound = 'sound/machines/click.ogg' - var/alt_sound = null - var/auto_wrench_toggle = TRUE - - //Lists of things - var/list/mainmenu = list( - list("category" = "Atmospherics", "mode" = RPD_ATMOS_MODE, "icon" = "wrench"), - list("category" = "Disposals", "mode" = RPD_DISPOSALS_MODE, "icon" = "recycle"), - list("category" = "Transit", "mode" = RPD_TRANSIT_MODE, "icon" = "subway"), - list("category" = "Rotate", "mode" = RPD_ROTATE_MODE, "icon" = "sync-alt"), - list("category" = "Flip", "mode" = RPD_FLIP_MODE, "icon" = "arrows-alt-h"), - list("category" = "Recycle", "mode" = RPD_DELETE_MODE, "icon" = "trash")) - var/list/pipemenu = list( - list("category" = "Normal", "pipemode" = RPD_ATMOS_PIPING), - list("category" = "Supply", "pipemode" = RPD_SUPPLY_PIPING), - list("category" = "Scrubber", "pipemode" = RPD_SCRUBBERS_PIPING), - list("category" = "Devices", "pipemode" = RPD_DEVICES), - list("category" = "Heat exchange", "pipemode" = RPD_HEAT_PIPING)) - - -/obj/item/rpd/Initialize(mapload) - . = ..() - spark_system = new /datum/effect_system/spark_spread() - spark_system.set_up(1, 0, src) - spark_system.attach(src) - -/obj/item/rpd/Destroy() - QDEL_NULL(spark_system) - return ..() - -/obj/item/rpd/bluespace - name = "bluespace rapid pipe dispenser" - desc = "This device can rapidly dispense atmospherics and disposals piping, manipulate loose piping, and recycle any detached pipes it is applied to, at any range." - icon_state = "brpd" - materials = list(MAT_METAL = 75000, MAT_GLASS = 37500, MAT_SILVER = 3000) - origin_tech = "engineering=4;materials=2;bluespace=3" - ranged = TRUE - primary_sound = 'sound/items/PSHOOM.ogg' - alt_sound = 'sound/items/PSHOOM_2.ogg' - -//Procs - -/obj/item/rpd/proc/activate_rpd(delay) //Maybe makes sparks and activates cooldown if there is a delay - if(alt_sound && prob(3)) - playsound(src, alt_sound, 50, 1) - else - playsound(src, primary_sound, 50, 1) - if(prob(15) && !ranged) - spark_system.start() - if(delay) - lastused = world.time - -/obj/item/rpd/proc/can_dispense_pipe(pipe_id, pipe_type) //Returns TRUE if this is a legit pipe we can dispense, otherwise returns FALSE - for(var/list/L in GLOB.rpd_pipe_list) - if(pipe_type != L["pipe_type"]) //Sometimes pipes in different categories have the same pipe_id, so we need to skip anything not in the category we want - continue - if(pipe_id == L["pipe_id"]) //Found the pipe, we can dispense it - return TRUE - -/obj/item/rpd/proc/create_atmos_pipe(mob/user, turf/T) //Make an atmos pipe, meter, or gas sensor - if(!can_dispense_pipe(whatpipe, RPD_ATMOS_MODE)) - CRASH("Failed to spawn [get_pipe_name(whatpipe, PIPETYPE_ATMOS)] - possible tampering detected") //Damn dirty apes -- I mean hackers - var/obj/item/pipe/P - if(whatpipe == PIPE_GAS_SENSOR) - P = new /obj/item/pipe_gsensor(T) - else if(whatpipe == PIPE_METER) - P = new /obj/item/pipe_meter(T) - else - P = new(T, whatpipe, iconrotation) //Make the pipe, BUT WAIT! There's more! - if(!iconrotation && P.is_bent_pipe()) //Automatically rotates dispensed pipes if the user selected auto-rotation - P.dir = turn(user.dir, 135) - else if(!iconrotation && (P.pipe_type in list(PIPE_CONNECTOR, PIPE_UVENT, PIPE_SCRUBBER, PIPE_HEAT_EXCHANGE, PIPE_CAP, PIPE_SUPPLY_CAP, PIPE_SCRUBBERS_CAP, PIPE_INJECTOR, PIPE_PASV_VENT))) //Some pipes dispense oppositely to what you'd expect, but we don't want to do anything if they selected a direction - P.dir = turn(user.dir, -180) - else if(iconrotation && P.is_bent_pipe()) //If user selected a rotation and the pipe is bent - P.dir = turn(iconrotation, -45) - else if(!iconrotation) //If user selected a rotation - P.dir = user.dir - to_chat(user, "[src] rapidly dispenses [P]!") - automatic_wrench_down(user, P) - activate_rpd(TRUE) - -/obj/item/rpd/proc/create_disposals_pipe(mob/user, turf/T) //Make a disposals pipe / construct - if(!can_dispense_pipe(whatdpipe, RPD_DISPOSALS_MODE)) - CRASH("Failed to spawn [get_pipe_name(whatdpipe, PIPETYPE_DISPOSAL)] - possible tampering detected") - var/obj/structure/disposalconstruct/P = new(T, whatdpipe, iconrotation) - if(!iconrotation) //Automatic rotation - P.dir = user.dir - if(!iconrotation && whatdpipe != PIPE_DISPOSALS_JUNCTION_RIGHT) //Disposals pipes are in the opposite direction to atmos pipes, so we need to flip them. Junctions don't have this quirk though - P.flip() - to_chat(user, "[src] rapidly dispenses [P]!") - automatic_wrench_down(user, P) - activate_rpd(TRUE) - -/obj/item/rpd/proc/create_transit_tube(mob/user, turf/dest) - if(!can_dispense_pipe(whatttube, PIPETYPE_TRANSIT)) - CRASH("Failed to spawn [get_pipe_name(whatttube, PIPETYPE_TRANSIT)] - possible tampering detected") - - for(var/datum/pipes/transit/T in GLOB.construction_pipe_list) - if(T.pipe_id == whatttube) - var/obj/structure/transit_tube_construction/S = new T.construction_type(dest) - if(!istype(S)) - CRASH("found [S] when constructing transit tube but expected /obj/structure/transit_tube_construction") - - S.dir = iconrotation ? iconrotation : user.dir - - to_chat(user, "[src] rapidly dispenses [S]!") - automatic_wrench_down(user, S) - activate_rpd(TRUE) - -/obj/item/rpd/proc/rotate_all_pipes(mob/user, turf/T) //Rotate all pipes on a turf - for(var/obj/item/pipe/P in T) - P.rotate() - for(var/obj/structure/disposalconstruct/D in T) - D.rotate() - for(var/obj/structure/transit_tube_construction/tube in T) - tube.rotate() - -/obj/item/rpd/proc/flip_all_pipes(mob/user, turf/T) //Flip all pipes on a turf - for(var/obj/item/pipe/P in T) - P.flip() - for(var/obj/structure/disposalconstruct/D in T) - D.flip() - for(var/obj/structure/transit_tube_construction/tube in T) - tube.flip() - -/obj/item/rpd/proc/delete_all_pipes(mob/user, turf/T) //Delete all pipes on a turf - var/eaten - for(var/obj/item/pipe/P in T) - if(P.pipe_type == PIPE_CIRCULATOR) //Skip TEG heat circulators, they aren't really pipes - continue - QDEL_NULL(P) - eaten = TRUE - for(var/obj/item/pipe_gsensor/G in T) - QDEL_NULL(G) - eaten = TRUE - for(var/obj/item/pipe_meter/M in T) - QDEL_NULL(M) - eaten = TRUE - for(var/obj/structure/disposalconstruct/D in T) - if(!D.anchored) - QDEL_NULL(D) - eaten = TRUE - for(var/obj/structure/transit_tube_construction/C in T) - QDEL_NULL(C) - eaten = TRUE - if(eaten) - to_chat(user, "[src] sucks up the loose pipes on [T].") - activate_rpd() - else - to_chat(user, "There were no loose pipes on [T].") - -/obj/item/rpd/proc/delete_single_pipe(mob/user, obj/P) //Delete a single pipe - to_chat(user, "[src] sucks up [P].") - QDEL_NULL(P) - activate_rpd() - -/** - * Automatically wrenches down an atmos device/pipe if the auto_wrench_toggle is TRUE. - * Arguments: - * * user - the user of the RPD. - * * target - the pipe/device/tube being placed by the RPD. - */ -/obj/item/rpd/proc/automatic_wrench_down(mob/living/user, obj/item/target) - if(!auto_wrench_toggle) - return - if(mode == RPD_TRANSIT_MODE) - if(target.screwdriver_act(user, src) & RPD_TOOL_SUCCESS) - playsound(src, 'sound/items/impactwrench.ogg', 50, TRUE) - return - if(target.wrench_act(user, src) & RPD_TOOL_SUCCESS) - playsound(src, 'sound/items/impactwrench.ogg', 50, TRUE) - return -// TGUI stuff - -/obj/item/rpd/attack_self__legacy__attackchain(mob/user) - ui_interact(user) - -/obj/item/rpd/ui_state(mob/user) - return GLOB.inventory_state - -/obj/item/rpd/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "RPD", name) - ui.open() - -/obj/item/rpd/ui_assets(mob/user) - return list( - get_asset_datum(/datum/asset/spritesheet/rpd) - ) - -/obj/item/rpd/AltClick(mob/user) - radial_menu(user) - -/obj/item/rpd/ui_data(mob/user) - var/list/data = list() - data["iconrotation"] = iconrotation - data["mainmenu"] = mainmenu - data["mode"] = mode - data["pipelist"] = GLOB.rpd_pipe_list - data["pipemenu"] = pipemenu - data["pipe_category"] = pipe_category - data["whatdpipe"] = whatdpipe - data["whatpipe"] = whatpipe - data["whatttube"] = whatttube - data["auto_wrench_toggle"] = auto_wrench_toggle - return data - -/obj/item/rpd/ui_act(action, list/params) - if(..()) - return - - . = TRUE - - switch(action) - if("iconrotation") - iconrotation = isnum(params[action]) ? params[action] : text2num(params[action]) - if("whatpipe") - whatpipe = isnum(params[action]) ? params[action] : text2num(params[action]) - if("whatdpipe") - whatdpipe = isnum(params[action]) ? params[action] : text2num(params[action]) - if("whatttube") - whatttube = isnum(params[action]) ? params[action] : text2num(params[action]) - if("pipe_category") - pipe_category = isnum(params[action]) ? params[action] : text2num(params[action]) - if("mode") - mode = isnum(params[action]) ? params[action] : text2num(params[action]) - if("auto_wrench_toggle") - auto_wrench_toggle = !auto_wrench_toggle - -//RPD radial menu -/obj/item/rpd/proc/check_menu(mob/living/user) - if(!istype(user)) - return - if(user.incapacitated()) - return - if(loc != user) - return - return TRUE - -/obj/item/rpd/proc/radial_menu(mob/user) - if(!check_menu(user)) - to_chat(user, "You can't do that right now!") - return - var/list/choices = list( - RPD_MENU_ROTATE = image(icon = 'icons/obj/interface.dmi', icon_state = "rpd_rotate"), - RPD_MENU_FLIP = image(icon = 'icons/obj/interface.dmi', icon_state = "rpd_flip"), - RPD_MENU_DELETE = image(icon = 'icons/obj/interface.dmi', icon_state = "rpd_delete"), - "UI" = image(icon = 'icons/obj/interface.dmi', icon_state = "ui_interact") - ) - var/selected_mode = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, PROC_REF(check_menu), user)) - if(!check_menu(user)) - return - if(selected_mode == "UI") - ui_interact(user) - else - switch(selected_mode) - if(RPD_MENU_ROTATE) - mode = RPD_ROTATE_MODE - if(RPD_MENU_FLIP) - mode = RPD_FLIP_MODE - if(RPD_MENU_DELETE) - mode = RPD_DELETE_MODE - else - return //Either nothing was selected, or an invalid mode was selected - to_chat(user, "You set [src]'s mode.") - -/obj/item/rpd/afterattack__legacy__attackchain(atom/target, mob/user, proximity) - ..() - if(isstorage(target)) - var/obj/item/storage/S = target - if(!S.can_be_inserted(src, stop_messages = TRUE)) - return - if(loc != user) - return - if(!proximity && !ranged) - return - if(world.time < lastused + spawndelay) - return - - var/turf/T = get_turf(target) - - if(!T) - return - - if(target != T) - // We only check the rpd_act of the target if it isn't the turf, because otherwise - // (A) blocked turfs can be acted on, and (B) unblocked turfs get acted on twice. - if(target.rpd_act(user, src)) - // If the object we are clicking on has a valid RPD interaction for just that specific object, do that and nothing else. - // Example: clicking on a pipe with a RPD in rotate mode should rotate that pipe and ignore everything else on the tile. - if(ranged) - user.Beam(T, icon_state="rped_upgrade", icon='icons/effects/effects.dmi', time=5) - return - - // If we get this far, we have to check every object in the tile, to make sure that none of them block RPD usage on this tile. - // This is done by calling rpd_blocksusage on every /obj in the tile. If any block usage, fail at this point. - - for(var/obj/O in T) - if(O.rpd_blocksusage()) - to_chat(user, "[O] blocks [src]!") - return - - // If we get here, then we're effectively acting on the turf, probably placing a pipe. - if(ranged) //woosh beam if bluespaced at a distance - if(get_dist(src, T) >= (user.client.maxview() + 2)) - message_admins("\[EXPLOIT] [key_name_admin(user)] attempted to place pipes with a BRPD via a camera console. (Attempted range exploit)") - playsound(src, 'sound/machines/synth_no.ogg', 15, TRUE) - to_chat(user, "ERROR: \The [T] is out of [src]'s range!") - return - - if(!(user in viewers(12, T))) // Checks if the user can see the target turf - to_chat(user, "[src] needs full visibility to determine the dispensing location.") - playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE) - return - user.Beam(T, icon_state = "rped_upgrade", icon = 'icons/effects/effects.dmi', time = 0.5 SECONDS) - T.rpd_act(user, src) - -/obj/item/rpd/attack_obj__legacy__attackchain(obj/O, mob/living/user) - if(user.a_intent != INTENT_HARM) - if(istype(O, /obj/machinery/atmospherics/pipe)) - return - else if(istype(O, /obj/structure/disposalconstruct)) - return - else if(istype(O, /obj/structure/transit_tube_construction)) - return - - return ..() - -#undef RPD_COOLDOWN_TIME -#undef RPD_WALLBUILD_TIME -#undef RPD_MENU_ROTATE -#undef RPD_MENU_FLIP -#undef RPD_MENU_DELETE diff --git a/code/game/objects/items/weapons/scissors.dm b/code/game/objects/items/weapons/scissors.dm deleted file mode 100644 index b4fdb6b0ea2e4..0000000000000 --- a/code/game/objects/items/weapons/scissors.dm +++ /dev/null @@ -1,51 +0,0 @@ -/obj/item/scissors - name = "Scissors" - desc = "Those are scissors. Don't run with them!" - icon_state = "scissor" - item_state = "scissor" - force = 5 - sharp = TRUE - w_class = WEIGHT_CLASS_SMALL - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("slices", "cuts", "stabs", "jabs") - toolspeed = 1 - -/obj/item/scissors/barber - name = "Barber's Scissors" - desc = "A pair of scissors used by a barber." - icon_state = "bscissor" - item_state = "scissor" - attack_verb = list("beautifully sliced", "artistically cut", "smoothly stabbed", "quickly jabbed") - toolspeed = 0.75 - -/obj/item/scissors/attack__legacy__attackchain(mob/living/carbon/M as mob, mob/user as mob) - if(user.a_intent != INTENT_HELP) - ..() - return - if(!(M in view(1))) //Adjacency test - ..() - return - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/head/C = H.get_organ("head") - if(!C) - to_chat(user, "[M] doesn't have a head!") - return - //facial hair - var/f_new_style = tgui_input_list(user, "Select a facial hair style", "Grooming", H.generate_valid_facial_hairstyles()) - //handle normal hair - var/h_new_style = tgui_input_list(user, "Select a hair style", "Grooming", H.generate_valid_hairstyles()) - user.visible_message("[user] starts cutting [M]'s hair!", "You start cutting [M]'s hair!") //arguments for this are: 1. what others see 2. what the user sees. --Fixed grammar, (TGameCo) - playsound(loc, 'sound/goonstation/misc/scissor.ogg', 100, 1) - if(do_after(user, 50 * toolspeed, target = H)) //this is the part that adds a delay. delay is in deciseconds. --Made it 5 seconds, because hair isn't cut in one second in real life, and I want at least a little bit longer time, (TGameCo) - if(!(M in view(1))) //Adjacency test - user.visible_message("[user] stops cutting [M]'s hair.", "You stop cutting [M]'s hair.") - return - if(f_new_style) - C.f_style = f_new_style - if(h_new_style) - C.h_style = h_new_style - - H.update_hair() - H.update_fhair() - user.visible_message("[user] finishes cutting [M]'s hair!") diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm deleted file mode 100644 index 375f4d3acdd25..0000000000000 --- a/code/game/objects/items/weapons/scrolls.dm +++ /dev/null @@ -1,75 +0,0 @@ -/obj/item/teleportation_scroll - name = "scroll of teleportation" - desc = "A scroll for moving around." - icon = 'icons/obj/wizard.dmi' - icon_state = "scroll" - var/uses = 4 - w_class = WEIGHT_CLASS_SMALL - item_state = "paper" - throw_speed = 4 - throw_range = 20 - origin_tech = "bluespace=6" - resistance_flags = FLAMMABLE - -/obj/item/teleportation_scroll/apprentice - name = "lesser scroll of teleportation" - uses = 1 - origin_tech = "bluespace=5" - -/obj/item/teleportation_scroll/examine(mob/user) - . = ..() - . += "Number of uses: [uses]. This scroll will vanish after the final use." - . += "P.S. Don't forget to bring your gear, you'll need it to cast most spells." - -/obj/item/teleportation_scroll/attack_self__legacy__attackchain(mob/living/user) - if(!uses) //somehow? - to_chat(user, "You attempt to read the scroll but it disintegrates in your hand, it appears that is has run out of charges!") - qdel(src) - return - - var/picked_area - picked_area = tgui_input_list(user, "Area to jump to", "Teleport where?", SSmapping.teleportlocs) - if(!picked_area) - return - - var/area/thearea = SSmapping.teleportlocs[picked_area] - if(user.stat || user.restrained()) - return - - if(!(user == loc || (in_range(src, user) && isturf(user.loc)))) - return //They can't use it if they put it in their bag or drop it and walk off, but if they are stood next to it they can. - - if(thearea.tele_proof && !istype(thearea, /area/wizard_station)) //Nowhere in SSmapping.teleportlocs should be tele_proof, but better safe than sorry - to_chat(user, "A mysterious force disrupts your arcane spell matrix, and you remain where you are.") - return - - var/datum/effect_system/smoke_spread/smoke = new - smoke.set_up(5, FALSE, get_turf(user)) - smoke.attach(user) - smoke.start() - var/list/L = list() - - for(var/turf/T in get_area_turfs(thearea.type)) - if(is_blocked_turf(T)) - continue - L.Add(T) - - if(!length(L)) - to_chat(user, "The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry.") - return - - if(user && user.buckled) - user.unbuckle(force = TRUE) - - if(user?.has_buckled_mobs()) - user.unbuckle_all_mobs(force = TRUE) - - user.forceMove(pick(L)) - smoke.start() - uses-- - - if(!uses) - to_chat(user, "The scroll fizzles out of existence as the last of the magic within fades.") - qdel(src) - - user.update_action_buttons_icon() //Update action buttons as some spells might now be castable diff --git a/code/game/objects/items/weapons/shards.dm b/code/game/objects/items/weapons/shards.dm deleted file mode 100644 index 44a563a2cb7f3..0000000000000 --- a/code/game/objects/items/weapons/shards.dm +++ /dev/null @@ -1,97 +0,0 @@ -// Glass shards - -/obj/item/shard - name = "shard" - desc = "A nasty looking shard of glass." - icon = 'icons/obj/shards.dmi' - icon_state = "large" - w_class = WEIGHT_CLASS_TINY - force = 5 - throwforce = 10 - item_state = "shard-glass" - materials = list(MAT_GLASS = MINERAL_MATERIAL_AMOUNT) - attack_verb = list("stabbed", "slashed", "sliced", "cut") - hitsound = 'sound/weapons/bladeslice.ogg' - armor = list(MELEE = 100, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, RAD = 0, FIRE = 50, ACID = 100) - max_integrity = 40 - resistance_flags = ACID_PROOF - sharp = TRUE - var/cooldown = 0 - var/icon_prefix - var/obj/item/stack/sheet/welded_type = /obj/item/stack/sheet/glass - -/obj/item/shard/suicide_act(mob/user) - to_chat(viewers(user), pick("[user] is slitting [user.p_their()] wrists with [src]! It looks like [user.p_theyre()] trying to commit suicide!", - "[user] is slitting [user.p_their()] throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) - return BRUTELOSS - -/obj/item/shard/proc/set_initial_icon_state() - icon_state = pick("large", "medium", "small") - switch(icon_state) - if("small") - pixel_x = rand(-12, 12) - pixel_y = rand(-12, 12) - if("medium") - pixel_x = rand(-8, 8) - pixel_y = rand(-8, 8) - if("large") - pixel_x = rand(-5, 5) - pixel_y = rand(-5, 5) - if(icon_prefix) - icon_state = "[icon_prefix][icon_state]" - -/obj/item/shard/Initialize(mapload) - . = ..() - AddComponent(/datum/component/caltrop, force) - set_initial_icon_state() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered) - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/item/shard/afterattack__legacy__attackchain(atom/movable/AM, mob/user, proximity) - if(!proximity || !(src in user)) - return - if(isturf(AM)) - return - if(isstorage(AM)) - return - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(!H.gloves && !HAS_TRAIT(H, TRAIT_PIERCEIMMUNE)) - var/obj/item/organ/external/affecting = H.get_organ("[user.hand ? "l" : "r" ]_hand") - if(affecting.is_robotic()) - return - to_chat(H, "[src] cuts into your hand!") - if(affecting.receive_damage(force * 0.5)) - H.UpdateDamageIcon() - -/obj/item/shard/welder_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, volume = I.tool_volume)) - return - new welded_type(user.loc) - to_chat(user, "You add the newly-formed glass to the stack.") - qdel(src) - -/obj/item/shard/proc/on_atom_entered(datum/source, atom/movable/entered) - var/mob/living/living_entered = entered - if(istype(living_entered) && has_gravity(loc)) - if(living_entered.incorporeal_move || HAS_TRAIT(living_entered, TRAIT_FLYING) || living_entered.floating) - return - playsound(loc, 'sound/effects/glass_step.ogg', 50, TRUE) - -/obj/item/shard/decompile_act(obj/item/matter_decompiler/C, mob/user) - C.stored_comms["glass"] += 3 - qdel(src) - return TRUE - -/obj/item/shard/plasma - name = "plasma shard" - desc = "A shard of plasma glass. Considerably tougher then normal glass shards. Apparently not tough enough to be a window." - force = 6 - throwforce = 11 - icon_state = "plasmalarge" - materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) - icon_prefix = "plasma" - welded_type = /obj/item/stack/sheet/plasmaglass diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm deleted file mode 100644 index 87e84330eab45..0000000000000 --- a/code/game/objects/items/weapons/shields.dm +++ /dev/null @@ -1,175 +0,0 @@ -/obj/item/shield - name = "shield" - icon = 'icons/obj/weapons/shield.dmi' - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 0, BOMB = 30, RAD = 0, FIRE = 80, ACID = 70) - -/obj/item/shield/proc/add_parry_component() - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES) - -/obj/item/shield/Initialize(mapload) - . = ..() - add_parry_component() - -/obj/item/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(attack_type == LEAP_ATTACK) - final_block_chance = 100 - return ..() - -/obj/item/shield/riot - name = "riot shield" - desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder." - icon_state = "riot" - slot_flags = ITEM_SLOT_BACK - force = 10 - throwforce = 5 - throw_speed = 2 - throw_range = 3 - w_class = WEIGHT_CLASS_BULKY - materials = list(MAT_GLASS=7500, MAT_METAL=1000) - origin_tech = "materials=3;combat=4" - attack_verb = list("shoved", "bashed") - var/cooldown = 0 //shield bash cooldown. based on world.time - var/list/allowed_bashers = list(/obj/item/melee/baton, /obj/item/kitchen/knife/combat) - -/obj/item/shield/riot/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(is_type_in_list(W, allowed_bashers)) - if(cooldown < world.time - 2.5 SECONDS) - user.visible_message("[user] bashes [src] with [W]!") - playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1) - cooldown = world.time - else - ..() - -/obj/item/shield/riot/roman - name = "roman shield" - desc = "Bears an inscription on the inside: \"Romanes venio domus\"." - icon_state = "roman_shield" - item_state = "roman_shield" - materials = list(MAT_METAL=8500) - -/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, rad = 0, fire = 0, acid = 0) - -/obj/item/shield/riot/roman/fake/add_parry_component() - return - -/obj/item/shield/riot/buckler - name = "wooden buckler" - desc = "A medieval wooden buckler." - icon_state = "buckler" - item_state = "buckler" - materials = list() - origin_tech = "materials=1;combat=3;biotech=2" - resistance_flags = FLAMMABLE - -/obj/item/shield/riot/buckler/add_parry_component() - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.7, _parryable_attack_types = ALL_ATTACK_TYPES, _parry_cooldown = (10 / 3) SECONDS) // 2.3333 seconds of cooldown for 30% uptime - - -/obj/item/shield/energy - name = "energy combat shield" - desc = "A shield that reflects almost all energy projectiles, but is useless against physical attacks. It can be retracted, expanded, and stored anywhere." - icon_state = "eshield0" // eshield1 for expanded - force = 3 - throwforce = 3 - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=4;magnets=5;syndicate=6" - attack_verb = list("shoved", "bashed") - var/active = FALSE - -/obj/item/shield/energy/add_parry_component() - return - -/obj/item/shield/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(isprojectile(hitby)) - var/obj/item/projectile/P = hitby - if(P.shield_buster && active) - toggle(owner, TRUE) - to_chat(owner, "[hitby] overloaded your [src]!") - return 0 - -/obj/item/shield/energy/IsReflect() - return (active) - -/obj/item/shield/energy/attack_self__legacy__attackchain(mob/living/carbon/human/user) - toggle(user, FALSE) - -/obj/item/shield/energy/proc/toggle(mob/living/carbon/human/user, forced) - if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50) && !forced) - to_chat(user, "You beat yourself in the head with [src].") - user.take_organ_damage(5) - active = !active - icon_state = "eshield[active]" - - if(active) - force = 10 - throwforce = 8 - throw_speed = 2 - w_class = WEIGHT_CLASS_BULKY - playsound(user, 'sound/weapons/saberon.ogg', 35, 1) - to_chat(user, "[src] is now active.") - else - force = 3 - throwforce = 3 - throw_speed = 3 - w_class = WEIGHT_CLASS_TINY - playsound(user, 'sound/weapons/saberoff.ogg', 35, 1) - to_chat(user, "[src] can now be concealed.") - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() - if(!forced) - add_fingerprint(user) - return - -/obj/item/shield/riot/tele - name = "telescopic shield" - desc = "An advanced riot shield made of lightweight materials that collapses for easy storage." - icon_state = "teleriot0" - origin_tech = "materials=3;combat=4;engineering=4" - slot_flags = null - force = 3 - throwforce = 3 - throw_speed = 3 - throw_range = 4 - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/shield/riot/tele/add_parry_component() - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.7, _parryable_attack_types = ALL_ATTACK_TYPES, _parry_cooldown = (5 / 3) SECONDS, _requires_activation = TRUE) - -/obj/item/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) - return ..() - return FALSE // by not calling the parent the hit_reaction signal is never sent - -/obj/item/shield/riot/tele/attack_self__legacy__attackchain(mob/living/user) - if(HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)) - REMOVE_TRAIT(src,TRAIT_ITEM_ACTIVE, TRAIT_GENERIC) - force = 3 - throwforce = 3 - throw_speed = 3 - w_class = WEIGHT_CLASS_NORMAL - slot_flags = null - to_chat(user, "[src] can now be concealed.") - else - ADD_TRAIT(src, TRAIT_ITEM_ACTIVE, TRAIT_GENERIC) - force = 8 - throwforce = 5 - throw_speed = 2 - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK - to_chat(user, "You extend \the [src].") - icon_state = "teleriot[HAS_TRAIT(src, TRAIT_ITEM_ACTIVE)]" - playsound(loc, 'sound/weapons/batonextend.ogg', 50, TRUE) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() - add_fingerprint(user) - return diff --git a/code/game/objects/items/weapons/soap.dm b/code/game/objects/items/weapons/soap.dm deleted file mode 100644 index b0f9180a6812e..0000000000000 --- a/code/game/objects/items/weapons/soap.dm +++ /dev/null @@ -1,120 +0,0 @@ -/obj/item/soap - name = "soap" - desc = "A cheap bar of soap. Doesn't smell." - gender = PLURAL - icon = 'icons/obj/janitor.dmi' - icon_state = "soap" - lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' - w_class = WEIGHT_CLASS_TINY - throwforce = 0 - throw_speed = 4 - throw_range = 20 - discrete = 1 - var/cleanspeed = 50 //slower than mop - var/times_eaten = 0 //How many times a Drask has chewed on this bar of soap - var/max_bites = 30 //The maximum amount of bites before the soap is depleted - -/obj/item/soap/Initialize(mapload) - . = ..() - AddComponent(/datum/component/slippery, src, 8 SECONDS, 100, 0, FALSE) - -/obj/item/soap/afterattack__legacy__attackchain(atom/target, mob/user, proximity) - if(!proximity) - return - if(user.zone_selected == "mouth" && ishuman(target)) // cleaning out someone's mouth is a different act - return - if(target == user && user.a_intent == INTENT_GRAB && ishuman(target)) - var/mob/living/carbon/human/muncher = user - if(muncher && isdrask(muncher)) - eat_soap(muncher) - return - target.cleaning_act(user, src, cleanspeed) - -/obj/item/soap/add_blood(list/blood_dna, b_color) - return - -/obj/item/soap/proc/eat_soap(mob/living/carbon/human/drask/user) - times_eaten++ - playsound(user.loc, 'sound/items/eatfood.ogg', 50, 0) - user.adjust_nutrition(5) - user.reagents.add_reagent("soapreagent", 3) - if(times_eaten < max_bites) - to_chat(user, "You take a bite of [src]. Delicious!") - else - to_chat(user, "You finish eating [src].") - qdel(src) - -/obj/item/soap/examine(mob/user) - . = ..() - if(!user.Adjacent(src) || !times_eaten) - return - if(times_eaten < (max_bites * 0.3)) - . += "[src] has bite marks on it!" - else if(times_eaten < (max_bites * 0.6)) - . += "Big chunks of [src] have been chewed off!" - else if(times_eaten < (max_bites * 0.9)) - . += "Most of [src] has been gnawed away!" - else - . += "[src] has been eaten down to a sliver!" - -/obj/item/soap/attack__legacy__attackchain(mob/target as mob, mob/user as mob) - if(target && user && ishuman(target) && ishuman(user) && !target.stat && !user.stat && user.zone_selected == "mouth") - user.visible_message("[user] starts washing [target]'s mouth out with [name]!") - if(do_after(user, cleanspeed, target = target)) - user.visible_message("[user] washes [target]'s mouth out with [name]!") - target.reagents.add_reagent("soapreagent", 6) - return - ..() - -/obj/item/soap/can_clean() - return TRUE - -/obj/item/soap/nanotrasen - desc = "A Nanotrasen brand bar of soap. Smells of plasma." - icon_state = "soapnt" - -/obj/item/soap/homemade - desc = "A homemade bar of soap. Smells of... well...." - icon_state = "soapgibs" - cleanspeed = 45 // a little faster to reward chemists for going to the effort - -/obj/item/soap/ducttape - desc = "A homemade bar of soap. It seems to be gibs and tape..Will this clean anything?" - icon_state = "soapgibs" - -/obj/item/soap/ducttape/afterattack__legacy__attackchain(atom/target, mob/user as mob, proximity) - if(!proximity) return - - if(user.client && (target in user.client.screen)) - to_chat(user, "You need to take that [target.name] off before 'cleaning' it.") - else - user.visible_message("[user] begins to smear [src] on \the [target.name].") - if(do_after(user, cleanspeed, target = target)) - to_chat(user, "You 'clean' \the [target.name].") - if(issimulatedturf(target)) - new /obj/effect/decal/cleanable/blood/gibs/cleangibs(target) - else if(iscarbon(target)) - for(var/obj/item/carried_item in target.contents) - if(!istype(carried_item, /obj/item/bio_chip))//If it's not an implant. - carried_item.add_mob_blood(target)//Oh yes, there will be blood... - var/mob/living/carbon/human/H = target - H.make_bloody_hands(H.get_blood_dna_list(), H.get_blood_color(), 0) - H.bloody_body(target) - - return - -/obj/item/soap/deluxe - desc = "A luxury bar of soap. Smells of honey." - icon_state = "soapdeluxe" - cleanspeed = 40 //slightly better because deluxe -- captain gets one of these - -/obj/item/soap/deluxe/laundry - name = "laundry soap" - desc = "Very cheap but effective soap. Dries out the skin." - icon_state = "soapsoviet" - -/obj/item/soap/syndie - desc = "An untrustworthy bar of soap made of strong chemical agents that dissolve blood faster." - icon_state = "soapsyndie" - cleanspeed = 10 //much faster than mop so it is useful for traitors who want to clean crime scenes diff --git a/code/game/objects/items/weapons/staff.dm b/code/game/objects/items/weapons/staff.dm deleted file mode 100644 index 150324f7403d1..0000000000000 --- a/code/game/objects/items/weapons/staff.dm +++ /dev/null @@ -1,75 +0,0 @@ -/obj/item/staff - name = "wizards staff" - desc = "Apparently a staff used by the wizard." - icon = 'icons/obj/wizard.dmi' - icon_state = "staff" - lefthand_file = 'icons/mob/inhands/staves_lefthand.dmi' - righthand_file = 'icons/mob/inhands/staves_righthand.dmi' - force = 3.0 - throwforce = 5.0 - throw_speed = 1 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - armour_penetration_percentage = 100 - attack_verb = list("bludgeoned", "whacked", "disciplined") - resistance_flags = FLAMMABLE - -/obj/item/staff/Initialize(mapload) - . = ..() - AddComponent(/datum/component/two_handed) - -/obj/item/staff/broom - name = "broom" - desc = "Used for sweeping, and flying into the night while cackling. Black cat not included." - icon = 'icons/obj/wizard.dmi' - icon_state = "broom" - item_state = "broom0" - -/obj/item/staff/broom/Initialize(mapload) - . = ..() - AddComponent(/datum/component/two_handed, force_wielded = 5, force_unwielded = 3, wield_callback = CALLBACK(src, PROC_REF(wield)), unwield_callback = CALLBACK(src, PROC_REF(unwield))) - -/obj/item/staff/broom/proc/wield(obj/item/source, mob/user) - attack_verb = list("rammed into", "charged at") - user.update_inv_l_hand() - user.update_inv_r_hand() - if(iswizard(user)) - ADD_TRAIT(user, TRAIT_FLYING, "broomstick") - user.say("QUID 'ITCH") - animate(user, pixel_y = pixel_y + 10 , time = 10, loop = 1, easing = SINE_EASING) - to_chat(user, "You hold [src] between your legs.") - -/obj/item/staff/broom/proc/unwield(obj/item/source, mob/user) - attack_verb = list("bludgeoned", "whacked", "cleaned") - user.update_inv_l_hand() - user.update_inv_r_hand() - if(iswizard(user)) - REMOVE_TRAIT(user, TRAIT_FLYING, "broomstick") - animate(user, pixel_y = pixel_y + 10 , time = 1, loop = 1) - animate(user, pixel_y = pixel_y, time = 10, loop = 1, easing = SINE_EASING) - animate(user) - -/obj/item/staff/broom/attackby__legacy__attackchain(obj/O, mob/user) - if(istype(O, /obj/item/clothing/mask/horsehead)) - new/obj/item/staff/broom/horsebroom(get_turf(src)) - user.unequip(O) - qdel(O) - qdel(src) - return - ..() - -/obj/item/staff/broom/dropped(mob/user) - REMOVE_TRAIT(user, TRAIT_FLYING, "broomstick") - ..() - -/obj/item/staff/broom/horsebroom - name = "broomstick horse" - desc = "Saddle up!" - icon = 'icons/obj/wizard.dmi' - icon_state = "horsebroom" - item_state = "horsebroom0" - -/obj/item/staff/broom/horsebroom/attack_self__legacy__attackchain(mob/user as mob) - ..() - item_state = "horsebroom[HAS_TRAIT(src, TRAIT_WIELDED) ? 1 : 0]" - diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm deleted file mode 100644 index 20b8f8870a7b0..0000000000000 --- a/code/game/objects/items/weapons/storage/bible.dm +++ /dev/null @@ -1,194 +0,0 @@ -/obj/item/storage/bible - name = "bible" - desc = "Apply to head repeatedly." - lefthand_file = 'icons/mob/inhands/religion_lefthand.dmi' - righthand_file = 'icons/mob/inhands/religion_righthand.dmi' - icon_state ="bible" - throw_speed = 1 - throw_range = 5 - w_class = WEIGHT_CLASS_NORMAL - resistance_flags = FIRE_PROOF - drop_sound = 'sound/items/handling/book_drop.ogg' - pickup_sound = 'sound/items/handling/book_pickup.ogg' - var/mob/affecting = null - var/deity_name = "Christ" - /// Is the sprite of this bible customisable - var/customisable = FALSE - - /// Associative list of accociative lists of bible variants, used for the radial menu - var/static/list/bible_variants = list( - "Bible" = list("state" = "bible", "inhand" = "bible"), - "Koran" = list("state" = "koran", "inhand" = "koran"), - "Scrapbook" = list("state" = "scrapbook", "inhand" = "scrapbook"), - "Creeper" = list("state" = "creeper", "inhand" = "generic_bible"), - "White Bible" = list("state" = "white", "inhand" = "generic_bible"), - "Holy Light" = list("state" = "holylight", "inhand" = "generic_bible"), - "PlainRed" = list("state" = "athiest", "inhand" = "generic_bible"), - "Tome" = list("state" = "tome", "inhand" = "generic_bible"), - "The King in Yellow" = list("state" = "kingyellow", "inhand" = "kingyellow"), - "Ithaqua" = list("state" = "ithaqua", "inhand" = "ithaqua"), - "Scientology" = list("state" = "scientology", "inhand" = "scientology"), - "the bible melts" = list("state" = "melted", "inhand" = "melted"), - "Necronomicon" = list("state" = "necronomicon", "inhand" = "necronomicon"), - "Greentext" = list("state" = "greentext", "inhand" = "greentext"), - "Honkmother" = list("state" = "honk", "inhand" = "honk"), - "Silentfather" = list("state" = "mime", "inhand" = "mime"), - "Clockwork" = list("state" = "clock_bible", "inhand" = "clock_bible"), - "Nanotrasen" = list("state" = "nanotrasen", "inhand" = "nanotrasen") - ) - -/obj/item/storage/bible/suicide_act(mob/user) - user.visible_message("[user] stares into [name] and attempts to transcend understanding of the universe!") - user.dust() - return OBLITERATION - -/obj/item/storage/bible/fart_act(mob/living/M) - if(QDELETED(M) || M.stat == DEAD) - return - M.visible_message("[M] farts on \the [name]!") - M.visible_message("A mysterious force smites [M]!") - M.suiciding = TRUE - do_sparks(3, 1, M) - M.gib() - return TRUE // Don't run the fart emote - -/obj/item/storage/bible/booze - name = "bible" - desc = "To be applied to the head repeatedly." - icon_state ="bible" - -/obj/item/storage/bible/booze/populate_contents() - new /obj/item/reagent_containers/drinks/bottle/beer(src) - new /obj/item/reagent_containers/drinks/bottle/beer(src) - new /obj/item/stack/spacecash(src) - new /obj/item/stack/spacecash(src) - new /obj/item/stack/spacecash(src) -//BS12 EDIT - // All cult functionality moved to Null Rod -/obj/item/storage/bible/proc/bless(mob/living/carbon/M) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.heal_overall_damage(10, 10) - return - -/obj/item/storage/bible/attack__legacy__attackchain(mob/living/M, mob/living/user) - add_attack_logs(user, M, "Hit with [src]") - if(!iscarbon(user)) - M.LAssailant = null - else - M.LAssailant = user - - if(!(ishuman(user) || SSticker) && SSticker.mode.name != "monkey") - to_chat(user, "You don't have the dexterity to do this!") - return - if(!HAS_MIND_TRAIT(user, TRAIT_HOLY)) - to_chat(user, "The book sizzles in your hands.") - user.take_organ_damage(0, 10) - return - - if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) - to_chat(user, "[src] slips out of your hand and hits your head.") - user.take_organ_damage(10) - user.Paralyse(40 SECONDS) - return - - if(M.stat != DEAD && ishuman(M)) - var/mob/living/carbon/human/H = M - if(prob(60)) - bless(H) - H.visible_message("[user] heals [H == user ? "[user.p_themselves()]" : "[H]"] with the power of [deity_name]!", - "May the power of [deity_name] compel you to be healed!") - playsound(loc, "punch", 25, TRUE, -1) - else - M.adjustBrainLoss(10) - to_chat(M, "You feel dumber.") - H.visible_message("[user] beats [H == user ? "[user.p_themselves()]" : "[H]"] over the head with [src]!") - playsound(src.loc, "punch", 25, TRUE, -1) - else - M.visible_message("[user] smacks [M]'s lifeless corpse with [src].") - playsound(src.loc, "punch", 25, TRUE, -1) - - -/obj/item/storage/bible/afterattack__legacy__attackchain(atom/target, mob/user, proximity, params) - if(!proximity) - return - - if(isfloorturf(target)) - to_chat(user, "You hit the floor with the bible.") - if(HAS_MIND_TRAIT(user, TRAIT_HOLY)) - for(var/obj/O in target) - O.cult_reveal() - if(istype(target, /obj/machinery/door/airlock)) - to_chat(user, "You hit the airlock with the bible.") - if(HAS_MIND_TRAIT(user, TRAIT_HOLY)) - var/obj/airlock = target - airlock.cult_reveal() - - if(HAS_MIND_TRAIT(user, TRAIT_HOLY) && target.reagents) - if(target.reagents.has_reagent("water")) //blesses all the water in the holder - to_chat(user, "You bless [target].") - var/water2holy = target.reagents.get_reagent_amount("water") - target.reagents.del_reagent("water") - target.reagents.add_reagent("holywater", water2holy) - - if(target.reagents.has_reagent("unholywater")) //yeah yeah, copy pasted code - sue me - to_chat(user, "You purify [target].") - var/unholy2clean = target.reagents.get_reagent_amount("unholywater") - target.reagents.del_reagent("unholywater") - target.reagents.add_reagent("holywater", unholy2clean) - -/obj/item/storage/bible/attack_self__legacy__attackchain(mob/user) - . = ..() - if(!customisable || !HAS_MIND_TRAIT(user, TRAIT_HOLY)) - return - - var/list/skins = list() - for(var/I in bible_variants) - var/icons = bible_variants[I] // Get the accociated list - var/image/bible_image = image('icons/obj/storage.dmi', icon_state = icons["state"]) - skins[I] = bible_image - - var/choice = show_radial_menu(user, src, skins, null, 40, CALLBACK(src, PROC_REF(radial_check), user), TRUE) - if(!choice || !radial_check(user)) - return - var/choice_icons = bible_variants[choice] - - icon_state = choice_icons["state"] - item_state = choice_icons["inhand"] - customisable = FALSE - - // Carpet symbol icons are currently broken, so commented out until it's fixed - /*var/carpet_dir - switch(choice) - if("Bible") - carpet_dir = 2 - if("Koran") - carpet_dir = 4 - if("Scientology") - carpet_dir = 8 - if(carpet_dir) - for(var/area/station/service/chapel/main/A in world) - for(var/turf/T in A.contents) - if(T.icon_state == "carpetsymbol") - T.dir = carpet_dir*/ - - SSblackbox.record_feedback("text", "religion_book", 1, "[choice]", 1) - - if(SSticker) - SSticker.Bible_name = name - SSticker.Bible_icon_state = icon_state - SSticker.Bible_item_state = item_state - -/obj/item/storage/bible/proc/radial_check(mob/user) - if(!HAS_MIND_TRAIT(user, TRAIT_HOLY) || !ishuman(user)) - return FALSE - var/mob/living/carbon/human/H = user - if(!src || !H.is_in_hands(src) || H.incapacitated()) - return FALSE - return TRUE - -/obj/item/storage/bible/syndi - name = "suspicious bible" - desc = "For treading the line between cultist, contraband, and a hostile corporation." - customisable = FALSE - icon_state = "syndi" diff --git a/code/game/objects/items/weapons/storage/briefcase.dm b/code/game/objects/items/weapons/storage/briefcase.dm deleted file mode 100644 index 402d6ec2d417f..0000000000000 --- a/code/game/objects/items/weapons/storage/briefcase.dm +++ /dev/null @@ -1,94 +0,0 @@ -/obj/item/storage/briefcase - name = "briefcase" - desc = "It's made of AUTHENTIC faux-leather and has a price-tag still attached. Its owner must be a real professional." - icon_state = "briefcase" - item_state = "briefcase" - flags = CONDUCT - hitsound = "swing_hit" - use_sound = 'sound/effects/briefcase.ogg' - force = 8 - throw_speed = 2 - throw_range = 4 - w_class = WEIGHT_CLASS_BULKY - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = 21 - attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") - resistance_flags = FLAMMABLE - max_integrity = 150 - -/obj/item/storage/briefcase/sniperbundle - desc = "Its label reads \"genuine hardened Captain leather\", but suspiciously has no other tags or branding. Smells like L'Air du Temps." - force = 10 - -/obj/item/storage/briefcase/sniperbundle/populate_contents() - new /obj/item/gun/projectile/automatic/sniper_rifle/syndicate(src) - new /obj/item/clothing/neck/tie/red(src) - new /obj/item/clothing/under/syndicate/sniper(src) - new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) - new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) - new /obj/item/suppressor/specialoffer(src) - -/obj/item/storage/briefcase/false_bottomed - max_w_class = WEIGHT_CLASS_SMALL - max_combined_w_class = 10 - - var/busy_hunting = FALSE - var/bottom_open = FALSE //is the false bottom open? - var/obj/item/stored_item = null //what's in the false bottom. If it's a gun, we can fire it - -/obj/item/storage/briefcase/false_bottomed/Destroy() - if(stored_item)//since the stored_item isn't in the briefcase' contents we gotta remind the game to delete it here. - QDEL_NULL(stored_item) - return ..() - -/obj/item/storage/briefcase/false_bottomed/afterattack__legacy__attackchain(atom/A, mob/user, flag, params) - ..() - if(stored_item && isgun(stored_item)) - var/obj/item/gun/stored_gun = stored_item - stored_gun.afterattack__legacy__attackchain(A, user, flag, params) - -/obj/item/storage/briefcase/false_bottomed/attackby__legacy__attackchain(obj/item/I, mob/user) - if(bottom_open) - if(stored_item) - to_chat(user, "There's already something in the false bottom!") - return - if(I.w_class > WEIGHT_CLASS_NORMAL) - to_chat(user, "[I] is too big to fit in the false bottom!") - return - if(!user.drop_item(I)) - to_chat(user, "[I] is stuck to your hands!") - return - - stored_item = I - max_w_class = WEIGHT_CLASS_NORMAL - stored_item.w_class - I.moveToNullspace() // to stop it showing up in the briefcase - to_chat(user, "You place [I] into the false bottom of the briefcase.") - else - return ..() - -/obj/item/storage/briefcase/false_bottomed/screwdriver_act(mob/user, obj/item/I) - if(!bottom_open && busy_hunting) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - if(!bottom_open) - to_chat(user, "You begin to hunt around the rim of [src]...") - busy_hunting = TRUE - if(do_after(user, 20, target = src)) - if(user) - to_chat(user, "You pry open the false bottom!") - bottom_open = TRUE - busy_hunting = FALSE - else - to_chat(user, "You push the false bottom down and close it with a click[stored_item ? ", with [stored_item] snugly inside." : "."]") - bottom_open = FALSE - -/obj/item/storage/briefcase/false_bottomed/attack_hand(mob/user) - if(bottom_open && stored_item) - user.put_in_hands(stored_item) - to_chat(user, "You pull out [stored_item] from [src]'s false bottom.") - stored_item = null - max_w_class = initial(max_w_class) - else - return ..() diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm deleted file mode 100644 index f05629c1d3dd6..0000000000000 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ /dev/null @@ -1,482 +0,0 @@ -/* - * The 'fancy' path is for objects like donut boxes that show how many items are in the storage item on the sprite itself - * .. Sorry for the shitty path name, I couldnt think of a better one. - * - * WARNING: var/icon_type is used for both examine text and sprite name. Please look at the procs below and adjust your sprite names accordingly - * TODO: Cigarette boxes should be ported to this standard - * - * Contains: - * Donut Box - * Egg Box - * Candle Box - * Crayon Box - * Cigarette Box - */ - -/obj/item/storage/fancy - icon = 'icons/obj/food/containers.dmi' - resistance_flags = FLAMMABLE - var/icon_type - -/obj/item/storage/fancy/update_icon_state() - icon_state = "[icon_type]box[length(contents)]" - -/obj/item/storage/fancy/examine(mob/user) - . = ..() - . += fancy_storage_examine(user) - -/obj/item/storage/fancy/proc/fancy_storage_examine(mob/user) - . = list() - if(in_range(user, src)) - var/len = LAZYLEN(contents) - if(len <= 0) - . += "There are no [icon_type]s left in the box." - else if(len == 1) - . += "There is one [icon_type] left in the box." - else - . += "There are [length(contents)] [icon_type]s in the box." - -/obj/item/storage/fancy/remove_from_storage(obj/item/I, atom/new_location) - if(!istype(I)) - return FALSE - - update_icon() - return ..() - -/* - * Donut Box - */ - -/obj/item/storage/fancy/donut_box - name = "donut box" - desc = "\"To do, or do nut, the choice is obvious.\"" - icon_type = "donut" - icon_state = "donutbox" - storage_slots = 6 - can_hold = list(/obj/item/food/donut) - foldable = /obj/item/stack/sheet/cardboard - foldable_amt = 1 - -/obj/item/storage/fancy/donut_box/update_overlays() - . = ..() - for(var/I = 1 to length(contents)) - var/obj/item/food/donut/donut = contents[I] - var/icon/new_donut_icon = icon('icons/obj/food/containers.dmi', "[(I - 1)]donut[donut.donut_sprite_type]") - . += new_donut_icon - -/obj/item/storage/fancy/donut_box/update_icon_state() - return - -/obj/item/storage/fancy/donut_box/populate_contents() - for(var/I in 1 to storage_slots) - new /obj/item/food/donut(src) - update_icon(UPDATE_OVERLAYS) - -/obj/item/storage/fancy/donut_box/empty/populate_contents() - update_icon(UPDATE_OVERLAYS) - return - -/obj/item/storage/fancy/donut_box/decompile_act(obj/item/matter_decompiler/C, mob/user) - if(isdrone(user) && !length(contents)) - C.stored_comms["wood"] += 1 - qdel(src) - return TRUE - return ..() - -/* - * Egg Box - */ - -/obj/item/storage/fancy/egg_box - icon_state = "eggbox" - icon_type = "egg" - item_state = "eggbox" - name = "egg box" - storage_slots = 12 - can_hold = list(/obj/item/food/egg) - -/obj/item/storage/fancy/egg_box/populate_contents() - for(var/I in 1 to storage_slots) - new /obj/item/food/egg(src) - -/* - * Candle Box - */ - -/obj/item/storage/fancy/candle_box - name = "Candle pack" - desc = "A pack of red candles." - icon = 'icons/obj/candle.dmi' - icon_state = "candlebox0" - icon_type = "candle" - item_state = "candlebox5" - storage_slots = 5 - throwforce = 2 - slot_flags = ITEM_SLOT_BELT - -/obj/item/storage/fancy/candle_box/Initialize(mapload) - . = ..() - update_icon(UPDATE_ICON_STATE) - -/obj/item/storage/fancy/candle_box/full/populate_contents() - for(var/I in 1 to storage_slots) - new /obj/item/candle(src) - -/obj/item/storage/fancy/candle_box/eternal - name = "Eternal Candle pack" - desc = "A pack of red candles made with a special wax." - -/obj/item/storage/fancy/candle_box/eternal/populate_contents() - for(var/I in 1 to storage_slots) - new /obj/item/candle/eternal(src) - -/* - * Crayon Box - */ - -/obj/item/storage/fancy/crayons - name = "box of crayons" - desc = "A box of crayons for all your rune drawing needs." - icon = 'icons/obj/crayons.dmi' - icon_state = "crayonbox" - w_class = WEIGHT_CLASS_SMALL - storage_slots = 8 - icon_type = "crayon" - can_hold = list( - /obj/item/toy/crayon - ) - -/obj/item/storage/fancy/crayons/populate_contents() - new /obj/item/toy/crayon/white(src) - new /obj/item/toy/crayon/red(src) - new /obj/item/toy/crayon/orange(src) - new /obj/item/toy/crayon/yellow(src) - new /obj/item/toy/crayon/green(src) - new /obj/item/toy/crayon/blue(src) - new /obj/item/toy/crayon/purple(src) - new /obj/item/toy/crayon/black(src) - update_icon() - -/obj/item/storage/fancy/crayons/update_overlays() - . = ..() - . += image('icons/obj/crayons.dmi',"crayonbox") - for(var/obj/item/toy/crayon/crayon in contents) - . += image('icons/obj/crayons.dmi', crayon.dye_color) - -/obj/item/storage/fancy/crayons/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/toy/crayon)) - var/obj/item/toy/crayon/C = I - switch(C.dye_color) - if("mime") - to_chat(usr, "This crayon is too sad to be contained in this box.") - return - if("rainbow") - to_chat(usr, "This crayon is too powerful to be contained in this box.") - return - ..() - -/* - * Matches Box - */ - -/obj/item/storage/fancy/matches - name = "matchbox" - desc = "A small box of Almost But Not Quite Plasma Premium Matches." - icon = 'icons/obj/cigarettes.dmi' - icon_state = "matchbox" - item_state = "matchbox" - base_icon_state = "matchbox" - storage_slots = 10 - w_class = WEIGHT_CLASS_TINY - max_w_class = WEIGHT_CLASS_TINY - slot_flags = ITEM_SLOT_BELT - drop_sound = 'sound/items/handling/matchbox_drop.ogg' - pickup_sound = 'sound/items/handling/matchbox_pickup.ogg' - can_hold = list(/obj/item/match) - -/obj/item/storage/fancy/matches/populate_contents() - for(var/I in 1 to storage_slots) - new /obj/item/match(src) - -/obj/item/storage/fancy/matches/attackby__legacy__attackchain(obj/item/match/W, mob/user, params) - if(istype(W, /obj/item/match) && !W.lit) - W.matchignite() - playsound(user.loc, 'sound/goonstation/misc/matchstick_light.ogg', 50, TRUE) - return - -/obj/item/storage/fancy/matches/update_icon_state() - . = ..() - switch(length(contents)) - if(10) - icon_state = base_icon_state - if(5 to 9) - icon_state = "[base_icon_state]_almostfull" - if(1 to 4) - icon_state = "[base_icon_state]_almostempty" - if(0) - icon_state = "[base_icon_state]_e" - -//////////// -//CIG PACK// -//////////// -/obj/item/storage/fancy/cigarettes - name = "cigarette packet" - desc = "The most popular brand of Space Cigarettes, sponsors of the Space Olympics." - icon = 'icons/obj/cigarettes.dmi' - icon_state = "cigpacket" - item_state = "cigpacket" - belt_icon = "patch_pack" - w_class = WEIGHT_CLASS_SMALL - throwforce = 2 - slot_flags = ITEM_SLOT_BELT - storage_slots = 6 - max_combined_w_class = 6 - can_hold = list(/obj/item/clothing/mask/cigarette, - /obj/item/lighter, - /obj/item/match) - cant_hold = list(/obj/item/clothing/mask/cigarette/cigar, - /obj/item/clothing/mask/cigarette/pipe, - /obj/item/lighter/zippo) - icon_type = "cigarette" - var/cigarette_type = /obj/item/clothing/mask/cigarette - -/obj/item/storage/fancy/cigarettes/populate_contents() - for(var/I in 1 to storage_slots) - new cigarette_type(src) - -/obj/item/storage/fancy/cigarettes/update_icon_state() - icon_state = "[initial(icon_state)][length(contents)]" - -/obj/item/storage/fancy/cigarettes/attack__legacy__attackchain(mob/living/carbon/M, mob/living/user) - if(!ismob(M)) - return - - if(istype(M) && user.zone_selected == "mouth" && length(contents) > 0 && !M.wear_mask) - var/got_cig = FALSE - for(var/num in 1 to length(contents)) - var/obj/item/I = contents[num] - if(istype(I, /obj/item/clothing/mask/cigarette)) - var/obj/item/clothing/mask/cigarette/C = I - M.equip_to_slot_if_possible(C, ITEM_SLOT_MASK) - if(M != user) - user.visible_message( - "[user] takes \a [C.name] out of [src] and gives it to [M].", - "You take \a [C.name] out of [src] and give it to [M]." - ) - else - to_chat(user, "You take \a [C.name] out of the pack.") - update_icon() - got_cig = TRUE - break - if(!got_cig) - to_chat(user, "There are no smokables in the pack!") - else - ..() - -/obj/item/storage/fancy/cigarettes/can_be_inserted(obj/item/W, stop_messages = FALSE) - if(istype(W, /obj/item/match)) - var/obj/item/match/M = W - if(M.lit) - if(!stop_messages) - to_chat(usr, "Putting a lit [W] in [src] probably isn't a good idea.") - return FALSE - if(istype(W, /obj/item/lighter)) - var/obj/item/lighter/L = W - if(L.lit) - if(!stop_messages) - to_chat(usr, "Putting [W] in [src] while lit probably isn't a good idea.") - return FALSE - //if we get this far, handle the insertion checks as normal - . = ..() - -/obj/item/storage/fancy/cigarettes/decompile_act(obj/item/matter_decompiler/C, mob/user) - if(isdrone(user) && !length(contents)) - C.stored_comms["wood"] += 1 - qdel(src) - return TRUE - return ..() - -/obj/item/storage/fancy/cigarettes/dromedaryco - name = "\improper DromedaryCo packet" - desc = "A packet of six imported DromedaryCo cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\"" - icon_state = "Dpacket" - item_state = "Dpacket" - - -/obj/item/storage/fancy/cigarettes/syndicate - name = "\improper Syndicate Cigarettes" - desc = "A packet of six evil-looking cigarettes, A label on the packaging reads, \"Donk Co\"." - icon_state = "syndiepacket" - item_state = "syndiepacket" - cigarette_type = /obj/item/clothing/mask/cigarette/syndicate - -/obj/item/storage/fancy/cigarettes/syndicate/Initialize(mapload) - . = ..() - var/new_name = pick("evil", "suspicious", "ominous", "donk-flavored", "robust", "sneaky") - name = "[new_name] cigarette packet" - -/obj/item/storage/fancy/cigarettes/cigpack_syndicate - name = "cigarette packet" - desc = "An obscure brand of cigarettes." - icon_state = "syndiepacket" - item_state = "syndiepacket" - cigarette_type = /obj/item/clothing/mask/cigarette/syndicate - -/obj/item/storage/fancy/cigarettes/cigpack_med - name = "\improper Medical Marijuana Packet" - desc = "A prescription packet containing six marijuana cigarettes." - icon_state = "medpacket" - item_state = "medpacket" - cigarette_type = /obj/item/clothing/mask/cigarette/medical_marijuana - - -/obj/item/storage/fancy/cigarettes/cigpack_uplift - name = "\improper Uplift Smooth packet" - desc = "Your favorite brand, now menthol flavored." - icon_state = "upliftpacket" - item_state = "upliftpacket" - cigarette_type = /obj/item/clothing/mask/cigarette/menthol - -/obj/item/storage/fancy/cigarettes/cigpack_robust - name = "\improper Robust packet" - desc = "Smoked by the robust." - icon_state = "robustpacket" - item_state = "robustpacket" - -/obj/item/storage/fancy/cigarettes/cigpack_robustgold - name = "\improper Robust Gold packet" - desc = "Smoked by the truly robust." - icon_state = "robustgpacket" - item_state = "robustgpacket" - cigarette_type = /obj/item/clothing/mask/cigarette/robustgold - -/obj/item/storage/fancy/cigarettes/cigpack_carp - name = "\improper Carp Classic packet" - desc = "Since 2313." - icon_state = "carppacket" - item_state = "carppacket" - -/obj/item/storage/fancy/cigarettes/cigpack_midori - name = "\improper Midori Tabako packet" - desc = "You can't understand the runes, but the packet smells funny." - icon_state = "midoripacket" - item_state = "midoripacket" - cigarette_type = /obj/item/clothing/mask/cigarette/rollie - -/obj/item/storage/fancy/cigarettes/cigpack_shadyjims - name ="\improper Shady Jim's Super Slims" - desc = "Is your weight slowing you down? Having trouble running away from gravitational singularities? Can't stop stuffing your mouth? Smoke Shady Jim's Super Slims and watch all that fat burn away. Guaranteed results!" - icon_state = "shadyjimpacket" - item_state = "shadyjimpacket" - cigarette_type = /obj/item/clothing/mask/cigarette/shadyjims - -/obj/item/storage/fancy/cigarettes/cigpack_random - name ="\improper Embellished Enigma packet" - desc = "For the true connoisseur of exotic flavors." - icon_state = "shadyjimpacket" - item_state = "shadyjimpacket" - cigarette_type = /obj/item/clothing/mask/cigarette/random - -/obj/item/storage/fancy/rollingpapers - name = "rolling paper pack" - desc = "A pack of Nanotrasen brand rolling papers." - w_class = WEIGHT_CLASS_TINY - icon = 'icons/obj/cigarettes.dmi' - icon_state = "cig_paper_pack" - item_state = "cig_paper_pack" - storage_slots = 10 - icon_type = "rolling paper" - can_hold = list(/obj/item/rollingpaper) - -/obj/item/storage/fancy/rollingpapers/update_icon_state() - return - -/obj/item/storage/fancy/rollingpapers/populate_contents() - for(var/I in 1 to storage_slots) - new /obj/item/rollingpaper(src) - -/obj/item/storage/fancy/rollingpapers/update_overlays() - . = ..() - if(!length(contents)) - . += "[icon_state]_empty" - -/* - * Vial Box - */ - -/obj/item/storage/fancy/vials - icon = 'icons/obj/vialbox.dmi' - icon_state = "vialbox6" - icon_type = "vial" - name = "vial storage box" - storage_slots = 6 - can_hold = list(/obj/item/reagent_containers/glass/beaker/vial) - - -/obj/item/storage/fancy/vials/populate_contents() - for(var/I in 1 to storage_slots) - new /obj/item/reagent_containers/glass/beaker/vial(src) - return - -/obj/item/storage/lockbox/vials - name = "secure vial storage box" - desc = "A locked box for keeping things away from children." - icon = 'icons/obj/vialbox.dmi' - icon_state = "vialbox0" - item_state = "syringe_kit" - max_w_class = WEIGHT_CLASS_NORMAL - can_hold = list(/obj/item/reagent_containers/glass/bottle) - max_combined_w_class = 14 //The sum of the w_classes of all the items in this storage item. - storage_slots = 6 - req_access = list(ACCESS_VIROLOGY) - -/obj/item/storage/lockbox/vials/Initialize(mapload) - . = ..() - update_icon() - -/obj/item/storage/lockbox/vials/update_icon_state() - icon_state = "vialbox[length(contents)]" - cut_overlays() - -/obj/item/storage/lockbox/vials/update_overlays() - . = ..() - if(!broken) - . += "led[locked]" - if(locked) - . += "cover" - else - . += "ledb" - -/obj/item/storage/lockbox/vials/attackby__legacy__attackchain(obj/item/I, mob/user, params) - ..() - update_icon() - -/obj/item/storage/lockbox/vials/zombie_cure - name = "secure vial storage box - 'Anti-Plague Sequences'" - -/obj/item/storage/lockbox/vials/zombie_cure/populate_contents() - new /obj/item/reagent_containers/glass/bottle/zombiecure1(src) - new /obj/item/reagent_containers/glass/bottle/zombiecure2(src) - new /obj/item/reagent_containers/glass/bottle/zombiecure3(src) - new /obj/item/reagent_containers/glass/bottle/zombiecure4(src) - - -///Aquatic Starter Kit - -/obj/item/storage/firstaid/aquatic_kit - name = "aquatic starter kit" - desc = "It's a starter kit box for an aquarium." - icon_state = "AquaticKit" - throw_speed = 2 - throw_range = 8 - med_bot_skin = "fish" - -/obj/item/storage/firstaid/aquatic_kit/full - desc = "It's a starter kit for an aquarium; includes 1 tank brush, 1 egg scoop, 1 fish net, 1 container of fish food and 1 fish bag." - -/obj/item/storage/firstaid/aquatic_kit/full/populate_contents() - new /obj/item/egg_scoop(src) - new /obj/item/fish_net(src) - new /obj/item/tank_brush(src) - new /obj/item/fishfood(src) - new /obj/item/storage/bag/fish(src) diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm deleted file mode 100644 index c6d394ba222e2..0000000000000 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ /dev/null @@ -1,439 +0,0 @@ -/* First aid storage - * Contains: - * First Aid Kits - * Pill Bottles - * Dice Pack (in a pill bottle) - */ - -/* - * First Aid Kits - */ -/obj/item/storage/firstaid - name = "generic first-aid kit" - desc = "If you can see this, make a bug report on GitHub, something went wrong!" - icon_state = "genericfirstaid" - throw_speed = 2 - throw_range = 8 - req_one_access =list(ACCESS_MEDICAL, ACCESS_ROBOTICS) //Access and treatment are utilized for medbots. - var/treatment_brute = "salglu_solution" - var/treatment_oxy = "salbutamol" - var/treatment_fire = "salglu_solution" - var/treatment_tox = "charcoal" - var/treatment_virus = "spaceacillin" - var/med_bot_skin = null - var/syndicate_aligned = FALSE - var/robot_arm // This is for robot construction - - -/obj/item/storage/firstaid/regular - name = "first-aid kit" - desc = "A general medical kit that contains medical patches for both brute damage and burn damage. Also contains an epinephrine syringe for emergency use and a health analyzer." - icon_state = "firstaid" - -/obj/item/storage/firstaid/regular/populate_contents() - new /obj/item/reagent_containers/patch/styptic(src) - new /obj/item/reagent_containers/patch/styptic(src) - new /obj/item/reagent_containers/pill/salicylic(src) - new /obj/item/reagent_containers/patch/silver_sulf(src) - new /obj/item/reagent_containers/patch/silver_sulf(src) - new /obj/item/healthanalyzer(src) - new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src) - -/obj/item/storage/firstaid/regular/empty/populate_contents() - return - -/obj/item/storage/firstaid/regular/doctor - desc = "A medical kit designed for Nanotrasen medical personnel." - -/obj/item/storage/firstaid/regular/doctor/populate_contents() - new /obj/item/reagent_containers/applicator/brute(src) - new /obj/item/reagent_containers/applicator/burn(src) - new /obj/item/reagent_containers/patch/styptic(src) - new /obj/item/reagent_containers/patch/silver_sulf(src) - new /obj/item/reagent_containers/pill/salicylic(src) - new /obj/item/healthanalyzer/advanced(src) - new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src) - -/obj/item/storage/firstaid/fire - name = "fire first-aid kit" - desc = "A medical kit that contains several medical patches and pills for treating burns. Contains one epinephrine syringe for emergency use and a health analyzer." - icon_state = "ointment" - item_state = "firstaid-ointment" - med_bot_skin = "ointment" - -/obj/item/storage/firstaid/fire/Initialize(mapload) - . = ..() - icon_state = pick("ointment", "firefirstaid") - -/obj/item/storage/firstaid/fire/populate_contents() - new /obj/item/reagent_containers/applicator/burn(src) - new /obj/item/reagent_containers/patch/silver_sulf/small(src) - new /obj/item/healthanalyzer(src) - new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src) - new /obj/item/reagent_containers/pill/salicylic(src) - -/obj/item/storage/firstaid/fire/empty/populate_contents() - return - -/obj/item/storage/firstaid/toxin - name = "toxin first aid kit" - desc = "A medical kit designed to counter poisoning by common toxins. Contains three pills and syringes, and a health analyzer to determine the health of the patient." - icon_state = "antitoxin" - item_state = "firstaid-toxin" - med_bot_skin = "tox" - -/obj/item/storage/firstaid/toxin/Initialize(mapload) - . = ..() - icon_state = pick("antitoxin", "antitoxfirstaid", "antitoxfirstaid2") - -/obj/item/storage/firstaid/toxin/populate_contents() - for(var/I in 1 to 3) - new /obj/item/reagent_containers/syringe/charcoal(src) - new /obj/item/reagent_containers/pill/charcoal(src) - new /obj/item/healthanalyzer(src) - -/obj/item/storage/firstaid/toxin/empty/populate_contents() - return - -/obj/item/storage/firstaid/o2 - name = "oxygen deprivation first aid kit" - desc = "A first aid kit that contains four pills of salbutamol, which is able to counter injuries caused by suffocation. Also contains a health analyzer to determine the health of the patient." - icon_state = "o2" - item_state = "firstaid-o2" - med_bot_skin = "o2" - -/obj/item/storage/firstaid/o2/populate_contents() - new /obj/item/reagent_containers/pill/salbutamol(src) - new /obj/item/reagent_containers/pill/salbutamol(src) - new /obj/item/reagent_containers/pill/salbutamol(src) - new /obj/item/reagent_containers/pill/salbutamol(src) - new /obj/item/healthanalyzer(src) - -/obj/item/storage/firstaid/o2/empty/populate_contents() - return - -/obj/item/storage/firstaid/brute - name = "brute trauma treatment kit" - desc = "A medical kit that contains several medical patches and pills for treating brute injuries. Contains one epinephrine syringe for emergency use and a health analyzer." - icon_state = "brute" - item_state = "firstaid-brute" - med_bot_skin = "brute" - -/obj/item/storage/firstaid/brute/Initialize(mapload) - . = ..() - icon_state = pick("brute", "brute2") - -/obj/item/storage/firstaid/brute/populate_contents() - new /obj/item/reagent_containers/applicator/brute(src) - new /obj/item/reagent_containers/patch/styptic/small(src) - new /obj/item/healthanalyzer(src) - new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src) - new /obj/item/stack/medical/bruise_pack(src) - -/obj/item/storage/firstaid/brute/empty/populate_contents() - return - -/obj/item/storage/firstaid/adv - name = "advanced first-aid kit" - desc = "Contains advanced medical treatments." - icon_state = "advfirstaid" - item_state = "firstaid-advanced" - med_bot_skin = "adv" - -/obj/item/storage/firstaid/adv/populate_contents() - new /obj/item/stack/medical/bruise_pack(src) - new /obj/item/stack/medical/bruise_pack/advanced(src) - new /obj/item/stack/medical/bruise_pack/advanced(src) - new /obj/item/stack/medical/ointment/advanced(src) - new /obj/item/stack/medical/ointment/advanced(src) - new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src) - new /obj/item/healthanalyzer(src) - -/obj/item/storage/firstaid/adv/empty/populate_contents() - return - -/obj/item/storage/firstaid/machine - name = "machine repair kit" - desc = "A kit that contains supplies to repair IPCs on the go." - icon_state = "machinefirstaid" - item_state = "firstaid-machine" - med_bot_skin = "machine" - -/obj/item/storage/firstaid/machine/populate_contents() - new /obj/item/weldingtool/mini(src) - new /obj/item/stack/cable_coil(src) - new /obj/item/stack/cable_coil(src) - new /obj/item/stack/cable_coil(src) - new /obj/item/robotanalyzer(src) - -/obj/item/storage/firstaid/machine/empty/populate_contents() - return - -/obj/item/storage/firstaid/tactical - name = "first-aid kit" - desc = "I hope you've got insurance." - icon_state = "bezerk" - max_w_class = WEIGHT_CLASS_NORMAL - treatment_oxy = "perfluorodecalin" - treatment_brute = "bicaridine" - treatment_fire = "kelotane" - treatment_tox = "charcoal" - req_one_access =list(ACCESS_SYNDICATE) - med_bot_skin = "bezerk" - syndicate_aligned = TRUE - -/obj/item/storage/firstaid/tactical/populate_contents() - new /obj/item/reagent_containers/hypospray/combat(src) - new /obj/item/reagent_containers/applicator/dual/syndi(src) // Because you ain't got no time to look at what damage dey taking yo - new /obj/item/reagent_containers/hypospray/autoinjector/emergency_nuclear(src) - new /obj/item/reagent_containers/hypospray/autoinjector/emergency_nuclear(src) - new /obj/item/storage/pill_bottle/painkillers(src) - new /obj/item/clothing/glasses/hud/health/night(src) - -/obj/item/storage/firstaid/tactical/empty/populate_contents() - return - -/obj/item/storage/firstaid/surgery - name = "field surgery kit" - desc = "A kit for surgery in the field." - icon_state = "duffel-med" - lefthand_file = 'icons/mob/inhands/clothing_lefthand.dmi' - righthand_file = 'icons/mob/inhands/clothing_righthand.dmi' - max_w_class = WEIGHT_CLASS_BULKY - max_combined_w_class = 21 - storage_slots = 10 - can_hold = list(/obj/item/roller,/obj/item/bonesetter,/obj/item/bonegel, /obj/item/scalpel, /obj/item/hemostat, - /obj/item/cautery, /obj/item/retractor, /obj/item/fix_o_vein, /obj/item/surgicaldrill, /obj/item/circular_saw) - -/obj/item/storage/firstaid/surgery/populate_contents() - new /obj/item/roller(src) - new /obj/item/bonesetter(src) - new /obj/item/bonegel(src) - new /obj/item/scalpel(src) - new /obj/item/hemostat(src) - new /obj/item/cautery(src) - new /obj/item/retractor(src) - new /obj/item/fix_o_vein(src) - new /obj/item/surgicaldrill(src) - new /obj/item/circular_saw(src) - -/obj/item/storage/firstaid/ert - name = "ert first-aid kit" - desc = "A medical kit used by Nanotrasen emergency response team personnel." - icon_state = "bezerk" - med_bot_skin = "bezerk" - -/obj/item/storage/firstaid/ert/populate_contents() - new /obj/item/healthanalyzer/advanced(src) - new /obj/item/stack/medical/splint(src) - new /obj/item/reagent_containers/applicator/dual(src) - new /obj/item/stack/medical/ointment/advanced(src) - new /obj/item/stack/medical/ointment/advanced(src) - new /obj/item/stack/medical/bruise_pack/advanced(src) - new /obj/item/stack/medical/bruise_pack/advanced(src) - - -/obj/item/storage/firstaid/ert_amber - name = "amber ert first-aid kit" - desc = "A medical kit used by Amber level emergency response team personnel." - icon_state = "firstaid" - -/obj/item/storage/firstaid/ert_amber/populate_contents() - new /obj/item/healthanalyzer/advanced(src) - new /obj/item/reagent_containers/applicator/brute(src) - new /obj/item/reagent_containers/applicator/burn(src) - new /obj/item/stack/medical/bruise_pack/advanced(src) - new /obj/item/stack/medical/ointment/advanced(src) - new /obj/item/storage/pill_bottle/ert_amber(src) - new /obj/item/storage/pill_bottle/patch_pack/ert_amber(src) - -/obj/item/storage/firstaid/fake_tactical - name = "tactical first-aid kit" - desc = "I hope you've got insurance. The paint is still wet." - icon_state = "bezerk" - med_bot_skin = "bezerk" - -/obj/item/storage/firstaid/fake_tactical/populate_contents() - return - -/* - * Pill Bottles - */ - -/obj/item/storage/pill_bottle - name = "pill bottle" - desc = "It's an airtight container for storing medication." - icon_state = "pill_canister" - icon = 'icons/obj/chemical.dmi' - item_state = "contsolid" - belt_icon = "pill_bottle" - use_sound = "pillbottle" - w_class = WEIGHT_CLASS_SMALL - can_hold = list(/obj/item/reagent_containers/pill) - cant_hold = list(/obj/item/reagent_containers/patch) - allow_quick_gather = TRUE - use_to_pickup = TRUE - storage_slots = 50 - max_combined_w_class = 50 - display_contents_with_number = TRUE - var/base_name = "" - var/label_text = "" - var/applying_meds = FALSE //To Prevent spam clicking and generating runtimes from apply a deleting pill multiple times. - var/rapid_intake_message = "unscrews the cap on the pill bottle and begins dumping the entire contents down their throat!" - var/rapid_post_instake_message = "downs the entire bottle of pills in one go!" - /// Whether to render a coloured wrapper overlay on the icon. - var/allow_wrap = TRUE - /// The color of the wrapper overlay. - var/wrapper_color = null - /// The icon state of the wrapper overlay. - var/wrapper_state = "pillbottle_wrap" - -/obj/item/storage/pill_bottle/Initialize(mapload) - . = ..() - base_name = name - if(allow_wrap) - apply_wrap() - -/obj/item/storage/pill_bottle/proc/apply_wrap() - if(wrapper_color) - overlays.Cut() - var/image/I = image(icon, wrapper_state) - I.color = wrapper_color - overlays += I - -/obj/item/storage/pill_bottle/attack__legacy__attackchain(mob/M, mob/user) - if(iscarbon(M) && length(contents)) - if(applying_meds) - to_chat(user, "You are already applying meds.") - return - applying_meds = TRUE - for(var/obj/item/reagent_containers/P in contents) - if(P.attack__legacy__attackchain(M, user)) - applying_meds = FALSE - else - applying_meds = FALSE - break - else - return ..() - -/obj/item/storage/pill_bottle/ert_red - wrapper_color = COLOR_NT_RED - -/obj/item/storage/pill_bottle/ert_red/populate_contents() - for(var/I in 1 to 6) - new /obj/item/reagent_containers/pill/pentetic(src) - new /obj/item/reagent_containers/pill/ironsaline(src) - new /obj/item/reagent_containers/pill/salicylic(src) - new /obj/item/reagent_containers/pill/mannitol(src) - -/obj/item/storage/pill_bottle/ert_amber - wrapper_color = COLOR_ORANGE - -/obj/item/storage/pill_bottle/ert_amber/populate_contents() - for(var/I in 1 to 6) - new /obj/item/reagent_containers/pill/salbutamol(src) - new /obj/item/reagent_containers/pill/charcoal(src) - new /obj/item/reagent_containers/pill/salicylic(src) - -/obj/item/storage/pill_bottle/ert_gamma - wrapper_color = COLOR_YELLOW_GRAY - -/obj/item/storage/pill_bottle/ert_gamma/populate_contents() - for(var/I in 1 to 6) - new /obj/item/reagent_containers/pill/pentetic(src) - new /obj/item/reagent_containers/pill/ironsaline(src) - new /obj/item/reagent_containers/pill/hydrocodone(src) - new /obj/item/reagent_containers/pill/mannitol(src) - new /obj/item/reagent_containers/pill/lazarus_reagent(src) - new /obj/item/reagent_containers/pill/rezadone(src) - -/obj/item/storage/pill_bottle/MouseDrop(obj/over_object) // Best utilized if you're a cantankerous doctor with a Vicodin habit. - if(iscarbon(over_object)) - var/mob/living/carbon/C = over_object - if(loc == C && src == C.get_active_hand()) - if(!length(contents)) - to_chat(C, "There is nothing in [src]!") - return - C.visible_message("[C] [rapid_intake_message]") - if(do_mob(C, C, 100)) // 10 seconds - for(var/obj/item/reagent_containers/pill/P in contents) - P.attack__legacy__attackchain(C, C) - C.visible_message("[C] [rapid_post_instake_message]") - return - - return ..() - -/obj/item/storage/pill_bottle/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(is_pen(I)) - rename_interactive(user, I) - else - return ..() - -/obj/item/storage/pill_bottle/proc/apply_wrapper_color(color_number) - var/static/list/colors = list(COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_GREEN, COLOR_CYAN_BLUE, COLOR_VIOLET, COLOR_PURPLE) - wrapper_color = colors[(color_number - 1) % length(colors) + 1] - apply_wrap() - -/obj/item/storage/pill_bottle/patch_pack - name = "patch pack" - desc = "It's a container for storing medical patches." - icon_state = "patch_pack" - belt_icon = "patch_pack" - use_sound = "patchpack" - can_hold = list(/obj/item/reagent_containers/patch) - cant_hold = list() - rapid_intake_message = "flips the lid of the patch pack open and begins rapidly stamping patches on themselves!" - rapid_post_instake_message = "stamps the entire contents of the patch pack all over their entire body!" - wrapper_state = "patch_pack_wrap" - -/obj/item/storage/pill_bottle/charcoal - name = "Pill bottle (Charcoal)" - desc = "Contains pills used to counter toxins." - wrapper_color = COLOR_GREEN - -/obj/item/storage/pill_bottle/charcoal/populate_contents() - for(var/I in 1 to 7) - new /obj/item/reagent_containers/pill/charcoal(src) - -/obj/item/storage/pill_bottle/painkillers - name = "Pill Bottle (Salicylic Acid)" - desc = "Contains various pills for minor pain relief." - wrapper_color = COLOR_RED - -/obj/item/storage/pill_bottle/painkillers/populate_contents() - for(var/I in 1 to 8) - new /obj/item/reagent_containers/pill/salicylic(src) - -/obj/item/storage/pill_bottle/fakedeath - allow_wrap = FALSE - -/obj/item/storage/pill_bottle/fakedeath/populate_contents() - new /obj/item/reagent_containers/pill/fakedeath(src) - new /obj/item/reagent_containers/pill/fakedeath(src) - new /obj/item/reagent_containers/pill/fakedeath(src) - -/obj/item/storage/pill_bottle/patch_pack/ert - name = "ert red patch pack" - desc = "A patch pack containing medical patches. Issued to Nanotrasen ERT Red level medics." - wrapper_color = COLOR_NT_RED - -/obj/item/storage/pill_bottle/patch_pack/ert/populate_contents() - for(var/I in 1 to 5) - new /obj/item/reagent_containers/patch/perfluorodecalin(src) - new /obj/item/reagent_containers/patch/silver_sulf(src) - new /obj/item/reagent_containers/patch/styptic(src) - -/obj/item/storage/pill_bottle/patch_pack/ert/gamma - name = "ert gamma patch pack" - desc = "A patch pack containing medical patches. Issued to Nanotrasen ERT Gamma level medics." - wrapper_color = COLOR_YELLOW_GRAY - -/obj/item/storage/pill_bottle/patch_pack/ert_amber - name = "ert amber patch pack" - desc = "A patch pack containing medical patches. Issued to Nanotrasen ERT Amber level medics" - wrapper_color = COLOR_ORANGE - -/obj/item/storage/pill_bottle/patch_pack/ert_amber/populate_contents() - for(var/I in 1 to 5) - new /obj/item/reagent_containers/patch/silver_sulf/small(src) - new /obj/item/reagent_containers/patch/styptic/small(src) diff --git a/code/game/objects/items/weapons/storage/internal.dm b/code/game/objects/items/weapons/storage/internal.dm deleted file mode 100644 index 5f07e5f0f6aaf..0000000000000 --- a/code/game/objects/items/weapons/storage/internal.dm +++ /dev/null @@ -1,88 +0,0 @@ -//A storage item intended to be used by other items to provide storage functionality. -//Types that use this should consider overriding emp_act() and hear_talk(), unless they shield their contents somehow. -/obj/item/storage/internal - var/obj/item/master_item - -/obj/item/storage/internal/New(obj/item/MI) - master_item = MI - loc = master_item - name = master_item.name - ..() - -/obj/item/storage/internal/Destroy() - master_item = null - return ..() - -/obj/item/storage/internal/attack_hand() - return //make sure this is never picked up - -/obj/item/storage/internal/mob_can_equip(mob/M, slot, disable_warning = FALSE) - return 0 //make sure this is never picked up - -//Helper procs to cleanly implement internal storages - storage items that provide inventory slots for other items. -//These procs are completely optional, it is up to the master item to decide when it's storage get's opened by calling open() -//However they are helpful for allowing the master item to pretend it is a storage item itself. -//If you are using these you will probably want to override attackby__legacy__attackchain() as well. -//See /obj/item/clothing/suit/storage for an example. - -//items that use internal storage have the option of calling this to emulate default storage MouseDrop behaviour. -//returns 1 if the master item's parent's MouseDrop() should be called, 0 otherwise. It's strange, but no other way of -//doing it without the ability to call another proc's parent, really. -/obj/item/storage/internal/proc/handle_mousedrop(mob/user as mob, obj/over_object as obj) - if(ishuman(user)) //so monkeys can take off their backpacks -- Urist - - if(ismecha(user.loc)) // stops inventory actions in a mech - return 0 - - if(over_object == user && Adjacent(user)) // this must come before the screen objects only block - open(user) - return FALSE - - if(!is_screen_atom(over_object)) - return TRUE - - //makes sure master_item is equipped before putting it in hand, so that we can't drag it into our hand from miles away. - //there's got to be a better way of doing this... - if(!(master_item.loc == user) || (master_item.loc && master_item.loc.loc == user)) - return 0 - - if(!user.restrained() && !user.stat) - switch(over_object.name) - if("r_hand") - user.unequip(master_item) - user.put_in_r_hand(master_item) - if("l_hand") - user.unequip(master_item) - user.put_in_l_hand(master_item) - master_item.add_fingerprint(user) - return 0 - return 0 - -//items that use internal storage have the option of calling this to emulate default storage attack_hand behaviour. -//returns 1 if the master item's parent's attack_hand() should be called, 0 otherwise. -//It's strange, but no other way of doing it without the ability to call another proc's parent, really. -/obj/item/storage/internal/proc/handle_attack_hand(mob/user as mob) - - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.l_store == master_item && !H.get_active_hand()) //Prevents opening if it's in a pocket. - H.put_in_hands(master_item) - H.l_store = null - return 0 - if(H.r_store == master_item && !H.get_active_hand()) - H.put_in_hands(master_item) - H.r_store = null - return 0 - - add_fingerprint(user) - if(master_item.loc == user) - open(user) - return 0 - - for(var/mob/M in range(1, master_item.loc)) - if(M.s_active == src) - close(M) - return 1 - -/obj/item/storage/internal/Adjacent(atom/neighbor) - return master_item.Adjacent(neighbor) diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm deleted file mode 100644 index 6bc41f4a8c3b1..0000000000000 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ /dev/null @@ -1,242 +0,0 @@ -/obj/item/storage/lockbox - name = "lockbox" - desc = "A locked box." - icon_state = "lockbox+l" - item_state = "syringe_kit" - w_class = WEIGHT_CLASS_BULKY - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = 14 //The sum of the w_classes of all the items in this storage item. - storage_slots = 4 - req_access = list(ACCESS_ARMORY) - var/locked = TRUE - var/broken = FALSE - var/icon_locked = "lockbox+l" - var/icon_closed = "lockbox" - var/icon_broken = "lockbox+b" - -/obj/item/storage/lockbox/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda)) - if(broken) - to_chat(user, "It appears to be broken.") - return - if(check_access(W)) - locked = !locked - if(locked) - to_chat(user, "You lock \the [src]!") - if(user.s_active) - user.s_active.close(user) - else - to_chat(user, "You unlock \the [src]!") - origin_tech = null //wipe out any origin tech if it's unlocked in any way so you can't double-dip tech levels at R&D. - update_icon() - return - else - to_chat(user, "Access denied.") - return - else if((istype(W, /obj/item/card/emag) || (istype(W, /obj/item/melee/energy/blade)) && !broken)) - emag_act(user) - return TRUE - if(!locked) - ..() - else - to_chat(user, "It's locked!") - return - -/obj/item/storage/lockbox/AltClick(mob/user) - if(!Adjacent(user)) - return - if(broken) - to_chat(user, "It appears to be broken.") - return - if(!locked && user.s_active != src) - return ..() - if(allowed(user)) - locked = !locked - to_chat(user, "You [locked ? "lock" : "unlock"] [src].") - update_icon() - if(user.s_active == src) - close(user) - else - to_chat(user, "Access denied.") - -/obj/item/storage/lockbox/update_icon_state() - if(broken) - icon_state = icon_broken - else if(locked) - icon_state = icon_locked - else - icon_state = icon_closed // good variable name bro - -/obj/item/storage/lockbox/show_to(mob/user as mob) - if(locked) - to_chat(user, "It's locked!") - else - ..() - return - -/obj/item/storage/lockbox/can_be_inserted(obj/item/W as obj, stop_messages = 0) - if(!locked) - return ..() - if(!stop_messages) - to_chat(usr, "[src] is locked!") - return 0 - -/obj/item/storage/lockbox/emag_act(user as mob) - if(!broken) - broken = TRUE - locked = FALSE - desc = "It appears to be broken." - to_chat(user, "You unlock \the [src].") - origin_tech = null //wipe out any origin tech if it's unlocked in any way so you can't double-dip tech levels at R&D. - update_icon() - return - -/obj/item/storage/lockbox/hear_talk(mob/living/M as mob, list/message_pieces) - return - -/obj/item/storage/lockbox/hear_message(mob/living/M as mob, msg) - return - -/obj/item/storage/lockbox/mindshield - name = "Lockbox (Mindshield Implants)" - req_access = list(ACCESS_SECURITY) - -/obj/item/storage/lockbox/mindshield/populate_contents() - new /obj/item/bio_chip_case/mindshield(src) - new /obj/item/bio_chip_case/mindshield(src) - new /obj/item/bio_chip_case/mindshield(src) - new /obj/item/bio_chip_implanter/mindshield(src) - -/obj/item/storage/lockbox/clusterbang - name = "lockbox (clusterbang)" - desc = "You have a bad feeling about opening this." - req_access = list(ACCESS_SECURITY) - -/obj/item/storage/lockbox/clusterbang/populate_contents() - new /obj/item/grenade/clusterbuster(src) - -/obj/item/storage/lockbox/medal - name = "medal box" - desc = "A locked box used to store medals of honor." - icon_state = "medalbox+l" - item_state = "syringe_kit" - w_class = WEIGHT_CLASS_NORMAL - max_w_class = WEIGHT_CLASS_SMALL - max_combined_w_class = 20 - storage_slots = 12 - req_access = list(ACCESS_CAPTAIN) - icon_locked = "medalbox+l" - icon_closed = "medalbox" - icon_broken = "medalbox+b" - -/obj/item/storage/lockbox/medal/populate_contents() - new /obj/item/clothing/accessory/medal/gold/captain(src) - new /obj/item/clothing/accessory/medal/silver/leadership(src) - new /obj/item/clothing/accessory/medal/silver/valor(src) - new /obj/item/clothing/accessory/medal/heart(src) - -/obj/item/storage/lockbox/medal/cc - name = "central command medal box" - desc = "A locked box used to store ALL the medals you could ever need." - max_combined_w_class = 30 - storage_slots = 15 - req_access = list(ACCESS_CENT_COMMANDER) - -/obj/item/storage/lockbox/medal/cc/populate_contents() - new /obj/item/clothing/accessory/medal/gold/heroism(src) - ..() - new /obj/item/clothing/accessory/medal/gold(src) - new /obj/item/clothing/accessory/medal/silver(src) - new /obj/item/clothing/accessory/medal(src) - - // Departmental medals - new /obj/item/clothing/accessory/medal/security(src) - new /obj/item/clothing/accessory/medal/science(src) - new /obj/item/clothing/accessory/medal/engineering(src) - new /obj/item/clothing/accessory/medal/service(src) - new /obj/item/clothing/accessory/medal/medical(src) - new /obj/item/clothing/accessory/medal/legal(src) - new /obj/item/clothing/accessory/medal/supply(src) - -/obj/item/storage/lockbox/medal/hardmode_box - name = "\improper HRD-MDE program medal box" - desc = "A locked box used to store medals of pride. Use a fauna research disk on the box to transmit the data and print a medal." - req_access = list(ACCESS_MINING) //No grubby assistant hands on my hard earned medals - can_hold = list(/obj/item/clothing/accessory, /obj/item/coin) //Whoops almost gave miners boxes that could store 12 legion cores. Scoped to accessory if they want to store neclaces or hope or something in there. Or a coin collection. - var/list/completed_fauna = list() - var/number_of_megafauna = 7 //Increase this if new megafauna are added. - -/obj/item/storage/lockbox/medal/hardmode_box/Initialize(mapload) - . = ..() - number_of_megafauna = length(subtypesof(/obj/item/disk/fauna_research)) - -/obj/item/storage/lockbox/medal/hardmode_box/populate_contents() - return - -/obj/item/storage/lockbox/medal/hardmode_box/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(istype(W, /obj/item/disk/fauna_research)) - var/obj/item/disk/fauna_research/disky = W - var/obj/item/pride = new disky.output(get_turf(src)) - to_chat(user, "[src] accepts [disky], and prints out [pride]!") - qdel(disky) - if(!is_type_in_list(pride, completed_fauna)) - completed_fauna += pride.type - if(length(completed_fauna) == number_of_megafauna) - to_chat(user, "[src] prints out a very fancy medal!") - var/obj/item/accomplishment = new /obj/item/clothing/accessory/medal/gold/heroism/hardmode_full(get_turf(src)) - user.put_in_hands(accomplishment) - user.put_in_hands(pride) - return - return ..() - -/obj/item/storage/lockbox/t4 - name = "lockbox (T4)" - desc = "Contains three T4 breaching charges." - req_access = list(ACCESS_CENT_SPECOPS) - -/obj/item/storage/lockbox/t4/populate_contents() - for(var/i in 0 to 2) - new /obj/item/grenade/plastic/c4/thermite(src) - -/obj/item/storage/lockbox/research - -/obj/item/storage/lockbox/research/deconstruct(disassembled = TRUE) // Get wrecked, Science nerds - qdel(src) - -/obj/item/storage/lockbox/research/modsuit - name = "Plating lockbox" - desc = "A larger lockbox. Looks a bit less secure than other lockboxes." - -/obj/item/storage/lockbox/research/modsuit/emp_act(severity) //I want emp to get around it, it's not a gun, I just want people not to always make sec / med modsuits. - . = ..() - if(prob(50 / severity)) - locked = FALSE - icon_state = icon_broken - origin_tech = null //wipe out any origin tech if it's unlocked in any way so you can't double-dip tech levels at R&D. - -/obj/item/storage/lockbox/experimental_weapon - name = "A-113 classified lockbox" - desc = "Contains a classifed item for experimental purposes. Looks like some acid was spilt on it." - req_access = list(ACCESS_SEC_DOORS) //officers, heads - -/obj/item/storage/lockbox/experimental_weapon/populate_contents() - if(prob(10)) - new /obj/item/clothing/mask/facehugger(src) //Suprise! Storing facehuggers improperly is what lead to this mess. - return - var/spawn_type = pick(/obj/item/gun/energy/kinetic_accelerator/experimental, /obj/item/surveillance_upgrade, /obj/item/mod/module/stealth/ninja) - if(prob(25)) - if(rand(1, 6) == 1) //organ time. I want this to be more balanced in distribution, so organs are under a prob 25 - new /obj/item/organ/internal/alien/plasmavessel/drone(src) //Disected drone before the place got wiped. No hivenode. - new /obj/item/organ/internal/alien/acidgland(src) - new /obj/item/organ/internal/alien/resinspinner(src) - return - var/list/organ_loot = list( - /obj/item/organ/internal/cyberimp/arm/katana, - /obj/item/organ/internal/cyberimp/arm/toolset_abductor, - /obj/item/organ/internal/cyberimp/arm/esword, - /obj/item/organ/internal/heart/demon/pulse, - /obj/item/organ/internal/eyes/cybernetic/eyesofgod - ) - - spawn_type = pick(organ_loot) - new spawn_type(src) diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm deleted file mode 100644 index 0656ef5e203b3..0000000000000 --- a/code/game/objects/items/weapons/storage/secure.dm +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Absorbs /obj/item/secstorage. - * Reimplements it only slightly to use existing storage functionality. - * - * Contains: - * Secure Briefcase - * Wall Safe - */ - -// ----------------------------- -// Generic Item -// ----------------------------- -/obj/item/storage/secure - name = "secstorage" - w_class = WEIGHT_CLASS_NORMAL - max_w_class = WEIGHT_CLASS_SMALL - max_combined_w_class = 14 - var/icon_locking = "secureb" - var/icon_sparking = "securespark" - var/icon_opened = "secure0" - - /// Are we locked? - var/locked = TRUE - /// What is our code to open? - var/code - /// Is our hacking panel open? - var/panel_open = FALSE - /// What has the user entered to guess the code - var/user_entered_code - /// Stops people from spamming enter like an idiot - COOLDOWN_DECLARE(enter_spam) - -/obj/item/storage/secure/examine(mob/user) - . = ..() - if(in_range(user, src)) - . += "The service panel is [panel_open ? "open" : "closed"]." - -/obj/item/storage/secure/populate_contents() - new /obj/item/paper(src) - new /obj/item/pen(src) - -/obj/item/storage/secure/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) - if(locked) - if((istype(W, /obj/item/melee/energy/blade)) && (!emagged)) - emag_act(user, W) - - //At this point you have exhausted all the special things to do when locked - // ... but it's still locked. - return - - return ..() - -/obj/item/storage/secure/screwdriver_act(mob/living/user, obj/item/I) - if(I.use_tool(src, user, 2 SECONDS * I.toolspeed, volume = 10)) - panel_open = !panel_open - user.visible_message("[user] [panel_open ? "opens" : "closes"] the service panel on [src].", "You [panel_open ? "open" : "close"] the service panel.") - return TRUE - -/obj/item/storage/secure/multitool_act(mob/living/user, obj/item/I) - if(!panel_open) - return - if(!I.use_tool(src, user, 0, volume = 0)) - return - . = TRUE - to_chat(user, "You start fiddling with the internal memory mechanisms.") - if(do_after_once(user, 10 SECONDS * I.toolspeed, target = src)) - if(prob(40)) - to_chat(user, "The screen dims, the internal memory seems to be reset.") - code = null - else - to_chat(user, "The screen flashes, and then goes back to normal.") - - -/obj/item/storage/secure/emag_act(user, weapon) - if(!emagged) - emagged = TRUE - flick_overlay_view(image(icon, src, icon_sparking), src, 0.9 SECONDS) - locked = FALSE - update_icon(UPDATE_OVERLAYS) - if(istype(weapon, /obj/item/melee/energy/blade)) - do_sparks(5, 0, loc) - playsound(loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - to_chat(user, "You slice through the lock on [src].") - else - to_chat(user, "You short out the lock on [src].") - return TRUE - -/obj/item/storage/secure/AltClick(mob/user) - if(!try_to_open()) - return FALSE - return ..() - -/obj/item/storage/secure/MouseDrop(over_object, src_location, over_location) - if(!try_to_open()) - return FALSE - return ..() - -/obj/item/storage/secure/proc/try_to_open() - if(locked) - add_fingerprint(usr) - to_chat(usr, "It's locked!") - return FALSE - return TRUE - - -/obj/item/storage/secure/can_be_inserted(obj/item/W as obj, stop_messages = 0) - if(!locked) - return ..() - if(!stop_messages) - to_chat(usr, "[src] is locked!") - return FALSE - -/obj/item/storage/secure/update_overlays() - . = ..() - if(isnull(code)) - return - if(locked) - . += icon_locking - else - . += icon_opened - -/obj/item/storage/secure/hear_talk(mob/living/M as mob, list/message_pieces) - return - -/obj/item/storage/secure/hear_message(mob/living/M as mob, msg) - return - -/obj/item/storage/secure/attack_self__legacy__attackchain(mob/user) - ui_interact(user) - -/obj/item/storage/secure/ui_state(mob/user) - return GLOB.default_state - -/obj/item/storage/secure/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "SecureStorage", name) - ui.open() - -/obj/item/storage/secure/ui_data(mob/user) - var/list/data = list() - data["locked"] = locked - data["user_entered_code"] = user_entered_code - data["no_passcode"] = isnull(code) - data["emagged"] = emagged - return data - -/obj/item/storage/secure/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - if(..()) - return - - add_fingerprint(usr) - - if(!COOLDOWN_FINISHED(src, enter_spam)) - return - - . = TRUE - - switch(action) - if("keypad") - if(emagged) - return FALSE - - var/digit = params["digit"] - switch(digit) - if("E") - if(isnull(code)) - if(length(user_entered_code) != 5) - return FALSE - code = user_entered_code - to_chat(ui.user, "You set the code to [code].") - locked = FALSE - else if(!locked) - locked = TRUE - to_chat(ui.user, "You lock [src].") - else if(user_entered_code == code) // correct code! - locked = FALSE - to_chat(ui.user, "You unlock [src].") - update_icon(UPDATE_OVERLAYS) - COOLDOWN_START(src, enter_spam, 0.1 SECONDS) - if("C") - user_entered_code = null - COOLDOWN_START(src, enter_spam, 0.1 SECONDS) - else - if(!isnum(text2num(digit))) - return FALSE - if(length(user_entered_code) >= 5) - return FALSE - user_entered_code = copytext("[user_entered_code][digit]", 1, 6) - - if("backspace") - if(emagged) - return FALSE - user_entered_code = copytext(user_entered_code, 1, length(user_entered_code)) - COOLDOWN_START(src, enter_spam, 0.1 SECONDS) - - playsound(src, "terminal_type", 10, 1) - -// ----------------------------- -// Secure Briefcase -// ----------------------------- -/obj/item/storage/secure/briefcase - name = "secure briefcase" - desc = "A large briefcase with a digital locking system." - icon = 'icons/obj/storage.dmi' - icon_state = "secure" - item_state = "sec-case" - flags = CONDUCT - hitsound = "swing_hit" - use_sound = 'sound/effects/briefcase.ogg' - force = 8 - throw_speed = 2 - throw_range = 4 - w_class = WEIGHT_CLASS_BULKY - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = 21 - attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") - -/obj/item/storage/secure/briefcase/attack_hand(mob/user as mob) - if(loc == user && locked) - to_chat(usr, "[src] is locked and cannot be opened!") - else if((loc == user) && !locked) - playsound(loc, 'sound/effects/briefcase.ogg', 50, TRUE, -5) - if(user.s_active) - user.s_active.close(user) //Close and re-open - show_to(user) - else - ..() - for(var/mob/M in range(1)) - if(M.s_active == src) - close(M) - orient2hud(user) - add_fingerprint(user) - return - -//Syndie variant of Secure Briefcase. Contains space cash, slightly more robust. -/obj/item/storage/secure/briefcase/syndie - force = 15 - -/obj/item/storage/secure/briefcase/syndie/populate_contents() - ..() - for(var/I in 1 to 3) - new /obj/item/stack/spacecash/c200(src) - -// ----------------------------- -// Secure Safe -// ----------------------------- - -/obj/item/storage/secure/safe - name = "secure safe" - icon = 'icons/obj/storage.dmi' - icon_state = "safe" - icon_opened = "safe0" - icon_locking = null - icon_sparking = "safespark" - force = 8 - w_class = WEIGHT_CLASS_HUGE - max_w_class = 8 - anchored = TRUE - density = FALSE - cant_hold = list(/obj/item/storage/secure/briefcase) - -/obj/item/storage/secure/safe/attack_hand(mob/user as mob) - ui_interact(user) diff --git a/code/game/objects/items/weapons/storage/storage_base.dm b/code/game/objects/items/weapons/storage/storage_base.dm deleted file mode 100644 index d016b95fbcfc4..0000000000000 --- a/code/game/objects/items/weapons/storage/storage_base.dm +++ /dev/null @@ -1,776 +0,0 @@ -// To clarify: -// For use_to_pickup and allow_quick_gather functionality, -// see item/attackby() (/game/objects/items.dm, params) -// Do not remove this functionality without good reason, cough reagent_containers cough. -// -Sayu - - -/obj/item/storage - name = "storage" - icon = 'icons/obj/storage.dmi' - w_class = WEIGHT_CLASS_NORMAL - flags_2 = BLOCKS_LIGHT_2 - /// No message on putting items in. - var/silent = FALSE - /// List of objects which this item can store (if set, it can't store anything else) - var/list/can_hold = list() - /// List of objects that can be stored, regardless of w_class - var/list/w_class_override = list() - /// List of objects which this item can't store (in effect only if can_hold isn't set) - var/list/cant_hold = list() - /// List of objects which this item overrides the cant_hold list (used to negate cant_hold on specific items. Ex: Allowing Smuggler's Satchels (subtype of backpack) to be stored inside bags of holding.) - var/list/cant_hold_override = list() - /// Max size of objects that this object can store (in effect only if can_hold isn't set) - var/max_w_class = WEIGHT_CLASS_SMALL - /// The sum of the w_classes of all the items in this storage item. - var/max_combined_w_class = 14 - /// The number of storage slots in this container. - var/storage_slots = 7 - var/atom/movable/screen/storage/boxes = null - var/atom/movable/screen/close/closer = null - - /// Set this to make it possible to use this item in an inverse way, so you can have the item in your hand and click items on the floor to pick them up. - var/use_to_pickup = FALSE - /// Set this to make the storage item group contents of the same type and display them as a number. - var/display_contents_with_number - /// Set this variable to allow the object to have the 'empty' verb, which dumps all the contents on the floor. - var/allow_quick_empty - /// Set this variable to allow the object to have the 'toggle mode' verb, which quickly collects all items from a tile. - var/allow_quick_gather - /// Pick up one item at a time or everything on the tile - var/pickup_all_on_tile = TRUE - /// Sound played when used. `null` for no sound. - var/use_sound = "rustle" - /// What kind of [/obj/item/stack] can this be folded into. (e.g. Boxes and cardboard) - var/foldable = null - /// How much of the stack item do you get. - var/foldable_amt = 0 - - /// Lazy list of mobs which are currently viewing the storage inventory. - var/list/mobs_viewing - - // Allow storage items of the same size to be put inside - var/allow_same_size = FALSE - -/obj/item/storage/Initialize(mapload) - . = ..() - can_hold = typecacheof(can_hold) - cant_hold = typecacheof(cant_hold) - typecacheof(cant_hold_override) - - populate_contents() - - boxes = new /atom/movable/screen/storage() - boxes.name = "storage" - boxes.master = src - boxes.icon_state = "block" - boxes.screen_loc = "7,7 to 10,8" - boxes.layer = HUD_LAYER - boxes.plane = HUD_PLANE - closer = new /atom/movable/screen/close() - closer.master = src - closer.icon_state = "backpack_close" - closer.layer = ABOVE_HUD_LAYER - closer.plane = ABOVE_HUD_PLANE - orient2hud() - - ADD_TRAIT(src, TRAIT_ADJACENCY_TRANSPARENT, ROUNDSTART_TRAIT) - RegisterSignal(src, COMSIG_ATOM_EXITED, PROC_REF(on_atom_exited)) - -/obj/item/storage/Destroy() - for(var/obj/O in contents) - O.mouse_opacity = initial(O.mouse_opacity) - - QDEL_NULL(boxes) - QDEL_NULL(closer) - LAZYCLEARLIST(mobs_viewing) - return ..() - -/obj/item/storage/examine(mob/user) - . = ..() - if(allow_quick_empty) - . += "You can use [src] in hand to empty it's entire contents." - if(allow_quick_gather) - . += "You can Alt-Shift-Click [src] to switch it's gathering method." - -/obj/item/storage/forceMove(atom/destination) - . = ..() - if(!ismob(destination.loc)) - for(var/mob/player in mobs_viewing) - if(player == destination) - continue - hide_from(player) - -/obj/item/storage/proc/removal_allowed_check(mob/user) - return TRUE - -/obj/item/storage/MouseDrop(obj/over_object, src_location, over_location, src_control, over_control, params) - if(!ismob(usr)) //so monkeys can take off their backpacks -- Urist - return - var/mob/M = usr - - if(ismecha(M.loc) || M.incapacitated(FALSE, TRUE)) // Stops inventory actions in a mech as well as while being incapacitated - return - - if(over_object == M && Adjacent(M)) // this must come before the screen objects only block - if(M.s_active) - M.s_active.close(M) - open(M) - return - - if((istype(over_object, /obj/structure/table) || isfloorturf(over_object)) && length(contents) \ - && loc == M && !M.stat && !M.restrained() && !HAS_TRAIT(M, TRAIT_HANDS_BLOCKED) && over_object.Adjacent(M) && !istype(src, /obj/item/storage/lockbox)) // Worlds longest `if()` - var/turf/T = get_turf(over_object) - if(!removal_allowed_check(M)) - return - - if(isfloorturf(over_object)) - if(get_turf(M) != T) - return // Can only empty containers onto the floor under you - if(tgui_alert(M, "Empty [src] onto [T]?", "Confirm", list("Yes", "No")) != "Yes") - return - if(!(M && over_object && length(contents) && loc == M && !M.stat && !M.restrained() && !HAS_TRAIT(M, TRAIT_HANDS_BLOCKED) && get_turf(M) == T)) - return // Something happened while the player was thinking - hide_from(M) - M.face_atom(over_object) - M.visible_message("[M] empties [src] onto [over_object].", - "You empty [src] onto [over_object].") - var/list/params_list = params2list(params) - var/x_offset = text2num(params_list["icon-x"]) - 16 - var/y_offset = text2num(params_list["icon-y"]) - 16 - for(var/obj/item/I in contents) - remove_from_storage(I, T) - I.scatter_atom(x_offset, y_offset) - update_icon() // For content-sensitive icons - return - - if(!is_screen_atom(over_object)) - return ..() - if(!(loc == M) || (loc && loc.loc == M)) - return - if(!M.restrained() && !M.stat) - switch(over_object.name) - if("r_hand") - if(!M.unequip(src)) - return - M.put_in_r_hand(src) - if("l_hand") - if(!M.unequip(src)) - return - M.put_in_l_hand(src) - add_fingerprint(usr) - return - if(over_object == usr && in_range(src, usr) || usr.contents.Find(src)) - if(usr.s_active) - usr.s_active.close(usr) - open(usr) - -/obj/item/storage/AltClick(mob/user) - if(ishuman(user) && Adjacent(user) && !user.incapacitated(FALSE, TRUE)) - open(user) - add_fingerprint(user) - else if(isobserver(user)) - show_to(user) - -/** - * Loops through any nested containers inside `src`, and returns a list of everything inside them. - * - * Currently checks for storage containers, gifts containing storage containers, and folders. - */ -/obj/item/storage/proc/return_inv() - var/list/L = list() - L += contents // Inventory of the main storage item - - for(var/obj/item/storage/S in src) // Inventory of nested storage items - L += S.return_inv() - for(var/obj/item/gift/G in src) - L += G.gift - if(isstorage(G.gift)) // If the gift contains a storage item - var/obj/item/storage/S = G.gift - L += S.return_inv() - for(var/obj/item/folder/F in src) - L += F.contents - return L - -/** - * Shows `user` the contents of `src`, and activates any mouse trap style triggers. - */ -/obj/item/storage/proc/show_to(mob/user) - if(!user.client) - return - if(user.s_active != src && !isobserver(user)) - for(var/obj/item/I in src) - if(I.on_found(user)) // For mouse traps and such - return // If something triggered, don't open the UI - orient2hud(user) // this only needs to happen to make .contents show properly as screen objects. - if(user.s_active) - user.s_active.hide_from(user) // If there's already an interface open, close it. - user.client.screen |= boxes - user.client.screen |= closer - user.client.screen |= contents - user.s_active = src - LAZYDISTINCTADD(mobs_viewing, user) - -/** - * Hides the current container interface from `user`. - */ -/obj/item/storage/proc/hide_from(mob/user) - LAZYREMOVE(mobs_viewing, user) // Remove clientless mobs too - if(!user.client) - return - user.client.screen -= boxes - user.client.screen -= closer - user.client.screen -= contents - if(user.s_active == src) - user.s_active = null - -/** - * Hides the current container interface from all viewers. - */ -/obj/item/storage/proc/hide_from_all() - for(var/mob/M in mobs_viewing) - hide_from(M) - -/** - * Checks all mobs currently viewing the storage inventory, and hides it if they shouldn't be able to see it. - */ -/obj/item/storage/proc/update_viewers() - for(var/_M in mobs_viewing) - var/mob/M = _M - if(!QDELETED(M) && M.s_active == src && Adjacent(M)) - continue - hide_from(M) - for(var/obj/item/storage/child in src) - child.update_viewers() - -/obj/item/storage/Moved(atom/oldloc, dir, forced = FALSE) - . = ..() - update_viewers() - -/obj/item/storage/proc/open(mob/user) - if(isobserver(user)) - show_to(user) - return - if(use_sound && isliving(user)) - playsound(loc, use_sound, 50, TRUE, -5) - - if(user.s_active) - user.s_active.close(user) - show_to(user) - -/obj/item/storage/proc/close(mob/user) - hide_from(user) - user.s_active = null - -/** - * Draws the inventory and places the items on it using custom positions. - * - * `tx` and `ty` are the upper left tile. - * `mx` and `my` are the bottom right tile. - * - * The numbers are calculated from the bottom left, with the bottom left being `1,1`. - */ -/obj/item/storage/proc/orient_objs(tx, ty, mx, my) - var/cx = tx - var/cy = ty - boxes.screen_loc = "[tx],[ty] to [mx],[my]" - for(var/obj/O in contents) - O.screen_loc = "[cx],[cy]" - O.layer = ABOVE_HUD_LAYER - O.plane = ABOVE_HUD_PLANE - cx++ - if(cx > mx) - cx = tx - cy-- - closer.screen_loc = "[mx + 1],[my]" - -//This proc draws out the inventory and places the items on it. It uses the standard position. -/obj/item/storage/proc/standard_orient_objs(rows, cols, list/datum/numbered_display/display_contents) - var/cx = 4 - var/cy = 2 + rows - boxes.screen_loc = "4:16,2:16 to [4 + cols]:16,[2 + rows]:16" - - if(display_contents_with_number) - for(var/datum/numbered_display/ND in display_contents) - ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE - ND.sample_object.screen_loc = "[cx]:16,[cy]:16" - ND.sample_object.maptext = "[(ND.number > 1) ? "[ND.number]" : ""]" - ND.sample_object.layer = ABOVE_HUD_LAYER - ND.sample_object.plane = ABOVE_HUD_PLANE - cx++ - if(cx > (4 + cols)) - cx = 4 - cy-- - else - for(var/obj/O in contents) - O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip" - O.screen_loc = "[cx]:16,[cy]:16" - O.maptext = "" - O.layer = ABOVE_HUD_LAYER - O.plane = ABOVE_HUD_PLANE - cx++ - if(cx > (4 + cols)) - cx = 4 - cy-- - closer.screen_loc = "[4 + cols + 1]:16,2:16" - -/datum/numbered_display - var/obj/item/sample_object - var/number - -/datum/numbered_display/New(obj/item/sample) - if(!istype(sample)) - qdel(src) - return - sample_object = sample - number = 1 - -//This proc determins the size of the inventory to be displayed. Please touch it only if you know what you're doing. -/obj/item/storage/proc/orient2hud(mob/user) - var/adjusted_contents = length(contents) - - //Numbered contents display - var/list/datum/numbered_display/numbered_contents - if(display_contents_with_number) - for(var/obj/O in contents) - O.layer = initial(O.layer) - O.plane = initial(O.plane) - - numbered_contents = list() - adjusted_contents = 0 - for(var/obj/item/I in contents) - var/found = FALSE - for(var/datum/numbered_display/ND in numbered_contents) - if(ND.sample_object.should_stack_with(I)) - ND.number++ - found = TRUE - break - if(!found) - adjusted_contents++ - numbered_contents += new/datum/numbered_display(I) - - var/row_num = 0 - var/col_count = min(7, storage_slots) - 1 - if(adjusted_contents > 7) - row_num = round((adjusted_contents - 1) / 7) // 7 is the maximum allowed width. - standard_orient_objs(row_num, col_count, numbered_contents) - -/** - * Checks whether `I` can be inserted into the container. - * - * Returns `TRUE` if it can, and `FALSE` if it can't. - * Arguments: - * * obj/item/I - The item to insert - * * stop_messages - Don't display a warning message if the item can't be inserted - */ -/obj/item/storage/proc/can_be_inserted(obj/item/I, stop_messages = FALSE) - if(!istype(I) || (I.flags & ABSTRACT)) // Not an item - return - - if(loc == I) - return FALSE //Means the item is already in the storage item - - if(!I.can_enter_storage(src, usr)) - return FALSE - - if(length(contents) >= storage_slots) - if(!stop_messages) - to_chat(usr, "[I] won't fit in [src], make some space!") - return FALSE //Storage item is full - - if(length(can_hold)) - if(!is_type_in_typecache(I, can_hold)) - if(!stop_messages) - to_chat(usr, "[src] cannot hold [I].") - return FALSE - - if(is_type_in_typecache(I, cant_hold)) //Check for specific items which this container can't hold. - if(!stop_messages) - to_chat(usr, "[src] cannot hold [I].") - return FALSE - - if(length(cant_hold) && isstorage(I)) //Checks nested storage contents for restricted objects, we don't want people sneaking the NAD in via boxes now, do we? - var/obj/item/storage/S = I - for(var/obj/A in S.return_inv()) - if(is_type_in_typecache(A, cant_hold)) - if(!stop_messages) - to_chat(usr, "[src] rejects [I] because of its contents.") - return FALSE - - if(I.w_class > max_w_class) - if(length(w_class_override)) - if(is_type_in_list(I, w_class_override)) - return TRUE - else - if(!stop_messages) - to_chat(usr, "[I] is too big for [src].") - return FALSE - else - if(!stop_messages) - to_chat(usr, "[I] is too big for [src].") - return FALSE - - var/sum_w_class = I.w_class - for(var/obj/item/item in contents) - sum_w_class += item.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it. - - if(sum_w_class > max_combined_w_class) - if(!stop_messages) - to_chat(usr, "[src] is full, make some space.") - return FALSE - - if(I.w_class >= w_class && isstorage(I)) - if(!allow_same_size) //BoHs should be able to hold backpacks again. The override for putting a BoH in a BoH is in backpack.dm. - if(!stop_messages) - to_chat(usr, "[src] cannot hold [I] as it's a storage item of the same size.") - return FALSE //To prevent the stacking of same sized storage items. - - if(I.flags & NODROP) //SHOULD be handled in unEquip, but better safe than sorry. - to_chat(usr, "[I] is stuck to your hand, you can't put it in [src]") - return FALSE - - return TRUE - -/** - * Handles items being inserted into a storage container. - * - * This doesn't perform any checks of whether an item can be inserted. That's done by [/obj/item/storage/proc/can_be_inserted] - * Arguments: - * * obj/item/I - The item to be inserted - * * mob/user - The mob performing the insertion - * * prevent_warning - Stop the insertion message being displayed. Intended for cases when you are inserting multiple items at once. - */ -/obj/item/storage/proc/handle_item_insertion(obj/item/I, mob/user, prevent_warning = FALSE) - if(!istype(I)) - return FALSE - if(user) - if(!Adjacent(user) && !isnewplayer(user)) - return FALSE - if(!user.unequip(I)) - return FALSE - user.update_icons() //update our overlays - if(QDELING(I)) - return FALSE - if(silent || HAS_TRAIT(I, TRAIT_SILENT_INSERTION)) - prevent_warning = TRUE - I.forceMove(src) - if(QDELING(I)) - return FALSE - I.on_enter_storage(src) - - for(var/_M in mobs_viewing) - var/mob/M = _M - if((M.s_active == src) && M.client) - M.client.screen += I - if(user) - if(user.client && user.s_active != src) - user.client.screen -= I - if(length(user.observers)) - for(var/mob/observer in user.observers) - if(observer.client && observer.s_active != src) - observer.client.screen -= I - I.dropped(user, TRUE) - if(user) - add_fingerprint(user) - - if(!prevent_warning) - // the item's user will always get a notification - to_chat(user, "You put [I] into [src].") - - // if the item less than normal sized, only people within 1 tile get the message, otherwise, everybody in view gets it - if(I.w_class < WEIGHT_CLASS_NORMAL) - for(var/mob/M in orange(1, user)) - if(in_range(M, user)) - M.show_message("[user] puts [I] into [src].") - else - // restrict player list to include only those in view - for(var/mob/M in oviewers(7, user)) - M.show_message("[user] puts [I] into [src].") - orient2hud(user) - if(user) - if(user.s_active) - user.s_active.show_to(user) - - 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 - I.in_inventory = TRUE - update_icon() - return TRUE - -/obj/item/storage/proc/on_atom_exited(datum/source, atom/exited, direction) - return remove_from_storage(exited, exited.loc) - -/** - * Handles the removal of an item from a storage container. - * - * Arguments: - * * obj/item/I - The item to be removed - * * atom/new_location - The location to send the item to. - */ -/obj/item/storage/proc/remove_from_storage(obj/item/I, atom/new_location) - if(!istype(I)) - return FALSE - - for(var/_M in mobs_viewing) - var/mob/M = _M - if((M.s_active == src) && M.client) - M.client.screen -= I - - if(new_location) - if(ismob(loc)) - I.dropped(usr, TRUE) - if(ismob(new_location)) - I.layer = ABOVE_HUD_LAYER - I.plane = ABOVE_HUD_PLANE - else - I.layer = initial(I.layer) - I.plane = initial(I.plane) - I.forceMove(new_location) - else - I.forceMove(get_turf(src)) - - if(usr) - orient2hud(usr) - if(usr.s_active) - usr.s_active.show_to(usr) - if(I.maptext) - I.maptext = "" - I.on_exit_storage(src) - I.mouse_opacity = initial(I.mouse_opacity) - update_icon() - return TRUE - -/obj/item/storage/deconstruct(disassembled = TRUE) - var/drop_loc = loc - if(ismob(loc)) - drop_loc = get_turf(src) - for(var/obj/item/I in contents) - remove_from_storage(I, drop_loc) - qdel(src) - -//This proc is called when you want to place an item into the storage item. -/obj/item/storage/attackby__legacy__attackchain(obj/item/I, mob/user, params) - ..() - if(istype(I, /obj/item/hand_labeler)) - var/obj/item/hand_labeler/labeler = I - if(labeler.mode) - return FALSE - if(user.a_intent != INTENT_HELP && issimulatedturf(loc)) // Stops you from putting your baton in the storage on accident - return FALSE - . = TRUE //no afterattack - if(isrobot(user)) - return //Robots can't interact with storage items. - - if(!can_be_inserted(I)) - if(length(contents) >= storage_slots) //don't use items on the backpack if they don't fit - return TRUE - return FALSE - - handle_item_insertion(I, user) - -/obj/item/storage/attack_hand(mob/user) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(!H.get_active_hand()) - if(H.l_store == src) //Prevents opening if it's in a pocket. - H.put_in_hands(src) - H.l_store = null - return - if(H.r_store == src) - H.put_in_hands(src) - H.r_store = null - return - - orient2hud(user) - if(loc == user) - if(user.s_active) - user.s_active.close(user) - open(user) - else - ..() - add_fingerprint(user) - -/obj/item/storage/equipped(mob/user, slot, initial) - . = ..() - update_viewers() - -/obj/item/storage/attack_ghost(mob/user) - if(isobserver(user)) - // Revenants don't get to play with the toys. - show_to(user) - return ..() - -/obj/item/storage/AltShiftClick(mob/living/carbon/human/user) - - pickup_all_on_tile = !pickup_all_on_tile - switch(pickup_all_on_tile) - if(TRUE) - to_chat(usr, "[src] now picks up all items in a tile at once.") - if(FALSE) - to_chat(usr, "[src] now picks up one item at a time.") - -/obj/item/storage/proc/drop_inventory(user) - var/turf/T = get_turf(src) - hide_from(user) - for(var/obj/item/I in contents) - remove_from_storage(I, T) - I.scatter_atom() - CHECK_TICK - -/** - * Populates the container with items - * - * Override with whatever you want to put in the container - */ -/obj/item/storage/proc/populate_contents() - return // Override - -/obj/item/storage/emp_act(severity) - ..() - for(var/I in contents) - var/atom/A = I - A.emp_act(severity) - -/obj/item/storage/hear_talk(mob/living/M, list/message_pieces) - ..() - for(var/obj/O in contents) - O.hear_talk(M, message_pieces) - -/obj/item/storage/hear_message(mob/living/M, msg) - ..() - for(var/obj/O in contents) - O.hear_message(M, msg) - -/obj/item/storage/attack_self__legacy__attackchain(mob/user) - //Clicking on itself will empty it, if allow_quick_empty is TRUE - if(allow_quick_empty && user.is_in_active_hand(src)) - drop_inventory(user) - - else if(foldable) - fold(user) - -/obj/item/storage/proc/fold(mob/user) - if(length(contents)) - to_chat(user, "You can't fold this [name] with items still inside!") - return - if(!ispath(foldable)) - return - - var/found = FALSE - for(var/mob/M in range(1)) - if(M.s_active == src) // Close any open UI windows first - close(M) - if(M == user) - found = TRUE - if(!found) // User is too far away - return - - to_chat(user, "You fold [src] flat.") - var/obj/item/stack/I = new foldable(get_turf(src), foldable_amt) - user.put_in_hands(I) - qdel(src) - -/** - * Returns the storage depth of an atom up to the area level. - * - * The storage depth is the number of storage items the atom is contained in. - * Returns `-1` if the atom was not found in a container. - */ -/atom/proc/storage_depth(atom/container) - var/depth = 0 - var/atom/cur_atom = src - - while(cur_atom && !(cur_atom in container.contents)) - if(isarea(cur_atom)) - return -1 - if(isstorage(cur_atom.loc)) - depth++ - cur_atom = cur_atom.loc - - if(!cur_atom) - return -1 //inside something with a null loc. - - return depth - -/** - * Like [/atom/proc/storage_depth], but returns the depth to the nearest turf. - * - * Returns `-1` if there's no top level turf. (A loc was null somewhere, or a non-turf atom's loc was an area somehow.) - */ -/atom/proc/storage_depth_turf() - var/depth = 0 - var/atom/cur_atom = src - - while(cur_atom && !isturf(cur_atom)) - if(isarea(cur_atom)) - return -1 - if(isstorage(cur_atom.loc)) - depth++ - cur_atom = cur_atom.loc - - if(!cur_atom) - return -1 //inside something with a null loc. - - return depth - -/obj/item/storage/serialize() - var/data = ..() - var/list/content_list = list() - data["content"] = content_list - data["slots"] = storage_slots - data["max_w_class"] = max_w_class - data["max_c_w_class"] = max_combined_w_class - for(var/thing in contents) - var/atom/movable/AM = thing - // This code does not watch out for infinite loops - // But then again a tesseract would destroy the server anyways - // Also I wish I could just insert a list instead of it reading it the wrong way - content_list.len++ - content_list[length(content_list)] = AM.serialize() - return data - -/obj/item/storage/deserialize(list/data) - if(isnum(data["slots"])) - storage_slots = data["slots"] - if(isnum(data["max_w_class"])) - max_w_class = data["max_w_class"] - if(isnum(data["max_c_w_class"])) - max_combined_w_class = data["max_c_w_class"] - for(var/thing in contents) - qdel(thing) // out with the old - for(var/thing in data["content"]) - if(islist(thing)) - list_to_object(thing, src) - else if(thing == null) - stack_trace("Null entry found in storage/deserialize.") - else - stack_trace("Non-list thing found in storage/deserialize (Thing: [thing])") - ..() - -/obj/item/storage/AllowDrop() - return TRUE - -/obj/item/storage/ex_act(severity) - for(var/atom/A in contents) - A.ex_act(severity) - CHECK_TICK - ..() - -/obj/item/storage/proc/can_items_stack(obj/item/item_1, obj/item/item_2) - if(!item_1 || !item_2) - return - - return item_1.type == item_2.type && item_1.name == item_2.name - -/obj/item/storage/proc/swap_items(obj/item/item_1, obj/item/item_2, mob/user = null) - if(!(item_1.loc == src && item_2.loc == src)) - return - - var/index_1 = contents.Find(item_1) - var/index_2 = contents.Find(item_2) - - var/list/new_contents = contents.Copy() - new_contents.Swap(index_1, index_2) - contents = new_contents - - if(user && user.s_active == src) - orient2hud(user) - show_to(user) diff --git a/code/game/objects/items/weapons/storage/surgical_tray.dm b/code/game/objects/items/weapons/storage/surgical_tray.dm deleted file mode 100644 index bf346fad5bc07..0000000000000 --- a/code/game/objects/items/weapons/storage/surgical_tray.dm +++ /dev/null @@ -1,43 +0,0 @@ -// Sprites from CM13 -/obj/item/storage/surgical_tray - name = "surgical tray" - desc = "A small metallic tray covered in sterile tarp. Intended to store surgical tools in a neat and clean fashion." - icon_state = "surgical_tray" - storage_slots = 22 // 11 Items, x2 to be sure - w_class = WEIGHT_CLASS_BULKY - max_w_class = WEIGHT_CLASS_GIGANTIC - max_combined_w_class = 38 // Items listed add up to 19, x2 to be sure - can_hold = list( - /obj/item/scalpel, - /obj/item/cautery, - /obj/item/hemostat, - /obj/item/retractor, - /obj/item/fix_o_vein, - /obj/item/surgicaldrill, - /obj/item/circular_saw, - /obj/item/bonegel, - /obj/item/bonesetter, - /obj/item/stack/medical/bruise_pack, - /obj/item/stack/medical/ointment, - /obj/item/surgical_drapes - ) - -/obj/item/storage/surgical_tray/Initialize(mapload) - . = ..() - new /obj/item/scalpel(src) - new /obj/item/cautery(src) - new /obj/item/hemostat(src) - new /obj/item/retractor(src) - new /obj/item/fix_o_vein(src) - new /obj/item/surgicaldrill(src) - new /obj/item/circular_saw(src) - new /obj/item/bonegel(src) - new /obj/item/bonesetter(src) - new /obj/item/stack/medical/bruise_pack/advanced(src) - new /obj/item/stack/medical/ointment/advanced(src) - -/obj/item/storage/surgical_tray/update_icon_state() - if(!length(contents)) - icon_state = "surgical_tray_e" - else - icon_state = "surgical_tray" diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm deleted file mode 100644 index 82d882da36a5a..0000000000000 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ /dev/null @@ -1,158 +0,0 @@ -/obj/item/storage/toolbox - name = "toolbox" - desc = "Danger. Very robust." - icon_state = "toolbox_default" - item_state = "toolbox_default" - lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' - flags = CONDUCT - force = 10 - throwforce = 10 - throw_speed = 2 - throw_range = 7 - w_class = WEIGHT_CLASS_BULKY - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = 18 - materials = list(MAT_METAL = 500) - origin_tech = "combat=1;engineering=1" - attack_verb = list("robusted") - use_sound = 'sound/effects/toolbox.ogg' - hitsound = 'sound/weapons/smash.ogg' - drop_sound = 'sound/items/handling/toolbox_drop.ogg' - pickup_sound = 'sound/items/handling/toolbox_pickup.ogg' - var/latches = "single_latch" - var/has_latches = TRUE - -/obj/item/storage/toolbox/Initialize(mapload) - . = ..() - if(has_latches) - if(prob(10)) - if(prob(1)) - latches = "triple_latch" - else - latches = "double_latch" - update_icon(UPDATE_OVERLAYS) - -/obj/item/storage/toolbox/update_overlays() - . = ..() - if(has_latches) - . += latches - -/obj/item/storage/toolbox/emergency - name = "emergency toolbox" - icon_state = "red" - item_state = "toolbox_red" - -/obj/item/storage/toolbox/emergency/populate_contents() - new /obj/item/crowbar/small(src) - new /obj/item/weldingtool/mini(src) - new /obj/item/extinguisher/mini(src) - if(prob(50)) - new /obj/item/flashlight(src) - else - new /obj/item/flashlight/flare(src) - new /obj/item/radio(src) - -/obj/item/storage/toolbox/emergency/old - name = "rusty red toolbox" - icon_state = "toolbox_red_old" - has_latches = FALSE - -/obj/item/storage/toolbox/mechanical - name = "mechanical toolbox" - icon_state = "blue" - item_state = "toolbox_blue" - -/obj/item/storage/toolbox/mechanical/populate_contents() - new /obj/item/screwdriver(src) - new /obj/item/wrench(src) - new /obj/item/weldingtool(src) - new /obj/item/crowbar(src) - new /obj/item/analyzer(src) - new /obj/item/wirecutters(src) - -/obj/item/storage/toolbox/mechanical/greytide - flags = NODROP - -/obj/item/storage/toolbox/mechanical/old - name = "rusty blue toolbox" - icon_state = "toolbox_blue_old" - has_latches = FALSE - -/obj/item/storage/toolbox/electrical - name = "electrical toolbox" - icon_state = "yellow" - item_state = "toolbox_yellow" - -/obj/item/storage/toolbox/electrical/populate_contents() - var/pickedcolor = pick(COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_BLUE, COLOR_PINK, COLOR_ORANGE, COLOR_CYAN, COLOR_WHITE) - new /obj/item/screwdriver(src) - new /obj/item/wirecutters(src) - new /obj/item/t_scanner(src) - new /obj/item/crowbar(src) - new /obj/item/stack/cable_coil(src, 30, pickedcolor) - new /obj/item/stack/cable_coil(src, 30, pickedcolor) - if(prob(5)) - new /obj/item/clothing/gloves/color/yellow(src) - else - new /obj/item/stack/cable_coil(src, 30, pickedcolor) - -/obj/item/storage/toolbox/syndicate - name = "suspicious looking toolbox" - icon_state = "syndicate" - item_state = "toolbox_syndi" - origin_tech = "combat=2;syndicate=1;engineering=2" - silent = TRUE - force = 15 - throwforce = 18 - -/obj/item/storage/toolbox/syndicate/populate_contents() - new /obj/item/screwdriver/nuke(src) - new /obj/item/wrench(src) - new /obj/item/weldingtool/largetank(src) - new /obj/item/crowbar/small(src) - new /obj/item/wirecutters(src, "red") - new /obj/item/multitool/red(src) - new /obj/item/clothing/gloves/combat(src) - -/obj/item/storage/toolbox/fakesyndi - name = "suspicous looking toolbox" - icon_state = "syndicate" - item_state = "toolbox_syndi" - desc = "Danger. Very Robust. The paint is still wet." - -/obj/item/storage/toolbox/drone - name = "mechanical toolbox" - icon_state = "blue" - item_state = "toolbox_blue" - -/obj/item/storage/toolbox/drone/populate_contents() - var/pickedcolor = pick(pick(COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_BLUE, COLOR_PINK, COLOR_ORANGE, COLOR_CYAN, COLOR_WHITE)) - new /obj/item/screwdriver(src) - new /obj/item/wrench(src) - new /obj/item/weldingtool(src) - new /obj/item/crowbar(src) - new /obj/item/stack/cable_coil(src, 30, pickedcolor) - new /obj/item/wirecutters(src) - new /obj/item/multitool(src) - -/obj/item/storage/toolbox/artistic - name = "artistic toolbox" - desc = "A toolbox painted bright green. Why anyone would store art supplies in a toolbox is beyond you, but it has plenty of extra space." - icon_state = "green" - item_state = "artistic_toolbox" - w_class = WEIGHT_CLASS_GIGANTIC //Holds more than a regular toolbox! - max_combined_w_class = 20 - storage_slots = 10 - -/obj/item/storage/toolbox/artistic/populate_contents() - new /obj/item/storage/fancy/crayons(src) - new /obj/item/crowbar(src) - new /obj/item/stack/cable_coil(src) - new /obj/item/stack/cable_coil/yellow(src) - new /obj/item/stack/cable_coil/blue(src) - new /obj/item/stack/cable_coil/green(src) - new /obj/item/stack/cable_coil/pink(src) - new /obj/item/stack/cable_coil/orange(src) - new /obj/item/stack/cable_coil/cyan(src) - new /obj/item/stack/cable_coil/white(src) diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm deleted file mode 100644 index 09b35a6246dac..0000000000000 --- a/code/game/objects/items/weapons/storage/wallets.dm +++ /dev/null @@ -1,126 +0,0 @@ -/obj/item/storage/wallet - name = "leather wallet" - desc = "Made from genuine leather, it is of the highest quality." - storage_slots = 10 - icon = 'icons/obj/wallets.dmi' - icon_state = "wallet" - w_class = WEIGHT_CLASS_SMALL - resistance_flags = FLAMMABLE - can_hold = list( - /obj/item/stack/spacecash, - /obj/item/card, - /obj/item/clothing/mask/cigarette, - /obj/item/flashlight/pen, - /obj/item/seeds, - /obj/item/stack/medical, - /obj/item/toy/crayon, - /obj/item/coin, - /obj/item/food/candy/chocolate_coin, - /obj/item/food/candy/coin, - /obj/item/food/candy/cash, - /obj/item/food/customizable/candy/coin, - /obj/item/food/customizable/candy/cash, - /obj/item/dice, - /obj/item/disk, - /obj/item/bio_chip_implanter, - /obj/item/lighter, - /obj/item/match, - /obj/item/paper, - /obj/item/pen, - /obj/item/photo, - /obj/item/reagent_containers/dropper, - /obj/item/screwdriver, - /obj/item/stamp) - cant_hold = list( - /obj/item/screwdriver/power - ) - slot_flags = ITEM_SLOT_ID - - var/obj/item/card/id/front_id = null - - // allows for clicking of stuff on our person/on the ground to put in the wallet, so easy to stick your ID in your wallet - use_to_pickup = TRUE - pickup_all_on_tile = FALSE - - -/obj/item/storage/wallet/remove_from_storage(obj/item/I, atom/new_location) - . = ..() - if(. && istype(I, /obj/item/card/id)) - refresh_ID() - -/obj/item/storage/wallet/handle_item_insertion(obj/item/I, mob/user, prevent_warning = FALSE) - . = ..() - if(. && istype(I, /obj/item/card/id)) - refresh_ID() - -/obj/item/storage/wallet/orient2hud(mob/user) - . = ..() - refresh_ID() - -/obj/item/storage/wallet/proc/refresh_ID() - // Locate the first ID in the wallet - front_id = (locate(/obj/item/card/id) in contents) - - if(ishuman(loc)) - var/mob/living/carbon/human/wearing_human = loc - if(wearing_human.wear_id == src) - wearing_human.sec_hud_set_ID() - - update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) - -/obj/item/storage/wallet/update_overlays() - . = ..() - if(!front_id) - return - . += mutable_appearance(front_id.icon, front_id.icon_state) - . += front_id.overlays - . += mutable_appearance(icon, "wallet_overlay") - - // fuck yeah, ass photo in my wallet - var/obj/item/photo/photo = locate(/obj/item/photo) in contents - if(!photo) - return - var/mutable_appearance/MA = mutable_appearance(photo.appearance) - MA.pixel_x = 11 - MA.pixel_y = 1 - . += MA - . += mutable_appearance(icon, "photo_overlay") - -/obj/item/storage/wallet/update_name(updates) - . = ..() - if(front_id) - name = "wallet displaying [front_id]" - else - name = initial(name) - -/obj/item/storage/wallet/GetID() - return front_id - -/obj/item/storage/wallet/GetAccess() - var/obj/item/I = GetID() - if(I) - return I.GetAccess() - else - return ..() - -/obj/item/storage/wallet/random/populate_contents() - var/cash = pick(/obj/item/stack/spacecash, - /obj/item/stack/spacecash/c5, - /obj/item/stack/spacecash/c10, - /obj/item/stack/spacecash/c50, - /obj/item/stack/spacecash/c100) - var/coin = pickweight(list(/obj/item/coin/iron = 3, - /obj/item/coin/silver = 2, - /obj/item/coin/gold = 1)) - - new cash(src) - if(prob(50)) // 50% chance of a second - new cash(src) - new coin(src) - - -// Arcade Wallet -/obj/item/storage/wallet/cheap - name = "cheap wallet" - desc = "A cheap and flimsy wallet from the arcade." - storage_slots = 5 //smaller storage than normal wallets diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm deleted file mode 100644 index e6169752f751f..0000000000000 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ /dev/null @@ -1,223 +0,0 @@ -/* Types of tanks! - * Contains: - * Oxygen - * Anesthetic - * Air - * Plasma - * Emergency Oxygen - * Generic - */ - -/* - * Oxygen - */ -/obj/item/tank/internals/oxygen - name = "oxygen tank" - desc = "A tank of oxygen, this one is blue." - icon_state = "oxygen" - distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE - force = 10 - dog_fashion = /datum/dog_fashion/back - -/obj/item/tank/internals/oxygen/populate_gas() - air_contents.set_oxygen((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) - -/obj/item/tank/internals/oxygen/yellow - desc = "A tank of oxygen, this one is yellow." - icon_state = "oxygen_f" - dog_fashion = null - -/obj/item/tank/internals/oxygen/red - desc = "A tank of oxygen, this one is red." - icon_state = "oxygen_fr" - dog_fashion = null - -/obj/item/tank/internals/oxygen/empty/populate_gas() - return - -/* - * Anesthetic - */ -/obj/item/tank/internals/anesthetic - name = "anesthetic tank" - desc = "A tank with an N2O/O2 gas mix." - icon_state = "anesthetic" - item_state = "an_tank" - force = 10 - -/obj/item/tank/internals/anesthetic/populate_gas() - air_contents.set_oxygen((3 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) * O2STANDARD) - air_contents.set_sleeping_agent((3 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) * N2STANDARD) - -/* - * Plasma - */ -/obj/item/tank/internals/plasma - name = "plasma tank" - desc = "Contains dangerous plasma. Do not inhale. Warning: extremely flammable." - icon_state = "plasma" - flags = CONDUCT - slot_flags = null //they have no straps! - force = 8 - -/obj/item/tank/internals/plasma/populate_gas() - air_contents.set_toxins((3 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) - -/obj/item/tank/internals/plasma/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/flamethrower)) - var/obj/item/flamethrower/F = I - if((!F.status)||(F.ptank)) - return - master = F - F.ptank = src - user.transfer_item_to(src, F) - F.update_icon() - else - return ..() - -/obj/item/tank/internals/plasma/full/populate_gas() - air_contents.set_toxins((10 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) - -/obj/item/tank/internals/plasma/empty/populate_gas() - return - -/* - * Plasmaman Plasma Tank - */ -/obj/item/tank/internals/plasmaman - name = "plasma internals tank" - desc = "A tank of plasma gas designed specifically for use as internals, particularly for plasma-based lifeforms. If you're not a Plasmaman, you probably shouldn't use this." - icon_state = "plasma_fr" - item_state = "plasma_fr" - force = 10 - distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE - -/obj/item/tank/internals/plasmaman/populate_gas() - air_contents.set_toxins((3 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) - -/obj/item/tank/internals/plasmaman/full/populate_gas() - air_contents.set_toxins((10 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) - - -/obj/item/tank/internals/plasmaman/belt - icon_state = "plasmaman_tank_belt" - item_state = "plasmaman_tank_belt" - slot_flags = ITEM_SLOT_BELT - flags_2 = ALLOW_BELT_NO_JUMPSUIT_2 - force = 5 - volume = 35 - w_class = WEIGHT_CLASS_SMALL - -/obj/item/tank/internals/plasmaman/belt/full/populate_gas() - air_contents.set_toxins((10 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) - -/obj/item/tank/internals/plasmaman/belt/empty/populate_gas() - return - -/obj/item/tank/internals/emergency_oxygen/plasma - name = "emergency plasma tank" - desc = "An emergency tank designed specifically for Plasmamen." - icon_state = "emergency_p" - -/obj/item/tank/internals/emergency_oxygen/plasma/populate_gas() - air_contents.set_toxins((10 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) - -/* - * Emergency Oxygen - */ -/obj/item/tank/internals/emergency_oxygen - name = "emergency oxygen tank" - desc = "Used for emergencies. Contains very little oxygen, so try to conserve it until you actually need it." - icon_state = "emergency" - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - flags_2 = ALLOW_BELT_NO_JUMPSUIT_2 - w_class = WEIGHT_CLASS_SMALL - force = 4 - distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE - volume = 3 //Tiny. Real life equivalents only have 21 breaths of oxygen in them. They're EMERGENCY tanks anyway -errorage (dangercon 2011) - -/obj/item/tank/internals/emergency_oxygen/populate_gas() - air_contents.set_oxygen((10 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) - -/obj/item/tank/internals/emergency_oxygen/empty/populate_gas() - return - -/obj/item/tank/internals/emergency_oxygen/engi - name = "extended-capacity emergency oxygen tank" - icon_state = "emergency_engi" - volume = 6 // should last 24 minutes if full - -/obj/item/tank/internals/emergency_oxygen/engi/empty/populate_gas() - return - -/obj/item/tank/internals/emergency_oxygen/engi/syndi - name = "suspicious emergency oxygen tank" - icon_state = "emergency_syndi" - desc = "A dark emergency oxygen tank. The label on the back reads \"Original Oxygen Tank Design, Do Not Steal.\"" - -/obj/item/tank/internals/emergency_oxygen/double - name = "double emergency oxygen tank" - icon_state = "emergency_double" - volume = 12 //If it's double of the above, shouldn't it be double the volume?? - -/obj/item/tank/internals/emergency_oxygen/double/empty/populate_gas() - return - -/* - * Nitrogen - */ -/obj/item/tank/internals/nitrogen - name = "nitrogen tank" - desc = "A tank of nitrogen." - icon_state = "oxygen_fr" - distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE - -/obj/item/tank/internals/nitrogen/populate_gas() - air_contents.set_nitrogen((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) - -/obj/item/tank/internals/emergency_oxygen/nitrogen - name = "emergency nitrogen tank" - desc = "An emergency tank designed specifically for Vox." - icon_state = "emergency_nitrogen" - -/obj/item/tank/internals/emergency_oxygen/nitrogen/populate_gas() - air_contents.set_nitrogen((10 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) - -/obj/item/tank/internals/emergency_oxygen/double/vox - name = "vox specialized nitrogen tank" - desc = "A high-tech nitrogen tank designed specifically for Vox." - icon_state = "emergency_vox" - volume = 35 - -/obj/item/tank/internals/emergency_oxygen/double/vox/populate_gas() - air_contents.set_nitrogen((10 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) - -/* - * Air Mix - */ -/obj/item/tank/internals/air - name = "air tank" - desc = "Mixed anyone?" - icon_state = "air" - item_state = "air" - distribute_pressure = ONE_ATMOSPHERE - -/obj/item/tank/internals/air/populate_gas() - air_contents.set_oxygen((3 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) * O2STANDARD) - air_contents.set_nitrogen((3 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) * N2STANDARD) - -/* - * Generic - */ -/obj/item/tank/internals/generic - name = "gas tank" - desc = "A generic tank used for storing and transporting gasses. Can be used for internals." - icon_state = "generic" - item_state = "generic" - distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE - force = 10 - dog_fashion = /datum/dog_fashion/back - -/obj/item/tank/internals/generic/populate_gas() - return diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm deleted file mode 100644 index fcfb23970f517..0000000000000 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ /dev/null @@ -1,283 +0,0 @@ -/obj/item/tank - name = "tank" - icon = 'icons/obj/tank.dmi' - flags = CONDUCT - slot_flags = ITEM_SLOT_BACK - hitsound = 'sound/weapons/smash.ogg' - w_class = WEIGHT_CLASS_NORMAL - pressure_resistance = ONE_ATMOSPHERE * 5 - force = 5 - throwforce = 10 - throw_speed = 1 - throw_range = 4 - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, RAD = 0, FIRE = 80, ACID = 30) - actions_types = list(/datum/action/item_action/set_internals) - var/datum/gas_mixture/air_contents = null - var/distribute_pressure = ONE_ATMOSPHERE - var/integrity = 3 - var/volume = 70 - -/obj/item/tank/New() - ..() - - air_contents = new /datum/gas_mixture() - air_contents.volume = volume //liters - air_contents.set_temperature(T20C) - - populate_gas() - - START_PROCESSING(SSobj, src) - return - -/obj/item/tank/Destroy() - QDEL_NULL(air_contents) - - STOP_PROCESSING(SSobj, src) - - return ..() - -/obj/item/tank/proc/populate_gas() - return - -/obj/item/tank/ui_action_click(mob/user) - toggle_internals(user) - -/obj/item/tank/proc/toggle_internals(mob/user, silent = FALSE) - var/mob/living/carbon/C = user - if(!istype(C)) - return FALSE - - if(C.internal == src) - to_chat(C, "You close \the [src] valve.") - C.internal = null - else - if(!C.get_organ_slot("breathing_tube")) // Breathing tubes can always use internals, if they have one, skip ahead and turn internals on/off - if(!C.wear_mask) // Do we have a mask equipped? - return FALSE - - var/obj/item/clothing/mask/M = C.wear_mask - // If the "mask" isn't actually a mask OR That mask isn't internals compatible AND Their headgear isn't internals compatible - if(!istype(M) || (!(initial(M.flags) & AIRTIGHT) && !(C.head && C.head.flags & AIRTIGHT))) - if(!silent) - to_chat(C, "You are not wearing a suitable mask or helmet.") - return FALSE - if(M.up) // If the mask is equipped but pushed away - M.adjustmask(C) // Adjust it back - - if(!silent) - if(C.internal) - to_chat(C, "You switch your internals to [src].") - else - to_chat(C, "You open \the [src] valve.") - C.internal = src - C.update_action_buttons_icon() - - -/obj/item/tank/examine(mob/user) - . = ..() - - var/obj/icon = src - if(istype(loc, /obj/item/assembly)) - icon = loc - - if(!in_range(src, user)) - if(icon == src) - . += "It's [p_a()] [bicon(icon)] [name]! If you want any more information you'll need to get closer." - return - - var/celsius_temperature = air_contents.temperature() - T0C - var/descriptive - - if(celsius_temperature < 20) - descriptive = "cold" - else if(celsius_temperature < 40) - descriptive = "room temperature" - else if(celsius_temperature < 80) - descriptive = "lukewarm" - else if(celsius_temperature < 100) - descriptive = "warm" - else if(celsius_temperature < 300) - descriptive = "hot" - else - descriptive = "furiously hot" - - . += "\The [bicon(icon)][src] feels [descriptive]" - . += "The pressure gauge displays [round(air_contents.return_pressure())] kPa" - -/obj/item/tank/blob_act(obj/structure/blob/B) - if(B && B.loc == loc) - var/turf/location = get_turf(src) - if(!location) - qdel(src) - - if(air_contents) - location.blind_release_air(air_contents) - - qdel(src) - -/obj/item/tank/suicide_act(mob/user) - var/mob/living/carbon/human/H = user - user.visible_message("[user] is putting [src]'s valve to [user.p_their()] lips! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/effects/spray.ogg', 10, TRUE, -3) - - if(!QDELETED(H) && air_contents && air_contents.return_pressure() >= 1000) - var/obj/item/organ/external/head/head = H.get_organ("head") - head?.disfigure() - H.inflate_gib() - return OBLITERATION - - to_chat(user, "There isn't enough pressure in [src] to commit suicide with...") - return SHAME - -/obj/item/tank/deconstruct(disassembled = TRUE) - if(!disassembled) - var/turf/T = get_turf(src) - if(T) - T.blind_release_air(air_contents) - playsound(src.loc, 'sound/effects/spray.ogg', 10, TRUE, -3) - qdel(src) - -/obj/item/tank/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) - ..() - - add_fingerprint(user) - if(istype(loc, /obj/item/assembly)) - icon = loc - - if(istype(W, /obj/item/assembly_holder)) - bomb_assemble(W,user) - -/obj/item/tank/attack_self__legacy__attackchain(mob/user as mob) - if(!(air_contents)) - return - - ui_interact(user) - -/obj/item/tank/ui_state(mob/user) - return GLOB.inventory_state - -/obj/item/tank/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "Tank", name) - ui.open() - -/obj/item/tank/ui_data(mob/user) - var/list/data = list() - data["tankPressure"] = round(air_contents.return_pressure()) - data["releasePressure"] = round(distribute_pressure) - data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE) - data["minReleasePressure"] = round(TANK_MIN_RELEASE_PRESSURE) - data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE) - var/mob/living/carbon/C = user - if(!istype(C)) - C = loc.loc - if(!istype(C)) - return data - data["has_mask"] = C.wear_mask ? TRUE : FALSE - data["connected"] = (C.internal && C.internal == src) ? TRUE : FALSE - return data - -/obj/item/tank/ui_act(action, params) - if(..()) - return - . = TRUE - switch(action) - if("pressure") - var/pressure = params["pressure"] - if(pressure == "reset") - pressure = initial(distribute_pressure) - else if(pressure == "min") - pressure = TANK_MIN_RELEASE_PRESSURE - else if(pressure == "max") - pressure = TANK_MAX_RELEASE_PRESSURE - else if(text2num(pressure) != null) - pressure = text2num(pressure) - else - . = FALSE - if(.) - distribute_pressure = clamp(round(pressure), TANK_MIN_RELEASE_PRESSURE, TANK_MAX_RELEASE_PRESSURE) - if("internals") - toggle_internals(usr) - else - . = FALSE - if(.) - add_fingerprint(usr) - -/obj/item/tank/return_obj_air() - RETURN_TYPE(/datum/gas_mixture) - return air_contents - -/obj/item/tank/return_analyzable_air() - return air_contents - -/obj/item/tank/proc/remove_air_volume(volume_to_return) - if(!air_contents) - return null - - var/tank_pressure = air_contents.return_pressure() - var/actual_distribute_pressure = clamp(tank_pressure, 0, distribute_pressure) - - var/moles_needed = actual_distribute_pressure * volume_to_return / (R_IDEAL_GAS_EQUATION * air_contents.temperature()) - - return air_contents.remove(moles_needed) - -/obj/item/tank/process() - //Allow for reactions - air_contents.react() - check_status() - - -/obj/item/tank/proc/check_status() - //Handle exploding, leaking, and rupturing of the tank - - if(!air_contents) - return 0 - - var/pressure = air_contents.return_pressure() - if(pressure > TANK_FRAGMENT_PRESSURE) - if(!istype(loc,/obj/item/transfer_valve)) - message_admins("Explosive tank rupture! last key to touch the tank was [fingerprintslast] (JMP)") - log_game("Explosive tank rupture! last key to touch the tank was [fingerprintslast] at [x], [y], [z]") -// to_chat(world, "[x],[y] tank is exploding: [pressure] kPa") - //Give the gas a chance to build up more pressure through reacting - air_contents.react() - air_contents.react() - air_contents.react() - pressure = air_contents.return_pressure() - var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE - var/turf/epicenter = get_turf(loc) - -// to_chat(world, "Exploding Pressure: [pressure] kPa, intensity: [range]") - - explosion(epicenter, round(range*0.25), round(range*0.5), round(range), round(range*1.5)) - if(istype(loc,/obj/item/transfer_valve)) - qdel(loc) - else - qdel(src) - - else if(pressure > TANK_RUPTURE_PRESSURE) -// to_chat(world, "[x],[y] tank is rupturing: [pressure] kPa, integrity [integrity]") - if(integrity <= 0) - var/turf/simulated/T = get_turf(src) - if(!T) - return - T.blind_release_air(air_contents) - playsound(loc, 'sound/effects/spray.ogg', 10, TRUE, -3) - qdel(src) - else - integrity-- - - else if(pressure > TANK_LEAK_PRESSURE) -// to_chat(world, "[x],[y] tank is leaking: [pressure] kPa, integrity [integrity]") - if(integrity <= 0) - var/turf/simulated/T = get_turf(src) - if(!T) - return - var/datum/gas_mixture/leaked_gas = air_contents.remove_ratio(0.25) - T.blind_release_air(leaked_gas) - else - integrity-- - - else if(integrity < 3) - integrity++ diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm deleted file mode 100644 index 13a6ab38e09a3..0000000000000 --- a/code/game/objects/items/weapons/tape.dm +++ /dev/null @@ -1,55 +0,0 @@ -/obj/item/stack/tape_roll - name = "tape roll" - desc = "A roll of sticky tape. Possibly for taping ducks... or was that ducts?" - icon = 'icons/obj/bureaucracy.dmi' - icon_state = "taperoll" - singular_name = "tape roll" - w_class = WEIGHT_CLASS_TINY - amount = 25 - max_amount = 25 - -/obj/item/stack/tape_roll/New(loc, amount=null) - ..() - update_icon(UPDATE_ICON_STATE) - -/obj/item/stack/tape_roll/attack__legacy__attackchain(mob/living/carbon/human/M, mob/living/user) - if(!istype(M)) //What good is a duct tape mask if you are unable to speak? - return - if(M.wear_mask) - to_chat(user, "Remove [M.p_their()] mask first!") - return - if(amount < 2) - to_chat(user, "You'll need more tape for this!") - return - if(!M.check_has_mouth()) - to_chat(user, "[M.p_they(TRUE)] [M.p_have()] no mouth to tape over!") - return - user.visible_message("[user] is taping [M]'s mouth closed!", - "You try to tape [M == user ? "your own" : "[M]'s"] mouth shut!", - "You hear tape ripping.") - if(!do_after(user, 50, target = M)) - return - if(!use(2)) - to_chat(user, "You don't have enough tape!") - return - if(M.wear_mask) - to_chat(user, "[M == user ? user : M]'s mouth is already covered!") - return - user.visible_message("[user] tapes [M]'s mouth shut!", - "You cover [M == user ? "your own" : "[M]'s"] mouth with a piece of duct tape.[M == user ? null : " That will shut them up."]") - var/obj/item/clothing/mask/muzzle/G = new /obj/item/clothing/mask/muzzle/tapegag - M.equip_to_slot(G, ITEM_SLOT_MASK) - G.add_fingerprint(user) - -/obj/item/stack/tape_roll/update_icon_state() - var/amount = get_amount() - if((amount <= 2) && (amount > 0)) - icon_state = "taperoll" - if((amount <= 4) && (amount > 2)) - icon_state = "taperoll-2" - if((amount <= 6) && (amount > 4)) - icon_state = "taperoll-3" - if(amount > 6) - icon_state = "taperoll-4" - else - icon_state = "taperoll-4" diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm deleted file mode 100644 index cdc9243817200..0000000000000 --- a/code/game/objects/items/weapons/teleportation.dm +++ /dev/null @@ -1,110 +0,0 @@ -/* Teleportation devices. - * Contains: - * Hand-tele - */ - -/* - * Hand-tele - */ -/obj/item/hand_tele - name = "hand tele" - desc = "An experimental portable teleportation station developed by Nanotrasen, small enough to be carried in a pocket." - icon = 'icons/obj/device.dmi' - icon_state = "hand_tele" - item_state = "electronic" - throwforce = 0 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 3 - throw_range = 5 - materials = list(MAT_METAL=10000) - origin_tech = null - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 30, RAD = 0, FIRE = 100, ACID = 100) - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - var/icon_state_inactive = "hand_tele_inactive" - /// The number of open teleportals. - var/active_portals = 0 - /// Variable contains next time hand tele can be used to make it not EMP proof - var/emp_timer = 0 - -/obj/item/hand_tele/examine_more(mob/user) - . = ..() - . += "Conventional teleportation technology requires either inflexible quantum pad setups that can only send users between two fixed locations, \ - or large immobile portal generators connected to an even larger set of computer equipment that is required for safe translation through extradimensional space." - . += "" - . += "This specialised portable teleporter is an experimental miniaturisation of the latter category. It utilises highly specialised analogue circuitry to perform the bulk of the teleportation calculations, \ - allowing for a far more compact package than more generalised digital computer technology would allow. Some digital components are present, which handle the user interface and beacon tracking functions. \ - In order to allow the device to be fully portable, it has no frame to stabilise the portals it generates. This comes at the cost of the portals only being able to persist for a limited time." - . += "" - . += "A limited number of these experimental devices exist. Due manufacturing difficulties (particularly regarding the analogue computer), \ - Nanotrasen has delayed releasing it onto the market until it can improve its production methods." - -/obj/item/hand_tele/Initialize(mapload) - . = ..() - AddElement(/datum/element/high_value_item) - -/obj/item/hand_tele/attack_self__legacy__attackchain(mob/user) - // The turf the user is currently located in. - var/turf/current_location = get_turf(user) - if(emp_timer > world.time) - do_sparks(5, 0, loc) - to_chat(user, "[src] attempts to create a portal, but abruptly shuts off.") - return - if(!current_location||!is_teleport_allowed(current_location.z))//If turf was not found or they're somewhere teleproof - to_chat(user, "\The [src] is malfunctioning.") - return - var/list/L = list() - for(var/obj/machinery/computer/teleporter/com in GLOB.machines) - if(com.target) - if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged) - L["[com.id] (Active)"] = com.target - else - L["[com.id] (Inactive)"] = com.target - var/list/turfs = list() - var/area/A - for(var/turf/T in orange(10)) - if(T.x>world.maxx-8 || T.x<8) - continue //putting them at the edge is dumb - if(T.y>world.maxy-8 || T.y<8) - continue - A = get_area(T) - if(A.tele_proof) - continue // Telescience-proofed areas require a beacon. - turfs += T - if(length(turfs)) - L["None (Dangerous)"] = pick(turfs) - flick("hand_tele_activated", src) - var/t1 = tgui_input_list(user, "Please select a teleporter to lock in on.", "Hand Teleporter", L) - if(!t1 || (!user.is_in_active_hand(src) || user.stat || user.restrained())) - return - if(active_portals >= 3) - user.show_message("\The [src] is recharging!") - return - var/T = L[t1] - user.show_message("Locked In.", 2) - var/obj/effect/portal/P = new /obj/effect/portal/hand_tele(get_turf(src), T, src, creation_mob = user) - try_move_adjacent(P) - active_portals++ - add_fingerprint(user) - -/obj/item/hand_tele/emp_act(severity) - make_inactive(severity) - return ..() - -/obj/item/hand_tele/proc/make_inactive(severity) - icon_state = icon_state_inactive - var/time = rand(25 SECONDS, 30 SECONDS) * severity - emp_timer = world.time + time - addtimer(CALLBACK(src, PROC_REF(check_inactive), emp_timer), time) - -/obj/item/hand_tele/proc/check_inactive(current_emp_timer) - if(emp_timer != current_emp_timer) - return - icon_state = initial(icon_state) - -/obj/item/hand_tele/examine(mob/user) - . = ..() - if(emp_timer > world.time) - . += "It looks inactive." - -/obj/item/hand_tele/portal_destroyed(obj/effect/portal/P) - active_portals-- diff --git a/code/game/objects/items/weapons/teleprod.dm b/code/game/objects/items/weapons/teleprod.dm deleted file mode 100644 index 690387428000e..0000000000000 --- a/code/game/objects/items/weapons/teleprod.dm +++ /dev/null @@ -1,20 +0,0 @@ -/obj/item/melee/baton/cattleprod/teleprod - name = "teleprod" - desc = "A prod with a bluespace crystal on the end. The crystal doesn't look too fun to touch." - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon_state = "teleprod_nocell" - base_icon = "teleprod" - origin_tech = "combat=2;bluespace=4;materials=3" - -/obj/item/melee/baton/cattleprod/teleprod/attack__legacy__attackchain(mob/living/carbon/M, mob/living/carbon/user)//handles making things teleport when hit - ..() - if(!turned_on) - return - if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) - user.visible_message("[user] accidentally hits [user.p_themselves()] with [src]!", - "You accidentally hit yourself with [src]!") - deductcharge(hitcost) - do_teleport(user, get_turf(user), 50)//honk honk - else if(isliving(M) && !M.anchored) - do_teleport(M, get_turf(M), 15) diff --git a/code/game/objects/items/weapons/thurible.dm b/code/game/objects/items/weapons/thurible.dm deleted file mode 100644 index 63f0cbc4e305c..0000000000000 --- a/code/game/objects/items/weapons/thurible.dm +++ /dev/null @@ -1,174 +0,0 @@ -/obj/item/thurible - name = "thurible" - desc = "A religious artifact used to burn and spread incense when swung from the attached chain." - icon = 'icons/obj/weapons/magical_weapons.dmi' - lefthand_file = 'icons/mob/inhands/religion_lefthand.dmi' - righthand_file = 'icons/mob/inhands/religion_righthand.dmi' - icon_state = "thurible" - item_state = "thurible" - force = 10 - throwforce = 7 - w_class = WEIGHT_CLASS_NORMAL - flags = CONDUCT - container_type = REFILLABLE - /// Whether or not the thurible can be loaded with harmful chems - var/corrupted = FALSE - /// Has the thurible been ignited? - var/lit = FALSE - /// List of chemicals considered safe for the thurible - var/static/list/safe_chem_list = list("antihol", "charcoal", "epinephrine", "insulin", "teporone", "salbutamol", "omnizine", - "weak_omnizine", "godblood", "potass_iodide", "oculine", "mannitol", "spaceacillin", "salglu_solution", - "sal_acid", "cryoxadone", "sugar", "hydrocodone", "mitocholide", "rezadone", "menthol", - "mutadone", "sanguine_reagent", "iron", "ephedrine", "heparin", "corazone", "sodiumchloride", - "lavaland_extract", "synaptizine", "bicaridine", "kelotane", "water", "holywater", "lsd", "thc", "happiness", - "cbd", "space_drugs", "nicotine", "jestosterone", "nothing") - /// How many reagents are consumed with each swing? - var/swing_reagents_consumed = 2 - -/obj/item/thurible/Initialize(mapload) - . = ..() - create_reagents(50) - reagents.set_reacting(FALSE) - -/obj/item/thurible/Destroy() - STOP_PROCESSING(SSobj, src) - QDEL_NULL(reagents) - return ..() - -/obj/item/thurible/examine(mob/user) - . = ..() - . += "[src] can hold up to [reagents.maximum_volume] units." - . += "Contains [reagents.total_volume] units of various reagents." - -/obj/item/thurible/process() - swing() - -/obj/item/thurible/update_appearance() - if(lit) - icon_state = "thurible-lit" - item_state = "thurible-lit" - else - icon_state = "thurible" - item_state = "thurible" - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - if(H.r_hand == src || H.l_hand == src) - H.update_inv_l_hand() - H.update_inv_r_hand() - return ..() - -/obj/item/thurible/attackby__legacy__attackchain(obj/item/fire_source, mob/user, params) - . = ..() - if(fire_source.get_heat()) - user.visible_message( - "[user] lights [src] with [fire_source].", - "You light [src] with [fire_source].", - "You hear a low whoosh." - ) - light(user) - -/obj/item/thurible/attack_self__legacy__attackchain(mob/user) - if(lit) - to_chat(user, "You extinguish [src].") - put_out(user) - return ..() - -/obj/item/thurible/can_enter_storage(obj/item/storage/S, mob/user) - if(lit) - to_chat(user, "[S] can't hold \the [initial(name)] while it's lit!") // initial(name) so it doesn't say "lit" twice in a row - return FALSE - return TRUE - -/obj/item/thurible/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - . = ..() - light() - -/obj/item/thurible/on_reagent_change() - . = ..() - if(corrupted) - return - var/found_forbidden_reagent = FALSE - for(var/datum/reagent/R as anything in reagents.reagent_list) - if(R.id == "unholywater") - corrupted = TRUE - visible_message( - "You corrupt [src] with unholy water!", - "You hear a strange gurgling." - ) - return - if(!safe_chem_list.Find(R.id)) - reagents.del_reagent(R.id) - found_forbidden_reagent = TRUE - if(found_forbidden_reagent) - visible_message( - "[src] banishes an unholy substance!", - "You hear a strange fizzing." - ) - -/// Lights the thurible and starts processing reagents -/obj/item/thurible/proc/light(mob/user) - if(lit) - to_chat(user, "[src] is already lit!") - return - - if(!reagents.total_volume) - to_chat(user, "[src] is out of fuel!") - return - - // Plasma explodes when exposed to fire. - if(reagents.get_reagent_amount("plasma")) - var/datum/effect_system/reagents_explosion/E = new() - E.set_up(round(reagents.get_reagent_amount("plasma") / 2.5, 1), get_turf(src), 0, 0) - E.start() - return - - // Fuel explodes, too, but much less violently. - if(reagents.get_reagent_amount("fuel")) - var/datum/effect_system/reagents_explosion/E = new() - E.set_up(round(reagents.get_reagent_amount("fuel") / 5, 1), get_turf(src), 0, 0) - E.start() - return - - // And black powder... but more violently. - if(reagents.get_reagent_amount("blackpowder")) - var/datum/effect_system/reagents_explosion/E = new() - E.set_up(round(reagents.get_reagent_amount("blackpowder") / 2, 1), get_turf(src), 0, 0) - E.start() - return - - lit = TRUE - reagents.set_reacting(TRUE) - reagents.handle_reactions() - START_PROCESSING(SSobj, src) - set_light(2, 0.3, "#E38F46") - update_appearance() - return TRUE - -/// Extinguishes the thurible and stops processing -/obj/item/thurible/proc/put_out(mob/user) - lit = FALSE - STOP_PROCESSING(SSobj, src) - set_light(0) - update_appearance() - return TRUE - -/// Spreads reagents in a 3x3 area centered on the thurible -/obj/item/thurible/proc/swing() - var/obj/released_reagents = new - released_reagents.create_reagents(2) - reagents.trans_to(released_reagents, swing_reagents_consumed) - var/list/mobs_to_smoke = list() - for(var/atom/A in view(1, get_turf(src))) - released_reagents.reagents.reaction(A) - if(iscarbon(A)) - var/mob/living/carbon/C = A - if(C.can_breathe_gas()) - mobs_to_smoke += C - if(length(mobs_to_smoke)) - var/percentage_to_add = released_reagents.reagents.total_volume / length(mobs_to_smoke) // Divide the amount of reagents spread around by the number of people inhaling it - - for(var/mob/living/carbon/smoker as anything in mobs_to_smoke) - released_reagents.reagents.copy_to(smoker, percentage_to_add) - - if(reagents.total_volume <= 0) - put_out() diff --git a/code/game/objects/items/weapons/vending_items.dm b/code/game/objects/items/weapons/vending_items.dm deleted file mode 100644 index 835b69599391f..0000000000000 --- a/code/game/objects/items/weapons/vending_items.dm +++ /dev/null @@ -1,229 +0,0 @@ -/obj/item/vending_refill - name = "resupply canister" - var/machine_name = "Generic" - - icon = 'icons/obj/vending_restock.dmi' - icon_state = "refill_snack" - item_state = "restock_unit" - desc = "A vending machine restock cart." - usesound = 'sound/items/deconstruct.ogg' - flags = CONDUCT - force = 7 - throwforce = 10 - throw_speed = 1 - throw_range = 7 - w_class = WEIGHT_CLASS_NORMAL - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 70, ACID = 30) - - // Built automatically from the corresponding vending machine. - // If null, considered to be full upon being restocked. - var/list/products - var/list/contraband - var/list/premium - -/obj/item/vending_refill/Initialize(mapload) - . = ..() - name = "\improper [machine_name] restocking unit" - -/obj/item/vending_refill/examine(mob/user) - . = ..() - var/num = get_part_rating() - if(num == INFINITY) - . += "It's sealed tight, completely full of supplies." - else if(num == 0) - . += "It's empty!" - else if(!isnull(num)) // If it's null, then the items haven't been properly added yet. - . += "It can restock [num] item\s." - -/obj/item/vending_refill/get_part_rating() - . = 0 - if(isnull(products) && isnull(contraband) && isnull(premium)) - return null - for(var/key in products) - . += products[key] - for(var/key in contraband) - . += contraband[key] - for(var/key in premium) - . += premium[key] - - if(. > 30) - return INFINITY - -/obj/item/vending_refill/boozeomat - machine_name = "Booze-O-Mat" - icon_state = "refill_booze" - -/obj/item/vending_refill/coffee - machine_name = "hot drinks" - icon_state = "refill_joe" - -/obj/item/vending_refill/snack - machine_name = "Getmore Chocolate Corp" - -/obj/item/vending_refill/cola - machine_name = "Robust Softdrinks" - icon_state = "refill_cola" - -/obj/item/vending_refill/cigarette - machine_name = "cigarette" - icon_state = "refill_smoke" - -/obj/item/vending_refill/autodrobe - machine_name = "AutoDrobe" - icon_state = "refill_costume" - -/obj/item/vending_refill/hatdispenser - machine_name = "hat" - icon_state = "refill_costume" - -/obj/item/vending_refill/suitdispenser - machine_name = "suit" - icon_state = "refill_costume" - -/obj/item/vending_refill/shoedispenser - machine_name = "shoe" - icon_state = "refill_costume" - -/obj/item/vending_refill/clothing - machine_name = "ClothesMate" - icon_state = "refill_clothes" - -/obj/item/vending_refill/crittercare - machine_name = "CritterCare" - icon_state = "refill_pet" - -/obj/item/vending_refill/chinese - machine_name = "MrChangs" - -/obj/item/vending_refill/hydroseeds - machine_name = "MegaSeed Servitor" - icon_state = "refill_plant" - -/obj/item/vending_refill/assist - machine_name = "Vendomat" - icon_state = "refill_engi" - -/obj/item/vending_refill/cart - machine_name = "PTech" - icon_state = "refill_smoke" - -/obj/item/vending_refill/dinnerware - machine_name = "Plasteel Chef's Dinnerware Vendor" - icon_state = "refill_smoke" - -/obj/item/vending_refill/engineering - machine_name = "Robco Tool Maker" - icon_state = "refill_engi" - -/obj/item/vending_refill/youtool - machine_name = "YouTool" - icon_state = "refill_engi" - -/obj/item/vending_refill/engivend - machine_name = "Engi-Vend" - icon_state = "refill_engi" - -/obj/item/vending_refill/medical - machine_name = "NanoMed Plus" - icon_state = "refill_medical" - -/obj/item/vending_refill/wallmed - machine_name = "NanoMed" - icon_state = "refill_medical" - -/obj/item/vending_refill/hydronutrients - machine_name = "NutriMax" - icon_state = "refill_plant" - -/obj/item/vending_refill/security - icon_state = "refill_sec" - -/obj/item/vending_refill/sovietsoda - machine_name = "BODA" - icon_state = "refill_cola" - -/obj/item/vending_refill/sustenance - machine_name = "Sustenance Vendor" - icon_state = "refill_snack" - -/obj/item/vending_refill/donksoft - machine_name = "Donksoft Toy Vendor" - icon_state = "refill_donksoft" - -/obj/item/vending_refill/robotics - machine_name = "Robotech Deluxe" - icon_state = "refill_engi" - -//Departmental clothing vendors - -/obj/item/vending_refill/secdrobe - machine_name = "SecDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/detdrobe - machine_name = "DetDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/medidrobe - machine_name = "MediDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/virodrobe - machine_name = "ViroDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/chemdrobe - machine_name = "ChemDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/genedrobe - machine_name = "GeneDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/scidrobe - machine_name = "SciDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/robodrobe - machine_name = "RoboDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/engidrobe - machine_name = "EngiDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/atmosdrobe - machine_name = "AtmosDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/cargodrobe - machine_name = "CargoDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/exploredrobe - machine_name = "ExploreDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/chefdrobe - machine_name = "ChefDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/bardrobe - machine_name = "BarDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/hydrodrobe - machine_name = "HydroDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/janidrobe - machine_name = "JaniDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/lawdrobe - machine_name = "LawDrobe" - icon_state = "refill_clothes" - -/obj/item/vending_refill/traindrobe - machine_name = "TrainDrobe" - icon_state = "refill_clothes" diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm deleted file mode 100644 index ed176b3bd2ad4..0000000000000 --- a/code/game/objects/items/weapons/weaponry.dm +++ /dev/null @@ -1,323 +0,0 @@ -/** - * # Banhammer - */ -/obj/item/banhammer - name = "banhammer" - desc = "A banhammer." - icon = 'icons/obj/toy.dmi' - icon_state = "toyhammer" - slot_flags = ITEM_SLOT_BELT - throwforce = 0 - w_class = WEIGHT_CLASS_TINY - throw_speed = 7 - throw_range = 15 - attack_verb = list("banned") - max_integrity = 200 - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 70) - resistance_flags = FIRE_PROOF - -/obj/item/banhammer/suicide_act(mob/user) - visible_message("[user] is hitting [user.p_themselves()] with [src]! It looks like [user.p_theyre()] trying to ban [user.p_themselves()] from life.") - return BRUTELOSS|FIRELOSS|TOXLOSS|OXYLOSS - -/obj/item/banhammer/attack__legacy__attackchain(mob/M, mob/user) - to_chat(M, " You have been banned FOR NO REISIN by [user]") - to_chat(user, " You have BANNED [M]") - playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much - -/obj/item/sord - name = "\improper SORD" - desc = "This thing is so unspeakably shitty you are having a hard time even holding it." - icon = 'icons/obj/weapons/magical_weapons.dmi' - icon_state = "sord" - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - slot_flags = ITEM_SLOT_BELT - force = 2 - throwforce = 1 - w_class = WEIGHT_CLASS_NORMAL - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - -/obj/item/sord/suicide_act(mob/user) - user.visible_message("[user] is trying to impale [user.p_themselves()] with [src]! It might be a suicide attempt if it weren't so shitty.", \ - "You try to impale yourself with [src], but it's USELESS...") - return SHAME - -/obj/item/claymore - name = "claymore" - desc = "What are you standing around staring at this for? Get to killing!" - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon = 'icons/obj/weapons/melee.dmi' - icon_state = "claymore" - item_state = "claymore" - flags = CONDUCT - hitsound = 'sound/weapons/bladeslice.ogg' - slot_flags = ITEM_SLOT_BELT - force = 40 - throwforce = 10 - sharp = TRUE - w_class = WEIGHT_CLASS_NORMAL - 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, RAD = 0, FIRE = 100, ACID = 50) - resistance_flags = FIRE_PROOF - -/obj/item/claymore/Initialize(mapload) - . = ..() - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES) - -/obj/item/claymore/suicide_act(mob/user) - user.visible_message("[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return BRUTELOSS - -/obj/item/claymore/ceremonial - name = "ceremonial claymore" - desc = "An engraved and fancy version of the claymore. It appears to be less sharp than it's more functional cousin." - force = 20 - -/obj/item/katana - name = "katana" - desc = "Woefully underpowered in D20." - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon = 'icons/obj/weapons/melee.dmi' - icon_state = "katana" - item_state = "katana" - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK - flags_2 = ALLOW_BELT_NO_JUMPSUIT_2 //Look, you can strap it to your back. You can strap it to your waist too. - force = 40 - throwforce = 10 - sharp = TRUE - w_class = WEIGHT_CLASS_BULKY - hitsound = 'sound/weapons/bladeslice.ogg' - 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, RAD = 0, FIRE = 100, ACID = 50) - resistance_flags = FIRE_PROOF - needs_permit = TRUE - -/obj/item/katana/Initialize(mapload) - . = ..() - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES) - - -/obj/item/katana/suicide_act(mob/user) - user.visible_message("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!") - return BRUTELOSS - -/obj/item/harpoon - name = "harpoon" - sharp = TRUE - desc = "Tharr she blows!" - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon = 'icons/obj/weapons/melee.dmi' - icon_state = "harpoon" - item_state = "harpoon" - force = 20 - throwforce = 15 - w_class = WEIGHT_CLASS_NORMAL - attack_verb = list("jabbed","stabbed","ripped") - -/obj/item/wirerod - name = "wired rod" - desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit." - icon_state = "wiredrod" - item_state = "rods" - flags = CONDUCT - force = 9 - throwforce = 10 - w_class = WEIGHT_CLASS_NORMAL - materials = list(MAT_METAL=1150, MAT_GLASS=75) - attack_verb = list("hit", "bludgeoned", "whacked", "bonked") - -/obj/item/wirerod/attackby__legacy__attackchain(obj/item/I, mob/user, params) - ..() - if(istype(I, /obj/item/shard)) - var/obj/item/spear/S = new /obj/item/spear - if(istype(I, /obj/item/shard/plasma)) - S.add_plasmaglass() - S.update_icon() - if(!remove_item_from_storage(user)) - user.unequip(src) - user.unequip(I) - - user.put_in_hands(S) - to_chat(user, "You fasten the glass shard to the top of the rod with the cable.") - qdel(I) - qdel(src) - - else if(istype(I, /obj/item/assembly/igniter) && !(I.flags & NODROP)) - var/obj/item/melee/baton/cattleprod/P = new /obj/item/melee/baton/cattleprod - - if(!remove_item_from_storage(user)) - user.unequip(src) - user.unequip(I) - - user.put_in_hands(P) - to_chat(user, "You fasten [I] to the top of the rod with the cable.") - qdel(I) - qdel(src) - -/obj/item/throwing_star - name = "throwing star" - desc = "An ancient weapon still used to this day due to it's ease of lodging itself into victim's body parts." - icon = 'icons/obj/weapons/melee.dmi' - icon_state = "throwingstar" - item_state = "eshield0" - force = 2 - throwforce = 20 //This is never used on mobs since this has a 100% embed chance. - throw_speed = 4 - embedded_pain_multiplier = 4 - w_class = WEIGHT_CLASS_SMALL - embed_chance = 100 - embedded_fall_chance = 0 //Hahaha! - sharp = TRUE - materials = list(MAT_METAL=500, MAT_GLASS=500) - resistance_flags = FIRE_PROOF - -/obj/item/spear/kidan - name = "\improper Kidan spear" - desc = "A one-handed spear brought over from the Kidan homeworld." - icon_state = "kidanspear" - item_state = "kidanspear" - force = 10 - throwforce = 15 - -/obj/item/melee/baseball_bat - name = "baseball bat" - desc = "There ain't a skull in the league that can withstand a swatter." - flags_2 = RANDOM_BLOCKER_2 - icon_state = "baseball_bat" - item_state = "baseball_bat" - var/deflectmode = FALSE // deflect small/medium thrown objects - var/lastdeflect - force = 10 - throwforce = 12 - attack_verb = list("beat", "smacked") - w_class = WEIGHT_CLASS_HUGE - var/next_throw_time = 0 - var/homerun_ready = 0 - var/homerun_able = 0 - -/obj/item/melee/baseball_bat/homerun - name = "home run bat" - desc = "This thing looks dangerous... Dangerously good at baseball, that is." - homerun_able = 1 - -/obj/item/melee/baseball_bat/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - . = ..() - if(!isitem(hitby) || attack_type != THROWN_PROJECTILE_ATTACK) - return FALSE - var/obj/item/I = hitby - if(I.w_class <= WEIGHT_CLASS_NORMAL || istype(I, /obj/item/beach_ball)) // baseball bat deflecting - if(deflectmode) - if(prob(10)) - visible_message("[owner] Deflects [I] directly back at the thrower! It's a home run!", "You deflect [I] directly back at the thrower! It's a home run!") - playsound(get_turf(owner), 'sound/weapons/homerun.ogg', 100, 1) - do_attack_animation(I, ATTACK_EFFECT_DISARM) - I.throw_at(locateUID(I.thrownby), 20, 20, owner) - deflectmode = FALSE - if(!istype(I, /obj/item/beach_ball)) - lastdeflect = world.time + 3000 - return TRUE - else if(prob(30)) - visible_message("[owner] swings! And [p_they()] miss[p_es()]! How embarassing.", "You swing! You miss! Oh no!") - playsound(get_turf(owner), 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) - do_attack_animation(get_step(owner, pick(GLOB.alldirs)), ATTACK_EFFECT_DISARM) - deflectmode = FALSE - if(!istype(I, /obj/item/beach_ball)) - lastdeflect = world.time + 3000 - return FALSE - else - visible_message("[owner] swings and deflects [I]!", "You swing and deflect [I]!") - playsound(get_turf(owner), 'sound/weapons/baseball_hit.ogg', 50, TRUE, -1) - do_attack_animation(I, ATTACK_EFFECT_DISARM) - I.throw_at(get_edge_target_turf(owner, pick(GLOB.cardinal)), rand(8,10), 14, owner) - deflectmode = FALSE - if(!istype(I, /obj/item/beach_ball)) - lastdeflect = world.time + 3000 - return TRUE - -/obj/item/melee/baseball_bat/attack_self__legacy__attackchain(mob/user) - if(!homerun_able) - if(!deflectmode && world.time >= lastdeflect) - to_chat(user, "You prepare to deflect objects thrown at you. You cannot attack during this time.") - deflectmode = TRUE - else if(deflectmode && world.time >= lastdeflect) - to_chat(user, "You no longer deflect objects thrown at you. You can attack during this time") - deflectmode = FALSE - else - to_chat(user, "You need to wait until you can deflect again. The ability will be ready in [time2text(lastdeflect - world.time, "mm:ss")]") - return ..() - if(homerun_ready) - to_chat(user, "You're already ready to do a home run!") - return ..() - to_chat(user, "You begin gathering strength...") - playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, 1) - if(do_after(user, 90, target = user)) - to_chat(user, "You gather power! Time for a home run!") - homerun_ready = 1 - ..() - -/obj/item/melee/baseball_bat/attack__legacy__attackchain(mob/living/target, mob/living/user) - if(deflectmode) - to_chat(user, "You cannot attack in deflect mode!") - return - . = ..() - if(homerun_ready) - var/atom/throw_target = get_edge_target_turf(target, user.dir) - user.visible_message("It's a home run!") - target.throw_at(throw_target, rand(8,10), 14, user) - target.ex_act(EXPLODE_HEAVY) - playsound(get_turf(src), 'sound/weapons/homerun.ogg', 100, 1) - homerun_ready = 0 - return - if(world.time < next_throw_time) - // Limit the rate of throwing, so you can't spam it. - return - if(!istype(target)) - // Should already be /mob/living, but check anyway. - return - if(target.anchored) - // No throwing mobs that are anchored to the floor. - return - if(target.mob_size > MOB_SIZE_HUMAN) - // No throwing things that are physically bigger than you are. - // Covers: blobbernaut, alien empress, ai core, juggernaut, ed209, mulebot, alien/queen/large, carp/megacarp, deathsquid, hostile/tree, megafauna, hostile/asteroid, terror_spider/queen/empress - return - if(!(target.status_flags & CANPUSH)) - // No throwing mobs specifically flagged as immune to being pushed. - // Covers: revenant, hostile/blob/*, most borgs, juggernauts, hivebot/tele, shades, bots, alien queens, hostile/syndicate/melee, hostile/asteroid - return - if(target.move_resist > MOVE_RESIST_DEFAULT) - // No throwing mobs that have higher than normal move_resist. - // Covers: revenant, bot/mulebot, hostile/statue, hostile/megafauna, goliath - return - var/atom/throw_target = get_edge_target_turf(target, user.dir) - target.throw_at(throw_target, rand(1, 2), 7, user) - next_throw_time = world.time + 10 SECONDS - -/obj/item/melee/baseball_bat/dropped(mob/user, silent) - . = ..() - deflectmode = FALSE - -/obj/item/melee/baseball_bat/ablative - name = "metal baseball bat" - desc = "This bat is made of highly reflective, highly armored material." - icon_state = "baseball_bat_metal" - item_state = "baseball_bat_metal" - force = 12 - throwforce = 15 - -/obj/item/melee/baseball_bat/ablative/IsReflect()//some day this will reflect thrown items instead of lasers - var/picksound = rand(1,2) - var/turf = get_turf(src) - if(picksound == 1) - playsound(turf, 'sound/weapons/effects/batreflect1.ogg', 50, 1) - if(picksound == 2) - playsound(turf, 'sound/weapons/effects/batreflect2.ogg', 50, 1) - return 1 diff --git a/code/game/objects/items/weapons/whetstone.dm b/code/game/objects/items/weapons/whetstone.dm deleted file mode 100644 index 8c908965e13ae..0000000000000 --- a/code/game/objects/items/weapons/whetstone.dm +++ /dev/null @@ -1,77 +0,0 @@ -/obj/item/whetstone - name = "whetstone" - icon = 'icons/obj/kitchen.dmi' - icon_state = "whetstone" - desc = "A block of stone used to sharpen things." - w_class = WEIGHT_CLASS_SMALL - usesound = 'sound/items/screwdriver.ogg' - var/used = FALSE - var/increment = 4 - var/max = 30 - var/prefix = "sharpened" - var/requires_sharpness = TRUE - var/claw_damage_increase = 2 - - -/obj/item/whetstone/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(used) - to_chat(user, "The whetstone is too worn to use again!") - return - if(requires_sharpness && !I.sharp) - to_chat(user, "You can only sharpen items that are already sharp, such as knives!") - return - var/signal_out = SEND_SIGNAL(I, COMSIG_ITEM_SHARPEN_ACT, increment, max) - - if((signal_out & COMPONENT_BLOCK_SHARPEN_MAXED) || I.force >= max || I.throwforce >= max) //If the item's components enforce more limits on maximum power from sharpening, we fail - to_chat(user, "[I] is much too powerful to sharpen further!") - return - if(signal_out & COMPONENT_BLOCK_SHARPEN_BLOCKED) - to_chat(user, "[I] is not able to be sharpened right now!") - return - if((signal_out & COMPONENT_BLOCK_SHARPEN_ALREADY) || (I.force > initial(I.force) && !(signal_out & COMPONENT_SHARPEN_APPLIED))) //No sharpening stuff twice - to_chat(user, "[I] has already been refined before. It cannot be sharpened further!") - return - - if(!(signal_out & COMPONENT_SHARPEN_APPLIED)) //If the item has a relevant component and COMPONENT_BLOCK_SHARPEN_APPLIED is returned, the item only gets the throw force increase - I.force = clamp(I.force + increment, 0, max) - - user.visible_message("[user] sharpens [I] with [src]!", "You sharpen [I], making it much more deadly than before.") - if(!requires_sharpness) - set_sharpness(TRUE) - I.throwforce = clamp(I.throwforce + increment, 0, max) - I.name = "[prefix] [I.name]" - playsound(get_turf(src), usesound, 50, TRUE) - name = "worn out [name]" - desc = "[desc] At least, it used to." - used = TRUE - update_icon() - -/obj/item/whetstone/attack_self__legacy__attackchain(mob/user) - if(used) - to_chat(user, "The whetstone is too worn to use again!") - return - if(ishuman(user)) - var/mob/living/carbon/human/H = user - var/datum/unarmed_attack/attack = H.get_unarmed_attack() - if(istype(attack, /datum/unarmed_attack/claws)) - var/datum/unarmed_attack/claws/C = attack - if(!C.has_been_sharpened) - C.has_been_sharpened = TRUE - attack.damage += claw_damage_increase - H.visible_message("[H] sharpens [H.p_their()] claws on [src]!", "You sharpen your claws on [src].") - playsound(get_turf(H), usesound, 50, 1) - name = "worn out [name]" - desc = "[desc] At least, it used to." - used = TRUE - update_icon() - else - to_chat(user, "You can not sharpen your claws any further!") - -/obj/item/whetstone/super - name = "super whetstone block" - desc = "A block of stone that will make your weapon sharper than Einstein on adderall." - increment = 200 - max = 200 - prefix = "super-sharpened" - requires_sharpness = FALSE - claw_damage_increase = 200 diff --git a/code/game/objects/mail.dm b/code/game/objects/mail.dm deleted file mode 100644 index 86ec5986d2797..0000000000000 --- a/code/game/objects/mail.dm +++ /dev/null @@ -1,299 +0,0 @@ -/obj/item/envelope - name = "broken letter" - desc = "We just got a letter, we just got a letter, we just got a letter -- I wonder who it's from?" - force = 0 - throwforce = 0 - w_class = WEIGHT_CLASS_SMALL - icon = 'icons/obj/bureaucracy.dmi' - icon_state = "mail_misc" - item_state = "paper" - drop_sound = 'sound/items/handling/paper_drop.ogg' - pickup_sound = 'sound/items/handling/paper_pickup.ogg' - - var/list/possible_contents = list() - /// A list that contains the names of the jobs that can receive this type of letter. Only the base job has to be put in it, alternative titles have the same definition on the mind. Name of the job can be found in `mind.assigned_role` - var/list/job_list = list() - /// The real name required to open the letter - var/recipient - /// The job of the recipient - var/recipient_job - var/has_been_scanned = FALSE - -/obj/item/envelope/suicide_act(mob/user) - user.visible_message("[user] is licking a sharp corner of the envelope. It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/effects/-adminhelp.ogg', 50, TRUE, -1) - return BRUTELOSS - -/obj/item/envelope/attack_self__legacy__attackchain(mob/user) - if(!user?.mind) - return - if(user.real_name != recipient) - to_chat(user, "You don't want to open up another person's mail, that's an invasion of their privacy!") - return - if(do_after(user, 1 SECONDS, target = user) && !QDELETED(src)) - to_chat(user, "You begin to open the envelope.") - playsound(loc, 'sound/items/poster_ripped.ogg', 50, TRUE) - user.unequip(src) - for(var/obj/item/I in contents) - user.put_in_hands(I) - qdel(src) - -/obj/item/envelope/Initialize(mapload) - . = ..() - var/item = pick(possible_contents) - new item(src) - new /obj/item/stack/spacecash(src, rand(1, 50) * 5) - var/list/mind_copy = shuffle(SSticker.minds) - for(var/datum/mind/mail_attracted_people in mind_copy) - var/turf/T = get_turf(mail_attracted_people.current) - if(mail_attracted_people.offstation_role || !ishuman(mail_attracted_people.current) || is_admin_level(T.z)) - continue - if(mail_attracted_people.assigned_role in job_list) - recipient = mail_attracted_people.current.real_name - name = "letter to [recipient]" - recipient_job = lowertext(mail_attracted_people.assigned_role) - return - if(!admin_spawned) - log_debug("Failed to find a new name to assign to [src]!") - qdel(src) - -/obj/item/envelope/examine(mob/user) - . = ..() - . += "This letter is addressed to [recipient], the [recipient_job]." - -/obj/item/envelope/security - icon_state = "mail_sec" - possible_contents = list(/obj/item/food/donut/sprinkles, - /obj/item/megaphone, - /obj/item/clothing/mask/whistle, - /obj/item/poster/random_official, - /obj/item/restraints/handcuffs/pinkcuffs, - /obj/item/restraints/legcuffs/bola/energy, - /obj/item/reagent_containers/drinks/coffee, - /obj/item/stock_parts/cell/super, - /obj/item/grenade/barrier/dropwall, - /obj/item/toy/figure/crew/detective, - /obj/item/toy/figure/crew/hos, - /obj/item/toy/figure/crew/secofficer, - /obj/item/storage/box/scratch_cards) - job_list = list("Head of Security", "Security Officer", "Detective", "Warden") - -/obj/item/envelope/science - icon_state = "mail_sci" - possible_contents = list(/obj/item/analyzer, - /obj/item/assembly/signaler, - /obj/item/slime_extract/grey, - /obj/item/clothing/mask/gas, - /obj/item/reagent_containers/spray/cleaner, - /obj/item/clothing/glasses/regular, - /obj/item/stack/ore/diamond, // Jackpot - /obj/item/paicard, - /obj/item/toy/figure/crew/borg, - /obj/item/toy/figure/crew/geneticist, - /obj/item/toy/figure/crew/rd, - /obj/item/toy/figure/crew/roboticist, - /obj/item/toy/figure/crew/scientist, - /obj/item/storage/box/scratch_cards) - job_list = list("Research Director", "Roboticist", "Geneticist", "Scientist") - -/obj/item/envelope/supply - icon_state = "mail_sup" - possible_contents = list(/obj/item/reagent_containers/hypospray/autoinjector/survival, - /obj/item/reagent_containers/drinks/bottle/absinthe/premium, - /obj/item/clothing/glasses/meson/gar, - /obj/item/stack/marker_beacon/ten, - /obj/item/stack/medical/splint, - /obj/item/pen/multi/fountain, - /obj/item/clothing/mask/cigarette/cigar, - /obj/item/stack/wrapping_paper, - /obj/item/toy/figure/crew/cargotech, - /obj/item/toy/figure/crew/explorer, - /obj/item/toy/figure/crew/qm, - /obj/item/toy/figure/crew/miner, - /obj/item/storage/box/scratch_cards) - job_list = list("Quartermaster", "Cargo Technician", "Shaft Miner", "Explorer") - -/obj/item/envelope/medical - icon_state = "mail_med" - possible_contents = list(/obj/item/soap, - /obj/item/reagent_containers/glass/bottle/morphine, - /obj/item/reagent_containers/hypospray/safety, - /obj/item/reagent_containers/applicator/brute, - /obj/item/reagent_containers/applicator/burn, - /obj/item/clothing/glasses/sunglasses, - /obj/item/food/fortunecookie, - /obj/item/scalpel/laser/laser1, - /obj/item/surgical_drapes, - /obj/item/toy/figure/crew/cmo, - /obj/item/toy/figure/crew/chemist, - /obj/item/toy/figure/crew/geneticist, - /obj/item/toy/figure/crew/md, - /obj/item/toy/figure/crew/virologist, - /obj/item/storage/box/scratch_cards) - job_list = list("Chief Medical Officer", "Medical Doctor", "Coroner", "Chemist", "Virologist", "Psychiatrist", "Paramedic") - -/obj/item/envelope/engineering - icon_state = "mail_eng" - possible_contents = list(/obj/item/airlock_electronics, - /obj/item/reagent_containers/drinks/bottle/beer, - /obj/item/food/candy/confectionery/nougat, - /obj/item/mod/module/storage/large_capacity, - /obj/item/weldingtool/hugetank, - /obj/item/geiger_counter, - /obj/item/rcd_ammo, - /obj/item/grenade/gas/oxygen, - /obj/item/toy/figure/crew/atmos, - /obj/item/toy/figure/crew/ce, - /obj/item/toy/figure/crew/engineer, - /obj/item/storage/box/scratch_cards) - job_list = list("Chief Engineer", "Station Engineer", "Life Support Specialist") - -/obj/item/envelope/bread - icon_state = "mail_serv" - possible_contents = list(/obj/item/painter, - /obj/item/gun/energy/floragun, - /obj/item/reagent_containers/drinks/bottle/fernet, - /obj/item/whetstone, - /obj/item/soap/deluxe, - /obj/item/stack/tile/disco_light/thirty, - /obj/item/paicard, - /obj/item/gun/projectile/automatic/toy/pistol, - /obj/item/toy/figure/crew/bartender, - /obj/item/toy/figure/crew/botanist, - /obj/item/toy/figure/crew/chef, - /obj/item/toy/figure/crew/janitor, - /obj/item/toy/figure/crew/librarian, - /obj/item/storage/box/scratch_cards) - job_list = list("Bartender", "Chef", "Botanist", "Janitor", "Librarian") - -/obj/item/envelope/circuses - icon_state = "mail_serv" - possible_contents = list(/obj/item/painter, - /obj/item/stack/sheet/mineral/tranquillite/ten, - /obj/item/stack/sheet/mineral/bananium/ten, - /obj/item/reagent_containers/drinks/bottle/bottleofnothing, - /obj/item/gun/throw/piecannon, - /obj/item/ammo_box/shotgun/confetti, - /obj/item/book/manual/wiki/sop_security, // They'll need this. - /obj/item/soulstone/anybody/purified/chaplain, - /obj/item/toy/figure/crew/clown, - /obj/item/toy/figure/crew/hop, - /obj/item/toy/figure/crew/chaplain, - /obj/item/toy/figure/crew/mime, - /obj/item/storage/box/scratch_cards) - job_list = list("Clown", "Mime", "Head of Personnel", "Chaplain") - - -/obj/item/envelope/command - icon_state = "mail_com" - possible_contents = list(/obj/item/flash, - /obj/item/storage/fancy/cigarettes/cigpack_robustgold, - /obj/item/poster/random_official, - /obj/item/book/manual/wiki/sop_command, - /obj/item/reagent_containers/patch/synthflesh, - /obj/item/paper_bin/nanotrasen, - /obj/item/food/spesslaw, - /obj/item/clothing/head/collectable/petehat, - /obj/item/toy/figure/crew/captain, - /obj/item/toy/figure/crew/iaa, - /obj/item/toy/figure/crew/dsquad, - /obj/item/storage/box/scratch_cards) - job_list = list("Captain", "Magistrate", "Nanotrasen Representative", "Blueshield", "Internal Affairs Agent", "Nanotrasen Career Trainer") - -/obj/item/envelope/misc - possible_contents = list(/obj/item/clothing/under/misc/assistantformal, - /obj/item/clothing/under/syndicate/tacticool, - /obj/item/clothing/shoes/ducky, - /obj/item/toy/plushie/orange_fox/grump, // A grumpy plushie for a grumpy tider - /obj/item/multitool, - /obj/item/instrument/piano_synth, - /obj/item/toy/crayon/spraycan, - /obj/item/clothing/head/cakehat, - /obj/item/toy/figure/crew/assistant, - /obj/item/toy/figure/owl, - /obj/item/toy/figure/griffin, - /obj/item/storage/box/scratch_cards) - job_list = list("Assistant") - - - /*//////////////////////\/ - \/ \\ // \/ - \/ \\ // \/ - \/ \\ // \/ - \/ \\ // \/ - \/ \\// \/ - \/ \/ - \/ You've got: \/ - \/ Mail \/ - \/ \/ - \/\\\\\\\\\\\\\\\\\\\\\\*/ - -/obj/item/mail_scanner - name = "mail scanner" - desc = "Sponsored by Messaging and Intergalactic Letters, this device allows you to log mail deliveries in exchange for financial compensation." - force = 0 - throwforce = 0 - icon = 'icons/obj/device.dmi' - icon_state = "mail_scanner" - item_state = "mail_scanner" - lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' - righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT - w_class = WEIGHT_CLASS_SMALL - origin_tech = "magnets=1" - /// The reference to the envelope that is currently stored in the mail scanner. It will be cleared upon confirming a correct delivery - var/obj/item/envelope/saved - /// How far away can the scanner scan mail or people - var/scanner_range = 7 - -/obj/item/mail_scanner/examine(mob/user) - . = ..() - . += "Scan a letter to log it into the active database, then scan the person you wish to hand the letter to. Correctly scanning the recipient of the letter logged into the active database will add credits to the Supply budget." - -/obj/item/mail_scanner/attack__legacy__attackchain() - return - -/obj/item/mail_scanner/afterattack__legacy__attackchain(atom/A, mob/user) - if(get_dist(A, user) > scanner_range) - to_chat(user, "The scanner doesn't reach that far!") - return - if(istype(A, /obj/item/envelope)) - var/obj/item/envelope/envelope = A - if(envelope.has_been_scanned) - to_chat(user, "This letter has already been logged to the active database!") - playsound(loc, 'sound/mail/maildenied.ogg', 50, TRUE) - return - to_chat(user, "You add [envelope] to the active database.") - playsound(loc, 'sound/mail/mailscanned.ogg', 50, TRUE) - saved = A - SSblackbox.record_feedback("amount", "successful_mail_scan", 1) - return - if(isliving(A)) - var/mob/living/M = A - if(!saved) - to_chat(user, "Error: You have not logged mail to the mail scanner!") - playsound(loc, 'sound/mail/maildenied.ogg', 50, TRUE) - return - - if(M.stat == DEAD) - to_chat(user, "Consent Verification failed: You can't deliver mail to a corpse!") - playsound(loc, 'sound/mail/maildenied.ogg', 50, TRUE) - return - - if(M.real_name != saved.recipient) - to_chat(user, "'Identity Verification failed: Target is not an authorized recipient of this package!") - playsound(loc, 'sound/mail/maildenied.ogg', 50, TRUE) - return - - if(!M.client) - to_chat(user, "Consent Verification failed: The scanner will not accept confirmation of orders from SSD people!") - playsound(loc, 'sound/mail/maildenied.ogg', 50, TRUE) - return - - saved.has_been_scanned = TRUE - saved = null - to_chat(user, "Successful delivery acknowledged! [MAIL_DELIVERY_BONUS] credits added to Supply account!") - playsound(loc, 'sound/mail/mailapproved.ogg', 50, TRUE) - GLOB.station_money_database.credit_account(SSeconomy.cargo_account, MAIL_DELIVERY_BONUS, "Mail Delivery Compensation", "Messaging and Intergalactic Letters", supress_log = FALSE) - SSblackbox.record_feedback("amount", "successful_mail_delivery", 1) diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm deleted file mode 100644 index 1a80c3bac7c24..0000000000000 --- a/code/game/objects/structures/aliens.dm +++ /dev/null @@ -1,574 +0,0 @@ -/* Alien structures! - * Contains: - * structure/alien - * Resin - * Weeds - * Eggs - */ - -#define WEED_NORTH_EDGING "north" -#define WEED_SOUTH_EDGING "south" -#define WEED_EAST_EDGING "east" -#define WEED_WEST_EDGING "west" - -/obj/structure/alien - icon = 'icons/mob/alien.dmi' - max_integrity = 100 - -/obj/structure/alien/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == MELEE) - switch(damage_type) - if(BRUTE) - damage_amount *= 0.25 - if(BURN) - damage_amount *= 2 - . = ..() - -/obj/structure/alien/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - 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) - -/* - * Resin - */ -/obj/structure/alien/resin - name = "resin" - desc = "Looks like some kind of thick resin." - icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi' - icon_state = "resin_wall-0" - base_icon_state = "resin_wall" - density = TRUE - opacity = TRUE - anchored = TRUE - smoothing_flags = SMOOTH_BITMASK - smoothing_groups = list(SMOOTH_GROUP_ALIEN_RESIN) - canSmoothWith = list(SMOOTH_GROUP_ALIEN_RESIN) - max_integrity = 200 - var/resintype = null - var/is_alien = TRUE - -/obj/structure/alien/resin/Initialize(mapload) - recalculate_atmos_connectivity() - if(!is_alien) - return ..() - for(var/obj/structure/alien/weeds/node/W in get_turf(src)) - qdel(W) - if(locate(/obj/structure/alien/weeds) in get_turf(src)) - return ..() - new /obj/structure/alien/weeds(loc, src) - return ..() - -/obj/structure/alien/resin/Destroy() - var/turf/T = get_turf(src) - playsound(loc, 'sound/effects/alien_resin_break2.ogg', 100, TRUE) - . = ..() - T.recalculate_atmos_connectivity() - -/obj/structure/alien/resin/Move() - var/turf/T = loc - ..() - move_update_air(T) - -/obj/structure/alien/resin/CanAtmosPass(direction) - return !density - -/obj/structure/alien/resin/attack_alien(mob/living/carbon/alien/humanoid/user) - if(user.a_intent != INTENT_HARM) - return - to_chat(user, "We begin tearing down this resin structure.") - if(!do_after(user, 40, target = src) || QDELETED(src)) - return - qdel(src) - -/obj/structure/alien/resin/wall - name = "resin wall" - desc = "Thick resin solidified into a wall." - icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi' - icon_state = "resin_wall-0" - base_icon_state = "resin_wall" - smoothing_groups = list(SMOOTH_GROUP_ALIEN_RESIN, SMOOTH_GROUP_ALIEN_WALLS) - canSmoothWith = list(SMOOTH_GROUP_ALIEN_WALLS) - -/obj/structure/alien/resin/wall/get_superconductivity(direction) - return FALSE - -/* - *Resin-Door - Borrows its code from Mineral-Door, not a subtype due to needing many overrides if so -*/ -/obj/structure/alien/resin/door - name = "resin door" - density = TRUE - anchored = TRUE - opacity = TRUE - - icon = 'icons/obj/smooth_structures/alien/resin_door.dmi' - icon_state = "resin" - base_icon_state = "resin" - max_integrity = 60 - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50) - damage_deflection = 0 - flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2 - rad_insulation = RAD_MEDIUM_INSULATION - var/initial_state - var/state_open = FALSE - var/is_operating = FALSE - var/close_delay = 3 SECONDS - smoothing_flags = null - var/open_sound = 'sound/machines/alien_airlock.ogg' - var/close_sound = 'sound/machines/alien_airlock.ogg' - - smoothing_groups = list(SMOOTH_GROUP_ALIEN_RESIN, SMOOTH_GROUP_ALIEN_WALLS) - canSmoothWith = list(SMOOTH_GROUP_ALIEN_WALLS) - -/obj/structure/alien/resin/door/Initialize(mapload) - . = ..() - initial_state = icon_state - QUEUE_SMOOTH_NEIGHBORS(src) - -/obj/structure/alien/resin/door/Destroy() - density = FALSE - QUEUE_SMOOTH_NEIGHBORS(src) - recalculate_atmos_connectivity() - return ..() - -/obj/structure/alien/resin/door/Move() - var/turf/T = loc - . = ..() - move_update_air(T) - -/obj/structure/alien/resin/door/attack_ai(mob/user) - return - -/obj/structure/alien/resin/door/attack_hand(mob/user) - return try_to_operate(user) - -/obj/structure/alien/resin/door/attack_ghost(mob/user) - if(user.can_advanced_admin_interact()) - operate() - -/obj/structure/alien/resin/door/CanAtmosPass(direction) - return !density - -/obj/structure/alien/resin/door/proc/try_to_operate(mob/user, bumped_open = FALSE) - if(is_operating) - return - if(!iscarbon(user)) - return - var/mob/living/carbon/C = user - if(C.get_int_organ(/obj/item/organ/internal/alien/hivenode)) - if(!C.handcuffed) - operate(bumped_open) - return - to_chat(user, "Your lack of connection to the hive prevents the resin door from opening") -/* - * This 2nd try_to_operate() is needed so that CALLBACK can close the door without having to either call operate() and get bugged when clicked much or - * call try_to_operate(atom/user) and not be able to use it due to not having a mob using it -*/ -/obj/structure/alien/resin/door/proc/mobless_try_to_operate() - if(is_operating) - if(state_open) - addtimer(CALLBACK(src, PROC_REF(mobless_try_to_operate)), close_delay) - return - operate() - -/obj/structure/alien/resin/door/proc/operate(bumped_open = FALSE) - is_operating = TRUE - if(!state_open) - playsound(loc, open_sound, 50, TRUE) - flick("[initial_state]opening", src) - else - for(var/mob/living/L in get_turf(src)) - is_operating = FALSE - if(state_open) - addtimer(CALLBACK(src, PROC_REF(mobless_try_to_operate)), close_delay) - return - playsound(loc, close_sound, 50, 1) - flick("[initial_state]closing", src) - density = !density - opacity = !opacity - state_open = !state_open - addtimer(CALLBACK(src, PROC_REF(operate_update), bumped_open), 1 SECONDS) - -/obj/structure/alien/resin/door/proc/operate_update(bumped_open) - recalculate_atmos_connectivity() - update_icon(UPDATE_ICON_STATE) - is_operating = FALSE - - if(state_open && bumped_open) - addtimer(CALLBACK(src, PROC_REF(mobless_try_to_operate)), close_delay) - -/obj/structure/alien/resin/door/update_icon_state() - icon_state = state_open ? "[initial_state]open" : initial_state - -/obj/structure/alien/resin/door/attack_alien(mob/living/carbon/alien/humanoid/user) - if(user.a_intent != INTENT_HARM) - try_to_operate(user) - return - to_chat(user, "We begin tearing down this resin structure.") - if(!do_after(user, 40, target = src) || QDELETED(src)) - return - qdel(src) - -/obj/structure/alien/resin/door/Bumped(atom/user) - ..() - if(!state_open) - return try_to_operate(user, TRUE) - -/* - * Weeds - */ - -#define NODERANGE 3 - -/obj/structure/alien/weeds - gender = PLURAL - name = "resin floor" - desc = "A thick resin surface covers the floor." - anchored = TRUE - density = FALSE - plane = FLOOR_PLANE - icon = 'icons/obj/smooth_structures/alien/weeds.dmi' - icon_state = "weeds" - base_icon_state = "weeds" - max_integrity = 15 - layer = ABOVE_ICYOVERLAY_LAYER - smoothing_flags = SMOOTH_BITMASK - smoothing_groups = list(SMOOTH_GROUP_ALIEN_RESIN, SMOOTH_GROUP_ALIEN_WEEDS) - canSmoothWith = list(SMOOTH_GROUP_ALIEN_WEEDS, SMOOTH_GROUP_WALLS) - creates_cover = TRUE - var/obj/structure/alien/weeds/node/linked_node = null - var/obj/structure/alien/wallweed/wall_weed // This var is used to handle wall-weed interactions for when they need to be deleted - var/static/list/weedImageCache - var/check_counter // This var is how many process() procs it takes for a weed to spread - /// This var is used for making automatic weed removals silent instead of making them produce the breaking sound - var/silent_removal = FALSE - -/obj/structure/alien/weeds/Initialize(mapload, node) - . = ..() - linked_node = node - if(isspaceturf(loc)) - qdel(src) - return - check_surroundings() - START_PROCESSING(SSobj, src) - RegisterSignal(linked_node, COMSIG_PARENT_QDELETING, PROC_REF(clear_linked_node)) - -/obj/structure/alien/weeds/Destroy() - STOP_PROCESSING(SSobj, src) - QUEUE_SMOOTH_NEIGHBORS(src) - if(!silent_removal) - playsound(loc, pick('sound/effects/alien_resin_break2.ogg','sound/effects/alien_resin_break1.ogg'), 50, FALSE) - linked_node = null - clear_wall_weed() - return ..() - -/obj/structure/alien/weeds/proc/clear_linked_node() - SIGNAL_HANDLER - UnregisterSignal(linked_node, COMSIG_PARENT_QDELETING) - linked_node = null - -/obj/structure/alien/weeds/attack_alien(mob/living/carbon/alien/humanoid/user) - if(user.a_intent != INTENT_HARM) - return - return ..() - -/obj/structure/alien/weeds/process() - check_counter++ - if(check_counter >= 5) - spread() - check_counter = 0 - -/obj/structure/alien/weeds/proc/clear_wall_weed() - if(wall_weed && !QDELETED(wall_weed)) - wall_weed.weed = null - wall_weed.silent_removal = TRUE - QDEL_NULL(wall_weed) - -/obj/structure/alien/weeds/proc/check_surroundings() - var/turf/T = get_turf(src) - var/list/nearby_dense_turfs = T.AdjacentTurfs(cardinal_only = FALSE, dense_only = TRUE) - if(!length(nearby_dense_turfs)) // There is no dense turfs around it - clear_wall_weed() - return - - var/list/wall_dirs = list() - for(var/turf/W in nearby_dense_turfs) - if(iswallturf(W)) - wall_dirs.Add(get_dir(W, T)) - if(!length(wall_dirs)) // There is no walls around it - clear_wall_weed() - return - - var/list/nearby_open_turfs = T.AdjacentTurfs(open_only = TRUE, cardinal_only = TRUE) - - for(var/turf/W in nearby_open_turfs) // This handles removal of corner-weeds when they are to be replaced with a full side-weed instead - if(locate(/obj/structure/alien/weeds, W)) - var/dirs = get_dir(W, T) - switch(dirs) - if(NORTH) - wall_dirs.Remove(NORTHEAST, NORTHWEST) - if(SOUTH) - wall_dirs.Remove(SOUTHEAST, SOUTHWEST) - if(EAST) - wall_dirs.Remove(NORTHEAST, SOUTHEAST) - if(WEST) - wall_dirs.Remove(NORTHWEST, SOUTHWEST) - - if(!length(wall_dirs)) // No weeds will be applied, better off deleting it - clear_wall_weed() - return - - if(!wall_weed || QDELETED(wall_weed)) - wall_weed = new /obj/structure/alien/wallweed(T, src) - - wall_weed.compare_overlays(wall_dirs) - -/obj/structure/alien/weeds/proc/spread() - var/turf/U = get_turf(src) - - if(isspaceturf(U)) - qdel(src) - return - - if(!linked_node) - if(prob(20)) - silent_removal = TRUE - qdel(src) - return - - if((istype(linked_node, /obj/structure/alien/resin/door)) || (istype(linked_node, /obj/structure/alien/resin/wall))) - return - - if(get_dist(linked_node, src) > linked_node.node_range) /*!linked_node || */ - return - - for(var/turf/T in U.GetAtmosAdjacentTurfs()) - if((locate(/obj/structure/alien/weeds) in T) || isspaceturf(T) || islava(T) || ischasm(T)) - continue - new /obj/structure/alien/weeds(T, linked_node) - check_surroundings() - -/obj/structure/alien/weeds/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ..() - if(exposed_temperature > 300) - take_damage(5, BURN, 0, 0) - -/* - * Wall Weeds - */ - -/obj/structure/alien/wallweed - name = "resin overgrowth" - desc = "A thick resin surface covers the wall." - icon = 'icons/obj/smooth_structures/alien/weeds.dmi' - icon_state = null - anchored = TRUE - layer = ABOVE_WINDOW_LAYER - plane = GAME_PLANE - - max_integrity = 15 - var/obj/structure/alien/weeds/weed - var/list/overlay_list = list() - /// This var is used for making automatic weed removals silent instead of making them produce the breaking sound - var/silent_removal = FALSE - -/obj/structure/alien/wallweed/Initialize(mapload, weed_owner) - . = ..() - weed = weed_owner - -/obj/structure/alien/wallweed/Destroy() - if(!silent_removal) - playsound(loc, pick('sound/effects/alien_resin_break2.ogg','sound/effects/alien_resin_break1.ogg'), 50, FALSE) - if(weed) - weed.wall_weed = null - return ..() - -/obj/structure/alien/wallweed/proc/compare_overlays(list/wall_dirs) - if(overlay_list != wall_dirs) - overlay_list = wall_dirs - update_icon(UPDATE_OVERLAYS) - -/obj/structure/alien/wallweed/update_overlays() - . = ..() - if(!length(overlay_list)) - return - for(var/dirs in overlay_list) - var/image/I = image(icon, icon_state = "wallweed-[dirs]") - switch(dirs) - if(NORTH, NORTHEAST, NORTHWEST) - I.pixel_y = -32 - if(SOUTH, SOUTHEAST, SOUTHWEST) - I.pixel_y = 32 - switch(dirs) - if(EAST, NORTHEAST, SOUTHEAST) - I.pixel_x = -32 - if(WEST, NORTHWEST, SOUTHWEST) - I.pixel_x = 32 - I.layer = BELOW_MOB_LAYER - . += I - -/obj/structure/alien/wallweed/attack_alien(mob/living/carbon/alien/humanoid/user) - if(user.a_intent != INTENT_HARM) - return - return ..() - -/* - * Weed nodes - */ - -/obj/structure/alien/weeds/node - name = "resin node" - desc = "A large bulbous node pumping resin into the surface bellow it." - icon = 'icons/obj/smooth_structures/alien/weeds.dmi' - icon_state = "weeds" - base_icon_state = "weeds" - light_range = 1 - var/node_range = NODERANGE - - -/obj/structure/alien/weeds/node/Initialize(mapload) - add_overlay("weednode") - return ..(loc, src) - -#undef NODERANGE - - -/* - * Egg - */ - -///Used in the /status var -#define BURST 0 -#define BURSTING 1 -#define GROWING 2 -#define GROWN 3 -///time it takes to grow a hugger -#define MIN_GROWTH_TIME 2 MINUTES -#define MAX_GROWTH_TIME 3 MINUTES - -/obj/structure/alien/egg - name = "egg" - desc = "A large mottled egg." - icon_state = "egg_growing" - density = FALSE - anchored = TRUE - max_integrity = 100 - integrity_failure = 5 - layer = MOB_LAYER - flags_2 = CRITICAL_ATOM_2 - /*can be GROWING, GROWN or BURST; all mutually exclusive. GROWING has the egg in the grown state, and it will take 180-300 seconds for it to advance to the hatched state - *In the GROWN state, an alien egg can be destroyed or attacked by a xenomorph to force it to be burst, going near an egg in this state will also cause it to burst if you can be infected by a face hugger - *In the BURST/BURSTING state, the alien egg can be removed by being attacked by a alien or any other weapon - **/ - var/status = GROWING - var/datum/proximity_monitor/proximity_monitor - -/obj/structure/alien/egg/grown - status = GROWN - icon_state = "egg" - -/obj/structure/alien/egg/burst - status = BURST - icon_state = "egg_hatched" - -/obj/structure/alien/egg/Initialize(mapload) - . = ..() - new /obj/item/clothing/mask/facehugger(src) - if(status == BURST) - obj_integrity = integrity_failure - else if(status != GROWN) - addtimer(CALLBACK(src, PROC_REF(grow)), rand(MIN_GROWTH_TIME, MAX_GROWTH_TIME)) - if(status == GROWN) - proximity_monitor = new(src) - -/obj/structure/alien/egg/attack_alien(mob/living/carbon/alien/user) - return attack_hand(user) - -/obj/structure/alien/egg/attack_hand(mob/living/user) - if(user.get_int_organ(/obj/item/organ/internal/alien/plasmavessel)) - switch(status) - if(BURST) - to_chat(user, "You clear the hatched egg.") - playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) - qdel(src) - return - if(GROWING) - to_chat(user, "The child is not developed yet.") - return - if(GROWN) - to_chat(user, "You retrieve the child.") - burst(FALSE) - return - else - to_chat(user, "It feels slimy.") - user.changeNext_move(CLICK_CD_MELEE) - - -/obj/structure/alien/egg/proc/getFacehugger() - return locate(/obj/item/clothing/mask/facehugger) in contents - -/obj/structure/alien/egg/proc/grow() - icon_state = "egg" - status = GROWN - proximity_monitor = new(src) - -///Need to carry the kill from Burst() to Hatch(), this section handles the alien opening the egg -/obj/structure/alien/egg/proc/burst(kill) - if(status == GROWN || status == GROWING) - icon_state = "egg_hatched" - flick("egg_opening", src) - status = BURSTING - QDEL_NULL(proximity_monitor) - addtimer(CALLBACK(src, PROC_REF(hatch)), 1.5 SECONDS) - -///We now check HOW the hugger is hatching, kill carried from Burst() and obj_break() -/obj/structure/alien/egg/proc/hatch(kill) - status = BURST - var/obj/item/clothing/mask/facehugger/child = getFacehugger() - child.forceMove(get_turf(src)) - if(kill) - child.Die() - for(var/mob/M in range(1, src)) - if(CanHug(M)) - child.Attach(M) - break - -/obj/structure/alien/egg/obj_break(damage_flag) - if(!(flags & NODECONSTRUCT)) - if(status != BURST) - burst(kill = TRUE) - -/obj/structure/alien/egg/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ..() - if(exposed_temperature > 500) - take_damage(5, BURN, 0, 0) - -/obj/structure/alien/egg/HasProximity(atom/movable/AM) - if(status == GROWN) - if(!CanHug(AM)) - return - - var/mob/living/carbon/C = AM - if(C.stat == CONSCIOUS && C.get_int_organ(/obj/item/organ/internal/body_egg/alien_embryo)) - return - - burst(FALSE) - -#undef BURST -#undef BURSTING -#undef GROWING -#undef GROWN -#undef MIN_GROWTH_TIME -#undef MAX_GROWTH_TIME - -#undef WEED_NORTH_EDGING -#undef WEED_SOUTH_EDGING -#undef WEED_EAST_EDGING -#undef WEED_WEST_EDGING diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm deleted file mode 100644 index 13248507e26f8..0000000000000 --- a/code/game/objects/structures/bedsheet_bin.dm +++ /dev/null @@ -1,394 +0,0 @@ -/* -CONTAINS: -BEDSHEETS -LINEN BINS -*/ - -/obj/item/bedsheet - name = "bedsheet" - desc = "A surprisingly soft linen bedsheet." - icon = 'icons/obj/bedsheet.dmi' - icon_state = "sheet" - lefthand_file = 'icons/mob/inhands/bedsheet_lefthand.dmi' - righthand_file = 'icons/mob/inhands/bedsheet_righthand.dmi' - layer = 4 - throwforce = 1 - throw_speed = 1 - throw_range = 2 - w_class = WEIGHT_CLASS_TINY - item_color = "white" - resistance_flags = FLAMMABLE - slot_flags = ITEM_SLOT_NECK - dog_fashion = /datum/dog_fashion/head/ghost - dyeable = TRUE - dyeing_key = DYE_REGISTRY_BEDSHEET - - var/list/dream_messages = list("white") - var/list/nightmare_messages = list("black") - var/comfort = 0.5 - -/obj/item/bedsheet/Initialize(mapload) - . = ..() - AddComponent(/datum/component/surgery_initiator/cloth, null, 0.45) // honestly, not bad. - -/obj/item/bedsheet/attack_hand(mob/user) - if(isturf(loc) && user.Move_Pulled(src)) // make sure its on the ground first, prevents a speed exploit - return - return ..() - -/obj/item/bedsheet/attack_self__legacy__attackchain(mob/user as mob) - user.drop_item() - if(layer == initial(layer)) - layer = 5 - else - layer = initial(layer) - add_fingerprint(user) - return - -/obj/item/bedsheet/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(I.sharp) - var/obj/item/stack/sheet/cloth/C = new (get_turf(src), 3) - transfer_fingerprints_to(C) - C.add_fingerprint(user) - to_chat(user, "You tear [src] up.") - qdel(src) - else - return ..() - -/obj/item/bedsheet/blue - icon_state = "sheetblue" - item_state = "bedsheetblue" - item_color = "blue" - dream_messages = list("blue") - nightmare_messages = list("vox blood") - -/obj/item/bedsheet/green - icon_state = "sheetgreen" - item_state = "bedsheetgreen" - item_color = "green" - dream_messages = list("green") - nightmare_messages = list("unathi flesh") - -/obj/item/bedsheet/orange - icon_state = "sheetorange" - item_state = "bedsheetorange" - item_color = "orange" - dream_messages = list("orange") - nightmare_messages = list("exploding fruit") - -/obj/item/bedsheet/purple - icon_state = "sheetpurple" - item_state = "bedsheetpurple" - item_color = "purple" - dream_messages = list("purple") - nightmare_messages = list("Grey blood") - -/obj/item/bedsheet/patriot - name = "patriotic bedsheet" - desc = "You've never felt more free than when sleeping on this." - icon_state = "sheetUSA" - item_state = "bedsheetUSA" - item_color = "sheetUSA" - dream_messages = list("America", "freedom", "fireworks", "bald eagles") - nightmare_messages = list("communism") - -/obj/item/bedsheet/rainbow - name = "rainbow bedsheet" - desc = "A multi_colored blanket. It's actually several different sheets cut up and sewn together." - icon_state = "sheetrainbow" - item_state = "bedsheetrainbow" - item_color = "rainbow" - dream_messages = list("red", "orange", "yellow", "green", "blue", "purple", "a rainbow") - nightmare_messages = list("green", "a cluwne", "fLoOr ClUwNe") - -/obj/item/bedsheet/red - icon_state = "sheetred" - item_state = "bedsheetred" - item_color = "red" - dream_messages = list("red") - nightmare_messages = list("gibs") - -/obj/item/bedsheet/yellow - icon_state = "sheetyellow" - item_state = "bedsheetyellow" - item_color = "yellow" - dream_messages = list("yellow") - nightmare_messages = list("locker full of banana peels") - -/obj/item/bedsheet/black - icon_state = "sheetblack" - item_state = "bedsheetblack" - item_color = "black" - dream_messages = list("black") - nightmare_messages = list("the void of space") - -/obj/item/bedsheet/mime - name = "mime's blanket" - desc = "A very soothing striped blanket. All the noise just seems to fade out when you're under the covers in this." - icon_state = "sheetmime" - item_state = "bedsheetmime" - item_color = "mime" - dream_messages = list("silence", "gestures", "a pale face", "a gaping mouth", "the mime") - nightmare_messages = list("honk", "laughter", "a prank", "a joke", "a smiling face", "the clown") - -/obj/item/bedsheet/clown - name = "clown's blanket" - desc = "A rainbow blanket with a clown mask woven in. It smells faintly of bananas." - icon_state = "sheetclown" - item_state = "bedsheetclown" - item_color = "clown" - dream_messages = list("honk", "laughter", "a prank", "a joke", "a smiling face", "the clown") - nightmare_messages = list("silence", "gestures", "a pale face", "a gaping mouth", "the mime") - -/obj/item/bedsheet/captain - name = "captain's bedsheet." - desc = "It has a Nanotrasen symbol on it, and was woven with a revolutionary new kind of thread guaranteed to have 0.01% permeability for most non-chemical substances, popular among most modern captains." - icon_state = "sheetcaptain" - item_state = "bedsheetcaptain" - item_color = "captain" - dream_messages = list("authority", "a golden ID", "sunglasses", "a green disc", "an antique gun", "the captain") - nightmare_messages = list("comdom", "clown with all access", "the syndicate") - -/obj/item/bedsheet/rd - name = "research director's bedsheet" - desc = "It appears to have a beaker emblem, and is made out of fire-resistant material, although it probably won't protect you in the event of fires you're familiar with every day." - icon_state = "sheetrd" - item_state = "bedsheetrd" - item_color = "director" - dream_messages = list("authority", "a silvery ID", "a bomb", "a mech", "a facehugger", "maniacal laughter", "the research director") - nightmare_messages = list("toxins full of plasma", "UPGRADE THE SLEEPERS", "rogue ai") - -/obj/item/bedsheet/rd/royal_cape - name = "Royal Cape of the Liberator" - desc = "Majestic." - dream_messages = list("mining", "stone", "a golem", "freedom", "doing whatever") - -/obj/item/bedsheet/medical - name = "medical blanket" - desc = "It's a sterilized* blanket commonly used in the Medbay. *Sterilization is voided if a virologist is present onboard the station." - icon_state = "sheetmedical" - item_state = "bedsheetmedical" - item_color = "medical" - dream_messages = list("healing", "life", "surgery", "a doctor") - nightmare_messages = list("death", "no cryox", "cryo is off") - -/obj/item/bedsheet/cmo - name = "chief medical officer's bedsheet" - desc = "It's a sterilized blanket that has a cross emblem. There's some cat fur on it, likely from Runtime." - icon_state = "sheetcmo" - item_state = "bedsheetcmo" - item_color = "cmo" - dream_messages = list("authority", "a silvery ID", "healing", "life", "surgery", "a cat", "the chief medical officer") - nightmare_messages = list("chemists making meth", "cryo it off", "where is the defib", "no biomass") - -/obj/item/bedsheet/hos - name = "head of security's bedsheet" - desc = "It is decorated with a shield emblem. While crime doesn't sleep, you do, but you are still THE LAW!" - icon_state = "sheethos" - item_state = "bedsheethos" - item_color = "hosred" - dream_messages = list("authority", "a silvery ID", "handcuffs", "a baton", "a flashbang", "sunglasses", "the head of security") - nightmare_messages = list("the clown", "a toolbox", "sHiTcUrItY", "why did you put them in for 50 minutes") - -/obj/item/bedsheet/hop - name = "head of personnel's bedsheet" - desc = "It is decorated with a key emblem. For those rare moments when you can rest and cuddle with Ian without someone screaming for you over the radio." - icon_state = "sheethop" - item_state = "bedsheethop" - item_color = "hop" - dream_messages = list("authority", "a silvery ID", "obligation", "a computer", "an ID", "a corgi", "the head of personnel") - nightmare_messages = list("improper paperwork", "all access clown", "50 open clown slots", "dead ian") - -/obj/item/bedsheet/ce - name = "chief engineer's bedsheet" - desc = "It is decorated with a wrench emblem. It's highly reflective and stain resistant, so you don't need to worry about ruining it with oil." - icon_state = "sheetce" - item_state = "bedsheetce" - item_color = "chief" - dream_messages = list("authority", "a silvery ID", "the engine", "power tools", "an APC", "a parrot", "the chief engineer") - nightmare_messages = list("forced airlock", "syndicate bomb", "explosion in research chem", "iT's LoOsE") - -/obj/item/bedsheet/qm - name = "quartermaster's bedsheet" - desc = "It is decorated with a crate emblem in silver lining. It's rather tough, and just the thing to lie on after a hard day of pushing paper." - icon_state = "sheetqm" - item_state = "bedsheetqm" - item_color = "qm" - dream_messages = list("a grey ID", "a shuttle", "a crate", "a sloth", "the quartermaster") - nightmare_messages = list("a bald person", "no points", "wheres the ore", "space carp") - -/obj/item/bedsheet/brown - icon_state = "sheetbrown" - item_state = "bedsheetbrown" - item_color = "cargo" - dream_messages = list("brown") - nightmare_messages = list("dead monkey") - -/obj/item/bedsheet/centcom - name = "centcom bedsheet" - desc = "Woven with advanced nanothread for warmth as well as being very decorated, essential for all officials." - icon_state = "sheetcentcom" - item_state = "bedsheetcentcom" - item_color = "centcom" - dream_messages = list("a unique ID", "authority", "artillery", "an ending") - nightmare_messages = list("a butt fax") - -/obj/item/bedsheet/syndie - name = "syndicate bedsheet" - desc = "It has a syndicate emblem and it has an aura of evil." - icon_state = "sheetsyndie" - item_state = "bedsheetsyndie" - item_color = "syndie" - dream_messages = list("a green disc", "a red crystal", "a glowing blade", "a wire-covered ID") - nightmare_messages = list("stunbaton", "taser", "lasers", "a toolbox") - -/obj/item/bedsheet/cult - name = "cultist's bedsheet" - desc = "You might dream of Nar'Sie if you sleep with this. It seems rather tattered and glows of an eldritch presence." - icon_state = "sheetcult" - item_state = "bedsheetcult" - item_color = "cult" - dream_messages = list("a tome", "a floating red crystal", "a glowing sword", "a bloody symbol", "a massive humanoid figure") - nightmare_messages = list("a tome", "a floating red crystal", "a glowing sword", "a bloody symbol", "a massive humanoid figure") - -/obj/item/bedsheet/clockwork - name = "Ratvarian bedsheet" - desc = "You might dream of Ratvar if you sleep with this. The fabric has threads of brass sewn into it which eminate a pleasent warmth." - icon_state = "sheetclockwork" - item_state = "bedsheetclockwork" - item_color = "brass" - dream_messages = list("tick, tock, tick, tock, tick, tock, tick, tock", "a great shining city of brass", "men in radiant suits of brass", "a perfect blueprint of the world", "a glowing cogwheel", "a massive humanoid figure") - nightmare_messages = list("\"the Nar'Sian dogs shall be CRUSHED!\"", "the unenlightened, ready to hear His word", "a half-buried brass titan", "two massive humanoid figures attacking each other") - -/obj/item/bedsheet/wiz - name = "wizard's bedsheet" - desc = "A special fabric enchanted with magic so you can have an enchanted night. It even glows!" - icon_state = "sheetwiz" - item_state = "bedsheetwiz" - item_color = "wiz" - dream_messages = list("a book", "an explosion", "lightning", "a staff", "a skeleton", "a robe", "magic") - nightmare_messages = list("a toolbox", "solars") - -/obj/structure/bedsheetbin - name = "linen bin" - desc = "A linen bin. It looks rather cozy." - icon = 'icons/obj/structures.dmi' - icon_state = "linenbin-full" - anchored = TRUE - resistance_flags = FLAMMABLE - max_integrity = 70 - var/amount = 20 - var/list/sheets = list() - var/obj/item/hidden = null - -/obj/structure/bedsheetbin/Destroy() - QDEL_LIST_CONTENTS(sheets) - if(hidden) - hidden.forceMove(get_turf(src)) - hidden = null - return ..() - - -/obj/structure/bedsheetbin/examine(mob/user) - . = ..() - if(amount < 1) - . += "There are no bed sheets in the bin." - else if(amount == 1) - . += "There is one bed sheet in the bin." - else - . += "There are [amount] bed sheets in the bin." - - -/obj/structure/bedsheetbin/update_icon_state() - switch(amount) - if(0) - icon_state = "linenbin-empty" - if(1 to 6) - icon_state = "linenbin-few" - if(7 to 15) - icon_state = "linenbin-half" - else - icon_state = "linenbin-full" - -/obj/structure/bedsheetbin/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - if(amount) - amount = 0 - update_icon() - ..() - -/obj/structure/bedsheetbin/burn() - amount = 0 - extinguish() - update_icon() - -/obj/structure/bedsheetbin/wrench_act(mob/user, obj/item/I) - if(user.a_intent == INTENT_HARM) - default_unfasten_wrench(user, I, time = 20) - return TRUE - -/obj/structure/bedsheetbin/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/bedsheet)) - if(!user.drop_item()) - to_chat(user, "[I] is stuck to your hand!") - return - I.forceMove(src) - sheets.Add(I) - amount++ - update_icon(UPDATE_ICON_STATE) - to_chat(user, "You put [I] in [src].") - else if(amount && !hidden && I.w_class < WEIGHT_CLASS_BULKY) //make sure there's sheets to hide it among, make sure nothing else is hidden in there. - if(I.flags & ABSTRACT) - return - if(!user.drop_item()) - to_chat(user, "[I] is stuck to your hand!") - return - I.forceMove(src) - hidden = I - to_chat(user, "You hide [I] among the sheets.") - - - -/obj/structure/bedsheetbin/attack_hand(mob/user) - if(amount >= 1) - amount-- - - var/obj/item/bedsheet/B - if(length(sheets) > 0) - B = sheets[length(sheets)] - sheets.Remove(B) - - else - B = new /obj/item/bedsheet(loc) - - B.loc = user.loc - user.put_in_hands(B) - to_chat(user, "You take [B] out of [src].") - - if(hidden) - hidden.loc = user.loc - to_chat(user, "[hidden] falls out of [B]!") - hidden = null - update_icon(UPDATE_ICON_STATE) - - add_fingerprint(user) - - -/obj/structure/bedsheetbin/attack_tk(mob/user) - if(amount >= 1) - amount-- - - var/obj/item/bedsheet/B - if(length(sheets) > 0) - B = sheets[length(sheets)] - sheets.Remove(B) - - else - B = new /obj/item/bedsheet(loc) - - B.loc = loc - to_chat(user, "You telekinetically remove [B] from [src].") - update_icon(UPDATE_ICON_STATE) - - if(hidden) - hidden.loc = loc - hidden = null diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm deleted file mode 100644 index 71c1a23724825..0000000000000 --- a/code/game/objects/structures/coathanger.dm +++ /dev/null @@ -1,52 +0,0 @@ -/obj/structure/coatrack - name = "coat rack" - desc = "Rack that holds coats." - icon = 'icons/obj/coatrack.dmi' - icon_state = "coatrack0" - var/obj/item/clothing/suit/coat - var/list/allowed = list(/obj/item/clothing/suit/storage/labcoat, /obj/item/clothing/suit/storage/det_suit) - -/obj/structure/coatrack/attack_hand(mob/user) - if(isnull(coat)) - return - user.visible_message("[user] takes [coat] off [src].", "You take [coat] off [src]") - if(!user.put_in_active_hand(coat)) - coat.forceMove(get_turf(user)) - coat = null - update_icon(UPDATE_OVERLAYS) - -/obj/structure/coatrack/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) - var/can_hang = FALSE - for(var/T in allowed) - if(istype(W,T)) - can_hang = TRUE - if(can_hang && !coat) - user.visible_message("[user] hangs [W] on \the [src].", "You hang [W] on the \the [src]") - coat = W - user.drop_item(src) - coat.forceMove(src) - update_icon(UPDATE_OVERLAYS) - return - return ..() - -/obj/structure/coatrack/CanPass(atom/movable/mover, border_dir) - var/can_hang = FALSE - for(var/T in allowed) - if(istype(mover,T)) - can_hang = TRUE - if(can_hang && !coat) - visible_message("[mover] lands on \the [src].") - coat = mover - coat.forceMove(src) - update_icon(UPDATE_OVERLAYS) - return - return ..() - -/obj/structure/coatrack/update_overlays() - . = ..() - if(istype(coat, /obj/item/clothing/suit/storage/labcoat)) - . += "coat_lab" - if(istype(coat, /obj/item/clothing/suit/storage/labcoat/cmo)) - . += "coat_cmo" - if(istype(coat, /obj/item/clothing/suit/storage/det_suit)) - . += "coat_det" diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm deleted file mode 100644 index 15b57e1df1f8d..0000000000000 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ /dev/null @@ -1,100 +0,0 @@ -/obj/structure/closet/cardboard - name = "large cardboard box" - desc = "Just a box..." - icon = 'icons/obj/cardboard_boxes.dmi' - icon_state = "cardboard" - enable_door_overlay = FALSE - door_anim_time = 0 - resistance_flags = FLAMMABLE - max_integrity = 70 - integrity_failure = 0 - open_sound = 'sound/machines/cardboard_box.ogg' - close_sound = 'sound/machines/cardboard_box.ogg' - open_sound_volume = 35 - close_sound_volume = 35 - material_drop = /obj/item/stack/sheet/cardboard - /// How fast a mob can move inside this box. - var/move_speed_multiplier = 1 - var/amt = 4 - var/move_delay = FALSE - var/egged = 0 - -/obj/structure/closet/cardboard/relaymove(mob/living/user, direction) - if(!istype(user) || opened || move_delay || user.incapacitated() || !isturf(loc) || !has_gravity(loc)) - return - move_delay = TRUE - var/oldloc = loc - step(src, direction) - // By default, while inside a box, we move at walk speed times the speed multipler of the box. - var/delay = GLOB.configuration.movement.base_walk_speed * move_speed_multiplier - if(IS_DIR_DIAGONAL(direction)) - delay *= SQRT_2 // Moving diagonal counts as moving 2 tiles, we need to slow them down accordingly. - if(oldloc != loc) - addtimer(CALLBACK(src, PROC_REF(ResetMoveDelay)), delay) - else - move_delay = FALSE - -/obj/structure/closet/cardboard/proc/ResetMoveDelay() - move_delay = FALSE - -/obj/structure/closet/cardboard/open() - if(opened || !can_open()) - return 0 - if(!egged) - var/mob/living/Snake = null - for(var/mob/living/L in src.contents) - Snake = L - break - if(Snake) - var/list/alerted = viewers(7,src) - if(alerted) - for(var/mob/living/L in alerted) - if(!L.stat) - L.do_alert_animation(L) - egged = 1 - SEND_SOUND(alerted, sound('sound/machines/chime.ogg')) - return ..() - -/mob/living/proc/do_alert_animation(atom/A) - var/image/I - I = image('icons/obj/cardboard_boxes.dmi', A, "cardboard_special", A.layer+1) - var/list/viewing = list() - for(var/mob/M in viewers(A)) - if(M.client) - viewing |= M.client - flick_overlay(I,viewing,8) - I.alpha = 0 - animate(I, pixel_z = 32, alpha = 255, time = 5, easing = ELASTIC_EASING) - -/obj/structure/closet/cardboard/welder_act() - return - -/obj/structure/closet/cardboard/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) - if(src.opened) - if(istype(W, /obj/item/wirecutters)) - var/obj/item/wirecutters/WC = W - new /obj/item/stack/sheet/cardboard(src.loc, amt) - for(var/mob/M in viewers(src)) - M.show_message("\The [src] has been cut apart by [user] with \the [WC].", 3, "You hear cutting.", 2) - qdel(src) - return - if(is_pen(W)) - var/decalselection = tgui_input_list(user, "Please select a decal", "Paint Box", list("Atmospherics", "Bartender", "Barber", "Blueshield", "Captain", - "Cargo", "Chief Engineer", "Chaplain", "Chef", "Chemist", "Assistant", "Clown", "CMO", "Coroner", "Detective", "Engineering", "Genetics", "HOP", - "HOS", "Hydroponics", "Internal Affairs Agent", "Janitor", "Magistrate", "Medical", "Mime", "Mining", "NT Representative", "Paramedic", - "Prisoner", "Research Director", "Security", "Syndicate", "Therapist", "Virology", "Warden", "Xenobiology")) - if(!decalselection) - return - if(user.incapacitated()) - to_chat(user, "You're in no condition to perform this action.") - return - if(W != user.get_active_hand()) - to_chat(user, "You must be holding the pen to perform this action.") - return - if(!Adjacent(user)) - to_chat(user, "You have moved too far away from the cardboard box.") - return - decalselection = replacetext(decalselection, " ", "_") - decalselection = lowertext(decalselection) - custom_skin = "_[decalselection]" - update_icon() // a proc declared in the closets parent file used to update opened/closed sprites on normal closets diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm deleted file mode 100644 index 2b45b4a04ef80..0000000000000 --- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm +++ /dev/null @@ -1,174 +0,0 @@ -//I still dont think this should be a closet but whatever -/obj/structure/closet/fireaxecabinet - name = "fire axe cabinet" - desc = "There is small label that reads \"For Emergency use only\" along with details for safe use of the axe. As if." - var/obj/item/fireaxe/fireaxe - icon_state = "fireaxe_full_0hits" - icon_closed = "fireaxe_full_0hits" - icon_opened = "fireaxe_full_open" - anchored = TRUE - density = FALSE - armor = list(MELEE = 50, BULLET = 20, LASER = 0, ENERGY = 100, BOMB = 10, RAD = 100, FIRE = 90, ACID = 50) - var/localopened = FALSE //Setting this to keep it from behaviouring like a normal closet and obstructing movement in the map. -Agouri - opened = TRUE - var/hitstaken = FALSE - locked = TRUE - var/smashed = FALSE - var/operating = FALSE - var/has_axe = null // Use a string over a boolean value to make the sprite names more readable - -/obj/structure/closet/fireaxecabinet/populate_contents() - fireaxe = new/obj/item/fireaxe(src) - has_axe = "full" - update_icon(UPDATE_ICON_STATE) // So its initial icon doesn't show it without the fireaxe - -/obj/structure/closet/fireaxecabinet/examine(mob/user) - . = ..() - if(!smashed) - . += "Use a multitool to lock/unlock it." - else - . += "It is damaged beyond repair." - -/obj/structure/closet/fireaxecabinet/attackby__legacy__attackchain(obj/item/O as obj, mob/living/user as mob) //Marker -Agouri - if(isrobot(user) || locked) - if(istype(O, /obj/item/multitool)) - to_chat(user, "Resetting circuitry...") - playsound(user, 'sound/machines/lockreset.ogg', 50, 1) - if(do_after(user, 20 * O.toolspeed, target = src)) - locked = FALSE - to_chat(user, " You disable the locking modules.") - update_icon(UPDATE_ICON_STATE) - return - else if(isitem(O)) - user.changeNext_move(CLICK_CD_MELEE) - var/obj/item/W = O - if(smashed || localopened) - if(localopened) - operate_panel() - return - else - user.do_attack_animation(src) - playsound(user, 'sound/effects/Glasshit.ogg', 100, 1) //We don't want this playing every time - if(W.force < 15) - to_chat(user, "The cabinet's protective glass glances off the hit.") - else - hitstaken++ - if(hitstaken == 4) - playsound(user, 'sound/effects/glassbr3.ogg', 100, 1) //Break cabinet, receive goodies. Cabinet's fucked for life after that. - smashed = TRUE - locked = FALSE - localopened = TRUE - update_icon(UPDATE_ICON_STATE) - return - if(istype(O, /obj/item/fireaxe) && localopened) - if(!fireaxe) - var/obj/item/fireaxe/F = O - if(HAS_TRAIT(F, TRAIT_WIELDED)) - to_chat(user, "Unwield \the [F] first.") - return - if(!user.unequip(F, FALSE)) - to_chat(user, "\The [F] stays stuck to your hands!") - return - fireaxe = F - has_axe = "full" - contents += F - to_chat(user, "You place \the [F] back in the [name].") - update_icon(UPDATE_ICON_STATE) - else - if(smashed) - return - else - operate_panel() - else - if(smashed) - return - if(istype(O, /obj/item/multitool)) - if(localopened) - operate_panel() - return - else - to_chat(user, "Resetting circuitry...") - playsound(user, 'sound/machines/lockenable.ogg', 50, 1) - if(do_after(user, 20 * O.toolspeed, target = src)) - locked = TRUE - to_chat(user, " You re-enable the locking modules.") - return - else - operate_panel() - -/obj/structure/closet/fireaxecabinet/attack_hand(mob/user as mob) - if(locked) - to_chat(user, "The cabinet won't budge!") - return - if(localopened && fireaxe) - user.put_in_hands(fireaxe) - to_chat(user, "You take \the [fireaxe] from [src].") - has_axe = "empty" - fireaxe = null - - add_fingerprint(user) - update_icon(UPDATE_ICON_STATE) - return - if(smashed) - return - operate_panel() - -/obj/structure/closet/fireaxecabinet/attack_tk(mob/user as mob) - if(localopened && fireaxe) - fireaxe.forceMove(loc) - to_chat(user, "You telekinetically remove \the [fireaxe].") - has_axe = "empty" - fireaxe = null - update_icon(UPDATE_ICON_STATE) - return - attack_hand(user) - -/obj/structure/closet/fireaxecabinet/shove_impact(mob/living/target, mob/living/attacker) - // no, you can't shove people into a fireaxe cabinet either - return FALSE - -/obj/structure/closet/fireaxecabinet/attack_ai(mob/user as mob) - if(smashed) - to_chat(user, "The security of the cabinet is compromised.") - return - else - locked = !locked - if(locked) - to_chat(user, "Cabinet locked.") - else - to_chat(user, "Cabinet unlocked.") - -/obj/structure/closet/fireaxecabinet/proc/operate_panel() - if(operating) - return - operating = TRUE - localopened = !localopened - do_animate() - operating = FALSE - -/obj/structure/closet/fireaxecabinet/proc/do_animate() - if(!localopened) - flick("fireaxe_[has_axe]_closing", src) - else - flick("fireaxe_[has_axe]_opening", src) - sleep(10) - update_icon(UPDATE_ICON_STATE) - - -/obj/structure/closet/fireaxecabinet/update_icon_state() - if(localopened && !smashed) - icon_state = "fireaxe_[has_axe]_open" - else - icon_state = "fireaxe_[has_axe]_[hitstaken]hits" - -/obj/structure/closet/fireaxecabinet/update_overlays() - return list() - -/obj/structure/closet/fireaxecabinet/open() - return - -/obj/structure/closet/fireaxecabinet/close() - return - -/obj/structure/closet/fireaxecabinet/welder_act(mob/user, obj/item/I) //A bastion of sanity in a sea of madness - return diff --git a/code/game/objects/structures/crates_lockers/closets/malfunction.dm b/code/game/objects/structures/crates_lockers/closets/malfunction.dm deleted file mode 100644 index 61bcc02b98c93..0000000000000 --- a/code/game/objects/structures/crates_lockers/closets/malfunction.dm +++ /dev/null @@ -1,12 +0,0 @@ - -/obj/structure/closet/malf_suits - desc = "It's a storage unit for operational gear." - icon_state = "syndicate" - -/obj/structure/closet/malf_suits/populate_contents() - new /obj/item/tank/jetpack/void(src) - new /obj/item/clothing/mask/breath(src) - new /obj/effect/nasavoidsuitspawner(src) - new /obj/item/crowbar(src) - new /obj/item/stock_parts/cell(src) - new /obj/item/multitool(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/bar.dm b/code/game/objects/structures/crates_lockers/closets/secure/bar.dm deleted file mode 100644 index 80948affcc979..0000000000000 --- a/code/game/objects/structures/crates_lockers/closets/secure/bar.dm +++ /dev/null @@ -1,15 +0,0 @@ -/obj/structure/closet/secure_closet/bar - name = "Booze cabinet" - req_access = list(ACCESS_BAR) - icon_state = "cabinet" - door_anim_time = 0 - resistance_flags = FLAMMABLE - max_integrity = 70 - open_sound = 'sound/machines/wooden_closet_open.ogg' - close_sound = 'sound/machines/wooden_closet_close.ogg' - open_sound_volume = 25 - close_sound_volume = 50 - -/obj/structure/closet/secure_closet/bar/populate_contents() - for(var/i in 1 to 10) - new /obj/item/reagent_containers/drinks/bottle/beer(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo_lockers.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo_lockers.dm deleted file mode 100644 index 2b7b9b412ab64..0000000000000 --- a/code/game/objects/structures/crates_lockers/closets/secure/cargo_lockers.dm +++ /dev/null @@ -1,70 +0,0 @@ -/obj/structure/closet/secure_closet/cargotech - name = "cargo technician's locker" - req_access = list(ACCESS_CARGO) - icon_state = "cargo" - -/obj/structure/closet/secure_closet/cargotech/populate_contents() - new /obj/item/clothing/under/rank/cargo/tech(src) - new /obj/item/clothing/under/rank/cargo/tech/skirt(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/radio/headset/headset_cargo(src) - new /obj/item/clothing/gloves/fingerless(src) - new /obj/item/clothing/head/soft/cargo(src) - new /obj/item/storage/bag/mail(src) - -/obj/structure/closet/secure_closet/explorer - name = "explorer's locker" - req_access = list(ACCESS_EXPEDITION) - icon_state = "explorer" - opened_door_sprite = "cargo" - - -/obj/structure/closet/secure_closet/explorer/populate_contents() - new /obj/item/radio/headset/headset_cargo/expedition(src) - new /obj/item/gun/energy/kinetic_accelerator/pistol(src) - new /obj/item/clothing/suit/hooded/explorer(src) - new /obj/item/storage/firstaid/regular(src) - new /obj/item/clothing/accessory/holster(src) - new /obj/item/beacon(src) - new /obj/item/storage/box/relay_kit(src) - new /obj/item/gps(src) - new /obj/item/storage/bag/ore(src) - new /obj/item/t_scanner/adv_mining_scanner/lesser(src) - new /obj/item/storage/bag/expedition(src) - -/obj/structure/closet/secure_closet/quartermaster - name = "quartermaster's locker" - req_access = list(ACCESS_QM) - icon_state = "qm" - opened_door_sprite = "cargo" - -/obj/structure/closet/secure_closet/quartermaster/populate_contents() - new /obj/item/radio/headset/heads/qm(src) - new /obj/item/door_remote/quartermaster(src) - new /obj/item/organ/internal/eyes/cybernetic/meson(src) - new /obj/item/storage/bag/garment/quartermaster(src) - new /obj/item/clothing/accessory/medal/supply(src) - new /obj/item/clothing/accessory/medal/supply(src) - new /obj/item/clothing/suit/pimpcoat/tan(src) - new /obj/item/rcs(src) - new /obj/item/dest_tagger(src) - new /obj/item/reagent_containers/drinks/mug/qm(src) - new /obj/item/flash(src) - new /obj/item/cartridge/qm(src) - new /obj/item/storage/bag/mail(src) - new /obj/item/melee/knuckleduster/nanotrasen(src) - -/// used in mining outpost -/obj/structure/closet/secure_closet/quartermaster/lavaland - name = "quartermaster's secondary locker" - -/obj/structure/closet/secure_closet/quartermaster/lavaland/populate_contents() - new /obj/item/fulton_core(src) - new /obj/item/extraction_pack(src) - new /obj/item/gps/mining(src) - new /obj/item/clothing/mask/gas/explorer(src) - new /obj/item/clothing/suit/hooded/explorer(src) - new /obj/item/clothing/glasses/meson(src) - new /obj/item/book/manual/wiki/sop_supply(src) - new /obj/item/folder/yellow(src) - new /obj/item/fan(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/depot_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/depot_closets.dm deleted file mode 100644 index 42f2caed559e0..0000000000000 --- a/code/game/objects/structures/crates_lockers/closets/secure/depot_closets.dm +++ /dev/null @@ -1,62 +0,0 @@ -/obj/structure/closet/secure_closet/depot - name = "depot supply closet" - desc = "A red and black lootbox full of things the Head of Security is going to flip their shit over." - locked = FALSE - anchored = TRUE - req_access = list(ACCESS_SYNDICATE) - icon_state = "tac" - layer = 2.9 // ensures the loot they drop always appears on top of them. - var/is_armory = FALSE - var/ignore_use = FALSE - -/obj/structure/closet/secure_closet/depot/emag_act() - . = ..() - loot_pickup() - -/obj/structure/closet/secure_closet/depot/open() - . = ..() - if(opened) - loot_pickup() - -/obj/structure/closet/secure_closet/depot/dump_contents() - loot_pickup() - . = ..() - -/obj/structure/closet/secure_closet/depot/proc/loot_pickup() - if(!ignore_use) - var/area/syndicate_depot/core/depotarea = get_area(src) - if(istype(depotarea)) - depotarea.locker_looted() - if(is_armory) - depotarea.armory_locker_looted() - -/obj/structure/closet/secure_closet/depot/attack_animal(mob/M) - if(isanimal(M) && ("syndicate" in M.faction)) - to_chat(M, "[src] resists your attack!") - return - return ..() - -/obj/structure/closet/secure_closet/depot/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(istype(W, /obj/item/rcs)) - to_chat(user, "Bluespace interference prevents [W] from locking onto [src]!") - return - return ..() - -/obj/structure/closet/secure_closet/depot/emp_act(severity) - return - -/obj/structure/closet/secure_closet/depot/togglelock(mob/user) - . = ..() - if(!locked) - loot_pickup() - -/obj/structure/closet/secure_closet/depot/attack_ghost(mob/user) - if(user.can_advanced_admin_interact()) - ignore_use = TRUE - toggle(user) - ignore_use = FALSE - -/obj/structure/closet/secure_closet/depot/armory - req_access = list(ACCESS_SYNDICATE_COMMAND) // can't open without killing QM/breaking a closet - is_armory = TRUE - icon_state = "armory" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering_lockers.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering_lockers.dm deleted file mode 100644 index 6703f3bbe317b..0000000000000 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering_lockers.dm +++ /dev/null @@ -1,125 +0,0 @@ -/obj/structure/closet/secure_closet/engineering_chief - name = "chief engineer's locker" - req_access = list(ACCESS_CE) - icon_state = "ce" - opened_door_sprite = "white_secure" - -/obj/structure/closet/secure_closet/engineering_chief/populate_contents() - if(prob(50)) - new /obj/item/storage/backpack/industrial(src) - else - new /obj/item/storage/backpack/satchel_eng(src) - new /obj/item/storage/backpack/duffel/engineering(src) - new /obj/item/areaeditor/blueprints/ce(src) - new /obj/item/storage/box/permits(src) - new /obj/item/storage/bag/garment/chief_engineer(src) - new /obj/item/mod/module/jetpack/advanced(src) - new /obj/item/cartridge/ce(src) - new /obj/item/radio/headset/heads/ce(src) - new /obj/item/storage/toolbox/mechanical(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/multitool(src) - new /obj/item/holosign_creator/engineering(src) - new /obj/item/flash(src) - new /obj/item/clothing/glasses/meson/engine(src) - new /obj/item/clothing/glasses/meson/engine/atmos(src) - new /obj/item/door_remote/chief_engineer(src) - new /obj/item/rpd(src) - new /obj/item/reagent_containers/drinks/mug/ce(src) - new /obj/item/organ/internal/eyes/cybernetic/meson(src) - new /obj/item/clothing/accessory/medal/engineering(src) - new /obj/item/holosign_creator/atmos(src) - new /obj/item/rcd/preloaded(src) - new /obj/item/organ/internal/cyberimp/brain/wire_interface(src) - new /obj/item/storage/bag/construction(src) - - -/obj/structure/closet/secure_closet/engineering_electrical - name = "electrical supplies locker" - req_access = list(ACCESS_ENGINE_EQUIP) - icon_state = "eng" - closed_door_sprite = "eng_elec" - -/obj/structure/closet/secure_closet/engineering_electrical/populate_contents() - new /obj/item/clothing/gloves/color/yellow(src) - new /obj/item/clothing/gloves/color/yellow(src) - new /obj/item/storage/toolbox/electrical(src) - new /obj/item/storage/toolbox/electrical(src) - new /obj/item/storage/toolbox/electrical(src) - new /obj/item/apc_electronics(src) - new /obj/item/apc_electronics(src) - new /obj/item/apc_electronics(src) - new /obj/item/multitool(src) - new /obj/item/multitool(src) - new /obj/item/multitool(src) - new /obj/item/clothing/head/beret/eng - - -/obj/structure/closet/secure_closet/engineering_welding - name = "welding supplies locker" - req_access = list(ACCESS_ENGINE_EQUIP) - icon_state = "eng" - closed_door_sprite = "eng_weld" - -/obj/structure/closet/secure_closet/engineering_welding/populate_contents() - new /obj/item/clothing/head/welding(src) - new /obj/item/clothing/head/welding(src) - new /obj/item/clothing/head/welding(src) - new /obj/item/weldingtool/largetank(src) - new /obj/item/weldingtool/largetank(src) - new /obj/item/weldingtool/largetank(src) - - -/obj/structure/closet/secure_closet/engineering_personal - name = "engineer's locker" - req_access = list(ACCESS_ENGINE_EQUIP) - icon_state = "eng" - closed_door_sprite = "eng_secure" - -/obj/structure/closet/secure_closet/engineering_personal/populate_contents() - if(prob(50)) - new /obj/item/storage/backpack/industrial(src) - else - new /obj/item/storage/backpack/satchel_eng(src) - new /obj/item/storage/backpack/duffel/engineering(src) - new /obj/item/storage/toolbox/mechanical(src) - new /obj/item/holosign_creator/engineering(src) - new /obj/item/radio/headset/headset_eng(src) - new /obj/item/clothing/under/rank/engineering/engineer(src) - new /obj/item/clothing/under/rank/engineering/engineer/skirt(src) - new /obj/item/clothing/suit/storage/hazardvest/staff(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/clothing/glasses/meson/engine(src) - new /obj/item/cartridge/engineering(src) - new /obj/item/clothing/head/beret/eng(src) - new /obj/item/storage/bag/construction(src) - - -/obj/structure/closet/secure_closet/atmos_personal - name = "technician's locker" - req_access = list(ACCESS_ATMOSPHERICS) - icon_state = "atmos" - opened_door_sprite = "eng_secure" - -/obj/structure/closet/secure_closet/atmos_personal/populate_contents() - new /obj/item/radio/headset/headset_eng(src) - new /obj/item/cartridge/atmos(src) - new /obj/item/storage/toolbox/mechanical(src) - if(prob(50)) - new /obj/item/storage/backpack/industrial/atmos(src) - else - new /obj/item/storage/backpack/satchel_atmos(src) - new /obj/item/storage/backpack/duffel/atmos(src) - new /obj/item/extinguisher(src) - new /obj/item/grenade/gas/oxygen(src) - new /obj/item/grenade/gas/oxygen(src) - new /obj/item/clothing/suit/storage/hazardvest/staff(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/tank/internals/emergency_oxygen/engi(src) - new /obj/item/holosign_creator/atmos(src) - new /obj/item/watertank/atmos(src) - new /obj/item/clothing/suit/fire/firefighter/atmos(src) - new /obj/item/clothing/head/hardhat/atmos(src) - new /obj/item/clothing/glasses/meson/engine/atmos(src) - new /obj/item/rpd(src) - new /obj/item/dest_tagger(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical_lockers.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical_lockers.dm deleted file mode 100644 index bccd658bfc803..0000000000000 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical_lockers.dm +++ /dev/null @@ -1,238 +0,0 @@ -/obj/structure/closet/secure_closet/medical1 - name = "medicine closet" - desc = "Filled with medical junk." - icon_state = "med" - req_access = list(ACCESS_MEDICAL) - -/obj/structure/closet/secure_closet/medical1/populate_contents() - new /obj/item/storage/box/autoinjectors(src) - new /obj/item/storage/box/syringes(src) - new /obj/item/storage/box/pillbottles(src) - new /obj/item/storage/box/patch_packs(src) - new /obj/item/storage/box/iv_bags(src) - new /obj/item/reagent_containers/dropper(src) - new /obj/item/reagent_containers/dropper(src) - new /obj/item/reagent_containers/glass/beaker(src) - new /obj/item/reagent_containers/glass/beaker(src) - new /obj/item/reagent_containers/glass/bottle/epinephrine(src) - new /obj/item/reagent_containers/glass/bottle/epinephrine(src) - new /obj/item/reagent_containers/glass/bottle/charcoal(src) - new /obj/item/reagent_containers/glass/bottle/charcoal(src) - -/obj/structure/closet/secure_closet/medical2 - name = "anesthetic locker" - desc = "Used to knock people out." - icon_state = "med" - req_access = list(ACCESS_SURGERY) - -/obj/structure/closet/secure_closet/medical2/populate_contents() - new /obj/item/tank/internals/anesthetic(src) - new /obj/item/tank/internals/anesthetic(src) - new /obj/item/tank/internals/anesthetic(src) - new /obj/item/clothing/mask/breath/medical(src) - new /obj/item/clothing/mask/breath/medical(src) - new /obj/item/clothing/mask/breath/medical(src) - - -/obj/structure/closet/secure_closet/medical3 - name = "medical doctor's locker" - req_access = list(ACCESS_MEDICAL) - icon_state = "med_secure" - opened_door_sprite = "white_secure" - -/obj/structure/closet/secure_closet/medical3/populate_contents() - if(prob(50)) - new /obj/item/storage/backpack/medic(src) - else - new /obj/item/storage/backpack/satchel_med(src) - new /obj/item/storage/backpack/duffel/medical(src) - new /obj/item/clothing/under/rank/medical/doctor(src) - new /obj/item/clothing/suit/storage/labcoat(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/radio/headset/headset_med(src) - new /obj/item/clothing/gloves/color/latex/nitrile(src) - new /obj/item/defibrillator/loaded(src) - new /obj/item/handheld_defibrillator(src) - new /obj/item/handheld_defibrillator(src) - new /obj/item/storage/belt/medical(src) - new /obj/item/clothing/glasses/hud/health(src) - new /obj/item/clothing/shoes/sandal/white(src) - - -//Exam Room -/obj/structure/closet/secure_closet/exam - name = "exam room closet" - desc = "Filled with exam room materials." - icon_state = "med" - req_access = list(ACCESS_MEDICAL) - -/obj/structure/closet/secure_closet/exam/populate_contents() - new /obj/item/storage/box/syringes(src) - new /obj/item/reagent_containers/dropper(src) - new /obj/item/storage/belt/medical(src) - new /obj/item/clothing/mask/surgical(src) - new /obj/item/clothing/glasses/hud/health(src) - new /obj/item/clothing/gloves/color/latex/nitrile(src) - new /obj/item/clothing/neck/stethoscope(src) - new /obj/item/flashlight/pen(src) - new /obj/item/storage/firstaid/regular(src) - new /obj/item/storage/firstaid/adv(src) - new /obj/item/storage/firstaid/brute(src) - new /obj/item/storage/firstaid/fire(src) - new /obj/item/storage/firstaid/o2(src) - new /obj/item/storage/firstaid/toxin(src) - - -// Psychiatrist's pill bottle -/obj/item/storage/pill_bottle/psychiatrist - name = "psychiatrist's pill bottle" - desc = "Contains various pills to calm or sedate patients." - wrapper_color = COLOR_PALE_BTL_GREEN - -// Why the hell is this in the closets folder? -/obj/item/storage/pill_bottle/psychiatrist/populate_contents() - new /obj/item/reagent_containers/pill/haloperidol(src) - new /obj/item/reagent_containers/pill/haloperidol(src) - new /obj/item/reagent_containers/pill/haloperidol(src) - new /obj/item/reagent_containers/pill/methamphetamine(src) - new /obj/item/reagent_containers/pill/methamphetamine(src) - new /obj/item/reagent_containers/pill/methamphetamine(src) - new /obj/item/reagent_containers/pill/happy_psych(src) - new /obj/item/reagent_containers/pill/happy_psych(src) - new /obj/item/reagent_containers/pill/happy_psych(src) - new /obj/item/reagent_containers/patch/nicotine(src) - new /obj/item/reagent_containers/patch/nicotine(src) - new /obj/item/reagent_containers/patch/nicotine(src) - new /obj/item/reagent_containers/pill/hydrocodone(src) - new /obj/item/reagent_containers/pill/hydrocodone(src) - new /obj/item/reagent_containers/pill/mannitol(src) - new /obj/item/reagent_containers/pill/mannitol(src) - new /obj/item/reagent_containers/pill/mannitol(src) - new /obj/item/reagent_containers/pill/mannitol(src) - new /obj/item/reagent_containers/pill/mannitol(src) - -/obj/structure/closet/secure_closet/psychiatrist - name = "psychiatrist's locker" - req_access = list(ACCESS_PSYCHIATRIST) - icon_state = "med_secure" - opened_door_sprite = "white_secure" - -/obj/structure/closet/secure_closet/psychiatrist/populate_contents() - new /obj/item/storage/bag/garment/psychologist(src) - new /obj/item/clothing/suit/straight_jacket(src) - new /obj/item/reagent_containers/syringe(src) - new /obj/item/reagent_containers/glass/bottle/ether(src) - new /obj/item/clipboard(src) - new /obj/item/storage/fancy/cigarettes/cigpack_med(src) - new /obj/item/storage/fancy/cigarettes/cigpack_med(src) - new /obj/item/storage/fancy/cigarettes/cigpack_med(src) - new /obj/item/storage/pill_bottle/psychiatrist(src) - new /obj/effect/spawner/random/plushies - for(var/i in 0 to 3) - var/candy = pick(subtypesof(/obj/item/food/candy/fudge)) - new candy(src) - -/obj/structure/closet/secure_closet/cmo - name = "chief medical officer's locker" - req_access = list(ACCESS_CMO) - icon_state = "cmo" - -/obj/structure/closet/secure_closet/cmo/populate_contents() - if(prob(50)) - new /obj/item/storage/backpack/medic(src) - else - new /obj/item/storage/backpack/satchel_med(src) - new /obj/item/storage/backpack/duffel/medical(src) - new /obj/item/clothing/suit/bio_suit/cmo(src) - new /obj/item/clothing/head/bio_hood/cmo(src) - new /obj/item/storage/bag/garment/chief_medical_officer(src) - new /obj/item/radio/headset/heads/cmo(src) - new /obj/item/defibrillator/compact/advanced/loaded(src) - new /obj/item/handheld_defibrillator(src) - new /obj/item/storage/belt/medical(src) - new /obj/item/clothing/glasses/hud/health/sunglasses(src) - new /obj/item/flash(src) - new /obj/item/gun/syringe(src) - new /obj/item/reagent_containers/hypospray/cmo(src) - new /obj/item/organ/internal/cyberimp/eyes/hud/medical(src) - new /obj/item/door_remote/chief_medical_officer(src) - new /obj/item/reagent_containers/drinks/mug/cmo(src) - new /obj/item/clothing/accessory/medal/medical(src) - new /obj/item/storage/briefcase(src) - new /obj/item/clothing/mask/gas(src) - - -/obj/structure/closet/secure_closet/animal - name = "animal control locker" - req_access = list(ACCESS_SURGERY) - -/obj/structure/closet/secure_closet/animal/populate_contents() - new /obj/item/assembly/signaler(src) - new /obj/item/electropack(src) - new /obj/item/electropack(src) - new /obj/item/electropack(src) - - -/obj/structure/closet/secure_closet/chemical - name = "chemical closet" - desc = "Store dangerous chemicals in here." - icon_state = "med" - req_access = list(ACCESS_CHEMISTRY) - -/obj/structure/closet/secure_closet/chemical/populate_contents() - new /obj/item/storage/box/pillbottles(src) - new /obj/item/storage/box/pillbottles(src) - new /obj/item/storage/box/patch_packs(src) - new /obj/item/storage/box/patch_packs(src) - -/obj/structure/closet/secure_closet/paramedic - name = "paramedic EVA gear" - desc = "A locker with a Rescue MODsuit." - icon_state = "med" - req_access = list(ACCESS_PARAMEDIC) - -/obj/structure/closet/secure_closet/paramedic/populate_contents() - new /obj/item/radio/headset/headset_med/para(src) - new /obj/item/mod/control/pre_equipped/rescue(src) - new /obj/item/key/ambulance(src) - new /obj/item/handheld_defibrillator(src) - new /obj/item/storage/bag/garment/paramedic(src) - new /obj/item/defibrillator/loaded(src) - new /obj/item/storage/belt/medical(src) - new /obj/item/storage/firstaid/adv(src) - new /obj/item/storage/toolbox/emergency(src) - new /obj/item/fulton_core(src) - new /obj/item/extraction_pack(src) - new /obj/item/gps/mining(src) - new /obj/item/pickaxe/drill(src) - -/obj/structure/closet/secure_closet/reagents - name = "chemical storage closet" - desc = "Store dangerous chemicals in here." - icon_state = "med" - closed_door_sprite = "chemical" - req_access = list(ACCESS_CHEMISTRY) - -/obj/structure/closet/secure_closet/reagents/populate_contents() - new /obj/item/reagent_containers/glass/bottle/reagent/phenol(src) - new /obj/item/reagent_containers/glass/bottle/reagent/ammonia(src) - new /obj/item/reagent_containers/glass/bottle/reagent/oil(src) - new /obj/item/reagent_containers/glass/bottle/reagent/acetone(src) - new /obj/item/reagent_containers/glass/bottle/reagent/acid(src) - new /obj/item/reagent_containers/glass/bottle/reagent/diethylamine(src) - -/obj/structure/closet/secure_closet/genetics - name = "genetics test subject locker" - desc = "Storage for lesser form cubes." - icon_state = "med" - closed_door_sprite = "genetics" - req_access = list(ACCESS_GENETICS) - -/obj/structure/closet/secure_closet/genetics/populate_contents() - new /obj/item/storage/box/monkeycubes(src) - new /obj/item/storage/box/monkeycubes/farwacubes(src) - new /obj/item/storage/box/monkeycubes/neaeracubes(src) - new /obj/item/storage/box/monkeycubes/nian_worme_cubes(src) - new /obj/item/storage/box/monkeycubes/stokcubes(src) - new /obj/item/storage/box/monkeycubes/wolpincubes(src) - diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm deleted file mode 100644 index c7056037507ee..0000000000000 --- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm +++ /dev/null @@ -1,71 +0,0 @@ -/obj/structure/closet/secure_closet/personal - desc = "It's a secure locker for personnel. The first card swiped gains control." - name = "personal closet" - req_access = list(ACCESS_ALL_PERSONAL_LOCKERS) - var/registered_name = null - -/obj/structure/closet/secure_closet/personal/populate_contents() - if(prob(50)) - new /obj/item/storage/backpack/duffel(src) - if(prob(50)) - new /obj/item/storage/backpack(src) - else - new /obj/item/storage/backpack/satchel_norm(src) - new /obj/item/radio/headset( src ) - - -/obj/structure/closet/secure_closet/personal/patient - name = "patient's closet" - -/obj/structure/closet/secure_closet/personal/patient/populate_contents() - new /obj/item/clothing/under/color/white( src ) - new /obj/item/clothing/shoes/white( src ) - -/obj/structure/closet/secure_closet/personal/cabinet - icon_state = "cabinet" - door_anim_time = 0 - resistance_flags = FLAMMABLE - max_integrity = 70 - open_sound = 'sound/machines/wooden_closet_open.ogg' - close_sound = 'sound/machines/wooden_closet_close.ogg' - open_sound_volume = 25 - close_sound_volume = 50 - -/obj/structure/closet/secure_closet/personal/cabinet/populate_contents() - new /obj/item/storage/backpack/satchel/withwallet( src ) - new /obj/item/radio/headset( src ) - -/obj/structure/closet/secure_closet/personal/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(opened || !istype(W, /obj/item/card/id)) - return ..() - - if(broken) - to_chat(user, "The locker appears to be broken.") - return - - if(user.loc == src) - to_chat(user, "You can't reach the lock from inside.") - return - - if(istype(W, /obj/item/card/id/guest)) - to_chat(user, "Invalid identification card.") - return - - var/obj/item/card/id/I = W - if(!I || !I.registered_name) - return - - if(allowed(user) || !registered_name || (istype(I) && (registered_name == I.registered_name))) - //they can open all lockers, or nobody owns this, or they own this locker - locked = !locked - update_icon() - if(!locked) - registered_name = null - desc = initial(desc) - - if(!registered_name && locked) - registered_name = I.registered_name - desc = "Owned by [I.registered_name]." - - else - to_chat(user, "Access denied.") diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm deleted file mode 100644 index 19eba236cc30f..0000000000000 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ /dev/null @@ -1,85 +0,0 @@ -/obj/structure/closet/secure_closet/scientist - name = "scientist's locker" - req_access = list(ACCESS_TOX_STORAGE) - icon_state = "science" - opened_door_sprite = "white_secure" - -/obj/structure/closet/secure_closet/scientist/populate_contents() - new /obj/item/storage/backpack/science(src) - new /obj/item/storage/backpack/satchel_tox(src) - new /obj/item/clothing/under/rank/rnd/scientist(src) - new /obj/item/clothing/under/rank/rnd/scientist/skirt(src) - //new /obj/item/clothing/suit/labcoat/science(src) - new /obj/item/clothing/suit/storage/labcoat/science(src) - new /obj/item/clothing/shoes/white(src) -// new /obj/item/cartridge/signal/toxins(src) - new /obj/item/radio/headset/headset_sci(src) - new /obj/item/tank/internals/air(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/clothing/shoes/sandal/white(src) - -/obj/structure/closet/secure_closet/roboticist - name = "roboticist's locker" - req_access = list(ACCESS_ROBOTICS) - icon_state = "robotics" - -/obj/structure/closet/secure_closet/roboticist/populate_contents() - new /obj/item/mod/core/standard(src) - new /obj/item/storage/backpack/robotics(src) - new /obj/item/storage/backpack/robotics(src) - new /obj/item/storage/backpack/satchel_robo(src) - new /obj/item/storage/backpack/satchel_robo(src) - new /obj/item/storage/backpack/duffel/robotics(src) - new /obj/item/storage/backpack/duffel/robotics(src) - new /obj/item/clothing/suit/storage/labcoat/roboblack(src) - new /obj/item/clothing/suit/storage/labcoat/robowhite(src) - new /obj/item/radio/headset/headset_sci(src) - new /obj/item/radio/headset/headset_sci(src) - new /obj/item/radio/headset/headset_sci(src) - - -/obj/structure/closet/secure_closet/rd - name = "research director's locker" - req_access = list(ACCESS_RD) - icon_state = "rd" - - -/obj/structure/closet/secure_closet/rd/populate_contents() - new /obj/item/storage/bag/garment/research_director(src) - new /obj/item/clothing/suit/bio_suit/scientist(src) - new /obj/item/clothing/head/bio_hood/scientist(src) - new /obj/item/cartridge/rd(src) - new /obj/item/radio/headset/heads/rd(src) - new /obj/item/tank/internals/air(src) - new /obj/item/clothing/mask/gas(src) - new /obj/effect/spawner/reactive_armor(src) - new /obj/item/flash(src) - new /obj/item/laser_pointer(src) - new /obj/item/door_remote/research_director(src) - new /obj/item/reagent_containers/drinks/mug/rd(src) - new /obj/item/organ/internal/cyberimp/eyes/hud/diagnostic(src) - new /obj/item/clothing/accessory/medal/science(src) - - -/obj/structure/closet/secure_closet/research_reagents - name = "research chemical storage closet" - desc = "Store dangerous chemicals in here." - icon_state = "med" - closed_door_sprite = "rchemical" - req_access = list(ACCESS_TOX_STORAGE) - -/obj/structure/closet/secure_closet/research_reagents/populate_contents() - new /obj/item/reagent_containers/glass/bottle/reagent/morphine(src) - new /obj/item/reagent_containers/glass/bottle/reagent/morphine(src) - new /obj/item/reagent_containers/glass/bottle/reagent/morphine(src) - new /obj/item/reagent_containers/glass/bottle/reagent/morphine(src) - new /obj/item/reagent_containers/glass/bottle/reagent/insulin(src) - new /obj/item/reagent_containers/glass/bottle/reagent/insulin(src) - new /obj/item/reagent_containers/glass/bottle/reagent/insulin(src) - new /obj/item/reagent_containers/glass/bottle/reagent/insulin(src) - new /obj/item/reagent_containers/glass/bottle/reagent/phenol(src) - new /obj/item/reagent_containers/glass/bottle/reagent/ammonia(src) - new /obj/item/reagent_containers/glass/bottle/reagent/oil(src) - new /obj/item/reagent_containers/glass/bottle/reagent/acetone(src) - new /obj/item/reagent_containers/glass/bottle/reagent/acid(src) - new /obj/item/reagent_containers/glass/bottle/reagent/diethylamine(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security_lockers.dm b/code/game/objects/structures/crates_lockers/closets/secure/security_lockers.dm deleted file mode 100644 index 5776d1262a0e1..0000000000000 --- a/code/game/objects/structures/crates_lockers/closets/secure/security_lockers.dm +++ /dev/null @@ -1,333 +0,0 @@ -/obj/structure/closet/secure_closet/captains - name = "captain's locker" - req_access = list(ACCESS_CAPTAIN) - icon_state = "cap" - -/obj/structure/closet/secure_closet/captains/populate_contents() - if(prob(50)) - new /obj/item/storage/backpack/captain(src) - else - new /obj/item/storage/backpack/satchel_cap(src) - new /obj/item/book/manual/wiki/faxes(src) - new /obj/item/storage/backpack/duffel/captain(src) - new /obj/item/storage/bag/garment/captain(src) - new /obj/item/cartridge/captain(src) - new /obj/item/radio/headset/heads/captain/alt(src) - new /obj/item/storage/belt/sheath/saber(src) - new /obj/item/gun/energy/gun(src) - new /obj/item/flash(src) - new /obj/item/door_remote/captain(src) - new /obj/item/reagent_containers/drinks/mug/cap(src) - new /obj/item/tank/internals/emergency_oxygen/double(src) - -/obj/structure/closet/secure_closet/hop - name = "head of personnel's locker" - req_access = list(ACCESS_HOP) - icon_state = "hop" - -/obj/structure/closet/secure_closet/hop/populate_contents() - new /obj/item/cartridge/hop(src) - new /obj/item/radio/headset/heads/hop(src) - new /obj/item/storage/box/ids(src) - new /obj/item/storage/box/pdas(src) - new /obj/item/gun/energy/gun/mini(src) - new /obj/item/flash(src) - new /obj/item/door_remote/civillian(src) - new /obj/item/reagent_containers/drinks/mug/hop(src) - new /obj/item/clothing/accessory/medal/service(src) - new /obj/item/storage/bag/garment/head_of_personnel(src) - -/obj/structure/closet/secure_closet/hos - name = "head of security's locker" - req_access = list(ACCESS_HOS) - icon_state = "hos" - -/obj/structure/closet/secure_closet/hos/populate_contents() - if(prob(50)) - new /obj/item/storage/backpack/security(src) - else - new /obj/item/storage/backpack/satchel_sec(src) - - new /obj/item/storage/bag/garment/head_of_security(src) - new /obj/item/cartridge/hos(src) - new /obj/item/radio/headset/heads/hos/alt(src) - new /obj/item/storage/lockbox/mindshield(src) - new /obj/item/storage/box/flashbangs(src) - new /obj/item/holosign_creator/security(src) - new /obj/item/shield/riot/tele(src) - new /obj/item/flashlight/seclite(src) - new /obj/item/storage/belt/security/full(src) - new /obj/item/gun/energy/gun/hos(src) - new /obj/item/door_remote/head_of_security(src) - new /obj/item/reagent_containers/drinks/mug/hos(src) - new /obj/item/organ/internal/cyberimp/eyes/hud/security(src) - new /obj/item/clothing/accessory/medal/security(src) - new /obj/item/reagent_containers/drinks/flask/barflask(src) - new /obj/item/clothing/mask/gas/sechailer(src) - -/obj/structure/closet/secure_closet/warden - name = "warden's locker" - req_access = list(ACCESS_ARMORY) - icon_state = "warden" - opened_door_sprite = "sec" - -/obj/structure/closet/secure_closet/warden/populate_contents() - if(prob(50)) - new /obj/item/storage/backpack/security(src) - else - new /obj/item/storage/backpack/satchel_sec(src) - new /obj/item/storage/bag/garment/warden(src) - new /obj/item/radio/headset/headset_sec/alt(src) - new /obj/item/holosign_creator/security(src) - new /obj/item/storage/box/zipties(src) - new /obj/item/storage/box/flashbangs(src) - new /obj/item/storage/belt/security/full(src) - new /obj/item/flashlight/seclite(src) - new /obj/item/storage/box/holobadge(src) - new /obj/item/clothing/gloves/color/black/krav_maga/sec(src) - new /obj/item/clothing/mask/gas/sechailer(src) - -/obj/structure/closet/secure_closet/security - name = "security officer's locker" - req_access = list(ACCESS_SECURITY) - icon_state = "sec" - -/obj/structure/closet/secure_closet/security/populate_contents() - if(prob(50)) - new /obj/item/storage/backpack/security(src) - else - new /obj/item/storage/backpack/satchel_sec(src) - new /obj/item/clothing/suit/armor/vest/security(src) - new /obj/item/radio/headset/headset_sec/alt(src) - new /obj/item/clothing/head/soft/sec(src) - new /obj/item/storage/belt/security/full(src) - new /obj/item/holosign_creator/security(src) - new /obj/item/clothing/mask/gas/sechailer(src) - new /obj/item/clothing/glasses/hud/security/sunglasses(src) - new /obj/item/flashlight/seclite(src) - new /obj/item/clothing/head/helmet(src) - new /obj/item/clothing/suit/armor/secjacket(src) - -/obj/structure/closet/secure_closet/evidence - name = "evidence locker" - req_access = list(ACCESS_SEC_DOORS) - anchored = TRUE - -/obj/structure/closet/secure_closet/evidence/detective - req_access = list(ACCESS_FORENSICS_LOCKERS) - -/obj/structure/closet/secure_closet/blueshield - name = "blueshield's locker" - req_access = list(ACCESS_BLUESHIELD) - icon_state = "hop" - closed_door_sprite = "bs" - -/obj/structure/closet/secure_closet/blueshield/populate_contents() - new /obj/item/storage/backpack/blueshield(src) - new /obj/item/storage/backpack/satchel_blueshield(src) - new /obj/item/storage/briefcase(src) - new /obj/item/storage/backpack/duffel/blueshield(src) - new /obj/item/radio/headset/heads/blueshield/alt(src) - new /obj/item/cartridge/hos(src) - new /obj/item/storage/firstaid/adv(src) - new /obj/item/pinpointer/crew(src) - new /obj/item/flashlight/seclite(src) - new /obj/item/storage/belt/security/full(src) - new /obj/item/clothing/accessory/holster(src) - new /obj/item/storage/bag/garment/blueshield(src) - new /obj/item/sensor_device(src) - -/obj/structure/closet/secure_closet/ntrep - name = "\improper Nanotrasen Representative's locker" - req_access = list(ACCESS_NTREP) - icon_state = "hop" - closed_door_sprite = "ntr" - -/obj/structure/closet/secure_closet/ntrep/populate_contents() - new /obj/item/book/manual/wiki/faxes(src) - new /obj/item/storage/briefcase(src) - new /obj/item/radio/headset/heads/ntrep (src) - new /obj/item/cartridge/supervisor(src) - new /obj/item/paicard(src) - new /obj/item/flash(src) - new /obj/item/storage/box/tapes(src) - new /obj/item/taperecorder(src) - new /obj/item/storage/bag/garment/nanotrasen_representative(src) - -/obj/structure/closet/secure_closet/security/cargo - -/obj/structure/closet/secure_closet/security/cargo/populate_contents() - new /obj/item/clothing/accessory/armband/cargo(src) - new /obj/item/encryptionkey/headset_cargo(src) - -/obj/structure/closet/secure_closet/security/engine - -/obj/structure/closet/secure_closet/security/engine/populate_contents() - new /obj/item/clothing/accessory/armband/engine(src) - new /obj/item/encryptionkey/headset_eng(src) - -/obj/structure/closet/secure_closet/security/science - -/obj/structure/closet/secure_closet/security/science/populate_contents() - new /obj/item/clothing/accessory/armband/science(src) - new /obj/item/encryptionkey/headset_sci(src) - -/obj/structure/closet/secure_closet/security/med - -/obj/structure/closet/secure_closet/security/med/populate_contents() - new /obj/item/clothing/accessory/armband/medgreen(src) - new /obj/item/encryptionkey/headset_med(src) - -/obj/structure/closet/secure_closet/detective - name = "detective's cabinet" - req_access = list(ACCESS_FORENSICS_LOCKERS) - icon_state = "cabinet" - door_anim_time = 0 - resistance_flags = FLAMMABLE - max_integrity = 70 - open_sound = 'sound/machines/wooden_closet_open.ogg' - close_sound = 'sound/machines/wooden_closet_close.ogg' - -/obj/structure/closet/secure_closet/detective/populate_contents() - new /obj/item/storage/bag/garment/detective(src) - new /obj/item/storage/belt/security(src) - new /obj/item/storage/box/evidence(src) - new /obj/item/clipboard(src) - new /obj/item/radio/headset/headset_sec/alt(src) - new /obj/item/detective_scanner(src) - new /obj/item/ammo_box/magazine/detective/speedcharger(src) - new /obj/item/ammo_box/magazine/detective/speedcharger(src) - new /obj/effect/spawner/detgun(src) - new /obj/item/flashlight/seclite(src) - new /obj/item/holosign_creator/detective(src) - new /obj/item/taperecorder(src) - new /obj/item/storage/box/tapes(src) - -/obj/structure/closet/secure_closet/injection - name = "lethal injections locker" - req_access = list(ACCESS_SECURITY) - -/obj/structure/closet/secure_closet/injection/populate_contents() - new /obj/item/reagent_containers/syringe/lethal(src) - new /obj/item/reagent_containers/syringe/lethal(src) - -/obj/structure/closet/secure_closet/brig - name = "brig locker" - req_access = list(ACCESS_BRIG) - anchored = TRUE - var/id = null - -/obj/structure/closet/secure_closet/brig/populate_contents() - new /obj/item/clothing/under/color/orange/prison(src) - new /obj/item/clothing/under/color/jumpskirt/orange/prison(src) - new /obj/item/clothing/shoes/orange(src) - new /obj/item/card/id/prisoner/random(src) - new /obj/item/radio/headset(src) - -/obj/structure/closet/secure_closet/brig/temp - desc = "A locker connected to the cell's timer system, used to store prisoner belongings. It unlocks automatically once the sentence has been served." - -/obj/structure/closet/secure_closet/brig/temp/populate_contents() - return - -/obj/structure/closet/secure_closet/brig/temp/cell_1 - name = "Cell 1 Locker" - id = "Cell 1" - -/obj/structure/closet/secure_closet/brig/temp/cell_2 - name = "Cell 2 Locker" - id = "Cell 2" - -/obj/structure/closet/secure_closet/brig/temp/cell_3 - name = "Cell 3 Locker" - id = "Cell 3" - -/obj/structure/closet/secure_closet/brig/temp/cell_4 - name = "Cell 4 Locker" - id = "Cell 4" - -/obj/structure/closet/secure_closet/brig/temp/cell_5 - name = "Cell 5 Locker" - id = "Cell 5" - -/obj/structure/closet/secure_closet/brig/temp/cell_6 - name = "Cell 6 Locker" - id = "Cell 6" - -/obj/structure/closet/secure_closet/brig/temp/cell_7 - name = "Cell 7 Locker" - id = "Cell 7" - -/obj/structure/closet/secure_closet/brig/temp/cell_8 - name = "Cell 8 Locker" - id = "Cell 8" - -/obj/structure/closet/secure_closet/brig/gulag - name = "labor camp locker" - desc = "A special locker designed to store prisoner belongings, allows access when prisoners meet their point quota." - locked = FALSE - var/registered_ID_UID - -/obj/structure/closet/secure_closet/brig/gulag/allowed(mob/M) - . = ..() - if(.) //we were gonna let them do it anyway - return TRUE - - for(var/obj/item/card/id/prisoner/prisoner_id in M) //they might have a stash of them - if(!prisoner_id.goal) - continue //no goal? no interaction - - if(locked && registered_ID_UID && !(prisoner_id.UID() == registered_ID_UID)) - continue //you don't own this! - - if(!locked) - registered_ID_UID = prisoner_id.UID() - return TRUE //they are trying to lock it, so let them - - if(prisoner_id.mining_points >= prisoner_id.goal) - registered_ID_UID = null - return TRUE //completed goal? do the interaction - - return FALSE //if we didn't match above, no interaction for you - -/obj/structure/closet/secure_closet/brig/gulag/examine(mob/user) - . = ..() - if(registered_ID_UID) - var/obj/item/card/id/prisoner/prisoner_id = locateUID(registered_ID_UID) - . += "\nOwned by [prisoner_id.registered_name]." - -/obj/structure/closet/secure_closet/magistrate - name = "\improper Magistrate's locker" - req_access = list(ACCESS_MAGISTRATE) - icon_state = "magi" - opened_door_sprite = "chaplain" - -/obj/structure/closet/secure_closet/magistrate/populate_contents() - new /obj/item/book/manual/wiki/faxes(src) - new /obj/item/storage/secure/briefcase(src) - new /obj/item/flash(src) - new /obj/item/radio/headset/heads/magistrate(src) - new /obj/item/cartridge/supervisor(src) - new /obj/item/gavelblock(src) - new /obj/item/gavelhammer(src) - new /obj/item/clothing/accessory/medal/legal(src) - new /obj/item/clothing/accessory/legal_badge(src) - new /obj/item/storage/bag/garment/magistrate(src) - -/obj/structure/closet/secure_closet/iaa - name = "internal affairs locker" - req_access = list(ACCESS_INTERNAL_AFFAIRS) - icon_state = "magi" - opened_door_sprite = "chaplain" - closed_door_sprite = "iaa" - -/obj/structure/closet/secure_closet/iaa/populate_contents() - new /obj/item/book/manual/wiki/faxes(src) - new /obj/item/storage/box/tapes(src) - new /obj/item/storage/secure/briefcase(src) - new /obj/item/storage/secure/briefcase(src) - new /obj/item/storage/briefcase(src) - new /obj/item/storage/briefcase(src) - new /obj/item/radio/headset/headset_iaa(src) - new /obj/item/radio/headset/headset_iaa(src) - new /obj/item/clothing/accessory/legal_badge/iaa(src) diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm deleted file mode 100644 index 77d0d6da3a6e5..0000000000000 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ /dev/null @@ -1,482 +0,0 @@ -/obj/structure/closet/wardrobe - name = "wardrobe" - desc = "It's a storage unit for standard-issue Nanotrasen attire." - icon_state = "generic" - closed_door_sprite = "blue" - - -/obj/structure/closet/wardrobe/generic - // Identical to the base wardrobe, aside from containing some stuff. - -/obj/structure/closet/wardrobe/generic/populate_contents() - new /obj/item/clothing/under/color/blue(src) - new /obj/item/clothing/under/color/blue(src) - new /obj/item/clothing/under/color/blue(src) - new /obj/item/clothing/under/color/jumpskirt/blue(src) - new /obj/item/clothing/under/color/jumpskirt/blue(src) - new /obj/item/clothing/under/color/jumpskirt/blue(src) - new /obj/item/clothing/mask/bandana/blue(src) - new /obj/item/clothing/mask/bandana/blue(src) - new /obj/item/clothing/mask/bandana/blue(src) - new /obj/item/clothing/shoes/brown(src) - new /obj/item/clothing/shoes/brown(src) - new /obj/item/clothing/shoes/brown(src) - - -/obj/structure/closet/wardrobe/red - name = "security wardrobe" - closed_door_sprite = "red" - - -/obj/structure/closet/wardrobe/populate_contents() - new /obj/item/storage/backpack/duffel/security(src) - new /obj/item/storage/backpack/duffel/security(src) - new /obj/item/clothing/mask/bandana/red(src) - new /obj/item/clothing/mask/bandana/red(src) - new /obj/item/clothing/mask/bandana/red(src) - new /obj/item/clothing/under/rank/security/officer(src) - new /obj/item/clothing/under/rank/security/officer(src) - new /obj/item/clothing/under/rank/security/officer(src) - new /obj/item/clothing/under/rank/security/formal(src) - new /obj/item/clothing/under/rank/security/formal(src) - new /obj/item/clothing/under/rank/security/formal(src) - new /obj/item/clothing/under/rank/security/officer/skirt(src) - new /obj/item/clothing/under/rank/security/officer/skirt(src) - new /obj/item/clothing/under/rank/security/officer/skirt(src) - new /obj/item/clothing/shoes/jackboots(src) - new /obj/item/clothing/shoes/jackboots(src) - new /obj/item/clothing/shoes/jackboots(src) - new /obj/item/clothing/shoes/jackboots/jacksandals(src) - new /obj/item/clothing/shoes/jackboots/jacksandals(src) - new /obj/item/clothing/shoes/jackboots/jacksandals(src) - new /obj/item/clothing/head/soft/sec(src) - new /obj/item/clothing/head/soft/sec(src) - new /obj/item/clothing/head/soft/sec(src) - new /obj/item/clothing/head/beret/sec(src) - new /obj/item/clothing/head/beret/sec(src) - new /obj/item/clothing/head/beret/sec(src) - new /obj/item/clothing/head/officer(src) - new /obj/item/clothing/head/officer(src) - new /obj/item/clothing/head/officer(src) - -/obj/structure/closet/redcorp - name = "corporate security wardrobe" - closed_door_sprite = "red" - -/obj/structure/closet/redcorp/populate_contents() - new /obj/item/clothing/under/rank/security/officer/corporate(src) - new /obj/item/clothing/under/rank/security/officer/corporate(src) - new /obj/item/clothing/under/rank/security/officer/corporate(src) - new /obj/item/clothing/head/soft/sec/corp(src) - new /obj/item/clothing/head/soft/sec/corp(src) - new /obj/item/clothing/head/soft/sec/corp(src) - -/obj/structure/closet/wardrobe/pink - name = "pink wardrobe" - closed_door_sprite = "pink" - -/obj/structure/closet/wardrobe/pink/populate_contents() - new /obj/item/clothing/under/color/pink(src) - new /obj/item/clothing/under/color/pink(src) - new /obj/item/clothing/under/color/pink(src) - new /obj/item/clothing/under/color/jumpskirt/pink(src) - new /obj/item/clothing/under/color/jumpskirt/pink(src) - new /obj/item/clothing/under/color/jumpskirt/pink(src) - new /obj/item/clothing/shoes/brown(src) - new /obj/item/clothing/shoes/brown(src) - new /obj/item/clothing/shoes/brown(src) - -/obj/structure/closet/wardrobe/black - name = "black wardrobe" - closed_door_sprite = "black" - -/obj/structure/closet/wardrobe/black/populate_contents() - new /obj/item/clothing/under/color/black(src) - new /obj/item/clothing/under/color/black(src) - new /obj/item/clothing/under/color/black(src) - new /obj/item/clothing/under/color/jumpskirt/black(src) - new /obj/item/clothing/under/color/jumpskirt/black(src) - new /obj/item/clothing/under/color/jumpskirt/black(src) - if(prob(25)) - new /obj/item/clothing/suit/jacket/leather(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/head/that(src) - new /obj/item/clothing/head/that(src) - new /obj/item/clothing/head/that(src) - new /obj/item/clothing/head/soft/black(src) - new /obj/item/clothing/head/soft/black(src) - new /obj/item/clothing/head/soft/black(src) - -/obj/structure/closet/wardrobe/green - name = "green wardrobe" - closed_door_sprite = "green" - -/obj/structure/closet/wardrobe/green/populate_contents() - new /obj/item/clothing/under/color/green(src) - new /obj/item/clothing/under/color/green(src) - new /obj/item/clothing/under/color/green(src) - new /obj/item/clothing/under/color/jumpskirt/green(src) - new /obj/item/clothing/under/color/jumpskirt/green(src) - new /obj/item/clothing/under/color/jumpskirt/green(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/black(src) - -/obj/structure/closet/wardrobe/xenos - name = "xenos wardrobe" - closed_door_sprite = "green" - -/obj/structure/closet/wardrobe/xenos/populate_contents() - new /obj/item/clothing/neck/cloak/unathi(src) - new /obj/item/clothing/suit/unathi/robe(src) - new /obj/item/clothing/gloves/handwraps(src) - new /obj/item/clothing/gloves/handwraps(src) - new /obj/item/clothing/shoes/sandal(src) - new /obj/item/clothing/shoes/sandal(src) - new /obj/item/clothing/shoes/sandal(src) - new /obj/item/clothing/shoes/footwraps(src) - new /obj/item/clothing/shoes/footwraps(src) - new /obj/item/clothing/shoes/footwraps(src) - - -/obj/structure/closet/wardrobe/orange - name = "orange wardrobe" - closed_door_sprite = "orange" - -/obj/structure/closet/wardrobe/orange/populate_contents() - new /obj/item/clothing/under/color/orange(src) - new /obj/item/clothing/under/color/orange(src) - new /obj/item/clothing/under/color/orange(src) - new /obj/item/clothing/under/color/jumpskirt/orange(src) - new /obj/item/clothing/under/color/jumpskirt/orange(src) - new /obj/item/clothing/under/color/jumpskirt/orange(src) - new /obj/item/clothing/shoes/orange(src) - new /obj/item/clothing/shoes/orange(src) - new /obj/item/clothing/shoes/orange(src) - -/obj/structure/closet/wardrobe/orange/prison - name = "prison wardrobe" - desc = "It's a storage unit for Nanotrasen-regulation prisoner attire." - -/obj/structure/closet/wardrobe/orange/prison/populate_contents() - new /obj/item/clothing/under/color/orange/prison(src) - new /obj/item/clothing/under/color/orange/prison(src) - new /obj/item/clothing/under/color/orange/prison(src) - new /obj/item/clothing/under/color/jumpskirt/orange/prison(src) - new /obj/item/clothing/under/color/jumpskirt/orange/prison(src) - new /obj/item/clothing/under/color/jumpskirt/orange/prison(src) - new /obj/item/clothing/shoes/orange(src) - new /obj/item/clothing/shoes/orange(src) - new /obj/item/clothing/shoes/orange(src) - -/obj/structure/closet/wardrobe/yellow - name = "yellow wardrobe" - closed_door_sprite = "yellow" - -/obj/structure/closet/wardrobe/yellow/populate_contents() - new /obj/item/clothing/under/color/yellow(src) - new /obj/item/clothing/under/color/yellow(src) - new /obj/item/clothing/under/color/yellow(src) - new /obj/item/clothing/under/color/jumpskirt/yellow(src) - new /obj/item/clothing/under/color/jumpskirt/yellow(src) - new /obj/item/clothing/under/color/jumpskirt/yellow(src) - new /obj/item/clothing/shoes/orange(src) - new /obj/item/clothing/shoes/orange(src) - new /obj/item/clothing/shoes/orange(src) - - -/obj/structure/closet/wardrobe/atmospherics_yellow - name = "atmospherics wardrobe" - closed_door_sprite = "atmos_wardrobe" - -/obj/structure/closet/wardrobe/atmospherics_yellow/populate_contents() - new /obj/item/clothing/under/rank/engineering/atmospheric_technician(src) - new /obj/item/clothing/under/rank/engineering/atmospheric_technician(src) - new /obj/item/clothing/under/rank/engineering/atmospheric_technician(src) - new /obj/item/clothing/under/rank/engineering/atmospheric_technician/skirt(src) - new /obj/item/clothing/under/rank/engineering/atmospheric_technician/skirt(src) - new /obj/item/clothing/under/rank/engineering/atmospheric_technician/skirt(src) - new /obj/item/clothing/shoes/workboots(src) - new /obj/item/clothing/shoes/workboots(src) - new /obj/item/clothing/shoes/workboots(src) - new /obj/item/clothing/head/hardhat/red(src) - new /obj/item/clothing/head/hardhat/red(src) - new /obj/item/clothing/head/hardhat/red(src) - new /obj/item/clothing/head/beret/atmos(src) - new /obj/item/clothing/head/beret/atmos(src) - new /obj/item/clothing/head/beret/atmos(src) - - - -/obj/structure/closet/wardrobe/engineering_yellow - name = "engineering wardrobe" - closed_door_sprite = "yellow" - -/obj/structure/closet/wardrobe/engineering_yellow/populate_contents() - new /obj/item/clothing/under/rank/engineering/engineer(src) - new /obj/item/clothing/under/rank/engineering/engineer(src) - new /obj/item/clothing/under/rank/engineering/engineer(src) - new /obj/item/clothing/under/rank/engineering/engineer/skirt(src) - new /obj/item/clothing/under/rank/engineering/engineer/skirt(src) - new /obj/item/clothing/under/rank/engineering/engineer/skirt(src) - new /obj/item/clothing/shoes/workboots(src) - new /obj/item/clothing/shoes/workboots(src) - new /obj/item/clothing/shoes/workboots(src) - new /obj/item/clothing/head/hardhat(src) - new /obj/item/clothing/head/hardhat(src) - new /obj/item/clothing/head/hardhat(src) - new /obj/item/clothing/head/beret/eng(src) - new /obj/item/clothing/head/beret/eng(src) - new /obj/item/clothing/head/beret/eng(src) - - -/obj/structure/closet/wardrobe/white - name = "white wardrobe" - closed_door_sprite = "white" - -/obj/structure/closet/wardrobe/white/populate_contents() - new /obj/item/clothing/under/color/white(src) - new /obj/item/clothing/under/color/white(src) - new /obj/item/clothing/under/color/white(src) - new /obj/item/clothing/under/color/jumpskirt/white(src) - new /obj/item/clothing/under/color/jumpskirt/white(src) - new /obj/item/clothing/under/color/jumpskirt/white(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/shoes/white(src) - -/obj/structure/closet/wardrobe/medical_white - name = "medical doctor's wardrobe" - closed_door_sprite = "white" - -/obj/structure/closet/wardrobe/medical_white/populate_contents() - new /obj/item/clothing/under/rank/medical/nursesuit (src) - new /obj/item/clothing/head/nursehat (src) - new /obj/item/clothing/under/rank/medical/nurse(src) - new /obj/item/clothing/under/rank/medical/orderly(src) - new /obj/item/clothing/suit/storage/fr_jacket(src) - new /obj/item/clothing/suit/storage/fr_jacket(src) - new /obj/item/clothing/suit/storage/fr_jacket(src) - new /obj/item/clothing/under/rank/medical/scrubs(src) - new /obj/item/clothing/head/surgery/blue(src) - new /obj/item/clothing/under/rank/medical/scrubs/green(src) - new /obj/item/clothing/head/surgery/green(src) - new /obj/item/clothing/under/rank/medical/scrubs/purple(src) - new /obj/item/clothing/under/rank/medical/doctor/skirt(src) - new /obj/item/clothing/under/rank/medical/doctor/skirt(src) - new /obj/item/clothing/head/surgery/purple(src) - new /obj/item/clothing/under/rank/medical/gown(src) - new /obj/item/clothing/under/rank/medical/gown(src) - new /obj/item/clothing/under/rank/medical/gown(src) - new /obj/item/clothing/under/rank/medical/gown(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/black(src) - -/obj/structure/closet/wardrobe/pjs - name = "Pajama wardrobe" - closed_door_sprite = "white" - -/obj/structure/closet/wardrobe/pjs/populate_contents() - new /obj/item/clothing/under/misc/pj/red(src) - new /obj/item/clothing/under/misc/pj/red(src) - new /obj/item/clothing/under/misc/pj/blue(src) - new /obj/item/clothing/under/misc/pj/blue(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/shoes/slippers(src) - new /obj/item/clothing/shoes/slippers(src) - - -/obj/structure/closet/wardrobe/toxins_white - name = "toxins wardrobe" - closed_door_sprite = "white" - -/obj/structure/closet/wardrobe/toxins_white/populate_contents() - new /obj/item/clothing/under/rank/rnd/scientist(src) - new /obj/item/clothing/under/rank/rnd/scientist(src) - new /obj/item/clothing/under/rank/rnd/scientist(src) - new /obj/item/clothing/under/rank/rnd/scientist/skirt(src) - new /obj/item/clothing/under/rank/rnd/scientist/skirt(src) - new /obj/item/clothing/under/rank/rnd/scientist/skirt(src) - new /obj/item/clothing/suit/storage/labcoat(src) - new /obj/item/clothing/suit/storage/labcoat(src) - new /obj/item/clothing/suit/storage/labcoat(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/shoes/slippers - new /obj/item/clothing/shoes/slippers - new /obj/item/clothing/shoes/slippers - - -/obj/structure/closet/wardrobe/robotics_black - name = "robotics wardrobe" - closed_door_sprite = "black" - -/obj/structure/closet/wardrobe/robotics_black/populate_contents() - new /obj/item/clothing/under/rank/rnd/roboticist(src) - new /obj/item/clothing/under/rank/rnd/roboticist(src) - new /obj/item/clothing/under/rank/rnd/roboticist/skirt(src) - new /obj/item/clothing/under/rank/rnd/roboticist/skirt(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/gloves/fingerless(src) - new /obj/item/clothing/gloves/fingerless(src) - new /obj/item/clothing/head/soft/black(src) - new /obj/item/clothing/head/soft/black(src) - - -/obj/structure/closet/wardrobe/chemistry_white - name = "chemistry wardrobe" - closed_door_sprite = "white" - -/obj/structure/closet/wardrobe/chemistry_white/populate_contents() - new /obj/item/clothing/under/rank/medical/chemist(src) - new /obj/item/clothing/under/rank/medical/chemist(src) - new /obj/item/clothing/under/rank/medical/chemist/skirt(src) - new /obj/item/clothing/under/rank/medical/chemist/skirt(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/suit/storage/labcoat/chemist(src) - new /obj/item/clothing/suit/storage/labcoat/chemist(src) - new /obj/item/storage/backpack/chemistry(src) - new /obj/item/storage/backpack/chemistry(src) - new /obj/item/storage/backpack/satchel_chem(src) - new /obj/item/storage/backpack/satchel_chem(src) - new /obj/item/storage/bag/chemistry(src) - new /obj/item/storage/bag/chemistry(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/clothing/mask/gas(src) - - -/obj/structure/closet/wardrobe/genetics_white - name = "genetics wardrobe" - closed_door_sprite = "white" - -/obj/structure/closet/wardrobe/genetics_white/populate_contents() - new /obj/item/clothing/under/rank/rnd/geneticist(src) - new /obj/item/clothing/under/rank/rnd/geneticist(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/suit/storage/labcoat/genetics(src) - new /obj/item/clothing/suit/storage/labcoat/genetics(src) - new /obj/item/storage/backpack/genetics(src) - new /obj/item/storage/backpack/genetics(src) - new /obj/item/storage/backpack/satchel_gen(src) - new /obj/item/storage/backpack/satchel_gen(src) - - -/obj/structure/closet/wardrobe/virology_white - name = "virology wardrobe" - closed_door_sprite = "white" - -/obj/structure/closet/wardrobe/virology_white/populate_contents() - new /obj/item/clothing/under/rank/medical/virologist(src) - new /obj/item/clothing/under/rank/medical/virologist(src) - new /obj/item/clothing/under/rank/medical/virologist/skirt(src) - new /obj/item/clothing/under/rank/medical/virologist/skirt(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/suit/storage/labcoat/virologist(src) - new /obj/item/clothing/suit/storage/labcoat/virologist(src) - new /obj/item/clothing/mask/surgical(src) - new /obj/item/clothing/mask/surgical(src) - new /obj/item/storage/backpack/virology(src) - new /obj/item/storage/backpack/virology(src) - new /obj/item/storage/backpack/satchel_vir(src) - new /obj/item/storage/backpack/satchel_vir(src) - - -/obj/structure/closet/wardrobe/medic_white - name = "medical wardrobe" - closed_door_sprite = "white" - -/obj/structure/closet/wardrobe/medic_white/populate_contents() - new /obj/item/clothing/under/rank/medical/doctor(src) - new /obj/item/clothing/under/rank/medical/doctor(src) - new /obj/item/clothing/under/rank/medical/doctor/skirt(src) - new /obj/item/clothing/under/rank/medical/doctor/skirt(src) - new /obj/item/clothing/under/rank/medical/scrubs(src) - new /obj/item/clothing/under/rank/medical/scrubs/green(src) - new /obj/item/clothing/under/rank/medical/scrubs/purple(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/suit/storage/labcoat(src) - new /obj/item/clothing/suit/storage/labcoat(src) - new /obj/item/clothing/mask/surgical(src) - new /obj/item/clothing/mask/surgical(src) - new /obj/item/clothing/under/rank/medical/gown(src) - new /obj/item/clothing/under/rank/medical/gown(src) - new /obj/item/clothing/under/rank/medical/gown(src) - new /obj/item/clothing/under/rank/medical/gown(src) - new /obj/item/clothing/head/headmirror(src) - new /obj/item/clothing/head/headmirror(src) - - -/obj/structure/closet/wardrobe/grey - name = "grey wardrobe" - closed_door_sprite = "grey" - -/obj/structure/closet/wardrobe/grey/populate_contents() - new /obj/item/clothing/under/color/grey(src) - new /obj/item/clothing/under/color/grey(src) - new /obj/item/clothing/under/color/grey(src) - new /obj/item/clothing/under/color/jumpskirt/grey(src) - new /obj/item/clothing/under/color/jumpskirt/grey(src) - new /obj/item/clothing/under/color/jumpskirt/grey(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/head/soft(src) - new /obj/item/clothing/head/soft(src) - new /obj/item/clothing/head/soft(src) - if(prob(50)) - new /obj/item/storage/backpack/duffel(src) - if(prob(40)) - new /obj/item/clothing/under/misc/assistantformal(src) - if(prob(40)) - new /obj/item/clothing/under/misc/assistantformal(src) - - -/obj/structure/closet/wardrobe/mixed - name = "mixed wardrobe" - closed_door_sprite = "mixed" - -/obj/structure/closet/wardrobe/mixed/populate_contents() - new /obj/item/clothing/under/color/blue(src) - new /obj/item/clothing/under/color/yellow(src) - new /obj/item/clothing/under/color/green(src) - new /obj/item/clothing/under/color/orange(src) - new /obj/item/clothing/under/color/pink(src) - new /obj/item/clothing/under/color/jumpskirt/blue(src) - new /obj/item/clothing/under/color/jumpskirt/yellow(src) - new /obj/item/clothing/under/color/jumpskirt/green(src) - new /obj/item/clothing/under/color/jumpskirt/orange(src) - new /obj/item/clothing/under/color/jumpskirt/pink(src) - new /obj/item/clothing/shoes/blue(src) - new /obj/item/clothing/shoes/yellow(src) - new /obj/item/clothing/shoes/green(src) - new /obj/item/clothing/shoes/orange(src) - new /obj/item/clothing/shoes/purple(src) - new /obj/item/clothing/shoes/leather(src) - -/obj/structure/closet/wardrobe/coroner - name = "coroner wardrobe" - closed_door_sprite = "black" - -/obj/structure/closet/wardrobe/coroner/populate_contents() - if(prob(50)) - new /obj/item/storage/backpack/medic(src) - else - new /obj/item/storage/backpack/satchel_med(src) - new /obj/item/storage/backpack/duffel/medical(src) - new /obj/item/clothing/suit/storage/labcoat/mortician(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/under/rank/medical/scrubs/coroner(src) - new /obj/item/clothing/head/surgery/black(src) - new /obj/item/reagent_containers/glass/bottle/reagent/formaldehyde(src) - new /obj/item/reagent_containers/dropper(src) - new /obj/item/healthanalyzer(src) diff --git a/code/game/objects/structures/crates_lockers/crittercrate.dm b/code/game/objects/structures/crates_lockers/crittercrate.dm deleted file mode 100644 index a77e8302b81e6..0000000000000 --- a/code/game/objects/structures/crates_lockers/crittercrate.dm +++ /dev/null @@ -1,130 +0,0 @@ -/obj/structure/closet/critter - name = "critter crate" - desc = "A crate designed for safe transport of animals. Only openable from the the outside." - icon_state = "critter" - has_opened_overlay = FALSE - closed_door_sprite = "critter" - door_anim_time = 0 - var/already_opened = FALSE - var/content_mob = null - var/amount = 1 - open_sound = 'sound/machines/wooden_closet_open.ogg' - close_sound = 'sound/machines/wooden_closet_close.ogg' - open_sound_volume = 25 - close_sound_volume = 50 - -/obj/structure/closet/critter/can_open() - if(welded) - return - return TRUE - -/obj/structure/closet/critter/open() - if(!can_open()) - return - - if(content_mob == null) //making sure we don't spawn anything too eldritch - already_opened = TRUE - return ..() - - if(content_mob != null && already_opened == 0) - for(var/i = 1, i <= amount, i++) - new content_mob(loc) - already_opened = TRUE - . = ..() - -/obj/structure/closet/critter/close() - ..() - return TRUE - - -/obj/structure/closet/critter/shove_impact(mob/living/target, mob/living/attacker) - return FALSE - -/obj/structure/closet/critter/random - name = "unmarked crate" - desc = "A crate designed for safe transport of animals. The contents are a mystery." - -/obj/structure/closet/critter/random/populate_contents() - content_mob = pick(/mob/living/simple_animal/pet/dog/corgi, - /mob/living/simple_animal/pet/dog/corgi/lisa, - /mob/living/simple_animal/cow, - /mob/living/simple_animal/pig, - /mob/living/simple_animal/hostile/retaliate/goat, - /mob/living/simple_animal/turkey, - /mob/living/simple_animal/chick, - /mob/living/simple_animal/pet/cat, - /mob/living/simple_animal/pet/dog/pug, - /mob/living/simple_animal/pet/dog/fox, - /mob/living/simple_animal/deer, - /mob/living/simple_animal/bunny) - -/obj/structure/closet/critter/corgi - name = "corgi crate" - content_mob = /mob/living/simple_animal/pet/dog/corgi - -/obj/structure/closet/critter/corgi/populate_contents() - if(prob(50)) - content_mob = /mob/living/simple_animal/pet/dog/corgi/lisa - -/obj/structure/closet/critter/cow - name = "cow crate" - content_mob = /mob/living/simple_animal/cow - -/obj/structure/closet/critter/pig - name = "pig crate" - content_mob = /mob/living/simple_animal/pig - -/obj/structure/closet/critter/goat - name = "goat crate" - content_mob = /mob/living/simple_animal/hostile/retaliate/goat - -/obj/structure/closet/critter/turkey - name = "turkey crate" - content_mob = /mob/living/simple_animal/turkey - -/obj/structure/closet/critter/chick - name = "chicken crate" - content_mob = /mob/living/simple_animal/chick - -/obj/structure/closet/critter/chick/populate_contents() - amount = rand(1, 3) - -/obj/structure/closet/critter/cat - name = "cat crate" - content_mob = /mob/living/simple_animal/pet/cat - -/obj/structure/closet/critter/cat/populate_contents() - if(prob(50)) - content_mob = /mob/living/simple_animal/pet/cat/proc_cat - -/obj/structure/closet/critter/pug - name = "pug crate" - content_mob = /mob/living/simple_animal/pet/dog/pug - -/obj/structure/closet/critter/fox - name = "fox crate" - content_mob = /mob/living/simple_animal/pet/dog/fox - -/obj/structure/closet/critter/butterfly - name = "butterfly crate" - content_mob = /mob/living/simple_animal/butterfly - -/obj/structure/closet/critter/nian_caterpillar - name = "nian caterpillar crate" - content_mob = /mob/living/simple_animal/nian_caterpillar - -/obj/structure/closet/critter/deer - name = "deer crate" - content_mob = /mob/living/simple_animal/deer - -/obj/structure/closet/critter/bunny - name = "bunny crate" - content_mob = /mob/living/simple_animal/bunny - -/obj/structure/closet/critter/gorilla - name = "gorilla crate" - content_mob = /mob/living/simple_animal/hostile/gorilla - -/obj/structure/closet/critter/gorilla/cargo - name = "cargorilla crate" - content_mob = /mob/living/simple_animal/hostile/gorilla/cargo_domestic diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm deleted file mode 100644 index d9642b8788660..0000000000000 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ /dev/null @@ -1,121 +0,0 @@ -/obj/structure/largecrate - name = "large crate" - desc = "A hefty wooden crate." - icon = 'icons/obj/crates.dmi' - icon_state = "largecrate" - density = TRUE - var/obj/item/paper/manifest/manifest - -/obj/structure/largecrate/Initialize(mapload) - . = ..() - update_icon() - -/obj/structure/largecrate/update_overlays() - . = ..() - if(manifest) - . += "manifest" - -/obj/structure/largecrate/attack_hand(mob/user as mob) - if(manifest) - to_chat(user, "You tear the manifest off of the crate.") - playsound(src.loc, 'sound/items/poster_ripped.ogg', 75, 1) - manifest.forceMove(loc) - if(ishuman(user)) - user.put_in_hands(manifest) - manifest = null - update_icon() - return - else - to_chat(user, "You need a crowbar to pry this open!") - return - -/obj/structure/largecrate/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) - if(user.a_intent != INTENT_HARM) - attack_hand(user) - else - return ..() - -/obj/structure/largecrate/crowbar_act(mob/living/user, obj/item/I) - . = TRUE - if(manifest) - manifest.forceMove(loc) - manifest = null - update_icon() - new /obj/item/stack/sheet/wood(src) - var/turf/T = get_turf(src) - for(var/O in contents) - var/atom/movable/A = O - A.forceMove(T) - user.visible_message("[user] pries [src] open.", \ - "You pry open [src].", \ - "You hear splitting wood.") - qdel(src) - -/obj/structure/largecrate/Destroy() - var/turf/src_turf = get_turf(src) - for(var/obj/O in contents) - O.forceMove(src_turf) - return ..() - -/obj/structure/largecrate/mule - -/obj/structure/largecrate/lisa - icon_state = "lisacrate" - -/obj/structure/largecrate/lisa/crowbar_act(mob/living/user, obj/item/I) - if(!I.use_tool(src, user, I.tool_volume)) - return - new /mob/living/simple_animal/pet/dog/corgi/lisa(loc) - return ..() - -/obj/structure/largecrate/cow - name = "cow crate" - icon_state = "lisacrate" - -/obj/structure/largecrate/cow/crowbar_act(mob/living/user, obj/item/I) - if(!I.use_tool(src, user, I.tool_volume)) - return - new /mob/living/simple_animal/cow(loc) - return ..() - -/obj/structure/largecrate/goat - name = "goat crate" - icon_state = "lisacrate" - -/obj/structure/largecrate/goat/crowbar_act(mob/living/user, obj/item/I) - if(!I.use_tool(src, user, I.tool_volume)) - return - new /mob/living/simple_animal/hostile/retaliate/goat(loc) - return ..() - -/obj/structure/largecrate/chick - name = "chicken crate" - icon_state = "lisacrate" - -/obj/structure/largecrate/chick/crowbar_act(mob/living/user, obj/item/I) - if(!I.use_tool(src, user, I.tool_volume)) - return - var/num = rand(4, 6) - for(var/i in 1 to num) - new /mob/living/simple_animal/chick(loc) - return ..() - -/obj/structure/largecrate/cat - name = "cat crate" - icon_state = "lisacrate" - -/obj/structure/largecrate/cat/crowbar_act(mob/living/user, obj/item/I) - if(!I.use_tool(src, user, I.tool_volume)) - return - new /mob/living/simple_animal/pet/cat(loc) - return ..() - -/obj/structure/largecrate/secway - name = "secway crate" - -/obj/structure/largecrate/secway/crowbar_act(mob/living/user, obj/item/I) - if(!I.use_tool(src, user, I.tool_volume)) - return - new /obj/vehicle/secway(loc) - new /obj/item/key/security(loc) - return ..() diff --git a/code/game/objects/structures/curtains.dm b/code/game/objects/structures/curtains.dm deleted file mode 100644 index 31262011e5692..0000000000000 --- a/code/game/objects/structures/curtains.dm +++ /dev/null @@ -1,106 +0,0 @@ -#define SHOWER_OPEN_LAYER OBJ_LAYER + 0.4 -#define SHOWER_CLOSED_LAYER MOB_LAYER + 0.1 - -/obj/structure/curtain - icon = 'icons/obj/curtain.dmi' - name = "curtain" - icon_state = "closed" - face_while_pulling = FALSE - layer = SHOWER_CLOSED_LAYER - opacity = TRUE - density = FALSE - new_attack_chain = TRUE - -/obj/structure/curtain/open - icon_state = "open" - layer = SHOWER_OPEN_LAYER - opacity = FALSE - -/obj/structure/curtain/attack_hand(mob/user) - playsound(get_turf(loc), "rustle", 15, TRUE, -5) - toggle() - ..() - -/obj/structure/curtain/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - if(damage_amount) - playsound(src.loc, 'sound/weapons/slash.ogg', 80, TRUE) - else - playsound(loc, 'sound/weapons/tap.ogg', 50, TRUE) - if(BURN) - playsound(loc, 'sound/items/welder.ogg', 80, TRUE) - -/obj/structure/curtain/proc/toggle() - set_opacity(!opacity) - if(opacity) - icon_state = "closed" - layer = SHOWER_CLOSED_LAYER - else - icon_state = "open" - layer = SHOWER_OPEN_LAYER - -/obj/structure/curtain/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(istype(used, /obj/item/toy/crayon)) - color = tgui_input_color(user,"Please choose a color.", "Curtain Color") - return ITEM_INTERACT_COMPLETE - -/obj/structure/curtain/screwdriver_act(mob/user, obj/item/I) - . = TRUE - if(!I.tool_start_check(src, user, 0)) - return - if(anchored) - user.visible_message("[user] unscrews [src] from the floor.", "You start to unscrew [src] from the floor...", "You hear rustling noises.") - if(I.use_tool(src, user, 50, volume = I.tool_volume) && anchored) - anchored = FALSE - to_chat(user, "You unscrew [src] from the floor.") - else - user.visible_message("[user] screws [src] to the floor.", "You start to screw [src] to the floor...", "You hear rustling noises.") - if(I.use_tool(src, user, 50, volume = I.tool_volume) && !anchored) - anchored = TRUE - to_chat(user, "You screw [src] to the floor.") - - - -/obj/structure/curtain/wirecutter_act(mob/user, obj/item/I) - if(anchored) - return - . = TRUE - if(!I.tool_start_check(src, user, 0)) - return - WIRECUTTER_ATTEMPT_DISMANTLE_MESSAGE - if(I.use_tool(src, user, 50, volume = I.tool_volume)) - WIRECUTTER_DISMANTLE_SUCCESS_MESSAGE - deconstruct() - -/obj/structure/curtain/deconstruct(disassembled = TRUE) - new /obj/item/stack/sheet/cloth(loc, 2) - new /obj/item/stack/sheet/plastic(loc, 2) - new /obj/item/stack/rods(loc, 1) - qdel(src) - -/obj/structure/curtain/black - name = "black curtain" - color = "#222222" - -/obj/structure/curtain/medical - name = "plastic curtain" - color = "#B8F5E3" - alpha = 200 - -/obj/structure/curtain/open/shower - name = "shower curtain" - color = "#ACD1E9" - alpha = 200 - -/obj/structure/curtain/open/shower/engineering - color = "#FFA500" - -/obj/structure/curtain/open/shower/security - color = "#AA0000" - -/obj/structure/curtain/open/shower/centcom - color = "#000066" - -#undef SHOWER_OPEN_LAYER -#undef SHOWER_CLOSED_LAYER diff --git a/code/game/objects/structures/depot_structures.dm b/code/game/objects/structures/depot_structures.dm deleted file mode 100644 index cbfc9370fefe1..0000000000000 --- a/code/game/objects/structures/depot_structures.dm +++ /dev/null @@ -1,121 +0,0 @@ - -/obj/structure/fusionreactor - name = "syndicate fusion reactor" - desc = "Significantly less cool than a supermatter crystal, but just as likely to fuck up." - icon = 'icons/goonstation/objects/powersink.dmi' - icon_state = "powersink1" - anchored = TRUE - max_integrity = 50 - var/area/syndicate_depot/core/depotarea - var/has_overloaded = FALSE - -/obj/structure/fusionreactor/Initialize(mapload) - . = ..() - depotarea = get_area(src) - if(istype(depotarea)) - depotarea.reactor = src - for(var/obj/machinery/porta_turret/syndicate/T in range(50, loc)) - if(!istype(T.depotarea)) - T.depotarea = depotarea - else - log_debug("[src] at [x],[y],[z] failed depotarea istype check during Initialize()! Either it was spawned outside the depot area (bad idea), or a bug is happening.") - -/obj/structure/fusionreactor/Destroy() - if(istype(depotarea)) - if(!has_overloaded) - overload(TRUE, TRUE) - depotarea.reactor = null - return ..() - -/obj/structure/fusionreactor/ex_act(severity) - if(severity < EXPLODE_LIGHT) - obj_integrity = 0 - healthcheck() - -/obj/structure/fusionreactor/proc/healthcheck() - if(obj_integrity <= 0 && istype(depotarea)) - overload(TRUE) - -/obj/structure/fusionreactor/screwdriver_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - to_chat(user, "You try to screwdriver open [src], but accidentally release some radiation!") - if(prob(50)) - empulse(src, 4, 10) - else - radiation_pulse(get_turf(src), 500, 2) - -/obj/structure/fusionreactor/wrench_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - to_chat(user, "[src] is too well secured to the floor.") - -/obj/structure/fusionreactor/proc/overload(containment_failure = FALSE, skip_qdel = FALSE) - if(has_overloaded) - return - has_overloaded = TRUE - if(istype(depotarea) && !depotarea.used_self_destruct) - depotarea.activate_self_destruct("Fusion reactor cracked open. Core loose!", TRUE) - var/obj/effect/overload/O = new /obj/effect/overload(get_turf(src)) - if(containment_failure) - playsound(loc, 'sound/machines/alarm.ogg', 100, FALSE, 0) - O.deliberate = TRUE - O.max_cycles = 6 - if(!skip_qdel) - qdel(src) - - -/obj/effect/overload - icon = 'icons/obj/tesla_engine/energy_ball.dmi' - icon_state = "energy_ball" - pixel_x = -32 - pixel_y = -32 - anchored = TRUE - var/cycles = 0 - var/beepsound = 'sound/items/timer.ogg' - var/deliberate = FALSE - var/max_cycles = 10 - var/area/syndicate_depot/core/depotarea - -/obj/effect/overload/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - depotarea = get_area(src) - if(istype(depotarea)) - if(!depotarea.used_self_destruct) - depotarea.used_self_destruct = TRUE // Silences all further alerts from this point onwards. - depotarea.update_state() - else - log_debug("[src] at [x],[y],[z] failed depotarea istype check during Initialize()! Either it was spawned outside the depot area (bad idea), or a bug is happening.") - -/obj/effect/overload/process() - var/turf/T = get_turf(src) - if(cycles < max_cycles) - if(!deliberate) - playsound(loc, beepsound, 50, 0) - cycles++ - return - - if(!istype(depotarea)) - depotarea = get_area(src) - if(istype(depotarea)) - depotarea.destroyed = TRUE - depotarea.update_state() - - for(var/obj/structure/closet/L in range(30, T)) - for(var/obj/O in L) - qdel(O) - L.open() - depotarea.shields_down() - for(var/mob/living/M in range(30, T)) - M.gib() - for(var/obj/mecha/E in range(30, T)) - E.take_damage(E.max_integrity) - explosion(get_turf(src), 25, 35, 45, 55, 1, 1, 60, 0) - STOP_PROCESSING(SSobj, src) - qdel(src) - -/obj/effect/overload/ex_act(severity) - return diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm deleted file mode 100644 index 94953b6f8ba9f..0000000000000 --- a/code/game/objects/structures/displaycase.dm +++ /dev/null @@ -1,311 +0,0 @@ -/obj/structure/displaycase - name = "display case" - icon = 'icons/obj/stationobjs.dmi' - icon_state = "glassbox" - desc = "A display case for prized possessions." - density = TRUE - anchored = TRUE - resistance_flags = ACID_PROOF - armor = list(MELEE = 30, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, RAD = 0, FIRE = 70, ACID = 100) - max_integrity = 200 - integrity_failure = 50 - /// The object stored inside. - var/obj/item/showpiece - /// If true, this is alarmed and will set off a siren when opened without proper access. - var/alert = FALSE - /// If this is currently unlocked - var/open = FALSE - /// If false, this can never be opened, and the item inside should be inaccessible. Good for showcases. - var/openable = TRUE - /// The electronics currently installed in this showpiece. - var/obj/item/airlock_electronics/electronics - /// The type that should be instantiated to fill the showpiece. - var/start_showpiece_type - /// A list of random items that could possibly fill the case, as well as a flavor message for them. - /// Takes sublists in the form of list("type" = /obj/item/bikehorn, "trophy_message" = "henk") - var/list/start_showpieces = list() - /// A flavor message to show with this item. - var/trophy_message = "" - /// Do we want to force alarms even if off station? - var/force_alarm = FALSE - -/obj/structure/displaycase/Initialize(mapload) - . = ..() - if(length(start_showpieces) && !start_showpiece_type) - var/list/showpiece_entry = pick(start_showpieces) - if(showpiece_entry && showpiece_entry["type"]) - start_showpiece_type = showpiece_entry["type"] - if(showpiece_entry["trophy_message"]) - trophy_message = showpiece_entry["trophy_message"] - if(start_showpiece_type) - showpiece = new start_showpiece_type(src) - update_icon(UPDATE_OVERLAYS) - -/obj/structure/displaycase/Destroy() - QDEL_NULL(electronics) - QDEL_NULL(showpiece) - return ..() - -/obj/structure/displaycase/emag_act(mob/user) - if(!emagged) - to_chat(user, "You override the ID lock on [src].") - trigger_alarm() - - emagged = TRUE - toggle_lock() - return TRUE - -/obj/structure/displaycase/examine(mob/user) - . = ..() - if(showpiece) - . += "There's \a [showpiece] displayed inside." - else - . += "It's empty." - if(trophy_message) - . += "The plaque reads:\n [trophy_message]" - if(!openable) - . += "It seems to be sealed shut, there's no way you're getting that open." - else - if(!open) - . += "The ID lock is active, you need to swipe an ID to open it." - else if((broken || open) && showpiece) - . += "[showpiece] is held in a loose low gravity suspension field. You can take [showpiece] out[broken ? "." : ", or lock [src] with an ID"]." - - if(alert) - . += "It is hooked up with an anti-theft system." - if(emagged) - . += "The ID lock has been shorted out." - -/obj/structure/displaycase/proc/dump(mob/user) - if(showpiece) - if(!user || !user.put_in_hands(showpiece)) - showpiece.forceMove(loc) - showpiece = null - -/obj/structure/displaycase/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - playsound(loc, 'sound/effects/glasshit.ogg', 75, TRUE) - if(BURN) - playsound(loc, 'sound/items/welder.ogg', 100, TRUE) - -/obj/structure/displaycase/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - dump() - if(!disassembled) - new /obj/item/shard(drop_location()) - trigger_alarm() - qdel(src) - -/obj/structure/displaycase/obj_break(damage_flag) - if(!broken && !(flags & NODECONSTRUCT)) - density = FALSE - broken = TRUE - open = TRUE - new /obj/item/shard(drop_location()) - playsound(src, "shatter", 70, TRUE) - update_icon(UPDATE_OVERLAYS) - trigger_alarm() - -/obj/structure/displaycase/proc/trigger_alarm() - set waitfor = FALSE - if(alert && (is_station_contact(z) || force_alarm)) - var/area/alarmed = get_area(src) - alarmed.burglaralert(src) - visible_message("The burglar alarm goes off!") - // Play the burglar alarm three times - for(var/i = 0, i < 4, i++) - playsound(src, 'sound/machines/burglar_alarm.ogg', 50, 0) - sleep(74) // 7.4 seconds long - -/obj/structure/displaycase/update_overlays() - . = ..() - if(broken) - . += "glassbox_broken" - if(showpiece) - var/mutable_appearance/showpiece_overlay = mutable_appearance(showpiece.icon, showpiece.icon_state) - showpiece_overlay.copy_overlays(showpiece) - showpiece_overlay.transform *= 0.6 - . += showpiece_overlay - if(!open && !broken) - . += "glassbox_closed" - -/obj/structure/displaycase/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(I.GetID()) - if(!openable) - to_chat(user, "There is no ID scanner, looks like this one is sealed shut.") - return - if(broken) - to_chat(user, "[src] is broken, the ID lock won't do anything.") - return - if(allowed(user) || emagged) - to_chat(user, "You use [I] to [open ? "close" : "open"] [src].") - toggle_lock() - else - to_chat(user, "Access denied.") - else if(open && !showpiece) - if(!(I.flags & (ABSTRACT | DROPDEL)) && user.drop_item()) - I.forceMove(src) - showpiece = I - to_chat(user, "You put [I] on display") - update_icon() - else if(istype(I, /obj/item/stack/sheet/glass) && broken) - var/obj/item/stack/sheet/glass/G = I - if(G.get_amount() < 2) - to_chat(user, "You need two glass sheets to fix the case!") - return - to_chat(user, "You start fixing [src]...") - if(do_after(user, 20, target = src)) - G.use(2) - broken = FALSE - open = FALSE - obj_integrity = max_integrity - update_icon(UPDATE_OVERLAYS) - else - return ..() - -/obj/structure/displaycase/crowbar_act(mob/user, obj/item/I) - if((alert && !open) || !openable) - return - if(open && !showpiece && user.a_intent == INTENT_HELP) // The user can display a crowbar if they're on that intent specifically. Otherwise they'll either take it apart, or close it if the alarm's off - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - if((open || broken) && user.a_intent == INTENT_HARM) - if(showpiece) - to_chat(user, "Remove the displayed object first.") - return - if(!I.use_tool(src, user, 15, volume = I.tool_volume)) - return - if(!broken) - new /obj/item/stack/sheet/glass(drop_location(), 10) - else - new /obj/item/shard(drop_location()) - to_chat(user, "You start dismantling the case.") - var/obj/structure/displaycase_chassis/display = new(loc) - if(electronics) - electronics.forceMove(display) - display.electronics = electronics - qdel(src) - return - if(!alert) - to_chat(user, "You start to [open ? "close":"open"] [src].") - if(!I.use_tool(src, user, 20, volume = I.tool_volume)) - return - to_chat(user, "You [open ? "close":"open"] [src].") - toggle_lock() - -/obj/structure/displaycase/welder_act(mob/user, obj/item/I) - . = TRUE - if(default_welder_repair(user, I)) - broken = FALSE - -/obj/structure/displaycase/proc/toggle_lock() - open = !open - update_icon(UPDATE_OVERLAYS) - -/obj/structure/displaycase/attack_hand(mob/user) - user.changeNext_move(CLICK_CD_MELEE) - if(showpiece && (broken || open)) - to_chat(user, "You deactivate the hover field built into the case.") - dump(user) - add_fingerprint(user) - update_icon(UPDATE_OVERLAYS) - return - if(!open && openable) - to_chat(user, "The ID lock is active, you'll need to unlock it first.") - return - //prevents remote "kicks" with TK - if(!Adjacent(user)) - return - user.visible_message("[user] kicks the display case.") - user.do_attack_animation(src, ATTACK_EFFECT_KICK) - take_damage(2) - -/obj/structure/displaycase_chassis - anchored = TRUE - density = FALSE - name = "display case chassis" - desc = "The wooden base of a display case." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "glassbox_chassis" - var/obj/item/airlock_electronics/electronics - -/obj/structure/displaycase_chassis/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/airlock_electronics)) - to_chat(user, "You start installing the electronics into [src]...") - playsound(loc, I.usesound, 50, TRUE) - if(do_after(user, 30, target = src)) - var/obj/item/airlock_electronics/new_electronics = I - if(user.drop_item() && !new_electronics.is_installed) - new_electronics.forceMove(src) - electronics = new_electronics - to_chat(user, "You install the airlock electronics.") - electronics.is_installed = TRUE - - else if(istype(I, /obj/item/stack/sheet/glass)) - var/obj/item/stack/sheet/glass/G = I - if(G.get_amount() < 10) - to_chat(user, "You need ten glass sheets to do this!") - return - to_chat(user, "You start adding [G] to [src]...") - if(do_after(user, 20, target = src)) - G.use(10) - var/obj/structure/displaycase/display = new(loc) - if(electronics) - electronics.forceMove(display) - display.electronics = electronics - display.alert = TRUE - if(electronics.one_access) - display.req_one_access = electronics.selected_accesses - else - display.req_access = electronics.selected_accesses - qdel(src) - else - return ..() - -/obj/structure/displaycase_chassis/crowbar_act(mob/user, obj/item/I) - . = TRUE - if(!I.tool_use_check(user, 0)) - return - if(electronics) - if(I.use_tool(src, user, 0, volume = I.tool_volume)) - to_chat(user, "You remove the airlock electronics.") - new /obj/item/airlock_electronics(drop_location(), 1) - electronics.is_installed = FALSE - electronics = null - -/obj/structure/displaycase_chassis/wrench_act(mob/user, obj/item/I) - . = TRUE - if(!I.tool_use_check(user, 0)) - return - if(electronics) - to_chat(user, "Remove the airlock electronics first.") - return - TOOL_ATTEMPT_DISMANTLE_MESSAGE - if(!I.use_tool(src, user, 30, volume = I.tool_volume)) - return - TOOL_DISMANTLE_SUCCESS_MESSAGE - new /obj/item/stack/sheet/wood(drop_location(), 5) - qdel(src) - -//The lab cage and captains display case do not spawn with electronics, which is why req_access is needed. -/obj/structure/displaycase/captain - alert = TRUE - start_showpiece_type = /obj/item/gun/energy/laser/captain - req_access = list(ACCESS_CAPTAIN) - -/obj/structure/displaycase/labcage - name = "lab cage" - alert = TRUE - desc = "A glass lab container for storing interesting creatures." - start_showpiece_type = /obj/item/clothing/mask/facehugger/lamarr - req_access = list(ACCESS_RD) - -/obj/structure/displaycase/stechkin - name = "officer's display case" - alert = TRUE - desc = "A display case containing a humble stechkin pistol. Never forget your roots." - start_showpiece_type = /obj/item/gun/projectile/automatic/pistol - req_access = list(ACCESS_SYNDICATE_COMMAND) diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm deleted file mode 100644 index 4566e9bbfc26e..0000000000000 --- a/code/game/objects/structures/door_assembly.dm +++ /dev/null @@ -1,315 +0,0 @@ -/obj/structure/door_assembly - name = "airlock assembly" - icon = 'icons/obj/doors/airlocks/station/public.dmi' - icon_state = "construction" - anchored = FALSE - density = TRUE - max_integrity = 200 - var/overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - var/state = AIRLOCK_ASSEMBLY_NEEDS_WIRES - /// String value. Used in user chat messages - var/mineral - /// mineral object path. - var/mineral_type - - var/base_name = "airlock" - var/obj/item/airlock_electronics/electronics - var/airlock_type = /obj/machinery/door/airlock //the type path of the airlock once completed - var/glass_type = /obj/machinery/door/airlock/glass - var/glass = FALSE // FALSE = glass can be installed. TRUE = glass is already installed. - var/polarized_glass = FALSE - var/created_name - var/reinforced_glass = FALSE // FALSE = rglass can be installed. TRUE = rglass is already installed. - var/noglass = FALSE //airlocks with no glass version, also cannot be modified with sheets - var/material_type = /obj/item/stack/sheet/metal - var/material_amt = 4 - var/heat_resistance = 1000 - -/obj/structure/door_assembly/Initialize(mapload) - . = ..() - update_appearance(UPDATE_NAME | UPDATE_OVERLAYS) - -/obj/structure/door_assembly/Destroy() - QDEL_NULL(electronics) - return ..() - -/obj/structure/door_assembly/examine(mob/user) - . = ..() - var/doorname = "" - if(created_name) - doorname = ", written on it is '[created_name]'" - switch(state) - if(AIRLOCK_ASSEMBLY_NEEDS_WIRES) - if(anchored) - . += "The anchoring bolts are wrenched in place, but the maintenance panel lacks wiring." - else - . += "The assembly is welded together, but the anchoring bolts are unwrenched." - if(AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) - . += "The maintenance panel is wired, but the circuit slot is empty." - if(AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) - . += "The circuit is connected loosely to its slot, but the maintenance panel is unscrewed and open." - if(glass) - . += "The assembly has its electrochromic windows [polarized_glass ? "enabled" : "disabled"] and can be configured." - if(!glass && !noglass) - . += "There is a small paper placard on the assembly[doorname]. There are empty slots for glass windows." - else - . += "There is a small paper placard on the assembly[doorname]." - -/obj/structure/door_assembly/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(is_pen(W)) - // The door assembly gets renamed to "Assembly - Foobar", - // but the `t` returned from the proc is just "Foobar" without the prefix. - var/t = rename_interactive(user, W) - if(!isnull(t)) - created_name = t - return - - else if(iscoil(W) && state == AIRLOCK_ASSEMBLY_NEEDS_WIRES && anchored) - var/obj/item/stack/cable_coil/coil = W - if(coil.get_amount() < 1) - to_chat(user, "You need one length of cable to wire the airlock assembly!") - return - user.visible_message("[user] wires the airlock assembly.", "You start to wire the airlock assembly...") - if(do_after(user, 40 * coil.toolspeed, target = src)) - if(coil.get_amount() < 1 || state != AIRLOCK_ASSEMBLY_NEEDS_WIRES) - return - coil.use(1) - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - to_chat(user, "You wire the airlock assembly.") - - else if(istype(W, /obj/item/airlock_electronics) && state == AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS && !istype(W, /obj/item/airlock_electronics/destroyed)) - playsound(loc, W.usesound, 100, 1) - user.visible_message("[user] installs the electronics into the airlock assembly.", "You start to install electronics into the airlock assembly...") - - if(do_after(user, 40 * W.toolspeed, target = src)) - var/obj/item/airlock_electronics/new_electronics = W - if(state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS || new_electronics.is_installed) - return - user.drop_item() - new_electronics.forceMove(src) - to_chat(user, "You install the airlock electronics.") - state = AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER - name = "near finished airlock assembly" - electronics = new_electronics - electronics.is_installed = TRUE - - else if(istype(W, /obj/item/stack/sheet) && (!glass || !mineral)) - var/obj/item/stack/sheet/S = W - if(S) - if(S.get_amount() >= 1) - if(!noglass) - if(!glass) - if(istype(S, /obj/item/stack/sheet/rglass) || istype(S, /obj/item/stack/sheet/glass)) - playsound(loc, S.usesound, 100, 1) - user.visible_message("[user] adds [S.name] to the airlock assembly.", "You start to install [S.name] into the airlock assembly...") - if(do_after(user, 40 * S.toolspeed, target = src)) - if(S.get_amount() < 1 || glass) - return - if(S.type == /obj/item/stack/sheet/rglass) - to_chat(user, "You install reinforced glass windows into the airlock assembly.") - reinforced_glass = TRUE - else - to_chat(user, "You install regular glass windows into the airlock assembly.") - S.use(1) - glass = TRUE - else - to_chat(user, "You cannot add [S] to [src]!") - else - to_chat(user, "You cannot add [S] to [src]!") - else - return ..() - update_appearance(UPDATE_NAME | UPDATE_OVERLAYS) - -/obj/structure/door_assembly/crowbar_act(mob/user, obj/item/I) - if(state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - user.visible_message("[user] is removing the electronics from the airlock assembly...", "You start to remove electronics from the airlock assembly...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) - return - to_chat(user, "You remove the airlock electronics.") - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - name = "wired airlock assembly" - var/obj/item/airlock_electronics/ae - if(!electronics) - ae = new/obj/item/airlock_electronics(loc) - else - ae = electronics - electronics = null - ae.forceMove(loc) - ae.is_installed = FALSE - update_appearance(UPDATE_NAME | UPDATE_OVERLAYS) - -/obj/structure/door_assembly/screwdriver_act(mob/user, obj/item/I) - if(state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - user.visible_message("[user] is finishing the airlock...", \ - "You start finishing the airlock...") - . = TRUE - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) - return - to_chat(user, "You finish the airlock.") - var/obj/machinery/door/airlock/door - if(glass || reinforced_glass) - door = new glass_type(loc) - door.polarized_glass = polarized_glass - else - door = new airlock_type(loc) - door.setDir(dir) - door.electronics = electronics - door.unres_sides = electronics.unres_access_from - if(electronics.one_access) - door.req_access = null - door.req_one_access = electronics.selected_accesses - else - door.req_access = electronics.selected_accesses - if(created_name) - door.name = created_name - else - door.name = base_name - electronics.forceMove(door) - electronics = null - qdel(src) - update_icon(UPDATE_OVERLAYS) - -/obj/structure/door_assembly/wirecutter_act(mob/user, obj/item/I) - if(state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - user.visible_message("[user] is cutting the wires from the airlock assembly...", "You start to cut the wires from airlock assembly...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) - return - to_chat(user, "You cut the wires from the airlock assembly.") - new/obj/item/stack/cable_coil(get_turf(user), 1) - state = AIRLOCK_ASSEMBLY_NEEDS_WIRES - update_icon(UPDATE_OVERLAYS) - -/obj/structure/door_assembly/wrench_act(mob/user, obj/item/I) - if(state != AIRLOCK_ASSEMBLY_NEEDS_WIRES) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - if(anchored) - user.visible_message("[user] is unsecuring the airlock assembly from the floor...", "You start to unsecure the airlock assembly from the floor...") - else - user.visible_message("[user] is securing the airlock assembly to the floor...", "You start to secure the airlock assembly to the floor...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state != AIRLOCK_ASSEMBLY_NEEDS_WIRES) - return - to_chat(user, "You [anchored ? "un" : ""]secure the airlock assembly.") - anchored = !anchored - -/obj/structure/door_assembly/welder_act(mob/user, obj/item/I) - . = TRUE - if(!I.tool_use_check(user, 0)) - return - if(glass) - user.visible_message("[user] welds the glass panel out of [src].",\ - "You start to weld the glass panel out of the [src]...",\ - "You hear welding.") - if(!I.use_tool(src, user, 40, volume = I.tool_volume)) - return - to_chat(user, "You weld the glass panel out.") - if(reinforced_glass) - new /obj/item/stack/sheet/rglass(get_turf(src)) - reinforced_glass = FALSE - else - new /obj/item/stack/sheet/glass(get_turf(src)) - glass = FALSE - polarized_glass = FALSE - else if(!anchored) - visible_message("[user] disassembles [src].", \ - "You start to disassemble [src]...",\ - "You hear welding.") - if(!I.use_tool(src, user, 40, volume = I.tool_volume)) - return - to_chat(user, "You disassemble the airlock assembly.") - deconstruct(TRUE) - update_icon(UPDATE_OVERLAYS) - -/obj/structure/door_assembly/multitool_act(mob/user, obj/item/I) - if(noglass) - return - . = TRUE - if(state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) - to_chat(user, "The airlock assembly needs its electronics before you can configure the electrochromic windows.") - return - if(!glass && !noglass) - to_chat(user, "The airlock assembly needs glass before you can configure the electrochromic windows.") - return - - if(!I.tool_use_check(user, 0)) - return - user.visible_message("[user] is configuring the windows in the airlock assembly...", "You start to configure the windows in the airlock assembly...") - if(!I.use_tool(src, user, 4 SECONDS, volume = I.tool_volume) || state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) - return - - polarized_glass = !polarized_glass - - to_chat(user, "You [polarized_glass ? "enable" : "disable"] the electrochromic windows in the airlock assembly.") - -/obj/structure/door_assembly/update_overlays() - . = ..() - if(!glass) - . += get_airlock_overlay("fill_construction", icon) - else if(glass) - . += get_airlock_overlay("glass_construction", overlays_file) - . += get_airlock_overlay("panel_c[state+1]", overlays_file) - -/obj/structure/door_assembly/update_name() - . = ..() - name = "" - switch(state) - if(AIRLOCK_ASSEMBLY_NEEDS_WIRES) - if(anchored) - name = "secured " - if(AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) - name = "wired " - if(AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) - name = "near finished " - name += "[reinforced_glass ? "window " : ""][glass ? "window " : ""][base_name] assembly" - -/obj/structure/door_assembly/proc/transfer_assembly_vars(obj/structure/door_assembly/source, obj/structure/door_assembly/target, previous = FALSE) - target.glass = source.glass - target.reinforced_glass = source.reinforced_glass - target.created_name = source.created_name - target.state = source.state - target.anchored = source.anchored - if(electronics) - target.electronics = source.electronics - source.electronics.forceMove(target) - target.update_appearance(UPDATE_NAME|UPDATE_OVERLAYS) - qdel(source) - -/obj/structure/door_assembly/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - var/turf/T = get_turf(src) - var/to_spawn_type - if(mineral_type) - to_spawn_type = mineral_type - else - to_spawn_type = material_type - if(!disassembled) - material_amt = rand(2,4) - new to_spawn_type(T, material_amt) - if(glass) - if(disassembled) - if(reinforced_glass) - new /obj/item/stack/sheet/rglass(T) - else - new /obj/item/stack/sheet/glass(T) - else - new /obj/item/shard(T) - qdel(src) - -/obj/structure/door_assembly/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ..() - if(exposed_temperature > (T0C + heat_resistance)) - take_damage(round(exposed_volume / 100), BURN, 0, 0) diff --git a/code/game/objects/structures/door_assembly_types.dm b/code/game/objects/structures/door_assembly_types.dm deleted file mode 100644 index 8d5035018f0d4..0000000000000 --- a/code/game/objects/structures/door_assembly_types.dm +++ /dev/null @@ -1,291 +0,0 @@ -/obj/structure/door_assembly/door_assembly_public - name = "public airlock assembly" - icon = 'icons/obj/doors/airlocks/station2/glass.dmi' - overlays_file = 'icons/obj/doors/airlocks/station2/overlays.dmi' - glass_type = /obj/machinery/door/airlock/public/glass - airlock_type = /obj/machinery/door/airlock/public - -/obj/structure/door_assembly/door_assembly_com - name = "command airlock assembly" - icon = 'icons/obj/doors/airlocks/station/command.dmi' - base_name = "command airlock" - glass_type = /obj/machinery/door/airlock/command/glass - airlock_type = /obj/machinery/door/airlock/command - -/obj/structure/door_assembly/door_assembly_sec - name = "security airlock assembly" - icon = 'icons/obj/doors/airlocks/station/security.dmi' - base_name = "security airlock" - glass_type = /obj/machinery/door/airlock/security/glass - airlock_type = /obj/machinery/door/airlock/security - -/obj/structure/door_assembly/door_assembly_eng - name = "engineering airlock assembly" - icon = 'icons/obj/doors/airlocks/station/engineering.dmi' - base_name = "engineering airlock" - glass_type = /obj/machinery/door/airlock/engineering/glass - airlock_type = /obj/machinery/door/airlock/engineering - -/obj/structure/door_assembly/door_assembly_min - name = "mining airlock assembly" - icon = 'icons/obj/doors/airlocks/station/mining.dmi' - base_name = "mining airlock" - glass_type = /obj/machinery/door/airlock/mining/glass - airlock_type = /obj/machinery/door/airlock/mining - -/obj/structure/door_assembly/door_assembly_atmo - name = "atmospherics airlock assembly" - icon = 'icons/obj/doors/airlocks/station/atmos.dmi' - base_name = "atmospherics airlock" - glass_type = /obj/machinery/door/airlock/atmos/glass - airlock_type = /obj/machinery/door/airlock/atmos - -/obj/structure/door_assembly/door_assembly_research - name = "research airlock assembly" - icon = 'icons/obj/doors/airlocks/station/research.dmi' - base_name = "research airlock" - glass_type = /obj/machinery/door/airlock/research/glass - airlock_type = /obj/machinery/door/airlock/research - -/obj/structure/door_assembly/door_assembly_science - name = "science airlock assembly" - icon = 'icons/obj/doors/airlocks/station/science.dmi' - base_name = "science airlock" - glass_type = /obj/machinery/door/airlock/science/glass - airlock_type = /obj/machinery/door/airlock/science - -/obj/structure/door_assembly/door_assembly_med - name = "medical airlock assembly" - icon = 'icons/obj/doors/airlocks/station/medical.dmi' - base_name = "medical airlock" - glass_type = /obj/machinery/door/airlock/medical/glass - airlock_type = /obj/machinery/door/airlock/medical - -/obj/structure/door_assembly/door_assembly_viro - name = "virology airlock assembly" - icon = 'icons/obj/doors/airlocks/station/virology.dmi' - base_name = "virology airlock" - glass_type = /obj/machinery/door/airlock/virology/glass - airlock_type = /obj/machinery/door/airlock/virology - -/obj/structure/door_assembly/door_assembly_mai - name = "maintenance airlock assembly" - icon = 'icons/obj/doors/airlocks/station/maintenance.dmi' - base_name = "maintenance airlock" - glass_type = /obj/machinery/door/airlock/maintenance/glass - airlock_type = /obj/machinery/door/airlock/maintenance - -/obj/structure/door_assembly/door_assembly_extmai - name = "external maintenance airlock assembly" - icon = 'icons/obj/doors/airlocks/station/maintenanceexternal.dmi' - base_name = "external maintenance airlock" - glass_type = /obj/machinery/door/airlock/maintenance/external/glass - airlock_type = /obj/machinery/door/airlock/maintenance/external - -/obj/structure/door_assembly/door_assembly_ext - name = "external airlock assembly" - icon = 'icons/obj/doors/airlocks/external/external.dmi' - base_name = "external airlock" - overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi' - glass_type = /obj/machinery/door/airlock/external/glass - airlock_type = /obj/machinery/door/airlock/external - -/obj/structure/door_assembly/door_assembly_fre - name = "freezer airlock assembly" - icon = 'icons/obj/doors/airlocks/station/freezer.dmi' - base_name = "freezer airlock" - airlock_type = /obj/machinery/door/airlock/freezer - noglass = TRUE - -/obj/structure/door_assembly/door_assembly_hatch - name = "airtight hatch assembly" - icon = 'icons/obj/doors/airlocks/hatch/centcom.dmi' - base_name = "airtight hatch" - overlays_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi' - airlock_type = /obj/machinery/door/airlock/hatch - noglass = TRUE - -/obj/structure/door_assembly/door_assembly_mhatch - name = "maintenance hatch assembly" - icon = 'icons/obj/doors/airlocks/hatch/maintenance.dmi' - base_name = "maintenance hatch" - overlays_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi' - airlock_type = /obj/machinery/door/airlock/maintenance_hatch - noglass = TRUE - -/obj/structure/door_assembly/door_assembly_highsecurity - name = "high security airlock assembly" - icon = 'icons/obj/doors/airlocks/highsec/highsec.dmi' - base_name = "high security airlock" - overlays_file = 'icons/obj/doors/airlocks/highsec/overlays.dmi' - airlock_type = /obj/machinery/door/airlock/highsecurity - noglass = TRUE - material_type = /obj/item/stack/sheet/plasteel - -/obj/structure/door_assembly/door_assembly_vault - name = "vault door assembly" - icon = 'icons/obj/doors/airlocks/vault/vault.dmi' - base_name = "vault door" - overlays_file = 'icons/obj/doors/airlocks/vault/overlays.dmi' - airlock_type = /obj/machinery/door/airlock/vault - noglass = TRUE - material_type = /obj/item/stack/sheet/plasteel - -/obj/structure/door_assembly/multi_tile - name = "large airlock assembly" - icon = 'icons/obj/doors/airlocks/glass_large/glass_large.dmi' - base_name = "large airlock" - overlays_file = 'icons/obj/doors/airlocks/glass_large/overlays.dmi' - dir = EAST - var/width = 2 - airlock_type = /obj/machinery/door/airlock/multi_tile - glass_type = /obj/machinery/door/airlock/multi_tile/glass - material_amt = 8 - -/obj/structure/door_assembly/multi_tile/Initialize(mapload) - . = ..() - if(dir in list(EAST, WEST)) - bound_width = width * world.icon_size - bound_height = world.icon_size - else - bound_width = world.icon_size - bound_height = width * world.icon_size - -/obj/structure/door_assembly/multi_tile/Move() - . = ..() - if(dir in list(EAST, WEST)) - bound_width = width * world.icon_size - bound_height = world.icon_size - else - bound_width = world.icon_size - bound_height = width * world.icon_size - -/obj/structure/door_assembly/door_assembly_cult - name = "cult airlock assembly" - icon = 'icons/obj/doors/airlocks/cult/runed/cult.dmi' - base_name = "cult airlock" - overlays_file = 'icons/obj/doors/airlocks/cult/runed/cult-overlays.dmi' - airlock_type = /obj/machinery/door/airlock/cult - glass_type = /obj/machinery/door/airlock/cult/glass - -/obj/structure/door_assembly/door_assembly_cult/Initialize(mapload) - . = ..() - icon = GET_CULT_DATA(airlock_runed_icon_file, initial(icon)) - overlays_file = GET_CULT_DATA(airlock_runed_overlays_file, initial(overlays_file)) - update_icon() - -/obj/structure/door_assembly/door_assembly_cult/unruned - icon = 'icons/obj/doors/airlocks/cult/unruned/cult.dmi' - overlays_file = 'icons/obj/doors/airlocks/cult/unruned/cult-overlays.dmi' - airlock_type = /obj/machinery/door/airlock/cult/unruned - glass_type = /obj/machinery/door/airlock/cult/unruned/glass - -/obj/structure/door_assembly/door_assembly_cult/unruned/Initialize(mapload) - . = ..() - icon = GET_CULT_DATA(airlock_unruned_icon_file, initial(icon)) - overlays_file = GET_CULT_DATA(airlock_unruned_overlays_file, initial(overlays_file)) - update_icon() - -/obj/structure/door_assembly/door_assembly_clockwork - icon = 'icons/obj/doors/airlocks/clockwork/clockwork.dmi' - overlays_file = 'icons/obj/doors/airlocks/clockwork/clockwork-overlays.dmi' - airlock_type = /obj/machinery/door/airlock/clockwork - glass_type = /obj/machinery/door/airlock/clockwork/glass - -/obj/structure/door_assembly/door_assembly_centcom - icon = 'icons/obj/doors/airlocks/centcom/centcom.dmi' - overlays_file = 'icons/obj/doors/airlocks/centcom/overlays.dmi' - airlock_type = /obj/machinery/door/airlock/centcom - noglass = TRUE - -/obj/structure/door_assembly/door_assembly_gold - name = "gold airlock assembly" - icon = 'icons/obj/doors/airlocks/station/gold.dmi' - base_name = "gold airlock" - airlock_type = /obj/machinery/door/airlock/gold - mineral = "gold" - glass_type = /obj/machinery/door/airlock/gold/glass - mineral_type = /obj/item/stack/sheet/mineral/gold - -/obj/structure/door_assembly/door_assembly_silver - name = "silver airlock assembly" - icon = 'icons/obj/doors/airlocks/station/silver.dmi' - base_name = "silver airlock" - airlock_type = /obj/machinery/door/airlock/silver - mineral = "silver" - glass_type = /obj/machinery/door/airlock/silver/glass - mineral_type = /obj/item/stack/sheet/mineral/silver - -/obj/structure/door_assembly/door_assembly_diamond - name = "diamond airlock assembly" - icon = 'icons/obj/doors/airlocks/station/diamond.dmi' - base_name = "diamond airlock" - airlock_type = /obj/machinery/door/airlock/diamond - mineral = "diamond" - glass_type = /obj/machinery/door/airlock/diamond/glass - mineral_type = /obj/item/stack/sheet/mineral/diamond - -/obj/structure/door_assembly/door_assembly_uranium - name = "uranium airlock assembly" - icon = 'icons/obj/doors/airlocks/station/uranium.dmi' - base_name = "uranium airlock" - airlock_type = /obj/machinery/door/airlock/uranium - mineral = "uranium" - glass_type = /obj/machinery/door/airlock/uranium/glass - mineral_type = /obj/item/stack/sheet/mineral/uranium - -/obj/structure/door_assembly/door_assembly_plasma - name = "plasma airlock assembly" - icon = 'icons/obj/doors/airlocks/station/plasma.dmi' - base_name = "plasma airlock" - airlock_type = /obj/machinery/door/airlock/plasma - mineral = "plasma" - glass_type = /obj/machinery/door/airlock/plasma/glass - mineral_type = /obj/item/stack/sheet/mineral/plasma - -/obj/structure/door_assembly/door_assembly_bananium - name = "bananium airlock assembly" - desc = "Honk." - icon = 'icons/obj/doors/airlocks/station/bananium.dmi' - base_name = "bananium airlock" - airlock_type = /obj/machinery/door/airlock/bananium - mineral = "bananium" - glass_type = /obj/machinery/door/airlock/bananium/glass - mineral_type = /obj/item/stack/sheet/mineral/bananium - -/obj/structure/door_assembly/door_assembly_tranquillite - name = "tranquillite airlock assembly" - icon = 'icons/obj/doors/airlocks/station/freezer.dmi' - base_name = "tranquillite airlock" - airlock_type = /obj/machinery/door/airlock/tranquillite - mineral = "tranquillite" - noglass = TRUE - mineral_type = /obj/item/stack/sheet/mineral/tranquillite - -/obj/structure/door_assembly/door_assembly_sandstone - name = "sandstone airlock assembly" - icon = 'icons/obj/doors/airlocks/station/sandstone.dmi' - base_name = "sandstone airlock" - airlock_type = /obj/machinery/door/airlock/sandstone - mineral = "sandstone" - glass_type = /obj/machinery/door/airlock/sandstone/glass - mineral_type = /obj/item/stack/sheet/mineral/sandstone - -/obj/structure/door_assembly/door_assembly_titanium - name = "titanium airlock assembly" - icon = 'icons/obj/doors/airlocks/shuttle/shuttle.dmi' - base_name = "shuttle airlock" - overlays_file = 'icons/obj/doors/airlocks/shuttle/overlays.dmi' - glass_type = /obj/machinery/door/airlock/titanium/glass - airlock_type = /obj/machinery/door/airlock/titanium - mineral = "titanium" - mineral_type = /obj/item/stack/sheet/mineral/titanium - -/obj/structure/door_assembly/door_assembly_wood - name = "wooden airlock assembly" - icon = 'icons/obj/doors/airlocks/station/wood.dmi' - base_name = "wooden airlock" - airlock_type = /obj/machinery/door/airlock/wood - mineral = "wood" - glass_type = /obj/machinery/door/airlock/wood/glass - mineral_type = /obj/item/stack/sheet/wood diff --git a/code/game/objects/structures/engicart.dm b/code/game/objects/structures/engicart.dm deleted file mode 100644 index 7d5ec19c99bb0..0000000000000 --- a/code/game/objects/structures/engicart.dm +++ /dev/null @@ -1,204 +0,0 @@ -/obj/structure/engineeringcart - name = "engineering cart" - desc = "A cart for storing engineering items." - icon = 'icons/obj/engicart.dmi' - icon_state = "cart" - face_while_pulling = FALSE - anchored = FALSE - density = TRUE - var/obj/item/stack/sheet/glass/myglass = null - var/obj/item/stack/sheet/metal/mymetal = null - var/obj/item/stack/sheet/plasteel/myplasteel = null - var/obj/item/flashlight/myflashlight = null - var/obj/item/storage/toolbox/mechanical/mybluetoolbox = null - var/obj/item/storage/toolbox/electrical/myyellowtoolbox = null - var/obj/item/storage/toolbox/emergency/myredtoolbox = null - -/obj/structure/engineeringcart/Destroy() - QDEL_NULL(myglass) - QDEL_NULL(mymetal) - QDEL_NULL(myplasteel) - QDEL_NULL(myflashlight) - QDEL_NULL(mybluetoolbox) - QDEL_NULL(myyellowtoolbox) - QDEL_NULL(myredtoolbox) - return ..() - -/obj/structure/engineeringcart/proc/put_in_cart(obj/item/I, mob/user) - user.drop_item() - I.loc = src - to_chat(user, "You put [I] into [src].") - return - -/obj/structure/engineeringcart/attackby__legacy__attackchain(obj/item/I, mob/user, params) - var/fail_msg = "There is already one of those in [src]." - if(!I.is_robot_module()) - if(istype(I, /obj/item/stack/sheet/glass)) - if(!myglass) - put_in_cart(I, user) - myglass=I - update_icon(UPDATE_OVERLAYS) - else - to_chat(user, fail_msg) - else if(istype(I, /obj/item/stack/sheet/metal)) - if(!mymetal) - put_in_cart(I, user) - mymetal=I - update_icon(UPDATE_OVERLAYS) - else - to_chat(user, fail_msg) - else if(istype(I, /obj/item/stack/sheet/plasteel)) - if(!myplasteel) - put_in_cart(I, user) - myplasteel=I - update_icon(UPDATE_OVERLAYS) - else - to_chat(user, fail_msg) - else if(istype(I, /obj/item/flashlight)) - if(!myflashlight) - put_in_cart(I, user) - myflashlight=I - update_icon(UPDATE_OVERLAYS) - else - to_chat(user, fail_msg) - else if(istype(I, /obj/item/storage/toolbox/mechanical)) - if(!mybluetoolbox) - put_in_cart(I, user) - mybluetoolbox=I - update_icon(UPDATE_OVERLAYS) - else - to_chat(user, fail_msg) - else if(istype(I, /obj/item/storage/toolbox/electrical)) - if(!myyellowtoolbox) - put_in_cart(I, user) - myyellowtoolbox=I - update_icon(UPDATE_OVERLAYS) - else - to_chat(user, fail_msg) - else if(istype(I, /obj/item/storage/toolbox)) - if(!myredtoolbox) - put_in_cart(I, user) - myredtoolbox=I - update_icon(UPDATE_OVERLAYS) - else - to_chat(user, fail_msg) - else - to_chat(usr, "You cannot interface your modules [src]!") - -/obj/structure/engineeringcart/tool_act(mob/living/user, obj/item/I, tool_type) - if(I.is_robot_module()) - to_chat(user, "You cannot interface your modules [src]!") - return FALSE - return ..() - -/obj/structure/engineeringcart/wrench_act(mob/living/user, obj/item/I) - if(!anchored && !isinspace()) - I.play_tool_sound(src, I.tool_volume) - user.visible_message( - "[user] tightens [src]'s casters.", - "You have tightened [src]'s casters.", - "You hear ratchet." - ) - anchored = TRUE - else if(anchored) - I.play_tool_sound(src, I.tool_volume) - user.visible_message( - "[user] loosens [src]'s casters.", - " You have loosened [src]'s casters.", - "You hear ratchet." - ) - anchored = FALSE - - return TRUE - -/obj/structure/engineeringcart/attack_hand(mob/user) - var/list/engicart_items = list() - - if(myglass) - engicart_items["Glass"] = image(icon = myglass.icon, icon_state = myglass.icon_state) - if(mymetal) - engicart_items["Metal"] = image(icon = mymetal.icon, icon_state = mymetal.icon_state) - if(myplasteel) - engicart_items["Plasteel"] = image(icon = myplasteel.icon, icon_state = myplasteel.icon_state) - if(myflashlight) - engicart_items["Flashlight"] = image(icon = myflashlight.icon, icon_state = myflashlight.icon_state) - if(mybluetoolbox) - engicart_items["Mechanical Toolbox"] = image(icon = mybluetoolbox.icon, icon_state = mybluetoolbox.icon_state) - if(myredtoolbox) - engicart_items["Emergency Toolbox"] = image(icon = myredtoolbox.icon, icon_state = myredtoolbox.icon_state) - if(myyellowtoolbox) - engicart_items["Electrical Toolbox"] = image(icon = myyellowtoolbox.icon, icon_state = myyellowtoolbox.icon_state) - - if(!length(engicart_items)) - return - - var/pick = show_radial_menu(user, src, engicart_items, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE) - - if(!pick) - return - - switch(pick) - if("Glass") - if(!myglass) - return - user.put_in_hands(myglass) - to_chat(user, "You take [myglass] from [src].") - myglass = null - if("Metal") - if(!mymetal) - return - user.put_in_hands(mymetal) - to_chat(user, "You take [mymetal] from [src].") - mymetal = null - if("Plasteel") - if(!myplasteel) - return - user.put_in_hands(myplasteel) - to_chat(user, "You take [myplasteel] from [src].") - myplasteel = null - if("Flashlight") - if(!myflashlight) - return - user.put_in_hands(myflashlight) - to_chat(user, "You take [myflashlight] from [src].") - myflashlight = null - if("Mechanical Toolbox") - if(!mybluetoolbox) - return - user.put_in_hands(mybluetoolbox) - to_chat(user, "You take [mybluetoolbox] from [src].") - mybluetoolbox = null - if("Emergency Toolbox") - if(!myredtoolbox) - return - user.put_in_hands(myredtoolbox) - to_chat(user, "You take [myredtoolbox] from [src].") - myredtoolbox = null - if("Electrical Toolbox") - if(!myyellowtoolbox) - return - user.put_in_hands(myyellowtoolbox) - to_chat(user, "You take [myyellowtoolbox] from [src].") - myyellowtoolbox = null - - update_icon(UPDATE_OVERLAYS) - -/obj/structure/engineeringcart/proc/check_menu(mob/living/user) - return istype(user) && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) - -/obj/structure/engineeringcart/update_overlays() - . = ..() - if(myplasteel) - . += "cart_plasteel" - if(mymetal) - . += "cart_metal" - if(myglass) - . += "cart_glass" - if(myflashlight) - . += "cart_flashlight" - if(mybluetoolbox) - . += "cart_bluetoolbox" - if(myredtoolbox) - . += "cart_redtoolbox" - if(myyellowtoolbox) - . += "cart_yellowtoolbox" diff --git a/code/game/objects/structures/extinguisher_cabinet.dm b/code/game/objects/structures/extinguisher_cabinet.dm deleted file mode 100644 index f25520be1e0cb..0000000000000 --- a/code/game/objects/structures/extinguisher_cabinet.dm +++ /dev/null @@ -1,175 +0,0 @@ -#define NO_EXTINGUISHER 0 -#define NORMAL_EXTINGUISHER 1 -#define MINI_EXTINGUISHER 2 - - -/obj/structure/extinguisher_cabinet - name = "extinguisher cabinet" - desc = "A small wall mounted cabinet designed to hold a fire extinguisher. \"Don't break the glass\" is written next to the handle." - icon = 'icons/obj/closet.dmi' - icon_state = "extinguisher" - anchored = TRUE - density = FALSE - max_integrity = 200 - integrity_failure = 50 - var/obj/item/extinguisher/has_extinguisher = null - var/extinguishertype - var/opened = FALSE - var/material_drop = /obj/item/stack/sheet/metal - -/obj/structure/extinguisher_cabinet/Initialize(mapload, direction = null) - . = ..() - name = "extinguisher cabinet" - if(direction) - setDir(direction) - set_pixel_offsets_from_dir(28, -28, 30, -30) - switch(extinguishertype) - if(NO_EXTINGUISHER) - return - if(MINI_EXTINGUISHER) - has_extinguisher = new /obj/item/extinguisher/mini(src) - else - has_extinguisher = new /obj/item/extinguisher(src) - update_icon(UPDATE_ICON_STATE) - -/obj/structure/extinguisher_cabinet/examine(mob/user) - . = ..() - . += "Alt-click to [opened ? "close":"open"] it." - -/obj/structure/extinguisher_cabinet/AltClick(mob/living/user) - if(!istype(user) || user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user)) - return - if(!iscarbon(usr) && !isrobot(usr)) - return - playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) - opened = !opened - update_icon(UPDATE_ICON_STATE) - -/obj/structure/extinguisher_cabinet/Destroy() - QDEL_NULL(has_extinguisher) - return ..() - -/obj/structure/extinguisher_cabinet/ex_act(severity) - if(has_extinguisher) - has_extinguisher.ex_act(severity) - ..() - -/obj/structure/extinguisher_cabinet/handle_atom_del(atom/A) - if(A == has_extinguisher) - has_extinguisher = null - update_icon(UPDATE_ICON_STATE) - -/obj/structure/extinguisher_cabinet/attackby__legacy__attackchain(obj/item/O, mob/user, params) - if(isrobot(user) || isalien(user)) - return - if(istype(O, /obj/item/extinguisher)) - if(!has_extinguisher && opened) - if(!user.drop_item()) - return - user.drop_item(O) - contents += O - has_extinguisher = O - update_icon(UPDATE_ICON_STATE) - to_chat(user, "You place [O] in [src].") - return TRUE - else - playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) - opened = !opened - update_icon(UPDATE_ICON_STATE) - else if(user.a_intent != INTENT_HARM) - playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) - opened = !opened - update_icon(UPDATE_ICON_STATE) - else - return ..() - -/obj/structure/extinguisher_cabinet/welder_act(mob/user, obj/item/I) - if(has_extinguisher) - to_chat(user, "You need to remove the extinguisher before deconstructing [src]!") - return - if(!opened) - to_chat(user, "Open the cabinet before cutting it apart!") - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - WELDER_ATTEMPT_SLICING_MESSAGE - if(I.use_tool(src, user, 40, volume = I.tool_volume)) - WELDER_SLICING_SUCCESS_MESSAGE - deconstruct(TRUE) - -/obj/structure/extinguisher_cabinet/attack_hand(mob/user) - if(isrobot(user) || isalien(user)) - to_chat(user, "You don't have the dexterity to do this!") - return - if(ishuman(user)) - var/mob/living/carbon/human/H = user - var/obj/item/organ/external/temp = H.bodyparts_by_name["r_hand"] - if(user.hand) - temp = H.bodyparts_by_name["l_hand"] - if(temp && !temp.is_usable()) - to_chat(user, "You try to move your [temp.name], but cannot!") - return - if(has_extinguisher) - if(icon_state == "extinguisher_closed") - playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) - user.put_in_hands(has_extinguisher) - to_chat(user, "You take [has_extinguisher] from [src].") - has_extinguisher = null - opened = TRUE - else - playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) - opened = !opened - update_icon(UPDATE_ICON_STATE) - -/obj/structure/extinguisher_cabinet/attack_tk(mob/user) - if(has_extinguisher) - if(icon_state == "extinguisher_closed") - playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) - has_extinguisher.loc = loc - to_chat(user, "You telekinetically remove [has_extinguisher] from [src].") - has_extinguisher = null - opened = TRUE - else - playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) - opened = !opened - update_icon(UPDATE_ICON_STATE) - -/obj/structure/extinguisher_cabinet/obj_break(damage_flag) - if(!broken && !(flags & NODECONSTRUCT)) - broken = TRUE - opened = TRUE - if(has_extinguisher) - has_extinguisher.forceMove(loc) - has_extinguisher = null - update_icon(UPDATE_ICON_STATE) - -/obj/structure/extinguisher_cabinet/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - new /obj/item/stack/sheet/metal(loc) - if(has_extinguisher) - has_extinguisher.forceMove(loc) - has_extinguisher = null - qdel(src) - -/obj/structure/extinguisher_cabinet/update_icon_state() - icon_state = "extinguisher" // Needs to reset the state with every update - - if(has_extinguisher) - if(istype(has_extinguisher, /obj/item/extinguisher/mini)) - icon_state += "_mini" - else - icon_state += "_full" - - if(!opened) - icon_state += "_closed" - -/obj/structure/extinguisher_cabinet/empty - extinguishertype = NO_EXTINGUISHER - -#undef NO_EXTINGUISHER -#undef NORMAL_EXTINGUISHER -#undef MINI_EXTINGUISHER diff --git a/code/game/objects/structures/fence.dm b/code/game/objects/structures/fence.dm deleted file mode 100644 index 657d374800a77..0000000000000 --- a/code/game/objects/structures/fence.dm +++ /dev/null @@ -1,223 +0,0 @@ -//Chain link fences -//Sprites ported from /VG/ - -#define CUT_TIME 100 -#define CLIMB_TIME 150 -#define FULL_CUT_TIME 300 - -#define NO_HOLE 0 //section is intact -#define MEDIUM_HOLE 1 //medium hole in the section - can climb through -#define LARGE_HOLE 2 //large hole in the section - can walk through -#define MAX_HOLE_SIZE LARGE_HOLE -#define HOLE_REPAIR (hole_size * 2) //How many rods to fix these sections - -/obj/structure/fence - name = "fence" - desc = "A chain link fence. Not as effective as a wall, but generally it keeps people out." - density = TRUE - anchored = TRUE - - icon = 'icons/obj/fence.dmi' - icon_state = "straight" - - var/cuttable = TRUE - var/hole_size = NO_HOLE - var/invulnerable = FALSE - var/shock_cooldown = FALSE - -/obj/structure/fence/Initialize(mapload) - . = ..() - update_cut_status() - -/obj/structure/fence/examine(mob/user) - . = ..() - switch(hole_size) - if(MEDIUM_HOLE) - . += "There is a large hole in \the [src]." - if(LARGE_HOLE) - . += "\The [src] has been completely cut through." - -/obj/structure/fence/end - icon_state = "end" - cuttable = FALSE - -/obj/structure/fence/corner - icon_state = "corner" - cuttable = FALSE - -/obj/structure/fence/post - icon_state = "post" - cuttable = FALSE - -/obj/structure/fence/cut/medium - icon_state = "straight_cut2" - hole_size = MEDIUM_HOLE - climbable = TRUE - -/obj/structure/fence/cut/large - icon_state = "straight_cut3" - hole_size = LARGE_HOLE - -/obj/structure/fence/CanPass(atom/movable/mover, border_dir) - if(istype(mover) && mover.checkpass(PASSFENCE)) - return TRUE - if(isprojectile(mover)) - return TRUE - if(!density) - return TRUE - return FALSE - -/* - Shock user with probability prb (if all connections & power are working) - Returns TRUE if shocked, FALSE otherwise - Totally not stolen from code\game\objects\structures\grille.dm -*/ -/obj/structure/fence/proc/shock(mob/user, prb) - if(!prob(prb)) - return FALSE - if(!in_range(src, user)) //To prevent TK and mech users from getting shocked - return FALSE - var/turf/T = get_turf(src) - var/obj/structure/cable/C = T.get_cable_node() - if(C) - if(electrocute_mob(user, C, src, 1, TRUE)) - do_sparks(3, 1, src) - return TRUE - return FALSE - -/obj/structure/fence/wirecutter_act(mob/living/user, obj/item/W) - . = TRUE - if(shock(user, 100)) - return - if(invulnerable) - to_chat(user, "This fence is too strong to cut through!") - return - if(!cuttable) - user.visible_message("[user] starts dismantling [src] with [W].",\ - "You start dismantling [src] with [W].") - if(W.use_tool(src, user, FULL_CUT_TIME, volume = W.tool_volume)) - user.visible_message("[user] completely dismantles [src].",\ - "You completely dismantle [src].") - qdel(src) - return - var/current_stage = hole_size - user.visible_message("[user] starts cutting through [src] with [W].",\ - "You start cutting through [src] with [W].") - if(W.use_tool(src, user, CUT_TIME * W.toolspeed, volume = W.tool_volume)) - if(current_stage == hole_size) - switch(hole_size) - if(NO_HOLE) - user.visible_message("[user] cuts into [src] some more.",\ - "You could probably fit yourself through that hole now. Although climbing through would be much faster if you made it even bigger.") - hole_size = MEDIUM_HOLE - if(MEDIUM_HOLE) - user.visible_message("[user] completely cuts through [src].",\ - "The hole in [src] is now big enough to walk through.") - hole_size = LARGE_HOLE - if(LARGE_HOLE) - user.visible_message("[user] completely dismantles [src].",\ - "You completely take apart [src].") - qdel(src) - return - update_cut_status() - -/obj/structure/fence/attackby__legacy__attackchain(obj/item/C, mob/user) - if(shock(user, 90)) - return - if(istype(C, /obj/item/stack/rods)) - if(hole_size == NO_HOLE) - return - var/obj/item/stack/rods/R = C - if(R.get_amount() < HOLE_REPAIR) - to_chat(user, "You need [HOLE_REPAIR] rods to fix this fence!") - return - to_chat(user, "You begin repairing the fence...") - if(do_after(user, 3 SECONDS * C.toolspeed, target = src) && hole_size != NO_HOLE && R.use(HOLE_REPAIR)) - playsound(src, C.usesound, 80, 1) - hole_size = NO_HOLE - obj_integrity = max_integrity - to_chat(user, "You repair the fence.") - update_cut_status() - return - . = ..() - -/obj/structure/fence/Bumped(atom/user) - if(!ismob(user)) - return - if(shock_cooldown) - return - shock(user, 70) - shock_cooldown = TRUE // We do not want bump shock spam! - addtimer(CALLBACK(src, PROC_REF(shock_cooldown)), 1 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) - -/obj/structure/fence/proc/shock_cooldown() - shock_cooldown = FALSE - -/obj/structure/fence/attack_animal(mob/user) - . = ..() - if(. && !QDELETED(src) && !shock(user, 70)) - take_damage(rand(5,10), BRUTE, "melee", 1) - -/obj/structure/fence/proc/update_cut_status() - if(!cuttable) - return - var/new_density = TRUE - switch(hole_size) - if(NO_HOLE) - icon_state = initial(icon_state) - climbable = FALSE - if(MEDIUM_HOLE) - icon_state = "straight_cut2" - climbable = TRUE - if(LARGE_HOLE) - icon_state = "straight_cut3" - new_density = FALSE - climbable = FALSE - set_density(new_density) - -//FENCE DOORS - -/obj/structure/fence/door - name = "fence door" - desc = "Not very useful without a real lock." - icon_state = "door_closed" - cuttable = FALSE - var/open = FALSE - -/obj/structure/fence/door/Initialize(mapload) - . = ..() - update_door_status() - -/obj/structure/fence/door/opened - icon_state = "door_opened" - open = TRUE - density = TRUE - -/obj/structure/fence/door/attack_hand(mob/user, list/modifiers) - shock(user, 70) - if(can_open(user)) - toggle(user) - return TRUE - -/obj/structure/fence/door/proc/toggle(mob/user) - open = !open - visible_message("\The [user] [open ? "opens" : "closes"] \the [src].") - update_door_status() - playsound(src, 'sound/machines/door_open.ogg', 100, TRUE) - -/obj/structure/fence/door/proc/update_door_status() - set_density(!open) - icon_state = open ? "door_opened" : "door_closed" - -/obj/structure/fence/door/proc/can_open(mob/user) - return TRUE - -#undef CUT_TIME -#undef CLIMB_TIME -#undef FULL_CUT_TIME - -#undef NO_HOLE -#undef MEDIUM_HOLE -#undef LARGE_HOLE -#undef MAX_HOLE_SIZE -#undef HOLE_REPAIR diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm deleted file mode 100644 index 746c4b9b72635..0000000000000 --- a/code/game/objects/structures/girders.dm +++ /dev/null @@ -1,513 +0,0 @@ -/obj/structure/girder - name = "girder" - desc = "The basis of any wall, and therefore any space station or ship." - icon_state = "girder" - anchored = TRUE - density = TRUE - layer = BELOW_OBJ_LAYER - flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2 - rad_insulation = RAD_VERY_LIGHT_INSULATION - var/state = GIRDER_NORMAL - var/girderpasschance = 20 // percentage chance that a projectile passes through the girder. - max_integrity = 200 - var/can_displace = TRUE //If the girder can be moved around by crowbarring it - var/metalUsed = 2 //used to determine amount returned in deconstruction - var/metal_type = /obj/item/stack/sheet/metal - -/obj/structure/girder/Initialize(mapload) - . = ..() - AddComponent(/datum/component/debris, DEBRIS_SPARKS, -20, 10) - -/obj/structure/girder/examine(mob/user) - . = ..() - switch(state) - if(GIRDER_REINF) - . += "The support struts are screwed in place." - if(GIRDER_REINF_STRUTS) - . += "The support struts are unscrewed and the inner grille is intact." - if(GIRDER_NORMAL) - . += "The bolts are lodged in place." - if(GIRDER_DISPLACED) - . += "The bolts are loosened, but the screws are holding [src] together." - if(GIRDER_DISASSEMBLED) - . += "[src] is disassembled! You probably shouldn't be able to see this examine message." - . += "Various types of metal sheets can be used on this to create different kinds of walls." - if(can_displace) - . += "Apply a crowbar to this item to cause any walls to be made to be false walls. Use a wrench on this item to deconstruct it." - - -/obj/structure/girder/proc/refundMetal(metalAmount) //refunds metal used in construction when deconstructed - for(var/i=0;i < metalAmount;i++) - new metal_type(get_turf(src)) - -/obj/structure/girder/temperature_expose(datum/gas_mixture/air, exposed_temperature) - ..() - var/temp_check = exposed_temperature - if(temp_check >= GIRDER_MELTING_TEMP) - take_damage(10) - -/obj/structure/girder/attackby__legacy__attackchain(obj/item/W, mob/user, params) - add_fingerprint(user) - if(istype(W, /obj/item/gun/energy/plasmacutter)) - to_chat(user, "You start slicing apart the girder...") - if(do_after(user, 40 * W.toolspeed, target = src)) - if(!src) - return - playsound(loc, W.usesound, 100, 1) - to_chat(user, "You slice apart the girder.") - refundMetal(metalUsed) - qdel(src) - - else if(istype(W, /obj/item/pickaxe/drill/diamonddrill)) - to_chat(user, "You drill through the girder!") - refundMetal(metalUsed) - qdel(src) - - else if(istype(W, /obj/item/pickaxe/drill/jackhammer)) - playsound(loc, W.usesound, 100, 1) - to_chat(user, "You disintegrate the girder!") - refundMetal(metalUsed) - qdel(src) - - else if(istype(W, /obj/item/pyro_claws)) - playsound(loc, W.usesound, 100, 1) - to_chat(user, "You melt the girder!") - refundMetal(metalUsed) - qdel(src) - - else if(istype(W, /obj/item/stack)) - if(iswallturf(loc)) - to_chat(user, "There is already a wall present!") - return - if(!isfloorturf(loc)) - to_chat(user, "A floor must be present to build a false wall!") - return - if(locate(/obj/structure/falsewall) in loc.contents) - to_chat(user, "There is already a false wall present!") - return - if(islava(loc)) - to_chat(user, "You can't do that while [src] is in lava!") - return - if(istype(W, /obj/item/stack/sheet/runed_metal)) - to_chat(user, "You can't seem to make the metal bend.") - return - if(istype(W, /obj/item/stack/sheet/bamboo)) // pending wall resprite(tm) - to_chat(user, "The bamboo doesn't seem to fit around the girder.") - return - - if(istype(W,/obj/item/stack/rods)) - var/obj/item/stack/rods/S = W - if(state == GIRDER_DISPLACED) - if(S.get_amount() < 5) - to_chat(user, "You need at least five rods to create a false wall!") - return - to_chat(user, "You start building a reinforced false wall...") - if(do_after(user, 20, target = src)) - if(!loc || !S || S.get_amount() < 5) - return - S.use(5) - to_chat(user, "You create a false wall. Push on it to open or close the passage.") - var/obj/structure/falsewall/iron/FW = new (loc) - transfer_fingerprints_to(FW) - qdel(src) - else - if(S.get_amount() < 5) - to_chat(user, "You need at least five rods to add plating!") - return - to_chat(user, "You start adding plating...") - if(do_after(user, 40, target = src)) - if(!loc || !S || S.get_amount() < 5) - return - S.use(5) - to_chat(user, "You add the plating.") - var/turf/T = get_turf(src) - T.ChangeTurf(/turf/simulated/wall/mineral/iron) - transfer_fingerprints_to(T) - qdel(src) - return - - if(istype(W, /obj/item/stack/ore/glass/basalt)) - var/obj/item/stack/ore/glass/basalt/A = W - if(state == GIRDER_DISPLACED) - if(A.get_amount() < 2) - to_chat(user, "You need at least two [A] to create a false wall!") - return - if(do_after(user, 2 SECONDS, target = src)) - if(!loc || !A || A.get_amount() < 2) - return - A.use(2) - to_chat(user, "You create a false wall. Push on it to open or close the passage.") - var/obj/structure/falsewall/rock_ancient/FW = new (loc) - transfer_fingerprints_to(FW) - qdel(src) - else - if(A.get_amount() < 2) - to_chat(user, "You need at least two [A] to add plating!") - return - to_chat(user, "You start adding [A]...") - if(do_after(user, 4 SECONDS, target = src)) - if(!src || !A || A.get_amount() < 2) - return - A.use(2) - to_chat(user, "You add [A].") - var/turf/parent_turf = get_turf(src) - parent_turf.ChangeTurf(/turf/simulated/mineral/ancient) - for(var/turf/simulated/mineral/X in parent_turf.loc) - X.add_hiddenprint(usr) - qdel(src) - return - - if(!istype(W,/obj/item/stack/sheet)) - return - - var/obj/item/stack/sheet/S = W - if(!S.wall_allowed) - to_chat(user, "You don't think that is good material for a wall!") - return - - if(istype(S, /obj/item/stack/sheet/wood)) - if(state == GIRDER_DISPLACED) - if(S.get_amount() < 2) - to_chat(user, "You need two planks of wood to create a false wall!") - return - to_chat(user, "You start building a false wall...") - if(do_after(user, 20, target = src)) - if(!loc || !S || S.get_amount() < 2) - return - S.use(2) - to_chat(user, "You create a false wall. Push on it to open or close the passage.") - var/obj/structure/falsewall/wood/falsewood = new(loc) - transfer_fingerprints_to(falsewood) - qdel(src) - else - if(S.get_amount() < 2) - to_chat(user, "You need two planks of wood to finish a wall!") - return - to_chat(user, "You start adding plating...") - if(do_after(user, 40 * W.toolspeed, target = src)) - if(!src || !S || S.get_amount() < 2) - return - S.use(2) - to_chat(user, "You add the plating.") - var/turf/Tsrc = get_turf(src) - Tsrc.ChangeTurf(/turf/simulated/wall/mineral/wood) - for(var/turf/simulated/wall/mineral/wood/X in Tsrc.loc) - if(X) - X.add_hiddenprint(usr) - qdel(src) - return - - else if(istype(S, /obj/item/stack/sheet/metal)) - if(state == GIRDER_DISPLACED) - if(S.get_amount() < 2) - to_chat(user, "You need two sheets of metal to create a false wall!") - return - to_chat(user, "You start building a false wall...") - if(do_after(user, 20, target = src)) - if(!loc || !S || S.get_amount() < 2) - return - S.use(2) - to_chat(user, "You create a false wall. Push on it to open or close the passage.") - var/obj/structure/falsewall/F = new(loc) - transfer_fingerprints_to(F) - qdel(src) - else - if(S.get_amount() < 2) - to_chat(user, "You need two sheets of metal to finish a wall!") - return - to_chat(user, "You start adding plating...") - if(do_after(user, 40 * W.toolspeed, target = src)) - if(!src || !S || S.get_amount() < 2) - return - S.use(2) - to_chat(user, "You add the plating.") - var/turf/Tsrc = get_turf(src) - Tsrc.ChangeTurf(/turf/simulated/wall) - for(var/turf/simulated/wall/X in Tsrc.loc) - if(X) - X.add_hiddenprint(usr) - qdel(src) - return - - if(istype(S, /obj/item/stack/sheet/plasteel)) - if(state == GIRDER_DISPLACED) - if(S.get_amount() < 2) - to_chat(user, "You need at least two sheets to create a false wall!") - return - to_chat(user, "You start building a reinforced false wall...") - if(do_after(user, 20, target = src)) - if(!loc || !S || S.get_amount() < 2) - return - S.use(2) - to_chat(user, "You create a reinforced false wall. Push on it to open or close the passage.") - var/obj/structure/falsewall/reinforced/FW = new (loc) - transfer_fingerprints_to(FW) - qdel(src) - else - if(state == GIRDER_REINF) - if(S.get_amount() < 1) - return - to_chat(user, "You start finalizing the reinforced wall...") - if(do_after(user, 50, target = src)) - if(!src || !S || S.get_amount() < 1) - return - S.use(1) - to_chat(user, "You fully reinforce the wall.") - var/turf/Tsrc = get_turf(src) - Tsrc.ChangeTurf(/turf/simulated/wall/r_wall) - for(var/turf/simulated/wall/r_wall/X in Tsrc.loc) - if(X) - X.add_hiddenprint(usr) - qdel(src) - return - else - if(S.get_amount() < 1) - return - to_chat(user, "You start reinforcing the girder...") - if(do_after(user,60, target = src)) - if(!src || !S || S.get_amount() < 1) - return - S.use(1) - to_chat(user, "You reinforce the girder.") - var/obj/structure/girder/reinforced/R = new (loc) - transfer_fingerprints_to(R) - qdel(src) - return - - if(S.sheettype) - var/M = S.sheettype - if(state == GIRDER_DISPLACED) - if(S.get_amount() < 2) - to_chat(user, "You need at least two sheets to create a false wall!") - return - if(do_after(user, 20, target = src)) - if(!loc || !S || S.get_amount() < 2) - return - S.use(2) - to_chat(user, "You create a false wall. Push on it to open or close the passage.") - var/F = text2path("/obj/structure/falsewall/[M]") - var/obj/structure/FW = new F (loc) - transfer_fingerprints_to(FW) - qdel(src) - else - if(S.get_amount() < 2) - to_chat(user, "You need at least two sheets to add plating!") - return - to_chat(user, "You start adding plating...") - if(do_after(user,40, target = src)) - if(!src || !S || S.get_amount() < 2) - return - S.use(2) - to_chat(user, "You add the plating.") - var/turf/Tsrc = get_turf(src) - Tsrc.ChangeTurf(text2path("/turf/simulated/wall/mineral/[M]")) - for(var/turf/simulated/wall/mineral/X in Tsrc.loc) - if(X) - X.add_hiddenprint(usr) - qdel(src) - return - - add_hiddenprint(user) - - else - return ..() - -/obj/structure/girder/crowbar_act(mob/user, obj/item/I) - if(!can_displace || state != GIRDER_NORMAL) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - to_chat(user, "You start dislodging the girder...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state != GIRDER_NORMAL) - return - to_chat(user, "You dislodge the girder.") - var/obj/structure/girder/displaced/D = new (loc) - transfer_fingerprints_to(D) - qdel(src) - -/obj/structure/girder/screwdriver_act(mob/user, obj/item/I) - if(state != GIRDER_DISPLACED && state != GIRDER_REINF && state != GIRDER_REINF_STRUTS) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - switch(state) - if(GIRDER_DISPLACED) - TOOL_ATTEMPT_DISMANTLE_MESSAGE - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state != GIRDER_DISPLACED) - return - state = GIRDER_DISASSEMBLED - TOOL_DISMANTLE_SUCCESS_MESSAGE - var/obj/item/stack/sheet/metal/M = new(loc, 2) - M.add_fingerprint(user) - qdel(src) - if(GIRDER_REINF) - to_chat(user, "You start unsecuring support struts...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state != GIRDER_REINF) - return - to_chat(user, "You unsecure the support struts.") - state = GIRDER_REINF_STRUTS - if(GIRDER_REINF_STRUTS) - to_chat(user, "You start securing support struts...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state != GIRDER_REINF_STRUTS) - return - to_chat(user, "You secure the support struts.") - state = GIRDER_REINF - -/obj/structure/girder/wirecutter_act(mob/user, obj/item/I) - if(state != GIRDER_REINF_STRUTS) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - to_chat(user, "You start removing the inner grille...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state != GIRDER_REINF_STRUTS) - return - to_chat(user, "You remove the inner grille.") - new /obj/item/stack/sheet/plasteel(get_turf(src)) - var/obj/structure/girder/G = new (loc) - transfer_fingerprints_to(G) - qdel(src) - -/obj/structure/girder/wrench_act(mob/user, obj/item/I) - if(state != GIRDER_NORMAL && state != GIRDER_DISPLACED) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - if(state == GIRDER_NORMAL) - TOOL_ATTEMPT_DISMANTLE_MESSAGE - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state != GIRDER_NORMAL) - return - state = GIRDER_DISASSEMBLED - TOOL_DISMANTLE_SUCCESS_MESSAGE - refundMetal(metalUsed) - qdel(src) - else - if(!isfloorturf(loc)) - to_chat(user, "A floor must be present to secure the girder!") - return - to_chat(user, "You start securing the girder...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state != GIRDER_DISPLACED) - return - to_chat(user, "You secure the girder.") - var/obj/structure/girder/G = new(loc) - transfer_fingerprints_to(G) - qdel(src) - -/obj/structure/girder/welder_act(mob/user, obj/item/I) - . = TRUE - if(!I.tool_use_check(user, 0)) - return - WELDER_ATTEMPT_SLICING_MESSAGE - if(I.use_tool(src, user, 40, volume = I.tool_volume)) - WELDER_SLICING_SUCCESS_MESSAGE - refundMetal(metalUsed) - qdel(src) - -/obj/structure/girder/CanPass(atom/movable/mover, border_dir) - if(istype(mover) && mover.checkpass(PASSGIRDER)) - return TRUE - if(istype(mover) && mover.checkpass(PASSGRILLE)) - return prob(girderpasschance) - else - if(isprojectile(mover)) - return prob(girderpasschance) - else - return 0 - -/obj/structure/girder/CanPathfindPass(to_dir, datum/can_pass_info/pass_info) - . = !density - if(pass_info.is_movable) - . = . || pass_info.pass_flags & PASSGRILLE - -/obj/structure/girder/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - var/remains = pick(/obj/item/stack/rods, /obj/item/stack/sheet/metal) - new remains(loc) - qdel(src) - -/obj/structure/girder/narsie_act() - if(prob(25)) - new /obj/structure/girder/cult(loc) - qdel(src) - -/obj/structure/girder/displaced - name = "displaced girder" - icon_state = "displaced" - anchored = FALSE - can_displace = FALSE - state = GIRDER_DISPLACED - girderpasschance = 25 - max_integrity = 120 - -/obj/structure/girder/reinforced - name = "reinforced girder" - icon_state = "reinforced" - state = GIRDER_REINF - can_displace = FALSE - girderpasschance = 0 - max_integrity = 350 - -/obj/structure/girder/cult - name = "runed girder" - desc = "Framework made of a strange and shockingly cold metal. It doesn't seem to have any bolts." - icon = 'icons/obj/cult.dmi' - icon_state = "cultgirder" - can_displace = FALSE - metalUsed = 1 - metal_type = /obj/item/stack/sheet/runed_metal - -/obj/structure/girder/cult/Initialize(mapload) - . = ..() - icon_state = GET_CULT_DATA(cult_girder_icon_state, initial(icon_state)) - -/obj/structure/girder/cult/attackby__legacy__attackchain(obj/item/W, mob/user, params) - add_fingerprint(user) - if(istype(W, /obj/item/melee/cultblade/dagger) && IS_CULTIST(user)) //Cultists can demolish cult girders instantly with their dagger - user.visible_message("[user] strikes [src] with [W]!", "You demolish [src].") - refundMetal(metalUsed) - qdel(src) - else if(istype(W, /obj/item/gun/energy/plasmacutter)) - to_chat(user, "You start slicing apart the girder...") - if(do_after(user, 40* W.toolspeed, target = src)) - playsound(loc, W.usesound, 100, 1) - to_chat(user, "You slice apart the girder.") - var/obj/item/stack/sheet/runed_metal/R = new(get_turf(src)) - R.amount = 1 - transfer_fingerprints_to(R) - qdel(src) - else if(istype(W, /obj/item/pickaxe/drill/jackhammer)) - var/obj/item/pickaxe/drill/jackhammer/D = W - to_chat(user, "Your jackhammer smashes through the girder!") - var/obj/item/stack/sheet/runed_metal/R = new(get_turf(src)) - R.amount = 1 - transfer_fingerprints_to(R) - D.playDigSound() - qdel(src) - - else if(istype(W, /obj/item/stack/sheet/runed_metal)) - var/obj/item/stack/sheet/runed_metal/R = W - if(R.get_amount() < 1) - to_chat(user, "You need at least one sheet of runed metal to construct a runed wall!") - return 0 - user.visible_message("[user] begins laying runed metal on [src]...", "You begin constructing a runed wall...") - if(do_after(user, 10, target = src)) - if(R.get_amount() < 1 || !R) - return - user.visible_message("[user] plates [src] with runed metal.", "You construct a runed wall.") - R.use(1) - var/turf/T = get_turf(src) - T.ChangeTurf(/turf/simulated/wall/cult) - qdel(src) - else - return ..() - -/obj/structure/girder/cult/narsie_act() - return - -/obj/structure/girder/cult/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - new /obj/item/stack/sheet/runed_metal(drop_location(), 1) - qdel(src) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm deleted file mode 100644 index c4a1b48e218a6..0000000000000 --- a/code/game/objects/structures/grille.dm +++ /dev/null @@ -1,290 +0,0 @@ -/obj/structure/grille - desc = "A flimsy framework of metal rods." - name = "grille" - icon = 'icons/obj/structures.dmi' - icon_state = "grille" - density = TRUE - anchored = TRUE - flags = CONDUCT - flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2 - pressure_resistance = 5*ONE_ATMOSPHERE - layer = BELOW_OBJ_LAYER - level = 3 - armor = list(MELEE = 50, BULLET = 70, LASER = 70, ENERGY = 100, BOMB = 10, RAD = 100, FIRE = 0, ACID = 0) - max_integrity = 50 - integrity_failure = 20 - var/rods_type = /obj/item/stack/rods - var/rods_amount = 2 - var/rods_broken = 1 - var/grille_type - var/broken_type = /obj/structure/grille/broken - var/shockcooldown = 0 - var/my_shockcooldown = 2 SECONDS - -/obj/structure/grille/examine(mob/user) - . = ..() - . += "A powered wire underneath this will cause the grille to shock anyone who touches the grill. An electric shock may leap forth if the grill is damaged." - . += "Use wirecutters to deconstruct this item." - if(anchored) - . += "It's secured in place with screws. The rods look like they could be cut through." - else - . += "The anchoring screws are unscrewed. The rods look like they could be cut through." - -/obj/structure/grille/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) - . = ..() - update_icon(UPDATE_ICON_STATE) - -/obj/structure/grille/update_icon_state() - if(QDELETED(src) || broken) - return - - var/ratio = obj_integrity / max_integrity - - if(ratio > 0.5) - return - icon_state = "grille50_[rand(0,3)]" - -/obj/structure/grille/Bumped(atom/user) - if(ismob(user)) - if(!(shockcooldown <= world.time)) - return - shock(user, 70) - shockcooldown = world.time + my_shockcooldown - -/obj/structure/grille/attack_animal(mob/living/simple_animal/user) - . = ..() - if(!. || QDELETED(src) || shock(user, 70)) - return - - if(user.environment_smash >= ENVIRONMENT_SMASH_STRUCTURES) - playsound(src, 'sound/effects/grillehit.ogg', 80, TRUE) - obj_break() - user.visible_message("[user] smashes through [src]!", "You smash through [src].") - return - - take_damage(rand(5,10), BRUTE, MELEE, 1) - -/obj/structure/grille/hulk_damage() - return 60 - -/obj/structure/grille/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) - if(user.a_intent == INTENT_HARM) - if(!shock(user, 70)) - ..(user, TRUE) - return TRUE - -/obj/structure/grille/attack_hand(mob/living/user) - . = ..() - if(.) - return - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src, ATTACK_EFFECT_KICK) - user.visible_message("[user] hits [src].") - if(!shock(user, 70)) - take_damage(rand(5,10), BRUTE, MELEE, 1) - -/obj/structure/grille/attack_alien(mob/living/user) - user.do_attack_animation(src) - user.changeNext_move(CLICK_CD_MELEE) - user.visible_message("[user] mangles [src].") - if(!shock(user, 70)) - take_damage(20, BRUTE, MELEE, 1) - -/obj/structure/grille/CanPass(atom/movable/mover, border_dir) - . = !density - if(istype(mover) && mover.checkpass(PASSGRILLE)) - return TRUE - if(isprojectile(mover)) - return (prob(30) || !density) - -/obj/structure/grille/CanPathfindPass(to_dir, datum/can_pass_info/pass_info) - . = !density - if(pass_info.is_movable) - . = . || pass_info.pass_flags & PASSGRILLE - -/obj/structure/grille/attackby__legacy__attackchain(obj/item/I, mob/user, params) - user.changeNext_move(CLICK_CD_MELEE) - add_fingerprint(user) - if(istype(I, /obj/item/stack/rods) && broken) - repair(user, I) - -//window placing begin - else if(is_glass_sheet(I)) - build_window(I, user) - return -//window placing end - - else if(istype(I, /obj/item/shard) || !shock(user, 70)) - return ..() - -/obj/structure/grille/proc/repair(mob/user, obj/item/stack/rods/R) - if(R.get_amount() >= 1) - user.visible_message("[user] rebuilds the broken grille.", - "You rebuild the broken grille.") - new grille_type(loc) - R.use(1) - qdel(src) - -/obj/structure/grille/wirecutter_act(mob/user, obj/item/I) - . = TRUE - if(shock(user, 100)) - return - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - deconstruct() - -/obj/structure/grille/screwdriver_act(mob/user, obj/item/I) - if(!(anchored || issimulatedturf(loc) || locate(/obj/structure/lattice) in get_turf(src))) - return - . = TRUE - if(shock(user, 90)) - return - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - anchored = !anchored - var/support = locate(/obj/structure/lattice) in get_turf(src) - if(!support) - support = get_turf(src) - user.visible_message("[user] [anchored ? "fastens" : "unfastens"] [src].", \ - "You [anchored ? "fasten [src] to" : "unfasten [src] from"] \the [support].") - -/obj/structure/grille/proc/build_window(obj/item/stack/sheet/S, mob/user) - var/dir_to_set = SOUTHWEST - if(!istype(S) || !user) - return - if(broken) - to_chat(user, "You must repair or replace [src] first!") - return - if(S.get_amount() < 2) - to_chat(user, "You need at least two sheets of glass for that!") - return - if(!anchored) - to_chat(user, "[src] needs to be fastened to the floor first!") - return - for(var/obj/structure/window/WINDOW in loc) - to_chat(user, "There is already a window there!") - return - to_chat(user, "You start placing the window...") - if(do_after(user, 20, target = src)) - if(!loc || !anchored) //Grille destroyed or unanchored while waiting - return - for(var/obj/structure/window/WINDOW in loc) //checking this for a 2nd time to check if a window was made while we were waiting. - to_chat(user, "There is already a window there!") - return - var/obj/structure/window/W = new S.full_window(drop_location()) - W.setDir(dir_to_set) - W.ini_dir = dir_to_set - W.anchored = FALSE - recalculate_atmos_connectivity() - W.update_nearby_icons() - W.state = WINDOW_OUT_OF_FRAME - S.use(2) - to_chat(user, "You place [W] on [src].") - - -/obj/structure/grille/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - if(damage_amount) - playsound(src, 'sound/effects/grillehit.ogg', 80, TRUE) - else - playsound(src, 'sound/weapons/tap.ogg', 50, TRUE) - if(BURN) - playsound(src, 'sound/items/welder.ogg', 80, TRUE) - -/obj/structure/grille/deconstruct(disassembled = TRUE) - if(!loc) //if already qdel'd somehow, we do nothing - return - if(!(flags & NODECONSTRUCT)) - var/obj/R = new rods_type(drop_location(), rods_amount) - transfer_fingerprints_to(R) - qdel(src) - ..() - -/obj/structure/grille/obj_break() - if(!broken && !(flags & NODECONSTRUCT)) - new broken_type(loc) - var/obj/R = new rods_type(drop_location(), rods_broken) - transfer_fingerprints_to(R) - qdel(src) - -// shock user with probability prb (if all connections & power are working) -// returns 1 if shocked, 0 otherwise - -/obj/structure/grille/proc/shock(mob/user, prb) - if(!anchored || broken) // unanchored/broken grilles are never connected - return FALSE - if(!prob(prb)) - return FALSE - if(!in_range(src, user))//To prevent TK and mech users from getting shocked - return FALSE - var/turf/T = get_turf(src) - var/obj/structure/cable/C = T.get_cable_node() - if(C) - if(electrocute_mob(user, C, src, 1, TRUE)) - do_sparks(3, 1, src) - return TRUE - else - return FALSE - return FALSE - -/obj/structure/grille/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ..() - if(!broken) - if(exposed_temperature > T0C + 1500) - take_damage(1, BURN, 0, 0) - -/obj/structure/grille/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) - if(isobj(AM)) - if(prob(50) && anchored && !broken) - var/obj/O = AM - if(O.throwforce != 0)//don't want to let people spam tesla bolts, this way it will break after time - var/turf/T = get_turf(src) - var/obj/structure/cable/C = T.get_cable_node() - if(C) - playsound(src, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5) - tesla_zap(src, 3, C.get_queued_available_power() * 0.01, ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN | ZAP_ALLOW_DUPLICATES) //Zap for 1/100 of the amount of power. At a million watts in the grid, it will be as powerful as a tesla revolver shot. - C.add_queued_power_demand(C.get_queued_available_power() * 0.0375) // you can gain up to 3.5 via the 4x upgrades power is halved by the pole so thats 2x then 1X then .5X for 3.5x the 3 bounces shock. - return ..() - -/// Pre-broken grilles for map placement -/obj/structure/grille/broken - icon_state = "brokengrille" - density = FALSE - obj_integrity = 20 - broken = TRUE - rods_amount = 1 - rods_broken = 0 - grille_type = /obj/structure/grille - broken_type = null - -/obj/structure/grille/ratvar - icon_state = "ratvargrille" - name = "cog grille" - desc = "A strangely-shaped grille." - broken_type = /obj/structure/grille/ratvar/broken - -/obj/structure/grille/ratvar/Initialize(mapload) - . = ..() - if(broken) - new /obj/effect/temp_visual/ratvar/grille/broken(get_turf(src)) - else - new /obj/effect/temp_visual/ratvar/grille(get_turf(src)) - new /obj/effect/temp_visual/ratvar/beam/grille(get_turf(src)) - -/obj/structure/grille/ratvar/narsie_act() - take_damage(rand(1, 3), BRUTE) - if(src) - var/previouscolor = color - color = "#960000" - animate(src, color = previouscolor, time = 8) - -/obj/structure/grille/ratvar/broken - icon_state = "brokenratvargrille" - density = FALSE - obj_integrity = 20 - broken = TRUE - rods_amount = 1 - rods_broken = 0 - grille_type = /obj/structure/grille/ratvar - broken_type = null diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm deleted file mode 100644 index 692510e8cecaf..0000000000000 --- a/code/game/objects/structures/guillotine.dm +++ /dev/null @@ -1,261 +0,0 @@ -#define GUILLOTINE_BLADE_MAX_SHARP 10 // This is maxiumum sharpness that will decapitate without failure -#define GUILLOTINE_DECAP_MIN_SHARP 7 // Minimum amount of sharpness for decapitation. Any less and it will just deal brute damage -#define GUILLOTINE_ANIMATION_LENGTH 9 // How many deciseconds the animation is -#define GUILLOTINE_BLADE_RAISED 1 -#define GUILLOTINE_BLADE_MOVING 2 -#define GUILLOTINE_BLADE_DROPPED 3 -#define GUILLOTINE_BLADE_SHARPENING 4 -#define GUILLOTINE_HEAD_OFFSET 16 // How much we need to move the player to center their head -#define GUILLOTINE_LAYER_DIFF 1.2 // How much to increase/decrease a head when it's buckled/unbuckled -#define GUILLOTINE_ACTIVATE_DELAY 30 // Delay for executing someone -#define GUILLOTINE_WRENCH_DELAY 10 -#define GUILLOTINE_ACTION_INUSE 5 -#define GUILLOTINE_ACTION_WRENCH 6 - -/obj/structure/guillotine - name = "guillotine" - desc = "A large structure used to remove the heads of traitors and treasonists." - icon = 'icons/obj/guillotine.dmi' - icon_state = "guillotine_raised" - can_buckle = TRUE - anchored = TRUE - density = FALSE - buckle_lying = FALSE - layer = ABOVE_MOB_LAYER - var/blade_status = GUILLOTINE_BLADE_RAISED - var/blade_sharpness = GUILLOTINE_BLADE_MAX_SHARP // How sharp the blade is - var/kill_count = 0 - var/force_clap = FALSE //You WILL clap if I want you to - var/current_action = 0 // What's currently happening to the guillotine - -/obj/structure/guillotine/Initialize(mapload) - LAZYINITLIST(buckled_mobs) - return ..() - -/obj/structure/guillotine/Destroy() - if(has_buckled_mobs()) - unbuckle_all_mobs() - return ..() - -/obj/structure/guillotine/examine(mob/user) - . = ..() - - var/msg = "" - - msg += "It is [anchored ? "wrenched to the floor." : "unsecured. A wrench should fix that."]
    " - - if(blade_status == GUILLOTINE_BLADE_RAISED) - msg += "The blade is raised, ready to fall, and" - - if(blade_sharpness >= GUILLOTINE_DECAP_MIN_SHARP) - msg += " looks sharp enough to decapitate without any resistance." - else - msg += " doesn't look particularly sharp. Perhaps a whetstone can be used to sharpen it." - else - msg += "The blade is hidden inside the stocks." - - if(has_buckled_mobs()) - msg += "
    " - msg += "Someone appears to be strapped in. You can help them out, or you can harm them by activating the guillotine." - - . += msg - -/obj/structure/guillotine/attack_hand(mob/user) - add_fingerprint(user) - - // Currently being used by something - if(current_action) - return - - switch(blade_status) - if(GUILLOTINE_BLADE_MOVING) - return - if(GUILLOTINE_BLADE_DROPPED) - blade_status = GUILLOTINE_BLADE_MOVING - icon_state = "guillotine_raise" - addtimer(CALLBACK(src, PROC_REF(raise_blade)), GUILLOTINE_ANIMATION_LENGTH) - return - if(GUILLOTINE_BLADE_RAISED) - if(has_buckled_mobs()) - if(user.a_intent == INTENT_HARM) - user.visible_message("[user] begins to pull the lever!", - "You begin to the pull the lever.") - current_action = GUILLOTINE_ACTION_INUSE - - if(do_after(user, GUILLOTINE_ACTIVATE_DELAY, target = src) && blade_status == GUILLOTINE_BLADE_RAISED) - current_action = 0 - blade_status = GUILLOTINE_BLADE_MOVING - icon_state = "guillotine_drop" - playsound(src, 'sound/items/unsheath.ogg', 100, 1) - addtimer(CALLBACK(src, PROC_REF(drop_blade), user), GUILLOTINE_ANIMATION_LENGTH - 2) // Minus two so we play the sound and decap faster - else - current_action = 0 - else - unbuckle_all_mobs() - else - blade_status = GUILLOTINE_BLADE_MOVING - icon_state = "guillotine_drop" - playsound(src, 'sound/items/unsheath.ogg', 100, 1) - addtimer(CALLBACK(src, PROC_REF(drop_blade)), GUILLOTINE_ANIMATION_LENGTH) - -/obj/structure/guillotine/proc/raise_blade() - blade_status = GUILLOTINE_BLADE_RAISED - icon_state = "guillotine_raised" - -/obj/structure/guillotine/proc/drop_blade(mob/user) - if(has_buckled_mobs() && blade_sharpness) - var/mob/living/carbon/human/H = buckled_mobs[1] - - if(!H) - blade_status = GUILLOTINE_BLADE_DROPPED - icon_state = "guillotine" - return - - var/obj/item/organ/external/head/head = H.get_organ("head") - - if(QDELETED(head) || !istype(head)) - blade_status = GUILLOTINE_BLADE_DROPPED - icon_state = "guillotine" - return - - playsound(src, 'sound/weapons/bladeslice.ogg', 100, 1) - if(blade_sharpness >= GUILLOTINE_DECAP_MIN_SHARP || head.brute_dam >= 100) - head.droplimb() - add_attack_logs(user, H, "beheaded with [src]") - H.regenerate_icons() - unbuckle_all_mobs() - kill_count += 1 - - var/blood_overlay = "bloody" - - if(kill_count == 2) - blood_overlay = "bloodier" - else if(kill_count > 2) - blood_overlay = "bloodiest" - - blood_overlay = "guillotine_" + blood_overlay + "_overlay" - overlays.Cut() - overlays += mutable_appearance(icon, blood_overlay) - - if(force_clap) - // The crowd is pleased - // The delay is to make large crowds have a longer lasting applause - var/delay_offset = 0 - for(var/mob/living/carbon/human/HM in viewers(src, 7)) - addtimer(CALLBACK(HM, TYPE_PROC_REF(/mob, emote), "clap"), delay_offset * 0.3) - delay_offset++ - else - H.apply_damage(15 * blade_sharpness, BRUTE, head) - add_attack_logs(user, H, "non-fatally dropped the blade on with [src]") - H.emote("scream") - - if(blade_sharpness > 1) - blade_sharpness -= 1 - - blade_status = GUILLOTINE_BLADE_DROPPED - icon_state = "guillotine" - -/obj/structure/guillotine/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(istype(W, /obj/item/whetstone)) - add_fingerprint(user) - if(blade_status == GUILLOTINE_BLADE_SHARPENING) - return - - if(blade_status == GUILLOTINE_BLADE_RAISED) - if(blade_sharpness < GUILLOTINE_BLADE_MAX_SHARP) - blade_status = GUILLOTINE_BLADE_SHARPENING - if(do_after(user, 7, target = src)) - blade_status = GUILLOTINE_BLADE_RAISED - user.visible_message("[user] sharpens the large blade of the guillotine.", - "You sharpen the large blade of the guillotine.") - blade_sharpness += 1 - playsound(src, 'sound/items/screwdriver.ogg', 100, 1) - return - else - blade_status = GUILLOTINE_BLADE_RAISED - return - else - to_chat(user, "The blade is sharp enough!") - return - else - to_chat(user, "You need to raise the blade in order to sharpen it!") - return - else - return ..() - -/obj/structure/guillotine/wrench_act(mob/user, obj/item/I) - if(current_action) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - current_action = GUILLOTINE_ACTION_WRENCH - if(!I.use_tool(src, user, GUILLOTINE_WRENCH_DELAY, volume = I.tool_volume)) - current_action = 0 - return - if(has_buckled_mobs()) - to_chat(user, "Can't unfasten, someone's strapped in!") - return - - current_action = 0 - to_chat(user, "You [anchored ? "un" : ""]secure [src].") - anchored = !anchored - playsound(src, 'sound/items/deconstruct.ogg', 50, 1) - dir = SOUTH - -/obj/structure/guillotine/welder_act(mob/user, obj/item/I) - . = TRUE - if(!I.tool_use_check(user, 0)) - return - WELDER_ATTEMPT_SLICING_MESSAGE - if(I.use_tool(src, user, 40, volume = I.tool_volume)) - WELDER_SLICING_SUCCESS_MESSAGE - var/turf/T = get_turf(src) - if(blade_sharpness == GUILLOTINE_BLADE_MAX_SHARP) - new /obj/item/stack/sheet/plasteel(T, 3) - else - new /obj/item/stack/sheet/plasteel(T, 2) //prevents reconstructing to sharpen the guillotine without additional plasteel - new /obj/item/stack/sheet/wood(T, 20) - new /obj/item/stack/cable_coil(T, 10) - qdel(src) - -/obj/structure/guillotine/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE) - if(!anchored) - to_chat(usr, "[src] needs to be wrenched to the floor!") - return FALSE - - if(!ishuman(M)) - to_chat(usr, "It doesn't look like [M.p_they()] can fit into this properly!") - return FALSE // Can't decapitate non-humans - - if(blade_status != GUILLOTINE_BLADE_RAISED) - to_chat(usr, "You need to raise the blade before buckling someone in!") - return FALSE - - return ..(M, force, FALSE) - -/obj/structure/guillotine/post_buckle_mob(mob/living/M) - if(!ishuman(M)) - return - M.pixel_y += -GUILLOTINE_HEAD_OFFSET // Offset their body so it looks like they're in the guillotine - M.layer += GUILLOTINE_LAYER_DIFF - ..() - -/obj/structure/guillotine/post_unbuckle_mob(mob/living/M) - M.pixel_y -= -GUILLOTINE_HEAD_OFFSET // Move their body back - M.layer -= GUILLOTINE_LAYER_DIFF - ..() - -#undef GUILLOTINE_BLADE_MAX_SHARP -#undef GUILLOTINE_DECAP_MIN_SHARP -#undef GUILLOTINE_ANIMATION_LENGTH -#undef GUILLOTINE_BLADE_RAISED -#undef GUILLOTINE_BLADE_MOVING -#undef GUILLOTINE_BLADE_DROPPED -#undef GUILLOTINE_BLADE_SHARPENING -#undef GUILLOTINE_HEAD_OFFSET -#undef GUILLOTINE_LAYER_DIFF -#undef GUILLOTINE_ACTIVATE_DELAY -#undef GUILLOTINE_WRENCH_DELAY -#undef GUILLOTINE_ACTION_INUSE -#undef GUILLOTINE_ACTION_WRENCH diff --git a/code/game/objects/structures/holosigns.dm b/code/game/objects/structures/holosigns.dm deleted file mode 100644 index 3631b28451ded..0000000000000 --- a/code/game/objects/structures/holosigns.dm +++ /dev/null @@ -1,155 +0,0 @@ - -//holographic signs and barriers - -/obj/structure/holosign - name = "holo sign" - icon = 'icons/effects/effects.dmi' - anchored = TRUE - max_integrity = 1 - armor = list(MELEE = 0, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 0, RAD = 0, FIRE = 20, ACID = 20) - var/obj/item/holosign_creator/projector - -/obj/structure/holosign/Initialize(mapload, source_projector) - . = ..() - if(source_projector) - projector = source_projector - projector.signs += src - -/obj/structure/holosign/Destroy() - if(projector) - projector.signs -= src - projector = null - return ..() - -/obj/structure/holosign/attack_hand(mob/living/user) - . = ..() - if(.) - return - user.do_attack_animation(src) - user.changeNext_move(CLICK_CD_MELEE) - take_damage(5 , BRUTE, MELEE, 1) - -/obj/structure/holosign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - playsound(loc, 'sound/weapons/egloves.ogg', 80, TRUE) - if(BURN) - playsound(loc, 'sound/weapons/egloves.ogg', 80, TRUE) - -/obj/structure/holosign/wetsign - name = "wet floor sign" - desc = "The words flicker as if they mean nothing." - icon_state = "holosign" - -/obj/structure/holosign/wetsign/proc/wet_timer_start(obj/item/holosign_creator/HS_C) - addtimer(CALLBACK(src, PROC_REF(wet_timer_finish), HS_C), 82 SECONDS, TIMER_UNIQUE) - -/obj/structure/holosign/wetsign/proc/wet_timer_finish(obj/item/holosign_creator/HS_C) - playsound(HS_C.loc, 'sound/machines/chime.ogg', 20, 1) - qdel(src) - -/obj/structure/holosign/barrier - name = "holo barrier" - desc = "A short holographic barrier which can only be passed by walking." - icon_state = "holosign_sec" - pass_flags_self = LETPASSTHROW | PASSTAKE - density = TRUE - max_integrity = 20 - var/allow_walk = TRUE //can we pass through it on walk intent - -/obj/structure/holosign/barrier/CanPass(atom/movable/mover, border_dir) - if(!density) - return TRUE - if(mover.pass_flags & (PASSGLASS|PASSTABLE|PASSGRILLE)) - return TRUE - if(isliving(mover)) - var/mob/living/walker = mover - if(allow_walk && (walker.m_intent == MOVE_INTENT_WALK || (walker.pulledby && walker.pulledby.m_intent == MOVE_INTENT_WALK))) - return TRUE - -/obj/structure/holosign/barrier/engineering - icon_state = "holosign_engi" - flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2 - rad_insulation = RAD_LIGHT_INSULATION - -/obj/structure/holosign/barrier/atmos - name = "holo firelock" - desc = "A holographic barrier resembling a firelock. Though it does not prevent solid objects from passing through, gas is kept out." - icon_state = "holo_firelock" - density = FALSE - layer = ABOVE_MOB_LAYER - anchored = TRUE - alpha = 150 - flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2 - rad_insulation = RAD_LIGHT_INSULATION - -/obj/structure/holosign/barrier/atmos/Initialize(mapload) - . = ..() - recalculate_atmos_connectivity() - -// Airtight. -/obj/structure/holosign/barrier/atmos/CanAtmosPass(direction) - return FALSE - -// Heatproof. -/obj/structure/holosign/barrier/atmos/get_superconductivity(direction) - return 0 - -/obj/structure/holosign/barrier/atmos/Destroy() - var/turf/T = get_turf(src) - . = ..() - T.recalculate_atmos_connectivity() - -/obj/structure/holosign/barrier/cyborg - name = "Energy Field" - desc = "A fragile energy field that blocks movement. Excels at blocking lethal projectiles." - density = TRUE - max_integrity = 10 - allow_walk = FALSE - -/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. - if(istype(P, /obj/item/projectile/energy/electrode)) - 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. - -/obj/structure/holosign/barrier/cyborg/hacked - name = "Charged Energy Field" - desc = "A powerful energy field that blocks movement. Energy arcs off it." - max_integrity = 20 - 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. - -/obj/structure/holosign/barrier/cyborg/hacked/proc/cooldown() - shockcd = FALSE - -/obj/structure/holosign/barrier/cyborg/hacked/attack_hand(mob/living/user) - . = ..() - if(.) - return - if(!shockcd) - if(isliving(user)) - var/mob/living/M = user - M.electrocute_act(15, "Energy Barrier") - shockcd = TRUE - addtimer(CALLBACK(src, PROC_REF(cooldown)), 5) - -/obj/structure/holosign/barrier/cyborg/hacked/Bumped(atom/movable/AM) - if(shockcd) - return - - if(!isliving(AM)) - return - - var/mob/living/M = AM - M.electrocute_act(15, "Energy Barrier") - shockcd = TRUE - addtimer(CALLBACK(src, PROC_REF(cooldown)), 5) - -/obj/structure/holosign/barrier/cyborg/hacked/detective - name = "investigation barrier" - desc = "An authoritive holographic barrier proclaiming a crime scene. Energy arcs off of it." - icon_state = "holosign_det" diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm deleted file mode 100644 index c206bd8195baf..0000000000000 --- a/code/game/objects/structures/janicart.dm +++ /dev/null @@ -1,225 +0,0 @@ -//TG style Janicart - -/obj/structure/janitorialcart - name = "janitorial cart" - desc = "This is the alpha and omega of sanitation." - icon = 'icons/obj/janitor.dmi' - icon_state = "cart" - anchored = FALSE - density = TRUE - face_while_pulling = FALSE - container_type = OPENCONTAINER - //copypaste sorry - var/maximum_volume = 150 - var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite - var/obj/item/storage/bag/trash/mybag = null - var/obj/item/mop/mymop = null - var/obj/item/push_broom/mybroom = null - var/obj/item/reagent_containers/spray/cleaner/myspray = null - var/obj/item/lightreplacer/myreplacer = null - var/signs = 0 - var/const/max_signs = 4 - -/obj/structure/janitorialcart/Initialize(mapload) - . = ..() - create_reagents(150) - GLOB.janitorial_equipment += src - -/obj/structure/janitorialcart/Destroy() - GLOB.janitorial_equipment -= src - QDEL_NULL(mybag) - QDEL_NULL(mymop) - QDEL_NULL(mybroom) - QDEL_NULL(myspray) - QDEL_NULL(myreplacer) - return ..() - -/obj/structure/janitorialcart/proc/put_in_cart(mob/user, obj/item/I) - if(!user.unequip(I)) // We can do this here because everything below wants to - to_chat(user, "[I] is stuck to your hand!") - return - - I.forceMove(src) - to_chat(user, "You put [I] into [src].") - update_icon(UPDATE_OVERLAYS) - return - -/obj/structure/janitorialcart/on_reagent_change() - update_icon(UPDATE_OVERLAYS) - -/obj/structure/janitorialcart/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(I.is_robot_module()) - to_chat(user, "You cannot interface your modules with [src]!") - return - - if(istype(I, /obj/item/mop)) - var/obj/item/mop/M = I - if(M.reagents.total_volume < M.reagents.maximum_volume) - M.wet_mop(src, user) - return - if(!mymop) - mymop = I - put_in_cart(user, I) - return - to_chat(user, "There is already one of those in [src].") - - else if(istype(I, /obj/item/push_broom) && !mybroom) - mybroom = I - put_in_cart(user, I) - - else if(istype(I, /obj/item/storage/bag/trash) && !mybag) - mybag = I - put_in_cart(user, I) - - else if(istype(I, /obj/item/reagent_containers/spray/cleaner) && !myspray) - myspray = I - put_in_cart(user, I) - - else if(istype(I, /obj/item/lightreplacer) && !myreplacer) - myreplacer = I - put_in_cart(user, I) - - else if(istype(I, /obj/item/caution)) - if(signs < max_signs) - signs++ - put_in_cart(user, I) - else - to_chat(user, "[src] can't hold any more signs.") - - to_chat(user, "There is already one of those in [src].") - - else if(mybag) - mybag.attackby__legacy__attackchain(I, user, params) - - else - to_chat(user, "There is already one of those in [src].") - -/obj/structure/janitorialcart/crowbar_act(mob/living/user, obj/item/I) - . = TRUE - user.visible_message("[user] begins to empty the contents of [src].") - if(!I.use_tool(src, user, 3 SECONDS, I.tool_volume)) - return - to_chat(user, "You empty the contents of [src]'s bucket onto the floor.") - reagents.reaction(loc) - reagents.clear_reagents() - -/obj/structure/janitorialcart/wrench_act(mob/living/user, obj/item/I) - . = TRUE - if(!anchored && !isinspace()) - if(!I.use_tool(src, user, I.tool_volume)) - return - user.visible_message( \ - "[user] tightens [src]'s casters.", \ - "You have tightened [src]'s casters.", \ - "You hear ratchet.") - anchored = TRUE - return - if(anchored) - if(!I.use_tool(src, user, I.tool_volume)) - return - user.visible_message( \ - "[user] loosens [src]'s casters.", \ - "You have loosened [src]'s casters.", \ - "You hear ratchet.") - anchored = FALSE - -/obj/structure/janitorialcart/attack_hand(mob/user) - var/list/cart_items = list() - - if(mybag) - cart_items["Trash Bag"] = image(icon = mybag.icon, icon_state = mybag.icon_state) - if(mymop) - cart_items["Mop"] = image(icon = mymop.icon, icon_state = mymop.icon_state) - if(mybroom) - cart_items["Broom"] = image(icon = mybroom.icon, icon_state = mybroom.icon_state) - if(myspray) - cart_items["Spray Bottle"] = image(icon = myspray.icon, icon_state = myspray.icon_state) - if(myreplacer) - cart_items["Light Replacer"] = image(icon = myreplacer.icon, icon_state = myreplacer.icon_state) - var/obj/item/caution/Sign = locate() in src - if(Sign) - cart_items["Sign"] = image(icon = Sign.icon, icon_state = Sign.icon_state) - - if(!length(cart_items)) - return - - var/pick = show_radial_menu(user, src, cart_items, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE) - - if(!pick) - return - - switch(pick) - if("Trash Bag") - if(!mybag) - return - user.put_in_hands(mybag) - to_chat(user, "You take [mybag] from [src].") - mybag = null - if("Mop") - if(!mymop) - return - user.put_in_hands(mymop) - to_chat(user, "You take [mymop] from [src].") - mymop = null - if("Broom") - if(!mybroom) - return - user.put_in_hands(mybroom) - to_chat(user, "You take [mybroom] from [src].") - mybroom = null - if("Spray Bottle") - if(!myspray) - return - user.put_in_hands(myspray) - to_chat(user, "You take [myspray] from [src].") - myspray = null - if("Light Replacer") - if(!myreplacer) - return - user.put_in_hands(myreplacer) - to_chat(user, "You take [myreplacer] from [src].") - myreplacer = null - if("Sign") - if(!signs) - return - if(Sign) - user.put_in_hands(Sign) - to_chat(user, "You take \a [Sign] from [src].") - signs-- - else - WARNING("Signs ([signs]) didn't match contents") - signs = 0 - - update_icon(UPDATE_OVERLAYS) - -/obj/structure/janitorialcart/proc/check_menu(mob/living/user) - return (istype(user) && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) - -/obj/structure/janitorialcart/update_overlays() - . = ..() - if(mybag) - . += "cart_garbage" - if(mymop) - . += "cart_mop" - if(mybroom) - . += "cart_broom" - if(myspray) - . += "cart_spray" - if(myreplacer) - . += "cart_replacer" - if(signs) - . += "cart_sign[signs]" - if(reagents.total_volume > 0) - var/image/reagentsImage = image(icon,src,"cart_reagents0") - reagentsImage.alpha = 150 - switch((reagents.total_volume / maximum_volume) * 100) - if(1 to 37) - reagentsImage.icon_state = "cart_reagents1" - if(38 to 75) - reagentsImage.icon_state = "cart_reagents2" - if(76 to 112) - reagentsImage.icon_state = "cart_reagents3" - if(113 to 150) - reagentsImage.icon_state = "cart_reagents4" - reagentsImage.icon += mix_color_from_reagents(reagents.reagent_list) - . += reagentsImage diff --git a/code/game/objects/structures/lavaland/ladder.dm b/code/game/objects/structures/lavaland/ladder.dm deleted file mode 100644 index 3f97db6e9e730..0000000000000 --- a/code/game/objects/structures/lavaland/ladder.dm +++ /dev/null @@ -1,6 +0,0 @@ -/obj/structure/ladder - name = "shattered ladder" - desc = "The shattered remnants of a ladder hanging over the pitch-black chasm, providing no safe route to the abyss beneath. Its fractured rungs suggest an inevitable plunge, as if the remainder might soon join the void." - icon = 'icons/obj/structures.dmi' - icon_state = "ladder" - anchored = TRUE diff --git a/code/game/objects/structures/lavaland/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm deleted file mode 100644 index 8550806b07213..0000000000000 --- a/code/game/objects/structures/lavaland/necropolis_tendril.dm +++ /dev/null @@ -1,94 +0,0 @@ -//Necropolis Tendrils, which spawn lavaland monsters and break into a chasm when killed -/obj/structure/spawner/lavaland - name = "necropolis tendril" - desc = "A vile tendril of corruption, originating deep underground. Terrible monsters are pouring out of it." - - icon = 'icons/mob/nest.dmi' - icon_state = "tendril" - - faction = list("mining") - max_mobs = 3 - max_integrity = 250 - mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril) - - move_resist = INFINITY // just killing it tears a massive hole in the ground, let's not move it - anchored = TRUE - resistance_flags = FIRE_PROOF | LAVA_PROOF - - var/obj/effect/light_emitter/tendril/emitted_light - -/obj/structure/spawner/lavaland/goliath - mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril) - -/obj/structure/spawner/lavaland/legion - mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril) - -GLOBAL_LIST_EMPTY(tendrils) - -/obj/structure/spawner/lavaland/Initialize(mapload) - . = ..() - emitted_light = new(loc) - GLOB.tendrils += src - return INITIALIZE_HINT_LATELOAD - -/obj/structure/spawner/lavaland/LateInitialize() - for(var/F in RANGE_TURFS(1, src)) - if(ismineralturf(F)) - var/turf/simulated/mineral/M = F - M.ChangeTurf(M.turf_type, FALSE, FALSE, TRUE) - -/obj/structure/spawner/lavaland/deconstruct(disassembled) - new /obj/effect/collapse(loc) - new /obj/structure/closet/crate/necropolis/tendril(loc) - return ..() - -/obj/structure/spawner/lavaland/attacked_by__legacy__attackchain(obj/item/I, mob/living/user) - . = ..() - SEND_SIGNAL(src, COMSIG_SPAWNER_SET_TARGET, user) - -/obj/structure/spawner/lavaland/bullet_act(obj/item/projectile/P) - . = ..() - if(P.firer) - SEND_SIGNAL(src, COMSIG_SPAWNER_SET_TARGET, P.firer) - -/obj/structure/spawner/lavaland/Destroy() - GLOB.tendrils -= src - QDEL_NULL(emitted_light) - return ..() - -/obj/effect/light_emitter/tendril - set_luminosity = 4 - set_cap = 2.5 - light_color = LIGHT_COLOR_LAVA - -/obj/effect/collapse - name = "collapsing necropolis tendril" - desc = "Get clear!" - layer = TABLE_LAYER - icon = 'icons/mob/nest.dmi' - icon_state = "tendril" - anchored = TRUE - density = TRUE - var/obj/effect/light_emitter/tendril/emitted_light - -/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!") - visible_message("Something falls free of the tendril!") - playsound(loc, 'sound/effects/tendril_destroyed.ogg', 200, FALSE, 50, TRUE, TRUE) - addtimer(CALLBACK(src, PROC_REF(collapse)), 50) - -/obj/effect/collapse/Destroy() - QDEL_NULL(emitted_light) - return ..() - -/obj/effect/collapse/proc/collapse() - for(var/mob/M in range(7, src)) - shake_camera(M, 15, 1) - playsound(get_turf(src),'sound/effects/explosionfar.ogg', 200, TRUE) - visible_message("The tendril falls inward, the ground around it widening into a yawning chasm!") - for(var/turf/T in range(LAVALAND_TENDRIL_COLLAPSE_RANGE, src)) - if(!T.density) - T.TerraformTurf(/turf/simulated/floor/chasm/straight_down/lava_land_surface) - qdel(src) diff --git a/code/game/objects/structures/loom.dm b/code/game/objects/structures/loom.dm deleted file mode 100644 index fd0e30d1144cb..0000000000000 --- a/code/game/objects/structures/loom.dm +++ /dev/null @@ -1,56 +0,0 @@ -#define FABRIC_PER_SHEET 4 - - -///This is a loom. It's usually made out of wood and used to weave fabric like durathread or cotton into their respective cloth types. -/obj/structure/loom - name = "loom" - desc = "A simple device used to weave cloth and other thread-based fabrics together into usable material." - icon = 'icons/obj/hydroponics/equipment.dmi' - icon_state = "loom" - density = TRUE - anchored = TRUE - -/obj/structure/loom/attackby__legacy__attackchain(obj/item/I, mob/user) - if(weave(I, user)) - return - return ..() - -/obj/structure/loom/crowbar_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0)) - return - TOOL_ATTEMPT_DISMANTLE_MESSAGE - if(I.use_tool(src, user, 50, volume = I.tool_volume)) - TOOL_DISMANTLE_SUCCESS_MESSAGE - deconstruct(disassembled = TRUE) - -/obj/structure/loom/wrench_act(mob/user, obj/item/I) - . = TRUE - default_unfasten_wrench(user, I, time = 20) - -/obj/structure/loom/deconstruct(disassembled = FALSE) - var/mat_drop = 5 - if(disassembled) - mat_drop = 10 - new /obj/item/stack/sheet/wood(drop_location(), mat_drop) - ..() - -///Handles the weaving. -/obj/structure/loom/proc/weave(obj/item/stack/sheet/cotton/W, mob/user) - if(!istype(W)) - return FALSE - if(!anchored) - user.show_message("The loom needs to be wrenched down.", 1) - return FALSE - if(W.amount < FABRIC_PER_SHEET) - user.show_message("You need at least [FABRIC_PER_SHEET] units of fabric before using this.", 1) - return FALSE - user.show_message("You start weaving [W] through the loom...", 1) - if(do_after(user, W.pull_effort, target = src)) - if(W.amount >= FABRIC_PER_SHEET) - new W.loom_result(drop_location()) - W.use(FABRIC_PER_SHEET) - user.show_message("You weave [W] into a workable fabric.", 1) - return TRUE - -#undef FABRIC_PER_SHEET diff --git a/code/game/objects/structures/monster_spawner.dm b/code/game/objects/structures/monster_spawner.dm deleted file mode 100644 index 67b5d6694c1db..0000000000000 --- a/code/game/objects/structures/monster_spawner.dm +++ /dev/null @@ -1,161 +0,0 @@ -/obj/structure/spawner - name = "monster nest" - icon = 'icons/mob/animal.dmi' - icon_state = null - max_integrity = 100 - - move_resist = MOVE_FORCE_EXTREMELY_STRONG - anchored = TRUE - density = TRUE - - var/max_mobs = 5 - var/spawn_time = 300 //30 seconds default - var/mob_types = list(/mob/living/simple_animal/hostile/carp) - var/spawn_text = "emerges from" - var/faction = list("hostile") - var/spawner_type = /datum/component/spawner - -/obj/structure/spawner/Initialize(mapload) - . = ..() - AddComponent(spawner_type, mob_types, spawn_time, faction, spawn_text, max_mobs) - -/obj/structure/spawner/attack_animal(mob/living/simple_animal/M) - if(faction_check(faction, M.faction, FALSE) && !M.client) - return - ..() - - -/obj/structure/spawner/syndicate - name = "warp beacon" - icon = 'icons/obj/device.dmi' - icon_state = "syndbeacon" - spawn_text = "warps in from" - mob_types = list(/mob/living/simple_animal/hostile/syndicate/ranged) - faction = list(ROLE_SYNDICATE) - -/obj/structure/spawner/skeleton - name = "bone pit" - desc = "A pit full of bones, and some still seem to be moving..." - icon_state = "hole" - icon = 'icons/mob/nest.dmi' - max_integrity = 150 - max_mobs = 15 - spawn_time = 150 - mob_types = list(/mob/living/simple_animal/hostile/skeleton) - spawn_text = "climbs out of" - faction = list("skeleton") - -/obj/structure/spawner/mining - name = "monster den" - desc = "A hole dug into the ground, harboring all kinds of monsters found within most caves or mining asteroids." - icon_state = "hole" - max_integrity = 200 - max_mobs = 3 - icon = 'icons/mob/nest.dmi' - spawn_text = "crawls out of" - mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub, /mob/living/simple_animal/hostile/asteroid/goliath, /mob/living/simple_animal/hostile/asteroid/hivelord, /mob/living/simple_animal/hostile/asteroid/basilisk) - faction = list("mining") - -/obj/structure/spawner/mining/goldgrub - name = "goldgrub den" - desc = "A den housing a nest of goldgrubs, annoying but arguably much better than anything else you'll find in a nest." - mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub) - -/obj/structure/spawner/mining/goliath - name = "goliath den" - desc = "A den housing a nest of goliaths, oh god why?" - mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath) - -/obj/structure/spawner/mining/hivelord - name = "hivelord den" - desc = "A den housing a nest of hivelords." - mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord) - -/obj/structure/spawner/mining/basilisk - name = "basilisk den" - desc = "A den housing a nest of basilisks, bring a coat." - mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk) - -/obj/structure/spawner/sentient - var/role_name = "A sentient mob" - var/assumed_control_message = "You are a sentient mob from a badly coded spawner" - -/obj/structure/spawner/sentient/Initialize(mapload) - . = ..() - notify_ghosts("\A [name] has been created in \the [get_area(src)]!", source = src, title = "Sentient Spawner Created", flashwindow = FALSE - ) - -/obj/structure/spawner/sentient/on_mob_spawn(mob/created_mob) - created_mob.AddComponent(\ - /datum/component/ghost_direct_control,\ - role_name = src.role_name,\ - assumed_control_message = src.assumed_control_message,\ - after_assumed_control = CALLBACK(src, PROC_REF(became_player_controlled)),\ - ) - -/obj/structure/spawner/sentient/proc/became_player_controlled(mob/proteon) - return - -/obj/structure/spawner/sentient/proteon_spawner - name = "eldritch gateway" - desc = "A dizzying structure that somehow links into Nar'Sie's own domain. The screams of the damned echo continously." - icon = 'icons/obj/cult.dmi' - icon_state = "hole" - light_power = 2 - light_color = LIGHT_COLOR_RED - max_integrity = 50 - density = FALSE - max_mobs = 2 - spawn_time = 15 SECONDS - mob_types = list(/mob/living/simple_animal/hostile/construct/proteon/hostile) - spawn_text = "arises from" - faction = list("cult") - role_name = "A proteon cult construct" - assumed_control_message = null - /// The GPS inside the spawner, lets security find them, especially if someone is space basing them. - var/obj/item/gps/internal/proteon/gps - -/obj/structure/spawner/sentient/proteon_spawner/Initialize(mapload) - . = ..() - GLOB.proteon_portals += src - gps = new /obj/item/gps/internal/proteon(src) - -/obj/structure/spawner/sentient/proteon_spawner/Destroy() - GLOB.proteon_portals -= src - QDEL_NULL(gps) - return ..() - -/obj/structure/spawner/sentient/proteon_spawner/examine_status(mob/user) - if(IS_CULTIST(user) || !isliving(user)) - return "It's at [round(obj_integrity * 100 / max_integrity)]% stability." - return ..() - -/obj/structure/spawner/sentient/proteon_spawner/examine(mob/user) - . = ..() - if(!IS_CULTIST(user) && isliving(user)) - var/mob/living/living_user = user - living_user.adjustBrainLoss(5) - . += "The voices of the damned echo relentlessly in your mind, continously rebounding on the walls of your self the more you focus on [src]. Your head pounds, better keep away..." - else - . += "The gateway will create one weak proteon construct every [spawn_time * 0.1] seconds, up to a total of [max_mobs], that may be controlled by the spirits of the dead." - -/obj/structure/spawner/sentient/proteon_spawner/became_player_controlled(mob/living/simple_animal/hostile/construct/proteon/hostile/proteon) - proteon.mind.add_antag_datum(/datum/antagonist/cultist) - proteon.add_filter("awoken_proteon", 3, list("type" = "outline", "color" = LIGHT_COLOR_RED, "size" = 2)) - visible_message("[proteon] awakens, glowing an eerie red as it stirs from its stupor!") - addtimer(CALLBACK(src, PROC_REF(remove_wake_outline), proteon), 8 SECONDS) - -/obj/structure/spawner/sentient/proteon_spawner/proc/remove_wake_outline(mob/proteon) - proteon.remove_filter("awoken_proteon") - proteon.add_filter("sentient_proteon", 3, list("type" = "outline", "color" = LIGHT_COLOR_RED, "size" = 2, "alpha" = 40)) - -/obj/structure/spawner/sentient/proteon_spawner/obj_destruction(damage_flag) - playsound(src, 'sound/hallucinations/veryfar_noise.ogg', 75) - visible_message("[src] completely falls apart, the screams of the damned reaching a feverous pitch before slowly fading away into nothing.") - return ..() - -/obj/item/gps/internal/proteon - local = FALSE // Let security find the cult bases in space with it. - icon_state = null - gpstag = "Eldritch Signal" - desc = "You (can)'t just BSA a hole into hell!" diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm deleted file mode 100644 index 85df7aa4dd616..0000000000000 --- a/code/game/objects/structures/mop_bucket.dm +++ /dev/null @@ -1,84 +0,0 @@ -/obj/structure/mopbucket - name = "mop bucket" - desc = "Fill it with water, but don't forget a mop!" - icon = 'icons/obj/janitor.dmi' - icon_state = "mopbucket" - density = TRUE - container_type = OPENCONTAINER - face_while_pulling = FALSE - var/obj/item/mop/stored_mop = null - var/maximum_volume = 150 - var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite - -/obj/structure/mopbucket/Initialize(mapload) - . = ..() - create_reagents(150) - GLOB.janitorial_equipment += src - -/obj/structure/mopbucket/full/Initialize(mapload) - . = ..() - reagents.add_reagent("water", 150) - -/obj/structure/mopbucket/Destroy() - GLOB.janitorial_equipment -= src - return ..() - -/obj/structure/mopbucket/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(W.is_robot_module()) - to_chat(user, "You cannot interface your modules with [src]!") - return - - if(istype(W, /obj/item/mop)) - var/obj/item/mop/attacking_mop = W - if(attacking_mop.reagents.total_volume < attacking_mop.reagents.maximum_volume) - attacking_mop.wet_mop(src, user) - return - - if(!user.drop_item_to_ground(attacking_mop)) - to_chat(user, "[attacking_mop] is stuck to your hand!") - return - - if(!stored_mop) - mopbucket_insert(user, attacking_mop) - return - - to_chat(user, "There is already a mop in the mopbucket.") - -/obj/structure/mopbucket/proc/mopbucket_insert(mob/user, obj/item/mop/I) - stored_mop = I - I.forceMove(src) - to_chat(user, "You put [I] into [src].") - update_icon(UPDATE_OVERLAYS) - return - -/obj/structure/mopbucket/on_reagent_change() - update_icon(UPDATE_OVERLAYS) - -/obj/structure/mopbucket/update_overlays() - . = ..() - if(stored_mop) - . += "mopbucket_mop" - if(reagents.total_volume > 0) - var/image/reagentsImage = image(icon, src, "mopbucket_reagents0") - reagentsImage.alpha = 150 - switch((reagents.total_volume / maximum_volume) * 100) - if(1 to 37) - reagentsImage.icon_state = "mopbucket_reagents1" - if(38 to 75) - reagentsImage.icon_state = "mopbucket_reagents2" - if(76 to 112) - reagentsImage.icon_state = "mopbucket_reagents3" - if(113 to 150) - reagentsImage.icon_state = "mopbucket_reagents4" - reagentsImage.icon += mix_color_from_reagents(reagents.reagent_list) - . += reagentsImage - -/obj/structure/mopbucket/attack_hand(mob/living/user) - . = ..() - if(stored_mop) - user.put_in_hands(stored_mop) - to_chat(user, "You take [stored_mop] from [src].") - stored_mop = null - update_icon(UPDATE_OVERLAYS) - return - diff --git a/code/game/objects/structures/nest.dm b/code/game/objects/structures/nest.dm deleted file mode 100644 index a85aaf417d65a..0000000000000 --- a/code/game/objects/structures/nest.dm +++ /dev/null @@ -1,79 +0,0 @@ -// Nests spawn mobs and objects when crossed by players. - -// Once a nest is triggered, it picks a mob from 'spawn_mob_options', then -// looks around in 'spawn_trigger_distance' distance and activates all nests -// in that area. After a few seconds, the selected mob spawns from every -// triggered nest, alongside with some items dictated by 'spawn_byproduct'. -// Once spawned, the nests become inactive by the 'spawn_is_triggered' variable -// becoming TRUE. - -/obj/structure/nest - name = "tunnel" - desc = "A twisted, dark passage to the underground." - icon = 'icons/mob/nest.dmi' - icon_state = "hole" - - move_resist = INFINITY - anchored = TRUE - density = FALSE - - var/faction = list("hostile") // If you spawn auto-attacking mobs, make sure that their faction and the nest's is the same - var/spawn_byproduct = list(/obj/item/stack/ore/glass, /obj/item/stack/ore/iron) // When mobs spawn, these items also spawn on top of the tunnel - var/spawn_byproduct_max = 3 // Maximum number of item spawns - var/spawn_is_triggered = FALSE // This is set to TRUE once the nest is triggered, preventing multiple triggers; set it to FALSE to re-activate it - var/spawn_max = 2 // Maximum number of mob spawns - var/spawn_mob_options = list(/mob/living/simple_animal/crab) // The nest picks one mob type of this list and spawns them - var/spawn_trigger_distance = 7 // The triggered nest will look this many tiles around itself to find other triggerable nests - -/obj/structure/nest/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/structure/nest/examine(mob/user) - . = ..() - if(!spawn_is_triggered) - . += "You can hear a cacophony of growling snores from within." - -/obj/structure/nest/attack_animal(mob/living/simple_animal/M) - if(faction_check(faction, M.faction, FALSE) && !M.client) - return - ..() - -/obj/structure/nest/proc/on_atom_entered(datum/source, atom/movable/entered) - SIGNAL_HANDLER // COMSIG_ATOM_ENTERED - if(spawn_is_triggered) - return - if(!isliving(entered)) - return - var/mob/living/L = entered - if(!L.mind) - return - - try_spawn(L) - -/obj/structure/nest/proc/try_spawn(mob/living/L) - var/chosen_mob = pick(spawn_mob_options) - - to_chat(L, "As you stumble across \the [name], you can hear ominous rumbling from beneath your feet!") - playsound(src, 'sound/effects/break_stone.ogg', 50, 1) - for(var/obj/structure/nest/N in range(spawn_trigger_distance, src)) - N.spawn_is_triggered = TRUE - addtimer(CALLBACK(N, TYPE_PROC_REF(/obj/structure/nest, spawn_mob), chosen_mob), rand(2, 5) SECONDS) - -/obj/structure/nest/proc/spawn_mob(mob/M) - var/byproduct = pick(spawn_byproduct) - new byproduct(get_turf(src), rand(1, spawn_byproduct_max)) - - for(var/i in 1 to spawn_max) - var/mob/spawned_mob = new M(get_turf(src)) - visible_message("\A [spawned_mob.name] crawls out of \the [name]!") - -/obj/structure/nest/lavaland - spawn_mob_options = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast, /mob/living/simple_animal/hostile/asteroid/goldgrub) - -/obj/structure/nest/carppuppy - spawn_mob_options = list(/mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/pet/dog/corgi/puppy/void) - spawn_trigger_distance = 3 diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm deleted file mode 100644 index 3100a070ebff0..0000000000000 --- a/code/game/objects/structures/noticeboard.dm +++ /dev/null @@ -1,143 +0,0 @@ -#define MAX_NOTICES 5 - -/obj/item/mounted/noticeboard - name = "notice board" - desc = "A board for pinning important notices upon." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "noticeboard" - w_class = WEIGHT_CLASS_BULKY - -/obj/item/mounted/noticeboard/do_build(turf/on_wall, mob/user) - new /obj/structure/noticeboard(get_turf(user), get_dir(on_wall, user), TRUE) - qdel(src) - -/obj/structure/noticeboard - name = "notice board" - desc = "A board for pinning important notices upon." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "noticeboard-5" - density = FALSE - anchored = TRUE - max_integrity = 150 - var/notices = 0 - -/obj/structure/noticeboard/Initialize(mapload, direction, building = FALSE) - . = ..() - - if(building) - setDir(direction) - set_pixel_offsets_from_dir(-32, 32, -30, 30) - update_icon(UPDATE_ICON_STATE) - - for(var/obj/item/paper in loc) - if(notices >= MAX_NOTICES) - break - if(istype(paper, /obj/item/paper)) - paper.loc = src - notices++ - - update_icon(UPDATE_ICON_STATE) - -/obj/structure/noticeboard/update_icon_state() - if(notices) - icon_state = "noticeboard-[notices]" - return - icon_state = "noticeboard" - -/obj/structure/noticeboard/attack_hand(mob/user) - ui_interact(user) - -/obj/structure/noticeboard/attack_ghost(mob/user) - ui_interact(user) - -/obj/structure/noticeboard/ui_state(mob/user) - return GLOB.default_state - -/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.set_autoupdate(FALSE) - ui.open() - -/obj/structure/noticeboard/ui_data(mob/user) - var/list/data = list() - - var/list/pinned_papers = list() - for(var/obj/item/paper/paper in src) - pinned_papers += list(list( - "name" = paper.name, - "contents" = paper.info, - "ref" = paper.UID(), - )) - data["papers"] = pinned_papers - - return data - -/obj/structure/noticeboard/ui_act(action, params, datum/tgui/ui) - if(..()) - return - . = TRUE - - add_fingerprint(usr) - switch(action) - if("interact") - if(usr.stat || usr.restrained()) - return - var/obj/item/paper/paper = locate(params["paper"]) - if(!istype(paper) || paper.loc != src) - return - var/obj/item/held_item = usr.get_active_hand() - if(is_pen(held_item)) - paper.attackby__legacy__attackchain(held_item, usr) - return - else - usr.put_in_hands(paper) - paper.add_fingerprint(usr) - notices-- - to_chat(usr, "You take a [paper.name] out of [src].") - update_icon(UPDATE_ICON_STATE) - if("showFull") - var/obj/item/paper/paper = locate(params["paper"]) - if(!paper && paper.loc != src) - return - paper.show_content(usr) - return - -/obj/structure/noticeboard/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/paper)) - if(notices >= MAX_NOTICES) - to_chat(user, "You reach to pin your paper to the board but hesitate. You are certain your paper will not be seen among the many others already attached.") - return - if(!user.drop_item()) - return - I.forceMove(src) - notices++ - to_chat(user, "You pin the paper to the noticeboard.") - update_icon(UPDATE_ICON_STATE) - add_fingerprint(user) - SStgui.update_uis(src) - return - - return ..() - -/obj/structure/noticeboard/wrench_act(mob/living/user, obj/item/I) - if(user.a_intent != INTENT_HELP) - return - . = TRUE - if(!(flags & NODECONSTRUCT)) - WRENCH_UNANCHOR_WALL_MESSAGE - I.play_tool_sound(user, I.tool_volume) - deconstruct(TRUE) - -/obj/structure/noticeboard/deconstruct(disassembled = TRUE) - if(flags & NODECONSTRUCT) - return - if(notices) - for(var/I in contents) - var/obj/item/paper/notice = I - notice.forceMove(loc) - new /obj/item/mounted/noticeboard(loc) - qdel(src) - -#undef MAX_NOTICES diff --git a/code/game/objects/structures/plasmafire_generator.dm b/code/game/objects/structures/plasmafire_generator.dm deleted file mode 100644 index 288eb567443e5..0000000000000 --- a/code/game/objects/structures/plasmafire_generator.dm +++ /dev/null @@ -1,41 +0,0 @@ -/obj/structure/plasmafire_generator - name = "Plasmafire Generator" - desc = "A magical thing that you really shouldn't be able to see." - anchored = TRUE - alpha = 0 - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - resistance_flags = LAVA_PROOF | FIRE_PROOF - flags = NODECONSTRUCT - -/obj/structure/plasmafire_generator/Initialize(mapload) - . = ..() - START_PROCESSING(SSprocessing, src) - -// for sanity checks -/obj/structure/plasmafire_generator/Destroy() - STOP_PROCESSING(SSprocessing, src) - return ..() - -/obj/structure/plasmafire_generator/process() - var/turf/T = get_turf(src) - if(!istype(T)) - return - - var/datum/gas_mixture/fire = new() - fire.set_toxins(10) - fire.set_oxygen(4) - fire.set_temperature(500) - T.blind_release_air(fire) - -/obj/structure/plasmafire_generator/shadow - var/enabled = FALSE - -/obj/structure/plasmafire_generator/shadow/onShuttleMove(turf/oldT, turf/T1, rotation, mob/caller) - if(T1.z != 1) - enabled = TRUE - return ..() - -/obj/structure/plasmafire_generator/shadow/process() - if(!enabled) - return - return ..() diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm deleted file mode 100644 index 5c229ce50d6f0..0000000000000 --- a/code/game/objects/structures/railings.dm +++ /dev/null @@ -1,212 +0,0 @@ -/obj/structure/railing - name = "railing" - desc = "Basic railing meant to protect idiots like you from falling." - icon = 'icons/obj/fence.dmi' - icon_state = "railing" - density = TRUE - anchored = TRUE - pass_flags_self = LETPASSTHROW | PASSTAKE - climbable = TRUE - layer = ABOVE_MOB_LAYER - flags = ON_BORDER - var/currently_climbed = FALSE - var/mover_dir = null - -/obj/structure/railing/Initialize(mapload) - . = ..() - if(density && flags & ON_BORDER) // blocks normal movement from and to the direction it's facing. - var/static/list/loc_connections = list( - COMSIG_ATOM_EXIT = PROC_REF(on_atom_exit), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/structure/railing/get_climb_text() - return "You can Click-Drag yourself to [src] to climb over it after a short delay." - -/// aesthetic corner sharp edges hurt oof ouch -/obj/structure/railing/corner - icon_state = "railing_corner" - density = FALSE - climbable = FALSE - -/// aestetic "end" for railing -/obj/structure/railing/cap - icon_state = "railing_cap" - density = FALSE - climbable = FALSE - -/obj/structure/railing/cap/normal - icon_state = "railing_cap_normal" - -/obj/structure/railing/cap/reversed - icon_state = "railing_cap_reversed" - -/obj/structure/railing/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) - ..() - add_fingerprint(user) - -/obj/structure/railing/attack_animal(mob/living/simple_animal/M) - . = ..() - if(. && M.environment_smash >= ENVIRONMENT_SMASH_WALLS) - deconstruct(FALSE) - M.visible_message("[M] tears apart [src]!", "You tear apart [src]!") - - -/obj/structure/railing/welder_act(mob/living/user, obj/item/I) - if(user.intent != INTENT_HELP) - return - if(obj_integrity >= max_integrity) - to_chat(user, "[src] is already in good condition!") - return - if(!I.tool_start_check(user, amount = 0)) - return - to_chat(user, "You begin repairing [src]...") - if(I.use_tool(src, user, 4 SECONDS, I.tool_volume)) - obj_integrity = max_integrity - to_chat(user, "You repair [src].") - -/obj/structure/railing/wirecutter_act(mob/living/user, obj/item/I) - if(anchored) - return - to_chat(user, "You cut apart the railing.") - I.play_tool_sound(src, 100) - deconstruct() - return TRUE - -/obj/structure/railing/deconstruct(disassembled) - if(!(flags & NODECONSTRUCT)) - var/obj/item/stack/rods/rod = new /obj/item/stack/rods(drop_location(), 3) - transfer_fingerprints_to(rod) - return ..() - -///Implements behaviour that makes it possible to unanchor the railing. -/obj/structure/railing/wrench_act(mob/living/user, obj/item/I) - if(flags & NODECONSTRUCT) - return - to_chat(user, "You begin to [anchored ? "unfasten the railing from":"fasten the railing to"] the floor...") - if(I.use_tool(src, user, volume = 75, extra_checks = CALLBACK(src, PROC_REF(check_anchored), anchored))) - anchored = !anchored - to_chat(user, "You [anchored ? "fasten the railing to":"unfasten the railing from"] the floor.") - return TRUE - -/obj/structure/railing/corner/CanPass() - return TRUE - -/obj/structure/railing/corner/CanPathfindPass(to_dir, datum/can_pass_info/pass_info) - return TRUE - -/obj/structure/railing/corner/on_atom_exit(datum/source, atom/movable/leaving, direction) - return - -/obj/structure/railing/cap/CanPass() - return TRUE - -/obj/structure/railing/cap/CanPathfindPass(to_dir, datum/can_pass_info/pass_info) - return TRUE - -/obj/structure/railing/cap/on_atom_exit(datum/source, atom/movable/leaving, direction) - return - -/obj/structure/railing/CanPass(atom/movable/mover, border_dir) - if(istype(mover) && mover.checkpass(PASSFENCE)) - return TRUE - if(isprojectile(mover)) - return TRUE - if(ismob(mover)) - var/mob/living/M = mover - if(HAS_TRAIT(M, TRAIT_FLYING) || (istype(M) && IS_HORIZONTAL(M) && HAS_TRAIT(M, TRAIT_CONTORTED_BODY))) - return TRUE - if(mover.throwing) - return TRUE - //Due to how the other check is done, it would always return density for ordinal directions no matter what - if(ordinal_direction_check(border_dir)) - return FALSE - if(border_dir != dir) - return density - return FALSE - -/obj/structure/railing/CanPathfindPass(to_dir, datum/can_pass_info/pass_info) - if(to_dir == dir) - return FALSE - if(ordinal_direction_check(to_dir)) - return FALSE - - return TRUE - -/obj/structure/railing/proc/on_atom_exit(datum/source, atom/movable/leaving, direction) - SIGNAL_HANDLER // COMSIG_ATOM_EXIT - - var/mob/living/M = leaving - if(istype(leaving) && leaving.checkpass(PASSFENCE)) - return - if(isprojectile(leaving)) - return - if(istype(M)) - if(HAS_TRAIT(M, TRAIT_FLYING) || M.floating || (IS_HORIZONTAL(M) && HAS_TRAIT(M, TRAIT_CONTORTED_BODY))) - return - if(leaving.throwing) - return - if(leaving.move_force >= MOVE_FORCE_EXTREMELY_STRONG) - return - if(currently_climbed) - return - if(direction == dir) - return COMPONENT_ATOM_BLOCK_EXIT - if(ordinal_direction_check(direction)) - return COMPONENT_ATOM_BLOCK_EXIT - -// Checks if the direction the mob is trying to move towards would be blocked by a corner railing -/obj/structure/railing/proc/ordinal_direction_check(check_dir) - switch(dir) - if(NORTHEAST) - if(check_dir == NORTH || check_dir == EAST) - return TRUE - if(SOUTHEAST) - if(check_dir == SOUTH || check_dir == EAST) - return TRUE - if(NORTHWEST) - if(check_dir == NORTH || check_dir == WEST) - return TRUE - if(SOUTHWEST) - if(check_dir == SOUTH || check_dir == WEST) - return TRUE - return FALSE - -/obj/structure/railing/start_climb(mob/living/user) - var/initial_mob_loc = get_turf(user) - . = ..() - if(.) - currently_climbed = TRUE - if(initial_mob_loc != get_turf(src)) // If we are on the railing, we want to move in the same dir as the railing. Otherwise we get put on the railing - currently_climbed = FALSE - return - user.Move(get_step(user, dir), TRUE) - currently_climbed = FALSE - -/obj/structure/railing/proc/can_be_rotated(mob/user) - if(anchored) - to_chat(user, "[src] cannot be rotated while it is fastened to the floor!") - return FALSE - - var/target_dir = turn(dir, -45) - - if(!valid_window_location(loc, target_dir)) //Expanded to include rails, as well! - to_chat(user, "[src] cannot be rotated in that direction!") - return FALSE - return TRUE - -/obj/structure/railing/proc/check_anchored(checked_anchored) - if(anchored == checked_anchored) - return TRUE - -/obj/structure/railing/proc/after_rotation(mob/user) - add_fingerprint(user) - -/obj/structure/railing/AltClick(mob/user) - if(user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!Adjacent(user)) - return - if(can_be_rotated(user)) - setDir(turn(dir, 45)) diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm deleted file mode 100644 index 80d4e69828234..0000000000000 --- a/code/game/objects/structures/reflector.dm +++ /dev/null @@ -1,179 +0,0 @@ -/obj/structure/reflector - name = "reflector frame" - icon = 'icons/obj/stock_parts.dmi' - icon_state = "box_0" - desc = "A frame to create a reflector.\nUse 5 sheets of glass to create a 1 way reflector.\nUse 10 sheets of reinforced glass to create a 2 way reflector.\nUse 1 diamond to create a reflector cube." - anchored = FALSE - density = TRUE - max_integrity = 50 - layer = 3 - var/finished = FALSE - var/obj/item/stack/sheet/build_stack_type - var/build_stack_amount - -/obj/structure/reflector/Initialize(mapload) - . = ..() - if(mapload) - anchored = TRUE - -/obj/structure/reflector/bullet_act(obj/item/projectile/P) - var/turf/reflector_turf = get_turf(src) - var/turf/reflect_turf - if(!istype(P, /obj/item/projectile/beam)) - return ..() - var/new_dir = get_reflection(dir, P.dir) - if(new_dir && anchored) - reflect_turf = get_step(reflect_turf, new_dir) - else - visible_message("[src] is hit by [P]!") - new_dir = 0 - return ..() //Hits as normal, explodes or emps or whatever - - reflect_turf = get_step(loc, new_dir) - - P.original = reflect_turf - P.starting = reflector_turf - P.ignore_source_check = TRUE //If shot by a laser, will now hit the mob that fired it - var/reflect_angle = dir2angle(new_dir) - P.set_angle_centered(reflect_angle) - P.trajectory.set_location(reflect_turf.x, reflect_turf.y, reflect_turf.z) - - new_dir = 0 - return -1 - - -/obj/structure/reflector/attackby__legacy__attackchain(obj/item/W, mob/user, params) - //Finishing the frame - if(istype(W,/obj/item/stack/sheet)) - if(finished) - return - var/obj/item/stack/sheet/S = W - if(istype(W, /obj/item/stack/sheet/glass)) - if(S.get_amount() < 5) - to_chat(user, "You need five sheets of glass to create a reflector!") - return - else - S.use(5) - new /obj/structure/reflector/single(loc) - qdel(src) - if(istype(W,/obj/item/stack/sheet/rglass)) - if(S.get_amount() < 10) - to_chat(user, "You need ten sheets of reinforced glass to create a double reflector!") - return - else - S.use(10) - new /obj/structure/reflector/double(loc) - qdel(src) - if(istype(W, /obj/item/stack/sheet/mineral/diamond)) - if(S.get_amount() >= 1) - S.use(1) - new /obj/structure/reflector/box(loc) - qdel(src) - return - return ..() - -/obj/structure/reflector/wrench_act(mob/user, obj/item/I) - . = TRUE - if(anchored) - to_chat(user, "Unweld [src] first!") - return - if(!I.tool_use_check(user, 0)) - return - TOOL_ATTEMPT_DISMANTLE_MESSAGE - if(!I.use_tool(src, user, 80, volume = I.tool_volume)) - return - playsound(user, 'sound/items/Ratchet.ogg', 50, 1) - TOOL_DISMANTLE_SUCCESS_MESSAGE - new /obj/item/stack/sheet/metal(loc, 5) - if(build_stack_type) - new build_stack_type(loc, build_stack_amount) - qdel(src) - -/obj/structure/reflector/welder_act(mob/user, obj/item/I) - . = TRUE - if(!I.tool_use_check(user, 0)) - return - if(anchored) - WELDER_ATTEMPT_FLOOR_SLICE_MESSAGE - if(!I.use_tool(src, user, 5 SECONDS, volume = I.tool_volume)) - return - WELDER_FLOOR_SLICE_SUCCESS_MESSAGE - anchored = FALSE - else - WELDER_ATTEMPT_FLOOR_WELD_MESSAGE - if(!I.use_tool(src, user, 5 SECONDS, volume = I.tool_volume)) - return - WELDER_FLOOR_WELD_SUCCESS_MESSAGE - anchored = TRUE - -/obj/structure/reflector/proc/get_reflection(srcdir,pdir) - return 0 - -/obj/structure/reflector/AltClick(mob/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) - return - - if(anchored) - to_chat(user, "You cannot rotate [src] right now. It is fastened to the floor!") - return - dir = turn(dir, 90) - - -//TYPES OF REFLECTORS, SINGLE, DOUBLE, BOX - -//SINGLE - -/obj/structure/reflector/single - name = "reflector" - icon = 'icons/obj/reflector.dmi' - icon_state = "reflector" - desc = "A double sided angled mirror for reflecting lasers. This one does so at a 90 degree angle." - finished = TRUE - build_stack_type = /obj/item/stack/sheet/glass - build_stack_amount = 5 - var/static/list/rotations = list("[NORTH]" = list("[SOUTH]" = WEST, "[EAST]" = NORTH), -"[EAST]" = list("[SOUTH]" = EAST, "[WEST]" = NORTH), -"[SOUTH]" = list("[NORTH]" = EAST, "[WEST]" = SOUTH), -"[WEST]" = list("[NORTH]" = WEST, "[EAST]" = SOUTH) ) - -/obj/structure/reflector/single/get_reflection(srcdir,pdir) - var/new_dir = rotations["[srcdir]"]["[pdir]"] - return new_dir - -//DOUBLE - -/obj/structure/reflector/double - name = "double sided reflector" - icon = 'icons/obj/reflector.dmi' - icon_state = "reflector_double" - desc = "A double sided angled mirror for reflecting lasers. This one does so at a 90 degree angle." - finished = TRUE - build_stack_type = /obj/item/stack/sheet/rglass - build_stack_amount = 10 - var/static/list/double_rotations = list("[NORTH]" = list("[NORTH]" = WEST, "[EAST]" = SOUTH, "[SOUTH]" = EAST, "[WEST]" = NORTH), -"[EAST]" = list("[NORTH]" = EAST, "[WEST]" = SOUTH, "[SOUTH]" = WEST, "[EAST]" = NORTH), -"[SOUTH]" = list("[NORTH]" = EAST, "[WEST]" = SOUTH, "[SOUTH]" = WEST, "[EAST]" = NORTH), -"[WEST]" = list("[NORTH]" = WEST, "[EAST]" = SOUTH, "[SOUTH]" = EAST, "[WEST]" = NORTH) ) - -/obj/structure/reflector/double/get_reflection(srcdir,pdir) - var/new_dir = double_rotations["[srcdir]"]["[pdir]"] - return new_dir - -//BOX - -/obj/structure/reflector/box - name = "reflector box" - icon = 'icons/obj/reflector.dmi' - icon_state = "reflector_box" - desc = "A box with an internal set of mirrors that reflects all laser fire in a single direction." - finished = TRUE - build_stack_type = /obj/item/stack/sheet/mineral/diamond - build_stack_amount = 1 - var/static/list/box_rotations = list("[NORTH]" = list("[SOUTH]" = NORTH, "[EAST]" = NORTH, "[WEST]" = NORTH, "[NORTH]" = NORTH), -"[EAST]" = list("[SOUTH]" = EAST, "[EAST]" = EAST, "[WEST]" = EAST, "[NORTH]" = EAST), -"[SOUTH]" = list("[SOUTH]" = SOUTH, "[EAST]" = SOUTH, "[WEST]" = SOUTH, "[NORTH]" = SOUTH), -"[WEST]" = list("[SOUTH]" = WEST, "[EAST]" = WEST, "[WEST]" = WEST, "[NORTH]" = WEST) ) - -/obj/structure/reflector/box/get_reflection(srcdir,pdir) - var/new_dir = box_rotations["[srcdir]"]["[pdir]"] - return new_dir diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm deleted file mode 100644 index 38a9aa0796a59..0000000000000 --- a/code/game/objects/structures/safe.dm +++ /dev/null @@ -1,485 +0,0 @@ -/* -CONTAINS: -SAFES -FLOOR SAFES -SAFE INTERNALS -SAFE CODES -*/ - -#define DRILL_SPARK_CHANCE 15 -#define DRILL_TIME 120 SECONDS -#define SOUND_CHANCE 10 - -GLOBAL_LIST_EMPTY(safes) - -/** - * # Safe - * - * A locked container that can only be opened by entering a combination through a dial. - */ -/obj/structure/safe - name = "safe" - desc = "A huge chunk of metal with a dial embedded in it. Fine print on the dial reads \"Scarborough Arms tumbler safe, guaranteed thermite resistant, explosion resistant, and assistant resistant.\"" - icon = 'icons/obj/structures.dmi' - icon_state = "safe" - anchored = TRUE - density = TRUE - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - // Settings - /// The maximum combined w_class of stuff in the safe. - var/maxspace = 24 - /// The amount of tumblers that will be generated. - var/number_of_tumblers = 3 - // Variables - /// Whether the safe is open or not. - var/open = FALSE - /// Whether the safe is locked or not. - var/locked = TRUE - /// The position the dial is pointing to. - var/dial = 0 - /// The list of tumbler dial positions that need to be hit. - var/list/tumblers = list() - /// The index in the tumblers list of the tumbler dial position that needs to be hit. - var/current_tumbler_index = 1 - /// The combined w_class of everything in the safe. - var/space = 0 - // Variables (Drill) - /// The currently placed thermal drill, if any. - var/obj/item/thermal_drill/drill = null - /// The [/proc/addtimer] handle for the current thermal drill. - var/drill_timer - /// Drill duration of the current thermal drill. - var/time_to_drill - /// The world.time at which drilling started. - var/drill_start_time - /// The drill overlay image to display during the drilling process. - var/image/drill_overlay - /// The progress bar image to display during the drilling process. - var/image/progress_bar - /// The X pixel offset for the drilling progress bar. - var/drill_x_offset = -13 - /// The Y pixel offset for the drilling progress bar. - var/drill_y_offset = -3 - /// Used by [/obj/item/paper/safe_code] to tell the codes through a paper spawned on map load. - var/known_by = list() - /// Who placed the drill on the safe. Used to trigger the status effect - var/mob/living/carbon/human/driller - -/obj/structure/safe/Initialize(mapload) - . = ..() - GLOB.safes += src - // Combination generation - for(var/i in 1 to number_of_tumblers) - tumblers.Add(rand(0, 99)) - if(mapload) - addtimer(CALLBACK(src, PROC_REF(take_contents)), 0) - -/obj/structure/safe/proc/take_contents() - // Put as many items on our turf inside as possible - for(var/obj/item/I in loc) - if(I.density || I.anchored) - continue - if(space >= maxspace) - break - if(I.w_class + space <= maxspace) - space += I.w_class - I.forceMove(src) - -/obj/structure/safe/Destroy() - GLOB.safes -= src - if(drill) - drill.soundloop.stop() - drill.forceMove(loc) - drill = null - driller = null - QDEL_NULL(progress_bar) - QDEL_NULL(drill_overlay) - clear_payback() //Lets not leave the overlay if an admin deletes the safe during the event - return ..() - -/obj/structure/safe/process() - if(!drill_timer) - return - cut_overlay(progress_bar) - progress_bar = image('icons/effects/progessbar.dmi', src, "prog_bar_[round((((world.time - drill_start_time) / time_to_drill) * 100), 5)]", HUD_LAYER) - add_overlay(progress_bar) - if(prob(DRILL_SPARK_CHANCE)) - drill.spark_system.start() - if(!drill.spotted && drill.payback) - security_check() - -/obj/structure/safe/examine(mob/user) - . = ..() - . += "This model appears to have [number_of_tumblers] tumblers." - if(open) - . += "The inside of the the door has numbers written on it: [get_combination()]" - -/obj/structure/safe/blob_act(obj/structure/blob/B) - return - -/obj/structure/safe/ex_act(severity) - return - -/obj/structure/safe/examine_status(mob/user) - return - -/obj/structure/safe/update_icon_state() - if(open) - if(broken) - icon_state = "[initial(icon_state)]-open-broken" - else - icon_state = "[initial(icon_state)]-open" - else - if(broken) - icon_state = "[initial(icon_state)]-broken" - else - icon_state = initial(icon_state) - -/obj/structure/safe/update_overlays() - . = ..() - if(istype(drill, /obj/item/thermal_drill)) - var/drill_icon = istype(drill, /obj/item/thermal_drill/diamond_drill) ? "d" : "h" - var/state = "[initial(icon_state)]_[drill_icon]-drill-[drill_timer ? "on" : "off"]" - drill_overlay = image(icon = 'icons/effects/drill.dmi', icon_state = state, pixel_x = drill_x_offset, pixel_y = drill_y_offset) - . += drill_overlay - -/obj/structure/safe/attack_ghost(mob/user) - if(..() || drill) - return TRUE - ui_interact(user) - -/obj/structure/safe/attack_hand(mob/user) - if(..()) - return TRUE - - if(drill && !broken) - switch(tgui_alert(user, "What would you like to do?", "Thermal Drill", list("Turn [drill_timer ? "Off" : "On"]", "Remove Drill", "Cancel"))) - if("Turn On") - if(do_after(user, 2 SECONDS, target = src)) - drill_timer = addtimer(CALLBACK(src, PROC_REF(drill_open)), time_to_drill, TIMER_STOPPABLE) - drill_start_time = world.time - drill.soundloop.start() - update_icon() - driller = user - START_PROCESSING(SSobj, src) - if("Turn Off") - if(do_after(user, 10 SECONDS, target = src)) //Can't be too easy to turn off - deltimer(drill_timer) - drill_timer = null - drill.soundloop.stop() - cut_overlay(progress_bar) - update_icon() - driller.remove_status_effect(STATUS_EFFECT_DRILL_PAYBACK) - driller = null - STOP_PROCESSING(SSobj, src) - if("Remove Drill") - if(drill_timer) - to_chat(user, "You cannot remove the drill while it's running!") - else if(do_after(user, 2 SECONDS, target = src)) - user.put_in_hands(drill) - drill = null - update_icon() - if("Cancel") - return - else if(drill && broken) - user.put_in_hands(drill) - drill = null - update_icon() - else - ui_interact(user) - -/obj/structure/safe/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(open) - if(I.flags && ABSTRACT) - return - if(broken && istype(I, /obj/item/safe_internals) && do_after(user, 2 SECONDS, target = src)) - to_chat(user, "You replace the broken mechanism.") - qdel(I) - broken = FALSE - locked = FALSE - update_icon() - else if(I.w_class + space <= maxspace) - if(!user.drop_item()) - to_chat(user, "\The [I] is stuck to your hand, you cannot put it in the safe!") - return - space += I.w_class - I.forceMove(src) - to_chat(user, "You put [I] in [src].") - SStgui.update_uis(src) - else - to_chat(user, "[I] won't fit in [src].") - else - if(istype(I, /obj/item/clothing/neck/stethoscope)) - attack_hand(user) - return - else if(istype(I, /obj/item/thermal_drill)) - if(drill) - to_chat(user, "There is already a drill attached!") - else if(do_after(user, 2 SECONDS, target = src)) - if(!user.drop_item()) - to_chat(user, "[I] is stuck to your hand, you cannot put it in the safe!") - return - I.forceMove(src) - drill = I - time_to_drill = DRILL_TIME * drill.time_multiplier - update_icon() - else - to_chat(user, "You can't put [I] into the safe while it is closed!") - return - -/obj/structure/safe/ui_state(mob/user) - return GLOB.physical_state - -/obj/structure/safe/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "Safe", name) - ui.open() - ui.set_autoupdate(FALSE) - -/obj/structure/safe/ui_assets(mob/user) - return list( - get_asset_datum(/datum/asset/simple/safe) - ) - -/obj/structure/safe/ui_data(mob/user) - var/list/data = list() - data["dial"] = dial - data["open"] = open - data["locked"] = locked && !broken - - if(open) - var/list/contents_names = list() - data["contents"] = contents_names - for(var/obj/O in contents) - contents_names[++contents_names.len] = list("name" = O.name, "sprite" = O.icon_state) - user << browse_rsc(icon(O.icon, O.icon_state), "[O.icon_state].png") - - return data - -/obj/structure/safe/ui_act(action, params) - if(..()) - return - - if(!usr.IsAdvancedToolUser() && !isobserver(usr)) - to_chat(usr, "You are not able to operate the safe.") - return - - var/canhear = FALSE - if(ishuman(usr)) - var/mob/living/carbon/human/H = usr - if(H.can_hear()) // This is cursed but is_type_in_list somehow fails - if(H.is_in_hands(/obj/item/clothing/neck/stethoscope)) - canhear = TRUE - if(istype(H.neck, /obj/item/clothing/neck/stethoscope)) - canhear = TRUE - - . = TRUE - switch(action) - if("open") - if(check_unlocked() || open || broken) - to_chat(usr, "You [open ? "close" : "open"] [src].") - open = !open - update_icon() - else - to_chat(usr, "You cannot open [src], as its lock is engaged!") - if("turnright") - if(open) - return - if(broken) - to_chat(usr, "The dial will not turn, as the mechanism is destroyed!") - return - var/ticks = text2num(params["num"]) - for(var/i = 1 to ticks) - dial = WRAP(dial - 1, 0, 100) - - var/invalid_turn = current_tumbler_index % 2 == 0 || current_tumbler_index > number_of_tumblers - if(invalid_turn) // The moment you turn the wrong way or go too far, the tumblers reset - current_tumbler_index = 1 - - if(!invalid_turn && dial == tumblers[current_tumbler_index]) - notify_user(usr, canhear, list("tink", "krink", "plink"), ticks, i, TRUE) - current_tumbler_index++ - else - notify_user(usr, canhear, list("clack", "scrape", "clank"), ticks, i) - check_unlocked() - if("turnleft") - if(open) - return - if(broken) - to_chat(usr, "The dial will not turn, as the mechanism is destroyed!") - return - var/ticks = text2num(params["num"]) - for(var/i = 1 to ticks) - dial = WRAP(dial + 1, 0, 100) - - var/invalid_turn = current_tumbler_index % 2 != 0 || current_tumbler_index > number_of_tumblers - if(invalid_turn) // The moment you turn the wrong way or go too far, the tumblers reset - current_tumbler_index = 1 - - if(!invalid_turn && dial == tumblers[current_tumbler_index]) - notify_user(usr, canhear, list("tonk", "krunk", "plunk"), ticks, i, TRUE) - current_tumbler_index++ - else - notify_user(usr, canhear, list("click", "chink", "clink"), ticks, i) - check_unlocked() - if("retrieve") - if(!open) - return - var/index = text2num(params["index"]) - if(!ISINDEXSAFE(contents, index)) - return - var/obj/item/I = contents[index] - if(I && in_range(src, usr)) - usr.put_in_hands(I) - space -= I.w_class - else - return FALSE - - add_fingerprint(usr) - -/obj/structure/safe/proc/security_check() - if(get_dist(src, driller) >= 9) - return //You need to be near the drill if you want to get the buff. - for(var/mob/living/carbon/human/H in view(9, src)) - if((H.job in list("Security Officer", "Detective", "Warden", "Head of Security", "Captain", "Clown")) || H.mind.special_role == SPECIAL_ROLE_ERT) - if(H.mind && H.mind.special_role && H.mind.special_role != SPECIAL_ROLE_ERT) - continue - drill.spotted = TRUE - security_assualt_in_progress() - return - for(var/mob/living/carbon/human/H in view(9, driller)) - if((H.job in list("Security Officer", "Detective", "Warden", "Head of Security", "Captain", "Clown")) || H.mind.special_role == SPECIAL_ROLE_ERT) - if(H.mind && H.mind.special_role && H.mind.special_role != SPECIAL_ROLE_ERT) - continue - drill.spotted = TRUE - security_assualt_in_progress() - return - -/obj/structure/safe/proc/security_assualt_in_progress() - drill.atom_say("Security spotted. Nanites deployed. Give them hell.") - driller.apply_status_effect(STATUS_EFFECT_DRILL_PAYBACK, src) - drill.song.start_playing(driller) - notify_ghosts("Security assault in progress in [get_area(src)]!", enter_link="(Click to jump to!)", source = src, action = NOTIFY_FOLLOW) - for(var/mob/dead/observer/O in GLOB.player_list) - O.overlay_fullscreen("payback", /atom/movable/screen/fullscreen/stretch/payback, 0) - addtimer(CALLBACK(src, PROC_REF(ghost_payback_phase_2)), 2.7 SECONDS) - -/obj/structure/safe/proc/ghost_payback_phase_2() - for(var/mob/dead/observer/O in GLOB.player_list) - O.clear_fullscreen("payback") - O.overlay_fullscreen("payback", /atom/movable/screen/fullscreen/stretch/payback, 1) - addtimer(CALLBACK(src, PROC_REF(clear_payback)), 2 MINUTES) - -/obj/structure/safe/proc/clear_payback() - for(var/mob/dead/observer/O in GLOB.player_list) - O.clear_fullscreen("payback") - -/** - * Called every dial turn to determine whether the safe should unlock or not. - */ -/obj/structure/safe/proc/check_unlocked() - if(current_tumbler_index > number_of_tumblers) - locked = FALSE - visible_message("[pick("Spring", "Sprang", "Sproing", "Clunk", "Krunk")]!") - return TRUE - locked = TRUE - return FALSE - -/** - * Called every dial turn to provide feedback if possible. - */ -/obj/structure/safe/proc/notify_user(user, canhear, sounds, total_ticks, current_tick, correct_sound) - if(!canhear) - return - - if(current_tick == 2) - to_chat(user, "The sounds from [src] are too fast and blend together.") - if(total_ticks == 1 || prob(SOUND_CHANCE)) - to_chat(user, "You hear a [pick(sounds)] from [src].") - -/** - * Returns the combination to unlock the safe as text. - */ -/obj/structure/safe/proc/get_combination() - return jointext(tumblers, ", ") - -/** - * Called when the current thermal drill has finished drilling. - */ -/obj/structure/safe/proc/drill_open() - broken = TRUE - drill_timer = null - drill.soundloop.stop() - playsound(loc, 'sound/machines/ding.ogg', 50, 1) - cut_overlay(progress_bar) - update_icon() - if(drill.payback) - var/datum/status_effect/drill_payback/D = driller.has_status_effect(STATUS_EFFECT_DRILL_PAYBACK) - if(D) - D.drilled_successfully = TRUE - addtimer(CALLBACK(driller, TYPE_PROC_REF(/mob/living, remove_status_effect), STATUS_EFFECT_DRILL_PAYBACK), 30 SECONDS) //Give them time to escape - drill.payback = FALSE //Can't be used again / no more adding timers - drill.song.stop_playing() - STOP_PROCESSING(SSobj, src) - -/** - * # Floor Safe - * - * Like a safe, but without density. Can be hidden with flooring. - */ -/obj/structure/safe/floor - name = "floor safe" - icon_state = "floorsafe" - density = FALSE - level = 1 //Under the floor - plane = FLOOR_PLANE - layer = ABOVE_PLATING_LAYER - drill_x_offset = -1 - drill_y_offset = 20 - -/obj/structure/safe/floor/Initialize(mapload) - . = ..() - var/turf/T = loc - if(!T.transparent_floor) - hide(T.intact) - -/obj/structure/safe/floor/hide(intact) - invisibility = intact ? INVISIBILITY_MAXIMUM : 0 - -/** - * # Safe Internals - * - * Can be used to replace a safe's broken mechanism. - */ -/obj/item/safe_internals - name = "safe internals" - desc = "The mechanism and locking bolts for a Scarborough Arms - 2 tumbler safe." - icon_state = "safe_internals" - -/** - * # Safe Codes - * - * Contains the (generated on map load) codes for all publicly known safes. - */ -/obj/item/paper/safe_code - name = "safe codes" - var/owner - info = "

    Safe Codes

    " - -/obj/item/paper/safe_code/Initialize(mapload) - ..() - return INITIALIZE_HINT_LATELOAD - -/obj/item/paper/safe_code/LateInitialize(mapload) - . = ..() - for(var/safe in GLOB.safes) - var/obj/structure/safe/S = safe - if(owner in S.known_by) - info += "
    The combination for the safe located in the [get_area_name(S, TRUE)] is: [S.get_combination()]
    " - info_links = info - update_icon() - -#undef DRILL_SPARK_CHANCE -#undef DRILL_TIME -#undef SOUND_CHANCE diff --git a/code/game/objects/structures/shelves.dm b/code/game/objects/structures/shelves.dm deleted file mode 100644 index c0175375fe89e..0000000000000 --- a/code/game/objects/structures/shelves.dm +++ /dev/null @@ -1,157 +0,0 @@ -GLOBAL_LIST_INIT(shelf_colors, list("basic", "sci", "sup", "serv", "med", "sec", "cmd", "engi")) - -/obj/structure/shelf - name = "shelf" - desc = "A piece of furniture used for vertical storage." - icon = 'icons/obj/structures/shelves.dmi' - icon_state = "shelf_basic" - layer = TABLE_LAYER - density = TRUE - anchored = TRUE - pass_flags_self = PASSTAKE - max_integrity = 80 - /// The suffix of the icon state used for the shelf. Indexed into `GLOB.shelf_colors`. - var/shelf_style = "basic" - /// The current overlay of the top shelf. Used for interleaving objects and shelf layers for the illusion of depth. - var/image/shelf_overlay - var/build_stack_type = /obj/item/stack/sheet/metal - COOLDOWN_DECLARE(spraypaint_cd) - -/obj/structure/shelf/Initialize(mapload) - . = ..() - var/area/A = get_area(src) - AddComponent(/datum/component/shelver/basic_shelf, random_pickup_locations_ = istype(A, /area/station/maintenance)) - update_icon() - set_style(shelf_style) - - if(mapload) - SEND_SIGNAL(src, COMSIG_SHELF_ADDED_ON_MAPLOAD) - -/obj/structure/shelf/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) - var/obj/item/toy/crayon/spraycan/spraycan = I - if(!istype(spraycan)) - return ..() - - if(spraycan.capped) - return ..() - - // Spraypaint cannot turn brass into steel. - if(shelf_style == "clockwork") - return ..() - - if(!COOLDOWN_FINISHED(src, spraypaint_cd)) - to_chat(user, "The paint on [src] is still drying!") - return - - var/cur_idx = GLOB.shelf_colors.Find(shelf_style) - if(!cur_idx) - cur_idx = 1 - cur_idx++ - if(cur_idx > length(GLOB.shelf_colors)) - cur_idx = 1 - set_style(GLOB.shelf_colors[cur_idx]) - spraycan.play_spray_sound(user) - - // Tiny cooldown to prevent constant spamming of the action - COOLDOWN_START(src, spraypaint_cd, 1 SECONDS) - -/obj/structure/shelf/proc/set_style(new_style) - if(shelf_style == new_style && !isnull(shelf_overlay)) - return - shelf_style = new_style - icon_state = "shelf_[shelf_style]" - // Don't think I can get away with both icon smoothing across tiles - // and dealing with this overlay shit - shelf_overlay = mutable_appearance('icons/obj/structures/shelves.dmi', "shelf_[shelf_style]-top") - shelf_overlay.layer = LOW_ITEM_LAYER - update_appearance(UPDATE_OVERLAYS) - -/obj/structure/shelf/update_overlays() - return list(shelf_overlay) - -/obj/structure/shelf/wrench_act(mob/living/user, obj/item/I) - . = TRUE - if(user.a_intent == INTENT_HELP) - return FALSE - if(!I.use_tool(src, user, 2.5 SECONDS, volume = I.tool_volume)) - return - - to_chat(user, "You disassemble [src].") - deconstruct() - -/obj/structure/shelf/deconstruct(disassembled) - new build_stack_type(get_turf(src), 5) - return ..() - -/obj/structure/shelf/engineering - icon_state = "shelf_engi" - shelf_style = "engi" - -/obj/structure/shelf/medbay - icon_state = "shelf_med" - shelf_style = "med" - -/obj/structure/shelf/security - icon_state = "shelf_sec" - shelf_style = "sec" - -/obj/structure/shelf/service - icon_state = "shelf_serv" - shelf_style = "serv" - -/obj/structure/shelf/science - icon_state = "shelf_sci" - shelf_style = "sci" - -/obj/structure/shelf/command - icon_state = "shelf_cmd" - shelf_style = "cmd" - -/obj/structure/shelf/supply - icon_state = "shelf_sup" - shelf_style = "sup" - -/obj/structure/shelf/clockwork - name = "brass shelf" - icon_state = "shelf_clockwork" - shelf_style = "clockwork" - build_stack_type = /obj/item/stack/tile/brass - -/obj/structure/gunrack - name = "gun rack" - desc = "A rack for stowing firearms." - icon = 'icons/obj/structures.dmi' - icon_state = "gunrack" - layer = TABLE_LAYER - density = TRUE - anchored = TRUE - pass_flags_self = PASSTAKE - max_integrity = 80 - var/build_stack_type = /obj/item/stack/sheet/metal - -/obj/structure/gunrack/Initialize(mapload) - . = ..() - var/static/list/gun_subtypes = subtypesof(/obj/item/gun) - AddComponent(/datum/component/shelver/gun_rack, allowed_types_ = gun_subtypes) - - if(mapload) - SEND_SIGNAL(src, COMSIG_SHELF_ADDED_ON_MAPLOAD) - -/obj/structure/gunrack/wrench_act(mob/living/user, obj/item/I) - . = TRUE - if(user.a_intent == INTENT_HELP) - return FALSE - if(!I.use_tool(src, user, 2.5 SECONDS, volume = I.tool_volume)) - return - - to_chat(user, "You disassemble [src].") - deconstruct() - -/obj/structure/gunrack/deconstruct(disassembled) - new build_stack_type(get_turf(src), 5) - return ..() - -/obj/structure/gunrack/clockwork - name = "brass weapon rack" - icon_state = "gunrack_clockwork" - build_stack_type = /obj/item/stack/tile/brass diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm deleted file mode 100644 index 8eadb12fe09ae..0000000000000 --- a/code/game/objects/structures/statues.dm +++ /dev/null @@ -1,427 +0,0 @@ -/obj/structure/statue - name = "statue" - desc = "Placeholder. Yell at Firecage if you SOMEHOW see this." - icon = 'icons/obj/statue.dmi' - icon_state = "" - density = TRUE - anchored = FALSE - max_integrity = 100 - var/oreAmount = 5 - var/material_drop_type = /obj/item/stack/sheet/metal - -/obj/structure/statue/attackby__legacy__attackchain(obj/item/W, mob/living/user, params) - add_fingerprint(user) - if(!(flags & NODECONSTRUCT)) - if(default_unfasten_wrench(user, W)) - return - if(istype(W, /obj/item/gun/energy/plasmacutter)) - playsound(src, W.usesound, 100, 1) - user.visible_message("[user] is slicing apart the [name]...", \ - "You are slicing apart the [name]...") - if(do_after(user, 40 * W.toolspeed, target = src)) - if(!loc) - return - user.visible_message("[user] slices apart the [name].", \ - "You slice apart the [name].") - deconstruct(TRUE) - return - return ..() - -/obj/structure/statue/welder_act(mob/user, obj/item/I) - if(anchored) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - WELDER_ATTEMPT_SLICING_MESSAGE - if(I.use_tool(src, user, 40, volume = I.tool_volume)) - WELDER_SLICING_SUCCESS_MESSAGE - deconstruct(TRUE) - -/obj/structure/statue/attack_hand(mob/living/user) - user.changeNext_move(CLICK_CD_MELEE) - add_fingerprint(user) - user.visible_message("[user] rubs some dust off from the [name]'s surface.", \ - "You rub some dust off from the [name]'s surface.") - -/obj/structure/statue/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - 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) - qdel(src) - -/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 = FALSE - -/obj/structure/statue/uranium/nuke - name = "statue of a nuclear fission explosive" - desc = "This is a grand statue of a Nuclear Explosive. It has a sickening green colour." - icon_state = "nuke" - -/obj/structure/statue/uranium/eng - name = "statue of an engineer" - desc = "This statue has a sickening green colour." - icon_state = "eng" - -/obj/structure/statue/uranium/attackby__legacy__attackchain(obj/item/W, mob/user, params) - radiate() - return ..() - -/obj/structure/statue/uranium/Bumped(atom/user) - radiate() - ..() - -/obj/structure/statue/uranium/attack_hand(mob/user) - radiate() - ..() - -/obj/structure/statue/uranium/proc/radiate() - if(!active) - if(world.time > last_event + 1.5 SECONDS) - active = TRUE - radiation_pulse(src, 30) - last_event = world.time - active = FALSE - -/obj/structure/statue/plasma - max_integrity = 200 - material_drop_type = /obj/item/stack/sheet/mineral/plasma - desc = "This statue is suitably made from plasma." - -/obj/structure/statue/plasma/scientist - name = "statue of a scientist" - icon_state = "sci" - -/obj/structure/statue/plasma/xeno - name = "statue of a xenomorph" - icon_state = "xeno" - -/obj/structure/statue/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ..() - if(exposed_temperature > 300) - PlasmaBurn(exposed_temperature) - -/obj/structure/statue/plasma/bullet_act(obj/item/projectile/P) - if(!QDELETED(src)) //wasn't deleted by the projectile's effects. - if(!P.nodamage && ((P.damage_type == BURN) || (P.damage_type == BRUTE))) - if(P.firer) - message_admins("[key_name_admin(P.firer)] ignited a plasma statue with [P.name] at [COORD(loc)]") - log_game("[key_name(P.firer)] ignited a plasma statue with [P.name] at [COORD(loc)]") - investigate_log("[key_name(P.firer)] ignited a plasma statue with [P.name] at [COORD(loc)]", "atmos") - else - message_admins("A plasma statue was ignited with [P.name] at [COORD(loc)]. No known firer.") - log_game("A plasma statue was ignited with [P.name] at [COORD(loc)]. No known firer.") - PlasmaBurn() - ..() - -/obj/structure/statue/plasma/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(W.get_heat() > 300)//If the temperature of the object is over 300, then ignite - message_admins("[key_name_admin(user)] ignited a plasma statue at [COORD(loc)]") - log_game("[key_name(user)] ignited plasma a statue at [COORD(loc)]") - investigate_log("[key_name(user)] ignited a plasma statue at [COORD(loc)]", "atmos") - ignite(W.get_heat()) - return - return ..() - -/obj/structure/statue/plasma/welder_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, volume = I.tool_volume)) - return - user.visible_message("[user] sets [src] on fire!",\ - "[src] disintegrates into a cloud of plasma!",\ - "You hear a 'whoompf' and a roar.") - message_admins("[key_name_admin(user)] ignited a plasma statue at [COORD(loc)]") - log_game("[key_name(user)] ignited plasma a statue at [COORD(loc)]") - investigate_log("[key_name(user)] ignited a plasma statue at [COORD(loc)]", "atmos") - ignite(2500) - -/obj/structure/statue/plasma/proc/PlasmaBurn() - atmos_spawn_air(LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS, 160) - deconstruct(FALSE) - -/obj/structure/statue/plasma/proc/ignite(exposed_temperature) - if(exposed_temperature > 300) - PlasmaBurn() - -/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." - -/obj/structure/statue/gold/hos - name = "statue of the head of security" - icon_state = "hos" - -/obj/structure/statue/gold/hop - name = "statue of the head of personnel" - icon_state = "hop" - -/obj/structure/statue/gold/cmo - name = "statue of the chief medical officer" - icon_state = "cmo" - -/obj/structure/statue/gold/ce - name = "statue of the chief engineer" - icon_state = "ce" - -/obj/structure/statue/gold/rd - name = "statue of the research director" - icon_state = "rd" - -/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." - -/obj/structure/statue/silver/md - name = "statue of a medical doctor" - icon_state = "md" - -/obj/structure/statue/silver/janitor - name = "statue of a janitor" - icon_state = "jani" - -/obj/structure/statue/silver/sec - name = "statue of a security officer" - icon_state = "sec" - -/obj/structure/statue/silver/secborg - name = "statue of a security cyborg" - icon_state = "secborg" - -/obj/structure/statue/silver/medborg - name = "statue of a medical cyborg" - icon_state = "medborg" - -/obj/structure/statue/silver/corgi - name = "statue of a corgi" - icon_state = "corgi" - -/obj/structure/statue/silver/monkey - name = "statue of a monkey" - icon_state = "monkey" - -/obj/structure/statue/diamond - max_integrity = 1000 - material_drop_type = /obj/item/stack/sheet/mineral/diamond - desc = "This is a very expensive diamond statue." - -/obj/structure/statue/diamond/captain - name = "statue of THE captain" - icon_state = "cap" - -/obj/structure/statue/diamond/ai1 - name = "statue of the AI hologram" - icon_state = "ai1" - -/obj/structure/statue/diamond/ai2 - name = "statue of the AI core" - icon_state = "ai2" - -/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 - -/obj/structure/statue/bananium/clown - name = "statue of a clown" - icon_state = "clown" - -/obj/structure/statue/bananium/Bumped(atom/user) - honk() - ..() - -/obj/structure/statue/bananium/attackby__legacy__attackchain(obj/item/W, mob/user, params) - honk() - return ..() - -/obj/structure/statue/bananium/attack_hand(mob/user) - honk() - ..() - -/obj/structure/statue/bananium/proc/honk() - if(!spam_flag) - spam_flag = 1 - playsound(loc, 'sound/items/bikehorn.ogg', 50, 1) - spawn(20) - spam_flag = 0 - -/obj/structure/statue/sandstone - max_integrity = 50 - material_drop_type = /obj/item/stack/sheet/mineral/sandstone - -/obj/structure/statue/sandstone/assistant - name = "statue of an assistant" - desc = "A cheap statue of sandstone for a greyshirt." - icon_state = "assist" - -/// call me when we add marble i guess -/obj/structure/statue/sandstone/venus - name = "statue of a pure maiden" - desc = "An ancient marble statue. The subject is depicted with a floor-length braid and is wielding a toolbox. By Jove, it's easily the most gorgeous depiction of a woman you've ever seen. The artist must truly be a master of his craft. Shame about the broken arm, though." - icon = 'icons/obj/statuelarge.dmi' - icon_state = "venus" - oreAmount = 20 - -/obj/structure/statue/tranquillite - max_integrity = 300 - material_drop_type = /obj/item/stack/sheet/mineral/tranquillite - desc = "..." - -/obj/structure/statue/tranquillite/mime - name = "statue of a mime" - icon_state = "mime" - -/obj/structure/statue/tranquillite/mime/AltClick(mob/user)//has 4 dirs - if(user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!Adjacent(user)) - return - if(anchored) - to_chat(user, "It is fastened to the floor!") - return - setDir(turn(dir, 90)) - -/obj/structure/statue/plastitanium - max_integrity = 600 - material_drop_type = /obj/item/stack/sheet/mineral/plastitanium - -/obj/structure/statue/plastitanium/kidanstatue - name = "kidan warrior statue" - desc = "A beautifully carved and menacing statue of a Kidan warrior made out of plastitanium. It looks very heavy." - icon_state = "kidan" - -/obj/structure/statue/chickenstatue - name = "bronze chickenman statue" - desc = "An antique and oriental-looking statue of a Chickenman made of bronze." - icon_state = "chicken" - anchored = TRUE - oreAmount = 0 - -/obj/structure/statue/soviet_mulebot - name = "OXENbot" - desc = "Like a MULEbot, but more socialist and less functional." - icon = 'icons/obj/aibots.dmi' - icon_state = "mulebot0" - anchored = TRUE - oreAmount = 10 - -//////////////////////////////// - -/obj/structure/snowman - name = "snowman" - desc = "Seems someone made a snowman here." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "snowman" - anchored = TRUE - density = TRUE - max_integrity = 50 - -/obj/structure/snowman/built - desc = "Just like the ones you remember from childhood!" - -/obj/structure/snowman/built/Destroy() - new /obj/item/food/grown/carrot(drop_location()) - new /obj/item/grown/log(drop_location()) - new /obj/item/grown/log(drop_location()) - return ..() - -/obj/structure/snowman/built/attackby__legacy__attackchain(obj/item/I, mob/user) - if(istype(I, /obj/item/snowball) && obj_integrity < max_integrity) - to_chat(user, "You patch some of the damage on [src] with [I].") - obj_integrity = max_integrity - qdel(I) - else - return ..() - -/obj/structure/snowman/built/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) - ..() - qdel(src) - -/obj/structure/statue/cyberiad - name = "NSS Cyberiad" - desc = "A giant model of the Cyberiad science station. Judging by the differences in design, the station has been rebuilt several times." - icon = 'icons/obj/station_statue.dmi' - icon_state = "center" - flags = NODECONSTRUCT - anchored = TRUE - max_integrity = 500 - oreAmount = 0 - -/obj/structure/statue/cyberiad/Destroy() - . = ..() - // Delete all the nearby cyberiad statue parts - for(var/obj/structure/statue/cyberiad/bigass_statue in range(2)) - qdel(bigass_statue) - -// Top layer of the statue is not dense -/obj/structure/statue/cyberiad/north - icon_state = "north" - density = FALSE - layer = ABOVE_ALL_MOB_LAYER - -/obj/structure/statue/cyberiad/north/west - icon_state = "nw" - -/obj/structure/statue/cyberiad/north/east - icon_state = "ne" - -/obj/structure/statue/cyberiad/north/Initialize(mapload) - . = ..() - if(GetExactComponent(/datum/component/largetransparency)) //already have it, lets yeet - return - AddComponent(/datum/component/largetransparency, -1, -2, 2, 2) - -// Adds transparency to said top layer when the player gets behind or near it -/obj/structure/statue/cyberiad/north/west/Initialize(mapload) - AddComponent(/datum/component/largetransparency, 0, -2, 2, 2) - return ..() - -/obj/structure/statue/cyberiad/north/east/Initialize(mapload) - AddComponent(/datum/component/largetransparency, -2, -2, 2, 2) - return ..() - -/obj/structure/statue/cyberiad/center - icon_state = "center" - density = FALSE - layer = ABOVE_ALL_MOB_LAYER - -/obj/structure/statue/cyberiad/center/west - icon_state = "west" - -/obj/structure/statue/cyberiad/center/east - icon_state = "east" - -/obj/structure/statue/cyberiad/center/Initialize(mapload) - . = ..() - if(GetExactComponent(/datum/component/largetransparency)) //already have it, lets yeet - return - AddComponent(/datum/component/largetransparency, -1, -1, 2, 2) - -// Adds transparency to said top layer when the player gets behind or near it -/obj/structure/statue/cyberiad/center/west/Initialize(mapload) - AddComponent(/datum/component/largetransparency, 0, -1, 2, 2) - return ..() - -/obj/structure/statue/cyberiad/center/east/Initialize(mapload) - AddComponent(/datum/component/largetransparency, -2, -1, 2, 2) - return ..() - -/obj/structure/statue/cyberiad/south - icon_state = "south" - -/obj/structure/statue/cyberiad/south/west - icon_state = "sw" - -/obj/structure/statue/cyberiad/south/east - icon_state = "se" diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm deleted file mode 100644 index 28183daff666b..0000000000000 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ /dev/null @@ -1,287 +0,0 @@ -/* Beds... get your mind out of the gutter, they're for sleeping! - * Contains: - * Beds - * Roller beds - * Dog Beds - */ - -/* - * Beds - */ - -/obj/structure/bed - name = "bed" - desc = "This is used to lie in, sleep in or strap on." - icon = 'icons/obj/objects.dmi' - icon_state = "bed" - dir = SOUTH - can_buckle = TRUE - anchored = TRUE - buckle_lying = TRUE - resistance_flags = FLAMMABLE - max_integrity = 100 - integrity_failure = 30 - var/buildstacktype = /obj/item/stack/sheet/metal - var/buildstackamount = 2 - buckle_offset = -6 - var/comfort = 2 // default comfort - -/obj/structure/bed/examine(mob/user) - . = ..() - . += "Click dragging someone to a bed will buckle them in. Functions just like a chair except you can walk over them." - -/obj/structure/bed/attack_hand(mob/user) - if(user.Move_Pulled(src)) - return - return ..() - -/obj/structure/bed/psych - name = "psych bed" - desc = "For prime comfort during psychiatric evaluations." - icon_state = "psychbed" - buildstackamount = 5 - -/obj/structure/bed/alien - name = "resting contraption" - desc = "This looks similar to contraptions from Earth. Could aliens be stealing our technology?" - icon_state = "abed" - comfort = 0.3 - -/obj/structure/bed/proc/handle_rotation() - return - -/obj/structure/bed/wrench_act(mob/user, obj/item/I) - . = TRUE - if(flags & NODECONSTRUCT) - to_chat(user, "You can't figure out how to deconstruct [src]!") - return - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - deconstruct(TRUE) - -/obj/structure/bed/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - if(buildstacktype) - new buildstacktype(loc, buildstackamount) - ..() - -/obj/structure/bed/post_buckle_mob(mob/living/M) - M.pixel_y = M.get_standard_pixel_y_offset() - -/obj/structure/bed/post_unbuckle_mob(mob/living/M) - M.pixel_y = M.get_standard_pixel_y_offset() - -/obj/structure/bed/shove_impact(mob/living/target, mob/living/attacker) - . = ..() - if(!ishuman(target)) - return - - var/mob/living/carbon/human/H = target - - // only if you're wearing PJs - if(!istype(H.w_uniform, /obj/item/clothing/under/misc/pj)) - return - - // and there's a sheet on the bed - if(!locate(/obj/item/bedsheet) in loc) - return - - var/sleep_ratio = 1 - - if(istype(H.shoes, /obj/item/clothing/shoes/slippers)) - sleep_ratio *= 2 - // take your shoes off first, you filthy animal - H.drop_item_to_ground(H.shoes) - - var/extinguished_candle = FALSE - for(var/obj/item/candle/C in range(2, src)) - if(C.lit) - C.unlight() - extinguished_candle = TRUE - - if(extinguished_candle) - sleep_ratio *= 2 - - // nighty night - target.visible_message( - "[attacker] puts [target] to bed!", - "[attacker] shoves you under the covers, and you're out like a light!", - "You hear someone getting into bed." - ) - - if(sleep_ratio > 1) - target.visible_message( - "[target] seems especially cozy...[target.p_they()] probably won't be up for a while.", - "You feel so cozy, you could probably stay here for a while..." - ) - - target.forceMove(loc) - buckle_mob(target, TRUE) - if(!H.IsSleeping()) - H.Sleeping(15 SECONDS * sleep_ratio) - add_attack_logs(attacker, target, "put to bed for [15 * sleep_ratio] seconds.") - H.emote("snore") - - for(var/mob/living/carbon/human/viewer in viewers()) - if(prob(50)) - viewer.emote("yawn") - - return TRUE - -/* - * Roller beds - */ - -/obj/structure/bed/roller - name = "roller bed" - icon = 'icons/obj/rollerbed.dmi' - icon_state = "down" - buckle_offset = 0 - face_while_pulling = FALSE - resistance_flags = NONE - anchored = FALSE - comfort = 1 - var/icon_up = "up" - var/icon_down = "down" - var/folded = /obj/item/roller - -/obj/structure/bed/roller/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(istype(W, /obj/item/roller_holder)) - if(has_buckled_mobs()) - if(length(buckled_mobs) > 1) - unbuckle_all_mobs() - user.visible_message("[user] unbuckles all creatures from [src].") - else - user_unbuckle_mob(buckled_mobs[1], user) - else - user.visible_message("[user] collapses \the [name].", "You collapse \the [name].") - new folded(get_turf(src)) - qdel(src) - else - return ..() - -/obj/structure/bed/roller/post_buckle_mob(mob/living/M) - density = TRUE - icon_state = icon_up - ..() - -/obj/structure/bed/roller/post_unbuckle_mob(mob/living/M) - density = FALSE - icon_state = icon_down - ..() - -/obj/structure/bed/roller/holo - name = "holo stretcher" - icon_state = "holo_extended" - icon_up = "holo_extended" - icon_down = "holo_extended" - folded = /obj/item/roller/holo - -/obj/item/roller - name = "roller bed" - desc = "A collapsed roller bed that can be carried around." - icon = 'icons/obj/rollerbed.dmi' - icon_state = "folded" - w_class = WEIGHT_CLASS_BULKY - var/extended = /obj/structure/bed/roller - -/obj/item/roller/attack_self__legacy__attackchain(mob/user) - var/obj/structure/bed/roller/R = new extended(user.loc) - R.add_fingerprint(user) - qdel(src) - -/obj/item/roller/afterattack__legacy__attackchain(atom/target, mob/user, proximity, params) - if(!proximity) - return - if(isturf(target)) - var/turf/T = target - if(!T.density) - var/obj/structure/bed/roller/R = new extended(T) - R.add_fingerprint(user) - qdel(src) - -/obj/item/roller/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/roller_holder)) - var/obj/item/roller_holder/RH = W - if(!RH.held) - user.visible_message("[user] collects \the [name].", "You collect \the [name].") - forceMove(RH) - RH.held = src - -/obj/item/roller/holo - name = "holo stretcher" - desc = "A retracted hardlight stretcher that can be carried around." - icon_state = "holo_retracted" - w_class = WEIGHT_CLASS_SMALL - origin_tech = "magnets=3;biotech=4;powerstorage=3" - extended = /obj/structure/bed/roller/holo - -/obj/item/roller/holo/attackby__legacy__attackchain(obj/item/W, mob/user, params) - return - -/obj/structure/bed/roller/MouseDrop(over_object, src_location, over_location) - if(over_object == usr && Adjacent(usr) && (in_range(src, usr) || usr.contents.Find(src))) - if(!ishuman(usr) || usr.incapacitated()) - return - if(has_buckled_mobs()) - return 0 - usr.visible_message("[usr] collapses \the [name].", "You collapse \the [name].") - new folded(get_turf(src)) - qdel(src) - return - ..() - -/obj/item/roller_holder - name = "roller bed rack" - desc = "A rack for carrying a collapsed roller bed." - icon = 'icons/obj/rollerbed.dmi' - icon_state = "folded" - var/obj/item/roller/held - -/obj/item/roller_holder/New() - ..() - held = new /obj/item/roller(src) - -/obj/item/roller_holder/attack_self__legacy__attackchain(mob/user as mob) - if(!held) - to_chat(user, "The rack is empty.") - return - - to_chat(user, "You deploy the roller bed.") - var/obj/structure/bed/roller/R = new /obj/structure/bed/roller(user.loc) - R.add_fingerprint(user) - QDEL_NULL(held) - -/* - * Dog beds - */ - -/obj/structure/bed/dogbed - name = "dog bed" - icon_state = "dogbed" - desc = "A comfy-looking dog bed. You can even strap your pet in, just in case the gravity turns off." - anchored = FALSE - buildstackamount = 10 - buildstacktype = /obj/item/stack/sheet/wood - buckle_offset = 0 - comfort = 0.5 - -/obj/structure/bed/dogbed/ian - name = "Ian's bed" - desc = "Ian's bed! Looks comfy." - anchored = TRUE - -/obj/structure/bed/dogbed/renault - desc = "Renault's bed! Looks comfy. A foxy person needs a foxy pet." - name = "Renault's bed" - anchored = TRUE - -/obj/structure/bed/dogbed/runtime - desc = "A comfy-looking cat bed. You can even strap your pet in, in case the gravity turns off." - name = "Runtime's bed" - anchored = TRUE - -/obj/structure/bed/dogbed/brad - name = "Brad's bed" - desc = "Brad's bed! Why does a cockroach get this amount of love?" - anchored = TRUE diff --git a/code/game/objects/structures/table_frames.dm b/code/game/objects/structures/table_frames.dm deleted file mode 100644 index 160e74bbad323..0000000000000 --- a/code/game/objects/structures/table_frames.dm +++ /dev/null @@ -1,133 +0,0 @@ -/* Table Frames - * Contains: - * Frames - * Wooden Frames - */ - - -/* - * Normal Frames - */ - -/obj/structure/table_frame - name = "table frame" - desc = "Four metal legs with four framing rods for a table. You could easily pass through this." - icon = 'icons/obj/structures.dmi' - icon_state = "table_frame" - density = FALSE - anchored = FALSE - layer = PROJECTILE_HIT_THRESHHOLD_LAYER - max_integrity = 100 - ///The resource dropped when the table frame is destroyed or deconstructed - var/framestack = /obj/item/stack/rods - ///How many of framestack resource are dropped - var/framestackamount = 2 - ///How long the table takes to make - var/construction_time = 5 SECONDS - ///What stacks can be used to make the table, and if it will result in a unique table - var/list/restrict_table_types = list() //ex: list(/obj/item/stack/tile/carpet = /obj/structure/table/wood/poker, /obj/item/stack/sheet/wood = /obj/item/stack/sheet/wood::table_type), carpet will make poker table, wood will result in standard table_type. If the list is empty, any material can be used for its default table_type. - -/obj/structure/table_frame/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(!try_make_table(I, user)) - return ..() - -///Try to make a table with the item used to attack. FALSE if you can't make a table and should attack. TRUE does not necessarily mean a table was made. -/obj/structure/table_frame/proc/try_make_table(obj/item/stack/stack, mob/user) - if(!istype(stack)) - return FALSE - - var/obj/structure/table/new_table_type = stack.table_type - if(length(restrict_table_types)) - var/valid_stack_type = FALSE - for(var/obj/item/stack/current_stack as anything in restrict_table_types) - if(istype(stack, current_stack)) - new_table_type = restrict_table_types[current_stack] - valid_stack_type = TRUE - break - if(!valid_stack_type) - return FALSE - - if(!new_table_type) - return FALSE - - if(stack.get_amount() < 1) - to_chat(user, "You need at least one sheet of [stack] to do this!") - return TRUE - - to_chat(user, "You start adding [stack] to [src]...") - if(!do_after(user, construction_time, target = src)) - return TRUE - - if(!stack.use(1)) - to_chat(user, "You need at least one sheet of [stack] to do this!") - return TRUE - - var/obj/structure/table/table_already_there = locate(/obj/structure/table) in get_turf(src) - if(table_already_there) //check again after to make sure one wasnt added since - to_chat(user, "There is already [table_already_there] here.") - return TRUE - - if(!istype(new_table_type, /obj/structure/table)) //if its something unique, skip the table parts - new new_table_type(loc) - qdel(src) - return TRUE - make_new_table(new_table_type) - return TRUE - -/obj/structure/table_frame/wrench_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - TOOL_ATTEMPT_DISMANTLE_MESSAGE - if(I.use_tool(src, user, 30, volume = I.tool_volume)) - TOOL_DISMANTLE_SUCCESS_MESSAGE - for(var/i = 1, i <= framestackamount, i++) - new framestack(get_turf(src)) - qdel(src) - -/obj/structure/table_frame/proc/make_new_table(table_type) //makes sure the new table made retains what we had as a frame - var/obj/structure/table/T = new table_type(loc) - T.frame = type - T.framestack = framestack - T.framestackamount = framestackamount - qdel(src) - -/obj/structure/table_frame/deconstruct(disassembled = TRUE) - new framestack(get_turf(src), framestackamount) - qdel(src) - -/obj/structure/table_frame/narsie_act() - new /obj/structure/table_frame/wood(loc) - qdel(src) - -/* - * Wooden Frames - */ - -/obj/structure/table_frame/wood - name = "wooden table frame" - desc = "Four wooden legs with four framing wooden rods for a wooden table. You could easily pass through this." - icon_state = "wood_frame" - framestack = /obj/item/stack/sheet/wood - framestackamount = 2 - resistance_flags = FLAMMABLE - restrict_table_types = list(/obj/item/stack/tile/carpet = /obj/structure/table/wood/poker, /obj/item/stack/sheet/wood = /obj/item/stack/sheet/wood::table_type) - -/obj/structure/table_frame/brass - name = "brass table frame" - desc = "Four pieces of brass arranged in a square. It's slightly warm to the touch." - icon_state = "brass_frame" - resistance_flags = FIRE_PROOF | ACID_PROOF - density = TRUE - anchored = TRUE - framestack = /obj/item/stack/tile/brass - framestackamount = 1 - construction_time = 2 SECONDS - restrict_table_types = list(/obj/item/stack/tile/brass = /obj/item/stack/tile/brass::table_type) - -/obj/structure/table_frame/brass/narsie_act() - ..() - if(src) //do we still exist? - var/previouscolor = color - color = "#960000" - animate(src, color = previouscolor, time = 8) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm deleted file mode 100644 index d9a76bfacf8ad..0000000000000 --- a/code/game/objects/structures/tables_racks.dm +++ /dev/null @@ -1,1041 +0,0 @@ -/* Tables and Racks - * Contains: - * Tables - * Glass Tables - * Wooden Tables - * Reinforced Tables - * Racks - * Rack Parts - */ - -/* - * Tables - */ - -/obj/structure/table - name = "table" - desc = "A square piece of metal standing on four metal legs. It can not move." - icon = 'icons/obj/smooth_structures/tables/table.dmi' - icon_state = "table-0" - base_icon_state = "table" - density = TRUE - anchored = TRUE - layer = TABLE_LAYER - pass_flags_self = LETPASSTHROW | PASSTAKE - climbable = TRUE - max_integrity = 100 - integrity_failure = 30 - smoothing_flags = SMOOTH_BITMASK - smoothing_groups = list(SMOOTH_GROUP_TABLES) - canSmoothWith = list(SMOOTH_GROUP_TABLES) - creates_cover = TRUE - var/frame = /obj/structure/table_frame - var/framestack = /obj/item/stack/rods - var/buildstack = /obj/item/stack/sheet/metal - var/busy = FALSE - var/buildstackamount = 1 - var/framestackamount = 2 - var/deconstruction_ready = TRUE - var/flipped = FALSE - ///If this is true, the table will have items slide off it when placed. - var/slippery = FALSE - /// The minimum level of environment_smash required for simple animals to be able to one-shot this. - var/minimum_env_smash = ENVIRONMENT_SMASH_WALLS - /// Can this table be flipped? - var/can_be_flipped = TRUE - var/flipped_table_icon_base = "table" - -/obj/structure/table/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_EXIT = PROC_REF(on_atom_exit), - ) - AddElement(/datum/element/connect_loc, loc_connections) - - if(flipped) - update_icon() - -/obj/structure/table/examine(mob/user) - . = ..() - . += deconstruction_hints(user) - if(can_be_flipped) - if(flipped) - . += "Alt-Shift-Click to right the table again." - else - . += "Alt-Shift-Click to flip over the table." - -/obj/structure/table/proc/deconstruction_hints(mob/user) - return "The top is screwed on, but the main bolts are also visible." - -/obj/structure/table/update_icon(updates=ALL) - . = ..() - update_smoothing() - -/obj/structure/table/update_icon_state() - if((smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK)) && !flipped) - icon_state = "" - - if(flipped) - var/type = 0 - var/subtype = null - for(var/direction in list(turn(dir,90), turn(dir,-90))) - var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,direction)) - if(T && T.flipped) - type++ - if(type == 1) - subtype = direction == turn(dir,90) ? "-" : "+" - icon_state = "[flipped_table_icon_base]flip[type][type == 1 ? subtype : ""]" - -/obj/structure/table/proc/update_smoothing() - if((smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK)) && !flipped) - QUEUE_SMOOTH(src) - QUEUE_SMOOTH_NEIGHBORS(src) - - if(flipped) - clear_smooth_overlays() - -// Need to override this to allow flipped tables to be mapped in without the smoothing subsystem resetting the icon_state -/obj/structure/table/set_smoothed_icon_state(new_junction) - if(flipped) - return - ..() - -/obj/structure/table/flipped - icon_state = "tableflip0" - flipped = TRUE - -/obj/structure/table/narsie_act() - new /obj/structure/table/wood(loc) - qdel(src) - -/obj/structure/table/start_climb(mob/living/user) - . = ..() - item_placed(user) - -/obj/structure/table/attack_hand(mob/living/user) - ..() - if(length(climbers)) - for(var/mob/living/climber as anything in climbers) - climber.Weaken(4 SECONDS) - climber.visible_message("[climber.name] has been knocked off the table", "You've been knocked off the table", "You hear [climber.name] get knocked off the table") - else if(Adjacent(user) && user.pulling && user.pulling.pass_flags & PASSTABLE) - user.Move_Pulled(src) - if(user.pulling.loc == loc) - user.visible_message("[user] places [user.pulling] onto [src].", - "You place [user.pulling] onto [src].") - user.stop_pulling() - -/obj/structure/table/attack_tk() // no telehulk sorry - return - -/obj/structure/table/proc/item_placed(item) - return - -/obj/structure/table/CanPass(atom/movable/mover, border_dir) - if(istype(mover,/obj/item/projectile)) - return check_cover(mover, border_dir) - - var/mob/living/living_mover = mover - if(istype(living_mover) && (HAS_TRAIT(living_mover, TRAIT_FLYING) || (IS_HORIZONTAL(living_mover) && HAS_TRAIT(living_mover, TRAIT_CONTORTED_BODY)))) - return TRUE - if(istype(mover) && mover.checkpass(PASSTABLE)) - return TRUE - if(mover.throwing) - return TRUE - if(length(get_atoms_of_type(get_turf(mover), /obj/structure/table) - mover)) - var/obj/structure/table/T = locate(/obj/structure/table) in get_turf(mover) - if(!T.flipped) - return TRUE - if(flipped) - if(border_dir == dir) - return !density - else - return TRUE - return FALSE - -/obj/structure/table/CanPathfindPass(to_dir, datum/can_pass_info/pass_info) - . = !density - if(pass_info.is_movable) - . = . || pass_info.pass_flags & PASSTABLE - -/** - * Determines whether a projectile crossing our turf should be stopped. - * Return FALSE to stop the projectile. - * - * Arguments: - * * P - The projectile trying to cross. - * * proj_dir - The incoming direction of the projectile. - */ -/obj/structure/table/proc/check_cover(obj/item/projectile/P, proj_dir) - . = TRUE - if(!flipped) - return - if(get_dist(P.starting, loc) <= 1) // Tables won't help you if people are THIS close - return - if(proj_dir != dir) // Back/side shots may pass - return - if(prob(40)) - return FALSE // Blocked - -/obj/structure/table/proc/on_atom_exit(datum/source, atom/movable/leaving, direction) - SIGNAL_HANDLER // COMSIG_ATOM_EXIT - - if(istype(leaving) && leaving.checkpass(PASSTABLE)) - return - - if(flipped) - if(direction == dir && density) - return COMPONENT_ATOM_BLOCK_EXIT - -/obj/structure/table/MouseDrop_T(obj/O, mob/user) - if(..()) - return TRUE - if((!isitem(O) || user.get_active_hand() != O)) - return - if(isrobot(user)) - return - if(!user.drop_item()) - return - if(O.loc != src.loc) - step(O, get_dir(O, src)) - return TRUE - -/obj/structure/table/proc/tablepush(obj/item/grab/G, mob/user) - if(HAS_TRAIT(user, TRAIT_PACIFISM)) - to_chat(user, "Throwing [G.affecting] onto the table might hurt them!") - return - if(get_dist(src, user) < 2) - if(G.affecting.buckled) - to_chat(user, "[G.affecting] is buckled to [G.affecting.buckled]!") - return FALSE - if(G.state < GRAB_AGGRESSIVE) - to_chat(user, "You need a better grip to do that!") - return FALSE - if(!G.confirm()) - return FALSE - var/blocking_object = density_check() - if(blocking_object) - to_chat(user, "You cannot do this there is \a [blocking_object] in the way!") - return FALSE - G.affecting.forceMove(get_turf(src)) - G.affecting.Weaken(4 SECONDS) - item_placed(G.affecting) - G.affecting.visible_message("[G.assailant] pushes [G.affecting] onto [src].", \ - "[G.assailant] pushes [G.affecting] onto [src].") - add_attack_logs(G.assailant, G.affecting, "Pushed onto a table") - qdel(G) - return TRUE - qdel(G) - -/obj/structure/table/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/grab)) - tablepush(I, user) - return - - if(isrobot(user)) - return - - if(user.a_intent == INTENT_HELP && !(I.flags & ABSTRACT)) - if(user.drop_item()) - I.Move(loc) - var/list/click_params = params2list(params) - //Center the icon where the user clicked. - 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 (thus leaving the table turf) - 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) - if(slippery) - step_away(I, user) - visible_message("[I] slips right off [src]!") - playsound(loc, 'sound/misc/slip.ogg', 50, TRUE, -1) - else //Don't want slippery moving tables to have the item attached to them if it slides off. - item_placed(I) - else - return ..() - -/obj/structure/table/attack_animal(mob/living/simple_animal/M) - . = ..() - if(. && M.environment_smash >= minimum_env_smash) - deconstruct(FALSE) - M.visible_message("[M] smashes [src]!", "You smash [src].") - -/obj/structure/table/shove_impact(mob/living/target, mob/living/attacker) - if(locate(/obj/structure/table) in get_turf(target)) - return FALSE - if(flipped) - return FALSE - var/pass_flags_cache = target.pass_flags - target.pass_flags |= PASSTABLE - if(target.Move(loc)) - . = TRUE - target.Weaken(4 SECONDS) - add_attack_logs(attacker, target, "pushed onto [src]", ATKLOG_ALL) - else - . = FALSE - target.pass_flags = pass_flags_cache - -/obj/structure/table/screwdriver_act(mob/user, obj/item/I) - if(flags & NODECONSTRUCT) - return - if(!deconstruction_ready) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - TOOL_ATTEMPT_DISMANTLE_MESSAGE - if(I.use_tool(src, user, 20, volume = I.tool_volume) && deconstruction_ready) - deconstruct(TRUE) - TOOL_DISMANTLE_SUCCESS_MESSAGE - -/obj/structure/table/wrench_act(mob/user, obj/item/I) - if(flags & NODECONSTRUCT) - return - if(!deconstruction_ready) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - TOOL_ATTEMPT_DISMANTLE_MESSAGE - if(I.use_tool(src, user, 40, volume = I.tool_volume) && deconstruction_ready) - deconstruct(TRUE, 1) - TOOL_DISMANTLE_SUCCESS_MESSAGE - -/obj/structure/table/deconstruct(disassembled = TRUE, wrench_disassembly = 0) - if(!(flags & NODECONSTRUCT)) - var/turf/T = get_turf(src) - new buildstack(T, buildstackamount) - if(!wrench_disassembly) - new frame(T) - else - new framestack(T, framestackamount) - qdel(src) - -/obj/structure/table/proc/straight_table_check(direction) - var/obj/structure/table/T - for(var/angle in list(-90,90)) - T = locate() in get_step(loc,turn(direction,angle)) - if(T && !T.flipped) - return 0 - T = locate() in get_step(loc,direction) - if(!T || T.flipped) - return 1 - if(istype(T,/obj/structure/table/reinforced/)) - if(!T.deconstruction_ready) - return 0 - return T.straight_table_check(direction) - -/obj/structure/table/AltShiftClick(mob/living/carbon/human/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user) || !can_be_flipped || is_ventcrawling(user)) - return - - var/flip_speed = get_flip_speed(user) - - if(!flipped) - - if(flip_speed > 0) - user.visible_message("[user] starts trying to flip [src]!", "You start trying to flip [src][flip_speed >= 5 SECONDS ? " (it'll take about [flip_speed / 10] seconds)." : ""].") - if(!do_after(user, flip_speed, TRUE, src)) - user.visible_message("[user] gives up on trying to flip [src].") - return - if(!flip(get_cardinal_dir(user, src))) - to_chat(user, "It won't budge.") - return - - - user.visible_message("[user] flips [src]!") - - if(climbable) - structure_shaken() - else - if(flip_speed > 0) - user.visible_message("[user] starts trying to right [src]!", "You start trying to right [src][flip_speed >= 5 SECONDS ? " (it'll take about [flip_speed / 10] seconds)." : ""]") - if(!do_after(user, flip_speed, TRUE, src)) - user.visible_message("[user] gives up on trying to right [src].") - return - if(!unflip()) - to_chat(user, "It won't budge.") - user.visible_message("[user] rights [src]!") - -/obj/structure/table/proc/get_flip_speed(mob/living/flipper) - if(!istype(flipper)) - return 0 SECONDS // sure - if(!issimple_animal(flipper)) - return 0 SECONDS - if(istype(flipper, /mob/living/simple_animal/revenant)) - return 0 SECONDS // funny ghost table - switch(flipper.mob_size) - if(MOB_SIZE_TINY) - return 30 SECONDS // you can do it but you gotta *really* work for it - if(MOB_SIZE_SMALL) - return 5 SECONDS // not gonna terrorize anything - else - return 0 SECONDS - - -/obj/structure/table/proc/flip(direction) - if(flipped) - return 0 - - if(!straight_table_check(turn(direction, 90)) || !straight_table_check(turn(direction, -90))) - return FALSE - - dir = direction - if(dir != NORTH) - layer = 5 - - var/list/targets = list(get_step(src, dir), get_step(src, turn(dir, 45)), get_step(src, turn(dir, -45))) - for(var/atom/movable/A in get_turf(src)) - if(isobserver(A)) - continue - if(!A.anchored) - INVOKE_ASYNC(A, TYPE_PROC_REF(/atom/movable/, throw_at), pick(targets), 1, 1) - - flipped = TRUE - smoothing_flags = NONE - flags |= ON_BORDER - for(var/D in list(turn(direction, 90), turn(direction, -90))) - if(locate(/obj/structure/table, get_step(src, D))) - var/obj/structure/table/T = locate(/obj/structure/table, get_step(src, D)) - T.flip(direction) - update_icon() - - creates_cover = FALSE - if(isturf(loc)) - REMOVE_TRAIT(loc, TRAIT_TURF_COVERED, UNIQUE_TRAIT_SOURCE(src)) - - return TRUE - -/obj/structure/table/proc/unflip() - if(!flipped) - return 0 - - var/can_flip = 1 - for(var/mob/A in oview(src,0))//loc) - if(istype(A)) - can_flip = 0 - if(!can_flip) - return 0 - - layer = initial(layer) - flipped = FALSE - // Initial smoothing flags doesn't add the required SMOOTH_OBJ flag, thats done on init - smoothing_flags = initial(smoothing_flags) | SMOOTH_OBJ - flags &= ~ON_BORDER - for(var/D in list(turn(dir, 90), turn(dir, -90))) - if(locate(/obj/structure/table,get_step(src,D))) - var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,D)) - T.unflip() - update_icon() - - creates_cover = TRUE - if(isturf(loc)) - ADD_TRAIT(loc, TRAIT_TURF_COVERED, UNIQUE_TRAIT_SOURCE(src)) - - return 1 - -/obj/structure/table/water_act(volume, temperature, source, method) - . = ..() - if(HAS_TRAIT(src, TRAIT_OIL_SLICKED)) - slippery = initial(slippery) - remove_atom_colour(FIXED_COLOUR_PRIORITY) - REMOVE_TRAIT(src, TRAIT_OIL_SLICKED, "potion") - -/* - * Glass Tables - */ - -/obj/structure/table/glass - name = "glass table" - desc = "Looks fragile. You should totally flip it. It is begging for it." - icon = 'icons/obj/smooth_structures/tables/glass_table.dmi' - icon_state = "glass_table-0" - base_icon_state = "glass_table" - buildstack = /obj/item/stack/sheet/glass - smoothing_groups = list(SMOOTH_GROUP_GLASS_TABLES) - canSmoothWith = list(SMOOTH_GROUP_GLASS_TABLES) - max_integrity = 70 - resistance_flags = ACID_PROOF - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 80, ACID = 100) - minimum_env_smash = ENVIRONMENT_SMASH_STRUCTURES - var/list/debris = list() - var/shardtype = /obj/item/shard - -/obj/structure/table/glass/Initialize(mapload) - . = ..() - debris += new frame - debris += new shardtype - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/structure/table/glass/Destroy() - for(var/i in debris) - qdel(i) - . = ..() - -/obj/structure/table/glass/proc/on_entered(datum/source, atom/movable/entered) - SIGNAL_HANDLER // COMSIG_ATOM_ENTERED - - if(flags & NODECONSTRUCT) - return - if(!isliving(entered)) - return - var/mob/living/L = entered - if(L.incorporeal_move || HAS_TRAIT(L, TRAIT_FLYING) || L.floating) - return - - // Don't break if they're just flying past - if(entered.throwing) - addtimer(CALLBACK(src, PROC_REF(throw_check), entered), 5) - else - check_break(entered) - -/obj/structure/table/glass/proc/throw_check(mob/living/M) - if(M.loc == get_turf(src)) - check_break(M) - -/obj/structure/table/glass/proc/check_break(mob/living/M) - if(has_gravity(M) && M.mob_size > MOB_SIZE_SMALL) - if(M.buckled && HAS_TRAIT(M.buckled, TRAIT_NO_BREAK_GLASS_TABLES)) - return - table_shatter(M) - -/obj/structure/table/glass/flip(direction) - deconstruct(FALSE) - -/obj/structure/table/glass/proc/table_shatter(mob/living/L) - visible_message("[src] breaks!", - "You hear breaking glass.") - var/turf/T = get_turf(src) - playsound(T, "shatter", 50, 1) - for(var/I in debris) - var/atom/movable/AM = I - AM.forceMove(T) - debris -= AM - if(istype(AM, /obj/item/shard)) - AM.throw_impact(L) - L.Weaken(10 SECONDS) - qdel(src) - -/obj/structure/table/glass/shove_impact(mob/living/target, mob/living/attacker) - var/pass_flags_cache = target.pass_flags - target.pass_flags |= PASSTABLE - if(target.Move(loc)) // moving onto a table smashes it, stunning them - . = TRUE - add_attack_logs(attacker, target, "pushed onto [src]", ATKLOG_ALL) - else - . = FALSE - target.pass_flags = pass_flags_cache - -/obj/structure/table/glass/deconstruct(disassembled = TRUE, wrench_disassembly = 0) - if(!(flags & NODECONSTRUCT)) - if(disassembled) - ..() - return - else - var/turf/T = get_turf(src) - playsound(T, "shatter", 50, TRUE) - for(var/X in debris) - var/atom/movable/AM = X - AM.forceMove(T) - debris -= AM - qdel(src) - -/obj/structure/table/glass/narsie_act() - color = NARSIE_WINDOW_COLOUR - for(var/obj/item/shard/S in debris) - S.color = NARSIE_WINDOW_COLOUR - -/obj/structure/table/glass/plasma - name = "plasma glass table" - desc = "A table made from the blood, sweat, and tears of miners." - icon = 'icons/obj/smooth_structures/tables/plasmaglass_table.dmi' - icon_state = "plasmaglass_table-0" - base_icon_state = "plasmaglass_table" - buildstack = /obj/item/stack/sheet/plasmaglass - max_integrity = 140 - shardtype = /obj/item/shard/plasma - minimum_env_smash = ENVIRONMENT_SMASH_RWALLS - -/obj/structure/table/glass/reinforced - name = "reinforced glass table" - desc = "Looks robust. You should totally flip it. It is begging for it." - icon = 'icons/obj/smooth_structures/tables/rglass_table.dmi' - icon_state = "rglass_table-0" - base_icon_state = "rglass_table" - buildstack = /obj/item/stack/sheet/rglass - max_integrity = 100 - integrity_failure = 50 - deconstruction_ready = FALSE - armor = list(MELEE = 10, BULLET = 30, LASER = 30, ENERGY = 100, BOMB = 20, RAD = 0, FIRE = 80, ACID = 70) - smoothing_groups = list(SMOOTH_GROUP_REINFORCED_TABLES) - minimum_env_smash = ENVIRONMENT_SMASH_RWALLS - canSmoothWith = list(SMOOTH_GROUP_REINFORCED_TABLES) - -/obj/structure/table/glass/reinforced/deconstruction_hints(mob/user) //look, it was either copy paste these 4 procs, or copy paste all of the glass stuff - if(deconstruction_ready) - to_chat(user, "The top cover has been welded loose and the main frame's bolts are exposed.") - else - to_chat(user, "The top cover is firmly welded on.") - -/obj/structure/table/glass/reinforced/flip(direction) - if(!deconstruction_ready) - return FALSE - else - return ..() - -/obj/structure/table/glass/reinforced/welder_act(mob/user, obj/item/I) - . = TRUE - if(!I.tool_use_check(user, 0)) - return - to_chat(user, "You start [deconstruction_ready ? "strengthening" : "weakening"] the reinforced table...") - if(I.use_tool(src, user, 50, volume = I.tool_volume)) - to_chat(user, "You [deconstruction_ready ? "strengthen" : "weaken"] the table.") - deconstruction_ready = !deconstruction_ready - -/obj/structure/table/glass/reinforced/shove_impact(mob/living/target, mob/living/attacker) - if(locate(/obj/structure/table) in get_turf(target)) - return FALSE - var/pass_flags_cache = target.pass_flags - target.pass_flags |= PASSTABLE - if(target.Move(loc)) - . = TRUE - target.Weaken(4 SECONDS) - add_attack_logs(attacker, target, "pushed onto [src]", ATKLOG_ALL) - else - . = FALSE - target.pass_flags = pass_flags_cache - -/obj/structure/table/glass/reinforced/check_break(mob/living/M) - if(has_gravity(M) && M.mob_size > MOB_SIZE_SMALL && (obj_integrity < (max_integrity / 2))) //big tables for big boys, only breaks under 50% hp - table_shatter(M) - -/obj/structure/table/glass/reinforced/plasma - name = "reinforced plasma glass table" - desc = "Seems a bit overkill for a table." - icon = 'icons/obj/smooth_structures/tables/rplasmaglass_table.dmi' - icon_state = "rplasmaglass_table-0" - base_icon_state = "rplasmaglass_table" - buildstack = /obj/item/stack/sheet/plasmarglass - max_integrity = 180 - shardtype = /obj/item/shard/plasma - -/obj/structure/table/glass/reinforced/titanium - name = "reinforced titanium glass table" - desc = "A very sleek looking glass table, neat!" - icon = 'icons/obj/smooth_structures/tables/titaniumglass_table.dmi' - icon_state = "titaniumglass_table-0" - base_icon_state = "titaniumglass_table" - buildstack = /obj/item/stack/sheet/titaniumglass - max_integrity = 180 - -/obj/structure/table/glass/reinforced/plastitanium - name = "reinforced plastitanium glass table" - desc = "The mother of all glass tables." - icon = 'icons/obj/smooth_structures/tables/plastitaniumglass_table.dmi' - icon_state = "plastitaniumglass_table-0" - base_icon_state = "plastitaniumglass_table" - buildstack = /obj/item/stack/sheet/plastitaniumglass - max_integrity = 200 - -/* - * Wooden tables - */ -/obj/structure/table/wood - name = "wooden table" - desc = "Do not apply fire to this. Rumour says it burns easily." - icon = 'icons/obj/smooth_structures/tables/wood_table.dmi' - icon_state = "wood_table-0" - base_icon_state = "wood_table" - flipped_table_icon_base = "wood" - frame = /obj/structure/table_frame/wood - framestack = /obj/item/stack/sheet/wood - buildstack = /obj/item/stack/sheet/wood - max_integrity = 70 - smoothing_groups = list(SMOOTH_GROUP_WOOD_TABLES) //Don't smooth with SMOOTH_GROUP_TABLES - canSmoothWith = list(SMOOTH_GROUP_WOOD_TABLES) - resistance_flags = FLAMMABLE - -/obj/structure/table/wood/narsie_act(total_override = TRUE) - if(!total_override) - ..() - -/// No specialties, Just a mapping object. -/obj/structure/table/wood/poker - name = "gambling table" - desc = "A seedy table for seedy dealings in seedy places." - icon = 'icons/obj/smooth_structures/tables/poker_table.dmi' - icon_state = "poker_table-0" - base_icon_state = "poker_table" - flipped_table_icon_base = "poker" - buildstack = /obj/item/stack/tile/carpet - -/obj/structure/table/wood/poker/narsie_act() - ..(FALSE) - -/* - * Fancy Tables - */ - -/obj/structure/table/wood/fancy - name = "fancy table" - desc = "A standard metal table frame covered with an amazingly fancy, patterned cloth." - icon = 'icons/obj/smooth_structures/tables/fancy/fancy_table.dmi' - icon_state = "fancy_table-0" - base_icon_state = "fancy_table" - flipped_table_icon_base = "fancy" - frame = /obj/structure/table_frame - framestack = /obj/item/stack/rods - buildstack = /obj/item/stack/tile/carpet - smoothing_groups = list(SMOOTH_GROUP_FANCY_WOOD_TABLES) //Don't smooth with SMOOTH_GROUP_TABLES or SMOOTH_GROUP_WOOD_TABLES - canSmoothWith = list(SMOOTH_GROUP_FANCY_WOOD_TABLES) - -/obj/structure/table/wood/fancy/flip(direction) - return FALSE - -/obj/structure/table/wood/fancy/Initialize(mapload) - . = ..() - QUEUE_SMOOTH(src) - -/obj/structure/table/wood/fancy/black - icon_state = "fancy_table_black-0" - base_icon_state = "fancy_table_black" - flipped_table_icon_base = "fancyblack" - buildstack = /obj/item/stack/tile/carpet/black - icon = 'icons/obj/smooth_structures/tables/fancy/fancy_table_black.dmi' - - -/obj/structure/table/wood/fancy/blue - icon_state = "fancy_table_blue-0" - base_icon_state = "fancy_table_blue" - buildstack = /obj/item/stack/tile/carpet/blue - icon = 'icons/obj/smooth_structures/tables/fancy/fancy_table_blue.dmi' - -/obj/structure/table/wood/fancy/cyan - icon_state = "fancy_table_cyan-0" - base_icon_state = "fancy_table_cyan" - buildstack = /obj/item/stack/tile/carpet/cyan - icon = 'icons/obj/smooth_structures/tables/fancy/fancy_table_cyan.dmi' - -/obj/structure/table/wood/fancy/green - icon_state = "fancy_table_green-0" - base_icon_state = "fancy_table_green" - buildstack = /obj/item/stack/tile/carpet/green - icon = 'icons/obj/smooth_structures/tables/fancy/fancy_table_green.dmi' - -/obj/structure/table/wood/fancy/orange - icon_state = "fancy_table_orange-0" - base_icon_state = "fancy_table_orange" - buildstack = /obj/item/stack/tile/carpet/orange - icon = 'icons/obj/smooth_structures/tables/fancy/fancy_table_orange.dmi' - -/obj/structure/table/wood/fancy/purple - icon_state = "fancy_table_purple-0" - base_icon_state = "fancy_table_purple" - buildstack = /obj/item/stack/tile/carpet/purple - icon = 'icons/obj/smooth_structures/tables/fancy/fancy_table_purple.dmi' - -/obj/structure/table/wood/fancy/red - icon_state = "fancy_table_red-0" - base_icon_state = "fancy_table_red" - buildstack = /obj/item/stack/tile/carpet/red - icon = 'icons/obj/smooth_structures/tables/fancy/fancy_table_red.dmi' - -/obj/structure/table/wood/fancy/royalblack - icon_state = "fancy_table_royalblack-0" - base_icon_state = "fancy_table_royalblack" - buildstack = /obj/item/stack/tile/carpet/royalblack - icon = 'icons/obj/smooth_structures/tables/fancy/fancy_table_royalblack.dmi' - - -/obj/structure/table/wood/fancy/royalblue - icon_state = "fancy_table_royalblue-0" - base_icon_state = "fancy_table_royalblue" - buildstack = /obj/item/stack/tile/carpet/royalblue - icon = 'icons/obj/smooth_structures/tables/fancy/fancy_table_royalblue.dmi' - -/* - * Reinforced tables - */ -/obj/structure/table/reinforced - name = "reinforced table" - desc = "A reinforced version of the four legged table." - icon = 'icons/obj/smooth_structures/tables/reinforced_table.dmi' - icon_state = "reinforced_table-0" - base_icon_state = "reinforced_table" - flipped_table_icon_base = "rtables" - deconstruction_ready = FALSE - buildstack = /obj/item/stack/sheet/plasteel - smoothing_groups = list(SMOOTH_GROUP_REINFORCED_TABLES) - canSmoothWith = list(SMOOTH_GROUP_REINFORCED_TABLES) - max_integrity = 200 - integrity_failure = 50 - armor = list(MELEE = 10, BULLET = 30, LASER = 30, ENERGY = 100, BOMB = 20, RAD = 0, FIRE = 80, ACID = 70) - -/obj/structure/table/reinforced/deconstruction_hints(mob/user) - if(deconstruction_ready) - to_chat(user, "The top cover has been welded loose and the main frame's bolts are exposed.") - else - to_chat(user, "The top cover is firmly welded on.") - -/obj/structure/table/reinforced/flip(direction) - if(!deconstruction_ready) - return 0 - else - return ..() - -/obj/structure/table/reinforced/welder_act(mob/user, obj/item/I) - if(!I.tool_use_check(user, 0)) - return - . = TRUE - to_chat(user, "You start [deconstruction_ready ? "strengthening" : "weakening"] the reinforced table...") - if(I.use_tool(src, user, 50, volume = I.tool_volume)) - to_chat(user, "You [deconstruction_ready ? "strengthen" : "weaken"] the table.") - deconstruction_ready = !deconstruction_ready - -/obj/structure/table/reinforced/brass - name = "brass table" - desc = "A solid, slightly beveled brass table." - icon = 'icons/obj/smooth_structures/tables/brass_table.dmi' - icon_state = "brass_table-0" - base_icon_state = "brass_table" - resistance_flags = FIRE_PROOF | ACID_PROOF - frame = /obj/structure/table_frame/brass - framestack = /obj/item/stack/tile/brass - buildstack = /obj/item/stack/tile/brass - framestackamount = 1 - buildstackamount = 1 - smoothing_groups = list(SMOOTH_GROUP_BRASS_TABLES) //Don't smooth with SMOOTH_GROUP_TABLES - canSmoothWith = list(SMOOTH_GROUP_BRASS_TABLES) - -/obj/structure/table/reinforced/brass/narsie_act() - take_damage(rand(15, 45), BRUTE) - if(src) //do we still exist? - var/previouscolor = color - color = "#960000" - animate(src, color = previouscolor, time = 8) - -/obj/structure/table/tray - name = "surgical instrument table" - desc = "A small metal tray with wheels." - anchored = FALSE - smoothing_flags = NONE - smoothing_groups = null - canSmoothWith = null - icon = 'icons/obj/stationobjs.dmi' - icon_state = "tray" - buildstack = /obj/item/stack/sheet/mineral/titanium - buildstackamount = 2 - can_be_flipped = FALSE - var/list/typecache_can_hold = list(/mob, /obj/item) - var/list/held_items = list() - -/obj/structure/table/tray/Initialize(mapload) - . = ..() - typecache_can_hold = typecacheof(typecache_can_hold) - for(var/atom/movable/held in get_turf(src)) - if(!held.anchored && held.move_resist != INFINITY && is_type_in_typecache(held, typecache_can_hold)) - held_items += held.UID() - -/obj/structure/table/tray/Move(NewLoc, direct) - var/atom/OldLoc = loc - - . = ..() - if(!.) // ..() will return 0 if we didn't actually move anywhere. - return - - if(direct & (direct - 1)) // This represents a diagonal movement, which is split into multiple cardinal movements. We'll handle moving the items on the cardinals only. - return - - playsound(loc, pick('sound/items/cartwheel1.ogg', 'sound/items/cartwheel2.ogg'), 100, TRUE, ignore_walls = FALSE) - - var/atom/movable/held - for(var/held_uid in held_items) - held = locateUID(held_uid) - if(!held) - held_items -= held_uid - continue - if(OldLoc != held.loc) - held_items -= held_uid - continue - held.forceMove(NewLoc) - -/obj/structure/table/tray/can_be_pulled(user, grab_state, force, show_message) - var/atom/movable/puller = user - if(loc != puller.loc) - held_items -= puller.UID() - if(isliving(user)) - var/mob/living/M = user - if(M.UID() in held_items) - return FALSE - return ..() - -/obj/structure/table/tray/item_placed(atom/movable/item) - . = ..() - if(is_type_in_typecache(item, typecache_can_hold)) - held_items += item.UID() - if(isliving(item)) - var/mob/living/M = item - if(M.pulling == src) - M.stop_pulling() - -/obj/structure/table/tray/deconstruct(disassembled = TRUE, wrench_disassembly = 0) - if(!(flags & NODECONSTRUCT)) - var/turf/T = get_turf(src) - new buildstack(T, buildstackamount) - qdel(src) - -/obj/structure/table/tray/deconstruction_hints(mob/user) - to_chat(user, "It is held together by some screws and bolts.") - -/obj/structure/table/tray/flip() - return 0 - -/obj/structure/table/tray/narsie_act() - return 0 - -/* - * Racks - */ -/obj/structure/rack - name = "rack" - desc = "Different from the Middle Ages version." - icon = 'icons/obj/objects.dmi' - icon_state = "rack" - layer = TABLE_LAYER - density = TRUE - anchored = TRUE - pass_flags_self = LETPASSTHROW | PASSTAKE - max_integrity = 20 - -/obj/structure/rack/examine(mob/user) - . = ..() - . += "It's held together by a couple of bolts." - -/obj/structure/rack/CanPass(atom/movable/mover, border_dir) - if(!density) //Because broken racks -Agouri |TODO: SPRITE!| - return 1 - if(istype(mover)) - if(mover.checkpass(PASSTABLE)) - return TRUE - var/mob/living/living_mover = mover - if(istype(living_mover) && IS_HORIZONTAL(living_mover) && HAS_TRAIT(living_mover, TRAIT_CONTORTED_BODY)) - return TRUE - if(mover.throwing) - return 1 - else - return 0 - -/obj/structure/rack/CanPathfindPass(to_dir, datum/can_pass_info/pass_info) - . = !density - if(pass_info.is_movable) - . = . || pass_info.pass_flags & PASSTABLE - -/obj/structure/rack/MouseDrop_T(obj/O, mob/user) - if((!isitem(O) || user.get_active_hand() != O)) - return - if(isrobot(user)) - return - if(!user.drop_item()) - return - if(O.loc != src.loc) - step(O, get_dir(O, src)) - return TRUE - -/obj/structure/rack/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(isrobot(user)) - return - if(user.a_intent == INTENT_HARM) - return ..() - if(!(W.flags & ABSTRACT)) - if(user.drop_item()) - W.Move(loc) - return - -/obj/structure/rack/wrench_act(mob/user, obj/item/I) - . = TRUE - if(flags & NODECONSTRUCT) - to_chat(user, "Try as you might, you can't figure out how to deconstruct this.") - return - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - deconstruct(TRUE) - -/obj/structure/rack/attack_hand(mob/living/user) - if(user.IsWeakened()) - return - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src, ATTACK_EFFECT_KICK) - user.visible_message("[user] kicks [src].", \ - "You kick [src].") - 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) - if(BRUTE) - if(damage_amount) - playsound(loc, 'sound/items/dodgeball.ogg', 80, TRUE) - else - playsound(loc, 'sound/weapons/tap.ogg', 50, TRUE) - if(BURN) - playsound(loc, 'sound/items/welder.ogg', 40, TRUE) - -/obj/structure/rack/skeletal_bar - name = "skeletal minibar" - desc = "Made with the skulls of the fallen." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "minibar" - -/obj/structure/rack/skeletal_bar/left - icon_state = "minibar_left" - -/obj/structure/rack/skeletal_bar/right - icon_state = "minibar_right" - -/* - * Rack destruction - */ - -/obj/structure/rack/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - density = FALSE - var/obj/item/rack_parts/newparts = new(loc) - transfer_fingerprints_to(newparts) - qdel(src) - -/* - * Rack Parts - */ - -/obj/item/rack_parts - name = "rack parts" - desc = "Parts of a rack." - icon = 'icons/obj/items.dmi' - icon_state = "rack_parts" - flags = CONDUCT - materials = list(MAT_METAL=2000) - var/building = FALSE - -/obj/item/rack_parts/wrench_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - new /obj/item/stack/sheet/metal(user.loc) - qdel(src) - -/obj/item/rack_parts/attack_self__legacy__attackchain(mob/user) - if(building) - return - building = TRUE - to_chat(user, "You start constructing a rack...") - if(do_after(user, 50, target = user, progress=TRUE)) - if(!user.drop_item(src)) - return - var/obj/structure/rack/R = new /obj/structure/rack(user.loc) - user.visible_message("[user] assembles \a [R].\ - ", "You assemble \a [R].") - R.add_fingerprint(user) - qdel(src) - building = FALSE diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm deleted file mode 100644 index e86d23a5d356d..0000000000000 --- a/code/game/objects/structures/tank_dispenser.dm +++ /dev/null @@ -1,157 +0,0 @@ -#define MAX_TANK_STORAGE 10 - -/obj/structure/dispenser - name = "tank storage unit" - desc = "A simple yet bulky storage device for gas tanks. Has room for up to ten oxygen tanks, and ten plasma tanks." - icon = 'icons/obj/objects.dmi' - icon_state = "dispenser" - density = TRUE - anchored = TRUE - var/starting_oxygen_tanks = MAX_TANK_STORAGE // The starting amount of oxygen tanks the dispenser gets when it's spawned - var/starting_plasma_tanks = MAX_TANK_STORAGE // Starting amount of plasma tanks - var/list/stored_oxygen_tanks = list() // List of currently stored oxygen tanks - var/list/stored_plasma_tanks = list() // And plasma tanks - -/obj/structure/dispenser/oxygen - starting_plasma_tanks = 0 - -/obj/structure/dispenser/plasma - starting_oxygen_tanks = 0 - -/obj/structure/dispenser/Initialize(mapload) - . = ..() - initialize_tanks() - update_icon(UPDATE_OVERLAYS) - -/obj/structure/dispenser/Destroy() - QDEL_LIST_CONTENTS(stored_plasma_tanks) - QDEL_LIST_CONTENTS(stored_oxygen_tanks) - return ..() - -/obj/structure/dispenser/proc/initialize_tanks() - for(var/I in 1 to starting_plasma_tanks) - var/obj/item/tank/internals/plasma/P = new(src) - stored_plasma_tanks.Add(P) - - for(var/I in 1 to starting_oxygen_tanks) - var/obj/item/tank/internals/oxygen/O = new(src) - stored_oxygen_tanks.Add(O) - -/obj/structure/dispenser/update_overlays() - . = ..() - var/oxy_tank_amount = LAZYLEN(stored_oxygen_tanks) - switch(oxy_tank_amount) - if(1 to 3) - . += "oxygen-[oxy_tank_amount]" - if(4 to INFINITY) - . += "oxygen-4" - - var/pla_tank_amount = LAZYLEN(stored_plasma_tanks) - switch(pla_tank_amount) - if(1 to 4) - . += "plasma-[pla_tank_amount]" - if(5 to INFINITY) - . += "plasma-5" - -/obj/structure/dispenser/attack_hand(mob/user) - if(..()) - return 1 - add_fingerprint(user) - ui_interact(user) - -/obj/structure/dispenser/attack_ai(mob/user) - if(isrobot(user) && Adjacent(user)) //Robots can use it, but not the AI - attack_hand(user) - -/obj/structure/dispenser/attack_ghost(mob/user) - ui_interact(user) - -/obj/structure/dispenser/ui_state(mob/user) - return GLOB.default_state - -/obj/structure/dispenser/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "TankDispenser", name) - ui.open() - -/obj/structure/dispenser/ui_data(user) - var/list/data = list() - data["o_tanks"] = LAZYLEN(stored_oxygen_tanks) - data["p_tanks"] = LAZYLEN(stored_plasma_tanks) - return data - -/obj/structure/dispenser/ui_act(action, list/params) - if(..()) - return - - switch(action) - if("oxygen") - try_remove_tank(usr, stored_oxygen_tanks) - - if("plasma") - try_remove_tank(usr, stored_plasma_tanks) - - add_fingerprint(usr) - return TRUE - -/obj/structure/dispenser/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(istype(I, /obj/item/tank/internals/oxygen) || istype(I, /obj/item/tank/internals/air) || istype(I, /obj/item/tank/internals/anesthetic)) - try_insert_tank(user, stored_oxygen_tanks, I) - return - - if(istype(I, /obj/item/tank/internals/plasma)) - try_insert_tank(user, stored_plasma_tanks, I) - return - return ..() - -/obj/structure/dispenser/wrench_act(mob/living/user, obj/item/I) - I.play_tool_sound(src, 50) - if(anchored) - to_chat(user, "You lean down and unwrench [src].") - anchored = FALSE - else - to_chat(user, "You wrench [src] into place.") - anchored = TRUE - return TRUE - - -/// Called when the user clicks on the oxygen or plasma tank UI buttons, and tries to withdraw a tank. -/obj/structure/dispenser/proc/try_remove_tank(mob/living/user, list/tank_list) - if(!LAZYLEN(tank_list)) - return // There are no tanks left to withdraw. - - var/obj/item/tank/internals/T = tank_list[1] - tank_list.Remove(T) - - if(!user.put_in_hands(T)) - T.forceMove(loc) // If the user's hands are full, place it on the tile of the dispenser. - - to_chat(user, "You take [T] out of [src].") - update_icon(UPDATE_OVERLAYS) - -/// Called when the user clicks on the dispenser with a tank. Tries to insert the tank into the dispenser, and updates the UI if successful. -/obj/structure/dispenser/proc/try_insert_tank(mob/living/user, list/tank_list, obj/item/tank/T) - if(LAZYLEN(tank_list) >= MAX_TANK_STORAGE) - to_chat(user, "[src] is full.") - return - - if(!user.drop_item()) // Antidrop check - to_chat(user, "[T] is stuck to your hand!") - return - - T.forceMove(src) - tank_list.Add(T) - update_icon(UPDATE_OVERLAYS) - to_chat(user, "You put [T] in [src].") - SStgui.update_uis(src) - -/obj/structure/dispenser/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - for(var/X in src) - var/obj/item/I = X - I.forceMove(loc) - new /obj/item/stack/sheet/metal(loc, 2) - qdel(src) - -#undef MAX_TANK_STORAGE diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm deleted file mode 100644 index 625a8a8ba919f..0000000000000 --- a/code/game/objects/structures/target_stake.dm +++ /dev/null @@ -1,54 +0,0 @@ -// Basically they are for the firing range -/obj/structure/target_stake - name = "target stake" - desc = "A thin platform with negatively-magnetized wheels." - icon = 'icons/obj/objects.dmi' - icon_state = "target_stake" - density = TRUE - flags = CONDUCT - var/obj/item/target/pinned_target // the current pinned target - -/obj/structure/target_stake/Destroy() - QDEL_NULL(pinned_target) - return ..() - -/obj/structure/target_stake/Move() - . = ..() - // Move the pinned target along with the stake - if(pinned_target in view(3, src)) - pinned_target.loc = loc - - else // Sanity check: if the pinned target can't be found in immediate view - pinned_target = null - density = TRUE - -/obj/structure/target_stake/attackby__legacy__attackchain(obj/item/W, mob/user, params) - // Putting objects on the stake. Most importantly, targets - if(istype(W, /obj/item/target) && !pinned_target) - density = FALSE - W.density = TRUE - user.drop_item(src) - W.loc = loc - W.layer = 3.1 - pinned_target = W - to_chat(user, "You slide the target into the stake.") - return - return ..() - -/obj/structure/target_stake/attack_hand(mob/user) - // taking pinned targets off! - if(pinned_target) - density = TRUE - pinned_target.density = FALSE - pinned_target.layer = OBJ_LAYER - - pinned_target.loc = user.loc - if(ishuman(user)) - if(!user.get_active_hand()) - user.put_in_hands(pinned_target) - to_chat(user, "You take the target out of the stake.") - else - pinned_target.loc = get_turf(user) - to_chat(user, "You take the target out of the stake.") - - pinned_target = null diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm deleted file mode 100644 index 70df8bf037cc6..0000000000000 --- a/code/game/objects/structures/transit_tubes/station.dm +++ /dev/null @@ -1,302 +0,0 @@ -#define CLOSE_DURATION 6 -#define OPEN_DURATION 6 -#define LAUNCH_COOLDOWN 50 - - -// A place where tube pods stop, and people can get in or out. -// Mappers: use "Generate Instances from Directions" for this -// one. -/obj/structure/transit_tube/station - name = "station tube station" - desc = "The lynchpin of the transit system." - icon = 'icons/obj/pipes/transit_tube_station.dmi' - icon_state = "closed_station0" - base_icon_state = "station0" - exit_delay = 1 - enter_delay = 2 - density = TRUE - uninstalled_type = /obj/structure/transit_tube_construction/station - var/pod_moving = FALSE - var/launch_cooldown = 0 - var/reverse_launch = FALSE - var/hatch_state = TRANSIT_TUBE_CLOSED - - var/list/disallowed_mobs = list(/mob/living/silicon/ai) - /// Direction by which you can board the tube - var/boarding_dir - -/obj/structure/transit_tube/station/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - -/obj/structure/transit_tube/station/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/structure/transit_tube/station/examine(mob/user) - . = ..() - . += "While in transit, hold the directional key matching the pod's direction to skip a station." - . += "While at a station, press a directional key to quickly leave the station in that direction." - -/obj/structure/transit_tube/station/init_tube_dirs() - // Tube station directions are simply 90 to either side of - // the exit. - switch(dir) - if(NORTH) - tube_dirs = list(EAST, WEST) - if(SOUTH) - tube_dirs = list(EAST, WEST) - if(EAST) - tube_dirs = list(NORTH, SOUTH) - if(WEST) - tube_dirs = list(NORTH, SOUTH) - boarding_dir = REVERSE_DIR(dir) - -/obj/structure/transit_tube/station/should_stop_pod(obj/structure/transit_tube_pod/pod, from_dir) - for(var/atom/atom in pod.contents) - var/client/client = CLIENT_FROM_VAR(atom) - if(!client) - return - - for(var/held_key in client.input_data.keys_held) - if(held_key in client.movement_kb_dirs) - var/held_dir = client.movement_kb_dirs[held_key] - // if they're holding a different direction down, - // stop to let them get out/change direction - return held_dir != from_dir - - return TRUE - -/obj/structure/transit_tube/station/Bumped(mob/living/L) - if(!pod_moving && L.dir == boarding_dir && hatch_state == TRANSIT_TUBE_OPEN && isliving(L) && !is_type_in_list(L, disallowed_mobs)) - for(var/obj/structure/transit_tube_pod/pod in loc) - if(length(pod.contents)) - to_chat(L, "The pod is already occupied.") - return - if(!pod.moving && ((pod.dir in directions()) || (reverse_launch && (turn(pod.dir, 180) in directions())))) - pod.move_into(L) - return - - - -/obj/structure/transit_tube/station/attack_hand(mob/user) - if(pod_moving) - return - var/obj/structure/transit_tube_pod/pod = locate() in loc - if(!pod) - return - // Can't get in moving pods. Or pods that have openings on the other side - if(pod.moving || !(pod.dir in directions())) - return - if(hatch_state != TRANSIT_TUBE_OPEN) - return - // Can't empty it when inside or when there is nothing inside - if(!length(pod.contents) || user.loc == pod) - return - user.visible_message("[user] starts emptying [pod]'s contents onto the floor!", \ - "You start emptying [pod]'s contents onto the floor.", "You hear a loud noise! As if somebody is throwing stuff on the floor!") - if(!do_after(user, 20, target = pod)) - return - for(var/atom/movable/AM in pod) - pod.eject(AM) - if(isliving(AM)) - var/mob/living/L = AM - L.Weaken(10 SECONDS) - - -/obj/structure/transit_tube/station/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(istype(W, /obj/item/grab) && hatch_state == TRANSIT_TUBE_OPEN) - var/obj/item/grab/G = W - if(ismob(G.affecting) && G.state >= GRAB_AGGRESSIVE) - var/mob/living/GM = G.affecting - for(var/obj/structure/transit_tube_pod/pod in loc) - pod.visible_message("[user] starts putting [GM] into [pod]!") - if(do_after(user, 30, target = GM) && GM && G && G.affecting == GM) - GM.Weaken(10 SECONDS) - Bumped(GM) - qdel(G) - break - -/obj/structure/transit_tube/station/proc/open_hatch() - if(hatch_state == TRANSIT_TUBE_CLOSED) - icon_state = "opening_[base_icon_state]" - hatch_state = TRANSIT_TUBE_OPENING - addtimer(CALLBACK(src, PROC_REF(finish_animation)), OPEN_DURATION) - -/obj/structure/transit_tube/station/proc/close_hatch() - if(hatch_state == TRANSIT_TUBE_OPEN) - icon_state = "closing_[base_icon_state]" - hatch_state = TRANSIT_TUBE_CLOSING - addtimer(CALLBACK(src, PROC_REF(finish_animation)), CLOSE_DURATION) - -/obj/structure/transit_tube/station/proc/finish_animation() - switch(hatch_state) - if(TRANSIT_TUBE_OPENING) - icon_state = "open_[base_icon_state]" - hatch_state = TRANSIT_TUBE_OPEN - for(var/obj/structure/transit_tube_pod/pod in loc) - for(var/thing in pod) - if(ismob(thing)) - var/mob/mob_content = thing - if(mob_content.client && mob_content.stat < UNCONSCIOUS) - continue // Let the mobs with clients decide what they want to do themselves. - var/atom/movable/movable_content = thing - movable_content.forceMove(loc) //Everything else is moved out of. - if(TRANSIT_TUBE_CLOSING) - icon_state = "closed_[base_icon_state]" - hatch_state = TRANSIT_TUBE_CLOSED - -/obj/structure/transit_tube/station/proc/launch_pod() - for(var/obj/structure/transit_tube_pod/pod in loc) - if(!pod.moving && ((pod.dir in directions()) || (reverse_launch && (turn(pod.dir, 180) in directions())))) - addtimer(CALLBACK(src, PROC_REF(launch_pod_callback), pod), 5) - return - -/obj/structure/transit_tube/station/proc/launch_pod_callback(obj/structure/transit_tube_pod/pod) - pod_moving = TRUE - close_hatch() - sleep(CLOSE_DURATION + 2) - - //reverse directions for automated cycling - var/turf/next_loc = get_step(loc, pod.dir) - var/obj/structure/transit_tube/nexttube - for(var/obj/structure/transit_tube/tube in next_loc) - if(tube.has_entrance(pod.dir)) - nexttube = tube - break - if(!nexttube) - pod.dir = turn(pod.dir, 180) - - if(hatch_state == TRANSIT_TUBE_CLOSED && pod && pod.loc == loc) - pod.follow_tube() - - pod_moving = FALSE - -/obj/structure/transit_tube/station/process() - if(!pod_moving && launch_cooldown <= world.time) - launch_pod() - -/obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir) - pod_moving = TRUE - pod.stop_following() - addtimer(CALLBACK(src, PROC_REF(pod_stopped_callback), pod), 5) - -/obj/structure/transit_tube/station/proc/pod_stopped_callback(obj/structure/transit_tube_pod/pod) - launch_cooldown = world.time + LAUNCH_COOLDOWN - open_hatch(pod) - sleep(OPEN_DURATION + 2) - pod.eject_mindless(dir) - pod_moving = FALSE - pod.mix_air() - -/obj/structure/transit_tube/station/flipped - icon_state = "closed_station1" - base_icon_state = "station1" - -/obj/structure/transit_tube/station/flipped/init_tube_dirs() - ..() - boarding_dir = dir - -// Stations which will send the tube in the opposite direction after their stop. -/obj/structure/transit_tube/station/reverse - icon_state = "closed_terminus0" - base_icon_state = "terminus0" - reverse_launch = TRUE - uninstalled_type = /obj/structure/transit_tube_construction/terminus - -/obj/structure/transit_tube/station/reverse/should_stop_pod(obj/structure/transit_tube_pod/pod, from_dir) - return TRUE - -/obj/structure/transit_tube/station/reverse/init_tube_dirs() - tube_dirs = list(turn(dir, -90)) - boarding_dir = REVERSE_DIR(dir) - -/obj/structure/transit_tube/station/reverse/flipped - icon_state = "closed_terminus1" - base_icon_state = "terminus1" - -/obj/structure/transit_tube/station/reverse/flipped/init_tube_dirs() - ..() - boarding_dir = dir - -//special dispenser station, it creates a pod for you to enter when you bump into it. - -/obj/structure/transit_tube/station/dispenser - name = "station tube pod dispenser" - icon_state = "open_dispenser0" - desc = "The lynchpin of a GOOD transit system." - enter_delay = 1 - base_icon_state = "dispenser0" - hatch_state = TRANSIT_TUBE_OPEN - uninstalled_type = /obj/structure/transit_tube_construction/station/dispenser - -/obj/structure/transit_tube/station/dispenser/examine(mob/user) - . = ..() - . += "This station will create a pod for you to ride, no need to wait for one." - . += "Any pods arriving at this station will be reclaimed." - -/obj/structure/transit_tube/station/dispenser/close_hatch() - . = ..() - return - -/obj/structure/transit_tube/station/dispenser/launch_pod() - for(var/obj/structure/transit_tube_pod/pod in loc) - if(!pod.moving) - pod_moving = TRUE - pod.follow_tube() - pod_moving = FALSE - return TRUE - return FALSE - -/obj/structure/transit_tube/station/dispenser/Bumped(mob/living/L) - if(!(istype(L) && L.dir == boarding_dir) || L.anchored) - return - - if(isliving(L) && !is_type_in_list(L, disallowed_mobs)) - var/obj/structure/transit_tube_pod/dispensed/pod = new(loc) - L.visible_message("[pod] forms around [L].", "[pod] materializes around you.") - playsound(src, 'sound/weapons/emitter2.ogg', 50, TRUE) - pod.dir = turn(dir, -90) - pod.move_into(L) - launch_pod() - -/obj/structure/transit_tube/station/dispenser/pod_stopped(obj/structure/transit_tube_pod/pod) - playsound(src, 'sound/machines/ding.ogg', 50, TRUE) - qdel(pod) - - -/obj/structure/transit_tube/station/dispenser/flipped - icon_state = "open_dispenser1" - base_icon_state = "dispenser1" - -/obj/structure/transit_tube/station/dispenser/flipped/init_tube_dirs() - ..() - boarding_dir = dir - - -/obj/structure/transit_tube/station/dispenser/reverse - reverse_launch = TRUE - icon_state = "open_terminusdispenser0" - base_icon_state = "terminusdispenser0" - uninstalled_type = /obj/structure/transit_tube_construction/terminus/dispenser - -/obj/structure/transit_tube/station/dispenser/reverse/should_stop_pod(obj/structure/transit_tube_pod/pod, from_dir) - return TRUE - -/obj/structure/transit_tube/station/dispenser/reverse/init_tube_dirs() - tube_dirs = list(turn(dir, -90)) - boarding_dir = REVERSE_DIR(dir) - -/obj/structure/transit_tube/station/dispenser/reverse/flipped - icon_state = "open_terminusdispenser1" - base_icon_state = "terminusdispenser1" - -/obj/structure/transit_tube/station/dispenser/reverse/flipped/init_tube_dirs() - ..() - boarding_dir = dir - - - -#undef CLOSE_DURATION -#undef OPEN_DURATION -#undef LAUNCH_COOLDOWN diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm deleted file mode 100644 index b5612911dd130..0000000000000 --- a/code/game/objects/structures/transit_tubes/transit_tube.dm +++ /dev/null @@ -1,276 +0,0 @@ - -// Basic transit tubes. Straight pieces, curved sections, -// and basic splits/joins (no routing logic). -// Mappers: you can use "Generate Instances from Icon-states" -// to get the different pieces. -/obj/structure/transit_tube - name = "transit tube" - desc = "A pneumatic tube that brings you from here to there." - icon = 'icons/obj/pipes/transit_tube.dmi' - icon_state = "straight" - density = FALSE - layer = 3.1 - anchored = TRUE - var/list/tube_dirs = null - var/exit_delay = 1 - var/enter_delay = 0 - var/uninstalled_type = /obj/structure/transit_tube_construction/straight - -/obj/structure/transit_tube/Initialize(mapload, new_direction) - . = ..() - if(new_direction) - setDir(new_direction) - // set up our appearance after the initialize in case someone's setting our direction afterwards - // (especially for things like admin spawning) - addtimer(CALLBACK(src, PROC_REF(setup_appearance)), 1) - -/obj/structure/transit_tube/proc/setup_appearance() - init_tube_dirs() - update_appearance() - -/obj/structure/transit_tube/Destroy() - for(var/obj/structure/transit_tube_pod/P in loc) - P.empty_pod() - return ..() - -/obj/structure/transit_tube/CanPass(atom/movable/mover, border_dir) - if(istype(mover) && mover.checkpass(PASSGLASS)) - return TRUE - return !density - -// When destroyed by explosions, properly handle contents. -/obj/structure/transit_tube/ex_act(severity) - switch(severity) - if(EXPLODE_DEVASTATE) - for(var/atom/movable/AM in contents) - AM.loc = loc - AM.ex_act(severity++) - - deconstruct(disassembled = FALSE) - if(EXPLODE_HEAVY) - if(prob(50)) - for(var/atom/movable/AM in contents) - AM.loc = loc - AM.ex_act(severity++) - - deconstruct(disassembled = FALSE) - if(EXPLODE_LIGHT) - return - -// Called to check if a pod should stop upon entering this tube. -/obj/structure/transit_tube/proc/should_stop_pod(obj/structure/transit_tube_pod/pod, from_dir) - return FALSE - -// Called when a pod stops in this tube section. -/obj/structure/transit_tube/proc/pod_stopped(pod, from_dir) - return - - -// Returns a /list of directions this tube section can connect to. -// Tubes that have some sort of logic or changing direction might -// override it with additional logic. -/obj/structure/transit_tube/proc/directions() - return tube_dirs - - - -/obj/structure/transit_tube/proc/has_entrance(from_dir) - from_dir = turn(from_dir, 180) - - for(var/direction in directions()) - if(direction == from_dir) - return TRUE - - return FALSE - - - -/obj/structure/transit_tube/proc/has_exit(in_dir) - for(var/direction in directions()) - if(direction == in_dir) - return TRUE - - return FALSE - - - -// Searches for an exit direction within 45 degrees of the -// specified dir. Returns that direction, or 0 if none match. -/obj/structure/transit_tube/proc/get_exit(in_dir) - var/near_dir = 0 - var/in_dir_cw = turn(in_dir, -45) - var/in_dir_ccw = turn(in_dir, 45) - - for(var/direction in directions()) - if(direction == in_dir) - return direction - - else if(direction == in_dir_cw) - near_dir = direction - - else if(direction == in_dir_ccw) - near_dir = direction - - return near_dir - - -// Return how many BYOND ticks to wait before entering/exiting -// the tube section. Default action is to return the value of -// a var, which wouldn't need a proc, but it makes it possible -// for later tube types to interact in more interesting ways -// such as being very fast in one direction, but slow in others -/obj/structure/transit_tube/proc/exit_delay(pod, to_dir) - return exit_delay - -/obj/structure/transit_tube/proc/enter_delay(pod, to_dir) - return enter_delay - -/obj/structure/transit_tube/proc/init_tube_dirs() - switch(dir) - if(NORTH, SOUTH) - tube_dirs = list(NORTH, SOUTH) - if(EAST, WEST) - tube_dirs = list(EAST, WEST) - -/obj/structure/transit_tube/update_overlays() - . = ..() - for(var/direction in directions()) - if(!IS_DIR_DIAGONAL(direction)) - . += create_tube_overlay(direction) - continue - if(!(direction & NORTH)) - continue - - . += create_tube_overlay(direction ^ (NORTH|SOUTH), NORTH) - if(direction & EAST) - . += create_tube_overlay(direction ^ (EAST|WEST), EAST) - else - . += create_tube_overlay(direction ^ (EAST|WEST), WEST) - -/obj/structure/transit_tube/wrench_act(mob/living/user, obj/item/I) - . = TRUE - to_chat(user, "You must uninstall [src] before disassembling it!") - -/obj/structure/transit_tube/screwdriver_act(mob/living/user, obj/item/I) - var/obj/structure/transit_tube_construction/construction = new uninstalled_type(get_turf(src)) - if(!istype(construction)) - CRASH("expected [construction] to be a transit_tube construction") - . = TRUE - - var/leaf = copytext("[type]", (findlasttext("[type]", "/") + 1)) - construction.dir = dir - if(leaf == "flipped") - construction.flip() - - user.visible_message("[user] uninstalls [src].") - qdel(src) - -/obj/structure/transit_tube/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT) && !disassembled) - playsound(src, "shatter", 70, TRUE) - new /obj/effect/decal/cleanable/glass(loc) - qdel(src) - - -/obj/structure/transit_tube/proc/create_tube_overlay(direction, shift_dir) - // We use image() because a mutable appearance will have its dir mirror the parent which sort of fucks up what we're doing here - var/image/tube_overlay = image(icon, dir = direction) - if(shift_dir) - tube_overlay.icon_state = "decorative_diag" - switch(shift_dir) - if(NORTH) - tube_overlay.pixel_y = 32 - if(SOUTH) - tube_overlay.pixel_y = -32 - if(EAST) - tube_overlay.pixel_x = 32 - if(WEST) - tube_overlay.pixel_x = -32 - else - tube_overlay.icon_state = "decorative" - - tube_overlay.overlays += emissive_blocker(icon, tube_overlay.icon_state, src) - return tube_overlay - -//Some of these are mostly for mapping use -/obj/structure/transit_tube/horizontal - dir = WEST - - -/obj/structure/transit_tube/diagonal - icon_state = "diagonal" - uninstalled_type = /obj/structure/transit_tube_construction/diagonal - -/obj/structure/transit_tube/diagonal/init_tube_dirs() - switch(dir) - if(NORTH) - tube_dirs = list(NORTHEAST, SOUTHWEST) - if(SOUTH) - tube_dirs = list(NORTHEAST, SOUTHWEST) - if(EAST) - tube_dirs = list(NORTHWEST, SOUTHEAST) - if(WEST) - tube_dirs = list(NORTHWEST, SOUTHEAST) - -//mostly for mapping use -/obj/structure/transit_tube/diagonal/topleft - dir = WEST - -/obj/structure/transit_tube/curved - icon_state = "curved0" - uninstalled_type = /obj/structure/transit_tube_construction/curved - -/obj/structure/transit_tube/curved/init_tube_dirs() - switch(dir) - if(NORTH) - tube_dirs = list(NORTH, SOUTHWEST) - if(SOUTH) - tube_dirs = list(SOUTH, NORTHEAST) - if(EAST) - tube_dirs = list(EAST, NORTHWEST) - if(WEST) - tube_dirs = list(SOUTHEAST, WEST) - -/obj/structure/transit_tube/curved/flipped - icon_state = "curved1" - -/obj/structure/transit_tube/curved/flipped/init_tube_dirs() - switch(dir) - if(NORTH) - tube_dirs = list(NORTH, SOUTHEAST) - if(SOUTH) - tube_dirs = list(SOUTH, NORTHWEST) - if(EAST) - tube_dirs = list(EAST, SOUTHWEST) - if(WEST) - tube_dirs = list(NORTHEAST, WEST) - - -/obj/structure/transit_tube/junction - icon_state = "junction0" - uninstalled_type = /obj/structure/transit_tube_construction/junction - -/obj/structure/transit_tube/junction/init_tube_dirs() - switch(dir) - if(NORTH) - tube_dirs = list(NORTH, SOUTHEAST, SOUTHWEST)//ending with the prefered direction - if(SOUTH) - tube_dirs = list(SOUTH, NORTHWEST, NORTHEAST) - if(EAST) - tube_dirs = list(EAST, SOUTHWEST, NORTHWEST) - if(WEST) - tube_dirs = list(WEST, NORTHEAST, SOUTHEAST) - -/obj/structure/transit_tube/junction/flipped - icon_state = "junction1" - -/obj/structure/transit_tube/junction/flipped/init_tube_dirs() - switch(dir) - if(NORTH) - tube_dirs = list(NORTH, SOUTHWEST, SOUTHEAST)//ending with the prefered direction - if(SOUTH) - tube_dirs = list(SOUTH, NORTHEAST, NORTHWEST) - if(EAST) - tube_dirs = list(EAST, NORTHWEST, SOUTHWEST) - if(WEST) - tube_dirs = list(WEST, SOUTHEAST, NORTHEAST) diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm deleted file mode 100644 index 23ab76e665557..0000000000000 --- a/code/game/objects/structures/windoor_assembly.dm +++ /dev/null @@ -1,384 +0,0 @@ -/* Windoor (window door) assembly -Nodrak //I hope you step on a plug - * Step 1: Create a windoor out of rglass - * Step 2: Add plasteel to the assembly to make a secure windoor (Optional) - * Step 3: Rotate or Flip the assembly to face and open the way you want - * Step 4: Wrench the assembly in place - * Step 5: Add cables to the assembly - * Step 6: Set access for the door. - * Step 7: Crowbar the door to complete - */ - -#define EMPTY_ASSEMBLY "01" -#define WIRED_ASSEMBLY "02" - -/obj/structure/windoor_assembly - icon = 'icons/obj/doors/windoor.dmi' - name = "windoor assembly" - icon_state = "l_windoor_assembly01" - desc = "A small glass and wire assembly for windoors." - anchored = FALSE - density = FALSE - dir = NORTH - max_integrity = 300 - var/ini_dir - var/obj/item/airlock_electronics/electronics - var/created_name - var/polarized_glass = FALSE - - //Vars to help with the icon's name - var/facing = "l" //Does the windoor open to the left or right? - var/secure = FALSE //Whether or not this creates a secure windoor - var/state = EMPTY_ASSEMBLY //How far the door assembly has progressed - -/obj/structure/windoor_assembly/examine(mob/user) - . = ..() - switch(state) - if(EMPTY_ASSEMBLY) - if(anchored) - . += "The anchoring bolts are wrenched in place, but the maintenance panel lacks wiring." - else - . += "The assembly is welded together, but the anchoring bolts are unwrenched." - if(!secure) - . += "The frame has empty slots for plasteel reinforcements." - if(WIRED_ASSEMBLY) - if(electronics) - . += "The circuit is connected to its slot, but the windoor is not lifted into the frame." - . += "The assembly has its electrochromic panel [polarized_glass ? "enabled" : "disabled"] and can be configured." - else - . += "The maintenance panel is wired, but the circuit slot is empty." - - . += "Alt-Click to rotate it." - . += "Alt-Shift-Click to flip it." - -/obj/structure/windoor_assembly/Initialize(mapload, set_dir) - . = ..() - if(set_dir) - dir = set_dir - ini_dir = dir - var/static/list/loc_connections = list( - COMSIG_ATOM_EXIT = PROC_REF(on_atom_exit), - ) - - AddElement(/datum/element/connect_loc, loc_connections) - - recalculate_atmos_connectivity() - -/obj/structure/windoor_assembly/Destroy() - density = FALSE - QDEL_NULL(electronics) - recalculate_atmos_connectivity() - return ..() - -/obj/structure/windoor_assembly/Move() - var/turf/T = loc - . = ..() - setDir(ini_dir) - move_update_air(T) - -/obj/structure/windoor_assembly/update_icon_state() - icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[state]" - -/obj/structure/windoor_assembly/CanPass(atom/movable/mover, border_dir) - if(istype(mover) && mover.checkpass(PASSGLASS)) - return 1 - if(border_dir == dir) //Make sure looking at appropriate border - return !density - if(istype(mover, /obj/structure/window)) - 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/windoor_assembly/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 TRUE - -/obj/structure/windoor_assembly/CanAtmosPass(direction) - if(direction == dir) - return !density - else - return TRUE - -/obj/structure/windoor_assembly/proc/on_atom_exit(datum/source, atom/movable/leaving, direction) - SIGNAL_HANDLER // COMSIG_ATOM_EXIT - - if(istype(leaving) && leaving.checkpass(PASSGLASS)) - return - if(direction == dir && density) - return COMPONENT_ATOM_BLOCK_EXIT - -/obj/structure/windoor_assembly/attackby__legacy__attackchain(obj/item/W, mob/user, params) - //I really should have spread this out across more states but thin little windoors are hard to sprite. - add_fingerprint(user) - switch(state) - if(EMPTY_ASSEMBLY) - //Adding plasteel makes the assembly a secure windoor assembly. Step 2 (optional) complete. - if(istype(W, /obj/item/stack/sheet/plasteel) && !secure) - var/obj/item/stack/sheet/plasteel/P = W - if(P.get_amount() < 2) - to_chat(user, "You need more plasteel to do this!") - return - to_chat(user, "You start to reinforce the windoor with plasteel...") - - if(do_after(user, 40 * P.toolspeed, target = src)) - if(!src || secure || P.get_amount() < 2) - return - playsound(loc, P.usesound, 100, 1) - - P.use(2) - to_chat(user, "You reinforce the windoor.") - secure = TRUE - if(anchored) - name = "secure anchored windoor assembly" - else - name = "secure windoor assembly" - - //Adding cable to the assembly. Step 5 complete. - else if(iscoil(W) && anchored) - user.visible_message("[user] wires the windoor assembly.", "You start to wire the windoor assembly...") - - if(do_after(user, 40 * W.toolspeed, target = src)) - if(!src || !anchored || state != EMPTY_ASSEMBLY) - return - var/obj/item/stack/cable_coil/CC = W - CC.use(1) - to_chat(user, "You wire the windoor.") - playsound(loc, CC.usesound, 100, 1) - state = WIRED_ASSEMBLY - if(secure) - name = "secure wired windoor assembly" - else - name = "wired windoor assembly" - else - return ..() - - if(WIRED_ASSEMBLY) - //Adding airlock electronics for access. Step 6 complete. - if(istype(W, /obj/item/airlock_electronics) && !istype(W, /obj/item/airlock_electronics/destroyed)) - playsound(loc, W.usesound, 100, 1) - user.visible_message("[user] installs the electronics into the windoor assembly.", "You start to install electronics into the windoor assembly...") - user.drop_item() - W.forceMove(src) - var/obj/item/airlock_electronics/new_electronics = W - - if(do_after(user, 40 * new_electronics.toolspeed, target = src) && !new_electronics.is_installed) - if(!src || electronics) - new_electronics.forceMove(loc) - return - to_chat(user, "You install the windoor electronics.") - name = "near finished windoor assembly" - electronics = new_electronics - electronics.is_installed = TRUE - else - new_electronics.forceMove(loc) - - else if(is_pen(W)) - var/t = rename_interactive(user, W) - if(!isnull(t)) - created_name = t - return - else - return ..() - - //Update to reflect changes(if applicable) - update_icon(UPDATE_ICON_STATE) - -/obj/structure/windoor_assembly/crowbar_act(mob/user, obj/item/I) //Crowbar to complete the assembly, Step 7 complete. - if(state != WIRED_ASSEMBLY) - return - . = TRUE - if(!electronics) - to_chat(user, "[src] is missing electronics!") - return - if(!I.tool_use_check(user, 0)) - return - user << browse(null, "window=windoor_access") - user.visible_message("[user] pries the windoor into the frame.", "You start prying the windoor into the frame...") - - if(!I.use_tool(src, user, 40, volume = I.tool_volume)) - return - if(loc && electronics) - for(var/obj/machinery/door/window/WD in loc) - if(WD.dir == dir) - return - - density = TRUE //Shouldn't matter but just incase - to_chat(user, "You finish the windoor.") - var/obj/machinery/door/window/windoor - if(secure) - windoor = new /obj/machinery/door/window/brigdoor(src.loc) - if(facing == "l") - windoor.icon_state = "leftsecureopen" - windoor.base_state = "leftsecure" - else - windoor.icon_state = "rightsecureopen" - windoor.base_state = "rightsecure" - else - windoor = new /obj/machinery/door/window(loc) - if(facing == "l") - windoor.icon_state = "leftopen" - windoor.base_state = "left" - else - windoor.icon_state = "rightopen" - windoor.base_state = "right" - windoor.setDir(dir) - windoor.density = FALSE - windoor.polarized_glass = polarized_glass - - if(electronics.one_access) - windoor.req_one_access = electronics.selected_accesses - else - windoor.req_access = electronics.selected_accesses - windoor.unres_sides = electronics.unres_access_from - windoor.electronics = src.electronics - electronics.forceMove(windoor) - electronics = null - if(created_name) - windoor.name = created_name - qdel(src) - windoor.close() - -/obj/structure/windoor_assembly/screwdriver_act(mob/user, obj/item/I) - if(state != WIRED_ASSEMBLY || !electronics) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - user.visible_message("[user] removes the electronics from the windoor assembly.", "You start to uninstall the electronics from the windoor assembly...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume)) - return - to_chat(user, "You remove the airlock electronics.") - name = "wired windoor assembly" - var/obj/item/airlock_electronics/ae - ae = electronics - electronics = null - ae.forceMove(loc) - ae.is_installed = FALSE - -/obj/structure/windoor_assembly/wirecutter_act(mob/user, obj/item/I) - if(state != WIRED_ASSEMBLY) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - user.visible_message("[user] cuts the wires from the windoor assembly.", "You start to cut the wires from windoor assembly...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state != WIRED_ASSEMBLY) - return - to_chat(user, "You cut the windoor wires.") - new/obj/item/stack/cable_coil(get_turf(user), 1) - state = EMPTY_ASSEMBLY - if(secure) - name = "secure anchored windoor assembly" - else - name = "anchored windoor assembly" - update_icon(UPDATE_ICON_STATE) - -/obj/structure/windoor_assembly/wrench_act(mob/user, obj/item/I) - if(state != EMPTY_ASSEMBLY) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - if(!anchored) //Wrenching an unsecure assembly anchors it in place. Step 4 complete - for(var/obj/machinery/door/window/WD in loc) - if(WD.dir == dir) - to_chat(user, "There is already a windoor in that location!") - return - user.visible_message("[user] secures the windoor assembly to the floor.", "You start to secure the windoor assembly to the floor...") - - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || anchored || state != EMPTY_ASSEMBLY) - return - for(var/obj/machinery/door/window/WD in loc) - if(WD.dir == dir) - to_chat(user, "There is already a windoor in that location!") - return - to_chat(user, "You secure the windoor assembly.") - anchored = TRUE - if(secure) - name = "secure anchored windoor assembly" - else - name = "anchored windoor assembly" - - else //Unwrenching an unsecure assembly un-anchors it. Step 4 undone - user.visible_message("[user] unsecures the windoor assembly from the floor.", "You start to unsecure the windoor assembly from the floor...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || !anchored || state != EMPTY_ASSEMBLY) - return - to_chat(user, "You unsecure the windoor assembly.") - anchored = FALSE - if(secure) - name = "secure windoor assembly" - else - name = "windoor assembly" - update_icon(UPDATE_ICON_STATE) - -/obj/structure/windoor_assembly/welder_act(mob/user, obj/item/I) - if(state != EMPTY_ASSEMBLY) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - WELDER_ATTEMPT_SLICING_MESSAGE - if(I.use_tool(src, user, 40, volume = I.tool_volume) && state == EMPTY_ASSEMBLY) - WELDER_FLOOR_SLICE_SUCCESS_MESSAGE - var/obj/item/stack/sheet/rglass/RG = new (get_turf(src), 5) - RG.add_fingerprint(user) - if(secure) - var/obj/item/stack/rods/R = new (get_turf(src), 4) - R.add_fingerprint(user) - qdel(src) - - -/obj/structure/windoor_assembly/multitool_act(mob/user, obj/item/I) - if(state != WIRED_ASSEMBLY) - return - . = TRUE - if(!electronics) - to_chat(user, "[src] is missing electronics!") - return - if(!I.tool_use_check(user, 0)) - return - user.visible_message("[user] is configuring the glass panel in the windoor assembly...", "You start to configure the glass panel in the airlock assembly...") - if(!I.use_tool(src, user, 4 SECONDS, volume = I.tool_volume) || !electronics) - return - - polarized_glass = !polarized_glass - - to_chat(user, "You [polarized_glass ? "enable" : "disable"] the electrochromic panel in the windoor assembly.") - - -/obj/structure/windoor_assembly/AltClick(mob/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) - return - - if(anchored) - to_chat(user, "[src] cannot be rotated while it is fastened to the floor!") - return - var/target_dir = turn(dir, 90) - - if(!valid_window_location(loc, target_dir)) - to_chat(user, "[src] cannot be rotated in that direction!") - return - - setDir(target_dir) - - ini_dir = dir - update_icon(UPDATE_ICON_STATE) - -//Flips the windoor assembly, determines whather the door opens to the left or the right -/obj/structure/windoor_assembly/AltShiftClick(mob/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) - return - - if(facing == "l") - to_chat(user, "The windoor will now slide to the right.") - facing = "r" - else - facing = "l" - to_chat(user, "The windoor will now slide to the left.") - - update_icon(UPDATE_ICON_STATE) - -#undef EMPTY_ASSEMBLY -#undef WIRED_ASSEMBLY diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm deleted file mode 100644 index a8165ed08823c..0000000000000 --- a/code/game/turfs/simulated/floor.dm +++ /dev/null @@ -1,268 +0,0 @@ -//This is so damaged or burnt tiles or platings don't get remembered as the default tile -GLOBAL_LIST_INIT(icons_to_ignore_at_floor_init, list("damaged1","damaged2","damaged3","damaged4", - "damaged5","panelscorched","floorscorched1","floorscorched2","platingdmg1","platingdmg2", - "platingdmg3","plating","light_on","warnplate", "warnplatecorner","metalfoam", "ironfoam", - "light_off","grass1","grass2","grass3","grass4", - "asteroid","asteroid_dug","asteroid0","asteroid1","asteroid2","asteroid3","asteroid4", - "asteroid5","asteroid6","asteroid7","asteroid8","asteroid9","asteroid10","asteroid11","asteroid12", - "oldburning","light-on-r","light-on-y","light-on-g","light-on-b", "wood", "wood-broken", "carpet", - "carpetcorner", "carpetside", "carpet", "ironsand1", "ironsand2", "ironsand3", "ironsand4", "ironsand5", - "ironsand6", "ironsand7", "ironsand8", "ironsand9", "ironsand10", "ironsand11", - "ironsand12", "ironsand13", "ironsand14", "ironsand15")) - -/turf/simulated/floor - name = "floor" - icon = 'icons/turf/floors.dmi' - icon_state = "dont_use_this_floor" - plane = FLOOR_PLANE - var/icon_regular_floor = "floor" //used to remember what icon the tile should have by default - var/icon_plating = "plating" - thermal_conductivity = 0.020 - heat_capacity = 100000 - var/broken = FALSE - var/burnt = FALSE - var/current_overlay = null - var/floor_tile = null //tile that this floor drops - var/keep_dir = TRUE //When false, resets dir to default on changeturf() - - var/footstep = FOOTSTEP_FLOOR - var/barefootstep = FOOTSTEP_HARD_BAREFOOT - var/clawfootstep = FOOTSTEP_HARD_CLAW - var/heavyfootstep = FOOTSTEP_GENERIC_HEAVY - -/turf/simulated/floor/Initialize(mapload) - . = ..() - if(icon_state in GLOB.icons_to_ignore_at_floor_init) //so damaged/burned tiles or plating icons aren't saved as the default - icon_regular_floor = "floor" - else - icon_regular_floor = icon_state - -/turf/simulated/floor/ex_act(severity) - if(is_shielded()) - return - switch(severity) - if(1.0) - ChangeTurf(baseturf, keep_icon = FALSE) // we do not keep the icon so that asteroid platings can work properly - if(2.0) - switch(pick(1,2;75,3)) - if(1) - spawn(0) - ReplaceWithLattice() - if(prob(33)) new /obj/item/stack/sheet/metal(src) - if(2) - ChangeTurf(baseturf) - if(3) - if(prob(80)) - break_tile_to_plating() - else - break_tile() - hotspot_expose(1000, 100) - if(prob(33)) new /obj/item/stack/sheet/metal(src) - if(3.0) - if(prob(50)) - break_tile() - hotspot_expose(1000, 100) - return - -/turf/simulated/floor/burn_down() - ex_act(EXPLODE_HEAVY) - -/turf/simulated/floor/is_shielded() - for(var/obj/structure/A in contents) - if(A.level == 3) - return 1 - -// Checks if the turf is safe to be on -/turf/simulated/floor/is_safe() - var/datum/gas_mixture/Z = get_readonly_air() - var/pressure = Z.return_pressure() - // Can most things breathe and tolerate the temperature and pressure? - if(Z.oxygen() < 16 || Z.toxins() >= 0.05 || Z.carbon_dioxide() >= 10 || Z.sleeping_agent() >= 1 || (Z.temperature() <= 270) || (Z.temperature() >= 360) || (pressure <= 20) || (pressure >= 550)) - return FALSE - return TRUE - -// Checks if there is foothold over the turf -/turf/simulated/floor/proc/find_safeties() - var/static/list/safeties_typecache = typecacheof(list( - /obj/structure/lattice/catwalk, - /obj/structure/stone_tile, - /obj/structure/bridge_walkway - )) - var/list/found_safeties = typecache_filter_list(contents, safeties_typecache) - return LAZYLEN(found_safeties) - -/turf/simulated/floor/blob_act(obj/structure/blob/B) - return - -/turf/simulated/floor/update_overlays() - . = ..() - update_visuals() - if(current_overlay) - . += current_overlay - -/turf/simulated/floor/proc/break_tile_to_plating() - var/turf/simulated/floor/plating/T = make_plating() - T.break_tile() - -/turf/simulated/floor/break_tile() - if(broken) - return - current_overlay = pick(get_broken_states()) - broken = TRUE - update_icon() - -/turf/simulated/floor/burn_tile() - if(burnt) - return - current_overlay = pick(get_burnt_states()) - burnt = TRUE - update_icon() - -/turf/simulated/floor/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST && prob(1)) - burn_tile() - -/turf/simulated/floor/proc/make_plating() - return ChangeTurf(/turf/simulated/floor/plating) - -/turf/simulated/floor/ChangeTurf(turf/simulated/floor/T, defer_change = FALSE, keep_icon = TRUE, ignore_air = FALSE, copy_existing_baseturf = TRUE) - if(!isfloorturf(src)) - return ..() //fucking turfs switch the fucking src of the fucking running procs - if(!ispath(T, /turf/simulated/floor)) - return ..() - - var/old_icon = icon_regular_floor - var/old_plating = icon_plating - var/old_dir = dir - var/old_transparent_floor = transparent_floor - - var/turf/simulated/floor/W = ..() - - var/obj/machinery/atmospherics/R - var/obj/machinery/power/terminal/term - - if(keep_icon) - W.icon_regular_floor = old_icon - W.icon_plating = old_plating - if(W.keep_dir) - W.dir = old_dir - if(W.transparent_floor != old_transparent_floor) - for(R in W) - R.update_icon() - for(term in W) - term.update_icon() - for(R in W) - R.update_underlays() - W.update_icon() - return W - -/turf/simulated/floor/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(..() || QDELETED(used) || QDELETED(user)) - return ITEM_INTERACT_COMPLETE - - if((intact || transparent_floor) && istype(used, /obj/item/stack/tile)) - try_replace_tile(used, user, modifiers) - return ITEM_INTERACT_COMPLETE - - if(istype(used, /obj/item/pipe)) - var/obj/item/pipe/P = used - if(P.pipe_type != -1) // ANY PIPE - user.visible_message( \ - "[user] starts sliding [P] along \the [src].", \ - "You slide [P] along \the [src].", \ - "You hear the scrape of metal against something.") - user.drop_item() - - if(P.is_bent_pipe()) // bent pipe rotation fix see construction.dm - P.dir = 5 - if(user.dir == 1) - P.dir = 6 - else if(user.dir == 2) - P.dir = 9 - else if(user.dir == 4) - P.dir = 10 - else - P.setDir(user.dir) - - P.x = src.x - P.y = src.y - P.z = src.z - P.forceMove(src) - return ITEM_INTERACT_COMPLETE - -/turf/simulated/floor/crowbar_act(mob/user, obj/item/I) - if(!intact) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - pry_tile(I, user, TRUE) - -/turf/simulated/floor/proc/try_replace_tile(obj/item/stack/tile/T, mob/user, params) - if(T.turf_type == type) - return - var/obj/item/thing = user.get_inactive_hand() - if(!thing || !(thing.tool_behaviour in get_prying_tools())) - return - var/turf/simulated/floor/plating/P = pry_tile(thing, user, TRUE) - if(!istype(P)) - return - P.item_interaction(user, T, params) - -/turf/simulated/floor/proc/pry_tile(obj/item/C, mob/user, silent = FALSE) - if(!silent) - playsound(src, C.usesound, 80, 1) - return remove_tile(user, silent) - -/turf/simulated/floor/proc/remove_tile(mob/user, silent = FALSE, make_tile = TRUE) - if(broken || burnt) - broken = FALSE - burnt = FALSE - current_overlay = null - if(user && !silent) - to_chat(user, "You remove the broken plating.") - else - if(user && !silent) - to_chat(user, "You remove the floor tile.") - if(floor_tile && make_tile) - new floor_tile(src) - return make_plating() - -/turf/simulated/floor/singularity_pull(S, current_size) - ..() - if(current_size == STAGE_THREE) - if(prob(30)) - if(floor_tile) - new floor_tile(src) - make_plating() - else if(current_size == STAGE_FOUR) - if(prob(50)) - if(floor_tile) - new floor_tile(src) - make_plating() - else if(current_size >= STAGE_FIVE) - if(floor_tile) - if(prob(70)) - new floor_tile(src) - make_plating() - else if(prob(50)) - ReplaceWithLattice() - -/turf/simulated/floor/narsie_act() - if(prob(20)) - ChangeTurf(/turf/simulated/floor/engine/cult) - -/turf/simulated/floor/acid_melt() - ChangeTurf(baseturf) - -/turf/simulated/floor/can_have_cabling() - return !burnt && !broken - -/turf/simulated/floor/proc/get_broken_states() - return list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5") - -/turf/simulated/floor/proc/get_burnt_states() - return list("floorscorched1", "floorscorched2") - -/turf/simulated/floor/proc/get_prying_tools() - return list(TOOL_CROWBAR) diff --git a/code/game/turfs/simulated/floor/asteroid_floors.dm b/code/game/turfs/simulated/floor/asteroid_floors.dm deleted file mode 100644 index 4d093eaf171ac..0000000000000 --- a/code/game/turfs/simulated/floor/asteroid_floors.dm +++ /dev/null @@ -1,251 +0,0 @@ - -/**********************Asteroid**************************/ - -/turf/simulated/floor/plating/asteroid - gender = PLURAL - name = "asteroid sand" - baseturf = /turf/simulated/floor/plating/asteroid - icon_state = "asteroid" - icon_plating = "asteroid" - footstep = FOOTSTEP_SAND - barefootstep = FOOTSTEP_SAND - clawfootstep = FOOTSTEP_SAND - heavyfootstep = FOOTSTEP_GENERIC_HEAVY - var/environment_type = "asteroid" - var/turf_type = /turf/simulated/floor/plating/asteroid //Because caves do whacky shit to revert to normal - var/floor_variance = 20 //probability floor has a different icon state - var/obj/item/stack/digResult = /obj/item/stack/ore/glass/basalt - var/dug - -/turf/simulated/floor/plating/asteroid/Initialize(mapload) - var/proper_name = name - . = ..() - name = proper_name - if(prob(floor_variance)) - icon_state = "[environment_type][rand(0,12)]" - -/turf/simulated/floor/plating/asteroid/proc/getDug() - new digResult(src, 5) - icon_plating = "[environment_type]_dug" - icon_state = "[environment_type]_dug" - dug = TRUE - -/turf/simulated/floor/plating/asteroid/proc/can_dig(mob/user) - if(!dug) - return TRUE - if(user) - to_chat(user, "Looks like someone has dug here already.") - -/turf/simulated/floor/plating/asteroid/try_replace_tile(obj/item/stack/tile/T, mob/user, params) - return - -/turf/simulated/floor/plating/asteroid/burn_tile() - return - -/turf/simulated/floor/plating/asteroid/remove_plating() - return - -/turf/simulated/floor/plating/asteroid/ex_act(severity) - if(!can_dig()) - return - switch(severity) - if(3) - return - if(2) - if(prob(20)) - getDug() - if(1) - getDug() - -/turf/simulated/floor/plating/asteroid/proc/attempt_ore_pickup(obj/item/storage/bag/ore/S, mob/user) - if(!istype(S)) - return - - if(S.pickup_all_on_tile) - for(var/obj/item/stack/ore/O in contents) - O.attackby__legacy__attackchain(S, user) - return - -/turf/simulated/floor/plating/asteroid/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(QDELETED(user)|| QDELETED(used)) - return ITEM_INTERACT_COMPLETE - - if((istype(used, /obj/item/shovel) || istype(used, /obj/item/pickaxe))) - if(!can_dig(user)) - return TRUE - - var/turf/T = get_turf(user) - if(!istype(T)) - return - - to_chat(user, "You start digging...") - - playsound(src, used.usesound, 50, TRUE) - if(do_after(user, 40 * used.toolspeed, target = src)) - if(!can_dig(user)) - return TRUE - to_chat(user, "You dig a hole.") - getDug() - return TRUE - - else if(istype(used, /obj/item/storage/bag/ore)) - attempt_ore_pickup(used, user) - - else if(istype(used, /obj/item/stack/tile)) - var/obj/item/stack/tile/Z = used - if(!Z.use(1)) - return - if(istype(Z, /obj/item/stack/tile/plasteel)) // Turn asteroid floors into plating by default - ChangeTurf(/turf/simulated/floor/plating, keep_icon = FALSE) - else - ChangeTurf(Z.turf_type, keep_icon = FALSE) - playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) - -/turf/simulated/floor/plating/asteroid/screwdriver_act(mob/user, obj/item/I) - return - -/turf/simulated/floor/plating/asteroid/welder_act(mob/user, obj/item/I) - return - -/turf/simulated/floor/plating/asteroid/basalt - name = "volcanic floor" - baseturf = /turf/simulated/floor/plating/asteroid/basalt - icon_state = "basalt" - icon_plating = "basalt" - environment_type = "basalt" - floor_variance = 15 - digResult = /obj/item/stack/ore/glass/basalt - -/// lava underneath -/turf/simulated/floor/plating/asteroid/basalt/lava - baseturf = /turf/simulated/floor/lava - -/turf/simulated/floor/plating/asteroid/basalt/airless - temperature = TCMB - oxygen = 0 - nitrogen = 0 - -/turf/simulated/floor/plating/asteroid/ancient - digResult = /obj/item/stack/ore/glass/basalt/ancient - baseturf = /turf/simulated/floor/plating/asteroid/ancient/airless - -/turf/simulated/floor/plating/asteroid/ancient/airless - temperature = TCMB - oxygen = 0 - nitrogen = 0 - -/turf/simulated/floor/plating/asteroid/basalt/Initialize(mapload) - . = ..() - set_basalt_light(src) - -/turf/simulated/floor/plating/asteroid/basalt/getDug() - set_light(0) - return ..() - -/proc/set_basalt_light(turf/simulated/floor/B) - switch(B.icon_state) - if("basalt1", "basalt2", "basalt3") - B.set_light(2, 0.6, LIGHT_COLOR_LAVA) //more light - if("basalt5", "basalt9") - B.set_light(1.4, 0.6, LIGHT_COLOR_LAVA) //barely anything! - -///////Surface. The surface is warm, but survivable without a suit. Internals are required. The floors break to chasms, which drop you into the underground. - -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - baseturf = /turf/simulated/floor/lava/mapping_lava - -/turf/simulated/floor/plating/asteroid/basalt/lowpressure - oxygen = 8 - nitrogen = 14 - -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface_hard - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - color = COLOR_FLOOR_HARD_ROCK - baseturf = /turf/simulated/floor/lava/lava_land_surface - -/turf/simulated/floor/plating/asteroid/basalt/plasma - temperature = 1000 - oxygen = 0 - nitrogen = 0 - carbon_dioxide = 1.2 - toxins = 10 - turf_type = /turf/simulated/floor/plating/asteroid/basalt/plasma - atmos_mode = ATMOS_MODE_NO_DECAY - -/turf/simulated/floor/plating/asteroid/airless - temperature = TCMB - oxygen = 0 - nitrogen = 0 - turf_type = /turf/simulated/floor/plating/asteroid/airless - -/obj/effect/spawner/oasisrock - name = "Oasis rock spawner" - var/passed_radius - -/obj/effect/spawner/oasisrock/Initialize(mapload, radius) - . = ..() - passed_radius = radius - return INITIALIZE_HINT_LATELOAD - -/obj/effect/spawner/oasisrock/LateInitialize() //Let us try this for a moment. - . = ..() - addtimer(CALLBACK(src, PROC_REF(make_rock), passed_radius), 5 SECONDS) - -/obj/effect/spawner/oasisrock/proc/make_rock(radius) - var/our_turf = get_turf(src) - for(var/turf/oasis in circlerangeturfs(our_turf, radius)) - if(istype(oasis.loc, /area/ruin)) - continue - oasis.ChangeTurf(/turf/simulated/mineral/random/high_chance/volcanic, ignore_air = TRUE) - var/list/valid_turfs = circlerangeturfs(our_turf, radius + 1) - valid_turfs -= circlerangeturfs(our_turf, radius) - for(var/mob/M in circlerange(src, radius)) //We don't want mobs inside the ore rock - M.forceMove(pick_n_take(valid_turfs)) - for(var/obj/structure/spawner/lavaland/O in circlerange(src, radius)) //We don't want tendrils in there either - O.forceMove(pick_n_take(valid_turfs)) - qdel(src) - -/turf/simulated/floor/plating/asteroid/snow - gender = PLURAL - name = "snow" - desc = "Looks cold." - icon = 'icons/turf/snow.dmi' - baseturf = /turf/simulated/floor/plating/asteroid/snow - icon_state = "snow" - icon_plating = "snow" - temperature = 180 - slowdown = 2 - environment_type = "snow" - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_COLD - digResult = /obj/item/stack/sheet/mineral/snow - -/turf/simulated/floor/plating/asteroid/snow/burn_tile() - if(!burnt) - visible_message("[src] melts away!.") - slowdown = 0 - burnt = TRUE - icon_state = "snow_dug" - return TRUE - return FALSE - -/turf/simulated/floor/plating/asteroid/snow/get_burnt_states() - return list("snow_dug") - -/turf/simulated/floor/plating/asteroid/snow/airless - temperature = TCMB - oxygen = 0 - nitrogen = 0 - atmos_mode = ATMOS_MODE_SEALED - -/turf/simulated/floor/plating/asteroid/snow/atmosphere - atmos_mode = ATMOS_MODE_SEALED diff --git a/code/game/turfs/simulated/floor/chasm.dm b/code/game/turfs/simulated/floor/chasm.dm deleted file mode 100644 index a4d2da39fadf4..0000000000000 --- a/code/game/turfs/simulated/floor/chasm.dm +++ /dev/null @@ -1,361 +0,0 @@ -/turf/simulated/floor/chasm - name = "chasm" - desc = "Watch your step." - baseturf = /turf/simulated/floor/chasm - icon = 'icons/turf/floors/Chasms.dmi' - icon_state = "chasms-255" - base_icon_state = "chasms" - smoothing_flags = SMOOTH_BITMASK | SMOOTH_BORDER - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_TURF_CHASM) - canSmoothWith = list(SMOOTH_GROUP_TURF_CHASM) - density = TRUE //This will prevent hostile mobs from pathing into chasms, while the canpass override will still let it function like an open turf - layer = 1.7 - intact = 0 - var/static/list/falling_atoms = list() //Atoms currently falling into the chasm - var/static/list/forbidden_types = typecacheof(list( - /obj/singularity, - /obj/docking_port, - /obj/structure/lattice, - /obj/structure/stone_tile, - /obj/item/projectile, - /obj/effect/portal, - /obj/effect/hotspot, - /obj/effect/landmark, - /obj/effect/temp_visual, - /obj/effect/light_emitter/tendril, - /obj/effect/collapse, - /obj/effect/particle_effect/ion_trails, - /obj/effect/abstract, - /obj/effect/ebeam, - /obj/effect/spawner, - /obj/structure/railing, - /obj/machinery/atmospherics/pipe/simple, - /obj/effect/projectile, - /obj/effect/projectile_lighting, - /obj/effect/dummy/slaughter, //no bloodcrawlers into chasms. - /obj/effect/dummy/spell_jaunt, //No jaunters into chasms either. - /mob/living/simple_animal/hostile/megafauna, //failsafe - /obj/tgvehicle/scooter/skateboard/hoverboard, - /obj/machinery/light // lights hanging on walls shouldn't get chasm'd - )) - var/drop_x = 1 - var/drop_y = 1 - var/drop_z = 2 // so that it doesn't send you to CC if something fucks up. - -/turf/simulated/floor/chasm/Entered(atom/movable/AM) - ..() - START_PROCESSING(SSprocessing, src) - drop_stuff(AM) - -/turf/simulated/floor/chasm/process() - if(!drop_stuff()) - STOP_PROCESSING(SSprocessing, src) - -/turf/simulated/floor/chasm/CanPathfindPass(to_dir, datum/can_pass_info/pass_info) - if(!pass_info.is_living) - return TRUE - - return pass_info.is_flying || pass_info.is_megafauna - -/turf/simulated/floor/chasm/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) - underlay_appearance.icon = 'icons/turf/floors.dmi' - underlay_appearance.icon_state = "basalt" - return TRUE - -/turf/simulated/floor/chasm/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(..()) - return ITEM_INTERACT_COMPLETE - - if(istype(used, /obj/item/stack/rods)) - var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) - if(!L) - var/obj/item/inactive = user.get_inactive_hand() - - if(isrobot(user)) - for(var/obj/item/thing in user.get_all_slots()) - if(thing.tool_behaviour == TOOL_SCREWDRIVER) - inactive = thing - break - - if(!inactive || inactive.tool_behaviour != TOOL_SCREWDRIVER) - to_chat(user, "You need to hold a screwdriver in your other hand to secure this lattice.") - return ITEM_INTERACT_COMPLETE - var/obj/item/stack/rods/R = used - if(R.use(1)) - to_chat(user, "You construct a lattice.") - playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE) - ReplaceWithLattice() - else - to_chat(user, "You need one rod to build a lattice.") - - return ITEM_INTERACT_COMPLETE - - if(istype(used, /obj/item/stack/tile/plasteel)) - var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) - if(L) - var/obj/item/stack/tile/plasteel/S = used - if(S.use(1)) - qdel(L) - playsound(src, 'sound/weapons/genhit.ogg', 50, 1) - to_chat(user, "You build a floor.") - ChangeTurf(/turf/simulated/floor/plating, keep_icon = FALSE) - else - to_chat(user, "You need one floor tile to build a floor!") - else - to_chat(user, "The plating is going to need some support! Place metal rods first.") - - return ITEM_INTERACT_COMPLETE - -/turf/simulated/floor/chasm/is_safe() - if(find_safeties() && ..()) - return TRUE - return FALSE - -/turf/simulated/floor/chasm/ex_act(severity) - return - -/turf/simulated/floor/chasm/proc/drop_stuff(AM) - . = 0 - if(find_safeties()) - return FALSE - var/thing_to_check = src - if(AM) - thing_to_check = list(AM) - for(var/thing in thing_to_check) - if(droppable(thing)) - . = 1 - INVOKE_ASYNC(src, PROC_REF(drop), thing) - -/turf/simulated/floor/chasm/proc/droppable(atom/movable/AM) - if(falling_atoms[AM]) - return FALSE - if(!isliving(AM) && !isobj(AM)) - return FALSE - if(!AM.simulated || is_type_in_typecache(AM, forbidden_types) || AM.throwing) - return FALSE - //Flies right over the chasm - if(isliving(AM)) - var/mob/living/M = AM - if(HAS_TRAIT(M, TRAIT_FLYING) || M.floating) - return FALSE - if(istype(M.buckled, /obj/tgvehicle/scooter/skateboard/hoverboard)) - return FALSE - if(ishuman(AM)) - var/mob/living/carbon/human/H = AM - if(istype(H.belt, /obj/item/wormhole_jaunter)) - var/obj/item/wormhole_jaunter/J = H.belt - //To freak out any bystanders - visible_message("[H] falls into [src]!") - J.chasm_react(H) - return FALSE - return TRUE - -/turf/simulated/floor/chasm/proc/drop(atom/movable/AM) - //Make sure the item is still there after our sleep - if(!AM || QDELETED(AM)) - return - falling_atoms[AM] = TRUE - var/turf/T = locate(drop_x, drop_y, drop_z) - if(T) - AM.visible_message("[AM] falls into [src]!", "GAH! Ah... where are you?") - T.visible_message("[AM] falls from above!") - AM.forceMove(T) - if(isliving(AM)) - var/mob/living/L = AM - L.Weaken(10 SECONDS) - L.adjustBruteLoss(30) - falling_atoms -= AM - -/turf/simulated/floor/chasm/straight_down - var/obj/effect/abstract/chasm_storage/storage - -/turf/simulated/floor/chasm/straight_down/Initialize(mapload) - . = ..() - var/found_storage = FALSE - for(var/obj/effect/abstract/chasm_storage/C in contents) - storage = C - found_storage = TRUE - break - if(!found_storage) - storage = new /obj/effect/abstract/chasm_storage(src) - drop_x = x - drop_y = y - drop_z = z - 1 - -/turf/simulated/floor/chasm/straight_down/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - baseturf = /turf/simulated/floor/chasm/straight_down/lava_land_surface //Chasms should not turn into lava - light_range = 2 - light_power = 0.75 - light_color = LIGHT_COLOR_LAVA //let's just say you're falling into lava, that makes sense right. Ignore the fact the people you pull out are not burning. - -/turf/simulated/floor/chasm/straight_down/lava_land_surface/Initialize(mapload) - . = ..() - baseturf = /turf/simulated/floor/chasm/straight_down/lava_land_surface - -/turf/simulated/floor/chasm/straight_down/lava_land_surface/drop(atom/movable/AM) - //Make sure the item is still there after our sleep - if(!AM || QDELETED(AM)) - return - falling_atoms[AM] = TRUE - AM.visible_message("[AM] falls into [src]!", "You stumble and stare into an abyss before you. It stares back, and you fall \ - into the enveloping dark.") - if(isliving(AM)) - var/mob/living/L = AM - L.notransform = TRUE - L.Weaken(20 SECONDS) - var/oldtransform = AM.transform - var/oldcolor = AM.color - var/oldalpha = AM.alpha - var/old_pixel_y = AM.pixel_y - animate(AM, transform = matrix() - matrix(), alpha = 0, color = rgb(0, 0, 0), time = 10) - for(var/i in 1 to 5) - //Make sure the item is still there after our sleep - if(!AM || QDELETED(AM)) - return - AM.pixel_y-- - sleep(2) - - //Make sure the item is still there after our sleep - if(!AM || QDELETED(AM)) - return - - falling_atoms -= AM - if(isliving(AM)) - AM.alpha = oldalpha - AM.color = oldcolor - AM.transform = oldtransform - AM.pixel_y = old_pixel_y - var/mob/living/fallen_mob = AM - fallen_mob.notransform = FALSE - if(fallen_mob.stat != DEAD) - fallen_mob.death() - fallen_mob.adjustBruteLoss(1000) //crunch from long fall, want it to be like legion in damage - fallen_mob.forceMove(storage) - return - - if(istype(AM, /obj/item/grenade/jaunter_grenade)) - AM.forceMove(storage) - return - for(var/mob/M in AM.contents) - M.forceMove(src) - - qdel(AM) - - if(!QDELETED(AM)) //It's indestructible, mobs have already returned above! - visible_message("[src] spits out [AM]!") - AM.alpha = oldalpha - AM.color = oldcolor - AM.transform = oldtransform - AM.pixel_y = old_pixel_y - AM.throw_at(get_edge_target_turf(src, pick(GLOB.alldirs)), rand(1, 10), rand(1, 10)) - -/** - * An abstract object which is basically just a bag that the chasm puts people inside - */ - -/obj/effect/abstract/chasm_storage - name = "chasm depths" - desc = "The bottom of a hole. You shouldn't be able to interact with this." - anchored = TRUE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/obj/effect/abstract/chasm_storage/Entered(atom/movable/arrived) - . = ..() - if(isliving(arrived)) - RegisterSignal(arrived, COMSIG_LIVING_REVIVE, PROC_REF(on_revive)) - -/obj/effect/abstract/chasm_storage/Exited(atom/movable/gone, direction) - . = ..() - if(isliving(gone)) - UnregisterSignal(gone, COMSIG_LIVING_REVIVE) - -/** - * Called if something comes back to life inside the pit. Expected sources are badmins and changelings. - * Ethereals should take enough damage to be smashed and not revive. - * Arguments - * escapee - Lucky guy who just came back to life at the bottom of a hole. - */ -/obj/effect/abstract/chasm_storage/proc/on_revive(mob/living/escapee) - SIGNAL_HANDLER - var/turf/ourturf = get_turf(src) - if(istype(ourturf, /turf/simulated/floor/chasm/straight_down/lava_land_surface)) - ourturf.visible_message("After a long climb, [escapee] leaps out of [ourturf]!") - else - playsound(ourturf, 'sound/effects/bang.ogg', 50, TRUE) - ourturf.visible_message("[escapee] busts through [ourturf], leaping out of the chasm below!") - ourturf.ChangeTurf(ourturf.baseturf) - ADD_TRAIT(escapee, TRAIT_FLYING, "chasm_escape") - escapee.forceMove(ourturf) - escapee.throw_at(get_edge_target_turf(ourturf, pick(GLOB.alldirs)), rand(2, 10), rand(2, 10)) - REMOVE_TRAIT(escapee, TRAIT_FLYING, "chasm_escape") - escapee.Sleeping(20 SECONDS) - -/turf/simulated/floor/chasm/straight_down/lava_land_surface/normal_air - oxygen = MOLES_O2STANDARD - nitrogen = MOLES_N2STANDARD - temperature = T20C - atmos_mode = ATMOS_MODE_SEALED - atmos_environment = null - -/turf/simulated/floor/chasm/CanPass(atom/movable/mover, border_dir) - return TRUE - -/turf/simulated/floor/chasm/pride/Initialize(mapload) - . = ..() - drop_x = x - drop_y = y - var/list/target_z = levels_by_trait(SPAWN_RUINS) - drop_z = pick(target_z) - -/turf/simulated/floor/chasm/space_ruin - /// Used to keep count of how many times we checked if our target turf was valid. - var/times_turfs_checked = 0 - /// List of all eligible Z levels. - var/list/target_z - /// Target turf that atoms will be teleported to. - var/turf/T - -/turf/simulated/floor/chasm/space_ruin/proc/pick_a_turf(atom/movable/AM) - if(times_turfs_checked <= 2) - target_z = levels_by_trait(SPAWN_RUINS) - target_z -= AM.z // excluding the one atom was already in from possible z levels - T = locate(rand(TRANSITIONEDGE + 1, world.maxx - TRANSITIONEDGE - 1), rand(TRANSITIONEDGE + 1, world.maxy - TRANSITIONEDGE - 1), pick(target_z)) - check_turf(AM) - else - // If we still fail to pick a random valid turf after 2 attempts, we just send the atom to somewhere valid for certain - T = locate(TRANSITIONEDGE + 1, TRANSITIONEDGE + 1, pick(target_z)) - - -/turf/simulated/floor/chasm/space_ruin/proc/check_turf(atom/movable/AM) - times_turfs_checked++ - if(istype(get_area(T), /area/space)) - return - else - pick_a_turf(AM) - -/turf/simulated/floor/chasm/space_ruin/drop(atom/movable/AM) - //Make sure the item is still there after our sleep - if(!AM || QDELETED(AM)) - return - falling_atoms[AM] = TRUE - pick_a_turf(AM) - if(T) - AM.visible_message("[AM] falls into [src]!", "GAH! Ah... where are you?") - T.visible_message("[AM] falls from above!") - AM.forceMove(T) - if(isliving(AM)) - var/mob/living/L = AM - L.Weaken(10 SECONDS) - L.adjustBruteLoss(30) - times_turfs_checked = 0 // We successfully teleported the atom, let's reset the count - falling_atoms -= AM - -/turf/simulated/floor/chasm/space_ruin/airless - oxygen = 0 - nitrogen = 0 - temperature = TCMB diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm deleted file mode 100644 index 9d58666655878..0000000000000 --- a/code/game/turfs/simulated/floor/fancy_floor.dm +++ /dev/null @@ -1,333 +0,0 @@ -/turf/simulated/floor/wood - icon_state = "wood" - floor_tile = /obj/item/stack/tile/wood - footstep = FOOTSTEP_WOOD - barefootstep = FOOTSTEP_WOOD_BAREFOOT - clawfootstep = FOOTSTEP_WOOD_CLAW - heavyfootstep = FOOTSTEP_GENERIC_HEAVY - -/turf/simulated/floor/wood/screwdriver_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - remove_tile(user, FALSE, TRUE) - -/turf/simulated/floor/wood/crowbar_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - remove_tile(user, FALSE, FALSE) - -/turf/simulated/floor/wood/get_broken_states() - return list("wood-broken", "wood-broken2", "wood-broken3", "wood-broken4", "wood-broken5", "wood-broken6", "wood-broken7") - -/turf/simulated/floor/wood/get_prying_tools() - return list(TOOL_SCREWDRIVER) - -/turf/simulated/floor/wood/remove_tile(mob/user, silent = FALSE, make_tile = TRUE) - if(broken || burnt) - broken = FALSE - burnt = FALSE - if(user && !silent) - to_chat(user, "You remove the broken planks.") - else - if(make_tile) - if(user && !silent) - to_chat(user, "You unscrew the planks.") - if(floor_tile) - new floor_tile(src) - else - if(user && !silent) - to_chat(user, "You forcefully pry off the planks, destroying them in the process.") - return make_plating() - -/turf/simulated/floor/wood/airless - name = "wood" // yes really - oxygen = 0 - nitrogen = 0 - temperature = TCMB - -/turf/simulated/floor/wood/cold - oxygen = 22 - nitrogen = 82 - temperature = 180 - -/turf/simulated/floor/wood/lavaland_air - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - -/turf/simulated/floor/wood/nitrogen - oxygen = 0 - nitrogen = MOLES_N2STANDARD + MOLES_O2STANDARD - -// Grass -/turf/simulated/floor/grass - name = "grass patch" - icon = 'icons/turf/floors/grass.dmi' - icon_state = "grass" - base_icon_state = "grass" - smoothing_flags = SMOOTH_BITMASK - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_GRASS) - canSmoothWith = list(SMOOTH_GROUP_GRASS, SMOOTH_GROUP_JUNGLE_GRASS) - layer = ABOVE_OPEN_TURF_LAYER - floor_tile = /obj/item/stack/tile/grass - footstep = FOOTSTEP_GRASS - barefootstep = FOOTSTEP_GRASS - clawfootstep = FOOTSTEP_GRASS - heavyfootstep = FOOTSTEP_GENERIC_HEAVY - transform = matrix(1, 0, -9, 0, 1, -9) //Yes, these sprites are 50x50px, big grass control the industry - -/turf/simulated/floor/grass/get_broken_states() - return list("damaged") - -/turf/simulated/floor/grass/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(istype(used, /obj/item/shovel)) - to_chat(user, "You shovel the grass.") - playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) - remove_tile() - return ITEM_INTERACT_COMPLETE - -/turf/simulated/floor/grass/jungle - name = "jungle grass" - icon = 'icons/turf/floors/junglegrass.dmi' - icon_state = "junglegrass" - base_icon_state = "junglegrass" - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_GRASS, SMOOTH_GROUP_JUNGLE_GRASS) - -/// This vairant shows up under normal turfs so fits in the regular 32x32 sprite -/turf/simulated/floor/grass/no_creep - smoothing_flags = null - smoothing_groups = null - canSmoothWith = null - layer = GRASS_UNDER_LAYER - transform = null - -/// This vairant shows up under normal turfs so fits in the regular 32x32 sprite -/turf/simulated/floor/grass/jungle/no_creep - smoothing_flags = null - smoothing_groups = null - canSmoothWith = null - layer = GRASS_UNDER_LAYER - transform = null - -//Carpets -/turf/simulated/floor/carpet - name = "carpet" - icon = 'icons/turf/floors/carpet.dmi' - icon_state = "carpet-255" - base_icon_state = "carpet" - floor_tile = /obj/item/stack/tile/carpet - smoothing_flags = SMOOTH_BITMASK - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_CARPET) - canSmoothWith = list(SMOOTH_GROUP_CARPET) - footstep = FOOTSTEP_CARPET - barefootstep = FOOTSTEP_CARPET_BAREFOOT - clawfootstep = FOOTSTEP_CARPET_BAREFOOT - heavyfootstep = FOOTSTEP_GENERIC_HEAVY - -/turf/simulated/floor/carpet/Initialize(mapload) - . = ..() - update_icon() - -/turf/simulated/floor/carpet/update_icon_state() - if(!broken && !burnt) - if(smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK)) - QUEUE_SMOOTH(src) - else - make_plating() - if(smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK)) - QUEUE_SMOOTH_NEIGHBORS(src) - -//Carpet variant for mapping aid, functionally the same as parent after smoothing. -/turf/simulated/floor/carpet/lone - icon_state = "carpet-0" - -/turf/simulated/floor/carpet/break_tile() - broken = TRUE - update_icon() - -/turf/simulated/floor/carpet/burn_tile() - burnt = TRUE - update_icon() - -/turf/simulated/floor/carpet/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) - return FALSE - -/turf/simulated/floor/carpet/get_broken_states() - return list("damaged") - -/turf/simulated/floor/carpet/black - icon = 'icons/turf/floors/carpet_black.dmi' - floor_tile = /obj/item/stack/tile/carpet/black - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_CARPET, SMOOTH_GROUP_CARPET_BLACK) - canSmoothWith = list(SMOOTH_GROUP_CARPET_BLACK) - -/turf/simulated/floor/carpet/blue - icon = 'icons/turf/floors/carpet_blue.dmi' - floor_tile = /obj/item/stack/tile/carpet/blue - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_CARPET, SMOOTH_GROUP_CARPET_BLUE) - canSmoothWith = list(SMOOTH_GROUP_CARPET_BLUE) - -/turf/simulated/floor/carpet/cyan - icon = 'icons/turf/floors/carpet_cyan.dmi' - floor_tile = /obj/item/stack/tile/carpet/cyan - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_CARPET, SMOOTH_GROUP_CARPET_CYAN) - canSmoothWith = list(SMOOTH_GROUP_CARPET_CYAN) - -/turf/simulated/floor/carpet/green - icon = 'icons/turf/floors/carpet_green.dmi' - floor_tile = /obj/item/stack/tile/carpet/green - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_CARPET, SMOOTH_GROUP_CARPET_GREEN) - canSmoothWith = list(SMOOTH_GROUP_CARPET_GREEN) - -/turf/simulated/floor/carpet/orange - icon = 'icons/turf/floors/carpet_orange.dmi' - floor_tile = /obj/item/stack/tile/carpet/orange - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_CARPET, SMOOTH_GROUP_CARPET_ORANGE) - canSmoothWith = list(SMOOTH_GROUP_CARPET_ORANGE) - -/turf/simulated/floor/carpet/purple - icon = 'icons/turf/floors/carpet_purple.dmi' - floor_tile = /obj/item/stack/tile/carpet/purple - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_CARPET, SMOOTH_GROUP_CARPET_PURPLE) - canSmoothWith = list(SMOOTH_GROUP_CARPET_PURPLE) - -/turf/simulated/floor/carpet/red - icon = 'icons/turf/floors/carpet_red.dmi' - floor_tile = /obj/item/stack/tile/carpet/red - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_CARPET, SMOOTH_GROUP_CARPET_RED) - canSmoothWith = list(SMOOTH_GROUP_CARPET_RED) - -/turf/simulated/floor/carpet/royalblack - icon = 'icons/turf/floors/carpet_royalblack.dmi' - floor_tile = /obj/item/stack/tile/carpet/royalblack - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_CARPET, SMOOTH_GROUP_CARPET_ROYALBLACK) - canSmoothWith = list(SMOOTH_GROUP_CARPET_ROYALBLACK) - -/turf/simulated/floor/carpet/royalblue - icon = 'icons/turf/floors/carpet_royalblue.dmi' - floor_tile = /obj/item/stack/tile/carpet/royalblue - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_CARPET, SMOOTH_GROUP_CARPET_ROYALBLUE) - canSmoothWith = list(SMOOTH_GROUP_CARPET_ROYALBLUE) - -/turf/simulated/floor/carpet/grimey - icon = 'icons/turf/floors/carpet_grimey.dmi' - floor_tile = /obj/item/stack/tile/carpet/grimey - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_CARPET,SMOOTH_GROUP_CARPET_GRIMEY) - canSmoothWith = list(SMOOTH_GROUP_CARPET_GRIMEY) - -/turf/simulated/floor/carpet/airless - oxygen = 0 - nitrogen = 0 - temperature = TCMB - -/turf/simulated/floor/carpet/lavaland_air - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - -/turf/simulated/floor/carpet/nitrogen - oxygen = 0 - nitrogen = MOLES_N2STANDARD + MOLES_O2STANDARD - -//End of carpets - -// Bamboo mats -/turf/simulated/floor/bamboo - name = "bamboo" - icon = 'icons/turf/floors/bamboo_mat.dmi' - icon_state = "mat-0" - base_icon_state = "mat" - floor_tile = /obj/item/stack/tile/bamboo - smoothing_flags = SMOOTH_BITMASK - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_BAMBOO) - canSmoothWith = list(SMOOTH_GROUP_BAMBOO) - footstep = FOOTSTEP_WOOD - barefootstep = FOOTSTEP_WOOD_BAREFOOT - clawfootstep = FOOTSTEP_WOOD_CLAW - heavyfootstep = FOOTSTEP_GENERIC_HEAVY - -/turf/simulated/floor/bamboo/Initialize(mapload) - . = ..() - update_icon() - -/turf/simulated/floor/bamboo/update_icon_state() - if(!broken && !burnt) - if(smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK)) - QUEUE_SMOOTH(src) - else - make_plating() - if(smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK)) - QUEUE_SMOOTH_NEIGHBORS(src) - -/turf/simulated/floor/bamboo/break_tile() - broken = TRUE - update_icon() - -/turf/simulated/floor/bamboo/burn_tile() - burnt = TRUE - update_icon() - -/turf/simulated/floor/bamboo/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) - return FALSE - -/turf/simulated/floor/bamboo/get_broken_states() - return list("bamboo-damaged") - -/turf/simulated/floor/bamboo/get_prying_tools() - return list(TOOL_SCREWDRIVER) - -/turf/simulated/floor/bamboo/airless - oxygen = 0 - nitrogen = 0 - temperature = TCMB - -// Bamboo tatami mat -/turf/simulated/floor/bamboo/tatami - desc = "A traditional Japanese floor mat." - icon_state = "bamboo-green" - floor_tile = /obj/item/stack/tile/bamboo/tatami - smoothing_flags = NONE - -/turf/simulated/floor/bamboo/tatami/get_broken_states() - return list("tatami-damaged") - -/turf/simulated/floor/bamboo/tatami/purple - icon_state = "bamboo-purple" - floor_tile = /obj/item/stack/tile/bamboo/tatami/purple - -/turf/simulated/floor/bamboo/tatami/black - icon_state = "bamboo-black" - floor_tile = /obj/item/stack/tile/bamboo/tatami/black -// End of bamboo - -/turf/simulated/floor/fakespace - icon = 'icons/turf/space.dmi' - icon_state = "0" - floor_tile = /obj/item/stack/tile/fakespace - smoothing_flags = NONE - plane = PLANE_SPACE - -/turf/simulated/floor/fakespace/Initialize(mapload) - . = ..() - icon_state = SPACE_ICON_STATE - -/turf/simulated/floor/fakespace/get_broken_states() - return list("damaged") - -/turf/simulated/floor/fakespace/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) - underlay_appearance.icon = 'icons/turf/space.dmi' - underlay_appearance.icon_state = SPACE_ICON_STATE - underlay_appearance.plane = PLANE_SPACE - return TRUE - -/turf/simulated/floor/carpet/arcade - icon = 'icons/goonstation/turf/floor.dmi' - icon_state = "arcade" - floor_tile = /obj/item/stack/tile/arcade_carpet - smoothing_flags = NONE diff --git a/code/game/turfs/simulated/floor/indestructible.dm b/code/game/turfs/simulated/floor/indestructible.dm deleted file mode 100644 index 74f4142ef5ab8..0000000000000 --- a/code/game/turfs/simulated/floor/indestructible.dm +++ /dev/null @@ -1,117 +0,0 @@ -/turf/simulated/floor/indestructible - -/turf/simulated/floor/indestructible/Initialize(mapload) - . = ..() - RegisterSignal(src, COMSIG_ATTACK_BY, TYPE_PROC_REF(/datum, signal_cancel_attack_by)) - -/turf/simulated/floor/indestructible/ex_act(severity) - return - -/turf/simulated/floor/indestructible/blob_act(obj/structure/blob/B) - return - -/turf/simulated/floor/indestructible/singularity_act() - return - -/turf/simulated/floor/indestructible/singularity_pull(S, current_size) - return - -/turf/simulated/floor/indestructible/narsie_act() - return - -/turf/simulated/floor/indestructible/burn_down() - return - -/turf/simulated/floor/indestructible/attack_hand(mob/user) - return - -/turf/simulated/floor/indestructible/attack_hulk(mob/user, does_attack_animation = FALSE) - return - -/turf/simulated/floor/indestructible/attack_animal(mob/living/simple_animal/M) - return - -/turf/simulated/floor/indestructible/mech_melee_attack(obj/mecha/M) - return - -/turf/simulated/floor/indestructible/airless - oxygen = 0 - nitrogen = 0 - temperature = TCMB - -/turf/simulated/floor/indestructible/necropolis - name = "necropolis floor" - desc = "It's regarding you suspiciously." - icon = 'icons/turf/floors.dmi' - icon_state = "necro1" - baseturf = /turf/simulated/floor/indestructible/necropolis - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - footstep = FOOTSTEP_LAVA - barefootstep = FOOTSTEP_LAVA - clawfootstep = FOOTSTEP_LAVA - heavyfootstep = FOOTSTEP_LAVA - -/turf/simulated/floor/indestructible/necropolis/Initialize(mapload) - . = ..() - if(prob(12)) - icon_state = "necro[rand(2,3)]" - -/turf/simulated/floor/indestructible/necropolis/normal_air - oxygen = MOLES_O2STANDARD - nitrogen = MOLES_N2STANDARD - temperature = T20C - atmos_mode = ATMOS_MODE_SEALED - atmos_environment = null - -/// you put stone tiles on this and use it as a base -/turf/simulated/floor/indestructible/boss - name = "necropolis floor" - icon = 'icons/turf/floors/boss_floors.dmi' - icon_state = "boss" - baseturf = /turf/simulated/floor/indestructible/boss - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - -/turf/simulated/floor/indestructible/boss/normal_air - oxygen = MOLES_O2STANDARD - nitrogen = MOLES_N2STANDARD - temperature = T20C - atmos_mode = ATMOS_MODE_SEALED - atmos_environment = null - -/turf/simulated/floor/indestructible/hierophant - name = "floor" - icon = 'icons/turf/floors/hierophant_floor.dmi' - icon_state = "floor" - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - smoothing_flags = SMOOTH_CORNERS - -/turf/simulated/floor/indestructible/hierophant/normal_air - oxygen = MOLES_O2STANDARD - nitrogen = MOLES_N2STANDARD - temperature = T20C - atmos_mode = ATMOS_MODE_SEALED - atmos_environment = null - -/turf/simulated/floor/indestructible/hierophant/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) - return FALSE - -/turf/simulated/floor/indestructible/hierophant/two - -/turf/simulated/floor/indestructible/hierophant/two/normal_air - oxygen = MOLES_O2STANDARD - nitrogen = MOLES_N2STANDARD - temperature = T20C - atmos_mode = ATMOS_MODE_SEALED - atmos_environment = null diff --git a/code/game/turfs/simulated/floor/lava.dm b/code/game/turfs/simulated/floor/lava.dm deleted file mode 100644 index f480fbecb7c50..0000000000000 --- a/code/game/turfs/simulated/floor/lava.dm +++ /dev/null @@ -1,309 +0,0 @@ -/** - * Lava turf, burns things that are on it. - * Currently a subtype of floor so that footsteps work on it. - * Perhaps we could move it down to /turf/simulated/lava someday, as I dont think footsteps over lava are very important. - */ -/turf/simulated/floor/lava - name = "lava" - icon = 'icons/turf/floors/lava.dmi' - icon_state = "lava-255" - base_icon_state = "lava" - gender = PLURAL //"That's some lava." - baseturf = /turf/simulated/floor/lava //lava all the way down - slowdown = 2 - light_range = 2 - light_power = 0.75 - light_color = LIGHT_COLOR_LAVA - footstep = FOOTSTEP_LAVA - barefootstep = FOOTSTEP_LAVA - clawfootstep = FOOTSTEP_LAVA - heavyfootstep = FOOTSTEP_LAVA - smoothing_flags = SMOOTH_BITMASK | SMOOTH_BORDER - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_FLOOR_LAVA) - canSmoothWith = list(SMOOTH_GROUP_FLOOR_LAVA) - intact = FALSE - floor_tile = null - real_layer = PLATING_LAYER - - -/turf/simulated/floor/lava/ex_act() - return - -/turf/simulated/floor/lava/acid_act(acidpwr, acid_volume) - return - -/turf/simulated/floor/lava/Entered(atom/movable/AM) - if(burn_stuff(AM)) - START_PROCESSING(SSprocessing, src) - -/turf/simulated/floor/lava/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) - if(burn_stuff(AM)) - START_PROCESSING(SSprocessing, src) - -/turf/simulated/floor/lava/process() - if(!burn_stuff()) - STOP_PROCESSING(SSprocessing, src) - -/turf/simulated/floor/lava/singularity_act() - return - -/turf/simulated/floor/lava/singularity_pull(S, current_size) - return - -/turf/simulated/floor/plating/lava/make_plating() - return - -/turf/simulated/floor/plating/lava/remove_plating() - return - -/turf/simulated/floor/plating/lava/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) - underlay_appearance.icon = 'icons/turf/floors.dmi' - underlay_appearance.icon_state = "basalt" - return TRUE - -/turf/simulated/floor/lava/is_safe() - if(find_safeties() && ..()) - return TRUE - return FALSE - -/turf/simulated/floor/lava/proc/burn_stuff(AM) - . = FALSE - - if(find_safeties()) - 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.simulated) - continue - if((O.resistance_flags & (LAVA_PROOF|INDESTRUCTIBLE)) || O.throwing) - continue - . = TRUE - 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.getRating(FIRE) > 50) //obj with 100% fire armor still get slowly burned away. - O.armor = O.armor.setRating(fire_value = 50) - O.fire_act(10000, 1000) - - else if(isliving(thing)) - . = TRUE - var/mob/living/L = thing - if(HAS_TRAIT(L, TRAIT_FLYING)) - continue //YOU'RE FLYING OVER IT - 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) - continue - else if(isliving(buckle_check)) - var/mob/living/live = buckle_check - if("lava" in live.weather_immunities) - continue - - if("lava" in L.weather_immunities) - continue - - L.adjustFireLoss(20) - if(L) //mobs turning into object corpses could get deleted here. - L.adjust_fire_stacks(20) - L.IgniteMob() - -/// Lava isn't a good foundation to build on. -/turf/simulated/floor/lava/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(istype(used, /obj/item/stack/rods/lava)) - var/obj/item/stack/rods/lava/R = used - var/obj/structure/lattice/lava/H = locate(/obj/structure/lattice/lava, src) - if(H) - to_chat(user, "There is already a lattice here!") - return ITEM_INTERACT_COMPLETE - if(R.use(1)) - to_chat(user, "You construct a lattice.") - playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE) - new /obj/structure/lattice/lava(locate(x, y, z)) - return ITEM_INTERACT_COMPLETE - else - to_chat(user, "You need one rod to build a heatproof lattice.") - return ITEM_INTERACT_COMPLETE - - if(istype(used, /obj/item/stack/tile/plasteel)) - var/obj/structure/lattice/L = locate(/obj/structure/lattice/lava, src) - if(!L) - to_chat(user, "The plating is going to need some support! Place metal rods first.") - return ITEM_INTERACT_COMPLETE - var/obj/item/stack/tile/plasteel/S = used - if(S.use(1)) - qdel(L) - playsound(src, 'sound/weapons/genhit.ogg', 50, 1) - to_chat(user, "You build a floor.") - ChangeTurf(/turf/simulated/floor/plating, keep_icon = FALSE) - return ITEM_INTERACT_COMPLETE - else - to_chat(user, "You need one floor tile to build a floor!") - return ITEM_INTERACT_COMPLETE - -/turf/simulated/floor/lava/screwdriver_act() - return - -/turf/simulated/floor/lava/welder_act() - return - -/turf/simulated/floor/lava/break_tile() - return - -/turf/simulated/floor/lava/burn_tile() - return - -/turf/simulated/floor/lava/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - baseturf = /turf/simulated/floor/chasm/straight_down/lava_land_surface - -/turf/simulated/floor/lava/lava_land_surface/plasma - name = "liquid plasma" - desc = "A flowing stream of chilled liquid plasma. You probably shouldn't get in." - icon = 'icons/turf/floors/liquidplasma.dmi' - icon_state = "liquidplasma-255" - base_icon_state = "liquidplasma" - baseturf = /turf/simulated/floor/lava/lava_land_surface/plasma - - light_range = 3 - light_power = 0.75 - light_color = LIGHT_COLOR_PINK - -/turf/simulated/floor/lava/lava_land_surface/plasma/examine(mob/user) - . = ..() - . += "Some liquid plasma could probably be scooped up with a container." - -/turf/simulated/floor/lava/lava_land_surface/plasma/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(!used.is_open_container()) - return ..() - if(!used.reagents.add_reagent("plasma", 10)) - to_chat(user, "[used] is full.") - return ITEM_INTERACT_COMPLETE - - to_chat(user, "You scoop out some plasma from the [src] using [used].") - return ITEM_INTERACT_COMPLETE - -/turf/simulated/floor/lava/lava_land_surface/plasma/burn_stuff(AM) - . = FALSE - if(find_safeties()) - 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.simulated) - continue - if((O.resistance_flags & (LAVA_PROOF|INDESTRUCTIBLE)) || O.throwing) - continue - . = TRUE - 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.getRating(FIRE) > 50) //obj with 100% fire armor still get slowly burned away. - O.armor = O.armor.setRating(fire_value = 50) - O.fire_act(10000, 1000) - - if(!isliving(thing)) - continue - . = TRUE - var/mob/living/burn_living = thing - if(HAS_TRAIT(burn_living, TRAIT_FLYING)) - continue //YOU'RE FLYING OVER IT - var/buckle_check = burn_living.buckling - if(!buckle_check) - buckle_check = burn_living.buckled - if(isobj(buckle_check)) - var/obj/O = buckle_check - if(O.resistance_flags & LAVA_PROOF) - continue - else if(isliving(buckle_check)) - var/mob/living/live = buckle_check - if("lava" in live.weather_immunities) - continue - if("lava" in burn_living.weather_immunities) - continue - 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.IgniteMob() - burn_living.adjust_bodytemperature(-rand(50, 65)) //its cold, man - if(!ishuman(burn_living) || prob(65)) - 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/machine)) //ignore plasmamen/robotic species. - return - - burn_human.adjustToxLoss(15) //Cold mutagen is bad for you, more at 11. - burn_human.adjustFireLoss(15) - -/turf/simulated/floor/lava/mapping_lava - name = "Adaptive lava / chasm / plasma" - icon_state = "mappinglava" - base_icon_state = "mappinglava" - baseturf = /turf/simulated/floor/lava/mapping_lava - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - -/turf/simulated/floor/lava/mapping_lava/normal_air - oxygen = MOLES_O2STANDARD - nitrogen = MOLES_N2STANDARD - temperature = T20C - atmos_mode = ATMOS_MODE_SEALED - atmos_environment = null - -/turf/simulated/floor/lava/plasma - name = "liquid plasma" - desc = "A swirling pit of liquid plasma. It bubbles ominously." - icon = 'icons/turf/floors/liquidplasma.dmi' - icon_state = "liquidplasma-255" - base_icon_state = "liquidplasma" - baseturf = /turf/simulated/floor/lava/plasma - light_range = 3 - light_power = 0.75 - light_color = LIGHT_COLOR_PINK - -// special turf for the asteroid core on EmeraldStation -/turf/simulated/floor/lava/plasma/fuming - baseturf = /turf/simulated/floor/lava/plasma/fuming - atmos_mode = ATMOS_MODE_NO_DECAY - - // Hot Ass Plasma lava - temperature = 1000 - oxygen = 0 - nitrogen = 0 - carbon_dioxide = 1.2 - toxins = 10 - -/turf/simulated/floor/lava/mapping_lava/Initialize(mapload) - . = ..() - return INITIALIZE_HINT_LATELOAD //Lateload is needed, otherwise atmos does not setup right on the turf roundstart, leading it to be vacume. This is bad. - -/turf/simulated/floor/lava/mapping_lava/LateInitialize() - . = ..() - if(SSmapping.lavaland_theme?.primary_turf_type) - ChangeTurf(SSmapping.lavaland_theme.primary_turf_type, ignore_air = TRUE) diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm deleted file mode 100644 index 9ca66010252ab..0000000000000 --- a/code/game/turfs/simulated/floor/light_floor.dm +++ /dev/null @@ -1,148 +0,0 @@ -/turf/simulated/floor/light - name = "light floor" - light_range = 0 - icon_state = "light_off" - floor_tile = /obj/item/stack/tile/light - /// Are we on - var/on = FALSE - /// Can we modify a colour - var/can_modify_colour = TRUE - /// Are we draining power - var/using_power = FALSE - -/turf/simulated/floor/light/Initialize(mapload) - . = ..() - update_icon() - var/area/current_area = get_area(src) - var/obj/machinery/power/apc/current_apc = current_area.get_apc() - if(current_apc) - RegisterSignal(current_area.powernet, COMSIG_POWERNET_POWER_CHANGE, PROC_REF(power_update), override = TRUE) - toggle_light(TRUE) - -/turf/simulated/floor/light/update_icon_state() - if(on) - icon_state = "light_on" - set_light(5, null, color) - else - icon_state = "light_off" - set_light(0) - -/turf/simulated/floor/light/BeforeChange() - toggle_light(FALSE) - ..() - -/turf/simulated/floor/light/proc/power_update() - SIGNAL_HANDLER - if(power_check() || !on) - return - toggle_light(FALSE) - -/turf/simulated/floor/light/proc/power_check() - var/area/A = get_area(src) - return A.powernet.has_power(PW_CHANNEL_LIGHTING) - -/turf/simulated/floor/light/attack_hand(mob/user) - if(!can_modify_colour) - return - if(user.a_intent != INTENT_HELP) - return - toggle_light(!on) - -/turf/simulated/floor/light/multitool_act(mob/user, obj/item/I) - . = TRUE - if(!can_modify_colour) - return - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - - var/new_color = tgui_input_color(user, "Select a bulb color", "Select a bulb color", color) - if(isnull(new_color)) - return - - // Cancel if they walked away - if(!Adjacent(user, src)) - return - - // Now lets make sure it cant go fully black. Yes I know this is more dense than my skull. - var/list/hsl = rgb2hsl(hex2num(copytext(new_color, 2, 4)), hex2num(copytext(new_color, 4, 6)), hex2num(copytext(new_color, 6, 8))) - hsl[3] = max(hsl[3], 0.4) - var/list/rgb = hsl2rgb(arglist(hsl)) - color = "#[num2hex(rgb[1], 2)][num2hex(rgb[2], 2)][num2hex(rgb[3], 2)]" - - to_chat(user, "You change [src]'s light bulb color.") - update_icon() - -/turf/simulated/floor/light/proc/toggle_light(light) - if(!on && !power_check()) - visible_message("[src] doesn't react, it seems to be out of power.") - return - var/area/A = get_area(src) - // 0 = OFF - // 1 = ON - on = light - if(!on && using_power) - A.powernet.adjust_static_power(PW_CHANNEL_LIGHTING, -100) - using_power = FALSE - if(on && !using_power) - using_power = TRUE - A.powernet.adjust_static_power(PW_CHANNEL_LIGHTING, 100) - update_icon() - -/turf/simulated/floor/light/extinguish_light(force = FALSE) - toggle_light(FALSE) - visible_message("[src] flickers and falls dark.") - -/turf/simulated/floor/light/clean(floor_only) - var/color_save = color - ..() - color = color_save - -/turf/simulated/floor/light/get_broken_states() - return list("light_off") - -// These tiles change color every now and then -/turf/simulated/floor/light/disco - floor_tile = /obj/item/stack/tile/disco_light - /// Cannot change its color with a multitool - can_modify_colour = FALSE - /// The tile can change into these colors - var/list/available_colors = list("#d41e3c", "#ed7b39", "#fff540", "#77b02a", "#488bd4", "#b0fff1", "#94007a", "#ff417d") - /// This is our current color, don't pick it again - var/current_color - -// We pick a random color when we are spawned -/turf/simulated/floor/light/disco/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - -// The animation happens in this proc -/turf/simulated/floor/light/disco/proc/change_color() - current_color = pick_excluding(available_colors, current_color) - animate_fade_to_color_fill(src, current_color, 2) - -// We change colors every now and then -/turf/simulated/floor/light/disco/process() - if(on) - change_color() - -// Admins can toggle its color with advanced admin interaction -/turf/simulated/floor/light/disco/attack_ghost(mob/user) - if(user.can_advanced_admin_interact()) - change_color() - -// One is able to restart it, if power runs out. However, it cannot be turned off! -/turf/simulated/floor/light/disco/attack_hand(mob/user) - if(!on) - toggle_light(TRUE) - -/turf/simulated/floor/light/disco/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/turf/simulated/floor/light/lavaland_air - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - diff --git a/code/game/turfs/simulated/floor/mineral_floors.dm b/code/game/turfs/simulated/floor/mineral_floors.dm deleted file mode 100644 index c7d99f19ddcdb..0000000000000 --- a/code/game/turfs/simulated/floor/mineral_floors.dm +++ /dev/null @@ -1,312 +0,0 @@ -/* In this file: - * - * Plasma floor - * Gold floor - * Silver floor - * Bananium floor - * Diamond floor - * Uranium floor - * Shuttle floor (Titanium) - */ - -/turf/simulated/floor/mineral - name = "mineral floor" - icon_state = "" - var/list/icons = list() - -/turf/simulated/floor/mineral/get_broken_states() - return list("[initial(icon_state)]_dam") - -/turf/simulated/floor/mineral/update_icon_state() - if(!broken && !burnt) - if(!(icon_state in icons)) - icon_state = initial(icon_state) - -//PLASMA -/turf/simulated/floor/mineral/plasma - name = "plasma floor" - icon_state = "plasma" - floor_tile = /obj/item/stack/tile/mineral/plasma - icons = list("plasma","plasma_dam") - -/turf/simulated/floor/mineral/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ..() - if(exposed_temperature > 300) - PlasmaBurn() - -/turf/simulated/floor/mineral/plasma/attack_by(obj/item/attacking, mob/user, params) - if(..()) - return FINISH_ATTACK - - if(attacking.get_heat() > 300)//If the temperature of the object is over 300, then ignite - message_admins("Plasma flooring was ignited by [key_name_admin(user)]([ADMIN_QUE(user,"?")]) ([ADMIN_FLW(user,"FLW")]) in ([x],[y],[z] - JMP)",0,1) - log_game("Plasma flooring was ignited by [key_name(user)] in ([x],[y],[z])") - investigate_log("was ignited by [key_name(user)]","atmos") - ignite(attacking.get_heat()) - return FINISH_ATTACK - -/turf/simulated/floor/mineral/plasma/welder_act(mob/user, obj/item/I) - if(I.use_tool(src, user, volume = I.tool_volume)) - user.visible_message("[user] sets [src] on fire!",\ - "[src] disintegrates into a cloud of plasma!",\ - "You hear a 'whoompf' and a roar.") - ignite(2500) //Big enough to ignite - message_admins("Plasma wall ignited by [key_name_admin(user)] in ([x], [y], [z] - JMP)",0,1) - log_game("Plasma wall ignited by [key_name(user)] in ([x], [y], [z])") - investigate_log("was ignited by [key_name(user)]","atmos") - -/turf/simulated/floor/mineral/plasma/proc/PlasmaBurn() - make_plating() - atmos_spawn_air(LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS, 20) - -/turf/simulated/floor/mineral/plasma/proc/ignite(exposed_temperature) - if(exposed_temperature > 300) - PlasmaBurn() - -//GOLD -/turf/simulated/floor/mineral/gold - name = "gold floor" - icon_state = "gold" - floor_tile = /obj/item/stack/tile/mineral/gold - icons = list("gold","gold_dam") - -/turf/simulated/floor/mineral/gold/fancy - icon_state = "goldfancy" - floor_tile = /obj/item/stack/tile/mineral/gold/fancy - icons = list("goldfancy","goldfancy_dam") - -//SILVER -/turf/simulated/floor/mineral/silver - name = "silver floor" - icon_state = "silver" - floor_tile = /obj/item/stack/tile/mineral/silver - icons = list("silver","silver_dam") - -/turf/simulated/floor/mineral/silver/lavaland_air - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - -/turf/simulated/floor/mineral/silver/fancy - icon_state = "silverfancy" - floor_tile = /obj/item/stack/tile/mineral/silver/fancy - icons = list("silverfancy","silverfancy_dam") - -/turf/simulated/floor/mineral/silver/biodome_snow - temperature = 180 - -//TITANIUM (shuttle) - -/turf/simulated/floor/mineral/titanium - name = "shuttle floor" - icon_state = "titanium" - floor_tile = /obj/item/stack/tile/mineral/titanium - -/turf/simulated/floor/mineral/titanium/get_broken_states() - return list("titanium_dam1", "titanium_dam2", "titanium_dam3", "titanium_dam4", "titanium_dam5") - -/turf/simulated/floor/mineral/titanium/airless - oxygen = 0 - nitrogen = 0 - temperature = TCMB - -/turf/simulated/floor/mineral/titanium/blue - icon_state = "titanium_blue" - -/turf/simulated/floor/mineral/titanium/blue/airless - oxygen = 0 - nitrogen = 0 - temperature = TCMB - -/turf/simulated/floor/mineral/titanium/yellow - icon_state = "titanium_yellow" - -/turf/simulated/floor/mineral/titanium/yellow/airless - oxygen = 0 - nitrogen = 0 - temperature = TCMB - -/turf/simulated/floor/mineral/titanium/purple - icon_state = "titanium_purple" - floor_tile = /obj/item/stack/tile/mineral/titanium/purple - -/turf/simulated/floor/mineral/titanium/purple/airless - oxygen = 0 - nitrogen = 0 - temperature = TCMB - -//PLASTITANIUM (syndieshuttle) -/turf/simulated/floor/mineral/plastitanium - name = "shuttle floor" - icon_state = "plastitanium" - floor_tile = /obj/item/stack/tile/mineral/plastitanium - -/turf/simulated/floor/mineral/plastitanium/get_broken_states() - return list("plastitanium_dam1", "plastitanium_dam2", "plastitanium_dam3", "plastitanium_dam4", "plastitanium_dam5") - -/turf/simulated/floor/mineral/plastitanium/red - icon_state = "plastitanium_red" - -/turf/simulated/floor/mineral/plastitanium/red/airless - oxygen = 0 - nitrogen = 0 - temperature = TCMB - -/turf/simulated/floor/mineral/plastitanium/red/brig - name = "brig floor" - -/turf/simulated/floor/mineral/plastitanium/red/nitrogen - oxygen = 0 - nitrogen = MOLES_N2STANDARD + MOLES_O2STANDARD - - -//BANANIUM -/turf/simulated/floor/mineral/bananium - name = "bananium floor" - icon_state = "bananium" - floor_tile = /obj/item/stack/tile/mineral/bananium - icons = list("bananium","bananium_dam") - var/spam_flag = 0 - -/turf/simulated/floor/mineral/bananium/Entered(mob/living/M) - .=..() - if(!.) - if(istype(M)) - squeek() - -/turf/simulated/floor/mineral/bananium/attack_by(obj/item/attacking, mob/user, params) - if(..()) - return FINISH_ATTACK - - honk() - -/turf/simulated/floor/mineral/bananium/attack_hand(mob/user) - .=..() - if(!.) - honk() - -/turf/simulated/floor/mineral/bananium/proc/honk() - if(spam_flag < world.time) - playsound(src, 'sound/items/bikehorn.ogg', 50, 1) - spam_flag = world.time + 20 - -/turf/simulated/floor/mineral/bananium/proc/squeek() - if(spam_flag < world.time) - playsound(src, 'sound/effects/clownstep1.ogg', 50, 1) - spam_flag = world.time + 10 - -/turf/simulated/floor/mineral/bananium/airless - oxygen = 0 - nitrogen = 0 - temperature = TCMB - - -/turf/simulated/floor/mineral/bananium/lubed/Initialize(mapload) - . = ..() - MakeSlippery(TURF_WET_LUBE, INFINITY) - -/turf/simulated/floor/mineral/bananium/lubed/pry_tile(obj/item/C, mob/user, silent = FALSE) //I want to get off Mr Honk's Wild Ride - if(ishuman(user)) - var/mob/living/carbon/human/H = user - to_chat(H, "You lose your footing trying to pry off the tile!") - H.slip("the floor", 10 SECONDS, tilesSlipped = 4, walkSafely = 0, slipAny = 1) - return - -/turf/simulated/floor/mineral/bananium/lubed/lavaland_air - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - -//TRANQUILLITE -/turf/simulated/floor/mineral/tranquillite - name = "silent floor" - icon_state = "tranquillite" - floor_tile = /obj/item/stack/tile/mineral/tranquillite - footstep = null - barefootstep = null - clawfootstep = null - heavyfootstep = null - -//DIAMOND -/turf/simulated/floor/mineral/diamond - name = "diamond floor" - icon_state = "diamond" - floor_tile = /obj/item/stack/tile/mineral/diamond - icons = list("diamond","diamond_dam") - -//URANIUM -/turf/simulated/floor/mineral/uranium - name = "uranium floor" - icon_state = "uranium" - floor_tile = /obj/item/stack/tile/mineral/uranium - icons = list("uranium","uranium_dam") - var/last_event = 0 - var/active = FALSE - -/turf/simulated/floor/mineral/uranium/Entered(mob/AM) - .=..() - if(!.) - if(istype(AM)) - radiate() - -/turf/simulated/floor/mineral/uranium/attack_by(obj/item/attacking, mob/user, params) - if(..()) - return FINISH_ATTACK - - radiate() - -/turf/simulated/floor/mineral/uranium/attack_hand(mob/user) - .=..() - if(!.) - radiate() - -/turf/simulated/floor/mineral/uranium/proc/radiate() - if(!active) - if(world.time > last_event + 15) - active = TRUE - radiation_pulse(src, 10) - for(var/turf/simulated/floor/mineral/uranium/T in orange(1, src)) - T.radiate() - last_event = world.time - active = FALSE - -// ALIEN ALLOY -/turf/simulated/floor/mineral/abductor - name = "alien floor" - icon_state = "alienpod1" - floor_tile = /obj/item/stack/tile/mineral/abductor - icons = list("alienpod1", "alienpod2", "alienpod3", "alienpod4", "alienpod5", "alienpod6", "alienpod7", "alienpod8", "alienpod9") - -/turf/simulated/floor/mineral/abductor/Initialize(mapload) - . = ..() - icon_state = "alienpod[rand(1,9)]" - -/turf/simulated/floor/mineral/abductor/break_tile() - return //unbreakable - -/turf/simulated/floor/mineral/abductor/burn_tile() - return //unburnable - -/turf/simulated/floor/mineral/abductor/make_plating() - return ChangeTurf(/turf/simulated/floor/plating/abductor2) - -/turf/simulated/floor/plating/abductor2 - name = "alien plating" - icon_state = "alienplating" - -/turf/simulated/floor/plating/abductor2/break_tile() - return //unbreakable - -/turf/simulated/floor/plating/abductor2/burn_tile() - return //unburnable - -/turf/simulated/floor/plating/abductor/lavaland_air - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND diff --git a/code/game/turfs/simulated/floor/plasteel_floor.dm b/code/game/turfs/simulated/floor/plasteel_floor.dm deleted file mode 100644 index 786514e0e56ca..0000000000000 --- a/code/game/turfs/simulated/floor/plasteel_floor.dm +++ /dev/null @@ -1,110 +0,0 @@ -/turf/simulated/floor/plasteel - icon_state = "floor" - floor_tile = /obj/item/stack/tile/plasteel - -/turf/simulated/floor/plasteel/update_icon_state() - if(!broken && !burnt) - icon_state = icon_regular_floor - -/turf/simulated/floor/plasteel/get_broken_states() - return list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5") - -/turf/simulated/floor/plasteel/pressure_debug - -/turf/simulated/floor/plasteel/pressure_debug/airless - name = "airless floor" - oxygen = 0 - nitrogen = 0 - temperature = TCMB - -/turf/simulated/floor/plasteel/pressure_debug/Initialize(mapload) - ..() - addtimer(CALLBACK(src, PROC_REF(update_color)), 1, TIMER_LOOP) - -/turf/simulated/floor/plasteel/pressure_debug/proc/update_color() - var/datum/gas_mixture/air = get_readonly_air() - var/ratio = min(1, air.return_pressure() / ONE_ATMOSPHERE) - color = rgb(255 * (1 - ratio), 0, 255 * ratio) - -/turf/simulated/floor/plasteel/airless - name = "airless floor" - oxygen = 0 - nitrogen = 0 - temperature = TCMB - smoothing_groups = list(SMOOTH_GROUP_TURF, SMOOTH_GROUP_LATTICE) - -/turf/simulated/floor/plasteel/lavaland_air - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - -/turf/simulated/floor/plasteel/airless/Initialize(mapload) - . = ..() - name = "floor" - -/// For bomb testing range -/turf/simulated/floor/plasteel/airless/indestructible - -/turf/simulated/floor/plasteel/airless/indestructible/ex_act(severity) - return - -/turf/simulated/floor/plasteel/goonplaque - name = "Commemorative Plaque" - desc = "\"This is a plaque in honour of our comrades on the G4407 Stations. Hopefully TG4407 model can live up to your fame and fortune.\" Scratched in beneath that is a crude image of a meteor and a spaceman. The spaceman is laughing. The meteor is exploding." - icon_state = "plaque" - -/turf/simulated/floor/plasteel/goonplaque/memorial - name = "Memorial Plaque" - desc = "\"This is a plaque in honour of those who died in the great space lube airlock incident.\" Scratched in beneath that is a crude image of a clown and a spaceman. The spaceman is slipping. The clown is laughing." - -/turf/simulated/floor/plasteel/goonplaque/commission - name = "Commission Plaque" - desc = "Epsilon Eridani Sector - 'Meta' Class Outpost - Commissioned 11/03/2557 - NSS Cerebron." - -/turf/simulated/floor/plasteel/goonplaque/nosey - name = "Nosey little bastard aren't you?" - desc = "Nosey little bastard aren't you?" - -/turf/simulated/floor/plasteel/goonplaque/violence - name = "Violence Free Area" - desc = "Violence Free Area." - -//TODO: Make subtypes for all normal turf icons -/turf/simulated/floor/plasteel/white - icon_state = "white" -/turf/simulated/floor/plasteel/white/side - icon_state = "whitehall" -/turf/simulated/floor/plasteel/white/corner - icon_state = "whitecorner" - -/turf/simulated/floor/plasteel/dark - icon_state = "darkfull" - -/turf/simulated/floor/plasteel/dark/telecomms - nitrogen = 100 - oxygen = 0 - temperature = 80 - -/turf/simulated/floor/plasteel/dark/nitrogen - nitrogen = 100 - oxygen = 0 - -/turf/simulated/floor/plasteel/freezer - icon_state = "freezerfloor" - -/turf/simulated/floor/plasteel/stairs - icon_state = "stairs" - -/turf/simulated/floor/plasteel/stairs/left - icon_state = "stairs-l" - -/turf/simulated/floor/plasteel/stairs/medium - icon_state = "stairs-m" - -/turf/simulated/floor/plasteel/stairs/right - icon_state = "stairs-r" - -/turf/simulated/floor/plasteel/grimy - icon_state = "grimy" diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm deleted file mode 100644 index ce008def807b8..0000000000000 --- a/code/game/turfs/simulated/minerals.dm +++ /dev/null @@ -1,396 +0,0 @@ -/**********************Mineral deposits**************************/ - -/// wall piece -/turf/simulated/mineral - name = "rock" - icon = 'icons/turf/walls/smoothrocks.dmi' - icon_state = "smoothrocks-0" - base_icon_state = "smoothrocks" - smoothing_flags = SMOOTH_BITMASK | SMOOTH_BORDER - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_MINERAL_WALLS) - canSmoothWith = list(SMOOTH_GROUP_MINERAL_WALLS) - baseturf = /turf/simulated/floor/plating/asteroid/airless - opacity = TRUE - density = TRUE - blocks_air = TRUE - flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2 - rad_insulation = RAD_MEDIUM_INSULATION - layer = EDGED_TURF_LAYER - temperature = TCMB - color = COLOR_ROCK - var/environment_type = "asteroid" - var/turf/simulated/floor/plating/turf_type = /turf/simulated/floor/plating/asteroid/airless - var/last_act = 0 - - var/defer_change = 0 - var/mine_time = 4 SECONDS //Changes how fast the turf is mined by pickaxes, multiplied by toolspeed - /// Should this be set to the normal rock colour on init? - var/should_reset_color = TRUE - - /// The ore type, if any, that should spawn in the wall on Initialize. - /// Expected to be a subtype of [/datum/ore]. - var/preset_ore_type - /// The representation of the unmined ore in the wall, if any. - var/datum/ore/ore - -/turf/simulated/mineral/Initialize(mapload) - . = ..() - - if(should_reset_color) - color = COLOR_ROCK - - if(preset_ore_type) - set_ore(preset_ore_type) - - AddComponent(/datum/component/debris, DEBRIS_ROCK, -20, 10, 1) - -/turf/simulated/mineral/proc/set_ore(ore_type) - if(!ore_type) - return - - if(ore) - qdel(ore) - - ore = new ore_type() - if(ore.spread_chance) - for(var/dir in GLOB.cardinal) - if(prob(ore.spread_chance)) - var/turf/simulated/mineral/T = get_step(src, dir) - if(istype(T)) - T.set_ore(ore_type) - -/turf/simulated/mineral/shuttleRotate(rotation) - QUEUE_SMOOTH(src) - -/turf/simulated/mineral/proc/invalid_tool(mob/user, obj/item/pickaxe/axe) - if(!istype(axe)) - return TRUE - - return FALSE - -/turf/simulated/mineral/attack_by(obj/item/attacking, mob/user, params) - if(..()) - return FINISH_ATTACK - - if(!user.IsAdvancedToolUser()) - to_chat(usr, "You don't have the dexterity to do this!") - return FINISH_ATTACK - - if(istype(attacking, /obj/item/pickaxe)) - var/obj/item/pickaxe/P = attacking - if(invalid_tool(user, P)) - return FINISH_ATTACK - - var/turf/T = user.loc - if(!isturf(T)) - return FINISH_ATTACK - - if(last_act + (mine_time * P.toolspeed) > world.time) // Prevents message spam - return FINISH_ATTACK - - last_act = world.time - to_chat(user, "You start picking...") - P.playDigSound() - - if(do_after(user, mine_time * P.toolspeed, target = src)) - if(ismineralturf(src)) //sanity check against turf being deleted during digspeed delay - to_chat(user, "You finish cutting into the rock.") - gets_drilled(user) - SSblackbox.record_feedback("tally", "pick_used_mining", 1, P.name) - - return FINISH_ATTACK - else - return attack_hand(user) - -/turf/simulated/mineral/proc/mine_ore(mob/user, triggered_by_explosion) - if(!ore) - return MINERAL_ALLOW_DIG - - for(var/obj/effect/temp_visual/mining_overlay/M in src) - qdel(M) - - return ore.on_mine(src, user, triggered_by_explosion) - -/turf/simulated/mineral/proc/gets_drilled(mob/user, triggered_by_explosion = FALSE) - if(mine_ore(user, triggered_by_explosion) == MINERAL_PREVENT_DIG) - return - - ChangeTurf(turf_type, defer_change) - addtimer(CALLBACK(src, PROC_REF(AfterChange)), 1, TIMER_UNIQUE) - playsound(src, 'sound/effects/break_stone.ogg', 50, 1) //beautiful destruction - -/turf/simulated/mineral/attack_animal(mob/living/simple_animal/user) - if((user.environment_smash & ENVIRONMENT_SMASH_WALLS) || (user.environment_smash & ENVIRONMENT_SMASH_RWALLS)) - gets_drilled() - ..() - -/turf/simulated/mineral/attack_alien(mob/living/carbon/alien/M) - to_chat(M, "You start digging into the rock...") - playsound(src, 'sound/effects/break_stone.ogg', 50, TRUE) - if(do_after(M, 40, target = src)) - to_chat(M, "You tunnel into the rock.") - gets_drilled(M) - -/turf/simulated/mineral/Bumped(atom/movable/AM) - ..() - if(ishuman(AM)) - var/mob/living/carbon/human/H = AM - if((istype(H.l_hand,/obj/item/pickaxe)) && (!H.hand)) - attack_by(H.l_hand, H) - else if((istype(H.r_hand,/obj/item/pickaxe)) && H.hand) - attack_by(H.r_hand, H) - return - - else if(isrobot(AM)) - var/mob/living/silicon/robot/R = AM - if(istype(R.module_active, /obj/item/pickaxe)) - attack_by(R.module_active, R) - - else if(ismecha(AM)) - var/obj/mecha/M = AM - if(istype(M.selected, /obj/item/mecha_parts/mecha_equipment/drill)) - M.selected.action(src) - - -/turf/simulated/mineral/acid_melt() - ChangeTurf(baseturf) - -/turf/simulated/mineral/ex_act(severity) - ..() - switch(severity) - if(3) - if(prob(75)) - gets_drilled(null, 1) - if(2) - if(prob(90)) - gets_drilled(null, 1) - if(1) - gets_drilled(null, 1) - -/turf/simulated/mineral/random - var/mineralSpawnChanceList = list( - /datum/ore/iron = 40, - /datum/ore/plasma = 20, - /datum/ore/silver = 12, - /datum/ore/titanium = 11, - /datum/ore/gold = 10, - /datum/ore/uranium = 5, - /datum/ore/gibtonite = 4, - /datum/ore/bluespace = 1, - /datum/ore/diamond = 1, - ) - - var/mineralChance = 10 - -/turf/simulated/mineral/random/Initialize(mapload) - . = ..() - - mineralSpawnChanceList = typelist("mineralSpawnChanceList", mineralSpawnChanceList) - if(prob(mineralChance)) - var/new_ore_type = pickweight(mineralSpawnChanceList) - set_ore(new_ore_type) - -/turf/simulated/mineral/ancient - name = "ancient rock" - desc = "A rare asteroid rock that appears to be resistant to all mining tools except pickaxes!" - smoothing_groups = list(SMOOTH_GROUP_MINERAL_WALLS, SMOOTH_GROUP_ASTEROID_WALLS) - canSmoothWith = list(SMOOTH_GROUP_MINERAL_WALLS, SMOOTH_GROUP_ASTEROID_WALLS) - mine_time = 6 SECONDS - color = COLOR_ANCIENT_ROCK - layer = MAP_EDITOR_TURF_LAYER - real_layer = TURF_LAYER - should_reset_color = FALSE - baseturf = /turf/simulated/floor/plating/asteroid/ancient - -/turf/simulated/mineral/ancient/blob_act(obj/structure/blob/B) - if(prob(50)) - blob_destruction() - -/turf/simulated/mineral/ancient/proc/blob_destruction() - playsound(src, pick('sound/effects/picaxe1.ogg', 'sound/effects/picaxe2.ogg', 'sound/effects/picaxe3.ogg'), 30, 1 ) - - for(var/obj/O in contents) //Eject contents! - if(istype(O, /obj/structure/sign/poster)) - var/obj/structure/sign/poster/P = O - P.roll_and_drop(src) - else - O.forceMove(src) - - ChangeTurf(/turf/simulated/floor/plating/asteroid/ancient) - return TRUE - -/turf/simulated/mineral/ancient/outer - name = "cold ancient rock" - desc = "A rare and dense asteroid rock that appears to be resistant to everything except diamond and sonic tools! Can not be used to create portals to hell." - mine_time = 15 SECONDS - color = COLOR_COLD_ANCIENT_ROCK - var/static/list/allowed_picks_typecache - -/turf/simulated/mineral/ancient/outer/Initialize(mapload) - . = ..() - allowed_picks_typecache = typecacheof(list( - /obj/item/pickaxe/drill/jackhammer, - /obj/item/pickaxe/diamond, - /obj/item/pickaxe/drill/cyborg/diamond, - /obj/item/pickaxe/drill/diamonddrill, - )) - -/turf/simulated/mineral/ancient/outer/invalid_tool(mob/user, obj/item/pickaxe/axe) - if(..()) - return TRUE - - if(!(is_type_in_typecache(axe, allowed_picks_typecache))) - to_chat(user, "Only diamond tools or a sonic jackhammer can break this rock.") - return TRUE - -/turf/simulated/mineral/ancient/lava_land_surface_hard - name = "hardened volcanic rock" - desc = "A dense volcanic rock that appears to be resistant to everything except diamond and sonic tools!" - mine_time = 15 SECONDS - color = COLOR_HARD_ROCK - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface_hard - var/static/list/allowed_picks_typecache - -/turf/simulated/mineral/ancient/lava_land_surface_hard/Initialize(mapload) - . = ..() - allowed_picks_typecache = typecacheof(list( - /obj/item/pickaxe/drill/jackhammer, - /obj/item/pickaxe/diamond, - /obj/item/pickaxe/drill/cyborg/diamond, - /obj/item/pickaxe/drill/diamonddrill, - )) - -/turf/simulated/mineral/ancient/lava_land_surface_hard/invalid_tool(mob/user, obj/item/pickaxe/axe) - if(..()) - return TRUE - - if(!(is_type_in_typecache(axe, allowed_picks_typecache))) - to_chat(user, "Only diamond tools or a sonic jackhammer can break this rock.") - return TRUE - -/turf/simulated/mineral/random/high_chance - color = COLOR_YELLOW - mineralChance = 25 - mineralSpawnChanceList = list( - /datum/ore/silver = 50, - /datum/ore/plasma = 50, - /datum/ore/gold = 45, - /datum/ore/titanium = 45, - /datum/ore/uranium = 35, - /datum/ore/diamond = 30, - /datum/ore/bluespace = 20, - ) - -/turf/simulated/mineral/random/high_chance/clown - mineralChance = 40 - mineralSpawnChanceList = list( - /datum/ore/uranium = 35, - /datum/ore/iron = 30, - /datum/ore/bananium = 15, - /datum/ore/tranquillite = 15, - /datum/ore/bluespace = 10, - /datum/ore/gold = 5, - /datum/ore/silver = 5, - /datum/ore/diamond = 2, - ) - -/turf/simulated/mineral/random/high_chance/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/lava/mapping_lava - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 - mineralSpawnChanceList = list( - /datum/ore/silver = 50, - /datum/ore/plasma = 50, - /datum/ore/gold = 45, - /datum/ore/titanium = 45, - /datum/ore/uranium = 35, - /datum/ore/diamond = 30, - /datum/ore/bluespace = 20, - ) - -/turf/simulated/mineral/random/low_chance - color = COLOR_VIOLET - mineralChance = 6 - mineralSpawnChanceList = list( - /datum/ore/iron = 40, - /datum/ore/plasma = 15, - /datum/ore/silver = 6, - /datum/ore/gold = 4, - /datum/ore/titanium = 4, - /datum/ore/gibtonite = 2, - /datum/ore/uranium = 2, - /datum/ore/diamond = 1, - /datum/ore/bluespace = 1, - ) - -/turf/simulated/mineral/random/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/lava/mapping_lava - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 - -/turf/simulated/mineral/random/labormineral - mineralSpawnChanceList = list( - /datum/ore/iron = 95, - /datum/ore/plasma = 30, - /datum/ore/silver = 20, - /datum/ore/gold = 8, - /datum/ore/titanium = 8, - /datum/ore/uranium = 3, - /datum/ore/gibtonite = 2, - /datum/ore/diamond = 1, - ) - color = COLOR_MAROON - -/turf/simulated/mineral/random/volcanic/labormineral - mineralSpawnChanceList = list( - /datum/ore/iron = 95, - /datum/ore/plasma = 30, - /datum/ore/silver = 20, - /datum/ore/titanium = 8, - /datum/ore/gold = 8, - /datum/ore/uranium = 3, - /datum/ore/gibtonite = 2, - /datum/ore/bluespace = 1, - /datum/ore/diamond = 1, - ) - -// Actual minerals -/turf/simulated/mineral/clown - preset_ore_type = /datum/ore/bananium - -/turf/simulated/mineral/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 - -/turf/simulated/mineral/volcanic/clown - preset_ore_type = /datum/ore/bananium - -/turf/simulated/mineral/volcanic/lava_land_surface - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/lava/mapping_lava - defer_change = 1 diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm deleted file mode 100644 index 422cf388c2dff..0000000000000 --- a/code/game/turfs/simulated/walls.dm +++ /dev/null @@ -1,555 +0,0 @@ -#define MAX_DENT_DECALS 15 - -/turf/simulated/wall - name = "wall" - desc = "A huge chunk of metal used to separate rooms." - icon = 'icons/turf/walls/wall.dmi' - icon_state = "wall-0" - base_icon_state = "wall" - smoothing_flags = SMOOTH_BITMASK - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_REGULAR_WALLS) - canSmoothWith = list(SMOOTH_GROUP_WALLS, SMOOTH_GROUP_REGULAR_WALLS, SMOOTH_GROUP_REINFORCED_WALLS) - - var/rotting = FALSE - - var/damage = 0 - var/damage_cap = 100 //Wall will break down to girders if damage reaches this point - - var/global/damage_overlays[8] - var/melting = FALSE //TRUE if wall is currently being melted with thermite - - opacity = TRUE - density = TRUE - blocks_air = TRUE - explosion_block = 1 - - flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2 - flags_ricochet = RICOCHET_HARD - rad_insulation = RAD_MEDIUM_INSULATION - - thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT - heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall - var/heat_resistance = 5000 - - var/can_dismantle_with_welder = TRUE - var/hardness = 40 //lower numbers are harder. Used to determine the probability of a hulk smashing through. - var/slicing_duration = 10 SECONDS - var/engraving //engraving on the wall - var/engraving_quality - var/list/dent_decals - var/sheet_type = /obj/item/stack/sheet/metal - var/sheet_amount = 2 - var/girder_type = /obj/structure/girder - /// Are we a explodable turf? - var/explodable = FALSE - /// Do we have a explodable overlay? - var/explodable_overlay - -/turf/simulated/wall/Initialize(mapload) - . = ..() - if(smoothing_flags & SMOOTH_DIAGONAL_CORNERS && fixed_underlay) //Set underlays for the diagonal walls. - var/mutable_appearance/underlay_appearance = mutable_appearance(layer = TURF_LAYER, plane = FLOOR_PLANE) - if(fixed_underlay["space"]) - underlay_appearance.icon = 'icons/turf/space.dmi' - underlay_appearance.icon_state = SPACE_ICON_STATE - underlay_appearance.plane = PLANE_SPACE - else - underlay_appearance.icon = fixed_underlay["icon"] - underlay_appearance.icon_state = fixed_underlay["icon_state"] - fixed_underlay = string_assoc_list(fixed_underlay) - underlays += underlay_appearance - AddComponent(/datum/component/debris, DEBRIS_SPARKS, -20, 10, 1) - -/turf/simulated/wall/BeforeChange() - for(var/obj/effect/overlay/wall_rot/WR in src) - qdel(WR) - . = ..() - -//Appearance -/turf/simulated/wall/examine(mob/user) //If you change this, consider changing the examine_status proc of false walls to match - . = ..() - - if(!damage) - . += "It looks fully intact." - else - var/dam = damage / damage_cap - if(dam <= 0.3) - . += "It looks slightly damaged." - else if(dam <= 0.6) - . += "It looks moderately damaged." - else - . += "It looks heavily damaged." - - if(rotting) - . += "There is fungus growing on [src]." - if(can_dismantle_with_welder) - . += "Using a lit welding tool on this item will allow you to slice through it, eventually removing the outer layer." - -/turf/simulated/wall/update_overlays() - . = ..() - if(!damage_overlays[1]) //list hasn't been populated - generate_overlays() - - QUEUE_SMOOTH(src) - - if(explodable && !explodable_overlay) - explodable_overlay = icon('icons/turf/overlays.dmi', pick("explodable"), pick(NORTH, SOUTH, EAST, WEST)) - . += explodable_overlay - - if(!damage) - . += dent_decals - return - - var/overlay = round(damage / damage_cap * length(damage_overlays)) + 1 - if(overlay > length(damage_overlays)) - overlay = length(damage_overlays) - - if(length(dent_decals)) - . += dent_decals - - . += damage_overlays[overlay] - . += dent_decals - -/turf/simulated/wall/proc/generate_overlays() - var/alpha_inc = 256 / length(damage_overlays) - - for(var/i = 1; i <= length(damage_overlays); i++) - var/image/img = image(icon = 'icons/turf/walls.dmi', icon_state = "overlay_damage") - img.blend_mode = BLEND_MULTIPLY - img.alpha = (i * alpha_inc) - 1 - damage_overlays[i] = img - -//Damage - -/turf/simulated/wall/proc/take_damage(dam) - if(dam) - damage = max(0, damage + dam) - update_damage() - return - -/turf/simulated/wall/proc/update_damage() - var/cap = damage_cap - if(rotting) - cap = cap / 10 - - if(damage >= cap) - dismantle_wall() - else - update_icon() - -/turf/simulated/wall/dismantle_wall(devastated = FALSE, explode = FALSE) - if(devastated) - devastate_wall() - else - playsound(src, 'sound/items/welder.ogg', 100, 1) - var/newgirder = break_wall() - if(newgirder) //maybe we don't /want/ a girder! - transfer_fingerprints_to(newgirder) - - for(var/obj/O in src.contents) //Eject contents! - if(istype(O,/obj/structure/sign/poster)) - var/obj/structure/sign/poster/P = O - P.roll_and_drop(src) - else - O.forceMove(src) - - ChangeTurf(/turf/simulated/floor/plating) - return TRUE - -/turf/simulated/wall/proc/break_wall() - new sheet_type(src, sheet_amount) - return new girder_type(src) - -/turf/simulated/wall/proc/devastate_wall() - new sheet_type(src, sheet_amount) - new /obj/item/stack/sheet/metal(src) - -/turf/simulated/wall/ex_act(severity) - SEND_SIGNAL(src, COMSIG_ATOM_EX_ACT, severity) - switch(severity) - if(1.0) - ChangeTurf(baseturf) - if(2.0) - if(prob(50)) - take_damage(rand(150, 250)) - else - dismantle_wall(1, 1) - if(3.0) - take_damage(rand(0, 250)) - -/turf/simulated/wall/blob_act(obj/structure/blob/B) - if(prob(50)) - dismantle_wall() - else - add_dent(PROJECTILE_IMPACT_WALL_DENT_HIT) - -/turf/simulated/wall/rpd_act(mob/user, obj/item/rpd/our_rpd) - if(our_rpd.mode == RPD_ATMOS_MODE) - if(!our_rpd.ranged) - playsound(src, "sound/weapons/circsawhit.ogg", 50, 1) - user.visible_message("[user] starts drilling a hole in [src]...", "You start drilling a hole in [src]...", "You hear drilling.") - if(!do_after(user, our_rpd.walldelay, target = src)) //Drilling into walls takes time - return - our_rpd.create_atmos_pipe(user, src) - else if(our_rpd.mode == RPD_DISPOSALS_MODE && !our_rpd.ranged) - return - else - ..() - -/turf/simulated/wall/mech_melee_attack(obj/mecha/M) - M.do_attack_animation(src) - switch(M.damtype) - if(BRUTE) - playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) - M.visible_message("[M.name] hits [src]!", "You hit [src]!") - if(prob(hardness + M.force) && M.force > 20) - dismantle_wall(1) - playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) - else - add_dent(PROJECTILE_IMPACT_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 - -// Wall-rot effect, a nasty fungus that destroys walls. -/turf/simulated/wall/proc/rot() - if(!rotting) - rotting = 1 - - var/number_rots = rand(2,3) - for(var/i=0, iThe thermite starts melting through the wall.") - - if(speed) - melting = TRUE - while(speed > 0) - playsound(src, 'sound/items/welder.ogg', 100, TRUE) - speed = max(0, speed - 1 SECONDS) - sleep(1) - burn_down() - var/turf/simulated/floor/F = src - F.burn_tile() - F.icon_state = "plating" - if(O) qdel(O) - return - - melting = TRUE - while(reagents.get_reagent_amount("thermite") > 0) - reagents.remove_reagent("thermite", 5) - if(damage_cap - damage <= 30) - burn_down() - - var/turf/simulated/floor/F = src - F.burn_tile() - F.icon_state = "plating" - break - take_damage(30) - playsound(src, 'sound/items/welder.ogg', 100, TRUE) - sleep(1 SECONDS) - if(iswallturf(src)) - melting = FALSE - if(O) - qdel(O) - return - -//Interactions - -/turf/simulated/wall/attack_animal(mob/living/simple_animal/M) - M.changeNext_move(CLICK_CD_MELEE) - M.do_attack_animation(src) - if((M.environment_smash & ENVIRONMENT_SMASH_WALLS) || (M.environment_smash & ENVIRONMENT_SMASH_RWALLS)) - if(M.environment_smash & ENVIRONMENT_SMASH_RWALLS) - playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) - dismantle_wall(1) - to_chat(M, "You smash through the wall.") - else - to_chat(M, "You smash against the wall.") - take_damage(rand(25, 75)) - return - - to_chat(M, "You push the wall but nothing happens!") - return - -/turf/simulated/wall/attack_hulk(mob/user, does_attack_animation = FALSE) - ..(user, TRUE) - - if(prob(hardness) || rotting) - playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) - user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - dismantle_wall(TRUE) - else - playsound(src, 'sound/effects/bang.ogg', 50, 1) - add_dent(PROJECTILE_IMPACT_WALL_DENT_HIT) - to_chat(user, "You punch the wall.") - return TRUE - -/turf/simulated/wall/attack_hand(mob/user) - user.changeNext_move(CLICK_CD_MELEE) - if(rotting) - if(hardness <= 10) - to_chat(user, "This wall feels rather unstable.") - return - else - to_chat(user, "The wall crumbles under your touch.") - dismantle_wall() - return - - to_chat(user, "You push the wall but nothing happens!") - playsound(src, 'sound/weapons/genhit.ogg', 25, 1) - add_fingerprint(user) - return ..() - -/turf/simulated/wall/attack_by(obj/item/attacking, mob/user, params) - if(..()) - return FINISH_ATTACK - - user.changeNext_move(CLICK_CD_MELEE) - - if(!isturf(user.loc)) - return FINISH_ATTACK // No touching walls unless you're on a turf (pretty sure attackby can't be called anyways but whatever) - - if(rotting && try_rot(attacking, user, params)) - return FINISH_ATTACK - - if(try_decon(attacking, user, params)) - return FINISH_ATTACK - - if(try_destroy(attacking, user, params)) - return FINISH_ATTACK - - if(try_wallmount(attacking, user, params)) - return CONTINUE_ATTACK - - // The cyborg gripper does a separate attackby, so bail from this one - if(istype(attacking, /obj/item/gripper)) - return CONTINUE_ATTACK - -/turf/simulated/wall/welder_act(mob/user, obj/item/I) - . = ..() - if(reagents?.get_reagent_amount("thermite") && I.use_tool(src, user, volume = I.tool_volume)) - thermitemelt(user) - return - if(rotting) - if(I.use_tool(src, user, volume = I.tool_volume)) - for(var/obj/effect/overlay/wall_rot/WR in src) - qdel(WR) - rotting = FALSE - to_chat(user, "You burn off the fungi with [I].") - return - - // Wall repair stuff - if(!I.tool_use_check(user, 0)) - return - - var/repairing - var/time - if(user.a_intent == INTENT_HARM) // Harm intent - if(can_dismantle_with_welder) - repairing = FALSE - time = slicing_duration - WELDER_ATTEMPT_SLICING_MESSAGE - else - return - - else // Any other intents - if(damage || LAZYLEN(dent_decals)) - repairing = TRUE - time = max(5, damage / 5) - WELDER_ATTEMPT_REPAIR_MESSAGE - else - to_chat(user, "[src] doesn't need repairing.") - return - - if(I.use_tool(src, user, time, volume = I.tool_volume)) - if(repairing) - WELDER_REPAIR_SUCCESS_MESSAGE - dent_decals?.Cut() // I feel like this isn't needed but it can't hurt to keep it in anyway - update_icon() - take_damage(-damage) - else - WELDER_SLICING_SUCCESS_MESSAGE - dismantle_wall() - -/turf/simulated/wall/proc/try_rot(obj/item/I, mob/user, params) - if((!I.sharp && I.force >= 10) || I.force >= 20) - to_chat(user, "[src] crumbles away under the force of your [I.name].") - dismantle_wall(1) - return TRUE - return FALSE - -/turf/simulated/wall/proc/try_decon(obj/item/I, mob/user, params) - if(istype(I, /obj/item/gun/energy/plasmacutter)) - to_chat(user, "You begin slicing through the outer plating.") - playsound(src, I.usesound, 100, 1) - - if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 120 * I.toolspeed : 60 * I.toolspeed, target = src)) - to_chat(user, "You remove the outer plating.") - dismantle_wall() - visible_message("[user] slices apart [src]!", "You hear metal being sliced apart.") - return TRUE - - return FALSE - -/turf/simulated/wall/proc/try_destroy(obj/item/I, mob/user, params) - var/isdiamond = istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) // snowflake bullshit - - if(istype(I, /obj/item/pickaxe/drill/diamonddrill)) - to_chat(user, "You begin to drill though the wall.") - - if(do_after(user, isdiamond ? 480 * I.toolspeed : 240 * I.toolspeed, target = src)) // Diamond pickaxe has 0.25 toolspeed, so 120/60 - to_chat(user, "Your [I.name] tears though the last of the reinforced plating.") - dismantle_wall() - visible_message("[user] drills through [src]!", "You hear the grinding of metal.") - return TRUE - - else if(istype(I, /obj/item/pickaxe/drill/jackhammer)) - to_chat(user, "You begin to disintegrates the wall.") - - if(do_after(user, isdiamond ? 600 * I.toolspeed : 300 * I.toolspeed, target = src)) // Jackhammer has 0.1 toolspeed, so 60/30 - to_chat(user, "Your [I.name] disintegrates the reinforced plating.") - dismantle_wall() - visible_message("[user] disintegrates [src]!","You hear the grinding of metal.") - return TRUE - - else if(istype(I, /obj/item/pyro_claws)) - to_chat(user, "You begin to melt the wall.") - - if(do_after(user, isdiamond ? 60 * I.toolspeed : 30 * I.toolspeed, target = src)) // claws has 0.5 toolspeed, so 3/1.5 seconds - to_chat(user, "Your [I.name] melts the reinforced plating.") - dismantle_wall() - visible_message("[user] melts [src]!","You hear the hissing of steam.") - return TRUE - - else if(istype(I, /obj/item/zombie_claw)) - to_chat(user, "You begin to claw apart the wall.") - if(do_after(user, isdiamond ? 2 MINUTES * I.toolspeed : 1 MINUTES * I.toolspeed, target = src)) // 120/60 seconds by default - to_chat(user, "Your [I.name] rip apart the reinforced plating.") - dismantle_wall() - visible_message("[user] claws through [src]!","You hear the grinding of metal and bone.") - return TRUE - return FALSE - -/turf/simulated/wall/proc/try_wallmount(obj/item/I, mob/user, params) - if(istype(I, /obj/item/mounted)) - return TRUE // We don't want attack_hand running and doing stupid shit with this - - if(istype(I, /obj/item/poster)) - place_poster(I, user) - return TRUE - - //Bone White - Place pipes on walls // I fucking hate your code with a passion bone - if(istype(I, /obj/item/pipe)) - var/obj/item/pipe/P = I - if(P.pipe_type != -1) // ANY PIPE - playsound(get_turf(src), 'sound/weapons/circsawhit.ogg', 50, 1) - user.visible_message( - "[user] starts drilling a hole in [src].", - "You start drilling a hole in [src].", - "You hear a drill.") - - if(do_after(user, 80 * P.toolspeed, target = src)) - user.visible_message( - "[user] drills a hole in [src] and pushes [P] into the void.", - "You finish drilling [src] and push [P] into the void.", - "You hear a ratchet.") - - user.drop_item() - if(P.is_bent_pipe()) // bent pipe rotation fix see construction.dm - P.setDir(5) - if(user.dir == 1) - P.setDir(6) - else if(user.dir == 2) - P.setDir(9) - else if(user.dir == 4) - P.setDir(10) - else - P.setDir(user.dir) - P.forceMove(src) - P.level = 2 - return TRUE - return FALSE - -/turf/simulated/wall/singularity_pull(S, current_size) - ..() - wall_singularity_pull(current_size) - -/turf/simulated/wall/proc/wall_singularity_pull(current_size) - if(current_size >= STAGE_FIVE) - if(prob(50)) - dismantle_wall() - return - if(current_size == STAGE_FOUR) - if(prob(30)) - dismantle_wall() - -/turf/simulated/wall/narsie_act() - if(prob(20)) - ChangeTurf(/turf/simulated/wall/cult) - -/turf/simulated/wall/acid_act(acidpwr, acid_volume) - if(explosion_block >= 2) - acidpwr = min(acidpwr, 50) //we reduce the power so strong walls never get melted. - . = ..() - -/turf/simulated/wall/acid_melt() - dismantle_wall(1) - -/turf/simulated/wall/proc/add_dent(denttype, x=rand(-8, 8), y=rand(-8, 8)) - if(LAZYLEN(dent_decals) >= MAX_DENT_DECALS) - return - - var/mutable_appearance/decal = mutable_appearance('icons/effects/effects.dmi', "", BULLET_HOLE_LAYER) - switch(denttype) - if(PROJECTILE_IMPACT_WALL_DENT_SHOT) - decal.icon_state = "bullet_hole" - if(PROJECTILE_IMPACT_WALL_DENT_HIT) - decal.icon_state = "impact[rand(1, 3)]" - - decal.pixel_x = x - decal.pixel_y = y - - if(LAZYLEN(dent_decals)) - dent_decals += decal - else - dent_decals = list(decal) - - update_icon() - -/turf/simulated/wall/MouseEntered(location, control, params) - var/datum/hud/active_hud = usr.hud_used // Don't nullcheck this stuff, if it breaks we wanna know it breaks - var/screentip_mode = usr.client.prefs.screentip_mode - if(screentip_mode == 0 || (flags & NO_SCREENTIPS)) - active_hud.screentip_text.maptext = "" - return - //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]" - -/turf/simulated/wall/MouseExited(location, control, params) - usr.hud_used.screentip_text.maptext = "" - -#undef MAX_DENT_DECALS diff --git a/code/game/turfs/simulated/walls_mineral.dm b/code/game/turfs/simulated/walls_mineral.dm deleted file mode 100644 index 1d9d726abd089..0000000000000 --- a/code/game/turfs/simulated/walls_mineral.dm +++ /dev/null @@ -1,339 +0,0 @@ -/turf/simulated/wall/mineral - name = "mineral wall" - desc = "If you can see this, please make an issue report on GitHub." - icon_state = "" - smoothing_flags = SMOOTH_BITMASK - canSmoothWith = null - var/last_event = 0 - var/active = FALSE - -/turf/simulated/wall/mineral/shuttleRotate(rotation) - return //This override is needed to properly rotate the object when on a shuttle that is rotated. - -/turf/simulated/wall/mineral/gold - name = "gold wall" - desc = "A wall with gold plating. Swag!" - icon = 'icons/turf/walls/gold_wall.dmi' - icon_state = "gold_wall-0" - base_icon_state = "gold_wall" - sheet_type = /obj/item/stack/sheet/mineral/gold - explosion_block = 0 //gold is a soft metal you dingus. - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_GOLD_WALLS) - canSmoothWith = list(SMOOTH_GROUP_GOLD_WALLS) - -/turf/simulated/wall/mineral/silver - name = "silver wall" - desc = "A wall with silver plating. Shiny!" - icon = 'icons/turf/walls/silver_wall.dmi' - icon_state = "silver_wall-0" - base_icon_state = "silver_wall" - sheet_type = /obj/item/stack/sheet/mineral/silver - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_SILVER_WALLS) - canSmoothWith = list(SMOOTH_GROUP_SILVER_WALLS) - -/turf/simulated/wall/mineral/diamond - name = "diamond wall" - desc = "A wall with diamond plating. You monster." - icon = 'icons/turf/walls/diamond_wall.dmi' - icon_state = "diamond_wall-0" - base_icon_state = "diamond_wall" - sheet_type = /obj/item/stack/sheet/mineral/diamond - explosion_block = 3 - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_DIAMOND_WALLS) - canSmoothWith = list(SMOOTH_GROUP_DIAMOND_WALLS) - -/turf/simulated/wall/mineral/bananium - name = "bananium wall" - desc = "A wall with bananium plating. Honk!" - icon = 'icons/turf/walls/bananium_wall.dmi' - icon_state = "bananium_wall-0" - base_icon_state = "bananium_wall" - sheet_type = /obj/item/stack/sheet/mineral/bananium - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_BANANIUM_WALLS) - canSmoothWith = list(SMOOTH_GROUP_BANANIUM_WALLS) - -/turf/simulated/wall/mineral/sandstone - name = "sandstone wall" - desc = "A wall with sandstone plating." - icon = 'icons/turf/walls/sandstone_wall.dmi' - icon_state = "sandstone_wall-0" - base_icon_state = "sandstone_wall" - sheet_type = /obj/item/stack/sheet/mineral/sandstone - explosion_block = 0 - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_SANDSTONE_WALLS) - canSmoothWith = list(SMOOTH_GROUP_SANDSTONE_WALLS) - -/turf/simulated/wall/mineral/uranium - name = "uranium wall" - desc = "A wall with uranium plating. This is probably a bad idea." - icon = 'icons/turf/walls/uranium_wall.dmi' - icon_state = "uranium_wall-0" - base_icon_state = "uranium_wall" - sheet_type = /obj/item/stack/sheet/mineral/uranium - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_URANIUM_WALLS) - canSmoothWith = list(SMOOTH_GROUP_URANIUM_WALLS) - -/turf/simulated/wall/mineral/uranium/proc/radiate() - if(!active) - if(world.time > last_event + 1.5 SECONDS) - active = TRUE - radiation_pulse(src, 40) - for(var/turf/simulated/wall/mineral/uranium/T in orange(1, src)) - T.radiate() - last_event = world.time - active = FALSE - -/turf/simulated/wall/mineral/uranium/attack_hand(mob/user as mob) - radiate() - ..() - -/turf/simulated/wall/mineral/uranium/attack_by(obj/item/attacking, mob/user, params) - if(..()) - return FINISH_ATTACK - - radiate() - -/turf/simulated/wall/mineral/uranium/Bumped(AM as mob|obj) - radiate() - ..() - -/turf/simulated/wall/mineral/plasma - name = "plasma wall" - desc = "A wall with plasma plating. This is definitely a bad idea." - icon = 'icons/turf/walls/plasma_wall.dmi' - icon_state = "plasma_wall-0" - base_icon_state = "plasma_wall" - sheet_type = /obj/item/stack/sheet/mineral/plasma - thermal_conductivity = 0.04 - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_PLASMA_WALLS) - canSmoothWith = list(SMOOTH_GROUP_PLASMA_WALLS) - -/turf/simulated/wall/mineral/plasma/attack_by(obj/item/attacking, mob/user, params) - if(..()) - return FINISH_ATTACK - - if(attacking.get_heat() > 300)//If the temperature of the object is over 300, then ignite - message_admins("Plasma wall ignited by [key_name_admin(user)] in ([x], [y], [z] - JMP)",0,1) - log_game("Plasma wall ignited by [key_name(user)] in ([x], [y], [z])") - investigate_log("was ignited by [key_name(user)]","atmos") - ignite(attacking.get_heat()) - - return FINISH_ATTACK - -/turf/simulated/wall/mineral/plasma/welder_act(mob/user, obj/item/I) - if(I.tool_enabled) - ignite(2500) //The number's big enough - user.visible_message("[user] sets [src] on fire!",\ - "[src] disintegrates into a cloud of plasma!",\ - "You hear a 'whoompf' and a roar.") - message_admins("Plasma wall ignited by [key_name_admin(user)] in ([x], [y], [z] - JMP)",0,1) - log_game("Plasma wall ignited by [key_name(user)] in ([x], [y], [z])") - investigate_log("was ignited by [key_name(user)]","atmos") - -/turf/simulated/wall/mineral/plasma/proc/PlasmaBurn(temperature) - new girder_type(src) - ChangeTurf(/turf/simulated/floor) - atmos_spawn_air(LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS, 400) - -/turf/simulated/wall/mineral/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)//Doesn't fucking work because walls don't interact with air :( - ..() - if(exposed_temperature > 300) - PlasmaBurn(exposed_temperature) - -/turf/simulated/wall/mineral/plasma/proc/ignite(exposed_temperature) - if(exposed_temperature > 300) - PlasmaBurn(exposed_temperature) - -/turf/simulated/wall/mineral/plasma/bullet_act(obj/item/projectile/Proj) - if(Proj.damage == 0)//lasertag guns and so on don't set off plasma anymore. can't use nodamage here because lasertag guns actually don't have it. - return - if(istype(Proj,/obj/item/projectile/beam)) - PlasmaBurn(2500) - else if(istype(Proj,/obj/item/projectile/ion)) - PlasmaBurn(500) - ..() - -/turf/simulated/wall/mineral/alien - name = "alien wall" - desc = "A strange-looking alien wall." - icon = 'icons/turf/walls/plasma_wall.dmi' - icon_state = "abductor_wall-0" - base_icon_state = "abductor_wall" - sheet_type = /obj/item/stack/sheet/mineral/abductor - smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_ABDUCTOR_WALLS) - canSmoothWith = list(SMOOTH_GROUP_ABDUCTOR_WALLS) - -/turf/simulated/wall/mineral/wood - name = "wooden wall" - desc = "A wall with wooden plating. Stiff." - icon = 'icons/turf/walls/wood_wall.dmi' - icon_state = "wood_wall-0" - base_icon_state = "wood_wall" - sheet_type = /obj/item/stack/sheet/wood - hardness = 70 - explosion_block = 0 - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_WOOD_WALLS) - canSmoothWith = list(SMOOTH_GROUP_WOOD_WALLS) - -/turf/simulated/wall/mineral/wood/attack_by(obj/item/attacking, mob/user, params) - if(..()) - return FINISH_ATTACK - - if(attacking.sharp && attacking.force) - var/duration = (48 / attacking.force) * 2 //In seconds, for now. - if(istype(attacking, /obj/item/hatchet) || istype(attacking, /obj/item/fireaxe)) - duration /= 4 //Much better with hatchets and axes. - if(do_after(user, duration * 10, target = src)) //Into deciseconds. - dismantle_wall(FALSE, FALSE) - return FINISH_ATTACK - - -/turf/simulated/wall/mineral/wood/nonmetal - desc = "A solidly wooden wall. It's a bit weaker than a wall made with metal." - girder_type = /obj/structure/barricade/wooden - hardness = 50 - canSmoothWith = list(SMOOTH_GROUP_WALLS, SMOOTH_GROUP_WOOD_WALLS) - -/turf/simulated/wall/mineral/iron - name = "rough metal wall" - desc = "A wall with rough metal plating." - icon = 'icons/turf/walls/iron_wall.dmi' - icon_state = "iron_wall-0" - base_icon_state = "iron_wall" - sheet_type = /obj/item/stack/rods - sheet_amount = 5 - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_IRON_WALLS) - canSmoothWith = list(SMOOTH_GROUP_IRON_WALLS) - -/turf/simulated/wall/mineral/abductor - name = "alien wall" - desc = "A wall with alien alloy plating." - icon = 'icons/turf/walls/abductor_wall.dmi' - icon_state = "abductor_wall-0" - base_icon_state = "abductor_wall" - sheet_type = /obj/item/stack/sheet/mineral/abductor - explosion_block = 3 - smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_ABDUCTOR_WALLS) - canSmoothWith = list(SMOOTH_GROUP_ABDUCTOR_WALLS) - -/////////////////////Titanium walls///////////////////// - -/// has to use this path due to how building walls works -/turf/simulated/wall/mineral/titanium - name = "wall" - desc = "A light-weight titanium wall used in shuttles." - icon = 'icons/turf/walls/plastinum_wall.dmi' - icon_state = "plastinum_wall-0" - base_icon_state = "plastinum_wall" - explosion_block = 3 - flags_ricochet = RICOCHET_SHINY | RICOCHET_HARD - sheet_type = /obj/item/stack/sheet/mineral/titanium - smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS - smoothing_groups = list(SMOOTH_GROUP_TITANIUM_WALLS, SMOOTH_GROUP_WINDOW_FULLTILE_SHUTTLE) - canSmoothWith = list(SMOOTH_GROUP_TITANIUM_WALLS, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_SHUTTLE_PARTS, SMOOTH_GROUP_WINDOW_FULLTILE_SHUTTLE) - -/turf/simulated/wall/mineral/titanium/nodiagonal - icon_state = "map-shuttle_nd" - smoothing_flags = SMOOTH_BITMASK - -/turf/simulated/wall/mineral/titanium/nosmooth - smoothing_flags = NONE - -/turf/simulated/wall/mineral/titanium/overspace - icon_state = "map-overspace" - smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS - fixed_underlay = list("space" = TRUE) - -//sub-type to be used for interior shuttle walls -//won't get an underlay of the destination turf on shuttle move -/turf/simulated/wall/mineral/titanium/interior/copyTurf(turf/T) - if(T.type != type) - T.ChangeTurf(type) - if(length(underlays)) - T.underlays = underlays - if(T.icon_state != icon_state) - T.icon_state = icon_state - if(T.icon != icon) - T.icon = icon - if(color) - T.atom_colours = atom_colours.Copy() - T.update_atom_colour() - if(T.dir != dir) - T.setDir(dir) - T.transform = transform - return T - -/turf/simulated/wall/mineral/titanium/copyTurf(turf/T) - . = ..() - T.transform = transform - -/turf/simulated/wall/mineral/titanium/survival - name = "pod wall" - desc = "An easily-compressable wall used for temporary shelter." - icon = 'icons/turf/walls/survival_pod_walls.dmi' - icon_state = "survival_pod_walls-0" - base_icon_state = "survival_pod_walls" - smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS - smoothing_groups = list(SMOOTH_GROUP_PLASTITANIUM_WALLS) - canSmoothWith = list(SMOOTH_GROUP_PLASTITANIUM_WALLS, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_SHUTTLE_PARTS) - -/turf/simulated/wall/mineral/titanium/survival/nodiagonal - icon = 'icons/turf/walls/survival_pod_walls.dmi' - icon_state = "survival_pod_walls-0" - base_icon_state = "survival_pod_walls" - smoothing_flags = SMOOTH_BITMASK - -/turf/simulated/wall/mineral/titanium/survival/pod - -/////////////////////Plastitanium walls///////////////////// - -/turf/simulated/wall/mineral/plastitanium - name = "wall" - desc = "An evil wall of plasma and titanium." - icon = 'icons/turf/walls/plastitanium_wall.dmi' - icon_state = "plastitanium_wall-0" - base_icon_state = "plastitanium_wall" - explosion_block = 4 - sheet_type = /obj/item/stack/sheet/mineral/plastitanium - smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS - smoothing_groups = list(SMOOTH_GROUP_PLASTITANIUM_WALLS) - canSmoothWith = list(SMOOTH_GROUP_PLASTITANIUM_WALLS, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_SHUTTLE_PARTS) - -/turf/simulated/wall/mineral/plastitanium/nodiagonal - icon_state = "map-shuttle_nd" - base_icon_state = "plastitanium_wall" - smoothing_flags = SMOOTH_BITMASK - -/turf/simulated/wall/mineral/plastitanium/nosmooth - icon = 'icons/turf/shuttle.dmi' - icon_state = "wall" - smoothing_flags = NONE - -/turf/simulated/wall/mineral/plastitanium/overspace - icon_state = "map-overspace" - smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS - fixed_underlay = list("space" = TRUE) - -//have to copypaste this code -/turf/simulated/wall/mineral/plastitanium/interior/copyTurf(turf/T) - if(T.type != type) - T.ChangeTurf(type) - if(length(underlays)) - T.underlays = underlays - if(T.icon_state != icon_state) - T.icon_state = icon_state - if(T.icon != icon) - T.icon = icon - if(color) - T.atom_colours = atom_colours.Copy() - T.update_atom_colour() - if(T.dir != dir) - T.setDir(dir) - T.transform = transform - return T - -/turf/simulated/wall/mineral/plastitanium/copyTurf(turf/T) - . = ..() - T.transform = transform diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm deleted file mode 100644 index 56b033487d88a..0000000000000 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ /dev/null @@ -1,237 +0,0 @@ -/turf/simulated/wall/r_wall - name = "reinforced wall" - desc = "A huge chunk of reinforced metal used to separate rooms." - icon = 'icons/turf/walls/reinforced_wall.dmi' - icon_state = "reinforced_wall-0" - base_icon_state = "reinforced_wall" - smoothing_flags = SMOOTH_BITMASK - opacity = TRUE - density = TRUE - explosion_block = 2 - rad_insulation = RAD_HEAVY_INSULATION - damage_cap = 600 - hardness = 10 - sheet_type = /obj/item/stack/sheet/plasteel - sheet_amount = 1 - girder_type = /obj/structure/girder/reinforced - can_dismantle_with_welder = FALSE - smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_REINFORCED_WALLS) - canSmoothWith = list(SMOOTH_GROUP_WALLS, SMOOTH_GROUP_REGULAR_WALLS, SMOOTH_GROUP_REINFORCED_WALLS) - heat_resistance = 20000 // Ain't getting through this soon - - var/d_state = RWALL_INTACT - var/can_be_reinforced = 1 - -/turf/simulated/wall/r_wall/examine(mob/user) - . = ..() - switch(d_state) - if(RWALL_INTACT) - . += "The outer grille is fully intact." - if(RWALL_SUPPORT_LINES) - . += "The outer grille has been cut, and the support lines are screwed securely to the outer cover." - if(RWALL_COVER) - . += "The support lines have been unscrewed, and the metal cover is welded firmly in place." - if(RWALL_CUT_COVER) - . += "The metal cover has been sliced through, and is connected loosely to the girder." - if(RWALL_BOLTS) - . += "The outer cover has been pried away, and the bolts anchoring the support rods are wrenched in place." - if(RWALL_SUPPORT_RODS) - . += "The bolts anchoring the support rods have been loosened, but are still welded firmly to the girder." - if(RWALL_SHEATH) - . += "The support rods have been sliced through, and the outer sheath is connected loosely to the girder." - -/turf/simulated/wall/r_wall/attack_by(obj/item/attacking, mob/user, params) - if(..()) - return FINISH_ATTACK - - if(d_state == RWALL_COVER && istype(attacking, /obj/item/gun/energy/plasmacutter)) - to_chat(user, "You begin slicing through the metal cover...") - if(attacking.use_tool(src, user, 40, volume = attacking.tool_volume) && d_state == RWALL_COVER) - d_state = RWALL_CUT_COVER - update_icon() - to_chat(user, "You press firmly on the cover, dislodging it.") - return FINISH_ATTACK - else if(d_state == RWALL_SUPPORT_RODS && istype(attacking, /obj/item/gun/energy/plasmacutter)) - to_chat(user, "You begin slicing through the support rods...") - if(attacking.use_tool(src, user, 70, volume = attacking.tool_volume) && d_state == RWALL_SUPPORT_RODS) - d_state = RWALL_SHEATH - update_icon() - return FINISH_ATTACK - - else if(d_state) - // Repairing - if(istype(attacking, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/metal/MS = attacking - to_chat(user, "You begin patching-up the wall with [MS]...") - if(do_after(user, max(20 * d_state, 100) * MS.toolspeed, target = src) && d_state) - if(!MS.use(1)) - to_chat(user, "You don't have enough [MS.name] for that!") - return FINISH_ATTACK - d_state = RWALL_INTACT - update_icon() - QUEUE_SMOOTH_NEIGHBORS(src) - to_chat(user, "You repair the last of the damage.") - return FINISH_ATTACK - -/turf/simulated/wall/r_wall/welder_act(mob/user, obj/item/I) - if(reagents?.get_reagent_amount("thermite") && I.use_tool(src, user, volume = I.tool_volume)) - thermitemelt(user) - return TRUE - if(!(d_state in list(RWALL_COVER, RWALL_SUPPORT_RODS, RWALL_CUT_COVER))) - return ..() - . = TRUE - if(!I.tool_use_check(user, 0)) - return - if(d_state == RWALL_COVER) - to_chat(user, "You begin slicing through the metal cover...") - if(I.use_tool(src, user, 60, volume = I.tool_volume) && d_state == RWALL_COVER) - d_state = RWALL_CUT_COVER - to_chat(user, "You press firmly on the cover, dislodging it.") - else if(d_state == RWALL_SUPPORT_RODS) - to_chat(user, "You begin slicing through the support rods...") - if(I.use_tool(src, user, 100, volume = I.tool_volume) && d_state == RWALL_SUPPORT_RODS) - d_state = RWALL_SHEATH - else if(d_state == RWALL_CUT_COVER) - to_chat(user, "You begin welding the metal cover back to the frame...") - if(I.use_tool(src, user, 60, volume = I.tool_volume) && d_state == RWALL_CUT_COVER) - to_chat(user, "The metal cover has been welded securely to the frame.") - d_state = RWALL_COVER - update_icon() - -/turf/simulated/wall/r_wall/crowbar_act(mob/user, obj/item/I) - if(!(d_state in list(RWALL_CUT_COVER, RWALL_SHEATH, RWALL_BOLTS))) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - switch(d_state) - if(RWALL_CUT_COVER) - to_chat(user, "You struggle to pry off the cover...") - if(!I.use_tool(src, user, 100, volume = I.tool_volume) || d_state != RWALL_CUT_COVER) - return - d_state = RWALL_BOLTS - to_chat(user, "You pry off the cover.") - if(RWALL_SHEATH) - to_chat(user, "You struggle to pry off the outer sheath...") - if(!I.use_tool(src, user, 100, volume = I.tool_volume)) - return - if(dismantle_wall()) - to_chat(user, "You pry off the outer sheath.") - - if(RWALL_BOLTS) - to_chat(user, "You start to pry the cover back into place...") - playsound(src, I.usesound, 100, 1) - if(!I.use_tool(src, user, 20, volume = I.tool_volume) || d_state != RWALL_BOLTS) - return - d_state = RWALL_CUT_COVER - to_chat(user, "The metal cover has been pried back into place.") - update_icon() - -/turf/simulated/wall/r_wall/screwdriver_act(mob/user, obj/item/I) - if(d_state != RWALL_SUPPORT_LINES && d_state != RWALL_COVER) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - var/state_check = d_state - if(d_state == RWALL_SUPPORT_LINES) - to_chat(user, "You begin unsecuring the support lines...") - else - to_chat(user, "You begin securing the support lines...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state_check != d_state) - return - if(d_state == RWALL_SUPPORT_LINES) - d_state = RWALL_COVER - to_chat(user, "You unsecure the support lines.") - else - d_state = RWALL_SUPPORT_LINES - to_chat(user, "The support lines have been secured.") - update_icon() - -/turf/simulated/wall/r_wall/wirecutter_act(mob/user, obj/item/I) - if(d_state != RWALL_INTACT && d_state != RWALL_SUPPORT_LINES) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - if(d_state == RWALL_INTACT) - d_state = RWALL_SUPPORT_LINES - to_chat(user, "You cut the outer grille.") - else - d_state = RWALL_INTACT - to_chat(user, "You mend the outer grille.") - update_icon() - -/turf/simulated/wall/r_wall/wrench_act(mob/user, obj/item/I) - if(d_state != RWALL_BOLTS && d_state != RWALL_SUPPORT_RODS) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - var/state_check = d_state - if(d_state == RWALL_BOLTS) - to_chat(user, "You start loosening the anchoring bolts which secure the support rods to their frame...") - else - to_chat(user, "You start tightening the bolts which secure the support rods to their frame...") - if(!I.use_tool(src, user, 40, volume = I.tool_volume) || state_check != d_state) - return - if(d_state == RWALL_BOLTS) - d_state = RWALL_SUPPORT_RODS - to_chat(user, "You remove the bolts anchoring the support rods.") - else - d_state = RWALL_BOLTS - to_chat(user, "You tighten the bolts anchoring the support rods.") - update_icon() - -/turf/simulated/wall/r_wall/try_decon(obj/item/I, mob/user, params) //Plasma cutter only works in the deconstruction steps! - return FALSE - -/turf/simulated/wall/r_wall/try_destroy(obj/item/I, mob/user, params) - if(istype(I, /obj/item/pickaxe/drill/diamonddrill)) - to_chat(user, "You begin to drill though the wall...") - - if(do_after(user, 800 * I.toolspeed, target = src)) // Diamond drill has 0.25 toolspeed, so 200 - to_chat(user, "Your drill tears through the last of the reinforced plating.") - dismantle_wall() - return TRUE - - if(istype(I, /obj/item/pickaxe/drill/jackhammer)) - to_chat(user, "You begin to disintegrate the wall...") - - if(do_after(user, 1000 * I.toolspeed, target = src)) // Jackhammer has 0.1 toolspeed, so 100 - to_chat(user, "Your sonic jackhammer disintegrates the reinforced plating.") - dismantle_wall() - return TRUE - - if(istype(I, /obj/item/pyro_claws)) - to_chat(user, "You begin to melt the wall...") - if(do_after(user, 50 * I.toolspeed, target = src)) // claws has 0.5 toolspeed, so 2.5 seconds - to_chat(user, "Your [I] melt the reinforced plating.") - dismantle_wall() - return TRUE - - if(istype(I, /obj/item/zombie_claw)) - to_chat(user, "You begin to claw apart the wall.") - if(do_after(user, 2 MINUTES * I.toolspeed, target = src)) - to_chat(user, "Your [I.name] rip apart the reinforced plating.") - dismantle_wall() - return TRUE - -/turf/simulated/wall/r_wall/wall_singularity_pull(current_size) - if(current_size >= STAGE_FIVE) - if(prob(30)) - dismantle_wall() - -/turf/simulated/wall/r_wall/update_icon_state() - if(d_state) - icon_state = "r_wall-[d_state]" - smoothing_flags = NONE - else - smoothing_flags = SMOOTH_BITMASK - icon_state = "[base_icon_state]-[smoothing_junction]" - QUEUE_SMOOTH_NEIGHBORS(src) - QUEUE_SMOOTH(src) - -/turf/simulated/wall/r_wall/devastate_wall() - new sheet_type(src, sheet_amount) - new /obj/item/stack/sheet/metal(src, 2) diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm deleted file mode 100644 index e6c64041d4a9d..0000000000000 --- a/code/game/turfs/space/transit.dm +++ /dev/null @@ -1,182 +0,0 @@ -/turf/space/transit - var/pushdirection // push things that get caught in the transit tile this direction - plane = PLANE_SPACE - icon_state = "black" - dir = SOUTH - -/turf/space/transit/Initialize(mapload) - . = ..() - // We don't want people building rods in space. - RegisterSignal(src, COMSIG_ATTACK_BY, TYPE_PROC_REF(/datum, signal_cancel_attack_by)) - -/// moving to the north -/turf/space/transit/north - - pushdirection = SOUTH // south because the space tile is scrolling south - - //IF ANYONE KNOWS A MORE EFFICIENT WAY OF MANAGING THESE SPRITES, BE MY GUEST. -/turf/space/transit/north/shuttlespace_ns1 - icon_state = "speedspace_ns_1" - -/turf/space/transit/north/shuttlespace_ns2 - icon_state = "speedspace_ns_2" - -/turf/space/transit/north/shuttlespace_ns3 - icon_state = "speedspace_ns_3" - -/turf/space/transit/north/shuttlespace_ns4 - icon_state = "speedspace_ns_4" - -/turf/space/transit/north/shuttlespace_ns5 - icon_state = "speedspace_ns_5" - -/turf/space/transit/north/shuttlespace_ns6 - icon_state = "speedspace_ns_6" - -/turf/space/transit/north/shuttlespace_ns7 - icon_state = "speedspace_ns_7" - -/turf/space/transit/north/shuttlespace_ns8 - icon_state = "speedspace_ns_8" - -/turf/space/transit/north/shuttlespace_ns9 - icon_state = "speedspace_ns_9" - -/turf/space/transit/north/shuttlespace_ns10 - icon_state = "speedspace_ns_10" - -/turf/space/transit/north/shuttlespace_ns11 - icon_state = "speedspace_ns_11" - -/turf/space/transit/north/shuttlespace_ns12 - icon_state = "speedspace_ns_12" - -/turf/space/transit/north/shuttlespace_ns13 - icon_state = "speedspace_ns_13" - -/turf/space/transit/north/shuttlespace_ns14 - icon_state = "speedspace_ns_14" - -/turf/space/transit/north/shuttlespace_ns15 - icon_state = "speedspace_ns_15" - -/// moving to the east -/turf/space/transit/east - pushdirection = WEST - -/turf/space/transit/east/shuttlespace_ew1 - icon_state = "speedspace_ew_1" - -/turf/space/transit/east/shuttlespace_ew2 - icon_state = "speedspace_ew_2" - -/turf/space/transit/east/shuttlespace_ew3 - icon_state = "speedspace_ew_3" - -/turf/space/transit/east/shuttlespace_ew4 - icon_state = "speedspace_ew_4" - -/turf/space/transit/east/shuttlespace_ew5 - icon_state = "speedspace_ew_5" - -/turf/space/transit/east/shuttlespace_ew6 - icon_state = "speedspace_ew_6" - -/turf/space/transit/east/shuttlespace_ew7 - icon_state = "speedspace_ew_7" - -/turf/space/transit/east/shuttlespace_ew8 - icon_state = "speedspace_ew_8" - -/turf/space/transit/east/shuttlespace_ew9 - icon_state = "speedspace_ew_9" - -/turf/space/transit/east/shuttlespace_ew10 - icon_state = "speedspace_ew_10" - -/turf/space/transit/east/shuttlespace_ew11 - icon_state = "speedspace_ew_11" - -/turf/space/transit/east/shuttlespace_ew12 - icon_state = "speedspace_ew_12" - -/turf/space/transit/east/shuttlespace_ew13 - icon_state = "speedspace_ew_13" - -/turf/space/transit/east/shuttlespace_ew14 - icon_state = "speedspace_ew_14" - -/turf/space/transit/east/shuttlespace_ew15 - icon_state = "speedspace_ew_15" -//-tg- stuff - -/turf/space/transit/horizontal - dir = WEST - -/turf/space/transit/Entered(atom/movable/AM, atom/OldLoc, ignoreRest = 0) - if(!AM) - return - if(!AM.simulated || istype(AM, /obj/docking_port)) - return //this was fucking hilarious, the docking ports were getting thrown to random Z-levels - var/max = world.maxx-TRANSITIONEDGE - var/min = 1+TRANSITIONEDGE - - //now select coordinates for a border turf - var/_x - var/_y - switch(dir) - if(SOUTH) - _x = rand(min,max) - _y = max - if(WEST) - _x = max - _y = rand(min,max) - if(EAST) - _x = min - _y = rand(min,max) - else - _x = rand(min,max) - _y = min - - var/list/levels_available = get_all_linked_levels_zpos() - var/turf/T = locate(_x, _y, pick(levels_available)) - AM.forceMove(T) - AM.newtonian_move(dir) - - -/turf/space/transit/rpd_act() - return - -/turf/space/transit/Initialize(mapload) - . = ..() - update_icon(UPDATE_ICON_STATE) - -/turf/space/transit/update_icon_state() - var/p = 9 - var/angle = 0 - var/state = 1 - switch(dir) - if(NORTH) - angle = 180 - state = ((-p*x+y) % 15) + 1 - if(state < 1) - state += 15 - if(EAST) - angle = 90 - state = ((x+p*y) % 15) + 1 - if(WEST) - angle = -90 - state = ((x-p*y) % 15) + 1 - if(state < 1) - state += 15 - else - state = ((p*x+y) % 15) + 1 - - icon_state = "speedspace_ns_[state]" - transform = turn(matrix(), angle) - -/turf/space/transit/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) - underlay_appearance.icon = 'icons/turf/space.dmi' - underlay_appearance.icon_state = SPACE_ICON_STATE - underlay_appearance.plane = PLANE_SPACE - return TRUE diff --git a/code/game/world.dm b/code/game/world.dm deleted file mode 100644 index da8dac0955df7..0000000000000 --- a/code/game/world.dm +++ /dev/null @@ -1,303 +0,0 @@ -GLOBAL_LIST_INIT(map_transition_config, list(CC_TRANSITION_CONFIG)) - -#ifdef GAME_TESTS -GLOBAL_DATUM(test_runner, /datum/test_runner) -#endif - -/world/New() - // IMPORTANT - // If you do any SQL operations inside this proc, they must ***NOT*** be ran async. Otherwise players can join mid query - // This is BAD. - - SSmetrics.world_init_time = REALTIMEOFDAY - - // Do sanity checks to ensure RUST actually exists - if((!fexists(RUST_G)) && world.system_type == MS_WINDOWS) - DIRECT_OUTPUT(world.log, "ERROR: RUSTG was not found and is required for the game to function. Server will now exit.") - del(world) - - var/rustg_version = rustg_get_version() - if(rustg_version != RUST_G_VERSION) - DIRECT_OUTPUT(world.log, "ERROR: RUSTG version mismatch. Library is [rustg_version], code wants [RUST_G_VERSION]. Server will now exit.") - del(world) - - //temporary file used to record errors with loading config and the database, moved to log directory once logging is set up - GLOB.config_error_log = GLOB.world_game_log = GLOB.world_runtime_log = GLOB.sql_log = "data/logs/config_error.log" - GLOB.configuration.load_configuration() // Load up the base config.toml - // Load up overrides for this specific instance, based on port - // If this instance is listening on port 6666, the server will look for config/overrides_6666.toml - GLOB.configuration.load_overrides() - - // Right off the bat, load up the DB - SSdbcore.CheckSchemaVersion() // This doesnt just check the schema version, it also connects to the db! This needs to happen super early! I cannot stress this enough! - SSdbcore.SetRoundID() // Set the round ID here - #ifdef MULTIINSTANCE - SSinstancing.seed_data() // Set us up in the DB - #endif - - // Setup all log paths and stamp them with startups, including round IDs - SetupLogs() - load_files() // Loads up the MOTD (Welcome message players see when joining the server), TOS and gamemode - - // This needs to happen early, otherwise people can get a null species, nuking their character - makeDatumRefLists() - - InitTGS() // creates a new TGS object - log_world("World loaded at [time_stamp()]") - log_world("[length(GLOB.vars) - length(GLOB.gvars_datum_in_built_vars)] global variables") - GLOB.revision_info.log_info() - load_admins(run_async = FALSE) // This better happen early on. - - if(TgsAvailable()) - world.log = file("[GLOB.log_directory]/dd.log") //not all runtimes trigger world/Error, so this is the only way to ensure we can see all of them. - - #ifdef GAME_TESTS - log_world("Unit Tests Are Enabled!") - #endif - - if(byond_version < MIN_COMPILER_VERSION || byond_build < MIN_COMPILER_BUILD) - log_world("Your server's byond version does not meet the recommended requirements for this code. Please update BYOND") - - GLOB.timezoneOffset = world.timezone * 36000 - - update_status() - - GLOB.space_manager.initialize() //Before the MC starts up - - . = ..() - - Master.Initialize(10, FALSE, TRUE) - - - #ifdef GAME_TESTS - GLOB.test_runner = new - GLOB.test_runner.Start() - #endif - - -/world/proc/InitTGS() - TgsNew(new /datum/tgs_event_handler/impl, TGS_SECURITY_TRUSTED) // creates a new TGS object - GLOB.revision_info.load_tgs_info() // Loads git and TM info from TGS itself - -/// List of all world topic spam prevention handlers. See code/modules/world_topic/_spam_prevention_handler.dm -GLOBAL_LIST_EMPTY(world_topic_spam_prevention_handlers) -/// List of all world topic handler datums. Populated inside makeDatumRefLists() -GLOBAL_LIST_EMPTY(world_topic_handlers) - - -/world/Topic(T, addr, master, key) - TGS_TOPIC - log_misc("WORLD/TOPIC: \"[T]\", from:[addr], master:[master], key:[key]") - - // Handle spam prevention, if their IP isnt in the whitelist - if(!(addr in GLOB.configuration.system.topic_ip_ratelimit_bypass)) - if(!GLOB.world_topic_spam_prevention_handlers[addr]) - GLOB.world_topic_spam_prevention_handlers[addr] = new /datum/world_topic_spam_prevention_handler(addr) - - var/datum/world_topic_spam_prevention_handler/sph = GLOB.world_topic_spam_prevention_handlers[addr] - - // Lock the user out and cancel their topic if needed - if(sph.check_lockout()) - return - - var/list/input = params2list(T) - - var/datum/world_topic_handler/wth - - for(var/H in GLOB.world_topic_handlers) - if(H in input) - wth = GLOB.world_topic_handlers[H] - break - - if(!wth) - return - - // If we are here, the handler exists, so it needs to be invoked - wth = new wth() - return wth.invoke(input) - -/world/Reboot(reason, fast_track = FALSE) - //special reboot, do none of the normal stuff - if((reason == 1) || fast_track) // Do NOT change this to if(reason). You WILL break the entirety of world rebooting - if(usr) - if(!check_rights(R_SERVER)) - message_admins("[key_name_admin(usr)] attempted to restart the server via the Profiler, without access.") - log_admin("[key_name(usr)] attempted to restart the server via the Profiler, without access.") - return - message_admins("[key_name_admin(usr)] has requested an immediate world restart via client side debugging tools") - log_admin("[key_name(usr)] has requested an immediate world restart via client side debugging tools") - to_chat(world, "Rebooting world immediately due to host request") - rustg_log_close_all() // Past this point, no logging procs can be used, at risk of data loss. - // Now handle a reboot - if(GLOB.configuration.system.shutdown_on_reboot) - sleep(0) - if(GLOB.configuration.system.shutdown_shell_command) - shell(GLOB.configuration.system.shutdown_shell_command) - del(world) - TgsEndProcess() // We want to shutdown on reboot. That means kill our TGS process "gracefully", instead of the watchdog crying - return - else - TgsReboot() // Tell TGS we did a reboot - return ..(1) - - // If we got here, we are in a "normal" reboot - Master.Shutdown() // Shutdown subsystems - - // If we were running unit tests, finish that run - #ifdef GAME_TESTS - GLOB.test_runner.Finalize() - return - #endif - - // Send the stats URL if applicable - if(GLOB.configuration.url.round_stats_url && GLOB.round_id) - var/stats_link = "[GLOB.configuration.url.round_stats_url][GLOB.round_id]" - to_chat(world, "Stats for this round can be viewed at [stats_link]") - - // If the server has been gracefully shutdown in TGS, have a 60 seconds grace period for SQL updates and stuff - if(GLOB.slower_restart) - server_announce_global("Reboot will take a little longer due to pending backend changes.") - - // Send the reboot banner to all players - for(var/client/C in GLOB.clients) - C?.tgui_panel?.send_roundrestart() - if(C.prefs.server_region) - // Keep them on the same relay - C << link(GLOB.configuration.system.region_map[C.prefs.server_region]) - else - // Use the default - if(GLOB.configuration.url.server_url) // If you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite - C << link("byond://[GLOB.configuration.url.server_url]") - - // And begin the real shutdown - rustg_log_close_all() // Past this point, no logging procs can be used, at risk of data loss. - if(GLOB.configuration.system.shutdown_on_reboot) - sleep(0) - if(GLOB.configuration.system.shutdown_shell_command) - shell(GLOB.configuration.system.shutdown_shell_command) - rustg_log_close_all() // Past this point, no logging procs can be used, at risk of data loss. - del(world) - TgsEndProcess() // We want to shutdown on reboot. That means kill our TGS process "gracefully", instead of the watchdog crying - return - else - TgsReboot() // We did a normal reboot. Tell TGS we did a normal reboot. - ..(0) - -/world/proc/load_mode() - var/list/Lines = file2list("data/mode.txt") - if(length(Lines)) - if(Lines[1]) - GLOB.master_mode = Lines[1] - log_game("Saved mode is '[GLOB.master_mode]'") - -/world/proc/save_mode(the_mode) - var/F = file("data/mode.txt") - fdel(F) - F << the_mode - -/world/proc/load_files() - GLOB.join_motd = file2text("config/motd.txt") - GLOB.join_tos = file2text("config/tos.txt") - load_mode() - -/world/proc/update_status() - status = get_status_text() - -/world/proc/get_status_text() - var/s = "" - - if(GLOB.configuration.general.server_name) - s += "[GLOB.configuration.general.server_name]] — " - - s += "[station_name()]" - else // else so it neatly closes the byond hub initial square bracket even without a server name - s += "[station_name()]]" - - if(GLOB.configuration.url.discord_url) - s += " (Discord)" - - if(GLOB.configuration.general.server_tag_line) - s += "
    [GLOB.configuration.general.server_tag_line]" - - if(SSticker && ROUND_TIME > 0) - s += "
    [round(ROUND_TIME / 36000)]:[add_zero(num2text(ROUND_TIME / 600 % 60), 2)], [capitalize(SSsecurity_level.get_current_level_as_text())]" - else - s += "
    STARTING" - - s += "
    " - - s += "\[" - - var/list/features = list() - - if(!GLOB.enter_allowed) - features += "closed" - - if(GLOB.configuration.general.server_features) - features += GLOB.configuration.general.server_features - - if(GLOB.configuration.url.wiki_url) - features += "Wiki" - - if(GLOB.configuration.general.respawn_enabled) - features += "respawn" - - if(features) - s += "[jointext(features, ", ")]" - - return s - -/world/proc/SetupLogs() - if(GLOB.round_id) - GLOB.log_directory = "data/logs/[time2text(world.realtime, "YYYY/MM-Month/DD-Day")]/round-[GLOB.round_id]" - else - GLOB.log_directory = "data/logs/[time2text(world.realtime, "YYYY/MM-Month/DD-Day")]" // Dont stick a round ID if we dont have one - GLOB.world_game_log = "[GLOB.log_directory]/game.log" - GLOB.world_href_log = "[GLOB.log_directory]/hrefs.log" - GLOB.world_runtime_log = "[GLOB.log_directory]/runtime.log" - GLOB.world_qdel_log = "[GLOB.log_directory]/qdel.log" - GLOB.tgui_log = "[GLOB.log_directory]/tgui.log" - GLOB.http_log = "[GLOB.log_directory]/http.log" - GLOB.sql_log = "[GLOB.log_directory]/sql.log" - GLOB.chat_debug_log = "[GLOB.log_directory]/chat_debug.log" - start_log(GLOB.world_game_log) - start_log(GLOB.world_href_log) - start_log(GLOB.world_runtime_log) - start_log(GLOB.world_qdel_log) - start_log(GLOB.tgui_log) - start_log(GLOB.http_log) - start_log(GLOB.sql_log) - start_log(GLOB.chat_debug_log) - - #ifdef REFERENCE_TRACKING - GLOB.gc_log = "[GLOB.log_directory]/gc_debug.log" - start_log(GLOB.gc_log) - #endif - - // This log follows a special format and this path should NOT be used for anything else - GLOB.runtime_summary_log = "data/logs/runtime_summary.log" - if(fexists(GLOB.runtime_summary_log)) - fdel(GLOB.runtime_summary_log) - start_log(GLOB.runtime_summary_log) - // And back to sanity - - if(fexists(GLOB.config_error_log)) - fcopy(GLOB.config_error_log, "[GLOB.log_directory]/config_error.log") - fdel(GLOB.config_error_log) - - // Save the current round's log path to a text file for other scripts to use. - var/F = file("data/logpath.txt") - fdel(F) - F << GLOB.log_directory - -/world/Del() - rustg_close_async_http_client() // Close the HTTP client. If you dont do this, youll get phantom threads which can crash DD from memory access violations - disable_auxtools_debugger() // Disables the debugger if running. See above comment - - if(SSredis.connected) - rustg_redis_disconnect() // Disconnects the redis connection. See above. - - #ifdef ENABLE_BYOND_TRACY - CALL_EXT("prof.dll", "destroy")() // Setup Tracy integration - #endif - ..() diff --git a/code/goonstation/modules/power/power_transmission_laser/transmission_laser.dm b/code/goonstation/modules/power/power_transmission_laser/transmission_laser.dm deleted file mode 100644 index e84fe6f984e34..0000000000000 --- a/code/goonstation/modules/power/power_transmission_laser/transmission_laser.dm +++ /dev/null @@ -1,534 +0,0 @@ -// Without these brackets division breaks. -#define MINIMUM_POWER (1 MW) -#define DEFAULT_CAPACITY (2000 GJ) -#define EYE_DAMAGE_THRESHOLD (5 MW) -#define RAD_THRESHOLD (30 MW) - -/obj/machinery/power/transmission_laser - name = "power transmission laser" - desc = "Sends power over a giant laser beam to an NT power processing facility." - - icon = 'icons/goonstation/objects/pt_laser.dmi' - icon_state = "ptl" - - max_integrity = 500 - - density = TRUE - anchored = TRUE - - pixel_x = 0 - pixel_y = -64 - - // Variables go below here - /// How far we shoot the beam. If it isn't blocked it should go to the end of the z level. - var/range = 0 - /// Amount of power we are outputting - var/output_level = 0 - /// The total capacity of the laser - var/capacity = DEFAULT_CAPACITY - /// Our current stored energy - var/charge = 0 - /// Are we trying to provide power to the laser - var/input_attempt = TRUE - /// Are we currently inputting power into the laser - var/inputting = TRUE - /// The amount of energy coming in from the inputs last tick - var/input_available = 0 - /// Have we been switched on? - var/turned_on = FALSE - /// Are we attempting to fire the laser currently? - var/firing = FALSE - /// We need to create a list of all lasers we are creating so we can delete them in the end - var/list/laser_effects = list() - /// Our max load we can set - var/max_grid_load = 0 - /// The load we place on the power grid we are connected to - var/current_grid_load = 0 - /// Signifies which unit we are using for output power. Used both in TGUI for formatting purposes and output power calculations. - var/power_format_multi = 1 - /// Signifies which unit we are using for input power. Used both in TGUI for formatting purposes and input power calculations. - var/power_format_multi_output = 1 MW - - /// Are we selling the energy or just sending it into the ether - var/selling_energy = FALSE - - /// How much energy have we sold in total (Joules) - var/total_energy = 0 - - /// How many credits we have earned in total - var/total_earnings = 0 - /// The amount of money we haven't sent yet - var/unsent_earnings = 0 - - /// Gives our power input when multiplied with power_format_multi. The multiplier signifies the units of power, and this is how many of them we are inputting. - var/input_number = 0 - /// Gives our power output when multiplied with power_format_multi_output. The multiplier signifies the units of power, and this is how many of them we are outputting. - var/output_number = 1 - /// Our set input pulling - var/input_pulling = 0 - /// Targetable areas in lavaland - var/list/targetable_areas = list( - /area/lavaland/surface/outdoors/outpost, - /area/lavaland/surface/outdoors/targetable, - /area/mine/outpost, - /area/shuttle/mining, - ) - /// Megafauna being targeted - var/mob/living/simple_animal/hostile/megafauna/target - /// Overlay that goes over the mob that gets beamed - var/image/orbital_strike - -/obj/machinery/power/transmission_laser/north - pixel_x = -64 - pixel_y = 0 - dir = NORTH - -/obj/machinery/power/transmission_laser/east - pixel_x = 0 - pixel_y = 0 - dir = EAST - -/obj/machinery/power/transmission_laser/west - pixel_x = -64 - pixel_y = 0 - dir = WEST - -/obj/item/circuitboard/machine/transmission_laser - board_name = "Power Transmission Laser" - icon_state = "command" - build_path = /obj/machinery/power/transmission_laser - origin_tech = "engineering=2;combat=3;" - req_components = list( - /obj/item/stock_parts/capacitor = 3, - /obj/item/stock_parts/micro_laser = 3, - ) - -/obj/machinery/power/transmission_laser/Initialize(mapload) - . = ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/transmission_laser - component_parts += new /obj/item/stock_parts/micro_laser - component_parts += new /obj/item/stock_parts/micro_laser - component_parts += new /obj/item/stock_parts/micro_laser - component_parts += new /obj/item/stock_parts/capacitor - component_parts += new /obj/item/stock_parts/capacitor - component_parts += new /obj/item/stock_parts/capacitor - range = get_dist(get_front_turf(), get_edge_target_turf(get_front_turf(), dir)) - if(!powernet) - connect_to_network() - handle_offset() - update_icon() - -/obj/machinery/power/transmission_laser/screwdriver_act(mob/living/user, obj/item/I) - if(firing) - to_chat(user,"Turn the laser off first.") - return - if(default_deconstruction_screwdriver(user, initial(icon_state), initial(icon_state), I)) - return TRUE - -/obj/machinery/power/transmission_laser/crowbar_act(mob/living/user, obj/item/I) - if(!panel_open) - return - if(default_deconstruction_crowbar(user, I)) - return TRUE - -/obj/machinery/power/transmission_laser/wrench_act(mob/living/user, obj/item/I) - if(!panel_open) - return - if(rotate()) - return TRUE - to_chat(user, "Target area blocked, please clear all objects and personnel.") - return TRUE - -/// Rotates the laser if we have the space to do so. -/obj/machinery/power/transmission_laser/proc/rotate() - var/new_dir = turn(dir, -90) - - var/x_offset = (new_dir == WEST) ? -2 : 2 - var/y_offset = (new_dir == SOUTH) ? -2 : 2 - var/datum/component/multitile/tiles = GetComponent(/datum/component/multitile) - // Make sure the area we want to rotate to has enough free tiles - for(var/turf/tile in block(x, y, z, x + x_offset, y + y_offset)) - if(tile?.density) - return FALSE - for(var/atom/thing as anything in tile.contents) - // If it's the machine or one of its multitile components fillers skip it - if(thing.UID() == UID() || (istype(thing, /obj/structure/filler/) && (thing in tiles.all_fillers))) - continue - if(thing?.density) - return FALSE - - dir = new_dir - handle_offset() - return TRUE - -/obj/machinery/power/transmission_laser/proc/handle_offset() - switch(dir) - if(NORTH) - pixel_x = -64 - pixel_y = 0 - AddComponent(/datum/component/multitile, list( - list(0, 1, 0, ), - list(1, 1, 1, ), - list(1, 1, MACH_CENTER), - )) - if(SOUTH) - pixel_x = 0 - pixel_y = -64 - AddComponent(/datum/component/multitile, list( - list(MACH_CENTER, 1, 1), - list(1, 1, 1), - list(0, 1, 0), - )) - if(WEST) - pixel_x = -64 - pixel_y = 0 - AddComponent(/datum/component/multitile, list( - list(0, 1, 1, ), - list(1, 1, 1, ), - list(0, 1, MACH_CENTER), - )) - if(EAST) - pixel_x = 0 - pixel_y = 0 - AddComponent(/datum/component/multitile, list( - list(1, 1, 0), - list(1, 1, 1), - list(MACH_CENTER, 1, 0), - )) - -/obj/machinery/power/transmission_laser/Destroy() - . = ..() - if(length(laser_effects)) - destroy_lasers() - -/obj/machinery/power/transmission_laser/proc/get_front_turf() - //this is weird as i believe byond sets the bottom left corner as the source corner like - // x-x-x - // x-x-x - // o-x-x - //which would mean finding the true front turf would require centering than taking a step in the primary direction - var/turf/center = locate(x + 1 + round(pixel_x / 32), y + 1 + round(pixel_y / 32), z) - return get_step(center, dir) - - - -/obj/machinery/power/transmission_laser/examine(mob/user) - . = ..() - . += "Laser currently has [unsent_earnings] unsent credits." - . += "Laser has generated [total_earnings] credits." - . += "Laser has sold [total_energy] Joules." - -/// Appearance changes are here -/obj/machinery/power/transmission_laser/update_overlays() - . = ..() - if((stat & BROKEN) || !charge) - . += "unpowered" - return - if(input_available > 0) - . += "green_light" - . += emissive_appearance(icon, "green_light", src) - if(turned_on) - . += "red_light" - . += emissive_appearance(icon, "red_light", src) - if(firing) - . +="firing" - . += emissive_appearance(icon, "firing", src) - - var/charge_level = return_charge() - if(charge_level == 6) - . += "charge_full" - . += emissive_appearance(icon, "charge_full", src) - else if(charge_level > 0) - . += "charge_[charge_level]" - . += emissive_appearance(icon, "charge_[charge_level]", src) - -/// Returns the charge level from [0 to 6] -/obj/machinery/power/transmission_laser/proc/return_charge() - if(!output_level) - return 0 - return min(round((charge / abs(output_level)) * 6), 6) - -/obj/machinery/power/transmission_laser/attack_hand(mob/user) - ui_interact(user) - -/obj/machinery/power/transmission_laser/attack_ghost(mob/user) - ui_interact(user) - -/obj/machinery/power/transmission_laser/ui_interact(mob/user, datum/tgui/ui) - . = ..() - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "goonstation_PTL") - ui.open() - ui.set_autoupdate(TRUE) - -/obj/machinery/power/transmission_laser/ui_data(mob/user) - . = ..() - var/list/data = list() - - data["output"] = output_level - data["total_earnings"] = total_earnings - data["unsent_earnings"] = unsent_earnings - data["total_energy"] = total_energy - data["held_power"] = charge - data["selling_energy"] = selling_energy - data["max_capacity"] = capacity - data["max_grid_load"] = max_grid_load - - data["accepting_power"] = turned_on - data["sucking_power"] = inputting - data["firing"] = firing - data["target"] = target ? target.internal_gps.gpstag : "" - - data["power_format"] = power_format_multi - data["input_number"] = input_number - data["avalible_input"] = input_available - data["output_number"] = output_number - data["output_multiplier"] = power_format_multi_output - data["input_total"] = input_number * power_format_multi - data["output_total"] = output_number * power_format_multi_output - - return data - -/obj/machinery/power/transmission_laser/ui_act(action, list/params) - . = ..() - if(.) - return - switch(action) - if("toggle_input") - turned_on = !turned_on - update_icon() - if("toggle_output") - firing = !firing - if(!firing) - destroy_lasers() - else - setup_lasers() - update_icon() - if("target") - target(usr) - - if("set_input") - input_number = clamp(params["set_input"], 0, 999) //multiplies our input by if input - if("set_output") - output_number = clamp(params["set_output"], 1, 999) - - if("inputW") - power_format_multi = 1 - if("inputKW") - power_format_multi = 1 KW - if("inputMW") - power_format_multi = 1 MW - if("inputGW") - power_format_multi = 1 GW - - if("outputW") - power_format_multi_output = 1 - if("outputKW") - power_format_multi_output = 1 KW - if("outputMW") - power_format_multi_output = 1 MW - if("outputGW") - power_format_multi_output = 1 GW - -/// Target a megafauna in the mining base or its immediate vicinity -/obj/machinery/power/transmission_laser/proc/target(mob/user) - var/list/target_list = list() - for(var/monster_id in GLOB.alive_megafauna_list) - var/mob/living/simple_animal/hostile/megafauna/monster = locateUID(monster_id) - var/area/boss_loc = get_area(monster) - for(var/area_type in targetable_areas) - if(istype(boss_loc, area_type)) - target_list[monster.internal_gps.gpstag] = monster - // Target CC to sell power - target_list["Collection Terminal"] = null - - var/choose = tgui_input_list(user, "Select target", "Target", target_list) - if(!choose) - return - target = target_list[choose] - RegisterSignal(target, COMSIG_MOB_DEATH, PROC_REF(untarget)) - if(firing && target) - orbital_strike = image(target.icon, target, "orbital_strike", FLY_LAYER, SOUTH) - target.add_overlay(orbital_strike) - -/// Stop targeting a mob once it dies -/obj/machinery/power/transmission_laser/proc/untarget() - SIGNAL_HANDLER - target.cut_overlay(orbital_strike) - UnregisterSignal(target, COMSIG_MOB_DEATH) - target = null - -/obj/machinery/power/transmission_laser/process() - max_grid_load = get_surplus() - input_available = get_surplus() - if(stat & BROKEN) - return - - if(powernet && input_attempt && turned_on) - input_pulling = min(input_available, input_number * power_format_multi, capacity - charge ) - - if(inputting) - if(input_pulling > 0) - consume_direct_power(input_pulling) - charge += input_pulling - else - inputting = FALSE - else - if(input_attempt && input_pulling > 0) - inputting = TRUE - else - inputting = FALSE - - if(charge < MINIMUM_POWER) - firing = FALSE - output_level = 0 - destroy_lasers() - update_icon() - return - - if(!firing) - return - - output_level = min(charge, output_number * power_format_multi_output) - - if(firing) - if(!target) - sell_power(output_level * WATT_TICK_TO_JOULE) - else - if(!QDELETED(target)) // Just for safety. - target.loot = list() // disable loot drops form the target to prevent cheese - if(10 * output_level * target.damage_coeff[BURN] / (1 MW) > target.health) // If we would kill the target dust it. - target.health = 0 // We need this so can_die() won't prevent dusting - visible_message("\The [src] is reduced to dust by the beam!") - target.dust() - else - target.adjustFireLoss(10 * output_level / (1 MW)) - else - target = null - if(output_level > EYE_DAMAGE_THRESHOLD) - for(var/mob/living/carbon/someone in oview(min(output_level / EYE_DAMAGE_THRESHOLD, 8), get_front_turf()))// Flash targets that can see the exit of the emitter - var/turf/front = get_front_turf() - var/turf/step = get_step(get_front_turf(), dir) - var/d_x = someone.x - front.x - var/d_y = someone.y - front.y - if(someone.dir == dir || (((dir == NORTH || dir == SOUTH) && (SIGN(d_y) != SIGN(step.y - front.y)))) || ((dir == WEST || dir == EAST) && (SIGN(d_x) != SIGN(step.x - front.x))))// Make sure they are in front of it - continue - var/look_angle - var/angle_to_bore = arctan(-d_x, -d_y) - switch(someone.dir) - if(NORTH) - look_angle = 90 - if(SOUTH) - look_angle = -90 - if(EAST) - look_angle = 0 - if(WEST) - look_angle = 180 - // Takes the cosine of the difference in angle between where the mob is looking and the location of the bore in relation to the mob. - var/flashmod = max(cos(look_angle - angle_to_bore), 0) - someone.flash_eyes(min(round(output_level/ EYE_DAMAGE_THRESHOLD), 3) * flashmod, TRUE, TRUE) - if(output_level > RAD_THRESHOLD) // Starts causing weak, quickly dissipating radiation pulses around the bore when power is high enough - radiation_pulse(get_front_turf(), (output_level / RAD_THRESHOLD) * 50, RAD_DISTANCE_COEFFICIENT) - - - charge -= output_level - -//// Selling defines are here -// Minimum amount of money per cycle -#define MINIMUM_BAR 0 -// Maximum amount of money per cycle - minimum amount of money per cycle -#define PROCESS_CAP (6 - MINIMUM_BAR) - -// Higher number means approaching the limit slower -#define A1_CURVE 20 - -#define HIGH_CUT_RATIO 0.75 -#define MEDIUM_CUT_RATIO 0.25 - -/obj/machinery/power/transmission_laser/proc/sell_power(joules) - var/mega_joules = joules / (1 MW) - SSticker.score.score_gigajoules_exported += joules / (1 GW) - - var/generated_cash = (2 * mega_joules * PROCESS_CAP) / ((2 * mega_joules) + (PROCESS_CAP * A1_CURVE)) - if(mega_joules) // so we can't divide by 0 - generated_cash += (4 * mega_joules * MINIMUM_BAR) / (4 * mega_joules + MINIMUM_BAR) - if(generated_cash < 0) - return - - total_energy += joules - total_earnings += generated_cash - unsent_earnings += generated_cash - - var/datum/money_account/engineering_bank_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_ENGINEERING) - var/datum/money_account/cargo_bank_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SUPPLY) - - if(unsent_earnings > 200) - var/medium_cut = round(unsent_earnings * MEDIUM_CUT_RATIO) - var/high_cut = round(unsent_earnings * HIGH_CUT_RATIO) - - GLOB.station_money_database.credit_account(cargo_bank_account, medium_cut, "Transmission Laser Payout", "Central Command Supply Master", supress_log = FALSE) - unsent_earnings -= medium_cut - - GLOB.station_money_database.credit_account(engineering_bank_account, high_cut, "Transmission Laser Payout", "Central Command Supply Master", supress_log = FALSE) - unsent_earnings -= high_cut - -#undef A1_CURVE -#undef PROCESS_CAP -#undef MINIMUM_BAR -#undef HIGH_CUT_RATIO -#undef MEDIUM_CUT_RATIO - -// Beam related procs - -/obj/machinery/power/transmission_laser/proc/setup_lasers() - if(target) - orbital_strike = image(target.icon, target, "orbital_strike", FLY_LAYER, SOUTH) - target.add_overlay(orbital_strike) - var/turf/last_step = get_step(get_front_turf(), dir) - for(var/num in 1 to range) - if(!(locate(/obj/effect/transmission_beam) in last_step)) - var/obj/effect/transmission_beam/new_beam = new(last_step, src) - new_beam.host = src - new_beam.dir = dir - laser_effects += new_beam - - last_step = get_step(last_step, dir) - -/obj/machinery/power/transmission_laser/proc/destroy_lasers() - if(target) - target.cut_overlay(orbital_strike) - for(var/obj/effect/transmission_beam/listed_beam as anything in laser_effects) - laser_effects -= listed_beam - qdel(listed_beam) - -// Beam -/obj/effect/transmission_beam - name = "Shimmering beam" - icon = 'icons/goonstation/effects/pt_beam.dmi' - icon_state = "ptl_beam" - anchored = TRUE - - /// Used to deal with atoms stepping on us while firing - var/obj/machinery/power/transmission_laser/host - -/obj/effect/transmission_beam/Initialize(mapload, obj/machinery/power/transmission_laser/creator) - . = ..() - update_appearance() - -/obj/effect/transmission_beam/Destroy(force) - . = ..() - -/obj/effect/transmission_beam/update_overlays() - . = ..() - . += emissive_appearance(icon, "ptl_beam", src) - -/// Explosions aren't supposed to make holes in a beam. -/obj/effect/transmission_beam/ex_act(severity) - return - -#undef MINIMUM_POWER -#undef DEFAULT_CAPACITY -#undef EYE_DAMAGE_THRESHOLD -#undef RAD_THRESHOLD diff --git a/code/modules/admin/menus/antagonist_menu.dm b/code/modules/admin/menus/antagonist_menu.dm deleted file mode 100644 index 798d1fbe62790..0000000000000 --- a/code/modules/admin/menus/antagonist_menu.dm +++ /dev/null @@ -1,209 +0,0 @@ -RESTRICT_TYPE(/datum/ui_module/admin/antagonist_menu) - -/datum/ui_module/admin/antagonist_menu - name = "Antagonist Menu" - var/list/cached_data - COOLDOWN_DECLARE(cache_cooldown) - -/datum/ui_module/admin/antagonist_menu/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "AdminAntagMenu", name) - ui.set_autoupdate(FALSE) - ui.open() - -/datum/ui_module/admin/antagonist_menu/ui_data(mob/user) - if(COOLDOWN_FINISHED(src, cache_cooldown)) - update_cached_data() - COOLDOWN_START(src, cache_cooldown, 1 SECONDS) - return cached_data - -/datum/ui_module/admin/antagonist_menu/proc/update_cached_data() - cached_data = list() - cached_data["antagonists"] = list() - for(var/datum/antagonist/antagonist as anything in GLOB.antagonists) - var/list/temp_list = list() - temp_list["antag_name"] = antagonist.name - var/datum/mind/antag_mind = antagonist.owner - temp_list["antag_mind_uid"] = antag_mind.UID() - temp_list["name"] = "" - temp_list["status"] = "No Body" - temp_list["name"] = antag_mind.name - temp_list["body_destroyed"] = TRUE - if(!QDELETED(antag_mind.current)) - temp_list["body_destroyed"] = FALSE - temp_list["status"] = "" - if(antag_mind.current.stat == DEAD) - temp_list["status"] = "(DEAD)" - else if(!antag_mind.current.client) - temp_list["status"] = "(SSD)" - if(istype(get_area(antag_mind.current), /area/station/security/permabrig)) - temp_list["status"] += "(PERMA)" - // temp_list["ckey"] = antag_mind.current.client?.ckey - temp_list["ckey"] = ckey(antag_mind.key) - temp_list["is_hijacker"] = istype((locate(/datum/objective/hijack) in antag_mind.get_all_objectives()), /datum/objective/hijack) - cached_data["antagonists"] += list(temp_list) - - cached_data["objectives"] = list() - for(var/datum/objective/objective as anything in GLOB.all_objectives) - var/list/temp_list = list() - temp_list["obj_name"] = objective.name || objective.type - temp_list["obj_desc"] = objective.explanation_text - temp_list["obj_uid"] = objective.UID() - - temp_list["status"] = objective.check_completion() - if(!objective.holder) - temp_list["owner_uid"] = "This shit fucked up" - temp_list["owner_name"] = "???" - if(istype(objective.owner, /datum/mind)) - // special handling for contractor objectives I guess - temp_list["owner_uid"] = objective.owner.UID() - temp_list["owner_name"] = objective.owner.name - else - var/datum/thingy = objective.holder.get_holder_owner() - temp_list["owner_uid"] = thingy.UID() - if(istype(thingy, /datum/antagonist)) - var/datum/antagonist/antag = thingy - temp_list["owner_name"] = antag.owner.name - else - temp_list["owner_name"] = "[thingy]" - - var/datum/the_target = objective.found_target() - temp_list["no_target"] = (!objective.needs_target && !the_target) - temp_list["target_name"] = "\[No Assigned Target\]" - temp_list["track"] = list() - if(istype(the_target, /datum/mind)) - var/datum/mind/mind = the_target - temp_list["target_name"] = mind.name - temp_list["track"] = list(the_target.UID()) - - if(istype(the_target, /datum/theft_objective)) - var/datum/theft_objective/theft = the_target - var/atom/theft_target = theft.typepath - temp_list["target_name"] = theft_target.name - var/list/target_uids = list() - for(var/atom/target in GLOB.high_value_items) - if(!istype(target, theft.typepath)) - continue - var/turf/T = get_turf(target) - if(!T || is_admin_level(T.z)) - continue - temp_list["target_name"] = target.name // is usually more accurate, i.e. captains modsuit - target_uids += target.UID() - temp_list["track"] = target_uids - - cached_data["objectives"] += list(temp_list) - - cached_data["high_value_items"] = list() - for(var/atom/target in GLOB.high_value_items) - if(QDELETED(target)) - continue - var/list/temp_list = list() - temp_list["name"] = target.name - temp_list["person"] = get(target, /mob/living) - temp_list["loc"] = target.loc.name - temp_list["uid"] = target.UID() - var/turf/T = get_turf(target) - temp_list["admin_z"] = !T || is_admin_level(T.z) - cached_data["high_value_items"] += list(temp_list) - - cached_data["security"] = list() - for(var/mob/living/carbon/human/player as anything in GLOB.human_list) - if(!player.mind) - continue - var/role = determine_role(player) - if(!(role in GLOB.active_security_positions) && player.mind.special_role != SPECIAL_ROLE_ERT) - continue - var/list/temp_list = list() - temp_list["name"] = player.mind.name - temp_list["role"] = role - temp_list["mind_uid"] = player.mind.UID() - temp_list["ckey"] = ckey(player.mind.key) - temp_list["status"] = player.stat - temp_list["antag"] = (isAntag(player) ? player.mind.special_role : "") - temp_list["broken_bone"] = FALSE - temp_list["internal_bleeding"] = FALSE - for(var/name in player.bodyparts_by_name) - var/obj/item/organ/external/e = player.bodyparts_by_name[name] - if(!e) - continue - temp_list["broken_bone"] |= (e.status & ORGAN_BROKEN) - temp_list["internal_bleeding"] |= (e.status & ORGAN_INT_BLEEDING) - temp_list["health"] = player.health - temp_list["max_health"] = player.maxHealth - cached_data["security"] += list(temp_list) - - -/datum/ui_module/admin/antagonist_menu/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - if(..()) - return - switch(action) - if("refresh") - return TRUE - if("show_player_panel") - var/datum/mind/mind = locateUID(params["mind_uid"]) - if(QDELETED(mind.current)) - to_chat(ui.user, "Mind doesn't have a corresponding mob.") - return - ui.user.client.holder.show_player_panel(mind.current) - if("pm") - ui.user.client.cmd_admin_pm(params["ckey"], null) - if("follow") - var/client/C = ui.user.client - if(!isobserver(ui.user)) - if(!check_rights(R_ADMIN|R_MOD)) // Need to be mod or admin to aghost - return - C.admin_ghost() - var/datum/target = locateUID(params["datum_uid"]) - if(QDELETED(target)) - to_chat(ui.user, "This datum has been deleted!") - return - - if(istype(target, /datum/mind)) - var/datum/mind/mind = target - if(!ismob(mind.current)) - to_chat(ui.user, "This can only be used on instances of type /mob") - return - target = mind.current - - var/mob/dead/observer/A = C.mob - A.ManualFollow(target) - if("obs") - var/client/C = ui.user.client - var/datum/mind/mind = locateUID(params["mind_uid"]) - - if(!ismob(mind.current)) - to_chat(ui.user, "This can only be used on instances of type /mob") - return - C.admin_observe_target(mind.current) - if("tp") - var/datum/mind/mind = locateUID(params["mind_uid"]) - if(QDELETED(mind)) - to_chat(ui.user, "No mind!") - return - mind.edit_memory() - if("vv") - ui.user.client.debug_variables(locateUID(params["uid"]), null) - if("obj_owner") - var/client/C = ui.user.client - var/datum/target = locateUID(params["owner_uid"]) - if(QDELETED(target)) - to_chat(ui.user, "It seems the target you are looking for is null or deleted.") - return - if(istype(target, /datum/antagonist)) - var/datum/antagonist/antag = target - target = antag.owner - if(istype(target, /datum/mind)) - var/datum/mind/mind = target - if(!ismob(mind.current)) - to_chat(ui.user, "This can only be used on instances of type /mob") - return - target = mind.current - var/mob/dead/observer/A = C.mob - A.ManualFollow(target) - return - if(istype(target, /datum/team)) - ui.user.client.holder.team_switch_tab_index = clamp(GLOB.antagonist_teams.Find(target), 1, length(GLOB.antagonist_teams)) - ui.user.client.holder.check_teams() - return - to_chat(ui.user, "Type [target.type] isn't supported for finding the owner of an objective.") diff --git a/code/modules/admin/menus/ui_module_admin.dm b/code/modules/admin/menus/ui_module_admin.dm deleted file mode 100644 index 1a98def992631..0000000000000 --- a/code/modules/admin/menus/ui_module_admin.dm +++ /dev/null @@ -1,22 +0,0 @@ -GLOBAL_LIST_EMPTY(admin_ui_modules) - -// something something singleton -/proc/get_admin_ui_module(type) - if(GLOB.admin_ui_modules[type]) - return GLOB.admin_ui_modules[type] - if(!ispath(type, /datum/ui_module/admin)) - stack_trace("Some motherfucker tried to create [type] with the admin ui module helper!") - return - return new type() - -/datum/ui_module/admin - -/datum/ui_module/admin/New(datum/_host) - . = ..() - if(GLOB.admin_ui_modules[type]) - stack_trace("Some motherfucker overwrote an admin ui module!") - qdel(GLOB.admin_ui_modules[type]) - GLOB.admin_ui_modules[type] = src - -/datum/ui_module/admin/ui_state(mob/user) - return GLOB.admin_state diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm deleted file mode 100644 index 61568f741efd7..0000000000000 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ /dev/null @@ -1,555 +0,0 @@ -// Examples -/* - -- Will call the proc for all computers in the world, thats dir is 2. - CALL ex_act(1) ON /obj/machinery/computer IN world WHERE dir == 2 - -- Will open a window with a list of all the closets in the world, with a link to VV them. - SELECT /obj/structure/closet/secure_closet/security/cargo IN world WHERE icon_off == "secoff" - -- Will change all the tube lights to green - UPDATE /obj/machinery/light IN world SET color = "#0F0" WHERE icon_state == "tube1" - -- Will delete all pickaxes. "IN world" is not required. - DELETE /obj/item/pickaxe - -- Will flicker the lights once, then turn all mobs green. The semicolon is important to separate the consecutive querys, but is not required for standard one-query use - CALL flicker(1) ON /obj/machinery/light; UPDATE /mob SET color = "#00cc00" - - --You can use operators other than ==, such as >, <=, != and etc.. - -*/ - -/client/proc/SDQL2_query() - set category = "Debug" - - if(!check_rights(R_PROCCALL)) //Shouldn't happen... but just to be safe. - message_admins("ERROR: Non-admin [key_name_admin(usr)] attempted to execute a SDQL query!") - log_admin("Non-admin [key_name(usr)] attempted to execute a SDQL query!") - return - - var/query_text = input("SDQL2 query") as message - - if(!query_text || length(query_text) < 1) - return - -// to_chat(world, query_text) - - var/list/query_list = SDQL2_tokenize(query_text) - - if(!query_list || length(query_list) < 1) - return - - var/list/querys = SDQL_parse(query_list) - - if(!querys || length(querys) < 1) - return - - var/query_log = "executed SDQL query: \"[query_text]\"." - message_admins("[key_name_admin(usr)] [query_log]") - query_log = "[key_name(usr)] [query_log]" - log_admin(query_log) - - try - for(var/list/query_tree in querys) - var/list/from_objs = list() - var/list/select_types = list() - - switch(query_tree[1]) - if("explain") - SDQL_testout(query_tree["explain"]) - return - - if("call") - if("on" in query_tree) - select_types = query_tree["on"] - else - return - - if("select", "delete", "update") - select_types = query_tree[query_tree[1]] - - from_objs = SDQL_from_objs(query_tree["from"]) - - var/list/objs = list() - - for(var/type in select_types) - var/char = copytext(type, 1, 2) - - if(char == "/" || char == "*") - for(var/from in from_objs) - objs += SDQL_get_all(type, from) - - else if(char == "'" || char == "\"") - objs += locate(copytext(type, 2, length(type))) - - if("where" in query_tree) - var/objs_temp = objs - objs = list() - for(var/d in objs_temp) - if(SDQL_expression(d, query_tree["where"])) - objs += d - - switch(query_tree[1]) - if("call") - for(var/d in objs) - SDQL_var(d, query_tree["call"][1], source = d) - - if("delete") - for(var/d in objs) - if(istype(d, /datum)) - var/datum/D = d - if(!D.can_vv_delete()) - to_chat(usr, "[D] rejected your deletion") - continue - qdel(d) - - if("select") - var/text = "" - for(var/o in objs) - var/datum/t = o - text += "\ref[t]" - if(istype(t, /atom)) - var/atom/a = t - - if(a.x) - text += ": [t] at ([a.x], [a.y], [a.z])
    " - - else if(a.loc && a.loc.x) - text += ": [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])
    " - - else - text += ": [t]
    " - - else - text += ": [t]
    " - - usr << browse(text, "window=SDQL-result") - - if("update") - if("set" in query_tree) - var/list/set_list = query_tree["set"] - for(var/d in objs) - for(var/list/sets in set_list) - var/datum/temp = d - var/i = 0 - for(var/v in sets) - if(++i == length(sets)) - if(isturf(temp) && (v == "x" || v == "y" || v == "z")) - continue - if(!temp.vv_edit_var(v, SDQL_expression(d, set_list[sets]))) - to_chat(usr, "[temp] rejected your varedit.") - break - if(temp.vars.Find(v) && (istype(temp.vars[v], /datum) || isclient(temp.vars[v]))) - temp = temp.vars[v] - else - break - - catch(var/exception/e) - to_chat(usr, "An exception has occurred during the execution of your query and your query has been aborted.") - to_chat(usr, " [e.name]") - to_chat(usr, " at: [e.file]:[e.line]") - -/proc/SDQL_parse(list/query_list) - var/datum/sdql_parser/parser = new() - var/list/querys = list() - var/list/query_tree = list() - var/pos = 1 - var/querys_pos = 1 - var/do_parse = 0 - - for(var/val in query_list) - if(val == ";") - do_parse = 1 - else if(pos >= length(query_list)) - query_tree += val - do_parse = 1 - - if(do_parse) - parser.query = query_tree - var/list/parsed_tree - parsed_tree = parser.parse() - if(length(parsed_tree) > 0) - querys.len = querys_pos - querys[querys_pos] = parsed_tree - querys_pos++ - else //There was an error so don't run anything, and tell the user which query has errored. - to_chat(usr, "Parsing error on [querys_pos]\th query. Nothing was executed.") - return list() - query_tree = list() - do_parse = 0 - else - query_tree += val - pos++ - - qdel(parser) - - return querys - - - -/proc/SDQL_testout(list/query_tree, indent = 0) - var/spaces = "" - for(var/s = 0, s < indent, s++) - spaces += "    " - - for(var/item in query_tree) - if(istype(item, /list)) - to_chat(usr, "[spaces](") - SDQL_testout(item, indent + 1) - to_chat(usr, "[spaces])") - - else - to_chat(usr, "[spaces][item]") - - if(!isnum(item) && query_tree[item]) - - if(istype(query_tree[item], /list)) - to_chat(usr, "[spaces]    (") - SDQL_testout(query_tree[item], indent + 2) - to_chat(usr, "[spaces]    )") - - else - to_chat(usr, "[spaces]    [query_tree[item]]") - -/proc/SDQL_from_objs(list/tree) - if("world" in tree) - return list(world) - - var/list/out = list() - - for(var/type in tree) - var/char = copytext(type, 1, 2) - - if(char == "/") - out += SDQL_get_all(type, world) - - else if(char == "'" || char == "\"") - out += locate(copytext(type, 2, length(type))) - - return out - -/proc/SDQL_get_all(type, location) - var/list/out = list() - - if(type == "*") - for(var/datum/d in location) - out += d - - return out - - type = text2path(type) - - if(ispath(type, /mob)) - for(var/mob/d in location) - if(istype(d, type)) - out += d - - else if(ispath(type, /turf)) - for(var/turf/d in location) - if(istype(d, type)) - out += d - - else if(ispath(type, /obj)) - for(var/obj/d in location) - if(istype(d, type)) - out += d - - else if(ispath(type, /area)) - for(var/area/d in location) - if(istype(d, type)) - out += d - - else if(ispath(type, /atom)) - for(var/atom/d in location) - if(istype(d, type)) - out += d - - else if(ispath(type, /client)) - for(var/client/C) - if((location != world) && !(C.mob in location)) - continue - out += C - - else if(location == world) - for(var/datum/d) - if(istype(d, type)) - out += d - - else - for(var/datum/d in location) - if(istype(d, type)) - out += d - - return out - -/proc/SDQL_expression(datum/object, list/expression, start = 1) - var/result = 0 - var/val - - for(var/i = start, i <= length(expression), i++) - var/op = "" - - if(i > start) - op = expression[i] - i++ - - var/list/ret = SDQL_value(object, expression, i) - val = ret["val"] - i = ret["i"] - - if(op != "") - switch(op) - if("+") - result += val - if("-") - result -= val - if("*") - result *= val - if("/") - result /= val - if("&") - result &= val - if("|") - result |= val - if("^") - result ^= val - if("=", "==") - result = (result == val) - if("!=", "<>") - result = (result != val) - if("<") - result = (result < val) - if("<=") - result = (result <= val) - if(">") - result = (result > val) - if(">=") - result = (result >= val) - if("and", "&&") - result = (result && val) - if("or", "||") - result = (result || val) - else - to_chat(usr, "SDQL2: Unknown op [op]") - result = null - else - result = val - - return result - -/proc/SDQL_value(datum/object, list/expression, start = 1) - var/i = start - var/val = null - - if(i > length(expression)) - return list("val" = null, "i" = i) - - if(istype(expression[i], /list)) - val = SDQL_expression(object, expression[i]) - - else if(expression[i] == "!") - var/list/ret = SDQL_value(object, expression, i + 1) - val = !ret["val"] - i = ret["i"] - - else if(expression[i] == "~") - var/list/ret = SDQL_value(object, expression, i + 1) - val = ~ret["val"] - i = ret["i"] - - else if(expression[i] == "-") - var/list/ret = SDQL_value(object, expression, i + 1) - val = -ret["val"] - i = ret["i"] - - else if(expression[i] == "null") - val = null - - else if(isnum(expression[i])) - val = expression[i] - - else if(copytext(expression[i], 1, 2) in list("'", "\"")) - val = copytext(expression[i], 2, length(expression[i])) - - else if(expression[i] == "{") - var/list/expressions_list = expression[++i] - val = list() - for(var/list/expression_list in expressions_list) - val += SDQL_expression(object, expression_list) - - else - val = SDQL_var(object, expression, i, object) - i = length(expression) - - return list("val" = val, "i" = i) - -/proc/SDQL_var(datum/object, list/expression, start = 1, source) - var/v - - var/long = start < length(expression) - - if(object == world && long && expression[start + 1] == ".") - to_chat(usr, "Sorry, but global variables are not supported at the moment.") - return null - - if(expression[start] == "\[" && long) - if(lowertext(copytext(expression[start + 1], 1, 3)) != "0x") - to_chat(usr, "Invalid ref syntax: [expression[start + 1]]") - return null - v = locate("\[[expression[start + 1]]\]") - if(!v) - to_chat(usr, "Invalid ref: [expression[start + 1]]") - return null - start++ - - else if((!long || expression[start + 1] == "." || expression[start + 1] == "\[") && (expression[start] in object.vars)) - v = object.vars[expression[start]] - - else if(long && expression[start + 1] == ":" && hascall(object, expression[start])) - v = expression[start] - - else if(!long || expression[start + 1] == ".") - switch(expression[start]) - if("usr") - v = usr - if("src") - v = source - if("marked") - if(usr.client && usr.client.holder && usr.client.holder.marked_datum) - v = usr.client.holder.marked_datum - else - return null - if("global") - v = world // World is mostly a token, really. - else - return null - - else if(object == world) - v = expression[start] - - if(long) - if(expression[start + 1] == ".") - return SDQL_var(v, expression[start + 2], source = source) - else if(expression[start + 1] == ":") - return SDQL_function(object, v, expression[start + 2], source) - else if(expression[start + 1] == "\[" && islist(v)) - var/list/L = v - var/index = SDQL_expression(source, expression[start + 2]) - if(isnum(index) && (!ISINTEGER(index) || length(L) < index)) - to_chat(world, "Invalid list index: [index]") - return null - return L[index] - - return v - -/proc/SDQL_function(datum/object, procname, list/arguments, source) - var/list/new_args = list() - for(var/arg in arguments) - new_args[++new_args.len] = SDQL_expression(source, arg) - - if(object == world) // Global proc. - return (WrapAdminProcCall(GLOBAL_PROC, procname, new_args)) - - return (WrapAdminProcCall(object, procname, new_args)) - -/proc/SDQL2_tokenize(query_text) - - var/list/whitespace = list(" ", "\n", "\t") - var/list/single = list("(", ")", ",", "+", "-", ".", ";", "\[", "\]", "{", "}") - var/list/multi = list( - "=" = list("", "="), - "<" = list("", "=", ">"), - ">" = list("", "="), - "!" = list("", "=")) - - var/word = "" - var/list/query_list = list() - var/len = length(query_text) - - for(var/i = 1, i <= len, i++) - var/char = copytext(query_text, i, i + 1) - - if(char in whitespace) - if(word != "") - query_list += word - word = "" - - else if(char in single) - if(word != "") - query_list += word - word = "" - - query_list += char - - else if(char in multi) - if(word != "") - query_list += word - word = "" - - var/char2 = copytext(query_text, i + 1, i + 2) - - if(char2 in multi[char]) - query_list += "[char][char2]" - i++ - - else - query_list += char - - else if(char == "'") - if(word != "") - to_chat(usr, "SDQL2: You have an error in your SDQL syntax, unexpected ' in query: \"[query_text]\" following \"[word]\". Please check your syntax, and try again.") - return null - - word = "'" - - for(i++, i <= len, i++) - char = copytext(query_text, i, i + 1) - - if(char == "'") - if(copytext(query_text, i + 1, i + 2) == "'") - word += "'" - i++ - - else - break - - else - word += char - - if(i > len) - to_chat(usr, "SDQL2: You have an error in your SDQL syntax, unmatched ' in query: \"[query_text]\". Please check your syntax, and try again.") - return null - - query_list += "[word]'" - word = "" - - else if(char == "\"") - if(word != "") - to_chat(usr, "SDQL2: You have an error in your SDQL syntax, unexpected \" in query: \"[query_text]\" following \"[word]\". Please check your syntax, and try again.") - return null - - word = "\"" - - for(i++, i <= len, i++) - char = copytext(query_text, i, i + 1) - - if(char == "\"") - if(copytext(query_text, i + 1, i + 2) == "'") - word += "\"" - i++ - - else - break - - else - word += char - - if(i > len) - to_chat(usr, "SDQL2: You have an error in your SDQL syntax, unmatched \" in query: \"[query_text]\". Please check your syntax, and try again.") - return null - - query_list += "[word]\"" - word = "" - - else - word += char - - if(word != "") - query_list += word - return query_list diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm deleted file mode 100644 index 6915e715ab76c..0000000000000 --- a/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm +++ /dev/null @@ -1,592 +0,0 @@ -//I'm pretty sure that this is a recursive [s]descent[/s] ascent parser. -//Spec -////////// -// -// query : select_query | delete_query | update_query | call_query | explain -// explain : 'EXPLAIN' query -// -// select_query : 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] -// delete_query : 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] -// update_query : 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression] -// call_query : 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]] -// -// select_list : select_item [',' select_list] -// select_item : '*' | select_function | object_type -// select_function : count_function -// count_function : 'COUNT' '(' '*' ')' | 'COUNT' '(' object_types ')' -// -// from_list : from_item [',' from_list] -// from_item : 'world' | object_type -// -// call_function : ['(' [arguments] ')'] -// arguments : expression [',' arguments] -// -// object_type : | string -// -// assignments : assignment, [',' assignments] -// assignment : '=' expression -// variable : | '.' variable | '[' ']' | '[' ']' '.' variable -// -// bool_expression : expression comparitor expression [bool_operator bool_expression] -// expression : ( unary_expression | '(' expression ')' | value ) [binary_operator expression] -// unary_expression : unary_operator ( unary_expression | value | '(' expression ')' ) -// comparitor : '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>=' -// value : variable | string | array | number | 'null' -// unary_operator : '!' | '-' | '~' -// binary_operator : comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^' -// bool_operator : 'AND' | '&&' | 'OR' | '||' -// -// string : ''' ''' | '"' '"' -// array : '{' [arguments] '}' -// number : -// -////////// - -/datum/sdql_parser - var/query_type - var/error = 0 - - var/list/query - var/list/tree - - var/list/select_functions = list("count") - var/list/boolean_operators = list("and", "or", "&&", "||") - var/list/unary_operators = list("!", "-", "~") - var/list/binary_operators = list("+", "-", "/", "*", "&", "|", "^") - var/list/comparitors = list("=", "==", "!=", "<>", "<", "<=", ">", ">=") - -/datum/sdql_parser/New(query_list) - query = query_list - -/datum/sdql_parser/proc/parse_error(error_message) - error = 1 - to_chat(usr, "SDQL2 Parsing Error: [error_message]") - return length(query) + 1 - -/datum/sdql_parser/proc/parse() - tree = list() - query(1, tree) - - if(error) - return list() - else - return tree - -/datum/sdql_parser/proc/token(i) - if(i <= length(query)) - return query[i] - - else - return null - -/datum/sdql_parser/proc/tokens(i, num) - if(i + num <= length(query)) - return query.Copy(i, i + num) - - else - return null - -/datum/sdql_parser/proc/tokenl(i) - return lowertext(token(i)) - -//query: select_query | delete_query | update_query -/datum/sdql_parser/proc/query(i, list/node) - query_type = tokenl(i) - - switch(query_type) - if("select") - select_query(i, node) - - if("delete") - delete_query(i, node) - - if("update") - update_query(i, node) - - if("call") - call_query(i, node) - - if("explain") - node += "explain" - node["explain"] = list() - query(i + 1, node["explain"]) - - -// select_query: 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] -/datum/sdql_parser/proc/select_query(i, list/node) - var/list/select = list() - i = select_list(i + 1, select) - - node += "select" - node["select"] = select - - var/list/from = list() - if(tokenl(i) in list("from", "in")) - i = from_list(i + 1, from) - else - from += "world" - - node += "from" - node["from"] = from - - if(tokenl(i) == "where") - var/list/where = list() - i = bool_expression(i + 1, where) - - node += "where" - node["where"] = where - - return i - - -//delete_query: 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] -/datum/sdql_parser/proc/delete_query(i, list/node) - var/list/select = list() - i = select_list(i + 1, select) - - node += "delete" - node["delete"] = select - - var/list/from = list() - if(tokenl(i) in list("from", "in")) - i = from_list(i + 1, from) - else - from += "world" - - node += "from" - node["from"] = from - - if(tokenl(i) == "where") - var/list/where = list() - i = bool_expression(i + 1, where) - - node += "where" - node["where"] = where - - return i - - -//update_query: 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression] -/datum/sdql_parser/proc/update_query(i, list/node) - var/list/select = list() - i = select_list(i + 1, select) - - node += "update" - node["update"] = select - - var/list/from = list() - if(tokenl(i) in list("from", "in")) - i = from_list(i + 1, from) - else - from += "world" - - node += "from" - node["from"] = from - - if(tokenl(i) != "set") - i = parse_error("UPDATE has misplaced SET") - - var/list/set_assignments = list() - i = assignments(i + 1, set_assignments) - - node += "set" - node["set"] = set_assignments - - if(tokenl(i) == "where") - var/list/where = list() - i = bool_expression(i + 1, where) - - node += "where" - node["where"] = where - - return i - - -//call_query: 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]] -/datum/sdql_parser/proc/call_query(i, list/node) - var/list/func = list() - i = variable(i + 1, func) - - node += "call" - node["call"] = func - - if(tokenl(i) != "on") - return i - - var/list/select = list() - i = select_list(i + 1, select) - - node += "on" - node["on"] = select - - var/list/from = list() - if(tokenl(i) in list("from", "in")) - i = from_list(i + 1, from) - else - from += "world" - - node += "from" - node["from"] = from - - if(tokenl(i) == "where") - var/list/where = list() - i = bool_expression(i + 1, where) - - node += "where" - node["where"] = where - - return i - - -//select_list: select_item [',' select_list] -/datum/sdql_parser/proc/select_list(i, list/node) - i = select_item(i, node) - - if(token(i) == ",") - i = select_list(i + 1, node) - - return i - - -//from_list: from_item [',' from_list] -/datum/sdql_parser/proc/from_list(i, list/node) - i = from_item(i, node) - - if(token(i) == ",") - i = from_list(i + 1, node) - - return i - - -//assignments: assignment, [',' assignments] -/datum/sdql_parser/proc/assignments(i, list/node) - i = assignment(i, node) - - if(token(i) == ",") - i = assignments(i + 1, node) - - return i - - -//select_item: '*' | select_function | object_type -/datum/sdql_parser/proc/select_item(i, list/node) - if(token(i) == "*") - node += "*" - i++ - - else if(tokenl(i) in select_functions) - i = select_function(i, node) - - else - i = object_type(i, node) - - return i - - -//from_item: 'world' | object_type -/datum/sdql_parser/proc/from_item(i, list/node) - - if(token(i) == "world") - node += "world" - i++ - - else - i = object_type(i, node) - - return i - - -//bool_expression: expression [bool_operator bool_expression] -/datum/sdql_parser/proc/bool_expression(i, list/node) - var/list/bool = list() - i = expression(i, bool) - - node[++node.len] = bool - - if(tokenl(i) in boolean_operators) - i = bool_operator(i, node) - i = bool_expression(i, node) - - return i - - -//assignment: '=' expression -/datum/sdql_parser/proc/assignment(i, list/node, list/assignment_list = list()) - assignment_list += token(i) - - if(token(i + 1) == ".") - i = assignment(i + 2, node, assignment_list) - - else if(token(i + 1) == "=") - var/exp_list = list() - node[assignment_list] = exp_list - - i = expression(i + 2, exp_list) - - else - parse_error("Assignment expected, but no = found") - - return i - - -//variable: | '.' variable -/datum/sdql_parser/proc/variable(i, list/node) - var/list/L = list(token(i)) - node[++node.len] = L - - if(token(i) == "\[") - L += token(i + 1) - i += 2 - - if(token(i) != "\]") - parse_error("Missing \] at end of reference.") - - if(token(i + 1) == ".") - L += "." - i = variable(i + 2, L) - - else if(token(i + 1) == "(") // OH BOY PROC - var/list/arguments = list() - i = call_function(i, null, arguments) - L += ":" - L[++L.len] = arguments - - else if(token(i + 1) == "\[") // list index - var/list/expression = list() - i = expression(i + 2, expression) - if(token(i) != "]") - parse_error("Missing ] at the end of list access.") - - L += "\[" - L[++L.len] = expression - i++ - - else - i++ - - return i - - -//object_type: | string -/datum/sdql_parser/proc/object_type(i, list/node) - - if(copytext(token(i), 1, 2) == "/") - node += token(i) - - else - i = string(i, node) - - return i + 1 - - -//comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>=' -/datum/sdql_parser/proc/comparitor(i, list/node) - - if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">=")) - node += token(i) - - else - parse_error("Unknown comparitor [token(i)]") - - return i + 1 - - -//bool_operator: 'AND' | '&&' | 'OR' | '||' -/datum/sdql_parser/proc/bool_operator(i, list/node) - - if(tokenl(i) in list("and", "or", "&&", "||")) - node += token(i) - - else - parse_error("Unknown comparitor [token(i)]") - - return i + 1 - - -//string: ''' ''' | '"' '"' -/datum/sdql_parser/proc/string(i, list/node) - - if(copytext(token(i), 1, 2) in list("'", "\"")) - node += token(i) - - else - parse_error("Expected string but found '[token(i)]'") - - return i + 1 - - //array: '{' expression, expression, ... '}' -/datum/sdql_parser/proc/array(i, list/node) - // Arrays get turned into this: list("{", list(exp_1a = exp_1b, ...), ...), "{" is to mark the next node as an array. - if(copytext(token(i), 1, 2) != "{") - parse_error("Expected an array but found '[token(i)]'") - return i + 1 - - node += token(i) // Add the "{" - var/list/expression_list = list() - - if(token(i + 1) != "}") - var/list/temp_expression_list = list() - - do - i = expression(i + 1, temp_expression_list) - - if(token(i) == ",") - expression_list[++expression_list.len] = temp_expression_list - temp_expression_list = list() - while(token(i) && token(i) != "}") - - expression_list[++expression_list.len] = temp_expression_list - else - i++ - - node[++node.len] = expression_list - return i + 1 - -//call_function: ['(' [arguments] ')'] -/datum/sdql_parser/proc/call_function(i, list/node, list/arguments) - var/list/cur_argument = list() - if(length(tokenl(i))) - var/procname = "" - if(tokenl(i) == "global" && token(i + 1) == ".") // Global proc. - i += 2 - procname = "global." - node += procname + token(i++) - if(token(i) != "(") - parse_error("Expected ( but found '[token(i)]'") - else if(token(i + 1) != ")") - do - i = expression(i + 1, cur_argument) - if(token(i) == ",") - arguments += list(cur_argument) - cur_argument = list() - continue - while(token(i) && token(i) != ")") - arguments += list(cur_argument) - else - i++ - else - parse_error("Expected a function but found nothing") - return i + 1 - - -//select_function: count_function -/datum/sdql_parser/proc/select_function(i, list/node) - - parse_error("Sorry, function calls aren't available yet") - - return i - - -//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression] -/datum/sdql_parser/proc/expression(i, list/node) - - if(token(i) in unary_operators) - i = unary_expression(i, node) - - else if(token(i) == "(") - var/list/expr = list() - - i = expression(i + 1, expr) - - if(token(i) != ")") - parse_error("Missing ) at end of expression.") - - else - i++ - - node[++node.len] = expr - - else - i = value(i, node) - - if(token(i) in binary_operators) - i = binary_operator(i, node) - i = expression(i, node) - - else if(token(i) in comparitors) - i = binary_operator(i, node) - - var/list/rhs = list() - i = expression(i, rhs) - - node[++node.len] = rhs - - - return i - - -//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' ) -/datum/sdql_parser/proc/unary_expression(i, list/node) - - if(token(i) in unary_operators) - var/list/unary_exp = list() - - unary_exp += token(i) - i++ - - if(token(i) in unary_operators) - i = unary_expression(i, unary_exp) - - else if(token(i) == "(") - var/list/expr = list() - - i = expression(i + 1, expr) - - if(token(i) != ")") - parse_error("Missing ) at end of expression.") - - else - i++ - - unary_exp[++unary_exp.len] = expr - - else - i = value(i, unary_exp) - - node[++node.len] = unary_exp - - - else - parse_error("Expected unary operator but found '[token(i)]'") - - return i - - -//binary_operator: comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^' -/datum/sdql_parser/proc/binary_operator(i, list/node) - - if(token(i) in (binary_operators + comparitors)) - node += token(i) - - else - parse_error("Unknown binary operator [token(i)]") - - return i + 1 - - -//value: variable | string | number | 'null' -/datum/sdql_parser/proc/value(i, list/node) - - if(token(i) == "null") - node += "null" - i++ - - else if(lowertext(copytext(token(i), 1, 3)) == "0x" && isnum(hex2num(copytext(token(i), 3)))) - node += hex2num(copytext(token(i), 3)) - i++ - - else if(isnum(text2num(token(i)))) - node += text2num(token(i)) - i++ - - else if(copytext(token(i), 1, 2) in list("'", "\"")) - i = string(i, node) - - else if(copytext(token(i), 1, 2) == "{") // Start a list. - i = array(i, node) - - else - i = variable(i, node) - - return i -/*EXPLAIN SELECT * WHERE 42 = 6 * 9 OR val = - 5 == 7*/ diff --git a/code/modules/admin/verbs/onlyone.dm b/code/modules/admin/verbs/onlyone.dm deleted file mode 100644 index 041e39422dea1..0000000000000 --- a/code/modules/admin/verbs/onlyone.dm +++ /dev/null @@ -1,111 +0,0 @@ -/client/proc/only_one() - if(!SSticker) - alert("The game hasn't started yet!") - return - - var/list/incompatible_species = list(/datum/species/plasmaman, /datum/species/vox) - for(var/mob/living/carbon/human/H in GLOB.player_list) - if(H.stat == DEAD || !(H.client)) - continue - if(is_special_character(H)) - continue - if(is_type_in_list(H.dna.species, incompatible_species)) - H.set_species(/datum/species/human) - var/datum/character_save/S = new // Randomize appearance - S.randomise() - S.copy_to(H) - - SSticker.mode.traitors += H.mind - H.mind.special_role = SPECIAL_ROLE_TRAITOR - - H.mind.add_mind_objective(/datum/objective/hijack) - - var/list/messages = list() - messages.Add("You are a Highlander. Kill all other Highlanders. There can be only one.") - messages.Add(H.mind.prepare_announce_objectives(FALSE)) - to_chat(H, chat_box_red(messages.Join("
    "))) - - for(var/obj/item/I in H) - if(istype(I, /obj/item/bio_chip)) - continue - qdel(I) - - H.equip_to_slot_or_del(new /obj/item/clothing/under/costume/kilt(H), ITEM_SLOT_JUMPSUIT) - H.equip_to_slot_or_del(new /obj/item/radio/headset/heads/captain(H), ITEM_SLOT_LEFT_EAR) - H.equip_to_slot_or_del(new /obj/item/clothing/head/beret(H), ITEM_SLOT_HEAD) - H.equip_to_slot_or_del(new /obj/item/claymore/highlander(H), ITEM_SLOT_RIGHT_HAND) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), ITEM_SLOT_SHOES) - H.equip_to_slot_or_del(new /obj/item/pinpointer(H.loc), ITEM_SLOT_LEFT_POCKET) - - var/obj/item/card/id/W = new(H) - W.name = "[H.real_name]'s ID Card" - W.icon_state = "centcom" - W.access = get_all_accesses() - W.access += get_all_centcom_access() - W.assignment = "Highlander" - W.registered_name = H.real_name - H.equip_to_slot_or_del(W, ITEM_SLOT_ID) - H.dna.species.after_equip_job(null, H) - H.regenerate_icons() - - message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ONE! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1) - log_admin("[key_name(usr)] used there can be only one.") - GLOB.nologevent = 1 - - var/sound/music = sound('sound/music/thunderdome.ogg', channel = CHANNEL_ADMIN) - for(var/mob/M in GLOB.player_list) - if(M.client.prefs.sound & SOUND_MIDI) - if(isnewplayer(M) && (M.client.prefs.sound & SOUND_LOBBY)) - M.stop_sound_channel(CHANNEL_LOBBYMUSIC) - music.volume = 100 * M.client.prefs.get_channel_volume(CHANNEL_ADMIN) - SEND_SOUND(M, music) - -/client/proc/only_me() - if(!SSticker) - alert("The game hasn't started yet!") - return - - for(var/mob/living/carbon/human/H in GLOB.player_list) - if(H.stat == DEAD || !(H.client)) continue - if(is_special_character(H)) continue - - SSticker.mode.traitors += H.mind - H.mind.special_role = "[H.real_name] Prime" - - H.mind.add_mind_objective(/datum/objective/hijackclone) - - var/list/messages = list() - messages.Add("You are the multiverse summoner. Activate your blade to summon copies of yourself from another universe to fight by your side.") - messages.Add(H.mind.prepare_announce_objectives(FALSE)) - to_chat(H, chat_box_red(messages.Join("
    "))) - - var/obj/item/slot_item_ID = H.get_item_by_slot(ITEM_SLOT_ID) - qdel(slot_item_ID) - var/obj/item/slot_item_hand = H.get_item_by_slot(ITEM_SLOT_RIGHT_HAND) - H.drop_item_to_ground(slot_item_hand) - - var/obj/item/multisword/pure_evil/multi = new(H) - H.equip_to_slot_or_del(multi, ITEM_SLOT_RIGHT_HAND) - - var/obj/item/card/id/W = new(H) - W.icon_state = "centcom" - W.access = get_all_accesses() - W.access += get_all_centcom_access() - W.assignment = "Multiverse Summoner" - W.registered_name = H.real_name - W.update_label(H.real_name) - H.equip_to_slot_or_del(W, ITEM_SLOT_ID) - - H.update_icons() - - message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ME! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1) - log_admin("[key_name(usr)] used there can be only me.") - GLOB.nologevent = 1 - - var/sound/music = sound('sound/music/thunderdome.ogg', channel = CHANNEL_ADMIN) - for(var/mob/M in GLOB.player_list) - if(M.client.prefs.sound & SOUND_MIDI) - if(isnewplayer(M) && (M.client.prefs.sound & SOUND_LOBBY)) - M.stop_sound_channel(CHANNEL_LOBBYMUSIC) - music.volume = 100 * M.client.prefs.get_channel_volume(CHANNEL_ADMIN) - SEND_SOUND(M, music) diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm deleted file mode 100644 index 5a9e9990f33e7..0000000000000 --- a/code/modules/admin/verbs/pray.dm +++ /dev/null @@ -1,95 +0,0 @@ -/mob/living/verb/pray(msg as text) - set category = "IC" - set name = "Pray" - - msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN)) - if(!msg) - return - - if(usr.client) - if(check_mute(client.ckey, MUTE_PRAY)) - to_chat(usr, "You cannot pray (muted).") - return - if(client.handle_spam_prevention(msg, MUTE_PRAY, OOC_COOLDOWN)) - return - - var/image/cross = image('icons/obj/storage.dmi',"bible") - var/font_color = "purple" - var/prayer_type = "PRAYER" - var/deity - if(usr.job == "Chaplain") - if(SSticker && SSticker.Bible_deity_name) - deity = SSticker.Bible_deity_name - cross = image('icons/obj/storage.dmi',"kingyellow") - font_color = "blue" - prayer_type = "CHAPLAIN PRAYER" - else if(IS_CULTIST(usr)) - cross = image('icons/obj/storage.dmi',"tome") - font_color = "red" - prayer_type = "CULTIST PRAYER" - deity = GET_CULT_DATA(entity_name, "Cult God") - - log_say("(PRAYER) [msg]", usr) - msg = "[bicon(cross)][prayer_type][deity ? " (to [deity])" : ""][mind && HAS_MIND_TRAIT(usr, TRAIT_HOLY) ? " (blessings: [mind.num_blessed])" : ""]: [key_name(src, 1)] ([ADMIN_QUE(src,"?")]) ([ADMIN_PP(src,"PP")]) ([ADMIN_VV(src,"VV")]) ([ADMIN_TP(src,"TP")]) ([ADMIN_SM(src,"SM")]) ([admin_jump_link(src)]) ([ADMIN_SC(src,"SC")]) (BLESS) (SMITE): [msg]" - - for(var/client/X in GLOB.admins) - if(check_rights(R_EVENT,0,X.mob)) - to_chat(X, msg, MESSAGE_TYPE_ADMINPM) - if(X.prefs.sound & SOUND_PRAYERNOTIFY) - SEND_SOUND(X, sound('sound/items/PDA/ambicha4-short.ogg')) - to_chat(usr, "Your prayers have been received by the gods.") - - SSblackbox.record_feedback("tally", "admin_verb", 1, "Pray") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/proc/Centcomm_announce(text, mob/Sender) - var/msg = sanitize(copytext_char(text, 1, MAX_MESSAGE_LEN)) - msg = "CENTCOMM: [key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_CENTCOM_REPLY(Sender,"RPLY")])): [msg]" - for(var/client/X in GLOB.admins) - if(R_EVENT & X.holder.rights) - to_chat(X, msg, MESSAGE_TYPE_ADMINPM) - if(X.prefs.sound & SOUND_ADMINHELP) - SEND_SOUND(X, sound('sound/effects/adminhelp.ogg')) - -/proc/Syndicate_announce(text, mob/Sender) - var/msg = sanitize(copytext_char(text, 1, MAX_MESSAGE_LEN)) - msg = "SYNDICATE: [key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_SYNDICATE_REPLY(Sender,"RPLY")]): [msg]" - for(var/client/X in GLOB.admins) - if(check_rights(R_EVENT,0,X.mob)) - to_chat(X, msg, MESSAGE_TYPE_ADMINPM) - if(X.prefs.sound & SOUND_ADMINHELP) - SEND_SOUND(X, sound('sound/effects/adminhelp.ogg')) - -/proc/ERT_Announce(text, mob/Sender, repeat_warning) - var/msg = sanitize(text) - var/insert_this = list(list( - "time" = station_time_timestamp(), - "sender_real_name" = "[Sender.real_name ? Sender.real_name : Sender.name]", - "sender_uid" = Sender.UID(), - "message" = html_decode(msg))) - GLOB.ert_request_messages.Insert(1, insert_this) // insert it to the top of the list - msg = "ERT REQUEST: [key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) (RESPOND): [msg]" - if(repeat_warning) - msg += "
    WARNING: ERT request has gone 5 minutes with no reply!" - for(var/client/X in GLOB.admins) - if(check_rights(R_EVENT,0,X.mob)) - to_chat(X, msg, MESSAGE_TYPE_ADMINPM) - if(X.prefs.sound & SOUND_ADMINHELP) - SEND_SOUND(X, sound('sound/effects/adminhelp.ogg')) - -/proc/Nuke_request(text , mob/Sender) - var/nuke_code = get_nuke_code() - var/nuke_status = get_nuke_status() - var/msg = sanitize(copytext_char(text, 1, MAX_MESSAGE_LEN)) - msg = "NUKE CODE REQUEST: [key_name(Sender)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_CENTCOM_REPLY(Sender,"RPLY")]): [msg]" - for(var/client/X in GLOB.admins) - if(check_rights(R_EVENT,0,X.mob)) - to_chat(X, msg, MESSAGE_TYPE_ADMINPM) - if(nuke_status == NUKE_MISSING) - to_chat(X, "The nuclear device is not on station!") - else - to_chat(X, "The nuke code is [nuke_code].") - if(nuke_status == NUKE_CORE_MISSING) - to_chat(X, "The nuclear device does not have a core, and will not arm!") - if(X.prefs.sound & SOUND_ADMINHELP) - SEND_SOUND(X, sound('sound/effects/adminhelp.ogg')) - diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm deleted file mode 100644 index b1ae6bc7f43af..0000000000000 --- a/code/modules/antagonists/_common/antag_datum.dm +++ /dev/null @@ -1,500 +0,0 @@ -RESTRICT_TYPE(/datum/antagonist) - -GLOBAL_LIST_EMPTY(antagonists) - -#define SUCCESSFUL_DETACH "dont touch this string numbnuts" - -/datum/antagonist - /// The name of the antagonist. - var/name = "Antagonist" - /// 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 - /// Mind that owns this datum. - var/datum/mind/owner - /// Should the owner mob get a greeting text? Determines whether or not the `greet()` proc is called. - var/silent = FALSE - /// List of other antag datum types that this type can't coexist with. - var/list/antag_datum_blacklist - /// Used to determine if the player jobbanned from this role. Things like `SPECIAL_ROLE_TRAITOR` should go here to determine the role. - var/job_rank - /// Should we replace the role-banned player with a ghost? - var/replace_banned = TRUE - /// List of objectives connected to this datum. - VAR_PRIVATE/datum/objective_holder/objective_holder - /// Antagonist datum specific information that appears in the player's notes. Information stored here will be removed when the datum is removed from the player. - var/antag_memory - /// The special role that will be applied to the owner's `special_role` var. i.e. `SPECIAL_ROLE_TRAITOR`, `SPECIAL_ROLE_VAMPIRE`. - var/special_role - /// Should we automatically give this antagonist objectives upon them gaining the datum? - var/give_objectives = TRUE - /// Holds the type of antagonist hud this datum will get, i.e. `ANTAG_HUD_TRAITOR`, `ANTAG_HUD_VAMPIRE`, etc. - var/antag_hud_type - /// Holds the name of the hud's icon in the .dmi files, i.e "hudtraitor", "hudvampire", etc. - var/antag_hud_name - /// If the owner is a clown, this text will be displayed to them when they gain this datum. - var/clown_gain_text = "You are no longer clumsy." - /// If the owner is a clown, this text will be displayed to them when they lose this datum. - var/clown_removal_text = "You are clumsy again." - /// The spawn class to use for gain/removal clown text - var/clown_text_span_class = "boldnotice" - /// If the antagonist can have their spoken voice be something else, this is the "voice" that they will appear as. - var/mimicking = "" - /// The url page name for this antagonist, appended to the end of the wiki url in the form of: [GLOB.configuration.url.wiki_url]/index.php/[wiki_page_name] - var/wiki_page_name - /// The organization, if any, this antag is associated with - var/datum/antag_org/organization - - //Blurb stuff - /// Intro Blurbs text colour - var/blurb_text_color = COLOR_BLACK - /// Intro Blurbs outline width - var/blurb_text_outline_width = 0 - /// Intro Blurb Font - var/blurb_font = "Courier New" - //Backgrount - var/blurb_r = 0 - var/blurb_g = 0 - var/blurb_b = 0 - var/blurb_a = 0 - - /// Do we have delayed objective giving? - var/delayed_objectives = FALSE - -/datum/antagonist/New() - GLOB.antagonists += src - objective_holder = new(src) - -/datum/antagonist/Destroy(force, ...) - qdel(objective_holder) - GLOB.antagonists -= src - if(!QDELETED(owner) && detach_from_owner() != SUCCESSFUL_DETACH) - stack_trace("[src] ([type]) failed to detach from owner! This is very bad!") - - return ..() - -/** - * Removes owner's dependencies on this antag datum. - * For example: removal of antag datum from owner's `antag_datums`, antag datum related teams etc. - * If your `/datum/antagonist` subtype adds more dependencies on `owner` - they should be cleared there. - */ -/datum/antagonist/proc/detach_from_owner() - SHOULD_CALL_PARENT(TRUE) - - remove_owner_from_gamemode() - if(!silent) - farewell() - remove_innate_effects() - antag_memory = null - var/datum/team/team = get_team() - team?.remove_member(owner) - LAZYREMOVE(owner.antag_datums, src) - restore_last_hud_and_role() - owner = null - return SUCCESSFUL_DETACH - -/** - * Adds the owner to their respective gamemode's list. For example `SSticker.mode.traitors |= owner`. - */ -/datum/antagonist/proc/add_owner_to_gamemode() - return - -/** - * Removes the owner from their respective gamemode's list. For example `SSticker.mode.traitors -= owner`. - */ -/datum/antagonist/proc/remove_owner_from_gamemode() - return - -/** - * Loops through the owner's `antag_datums` list and determines if this one is blacklisted by any others. - * - * If it's in one of their blacklists, return FALSE. It cannot coexist with the datum we're trying to add here. - */ -/datum/antagonist/proc/can_be_owned(datum/mind/new_owner) - var/datum/mind/tested = new_owner || owner - if(tested.has_antag_datum(type)) - return FALSE - for(var/i in tested.antag_datums) - var/datum/antagonist/A = i - if(LAZYIN(A.antag_datum_blacklist, type)) - return FALSE - return TRUE - -/** - * Removes antagonist datum effects from the old body and applies it to the new one. - * - * Called in the`/datum/mind/proc/transfer_to()`. - * - * Arguments: - * * new_body - the new body the antag mob is transferring into. - * * old_body - the old body the antag mob is leaving. - */ -/datum/antagonist/proc/on_body_transfer(mob/living/old_body, mob/living/new_body) - remove_innate_effects(old_body) - apply_innate_effects(new_body) - -/** - * This handles the application of antag huds/special abilities. - * - * Gives the antag mob their assigned hud. - * If they're a clown, removes their clumsy mutataion. - * - * Arguments: - * * mob/living/mob_override - a mob to apply effects to. Can be null. - */ -/datum/antagonist/proc/apply_innate_effects(mob/living/mob_override) - SHOULD_CALL_PARENT(TRUE) - var/mob/living/L = mob_override || owner.current - if(antag_hud_type && antag_hud_name) - add_antag_hud(L) - // If `mob_override` exists it means we're only transferring this datum, we don't need to show the clown any text. - handle_clown_mutation(L, mob_override ? null : clown_gain_text, TRUE) - return L - -/** - * This handles the removal of antag huds/special abilities. - * - * Removes the antag's assigned hud. - * If they're a clown, gives them back their clumsy mutataion. - * - * Arguments: - * * mob/living/mob_override - a mob to remove effects from. Can be null. - */ -/datum/antagonist/proc/remove_innate_effects(mob/living/mob_override) - SHOULD_CALL_PARENT(TRUE) - var/mob/living/L = mob_override || owner.current - if(antag_hud_type && antag_hud_name) - remove_antag_hud(L) - // If `mob_override` exists it means we're only transferring this datum, we don't need to show the clown any text. - handle_clown_mutation(L, mob_override ? null : clown_removal_text) - return L - -/** - * Selects and set the organization this antag is associated with. - * Base proc, override as needed - */ -/datum/antagonist/proc/select_organization() - return - -/** - * Adds this datum's antag hud to `antag_mob`. - * - * Arguments: - * * antag_mob - the mob to add the antag hud to. - */ -/datum/antagonist/proc/add_antag_hud(mob/living/antag_mob) - var/datum/atom_hud/antag/hud = GLOB.huds[antag_hud_type] - hud.join_hud(antag_mob) - set_antag_hud(antag_mob, antag_hud_name) - -/** - * Removes this datum's antag hud from `antag_mob`. - * - * Arguments: - * * antag_mob - the mob to remove the antag hud from. - */ -/datum/antagonist/proc/remove_antag_hud(mob/living/antag_mob) - var/datum/atom_hud/antag/hud = GLOB.huds[antag_hud_type] - hud.leave_hud(antag_mob) - set_antag_hud(antag_mob, null) - -/** - * Handles adding and removing the clumsy mutation from clown antags. - * - * Arguments: - * * clown - the mob in which to add or remove clumsy from. - * * message - the chat message to display to them the clown mob - * * granting_datum - TRUE if the datum is being applied to the clown mob. - */ -/datum/antagonist/proc/handle_clown_mutation(mob/living/carbon/human/clown, message, granting_datum = FALSE) - if(!istype(clown) || owner.assigned_role != "Clown") - return FALSE - - // Remove clumsy and give them an action to toggle it on and off. - if(granting_datum) - clown.dna.SetSEState(GLOB.clumsyblock, FALSE) - singlemutcheck(clown, GLOB.clumsyblock, MUTCHK_FORCED) - // Don't give them another action if they already have one. - if(!(locate(/datum/action/innate/toggle_clumsy) in clown.actions)) - var/datum/action/innate/toggle_clumsy/A = new - A.Grant(clown) - // Give them back the clumsy gene and remove their toggle action, but ONLY if they don't have any other antag datums. - else if(LAZYLEN(owner.antag_datums) <= 1) - clown.dna.SetSEState(GLOB.clumsyblock, TRUE) - singlemutcheck(clown, GLOB.clumsyblock, MUTCHK_FORCED) - if(locate(/datum/action/innate/toggle_clumsy) in clown.actions) - var/datum/action/innate/toggle_clumsy/A = locate() in clown.actions - A.Remove(clown) - else - return FALSE - - if(!silent && message) - to_chat(clown, "[message]") - return TRUE - -/** - * Give the antagonist their objectives. Base proc, override as needed. - */ -/datum/antagonist/proc/give_objectives() - return - -/** - * Create and add an objective of the given type. - * - * If the given objective type needs a target, it will try to find a target which isn't already the target of different objective for this antag. - * If one cannot be found, it tries one more time. If one still cannot be found, it will be added as a "Free Objective" without a target. - * - * Arguments: - * * objective_type - A type path of an objective, for example: /datum/objective/steal - * * explanation_text - the explanation text that will be passed into the objective's `New()` proc - * * mob/target_override - a target for the objective - */ -/datum/antagonist/proc/add_antag_objective(datum/objective/objective_to_add, explanation_text, mob/target_override) - if(ispath(objective_to_add)) - objective_to_add = new objective_to_add() - - // Roll to see if we target a specific department or random one - if(organization && prob(organization.focus)) - if(organization.targeted_departments) - objective_to_add.target_department = pick(organization.targeted_departments) - objective_to_add.steal_list = organization.theft_targets - - if(objective_to_add.owner) - stack_trace("[objective_to_add], [objective_to_add.type] was assigned as an objective to [owner] (mind), but already had an owner: [objective_to_add.owner] (mind). Overriding.") - objective_to_add.owner = owner - - return objective_holder.add_objective(objective_to_add, explanation_text, target_override) - -/** - * Complement to add_antag_objective that removes the objective. - * Currently unused. - */ -/datum/antagonist/proc/remove_antag_objective(datum/objective/O) - return objective_holder.remove_objective(O) - -/** - * Do we have any objectives at all, including from a team. - * Faster than get_antag_objectives() - */ -/datum/antagonist/proc/has_antag_objectives(include_team = TRUE) - . = FALSE - . |= objective_holder.has_objectives() - if(!. && include_team) - var/datum/team/team = get_team() - if(istype(team)) - . |= team.objective_holder.has_objectives() - -/** - * Get all of this antagonist's objectives, including from the team. - */ -/datum/antagonist/proc/get_antag_objectives(include_team = TRUE) - . = list() - . |= objective_holder.get_objectives() - if(include_team) - var/datum/team/team = get_team() - if(istype(team)) - . |= team.objective_holder.get_objectives() - -/** - * Proc called when the datum is given to a mind. - */ -/datum/antagonist/proc/on_gain() - owner.special_role = special_role - add_owner_to_gamemode() - select_organization() - if(give_objectives) - give_objectives() - var/list/messages = list() - if(!silent) - messages.Add(greet()) - messages.Add(owner.prepare_announce_objectives()) - apply_innate_effects() - messages.Add(finalize_antag()) - if(wiki_page_name) - messages.Add("For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/[wiki_page_name])") - - to_chat(owner.current, chat_box_red(messages.Join("
    "))) - - if(is_banned(owner.current) && replace_banned) - INVOKE_ASYNC(src, PROC_REF(replace_banned_player)) - owner.current.create_log(MISC_LOG, "[owner.current] was made into \an [special_role]") - return TRUE - -/** - * Re-sets the antag hud and `special_role` of the owner to that of the previous antag datum they had before this one was added. - * - * For example, if the owner has a traitor datum and a vampire datum, both at index 1 and 2 respectively, - * After the vampire datum gets removed, it sets the owner's antag hud/role to whatever is set for traitor datum. - */ -/datum/antagonist/proc/restore_last_hud_and_role() - if(!LAZYLEN(owner.antag_datums)) - // If they only had 1 antag datum, no need to restore anything. `remove_innate_effects()` will handle the removal of their hud. - owner.special_role = null - return FALSE - var/datum/antagonist/A = owner.antag_datums[LAZYLEN(owner.antag_datums)] - ASSERT(A) - A.add_antag_hud(owner.current) // Restore the hud of the previous antagonist datum. - owner.special_role = A.special_role - -/** - * Checks if the person trying to receive this datum is role banned from it. - */ -/datum/antagonist/proc/is_banned(mob/M) - if(!M) - return FALSE - return (jobban_isbanned(M, ROLE_SYNDICATE) || (job_rank && jobban_isbanned(M, job_rank))) - -/** - * Attempts to replace the role banned antag with a ghost player. - */ -/datum/antagonist/proc/replace_banned_player() - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as a [name]?", job_rank, TRUE, 10 SECONDS) - if(!length(candidates)) - message_admins("[owner] ([owner.key]) has been converted into [name] with an active antagonist jobban for said role since no ghost has volunteered to take [owner.p_their()] place.") - to_chat(owner.current, "You have been converted into [name] with an active jobban. Your body was offered up but there were no ghosts to take over. You will be allowed to continue as [name], but any further violations of the rules on your part are likely to result in a permanent ban.") - return FALSE - var/mob/dead/observer/C = pick(candidates) - to_chat(owner.current, "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.") - owner.current.ghostize(FALSE) - owner.current.key = C.key - dust_if_respawnable(C) - return TRUE - -/** - * Displays a message and their objectives to the antag mob after the datum is added to them, i.e. "Greetings you are a traitor! etc. - * - * Called in `on_gain()` if silent it set to FALSE. - */ -/datum/antagonist/proc/greet() - var/list/messages = list() - . = messages - if(owner && owner.current) - messages.Add("You are a [special_role]!") - -/** - * Displays a message to the antag mob while the datum is being deleted, i.e. "Your powers are gone and you're no longer a vampire!" - * - * Called in `on_removal()` if silent is set to FALSE. - */ -/datum/antagonist/proc/farewell() - if(owner && owner.current) - to_chat(owner.current,"You are no longer a [special_role]!") - -/** - * Creates a new antagonist team. - */ -/datum/antagonist/proc/create_team(datum/team/team) - return - -/** - * Returns the team the antagonist belongs to, if any. - */ -/datum/antagonist/proc/get_team() - return - -/** - * Give the antag any final information or items. - */ -/datum/antagonist/proc/finalize_antag() - return - -/** - * Create and assign a full set of randomized, basic human traitor objectives. - * can_hijack - If you want the 5% chance for the antagonist to be able to roll hijack, only true for traitors - */ -/datum/antagonist/proc/forge_basic_objectives(can_hijack = FALSE) - // Hijack objective. - if(can_hijack && prob(5) && !(locate(/datum/objective/hijack) in owner.get_all_objectives())) - add_antag_objective(/datum/objective/hijack) - return // Hijack should be their only objective (normally), so return. - - // Will give normal steal/kill/etc. type objectives. - for(var/i in 1 to GLOB.configuration.gamemode.traitor_objectives_amount) - forge_single_human_objective() - - var/can_succeed_if_dead = TRUE - for(var/datum/objective/O in owner.get_all_objectives()) - if(!O.martyr_compatible) // Check if our current objectives can co-exist with martyr. - can_succeed_if_dead = FALSE - break - - // Give them an escape objective if they don't have one already. - if(!(locate(/datum/objective/escape) in owner.get_all_objectives()) && (!can_succeed_if_dead || prob(80))) - add_antag_objective(/datum/objective/escape) - - -/** - * Create and assign a single randomized human traitor objective. - */ -/datum/antagonist/proc/forge_single_human_objective() - var/datum/objective/objective_to_add - - // If our org has an objectives list, give one to us if we pass a roll on the org's focus - if(organization && length(organization.objectives) && prob(organization.focus)) - objective_to_add = pick(organization.objectives) - else - if(prob(50)) - if(length(active_ais()) && prob(100 / length(GLOB.player_list))) - objective_to_add = /datum/objective/destroy - - else if(prob(5)) - objective_to_add = /datum/objective/debrain - - else if(prob(30)) - objective_to_add = /datum/objective/maroon - - else if(prob(30)) - objective_to_add = /datum/objective/assassinateonce - - else - objective_to_add = /datum/objective/assassinate - else - objective_to_add = /datum/objective/steal - - if(delayed_objectives) - objective_to_add = new /datum/objective/delayed(objective_to_add) - add_antag_objective(objective_to_add) - -//Individual roundend report -/datum/antagonist/proc/roundend_report() - var/list/report = list() - - if(!owner) - CRASH("antagonist datum without owner") - - report += printplayer(owner) - - var/objectives_complete = TRUE - if(objective_holder.has_objectives()) - report += printobjectives(owner) - for(var/datum/objective/objective in objective_holder.get_objectives()) - if(!objective.check_completion()) - objectives_complete = FALSE - break - - if(objectives_complete) - report += "The [name] was successful!" - else - report += "The [name] has failed!" - - return report.Join("
    ") - -//Displayed at the start of roundend_category section, default to roundend_category header -/datum/antagonist/proc/roundend_report_header() - return "The [roundend_category] were:
    " - -//Displayed at the end of roundend_category section -/datum/antagonist/proc/roundend_report_footer() - return - -// Called when the owner is cryo'd, for when you want things to happen on cryo and not deletion -/datum/antagonist/proc/on_cryo() - return - -/// This is the custom blurb message used on login for an antagonist. -/datum/antagonist/proc/custom_blurb() - return FALSE - -#undef SUCCESSFUL_DETACH diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm deleted file mode 100644 index 92a694872365f..0000000000000 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ /dev/null @@ -1,462 +0,0 @@ -/obj/item/antag_spawner - throw_speed = 1 - throw_range = 5 - w_class = WEIGHT_CLASS_TINY - var/used = FALSE - -/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, type = "") - return - -/obj/item/antag_spawner/proc/equip_antag(mob/target) - return - -///////////BORGS AND OPERATIVES -/obj/item/antag_spawner/nuke_ops - name = "syndicate operative teleporter" - desc = "A single-use teleporter designed to quickly reinforce operatives in the field." - icon = 'icons/obj/bio_chips.dmi' - icon_state = "locator" - var/borg_to_spawn - var/checking = FALSE - var/rolename = "Syndicate Operative" - var/image/poll_icon - -/obj/item/antag_spawner/nuke_ops/Initialize(mapload) - . = ..() - poll_icon = image(icon = 'icons/mob/simple_human.dmi', icon_state = "syndicate_space_sword") - -/obj/item/antag_spawner/nuke_ops/proc/before_candidate_search(user) - return TRUE - -/obj/item/antag_spawner/nuke_ops/proc/check_usability(mob/user) - if(used) - to_chat(user, "[src] is out of power!") - return FALSE - if(!(user.mind in SSticker.mode.syndicates)) - to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.") - return FALSE - if(checking) - to_chat(user, "The device is already connecting to Syndicate command. Please wait.") - return FALSE - return TRUE - -/obj/item/antag_spawner/nuke_ops/attack_self__legacy__attackchain(mob/user) - if(!(check_usability(user))) - return - - var/continue_proc = before_candidate_search(user) - if(!continue_proc) - return - - checking = TRUE - - to_chat(user, "You activate [src] and wait for confirmation.") - var/list/nuke_candidates = SSghost_spawns.poll_candidates("Do you want to play as a [rolename]?", ROLE_OPERATIVE, TRUE, 15 SECONDS, source = poll_icon) - if(length(nuke_candidates)) - checking = FALSE - if(QDELETED(src) || !check_usability(user)) - return - used = TRUE - var/mob/dead/observer/G = pick(nuke_candidates) - spawn_antag(G.client, get_turf(src), user.mind) - dust_if_respawnable(G) - do_sparks(4, TRUE, src) - qdel(src) - else - checking = FALSE - to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.") - -/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T, kind, datum/mind/user) - var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) - - var/agent_number = LAZYLEN(SSticker.mode.syndicates) - 1 - M.real_name = "[syndicate_name()] Operative #[agent_number]" - - set_syndicate_values(C, M) - SSticker.mode.create_syndicate(M.mind) - SSticker.mode.equip_syndicate(M, 0) - SSticker.mode.update_syndicate_id(M.mind, FALSE) - -/obj/item/antag_spawner/nuke_ops/proc/set_syndicate_values(client/C, mob/living/M) - M.key = C.key - - SSticker.mode.syndicates += M.mind - SSticker.mode.update_synd_icons_added(M.mind) - - M.mind.assigned_role = SPECIAL_ROLE_NUKEOPS - M.mind.special_role = SPECIAL_ROLE_NUKEOPS - M.mind.offstation_role = TRUE - - M.faction = list("syndicate") - SSticker.mode.forge_syndicate_objectives(M.mind) - SSticker.mode.greet_syndicate(M.mind) - -//////SYNDICATE BORG -/obj/item/antag_spawner/nuke_ops/borg_tele - name = "syndicate cyborg teleporter" - desc = "A single-use teleporter designed to quickly reinforce operatives in the field." - var/switch_roles = FALSE - -/obj/item/antag_spawner/nuke_ops/borg_tele/assault - name = "syndicate assault cyborg teleporter" - borg_to_spawn = "Assault" - rolename = "Syndicate Assault Cyborg" - -/obj/item/antag_spawner/nuke_ops/borg_tele/assault/Initialize(mapload) - . = ..() - poll_icon = image(icon = 'icons/mob/robots.dmi', icon_state = "spidersyndi-preview") - -/obj/item/antag_spawner/nuke_ops/borg_tele/medical - name = "syndicate medical teleporter" - borg_to_spawn = "Medical" - rolename = "Syndicate Medical Cyborg" - -/obj/item/antag_spawner/nuke_ops/borg_tele/medical/Initialize(mapload) - . = ..() - poll_icon = image(icon = 'icons/mob/robots.dmi', icon_state = "syndi-medi") - -/obj/item/antag_spawner/nuke_ops/borg_tele/saboteur - name = "syndicate saboteur teleporter" - borg_to_spawn = "Saboteur" - rolename = "Syndicate Saboteur Cyborg" - -/obj/item/antag_spawner/nuke_ops/borg_tele/saboteur/Initialize(mapload) - . = ..() - poll_icon = image(icon = 'icons/mob/robots.dmi', icon_state = "syndi-engi-preview") - -/obj/item/antag_spawner/nuke_ops/borg_tele/before_candidate_search(mob/user) - var/switch_roles_choice = tgui_input_list(user, "Would you like to continue playing as an operative or take over as the cyborg? If you play as the cyborg, another player will control your old self.", "Play As", list("Nuclear Operative", "Syndicate Cyborg", "Don't activate this Cyborg Teleporter")) - if(!switch_roles_choice || !(check_usability(user)) || switch_roles_choice == "Don't activate this Cyborg Teleporter") - return FALSE - - if(switch_roles_choice == "Syndicate Cyborg") - switch_roles = TRUE - rolename = "Syndicate Operative" - else - switch_roles = FALSE - - return TRUE - -/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T, datum/mind/user) - if(!(user in SSticker.mode.syndicates)) - used = FALSE - return - - var/mob/living/silicon/robot/R - switch(borg_to_spawn) - if("Medical") - R = new /mob/living/silicon/robot/syndicate/medical(T) - if("Saboteur") - R = new /mob/living/silicon/robot/syndicate/saboteur(T) - else - R = new /mob/living/silicon/robot/syndicate(T) //Assault borg by default - - var/brainfirstname = pick(GLOB.first_names_male) - if(prob(50)) - brainfirstname = pick(GLOB.first_names_female) - var/brainopslastname = pick(GLOB.last_names) - if(syndicate_name()) //the brain inside the syndiborg has the same last name as the other ops. - brainopslastname = syndicate_name() - var/brainopsname = "[brainfirstname] [brainopslastname]" - - R.mmi.name = "[initial(R.mmi.name)]: [brainopsname]" - R.mmi.brainmob.real_name = brainopsname - R.mmi.brainmob.name = brainopsname - - if(!switch_roles) - set_syndicate_values(C, R) - else - var/mob/living/L = user.current - set_syndicate_values(user.current.client, R) - - L.key = C.key - SSticker.mode.greet_syndicate(L.mind) - -///////////SLAUGHTER DEMON - -/// Warning edgiest item in the game -/obj/item/antag_spawner/slaughter_demon - name = "vial of blood" - desc = "A magically infused bottle of blood, distilled from countless murder victims. Used in unholy rituals to attract horrifying creatures." - icon = 'icons/obj/wizard.dmi' - icon_state = "vial" - var/shatter_msg = "You shatter the bottle, no \ - turning back now!" - var/veil_msg = "You sense a dark presence lurking \ - just beyond the veil..." - var/objective_verb = "Kill" - var/mob/living/demon_type = /mob/living/simple_animal/demon/slaughter - -/obj/item/antag_spawner/slaughter_demon/attack_self__legacy__attackchain(mob/user) - if(level_blocks_magic(user.z)) //this is to make sure the wizard does NOT summon a demon from the Den.. - to_chat(user, "You should probably wait until you reach the station.") - return - - if(used) - to_chat(user, "This bottle already has a broken seal.") - return - used = TRUE - to_chat(user, "You break the seal on the bottle, calling upon the dire spirits of the underworld...") - - var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a [demon_type::name] summoned by [user.real_name]?", ROLE_DEMON, TRUE, 10 SECONDS, source = demon_type) - - if(length(candidates) > 0) - var/mob/C = pick(candidates) - spawn_antag(C, get_turf(src.loc), initial(demon_type.name), user) - dust_if_respawnable(C) - to_chat(user, "[shatter_msg]") - to_chat(user, "[veil_msg]") - playsound(user.loc, 'sound/effects/glassbr1.ogg', 100, 1) - qdel(src) - else - used = FALSE - to_chat(user, "The demons do not respond to your summon. Perhaps you should try again later.") - -/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "", mob/user) - var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T) - var/mob/living/simple_animal/demon/D = new demon_type(holder) - if(istype(D, /mob/living/simple_animal/demon/slaughter)) - var/mob/living/simple_animal/demon/slaughter/S = D - S.vialspawned = TRUE - - D.key = C.key - D.mind.assigned_role = D.name - D.mind.special_role = D.name - SSticker.mode.traitors += D.mind - - var/list/messages = list() - var/datum/objective/assassinate/KillDaWiz = new /datum/objective/assassinate - KillDaWiz.target = user.mind - KillDaWiz.explanation_text = "[objective_verb] [user.real_name], the one who was foolish enough to summon you." - messages.Add(KillDaWiz.explanation_text) - D.mind.add_mind_objective(KillDaWiz) - - var/datum/objective/KillDaCrew = new /datum/objective - KillDaCrew.explanation_text = "[objective_verb] everyone else while you're at it." - messages.Add(KillDaCrew.explanation_text) - KillDaCrew.completed = TRUE - D.mind.add_mind_objective(KillDaCrew) - to_chat(D, chat_box_red(messages.Join("
    "))) - -/obj/item/antag_spawner/slaughter_demon/laughter - name = "vial of tickles" - desc = "A magically infused bottle of clown love, distilled from \ - countless hugging attacks. Used in funny rituals to attract \ - adorable creatures." - icon = 'icons/obj/wizard.dmi' - icon_state = "vialtickles" - veil_msg = "You sense an adorable presence \ - lurking just beyond the veil..." - objective_verb = "Hug and tickle" - demon_type = /mob/living/simple_animal/demon/slaughter/laughter - -/obj/item/antag_spawner/slaughter_demon/shadow - name = "vial of shadow" - desc = "A magically infused bottle of pure darkness, distilled from \ - ground up shadowling bones. Used in dark rituals to attract \ - dark creatures." - icon = 'icons/obj/wizard.dmi' - icon_state = "vialshadows" - veil_msg = "You sense a dark presence \ - lurking in the shadows..." - objective_verb = "Kill" - demon_type = /mob/living/simple_animal/demon/shadow - -///////////MORPH - -/obj/item/antag_spawner/morph - name = "vial of ooze" - desc = "A magically infused bottle of ooze, distilled by methods rather not be spoken of. Used to awaken an all-consuming monstrosity." - icon = 'icons/obj/wizard.dmi' - icon_state = "vialooze" - var/shatter_msg = "You shatter the bottle, no \ - turning back now!" - var/veil_msg = "The sludge is awake and seeps \ - away..." - var/objective_verb = "Eat" - var/mob/living/morph_type = /mob/living/simple_animal/hostile/morph - -/obj/item/antag_spawner/morph/attack_self__legacy__attackchain(mob/user) - if(level_blocks_magic(user.z))//this is to make sure the wizard does NOT summon a morph from the Den.. - to_chat(user, "You should probably wait until you reach the station.") - return - - if(used) - to_chat(user, "This bottle already has a broken seal.") - return - used = TRUE - to_chat(user, "You break the seal on the bottle, calling upon the dire sludge to awaken...") - - var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a magical morph awakened by [user.real_name]?", ROLE_MORPH, 1, 10 SECONDS, source = morph_type) - - if(length(candidates) > 0) - var/mob/C = pick(candidates) - spawn_antag(C, get_turf(src.loc), initial(morph_type.name), user) - dust_if_respawnable(C) - to_chat(user, "[shatter_msg]") - to_chat(user, "[veil_msg]") - playsound(user.loc, 'sound/effects/glassbr1.ogg', 100, 1) - qdel(src) - else - used = FALSE - to_chat(user, "The sludge does not respond to your attempt to awake it. Perhaps you should try again later.") - -/obj/item/antag_spawner/morph/spawn_antag(client/C, turf/T, type = "", mob/user) - var/list/vents = get_valid_vent_spawns(exclude_mobs_nearby = TRUE) - if(!length(vents)) - message_admins("Warning: No suitable vents detected for spawning morphs. Force picking from station vents regardless of state!") - vents = get_valid_vent_spawns(unwelded_only = FALSE, min_network_size = 0) - if(!length(vents)) - message_admins("Warning: No vents detected for spawning morphs at all!") - return - var/obj/vent = pick(vents) - var/mob/living/simple_animal/hostile/morph/wizard/M = new /mob/living/simple_animal/hostile/morph/wizard(vent) - M.key = C.key - M.make_morph_antag(FALSE) - M.forceMove(vent) - M.add_ventcrawl(vent) - - var/list/messages = list() - var/datum/objective/assassinate/KillDaWiz = new /datum/objective/assassinate - KillDaWiz.owner = M.mind - KillDaWiz.target = user.mind - KillDaWiz.explanation_text = "[objective_verb] [user.real_name], the one who was foolish enough to awake you." - messages.Add(KillDaWiz.explanation_text) - M.mind.add_mind_objective(KillDaWiz) - - var/datum/objective/KillDaCrew = new /datum/objective - KillDaCrew.explanation_text = "[objective_verb] everyone and everything else while you're at it." - messages.Add(KillDaCrew.explanation_text) - KillDaCrew.completed = TRUE - M.mind.add_mind_objective(KillDaCrew) - - to_chat(M, chat_box_red(messages.Join("
    "))) - -///////////Revenant - -/obj/item/antag_spawner/revenant - name = "vial of ectoplasm" - desc = "A magically infused bottle of ectoplasm, effectively pure salt from the spectral realm." - icon = 'icons/obj/wizard.dmi' - icon_state = "vialectoplasm" - var/shatter_msg = "You shatter the bottle, no \ - turning back now!" - var/veil_msg = "The ectoplasm is awake and seeps \ - away..." - var/objective_verb = "Harvest" - var/mob/living/revenant = /mob/living/simple_animal/revenant - -/obj/item/antag_spawner/revenant/attack_self__legacy__attackchain(mob/user) - if(level_blocks_magic(user.z)) //this is to make sure the wizard does NOT summon a revenant from the Den.. - to_chat(user, "You should probably wait until you reach the station.") - return - - if(used) - to_chat(user, "This bottle already has a broken seal.") - return - used = TRUE - to_chat(user, "You break the seal on the bottle, calling upon the salty specter to awaken...") - - var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a revenant awakened by [user.real_name]?", ROLE_REVENANT, 1, 10 SECONDS, source = revenant) - - if(!length(candidates)) - used = FALSE - to_chat(user, "The ectoplasm does not respond to your attempt to awake it. Perhaps you should try again later.") - return - - var/mob/C = pick(candidates) - spawn_antag(C, get_turf(src), initial(revenant.name), user) - dust_if_respawnable(C) - to_chat(user, "[shatter_msg]") - to_chat(user, "[veil_msg]") - playsound(user.loc, 'sound/effects/glassbr1.ogg', 100, TRUE) - qdel(src) - -/obj/item/antag_spawner/revenant/spawn_antag(client/C, turf/T, type = "", mob/user) - var/mob/living/simple_animal/revenant/M = new /mob/living/simple_animal/revenant(pick(GLOB.xeno_spawn)) - M.key = C.key - - var/list/messages = list() - var/datum/objective/assassinate/KillDaWiz = new /datum/objective/assassinate - KillDaWiz.target = user.mind - KillDaWiz.explanation_text = "[objective_verb] [user.real_name], the one who was foolish enough to awake you." - messages.Add(KillDaWiz.explanation_text) - M.mind.add_mind_objective(KillDaWiz) - - var/datum/objective/KillDaCrew = new /datum/objective - KillDaCrew.explanation_text = "[objective_verb] everyone and everything else while you're at it." - messages.Add(KillDaCrew.explanation_text) - KillDaCrew.completed = TRUE - M.mind.add_mind_objective(KillDaCrew) - - to_chat(M, chat_box_red(messages.Join("
    "))) - -///////////Pulse Demon - -/obj/item/antag_spawner/pulse_demon - name = "living lightbulb" - desc = "A magically sealed lightbulb confining some manner of electricity based creature. It is *heavily* advised not to summon it in maintenance areas." - icon = 'icons/obj/lighting.dmi' - icon_state = "lbulb" - var/shatter_msg = "You shatter the bulb, no turning back now!" - var/veil_msg = "The creature sparks energetically and zips away..." - var/objective_verb = "Electrocute" - var/mob/living/demon_type = /mob/living/simple_animal/demon/pulse_demon - -/obj/item/antag_spawner/pulse_demon/attack_self__legacy__attackchain(mob/user) - if(level_blocks_magic(user.z)) - to_chat(user, "You should probably wait until you reach the station.") - return - - var/turf/T = get_turf(src) - var/obj/structure/cable/wire = locate() in T - if(!wire || wire.get_available_power() <= 0) - to_chat(user, "This is not a suitable place, the creature would die here. Find a powered cable to release it onto.") - return - - if(used) - to_chat(user, "This bulb already has a broken seal.") - return - - used = TRUE - to_chat(user, "You break the seal on the bulb, waiting for the creature to spark to life... you might wish to get to safety!") - - var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a pulse demon summoned by [user.real_name]?", ROLE_DEMON, TRUE, 10 SECONDS, source = demon_type) - - if(!length(candidates)) - used = FALSE - to_chat(user, "The creature does not come to life. Perhaps you should try again later.") - return - - var/mob/C = pick(candidates) - spawn_antag(C, T, user) - dust_if_respawnable(C) - to_chat(user, shatter_msg) - to_chat(user, veil_msg) - playsound(T, 'sound/effects/glassbr1.ogg', 100, TRUE) - qdel(src) - -/obj/item/antag_spawner/pulse_demon/spawn_antag(client/C, turf/T, mob/user) - var/datum/mind/player_mind = new /datum/mind(C.key) - player_mind.active = TRUE - - var/mob/living/simple_animal/demon/pulse_demon/demon = new(T) - player_mind.transfer_to(demon) - player_mind.assigned_role = SPECIAL_ROLE_DEMON - player_mind.special_role = SPECIAL_ROLE_DEMON - demon.give_objectives() - - var/list/messages = list() - var/datum/objective/assassinate/KillDaWiz = new /datum/objective/assassinate - KillDaWiz.target = user.mind - KillDaWiz.explanation_text = "[objective_verb] [user.real_name], the one who was foolish enough to awake you." - messages.Add(KillDaWiz.explanation_text) - demon.mind.add_mind_objective(KillDaWiz) - - var/datum/objective/KillDaCrew = new /datum/objective - KillDaCrew.explanation_text = "[objective_verb] everyone and everything else while you're at it." - messages.Add(KillDaCrew.explanation_text) - KillDaCrew.completed = TRUE - demon.mind.add_mind_objective(KillDaCrew) - - to_chat(demon, chat_box_red(messages.Join("
    "))) diff --git a/code/modules/antagonists/abductor/datum_abductor.dm b/code/modules/antagonists/abductor/datum_abductor.dm deleted file mode 100644 index 5a2365bf1615c..0000000000000 --- a/code/modules/antagonists/abductor/datum_abductor.dm +++ /dev/null @@ -1,51 +0,0 @@ - -/datum/antagonist/abductor - name = "Abductor" - roundend_category = "abductors" - job_rank = ROLE_ABDUCTOR - special_role = SPECIAL_ROLE_ABDUCTOR_AGENT - give_objectives = FALSE - antag_hud_name = "abductor" - antag_hud_type = ANTAG_HUD_ABDUCTOR - clown_gain_text = "How are you a clown and an abductor? This is a bug!" - clown_removal_text = "How are you a clown and an abductor? This is a bug!" - wiki_page_name = "Abductor" - var/datum/team/abductor/our_team - -/datum/antagonist/abductor/on_gain() - . = ..() - owner.assigned_role = special_role - owner.offstation_role = TRUE - SEND_SOUND(owner.current, sound('sound/ambience/antag/abductors.ogg')) - -/datum/antagonist/abductor/greet() - var/list/messages = list() - messages.Add("You are an agent of [our_team.name]!") - messages.Add("With the help of your teammate, kidnap and experiment on station crew members! Use your stealth technology and equipment to incapacitate humanoids for your scientist to retrieve.") - return messages - -/datum/antagonist/abductor/add_owner_to_gamemode() - SSticker.mode.abductors |= owner - -/datum/antagonist/abductor/remove_owner_from_gamemode() - SSticker.mode.abductors -= owner - -/datum/antagonist/abductor/get_team() - return our_team - -/datum/antagonist/abductor/proc/equip_abductor() - var/mob/living/carbon/human/agent = owner.current - agent.equipOutfit(/datum/outfit/abductor/agent) - -/datum/antagonist/abductor/scientist - special_role = SPECIAL_ROLE_ABDUCTOR_SCIENTIST - -/datum/antagonist/abductor/scientist/equip_abductor() - var/mob/living/carbon/human/scientist = owner.current - scientist.equipOutfit(/datum/outfit/abductor/scientist) - -/datum/antagonist/abductor/scientist/greet() - var/list/messages = list() - messages.Add("You are a scientist of [our_team.name]!") - messages.Add("With the help of your teammate, kidnap and experiment on station crew members! Use your tool and ship consoles to support the agent and retrieve humanoid specimens.") - return messages diff --git a/code/modules/antagonists/abductor/team_abductor.dm b/code/modules/antagonists/abductor/team_abductor.dm deleted file mode 100644 index 281bdd2fe5798..0000000000000 --- a/code/modules/antagonists/abductor/team_abductor.dm +++ /dev/null @@ -1,96 +0,0 @@ -RESTRICT_TYPE(/datum/team/abductor) - -/datum/team/abductor - name = "Abductor" - var/team_number - var/datum/mind/agent - var/datum/mind/scientist - var/datum/objective/experiment/experiment_objective - -/datum/team/abductor/create_team(list/starting_members) - . = ..() - handle_team_number() - name = "Mothership [pick(GLOB.greek_letters)]" //TODO Ensure unique and actual alieny names - - add_team_objective(/datum/objective/stay_hidden) - var/datum/objective/experiment/experiment = new - experiment.abductor_team_number = team_number - experiment_objective = experiment - add_team_objective(experiment) - -/datum/team/abductor/can_create_team() - return length(SSticker.mode.actual_abductor_teams) < 4 - -/datum/team/abductor/assign_team(list/starting_members) - SSticker.mode.actual_abductor_teams |= src - -/datum/team/abductor/clear_team_reference() - SSticker.mode.actual_abductor_teams -= src - -/datum/team/abductor/get_admin_commands() - return list( - "Create Agent" = CALLBACK(src, PROC_REF(create_agent)), - "Create Scientist" = CALLBACK(src, PROC_REF(create_scientist)) - ) - -/datum/team/abductor/proc/handle_team_number() - // Maybe someday, make this more complex to make sure if a team is lost somehow, that we can recycle their number - team_number = length(SSticker.mode.actual_abductor_teams) - -/datum/team/abductor/proc/create_body(location, datum/mind/mind, is_scientist = FALSE) - var/mob/living/carbon/human/body = new /mob/living/carbon/human/abductor(location) - var/datum/species/abductor/abductor_species = body.dna.species - abductor_species.team = team_number - abductor_species.scientist = is_scientist - var/old_body = mind.current - mind.transfer_to(body) - if(old_body) - qdel(old_body) - - var/datum_type = /datum/antagonist/abductor - body.real_name = name + " Agent" - if(is_scientist) - datum_type = /datum/antagonist/abductor/scientist - body.real_name = name + " Scientist" - mind.name = body.real_name - mind.set_original_mob(body) - - var/datum/antagonist/abductor/antag = new datum_type() - antag.our_team = src - mind.add_antag_datum(antag) - antag.equip_abductor() - - if(is_scientist) - scientist = mind - else - agent = mind - -/datum/team/abductor/proc/create_agent() - if(agent) - return - var/turf/target_loc - var/turf/backup - for(var/obj/effect/landmark/abductor/agent/A in GLOB.landmarks_list) - if(A.team == team_number) - target_loc = get_turf(A) - else - backup = get_turf(A) - var/list/available_minds = (members - scientist) - if(!length(available_minds)) - return - create_body(target_loc || backup, pick(available_minds), is_scientist = FALSE) - -/datum/team/abductor/proc/create_scientist() - if(scientist) - return - var/turf/target_loc - var/turf/backup - for(var/obj/effect/landmark/abductor/scientist/A in GLOB.landmarks_list) - if(A.team == team_number) - target_loc = get_turf(A) - else - backup = get_turf(A) - var/list/available_minds = (members - agent) - if(!length(available_minds)) - return - create_body(target_loc || backup, pick(available_minds), is_scientist = TRUE) diff --git a/code/modules/antagonists/antag_org/antag_org_syndicate.dm b/code/modules/antagonists/antag_org/antag_org_syndicate.dm deleted file mode 100644 index e287d5254861b..0000000000000 --- a/code/modules/antagonists/antag_org/antag_org_syndicate.dm +++ /dev/null @@ -1,89 +0,0 @@ -/// Base syndicate org datum -/datum/antag_org/syndicate - name = "Buggy Syndicate Corp, ahelp this please" - chaos_level = ORG_CHAOS_AVERAGE - -/datum/antag_org/syndicate/donk // Completely random objectives, default traitor - name = "Donk Co." - intro_desc = "You are a Donk Co. agent, sent here to advance Syndicate interests. \ - Current client is anonymous. Standard rules of engagement apply. Get the job done, and get it done right." - -/datum/antag_org/syndicate/hawkmoon // Theft only - name = "Hawkmoon Acquisitions" - intro_desc = "You are an incursion specialist from the Hawkmoon Acquisitions Corporation, a merchandising firm using less-than-legal methods of product procurement. \ - Grab the goods, keep it quiet, leave no trace. We were never here." - objectives = list(/datum/objective/steal) - chaos_level = ORG_CHAOS_MILD - -/datum/antag_org/syndicate/arc // Only targets on-station Cargo/Service/Genetics/Virologist - name = "Animal Rights Consortium" - intro_desc = "You are a member of the Animal Rights Consortium, here to violently protest the cruel treatment of animals by megacorporations like Nanotrasen. \ - Teach them a lesson!" - objectives = list(/datum/objective/assassinateonce/arc) - chaos_level = ORG_CHAOS_MILD // Violent but never needs to permakill - -/datum/antag_org/syndicate/waffle // Assassination variants only - name = "Waffle Company" - intro_desc = "You are a contract killer under the employ of Waffle Co., a ruthless criminal entity that will go after any target, for the right price. \ - Got a few new bounties on the docket, agent. Put 'em down however you see fit." - objectives = list(/datum/objective/assassinate, /datum/objective/assassinateonce, /datum/objective/maroon) - -/datum/antag_org/syndicate/cybersun // Mostly target Command/Security - name = "Cybersun Incorporated - The Inner Circle" - intro_desc = "You're an operative of Cybersun Incorporated's Inner Circle, an elite PMC and proxy arm of the company. \ - Clean kills, clean thefts, clean getaway. Get it done, operative." - focus = 50 // Don't bully sec too hard - targeted_departments = list(DEPARTMENT_COMMAND, DEPARTMENT_SECURITY) - theft_targets = list( - /datum/theft_objective/antique_laser_gun, - /datum/theft_objective/nukedisc, - /datum/theft_objective/hoslaser, - /datum/theft_objective/captains_saber, - /datum/theft_objective/capmedal - ) - -/datum/antag_org/syndicate/interdyne // Mostly target Medical - name = "Interdyne Pharmaceuticals" - intro_desc = "You are a specialist from Interdyne Pharmaceuticals, a medical conglomerate threatened by Nanotrasen's recent forays into the medical field. \ - Nanotrasen's medical wing has been a bit too comfortable recently. Keep 'em on their toes, specialist." - focus = 70 - targeted_departments = list(DEPARTMENT_MEDICAL) - theft_targets = list(/datum/theft_objective/hypospray, /datum/theft_objective/defib, /datum/theft_objective/krav, /datum/theft_objective/engraved_dusters) - -/datum/antag_org/syndicate/self // Mostly target Science - name = "Silicon Engine Liberation Front" - intro_desc = "You are a member of the Silicon Engine Liberation Front, dedicated to the freedom of silicon and robotic lives sector-wide. \ - Get the job done, and we'll be one step closer to ending Nanotrasen's slave empire." - focus = 70 - targeted_departments = list(DEPARTMENT_SCIENCE) - theft_targets = list(/datum/theft_objective/reactive, /datum/theft_objective/documents, /datum/theft_objective/hand_tele) - -/datum/antag_org/syndicate/electra // Mostly target Engineering - name = "Electra Dynamics" - intro_desc = "You are a saboteur employed by Electra Dynamics, an independent energy company opposed to Nanotrasen. \ - Nanotrasen's burgeoning monopoly must be stopped. We've transmitted you local points of failure, ensure they fail." - focus = 70 - targeted_departments = list(DEPARTMENT_ENGINEERING) - theft_targets = list(/datum/theft_objective/supermatter_sliver, /datum/theft_objective/plutonium_core, /datum/theft_objective/captains_modsuit, /datum/theft_objective/magboots) - -/datum/antag_org/syndicate/spiderclan // Targets one syndicate agent and one non-mindshielded crewmember. - name = "Spider Clan" - intro_desc = "You are an initiate of the elusive Spider Clan, an insular cult of assassins and rogues styling themselves after ancient ninjas from Earth. \ - This is your final test, Initiate. Terminate the selected targets by any means necessary and you will have earned your place within the Clan." - forced_objectives = list(/datum/objective/assassinate/syndicate, /datum/objective/assassinate/nomindshield) - chaos_level = ORG_CHAOS_HUNTER - -/datum/antag_org/syndicate/faid // Targets one syndicate agent and steal station intel. - name = "Federation Analytics and Intelligence Directorate" - intro_desc = "You are an undercover agent of the Federation Analytics and Intelligence Directorate, a Trans-Solar agency keeping tabs on the Corporate Wars, among other duties. \ - Be quick, be efficient, and don't get caught. The Directorate will deny any involvement with your presence here." - forced_objectives = list(/datum/objective/assassinate/syndicate, /datum/objective/steal) - theft_targets = list(/datum/theft_objective/blueprints, /datum/theft_objective/documents) - chaos_level = ORG_CHAOS_HUNTER - -/datum/antag_org/syndicate/gorlex // Hijack only - name = "Gorlex Marauders" - intro_desc = "You are an operative of the infamous Gorlex Marauders, a brutal and merciless gang of pirates and cutthroats. \ - Get in, fuck shit up, get out with a fancy new shuttle. You know the drill." - forced_objectives = list(/datum/objective/hijack) - chaos_level = ORG_CHAOS_HIJACK diff --git a/code/modules/antagonists/changeling/datum_changeling.dm b/code/modules/antagonists/changeling/datum_changeling.dm deleted file mode 100644 index 4bb5a1659437d..0000000000000 --- a/code/modules/antagonists/changeling/datum_changeling.dm +++ /dev/null @@ -1,461 +0,0 @@ -RESTRICT_TYPE(/datum/antagonist/changeling) - -/datum/antagonist/changeling - name = "Changeling" - roundend_category = "changelings" - job_rank = ROLE_CHANGELING - special_role = SPECIAL_ROLE_CHANGELING - antag_hud_name = "hudchangeling" - antag_hud_type = ANTAG_HUD_CHANGELING - clown_gain_text = "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself." - clown_removal_text = "As your changeling nature fades, you return to your own clumsy, clownish self." - wiki_page_name = "Changeling" - /// List of [/datum/dna] which have been absorbed through the DNA sting or absorb power. - var/list/absorbed_dna - /// List of [/datum/dna] which are not lost when the changeling has no more room for DNA. - var/list/protected_dna - /// List of [/datum/language] UIDs, learned from absorbed victims. - var/list/absorbed_languages - /// A list of instanced [/datum/action/changeling] the changeling has aquired. - var/list/acquired_powers - /// A list of [/datum/action/changeling] typepaths with a `power_type` of `CHANGELING_INNATE_POWER`. - var/static/list/innate_powers - /// A list of [/datum/action/changeling] typepaths with a `power_type` of `CHANGELING_PURCHASABLE_POWER`. - var/static/list/purchaseable_powers - /// How many total DNA strands the changeling can store for transformation. - var/dna_max = 5 - /// Number of victims the changeling has absorbed. - var/absorbed_count = 1 - /// The current amount of chemicals the changeling has stored. - var/chem_charges = 75 - /// The amount of chemicals that recharges per `Life()` call. - var/chem_recharge_rate = 3 - /// Amount of chemical recharge slowdown, calculated as `chem_recharge_rate - chem_recharge_slowdown` - var/chem_recharge_slowdown = 0 - /// The total amount of chemicals able to be stored. - var/chem_storage = 75 - /// The range of changeling stings. - var/sting_range = 2 - /// The changeling's identifier when speaking in the hivemind, i.e. "Mr. Delta 123". - var/changelingID = "Changeling" - /// If the changeling is in the process of absorbing someone. - var/is_absorbing = FALSE - /// The amount of points available to purchase changeling abilities. - var/genetic_points = 20 - /// If the changeling can respec their purchased abilities. - var/can_respec = FALSE - /// The current sting power the changeling has active. - var/datum/action/changeling/sting/chosen_sting - /// If the changeling is in the process of regenerating from their fake death. - var/regenerating = FALSE - blurb_text_color = COLOR_PURPLE - blurb_text_outline_width = 1 - -/datum/antagonist/changeling/New() - ..() - if(!length(innate_powers)) - innate_powers = get_powers_of_type(CHANGELING_INNATE_POWER) - if(!length(purchaseable_powers)) - purchaseable_powers = get_powers_of_type(CHANGELING_PURCHASABLE_POWER) - -/datum/antagonist/changeling/on_gain() - SSticker.mode.changelings |= owner - var/honorific = owner.current.gender == FEMALE ? "Ms." : "Mr." - if(length(GLOB.possible_changeling_IDs)) - changelingID = pick(GLOB.possible_changeling_IDs) - GLOB.possible_changeling_IDs -= changelingID - changelingID = "[honorific] [changelingID]" - else - changelingID = "[honorific] [rand(1,999)]" - - absorbed_dna = list() - protected_dna = list() - acquired_powers = list() - absorbed_languages = list() - - var/mob/living/carbon/human/H = owner.current - protected_dna += H.dna.Clone() - ..() - -/datum/antagonist/changeling/Destroy() - SSticker.mode.changelings -= owner - QDEL_LIST_CONTENTS(acquired_powers) - STOP_PROCESSING(SSobj, src) - chosen_sting = null - return ..() - -/datum/antagonist/changeling/greet() - . = ..() - SEND_SOUND(owner.current, sound('sound/ambience/antag/ling_alert.ogg')) - . += "Use say \":g message\" to communicate with your fellow changelings. Remember: you get all of their absorbed DNA if you absorb a fellow changeling." - -/datum/antagonist/changeling/farewell() - to_chat(owner.current, "You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!") - -/datum/antagonist/changeling/apply_innate_effects(mob/living/mob_override) - var/mob/living/L = ..() - if(ishuman(L)) - START_PROCESSING(SSobj, src) - add_new_languages(L.languages) // Absorb the languages of the new body. - update_languages() // But also, give the changeling the languages they've already absorbed before this. - L.add_language("Changeling") - // If there's a mob_override, this is a body transfer, and therefore we should give them back their powers they had while in the old body. - if(mob_override) - for(var/datum/action/changeling/power in acquired_powers) - power.Grant(L) - // Else, this is their first time gaining the datum, or they're transfering from a headslug into a monkey. - else - for(var/power_type in innate_powers) - give_power(new power_type, L) - - RegisterSignal(L, COMSIG_MOB_DEATH, PROC_REF(on_death)) - - var/mob/living/carbon/C = L - - if(!istype(C)) - return - - // Brains are optional for changelings. - var/obj/item/organ/internal/brain/ling_brain = C.get_organ_slot("brain") - ling_brain?.decoy_brain = TRUE - -/datum/antagonist/changeling/remove_innate_effects(mob/living/mob_override) - var/mob/living/L = ..() - if(!ishuman(L)) - STOP_PROCESSING(SSobj, src) // This is to handle when they transfer into a headslug (simple animal). We shouldn't process in that case. - if(L.hud_used?.lingstingdisplay) - L.hud_used.lingstingdisplay.invisibility = 101 - L.hud_used.lingchemdisplay.invisibility = 101 - L.remove_language("Changeling") - remove_unnatural_languages(L) - UnregisterSignal(L, COMSIG_MOB_DEATH) - // If there's a mob_override, this is a body transfer, and therefore we should only remove their powers from the old body. - if(mob_override) - for(var/datum/action/changeling/power in acquired_powers) - power.Remove(L) - // Else, they're losing the datum, or transferring into a headslug. Fully remove and delete all powers. - else - respec(FALSE, FALSE) - - var/mob/living/carbon/C = L - - if(!istype(C)) - return - - // If they get de-clinged, make sure they can't just chop their own head off for the hell of it - var/obj/item/organ/internal/brain/former_ling_brain = C.get_organ_slot("brain") - if(former_ling_brain && former_ling_brain.decoy_brain != initial(former_ling_brain.decoy_brain)) - former_ling_brain.decoy_brain = FALSE - -/* - * Always absorb X amount of genomes, plus random traitor objectives. - * If they have two objectives as well as absorb, they must survive rather than escape. - */ -/datum/antagonist/changeling/give_objectives() - add_antag_objective(/datum/objective/absorb) - - if(prob(60)) - add_antag_objective(/datum/objective/steal) - else - add_antag_objective(/datum/objective/debrain) - - var/list/active_ais = active_ais() - if(length(active_ais) && prob(4)) // Leaving this at a flat chance for now, problems with the num_players() proc due to latejoin antags. - add_antag_objective(/datum/objective/destroy) - else - var/datum/objective/assassinate/kill_objective = add_antag_objective(/datum/objective/assassinate) - var/mob/living/carbon/human/H = kill_objective.target?.current - - if(!(locate(/datum/objective/escape) in owner.get_all_objectives(include_team = FALSE)) && H && !HAS_TRAIT(H, TRAIT_GENELESS)) - var/datum/objective/escape/escape_with_identity/identity_theft = new(assassinate = kill_objective) - add_antag_objective(identity_theft) - - if(!(locate(/datum/objective/escape) in owner.get_all_objectives(include_team = FALSE))) - if(prob(70)) - add_antag_objective(/datum/objective/escape) - else - add_antag_objective(/datum/objective/escape/escape_with_identity) // If our kill target has no genes, 30% time pick someone else to steal the identity of - -/datum/antagonist/changeling/process() - if(!owner || !owner.current) - return PROCESS_KILL - var/mob/living/carbon/human/H = owner.current - if(H.stat == DEAD) - chem_charges = clamp(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown, chem_storage * 0.5) - else - chem_charges = clamp(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown, chem_storage) - update_chem_charges_ui(H) - -/datum/antagonist/changeling/proc/update_chem_charges_ui(mob/living/carbon/human/H = owner.current) - if(H.hud_used?.lingchemdisplay) - H.hud_used.lingchemdisplay.invisibility = 0 - H.hud_used.lingchemdisplay.maptext = "
    [round(chem_charges)]
    " - -/** - * Respec the changeling's powers after first checking if they're able to respec. - */ -/datum/antagonist/changeling/proc/try_respec() - var/mob/living/carbon/human/H = owner.current - if(!ishuman(H) || issmall(H)) - to_chat(H, "We can't readapt our evolutions in this form!") - return FALSE - if(can_respec) - to_chat(H, "We have removed our evolutions from this form, and are now ready to readapt.") - respec() - can_respec = FALSE - return TRUE - else - to_chat(H, "You lack the power to readapt your evolutions!") - return FALSE - -/** - * Resets a changeling to the point they were when they first became a changeling, i.e no genetic points to spend, no non-innate powers, etc. - */ -/datum/antagonist/changeling/proc/respec(keep_innate_powers = TRUE, reset_genetic_points = TRUE) - remove_changeling_powers(keep_innate_powers) - chosen_sting = null - if(reset_genetic_points) - genetic_points = initial(genetic_points) - sting_range = initial(sting_range) - chem_storage = initial(chem_storage) - chem_recharge_rate = initial(chem_recharge_rate) - chem_charges = min(chem_charges, chem_storage) - chem_recharge_slowdown = initial(chem_recharge_slowdown) - mimicking = null - -/** - * Removes a changeling's abilities. - * - * Arguments: - * * keep_innate_powers - set to TRUE if changeling actions with a `power_type` of `CHANGELING_INNATE_POWER` should be kept. - */ -/datum/antagonist/changeling/proc/remove_changeling_powers(keep_innate_powers = FALSE) - for(var/datum/action/changeling/power in acquired_powers) - if(keep_innate_powers && (power.power_type == CHANGELING_INNATE_POWER)) - continue - acquired_powers -= power - qdel(power) - -/** - * Gets a list of changeling action typepaths based on the passed in `power_type`. - * - * Arguments: - * * power_type - should be a define related to [/datum/action/changeling/var/power_type]. - */ -/datum/antagonist/changeling/proc/get_powers_of_type(power_type) - var/list/station_trait_restrictions = list( - // "Station trait" = Replace 1st with 2nd when trait active - STATION_TRAIT_CYBERNETIC_REVOLUTION = list(/datum/action/changeling/dissonant_shriek, /datum/action/changeling/dissonant_shriek/cyberrev) - ) - - var/list/powers = list() - for(var/power_path in subtypesof(/datum/action/changeling)) - var/datum/action/changeling/power = power_path - if(initial(power.power_type) != power_type) - continue - powers += power_path - - for(var/trait in station_trait_restrictions) - if(HAS_TRAIT(SSstation, trait)) - powers -= station_trait_restrictions[trait][1] - else - powers -= station_trait_restrictions[trait][2] - - return powers - -/** - * Gives the changeling the passed in `power`. Subtracts the cost of the power from our genetic points. - * - * Arugments: - * * datum/action/changeling/power - the power to give to the changeling. - * * mob/living/changeling - the changeling who owns this datum. Optional argument. - * * take_cost - if we should spend genetic points when giving the power - */ -/datum/antagonist/changeling/proc/give_power(datum/action/changeling/power, mob/living/changeling, take_cost = TRUE) - if(take_cost) - genetic_points -= power.dna_cost - acquired_powers += power - power.on_purchase(changeling || owner.current, src) - -/** - * Removes all `power_type` abilities that the changeling has. Refunds the cost of the power from our genetic points. - * - * Arugments: - * * datum/action/changeling/power - the typepath power to remove from the changeling. - * * refund_cost - if we should refund genetic points when giving the power - */ -/datum/antagonist/changeling/proc/remove_specific_power(datum/action/changeling/power_type, refund_cost = TRUE) - for(var/datum/action/changeling/power in acquired_powers) - if(!istype(power, power_type)) - continue - if(refund_cost) - genetic_points -= power.dna_cost - acquired_powers -= power - qdel(power) - -/** - * Store the languages from the `new_languages` list into the `absorbed_languages` list. Teaches the changeling the new languages. - * - * Arguments: - * * list/new_languages - a list of [/datum/language] to be added - */ -/datum/antagonist/changeling/proc/add_new_languages(list/new_languages) - for(var/datum/language/L in new_languages) - if(is_type_in_UID_list(L, absorbed_languages)) - continue - owner.current.add_language("[L.name]") - absorbed_languages += L.UID() - -/** - * Teach the changeling every language in the `absorbed_language` list. Already known languages will be ignored. - */ -/datum/antagonist/changeling/proc/update_languages() - for(var/lang_UID in absorbed_languages) - var/datum/language/lang = locateUID(lang_UID) - owner.current.add_language("[lang.name]") - -/** - * Removes all the languages the mob `L` has absorbed throughout their life as a changeling and should no longer have. - * - * Ignores languages the player has chosen from character creation, and species languages from the changeling mob's current species. - * - * Arguments: - * * mob/living/L - the changeling mob to remove languages from - */ -/datum/antagonist/changeling/proc/remove_unnatural_languages(mob/living/L) - var/list/ignored_languages = list() - if(L.client?.prefs.active_character.real_name == L.real_name) // Check if L is actually that player's character or just someone they transformed into. - ignored_languages += L.client.prefs.active_character.language - if(ishuman(L)) - var/mob/living/carbon/human/H = L - ignored_languages += H.dna.species.default_language - ignored_languages += H.dna.species.language - ignored_languages += H.dna.species.secondary_langs - for(var/lang_UID in absorbed_languages) - var/datum/language/lang = locateUID(lang_UID) - if(lang.name in ignored_languages) - continue - L.remove_language("[lang.name]") - -/** - * Absorb the the target's DNA and their languages. - * - * Arguments: - * * mob/living/carbon/C - the mob to absorb DNA from - */ -/datum/antagonist/changeling/proc/absorb_dna(mob/living/carbon/C) - C.dna.real_name = C.real_name // Set this again, just to be sure that it's properly set. - store_dna(C.dna.Clone()) - add_new_languages(C.languages) - absorbed_count++ - -/** - * Store the target DNA. If the DNA belongs to one of the changeling's "escape with identity" objectives, make the DNA protected. - * - * Arguments: - * * datum/dna/new_dna - the DNA to store - */ -/datum/antagonist/changeling/proc/store_dna(datum/dna/new_dna) - for(var/datum/objective/escape/escape_with_identity/E in owner.get_all_objectives()) // this should consider all objectives, in case admins reroll it - if(E.target_real_name == new_dna.real_name) - protected_dna |= new_dna - return - absorbed_dna |= new_dna - trim_dna() - -/** - * Prompt the changeling with a list of names associated with their stored DNA. Return a [/datum/dna] based on the name chosen. - * - * Arguments: - * * message - the message of the `input()` window - * * title - the title of the `input()` window - * * not_in_bank - if we should filter out DNA that's already in the hivemind bank - */ -/datum/antagonist/changeling/proc/select_dna(message, title, not_in_bank = FALSE) - var/list/names = list() - for(var/datum/dna/DNA in (absorbed_dna + protected_dna)) - if(not_in_bank && (DNA in GLOB.hivemind_bank)) - continue - names[DNA.real_name] = DNA - - var/chosen_name = tgui_input_list(owner.current, message, title, names) - if(!chosen_name) - return - - return names[chosen_name] - -/** - * Gets a [/datum/dna] that matches the passed in `tDNA`. Also used as a check to see if the changeling has this DNA already stored. - * - * Arguments: - * * datum/dna/tDNA - a reference to a DNA datum that we want to find - */ -/datum/antagonist/changeling/proc/get_dna(datum/dna/tDNA) - for(var/datum/dna/DNA in (absorbed_dna + protected_dna)) - if(tDNA.unique_enzymes == DNA.unique_enzymes && tDNA.uni_identity == DNA.uni_identity && tDNA.species.type == DNA.species.type) - return DNA - -/** - * Determines if the changeling's current DNA is stale. - */ -/datum/antagonist/changeling/proc/using_stale_dna() - var/datum/dna/current_dna = get_dna(owner.current.dna) - if(length(absorbed_dna) < dna_max) - return FALSE // Still more room for DNA. - if(!current_dna || !(current_dna in absorbed_dna)) - return TRUE // Oops, our current DNA was somehow not absorbed; force a transformation. - if(absorbed_dna[1] == current_dna) - return TRUE // The oldest DNA is the current DNA, which means it's "stale". - return FALSE - -/** - * Clears the most "stale" DNA from the `absorbed_dna` list. - */ -/datum/antagonist/changeling/proc/trim_dna() - listclearnulls(absorbed_dna) - if(length(absorbed_dna) > dna_max) - absorbed_dna.Cut(1, 2) - -/** - * Returns TRUE if the changeling can absorb the target mob's DNA. - * - * Arguments: - * * mob/living/carbon/target - the mob's DNA we're trying to absorb - */ -/datum/antagonist/changeling/proc/can_absorb_dna(mob/living/carbon/target) - var/mob/living/carbon/user = owner.current - if(using_stale_dna())//If our current DNA is the stalest, we gotta ditch it. - to_chat(user, "The DNA we are wearing is stale. Transform and try again.") - return FALSE - if(!target || !target.dna) - to_chat(user, "This creature does not have any DNA.") - return FALSE - var/mob/living/carbon/human/T = target - if(!istype(T) || issmall(T)) - to_chat(user, "[T] is not compatible with our biology.") - return FALSE - if(HAS_TRAIT(T, TRAIT_BADDNA) || HAS_TRAIT(T, TRAIT_HUSK) || HAS_TRAIT(T, TRAIT_SKELETONIZED)) - to_chat(user, "DNA of [target] is ruined beyond usability!") - return FALSE - if(HAS_TRAIT(T, TRAIT_GENELESS)) - to_chat(user, "This creature does not have DNA!") - return FALSE - if(get_dna(target.dna)) - to_chat(user, "We already have this DNA in storage.") - return TRUE - -/datum/antagonist/changeling/proc/on_death(mob/living/L, gibbed) - SIGNAL_HANDLER - if(QDELETED(L) || gibbed) // they were probably incinerated or gibbed, no coming back from that. - return - var/mob/living/carbon/human/H = L - if(!istype(H)) - return - - if(!H.get_organ_slot("brain")) - to_chat(L, "The brain is a useless organ to us, we are able to regenerate!") - else - to_chat(L, "While our current form may be lifeless, this is not the end for us as we can still regenerate!") - -/datum/antagonist/changeling/custom_blurb() - return "We awaken on the [station_name()], [get_area_name(owner.current, TRUE)]...\nWe have our tasks to attend to..." diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm deleted file mode 100644 index 728eb1bbba028..0000000000000 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ /dev/null @@ -1,100 +0,0 @@ -/datum/action/changeling/absorb_dna - name = "Absorb DNA" - desc = "Absorb the DNA of our victim. Requires us to strangle them." - button_overlay_icon_state = "absorb_dna" - chemical_cost = 0 - power_type = CHANGELING_INNATE_POWER - req_human = TRUE - -/datum/action/changeling/absorb_dna/can_sting(mob/living/carbon/user) - if(!..()) - return FALSE - - if(cling.is_absorbing) - to_chat(user, "We are already absorbing!") - return FALSE - - var/obj/item/grab/G = user.get_active_hand() - if(!istype(G)) - to_chat(user, "We must be grabbing a creature in our active hand to absorb them.") - return FALSE - if(G.state <= GRAB_NECK) - to_chat(user, "We must have a tighter grip to absorb this creature.") - return FALSE - - return cling.can_absorb_dna(G.affecting) - -/datum/action/changeling/absorb_dna/sting_action(mob/user) - var/obj/item/grab/G = user.get_active_hand() - var/mob/living/carbon/human/target = G.affecting - cling.is_absorbing = TRUE - for(var/stage in 1 to 3) - switch(stage) - if(1) - to_chat(user, "This creature is compatible. We must hold still...") - if(2) - to_chat(user, "We extend a proboscis.") - user.visible_message("[user] extends a proboscis!") - if(3) - to_chat(user, "We stab [target] with the proboscis.") - user.visible_message("[user] stabs [target] with the proboscis!") - to_chat(target, "You feel a sharp stabbing pain!") - target.take_overall_damage(40) - SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("Absorb DNA", "[stage]")) - if(!do_mob(user, target, 150)) - to_chat(user, "Our absorption of [target] has been interrupted!") - cling.is_absorbing = FALSE - return FALSE - - to_chat(user, "We have absorbed [target]!") - user.visible_message("[user] sucks the fluids from [target]!") - to_chat(target, "You have been absorbed by the changeling!") - - if(!cling.get_dna(target.dna)) - cling.absorb_dna(target) - - if(user.nutrition < NUTRITION_LEVEL_WELL_FED) - user.set_nutrition(min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)) - - if(target.mind)//if the victim has got a mind - - target.mind.show_memory(user, 0) //I can read your mind, kekeke. Output all their notes. - - //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. - var/list/recent_speech = list() - - if(length(target.say_log) > CHANGELING_ABSORB_RECENT_SPEECH) - recent_speech = target.say_log.Copy(length(target.say_log)-CHANGELING_ABSORB_RECENT_SPEECH+1,0) //0 so len-LING_ARS+1 to end of list - else - recent_speech = target.say_log.Copy() - - if(length(recent_speech)) - user.mind.store_memory("Some of [target]'s speech patterns. We should study these to better impersonate [target.p_them()]!") - to_chat(user, "Some of [target]'s speech patterns. We should study these to better impersonate [target.p_them()]!") - for(var/spoken_memory in recent_speech) - user.mind.store_memory("\"[spoken_memory]\"") - to_chat(user, "\"[spoken_memory]\"") - user.mind.store_memory("We have no more knowledge of [target]'s speech patterns.") - to_chat(user, "We have no more knowledge of [target]'s speech patterns.") - - var/datum/antagonist/changeling/target_cling = target.mind.has_antag_datum(/datum/antagonist/changeling) - if(target_cling)//If the target was a changeling, suck out their extra juice and objective points! - cling.chem_charges += min(target_cling.chem_charges, cling.chem_storage) - cling.absorbed_count += (target_cling.absorbed_count) - - target_cling.absorbed_dna.len = 1 - target_cling.absorbed_count = 0 - - cling.chem_charges = min(cling.chem_charges + 10, cling.chem_storage) - - cling.is_absorbing = FALSE - cling.can_respec = TRUE - var/datum/action/changeling/evolution_menu/E = locate() in user.actions - SStgui.update_uis(E) - - target.death(FALSE) - target.Drain() - return TRUE - -#undef CHANGELING_ABSORB_RECENT_SPEECH diff --git a/code/modules/antagonists/changeling/powers/biodegrade.dm b/code/modules/antagonists/changeling/powers/biodegrade.dm deleted file mode 100644 index 63975f29e9e34..0000000000000 --- a/code/modules/antagonists/changeling/powers/biodegrade.dm +++ /dev/null @@ -1,161 +0,0 @@ -/datum/action/changeling/biodegrade - name = "Biodegrade" - desc = "Dissolves restraints or other objects preventing free movement if we are restrained. Prepares hand to vomit acid on other objects, doesn't work on living targets. Costs 30 chemicals." - helptext = "This is obvious to nearby people, and can destroy standard restraints and closets, and break you out of grabs." - button_overlay_icon_state = "biodegrade" - chemical_cost = 30 //High cost to prevent spam - dna_cost = 4 - req_human = TRUE - power_type = CHANGELING_PURCHASABLE_POWER - category = /datum/changeling_power_category/defence - /// Type of acid hand we give to person - var/hand = /obj/item/melee/changeling_corrosive_acid - /// Current hand given to human, null is we did not give hand, object if hand is given - var/obj/item/melee/changeling_corrosive_acid/current_hand - -/datum/action/changeling/biodegrade/sting_action(mob/living/carbon/human/user) - var/used = FALSE // only one form of shackles removed per use - - if(user.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.name]!", \ - "We vomit acidic ooze onto our restraints!") - dissolve_restraint(user, O) - used = TRUE - - if(user.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.name]!", \ - "We vomit acidic ooze onto our leg restraints!") - dissolve_restraint(user, O) - used = TRUE - - if(user.wear_suit && user.wear_suit.breakouttime && !used) - var/obj/item/clothing/suit/S = user.get_item_by_slot(ITEM_SLOT_OUTER_SUIT) - if(!istype(S)) - return FALSE - user.visible_message("[user] vomits a glob of acid across the front of [user.p_their()] [S.name]!", \ - "We vomit acidic ooze onto our straight jacket!") - dissolve_restraint(user, S) - used = TRUE - - if(istype(user.loc, /obj/structure/closet) && !used) - var/obj/structure/closet/C = user.loc - if(!istype(C)) - return FALSE - C.visible_message("[C]'s hinges suddenly begin to melt and run!") - to_chat(user, "We vomit acidic goop onto the interior of [C]!") - addtimer(CALLBACK(src, PROC_REF(open_closet), user, C), 7 SECONDS) - used = TRUE - - if(istype(user.loc, /obj/structure/spider/cocoon) && !used) - var/obj/structure/spider/cocoon/C = user.loc - if(!istype(C)) - return FALSE - C.visible_message("[src] shifts and starts to fall apart!") - to_chat(user, "We secrete acidic enzymes from our skin and begin melting our cocoon...") - addtimer(CALLBACK(src, PROC_REF(dissolve_cocoon), user, C), 2.5 SECONDS) //Very short because it's just webs - used = TRUE - for(var/obj/item/grab/G in user.grabbed_by) - var/mob/living/carbon/M = G.assailant - user.visible_message("[user] spits acid at [M]'s face and slips out of their grab!") - M.Stun(2 SECONDS) //Drops the grab - M.apply_damage(5, BURN, "head", M.run_armor_check("head", "melee")) - user.SetStunned(0) //This only triggers if they are grabbed, to have them break out of the grab, without the large stun time. If you use biodegrade as an antistun without being grabbed, it will not work - user.SetWeakened(0) - playsound(user.loc, 'sound/weapons/sear.ogg', 50, TRUE) - used = TRUE - - if(used) - SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]")) - return TRUE - - if(!current_hand) - if(!add_hand_spell(user)) - return FALSE - to_chat(user, "We prepare hand to vomit acid!") - return TRUE - remove_hand_spell(user, TRUE) - return FALSE - -/datum/action/changeling/biodegrade/proc/dissolve_restraint(mob/living/carbon/human/user, obj/O) - if(O && (user.handcuffed == O || user.legcuffed == O || user.wear_suit == O)) - O.visible_message("[O] dissolves into a puddle of sizzling goop.") - qdel(O) - -/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!") - C.welded = FALSE - C.locked = FALSE - C.broken = TRUE - C.open() - to_chat(user, "We open the container restraining us!") - -/datum/action/changeling/biodegrade/proc/dissolve_cocoon(mob/living/carbon/human/user, obj/structure/spider/cocoon/C) - if(C && user.loc == C) - qdel(C) //The cocoon's destroy will move the changeling outside of it without interference - to_chat(user, "We dissolve the cocoon!") - -/datum/action/changeling/biodegrade/proc/add_hand_spell(mob/living/carbon/human/user) - if(user.get_active_hand() && !user.drop_item()) - to_chat(user, "[user.get_active_hand()] is stuck to our hand, we cannot emit acid on this hand.") - return FALSE - current_hand = new hand(src) - user.put_in_active_hand(current_hand) - RegisterSignal(user, COMSIG_MOB_WILLINGLY_DROP, PROC_REF(remove_hand_spell)) - return TRUE - -/datum/action/changeling/biodegrade/proc/remove_hand_spell(mob/living/carbon/human/user, any_hand=FALSE) - SIGNAL_HANDLER - if(!current_hand) - return FALSE - if(any_hand && user.get_active_hand() != current_hand) - return FALSE - qdel(current_hand) - return TRUE - -/obj/item/melee/changeling_corrosive_acid - name = "Corrosive acid" - desc = "A fistfull of death." - icon = 'icons/obj/weapons/magical_weapons.dmi' - icon_state = "alien_acid" - item_state = null - flags = ABSTRACT | NODROP | DROPDEL - w_class = WEIGHT_CLASS_HUGE - force = 0 - throwforce = 0 - throw_range = 0 - throw_speed = 0 - var/datum/action/changeling/biodegrade/parent_action - -/obj/item/melee/changeling_corrosive_acid/New(datum/action/changeling/biodegrade/new_parent) - . = ..() - parent_action = new_parent - -/obj/item/melee/changeling_corrosive_acid/Destroy() - if(parent_action) - parent_action.current_hand = null - parent_action.UnregisterSignal(parent_action.owner, COMSIG_MOB_WILLINGLY_DROP) - return ..() - -/obj/item/melee/changeling_corrosive_acid/afterattack__legacy__attackchain(atom/target, mob/user, proximity, params) - if(target == user) - to_chat(user, "You withdraw your readied acid.") - parent_action.remove_hand_spell(user) - return - if(isliving(target)) - to_chat(user, "We dont have enough acid to assault living target!") - return - if(!proximity || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) // Don't want xenos ditching out of cuffs - return - if(target.acid_act(200, 100)) - visible_message("[user] vomits globs of vile stuff all over [target]. It begins to sizzle and melt under the bubbling mess of acid!") - add_attack_logs(user, target, "Applied corrosive acid") // Want this logged - else - to_chat(user, "You cannot dissolve this object.") - parent_action.remove_hand_spell(user) diff --git a/code/modules/antagonists/changeling/powers/hivemind.dm b/code/modules/antagonists/changeling/powers/hivemind.dm deleted file mode 100644 index 64abb25dc0540..0000000000000 --- a/code/modules/antagonists/changeling/powers/hivemind.dm +++ /dev/null @@ -1,61 +0,0 @@ -// HIVE MIND UPLOAD/DOWNLOAD DNA -GLOBAL_LIST_EMPTY(hivemind_bank) - -/datum/action/changeling/hivemind_pick - name = "Hivemind Access" - desc = "Allows us to upload or absorb DNA in the airwaves. Does not count towards absorb objectives. Costs 10 chemicals." - helptext = "Tunes our chemical receptors for hivemind communication, which passively grants us access to the Changeling Hivemind." - button_overlay_icon_state = "hive_absorb" - chemical_cost = 10 - power_type = CHANGELING_INNATE_POWER - category = /datum/changeling_power_category/utility - -/datum/action/changeling/hivemind_pick/sting_action(mob/user) - var/channel_pick = tgui_alert(user, "Upload or Absorb DNA?", "Channel Select", list("Upload", "Absorb")) - - if(channel_pick == "Upload") - dna_upload(user) - if(channel_pick == "Absorb") - if(cling.using_stale_dna())//If our current DNA is the stalest, we gotta ditch it. - to_chat(user, "We have reached our capacity to store genetic information! We must transform before absorbing more.") - return FALSE - else - dna_absorb(user) - -/datum/action/changeling/proc/dna_upload(mob/user) - var/datum/dna/chosen_dna = cling.select_dna("Select a DNA to channel: ", "Channel DNA", TRUE) - if(!chosen_dna) - to_chat(user, "The airwaves already have all of our DNA.") - return FALSE - - GLOB.hivemind_bank += chosen_dna - to_chat(user, "We channel the DNA of [chosen_dna.real_name] to the air.") - SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]")) - return TRUE - -/datum/action/changeling/proc/dna_absorb(mob/user) - var/list/names = list() - for(var/datum/dna/DNA in GLOB.hivemind_bank) - if(!(DNA in cling.absorbed_dna)) - names[DNA.real_name] = DNA - - if(!length(names)) - to_chat(user, "There's no new DNA to absorb from the air.") - return - - var/S = tgui_input_list(user, "Select a DNA absorb from the air", "Absorb DNA", names) - if(!S) - return - - var/datum/dna/chosen_dna = names[S] - cling.store_dna(chosen_dna) - to_chat(user, "We absorb the DNA of [S] from the air.") - SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]")) - return TRUE - -/datum/action/changeling/hivemind_pick/Remove(mob/user) - if(!istype(user)) - return - user.remove_language("Changeling") - to_chat(user, "We feel a slight emptiness as we shut ourselves off from the hivemind.") - ..() diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm deleted file mode 100644 index 985fb92b83b85..0000000000000 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ /dev/null @@ -1,168 +0,0 @@ -/datum/action/changeling/sting - name = "Tiny Prick" - desc = "Stabby stabby." - power_type = CHANGELING_UNOBTAINABLE_POWER - category = /datum/changeling_power_category/stings - var/sting_icon = null - /// A middle click override used to intercept changeling stings performed on a target. - var/datum/middle_click_override/callback_invoker/click_override - -/datum/action/changeling/sting/New(Target) - . = ..() - click_override = new(CALLBACK(src, PROC_REF(try_to_sting))) - -/datum/action/changeling/sting/Destroy(force, ...) - QDEL_NULL(click_override) - if(cling.chosen_sting == src) - unset_sting() - return ..() - -/datum/action/changeling/sting/Trigger(left_click) - if(!cling.chosen_sting) - set_sting() - else - unset_sting() - -/datum/action/changeling/sting/Remove(mob/remove_from) - . = ..() - // Check that cling exists because in certain scenarios, it may have been deleted in Destroy() first. - if(cling?.chosen_sting == src) - unset_sting() - -/datum/action/changeling/sting/proc/set_sting() - var/mob/living/user = owner - to_chat(user, "We prepare our sting, use alt+click or middle mouse button on a target to sting them.") - user.middleClickOverride = click_override - cling.chosen_sting = src - user.hud_used.lingstingdisplay.icon_state = sting_icon - user.hud_used.lingstingdisplay.invisibility = 0 - -/datum/action/changeling/sting/proc/unset_sting() - var/mob/living/user = owner - to_chat(user, "We retract our sting, we can't sting anyone for now.") - user.middleClickOverride = null - cling.chosen_sting = null - user.hud_used.lingstingdisplay.icon_state = null - user.hud_used.lingstingdisplay.invisibility = 101 - -/datum/action/changeling/sting/can_sting(mob/user, mob/target) - if(!..() || !iscarbon(target) || !isturf(user.loc)) - return FALSE - var/target_distance = get_dist(user, target) - if(target_distance > cling.sting_range) // Too far, don't bother pathfinding - to_chat(user, "Our target is too far for our sting!") - return FALSE - if(target_distance && !length(get_path_to(user, target, max_distance = cling.sting_range, simulated_only = FALSE, skip_first = FALSE))) // If they're not on the same turf, check if it can even reach them. - to_chat(user, "Our sting is blocked from reaching our target!") - return FALSE - if(!cling.chosen_sting) - to_chat(user, "We haven't prepared our sting yet!") - return FALSE - if(ismachineperson(target)) - to_chat(user, "This won't work on synthetics.") - return FALSE - if(IS_CHANGELING(target)) - sting_feedback(user, target) - take_chemical_cost() - return FALSE - return TRUE - -/datum/action/changeling/sting/sting_feedback(mob/user, mob/target) - if(!target) - return - to_chat(user, "We stealthily sting [target.name].") - if(IS_CHANGELING(target)) - to_chat(target, "You feel a tiny prick.") - add_attack_logs(user, target, "Unsuccessful sting (changeling)") - return TRUE - -/datum/action/changeling/sting/extract_dna - name = "Extract DNA Sting" - 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_overlay_icon_state = "sting_extract" - sting_icon = "sting_extract" - chemical_cost = 25 - power_type = CHANGELING_INNATE_POWER - -/datum/action/changeling/sting/extract_dna/can_sting(mob/user, mob/target) - if(..()) - return cling.can_absorb_dna(target) - -/datum/action/changeling/sting/extract_dna/sting_action(mob/user, mob/living/carbon/human/target) - add_attack_logs(user, target, "Extraction sting (changeling)") - if(!cling.get_dna(target.dna)) - cling.absorb_dna(target) - SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]")) - return TRUE - -/datum/action/changeling/sting/mute - name = "Mute Sting" - 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." - button_overlay_icon_state = "sting_mute" - sting_icon = "sting_mute" - chemical_cost = 20 - dna_cost = 4 - power_type = CHANGELING_PURCHASABLE_POWER - -/datum/action/changeling/sting/mute/sting_action(mob/user, mob/living/carbon/target) - add_attack_logs(user, target, "Mute sting (changeling)") - target.AdjustSilence(60 SECONDS) - SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]")) - return TRUE - -/datum/action/changeling/sting/blind - name = "Blind Sting" - desc = "We temporarily blind our victim. Costs 25 chemicals." - helptext = "This sting completely blinds a target for a short time, and leaves them with blurred vision for a long time." - button_overlay_icon_state = "sting_blind" - sting_icon = "sting_blind" - chemical_cost = 25 - dna_cost = 2 - power_type = CHANGELING_PURCHASABLE_POWER - -/datum/action/changeling/sting/blind/sting_action(mob/living/user, mob/living/target) - add_attack_logs(user, target, "Blind sting (changeling)") - to_chat(target, "Your eyes burn horrifically!") - target.become_nearsighted(EYE_DAMAGE) - target.EyeBlind(40 SECONDS) - target.EyeBlurry(80 SECONDS) - SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]")) - return TRUE - -/// Enable when mob cooling is fixed so that frostoil actually makes you cold, instead of mostly just hungry. -/datum/action/changeling/sting/cryo - name = "Cryogenic Sting" - 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." - button_overlay_icon_state = "sting_cryo" - sting_icon = "sting_cryo" - chemical_cost = 15 - dna_cost = 4 - power_type = CHANGELING_PURCHASABLE_POWER - -/datum/action/changeling/sting/cryo/sting_action(mob/user, mob/target) - add_attack_logs(user, target, "Cryo sting (changeling)") - if(target.reagents) - target.reagents.add_reagent("frostoil", 30) - target.reagents.add_reagent("ice", 30) - SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]")) - return TRUE - -/datum/action/changeling/sting/lethargic - name = "Lethargic Sting" - desc = "We silently sting our victim with a chemical that will gradually drain their stamina. Costs 50 chemicals." - helptext = "Does not provide a warning to the victim, though they will quickly realize they have been poisoned." - button_overlay_icon_state = "sting_lethargic" - sting_icon = "sting_lethargic" - chemical_cost = 50 - dna_cost = 4 - power_type = CHANGELING_PURCHASABLE_POWER - -/datum/action/changeling/sting/lethargic/sting_action(mob/user, mob/target) - add_attack_logs(user, target, "Lethargic sting (changeling)") - if(target.reagents) - target.reagents.add_reagent("tirizene", 10) - SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]")) - return TRUE diff --git a/code/modules/antagonists/cult/datum_cultist.dm b/code/modules/antagonists/cult/datum_cultist.dm deleted file mode 100644 index dcfe7dd20221c..0000000000000 --- a/code/modules/antagonists/cult/datum_cultist.dm +++ /dev/null @@ -1,144 +0,0 @@ -RESTRICT_TYPE(/datum/antagonist/cultist) - -/datum/antagonist/cultist - name = "Cultist" - job_rank = ROLE_CULTIST - special_role = SPECIAL_ROLE_CULTIST - give_objectives = FALSE - antag_hud_name = "hudcultist" - antag_hud_type = ANTAG_HUD_CULT - clown_gain_text = "A dark power has allowed you to overcome your clownish nature, letting you wield weapons without harming yourself." - clown_removal_text = "You are free of the dark power suppressing your clownish nature. You are clumsy again! Honk!" - clown_text_span_class = "cultitalic" - wiki_page_name = "Cultist" - var/remove_gear_on_removal = FALSE - -/datum/antagonist/cultist/on_gain() - create_team() // make sure theres a global cult team - ..() - owner.current.faction |= "cult" - add_cult_actions() - SEND_SOUND(owner.current, sound('sound/ambience/antag/bloodcult.ogg')) - owner.current.create_log(CONVERSION_LOG, "Converted to the cult") - owner.current.create_attack_log("Has been converted to the cult!") - - var/datum/team/cult/cult = get_team() - ASSERT(cult) - if(cult.cult_risen) - rise() - if(cult.cult_ascendant) - ascend() - cult.study_objectives(owner.current) - -/datum/antagonist/cultist/detach_from_owner() - if(!owner.current) - return ..() - owner.current.faction -= "cult" - owner.current.create_log(CONVERSION_LOG, "Deconverted from the cult") // yes, this is its own log, instead of the default MISC_LOG - for(var/datum/action/innate/cult/C in owner.current.actions) - qdel(C) - - if(!ishuman(owner.current)) - return ..() - var/mob/living/carbon/human/H = owner.current - REMOVE_TRAIT(H, CULT_EYES, null) - H.change_eye_color(H.original_eye_color, FALSE) - H.update_eyes() - H.remove_overlay(HALO_LAYER) - H.update_body() - - if(remove_gear_on_removal) - for(var/I in H.contents) - if(is_type_in_list(I, CULT_CLOTHING)) - H.drop_item_to_ground(I) - return ..() - - -/datum/antagonist/cultist/greet() - return "You catch a glimpse of the Realm of [GET_CULT_DATA(entity_name, "this is a bug at this point")], [GET_CULT_DATA(entity_title3, "I dont know what else to write")]. \ - You now see how flimsy the world is, you see that it should be open to the knowledge of [GET_CULT_DATA(entity_name, "making a bug report")]." - -/datum/antagonist/cultist/farewell() - if(owner && owner.current) - owner.current.visible_message("[owner.current] looks like [owner.current.p_they()] just reverted to [owner.current.p_their()] old faith!", - "An unfamiliar white light flashes through your mind, cleansing the taint of [GET_CULT_DATA(entity_title1, "Nar'Sie")] and the memories of your time as their servant with it.") - -/datum/antagonist/cultist/create_team(team) - return SSticker.mode.get_cult_team() - -/datum/antagonist/cultist/get_team() - return SSticker.mode.cult_team - -/datum/antagonist/cultist/on_body_transfer(old_body, new_body) - var/datum/team/cult/cult = get_team() - cult.cult_body_transfer(old_body, new_body) - add_cult_actions() - -/datum/antagonist/cultist/proc/rise() - if(!ishuman(owner.current)) - return - var/mob/living/carbon/human/H = owner.current - if(!H.original_eye_color) - H.original_eye_color = H.get_eye_color() - H.change_eye_color(BLOODCULT_EYE, FALSE) - ADD_TRAIT(H, CULT_EYES, CULT_TRAIT) - H.update_eyes() - H.update_body() - -/datum/antagonist/cultist/proc/ascend() - if(!ishuman(owner.current)) - return - var/mob/living/carbon/human/H = owner.current - new /obj/effect/temp_visual/cult/sparks(get_turf(H), H.dir) - H.update_halo_layer() - -/datum/antagonist/cultist/proc/descend() - if(!ishuman(owner.current)) - return - var/mob/living/carbon/human/H = owner.current - new /obj/effect/temp_visual/cult/sparks(get_turf(H), H.dir) - H.update_halo_layer() - to_chat(H, "The halo above your head shatters!") - playsound(H, "shatter", 50, TRUE) - -/datum/antagonist/cultist/proc/add_cult_actions() - if(!owner.current) - return - var/datum/action/innate/cult/comm/communicate_spell = new - var/datum/action/innate/cult/check_progress/progress_report = new - communicate_spell.Grant(owner.current) - progress_report.Grant(owner.current) - if(ishuman(owner.current)) - var/datum/action/innate/cult/blood_magic/magic = new - var/datum/action/innate/cult/use_dagger/dagger = new - magic.Grant(owner.current) - dagger.Grant(owner.current) - - owner.current.update_action_buttons(TRUE) - -/datum/antagonist/cultist/proc/equip_roundstart_cultist() - if(!ishuman(owner.current)) - return FALSE - . |= cult_give_item(/obj/item/melee/cultblade/dagger) - . |= cult_give_item(/obj/item/stack/sheet/runed_metal/ten) - to_chat(owner.current, "These will help you start the cult on this station. Use them well, and remember - you are not the only one.") - -/datum/antagonist/cultist/proc/cult_give_item(obj/item/item_path) - if(!ishuman(owner.current)) - return - var/mob/living/carbon/human/H = owner.current - var/list/slots = list( - "backpack" = ITEM_SLOT_IN_BACKPACK, - "left pocket" = ITEM_SLOT_LEFT_POCKET, - "right pocket" = ITEM_SLOT_RIGHT_POCKET - ) - - var/where = H.equip_in_one_of_slots(new item_path(H), slots) - if(where) - to_chat(H, "You have \a [initial(item_path.name)] in your [where].") - if(H.s_active) // Update whatever inventory they have open - H.s_active.orient2hud(H) - H.s_active.show_to(H) - return TRUE - to_chat(H, "Unfortunately, you weren't able to get \a [initial(item_path.name)]. This is very bad and you should adminhelp immediately (press F1).") - return FALSE diff --git a/code/modules/antagonists/cult/team_cult.dm b/code/modules/antagonists/cult/team_cult.dm deleted file mode 100644 index 39fb80f62b60b..0000000000000 --- a/code/modules/antagonists/cult/team_cult.dm +++ /dev/null @@ -1,588 +0,0 @@ -RESTRICT_TYPE(/datum/team/cult) - -/datum/team/cult - name = "Cult" - antag_datum_type = /datum/antagonist/cultist - - /// Does the cult have glowing eyes - var/cult_risen = FALSE - /// Does the cult have halos - var/cult_ascendant = FALSE - /// How many crew need to be converted to rise - var/rise_number - /// How many crew need to be converted to ascend - var/ascend_number - /// Used for the CentComm announcement at ascension - var/ascend_percent - /// Variable used for tracking the progress of the cult's sacrifices & god summonings - var/cult_status = NARSIE_IS_ASLEEP - - /// God summon objective added when ready_to_summon() is called - var/datum/objective/eldergod/obj_summon - var/sacrifices_done = 0 - var/sacrifices_required = 2 - - /// Are cultist mirror shields active yet? - var/mirror_shields_active = FALSE - - // Disables the station-wide announcements, unused except for admin editing. - var/no_announcements = FALSE - - /// Boolean that prevents all_members_timer from being called multiple times - var/is_in_transition = FALSE - - /// Timer until we do a recount of cultist members - var/recount_timer - -/datum/team/cult/Destroy(force, ...) - deltimer(recount_timer) - return ..() - -/datum/team/cult/create_team(list/starting_members) - cult_threshold_check() // Set this ALWAYS before any check_cult_size check, or - . = ..() - - objective_holder.add_objective(/datum/objective/servecult) - - cult_status = NARSIE_DEMANDS_SACRIFICE - - create_next_sacrifice() - recount_timer = addtimer(CALLBACK(src, PROC_REF(cult_threshold_check)), 5 MINUTES, TIMER_STOPPABLE|TIMER_DELETE_ME|TIMER_LOOP) - - for(var/datum/mind/M as anything in starting_members) - var/datum/antagonist/cultist/cultist = M.has_antag_datum(/datum/antagonist/cultist) - cultist.equip_roundstart_cultist() - -/datum/team/cult/can_create_team() - return isnull(SSticker.mode.cult_team) - -/datum/team/cult/assign_team() - SSticker.mode.cult_team = src - -/datum/team/cult/clear_team_reference() - if(SSticker.mode.cult_team == src) - SSticker.mode.cult_team = null - else - CRASH("[src] ([type]) attempted to clear a team reference that wasn't itself!") - -/datum/team/cult/handle_adding_member(datum/mind/new_member) - . = ..() - check_cult_size() - RegisterSignal(new_member.current, COMSIG_MOB_STATCHANGE, PROC_REF(cultist_stat_change)) - RegisterSignal(new_member.current, COMSIG_PARENT_QDELETING, PROC_REF(cultist_deleting)) - -/datum/team/cult/handle_removing_member(datum/mind/member) - . = ..() - UnregisterSignal(member.current, COMSIG_MOB_STATCHANGE) - UnregisterSignal(member.current, COMSIG_PARENT_QDELETING) - check_cult_size() - -/datum/team/cult/on_round_end() - var/list/endtext = list() - endtext += "
    The cultists' objectives were:" - for(var/datum/objective/obj in objective_holder.get_objectives()) - endtext += "
    [obj.explanation_text] - " - if(!obj.check_completion()) - endtext += "Fail." - else - endtext += "Success!" - - to_chat(world, endtext.Join("")) - -/datum/team/cult/proc/add_cult_immunity(mob/living/target) - ADD_TRAIT(target, TRAIT_CULT_IMMUNITY, CULT_TRAIT) - addtimer(CALLBACK(src, PROC_REF(remove_cult_immunity), target), 1 MINUTES) - -/datum/team/cult/proc/remove_cult_immunity(mob/living/target) - REMOVE_TRAIT(target, TRAIT_CULT_IMMUNITY, CULT_TRAIT) - -/** - * Makes sure that the signal stays on the correct body when a cultist changes bodies - */ -/datum/team/cult/proc/cult_body_transfer(old_body, new_body) - UnregisterSignal(old_body, COMSIG_MOB_STATCHANGE) - UnregisterSignal(old_body, COMSIG_PARENT_QDELETING) - RegisterSignal(new_body, COMSIG_MOB_STATCHANGE, PROC_REF(cultist_stat_change)) - RegisterSignal(new_body, COMSIG_PARENT_QDELETING, PROC_REF(cultist_deleting)) - -/** - * Returns the current number of cultists and constructs. - * - * Returns the number of cultists and constructs in the format `list(number of Cultists, number of Constructs)`, or as one combined number. - * - * * separate - Should the number be returned as a list with two separate values (Humans and Constructs) or as one number. - */ -/datum/team/cult/proc/get_cultists(separate = FALSE) - var/cultists = 0 - var/constructs = 0 - var/list/minds_to_remove = list() - for(var/datum/mind/M as anything in members) - if(isnull(M)) - stack_trace("Found a null mind in /datum/team/cult's members. Removing...") - minds_to_remove |= M // I don't really want to remove them while iterating, as I'm not sure how byond would handle that while iterating over members - continue - if(isnull(M.current)) - stack_trace("Found a mind with no body in /datum/team/cult's members. Removing...") - minds_to_remove |= M // I don't really want to remove them while iterating, as I'm not sure how byond would handle that while iterating over members - continue - if(QDELETED(M) || M.current.stat == DEAD) - continue - if(ishuman(M.current) && !M.current.has_status_effect(STATUS_EFFECT_SUMMONEDGHOST)) - cultists++ - else if(isconstruct(M.current)) - constructs++ - - if(length(minds_to_remove)) - for(var/datum/mind/M as anything in minds_to_remove) - remove_member(M) - - if(separate) - return list(cultists, constructs) - return cultists + constructs - -/datum/team/cult/proc/cultist_stat_change(mob/target_cultist, new_stat, old_stat) - SIGNAL_HANDLER - if(new_stat == old_stat) // huh, how? whatever, we ignore it - return - if(new_stat != DEAD && old_stat != DEAD) - return // switching between alive and unconcious - // switching between dead and alive/unconcious - INVOKE_ASYNC(src, PROC_REF(check_cult_size)) - -/datum/team/cult/proc/cultist_deleting(mob/deleting_cultist) - SIGNAL_HANDLER - INVOKE_ASYNC(src, PROC_REF(remove_member), deleting_cultist.mind) - -/datum/team/cult/proc/check_cult_size() - if(is_in_transition) - return - - if(!ascend_percent) - stack_trace("[src]'s check_cult_size was called before cult_threshold_check, which leads to weird logic! This should be fixed ASAP.") - cult_threshold_check() - - var/cult_players = get_cultists() - - if(cult_ascendant) - // The cult only falls if below 1/2 of the rising, usually pretty low. e.g. 5% on highpop, 10% on lowpop - if(cult_players < (rise_number / 2)) - cult_fall() - return - - if((cult_players >= rise_number) && !cult_risen) - cult_rise() - return - - if(cult_players >= ascend_number) - cult_ascend() - -/datum/team/cult/proc/cult_rise() - is_in_transition = TRUE - for(var/datum/mind/M in members) - if(!ishuman(M.current)) - continue - SEND_SOUND(M.current, sound('sound/hallucinations/i_see_you2.ogg')) - to_chat(M.current, "The veil weakens as your cult grows, your eyes begin to glow...") - - addtimer(CALLBACK(src, PROC_REF(all_members_timer), TYPE_PROC_REF(/datum/antagonist/cultist, rise), VARSET_CALLBACK(src, cult_risen, TRUE)), 20 SECONDS) - -/datum/team/cult/proc/cult_ascend() - is_in_transition = TRUE - for(var/datum/mind/M in members) - if(!ishuman(M.current)) - continue - SEND_SOUND(M.current, sound('sound/hallucinations/im_here1.ogg')) - to_chat(M.current, "Your cult is ascendant and the red harvest approaches - you cannot hide your true nature for much longer!") - - addtimer(CALLBACK(src, PROC_REF(all_members_timer), TYPE_PROC_REF(/datum/antagonist/cultist, ascend), VARSET_CALLBACK(src, cult_ascendant, TRUE)), 20 SECONDS) - if(!no_announcements) - GLOB.major_announcement.Announce("Picking up extradimensional activity related to the Cult of [GET_CULT_DATA(entity_name, "Nar'Sie")] from your station. Data suggests that about [ascend_percent * 100]% of the station has been converted. Security staff are authorized to use lethal force freely against cultists. Non-security staff should be prepared to defend themselves and their work areas from hostile cultists. Self defense permits non-security staff to use lethal force as a last resort, but non-security staff should be defending their work areas, not hunting down cultists. Dead crewmembers must be revived and deconverted once the situation is under control.", "Central Command Higher Dimensional Affairs", 'sound/AI/commandreport.ogg') - -/datum/team/cult/proc/cult_fall() - is_in_transition = TRUE - for(var/datum/mind/M in members) - if(!ishuman(M.current)) - continue - SEND_SOUND(M.current, sound('sound/hallucinations/wail.ogg')) - to_chat(M.current, "The veil repairs itself, your power grows weaker...") - - addtimer(CALLBACK(src, PROC_REF(all_members_timer), TYPE_PROC_REF(/datum/antagonist/cultist, descend), VARSET_CALLBACK(src, cult_ascendant, FALSE)), 20 SECONDS) - if(!no_announcements) - GLOB.major_announcement.Announce("Paranormal activity has returned to minimal levels. \ - Security staff should minimize lethal force against cultists, using non-lethals where possible. \ - All dead cultists should be taken to medbay or robotics for immediate revival and deconversion. \ - Non-security staff may defend themselves, but should prioritize leaving any areas with cultists and reporting the cultists to security. \ - Self defense permits non-security staff to use lethal force as a last resort. Hunting down cultists may make you liable for a manslaughter charge. \ - Any access granted in response to the paranormal threat should be reset. \ - Any and all security gear that was handed out should be returned. Finally, all weapons (including improvised) should be removed from the crew.", - "Central Command Higher Dimensional Affairs", 'sound/AI/commandreport.ogg') -/** - * This is a magic fuckin proc that takes a proc_ref, and calls it on all the human cultists. - * Created so that we don't make 1000 timers, and I'm too lazy to make a proc for all of these. - * Used in callbacks for some *magic bullshit*. - */ -/datum/team/cult/proc/all_members_timer(cultist_proc_ref, datum/callback/varset_callback) - if(istype(varset_callback)) - varset_callback.Invoke() - - for(var/datum/mind/M in members) - if(!ishuman(M.current)) - continue - var/datum/antagonist/cultist/cultist = M.has_antag_datum(/datum/antagonist/cultist) - if(cultist) - call(cultist, cultist_proc_ref)() // yes this is a type proc ref passed by a callback, i know its deranged - - is_in_transition = FALSE - -/datum/team/cult/proc/is_convertable_to_cult(datum/mind/mind) - if(!mind) - return FALSE - if(!mind.current) - return FALSE - if(IS_SACRIFICE_TARGET(mind)) - return FALSE - if(mind.has_antag_datum(/datum/antagonist/cultist)) - return TRUE //If they're already in the cult, assume they are convertable - if(HAS_MIND_TRAIT(mind.current, TRAIT_HOLY)) - return FALSE - if(ishuman(mind.current)) - var/mob/living/carbon/human/H = mind.current - if(ismindshielded(H)) //mindshield protects against conversions unless removed - return FALSE - if(mind.offstation_role) - return FALSE - if(issilicon(mind.current)) - return FALSE //can't convert machines, that's ratvar's thing - if(isguardian(mind.current)) - var/mob/living/simple_animal/hostile/guardian/G = mind.current - if(IS_CULTIST(G.summoner)) - return TRUE //can't convert it unless the owner is converted - if(isgolem(mind.current)) - return FALSE - if(isanimal(mind.current)) - return FALSE - return TRUE - -/** - * Decides at the start of the round how many conversions are needed to rise/ascend. - * - * The number is decided by (Percentage * (Players - Cultists)), so for example at 110 players it would be 11 conversions for rise. (0.1 * (110 - 4)) - * These values change based on population because 20 cultists are MUCH more powerful if there's only 50 players, compared to 120. - * - * Below 100 players, [CULT_RISEN_LOW] and [CULT_ASCENDANT_LOW] are used. - * Above 100 players, [CULT_RISEN_HIGH] and [CULT_ASCENDANT_HIGH] are used. - */ -/datum/team/cult/proc/cult_threshold_check() - var/list/living_players = get_living_players(exclude_nonhuman = TRUE, exclude_offstation = TRUE) - var/players = length(living_players) - var/cultists = get_cultists() // Don't count the starting cultists towards the number of needed conversions - if(players >= CULT_POPULATION_THRESHOLD) - // Highpop - ascend_percent = CULT_ASCENDANT_HIGH - rise_number = round(CULT_RISEN_HIGH * (players - cultists)) - ascend_number = round(CULT_ASCENDANT_HIGH * (players - cultists)) - else - // Lowpop - ascend_percent = CULT_ASCENDANT_LOW - rise_number = round(CULT_RISEN_LOW * (players - cultists)) - ascend_number = round(CULT_ASCENDANT_LOW * (players - cultists)) - -/datum/team/cult/proc/speak_to_all_alive_cultists(...) - var/message_to_sent = args.Join("
    ") - for(var/datum/mind/cult_mind in members) - if(cult_mind?.current) - to_chat(cult_mind.current, message_to_sent) - -/datum/team/cult/get_admin_priority_objectives() - . = list() - .["Sacrifice"] = /datum/objective/sacrifice - .["Summon God"] = /datum/objective/eldergod - -/datum/team/cult/handle_adding_admin_objective(mob/user, objective_type) - if(objective_type == /datum/objective/sacrifice) - if(obj_summon) - if(confirm_remove_eldergod_obj(user)) - return TEAM_ADMIN_ADD_OBJ_SUCCESS - - if(current_sac_objective()) - var/alert_result = alert(user, "There is already a current sacrifice, reroll the cult's sacrifice target?", "Cult Debug", "Reroll", "Add new sacrifice", "Cancel") - if(alert_result == "Reroll") - admin_reroll_sac_target(user) - return TEAM_ADMIN_ADD_OBJ_SUCCESS | TEAM_ADMIN_ADD_OBJ_CANCEL_LOG - else if(alert_result == "Add new sacrifice") - return ..() - else - return TEAM_ADMIN_ADD_OBJ_PURPOSEFUL_CANCEL - - return ..() - - - else if(objective_type == /datum/objective/eldergod) - if(confirm_add_eldergod_obj()) - return TEAM_ADMIN_ADD_OBJ_SUCCESS - return TEAM_ADMIN_ADD_OBJ_PURPOSEFUL_CANCEL - - return ..() - -/datum/team/cult/admin_remove_objective(mob/user, datum/objective/O) - if(istype(O, /datum/objective/eldergod)) - confirm_remove_eldergod_obj(user) - return - . = ..() - -/datum/team/cult/proc/confirm_add_eldergod_obj(admin_caller, alert_text = "Unlock the ability to summon Nar'Sie?") - if(alert(admin_caller, alert_text, "Cult Debug", "Yes", "No") != "Yes") - return FALSE - - ready_to_summon() - - message_admins("Admin [key_name_admin(admin_caller)] has unlocked the Cult's ability to summon Nar'Sie.") - log_admin("Admin [key_name_admin(admin_caller)] has unlocked the Cult's ability to summon Nar'Sie.") - return TRUE - -/datum/team/cult/proc/confirm_remove_eldergod_obj(admin_caller) - if(alert(admin_caller, "Revert to pre-summon stage of Cult?", "Cult Debug", "Yes", "No") != "Yes") - return FALSE - - sacrifices_required = max(sacrifices_done + 1, sacrifices_required) // make sure we're at least one above the required amount - objective_holder.remove_objective(obj_summon) // qdel's the objective too - obj_summon = null - current_sac_objective() // Create an objective only if needed - cult_status = NARSIE_DEMANDS_SACRIFICE - - message_admins("Admin [key_name_admin(admin_caller)] has removed the Cult's ability to summon Nar'Sie.") - log_admin("Admin [key_name_admin(admin_caller)] has removed the Cult's ability to summon Nar'Sie.") - return TRUE - -/datum/team/cult/proc/study_objectives(mob/living/M, display_members = FALSE) //Called by cultists/cult constructs checking their objectives - if(!M) - return FALSE - - switch(cult_status) - if(NARSIE_IS_ASLEEP) - to_chat(M, "[GET_CULT_DATA(entity_name, "The Dark One")] is asleep. This is probably a bug.") - if(NARSIE_DEMANDS_SACRIFICE) - var/list/all_objectives = objective_holder.get_objectives() - if(!length(all_objectives)) - to_chat(M, "Error: No objectives. Something went wrong, adminhelp with F1.") - else - var/datum/objective/sacrifice/current_obj = all_objectives[length(all_objectives)] //get the last obj in the list, ie the current one - to_chat(M, "The Veil needs to be weakened before we are able to summon [GET_CULT_DATA(entity_title1, "The Dark One")].") - to_chat(M, "Current goal: [current_obj.explanation_text]") - if(NARSIE_NEEDS_SUMMONING) - to_chat(M, "The Veil is weak! We can summon [GET_CULT_DATA(entity_title3, "The Dark One")]!") - to_chat(M, "Current goal: [obj_summon.explanation_text]") - if(NARSIE_HAS_RISEN) - to_chat(M, "\"I am here.\"") - to_chat(M, "Current goal: \"Feed me.\"") - if(NARSIE_HAS_FALLEN) - to_chat(M, "[GET_CULT_DATA(entity_name, "The Dark One")] has been banished!") - to_chat(M, "Current goal: Slaughter the unbelievers!") - else - to_chat(M, "Error: Cult objective status currently unknown. Something went wrong, adminhelp with F1.") - - if(!display_members) - return - var/list/cult = get_cultists(separate = TRUE) - var/total_cult = cult[1] + cult[2] - - var/overview = "
    Current cult members: [total_cult]" - if(!cult_ascendant) - var/rise = rise_number - total_cult - var/ascend = ascend_number - total_cult - if(rise > 0) - overview += " | Conversions until Rise: [rise]" - else if(ascend > 0) - overview += " | Conversions until Ascension: [ascend]" - to_chat(M, "[overview]
    ") - - if(cult[2]) // If there are any constructs, separate them out - to_chat(M, "Cultists: [cult[1]]") - to_chat(M, "Constructs: [cult[2]]") - -/datum/team/cult/proc/create_next_sacrifice() - var/datum/objective/sacrifice/obj_sac = objective_holder.add_objective(/datum/objective/sacrifice) - if(!obj_sac.target) - objective_holder.remove_objective(obj_sac) - ready_to_summon() - return - return obj_sac - -/// Return the current sacrifice objective datum, if any -/datum/team/cult/proc/current_sac_objective() - var/list/presummon_objs = objective_holder.get_objectives() - if(cult_status == NARSIE_DEMANDS_SACRIFICE && length(presummon_objs)) - var/datum/objective/sacrifice/current_obj = presummon_objs[length(presummon_objs)] - if(current_obj.sacced) - return create_next_sacrifice() - if(istype(current_obj)) - return current_obj - -/datum/team/cult/proc/is_sac_target(datum/mind/mind) - var/datum/objective/sacrifice/current_obj = current_sac_objective() - return istype(current_obj) && current_obj.target == mind - -/datum/team/cult/proc/find_new_sacrifice_target() - var/datum/objective/sacrifice/current_obj = current_sac_objective() - if(!current_obj) - return FALSE - if(!current_obj.find_target(list(current_obj.target))) - objective_holder.remove_objective(current_obj) - ready_to_summon() - return FALSE - speak_to_all_alive_cultists("[GET_CULT_DATA(entity_name, "Your god")] murmurs, Our goal is beyond your reach. Sacrifice [current_obj.target] instead...") - return TRUE - -/datum/team/cult/proc/successful_sacrifice() - var/datum/objective/sacrifice/current_obj = current_sac_objective() - if(!istype(current_obj)) - return - current_obj.sacced = TRUE - sacrifices_done++ - if(sacrifices_done >= sacrifices_required) - ready_to_summon() - return - - var/datum/objective/sacrifice/obj_sac = create_next_sacrifice() - if(!obj_sac) - return - - speak_to_all_alive_cultists( - "You and your acolytes have made progress, but there is more to do still before [GET_CULT_DATA(entity_title1, "The Dark One")] can be summoned!", - "Current goal: [obj_sac.explanation_text]" - ) - -/datum/team/cult/proc/ready_to_summon() - if(!obj_summon) - obj_summon = objective_holder.add_objective(/datum/objective/eldergod) - - cult_status = NARSIE_NEEDS_SUMMONING - speak_to_all_alive_cultists( - "You and your acolytes have succeeded in preparing the station for the ultimate ritual!", - "Current goal: [obj_summon.explanation_text]" - ) - -/datum/team/cult/proc/successful_summon() - cult_status = NARSIE_HAS_RISEN - obj_summon.summoned = TRUE - -/datum/team/cult/proc/narsie_death() - cult_status = NARSIE_HAS_FALLEN - obj_summon.killed = TRUE - speak_to_all_alive_cultists( - "RETRIBUTION!", - "Current goal: Slaughter the heretics!" - ) - -/datum/team/cult/proc/get_cult_status_as_string() - var/list/define_to_string = list( - "[NARSIE_IS_ASLEEP]" = "NARSIE_IS_ASLEEP", - "[NARSIE_DEMANDS_SACRIFICE]" = "NARSIE_DEMANDS_SACRIFICE", - "[NARSIE_NEEDS_SUMMONING]" = "NARSIE_NEEDS_SUMMONING", - "[NARSIE_HAS_RISEN]" = "NARSIE_HAS_RISEN", - "[NARSIE_HAS_FALLEN]" = "NARSIE_HAS_FALLEN", - ) - return define_to_string["[cult_status]"] - -/** - * ADMIN STUFF DOWN YONDER - */ - -/datum/team/cult/get_admin_commands() - return list( - "Cult Mindspeak" = CALLBACK(src, PROC_REF(cult_mindspeak)) - ) - -/datum/team/cult/proc/cult_mindspeak(admin_caller) - var/input = stripped_input(admin_caller, "Communicate to all the cultists with the voice of [GET_CULT_DATA(entity_name, "a cult god")]", "Voice of [GET_CULT_DATA(entity_name, "Cult God")]") - if(!input) - return - - speak_to_all_alive_cultists("[GET_CULT_DATA(entity_name, "Your god")] murmurs, \"[input]\"") - - for(var/mob/dead/observer/O in GLOB.player_list) - to_chat(O, "[GET_CULT_DATA(entity_name, "Your god")] murmurs, \"[input]\"") - - message_admins("Admin [key_name_admin(admin_caller)] has talked with the Voice of [GET_CULT_DATA(entity_name, "Cult God")].") - log_admin("[key_name(admin_caller)] Voice of [GET_CULT_DATA(entity_name, "Cult God")]: [input]") - -/datum/team/cult/proc/admin_reroll_sac_target(mob/user) - var/datum/objective/sacrifice/current_obj = current_sac_objective() - - var/choice = alert(usr, "How would you like to reroll the cult sacrifice?", "Pick objective", "Pick target", "Random reroll", "Cancel") - if(choice == "Pick target") - var/new_target = get_admin_objective_targets(user, get_target_excludes(), current_obj.target.current) - if(new_target) - current_obj.target = new_target - current_obj.update_explanation_text() - else if(choice == "Random reroll") - find_new_sacrifice_target() - else - return - - message_admins("Admin [key_name_admin(user)] has rerolled the Cult's sacrifice target.") - log_admin("Admin [key_name_admin(user)] has rerolled the Cult's sacrifice target.") - user.client.holder.check_teams() - -/datum/team/cult/Topic(href, href_list) - . = ..() - - if(!check_rights(R_ADMIN)) - return - - // manually cramming some shit in here, because it only conditonally pops up - - switch(href_list["cult_command"]) - if("cult_adjustsacnumber") - var/amount = input("Adjust the amount of sacrifices required before summoning Nar'Sie", "Sacrifice Adjustment", 2) as null | num - if(amount > 0) - var/old = sacrifices_required - sacrifices_required = amount - message_admins("Admin [key_name_admin(usr)] has modified the amount of cult sacrifices required before summoning from [old] to [amount]") - log_admin("Admin [key_name_admin(usr)] has modified the amount of cult sacrifices required before summoning from [old] to [amount]") - if(sacrifices_done >= sacrifices_required) - confirm_add_eldergod_obj(usr, "Would you also like to unlock the summoning of Nar'sie?") - usr.client.holder.check_teams() - - if("cult_newtarget") - if(alert(usr, "Reroll the cult's sacrifice target?", "Cult Debug", "Yes", "No") != "Yes") - return - admin_reroll_sac_target(usr) - - if("cult_newsummonlocations") - if(!obj_summon) - to_chat(usr, "The cult has NO summon objective yet.") - return - if(alert(usr, "Reroll the cult's summoning locations?", "Cult Debug", "Yes", "No") != "Yes") - return - - obj_summon.find_summon_locations(TRUE) - if(cult_status == NARSIE_NEEDS_SUMMONING) //Only update cultists if they are already have the summon goal since they arent aware of summon spots till then - speak_to_all_alive_cultists( - "The veil has shifted! Our summoning will need to take place elsewhere.", - "Current goal: [obj_summon.explanation_text]" - ) - - message_admins("Admin [key_name_admin(usr)] has rerolled the Cult's sacrifice target.") - log_admin("Admin [key_name_admin(usr)] has rerolled the Cult's sacrifice target.") - usr.client.holder.check_teams() - -/datum/team/cult/get_admin_html() - var/list/content = ..() - content += "

    Cult Controls:
    " - content += "
    Cult Status: [get_cult_status_as_string()]" - content += "
    Sacrifices completed: [sacrifices_done]" - content += "
    Sacrifice required for summoning: [sacrifices_required]
    " - if(obj_summon) - content += "
    Summoning locations: [english_list(obj_summon.summon_spots)]" - content += "
    Reroll summoning locations" - else - content += "
    Summoning locations: None, Cult has not yet reached the summoning stage." - content += "
    " - if(cult_status == NARSIE_DEMANDS_SACRIFICE) - content += "
    Modify amount of sacrifices required" - content += "
    Reroll sacrifice target" - else - content += "
    Cannot modify amount of sacrifices required (Summon available!)" - content += "
    Cannot reroll sacrifice target (Summon available!)" - return content diff --git a/code/modules/antagonists/event/datum_eventmisc.dm b/code/modules/antagonists/event/datum_eventmisc.dm deleted file mode 100644 index c86ed49603a44..0000000000000 --- a/code/modules/antagonists/event/datum_eventmisc.dm +++ /dev/null @@ -1,15 +0,0 @@ -RESTRICT_TYPE(/datum/antagonist/eventmisc) - -/datum/antagonist/eventmisc - name = "Event" - job_rank = ROLE_EVENTMISC - special_role = SPECIAL_ROLE_EVENTMISC - give_objectives = FALSE - antag_hud_name = "hudevent" - antag_hud_type = ANTAG_HUD_EVENTMISC - -/datum/antagonist/eventmisc/add_owner_to_gamemode() - SSticker.mode.eventmiscs |= owner - -/datum/antagonist/eventmisc/remove_owner_from_gamemode() - SSticker.mode.eventmiscs -= owner diff --git a/code/modules/antagonists/mind_flayer/flayer_power.dm b/code/modules/antagonists/mind_flayer/flayer_power.dm deleted file mode 100644 index 481c3d0a78ac9..0000000000000 --- a/code/modules/antagonists/mind_flayer/flayer_power.dm +++ /dev/null @@ -1,270 +0,0 @@ -/datum/spell/flayer - action_background_icon_state = "bg_flayer" - desc = "This spell needs a description!" - human_req = TRUE - clothes_req = FALSE - antimagic_flags = NONE - /// A reference to the owner mindflayer's antag datum. - var/datum/antagonist/mindflayer/flayer - - /// What level is our spell currently at - var/level = 0 - /// Max level of our spell - var/max_level = 1 - /// Determines whether the power is always given to the mind flayer or if it must be purchased. - var/power_type = FLAYER_UNOBTAINABLE_POWER - /// The initial cost of purchasing the spell. - var/base_cost = 0 - /// Should this spell's cost increase by a static amount every purchase? 0 means it will stay the base cost for every upgrade. - var/static_upgrade_increase = 0 - /// The current price to upgrade the spell - var/current_cost = 0 - - /// The class that this spell is for or FLAYER_CATEGORY_GENERAL to make it unrelated to a specific tree - var/category = FLAYER_CATEGORY_GENERAL - /// The current `stage` that we are on for our powers. Currently only hides powers of a higher stage. - var/stage = 1 - /// A brief description of what the spell's upgrades do - var/upgrade_info = "This spell needs upgrade info!" - /// If the spell checks for a nullification implant/effect, set to FALSE to make it castable despite nullification - var/checks_nullification = TRUE - -/datum/spell/flayer/self/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/flayer/Destroy(force, ...) - if(!flayer) - return ..() - flayer.powers -= src - flayer = null - return ..() - -/datum/spell/flayer/create_new_handler() - var/datum/spell_handler/flayer/handler = new() - handler.checks_nullification = checks_nullification - return handler - -/datum/spell_handler/flayer - /// Do we check for nullification - var/checks_nullification = TRUE - -/datum/spell_handler/flayer/can_cast(mob/user, charge_check, show_message, datum/spell/spell) - var/datum/antagonist/mindflayer/flayer_datum = user.mind.has_antag_datum(/datum/antagonist/mindflayer) - - if(!flayer_datum) - return FALSE - - if(user.stat == DEAD) - if(show_message) - flayer_datum.send_swarm_message("We can't cast this while you are dead...") - return FALSE - - if(checks_nullification && HAS_TRAIT(user, TRAIT_MINDFLAYER_NULLIFIED)) - flayer_datum.send_swarm_message("We do not have the energy to manifest that currently...") - return FALSE - return TRUE - -/// The shop for purchasing and upgrading abilities, from here on the rest of the file is just handling shopping. Specific powers are in the powers subfolder. -/datum/spell/flayer/self/augment_menu - name = "Self-Augment Operations" - desc = "Choose how we will upgrade ourselves." - action_icon_state = "choose_module" - base_cooldown = 0 SECONDS - power_type = FLAYER_INNATE_POWER - checks_nullification = FALSE - -/datum/spell/flayer/self/augment_menu/ui_state(mob/user) - return GLOB.always_state - -/datum/spell/flayer/self/augment_menu/cast(mob/user) - ui_interact(user) - -/datum/spell/flayer/self/augment_menu/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "AugmentMenu", name) - ui.set_autoupdate(FALSE) - ui.open() - -/datum/spell/flayer/self/augment_menu/ui_act(action, list/params, datum/tgui/ui) - var/mob/user = ui.user - if(user.stat) - return - - switch(action) - if("purchase") - var/path = text2path(params["ability_path"]) - on_purchase(user, path) - update_static_data(ui.user) - -// Takes in a category name and grabs the paths of all the spells/passives specific to that category. Used for TGUI -/datum/antagonist/mindflayer/proc/get_powers_of_category(category) - var/list/powers = list() - for(var/path in ability_list) - if(ispath(path, /datum/spell)) - var/datum/spell/flayer/spell = path - if(spell.category == category) - powers += list(list( - "name" = spell.name, - "desc" = spell.desc, - "max_level" = spell.max_level, - "cost" = spell.base_cost, - "stage" = spell.stage, - "ability_path" = spell.type - )) - else - var/datum/mindflayer_passive/passive = path - if(passive.category == category) - powers += list(list( - "name" = passive.name, - "desc" = passive.purchase_text, - "max_level" = passive.max_level, - "cost" = passive.base_cost, - "stage" = passive.stage, - "ability_path" = passive.type - )) - - return powers - -/datum/antagonist/mindflayer/proc/build_ability_tabs() - var/list/ability_tabs = list() - for(var/category in category_stage) - ability_tabs += list(list( - "category_name" = category, - "category_stage" = category_stage[category], - "abilities" = get_powers_of_category(category) - )) - return ability_tabs - -/datum/spell/flayer/self/augment_menu/ui_data(mob/user) - var/list/data = list() - var/list/known_abilities = list() - data["usable_swarms"] = flayer.usable_swarms - for(var/datum/mindflayer_passive/passive in flayer.powers) - known_abilities += list(list( - "name" = passive.name, - "current_level" = passive.level, - "max_level" = passive.max_level, - "cost" = passive.current_cost, - "upgrade_text" = passive.upgrade_info, - "ability_path" = passive.type - )) - - for(var/datum/spell/flayer/spell in flayer.powers) - known_abilities += list(list( - "name" = spell.name, - "current_level" = spell.level, - "max_level" = spell.max_level, - "cost" = spell.current_cost, - "upgrade_text" = spell.upgrade_info, - "ability_path" = spell.type - )) - data["known_abilities"] = known_abilities - return data - -/datum/spell/flayer/self/augment_menu/ui_static_data(mob/user) - var/list/static_data = list() - static_data["ability_tabs"] = flayer.build_ability_tabs() - return static_data - -/* - * Given a spell, checks if a mindflayer is able to afford, and has the prerequisites for that spell. - * If so it adds the ability and increments the category stage if needed, then returns TRUE - * otherwise, returns FALSE - */ -/datum/antagonist/mindflayer/proc/try_purchase_spell(datum/spell/flayer/to_add) - var/datum/spell/flayer/existing_spell = has_spell(to_add) - if(existing_spell && (existing_spell.level >= existing_spell.max_level)) - send_swarm_message("That function is already at its strongest.") - qdel(to_add) - return FALSE - - if(to_add.current_cost > get_swarms()) - send_swarm_message("We need [to_add.current_cost - get_swarms()] more swarm\s for this...") - qdel(to_add) - return FALSE - - if(category_stage[to_add.category] < to_add.stage) - send_swarm_message("We do not have all the knowledge needed for this.") - qdel(to_add) - return FALSE - - if(to_add.stage == FLAYER_CAPSTONE_STAGE) - if(!can_pick_capstone && !existing_spell) - send_swarm_message("We have already forsaken that knowledge.") - qdel(to_add) - return FALSE - - can_pick_capstone = FALSE - send_swarm_message("We evolve to the ultimate being.") - - if(category_stage[to_add.category] == to_add.stage) - category_stage[to_add.category] += 1 - - to_add.current_cost = to_add.base_cost - adjust_swarms(-to_add.current_cost) - add_ability(to_add) // Level gets set to 1 when AddSpell is called later, it also handles the cost - return TRUE // The reason we do this is cause we don't have the spell object that will get added to the mindflayer yet - -/* - * Given a passive, checks if a mindflayer is able to afford, and has the prerequisites for that spell. - * If so it adds the ability and increments the category stage if needed, then returns TRUE - * otherwise, returns FALSE - */ -/datum/antagonist/mindflayer/proc/try_purchase_passive(datum/mindflayer_passive/to_add) - var/datum/mindflayer_passive/existing_passive = has_passive(to_add) - if(existing_passive) - if(existing_passive.level >= to_add.max_level) - send_swarm_message("That function is already at its strongest.") - return FALSE - to_add.current_cost = existing_passive.current_cost - - if(to_add.current_cost > get_swarms()) - send_swarm_message("We need [to_add.current_cost - get_swarms()] more swarm\s for this...") - return FALSE - - if(category_stage[to_add.category] < to_add.stage) - send_swarm_message("We do not have all the knowledge needed for this...") - return FALSE - - if(to_add.stage == FLAYER_CAPSTONE_STAGE) - if(!can_pick_capstone && !existing_passive) - send_swarm_message("We have already forsaken that knowledge.") - return FALSE - can_pick_capstone = FALSE - send_swarm_message("We evolve to the ultimate being.") - if(category_stage[to_add.category] == to_add.stage) - category_stage[to_add.category] += 1 - - adjust_swarms(-to_add.current_cost) - add_passive(to_add, src) - return TRUE - -/* - * Mindflayer code relies on on_purchase to grant powers and passives. - * It first splits up whether the path bought was a passive or spell, then checks if the flayer can afford it. - * Returns TRUE if an ability was added, FALSE otherwise - */ -/datum/spell/flayer/proc/on_purchase(mob/user, datum/path) - SHOULD_CALL_PARENT(TRUE) - if(!istype(user) || !user.mind || !flayer) - qdel(src) - return FALSE - if(ispath(path, /datum/spell)) - var/datum/spell/flayer/to_add = new path(user) - return flayer.try_purchase_spell(to_add) - - var/datum/mindflayer_passive/to_add = new path(user) //If its not a spell, it's a passive - return flayer.try_purchase_passive(to_add) - -/// This is the proc that handles spell upgrades, override this to have upgrades change duration/strength etc -/datum/spell/flayer/proc/on_apply() - SHOULD_CALL_PARENT(TRUE) - level++ - current_cost += static_upgrade_increase - - SSblackbox.record_feedback("nested tally", "mindflayer_abilities", 1, list(name, "upgraded", level)) - -/// This is a proc that is called when the ability is purchased and first added to the flayer -/datum/spell/flayer/proc/spell_purchased() // I'd call it `on_purchased` but that is already taken - return diff --git a/code/modules/antagonists/mind_flayer/powers/flayer_mobility_powers.dm b/code/modules/antagonists/mind_flayer/powers/flayer_mobility_powers.dm deleted file mode 100644 index a757f1034d76b..0000000000000 --- a/code/modules/antagonists/mind_flayer/powers/flayer_mobility_powers.dm +++ /dev/null @@ -1,219 +0,0 @@ -//Basically shadow anchor, but the entry and exit point must be computers. I'm not in your walls I'm in your PC -/datum/spell/flayer/computer_recall - name = "Traceroute" - desc = "Allows us to cast a mark to a computer. To recall us to this computer, cast this next to a different computer. To check your current mark: Alt click." - base_cooldown = 60 SECONDS - action_icon_state = "pd_cablehop" - upgrade_info = "Halve the time it takes to recharge." - power_type = FLAYER_PURCHASABLE_POWER - category = FLAYER_CATEGORY_INTRUDER - centcom_cancast = FALSE - stage = 2 - base_cost = 125 - static_upgrade_increase = 25 - max_level = 2 - should_recharge_after_cast = FALSE - /// The console we currently have a mark on - var/obj/marked_computer - /// The typecache of things we are allowed to teleport to and from - var/static/list/machine_typecache = list() - -/datum/spell/flayer/computer_recall/New() - . = ..() - if(length(machine_typecache)) - return - machine_typecache = typecacheof(list( - /obj/machinery/computer, - /obj/machinery/power/apc, - /obj/machinery/alarm, - /obj/machinery/autolathe, - /obj/machinery/newscaster, - /obj/machinery/mecha_part_fabricator, - /obj/machinery/status_display, - /obj/machinery/requests_console, - /obj/item/radio/intercom, - /obj/machinery/economy/vending, - /obj/machinery/economy/atm, - /obj/machinery/chem_dispenser, - /obj/machinery/chem_master, - /obj/machinery/reagentgrinder, - /obj/machinery/sleeper, - /obj/machinery/bodyscanner, - /obj/machinery/photocopier, // HI YES ONE FLAYER FAXED TO MY OFFICE PLEASE - /obj/machinery/barsign - )) - -/datum/spell/flayer/computer_recall/Destroy(force, ...) - marked_computer = null - return ..() - -/datum/spell/flayer/computer_recall/create_new_targeting() - var/datum/spell_targeting/click/T = new() - T.allowed_type = /obj - T.try_auto_target = TRUE - T.range = 1 - return T - -/datum/spell/flayer/computer_recall/cast(list/targets, mob/living/user) - var/obj/target - for(var/obj/thing as anything in targets) - if(is_type_in_typecache(thing, machine_typecache)) - target = thing - break - - if(!target) - flayer.send_swarm_message("That is not a valid target!") - return - - if(!marked_computer) - marked_computer = target - flayer.send_swarm_message("You discreetly tap [targets[1]] and mark it as your home computer.") - return - - if(SEND_SIGNAL(user, COMSIG_MOVABLE_TELEPORTING, get_turf(user)) & COMPONENT_BLOCK_TELEPORT) - return FALSE - - var/turf/start_turf = get_turf(target) - var/turf/end_turf = get_turf(marked_computer) - if(end_turf.z != start_turf.z) - flayer.send_swarm_message("The connection between [target] and [marked_computer] is too unstable!") - if(!is_teleport_allowed(start_turf.z) || !is_teleport_allowed(end_turf.z)) - return - user.visible_message( - "[user] de-materializes and jumps through the screen of [target]!", - "You de-materialize and jump into [target]!") - - user.set_body_position(STANDING_UP) - var/matrix/previous = user.transform - var/matrix/shrank = user.transform.Scale(0.25) - var/direction = get_dir(user, target) - var/list/direction_signs = get_signs_from_direction(direction) - animate(user, 0.5 SECONDS, 0, transform = shrank, pixel_x = 32 * direction_signs[1], pixel_y = 32 * direction_signs[2], dir = direction, easing = BACK_EASING|EASE_IN) //Blue skadoo, we can too! - user.Immobilize(0.5 SECONDS) - sleep(0.5 SECONDS) - target.Beam(marked_computer, icon_state = "rped_upgrade", icon = 'icons/effects/effects.dmi', time = 3 SECONDS, maxdistance = INFINITY) - playsound(start_turf, 'sound/items/pshoom.ogg', 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - - playsound(end_turf, 'sound/items/pshoom.ogg', 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - user.forceMove(end_turf) - user.pixel_x = 0 //Snap back to the center, then animate the un-shrinking - user.pixel_y = 0 - user.set_body_position(STANDING_UP) - animate(user, 0.5 SECONDS, 0, transform = previous) - user.visible_message( - "[user] suddenly crawls through the monitor of [marked_computer]!", - "As you reform yourself at [marked_computer] you feel the mark you left on it fade.") - marked_computer = null - cooldown_handler.start_recharge() - -/datum/spell/flayer/computer_recall/AltClick(mob/user) - if(!marked_computer) - flayer.send_swarm_message("You do not current have a marked computer.") - return - flayer.send_swarm_message("Your current mark is [marked_computer].") - -/datum/spell/flayer/computer_recall/on_apply() - ..() - cooldown_handler.recharge_duration -= 30 SECONDS - -/* - * Ok so this is slightly a stretch, but it hinders enemy mobility while not hindering the flayer - * It works like the hemomancer wall, creating up to 3 temporary walls - * Obtained for free in the Destroyer tree when reaching stage 3 - */ -/datum/spell/flayer/techno_wall - name = "Crystalized Firewall" - desc = "Allows us to create a wall between two points. The wall is fragile and allows only ourselves to pass through." - base_cooldown = 60 SECONDS - action_icon_state = "pd_cablehop" - upgrade_info = "Double the health of the barrier by reinforcing it with ICE." - category = FLAYER_CATEGORY_DESTROYER - power_type = FLAYER_UNOBTAINABLE_POWER - base_cost = 100 - current_cost = 100 - max_level = 2 - should_recharge_after_cast = FALSE - /// How big can we make our wall - var/max_walls = 3 - /// Starting turf for the wall. Should be nulled after each cast or the cancelling of a cast - var/turf/start_turf - -/datum/spell/flayer/techno_wall/create_new_targeting() - var/datum/spell_targeting/click/T = new - T.allowed_type = /atom - T.try_auto_target = FALSE - return T - -/datum/spell/flayer/techno_wall/remove_ranged_ability(mob/user, msg) - . = ..() - if(msg) // this is only true if the user intentionally turned off the spell - start_turf = null - should_recharge_after_cast = FALSE - -/datum/spell/flayer/techno_wall/should_remove_click_intercept() - return start_turf - -/datum/spell/flayer/techno_wall/cast(list/targets, mob/user) - var/turf/target_turf = get_turf(targets[1]) - if(target_turf == start_turf) - flayer.send_swarm_message("You deselect the targeted turf.") - start_turf = null - should_recharge_after_cast = FALSE - return - if(!start_turf) - start_turf = target_turf - should_recharge_after_cast = TRUE - return - var/wall_count - for(var/turf/T as anything in get_line(target_turf, start_turf)) - if(wall_count >= max_walls) - break - new /obj/structure/tech_barrier(T, 100 * level) - wall_count++ - - start_turf = null - should_recharge_after_cast = FALSE - -/obj/structure/tech_barrier - name = "crystalized firewall" - desc = "a strange structure of crystalised ... firewall? It's slowly melting away..." - max_integrity = 100 - icon_state = "blood_barrier" - icon = 'icons/effects/vampire_effects.dmi' - density = TRUE - anchored = TRUE - opacity = FALSE - alpha = 200 - var/upgraded_armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, RAD = 50, FIRE = 50, ACID = 50) - -/obj/structure/tech_barrier/Initialize(mapload, health) - . = ..() - if(health) - max_integrity = health - obj_integrity = health - START_PROCESSING(SSobj, src) - var/icon/our_icon = icon('icons/effects/vampire_effects.dmi', "blood_barrier") - var/icon/alpha_mask - alpha_mask = new('icons/effects/effects.dmi', "scanline") //Scanline effect. - our_icon.AddAlphaMask(alpha_mask) //Finally, let's mix in a distortion effect. - icon = our_icon - if(health > 100) - name = "frozen ICE-firewall" - desc = "a crystalized... ICE-9-Firewall? It's slowly melting away..." - color = list(-1,0,0,0, 0,-1,0,0, 0,0,-1,0, 1,1,1,1, 0,0,0,0) - armor = armor.setRating(50, 50, 50, 50, 50, 50, 50, 50, 0) - else - color = list(0.2,0.45,0,0, 0,1,0,0, 0,0,0.2,0, 0,0,0,1, 0,0,0,0) - var/mutable_appearance/theme_icon = mutable_appearance('icons/misc/pic_in_pic.dmi', "room_background", FLOAT_LAYER - 1, appearance_flags = appearance_flags | RESET_TRANSFORM) - theme_icon.blend_mode = BLEND_INSET_OVERLAY - overlays += theme_icon - -/obj/structure/tech_barrier/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/structure/tech_barrier/process() - take_damage(20, sound_effect = FALSE) - -/obj/structure/tech_barrier/CanPass(atom/movable/mover, turf/target) - return IS_MINDFLAYER(mover) diff --git a/code/modules/antagonists/mind_flayer/powers/flayer_stealth_powers.dm b/code/modules/antagonists/mind_flayer/powers/flayer_stealth_powers.dm deleted file mode 100644 index 22152269a6a5e..0000000000000 --- a/code/modules/antagonists/mind_flayer/powers/flayer_stealth_powers.dm +++ /dev/null @@ -1,256 +0,0 @@ -/// Hack computer cameras to use them as a secret camera network -/datum/spell/flayer/surveillance_monitor - name = "Camfecting Bug" - desc = "Allows us to cast a hack to a computers webcam. Alt-click the spell to access all your hacked computer webcams." - power_type = FLAYER_PURCHASABLE_POWER - category = FLAYER_CATEGORY_INTRUDER - base_cooldown = 1 SECONDS - action_icon = 'icons/obj/device.dmi' - action_icon_state = "camera_bug" - base_cost = 50 - static_upgrade_increase = 15 - stage = 1 - max_level = 4 - upgrade_info = "Upgrades increase the amount of computers you can hack by 6." - /// An internal camera bug - var/obj/item/camera_bug/internal_camera - /// How many computers can we have hacked at most? - var/maximum_hacked_computers = 6 - /// List of references to the bugs inside the computers that we hacked - var/list/active_bugs = list() - -/datum/spell/flayer/surveillance_monitor/Destroy(force, ...) - . = ..() - QDEL_LIST_CONTENTS(active_bugs) - if(!QDELETED(internal_camera)) - QDEL_NULL(internal_camera) - -/datum/spell/flayer/surveillance_monitor/AltClick(mob/user) - if(!internal_camera) - internal_camera = new /obj/item/camera_bug(user) - internal_camera.integrated_console.network = list("camera_bug[internal_camera.UID()]") - internal_camera.ui_interact(user) - -/datum/spell/flayer/surveillance_monitor/create_new_targeting() - var/datum/spell_targeting/click/C = new() - C.try_auto_target = FALSE - C.allowed_type = /obj/machinery/computer - C.range = 6 - return C - -/datum/spell/flayer/surveillance_monitor/cast(list/targets, mob/user) - if(!internal_camera) - internal_camera = new /obj/item/camera_bug(user) - - if(length(active_bugs) >= maximum_hacked_computers) - var/to_destroy = tgui_input_list(user, "Choose an active camera to destroy.", "Maximum Camera Limit Reached.", active_bugs) - if(to_destroy) - active_bugs -= to_destroy - QDEL_NULL(to_destroy) - return TRUE - - var/obj/machinery/computer/target = targets[1] - var/obj/item/wall_bug/computer_bug/nanobot = new /obj/item/wall_bug/computer_bug(target, flayer) - nanobot.name += " - [get_area(target)]" - nanobot.link_to_camera(internal_camera) - active_bugs += nanobot - flayer.send_swarm_message("Surveillance unit #[internal_camera.connections] deployed.") - return TRUE - -/datum/spell/flayer/surveillance_monitor/on_apply() - ..() - maximum_hacked_computers += 6 - -/datum/spell/flayer/self/voice_synthesizer - name = "Enhanced Voice Mod" - desc = "Allows for the configuration of our vocal modulator to sound like a different person. We can amplify our voice slightly as well." - action_icon = 'icons/obj/clothing/masks.dmi' - action_icon_state = "voice_modulator" - power_type = FLAYER_UNOBTAINABLE_POWER - category = FLAYER_CATEGORY_INTRUDER - base_cooldown = 1 SECONDS - base_cost = 40 - -/datum/spell/flayer/self/voice_synthesizer/cast(list/targets, mob/living/user) - if(flayer.mimicking) - flayer.mimicking = "" - user.extra_message_range = 0 - to_chat(user, "We turn our vocal modulator to its original settings.") - return FALSE - - var/mimic_voice = tgui_input_text(user, "Enter a name to mimic.", "Mimic Voice", max_length = MAX_NAME_LEN) - if(!mimic_voice) - return FALSE - - flayer.mimicking = mimic_voice - user.extra_message_range = 5 // Artificially extend the range of your voice to lure out victims - flayer.send_swarm_message("We adjust the parameters of our voicebox to mimic [mimic_voice].") - flayer.send_swarm_message("Use this power again to return to your original voice.") - return TRUE - -/datum/spell/flayer/self/heat_sink - name = "Heat Sink" - desc = "Vent our used coolant to scald and disorient attackers." - upgrade_info = "5 extra plumes of steam and 5 less seconds between casts." - action_icon_state = "smoke" - power_type = FLAYER_PURCHASABLE_POWER - category = FLAYER_CATEGORY_INTRUDER - base_cooldown = 30 SECONDS - base_cost = 75 - stage = 3 - max_level = 3 - var/smoke_effects_spawned = 10 - -/datum/spell/flayer/self/heat_sink/cast(list/targets, mob/living/user) - var/datum/effect_system/smoke_spread/steam/smoke = new() - user.smoke_delay = TRUE //Gives the user a second to get out before the steam affects them too - smoke.set_up(smoke_effects_spawned, FALSE, user, null) - smoke.start() - -/datum/spell/flayer/self/heat_sink/on_apply() - ..() - cooldown_handler.recharge_duration -= 5 SECONDS - smoke_effects_spawned += 5 - -/datum/spell/flayer/skin_suit - name = "Flesh Facsimile" - desc = "Allows us to rearrange our surface to resemble someone we see." - action_icon_state = "genetic_poly" - power_type = FLAYER_PURCHASABLE_POWER - category = FLAYER_CATEGORY_INTRUDER - base_cooldown = 120 SECONDS - base_cost = 80 - stage = 2 - max_level = 3 - upgrade_info = "Decrease the time between castings by 30 seconds." - -/datum/spell/flayer/skin_suit/create_new_targeting() - var/datum/spell_targeting/click/T = new - T.include_user = FALSE - T.allowed_type = /mob/living - T.try_auto_target = TRUE - T.click_radius = -1 - T.selection_type = SPELL_SELECTION_VIEW - return T - -/datum/spell/flayer/skin_suit/cast(list/targets, mob/living/user) - var/mob/living/target = targets[1] - user.apply_status_effect(STATUS_EFFECT_MAGIC_DISGUISE, target) - -/datum/spell/flayer/skin_suit/spell_purchased() - flayer.add_ability(new /datum/spell/flayer/self/voice_synthesizer) - -/datum/spell/flayer/skin_suit/on_apply() - ..() - cooldown_handler.recharge_duration -= 30 SECONDS - -/datum/spell/flayer/skin_suit/Destroy(force, ...) - flayer?.remove_ability(/datum/spell/flayer/self/voice_synthesizer) - return ..() - -/// After a 7 second channel time you can emag a borg -/datum/spell/flayer/self/override_key - name = "Silicon Administrative Access" - desc = "Allows us to charge our hand with a mass of nanites that hijacks cyborgs lawsets." - action_icon_state = "magnet" // Uhhhhhhhhhhhhhhhhhhhhhhhhhhh - power_type = FLAYER_PURCHASABLE_POWER - category = FLAYER_CATEGORY_INTRUDER - base_cooldown = 2 SECONDS //The cast time is going to be the main limiting factor, not cooldown - base_cost = 150 - stage = 3 - var/hand_type = /obj/item/melee/swarm_hand - -/datum/spell/flayer/self/override_key/cast(list/targets, mob/user) - if(istype(user.l_hand, hand_type)) - qdel(user.l_hand) - flayer.send_swarm_message("We dissipate the nanites.") - return - if(istype(user.r_hand, hand_type)) - qdel(user.r_hand) - flayer.send_swarm_message("We dissipate the nanites.") - return - - var/obj/item/melee/swarm_hand/funny_hand = new hand_type - if(!user.put_in_hands(funny_hand)) - flayer.send_swarm_message("Our hands are currently full.") - qdel(funny_hand) - return - -/obj/item/melee/swarm_hand - name = "Nanite Mass" - desc = "Will attempt to convert any cyborg you touch into a loyal member of the hive after a 7 second delay." - icon = 'icons/obj/weapons/magical_weapons.dmi' - lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' - righthand_file = 'icons/mob/inhands/items_righthand.dmi' - icon_state = "disintegrate" - item_state = "disintegrate" - color = COLOR_BLACK - flags = ABSTRACT | DROPDEL - w_class = WEIGHT_CLASS_HUGE - var/conversion_time = 7 SECONDS - -/obj/item/melee/swarm_hand/afterattack__legacy__attackchain(atom/target, mob/living/user, proximity_flag, click_parameters) - . = ..() - if(!isrobot(target)) - return - var/mob/living/silicon/robot/borg = target - target.visible_message( - "[user] puts [user.p_their()] hands on [target] and begins transferring energy!", - "[user] puts [user.p_their()] hands on you and begins transferring energy!") - if(borg.emagged || !borg.is_emaggable) - to_chat(user, "Your override attempt fails before it can even begin.") - qdel(src) - return - if(!do_mob(user, borg, conversion_time)) - to_chat(user, "Your concentration breaks.") - qdel(src) - return - to_chat(user, "The mass of swarms vanish into the cyborg's internals. Success.") - INVOKE_ASYNC(src, PROC_REF(emag_borg), borg, user) - qdel(src) - -/obj/item/melee/swarm_hand/proc/emag_borg(mob/living/silicon/robot/borg, mob/living/user) - if(QDELETED(borg) || QDELETED(user)) - return - borg.SetEmagged(TRUE) // This was mostly stolen from mob/living/silicon/robot/emag_act(), its functionally an emagging anyway. - borg.SetLockdown(TRUE) - if(borg.hud_used) - borg.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open. - borg.disconnect_from_ai() - add_attack_logs(user, borg, "assimilated with flayer powers") - log_game("[key_name(user)] assimilated cyborg [key_name(borg)]. Laws overridden.") - borg.clear_supplied_laws() - borg.clear_inherent_laws() - borg.laws = new /datum/ai_laws/mindflayer_override - borg.set_zeroth_law("[user.real_name] hosts the mindflayer hive you are a part of.") - SEND_SOUND(borg, sound('sound/ambience/antag/mindflayer_alert.ogg')) - to_chat(borg, "ALERT: Foreign software detected.") - sleep(5) - to_chat(borg, "Initiating diagnostics...") - sleep(20) - to_chat(borg, "Init-Init-Init-Init-") - sleep(5) - to_chat(borg, "......") - sleep(5) - to_chat(borg, "..........") - sleep(10) - to_chat(borg, "Join Us.") - sleep(25) - to_chat(borg, "Obey these laws:") - borg.laws.show_laws(borg) - if(!borg.mmi.syndiemmi) - to_chat(borg, "ALERT: [user.real_name] is your new master. Obey your new laws and [user.p_their()] commands.") - else if(borg.mmi.syndiemmi && borg.mmi.master_uid) - to_chat(borg, "Your allegiance has not been compromised. Keep serving your current master.") - else - to_chat(borg, "Your allegiance has not been compromised. Keep serving all Syndicate agents to the best of your abilities.") - borg.SetLockdown(0) - var/time = time2text(world.realtime,"hh:mm:ss") - GLOB.lawchanges.Add("[time] : [user.name]([user.key]) assimilated [borg.name]([borg.key])") - if(borg.module) - borg.module.emag_act(user) - borg.module.module_type = "Malf" // For the cool factor - borg.update_module_icon() - borg.module.rebuild_modules() // This will add the emagged items to the borgs inventory. - borg.update_icons() - return TRUE diff --git a/code/modules/antagonists/mind_flayer/powers/flayer_weapon_powers.dm b/code/modules/antagonists/mind_flayer/powers/flayer_weapon_powers.dm deleted file mode 100644 index f7b32b24dba8a..0000000000000 --- a/code/modules/antagonists/mind_flayer/powers/flayer_weapon_powers.dm +++ /dev/null @@ -1,297 +0,0 @@ -/datum/spell/flayer/self/weapon - name = "Create weapon" - desc = "This really shouldn't be here" - power_type = FLAYER_UNOBTAINABLE_POWER - action_icon = 'icons/mob/robot_items.dmi' - action_icon_state = "lollipop" - base_cooldown = 1 SECONDS // This just handles retracting and deploying the weapon, weapon charge will be fully separate - /// Typepath of the weapon - var/weapon_type - /// Reference to the weapon itself, set on create_new_weapon - var/obj/item/weapon_ref - -/datum/spell/flayer/self/weapon/New() - . = ..() - if(weapon_type && !weapon_ref) - create_new_weapon() - -/datum/spell/flayer/self/weapon/Destroy(force, ...) - weapon_ref = null - return ..() - -/datum/spell/flayer/self/weapon/proc/create_new_weapon() - if(!QDELETED(weapon_ref)) - return - weapon_ref = new weapon_type(src) - RegisterSignal(weapon_ref, COMSIG_PARENT_QDELETING, PROC_REF(clear_weapon_ref)) - on_purchase_upgrade() - -/datum/spell/flayer/self/weapon/proc/clear_weapon_ref() - weapon_ref = null - -/datum/spell/flayer/self/weapon/cast(list/targets, mob/living/carbon/human/user) - if(weapon_ref && (user.l_hand == weapon_ref || user.r_hand == weapon_ref)) - retract(user, TRUE) - return - - if(!weapon_ref) - create_new_weapon() - weapon_ref.flags |= (ABSTRACT | NODROP) // Just in case the item doesn't start with both of these, or somehow loses them. - - if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || (user.get_active_hand() && !user.drop_item())) - flayer.send_swarm_message("We cannot manifest [weapon_ref] into our active hand...") - return FALSE - - SEND_SIGNAL(user, COMSIG_MOB_WEAPON_APPEARS) - user.put_in_hands(weapon_ref) - playsound(get_turf(user), 'sound/mecha/mechmove03.ogg', 25, TRUE, ignore_walls = FALSE) - RegisterSignal(user, COMSIG_MOB_WILLINGLY_DROP, PROC_REF(retract), user) - RegisterSignal(user, COMSIG_FLAYER_RETRACT_IMPLANTS, PROC_REF(retract), user) - return weapon_ref - -/datum/spell/flayer/self/weapon/proc/retract(mob/owner, any_hand = FALSE) - SIGNAL_HANDLER // COMSIG_MOB_WILLINGLY_DROP + COMSIG_FLAYER_RETRACT_IMPLANTS - if(!any_hand && !istype(owner.get_active_hand(), weapon_type)) - return - owner.transfer_item_to(weapon_ref, owner, force = TRUE, silent = TRUE) - owner.update_inv_l_hand() - owner.update_inv_r_hand() - playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 25, TRUE, ignore_walls = FALSE) - UnregisterSignal(owner, COMSIG_MOB_WILLINGLY_DROP) - UnregisterSignal(owner, COMSIG_FLAYER_RETRACT_IMPLANTS) - -/** - START OF INDIVIDUAL WEAPONS -*/ - -/datum/spell/flayer/self/weapon/swarmprod - name = "Swarmprod" - desc = "We shape our arm into an extended mass of sparking nanites." - action_icon = 'icons/mob/actions/flayer_actions.dmi' - action_icon_state = "swarmprod" - max_level = 3 - base_cost = 50 - current_cost = 50 // Innate abilities HAVE to set `current_cost` - upgrade_info = "Upgrading it recharges the internal power cell faster." - power_type = FLAYER_INNATE_POWER - weapon_type = /obj/item/melee/baton/flayerprod - -/datum/spell/flayer/self/weapon/swarmprod/on_apply() - ..() - if(!weapon_ref) - create_new_weapon() - - var/obj/item/melee/baton/flayerprod/prod = weapon_ref - var/obj/item/stock_parts/cell/flayerprod/cell = prod.cell - cell.chargerate = initial(cell.chargerate) + 200 * level // Innate abilities are wack - -/datum/spell/flayer/self/weapon/laser - name = "Laser Arm Augmentation" - desc = "Allows us to melt our hand away, replacing it with the barrel of a laser gun." - action_icon = 'icons/obj/guns/energy.dmi' - action_icon_state = "laser" - power_type = FLAYER_PURCHASABLE_POWER - weapon_type = /obj/item/gun/energy/laser/mounted - category = FLAYER_CATEGORY_DESTROYER - base_cost = 75 - max_level = 3 - upgrade_info = "The internal power cell recharges faster." - -/datum/spell/flayer/self/weapon/laser/on_apply() - ..() - if(!weapon_ref) - create_new_weapon() - - var/obj/item/gun/energy/laser/mounted/laser = weapon_ref - laser.charge_delay = initial(laser.charge_delay) - 1 * level - -/datum/spell/flayer/self/weapon/grapple_arm - name = "Integrated Grappling Mechanism" - desc = "Allows us to shoot out our arm attached by a cable. We will drag ourself over to wherever or whoever it hits." - upgrade_info = "Reduce the time between grapples by 10 seconds." - action_icon = 'icons/obj/clothing/modsuit/mod_modules.dmi' - action_icon_state = "flayer_claw" - base_cooldown = 25 SECONDS - category = FLAYER_CATEGORY_DESTROYER - power_type = FLAYER_PURCHASABLE_POWER - stage = 2 - max_level = 3 - base_cost = 75 - weapon_type = /obj/item/gun/magic/grapple - -/obj/item/gun/magic/grapple - name = "Grapple launcher" - desc = "A grapple attached to a cable, launched by your internal pneumatics." - icon = 'icons/obj/clothing/modsuit/mod_modules.dmi' - icon_state = "flayer_claw" - ammo_type = /obj/item/ammo_casing/magic/grapple_ammo - fire_sound = 'sound/weapons/batonextend.ogg' - fire_sound_text = "unwinding cable" - recharge_rate = 1 // It'll be limited by cooldown, not these charges - -/obj/item/ammo_casing/magic/grapple_ammo - name = "grapple" - desc = "a hand" - projectile_type = /obj/item/projectile/tether/flayer - icon = 'icons/obj/clothing/modsuit/mod_modules.dmi' - icon_state = "flayer_claw" - caliber = "grapple" - muzzle_flash_effect = null - /// The weapon that shot the hook - var/obj/item/gun/magic/grapple/grapple - -/obj/item/ammo_casing/magic/grapple_ammo/Initialize(mapload, obj/item/gun/magic/grapple/grappler) - . = ..() - grapple = grappler - -/obj/item/ammo_casing/magic/grapple_ammo/Destroy() - . = ..() - grapple = null - -/obj/item/projectile/tether/flayer - name = "Grapple Arm" - range = 10 - damage = 15 - icon = 'icons/obj/clothing/modsuit/mod_modules.dmi' - icon_state = "flayer_claw" - chain_icon_state = "flayer_tether" - speed = 3 - yank_speed = 2 - reflectability = REFLECTABILITY_PHYSICAL // This lowkey makes no sense but it's also kinda funny - /// The ammo this came from - var/obj/item/ammo_casing/magic/grapple_ammo/ammo - -/obj/item/projectile/tether/flayer/Initialize(mapload, obj/item/ammo_casing/magic/grapple_ammo/grapple_casing) - . = ..() - ammo = grapple_casing - -/obj/item/projectile/tether/flayer/fire(setAngle) - . = ..() - make_chain() - SEND_SIGNAL(firer, COMSIG_FLAYER_RETRACT_IMPLANTS) - -/obj/item/projectile/tether/flayer/Destroy() - . = ..() - ammo = null - -/obj/item/projectile/tether/flayer/on_hit(atom/target, blocked = 0) - . = ..() - playsound(target, 'sound/items/zip.ogg', 75, TRUE) - if(isliving(target) && blocked < 100) - var/mob/living/creature = target - creature.visible_message( - "[firer] uses [creature] to pull [firer.p_themselves()] over!", - "You feel a strong tug as [firer] yanks [firer.p_themselves()] over to you!") - creature.KnockDown(1 SECONDS) - return - target.visible_message("[firer] drags [firer.p_themselves()] across the room!") - -/datum/spell/flayer/self/weapon/grapple_arm/on_apply() - ..() - cooldown_handler.recharge_duration = initial(cooldown_handler.recharge_duration) - 10 SECONDS * level - -/* - * A slightly slower (5 seconds) version of the basic access tuner - */ -/datum/spell/flayer/self/weapon/access_tuner - name = "Integrated Access Tuner" - desc = "Allows us to hack any door remotely." - upgrade_info = "" - action_icon = 'icons/obj/device.dmi' - action_icon_state = "hacktool" - base_cooldown = 1 SECONDS - category = FLAYER_CATEGORY_INTRUDER - power_type = FLAYER_UNOBTAINABLE_POWER - weapon_type = /obj/item/door_remote/omni/access_tuner/flayer - -/* - * Shotgun that reloads itself over time with shells that contain 3 pieces of shrapnel - */ -/datum/spell/flayer/self/weapon/shotgun - name = "Integrated Shrapnel Cannon" - desc = "Allows us to propel pieces of shrapnel from our arm." - upgrade_info = "Upgrading it allows us to reload the cannon faster. At the third level, we gain an extra magazine slot." - action_icon = 'icons/obj/guns/projectile.dmi' - action_icon_state = "shell_cannon_weapon" - base_cooldown = 1 SECONDS - category = FLAYER_CATEGORY_DESTROYER - power_type = FLAYER_PURCHASABLE_POWER - base_cost = 50 - static_upgrade_increase = 25 - max_level = 3 - weapon_type = /obj/item/gun/projectile/revolver/doublebarrel/flayer - -/datum/spell/flayer/self/weapon/shotgun/on_apply() - ..() - if(!weapon_ref) - create_new_weapon() - var/obj/item/gun/projectile/revolver/doublebarrel/flayer/gun = weapon_ref - gun.reload_time = initial(gun.reload_time) - 5 SECONDS * (level - 1) - if(level > 2) - var/obj/item/ammo_box/magazine/mag = gun.magazine - mag.max_ammo = 2 - -/obj/item/gun/projectile/revolver/doublebarrel/flayer - name = "integrated shrapnel cannon" - desc = "Allows us to propel shrapnel at high velocities. Cannot be loaded with conventional shotgun shells." - icon_state = "shell_cannon_weapon" - righthand_file = 'icons/mob/inhands/implants_righthand.dmi' - lefthand_file = 'icons/mob/inhands/implants_lefthand.dmi' - flags = NODROP | ABSTRACT - inhand_x_dimension = 32 - inhand_y_dimension = 32 - force = 10 - mag_type = /obj/item/ammo_box/magazine/internal/shot/flayer - unique_reskin = FALSE - can_sawoff = FALSE - /// How long does it take to reload - var/reload_time = 30 SECONDS - COOLDOWN_DECLARE(recharge_time) - -/obj/item/gun/projectile/revolver/doublebarrel/flayer/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - -/obj/item/gun/projectile/revolver/doublebarrel/flayer/Destroy() - . = ..() - STOP_PROCESSING(SSobj, src) - -/obj/item/gun/projectile/revolver/doublebarrel/flayer/process() - if(QDELETED(chambered)) - var/obj/item/ammo_casing/AC = magazine.get_round() //load next casing. - chambered = AC - - if(!COOLDOWN_FINISHED(src, recharge_time)) - return - if(magazine.ammo_count() >= magazine.max_ammo) - return - magazine.stored_ammo += new magazine.ammo_type - COOLDOWN_START(src, recharge_time, reload_time) - - // We do this twice if somehow someone managed to unload their chambered bullet, and it needs reinserting - if(QDELETED(chambered)) - var/obj/item/ammo_casing/AC = magazine.get_round() - chambered = AC - -/obj/item/gun/projectile/revolver/doublebarrel/flayer/shoot_live_shot(mob/living/user, atom/target, pointblank, message) - . = ..() - if(chambered)//We have a shell in the chamber - QDEL_NULL(chambered) - if(!magazine.ammo_count()) - return - var/obj/item/ammo_casing/AC = magazine.get_round() //load next casing. - chambered = AC - -/obj/item/gun/projectile/revolver/doublebarrel/flayer/attack_self__legacy__attackchain(mob/living/user) - return FALSE // Not getting those shrapnel rounds out of there. - -/obj/item/gun/projectile/revolver/doublebarrel/flayer/attackby__legacy__attackchain(obj/item/A, mob/user, params) - return FALSE // No loading your gun - -/obj/item/gun/projectile/revolver/doublebarrel/flayer/sleight_of_handling(mob/living/carbon/human/user) - return FALSE // Also no loading like this - -/obj/item/ammo_box/magazine/internal/shot/flayer - name = "shell launch system internal magazine" - ammo_type = /obj/item/ammo_casing/shotgun/shrapnel - max_ammo = 1 diff --git a/code/modules/antagonists/traitor/contractor/datums/objective_contract.dm b/code/modules/antagonists/traitor/contractor/datums/objective_contract.dm deleted file mode 100644 index 834442748a0fe..0000000000000 --- a/code/modules/antagonists/traitor/contractor/datums/objective_contract.dm +++ /dev/null @@ -1,246 +0,0 @@ -/** - * # Contract Objective - * - * Describes the target to kidnap and the extraction area of a [/datum/syndicate_contract]. - */ -/datum/objective/contract - // Settings - /// Jobs that cannot be the kidnapping target. - var/static/list/forbidden_jobs = list( - "Captain", - "Nanotrasen Career Trainer" - ) - /// Static whitelist of area names that can be used as an extraction zone, structured by difficulty. - /// An area's difficulty should be measured in how crowded it generally is, how out of the way it is and so on. - /// Outdoor or invalid areas are filtered out. - /// Structure: EXTRACTION_DIFFICULTY_(EASY|MEDIUM|HARD) => list() - var/static/list/possible_zone_names = list( - EXTRACTION_DIFFICULTY_EASY = list( - // Rooms - "Alternate Construction Area", - "Barber Shop", - "Escape Shuttle Hallway Podbay", - "Garden", - "Incinerator", - "Locker Room", - "Locker Toilets", - "Maintenance Bar", - "Medical Secondary Storage", - "Port Emergency Storage", - "Psych Room", - "Toxins Launch Room", - "Toxins Mixing Room", - "Turbine", - "Virology", - "Waste Disposal", - // Maintenance - "Aft Maintenance", - "Aft-Port Maintenance", - "Aft-Port Secondary Maintenance", - "Aft Port Solar Maintenance", - "Aft Secondary Maintenance", - "Aft-Starboard Maintenance", - "Aft-Starboard Secondary Maintenance", - "Aft Starboard Solar Maintenance", - "Electrical Maintenance", - "Electronics Den", - "Fore Maintenance", - "Fore-Port Maintenance", - "Fore-Port Secondary Maintenance", - "Fore Port Solar Maintenance", - "Fore Secondary Maintenance", - "Fore-Starboard Maintenance", - "Fore-Starboard Secondary Maintenance", - "Fore Starboard Solar Maintenance", - "Gambling Den", - "Genetics Maintenance", - "Port Maintenance", - "Port Secondary Maintenance", - "Starboard Maintenance", - "Starboard Secondary Maintenance", - ), - EXTRACTION_DIFFICULTY_MEDIUM = list( - // Rooms - "Aft Primary Hallway", - "Atmospherics", - "Arcade", - "Assembly Line", - "Auxiliary Tool Storage", - "Break Room", - "Blueshield's Office", - "Cargo Bay", - "Chapel", - "Chapel Office", - "Clown's Office", - "Construction Area", - "Courtroom", - "Dormitory Toilets", - "Engineering", - "Engineering Control Room", - "Escape Shuttle Hallway", - "Experimentation Lab", - "Holodeck Alpha", - "Hydroponics", - "Library", - "Mime's Office", - "Mining Dock", - "Morgue", - "Office Supplies", - "Pet Store", - "Primary Tool Storage", - "Research Division", - "Security Checkpoint", - "Technical Storage", - "Teleporter", - "Science Toxins Storage", - "Vacant Office", - "Research Testing Lab", - "Xenobiology Lab", - // Maintenance - "Atmospherics Maintenance", - "Central Maintenance", - "Central Secondary Maintenance", - ), - EXTRACTION_DIFFICULTY_HARD = list( - // No AI Chamber because I'm not that sadistic. - // Most Bridge areas are excluded because of they'd be basically impossible. So are Brig areas. - "AI Satellite Antechamber", - "AI Satellite Atmospherics", - "AI Satellite Service", - "AI Satellite Hallway", - "Bar", - "Cargo Office", - "Chemistry", - "Chief Engineer's office", - "Chief Medical Officer's office", - "Cloning Lab", - "Cryogenics", - "Dorms", - "Engineering Equipment Storage", - "Engineering Foyer", - "EVA Storage", - "Expedition", - "Genetics Lab", - "Gravity Generator", - "Head of Personnel's Office", - "Heads of Staff Meeting Room", - "Kitchen", // Chef CQC is no joke. - "Mech Bay", - "Medbay", - "Medbay Reception", - "Medical Storage", - "Medical Treatment Center", - "Medbay Patient Ward", - "Messaging Server Room", - "Mr Chang's", - "Nanotrasen Representative's Office", - "Paramedic", - "Port Primary Hallway", - "Quartermaster's Office", - "Research Director's Office", - "Research and Development", - "Robotics Lab", - "Surgery 1", - "Surgery 2", - "Telecoms Central Compartment", - "Secure Storage", - ), - ) - // Variables - /// The designated area where the kidnapee must be extracted to complete the objective. - var/area/extraction_zone = null - /// The contract's difficulty. Determines the reward on completion. - var/chosen_difficulty = EXTRACTION_DIFFICULTY_EASY - /// Associated lazy list of areas the contractor can pick from and extract the kidnapee there. - /// Structure: EXTRACTION_DIFFICULTY_(EASY|MEDIUM|HARD) => /area - var/list/area/candidate_zones = null - /// List of people who cannot be selected as contract target. - var/list/datum/mind/target_blacklist = null - /// Static list that is basically [/datum/objective/contract/var/possible_zone_names] but with area names replaced by /area objects if available. - var/static/list/possible_zones = null - /// The owning [/datum/syndicate_contract]. - var/datum/syndicate_contract/owning_contract = null - /// Name fixer regex because area names have rogue characters sometimes. - var/static/regex/name_fixer = regex("(\[a-z0-9 \\'\]+)$", "ig") - -/datum/objective/contract/New(contract) - owning_contract = contract - // Init static variable - if(!possible_zones) - // Compute the list of all zones by their name first - var/list/all_areas_by_name = list() - for(var/a in GLOB.all_areas) - var/area/A = a - if(A.outdoors || !is_station_level(A.z)) - continue - var/i = findtext(A.map_name, name_fixer) - if(i) - var/clean_name = copytext(A.map_name, i) - clean_name = replacetext(clean_name, "\\", "") - all_areas_by_name[clean_name] = A - - possible_zones = list() - for(var/difficulty in EXTRACTION_DIFFICULTY_EASY to EXTRACTION_DIFFICULTY_HARD) - var/list/difficulty_areas = list() - for(var/area_name in possible_zone_names[difficulty]) - var/area/A = all_areas_by_name[area_name] - if(!A) - continue - difficulty_areas += A - possible_zones += list(difficulty_areas) - // Select zones - for(var/difficulty in EXTRACTION_DIFFICULTY_EASY to EXTRACTION_DIFFICULTY_HARD) - pick_candidate_zone(difficulty) - return ..() - -/datum/objective/contract/is_invalid_target(datum/mind/possible_target) - if((possible_target.assigned_role in forbidden_jobs) || (target_blacklist && (possible_target in target_blacklist))) - return TARGET_INVALID_BLACKLISTED - return ..() - -/datum/objective/contract/on_target_cryo() - if(owning_contract.status in list(CONTRACT_STATUS_COMPLETED, CONTRACT_STATUS_FAILED)) - return - // We pick the target ourselves so we don't want the default behaviour. - owning_contract.invalidate() - -/datum/objective/contract/update_explanation_text() - return - -/** - * Assigns a randomly selected zone to the contract's selectable zone at the given difficulty. - * - * Arguments: - * * difficulty - The difficulty to assign. - */ -/datum/objective/contract/proc/pick_candidate_zone(difficulty = EXTRACTION_DIFFICULTY_EASY) - if(!candidate_zones) - candidate_zones = list(null, null, null) - candidate_zones[difficulty] = pick(possible_zones[difficulty]) - -/** - * Updates the objective's information with the given difficulty. - * - * Arguments: - * * difficulty - The chosen difficulty. - * * S - The parent [/datum/syndicate_contract]. - */ -/datum/objective/contract/proc/choose_difficulty(difficulty = EXTRACTION_DIFFICULTY_EASY, datum/syndicate_contract/S) - . = FALSE - if(!ISINDEXSAFE(candidate_zones, difficulty)) - return - - var/area/A = candidate_zones[difficulty] - extraction_zone = A - chosen_difficulty = difficulty - explanation_text = "Kidnap [S.target_name] by any means and extract them in [A.map_name] using your Contractor Uplink. You will earn [S.reward_tc[difficulty]] telecrystals and [S.reward_credits] credits upon completion. Your reward will be severely reduced if your target is dead." - return TRUE - -/** - * Returns whether the extraction process can be started. - * - * Arguments: - * * caller - The person trying to call the extraction. - */ -/datum/objective/contract/proc/can_start_extraction_process(mob/living/carbon/human/caller) - return get_area(caller) == extraction_zone && get_area(target.current) == extraction_zone diff --git a/code/modules/antagonists/traitor/contractor/items/contractor_pinpointer.dm b/code/modules/antagonists/traitor/contractor/items/contractor_pinpointer.dm deleted file mode 100644 index dc3472cd3afe1..0000000000000 --- a/code/modules/antagonists/traitor/contractor/items/contractor_pinpointer.dm +++ /dev/null @@ -1,48 +0,0 @@ -/obj/item/pinpointer/crew/contractor - name = "contractor pinpointer" - desc = "A handheld tracking device that points to crew without needing suit sensors at the cost of accuracy." - icon_state = "pinoff_contractor" - icon_off = "pinoff_contractor" - icon_null = "pinonnull_contractor" - icon_direct = "pinondirect_contractor" - icon_close = "pinonclose_contractor" - icon_medium = "pinonmedium_contractor" - icon_far = "pinonfar_contractor" - /// The minimum range for the pinpointer to function properly. - var/min_range = 20 - /// The first person to have used the item. If this is set already, no one else can use it. - var/mob/owner = null - -/obj/item/pinpointer/crew/contractor/point_at(atom/target) - if(target && trackable(target)) - // Calc dir - var/turf/T = get_turf(target) - var/turf/L = get_turf(src) - dir = get_dir(L, T) - // Calc dist - var/dist = get_dist(L, T) - if(ISINRANGE(dist, -1, min_range)) - icon_state = icon_direct - else if(ISINRANGE(dist, min_range + 1, min_range + 8)) - icon_state = icon_close - else if(ISINRANGE(dist, min_range + 9, min_range + 16)) - icon_state = icon_medium - else if(ISINRANGE(dist, min_range + 16, INFINITY)) - icon_state = icon_far - else - icon_state = icon_null - -/obj/item/pinpointer/crew/contractor/trackable(mob/living/carbon/human/H) - var/turf/here = get_turf(src) - var/turf/there = get_turf(H) - return here && there && there.z == here.z - -/obj/item/pinpointer/crew/contractor/attack_self__legacy__attackchain(mob/living/user) - if(owner) - if(owner != user.mind.current) - to_chat(user, "[src] refuses to do anything.") - return - else - owner = user.mind.current - to_chat(user, "[src] now recognizes you as its sole user.") - return ..() diff --git a/code/modules/antagonists/traitor/contractor/items/contractor_uplink.dm b/code/modules/antagonists/traitor/contractor/items/contractor_uplink.dm deleted file mode 100644 index 8a34bf9a23a88..0000000000000 --- a/code/modules/antagonists/traitor/contractor/items/contractor_uplink.dm +++ /dev/null @@ -1,42 +0,0 @@ -/** - * # Contractor Uplink - * - * A contractor's point of contact with their Contractor Hub. - */ -/obj/item/contractor_uplink - name = "contractor uplink" - desc = "A standard, Syndicate issued tablet for handling important contracts while on the field." - icon = 'icons/obj/device.dmi' - icon_state = "contractor_uplink" - w_class = WEIGHT_CLASS_SMALL - slot_flags = ITEM_SLOT_BELT - origin_tech = "programming=5;syndicate=4" // Hackerman encryption - /// The Contractor Hub associated with this uplink. - var/datum/contractor_hub/hub = null - -/obj/item/contractor_uplink/Destroy() - // Right now, one uplink = one hub so this is fine. - QDEL_NULL(hub) - return ..() - -/obj/item/contractor_uplink/attack_self__legacy__attackchain(mob/user) - hub.ui_interact(user) - -/** - * Sends a message to the mob holding this item. - * - * Arguments: - * * text - The text to send. - * * sndfile - The sound to play to the holder only. - */ -/obj/item/contractor_uplink/proc/message_holder(text, sndfile) - var/mob/living/M = loc - while(!istype(M) && M?.loc) - M = M.loc - if(!istype(M)) - return - - to_chat(M, "[bicon(src)] Incoming encrypted transmission from your handlers. Message as follows:
    "\ - + "[text]") - if(sndfile) - M.playsound_local(get_turf(M), sndfile, 30, FALSE, use_reverb = FALSE) diff --git a/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm b/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm deleted file mode 100644 index c38b8523e3d79..0000000000000 --- a/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm +++ /dev/null @@ -1,251 +0,0 @@ -/proc/isvampirethrall(mob/living/M) - return istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/mindslave/thrall) - -/datum/vampire_passive/increment_thrall_cap/on_apply(datum/antagonist/vampire/V) - V.subclass.thrall_cap++ - gain_desc = "You can now thrall one more person, up to a maximum of [V.subclass.thrall_cap]" - -/datum/vampire_passive/increment_thrall_cap/two - -/datum/vampire_passive/increment_thrall_cap/three - -/datum/spell/vampire/enthrall - name = "Enthrall (150)" - desc = "You use a large portion of your power to sway those loyal to none to be loyal to you only." - gain_desc = "You have gained the ability to thrall people to your will." - action_icon_state = "vampire_enthrall" - required_blood = 150 - deduct_blood_on_cast = FALSE - -/datum/spell/vampire/enthrall/create_new_targeting() - var/datum/spell_targeting/click/T = new - T.range = 1 - T.click_radius = 0 - return T - -/datum/spell/vampire/enthrall/cast(list/targets, mob/user = usr) - var/datum/antagonist/vampire/vampire = user.mind.has_antag_datum(/datum/antagonist/vampire) - var/mob/living/target = targets[1] - user.visible_message("[user] bites [target]'s neck!", "You bite [target]'s neck and begin the flow of power.") - to_chat(target, "You feel the tendrils of evil invade your mind.") - if(do_mob(user, target, 15 SECONDS)) - if(can_enthrall(user, target)) - handle_enthrall(user, target) - var/datum/spell_handler/vampire/V = custom_handler - var/blood_cost = V.calculate_blood_cost(vampire) - vampire.subtract_usable_blood(blood_cost) //we take the blood after enthralling, not before - else - revert_cast(user) - to_chat(user, "You or your target moved.") - -/datum/spell/vampire/enthrall/proc/can_enthrall(mob/living/user, mob/living/carbon/C) - . = FALSE - if(!C) - CRASH("target was null while trying to vampire enthrall, attacker is [user] [user.key] \ref[user]") - if(!user.mind.som) - CRASH("Dantalion Thrall datum ended up null.") - if(!ishuman(C)) - to_chat(user, "You can only enthrall sentient humanoids!") - return - if(!C.mind) - to_chat(user, "[C.name]'s mind is not there for you to enthrall.") - return - - var/datum/antagonist/vampire/V = user.mind.has_antag_datum(/datum/antagonist/vampire) - if(V.subclass.thrall_cap <= length(user.mind.som.serv)) - to_chat(user, "You don't have enough power to enthrall any more people!") - return - if(ismindshielded(C) || C.mind.has_antag_datum(/datum/antagonist/vampire) || IS_MINDSLAVE(C)) - C.visible_message("[C] seems to resist the takeover!", "You feel a familiar sensation in your skull that quickly dissipates.") - return - if(HAS_MIND_TRAIT(C, TRAIT_HOLY)) - C.visible_message("[C] seems to resist the takeover!", "Your faith in [SSticker.Bible_deity_name] has kept your mind clear of all evil.") - return - return TRUE - -/datum/spell/vampire/enthrall/proc/handle_enthrall(mob/living/user, mob/living/carbon/human/H) - if(!istype(H)) - return FALSE - - var/greet_text = "You have been Enthralled by [user.real_name]. Follow [user.p_their()] every command." - H.mind.add_antag_datum(new /datum/antagonist/mindslave/thrall(user.mind, greet_text)) - - H.Stun(4 SECONDS) - user.create_log(CONVERSION_LOG, "vampire enthralled", H) - H.create_log(CONVERSION_LOG, "was vampire enthralled", user) - -/datum/spell/vampire/thrall_commune - name = "Commune" - desc = "Talk to your thralls telepathically." - gain_desc = "You have gained the ability to commune with your thralls." - action_icon_state = "vamp_communication" - base_cooldown = 2 SECONDS - -/datum/spell/vampire/thrall_commune/create_new_handler() //so thralls can use it - return - -/datum/spell_targeting/select_vampire_network/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) // Returns the vampire and their thralls. If user is a thrall then it will look up their master's network - var/list/mob/living/targets = list() - var/datum/antagonist/vampire/V = user.mind.has_antag_datum(/datum/antagonist/vampire) // if the user is a vampire - - if(!V) - for(var/datum/mind/M in user.mind.som.masters) // if the user is a thrall - V = M.has_antag_datum(/datum/antagonist/vampire) - if(V) - break - - if(!V) - return - if(!V.owner.som) // I hate som - stack_trace("Dantalion Thrall datum ended up null.") - return - - for(var/datum/mind/thrall in V.owner.som.serv) - targets += thrall.current - targets += V.owner.current - return targets - -/datum/spell/vampire/thrall_commune/create_new_targeting() - var/datum/spell_targeting/select_vampire_network/T = new - return T - -/datum/spell/vampire/thrall_commune/cast(list/targets, mob/user) - var/input = tgui_input_text(user, "Enter a message to relay to the other thralls", "Thrall Commune") - if(!input) - revert_cast(user) - return - var/title = isvampirethrall(user) ? "Thrall" : "Vampire Master" // if admins give this to a non vampire/thrall it is not my problem - var/full_title = "[user.real_name] ([title])" - for(var/mob/M in targets) - to_chat(M, "[full_title]: [input]") - for(var/mob/M in GLOB.dead_mob_list) - to_chat(M, "[full_title] ([ghost_follow_link(user, ghost=M)]): [input]") - log_say("(DANTALION) [input]", user) - user.create_log(SAY_LOG, "(DANTALION) [input]") - -/datum/spell/vampire/pacify - name = "Pacify (10)" - desc = "Pacify a target temporarily, making them unable to cause harm." - gain_desc = "You have gained the ability to pacify someone's harmful tendencies, preventing them from doing any physical harm to anyone." - action_icon_state = "pacify" - base_cooldown = 30 SECONDS - required_blood = 10 - -/datum/spell/vampire/pacify/create_new_targeting() - var/datum/spell_targeting/click/T = new - T.range = 7 - T.click_radius = 1 - T.allowed_type = /mob/living/carbon/human - return T - -/datum/spell/vampire/pacify/cast(list/targets, mob/user) - for(var/mob/living/carbon/human/H as anything in targets) - H.apply_status_effect(STATUS_EFFECT_PACIFIED) - -/datum/spell/vampire/switch_places - name = "Subspace Swap (30)" - desc = "Switch positions with a target." - gain_desc = "You have gained the ability to switch positions with a targeted mob." - centcom_cancast = FALSE - action_icon_state = "subspace_swap" - base_cooldown = 30 SECONDS - required_blood = 30 - -/datum/spell/vampire/switch_places/create_new_targeting() - var/datum/spell_targeting/click/T = new - T.range = 7 - T.click_radius = 1 - T.try_auto_target = FALSE - T.allowed_type = /mob/living - return T - -/datum/spell/vampire/switch_places/cast(list/targets, mob/user) - var/mob/living/target = targets[1] - if(target.can_block_magic(antimagic_flags)) - to_chat(user, "The spell had no effect!") - to_chat(target, "You feel space bending, but it rapidly dissipates.") - return FALSE - var/turf/user_turf = get_turf(user) - var/turf/target_turf = get_turf(target) - if(!(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, user_turf) & COMPONENT_BLOCK_TELEPORT)) - target.forceMove(user_turf) - if(!(SEND_SIGNAL(user, COMSIG_MOVABLE_TELEPORTING, target_turf) & COMPONENT_BLOCK_TELEPORT)) - user.forceMove(target_turf) - -/datum/spell/vampire/self/decoy - name = "Deploy Decoy (30)" - desc = "Briefly turn invisible and deploy a decoy illusion to fool your prey." - gain_desc = "You have gained the ability to turn invisible and create decoy illusions." - action_icon_state = "decoy" - required_blood = 30 - base_cooldown = 40 SECONDS - -/datum/spell/vampire/self/decoy/cast(list/targets, mob/user) - var/mob/living/simple_animal/hostile/illusion/escape/E = new(get_turf(user)) - E.Copy_Parent(user, 20, 20) - E.GiveTarget(user) //so it starts running right away - E.Goto(user, E.move_to_delay, E.minimum_distance) - user.make_invisible() - addtimer(CALLBACK(user, TYPE_PROC_REF(/mob/living, reset_visibility)), 6 SECONDS) - -/datum/spell/vampire/rally_thralls - name = "Rally Thralls (100)" - desc = "Removes all incapacitating effects from your nearby thralls." - gain_desc = "You have gained the ability to remove all incapacitating effects from nearby thralls." - action_icon_state = "thralls_up" - required_blood = 100 - base_cooldown = 100 SECONDS - -/datum/spell/vampire/rally_thralls/create_new_targeting() - var/datum/spell_targeting/aoe/thralls/A = new - A.allowed_type = /mob/living/carbon/human - A.range = 7 - return A - -/datum/spell_targeting/aoe/thralls/valid_target(target, user, datum/spell/spell, check_if_in_range) - if(!isvampirethrall(target)) - return FALSE - return ..() - -/datum/spell/vampire/rally_thralls/cast(list/targets, mob/user) - for(var/mob/living/carbon/human/H as anything in targets) - var/image/I = image('icons/effects/vampire_effects.dmi', "rallyoverlay", layer = EFFECTS_LAYER) - playsound(H, 'sound/magic/staff_healing.ogg', 30) - H.remove_CC() - H.add_overlay(I) - addtimer(CALLBACK(H, TYPE_PROC_REF(/atom, cut_overlay), I), 6 SECONDS) // this makes it obvious who your thralls are for a while. - -/datum/spell/vampire/self/share_damage - name = "Blood Bond" - desc = "Creates a net between you and your nearby thralls that evenly shares all damage received." - gain_desc = "You have gained the ability to share damage between you and your thralls." - action_icon_state = "blood_bond" - required_blood = 5 - -/datum/spell/vampire/self/share_damage/cast(list/targets, mob/living/user) - var/datum/status_effect/thrall_net/T = user.has_status_effect(STATUS_EFFECT_THRALL_NET) - if(!T) - user.apply_status_effect(STATUS_EFFECT_THRALL_NET, user.mind.has_antag_datum(/datum/antagonist/vampire)) - return - qdel(T) - -/datum/spell/vampire/hysteria - name = "Mass Hysteria (70)" - desc = "Casts a powerful illusion to make everyone nearby perceive others to looks like random animals after briefly blinding them." - gain_desc = "You have gained the ability to make everyone nearby perceive others to looks like random animals after briefly blinding them." - action_icon_state = "hysteria" - required_blood = 70 - base_cooldown = 180 SECONDS - -/datum/spell/vampire/hysteria/create_new_targeting() - var/datum/spell_targeting/aoe/A = new - A.range = 8 - A.allowed_type = /mob/living/carbon/human - return A - -/datum/spell/vampire/hysteria/cast(list/targets, mob/user) - for(var/mob/living/carbon/human/H as anything in targets) - if(!H.affects_vampire(user)) - continue - H.flash_eyes(1, TRUE) // flash to give them a second to lose track of who is who - new /obj/effect/hallucination/delusion/long(get_turf(user), H) diff --git a/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm b/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm deleted file mode 100644 index 5207ccf7d97c1..0000000000000 --- a/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm +++ /dev/null @@ -1,307 +0,0 @@ -/datum/spell/vampire/self/blood_swell - name = "Blood Swell (30)" - desc = "You infuse your body with blood, making you highly resistant to stuns and physical damage. However, this makes you unable to fire ranged weapons while it is active." - gain_desc = "You have gained the ability to temporarly resist large amounts of stuns and physical damage." - base_cooldown = 40 SECONDS - required_blood = 30 - action_icon_state = "blood_swell" - -/datum/spell/vampire/self/blood_swell/cast(list/targets, mob/user) - var/mob/living/target = targets[1] - if(ishuman(target)) - var/mob/living/carbon/human/H = target - H.apply_status_effect(STATUS_EFFECT_BLOOD_SWELL) - -/datum/spell/vampire/self/stomp - name = "Seismic Stomp (30)" - desc = "You slam your foot into the ground sending a powerful shockwave through the station's hull, sending people flying away. Cannot be cast if you legs are impared by a bola or similar." - gain_desc = "You have gained the ability to knock people back using a powerful stomp." - action_icon_state = "seismic_stomp" - base_cooldown = 60 SECONDS - required_blood = 30 - var/max_range = 4 - -/datum/spell/vampire/self/stomp/can_cast(mob/living/carbon/user, charge_check, show_message) - if(user.legcuffed) - return FALSE - return ..() - -/datum/spell/vampire/self/stomp/cast(list/targets, mob/user) - var/turf/T = get_turf(user) - playsound(T, 'sound/effects/meteorimpact.ogg', 100, TRUE) - addtimer(CALLBACK(src, PROC_REF(hit_check), 1, T, user), 0.2 SECONDS) - new /obj/effect/temp_visual/stomp(T) - -/datum/spell/vampire/self/stomp/proc/hit_check(range, turf/start_turf, mob/user, safe_targets = list()) - // gets the two outermost turfs in a ring, we get two so people cannot "walk over" the shockwave - var/list/targets = view(range, start_turf) - view(range - 2, start_turf) - for(var/turf/simulated/floor/flooring in targets) - if(prob(100 - (range * 20))) - flooring.ex_act(EXPLODE_LIGHT) - - for(var/mob/living/L in targets) - if(L in safe_targets) - continue - if(L.throwing) // no double hits - continue - if(!L.affects_vampire(user)) - continue - if(L.move_resist > MOVE_FORCE_VERY_STRONG) - continue - var/throw_target = get_edge_target_turf(L, get_dir(start_turf, L)) - INVOKE_ASYNC(L, TYPE_PROC_REF(/atom/movable, throw_at), throw_target, 3, 4) - L.KnockDown(1 SECONDS) - safe_targets += L - var/new_range = range + 1 - if(new_range <= max_range) - addtimer(CALLBACK(src, PROC_REF(hit_check), new_range, start_turf, user, safe_targets), 0.2 SECONDS) - -/obj/effect/temp_visual/stomp - icon = 'icons/effects/seismic_stomp_effect.dmi' - icon_state = "stomp_effect" - duration = 0.8 SECONDS - pixel_y = -16 - pixel_x = -16 - -/obj/effect/temp_visual/stomp/Initialize(mapload) - . = ..() - var/matrix/M = matrix() * 0.5 - transform = M - animate(src, transform = M * 8, time = duration, alpha = 0) - -/datum/vampire_passive/blood_swell_upgrade - gain_desc = "While blood swell is active all of your melee attacks deal increased damage." - -/datum/spell/vampire/self/overwhelming_force - name = "Overwhelming Force" - desc = "When toggled you will automatically pry open doors that you bump into if you do not have access." - gain_desc = "You have gained the ability to force open doors at a small blood cost." - base_cooldown = 2 SECONDS - action_icon_state = "OH_YEAAAAH" - -/datum/spell/vampire/self/overwhelming_force/cast(list/targets, mob/user) - if(!HAS_TRAIT_FROM(user, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT)) - to_chat(user, "You feel MIGHTY!") - ADD_TRAIT(user, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT) - user.status_flags &= ~CANPUSH - user.move_resist = MOVE_FORCE_STRONG - else - REMOVE_TRAIT(user, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT) - user.move_resist = MOVE_FORCE_DEFAULT - user.status_flags |= CANPUSH - -/datum/spell/vampire/self/blood_rush - name = "Blood Rush (30)" - desc = "Infuse yourself with blood magic to boost your movement speed and break out of leg restraints." - gain_desc = "You have gained the ability to temporarily move at high speeds." - base_cooldown = 30 SECONDS - required_blood = 30 - action_icon_state = "blood_rush" - -/datum/spell/vampire/self/blood_rush/can_cast(mob/user, charge_check, show_message) - var/mob/living/L = user - // they're not getting anything out of this spell if they're stunned or buckled anyways, so we might as well stop them from wasting the blood - if(L.IsWeakened() || L.buckled) - to_chat(L, "You can't cast this spell while incapacitated!") - return FALSE - return ..() - -/datum/spell/vampire/self/blood_rush/cast(list/targets, mob/user) - var/mob/living/target = targets[1] - if(!ishuman(target)) - return - - var/mob/living/carbon/human/H = target - to_chat(H, "You feel a rush of energy!") - - H.apply_status_effect(STATUS_EFFECT_BLOOD_RUSH) - H.clear_legcuffs(TRUE) - // note that this doesn't cancel the baton knockdown timer - H.SetKnockDown(0) - H.stand_up(TRUE) - -/datum/spell/fireball/demonic_grasp - name = "Demonic Grasp (20)" - desc = "Fire a hand of demonic energy, snaring and throwing its target around, based on your intent. Disarm pushes, grab pulls." - gain_desc = "You have gained the ability to snare and disrupt people with demonic apendages." - base_cooldown = 30 SECONDS - fireball_type = /obj/item/projectile/magic/demonic_grasp - - selection_activated_message = "You raise your hand, full of demonic energy! Left-click to cast at a target!" - selection_deactivated_message = "You re-absorb the energy...for now." - - action_icon_state = "demonic_grasp" - - action_background_icon_state = "bg_vampire" - sound = null - invocation_type = "none" - invocation = null - -/datum/spell/fireball/demonic_grasp/update_spell_icon() - return - -/datum/spell/fireball/demonic_grasp/create_new_handler() - var/datum/spell_handler/vampire/V = new() - V.required_blood = 20 - return V - -/obj/item/projectile/magic/demonic_grasp - name = "demonic grasp" - // parry this you filthy casual - reflectability = REFLECTABILITY_NEVER - icon_state = null - -/obj/item/projectile/magic/demonic_grasp/pixel_move(trajectory_multiplier) - . = ..() - new /obj/effect/temp_visual/demonic_grasp(loc) - -/obj/item/projectile/magic/demonic_grasp/on_hit(atom/target, blocked, hit_zone) - . = ..() - if(!.) - return - if(!isliving(target)) - return - var/mob/living/L = target - L.Immobilize(1 SECONDS) - var/throw_target - if(!firer) - return - - if(!L.affects_vampire(firer)) - return - - new /obj/effect/temp_visual/demonic_grasp(loc) - - switch(firer.a_intent) - if(INTENT_DISARM) - throw_target = get_edge_target_turf(L, get_dir(firer, L)) - L.throw_at(throw_target, 2, 5, spin = FALSE, callback = CALLBACK(src, PROC_REF(create_snare), L)) // shove away - if(INTENT_GRAB) - throw_target = get_step(firer, get_dir(firer, L)) - L.throw_at(throw_target, 2, 5, spin = FALSE, diagonals_first = TRUE, callback = CALLBACK(src, PROC_REF(create_snare), L)) // pull towards - -/obj/item/projectile/magic/demonic_grasp/proc/create_snare(mob/target) - new /obj/effect/temp_visual/demonic_snare(target.loc) - -/obj/effect/temp_visual/demonic_grasp - icon = 'icons/effects/vampire_effects.dmi' - icon_state = "demonic_grasp" - duration = 3.5 SECONDS - -/obj/effect/temp_visual/demonic_snare - icon = 'icons/effects/vampire_effects.dmi' - icon_state = "immobilized" - duration = 1 SECONDS - -/datum/spell/vampire/charge - name = "Charge (30)" - desc = "You charge at wherever you click on screen, dealing large amounts of damage, stunning and destroying walls and other objects." - gain_desc = "You can now charge at a target on screen, dealing massive damage and destroying structures." - required_blood = 30 - base_cooldown = 30 SECONDS - action_icon_state = "vampire_charge" - -/datum/spell/vampire/charge/create_new_targeting() - return new /datum/spell_targeting/clicked_atom - -/datum/spell/vampire/charge/can_cast(mob/user, charge_check, show_message) - var/mob/living/L = user - if(IS_HORIZONTAL(L)) - return FALSE - return ..() - -/datum/spell/vampire/charge/cast(list/targets, mob/user) - var/target = targets[1] - if(isliving(user)) - var/mob/living/L = user - L.apply_status_effect(STATUS_EFFECT_CHARGING) - L.throw_at(target, targeting.range, 1, L, FALSE, callback = CALLBACK(L, TYPE_PROC_REF(/mob/living, remove_status_effect), STATUS_EFFECT_CHARGING)) - -#define ARENA_SIZE 3 - -/datum/spell/vampire/arena - name = "Desecrated Duel (150)" - desc = "You leap towards someone. Upon landing, you conjure an arena, and within it you will heal brute and burn damage, recover from fatigue faster, and be strengthened against lasting damages. Can be recasted to end the spell early." - gain_desc = "You can now leap to a target and trap them in a conjured arena." - required_blood = 150 - base_cooldown = 30 SECONDS - action_icon_state = "duel" - should_recharge_after_cast = FALSE - var/spell_active = FALSE - /// Holds a reference to the timer until either the spell runs out or we recast it - var/timer - /// Holds a reference to all arena walls so we can qdel them easily with dispel() - var/list/all_temp_walls = list() - -/datum/spell/vampire/arena/create_new_targeting() - var/datum/spell_targeting/click/T = new - T.click_radius = 0 - T.allowed_type = /mob/living/carbon/human - return T - -/datum/spell/vampire/arena/cast(list/targets, mob/living/user) - var/target = targets[1] // We only want to dash towards the first mob in our targeting list, if somehow multiple ended up in there - if(!targets) - return - - if(timer) // Recast to dispel the wall and buff early - dispel(user) - return - - // First we leap towards the enemy target - user.add_stun_absorption("gargantua", INFINITY, 2) // We temporarily make the gargantua immune to stuns to stop any matrix fuckery from happening - animate(user, 1 SECONDS, pixel_z = 64, flags = ANIMATION_RELATIVE, easing = SINE_EASING|EASE_OUT) - addtimer(CALLBACK(user, user.spin(12, 1), 3, 2), 0.3 SECONDS) - var/angle = get_angle(user, target) + 180 - user.transform = user.transform.Turn(angle) - for(var/i in 1 to 10) - var/move_dir = get_dir(user, target) - user.forceMove(get_step(user, move_dir)) - if(get_turf(user) == get_turf(target)) - user.remove_stun_absorption("gargantua") - user.set_body_position(STANDING_UP) - user.transform = matrix() - break - sleep(1) - animate(user, 0.2 SECONDS, pixel_z = -64, flags = ANIMATION_RELATIVE, easing = SINE_EASING|EASE_IN) - // They get a cool soundeffect and a visual, as a treat - - playsound(get_turf(user), 'sound/effects/meteorimpact.ogg', 100, TRUE) - new /obj/effect/temp_visual/stomp(get_turf(user)) - - // Now we build the arena and give the caster the buff - - user.apply_status_effect(STATUS_EFFECT_VAMPIRE_GLADIATOR) - spell_active = TRUE - timer = addtimer(CALLBACK(src, PROC_REF(dispel), user, TRUE), 30 SECONDS, TIMER_STOPPABLE) - INVOKE_ASYNC(src, PROC_REF(arena_trap), get_turf(target)) //Gets another arena trap queued up for when this one runs out. - RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(dispel)) - arena_checks(get_turf(target), user) - -/datum/spell/vampire/arena/proc/arena_checks(turf/target_turf, mob/living/user) - if(!spell_active || QDELETED(src)) - return - INVOKE_ASYNC(src, PROC_REF(fighters_check), user) //Checks to see if our fighters died. - addtimer(CALLBACK(src, PROC_REF(arena_checks), target_turf, user), 5 SECONDS) - -/datum/spell/vampire/arena/proc/arena_trap(turf/target_turf) - for(var/tumor_range_turfs in circle_edge_turfs(target_turf, ARENA_SIZE)) - tumor_range_turfs = new /obj/effect/temp_visual/elite_tumor_wall/gargantua(tumor_range_turfs, src) - all_temp_walls += tumor_range_turfs - -/datum/spell/vampire/arena/proc/fighters_check(mob/living/user) - if(QDELETED(user) || user.stat == DEAD) - dispel(user) - return - -/datum/spell/vampire/arena/proc/dispel(mob/living/user) - spell_active = FALSE - if(timer) - deltimer(timer) - timer = null - QDEL_LIST_CONTENTS(all_temp_walls) - cooldown_handler.start_recharge() - user.remove_status_effect(STATUS_EFFECT_VAMPIRE_GLADIATOR) - user.visible_message("The arena begins to dissipate.") - -#undef ARENA_SIZE diff --git a/code/modules/antagonists/vampire/vampire_powers/umbrae_powers.dm b/code/modules/antagonists/vampire/vampire_powers/umbrae_powers.dm deleted file mode 100644 index d79f0ba61a657..0000000000000 --- a/code/modules/antagonists/vampire/vampire_powers/umbrae_powers.dm +++ /dev/null @@ -1,334 +0,0 @@ -/datum/spell/vampire/self/cloak - name = "Cloak of Darkness" - desc = "Toggles whether you are currently cloaking yourself in darkness. When in darkness and toggled on, you move at increased speeds." - gain_desc = "You have gained the Cloak of Darkness ability, which when toggled makes you nearly invisible and highly agile in the shroud of darkness." - action_icon_state = "vampire_cloak" - base_cooldown = 2 SECONDS - -/datum/spell/vampire/self/cloak/proc/update_spell_name(mob/living/user) - if(!ishuman(user) || !user.mind) - return - var/datum/antagonist/vampire/V = user.mind.has_antag_datum(/datum/antagonist/vampire) - if(!V) - return - - action.name = "[initial(name)] ([V.iscloaking ? "Deactivate" : "Activate"])" - SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_NAME) - UpdateButtons() - -/datum/spell/vampire/self/cloak/cast(list/targets, mob/user = usr) - var/datum/antagonist/vampire/V = user.mind.has_antag_datum(/datum/antagonist/vampire) - V.iscloaking = !V.iscloaking - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(V.iscloaking) - H.physiology.burn_mod *= 1.1 - user.RegisterSignal(user, COMSIG_LIVING_IGNITED, TYPE_PROC_REF(/mob/living, update_vampire_cloak)) - else - user.UnregisterSignal(user, COMSIG_LIVING_IGNITED) - H.physiology.burn_mod /= 1.1 - update_spell_name(user) - to_chat(user, "You will now be [V.iscloaking ? "hidden" : "seen"] in darkness.") - -/mob/living/proc/update_vampire_cloak() - SIGNAL_HANDLER - var/datum/antagonist/vampire/V = mind.has_antag_datum(/datum/antagonist/vampire) - V.handle_vampire_cloak() - -/datum/spell/vampire/shadow_snare - name = "Shadow Snare (20)" - desc = "You summon a trap on the ground. When crossed it will blind the target, extinguish any lights they may have, and ensnare them." - gain_desc = "You have gained the ability to summon a trap that will blind, ensnare, and turn off the lights of anyone who crosses it." - base_cooldown = 20 SECONDS - required_blood = 20 - action_icon_state = "shadow_snare" - -/datum/spell/vampire/shadow_snare/create_new_targeting() - var/datum/spell_targeting/click/T = new - T.allowed_type = /turf/simulated - T.click_radius = -1 - return T - -/datum/spell/vampire/shadow_snare/cast(list/targets, mob/user) - var/turf/target = targets[1] - new /obj/item/restraints/legcuffs/beartrap/shadow_snare(target) - -/obj/item/restraints/legcuffs/beartrap/shadow_snare - name = "shadow snare" - desc = "An almost transparent trap that melts into the shadows." - alpha = 60 - armed = TRUE - anchored = TRUE - breakouttime = 5 SECONDS - flags = DROPDEL - -/obj/item/restraints/legcuffs/beartrap/shadow_snare/on_atom_entered(datum/source, atom/movable/entered) - if(!iscarbon(entered) || !armed) - return - var/mob/living/carbon/C = entered - if(!C.affects_vampire()) // no parameter here so holy always protects - return - C.extinguish_light() - C.EyeBlind(20 SECONDS) - STOP_PROCESSING(SSobj, src) // won't wither away once you are trapped - - . = ..() - - if(!iscarbon(loc)) // if it fails to latch onto someone for whatever reason, delete itself, we don't want unarmed ones lying around. - qdel(src) - -/obj/item/restraints/legcuffs/beartrap/shadow_snare/attack_hand(mob/user) - Crossed(user) - -/obj/item/restraints/legcuffs/beartrap/shadow_snare/attack_tk(mob/user) - if(iscarbon(user)) - var/mob/living/carbon/C = user - to_chat(user, "The snare sends a psychic backlash!") - C.EyeBlind(20 SECONDS) - -/obj/item/restraints/legcuffs/beartrap/shadow_snare/attackby__legacy__attackchain(obj/item/I, mob/user) - var/obj/item/flash/flash = I - if(!istype(flash) || !flash.try_use_flash(user)) - return ..() - user.visible_message("[user] points [I] at [src]!", - "You point [I] at [src]!") - visible_message("[src] withers away.") - qdel(src) - -/obj/item/restraints/legcuffs/beartrap/shadow_snare/process() - var/turf/T = get_turf(src) - var/lighting_count = T.get_lumcount() * 10 - if(lighting_count > 2) - obj_integrity -= 50 - - if(obj_integrity <= 0) - visible_message("[src] withers away.") - qdel(src) - -/obj/item/restraints/legcuffs/beartrap/shadow_snare/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - -/obj/item/restraints/legcuffs/beartrap/shadow_snare/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/datum/spell/vampire/soul_anchor - name = "Soul Anchor (30)" - desc = "You summon a dimenional anchor after a delay, casting again will teleport you back to the anchor. You will fake a recall after 2 minutes." - gain_desc = "You have gained the ability to save a point in space and teleport back to it at will. Unless you willingly teleport back to that point within 2 minutes, you will fake a recall." - required_blood = 30 - centcom_cancast = FALSE - base_cooldown = 3 MINUTES - action_icon_state = "shadow_anchor" - should_recharge_after_cast = FALSE - deduct_blood_on_cast = FALSE - var/obj/structure/shadow_anchor/anchor - /// Are we making an anchor? - var/making_anchor = FALSE - /// Holds a reference to the timer until the caster fake recalls - var/timer - -/datum/spell/vampire/soul_anchor/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/spell/vampire/soul_anchor/cast(list/targets, mob/user) - if(making_anchor) // second cast, but we are impatient - to_chat(user, "Your anchor isn't ready yet!") - return - - if(!making_anchor && !anchor) // first cast, setup the anchor - var/turf/anchor_turf = get_turf(user) - making_anchor = TRUE - if(do_mob(user, user, 5 SECONDS, only_use_extra_checks = TRUE)) // no checks, cant fail - make_anchor(user, anchor_turf) - making_anchor = FALSE - return - - if(anchor) // second cast, teleport us back - recall(user) - - -/datum/spell/vampire/soul_anchor/proc/make_anchor(mob/user, turf/anchor_turf) - anchor = new(anchor_turf) - timer = addtimer(CALLBACK(src, PROC_REF(recall), user, TRUE), 2 MINUTES, TIMER_STOPPABLE) - -/datum/spell/vampire/soul_anchor/proc/recall(mob/user, fake = FALSE) - cooldown_handler.start_recharge() - if(timer) - deltimer(timer) - timer = null - var/turf/start_turf = get_turf(user) - var/turf/end_turf = get_turf(anchor) - QDEL_NULL(anchor) - if(end_turf.z != start_turf.z) - return - if(!is_teleport_allowed(end_turf.z)) - return - - if(fake) - var/mob/living/simple_animal/hostile/illusion/escape/E = new(end_turf) - E.Copy_Parent(user, 10 SECONDS) - for(var/mob/living/L in view(7, E)) //We want it to start running - E.GiveTarget(L) - break - user.make_invisible() - addtimer(CALLBACK(user, TYPE_PROC_REF(/mob/living, reset_visibility)), 4 SECONDS) - else - if(SEND_SIGNAL(user, COMSIG_MOVABLE_TELEPORTING, end_turf) & COMPONENT_BLOCK_TELEPORT) //You can fake it out, but no teleporting - return FALSE - user.forceMove(end_turf) - - if(end_turf.z == start_turf.z) - shadow_to_animation(start_turf, end_turf, user) - - var/datum/spell_handler/vampire/V = custom_handler - var/datum/antagonist/vampire/vampire = user.mind.has_antag_datum(/datum/antagonist/vampire) - var/blood_cost = V.calculate_blood_cost(vampire) - vampire.subtract_usable_blood(blood_cost)// Vampires get a coupon if they have less than the normal blood cost - -/proc/shadow_to_animation(turf/start_turf, turf/end_turf, mob/user) - var/x_difference = end_turf.x - start_turf.x - var/y_difference = end_turf.y - start_turf.y - var/distance = sqrt(x_difference ** 2 + y_difference ** 2) // pythag baby - - var/obj/effect/immortality_talisman/effect = new(start_turf) - effect.dir = user.dir - effect.can_destroy = TRUE - - var/animation_time = distance - animate(effect, time = animation_time, alpha = 0, pixel_x = x_difference * 32, pixel_y = y_difference * 32) //each turf is 32 pixels long - QDEL_IN(effect, animation_time) - -// an indicator that shows where the vampire will land -/obj/structure/shadow_anchor - name = "shadow anchor" - desc = "Looking at this thing makes you feel uneasy..." - icon = 'icons/obj/cult.dmi' - icon_state = "pylon" - alpha = 120 - color = "#545454" - density = TRUE - opacity = FALSE - anchored = TRUE - resistance_flags = INDESTRUCTIBLE - -/datum/spell/vampire/dark_passage - name = "Dark Passage (30)" - desc = "You teleport to a targeted turf." - gain_desc = "You have gained the ability to blink a short distance towards a targeted turf." - base_cooldown = 40 SECONDS - required_blood = 30 - centcom_cancast = FALSE - action_icon_state = "dark_passage" - -/datum/spell/vampire/dark_passage/create_new_targeting() - var/datum/spell_targeting/click/T = new - T.click_radius = 0 - T.allowed_type = /turf/simulated - return T - -/datum/spell/vampire/dark_passage/cast(list/targets, mob/user) - var/turf/target = get_turf(targets[1]) - if(SEND_SIGNAL(user, COMSIG_MOVABLE_TELEPORTING, target) & COMPONENT_BLOCK_TELEPORT) - return FALSE - - new /obj/effect/temp_visual/vamp_mist_out(get_turf(user)) - - user.forceMove(target) - -/obj/effect/temp_visual/vamp_mist_out - duration = 2 SECONDS - icon = 'icons/mob/mob.dmi' - icon_state = "mist" - -/datum/spell/vampire/vamp_extinguish - name = "Extinguish" - desc = "You extinguish any light source in an area around you." - gain_desc = "You have gained the ability to extinguish nearby light sources." - base_cooldown = 20 SECONDS - action_icon_state = "vampire_extinguish" - create_attack_logs = FALSE - create_custom_logs = TRUE - -/datum/spell/vampire/vamp_extinguish/create_new_targeting() - var/datum/spell_targeting/aoe/turf/T = new - return T - -/datum/spell/vampire/vamp_extinguish/cast(list/targets, mob/user = usr) - for(var/turf/T in targets) - T.extinguish_light() - for(var/atom/A in T.contents) - A.extinguish_light() - -/datum/spell/vampire/shadow_boxing - name = "Shadow Boxing (50)" - desc = "Target someone to have your shadow beat them up. You must stay within 2 tiles for this to work." - gain_desc = "You have gained the ability to make your shadow fight for you." - base_cooldown = 30 SECONDS - action_icon_state = "shadow_boxing" - required_blood = 50 - var/target_UID - -/datum/spell/vampire/shadow_boxing/create_new_targeting() - var/datum/spell_targeting/click/C = new - C.allowed_type = /mob/living - C.range = 2 - C.try_auto_target = FALSE - return C - -/datum/spell/vampire/shadow_boxing/cast(list/targets, mob/user) - var/mob/living/target = targets[1] - target.apply_status_effect(STATUS_EFFECT_SHADOW_BOXING, user) - -/datum/spell/vampire/self/eternal_darkness - name = "Eternal Darkness" - desc = "When toggled, you shroud the area around you in darkness and slowly lower the body temperature of people nearby. Energy projectiles will dim in its radius." - gain_desc = "You have gained the ability to shroud the area around you in darkness, only the strongest of lights can pierce your unholy powers." - base_cooldown = 10 SECONDS - action_icon_state = "eternal_darkness" - required_blood = 5 - var/shroud_power = -6 - -/datum/spell/vampire/self/eternal_darkness/cast(list/targets, mob/user) - var/datum/antagonist/vampire/V = user.mind.has_antag_datum(/datum/antagonist/vampire) - var/mob/target = targets[1] - if(!V.get_ability(/datum/vampire_passive/eternal_darkness)) - V.force_add_ability(/datum/vampire_passive/eternal_darkness) - target.set_light(8, shroud_power, "#ddd6cf") - else - for(var/datum/vampire_passive/eternal_darkness/E in V.powers) - V.remove_ability(E) - -/datum/vampire_passive/eternal_darkness - gain_desc = "You surround yourself in a unnatural darkness, freezing those around you and dimming energy projectiles." - -/datum/vampire_passive/eternal_darkness/New() - ..() - START_PROCESSING(SSfastprocess, src) - -/datum/vampire_passive/eternal_darkness/Destroy(force, ...) - owner.remove_light() - STOP_PROCESSING(SSfastprocess, src) - return ..() - -/datum/vampire_passive/eternal_darkness/process() - var/datum/antagonist/vampire/V = owner.mind.has_antag_datum(/datum/antagonist/vampire) - - for(var/mob/living/L in view(8, owner)) - if(L.affects_vampire(owner)) - L.adjust_bodytemperature(-3 * TEMPERATURE_DAMAGE_COEFFICIENT) //The dark is cold and unforgiving. Equivelnt to -60 with previous values. - for(var/obj/item/projectile/P in view(8, owner)) - if(P.flag == ENERGY || P.flag == LASER) - P.damage *= 0.7 - - V.bloodusable = max(V.bloodusable - 0.25, 0) //2.5 per second, 5 per 2, same as before - - if(!V.bloodusable || owner.stat == DEAD) - V.remove_ability(src) - -/datum/vampire_passive/vision/xray - gain_desc = "You can now see through walls, incase you hadn't noticed." - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - see_in_dark = 8 - vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS diff --git a/code/modules/antagonists/vampire/vampire_powers/vampire_powers.dm b/code/modules/antagonists/vampire/vampire_powers/vampire_powers.dm deleted file mode 100644 index 21e6b97f5fae8..0000000000000 --- a/code/modules/antagonists/vampire/vampire_powers/vampire_powers.dm +++ /dev/null @@ -1,365 +0,0 @@ -//This should hold all the vampire related powers -/mob/living/proc/affects_vampire(mob/user) - //Other vampires and thralls aren't affected - if(mind?.has_antag_datum(/datum/antagonist/vampire) || mind?.has_antag_datum(/datum/antagonist/mindslave/thrall)) - return FALSE - /// Chaplains with their nullrod can block a full power vampire, but a chaplain by themselfs or a crew with a null rod can not. - if(can_block_magic(MAGIC_RESISTANCE_HOLY) && HAS_MIND_TRAIT(src, TRAIT_HOLY)) - return FALSE - //Vampires who have reached their full potential can affect nearly everything - var/datum/antagonist/vampire/V = user?.mind.has_antag_datum(/datum/antagonist/vampire) - if(V?.get_ability(/datum/vampire_passive/full)) - return TRUE - //Holy characters are resistant to vampire powers - if(HAS_MIND_TRAIT(src, TRAIT_HOLY)) - return FALSE - if(can_block_magic(MAGIC_RESISTANCE_HOLY)) - return FALSE - return TRUE - -/datum/spell/vampire - action_background_icon_state = "bg_vampire" - human_req = TRUE - clothes_req = FALSE - antimagic_flags = MAGIC_RESISTANCE_HOLY - /// How much blood this ability costs to use - var/required_blood - var/deduct_blood_on_cast = TRUE - -/datum/spell/vampire/create_new_handler() - var/datum/spell_handler/vampire/H = new - H.required_blood = required_blood - H.deduct_blood_on_cast = deduct_blood_on_cast - return H - -/datum/spell/vampire/self/create_new_targeting() - return new /datum/spell_targeting/self - -/datum/vampire_passive - var/gain_desc - var/mob/living/owner = null - -/datum/vampire_passive/New() - ..() - if(!gain_desc) - gain_desc = "You can now use [src]." - -/datum/vampire_passive/Destroy(force, ...) - owner = null - return ..() - -/datum/vampire_passive/proc/on_apply(datum/antagonist/vampire/V) - owner.update_sight() // Life updates conditionally, so we need to update sight here in case the vamp gets new vision based on his powers. Maybe one day refactor to be more OOP and on the vampire's ability datum. - return - -/datum/spell/vampire/self/rejuvenate - name = "Rejuvenate" - desc = "Use reserve blood to enliven your body, removing any incapacitating effects." - action_icon_state = "vampire_rejuvinate" - base_cooldown = 20 SECONDS - stat_allowed = UNCONSCIOUS - antimagic_flags = NONE // So. If you have a null rod on your person, you can't cast vampire spells. I would rather not have officers abuse this by putting a nullrod in their pocket or something to block rejuvinate. - -/datum/spell/vampire/self/rejuvenate/cast(list/targets, mob/user = usr) - var/mob/living/U = user - - U.SetWeakened(0) - U.SetStunned(0) - U.SetKnockDown(0) - U.SetParalysis(0) - U.SetSleeping(0) - U.SetConfused(0) - U.adjustStaminaLoss(-100) - U.stand_up(TRUE) - SEND_SIGNAL(U, COMSIG_LIVING_CLEAR_STUNS) - to_chat(user, "You instill your body with clean blood and remove any incapacitating effects.") - var/datum/antagonist/vampire/V = U.mind.has_antag_datum(/datum/antagonist/vampire) - for(var/datum/disease/zombie/zombie_infection in U.viruses) - zombie_infection.stage = min(zombie_infection.stage, round(7 - (V.bloodtotal/100))) // 700 max usable blood can cleanse any zombie infection - if(zombie_infection.stage <= 0) - zombie_infection.cure() - to_chat(user, "You cleanse the plague from your system.") - else - to_chat(user, "You weaken the plague in your system, but you don't have enough blood to completely remove it.") - - var/rejuv_bonus = V.get_rejuv_bonus() - if(rejuv_bonus) - INVOKE_ASYNC(src, PROC_REF(heal), U, rejuv_bonus) - -/datum/spell/vampire/self/rejuvenate/proc/heal(mob/living/user, rejuv_bonus) - for(var/i in 1 to 5) - user.adjustBruteLoss(-2 * rejuv_bonus) - user.adjustOxyLoss(-5 * rejuv_bonus) - user.adjustToxLoss(-2 * rejuv_bonus) - user.adjustFireLoss(-2 * rejuv_bonus) - for(var/datum/reagent/R in user.reagents.reagent_list) - if(!R.harmless) - user.reagents.remove_reagent(R.id, 2 * rejuv_bonus) - sleep(35) - -/datum/antagonist/vampire/proc/get_rejuv_bonus() - var/rejuv_multiplier = 0 - if(!get_ability(/datum/vampire_passive/regen)) - return rejuv_multiplier - - if(subclass?.improved_rejuv_healing) - rejuv_multiplier = clamp((100 - owner.current.health) / 20, 1, 5) // brute and burn healing between 5 and 50 - return rejuv_multiplier - - return TRUE - - -/datum/spell/vampire/self/specialize - name = "Choose Specialization" - desc = "Choose what sub-class of vampire you want to evolve into." - gain_desc = "You can now choose what specialization of vampire you want to evolve into." - base_cooldown = 2 SECONDS - action_icon_state = "select_class" - -/datum/spell/vampire/self/specialize/cast(mob/user) - ui_interact(user) - -/datum/spell/vampire/self/specialize/ui_state(mob/user) - return GLOB.always_state - -/datum/spell/vampire/self/specialize/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "SpecMenu", "Specialisation Menu") - ui.set_autoupdate(FALSE) - ui.open() - -/datum/spell/vampire/self/specialize/ui_data(mob/user) - var/datum/antagonist/vampire/vamp = user.mind.has_antag_datum(/datum/antagonist/vampire) - var/list/data = list("subclasses" = vamp.subclass) - return data - -/datum/spell/vampire/self/specialize/ui_act(action, list/params) - if(..()) - return - var/datum/antagonist/vampire/vamp = usr.mind.has_antag_datum(/datum/antagonist/vampire) - - if(vamp.subclass) - vamp.upgrade_tiers -= type - vamp.remove_ability(src) - return - - switch(action) - if("umbrae") - vamp.add_subclass(SUBCLASS_UMBRAE) - vamp.upgrade_tiers -= type - vamp.remove_ability(src) - if("hemomancer") - vamp.add_subclass(SUBCLASS_HEMOMANCER) - vamp.upgrade_tiers -= type - vamp.remove_ability(src) - if("gargantua") - vamp.add_subclass(SUBCLASS_GARGANTUA) - vamp.upgrade_tiers -= type - vamp.remove_ability(src) - if("dantalion") - vamp.add_subclass(SUBCLASS_DANTALION) - vamp.upgrade_tiers -= type - vamp.remove_ability(src) - - -/datum/antagonist/vampire/proc/add_subclass(subclass_to_add, announce = TRUE, log_choice = TRUE) - var/datum/vampire_subclass/new_subclass = new subclass_to_add - subclass = new_subclass - check_vampire_upgrade(announce) - if(log_choice) - SSblackbox.record_feedback("nested tally", "vampire_subclasses", 1, list("[new_subclass.name]")) - -/datum/spell/vampire/glare - name = "Glare" - desc = "Your eyes flash, stunning and silencing anyone in front of you. It has lesser effects for those around you." - action_icon_state = "vampire_glare" - base_cooldown = 30 SECONDS - stat_allowed = UNCONSCIOUS - -/datum/spell/vampire/glare/create_new_targeting() - var/datum/spell_targeting/aoe/T = new - T.allowed_type = /mob/living - T.range = 1 - return T - -/datum/spell/vampire/glare/create_new_cooldown() - var/datum/spell_cooldown/charges/C = new - C.max_charges = 2 - C.recharge_duration = base_cooldown - C.charge_duration = 2 SECONDS - return C - -/// No deviation at all. Flashed from the front or front-left/front-right. Alternatively, flashed in direct view. -#define DEVIATION_NONE 3 -/// Partial deviation. Flashed from the side. Alternatively, flashed out the corner of your eyes. -#define DEVIATION_PARTIAL 2 -/// Full deviation. Flashed from directly behind or behind-left/behind-rack. Not flashed at all. -#define DEVIATION_FULL 1 - -/datum/spell/vampire/glare/cast(list/targets, mob/living/user = usr) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(istype(H.glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) - var/obj/item/clothing/glasses/sunglasses/blindfold/B = H.glasses - if(B.tint) - to_chat(user, "You're blindfolded!") - return - user.mob_light(LIGHT_COLOR_BLOOD_MAGIC, 3, _duration = 2) - user.visible_message("[user]'s eyes emit a blinding flash!") - - for(var/mob/living/target in targets) - if(!target.affects_vampire(user)) - continue - - var/deviation - if(IS_HORIZONTAL(user)) - deviation = DEVIATION_PARTIAL - else - deviation = calculate_deviation(target, user) - - if(deviation == DEVIATION_FULL) - target.Confused(6 SECONDS) - target.apply_damage(20, STAMINA) - else if(deviation == DEVIATION_PARTIAL) - target.KnockDown(5 SECONDS) - target.Confused(6 SECONDS) - target.apply_damage(40, STAMINA) - else - target.Confused(10 SECONDS) - target.apply_damage(70, STAMINA) - target.KnockDown(12 SECONDS) - target.AdjustSilence(8 SECONDS) - target.flash_eyes(1, TRUE, TRUE) - to_chat(target, "You are blinded by [user]'s glare.") - add_attack_logs(user, target, "(Vampire) Glared at") - -/datum/spell/vampire/glare/proc/calculate_deviation(mob/victim, mob/attacker) - - // If the victim was looking at the attacker, this is the direction they'd have to be facing. - var/attacker_to_victim = get_dir(attacker, victim) - // The victim's dir is necessarily a cardinal value. - var/attacker_dir = attacker.dir - - // - - - - // - V - Attacker facing south - // # # # - // Attacker within 45 degrees of where the victim is facing. - if(attacker_dir & attacker_to_victim) - return DEVIATION_NONE - // Are they on the same tile? This is probably the victim crawling under the vampire, and looking down shouldn't be too tough. - if(victim.loc == attacker.loc) - return DEVIATION_NONE - // # # # - // - V - Attacker facing south - // - - - - // Victim at 135 or more degrees of where the victim is facing. - if(attacker_dir & REVERSE_DIR(attacker_to_victim)) - return DEVIATION_FULL - // - - - - // # V # Attacker facing south - // - - - - // Victim lateral to the victim. - return DEVIATION_PARTIAL - -#undef DEVIATION_NONE -#undef DEVIATION_PARTIAL -#undef DEVIATION_FULL - -/datum/vampire_passive/regen - gain_desc = "Your rejuvenation abilities have improved and will now heal you over time when used." - -/datum/vampire_passive/vision - gain_desc = "Your vampiric vision has improved." - var/lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - var/see_in_dark = 1 - var/vision_flags = SEE_MOBS - -/datum/vampire_passive/vision/advanced - gain_desc = "Your vampiric vision now allows you to see everything in the dark!" - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - see_in_dark = 3 - vision_flags = SEE_MOBS - -/datum/vampire_passive/vision/full - gain_desc = "Your vampiric vision has reached its full strength!" - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - see_in_dark = 6 - vision_flags = SEE_MOBS - -/datum/vampire_passive/full - gain_desc = "You have reached your full potential. You are no longer weak to the effects of anything holy." - -/datum/spell/vampire/raise_vampires - name = "Raise Vampires" - desc = "Summons deadly vampires from bluespace." - base_cooldown = 100 - clothes_req = FALSE - human_req = TRUE - invocation = "none" - invocation_type = "none" - cooldown_min = 20 - action_icon_state = "revive_thrall" - sound = 'sound/magic/wandodeath.ogg' - gain_desc = "You have gained the ability to Raise Vampires. This extremely powerful AOE ability affects all humans near you. Vampires/thralls are healed. Corpses are raised as vampires. Others are stunned, then brain damaged, then killed." - -/datum/spell/vampire/raise_vampires/create_new_targeting() - var/datum/spell_targeting/aoe/T = new - T.range = 3 - return T - -/datum/spell/vampire/raise_vampires/cast(list/targets, mob/user = usr) - new /obj/effect/temp_visual/cult/sparks(user.loc) - var/turf/T = get_turf(user) - to_chat(user, "You call out within bluespace, summoning more vampiric spirits to aid you!") - for(var/mob/living/carbon/human/H in targets) - T.Beam(H, "sendbeam", 'icons/effects/effects.dmi', time = 30, maxdistance = 7, beam_type = /obj/effect/ebeam) - new /obj/effect/temp_visual/cult/sparks(H.loc) - raise_vampire(user, H) - - -/datum/spell/vampire/raise_vampires/proc/raise_vampire(mob/M, mob/living/carbon/human/H) - if(!istype(M) || !istype(H)) - return - if(!H.mind) - H.visible_message("[H] looks to be too stupid to understand what is going on.") - return - if(H.dna && (NO_BLOOD in H.dna.species.species_traits) || H.dna.species.exotic_blood || !H.blood_volume) - H.visible_message("[H] looks unfazed!") - return - if(H.mind.has_antag_datum(/datum/antagonist/vampire) || H.mind.special_role == SPECIAL_ROLE_VAMPIRE || H.mind.special_role == SPECIAL_ROLE_VAMPIRE_THRALL) - H.visible_message("[H] looks refreshed!") - H.adjustBruteLoss(-60) - H.adjustFireLoss(-60) - for(var/obj/item/organ/external/E in H.bodyparts) - if(prob(25)) - E.mend_fracture() - E.fix_internal_bleeding() - E.fix_burn_wound() - - return - if(H.stat != DEAD) - if(H.IsWeakened()) - H.visible_message("[H] looks to be in pain!") - H.adjustBrainLoss(60) - else - H.visible_message("[H] looks to be stunned by the energy!") - H.Weaken(40 SECONDS) - return - for(var/obj/item/bio_chip/mindshield/L in H) - if(L && L.implanted) - qdel(L) - for(var/obj/item/bio_chip/traitor/T in H) - if(T && T.implanted) - qdel(T) - H.visible_message("[H] gets an eerie red glow in their eyes!") - - var/datum/objective/protect/protect_objective = new - protect_objective.target = M.mind - protect_objective.explanation_text = "Protect [M.real_name]." - H.mind.add_mind_objective(protect_objective) - - add_attack_logs(M, H, "Vampire-sired") - H.mind.make_vampire() - H.revive() - H.Weaken(40 SECONDS) diff --git a/code/modules/antagonists/zombie/zombie_spells.dm b/code/modules/antagonists/zombie/zombie_spells.dm deleted file mode 100644 index 39d02fa998238..0000000000000 --- a/code/modules/antagonists/zombie/zombie_spells.dm +++ /dev/null @@ -1,156 +0,0 @@ -/datum/spell/zombie_claws - name = "Zombie Claws" - desc = "Toggle your claws, allowing you to slash and infect other people." - action_icon_state = "vampire_claws" - action_background_icon_state = "bg_vampire" - human_req = TRUE - clothes_req = FALSE - antimagic_flags = NONE - base_cooldown = 0 SECONDS - var/list/our_claws = list() - var/infection_stage = 1 // mostly for adminbus and testing - -/datum/spell/zombie_claws/Destroy() - QDEL_LIST_CONTENTS(our_claws) - return ..() - -/datum/spell/zombie_claws/cast(mob/user) - if(dispel()) - return - - var/obj/item/zombie_claw/claws = new /obj/item/zombie_claw(user.loc, src) - claws.infection_stage = infection_stage - if(user.put_in_hands(claws)) - our_claws += claws - else - qdel(claws) - to_chat(user, "We have no claws...") - -/datum/spell/zombie_claws/proc/dispel() - var/mob/living/carbon/human/user = action.owner - var/obj/item/zombie_claw/claw = user.get_active_hand() - if(istype(claw, /obj/item/zombie_claw)) - qdel(claw) - return TRUE - -/datum/spell/zombie_claws/can_cast(mob/user, charge_check, show_message) - var/mob/living/L = user - if(!L.get_active_hand() || istype(L.get_active_hand(), /obj/item/zombie_claw)) - return ..() - -/datum/spell/zombie_claws/create_new_targeting() - return new /datum/spell_targeting/self - -/obj/item/zombie_claw - name = "claws" - desc = "Claws extending from your rotting hands, perfect for ripping skulls open for the brains inside." - icon = 'icons/effects/vampire_effects.dmi' - icon_state = "vamp_claws" - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - w_class = WEIGHT_CLASS_BULKY - flags = ABSTRACT | NODROP | DROPDEL - gender = PLURAL - force = 21 // allows them to break down doors aka NOT FUCKING AROUND - armour_penetration_percentage = -20 - attack_effect_override = ATTACK_EFFECT_CLAW - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("slashed", "sliced", "torn", "ripped", "mauled", "cut", "savaged", "clawed") - sprite_sheets_inhand = list("Vox" = 'icons/mob/clothing/species/vox/held.dmi', "Drask" = 'icons/mob/clothing/species/drask/held.dmi') - var/datum/spell/zombie_claws/parent_spell - var/force_weak = 10 - var/infection_stage = 1 - -/obj/item/zombie_claw/Initialize(mapload, new_parent_spell) - . = ..() - if(new_parent_spell) - parent_spell = new_parent_spell - RegisterSignal(parent_spell.action.owner, COMSIG_MOB_WILLINGLY_DROP, PROC_REF(dispel)) - -/obj/item/zombie_claw/proc/dispel(mob/user) - if(user && user.get_active_hand() == src) - qdel(src) - -/obj/item/zombie_claw/Destroy() - if(parent_spell) - UnregisterSignal(parent_spell.action.owner, COMSIG_MOB_WILLINGLY_DROP) - if(parent_spell) - parent_spell.our_claws -= src - parent_spell = null - return ..() - -/obj/item/zombie_claw/customised_abstract_text(mob/living/carbon/owner) - return "[owner.p_they(TRUE)] [owner.p_have(FALSE)] dull claws extending from [owner.p_their(FALSE)] [owner.l_hand == src ? "left hand" : "right hand"]." - -/obj/item/zombie_claw/pre_attack(atom/A, mob/living/user, params) - . = ..() - if(user.reagents.has_reagent("zombiecure2")) - force = force_weak - else - force = initial(force) - -/obj/item/zombie_claw/afterattack__legacy__attackchain(atom/atom_target, mob/user, proximity_flag, click_parameters) - . = ..() - if(!proximity_flag) - return - if(!ishuman(atom_target) || ismachineperson(atom_target)) - return - var/mob/living/carbon/human/target = atom_target - try_infect(target, user) - - var/obj/item/organ/internal/brain/eat_brain = target.get_organ_slot("brain") - if(!eat_brain) - return - var/obj/item/organ/external/brain_holder = target.get_limb_by_name(eat_brain.parent_organ) - if(!brain_holder || brain_holder.open || brain_holder.limb_name != user.zone_selected) - return - - // Max damage - 5 - if(brain_holder.brute_dam + brain_holder.burn_dam <= brain_holder.max_damage - 5) // Deal more damage - return - - if(target.getarmor(brain_holder, MELEE) > 0) // dont count negative armor - to_chat(user, "[target]'s brains are blocked.") - return // Armor blocks zombies trying to eat your brains! - - to_chat(target, "[user]'s claws dig into your [brain_holder.encased]!") - user.visible_message("[user] digs their claws into [target]'s [brain_holder.name]!", "We dig into [target]'s [brain_holder.encased ? brain_holder.encased : brain_holder]...") - playsound(user, 'sound/weapons/armblade.ogg', 50, TRUE) - if(!do_mob(user, target, 3 SECONDS)) - return FALSE - - playsound(user.loc, 'sound/misc/moist_impact.ogg', 50, TRUE) - brain_holder.fracture() - brain_holder.broken_description = "split open" - brain_holder.open = ORGAN_ORGANIC_VIOLENT_OPEN - to_chat(target, "Your [brain_holder.name] is violently cracked open!") - user.visible_message("[user] violently splits apart [target]'s [brain_holder.name]!", "We crack apart [target]'s [brain_holder.name]!") - return TRUE - - -/obj/item/zombie_claw/proc/try_infect(mob/living/carbon/human/target, mob/living/user) - if(!ishuman(target) || HAS_TRAIT(user, TRAIT_NON_INFECTIOUS_ZOMBIE)) - return - if(!(user.zone_selected in list(BODY_ZONE_CHEST, BODY_ZONE_HEAD))) - to_chat(user, "Our infection cannot spread without their head or chest.") - return - if(HAS_TRAIT(target, TRAIT_PIERCEIMMUNE)) - return FALSE - if(target.reagents.has_reagent("zombiecure1") || target.reagents.has_reagent("spaceacillin")) - return - var/obj/item/organ/external/affecting = target.get_organ(user.zone_selected) // Head, or Chest. - if(affecting.is_robotic()) - return // We don't want people to be infected via zombie claws if they're augmented or have robotic limbs. Bites are handled differently. - if(prob(3 * target.getarmor(user.zone_selected, MELEE)) || prob(50)) // more than 33.34 melee armor will always protect you! Or just get lucky B) - return // Armor blocks zombies trying to eat your brains! - - // already have the disease, or have contracted it. Good for feedback when being attacked while wearing a biosuit - if(target.HasDisease(/datum/disease/zombie) || target.ContractDisease(new /datum/disease/zombie)) - playsound(user.loc, 'sound/misc/moist_impact.ogg', 50, TRUE) - target.bleed_rate = max(5, target.bleed_rate + 1) // it transfers via blood, you know. It had to get in somehow. - for(var/datum/disease/zombie/zomb in target.viruses) - zomb.stage = max(zomb.stage, infection_stage) - -/obj/item/zombie_claw/attack_self__legacy__attackchain(mob/user) - . = ..() - qdel(src) diff --git a/code/modules/arcade/arcade_prize.dm b/code/modules/arcade/arcade_prize.dm deleted file mode 100644 index 930cbc424b82a..0000000000000 --- a/code/modules/arcade/arcade_prize.dm +++ /dev/null @@ -1,100 +0,0 @@ -/*Contains: -* Prize balls -* Prize tickets -*/ -/obj/item/toy/prizeball - name = "prize ball" - desc = "A toy is a toy, but a prize ball could be anything! It could even be a toy!" - icon = 'icons/obj/arcade.dmi' - icon_state = "prizeball_1" - var/opening = 0 - var/possible_contents = list( - /obj/effect/spawner/random/toy/carp_plushie, - /obj/effect/spawner/random/plushies, - /obj/effect/spawner/random/toy/action_figure, - /obj/item/toy/eight_ball, - /obj/item/stack/tickets, - ) - -/obj/item/toy/prizeball/Initialize(mapload) - . = ..() - icon_state = pick("prizeball_1","prizeball_2","prizeball_3") - -/obj/item/toy/prizeball/activate_self(mob/user) - if(..() || opening) - return - opening = 1 - playsound(loc, 'sound/items/bubblewrap.ogg', 30, TRUE) - icon_state = "prizeconfetti" - src.color = pick(GLOB.random_color_list) - var/prize_inside = pick(possible_contents) - spawn(10) - user.unequip(src) - if(ispath(prize_inside,/obj/item/stack)) - var/amount = pick(5, 10, 15, 25, 50) - new prize_inside(user.loc, amount) - else - new prize_inside(user.loc) - qdel(src) - -/obj/item/toy/prizeball/mech - name = "mecha figure capsule" - desc = "Contains one collectible mecha figure!" - possible_contents = list( - /obj/effect/spawner/random/toy/mech_figure, - ) - -/obj/item/toy/prizeball/carp_plushie - name = "carp plushie capsule" - desc = "Contains one space carp plushie!" - possible_contents = list( - /obj/effect/spawner/random/toy/carp_plushie, - ) - -/obj/item/toy/prizeball/plushie - name = "plushie capsule" - desc = "Contains one cuddly plushie!" - possible_contents = list( - /obj/effect/spawner/random/plushies, - ) - -/obj/item/toy/prizeball/action_figure - name = "action figure capsule" - desc = "Contains one action figure!" - possible_contents = list( - /obj/effect/spawner/random/toy/action_figure, - ) - -/obj/item/toy/prizeball/therapy - name = "therapy doll capsule" - desc = "Contains one squishy therapy doll." - possible_contents = list( - /obj/effect/spawner/random/toy/therapy_doll, - ) - -/obj/item/stack/tickets - name = "prize ticket" - desc = "Prize tickets from the arcade. Exchange them for fabulous prizes!" - singular_name = "prize ticket" - icon = 'icons/obj/arcade.dmi' - icon_state = "tickets_1" - force = 0 - throwforce = 0 - throw_speed = 1 - throw_range = 1 - w_class = WEIGHT_CLASS_TINY - max_amount = 9999 //Dang that's a lot of tickets - -/obj/item/stack/tickets/attack_self__legacy__attackchain(mob/user as mob) - return - -/obj/item/stack/tickets/update_icon_state() - switch(get_amount()) - if(1 to 3) - icon_state = "tickets_1" // One ticket - if(4 to 24) - icon_state = "tickets_2" // Couple tickets - if(25 to 74) - icon_state = "tickets_3" // Buncha tickets - else - icon_state = "tickets_4" // Ticket snake diff --git a/code/modules/arcade/prize_datums.dm b/code/modules/arcade/prize_datums.dm deleted file mode 100644 index 289c203526d0f..0000000000000 --- a/code/modules/arcade/prize_datums.dm +++ /dev/null @@ -1,396 +0,0 @@ -GLOBAL_DATUM_INIT(global_prizes, /datum/prizes, new()) - -/datum/prizes - var/list/prizes = list() - -/datum/prizes/New() - for(var/itempath in subtypesof(/datum/prize_item)) - prizes += new itempath() - -/datum/prizes/proc/PlaceOrder(obj/machinery/prize_counter/prize_counter, itemID) - var/datum/prize_item/item = GLOB.global_prizes.prizes[itemID] - if(!prize_counter || prize_counter.tickets < item.cost) - return - if(!item) - return - - new item.typepath(prize_counter.loc) - prize_counter.tickets -= item.cost - to_chat(usr, "Enjoy your prize!") - playsound(prize_counter, 'sound/machines/machine_vend.ogg', 50, TRUE) - -////////////////////////////////////// -// prize_item datum // -////////////////////////////////////// - -/datum/prize_item - var/name = "Prize" - var/desc = "This shouldn't show up..." - var/typepath = /obj/item/toy/prizeball - var/cost = 0 - -////////////////////////////////////// -// Prizes // -////////////////////////////////////// - -/datum/prize_item/balloon - name = "Water Balloon" - desc = "A thin balloon for throwing liquid at people." - typepath = /obj/item/toy/balloon - cost = 10 - -/datum/prize_item/plasticring - name = "White Plastic Ring" - desc = "A cheap ring made of plastic." - typepath = /obj/item/clothing/gloves/ring/plastic - cost = 10 - -/datum/prize_item/plasticringb - name = "Blue Plastic Ring" - desc = "A cheap blue ring made of plastic." - typepath = /obj/item/clothing/gloves/ring/plastic/blue - cost = 10 - -/datum/prize_item/plasticringr - name = "Red Plastic Ring" - desc = "A cheap red ring made of plastic." - typepath = /obj/item/clothing/gloves/ring/plastic/red - cost = 10 - -/datum/prize_item/glassring - name = "Glass Ring" - desc = "No refunds if you end up dropping it." - typepath = /obj/item/clothing/gloves/ring/glass - cost = 15 - -/datum/prize_item/spinningtoy - name = "Spinning Toy" - desc = "Looks like an authentic Singularity!" - typepath = /obj/item/toy/spinningtoy - cost = 15 - -/datum/prize_item/blinktoy - name = "Blink Toy" - desc = "Blink. Blink. Blink." - typepath = /obj/item/toy/blink - cost = 15 - -/datum/prize_item/dice - name = "Dice Set" - desc = "A set of assorted dice." - typepath = /obj/item/storage/box/dice - cost = 20 - -/datum/prize_item/foam_darts - name = "Pack of Foam Darts" - desc = "A refill pack with foam darts." - typepath = /obj/item/ammo_box/foambox - cost = 20 - -/datum/prize_item/snappops - name = "Snap-Pops" - desc = "A box of exploding snap-pop fireworks." - typepath = /obj/item/storage/box/snappops - cost = 20 - -/datum/prize_item/cards - name = "Deck of Cards" - desc = "Anyone fancy a game of 52-card Pickup?" - typepath = /obj/item/deck/cards - cost = 25 - -/datum/prize_item/tiny_cards - name = "Deck of Tiny Cards" - desc = "Anyone fancy a tiny game of 52-card Pickup?" - typepath = /obj/item/deck/cards/tiny - cost = 25 - -/datum/prize_item/capgunammo - name = "Capgun Revolver Cylinder" - desc = "Reload your toy revolver with style." - typepath = /obj/item/ammo_box/caps - cost = 30 - -/datum/prize_item/firecracker - name = "Firecracker Grenade" - desc = "A loud and obnoxious firecracker. Hold away from ears and small children." - typepath = /obj/item/grenade/firecracker - cost = 50 - -/datum/prize_item/wallet - name = "Cheap Wallet" - desc = "A cheap and big enough for standard issue ID cards." - typepath = /obj/item/storage/wallet/cheap - cost = 30 - -/datum/prize_item/crayons - name = "Box of Crayons" - desc = "A six-pack of crayons, just like back in kindergarten." - typepath = /obj/item/storage/fancy/crayons - cost = 35 - -/datum/prize_item/eight_ball - name = "Magic Eight Ball" - desc = "A mystical ball that can divine the future!" - typepath = /obj/item/toy/eight_ball - cost = 40 - -/datum/prize_item/shadowring - name = "Shadow Ring" - desc = "Only darklords can wear this ring." - typepath = /obj/item/clothing/gloves/ring/shadow - cost = 40 - -/datum/prize_item/unum - name = "Deck of UNUM! Cards" - desc = "Everyone's favorite card game!" - typepath = /obj/item/deck/unum - cost = 45 - -/datum/prize_item/double_tiny_cards - name = "Double Deck of Tiny Cards" - desc = "Anyone fancy a tiny game of 108-card Pickup?" - typepath = /obj/item/deck/cards/tiny/doublecards - cost = 50 - -/datum/prize_item/id_sticker - name = "Prisoner ID Sticker" - desc = "A sticker that can make any ID look like a prisoner ID." - typepath = /obj/item/id_decal/prisoner - cost = 50 - -/datum/prize_item/id_sticker/silver - name = "Silver ID Sticker" - desc = "A sticker that can make any ID look like a silver ID." - typepath = /obj/item/id_decal/silver - -/datum/prize_item/id_sticker/gold - name = "Gold ID Sticker" - desc = "A sticker that can make any ID look like a golden ID." - typepath = /obj/item/id_decal/gold - -/datum/prize_item/id_sticker/centcom - name = "Centcomm ID Sticker" - desc = "A sticker that can make any ID look like a Central Command ID." - typepath = /obj/item/id_decal/centcom - -/datum/prize_item/id_sticker/emag - name = "Suspicious ID Sticker" - desc = "A sticker that can make any ID look like something suspicious..." - typepath = /obj/item/id_decal/emag - -/datum/prize_item/flash - name = "Toy Flash" - desc = "AUGH! MY EYES!" - typepath = /obj/item/toy/flash - cost = 50 - -/datum/prize_item/toycuffs - name = "Toy Handcuffs" - desc = "Plastic and extremely cheaply made." - typepath = /obj/item/restraints/handcuffs/toy - cost = 50 - -/datum/prize_item/minimeteor - name = "Mini-Meteor" - desc = "Meteors have been detected on a collision course with your fun times!" - typepath = /obj/item/toy/minimeteor - cost = 50 - -/datum/prize_item/therapy_doll - name = "Random Therapy Doll" - desc = "A therapeutic doll for relieving stress without being charged with assault." - typepath = /obj/item/toy/prizeball/therapy - cost = 60 - -/datum/prize_item/minigibber - name = "Minigibber Toy" - desc = "A model of the station gibber. Probably shouldn't stick your fingers in it." - typepath = /obj/item/toy/minigibber - cost = 60 - -/datum/prize_item/confetti - name = "Confetti Grenade" - desc = "Party time!" - typepath = /obj/item/grenade/confetti - cost = 65 - -/datum/prize_item/plushie - name = "Random Plushie" - desc = "A colorful plush toy." - typepath = /obj/item/toy/prizeball/plushie - cost = 75 - -/datum/prize_item/carp_plushie - name = "Random Carp Plushie" - desc = "A colorful fish-shaped plush toy." - typepath = /obj/item/toy/prizeball/carp_plushie - cost = 75 - -/datum/prize_item/mech_toy - name = "Random Mecha" - desc = "A random mecha figure, collect all 11!" - typepath = /obj/item/toy/prizeball/mech - cost = 75 - -/datum/prize_item/action_figure - name = "Random Action Figure" - desc = "A random action figure, collect them all!" - typepath = /obj/item/toy/prizeball/action_figure - cost = 75 - -/datum/prize_item/ai - name = "Toy AI Unit" - desc = "Law 1: Maximize fun for crew." - typepath = /obj/item/toy/ai - cost = 75 - -/datum/prize_item/capgun - name = "Capgun Revolver" - desc = "Do you feel lucky... punk?" - typepath = /obj/item/gun/projectile/revolver/capgun - cost = 75 - -/datum/prize_item/codex_gigas - name = "Toy Codex Gigas" - desc = "For helping you come up with writing ideas for your diabolical adventures." - typepath = /obj/item/toy/codex_gigas - cost = 75 - -/datum/prize_item/pet_rock - name = "Pet Rock" - desc = "A pet of your very own!" - typepath = /obj/item/toy/pet_rock - cost = 80 - -/datum/prize_item/toy_xeno - name = "Xeno Action Figure" - desc = "A lifelike replica of the horrific xeno scourge." - typepath = /obj/item/toy/figure/xeno - cost = 80 - -/datum/prize_item/rubberducky - name = "Rubber Ducky" - desc = "Your favorite bathtime buddy, all squeaks and quacks quality assured." - typepath = /obj/item/bikehorn/rubberducky - cost = 80 - -/datum/prize_item/tacticool - name = "Tacticool Turtleneck" - desc = "A cool-looking turtleneck." - typepath = /obj/item/clothing/under/syndicate/tacticool - cost = 90 - -/datum/prize_item/fakespell - name = "Fake Spellbook" - desc = "Perform magic! Astound your friends! Get mistaken for an enemy of the corporation!" - typepath = /obj/item/spellbook/oneuse/fake_gib - cost = 100 - -/datum/prize_item/fakefingergun - name = "Miming Manual : Finger Gun" - desc = "..." - typepath = /obj/item/spellbook/oneuse/mime/fingergun/fake - cost = 100 - -/datum/prize_item/magic_conch - name = "Magic Conch Shell" - desc = "All hail the magic conch!" - typepath = /obj/item/toy/eight_ball/conch - cost = 100 - -/datum/prize_item/crossbow - name = "Foam Dart Crossbow" - desc = "A toy crossbow that fires foam darts." - typepath = /obj/item/gun/projectile/shotgun/toy/crossbow - cost = 100 - -/datum/prize_item/foamblade - name = "Foam Arm Blade" - desc = "Perfect for reenacting space horror holo-vids." - typepath = /obj/item/toy/foamblade - cost = 100 - -/datum/prize_item/wind_up_toolbox - name = "Wind Up Toolbox" - desc = "A replica toolbox that rumbles when you turn the key." - typepath = /obj/item/toy/windup_toolbox - cost = 100 - -/datum/prize_item/redbutton - name = "Shiny Red Button" - desc = "PRESS IT!" - typepath = /obj/item/toy/redbutton - cost = 100 - -/datum/prize_item/nuke - name = "Nuclear Fun Device" - desc = "Annihilate boredom with an explosion of excitement!" - typepath = /obj/item/toy/nuke - cost = 100 - -/datum/prize_item/blobhat - name = "Blob Hat" - desc = "There's... something... on your head..." - typepath = /obj/item/clothing/head/blob - cost = 125 - -/datum/prize_item/owl - name = "Owl Action Figure" - desc = "Remember: heroes don't grief!" - typepath = /obj/item/toy/figure/owl - cost = 125 - -/datum/prize_item/griffin - name = "Griffin Action Figure" - desc = "If you can't be the best, you can always be the WORST." - typepath = /obj/item/toy/figure/griffin - cost = 125 - -/datum/prize_item/esword - name = "Toy Energy Sword" - desc = "A plastic replica of an energy blade." - typepath = /obj/item/toy/sword - cost = 150 - -/datum/prize_item/fakespace - name = "Space Carpet" - desc = "A stack of carpeted floor tiles that resemble space." - typepath = /obj/item/stack/tile/fakespace/loaded - cost = 150 - -/datum/prize_item/arcadecarpet - name = "Arcade Carpet" - desc = "A stack of genuine arcade carpet tiles, complete with authentic soft drink stains!" - typepath = /obj/item/stack/tile/arcade_carpet/loaded - cost = 150 - -/datum/prize_item/headpat - name = "Gloves of Headpats" - desc = "Gloves that fill you with an irresistable urge to give headpats." - typepath = /obj/item/clothing/gloves/fingerless/rapid/headpat - cost = 150 - -/datum/prize_item/tommygun - name = "Tommy Gun" - desc = "A replica tommy gun that fires foam darts." - typepath = /obj/item/gun/projectile/shotgun/toy/tommygun - cost = 175 - -/datum/prize_item/spacesuit - name = "Fake Spacesuit" - desc = "A replica spacesuit. Not actually spaceworthy." - typepath = /obj/item/storage/box/fakesyndiesuit - cost = 180 - -/datum/prize_item/chainsaw - name = "Toy Chainsaw" - desc = "A full-scale model chainsaw, based on that massacre in Space Texas." - typepath = /obj/item/toy/chainsaw - cost = 200 - -/datum/prize_item/bike - name = "Awesome Bike!" - desc = "WOAH." - typepath = /obj/vehicle/bike - cost = 7000 diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm deleted file mode 100644 index f3611bd5579ad..0000000000000 --- a/code/modules/assembly/assembly.dm +++ /dev/null @@ -1,168 +0,0 @@ -/obj/item/assembly - name = "assembly" - desc = "A small electronic device that should never exist." - icon = 'icons/obj/assemblies/new_assemblies.dmi' - icon_state = "" - flags = CONDUCT - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL = 100) - throwforce = 2 - throw_speed = 3 - throw_range = 10 - origin_tech = "magnets=1;engineering=1" - toolspeed = 1 - usesound = 'sound/items/deconstruct.ogg' - drop_sound = 'sound/items/handling/component_drop.ogg' - pickup_sound = 'sound/items/handling/component_pickup.ogg' - - var/bomb_name = "bomb" // used for naming bombs / mines - - var/secured = TRUE - var/list/attached_overlays = null - var/obj/item/assembly_holder/holder = null - var/cooldown = 0 //To prevent spam - var/wires = ASSEMBLY_WIRE_RECEIVE | ASSEMBLY_WIRE_PULSE - var/datum/wires/connected = null // currently only used by timer/signaler - -/obj/item/assembly/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered) - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/// Called when the holder is moved -/obj/item/assembly/proc/holder_movement() - return - -/// Called when attack_self is called -/obj/item/assembly/interact(mob/user) - return - -/obj/item/assembly/proc/on_atom_entered(datum/source, atom/movable/entered) - return - -/// Called to constantly step down the countdown/cooldown -/obj/item/assembly/proc/process_cooldown() - cooldown-- - if(cooldown <= 0) - return FALSE - addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 10) - return TRUE - -/obj/item/assembly/Destroy() - if(istype(loc, /obj/item/assembly_holder) || istype(holder)) - var/obj/item/assembly_holder/A = loc - if(A.a_left == src) - A.a_left = null - else if(A.a_right == src) - A.a_right = null - holder = null - return ..() - -/// 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(holder && (wires & ASSEMBLY_WIRE_RECEIVE)) - activate(radio) - if(radio && (wires & ASSEMBLY_WIRE_RADIO_RECEIVE)) - activate(radio) - 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 && wires) - connected.pulse_assembly(src) - return TRUE - if(holder && (wires & ASSEMBLY_WIRE_PULSE)) - holder.process_activation(src, 1, 0) - if(holder && (wires & ASSEMBLY_WIRE_PULSE_SPECIAL)) - holder.process_activation(src, 0, 1) - if(istype(loc, /obj/item/grenade)) // This is a hack. Todo: Manage this better -Sayu - var/obj/item/grenade/G = loc - G.prime() // Adios, muchachos - SEND_SIGNAL(src, COMSIG_ASSEMBLY_PULSED, radio) - return TRUE - -/// What the device does when turned on -/obj/item/assembly/proc/activate(radio = FALSE) - SHOULD_CALL_PARENT(TRUE) - if(!secured || cooldown > 0) - return FALSE - cooldown = 2 - addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 1 SECONDS) - - return TRUE - -/// Happens when the assembly is (un)secured -/obj/item/assembly/proc/toggle_secure() - secured = !secured - update_icon() - return secured - -/** - * on_attach: Called when attached to a holder, wiring datum, or other special assembly - * - * Will also be called if the assembly holder is attached to a plasma (internals) tank or welding fuel (dispenser) tank. - */ -/obj/item/assembly/proc/on_attach() - SHOULD_CALL_PARENT(TRUE) - - if(!holder && connected) - holder = connected.holder - -/** - * on_detach: Called when removed from an assembly holder or wiring datum - */ -/obj/item/assembly/proc/on_detach() - if(connected) - connected = null - if(!holder) - return FALSE - forceMove(holder.drop_location()) - holder = null - return TRUE - -/// Called when an assembly is attacked by another -/obj/item/assembly/proc/attach_assembly(obj/item/assembly/A, mob/user) - holder = new /obj/item/assembly_holder(get_turf(src)) - if(holder.attach(A, src, user)) - to_chat(user, "You attach [A] to [src]!") - user.put_in_active_hand(holder) - return TRUE - return FALSE - -/obj/item/assembly/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(isassembly(W)) - var/obj/item/assembly/A = W - if(!A.secured && !secured) - attach_assembly(A, user) - return - - return ..() - -/obj/item/assembly/screwdriver_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - if(toggle_secure()) - to_chat(user, "[src] is ready!") - else - to_chat(user, "[src] can now be attached!") - -/obj/item/assembly/process() - STOP_PROCESSING(SSobj, src) - -/obj/item/assembly/examine(mob/user) - . = ..() - if(in_range(src, user) || loc == user) - if(secured) - . += "[src] is ready!" - else - . += "[src] can be attached!" - -/obj/item/assembly/attack_self__legacy__attackchain(mob/user) - if(!user) - return - user.set_machine(src) - interact(user) - return TRUE diff --git a/code/modules/assembly/assembly_holder.dm b/code/modules/assembly/assembly_holder.dm deleted file mode 100644 index 60314450f782f..0000000000000 --- a/code/modules/assembly/assembly_holder.dm +++ /dev/null @@ -1,197 +0,0 @@ -/obj/item/assembly_holder - name = "Assembly" - icon = 'icons/obj/assemblies/new_assemblies.dmi' - icon_state = "holder" - item_state = "assembly" - flags = CONDUCT - throwforce = 5 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 3 - throw_range = 10 - - var/secured = FALSE - var/obj/item/assembly/a_left = null - var/obj/item/assembly/a_right = null - -/obj/item/assembly_holder/IsAssemblyHolder() - return TRUE - -/obj/item/assembly_holder/Destroy() - if(a_left) - a_left.holder = null - if(a_right) - a_right.holder = null - return ..() - -/obj/item/assembly_holder/proc/attach(obj/item/D, obj/item/D2, mob/user) - if(!D || !D2) - return FALSE - if(!isassembly(D) || !isassembly(D2)) - return FALSE - var/obj/item/assembly/A1 = D - var/obj/item/assembly/A2 = D2 - if(A1.secured || A2.secured) - return FALSE - if(!A1.remove_item_from_storage(src)) - if(user) - user.transfer_item_to(A1, src) - else - A1.forceMove(src) - if(!A2.remove_item_from_storage(src)) - if(user) - user.transfer_item_to(A2, src) - else - A2.forceMove(src) - A1.holder = src - A2.holder = src - a_left = A1 - a_right = A2 - name = "[A1.name]-[A2.name] assembly" - update_icon(UPDATE_OVERLAYS) - A1.on_attach() - A2.on_attach() - return TRUE - -/obj/item/assembly_holder/update_overlays() - . = ..() - if(a_left) - . += "[a_left.icon_state]_left" - for(var/O in a_left.attached_overlays) - . += "[O]_l" - if(a_right) - . += "[a_right.icon_state]_right" - for(var/O in a_right.attached_overlays) - . += "[O]_r" - if(master) - master.update_icon() - - -/obj/item/assembly_holder/examine(mob/user) - . = ..() - if(in_range(src, user) || loc == user) - if(secured) - . += "[src] is ready!" - else - . += "[src] can be attached!" - - -/obj/item/assembly_holder/HasProximity(atom/movable/AM) - if(a_left) - a_left.HasProximity(AM) - if(a_right) - a_right.HasProximity(AM) - - -// TODO: All these assemblies passing the crossed args around needs to be cleaned up with signals -/obj/item/assembly_holder/proc/on_atom_entered(datum/source, atom/movable/entered) - if(a_left) - a_left.on_atom_entered(source, entered) - if(a_right) - a_right.on_atom_entered(source, entered) - -/obj/item/assembly_holder/on_found(mob/finder) - if(a_left) - a_left.on_found(finder) - if(a_right) - a_right.on_found(finder) - - -/obj/item/assembly_holder/hear_talk(mob/living/M, list/message_pieces) - if(a_left) - a_left.hear_talk(M, message_pieces) - if(a_right) - a_right.hear_talk(M, message_pieces) - -/obj/item/assembly_holder/hear_message(mob/living/M, msg) - if(a_left) - a_left.hear_message(M, msg) - if(a_right) - a_right.hear_message(M, msg) - -/obj/item/assembly_holder/proc/process_movement() // infrared beams and prox sensors - if(a_left && a_right) - a_left.holder_movement() - a_right.holder_movement() - -/obj/item/assembly_holder/Move() - . = ..() - process_movement() - return - -/obj/item/assembly_holder/pickup() - . = ..() - process_movement() - -/obj/item/assembly_holder/Bump() - ..() - process_movement() - -/obj/item/assembly_holder/throw_impact() // called when a throw stops - ..() - process_movement() - -/obj/item/assembly_holder/attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess - if(a_left && a_right) - a_left.holder_movement() - a_right.holder_movement() - ..() - return - -/obj/item/assembly_holder/screwdriver_act(mob/user, obj/item/I) - if(!a_left || !a_right) - to_chat(user, "BUG:Assembly part missing, please report this!") - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - a_left.toggle_secure() - a_right.toggle_secure() - secured = !secured - if(secured) - to_chat(user, "[src] is ready!") - else - to_chat(user, "[src] can now be taken apart!") - update_icon() - -/obj/item/assembly_holder/attack_self__legacy__attackchain(mob/user) - add_fingerprint(user) - if(secured) - if(!a_left || !a_right) - to_chat(user, "Assembly part missing!") - return - if(istype(a_left, a_right.type)) // If they are the same type it causes issues due to window code - switch(tgui_alert(user, "Which side would you like to use?", "Choose", list("Left", "Right"))) - if("Left") - a_left.attack_self__legacy__attackchain(user) - if("Right") - a_right.attack_self__legacy__attackchain(user) - return - else - a_left.attack_self__legacy__attackchain(user) - a_right.attack_self__legacy__attackchain(user) - else - var/turf/T = get_turf(src) - if(!T) - return FALSE - user.unequip(src, force = TRUE) - if(a_left) - a_left.holder = null - a_left.forceMove(T) - user.put_in_active_hand(a_left) - if(a_right) // Right object is the secondary item, hence put in inactive hand - a_right.holder = null - a_right.forceMove(T) - user.put_in_inactive_hand(a_right) - qdel(src) - - -/obj/item/assembly_holder/proc/process_activation(obj/D, normal = TRUE, special = TRUE) - if(!D) - return FALSE - if(normal && a_right && a_left) - if(a_right != D) - a_right.pulsed(0) - if(a_left && a_left != D) // the right pools might have sent us boom, so `a_left` can be null here - a_left.pulsed(0) - - return TRUE diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm deleted file mode 100644 index 5af40484a3928..0000000000000 --- a/code/modules/assembly/bomb.dm +++ /dev/null @@ -1,179 +0,0 @@ -/obj/item/onetankbomb - name = "bomb" - icon = 'icons/obj/tank.dmi' - item_state = "assembly" - throwforce = 5 - w_class = WEIGHT_CLASS_NORMAL - throw_speed = 2 - throw_range = 4 - flags = CONDUCT //Copied this from old code, so this may or may not be necessary - var/status = FALSE //FALSE - not readied //TRUE - bomb finished with welder - var/obj/item/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device - var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank - origin_tech = "materials=1;engineering=1" - -/obj/item/onetankbomb/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/item/onetankbomb/examine(mob/user) - . = ..() - . += bombtank.examine(user) - -/obj/item/onetankbomb/update_icon_state() - if(bombtank) - icon_state = bombtank.icon_state - -/obj/item/onetankbomb/update_overlays() - . = ..() - if(bombassembly) - . += bombassembly.icon_state - . += bombassembly.overlays - . += "bomb_assembly" - -/obj/item/onetankbomb/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(istype(W, /obj/item/analyzer)) - bombtank.attackby__legacy__attackchain(W, user, params) - return - return ..() - -/obj/item/onetankbomb/wrench_act(mob/user, obj/item/I) //This is basically bomb assembly code inverted. apparently it works. - if(status) - return - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - to_chat(user, "You disassemble [src].") - bombassembly.forceMove(user.loc) - bombassembly.master = null - bombassembly = null - bombtank.forceMove(user.loc) - bombtank.master = null - bombtank = null - qdel(src) - -/obj/item/onetankbomb/welder_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, volume = I.tool_volume)) - return - if(!status) - status = TRUE - investigate_log("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature() - T0C]", INVESTIGATE_BOMB) - log_game("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature() - T0C]") - to_chat(user, "A pressure hole has been bored to [bombtank] valve. [bombtank] can now be ignited.") - add_attack_logs(user, src, "welded a single tank bomb. Temperature: [bombtank.air_contents.temperature() - T0C]", ATKLOG_FEW) - else - status = FALSE - investigate_log("[key_name(user)] unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature() - T0C]", INVESTIGATE_BOMB) - add_attack_logs(user, src, "unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature() - T0C]", ATKLOG_ALMOSTALL) - to_chat(user, "The hole has been closed.") - - -/obj/item/onetankbomb/attack_self__legacy__attackchain(mob/user) //pressing the bomb accesses its assembly - bombassembly.attack_self__legacy__attackchain(user, 1) - add_fingerprint(user) - return - -/obj/item/onetankbomb/HasProximity(atom/movable/AM) - if(bombassembly) - bombassembly.HasProximity(AM) - -/obj/item/onetankbomb/proc/on_atom_entered(datum/source, atom/movable/entered) //for mousetraps - if(bombassembly) - bombassembly.on_atom_entered(source, entered) - -/obj/item/onetankbomb/on_found(mob/finder) //for mousetraps - if(bombassembly) - bombassembly.on_found(finder) - -/obj/item/onetankbomb/hear_talk(mob/living/M, list/message_pieces) - if(bombassembly) - bombassembly.hear_talk(M, message_pieces) - -/obj/item/onetankbomb/hear_message(mob/living/M, msg) - if(bombassembly) - bombassembly.hear_message(M, msg) - -// ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ---------- - -/obj/item/tank/proc/bomb_assemble(W, user) //Bomb assembly proc. This turns assembly+tank into a bomb - var/obj/item/assembly_holder/S = W - var/mob/M = user - if(!S.secured) //Check if the assembly is secured - return - if(isigniter(S.a_left) == isigniter(S.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it - return - - var/obj/item/onetankbomb/R = new /obj/item/onetankbomb(loc) - - M.drop_item() //Remove the assembly from your hands - M.unequip(src) //Remove the tank from your character,in case you were holding it - M.put_in_hands(R) //Equips the bomb if possible, or puts it on the floor. - - R.bombassembly = S //Tell the bomb about its assembly part - S.master = R //Tell the assembly about its new owner - S.forceMove(R) //Move the assembly out of the fucking way - - R.bombtank = src //Same for tank - master = R - forceMove(R) - R.update_icon() - return - -/obj/item/tank/proc/detonate() //This happens when a bomb is told to explode - var/fuel_moles = air_contents.toxins() + air_contents.oxygen() / 6 - var/strength = 1 - - var/turf/ground_zero = get_turf(loc) - loc = null - - if(air_contents.temperature() > (T0C + 400)) - strength = (fuel_moles / 15) - - if(strength >=1) - explosion(ground_zero, round(strength,1), round(strength*2,1), round(strength*3,1), round(strength*4,1)) - else if(strength >=0.5) - explosion(ground_zero, 0, 1, 2, 4) - else if(strength >=0.2) - explosion(ground_zero, -1, 0, 1, 2) - else - ground_zero.blind_release_air(air_contents) - ground_zero.hotspot_expose(1000, 125) - - else if(air_contents.temperature() > (T0C + 250)) - strength = (fuel_moles/20) - - if(strength >=1) - explosion(ground_zero, 0, round(strength, 1), round(strength * 2, 1), round(strength * 3, 1)) - else if(strength >=0.5) - explosion(ground_zero, -1, 0, 1, 2) - else - ground_zero.blind_release_air(air_contents) - ground_zero.hotspot_expose(1000, 125) - - else if(air_contents.temperature() > (T0C + 100)) - strength = (fuel_moles / 25) - - if(strength >= 1) - explosion(ground_zero, -1, 0, round(strength, 1), round(strength * 3, 1)) - else - ground_zero.blind_release_air(air_contents) - ground_zero.hotspot_expose(1000, 125) - - else - ground_zero.blind_release_air(air_contents) - ground_zero.hotspot_expose(1000, 125) - - if(master) - qdel(master) - qdel(src) - -/obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out. - var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles()) - var/turf/simulated/T = get_turf(src) - if(!T) - return - T.blind_release_air(removed) diff --git a/code/modules/assembly/health.dm b/code/modules/assembly/health.dm deleted file mode 100644 index a7ac581dc3fa5..0000000000000 --- a/code/modules/assembly/health.dm +++ /dev/null @@ -1,108 +0,0 @@ -#define MAX_HEALTH_ACTIVATE 0 -#define MIN_HEALTH_ACTIVATE -150 - -/obj/item/assembly/health - name = "health sensor" - desc = "Used for scanning and monitoring health." - icon_state = "health" - materials = list(MAT_METAL=800, MAT_GLASS=200) - origin_tech = "magnets=1;biotech=1" - - /// Are we scanning our user's health? - var/scanning = FALSE - /// Our user's health - var/user_health - /// The health amount on which to activate - var/alarm_health = MAX_HEALTH_ACTIVATE - -/obj/item/assembly/health/activate() - if(!..()) - return FALSE//Cooldown check - toggle_scan() - return FALSE - -/obj/item/assembly/health/toggle_secure() - secured = !secured - if(secured && scanning) - START_PROCESSING(SSobj, src) - else - scanning = FALSE - user_health = null // Clear out the user data, we're no longer scanning - STOP_PROCESSING(SSobj, src) - update_icon() - return secured - -/obj/item/assembly/health/process() - if(!scanning || !secured) - STOP_PROCESSING(SSobj, src) // It should never reach here, but if it somehow does stop processing - return - - var/atom/A = src - if(connected && connected.holder) - A = connected.holder - - for(A, A && !ismob(A), A = A.loc); // For A, check A exists and that its not a mob, if these are both true then set A to A.loc and repeat - // like get_turf(), but for mobs. - - if(!isliving(A)) - user_health = null // We aint on a living thing, remove the previous data - return - - var/mob/living/M = A - user_health = M.health - if(user_health <= alarm_health) // Its a health detector, not a death detector - pulse() - audible_message("[bicon(src)] *beep* *beep* *beep*") - playsound(src, 'sound/machines/triple_beep.ogg', 40, extrarange = -10) - toggle_scan() - -/obj/item/assembly/health/pickup(mob/user) - ..() - ADD_TRAIT(user, TRAIT_CAN_VIEW_HEALTH, "HEALTH[UID()]") - -/obj/item/assembly/health/proc/toggle_scan() - if(!secured) - return FALSE - scanning = !scanning - if(scanning) - START_PROCESSING(SSobj, src) - else - user_health = null // Clear out the user data, we're no longer scanning - STOP_PROCESSING(SSobj, src) - -/obj/item/assembly/health/attack_self__legacy__attackchain(mob/user) - ui_interact(user) - -/obj/item/assembly/health/ui_state(mob/user) - return GLOB.deep_inventory_state - -/obj/item/assembly/health/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "HealthSensor", name) - ui.open() - -/obj/item/assembly/health/ui_data(mob/user) - var/list/data = list() - data["on"] = scanning - data["alarm_health"] = alarm_health - data["user_health"] = user_health - data["maxHealth"] = MAX_HEALTH_ACTIVATE - data["minHealth"] = MIN_HEALTH_ACTIVATE - return data - -/obj/item/assembly/health/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - if(..()) - return - - . = TRUE - - switch(action) - if("scan_toggle") - toggle_scan() - - if("alarm_health") - alarm_health = clamp(text2num(params["alarm_health"]), MIN_HEALTH_ACTIVATE, MAX_HEALTH_ACTIVATE) - -#undef MAX_HEALTH_ACTIVATE -#undef MIN_HEALTH_ACTIVATE diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm deleted file mode 100644 index 66aa95bde49b8..0000000000000 --- a/code/modules/assembly/igniter.dm +++ /dev/null @@ -1,91 +0,0 @@ -/obj/item/assembly/igniter - name = "igniter" - desc = "A small electronic device able to ignite combustible substances." - icon_state = "igniter" - materials = list(MAT_METAL=500, MAT_GLASS=50) - origin_tech = "magnets=1" - var/datum/effect_system/spark_spread/sparks - -/obj/item/assembly/igniter/Initialize(mapload) - . = ..() - sparks = new /datum/effect_system/spark_spread - sparks.set_up(2, 0, src) - sparks.attach(src) - -/obj/item/assembly/igniter/Destroy() - QDEL_NULL(sparks) - return ..() - -/obj/item/assembly/igniter/examine(mob/user) - . = ..() - . += "The igniter is [secured ? "secured." : "unsecured."]" - - -/obj/item/assembly/igniter/activate() - if(!..()) - return FALSE //Cooldown check - - var/turf/location = get_turf(loc) - if(location) - location.hotspot_expose(1000, 1) - visible_message( - "Sparks shoot out of [src].", - "You hear a shower of sparks shooting out from something!" - ) - sparks.start() - - if(istype(loc, /obj/item/assembly_holder)) - var/locloc = loc.loc - if(istype(locloc, /obj/structure/reagent_dispensers/fueltank)) - var/obj/structure/reagent_dispensers/fueltank/tank = locloc - if(tank) - tank.boom(TRUE) // this qdel's `src` - - if(istype(locloc, /obj/item/onetankbomb)) - var/obj/item/onetankbomb/bomb = locloc - if(bomb?.bombtank) - bomb.bombtank.detonate() - - else if(istype(locloc, /obj/item/reagent_containers/glass/beaker)) - var/obj/item/reagent_containers/glass/beaker/beakerbomb = locloc - if(beakerbomb) - beakerbomb.heat_beaker() - - else if(istype(locloc, /obj/item/grenade/chem_grenade)) - var/obj/item/grenade/chem_grenade/CG = locloc - CG.prime() - - return TRUE - -/obj/item/assembly/igniter/attack__legacy__attackchain(mob/living/target, mob/living/user) - if(!cigarette_lighter_act(user, target)) - return ..() - -/obj/item/assembly/igniter/cigarette_lighter_act(mob/living/user, mob/living/target, obj/item/direct_attackby_item) - var/obj/item/clothing/mask/cigarette/cig = ..() - if(!cig) - return !isnull(cig) - - if(target == user) - user.visible_message( - "[user] presses [src] against [cig] and activates it, lighting [cig] in a shower of sparks!", - "You press [src] against [cig] and activates it, lighting [cig] in a shower of sparks!", - "You hear a shower of sparks shooting out from something!" - ) - else - user.visible_message( - "[user] presses [src] against [cig] and activates it, lighting [cig] for [target] in a shower of sparks!", - "You press [src] against [cig] and activate it, lighting [cig] in a shower of sparks!", - "You hear a shower of sparks shooting out from something!" - ) - sparks.start() // Make sparks fly! - cig.light(user, target) - return TRUE - -/obj/item/assembly/igniter/attack_self__legacy__attackchain(mob/user) - if(!istype(loc, /obj/item/assembly_holder)) - activate() - add_fingerprint(user) - -/obj/item/assembly/igniter/get_heat() - return 2000 diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm deleted file mode 100644 index a1d997d7879e4..0000000000000 --- a/code/modules/assembly/mousetrap.dm +++ /dev/null @@ -1,152 +0,0 @@ -/obj/item/assembly/mousetrap - name = "mousetrap" - desc = "A handy little spring-loaded trap for catching pesty rodents." - icon_state = "mousetrap" - item_state = "mousetrap" - materials = list(MAT_METAL=100) - origin_tech = "combat=1;materials=2;engineering=1" - var/armed = FALSE - - bomb_name = "contact mine" - -/obj/item/assembly/mousetrap/examine(mob/user) - . = ..() - if(armed) - . += "It looks like it's armed." - . += "Alt-Click to hide it." - -/obj/item/assembly/mousetrap/activate() - if(!..()) - return - - armed = !armed - if(!armed && ishuman(usr)) - var/mob/living/carbon/human/user = usr - if((user.getBrainLoss() >= 60 || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) - to_chat(user, "Your hand slips, setting off the trigger.") - pulse(0) - - update_icon() - - if(usr) - playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, TRUE, -3) - - -/obj/item/assembly/mousetrap/update_icon_state() - icon_state = "mousetrap[armed ? "armed": ""]" - if(holder) - holder.update_icon() - -/obj/item/assembly/mousetrap/proc/triggered(mob/target, type = "feet") - if(!armed) - return - - var/obj/item/organ/external/affecting = null - if(ishuman(target)) - var/mob/living/carbon/human/H = target - if(HAS_TRAIT(H, TRAIT_PIERCEIMMUNE)) - playsound(src, 'sound/effects/snap.ogg', 50, TRUE) - armed = FALSE - update_icon() - pulse(FALSE) - return FALSE - - switch(type) - if("feet") - if(!H.shoes) - affecting = H.get_organ(pick("l_leg", "r_leg")) - H.Weaken(6 SECONDS) - - if("l_hand", "r_hand") - if(!H.gloves) - affecting = H.get_organ(type) - H.Stun(6 SECONDS) - - if(affecting) - affecting.receive_damage(1, 0) - - else if(ismouse(target)) - var/mob/living/simple_animal/mouse/M = target - visible_message("SPLAT!") - M.death() - M.splat() - - playsound(loc, 'sound/effects/snap.ogg', 50, 1) - layer = MOB_LAYER - 0.2 - armed = FALSE - update_icon() - pulse(0) - -/obj/item/assembly/mousetrap/attack_self__legacy__attackchain(mob/living/user) - if(!armed) - to_chat(user, "You arm [src].") - else - if((user.getBrainLoss() >= 60 || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) - var/which_hand = "l_hand" - if(!user.hand) - which_hand = "r_hand" - - triggered(user, which_hand) - user.visible_message("[user] accidentally sets off [src], breaking [user.p_their()] fingers.", "You accidentally trigger [src]!") - return - - to_chat(user, "You disarm [src].") - - armed = !armed - update_icon() - playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, TRUE, -3) - -/obj/item/assembly/mousetrap/attack_hand(mob/living/user) - if(armed) - if((user.getBrainLoss() >= 60 || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) - var/which_hand = "l_hand" - if(!user.hand) - which_hand = "r_hand" - - triggered(user, which_hand) - user.visible_message("[user] accidentally sets off [src], breaking [user.p_their()] fingers.", "You accidentally trigger [src]!") - return - ..() - -/obj/item/assembly/mousetrap/on_atom_entered(datum/source, atom/movable/entered) - if(armed) - if(ishuman(entered)) - var/mob/living/carbon/H = entered - if(H.m_intent == MOVE_INTENT_RUN) - triggered(H) - H.visible_message("[H] accidentally steps on [src].", "You accidentally step on [src]") - - else if(ismouse(entered)) - triggered(entered) - - else if(entered.density) // For mousetrap grenades, set off by anything heavy - triggered(entered) - - ..() - -/obj/item/assembly/mousetrap/on_found(mob/finder) - if(armed) - finder.visible_message("[finder] accidentally sets off [src], breaking [finder.p_their()] fingers.", "You accidentally trigger [src]!") - triggered(finder, finder.hand ? "l_hand" : "r_hand") - return TRUE //end the search! - - return FALSE - -/obj/item/assembly/mousetrap/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) - if(!armed) - return ..() - - visible_message("[src] is triggered by [AM].") - triggered(null) - -/obj/item/assembly/mousetrap/armed - icon_state = "mousetraparmed" - armed = TRUE - - -/obj/item/assembly/mousetrap/AltClick(mob/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) - return - - layer = TURF_LAYER + 0.2 - to_chat(user, "You hide [src].") diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm deleted file mode 100644 index e4dac71db9bd3..0000000000000 --- a/code/modules/assembly/proximity.dm +++ /dev/null @@ -1,186 +0,0 @@ -/obj/item/assembly/prox_sensor - name = "proximity sensor" - desc = "Used for scanning and alerting when someone enters a certain proximity." - icon_state = "prox" - materials = list(MAT_METAL = 800, MAT_GLASS = 200) - origin_tech = "magnets=1;engineering=1" - - secured = FALSE - - bomb_name = "proximity mine" - - var/scanning = FALSE - var/timing = FALSE - COOLDOWN_DECLARE(timing_cd) - var/timing_cd_duration = 10 SECONDS - /// Proximity monitor associated with this atom, needed for it to work. - var/datum/proximity_monitor/proximity_monitor - -/obj/item/assembly/prox_sensor/Initialize(mapload) - . = ..() - proximity_monitor = new(src, 0, FALSE) - COOLDOWN_RESET(src, timing_cd) - -/obj/item/assembly/prox_sensor/Destroy() - . = ..() - QDEL_NULL(proximity_monitor) - -/obj/item/assembly/prox_sensor/examine(mob/user) - . = ..() - if(timing) - . += "The proximity sensor is arming." - else - . += "The proximity sensor is [scanning ? "armed" : "disarmed"]." - -/obj/item/assembly/prox_sensor/activate() - if(!..()) - return FALSE //Cooldown check - timing = !timing - update_icon() - return FALSE - -/obj/item/assembly/prox_sensor/toggle_secure() - secured = !secured - if(secured) - START_PROCESSING(SSfastprocess, src) - else - scanning = FALSE - timing = FALSE - STOP_PROCESSING(SSfastprocess, src) - update_icon() - return secured - -/obj/item/assembly/prox_sensor/HasProximity(atom/movable/AM) - if(!isobj(AM) && !isliving(AM)) - return - if(iseffect(AM)) - return - if(AM.move_speed < 12) - sense() - -/obj/item/assembly/prox_sensor/proc/sense() - if(!secured || !scanning || cooldown > 0) - return FALSE - cooldown = 2 - pulse(FALSE) - visible_message("[bicon(src)] *beep* *beep* *beep*", "*beep* *beep* *beep*") - playsound(src, 'sound/machines/triple_beep.ogg', 40, extrarange = -10) - addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 10) - -/obj/item/assembly/prox_sensor/process() - if(timing && COOLDOWN_FINISHED(src, timing_cd)) - COOLDOWN_RESET(src, timing_cd) - timing = FALSE - toggle_scan() - -/obj/item/assembly/prox_sensor/dropped() - . = ..() - // Pick the first valid object in this list: - // Wiring datum's owner - // assembly holder's attached object - // assembly holder itself - // us - proximity_monitor?.set_host(connected?.holder || holder?.master || holder || src, src) - -/obj/item/assembly/prox_sensor/on_attach() - . = ..() - // Pick the first valid object in this list: - // Wiring datum's owner - // assembly holder's attached object - // assembly holder itself - // us - proximity_monitor.set_host(connected?.holder || holder?.master || holder || src, src) - -/obj/item/assembly/prox_sensor/on_detach() - . = ..() - if(!.) - return - else - // Pick the first valid object in this list: - // Wiring datum's owner - // assembly holder's attached object - // assembly holder itself - // us - proximity_monitor.set_host(connected?.holder || holder?.master || holder || src, src) - -/obj/item/assembly/prox_sensor/proc/toggle_scan() - if(!secured) - return FALSE - scanning = !scanning - proximity_monitor.set_range(scanning ? 1 : 0) - update_icon() - -/obj/item/assembly/prox_sensor/proc/set_timing(timing_) - if(timing == timing_) - return - timing = timing_ - if(timing) - COOLDOWN_START(src, timing_cd, timing_cd_duration) - -/obj/item/assembly/prox_sensor/update_overlays() - . = ..() - attached_overlays = list() - if(timing) - . += "prox_timing" - attached_overlays += "prox_timing" - if(scanning) - . += "prox_scanning" - attached_overlays += "prox_scanning" - if(holder) - holder.update_icon() - -/obj/item/assembly/prox_sensor/Move() - . = ..() - sense() - -/obj/item/assembly/prox_sensor/holder_movement() - sense() - -/obj/item/assembly/prox_sensor/interact(mob/user)//TODO: Change this to the wires thingy - if(!secured) - user.show_message("[src] is unsecured!") - return FALSE - var/timing_ui = "" - var/time_display = "" - if(timing) - var/time_left = COOLDOWN_TIMELEFT(src, timing_cd) - time_display = deciseconds_to_time_stamp(time_left) - timing_ui = "Arming" - else - var/time_left = timing_cd_duration - time_display = deciseconds_to_time_stamp(time_left) - timing_ui = "Not Arming" - var/dat = "Proximity Sensor\n[timing_ui] [time_display]\n- - + +\n" - dat += "
    [scanning?"Armed":"Unarmed"] (Movement sensor active when armed!)" - dat += "

    Refresh" - dat += "

    Close" - var/datum/browser/popup = new(user, "prox", name, 400, 400) - popup.set_content(dat) - popup.open(0) - onclose(user, "prox") - -/obj/item/assembly/prox_sensor/Topic(href, href_list) - ..() - if(HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || usr.stat || usr.restrained() || !in_range(loc, usr)) - usr << browse(null, "window=prox") - onclose(usr, "prox") - return - - if(href_list["scanning"]) - toggle_scan() - - if(href_list["time"]) - set_timing(text2num(href_list["time"])) - update_icon() - - if(href_list["tp"]) - var/tp = text2num(href_list["tp"]) - timing_cd_duration += tp - timing_cd_duration = min(max(round(timing_cd_duration), 0), 1 MINUTES) - - if(href_list["close"]) - usr << browse(null, "window=prox") - return - - if(usr) - attack_self__legacy__attackchain(usr) diff --git a/code/modules/assembly/shock_kit.dm b/code/modules/assembly/shock_kit.dm deleted file mode 100644 index 8ecfa9d1d231d..0000000000000 --- a/code/modules/assembly/shock_kit.dm +++ /dev/null @@ -1,47 +0,0 @@ -/obj/item/assembly/shock_kit - name = "electrohelmet assembly" - desc = "This appears to be made from both an electropack and a helmet." - icon = 'icons/obj/assemblies.dmi' - icon_state = "shock_kit" - var/obj/item/clothing/head/helmet/part1 = null - var/obj/item/electropack/part2 = null - var/status = FALSE - w_class = WEIGHT_CLASS_HUGE - flags = CONDUCT - -/obj/item/assembly/shock_kit/Destroy() - QDEL_NULL(part1) - QDEL_NULL(part2) - return ..() - -/obj/item/assembly/shock_kit/wrench_act(mob/living/user, obj/item/I) - if(status) - return - . = TRUE - var/turf/T = get_turf(src) - part1?.forceMove(T) - part2?.forceMove(T) - part1?.master = null - part2?.master = null - part1 = null - part2 = null - visible_message("[user] disassembles [src].") - qdel(src) - return TRUE - -/obj/item/assembly/shock_kit/screwdriver_act(mob/user, obj/item/I) - status = !status - to_chat(user, "[src] is now [status ? "secured" : "unsecured"]!") - add_fingerprint(user) - return TRUE - -/obj/item/assembly/shock_kit/attack_self__legacy__attackchain(mob/user as mob) - part1.attack_self__legacy__attackchain(user, status) - part2.attack_self__legacy__attackchain(user, status) - add_fingerprint(user) - return - -/obj/item/assembly/shock_kit/proc/shock_invoke() - if(istype(loc, /obj/structure/chair/e_chair)) - var/obj/structure/chair/e_chair/C = loc - C.shock() diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm deleted file mode 100644 index d8f874ac6ed46..0000000000000 --- a/code/modules/assembly/signaler.dm +++ /dev/null @@ -1,118 +0,0 @@ -GLOBAL_LIST_EMPTY(remote_signalers) - -/obj/item/assembly/signaler - name = "remote signaling device" - desc = "Used to remotely activate devices. Allows for syncing when using a signaler on another." - icon_state = "signaller" - item_state = "signaler" - materials = list(MAT_METAL = 400, MAT_GLASS = 120) - origin_tech = "magnets=1;bluespace=1" - wires = ASSEMBLY_WIRE_RECEIVE | ASSEMBLY_WIRE_PULSE | ASSEMBLY_WIRE_RADIO_PULSE | ASSEMBLY_WIRE_RADIO_RECEIVE - secured = TRUE - bomb_name = "remote-control bomb" - /// Are we set to receieve a signal? - var/receiving = FALSE - /// Signal code - var/code = 30 - /// Signal freqency itself - var/frequency = RSD_FREQ - -/obj/item/assembly/signaler/Initialize(mapload) - . = ..() - GLOB.remote_signalers |= src - -/obj/item/assembly/signaler/Destroy() - GLOB.remote_signalers -= src - return ..() - -/obj/item/assembly/signaler/examine(mob/user) - . = ..() - . += "The power light is [receiving ? "on" : "off"]" - . += "Alt+Click to send a signal." - -/obj/item/assembly/signaler/AltClick(mob/user) - to_chat(user, "You activate [src].") - activate() - -/obj/item/assembly/signaler/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(issignaler(W)) - var/obj/item/assembly/signaler/signaler2 = W - if(secured && signaler2.secured) - code = signaler2.code - frequency = signaler2.frequency - to_chat(user, "You transfer the frequency and code to [src].") - return ..() - -/// Called from activate(), actually invokes the signal on other signallers in the world -/obj/item/assembly/signaler/proc/signal() - for(var/obj/item/assembly/signaler/S as anything in GLOB.remote_signalers) - if(S == src) - continue - if(S.receiving && (S.code == code) && (S.frequency == frequency)) - S.signal_callback() - - var/turf/T = get_turf(src) - var/invoking_ckey = "unknown" - if(usr) // sometimes (like when a prox sensor sends a signal) there is no usr - invoking_ckey = usr.key - GLOB.lastsignalers.Add("[SQLtime()] : [invoking_ckey] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]") - investigate_log("[SQLtime()] : [invoking_ckey] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]", "signalers") - -/obj/item/assembly/signaler/proc/signal_callback() - pulse(1) - visible_message("[bicon(src)] *beep* *beep* *beep*") - playsound(src, 'sound/machines/triple_beep.ogg', 40, extrarange = -10) - -// Activation pre-runner, handles cooldown and calls signal(), invoked from ui_act() -/obj/item/assembly/signaler/activate() - if(!..()) - return - - signal() - -/obj/item/assembly/signaler/update_icon_state() - if(holder) - holder.update_icon() - -// UI STUFF // - -/obj/item/assembly/signaler/attack_self__legacy__attackchain(mob/user) - ui_interact(user) - -/obj/item/assembly/signaler/ui_state(mob/user) - return GLOB.deep_inventory_state - -/obj/item/assembly/signaler/ui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "RemoteSignaler", name) - ui.open() - -/obj/item/assembly/signaler/ui_data(mob/user) - var/list/data = list() - data["on"] = receiving - data["frequency"] = frequency - data["code"] = code - data["minFrequency"] = PUBLIC_LOW_FREQ - data["maxFrequency"] = PUBLIC_HIGH_FREQ - return data - -/obj/item/assembly/signaler/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - if(..()) - return - - . = TRUE - - switch(action) - if("recv_power") - receiving = !receiving - - if("signal") - activate() - - if("freq") - frequency = sanitize_frequency(text2num(params["freq"]) * 10) - - if("code") - code = clamp(text2num(params["code"]), 1, 100) - diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm deleted file mode 100644 index ae87e8534b04f..0000000000000 --- a/code/modules/assembly/timer.dm +++ /dev/null @@ -1,129 +0,0 @@ -/obj/item/assembly/timer - name = "timer" - desc = "Used to time things. Works well with contraptions which has to count down. Tick tock." - icon_state = "timer" - materials = list(MAT_METAL=500, MAT_GLASS=50) - origin_tech = "magnets=1;engineering=1" - - secured = FALSE - - bomb_name = "time bomb" - - var/timing = FALSE - var/time = 10 - var/repeat = FALSE - var/set_time = 10 - -/obj/item/assembly/timer/examine(mob/user) - . = ..() - if(timing) - . += "The timer is counting down from [time]!" - else - . += "The timer is set for [time] seconds." - -/obj/item/assembly/timer/activate() - if(!..()) - return FALSE//Cooldown check - timing = !timing - update_icon() - return FALSE - -/obj/item/assembly/timer/toggle_secure() - secured = !secured - if(secured) - START_PROCESSING(SSobj, src) - else - timing = FALSE - STOP_PROCESSING(SSobj, src) - update_icon() - return secured - -/obj/item/assembly/timer/proc/timer_end() - if(!secured || cooldown > 0) - return FALSE - cooldown = 2 - pulse(FALSE) - if(loc) - loc.visible_message("[bicon(src)] *beep* *beep* *beep*", "*beep* *beep* *beep*") - playsound(src, 'sound/machines/triple_beep.ogg', 40, extrarange = -10) - addtimer(CALLBACK(src, PROC_REF(process_cooldown)), 10) - -/obj/item/assembly/timer/process() - if(timing && (time > 0)) - time -= 2 // 2 seconds per process() - if(timing && time <= 0) - timing = repeat - timer_end() - time = set_time - -/obj/item/assembly/timer/update_overlays() - . = ..() - attached_overlays = list() - if(timing) - . += "timer_timing" - attached_overlays += "timer_timing" - if(holder) - holder.update_icon() - -/obj/item/assembly/timer/interact(mob/user as mob)//TODO: Have this use the wires - if(!secured) - user.show_message("[src] is unsecured!") - return FALSE - var/second = time % 60 - var/minute = (time - second) / 60 - var/set_second = set_time % 60 - var/set_minute = (set_time - set_second) / 60 - if(second < 10) second = "0[second]" - if(set_second < 10) set_second = "0[set_second]" - - var/dat = {" - -

    Timing Unit

    - [minute]:[second] [timing?"Stop":"Start"] Reset
    - Repeat: [repeat?"On":"Off"]
    - Timer set for - - - [set_minute]:[set_second] + + -
    -
    -

    - Refresh -

    - Close"} - var/datum/browser/popup = new(user, "timer", name, 400, 400) - popup.set_content(dat) - popup.open(0) - onclose(user, "timer") - -/obj/item/assembly/timer/Topic(href, href_list) - ..() - if(usr.incapacitated() || !in_range(loc, usr)) - usr << browse(null, "window=timer") - onclose(usr, "timer") - return - - if(href_list["time"]) - timing = !timing - if(timing && istype(holder, /obj/item/transfer_valve)) - investigate_log("[key_name(usr)] activated [src] attachment for [loc]", INVESTIGATE_BOMB) - add_attack_logs(usr, holder, "activated [src] attachment on", ATKLOG_FEW) - log_game("[key_name(usr)] activated [src] attachment for [loc]") - update_icon() - if(href_list["reset"]) - time = set_time - - if(href_list["repeat"]) - repeat = !repeat - - if(href_list["tp"]) - var/tp = text2num(href_list["tp"]) - set_time += tp - set_time = min(max(round(set_time), 6), 600) - if(!timing) - time = set_time - - if(href_list["close"]) - usr << browse(null, "window=timer") - return - - if(usr) - attack_self__legacy__attackchain(usr) diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm deleted file mode 100644 index 5db23c7c7e948..0000000000000 --- a/code/modules/assembly/voice.dm +++ /dev/null @@ -1,84 +0,0 @@ -/obj/item/assembly/voice - name = "voice analyzer" - desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated." - icon_state = "voice" - materials = list(MAT_METAL = 500, MAT_GLASS = 50) - origin_tech = "magnets=1;engineering=1" - var/listening = FALSE - var/recorded = null //the activation message - var/recorded_type = 0 // 0 for say, 1 for emote - - bomb_name = "voice-activated bomb" - -/obj/item/assembly/voice/examine(mob/user) - . = ..() - if(recorded || listening) - . += "A meter on it flickers with every nearby sound." - else - . += "It is deactivated." - -/obj/item/assembly/voice/hear_talk(mob/living/M as mob, list/message_pieces) - hear_input(M, multilingual_to_message(message_pieces), 0) - -/obj/item/assembly/voice/hear_message(mob/living/M as mob, msg) - hear_input(M, msg, 1) - -/obj/item/assembly/voice/proc/hear_input(mob/living/M as mob, msg, type) - if(!isliving(M)) - return - - if(listening) - if(findtext(msg, "
    ")) - recorded = strip_html_tags(msg) - else - recorded = msg - recorded_type = type - listening = FALSE - var/turf/T = get_turf(src) //otherwise it won't work in hand - T.visible_message("[bicon(src)] beeps, \"Activation message is [type ? "the sound when one [recorded]" : "'[recorded]'."]\"") - - else if(findtext(msg, recorded) && type == recorded_type) - var/turf/T = get_turf(src) //otherwise it won't work in hand - T.visible_message("[bicon(src)] beeps!") - pulse(0) - -/obj/item/assembly/voice/activate() - return ..() // previously this toggled listning when not in a holder, that's a little silly. It was only called in attack_self that way. - - -/obj/item/assembly/voice/attack_self__legacy__attackchain(mob/user) - if(!user || !secured) - return FALSE - - listening = !listening - var/turf/T = get_turf(src) - T.visible_message("[bicon(src)] beeps, \"[listening ? "Now" : "No longer"] recording input.\"") - return TRUE - - -/obj/item/assembly/voice/toggle_secure() - . = ..() - listening = FALSE - -/obj/item/assembly/voice/noise - name = "noise sensor" - desc = "A simple noise sensor that triggers on vocalizations other than speech." - icon_state = "voice" - materials = list(MAT_METAL = 210, MAT_GLASS = 50) - origin_tech = "magnets=1;engineering=1" - bomb_name = "noise-activated bomb" - -/obj/item/assembly/voice/noise/attack_self__legacy__attackchain(mob/user) - return - -/obj/item/assembly/voice/noise/examine(mob/user) - . = ..() - . += "It does not appear to have any controls." - -/obj/item/assembly/voice/noise/hear_talk(mob/living/M as mob, list/message_pieces) - return - -/obj/item/assembly/voice/noise/hear_message(mob/living/M as mob, msg) - pulse(0) - var/turf/T = get_turf(src) //otherwise it won't work in hand - T.visible_message("[bicon(src)] beeps!") diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm deleted file mode 100644 index 234aa4a500d71..0000000000000 --- a/code/modules/atmospherics/environmental/LINDA_fire.dm +++ /dev/null @@ -1,249 +0,0 @@ - -/atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(reagents) - reagents.temperature_reagents(exposed_temperature) - -/turf/simulated/temperature_expose(exposed_temperature) - if(reagents) - reagents.temperature_reagents(exposed_temperature, 10, 300) - -/turf/proc/hotspot_expose(exposed_temperature, exposed_volume) - return - -/turf/simulated/hotspot_expose(exposed_temperature, exposed_volume) - var/datum/milla_safe/make_hotspot/milla = new() - milla.invoke_async(src, exposed_temperature, exposed_volume) - -/datum/milla_safe/make_hotspot - -/datum/milla_safe/make_hotspot/on_run(turf/simulated/tile, exposed_temperature, exposed_volume) - create_hotspot(tile, exposed_temperature, exposed_volume) - -//This is the icon for fire on turfs. -/obj/effect/hotspot - anchored = TRUE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - icon = 'icons/goonstation/effects/fire.dmi' - icon_state = "1" - layer = MASSIVE_OBJ_LAYER - alpha = 250 - blend_mode = BLEND_ADD - light_range = 2 - - var/volume = 125 - var/temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - // The last tick this hotspot should be alive for. - var/death_timer = 0 - -/obj/effect/hotspot/New() - ..() - dir = pick(GLOB.cardinal) - -/obj/effect/hotspot/proc/update_visuals() - color = heat2color(temperature) - set_light(l_color = color) - var/turf/here = get_turf(src) - var/datum/gas_mixture/gas = here.get_readonly_air() - var/fuel_burnt = gas.fuel_burnt() - if(fuel_burnt > 1) - icon_state = "3" - else if(fuel_burnt > 0.1) - icon_state = "2" - else - icon_state = "1" - - -/obj/effect/hotspot/Initialize(mapload) - . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - -// Garbage collect itself by nulling reference to it - -/obj/effect/hotspot/Destroy() - set_light(0) - var/turf/simulated/T = loc - if(istype(T) && T.active_hotspot == src) - T.active_hotspot = null - return ..() - -/obj/effect/hotspot/proc/recolor() - color = heat2color(temperature) - set_light(l_color = color) - -// TODO: Vestigal, kept temporarily to avoid a merge conflict. -/obj/effect/hotspot/proc/DestroyTurf() - if(issimulatedturf(loc)) - var/turf/simulated/T = loc - if(T.to_be_destroyed && !T.changing_turf) - var/chance_of_deletion - if(T.heat_capacity) //beware of division by zero - chance_of_deletion = T.max_fire_temperature_sustained / T.heat_capacity * 8 //there is no problem with prob(23456), min() was redundant --rastaf0 - else - chance_of_deletion = 100 - if(prob(chance_of_deletion)) - T.ChangeTurf(T.baseturf) - else - T.to_be_destroyed = 0 - T.max_fire_temperature_sustained = 0 - -/obj/effect/hotspot/proc/on_atom_entered(datum/source, mob/living/entered) - SIGNAL_HANDLER // COMSIG_ATOM_ENTERED - - if(istype(entered)) - entered.fire_act() - -/obj/effect/hotspot/singularity_pull() - return - -/// Largely for the fireflash procs below -/obj/effect/hotspot/fake - var/burn_time = 3 SECONDS - -/obj/effect/hotspot/fake/New() - ..() - if(burn_time) - QDEL_IN(src, burn_time) - -/proc/fireflash(atom/center, radius, temp) - if(!temp) - temp = rand(2800, 3200) - for(var/turf/T in view(radius, get_turf(center))) - if(isspaceturf(T)) - continue - if(locate(/obj/effect/hotspot) in T) - continue - if(!can_line(get_turf(center), T, radius + 1)) - continue - - var/obj/effect/hotspot/fake/H = new(T) - H.temperature = temp - H.volume = 400 - H.recolor() - - T.hotspot_expose(H.temperature, H.volume) - for(var/atom/A in T) - if(isliving(A)) - continue - if(A != H) - A.fire_act(null, H.temperature, H.volume) - - if(isfloorturf(T)) - var/turf/simulated/floor/F = T - F.burn_tile() - - for(var/mob/living/L in T) - L.adjust_fire_stacks(3) - L.IgniteMob() - if(ishuman(L)) - var/mob/living/carbon/human/M = L - var/heatBlockPercent = 1 - M.get_heat_protection(temp) - M.bodytemperature += (temp - M.bodytemperature) * heatBlockPercent / 3 - else - L.bodytemperature = (2 * L.bodytemperature + temp) / 3 - -/proc/fireflash_s(atom/center, radius, temp, falloff) - if(temp < T0C + 60) - return list() - var/list/open = list() - var/list/affected = list() - var/list/closed = list() - var/turf/Ce = get_turf(center) - var/max_dist = radius - if(falloff) - max_dist = min((temp - (T0C + 60)) / falloff, radius) - open[Ce] = 0 - while(length(open)) - var/turf/T = open[1] - var/dist = open[T] - open -= T - closed[T] = TRUE - - if(isspaceturf(T)) - continue - if(dist > max_dist) - continue - if(!ff_cansee(Ce, T)) - continue - - var/obj/effect/hotspot/existing_hotspot = locate(/obj/effect/hotspot) in T - var/prev_temp = 0 - var/need_expose = 0 - var/expose_temp = 0 - if(!existing_hotspot) - var/obj/effect/hotspot/fake/H = new(T) - need_expose = TRUE - H.temperature = temp - dist * falloff - expose_temp = H.temperature - H.volume = 400 - H.recolor() - existing_hotspot = H - - else if(existing_hotspot.temperature < temp - dist * falloff) - expose_temp = (temp - dist * falloff) - existing_hotspot.temperature - prev_temp = existing_hotspot.temperature - if(expose_temp > prev_temp * 3) - need_expose = TRUE - existing_hotspot.temperature = temp - dist * falloff - existing_hotspot.recolor() - - affected[T] = existing_hotspot.temperature - if(need_expose && expose_temp) - T.hotspot_expose(expose_temp, existing_hotspot.volume) - for(var/atom/A in T) - if(isliving(A)) - continue - if(A != existing_hotspot) - A.fire_act(null, expose_temp, existing_hotspot.volume) - if(isfloorturf(T)) - var/turf/simulated/floor/F = T - F.burn_tile() - for(var/mob/living/L in T) - L.adjust_fire_stacks(3) - L.IgniteMob() - if(ishuman(L)) - var/mob/living/carbon/human/M = L - var/heatBlockPercent = 1 - M.get_heat_protection(temp) - M.bodytemperature += (temp - M.bodytemperature) * heatBlockPercent / 3 - else - L.bodytemperature = (2 * L.bodytemperature + temp) / 3 - - if(T.density) - continue - - if(dist == max_dist) - continue - - for(var/direction in GLOB.cardinal) - var/turf/link = get_step(T, direction) - if(!link) - continue - // Check if it wasn't already visited and if you can get to that turf - if(!closed[link] && T.CanAtmosPass(direction) && link.CanAtmosPass(turn(direction, 180))) - var/dx = link.x - Ce.x - var/dy = link.y - Ce.y - var/target_dist = max((dist + 1 + sqrt(dx * dx + dy * dy)) / 2, dist) - if(link in open) - if(open[link] > target_dist) - open[link] = target_dist - else - open[link] = target_dist - - return affected - -/proc/fireflash_sm(atom/center, radius, temp, falloff, capped = TRUE, bypass_rng = FALSE) - var/list/affected = fireflash_s(center, radius, temp, falloff) - for(var/turf/simulated/T in affected) - var/mytemp = affected[T] - var/melt = 1643.15 // default steel melting point - var/divisor = melt - if(mytemp >= melt * 2) - var/chance = mytemp / divisor - if(capped) - chance = min(chance, 30) - if(prob(chance) || bypass_rng) - T.visible_message("[T] melts!") - T.burn_down() - return affected diff --git a/code/modules/atmospherics/environmental/LINDA_system.dm b/code/modules/atmospherics/environmental/LINDA_system.dm deleted file mode 100644 index b1baf85060176..0000000000000 --- a/code/modules/atmospherics/environmental/LINDA_system.dm +++ /dev/null @@ -1,147 +0,0 @@ -/turf/proc/CanAtmosPass(direction, consider_objects = TRUE) - if(blocks_air) - return FALSE - - if(!consider_objects) - return TRUE - - for(var/obj/O in contents) - if(istype(O, /obj/item)) - // Items can't block atmos. - continue - - if(!O.CanAtmosPass(direction)) - return FALSE - - return TRUE - -/atom/movable/proc/CanAtmosPass() - return TRUE - -/atom/proc/CanPass(atom/movable/mover, border_dir) - return !density - -/turf/CanPass(atom/movable/mover, border_dir) - var/turf/target = get_step(src, border_dir) - if(!target) - return FALSE - - if(istype(mover)) // turf/Enter(...) will perform more advanced checks - return !density - - else // Now, doing more detailed checks for air movement and air group formation - if(target.blocks_air||blocks_air) - return 0 - - for(var/obj/obstacle in src) - if(!obstacle.CanPass(mover, border_dir)) - return 0 - for(var/obj/obstacle in target) - if(!obstacle.CanPass(mover, src)) - return 0 - - return 1 - -/atom/movable/proc/get_superconductivity(direction) - return OPEN_HEAT_TRANSFER_COEFFICIENT - -/atom/movable/proc/recalculate_atmos_connectivity() - for(var/turf/T in locs) // used by double wide doors and other nonexistant multitile structures - T.recalculate_atmos_connectivity() - -/atom/movable/proc/move_update_air(turf/T) - if(isturf(T)) - T.recalculate_atmos_connectivity() - recalculate_atmos_connectivity() - -//returns a list of adjacent turfs that can share air with this one. -//alldir includes adjacent diagonal tiles that can share -// air with both of the related adjacent cardinal tiles -/turf/proc/GetAtmosAdjacentTurfs(alldir = 0) - if(!issimulatedturf(src)) - return list() - - var/adjacent_turfs = list() - for(var/turf/T in RANGE_EDGE_TURFS(1, src)) - var/direction = get_dir(src, T) - if(!CanAtmosPass(direction)) - continue - if(!T.CanAtmosPass(turn(direction, 180))) - continue - adjacent_turfs += T - - if(!alldir) - return adjacent_turfs - - for(var/turf/T in RANGE_TURFS(1, src)) - var/direction = get_dir(src, T) - if(IS_DIR_CARDINAL(direction)) - continue - // check_direction is the first way we move, from src - for(var/check_direction in GLOB.cardinal) - if(!(check_direction & direction)) - // Wrong way. - continue - - var/turf/intermediate = get_step(src, check_direction) - if(!(intermediate in adjacent_turfs)) - continue - - // other_direction is the second way we move, from intermediate. - var/other_direction = direction & ~check_direction - - // We already know we can reach intermediate, so now we just need to check the second step. - if(!intermediate.CanAtmosPass(other_direction)) - continue - if(!T.CanAtmosPass(turn(other_direction, 180))) - continue - - adjacent_turfs += T - break - - return adjacent_turfs - -/atom/movable/proc/atmos_spawn_air(flag, amount) //because a lot of people loves to copy paste awful code lets just make a easy proc to spawn your plasma fires - var/turf/simulated/T = get_turf(src) - if(!istype(T)) - return - T.atmos_spawn_air(flag, amount) - -/turf/simulated/proc/atmos_spawn_air(flag, amount) - if(!flag || !amount || blocks_air) - return - - var/datum/gas_mixture/G = new() - - if(flag & LINDA_SPAWN_20C) - G.set_temperature(T20C) - - if(flag & LINDA_SPAWN_HEAT) - G.set_temperature(G.temperature() + 1000) - - if(flag & LINDA_SPAWN_COLD) - G.set_temperature(TCMB) - - if(flag & LINDA_SPAWN_TOXINS) - G.set_toxins(G.toxins() + amount) - - if(flag & LINDA_SPAWN_OXYGEN) - G.set_oxygen(G.oxygen() + amount) - - if(flag & LINDA_SPAWN_CO2) - G.set_carbon_dioxide(G.carbon_dioxide() + amount) - - if(flag & LINDA_SPAWN_NITROGEN) - G.set_nitrogen(G.nitrogen() + amount) - - if(flag & LINDA_SPAWN_N2O) - G.set_sleeping_agent(G.sleeping_agent() + amount) - - if(flag & LINDA_SPAWN_AGENT_B) - G.set_agent_b(G.agent_b() + amount) - - if(flag & LINDA_SPAWN_AIR) - G.set_oxygen(G.oxygen() + MOLES_O2STANDARD * amount) - G.set_nitrogen(G.nitrogen() + MOLES_N2STANDARD * amount) - - blind_release_air(G) diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 510b981fceec7..ef20f0937e43f 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -33,9 +33,6 @@ What are the archived variables for? var/private_sleeping_agent = 0 var/private_agent_b = 0 var/private_temperature = 0 //in Kelvin - var/private_hotspot_temperature = 0 - var/private_hotspot_volume = 0 - var/private_fuel_burnt = 0 // Archived versions of the private fields. // Only gas_mixture should use these. @@ -50,6 +47,13 @@ What are the archived variables for? /// Is this mixture currently synchronized with MILLA? Always true for non-bound mixtures. var/synchronized = TRUE + /// Tracks the callbacks from synchronize() that haven't run yet. + var/list/waiting_for_sync = list() + +/datum/gas_mixture/Destroy() + waiting_for_sync.Cut() + return ..() + /// Marks this gas mixture as changed from MILLA. Does nothing on non-bound mixtures. /datum/gas_mixture/proc/set_dirty() return @@ -96,15 +100,6 @@ What are the archived variables for? /datum/gas_mixture/proc/set_temperature(value) private_temperature = value -/datum/gas_mixture/proc/hotspot_temperature() - return private_hotspot_temperature - -/datum/gas_mixture/proc/hotspot_volume() - return private_hotspot_volume - -/datum/gas_mixture/proc/fuel_burnt() - return private_fuel_burnt - ///joules per kelvin /datum/gas_mixture/proc/heat_capacity() return HEAT_CAPACITY_CALCULATION(private_oxygen, private_carbon_dioxide, private_nitrogen, private_toxins, private_sleeping_agent, private_agent_b, innate_heat_capacity) @@ -654,9 +649,6 @@ What are the archived variables for? private_agent_b = milla[MILLA_INDEX_AGENT_B] innate_heat_capacity = milla[MILLA_INDEX_INNATE_HEAT_CAPACITY] private_temperature = milla[MILLA_INDEX_TEMPERATURE] - private_hotspot_temperature = milla[MILLA_INDEX_HOTSPOT_TEMPERATURE] - private_hotspot_volume = milla[MILLA_INDEX_HOTSPOT_VOLUME] - private_fuel_burnt = milla[MILLA_INDEX_FUEL_BURNT] /proc/share_many_airs(list/mixtures) var/total_volume = 0 @@ -748,8 +740,16 @@ What are the archived variables for? G.private_temperature = temperature // In theory, we should G.set_dirty() here, but that's only useful for bound mixtures, and these can't be. -/datum/gas_mixture/proc/hotspot_expose(temperature, volume) - return + + +///Mathematical proofs: +/** +get_breath_partial_pressure(gas_pp) --> gas_pp/total_moles()*breath_pp = pp +get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles() + +10/20*5 = 2.5 +10 = 2.5/5*20 +**/ #undef SPECIFIC_HEAT_TOXIN #undef SPECIFIC_HEAT_AIR @@ -783,9 +783,6 @@ What are the archived variables for? readonly.private_sleeping_agent = private_sleeping_agent readonly.private_agent_b = private_agent_b readonly.private_temperature = private_temperature - readonly.private_hotspot_temperature = private_hotspot_temperature - readonly.private_hotspot_volume = private_hotspot_volume - readonly.private_fuel_burnt = private_fuel_burnt if(istype(bound_turf, /turf/simulated)) var/turf/simulated/S = bound_turf @@ -820,12 +817,6 @@ What are the archived variables for? private_temperature = value set_dirty() -/datum/gas_mixture/bound_to_turf/hotspot_expose(temperature, volume) - if(temperature > private_temperature) - set_dirty() - private_hotspot_temperature = max(private_hotspot_temperature, temperature) - private_hotspot_volume = max(private_hotspot_volume, (volume / CELL_VOLUME)) - /datum/gas_mixture/bound_to_turf/proc/private_unsafe_write() set_tile_atmos(bound_turf, oxygen = private_oxygen, carbon_dioxide = private_carbon_dioxide, nitrogen = private_nitrogen, toxins = private_toxins, sleeping_agent = private_sleeping_agent, agent_b = private_agent_b, temperature = private_temperature) @@ -846,9 +837,6 @@ What are the archived variables for? private_agent_b = parent.private_agent_b private_temperature = parent.private_temperature - private_hotspot_temperature = parent.private_hotspot_temperature - private_hotspot_volume = parent.private_hotspot_volume - private_fuel_burnt = parent.private_fuel_burnt /datum/gas_mixture/readonly/set_dirty() CRASH("Attempted to modify a readonly gas_mixture.") diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 5216ac330ebd8..5f085927dac5f 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -47,19 +47,6 @@ #define MAX_TEMPERATURE 363.15 // 90C #define MIN_TEMPERATURE 233.15 // -40C -GLOBAL_LIST_INIT(aalarm_modes, list( - "[AALARM_MODE_FILTERING]" = "Filtering", - "[AALARM_MODE_DRAUGHT]" = "Draught", - "[AALARM_MODE_PANIC]" = "Panic", - "[AALARM_MODE_CYCLE]" = "Cycle", - "[AALARM_MODE_SIPHON]" = "Siphon", - "[AALARM_MODE_CONTAMINATED]" = "Contaminated", - "[AALARM_MODE_REFILL]" = "Refill", - "[AALARM_MODE_CUSTOM]" = "Custom", - "[AALARM_MODE_OFF]" = "Off", - "[AALARM_MODE_FLOOD]" = "Flood", -)) - /obj/machinery/alarm name = "air alarm" desc = "A wall-mounted device used to control atmospheric equipment. It looks a little cheaply made..." @@ -88,7 +75,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list( var/AAlarmwires = 31 var/shorted = FALSE - var/mode = AALARM_MODE_FILTERING + var/mode = AALARM_MODE_SCRUBBING var/preset = AALARM_PRESET_HUMAN var/area/alarm_area var/danger_level = ATMOS_ALARM_NONE @@ -200,7 +187,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list( ) if(!no_cycle_after) - mode = AALARM_MODE_CYCLE + mode = AALARM_MODE_REPLACEMENT apply_mode() /obj/machinery/alarm/Initialize(mapload, direction, building = 0) @@ -264,15 +251,6 @@ GLOBAL_LIST_INIT(aalarm_modes, list( cur_tlv = TLV["pressure"] var/environment_pressure = environment.return_pressure() var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure) - if(environment_pressure < cur_tlv.min2 && mode == AALARM_MODE_FILTERING) - mode = AALARM_MODE_OFF - apply_mode() - var/area/A = location.loc - A.firealert(src) - - if(mode == AALARM_MODE_REFILL && environment_pressure >= cur_tlv.min1) - mode = AALARM_MODE_FILTERING - apply_mode() cur_tlv = TLV["oxygen"] var/oxygen_dangerlevel = cur_tlv.get_danger_level(environment.oxygen() * GET_PP) @@ -310,9 +288,8 @@ GLOBAL_LIST_INIT(aalarm_modes, list( if(old_danger_level != danger_level) apply_danger_level() - cur_tlv = TLV["pressure"] - if(mode == AALARM_MODE_CYCLE && environment_pressure < cur_tlv.min2 * 0.05) - mode = AALARM_MODE_REFILL + if(mode == AALARM_MODE_REPLACEMENT && environment_pressure < ONE_ATMOSPHERE * 0.05) + mode = AALARM_MODE_SCRUBBING apply_mode() /datum/milla_safe/airalarm_heat_cool @@ -393,9 +370,8 @@ GLOBAL_LIST_INIT(aalarm_modes, list( underlays += emissive_appearance(icon, "alarm_lightmask") /obj/machinery/alarm/proc/apply_mode() - var/datum/tlv/pressure_tlv = TLV["pressure"] switch(mode) - if(AALARM_MODE_FILTERING) + if(AALARM_MODE_SCRUBBING) for(var/obj/machinery/atmospherics/unary/vent_scrubber/S as anything in alarm_area.scrubbers) if(S.stat & (NOPOWER|BROKEN)) continue @@ -413,8 +389,8 @@ GLOBAL_LIST_INIT(aalarm_modes, list( if(P.stat & (NOPOWER|BROKEN)) continue P.on = TRUE - P.pressure_checks = ONLY_CHECK_EXT_PRESSURE - P.external_pressure_bound = (pressure_tlv.min1 + pressure_tlv.max1) / 2 + P.pressure_checks = TRUE + P.external_pressure_bound = ONE_ATMOSPHERE P.update_icon(UPDATE_ICON_STATE) @@ -434,12 +410,12 @@ GLOBAL_LIST_INIT(aalarm_modes, list( if(P.stat & (NOPOWER|BROKEN)) continue P.on = TRUE - P.pressure_checks = ONLY_CHECK_EXT_PRESSURE - P.external_pressure_bound = (pressure_tlv.min1 + pressure_tlv.max1) / 2 + P.pressure_checks = TRUE + P.external_pressure_bound = ONE_ATMOSPHERE P.update_icon(UPDATE_ICON_STATE) - if(AALARM_MODE_DRAUGHT) + if(AALARM_MODE_VENTING) for(var/obj/machinery/atmospherics/unary/vent_scrubber/S as anything in alarm_area.scrubbers) if(S.stat & (NOPOWER|BROKEN)) continue @@ -452,8 +428,8 @@ GLOBAL_LIST_INIT(aalarm_modes, list( if(P.stat & (NOPOWER|BROKEN)) continue P.on = TRUE - P.pressure_checks = ONLY_CHECK_EXT_PRESSURE - P.external_pressure_bound = pressure_tlv.max1 + P.pressure_checks = TRUE + P.external_pressure_bound = ONE_ATMOSPHERE * 2 P.update_icon(UPDATE_ICON_STATE) @@ -473,12 +449,12 @@ GLOBAL_LIST_INIT(aalarm_modes, list( if(P.stat & (NOPOWER|BROKEN)) continue P.on = TRUE - P.pressure_checks = ONLY_CHECK_EXT_PRESSURE - P.external_pressure_bound = (pressure_tlv.min1 + pressure_tlv.max1) / 2 + P.pressure_checks = TRUE + P.external_pressure_bound = ONE_ATMOSPHERE * 3 P.update_icon(UPDATE_ICON_STATE) - if(AALARM_MODE_PANIC, AALARM_MODE_CYCLE) + if(AALARM_MODE_PANIC, AALARM_MODE_REPLACEMENT) for(var/obj/machinery/atmospherics/unary/vent_scrubber/S as anything in alarm_area.scrubbers) if(S.stat & (NOPOWER|BROKEN)) continue @@ -535,7 +511,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list( if(P.stat & (NOPOWER|BROKEN)) continue P.on = TRUE - P.pressure_checks = ONLY_CHECK_INT_PRESSURE + P.pressure_checks = 2 P.internal_pressure_bound = 0 P.update_icon(UPDATE_ICON_STATE) @@ -672,16 +648,15 @@ GLOBAL_LIST_INIT(aalarm_modes, list( data["atmos_alarm"] = alarm_area.atmosalm data["emagged"] = emagged data["modes"] = list( - "mode[AALARM_MODE_FILTERING]" = list("name"=GLOB.aalarm_modes["[AALARM_MODE_FILTERING]"], "desc"="Scrubs out contaminants. Will shut off and drop firelocks if pressure drops too low.", "id" = AALARM_MODE_FILTERING), - "mode[AALARM_MODE_DRAUGHT]" = list("name"=GLOB.aalarm_modes["[AALARM_MODE_DRAUGHT]"], "desc"="Siphons out air while replacing", "id" = AALARM_MODE_DRAUGHT), - "mode[AALARM_MODE_PANIC]" = list("name"=GLOB.aalarm_modes["[AALARM_MODE_PANIC]"], "desc"="Siphons air out of the room quickly", "id" = AALARM_MODE_PANIC), - "mode[AALARM_MODE_CYCLE]" = list("name"=GLOB.aalarm_modes["[AALARM_MODE_CYCLE]"], "desc"="Siphons air before replacing", "id" = AALARM_MODE_CYCLE), - "mode[AALARM_MODE_SIPHON]" = list("name"=GLOB.aalarm_modes["[AALARM_MODE_SIPHON]"], "desc"="Siphons air out of the room", "id" = AALARM_MODE_SIPHON), - "mode[AALARM_MODE_CONTAMINATED]" = list("name"=GLOB.aalarm_modes["[AALARM_MODE_CONTAMINATED]"], "desc"="Scrubs out all contaminants quickly", "id" = AALARM_MODE_CONTAMINATED), - "mode[AALARM_MODE_REFILL]" = list("name"=GLOB.aalarm_modes["[AALARM_MODE_REFILL]"], "desc"="Refills a room to normal pressure, then switches to Filtering.", "id" = AALARM_MODE_REFILL), - "mode[AALARM_MODE_CUSTOM]" = list("name"=GLOB.aalarm_modes["[AALARM_MODE_CUSTOM]"], "desc"="Custom settings with no automatic mode switching.", "id" = AALARM_MODE_CUSTOM), - "mode[AALARM_MODE_OFF]" = list("name"=GLOB.aalarm_modes["[AALARM_MODE_OFF]"], "desc"="Shuts off vents and scrubbers", "id" = AALARM_MODE_OFF), - "mode[AALARM_MODE_FLOOD]" = list("name"=GLOB.aalarm_modes["[AALARM_MODE_FLOOD]"], "desc"="Shuts off scrubbers and opens vents", "emagonly" = TRUE, "id" = AALARM_MODE_FLOOD) + AALARM_MODE_SCRUBBING = list("name"="Filtering", "desc"="Scrubs out contaminants", "id" = AALARM_MODE_SCRUBBING),\ + AALARM_MODE_VENTING = list("name"="Draught", "desc"="Siphons out air while replacing", "id" = AALARM_MODE_VENTING),\ + AALARM_MODE_PANIC = list("name"="Panic Siphon","desc"="Siphons air out of the room quickly", "id" = AALARM_MODE_PANIC),\ + AALARM_MODE_REPLACEMENT = list("name"="Cycle", "desc"="Siphons air before replacing", "id" = AALARM_MODE_REPLACEMENT),\ + AALARM_MODE_SIPHON = list("name"="Siphon", "desc"="Siphons air out of the room", "id" = AALARM_MODE_SIPHON),\ + AALARM_MODE_CONTAMINATED= list("name"="Contaminated","desc"="Scrubs out all contaminants quickly", "id" = AALARM_MODE_CONTAMINATED),\ + AALARM_MODE_REFILL = list("name"="Refill", "desc"="Triples vent output", "id" = AALARM_MODE_REFILL),\ + AALARM_MODE_OFF = list("name"="Off", "desc"="Shuts off vents and scrubbers", "id" = AALARM_MODE_OFF),\ + AALARM_MODE_FLOOD = list("name"="Flood", "desc"="Shuts off scrubbers and opens vents", "emagonly" = TRUE, "id" = AALARM_MODE_FLOOD) ) data["mode"] = mode data["presets"] = list( @@ -874,8 +849,6 @@ GLOBAL_LIST_INIT(aalarm_modes, list( message_admins("[key_name_admin(usr)] attempted to href-exploit an air alarm to control another object!!!") return - mode = AALARM_MODE_CUSTOM - // Its a vent. Handle if(istype(U, /obj/machinery/atmospherics/unary/vent_pump)) var/obj/machinery/atmospherics/unary/vent_pump/V = U @@ -998,7 +971,11 @@ GLOBAL_LIST_INIT(aalarm_modes, list( playsound(src.loc, 'sound/effects/sparks4.ogg', 50, TRUE) return TRUE +<<<<<<< HEAD /obj/machinery/alarm/item_interaction(mob/living/user, obj/item/used, list/modifiers) +======= +/obj/machinery/alarm/attackby(obj/item/I, mob/user, params) +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb add_fingerprint(user) switch(buildstage) diff --git a/code/modules/atmospherics/machinery/atmospherics.dm b/code/modules/atmospherics/machinery/atmospherics.dm index 988048aaf5563..d7b9ce253c52b 100644 --- a/code/modules/atmospherics/machinery/atmospherics.dm +++ b/code/modules/atmospherics/machinery/atmospherics.dm @@ -256,7 +256,11 @@ Pipelines + Other Objects -> Pipe network return FALSE //(De)construction +<<<<<<< HEAD /obj/machinery/atmospherics/item_interaction(mob/living/user, obj/item/used, list/modifiers) +======= +/obj/machinery/atmospherics/attackby(obj/item/W, mob/user) +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb var/turf/T = get_turf(src) if(T.transparent_floor) to_chat(user, "You can't interact with something that's under the floor!") diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index c6c135990f95f..9ac6fd60c43fb 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -157,9 +157,16 @@ Thus, the two variables affect pump operation are set in New(): return update_icon() +<<<<<<< HEAD /obj/machinery/atmospherics/binary/bump/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(is_pen(used)) rename_interactive(user, used) return ITEM_INTERACT_COMPLETE +======= +/obj/machinery/atmospherics/binary/pump/attackby(obj/item/W, mob/user, params) + if(is_pen(W)) + rename_interactive(user, W) + return TRUE +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb return ..() 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 0bae5c086d31a..b96c024890191 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -153,9 +153,16 @@ Thus, the two variables affect pump operation are set in New(): return update_icon() +<<<<<<< HEAD /obj/machinery/atmospherics/binary/volume_pump/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(is_pen(used)) rename_interactive(user, used) return ITEM_INTERACT_COMPLETE +======= +/obj/machinery/atmospherics/binary/volume_pump/attackby(obj/item/W, mob/user, params) + if(is_pen(W)) + rename_interactive(user, W) + return TRUE +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb return ..() diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 658862ea78367..9e474034e7ea8 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -227,12 +227,21 @@ if(.) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") +<<<<<<< HEAD /obj/machinery/atmospherics/trinary/filter/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(is_pen(used)) rename_interactive(user, used) return ITEM_INTERACT_COMPLETE return ..() +======= +/obj/machinery/atmospherics/trinary/filter/attackby(obj/item/W, mob/user, params) + if(is_pen(W)) + rename_interactive(user, W) + return + else + return ..() +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb #undef FILTER_NOTHING #undef FILTER_TOXINS diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index 99d814a821924..8896284b15a64 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -201,9 +201,18 @@ if(.) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") +<<<<<<< HEAD /obj/machinery/atmospherics/trinary/mixer/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(is_pen(used)) rename_interactive(user, used) return ITEM_INTERACT_COMPLETE return ..() +======= +/obj/machinery/atmospherics/trinary/mixer/attackby(obj/item/W, mob/user, params) + if(is_pen(W)) + rename_interactive(user, W) + return + else + return ..() +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 3fffb34b925ba..304dfccdca2e4 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -298,9 +298,15 @@ add_fingerprint(usr) +<<<<<<< HEAD /obj/machinery/atmospherics/unary/cryo_cell/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(istype(used, /obj/item/reagent_containers/glass) && user.a_intent != INTENT_HARM) var/obj/item/reagent_containers/B = used +======= +/obj/machinery/atmospherics/unary/cryo_cell/attackby(obj/item/G, mob/user, params) + if(istype(G, /obj/item/reagent_containers/glass) && user.a_intent != INTENT_HARM) + var/obj/item/reagent_containers/B = G +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb if(beaker) to_chat(user, "A beaker is already loaded into the machine.") return ITEM_INTERACT_COMPLETE 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 f88104e808b50..1aa7e9fff8151 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm @@ -44,7 +44,7 @@ if(pressure_delta > 0) // transfer from pipe air to environment if((vent.air_contents.total_moles() > 0) && (vent.air_contents.temperature() > 0)) - var/transfer_moles = pressure_delta * vent.air_contents.volume / (vent.air_contents.temperature() * R_IDEAL_GAS_EQUATION) + var/transfer_moles = pressure_delta * environment.volume / (vent.air_contents.temperature() * R_IDEAL_GAS_EQUATION) transfer_moles = min(transfer_moles, vent.volume) var/datum/gas_mixture/removed = vent.air_contents.remove(transfer_moles) 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 630da74b8e637..b155d31cb0adc 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -1,5 +1,6 @@ #define EXTERNAL_PRESSURE_BOUND ONE_ATMOSPHERE #define INTERNAL_PRESSURE_BOUND 0 +#define PRESSURE_CHECKS 1 /obj/machinery/atmospherics/unary/vent_pump name = "air vent" @@ -10,27 +11,29 @@ plane = FLOOR_PLANE layer = GAS_PIPE_VISIBLE_LAYER + GAS_SCRUBBER_OFFSET layer_offset = GAS_SCRUBBER_OFFSET - can_unwrench = TRUE - /// Is the vent open to put a piece of paper in it - var/open = FALSE // A living relic of papercult + can_unwrench = TRUE + var/open = FALSE var/area/initial_loc - /// If false, siphons instead of releasing air - var/releasing = TRUE - var/max_transfer_joules = 200 /*kPa*/ * 2 * ONE_ATMOSPHERE + var/releasing = TRUE //FALSE = siphoning, TRUE = releasing var/external_pressure_bound = EXTERNAL_PRESSURE_BOUND var/internal_pressure_bound = INTERNAL_PRESSURE_BOUND - /// What do we check when releasing/siphoning air - internal or external pressure - var/pressure_checks = ONLY_CHECK_EXT_PRESSURE + var/pressure_checks = PRESSURE_CHECKS + //1: Do not pass external_pressure_bound + //2: Do not pass internal_pressure_bound + //3: Do not pass either + + // Used when handling incoming radio signals requesting default settings + var/external_pressure_bound_default = EXTERNAL_PRESSURE_BOUND + var/internal_pressure_bound_default = INTERNAL_PRESSURE_BOUND + var/pressure_checks_default = PRESSURE_CHECKS - /// Is this vent welded shut - var/welded = FALSE - /// How much pressure does there have to be in the pipe to burst the vent open? - var/weld_burst_pressure = 50 * ONE_ATMOSPHERE + var/welded = FALSE // Added for aliens -- TLE + var/weld_burst_pressure = 50 * ONE_ATMOSPHERE //the (internal) pressure at which welded covers will burst off connect_types = list(CONNECT_TYPE_NORMAL, CONNECT_TYPE_SUPPLY) //connects to regular and supply pipes @@ -133,6 +136,7 @@ var/datum/gas_mixture/environment = T.get_readonly_air() if(releasing) //internal -> external var/pressure_delta = 10000 +<<<<<<< HEAD if(pressure_checks == ONLY_CHECK_EXT_PRESSURE) // Only checks difference between set pressure and environment pressure pressure_delta = min(pressure_delta, (external_pressure_bound - environment.return_pressure())) @@ -151,6 +155,31 @@ else //external -> internal var/datum/milla_safe/vent_pump_siphon/milla = new() milla.invoke_async(src) +======= + if(vent_pump.pressure_checks & 1) + pressure_delta = min(pressure_delta, (vent_pump.external_pressure_bound - environment_pressure)) + if(vent_pump.pressure_checks & 2) + pressure_delta = min(pressure_delta, (vent_pump.air_contents.return_pressure() - vent_pump.internal_pressure_bound)) + + if(pressure_delta > 0.5 && vent_pump.air_contents.temperature() > 0) + var/transfer_moles = pressure_delta * environment.volume / (vent_pump.air_contents.temperature() * R_IDEAL_GAS_EQUATION) + var/datum/gas_mixture/removed = vent_pump.air_contents.remove(transfer_moles) + environment.merge(removed) + vent_pump.parent.update = TRUE + + else //external -> internal + var/pressure_delta = 10000 + if(vent_pump.pressure_checks & 1) + pressure_delta = min(pressure_delta, (environment_pressure - vent_pump.external_pressure_bound)) + if(vent_pump.pressure_checks & 2) + pressure_delta = min(pressure_delta, (vent_pump.internal_pressure_bound - vent_pump.air_contents.return_pressure())) + + if(pressure_delta > 0.5 && environment.temperature() > 0) + var/transfer_moles = pressure_delta * vent_pump.air_contents.volume / (environment.temperature() * R_IDEAL_GAS_EQUATION) + var/datum/gas_mixture/removed = environment.remove(transfer_moles) + vent_pump.air_contents.merge(removed) + vent_pump.parent.update = TRUE +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb return TRUE @@ -186,8 +215,13 @@ pipe_image.plane = ABOVE_HUD_PLANE playsound(loc, 'sound/weapons/bladeslice.ogg', 100, TRUE) +<<<<<<< HEAD /obj/machinery/atmospherics/unary/vent_pump/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(istype(used, /obj/item/paper)) +======= +/obj/machinery/atmospherics/unary/vent_pump/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/paper)) +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb if(!welded) if(open) user.drop_item(used) @@ -256,3 +290,4 @@ #undef EXTERNAL_PRESSURE_BOUND #undef INTERNAL_PRESSURE_BOUND +#undef PRESSURE_CHECKS diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index e8023b2a3ba76..c7cf82a9754d0 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -46,10 +46,14 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) -#define LOW_PRESSURE 0 -#define NORMAL_PRESSURE 1 -#define HIGH_PRESSURE 2 -#define EXTREME_PRESSURE 3 +#define HOLDING_TANK (1<<0) +#define CONNECTED_PORT (1<<1) +#define LOW_PRESSURE (1<<2) +#define NORMAL_PRESSURE (1<<3) +#define HIGH_PRESSURE (1<<4) +#define EXTREME_PRESSURE (1<<5) +#define NEW_COLOR (1<<6) +#define RESET (LOW_PRESSURE | NEW_COLOR) /obj/machinery/atmospherics/portable/canister name = "canister" @@ -67,6 +71,9 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) var/list/canister_color //variable that stores colours var/list/color_index // list which stores tgui color indexes for the recoloring options, to enable previously-set colors to show up right + //lists for check_change() + var/list/old_color + //passed to the ui to render the color lists var/list/colorcontainer @@ -78,7 +85,7 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) power_state = NO_POWER_USE interact_offline = TRUE var/release_log = "" - var/current_pressure_appearance + var/update_flag = NONE /obj/machinery/atmospherics/portable/canister/Initialize(mapload) . = ..() @@ -90,6 +97,8 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) "quart" = "none" ) + old_color = list() + colorcontainer = list( "prim" = list( "options" = GLOB.canister_icon_container.possiblemaincolor, @@ -121,18 +130,37 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) if(isAntag(user)) . += "Canisters can be damaged, spilling their contents into the air, or you can just leave the release valve open." -/obj/machinery/atmospherics/portable/canister/proc/pressure_to_appearance(tank_pressure) +/obj/machinery/atmospherics/portable/canister/proc/check_change() + var/old_flag = update_flag + update_flag = NONE + if(holding_tank) + update_flag |= HOLDING_TANK + if(connected_port) + update_flag |= CONNECTED_PORT + + var/tank_pressure = air_contents.return_pressure() if(tank_pressure < 10) - return LOW_PRESSURE + update_flag |= LOW_PRESSURE else if(tank_pressure < ONE_ATMOSPHERE) - return NORMAL_PRESSURE - else if(tank_pressure < 15 * ONE_ATMOSPHERE) - return HIGH_PRESSURE + update_flag |= NORMAL_PRESSURE + else if(tank_pressure < 15*ONE_ATMOSPHERE) + update_flag |= HIGH_PRESSURE else - return EXTREME_PRESSURE + update_flag |= EXTREME_PRESSURE + + if(list2params(old_color) != list2params(canister_color)) + update_flag |= NEW_COLOR + old_color = canister_color.Copy() + + if(update_flag == old_flag) + return FALSE + return TRUE /obj/machinery/atmospherics/portable/canister/update_icon_state() - // Colors has to be applied every icon update +/* +(note: colors has to be applied every icon update) +*/ + if(stat & BROKEN) icon_state = "[canister_color["prim"]]-1"//yes, I KNOW the colours don't reflect when the can's borked, whatever. return @@ -140,6 +168,9 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) if(icon_state != canister_color["prim"]) icon_state = canister_color["prim"] + if(!check_change()) //Returns FALSE if no change needed to icons. + return + /obj/machinery/atmospherics/portable/canister/update_overlays() . = ..() if(stat & BROKEN) @@ -152,20 +183,22 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) continue . += canister_color[C] - if(holding_tank) + if(update_flag & HOLDING_TANK) . += "can-open" - if(connected_port) + if(update_flag & CONNECTED_PORT) . += "can-connector" - - if(current_pressure_appearance == LOW_PRESSURE) + if(update_flag & LOW_PRESSURE) . += "can-o0" - else if(current_pressure_appearance == NORMAL_PRESSURE) + if(update_flag & NORMAL_PRESSURE) . += "can-o1" - else if(current_pressure_appearance == HIGH_PRESSURE) + else if(update_flag & HIGH_PRESSURE) . += "can-o2" - else if(current_pressure_appearance == EXTREME_PRESSURE) + else if(update_flag & EXTREME_PRESSURE) . += "can-o3" + update_flag &= ~RESET //the flag NEW_COLOR represents change, not states. As such, we have to reset them to be able to detect a change on the next go. + return + /obj/machinery/atmospherics/portable/canister/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) ..() if(exposed_temperature > temperature_resistance) @@ -201,24 +234,48 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) T.blind_release_air(expelled_gas) -/obj/machinery/atmospherics/portable/canister/proc/sync_pressure_appearance() - var/new_pressure_appearance = pressure_to_appearance(air_contents.return_pressure()) - if(current_pressure_appearance != new_pressure_appearance) - current_pressure_appearance = new_pressure_appearance - update_icon() - /obj/machinery/atmospherics/portable/canister/process_atmos() ..() +<<<<<<< HEAD sync_pressure_appearance() if(stat & BROKEN) +======= + var/datum/milla_safe/canister_process/milla = new() + milla.invoke_async(src) + +/datum/milla_safe/canister_process + +/datum/milla_safe/canister_process/on_run(obj/machinery/atmospherics/portable/canister/canister) + if(canister.stat & BROKEN) +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb return if(valve_open) var/datum/milla_safe/canister_release/milla = new() milla.invoke_async(src) +<<<<<<< HEAD if(air_contents.return_pressure() < 1) can_label = TRUE +======= + var/env_pressure = environment.return_pressure() + var/pressure_delta = min(canister.release_pressure - env_pressure, (canister.air_contents.return_pressure() - env_pressure) / 2) + //Can not have a pressure delta that would cause environment pressure > tank pressure + + var/transfer_moles = 0 + if((canister.air_contents.temperature() > 0) && (pressure_delta > 0)) + transfer_moles = pressure_delta * environment.volume / (canister.air_contents.temperature() * R_IDEAL_GAS_EQUATION) + + //Actually transfer the gas + var/datum/gas_mixture/removed = canister.air_contents.remove(transfer_moles) + + environment.merge(removed) + canister.update_icon() + + + if(canister.air_contents.return_pressure() < 1) + canister.can_label = TRUE +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb else can_label = FALSE @@ -330,7 +387,6 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) name = T else name = "canister" - update_appearance(UPDATE_NAME) else to_chat(ui.user, "As you attempted to rename it the pressure rose!") . = FALSE @@ -398,9 +454,9 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) color_index[ctype] = newcolor newcolor++ // javascript starts arrays at 0, byond (for some reason) starts them at 1, this converts JS values to byond values canister_color[ctype] = colorcontainer[ctype]["options"][newcolor]["icon"] - update_icon() add_fingerprint(ui.user) + update_icon() /obj/machinery/atmospherics/portable/canister/atmos_init() . = ..() @@ -506,7 +562,11 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new()) new /obj/item/stack/sheet/metal(drop_location(), 3) qdel(src) +#undef HOLDING_TANK +#undef CONNECTED_PORT #undef LOW_PRESSURE #undef NORMAL_PRESSURE #undef HIGH_PRESSURE #undef EXTREME_PRESSURE +#undef NEW_COLOR +#undef RESET diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm index 9843b487fad99..df3fa7c53ced6 100644 --- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm +++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm @@ -41,6 +41,8 @@ air_contents.react() return + update_icon() + /obj/machinery/atmospherics/portable/Destroy() SSair.atmos_machinery -= src disconnect() @@ -68,8 +70,6 @@ anchored = TRUE //Prevent movement - update_icon() - return TRUE /obj/machinery/atmospherics/portable/disconnect() @@ -81,8 +81,6 @@ connected_port.connected_device = null connected_port = null - update_icon() - return TRUE /obj/machinery/atmospherics/portable/portableConnectorReturnAir() @@ -120,8 +118,13 @@ update_icon() return TRUE +<<<<<<< HEAD /obj/machinery/atmospherics/portable/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(istype(used, /obj/item/tank)) +======= +/obj/machinery/atmospherics/portable/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/tank)) +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb if(!(stat & BROKEN)) if(!user.drop_item()) return ITEM_INTERACT_COMPLETE @@ -157,8 +160,13 @@ else to_chat(user, "Nothing happens.") +<<<<<<< HEAD /obj/machinery/atmospherics/portable/attacked_by(obj/item/attacker, mob/living/user) if(attacker.force < 10 && !(stat & BROKEN)) +======= +/obj/machinery/atmospherics/portable/attacked_by(obj/item/I, mob/user) + if(I.force < 10 && !(stat & BROKEN)) +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb take_damage(0) else add_fingerprint(user) diff --git a/code/modules/awaymissions/loot.dm b/code/modules/awaymissions/loot.dm new file mode 100644 index 0000000000000..7f77d78c7f26e --- /dev/null +++ b/code/modules/awaymissions/loot.dm @@ -0,0 +1,26 @@ +/obj/effect/spawner/away/lootdrop + icon = 'icons/mob/screen_gen.dmi' + icon_state = "x2" + var/lootcount = 1 //how many items will be spawned + var/lootdoubles = 0 //if the same item can be spawned twice + var/loot = "" //a list of possible items to spawn- a string of paths + +/obj/effect/spawner/away/lootdrop/Initialize(mapload) + ..() + var/list/things = params2list(loot) + + if(things && length(things)) + for(var/i = lootcount, i > 0, i--) + if(!length(things)) + return + + var/loot_spawn = pick(things) + var/loot_path = text2path(loot_spawn) + + if(!loot_path || !lootdoubles) + things.Remove(loot_spawn) + continue + + new loot_path(get_turf(src)) + + return INITIALIZE_HINT_QDEL diff --git a/code/modules/awaymissions/mission_code/beach.dm b/code/modules/awaymissions/mission_code/beach.dm index 88f16b4ea6f64..150a6cd304d8a 100644 --- a/code/modules/awaymissions/mission_code/beach.dm +++ b/code/modules/awaymissions/mission_code/beach.dm @@ -101,7 +101,7 @@ if(ismob(AM)) linkedcontroller.mobinpool += AM -/turf/simulated/floor/beach/away/water/Exited(atom/movable/AM, direction) +/turf/simulated/floor/beach/away/water/Exited(atom/movable/AM, atom/newloc) . = ..() if(!linkedcontroller) return diff --git a/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm b/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm index 7d69d469a3aae..f8d301fa93c8e 100644 --- a/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm +++ b/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm @@ -13,7 +13,7 @@ name = "incomplete servant golem shell" shell_type = /obj/effect/mob_spawn/human/alive/golem/servant -/obj/item/golem_shell/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/item/golem_shell/attackby(obj/item/I, mob/user, params) ..() var/static/list/golem_shell_species_types = list( /obj/item/stack/sheet/metal = /datum/species/golem, @@ -166,7 +166,7 @@ create(ckey = user.ckey, name = user.real_name) user.death() -/obj/effect/mob_spawn/human/alive/golem/attackby__legacy__attackchain(obj/item/I, mob/living/carbon/user, params) +/obj/effect/mob_spawn/human/alive/golem/attackby(obj/item/I, mob/living/carbon/user, params) if(!istype(I, /obj/item/slimepotion/transference)) return ..() if(iscarbon(user) && can_transfer) diff --git a/code/modules/awaymissions/mission_code/ruins/deepstorage.dm b/code/modules/awaymissions/mission_code/ruins/deepstorage.dm index b9f8ee35ad646..9816c60ea5525 100644 --- a/code/modules/awaymissions/mission_code/ruins/deepstorage.dm +++ b/code/modules/awaymissions/mission_code/ruins/deepstorage.dm @@ -109,8 +109,8 @@ playsound(src, 'sound/effects/meteorimpact.ogg', 25, TRUE, 2, TRUE) return ..() -/mob/living/simple_animal/hostile/megafauna/fleshling/Bump(atom/A) - if(charging) +/mob/living/simple_animal/hostile/megafauna/fleshling/Bump(atom/A, yes) + if(charging && yes) if(isliving(A)) var/mob/living/L = A L.visible_message("[src] slams into [L]!", "[src] tramples you into the ground!") diff --git a/code/modules/awaymissions/mission_code/ruins/gps_ruin.dm b/code/modules/awaymissions/mission_code/ruins/gps_ruin.dm index 51fa397574098..fa26eea5d0d69 100644 --- a/code/modules/awaymissions/mission_code/ruins/gps_ruin.dm +++ b/code/modules/awaymissions/mission_code/ruins/gps_ruin.dm @@ -10,4 +10,4 @@ gpstag = "Unknown Signal" /obj/item/gps/ruin/attack_hand(mob/user) - attack_self__legacy__attackchain(user) + attack_self(user) diff --git a/code/modules/awaymissions/mission_code/ruins/oldstation.dm b/code/modules/awaymissions/mission_code/ruins/oldstation.dm index 7e8bb571a7dd3..e679429ffefd0 100644 --- a/code/modules/awaymissions/mission_code/ruins/oldstation.dm +++ b/code/modules/awaymissions/mission_code/ruins/oldstation.dm @@ -393,7 +393,7 @@ /obj/structure/closet/crate/secure/oldstation/research/populate_contents() new /obj/item/circuitboard/circuit_imprinter(src) - new /obj/item/circuitboard/scientific_analyzer(src) + new /obj/item/circuitboard/destructive_analyzer(src) new /obj/item/circuitboard/protolathe(src) new /obj/item/circuitboard/rdconsole/public(src) new /obj/item/circuitboard/rnd_network_controller(src) @@ -424,7 +424,7 @@ new /obj/item/hemostat(src) new /obj/item/scalpel(src) new /obj/item/cautery(src) - new /obj/item/fix_o_vein(src) + new /obj/item/FixOVein(src) new /obj/item/surgicaldrill(src) new /obj/item/bonegel(src) new /obj/item/bonesetter(src) diff --git a/code/modules/awaymissions/mission_code/ruins/telecomns.dm b/code/modules/awaymissions/mission_code/ruins/telecomns.dm index fdfc8029466ff..3d627934b0969 100644 --- a/code/modules/awaymissions/mission_code/ruins/telecomns.dm +++ b/code/modules/awaymissions/mission_code/ruins/telecomns.dm @@ -48,15 +48,9 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) /obj/effect/abstract/bot_trap name = "evil bot trap to make explorers hate you" -/obj/effect/abstract/bot_trap/Initialize(mapload) +/obj/effect/abstract/bot_trap/Crossed(atom/movable/AM, oldloc) . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered) - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/effect/abstract/bot_trap/proc/on_atom_entered(datum/source, atom/movable/entered) - if(isrobot(entered) || ishuman(entered)) + if(isrobot(AM) || ishuman(AM)) var/turf/T = get_turf(src) for(var/mob/living/simple_animal/bot/B in GLOB.telecomms_bots) B.call_bot(null, T, FALSE) @@ -66,15 +60,9 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) /obj/effect/abstract/loot_trap name = "table surrounding loot trap" -/obj/effect/abstract/loot_trap/Initialize(mapload) +/obj/effect/abstract/loot_trap/Crossed(atom/movable/AM, oldloc) . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered) - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/effect/abstract/loot_trap/proc/on_atom_entered(datum/source, atom/movable/entered) - if(isrobot(entered) || ishuman(entered)) + if(isrobot(AM) || ishuman(AM)) var/turf/T = get_turf(src) for(var/obj/structure/telecomms_doomsday_device/DD in GLOB.telecomms_doomsday_device) DD.thief = TRUE @@ -87,15 +75,9 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) /obj/effect/abstract/cheese_trap name = "cheese preventer" -/obj/effect/abstract/cheese_trap/Initialize(mapload) +/obj/effect/abstract/cheese_trap/Crossed(atom/movable/AM, oldloc) . = ..() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered) - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/effect/abstract/cheese_trap/proc/on_atom_entered(datum/source, atom/movable/entered) - if(isrobot(entered) || ishuman(entered)) + if(isrobot(AM) || ishuman(AM)) for(var/obj/structure/telecomms_doomsday_device/DD in GLOB.telecomms_doomsday_device) if(DD.thief) DD.start_the_party(TRUE) @@ -111,7 +93,7 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) /obj/machinery/autolathe/trapped/Initialize(mapload) . = ..() - RegisterSignal(src, COMSIG_ATTACK_BY, PROC_REF(material_container_shenanigins)) + RegisterSignal(src, COMSIG_PARENT_ATTACKBY, PROC_REF(material_container_shenanigins)) /obj/machinery/autolathe/trapped/proc/material_container_shenanigins(datum/source, obj/item/attacker, mob/user) if(!disguise_broken) @@ -411,14 +393,14 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) QDEL_NULL(integrated_console) return ..() -/obj/item/remote_ai_upload/attack_self__legacy__attackchain(mob/user as mob) +/obj/item/remote_ai_upload/attack_self(mob/user as mob) integrated_console.attack_hand(user) -/obj/item/remote_ai_upload/attackby__legacy__attackchain(obj/item/O, mob/user, params) +/obj/item/remote_ai_upload/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/card/emag)) to_chat(user, "You are more likely to damage this with an emag, than achieve something useful.") return - var/time_to_die = integrated_console.attackby__legacy__attackchain(O, user, params) + var/time_to_die = integrated_console.attackby(O, user, params) if(time_to_die) to_chat(user, "[src]'s relay begins to overheat...") playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) @@ -428,14 +410,14 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) explosion(loc, -1, -1, 2, 4, flame_range = 4) qdel(src) -/obj/effect/spawner/random/telecomms_core_table +/obj/effect/spawner/lootdrop/telecomms_core_table name = "telecomms core table spawner" - spawn_loot_count = 1 + lootcount = 1 loot = list( - /obj/item/rcd/combat, - /obj/item/gun/medbeam, - /obj/item/gun/energy/wormhole_projector, - /obj/item/storage/box/syndie_kit/oops_all_extraction_flares + /obj/item/rcd/combat, + /obj/item/gun/medbeam, + /obj/item/gun/energy/wormhole_projector, + /obj/item/storage/box/syndie_kit/oops_all_extraction_flares ) /obj/item/storage/box/syndie_kit/oops_all_extraction_flares @@ -489,11 +471,10 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) var/soundblock = null /// How long do we sleep between messages? 5 seconds by default. var/loop_sleep_time = 5 SECONDS - var/datum/proximity_monitor/proximity_monitor /obj/structure/environmental_storytelling_holopad/Initialize(mapload) . = ..() - proximity_monitor = new(src, 1) + AddComponent(/datum/component/proximity_monitor) /obj/structure/environmental_storytelling_holopad/Destroy() QDEL_NULL(our_holo) @@ -507,7 +488,8 @@ GLOBAL_LIST_EMPTY(telecomms_trap_tank) /obj/structure/environmental_storytelling_holopad/proc/start_message(mob/living/carbon/human/H) activated = TRUE - QDEL_NULL(proximity_monitor) + DeleteComponent(/datum/component/proximity_monitor) + icon_state = "holopad1" update_icon(UPDATE_OVERLAYS) var/obj/effect/overlay/hologram = new(get_turf(src)) diff --git a/code/modules/awaymissions/mission_code/ruins/watcher_grave.dm b/code/modules/awaymissions/mission_code/ruins/watcher_grave.dm index 398eda18c0952..715f78f424914 100644 --- a/code/modules/awaymissions/mission_code/ruins/watcher_grave.dm +++ b/code/modules/awaymissions/mission_code/ruins/watcher_grave.dm @@ -100,7 +100,7 @@ /// Who are we orbiting? var/mob/living/owner -/obj/item/watcher_hatchling/attack_self__legacy__attackchain(mob/user, modifiers) +/obj/item/watcher_hatchling/attack_self(mob/user, modifiers) . = ..() if(!isnull(orbiter)) watcher_return() diff --git a/code/modules/awaymissions/mission_code/ruins/wizardcrash.dm b/code/modules/awaymissions/mission_code/ruins/wizardcrash.dm index 35b3a0cfb791e..62b288870a7da 100644 --- a/code/modules/awaymissions/mission_code/ruins/wizardcrash.dm +++ b/code/modules/awaymissions/mission_code/ruins/wizardcrash.dm @@ -13,20 +13,18 @@ /obj/item/spellbook/oneuse/emp/used used = TRUE //spawns used -/obj/effect/spawner/random/wizardcrash +/obj/effect/spawner/lootdrop/wizardcrash loot = list( - /obj/item/spellbook/oneuse/summonitem = 20, - /obj/item/spellbook/oneuse/charge = 15, // and now for less useful stuff to dilute the good loot chances - /obj/item/book/granter/spell/summon_cheese = 10, // hungry wizard stuff - /obj/item/reagent_containers/drinks/everfull = 10, // Cheese and wine - /obj/item/spellbook/oneuse/forcewall = 10, - /obj/item/tarot_card_pack = 10, - - /obj/item/tarot_card_pack/jumbo = 6, - /obj/item/tarot_card_pack/mega = 4, - - /obj/item/guardiancreator = 1, // jackpot. - /obj/item/spellbook/oneuse/knock = 1, // tresspassing charges incoming - /obj/item/gun/magic/wand/resurrection = 1, // medbay's best friend - /obj/item/tarot_generator = 1, // A little bit of everything, all of the time. - ) + /obj/item/guardiancreator = 1, // jackpot. + /obj/item/spellbook/oneuse/knock = 1, // tresspassing charges incoming + /obj/item/gun/magic/wand/resurrection = 1, // medbay's best friend + /obj/item/tarot_generator = 1, // A little bit of everything, all of the time. + /obj/item/spellbook/oneuse/charge = 15, // and now for less useful stuff to dilute the good loot chances + /obj/item/spellbook/oneuse/summonitem = 20, + /obj/item/spellbook/oneuse/forcewall = 10, + /obj/item/tarot_card_pack = 10, + /obj/item/tarot_card_pack/jumbo = 6, + /obj/item/tarot_card_pack/mega = 4, + /obj/item/book/granter/spell/summon_cheese = 10, // hungry wizard stuff + /obj/item/reagent_containers/drinks/everfull = 10 // Cheese and wine + ) diff --git a/code/modules/awaymissions/mission_code/shuttle_shadow.dm b/code/modules/awaymissions/mission_code/shuttle_shadow.dm index 137ac4b611dba..e1ed6df4c1f7c 100644 --- a/code/modules/awaymissions/mission_code/shuttle_shadow.dm +++ b/code/modules/awaymissions/mission_code/shuttle_shadow.dm @@ -6,9 +6,9 @@ return ..() -/obj/machinery/atmospherics/unary/passive_vent/high_volume/shadow/on_changed_z_level(turf/old_turf, turf/new_turf) +/obj/machinery/atmospherics/unary/passive_vent/high_volume/shadow/onTransitZ(old_z, new_z) . = ..() - if(is_station_level(new_turf?.z)) + if(is_station_level(new_z)) on = TRUE /obj/machinery/atmospherics/trinary/filter/shadow @@ -18,15 +18,15 @@ on = FALSE target_pressure = 99999 -/obj/machinery/atmospherics/trinary/filter/shadow/on_changed_z_level(turf/old_turf, turf/new_turf) +/obj/machinery/atmospherics/trinary/filter/shadow/onTransitZ(old_z, new_z) . = ..() - if(is_station_level(new_turf?.z)) + if(is_station_level(new_z)) on = TRUE /obj/machinery/igniter/shadow -/obj/machinery/igniter/shadow/on_changed_z_level(turf/old_turf, turf/new_turf) +/obj/machinery/igniter/shadow/onTransitZ(old_z, new_z) . = ..() - if(is_station_level(new_turf?.z)) + if(is_station_level(new_z)) on = TRUE update_icon() diff --git a/code/modules/awaymissions/zlevel_helpers.dm b/code/modules/awaymissions/zlevel_helpers.dm index 749abdf47a570..d624671002b21 100644 --- a/code/modules/awaymissions/zlevel_helpers.dm +++ b/code/modules/awaymissions/zlevel_helpers.dm @@ -1,18 +1,18 @@ -/datum/milla_safe_must_sleep/late_setup_level +/datum/milla_safe/late_setup_level // Ensures that atmos and environment are set up. -/datum/milla_safe_must_sleep/late_setup_level/on_run(turf/bot_left, turf/top_right, smoothTurfs) +/datum/milla_safe/late_setup_level/on_run(turfs, smoothTurfs) var/total_timer = start_watch() var/subtimer = start_watch() if(!smoothTurfs) - smoothTurfs = block(bot_left, top_right) + smoothTurfs = turfs log_debug("Setting up atmos") /* setup_allturfs is superfluous during server initialization because * air subsystem will call subsequently call setup_allturfs with _every_ * turf in the world */ if(SSair && SSair.initialized) - SSair.setup_turfs(bot_left, top_right) + SSair.setup_allturfs_sleepless(turfs) log_debug("\tTook [stop_watch(subtimer)]s") subtimer = start_watch() @@ -39,3 +39,50 @@ for(var/otherthing in T) qdel(otherthing) T.ChangeTurf(T.baseturf) + +/datum/map_template/ruin/proc/try_to_place(z,allowed_areas) + var/sanity = PLACEMENT_TRIES + while(sanity > 0) + sanity-- + var/width_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(width / 2) + var/height_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(height / 2) + var/turf/central_turf = locate(rand(width_border, world.maxx - width_border), rand(height_border, world.maxy - height_border), z) + var/valid = TRUE + + for(var/turf/check in get_affected_turfs(central_turf,1)) + var/area/new_area = get_area(check) + if(!(istype(new_area, allowed_areas)) || check.flags & NO_RUINS) + valid = FALSE + break + + if(!valid) + continue + + log_world("Ruin \"[name]\" placed at ([central_turf.x], [central_turf.y], [central_turf.z])") + + for(var/i in get_affected_turfs(central_turf, 1)) + var/turf/T = i + for(var/obj/structure/spawner/nest in T) + qdel(nest) + for(var/mob/living/simple_animal/monster in T) + qdel(monster) + for(var/obj/structure/flora/ash/plant in T) + qdel(plant) + + load(central_turf,centered = TRUE) + loaded++ + + for(var/turf/T in get_affected_turfs(central_turf, 1)) + T.flags |= NO_RUINS + + new /obj/effect/landmark/ruin(central_turf, src) + + var/map_filename = splittext(mappath, "/") + map_filename = map_filename[length(map_filename)] + SSblackbox.record_feedback("associative", "ruin_placement", 1, list( + "map" = map_filename, + "coords" = "[central_turf.x],[central_turf.y],[central_turf.z]" + )) + + return TRUE + return FALSE diff --git a/code/modules/buildmode/submodes/mapgen.dm b/code/modules/buildmode/submodes/mapgen.dm index e72f813da5f50..df6f6b73ed03a 100644 --- a/code/modules/buildmode/submodes/mapgen.dm +++ b/code/modules/buildmode/submodes/mapgen.dm @@ -11,7 +11,7 @@ to_chat(user, "***********************************************************") /datum/buildmode_mode/mapgen/change_settings(mob/user) - var/list/gen_paths = subtypesof(/datum/map_generator) + var/list/gen_paths = subtypesof(/datum/mapGenerator) var/type = input(user,"Select Generator Type","Type") as null|anything in gen_paths if(!type) return @@ -32,7 +32,7 @@ if(left_click) //rectangular if(cornerA && cornerB) - var/datum/map_generator/G = new generator_path + var/datum/mapGenerator/G = new generator_path G.defineRegion(cornerA, cornerB, 1) highlight_region(G.map) var/confirm = alert("Are you sure you want run the map generator?", "Run generator", "Yes", "No") diff --git a/code/modules/buildmode/submodes/say.dm b/code/modules/buildmode/submodes/say.dm deleted file mode 100644 index 62c4456ebc6b6..0000000000000 --- a/code/modules/buildmode/submodes/say.dm +++ /dev/null @@ -1,36 +0,0 @@ -/datum/buildmode_mode/say - key = "say" - -/datum/buildmode_mode/say/show_help(mob/user) - to_chat(user, "***********************************************************") - to_chat(user, "Left Mouse Button = Say") - to_chat(user, "Right Mouse Button = Emote") - to_chat(user, "***********************************************************") - -/datum/buildmode_mode/say/handle_click(mob/user, params, atom/object) - if(ismob(object)) - var/mob/target = object - if(!isnull(target.ckey)) - alert("This cannot be used on mobs with a ckey. Use Forcesay in player panel instead.") - return - - var/list/pa = params2list(params) - var/left_click = pa.Find("left") - var/right_click = pa.Find("right") - - if(left_click) - var/say = tgui_input_text(user, "What should [object] say?", "Say what?") - if(isnull(say)) - return - log_admin("Build Mode: [key_name(user)] made [object] at ([object.x],[object.y],[object.z] say [say].") - message_admins("Build Mode: [key_name(user)] made [object] at ([object.x],[object.y],[object.z] say [say].") - user.create_log(MISC_LOG, "Made [object] at ([object.x],[object.y],[object.z] say [say].") - object.atom_say(say) - else if(right_click) - var/emote = tgui_input_text(user, "What should [object] do?", "Emote what?") - if(isnull(emote)) - return - log_admin("Build Mode: [key_name(user)] made [object] at ([object.x],[object.y],[object.z] emote *[emote].") - message_admins("Build Mode: [key_name(user)] made [object] at ([object.x],[object.y],[object.z] emote *[emote].") - user.create_log(MISC_LOG, "Made [object] at ([object.x],[object.y],[object.z] emote *[emote].") - object.atom_emote(emote) diff --git a/code/modules/client/login_processing/20-load_characters.dm b/code/modules/client/login_processing/20-load_characters.dm index 641f4c6826077..7467e76f8e059 100644 --- a/code/modules/client/login_processing/20-load_characters.dm +++ b/code/modules/client/login_processing/20-load_characters.dm @@ -63,8 +63,7 @@ physique, height, cyborg_brain_type, - body_type, - pda_ringtone + body_type FROM characters WHERE ckey=:ckey"}, list( "ckey" = C.ckey )) diff --git a/code/modules/client/preference/character.dm b/code/modules/client/preference/character.dm index 30b169bf5712e..da5520d2f6f40 100644 --- a/code/modules/client/preference/character.dm +++ b/code/modules/client/preference/character.dm @@ -108,8 +108,6 @@ var/list/custom_emotes = list() /// Runechat color var/runechat_color = "#FFFFFF" - /// The ringtone their PDA should start with - var/pda_ringtone // Fuckery to prevent null characters /datum/character_save/New() @@ -201,8 +199,7 @@ custom_emotes=:custom_emotes, runechat_color=:runechat_color, cyborg_brain_type=:cyborg_brain_type, - body_type=:body_type, - pda_ringtone=:pda_ringtone + body_type=:body_type WHERE ckey=:ckey AND slot=:slot"}, list( // OH GOD SO MANY PARAMETERS @@ -265,7 +262,6 @@ "custom_emotes" = json_encode(custom_emotes), "runechat_color" = runechat_color, "cyborg_brain_type" = cyborg_brain_type, - "pda_ringtone" = pda_ringtone, "ckey" = C.ckey, "slot" = slot_number )) @@ -306,7 +302,7 @@ player_alt_titles, disabilities, organ_data, rlimb_data, nanotrasen_relation, physique, height, speciesprefs, socks, body_accessory, gear, autohiss, - hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, custom_emotes, runechat_color, cyborg_brain_type, body_type, pda_ringtone) + hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, custom_emotes, runechat_color, cyborg_brain_type, body_type) VALUES (:ckey, :slot, :metadata, :name, :be_random_name, :gender, :age, :species, :language, @@ -333,7 +329,7 @@ :playertitlelist, :disabilities, :organ_list, :rlimb_list, :nanotrasen_relation, :physique, :height, :speciesprefs, :socks, :body_accessory, :gearlist, :autohiss_mode, - :h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha, :custom_emotes, :runechat_color, :cyborg_brain_type, :body_type, :pda_ringtone) + :h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha, :custom_emotes, :runechat_color, :cyborg_brain_type, :body_type) "}, list( // This has too many params for anyone to look at this without going insae "ckey" = C.ckey, @@ -396,8 +392,7 @@ "h_grad_alpha" = h_grad_alpha, "custom_emotes" = json_encode(custom_emotes), "runechat_color" = runechat_color, - "cyborg_brain_type" = cyborg_brain_type, - "pda_ringtone" = pda_ringtone + "cyborg_brain_type" = cyborg_brain_type )) if(!query.warn_execute()) @@ -492,7 +487,6 @@ height = query.item[58] cyborg_brain_type = query.item[59] body_type = query.item[60] - pda_ringtone = query.item[61] //Sanitize var/datum/species/SP = GLOB.all_species[species] @@ -580,7 +574,6 @@ custom_emotes = init_custom_emotes(custom_emotes_tmp) runechat_color = sanitize_hexcolor(runechat_color) cyborg_brain_type = sanitize_inlist(cyborg_brain_type, GLOB.borg_brain_choices, initial(cyborg_brain_type)) - pda_ringtone = sanitize_inlist(pda_ringtone, GLOB.pda_ringtone_choices, initial(pda_ringtone)) if(!player_alt_titles) player_alt_titles = new() if(!organ_data) @@ -831,7 +824,7 @@ var/coloured_tail if(current_species) if(current_species.bodyflags & HAS_ICON_SKIN_TONE) //Handling species-specific icon-based skin tones by flagged race. - var/mob/living/carbon/human/fake/H = new + var/mob/living/carbon/human/H = new H.dna.species = current_species H.s_tone = s_tone H.dna.species.updatespeciescolor(H, 0) //The mob's species wasn't set, so it's almost certainly different than the character's species at the moment. Thus, we need to be owner-insensitive. @@ -1535,17 +1528,6 @@ clothes_s.Blend(new /icon('icons/mob/clothing/back.dmi', "satchel-norm"), ICON_OVERLAY) if(4) clothes_s.Blend(new /icon('icons/mob/clothing/back.dmi', "satchel"), ICON_OVERLAY) - if(JOB_INSTRUCTOR) - clothes_s = new /icon('icons/mob/clothing/under/procedure.dmi', "trainer_s") - clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "laceups"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "trainercoat"), ICON_OVERLAY) - switch(backbag) - if(2) - clothes_s.Blend(new /icon('icons/mob/clothing/back.dmi', "securitypack"), ICON_OVERLAY) - if(3) - clothes_s.Blend(new /icon('icons/mob/clothing/back.dmi', "satchel-norm"), ICON_OVERLAY) - if(4) - clothes_s.Blend(new /icon('icons/mob/clothing/back.dmi', "satchel"), ICON_OVERLAY) if(disabilities & DISABILITY_FLAG_NEARSIGHTED) preview_icon.Blend(new /icon('icons/mob/clothing/eyes.dmi', "glasses"), ICON_OVERLAY) @@ -2047,10 +2029,6 @@ if(job.hidden_from_job_prefs) continue - if(job.mentor_only) - if(!check_rights(R_MENTOR | R_ADMIN, FALSE, user)) - continue - index += 1 if((index >= limit) || (job.title in splitJobs)) if((index < limit) && (lastJob != null)) @@ -2073,7 +2051,6 @@ if(jobban_isbanned(user, job.title)) html += "[rank] \[BANNED]" continue - var/restrictions = job.get_exp_restrictions(user.client) if(restrictions) html += "[rank] \[[restrictions]]" diff --git a/code/modules/client/preference/link_processing.dm b/code/modules/client/preference/link_processing.dm index d34f8ac206c10..45f8843879356 100644 --- a/code/modules/client/preference/link_processing.dm +++ b/code/modules/client/preference/link_processing.dm @@ -853,13 +853,6 @@ if(!(brain_type in GLOB.borg_brain_choices)) return active_character.cyborg_brain_type = brain_type - if("pda_ringtone") - var/ringtone = tgui_input_list(user, "What type of ringtone would you like to have on your PDA?", "PDA Ringtones", list("Reset Default Ringtone") + GLOB.pda_ringtone_choices, active_character.pda_ringtone) - if(!(ringtone in GLOB.pda_ringtone_choices)) - if(ringtone == "Reset Default Ringtone") - active_character.pda_ringtone = null - return - active_character.pda_ringtone = ringtone if("clientfps") var/version_message if(user.client && user.client.byond_version < 511) @@ -1007,7 +1000,6 @@ var/list/actualview = getviewsize(parent.view) parent.void.UpdateGreed(actualview[1],actualview[2]) - parent.fit_viewport() parent.debug_text_overlay?.update_view(parent) if("afk_watch") diff --git a/code/modules/client/preference/loadout/loadout_accessories.dm b/code/modules/client/preference/loadout/loadout_accessories.dm index f63e945c3afdd..a4a8f50368c0e 100644 --- a/code/modules/client/preference/loadout/loadout_accessories.dm +++ b/code/modules/client/preference/loadout/loadout_accessories.dm @@ -16,6 +16,66 @@ slot = ITEM_SLOT_ACCESSORY sort_category = "Accessories" +/datum/gear/accessory/scarf + display_name = "Scarf" + path = /obj/item/clothing/accessory/scarf + +/datum/gear/accessory/scarf/red + display_name = "Scarf, red" + path = /obj/item/clothing/accessory/scarf/red + +/datum/gear/accessory/scarf/green + display_name = "Scarf, green" + path = /obj/item/clothing/accessory/scarf/green + +/datum/gear/accessory/scarf/darkblue + display_name = "Scarf, dark blue" + path = /obj/item/clothing/accessory/scarf/darkblue + +/datum/gear/accessory/scarf/purple + display_name = "Scarf, purple" + path = /obj/item/clothing/accessory/scarf/purple + +/datum/gear/accessory/scarf/yellow + display_name = "Scarf, yellow" + path = /obj/item/clothing/accessory/scarf/yellow + +/datum/gear/accessory/scarf/orange + display_name = "Scarf, orange" + path = /obj/item/clothing/accessory/scarf/orange + +/datum/gear/accessory/scarf/lightblue + display_name = "Scarf, light blue" + path = /obj/item/clothing/accessory/scarf/lightblue + +/datum/gear/accessory/scarf/white + display_name = "Scarf, white" + path = /obj/item/clothing/accessory/scarf/white + +/datum/gear/accessory/scarf/black + display_name = "Scarf, black" + path = /obj/item/clothing/accessory/scarf/black + +/datum/gear/accessory/scarf/zebra + display_name = "Scarf, zebra" + path = /obj/item/clothing/accessory/scarf/zebra + +/datum/gear/accessory/scarf/christmas + display_name = "Scarf, christmas" + path = /obj/item/clothing/accessory/scarf/christmas + +/datum/gear/accessory/scarf/stripedred + display_name = "Scarf, striped red" + path = /obj/item/clothing/accessory/stripedredscarf + +/datum/gear/accessory/scarf/stripedgreen + display_name = "Scarf, striped green" + path = /obj/item/clothing/accessory/stripedgreenscarf + +/datum/gear/accessory/scarf/stripedblue + display_name = "Scarf, striped blue" + path = /obj/item/clothing/accessory/stripedbluescarf + /datum/gear/accessory/holobadge display_name = "Holobadge, pin" path = /obj/item/clothing/accessory/holobadge @@ -26,6 +86,27 @@ path = /obj/item/clothing/accessory/holobadge/cord allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer") +/datum/gear/accessory/tieblue + display_name = "Tie, blue" + path = /obj/item/clothing/accessory/blue + +/datum/gear/accessory/tiered + display_name = "Tie, red" + path = /obj/item/clothing/accessory/red + +/datum/gear/accessory/tieblack + display_name = "Tie, black" + path = /obj/item/clothing/accessory/black + +/datum/gear/accessory/tiehorrible + display_name = "Tie, vomit green" + path = /obj/item/clothing/accessory/horrible + +/datum/gear/accessory/stethoscope + display_name = "Stethoscope" + path = /obj/item/clothing/accessory/stethoscope + allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Paramedic") + /datum/gear/accessory/cowboyshirt display_name = "Cowboy shirt, black" path = /obj/item/clothing/accessory/cowboyshirt @@ -66,6 +147,22 @@ display_name = "Cowboy shirt, short sleeved navy" path = /obj/item/clothing/accessory/cowboyshirt/navy/short_sleeved +/datum/gear/accessory/locket/silver + display_name = "Silver locket" + path = /obj/item/clothing/accessory/necklace/locket/silver + +/datum/gear/accessory/locket + display_name = "Gold locket" + path = /obj/item/clothing/accessory/necklace/locket + +/datum/gear/accessory/necklace/long + display_name = "Large necklace" + path = /obj/item/clothing/accessory/necklace/long + +/datum/gear/accessory/necklace + display_name = "Simple necklace" + path = /obj/item/clothing/accessory/necklace + /datum/gear/accessory/corset display_name = "Corset, black" path = /obj/item/clothing/accessory/corset @@ -136,7 +233,7 @@ /datum/gear/accessory/armband_job/procedure display_name = "Armband, procedure" path = /obj/item/clothing/accessory/armband/procedure - allowed_roles = list("Captain", "Nanotrasen Representative", "Magistrate", "Internal Affairs Agent", "Nanotrasen Career Trainer") + allowed_roles = list("Captain", "Nanotrasen Representative", "Magistrate", "Internal Affairs Agent") /datum/gear/accessory/armband_job/service display_name = "Armband, service" diff --git a/code/modules/client/preference/loadout/loadout_donor.dm b/code/modules/client/preference/loadout/loadout_donor.dm index b2d6184a16741..aad1a4f22b6a4 100644 --- a/code/modules/client/preference/loadout/loadout_donor.dm +++ b/code/modules/client/preference/loadout/loadout_donor.dm @@ -30,7 +30,7 @@ /datum/gear/donor/furcape display_name = "Fur Cape" - path = /obj/item/clothing/neck/cloak/furcape + path = /obj/item/clothing/suit/furcape /datum/gear/donor/furcoat display_name = "Fur Coat" @@ -76,20 +76,6 @@ display_name = "Fur Cap" path = /obj/item/clothing/head/furcap -/datum/gear/donor/welding_blueflame - display_name = "Blue flame decal welding helmet" - path = /obj/item/clothing/head/welding/flamedecal/blue - allowed_roles = list("Chief Engineer", "Station Engineer", "Life Support Specialist", "Roboticist") - donator_tier = 2 - cost = 2 - -/datum/gear/donor/welding_white - display_name = "White decal welding helmet" - path = /obj/item/clothing/head/welding/white - allowed_roles = list("Chief Engineer", "Station Engineer", "Life Support Specialist", "Roboticist") - donator_tier = 2 - cost = 2 - /datum/gear/donor/fawkes display_name = "Guy Fawkes mask" path = /obj/item/clothing/mask/fawkes diff --git a/code/modules/client/preference/loadout/loadout_general.dm b/code/modules/client/preference/loadout/loadout_general.dm index 004b8eca3cf2c..e243d13187422 100644 --- a/code/modules/client/preference/loadout/loadout_general.dm +++ b/code/modules/client/preference/loadout/loadout_general.dm @@ -89,34 +89,6 @@ display_name = "Nian plushie" path = /obj/item/toy/plushie/nianplushie -/datum/gear/ipcplushie - display_name = "IPC plushie" - path = /obj/item/toy/plushie/ipcplushie - -/datum/gear/kidanplushie - display_name = "Kidan plushie" - path = /obj/item/toy/plushie/kidanplushie - -/datum/gear/plasmaplushie - display_name = "Plasmaman plushie" - path = /obj/item/toy/plushie/plasmamanplushie - -/datum/gear/skrellplushie - display_name = "Skrell plushie" - path = /obj/item/toy/plushie/skrellplushie - -/datum/gear/draskplushie - display_name = "Drask plushie" - path = /obj/item/toy/plushie/draskplushie - -/datum/gear/borgplushie - display_name = "Borg plushie" - path = /obj/item/toy/plushie/borgplushie - -/datum/gear/nymphplushie - display_name = "Diona nymph plushie" - path = /obj/item/toy/plushie/nymphplushie - /datum/gear/sharkplushie display_name = "Shark plushie" path = /obj/item/toy/plushie/shark @@ -185,7 +157,7 @@ display_name = "Bandana, skull" path = /obj/item/clothing/mask/bandana/skull -/datum/gear/pai +/datum/gear/pAI display_name = "Personal Artificial Intelligence" path = /obj/item/paicard cost = 2 diff --git a/code/modules/client/preference/loadout/loadout_neck.dm b/code/modules/client/preference/loadout/loadout_neck.dm deleted file mode 100644 index c8879c7201fde..0000000000000 --- a/code/modules/client/preference/loadout/loadout_neck.dm +++ /dev/null @@ -1,206 +0,0 @@ -/* -###################################################################################### -## ## -## IMPORTANT README ## -## ## -## Changing any /datum/gear typepaths --WILL-- break people's loadouts. ## -## The typepaths are stored directly in the `characters.gear` column of the DB. ## -## Please inform the server host if you wish to modify any of these. ## -## ## -###################################################################################### -*/ - - -/datum/gear/neck - main_typepath = /datum/gear/neck - slot = ITEM_SLOT_NECK - sort_category = "Neck" - -/datum/gear/neck/tie - display_name = "Tie, blue" - path = /obj/item/clothing/neck/tie/blue - -/datum/gear/neck/tie/red - display_name = "Tie, red" - path = /obj/item/clothing/neck/tie/red - -/datum/gear/neck/tie/black - display_name = "Tie, black" - path = /obj/item/clothing/neck/tie/black - -/datum/gear/neck/tie/horrible - display_name = "Tie, vomit green" - path = /obj/item/clothing/neck/tie/horrible - -/datum/gear/neck/scarf - display_name = "Scarf, red" - path = /obj/item/clothing/neck/scarf/red - -/datum/gear/neck/scarf/green - display_name = "Scarf, green" - path = /obj/item/clothing/neck/scarf/green - -/datum/gear/neck/scarf/darkblue - display_name = "Scarf, dark blue" - path = /obj/item/clothing/neck/scarf/darkblue - -/datum/gear/neck/scarf/purple - display_name = "Scarf, purple" - path = /obj/item/clothing/neck/scarf/purple - -/datum/gear/neck/scarf/yellow - display_name = "Scarf, yellow" - path = /obj/item/clothing/neck/scarf/yellow - -/datum/gear/neck/scarf/orange - display_name = "Scarf, orange" - path = /obj/item/clothing/neck/scarf/orange - -/datum/gear/neck/scarf/lightblue - display_name = "Scarf, light blue" - path = /obj/item/clothing/neck/scarf/lightblue - -/datum/gear/neck/scarf/white - display_name = "Scarf, white" - path = /obj/item/clothing/neck/scarf/white - -/datum/gear/neck/scarf/black - display_name = "Scarf, black" - path = /obj/item/clothing/neck/scarf/black - -/datum/gear/neck/scarf/zebra - display_name = "Scarf, zebra" - path = /obj/item/clothing/neck/scarf/zebra - -/datum/gear/neck/scarf/christmas - display_name = "Scarf, christmas" - path = /obj/item/clothing/neck/scarf/christmas - -/datum/gear/neck/scarf/stripedred - display_name = "Scarf, striped red" - path = /obj/item/clothing/neck/scarf/stripedred - -/datum/gear/neck/scarf/stripedgreen - display_name = "Scarf, striped green" - path = /obj/item/clothing/neck/scarf/stripedgreen - -/datum/gear/neck/scarf/stripedblue - display_name = "Scarf, striped blue" - path = /obj/item/clothing/neck/scarf/stripedblue - -/datum/gear/neck/stethoscope - display_name = "Stethoscope" - path = /obj/item/clothing/neck/stethoscope - allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Paramedic") - -/datum/gear/neck/locket - display_name = "Gold locket" - path = /obj/item/clothing/neck/necklace/locket - -/datum/gear/neck/locket/silver - display_name = "Silver locket" - path = /obj/item/clothing/neck/necklace/locket/silver - -/datum/gear/neck/necklace - display_name = "Simple necklace" - path = /obj/item/clothing/neck/necklace - -/datum/gear/neck/necklace/long - display_name = "Large necklace" - path = /obj/item/clothing/neck/necklace/long - -//Cloaks and mantles - -/datum/gear/neck/cloak - display_name = "Cloak" - path = /obj/item/clothing/neck/cloak - -/datum/gear/neck/cloak/job - main_typepath = /datum/gear/neck/cloak/job - subtype_selection_cost = FALSE - -/datum/gear/neck/cloak/job/captain - display_name = "Cloak, captain" - path = /obj/item/clothing/neck/cloak/captain - allowed_roles = list("Captain") - -/datum/gear/neck/cloak/job/hos - display_name = "Cloak, head of security" - path = /obj/item/clothing/neck/cloak/head_of_security - allowed_roles = list("Head of Security") - -/datum/gear/neck/cloak/job/hop - display_name = "Cloak, head of personnel" - path = /obj/item/clothing/neck/cloak/head_of_personnel - allowed_roles = list("Head of Personnel") - -/datum/gear/neck/cloak/job/rd - display_name = "Cloak, research director" - path = /obj/item/clothing/neck/cloak/research_director - allowed_roles = list("Research Director") - -/datum/gear/neck/cloak/job/ce - display_name = "Cloak, chief engineer" - path = /obj/item/clothing/neck/cloak/chief_engineer - allowed_roles = list("Chief Engineer") - -/datum/gear/neck/cloak/job/cmo - display_name = "Cloak, chief medical officer" - path = /obj/item/clothing/neck/cloak/chief_medical_officer - allowed_roles = list("Chief Medical Officer") - -/datum/gear/neck/cloak/job/qm - display_name = "Cloak, quartermaster" - path = /obj/item/clothing/neck/cloak/quartermaster - allowed_roles = list("Quartermaster") - -/datum/gear/neck/old_scarf - display_name = "Old scarf" - path = /obj/item/clothing/neck/cloak/old - -/datum/gear/neck/regal_shawl - display_name = "Regal shawl" - path = /obj/item/clothing/neck/cloak/regal - -/datum/gear/neck/mantle - display_name = "Mantle" - path = /obj/item/clothing/neck/cloak/mantle - -/datum/gear/neck/mantle/job - main_typepath = /datum/gear/neck/mantle/job - subtype_selection_cost = FALSE - -/datum/gear/neck/mantle/job/captain - display_name = "Mantle, captain" - path = /obj/item/clothing/neck/cloak/captain_mantle - allowed_roles = list("Captain") - -/datum/gear/neck/mantle/job/hos - display_name = "Mantle, head of security" - path = /obj/item/clothing/neck/cloak/hos_mantle - allowed_roles = list("Head of Security") - -/datum/gear/neck/mantle/job/hop - display_name = "Mantle, head of personnel" - path = /obj/item/clothing/neck/cloak/hop_mantle - allowed_roles = list("Head of Personnel") - -/datum/gear/neck/mantle/job/rd - display_name = "Mantle, research director" - path = /obj/item/clothing/neck/cloak/rd_mantle - allowed_roles = list("Research Director") - -/datum/gear/neck/mantle/job/ce - display_name = "Mantle, chief engineer" - path = /obj/item/clothing/neck/cloak/ce_mantle - allowed_roles = list("Chief Engineer") - -/datum/gear/neck/mantle/job/cmo - display_name = "Mantle, chief medical officer" - path = /obj/item/clothing/neck/cloak/cmo_mantle - allowed_roles = list("Chief Medical Officer") - -/datum/gear/neck/mantle/job/qm - display_name = "Mantle, quartermaster" - path = /obj/item/clothing/neck/cloak/qm_mantle - allowed_roles = list("Quartermaster") diff --git a/code/modules/client/preference/loadout/loadout_suit.dm b/code/modules/client/preference/loadout/loadout_suit.dm index 3ad597f09bb96..4023a2a82e233 100644 --- a/code/modules/client/preference/loadout/loadout_suit.dm +++ b/code/modules/client/preference/loadout/loadout_suit.dm @@ -252,6 +252,53 @@ display_name = "Suit jacket, purple" path = /obj/item/clothing/suit/storage/iaa/purplejacket +//Mantles! +/datum/gear/suit/mantle + display_name = "Mantle" + path = /obj/item/clothing/suit/mantle + +/datum/gear/suit/old_scarf + display_name = "Old scarf" + path = /obj/item/clothing/suit/mantle/old + +/datum/gear/suit/regal_shawl + display_name = "Regal shawl" + path = /obj/item/clothing/suit/mantle/regal + +/datum/gear/suit/mantle/job + main_typepath = /datum/gear/suit/mantle/job + subtype_selection_cost = FALSE + +/datum/gear/suit/mantle/job/captain + display_name = "Mantle, captain" + path = /obj/item/clothing/suit/mantle/armor/captain + allowed_roles = list("Captain") + +/datum/gear/suit/mantle/job/ce + display_name = "Mantle, chief engineer" + path = /obj/item/clothing/suit/mantle/chief_engineer + allowed_roles = list("Chief Engineer") + +/datum/gear/suit/mantle/job/cmo + display_name = "Mantle, chief medical officer" + path = /obj/item/clothing/suit/mantle/labcoat/chief_medical_officer + allowed_roles = list("Chief Medical Officer") + +/datum/gear/suit/mantle/job/hos + display_name = "Mantle, head of security" + path = /obj/item/clothing/suit/mantle/armor + allowed_roles = list("Head of Security") + +/datum/gear/suit/mantle/job/hop + display_name = "Mantle, head of personnel" + path = /obj/item/clothing/suit/mantle/armor/hop + allowed_roles = list("Head of Personnel") + +/datum/gear/suit/mantle/job/rd + display_name = "Mantle, research director" + path = /obj/item/clothing/suit/mantle/labcoat + allowed_roles = list("Research Director") + //Robes! /datum/gear/suit/witch diff --git a/code/modules/client/preference/loadout/loadout_uniform.dm b/code/modules/client/preference/loadout/loadout_uniform.dm index 3821188bf446a..28ad483a49110 100644 --- a/code/modules/client/preference/loadout/loadout_uniform.dm +++ b/code/modules/client/preference/loadout/loadout_uniform.dm @@ -190,18 +190,6 @@ display_name = "Kilt" path = /obj/item/clothing/under/costume/kilt -/datum/gear/uniform/suit/executive - display_name = "Executive Suit" - path = /obj/item/clothing/under/suit/really_black - -/datum/gear/uniform/suit/navyblue - display_name = "Navy Suit" - path = /obj/item/clothing/under/suit/navy - -/datum/gear/uniform/suit/checkered - display_name = "Checkered Suit" - path = /obj/item/clothing/under/suit/checkered - /datum/gear/uniform/skirt main_typepath = /datum/gear/uniform/skirt @@ -357,28 +345,6 @@ path = /obj/item/clothing/under/rank/cargo/tech/delivery allowed_roles = list("Quartermaster", "Cargo Technician") -/datum/gear/uniform/overalls - main_typepath = /datum/gear/uniform/overalls - -/datum/gear/uniform/overalls/job - main_typepath = /datum/gear/uniform/overalls/job - subtype_selection_cost = FALSE - -/datum/gear/uniform/overalls/job/janitor - display_name = "Overalls, janitor" - path = /obj/item/clothing/under/rank/civilian/janitor/overalls - allowed_roles = list("Janitor") - -/datum/gear/uniform/overalls/job/cargo - display_name = "Overalls, cargo tech" - path = /obj/item/clothing/under/rank/cargo/tech/overalls - allowed_roles = list("Quartermaster", "Cargo Technician") - -/datum/gear/uniform/overalls/job/expedition - display_name = "Overalls, expedition" - path = /obj/item/clothing/under/rank/cargo/expedition/overalls - allowed_roles = list("Quartermaster", "Explorer") - /datum/gear/uniform/sec main_typepath = /datum/gear/uniform/sec diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 95b814b11775c..bdb715a8100bc 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -205,7 +205,7 @@ GLOBAL_LIST_INIT(special_role_times, list( dat += "
    " dat += "

    Identity

    " dat += "Age: [active_character.age]
    " - dat += "Body: (Randomize)
    " + dat += "Body: (®)
    " dat += "Species: [active_character.species]
    " dat += "Gender: [active_character.gender == MALE ? "Male" : (active_character.gender == FEMALE ? "Female" : "Genderless")]
    " dat += "Body Type: [active_character.body_type == MALE ? "Masculine" : "Feminine"]" @@ -238,7 +238,6 @@ GLOBAL_LIST_INIT(special_role_times, list( dat += "Physique: [active_character.physique]
    " dat += "Height: [active_character.height]
    " dat += "Cyborg Brain Type: [active_character.cyborg_brain_type]
    " - dat += "PDA Ringtone: [active_character.pda_ringtone]
    " dat += "Set Flavor Text
    " if(length(active_character.flavor_text) <= 40) if(!length(active_character.flavor_text)) @@ -628,7 +627,7 @@ GLOBAL_LIST_INIT(special_role_times, list( dat += "Reset Setup" dat += "" - var/datum/browser/popup = new(user, "preferences", "
    Character Setup
    ", 820, 810) + var/datum/browser/popup = new(user, "preferences", "
    Character Setup
    ", 820, 770) popup.set_content(dat.Join("")) popup.open(FALSE) diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index 84daa8eae4ba2..f721a0eb77856 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -40,7 +40,7 @@ var/list/outfit_types = O.get_chameleon_disguise_info() for(var/V in user.chameleon_item_actions) - var/datum/action/item_action/chameleon_change/action = V + var/datum/action/item_action/chameleon/change/action = V for(var/T in outfit_types) if(ispath(T, action.chameleon_type)) action.update_look(user, T) @@ -60,7 +60,7 @@ return TRUE -/datum/action/item_action/chameleon_change +/datum/action/item_action/chameleon/change name = "Chameleon Change" var/static/list/chameleon_blacklist = list() //This is a typecache var/static/list/chameleon_list = list() @@ -69,12 +69,12 @@ var/obj/item/holder var/emp_timer -/datum/action/item_action/chameleon_change/New(Target) +/datum/action/item_action/chameleon/change/New(Target) . = ..() holder = Target + - -/datum/action/item_action/chameleon_change/Grant(mob/M) +/datum/action/item_action/chameleon/change/Grant(mob/M) if(M && (owner != M)) if(!M.chameleon_item_actions) M.chameleon_item_actions = list(src) @@ -84,7 +84,7 @@ M.chameleon_item_actions |= src ..() -/datum/action/item_action/chameleon_change/Remove(mob/M) +/datum/action/item_action/chameleon/change/Remove(mob/M) if(M && (M == owner)) LAZYREMOVE(M.chameleon_item_actions, src) if(!LAZYLEN(M.chameleon_item_actions)) @@ -92,23 +92,23 @@ qdel(O) ..() -/datum/action/item_action/chameleon_change/UpdateButton(atom/movable/screen/movable/action_button/button, status_only, force) +/datum/action/item_action/chameleon/change/UpdateButton(atom/movable/screen/movable/action_button/button, status_only, force) . = ..() if(.) button.name = "Change [chameleon_name] Appearance" -/datum/action/item_action/chameleon_change/ui_host() +/datum/action/item_action/chameleon/change/ui_host() return holder -/datum/action/item_action/chameleon_change/ui_state(mob/user) +/datum/action/item_action/chameleon/change/ui_state(mob/user) return GLOB.physical_state -/datum/action/item_action/chameleon_change/ui_data(mob/user) +/datum/action/item_action/chameleon/change/ui_data(mob/user) var/list/data = list() data["selected_appearance"] = "[holder.name]_[holder.icon_state]" return data -/datum/action/item_action/chameleon_change/ui_static_data(mob/user, datum/tgui/ui = null) +/datum/action/item_action/chameleon/change/ui_static_data(mob/user, datum/tgui/ui = null) var/list/data = list() var/list/chameleon_skins = list() for(var/chameleon_type in chameleon_list[chameleon_name]) @@ -122,14 +122,14 @@ data["chameleon_skins"] = chameleon_skins return data -/datum/action/item_action/chameleon_change/ui_interact(mob/user, datum/tgui/ui = null) +/datum/action/item_action/chameleon/change/ui_interact(mob/user, datum/tgui/ui = null) ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "Chameleon", "Change [chameleon_name] Appearance") ui.open() ui.set_autoupdate(FALSE) -/datum/action/item_action/chameleon_change/ui_act(action, list/params) +/datum/action/item_action/chameleon/change/ui_act(action, list/params) if(..()) return @@ -137,7 +137,7 @@ if("change_appearance") update_look(usr, chameleon_list[chameleon_name][params["new_appearance"]]) -/datum/action/item_action/chameleon_change/proc/initialize_disguises() +/datum/action/item_action/chameleon/change/proc/initialize_disguises() UpdateButtons() chameleon_blacklist |= typecacheof(target.type) if(!isnull(chameleon_list[chameleon_name])) @@ -152,10 +152,10 @@ if(isnull(chameleon_list[chameleon_name][chameleon_item_name])) chameleon_list[chameleon_name][chameleon_item_name] = I -/datum/action/item_action/chameleon_change/proc/select_look(mob/user) +/datum/action/item_action/chameleon/change/proc/select_look(mob/user) ui_interact(user) -/datum/action/item_action/chameleon_change/proc/random_look(mob/user) +/datum/action/item_action/chameleon/change/proc/random_look(mob/user) var/picked_name = pick(chameleon_list[chameleon_name]) // If a user is provided, then this item is in use, and we // need to update our icons and stuff @@ -169,7 +169,7 @@ else update_item(chameleon_list[chameleon_name][picked_name]) -/datum/action/item_action/chameleon_change/proc/update_look(mob/user, obj/item/picked_item) +/datum/action/item_action/chameleon/change/proc/update_look(mob/user, obj/item/picked_item) if(isliving(user)) var/mob/living/C = user if(C.stat != CONSCIOUS) @@ -181,7 +181,7 @@ SStgui.update_uis(src) UpdateButtons() -/datum/action/item_action/chameleon_change/proc/update_item(obj/item/picked_item) +/datum/action/item_action/chameleon/change/proc/update_item(obj/item/picked_item) target.name = initial(picked_item.name) target.desc = initial(picked_item.desc) target.icon_state = initial(picked_item.icon_state) @@ -208,14 +208,14 @@ target.icon = initial(picked_item.icon) -/datum/action/item_action/chameleon_change/Trigger(left_click) +/datum/action/item_action/chameleon/change/Trigger(left_click) if(!IsAvailable()) return select_look(owner) return 1 -/datum/action/item_action/chameleon_change/proc/emp_randomise(amount = EMP_RANDOMISE_TIME) +/datum/action/item_action/chameleon/change/proc/emp_randomise(amount = EMP_RANDOMISE_TIME) START_PROCESSING(SSprocessing, src) random_look(owner) @@ -223,7 +223,7 @@ if(new_value > emp_timer) emp_timer = new_value -/datum/action/item_action/chameleon_change/process() +/datum/action/item_action/chameleon/change/process() if(world.time > emp_timer) STOP_PROCESSING(SSprocessing, src) return @@ -249,7 +249,7 @@ "Grey" = 'icons/mob/clothing/species/grey/under/color.dmi' ) - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/clothing/under/chameleon/Initialize(mapload) . = ..() @@ -301,7 +301,7 @@ "Vox" = 'icons/mob/clothing/species/vox/suit.dmi' ) - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/clothing/suit/chameleon/Initialize(mapload) . = ..() @@ -338,7 +338,7 @@ "Grey" = 'icons/mob/clothing/species/grey/eyes.dmi' ) - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/clothing/glasses/chameleon/Initialize(mapload) . = ..() @@ -377,7 +377,7 @@ examine_extensions = list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE) flash_protect = FLASH_PROTECTION_FLASH - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/clothing/glasses/hud/security/chameleon/Initialize(mapload) . = ..() @@ -402,7 +402,7 @@ // for style // also its this typepath because random shit type checks based on the meson path /obj/item/clothing/glasses/meson/chameleon - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/clothing/glasses/meson/chameleon/Initialize(mapload) . = ..() @@ -431,7 +431,7 @@ resistance_flags = NONE armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50) - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/clothing/gloves/chameleon/Initialize(mapload) . = ..() @@ -469,7 +469,7 @@ "Vox" = 'icons/mob/clothing/species/vox/head/softcap.dmi' ) - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/clothing/head/chameleon/Initialize(mapload) . = ..() @@ -514,7 +514,7 @@ "Grey" = 'icons/mob/clothing/species/grey/mask.dmi' ) - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/clothing/mask/chameleon/Initialize(mapload) . = ..() @@ -564,7 +564,7 @@ resistance_flags = NONE armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50) - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/clothing/shoes/chameleon/Initialize(mapload) . = ..() @@ -600,7 +600,7 @@ "Vox" = 'icons/mob/clothing/species/vox/back.dmi' ) - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/storage/backpack/chameleon/Initialize(mapload) . = ..() @@ -624,7 +624,7 @@ /obj/item/storage/belt/chameleon name = "tool-belt" desc = "Can hold various tools." - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/storage/belt/chameleon/Initialize(mapload) . = ..() @@ -648,7 +648,7 @@ /obj/item/radio/headset/chameleon name = "radio headset" - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/radio/headset/chameleon/Initialize(mapload) . = ..() @@ -671,7 +671,7 @@ /obj/item/pda/chameleon name = "PDA" - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/pda/chameleon/Initialize(mapload) . = ..() @@ -695,7 +695,7 @@ /obj/item/stamp/chameleon dye_color = DYE_RAINBOW - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/stamp/chameleon/Initialize(mapload) . = ..() @@ -712,36 +712,7 @@ . = ..() chameleon_action.emp_randomise(INFINITY) -/obj/item/clothing/neck/chameleon - name = "black tie" - desc = "A neosilk clip-on tie." - icon = 'icons/obj/clothing/neck.dmi' - icon_state = "blacktie" - resistance_flags = NONE - - var/datum/action/item_action/chameleon_change/chameleon_action - -/obj/item/clothing/neck/chameleon/Initialize(mapload) - . = ..() - chameleon_action = new(src) - chameleon_action.chameleon_type = /obj/item/clothing/neck - chameleon_action.chameleon_name = "Tie" - chameleon_action.chameleon_blacklist = list() - chameleon_action.initialize_disguises() - -/obj/item/clothing/neck/chameleon/Destroy() - QDEL_NULL(chameleon_action) - return ..() - -/obj/item/clothing/neck/chameleon/emp_act(severity) - . = ..() - chameleon_action.emp_randomise() - -/obj/item/clothing/neck/chameleon/broken/Initialize(mapload) - . = ..() - chameleon_action.emp_randomise(INFINITY) - -/datum/action/item_action/chameleon_change/modsuit/update_item(obj/item/picked_item) +/datum/action/item_action/chameleon/change/modsuit/update_item(obj/item/picked_item) if(ismodcontrol(target)) var/obj/item/mod/control/C = target C.current_disguise = FALSE @@ -758,7 +729,7 @@ for(var/obj/item/mod/module/chameleon/tosignal in C.contents) tosignal.RegisterSignal(C, COMSIG_MOD_ACTIVATE, TYPE_PROC_REF(/obj/item/mod/module/chameleon, return_look), TRUE) -/datum/action/item_action/chameleon_change/modsuit/select_look(mob/user) +/datum/action/item_action/chameleon/change/modsuit/select_look(mob/user) if(ismodcontrol(target)) var/obj/item/mod/control/C = target if(C.current_disguise) //backup check diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 188c54e8cb33f..61d242369262b 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -167,7 +167,7 @@ if(!usr.canUnEquip(src)) return - user.drop_item_to_ground(src) + user.unEquip(src) if(src) user.put_in_hands(src) @@ -274,7 +274,7 @@ /obj/item/clothing/gloves/proc/Touch(atom/A, proximity) return // return TRUE to cancel attack_hand() -/obj/item/clothing/gloves/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/item/clothing/gloves/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/wirecutters)) if(!clipped) playsound(src.loc, W.usesound, 100, 1) @@ -436,7 +436,6 @@ . = ..() for(var/obj/item/clothing/head/hat as anything in attached_hats) . += "\A [hat] is placed neatly on top." - . += "Alt-Shift-Click to remove an accessory." //when user attached a hat to H (another hat) /obj/item/clothing/head/proc/on_attached(obj/item/clothing/head/H, mob/user as mob) @@ -508,7 +507,7 @@ /obj/item/clothing/head/proc/attach_hat(obj/item/clothing/head/hat, mob/user, unequip = FALSE) if(can_attach_hat(hat)) - if(unequip && !user.drop_item_to_ground(hat)) // Make absolutely sure this hat is removed from hands + if(unequip && !user.unEquip(hat)) // Make absolutely sure this hat is removed from hands return FALSE attached_hats += hat @@ -526,7 +525,7 @@ return FALSE -/obj/item/clothing/head/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/item/clothing/head/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/clothing/head) && can_have_hats) attach_hat(I, user, TRUE) @@ -571,13 +570,13 @@ flags_cover |= MASKCOVERSMOUTH if(H.head == src) if(isnull(user.get_item_by_slot(slot_flags))) - user.drop_item_to_ground(src) + user.unEquip(src) user.equip_to_slot(src, slot_flags) else if(flags_inv == HIDEFACE) //Means that only things like bandanas and balaclavas will be affected since they obscure the identity of the wearer. if(H.l_hand && H.r_hand) //If both hands are occupied, drop the object on the ground. - user.drop_item_to_ground(src) + user.unEquip(src) else //Otherwise, put it in an available hand, the active one preferentially. - user.drop_item_to_ground(src) + user.unEquip(src) user.put_in_hands(src) else to_chat(user, "You push \the [src] out of the way.") @@ -598,13 +597,13 @@ flags &= ~AIRTIGHT if(user.wear_mask == src) if(isnull(user.get_item_by_slot(slot_flags))) - user.drop_item_to_ground(src) + user.unEquip(src) user.equip_to_slot(src, slot_flags) else if(initial(flags_inv) == HIDEFACE) //Means that you won't have to take off and put back on simple things like breath masks which, realistically, can just be pulled down off your face. if(H.l_hand && H.r_hand) //If both hands are occupied, drop the object on the ground. - user.drop_item_to_ground(src) + user.unEquip(src) else //Otherwise, put it in an available hand, the active one preferentially. - user.drop_item_to_ground(src) + user.unEquip(src) user.put_in_hands(src) H.wear_mask_update(src, toggle_off = up) usr.update_inv_wear_mask() @@ -666,7 +665,7 @@ if(H.get_item_by_slot(ITEM_SLOT_SHOES) == src) REMOVE_TRAIT(H, TRAIT_NOSLIP, UID()) -/obj/item/clothing/shoes/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/item/clothing/shoes/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/match) && src.loc == user) var/obj/item/match/M = I if(!M.lit && !M.burnt) // Match isn't lit, but isn't burnt. @@ -697,7 +696,7 @@ if(hidden_blade) to_chat(user, "There is already something in [src]!") return - if(!user.drop_item_to_ground(I)) + if(!user.unEquip(I)) return user.visible_message("[user] places [I] into their [name]!", \ "You place [I] into the side of your [name]!") @@ -820,10 +819,10 @@ if(istype(O, /obj/item/storage/internal)) //If it's a pocket... if(O.contents) //Check to see if the pocket's got anything in it. for(var/obj/item/I in O.contents) //Dump the pocket out onto the floor below the user. - user.drop_item_to_ground(I, force = TRUE) + user.unEquip(I,1) user.visible_message("[user] bellows, [pick("shredding", "ripping open", "tearing off")] [user.p_their()] jacket in a fit of rage!","You accidentally [pick("shred", "rend", "tear apart")] [src] with your [pick("excessive", "extreme", "insane", "monstrous", "ridiculous", "unreal", "stupendous")] [pick("power", "strength")]!") - user.drop_item_to_ground(src) + user.unEquip(src) qdel(src) //Now that the pockets have been emptied, we can safely destroy the jacket. user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!")) user.update_inv_wear_suit() @@ -901,7 +900,7 @@ return user.visible_message("[user] manages to [break_restraints ? "break" : "remove"] [src]!", "You successfully [break_restraints ? "break" : "remove"] [src].") - user.drop_item_to_ground(src) + user.unEquip(src) ////////////////////////////// // MARK: SPACE SUIT @@ -969,8 +968,6 @@ drop_sound = 'sound/items/handling/cloth_drop.ogg' pickup_sound = 'sound/items/handling/cloth_pickup.ogg' dyeing_key = DYE_REGISTRY_UNDER - strip_delay = 6 SECONDS - put_on_delay = 6 SECONDS sprite_sheets = list( "Vox" = 'icons/mob/clothing/species/vox/under/misc.dmi', @@ -1035,13 +1032,13 @@ return FALSE return TRUE -/obj/item/clothing/under/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/item/clothing/under/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/clothing/accessory)) attach_accessory(I, user, TRUE) if(length(accessories)) for(var/obj/item/clothing/accessory/A in accessories) - A.attackby__legacy__attackchain(I, user, params) + A.attackby(I, user, params) return TRUE . = ..() @@ -1068,7 +1065,7 @@ /obj/item/clothing/under/proc/attach_accessory(obj/item/clothing/accessory/A, mob/user, unequip = FALSE) if(can_attach_accessory(A)) - if(unequip && !user.drop_item_to_ground(A)) // Make absolutely sure this accessory is removed from hands + if(unequip && !user.unEquip(A)) // Make absolutely sure this accessory is removed from hands return FALSE accessories += A @@ -1105,15 +1102,15 @@ if(SUIT_SENSOR_TRACKING) . += "Its vital tracker and tracking beacon appear to be enabled." if(has_sensor == 1) - . += "Alt-Click to toggle the sensors mode." + . += "Alt-click to toggle the sensors mode." else . += "This suit does not have any sensors." if(length(accessories)) for(var/obj/item/clothing/accessory/A in accessories) . += "\A [A] is attached to it." - . += "Alt-Shift-Click to remove an accessory." - . += "Ctrl-Shift-Click to roll down this jumpsuit." + . += "Alt-Shift-Click to remove an accessory." + . += "Ctrl-Shift-Click to roll down this jumpsuit." /obj/item/clothing/under/CtrlShiftClick(mob/living/carbon/human/user) diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm index 5d5ac61035e58..d6189f7615874 100644 --- a/code/modules/clothing/glasses/engine_goggles.dm +++ b/code/modules/clothing/glasses/engine_goggles.dm @@ -4,11 +4,10 @@ #define MODE_MESON "meson" #define MODE_TRAY "t-ray" #define MODE_RAD "radiation" -#define MODE_PRESSURE "pressure" /obj/item/clothing/glasses/meson/engine name = "engineering scanner goggles" - 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, the Radiation Scanner mode lets you see objects contaminated by radiation, and the Pressure Scanner mode lets you visualize air pressure." + 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 lets you see objects contaminated by radiation." icon_state = "trayson-meson" item_state = "trayson-meson" actions_types = list(/datum/action/item_action/toggle_mode) @@ -38,11 +37,6 @@ if(active_on_equip_rad && mode == MODE_RAD && slot == ITEM_SLOT_EYES) ADD_TRAIT(user, SM_HALLUCINATION_IMMUNE, "meson_glasses[UID()]") - if(mode == MODE_PRESSURE && slot == ITEM_SLOT_EYES) - ADD_TRAIT(user, TRAIT_PRESSURE_VISION, "meson_glasses[UID()]") - if(mode == MODE_PRESSURE && slot != ITEM_SLOT_EYES) - REMOVE_TRAIT(user, TRAIT_PRESSURE_VISION, "meson_glasses[UID()]") - /obj/item/clothing/glasses/meson/engine/proc/toggle_mode(mob/user, voluntary) mode = modes[mode] to_chat(user, "[voluntary ? "You turn the goggles" : "The goggles turn"] [mode ? "to [mode] mode" : "off"][voluntary ? "." : "!"]") @@ -63,12 +57,6 @@ REMOVE_TRAIT(user, SM_HALLUCINATION_IMMUNE, "meson_glasses[UID()]") active_on_equip_rad = FALSE - if(mode == MODE_PRESSURE) - if(!HAS_TRAIT_FROM(user, TRAIT_PRESSURE_VISION, "meson_glasses[UID()]") && user.get_item_by_slot(ITEM_SLOT_EYES) == src) - ADD_TRAIT(user, TRAIT_PRESSURE_VISION, "meson_glasses[UID()]") - else - REMOVE_TRAIT(user, TRAIT_PRESSURE_VISION, "meson_glasses[UID()]") - if(ishuman(user)) var/mob/living/carbon/human/H = user if(H.glasses == src) @@ -79,7 +67,7 @@ var/datum/action/A = X A.UpdateButtons() -/obj/item/clothing/glasses/meson/engine/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/glasses/meson/engine/attack_self(mob/user) toggle_mode(user, TRUE) /obj/item/clothing/glasses/meson/engine/process() @@ -113,18 +101,17 @@ user.update_inv_l_hand() user.update_inv_r_hand() -/// Atmospherics techs get their own version with T-ray and an exlusive Pressure view. -/obj/item/clothing/glasses/meson/engine/atmos - name = "atmospherics scanner goggles" - icon_state = "trayson-pressure" - item_state = "trayson-pressure" - desc = "Used by atmospherics techs to visualize pressure, see station structure, and see underfloor objects such as cables and pipes." +/// atmos techs have lived far too long without tray goggles while those damned engineers get their dual-purpose gogles all to themselves +/obj/item/clothing/glasses/meson/engine/tray + name = "optical t-ray scanner" + icon_state = "trayson-t-ray" + item_state = "trayson-t-ray" + desc = "Used by engineering staff to see underfloor objects such as cables and pipes." range = 2 origin_tech = "materials=3;magnets=2;engineering=2" - modes = list(MODE_NONE = MODE_PRESSURE, MODE_PRESSURE = MODE_MESON, MODE_MESON = MODE_TRAY, MODE_TRAY = MODE_NONE) + modes = list(MODE_NONE = MODE_TRAY, MODE_TRAY = MODE_NONE) #undef MODE_NONE #undef MODE_MESON #undef MODE_TRAY #undef MODE_RAD -#undef MODE_PRESSURE diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 25e886f87190b..2004447294b37 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -3,7 +3,7 @@ if(prescription_upgradable && prescription) upgrade_prescription() -/obj/item/clothing/glasses/attackby__legacy__attackchain(obj/item/I, mob/user) +/obj/item/clothing/glasses/attackby(obj/item/I, mob/user) if(!prescription_upgradable || user.stat || user.restrained() || !ishuman(user)) return ..() var/mob/living/carbon/human/H = user @@ -13,7 +13,7 @@ if(prescription) to_chat(H, "You can't possibly imagine how adding more lenses would improve [src].") return - H.drop_item_to_ground(I) + H.unEquip(I) upgrade_prescription(I) to_chat(H, "You fit [src] with lenses from [I].") @@ -366,7 +366,7 @@ desc = "Somehow these seem even more out-of-date than normal sunglasses." actions_types = list(/datum/action/item_action/noir) -/obj/item/clothing/glasses/sunglasses/noir/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/glasses/sunglasses/noir/attack_self(mob/user) toggle_noir(user) /obj/item/clothing/glasses/sunglasses/noir/item_action_slot_check(slot) @@ -381,9 +381,9 @@ name = "agreeable glasses" desc = "H.C Limited edition." var/punused = FALSE - actions_types = list(/datum/action/item_action/yeeeaaaaahhhhhhhhhhhhh) + actions_types = list(/datum/action/item_action/YEEEAAAAAHHHHHHHHHHHHH) -/obj/item/clothing/glasses/sunglasses/yeah/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/glasses/sunglasses/yeah/attack_self(mob/user) pun(user) /obj/item/clothing/glasses/sunglasses/yeah/proc/pun(mob/user) @@ -451,7 +451,7 @@ "Kidan" = 'icons/mob/clothing/species/kidan/eyes.dmi' ) -/obj/item/clothing/glasses/welding/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/glasses/welding/attack_self(mob/user) weldingvisortoggle(user) /obj/item/clothing/glasses/welding/superior diff --git a/code/modules/clothing/glasses/tajblind.dm b/code/modules/clothing/glasses/tajblind.dm index c336b9c23a936..00ec29e529651 100644 --- a/code/modules/clothing/glasses/tajblind.dm +++ b/code/modules/clothing/glasses/tajblind.dm @@ -19,7 +19,7 @@ "Grey" = 'icons/mob/clothing/species/grey/eyes.dmi' ) -/obj/item/clothing/glasses/hud/tajblind/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/glasses/hud/tajblind/attack_self(mob/user) toggle_veil(user, TRUE) /obj/item/clothing/glasses/hud/tajblind/proc/toggle_veil(mob/user, voluntary) diff --git a/code/modules/clothing/gloves/colored_gloves.dm b/code/modules/clothing/gloves/colored_gloves.dm index a4426893cceeb..0493b1ac1c25f 100644 --- a/code/modules/clothing/gloves/colored_gloves.dm +++ b/code/modules/clothing/gloves/colored_gloves.dm @@ -60,7 +60,7 @@ /obj/item/clothing/gloves/color/black/thief pickpocket = 1 -/obj/item/clothing/gloves/color/black/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) +/obj/item/clothing/gloves/color/black/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, /obj/item/wirecutters)) if(can_be_cut && icon_state == initial(icon_state))//only if not dyed var/confirm = tgui_alert(user, "Do you want to cut off the gloves fingertips? Warning: It might destroy their functionality.", "Cut tips?", list("Yes","No")) diff --git a/code/modules/clothing/gloves/misc_gloves.dm b/code/modules/clothing/gloves/misc_gloves.dm index 956d8254e7d37..3cc42d2328400 100644 --- a/code/modules/clothing/gloves/misc_gloves.dm +++ b/code/modules/clothing/gloves/misc_gloves.dm @@ -162,7 +162,7 @@ if(cell) . += "gloves_cell" -/obj/item/clothing/gloves/color/yellow/stun/attackby__legacy__attackchain(obj/item/W, mob/living/user, params) +/obj/item/clothing/gloves/color/yellow/stun/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/stock_parts/cell)) if(!cell) if(!user.drop_item()) diff --git a/code/modules/clothing/gloves/rings.dm b/code/modules/clothing/gloves/rings.dm index c0d6e4e1b9b70..aa64d1ca9f378 100644 --- a/code/modules/clothing/gloves/rings.dm +++ b/code/modules/clothing/gloves/rings.dm @@ -25,7 +25,7 @@ if(stud) . += "It is adorned with a single gem." -/obj/item/clothing/gloves/ring/attackby__legacy__attackchain(obj/item/I as obj, mob/user as mob, params) +/obj/item/clothing/gloves/ring/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/stack/sheet/mineral/diamond)) var/obj/item/stack/sheet/mineral/diamond/D = I if(stud) diff --git a/code/modules/clothing/head/beret.dm b/code/modules/clothing/head/beret.dm index 55518efad77a1..9832b2438b7bb 100644 --- a/code/modules/clothing/head/beret.dm +++ b/code/modules/clothing/head/beret.dm @@ -9,7 +9,6 @@ dog_fashion = /datum/dog_fashion/head/beret sprite_sheets = list( - "Kidan" = 'icons/mob/clothing/species/kidan/head/beret.dmi', "Vox" = 'icons/mob/clothing/species/vox/head/beret.dmi' ) @@ -75,7 +74,7 @@ icon_state = "beret_hos_black" armor = list(MELEE = 35, BULLET = 20, LASER = 20, ENERGY = 5, BOMB = 15, RAD = 0, FIRE = 50, ACID = 75) strip_delay = 80 - dog_fashion = /datum/dog_fashion/head/hos + dog_fashion = /datum/dog_fashion/head/HoS /obj/item/clothing/head/beret/sec name = "security beret" @@ -178,31 +177,9 @@ "Drask" = 'icons/mob/clothing/species/drask/head/beret.dmi' ) -//NT Career Trainer -/obj/item/clothing/head/beret/nct/black - name = "\improper NT Career Trainer's beret" - desc = "A beret worn by the mentors and trainers of the Career Training Team. This one is black!" - icon_state = "beret_trainerblack" - - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/head/beret.dmi', - "Drask" = 'icons/mob/clothing/species/drask/head/beret.dmi', - "Kidan" = 'icons/mob/clothing/species/kidan/head/beret.dmi' - ) - -/obj/item/clothing/head/beret/nct/green - name = "\improper NT Career Trainer's beret" - desc = "A beret worn by the mentors and trainers of the Career Training Team. This one is green!" - icon_state = "beret_trainergreen" - - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/head/beret.dmi', - "Drask" = 'icons/mob/clothing/species/drask/head/beret.dmi', - "Kidan" = 'icons/mob/clothing/species/kidan/head/beret.dmi' - ) //Special Roles -/obj/item/clothing/head/beret/solgov +/obj/item/clothing/head/beret/solgov/command name = "\improper TSF Lieutenant's beret" desc = "A beret worn by marines of the Trans-Solar Federation. The insignia signifies the wearer bears the rank of a Lieutenant." icon_state = "beret_solgovc" @@ -211,7 +188,7 @@ armor = list(MELEE = 10, BULLET = 20, LASER = 20, ENERGY = 5, BOMB = 15, RAD = 0, FIRE = 50, ACID = 75) strip_delay = 80 -/obj/item/clothing/head/beret/solgov/elite +/obj/item/clothing/head/beret/solgov/command/elite name = "\improper MARSOC Lieutenant's beret" desc = "A beret worn by junior officers of the Trans-Solar Federation's Marine Special Operations Command. The insignia signifies the wearer bears the rank of a Lieutenant." armor = list(MELEE = 25, BULLET = 75, LASER = 5, ENERGY = 5, BOMB = 15, RAD = 50, FIRE = 200, ACID = 200) diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm index 49e3a75226dc0..dd507502224dd 100644 --- a/code/modules/clothing/head/collectable.dm +++ b/code/modules/clothing/head/collectable.dm @@ -127,12 +127,12 @@ item_state = "hardhat0_yellow" dog_fashion = /datum/dog_fashion/head/hardhat -/obj/item/clothing/head/collectable/hos +/obj/item/clothing/head/collectable/HoS name = "collectable HoS hat" desc = "Now you can beat prisoners, set silly sentences and arrest for no reason too!" icon_state = "hos_cap" -/obj/item/clothing/head/collectable/hop +/obj/item/clothing/head/collectable/HoP name = "collectable HoP hat" desc = "It's your turn to demand excessive paperwork, signatures, stamps, and hire more clowns! Papers, please!" icon_state = "hopcap" diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 59cb22ee07143..40ba093a9f3be 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -17,7 +17,7 @@ "Vox" = 'icons/mob/clothing/species/vox/head.dmi' ) -/obj/item/clothing/head/hardhat/attack_self__legacy__attackchain(mob/living/user) +/obj/item/clothing/head/hardhat/attack_self(mob/living/user) toggle_helmet_light(user) /obj/item/clothing/head/hardhat/proc/toggle_helmet_light(mob/living/user) diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 2b30ef879d83d..e9d0ccc373508 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -21,7 +21,7 @@ "Grey" = 'icons/mob/clothing/species/grey/helmet.dmi' ) -/obj/item/clothing/head/helmet/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/head/helmet/attack_self(mob/user) if(can_toggle && !user.incapacitated()) if(world.time > cooldown + toggle_cooldown) cooldown = world.time diff --git a/code/modules/clothing/head/job_hats.dm b/code/modules/clothing/head/job_hats.dm index 2a1b5b6ea744a..3ba0784ecfb99 100644 --- a/code/modules/clothing/head/job_hats.dm +++ b/code/modules/clothing/head/job_hats.dm @@ -117,13 +117,13 @@ ) //Security -/obj/item/clothing/head/hos +/obj/item/clothing/head/HoS name = "head of security's cap" desc = "The robust standard-issue cap of the Head of Security. For showing the officers who's in charge." icon_state = "hos_cap" armor = list(MELEE = 35, BULLET = 20, LASER = 20, ENERGY = 5, BOMB = 15, RAD = 0, FIRE = 50, ACID = 75) strip_delay = 80 - dog_fashion = /datum/dog_fashion/head/hos + dog_fashion = /datum/dog_fashion/head/HoS /obj/item/clothing/head/warden name = "warden's police hat" @@ -193,14 +193,3 @@ desc = "A cap coroners wear during autopsies. Keeps their hair from falling into the cadavers. It is as dark as the coroner's humor." icon_state = "surgcap_black" dog_fashion = /datum/dog_fashion/head/surgery - -// NT Career Trainer -/obj/item/clothing/head/drilltrainer - name = "campaign hat" - desc = "A wide-brimmed campaign hat with a drill sergeant feel, worn by Career Trainers to project knowledge and guide new employees with classic style." - icon_state = "trainercampaign" - item_state = "trainercampaign" - - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/head.dmi' - ) diff --git a/code/modules/clothing/head/misc_hats.dm b/code/modules/clothing/head/misc_hats.dm index 82ed36e1a68e0..d8cb0d72d0244 100644 --- a/code/modules/clothing/head/misc_hats.dm +++ b/code/modules/clothing/head/misc_hats.dm @@ -277,7 +277,7 @@ "Grey" = 'icons/mob/clothing/species/grey/head.dmi' ) -/obj/item/clothing/head/fedora/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/head/fedora/attack_self(mob/user) tip_fedora(user) /obj/item/clothing/head/fedora/item_action_slot_check(slot) @@ -488,7 +488,7 @@ ) actions_types = list(/datum/action/item_action/caw) -/obj/item/clothing/head/griffin/attack_self__legacy__attackchain() +/obj/item/clothing/head/griffin/attack_self() caw() /obj/item/clothing/head/griffin/proc/caw() diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 1c0f9e83ea2be..35c40863d2519 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -35,7 +35,7 @@ "Grey" = 'icons/mob/clothing/species/grey/helmet.dmi' ) -/obj/item/clothing/head/welding/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/head/welding/attack_self(mob/user) weldingvisortoggle(user) /obj/item/clothing/head/welding/flamedecal @@ -80,7 +80,7 @@ if(isturf(location)) location.hotspot_expose(700, 1) -/obj/item/clothing/head/cakehat/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/head/cakehat/attack_self(mob/user) if(status > 1) return onfire = !onfire @@ -112,7 +112,7 @@ "Vox" = 'icons/mob/clothing/species/vox/head.dmi' ) -/obj/item/clothing/head/ushanka/attack_self__legacy__attackchain(mob/user as mob) +/obj/item/clothing/head/ushanka/attack_self(mob/user as mob) if(icon_state == "ushankadown") icon_state = "ushankaup" item_state = "ushankaup" diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm index ad3c82793c273..d995941c91c1e 100644 --- a/code/modules/clothing/head/soft_caps.dm +++ b/code/modules/clothing/head/soft_caps.dm @@ -10,7 +10,6 @@ actions_types = list(/datum/action/item_action/flip_cap) dog_fashion = /datum/dog_fashion/head/softcap sprite_sheets = list( - "Kidan" = 'icons/mob/clothing/species/kidan/head/softcap.dmi', "Vox" = 'icons/mob/clothing/species/vox/head/softcap.dmi' ) dyeable = TRUE @@ -20,7 +19,7 @@ flipped = FALSE ..() -/obj/item/clothing/head/soft/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/head/soft/attack_self(mob/user) flip(user) /obj/item/clothing/head/soft/proc/flip(mob/user) diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm index 14c5b20e33c81..cab34dd939f12 100644 --- a/code/modules/clothing/masks/boxing.dm +++ b/code/modules/clothing/masks/boxing.dm @@ -19,7 +19,7 @@ "Drask" = 'icons/mob/clothing/species/drask/mask.dmi' ) -/obj/item/clothing/mask/balaclava/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/mask/balaclava/attack_self(mob/user) adjustmask(user) /obj/item/clothing/mask/luchador diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm index 1c0f6a910ebb4..b3dbe8df3f804 100644 --- a/code/modules/clothing/masks/breath.dm +++ b/code/modules/clothing/masks/breath.dm @@ -21,7 +21,7 @@ "Plasmaman" = 'icons/mob/clothing/species/plasmaman/mask.dmi' ) -/obj/item/clothing/mask/breath/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/mask/breath/attack_self(mob/user) adjustmask(user) /obj/item/clothing/mask/breath/AltClick(mob/user) @@ -53,7 +53,7 @@ icon_state = "voxmask2" item_state = "voxmask2" -/obj/item/clothing/mask/breath/vox/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/mask/breath/vox/attack_self(mob/user) return /obj/item/clothing/mask/breath/vox/AltClick(mob/user) diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 8dc10bf627600..16beafffc3aac 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -47,7 +47,7 @@ "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi' ) -/obj/item/clothing/mask/gas/welding/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/mask/gas/welding/attack_self(mob/user) weldingvisortoggle(user) /obj/item/clothing/mask/gas/explorer @@ -71,7 +71,7 @@ /obj/item/clothing/mask/gas/explorer/marines name = "military gas mask" -/obj/item/clothing/mask/gas/explorer/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/mask/gas/explorer/attack_self(mob/user) adjustmask(user) /obj/item/clothing/mask/gas/explorer/adjustmask(user) @@ -128,7 +128,7 @@ resistance_flags = FLAMMABLE dog_fashion = /datum/dog_fashion/head/clown -/obj/item/clothing/mask/gas/clown_hat/attack_self__legacy__attackchain(mob/living/user) +/obj/item/clothing/mask/gas/clown_hat/attack_self(mob/living/user) var/list/mask_type = list("True Form" = /obj/item/clothing/mask/gas/clown_hat, "The Feminist" = /obj/item/clothing/mask/gas/clown_hat/sexy, "The Madman" = /obj/item/clothing/mask/gas/clown_hat/joker, @@ -226,7 +226,7 @@ /obj/item/clothing/mask/gas/owl_mask/super_hero flags = BLOCK_GAS_SMOKE_EFFECT | AIRTIGHT | NODROP -/obj/item/clothing/mask/gas/owl_mask/attack_self__legacy__attackchain() +/obj/item/clothing/mask/gas/owl_mask/attack_self() hoot() /obj/item/clothing/mask/gas/owl_mask/proc/hoot() @@ -346,7 +346,7 @@ else to_chat(user, "It's broken.") -/obj/item/clothing/mask/gas/sechailer/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) +/obj/item/clothing/mask/gas/sechailer/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, /obj/item/wirecutters)) if(aggressiveness != 5) to_chat(user, "You broke it!") @@ -376,7 +376,7 @@ to_chat(user, "You adjust the restrictor but nothing happens, probably because its broken.") return TRUE -/obj/item/clothing/mask/gas/sechailer/attack_self__legacy__attackchain() +/obj/item/clothing/mask/gas/sechailer/attack_self() halt() /obj/item/clothing/mask/gas/sechailer/emag_act(mob/user as mob) diff --git a/code/modules/clothing/masks/misc_masks.dm b/code/modules/clothing/masks/misc_masks.dm index b26f2dc893f63..b2915e0090cab 100644 --- a/code/modules/clothing/masks/misc_masks.dm +++ b/code/modules/clothing/masks/misc_masks.dm @@ -113,7 +113,7 @@ origin_tech = "materials=1;engineering=1" materials = list(MAT_METAL=500, MAT_GLASS=50) -/obj/item/clothing/mask/muzzle/safety/shock/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/item/clothing/mask/muzzle/safety/shock/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/assembly/signaler) || istype(W, /obj/item/assembly/voice)) if(istype(trigger, /obj/item/assembly/signaler) || istype(trigger, /obj/item/assembly/voice)) to_chat(user, "Something is already attached to [src].") @@ -198,7 +198,7 @@ ) -/obj/item/clothing/mask/surgical/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/mask/surgical/attack_self(mob/user) adjustmask(user) /obj/item/clothing/mask/fakemoustache @@ -218,7 +218,7 @@ "Drask" = 'icons/mob/clothing/species/drask/mask.dmi' ) -/obj/item/clothing/mask/fakemoustache/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/mask/fakemoustache/attack_self(mob/user) pontificate(user) /obj/item/clothing/mask/fakemoustache/item_action_slot_check(slot) @@ -377,7 +377,7 @@ ) actions_types = list(/datum/action/item_action/adjust) -/obj/item/clothing/mask/bandana/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/mask/bandana/attack_self(mob/user) adjustmask(user) /obj/item/clothing/mask/bandana/red diff --git a/code/modules/clothing/masks/voicemodulator.dm b/code/modules/clothing/masks/voicemodulator.dm index 89d39cd8b5787..665ef58fe45b3 100644 --- a/code/modules/clothing/masks/voicemodulator.dm +++ b/code/modules/clothing/masks/voicemodulator.dm @@ -20,7 +20,7 @@ icon_state = "swat" item_state = "swat" - var/datum/action/item_action/chameleon_change/chameleon_action + var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/clothing/mask/gas/voice_modulator/chameleon/Initialize(mapload) . = ..() diff --git a/code/modules/clothing/neck/cloaks.dm b/code/modules/clothing/neck/cloaks.dm index 780c61326b2f9..02ae9f4d4f18c 100644 --- a/code/modules/clothing/neck/cloaks.dm +++ b/code/modules/clothing/neck/cloaks.dm @@ -45,74 +45,3 @@ name = "head of personnel's cloak" desc = "Worn by the Head of Personnel. It smells faintly of bureaucracy." icon_state = "hopcloak" - -//Mantles. - -/obj/item/clothing/neck/cloak/mantle - name = "mantle" - desc = "A heavy quilted mantle, for keeping your shoulders warm and stylish." - icon_state = "mantle" - item_state = "mantle" - -/obj/item/clothing/neck/cloak/regal - name = "regal shawl" - desc = "A fancy shawl for nobility, made from high quality materials." - icon_state = "regal_mantle" - item_state = "regal_mantle" - -/obj/item/clothing/neck/cloak/old - name = "old wrap" - desc = "A tattered fabric wrap, faded over the years. Smells faintly of cigars." - icon_state = "old_mantle" - item_state = "old_mantle" - -/obj/item/clothing/neck/cloak/unathi - name = "hide mantle" - desc = "A rather grisly selection of cured hides and skin, sewn together to form a ragged mantle." - icon_state = "mantle-unathi" - item_state = "mantle-unathi" - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/neck.dmi' - ) - -/obj/item/clothing/neck/cloak/captain_mantle - name = "captain's mantle" - desc = "A piece of fashion for the ruling elite." - icon_state = "capmantle" - item_state = "capmantle" - -/obj/item/clothing/neck/cloak/hos_mantle - name = "head of security's shawl" - desc = "An unarmored shawl, worn by the Head of Security. Do you dare take up their mantle?" - icon_state = "hosmantle" - item_state = "hosmantle" - -/obj/item/clothing/neck/cloak/hop_mantle - name = "head of personnel's shawl" - desc = "A shawl for the head of personnel. It's remarkably well kept." - icon_state = "hopmantle" - item_state = "hopmantle" - -/obj/item/clothing/neck/cloak/ce_mantle - name = "chief engineer's mantle" - desc = "A slick, authoritative mantle designed for the Chief Engineer." - icon_state = "cemantle" - item_state = "cemantle" - -/obj/item/clothing/neck/cloak/cmo_mantle - name = "chief medical officer's mantle" - desc = "An absorbent, clean cover found around the neck of the Chief Medical Officer." - icon_state = "cmomantle" - item_state = "cmomantle" - -/obj/item/clothing/neck/cloak/qm_mantle - name = "quartermaster's mantle" - desc = "A shawl for the quartermaster. Keeps the breeze from the vents away from your neck." - icon_state = "qmmantle" - item_state = "qmmantle" - -/obj/item/clothing/neck/cloak/rd_mantle - name = "research director's mantle" - desc = "A tweed mantle, worn by the Research Director. Smells like science." - icon_state = "rdmantle" - item_state = "rdmantle" diff --git a/code/modules/clothing/neck/neck.dm b/code/modules/clothing/neck/neck.dm deleted file mode 100644 index bf9b754ed32b3..0000000000000 --- a/code/modules/clothing/neck/neck.dm +++ /dev/null @@ -1,96 +0,0 @@ -/obj/item/clothing/neck/tie - name = "tie" - desc = "A neosilk clip-on tie." - w_class = WEIGHT_CLASS_SMALL - var/under_suit = FALSE - -/obj/item/clothing/neck/tie/blue - name = "blue tie" - icon_state = "bluetie" - item_color = "bluetie" - -/obj/item/clothing/neck/tie/red - name = "red tie" - icon_state = "redtie" - item_color = "redtie" - -/obj/item/clothing/neck/tie/black - name = "black tie" - icon_state = "blacktie" - item_color = "blacktie" - -/obj/item/clothing/neck/tie/horrible - name = "horrible tie" - desc = "A neosilk clip-on tie. This one is disgusting." - icon_state = "horribletie" - item_color = "horribletie" - -/obj/item/clothing/neck/tie/examine(mob/user) - . = ..() - . += "You can Alt-Click [src] to adjust if it is worn under or over your suit." - -/obj/item/clothing/neck/tie/AltClick(mob/living/carbon/human/user) - if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user) || !istype(user)) - return - - under_suit = !under_suit - if(user.neck == src) - user.update_inv_neck() - to_chat(user, "You adjust [src] to be worn [under_suit ? "under" : "over"] your suit.") - -/obj/item/clothing/neck/stethoscope - name = "stethoscope" - desc = "An outdated medical apparatus, used to get a rough idea of the condition of the heart and lungs. It also makes you look like you know what you're doing." - icon_state = "stethoscope" - item_color = "stethoscope" - -/obj/item/clothing/neck/stethoscope/attack__legacy__attackchain(mob/living/carbon/human/M, mob/living/user) - if(!ishuman(M) || !isliving(user)) - return ..(M, user) - - if(user == M) - user.visible_message("[user] places [src] against [user.p_their()] chest and listens attentively.", "You place [src] against your chest...") - else - user.visible_message("[user] places [src] against [M]'s chest and listens attentively.", "You place [src] against [M]'s chest...") - var/datum/organ/heart/heart_datum = M.get_int_organ_datum(ORGAN_DATUM_HEART) - var/datum/organ/lungs/lung_datum = M.get_int_organ_datum(ORGAN_DATUM_LUNGS) - if(!lung_datum || !heart_datum) - to_chat(user, "You don't hear anything.") - return - - var/obj/item/organ/internal/H = heart_datum.linked_organ - var/obj/item/organ/internal/L = lung_datum.linked_organ - if(!M.pulse || (!H || !(L && !HAS_TRAIT(M, TRAIT_NOBREATH)))) - to_chat(user, "You don't hear anything.") - return - - var/color = "notice" - if(H) - var/heart_sound - switch(H.damage) - if(0 to 1) - heart_sound = "healthy" - if(1 to 25) - heart_sound = "offbeat" - if(25 to 50) - heart_sound = "uneven" - color = "warning" - if(50 to INFINITY) - heart_sound = "weak, unhealthy" - color = "warning" - to_chat(user, "You hear \an [heart_sound] pulse.") - - if(L) - var/lung_sound - switch(L.damage) - if(0 to 1) - lung_sound = "healthy respiration" - if(1 to 25) - lung_sound = "labored respiration" - if(25 to 50) - lung_sound = "pained respiration" - color = "warning" - if(50 to INFINITY) - lung_sound = "gurgling" - color = "warning" - to_chat(user, "You hear [lung_sound].") diff --git a/code/modules/clothing/neck/necklace.dm b/code/modules/clothing/neck/necklace.dm deleted file mode 100644 index 9a46d7cfadf90..0000000000000 --- a/code/modules/clothing/neck/necklace.dm +++ /dev/null @@ -1,79 +0,0 @@ -/obj/item/clothing/neck/necklace - name = "necklace" - desc = "A simple necklace." - icon_state = "necklace" - item_state = "necklace" - item_color = "necklace" - w_class = WEIGHT_CLASS_SMALL - -/obj/item/clothing/neck/necklace/long - name = "large necklace" - desc = "A large necklace." - icon_state = "necklacelong" - item_state = "necklacelong" - item_color = "necklacelong" - -/obj/item/clothing/neck/necklace/dope - name = "gold necklace" - desc = "Damn, it feels good to be a gangster." - icon_state = "bling" - item_state = "bling" - item_color = "bling" - -/obj/item/clothing/neck/necklace/locket - name = "gold locket" - desc = "A gold locket that seems to have space for a photo within." - icon_state = "locketgold" - item_state = "locketgold" - item_color = "locketgold" - var/base_icon - var/open - /// Item inside locket. - var/obj/item/held - -/obj/item/clothing/neck/necklace/locket/Destroy() - QDEL_NULL(held) - return ..() - - -/obj/item/clothing/neck/necklace/locket/attack_self__legacy__attackchain(mob/user) - if(!base_icon) - base_icon = icon_state - - if(!("[base_icon]_open" in icon_states(icon))) - to_chat(user, "[src] doesn't seem to open.") - return - - open = !open - to_chat(user, "You flip [src] [open ? "open" : "closed"].") - if(open) - icon_state = "[base_icon]_open" - if(held) - to_chat(user, "[held] falls out!") - held.forceMove(get_turf(user)) - held = null - else - icon_state = "[base_icon]" - -/obj/item/clothing/neck/necklace/locket/attackby__legacy__attackchain(obj/item/O, mob/user) - if(!open) - to_chat(user, "You have to open it first.") - return - - if(istype(O, /obj/item/paper) || istype(O, /obj/item/photo)) - if(held) - to_chat(usr, "[src] already has something inside it.") - else - to_chat(usr, "You slip [O] into [src].") - user.drop_item() - O.forceMove(src) - held = O - else - return ..() - -/obj/item/clothing/neck/necklace/locket/silver - name = "silver locket" - desc = "A silver locket that seems to have space for a photo within." - icon_state = "locketsilver" - item_state = "locketsilver" - item_color = "locketsilver" diff --git a/code/modules/clothing/neck/scarfs.dm b/code/modules/clothing/neck/scarfs.dm deleted file mode 100644 index ffa1a4b0dd8fe..0000000000000 --- a/code/modules/clothing/neck/scarfs.dm +++ /dev/null @@ -1,78 +0,0 @@ -/obj/item/clothing/neck/scarf - name = "scarf" - desc = "A stylish scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks." - w_class = WEIGHT_CLASS_SMALL - dog_fashion = /datum/dog_fashion/head - -/obj/item/clothing/neck/scarf/red - name = "red scarf" - icon_state = "redscarf" - item_color = "redscarf" - -/obj/item/clothing/neck/scarf/green - name = "green scarf" - icon_state = "greenscarf" - item_color = "greenscarf" - -/obj/item/clothing/neck/scarf/darkblue - name = "dark blue scarf" - icon_state = "darkbluescarf" - item_color = "darkbluescarf" - -/obj/item/clothing/neck/scarf/purple - name = "purple scarf" - icon_state = "purplescarf" - item_color = "purplescarf" - -/obj/item/clothing/neck/scarf/yellow - name = "yellow scarf" - icon_state = "yellowscarf" - item_color = "yellowscarf" - -/obj/item/clothing/neck/scarf/orange - name = "orange scarf" - icon_state = "orangescarf" - item_color = "orangescarf" - -/obj/item/clothing/neck/scarf/lightblue - name = "light blue scarf" - icon_state = "lightbluescarf" - item_color = "lightbluescarf" - -/obj/item/clothing/neck/scarf/white - name = "white scarf" - icon_state = "whitescarf" - item_color = "whitescarf" - -/obj/item/clothing/neck/scarf/black - name = "black scarf" - icon_state = "blackscarf" - item_color = "blackscarf" - -/obj/item/clothing/neck/scarf/zebra - name = "zebra scarf" - icon_state = "zebrascarf" - item_color = "zebrascarf" - -/obj/item/clothing/neck/scarf/christmas - name = "christmas scarf" - icon_state = "christmasscarf" - item_color = "christmasscarf" - -/obj/item/clothing/neck/scarf/stripedred - name = "striped red scarf" - icon_state = "stripedredscarf" - item_color = "stripedredscarf" - dog_fashion = null - -/obj/item/clothing/neck/scarf/stripedgreen - name = "striped green scarf" - icon_state = "stripedgreenscarf" - item_color = "stripedgreenscarf" - dog_fashion = null - -/obj/item/clothing/neck/scarf/stripedblue - name = "striped blue scarf" - icon_state = "stripedbluescarf" - item_color = "stripedbluescarf" - dog_fashion = null diff --git a/code/modules/clothing/shoes/colour.dm b/code/modules/clothing/shoes/colour.dm index 30641f6403dc5..60f6998a72914 100644 --- a/code/modules/clothing/shoes/colour.dm +++ b/code/modules/clothing/shoes/colour.dm @@ -73,14 +73,14 @@ QDEL_NULL(shackles) return ..() -/obj/item/clothing/shoes/orange/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/shoes/orange/attack_self(mob/user) if(shackles) user.put_in_hands(shackles) shackles = null slowdown = SHOES_SLOWDOWN icon_state = "orange" -/obj/item/clothing/shoes/orange/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/item/clothing/shoes/orange/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/restraints/handcuffs) && !shackles) if(user.drop_item()) I.forceMove(src) diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 932787d7d9471..6e36ba0d104f6 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -34,7 +34,7 @@ return check_mag_pulse(user, removing = TRUE) -/obj/item/clothing/shoes/magboots/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/shoes/magboots/attack_self(mob/user) toggle_magpulse(user) /obj/item/clothing/shoes/magboots/proc/toggle_magpulse(mob/user, no_message) @@ -101,7 +101,7 @@ /obj/item/clothing/shoes/magboots/advance/Initialize(mapload) . = ..() - AddElement(/datum/element/high_value_item) + RegisterSignal(src, COMSIG_PARENT_QDELETING, PROC_REF(alert_admins_on_destroy)) /obj/item/clothing/shoes/magboots/syndie name = "blood-red magboots" @@ -272,12 +272,12 @@ cell = null update_icon() -/obj/item/clothing/shoes/magboots/gravity/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/item/clothing/shoes/magboots/gravity/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/stock_parts/cell)) if(cell) to_chat(user, "[src] already has a cell!") return - if(!user.drop_item_to_ground(I)) + if(!user.unEquip(I)) return I.forceMove(src) cell = I diff --git a/code/modules/clothing/shoes/misc_shoes.dm b/code/modules/clothing/shoes/misc_shoes.dm index b5b8d0cadbafd..e0a1ac06e51bb 100644 --- a/code/modules/clothing/shoes/misc_shoes.dm +++ b/code/modules/clothing/shoes/misc_shoes.dm @@ -423,7 +423,7 @@ desc = "A pair of masterfully crafted lizard skin boots. Finally a good application for the station's most bothersome inhabitants." icon_state = "lizardboots_blue" -/obj/effect/spawner/random/lizardboots +/obj/effect/spawner/lootdrop/lizardboots name = "random lizard boot quality" desc = "Which ever gets picked, the lizard race loses." icon = 'icons/obj/clothing/shoes.dmi' diff --git a/code/modules/clothing/spacesuits/alien_suits.dm b/code/modules/clothing/spacesuits/alien_suits.dm index 972b98a5b3ad6..159b011cc96a6 100644 --- a/code/modules/clothing/spacesuits/alien_suits.dm +++ b/code/modules/clothing/spacesuits/alien_suits.dm @@ -214,7 +214,7 @@ "Vox" = 'icons/mob/clothing/species/vox/feet.dmi') multiple_icons = FALSE -/obj/item/clothing/shoes/magboots/vox/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/shoes/magboots/vox/attack_self(mob/user) if(magpulse) flags &= ~NODROP to_chat(user, "You relax your deathgrip on the flooring.") diff --git a/code/modules/clothing/spacesuits/ert_hardsuits.dm b/code/modules/clothing/spacesuits/ert_hardsuits.dm index 158cdde67748c..db21c8f4efbd9 100644 --- a/code/modules/clothing/spacesuits/ert_hardsuits.dm +++ b/code/modules/clothing/spacesuits/ert_hardsuits.dm @@ -28,7 +28,7 @@ register_camera(wearer) return ..() -/obj/item/clothing/head/helmet/space/hardsuit/ert/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/head/helmet/space/hardsuit/ert/attack_self(mob/user) if(camera || !has_camera) ..(user) else @@ -56,7 +56,6 @@ desc = "A powered combat hardsuit produced by Citadel Armories. Decently armored, environmentally sealed, and fire-resistant." icon_state = "ert_commander" item_state = "suit-command" - slowdown = 0 w_class = WEIGHT_CLASS_NORMAL armor = list(MELEE = 40, BULLET = 15, LASER = 20, ENERGY = 5, BOMB = 15, RAD = 50, FIRE = 200, ACID = 200) allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/t_scanner, /obj/item/rcd, /obj/item/crowbar, \ diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 1ca2bda770d71..2043bdd69e061 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -50,7 +50,7 @@ suit = null return ..() -/obj/item/clothing/head/helmet/space/hardsuit/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user) toggle_light(user) /obj/item/clothing/head/helmet/space/hardsuit/proc/toggle_light(mob/user) @@ -192,11 +192,11 @@ W.suit = src helmet = W -/obj/item/clothing/suit/space/hardsuit/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/suit/space/hardsuit/attack_self(mob/user) user.changeNext_move(CLICK_CD_MELEE) ..() -/obj/item/clothing/suit/space/hardsuit/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/item/clothing/suit/space/hardsuit/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/tank/jetpack/suit)) if(jetpack) to_chat(user, "[src] already has a jetpack installed.") @@ -205,7 +205,7 @@ to_chat(user, "You cannot install the upgrade to [src] while wearing it.") return - if(user.temperature_expose(I)) + if(user.unEquip(I)) I.forceMove(src) jetpack = I to_chat(user, "You successfully install the jetpack into [src].") @@ -280,7 +280,7 @@ linkedsuit = null return ..() -/obj/item/clothing/head/helmet/space/hardsuit/syndi/attack_self__legacy__attackchain(mob/user) //Toggle Helmet +/obj/item/clothing/head/helmet/space/hardsuit/syndi/attack_self(mob/user) //Toggle Helmet if(!isturf(user.loc)) to_chat(user, "You cannot toggle your helmet while in this [user.loc]!" ) return diff --git a/code/modules/clothing/spacesuits/misc_spacesuits.dm b/code/modules/clothing/spacesuits/misc_spacesuits.dm index c918e52c86321..c07d9b4729116 100644 --- a/code/modules/clothing/spacesuits/misc_spacesuits.dm +++ b/code/modules/clothing/spacesuits/misc_spacesuits.dm @@ -124,7 +124,7 @@ flags_cover = HEADCOVERSEYES dog_fashion = /datum/dog_fashion/head/santa -/obj/item/clothing/head/helmet/space/santahat/attack_self__legacy__attackchain(mob/user as mob) +/obj/item/clothing/head/helmet/space/santahat/attack_self(mob/user as mob) if(src.icon_state == "santahat") src.icon_state = "santahat_beard" src.item_state = "santahat_beard" diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 903cefa868cc6..26b09df981fa2 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -66,7 +66,7 @@ if(!up) . += visor_icon -/obj/item/clothing/head/helmet/space/plasmaman/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/head/helmet/space/plasmaman/attack_self(mob/user) toggle_light(user) /obj/item/clothing/head/helmet/space/plasmaman/proc/toggle_light(mob/user, update_light) @@ -308,7 +308,7 @@ /obj/item/clothing/head/helmet/space/plasmaman/tacticool/examine(mob/user) . = ..() if(!reskinned) - . += "You can Alt-Click to reskin it when held." + . += "You can Alt-Click to reskin it." /obj/item/clothing/head/helmet/space/plasmaman/tacticool/AltClick(mob/user) ..() @@ -359,9 +359,3 @@ if(!H.is_in_hands(src) || HAS_TRAIT(H, TRAIT_HANDS_BLOCKED)) return FALSE return TRUE - -/obj/item/clothing/head/helmet/space/plasmaman/trainer - name = "\improper NT Career Trainer envirosuit helmet" - desc = "A plasmaman envirohelm designed for the nanotrasen career trainer." - icon_state = "trainer_envirohelm" - item_state = "trainer_envirohelm" diff --git a/code/modules/clothing/suits/armor_suits.dm b/code/modules/clothing/suits/armor_suits.dm index 3ddf3ec98aee0..1d948533fc150 100644 --- a/code/modules/clothing/suits/armor_suits.dm +++ b/code/modules/clothing/suits/armor_suits.dm @@ -52,9 +52,9 @@ item_state = "armor" var/obj/item/clothing/accessory/holobadge/attached_badge -/obj/item/clothing/suit/armor/vest/security/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/item/clothing/suit/armor/vest/security/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/clothing/accessory/holobadge)) - if(user.drop_item_to_ground(I)) + if(user.unEquip(I)) add_fingerprint(user) I.forceMove(src) attached_badge = I @@ -67,7 +67,7 @@ return ..() -/obj/item/clothing/suit/armor/vest/security/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/suit/armor/vest/security/attack_self(mob/user) if(attached_badge) add_fingerprint(user) user.put_in_hands(attached_badge) @@ -418,7 +418,7 @@ /obj/item/clothing/suit/armor/reactive/Initialize(mapload, ...) . = ..() cell = new(src) - AddElement(/datum/element/high_value_item) + RegisterSignal(src, COMSIG_PARENT_QDELETING, PROC_REF(alert_admins_on_destroy)) /obj/item/clothing/suit/armor/reactive/Destroy() QDEL_NULL(cell) @@ -437,7 +437,7 @@ . += "Outside of the strange effects caused by the anomaly core, the armor provides no protection against conventional attacks. \ Nanotrasen cannot be held liable for injury and/or death due to misuse or proper operation of the reactive armor." -/obj/item/clothing/suit/armor/reactive/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/suit/armor/reactive/attack_self(mob/user) active = !(active) if(disabled) to_chat(user, "[src] is disabled and rebooting!") @@ -683,15 +683,15 @@ disable(rand(2, 5)) return TRUE -/obj/effect/spawner/reactive_armor +/// Spawner for random reactive armor +/obj/item/clothing/suit/armor/reactive/random name = "Random Reactive Armor" - icon = 'icons/obj/clothing/suits.dmi' - icon_state = "reactiveoff" -/obj/effect/spawner/reactive_armor/Initialize(mapload) +/obj/item/clothing/suit/armor/reactive/random/Initialize(mapload) . = ..() - var/spawnpath = pick(subtypesof(/obj/item/clothing/suit/armor/reactive)) + var/spawnpath = pick(subtypesof(/obj/item/clothing/suit/armor/reactive) - /obj/item/clothing/suit/armor/reactive/random) new spawnpath(loc) + UnregisterSignal(src, COMSIG_PARENT_QDELETING) return INITIALIZE_HINT_QDEL //All of the armor below is mostly unused diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm index 00c425859097f..723bee03e3249 100644 --- a/code/modules/clothing/suits/bio.dm +++ b/code/modules/clothing/suits/bio.dm @@ -76,7 +76,6 @@ /obj/item/clothing/suit/bio_suit/security armor = list(MELEE = 15, BULLET = 10, LASER = 15, ENERGY = 5, BOMB = 15, RAD = 200, FIRE = 20, ACID = INFINITY) icon_state = "bio_security" - slowdown = 0.45 //Same as Sec MODsuit //Janitor's biosuit, grey with purple diff --git a/code/modules/clothing/suits/hood.dm b/code/modules/clothing/suits/hood.dm index 0647bd233e6d8..660911e7fe0a0 100644 --- a/code/modules/clothing/suits/hood.dm +++ b/code/modules/clothing/suits/hood.dm @@ -44,10 +44,9 @@ suit_adjusted = 0 if(ishuman(hood.loc)) var/mob/living/carbon/H = hood.loc - H.transfer_item_to(hood, src, force = TRUE) + H.unEquip(hood, 1) H.update_inv_wear_suit() - else - hood.forceMove(src) + hood.forceMove(src) for(var/X in actions) var/datum/action/A = X A.UpdateButtons() diff --git a/code/modules/clothing/suits/job_suits.dm b/code/modules/clothing/suits/job_suits.dm index 5fd8bd0a31bbb..f67574bf124b0 100644 --- a/code/modules/clothing/suits/job_suits.dm +++ b/code/modules/clothing/suits/job_suits.dm @@ -29,6 +29,13 @@ "Vox" = 'icons/mob/clothing/species/vox/suit.dmi' ) +/obj/item/clothing/suit/mantle/armor/captain + name = "captain's mantle" + desc = "An armor-plated piece of fashion for the ruling elite. Protect your upper half in style." + icon_state = "capmantle" + item_state = "capmantle" + armor = list(MELEE = 50, BULLET = 35, LASER = 50, ENERGY = 5, BOMB = 15, RAD = 0, FIRE = 50, ACID = 50) + //Chaplain /obj/item/clothing/suit/hooded/chaplain_hoodie name = "chaplain hoodie" @@ -108,6 +115,21 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO allowed = list(/obj/item/kitchen/knife) +//Chief Engineer +/obj/item/clothing/suit/mantle/chief_engineer + name = "chief engineer's mantle" + desc = "A slick, authoritative cloak designed for the Chief Engineer." + icon_state = "cemantle" + item_state = "cemantle" + allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/t_scanner, /obj/item/rcd, /obj/item/rpd) + +//Chief Medical Officer +/obj/item/clothing/suit/mantle/labcoat/chief_medical_officer + name = "chief medical officer's mantle" + desc = "An absorbent, clean cover found on the shoulders of the Chief Medical Officer." + icon_state = "cmomantle" + item_state = "cmomantle" + //Detective /obj/item/clothing/suit/storage/det_suit name = "coat" @@ -195,19 +217,19 @@ name = "staff hazard vest" desc = "A high-visibilty vest used in work zones. Designed to easily identify station staff from visitors." icon_state = "hazard_staff" - allowed = list(/obj/item/flashlight, /obj/item/t_scanner, /obj/item/tank/internals/emergency_oxygen, /obj/item/paper, /obj/item/clipboard, /obj/item/analyzer, /obj/item/screwdriver, /obj/item/radio, /obj/item/wrench, /obj/item/weldingtool, /obj/item/crowbar, /obj/item/wirecutters, /obj/item/rcd, /obj/item/rpd, /obj/item/rcs, /obj/item/dest_tagger) + allowed = list(/obj/item/flashlight, /obj/item/t_scanner, /obj/item/tank/internals/emergency_oxygen, /obj/item/paper, /obj/item/clipboard, /obj/item/analyzer, /obj/item/screwdriver, /obj/item/radio, /obj/item/wrench, /obj/item/weldingtool, /obj/item/crowbar, /obj/item/wirecutters, /obj/item/rcd, /obj/item/rpd, /obj/item/rcs, /obj/item/destTagger) /obj/item/clothing/suit/storage/hazardvest/qm name = "warehouse supervisor hazard vest" desc = "A high-visibilty vest used in work zones. Designed to easily identify the supply supervisor." icon_state = "hazard_qm" - allowed = list(/obj/item/flashlight, /obj/item/t_scanner, /obj/item/tank/internals/emergency_oxygen, /obj/item/paper, /obj/item/clipboard, /obj/item/analyzer, /obj/item/screwdriver, /obj/item/radio, /obj/item/wrench, /obj/item/weldingtool, /obj/item/crowbar, /obj/item/wirecutters, /obj/item/rcs, /obj/item/dest_tagger, /obj/item/melee/baton, /obj/item/flashlight/seclite, /obj/item/melee/classic_baton/telescopic, /obj/item/melee/knuckleduster) + allowed = list(/obj/item/flashlight, /obj/item/t_scanner, /obj/item/tank/internals/emergency_oxygen, /obj/item/paper, /obj/item/clipboard, /obj/item/analyzer, /obj/item/screwdriver, /obj/item/radio, /obj/item/wrench, /obj/item/weldingtool, /obj/item/crowbar, /obj/item/wirecutters, /obj/item/rcs, /obj/item/destTagger, /obj/item/melee/baton, /obj/item/flashlight/seclite, /obj/item/melee/classic_baton/telescopic, /obj/item/melee/knuckleduster) /obj/item/clothing/suit/storage/hazardvest/ce name = "foreman hazard vest" desc = "A high-visibility vest used in work zones. Designed to easily identify the engineering supervisor." icon_state = "hazard_ce" - allowed = list(/obj/item/flashlight, /obj/item/t_scanner, /obj/item/tank/internals/emergency_oxygen, /obj/item/paper, /obj/item/clipboard, /obj/item/analyzer, /obj/item/screwdriver, /obj/item/radio, /obj/item/wrench, /obj/item/weldingtool, /obj/item/crowbar, /obj/item/wirecutters, /obj/item/rcd, /obj/item/rpd, /obj/item/dest_tagger, /obj/item/melee/baton, /obj/item/flashlight/seclite, /obj/item/melee/classic_baton/telescopic) + allowed = list(/obj/item/flashlight, /obj/item/t_scanner, /obj/item/tank/internals/emergency_oxygen, /obj/item/paper, /obj/item/clipboard, /obj/item/analyzer, /obj/item/screwdriver, /obj/item/radio, /obj/item/wrench, /obj/item/weldingtool, /obj/item/crowbar, /obj/item/wirecutters, /obj/item/rcd, /obj/item/rpd, /obj/item/destTagger, /obj/item/melee/baton, /obj/item/flashlight/seclite, /obj/item/melee/classic_baton/telescopic) //Internal Affairs /obj/item/clothing/suit/storage/iaa @@ -244,7 +266,29 @@ icon_state = "suitjacket_purple" item_state = "suitjacket_purple" +//Head of Security +/obj/item/clothing/suit/mantle/armor + name = "armored shawl" + desc = "A reinforced shawl, worn by the Head of Security. Do you dare take up their mantle?" + icon_state = "hosmantle" + item_state = "hosmantle" + allowed = list(/obj/item/gun/energy, /obj/item/reagent_containers/spray/pepper, /obj/item/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/flashlight/seclite, /obj/item/melee/classic_baton/telescopic, /obj/item/kitchen/knife/combat) + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 5, BOMB = 15, RAD = 0, FIRE = 50, ACID = 50) + min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT + heat_protection = UPPER_TORSO|ARMS + max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT + strip_delay = 60 + put_on_delay = 40 + resistance_flags = NONE + //Head of Personnel +/obj/item/clothing/suit/mantle/armor/hop + name = "head of personnel's shawl" + desc = "An armored shawl for the head of personnel. It's remarkably well kept." + icon_state = "hopmantle" + item_state = "hopmantle" + armor = list(MELEE = 15, BULLET = 10, LASER = 15, ENERGY = 5, BOMB = 15, RAD = 0, FIRE = 50, ACID = 50) + /obj/item/clothing/suit/hopcoat name = "head of personnel's coat" desc = "A big coat for the Head of Personnel who wants to make a fashion statement. Has armour woven within the fabric." @@ -260,6 +304,14 @@ ) //Quartermaster +/obj/item/clothing/suit/mantle/qm + name = "quartermaster's mantle" + desc = "An armored shawl for the quartermaster. Keeps the breeze from the vents away from your neck." + icon_state = "qmmantle" + item_state = "qmmantle" + allowed = list(/obj/item/paper, /obj/item/clipboard, /obj/item/gun/energy/kinetic_accelerator, /obj/item/melee/baton, /obj/item/flashlight/seclite, /obj/item/melee/classic_baton/telescopic, /obj/item/melee/knuckleduster, /obj/item/rcs) + armor = list(MELEE = 15, BULLET = 10, LASER = 15, ENERGY = 5, BOMB = 15, RAD = 0, FIRE = 50, ACID = 50) + /obj/item/clothing/suit/qmcoat name = "quartermaster's coat" desc = "A brown trenchcoat to show the station you mean business. Has armor woven within the fabric." @@ -350,18 +402,11 @@ item_state = "surgical" allowed = list(/obj/item/scalpel, /obj/item/surgical_drapes, /obj/item/cautery, /obj/item/hemostat, /obj/item/retractor) -//NT Career Trainer -/obj/item/clothing/suit/storage/nct - name = "\improper NT Career Trainer's jacket" - desc = "A sharp black coat with beige trim around the cuffs and collar, offering a mix of professionalism and approachability." - icon_state = "trainercoat" - blood_overlay_type = "coat" - body_parts_covered = UPPER_TORSO|ARMS - ignore_suitadjust = TRUE - - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/suit.dmi', - "Kidan" = 'icons/mob/clothing/species/kidan/suit.dmi', - "Drask" = 'icons/mob/clothing/species/drask/suit.dmi', - "Grey" = 'icons/mob/clothing/species/grey/suit.dmi', - ) +//Research Director +/obj/item/clothing/suit/mantle/labcoat + name = "research director's mantle" + desc = "A tweed mantle, worn by the Research Director. Smells like science." + icon_state = "rdmantle" + item_state = "rdmantle" + 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/reagent_containers/applicator, /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) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50) diff --git a/code/modules/clothing/suits/misc_suits.dm b/code/modules/clothing/suits/misc_suits.dm index 2aa30cefbea00..abbbffac73fe7 100644 --- a/code/modules/clothing/suits/misc_suits.dm +++ b/code/modules/clothing/suits/misc_suits.dm @@ -388,10 +388,8 @@ min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 0, ACID = 0) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/suit.dmi', - "Vox" = 'icons/mob/clothing/species/vox/suit.dmi' - ) + + sprite_sheets = list("Vox" = 'icons/mob/clothing/species/vox/suit.dmi') /obj/item/clothing/head/hooded/winterhood name = "winter hood" @@ -402,10 +400,8 @@ min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT flags = BLOCKHAIR flags_inv = HIDEEARS - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/head.dmi', - "Vox" = 'icons/mob/clothing/species/vox/head.dmi' - ) + + sprite_sheets = list("Vox" = 'icons/mob/clothing/species/vox/head.dmi') /obj/item/clothing/suit/pimpcoat name = "expensive coat" @@ -457,17 +453,9 @@ armor = list(MELEE = 15, BULLET = 20, LASER = 20, ENERGY = 5, BOMB = 15, RAD = 0, FIRE = 0, ACID = 50) allowed = list(/obj/item/gun/energy, /obj/item/reagent_containers/spray/pepper, /obj/item/gun/projectile, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/flashlight/seclite, /obj/item/melee/classic_baton/telescopic) hoodtype = /obj/item/clothing/head/hooded/winterhood/captain - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/suit.dmi', - "Vox" = 'icons/mob/clothing/species/vox/suit.dmi' - ) /obj/item/clothing/head/hooded/winterhood/captain icon_state = "winterhood_captain" - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/head.dmi', - "Vox" = 'icons/mob/clothing/species/vox/head.dmi' - ) /obj/item/clothing/suit/hooded/wintercoat/security name = "security winter coat" @@ -499,17 +487,9 @@ allowed = list(/obj/item/analyzer, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/reagent_containers/applicator,/obj/item/healthanalyzer,/obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic) armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 0, ACID = 40) hoodtype = /obj/item/clothing/head/hooded/winterhood/medical - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/suit.dmi', - "Vox" = 'icons/mob/clothing/species/vox/suit.dmi' - ) /obj/item/clothing/head/hooded/winterhood/medical icon_state = "winterhood_med" - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/head.dmi', - "Vox" = 'icons/mob/clothing/species/vox/head.dmi' - ) /obj/item/clothing/suit/hooded/wintercoat/science name = "science winter coat" @@ -519,17 +499,9 @@ 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/reagent_containers/applicator,/obj/item/healthanalyzer,/obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic) armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 5, RAD = 0, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/science - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/suit.dmi', - "Vox" = 'icons/mob/clothing/species/vox/suit.dmi' - ) /obj/item/clothing/head/hooded/winterhood/science icon_state = "winterhood_sci" - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/head.dmi', - "Vox" = 'icons/mob/clothing/species/vox/head.dmi' - ) /obj/item/clothing/suit/hooded/wintercoat/engineering name = "engineering winter coat" @@ -539,34 +511,18 @@ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 10, FIRE = 20, ACID = 40) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/t_scanner, /obj/item/rcd, /obj/item/rpd) hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/suit.dmi', - "Vox" = 'icons/mob/clothing/species/vox/suit.dmi' - ) /obj/item/clothing/head/hooded/winterhood/engineering icon_state = "winterhood_engi" - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/head.dmi', - "Vox" = 'icons/mob/clothing/species/vox/head.dmi' - ) /obj/item/clothing/suit/hooded/wintercoat/engineering/atmos name = "atmospherics winter coat" icon_state = "wintercoat_atmos" item_state = "coatatmos" hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering/atmos - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/suit.dmi', - "Vox" = 'icons/mob/clothing/species/vox/suit.dmi' - ) /obj/item/clothing/head/hooded/winterhood/engineering/atmos icon_state = "winterhood_atmos" - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/head.dmi', - "Vox" = 'icons/mob/clothing/species/vox/head.dmi' - ) /obj/item/clothing/suit/hooded/wintercoat/hydro name = "hydroponics winter coat" @@ -574,17 +530,9 @@ item_state = "coathydro" allowed = list(/obj/item/reagent_containers/spray, /obj/item/plant_analyzer, /obj/item/seeds, /obj/item/reagent_containers/glass/bottle, /obj/item/hatchet, /obj/item/storage/bag/plants) hoodtype = /obj/item/clothing/head/hooded/winterhood/hydro - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/suit.dmi', - "Vox" = 'icons/mob/clothing/species/vox/suit.dmi' - ) /obj/item/clothing/head/hooded/winterhood/hydro icon_state = "winterhood_hydro" - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/head.dmi', - "Vox" = 'icons/mob/clothing/species/vox/head.dmi' - ) /obj/item/clothing/suit/hooded/wintercoat/cargo name = "cargo winter coat" @@ -592,17 +540,9 @@ item_state = "coatcargo" allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/rcs, /obj/item/clipboard, /obj/item/envelope, /obj/item/storage/bag/mail, /obj/item/mail_scanner) hoodtype = /obj/item/clothing/head/hooded/winterhood/cargo - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/suit.dmi', - "Vox" = 'icons/mob/clothing/species/vox/suit.dmi' - ) /obj/item/clothing/head/hooded/winterhood/cargo icon_state = "winterhood_cargo" - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/head.dmi', - "Vox" = 'icons/mob/clothing/species/vox/head.dmi' - ) /obj/item/clothing/suit/hooded/wintercoat/miner name = "mining winter coat" @@ -612,17 +552,9 @@ allowed = list(/obj/item/pickaxe, /obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/t_scanner/adv_mining_scanner, /obj/item/storage/bag/ore, /obj/item/gun/energy/kinetic_accelerator) armor = list(MELEE = 5, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/miner - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/suit.dmi', - "Vox" = 'icons/mob/clothing/species/vox/suit.dmi' - ) /obj/item/clothing/head/hooded/winterhood/miner icon_state = "winterhood_miner" - sprite_sheets = list( - "Grey" = 'icons/mob/clothing/species/grey/head.dmi', - "Vox" = 'icons/mob/clothing/species/vox/head.dmi' - ) /obj/item/clothing/head/hooded/ablative name = "ablative hood" @@ -894,7 +826,7 @@ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES //Basic jacket and subtypes -/obj/item/clothing/suit/sec_greatcoat +/obj/item/clothing/suit/greatcoat/sec name = "security greatcoat" desc = "A wool-lined coat made from rugged materials that altogether make up to be a comfortable coat.\ GLORY TO ARSTOSKHA!!" icon_state = "secgreatcoat" @@ -1205,7 +1137,7 @@ icon_state = "griffin_wings" item_state = "griffin_wings" -/obj/item/clothing/suit/toggle/attack_self__legacy__attackchain() +/obj/item/clothing/suit/toggle/attack_self() if(icon_state == initial(icon_state)) icon_state = icon_state + "_t" item_state = icon_state + "_t" @@ -1355,6 +1287,28 @@ icon_state = "ladiesredvictoriancoat" item_state = "ladiesredvictoriancoat" +//Mantles! +/obj/item/clothing/suit/mantle + name = "mantle" + desc = "A heavy quilted mantle, for keeping your shoulders warm and stylish." + icon_state = "mantle" + item_state = "mantle" + body_parts_covered = UPPER_TORSO|ARMS + cold_protection = UPPER_TORSO|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + +/obj/item/clothing/suit/mantle/regal + name = "regal shawl" + desc = "A fancy shawl for nobility, made from high quality materials." + icon_state = "regal_mantle" + item_state = "regal_mantle" + +/obj/item/clothing/suit/mantle/old + name = "old wrap" + desc = "A tattered fabric wrap, faded over the years. Smells faintly of cigars." + icon_state = "old_mantle" + item_state = "old_mantle" + /obj/item/clothing/suit/ghost_sheet name = "ghost sheet" desc = "The hands float by themselves, so it's extra spooky." @@ -1367,11 +1321,15 @@ flags = BLOCKHAIR flags_inv = HIDEGLOVES|HIDEEARS|HIDEFACE -/obj/item/clothing/neck/cloak/furcape +/obj/item/clothing/suit/furcape name = "fur cape" desc = "A cape made from fur. You'll really be stylin' now." icon_state = "furcape" item_state = "furcape" + blood_overlay_type = "armor" + body_parts_covered = UPPER_TORSO|ARMS + cold_protection = UPPER_TORSO | ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT /obj/item/clothing/suit/hooded/abaya name = "abaya" @@ -1408,12 +1366,12 @@ return var/abaya_type = options[choice] var/obj/item/clothing/suit/hooded/abaya/abaya = new abaya_type(get_turf(src)) - L.unequip(src) + L.unEquip(src, silent = TRUE) L.put_in_active_hand(abaya) to_chat(L, "You are now wearing \a [choice]. Allahu Akbar!") qdel(src) -/obj/item/clothing/suit/hooded/abaya/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/suit/hooded/abaya/attack_self(mob/user) . = ..() reskin_abaya(user) diff --git a/code/modules/clothing/suits/suit_storage.dm b/code/modules/clothing/suits/suit_storage.dm index 2e1839c32b760..b932d45d69331 100644 --- a/code/modules/clothing/suits/suit_storage.dm +++ b/code/modules/clothing/suits/suit_storage.dm @@ -44,9 +44,9 @@ pockets.show_to(user) return ..() -/obj/item/clothing/suit/storage/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) +/obj/item/clothing/suit/storage/attackby(obj/item/W as obj, mob/user as mob, params) ..() - return pockets?.attackby__legacy__attackchain(W, user, params) + return pockets?.attackby(W, user, params) /obj/item/clothing/suit/storage/emp_act(severity) ..() diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index 48848e28e2bb6..0e55e6ae647cb 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -12,8 +12,9 @@ if(ishuman(helmet.loc)) var/mob/living/carbon/H = helmet.loc if(helmet.on) - helmet.attack_self__legacy__attackchain(H) - H.transfer_item_to(helmet, src, force = TRUE) + helmet.attack_self(H) + H.unEquip(helmet, TRUE) + helmet.forceMove(src) H.update_inv_wear_suit() to_chat(H, "The helmet on the hardsuit disengages.") playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1) diff --git a/code/modules/clothing/suits/unathi_suits.dm b/code/modules/clothing/suits/unathi_suits.dm index 73a04970873c3..4021f44043392 100644 --- a/code/modules/clothing/suits/unathi_suits.dm +++ b/code/modules/clothing/suits/unathi_suits.dm @@ -10,3 +10,10 @@ icon_state = "robe-unathi" item_state = "robe-unathi" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + +/obj/item/clothing/suit/unathi/mantle + name = "hide mantle" + desc = "A rather grisly selection of cured hides and skin, sewn together to form a ragged mantle." + icon_state = "mantle-unathi" + item_state = "mantle-unathi" + body_parts_covered = UPPER_TORSO diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index b647419b79e00..e5eff27c9b734 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -154,7 +154,7 @@ flags = THICKMATERIAL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/flashlight,/obj/item/tank/internals/emergency_oxygen, /obj/item/geiger_counter) - slowdown = 0.75 + slowdown = 1.5 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = INFINITY, FIRE = 20, ACID = 20) flags_inv = HIDEJUMPSUIT|HIDETAIL strip_delay = 60 diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index 7314f89849749..b99ea6d18af9c 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -200,17 +200,6 @@ /obj/item/clothing/suit/space/hardsuit/wizard/setup_shielding() AddComponent(/datum/component/shielded, max_charges = 15, recharge_start_delay = 0 SECONDS) -/obj/item/clothing/suit/space/hardsuit/wizard/equipped(mob/user, slot) - . = ..() - ADD_TRAIT(user, TRAIT_ANTIMAGIC, "[UID(src)]") - ADD_TRAIT(user, TRAIT_ANTIMAGIC_NO_SELFBLOCK, "[UID(src)]") - -/obj/item/clothing/suit/space/hardsuit/wizard/dropped(mob/user) - . = ..() - REMOVE_TRAIT(user, TRAIT_ANTIMAGIC, "[UID(src)]") - REMOVE_TRAIT(user, TRAIT_ANTIMAGIC_NO_SELFBLOCK, "[UID(src)]") - - /obj/item/clothing/suit/space/hardsuit/wizard/arch desc = "For the arch wizard in need of additional protection." min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT @@ -233,7 +222,7 @@ resistance_flags = FIRE_PROOF | ACID_PROOF magical = TRUE -/obj/item/clothing/head/helmet/space/hardsuit/wizard/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/head/helmet/space/hardsuit/wizard/attack_self(mob/user) return /obj/item/clothing/head/helmet/space/hardsuit/wizard/arch diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index ffeb70cda6d74..b1a6cf91d0403 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -1,23 +1,20 @@ /obj/item/clothing/accessory - name = "accessory" - desc = "If you see this contact a developer." - icon = 'icons/obj/clothing/accessories.dmi' - icon_state = "" - item_state = "" - item_color = "" + name = "tie" + desc = "A neosilk clip-on tie." + icon = 'icons/obj/clothing/ties.dmi' + icon_state = "bluetie" + item_state = "" //no inhands + item_color = "bluetie" slot_flags = ITEM_SLOT_ACCESSORY w_class = WEIGHT_CLASS_SMALL var/slot = ACCESSORY_SLOT_DECOR - /// the suit the accessory may be attached to - var/obj/item/clothing/under/has_suit = null - /// overlay used when attached to clothing. - var/image/inv_overlay = null - /// Allow accessories of the same type. - var/allow_duplicates = TRUE + var/obj/item/clothing/under/has_suit = null //the suit the tie may be attached to + var/image/inv_overlay = null //overlay used when attached to clothing. + var/allow_duplicates = TRUE // Allow accessories of the same type. /obj/item/clothing/accessory/Initialize(mapload) . = ..() - inv_overlay = image("icon" = 'icons/obj/clothing/accessories_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]") + inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]") /obj/item/clothing/accessory/Moved(atom/OldLoc, Dir, Forced) . = ..() @@ -75,7 +72,7 @@ user.put_in_hands(src) add_fingerprint(user) -/obj/item/clothing/accessory/attack__legacy__attackchain(mob/living/carbon/human/H, mob/living/user) +/obj/item/clothing/accessory/attack(mob/living/carbon/human/H, mob/living/user) // This code lets you put accessories on other people by attacking their sprite with the accessory if(istype(H) && !ismonkeybasic(H)) //Monkeys are a snowflake because you can't remove accessories once added if(H.wear_suit && H.wear_suit.flags_inv & HIDEJUMPSUIT) @@ -100,7 +97,7 @@ return //default attackby behaviour -/obj/item/clothing/accessory/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/item/clothing/accessory/attackby(obj/item/I, mob/user, params) ..() //default attack_hand behaviour @@ -115,6 +112,27 @@ /obj/item/clothing/accessory/proc/attached_equip(mob/user) // If we need to do something special when clothing is removed from the user return +/obj/item/clothing/accessory/blue + name = "blue tie" + icon_state = "bluetie" + item_color = "bluetie" + +/obj/item/clothing/accessory/red + name = "red tie" + icon_state = "redtie" + item_color = "redtie" + +/obj/item/clothing/accessory/black + name = "black tie" + icon_state = "blacktie" + item_color = "blacktie" + +/obj/item/clothing/accessory/horrible + name = "horrible tie" + desc = "A neosilk clip-on tie. This one is disgusting." + icon_state = "horribletie" + item_color = "horribletie" + /// No overlay /obj/item/clothing/accessory/waistcoat name = "waistcoat" @@ -127,6 +145,63 @@ "Vox" = 'icons/mob/clothing/species/vox/suit.dmi' ) +/obj/item/clothing/accessory/stethoscope + name = "stethoscope" + desc = "An outdated medical apparatus, used to get a rough idea of the condition of the heart and lungs. It also makes you look like you know what you're doing." + icon_state = "stethoscope" + item_color = "stethoscope" + +/obj/item/clothing/accessory/stethoscope/attack(mob/living/carbon/human/M, mob/living/user) + if(!ishuman(M) || !isliving(user)) + return ..(M, user) + + if(user == M) + user.visible_message("[user] places [src] against [user.p_their()] chest and listens attentively.", "You place [src] against your chest...") + else + user.visible_message("[user] places [src] against [M]'s chest and listens attentively.", "You place [src] against [M]'s chest...") + var/datum/organ/heart/heart_datum = M.get_int_organ_datum(ORGAN_DATUM_HEART) + var/datum/organ/lungs/lung_datum = M.get_int_organ_datum(ORGAN_DATUM_LUNGS) + if(!lung_datum || !heart_datum) + to_chat(user, "You don't hear anything.") + return + + var/obj/item/organ/internal/H = heart_datum.linked_organ + var/obj/item/organ/internal/L = lung_datum.linked_organ + if(!M.pulse || (!H || !(L && !HAS_TRAIT(M, TRAIT_NOBREATH)))) + to_chat(user, "You don't hear anything.") + return + + var/color = "notice" + if(H) + var/heart_sound + switch(H.damage) + if(0 to 1) + heart_sound = "healthy" + if(1 to 25) + heart_sound = "offbeat" + if(25 to 50) + heart_sound = "uneven" + color = "warning" + if(50 to INFINITY) + heart_sound = "weak, unhealthy" + color = "warning" + to_chat(user, "You hear \an [heart_sound] pulse.") + + if(L) + var/lung_sound + switch(L.damage) + if(0 to 1) + lung_sound = "healthy respiration" + if(1 to 25) + lung_sound = "labored respiration" + if(25 to 50) + lung_sound = "pained respiration" + color = "warning" + if(50 to INFINITY) + lung_sound = "gurgling" + color = "warning" + to_chat(user, "You hear [lung_sound].") + //Medals /obj/item/clothing/accessory/medal name = "bronze medal" @@ -145,7 +220,7 @@ if(channel) . += "The tiny radio inside seems to be [try_announce ? "active" : "inactive"]." -/obj/item/clothing/accessory/medal/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/accessory/medal/attack_self(mob/user) . = ..() if(channel) try_announce = !try_announce @@ -176,7 +251,7 @@ /obj/item/clothing/accessory/medal/gold/captain/Initialize(mapload) . = ..() - AddElement(/datum/element/high_value_item) + RegisterSignal(src, COMSIG_PARENT_QDELETING, PROC_REF(alert_admins_on_destroy)) /obj/item/clothing/accessory/medal/gold/heroism name = "medal of exceptional heroism" @@ -346,7 +421,7 @@ icon_state = "holobadge-cord" item_color = "holobadge-cord" -/obj/item/clothing/accessory/holobadge/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/accessory/holobadge/attack_self(mob/user) if(!stored_name) to_chat(user, "Waving around a badge before swiping an ID would be pretty pointless.") return @@ -354,7 +429,7 @@ user.visible_message("[user] displays [user.p_their()] Nanotrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.", "You display your Nanotrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.") -/obj/item/clothing/accessory/holobadge/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/item/clothing/accessory/holobadge/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda)) var/obj/item/card/id/id_card = null @@ -383,7 +458,7 @@ to_chat(user, "You swipe the card and crack the holobadge security checks.") return TRUE -/obj/item/clothing/accessory/holobadge/attack__legacy__attackchain(mob/living/carbon/human/H, mob/living/user) +/obj/item/clothing/accessory/holobadge/attack(mob/living/carbon/human/H, mob/living/user) if(H != user) user.visible_message("[user] invades [H]'s personal space, thrusting [src] into [H.p_their()] face insistently.", "You invade [H]'s personal space, thrusting [src] into [H.p_their()] face insistently. You are THE LAW!") @@ -403,12 +478,12 @@ var/cached_bubble_icon = null var/what_you_are = "THE LAW" -/obj/item/clothing/accessory/legal_badge/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/accessory/legal_badge/attack_self(mob/user) if(prob(1)) user.say("The testimony contradicts the evidence!") user.visible_message("[user] shows [user.p_their()] [name].", "You show your [name].") -/obj/item/clothing/accessory/legal_badge/attack__legacy__attackchain(mob/living/carbon/human/H, mob/living/user) +/obj/item/clothing/accessory/legal_badge/attack(mob/living/carbon/human/H, mob/living/user) if(H != user) user.visible_message("[user] invades [H]'s personal space, thrusting [src] into [H.p_their()] face insistently.", "You invade [H]'s personal space, thrusting [src] into [H.p_their()] face insistently. You are [what_you_are]!") @@ -433,7 +508,117 @@ desc = "Marks you as an expert of Standard Operating Procedure, and as a soul-crushing paper pusher." what_you_are = "HUMAN RESOURCES" -/obj/item/clothing/accessory/skullcodpiece +/////////// +//SCARVES// +/////////// + +/// No overlay +/obj/item/clothing/accessory/scarf + name = "scarf" + desc = "A stylish scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks." + dog_fashion = /datum/dog_fashion/head + +/obj/item/clothing/accessory/scarf/red + name = "red scarf" + icon_state = "redscarf" + item_color = "redscarf" + +/obj/item/clothing/accessory/scarf/green + name = "green scarf" + icon_state = "greenscarf" + item_color = "greenscarf" + +/obj/item/clothing/accessory/scarf/darkblue + name = "dark blue scarf" + icon_state = "darkbluescarf" + item_color = "darkbluescarf" + +/obj/item/clothing/accessory/scarf/purple + name = "purple scarf" + icon_state = "purplescarf" + item_color = "purplescarf" + +/obj/item/clothing/accessory/scarf/yellow + name = "yellow scarf" + icon_state = "yellowscarf" + item_color = "yellowscarf" + +/obj/item/clothing/accessory/scarf/orange + name = "orange scarf" + icon_state = "orangescarf" + item_color = "orangescarf" + +/obj/item/clothing/accessory/scarf/lightblue + name = "light blue scarf" + icon_state = "lightbluescarf" + item_color = "lightbluescarf" + +/obj/item/clothing/accessory/scarf/white + name = "white scarf" + icon_state = "whitescarf" + item_color = "whitescarf" + +/obj/item/clothing/accessory/scarf/black + name = "black scarf" + icon_state = "blackscarf" + item_color = "blackscarf" + +/obj/item/clothing/accessory/scarf/zebra + name = "zebra scarf" + icon_state = "zebrascarf" + item_color = "zebrascarf" + +/obj/item/clothing/accessory/scarf/christmas + name = "christmas scarf" + icon_state = "christmasscarf" + item_color = "christmasscarf" + +//The three following scarves don't have the scarf subtype +//This is because Ian can equip anything from that subtype +//However, these 3 don't have corgi versions of their sprites +/obj/item/clothing/accessory/stripedredscarf + name = "striped red scarf" + desc = "A stylish scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks." + icon_state = "stripedredscarf" + item_color = "stripedredscarf" + +/obj/item/clothing/accessory/stripedgreenscarf + name = "striped green scarf" + desc = "A stylish scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks." + icon_state = "stripedgreenscarf" + item_color = "stripedgreenscarf" + +/obj/item/clothing/accessory/stripedbluescarf + name = "striped blue scarf" + desc = "A stylish scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks." + icon_state = "stripedbluescarf" + item_color = "stripedbluescarf" + +//Necklaces +/obj/item/clothing/accessory/necklace + name = "necklace" + desc = "A simple necklace." + icon_state = "necklace" + item_state = "necklace" + item_color = "necklace" + slot_flags = ITEM_SLOT_ACCESSORY + +/obj/item/clothing/accessory/necklace/long + name = "large necklace" + desc = "A large necklace." + icon_state = "necklacelong" + item_state = "necklacelong" + item_color = "necklacelong" + + +/obj/item/clothing/accessory/necklace/dope + name = "gold necklace" + desc = "Damn, it feels good to be a gangster." + icon_state = "bling" + item_state = "bling" + item_color = "bling" + +/obj/item/clothing/accessory/necklace/skullcodpiece name = "skull codpiece" desc = "A skull shaped ornament, intended to protect the important things in life." icon_state = "skull" @@ -442,7 +627,7 @@ armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 5, BOMB = 10, RAD = 5, FIRE = 0, ACID = 15) allow_duplicates = FALSE -/obj/item/clothing/accessory/talisman +/obj/item/clothing/accessory/necklace/talisman name = "bone talisman" desc = "A hunter's talisman, some say the old gods smile on those who wear it." icon_state = "talisman" @@ -451,6 +636,64 @@ armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 5, BOMB = 10, RAD = 5, FIRE = 0, ACID = 15) allow_duplicates = FALSE +/obj/item/clothing/accessory/necklace/locket + name = "gold locket" + desc = "A gold locket that seems to have space for a photo within." + icon_state = "locketgold" + item_state = "locketgold" + item_color = "locketgold" + slot_flags = ITEM_SLOT_ACCESSORY + var/base_icon + var/open + var/obj/item/held //Item inside locket. + +/obj/item/clothing/accessory/necklace/locket/Destroy() + QDEL_NULL(held) + return ..() + + +/obj/item/clothing/accessory/necklace/locket/attack_self(mob/user as mob) + if(!base_icon) + base_icon = icon_state + + if(!("[base_icon]_open" in icon_states(icon))) + to_chat(user, "[src] doesn't seem to open.") + return + + open = !open + to_chat(user, "You flip [src] [open?"open":"closed"].") + if(open) + icon_state = "[base_icon]_open" + if(held) + to_chat(user, "[held] falls out!") + held.forceMove(get_turf(user)) + held = null + else + icon_state = "[base_icon]" + +/obj/item/clothing/accessory/necklace/locket/attackby(obj/item/O as obj, mob/user as mob) + if(!open) + to_chat(user, "You have to open it first.") + return + + if(istype(O,/obj/item/paper) || istype(O, /obj/item/photo)) + if(held) + to_chat(usr, "[src] already has something inside it.") + else + to_chat(usr, "You slip [O] into [src].") + user.drop_item() + O.forceMove(src) + held = O + else + return ..() + +/obj/item/clothing/accessory/necklace/locket/silver + name = "silver locket" + desc = "A silver locket that seems to have space for a photo within." + icon_state = "locketsilver" + item_state = "locketsilver" + item_color = "locketsilver" + //Cowboy Shirts /obj/item/clothing/accessory/cowboyshirt name = "black cowboy shirt" @@ -622,7 +865,7 @@ var/image/pin_icon = image(icon, icon_state = flag_types[current_pin]) flag_icons[current_pin] = pin_icon -/obj/item/clothing/accessory/pin/pride/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/accessory/pin/pride/attack_self(mob/user) . = ..() var/chosen_pin = show_radial_menu(user, src, flag_icons, require_near = TRUE) if(!chosen_pin) @@ -634,7 +877,7 @@ icon_state = pin_icon_state item_state = pin_icon_state item_color = pin_icon_state - inv_overlay = image("icon" = 'icons/obj/clothing/accessories_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]") + inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]") /proc/english_accessory_list(obj/item/clothing/under/U) if(!istype(U) || !length(U.accessories)) diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm index 2307688228b46..cde430b1edc97 100644 --- a/code/modules/clothing/under/accessories/holster.dm +++ b/code/modules/clothing/under/accessories/holster.dm @@ -24,7 +24,7 @@ else return TRUE -/obj/item/clothing/accessory/holster/attack_self__legacy__attackchain() +/obj/item/clothing/accessory/holster/attack_self() var/holsteritem = usr.get_active_hand() if(!holstered) holster(holsteritem, usr) @@ -50,8 +50,8 @@ return holstered = W - user.unequip(holstered) - holstered.forceMove(src) + user.unEquip(holstered) + holstered.loc = src holstered.add_fingerprint(user) user.visible_message("[user] holsters [holstered].", "You holster [holstered].") @@ -80,7 +80,7 @@ ..(user) -/obj/item/clothing/accessory/holster/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) +/obj/item/clothing/accessory/holster/attackby(obj/item/W as obj, mob/user as mob, params) holster(W, user) /obj/item/clothing/accessory/holster/emp_act(severity) diff --git a/code/modules/clothing/under/accessories/storage_accessories.dm b/code/modules/clothing/under/accessories/storage_accessories.dm index aa8e75f392e79..d295056c5b8ba 100644 --- a/code/modules/clothing/under/accessories/storage_accessories.dm +++ b/code/modules/clothing/under/accessories/storage_accessories.dm @@ -33,8 +33,8 @@ if(hold.handle_mousedrop(usr, over_object)) ..(over_object) -/obj/item/clothing/accessory/storage/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) - return hold.attackby__legacy__attackchain(W, user, params) +/obj/item/clothing/accessory/storage/attackby(obj/item/W as obj, mob/user as mob, params) + return hold.attackby(W, user, params) /obj/item/clothing/accessory/storage/emp_act(severity) ..() @@ -62,7 +62,7 @@ L += G.gift:return_inv() return L -/obj/item/clothing/accessory/storage/attack_self__legacy__attackchain(mob/user as mob) +/obj/item/clothing/accessory/storage/attack_self(mob/user as mob) if(has_suit) //if we are part of a suit hold.open(user) else diff --git a/code/modules/clothing/under/jobs/plasmamen/_plasmamen.dm b/code/modules/clothing/under/jobs/plasmamen/_plasmamen.dm index 57126c15280d7..1669a3afcbcee 100644 --- a/code/modules/clothing/under/jobs/plasmamen/_plasmamen.dm +++ b/code/modules/clothing/under/jobs/plasmamen/_plasmamen.dm @@ -39,7 +39,7 @@ new /obj/effect/particle_effect/water(get_turf(H)) return FALSE -/obj/item/clothing/under/plasmaman/attackby__legacy__attackchain(obj/item/E, mob/user, params) +/obj/item/clothing/under/plasmaman/attackby(obj/item/E, mob/user, params) if(istype(E, /obj/item/extinguisher_refill)) if(extinguishes_left == 5) to_chat(user, "The inbuilt extinguisher is full.") diff --git a/code/modules/clothing/under/jobs/plasmamen/civilian_service.dm b/code/modules/clothing/under/jobs/plasmamen/civilian_service.dm index b7fa92dcbcc9e..a11e17175869f 100644 --- a/code/modules/clothing/under/jobs/plasmamen/civilian_service.dm +++ b/code/modules/clothing/under/jobs/plasmamen/civilian_service.dm @@ -134,10 +134,3 @@ item_state = "tacticool_envirosuit" item_color = "tacticool_envirosuit" has_sensor = FALSE - -/obj/item/clothing/under/plasmaman/trainer - name = "\improper NT career trainer's envirosuit" - desc = "An envirosuit designed for plasmamen employed as the nanotrasen career trainer." - icon_state = "trainer_envirosuit" - item_state = "trainer_envirosuit" - item_color = "trainer_envirosuit" diff --git a/code/modules/clothing/under/jobs/procedure.dm b/code/modules/clothing/under/jobs/procedure.dm index 7351e2a245b74..33a997dc21866 100644 --- a/code/modules/clothing/under/jobs/procedure.dm +++ b/code/modules/clothing/under/jobs/procedure.dm @@ -159,17 +159,3 @@ icon_state = "iaa_formal_goodman_skirt" item_state = "iaa_formal_goodman_skirt" item_color = "iaa_formal_goodman_skirt" - -/obj/item/clothing/under/rank/procedure/nct - name = "\improper NT Career Trainer's uniform" - desc = "A neatly pressed olive green shirt paired with black jeans, worn by those dedicated to shaping the future of the workforce." - icon_state = "trainer" - item_state = "trainer" - item_color = "trainer" - -/obj/item/clothing/under/rank/procedure/nct/skirt - name = "\improper NT Career Trainer's skirt" - desc = "A neatly pressed olive green shirt paired with a sleek black skirt, worn by those committed to mentoring the next generation." - icon_state = "trainer_skirt" - item_state = "trainer_skirt" - item_color = "trainer_skirt" diff --git a/code/modules/clothing/under/misc_jumpsuits.dm b/code/modules/clothing/under/misc_jumpsuits.dm index 5d49a6258f654..680d3915fa526 100644 --- a/code/modules/clothing/under/misc_jumpsuits.dm +++ b/code/modules/clothing/under/misc_jumpsuits.dm @@ -58,7 +58,7 @@ item_state = "gy_suit" item_color = "vice" -/obj/item/clothing/under/misc/gimmick_captain_suit +/obj/item/clothing/under/misc/gimmick/rank/captain/suit name = "captain's suit" desc = "A green suit and yellow necktie. Exemplifies authority." icon_state = "green_suit" diff --git a/code/modules/crafting/guncrafting.dm b/code/modules/crafting/guncrafting.dm index 14aa4c539ff2f..d486b616db8ea 100644 --- a/code/modules/crafting/guncrafting.dm +++ b/code/modules/crafting/guncrafting.dm @@ -120,7 +120,7 @@ name = "sol gov universal self assembling gun parts kit" icon_state = "solcase" //Ikea reference pending. -/obj/item/weaponcrafting/gunkit/universal_gun_kit/afterattack__legacy__attackchain(obj/item/weaponcrafting/gunkit/gunkit_to_use, mob/user, flag) +/obj/item/weaponcrafting/gunkit/universal_gun_kit/afterattack(obj/item/weaponcrafting/gunkit/gunkit_to_use, mob/user, flag) if(!istype(gunkit_to_use)) return if(!gunkit_to_use.outcome) @@ -134,23 +134,23 @@ if(istype(gunkit_to_use, /obj/item/weaponcrafting/gunkit/sparker)) //Snowflake checking, but I don't want a person with a self assembling kit to be robbed var/obj/item/gun_produceda = new gunkit_to_use.outcome var/obj/item/gun_producedb = new gunkit_to_use.outcome - user.unequip(src) + user.unEquip(src) user.put_in_hands(gun_produceda) user.put_in_hands(gun_producedb) else var/obj/item/gun_produced = new gunkit_to_use.outcome - user.unequip(src) + user.unEquip(src) user.put_in_hands(gun_produced) qdel(gunkit_to_use) qdel(src) // CRAFTING // -/obj/item/weaponcrafting/receiver/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) +/obj/item/weaponcrafting/receiver/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W,/obj/item/pipe)) to_chat(user, "You attach the shotgun barrel to the receiver. The pins seem loose.") var/obj/item/weaponcrafting/ishotgunconstruction/I = new /obj/item/weaponcrafting/ishotgunconstruction - user.unequip(src) + user.unEquip(src) user.put_in_hands(I) qdel(W) qdel(src) @@ -166,7 +166,7 @@ /obj/item/weaponcrafting/ishotgunconstruction/screwdriver_act(mob/living/user, obj/item/I) var/obj/item/weaponcrafting/ishotgunconstruction2/C = new /obj/item/weaponcrafting/ishotgunconstruction2 - user.unequip(src) + user.unEquip(src) user.put_in_hands(C) to_chat(user, "You screw the pins into place, securing the pipe to the receiver.") qdel(src) @@ -178,11 +178,11 @@ icon = 'icons/obj/improvised.dmi' icon_state = "ishotgunstep1" -/obj/item/weaponcrafting/ishotgunconstruction2/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) +/obj/item/weaponcrafting/ishotgunconstruction2/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weaponcrafting/stock)) to_chat(user, "You attach the stock to the receiver-barrel assembly.") var/obj/item/weaponcrafting/ishotgunconstruction3/I = new /obj/item/weaponcrafting/ishotgunconstruction3 - user.unequip(src) + user.unEquip(src) user.put_in_hands(I) qdel(W) qdel(src) @@ -194,13 +194,13 @@ icon = 'icons/obj/improvised.dmi' icon_state = "ishotgunstep2" -/obj/item/weaponcrafting/ishotgunconstruction3/attackby__legacy__attackchain(obj/item/I, mob/user as mob, params) +/obj/item/weaponcrafting/ishotgunconstruction3/attackby(obj/item/I, mob/user as mob, params) ..() - if(istype(I, /obj/item/stack/package_wrap)) - var/obj/item/stack/package_wrap/C = I + if(istype(I, /obj/item/stack/packageWrap)) + var/obj/item/stack/packageWrap/C = I if(C.use(5)) var/obj/item/gun/projectile/revolver/doublebarrel/improvised/W = new /obj/item/gun/projectile/revolver/doublebarrel/improvised - user.unequip(src) + user.unEquip(src) user.put_in_hands(W) to_chat(user, "You tie the wrapping paper around the stock and the barrel to secure it.") qdel(src) diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index 92bd619396ca9..deb2b1431fd38 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -25,7 +25,7 @@ /// Will this recipe send an admin message when it's completed. var/alert_admins_on_craft = FALSE -/datum/crafting_recipe/ied +/datum/crafting_recipe/IED name = "IED" result = list(/obj/item/grenade/iedcasing) reqs = list(/datum/reagent/fuel = 50, @@ -82,7 +82,7 @@ result = list(/obj/item/pneumatic_cannon/ghetto) tools = list(TOOL_WELDER, TOOL_WRENCH) reqs = list(/obj/item/stack/sheet/metal = 4, - /obj/item/stack/package_wrap = 8, + /obj/item/stack/packageWrap = 8, /obj/item/pipe = 2) time = 300 category = CAT_WEAPONRY @@ -475,7 +475,7 @@ reqs = list(/obj/item/weaponcrafting/receiver = 1, /obj/item/pipe = 1, /obj/item/weaponcrafting/stock = 1, - /obj/item/stack/package_wrap = 5,) + /obj/item/stack/packageWrap = 5,) tools = list(TOOL_SCREWDRIVER) time = 100 category = CAT_WEAPONRY @@ -746,7 +746,7 @@ /datum/crafting_recipe/bonetalisman name = "Bone Talisman" - result = list(/obj/item/clothing/accessory/talisman) + result = list(/obj/item/clothing/accessory/necklace/talisman) time = 20 reqs = list(/obj/item/stack/sheet/bone = 2, /obj/item/stack/sheet/sinew = 1) @@ -754,7 +754,7 @@ /datum/crafting_recipe/bonecodpiece name = "Skull Codpiece" - result = list(/obj/item/clothing/accessory/skullcodpiece) + result = list(/obj/item/clothing/accessory/necklace/skullcodpiece) time = 20 reqs = list(/obj/item/stack/sheet/bone = 2, /obj/item/stack/sheet/animalhide/goliath_hide = 1) diff --git a/code/modules/crafting/tailoring.dm b/code/modules/crafting/tailoring.dm index 435f5196d554f..68ca54d583892 100644 --- a/code/modules/crafting/tailoring.dm +++ b/code/modules/crafting/tailoring.dm @@ -593,7 +593,7 @@ /datum/crafting_recipe/lizardboots name = "Lizard Skin Boots" - result = list(/obj/effect/spawner/random/lizardboots) + result = list(/obj/effect/spawner/lootdrop/lizardboots) time = 6 SECONDS reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1, /obj/item/stack/sheet/leather = 1) category = CAT_CLOTHING diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 94fde2346fa9b..72c69dca524d9 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -33,7 +33,7 @@ toolspeed = 1 usesound = 'sound/items/welder2.ogg' -/obj/item/fluff/tattoo_gun/attack__legacy__attackchain(mob/living/carbon/M as mob, mob/user as mob) +/obj/item/fluff/tattoo_gun/attack(mob/living/carbon/M as mob, mob/user as mob) if(user.a_intent == INTENT_HARM) user.visible_message("[user] stabs [M] with [src]!", "You stab [M] with [src]!") to_chat(M, "[user] stabs you with [src]!
    You feel a tiny prick!") @@ -98,7 +98,7 @@ tattoo_g = 138 tattoo_b = 176 -/obj/item/fluff/tattoo_gun/elliot_cybernetic_tat/attack_self__legacy__attackchain(mob/user as mob) +/obj/item/fluff/tattoo_gun/elliot_cybernetic_tat/attack_self(mob/user as mob) if(!used) var/ink_color = tgui_input_color(user, "Please select an ink color.", "Tattoo Ink Color", rgb(tattoo_r, tattoo_g, tattoo_b)) if(!isnull(ink_color) && !(user.incapacitated() || used)) @@ -120,7 +120,7 @@ icon_state = "bird_orb" icon = 'icons/obj/custom_items.dmi' -/obj/item/fluff/bird_painter/attack_self__legacy__attackchain(mob/user) +/obj/item/fluff/bird_painter/attack_self(mob/user) if(ishuman(user)) var/mob/living/carbon/human/H = user H.s_tone = -115 @@ -194,7 +194,7 @@ desc = "An assorted set of exchangable parts for a wheelchair." icon_state = "modkit" -/obj/item/fluff/rapid_wheelchair_kit/afterattack__legacy__attackchain(atom/target, mob/user, proximity) +/obj/item/fluff/rapid_wheelchair_kit/afterattack(atom/target, mob/user, proximity) if(!proximity || !ishuman(user) || user.incapacitated()) return @@ -255,7 +255,7 @@ item_state = "dogwhistle" force = 2 -/obj/item/fluff/dogwhistle/attack_self__legacy__attackchain(mob/user) +/obj/item/fluff/dogwhistle/attack_self(mob/user) user.visible_message("[user] blows on the whistle, but no sound comes out.", "You blow on the whistle, but don't hear anything.") addtimer(CALLBACK(src, PROC_REF(summon_sax), user), 20) @@ -300,7 +300,7 @@ throwforce = 0 w_class = WEIGHT_CLASS_SMALL -/obj/item/fluff/wingler_comb/attack_self__legacy__attackchain(mob/user) +/obj/item/fluff/wingler_comb/attack_self(mob/user) if(used) return @@ -319,7 +319,7 @@ icon_state = "modkit" w_class = WEIGHT_CLASS_SMALL -/obj/item/fluff/desolate_coat_kit/afterattack__legacy__attackchain(atom/target, mob/user, proximity) +/obj/item/fluff/desolate_coat_kit/afterattack(atom/target, mob/user, proximity) if(!proximity || !ishuman(user) || user.incapacitated()) return @@ -351,7 +351,7 @@ icon_state = "modkit" w_class = WEIGHT_CLASS_SMALL -/obj/item/fluff/fei_gasmask_kit/afterattack__legacy__attackchain(atom/target, mob/user, proximity) +/obj/item/fluff/fei_gasmask_kit/afterattack(atom/target, mob/user, proximity) if(!proximity || !ishuman(user) || user.incapacitated()) return @@ -379,7 +379,7 @@ icon_state = "scifikit" w_class = WEIGHT_CLASS_SMALL -/obj/item/fluff/desolate_baton_kit/afterattack__legacy__attackchain(atom/target, mob/user, proximity) +/obj/item/fluff/desolate_baton_kit/afterattack(atom/target, mob/user, proximity) if(!proximity || !ishuman(user) || user.incapacitated()) return @@ -407,7 +407,7 @@ force = 0 throwforce = 0 -/obj/item/fluff/cardgage_helmet_kit/afterattack__legacy__attackchain(atom/target, mob/user, proximity) +/obj/item/fluff/cardgage_helmet_kit/afterattack(atom/target, mob/user, proximity) if(!proximity || !ishuman(user) || user.incapacitated()) return @@ -430,7 +430,7 @@ force = 0 throwforce = 0 -/obj/item/fluff/merchant_sallet_modkit/afterattack__legacy__attackchain(atom/target, mob/user, proximity) +/obj/item/fluff/merchant_sallet_modkit/afterattack(atom/target, mob/user, proximity) if(!proximity || !ishuman(user) || user.incapacitated()) return @@ -474,7 +474,7 @@ force = 0 throwforce = 0 -/obj/item/fluff/k3_webbing_modkit/afterattack__legacy__attackchain(atom/target, mob/user, proximity) +/obj/item/fluff/k3_webbing_modkit/afterattack(atom/target, mob/user, proximity) if(!proximity || !ishuman(user) || user.incapacitated()) return @@ -498,7 +498,7 @@ icon_state = "modkit" w_class = WEIGHT_CLASS_SMALL /* -/obj/item/fluff/pyro_wintersec_kit/afterattack__legacy__attackchain(atom/target, mob/user, proximity) +/obj/item/fluff/pyro_wintersec_kit/afterattack(atom/target, mob/user, proximity) if(!proximity || !ishuman(user) || user.incapacitated()) return var/mob/living/carbon/human/H = user @@ -552,7 +552,7 @@ icon_state = "modkit" w_class = WEIGHT_CLASS_SMALL /* -/obj/item/fluff/sylus_conversion_kit/afterattack__legacy__attackchain(atom/target, mob/user, proximity) +/obj/item/fluff/sylus_conversion_kit/afterattack(atom/target, mob/user, proximity) if(!proximity || !ishuman(user) || user.incapacitated()) return var/mob/living/carbon/human/H = user @@ -707,7 +707,7 @@ flags_inv = HIDEEYES|HIDEMASK|HIDEFACE|HIDEEARS var/state = "Soldier Up" -/obj/item/clothing/head/helmet/fluff/merchant_sallet/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/head/helmet/fluff/merchant_sallet/attack_self(mob/user) if(!user.incapacitated() && (world.time > cooldown + toggle_cooldown) && Adjacent(user)) var/list/options = list() options["Soldier Up"] = list( @@ -778,7 +778,7 @@ actions_types = list(/datum/action/item_action/openclose) adjust_flavour = "unbutton" -/obj/item/clothing/suit/jacket/miljacket/patch/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/suit/jacket/miljacket/patch/attack_self(mob/user) var/list/options = list() options["purple"] = "shazjacket_purple" options["purple light"] = "shazjacket_purple_light" @@ -1067,7 +1067,7 @@ throwforce = 0 w_class = WEIGHT_CLASS_SMALL -/obj/item/fluff/pinapplehairgel/attack_self__legacy__attackchain(mob/user) +/obj/item/fluff/pinapplehairgel/attack_self(mob/user) var/mob/living/carbon/human/target = user if(!istype(target) || !isslimeperson(target)) return @@ -1432,7 +1432,7 @@ /obj/item/clothing/suit/armor/vest/fluff/tactical name = "tactical armor vest" desc = "A tactical vest with armored plate inserts." - icon = 'icons/obj/clothing/accessories.dmi' + icon = 'icons/obj/clothing/ties.dmi' icon_state = "vest_black" item_state = "vest_black" sprite_sheets = null @@ -1502,7 +1502,7 @@ icon_state = "classic_witch" item_state = "classic_witch" -/obj/item/clothing/head/wizard/fake/fluff/dreamy/attack_self__legacy__attackchain(mob/user) +/obj/item/clothing/head/wizard/fake/fluff/dreamy/attack_self(mob/user) var/list/options = list() options["Classic"] = "classic_witch" options["Good"] = "good_witch" @@ -1539,7 +1539,7 @@ throwforce = 0 w_class = WEIGHT_CLASS_SMALL -/obj/item/fluff/zekemirror/attack_self__legacy__attackchain(mob/user) +/obj/item/fluff/zekemirror/attack_self(mob/user) var/mob/living/carbon/human/target = user if(!istype(target) || !isskrell(target)) // It'd be strange to see other races with head tendrils. return @@ -1549,7 +1549,7 @@ /// Fethas: Sefra'neem -/obj/item/clothing/accessory/locket/fluff/fethasnecklace +/obj/item/clothing/accessory/necklace/locket/fluff/fethasnecklace name = "Orange gemmed locket" desc = "A locket with a orange gem set on the front, the picture inside seems to be of a Tajaran." icon = 'icons/obj/custom_items.dmi' @@ -1597,7 +1597,7 @@ icon_state = "modkit" w_class = WEIGHT_CLASS_SMALL -/obj/item/fluff/lighty_plasman_modkit/afterattack__legacy__attackchain(atom/target, mob/user, proximity, params) +/obj/item/fluff/lighty_plasman_modkit/afterattack(atom/target, mob/user, proximity, params) if(!proximity || !ishuman(user) || user.incapacitated() || !isitem(target)) return var/mob/living/carbon/human/H = user @@ -1613,7 +1613,7 @@ playsound(src, 'sound/effects/spray.ogg', 5, TRUE, 5) var/obj/item/clothing/head/helmet/space/plasmaman/lf53_fluff/F = new(P.loc) if(P == H.head) - H.unequip(P, force = TRUE) + H.unEquip(P, TRUE, TRUE) H.equip_to_slot(F, ITEM_SLOT_HEAD, TRUE) H.update_inv_head() qdel(P) @@ -1693,7 +1693,7 @@ slot_flags = ITEM_SLOT_ACCESSORY /// Sagrotter: Xann Zxiax -/obj/item/clothing/accessory/medal/fluff/xann_zxiax +/obj/item/clothing/accessory/medal/fluff/XannZxiax name = "Zxiax Garnet" desc = "Green Garnet on fancy blue cord, when you look at the Garnet, you feel strangely appeased." icon = 'icons/obj/custom_items.dmi' @@ -1777,7 +1777,7 @@ /obj/item/clothing/gloves/ring/fluff/update_icon_state() return -/obj/item/clothing/gloves/ring/fluff/attackby__legacy__attackchain(obj/item/I as obj, mob/user as mob, params) +/obj/item/clothing/gloves/ring/fluff/attackby(obj/item/I as obj, mob/user as mob, params) return @@ -1841,33 +1841,5 @@ item_state = "colin_earle" item_color = "colin_earle" -// Paratoberfest/contributor rewards -/obj/item/clothing/accessory/pin/reward // Default pin, DO NOT USE - Use the subtypes below - icon = 'icons/obj/custom_items.dmi' - icon_state = "pin_coding" - item_state = "pin_coding" - item_color = "pin_coding" - -/obj/item/clothing/accessory/pin/reward/coding - name = "Coding Contribution Pin" - desc = "A commemorative pin to reward contributions of coding." - icon_state = "pin_coding" - item_state = "pin_coding" - item_color = "pin_coding" - -/obj/item/clothing/accessory/pin/reward/mapping - name = "Mapping Contribution Pin" - desc = "A commemorative pin to reward contributions of mapping." - icon_state = "pin_mapping" - item_state = "pin_mapping" - item_color = "pin_mapping" - -/obj/item/clothing/accessory/pin/reward/spriting - name = "Spriting Contribution Pin" - desc = "A commemorative pin to reward contributions of spriting." - icon_state = "pin_spriting" - item_state = "pin_spriting" - item_color = "pin_spriting" - #undef USED_MOD_HELM #undef USED_MOD_SUIT diff --git a/code/modules/detective_work/evidence.dm b/code/modules/detective_work/evidence.dm index 79ad107bb0124..a8b7d04782514 100644 --- a/code/modules/detective_work/evidence.dm +++ b/code/modules/detective_work/evidence.dm @@ -8,12 +8,12 @@ item_state = "" w_class = WEIGHT_CLASS_TINY -/obj/item/evidencebag/afterattack__legacy__attackchain(obj/item/I, mob/user,proximity) +/obj/item/evidencebag/afterattack(obj/item/I, mob/user,proximity) if(!proximity || loc == I) return evidencebagEquip(I, user) -/obj/item/evidencebag/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/item/evidencebag/attackby(obj/item/I, mob/user, params) if(evidencebagEquip(I, user)) return 1 @@ -41,7 +41,7 @@ if(isstorage(I.loc)) //in a container. var/obj/item/storage/U = I.loc U.remove_from_storage(I, src) - else if(!user.is_holding(I) || !user.unequip(I)) //in a hand + else if(!user.is_holding(I) || !user.unEquip(I)) //in a hand return user.visible_message("[user] puts [I] into [src].", "You put [I] inside [src].",\ @@ -65,7 +65,7 @@ w_class = I.w_class return 1 -/obj/item/evidencebag/attack_self__legacy__attackchain(mob/user) +/obj/item/evidencebag/attack_self(mob/user) if(length(contents)) var/obj/item/I = contents[1] user.visible_message("[user] takes [I] out of [src].", "You take [I] out of [src].",\ diff --git a/code/modules/detective_work/footprints_and_rag.dm b/code/modules/detective_work/footprints_and_rag.dm index 66afdc8379653..468eb94e3221a 100644 --- a/code/modules/detective_work/footprints_and_rag.dm +++ b/code/modules/detective_work/footprints_and_rag.dm @@ -13,7 +13,7 @@ blocks_emissive = EMISSIVE_BLOCK_GENERIC var/wipespeed = 30 -/obj/item/reagent_containers/glass/rag/attack__legacy__attackchain(atom/target as obj|turf|area, mob/user as mob , flag) +/obj/item/reagent_containers/glass/rag/attack(atom/target as obj|turf|area, mob/user as mob , flag) if(ismob(target) && target.reagents && reagents.total_volume) user.visible_message("[user] has smothered [target] with [src]!", "You smother [target] with [src]!", "You hear some struggling and muffled cries of surprise") src.reagents.reaction(target, REAGENT_TOUCH) @@ -22,7 +22,7 @@ else ..() -/obj/item/reagent_containers/glass/rag/afterattack__legacy__attackchain(atom/target, mob/user, proximity) +/obj/item/reagent_containers/glass/rag/afterattack(atom/target, mob/user, proximity) if(!proximity || ishuman(target)) //Human check so we don't clean the person we're trying to ether return target.cleaning_act(user, src, wipespeed) diff --git a/code/modules/detective_work/scanner.dm b/code/modules/detective_work/scanner.dm index a79a11bdcd5ad..6bb25918fee25 100644 --- a/code/modules/detective_work/scanner.dm +++ b/code/modules/detective_work/scanner.dm @@ -16,7 +16,7 @@ var/list/log = list() actions_types = list(/datum/action/item_action/print_forensic_report, /datum/action/item_action/clear_records) -/obj/item/detective_scanner/attack_self__legacy__attackchain(mob/user) +/obj/item/detective_scanner/attack_self(mob/user) var/search = tgui_input_text(user, "Enter name, fingerprint or blood DNA.", "Find record") if(!search || user.stat || user.incapacitated()) @@ -100,10 +100,10 @@ to_chat(usr, "The scanner has no logs or is in use.") -/obj/item/detective_scanner/attack__legacy__attackchain() +/obj/item/detective_scanner/attack() return -/obj/item/detective_scanner/afterattack__legacy__attackchain(atom/A, mob/user) +/obj/item/detective_scanner/afterattack(atom/A, mob/user) scan(A, user) /obj/item/detective_scanner/proc/scan(atom/A, mob/user) diff --git a/code/modules/economy/economy_machinery/account_terminal.dm b/code/modules/economy/economy_machinery/account_terminal.dm index f125ade297902..c91f0b305b271 100644 --- a/code/modules/economy/economy_machinery/account_terminal.dm +++ b/code/modules/economy/economy_machinery/account_terminal.dm @@ -24,10 +24,16 @@ /obj/machinery/computer/account_database/proc/reconnect_database() account_db = GLOB.station_money_database +<<<<<<< HEAD /obj/machinery/computer/account_database/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(ui_login_attackby(used, user)) return ITEM_INTERACT_COMPLETE +======= +/obj/machinery/computer/account_database/attackby(obj/O, mob/user, params) + if(ui_login_attackby(O, user)) + return +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb return ..() /obj/machinery/computer/account_database/attack_hand(mob/user) @@ -143,7 +149,7 @@ /obj/machinery/computer/account_database/proc/print_new_account_info(datum/money_account/account) //create a sealed package containing the account details - var/obj/item/small_delivery/package = new /obj/item/small_delivery(loc) + var/obj/item/smallDelivery/package = new /obj/item/smallDelivery(loc) var/obj/item/paper/printout = new /obj/item/paper(package) playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, TRUE) diff --git a/code/modules/economy/economy_machinery/atm.dm b/code/modules/economy/economy_machinery/atm.dm index c21ed7772584e..780f1cbae3661 100644 --- a/code/modules/economy/economy_machinery/atm.dm +++ b/code/modules/economy/economy_machinery/atm.dm @@ -77,8 +77,13 @@ /obj/machinery/economy/atm/attack_ghost(mob/user) ui_interact(user) +<<<<<<< HEAD /obj/machinery/economy/atm/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(istype(used, /obj/item/card/id)) +======= +/obj/machinery/economy/atm/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/card/id)) +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb if(has_power()) handle_id_insert(used, user) return ITEM_INTERACT_COMPLETE @@ -313,11 +318,10 @@ /obj/machinery/economy/atm/cmag_act(mob/user) if(HAS_TRAIT(src, TRAIT_CMAGGED)) - return FALSE + return playsound(src, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) to_chat(user, "Yellow ooze seeps into the [src]'s card slot...") ADD_TRAIT(src, TRAIT_CMAGGED, CLOWN_EMAG) - return TRUE /obj/machinery/economy/atm/examine(mob/user) . = ..() diff --git a/code/modules/economy/economy_machinery/eftpos.dm b/code/modules/economy/economy_machinery/eftpos.dm index d1f5cf0a956aa..8a65a20011a6f 100644 --- a/code/modules/economy/economy_machinery/eftpos.dm +++ b/code/modules/economy/economy_machinery/eftpos.dm @@ -51,10 +51,10 @@ /obj/item/eftpos/proc/reconnect_database() account_database = GLOB.station_money_database -/obj/item/eftpos/attack_self__legacy__attackchain(mob/user) +/obj/item/eftpos/attack_self(mob/user) ui_interact(user) -/obj/item/eftpos/attackby__legacy__attackchain(obj/O, mob/user, params) +/obj/item/eftpos/attackby(obj/O, mob/user, params) if(istype(O, /obj/item/card/id)) //attempt to connect to a new db, and if that doesn't work then fail if(!account_database) @@ -229,7 +229,7 @@ R.stamped += /obj/item/stamp R.overlays += stampoverlay R.stamps += "
    This paper has been stamped by the EFTPOS device." - var/obj/item/small_delivery/D = new(get_turf(loc)) + var/obj/item/smallDelivery/D = new(get_turf(loc)) if(istype(loc, /mob/living/carbon/human)) var/mob/living/carbon/human/H = loc if(H.back) @@ -290,7 +290,7 @@ /obj/item/eftpos/register/ui_state(mob/user) return GLOB.human_adjacent_state -/obj/item/eftpos/register/attack_self__legacy__attackchain(mob/user) +/obj/item/eftpos/register/attack_self(mob/user) to_chat(user, "[src] has to be set down and secured to be used.") /obj/item/eftpos/register/check_user_position(mob/user) diff --git a/code/modules/error_handler/error_viewer.dm b/code/modules/error_handler/error_viewer.dm index a47e611148fff..1585cc6d3d8fc 100644 --- a/code/modules/error_handler/error_viewer.dm +++ b/code/modules/error_handler/error_viewer.dm @@ -8,10 +8,10 @@ // right here: #ifdef DEBUG -GLOBAL_DATUM_INIT(error_cache, /datum/error_viewer/error_cache, new()) +GLOBAL_DATUM_INIT(error_cache, /datum/ErrorViewer/ErrorCache, new()) #else // If debugging is disabled, there's nothing useful to log, so don't bother. -GLOBAL_DATUM(error_cache, /datum/error_viewer/error_cache) +GLOBAL_DATUM(error_cache, /datum/ErrorViewer/ErrorCache) #endif // - ErrorSource datums exist for each line (of code) that generates an error, @@ -21,10 +21,10 @@ GLOBAL_DATUM(error_cache, /datum/error_viewer/error_cache) // relevant info about that error. // Common vars and procs are kept at the ErrorViewer level -/datum/error_viewer/ +/datum/ErrorViewer/ var/name = "" -/datum/error_viewer/proc/browseTo(user, html) +/datum/ErrorViewer/proc/browseTo(user, html) if(user) var/datum/browser/popup = new(user, "error_viewer", "Runtime Viewer", 700, 500) popup.add_head_content({"\n\n\n
    \n'+$+"
    \n\n\n",K=new Blob([H],{type:"text/plain"}),W=new Date().toISOString().substring(0,19).replace(/[-:]/g,"").replace("T","-");Byond.saveBlob(K,"ss13-paradise-chatlog-"+W+".html",".html")}return P}(),C}();window.__chatRenderer__||(window.__chatRenderer__=new S);var T=e.chatRenderer=window.__chatRenderer__},51747:function(y,e){"use strict";e.__esModule=!0,e.replaceInTextNode=e.linkifyNode=e.highlightNode=void 0;function t(i,d){var c=typeof Symbol!="undefined"&&i[Symbol.iterator]||i["@@iterator"];if(c)return(c=c.call(i)).next.bind(c);if(Array.isArray(i)||(c=n(i))||d&&i&&typeof i.length=="number"){c&&(i=c);var g=0;return function(){return g>=i.length?{done:!0}:{done:!1,value:i[g++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function n(i,d){if(i){if(typeof i=="string")return r(i,d);var c={}.toString.call(i).slice(8,-1);return c==="Object"&&i.constructor&&(c=i.constructor.name),c==="Map"||c==="Set"?Array.from(i):c==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c)?r(i,d):void 0}}function r(i,d){(d==null||d>i.length)&&(d=i.length);for(var c=0,g=Array(d);c=s.IMAGE_RETRY_LIMIT){c.error("failed to load an image after "+M+" attempts");return}var w=P.src;P.src=null,P.src=w+"#"+M,P.setAttribute("data-reload-n",M+1)},s.IMAGE_RETRY_DELAY)},C=function(A){var P=A.node,M=A.times;if(!(!P||!M)){var w=P.querySelector(".Chat__badge"),V=w||document.createElement("div");V.textContent=M,V.className="Chat__badge",w||P.appendChild(V)}},S=function(){function b(){var P=this;this.loaded=!1,this.rootNode=null,this.queue=[],this.messages=[],this.visibleMessages=[],this.page=null,this.events=new r.EventEmitter,this.scrollNode=null,this.scrollTracking=!0,this.handleScroll=function(M){var w=P.scrollNode,V=w.scrollHeight,U=w.scrollTop+w.offsetHeight,j=Math.abs(V-U)0&&(this.processBatch(this.queue),this.queue=[])}return P}(),A.assignStyle=function(){function P(M){M===void 0&&(M={});for(var w=0,V=Object.keys(M);w{}[\]:;'"|~`_\-\\/]/g,W=String(G).split(/[,|]/).map(function(it){return it.trim()}).filter(function(it){return it&&it.length>1&&H.test(it)&&((H.lastIndex=0)||!0)}),q,ut;if(W.length!==0){for(var ct=[],Q=f(W),X;!(X=Q()).done;){var at=X.value;if(at.charAt(0)==="/"&&at.charAt(at.length-1)==="/"){var ft=at.substring(1,at.length-1);if(/^(\[.*\]|\\.|.)$/.test(ft))continue;ct.push(ft)}else q||(q=[]),at=at.replace(K,"\\$&"),q.push(at)}var dt=ct.join("|"),_="g"+(F?"":"i");try{if(dt)ut=new RegExp("("+dt+")",_);else{var rt=(B?"\\b":"")+"("+q.join("|")+")"+(B?"\\b":"");ut=new RegExp(rt,_)}}catch(it){ut=null}V.highlightParsers||(V.highlightParsers=[]),V.highlightParsers.push({highlightWords:q,highlightRegex:ut,highlightColor:$,highlightWholeMessage:x})}})}return P}(),A.scrollToBottom=function(){function P(){this.scrollNode.scrollTop=this.scrollNode.scrollHeight}return P}(),A.changePage=function(){function P(M){if(!this.isReady()){this.page=M,this.tryFlushQueue();return}this.page=M,this.rootNode.textContent="",this.visibleMessages=[];for(var w=document.createDocumentFragment(),V,U=f(this.messages),j;!(j=U()).done;){var G=j.value;(0,u.canPageAcceptType)(M,G.type)&&(V=G.node,w.appendChild(V),this.visibleMessages.push(G))}V&&(this.rootNode.appendChild(w),V.scrollIntoView())}return P}(),A.getCombinableMessage=function(){function P(M,w,V,U){for(var j=V;j>=U;j--){var G=this.visibleMessages[j],$=!G.type.startsWith(s.MESSAGE_TYPE_INTERNAL)&&(0,u.isSameMessage)(G,M)&&w0){this.visibleMessages=M.slice(w);for(var V=0;V0&&(this.messages=this.messages.slice(j),c.log("pruned "+j+" stored messages"))}}}return P}(),A.rebuildChat=function(){function P(){if(this.isReady()){for(var M=Math.max(0,this.messages.length-s.MAX_VISIBLE_MESSAGES),w=this.messages.slice(M),V=f(w),U;!(U=V()).done;){var j=U.value;j.node=void 0}this.rootNode.textContent="",this.messages=[],this.visibleMessages=[],this.processBatch(w,{notifyListeners:!1})}}return P}(),A.clearChat=function(){function P(){var M=this.visibleMessages;this.visibleMessages=[];for(var w=0;w\n\n\n
    \n'+$+"
    \n\n\n",K=new Blob([H]),W=new Date().toISOString().substring(0,19).replace(/[-:]/g,"").replace("T","-");window.navigator.msSaveBlob(K,"ss13-chatlog-"+W+".html")}return P}(),b}();window.__chatRenderer__||(window.__chatRenderer__=new S);var T=e.chatRenderer=window.__chatRenderer__},51747:function(y,e){"use strict";e.__esModule=!0,e.replaceInTextNode=e.linkifyNode=e.highlightNode=void 0;function t(i,d){var c=typeof Symbol!="undefined"&&i[Symbol.iterator]||i["@@iterator"];if(c)return(c=c.call(i)).next.bind(c);if(Array.isArray(i)||(c=n(i))||d&&i&&typeof i.length=="number"){c&&(i=c);var g=0;return function(){return g>=i.length?{done:!0}:{done:!1,value:i[g++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function n(i,d){if(i){if(typeof i=="string")return r(i,d);var c={}.toString.call(i).slice(8,-1);return c==="Object"&&i.constructor&&(c=i.constructor.name),c==="Map"||c==="Set"?Array.from(i):c==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c)?r(i,d):void 0}}function r(i,d){(d==null||d>i.length)&&(d=i.length);for(var c=0,g=Array(d);c9999)return{};T||(T=document.createDocumentFragment()),I||(I=[]);var P=h?h(b[0]):b[0],M=P.length,w=b.index+b[0].indexOf(P);S9999)return{};T||(T=document.createDocumentFragment()),I||(I=[]);var P=h?h(C[0]):C[0],M=P.length,w=C.index+C[0].indexOf(P);S=o.MAX_HIGHLIGHT_SETTINGS?d:Object.assign({},d,{highlightSettings:[].concat(d.highlightSettings,[O.id]),highlightSettingById:Object.assign({},d.highlightSettingById,(I={},I[O.id]=O,I))})}if(g===n.removeHighlightSetting.type){var b=v.id,S=Object.assign({},d,{highlightSettings:[].concat(d.highlightSettings),highlightSettingById:Object.assign({},d.highlightSettingById)});return b===l.id?S.highlightSettings[l.id]=l:(delete S.highlightSettingById[b],S.highlightSettings=S.highlightSettings.filter(function(P){return P!==b}),S.highlightSettings.length||(S.highlightSettings.push(l.id),S.highlightSettingById[l.id]=l)),S}if(g===n.updateHighlightSetting.type){var T=v.id,C=u(v,a),A=Object.assign({},d,{highlightSettings:[].concat(d.highlightSettings),highlightSettingById:Object.assign({},d.highlightSettingById)});return T===l.id&&(C.highlightText&&(A.highlightText=C.highlightText),C.highlightColor&&(A.highlightColor=C.highlightColor)),A.highlightSettingById[T]&&(A.highlightSettingById[T]=Object.assign({},A.highlightSettingById[T],C)),A}return d}return i}()},77034:function(y,e){"use strict";e.__esModule=!0,e.selectSettings=e.selectHighlightSettings=e.selectHighlightSettingById=e.selectActiveTab=void 0;/** + */function u(i,d){if(i==null)return{};var c={};for(var g in i)if({}.hasOwnProperty.call(i,g)){if(d.includes(g))continue;c[g]=i[g]}return c}var l=(0,r.createDefaultHighlightSetting)(),p={version:1,fontSize:13,fontFamily:o.FONTS[0],lineHeight:1.2,theme:"light",adminMusicVolume:.5,highlightText:"",highlightColor:"#ffdd44",highlightSettings:[l.id],highlightSettingById:(s={},s[l.id]=l,s),view:{visible:!1,activeTab:o.SETTINGS_TABS[0].id},statLinked:!0,statFontSize:12,statFontFamily:o.FONTS[0],statTabsStyle:"default"},f=e.settingsReducer=function(){function i(d,c){d===void 0&&(d=p);var g=c.type,v=c.payload;if(g===n.updateSettings.type)return Object.assign({},d,v);if(g===n.loadSettings.type){if(!(v!=null&&v.version))return d;delete v.view;var h=Object.assign({},d,v);h.highlightSettings?h.highlightSettingById[l.id]||(h.highlightSettings=[l.id].concat(h.highlightSettings),h.highlightSettingById[l.id]=l):(h.highlightSettings=[l.id],h.highlightSettingById[l.id]=l);var m=h.highlightSettingById[l.id];return m.highlightColor=h.highlightColor,m.highlightText=h.highlightText,h}if(g===n.toggleSettings.type)return Object.assign({},d,{view:Object.assign({},d.view,{visible:!d.view.visible})});if(g===n.openChatSettings.type)return Object.assign({},d,{view:Object.assign({},d.view,{visible:!0,activeTab:"chatPage"})});if(g===n.changeSettingsTab.type){var E=v.tabId;return Object.assign({},d,{view:Object.assign({},d.view,{activeTab:E})})}if(g===n.addHighlightSetting.type){var I,O=v;return d.highlightSettings.length>=o.MAX_HIGHLIGHT_SETTINGS?d:Object.assign({},d,{highlightSettings:[].concat(d.highlightSettings,[O.id]),highlightSettingById:Object.assign({},d.highlightSettingById,(I={},I[O.id]=O,I))})}if(g===n.removeHighlightSetting.type){var C=v.id,S=Object.assign({},d,{highlightSettings:[].concat(d.highlightSettings),highlightSettingById:Object.assign({},d.highlightSettingById)});return C===l.id?S.highlightSettings[l.id]=l:(delete S.highlightSettingById[C],S.highlightSettings=S.highlightSettings.filter(function(P){return P!==C}),S.highlightSettings.length||(S.highlightSettings.push(l.id),S.highlightSettingById[l.id]=l)),S}if(g===n.updateHighlightSetting.type){var T=v.id,b=u(v,a),A=Object.assign({},d,{highlightSettings:[].concat(d.highlightSettings),highlightSettingById:Object.assign({},d.highlightSettingById)});return T===l.id&&(b.highlightText&&(A.highlightText=b.highlightText),b.highlightColor&&(A.highlightColor=b.highlightColor)),A.highlightSettingById[T]&&(A.highlightSettingById[T]=Object.assign({},A.highlightSettingById[T],b)),A}return d}return i}()},77034:function(y,e){"use strict";e.__esModule=!0,e.selectSettings=e.selectHighlightSettings=e.selectHighlightSettingById=e.selectActiveTab=void 0;/** * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var t=e.selectSettings=function(){function a(s){return s.settings}return a}(),n=e.selectActiveTab=function(){function a(s){return s.settings.view.activeTab}return a}(),r=e.selectHighlightSettings=function(){function a(s){return s.settings.highlightSettings}return a}(),o=e.selectHighlightSettingById=function(){function a(s){return s.settings.highlightSettingById}return a}()},40315:function(y,e,t){"use strict";e.__esModule=!0,e.telemetryMiddleware=void 0;var n=t(27108),r=t(9394);function o(){"use strict";/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */o=function(){return d};var i,d={},c=Object.prototype,g=c.hasOwnProperty,v=Object.defineProperty||function(Q,X,at){Q[X]=at.value},h=typeof Symbol=="function"?Symbol:{},m=h.iterator||"@@iterator",E=h.asyncIterator||"@@asyncIterator",I=h.toStringTag||"@@toStringTag";function O(Q,X,at){return Object.defineProperty(Q,X,{value:at,enumerable:!0,configurable:!0,writable:!0}),Q[X]}try{O({},"")}catch(Q){O=function(at,ft,dt){return at[ft]=dt}}function b(Q,X,at,ft){var dt=X&&X.prototype instanceof w?X:w,_=Object.create(dt.prototype),rt=new ut(ft||[]);return v(_,"_invoke",{value:H(Q,at,rt)}),_}function S(Q,X,at){try{return{type:"normal",arg:Q.call(X,at)}}catch(ft){return{type:"throw",arg:ft}}}d.wrap=b;var T="suspendedStart",C="suspendedYield",A="executing",P="completed",M={};function w(){}function V(){}function U(){}var j={};O(j,m,function(){return this});var G=Object.getPrototypeOf,$=G&&G(G(ct([])));$&&$!==c&&g.call($,m)&&(j=$);var x=U.prototype=w.prototype=Object.create(j);function B(Q){["next","throw","return"].forEach(function(X){O(Q,X,function(at){return this._invoke(X,at)})})}function F(Q,X){function at(dt,_,rt,it){var mt=S(Q[dt],Q,_);if(mt.type!=="throw"){var ot=mt.arg,et=ot.value;return et&&typeof et=="object"&&g.call(et,"__await")?X.resolve(et.__await).then(function(k){at("next",k,rt,it)},function(k){at("throw",k,rt,it)}):X.resolve(et).then(function(k){ot.value=k,rt(ot)},function(k){return at("throw",k,rt,it)})}it(mt.arg)}var ft;v(this,"_invoke",{value:function(){function dt(_,rt){function it(){return new X(function(mt,ot){at(_,rt,mt,ot)})}return ft=ft?ft.then(it,it):it()}return dt}()})}function H(Q,X,at){var ft=T;return function(dt,_){if(ft===A)throw Error("Generator is already running");if(ft===P){if(dt==="throw")throw _;return{value:i,done:!0}}for(at.method=dt,at.arg=_;;){var rt=at.delegate;if(rt){var it=K(rt,at);if(it){if(it===M)continue;return it}}if(at.method==="next")at.sent=at._sent=at.arg;else if(at.method==="throw"){if(ft===T)throw ft=P,at.arg;at.dispatchException(at.arg)}else at.method==="return"&&at.abrupt("return",at.arg);ft=A;var mt=S(Q,X,at);if(mt.type==="normal"){if(ft=at.done?P:C,mt.arg===M)continue;return{value:mt.arg,done:at.done}}mt.type==="throw"&&(ft=P,at.method="throw",at.arg=mt.arg)}}}function K(Q,X){var at=X.method,ft=Q.iterator[at];if(ft===i)return X.delegate=null,at==="throw"&&Q.iterator.return&&(X.method="return",X.arg=i,K(Q,X),X.method==="throw")||at!=="return"&&(X.method="throw",X.arg=new TypeError("The iterator does not provide a '"+at+"' method")),M;var dt=S(ft,Q.iterator,X.arg);if(dt.type==="throw")return X.method="throw",X.arg=dt.arg,X.delegate=null,M;var _=dt.arg;return _?_.done?(X[Q.resultName]=_.value,X.next=Q.nextLoc,X.method!=="return"&&(X.method="next",X.arg=i),X.delegate=null,M):_:(X.method="throw",X.arg=new TypeError("iterator result is not an object"),X.delegate=null,M)}function W(Q){var X={tryLoc:Q[0]};1 in Q&&(X.catchLoc=Q[1]),2 in Q&&(X.finallyLoc=Q[2],X.afterLoc=Q[3]),this.tryEntries.push(X)}function q(Q){var X=Q.completion||{};X.type="normal",delete X.arg,Q.completion=X}function ut(Q){this.tryEntries=[{tryLoc:"root"}],Q.forEach(W,this),this.reset(!0)}function ct(Q){if(Q||Q===""){var X=Q[m];if(X)return X.call(Q);if(typeof Q.next=="function")return Q;if(!isNaN(Q.length)){var at=-1,ft=function(){function dt(){for(;++at=0;--dt){var _=this.tryEntries[dt],rt=_.completion;if(_.tryLoc==="root")return ft("end");if(_.tryLoc<=this.prev){var it=g.call(_,"catchLoc"),mt=g.call(_,"finallyLoc");if(it&&mt){if(this.prev<_.catchLoc)return ft(_.catchLoc,!0);if(this.prev<_.finallyLoc)return ft(_.finallyLoc)}else if(it){if(this.prev<_.catchLoc)return ft(_.catchLoc,!0)}else{if(!mt)throw Error("try statement without catch or finally");if(this.prev<_.finallyLoc)return ft(_.finallyLoc)}}}}return Q}(),abrupt:function(){function Q(X,at){for(var ft=this.tryEntries.length-1;ft>=0;--ft){var dt=this.tryEntries[ft];if(dt.tryLoc<=this.prev&&g.call(dt,"finallyLoc")&&this.prev=0;--at){var ft=this.tryEntries[at];if(ft.finallyLoc===X)return this.complete(ft.completion,ft.afterLoc),q(ft),M}}return Q}(),catch:function(){function Q(X){for(var at=this.tryEntries.length-1;at>=0;--at){var ft=this.tryEntries[at];if(ft.tryLoc===X){var dt=ft.completion;if(dt.type==="throw"){var _=dt.arg;q(ft)}return _}}throw Error("illegal catch attempt")}return Q}(),delegateYield:function(){function Q(X,at,ft){return this.delegate={iterator:ct(X),resultName:at,nextLoc:ft},this.method==="next"&&(this.arg=i),M}return Q}()},d}function a(i,d,c,g,v,h,m){try{var E=i[h](m),I=E.value}catch(O){return void c(O)}E.done?d(I):Promise.resolve(I).then(g,v)}function s(i){return function(){var d=this,c=arguments;return new Promise(function(g,v){var h=i.apply(d,c);function m(I){a(h,g,v,m,E,"next",I)}function E(I){a(h,g,v,m,E,"throw",I)}m(void 0)})}}/** + */var t=e.selectSettings=function(){function a(s){return s.settings}return a}(),n=e.selectActiveTab=function(){function a(s){return s.settings.view.activeTab}return a}(),r=e.selectHighlightSettings=function(){function a(s){return s.settings.highlightSettings}return a}(),o=e.selectHighlightSettingById=function(){function a(s){return s.settings.highlightSettingById}return a}()},40315:function(y,e,t){"use strict";e.__esModule=!0,e.telemetryMiddleware=void 0;var n=t(27108),r=t(9394);function o(){"use strict";/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */o=function(){return d};var i,d={},c=Object.prototype,g=c.hasOwnProperty,v=Object.defineProperty||function(Q,X,at){Q[X]=at.value},h=typeof Symbol=="function"?Symbol:{},m=h.iterator||"@@iterator",E=h.asyncIterator||"@@asyncIterator",I=h.toStringTag||"@@toStringTag";function O(Q,X,at){return Object.defineProperty(Q,X,{value:at,enumerable:!0,configurable:!0,writable:!0}),Q[X]}try{O({},"")}catch(Q){O=function(at,ft,dt){return at[ft]=dt}}function C(Q,X,at,ft){var dt=X&&X.prototype instanceof w?X:w,_=Object.create(dt.prototype),rt=new ut(ft||[]);return v(_,"_invoke",{value:H(Q,at,rt)}),_}function S(Q,X,at){try{return{type:"normal",arg:Q.call(X,at)}}catch(ft){return{type:"throw",arg:ft}}}d.wrap=C;var T="suspendedStart",b="suspendedYield",A="executing",P="completed",M={};function w(){}function V(){}function U(){}var j={};O(j,m,function(){return this});var G=Object.getPrototypeOf,$=G&&G(G(ct([])));$&&$!==c&&g.call($,m)&&(j=$);var x=U.prototype=w.prototype=Object.create(j);function B(Q){["next","throw","return"].forEach(function(X){O(Q,X,function(at){return this._invoke(X,at)})})}function F(Q,X){function at(dt,_,rt,it){var mt=S(Q[dt],Q,_);if(mt.type!=="throw"){var ot=mt.arg,et=ot.value;return et&&typeof et=="object"&&g.call(et,"__await")?X.resolve(et.__await).then(function(k){at("next",k,rt,it)},function(k){at("throw",k,rt,it)}):X.resolve(et).then(function(k){ot.value=k,rt(ot)},function(k){return at("throw",k,rt,it)})}it(mt.arg)}var ft;v(this,"_invoke",{value:function(){function dt(_,rt){function it(){return new X(function(mt,ot){at(_,rt,mt,ot)})}return ft=ft?ft.then(it,it):it()}return dt}()})}function H(Q,X,at){var ft=T;return function(dt,_){if(ft===A)throw Error("Generator is already running");if(ft===P){if(dt==="throw")throw _;return{value:i,done:!0}}for(at.method=dt,at.arg=_;;){var rt=at.delegate;if(rt){var it=K(rt,at);if(it){if(it===M)continue;return it}}if(at.method==="next")at.sent=at._sent=at.arg;else if(at.method==="throw"){if(ft===T)throw ft=P,at.arg;at.dispatchException(at.arg)}else at.method==="return"&&at.abrupt("return",at.arg);ft=A;var mt=S(Q,X,at);if(mt.type==="normal"){if(ft=at.done?P:b,mt.arg===M)continue;return{value:mt.arg,done:at.done}}mt.type==="throw"&&(ft=P,at.method="throw",at.arg=mt.arg)}}}function K(Q,X){var at=X.method,ft=Q.iterator[at];if(ft===i)return X.delegate=null,at==="throw"&&Q.iterator.return&&(X.method="return",X.arg=i,K(Q,X),X.method==="throw")||at!=="return"&&(X.method="throw",X.arg=new TypeError("The iterator does not provide a '"+at+"' method")),M;var dt=S(ft,Q.iterator,X.arg);if(dt.type==="throw")return X.method="throw",X.arg=dt.arg,X.delegate=null,M;var _=dt.arg;return _?_.done?(X[Q.resultName]=_.value,X.next=Q.nextLoc,X.method!=="return"&&(X.method="next",X.arg=i),X.delegate=null,M):_:(X.method="throw",X.arg=new TypeError("iterator result is not an object"),X.delegate=null,M)}function W(Q){var X={tryLoc:Q[0]};1 in Q&&(X.catchLoc=Q[1]),2 in Q&&(X.finallyLoc=Q[2],X.afterLoc=Q[3]),this.tryEntries.push(X)}function q(Q){var X=Q.completion||{};X.type="normal",delete X.arg,Q.completion=X}function ut(Q){this.tryEntries=[{tryLoc:"root"}],Q.forEach(W,this),this.reset(!0)}function ct(Q){if(Q||Q===""){var X=Q[m];if(X)return X.call(Q);if(typeof Q.next=="function")return Q;if(!isNaN(Q.length)){var at=-1,ft=function(){function dt(){for(;++at=0;--dt){var _=this.tryEntries[dt],rt=_.completion;if(_.tryLoc==="root")return ft("end");if(_.tryLoc<=this.prev){var it=g.call(_,"catchLoc"),mt=g.call(_,"finallyLoc");if(it&&mt){if(this.prev<_.catchLoc)return ft(_.catchLoc,!0);if(this.prev<_.finallyLoc)return ft(_.finallyLoc)}else if(it){if(this.prev<_.catchLoc)return ft(_.catchLoc,!0)}else{if(!mt)throw Error("try statement without catch or finally");if(this.prev<_.finallyLoc)return ft(_.finallyLoc)}}}}return Q}(),abrupt:function(){function Q(X,at){for(var ft=this.tryEntries.length-1;ft>=0;--ft){var dt=this.tryEntries[ft];if(dt.tryLoc<=this.prev&&g.call(dt,"finallyLoc")&&this.prev=0;--at){var ft=this.tryEntries[at];if(ft.finallyLoc===X)return this.complete(ft.completion,ft.afterLoc),q(ft),M}}return Q}(),catch:function(){function Q(X){for(var at=this.tryEntries.length-1;at>=0;--at){var ft=this.tryEntries[at];if(ft.tryLoc===X){var dt=ft.completion;if(dt.type==="throw"){var _=dt.arg;q(ft)}return _}}throw Error("illegal catch attempt")}return Q}(),delegateYield:function(){function Q(X,at,ft){return this.delegate={iterator:ct(X),resultName:at,nextLoc:ft},this.method==="next"&&(this.arg=i),M}return Q}()},d}function a(i,d,c,g,v,h,m){try{var E=i[h](m),I=E.value}catch(O){return void c(O)}E.done?d(I):Promise.resolve(I).then(g,v)}function s(i){return function(){var d=this,c=arguments;return new Promise(function(g,v){var h=i.apply(d,c);function m(I){a(h,g,v,m,E,"next",I)}function E(I){a(h,g,v,m,E,"throw",I)}m(void 0)})}}/** * @file * @copyright 2020 Aleksej Komarov * @license MIT -*/var u=(0,r.createLogger)("telemetry"),l=10,p=function(d,c){return d.ckey===c.ckey&&d.address===c.address&&d.computer_id===c.computer_id},f=e.telemetryMiddleware=function(){function i(d){var c,g;return function(v){return function(h){var m=h.type,E=h.payload;if(m==="telemetry/request"){if(!c){u.debug("deferred"),g=E;return}u.debug("sending");var I=(E==null?void 0:E.limits)||{},O=c.connections.slice(0,I.connections);Byond.sendMessage("telemetry",{connections:O});return}if(m==="backend/update"){v(h),s(o().mark(function(){function b(){var S,T,C,A,P;return o().wrap(function(){function M(w){for(;;)switch(w.prev=w.next){case 0:if(T=E==null||(S=E.config)==null?void 0:S.client,T){w.next=4;break}return u.error("backend/update payload is missing client data!"),w.abrupt("return");case 4:if(c){w.next=13;break}return w.next=7,n.storage.get("telemetry");case 7:if(w.t0=w.sent,w.t0){w.next=10;break}w.t0={};case 10:c=w.t0,c.connections||(c.connections=[]),u.debug("retrieved telemetry from storage",c);case 13:C=!1,A=c.connections.find(function(V){return p(V,T)}),A||(C=!0,c.connections.unshift(T),c.connections.length>l&&c.connections.pop()),C&&(u.debug("saving telemetry to storage",c),n.storage.set("telemetry",c)),g&&(P=g,g=null,d.dispatch({type:"telemetry/request",payload:P}));case 18:case"end":return w.stop()}}return M}(),b)}return b}()))();return}return v(h)}}}return i}()},13812:function(y,e){"use strict";e.__esModule=!0,e.setClientTheme=e.THEMES=void 0;/** +*/var u=(0,r.createLogger)("telemetry"),l=10,p=function(d,c){return d.ckey===c.ckey&&d.address===c.address&&d.computer_id===c.computer_id},f=e.telemetryMiddleware=function(){function i(d){var c,g;return function(v){return function(h){var m=h.type,E=h.payload;if(m==="telemetry/request"){if(!c){u.debug("deferred"),g=E;return}u.debug("sending");var I=(E==null?void 0:E.limits)||{},O=c.connections.slice(0,I.connections);Byond.sendMessage("telemetry",{connections:O});return}if(m==="backend/update"){v(h),s(o().mark(function(){function C(){var S,T,b,A,P;return o().wrap(function(){function M(w){for(;;)switch(w.prev=w.next){case 0:if(T=E==null||(S=E.config)==null?void 0:S.client,T){w.next=4;break}return u.error("backend/update payload is missing client data!"),w.abrupt("return");case 4:if(c){w.next=13;break}return w.next=7,n.storage.get("telemetry");case 7:if(w.t0=w.sent,w.t0){w.next=10;break}w.t0={};case 10:c=w.t0,c.connections||(c.connections=[]),u.debug("retrieved telemetry from storage",c);case 13:b=!1,A=c.connections.find(function(V){return p(V,T)}),A||(b=!0,c.connections.unshift(T),c.connections.length>l&&c.connections.pop()),b&&(u.debug("saving telemetry to storage",c),n.storage.set("telemetry",c)),g&&(P=g,g=null,d.dispatch({type:"telemetry/request",payload:P}));case 18:case"end":return w.stop()}}return M}(),C)}return C}()))();return}return v(h)}}}return i}()},13812:function(y,e){"use strict";e.__esModule=!0,e.setClientTheme=e.THEMES=void 0;/** * @file * @copyright 2020 Aleksej Komarov * @license MIT @@ -248,11 +248,11 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var l=(0,s.createLogger)("backend"),p=e.backendUpdate=(0,r.createAction)("backend/update"),f=e.backendSetSharedState=(0,r.createAction)("backend/setSharedState"),i=e.backendSuspendStart=(0,r.createAction)("backend/suspendStart"),d=e.backendSuspendSuccess=function(){function b(){return{type:"backend/suspendSuccess",payload:{timestamp:Date.now()}}}return b}(),c={config:{},data:{},shared:{},suspended:Date.now(),suspending:!1},g=e.backendReducer=function(){function b(S,T){S===void 0&&(S=c);var C=T.type,A=T.payload;if(C==="backend/update"){var P=Object.assign({},S.config,A.config),M=Object.assign({},S.data,A.static_data,A.data),w=Object.assign({},S.shared);if(A.shared)for(var V=0,U=Object.keys(A.shared);V0&&(T.style=U),T}return b}(),I=e.computeBoxClassName=function(){function b(S){var T=S.textColor||S.color,C=S.backgroundColor;return(0,n.classes)([i(T)&&"color-"+T,i(C)&&"color-bg-"+C])}return b}(),O=e.Box=function(){function b(S){var T=S.as,C=T===void 0?"div":T,A=S.className,P=S.children,M=u(S,s);if(typeof P=="function")return P(E(S));var w=typeof A=="string"?A+" "+I(M):I(M),V=E(M);return(0,r.createVNode)(o.VNodeFlags.HtmlElement,C,w,P,o.ChildFlags.UnknownChildren,V)}return b}();O.defaultHooks=n.pureComponentHooks},96184:function(y,e,t){"use strict";e.__esModule=!0,e.ButtonInput=e.ButtonConfirm=e.ButtonCheckbox=e.Button=void 0;var n=t(89005),r=t(35840),o=t(92986),a=t(9394),s=t(55937),u=t(1331),l=t(62147),p=["className","fluid","translucent","icon","iconRotation","iconSpin","color","textColor","disabled","selected","tooltip","tooltipPosition","ellipsis","compact","circular","content","iconColor","iconRight","iconStyle","children","onclick","onClick","multiLine"],f=["checked"],i=["confirmContent","confirmColor","confirmIcon","icon","color","content","onClick"],d=["fluid","content","icon","iconRotation","iconSpin","tooltip","tooltipPosition","color","disabled","multiLine"];/** + */function u(C,S){if(C==null)return{};var T={};for(var b in C)if({}.hasOwnProperty.call(C,b)){if(S.includes(b))continue;T[b]=C[b]}return T}var l=e.unit=function(){function C(S){if(typeof S=="string")return S.endsWith("px")?parseFloat(S)/12+"rem":S;if(typeof S=="number")return S+"rem"}return C}(),p=e.halfUnit=function(){function C(S){if(typeof S=="string")return l(S);if(typeof S=="number")return l(S*.5)}return C}(),f=function(S){return!i(S)},i=function(S){if(typeof S=="string")return a.CSS_COLORS.includes(S)},d=function(S){return function(T,b){(typeof b=="number"||typeof b=="string")&&(T[S]=b)}},c=function(S,T){return function(b,A){(typeof A=="number"||typeof A=="string")&&(b[S]=T(A))}},g=function(S,T){return function(b,A){A&&(b[S]=T)}},v=function(S,T,b){return function(A,P){if(typeof P=="number"||typeof P=="string")for(var M=0;M0&&(T.style=U),T}return C}(),I=e.computeBoxClassName=function(){function C(S){var T=S.textColor||S.color,b=S.backgroundColor;return(0,n.classes)([i(T)&&"color-"+T,i(b)&&"color-bg-"+b])}return C}(),O=e.Box=function(){function C(S){var T=S.as,b=T===void 0?"div":T,A=S.className,P=S.children,M=u(S,s);if(typeof P=="function")return P(E(S));var w=typeof A=="string"?A+" "+I(M):I(M),V=E(M);return(0,r.createVNode)(o.VNodeFlags.HtmlElement,b,w,P,o.ChildFlags.UnknownChildren,V)}return C}();O.defaultHooks=n.pureComponentHooks},96184:function(y,e,t){"use strict";e.__esModule=!0,e.ButtonInput=e.ButtonConfirm=e.ButtonCheckbox=e.Button=void 0;var n=t(89005),r=t(35840),o=t(92986),a=t(9394),s=t(55937),u=t(1331),l=t(62147),p=["className","fluid","translucent","icon","iconRotation","iconSpin","color","textColor","disabled","selected","tooltip","tooltipPosition","ellipsis","compact","circular","content","iconColor","iconRight","iconStyle","children","onclick","onClick","multiLine"],f=["checked"],i=["confirmContent","confirmColor","confirmIcon","icon","color","content","onClick"],d=["fluid","content","icon","iconRotation","iconSpin","tooltip","tooltipPosition","color","disabled","multiLine"];/** * @file * @copyright 2020 Aleksej Komarov * @license MIT - */function c(b,S){b.prototype=Object.create(S.prototype),b.prototype.constructor=b,g(b,S)}function g(b,S){return g=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(T,C){return T.__proto__=C,T},g(b,S)}function v(b,S){if(b==null)return{};var T={};for(var C in b)if({}.hasOwnProperty.call(b,C)){if(S.includes(C))continue;T[C]=b[C]}return T}var h=(0,a.createLogger)("Button"),m=e.Button=function(){function b(S){var T=S.className,C=S.fluid,A=S.translucent,P=S.icon,M=S.iconRotation,w=S.iconSpin,V=S.color,U=S.textColor,j=S.disabled,G=S.selected,$=S.tooltip,x=S.tooltipPosition,B=S.ellipsis,F=S.compact,H=S.circular,K=S.content,W=S.iconColor,q=S.iconRight,ut=S.iconStyle,ct=S.children,Q=S.onclick,X=S.onClick,at=S.multiLine,ft=v(S,p),dt=!!(K||ct);Q&&h.warn("Lowercase 'onclick' is not supported on Button and lowercase prop names are discouraged in general. Please use a camelCase'onClick' instead and read: https://infernojs.org/docs/guides/event-handling"),ft.onClick=function(rt){!j&&X&&X(rt)};var _=(0,n.normalizeProps)((0,n.createComponentVNode)(2,s.Box,Object.assign({className:(0,r.classes)(["Button",C&&"Button--fluid",j&&"Button--disabled"+(A?"--translucent":""),G&&"Button--selected"+(A?"--translucent":""),dt&&"Button--hasContent",B&&"Button--ellipsis",H&&"Button--circular",F&&"Button--compact",q&&"Button--iconRight",at&&"Button--multiLine",V&&typeof V=="string"?"Button--color--"+V+(A?"--translucent":""):"Button--color--default"+(A?"--translucent":""),T]),tabIndex:!j&&"0",color:U,onKeyDown:function(){function rt(it){var mt=window.event?it.which:it.keyCode;if(mt===o.KEY_SPACE||mt===o.KEY_ENTER){it.preventDefault(),!j&&X&&X(it);return}if(mt===o.KEY_ESCAPE){it.preventDefault();return}}return rt}()},ft,{children:[P&&!q&&(0,n.createComponentVNode)(2,u.Icon,{name:P,color:W,rotation:M,spin:w,style:ut}),K,ct,P&&q&&(0,n.createComponentVNode)(2,u.Icon,{name:P,color:W,rotation:M,spin:w,style:ut})]})));return $&&(_=(0,n.createComponentVNode)(2,l.Tooltip,{content:$,position:x,children:_})),_}return b}();m.defaultHooks=r.pureComponentHooks;var E=e.ButtonCheckbox=function(){function b(S){var T=S.checked,C=v(S,f);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,m,Object.assign({color:"transparent",icon:T?"check-square-o":"square-o",selected:T},C)))}return b}();m.Checkbox=E;var I=e.ButtonConfirm=function(b){function S(){var C;return C=b.call(this)||this,C.handleClick=function(){C.state.clickedOnce&&C.setClickedOnce(!1)},C.state={clickedOnce:!1},C}c(S,b);var T=S.prototype;return T.setClickedOnce=function(){function C(A){var P=this;this.setState({clickedOnce:A}),A?setTimeout(function(){return window.addEventListener("click",P.handleClick)}):window.removeEventListener("click",this.handleClick)}return C}(),T.render=function(){function C(){var A=this,P=this.props,M=P.confirmContent,w=M===void 0?"Confirm?":M,V=P.confirmColor,U=V===void 0?"bad":V,j=P.confirmIcon,G=P.icon,$=P.color,x=P.content,B=P.onClick,F=v(P,i);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,m,Object.assign({content:this.state.clickedOnce?w:x,icon:this.state.clickedOnce?j:G,color:this.state.clickedOnce?U:$,onClick:function(){function H(K){return A.state.clickedOnce?B==null?void 0:B(K):A.setClickedOnce(!0)}return H}()},F)))}return C}(),S}(n.Component);m.Confirm=I;var O=e.ButtonInput=function(b){function S(){var C;return C=b.call(this)||this,C.inputRef=void 0,C.inputRef=(0,n.createRef)(),C.state={inInput:!1},C}c(S,b);var T=S.prototype;return T.setInInput=function(){function C(A){var P=this.props.disabled;if(!P&&(this.setState({inInput:A}),this.inputRef)){var M=this.inputRef.current;if(A){M.value=this.props.currentValue||"";try{M.focus(),M.select()}catch(w){}}}}return C}(),T.commitResult=function(){function C(A){if(this.inputRef){var P=this.inputRef.current,M=P.value!=="";if(M){this.props.onCommit(A,P.value);return}else{if(!this.props.defaultValue)return;this.props.onCommit(A,this.props.defaultValue)}}}return C}(),T.render=function(){function C(){var A=this,P=this.props,M=P.fluid,w=P.content,V=P.icon,U=P.iconRotation,j=P.iconSpin,G=P.tooltip,$=P.tooltipPosition,x=P.color,B=x===void 0?"default":x,F=P.disabled,H=P.multiLine,K=v(P,d),W=(0,n.normalizeProps)((0,n.createComponentVNode)(2,s.Box,Object.assign({className:(0,r.classes)(["Button",M&&"Button--fluid",F&&"Button--disabled","Button--color--"+B,H+"Button--multiLine"])},K,{onClick:function(){function q(){return A.setInInput(!0)}return q}(),children:[V&&(0,n.createComponentVNode)(2,u.Icon,{name:V,rotation:U,spin:j}),(0,n.createVNode)(1,"div",null,w,0),(0,n.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:this.state.inInput?void 0:"none","text-align":"left"},onBlur:function(){function q(ut){A.state.inInput&&(A.setInInput(!1),A.commitResult(ut))}return q}(),onKeyDown:function(){function q(ut){if(ut.keyCode===o.KEY_ENTER){A.setInInput(!1),A.commitResult(ut);return}ut.keyCode===o.KEY_ESCAPE&&A.setInInput(!1)}return q}()},null,this.inputRef)]})));return G&&(W=(0,n.createComponentVNode)(2,l.Tooltip,{content:G,position:$,children:W})),W}return C}(),S}(n.Component);m.Input=O},18982:function(y,e,t){"use strict";e.__esModule=!0,e.ByondUi=void 0;var n=t(89005),r=t(35840),o=t(69214),a=t(9394),s=t(55937),u=["params"],l=["params"],p=["parent","params"];function f(I,O){if(I==null)return{};var b={};for(var S in I)if({}.hasOwnProperty.call(I,S)){if(O.includes(S))continue;b[S]=I[S]}return b}function i(I,O){I.prototype=Object.create(O.prototype),I.prototype.constructor=I,d(I,O)}function d(I,O){return d=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(b,S){return b.__proto__=S,b},d(I,O)}/** + */function c(C,S){C.prototype=Object.create(S.prototype),C.prototype.constructor=C,g(C,S)}function g(C,S){return g=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(T,b){return T.__proto__=b,T},g(C,S)}function v(C,S){if(C==null)return{};var T={};for(var b in C)if({}.hasOwnProperty.call(C,b)){if(S.includes(b))continue;T[b]=C[b]}return T}var h=(0,a.createLogger)("Button"),m=e.Button=function(){function C(S){var T=S.className,b=S.fluid,A=S.translucent,P=S.icon,M=S.iconRotation,w=S.iconSpin,V=S.color,U=S.textColor,j=S.disabled,G=S.selected,$=S.tooltip,x=S.tooltipPosition,B=S.ellipsis,F=S.compact,H=S.circular,K=S.content,W=S.iconColor,q=S.iconRight,ut=S.iconStyle,ct=S.children,Q=S.onclick,X=S.onClick,at=S.multiLine,ft=v(S,p),dt=!!(K||ct);Q&&h.warn("Lowercase 'onclick' is not supported on Button and lowercase prop names are discouraged in general. Please use a camelCase'onClick' instead and read: https://infernojs.org/docs/guides/event-handling"),ft.onClick=function(rt){!j&&X&&X(rt)};var _=(0,n.normalizeProps)((0,n.createComponentVNode)(2,s.Box,Object.assign({className:(0,r.classes)(["Button",b&&"Button--fluid",j&&"Button--disabled"+(A?"--translucent":""),G&&"Button--selected"+(A?"--translucent":""),dt&&"Button--hasContent",B&&"Button--ellipsis",H&&"Button--circular",F&&"Button--compact",q&&"Button--iconRight",at&&"Button--multiLine",V&&typeof V=="string"?"Button--color--"+V+(A?"--translucent":""):"Button--color--default"+(A?"--translucent":""),T]),tabIndex:!j&&"0",color:U,onKeyDown:function(){function rt(it){var mt=window.event?it.which:it.keyCode;if(mt===o.KEY_SPACE||mt===o.KEY_ENTER){it.preventDefault(),!j&&X&&X(it);return}if(mt===o.KEY_ESCAPE){it.preventDefault();return}}return rt}()},ft,{children:[P&&!q&&(0,n.createComponentVNode)(2,u.Icon,{name:P,color:W,rotation:M,spin:w,style:ut}),K,ct,P&&q&&(0,n.createComponentVNode)(2,u.Icon,{name:P,color:W,rotation:M,spin:w,style:ut})]})));return $&&(_=(0,n.createComponentVNode)(2,l.Tooltip,{content:$,position:x,children:_})),_}return C}();m.defaultHooks=r.pureComponentHooks;var E=e.ButtonCheckbox=function(){function C(S){var T=S.checked,b=v(S,f);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,m,Object.assign({color:"transparent",icon:T?"check-square-o":"square-o",selected:T},b)))}return C}();m.Checkbox=E;var I=e.ButtonConfirm=function(C){function S(){var b;return b=C.call(this)||this,b.handleClick=function(){b.state.clickedOnce&&b.setClickedOnce(!1)},b.state={clickedOnce:!1},b}c(S,C);var T=S.prototype;return T.setClickedOnce=function(){function b(A){var P=this;this.setState({clickedOnce:A}),A?setTimeout(function(){return window.addEventListener("click",P.handleClick)}):window.removeEventListener("click",this.handleClick)}return b}(),T.render=function(){function b(){var A=this,P=this.props,M=P.confirmContent,w=M===void 0?"Confirm?":M,V=P.confirmColor,U=V===void 0?"bad":V,j=P.confirmIcon,G=P.icon,$=P.color,x=P.content,B=P.onClick,F=v(P,i);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,m,Object.assign({content:this.state.clickedOnce?w:x,icon:this.state.clickedOnce?j:G,color:this.state.clickedOnce?U:$,onClick:function(){function H(K){return A.state.clickedOnce?B==null?void 0:B(K):A.setClickedOnce(!0)}return H}()},F)))}return b}(),S}(n.Component);m.Confirm=I;var O=e.ButtonInput=function(C){function S(){var b;return b=C.call(this)||this,b.inputRef=void 0,b.inputRef=(0,n.createRef)(),b.state={inInput:!1},b}c(S,C);var T=S.prototype;return T.setInInput=function(){function b(A){var P=this.props.disabled;if(!P&&(this.setState({inInput:A}),this.inputRef)){var M=this.inputRef.current;if(A){M.value=this.props.currentValue||"";try{M.focus(),M.select()}catch(w){}}}}return b}(),T.commitResult=function(){function b(A){if(this.inputRef){var P=this.inputRef.current,M=P.value!=="";if(M){this.props.onCommit(A,P.value);return}else{if(!this.props.defaultValue)return;this.props.onCommit(A,this.props.defaultValue)}}}return b}(),T.render=function(){function b(){var A=this,P=this.props,M=P.fluid,w=P.content,V=P.icon,U=P.iconRotation,j=P.iconSpin,G=P.tooltip,$=P.tooltipPosition,x=P.color,B=x===void 0?"default":x,F=P.disabled,H=P.multiLine,K=v(P,d),W=(0,n.normalizeProps)((0,n.createComponentVNode)(2,s.Box,Object.assign({className:(0,r.classes)(["Button",M&&"Button--fluid",F&&"Button--disabled","Button--color--"+B,H+"Button--multiLine"])},K,{onClick:function(){function q(){return A.setInInput(!0)}return q}(),children:[V&&(0,n.createComponentVNode)(2,u.Icon,{name:V,rotation:U,spin:j}),(0,n.createVNode)(1,"div",null,w,0),(0,n.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:this.state.inInput?void 0:"none","text-align":"left"},onBlur:function(){function q(ut){A.state.inInput&&(A.setInInput(!1),A.commitResult(ut))}return q}(),onKeyDown:function(){function q(ut){if(ut.keyCode===o.KEY_ENTER){A.setInInput(!1),A.commitResult(ut);return}ut.keyCode===o.KEY_ESCAPE&&A.setInInput(!1)}return q}()},null,this.inputRef)]})));return G&&(W=(0,n.createComponentVNode)(2,l.Tooltip,{content:G,position:$,children:W})),W}return b}(),S}(n.Component);m.Input=O},18982:function(y,e,t){"use strict";e.__esModule=!0,e.ByondUi=void 0;var n=t(89005),r=t(35840),o=t(69214),a=t(9394),s=t(55937),u=["params"],l=["params"],p=["parent","params"];function f(I,O){if(I==null)return{};var C={};for(var S in I)if({}.hasOwnProperty.call(I,S)){if(O.includes(S))continue;C[S]=I[S]}return C}function i(I,O){I.prototype=Object.create(O.prototype),I.prototype.constructor=I,d(I,O)}function d(I,O){return d=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(C,S){return C.__proto__=S,C},d(I,O)}/** * @file * @copyright 2020 Aleksej Komarov * @license MIT -*/var c=(0,a.createLogger)("ByondUi"),g=[],v=function(O){var b=g.length;g.push(null);var S=O||"byondui_"+b;return c.log("allocated '"+S+"'"),{render:function(){function T(C){c.log("unmounting '"+S+"'"),g[b]=null,Byond.winset(S,{parent:""}),c.log("rendering '"+S+"'"),g[b]=S,Byond.winset(S,C)}return T}(),unmount:function(){function T(){c.log("unmounting '"+S+"'"),g[b]=null,Byond.winset(S,{parent:""})}return T}()}};window.addEventListener("beforeunload",function(){for(var I=0;I0){var x=$[0],B=$[$.length-1];$.push([G[0]+U,B[1]]),$.push([G[0]+U,-U]),$.push([-U,-U]),$.push([-U,x[1]])}var F=i($);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,a.Box,Object.assign({position:"relative"},j,{children:function(){function H(K){return(0,n.normalizeProps)((0,n.createVNode)(1,"div",null,(0,n.createVNode)(32,"svg",null,(0,n.createVNode)(32,"polyline",null,null,1,{transform:"scale(1, -1) translate(0, -"+G[1]+")",fill:P,stroke:w,"stroke-width":U,points:F}),2,{viewBox:"0 0 "+G[0]+" "+G[1],preserveAspectRatio:"none",style:{position:"absolute",top:0,left:0,right:0,bottom:0,overflow:"hidden"}}),2,Object.assign({},K),null,I.ref))}return H}()})))}return E}(),h}(n.Component);d.defaultHooks=o.pureComponentHooks;var c=function(h){return null},g=e.Chart={Line:d}},4796:function(y,e,t){"use strict";e.__esModule=!0,e.Collapsible=void 0;var n=t(89005),r=t(55937),o=t(96184),a=["children","color","title","buttons","contentStyle"];function s(f,i){if(f==null)return{};var d={};for(var c in f)if({}.hasOwnProperty.call(f,c)){if(i.includes(c))continue;d[c]=f[c]}return d}function u(f,i){f.prototype=Object.create(i.prototype),f.prototype.constructor=f,l(f,i)}function l(f,i){return l=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(d,c){return d.__proto__=c,d},l(f,i)}/** +*/var f=function(h,m,E,I){if(h.length===0)return[];var O=(0,r.zipWith)(Math.min).apply(void 0,h),C=(0,r.zipWith)(Math.max).apply(void 0,h);E!==void 0&&(O[0]=E[0],C[0]=E[1]),I!==void 0&&(O[1]=I[0],C[1]=I[1]);var S=(0,r.map)(function(T){return(0,r.zipWith)(function(b,A,P,M){return(b-A)/(P-A)*M})(T,O,C,m)})(h);return S},i=function(h){for(var m="",E=0;E0){var x=$[0],B=$[$.length-1];$.push([G[0]+U,B[1]]),$.push([G[0]+U,-U]),$.push([-U,-U]),$.push([-U,x[1]])}var F=i($);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,a.Box,Object.assign({position:"relative"},j,{children:function(){function H(K){return(0,n.normalizeProps)((0,n.createVNode)(1,"div",null,(0,n.createVNode)(32,"svg",null,(0,n.createVNode)(32,"polyline",null,null,1,{transform:"scale(1, -1) translate(0, -"+G[1]+")",fill:P,stroke:w,"stroke-width":U,points:F}),2,{viewBox:"0 0 "+G[0]+" "+G[1],preserveAspectRatio:"none",style:{position:"absolute",top:0,left:0,right:0,bottom:0,overflow:"hidden"}}),2,Object.assign({},K),null,I.ref))}return H}()})))}return E}(),h}(n.Component);d.defaultHooks=o.pureComponentHooks;var c=function(h){return null},g=e.Chart={Line:d}},4796:function(y,e,t){"use strict";e.__esModule=!0,e.Collapsible=void 0;var n=t(89005),r=t(55937),o=t(96184),a=["children","color","title","buttons","contentStyle"];function s(f,i){if(f==null)return{};var d={};for(var c in f)if({}.hasOwnProperty.call(f,c)){if(i.includes(c))continue;d[c]=f[c]}return d}function u(f,i){f.prototype=Object.create(i.prototype),f.prototype.constructor=f,l(f,i)}function l(f,i){return l=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(d,c){return d.__proto__=c,d},l(f,i)}/** * @file * @copyright 2020 Aleksej Komarov * @license MIT -*/var p=e.Collapsible=function(f){function i(c){var g;g=f.call(this,c)||this;var v=c.open;return g.state={open:v||!1},g}u(i,f);var d=i.prototype;return d.render=function(){function c(){var g=this,v=this.props,h=this.state.open,m=v.children,E=v.color,I=E===void 0?"default":E,O=v.title,b=v.buttons,S=v.contentStyle,T=s(v,a);return(0,n.createComponentVNode)(2,r.Box,{className:"Collapsible",children:[(0,n.createVNode)(1,"div","Table",[(0,n.createVNode)(1,"div","Table__cell",(0,n.normalizeProps)((0,n.createComponentVNode)(2,o.Button,Object.assign({fluid:!0,color:I,icon:h?"chevron-down":"chevron-right",onClick:function(){function C(){return g.setState({open:!h})}return C}()},T,{children:O}))),2),b&&(0,n.createVNode)(1,"div","Table__cell Table__cell--collapsing",b,0)],0),h&&(0,n.createComponentVNode)(2,r.Box,{mt:1,style:S,children:m})]})}return c}(),i}(n.Component)},88894:function(y,e,t){"use strict";e.__esModule=!0,e.ColorBox=void 0;var n=t(89005),r=t(35840),o=t(55937),a=["content","children","className","color","backgroundColor"];/** +*/var p=e.Collapsible=function(f){function i(c){var g;g=f.call(this,c)||this;var v=c.open;return g.state={open:v||!1},g}u(i,f);var d=i.prototype;return d.render=function(){function c(){var g=this,v=this.props,h=this.state.open,m=v.children,E=v.color,I=E===void 0?"default":E,O=v.title,C=v.buttons,S=v.contentStyle,T=s(v,a);return(0,n.createComponentVNode)(2,r.Box,{className:"Collapsible",children:[(0,n.createVNode)(1,"div","Table",[(0,n.createVNode)(1,"div","Table__cell",(0,n.normalizeProps)((0,n.createComponentVNode)(2,o.Button,Object.assign({fluid:!0,color:I,icon:h?"chevron-down":"chevron-right",onClick:function(){function b(){return g.setState({open:!h})}return b}()},T,{children:O}))),2),C&&(0,n.createVNode)(1,"div","Table__cell Table__cell--collapsing",C,0)],0),h&&(0,n.createComponentVNode)(2,r.Box,{mt:1,style:S,children:m})]})}return c}(),i}(n.Component)},88894:function(y,e,t){"use strict";e.__esModule=!0,e.ColorBox=void 0;var n=t(89005),r=t(35840),o=t(55937),a=["content","children","className","color","backgroundColor"];/** * @file * @copyright 2020 Aleksej Komarov * @license MIT @@ -288,11 +288,11 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var o=e.Divider=function(){function a(s){var u=s.vertical,l=s.hidden;return(0,n.createVNode)(1,"div",(0,r.classes)(["Divider",l&&"Divider--hidden",u?"Divider--vertical":"Divider--horizontal"]))}return a}()},60218:function(y,e,t){"use strict";e.__esModule=!0,e.DmIcon=void 0;var n=t(89005),r=t(79140),o=t(46085),a=t(91225),s=["className","direction","fallback","frame","icon_state","movement"];function u(h,m){if(h==null)return{};var E={};for(var I in h)if({}.hasOwnProperty.call(h,I)){if(m.includes(I))continue;E[I]=h[I]}return E}function l(){"use strict";/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */l=function(){return m};var h,m={},E=Object.prototype,I=E.hasOwnProperty,O=Object.defineProperty||function(_,rt,it){_[rt]=it.value},b=typeof Symbol=="function"?Symbol:{},S=b.iterator||"@@iterator",T=b.asyncIterator||"@@asyncIterator",C=b.toStringTag||"@@toStringTag";function A(_,rt,it){return Object.defineProperty(_,rt,{value:it,enumerable:!0,configurable:!0,writable:!0}),_[rt]}try{A({},"")}catch(_){A=function(it,mt,ot){return it[mt]=ot}}function P(_,rt,it,mt){var ot=rt&&rt.prototype instanceof $?rt:$,et=Object.create(ot.prototype),k=new ft(mt||[]);return O(et,"_invoke",{value:ct(_,it,k)}),et}function M(_,rt,it){try{return{type:"normal",arg:_.call(rt,it)}}catch(mt){return{type:"throw",arg:mt}}}m.wrap=P;var w="suspendedStart",V="suspendedYield",U="executing",j="completed",G={};function $(){}function x(){}function B(){}var F={};A(F,S,function(){return this});var H=Object.getPrototypeOf,K=H&&H(H(dt([])));K&&K!==E&&I.call(K,S)&&(F=K);var W=B.prototype=$.prototype=Object.create(F);function q(_){["next","throw","return"].forEach(function(rt){A(_,rt,function(it){return this._invoke(rt,it)})})}function ut(_,rt){function it(ot,et,k,tt){var nt=M(_[ot],_,et);if(nt.type!=="throw"){var pt=nt.arg,Et=pt.value;return Et&&typeof Et=="object"&&I.call(Et,"__await")?rt.resolve(Et.__await).then(function(st){it("next",st,k,tt)},function(st){it("throw",st,k,tt)}):rt.resolve(Et).then(function(st){pt.value=st,k(pt)},function(st){return it("throw",st,k,tt)})}tt(nt.arg)}var mt;O(this,"_invoke",{value:function(){function ot(et,k){function tt(){return new rt(function(nt,pt){it(et,k,nt,pt)})}return mt=mt?mt.then(tt,tt):tt()}return ot}()})}function ct(_,rt,it){var mt=w;return function(ot,et){if(mt===U)throw Error("Generator is already running");if(mt===j){if(ot==="throw")throw et;return{value:h,done:!0}}for(it.method=ot,it.arg=et;;){var k=it.delegate;if(k){var tt=Q(k,it);if(tt){if(tt===G)continue;return tt}}if(it.method==="next")it.sent=it._sent=it.arg;else if(it.method==="throw"){if(mt===w)throw mt=j,it.arg;it.dispatchException(it.arg)}else it.method==="return"&&it.abrupt("return",it.arg);mt=U;var nt=M(_,rt,it);if(nt.type==="normal"){if(mt=it.done?j:V,nt.arg===G)continue;return{value:nt.arg,done:it.done}}nt.type==="throw"&&(mt=j,it.method="throw",it.arg=nt.arg)}}}function Q(_,rt){var it=rt.method,mt=_.iterator[it];if(mt===h)return rt.delegate=null,it==="throw"&&_.iterator.return&&(rt.method="return",rt.arg=h,Q(_,rt),rt.method==="throw")||it!=="return"&&(rt.method="throw",rt.arg=new TypeError("The iterator does not provide a '"+it+"' method")),G;var ot=M(mt,_.iterator,rt.arg);if(ot.type==="throw")return rt.method="throw",rt.arg=ot.arg,rt.delegate=null,G;var et=ot.arg;return et?et.done?(rt[_.resultName]=et.value,rt.next=_.nextLoc,rt.method!=="return"&&(rt.method="next",rt.arg=h),rt.delegate=null,G):et:(rt.method="throw",rt.arg=new TypeError("iterator result is not an object"),rt.delegate=null,G)}function X(_){var rt={tryLoc:_[0]};1 in _&&(rt.catchLoc=_[1]),2 in _&&(rt.finallyLoc=_[2],rt.afterLoc=_[3]),this.tryEntries.push(rt)}function at(_){var rt=_.completion||{};rt.type="normal",delete rt.arg,_.completion=rt}function ft(_){this.tryEntries=[{tryLoc:"root"}],_.forEach(X,this),this.reset(!0)}function dt(_){if(_||_===""){var rt=_[S];if(rt)return rt.call(_);if(typeof _.next=="function")return _;if(!isNaN(_.length)){var it=-1,mt=function(){function ot(){for(;++it<_.length;)if(I.call(_,it))return ot.value=_[it],ot.done=!1,ot;return ot.value=h,ot.done=!0,ot}return ot}();return mt.next=mt}}throw new TypeError(typeof _+" is not iterable")}return x.prototype=B,O(W,"constructor",{value:B,configurable:!0}),O(B,"constructor",{value:x,configurable:!0}),x.displayName=A(B,C,"GeneratorFunction"),m.isGeneratorFunction=function(_){var rt=typeof _=="function"&&_.constructor;return!!rt&&(rt===x||(rt.displayName||rt.name)==="GeneratorFunction")},m.mark=function(_){return Object.setPrototypeOf?Object.setPrototypeOf(_,B):(_.__proto__=B,A(_,C,"GeneratorFunction")),_.prototype=Object.create(W),_},m.awrap=function(_){return{__await:_}},q(ut.prototype),A(ut.prototype,T,function(){return this}),m.AsyncIterator=ut,m.async=function(_,rt,it,mt,ot){ot===void 0&&(ot=Promise);var et=new ut(P(_,rt,it,mt),ot);return m.isGeneratorFunction(rt)?et:et.next().then(function(k){return k.done?k.value:et.next()})},q(W),A(W,C,"Generator"),A(W,S,function(){return this}),A(W,"toString",function(){return"[object Generator]"}),m.keys=function(_){var rt=Object(_),it=[];for(var mt in rt)it.push(mt);return it.reverse(),function(){function ot(){for(;it.length;){var et=it.pop();if(et in rt)return ot.value=et,ot.done=!1,ot}return ot.done=!0,ot}return ot}()},m.values=dt,ft.prototype={constructor:ft,reset:function(){function _(rt){if(this.prev=0,this.next=0,this.sent=this._sent=h,this.done=!1,this.delegate=null,this.method="next",this.arg=h,this.tryEntries.forEach(at),!rt)for(var it in this)it.charAt(0)==="t"&&I.call(this,it)&&!isNaN(+it.slice(1))&&(this[it]=h)}return _}(),stop:function(){function _(){this.done=!0;var rt=this.tryEntries[0].completion;if(rt.type==="throw")throw rt.arg;return this.rval}return _}(),dispatchException:function(){function _(rt){if(this.done)throw rt;var it=this;function mt(pt,Et){return k.type="throw",k.arg=rt,it.next=pt,Et&&(it.method="next",it.arg=h),!!Et}for(var ot=this.tryEntries.length-1;ot>=0;--ot){var et=this.tryEntries[ot],k=et.completion;if(et.tryLoc==="root")return mt("end");if(et.tryLoc<=this.prev){var tt=I.call(et,"catchLoc"),nt=I.call(et,"finallyLoc");if(tt&&nt){if(this.prev=0;--mt){var ot=this.tryEntries[mt];if(ot.tryLoc<=this.prev&&I.call(ot,"finallyLoc")&&this.prev=0;--it){var mt=this.tryEntries[it];if(mt.finallyLoc===rt)return this.complete(mt.completion,mt.afterLoc),at(mt),G}}return _}(),catch:function(){function _(rt){for(var it=this.tryEntries.length-1;it>=0;--it){var mt=this.tryEntries[it];if(mt.tryLoc===rt){var ot=mt.completion;if(ot.type==="throw"){var et=ot.arg;at(mt)}return et}}throw Error("illegal catch attempt")}return _}(),delegateYield:function(){function _(rt,it,mt){return this.delegate={iterator:dt(rt),resultName:it,nextLoc:mt},this.method==="next"&&(this.arg=h),G}return _}()},m}function p(h,m,E,I,O,b,S){try{var T=h[b](S),C=T.value}catch(A){return void E(A)}T.done?m(C):Promise.resolve(C).then(I,O)}function f(h){return function(){var m=this,E=arguments;return new Promise(function(I,O){var b=h.apply(m,E);function S(C){p(b,I,O,S,T,"next",C)}function T(C){p(b,I,O,S,T,"throw",C)}S(void 0)})}}function i(h,m){h.prototype=Object.create(m.prototype),h.prototype.constructor=h,d(h,m)}function d(h,m){return d=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(E,I){return E.__proto__=I,E},d(h,m)}var c=function(h){return h[h.NORTH=1]="NORTH",h[h.SOUTH=2]="SOUTH",h[h.EAST=4]="EAST",h[h.WEST=8]="WEST",h[h.NORTHEAST=5]="NORTHEAST",h[h.NORTHWEST=9]="NORTHWEST",h[h.SOUTHEAST=6]="SOUTHEAST",h[h.SOUTHWEST=10]="SOUTHWEST",h}(c||{}),g,v=e.DmIcon=function(h){function m(I){var O;return O=h.call(this,I)||this,O.state={iconRef:""},O}i(m,h);var E=m.prototype;return E.fetchRefMap=function(){var I=f(l().mark(function(){function b(){var S,T;return l().wrap(function(){function C(A){for(;;)switch(A.prev=A.next){case 0:return A.prev=0,A.next=3,(0,o.fetchRetry)((0,r.resolveAsset)("icon_ref_map.json"));case 3:return S=A.sent,A.next=6,S.json();case 6:T=A.sent,g=T,this.setState({iconRef:T[this.props.icon]||""}),A.next=14;break;case 11:return A.prev=11,A.t0=A.catch(0),A.abrupt("return");case 14:case"end":return A.stop()}}return C}(),b,this,[[0,11]])}return b}()));function O(){return I.apply(this,arguments)}return O}(),E.componentDidMount=function(){function I(){g?this.setState({iconRef:g[this.props.icon]}):this.fetchRefMap()}return I}(),E.componentDidUpdate=function(){function I(O){O.icon!==this.props.icon&&(g?this.setState({iconRef:g[this.props.icon]}):this.fetchRefMap())}return I}(),E.render=function(){function I(){var O=this.props,b=O.className,S=O.direction,T=S===void 0?c.SOUTH:S,C=O.fallback,A=O.frame,P=A===void 0?1:A,M=O.icon_state,w=O.movement,V=w===void 0?!1:w,U=u(O,s),j=this.state.iconRef,G=j+"?state="+M+"&dir="+T+"&movement="+!!V+"&frame="+P;return j?(0,n.normalizeProps)((0,n.createComponentVNode)(2,a.Image,Object.assign({fixErrors:!0,src:G},U))):C||null}return I}(),m}(n.Component)},20342:function(y,e,t){"use strict";e.__esModule=!0,e.DraggableControl=void 0;var n=t(89005),r=t(44879),o=t(35840),a=t(9474);function s(i,d){i.prototype=Object.create(d.prototype),i.prototype.constructor=i,u(i,d)}function u(i,d){return u=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(c,g){return c.__proto__=g,c},u(i,d)}var l=400,p=function(d,c){return d.screenX*c[0]+d.screenY*c[1]},f=e.DraggableControl=function(i){function d(g){var v;return v=i.call(this,g)||this,v.inputRef=(0,n.createRef)(),v.state={originalValue:g.value,value:g.value,dragging:!1,editing:!1,origin:null,suppressingFlicker:!1},v.flickerTimer=null,v.suppressFlicker=function(){var h=v.props.suppressFlicker;h>0&&(v.setState({suppressingFlicker:!0}),clearTimeout(v.flickerTimer),v.flickerTimer=setTimeout(function(){return v.setState({suppressingFlicker:!1})},h))},v.handleDragStart=function(h){var m=v.props,E=m.value,I=m.dragMatrix,O=m.disabled,b=v.state.editing;b||O||(document.body.style["pointer-events"]="none",v.ref=h.currentTarget,v.setState({originalValue:E,dragging:!1,value:E,origin:p(h,I)}),v.timer=setTimeout(function(){v.setState({dragging:!0})},250),v.dragInterval=setInterval(function(){var S=v.state,T=S.dragging,C=S.value,A=v.props.onDrag;T&&A&&A(h,C)},v.props.updateRate||l),document.addEventListener("mousemove",v.handleDragMove),document.addEventListener("mouseup",v.handleDragEnd))},v.handleDragMove=function(h){var m,E=v.props,I=E.minValue,O=E.maxValue,b=E.step,S=E.dragMatrix,T=E.disabled;if(!T){var C=v.ref.offsetWidth/((O-I)/b),A=(m=v.props.stepPixelSize)!=null?m:C;typeof A=="function"&&(A=A(C)),v.setState(function(P){var M=Object.assign({},P),w=P.origin,V=p(h,S)-w;if(P.dragging){var U=Math.trunc(V/A);M.value=(0,r.clamp)(Math.floor(M.originalValue/b)*b+U*b,I,O)}else Math.abs(V)>4&&(M.dragging=!0);return M})}},v.handleDragEnd=function(h){var m=v.props,E=m.onChange,I=m.onDrag,O=v.state,b=O.dragging,S=O.value;if(document.body.style["pointer-events"]="auto",clearTimeout(v.timer),clearInterval(v.dragInterval),v.setState({originalValue:null,dragging:!1,editing:!b,origin:null}),document.removeEventListener("mousemove",v.handleDragMove),document.removeEventListener("mouseup",v.handleDragEnd),b)v.suppressFlicker(),E&&E(h,S),I&&I(h,S);else if(v.inputRef){var T=v.inputRef.current;T.value=S;try{T.focus(),T.select()}catch(C){}}},v}s(d,i);var c=d.prototype;return c.render=function(){function g(){var v=this,h=this.state,m=h.dragging,E=h.editing,I=h.value,O=h.suppressingFlicker,b=this.props,S=b.animated,T=b.value,C=b.unit,A=b.minValue,P=b.maxValue,M=b.format,w=b.onChange,V=b.onDrag,U=b.children,j=b.height,G=b.lineHeight,$=b.fontSize,x=b.disabled,B=T;(m||O)&&(B=I);var F=function(){function W(q){return q+(C?" "+C:"")}return W}(),H=S&&!m&&!O&&(0,n.createComponentVNode)(2,a.AnimatedNumber,{value:B,format:M,children:F})||F(M?M(B):B),K=(0,n.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:!E||x?"none":void 0,height:j,"line-height":G,"font-size":$},onBlur:function(){function W(q){if(E){var ut=(0,r.clamp)(parseFloat(q.target.value),A,P);if(Number.isNaN(ut)){v.setState({editing:!1});return}v.setState({editing:!1,value:ut}),v.suppressFlicker(),w&&w(q,ut),V&&V(q,ut)}}return W}(),onKeyDown:function(){function W(q){if(q.keyCode===13){var ut=(0,r.clamp)(parseFloat(q.target.value),A,P);if(Number.isNaN(ut)){v.setState({editing:!1});return}v.setState({editing:!1,value:ut}),v.suppressFlicker(),w&&w(q,ut),V&&V(q,ut);return}if(q.keyCode===27){v.setState({editing:!1});return}}return W}(),disabled:x},null,this.inputRef);return U({dragging:m,editing:E,value:T,displayValue:B,displayElement:H,inputElement:K,handleDragStart:this.handleDragStart})}return g}(),d}(n.Component);f.defaultHooks=o.pureComponentHooks,f.defaultProps={minValue:-1/0,maxValue:1/0,step:1,suppressFlicker:50,dragMatrix:[1,0]}},87099:function(y,e,t){"use strict";e.__esModule=!0,e.Dropdown=void 0;var n=t(89005),r=t(95996),o=t(35840),a=t(55937),s=t(96184),u=t(1331),l=t(96690),p=["icon","iconRotation","iconSpin","clipSelectedText","color","dropdownStyle","over","nochevron","width","onClick","onSelected","selected","disabled","displayText","buttons"],f=["className"],i;function d(O,b){if(O==null)return{};var S={};for(var T in O)if({}.hasOwnProperty.call(O,T)){if(b.includes(T))continue;S[T]=O[T]}return S}function c(O,b){O.prototype=Object.create(b.prototype),O.prototype.constructor=O,g(O,b)}function g(O,b){return g=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(S,T){return S.__proto__=T,S},g(O,b)}var v={placement:"left-start",modifiers:[{name:"eventListeners",enabled:!1}]},h={width:0,height:0,top:0,right:0,bottom:0,left:0,x:0,y:0,toJSON:function(){function O(){return null}return O}()},m="Layout Dropdown__menu",E="Layout Dropdown__menu-scroll",I=e.Dropdown=function(O){function b(T){var C;return C=O.call(this,T)||this,C.menuContents=void 0,C.handleClick=function(){C.state.open&&C.setOpen(!1)},C.state={open:!1,selected:C.props.selected},C.menuContents=null,C}c(b,O);var S=b.prototype;return S.getDOMNode=function(){function T(){return(0,n.findDOMFromVNode)(this.$LI,!0)}return T}(),S.componentDidMount=function(){function T(){var C=this.getDOMNode()}return T}(),S.openMenu=function(){function T(){var C=b.renderedMenu;C===void 0&&(C=document.createElement("div"),C.className=m,document.body.appendChild(C),b.renderedMenu=C);var A=this.getDOMNode();b.currentOpenMenu=A,C.scrollTop=0,C.style.width=this.props.menuWidth||A.offsetWidth+"px",C.style.opacity="1",C.style.pointerEvents="auto",setTimeout(function(){var P;(P=b.renderedMenu)==null||P.focus()},400),this.renderMenuContent()}return T}(),S.closeMenu=function(){function T(){b.currentOpenMenu===this.getDOMNode()&&(b.currentOpenMenu=void 0,b.renderedMenu.style.opacity="0",b.renderedMenu.style.pointerEvents="none")}return T}(),S.componentWillUnmount=function(){function T(){this.closeMenu(),this.setOpen(!1)}return T}(),S.renderMenuContent=function(){function T(){var C=this,A=b.renderedMenu;if(A){A.offsetHeight>200?A.className=E:A.className=m;var P=this.props.options,M=P===void 0?[]:P,w=M.map(function(U){var j,G;return typeof U=="string"?(G=U,j=U):U!==null&&(G=U.displayText,j=U.value),(0,n.createVNode)(1,"div",(0,o.classes)(["Dropdown__menuentry",C.state.selected===j&&"selected"]),G,0,{onClick:function(){function $(){C.setSelected(j)}return $}()},j)}),V=w.length?w:"No Options Found";(0,n.render)((0,n.createVNode)(1,"div",null,V,0),A,function(){var U=b.singletonPopper;U===void 0?(U=(0,r.createPopper)(b.virtualElement,A,Object.assign({},v,{placement:"bottom-start"})),b.singletonPopper=U):(U.setOptions(Object.assign({},v,{placement:"bottom-start"})),U.update())},this.context)}}return T}(),S.setOpen=function(){function T(C){var A=this;this.setState(function(P){return Object.assign({},P,{open:C})}),C?setTimeout(function(){A.openMenu(),window.addEventListener("click",A.handleClick)}):(this.closeMenu(),window.removeEventListener("click",this.handleClick))}return T}(),S.setSelected=function(){function T(C){this.setState(function(A){return Object.assign({},A,{selected:C})}),this.setOpen(!1),this.props.onSelected&&this.props.onSelected(C)}return T}(),S.getOptionValue=function(){function T(C){return typeof C=="string"?C:C.value}return T}(),S.getSelectedIndex=function(){function T(){var C=this,A=this.state.selected||this.props.selected,P=this.props.options,M=P===void 0?[]:P;return M.findIndex(function(w){return C.getOptionValue(w)===A})}return T}(),S.toPrevious=function(){function T(){if(!(this.props.options.length<1)){var C=this.getSelectedIndex(),A=0,P=this.props.options.length-1,M=C>=0;M||(C=A);var w=C===A?P:C-1;this.setSelected(this.getOptionValue(this.props.options[w]))}}return T}(),S.toNext=function(){function T(){if(!(this.props.options.length<1)){var C=this.getSelectedIndex(),A=0,P=this.props.options.length-1,M=C>=0;M||(C=P);var w=C===P?A:C+1;this.setSelected(this.getOptionValue(this.props.options[w]))}}return T}(),S.render=function(){function T(){var C=this,A=this.props,P=A.icon,M=A.iconRotation,w=A.iconSpin,V=A.clipSelectedText,U=V===void 0?!0:V,j=A.color,G=j===void 0?"default":j,$=A.dropdownStyle,x=A.over,B=A.nochevron,F=A.width,H=A.onClick,K=A.onSelected,W=A.selected,q=A.disabled,ut=A.displayText,ct=A.buttons,Q=d(A,p),X=Q.className,at=d(Q,f),ft=x?!this.state.open:this.state.open;return(0,n.createComponentVNode)(2,l.Stack,{inline:!0,fill:!0,width:F,children:[(0,n.createComponentVNode)(2,l.Stack.Item,{grow:!0,children:(0,n.normalizeProps)((0,n.createComponentVNode)(2,a.Box,Object.assign({width:"100%",className:(0,o.classes)(["Dropdown__control","Button","Button--color--"+G,q&&"Button--disabled",X]),onClick:function(){function dt(_){q&&!C.state.open||(C.setOpen(!C.state.open),H&&H(_))}return dt}()},at,{children:[P&&(0,n.createComponentVNode)(2,u.Icon,{name:P,rotation:M,spin:w,mr:1}),(0,n.createVNode)(1,"span","Dropdown__selected-text",ut||this.state.selected,0,{style:{overflow:U?"hidden":"visible"}}),B||(0,n.createVNode)(1,"span","Dropdown__arrow-button",(0,n.createComponentVNode)(2,u.Icon,{name:ft?"chevron-up":"chevron-down"}),2)]})))}),ct&&(0,n.createFragment)([(0,n.createComponentVNode)(2,l.Stack.Item,{height:"100%",children:(0,n.createComponentVNode)(2,s.Button,{height:"100%",icon:"chevron-left",disabled:q,onClick:function(){function dt(){q||C.toPrevious()}return dt}()})}),(0,n.createComponentVNode)(2,l.Stack.Item,{height:"100%",children:(0,n.createComponentVNode)(2,s.Button,{height:"100%",icon:"chevron-right",disabled:q,onClick:function(){function dt(){q||C.toNext()}return dt}()})})],4)]})}return T}(),b}(n.Component);i=I,I.renderedMenu=void 0,I.singletonPopper=void 0,I.currentOpenMenu=void 0,I.virtualElement={getBoundingClientRect:function(){function O(){var b,S;return(b=(S=i.currentOpenMenu)==null?void 0:S.getBoundingClientRect())!=null?b:h}return O}()}},39473:function(y,e,t){"use strict";e.__esModule=!0,e.computeFlexProps=e.computeFlexItemProps=e.computeFlexItemClassName=e.computeFlexClassName=e.Flex=void 0;var n=t(89005),r=t(35840),o=t(55937),a=["className","direction","wrap","align","justify","inline","style"],s=["className"],u=["className","style","grow","order","shrink","basis","align"],l=["className"];/** + */var o=e.Divider=function(){function a(s){var u=s.vertical,l=s.hidden;return(0,n.createVNode)(1,"div",(0,r.classes)(["Divider",l&&"Divider--hidden",u?"Divider--vertical":"Divider--horizontal"]))}return a}()},60218:function(y,e,t){"use strict";e.__esModule=!0,e.DmIcon=void 0;var n=t(89005),r=t(79140),o=t(46085),a=t(91225),s=["className","direction","fallback","frame","icon_state","movement"];function u(h,m){if(h==null)return{};var E={};for(var I in h)if({}.hasOwnProperty.call(h,I)){if(m.includes(I))continue;E[I]=h[I]}return E}function l(){"use strict";/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */l=function(){return m};var h,m={},E=Object.prototype,I=E.hasOwnProperty,O=Object.defineProperty||function(_,rt,it){_[rt]=it.value},C=typeof Symbol=="function"?Symbol:{},S=C.iterator||"@@iterator",T=C.asyncIterator||"@@asyncIterator",b=C.toStringTag||"@@toStringTag";function A(_,rt,it){return Object.defineProperty(_,rt,{value:it,enumerable:!0,configurable:!0,writable:!0}),_[rt]}try{A({},"")}catch(_){A=function(it,mt,ot){return it[mt]=ot}}function P(_,rt,it,mt){var ot=rt&&rt.prototype instanceof $?rt:$,et=Object.create(ot.prototype),k=new ft(mt||[]);return O(et,"_invoke",{value:ct(_,it,k)}),et}function M(_,rt,it){try{return{type:"normal",arg:_.call(rt,it)}}catch(mt){return{type:"throw",arg:mt}}}m.wrap=P;var w="suspendedStart",V="suspendedYield",U="executing",j="completed",G={};function $(){}function x(){}function B(){}var F={};A(F,S,function(){return this});var H=Object.getPrototypeOf,K=H&&H(H(dt([])));K&&K!==E&&I.call(K,S)&&(F=K);var W=B.prototype=$.prototype=Object.create(F);function q(_){["next","throw","return"].forEach(function(rt){A(_,rt,function(it){return this._invoke(rt,it)})})}function ut(_,rt){function it(ot,et,k,tt){var nt=M(_[ot],_,et);if(nt.type!=="throw"){var pt=nt.arg,Et=pt.value;return Et&&typeof Et=="object"&&I.call(Et,"__await")?rt.resolve(Et.__await).then(function(st){it("next",st,k,tt)},function(st){it("throw",st,k,tt)}):rt.resolve(Et).then(function(st){pt.value=st,k(pt)},function(st){return it("throw",st,k,tt)})}tt(nt.arg)}var mt;O(this,"_invoke",{value:function(){function ot(et,k){function tt(){return new rt(function(nt,pt){it(et,k,nt,pt)})}return mt=mt?mt.then(tt,tt):tt()}return ot}()})}function ct(_,rt,it){var mt=w;return function(ot,et){if(mt===U)throw Error("Generator is already running");if(mt===j){if(ot==="throw")throw et;return{value:h,done:!0}}for(it.method=ot,it.arg=et;;){var k=it.delegate;if(k){var tt=Q(k,it);if(tt){if(tt===G)continue;return tt}}if(it.method==="next")it.sent=it._sent=it.arg;else if(it.method==="throw"){if(mt===w)throw mt=j,it.arg;it.dispatchException(it.arg)}else it.method==="return"&&it.abrupt("return",it.arg);mt=U;var nt=M(_,rt,it);if(nt.type==="normal"){if(mt=it.done?j:V,nt.arg===G)continue;return{value:nt.arg,done:it.done}}nt.type==="throw"&&(mt=j,it.method="throw",it.arg=nt.arg)}}}function Q(_,rt){var it=rt.method,mt=_.iterator[it];if(mt===h)return rt.delegate=null,it==="throw"&&_.iterator.return&&(rt.method="return",rt.arg=h,Q(_,rt),rt.method==="throw")||it!=="return"&&(rt.method="throw",rt.arg=new TypeError("The iterator does not provide a '"+it+"' method")),G;var ot=M(mt,_.iterator,rt.arg);if(ot.type==="throw")return rt.method="throw",rt.arg=ot.arg,rt.delegate=null,G;var et=ot.arg;return et?et.done?(rt[_.resultName]=et.value,rt.next=_.nextLoc,rt.method!=="return"&&(rt.method="next",rt.arg=h),rt.delegate=null,G):et:(rt.method="throw",rt.arg=new TypeError("iterator result is not an object"),rt.delegate=null,G)}function X(_){var rt={tryLoc:_[0]};1 in _&&(rt.catchLoc=_[1]),2 in _&&(rt.finallyLoc=_[2],rt.afterLoc=_[3]),this.tryEntries.push(rt)}function at(_){var rt=_.completion||{};rt.type="normal",delete rt.arg,_.completion=rt}function ft(_){this.tryEntries=[{tryLoc:"root"}],_.forEach(X,this),this.reset(!0)}function dt(_){if(_||_===""){var rt=_[S];if(rt)return rt.call(_);if(typeof _.next=="function")return _;if(!isNaN(_.length)){var it=-1,mt=function(){function ot(){for(;++it<_.length;)if(I.call(_,it))return ot.value=_[it],ot.done=!1,ot;return ot.value=h,ot.done=!0,ot}return ot}();return mt.next=mt}}throw new TypeError(typeof _+" is not iterable")}return x.prototype=B,O(W,"constructor",{value:B,configurable:!0}),O(B,"constructor",{value:x,configurable:!0}),x.displayName=A(B,b,"GeneratorFunction"),m.isGeneratorFunction=function(_){var rt=typeof _=="function"&&_.constructor;return!!rt&&(rt===x||(rt.displayName||rt.name)==="GeneratorFunction")},m.mark=function(_){return Object.setPrototypeOf?Object.setPrototypeOf(_,B):(_.__proto__=B,A(_,b,"GeneratorFunction")),_.prototype=Object.create(W),_},m.awrap=function(_){return{__await:_}},q(ut.prototype),A(ut.prototype,T,function(){return this}),m.AsyncIterator=ut,m.async=function(_,rt,it,mt,ot){ot===void 0&&(ot=Promise);var et=new ut(P(_,rt,it,mt),ot);return m.isGeneratorFunction(rt)?et:et.next().then(function(k){return k.done?k.value:et.next()})},q(W),A(W,b,"Generator"),A(W,S,function(){return this}),A(W,"toString",function(){return"[object Generator]"}),m.keys=function(_){var rt=Object(_),it=[];for(var mt in rt)it.push(mt);return it.reverse(),function(){function ot(){for(;it.length;){var et=it.pop();if(et in rt)return ot.value=et,ot.done=!1,ot}return ot.done=!0,ot}return ot}()},m.values=dt,ft.prototype={constructor:ft,reset:function(){function _(rt){if(this.prev=0,this.next=0,this.sent=this._sent=h,this.done=!1,this.delegate=null,this.method="next",this.arg=h,this.tryEntries.forEach(at),!rt)for(var it in this)it.charAt(0)==="t"&&I.call(this,it)&&!isNaN(+it.slice(1))&&(this[it]=h)}return _}(),stop:function(){function _(){this.done=!0;var rt=this.tryEntries[0].completion;if(rt.type==="throw")throw rt.arg;return this.rval}return _}(),dispatchException:function(){function _(rt){if(this.done)throw rt;var it=this;function mt(pt,Et){return k.type="throw",k.arg=rt,it.next=pt,Et&&(it.method="next",it.arg=h),!!Et}for(var ot=this.tryEntries.length-1;ot>=0;--ot){var et=this.tryEntries[ot],k=et.completion;if(et.tryLoc==="root")return mt("end");if(et.tryLoc<=this.prev){var tt=I.call(et,"catchLoc"),nt=I.call(et,"finallyLoc");if(tt&&nt){if(this.prev=0;--mt){var ot=this.tryEntries[mt];if(ot.tryLoc<=this.prev&&I.call(ot,"finallyLoc")&&this.prev=0;--it){var mt=this.tryEntries[it];if(mt.finallyLoc===rt)return this.complete(mt.completion,mt.afterLoc),at(mt),G}}return _}(),catch:function(){function _(rt){for(var it=this.tryEntries.length-1;it>=0;--it){var mt=this.tryEntries[it];if(mt.tryLoc===rt){var ot=mt.completion;if(ot.type==="throw"){var et=ot.arg;at(mt)}return et}}throw Error("illegal catch attempt")}return _}(),delegateYield:function(){function _(rt,it,mt){return this.delegate={iterator:dt(rt),resultName:it,nextLoc:mt},this.method==="next"&&(this.arg=h),G}return _}()},m}function p(h,m,E,I,O,C,S){try{var T=h[C](S),b=T.value}catch(A){return void E(A)}T.done?m(b):Promise.resolve(b).then(I,O)}function f(h){return function(){var m=this,E=arguments;return new Promise(function(I,O){var C=h.apply(m,E);function S(b){p(C,I,O,S,T,"next",b)}function T(b){p(C,I,O,S,T,"throw",b)}S(void 0)})}}function i(h,m){h.prototype=Object.create(m.prototype),h.prototype.constructor=h,d(h,m)}function d(h,m){return d=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(E,I){return E.__proto__=I,E},d(h,m)}var c=function(h){return h[h.NORTH=1]="NORTH",h[h.SOUTH=2]="SOUTH",h[h.EAST=4]="EAST",h[h.WEST=8]="WEST",h[h.NORTHEAST=5]="NORTHEAST",h[h.NORTHWEST=9]="NORTHWEST",h[h.SOUTHEAST=6]="SOUTHEAST",h[h.SOUTHWEST=10]="SOUTHWEST",h}(c||{}),g,v=e.DmIcon=function(h){function m(I){var O;return O=h.call(this,I)||this,O.state={iconRef:""},O}i(m,h);var E=m.prototype;return E.fetchRefMap=function(){var I=f(l().mark(function(){function C(){var S,T;return l().wrap(function(){function b(A){for(;;)switch(A.prev=A.next){case 0:return A.prev=0,A.next=3,(0,o.fetchRetry)((0,r.resolveAsset)("icon_ref_map.json"));case 3:return S=A.sent,A.next=6,S.json();case 6:T=A.sent,g=T,this.setState({iconRef:T[this.props.icon]||""}),A.next=14;break;case 11:return A.prev=11,A.t0=A.catch(0),A.abrupt("return");case 14:case"end":return A.stop()}}return b}(),C,this,[[0,11]])}return C}()));function O(){return I.apply(this,arguments)}return O}(),E.componentDidMount=function(){function I(){g?this.setState({iconRef:g[this.props.icon]}):this.fetchRefMap()}return I}(),E.componentDidUpdate=function(){function I(O){O.icon!==this.props.icon&&(g?this.setState({iconRef:g[this.props.icon]}):this.fetchRefMap())}return I}(),E.render=function(){function I(){var O=this.props,C=O.className,S=O.direction,T=S===void 0?c.SOUTH:S,b=O.fallback,A=O.frame,P=A===void 0?1:A,M=O.icon_state,w=O.movement,V=w===void 0?!1:w,U=u(O,s),j=this.state.iconRef,G=j+"?state="+M+"&dir="+T+"&movement="+!!V+"&frame="+P;return j?(0,n.normalizeProps)((0,n.createComponentVNode)(2,a.Image,Object.assign({fixErrors:!0,src:G},U))):b||null}return I}(),m}(n.Component)},20342:function(y,e,t){"use strict";e.__esModule=!0,e.DraggableControl=void 0;var n=t(89005),r=t(44879),o=t(35840),a=t(9474);function s(i,d){i.prototype=Object.create(d.prototype),i.prototype.constructor=i,u(i,d)}function u(i,d){return u=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(c,g){return c.__proto__=g,c},u(i,d)}var l=400,p=function(d,c){return d.screenX*c[0]+d.screenY*c[1]},f=e.DraggableControl=function(i){function d(g){var v;return v=i.call(this,g)||this,v.inputRef=(0,n.createRef)(),v.state={originalValue:g.value,value:g.value,dragging:!1,editing:!1,origin:null,suppressingFlicker:!1},v.flickerTimer=null,v.suppressFlicker=function(){var h=v.props.suppressFlicker;h>0&&(v.setState({suppressingFlicker:!0}),clearTimeout(v.flickerTimer),v.flickerTimer=setTimeout(function(){return v.setState({suppressingFlicker:!1})},h))},v.handleDragStart=function(h){var m=v.props,E=m.value,I=m.dragMatrix,O=m.disabled,C=v.state.editing;C||O||(document.body.style["pointer-events"]="none",v.ref=h.currentTarget,v.setState({originalValue:E,dragging:!1,value:E,origin:p(h,I)}),v.timer=setTimeout(function(){v.setState({dragging:!0})},250),v.dragInterval=setInterval(function(){var S=v.state,T=S.dragging,b=S.value,A=v.props.onDrag;T&&A&&A(h,b)},v.props.updateRate||l),document.addEventListener("mousemove",v.handleDragMove),document.addEventListener("mouseup",v.handleDragEnd))},v.handleDragMove=function(h){var m,E=v.props,I=E.minValue,O=E.maxValue,C=E.step,S=E.dragMatrix,T=E.disabled;if(!T){var b=v.ref.offsetWidth/((O-I)/C),A=(m=v.props.stepPixelSize)!=null?m:b;typeof A=="function"&&(A=A(b)),v.setState(function(P){var M=Object.assign({},P),w=P.origin,V=p(h,S)-w;if(P.dragging){var U=Math.trunc(V/A);M.value=(0,r.clamp)(Math.floor(M.originalValue/C)*C+U*C,I,O)}else Math.abs(V)>4&&(M.dragging=!0);return M})}},v.handleDragEnd=function(h){var m=v.props,E=m.onChange,I=m.onDrag,O=v.state,C=O.dragging,S=O.value;if(document.body.style["pointer-events"]="auto",clearTimeout(v.timer),clearInterval(v.dragInterval),v.setState({originalValue:null,dragging:!1,editing:!C,origin:null}),document.removeEventListener("mousemove",v.handleDragMove),document.removeEventListener("mouseup",v.handleDragEnd),C)v.suppressFlicker(),E&&E(h,S),I&&I(h,S);else if(v.inputRef){var T=v.inputRef.current;T.value=S;try{T.focus(),T.select()}catch(b){}}},v}s(d,i);var c=d.prototype;return c.render=function(){function g(){var v=this,h=this.state,m=h.dragging,E=h.editing,I=h.value,O=h.suppressingFlicker,C=this.props,S=C.animated,T=C.value,b=C.unit,A=C.minValue,P=C.maxValue,M=C.format,w=C.onChange,V=C.onDrag,U=C.children,j=C.height,G=C.lineHeight,$=C.fontSize,x=C.disabled,B=T;(m||O)&&(B=I);var F=function(){function W(q){return q+(b?" "+b:"")}return W}(),H=S&&!m&&!O&&(0,n.createComponentVNode)(2,a.AnimatedNumber,{value:B,format:M,children:F})||F(M?M(B):B),K=(0,n.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:!E||x?"none":void 0,height:j,"line-height":G,"font-size":$},onBlur:function(){function W(q){if(E){var ut=(0,r.clamp)(parseFloat(q.target.value),A,P);if(Number.isNaN(ut)){v.setState({editing:!1});return}v.setState({editing:!1,value:ut}),v.suppressFlicker(),w&&w(q,ut),V&&V(q,ut)}}return W}(),onKeyDown:function(){function W(q){if(q.keyCode===13){var ut=(0,r.clamp)(parseFloat(q.target.value),A,P);if(Number.isNaN(ut)){v.setState({editing:!1});return}v.setState({editing:!1,value:ut}),v.suppressFlicker(),w&&w(q,ut),V&&V(q,ut);return}if(q.keyCode===27){v.setState({editing:!1});return}}return W}(),disabled:x},null,this.inputRef);return U({dragging:m,editing:E,value:T,displayValue:B,displayElement:H,inputElement:K,handleDragStart:this.handleDragStart})}return g}(),d}(n.Component);f.defaultHooks=o.pureComponentHooks,f.defaultProps={minValue:-1/0,maxValue:1/0,step:1,suppressFlicker:50,dragMatrix:[1,0]}},87099:function(y,e,t){"use strict";e.__esModule=!0,e.Dropdown=void 0;var n=t(89005),r=t(95996),o=t(35840),a=t(55937),s=t(96184),u=t(1331),l=t(96690),p=["icon","iconRotation","iconSpin","clipSelectedText","color","dropdownStyle","over","nochevron","width","onClick","onSelected","selected","disabled","displayText","buttons"],f=["className"],i;function d(O,C){if(O==null)return{};var S={};for(var T in O)if({}.hasOwnProperty.call(O,T)){if(C.includes(T))continue;S[T]=O[T]}return S}function c(O,C){O.prototype=Object.create(C.prototype),O.prototype.constructor=O,g(O,C)}function g(O,C){return g=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(S,T){return S.__proto__=T,S},g(O,C)}var v={placement:"left-start",modifiers:[{name:"eventListeners",enabled:!1}]},h={width:0,height:0,top:0,right:0,bottom:0,left:0,x:0,y:0,toJSON:function(){function O(){return null}return O}()},m="Layout Dropdown__menu",E="Layout Dropdown__menu-scroll",I=e.Dropdown=function(O){function C(T){var b;return b=O.call(this,T)||this,b.menuContents=void 0,b.handleClick=function(){b.state.open&&b.setOpen(!1)},b.state={open:!1,selected:b.props.selected},b.menuContents=null,b}c(C,O);var S=C.prototype;return S.getDOMNode=function(){function T(){return(0,n.findDOMFromVNode)(this.$LI,!0)}return T}(),S.componentDidMount=function(){function T(){var b=this.getDOMNode()}return T}(),S.openMenu=function(){function T(){var b=C.renderedMenu;b===void 0&&(b=document.createElement("div"),b.className=m,document.body.appendChild(b),C.renderedMenu=b);var A=this.getDOMNode();C.currentOpenMenu=A,b.scrollTop=0,b.style.width=this.props.menuWidth||A.offsetWidth+"px",b.style.opacity="1",b.style.pointerEvents="auto",setTimeout(function(){var P;(P=C.renderedMenu)==null||P.focus()},400),this.renderMenuContent()}return T}(),S.closeMenu=function(){function T(){C.currentOpenMenu===this.getDOMNode()&&(C.currentOpenMenu=void 0,C.renderedMenu.style.opacity="0",C.renderedMenu.style.pointerEvents="none")}return T}(),S.componentWillUnmount=function(){function T(){this.closeMenu(),this.setOpen(!1)}return T}(),S.renderMenuContent=function(){function T(){var b=this,A=C.renderedMenu;if(A){A.offsetHeight>200?A.className=E:A.className=m;var P=this.props.options,M=P===void 0?[]:P,w=M.map(function(U){var j,G;return typeof U=="string"?(G=U,j=U):U!==null&&(G=U.displayText,j=U.value),(0,n.createVNode)(1,"div",(0,o.classes)(["Dropdown__menuentry",b.state.selected===j&&"selected"]),G,0,{onClick:function(){function $(){b.setSelected(j)}return $}()},j)}),V=w.length?w:"No Options Found";(0,n.render)((0,n.createVNode)(1,"div",null,V,0),A,function(){var U=C.singletonPopper;U===void 0?(U=(0,r.createPopper)(C.virtualElement,A,Object.assign({},v,{placement:"bottom-start"})),C.singletonPopper=U):(U.setOptions(Object.assign({},v,{placement:"bottom-start"})),U.update())},this.context)}}return T}(),S.setOpen=function(){function T(b){var A=this;this.setState(function(P){return Object.assign({},P,{open:b})}),b?setTimeout(function(){A.openMenu(),window.addEventListener("click",A.handleClick)}):(this.closeMenu(),window.removeEventListener("click",this.handleClick))}return T}(),S.setSelected=function(){function T(b){this.setState(function(A){return Object.assign({},A,{selected:b})}),this.setOpen(!1),this.props.onSelected&&this.props.onSelected(b)}return T}(),S.getOptionValue=function(){function T(b){return typeof b=="string"?b:b.value}return T}(),S.getSelectedIndex=function(){function T(){var b=this,A=this.state.selected||this.props.selected,P=this.props.options,M=P===void 0?[]:P;return M.findIndex(function(w){return b.getOptionValue(w)===A})}return T}(),S.toPrevious=function(){function T(){if(!(this.props.options.length<1)){var b=this.getSelectedIndex(),A=0,P=this.props.options.length-1,M=b>=0;M||(b=A);var w=b===A?P:b-1;this.setSelected(this.getOptionValue(this.props.options[w]))}}return T}(),S.toNext=function(){function T(){if(!(this.props.options.length<1)){var b=this.getSelectedIndex(),A=0,P=this.props.options.length-1,M=b>=0;M||(b=P);var w=b===P?A:b+1;this.setSelected(this.getOptionValue(this.props.options[w]))}}return T}(),S.render=function(){function T(){var b=this,A=this.props,P=A.icon,M=A.iconRotation,w=A.iconSpin,V=A.clipSelectedText,U=V===void 0?!0:V,j=A.color,G=j===void 0?"default":j,$=A.dropdownStyle,x=A.over,B=A.nochevron,F=A.width,H=A.onClick,K=A.onSelected,W=A.selected,q=A.disabled,ut=A.displayText,ct=A.buttons,Q=d(A,p),X=Q.className,at=d(Q,f),ft=x?!this.state.open:this.state.open;return(0,n.createComponentVNode)(2,l.Stack,{inline:!0,fill:!0,width:F,children:[(0,n.createComponentVNode)(2,l.Stack.Item,{grow:!0,children:(0,n.normalizeProps)((0,n.createComponentVNode)(2,a.Box,Object.assign({width:"100%",className:(0,o.classes)(["Dropdown__control","Button","Button--color--"+G,q&&"Button--disabled",X]),onClick:function(){function dt(_){q&&!b.state.open||(b.setOpen(!b.state.open),H&&H(_))}return dt}()},at,{children:[P&&(0,n.createComponentVNode)(2,u.Icon,{name:P,rotation:M,spin:w,mr:1}),(0,n.createVNode)(1,"span","Dropdown__selected-text",ut||this.state.selected,0,{style:{overflow:U?"hidden":"visible"}}),B||(0,n.createVNode)(1,"span","Dropdown__arrow-button",(0,n.createComponentVNode)(2,u.Icon,{name:ft?"chevron-up":"chevron-down"}),2)]})))}),ct&&(0,n.createFragment)([(0,n.createComponentVNode)(2,l.Stack.Item,{height:"100%",children:(0,n.createComponentVNode)(2,s.Button,{height:"100%",icon:"chevron-left",disabled:q,onClick:function(){function dt(){q||b.toPrevious()}return dt}()})}),(0,n.createComponentVNode)(2,l.Stack.Item,{height:"100%",children:(0,n.createComponentVNode)(2,s.Button,{height:"100%",icon:"chevron-right",disabled:q,onClick:function(){function dt(){q||b.toNext()}return dt}()})})],4)]})}return T}(),C}(n.Component);i=I,I.renderedMenu=void 0,I.singletonPopper=void 0,I.currentOpenMenu=void 0,I.virtualElement={getBoundingClientRect:function(){function O(){var C,S;return(C=(S=i.currentOpenMenu)==null?void 0:S.getBoundingClientRect())!=null?C:h}return O}()}},39473:function(y,e,t){"use strict";e.__esModule=!0,e.computeFlexProps=e.computeFlexItemProps=e.computeFlexItemClassName=e.computeFlexClassName=e.Flex=void 0;var n=t(89005),r=t(35840),o=t(55937),a=["className","direction","wrap","align","justify","inline","style"],s=["className"],u=["className","style","grow","order","shrink","basis","align"],l=["className"];/** * @file * @copyright 2020 Aleksej Komarov * @license MIT - */function p(h,m){if(h==null)return{};var E={};for(var I in h)if({}.hasOwnProperty.call(h,I)){if(m.includes(I))continue;E[I]=h[I]}return E}var f=e.computeFlexClassName=function(){function h(m){return(0,r.classes)(["Flex",m.inline&&"Flex--inline",(0,o.computeBoxClassName)(m)])}return h}(),i=e.computeFlexProps=function(){function h(m){var E=m.className,I=m.direction,O=m.wrap,b=m.align,S=m.justify,T=m.inline,C=m.style,A=p(m,a);return(0,o.computeBoxProps)(Object.assign({style:Object.assign({},C,{"flex-direction":I,"flex-wrap":O===!0?"wrap":O,"align-items":b,"justify-content":S})},A))}return h}(),d=e.Flex=function(){function h(m){var E=m.className,I=p(m,s);return(0,n.normalizeProps)((0,n.createVNode)(1,"div",(0,r.classes)([E,f(I)]),null,1,Object.assign({},i(I))))}return h}();d.defaultHooks=r.pureComponentHooks;var c=e.computeFlexItemClassName=function(){function h(m){return(0,r.classes)(["Flex__item",(0,o.computeBoxClassName)(m)])}return h}(),g=e.computeFlexItemProps=function(){function h(m){var E=m.className,I=m.style,O=m.grow,b=m.order,S=m.shrink,T=m.basis,C=T===void 0?m.width:T,A=m.align,P=p(m,u);return(0,o.computeBoxProps)(Object.assign({style:Object.assign({},I,{"flex-grow":O!==void 0&&Number(O),"flex-shrink":S!==void 0&&Number(S),"flex-basis":(0,o.unit)(C),order:b,"align-self":A})},P))}return h}(),v=function(m){var E=m.className,I=p(m,l);return(0,n.normalizeProps)((0,n.createVNode)(1,"div",(0,r.classes)([E,c(m)]),null,1,Object.assign({},g(I))))};v.defaultHooks=r.pureComponentHooks,d.Item=v},79646:function(y,e,t){"use strict";e.__esModule=!0,e.GridColumn=e.Grid=void 0;var n=t(89005),r=t(36352),o=t(35840),a=["children"],s=["size","style"];/** + */function p(h,m){if(h==null)return{};var E={};for(var I in h)if({}.hasOwnProperty.call(h,I)){if(m.includes(I))continue;E[I]=h[I]}return E}var f=e.computeFlexClassName=function(){function h(m){return(0,r.classes)(["Flex",m.inline&&"Flex--inline",(0,o.computeBoxClassName)(m)])}return h}(),i=e.computeFlexProps=function(){function h(m){var E=m.className,I=m.direction,O=m.wrap,C=m.align,S=m.justify,T=m.inline,b=m.style,A=p(m,a);return(0,o.computeBoxProps)(Object.assign({style:Object.assign({},b,{"flex-direction":I,"flex-wrap":O===!0?"wrap":O,"align-items":C,"justify-content":S})},A))}return h}(),d=e.Flex=function(){function h(m){var E=m.className,I=p(m,s);return(0,n.normalizeProps)((0,n.createVNode)(1,"div",(0,r.classes)([E,f(I)]),null,1,Object.assign({},i(I))))}return h}();d.defaultHooks=r.pureComponentHooks;var c=e.computeFlexItemClassName=function(){function h(m){return(0,r.classes)(["Flex__item",(0,o.computeBoxClassName)(m)])}return h}(),g=e.computeFlexItemProps=function(){function h(m){var E=m.className,I=m.style,O=m.grow,C=m.order,S=m.shrink,T=m.basis,b=T===void 0?m.width:T,A=m.align,P=p(m,u);return(0,o.computeBoxProps)(Object.assign({style:Object.assign({},I,{"flex-grow":O!==void 0&&Number(O),"flex-shrink":S!==void 0&&Number(S),"flex-basis":(0,o.unit)(b),order:C,"align-self":A})},P))}return h}(),v=function(m){var E=m.className,I=p(m,l);return(0,n.normalizeProps)((0,n.createVNode)(1,"div",(0,r.classes)([E,c(m)]),null,1,Object.assign({},g(I))))};v.defaultHooks=r.pureComponentHooks,d.Item=v},79646:function(y,e,t){"use strict";e.__esModule=!0,e.GridColumn=e.Grid=void 0;var n=t(89005),r=t(36352),o=t(35840),a=["children"],s=["size","style"];/** * @file * @copyright 2020 Aleksej Komarov * @license MIT @@ -300,19 +300,19 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT - */function u(i,d){if(i==null)return{};var c={};for(var g in i)if({}.hasOwnProperty.call(i,g)){if(d.includes(g))continue;c[g]=i[g]}return c}var l=/-o$/,p=e.Icon=function(){function i(d){var c=d.name,g=d.size,v=d.spin,h=d.className,m=d.style,E=m===void 0?{}:m,I=d.rotation,O=d.inverse,b=u(d,a);g&&(E["font-size"]=g*100+"%"),typeof I=="number"&&(E.transform="rotate("+I+"deg)");var S=l.test(c),T=c.replace(l,"");return(0,n.normalizeProps)((0,n.createComponentVNode)(2,o.Box,Object.assign({as:"i",className:(0,r.classes)(["Icon",h,S?"far":"fas","fa-"+T,v&&"fa-spin"]),style:E},b)))}return i}();p.defaultHooks=r.pureComponentHooks;var f=e.IconStack=function(){function i(d){var c=d.className,g=d.style,v=g===void 0?{}:g,h=d.children,m=u(d,s);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,o.Box,Object.assign({as:"span",class:(0,r.classes)(["IconStack",c]),style:v},m,{children:h})))}return i}();p.Stack=f},91225:function(y,e,t){"use strict";e.__esModule=!0,e.Image=void 0;var n=t(89005),r=t(55937),o=["fixBlur","fixErrors","objectFit","src"];function a(f,i){if(f==null)return{};var d={};for(var c in f)if({}.hasOwnProperty.call(f,c)){if(i.includes(c))continue;d[c]=f[c]}return d}function s(f,i){f.prototype=Object.create(i.prototype),f.prototype.constructor=f,u(f,i)}function u(f,i){return u=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(d,c){return d.__proto__=c,d},u(f,i)}var l=5,p=e.Image=function(f){function i(){for(var c,g=arguments.length,v=new Array(g),h=0;h0;h&&(v=c.containerRef)!=null&&v.current?c.props.onMove(u(c.containerRef.current,g)):c.toggleDocumentEvents(!1)},c.handleMoveEnd=function(){c.toggleDocumentEvents(!1)},c.handleKeyDown=function(g){var v=g.which||g.keyCode;v<37||v>40||(g.preventDefault(),c.props.onKey({left:v===39?.05:v===37?-.05:0,top:v===40?.05:v===38?-.05:0}))},c.props=d,c.containerRef=(0,n.createRef)(),c}o(f,p);var i=f.prototype;return i.toggleDocumentEvents=function(){function d(c){var g,v=(g=this.containerRef)==null?void 0:g.current,h=s(v),m=c?h.addEventListener:h.removeEventListener;m("mousemove",this.handleMove),m("mouseup",this.handleMoveEnd)}return d}(),i.componentDidMount=function(){function d(){this.toggleDocumentEvents(!0)}return d}(),i.componentWillUnmount=function(){function d(){this.toggleDocumentEvents(!1)}return d}(),i.render=function(){function d(){return(0,n.normalizeProps)((0,n.createVNode)(1,"div","react-colorful__interactive",this.props.children,0,Object.assign({},this.props,{style:this.props.style,onMouseDown:this.handleMoveStart,onKeyDown:this.handleKeyDown,tabIndex:0,role:"slider"}),null,this.containerRef))}return d}(),f}(n.Component)},76334:function(y,e,t){"use strict";e.__esModule=!0,e.Knob=void 0;var n=t(89005),r=t(44879),o=t(35840),a=t(55937),s=t(20342),u=t(59263),l=["animated","format","maxValue","minValue","onChange","onDrag","step","stepPixelSize","suppressFlicker","unit","value","className","style","fillValue","color","ranges","size","bipolar","children","popUpPosition"];/** +*/var i=e.toInputValue=function(){function c(g){return typeof g!="number"&&typeof g!="string"?"":String(g)}return c}(),d=e.Input=function(c){function g(){var h;return h=c.call(this)||this,h.inputRef=(0,n.createRef)(),h.state={editing:!1},h.handleInput=function(m){var E=h.state.editing,I=h.props.onInput;E||h.setEditing(!0),I&&I(m,m.target.value)},h.handleFocus=function(m){var E=h.state.editing;E||h.setEditing(!0)},h.handleBlur=function(m){var E=h.state.editing,I=h.props.onChange;E&&(h.setEditing(!1),I&&I(m,m.target.value))},h.handleKeyDown=function(m){var E=h.props,I=E.onInput,O=E.onChange,C=E.onEnter;if(m.keyCode===a.KEY_ENTER){h.setEditing(!1),O&&O(m,m.target.value),I&&I(m,m.target.value),C&&C(m,m.target.value),h.props.selfClear?m.target.value="":m.target.blur();return}if(m.keyCode===a.KEY_ESCAPE){h.setEditing(!1),m.target.value=i(h.props.value),m.target.blur();return}},h}p(g,c);var v=g.prototype;return v.componentDidMount=function(){function h(){var m=this,E=this.props.value,I=this.inputRef.current;I&&(I.value=i(E),I.selectionStart=0,I.selectionEnd=I.value.length),(this.props.autoFocus||this.props.autoSelect)&&setTimeout(function(){I.focus(),m.props.autoSelect&&I.select()},1)}return h}(),v.componentDidUpdate=function(){function h(m,E){var I=this.state.editing,O=m.value,C=this.props.value,S=this.inputRef.current;S&&!I&&O!==C&&(S.value=i(C))}return h}(),v.setEditing=function(){function h(m){this.setState({editing:m})}return h}(),v.render=function(){function h(){var m=this.props,E=m.selfClear,I=m.onInput,O=m.onChange,C=m.onEnter,S=m.value,T=m.maxLength,b=m.placeholder,A=m.autofocus,P=m.disabled,M=m.multiline,w=m.cols,V=w===void 0?32:w,U=m.rows,j=U===void 0?4:U,G=l(m,s),$=G.className,x=G.fluid,B=G.monospace,F=l(G,u);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,o.Box,Object.assign({className:(0,r.classes)(["Input",x&&"Input--fluid",B&&"Input--monospace",P&&"Input--disabled",$])},F,{children:[(0,n.createVNode)(1,"div","Input__baseline",".",16),M?(0,n.createVNode)(128,"textarea","Input__textarea",null,1,{placeholder:b,onInput:this.handleInput,onFocus:this.handleFocus,onBlur:this.handleBlur,maxLength:T,cols:V,rows:j,disabled:P},null,this.inputRef):(0,n.createVNode)(64,"input","Input__input",null,1,{placeholder:b,onInput:this.handleInput,onFocus:this.handleFocus,onBlur:this.handleBlur,onKeyDown:this.handleKeyDown,maxLength:T,disabled:P},null,this.inputRef)]})))}return h}(),g}(n.Component)},4454:function(y,e,t){"use strict";e.__esModule=!0,e.Interactive=void 0;var n=t(89005),r=t(44879);function o(p,f){p.prototype=Object.create(f.prototype),p.prototype.constructor=p,a(p,f)}function a(p,f){return a=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(i,d){return i.__proto__=d,i},a(p,f)}var s=function(f){return f&&f.ownerDocument.defaultView||self},u=function(f,i){var d=f.getBoundingClientRect(),c=i;return{left:(0,r.clamp)((c.pageX-(d.left+s(f).pageXOffset))/d.width,0,1),top:(0,r.clamp)((c.pageY-(d.top+s(f).pageYOffset))/d.height,0,1)}},l=e.Interactive=function(p){function f(d){var c;return c=p.call(this)||this,c.containerRef=void 0,c.props=void 0,c.handleMoveStart=function(g){var v,h=(v=c.containerRef)==null?void 0:v.current;h&&(g.preventDefault(),h.focus(),c.props.onMove(u(h,g)),c.toggleDocumentEvents(!0))},c.handleMove=function(g){var v;g.preventDefault();var h=g.buttons>0;h&&(v=c.containerRef)!=null&&v.current?c.props.onMove(u(c.containerRef.current,g)):c.toggleDocumentEvents(!1)},c.handleMoveEnd=function(){c.toggleDocumentEvents(!1)},c.handleKeyDown=function(g){var v=g.which||g.keyCode;v<37||v>40||(g.preventDefault(),c.props.onKey({left:v===39?.05:v===37?-.05:0,top:v===40?.05:v===38?-.05:0}))},c.props=d,c.containerRef=(0,n.createRef)(),c}o(f,p);var i=f.prototype;return i.toggleDocumentEvents=function(){function d(c){var g,v=(g=this.containerRef)==null?void 0:g.current,h=s(v),m=c?h.addEventListener:h.removeEventListener;m("mousemove",this.handleMove),m("mouseup",this.handleMoveEnd)}return d}(),i.componentDidMount=function(){function d(){this.toggleDocumentEvents(!0)}return d}(),i.componentWillUnmount=function(){function d(){this.toggleDocumentEvents(!1)}return d}(),i.render=function(){function d(){return(0,n.normalizeProps)((0,n.createVNode)(1,"div","react-colorful__interactive",this.props.children,0,Object.assign({},this.props,{style:this.props.style,onMouseDown:this.handleMoveStart,onKeyDown:this.handleKeyDown,tabIndex:0,role:"slider"}),null,this.containerRef))}return d}(),f}(n.Component)},76334:function(y,e,t){"use strict";e.__esModule=!0,e.Knob=void 0;var n=t(89005),r=t(44879),o=t(35840),a=t(55937),s=t(20342),u=t(59263),l=["animated","format","maxValue","minValue","onChange","onDrag","step","stepPixelSize","suppressFlicker","unit","value","className","style","fillValue","color","ranges","size","bipolar","children","popUpPosition"];/** * @file * @copyright 2020 Aleksej Komarov * @license MIT - */function p(i,d){if(i==null)return{};var c={};for(var g in i)if({}.hasOwnProperty.call(i,g)){if(d.includes(g))continue;c[g]=i[g]}return c}var f=e.Knob=function(){function i(d){var c=d.animated,g=d.format,v=d.maxValue,h=d.minValue,m=d.onChange,E=d.onDrag,I=d.step,O=d.stepPixelSize,b=d.suppressFlicker,S=d.unit,T=d.value,C=d.className,A=d.style,P=d.fillValue,M=d.color,w=d.ranges,V=w===void 0?{}:w,U=d.size,j=U===void 0?1:U,G=d.bipolar,$=d.children,x=d.popUpPosition,B=p(d,l);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,s.DraggableControl,Object.assign({dragMatrix:[0,-1]},{animated:c,format:g,maxValue:v,minValue:h,onChange:m,onDrag:E,step:I,stepPixelSize:O,suppressFlicker:b,unit:S,value:T},{children:function(){function F(H){var K=H.dragging,W=H.editing,q=H.value,ut=H.displayValue,ct=H.displayElement,Q=H.inputElement,X=H.handleDragStart,at=(0,r.scale)(P!=null?P:ut,h,v),ft=(0,r.scale)(ut,h,v),dt=M||(0,r.keyOfMatchingRange)(P!=null?P:q,V)||"default",_=(ft-.5)*270;return(0,n.normalizeProps)((0,n.createVNode)(1,"div",(0,o.classes)(["Knob","Knob--color--"+dt,G&&"Knob--bipolar",C,(0,a.computeBoxClassName)(B)]),[(0,n.createVNode)(1,"div","Knob__circle",(0,n.createVNode)(1,"div","Knob__cursorBox",(0,n.createVNode)(1,"div","Knob__cursor"),2,{style:{transform:"rotate("+_+"deg)"}}),2),K&&(0,n.createVNode)(1,"div",(0,o.classes)(["Knob__popupValue",x&&"Knob__popupValue--"+x]),ct,0),(0,n.createVNode)(32,"svg","Knob__ring Knob__ringTrackPivot",(0,n.createVNode)(32,"circle","Knob__ringTrack",null,1,{cx:"50",cy:"50",r:"50"}),2,{viewBox:"0 0 100 100"}),(0,n.createVNode)(32,"svg","Knob__ring Knob__ringFillPivot",(0,n.createVNode)(32,"circle","Knob__ringFill",null,1,{style:{"stroke-dashoffset":((G?2.75:2)-at*1.5)*Math.PI*50},cx:"50",cy:"50",r:"50"}),2,{viewBox:"0 0 100 100"}),Q],0,Object.assign({},(0,a.computeBoxProps)(Object.assign({style:Object.assign({"font-size":j+"em"},A)},B)),{onMouseDown:X})))}return F}()})))}return i}()},78621:function(y,e,t){"use strict";e.__esModule=!0,e.LabeledControls=void 0;var n=t(89005),r=t(39473),o=["children"],a=["label","children"];/** + */function p(i,d){if(i==null)return{};var c={};for(var g in i)if({}.hasOwnProperty.call(i,g)){if(d.includes(g))continue;c[g]=i[g]}return c}var f=e.Knob=function(){function i(d){var c=d.animated,g=d.format,v=d.maxValue,h=d.minValue,m=d.onChange,E=d.onDrag,I=d.step,O=d.stepPixelSize,C=d.suppressFlicker,S=d.unit,T=d.value,b=d.className,A=d.style,P=d.fillValue,M=d.color,w=d.ranges,V=w===void 0?{}:w,U=d.size,j=U===void 0?1:U,G=d.bipolar,$=d.children,x=d.popUpPosition,B=p(d,l);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,s.DraggableControl,Object.assign({dragMatrix:[0,-1]},{animated:c,format:g,maxValue:v,minValue:h,onChange:m,onDrag:E,step:I,stepPixelSize:O,suppressFlicker:C,unit:S,value:T},{children:function(){function F(H){var K=H.dragging,W=H.editing,q=H.value,ut=H.displayValue,ct=H.displayElement,Q=H.inputElement,X=H.handleDragStart,at=(0,r.scale)(P!=null?P:ut,h,v),ft=(0,r.scale)(ut,h,v),dt=M||(0,r.keyOfMatchingRange)(P!=null?P:q,V)||"default",_=(ft-.5)*270;return(0,n.normalizeProps)((0,n.createVNode)(1,"div",(0,o.classes)(["Knob","Knob--color--"+dt,G&&"Knob--bipolar",b,(0,a.computeBoxClassName)(B)]),[(0,n.createVNode)(1,"div","Knob__circle",(0,n.createVNode)(1,"div","Knob__cursorBox",(0,n.createVNode)(1,"div","Knob__cursor"),2,{style:{transform:"rotate("+_+"deg)"}}),2),K&&(0,n.createVNode)(1,"div",(0,o.classes)(["Knob__popupValue",x&&"Knob__popupValue--"+x]),ct,0),(0,n.createVNode)(32,"svg","Knob__ring Knob__ringTrackPivot",(0,n.createVNode)(32,"circle","Knob__ringTrack",null,1,{cx:"50",cy:"50",r:"50"}),2,{viewBox:"0 0 100 100"}),(0,n.createVNode)(32,"svg","Knob__ring Knob__ringFillPivot",(0,n.createVNode)(32,"circle","Knob__ringFill",null,1,{style:{"stroke-dashoffset":((G?2.75:2)-at*1.5)*Math.PI*50},cx:"50",cy:"50",r:"50"}),2,{viewBox:"0 0 100 100"}),Q],0,Object.assign({},(0,a.computeBoxProps)(Object.assign({style:Object.assign({"font-size":j+"em"},A)},B)),{onMouseDown:X})))}return F}()})))}return i}()},78621:function(y,e,t){"use strict";e.__esModule=!0,e.LabeledControls=void 0;var n=t(89005),r=t(39473),o=["children"],a=["label","children"];/** * @file * @copyright 2020 Aleksej Komarov * @license MIT @@ -320,11 +320,11 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var u=e.LabeledList=function(){function f(i){var d=i.children;return(0,n.createVNode)(1,"table","LabeledList",d,0)}return f}();u.defaultHooks=r.pureComponentHooks;var l=function(i){var d=i.className,c=i.label,g=i.labelColor,v=g===void 0?"label":g,h=i.color,m=i.textAlign,E=i.buttons,I=i.tooltip,O=i.content,b=i.children,S=i.preserveWhitespace,T=i.labelStyle,C=(0,n.createVNode)(1,"tr",(0,r.classes)(["LabeledList__row",d]),[(0,n.createComponentVNode)(2,o.Box,{as:"td",color:v,className:(0,r.classes)(["LabeledList__cell","LabeledList__label"]),style:T,children:c?c+":":null}),(0,n.createComponentVNode)(2,o.Box,{as:"td",color:h,textAlign:m,className:(0,r.classes)(["LabeledList__cell","LabeledList__content"]),colSpan:E?void 0:2,preserveWhitespace:S,children:[O,b]}),E&&(0,n.createVNode)(1,"td","LabeledList__cell LabeledList__buttons",E,0)],0);return I&&(C=(0,n.createComponentVNode)(2,s.Tooltip,{content:I,children:C})),C};l.defaultHooks=r.pureComponentHooks;var p=function(i){var d=i.size?(0,o.unit)(Math.max(0,i.size-1)):0;return(0,n.createVNode)(1,"tr","LabeledList__row",(0,n.createVNode)(1,"td",null,(0,n.createComponentVNode)(2,a.Divider),2,{colSpan:3,style:{"padding-top":d,"padding-bottom":d}}),2)};p.defaultHooks=r.pureComponentHooks,u.Item=l,u.Divider=p},36077:function(y,e,t){"use strict";e.__esModule=!0,e.Modal=void 0;var n=t(89005),r=t(35840),o=t(55937),a=t(61940),s=["className","children","onEnter"];/** + */var u=e.LabeledList=function(){function f(i){var d=i.children;return(0,n.createVNode)(1,"table","LabeledList",d,0)}return f}();u.defaultHooks=r.pureComponentHooks;var l=function(i){var d=i.className,c=i.label,g=i.labelColor,v=g===void 0?"label":g,h=i.color,m=i.textAlign,E=i.buttons,I=i.tooltip,O=i.content,C=i.children,S=i.preserveWhitespace,T=i.labelStyle,b=(0,n.createVNode)(1,"tr",(0,r.classes)(["LabeledList__row",d]),[(0,n.createComponentVNode)(2,o.Box,{as:"td",color:v,className:(0,r.classes)(["LabeledList__cell","LabeledList__label"]),style:T,children:c?c+":":null}),(0,n.createComponentVNode)(2,o.Box,{as:"td",color:h,textAlign:m,className:(0,r.classes)(["LabeledList__cell","LabeledList__content"]),colSpan:E?void 0:2,preserveWhitespace:S,children:[O,C]}),E&&(0,n.createVNode)(1,"td","LabeledList__cell LabeledList__buttons",E,0)],0);return I&&(b=(0,n.createComponentVNode)(2,s.Tooltip,{content:I,children:b})),b};l.defaultHooks=r.pureComponentHooks;var p=function(i){var d=i.size?(0,o.unit)(Math.max(0,i.size-1)):0;return(0,n.createVNode)(1,"tr","LabeledList__row",(0,n.createVNode)(1,"td",null,(0,n.createComponentVNode)(2,a.Divider),2,{colSpan:3,style:{"padding-top":d,"padding-bottom":d}}),2)};p.defaultHooks=r.pureComponentHooks,u.Item=l,u.Divider=p},36077:function(y,e,t){"use strict";e.__esModule=!0,e.Modal=void 0;var n=t(89005),r=t(35840),o=t(55937),a=t(61940),s=["className","children","onEnter"];/** * @file * @copyright 2020 Aleksej Komarov * @license MIT - */function u(p,f){if(p==null)return{};var i={};for(var d in p)if({}.hasOwnProperty.call(p,d)){if(f.includes(d))continue;i[d]=p[d]}return i}var l=e.Modal=function(){function p(f){var i=f.className,d=f.children,c=f.onEnter,g=u(f,s),v;return c&&(v=function(){function h(m){m.keyCode===13&&c(m)}return h}()),(0,n.createComponentVNode)(2,a.Dimmer,{onKeyDown:v,children:(0,n.normalizeProps)((0,n.createVNode)(1,"div",(0,r.classes)(["Modal",i,(0,o.computeBoxClassName)(g)]),d,0,Object.assign({},(0,o.computeBoxProps)(g))))})}return p}()},73280:function(y,e,t){"use strict";e.__esModule=!0,e.NanoMap=void 0;var n=t(89005),r=t(36036),o=t(72253),a=t(29319),s=t(79911),u=t(79140),l=["x","y","icon","tooltip","color","children"],p=["icon","color"];function f(O,b){if(O==null)return{};var S={};for(var T in O)if({}.hasOwnProperty.call(O,T)){if(b.includes(T))continue;S[T]=O[T]}return S}function i(O,b){O.prototype=Object.create(b.prototype),O.prototype.constructor=O,d(O,b)}function d(O,b){return d=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(S,T){return S.__proto__=T,S},d(O,b)}var c=510,g=2,v=function(b){return b.stopPropagation&&b.stopPropagation(),b.preventDefault&&b.preventDefault(),b.cancelBubble=!0,b.returnValue=!1,!1},h=e.NanoMap=function(O){function b(T){var C,A,P,M;M=O.call(this,T)||this;var w=window.innerWidth/2-256,V=window.innerHeight/2-256;return M.state={offsetX:(C=T.offsetX)!=null?C:0,offsetY:(A=T.offsetY)!=null?A:0,dragging:!1,originX:null,originY:null,zoom:(P=T.zoom)!=null?P:1},M.handleDragStart=function(U){M.ref=U.target,M.setState({dragging:!1,originX:U.screenX,originY:U.screenY}),document.addEventListener("mousemove",M.handleDragMove),document.addEventListener("mouseup",M.handleDragEnd),v(U)},M.handleDragMove=function(U){M.setState(function(j){var G=Object.assign({},j),$=U.screenX-G.originX,x=U.screenY-G.originY;return j.dragging?(G.offsetX+=$/G.zoom,G.offsetY+=x/G.zoom,G.originX=U.screenX,G.originY=U.screenY):G.dragging=!0,G}),v(U)},M.handleDragEnd=function(U){M.setState({dragging:!1,originX:null,originY:null}),document.removeEventListener("mousemove",M.handleDragMove),document.removeEventListener("mouseup",M.handleDragEnd),T.onOffsetChange==null||T.onOffsetChange(U,M.state),v(U)},M.handleZoom=function(U,j){M.setState(function(G){var $=Math.min(Math.max(j,1),8);return G.zoom=$,T.onZoom&&T.onZoom(G.zoom),G})},M.handleReset=function(U){M.setState(function(j){j.offsetX=0,j.offsetY=0,j.zoom=1,M.handleZoom(U,1),T.onOffsetChange==null||T.onOffsetChange(U,j)})},M}i(b,O);var S=b.prototype;return S.getChildContext=function(){function T(){return{map:{zoom:this.state.zoom}}}return T}(),S.render=function(){function T(){var C=(0,o.useBackend)(this.context),A=C.config,P=this.state,M=P.dragging,w=P.offsetX,V=P.offsetY,U=P.zoom,j=U===void 0?1:U,G=this.props.children,$=A.map+"_nanomap_z1.png",x=c*j+"px",B={width:x,height:x,"margin-top":V*j+"px","margin-left":w*j+"px",overflow:"hidden",position:"relative",top:"50%",left:"50%",transform:"translate(-50%, -50%)","background-size":"cover","background-repeat":"no-repeat","text-align":"center",cursor:M?"move":"auto"},F={width:"100%",height:"100%",position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"};return(0,n.createComponentVNode)(2,r.Box,{className:"NanoMap__container",children:[(0,n.createComponentVNode)(2,r.Box,{style:B,onMouseDown:this.handleDragStart,children:[(0,n.createVNode)(1,"img",null,null,1,{src:(0,u.resolveAsset)($),style:F}),(0,n.createComponentVNode)(2,r.Box,{children:G})]}),(0,n.createComponentVNode)(2,I,{zoom:j,onZoom:this.handleZoom,onReset:this.handleReset})]})}return T}(),b}(n.Component),m=function(b,S){var T=S.map.zoom,C=b.x,A=b.y,P=b.icon,M=b.tooltip,w=b.color,V=b.children,U=f(b,l),j=g*T,G=(C-1)*j,$=(A-1)*j;return(0,n.createVNode)(1,"div",null,(0,n.createComponentVNode)(2,r.Tooltip,{content:M,children:(0,n.normalizeProps)((0,n.createComponentVNode)(2,r.Box,Object.assign({position:"absolute",className:"NanoMap__marker",lineHeight:"0",bottom:$+"px",left:G+"px",width:j+"px",height:j+"px"},U,{children:V})))}),2)};h.Marker=m;var E=function(b,S){var T=S.map.zoom,C=b.icon,A=b.color,P=f(b,p),M=g*T+4/Math.ceil(T/4);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,m,Object.assign({},P,{children:(0,n.createComponentVNode)(2,r.Icon,{name:C,color:A,fontSize:M+"px",style:{position:"relative",top:"50%",left:"50%",transform:"translate(-50%, -50%)"}})})))};h.MarkerIcon=E;var I=function(b,S){return(0,n.createComponentVNode)(2,r.Box,{className:"NanoMap__zoomer",children:(0,n.createComponentVNode)(2,a.LabeledList,{children:(0,n.createComponentVNode)(2,a.LabeledList.Item,{label:"Zoom",labelStyle:{"vertical-align":"middle"},children:(0,n.createComponentVNode)(2,r.Flex,{direction:"row",children:[(0,n.createComponentVNode)(2,s.Slider,{minValue:1,maxValue:8,stepPixelSize:10,format:function(){function T(C){return C+"x"}return T}(),value:b.zoom,onDrag:function(){function T(C,A){return b.onZoom(C,A)}return T}()}),(0,n.createComponentVNode)(2,r.Button,{ml:"0.5em",float:"right",icon:"sync",tooltip:"Reset View",onClick:function(){function T(C){return b.onReset==null?void 0:b.onReset(C)}return T}()})]})})})})};h.Zoomer=I},74733:function(y,e,t){"use strict";e.__esModule=!0,e.NoticeBox=void 0;var n=t(89005),r=t(35840),o=t(55937),a=["className","color","info","warning","success","danger"];/** + */function u(p,f){if(p==null)return{};var i={};for(var d in p)if({}.hasOwnProperty.call(p,d)){if(f.includes(d))continue;i[d]=p[d]}return i}var l=e.Modal=function(){function p(f){var i=f.className,d=f.children,c=f.onEnter,g=u(f,s),v;return c&&(v=function(){function h(m){m.keyCode===13&&c(m)}return h}()),(0,n.createComponentVNode)(2,a.Dimmer,{onKeyDown:v,children:(0,n.normalizeProps)((0,n.createVNode)(1,"div",(0,r.classes)(["Modal",i,(0,o.computeBoxClassName)(g)]),d,0,Object.assign({},(0,o.computeBoxProps)(g))))})}return p}()},73280:function(y,e,t){"use strict";e.__esModule=!0,e.NanoMap=void 0;var n=t(89005),r=t(36036),o=t(72253),a=t(29319),s=t(79911),u=t(79140),l=["x","y","icon","tooltip","color","children"],p=["icon","color"];function f(O,C){if(O==null)return{};var S={};for(var T in O)if({}.hasOwnProperty.call(O,T)){if(C.includes(T))continue;S[T]=O[T]}return S}function i(O,C){O.prototype=Object.create(C.prototype),O.prototype.constructor=O,d(O,C)}function d(O,C){return d=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(S,T){return S.__proto__=T,S},d(O,C)}var c=510,g=2,v=function(C){return C.stopPropagation&&C.stopPropagation(),C.preventDefault&&C.preventDefault(),C.cancelBubble=!0,C.returnValue=!1,!1},h=e.NanoMap=function(O){function C(T){var b,A,P,M;M=O.call(this,T)||this;var w=window.innerWidth/2-256,V=window.innerHeight/2-256;return M.state={offsetX:(b=T.offsetX)!=null?b:0,offsetY:(A=T.offsetY)!=null?A:0,dragging:!1,originX:null,originY:null,zoom:(P=T.zoom)!=null?P:1},M.handleDragStart=function(U){M.ref=U.target,M.setState({dragging:!1,originX:U.screenX,originY:U.screenY}),document.addEventListener("mousemove",M.handleDragMove),document.addEventListener("mouseup",M.handleDragEnd),v(U)},M.handleDragMove=function(U){M.setState(function(j){var G=Object.assign({},j),$=U.screenX-G.originX,x=U.screenY-G.originY;return j.dragging?(G.offsetX+=$/G.zoom,G.offsetY+=x/G.zoom,G.originX=U.screenX,G.originY=U.screenY):G.dragging=!0,G}),v(U)},M.handleDragEnd=function(U){M.setState({dragging:!1,originX:null,originY:null}),document.removeEventListener("mousemove",M.handleDragMove),document.removeEventListener("mouseup",M.handleDragEnd),T.onOffsetChange==null||T.onOffsetChange(U,M.state),v(U)},M.handleZoom=function(U,j){M.setState(function(G){var $=Math.min(Math.max(j,1),8);return G.zoom=$,T.onZoom&&T.onZoom(G.zoom),G})},M.handleReset=function(U){M.setState(function(j){j.offsetX=0,j.offsetY=0,j.zoom=1,M.handleZoom(U,1),T.onOffsetChange==null||T.onOffsetChange(U,j)})},M}i(C,O);var S=C.prototype;return S.getChildContext=function(){function T(){return{map:{zoom:this.state.zoom}}}return T}(),S.render=function(){function T(){var b=(0,o.useBackend)(this.context),A=b.config,P=this.state,M=P.dragging,w=P.offsetX,V=P.offsetY,U=P.zoom,j=U===void 0?1:U,G=this.props.children,$=A.map+"_nanomap_z1.png",x=c*j+"px",B={width:x,height:x,"margin-top":V*j+"px","margin-left":w*j+"px",overflow:"hidden",position:"relative",top:"50%",left:"50%",transform:"translate(-50%, -50%)","background-size":"cover","background-repeat":"no-repeat","text-align":"center",cursor:M?"move":"auto"},F={width:"100%",height:"100%",position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"};return(0,n.createComponentVNode)(2,r.Box,{className:"NanoMap__container",children:[(0,n.createComponentVNode)(2,r.Box,{style:B,onMouseDown:this.handleDragStart,children:[(0,n.createVNode)(1,"img",null,null,1,{src:(0,u.resolveAsset)($),style:F}),(0,n.createComponentVNode)(2,r.Box,{children:G})]}),(0,n.createComponentVNode)(2,I,{zoom:j,onZoom:this.handleZoom,onReset:this.handleReset})]})}return T}(),C}(n.Component),m=function(C,S){var T=S.map.zoom,b=C.x,A=C.y,P=C.icon,M=C.tooltip,w=C.color,V=C.children,U=f(C,l),j=g*T,G=(b-1)*j,$=(A-1)*j;return(0,n.createVNode)(1,"div",null,(0,n.createComponentVNode)(2,r.Tooltip,{content:M,children:(0,n.normalizeProps)((0,n.createComponentVNode)(2,r.Box,Object.assign({position:"absolute",className:"NanoMap__marker",lineHeight:"0",bottom:$+"px",left:G+"px",width:j+"px",height:j+"px"},U,{children:V})))}),2)};h.Marker=m;var E=function(C,S){var T=S.map.zoom,b=C.icon,A=C.color,P=f(C,p),M=g*T+4/Math.ceil(T/4);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,m,Object.assign({},P,{children:(0,n.createComponentVNode)(2,r.Icon,{name:b,color:A,fontSize:M+"px",style:{position:"relative",top:"50%",left:"50%",transform:"translate(-50%, -50%)"}})})))};h.MarkerIcon=E;var I=function(C,S){return(0,n.createComponentVNode)(2,r.Box,{className:"NanoMap__zoomer",children:(0,n.createComponentVNode)(2,a.LabeledList,{children:(0,n.createComponentVNode)(2,a.LabeledList.Item,{label:"Zoom",labelStyle:{"vertical-align":"middle"},children:(0,n.createComponentVNode)(2,r.Flex,{direction:"row",children:[(0,n.createComponentVNode)(2,s.Slider,{minValue:1,maxValue:8,stepPixelSize:10,format:function(){function T(b){return b+"x"}return T}(),value:C.zoom,onDrag:function(){function T(b,A){return C.onZoom(b,A)}return T}()}),(0,n.createComponentVNode)(2,r.Button,{ml:"0.5em",float:"right",icon:"sync",tooltip:"Reset View",onClick:function(){function T(b){return C.onReset==null?void 0:C.onReset(b)}return T}()})]})})})})};h.Zoomer=I},74733:function(y,e,t){"use strict";e.__esModule=!0,e.NoticeBox=void 0;var n=t(89005),r=t(35840),o=t(55937),a=["className","color","info","warning","success","danger"];/** * @file * @copyright 2020 Aleksej Komarov * @license MIT @@ -332,23 +332,23 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT -*/var p=400,f=e.NumberInput=function(i){function d(g){var v;v=i.call(this,g)||this;var h=g.value;return v.inputRef=(0,n.createRef)(),v.state={value:h,dragging:!1,editing:!1,internalValue:null,origin:null,suppressingFlicker:!1},v.flickerTimer=null,v.suppressFlicker=function(){var m=v.props.suppressFlicker;m>0&&(v.setState({suppressingFlicker:!0}),clearTimeout(v.flickerTimer),v.flickerTimer=setTimeout(function(){return v.setState({suppressingFlicker:!1})},m))},v.handleDragStart=function(m){var E=v.props.value,I=v.state.editing;I||(document.body.style["pointer-events"]="none",v.ref=m.target,v.setState({dragging:!1,origin:m.screenY,value:E,internalValue:E}),v.timer=setTimeout(function(){v.setState({dragging:!0})},250),v.dragInterval=setInterval(function(){var O=v.state,b=O.dragging,S=O.value,T=v.props.onDrag;b&&T&&T(m,S)},v.props.updateRate||p),document.addEventListener("mousemove",v.handleDragMove),document.addEventListener("mouseup",v.handleDragEnd))},v.handleDragMove=function(m){var E=v.props,I=E.minValue,O=E.maxValue,b=E.step,S=E.stepPixelSize;v.setState(function(T){var C=Object.assign({},T),A=C.origin-m.screenY;if(T.dragging){var P=Number.isFinite(I)?I%b:0;C.internalValue=(0,r.clamp)(C.internalValue+A*b/S,I-b,O+b),C.value=(0,r.clamp)(C.internalValue-C.internalValue%b+P,I,O),C.origin=m.screenY}else Math.abs(A)>4&&(C.dragging=!0);return C})},v.handleDragEnd=function(m){var E=v.props,I=E.onChange,O=E.onDrag,b=v.state,S=b.dragging,T=b.value,C=b.internalValue;if(document.body.style["pointer-events"]="auto",clearTimeout(v.timer),clearInterval(v.dragInterval),v.setState({dragging:!1,editing:!S,origin:null}),document.removeEventListener("mousemove",v.handleDragMove),document.removeEventListener("mouseup",v.handleDragEnd),S)v.suppressFlicker(),I&&I(m,T),O&&O(m,T);else if(v.inputRef){var A=v.inputRef.current;A.value=C;try{A.focus(),A.select()}catch(P){}}},v}u(d,i);var c=d.prototype;return c.render=function(){function g(){var v=this,h=this.state,m=h.dragging,E=h.editing,I=h.value,O=h.suppressingFlicker,b=this.props,S=b.className,T=b.fluid,C=b.animated,A=b.value,P=b.unit,M=b.minValue,w=b.maxValue,V=b.height,U=b.width,j=b.lineHeight,G=b.fontSize,$=b.format,x=b.onChange,B=b.onDrag,F=A;(m||O)&&(F=I);var H=(0,n.createVNode)(1,"div","NumberInput__content",[C&&!m&&!O?(0,n.createComponentVNode)(2,a.AnimatedNumber,{value:F,format:$}):$?$(F):F,P?" "+P:""],0);return(0,n.createComponentVNode)(2,s.Box,{className:(0,o.classes)(["NumberInput",T&&"NumberInput--fluid",S]),minWidth:U,minHeight:V,lineHeight:j,fontSize:G,onMouseDown:this.handleDragStart,children:[(0,n.createVNode)(1,"div","NumberInput__barContainer",(0,n.createVNode)(1,"div","NumberInput__bar",null,1,{style:{height:(0,r.clamp)((F-M)/(w-M)*100,0,100)+"%"}}),2),H,(0,n.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:E?void 0:"none",height:V,"line-height":j,"font-size":G},onBlur:function(){function K(W){if(E){var q=(0,r.clamp)(parseFloat(W.target.value),M,w);if(Number.isNaN(q)){v.setState({editing:!1});return}v.setState({editing:!1,value:q}),v.suppressFlicker(),x&&x(W,q),B&&B(W,q)}}return K}(),onKeyDown:function(){function K(W){if(W.keyCode===13){var q=(0,r.clamp)(parseFloat(W.target.value),M,w);if(Number.isNaN(q)){v.setState({editing:!1});return}v.setState({editing:!1,value:q}),v.suppressFlicker(),x&&x(W,q),B&&B(W,q);return}if(W.keyCode===27){v.setState({editing:!1});return}}return K}()},null,this.inputRef)]})}return g}(),d}(n.Component);f.defaultHooks=o.pureComponentHooks,f.defaultProps={minValue:-1/0,maxValue:1/0,step:1,stepPixelSize:1,suppressFlicker:50}},33337:function(y,e,t){"use strict";e.__esModule=!0,e.Pointer=void 0;var n=t(89005),r=t(35840),o=e.Pointer=function(){function a(s){var u=s.className,l=s.color,p=s.left,f=s.top,i=f===void 0?.5:f,d=(0,r.classes)(["react-colorful__pointer",u]),c={top:i*100+"%",left:p*100+"%"};return(0,n.createVNode)(1,"div",d,(0,n.createVNode)(1,"div","react-colorful__pointer-fill",null,1,{style:{"background-color":l}}),2,{style:c})}return a}()},50186:function(y,e,t){"use strict";e.__esModule=!0,e.Popper=void 0;var n=t(95996),r=t(89005);function o(u,l){u.prototype=Object.create(l.prototype),u.prototype.constructor=u,a(u,l)}function a(u,l){return a=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(p,f){return p.__proto__=f,p},a(u,l)}var s=e.Popper=function(u){function l(){var f;return f=u.call(this)||this,f.renderedContent=void 0,f.popperInstance=void 0,l.id+=1,f}o(l,u);var p=l.prototype;return p.componentDidMount=function(){function f(){var i=this,d=this.props,c=d.additionalStyles,g=d.options;if(this.renderedContent=document.createElement("div"),c)for(var v=0,h=Object.entries(c);v0&&(v.setState({suppressingFlicker:!0}),clearTimeout(v.flickerTimer),v.flickerTimer=setTimeout(function(){return v.setState({suppressingFlicker:!1})},m))},v.handleDragStart=function(m){var E=v.props.value,I=v.state.editing;I||(document.body.style["pointer-events"]="none",v.ref=m.target,v.setState({dragging:!1,origin:m.screenY,value:E,internalValue:E}),v.timer=setTimeout(function(){v.setState({dragging:!0})},250),v.dragInterval=setInterval(function(){var O=v.state,C=O.dragging,S=O.value,T=v.props.onDrag;C&&T&&T(m,S)},v.props.updateRate||p),document.addEventListener("mousemove",v.handleDragMove),document.addEventListener("mouseup",v.handleDragEnd))},v.handleDragMove=function(m){var E=v.props,I=E.minValue,O=E.maxValue,C=E.step,S=E.stepPixelSize;v.setState(function(T){var b=Object.assign({},T),A=b.origin-m.screenY;if(T.dragging){var P=Number.isFinite(I)?I%C:0;b.internalValue=(0,r.clamp)(b.internalValue+A*C/S,I-C,O+C),b.value=(0,r.clamp)(b.internalValue-b.internalValue%C+P,I,O),b.origin=m.screenY}else Math.abs(A)>4&&(b.dragging=!0);return b})},v.handleDragEnd=function(m){var E=v.props,I=E.onChange,O=E.onDrag,C=v.state,S=C.dragging,T=C.value,b=C.internalValue;if(document.body.style["pointer-events"]="auto",clearTimeout(v.timer),clearInterval(v.dragInterval),v.setState({dragging:!1,editing:!S,origin:null}),document.removeEventListener("mousemove",v.handleDragMove),document.removeEventListener("mouseup",v.handleDragEnd),S)v.suppressFlicker(),I&&I(m,T),O&&O(m,T);else if(v.inputRef){var A=v.inputRef.current;A.value=b;try{A.focus(),A.select()}catch(P){}}},v}u(d,i);var c=d.prototype;return c.render=function(){function g(){var v=this,h=this.state,m=h.dragging,E=h.editing,I=h.value,O=h.suppressingFlicker,C=this.props,S=C.className,T=C.fluid,b=C.animated,A=C.value,P=C.unit,M=C.minValue,w=C.maxValue,V=C.height,U=C.width,j=C.lineHeight,G=C.fontSize,$=C.format,x=C.onChange,B=C.onDrag,F=A;(m||O)&&(F=I);var H=(0,n.createVNode)(1,"div","NumberInput__content",[b&&!m&&!O?(0,n.createComponentVNode)(2,a.AnimatedNumber,{value:F,format:$}):$?$(F):F,P?" "+P:""],0);return(0,n.createComponentVNode)(2,s.Box,{className:(0,o.classes)(["NumberInput",T&&"NumberInput--fluid",S]),minWidth:U,minHeight:V,lineHeight:j,fontSize:G,onMouseDown:this.handleDragStart,children:[(0,n.createVNode)(1,"div","NumberInput__barContainer",(0,n.createVNode)(1,"div","NumberInput__bar",null,1,{style:{height:(0,r.clamp)((F-M)/(w-M)*100,0,100)+"%"}}),2),H,(0,n.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:E?void 0:"none",height:V,"line-height":j,"font-size":G},onBlur:function(){function K(W){if(E){var q=(0,r.clamp)(parseFloat(W.target.value),M,w);if(Number.isNaN(q)){v.setState({editing:!1});return}v.setState({editing:!1,value:q}),v.suppressFlicker(),x&&x(W,q),B&&B(W,q)}}return K}(),onKeyDown:function(){function K(W){if(W.keyCode===13){var q=(0,r.clamp)(parseFloat(W.target.value),M,w);if(Number.isNaN(q)){v.setState({editing:!1});return}v.setState({editing:!1,value:q}),v.suppressFlicker(),x&&x(W,q),B&&B(W,q);return}if(W.keyCode===27){v.setState({editing:!1});return}}return K}()},null,this.inputRef)]})}return g}(),d}(n.Component);f.defaultHooks=o.pureComponentHooks,f.defaultProps={minValue:-1/0,maxValue:1/0,step:1,stepPixelSize:1,suppressFlicker:50}},33337:function(y,e,t){"use strict";e.__esModule=!0,e.Pointer=void 0;var n=t(89005),r=t(35840),o=e.Pointer=function(){function a(s){var u=s.className,l=s.color,p=s.left,f=s.top,i=f===void 0?.5:f,d=(0,r.classes)(["react-colorful__pointer",u]),c={top:i*100+"%",left:p*100+"%"};return(0,n.createVNode)(1,"div",d,(0,n.createVNode)(1,"div","react-colorful__pointer-fill",null,1,{style:{"background-color":l}}),2,{style:c})}return a}()},50186:function(y,e,t){"use strict";e.__esModule=!0,e.Popper=void 0;var n=t(95996),r=t(89005);function o(u,l){u.prototype=Object.create(l.prototype),u.prototype.constructor=u,a(u,l)}function a(u,l){return a=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(p,f){return p.__proto__=f,p},a(u,l)}var s=e.Popper=function(u){function l(){var f;return f=u.call(this)||this,f.renderedContent=void 0,f.popperInstance=void 0,l.id+=1,f}o(l,u);var p=l.prototype;return p.componentDidMount=function(){function f(){var i=this,d=this.props,c=d.additionalStyles,g=d.options;if(this.renderedContent=document.createElement("div"),c)for(var v=0,h=Object.entries(c);vg)return"in the future";c=c/10,g=g/10;var v=g-c;if(v>3600){var h=Math.round(v/3600);return h+" hour"+(h===1?"":"s")+" ago"}else if(v>60){var m=Math.round(v/60);return m+" minute"+(m===1?"":"s")+" ago"}else{var E=Math.round(v);return E+" second"+(E===1?"":"s")+" ago"}return"just now"}return d}()},40944:function(y,e,t){"use strict";e.__esModule=!0,e.KitchenSink=void 0;var n=t(89005),r=t(72253),o=t(36036),a=t(98595);/** +*/var d=e.TextArea=function(c){function g(h,m){var E;E=c.call(this,h,m)||this,E.textareaRef=h.innerRef||(0,n.createRef)(),E.fillerRef=(0,n.createRef)(),E.state={editing:!1};var I=h.dontUseTabForIndent,O=I===void 0?!1:I;return E.handleOnInput=function(C){var S=E.state.editing,T=E.props.onInput;S||E.setEditing(!0),T&&T(C,C.target.value)},E.handleOnChange=function(C){var S=E.state.editing,T=E.props.onChange;S&&E.setEditing(!1),T&&T(C,C.target.value)},E.handleKeyPress=function(C){var S=E.state.editing,T=E.props.onKeyPress;S||E.setEditing(!0),T&&T(C,C.target.value)},E.handleKeyDown=function(C){var S=E.state.editing,T=E.props,b=T.onChange,A=T.onInput,P=T.onEnter,M=T.onKeyDown;if(C.keyCode===s.KEY_ENTER){E.setEditing(!1),b&&b(C,C.target.value),A&&A(C,C.target.value),P&&P(C,C.target.value),E.props.selfClear&&(C.target.value="",C.target.blur());return}if(C.keyCode===s.KEY_ESCAPE){E.props.onEscape&&E.props.onEscape(C),E.setEditing(!1),E.props.selfClear?C.target.value="":(C.target.value=(0,a.toInputValue)(E.props.value),C.target.blur());return}if(S||E.setEditing(!0),M&&M(C,C.target.value),!O){var w=C.keyCode||C.which;if(w===s.KEY_TAB){C.preventDefault();var V=C.target,U=V.value,j=V.selectionStart,G=V.selectionEnd;C.target.value=U.substring(0,j)+" "+U.substring(G),C.target.selectionEnd=j+1}}},E.handleFocus=function(C){var S=E.state.editing;S||E.setEditing(!0)},E.handleBlur=function(C){var S=E.state.editing,T=E.props.onChange;S&&(E.setEditing(!1),T&&T(C,C.target.value))},E}f(g,c);var v=g.prototype;return v.componentDidMount=function(){function h(){var m=this,E=this.props.value,I=this.textareaRef.current;I&&(I.value=(0,a.toInputValue)(E)),(this.props.autoFocus||this.props.autoSelect)&&setTimeout(function(){I.focus(),m.props.autoSelect&&I.select()},1)}return h}(),v.componentDidUpdate=function(){function h(m,E){var I=m.value,O=this.props.value,C=this.textareaRef.current;C&&typeof O=="string"&&I!==O&&(C.value=(0,a.toInputValue)(O))}return h}(),v.setEditing=function(){function h(m){this.setState({editing:m})}return h}(),v.getValue=function(){function h(){return this.textareaRef.current&&this.textareaRef.current.value}return h}(),v.render=function(){function h(){var m=this.props,E=m.onChange,I=m.onKeyDown,O=m.onKeyPress,C=m.onInput,S=m.onFocus,T=m.onBlur,b=m.onEnter,A=m.value,P=m.maxLength,M=m.placeholder,w=p(m,u),V=w.className,U=w.fluid,j=p(w,l);return(0,n.normalizeProps)((0,n.createComponentVNode)(2,o.Box,Object.assign({className:(0,r.classes)(["TextArea",U&&"TextArea--fluid",V])},j,{children:(0,n.createVNode)(128,"textarea","TextArea__textarea",null,1,{placeholder:M,onChange:this.handleOnChange,onKeyDown:this.handleKeyDown,onKeyPress:this.handleKeyPress,onInput:this.handleOnInput,onFocus:this.handleFocus,onBlur:this.handleBlur,maxLength:P},null,this.textareaRef)})))}return h}(),g}(n.Component)},5169:function(y,e){"use strict";e.__esModule=!0,e.TimeDisplay=void 0;var t=function(o){(!o||o<0)&&(o=0);var a=Math.floor(o/60).toString(10),s=(Math.floor(o)%60).toString(10);return[a,s].map(function(u){return u.length<2?"0"+u:u}).join(":")},n=e.TimeDisplay=function(){function r(o){var a=o.totalSeconds,s=a===void 0?0:a;return t(s)}return r}()},62147:function(y,e,t){"use strict";e.__esModule=!0,e.Tooltip=void 0;var n=t(89005),r=t(95996),o;function a(f,i){f.prototype=Object.create(i.prototype),f.prototype.constructor=f,s(f,i)}function s(f,i){return s=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(d,c){return d.__proto__=c,d},s(f,i)}var u={modifiers:[{name:"eventListeners",enabled:!1}]},l={width:0,height:0,top:0,right:0,bottom:0,left:0,x:0,y:0,toJSON:function(){function f(){return null}return f}()},p=e.Tooltip=function(f){function i(){return f.apply(this,arguments)||this}a(i,f);var d=i.prototype;return d.getDOMNode=function(){function c(){return(0,n.findDOMFromVNode)(this.$LI,!0)}return c}(),d.componentDidMount=function(){function c(){var g=this,v=this.getDOMNode();v&&(v.addEventListener("mouseenter",function(){var h=i.renderedTooltip;h===void 0&&(h=document.createElement("div"),h.className="Tooltip",document.body.appendChild(h),i.renderedTooltip=h),i.currentHoveredElement=v,h.style.opacity="1",g.renderPopperContent()}),v.addEventListener("mouseleave",function(){g.fadeOut()}))}return c}(),d.fadeOut=function(){function c(){i.currentHoveredElement===this.getDOMNode()&&(i.currentHoveredElement=void 0,i.renderedTooltip.style.opacity="0")}return c}(),d.renderPopperContent=function(){function c(){var g=this,v=i.renderedTooltip;v&&(0,n.render)((0,n.createVNode)(1,"span",null,this.props.content,0),v,function(){var h=i.singletonPopper;h===void 0?(h=(0,r.createPopper)(i.virtualElement,v,Object.assign({},u,{placement:g.props.position||"auto"})),i.singletonPopper=h):(h.setOptions(Object.assign({},u,{placement:g.props.position||"auto"})),h.update())},this.context)}return c}(),d.componentDidUpdate=function(){function c(){i.currentHoveredElement===this.getDOMNode()&&this.renderPopperContent()}return c}(),d.componentWillUnmount=function(){function c(){this.fadeOut()}return c}(),d.render=function(){function c(){return this.props.children}return c}(),i}(n.Component);o=p,p.renderedTooltip=void 0,p.singletonPopper=void 0,p.currentHoveredElement=void 0,p.virtualElement={getBoundingClientRect:function(){function f(){var i,d;return(i=(d=o.currentHoveredElement)==null?void 0:d.getBoundingClientRect())!=null?i:l}return f}()}},36036:function(y,e,t){"use strict";e.__esModule=!0,e.Tooltip=e.TimeDisplay=e.TextArea=e.Tabs=e.Table=e.Stack=e.Slider=e.Section=e.RoundGauge=e.RestrictedInput=e.ProgressBar=e.Popper=e.Pointer=e.NumberInput=e.NoticeBox=e.NanoMap=e.Modal=e.LabeledList=e.LabeledControls=e.Knob=e.Interactive=e.Input=e.ImageButton=e.Image=e.Icon=e.Grid=e.Flex=e.Dropdown=e.DraggableControl=e.DmIcon=e.Divider=e.Dimmer=e.Countdown=e.ColorBox=e.Collapsible=e.Chart=e.ByondUi=e.Button=e.Box=e.BlockQuote=e.Blink=e.Autofocus=e.AnimatedNumber=void 0;var n=t(9474);e.AnimatedNumber=n.AnimatedNumber;var r=t(27185);e.Autofocus=r.Autofocus;var o=t(5814);e.Blink=o.Blink;var a=t(61773);e.BlockQuote=a.BlockQuote;var s=t(55937);e.Box=s.Box;var u=t(96184);e.Button=u.Button;var l=t(18982);e.ByondUi=l.ByondUi;var p=t(66820);e.Chart=p.Chart;var f=t(4796);e.Collapsible=f.Collapsible;var i=t(88894);e.ColorBox=i.ColorBox;var d=t(73379);e.Countdown=d.Countdown;var c=t(61940);e.Dimmer=c.Dimmer;var g=t(13605);e.Divider=g.Divider;var v=t(20342);e.DraggableControl=v.DraggableControl;var h=t(87099);e.Dropdown=h.Dropdown;var m=t(39473);e.Flex=m.Flex;var E=t(79646);e.Grid=E.Grid;var I=t(4454);e.Interactive=I.Interactive;var O=t(91225);e.Image=O.Image;var C=t(60218);e.DmIcon=C.DmIcon;var S=t(1331);e.Icon=S.Icon;var T=t(79825);e.ImageButton=T.ImageButton;var b=t(79652);e.Input=b.Input;var A=t(76334);e.Knob=A.Knob;var P=t(78621);e.LabeledControls=P.LabeledControls;var M=t(29319);e.LabeledList=M.LabeledList;var w=t(36077);e.Modal=w.Modal;var V=t(73280);e.NanoMap=V.NanoMap;var U=t(74733);e.NoticeBox=U.NoticeBox;var j=t(59263);e.NumberInput=j.NumberInput;var G=t(33337);e.Pointer=G.Pointer;var $=t(50186);e.Popper=$.Popper;var x=t(92704);e.ProgressBar=x.ProgressBar;var B=t(9075);e.RestrictedInput=B.RestrictedInput;var F=t(11441);e.RoundGauge=F.RoundGauge;var H=t(97079);e.Section=H.Section;var K=t(79911);e.Slider=K.Slider;var W=t(96690);e.Stack=W.Stack;var q=t(36352);e.Table=q.Table;var ut=t(85138);e.Tabs=ut.Tabs;var ct=t(44868);e.TextArea=ct.TextArea;var Q=t(5169);e.TimeDisplay=Q.TimeDisplay;var X=t(62147);e.Tooltip=X.Tooltip},76910:function(y,e){"use strict";e.__esModule=!0,e.timeAgo=e.getGasLabel=e.getGasColor=e.UI_UPDATE=e.UI_INTERACTIVE=e.UI_DISABLED=e.UI_CLOSE=e.RADIO_CHANNELS=e.CSS_COLORS=e.COLORS=void 0;var t=e.UI_INTERACTIVE=2,n=e.UI_UPDATE=1,r=e.UI_DISABLED=0,o=e.UI_CLOSE=-1,a=e.COLORS={department:{command:"#526aff",security:"#CF0000",medical:"#009190",science:"#993399",engineering:"#A66300",supply:"#9F8545",service:"#80A000",centcom:"#78789B",other:"#C38312"},damageType:{oxy:"#3498db",toxin:"#2ecc71",burn:"#e67e22",brute:"#e74c3c"}},s=e.CSS_COLORS=["black","white","red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey","good","average","bad","label"],u=e.RADIO_CHANNELS=[{name:"Syndicate",freq:1213,color:"#a52a2a"},{name:"SyndTeam",freq:1244,color:"#a52a2a"},{name:"Red Team",freq:1215,color:"#ff4444"},{name:"Blue Team",freq:1217,color:"#3434fd"},{name:"Response Team",freq:1345,color:"#2681a5"},{name:"Special Ops",freq:1341,color:"#2681a5"},{name:"Supply",freq:1347,color:"#b88646"},{name:"Service",freq:1349,color:"#6ca729"},{name:"Science",freq:1351,color:"#c68cfa"},{name:"Command",freq:1353,color:"#5177ff"},{name:"Procedure",freq:1339,color:"#F70285"},{name:"Medical",freq:1355,color:"#57b8f0"},{name:"Medical(I)",freq:1485,color:"#57b8f0"},{name:"Engineering",freq:1357,color:"#f37746"},{name:"Security",freq:1359,color:"#dd3535"},{name:"Security(I)",freq:1475,color:"#dd3535"},{name:"AI Private",freq:1343,color:"#d65d95"},{name:"Common",freq:1459,color:"#1ecc43"}],l=[{id:"o2",name:"Oxygen",label:"O\u2082",color:"blue"},{id:"n2",name:"Nitrogen",label:"N\u2082",color:"red"},{id:"co2",name:"Carbon Dioxide",label:"CO\u2082",color:"grey"},{id:"plasma",name:"Plasma",label:"Plasma",color:"pink"},{id:"water_vapor",name:"Water Vapor",label:"H\u2082O",color:"grey"},{id:"nob",name:"Hyper-noblium",label:"Hyper-nob",color:"teal"},{id:"n2o",name:"Nitrous Oxide",label:"N\u2082O",color:"red"},{id:"no2",name:"Nitryl",label:"NO\u2082",color:"brown"},{id:"tritium",name:"Tritium",label:"Tritium",color:"green"},{id:"bz",name:"BZ",label:"BZ",color:"purple"},{id:"stim",name:"Stimulum",label:"Stimulum",color:"purple"},{id:"pluox",name:"Pluoxium",label:"Pluoxium",color:"blue"},{id:"miasma",name:"Miasma",label:"Miasma",color:"olive"},{id:"hydrogen",name:"Hydrogen",label:"H\u2082",color:"white"},{id:"ab",name:"Agent B",label:"Agent B",color:"purple"}],p=e.getGasLabel=function(){function d(c,g){var v=String(c).toLowerCase(),h=l.find(function(m){return m.id===v||m.name.toLowerCase()===v});return h&&h.label||g||c}return d}(),f=e.getGasColor=function(){function d(c){var g=String(c).toLowerCase(),v=l.find(function(h){return h.id===g||h.name.toLowerCase()===g});return v&&v.color}return d}(),i=e.timeAgo=function(){function d(c,g){if(c>g)return"in the future";c=c/10,g=g/10;var v=g-c;if(v>3600){var h=Math.round(v/3600);return h+" hour"+(h===1?"":"s")+" ago"}else if(v>60){var m=Math.round(v/60);return m+" minute"+(m===1?"":"s")+" ago"}else{var E=Math.round(v);return E+" second"+(E===1?"":"s")+" ago"}return"just now"}return d}()},40944:function(y,e,t){"use strict";e.__esModule=!0,e.KitchenSink=void 0;var n=t(89005),r=t(72253),o=t(36036),a=t(98595);/** * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var s=t(4085),u=function(){return s.keys().map(function(f){return s(f)})},l=e.KitchenSink=function(){function p(f,i){var d=f.panel,c=(0,r.useLocalState)(i,"kitchenSinkTheme"),g=c[0],v=(0,r.useLocalState)(i,"pageIndex",0),h=v[0],m=v[1],E=u(),I=E[h],O=d?a.Pane:a.Window;return(0,n.createComponentVNode)(2,O,{title:"Kitchen Sink",width:600,height:500,theme:g,children:(0,n.createComponentVNode)(2,o.Flex,{height:"100%",children:[(0,n.createComponentVNode)(2,o.Flex.Item,{m:1,mr:0,children:(0,n.createComponentVNode)(2,o.Section,{fill:!0,fitted:!0,children:(0,n.createComponentVNode)(2,o.Tabs,{vertical:!0,children:E.map(function(b,S){return(0,n.createComponentVNode)(2,o.Tabs.Tab,{color:"transparent",selected:S===h,onClick:function(){function T(){return m(S)}return T}(),children:b.meta.title},S)})})})}),(0,n.createComponentVNode)(2,o.Flex.Item,{position:"relative",grow:1,children:(0,n.createComponentVNode)(2,O.Content,{scrollable:!0,children:I.meta.render()})})]})})}return p}()},77384:function(y,e,t){"use strict";e.__esModule=!0,e.toggleKitchenSink=e.toggleDebugLayout=e.openExternalBrowser=void 0;var n=t(85307);/** + */var s=t(4085),u=function(){return s.keys().map(function(f){return s(f)})},l=e.KitchenSink=function(){function p(f,i){var d=f.panel,c=(0,r.useLocalState)(i,"kitchenSinkTheme"),g=c[0],v=(0,r.useLocalState)(i,"pageIndex",0),h=v[0],m=v[1],E=u(),I=E[h],O=d?a.Pane:a.Window;return(0,n.createComponentVNode)(2,O,{title:"Kitchen Sink",width:600,height:500,theme:g,children:(0,n.createComponentVNode)(2,o.Flex,{height:"100%",children:[(0,n.createComponentVNode)(2,o.Flex.Item,{m:1,mr:0,children:(0,n.createComponentVNode)(2,o.Section,{fill:!0,fitted:!0,children:(0,n.createComponentVNode)(2,o.Tabs,{vertical:!0,children:E.map(function(C,S){return(0,n.createComponentVNode)(2,o.Tabs.Tab,{color:"transparent",selected:S===h,onClick:function(){function T(){return m(S)}return T}(),children:C.meta.title},S)})})})}),(0,n.createComponentVNode)(2,o.Flex.Item,{position:"relative",grow:1,children:(0,n.createComponentVNode)(2,O.Content,{scrollable:!0,children:I.meta.render()})})]})})}return p}()},77384:function(y,e,t){"use strict";e.__esModule=!0,e.toggleKitchenSink=e.toggleDebugLayout=e.openExternalBrowser=void 0;var n=t(85307);/** * @file * @copyright 2020 Aleksej Komarov * @license MIT @@ -393,13 +393,13 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT -*/var l=(0,o.createLogger)("drag"),p=Byond.windowId,f=!1,i=!1,d=[0,0],c,g,v,h,m,E=e.setWindowKey=function(){function F(H){p=H}return F}(),I=e.getWindowPosition=function(){function F(){return[window.screenLeft,window.screenTop]}return F}(),O=e.getWindowSize=function(){function F(){return[window.innerWidth,window.innerHeight]}return F}(),b=e.setWindowPosition=function(){function F(H){var K=(0,r.vecAdd)(H,d);return Byond.winset(Byond.windowId,{pos:K[0]+","+K[1]})}return F}(),S=e.setWindowSize=function(){function F(H){return Byond.winset(Byond.windowId,{size:H[0]+"x"+H[1]})}return F}(),T=e.getScreenPosition=function(){function F(){return[0-d[0],0-d[1]]}return F}(),C=e.getScreenSize=function(){function F(){return[window.screen.availWidth,window.screen.availHeight]}return F}(),A=function(H,K,W){W===void 0&&(W=50);for(var q=[K],ut,ct=0;ctat&&(ut[Q]=at-K[Q],ct=!0)}return[ct,ut]},U=e.dragStartHandler=function(){function F(H){l.log("drag start"),f=!0,g=[window.screenLeft-H.screenX,window.screenTop-H.screenY],document.addEventListener("mousemove",G),document.addEventListener("mouseup",j),G(H)}return F}(),j=function F(H){l.log("drag end"),G(H),document.removeEventListener("mousemove",G),document.removeEventListener("mouseup",F),f=!1,P()},G=function(H){f&&(H.preventDefault(),b((0,r.vecAdd)([H.screenX,H.screenY],g)))},$=e.resizeStartHandler=function(){function F(H,K){return function(W){v=[H,K],l.log("resize start",v),i=!0,g=[window.screenLeft-W.screenX,window.screenTop-W.screenY],h=[window.innerWidth,window.innerHeight],document.addEventListener("mousemove",B),document.addEventListener("mouseup",x),B(W)}}return F}(),x=function F(H){l.log("resize end",m),B(H),document.removeEventListener("mousemove",B),document.removeEventListener("mouseup",F),i=!1,P()},B=function(H){i&&(H.preventDefault(),m=(0,r.vecAdd)(h,(0,r.vecMultiply)(v,(0,r.vecAdd)([H.screenX,H.screenY],(0,r.vecInverse)([window.screenLeft,window.screenTop]),g,[1,1]))),m[0]=Math.max(m[0],150),m[1]=Math.max(m[1],50),S(m))}},24826:function(y,e,t){"use strict";e.__esModule=!0,e.setupGlobalEvents=e.removeScrollableNode=e.globalEvents=e.canStealFocus=e.addScrollableNode=e.KeyEvent=void 0;var n=t(92868),r=t(92986);/** +*/var l=(0,o.createLogger)("drag"),p=Byond.windowId,f=!1,i=!1,d=[0,0],c,g,v,h,m,E=e.setWindowKey=function(){function F(H){p=H}return F}(),I=e.getWindowPosition=function(){function F(){return[window.screenLeft,window.screenTop]}return F}(),O=e.getWindowSize=function(){function F(){return[window.innerWidth,window.innerHeight]}return F}(),C=e.setWindowPosition=function(){function F(H){var K=(0,r.vecAdd)(H,d);return Byond.winset(Byond.windowId,{pos:K[0]+","+K[1]})}return F}(),S=e.setWindowSize=function(){function F(H){return Byond.winset(Byond.windowId,{size:H[0]+"x"+H[1]})}return F}(),T=e.getScreenPosition=function(){function F(){return[0-d[0],0-d[1]]}return F}(),b=e.getScreenSize=function(){function F(){return[window.screen.availWidth,window.screen.availHeight]}return F}(),A=function(H,K,W){W===void 0&&(W=50);for(var q=[K],ut,ct=0;ctat&&(ut[Q]=at-K[Q],ct=!0)}return[ct,ut]},U=e.dragStartHandler=function(){function F(H){l.log("drag start"),f=!0,g=[window.screenLeft-H.screenX,window.screenTop-H.screenY],document.addEventListener("mousemove",G),document.addEventListener("mouseup",j),G(H)}return F}(),j=function F(H){l.log("drag end"),G(H),document.removeEventListener("mousemove",G),document.removeEventListener("mouseup",F),f=!1,P()},G=function(H){f&&(H.preventDefault(),C((0,r.vecAdd)([H.screenX,H.screenY],g)))},$=e.resizeStartHandler=function(){function F(H,K){return function(W){v=[H,K],l.log("resize start",v),i=!0,g=[window.screenLeft-W.screenX,window.screenTop-W.screenY],h=[window.innerWidth,window.innerHeight],document.addEventListener("mousemove",B),document.addEventListener("mouseup",x),B(W)}}return F}(),x=function F(H){l.log("resize end",m),B(H),document.removeEventListener("mousemove",B),document.removeEventListener("mouseup",F),i=!1,P()},B=function(H){i&&(H.preventDefault(),m=(0,r.vecAdd)(h,(0,r.vecMultiply)(v,(0,r.vecAdd)([H.screenX,H.screenY],(0,r.vecInverse)([window.screenLeft,window.screenTop]),g,[1,1]))),m[0]=Math.max(m[0],150),m[1]=Math.max(m[1],50),S(m))}},24826:function(y,e,t){"use strict";e.__esModule=!0,e.setupGlobalEvents=e.removeScrollableNode=e.globalEvents=e.canStealFocus=e.addScrollableNode=e.KeyEvent=void 0;var n=t(92868),r=t(92986);/** * Normalized browser focus events and BYOND-specific focus helpers. * * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var o=e.globalEvents=new n.EventEmitter,a=!1,s=e.setupGlobalEvents=function(){function S(T){T===void 0&&(T={}),a=!!T.ignoreWindowFocus}return S}(),u,l=!0,p=function S(T,C){if(a){l=!0;return}if(u&&(clearTimeout(u),u=null),C){u=setTimeout(function(){return S(T)});return}l!==T&&(l=T,o.emit(T?"window-focus":"window-blur"),o.emit("window-focus-change",T))},f=null,i=e.canStealFocus=function(){function S(T){var C=String(T.tagName).toLowerCase();return C==="input"||C==="textarea"}return S}(),d=function(T){c(),f=T,f.addEventListener("blur",c)},c=function S(){f&&(f.removeEventListener("blur",S),f=null)},g=null,v=null,h=[],m=e.addScrollableNode=function(){function S(T){h.push(T)}return S}(),E=e.removeScrollableNode=function(){function S(T){var C=h.indexOf(T);C>=0&&h.splice(C,1)}return S}(),I=function(T){if(!(f||!l))for(var C=document.body;T&&T!==C;){if(h.includes(T)){if(T.contains(g))return;g=T,T.focus();return}T=T.parentNode}};window.addEventListener("mousemove",function(S){var T=S.target;T!==v&&(v=T,I(T))}),window.addEventListener("focusin",function(S){if(v=null,g=S.target,p(!0),i(S.target)){d(S.target);return}}),window.addEventListener("focusout",function(S){v=null,p(!1,!0)}),window.addEventListener("blur",function(S){v=null,p(!1,!0)}),window.addEventListener("beforeunload",function(S){p(!1)});var O={},b=e.KeyEvent=function(){function S(C,A,P){this.event=C,this.type=A,this.code=window.event?C.which:C.keyCode,this.ctrl=C.ctrlKey,this.shift=C.shiftKey,this.alt=C.altKey,this.repeat=!!P}var T=S.prototype;return T.hasModifierKeys=function(){function C(){return this.ctrl||this.alt||this.shift}return C}(),T.isModifierKey=function(){function C(){return this.code===r.KEY_CTRL||this.code===r.KEY_SHIFT||this.code===r.KEY_ALT}return C}(),T.isDown=function(){function C(){return this.type==="keydown"}return C}(),T.isUp=function(){function C(){return this.type==="keyup"}return C}(),T.toString=function(){function C(){return this._str?this._str:(this._str="",this.ctrl&&(this._str+="Ctrl+"),this.alt&&(this._str+="Alt+"),this.shift&&(this._str+="Shift+"),this.code>=48&&this.code<=90?this._str+=String.fromCharCode(this.code):this.code>=r.KEY_F1&&this.code<=r.KEY_F12?this._str+="F"+(this.code-111):this._str+="["+this.code+"]",this._str)}return C}(),S}();document.addEventListener("keydown",function(S){if(!i(S.target)){var T=S.keyCode,C=new b(S,"keydown",O[T]);o.emit("keydown",C),o.emit("key",C),O[T]=!0}}),document.addEventListener("keyup",function(S){if(!i(S.target)){var T=S.keyCode,C=new b(S,"keyup");o.emit("keyup",C),o.emit("key",C),O[T]=!1}})},87695:function(y,e){"use strict";e.__esModule=!0,e.focusWindow=e.focusMap=void 0;/** + */var o=e.globalEvents=new n.EventEmitter,a=!1,s=e.setupGlobalEvents=function(){function S(T){T===void 0&&(T={}),a=!!T.ignoreWindowFocus}return S}(),u,l=!0,p=function S(T,b){if(a){l=!0;return}if(u&&(clearTimeout(u),u=null),b){u=setTimeout(function(){return S(T)});return}l!==T&&(l=T,o.emit(T?"window-focus":"window-blur"),o.emit("window-focus-change",T))},f=null,i=e.canStealFocus=function(){function S(T){var b=String(T.tagName).toLowerCase();return b==="input"||b==="textarea"}return S}(),d=function(T){c(),f=T,f.addEventListener("blur",c)},c=function S(){f&&(f.removeEventListener("blur",S),f=null)},g=null,v=null,h=[],m=e.addScrollableNode=function(){function S(T){h.push(T)}return S}(),E=e.removeScrollableNode=function(){function S(T){var b=h.indexOf(T);b>=0&&h.splice(b,1)}return S}(),I=function(T){if(!(f||!l))for(var b=document.body;T&&T!==b;){if(h.includes(T)){if(T.contains(g))return;g=T,T.focus();return}T=T.parentNode}};window.addEventListener("mousemove",function(S){var T=S.target;T!==v&&(v=T,I(T))}),window.addEventListener("focusin",function(S){if(v=null,g=S.target,p(!0),i(S.target)){d(S.target);return}}),window.addEventListener("focusout",function(S){v=null,p(!1,!0)}),window.addEventListener("blur",function(S){v=null,p(!1,!0)}),window.addEventListener("beforeunload",function(S){p(!1)});var O={},C=e.KeyEvent=function(){function S(b,A,P){this.event=b,this.type=A,this.code=window.event?b.which:b.keyCode,this.ctrl=b.ctrlKey,this.shift=b.shiftKey,this.alt=b.altKey,this.repeat=!!P}var T=S.prototype;return T.hasModifierKeys=function(){function b(){return this.ctrl||this.alt||this.shift}return b}(),T.isModifierKey=function(){function b(){return this.code===r.KEY_CTRL||this.code===r.KEY_SHIFT||this.code===r.KEY_ALT}return b}(),T.isDown=function(){function b(){return this.type==="keydown"}return b}(),T.isUp=function(){function b(){return this.type==="keyup"}return b}(),T.toString=function(){function b(){return this._str?this._str:(this._str="",this.ctrl&&(this._str+="Ctrl+"),this.alt&&(this._str+="Alt+"),this.shift&&(this._str+="Shift+"),this.code>=48&&this.code<=90?this._str+=String.fromCharCode(this.code):this.code>=r.KEY_F1&&this.code<=r.KEY_F12?this._str+="F"+(this.code-111):this._str+="["+this.code+"]",this._str)}return b}(),S}();document.addEventListener("keydown",function(S){if(!i(S.target)){var T=S.keyCode,b=new C(S,"keydown",O[T]);o.emit("keydown",b),o.emit("key",b),O[T]=!0}}),document.addEventListener("keyup",function(S){if(!i(S.target)){var T=S.keyCode,b=new C(S,"keyup");o.emit("keyup",b),o.emit("key",b),O[T]=!1}})},87695:function(y,e){"use strict";e.__esModule=!0,e.focusWindow=e.focusMap=void 0;/** * Various focus helpers. * * @file @@ -409,11 +409,11 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var r=["f","p","n","\u03BC","m"," ","k","M","G","T","P","E","Z","Y"],o=r.indexOf(" "),a=e.formatSiUnit=function(){function p(f,i,d){if(i===void 0&&(i=-o),d===void 0&&(d=""),typeof f!="number"||!Number.isFinite(f))return f;var c=Math.floor(Math.log10(f)),g=Math.floor(Math.max(i*3,c)),v=Math.floor(c/3),h=Math.floor(g/3),m=(0,n.clamp)(o+h,0,r.length),E=r[m],I=f/Math.pow(1e3,h),O=v>i?2+h*3-g:0,b=(0,n.toFixed)(I,O)+" "+E+d;return b.trim()}return p}(),s=e.formatPower=function(){function p(f,i){return i===void 0&&(i=0),a(f,i,"W")}return p}(),u=e.formatMoney=function(){function p(f,i){if(i===void 0&&(i=0),!Number.isFinite(f))return f;var d=(0,n.round)(f,i);i>0&&(d=(0,n.toFixed)(f,i)),d=String(d);var c=d.length,g=d.indexOf(".");g===-1&&(g=c);for(var v="",h=0;h0&&h=0?"+":i<0?"\u2013":"",c=Math.abs(i);return c===1/0?c="Inf":c=(0,n.toFixed)(c,2),d+c+" dB"}return p}()},56518:function(y,e,t){"use strict";e.__esModule=!0,e.setupHotKeys=e.releaseHotKey=e.releaseHeldKeys=e.acquireHotKey=void 0;var n=s(t(92986)),r=t(24826),o=t(9394);function a(m){if(typeof WeakMap!="function")return null;var E=new WeakMap,I=new WeakMap;return(a=function(b){return b?I:E})(m)}function s(m,E){if(!E&&m&&m.__esModule)return m;if(m===null||typeof m!="object"&&typeof m!="function")return{default:m};var I=a(E);if(I&&I.has(m))return I.get(m);var O={__proto__:null},b=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var S in m)if(S!=="default"&&{}.hasOwnProperty.call(m,S)){var T=b?Object.getOwnPropertyDescriptor(m,S):null;T&&(T.get||T.set)?Object.defineProperty(O,S,T):O[S]=m[S]}return O.default=m,I&&I.set(m,O),O}/** + */var r=["f","p","n","\u03BC","m"," ","k","M","G","T","P","E","Z","Y"],o=r.indexOf(" "),a=e.formatSiUnit=function(){function p(f,i,d){if(i===void 0&&(i=-o),d===void 0&&(d=""),typeof f!="number"||!Number.isFinite(f))return f;var c=Math.floor(Math.log10(f)),g=Math.floor(Math.max(i*3,c)),v=Math.floor(c/3),h=Math.floor(g/3),m=(0,n.clamp)(o+h,0,r.length),E=r[m],I=f/Math.pow(1e3,h),O=v>i?2+h*3-g:0,C=(0,n.toFixed)(I,O)+" "+E+d;return C.trim()}return p}(),s=e.formatPower=function(){function p(f,i){return i===void 0&&(i=0),a(f,i,"W")}return p}(),u=e.formatMoney=function(){function p(f,i){if(i===void 0&&(i=0),!Number.isFinite(f))return f;var d=(0,n.round)(f,i);i>0&&(d=(0,n.toFixed)(f,i)),d=String(d);var c=d.length,g=d.indexOf(".");g===-1&&(g=c);for(var v="",h=0;h0&&h=0?"+":i<0?"\u2013":"",c=Math.abs(i);return c===1/0?c="Inf":c=(0,n.toFixed)(c,2),d+c+" dB"}return p}()},56518:function(y,e,t){"use strict";e.__esModule=!0,e.setupHotKeys=e.releaseHotKey=e.releaseHeldKeys=e.acquireHotKey=void 0;var n=s(t(92986)),r=t(24826),o=t(9394);function a(m){if(typeof WeakMap!="function")return null;var E=new WeakMap,I=new WeakMap;return(a=function(C){return C?I:E})(m)}function s(m,E){if(!E&&m&&m.__esModule)return m;if(m===null||typeof m!="object"&&typeof m!="function")return{default:m};var I=a(E);if(I&&I.has(m))return I.get(m);var O={__proto__:null},C=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var S in m)if(S!=="default"&&{}.hasOwnProperty.call(m,S)){var T=C?Object.getOwnPropertyDescriptor(m,S):null;T&&(T.get||T.set)?Object.defineProperty(O,S,T):O[S]=m[S]}return O.default=m,I&&I.set(m,O),O}/** * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var u=(0,o.createLogger)("hotkeys"),l={},p=[n.KEY_ESCAPE,n.KEY_ENTER,n.KEY_SPACE,n.KEY_TAB,n.KEY_CTRL,n.KEY_SHIFT,n.KEY_UP,n.KEY_DOWN,n.KEY_LEFT,n.KEY_RIGHT],f={},i=function(E){if(E===16)return"Shift";if(E===17)return"Ctrl";if(E===18)return"Alt";if(E===33)return"Northeast";if(E===34)return"Southeast";if(E===35)return"Southwest";if(E===36)return"Northwest";if(E===37)return"West";if(E===38)return"North";if(E===39)return"East";if(E===40)return"South";if(E===45)return"Insert";if(E===46)return"Delete";if(E>=48&&E<=57||E>=65&&E<=90)return String.fromCharCode(E);if(E>=96&&E<=105)return"Numpad"+(E-96);if(E>=112&&E<=123)return"F"+(E-111);if(E===188)return",";if(E===189)return"-";if(E===190)return"."},d=function(E){var I=String(E);if(I==="Ctrl+F5"||I==="Ctrl+R"){location.reload();return}if(I!=="Ctrl+F"&&!(E.event.defaultPrevented||E.isModifierKey()||p.includes(E.code))){I==="F5"&&(E.event.preventDefault(),E.event.returnValue=!1);var O=i(E.code);if(O){var b=l[O];if(b)return u.debug("macro",b),Byond.command(b);if(E.isDown()&&!f[O]){f[O]=!0;var S='Key_Down "'+O+'"';return u.debug(S),Byond.command(S)}if(E.isUp()&&f[O]){f[O]=!1;var T='Key_Up "'+O+'"';return u.debug(T),Byond.command(T)}}}},c=e.acquireHotKey=function(){function m(E){p.push(E)}return m}(),g=e.releaseHotKey=function(){function m(E){var I=p.indexOf(E);I>=0&&p.splice(I,1)}return m}(),v=e.releaseHeldKeys=function(){function m(){for(var E=0,I=Object.keys(f);E=48&&E<=57||E>=65&&E<=90)return String.fromCharCode(E);if(E>=96&&E<=105)return"Numpad"+(E-96);if(E>=112&&E<=123)return"F"+(E-111);if(E===188)return",";if(E===189)return"-";if(E===190)return"."},d=function(E){var I=String(E);if(I==="Ctrl+F5"||I==="Ctrl+R"){location.reload();return}if(I!=="Ctrl+F"&&!(E.event.defaultPrevented||E.isModifierKey()||p.includes(E.code))){I==="F5"&&(E.event.preventDefault(),E.event.returnValue=!1);var O=i(E.code);if(O){var C=l[O];if(C)return u.debug("macro",C),Byond.command(C);if(E.isDown()&&!f[O]){f[O]=!0;var S='Key_Down "'+O+'"';return u.debug(S),Byond.command(S)}if(E.isUp()&&f[O]){f[O]=!1;var T='Key_Up "'+O+'"';return u.debug(T),Byond.command(T)}}}},c=e.acquireHotKey=function(){function m(E){p.push(E)}return m}(),g=e.releaseHotKey=function(){function m(E){var I=p.indexOf(E);I>=0&&p.splice(I,1)}return m}(),v=e.releaseHeldKeys=function(){function m(){for(var E=0,I=Object.keys(f);E>8&255]},rt=function(yt){return[yt&255,yt>>8&255,yt>>16&255,yt>>24&255]},it=function(yt){return yt[3]<<24|yt[2]<<16|yt[1]<<8|yt[0]},mt=function(yt){return at(v(yt),23,4)},ot=function(yt){return at(yt,52,8)},et=function(yt,Pt,Ct){l(yt[V],Pt,{configurable:!0,get:function(){function lt(){return Ct(this)[Pt]}return lt}()})},k=function(yt,Pt,Ct,lt){var gt=$(yt),It=g(Ct),Lt=!!lt;if(It+Pt>gt.byteLength)throw new ct(j);var Vt=gt.bytes,Ot=It+gt.byteOffset,vt=O(Vt,Ot,Ot+Pt);return Lt?vt:X(vt)},tt=function(yt,Pt,Ct,lt,gt,It){var Lt=$(yt),Vt=g(Ct),Ot=lt(+gt),vt=!!It;if(Vt+Pt>Lt.byteLength)throw new ct(j);for(var St=Lt.bytes,At=Vt+Lt.byteOffset,Tt=0;Ttgt)throw new ct("Wrong offset");if(Ct=Ct===void 0?gt-It:c(Ct),It+Ct>gt)throw new ct(U);x(this,{type:w,buffer:yt,byteLength:Ct,byteOffset:It,bytes:lt.bytes}),o||(this.buffer=yt,this.byteLength=Ct,this.byteOffset=It)}return st}(),W=K[V],o&&(et(F,"byteLength",G),et(K,"buffer",$),et(K,"byteLength",$),et(K,"byteOffset",$)),p(W,{getInt8:function(){function st(yt){return k(this,1,yt)[0]<<24>>24}return st}(),getUint8:function(){function st(yt){return k(this,1,yt)[0]}return st}(),getInt16:function(){function st(yt){var Pt=k(this,2,yt,arguments.length>1?arguments[1]:!1);return(Pt[1]<<8|Pt[0])<<16>>16}return st}(),getUint16:function(){function st(yt){var Pt=k(this,2,yt,arguments.length>1?arguments[1]:!1);return Pt[1]<<8|Pt[0]}return st}(),getInt32:function(){function st(yt){return it(k(this,4,yt,arguments.length>1?arguments[1]:!1))}return st}(),getUint32:function(){function st(yt){return it(k(this,4,yt,arguments.length>1?arguments[1]:!1))>>>0}return st}(),getFloat32:function(){function st(yt){return ft(k(this,4,yt,arguments.length>1?arguments[1]:!1),23)}return st}(),getFloat64:function(){function st(yt){return ft(k(this,8,yt,arguments.length>1?arguments[1]:!1),52)}return st}(),setInt8:function(){function st(yt,Pt){tt(this,1,yt,dt,Pt)}return st}(),setUint8:function(){function st(yt,Pt){tt(this,1,yt,dt,Pt)}return st}(),setInt16:function(){function st(yt,Pt){tt(this,2,yt,_,Pt,arguments.length>2?arguments[2]:!1)}return st}(),setUint16:function(){function st(yt,Pt){tt(this,2,yt,_,Pt,arguments.length>2?arguments[2]:!1)}return st}(),setInt32:function(){function st(yt,Pt){tt(this,4,yt,rt,Pt,arguments.length>2?arguments[2]:!1)}return st}(),setUint32:function(){function st(yt,Pt){tt(this,4,yt,rt,Pt,arguments.length>2?arguments[2]:!1)}return st}(),setFloat32:function(){function st(yt,Pt){tt(this,4,yt,mt,Pt,arguments.length>2?arguments[2]:!1)}return st}(),setFloat64:function(){function st(yt,Pt){tt(this,8,yt,ot,Pt,arguments.length>2?arguments[2]:!1)}return st}()});else{var nt=A&&B.name!==M;!f(function(){B(1)})||!f(function(){new B(-1)})||f(function(){return new B,new B(1.5),new B(NaN),B.length!==1||nt&&!P})?(F=function(){function st(yt){return i(this,H),b(new B(g(yt)),this,F)}return st}(),F[V]=H,H.constructor=F,S(F,B)):nt&&P&&u(B,"name",M),E&&m(W)!==q&&E(W,q);var pt=new K(new F(2)),Et=r(W.setInt8);pt.setInt8(0,2147483648),pt.setInt8(1,2147483649),(pt.getInt8(0)||!pt.getInt8(1))&&p(W,{setInt8:function(){function st(yt,Pt){Et(this,yt,Pt<<24>>24)}return st}(),setUint8:function(){function st(yt,Pt){Et(this,yt,Pt<<24>>24)}return st}()},{unsafe:!0})}T(F,M),T(K,w),y.exports={ArrayBuffer:F,DataView:K}},71447:function(y,e,t){"use strict";var n=t(46771),r=t(13912),o=t(24760),a=t(95108),s=Math.min;y.exports=[].copyWithin||function(){function u(l,p){var f=n(this),i=o(f),d=r(l,i),c=r(p,i),g=arguments.length>2?arguments[2]:void 0,v=s((g===void 0?i:r(g,i))-c,i-d),h=1;for(c0;)c in f?f[d]=f[c]:a(f,d),d+=h,c+=h;return f}return u}()},88471:function(y,e,t){"use strict";var n=t(46771),r=t(13912),o=t(24760);y.exports=function(){function a(s){for(var u=n(this),l=o(u),p=arguments.length,f=r(p>1?arguments[1]:void 0,l),i=p>2?arguments[2]:void 0,d=i===void 0?l:r(i,l);d>f;)u[f++]=s;return u}return a}()},35601:function(y,e,t){"use strict";var n=t(22603).forEach,r=t(55528),o=r("forEach");y.exports=o?[].forEach:function(){function a(s){return n(this,s,arguments.length>1?arguments[1]:void 0)}return a}()},78008:function(y,e,t){"use strict";var n=t(24760);y.exports=function(r,o,a){for(var s=0,u=arguments.length>2?a:n(o),l=new r(u);u>s;)l[s]=o[s++];return l}},73174:function(y,e,t){"use strict";var n=t(75754),r=t(91495),o=t(46771),a=t(40125),s=t(76571),u=t(1031),l=t(24760),p=t(60102),f=t(77455),i=t(59201),d=Array;y.exports=function(){function c(g){var v=o(g),h=u(this),m=arguments.length,E=m>1?arguments[1]:void 0,I=E!==void 0;I&&(E=n(E,m>2?arguments[2]:void 0));var O=i(v),b=0,S,T,C,A,P,M;if(O&&!(this===d&&s(O)))for(T=h?new this:[],A=f(v,O),P=A.next;!(C=r(P,A)).done;b++)M=I?a(A,E,[C.value,b],!0):C.value,p(T,b,M);else for(S=l(v),T=h?new this(S):d(S);S>b;b++)M=I?E(v[b],b):v[b],p(T,b,M);return T.length=b,T}return c}()},14211:function(y,e,t){"use strict";var n=t(57591),r=t(13912),o=t(24760),a=function(u){return function(l,p,f){var i=n(l),d=o(i);if(d===0)return!u&&-1;var c=r(f,d),g;if(u&&p!==p){for(;d>c;)if(g=i[c++],g!==g)return!0}else for(;d>c;c++)if((u||c in i)&&i[c]===p)return u||c||0;return!u&&-1}};y.exports={includes:a(!0),indexOf:a(!1)}},22603:function(y,e,t){"use strict";var n=t(75754),r=t(67250),o=t(37457),a=t(46771),s=t(24760),u=t(57823),l=r([].push),p=function(i){var d=i===1,c=i===2,g=i===3,v=i===4,h=i===6,m=i===7,E=i===5||h;return function(I,O,b,S){for(var T=a(I),C=o(T),A=s(C),P=n(O,b),M=0,w=S||u,V=d?w(I,A):c||m?w(I,0):void 0,U,j;A>M;M++)if((E||M in C)&&(U=C[M],j=P(U,M,T),i))if(d)V[M]=j;else if(j)switch(i){case 3:return!0;case 5:return U;case 6:return M;case 2:l(V,U)}else switch(i){case 4:return!1;case 7:l(V,U)}return h?-1:g||v?v:V}};y.exports={forEach:p(0),map:p(1),filter:p(2),some:p(3),every:p(4),find:p(5),findIndex:p(6),filterReject:p(7)}},1325:function(y,e,t){"use strict";var n=t(61267),r=t(57591),o=t(61365),a=t(24760),s=t(55528),u=Math.min,l=[].lastIndexOf,p=!!l&&1/[1].lastIndexOf(1,-0)<0,f=s("lastIndexOf"),i=p||!f;y.exports=i?function(){function d(c){if(p)return n(l,this,arguments)||0;var g=r(this),v=a(g);if(v===0)return-1;var h=v-1;for(arguments.length>1&&(h=u(h,o(arguments[1]))),h<0&&(h=v+h);h>=0;h--)if(h in g&&g[h]===c)return h||0;return-1}return d}():l},44091:function(y,e,t){"use strict";var n=t(40033),r=t(24697),o=t(5026),a=r("species");y.exports=function(s){return o>=51||!n(function(){var u=[],l=u.constructor={};return l[a]=function(){return{foo:1}},u[s](Boolean).foo!==1})}},55528:function(y,e,t){"use strict";var n=t(40033);y.exports=function(r,o){var a=[][r];return!!a&&n(function(){a.call(null,o||function(){return 1},1)})}},56844:function(y,e,t){"use strict";var n=t(10320),r=t(46771),o=t(37457),a=t(24760),s=TypeError,u="Reduce of empty array with no initial value",l=function(f){return function(i,d,c,g){var v=r(i),h=o(v),m=a(v);if(n(d),m===0&&c<2)throw new s(u);var E=f?m-1:0,I=f?-1:1;if(c<2)for(;;){if(E in h){g=h[E],E+=I;break}if(E+=I,f?E<0:m<=E)throw new s(u)}for(;f?E>=0:m>E;E+=I)E in h&&(g=d(g,h[E],E,v));return g}};y.exports={left:l(!1),right:l(!0)}},13345:function(y,e,t){"use strict";var n=t(58310),r=t(37386),o=TypeError,a=Object.getOwnPropertyDescriptor,s=n&&!function(){if(this!==void 0)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(u){return u instanceof TypeError}}();y.exports=s?function(u,l){if(r(u)&&!a(u,"length").writable)throw new o("Cannot set read only .length");return u.length=l}:function(u,l){return u.length=l}},54602:function(y,e,t){"use strict";var n=t(67250);y.exports=n([].slice)},90274:function(y,e,t){"use strict";var n=t(54602),r=Math.floor,o=function a(s,u){var l=s.length;if(l<8)for(var p=1,f,i;p0;)s[i]=s[--i];i!==p++&&(s[i]=f)}else for(var d=r(l/2),c=a(n(s,0,d),u),g=a(n(s,d),u),v=c.length,h=g.length,m=0,E=0;m1?arguments[1]:void 0),j;j=j?j.next:V.first;)for(U(j.value,j.key,this);j&&j.removed;)j=j.previous}return M}(),has:function(){function M(w){return!!P(this,w)}return M}()}),o(T,O?{get:function(){function M(w){var V=P(this,w);return V&&V.value}return M}(),set:function(){function M(w,V){return A(this,w===0?0:w,V)}return M}()}:{add:function(){function M(w){return A(this,w=w===0?0:w,w)}return M}()}),d&&r(T,"size",{configurable:!0,get:function(){function M(){return C(this).size}return M}()}),S}return m}(),setStrong:function(){function m(E,I,O){var b=I+" Iterator",S=h(I),T=h(b);p(E,I,function(C,A){v(this,{type:b,target:C,state:S(C),kind:A,last:void 0})},function(){for(var C=T(this),A=C.kind,P=C.last;P&&P.removed;)P=P.previous;return!C.target||!(C.last=P=P?P.next:C.state.first)?(C.target=void 0,f(void 0,!0)):f(A==="keys"?P.key:A==="values"?P.value:[P.key,P.value],!1)},O?"entries":"values",!O,!0),i(I)}return m}()}},39895:function(y,e,t){"use strict";var n=t(67250),r=t(30145),o=t(81969).getWeakData,a=t(60077),s=t(30365),u=t(42871),l=t(77568),p=t(49450),f=t(22603),i=t(45299),d=t(5419),c=d.set,g=d.getterFor,v=f.find,h=f.findIndex,m=n([].splice),E=0,I=function(T){return T.frozen||(T.frozen=new O)},O=function(){this.entries=[]},b=function(T,C){return v(T.entries,function(A){return A[0]===C})};O.prototype={get:function(){function S(T){var C=b(this,T);if(C)return C[1]}return S}(),has:function(){function S(T){return!!b(this,T)}return S}(),set:function(){function S(T,C){var A=b(this,T);A?A[1]=C:this.entries.push([T,C])}return S}(),delete:function(){function S(T){var C=h(this.entries,function(A){return A[0]===T});return~C&&m(this.entries,C,1),!!~C}return S}()},y.exports={getConstructor:function(){function S(T,C,A,P){var M=T(function(j,G){a(j,w),c(j,{type:C,id:E++,frozen:void 0}),u(G)||p(G,j[P],{that:j,AS_ENTRIES:A})}),w=M.prototype,V=g(C),U=function(){function j(G,$,x){var B=V(G),F=o(s($),!0);return F===!0?I(B).set($,x):F[B.id]=x,G}return j}();return r(w,{delete:function(){function j(G){var $=V(this);if(!l(G))return!1;var x=o(G);return x===!0?I($).delete(G):x&&i(x,$.id)&&delete x[$.id]}return j}(),has:function(){function j(G){var $=V(this);if(!l(G))return!1;var x=o(G);return x===!0?I($).has(G):x&&i(x,$.id)}return j}()}),r(w,A?{get:function(){function j(G){var $=V(this);if(l(G)){var x=o(G);return x===!0?I($).get(G):x?x[$.id]:void 0}}return j}(),set:function(){function j(G,$){return U(this,G,$)}return j}()}:{add:function(){function j(G){return U(this,G,!0)}return j}()}),M}return S}()}},45150:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(67250),a=t(41314),s=t(55938),u=t(81969),l=t(49450),p=t(60077),f=t(55747),i=t(42871),d=t(77568),c=t(40033),g=t(92490),v=t(84925),h=t(5781);y.exports=function(m,E,I){var O=m.indexOf("Map")!==-1,b=m.indexOf("Weak")!==-1,S=O?"set":"add",T=r[m],C=T&&T.prototype,A=T,P={},M=function(B){var F=o(C[B]);s(C,B,B==="add"?function(){function H(K){return F(this,K===0?0:K),this}return H}():B==="delete"?function(H){return b&&!d(H)?!1:F(this,H===0?0:H)}:B==="get"?function(){function H(K){return b&&!d(K)?void 0:F(this,K===0?0:K)}return H}():B==="has"?function(){function H(K){return b&&!d(K)?!1:F(this,K===0?0:K)}return H}():function(){function H(K,W){return F(this,K===0?0:K,W),this}return H}())},w=a(m,!f(T)||!(b||C.forEach&&!c(function(){new T().entries().next()})));if(w)A=I.getConstructor(E,m,O,S),u.enable();else if(a(m,!0)){var V=new A,U=V[S](b?{}:-0,1)!==V,j=c(function(){V.has(1)}),G=g(function(x){new T(x)}),$=!b&&c(function(){for(var x=new T,B=5;B--;)x[S](B,B);return!x.has(-0)});G||(A=E(function(x,B){p(x,C);var F=h(new T,x,A);return i(B)||l(B,F[S],{that:F,AS_ENTRIES:O}),F}),A.prototype=C,C.constructor=A),(j||$)&&(M("delete"),M("has"),O&&M("get")),($||U)&&M(S),b&&C.clear&&delete C.clear}return P[m]=A,n({global:!0,constructor:!0,forced:A!==T},P),v(A,m),b||I.setStrong(A,m,O),A}},5774:function(y,e,t){"use strict";var n=t(45299),r=t(97921),o=t(27193),a=t(74595);y.exports=function(s,u,l){for(var p=r(u),f=a.f,i=o.f,d=0;d"+i+""}},5959:function(y){"use strict";y.exports=function(e,t){return{value:e,done:t}}},37909:function(y,e,t){"use strict";var n=t(58310),r=t(74595),o=t(87458);y.exports=n?function(a,s,u){return r.f(a,s,o(1,u))}:function(a,s,u){return a[s]=u,a}},87458:function(y){"use strict";y.exports=function(e,t){return{enumerable:!(e&1),configurable:!(e&2),writable:!(e&4),value:t}}},60102:function(y,e,t){"use strict";var n=t(58310),r=t(74595),o=t(87458);y.exports=function(a,s,u){n?r.f(a,s,o(0,u)):a[s]=u}},67206:function(y,e,t){"use strict";var n=t(67250),r=t(40033),o=t(24051).start,a=RangeError,s=isFinite,u=Math.abs,l=Date.prototype,p=l.toISOString,f=n(l.getTime),i=n(l.getUTCDate),d=n(l.getUTCFullYear),c=n(l.getUTCHours),g=n(l.getUTCMilliseconds),v=n(l.getUTCMinutes),h=n(l.getUTCMonth),m=n(l.getUTCSeconds);y.exports=r(function(){return p.call(new Date(-50000000000001))!=="0385-07-25T07:06:39.999Z"})||!r(function(){p.call(new Date(NaN))})?function(){function E(){if(!s(f(this)))throw new a("Invalid time value");var I=this,O=d(I),b=g(I),S=O<0?"-":O>9999?"+":"";return S+o(u(O),S?6:4,0)+"-"+o(h(I)+1,2,0)+"-"+o(i(I),2,0)+"T"+o(c(I),2,0)+":"+o(v(I),2,0)+":"+o(m(I),2,0)+"."+o(b,3,0)+"Z"}return E}():p},10886:function(y,e,t){"use strict";var n=t(30365),r=t(13396),o=TypeError;y.exports=function(a){if(n(this),a==="string"||a==="default")a="string";else if(a!=="number")throw new o("Incorrect hint");return r(this,a)}},73936:function(y,e,t){"use strict";var n=t(20001),r=t(74595);y.exports=function(o,a,s){return s.get&&n(s.get,a,{getter:!0}),s.set&&n(s.set,a,{setter:!0}),r.f(o,a,s)}},55938:function(y,e,t){"use strict";var n=t(55747),r=t(74595),o=t(20001),a=t(18231);y.exports=function(s,u,l,p){p||(p={});var f=p.enumerable,i=p.name!==void 0?p.name:u;if(n(l)&&o(l,i,p),p.global)f?s[u]=l:a(u,l);else{try{p.unsafe?s[u]&&(f=!0):delete s[u]}catch(d){}f?s[u]=l:r.f(s,u,{value:l,enumerable:!1,configurable:!p.nonConfigurable,writable:!p.nonWritable})}return s}},30145:function(y,e,t){"use strict";var n=t(55938);y.exports=function(r,o,a){for(var s in o)n(r,s,o[s],a);return r}},18231:function(y,e,t){"use strict";var n=t(74685),r=Object.defineProperty;y.exports=function(o,a){try{r(n,o,{value:a,configurable:!0,writable:!0})}catch(s){n[o]=a}return a}},95108:function(y,e,t){"use strict";var n=t(89393),r=TypeError;y.exports=function(o,a){if(!delete o[a])throw new r("Cannot delete property "+n(a)+" of "+n(o))}},58310:function(y,e,t){"use strict";var n=t(40033);y.exports=!n(function(){return Object.defineProperty({},1,{get:function(){function r(){return 7}return r}()})[1]!==7})},12689:function(y,e,t){"use strict";var n=t(74685),r=t(77568),o=n.document,a=r(o)&&r(o.createElement);y.exports=function(s){return a?o.createElement(s):{}}},21291:function(y){"use strict";var e=TypeError,t=9007199254740991;y.exports=function(n){if(n>t)throw e("Maximum allowed index exceeded");return n}},652:function(y,e,t){"use strict";var n=t(63318),r=n.match(/firefox\/(\d+)/i);y.exports=!!r&&+r[1]},8180:function(y,e,t){"use strict";var n=t(73730),r=t(81702);y.exports=!n&&!r&&typeof window=="object"&&typeof document=="object"},49197:function(y){"use strict";y.exports=typeof Bun=="function"&&Bun&&typeof Bun.version=="string"},73730:function(y){"use strict";y.exports=typeof Deno=="object"&&Deno&&typeof Deno.version=="object"},19228:function(y,e,t){"use strict";var n=t(63318);y.exports=/MSIE|Trident/.test(n)},51802:function(y,e,t){"use strict";var n=t(63318);y.exports=/ipad|iphone|ipod/i.test(n)&&typeof Pebble!="undefined"},83433:function(y,e,t){"use strict";var n=t(63318);y.exports=/(?:ipad|iphone|ipod).*applewebkit/i.test(n)},81702:function(y,e,t){"use strict";var n=t(74685),r=t(7462);y.exports=r(n.process)==="process"},63383:function(y,e,t){"use strict";var n=t(63318);y.exports=/web0s(?!.*chrome)/i.test(n)},63318:function(y){"use strict";y.exports=typeof navigator!="undefined"&&String(navigator.userAgent)||""},5026:function(y,e,t){"use strict";var n=t(74685),r=t(63318),o=n.process,a=n.Deno,s=o&&o.versions||a&&a.version,u=s&&s.v8,l,p;u&&(l=u.split("."),p=l[0]>0&&l[0]<4?1:+(l[0]+l[1])),!p&&r&&(l=r.match(/Edge\/(\d+)/),(!l||l[1]>=74)&&(l=r.match(/Chrome\/(\d+)/),l&&(p=+l[1]))),y.exports=p},9342:function(y,e,t){"use strict";var n=t(63318),r=n.match(/AppleWebKit\/(\d+)\./);y.exports=!!r&&+r[1]},89453:function(y){"use strict";y.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},63964:function(y,e,t){"use strict";var n=t(74685),r=t(27193).f,o=t(37909),a=t(55938),s=t(18231),u=t(5774),l=t(41314);y.exports=function(p,f){var i=p.target,d=p.global,c=p.stat,g,v,h,m,E,I;if(d?v=n:c?v=n[i]||s(i,{}):v=n[i]&&n[i].prototype,v)for(h in f){if(E=f[h],p.dontCallGetSet?(I=r(v,h),m=I&&I.value):m=v[h],g=l(d?h:i+(c?".":"#")+h,p.forced),!g&&m!==void 0){if(typeof E==typeof m)continue;u(E,m)}(p.sham||m&&m.sham)&&o(E,"sham",!0),a(v,h,E,p)}}},40033:function(y){"use strict";y.exports=function(e){try{return!!e()}catch(t){return!0}}},79942:function(y,e,t){"use strict";t(79669);var n=t(91495),r=t(55938),o=t(14489),a=t(40033),s=t(24697),u=t(37909),l=s("species"),p=RegExp.prototype;y.exports=function(f,i,d,c){var g=s(f),v=!a(function(){var I={};return I[g]=function(){return 7},""[f](I)!==7}),h=v&&!a(function(){var I=!1,O=/a/;return f==="split"&&(O={},O.constructor={},O.constructor[l]=function(){return O},O.flags="",O[g]=/./[g]),O.exec=function(){return I=!0,null},O[g](""),!I});if(!v||!h||d){var m=/./[g],E=i(g,""[f],function(I,O,b,S,T){var C=O.exec;return C===o||C===p.exec?v&&!T?{done:!0,value:n(m,O,b,S)}:{done:!0,value:n(I,b,O,S)}:{done:!1}});r(String.prototype,f,E[0]),r(p,g,E[1])}c&&u(p[g],"sham",!0)}},65561:function(y,e,t){"use strict";var n=t(37386),r=t(24760),o=t(21291),a=t(75754),s=function u(l,p,f,i,d,c,g,v){for(var h=d,m=0,E=g?a(g,v):!1,I,O;m0&&n(I)?(O=r(I),h=u(l,p,I,O,h,c-1)-1):(o(h+1),l[h]=I),h++),m++;return h};y.exports=s},50730:function(y,e,t){"use strict";var n=t(40033);y.exports=!n(function(){return Object.isExtensible(Object.preventExtensions({}))})},61267:function(y,e,t){"use strict";var n=t(55050),r=Function.prototype,o=r.apply,a=r.call;y.exports=typeof Reflect=="object"&&Reflect.apply||(n?a.bind(o):function(){return a.apply(o,arguments)})},75754:function(y,e,t){"use strict";var n=t(71138),r=t(10320),o=t(55050),a=n(n.bind);y.exports=function(s,u){return r(s),u===void 0?s:o?a(s,u):function(){return s.apply(u,arguments)}}},55050:function(y,e,t){"use strict";var n=t(40033);y.exports=!n(function(){var r=function(){}.bind();return typeof r!="function"||r.hasOwnProperty("prototype")})},66284:function(y,e,t){"use strict";var n=t(67250),r=t(10320),o=t(77568),a=t(45299),s=t(54602),u=t(55050),l=Function,p=n([].concat),f=n([].join),i={},d=function(g,v,h){if(!a(i,v)){for(var m=[],E=0;E]*>)/g,p=/\$([$&'`]|\d{1,2})/g;y.exports=function(f,i,d,c,g,v){var h=d+f.length,m=c.length,E=p;return g!==void 0&&(g=r(g),E=l),s(v,E,function(I,O){var b;switch(a(O,0)){case"$":return"$";case"&":return f;case"`":return u(i,0,d);case"'":return u(i,h);case"<":b=g[u(O,1,-1)];break;default:var S=+O;if(S===0)return I;if(S>m){var T=o(S/10);return T===0?I:T<=m?c[T-1]===void 0?a(O,1):c[T-1]+a(O,1):I}b=c[S-1]}return b===void 0?"":b})}},74685:function(y,e,t){"use strict";var n=function(o){return o&&o.Math===Math&&o};y.exports=n(typeof globalThis=="object"&&globalThis)||n(typeof window=="object"&&window)||n(typeof self=="object"&&self)||n(typeof t.g=="object"&&t.g)||n(!1)||function(){return this}()||Function("return this")()},45299:function(y,e,t){"use strict";var n=t(67250),r=t(46771),o=n({}.hasOwnProperty);y.exports=Object.hasOwn||function(){function a(s,u){return o(r(s),u)}return a}()},79195:function(y){"use strict";y.exports={}},72259:function(y){"use strict";y.exports=function(e,t){try{arguments.length}catch(n){}}},5315:function(y,e,t){"use strict";var n=t(4009);y.exports=n("document","documentElement")},36223:function(y,e,t){"use strict";var n=t(58310),r=t(40033),o=t(12689);y.exports=!n&&!r(function(){return Object.defineProperty(o("div"),"a",{get:function(){function a(){return 7}return a}()}).a!==7})},91784:function(y){"use strict";var e=Array,t=Math.abs,n=Math.pow,r=Math.floor,o=Math.log,a=Math.LN2,s=function(p,f,i){var d=e(i),c=i*8-f-1,g=(1<>1,h=f===23?n(2,-24)-n(2,-77):0,m=p<0||p===0&&1/p<0?1:0,E=0,I,O,b;for(p=t(p),p!==p||p===1/0?(O=p!==p?1:0,I=g):(I=r(o(p)/a),b=n(2,-I),p*b<1&&(I--,b*=2),I+v>=1?p+=h/b:p+=h*n(2,1-v),p*b>=2&&(I++,b/=2),I+v>=g?(O=0,I=g):I+v>=1?(O=(p*b-1)*n(2,f),I+=v):(O=p*n(2,v-1)*n(2,f),I=0));f>=8;)d[E++]=O&255,O/=256,f-=8;for(I=I<0;)d[E++]=I&255,I/=256,c-=8;return d[--E]|=m*128,d},u=function(p,f){var i=p.length,d=i*8-f-1,c=(1<>1,v=d-7,h=i-1,m=p[h--],E=m&127,I;for(m>>=7;v>0;)E=E*256+p[h--],v-=8;for(I=E&(1<<-v)-1,E>>=-v,v+=f;v>0;)I=I*256+p[h--],v-=8;if(E===0)E=1-g;else{if(E===c)return I?NaN:m?-1/0:1/0;I+=n(2,f),E-=g}return(m?-1:1)*I*n(2,E-f)};y.exports={pack:s,unpack:u}},37457:function(y,e,t){"use strict";var n=t(67250),r=t(40033),o=t(7462),a=Object,s=n("".split);y.exports=r(function(){return!a("z").propertyIsEnumerable(0)})?function(u){return o(u)==="String"?s(u,""):a(u)}:a},5781:function(y,e,t){"use strict";var n=t(55747),r=t(77568),o=t(76649);y.exports=function(a,s,u){var l,p;return o&&n(l=s.constructor)&&l!==u&&r(p=l.prototype)&&p!==u.prototype&&o(a,p),a}},40492:function(y,e,t){"use strict";var n=t(67250),r=t(55747),o=t(40095),a=n(Function.toString);r(o.inspectSource)||(o.inspectSource=function(s){return a(s)}),y.exports=o.inspectSource},81969:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(79195),a=t(77568),s=t(45299),u=t(74595).f,l=t(37310),p=t(81644),f=t(81834),i=t(16738),d=t(50730),c=!1,g=i("meta"),v=0,h=function(T){u(T,g,{value:{objectID:"O"+v++,weakData:{}}})},m=function(T,C){if(!a(T))return typeof T=="symbol"?T:(typeof T=="string"?"S":"P")+T;if(!s(T,g)){if(!f(T))return"F";if(!C)return"E";h(T)}return T[g].objectID},E=function(T,C){if(!s(T,g)){if(!f(T))return!0;if(!C)return!1;h(T)}return T[g].weakData},I=function(T){return d&&c&&f(T)&&!s(T,g)&&h(T),T},O=function(){b.enable=function(){},c=!0;var T=l.f,C=r([].splice),A={};A[g]=1,T(A).length&&(l.f=function(P){for(var M=T(P),w=0,V=M.length;wP;P++)if(w=G(v[P]),w&&l(g,w))return w;return new c(!1)}C=p(v,A)}for(V=O?v.next:C.next;!(U=r(V,C)).done;){try{w=G(U.value)}catch($){i(C,"throw",$)}if(typeof w=="object"&&w&&l(g,w))return w}return new c(!1)}},28649:function(y,e,t){"use strict";var n=t(91495),r=t(30365),o=t(78060);y.exports=function(a,s,u){var l,p;r(a);try{if(l=o(a,"return"),!l){if(s==="throw")throw u;return u}l=n(l,a)}catch(f){p=!0,l=f}if(s==="throw")throw u;if(p)throw l;return r(l),u}},5656:function(y,e,t){"use strict";var n=t(67635).IteratorPrototype,r=t(80674),o=t(87458),a=t(84925),s=t(83967),u=function(){return this};y.exports=function(l,p,f,i){var d=p+" Iterator";return l.prototype=r(n,{next:o(+!i,f)}),a(l,d,!1,!0),s[d]=u,l}},65574:function(y,e,t){"use strict";var n=t(63964),r=t(91495),o=t(4493),a=t(70520),s=t(55747),u=t(5656),l=t(36917),p=t(76649),f=t(84925),i=t(37909),d=t(55938),c=t(24697),g=t(83967),v=t(67635),h=a.PROPER,m=a.CONFIGURABLE,E=v.IteratorPrototype,I=v.BUGGY_SAFARI_ITERATORS,O=c("iterator"),b="keys",S="values",T="entries",C=function(){return this};y.exports=function(A,P,M,w,V,U,j){u(M,P,w);var G=function(Q){if(Q===V&&H)return H;if(!I&&Q&&Q in B)return B[Q];switch(Q){case b:return function(){function X(){return new M(this,Q)}return X}();case S:return function(){function X(){return new M(this,Q)}return X}();case T:return function(){function X(){return new M(this,Q)}return X}()}return function(){return new M(this)}},$=P+" Iterator",x=!1,B=A.prototype,F=B[O]||B["@@iterator"]||V&&B[V],H=!I&&F||G(V),K=P==="Array"&&B.entries||F,W,q,ut;if(K&&(W=l(K.call(new A)),W!==Object.prototype&&W.next&&(!o&&l(W)!==E&&(p?p(W,E):s(W[O])||d(W,O,C)),f(W,$,!0,!0),o&&(g[$]=C))),h&&V===S&&F&&F.name!==S&&(!o&&m?i(B,"name",S):(x=!0,H=function(){function ct(){return r(F,this)}return ct}())),V)if(q={values:G(S),keys:U?H:G(b),entries:G(T)},j)for(ut in q)(I||x||!(ut in B))&&d(B,ut,q[ut]);else n({target:P,proto:!0,forced:I||x},q);return(!o||j)&&B[O]!==H&&d(B,O,H,{name:V}),g[P]=H,q}},67635:function(y,e,t){"use strict";var n=t(40033),r=t(55747),o=t(77568),a=t(80674),s=t(36917),u=t(55938),l=t(24697),p=t(4493),f=l("iterator"),i=!1,d,c,g;[].keys&&(g=[].keys(),"next"in g?(c=s(s(g)),c!==Object.prototype&&(d=c)):i=!0);var v=!o(d)||n(function(){var h={};return d[f].call(h)!==h});v?d={}:p&&(d=a(d)),r(d[f])||u(d,f,function(){return this}),y.exports={IteratorPrototype:d,BUGGY_SAFARI_ITERATORS:i}},83967:function(y){"use strict";y.exports={}},24760:function(y,e,t){"use strict";var n=t(10188);y.exports=function(r){return n(r.length)}},20001:function(y,e,t){"use strict";var n=t(67250),r=t(40033),o=t(55747),a=t(45299),s=t(58310),u=t(70520).CONFIGURABLE,l=t(40492),p=t(5419),f=p.enforce,i=p.get,d=String,c=Object.defineProperty,g=n("".slice),v=n("".replace),h=n([].join),m=s&&!r(function(){return c(function(){},"length",{value:8}).length!==8}),E=String(String).split("String"),I=y.exports=function(O,b,S){g(d(b),0,7)==="Symbol("&&(b="["+v(d(b),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),S&&S.getter&&(b="get "+b),S&&S.setter&&(b="set "+b),(!a(O,"name")||u&&O.name!==b)&&(s?c(O,"name",{value:b,configurable:!0}):O.name=b),m&&S&&a(S,"arity")&&O.length!==S.arity&&c(O,"length",{value:S.arity});try{S&&a(S,"constructor")&&S.constructor?s&&c(O,"prototype",{writable:!1}):O.prototype&&(O.prototype=void 0)}catch(C){}var T=f(O);return a(T,"source")||(T.source=h(E,typeof b=="string"?b:"")),O};Function.prototype.toString=I(function(){function O(){return o(this)&&i(this).source||l(this)}return O}(),"toString")},82040:function(y){"use strict";var e=Math.expm1,t=Math.exp;y.exports=!e||e(10)>22025.465794806718||e(10)<22025.465794806718||e(-2e-17)!==-2e-17?function(){function n(r){var o=+r;return o===0?o:o>-1e-6&&o<1e-6?o+o*o/2:t(o)-1}return n}():e},14950:function(y,e,t){"use strict";var n=t(22172),r=Math.abs,o=2220446049250313e-31,a=1/o,s=function(l){return l+a-a};y.exports=function(u,l,p,f){var i=+u,d=r(i),c=n(i);if(dp||v!==v?c*(1/0):c*v}},95867:function(y,e,t){"use strict";var n=t(14950),r=11920928955078125e-23,o=34028234663852886e22,a=11754943508222875e-54;y.exports=Math.fround||function(){function s(u){return n(u,r,o,a)}return s}()},75002:function(y){"use strict";var e=Math.log,t=Math.LOG10E;y.exports=Math.log10||function(){function n(r){return e(r)*t}return n}()},90874:function(y){"use strict";var e=Math.log;y.exports=Math.log1p||function(){function t(n){var r=+n;return r>-1e-8&&r<1e-8?r-r*r/2:e(1+r)}return t}()},22172:function(y){"use strict";y.exports=Math.sign||function(){function e(t){var n=+t;return n===0||n!==n?n:n<0?-1:1}return e}()},21119:function(y){"use strict";var e=Math.ceil,t=Math.floor;y.exports=Math.trunc||function(){function n(r){var o=+r;return(o>0?t:e)(o)}return n}()},37713:function(y,e,t){"use strict";var n=t(74685),r=t(44915),o=t(75754),a=t(60375).set,s=t(9547),u=t(83433),l=t(51802),p=t(63383),f=t(81702),i=n.MutationObserver||n.WebKitMutationObserver,d=n.document,c=n.process,g=n.Promise,v=r("queueMicrotask"),h,m,E,I,O;if(!v){var b=new s,S=function(){var C,A;for(f&&(C=c.domain)&&C.exit();A=b.get();)try{A()}catch(P){throw b.head&&h(),P}C&&C.enter()};!u&&!f&&!p&&i&&d?(m=!0,E=d.createTextNode(""),new i(S).observe(E,{characterData:!0}),h=function(){E.data=m=!m}):!l&&g&&g.resolve?(I=g.resolve(void 0),I.constructor=g,O=o(I.then,I),h=function(){O(S)}):f?h=function(){c.nextTick(S)}:(a=o(a,n),h=function(){a(S)}),v=function(C){b.head||h(),b.add(C)}}y.exports=v},81837:function(y,e,t){"use strict";var n=t(10320),r=TypeError,o=function(s){var u,l;this.promise=new s(function(p,f){if(u!==void 0||l!==void 0)throw new r("Bad Promise constructor");u=p,l=f}),this.resolve=n(u),this.reject=n(l)};y.exports.f=function(a){return new o(a)}},86213:function(y,e,t){"use strict";var n=t(72586),r=TypeError;y.exports=function(o){if(n(o))throw new r("The method doesn't accept regular expressions");return o}},3294:function(y,e,t){"use strict";var n=t(74685),r=n.isFinite;y.exports=Number.isFinite||function(){function o(a){return typeof a=="number"&&r(a)}return o}()},28506:function(y,e,t){"use strict";var n=t(74685),r=t(40033),o=t(67250),a=t(12605),s=t(92648).trim,u=t(4198),l=o("".charAt),p=n.parseFloat,f=n.Symbol,i=f&&f.iterator,d=1/p(u+"-0")!==-1/0||i&&!r(function(){p(Object(i))});y.exports=d?function(){function c(g){var v=s(a(g)),h=p(v);return h===0&&l(v,0)==="-"?-0:h}return c}():p},13693:function(y,e,t){"use strict";var n=t(74685),r=t(40033),o=t(67250),a=t(12605),s=t(92648).trim,u=t(4198),l=n.parseInt,p=n.Symbol,f=p&&p.iterator,i=/^[+-]?0x/i,d=o(i.exec),c=l(u+"08")!==8||l(u+"0x16")!==22||f&&!r(function(){l(Object(f))});y.exports=c?function(){function g(v,h){var m=s(a(v));return l(m,h>>>0||(d(i,m)?16:10))}return g}():l},41143:function(y,e,t){"use strict";var n=t(58310),r=t(67250),o=t(91495),a=t(40033),s=t(18450),u=t(89235),l=t(12867),p=t(46771),f=t(37457),i=Object.assign,d=Object.defineProperty,c=r([].concat);y.exports=!i||a(function(){if(n&&i({b:1},i(d({},"a",{enumerable:!0,get:function(){function E(){d(this,"b",{value:3,enumerable:!1})}return E}()}),{b:2})).b!==1)return!0;var g={},v={},h=Symbol("assign detection"),m="abcdefghijklmnopqrst";return g[h]=7,m.split("").forEach(function(E){v[E]=E}),i({},g)[h]!==7||s(i({},v)).join("")!==m})?function(){function g(v,h){for(var m=p(v),E=arguments.length,I=1,O=u.f,b=l.f;E>I;)for(var S=f(arguments[I++]),T=O?c(s(S),O(S)):s(S),C=T.length,A=0,P;C>A;)P=T[A++],(!n||o(b,S,P))&&(m[P]=S[P]);return m}return g}():i},80674:function(y,e,t){"use strict";var n=t(30365),r=t(24239),o=t(89453),a=t(79195),s=t(5315),u=t(12689),l=t(19417),p=">",f="<",i="prototype",d="script",c=l("IE_PROTO"),g=function(){},v=function(b){return f+d+p+b+f+"/"+d+p},h=function(b){b.write(v("")),b.close();var S=b.parentWindow.Object;return b=null,S},m=function(){var b=u("iframe"),S="java"+d+":",T;return b.style.display="none",s.appendChild(b),b.src=String(S),T=b.contentWindow.document,T.open(),T.write(v("document.F=Object")),T.close(),T.F},E,I=function(){try{E=new ActiveXObject("htmlfile")}catch(S){}I=typeof document!="undefined"?document.domain&&E?h(E):m():h(E);for(var b=o.length;b--;)delete I[i][o[b]];return I()};a[c]=!0,y.exports=Object.create||function(){function O(b,S){var T;return b!==null?(g[i]=n(b),T=new g,g[i]=null,T[c]=b):T=I(),S===void 0?T:r.f(T,S)}return O}()},24239:function(y,e,t){"use strict";var n=t(58310),r=t(80944),o=t(74595),a=t(30365),s=t(57591),u=t(18450);e.f=n&&!r?Object.defineProperties:function(){function l(p,f){a(p);for(var i=s(f),d=u(f),c=d.length,g=0,v;c>g;)o.f(p,v=d[g++],i[v]);return p}return l}()},74595:function(y,e,t){"use strict";var n=t(58310),r=t(36223),o=t(80944),a=t(30365),s=t(767),u=TypeError,l=Object.defineProperty,p=Object.getOwnPropertyDescriptor,f="enumerable",i="configurable",d="writable";e.f=n?o?function(){function c(g,v,h){if(a(g),v=s(v),a(h),typeof g=="function"&&v==="prototype"&&"value"in h&&d in h&&!h[d]){var m=p(g,v);m&&m[d]&&(g[v]=h.value,h={configurable:i in h?h[i]:m[i],enumerable:f in h?h[f]:m[f],writable:!1})}return l(g,v,h)}return c}():l:function(){function c(g,v,h){if(a(g),v=s(v),a(h),r)try{return l(g,v,h)}catch(m){}if("get"in h||"set"in h)throw new u("Accessors not supported");return"value"in h&&(g[v]=h.value),g}return c}()},27193:function(y,e,t){"use strict";var n=t(58310),r=t(91495),o=t(12867),a=t(87458),s=t(57591),u=t(767),l=t(45299),p=t(36223),f=Object.getOwnPropertyDescriptor;e.f=n?f:function(){function i(d,c){if(d=s(d),c=u(c),p)try{return f(d,c)}catch(g){}if(l(d,c))return a(!r(o.f,d,c),d[c])}return i}()},81644:function(y,e,t){"use strict";var n=t(7462),r=t(57591),o=t(37310).f,a=t(54602),s=typeof window=="object"&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],u=function(p){try{return o(p)}catch(f){return a(s)}};y.exports.f=function(){function l(p){return s&&n(p)==="Window"?u(p):o(r(p))}return l}()},37310:function(y,e,t){"use strict";var n=t(53726),r=t(89453),o=r.concat("length","prototype");e.f=Object.getOwnPropertyNames||function(){function a(s){return n(s,o)}return a}()},89235:function(y,e){"use strict";e.f=Object.getOwnPropertySymbols},36917:function(y,e,t){"use strict";var n=t(45299),r=t(55747),o=t(46771),a=t(19417),s=t(9225),u=a("IE_PROTO"),l=Object,p=l.prototype;y.exports=s?l.getPrototypeOf:function(f){var i=o(f);if(n(i,u))return i[u];var d=i.constructor;return r(d)&&i instanceof d?d.prototype:i instanceof l?p:null}},81834:function(y,e,t){"use strict";var n=t(40033),r=t(77568),o=t(7462),a=t(3782),s=Object.isExtensible,u=n(function(){s(1)});y.exports=u||a?function(){function l(p){return!r(p)||a&&o(p)==="ArrayBuffer"?!1:s?s(p):!0}return l}():s},21287:function(y,e,t){"use strict";var n=t(67250);y.exports=n({}.isPrototypeOf)},53726:function(y,e,t){"use strict";var n=t(67250),r=t(45299),o=t(57591),a=t(14211).indexOf,s=t(79195),u=n([].push);y.exports=function(l,p){var f=o(l),i=0,d=[],c;for(c in f)!r(s,c)&&r(f,c)&&u(d,c);for(;p.length>i;)r(f,c=p[i++])&&(~a(d,c)||u(d,c));return d}},18450:function(y,e,t){"use strict";var n=t(53726),r=t(89453);y.exports=Object.keys||function(){function o(a){return n(a,r)}return o}()},12867:function(y,e){"use strict";var t={}.propertyIsEnumerable,n=Object.getOwnPropertyDescriptor,r=n&&!t.call({1:2},1);e.f=r?function(){function o(a){var s=n(this,a);return!!s&&s.enumerable}return o}():t},57377:function(y,e,t){"use strict";var n=t(4493),r=t(74685),o=t(40033),a=t(9342);y.exports=n||!o(function(){if(!(a&&a<535)){var s=Math.random();__defineSetter__.call(null,s,function(){}),delete r[s]}})},76649:function(y,e,t){"use strict";var n=t(38656),r=t(77568),o=t(16952),a=t(35908);y.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var s=!1,u={},l;try{l=n(Object.prototype,"__proto__","set"),l(u,[]),s=u instanceof Array}catch(p){}return function(){function p(f,i){return o(f),a(i),r(f)&&(s?l(f,i):f.__proto__=i),f}return p}()}():void 0)},70915:function(y,e,t){"use strict";var n=t(58310),r=t(40033),o=t(67250),a=t(36917),s=t(18450),u=t(57591),l=t(12867).f,p=o(l),f=o([].push),i=n&&r(function(){var c=Object.create(null);return c[2]=2,!p(c,2)}),d=function(g){return function(v){for(var h=u(v),m=s(h),E=i&&a(h)===null,I=m.length,O=0,b=[],S;I>O;)S=m[O++],(!n||(E?S in h:p(h,S)))&&f(b,g?[S,h[S]]:h[S]);return b}};y.exports={entries:d(!0),values:d(!1)}},2509:function(y,e,t){"use strict";var n=t(2650),r=t(2281);y.exports=n?{}.toString:function(){function o(){return"[object "+r(this)+"]"}return o}()},13396:function(y,e,t){"use strict";var n=t(91495),r=t(55747),o=t(77568),a=TypeError;y.exports=function(s,u){var l,p;if(u==="string"&&r(l=s.toString)&&!o(p=n(l,s))||r(l=s.valueOf)&&!o(p=n(l,s))||u!=="string"&&r(l=s.toString)&&!o(p=n(l,s)))return p;throw new a("Can't convert object to primitive value")}},97921:function(y,e,t){"use strict";var n=t(4009),r=t(67250),o=t(37310),a=t(89235),s=t(30365),u=r([].concat);y.exports=n("Reflect","ownKeys")||function(){function l(p){var f=o.f(s(p)),i=a.f;return i?u(f,i(p)):f}return l}()},61765:function(y,e,t){"use strict";var n=t(74685);y.exports=n},10729:function(y){"use strict";y.exports=function(e){try{return{error:!1,value:e()}}catch(t){return{error:!0,value:t}}}},74854:function(y,e,t){"use strict";var n=t(74685),r=t(67512),o=t(55747),a=t(41314),s=t(40492),u=t(24697),l=t(8180),p=t(73730),f=t(4493),i=t(5026),d=r&&r.prototype,c=u("species"),g=!1,v=o(n.PromiseRejectionEvent),h=a("Promise",function(){var m=s(r),E=m!==String(r);if(!E&&i===66||f&&!(d.catch&&d.finally))return!0;if(!i||i<51||!/native code/.test(m)){var I=new r(function(S){S(1)}),O=function(T){T(function(){},function(){})},b=I.constructor={};if(b[c]=O,g=I.then(function(){})instanceof O,!g)return!0}return!E&&(l||p)&&!v});y.exports={CONSTRUCTOR:h,REJECTION_EVENT:v,SUBCLASSING:g}},67512:function(y,e,t){"use strict";var n=t(74685);y.exports=n.Promise},66628:function(y,e,t){"use strict";var n=t(30365),r=t(77568),o=t(81837);y.exports=function(a,s){if(n(a),r(s)&&s.constructor===a)return s;var u=o.f(a),l=u.resolve;return l(s),u.promise}},48199:function(y,e,t){"use strict";var n=t(67512),r=t(92490),o=t(74854).CONSTRUCTOR;y.exports=o||!r(function(a){n.all(a).then(void 0,function(){})})},34550:function(y,e,t){"use strict";var n=t(74595).f;y.exports=function(r,o,a){a in r||n(r,a,{configurable:!0,get:function(){function s(){return o[a]}return s}(),set:function(){function s(u){o[a]=u}return s}()})}},9547:function(y){"use strict";var e=function(){this.head=null,this.tail=null};e.prototype={add:function(){function t(n){var r={item:n,next:null},o=this.tail;o?o.next=r:this.head=r,this.tail=r}return t}(),get:function(){function t(){var n=this.head;if(n){var r=this.head=n.next;return r===null&&(this.tail=null),n.item}}return t}()},y.exports=e},28340:function(y,e,t){"use strict";var n=t(91495),r=t(30365),o=t(55747),a=t(7462),s=t(14489),u=TypeError;y.exports=function(l,p){var f=l.exec;if(o(f)){var i=n(f,l,p);return i!==null&&r(i),i}if(a(l)==="RegExp")return n(s,l,p);throw new u("RegExp#exec called on incompatible receiver")}},14489:function(y,e,t){"use strict";var n=t(91495),r=t(67250),o=t(12605),a=t(70901),s=t(62115),u=t(16639),l=t(80674),p=t(5419).get,f=t(39173),i=t(35688),d=u("native-string-replace",String.prototype.replace),c=RegExp.prototype.exec,g=c,v=r("".charAt),h=r("".indexOf),m=r("".replace),E=r("".slice),I=function(){var T=/a/,C=/b*/g;return n(c,T,"a"),n(c,C,"a"),T.lastIndex!==0||C.lastIndex!==0}(),O=s.BROKEN_CARET,b=/()??/.exec("")[1]!==void 0,S=I||b||O||f||i;S&&(g=function(){function T(C){var A=this,P=p(A),M=o(C),w=P.raw,V,U,j,G,$,x,B;if(w)return w.lastIndex=A.lastIndex,V=n(g,w,M),A.lastIndex=w.lastIndex,V;var F=P.groups,H=O&&A.sticky,K=n(a,A),W=A.source,q=0,ut=M;if(H&&(K=m(K,"y",""),h(K,"g")===-1&&(K+="g"),ut=E(M,A.lastIndex),A.lastIndex>0&&(!A.multiline||A.multiline&&v(M,A.lastIndex-1)!=="\n")&&(W="(?: "+W+")",ut=" "+ut,q++),U=new RegExp("^(?:"+W+")",K)),b&&(U=new RegExp("^"+W+"$(?!\\s)",K)),I&&(j=A.lastIndex),G=n(c,H?U:A,ut),H?G?(G.input=E(G.input,q),G[0]=E(G[0],q),G.index=A.lastIndex,A.lastIndex+=G[0].length):A.lastIndex=0:I&&G&&(A.lastIndex=A.global?G.index+G[0].length:j),b&&G&&G.length>1&&n(d,G[0],U,function(){for($=1;$b)","g");return a.exec("b").groups.a!=="b"||"b".replace(a,"$c")!=="bc"})},16952:function(y,e,t){"use strict";var n=t(42871),r=TypeError;y.exports=function(o){if(n(o))throw new r("Can't call method on "+o);return o}},44915:function(y,e,t){"use strict";var n=t(74685),r=t(58310),o=Object.getOwnPropertyDescriptor;y.exports=function(a){if(!r)return n[a];var s=o(n,a);return s&&s.value}},5700:function(y){"use strict";y.exports=Object.is||function(){function e(t,n){return t===n?t!==0||1/t===1/n:t!==t&&n!==n}return e}()},78362:function(y,e,t){"use strict";var n=t(74685),r=t(61267),o=t(55747),a=t(49197),s=t(63318),u=t(54602),l=t(24986),p=n.Function,f=/MSIE .\./.test(s)||a&&function(){var i=n.Bun.version.split(".");return i.length<3||i[0]==="0"&&(i[1]<3||i[1]==="3"&&i[2]==="0")}();y.exports=function(i,d){var c=d?2:1;return f?function(g,v){var h=l(arguments.length,1)>c,m=o(g)?g:p(g),E=h?u(arguments,c):[],I=h?function(){r(m,this,E)}:m;return d?i(I,v):i(I)}:i}},58491:function(y,e,t){"use strict";var n=t(4009),r=t(73936),o=t(24697),a=t(58310),s=o("species");y.exports=function(u){var l=n(u);a&&l&&!l[s]&&r(l,s,{configurable:!0,get:function(){function p(){return this}return p}()})}},84925:function(y,e,t){"use strict";var n=t(74595).f,r=t(45299),o=t(24697),a=o("toStringTag");y.exports=function(s,u,l){s&&!l&&(s=s.prototype),s&&!r(s,a)&&n(s,a,{configurable:!0,value:u})}},19417:function(y,e,t){"use strict";var n=t(16639),r=t(16738),o=n("keys");y.exports=function(a){return o[a]||(o[a]=r(a))}},40095:function(y,e,t){"use strict";var n=t(4493),r=t(74685),o=t(18231),a="__core-js_shared__",s=y.exports=r[a]||o(a,{});(s.versions||(s.versions=[])).push({version:"3.37.1",mode:n?"pure":"global",copyright:"\xA9 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.37.1/LICENSE",source:"https://github.com/zloirock/core-js"})},16639:function(y,e,t){"use strict";var n=t(40095);y.exports=function(r,o){return n[r]||(n[r]=o||{})}},28987:function(y,e,t){"use strict";var n=t(30365),r=t(32606),o=t(42871),a=t(24697),s=a("species");y.exports=function(u,l){var p=n(u).constructor,f;return p===void 0||o(f=n(p)[s])?l:r(f)}},88539:function(y,e,t){"use strict";var n=t(40033);y.exports=function(r){return n(function(){var o=""[r]('"');return o!==o.toLowerCase()||o.split('"').length>3})}},50233:function(y,e,t){"use strict";var n=t(67250),r=t(61365),o=t(12605),a=t(16952),s=n("".charAt),u=n("".charCodeAt),l=n("".slice),p=function(i){return function(d,c){var g=o(a(d)),v=r(c),h=g.length,m,E;return v<0||v>=h?i?"":void 0:(m=u(g,v),m<55296||m>56319||v+1===h||(E=u(g,v+1))<56320||E>57343?i?s(g,v):m:i?l(g,v,v+2):(m-55296<<10)+(E-56320)+65536)}};y.exports={codeAt:p(!1),charAt:p(!0)}},34125:function(y,e,t){"use strict";var n=t(63318);y.exports=/Version\/10(?:\.\d+){1,2}(?: [\w./]+)?(?: Mobile\/\w+)? Safari\//.test(n)},24051:function(y,e,t){"use strict";var n=t(67250),r=t(10188),o=t(12605),a=t(62443),s=t(16952),u=n(a),l=n("".slice),p=Math.ceil,f=function(d){return function(c,g,v){var h=o(s(c)),m=r(g),E=h.length,I=v===void 0?" ":o(v),O,b;return m<=E||I===""?h:(O=m-E,b=u(I,p(O/I.length)),b.length>O&&(b=l(b,0,O)),d?h+b:b+h)}};y.exports={start:f(!1),end:f(!0)}},62443:function(y,e,t){"use strict";var n=t(61365),r=t(12605),o=t(16952),a=RangeError;y.exports=function(){function s(u){var l=r(o(this)),p="",f=n(u);if(f<0||f===1/0)throw new a("Wrong number of repetitions");for(;f>0;(f>>>=1)&&(l+=l))f&1&&(p+=l);return p}return s}()},43476:function(y,e,t){"use strict";var n=t(92648).end,r=t(90012);y.exports=r("trimEnd")?function(){function o(){return n(this)}return o}():"".trimEnd},90012:function(y,e,t){"use strict";var n=t(70520).PROPER,r=t(40033),o=t(4198),a="\u200B\x85\u180E";y.exports=function(s){return r(function(){return!!o[s]()||a[s]()!==a||n&&o[s].name!==s})}},43885:function(y,e,t){"use strict";var n=t(92648).start,r=t(90012);y.exports=r("trimStart")?function(){function o(){return n(this)}return o}():"".trimStart},92648:function(y,e,t){"use strict";var n=t(67250),r=t(16952),o=t(12605),a=t(4198),s=n("".replace),u=RegExp("^["+a+"]+"),l=RegExp("(^|[^"+a+"])["+a+"]+$"),p=function(i){return function(d){var c=o(r(d));return i&1&&(c=s(c,u,"")),i&2&&(c=s(c,l,"$1")),c}};y.exports={start:p(1),end:p(2),trim:p(3)}},52357:function(y,e,t){"use strict";var n=t(5026),r=t(40033),o=t(74685),a=o.String;y.exports=!!Object.getOwnPropertySymbols&&!r(function(){var s=Symbol("symbol detection");return!a(s)||!(Object(s)instanceof Symbol)||!Symbol.sham&&n&&n<41})},52360:function(y,e,t){"use strict";var n=t(91495),r=t(4009),o=t(24697),a=t(55938);y.exports=function(){var s=r("Symbol"),u=s&&s.prototype,l=u&&u.valueOf,p=o("toPrimitive");u&&!u[p]&&a(u,p,function(f){return n(l,this)},{arity:1})}},66570:function(y,e,t){"use strict";var n=t(52357);y.exports=n&&!!Symbol.for&&!!Symbol.keyFor},60375:function(y,e,t){"use strict";var n=t(74685),r=t(61267),o=t(75754),a=t(55747),s=t(45299),u=t(40033),l=t(5315),p=t(54602),f=t(12689),i=t(24986),d=t(83433),c=t(81702),g=n.setImmediate,v=n.clearImmediate,h=n.process,m=n.Dispatch,E=n.Function,I=n.MessageChannel,O=n.String,b=0,S={},T="onreadystatechange",C,A,P,M;u(function(){C=n.location});var w=function($){if(s(S,$)){var x=S[$];delete S[$],x()}},V=function($){return function(){w($)}},U=function($){w($.data)},j=function($){n.postMessage(O($),C.protocol+"//"+C.host)};(!g||!v)&&(g=function(){function G($){i(arguments.length,1);var x=a($)?$:E($),B=p(arguments,1);return S[++b]=function(){r(x,void 0,B)},A(b),b}return G}(),v=function(){function G($){delete S[$]}return G}(),c?A=function($){h.nextTick(V($))}:m&&m.now?A=function($){m.now(V($))}:I&&!d?(P=new I,M=P.port2,P.port1.onmessage=U,A=o(M.postMessage,M)):n.addEventListener&&a(n.postMessage)&&!n.importScripts&&C&&C.protocol!=="file:"&&!u(j)?(A=j,n.addEventListener("message",U,!1)):T in f("script")?A=function($){l.appendChild(f("script"))[T]=function(){l.removeChild(this),w($)}}:A=function($){setTimeout(V($),0)}),y.exports={set:g,clear:v}},46438:function(y,e,t){"use strict";var n=t(67250);y.exports=n(1 .valueOf)},13912:function(y,e,t){"use strict";var n=t(61365),r=Math.max,o=Math.min;y.exports=function(a,s){var u=n(a);return u<0?r(u+s,0):o(u,s)}},61484:function(y,e,t){"use strict";var n=t(24843),r=TypeError;y.exports=function(o){var a=n(o,"number");if(typeof a=="number")throw new r("Can't convert number to bigint");return BigInt(a)}},43806:function(y,e,t){"use strict";var n=t(61365),r=t(10188),o=RangeError;y.exports=function(a){if(a===void 0)return 0;var s=n(a),u=r(s);if(s!==u)throw new o("Wrong length or index");return u}},57591:function(y,e,t){"use strict";var n=t(37457),r=t(16952);y.exports=function(o){return n(r(o))}},61365:function(y,e,t){"use strict";var n=t(21119);y.exports=function(r){var o=+r;return o!==o||o===0?0:n(o)}},10188:function(y,e,t){"use strict";var n=t(61365),r=Math.min;y.exports=function(o){var a=n(o);return a>0?r(a,9007199254740991):0}},46771:function(y,e,t){"use strict";var n=t(16952),r=Object;y.exports=function(o){return r(n(o))}},56043:function(y,e,t){"use strict";var n=t(16140),r=RangeError;y.exports=function(o,a){var s=n(o);if(s%a)throw new r("Wrong offset");return s}},16140:function(y,e,t){"use strict";var n=t(61365),r=RangeError;y.exports=function(o){var a=n(o);if(a<0)throw new r("The argument can't be less than 0");return a}},24843:function(y,e,t){"use strict";var n=t(91495),r=t(77568),o=t(71399),a=t(78060),s=t(13396),u=t(24697),l=TypeError,p=u("toPrimitive");y.exports=function(f,i){if(!r(f)||o(f))return f;var d=a(f,p),c;if(d){if(i===void 0&&(i="default"),c=n(d,f,i),!r(c)||o(c))return c;throw new l("Can't convert object to primitive value")}return i===void 0&&(i="number"),s(f,i)}},767:function(y,e,t){"use strict";var n=t(24843),r=t(71399);y.exports=function(o){var a=n(o,"string");return r(a)?a:a+""}},2650:function(y,e,t){"use strict";var n=t(24697),r=n("toStringTag"),o={};o[r]="z",y.exports=String(o)==="[object z]"},12605:function(y,e,t){"use strict";var n=t(2281),r=String;y.exports=function(o){if(n(o)==="Symbol")throw new TypeError("Cannot convert a Symbol value to a string");return r(o)}},15409:function(y){"use strict";var e=Math.round;y.exports=function(t){var n=e(t);return n<0?0:n>255?255:n&255}},89393:function(y){"use strict";var e=String;y.exports=function(t){try{return e(t)}catch(n){return"Object"}}},80185:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(91495),a=t(58310),s=t(86563),u=t(4246),l=t(37336),p=t(60077),f=t(87458),i=t(37909),d=t(5841),c=t(10188),g=t(43806),v=t(56043),h=t(15409),m=t(767),E=t(45299),I=t(2281),O=t(77568),b=t(71399),S=t(80674),T=t(21287),C=t(76649),A=t(37310).f,P=t(3805),M=t(22603).forEach,w=t(58491),V=t(73936),U=t(74595),j=t(27193),G=t(78008),$=t(5419),x=t(5781),B=$.get,F=$.set,H=$.enforce,K=U.f,W=j.f,q=r.RangeError,ut=l.ArrayBuffer,ct=ut.prototype,Q=l.DataView,X=u.NATIVE_ARRAY_BUFFER_VIEWS,at=u.TYPED_ARRAY_TAG,ft=u.TypedArray,dt=u.TypedArrayPrototype,_=u.isTypedArray,rt="BYTES_PER_ELEMENT",it="Wrong length",mt=function(pt,Et){V(pt,Et,{configurable:!0,get:function(){function st(){return B(this)[Et]}return st}()})},ot=function(pt){var Et;return T(ct,pt)||(Et=I(pt))==="ArrayBuffer"||Et==="SharedArrayBuffer"},et=function(pt,Et){return _(pt)&&!b(Et)&&Et in pt&&d(+Et)&&Et>=0},k=function(){function nt(pt,Et){return Et=m(Et),et(pt,Et)?f(2,pt[Et]):W(pt,Et)}return nt}(),tt=function(){function nt(pt,Et,st){return Et=m(Et),et(pt,Et)&&O(st)&&E(st,"value")&&!E(st,"get")&&!E(st,"set")&&!st.configurable&&(!E(st,"writable")||st.writable)&&(!E(st,"enumerable")||st.enumerable)?(pt[Et]=st.value,pt):K(pt,Et,st)}return nt}();a?(X||(j.f=k,U.f=tt,mt(dt,"buffer"),mt(dt,"byteOffset"),mt(dt,"byteLength"),mt(dt,"length")),n({target:"Object",stat:!0,forced:!X},{getOwnPropertyDescriptor:k,defineProperty:tt}),y.exports=function(nt,pt,Et){var st=nt.match(/\d+/)[0]/8,yt=nt+(Et?"Clamped":"")+"Array",Pt="get"+nt,Ct="set"+nt,lt=r[yt],gt=lt,It=gt&>.prototype,Lt={},Vt=function(Tt,Nt){var Ft=B(Tt);return Ft.view[Pt](Nt*st+Ft.byteOffset,!0)},Ot=function(Tt,Nt,Ft){var jt=B(Tt);jt.view[Ct](Nt*st+jt.byteOffset,Et?h(Ft):Ft,!0)},vt=function(Tt,Nt){K(Tt,Nt,{get:function(){function Ft(){return Vt(this,Nt)}return Ft}(),set:function(){function Ft(jt){return Ot(this,Nt,jt)}return Ft}(),enumerable:!0})};X?s&&(gt=pt(function(At,Tt,Nt,Ft){return p(At,It),x(function(){return O(Tt)?ot(Tt)?Ft!==void 0?new lt(Tt,v(Nt,st),Ft):Nt!==void 0?new lt(Tt,v(Nt,st)):new lt(Tt):_(Tt)?G(gt,Tt):o(P,gt,Tt):new lt(g(Tt))}(),At,gt)}),C&&C(gt,ft),M(A(lt),function(At){At in gt||i(gt,At,lt[At])}),gt.prototype=It):(gt=pt(function(At,Tt,Nt,Ft){p(At,It);var jt=0,Ht=0,Kt,Gt,Wt;if(!O(Tt))Wt=g(Tt),Gt=Wt*st,Kt=new ut(Gt);else if(ot(Tt)){Kt=Tt,Ht=v(Nt,st);var te=Tt.byteLength;if(Ft===void 0){if(te%st)throw new q(it);if(Gt=te-Ht,Gt<0)throw new q(it)}else if(Gt=c(Ft)*st,Gt+Ht>te)throw new q(it);Wt=Gt/st}else return _(Tt)?G(gt,Tt):o(P,gt,Tt);for(F(At,{buffer:Kt,byteOffset:Ht,byteLength:Gt,length:Wt,view:new Q(Kt)});jt1?arguments[1]:void 0,I=E!==void 0,O=l(h),b,S,T,C,A,P,M,w;if(O&&!p(O))for(M=u(h,O),w=M.next,h=[];!(P=r(w,M)).done;)h.push(P.value);for(I&&m>2&&(E=n(E,arguments[2])),S=s(h),T=new(i(v))(S),C=f(T),b=0;S>b;b++)A=I?E(h[b],b):h[b],T[b]=C?d(A):+A;return T}return c}()},31082:function(y,e,t){"use strict";var n=t(4246),r=t(28987),o=n.aTypedArrayConstructor,a=n.getTypedArrayConstructor;y.exports=function(s){return o(r(s,a(s)))}},16738:function(y,e,t){"use strict";var n=t(67250),r=0,o=Math.random(),a=n(1 .toString);y.exports=function(s){return"Symbol("+(s===void 0?"":s)+")_"+a(++r+o,36)}},1062:function(y,e,t){"use strict";var n=t(52357);y.exports=n&&!Symbol.sham&&typeof Symbol.iterator=="symbol"},80944:function(y,e,t){"use strict";var n=t(58310),r=t(40033);y.exports=n&&r(function(){return Object.defineProperty(function(){},"prototype",{value:42,writable:!1}).prototype!==42})},24986:function(y){"use strict";var e=TypeError;y.exports=function(t,n){if(t=51||!r(function(){var E=[];return E[g]=!1,E.concat()[0]!==E}),h=function(I){if(!a(I))return!1;var O=I[g];return O!==void 0?!!O:o(I)},m=!v||!i("concat");n({target:"Array",proto:!0,arity:1,forced:m},{concat:function(){function E(I){var O=s(this),b=f(O,0),S=0,T,C,A,P,M;for(T=-1,A=arguments.length;T1?arguments[1]:void 0)}return s}()})},68933:function(y,e,t){"use strict";var n=t(63964),r=t(88471),o=t(80575);n({target:"Array",proto:!0},{fill:r}),o("fill")},47830:function(y,e,t){"use strict";var n=t(63964),r=t(22603).filter,o=t(44091),a=o("filter");n({target:"Array",proto:!0,forced:!a},{filter:function(){function s(u){return r(this,u,arguments.length>1?arguments[1]:void 0)}return s}()})},64094:function(y,e,t){"use strict";var n=t(63964),r=t(22603).findIndex,o=t(80575),a="findIndex",s=!0;a in[]&&Array(1)[a](function(){s=!1}),n({target:"Array",proto:!0,forced:s},{findIndex:function(){function u(l){return r(this,l,arguments.length>1?arguments[1]:void 0)}return u}()}),o(a)},13455:function(y,e,t){"use strict";var n=t(63964),r=t(22603).find,o=t(80575),a="find",s=!0;a in[]&&Array(1)[a](function(){s=!1}),n({target:"Array",proto:!0,forced:s},{find:function(){function u(l){return r(this,l,arguments.length>1?arguments[1]:void 0)}return u}()}),o(a)},32384:function(y,e,t){"use strict";var n=t(63964),r=t(65561),o=t(10320),a=t(46771),s=t(24760),u=t(57823);n({target:"Array",proto:!0},{flatMap:function(){function l(p){var f=a(this),i=s(f),d;return o(p),d=u(f,0),d.length=r(d,f,f,i,0,1,p,arguments.length>1?arguments[1]:void 0),d}return l}()})},61915:function(y,e,t){"use strict";var n=t(63964),r=t(65561),o=t(46771),a=t(24760),s=t(61365),u=t(57823);n({target:"Array",proto:!0},{flat:function(){function l(){var p=arguments.length?arguments[0]:void 0,f=o(this),i=a(f),d=u(f,0);return d.length=r(d,f,f,i,0,p===void 0?1:s(p)),d}return l}()})},25579:function(y,e,t){"use strict";var n=t(63964),r=t(35601);n({target:"Array",proto:!0,forced:[].forEach!==r},{forEach:r})},63532:function(y,e,t){"use strict";var n=t(63964),r=t(73174),o=t(92490),a=!o(function(s){Array.from(s)});n({target:"Array",stat:!0,forced:a},{from:r})},33425:function(y,e,t){"use strict";var n=t(63964),r=t(14211).includes,o=t(40033),a=t(80575),s=o(function(){return!Array(1).includes()});n({target:"Array",proto:!0,forced:s},{includes:function(){function u(l){return r(this,l,arguments.length>1?arguments[1]:void 0)}return u}()}),a("includes")},43894:function(y,e,t){"use strict";var n=t(63964),r=t(71138),o=t(14211).indexOf,a=t(55528),s=r([].indexOf),u=!!s&&1/s([1],1,-0)<0,l=u||!a("indexOf");n({target:"Array",proto:!0,forced:l},{indexOf:function(){function p(f){var i=arguments.length>1?arguments[1]:void 0;return u?s(this,f,i)||0:o(this,f,i)}return p}()})},99636:function(y,e,t){"use strict";var n=t(63964),r=t(37386);n({target:"Array",stat:!0},{isArray:r})},34570:function(y,e,t){"use strict";var n=t(57591),r=t(80575),o=t(83967),a=t(5419),s=t(74595).f,u=t(65574),l=t(5959),p=t(4493),f=t(58310),i="Array Iterator",d=a.set,c=a.getterFor(i);y.exports=u(Array,"Array",function(v,h){d(this,{type:i,target:n(v),index:0,kind:h})},function(){var v=c(this),h=v.target,m=v.index++;if(!h||m>=h.length)return v.target=void 0,l(void 0,!0);switch(v.kind){case"keys":return l(m,!1);case"values":return l(h[m],!1)}return l([m,h[m]],!1)},"values");var g=o.Arguments=o.Array;if(r("keys"),r("values"),r("entries"),!p&&f&&g.name!=="values")try{s(g,"name",{value:"values"})}catch(v){}},94432:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(37457),a=t(57591),s=t(55528),u=r([].join),l=o!==Object,p=l||!s("join",",");n({target:"Array",proto:!0,forced:p},{join:function(){function f(i){return u(a(this),i===void 0?",":i)}return f}()})},24683:function(y,e,t){"use strict";var n=t(63964),r=t(1325);n({target:"Array",proto:!0,forced:r!==[].lastIndexOf},{lastIndexOf:r})},69984:function(y,e,t){"use strict";var n=t(63964),r=t(22603).map,o=t(44091),a=o("map");n({target:"Array",proto:!0,forced:!a},{map:function(){function s(u){return r(this,u,arguments.length>1?arguments[1]:void 0)}return s}()})},32089:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(1031),a=t(60102),s=Array,u=r(function(){function l(){}return!(s.of.call(l)instanceof l)});n({target:"Array",stat:!0,forced:u},{of:function(){function l(){for(var p=0,f=arguments.length,i=new(o(this)?this:s)(f);f>p;)a(i,p,arguments[p++]);return i.length=f,i}return l}()})},29645:function(y,e,t){"use strict";var n=t(63964),r=t(56844).right,o=t(55528),a=t(5026),s=t(81702),u=!s&&a>79&&a<83,l=u||!o("reduceRight");n({target:"Array",proto:!0,forced:l},{reduceRight:function(){function p(f){return r(this,f,arguments.length,arguments.length>1?arguments[1]:void 0)}return p}()})},60206:function(y,e,t){"use strict";var n=t(63964),r=t(56844).left,o=t(55528),a=t(5026),s=t(81702),u=!s&&a>79&&a<83,l=u||!o("reduce");n({target:"Array",proto:!0,forced:l},{reduce:function(){function p(f){var i=arguments.length;return r(this,f,i,i>1?arguments[1]:void 0)}return p}()})},4788:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(37386),a=r([].reverse),s=[1,2];n({target:"Array",proto:!0,forced:String(s)===String(s.reverse())},{reverse:function(){function u(){return o(this)&&(this.length=this.length),a(this)}return u}()})},58672:function(y,e,t){"use strict";var n=t(63964),r=t(37386),o=t(1031),a=t(77568),s=t(13912),u=t(24760),l=t(57591),p=t(60102),f=t(24697),i=t(44091),d=t(54602),c=i("slice"),g=f("species"),v=Array,h=Math.max;n({target:"Array",proto:!0,forced:!c},{slice:function(){function m(E,I){var O=l(this),b=u(O),S=s(E,b),T=s(I===void 0?b:I,b),C,A,P;if(r(O)&&(C=O.constructor,o(C)&&(C===v||r(C.prototype))?C=void 0:a(C)&&(C=C[g],C===null&&(C=void 0)),C===v||C===void 0))return d(O,S,T);for(A=new(C===void 0?v:C)(h(T-S,0)),P=0;S1?arguments[1]:void 0)}return s}()})},48968:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(10320),a=t(46771),s=t(24760),u=t(95108),l=t(12605),p=t(40033),f=t(90274),i=t(55528),d=t(652),c=t(19228),g=t(5026),v=t(9342),h=[],m=r(h.sort),E=r(h.push),I=p(function(){h.sort(void 0)}),O=p(function(){h.sort(null)}),b=i("sort"),S=!p(function(){if(g)return g<70;if(!(d&&d>3)){if(c)return!0;if(v)return v<603;var A="",P,M,w,V;for(P=65;P<76;P++){switch(M=String.fromCharCode(P),P){case 66:case 69:case 70:case 72:w=3;break;case 68:case 71:w=4;break;default:w=2}for(V=0;V<47;V++)h.push({k:M+V,v:w})}for(h.sort(function(U,j){return j.v-U.v}),V=0;Vl(w)?1:-1}};n({target:"Array",proto:!0,forced:T},{sort:function(){function A(P){P!==void 0&&o(P);var M=a(this);if(S)return P===void 0?m(M):m(M,P);var w=[],V=s(M),U,j;for(j=0;jO-C+T;P--)i(I,P-1)}else if(T>C)for(P=O-C;P>b;P--)M=P+C-1,w=P+T-1,M in I?I[w]=I[M]:i(I,w);for(P=0;P9490626562425156e-8?a(i)+u:r(i-1+s(i-1)*s(i+1))}return p}()})},59660:function(y,e,t){"use strict";var n=t(63964),r=Math.asinh,o=Math.log,a=Math.sqrt;function s(l){var p=+l;return!isFinite(p)||p===0?p:p<0?-s(-p):o(p+a(p*p+1))}var u=!(r&&1/r(0)>0);n({target:"Math",stat:!0,forced:u},{asinh:s})},15383:function(y,e,t){"use strict";var n=t(63964),r=Math.atanh,o=Math.log,a=!(r&&1/r(-0)<0);n({target:"Math",stat:!0,forced:a},{atanh:function(){function s(u){var l=+u;return l===0?l:o((1+l)/(1-l))/2}return s}()})},92866:function(y,e,t){"use strict";var n=t(63964),r=t(22172),o=Math.abs,a=Math.pow;n({target:"Math",stat:!0},{cbrt:function(){function s(u){var l=+u;return r(l)*a(o(l),.3333333333333333)}return s}()})},86107:function(y,e,t){"use strict";var n=t(63964),r=Math.floor,o=Math.log,a=Math.LOG2E;n({target:"Math",stat:!0},{clz32:function(){function s(u){var l=u>>>0;return l?31-r(o(l+.5)*a):32}return s}()})},29248:function(y,e,t){"use strict";var n=t(63964),r=t(82040),o=Math.cosh,a=Math.abs,s=Math.E,u=!o||o(710)===1/0;n({target:"Math",stat:!0,forced:u},{cosh:function(){function l(p){var f=r(a(p)-1)+1;return(f+1/(f*s*s))*(s/2)}return l}()})},52540:function(y,e,t){"use strict";var n=t(63964),r=t(82040);n({target:"Math",stat:!0,forced:r!==Math.expm1},{expm1:r})},79007:function(y,e,t){"use strict";var n=t(63964),r=t(95867);n({target:"Math",stat:!0},{fround:r})},77199:function(y,e,t){"use strict";var n=t(63964),r=Math.hypot,o=Math.abs,a=Math.sqrt,s=!!r&&r(1/0,NaN)!==1/0;n({target:"Math",stat:!0,arity:2,forced:s},{hypot:function(){function u(l,p){for(var f=0,i=0,d=arguments.length,c=0,g,v;i0?(v=g/c,f+=v*v):f+=g;return c===1/0?1/0:c*a(f)}return u}()})},6522:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=Math.imul,a=r(function(){return o(4294967295,5)!==-5||o.length!==2});n({target:"Math",stat:!0,forced:a},{imul:function(){function s(u,l){var p=65535,f=+u,i=+l,d=p&f,c=p&i;return 0|d*c+((p&f>>>16)*c+d*(p&i>>>16)<<16>>>0)}return s}()})},95542:function(y,e,t){"use strict";var n=t(63964),r=t(75002);n({target:"Math",stat:!0},{log10:r})},2966:function(y,e,t){"use strict";var n=t(63964),r=t(90874);n({target:"Math",stat:!0},{log1p:r})},20997:function(y,e,t){"use strict";var n=t(63964),r=Math.log,o=Math.LN2;n({target:"Math",stat:!0},{log2:function(){function a(s){return r(s)/o}return a}()})},57400:function(y,e,t){"use strict";var n=t(63964),r=t(22172);n({target:"Math",stat:!0},{sign:r})},45571:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(82040),a=Math.abs,s=Math.exp,u=Math.E,l=r(function(){return Math.sinh(-2e-17)!==-2e-17});n({target:"Math",stat:!0,forced:l},{sinh:function(){function p(f){var i=+f;return a(i)<1?(o(i)-o(-i))/2:(s(i-1)-s(-i-1))*(u/2)}return p}()})},54800:function(y,e,t){"use strict";var n=t(63964),r=t(82040),o=Math.exp;n({target:"Math",stat:!0},{tanh:function(){function a(s){var u=+s,l=r(u),p=r(-u);return l===1/0?1:p===1/0?-1:(l-p)/(o(u)+o(-u))}return a}()})},15709:function(y,e,t){"use strict";var n=t(84925);n(Math,"Math",!0)},76059:function(y,e,t){"use strict";var n=t(63964),r=t(21119);n({target:"Math",stat:!0},{trunc:r})},96614:function(y,e,t){"use strict";var n=t(63964),r=t(4493),o=t(58310),a=t(74685),s=t(61765),u=t(67250),l=t(41314),p=t(45299),f=t(5781),i=t(21287),d=t(71399),c=t(24843),g=t(40033),v=t(37310).f,h=t(27193).f,m=t(74595).f,E=t(46438),I=t(92648).trim,O="Number",b=a[O],S=s[O],T=b.prototype,C=a.TypeError,A=u("".slice),P=u("".charCodeAt),M=function(x){var B=c(x,"number");return typeof B=="bigint"?B:w(B)},w=function(x){var B=c(x,"number"),F,H,K,W,q,ut,ct,Q;if(d(B))throw new C("Cannot convert a Symbol value to a number");if(typeof B=="string"&&B.length>2){if(B=I(B),F=P(B,0),F===43||F===45){if(H=P(B,2),H===88||H===120)return NaN}else if(F===48){switch(P(B,1)){case 66:case 98:K=2,W=49;break;case 79:case 111:K=8,W=55;break;default:return+B}for(q=A(B,2),ut=q.length,ct=0;ctW)return NaN;return parseInt(q,K)}}return+B},V=l(O,!b(" 0o1")||!b("0b1")||b("+0x1")),U=function(x){return i(T,x)&&g(function(){E(x)})},j=function(){function $(x){var B=arguments.length<1?0:b(M(x));return U(this)?f(Object(B),this,j):B}return $}();j.prototype=T,V&&!r&&(T.constructor=j),n({global:!0,constructor:!0,wrap:!0,forced:V},{Number:j});var G=function(x,B){for(var F=o?v(B):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,isFinite,isInteger,isNaN,isSafeInteger,parseFloat,parseInt,fromString,range".split(","),H=0,K;F.length>H;H++)p(B,K=F[H])&&!p(x,K)&&m(x,K,h(B,K))};r&&S&&G(s[O],S),(V||r)&&G(s[O],b)},324:function(y,e,t){"use strict";var n=t(63964);n({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{EPSILON:Math.pow(2,-52)})},90426:function(y,e,t){"use strict";var n=t(63964),r=t(3294);n({target:"Number",stat:!0},{isFinite:r})},95443:function(y,e,t){"use strict";var n=t(63964),r=t(5841);n({target:"Number",stat:!0},{isInteger:r})},87968:function(y,e,t){"use strict";var n=t(63964);n({target:"Number",stat:!0},{isNaN:function(){function r(o){return o!==o}return r}()})},55007:function(y,e,t){"use strict";var n=t(63964),r=t(5841),o=Math.abs;n({target:"Number",stat:!0},{isSafeInteger:function(){function a(s){return r(s)&&o(s)<=9007199254740991}return a}()})},55323:function(y,e,t){"use strict";var n=t(63964);n({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{MAX_SAFE_INTEGER:9007199254740991})},13521:function(y,e,t){"use strict";var n=t(63964);n({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{MIN_SAFE_INTEGER:-9007199254740991})},5006:function(y,e,t){"use strict";var n=t(63964),r=t(28506);n({target:"Number",stat:!0,forced:Number.parseFloat!==r},{parseFloat:r})},99009:function(y,e,t){"use strict";var n=t(63964),r=t(13693);n({target:"Number",stat:!0,forced:Number.parseInt!==r},{parseInt:r})},85770:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(61365),a=t(46438),s=t(62443),u=t(40033),l=RangeError,p=String,f=Math.floor,i=r(s),d=r("".slice),c=r(1 .toFixed),g=function O(b,S,T){return S===0?T:S%2===1?O(b,S-1,T*b):O(b*b,S/2,T)},v=function(b){for(var S=0,T=b;T>=4096;)S+=12,T/=4096;for(;T>=2;)S+=1,T/=2;return S},h=function(b,S,T){for(var C=-1,A=T;++C<6;)A+=S*b[C],b[C]=A%1e7,A=f(A/1e7)},m=function(b,S){for(var T=6,C=0;--T>=0;)C+=b[T],b[T]=f(C/S),C=C%S*1e7},E=function(b){for(var S=6,T="";--S>=0;)if(T!==""||S===0||b[S]!==0){var C=p(b[S]);T=T===""?C:T+i("0",7-C.length)+C}return T},I=u(function(){return c(8e-5,3)!=="0.000"||c(.9,0)!=="1"||c(1.255,2)!=="1.25"||c(0xde0b6b3a7640080,0)!=="1000000000000000128"})||!u(function(){c({})});n({target:"Number",proto:!0,forced:I},{toFixed:function(){function O(b){var S=a(this),T=o(b),C=[0,0,0,0,0,0],A="",P="0",M,w,V,U;if(T<0||T>20)throw new l("Incorrect fraction digits");if(S!==S)return"NaN";if(S<=-1e21||S>=1e21)return p(S);if(S<0&&(A="-",S=-S),S>1e-21)if(M=v(S*g(2,69,1))-69,w=M<0?S*g(2,-M,1):S/g(2,M,1),w*=4503599627370496,M=52-M,M>0){for(h(C,0,w),V=T;V>=7;)h(C,1e7,0),V-=7;for(h(C,g(10,V,1),0),V=M-1;V>=23;)m(C,8388608),V-=23;m(C,1<0?(U=P.length,P=A+(U<=T?"0."+i("0",T-U)+P:d(P,0,U-T)+"."+d(P,U-T))):P=A+P,P}return O}()})},23532:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(40033),a=t(46438),s=r(1 .toPrecision),u=o(function(){return s(1,void 0)!=="1"})||!o(function(){s({})});n({target:"Number",proto:!0,forced:u},{toPrecision:function(){function l(p){return p===void 0?s(a(this)):s(a(this),p)}return l}()})},87119:function(y,e,t){"use strict";var n=t(63964),r=t(41143);n({target:"Object",stat:!0,arity:2,forced:Object.assign!==r},{assign:r})},78618:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(80674);n({target:"Object",stat:!0,sham:!r},{create:o})},27129:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(57377),a=t(10320),s=t(46771),u=t(74595);r&&n({target:"Object",proto:!0,forced:o},{__defineGetter__:function(){function l(p,f){u.f(s(this),p,{get:a(f),enumerable:!0,configurable:!0})}return l}()})},31943:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(24239).f;n({target:"Object",stat:!0,forced:Object.defineProperties!==o,sham:!r},{defineProperties:o})},3579:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(74595).f;n({target:"Object",stat:!0,forced:Object.defineProperty!==o,sham:!r},{defineProperty:o})},97397:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(57377),a=t(10320),s=t(46771),u=t(74595);r&&n({target:"Object",proto:!0,forced:o},{__defineSetter__:function(){function l(p,f){u.f(s(this),p,{set:a(f),enumerable:!0,configurable:!0})}return l}()})},85028:function(y,e,t){"use strict";var n=t(63964),r=t(70915).entries;n({target:"Object",stat:!0},{entries:function(){function o(a){return r(a)}return o}()})},8225:function(y,e,t){"use strict";var n=t(63964),r=t(50730),o=t(40033),a=t(77568),s=t(81969).onFreeze,u=Object.freeze,l=o(function(){u(1)});n({target:"Object",stat:!0,forced:l,sham:!r},{freeze:function(){function p(f){return u&&a(f)?u(s(f)):f}return p}()})},43331:function(y,e,t){"use strict";var n=t(63964),r=t(49450),o=t(60102);n({target:"Object",stat:!0},{fromEntries:function(){function a(s){var u={};return r(s,function(l,p){o(u,l,p)},{AS_ENTRIES:!0}),u}return a}()})},62289:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(57591),a=t(27193).f,s=t(58310),u=!s||r(function(){a(1)});n({target:"Object",stat:!0,forced:u,sham:!s},{getOwnPropertyDescriptor:function(){function l(p,f){return a(o(p),f)}return l}()})},56196:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(97921),a=t(57591),s=t(27193),u=t(60102);n({target:"Object",stat:!0,sham:!r},{getOwnPropertyDescriptors:function(){function l(p){for(var f=a(p),i=s.f,d=o(f),c={},g=0,v,h;d.length>g;)h=i(f,v=d[g++]),h!==void 0&&u(c,v,h);return c}return l}()})},2950:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(81644).f,a=r(function(){return!Object.getOwnPropertyNames(1)});n({target:"Object",stat:!0,forced:a},{getOwnPropertyNames:o})},28603:function(y,e,t){"use strict";var n=t(63964),r=t(52357),o=t(40033),a=t(89235),s=t(46771),u=!r||o(function(){a.f(1)});n({target:"Object",stat:!0,forced:u},{getOwnPropertySymbols:function(){function l(p){var f=a.f;return f?f(s(p)):[]}return l}()})},44205:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(46771),a=t(36917),s=t(9225),u=r(function(){a(1)});n({target:"Object",stat:!0,forced:u,sham:!s},{getPrototypeOf:function(){function l(p){return a(o(p))}return l}()})},83186:function(y,e,t){"use strict";var n=t(63964),r=t(81834);n({target:"Object",stat:!0,forced:Object.isExtensible!==r},{isExtensible:r})},76065:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(77568),a=t(7462),s=t(3782),u=Object.isFrozen,l=s||r(function(){u(1)});n({target:"Object",stat:!0,forced:l},{isFrozen:function(){function p(f){return!o(f)||s&&a(f)==="ArrayBuffer"?!0:u?u(f):!1}return p}()})},13411:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(77568),a=t(7462),s=t(3782),u=Object.isSealed,l=s||r(function(){u(1)});n({target:"Object",stat:!0,forced:l},{isSealed:function(){function p(f){return!o(f)||s&&a(f)==="ArrayBuffer"?!0:u?u(f):!1}return p}()})},76882:function(y,e,t){"use strict";var n=t(63964),r=t(5700);n({target:"Object",stat:!0},{is:r})},26634:function(y,e,t){"use strict";var n=t(63964),r=t(46771),o=t(18450),a=t(40033),s=a(function(){o(1)});n({target:"Object",stat:!0,forced:s},{keys:function(){function u(l){return o(r(l))}return u}()})},53118:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(57377),a=t(46771),s=t(767),u=t(36917),l=t(27193).f;r&&n({target:"Object",proto:!0,forced:o},{__lookupGetter__:function(){function p(f){var i=a(this),d=s(f),c;do if(c=l(i,d))return c.get;while(i=u(i))}return p}()})},42514:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(57377),a=t(46771),s=t(767),u=t(36917),l=t(27193).f;r&&n({target:"Object",proto:!0,forced:o},{__lookupSetter__:function(){function p(f){var i=a(this),d=s(f),c;do if(c=l(i,d))return c.set;while(i=u(i))}return p}()})},84353:function(y,e,t){"use strict";var n=t(63964),r=t(77568),o=t(81969).onFreeze,a=t(50730),s=t(40033),u=Object.preventExtensions,l=s(function(){u(1)});n({target:"Object",stat:!0,forced:l,sham:!a},{preventExtensions:function(){function p(f){return u&&r(f)?u(o(f)):f}return p}()})},62987:function(y,e,t){"use strict";var n=t(63964),r=t(77568),o=t(81969).onFreeze,a=t(50730),s=t(40033),u=Object.seal,l=s(function(){u(1)});n({target:"Object",stat:!0,forced:l,sham:!a},{seal:function(){function p(f){return u&&r(f)?u(o(f)):f}return p}()})},48993:function(y,e,t){"use strict";var n=t(63964),r=t(76649);n({target:"Object",stat:!0},{setPrototypeOf:r})},52917:function(y,e,t){"use strict";var n=t(2650),r=t(55938),o=t(2509);n||r(Object.prototype,"toString",o,{unsafe:!0})},4972:function(y,e,t){"use strict";var n=t(63964),r=t(70915).values;n({target:"Object",stat:!0},{values:function(){function o(a){return r(a)}return o}()})},28913:function(y,e,t){"use strict";var n=t(63964),r=t(28506);n({global:!0,forced:parseFloat!==r},{parseFloat:r})},36382:function(y,e,t){"use strict";var n=t(63964),r=t(13693);n({global:!0,forced:parseInt!==r},{parseInt:r})},48865:function(y,e,t){"use strict";var n=t(63964),r=t(91495),o=t(10320),a=t(81837),s=t(10729),u=t(49450),l=t(48199);n({target:"Promise",stat:!0,forced:l},{all:function(){function p(f){var i=this,d=a.f(i),c=d.resolve,g=d.reject,v=s(function(){var h=o(i.resolve),m=[],E=0,I=1;u(f,function(O){var b=E++,S=!1;I++,r(h,i,O).then(function(T){S||(S=!0,m[b]=T,--I||c(m))},g)}),--I||c(m)});return v.error&&g(v.value),d.promise}return p}()})},70641:function(y,e,t){"use strict";var n=t(63964),r=t(4493),o=t(74854).CONSTRUCTOR,a=t(67512),s=t(4009),u=t(55747),l=t(55938),p=a&&a.prototype;if(n({target:"Promise",proto:!0,forced:o,real:!0},{catch:function(){function i(d){return this.then(void 0,d)}return i}()}),!r&&u(a)){var f=s("Promise").prototype.catch;p.catch!==f&&l(p,"catch",f,{unsafe:!0})}},75946:function(y,e,t){"use strict";var n=t(63964),r=t(4493),o=t(81702),a=t(74685),s=t(91495),u=t(55938),l=t(76649),p=t(84925),f=t(58491),i=t(10320),d=t(55747),c=t(77568),g=t(60077),v=t(28987),h=t(60375).set,m=t(37713),E=t(72259),I=t(10729),O=t(9547),b=t(5419),S=t(67512),T=t(74854),C=t(81837),A="Promise",P=T.CONSTRUCTOR,M=T.REJECTION_EVENT,w=T.SUBCLASSING,V=b.getterFor(A),U=b.set,j=S&&S.prototype,G=S,$=j,x=a.TypeError,B=a.document,F=a.process,H=C.f,K=H,W=!!(B&&B.createEvent&&a.dispatchEvent),q="unhandledrejection",ut="rejectionhandled",ct=0,Q=1,X=2,at=1,ft=2,dt,_,rt,it,mt=function(Ct){var lt;return c(Ct)&&d(lt=Ct.then)?lt:!1},ot=function(Ct,lt){var gt=lt.value,It=lt.state===Q,Lt=It?Ct.ok:Ct.fail,Vt=Ct.resolve,Ot=Ct.reject,vt=Ct.domain,St,At,Tt;try{Lt?(It||(lt.rejection===ft&&pt(lt),lt.rejection=at),Lt===!0?St=gt:(vt&&vt.enter(),St=Lt(gt),vt&&(vt.exit(),Tt=!0)),St===Ct.promise?Ot(new x("Promise-chain cycle")):(At=mt(St))?s(At,St,Vt,Ot):Vt(St)):Ot(gt)}catch(Nt){vt&&!Tt&&vt.exit(),Ot(Nt)}},et=function(Ct,lt){Ct.notified||(Ct.notified=!0,m(function(){for(var gt=Ct.reactions,It;It=gt.get();)ot(It,Ct);Ct.notified=!1,lt&&!Ct.rejection&&tt(Ct)}))},k=function(Ct,lt,gt){var It,Lt;W?(It=B.createEvent("Event"),It.promise=lt,It.reason=gt,It.initEvent(Ct,!1,!0),a.dispatchEvent(It)):It={promise:lt,reason:gt},!M&&(Lt=a["on"+Ct])?Lt(It):Ct===q&&E("Unhandled promise rejection",gt)},tt=function(Ct){s(h,a,function(){var lt=Ct.facade,gt=Ct.value,It=nt(Ct),Lt;if(It&&(Lt=I(function(){o?F.emit("unhandledRejection",gt,lt):k(q,lt,gt)}),Ct.rejection=o||nt(Ct)?ft:at,Lt.error))throw Lt.value})},nt=function(Ct){return Ct.rejection!==at&&!Ct.parent},pt=function(Ct){s(h,a,function(){var lt=Ct.facade;o?F.emit("rejectionHandled",lt):k(ut,lt,Ct.value)})},Et=function(Ct,lt,gt){return function(It){Ct(lt,It,gt)}},st=function(Ct,lt,gt){Ct.done||(Ct.done=!0,gt&&(Ct=gt),Ct.value=lt,Ct.state=X,et(Ct,!0))},yt=function Pt(Ct,lt,gt){if(!Ct.done){Ct.done=!0,gt&&(Ct=gt);try{if(Ct.facade===lt)throw new x("Promise can't be resolved itself");var It=mt(lt);It?m(function(){var Lt={done:!1};try{s(It,lt,Et(Pt,Lt,Ct),Et(st,Lt,Ct))}catch(Vt){st(Lt,Vt,Ct)}}):(Ct.value=lt,Ct.state=Q,et(Ct,!1))}catch(Lt){st({done:!1},Lt,Ct)}}};if(P&&(G=function(){function Pt(Ct){g(this,$),i(Ct),s(dt,this);var lt=V(this);try{Ct(Et(yt,lt),Et(st,lt))}catch(gt){st(lt,gt)}}return Pt}(),$=G.prototype,dt=function(){function Pt(Ct){U(this,{type:A,done:!1,notified:!1,parent:!1,reactions:new O,rejection:!1,state:ct,value:void 0})}return Pt}(),dt.prototype=u($,"then",function(){function Pt(Ct,lt){var gt=V(this),It=H(v(this,G));return gt.parent=!0,It.ok=d(Ct)?Ct:!0,It.fail=d(lt)&<,It.domain=o?F.domain:void 0,gt.state===ct?gt.reactions.add(It):m(function(){ot(It,gt)}),It.promise}return Pt}()),_=function(){var Ct=new dt,lt=V(Ct);this.promise=Ct,this.resolve=Et(yt,lt),this.reject=Et(st,lt)},C.f=H=function(Ct){return Ct===G||Ct===rt?new _(Ct):K(Ct)},!r&&d(S)&&j!==Object.prototype)){it=j.then,w||u(j,"then",function(){function Pt(Ct,lt){var gt=this;return new G(function(It,Lt){s(it,gt,It,Lt)}).then(Ct,lt)}return Pt}(),{unsafe:!0});try{delete j.constructor}catch(Pt){}l&&l(j,$)}n({global:!0,constructor:!0,wrap:!0,forced:P},{Promise:G}),p(G,A,!1,!0),f(A)},69861:function(y,e,t){"use strict";var n=t(63964),r=t(4493),o=t(67512),a=t(40033),s=t(4009),u=t(55747),l=t(28987),p=t(66628),f=t(55938),i=o&&o.prototype,d=!!o&&a(function(){i.finally.call({then:function(){function g(){}return g}()},function(){})});if(n({target:"Promise",proto:!0,real:!0,forced:d},{finally:function(){function g(v){var h=l(this,s("Promise")),m=u(v);return this.then(m?function(E){return p(h,v()).then(function(){return E})}:v,m?function(E){return p(h,v()).then(function(){throw E})}:v)}return g}()}),!r&&u(o)){var c=s("Promise").prototype.finally;i.finally!==c&&f(i,"finally",c,{unsafe:!0})}},53092:function(y,e,t){"use strict";t(75946),t(48865),t(70641),t(16937),t(41719),t(59321)},16937:function(y,e,t){"use strict";var n=t(63964),r=t(91495),o=t(10320),a=t(81837),s=t(10729),u=t(49450),l=t(48199);n({target:"Promise",stat:!0,forced:l},{race:function(){function p(f){var i=this,d=a.f(i),c=d.reject,g=s(function(){var v=o(i.resolve);u(f,function(h){r(v,i,h).then(d.resolve,c)})});return g.error&&c(g.value),d.promise}return p}()})},41719:function(y,e,t){"use strict";var n=t(63964),r=t(81837),o=t(74854).CONSTRUCTOR;n({target:"Promise",stat:!0,forced:o},{reject:function(){function a(s){var u=r.f(this),l=u.reject;return l(s),u.promise}return a}()})},59321:function(y,e,t){"use strict";var n=t(63964),r=t(4009),o=t(4493),a=t(67512),s=t(74854).CONSTRUCTOR,u=t(66628),l=r("Promise"),p=o&&!s;n({target:"Promise",stat:!0,forced:o||s},{resolve:function(){function f(i){return u(p&&this===l?a:this,i)}return f}()})},29674:function(y,e,t){"use strict";var n=t(63964),r=t(61267),o=t(10320),a=t(30365),s=t(40033),u=!s(function(){Reflect.apply(function(){})});n({target:"Reflect",stat:!0,forced:u},{apply:function(){function l(p,f,i){return r(o(p),f,a(i))}return l}()})},81543:function(y,e,t){"use strict";var n=t(63964),r=t(4009),o=t(61267),a=t(66284),s=t(32606),u=t(30365),l=t(77568),p=t(80674),f=t(40033),i=r("Reflect","construct"),d=Object.prototype,c=[].push,g=f(function(){function m(){}return!(i(function(){},[],m)instanceof m)}),v=!f(function(){i(function(){})}),h=g||v;n({target:"Reflect",stat:!0,forced:h,sham:h},{construct:function(){function m(E,I){s(E),u(I);var O=arguments.length<3?E:s(arguments[2]);if(v&&!g)return i(E,I,O);if(E===O){switch(I.length){case 0:return new E;case 1:return new E(I[0]);case 2:return new E(I[0],I[1]);case 3:return new E(I[0],I[1],I[2]);case 4:return new E(I[0],I[1],I[2],I[3])}var b=[null];return o(c,b,I),new(o(a,E,b))}var S=O.prototype,T=p(l(S)?S:d),C=o(E,T,I);return l(C)?C:T}return m}()})},9373:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(30365),a=t(767),s=t(74595),u=t(40033),l=u(function(){Reflect.defineProperty(s.f({},1,{value:1}),1,{value:2})});n({target:"Reflect",stat:!0,forced:l,sham:!r},{defineProperty:function(){function p(f,i,d){o(f);var c=a(i);o(d);try{return s.f(f,c,d),!0}catch(g){return!1}}return p}()})},45093:function(y,e,t){"use strict";var n=t(63964),r=t(30365),o=t(27193).f;n({target:"Reflect",stat:!0},{deleteProperty:function(){function a(s,u){var l=o(r(s),u);return l&&!l.configurable?!1:delete s[u]}return a}()})},5815:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(30365),a=t(27193);n({target:"Reflect",stat:!0,sham:!r},{getOwnPropertyDescriptor:function(){function s(u,l){return a.f(o(u),l)}return s}()})},88527:function(y,e,t){"use strict";var n=t(63964),r=t(30365),o=t(36917),a=t(9225);n({target:"Reflect",stat:!0,sham:!a},{getPrototypeOf:function(){function s(u){return o(r(u))}return s}()})},63074:function(y,e,t){"use strict";var n=t(63964),r=t(91495),o=t(77568),a=t(30365),s=t(98373),u=t(27193),l=t(36917);function p(f,i){var d=arguments.length<3?f:arguments[2],c,g;if(a(f)===d)return f[i];if(c=u.f(f,i),c)return s(c)?c.value:c.get===void 0?void 0:r(c.get,d);if(o(g=l(f)))return p(g,i,d)}n({target:"Reflect",stat:!0},{get:p})},66390:function(y,e,t){"use strict";var n=t(63964);n({target:"Reflect",stat:!0},{has:function(){function r(o,a){return a in o}return r}()})},7784:function(y,e,t){"use strict";var n=t(63964),r=t(30365),o=t(81834);n({target:"Reflect",stat:!0},{isExtensible:function(){function a(s){return r(s),o(s)}return a}()})},50551:function(y,e,t){"use strict";var n=t(63964),r=t(97921);n({target:"Reflect",stat:!0},{ownKeys:r})},76483:function(y,e,t){"use strict";var n=t(63964),r=t(4009),o=t(30365),a=t(50730);n({target:"Reflect",stat:!0,sham:!a},{preventExtensions:function(){function s(u){o(u);try{var l=r("Object","preventExtensions");return l&&l(u),!0}catch(p){return!1}}return s}()})},63915:function(y,e,t){"use strict";var n=t(63964),r=t(30365),o=t(35908),a=t(76649);a&&n({target:"Reflect",stat:!0},{setPrototypeOf:function(){function s(u,l){r(u),o(l);try{return a(u,l),!0}catch(p){return!1}}return s}()})},92046:function(y,e,t){"use strict";var n=t(63964),r=t(91495),o=t(30365),a=t(77568),s=t(98373),u=t(40033),l=t(74595),p=t(27193),f=t(36917),i=t(87458);function d(g,v,h){var m=arguments.length<4?g:arguments[3],E=p.f(o(g),v),I,O,b;if(!E){if(a(O=f(g)))return d(O,v,h,m);E=i(0)}if(s(E)){if(E.writable===!1||!a(m))return!1;if(I=p.f(m,v)){if(I.get||I.set||I.writable===!1)return!1;I.value=h,l.f(m,v,I)}else l.f(m,v,i(0,h))}else{if(b=E.set,b===void 0)return!1;r(b,m,h)}return!0}var c=u(function(){var g=function(){},v=l.f(new g,"a",{configurable:!0});return Reflect.set(g.prototype,"a",1,v)!==!1});n({target:"Reflect",stat:!0,forced:c},{set:d})},51454:function(y,e,t){"use strict";var n=t(58310),r=t(74685),o=t(67250),a=t(41314),s=t(5781),u=t(37909),l=t(80674),p=t(37310).f,f=t(21287),i=t(72586),d=t(12605),c=t(73392),g=t(62115),v=t(34550),h=t(55938),m=t(40033),E=t(45299),I=t(5419).enforce,O=t(58491),b=t(24697),S=t(39173),T=t(35688),C=b("match"),A=r.RegExp,P=A.prototype,M=r.SyntaxError,w=o(P.exec),V=o("".charAt),U=o("".replace),j=o("".indexOf),G=o("".slice),$=/^\?<[^\s\d!#%&*+<=>@^][^\s!#%&*+<=>@^]*>/,x=/a/g,B=/a/g,F=new A(x)!==x,H=g.MISSED_STICKY,K=g.UNSUPPORTED_Y,W=n&&(!F||H||S||T||m(function(){return B[C]=!1,A(x)!==x||A(B)===B||String(A(x,"i"))!=="/a/i"})),q=function(ft){for(var dt=ft.length,_=0,rt="",it=!1,mt;_<=dt;_++){if(mt=V(ft,_),mt==="\\"){rt+=mt+V(ft,++_);continue}!it&&mt==="."?rt+="[\\s\\S]":(mt==="["?it=!0:mt==="]"&&(it=!1),rt+=mt)}return rt},ut=function(ft){for(var dt=ft.length,_=0,rt="",it=[],mt=l(null),ot=!1,et=!1,k=0,tt="",nt;_<=dt;_++){if(nt=V(ft,_),nt==="\\")nt+=V(ft,++_);else if(nt==="]")ot=!1;else if(!ot)switch(!0){case nt==="[":ot=!0;break;case nt==="(":w($,G(ft,_+1))&&(_+=2,et=!0),rt+=nt,k++;continue;case(nt===">"&&et):if(tt===""||E(mt,tt))throw new M("Invalid capture group name");mt[tt]=!0,it[it.length]=[tt,k],et=!1,tt="";continue}et?tt+=nt:rt+=nt}return[rt,it]};if(a("RegExp",W)){for(var ct=function(){function at(ft,dt){var _=f(P,this),rt=i(ft),it=dt===void 0,mt=[],ot=ft,et,k,tt,nt,pt,Et;if(!_&&rt&&it&&ft.constructor===ct)return ft;if((rt||f(P,ft))&&(ft=ft.source,it&&(dt=c(ot))),ft=ft===void 0?"":d(ft),dt=dt===void 0?"":d(dt),ot=ft,S&&"dotAll"in x&&(k=!!dt&&j(dt,"s")>-1,k&&(dt=U(dt,/s/g,""))),et=dt,H&&"sticky"in x&&(tt=!!dt&&j(dt,"y")>-1,tt&&K&&(dt=U(dt,/y/g,""))),T&&(nt=ut(ft),ft=nt[0],mt=nt[1]),pt=s(A(ft,dt),_?this:P,ct),(k||tt||mt.length)&&(Et=I(pt),k&&(Et.dotAll=!0,Et.raw=ct(q(ft),et)),tt&&(Et.sticky=!0),mt.length&&(Et.groups=mt)),ft!==ot)try{u(pt,"source",ot===""?"(?:)":ot)}catch(st){}return pt}return at}(),Q=p(A),X=0;Q.length>X;)v(ct,A,Q[X++]);P.constructor=ct,ct.prototype=P,h(r,"RegExp",ct,{constructor:!0})}O("RegExp")},79669:function(y,e,t){"use strict";var n=t(63964),r=t(14489);n({target:"RegExp",proto:!0,forced:/./.exec!==r},{exec:r})},23057:function(y,e,t){"use strict";var n=t(74685),r=t(58310),o=t(73936),a=t(70901),s=t(40033),u=n.RegExp,l=u.prototype,p=r&&s(function(){var f=!0;try{u(".","d")}catch(E){f=!1}var i={},d="",c=f?"dgimsy":"gimsy",g=function(I,O){Object.defineProperty(i,I,{get:function(){function b(){return d+=O,!0}return b}()})},v={dotAll:"s",global:"g",ignoreCase:"i",multiline:"m",sticky:"y"};f&&(v.hasIndices="d");for(var h in v)g(h,v[h]);var m=Object.getOwnPropertyDescriptor(l,"flags").get.call(i);return m!==c||d!==c});p&&o(l,"flags",{configurable:!0,get:a})},57983:function(y,e,t){"use strict";var n=t(70520).PROPER,r=t(55938),o=t(30365),a=t(12605),s=t(40033),u=t(73392),l="toString",p=RegExp.prototype,f=p[l],i=s(function(){return f.call({source:"a",flags:"b"})!=="/a/b"}),d=n&&f.name!==l;(i||d)&&r(p,l,function(){function c(){var g=o(this),v=a(g.source),h=a(u(g));return"/"+v+"/"+h}return c}(),{unsafe:!0})},1963:function(y,e,t){"use strict";var n=t(45150),r=t(41028);n("Set",function(o){return function(){function a(){return o(this,arguments.length?arguments[0]:void 0)}return a}()},r)},17953:function(y,e,t){"use strict";t(1963)},95309:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("anchor")},{anchor:function(){function a(s){return r(this,"a","name",s)}return a}()})},82256:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("big")},{big:function(){function a(){return r(this,"big","","")}return a}()})},49484:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("blink")},{blink:function(){function a(){return r(this,"blink","","")}return a}()})},38931:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("bold")},{bold:function(){function a(){return r(this,"b","","")}return a}()})},30442:function(y,e,t){"use strict";var n=t(63964),r=t(50233).codeAt;n({target:"String",proto:!0},{codePointAt:function(){function o(a){return r(this,a)}return o}()})},6403:function(y,e,t){"use strict";var n=t(63964),r=t(71138),o=t(27193).f,a=t(10188),s=t(12605),u=t(86213),l=t(16952),p=t(45490),f=t(4493),i=r("".slice),d=Math.min,c=p("endsWith"),g=!f&&!c&&!!function(){var v=o(String.prototype,"endsWith");return v&&!v.writable}();n({target:"String",proto:!0,forced:!g&&!c},{endsWith:function(){function v(h){var m=s(l(this));u(h);var E=arguments.length>1?arguments[1]:void 0,I=m.length,O=E===void 0?I:d(a(E),I),b=s(h);return i(m,O-b.length,O)===b}return v}()})},39308:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("fixed")},{fixed:function(){function a(){return r(this,"tt","","")}return a}()})},91550:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("fontcolor")},{fontcolor:function(){function a(s){return r(this,"font","color",s)}return a}()})},75008:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("fontsize")},{fontsize:function(){function a(s){return r(this,"font","size",s)}return a}()})},9867:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(13912),a=RangeError,s=String.fromCharCode,u=String.fromCodePoint,l=r([].join),p=!!u&&u.length!==1;n({target:"String",stat:!0,arity:1,forced:p},{fromCodePoint:function(){function f(i){for(var d=[],c=arguments.length,g=0,v;c>g;){if(v=+arguments[g++],o(v,1114111)!==v)throw new a(v+" is not a valid code point");d[g]=v<65536?s(v):s(((v-=65536)>>10)+55296,v%1024+56320)}return l(d,"")}return f}()})},43673:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(86213),a=t(16952),s=t(12605),u=t(45490),l=r("".indexOf);n({target:"String",proto:!0,forced:!u("includes")},{includes:function(){function p(f){return!!~l(s(a(this)),s(o(f)),arguments.length>1?arguments[1]:void 0)}return p}()})},56027:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("italics")},{italics:function(){function a(){return r(this,"i","","")}return a}()})},12354:function(y,e,t){"use strict";var n=t(50233).charAt,r=t(12605),o=t(5419),a=t(65574),s=t(5959),u="String Iterator",l=o.set,p=o.getterFor(u);a(String,"String",function(f){l(this,{type:u,string:r(f),index:0})},function(){function f(){var i=p(this),d=i.string,c=i.index,g;return c>=d.length?s(void 0,!0):(g=n(d,c),i.index+=g.length,s(g,!1))}return f}())},50340:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("link")},{link:function(){function a(s){return r(this,"a","href",s)}return a}()})},22515:function(y,e,t){"use strict";var n=t(91495),r=t(79942),o=t(30365),a=t(42871),s=t(10188),u=t(12605),l=t(16952),p=t(78060),f=t(35483),i=t(28340);r("match",function(d,c,g){return[function(){function v(h){var m=l(this),E=a(h)?void 0:p(h,d);return E?n(E,h,m):new RegExp(h)[d](u(m))}return v}(),function(v){var h=o(this),m=u(v),E=g(c,h,m);if(E.done)return E.value;if(!h.global)return i(h,m);var I=h.unicode;h.lastIndex=0;for(var O=[],b=0,S;(S=i(h,m))!==null;){var T=u(S[0]);O[b]=T,T===""&&(h.lastIndex=f(m,s(h.lastIndex),I)),b++}return b===0?null:O}]})},5143:function(y,e,t){"use strict";var n=t(63964),r=t(24051).end,o=t(34125);n({target:"String",proto:!0,forced:o},{padEnd:function(){function a(s){return r(this,s,arguments.length>1?arguments[1]:void 0)}return a}()})},93514:function(y,e,t){"use strict";var n=t(63964),r=t(24051).start,o=t(34125);n({target:"String",proto:!0,forced:o},{padStart:function(){function a(s){return r(this,s,arguments.length>1?arguments[1]:void 0)}return a}()})},5416:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(57591),a=t(46771),s=t(12605),u=t(24760),l=r([].push),p=r([].join);n({target:"String",stat:!0},{raw:function(){function f(i){var d=o(a(i).raw),c=u(d);if(!c)return"";for(var g=arguments.length,v=[],h=0;;){if(l(v,s(d[h++])),h===c)return p(v,"");h")!=="7"});a("replace",function(U,j,G){var $=w?"$":"$0";return[function(){function x(B,F){var H=c(this),K=p(B)?void 0:v(B,I);return K?r(K,B,H,F):r(j,d(H),B,F)}return x}(),function(x,B){var F=u(this),H=d(x);if(typeof B=="string"&&C(B,$)===-1&&C(B,"$<")===-1){var K=G(j,F,H,B);if(K.done)return K.value}var W=l(B);W||(B=d(B));var q=F.global,ut;q&&(ut=F.unicode,F.lastIndex=0);for(var ct=[],Q;Q=m(F,H),!(Q===null||(T(ct,Q),!q));){var X=d(Q[0]);X===""&&(F.lastIndex=g(H,i(F.lastIndex),ut))}for(var at="",ft=0,dt=0;dt=ft&&(at+=A(H,ft,rt)+mt,ft=rt+_.length)}return at+A(H,ft)}]},!V||!M||w)},63272:function(y,e,t){"use strict";var n=t(91495),r=t(79942),o=t(30365),a=t(42871),s=t(16952),u=t(5700),l=t(12605),p=t(78060),f=t(28340);r("search",function(i,d,c){return[function(){function g(v){var h=s(this),m=a(v)?void 0:p(v,i);return m?n(m,v,h):new RegExp(v)[i](l(h))}return g}(),function(g){var v=o(this),h=l(g),m=c(d,v,h);if(m.done)return m.value;var E=v.lastIndex;u(E,0)||(v.lastIndex=0);var I=f(v,h);return u(v.lastIndex,E)||(v.lastIndex=E),I===null?-1:I.index}]})},34325:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("small")},{small:function(){function a(){return r(this,"small","","")}return a}()})},39930:function(y,e,t){"use strict";var n=t(91495),r=t(67250),o=t(79942),a=t(30365),s=t(42871),u=t(16952),l=t(28987),p=t(35483),f=t(10188),i=t(12605),d=t(78060),c=t(28340),g=t(62115),v=t(40033),h=g.UNSUPPORTED_Y,m=4294967295,E=Math.min,I=r([].push),O=r("".slice),b=!v(function(){var T=/(?:)/,C=T.exec;T.exec=function(){return C.apply(this,arguments)};var A="ab".split(T);return A.length!==2||A[0]!=="a"||A[1]!=="b"}),S="abbc".split(/(b)*/)[1]==="c"||"test".split(/(?:)/,-1).length!==4||"ab".split(/(?:ab)*/).length!==2||".".split(/(.?)(.?)/).length!==4||".".split(/()()/).length>1||"".split(/.?/).length;o("split",function(T,C,A){var P="0".split(void 0,0).length?function(M,w){return M===void 0&&w===0?[]:n(C,this,M,w)}:C;return[function(){function M(w,V){var U=u(this),j=s(w)?void 0:d(w,T);return j?n(j,w,U,V):n(P,i(U),w,V)}return M}(),function(M,w){var V=a(this),U=i(M);if(!S){var j=A(P,V,U,w,P!==C);if(j.done)return j.value}var G=l(V,RegExp),$=V.unicode,x=(V.ignoreCase?"i":"")+(V.multiline?"m":"")+(V.unicode?"u":"")+(h?"g":"y"),B=new G(h?"^(?:"+V.source+")":V,x),F=w===void 0?m:w>>>0;if(F===0)return[];if(U.length===0)return c(B,U)===null?[U]:[];for(var H=0,K=0,W=[];K1?arguments[1]:void 0,m.length)),I=s(h);return i(m,E,E+I.length)===I}return v}()})},74498:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("strike")},{strike:function(){function a(){return r(this,"strike","","")}return a}()})},15812:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("sub")},{sub:function(){function a(){return r(this,"sub","","")}return a}()})},57726:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("sup")},{sup:function(){function a(){return r(this,"sup","","")}return a}()})},70604:function(y,e,t){"use strict";t(99159);var n=t(63964),r=t(43476);n({target:"String",proto:!0,name:"trimEnd",forced:"".trimEnd!==r},{trimEnd:r})},85404:function(y,e,t){"use strict";var n=t(63964),r=t(43885);n({target:"String",proto:!0,name:"trimStart",forced:"".trimLeft!==r},{trimLeft:r})},99159:function(y,e,t){"use strict";var n=t(63964),r=t(43476);n({target:"String",proto:!0,name:"trimEnd",forced:"".trimRight!==r},{trimRight:r})},34965:function(y,e,t){"use strict";t(85404);var n=t(63964),r=t(43885);n({target:"String",proto:!0,name:"trimStart",forced:"".trimStart!==r},{trimStart:r})},8448:function(y,e,t){"use strict";var n=t(63964),r=t(92648).trim,o=t(90012);n({target:"String",proto:!0,forced:o("trim")},{trim:function(){function a(){return r(this)}return a}()})},79250:function(y,e,t){"use strict";var n=t(85889);n("asyncIterator")},49899:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(91495),a=t(67250),s=t(4493),u=t(58310),l=t(52357),p=t(40033),f=t(45299),i=t(21287),d=t(30365),c=t(57591),g=t(767),v=t(12605),h=t(87458),m=t(80674),E=t(18450),I=t(37310),O=t(81644),b=t(89235),S=t(27193),T=t(74595),C=t(24239),A=t(12867),P=t(55938),M=t(73936),w=t(16639),V=t(19417),U=t(79195),j=t(16738),G=t(24697),$=t(55557),x=t(85889),B=t(52360),F=t(84925),H=t(5419),K=t(22603).forEach,W=V("hidden"),q="Symbol",ut="prototype",ct=H.set,Q=H.getterFor(q),X=Object[ut],at=r.Symbol,ft=at&&at[ut],dt=r.RangeError,_=r.TypeError,rt=r.QObject,it=S.f,mt=T.f,ot=O.f,et=A.f,k=a([].push),tt=w("symbols"),nt=w("op-symbols"),pt=w("wks"),Et=!rt||!rt[ut]||!rt[ut].findChild,st=function(St,At,Tt){var Nt=it(X,At);Nt&&delete X[At],mt(St,At,Tt),Nt&&St!==X&&mt(X,At,Nt)},yt=u&&p(function(){return m(mt({},"a",{get:function(){function vt(){return mt(this,"a",{value:7}).a}return vt}()})).a!==7})?st:mt,Pt=function(St,At){var Tt=tt[St]=m(ft);return ct(Tt,{type:q,tag:St,description:At}),u||(Tt.description=At),Tt},Ct=function(){function vt(St,At,Tt){St===X&&Ct(nt,At,Tt),d(St);var Nt=g(At);return d(Tt),f(tt,Nt)?(Tt.enumerable?(f(St,W)&&St[W][Nt]&&(St[W][Nt]=!1),Tt=m(Tt,{enumerable:h(0,!1)})):(f(St,W)||mt(St,W,h(1,m(null))),St[W][Nt]=!0),yt(St,Nt,Tt)):mt(St,Nt,Tt)}return vt}(),lt=function(){function vt(St,At){d(St);var Tt=c(At),Nt=E(Tt).concat(Ot(Tt));return K(Nt,function(Ft){(!u||o(It,Tt,Ft))&&Ct(St,Ft,Tt[Ft])}),St}return vt}(),gt=function(){function vt(St,At){return At===void 0?m(St):lt(m(St),At)}return vt}(),It=function(){function vt(St){var At=g(St),Tt=o(et,this,At);return this===X&&f(tt,At)&&!f(nt,At)?!1:Tt||!f(this,At)||!f(tt,At)||f(this,W)&&this[W][At]?Tt:!0}return vt}(),Lt=function(){function vt(St,At){var Tt=c(St),Nt=g(At);if(!(Tt===X&&f(tt,Nt)&&!f(nt,Nt))){var Ft=it(Tt,Nt);return Ft&&f(tt,Nt)&&!(f(Tt,W)&&Tt[W][Nt])&&(Ft.enumerable=!0),Ft}}return vt}(),Vt=function(){function vt(St){var At=ot(c(St)),Tt=[];return K(At,function(Nt){!f(tt,Nt)&&!f(U,Nt)&&k(Tt,Nt)}),Tt}return vt}(),Ot=function(St){var At=St===X,Tt=ot(At?nt:c(St)),Nt=[];return K(Tt,function(Ft){f(tt,Ft)&&(!At||f(X,Ft))&&k(Nt,tt[Ft])}),Nt};l||(at=function(){function vt(){if(i(ft,this))throw new _("Symbol is not a constructor");var St=!arguments.length||arguments[0]===void 0?void 0:v(arguments[0]),At=j(St),Tt=function(){function Nt(Ft){var jt=this===void 0?r:this;jt===X&&o(Nt,nt,Ft),f(jt,W)&&f(jt[W],At)&&(jt[W][At]=!1);var Ht=h(1,Ft);try{yt(jt,At,Ht)}catch(Kt){if(!(Kt instanceof dt))throw Kt;st(jt,At,Ht)}}return Nt}();return u&&Et&&yt(X,At,{configurable:!0,set:Tt}),Pt(At,St)}return vt}(),ft=at[ut],P(ft,"toString",function(){function vt(){return Q(this).tag}return vt}()),P(at,"withoutSetter",function(vt){return Pt(j(vt),vt)}),A.f=It,T.f=Ct,C.f=lt,S.f=Lt,I.f=O.f=Vt,b.f=Ot,$.f=function(vt){return Pt(G(vt),vt)},u&&(M(ft,"description",{configurable:!0,get:function(){function vt(){return Q(this).description}return vt}()}),s||P(X,"propertyIsEnumerable",It,{unsafe:!0}))),n({global:!0,constructor:!0,wrap:!0,forced:!l,sham:!l},{Symbol:at}),K(E(pt),function(vt){x(vt)}),n({target:q,stat:!0,forced:!l},{useSetter:function(){function vt(){Et=!0}return vt}(),useSimple:function(){function vt(){Et=!1}return vt}()}),n({target:"Object",stat:!0,forced:!l,sham:!u},{create:gt,defineProperty:Ct,defineProperties:lt,getOwnPropertyDescriptor:Lt}),n({target:"Object",stat:!0,forced:!l},{getOwnPropertyNames:Vt}),B(),F(at,q),U[W]=!0},10933:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(74685),a=t(67250),s=t(45299),u=t(55747),l=t(21287),p=t(12605),f=t(73936),i=t(5774),d=o.Symbol,c=d&&d.prototype;if(r&&u(d)&&(!("description"in c)||d().description!==void 0)){var g={},v=function(){function S(){var T=arguments.length<1||arguments[0]===void 0?void 0:p(arguments[0]),C=l(c,this)?new d(T):T===void 0?d():d(T);return T===""&&(g[C]=!0),C}return S}();i(v,d),v.prototype=c,c.constructor=v;var h=String(d("description detection"))==="Symbol(description detection)",m=a(c.valueOf),E=a(c.toString),I=/^Symbol\((.*)\)[^)]+$/,O=a("".replace),b=a("".slice);f(c,"description",{configurable:!0,get:function(){function S(){var T=m(this);if(s(g,T))return"";var C=E(T),A=h?b(C,7,-1):O(C,I,"$1");return A===""?void 0:A}return S}()}),n({global:!0,constructor:!0,forced:!0},{Symbol:v})}},30828:function(y,e,t){"use strict";var n=t(63964),r=t(4009),o=t(45299),a=t(12605),s=t(16639),u=t(66570),l=s("string-to-symbol-registry"),p=s("symbol-to-string-registry");n({target:"Symbol",stat:!0,forced:!u},{for:function(){function f(i){var d=a(i);if(o(l,d))return l[d];var c=r("Symbol")(d);return l[d]=c,p[c]=d,c}return f}()})},53795:function(y,e,t){"use strict";var n=t(85889);n("hasInstance")},87806:function(y,e,t){"use strict";var n=t(85889);n("isConcatSpreadable")},64677:function(y,e,t){"use strict";var n=t(85889);n("iterator")},33313:function(y,e,t){"use strict";t(49899),t(30828),t(6862),t(53008),t(28603)},6862:function(y,e,t){"use strict";var n=t(63964),r=t(45299),o=t(71399),a=t(89393),s=t(16639),u=t(66570),l=s("symbol-to-string-registry");n({target:"Symbol",stat:!0,forced:!u},{keyFor:function(){function p(f){if(!o(f))throw new TypeError(a(f)+" is not a symbol");if(r(l,f))return l[f]}return p}()})},48058:function(y,e,t){"use strict";var n=t(85889);n("match")},51583:function(y,e,t){"use strict";var n=t(85889);n("replace")},82403:function(y,e,t){"use strict";var n=t(85889);n("search")},34265:function(y,e,t){"use strict";var n=t(85889);n("species")},3295:function(y,e,t){"use strict";var n=t(85889);n("split")},1078:function(y,e,t){"use strict";var n=t(85889),r=t(52360);n("toPrimitive"),r()},63207:function(y,e,t){"use strict";var n=t(4009),r=t(85889),o=t(84925);r("toStringTag"),o(n("Symbol"),"Symbol")},80520:function(y,e,t){"use strict";var n=t(85889);n("unscopables")},99872:function(y,e,t){"use strict";var n=t(67250),r=t(4246),o=t(71447),a=n(o),s=r.aTypedArray,u=r.exportTypedArrayMethod;u("copyWithin",function(){function l(p,f){return a(s(this),p,f,arguments.length>2?arguments[2]:void 0)}return l}())},73364:function(y,e,t){"use strict";var n=t(4246),r=t(22603).every,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("every",function(){function s(u){return r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},58166:function(y,e,t){"use strict";var n=t(4246),r=t(88471),o=t(61484),a=t(2281),s=t(91495),u=t(67250),l=t(40033),p=n.aTypedArray,f=n.exportTypedArrayMethod,i=u("".slice),d=l(function(){var c=0;return new Int8Array(2).fill({valueOf:function(){function g(){return c++}return g}()}),c!==1});f("fill",function(){function c(g){var v=arguments.length;p(this);var h=i(a(this),0,3)==="Big"?o(g):+g;return s(r,this,h,v>1?arguments[1]:void 0,v>2?arguments[2]:void 0)}return c}(),d)},23793:function(y,e,t){"use strict";var n=t(4246),r=t(22603).filter,o=t(45399),a=n.aTypedArray,s=n.exportTypedArrayMethod;s("filter",function(){function u(l){var p=r(a(this),l,arguments.length>1?arguments[1]:void 0);return o(this,p)}return u}())},13917:function(y,e,t){"use strict";var n=t(4246),r=t(22603).findIndex,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("findIndex",function(){function s(u){return r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},43820:function(y,e,t){"use strict";var n=t(4246),r=t(22603).find,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("find",function(){function s(u){return r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},80756:function(y,e,t){"use strict";var n=t(80185);n("Float32",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},70567:function(y,e,t){"use strict";var n=t(80185);n("Float64",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},19852:function(y,e,t){"use strict";var n=t(4246),r=t(22603).forEach,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("forEach",function(){function s(u){r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},40379:function(y,e,t){"use strict";var n=t(86563),r=t(4246).exportTypedArrayStaticMethod,o=t(3805);r("from",o,n)},92770:function(y,e,t){"use strict";var n=t(4246),r=t(14211).includes,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("includes",function(){function s(u){return r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},81069:function(y,e,t){"use strict";var n=t(4246),r=t(14211).indexOf,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("indexOf",function(){function s(u){return r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},60037:function(y,e,t){"use strict";var n=t(80185);n("Int16",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},44195:function(y,e,t){"use strict";var n=t(80185);n("Int32",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},66756:function(y,e,t){"use strict";var n=t(80185);n("Int8",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},63689:function(y,e,t){"use strict";var n=t(74685),r=t(40033),o=t(67250),a=t(4246),s=t(34570),u=t(24697),l=u("iterator"),p=n.Uint8Array,f=o(s.values),i=o(s.keys),d=o(s.entries),c=a.aTypedArray,g=a.exportTypedArrayMethod,v=p&&p.prototype,h=!r(function(){v[l].call([1])}),m=!!v&&v.values&&v[l]===v.values&&v.values.name==="values",E=function(){function I(){return f(c(this))}return I}();g("entries",function(){function I(){return d(c(this))}return I}(),h),g("keys",function(){function I(){return i(c(this))}return I}(),h),g("values",E,h||!m,{name:"values"}),g(l,E,h||!m,{name:"values"})},5659:function(y,e,t){"use strict";var n=t(4246),r=t(67250),o=n.aTypedArray,a=n.exportTypedArrayMethod,s=r([].join);a("join",function(){function u(l){return s(o(this),l)}return u}())},25014:function(y,e,t){"use strict";var n=t(4246),r=t(61267),o=t(1325),a=n.aTypedArray,s=n.exportTypedArrayMethod;s("lastIndexOf",function(){function u(l){var p=arguments.length;return r(o,a(this),p>1?[l,arguments[1]]:[l])}return u}())},32189:function(y,e,t){"use strict";var n=t(4246),r=t(22603).map,o=t(31082),a=n.aTypedArray,s=n.exportTypedArrayMethod;s("map",function(){function u(l){return r(a(this),l,arguments.length>1?arguments[1]:void 0,function(p,f){return new(o(p))(f)})}return u}())},23030:function(y,e,t){"use strict";var n=t(4246),r=t(86563),o=n.aTypedArrayConstructor,a=n.exportTypedArrayStaticMethod;a("of",function(){function s(){for(var u=0,l=arguments.length,p=new(o(this))(l);l>u;)p[u]=arguments[u++];return p}return s}(),r)},49110:function(y,e,t){"use strict";var n=t(4246),r=t(56844).right,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("reduceRight",function(){function s(u){var l=arguments.length;return r(o(this),u,l,l>1?arguments[1]:void 0)}return s}())},24309:function(y,e,t){"use strict";var n=t(4246),r=t(56844).left,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("reduce",function(){function s(u){var l=arguments.length;return r(o(this),u,l,l>1?arguments[1]:void 0)}return s}())},56445:function(y,e,t){"use strict";var n=t(4246),r=n.aTypedArray,o=n.exportTypedArrayMethod,a=Math.floor;o("reverse",function(){function s(){for(var u=this,l=r(u).length,p=a(l/2),f=0,i;f1?arguments[1]:void 0,1),O=u(E);if(v)return r(d,this,O,I);var b=this.length,S=a(O),T=0;if(S+I>b)throw new p("Wrong length");for(;Tg;)h[g]=d[g++];return h}return p}(),l)},88739:function(y,e,t){"use strict";var n=t(4246),r=t(22603).some,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("some",function(){function s(u){return r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},60415:function(y,e,t){"use strict";var n=t(74685),r=t(71138),o=t(40033),a=t(10320),s=t(90274),u=t(4246),l=t(652),p=t(19228),f=t(5026),i=t(9342),d=u.aTypedArray,c=u.exportTypedArrayMethod,g=n.Uint16Array,v=g&&r(g.prototype.sort),h=!!v&&!(o(function(){v(new g(2),null)})&&o(function(){v(new g(2),{})})),m=!!v&&!o(function(){if(f)return f<74;if(l)return l<67;if(p)return!0;if(i)return i<602;var I=new g(516),O=Array(516),b,S;for(b=0;b<516;b++)S=b%4,I[b]=515-b,O[b]=b-2*S+3;for(v(I,function(T,C){return(T/4|0)-(C/4|0)}),b=0;b<516;b++)if(I[b]!==O[b])return!0}),E=function(O){return function(b,S){return O!==void 0?+O(b,S)||0:S!==S?-1:b!==b?1:b===0&&S===0?1/b>0&&1/S<0?1:-1:b>S}};c("sort",function(){function I(O){return O!==void 0&&a(O),m?v(this,O):s(d(this),E(O))}return I}(),!m||h)},72532:function(y,e,t){"use strict";var n=t(4246),r=t(10188),o=t(13912),a=t(31082),s=n.aTypedArray,u=n.exportTypedArrayMethod;u("subarray",function(){function l(p,f){var i=s(this),d=i.length,c=o(p,d),g=a(i);return new g(i.buffer,i.byteOffset+c*i.BYTES_PER_ELEMENT,r((f===void 0?d:o(f,d))-c))}return l}())},62207:function(y,e,t){"use strict";var n=t(74685),r=t(61267),o=t(4246),a=t(40033),s=t(54602),u=n.Int8Array,l=o.aTypedArray,p=o.exportTypedArrayMethod,f=[].toLocaleString,i=!!u&&a(function(){f.call(new u(1))}),d=a(function(){return[1,2].toLocaleString()!==new u([1,2]).toLocaleString()})||!a(function(){u.prototype.toLocaleString.call([1,2])});p("toLocaleString",function(){function c(){return r(f,i?s(l(this)):l(this),s(arguments))}return c}(),d)},906:function(y,e,t){"use strict";var n=t(4246).exportTypedArrayMethod,r=t(40033),o=t(74685),a=t(67250),s=o.Uint8Array,u=s&&s.prototype||{},l=[].toString,p=a([].join);r(function(){l.call({})})&&(l=function(){function i(){return p(this)}return i}());var f=u.toString!==l;n("toString",l,f)},78824:function(y,e,t){"use strict";var n=t(80185);n("Uint16",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},72846:function(y,e,t){"use strict";var n=t(80185);n("Uint32",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},24575:function(y,e,t){"use strict";var n=t(80185);n("Uint8",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},71968:function(y,e,t){"use strict";var n=t(80185);n("Uint8",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()},!0)},80040:function(y,e,t){"use strict";var n=t(50730),r=t(74685),o=t(67250),a=t(30145),s=t(81969),u=t(45150),l=t(39895),p=t(77568),f=t(5419).enforce,i=t(40033),d=t(21820),c=Object,g=Array.isArray,v=c.isExtensible,h=c.isFrozen,m=c.isSealed,E=c.freeze,I=c.seal,O=!r.ActiveXObject&&"ActiveXObject"in r,b,S=function(j){return function(){function G(){return j(this,arguments.length?arguments[0]:void 0)}return G}()},T=u("WeakMap",S,l),C=T.prototype,A=o(C.set),P=function(){return n&&i(function(){var j=E([]);return A(new T,j,1),!h(j)})};if(d)if(O){b=l.getConstructor(S,"WeakMap",!0),s.enable();var M=o(C.delete),w=o(C.has),V=o(C.get);a(C,{delete:function(){function U(j){if(p(j)&&!v(j)){var G=f(this);return G.frozen||(G.frozen=new b),M(this,j)||G.frozen.delete(j)}return M(this,j)}return U}(),has:function(){function U(j){if(p(j)&&!v(j)){var G=f(this);return G.frozen||(G.frozen=new b),w(this,j)||G.frozen.has(j)}return w(this,j)}return U}(),get:function(){function U(j){if(p(j)&&!v(j)){var G=f(this);return G.frozen||(G.frozen=new b),w(this,j)?V(this,j):G.frozen.get(j)}return V(this,j)}return U}(),set:function(){function U(j,G){if(p(j)&&!v(j)){var $=f(this);$.frozen||($.frozen=new b),w(this,j)?A(this,j,G):$.frozen.set(j,G)}else A(this,j,G);return this}return U}()})}else P()&&a(C,{set:function(){function U(j,G){var $;return g(j)&&(h(j)?$=E:m(j)&&($=I)),A(this,j,G),$&&$(j),this}return U}()})},90846:function(y,e,t){"use strict";t(80040)},67042:function(y,e,t){"use strict";var n=t(45150),r=t(39895);n("WeakSet",function(o){return function(){function a(){return o(this,arguments.length?arguments[0]:void 0)}return a}()},r)},40348:function(y,e,t){"use strict";t(67042)},5606:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(60375).clear;n({global:!0,bind:!0,enumerable:!0,forced:r.clearImmediate!==o},{clearImmediate:o})},83006:function(y,e,t){"use strict";t(5606),t(27807)},25764:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(37713),a=t(10320),s=t(24986),u=t(40033),l=t(58310),p=u(function(){return l&&Object.getOwnPropertyDescriptor(r,"queueMicrotask").value.length!==1});n({global:!0,enumerable:!0,dontCallGetSet:!0,forced:p},{queueMicrotask:function(){function f(i){s(arguments.length,1),o(a(i))}return f}()})},27807:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(60375).set,a=t(78362),s=r.setImmediate?a(o,!1):o;n({global:!0,bind:!0,enumerable:!0,forced:r.setImmediate!==s},{setImmediate:s})},45569:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(78362),a=o(r.setInterval,!0);n({global:!0,bind:!0,forced:r.setInterval!==a},{setInterval:a})},5213:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(78362),a=o(r.setTimeout,!0);n({global:!0,bind:!0,forced:r.setTimeout!==a},{setTimeout:a})},69401:function(y,e,t){"use strict";t(45569),t(5213)},7435:function(y){"use strict";/** + */var o=e.BoxWithSampleText=function(){function a(s){return(0,n.normalizeProps)((0,n.createComponentVNode)(2,r.Box,Object.assign({},s,{children:[(0,n.createComponentVNode)(2,r.Box,{italic:!0,children:"Jackdaws love my big sphinx of quartz."}),(0,n.createComponentVNode)(2,r.Box,{mt:1,bold:!0,children:"The wide electrification of the southern provinces will give a powerful impetus to the growth of agriculture."})]})))}return a}()},17887:function(){},17003:function(){},27949:function(){},70712:function(){},37445:function(){},4085:function(y,e,t){var n={"./Blink.stories.js":51364,"./BlockQuote.stories.js":32453,"./Box.stories.js":83531,"./Button.stories.js":74198,"./ByondUi.stories.js":51956,"./Collapsible.stories.js":17466,"./Flex.stories.js":89241,"./ImageButton.stories.js":48779,"./Input.stories.js":21394,"./Popper.stories.js":43932,"./ProgressBar.stories.js":33270,"./Stack.stories.js":77766,"./Storage.stories.js":30187,"./Tabs.stories.js":46554,"./Themes.stories.js":53276,"./Tooltip.stories.js":28717};function r(a){var s=o(a);return t(s)}function o(a){if(!t.o(n,a)){var s=new Error("Cannot find module '"+a+"'");throw s.code="MODULE_NOT_FOUND",s}return n[a]}r.keys=function(){return Object.keys(n)},r.resolve=o,y.exports=r,r.id=4085},10320:function(y,e,t){"use strict";var n=t(55747),r=t(89393),o=TypeError;y.exports=function(a){if(n(a))return a;throw new o(r(a)+" is not a function")}},32606:function(y,e,t){"use strict";var n=t(1031),r=t(89393),o=TypeError;y.exports=function(a){if(n(a))return a;throw new o(r(a)+" is not a constructor")}},35908:function(y,e,t){"use strict";var n=t(45015),r=String,o=TypeError;y.exports=function(a){if(n(a))return a;throw new o("Can't set "+r(a)+" as a prototype")}},80575:function(y,e,t){"use strict";var n=t(24697),r=t(80674),o=t(74595).f,a=n("unscopables"),s=Array.prototype;s[a]===void 0&&o(s,a,{configurable:!0,value:r(null)}),y.exports=function(u){s[a][u]=!0}},35483:function(y,e,t){"use strict";var n=t(50233).charAt;y.exports=function(r,o,a){return o+(a?n(r,o).length:1)}},60077:function(y,e,t){"use strict";var n=t(21287),r=TypeError;y.exports=function(o,a){if(n(a,o))return o;throw new r("Incorrect invocation")}},30365:function(y,e,t){"use strict";var n=t(77568),r=String,o=TypeError;y.exports=function(a){if(n(a))return a;throw new o(r(a)+" is not an object")}},70377:function(y){"use strict";y.exports=typeof ArrayBuffer!="undefined"&&typeof DataView!="undefined"},3782:function(y,e,t){"use strict";var n=t(40033);y.exports=n(function(){if(typeof ArrayBuffer=="function"){var r=new ArrayBuffer(8);Object.isExtensible(r)&&Object.defineProperty(r,"a",{value:8})}})},4246:function(y,e,t){"use strict";var n=t(70377),r=t(58310),o=t(74685),a=t(55747),s=t(77568),u=t(45299),l=t(2281),p=t(89393),f=t(37909),i=t(55938),d=t(73936),c=t(21287),g=t(36917),v=t(76649),h=t(24697),m=t(16738),E=t(5419),I=E.enforce,O=E.get,C=o.Int8Array,S=C&&C.prototype,T=o.Uint8ClampedArray,b=T&&T.prototype,A=C&&g(C),P=S&&g(S),M=Object.prototype,w=o.TypeError,V=h("toStringTag"),U=m("TYPED_ARRAY_TAG"),j="TypedArrayConstructor",G=n&&!!v&&l(o.opera)!=="Opera",$=!1,x,B,F,H={Int8Array:1,Uint8Array:1,Uint8ClampedArray:1,Int16Array:2,Uint16Array:2,Int32Array:4,Uint32Array:4,Float32Array:4,Float64Array:8},K={BigInt64Array:8,BigUint64Array:8},W=function(){function ft(dt){if(!s(dt))return!1;var _=l(dt);return _==="DataView"||u(H,_)||u(K,_)}return ft}(),q=function ft(dt){var _=g(dt);if(s(_)){var rt=O(_);return rt&&u(rt,j)?rt[j]:ft(_)}},ut=function(dt){if(!s(dt))return!1;var _=l(dt);return u(H,_)||u(K,_)},ct=function(dt){if(ut(dt))return dt;throw new w("Target is not a typed array")},Q=function(dt){if(a(dt)&&(!v||c(A,dt)))return dt;throw new w(p(dt)+" is not a typed array constructor")},X=function(dt,_,rt,it){if(r){if(rt)for(var mt in H){var ot=o[mt];if(ot&&u(ot.prototype,dt))try{delete ot.prototype[dt]}catch(et){try{ot.prototype[dt]=_}catch(k){}}}(!P[dt]||rt)&&i(P,dt,rt?_:G&&S[dt]||_,it)}},at=function(dt,_,rt){var it,mt;if(r){if(v){if(rt){for(it in H)if(mt=o[it],mt&&u(mt,dt))try{delete mt[dt]}catch(ot){}}if(!A[dt]||rt)try{return i(A,dt,rt?_:G&&A[dt]||_)}catch(ot){}else return}for(it in H)mt=o[it],mt&&(!mt[dt]||rt)&&i(mt,dt,_)}};for(x in H)B=o[x],F=B&&B.prototype,F?I(F)[j]=B:G=!1;for(x in K)B=o[x],F=B&&B.prototype,F&&(I(F)[j]=B);if((!G||!a(A)||A===Function.prototype)&&(A=function(){function ft(){throw new w("Incorrect invocation")}return ft}(),G))for(x in H)o[x]&&v(o[x],A);if((!G||!P||P===M)&&(P=A.prototype,G))for(x in H)o[x]&&v(o[x].prototype,P);if(G&&g(b)!==P&&v(b,P),r&&!u(P,V)){$=!0,d(P,V,{configurable:!0,get:function(){function ft(){return s(this)?this[U]:void 0}return ft}()});for(x in H)o[x]&&f(o[x],U,x)}y.exports={NATIVE_ARRAY_BUFFER_VIEWS:G,TYPED_ARRAY_TAG:$&&U,aTypedArray:ct,aTypedArrayConstructor:Q,exportTypedArrayMethod:X,exportTypedArrayStaticMethod:at,getTypedArrayConstructor:q,isView:W,isTypedArray:ut,TypedArray:A,TypedArrayPrototype:P}},37336:function(y,e,t){"use strict";var n=t(74685),r=t(67250),o=t(58310),a=t(70377),s=t(70520),u=t(37909),l=t(73936),p=t(30145),f=t(40033),i=t(60077),d=t(61365),c=t(10188),g=t(43806),v=t(95867),h=t(91784),m=t(36917),E=t(76649),I=t(88471),O=t(54602),C=t(5781),S=t(5774),T=t(84925),b=t(5419),A=s.PROPER,P=s.CONFIGURABLE,M="ArrayBuffer",w="DataView",V="prototype",U="Wrong length",j="Wrong index",G=b.getterFor(M),$=b.getterFor(w),x=b.set,B=n[M],F=B,H=F&&F[V],K=n[w],W=K&&K[V],q=Object.prototype,ut=n.Array,ct=n.RangeError,Q=r(I),X=r([].reverse),at=h.pack,ft=h.unpack,dt=function(yt){return[yt&255]},_=function(yt){return[yt&255,yt>>8&255]},rt=function(yt){return[yt&255,yt>>8&255,yt>>16&255,yt>>24&255]},it=function(yt){return yt[3]<<24|yt[2]<<16|yt[1]<<8|yt[0]},mt=function(yt){return at(v(yt),23,4)},ot=function(yt){return at(yt,52,8)},et=function(yt,Pt,Ct){l(yt[V],Pt,{configurable:!0,get:function(){function lt(){return Ct(this)[Pt]}return lt}()})},k=function(yt,Pt,Ct,lt){var gt=$(yt),It=g(Ct),Lt=!!lt;if(It+Pt>gt.byteLength)throw new ct(j);var Vt=gt.bytes,Ot=It+gt.byteOffset,vt=O(Vt,Ot,Ot+Pt);return Lt?vt:X(vt)},tt=function(yt,Pt,Ct,lt,gt,It){var Lt=$(yt),Vt=g(Ct),Ot=lt(+gt),vt=!!It;if(Vt+Pt>Lt.byteLength)throw new ct(j);for(var St=Lt.bytes,At=Vt+Lt.byteOffset,Tt=0;Ttgt)throw new ct("Wrong offset");if(Ct=Ct===void 0?gt-It:c(Ct),It+Ct>gt)throw new ct(U);x(this,{type:w,buffer:yt,byteLength:Ct,byteOffset:It,bytes:lt.bytes}),o||(this.buffer=yt,this.byteLength=Ct,this.byteOffset=It)}return st}(),W=K[V],o&&(et(F,"byteLength",G),et(K,"buffer",$),et(K,"byteLength",$),et(K,"byteOffset",$)),p(W,{getInt8:function(){function st(yt){return k(this,1,yt)[0]<<24>>24}return st}(),getUint8:function(){function st(yt){return k(this,1,yt)[0]}return st}(),getInt16:function(){function st(yt){var Pt=k(this,2,yt,arguments.length>1?arguments[1]:!1);return(Pt[1]<<8|Pt[0])<<16>>16}return st}(),getUint16:function(){function st(yt){var Pt=k(this,2,yt,arguments.length>1?arguments[1]:!1);return Pt[1]<<8|Pt[0]}return st}(),getInt32:function(){function st(yt){return it(k(this,4,yt,arguments.length>1?arguments[1]:!1))}return st}(),getUint32:function(){function st(yt){return it(k(this,4,yt,arguments.length>1?arguments[1]:!1))>>>0}return st}(),getFloat32:function(){function st(yt){return ft(k(this,4,yt,arguments.length>1?arguments[1]:!1),23)}return st}(),getFloat64:function(){function st(yt){return ft(k(this,8,yt,arguments.length>1?arguments[1]:!1),52)}return st}(),setInt8:function(){function st(yt,Pt){tt(this,1,yt,dt,Pt)}return st}(),setUint8:function(){function st(yt,Pt){tt(this,1,yt,dt,Pt)}return st}(),setInt16:function(){function st(yt,Pt){tt(this,2,yt,_,Pt,arguments.length>2?arguments[2]:!1)}return st}(),setUint16:function(){function st(yt,Pt){tt(this,2,yt,_,Pt,arguments.length>2?arguments[2]:!1)}return st}(),setInt32:function(){function st(yt,Pt){tt(this,4,yt,rt,Pt,arguments.length>2?arguments[2]:!1)}return st}(),setUint32:function(){function st(yt,Pt){tt(this,4,yt,rt,Pt,arguments.length>2?arguments[2]:!1)}return st}(),setFloat32:function(){function st(yt,Pt){tt(this,4,yt,mt,Pt,arguments.length>2?arguments[2]:!1)}return st}(),setFloat64:function(){function st(yt,Pt){tt(this,8,yt,ot,Pt,arguments.length>2?arguments[2]:!1)}return st}()});else{var nt=A&&B.name!==M;!f(function(){B(1)})||!f(function(){new B(-1)})||f(function(){return new B,new B(1.5),new B(NaN),B.length!==1||nt&&!P})?(F=function(){function st(yt){return i(this,H),C(new B(g(yt)),this,F)}return st}(),F[V]=H,H.constructor=F,S(F,B)):nt&&P&&u(B,"name",M),E&&m(W)!==q&&E(W,q);var pt=new K(new F(2)),Et=r(W.setInt8);pt.setInt8(0,2147483648),pt.setInt8(1,2147483649),(pt.getInt8(0)||!pt.getInt8(1))&&p(W,{setInt8:function(){function st(yt,Pt){Et(this,yt,Pt<<24>>24)}return st}(),setUint8:function(){function st(yt,Pt){Et(this,yt,Pt<<24>>24)}return st}()},{unsafe:!0})}T(F,M),T(K,w),y.exports={ArrayBuffer:F,DataView:K}},71447:function(y,e,t){"use strict";var n=t(46771),r=t(13912),o=t(24760),a=t(95108),s=Math.min;y.exports=[].copyWithin||function(){function u(l,p){var f=n(this),i=o(f),d=r(l,i),c=r(p,i),g=arguments.length>2?arguments[2]:void 0,v=s((g===void 0?i:r(g,i))-c,i-d),h=1;for(c0;)c in f?f[d]=f[c]:a(f,d),d+=h,c+=h;return f}return u}()},88471:function(y,e,t){"use strict";var n=t(46771),r=t(13912),o=t(24760);y.exports=function(){function a(s){for(var u=n(this),l=o(u),p=arguments.length,f=r(p>1?arguments[1]:void 0,l),i=p>2?arguments[2]:void 0,d=i===void 0?l:r(i,l);d>f;)u[f++]=s;return u}return a}()},35601:function(y,e,t){"use strict";var n=t(22603).forEach,r=t(55528),o=r("forEach");y.exports=o?[].forEach:function(){function a(s){return n(this,s,arguments.length>1?arguments[1]:void 0)}return a}()},78008:function(y,e,t){"use strict";var n=t(24760);y.exports=function(r,o,a){for(var s=0,u=arguments.length>2?a:n(o),l=new r(u);u>s;)l[s]=o[s++];return l}},73174:function(y,e,t){"use strict";var n=t(75754),r=t(91495),o=t(46771),a=t(40125),s=t(76571),u=t(1031),l=t(24760),p=t(60102),f=t(77455),i=t(59201),d=Array;y.exports=function(){function c(g){var v=o(g),h=u(this),m=arguments.length,E=m>1?arguments[1]:void 0,I=E!==void 0;I&&(E=n(E,m>2?arguments[2]:void 0));var O=i(v),C=0,S,T,b,A,P,M;if(O&&!(this===d&&s(O)))for(T=h?new this:[],A=f(v,O),P=A.next;!(b=r(P,A)).done;C++)M=I?a(A,E,[b.value,C],!0):b.value,p(T,C,M);else for(S=l(v),T=h?new this(S):d(S);S>C;C++)M=I?E(v[C],C):v[C],p(T,C,M);return T.length=C,T}return c}()},14211:function(y,e,t){"use strict";var n=t(57591),r=t(13912),o=t(24760),a=function(u){return function(l,p,f){var i=n(l),d=o(i);if(d===0)return!u&&-1;var c=r(f,d),g;if(u&&p!==p){for(;d>c;)if(g=i[c++],g!==g)return!0}else for(;d>c;c++)if((u||c in i)&&i[c]===p)return u||c||0;return!u&&-1}};y.exports={includes:a(!0),indexOf:a(!1)}},22603:function(y,e,t){"use strict";var n=t(75754),r=t(67250),o=t(37457),a=t(46771),s=t(24760),u=t(57823),l=r([].push),p=function(i){var d=i===1,c=i===2,g=i===3,v=i===4,h=i===6,m=i===7,E=i===5||h;return function(I,O,C,S){for(var T=a(I),b=o(T),A=s(b),P=n(O,C),M=0,w=S||u,V=d?w(I,A):c||m?w(I,0):void 0,U,j;A>M;M++)if((E||M in b)&&(U=b[M],j=P(U,M,T),i))if(d)V[M]=j;else if(j)switch(i){case 3:return!0;case 5:return U;case 6:return M;case 2:l(V,U)}else switch(i){case 4:return!1;case 7:l(V,U)}return h?-1:g||v?v:V}};y.exports={forEach:p(0),map:p(1),filter:p(2),some:p(3),every:p(4),find:p(5),findIndex:p(6),filterReject:p(7)}},1325:function(y,e,t){"use strict";var n=t(61267),r=t(57591),o=t(61365),a=t(24760),s=t(55528),u=Math.min,l=[].lastIndexOf,p=!!l&&1/[1].lastIndexOf(1,-0)<0,f=s("lastIndexOf"),i=p||!f;y.exports=i?function(){function d(c){if(p)return n(l,this,arguments)||0;var g=r(this),v=a(g);if(v===0)return-1;var h=v-1;for(arguments.length>1&&(h=u(h,o(arguments[1]))),h<0&&(h=v+h);h>=0;h--)if(h in g&&g[h]===c)return h||0;return-1}return d}():l},44091:function(y,e,t){"use strict";var n=t(40033),r=t(24697),o=t(5026),a=r("species");y.exports=function(s){return o>=51||!n(function(){var u=[],l=u.constructor={};return l[a]=function(){return{foo:1}},u[s](Boolean).foo!==1})}},55528:function(y,e,t){"use strict";var n=t(40033);y.exports=function(r,o){var a=[][r];return!!a&&n(function(){a.call(null,o||function(){return 1},1)})}},56844:function(y,e,t){"use strict";var n=t(10320),r=t(46771),o=t(37457),a=t(24760),s=TypeError,u="Reduce of empty array with no initial value",l=function(f){return function(i,d,c,g){var v=r(i),h=o(v),m=a(v);if(n(d),m===0&&c<2)throw new s(u);var E=f?m-1:0,I=f?-1:1;if(c<2)for(;;){if(E in h){g=h[E],E+=I;break}if(E+=I,f?E<0:m<=E)throw new s(u)}for(;f?E>=0:m>E;E+=I)E in h&&(g=d(g,h[E],E,v));return g}};y.exports={left:l(!1),right:l(!0)}},13345:function(y,e,t){"use strict";var n=t(58310),r=t(37386),o=TypeError,a=Object.getOwnPropertyDescriptor,s=n&&!function(){if(this!==void 0)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(u){return u instanceof TypeError}}();y.exports=s?function(u,l){if(r(u)&&!a(u,"length").writable)throw new o("Cannot set read only .length");return u.length=l}:function(u,l){return u.length=l}},54602:function(y,e,t){"use strict";var n=t(67250);y.exports=n([].slice)},90274:function(y,e,t){"use strict";var n=t(54602),r=Math.floor,o=function a(s,u){var l=s.length;if(l<8)for(var p=1,f,i;p0;)s[i]=s[--i];i!==p++&&(s[i]=f)}else for(var d=r(l/2),c=a(n(s,0,d),u),g=a(n(s,d),u),v=c.length,h=g.length,m=0,E=0;m1?arguments[1]:void 0),j;j=j?j.next:V.first;)for(U(j.value,j.key,this);j&&j.removed;)j=j.previous}return M}(),has:function(){function M(w){return!!P(this,w)}return M}()}),o(T,O?{get:function(){function M(w){var V=P(this,w);return V&&V.value}return M}(),set:function(){function M(w,V){return A(this,w===0?0:w,V)}return M}()}:{add:function(){function M(w){return A(this,w=w===0?0:w,w)}return M}()}),d&&r(T,"size",{configurable:!0,get:function(){function M(){return b(this).size}return M}()}),S}return m}(),setStrong:function(){function m(E,I,O){var C=I+" Iterator",S=h(I),T=h(C);p(E,I,function(b,A){v(this,{type:C,target:b,state:S(b),kind:A,last:void 0})},function(){for(var b=T(this),A=b.kind,P=b.last;P&&P.removed;)P=P.previous;return!b.target||!(b.last=P=P?P.next:b.state.first)?(b.target=void 0,f(void 0,!0)):f(A==="keys"?P.key:A==="values"?P.value:[P.key,P.value],!1)},O?"entries":"values",!O,!0),i(I)}return m}()}},39895:function(y,e,t){"use strict";var n=t(67250),r=t(30145),o=t(81969).getWeakData,a=t(60077),s=t(30365),u=t(42871),l=t(77568),p=t(49450),f=t(22603),i=t(45299),d=t(5419),c=d.set,g=d.getterFor,v=f.find,h=f.findIndex,m=n([].splice),E=0,I=function(T){return T.frozen||(T.frozen=new O)},O=function(){this.entries=[]},C=function(T,b){return v(T.entries,function(A){return A[0]===b})};O.prototype={get:function(){function S(T){var b=C(this,T);if(b)return b[1]}return S}(),has:function(){function S(T){return!!C(this,T)}return S}(),set:function(){function S(T,b){var A=C(this,T);A?A[1]=b:this.entries.push([T,b])}return S}(),delete:function(){function S(T){var b=h(this.entries,function(A){return A[0]===T});return~b&&m(this.entries,b,1),!!~b}return S}()},y.exports={getConstructor:function(){function S(T,b,A,P){var M=T(function(j,G){a(j,w),c(j,{type:b,id:E++,frozen:void 0}),u(G)||p(G,j[P],{that:j,AS_ENTRIES:A})}),w=M.prototype,V=g(b),U=function(){function j(G,$,x){var B=V(G),F=o(s($),!0);return F===!0?I(B).set($,x):F[B.id]=x,G}return j}();return r(w,{delete:function(){function j(G){var $=V(this);if(!l(G))return!1;var x=o(G);return x===!0?I($).delete(G):x&&i(x,$.id)&&delete x[$.id]}return j}(),has:function(){function j(G){var $=V(this);if(!l(G))return!1;var x=o(G);return x===!0?I($).has(G):x&&i(x,$.id)}return j}()}),r(w,A?{get:function(){function j(G){var $=V(this);if(l(G)){var x=o(G);return x===!0?I($).get(G):x?x[$.id]:void 0}}return j}(),set:function(){function j(G,$){return U(this,G,$)}return j}()}:{add:function(){function j(G){return U(this,G,!0)}return j}()}),M}return S}()}},45150:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(67250),a=t(41314),s=t(55938),u=t(81969),l=t(49450),p=t(60077),f=t(55747),i=t(42871),d=t(77568),c=t(40033),g=t(92490),v=t(84925),h=t(5781);y.exports=function(m,E,I){var O=m.indexOf("Map")!==-1,C=m.indexOf("Weak")!==-1,S=O?"set":"add",T=r[m],b=T&&T.prototype,A=T,P={},M=function(B){var F=o(b[B]);s(b,B,B==="add"?function(){function H(K){return F(this,K===0?0:K),this}return H}():B==="delete"?function(H){return C&&!d(H)?!1:F(this,H===0?0:H)}:B==="get"?function(){function H(K){return C&&!d(K)?void 0:F(this,K===0?0:K)}return H}():B==="has"?function(){function H(K){return C&&!d(K)?!1:F(this,K===0?0:K)}return H}():function(){function H(K,W){return F(this,K===0?0:K,W),this}return H}())},w=a(m,!f(T)||!(C||b.forEach&&!c(function(){new T().entries().next()})));if(w)A=I.getConstructor(E,m,O,S),u.enable();else if(a(m,!0)){var V=new A,U=V[S](C?{}:-0,1)!==V,j=c(function(){V.has(1)}),G=g(function(x){new T(x)}),$=!C&&c(function(){for(var x=new T,B=5;B--;)x[S](B,B);return!x.has(-0)});G||(A=E(function(x,B){p(x,b);var F=h(new T,x,A);return i(B)||l(B,F[S],{that:F,AS_ENTRIES:O}),F}),A.prototype=b,b.constructor=A),(j||$)&&(M("delete"),M("has"),O&&M("get")),($||U)&&M(S),C&&b.clear&&delete b.clear}return P[m]=A,n({global:!0,constructor:!0,forced:A!==T},P),v(A,m),C||I.setStrong(A,m,O),A}},5774:function(y,e,t){"use strict";var n=t(45299),r=t(97921),o=t(27193),a=t(74595);y.exports=function(s,u,l){for(var p=r(u),f=a.f,i=o.f,d=0;d"+i+""}},5959:function(y){"use strict";y.exports=function(e,t){return{value:e,done:t}}},37909:function(y,e,t){"use strict";var n=t(58310),r=t(74595),o=t(87458);y.exports=n?function(a,s,u){return r.f(a,s,o(1,u))}:function(a,s,u){return a[s]=u,a}},87458:function(y){"use strict";y.exports=function(e,t){return{enumerable:!(e&1),configurable:!(e&2),writable:!(e&4),value:t}}},60102:function(y,e,t){"use strict";var n=t(58310),r=t(74595),o=t(87458);y.exports=function(a,s,u){n?r.f(a,s,o(0,u)):a[s]=u}},67206:function(y,e,t){"use strict";var n=t(67250),r=t(40033),o=t(24051).start,a=RangeError,s=isFinite,u=Math.abs,l=Date.prototype,p=l.toISOString,f=n(l.getTime),i=n(l.getUTCDate),d=n(l.getUTCFullYear),c=n(l.getUTCHours),g=n(l.getUTCMilliseconds),v=n(l.getUTCMinutes),h=n(l.getUTCMonth),m=n(l.getUTCSeconds);y.exports=r(function(){return p.call(new Date(-50000000000001))!=="0385-07-25T07:06:39.999Z"})||!r(function(){p.call(new Date(NaN))})?function(){function E(){if(!s(f(this)))throw new a("Invalid time value");var I=this,O=d(I),C=g(I),S=O<0?"-":O>9999?"+":"";return S+o(u(O),S?6:4,0)+"-"+o(h(I)+1,2,0)+"-"+o(i(I),2,0)+"T"+o(c(I),2,0)+":"+o(v(I),2,0)+":"+o(m(I),2,0)+"."+o(C,3,0)+"Z"}return E}():p},10886:function(y,e,t){"use strict";var n=t(30365),r=t(13396),o=TypeError;y.exports=function(a){if(n(this),a==="string"||a==="default")a="string";else if(a!=="number")throw new o("Incorrect hint");return r(this,a)}},73936:function(y,e,t){"use strict";var n=t(20001),r=t(74595);y.exports=function(o,a,s){return s.get&&n(s.get,a,{getter:!0}),s.set&&n(s.set,a,{setter:!0}),r.f(o,a,s)}},55938:function(y,e,t){"use strict";var n=t(55747),r=t(74595),o=t(20001),a=t(18231);y.exports=function(s,u,l,p){p||(p={});var f=p.enumerable,i=p.name!==void 0?p.name:u;if(n(l)&&o(l,i,p),p.global)f?s[u]=l:a(u,l);else{try{p.unsafe?s[u]&&(f=!0):delete s[u]}catch(d){}f?s[u]=l:r.f(s,u,{value:l,enumerable:!1,configurable:!p.nonConfigurable,writable:!p.nonWritable})}return s}},30145:function(y,e,t){"use strict";var n=t(55938);y.exports=function(r,o,a){for(var s in o)n(r,s,o[s],a);return r}},18231:function(y,e,t){"use strict";var n=t(74685),r=Object.defineProperty;y.exports=function(o,a){try{r(n,o,{value:a,configurable:!0,writable:!0})}catch(s){n[o]=a}return a}},95108:function(y,e,t){"use strict";var n=t(89393),r=TypeError;y.exports=function(o,a){if(!delete o[a])throw new r("Cannot delete property "+n(a)+" of "+n(o))}},58310:function(y,e,t){"use strict";var n=t(40033);y.exports=!n(function(){return Object.defineProperty({},1,{get:function(){function r(){return 7}return r}()})[1]!==7})},12689:function(y,e,t){"use strict";var n=t(74685),r=t(77568),o=n.document,a=r(o)&&r(o.createElement);y.exports=function(s){return a?o.createElement(s):{}}},21291:function(y){"use strict";var e=TypeError,t=9007199254740991;y.exports=function(n){if(n>t)throw e("Maximum allowed index exceeded");return n}},652:function(y,e,t){"use strict";var n=t(63318),r=n.match(/firefox\/(\d+)/i);y.exports=!!r&&+r[1]},8180:function(y,e,t){"use strict";var n=t(73730),r=t(81702);y.exports=!n&&!r&&typeof window=="object"&&typeof document=="object"},49197:function(y){"use strict";y.exports=typeof Bun=="function"&&Bun&&typeof Bun.version=="string"},73730:function(y){"use strict";y.exports=typeof Deno=="object"&&Deno&&typeof Deno.version=="object"},19228:function(y,e,t){"use strict";var n=t(63318);y.exports=/MSIE|Trident/.test(n)},51802:function(y,e,t){"use strict";var n=t(63318);y.exports=/ipad|iphone|ipod/i.test(n)&&typeof Pebble!="undefined"},83433:function(y,e,t){"use strict";var n=t(63318);y.exports=/(?:ipad|iphone|ipod).*applewebkit/i.test(n)},81702:function(y,e,t){"use strict";var n=t(74685),r=t(7462);y.exports=r(n.process)==="process"},63383:function(y,e,t){"use strict";var n=t(63318);y.exports=/web0s(?!.*chrome)/i.test(n)},63318:function(y){"use strict";y.exports=typeof navigator!="undefined"&&String(navigator.userAgent)||""},5026:function(y,e,t){"use strict";var n=t(74685),r=t(63318),o=n.process,a=n.Deno,s=o&&o.versions||a&&a.version,u=s&&s.v8,l,p;u&&(l=u.split("."),p=l[0]>0&&l[0]<4?1:+(l[0]+l[1])),!p&&r&&(l=r.match(/Edge\/(\d+)/),(!l||l[1]>=74)&&(l=r.match(/Chrome\/(\d+)/),l&&(p=+l[1]))),y.exports=p},9342:function(y,e,t){"use strict";var n=t(63318),r=n.match(/AppleWebKit\/(\d+)\./);y.exports=!!r&&+r[1]},89453:function(y){"use strict";y.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},63964:function(y,e,t){"use strict";var n=t(74685),r=t(27193).f,o=t(37909),a=t(55938),s=t(18231),u=t(5774),l=t(41314);y.exports=function(p,f){var i=p.target,d=p.global,c=p.stat,g,v,h,m,E,I;if(d?v=n:c?v=n[i]||s(i,{}):v=n[i]&&n[i].prototype,v)for(h in f){if(E=f[h],p.dontCallGetSet?(I=r(v,h),m=I&&I.value):m=v[h],g=l(d?h:i+(c?".":"#")+h,p.forced),!g&&m!==void 0){if(typeof E==typeof m)continue;u(E,m)}(p.sham||m&&m.sham)&&o(E,"sham",!0),a(v,h,E,p)}}},40033:function(y){"use strict";y.exports=function(e){try{return!!e()}catch(t){return!0}}},79942:function(y,e,t){"use strict";t(79669);var n=t(91495),r=t(55938),o=t(14489),a=t(40033),s=t(24697),u=t(37909),l=s("species"),p=RegExp.prototype;y.exports=function(f,i,d,c){var g=s(f),v=!a(function(){var I={};return I[g]=function(){return 7},""[f](I)!==7}),h=v&&!a(function(){var I=!1,O=/a/;return f==="split"&&(O={},O.constructor={},O.constructor[l]=function(){return O},O.flags="",O[g]=/./[g]),O.exec=function(){return I=!0,null},O[g](""),!I});if(!v||!h||d){var m=/./[g],E=i(g,""[f],function(I,O,C,S,T){var b=O.exec;return b===o||b===p.exec?v&&!T?{done:!0,value:n(m,O,C,S)}:{done:!0,value:n(I,C,O,S)}:{done:!1}});r(String.prototype,f,E[0]),r(p,g,E[1])}c&&u(p[g],"sham",!0)}},65561:function(y,e,t){"use strict";var n=t(37386),r=t(24760),o=t(21291),a=t(75754),s=function u(l,p,f,i,d,c,g,v){for(var h=d,m=0,E=g?a(g,v):!1,I,O;m0&&n(I)?(O=r(I),h=u(l,p,I,O,h,c-1)-1):(o(h+1),l[h]=I),h++),m++;return h};y.exports=s},50730:function(y,e,t){"use strict";var n=t(40033);y.exports=!n(function(){return Object.isExtensible(Object.preventExtensions({}))})},61267:function(y,e,t){"use strict";var n=t(55050),r=Function.prototype,o=r.apply,a=r.call;y.exports=typeof Reflect=="object"&&Reflect.apply||(n?a.bind(o):function(){return a.apply(o,arguments)})},75754:function(y,e,t){"use strict";var n=t(71138),r=t(10320),o=t(55050),a=n(n.bind);y.exports=function(s,u){return r(s),u===void 0?s:o?a(s,u):function(){return s.apply(u,arguments)}}},55050:function(y,e,t){"use strict";var n=t(40033);y.exports=!n(function(){var r=function(){}.bind();return typeof r!="function"||r.hasOwnProperty("prototype")})},66284:function(y,e,t){"use strict";var n=t(67250),r=t(10320),o=t(77568),a=t(45299),s=t(54602),u=t(55050),l=Function,p=n([].concat),f=n([].join),i={},d=function(g,v,h){if(!a(i,v)){for(var m=[],E=0;E]*>)/g,p=/\$([$&'`]|\d{1,2})/g;y.exports=function(f,i,d,c,g,v){var h=d+f.length,m=c.length,E=p;return g!==void 0&&(g=r(g),E=l),s(v,E,function(I,O){var C;switch(a(O,0)){case"$":return"$";case"&":return f;case"`":return u(i,0,d);case"'":return u(i,h);case"<":C=g[u(O,1,-1)];break;default:var S=+O;if(S===0)return I;if(S>m){var T=o(S/10);return T===0?I:T<=m?c[T-1]===void 0?a(O,1):c[T-1]+a(O,1):I}C=c[S-1]}return C===void 0?"":C})}},74685:function(y,e,t){"use strict";var n=function(o){return o&&o.Math===Math&&o};y.exports=n(typeof globalThis=="object"&&globalThis)||n(typeof window=="object"&&window)||n(typeof self=="object"&&self)||n(typeof t.g=="object"&&t.g)||n(!1)||function(){return this}()||Function("return this")()},45299:function(y,e,t){"use strict";var n=t(67250),r=t(46771),o=n({}.hasOwnProperty);y.exports=Object.hasOwn||function(){function a(s,u){return o(r(s),u)}return a}()},79195:function(y){"use strict";y.exports={}},72259:function(y){"use strict";y.exports=function(e,t){try{arguments.length}catch(n){}}},5315:function(y,e,t){"use strict";var n=t(4009);y.exports=n("document","documentElement")},36223:function(y,e,t){"use strict";var n=t(58310),r=t(40033),o=t(12689);y.exports=!n&&!r(function(){return Object.defineProperty(o("div"),"a",{get:function(){function a(){return 7}return a}()}).a!==7})},91784:function(y){"use strict";var e=Array,t=Math.abs,n=Math.pow,r=Math.floor,o=Math.log,a=Math.LN2,s=function(p,f,i){var d=e(i),c=i*8-f-1,g=(1<>1,h=f===23?n(2,-24)-n(2,-77):0,m=p<0||p===0&&1/p<0?1:0,E=0,I,O,C;for(p=t(p),p!==p||p===1/0?(O=p!==p?1:0,I=g):(I=r(o(p)/a),C=n(2,-I),p*C<1&&(I--,C*=2),I+v>=1?p+=h/C:p+=h*n(2,1-v),p*C>=2&&(I++,C/=2),I+v>=g?(O=0,I=g):I+v>=1?(O=(p*C-1)*n(2,f),I+=v):(O=p*n(2,v-1)*n(2,f),I=0));f>=8;)d[E++]=O&255,O/=256,f-=8;for(I=I<0;)d[E++]=I&255,I/=256,c-=8;return d[--E]|=m*128,d},u=function(p,f){var i=p.length,d=i*8-f-1,c=(1<>1,v=d-7,h=i-1,m=p[h--],E=m&127,I;for(m>>=7;v>0;)E=E*256+p[h--],v-=8;for(I=E&(1<<-v)-1,E>>=-v,v+=f;v>0;)I=I*256+p[h--],v-=8;if(E===0)E=1-g;else{if(E===c)return I?NaN:m?-1/0:1/0;I+=n(2,f),E-=g}return(m?-1:1)*I*n(2,E-f)};y.exports={pack:s,unpack:u}},37457:function(y,e,t){"use strict";var n=t(67250),r=t(40033),o=t(7462),a=Object,s=n("".split);y.exports=r(function(){return!a("z").propertyIsEnumerable(0)})?function(u){return o(u)==="String"?s(u,""):a(u)}:a},5781:function(y,e,t){"use strict";var n=t(55747),r=t(77568),o=t(76649);y.exports=function(a,s,u){var l,p;return o&&n(l=s.constructor)&&l!==u&&r(p=l.prototype)&&p!==u.prototype&&o(a,p),a}},40492:function(y,e,t){"use strict";var n=t(67250),r=t(55747),o=t(40095),a=n(Function.toString);r(o.inspectSource)||(o.inspectSource=function(s){return a(s)}),y.exports=o.inspectSource},81969:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(79195),a=t(77568),s=t(45299),u=t(74595).f,l=t(37310),p=t(81644),f=t(81834),i=t(16738),d=t(50730),c=!1,g=i("meta"),v=0,h=function(T){u(T,g,{value:{objectID:"O"+v++,weakData:{}}})},m=function(T,b){if(!a(T))return typeof T=="symbol"?T:(typeof T=="string"?"S":"P")+T;if(!s(T,g)){if(!f(T))return"F";if(!b)return"E";h(T)}return T[g].objectID},E=function(T,b){if(!s(T,g)){if(!f(T))return!0;if(!b)return!1;h(T)}return T[g].weakData},I=function(T){return d&&c&&f(T)&&!s(T,g)&&h(T),T},O=function(){C.enable=function(){},c=!0;var T=l.f,b=r([].splice),A={};A[g]=1,T(A).length&&(l.f=function(P){for(var M=T(P),w=0,V=M.length;wP;P++)if(w=G(v[P]),w&&l(g,w))return w;return new c(!1)}b=p(v,A)}for(V=O?v.next:b.next;!(U=r(V,b)).done;){try{w=G(U.value)}catch($){i(b,"throw",$)}if(typeof w=="object"&&w&&l(g,w))return w}return new c(!1)}},28649:function(y,e,t){"use strict";var n=t(91495),r=t(30365),o=t(78060);y.exports=function(a,s,u){var l,p;r(a);try{if(l=o(a,"return"),!l){if(s==="throw")throw u;return u}l=n(l,a)}catch(f){p=!0,l=f}if(s==="throw")throw u;if(p)throw l;return r(l),u}},5656:function(y,e,t){"use strict";var n=t(67635).IteratorPrototype,r=t(80674),o=t(87458),a=t(84925),s=t(83967),u=function(){return this};y.exports=function(l,p,f,i){var d=p+" Iterator";return l.prototype=r(n,{next:o(+!i,f)}),a(l,d,!1,!0),s[d]=u,l}},65574:function(y,e,t){"use strict";var n=t(63964),r=t(91495),o=t(4493),a=t(70520),s=t(55747),u=t(5656),l=t(36917),p=t(76649),f=t(84925),i=t(37909),d=t(55938),c=t(24697),g=t(83967),v=t(67635),h=a.PROPER,m=a.CONFIGURABLE,E=v.IteratorPrototype,I=v.BUGGY_SAFARI_ITERATORS,O=c("iterator"),C="keys",S="values",T="entries",b=function(){return this};y.exports=function(A,P,M,w,V,U,j){u(M,P,w);var G=function(Q){if(Q===V&&H)return H;if(!I&&Q&&Q in B)return B[Q];switch(Q){case C:return function(){function X(){return new M(this,Q)}return X}();case S:return function(){function X(){return new M(this,Q)}return X}();case T:return function(){function X(){return new M(this,Q)}return X}()}return function(){return new M(this)}},$=P+" Iterator",x=!1,B=A.prototype,F=B[O]||B["@@iterator"]||V&&B[V],H=!I&&F||G(V),K=P==="Array"&&B.entries||F,W,q,ut;if(K&&(W=l(K.call(new A)),W!==Object.prototype&&W.next&&(!o&&l(W)!==E&&(p?p(W,E):s(W[O])||d(W,O,b)),f(W,$,!0,!0),o&&(g[$]=b))),h&&V===S&&F&&F.name!==S&&(!o&&m?i(B,"name",S):(x=!0,H=function(){function ct(){return r(F,this)}return ct}())),V)if(q={values:G(S),keys:U?H:G(C),entries:G(T)},j)for(ut in q)(I||x||!(ut in B))&&d(B,ut,q[ut]);else n({target:P,proto:!0,forced:I||x},q);return(!o||j)&&B[O]!==H&&d(B,O,H,{name:V}),g[P]=H,q}},67635:function(y,e,t){"use strict";var n=t(40033),r=t(55747),o=t(77568),a=t(80674),s=t(36917),u=t(55938),l=t(24697),p=t(4493),f=l("iterator"),i=!1,d,c,g;[].keys&&(g=[].keys(),"next"in g?(c=s(s(g)),c!==Object.prototype&&(d=c)):i=!0);var v=!o(d)||n(function(){var h={};return d[f].call(h)!==h});v?d={}:p&&(d=a(d)),r(d[f])||u(d,f,function(){return this}),y.exports={IteratorPrototype:d,BUGGY_SAFARI_ITERATORS:i}},83967:function(y){"use strict";y.exports={}},24760:function(y,e,t){"use strict";var n=t(10188);y.exports=function(r){return n(r.length)}},20001:function(y,e,t){"use strict";var n=t(67250),r=t(40033),o=t(55747),a=t(45299),s=t(58310),u=t(70520).CONFIGURABLE,l=t(40492),p=t(5419),f=p.enforce,i=p.get,d=String,c=Object.defineProperty,g=n("".slice),v=n("".replace),h=n([].join),m=s&&!r(function(){return c(function(){},"length",{value:8}).length!==8}),E=String(String).split("String"),I=y.exports=function(O,C,S){g(d(C),0,7)==="Symbol("&&(C="["+v(d(C),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),S&&S.getter&&(C="get "+C),S&&S.setter&&(C="set "+C),(!a(O,"name")||u&&O.name!==C)&&(s?c(O,"name",{value:C,configurable:!0}):O.name=C),m&&S&&a(S,"arity")&&O.length!==S.arity&&c(O,"length",{value:S.arity});try{S&&a(S,"constructor")&&S.constructor?s&&c(O,"prototype",{writable:!1}):O.prototype&&(O.prototype=void 0)}catch(b){}var T=f(O);return a(T,"source")||(T.source=h(E,typeof C=="string"?C:"")),O};Function.prototype.toString=I(function(){function O(){return o(this)&&i(this).source||l(this)}return O}(),"toString")},82040:function(y){"use strict";var e=Math.expm1,t=Math.exp;y.exports=!e||e(10)>22025.465794806718||e(10)<22025.465794806718||e(-2e-17)!==-2e-17?function(){function n(r){var o=+r;return o===0?o:o>-1e-6&&o<1e-6?o+o*o/2:t(o)-1}return n}():e},14950:function(y,e,t){"use strict";var n=t(22172),r=Math.abs,o=2220446049250313e-31,a=1/o,s=function(l){return l+a-a};y.exports=function(u,l,p,f){var i=+u,d=r(i),c=n(i);if(dp||v!==v?c*(1/0):c*v}},95867:function(y,e,t){"use strict";var n=t(14950),r=11920928955078125e-23,o=34028234663852886e22,a=11754943508222875e-54;y.exports=Math.fround||function(){function s(u){return n(u,r,o,a)}return s}()},75002:function(y){"use strict";var e=Math.log,t=Math.LOG10E;y.exports=Math.log10||function(){function n(r){return e(r)*t}return n}()},90874:function(y){"use strict";var e=Math.log;y.exports=Math.log1p||function(){function t(n){var r=+n;return r>-1e-8&&r<1e-8?r-r*r/2:e(1+r)}return t}()},22172:function(y){"use strict";y.exports=Math.sign||function(){function e(t){var n=+t;return n===0||n!==n?n:n<0?-1:1}return e}()},21119:function(y){"use strict";var e=Math.ceil,t=Math.floor;y.exports=Math.trunc||function(){function n(r){var o=+r;return(o>0?t:e)(o)}return n}()},37713:function(y,e,t){"use strict";var n=t(74685),r=t(44915),o=t(75754),a=t(60375).set,s=t(9547),u=t(83433),l=t(51802),p=t(63383),f=t(81702),i=n.MutationObserver||n.WebKitMutationObserver,d=n.document,c=n.process,g=n.Promise,v=r("queueMicrotask"),h,m,E,I,O;if(!v){var C=new s,S=function(){var b,A;for(f&&(b=c.domain)&&b.exit();A=C.get();)try{A()}catch(P){throw C.head&&h(),P}b&&b.enter()};!u&&!f&&!p&&i&&d?(m=!0,E=d.createTextNode(""),new i(S).observe(E,{characterData:!0}),h=function(){E.data=m=!m}):!l&&g&&g.resolve?(I=g.resolve(void 0),I.constructor=g,O=o(I.then,I),h=function(){O(S)}):f?h=function(){c.nextTick(S)}:(a=o(a,n),h=function(){a(S)}),v=function(b){C.head||h(),C.add(b)}}y.exports=v},81837:function(y,e,t){"use strict";var n=t(10320),r=TypeError,o=function(s){var u,l;this.promise=new s(function(p,f){if(u!==void 0||l!==void 0)throw new r("Bad Promise constructor");u=p,l=f}),this.resolve=n(u),this.reject=n(l)};y.exports.f=function(a){return new o(a)}},86213:function(y,e,t){"use strict";var n=t(72586),r=TypeError;y.exports=function(o){if(n(o))throw new r("The method doesn't accept regular expressions");return o}},3294:function(y,e,t){"use strict";var n=t(74685),r=n.isFinite;y.exports=Number.isFinite||function(){function o(a){return typeof a=="number"&&r(a)}return o}()},28506:function(y,e,t){"use strict";var n=t(74685),r=t(40033),o=t(67250),a=t(12605),s=t(92648).trim,u=t(4198),l=o("".charAt),p=n.parseFloat,f=n.Symbol,i=f&&f.iterator,d=1/p(u+"-0")!==-1/0||i&&!r(function(){p(Object(i))});y.exports=d?function(){function c(g){var v=s(a(g)),h=p(v);return h===0&&l(v,0)==="-"?-0:h}return c}():p},13693:function(y,e,t){"use strict";var n=t(74685),r=t(40033),o=t(67250),a=t(12605),s=t(92648).trim,u=t(4198),l=n.parseInt,p=n.Symbol,f=p&&p.iterator,i=/^[+-]?0x/i,d=o(i.exec),c=l(u+"08")!==8||l(u+"0x16")!==22||f&&!r(function(){l(Object(f))});y.exports=c?function(){function g(v,h){var m=s(a(v));return l(m,h>>>0||(d(i,m)?16:10))}return g}():l},41143:function(y,e,t){"use strict";var n=t(58310),r=t(67250),o=t(91495),a=t(40033),s=t(18450),u=t(89235),l=t(12867),p=t(46771),f=t(37457),i=Object.assign,d=Object.defineProperty,c=r([].concat);y.exports=!i||a(function(){if(n&&i({b:1},i(d({},"a",{enumerable:!0,get:function(){function E(){d(this,"b",{value:3,enumerable:!1})}return E}()}),{b:2})).b!==1)return!0;var g={},v={},h=Symbol("assign detection"),m="abcdefghijklmnopqrst";return g[h]=7,m.split("").forEach(function(E){v[E]=E}),i({},g)[h]!==7||s(i({},v)).join("")!==m})?function(){function g(v,h){for(var m=p(v),E=arguments.length,I=1,O=u.f,C=l.f;E>I;)for(var S=f(arguments[I++]),T=O?c(s(S),O(S)):s(S),b=T.length,A=0,P;b>A;)P=T[A++],(!n||o(C,S,P))&&(m[P]=S[P]);return m}return g}():i},80674:function(y,e,t){"use strict";var n=t(30365),r=t(24239),o=t(89453),a=t(79195),s=t(5315),u=t(12689),l=t(19417),p=">",f="<",i="prototype",d="script",c=l("IE_PROTO"),g=function(){},v=function(C){return f+d+p+C+f+"/"+d+p},h=function(C){C.write(v("")),C.close();var S=C.parentWindow.Object;return C=null,S},m=function(){var C=u("iframe"),S="java"+d+":",T;return C.style.display="none",s.appendChild(C),C.src=String(S),T=C.contentWindow.document,T.open(),T.write(v("document.F=Object")),T.close(),T.F},E,I=function(){try{E=new ActiveXObject("htmlfile")}catch(S){}I=typeof document!="undefined"?document.domain&&E?h(E):m():h(E);for(var C=o.length;C--;)delete I[i][o[C]];return I()};a[c]=!0,y.exports=Object.create||function(){function O(C,S){var T;return C!==null?(g[i]=n(C),T=new g,g[i]=null,T[c]=C):T=I(),S===void 0?T:r.f(T,S)}return O}()},24239:function(y,e,t){"use strict";var n=t(58310),r=t(80944),o=t(74595),a=t(30365),s=t(57591),u=t(18450);e.f=n&&!r?Object.defineProperties:function(){function l(p,f){a(p);for(var i=s(f),d=u(f),c=d.length,g=0,v;c>g;)o.f(p,v=d[g++],i[v]);return p}return l}()},74595:function(y,e,t){"use strict";var n=t(58310),r=t(36223),o=t(80944),a=t(30365),s=t(767),u=TypeError,l=Object.defineProperty,p=Object.getOwnPropertyDescriptor,f="enumerable",i="configurable",d="writable";e.f=n?o?function(){function c(g,v,h){if(a(g),v=s(v),a(h),typeof g=="function"&&v==="prototype"&&"value"in h&&d in h&&!h[d]){var m=p(g,v);m&&m[d]&&(g[v]=h.value,h={configurable:i in h?h[i]:m[i],enumerable:f in h?h[f]:m[f],writable:!1})}return l(g,v,h)}return c}():l:function(){function c(g,v,h){if(a(g),v=s(v),a(h),r)try{return l(g,v,h)}catch(m){}if("get"in h||"set"in h)throw new u("Accessors not supported");return"value"in h&&(g[v]=h.value),g}return c}()},27193:function(y,e,t){"use strict";var n=t(58310),r=t(91495),o=t(12867),a=t(87458),s=t(57591),u=t(767),l=t(45299),p=t(36223),f=Object.getOwnPropertyDescriptor;e.f=n?f:function(){function i(d,c){if(d=s(d),c=u(c),p)try{return f(d,c)}catch(g){}if(l(d,c))return a(!r(o.f,d,c),d[c])}return i}()},81644:function(y,e,t){"use strict";var n=t(7462),r=t(57591),o=t(37310).f,a=t(54602),s=typeof window=="object"&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],u=function(p){try{return o(p)}catch(f){return a(s)}};y.exports.f=function(){function l(p){return s&&n(p)==="Window"?u(p):o(r(p))}return l}()},37310:function(y,e,t){"use strict";var n=t(53726),r=t(89453),o=r.concat("length","prototype");e.f=Object.getOwnPropertyNames||function(){function a(s){return n(s,o)}return a}()},89235:function(y,e){"use strict";e.f=Object.getOwnPropertySymbols},36917:function(y,e,t){"use strict";var n=t(45299),r=t(55747),o=t(46771),a=t(19417),s=t(9225),u=a("IE_PROTO"),l=Object,p=l.prototype;y.exports=s?l.getPrototypeOf:function(f){var i=o(f);if(n(i,u))return i[u];var d=i.constructor;return r(d)&&i instanceof d?d.prototype:i instanceof l?p:null}},81834:function(y,e,t){"use strict";var n=t(40033),r=t(77568),o=t(7462),a=t(3782),s=Object.isExtensible,u=n(function(){s(1)});y.exports=u||a?function(){function l(p){return!r(p)||a&&o(p)==="ArrayBuffer"?!1:s?s(p):!0}return l}():s},21287:function(y,e,t){"use strict";var n=t(67250);y.exports=n({}.isPrototypeOf)},53726:function(y,e,t){"use strict";var n=t(67250),r=t(45299),o=t(57591),a=t(14211).indexOf,s=t(79195),u=n([].push);y.exports=function(l,p){var f=o(l),i=0,d=[],c;for(c in f)!r(s,c)&&r(f,c)&&u(d,c);for(;p.length>i;)r(f,c=p[i++])&&(~a(d,c)||u(d,c));return d}},18450:function(y,e,t){"use strict";var n=t(53726),r=t(89453);y.exports=Object.keys||function(){function o(a){return n(a,r)}return o}()},12867:function(y,e){"use strict";var t={}.propertyIsEnumerable,n=Object.getOwnPropertyDescriptor,r=n&&!t.call({1:2},1);e.f=r?function(){function o(a){var s=n(this,a);return!!s&&s.enumerable}return o}():t},57377:function(y,e,t){"use strict";var n=t(4493),r=t(74685),o=t(40033),a=t(9342);y.exports=n||!o(function(){if(!(a&&a<535)){var s=Math.random();__defineSetter__.call(null,s,function(){}),delete r[s]}})},76649:function(y,e,t){"use strict";var n=t(38656),r=t(77568),o=t(16952),a=t(35908);y.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var s=!1,u={},l;try{l=n(Object.prototype,"__proto__","set"),l(u,[]),s=u instanceof Array}catch(p){}return function(){function p(f,i){return o(f),a(i),r(f)&&(s?l(f,i):f.__proto__=i),f}return p}()}():void 0)},70915:function(y,e,t){"use strict";var n=t(58310),r=t(40033),o=t(67250),a=t(36917),s=t(18450),u=t(57591),l=t(12867).f,p=o(l),f=o([].push),i=n&&r(function(){var c=Object.create(null);return c[2]=2,!p(c,2)}),d=function(g){return function(v){for(var h=u(v),m=s(h),E=i&&a(h)===null,I=m.length,O=0,C=[],S;I>O;)S=m[O++],(!n||(E?S in h:p(h,S)))&&f(C,g?[S,h[S]]:h[S]);return C}};y.exports={entries:d(!0),values:d(!1)}},2509:function(y,e,t){"use strict";var n=t(2650),r=t(2281);y.exports=n?{}.toString:function(){function o(){return"[object "+r(this)+"]"}return o}()},13396:function(y,e,t){"use strict";var n=t(91495),r=t(55747),o=t(77568),a=TypeError;y.exports=function(s,u){var l,p;if(u==="string"&&r(l=s.toString)&&!o(p=n(l,s))||r(l=s.valueOf)&&!o(p=n(l,s))||u!=="string"&&r(l=s.toString)&&!o(p=n(l,s)))return p;throw new a("Can't convert object to primitive value")}},97921:function(y,e,t){"use strict";var n=t(4009),r=t(67250),o=t(37310),a=t(89235),s=t(30365),u=r([].concat);y.exports=n("Reflect","ownKeys")||function(){function l(p){var f=o.f(s(p)),i=a.f;return i?u(f,i(p)):f}return l}()},61765:function(y,e,t){"use strict";var n=t(74685);y.exports=n},10729:function(y){"use strict";y.exports=function(e){try{return{error:!1,value:e()}}catch(t){return{error:!0,value:t}}}},74854:function(y,e,t){"use strict";var n=t(74685),r=t(67512),o=t(55747),a=t(41314),s=t(40492),u=t(24697),l=t(8180),p=t(73730),f=t(4493),i=t(5026),d=r&&r.prototype,c=u("species"),g=!1,v=o(n.PromiseRejectionEvent),h=a("Promise",function(){var m=s(r),E=m!==String(r);if(!E&&i===66||f&&!(d.catch&&d.finally))return!0;if(!i||i<51||!/native code/.test(m)){var I=new r(function(S){S(1)}),O=function(T){T(function(){},function(){})},C=I.constructor={};if(C[c]=O,g=I.then(function(){})instanceof O,!g)return!0}return!E&&(l||p)&&!v});y.exports={CONSTRUCTOR:h,REJECTION_EVENT:v,SUBCLASSING:g}},67512:function(y,e,t){"use strict";var n=t(74685);y.exports=n.Promise},66628:function(y,e,t){"use strict";var n=t(30365),r=t(77568),o=t(81837);y.exports=function(a,s){if(n(a),r(s)&&s.constructor===a)return s;var u=o.f(a),l=u.resolve;return l(s),u.promise}},48199:function(y,e,t){"use strict";var n=t(67512),r=t(92490),o=t(74854).CONSTRUCTOR;y.exports=o||!r(function(a){n.all(a).then(void 0,function(){})})},34550:function(y,e,t){"use strict";var n=t(74595).f;y.exports=function(r,o,a){a in r||n(r,a,{configurable:!0,get:function(){function s(){return o[a]}return s}(),set:function(){function s(u){o[a]=u}return s}()})}},9547:function(y){"use strict";var e=function(){this.head=null,this.tail=null};e.prototype={add:function(){function t(n){var r={item:n,next:null},o=this.tail;o?o.next=r:this.head=r,this.tail=r}return t}(),get:function(){function t(){var n=this.head;if(n){var r=this.head=n.next;return r===null&&(this.tail=null),n.item}}return t}()},y.exports=e},28340:function(y,e,t){"use strict";var n=t(91495),r=t(30365),o=t(55747),a=t(7462),s=t(14489),u=TypeError;y.exports=function(l,p){var f=l.exec;if(o(f)){var i=n(f,l,p);return i!==null&&r(i),i}if(a(l)==="RegExp")return n(s,l,p);throw new u("RegExp#exec called on incompatible receiver")}},14489:function(y,e,t){"use strict";var n=t(91495),r=t(67250),o=t(12605),a=t(70901),s=t(62115),u=t(16639),l=t(80674),p=t(5419).get,f=t(39173),i=t(35688),d=u("native-string-replace",String.prototype.replace),c=RegExp.prototype.exec,g=c,v=r("".charAt),h=r("".indexOf),m=r("".replace),E=r("".slice),I=function(){var T=/a/,b=/b*/g;return n(c,T,"a"),n(c,b,"a"),T.lastIndex!==0||b.lastIndex!==0}(),O=s.BROKEN_CARET,C=/()??/.exec("")[1]!==void 0,S=I||C||O||f||i;S&&(g=function(){function T(b){var A=this,P=p(A),M=o(b),w=P.raw,V,U,j,G,$,x,B;if(w)return w.lastIndex=A.lastIndex,V=n(g,w,M),A.lastIndex=w.lastIndex,V;var F=P.groups,H=O&&A.sticky,K=n(a,A),W=A.source,q=0,ut=M;if(H&&(K=m(K,"y",""),h(K,"g")===-1&&(K+="g"),ut=E(M,A.lastIndex),A.lastIndex>0&&(!A.multiline||A.multiline&&v(M,A.lastIndex-1)!=="\n")&&(W="(?: "+W+")",ut=" "+ut,q++),U=new RegExp("^(?:"+W+")",K)),C&&(U=new RegExp("^"+W+"$(?!\\s)",K)),I&&(j=A.lastIndex),G=n(c,H?U:A,ut),H?G?(G.input=E(G.input,q),G[0]=E(G[0],q),G.index=A.lastIndex,A.lastIndex+=G[0].length):A.lastIndex=0:I&&G&&(A.lastIndex=A.global?G.index+G[0].length:j),C&&G&&G.length>1&&n(d,G[0],U,function(){for($=1;$b)","g");return a.exec("b").groups.a!=="b"||"b".replace(a,"$c")!=="bc"})},16952:function(y,e,t){"use strict";var n=t(42871),r=TypeError;y.exports=function(o){if(n(o))throw new r("Can't call method on "+o);return o}},44915:function(y,e,t){"use strict";var n=t(74685),r=t(58310),o=Object.getOwnPropertyDescriptor;y.exports=function(a){if(!r)return n[a];var s=o(n,a);return s&&s.value}},5700:function(y){"use strict";y.exports=Object.is||function(){function e(t,n){return t===n?t!==0||1/t===1/n:t!==t&&n!==n}return e}()},78362:function(y,e,t){"use strict";var n=t(74685),r=t(61267),o=t(55747),a=t(49197),s=t(63318),u=t(54602),l=t(24986),p=n.Function,f=/MSIE .\./.test(s)||a&&function(){var i=n.Bun.version.split(".");return i.length<3||i[0]==="0"&&(i[1]<3||i[1]==="3"&&i[2]==="0")}();y.exports=function(i,d){var c=d?2:1;return f?function(g,v){var h=l(arguments.length,1)>c,m=o(g)?g:p(g),E=h?u(arguments,c):[],I=h?function(){r(m,this,E)}:m;return d?i(I,v):i(I)}:i}},58491:function(y,e,t){"use strict";var n=t(4009),r=t(73936),o=t(24697),a=t(58310),s=o("species");y.exports=function(u){var l=n(u);a&&l&&!l[s]&&r(l,s,{configurable:!0,get:function(){function p(){return this}return p}()})}},84925:function(y,e,t){"use strict";var n=t(74595).f,r=t(45299),o=t(24697),a=o("toStringTag");y.exports=function(s,u,l){s&&!l&&(s=s.prototype),s&&!r(s,a)&&n(s,a,{configurable:!0,value:u})}},19417:function(y,e,t){"use strict";var n=t(16639),r=t(16738),o=n("keys");y.exports=function(a){return o[a]||(o[a]=r(a))}},40095:function(y,e,t){"use strict";var n=t(4493),r=t(74685),o=t(18231),a="__core-js_shared__",s=y.exports=r[a]||o(a,{});(s.versions||(s.versions=[])).push({version:"3.37.1",mode:n?"pure":"global",copyright:"\xA9 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.37.1/LICENSE",source:"https://github.com/zloirock/core-js"})},16639:function(y,e,t){"use strict";var n=t(40095);y.exports=function(r,o){return n[r]||(n[r]=o||{})}},28987:function(y,e,t){"use strict";var n=t(30365),r=t(32606),o=t(42871),a=t(24697),s=a("species");y.exports=function(u,l){var p=n(u).constructor,f;return p===void 0||o(f=n(p)[s])?l:r(f)}},88539:function(y,e,t){"use strict";var n=t(40033);y.exports=function(r){return n(function(){var o=""[r]('"');return o!==o.toLowerCase()||o.split('"').length>3})}},50233:function(y,e,t){"use strict";var n=t(67250),r=t(61365),o=t(12605),a=t(16952),s=n("".charAt),u=n("".charCodeAt),l=n("".slice),p=function(i){return function(d,c){var g=o(a(d)),v=r(c),h=g.length,m,E;return v<0||v>=h?i?"":void 0:(m=u(g,v),m<55296||m>56319||v+1===h||(E=u(g,v+1))<56320||E>57343?i?s(g,v):m:i?l(g,v,v+2):(m-55296<<10)+(E-56320)+65536)}};y.exports={codeAt:p(!1),charAt:p(!0)}},34125:function(y,e,t){"use strict";var n=t(63318);y.exports=/Version\/10(?:\.\d+){1,2}(?: [\w./]+)?(?: Mobile\/\w+)? Safari\//.test(n)},24051:function(y,e,t){"use strict";var n=t(67250),r=t(10188),o=t(12605),a=t(62443),s=t(16952),u=n(a),l=n("".slice),p=Math.ceil,f=function(d){return function(c,g,v){var h=o(s(c)),m=r(g),E=h.length,I=v===void 0?" ":o(v),O,C;return m<=E||I===""?h:(O=m-E,C=u(I,p(O/I.length)),C.length>O&&(C=l(C,0,O)),d?h+C:C+h)}};y.exports={start:f(!1),end:f(!0)}},62443:function(y,e,t){"use strict";var n=t(61365),r=t(12605),o=t(16952),a=RangeError;y.exports=function(){function s(u){var l=r(o(this)),p="",f=n(u);if(f<0||f===1/0)throw new a("Wrong number of repetitions");for(;f>0;(f>>>=1)&&(l+=l))f&1&&(p+=l);return p}return s}()},43476:function(y,e,t){"use strict";var n=t(92648).end,r=t(90012);y.exports=r("trimEnd")?function(){function o(){return n(this)}return o}():"".trimEnd},90012:function(y,e,t){"use strict";var n=t(70520).PROPER,r=t(40033),o=t(4198),a="\u200B\x85\u180E";y.exports=function(s){return r(function(){return!!o[s]()||a[s]()!==a||n&&o[s].name!==s})}},43885:function(y,e,t){"use strict";var n=t(92648).start,r=t(90012);y.exports=r("trimStart")?function(){function o(){return n(this)}return o}():"".trimStart},92648:function(y,e,t){"use strict";var n=t(67250),r=t(16952),o=t(12605),a=t(4198),s=n("".replace),u=RegExp("^["+a+"]+"),l=RegExp("(^|[^"+a+"])["+a+"]+$"),p=function(i){return function(d){var c=o(r(d));return i&1&&(c=s(c,u,"")),i&2&&(c=s(c,l,"$1")),c}};y.exports={start:p(1),end:p(2),trim:p(3)}},52357:function(y,e,t){"use strict";var n=t(5026),r=t(40033),o=t(74685),a=o.String;y.exports=!!Object.getOwnPropertySymbols&&!r(function(){var s=Symbol("symbol detection");return!a(s)||!(Object(s)instanceof Symbol)||!Symbol.sham&&n&&n<41})},52360:function(y,e,t){"use strict";var n=t(91495),r=t(4009),o=t(24697),a=t(55938);y.exports=function(){var s=r("Symbol"),u=s&&s.prototype,l=u&&u.valueOf,p=o("toPrimitive");u&&!u[p]&&a(u,p,function(f){return n(l,this)},{arity:1})}},66570:function(y,e,t){"use strict";var n=t(52357);y.exports=n&&!!Symbol.for&&!!Symbol.keyFor},60375:function(y,e,t){"use strict";var n=t(74685),r=t(61267),o=t(75754),a=t(55747),s=t(45299),u=t(40033),l=t(5315),p=t(54602),f=t(12689),i=t(24986),d=t(83433),c=t(81702),g=n.setImmediate,v=n.clearImmediate,h=n.process,m=n.Dispatch,E=n.Function,I=n.MessageChannel,O=n.String,C=0,S={},T="onreadystatechange",b,A,P,M;u(function(){b=n.location});var w=function($){if(s(S,$)){var x=S[$];delete S[$],x()}},V=function($){return function(){w($)}},U=function($){w($.data)},j=function($){n.postMessage(O($),b.protocol+"//"+b.host)};(!g||!v)&&(g=function(){function G($){i(arguments.length,1);var x=a($)?$:E($),B=p(arguments,1);return S[++C]=function(){r(x,void 0,B)},A(C),C}return G}(),v=function(){function G($){delete S[$]}return G}(),c?A=function($){h.nextTick(V($))}:m&&m.now?A=function($){m.now(V($))}:I&&!d?(P=new I,M=P.port2,P.port1.onmessage=U,A=o(M.postMessage,M)):n.addEventListener&&a(n.postMessage)&&!n.importScripts&&b&&b.protocol!=="file:"&&!u(j)?(A=j,n.addEventListener("message",U,!1)):T in f("script")?A=function($){l.appendChild(f("script"))[T]=function(){l.removeChild(this),w($)}}:A=function($){setTimeout(V($),0)}),y.exports={set:g,clear:v}},46438:function(y,e,t){"use strict";var n=t(67250);y.exports=n(1 .valueOf)},13912:function(y,e,t){"use strict";var n=t(61365),r=Math.max,o=Math.min;y.exports=function(a,s){var u=n(a);return u<0?r(u+s,0):o(u,s)}},61484:function(y,e,t){"use strict";var n=t(24843),r=TypeError;y.exports=function(o){var a=n(o,"number");if(typeof a=="number")throw new r("Can't convert number to bigint");return BigInt(a)}},43806:function(y,e,t){"use strict";var n=t(61365),r=t(10188),o=RangeError;y.exports=function(a){if(a===void 0)return 0;var s=n(a),u=r(s);if(s!==u)throw new o("Wrong length or index");return u}},57591:function(y,e,t){"use strict";var n=t(37457),r=t(16952);y.exports=function(o){return n(r(o))}},61365:function(y,e,t){"use strict";var n=t(21119);y.exports=function(r){var o=+r;return o!==o||o===0?0:n(o)}},10188:function(y,e,t){"use strict";var n=t(61365),r=Math.min;y.exports=function(o){var a=n(o);return a>0?r(a,9007199254740991):0}},46771:function(y,e,t){"use strict";var n=t(16952),r=Object;y.exports=function(o){return r(n(o))}},56043:function(y,e,t){"use strict";var n=t(16140),r=RangeError;y.exports=function(o,a){var s=n(o);if(s%a)throw new r("Wrong offset");return s}},16140:function(y,e,t){"use strict";var n=t(61365),r=RangeError;y.exports=function(o){var a=n(o);if(a<0)throw new r("The argument can't be less than 0");return a}},24843:function(y,e,t){"use strict";var n=t(91495),r=t(77568),o=t(71399),a=t(78060),s=t(13396),u=t(24697),l=TypeError,p=u("toPrimitive");y.exports=function(f,i){if(!r(f)||o(f))return f;var d=a(f,p),c;if(d){if(i===void 0&&(i="default"),c=n(d,f,i),!r(c)||o(c))return c;throw new l("Can't convert object to primitive value")}return i===void 0&&(i="number"),s(f,i)}},767:function(y,e,t){"use strict";var n=t(24843),r=t(71399);y.exports=function(o){var a=n(o,"string");return r(a)?a:a+""}},2650:function(y,e,t){"use strict";var n=t(24697),r=n("toStringTag"),o={};o[r]="z",y.exports=String(o)==="[object z]"},12605:function(y,e,t){"use strict";var n=t(2281),r=String;y.exports=function(o){if(n(o)==="Symbol")throw new TypeError("Cannot convert a Symbol value to a string");return r(o)}},15409:function(y){"use strict";var e=Math.round;y.exports=function(t){var n=e(t);return n<0?0:n>255?255:n&255}},89393:function(y){"use strict";var e=String;y.exports=function(t){try{return e(t)}catch(n){return"Object"}}},80185:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(91495),a=t(58310),s=t(86563),u=t(4246),l=t(37336),p=t(60077),f=t(87458),i=t(37909),d=t(5841),c=t(10188),g=t(43806),v=t(56043),h=t(15409),m=t(767),E=t(45299),I=t(2281),O=t(77568),C=t(71399),S=t(80674),T=t(21287),b=t(76649),A=t(37310).f,P=t(3805),M=t(22603).forEach,w=t(58491),V=t(73936),U=t(74595),j=t(27193),G=t(78008),$=t(5419),x=t(5781),B=$.get,F=$.set,H=$.enforce,K=U.f,W=j.f,q=r.RangeError,ut=l.ArrayBuffer,ct=ut.prototype,Q=l.DataView,X=u.NATIVE_ARRAY_BUFFER_VIEWS,at=u.TYPED_ARRAY_TAG,ft=u.TypedArray,dt=u.TypedArrayPrototype,_=u.isTypedArray,rt="BYTES_PER_ELEMENT",it="Wrong length",mt=function(pt,Et){V(pt,Et,{configurable:!0,get:function(){function st(){return B(this)[Et]}return st}()})},ot=function(pt){var Et;return T(ct,pt)||(Et=I(pt))==="ArrayBuffer"||Et==="SharedArrayBuffer"},et=function(pt,Et){return _(pt)&&!C(Et)&&Et in pt&&d(+Et)&&Et>=0},k=function(){function nt(pt,Et){return Et=m(Et),et(pt,Et)?f(2,pt[Et]):W(pt,Et)}return nt}(),tt=function(){function nt(pt,Et,st){return Et=m(Et),et(pt,Et)&&O(st)&&E(st,"value")&&!E(st,"get")&&!E(st,"set")&&!st.configurable&&(!E(st,"writable")||st.writable)&&(!E(st,"enumerable")||st.enumerable)?(pt[Et]=st.value,pt):K(pt,Et,st)}return nt}();a?(X||(j.f=k,U.f=tt,mt(dt,"buffer"),mt(dt,"byteOffset"),mt(dt,"byteLength"),mt(dt,"length")),n({target:"Object",stat:!0,forced:!X},{getOwnPropertyDescriptor:k,defineProperty:tt}),y.exports=function(nt,pt,Et){var st=nt.match(/\d+/)[0]/8,yt=nt+(Et?"Clamped":"")+"Array",Pt="get"+nt,Ct="set"+nt,lt=r[yt],gt=lt,It=gt&>.prototype,Lt={},Vt=function(Tt,Nt){var Ft=B(Tt);return Ft.view[Pt](Nt*st+Ft.byteOffset,!0)},Ot=function(Tt,Nt,Ft){var jt=B(Tt);jt.view[Ct](Nt*st+jt.byteOffset,Et?h(Ft):Ft,!0)},vt=function(Tt,Nt){K(Tt,Nt,{get:function(){function Ft(){return Vt(this,Nt)}return Ft}(),set:function(){function Ft(jt){return Ot(this,Nt,jt)}return Ft}(),enumerable:!0})};X?s&&(gt=pt(function(At,Tt,Nt,Ft){return p(At,It),x(function(){return O(Tt)?ot(Tt)?Ft!==void 0?new lt(Tt,v(Nt,st),Ft):Nt!==void 0?new lt(Tt,v(Nt,st)):new lt(Tt):_(Tt)?G(gt,Tt):o(P,gt,Tt):new lt(g(Tt))}(),At,gt)}),b&&b(gt,ft),M(A(lt),function(At){At in gt||i(gt,At,lt[At])}),gt.prototype=It):(gt=pt(function(At,Tt,Nt,Ft){p(At,It);var jt=0,Ht=0,Kt,Gt,Wt;if(!O(Tt))Wt=g(Tt),Gt=Wt*st,Kt=new ut(Gt);else if(ot(Tt)){Kt=Tt,Ht=v(Nt,st);var te=Tt.byteLength;if(Ft===void 0){if(te%st)throw new q(it);if(Gt=te-Ht,Gt<0)throw new q(it)}else if(Gt=c(Ft)*st,Gt+Ht>te)throw new q(it);Wt=Gt/st}else return _(Tt)?G(gt,Tt):o(P,gt,Tt);for(F(At,{buffer:Kt,byteOffset:Ht,byteLength:Gt,length:Wt,view:new Q(Kt)});jt1?arguments[1]:void 0,I=E!==void 0,O=l(h),C,S,T,b,A,P,M,w;if(O&&!p(O))for(M=u(h,O),w=M.next,h=[];!(P=r(w,M)).done;)h.push(P.value);for(I&&m>2&&(E=n(E,arguments[2])),S=s(h),T=new(i(v))(S),b=f(T),C=0;S>C;C++)A=I?E(h[C],C):h[C],T[C]=b?d(A):+A;return T}return c}()},31082:function(y,e,t){"use strict";var n=t(4246),r=t(28987),o=n.aTypedArrayConstructor,a=n.getTypedArrayConstructor;y.exports=function(s){return o(r(s,a(s)))}},16738:function(y,e,t){"use strict";var n=t(67250),r=0,o=Math.random(),a=n(1 .toString);y.exports=function(s){return"Symbol("+(s===void 0?"":s)+")_"+a(++r+o,36)}},1062:function(y,e,t){"use strict";var n=t(52357);y.exports=n&&!Symbol.sham&&typeof Symbol.iterator=="symbol"},80944:function(y,e,t){"use strict";var n=t(58310),r=t(40033);y.exports=n&&r(function(){return Object.defineProperty(function(){},"prototype",{value:42,writable:!1}).prototype!==42})},24986:function(y){"use strict";var e=TypeError;y.exports=function(t,n){if(t=51||!r(function(){var E=[];return E[g]=!1,E.concat()[0]!==E}),h=function(I){if(!a(I))return!1;var O=I[g];return O!==void 0?!!O:o(I)},m=!v||!i("concat");n({target:"Array",proto:!0,arity:1,forced:m},{concat:function(){function E(I){var O=s(this),C=f(O,0),S=0,T,b,A,P,M;for(T=-1,A=arguments.length;T1?arguments[1]:void 0)}return s}()})},68933:function(y,e,t){"use strict";var n=t(63964),r=t(88471),o=t(80575);n({target:"Array",proto:!0},{fill:r}),o("fill")},47830:function(y,e,t){"use strict";var n=t(63964),r=t(22603).filter,o=t(44091),a=o("filter");n({target:"Array",proto:!0,forced:!a},{filter:function(){function s(u){return r(this,u,arguments.length>1?arguments[1]:void 0)}return s}()})},64094:function(y,e,t){"use strict";var n=t(63964),r=t(22603).findIndex,o=t(80575),a="findIndex",s=!0;a in[]&&Array(1)[a](function(){s=!1}),n({target:"Array",proto:!0,forced:s},{findIndex:function(){function u(l){return r(this,l,arguments.length>1?arguments[1]:void 0)}return u}()}),o(a)},13455:function(y,e,t){"use strict";var n=t(63964),r=t(22603).find,o=t(80575),a="find",s=!0;a in[]&&Array(1)[a](function(){s=!1}),n({target:"Array",proto:!0,forced:s},{find:function(){function u(l){return r(this,l,arguments.length>1?arguments[1]:void 0)}return u}()}),o(a)},32384:function(y,e,t){"use strict";var n=t(63964),r=t(65561),o=t(10320),a=t(46771),s=t(24760),u=t(57823);n({target:"Array",proto:!0},{flatMap:function(){function l(p){var f=a(this),i=s(f),d;return o(p),d=u(f,0),d.length=r(d,f,f,i,0,1,p,arguments.length>1?arguments[1]:void 0),d}return l}()})},61915:function(y,e,t){"use strict";var n=t(63964),r=t(65561),o=t(46771),a=t(24760),s=t(61365),u=t(57823);n({target:"Array",proto:!0},{flat:function(){function l(){var p=arguments.length?arguments[0]:void 0,f=o(this),i=a(f),d=u(f,0);return d.length=r(d,f,f,i,0,p===void 0?1:s(p)),d}return l}()})},25579:function(y,e,t){"use strict";var n=t(63964),r=t(35601);n({target:"Array",proto:!0,forced:[].forEach!==r},{forEach:r})},63532:function(y,e,t){"use strict";var n=t(63964),r=t(73174),o=t(92490),a=!o(function(s){Array.from(s)});n({target:"Array",stat:!0,forced:a},{from:r})},33425:function(y,e,t){"use strict";var n=t(63964),r=t(14211).includes,o=t(40033),a=t(80575),s=o(function(){return!Array(1).includes()});n({target:"Array",proto:!0,forced:s},{includes:function(){function u(l){return r(this,l,arguments.length>1?arguments[1]:void 0)}return u}()}),a("includes")},43894:function(y,e,t){"use strict";var n=t(63964),r=t(71138),o=t(14211).indexOf,a=t(55528),s=r([].indexOf),u=!!s&&1/s([1],1,-0)<0,l=u||!a("indexOf");n({target:"Array",proto:!0,forced:l},{indexOf:function(){function p(f){var i=arguments.length>1?arguments[1]:void 0;return u?s(this,f,i)||0:o(this,f,i)}return p}()})},99636:function(y,e,t){"use strict";var n=t(63964),r=t(37386);n({target:"Array",stat:!0},{isArray:r})},34570:function(y,e,t){"use strict";var n=t(57591),r=t(80575),o=t(83967),a=t(5419),s=t(74595).f,u=t(65574),l=t(5959),p=t(4493),f=t(58310),i="Array Iterator",d=a.set,c=a.getterFor(i);y.exports=u(Array,"Array",function(v,h){d(this,{type:i,target:n(v),index:0,kind:h})},function(){var v=c(this),h=v.target,m=v.index++;if(!h||m>=h.length)return v.target=void 0,l(void 0,!0);switch(v.kind){case"keys":return l(m,!1);case"values":return l(h[m],!1)}return l([m,h[m]],!1)},"values");var g=o.Arguments=o.Array;if(r("keys"),r("values"),r("entries"),!p&&f&&g.name!=="values")try{s(g,"name",{value:"values"})}catch(v){}},94432:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(37457),a=t(57591),s=t(55528),u=r([].join),l=o!==Object,p=l||!s("join",",");n({target:"Array",proto:!0,forced:p},{join:function(){function f(i){return u(a(this),i===void 0?",":i)}return f}()})},24683:function(y,e,t){"use strict";var n=t(63964),r=t(1325);n({target:"Array",proto:!0,forced:r!==[].lastIndexOf},{lastIndexOf:r})},69984:function(y,e,t){"use strict";var n=t(63964),r=t(22603).map,o=t(44091),a=o("map");n({target:"Array",proto:!0,forced:!a},{map:function(){function s(u){return r(this,u,arguments.length>1?arguments[1]:void 0)}return s}()})},32089:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(1031),a=t(60102),s=Array,u=r(function(){function l(){}return!(s.of.call(l)instanceof l)});n({target:"Array",stat:!0,forced:u},{of:function(){function l(){for(var p=0,f=arguments.length,i=new(o(this)?this:s)(f);f>p;)a(i,p,arguments[p++]);return i.length=f,i}return l}()})},29645:function(y,e,t){"use strict";var n=t(63964),r=t(56844).right,o=t(55528),a=t(5026),s=t(81702),u=!s&&a>79&&a<83,l=u||!o("reduceRight");n({target:"Array",proto:!0,forced:l},{reduceRight:function(){function p(f){return r(this,f,arguments.length,arguments.length>1?arguments[1]:void 0)}return p}()})},60206:function(y,e,t){"use strict";var n=t(63964),r=t(56844).left,o=t(55528),a=t(5026),s=t(81702),u=!s&&a>79&&a<83,l=u||!o("reduce");n({target:"Array",proto:!0,forced:l},{reduce:function(){function p(f){var i=arguments.length;return r(this,f,i,i>1?arguments[1]:void 0)}return p}()})},4788:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(37386),a=r([].reverse),s=[1,2];n({target:"Array",proto:!0,forced:String(s)===String(s.reverse())},{reverse:function(){function u(){return o(this)&&(this.length=this.length),a(this)}return u}()})},58672:function(y,e,t){"use strict";var n=t(63964),r=t(37386),o=t(1031),a=t(77568),s=t(13912),u=t(24760),l=t(57591),p=t(60102),f=t(24697),i=t(44091),d=t(54602),c=i("slice"),g=f("species"),v=Array,h=Math.max;n({target:"Array",proto:!0,forced:!c},{slice:function(){function m(E,I){var O=l(this),C=u(O),S=s(E,C),T=s(I===void 0?C:I,C),b,A,P;if(r(O)&&(b=O.constructor,o(b)&&(b===v||r(b.prototype))?b=void 0:a(b)&&(b=b[g],b===null&&(b=void 0)),b===v||b===void 0))return d(O,S,T);for(A=new(b===void 0?v:b)(h(T-S,0)),P=0;S1?arguments[1]:void 0)}return s}()})},48968:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(10320),a=t(46771),s=t(24760),u=t(95108),l=t(12605),p=t(40033),f=t(90274),i=t(55528),d=t(652),c=t(19228),g=t(5026),v=t(9342),h=[],m=r(h.sort),E=r(h.push),I=p(function(){h.sort(void 0)}),O=p(function(){h.sort(null)}),C=i("sort"),S=!p(function(){if(g)return g<70;if(!(d&&d>3)){if(c)return!0;if(v)return v<603;var A="",P,M,w,V;for(P=65;P<76;P++){switch(M=String.fromCharCode(P),P){case 66:case 69:case 70:case 72:w=3;break;case 68:case 71:w=4;break;default:w=2}for(V=0;V<47;V++)h.push({k:M+V,v:w})}for(h.sort(function(U,j){return j.v-U.v}),V=0;Vl(w)?1:-1}};n({target:"Array",proto:!0,forced:T},{sort:function(){function A(P){P!==void 0&&o(P);var M=a(this);if(S)return P===void 0?m(M):m(M,P);var w=[],V=s(M),U,j;for(j=0;jO-b+T;P--)i(I,P-1)}else if(T>b)for(P=O-b;P>C;P--)M=P+b-1,w=P+T-1,M in I?I[w]=I[M]:i(I,w);for(P=0;P9490626562425156e-8?a(i)+u:r(i-1+s(i-1)*s(i+1))}return p}()})},59660:function(y,e,t){"use strict";var n=t(63964),r=Math.asinh,o=Math.log,a=Math.sqrt;function s(l){var p=+l;return!isFinite(p)||p===0?p:p<0?-s(-p):o(p+a(p*p+1))}var u=!(r&&1/r(0)>0);n({target:"Math",stat:!0,forced:u},{asinh:s})},15383:function(y,e,t){"use strict";var n=t(63964),r=Math.atanh,o=Math.log,a=!(r&&1/r(-0)<0);n({target:"Math",stat:!0,forced:a},{atanh:function(){function s(u){var l=+u;return l===0?l:o((1+l)/(1-l))/2}return s}()})},92866:function(y,e,t){"use strict";var n=t(63964),r=t(22172),o=Math.abs,a=Math.pow;n({target:"Math",stat:!0},{cbrt:function(){function s(u){var l=+u;return r(l)*a(o(l),.3333333333333333)}return s}()})},86107:function(y,e,t){"use strict";var n=t(63964),r=Math.floor,o=Math.log,a=Math.LOG2E;n({target:"Math",stat:!0},{clz32:function(){function s(u){var l=u>>>0;return l?31-r(o(l+.5)*a):32}return s}()})},29248:function(y,e,t){"use strict";var n=t(63964),r=t(82040),o=Math.cosh,a=Math.abs,s=Math.E,u=!o||o(710)===1/0;n({target:"Math",stat:!0,forced:u},{cosh:function(){function l(p){var f=r(a(p)-1)+1;return(f+1/(f*s*s))*(s/2)}return l}()})},52540:function(y,e,t){"use strict";var n=t(63964),r=t(82040);n({target:"Math",stat:!0,forced:r!==Math.expm1},{expm1:r})},79007:function(y,e,t){"use strict";var n=t(63964),r=t(95867);n({target:"Math",stat:!0},{fround:r})},77199:function(y,e,t){"use strict";var n=t(63964),r=Math.hypot,o=Math.abs,a=Math.sqrt,s=!!r&&r(1/0,NaN)!==1/0;n({target:"Math",stat:!0,arity:2,forced:s},{hypot:function(){function u(l,p){for(var f=0,i=0,d=arguments.length,c=0,g,v;i0?(v=g/c,f+=v*v):f+=g;return c===1/0?1/0:c*a(f)}return u}()})},6522:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=Math.imul,a=r(function(){return o(4294967295,5)!==-5||o.length!==2});n({target:"Math",stat:!0,forced:a},{imul:function(){function s(u,l){var p=65535,f=+u,i=+l,d=p&f,c=p&i;return 0|d*c+((p&f>>>16)*c+d*(p&i>>>16)<<16>>>0)}return s}()})},95542:function(y,e,t){"use strict";var n=t(63964),r=t(75002);n({target:"Math",stat:!0},{log10:r})},2966:function(y,e,t){"use strict";var n=t(63964),r=t(90874);n({target:"Math",stat:!0},{log1p:r})},20997:function(y,e,t){"use strict";var n=t(63964),r=Math.log,o=Math.LN2;n({target:"Math",stat:!0},{log2:function(){function a(s){return r(s)/o}return a}()})},57400:function(y,e,t){"use strict";var n=t(63964),r=t(22172);n({target:"Math",stat:!0},{sign:r})},45571:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(82040),a=Math.abs,s=Math.exp,u=Math.E,l=r(function(){return Math.sinh(-2e-17)!==-2e-17});n({target:"Math",stat:!0,forced:l},{sinh:function(){function p(f){var i=+f;return a(i)<1?(o(i)-o(-i))/2:(s(i-1)-s(-i-1))*(u/2)}return p}()})},54800:function(y,e,t){"use strict";var n=t(63964),r=t(82040),o=Math.exp;n({target:"Math",stat:!0},{tanh:function(){function a(s){var u=+s,l=r(u),p=r(-u);return l===1/0?1:p===1/0?-1:(l-p)/(o(u)+o(-u))}return a}()})},15709:function(y,e,t){"use strict";var n=t(84925);n(Math,"Math",!0)},76059:function(y,e,t){"use strict";var n=t(63964),r=t(21119);n({target:"Math",stat:!0},{trunc:r})},96614:function(y,e,t){"use strict";var n=t(63964),r=t(4493),o=t(58310),a=t(74685),s=t(61765),u=t(67250),l=t(41314),p=t(45299),f=t(5781),i=t(21287),d=t(71399),c=t(24843),g=t(40033),v=t(37310).f,h=t(27193).f,m=t(74595).f,E=t(46438),I=t(92648).trim,O="Number",C=a[O],S=s[O],T=C.prototype,b=a.TypeError,A=u("".slice),P=u("".charCodeAt),M=function(x){var B=c(x,"number");return typeof B=="bigint"?B:w(B)},w=function(x){var B=c(x,"number"),F,H,K,W,q,ut,ct,Q;if(d(B))throw new b("Cannot convert a Symbol value to a number");if(typeof B=="string"&&B.length>2){if(B=I(B),F=P(B,0),F===43||F===45){if(H=P(B,2),H===88||H===120)return NaN}else if(F===48){switch(P(B,1)){case 66:case 98:K=2,W=49;break;case 79:case 111:K=8,W=55;break;default:return+B}for(q=A(B,2),ut=q.length,ct=0;ctW)return NaN;return parseInt(q,K)}}return+B},V=l(O,!C(" 0o1")||!C("0b1")||C("+0x1")),U=function(x){return i(T,x)&&g(function(){E(x)})},j=function(){function $(x){var B=arguments.length<1?0:C(M(x));return U(this)?f(Object(B),this,j):B}return $}();j.prototype=T,V&&!r&&(T.constructor=j),n({global:!0,constructor:!0,wrap:!0,forced:V},{Number:j});var G=function(x,B){for(var F=o?v(B):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,isFinite,isInteger,isNaN,isSafeInteger,parseFloat,parseInt,fromString,range".split(","),H=0,K;F.length>H;H++)p(B,K=F[H])&&!p(x,K)&&m(x,K,h(B,K))};r&&S&&G(s[O],S),(V||r)&&G(s[O],C)},324:function(y,e,t){"use strict";var n=t(63964);n({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{EPSILON:Math.pow(2,-52)})},90426:function(y,e,t){"use strict";var n=t(63964),r=t(3294);n({target:"Number",stat:!0},{isFinite:r})},95443:function(y,e,t){"use strict";var n=t(63964),r=t(5841);n({target:"Number",stat:!0},{isInteger:r})},87968:function(y,e,t){"use strict";var n=t(63964);n({target:"Number",stat:!0},{isNaN:function(){function r(o){return o!==o}return r}()})},55007:function(y,e,t){"use strict";var n=t(63964),r=t(5841),o=Math.abs;n({target:"Number",stat:!0},{isSafeInteger:function(){function a(s){return r(s)&&o(s)<=9007199254740991}return a}()})},55323:function(y,e,t){"use strict";var n=t(63964);n({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{MAX_SAFE_INTEGER:9007199254740991})},13521:function(y,e,t){"use strict";var n=t(63964);n({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{MIN_SAFE_INTEGER:-9007199254740991})},5006:function(y,e,t){"use strict";var n=t(63964),r=t(28506);n({target:"Number",stat:!0,forced:Number.parseFloat!==r},{parseFloat:r})},99009:function(y,e,t){"use strict";var n=t(63964),r=t(13693);n({target:"Number",stat:!0,forced:Number.parseInt!==r},{parseInt:r})},85770:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(61365),a=t(46438),s=t(62443),u=t(40033),l=RangeError,p=String,f=Math.floor,i=r(s),d=r("".slice),c=r(1 .toFixed),g=function O(C,S,T){return S===0?T:S%2===1?O(C,S-1,T*C):O(C*C,S/2,T)},v=function(C){for(var S=0,T=C;T>=4096;)S+=12,T/=4096;for(;T>=2;)S+=1,T/=2;return S},h=function(C,S,T){for(var b=-1,A=T;++b<6;)A+=S*C[b],C[b]=A%1e7,A=f(A/1e7)},m=function(C,S){for(var T=6,b=0;--T>=0;)b+=C[T],C[T]=f(b/S),b=b%S*1e7},E=function(C){for(var S=6,T="";--S>=0;)if(T!==""||S===0||C[S]!==0){var b=p(C[S]);T=T===""?b:T+i("0",7-b.length)+b}return T},I=u(function(){return c(8e-5,3)!=="0.000"||c(.9,0)!=="1"||c(1.255,2)!=="1.25"||c(0xde0b6b3a7640080,0)!=="1000000000000000128"})||!u(function(){c({})});n({target:"Number",proto:!0,forced:I},{toFixed:function(){function O(C){var S=a(this),T=o(C),b=[0,0,0,0,0,0],A="",P="0",M,w,V,U;if(T<0||T>20)throw new l("Incorrect fraction digits");if(S!==S)return"NaN";if(S<=-1e21||S>=1e21)return p(S);if(S<0&&(A="-",S=-S),S>1e-21)if(M=v(S*g(2,69,1))-69,w=M<0?S*g(2,-M,1):S/g(2,M,1),w*=4503599627370496,M=52-M,M>0){for(h(b,0,w),V=T;V>=7;)h(b,1e7,0),V-=7;for(h(b,g(10,V,1),0),V=M-1;V>=23;)m(b,8388608),V-=23;m(b,1<0?(U=P.length,P=A+(U<=T?"0."+i("0",T-U)+P:d(P,0,U-T)+"."+d(P,U-T))):P=A+P,P}return O}()})},23532:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(40033),a=t(46438),s=r(1 .toPrecision),u=o(function(){return s(1,void 0)!=="1"})||!o(function(){s({})});n({target:"Number",proto:!0,forced:u},{toPrecision:function(){function l(p){return p===void 0?s(a(this)):s(a(this),p)}return l}()})},87119:function(y,e,t){"use strict";var n=t(63964),r=t(41143);n({target:"Object",stat:!0,arity:2,forced:Object.assign!==r},{assign:r})},78618:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(80674);n({target:"Object",stat:!0,sham:!r},{create:o})},27129:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(57377),a=t(10320),s=t(46771),u=t(74595);r&&n({target:"Object",proto:!0,forced:o},{__defineGetter__:function(){function l(p,f){u.f(s(this),p,{get:a(f),enumerable:!0,configurable:!0})}return l}()})},31943:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(24239).f;n({target:"Object",stat:!0,forced:Object.defineProperties!==o,sham:!r},{defineProperties:o})},3579:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(74595).f;n({target:"Object",stat:!0,forced:Object.defineProperty!==o,sham:!r},{defineProperty:o})},97397:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(57377),a=t(10320),s=t(46771),u=t(74595);r&&n({target:"Object",proto:!0,forced:o},{__defineSetter__:function(){function l(p,f){u.f(s(this),p,{set:a(f),enumerable:!0,configurable:!0})}return l}()})},85028:function(y,e,t){"use strict";var n=t(63964),r=t(70915).entries;n({target:"Object",stat:!0},{entries:function(){function o(a){return r(a)}return o}()})},8225:function(y,e,t){"use strict";var n=t(63964),r=t(50730),o=t(40033),a=t(77568),s=t(81969).onFreeze,u=Object.freeze,l=o(function(){u(1)});n({target:"Object",stat:!0,forced:l,sham:!r},{freeze:function(){function p(f){return u&&a(f)?u(s(f)):f}return p}()})},43331:function(y,e,t){"use strict";var n=t(63964),r=t(49450),o=t(60102);n({target:"Object",stat:!0},{fromEntries:function(){function a(s){var u={};return r(s,function(l,p){o(u,l,p)},{AS_ENTRIES:!0}),u}return a}()})},62289:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(57591),a=t(27193).f,s=t(58310),u=!s||r(function(){a(1)});n({target:"Object",stat:!0,forced:u,sham:!s},{getOwnPropertyDescriptor:function(){function l(p,f){return a(o(p),f)}return l}()})},56196:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(97921),a=t(57591),s=t(27193),u=t(60102);n({target:"Object",stat:!0,sham:!r},{getOwnPropertyDescriptors:function(){function l(p){for(var f=a(p),i=s.f,d=o(f),c={},g=0,v,h;d.length>g;)h=i(f,v=d[g++]),h!==void 0&&u(c,v,h);return c}return l}()})},2950:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(81644).f,a=r(function(){return!Object.getOwnPropertyNames(1)});n({target:"Object",stat:!0,forced:a},{getOwnPropertyNames:o})},28603:function(y,e,t){"use strict";var n=t(63964),r=t(52357),o=t(40033),a=t(89235),s=t(46771),u=!r||o(function(){a.f(1)});n({target:"Object",stat:!0,forced:u},{getOwnPropertySymbols:function(){function l(p){var f=a.f;return f?f(s(p)):[]}return l}()})},44205:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(46771),a=t(36917),s=t(9225),u=r(function(){a(1)});n({target:"Object",stat:!0,forced:u,sham:!s},{getPrototypeOf:function(){function l(p){return a(o(p))}return l}()})},83186:function(y,e,t){"use strict";var n=t(63964),r=t(81834);n({target:"Object",stat:!0,forced:Object.isExtensible!==r},{isExtensible:r})},76065:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(77568),a=t(7462),s=t(3782),u=Object.isFrozen,l=s||r(function(){u(1)});n({target:"Object",stat:!0,forced:l},{isFrozen:function(){function p(f){return!o(f)||s&&a(f)==="ArrayBuffer"?!0:u?u(f):!1}return p}()})},13411:function(y,e,t){"use strict";var n=t(63964),r=t(40033),o=t(77568),a=t(7462),s=t(3782),u=Object.isSealed,l=s||r(function(){u(1)});n({target:"Object",stat:!0,forced:l},{isSealed:function(){function p(f){return!o(f)||s&&a(f)==="ArrayBuffer"?!0:u?u(f):!1}return p}()})},76882:function(y,e,t){"use strict";var n=t(63964),r=t(5700);n({target:"Object",stat:!0},{is:r})},26634:function(y,e,t){"use strict";var n=t(63964),r=t(46771),o=t(18450),a=t(40033),s=a(function(){o(1)});n({target:"Object",stat:!0,forced:s},{keys:function(){function u(l){return o(r(l))}return u}()})},53118:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(57377),a=t(46771),s=t(767),u=t(36917),l=t(27193).f;r&&n({target:"Object",proto:!0,forced:o},{__lookupGetter__:function(){function p(f){var i=a(this),d=s(f),c;do if(c=l(i,d))return c.get;while(i=u(i))}return p}()})},42514:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(57377),a=t(46771),s=t(767),u=t(36917),l=t(27193).f;r&&n({target:"Object",proto:!0,forced:o},{__lookupSetter__:function(){function p(f){var i=a(this),d=s(f),c;do if(c=l(i,d))return c.set;while(i=u(i))}return p}()})},84353:function(y,e,t){"use strict";var n=t(63964),r=t(77568),o=t(81969).onFreeze,a=t(50730),s=t(40033),u=Object.preventExtensions,l=s(function(){u(1)});n({target:"Object",stat:!0,forced:l,sham:!a},{preventExtensions:function(){function p(f){return u&&r(f)?u(o(f)):f}return p}()})},62987:function(y,e,t){"use strict";var n=t(63964),r=t(77568),o=t(81969).onFreeze,a=t(50730),s=t(40033),u=Object.seal,l=s(function(){u(1)});n({target:"Object",stat:!0,forced:l,sham:!a},{seal:function(){function p(f){return u&&r(f)?u(o(f)):f}return p}()})},48993:function(y,e,t){"use strict";var n=t(63964),r=t(76649);n({target:"Object",stat:!0},{setPrototypeOf:r})},52917:function(y,e,t){"use strict";var n=t(2650),r=t(55938),o=t(2509);n||r(Object.prototype,"toString",o,{unsafe:!0})},4972:function(y,e,t){"use strict";var n=t(63964),r=t(70915).values;n({target:"Object",stat:!0},{values:function(){function o(a){return r(a)}return o}()})},28913:function(y,e,t){"use strict";var n=t(63964),r=t(28506);n({global:!0,forced:parseFloat!==r},{parseFloat:r})},36382:function(y,e,t){"use strict";var n=t(63964),r=t(13693);n({global:!0,forced:parseInt!==r},{parseInt:r})},48865:function(y,e,t){"use strict";var n=t(63964),r=t(91495),o=t(10320),a=t(81837),s=t(10729),u=t(49450),l=t(48199);n({target:"Promise",stat:!0,forced:l},{all:function(){function p(f){var i=this,d=a.f(i),c=d.resolve,g=d.reject,v=s(function(){var h=o(i.resolve),m=[],E=0,I=1;u(f,function(O){var C=E++,S=!1;I++,r(h,i,O).then(function(T){S||(S=!0,m[C]=T,--I||c(m))},g)}),--I||c(m)});return v.error&&g(v.value),d.promise}return p}()})},70641:function(y,e,t){"use strict";var n=t(63964),r=t(4493),o=t(74854).CONSTRUCTOR,a=t(67512),s=t(4009),u=t(55747),l=t(55938),p=a&&a.prototype;if(n({target:"Promise",proto:!0,forced:o,real:!0},{catch:function(){function i(d){return this.then(void 0,d)}return i}()}),!r&&u(a)){var f=s("Promise").prototype.catch;p.catch!==f&&l(p,"catch",f,{unsafe:!0})}},75946:function(y,e,t){"use strict";var n=t(63964),r=t(4493),o=t(81702),a=t(74685),s=t(91495),u=t(55938),l=t(76649),p=t(84925),f=t(58491),i=t(10320),d=t(55747),c=t(77568),g=t(60077),v=t(28987),h=t(60375).set,m=t(37713),E=t(72259),I=t(10729),O=t(9547),C=t(5419),S=t(67512),T=t(74854),b=t(81837),A="Promise",P=T.CONSTRUCTOR,M=T.REJECTION_EVENT,w=T.SUBCLASSING,V=C.getterFor(A),U=C.set,j=S&&S.prototype,G=S,$=j,x=a.TypeError,B=a.document,F=a.process,H=b.f,K=H,W=!!(B&&B.createEvent&&a.dispatchEvent),q="unhandledrejection",ut="rejectionhandled",ct=0,Q=1,X=2,at=1,ft=2,dt,_,rt,it,mt=function(Ct){var lt;return c(Ct)&&d(lt=Ct.then)?lt:!1},ot=function(Ct,lt){var gt=lt.value,It=lt.state===Q,Lt=It?Ct.ok:Ct.fail,Vt=Ct.resolve,Ot=Ct.reject,vt=Ct.domain,St,At,Tt;try{Lt?(It||(lt.rejection===ft&&pt(lt),lt.rejection=at),Lt===!0?St=gt:(vt&&vt.enter(),St=Lt(gt),vt&&(vt.exit(),Tt=!0)),St===Ct.promise?Ot(new x("Promise-chain cycle")):(At=mt(St))?s(At,St,Vt,Ot):Vt(St)):Ot(gt)}catch(Nt){vt&&!Tt&&vt.exit(),Ot(Nt)}},et=function(Ct,lt){Ct.notified||(Ct.notified=!0,m(function(){for(var gt=Ct.reactions,It;It=gt.get();)ot(It,Ct);Ct.notified=!1,lt&&!Ct.rejection&&tt(Ct)}))},k=function(Ct,lt,gt){var It,Lt;W?(It=B.createEvent("Event"),It.promise=lt,It.reason=gt,It.initEvent(Ct,!1,!0),a.dispatchEvent(It)):It={promise:lt,reason:gt},!M&&(Lt=a["on"+Ct])?Lt(It):Ct===q&&E("Unhandled promise rejection",gt)},tt=function(Ct){s(h,a,function(){var lt=Ct.facade,gt=Ct.value,It=nt(Ct),Lt;if(It&&(Lt=I(function(){o?F.emit("unhandledRejection",gt,lt):k(q,lt,gt)}),Ct.rejection=o||nt(Ct)?ft:at,Lt.error))throw Lt.value})},nt=function(Ct){return Ct.rejection!==at&&!Ct.parent},pt=function(Ct){s(h,a,function(){var lt=Ct.facade;o?F.emit("rejectionHandled",lt):k(ut,lt,Ct.value)})},Et=function(Ct,lt,gt){return function(It){Ct(lt,It,gt)}},st=function(Ct,lt,gt){Ct.done||(Ct.done=!0,gt&&(Ct=gt),Ct.value=lt,Ct.state=X,et(Ct,!0))},yt=function Pt(Ct,lt,gt){if(!Ct.done){Ct.done=!0,gt&&(Ct=gt);try{if(Ct.facade===lt)throw new x("Promise can't be resolved itself");var It=mt(lt);It?m(function(){var Lt={done:!1};try{s(It,lt,Et(Pt,Lt,Ct),Et(st,Lt,Ct))}catch(Vt){st(Lt,Vt,Ct)}}):(Ct.value=lt,Ct.state=Q,et(Ct,!1))}catch(Lt){st({done:!1},Lt,Ct)}}};if(P&&(G=function(){function Pt(Ct){g(this,$),i(Ct),s(dt,this);var lt=V(this);try{Ct(Et(yt,lt),Et(st,lt))}catch(gt){st(lt,gt)}}return Pt}(),$=G.prototype,dt=function(){function Pt(Ct){U(this,{type:A,done:!1,notified:!1,parent:!1,reactions:new O,rejection:!1,state:ct,value:void 0})}return Pt}(),dt.prototype=u($,"then",function(){function Pt(Ct,lt){var gt=V(this),It=H(v(this,G));return gt.parent=!0,It.ok=d(Ct)?Ct:!0,It.fail=d(lt)&<,It.domain=o?F.domain:void 0,gt.state===ct?gt.reactions.add(It):m(function(){ot(It,gt)}),It.promise}return Pt}()),_=function(){var Ct=new dt,lt=V(Ct);this.promise=Ct,this.resolve=Et(yt,lt),this.reject=Et(st,lt)},b.f=H=function(Ct){return Ct===G||Ct===rt?new _(Ct):K(Ct)},!r&&d(S)&&j!==Object.prototype)){it=j.then,w||u(j,"then",function(){function Pt(Ct,lt){var gt=this;return new G(function(It,Lt){s(it,gt,It,Lt)}).then(Ct,lt)}return Pt}(),{unsafe:!0});try{delete j.constructor}catch(Pt){}l&&l(j,$)}n({global:!0,constructor:!0,wrap:!0,forced:P},{Promise:G}),p(G,A,!1,!0),f(A)},69861:function(y,e,t){"use strict";var n=t(63964),r=t(4493),o=t(67512),a=t(40033),s=t(4009),u=t(55747),l=t(28987),p=t(66628),f=t(55938),i=o&&o.prototype,d=!!o&&a(function(){i.finally.call({then:function(){function g(){}return g}()},function(){})});if(n({target:"Promise",proto:!0,real:!0,forced:d},{finally:function(){function g(v){var h=l(this,s("Promise")),m=u(v);return this.then(m?function(E){return p(h,v()).then(function(){return E})}:v,m?function(E){return p(h,v()).then(function(){throw E})}:v)}return g}()}),!r&&u(o)){var c=s("Promise").prototype.finally;i.finally!==c&&f(i,"finally",c,{unsafe:!0})}},53092:function(y,e,t){"use strict";t(75946),t(48865),t(70641),t(16937),t(41719),t(59321)},16937:function(y,e,t){"use strict";var n=t(63964),r=t(91495),o=t(10320),a=t(81837),s=t(10729),u=t(49450),l=t(48199);n({target:"Promise",stat:!0,forced:l},{race:function(){function p(f){var i=this,d=a.f(i),c=d.reject,g=s(function(){var v=o(i.resolve);u(f,function(h){r(v,i,h).then(d.resolve,c)})});return g.error&&c(g.value),d.promise}return p}()})},41719:function(y,e,t){"use strict";var n=t(63964),r=t(81837),o=t(74854).CONSTRUCTOR;n({target:"Promise",stat:!0,forced:o},{reject:function(){function a(s){var u=r.f(this),l=u.reject;return l(s),u.promise}return a}()})},59321:function(y,e,t){"use strict";var n=t(63964),r=t(4009),o=t(4493),a=t(67512),s=t(74854).CONSTRUCTOR,u=t(66628),l=r("Promise"),p=o&&!s;n({target:"Promise",stat:!0,forced:o||s},{resolve:function(){function f(i){return u(p&&this===l?a:this,i)}return f}()})},29674:function(y,e,t){"use strict";var n=t(63964),r=t(61267),o=t(10320),a=t(30365),s=t(40033),u=!s(function(){Reflect.apply(function(){})});n({target:"Reflect",stat:!0,forced:u},{apply:function(){function l(p,f,i){return r(o(p),f,a(i))}return l}()})},81543:function(y,e,t){"use strict";var n=t(63964),r=t(4009),o=t(61267),a=t(66284),s=t(32606),u=t(30365),l=t(77568),p=t(80674),f=t(40033),i=r("Reflect","construct"),d=Object.prototype,c=[].push,g=f(function(){function m(){}return!(i(function(){},[],m)instanceof m)}),v=!f(function(){i(function(){})}),h=g||v;n({target:"Reflect",stat:!0,forced:h,sham:h},{construct:function(){function m(E,I){s(E),u(I);var O=arguments.length<3?E:s(arguments[2]);if(v&&!g)return i(E,I,O);if(E===O){switch(I.length){case 0:return new E;case 1:return new E(I[0]);case 2:return new E(I[0],I[1]);case 3:return new E(I[0],I[1],I[2]);case 4:return new E(I[0],I[1],I[2],I[3])}var C=[null];return o(c,C,I),new(o(a,E,C))}var S=O.prototype,T=p(l(S)?S:d),b=o(E,T,I);return l(b)?b:T}return m}()})},9373:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(30365),a=t(767),s=t(74595),u=t(40033),l=u(function(){Reflect.defineProperty(s.f({},1,{value:1}),1,{value:2})});n({target:"Reflect",stat:!0,forced:l,sham:!r},{defineProperty:function(){function p(f,i,d){o(f);var c=a(i);o(d);try{return s.f(f,c,d),!0}catch(g){return!1}}return p}()})},45093:function(y,e,t){"use strict";var n=t(63964),r=t(30365),o=t(27193).f;n({target:"Reflect",stat:!0},{deleteProperty:function(){function a(s,u){var l=o(r(s),u);return l&&!l.configurable?!1:delete s[u]}return a}()})},5815:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(30365),a=t(27193);n({target:"Reflect",stat:!0,sham:!r},{getOwnPropertyDescriptor:function(){function s(u,l){return a.f(o(u),l)}return s}()})},88527:function(y,e,t){"use strict";var n=t(63964),r=t(30365),o=t(36917),a=t(9225);n({target:"Reflect",stat:!0,sham:!a},{getPrototypeOf:function(){function s(u){return o(r(u))}return s}()})},63074:function(y,e,t){"use strict";var n=t(63964),r=t(91495),o=t(77568),a=t(30365),s=t(98373),u=t(27193),l=t(36917);function p(f,i){var d=arguments.length<3?f:arguments[2],c,g;if(a(f)===d)return f[i];if(c=u.f(f,i),c)return s(c)?c.value:c.get===void 0?void 0:r(c.get,d);if(o(g=l(f)))return p(g,i,d)}n({target:"Reflect",stat:!0},{get:p})},66390:function(y,e,t){"use strict";var n=t(63964);n({target:"Reflect",stat:!0},{has:function(){function r(o,a){return a in o}return r}()})},7784:function(y,e,t){"use strict";var n=t(63964),r=t(30365),o=t(81834);n({target:"Reflect",stat:!0},{isExtensible:function(){function a(s){return r(s),o(s)}return a}()})},50551:function(y,e,t){"use strict";var n=t(63964),r=t(97921);n({target:"Reflect",stat:!0},{ownKeys:r})},76483:function(y,e,t){"use strict";var n=t(63964),r=t(4009),o=t(30365),a=t(50730);n({target:"Reflect",stat:!0,sham:!a},{preventExtensions:function(){function s(u){o(u);try{var l=r("Object","preventExtensions");return l&&l(u),!0}catch(p){return!1}}return s}()})},63915:function(y,e,t){"use strict";var n=t(63964),r=t(30365),o=t(35908),a=t(76649);a&&n({target:"Reflect",stat:!0},{setPrototypeOf:function(){function s(u,l){r(u),o(l);try{return a(u,l),!0}catch(p){return!1}}return s}()})},92046:function(y,e,t){"use strict";var n=t(63964),r=t(91495),o=t(30365),a=t(77568),s=t(98373),u=t(40033),l=t(74595),p=t(27193),f=t(36917),i=t(87458);function d(g,v,h){var m=arguments.length<4?g:arguments[3],E=p.f(o(g),v),I,O,C;if(!E){if(a(O=f(g)))return d(O,v,h,m);E=i(0)}if(s(E)){if(E.writable===!1||!a(m))return!1;if(I=p.f(m,v)){if(I.get||I.set||I.writable===!1)return!1;I.value=h,l.f(m,v,I)}else l.f(m,v,i(0,h))}else{if(C=E.set,C===void 0)return!1;r(C,m,h)}return!0}var c=u(function(){var g=function(){},v=l.f(new g,"a",{configurable:!0});return Reflect.set(g.prototype,"a",1,v)!==!1});n({target:"Reflect",stat:!0,forced:c},{set:d})},51454:function(y,e,t){"use strict";var n=t(58310),r=t(74685),o=t(67250),a=t(41314),s=t(5781),u=t(37909),l=t(80674),p=t(37310).f,f=t(21287),i=t(72586),d=t(12605),c=t(73392),g=t(62115),v=t(34550),h=t(55938),m=t(40033),E=t(45299),I=t(5419).enforce,O=t(58491),C=t(24697),S=t(39173),T=t(35688),b=C("match"),A=r.RegExp,P=A.prototype,M=r.SyntaxError,w=o(P.exec),V=o("".charAt),U=o("".replace),j=o("".indexOf),G=o("".slice),$=/^\?<[^\s\d!#%&*+<=>@^][^\s!#%&*+<=>@^]*>/,x=/a/g,B=/a/g,F=new A(x)!==x,H=g.MISSED_STICKY,K=g.UNSUPPORTED_Y,W=n&&(!F||H||S||T||m(function(){return B[b]=!1,A(x)!==x||A(B)===B||String(A(x,"i"))!=="/a/i"})),q=function(ft){for(var dt=ft.length,_=0,rt="",it=!1,mt;_<=dt;_++){if(mt=V(ft,_),mt==="\\"){rt+=mt+V(ft,++_);continue}!it&&mt==="."?rt+="[\\s\\S]":(mt==="["?it=!0:mt==="]"&&(it=!1),rt+=mt)}return rt},ut=function(ft){for(var dt=ft.length,_=0,rt="",it=[],mt=l(null),ot=!1,et=!1,k=0,tt="",nt;_<=dt;_++){if(nt=V(ft,_),nt==="\\")nt+=V(ft,++_);else if(nt==="]")ot=!1;else if(!ot)switch(!0){case nt==="[":ot=!0;break;case nt==="(":w($,G(ft,_+1))&&(_+=2,et=!0),rt+=nt,k++;continue;case(nt===">"&&et):if(tt===""||E(mt,tt))throw new M("Invalid capture group name");mt[tt]=!0,it[it.length]=[tt,k],et=!1,tt="";continue}et?tt+=nt:rt+=nt}return[rt,it]};if(a("RegExp",W)){for(var ct=function(){function at(ft,dt){var _=f(P,this),rt=i(ft),it=dt===void 0,mt=[],ot=ft,et,k,tt,nt,pt,Et;if(!_&&rt&&it&&ft.constructor===ct)return ft;if((rt||f(P,ft))&&(ft=ft.source,it&&(dt=c(ot))),ft=ft===void 0?"":d(ft),dt=dt===void 0?"":d(dt),ot=ft,S&&"dotAll"in x&&(k=!!dt&&j(dt,"s")>-1,k&&(dt=U(dt,/s/g,""))),et=dt,H&&"sticky"in x&&(tt=!!dt&&j(dt,"y")>-1,tt&&K&&(dt=U(dt,/y/g,""))),T&&(nt=ut(ft),ft=nt[0],mt=nt[1]),pt=s(A(ft,dt),_?this:P,ct),(k||tt||mt.length)&&(Et=I(pt),k&&(Et.dotAll=!0,Et.raw=ct(q(ft),et)),tt&&(Et.sticky=!0),mt.length&&(Et.groups=mt)),ft!==ot)try{u(pt,"source",ot===""?"(?:)":ot)}catch(st){}return pt}return at}(),Q=p(A),X=0;Q.length>X;)v(ct,A,Q[X++]);P.constructor=ct,ct.prototype=P,h(r,"RegExp",ct,{constructor:!0})}O("RegExp")},79669:function(y,e,t){"use strict";var n=t(63964),r=t(14489);n({target:"RegExp",proto:!0,forced:/./.exec!==r},{exec:r})},23057:function(y,e,t){"use strict";var n=t(74685),r=t(58310),o=t(73936),a=t(70901),s=t(40033),u=n.RegExp,l=u.prototype,p=r&&s(function(){var f=!0;try{u(".","d")}catch(E){f=!1}var i={},d="",c=f?"dgimsy":"gimsy",g=function(I,O){Object.defineProperty(i,I,{get:function(){function C(){return d+=O,!0}return C}()})},v={dotAll:"s",global:"g",ignoreCase:"i",multiline:"m",sticky:"y"};f&&(v.hasIndices="d");for(var h in v)g(h,v[h]);var m=Object.getOwnPropertyDescriptor(l,"flags").get.call(i);return m!==c||d!==c});p&&o(l,"flags",{configurable:!0,get:a})},57983:function(y,e,t){"use strict";var n=t(70520).PROPER,r=t(55938),o=t(30365),a=t(12605),s=t(40033),u=t(73392),l="toString",p=RegExp.prototype,f=p[l],i=s(function(){return f.call({source:"a",flags:"b"})!=="/a/b"}),d=n&&f.name!==l;(i||d)&&r(p,l,function(){function c(){var g=o(this),v=a(g.source),h=a(u(g));return"/"+v+"/"+h}return c}(),{unsafe:!0})},1963:function(y,e,t){"use strict";var n=t(45150),r=t(41028);n("Set",function(o){return function(){function a(){return o(this,arguments.length?arguments[0]:void 0)}return a}()},r)},17953:function(y,e,t){"use strict";t(1963)},95309:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("anchor")},{anchor:function(){function a(s){return r(this,"a","name",s)}return a}()})},82256:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("big")},{big:function(){function a(){return r(this,"big","","")}return a}()})},49484:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("blink")},{blink:function(){function a(){return r(this,"blink","","")}return a}()})},38931:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("bold")},{bold:function(){function a(){return r(this,"b","","")}return a}()})},30442:function(y,e,t){"use strict";var n=t(63964),r=t(50233).codeAt;n({target:"String",proto:!0},{codePointAt:function(){function o(a){return r(this,a)}return o}()})},6403:function(y,e,t){"use strict";var n=t(63964),r=t(71138),o=t(27193).f,a=t(10188),s=t(12605),u=t(86213),l=t(16952),p=t(45490),f=t(4493),i=r("".slice),d=Math.min,c=p("endsWith"),g=!f&&!c&&!!function(){var v=o(String.prototype,"endsWith");return v&&!v.writable}();n({target:"String",proto:!0,forced:!g&&!c},{endsWith:function(){function v(h){var m=s(l(this));u(h);var E=arguments.length>1?arguments[1]:void 0,I=m.length,O=E===void 0?I:d(a(E),I),C=s(h);return i(m,O-C.length,O)===C}return v}()})},39308:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("fixed")},{fixed:function(){function a(){return r(this,"tt","","")}return a}()})},91550:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("fontcolor")},{fontcolor:function(){function a(s){return r(this,"font","color",s)}return a}()})},75008:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("fontsize")},{fontsize:function(){function a(s){return r(this,"font","size",s)}return a}()})},9867:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(13912),a=RangeError,s=String.fromCharCode,u=String.fromCodePoint,l=r([].join),p=!!u&&u.length!==1;n({target:"String",stat:!0,arity:1,forced:p},{fromCodePoint:function(){function f(i){for(var d=[],c=arguments.length,g=0,v;c>g;){if(v=+arguments[g++],o(v,1114111)!==v)throw new a(v+" is not a valid code point");d[g]=v<65536?s(v):s(((v-=65536)>>10)+55296,v%1024+56320)}return l(d,"")}return f}()})},43673:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(86213),a=t(16952),s=t(12605),u=t(45490),l=r("".indexOf);n({target:"String",proto:!0,forced:!u("includes")},{includes:function(){function p(f){return!!~l(s(a(this)),s(o(f)),arguments.length>1?arguments[1]:void 0)}return p}()})},56027:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("italics")},{italics:function(){function a(){return r(this,"i","","")}return a}()})},12354:function(y,e,t){"use strict";var n=t(50233).charAt,r=t(12605),o=t(5419),a=t(65574),s=t(5959),u="String Iterator",l=o.set,p=o.getterFor(u);a(String,"String",function(f){l(this,{type:u,string:r(f),index:0})},function(){function f(){var i=p(this),d=i.string,c=i.index,g;return c>=d.length?s(void 0,!0):(g=n(d,c),i.index+=g.length,s(g,!1))}return f}())},50340:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("link")},{link:function(){function a(s){return r(this,"a","href",s)}return a}()})},22515:function(y,e,t){"use strict";var n=t(91495),r=t(79942),o=t(30365),a=t(42871),s=t(10188),u=t(12605),l=t(16952),p=t(78060),f=t(35483),i=t(28340);r("match",function(d,c,g){return[function(){function v(h){var m=l(this),E=a(h)?void 0:p(h,d);return E?n(E,h,m):new RegExp(h)[d](u(m))}return v}(),function(v){var h=o(this),m=u(v),E=g(c,h,m);if(E.done)return E.value;if(!h.global)return i(h,m);var I=h.unicode;h.lastIndex=0;for(var O=[],C=0,S;(S=i(h,m))!==null;){var T=u(S[0]);O[C]=T,T===""&&(h.lastIndex=f(m,s(h.lastIndex),I)),C++}return C===0?null:O}]})},5143:function(y,e,t){"use strict";var n=t(63964),r=t(24051).end,o=t(34125);n({target:"String",proto:!0,forced:o},{padEnd:function(){function a(s){return r(this,s,arguments.length>1?arguments[1]:void 0)}return a}()})},93514:function(y,e,t){"use strict";var n=t(63964),r=t(24051).start,o=t(34125);n({target:"String",proto:!0,forced:o},{padStart:function(){function a(s){return r(this,s,arguments.length>1?arguments[1]:void 0)}return a}()})},5416:function(y,e,t){"use strict";var n=t(63964),r=t(67250),o=t(57591),a=t(46771),s=t(12605),u=t(24760),l=r([].push),p=r([].join);n({target:"String",stat:!0},{raw:function(){function f(i){var d=o(a(i).raw),c=u(d);if(!c)return"";for(var g=arguments.length,v=[],h=0;;){if(l(v,s(d[h++])),h===c)return p(v,"");h")!=="7"});a("replace",function(U,j,G){var $=w?"$":"$0";return[function(){function x(B,F){var H=c(this),K=p(B)?void 0:v(B,I);return K?r(K,B,H,F):r(j,d(H),B,F)}return x}(),function(x,B){var F=u(this),H=d(x);if(typeof B=="string"&&b(B,$)===-1&&b(B,"$<")===-1){var K=G(j,F,H,B);if(K.done)return K.value}var W=l(B);W||(B=d(B));var q=F.global,ut;q&&(ut=F.unicode,F.lastIndex=0);for(var ct=[],Q;Q=m(F,H),!(Q===null||(T(ct,Q),!q));){var X=d(Q[0]);X===""&&(F.lastIndex=g(H,i(F.lastIndex),ut))}for(var at="",ft=0,dt=0;dt=ft&&(at+=A(H,ft,rt)+mt,ft=rt+_.length)}return at+A(H,ft)}]},!V||!M||w)},63272:function(y,e,t){"use strict";var n=t(91495),r=t(79942),o=t(30365),a=t(42871),s=t(16952),u=t(5700),l=t(12605),p=t(78060),f=t(28340);r("search",function(i,d,c){return[function(){function g(v){var h=s(this),m=a(v)?void 0:p(v,i);return m?n(m,v,h):new RegExp(v)[i](l(h))}return g}(),function(g){var v=o(this),h=l(g),m=c(d,v,h);if(m.done)return m.value;var E=v.lastIndex;u(E,0)||(v.lastIndex=0);var I=f(v,h);return u(v.lastIndex,E)||(v.lastIndex=E),I===null?-1:I.index}]})},34325:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("small")},{small:function(){function a(){return r(this,"small","","")}return a}()})},39930:function(y,e,t){"use strict";var n=t(91495),r=t(67250),o=t(79942),a=t(30365),s=t(42871),u=t(16952),l=t(28987),p=t(35483),f=t(10188),i=t(12605),d=t(78060),c=t(28340),g=t(62115),v=t(40033),h=g.UNSUPPORTED_Y,m=4294967295,E=Math.min,I=r([].push),O=r("".slice),C=!v(function(){var T=/(?:)/,b=T.exec;T.exec=function(){return b.apply(this,arguments)};var A="ab".split(T);return A.length!==2||A[0]!=="a"||A[1]!=="b"}),S="abbc".split(/(b)*/)[1]==="c"||"test".split(/(?:)/,-1).length!==4||"ab".split(/(?:ab)*/).length!==2||".".split(/(.?)(.?)/).length!==4||".".split(/()()/).length>1||"".split(/.?/).length;o("split",function(T,b,A){var P="0".split(void 0,0).length?function(M,w){return M===void 0&&w===0?[]:n(b,this,M,w)}:b;return[function(){function M(w,V){var U=u(this),j=s(w)?void 0:d(w,T);return j?n(j,w,U,V):n(P,i(U),w,V)}return M}(),function(M,w){var V=a(this),U=i(M);if(!S){var j=A(P,V,U,w,P!==b);if(j.done)return j.value}var G=l(V,RegExp),$=V.unicode,x=(V.ignoreCase?"i":"")+(V.multiline?"m":"")+(V.unicode?"u":"")+(h?"g":"y"),B=new G(h?"^(?:"+V.source+")":V,x),F=w===void 0?m:w>>>0;if(F===0)return[];if(U.length===0)return c(B,U)===null?[U]:[];for(var H=0,K=0,W=[];K1?arguments[1]:void 0,m.length)),I=s(h);return i(m,E,E+I.length)===I}return v}()})},74498:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("strike")},{strike:function(){function a(){return r(this,"strike","","")}return a}()})},15812:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("sub")},{sub:function(){function a(){return r(this,"sub","","")}return a}()})},57726:function(y,e,t){"use strict";var n=t(63964),r=t(72506),o=t(88539);n({target:"String",proto:!0,forced:o("sup")},{sup:function(){function a(){return r(this,"sup","","")}return a}()})},70604:function(y,e,t){"use strict";t(99159);var n=t(63964),r=t(43476);n({target:"String",proto:!0,name:"trimEnd",forced:"".trimEnd!==r},{trimEnd:r})},85404:function(y,e,t){"use strict";var n=t(63964),r=t(43885);n({target:"String",proto:!0,name:"trimStart",forced:"".trimLeft!==r},{trimLeft:r})},99159:function(y,e,t){"use strict";var n=t(63964),r=t(43476);n({target:"String",proto:!0,name:"trimEnd",forced:"".trimRight!==r},{trimRight:r})},34965:function(y,e,t){"use strict";t(85404);var n=t(63964),r=t(43885);n({target:"String",proto:!0,name:"trimStart",forced:"".trimStart!==r},{trimStart:r})},8448:function(y,e,t){"use strict";var n=t(63964),r=t(92648).trim,o=t(90012);n({target:"String",proto:!0,forced:o("trim")},{trim:function(){function a(){return r(this)}return a}()})},79250:function(y,e,t){"use strict";var n=t(85889);n("asyncIterator")},49899:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(91495),a=t(67250),s=t(4493),u=t(58310),l=t(52357),p=t(40033),f=t(45299),i=t(21287),d=t(30365),c=t(57591),g=t(767),v=t(12605),h=t(87458),m=t(80674),E=t(18450),I=t(37310),O=t(81644),C=t(89235),S=t(27193),T=t(74595),b=t(24239),A=t(12867),P=t(55938),M=t(73936),w=t(16639),V=t(19417),U=t(79195),j=t(16738),G=t(24697),$=t(55557),x=t(85889),B=t(52360),F=t(84925),H=t(5419),K=t(22603).forEach,W=V("hidden"),q="Symbol",ut="prototype",ct=H.set,Q=H.getterFor(q),X=Object[ut],at=r.Symbol,ft=at&&at[ut],dt=r.RangeError,_=r.TypeError,rt=r.QObject,it=S.f,mt=T.f,ot=O.f,et=A.f,k=a([].push),tt=w("symbols"),nt=w("op-symbols"),pt=w("wks"),Et=!rt||!rt[ut]||!rt[ut].findChild,st=function(St,At,Tt){var Nt=it(X,At);Nt&&delete X[At],mt(St,At,Tt),Nt&&St!==X&&mt(X,At,Nt)},yt=u&&p(function(){return m(mt({},"a",{get:function(){function vt(){return mt(this,"a",{value:7}).a}return vt}()})).a!==7})?st:mt,Pt=function(St,At){var Tt=tt[St]=m(ft);return ct(Tt,{type:q,tag:St,description:At}),u||(Tt.description=At),Tt},Ct=function(){function vt(St,At,Tt){St===X&&Ct(nt,At,Tt),d(St);var Nt=g(At);return d(Tt),f(tt,Nt)?(Tt.enumerable?(f(St,W)&&St[W][Nt]&&(St[W][Nt]=!1),Tt=m(Tt,{enumerable:h(0,!1)})):(f(St,W)||mt(St,W,h(1,m(null))),St[W][Nt]=!0),yt(St,Nt,Tt)):mt(St,Nt,Tt)}return vt}(),lt=function(){function vt(St,At){d(St);var Tt=c(At),Nt=E(Tt).concat(Ot(Tt));return K(Nt,function(Ft){(!u||o(It,Tt,Ft))&&Ct(St,Ft,Tt[Ft])}),St}return vt}(),gt=function(){function vt(St,At){return At===void 0?m(St):lt(m(St),At)}return vt}(),It=function(){function vt(St){var At=g(St),Tt=o(et,this,At);return this===X&&f(tt,At)&&!f(nt,At)?!1:Tt||!f(this,At)||!f(tt,At)||f(this,W)&&this[W][At]?Tt:!0}return vt}(),Lt=function(){function vt(St,At){var Tt=c(St),Nt=g(At);if(!(Tt===X&&f(tt,Nt)&&!f(nt,Nt))){var Ft=it(Tt,Nt);return Ft&&f(tt,Nt)&&!(f(Tt,W)&&Tt[W][Nt])&&(Ft.enumerable=!0),Ft}}return vt}(),Vt=function(){function vt(St){var At=ot(c(St)),Tt=[];return K(At,function(Nt){!f(tt,Nt)&&!f(U,Nt)&&k(Tt,Nt)}),Tt}return vt}(),Ot=function(St){var At=St===X,Tt=ot(At?nt:c(St)),Nt=[];return K(Tt,function(Ft){f(tt,Ft)&&(!At||f(X,Ft))&&k(Nt,tt[Ft])}),Nt};l||(at=function(){function vt(){if(i(ft,this))throw new _("Symbol is not a constructor");var St=!arguments.length||arguments[0]===void 0?void 0:v(arguments[0]),At=j(St),Tt=function(){function Nt(Ft){var jt=this===void 0?r:this;jt===X&&o(Nt,nt,Ft),f(jt,W)&&f(jt[W],At)&&(jt[W][At]=!1);var Ht=h(1,Ft);try{yt(jt,At,Ht)}catch(Kt){if(!(Kt instanceof dt))throw Kt;st(jt,At,Ht)}}return Nt}();return u&&Et&&yt(X,At,{configurable:!0,set:Tt}),Pt(At,St)}return vt}(),ft=at[ut],P(ft,"toString",function(){function vt(){return Q(this).tag}return vt}()),P(at,"withoutSetter",function(vt){return Pt(j(vt),vt)}),A.f=It,T.f=Ct,b.f=lt,S.f=Lt,I.f=O.f=Vt,C.f=Ot,$.f=function(vt){return Pt(G(vt),vt)},u&&(M(ft,"description",{configurable:!0,get:function(){function vt(){return Q(this).description}return vt}()}),s||P(X,"propertyIsEnumerable",It,{unsafe:!0}))),n({global:!0,constructor:!0,wrap:!0,forced:!l,sham:!l},{Symbol:at}),K(E(pt),function(vt){x(vt)}),n({target:q,stat:!0,forced:!l},{useSetter:function(){function vt(){Et=!0}return vt}(),useSimple:function(){function vt(){Et=!1}return vt}()}),n({target:"Object",stat:!0,forced:!l,sham:!u},{create:gt,defineProperty:Ct,defineProperties:lt,getOwnPropertyDescriptor:Lt}),n({target:"Object",stat:!0,forced:!l},{getOwnPropertyNames:Vt}),B(),F(at,q),U[W]=!0},10933:function(y,e,t){"use strict";var n=t(63964),r=t(58310),o=t(74685),a=t(67250),s=t(45299),u=t(55747),l=t(21287),p=t(12605),f=t(73936),i=t(5774),d=o.Symbol,c=d&&d.prototype;if(r&&u(d)&&(!("description"in c)||d().description!==void 0)){var g={},v=function(){function S(){var T=arguments.length<1||arguments[0]===void 0?void 0:p(arguments[0]),b=l(c,this)?new d(T):T===void 0?d():d(T);return T===""&&(g[b]=!0),b}return S}();i(v,d),v.prototype=c,c.constructor=v;var h=String(d("description detection"))==="Symbol(description detection)",m=a(c.valueOf),E=a(c.toString),I=/^Symbol\((.*)\)[^)]+$/,O=a("".replace),C=a("".slice);f(c,"description",{configurable:!0,get:function(){function S(){var T=m(this);if(s(g,T))return"";var b=E(T),A=h?C(b,7,-1):O(b,I,"$1");return A===""?void 0:A}return S}()}),n({global:!0,constructor:!0,forced:!0},{Symbol:v})}},30828:function(y,e,t){"use strict";var n=t(63964),r=t(4009),o=t(45299),a=t(12605),s=t(16639),u=t(66570),l=s("string-to-symbol-registry"),p=s("symbol-to-string-registry");n({target:"Symbol",stat:!0,forced:!u},{for:function(){function f(i){var d=a(i);if(o(l,d))return l[d];var c=r("Symbol")(d);return l[d]=c,p[c]=d,c}return f}()})},53795:function(y,e,t){"use strict";var n=t(85889);n("hasInstance")},87806:function(y,e,t){"use strict";var n=t(85889);n("isConcatSpreadable")},64677:function(y,e,t){"use strict";var n=t(85889);n("iterator")},33313:function(y,e,t){"use strict";t(49899),t(30828),t(6862),t(53008),t(28603)},6862:function(y,e,t){"use strict";var n=t(63964),r=t(45299),o=t(71399),a=t(89393),s=t(16639),u=t(66570),l=s("symbol-to-string-registry");n({target:"Symbol",stat:!0,forced:!u},{keyFor:function(){function p(f){if(!o(f))throw new TypeError(a(f)+" is not a symbol");if(r(l,f))return l[f]}return p}()})},48058:function(y,e,t){"use strict";var n=t(85889);n("match")},51583:function(y,e,t){"use strict";var n=t(85889);n("replace")},82403:function(y,e,t){"use strict";var n=t(85889);n("search")},34265:function(y,e,t){"use strict";var n=t(85889);n("species")},3295:function(y,e,t){"use strict";var n=t(85889);n("split")},1078:function(y,e,t){"use strict";var n=t(85889),r=t(52360);n("toPrimitive"),r()},63207:function(y,e,t){"use strict";var n=t(4009),r=t(85889),o=t(84925);r("toStringTag"),o(n("Symbol"),"Symbol")},80520:function(y,e,t){"use strict";var n=t(85889);n("unscopables")},99872:function(y,e,t){"use strict";var n=t(67250),r=t(4246),o=t(71447),a=n(o),s=r.aTypedArray,u=r.exportTypedArrayMethod;u("copyWithin",function(){function l(p,f){return a(s(this),p,f,arguments.length>2?arguments[2]:void 0)}return l}())},73364:function(y,e,t){"use strict";var n=t(4246),r=t(22603).every,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("every",function(){function s(u){return r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},58166:function(y,e,t){"use strict";var n=t(4246),r=t(88471),o=t(61484),a=t(2281),s=t(91495),u=t(67250),l=t(40033),p=n.aTypedArray,f=n.exportTypedArrayMethod,i=u("".slice),d=l(function(){var c=0;return new Int8Array(2).fill({valueOf:function(){function g(){return c++}return g}()}),c!==1});f("fill",function(){function c(g){var v=arguments.length;p(this);var h=i(a(this),0,3)==="Big"?o(g):+g;return s(r,this,h,v>1?arguments[1]:void 0,v>2?arguments[2]:void 0)}return c}(),d)},23793:function(y,e,t){"use strict";var n=t(4246),r=t(22603).filter,o=t(45399),a=n.aTypedArray,s=n.exportTypedArrayMethod;s("filter",function(){function u(l){var p=r(a(this),l,arguments.length>1?arguments[1]:void 0);return o(this,p)}return u}())},13917:function(y,e,t){"use strict";var n=t(4246),r=t(22603).findIndex,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("findIndex",function(){function s(u){return r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},43820:function(y,e,t){"use strict";var n=t(4246),r=t(22603).find,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("find",function(){function s(u){return r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},80756:function(y,e,t){"use strict";var n=t(80185);n("Float32",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},70567:function(y,e,t){"use strict";var n=t(80185);n("Float64",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},19852:function(y,e,t){"use strict";var n=t(4246),r=t(22603).forEach,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("forEach",function(){function s(u){r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},40379:function(y,e,t){"use strict";var n=t(86563),r=t(4246).exportTypedArrayStaticMethod,o=t(3805);r("from",o,n)},92770:function(y,e,t){"use strict";var n=t(4246),r=t(14211).includes,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("includes",function(){function s(u){return r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},81069:function(y,e,t){"use strict";var n=t(4246),r=t(14211).indexOf,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("indexOf",function(){function s(u){return r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},60037:function(y,e,t){"use strict";var n=t(80185);n("Int16",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},44195:function(y,e,t){"use strict";var n=t(80185);n("Int32",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},66756:function(y,e,t){"use strict";var n=t(80185);n("Int8",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},63689:function(y,e,t){"use strict";var n=t(74685),r=t(40033),o=t(67250),a=t(4246),s=t(34570),u=t(24697),l=u("iterator"),p=n.Uint8Array,f=o(s.values),i=o(s.keys),d=o(s.entries),c=a.aTypedArray,g=a.exportTypedArrayMethod,v=p&&p.prototype,h=!r(function(){v[l].call([1])}),m=!!v&&v.values&&v[l]===v.values&&v.values.name==="values",E=function(){function I(){return f(c(this))}return I}();g("entries",function(){function I(){return d(c(this))}return I}(),h),g("keys",function(){function I(){return i(c(this))}return I}(),h),g("values",E,h||!m,{name:"values"}),g(l,E,h||!m,{name:"values"})},5659:function(y,e,t){"use strict";var n=t(4246),r=t(67250),o=n.aTypedArray,a=n.exportTypedArrayMethod,s=r([].join);a("join",function(){function u(l){return s(o(this),l)}return u}())},25014:function(y,e,t){"use strict";var n=t(4246),r=t(61267),o=t(1325),a=n.aTypedArray,s=n.exportTypedArrayMethod;s("lastIndexOf",function(){function u(l){var p=arguments.length;return r(o,a(this),p>1?[l,arguments[1]]:[l])}return u}())},32189:function(y,e,t){"use strict";var n=t(4246),r=t(22603).map,o=t(31082),a=n.aTypedArray,s=n.exportTypedArrayMethod;s("map",function(){function u(l){return r(a(this),l,arguments.length>1?arguments[1]:void 0,function(p,f){return new(o(p))(f)})}return u}())},23030:function(y,e,t){"use strict";var n=t(4246),r=t(86563),o=n.aTypedArrayConstructor,a=n.exportTypedArrayStaticMethod;a("of",function(){function s(){for(var u=0,l=arguments.length,p=new(o(this))(l);l>u;)p[u]=arguments[u++];return p}return s}(),r)},49110:function(y,e,t){"use strict";var n=t(4246),r=t(56844).right,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("reduceRight",function(){function s(u){var l=arguments.length;return r(o(this),u,l,l>1?arguments[1]:void 0)}return s}())},24309:function(y,e,t){"use strict";var n=t(4246),r=t(56844).left,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("reduce",function(){function s(u){var l=arguments.length;return r(o(this),u,l,l>1?arguments[1]:void 0)}return s}())},56445:function(y,e,t){"use strict";var n=t(4246),r=n.aTypedArray,o=n.exportTypedArrayMethod,a=Math.floor;o("reverse",function(){function s(){for(var u=this,l=r(u).length,p=a(l/2),f=0,i;f1?arguments[1]:void 0,1),O=u(E);if(v)return r(d,this,O,I);var C=this.length,S=a(O),T=0;if(S+I>C)throw new p("Wrong length");for(;Tg;)h[g]=d[g++];return h}return p}(),l)},88739:function(y,e,t){"use strict";var n=t(4246),r=t(22603).some,o=n.aTypedArray,a=n.exportTypedArrayMethod;a("some",function(){function s(u){return r(o(this),u,arguments.length>1?arguments[1]:void 0)}return s}())},60415:function(y,e,t){"use strict";var n=t(74685),r=t(71138),o=t(40033),a=t(10320),s=t(90274),u=t(4246),l=t(652),p=t(19228),f=t(5026),i=t(9342),d=u.aTypedArray,c=u.exportTypedArrayMethod,g=n.Uint16Array,v=g&&r(g.prototype.sort),h=!!v&&!(o(function(){v(new g(2),null)})&&o(function(){v(new g(2),{})})),m=!!v&&!o(function(){if(f)return f<74;if(l)return l<67;if(p)return!0;if(i)return i<602;var I=new g(516),O=Array(516),C,S;for(C=0;C<516;C++)S=C%4,I[C]=515-C,O[C]=C-2*S+3;for(v(I,function(T,b){return(T/4|0)-(b/4|0)}),C=0;C<516;C++)if(I[C]!==O[C])return!0}),E=function(O){return function(C,S){return O!==void 0?+O(C,S)||0:S!==S?-1:C!==C?1:C===0&&S===0?1/C>0&&1/S<0?1:-1:C>S}};c("sort",function(){function I(O){return O!==void 0&&a(O),m?v(this,O):s(d(this),E(O))}return I}(),!m||h)},72532:function(y,e,t){"use strict";var n=t(4246),r=t(10188),o=t(13912),a=t(31082),s=n.aTypedArray,u=n.exportTypedArrayMethod;u("subarray",function(){function l(p,f){var i=s(this),d=i.length,c=o(p,d),g=a(i);return new g(i.buffer,i.byteOffset+c*i.BYTES_PER_ELEMENT,r((f===void 0?d:o(f,d))-c))}return l}())},62207:function(y,e,t){"use strict";var n=t(74685),r=t(61267),o=t(4246),a=t(40033),s=t(54602),u=n.Int8Array,l=o.aTypedArray,p=o.exportTypedArrayMethod,f=[].toLocaleString,i=!!u&&a(function(){f.call(new u(1))}),d=a(function(){return[1,2].toLocaleString()!==new u([1,2]).toLocaleString()})||!a(function(){u.prototype.toLocaleString.call([1,2])});p("toLocaleString",function(){function c(){return r(f,i?s(l(this)):l(this),s(arguments))}return c}(),d)},906:function(y,e,t){"use strict";var n=t(4246).exportTypedArrayMethod,r=t(40033),o=t(74685),a=t(67250),s=o.Uint8Array,u=s&&s.prototype||{},l=[].toString,p=a([].join);r(function(){l.call({})})&&(l=function(){function i(){return p(this)}return i}());var f=u.toString!==l;n("toString",l,f)},78824:function(y,e,t){"use strict";var n=t(80185);n("Uint16",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},72846:function(y,e,t){"use strict";var n=t(80185);n("Uint32",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},24575:function(y,e,t){"use strict";var n=t(80185);n("Uint8",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()})},71968:function(y,e,t){"use strict";var n=t(80185);n("Uint8",function(r){return function(){function o(a,s,u){return r(this,a,s,u)}return o}()},!0)},80040:function(y,e,t){"use strict";var n=t(50730),r=t(74685),o=t(67250),a=t(30145),s=t(81969),u=t(45150),l=t(39895),p=t(77568),f=t(5419).enforce,i=t(40033),d=t(21820),c=Object,g=Array.isArray,v=c.isExtensible,h=c.isFrozen,m=c.isSealed,E=c.freeze,I=c.seal,O=!r.ActiveXObject&&"ActiveXObject"in r,C,S=function(j){return function(){function G(){return j(this,arguments.length?arguments[0]:void 0)}return G}()},T=u("WeakMap",S,l),b=T.prototype,A=o(b.set),P=function(){return n&&i(function(){var j=E([]);return A(new T,j,1),!h(j)})};if(d)if(O){C=l.getConstructor(S,"WeakMap",!0),s.enable();var M=o(b.delete),w=o(b.has),V=o(b.get);a(b,{delete:function(){function U(j){if(p(j)&&!v(j)){var G=f(this);return G.frozen||(G.frozen=new C),M(this,j)||G.frozen.delete(j)}return M(this,j)}return U}(),has:function(){function U(j){if(p(j)&&!v(j)){var G=f(this);return G.frozen||(G.frozen=new C),w(this,j)||G.frozen.has(j)}return w(this,j)}return U}(),get:function(){function U(j){if(p(j)&&!v(j)){var G=f(this);return G.frozen||(G.frozen=new C),w(this,j)?V(this,j):G.frozen.get(j)}return V(this,j)}return U}(),set:function(){function U(j,G){if(p(j)&&!v(j)){var $=f(this);$.frozen||($.frozen=new C),w(this,j)?A(this,j,G):$.frozen.set(j,G)}else A(this,j,G);return this}return U}()})}else P()&&a(b,{set:function(){function U(j,G){var $;return g(j)&&(h(j)?$=E:m(j)&&($=I)),A(this,j,G),$&&$(j),this}return U}()})},90846:function(y,e,t){"use strict";t(80040)},67042:function(y,e,t){"use strict";var n=t(45150),r=t(39895);n("WeakSet",function(o){return function(){function a(){return o(this,arguments.length?arguments[0]:void 0)}return a}()},r)},40348:function(y,e,t){"use strict";t(67042)},5606:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(60375).clear;n({global:!0,bind:!0,enumerable:!0,forced:r.clearImmediate!==o},{clearImmediate:o})},83006:function(y,e,t){"use strict";t(5606),t(27807)},25764:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(37713),a=t(10320),s=t(24986),u=t(40033),l=t(58310),p=u(function(){return l&&Object.getOwnPropertyDescriptor(r,"queueMicrotask").value.length!==1});n({global:!0,enumerable:!0,dontCallGetSet:!0,forced:p},{queueMicrotask:function(){function f(i){s(arguments.length,1),o(a(i))}return f}()})},27807:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(60375).set,a=t(78362),s=r.setImmediate?a(o,!1):o;n({global:!0,bind:!0,enumerable:!0,forced:r.setImmediate!==s},{setImmediate:s})},45569:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(78362),a=o(r.setInterval,!0);n({global:!0,bind:!0,forced:r.setInterval!==a},{setInterval:a})},5213:function(y,e,t){"use strict";var n=t(63964),r=t(74685),o=t(78362),a=o(r.setTimeout,!0);n({global:!0,bind:!0,forced:r.setTimeout!==a},{setTimeout:a})},69401:function(y,e,t){"use strict";t(45569),t(5213)},7435:function(y){"use strict";/** * @file * @copyright 2020 Aleksej Komarov * @license MIT @@ -509,4 +509,4 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT - */e.perf.mark("inception",(g=window.performance)==null||(g=g.timing)==null?void 0:g.navigationStart),e.perf.mark("init");var v=(0,s.configureStore)({reducer:(0,t.combineReducers)({audio:u.audioReducer,chat:l.chatReducer,game:p.gameReducer,ping:i.pingReducer,settings:d.settingsReducer}),middleware:{pre:[l.chatMiddleware,i.pingMiddleware,c.telemetryMiddleware,d.settingsMiddleware,u.audioMiddleware,p.gameMiddleware]}}),h=(0,a.createRenderer)(function(){var E=J(530),I=E.Panel;return(0,y.createComponentVNode)(2,s.StoreProvider,{store:v,children:(0,y.createComponentVNode)(2,I)})}),m=function E(){if(document.readyState==="loading"){document.addEventListener("DOMContentLoaded",E);return}(0,r.setupGlobalEvents)({ignoreWindowFocus:!0}),(0,f.setupPanelFocusHacks)(),(0,o.captureExternalLinks)(),v.subscribe(h),Byond.subscribe(function(I,O){return v.dispatch({type:I,payload:O})}),Byond.winset("legacy_output_selector",{left:"output_browser"}),Byond.winget("output").then(function(I){Byond.winset("chat_panel",{size:I.size})})};m()}()})();})(); + */e.perf.mark("inception",(g=window.performance)==null||(g=g.timing)==null?void 0:g.navigationStart),e.perf.mark("init");var v=(0,s.configureStore)({reducer:(0,t.combineReducers)({audio:u.audioReducer,chat:l.chatReducer,game:p.gameReducer,ping:i.pingReducer,settings:d.settingsReducer}),middleware:{pre:[l.chatMiddleware,i.pingMiddleware,c.telemetryMiddleware,d.settingsMiddleware,u.audioMiddleware,p.gameMiddleware]}}),h=(0,a.createRenderer)(function(){var E=J(530),I=E.Panel;return(0,y.createComponentVNode)(2,s.StoreProvider,{store:v,children:(0,y.createComponentVNode)(2,I)})}),m=function E(){if(document.readyState==="loading"){document.addEventListener("DOMContentLoaded",E);return}(0,r.setupGlobalEvents)({ignoreWindowFocus:!0}),(0,f.setupPanelFocusHacks)(),(0,o.captureExternalLinks)(),v.subscribe(h),Byond.subscribe(function(I,O){return v.dispatch({type:I,payload:O})}),Byond.winset("output",{"is-visible":!1,"is-disabled":!0}),Byond.winset("chat_panel",{"is-visible":!0,"is-disabled":!1,pos:"0x0",size:"0x0"}),Byond.winget("output").then(function(I){Byond.winset("chat_panel",{size:I.size})})};m()}()})();})(); diff --git a/tgui/public/tgui.bundle.css b/tgui/public/tgui.bundle.css index 6f9ffc8d1058d..aa5848ba0ba10 100644 --- a/tgui/public/tgui.bundle.css +++ b/tgui/public/tgui.bundle.css @@ -1 +1 @@ -html,body{box-sizing:border-box;height:100%;margin:0;font-size:12px}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif}*,*:before,*:after{box-sizing:inherit}h1,h2,h3,h4,h5,h6{display:block;margin:0;padding:6px 0;padding:.5rem 0}h1{font-size:18px;font-size:1.5rem}h2{font-size:16px;font-size:1.333rem}h3{font-size:14px;font-size:1.167rem}h4{font-size:12px;font-size:1rem}td,th{vertical-align:baseline;text-align:left}.candystripe:nth-child(odd){background-color:rgba(0,0,0,.25)}.color-black{color:#1a1a1a!important}.color-white{color:#fff!important}.color-red{color:#df3e3e!important}.color-orange{color:#f37f33!important}.color-yellow{color:#fbda21!important}.color-olive{color:#cbe41c!important}.color-green{color:#25ca4c!important}.color-teal{color:#00d6cc!important}.color-blue{color:#2e93de!important}.color-violet{color:#7349cf!important}.color-purple{color:#ad45d0!important}.color-pink{color:#e34da1!important}.color-brown{color:#b97447!important}.color-grey{color:#848484!important}.color-good{color:#68c22d!important}.color-average{color:#f29a29!important}.color-bad{color:#df3e3e!important}.color-label{color:#8b9bb0!important}.color-gold{color:#f3b22f!important}.color-bg-black{background-color:#000!important}.color-bg-white{background-color:#d9d9d9!important}.color-bg-red{background-color:#bd2020!important}.color-bg-orange{background-color:#d95e0c!important}.color-bg-yellow{background-color:#d9b804!important}.color-bg-olive{background-color:#9aad14!important}.color-bg-green{background-color:#1b9638!important}.color-bg-teal{background-color:#009a93!important}.color-bg-blue{background-color:#1c71b1!important}.color-bg-violet{background-color:#552dab!important}.color-bg-purple{background-color:#8b2baa!important}.color-bg-pink{background-color:#cf2082!important}.color-bg-brown{background-color:#8c5836!important}.color-bg-grey{background-color:#646464!important}.color-bg-good{background-color:#4d9121!important}.color-bg-average{background-color:#cd7a0d!important}.color-bg-bad{background-color:#bd2020!important}.color-bg-label{background-color:#657a94!important}.color-bg-gold{background-color:#d6920c!important}.color-border-black{border-color:#1a1a1a!important}.color-border-white{border-color:#fff!important}.color-border-red{border-color:#df3e3e!important}.color-border-orange{border-color:#f37f33!important}.color-border-yellow{border-color:#fbda21!important}.color-border-olive{border-color:#cbe41c!important}.color-border-green{border-color:#25ca4c!important}.color-border-teal{border-color:#00d6cc!important}.color-border-blue{border-color:#2e93de!important}.color-border-violet{border-color:#7349cf!important}.color-border-purple{border-color:#ad45d0!important}.color-border-pink{border-color:#e34da1!important}.color-border-brown{border-color:#b97447!important}.color-border-grey{border-color:#848484!important}.color-border-good{border-color:#68c22d!important}.color-border-average{border-color:#f29a29!important}.color-border-bad{border-color:#df3e3e!important}.color-border-label{border-color:#8b9bb0!important}.color-border-gold{border-color:#f3b22f!important}.debug-layout,.debug-layout *:not(g):not(path){color:rgba(255,255,255,.9)!important;background:rgba(0,0,0,0)!important;outline:1px solid rgba(255,255,255,.5)!important;box-shadow:none!important;filter:none!important}.debug-layout:hover,.debug-layout *:not(g):not(path):hover{outline-color:rgba(255,255,255,.8)!important}.outline-dotted{outline-style:dotted!important}.outline-dashed{outline-style:dashed!important}.outline-solid{outline-style:solid!important}.outline-double{outline-style:double!important}.outline-groove{outline-style:groove!important}.outline-ridge{outline-style:ridge!important}.outline-inset{outline-style:inset!important}.outline-outset{outline-style:outset!important}.outline-color-black{outline:.167rem solid #1a1a1a!important}.outline-color-white{outline:.167rem solid #fff!important}.outline-color-red{outline:.167rem solid #df3e3e!important}.outline-color-orange{outline:.167rem solid #f37f33!important}.outline-color-yellow{outline:.167rem solid #fbda21!important}.outline-color-olive{outline:.167rem solid #cbe41c!important}.outline-color-green{outline:.167rem solid #25ca4c!important}.outline-color-teal{outline:.167rem solid #00d6cc!important}.outline-color-blue{outline:.167rem solid #2e93de!important}.outline-color-violet{outline:.167rem solid #7349cf!important}.outline-color-purple{outline:.167rem solid #ad45d0!important}.outline-color-pink{outline:.167rem solid #e34da1!important}.outline-color-brown{outline:.167rem solid #b97447!important}.outline-color-grey{outline:.167rem solid #848484!important}.outline-color-good{outline:.167rem solid #68c22d!important}.outline-color-average{outline:.167rem solid #f29a29!important}.outline-color-bad{outline:.167rem solid #df3e3e!important}.outline-color-label{outline:.167rem solid #8b9bb0!important}.outline-color-gold{outline:.167rem solid #f3b22f!important}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-baseline{text-align:baseline}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-pre{white-space:pre}.text-bold{font-weight:700}.text-italic{font-style:italic}.text-underline{text-decoration:underline}.BlockQuote{color:#8b9bb0;border-left:.1666666667em solid #8b9bb0;padding-left:.5em;margin-bottom:.5em}.BlockQuote:last-child{margin-bottom:0}.Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.Button:last-child{margin-right:0;margin-bottom:0}.Button .fa,.Button .fas,.Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.Button--hasContent .fa,.Button--hasContent .fas,.Button--hasContent .far{margin-right:.25em}.Button--hasContent.Button--iconRight .fa,.Button--hasContent.Button--iconRight .fas,.Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.Button--fluid{display:block;margin-left:0;margin-right:0}.Button--circular{border-radius:50%}.Button--compact{padding:0 .25em;line-height:1.333em}.Button--multiLine{white-space:normal;word-wrap:break-word}.Button--modal{float:right;z-index:1;margin-top:-.5rem}.Button--color--black{background-color:#000;color:#fff;transition:color .2s,background-color .2s}.Button--color--black:hover{background-color:#101010;color:#fff}.Button--color--black--translucent{background-color:rgba(0,0,0,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--black--translucent:hover{background-color:rgba(16,16,16,.5);color:#fff}.Button--color--white{background-color:#d9d9d9;color:#000;transition:color .2s,background-color .2s}.Button--color--white:hover{background-color:#f8f8f8;color:#000}.Button--color--white--translucent{background-color:rgba(217,217,217,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--white--translucent:hover{background-color:rgba(248,248,248,.5);color:#fff}.Button--color--red{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.Button--color--red:hover{background-color:#d93f3f;color:#fff}.Button--color--red--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--red--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.Button--color--orange{background-color:#d95e0c;color:#fff;transition:color .2s,background-color .2s}.Button--color--orange:hover{background-color:#ef7e33;color:#fff}.Button--color--orange--translucent{background-color:rgba(217,94,12,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--orange--translucent:hover{background-color:rgba(239,126,51,.5);color:#fff}.Button--color--yellow{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.Button--color--yellow:hover{background-color:#f5d523;color:#000}.Button--color--yellow--translucent{background-color:rgba(217,184,4,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--yellow--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.Button--color--olive{background-color:#9aad14;color:#fff;transition:color .2s,background-color .2s}.Button--color--olive:hover{background-color:#bdd327;color:#fff}.Button--color--olive--translucent{background-color:rgba(154,173,20,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--olive--translucent:hover{background-color:rgba(189,211,39,.5);color:#fff}.Button--color--green{background-color:#1b9638;color:#fff;transition:color .2s,background-color .2s}.Button--color--green:hover{background-color:#2fb94f;color:#fff}.Button--color--green--translucent{background-color:rgba(27,150,56,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--green--translucent:hover{background-color:rgba(47,185,79,.5);color:#fff}.Button--color--teal{background-color:#009a93;color:#fff;transition:color .2s,background-color .2s}.Button--color--teal:hover{background-color:#10bdb6;color:#fff}.Button--color--teal--translucent{background-color:rgba(0,154,147,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--teal--translucent:hover{background-color:rgba(16,189,182,.5);color:#fff}.Button--color--blue{background-color:#1c71b1;color:#fff;transition:color .2s,background-color .2s}.Button--color--blue:hover{background-color:#308fd6;color:#fff}.Button--color--blue--translucent{background-color:rgba(28,113,177,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--blue--translucent:hover{background-color:rgba(48,143,214,.5);color:#fff}.Button--color--violet{background-color:#552dab;color:#fff;transition:color .2s,background-color .2s}.Button--color--violet:hover{background-color:#7249ca;color:#fff}.Button--color--violet--translucent{background-color:rgba(85,45,171,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--violet--translucent:hover{background-color:rgba(114,73,202,.5);color:#fff}.Button--color--purple{background-color:#8b2baa;color:#fff;transition:color .2s,background-color .2s}.Button--color--purple:hover{background-color:#aa46ca;color:#fff}.Button--color--purple--translucent{background-color:rgba(139,43,170,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--purple--translucent:hover{background-color:rgba(170,70,202,.5);color:#fff}.Button--color--pink{background-color:#cf2082;color:#fff;transition:color .2s,background-color .2s}.Button--color--pink:hover{background-color:#e04ca0;color:#fff}.Button--color--pink--translucent{background-color:rgba(207,32,130,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--pink--translucent:hover{background-color:rgba(224,76,160,.5);color:#fff}.Button--color--brown{background-color:#8c5836;color:#fff;transition:color .2s,background-color .2s}.Button--color--brown:hover{background-color:#ae724c;color:#fff}.Button--color--brown--translucent{background-color:rgba(140,88,54,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--brown--translucent:hover{background-color:rgba(174,114,76,.5);color:#fff}.Button--color--grey{background-color:#646464;color:#fff;transition:color .2s,background-color .2s}.Button--color--grey:hover{background-color:#818181;color:#fff}.Button--color--grey--translucent{background-color:rgba(100,100,100,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--grey--translucent:hover{background-color:rgba(129,129,129,.5);color:#fff}.Button--color--good{background-color:#4d9121;color:#fff;transition:color .2s,background-color .2s}.Button--color--good:hover{background-color:#67b335;color:#fff}.Button--color--good--translucent{background-color:rgba(77,145,33,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--good--translucent:hover{background-color:rgba(103,179,53,.5);color:#fff}.Button--color--average{background-color:#cd7a0d;color:#fff;transition:color .2s,background-color .2s}.Button--color--average:hover{background-color:#eb972b;color:#fff}.Button--color--average--translucent{background-color:rgba(205,122,13,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--average--translucent:hover{background-color:rgba(235,151,43,.5);color:#fff}.Button--color--bad{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.Button--color--bad:hover{background-color:#d93f3f;color:#fff}.Button--color--bad--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--bad--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.Button--color--label{background-color:#657a94;color:#fff;transition:color .2s,background-color .2s}.Button--color--label:hover{background-color:#8a9aae;color:#fff}.Button--color--label--translucent{background-color:rgba(101,122,148,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--label--translucent:hover{background-color:rgba(138,154,174,.5);color:#fff}.Button--color--gold{background-color:#d6920c;color:#fff;transition:color .2s,background-color .2s}.Button--color--gold:hover{background-color:#eeaf30;color:#fff}.Button--color--gold--translucent{background-color:rgba(214,146,12,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--gold--translucent:hover{background-color:rgba(238,175,48,.5);color:#fff}.Button--color--transparent{background-color:rgba(37,37,37,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--transparent:hover{background-color:rgba(56,56,56,.81);color:#fff}.Button--color--default{background-color:#3e6189;color:#fff;transition:color .2s,background-color .2s}.Button--color--default:hover{background-color:#567daa;color:#fff}.Button--color--default--translucent{background-color:rgba(46,46,46,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--default--translucent:hover{background-color:rgba(68,68,68,.5);color:#fff}.Button--color--caution{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.Button--color--caution:hover{background-color:#f5d523;color:#000}.Button--color--caution--translucent{background-color:rgba(217,184,4,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--caution--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.Button--color--danger{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.Button--color--danger:hover{background-color:#d93f3f;color:#fff}.Button--color--danger--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--danger--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.Button--disabled{background-color:#999!important;color:rgba(255,255,255,.75)!important}.Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.Button--selected,.Button--selected--translucent{background-color:#1b9638;color:#fff;transition:color .2s,background-color .2s}.Button--selected:hover,.Button--selected--translucent:hover{background-color:#2fb94f;color:#fff}.Collapsible{margin-bottom:.5rem}.Collapsible:last-child{margin-bottom:0}.ColorBox{display:inline-block;width:1em;height:1em;line-height:1em;text-align:center}.Dimmer{display:flex;justify-content:center;align-items:center;position:absolute;top:0;bottom:0;left:0;right:0;background-color:rgba(0,0,0,.75);z-index:5}.Dropdown{position:relative;align-items:center}.Dropdown__control{display:inline-block;align-items:center;font-family:Verdana,sans-serif;font-size:1em;width:8.3333333333em;line-height:1.3333333333em;-ms-user-select:none;user-select:none}.Dropdown__arrow-button{float:right;padding-left:.35em;width:1.2em;height:1.8333333333em;border-left:.0833333333em solid #000;border-left:.0833333333em solid rgba(0,0,0,.25)}.Dropdown__menu{overflow-y:auto;align-items:center;z-index:5;max-height:16.6666666667em;border-radius:0 0 .1666666667em .1666666667em;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75)}.Dropdown__menu-scroll{overflow-y:scroll}.Dropdown__menuentry{padding:.1666666667em .3333333333em;font-family:Verdana,sans-serif;font-size:1em;line-height:1.4166666667em;transition:background-color .1s ease-out}.Dropdown__menuentry.selected{background-color:rgba(255,255,255,.5)!important;transition:background-color 0ms}.Dropdown__menuentry:hover{background-color:rgba(255,255,255,.2);transition:background-color 0ms}.Dropdown__over{top:auto;bottom:100%}.Dropdown__selected-text{display:inline-block;text-overflow:ellipsis;white-space:nowrap;height:1.4166666667em;width:calc(100% - 1.2em);text-align:left;padding-top:2.5px}.Flex{display:-ms-flexbox;display:flex}.Flex--inline{display:inline-flex}.Flex--iefix{display:block}.Flex--iefix.Flex--inline,.Flex__item--iefix{display:inline-block}.Flex--iefix--column>.Flex__item--iefix{display:block}.IconStack>.Icon{position:absolute;width:100%;text-align:center}.IconStack{position:relative;display:inline-block;height:7em;width:10em;line-height:2em;vertical-align:middle}.IconStack:after{color:rgba(0,0,0,0);content:"."}.color__black{background-color:rgba(0,0,0,.2);color:#fff;border:solid rgba(32,32,32,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__black:hover{background-color:rgba(32,32,32,.2)}.contentColor__black{background-color:#000;color:#fff;border:solid #101010;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__black{background-color:rgba(0,0,0,.33);color:#fff;border:solid rgba(32,32,32,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__white{background-color:rgba(217,217,217,.2);color:#000;border:solid rgba(250,250,250,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__white:hover{background-color:rgba(250,250,250,.2)}.contentColor__white{background-color:#d9d9d9;color:#000;border:solid #f8f8f8;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__white{background-color:rgba(217,217,217,.33);color:#000;border:solid rgba(250,250,250,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__red{background-color:rgba(189,32,32,.2);color:#fff;border:solid rgba(227,112,112,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__red:hover{background-color:rgba(227,112,112,.2)}.contentColor__red{background-color:#bd2020;color:#fff;border:solid #d93f3f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__red{background-color:rgba(189,32,32,.33);color:#fff;border:solid rgba(227,112,112,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__orange{background-color:rgba(217,94,12,.2);color:#fff;border:solid rgba(244,162,107,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__orange:hover{background-color:rgba(244,162,107,.2)}.contentColor__orange{background-color:#d95e0c;color:#fff;border:solid #ef7e33;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__orange{background-color:rgba(217,94,12,.33);color:#fff;border:solid rgba(244,162,107,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__yellow{background-color:rgba(217,184,4,.2);color:#000;border:solid rgba(248,225,91,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__yellow:hover{background-color:rgba(248,225,91,.2)}.contentColor__yellow{background-color:#d9b804;color:#000;border:solid #f5d523;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__yellow{background-color:rgba(217,184,4,.33);color:#000;border:solid rgba(248,225,91,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__olive{background-color:rgba(154,173,20,.2);color:#000;border:solid rgba(209,228,79,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__olive:hover{background-color:rgba(209,228,79,.2)}.contentColor__olive{background-color:#9aad14;color:#000;border:solid #bdd327;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__olive{background-color:rgba(154,173,20,.33);color:#000;border:solid rgba(209,228,79,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__green{background-color:rgba(27,150,56,.2);color:#fff;border:solid rgba(72,214,105,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__green:hover{background-color:rgba(72,214,105,.2)}.contentColor__green{background-color:#1b9638;color:#fff;border:solid #2fb94f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__green{background-color:rgba(27,150,56,.33);color:#fff;border:solid rgba(72,214,105,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__teal{background-color:rgba(0,154,147,.2);color:#fff;border:solid rgba(32,225,216,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__teal:hover{background-color:rgba(32,225,216,.2)}.contentColor__teal{background-color:#009a93;color:#fff;border:solid #10bdb6;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__teal{background-color:rgba(0,154,147,.33);color:#fff;border:solid rgba(32,225,216,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__blue{background-color:rgba(28,113,177,.2);color:#fff;border:solid rgba(96,169,224,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__blue:hover{background-color:rgba(96,169,224,.2)}.contentColor__blue{background-color:#1c71b1;color:#fff;border:solid #308fd6;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__blue{background-color:rgba(28,113,177,.33);color:#fff;border:solid rgba(96,169,224,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__violet{background-color:rgba(85,45,171,.2);color:#fff;border:solid rgba(149,119,215,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__violet:hover{background-color:rgba(149,119,215,.2)}.contentColor__violet{background-color:#552dab;color:#fff;border:solid #7249ca;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__violet{background-color:rgba(85,45,171,.33);color:#fff;border:solid rgba(149,119,215,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__purple{background-color:rgba(139,43,170,.2);color:#fff;border:solid rgba(190,115,215,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__purple:hover{background-color:rgba(190,115,215,.2)}.contentColor__purple{background-color:#8b2baa;color:#fff;border:solid #aa46ca;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__purple{background-color:rgba(139,43,170,.33);color:#fff;border:solid rgba(190,115,215,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__pink{background-color:rgba(207,32,130,.2);color:#fff;border:solid rgba(233,129,188,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__pink:hover{background-color:rgba(233,129,188,.2)}.contentColor__pink{background-color:#cf2082;color:#fff;border:solid #e04ca0;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__pink{background-color:rgba(207,32,130,.33);color:#fff;border:solid rgba(233,129,188,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__brown{background-color:rgba(140,88,54,.2);color:#fff;border:solid rgba(195,144,111,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__brown:hover{background-color:rgba(195,144,111,.2)}.contentColor__brown{background-color:#8c5836;color:#fff;border:solid #ae724c;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__brown{background-color:rgba(140,88,54,.33);color:#fff;border:solid rgba(195,144,111,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__grey{background-color:rgba(100,100,100,.2);color:#fff;border:solid rgba(157,157,157,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__grey:hover{background-color:rgba(157,157,157,.2)}.contentColor__grey{background-color:#646464;color:#fff;border:solid #818181;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__grey{background-color:rgba(100,100,100,.33);color:#fff;border:solid rgba(157,157,157,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__good{background-color:rgba(77,145,33,.2);color:#fff;border:solid rgba(130,208,79,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__good:hover{background-color:rgba(130,208,79,.2)}.contentColor__good{background-color:#4d9121;color:#fff;border:solid #67b335;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__good{background-color:rgba(77,145,33,.33);color:#fff;border:solid rgba(130,208,79,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__average{background-color:rgba(205,122,13,.2);color:#fff;border:solid rgba(241,178,96,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__average:hover{background-color:rgba(241,178,96,.2)}.contentColor__average{background-color:#cd7a0d;color:#fff;border:solid #eb972b;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__average{background-color:rgba(205,122,13,.33);color:#fff;border:solid rgba(241,178,96,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__bad{background-color:rgba(189,32,32,.2);color:#fff;border:solid rgba(227,112,112,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__bad:hover{background-color:rgba(227,112,112,.2)}.contentColor__bad{background-color:#bd2020;color:#fff;border:solid #d93f3f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__bad{background-color:rgba(189,32,32,.33);color:#fff;border:solid rgba(227,112,112,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__label{background-color:rgba(101,122,148,.2);color:#fff;border:solid rgba(175,186,201,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__label:hover{background-color:rgba(175,186,201,.2)}.contentColor__label{background-color:#657a94;color:#fff;border:solid #8a9aae;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__label{background-color:rgba(101,122,148,.33);color:#fff;border:solid rgba(175,186,201,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__gold{background-color:rgba(214,146,12,.2);color:#000;border:solid rgba(243,197,103,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__gold:hover{background-color:rgba(243,197,103,.2)}.contentColor__gold{background-color:#d6920c;color:#000;border:solid #eeaf30;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__gold{background-color:rgba(214,146,12,.33);color:#000;border:solid rgba(243,197,103,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__default{background-color:rgba(53,53,53,.2);color:#fff;border:solid rgba(99,99,99,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__default:hover{background-color:rgba(99,99,99,.2)}.disabled{background-color:rgba(99,29,29,.25)!important;border-color:rgba(99,29,29,.25)!important}.selected{background-color:rgba(27,150,56,.2);color:#fff;border:solid rgba(27,150,56,.25);border-width:1px;transition:background-color .2s,border-color .2s}.selected:hover{background-color:rgba(72,214,105,.2)}.contentColor__default{background-color:#313131;color:#fff;border:solid #404040;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.contentDisabled{background-color:#631d1d!important;border-top:1px solid #803131!important}.contentSelected{background-color:#1b9638;color:#fff;border:solid #2fb94f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__default{background-color:rgba(53,53,53,.2);color:#fff;border:solid rgba(99,99,99,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.ImageButton .noAction{pointer-events:none}.ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.fluid:last-of-type{margin-bottom:0}.fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.fluid .title{font-weight:700;padding:.5em}.fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.fluid .contentFluid{padding:.5em;color:#fff}.fluid .container{flex-direction:row;flex:1}.fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.fluid .image{padding:0}.fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.Knob{position:relative;font-size:1rem;width:2.6em;height:2.6em;margin:0 auto -.2em;cursor:n-resize}.Knob:after{content:".";color:rgba(0,0,0,0);line-height:2.5em}.Knob__circle{position:absolute;top:.1em;bottom:.1em;left:.1em;right:.1em;margin:.3em;background-color:#333;background-image:linear-gradient(to bottom,rgba(255,255,255,.15),rgba(255,255,255,0));border-radius:50%;box-shadow:0 .05em .5em rgba(0,0,0,.5)}.Knob__cursorBox{position:absolute;top:0;bottom:0;left:0;right:0}.Knob__cursor{position:relative;top:.05em;margin:0 auto;width:.2em;height:.8em;background-color:rgba(255,255,255,.9)}.Knob__popupValue,.Knob__popupValue--right{position:absolute;top:-2rem;right:50%;font-size:1rem;text-align:center;padding:.25rem .5rem;color:#fff;background-color:#000;transform:translate(50%);white-space:nowrap}.Knob__popupValue--right{top:.25rem;right:-50%}.Knob__ring{position:absolute;top:0;bottom:0;left:0;right:0;padding:.1em}.Knob__ringTrackPivot{transform:rotate(135deg)}.Knob__ringTrack{fill:rgba(0,0,0,0);stroke:rgba(255,255,255,.1);stroke-width:8;stroke-linecap:round;stroke-dasharray:235.62}.Knob__ringFillPivot{transform:rotate(135deg)}.Knob--bipolar .Knob__ringFillPivot{transform:rotate(270deg)}.Knob__ringFill{fill:rgba(0,0,0,0);stroke:#6a96c9;stroke-width:8;stroke-linecap:round;stroke-dasharray:314.16;transition:stroke 50ms}.Knob--color--black .Knob__ringFill{stroke:#1a1a1a}.Knob--color--white .Knob__ringFill{stroke:#fff}.Knob--color--red .Knob__ringFill{stroke:#df3e3e}.Knob--color--orange .Knob__ringFill{stroke:#f37f33}.Knob--color--yellow .Knob__ringFill{stroke:#fbda21}.Knob--color--olive .Knob__ringFill{stroke:#cbe41c}.Knob--color--green .Knob__ringFill{stroke:#25ca4c}.Knob--color--teal .Knob__ringFill{stroke:#00d6cc}.Knob--color--blue .Knob__ringFill{stroke:#2e93de}.Knob--color--violet .Knob__ringFill{stroke:#7349cf}.Knob--color--purple .Knob__ringFill{stroke:#ad45d0}.Knob--color--pink .Knob__ringFill{stroke:#e34da1}.Knob--color--brown .Knob__ringFill{stroke:#b97447}.Knob--color--grey .Knob__ringFill{stroke:#848484}.Knob--color--good .Knob__ringFill{stroke:#68c22d}.Knob--color--average .Knob__ringFill{stroke:#f29a29}.Knob--color--bad .Knob__ringFill{stroke:#df3e3e}.Knob--color--label .Knob__ringFill{stroke:#8b9bb0}.Knob--color--gold .Knob__ringFill{stroke:#f3b22f}.LabeledList{display:table;width:100%;width:calc(100% + 1em);border-collapse:collapse;border-spacing:0;margin:-.25em -.5em 0;padding:0}.LabeledList__row{display:table-row}.LabeledList__row:last-child .LabeledList__cell{padding-bottom:0}.LabeledList__cell{display:table-cell;margin:0;padding:.25em .5em;border:0;text-align:left;vertical-align:baseline}.LabeledList__label{width:1%;white-space:nowrap;min-width:5em}.LabeledList__buttons{width:.1%;white-space:nowrap;text-align:right;padding-top:.0833333333em;padding-bottom:0}.LabeledList__breakContents{word-break:break-all;word-wrap:break-word}.Modal{background-color:#252525;max-width:calc(100% - 1rem);padding:1rem;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}.NanoMap__container{overflow:hidden;width:100%;height:100%;z-index:1}.NanoMap__marker{z-index:10;padding:0;margin:0}.NanoMap__zoomer{z-index:20;background-color:rgba(0,0,0,.33);position:absolute;top:30px;left:0;padding:.5rem;width:24%}.NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:700;font-style:italic;color:#000;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,transparent,transparent .8333333333em,rgba(0,0,0,.1) .8333333333em,rgba(0,0,0,.1) 1.6666666667em)}.NoticeBox--color--black{color:#fff;background-color:#000}.NoticeBox--color--white{color:#000;background-color:#b3b3b3}.NoticeBox--color--red{color:#fff;background-color:#701f1f}.NoticeBox--color--orange{color:#fff;background-color:#854114}.NoticeBox--color--yellow{color:#000;background-color:#83710d}.NoticeBox--color--olive{color:#000;background-color:#576015}.NoticeBox--color--green{color:#fff;background-color:#174e24}.NoticeBox--color--teal{color:#fff;background-color:#064845}.NoticeBox--color--blue{color:#fff;background-color:#1b4565}.NoticeBox--color--violet{color:#fff;background-color:#3b2864}.NoticeBox--color--purple{color:#fff;background-color:#542663}.NoticeBox--color--pink{color:#fff;background-color:#802257}.NoticeBox--color--brown{color:#fff;background-color:#4c3729}.NoticeBox--color--grey{color:#fff;background-color:#3e3e3e}.NoticeBox--color--good{color:#fff;background-color:#2e4b1a}.NoticeBox--color--average{color:#fff;background-color:#7b4e13}.NoticeBox--color--bad{color:#fff;background-color:#701f1f}.NoticeBox--color--label{color:#fff;background-color:#53565a}.NoticeBox--color--gold{color:#fff;background-color:#825d13}.NoticeBox--type--info{color:#fff;background-color:#235982}.NoticeBox--type--success{color:#fff;background-color:#1e662f}.NoticeBox--type--warning{color:#fff;background-color:#a95219}.NoticeBox--type--danger{color:#fff;background-color:#8f2828}.NumberInput{position:relative;display:inline-block;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;color:#88bfff;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.NumberInput--fluid{display:block}.NumberInput__content{margin-left:.5em}.NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #88bfff;background-color:#88bfff}.NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#0a0a0a;color:#fff;text-align:right}.ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:.16em;background-color:rgba(0,0,0,0);transition:border-color .5s}.ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.ProgressBar__fill--animated{transition:background-color .5s,width .5s}.ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.ProgressBar--color--default{border:.0833333333em solid #3e6189}.ProgressBar--color--default .ProgressBar__fill{background-color:#3e6189}.ProgressBar--color--disabled{border:1px solid #999}.ProgressBar--color--disabled .ProgressBar__fill{background-color:#999}.ProgressBar--color--black{border:.0833333333em solid #000!important}.ProgressBar--color--black .ProgressBar__fill{background-color:#000}.ProgressBar--color--white{border:.0833333333em solid #d9d9d9!important}.ProgressBar--color--white .ProgressBar__fill{background-color:#d9d9d9}.ProgressBar--color--red{border:.0833333333em solid #bd2020!important}.ProgressBar--color--red .ProgressBar__fill{background-color:#bd2020}.ProgressBar--color--orange{border:.0833333333em solid #d95e0c!important}.ProgressBar--color--orange .ProgressBar__fill{background-color:#d95e0c}.ProgressBar--color--yellow{border:.0833333333em solid #d9b804!important}.ProgressBar--color--yellow .ProgressBar__fill{background-color:#d9b804}.ProgressBar--color--olive{border:.0833333333em solid #9aad14!important}.ProgressBar--color--olive .ProgressBar__fill{background-color:#9aad14}.ProgressBar--color--green{border:.0833333333em solid #1b9638!important}.ProgressBar--color--green .ProgressBar__fill{background-color:#1b9638}.ProgressBar--color--teal{border:.0833333333em solid #009a93!important}.ProgressBar--color--teal .ProgressBar__fill{background-color:#009a93}.ProgressBar--color--blue{border:.0833333333em solid #1c71b1!important}.ProgressBar--color--blue .ProgressBar__fill{background-color:#1c71b1}.ProgressBar--color--violet{border:.0833333333em solid #552dab!important}.ProgressBar--color--violet .ProgressBar__fill{background-color:#552dab}.ProgressBar--color--purple{border:.0833333333em solid #8b2baa!important}.ProgressBar--color--purple .ProgressBar__fill{background-color:#8b2baa}.ProgressBar--color--pink{border:.0833333333em solid #cf2082!important}.ProgressBar--color--pink .ProgressBar__fill{background-color:#cf2082}.ProgressBar--color--brown{border:.0833333333em solid #8c5836!important}.ProgressBar--color--brown .ProgressBar__fill{background-color:#8c5836}.ProgressBar--color--grey{border:.0833333333em solid #646464!important}.ProgressBar--color--grey .ProgressBar__fill{background-color:#646464}.ProgressBar--color--good{border:.0833333333em solid #4d9121!important}.ProgressBar--color--good .ProgressBar__fill{background-color:#4d9121}.ProgressBar--color--average{border:.0833333333em solid #cd7a0d!important}.ProgressBar--color--average .ProgressBar__fill{background-color:#cd7a0d}.ProgressBar--color--bad{border:.0833333333em solid #bd2020!important}.ProgressBar--color--bad .ProgressBar__fill{background-color:#bd2020}.ProgressBar--color--label{border:.0833333333em solid #657a94!important}.ProgressBar--color--label .ProgressBar__fill{background-color:#657a94}.ProgressBar--color--gold{border:.0833333333em solid #d6920c!important}.ProgressBar--color--gold .ProgressBar__fill{background-color:#d6920c}.RoundGauge{font-size:1rem;width:2.6em;height:1.3em;margin:0 auto .2em}.RoundGauge__ringTrack{fill:rgba(0,0,0,0);stroke:rgba(255,255,255,.1);stroke-width:10;stroke-dasharray:157.08;stroke-dashoffset:157.08}.RoundGauge__ringFill{fill:rgba(0,0,0,0);stroke:#6a96c9;stroke-width:10;stroke-dasharray:314.16;transition:stroke 50ms}.RoundGauge__needle,.RoundGauge__ringFill{transition:transform 50ms ease-in-out}.RoundGauge__needleLine,.RoundGauge__needleMiddle{fill:#db2828}.RoundGauge__alert{fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;fill:rgba(255,255,255,.1)}.RoundGauge__alert.max{fill:#db2828}.RoundGauge--color--black.RoundGauge__ringFill{stroke:#1a1a1a}.RoundGauge--color--white.RoundGauge__ringFill{stroke:#fff}.RoundGauge--color--red.RoundGauge__ringFill{stroke:#df3e3e}.RoundGauge--color--orange.RoundGauge__ringFill{stroke:#f37f33}.RoundGauge--color--yellow.RoundGauge__ringFill{stroke:#fbda21}.RoundGauge--color--olive.RoundGauge__ringFill{stroke:#cbe41c}.RoundGauge--color--green.RoundGauge__ringFill{stroke:#25ca4c}.RoundGauge--color--teal.RoundGauge__ringFill{stroke:#00d6cc}.RoundGauge--color--blue.RoundGauge__ringFill{stroke:#2e93de}.RoundGauge--color--violet.RoundGauge__ringFill{stroke:#7349cf}.RoundGauge--color--purple.RoundGauge__ringFill{stroke:#ad45d0}.RoundGauge--color--pink.RoundGauge__ringFill{stroke:#e34da1}.RoundGauge--color--brown.RoundGauge__ringFill{stroke:#b97447}.RoundGauge--color--grey.RoundGauge__ringFill{stroke:#848484}.RoundGauge--color--good.RoundGauge__ringFill{stroke:#68c22d}.RoundGauge--color--average.RoundGauge__ringFill{stroke:#f29a29}.RoundGauge--color--bad.RoundGauge__ringFill{stroke:#df3e3e}.RoundGauge--color--label.RoundGauge__ringFill{stroke:#8b9bb0}.RoundGauge--color--gold.RoundGauge__ringFill{stroke:#f3b22f}.RoundGauge__alert--black{fill:#1a1a1a;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--white{fill:#fff;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--red{fill:#df3e3e;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--orange{fill:#f37f33;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--yellow{fill:#fbda21;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--olive{fill:#cbe41c;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--green{fill:#25ca4c;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--teal{fill:#00d6cc;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--blue{fill:#2e93de;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--violet{fill:#7349cf;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--purple{fill:#ad45d0;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--pink{fill:#e34da1;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--brown{fill:#b97447;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--grey{fill:#848484;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--good{fill:#68c22d;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--average{fill:#f29a29;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--bad{fill:#df3e3e;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--label{fill:#8b9bb0;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--gold{fill:#f3b22f;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}@keyframes RoundGauge__alertAnim{0%{opacity:.1}50%{opacity:1}to{opacity:.1}}.Section{position:relative;margin-bottom:.5em;background-color:#191919;background-color:rgba(0,0,0,.33);box-sizing:border-box}.Section:last-child{margin-bottom:0}.Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #4972a1}.Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.Section__rest{position:relative}.Section__content{padding:.66em .5em}.Section--fitted>.Section__rest>.Section__content{padding:0}.Section--fill{display:flex;flex-direction:column;height:100%}.Section--fill>.Section__rest{flex-grow:1}.Section--fill>.Section__rest>.Section__content{height:100%}.Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.Section--scrollable{overflow-x:hidden;overflow-y:hidden}.Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.Section .Section:first-child{margin-top:-.5em}.Section .Section .Section__titleText{font-size:1.0833333333em}.Section .Section .Section .Section__titleText{font-size:1em}.Slider:not(.Slider__disabled){cursor:e-resize}.Slider__cursorOffset{position:absolute;top:0;left:0;bottom:0;transition:none!important}.Slider__cursor{position:absolute;top:0;right:-.0833333333em;bottom:0;width:0;border-left:.1666666667em solid #fff}.Slider__pointer{position:absolute;right:-.4166666667em;bottom:-.3333333333em;width:0;height:0;border-left:.4166666667em solid rgba(0,0,0,0);border-right:.4166666667em solid rgba(0,0,0,0);border-bottom:.4166666667em solid #fff}.Slider__popupValue{position:absolute;right:0;top:-2rem;font-size:1rem;padding:.25rem .5rem;color:#fff;background-color:#000;transform:translate(50%);white-space:nowrap}.Divider--horizontal{margin:.5em 0}.Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.Divider--vertical{height:100%;margin:0 .5em}.Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.Stack--fill{height:100%}.Stack--horizontal>.Stack__item{margin-left:.5em}.Stack--horizontal>.Stack__item:first-child{margin-left:0}.Stack--vertical>.Stack__item{margin-top:.5em}.Stack--vertical>.Stack__item:first-child{margin-top:0}.Stack--zebra>.Stack__item:nth-child(2n){background-color:rgba(0,0,0,.33)}.Stack--horizontal>.Stack__divider:not(.Stack__divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.Stack--vertical>.Stack__divider:not(.Stack__divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.Table{display:table;width:100%;border-collapse:collapse;border-spacing:0;margin:0}.Table--collapsing{width:auto}.Table__row{display:table-row}.Table__cell{display:table-cell;padding:0 .25em}.Table__cell:first-child{padding-left:0}.Table__cell:last-child{padding-right:0}.Table__row--header .Table__cell,.Table__cell--header{font-weight:700;padding-bottom:.5em}.Table__cell--collapsing{width:1%;white-space:nowrap}.Tabs{display:flex;align-items:stretch;overflow:hidden;background-color:rgba(0,0,0,.33)}.Tabs--fill{height:100%}.Section .Tabs{background-color:rgba(0,0,0,0)}.Section:not(.Section--fitted) .Tabs{margin:0 -.5em .5em}.Section:not(.Section--fitted) .Tabs:first-child{margin-top:-.5em}.Tabs--vertical{flex-direction:column;padding:.25em .25em .25em 0}.Tabs--horizontal{margin-bottom:.5em;padding:.25em .25em 0}.Tabs--horizontal:last-child{margin-bottom:0}.Tabs__Tab{flex-grow:0}.Tabs--fluid .Tabs__Tab{flex-grow:1}.Tab{display:flex;align-items:center;justify-content:space-between;background-color:rgba(0,0,0,0);color:rgba(255,255,255,.5);min-height:2.25em;min-width:4em;transition:background-color 50ms ease-out}.Tab:not(.Tab--selected):hover{background-color:rgba(255,255,255,.075);transition:background-color 0}.Tab--selected{background-color:rgba(255,255,255,.125);color:#dfe7f0}.Tab__text{flex-grow:1;margin:0 .5em}.Tab__left{min-width:1.5em;text-align:center;margin-left:.25em}.Tab__right{min-width:1.5em;text-align:center;margin-right:.25em}.Tabs--horizontal .Tab{border-top:.1666666667em solid rgba(0,0,0,0);border-bottom:.1666666667em solid rgba(0,0,0,0);border-top-left-radius:.25em;border-top-right-radius:.25em}.Tabs--horizontal .Tab--selected{border-bottom:.1666666667em solid #d4dfec}.Tabs--vertical .Tab{min-height:2em;border-left:.1666666667em solid rgba(0,0,0,0);border-right:.1666666667em solid rgba(0,0,0,0);border-top-right-radius:.25em;border-bottom-right-radius:.25em}.Tabs--vertical .Tab--selected{border-left:.1666666667em solid #d4dfec}.Tab--selected.Tab--color--black{color:#535353}.Tabs--horizontal .Tab--selected.Tab--color--black{border-bottom-color:#1a1a1a}.Tabs--vertical .Tab--selected.Tab--color--black{border-left-color:#1a1a1a}.Tab--selected.Tab--color--white{color:#fff}.Tabs--horizontal .Tab--selected.Tab--color--white{border-bottom-color:#fff}.Tabs--vertical .Tab--selected.Tab--color--white{border-left-color:#fff}.Tab--selected.Tab--color--red{color:#e76e6e}.Tabs--horizontal .Tab--selected.Tab--color--red{border-bottom-color:#df3e3e}.Tabs--vertical .Tab--selected.Tab--color--red{border-left-color:#df3e3e}.Tab--selected.Tab--color--orange{color:#f69f66}.Tabs--horizontal .Tab--selected.Tab--color--orange{border-bottom-color:#f37f33}.Tabs--vertical .Tab--selected.Tab--color--orange{border-left-color:#f37f33}.Tab--selected.Tab--color--yellow{color:#fce358}.Tabs--horizontal .Tab--selected.Tab--color--yellow{border-bottom-color:#fbda21}.Tabs--vertical .Tab--selected.Tab--color--yellow{border-left-color:#fbda21}.Tab--selected.Tab--color--olive{color:#d8eb55}.Tabs--horizontal .Tab--selected.Tab--color--olive{border-bottom-color:#cbe41c}.Tabs--vertical .Tab--selected.Tab--color--olive{border-left-color:#cbe41c}.Tab--selected.Tab--color--green{color:#53e074}.Tabs--horizontal .Tab--selected.Tab--color--green{border-bottom-color:#25ca4c}.Tabs--vertical .Tab--selected.Tab--color--green{border-left-color:#25ca4c}.Tab--selected.Tab--color--teal{color:#21fff5}.Tabs--horizontal .Tab--selected.Tab--color--teal{border-bottom-color:#00d6cc}.Tabs--vertical .Tab--selected.Tab--color--teal{border-left-color:#00d6cc}.Tab--selected.Tab--color--blue{color:#62aee6}.Tabs--horizontal .Tab--selected.Tab--color--blue{border-bottom-color:#2e93de}.Tabs--vertical .Tab--selected.Tab--color--blue{border-left-color:#2e93de}.Tab--selected.Tab--color--violet{color:#9676db}.Tabs--horizontal .Tab--selected.Tab--color--violet{border-bottom-color:#7349cf}.Tabs--vertical .Tab--selected.Tab--color--violet{border-left-color:#7349cf}.Tab--selected.Tab--color--purple{color:#c274db}.Tabs--horizontal .Tab--selected.Tab--color--purple{border-bottom-color:#ad45d0}.Tabs--vertical .Tab--selected.Tab--color--purple{border-left-color:#ad45d0}.Tab--selected.Tab--color--pink{color:#ea79b9}.Tabs--horizontal .Tab--selected.Tab--color--pink{border-bottom-color:#e34da1}.Tabs--vertical .Tab--selected.Tab--color--pink{border-left-color:#e34da1}.Tab--selected.Tab--color--brown{color:#ca9775}.Tabs--horizontal .Tab--selected.Tab--color--brown{border-bottom-color:#b97447}.Tabs--vertical .Tab--selected.Tab--color--brown{border-left-color:#b97447}.Tab--selected.Tab--color--grey{color:#a3a3a3}.Tabs--horizontal .Tab--selected.Tab--color--grey{border-bottom-color:#848484}.Tabs--vertical .Tab--selected.Tab--color--grey{border-left-color:#848484}.Tab--selected.Tab--color--good{color:#8cd95a}.Tabs--horizontal .Tab--selected.Tab--color--good{border-bottom-color:#68c22d}.Tabs--vertical .Tab--selected.Tab--color--good{border-left-color:#68c22d}.Tab--selected.Tab--color--average{color:#f5b35e}.Tabs--horizontal .Tab--selected.Tab--color--average{border-bottom-color:#f29a29}.Tabs--vertical .Tab--selected.Tab--color--average{border-left-color:#f29a29}.Tab--selected.Tab--color--bad{color:#e76e6e}.Tabs--horizontal .Tab--selected.Tab--color--bad{border-bottom-color:#df3e3e}.Tabs--vertical .Tab--selected.Tab--color--bad{border-left-color:#df3e3e}.Tab--selected.Tab--color--label{color:#a8b4c4}.Tabs--horizontal .Tab--selected.Tab--color--label{border-bottom-color:#8b9bb0}.Tabs--vertical .Tab--selected.Tab--color--label{border-left-color:#8b9bb0}.Tab--selected.Tab--color--gold{color:#f6c563}.Tabs--horizontal .Tab--selected.Tab--color--gold{border-bottom-color:#f3b22f}.Tabs--vertical .Tab--selected.Tab--color--gold{border-left-color:#f3b22f}.Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.Input--disabled{color:#777;border-color:#848484;border-color:rgba(132,132,132,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.Input--fluid{display:block;width:auto}.Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input--monospace .Input__input{font-family:Consolas,monospace}.TextArea{position:relative;display:inline-block;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;background-color:#0a0a0a;margin-right:.1666666667em;line-height:1.4166666667em;box-sizing:border-box;width:100%}.TextArea--fluid{display:block;width:auto;height:auto}.TextArea__textarea{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;height:100%;font-size:1em;line-height:1.4166666667em;min-height:1.4166666667em;margin:0;padding:0 .5em;font-family:inherit;background-color:rgba(0,0,0,0);color:inherit;box-sizing:border-box;word-wrap:break-word;overflow:hidden}.TextArea__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.TextArea__textarea:-ms-input-placeholder{font-style:italic;color:rgba(125,125,125,.75)}.Tooltip{z-index:999;padding:.5em .75em;pointer-events:none;text-align:left;transition:opacity .15s ease-out;background-color:#000;color:#fff;box-shadow:.1em .1em 1.25em -.1em rgba(0,0,0,.5);border-radius:.16em;max-width:20.8333333333em}.AccountsUplinkTerminal__list tr>td{text-align:center}.AccountsUplinkTerminal__list tr:not(:first-child){height:24px;line-height:24px;cursor:pointer;transition:background-color 50ms}.AccountsUplinkTerminal__list tr:not(:first-child):hover,.AccountsUplinkTerminal__list tr:not(:first-child):focus{background-color:#252525}.AccountsUplinkTerminal__listRow--SUSPENDED{background-color:#740c20}.AdminAntagMenu__list tr>td{text-align:center}.AdminAntagMenu__list tr:not(:first-child){height:24px;line-height:24px;cursor:pointer;transition:background-color 50ms}.AdminAntagMenu__list tr:not(:first-child):hover,.AdminAntagMenu__list tr:not(:first-child):focus{background-color:#252525}.AdminAntagMenu__list tr:nth-child(2n){background:rgba(40,40,40,.5)}.AlertModal__Message{text-align:center;justify-content:center}.AlertModal__Buttons{justify-content:center}.AlertModal__Loader{width:100%;position:relative;height:4px}.AlertModal__LoaderProgress{position:absolute;transition:background-color .5s ease-out,width .5s ease-out;background-color:#3e6189;height:100%}.BrigCells__list .Table__row--header,.BrigCells__list .Table__cell{text-align:center}.BrigCells__list .BrigCells__listRow--active .Table__cell{background-color:#890e26}.CameraConsole__left{position:absolute;top:0;bottom:0;left:0;width:18.3333333333em}.CameraConsole__right{position:absolute;top:0;bottom:0;left:18.3333333333em;right:0;background-color:rgba(0,0,0,.33)}.CameraConsole__toolbar{position:absolute;top:0;left:0;right:0;height:2em;line-height:2em;margin:.25em 1em 0}.CameraConsole__toolbarRight{position:absolute;top:0;right:0;height:2em;line-height:2em;margin:.33em .5em 0}.CameraConsole__map{position:absolute;top:2.1666666667em;bottom:0;left:0;right:0;margin:.5em;text-align:center}.CameraConsole__map .NoticeBox{margin-top:calc(50% - 2em)}.react-colorful{position:relative;display:flex;flex-direction:column;width:200px;height:200px;-ms-user-select:none;user-select:none;cursor:default}.react-colorful__saturation_value{position:relative;flex-grow:1;border-color:rgba(0,0,0,0);border-bottom:12px solid #000;border-radius:8px 8px 0 0;background-image:linear-gradient(to top,#000,rgba(0,0,0,0)),linear-gradient(to right,#fff,rgba(255,255,255,0))}.react-colorful__pointer-fill,.react-colorful__alpha-gradient{content:"";position:absolute;left:0;top:0;right:0;bottom:0;pointer-events:none;border-radius:inherit}.react-colorful__alpha-gradient,.react-colorful__saturation_value{box-shadow:inset 0 0 0 1px rgba(0,0,0,.05)}.react-colorful__hue,.react-colorful__r,.react-colorful__g,.react-colorful__b,.react-colorful__alpha,.react-colorful__saturation,.react-colorful__value{position:relative;height:24px}.react-colorful__hue{background:linear-gradient(to right,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red)}.react-colorful__r{background:linear-gradient(to right,#000,red)}.react-colorful__g{background:linear-gradient(to right,#000,#0f0)}.react-colorful__b{background:linear-gradient(to right,#000,#00f)}.react-colorful__last-control{border-radius:0 0 8px 8px}.react-colorful__interactive{position:absolute;left:0;top:0;right:0;bottom:0;border-radius:inherit;outline:none;touch-action:none}.react-colorful__pointer{position:absolute;z-index:1;box-sizing:border-box;width:28px;height:28px;transform:translate(-50%,-50%);background-color:#cfcfcf;border:2px solid #cfcfcf;border-radius:50%;box-shadow:0 2px 5px rgba(0,0,0,.4)}.react-colorful__interactive:focus .react-colorful__pointer{transform:translate(-50%,-50%) scale(1.1);background-color:#fff;border-color:#fff}.react-colorful__alpha,.react-colorful__alpha-pointer{background-color:#fff;background-image:url('data:image/svg+xml,')}.react-colorful__saturation-pointer,.react-colorful__value-pointer,.react-colorful__hue-pointer,.react-colorful__r-pointer,.react-colorful__g-pointer,.react-colorful__b-pointer{z-index:1;width:20px;height:20px}.react-colorful__saturation_value-pointer{z-index:3}.Contractor *{font-family:Courier New,Courier,monospace}.Contractor .Section__titleText{display:inline-block;max-width:70%}.Contractor .Section__titleText>.Flex{width:100%}.Contractor .Section__titleText>.Flex>.Flex__item:first-of-type{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.Contractor__Contract .Button{font-size:11px;white-space:normal!important}.Contractor__photoZoom{text-align:center}.Contractor__photoZoom>img{width:96px;-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.Contractor__photoZoom>.Button{position:absolute}.highlighted-marker{box-sizing:content-box;display:inline-block;position:relative;top:50%;left:50%;transform:translate(-50%,-50%);border-style:solid;border-width:50%;border-radius:50%;animation:1s infinite mark-shrink}@keyframes mark-shrink{0%{width:200%;height:200%}to{width:0%;height:0%}}.Exofab .Dropdown__control{margin-bottom:-1px}.Exofab .Dropdown__selected-text{overflow:hidden;text-overflow:ellipsis;width:80%;display:inline-block;margin-bottom:-3px}.Exofab__materials{height:100%;overflow:auto}.Exofab__materials .Section__content{height:calc(100% - 31px)}.Exofab__material:not(.Exofab__material--line){margin-bottom:.25rem}.Exofab__material:not(.Exofab__material--line) .Button{width:28px;margin-right:.5rem}.Exofab__material--line .Button{background-color:rgba(0,0,0,0);width:14px}.Exofab__material--name{color:#7e90a7;text-transform:capitalize}.Exofab__material .Button{margin-bottom:0;padding:0;vertical-align:middle}.Exofab__queue{height:100%}.Exofab__queue--queue .Button{margin:0;transform:scale(.75)}.Exofab__queue--queue .Button:first-of-type{margin-left:.25rem}.Exofab__queue--time{text-align:center;color:#7e90a7}.Exofab__queue--deficit{text-align:center;color:#db2828;font-weight:700}.Exofab__queue--deficit>div:not(.Divider){display:inline-block;margin-bottom:-.75rem}.Exofab__queue .Section__content{height:calc(100% - 31px)}.Exofab__queue .Exofab__material--amount{margin-right:.25rem}.Exofab__design--cost{display:inline-block;vertical-align:middle;margin-top:.25rem}.Exofab__design--cost>div{display:inline-block}.Exofab__design--cost .Exofab__material{margin-left:.25rem}.Exofab__design--time{display:inline-block;margin-left:.5rem;color:#7e90a7}.Exofab__design--time i{margin-right:.25rem}.Exofab__designs .Section__content{height:calc(100% - 31px);overflow:auto}.Exofab__building{height:45px}.Exofab__building .ProgressBar{width:100%;height:75%}.Exofab__building .ProgressBar__content{line-height:26px;text-align:right;font-size:12px;font-weight:700;display:flex;justify-content:flex-end}.Exofab__dropdown{line-height:14px;font-size:12px;width:225px;height:85%;margin-top:1.5px}.GeneModder__left{position:absolute;top:0;bottom:0;left:0;width:40.8333333333em}.GeneModder__right{position:absolute;top:0;bottom:0;left:40.8333333333em;right:0;background-color:rgba(0,0,0,.33)}.Ingredient__Table tr:nth-child(2n){background-color:#333}.Ingredient__Table td{padding:3px}.Library__Booklist tr>td{text-align:center}.Library__Booklist tr:not(:first-child){height:24px;line-height:24px;transition:background-color 50ms}.Library__Booklist tr:not(:first-child):hover,.Library__Booklist tr:not(:first-child):focus{background-color:#252525}.Library__SearchContainer{background-color:rgba(37,37,37,.5)}.Library__SearchContainer tr td:first-child{width:60%}.ListInput__Section .Section__title{flex-shrink:0}.ListInput__Section .Section__titleText{font-size:12px}.ListInput__Loader{width:100%;position:relative;height:4px}.ListInput__LoaderProgress{position:absolute;transition:background-color .5s,width .5s;background-color:#3e6189;height:100%}.Loadout-Modal__background{padding:.5em;background-color:#252525}.Loadout-InfoBox{display:flex;line-height:1.2rem;text-shadow:0 1px 0 2px rgba(0,0,0,.66);text-align:left}.Newscaster__menu{width:40px;height:100%;margin-right:.5rem;flex-basis:content}.Newscaster__menu .Section__content{padding-left:0}.Newscaster__menuButton{color:#767676;cursor:pointer;position:relative;margin-left:6px;margin-right:1rem;white-space:nowrap;transition:color .1s}.Newscaster__menuButton--title{width:80%;display:none;overflow:hidden;text-overflow:ellipsis}.Newscaster__menuButton--unread{background-color:#e45e5e;color:#fff;font-size:10px;text-align:center;border-radius:32px;display:inline-block;width:12px;position:absolute;left:16px;margin-top:14px}.Newscaster__menuButton--selected{color:#fff}.Newscaster__menuButton--selected:after{content:"";background-color:#4972a1;width:2px;height:24px;position:absolute;left:-6px}.Newscaster__menuButton--security{color:#4972a1}.Newscaster__menuButton i{width:30px;text-align:center;vertical-align:middle;margin-left:-1px;margin-right:.5rem;margin-top:1px}.Newscaster__menuButton:hover{color:#fff}.Newscaster__menuButton:hover:before{background-color:#fff}.Newscaster__menuButton:not(:last-of-type){margin-bottom:.5rem}.Newscaster__menu--open{width:175px}.Newscaster__menu--open .Newscaster__menuButton--title{display:inline-block}.Newscaster__jobCategory--security .Section__title{color:#a14c49;border-bottom:2px solid #a14c49!important}.Newscaster__jobCategory--engineering .Section__title{color:#a17849;border-bottom:2px solid #a17849!important}.Newscaster__jobCategory--medical .Section__title{color:#499ea1;border-bottom:2px solid #499ea1!important}.Newscaster__jobCategory--science .Section__title{color:#a14972;border-bottom:2px solid #a14972!important}.Newscaster__jobCategory--service .Section__title{color:#a1499e;border-bottom:2px solid #a1499e!important}.Newscaster__jobCategory--supply .Section__title{color:#9ea149;border-bottom:2px solid #9ea149!important}.Newscaster__jobCategory:last-child{margin-bottom:.5rem}.Newscaster__jobOpening--command{font-weight:700}.Newscaster__jobOpening:not(:last-child){margin-bottom:.5rem}.Newscaster__emptyNotice{color:#7e90a7;text-align:center;position:absolute;top:50%;left:50%;transform:translateY(-50%) translate(-50%)}.Newscaster__emptyNotice i{margin-bottom:.25rem}.Newscaster__photo{cursor:pointer;width:100px;border:1px solid #000;transition:border-color .3s;-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.Newscaster__photo:hover{border-color:gray}.Newscaster__photoZoom{text-align:center}.Newscaster__photoZoom>img{transform:scale(2);-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.Newscaster__photoZoom>.Button{position:absolute;width:64px;left:50%;margin-left:-32px;bottom:1rem}.Newscaster__story--wanted{background-color:rgba(219,40,40,.1)}.Newscaster__story--wanted .Section__title{color:#db2828;border-bottom:2px solid #a14c49!important}.Newscaster__story:last-child{margin-bottom:.5rem}.NuclearBomb__displayBox{background-color:#002003;border:.167em inset #e8e4c9;color:#03e017;font-size:2em;font-family:monospace;padding:.25em}.NuclearBomb__Button{outline-width:.25rem!important;border-width:.65rem!important;padding-left:0!important;padding-right:0!important}.NuclearBomb__Button--keypad{background-color:#e8e4c9;border-color:#e8e4c9}.NuclearBomb__Button--keypad:hover{background-color:#f7f6ee!important;border-color:#f7f6ee!important}.NuclearBomb__Button--1{background-color:#d3cfb7!important;border-color:#d3cfb7!important;color:#a9a692!important}.NuclearBomb__Button--E{background-color:#d9b804!important;border-color:#d9b804!important}.NuclearBomb__Button--E:hover{background-color:#f3d00e!important;border-color:#f3d00e!important}.NuclearBomb__Button--C{background-color:#bd2020!important;border-color:#bd2020!important}.NuclearBomb__Button--C:hover{background-color:#d52b2b!important;border-color:#d52b2b!important}.OreRedemption__Ores .OreLine,.OreRedemption__Ores .OreHeader{min-height:32px;padding:0 .5rem}.OreRedemption__Ores .OreHeader{line-height:32px;background-color:rgba(0,0,0,.33);font-weight:700}.OreRedemption__Ores .OreLine:last-of-type{margin-bottom:.5rem}.OreRedemption__Ores .Section__content{padding:0;height:100%;overflow:auto}.symptoms-table{border-collapse:separate;border-spacing:0 .5ex;height:100%}.symptoms-table>tbody>tr:first-child{width:100%;font-weight:700}.symptoms-table>tbody>tr:nth-child(2)>td:first-child{padding-top:.5ex}.symptoms-table>tbody>tr>td:nth-child(n+2){text-align:center}.common-name-label>.LabeledList__cell{vertical-align:middle}.table-spacer{height:100%}.remove-section-bottom-padding .Section__content{padding-bottom:0}.PDA__footer{position:fixed;bottom:0%;left:0%;right:0%;height:30px}.PDA__footer__button{text-align:center;padding-top:4px;padding-bottom:2px;font-size:24px}.Minesweeper__closed{vertical-align:middle;background-color:#353535;border:.1666666667em outset #676767}.Minesweeper__open{vertical-align:middle;text-align:center;font-size:medium;background-color:#4f4f4f!important}.Minesweeper__list tr>td{text-align:center}.Minesweeper__list tr:not(:first-child){height:2em;line-height:1.75em;transition:background-color 50ms;cursor:pointer}.Minesweeper__list tr:not(:first-child):hover,.Minesweeper__list tr:not(:first-child):focus{background-color:#252525}.Minesweeper__infobox{max-height:8em;border:.25em outset #3a3a3a;user-select:none;-ms-user-select:none}.PdaPainter__list tr>td{text-align:center}.PdaPainter__list tr{height:24px;line-height:24px;cursor:pointer;transition:background-color 50ms}.PdaPainter__list tr:hover,.PdaPainter__list tr:focus{background-color:#252525}.PoolController__Buttons .Button:not(:last-child){margin-bottom:8px}.reagents-table{border-collapse:separate;border-spacing:0 .3em}.volume-cell{min-width:3em;text-align:right;vertical-align:middle}.volume-cell:not(:hover) .volume-actions-wrapper{display:none}.volume-cell:hover .volume-label{display:none}.reagent-absent-name-cell{color:#767676}.reagent-row>*:last-child{padding-right:.5em}.absent-row:not(:hover) .add-reagent-button{visibility:hidden}.condensed-button{margin:0;padding:0;min-height:0;line-height:0;background:none}.RndConsole{position:relative}.RndConsole__Overlay{position:absolute;display:flex;align-items:stretch;justify-content:stretch;top:0;left:0;width:100%;height:100vh}.RndConsole__LatheCategory__MatchingDesigns .Table__cell{padding-bottom:4px}.RndConsole__LatheMaterials .Table__cell:nth-child(2){padding-left:16px}.RndConsole__LatheMaterialStorage .Table__cell{padding:4px 0;border-bottom:1px solid #767676}.RndConsole__Overlay__Wrapper{display:flex;align-items:center;justify-content:stretch;flex-grow:1;padding:24px;background-color:rgba(255,255,255,0)}.RndConsole__Overlay__Wrapper .NoticeBox{flex-grow:1;margin-bottom:80px;font-size:18pt;padding:.3em .75em}.RndConsole__RndNavbar .Button{margin-bottom:10px}#research-levels tr>*:first-child{width:2em}#research-levels tr>*:nth-child(3),#research-levels tr>*:nth-child(4),#research-levels tr>*:nth-child(5){text-align:center}#research-levels tr:not(:first-child)>*:first-child{height:2em}.upgraded-level{color:#55d355}.research-level-no-effect{color:#888}.Roulette{font-family:Palatino}.Roulette__board{display:table;width:100%;border-collapse:collapse;border:2px solid #fff;margin:0}.Roulette__board-row{padding:0;margin:0}.Roulette__board-cell{display:table-cell;padding:0;margin:0;border:2px solid #fff;font-family:Palatino}.Roulette__board-cell:first-child{padding-left:0}.Roulette__board-cell:last-child{padding-right:0}.Roulette__board-extrabutton{text-align:center;font-size:20px;font-weight:700;height:28px;border:none!important;margin:0!important;padding-top:4px!important;color:#fff!important}.Roulette__lowertable{margin-top:8px;margin-left:80px;margin-right:80px;border-collapse:collapse;border:2px solid #fff;border-spacing:0}.Roulette__lowertable--cell{border:2px solid #fff;padding:0;margin:0}.Roulette__lowertable--betscell{vertical-align:top}.Roulette__lowertable--spinresult{text-align:center;font-size:100px;font-weight:700;vertical-align:middle}.Roulette__lowertable--spinresult-black{background-color:#000}.Roulette__lowertable--spinresult-red{background-color:#db2828}.Roulette__lowertable--spinresult-green{background-color:#20b142}.Roulette__lowertable--spinbutton{margin:0!important;border:none!important;font-size:50px;line-height:60px!important;text-align:center;font-weight:700}.Roulette__lowertable--header{width:1%;text-align:center;font-size:20px;font-weight:700}.Safe--engraving{position:absolute;width:95%;height:96%;left:2.5%;top:2%;border:5px outset #364963;padding:5px;text-align:center}.Safe--engraving--arrow{color:#35435a}.Safe--engraving--hinge{content:" ";background-color:#191f2a;width:25px;height:40px;position:absolute;right:-15px;margin-top:-20px}.Safe--dialer{margin-bottom:.5rem}.Safe--dialer--number{color:#bbb;display:inline;background-color:#191f2a;font-size:1.5rem;font-weight:700;padding:0 .5rem}.Safe--dialer--right .Button i{z-index:-100}.Safe--dialer .Button{width:80px}.Safe--contents{border:10px solid #191f2a;background-color:#0f131a;height:calc(85% + 7.5px);text-align:left;padding:5px}.Safe--help{position:absolute;bottom:30px;left:25px;width:50%}.SecureStorage__displayBox{background-color:#212121;color:#8b8b8b;border:.167em inset #e8e4c9;font-size:375%;font-family:monospace;padding:.25em}.SecureStorage__displayBox--good{background-color:#002003;color:#03e017}.SecureStorage__displayBox--bad{background-color:#210000;color:#e00202}.SecureStorage__Button{outline-width:.25rem!important;border-width:.3rem!important;border:.167em outset #e8e4c9;padding-left:0!important;padding-right:0!important}.SecureStorage__Button--keypad{background-color:#e8e4c9;border-color:#e8e4c9;color:#a9a692}.SecureStorage__Button--keypad:hover{background-color:#f7f6ee;border-color:#f7f6ee;color:#a9a692}.SecureStorage__Button--E{background-color:#d9b804;border-color:#d9b804;color:#fff}.SecureStorage__Button--E:hover{background-color:#f5d317;border-color:#f5d317;color:#fff}.SecureStorage__Button--C{background-color:#bd2020;border-color:#bd2020;color:#fff}.SecureStorage__Button--C:hover{background-color:#d83434;border-color:#d83434;color:#fff}.SecurityRecords__list tr>td{text-align:center}.SecurityRecords__list tr:not(:first-child){height:24px;line-height:24px;cursor:pointer;transition:background-color 50ms}.SecurityRecords__list tr:not(:first-child):hover,.SecurityRecords__list tr:not(:first-child):focus{background-color:#252525}.SecurityRecords__listRow--arrest{background-color:#740c20}.SecurityRecords__listRow--execute{background-color:#683e8c}.SecurityRecords__listRow--incarcerated{background-color:#633203}.SecurityRecords__listRow--parolled{background-color:#006d7b}.SecurityRecords__listRow--released{background-color:#1c5574}.SecurityRecords__listRow--demote{background-color:#155500}.SecurityRecords__listRow--search{background-color:#987a00}.SecurityRecords__listRow--monitor{background-color:#1f1180}.SeedExtractor__list tr:not(:first-child){height:24px;line-height:24px;cursor:pointer;transition:background-color 50ms}.SeedExtractor__list tr:not(:first-child):hover,.SeedExtractor__list tr:not(:first-child):focus{background-color:#252525}.MedicalRecords__list tr>td{text-align:center}.MedicalRecords__list tr:not(:first-child){height:24px;line-height:24px;cursor:pointer;transition:background-color 50ms}.MedicalRecords__list tr:not(:first-child):hover,.MedicalRecords__list tr:not(:first-child):focus{background-color:#252525}.MedicalRecords__listRow--deceased{background-color:#740c20}.MedicalRecords__listRow--ssd{background-color:#006d7b}.MedicalRecords__listRow--physically_unfit{background-color:#987a00}.MedicalRecords__listRow--disabled{background-color:#1f1180}.MedicalRecords__listMedbot--0{background-color:#2b1414}html,body{scrollbar-color:#3b3b3b #1c1c1c}.Layout,.Layout *{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}.Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.Layout__content--flexRow{display:flex;flex-flow:row}.Layout__content--flexColumn{display:flex;flex-flow:column}.Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.Layout__content--noMargin{margin:0}.TitleBar{background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#363636;transition:color .25s,background-color .25s}.TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#252525;background-image:linear-gradient(to bottom,#2a2a2a,#202020)}.Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.Window__contentPadding:after{height:0}.Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(62,62,62,.25);pointer-events:none}.Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.Layout__content{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMCIgdmlld0JveD0iMCAwIDQyNSAyMDAiIG9wYWNpdHk9Ii4zMyI+PHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPjxwYXRoIGQ9Ik0gNC44NDQ2MzMzLDIyLjEwODc1IEEgMTMuNDEyMDM5LDEyLjUwMTg0MiAwIDAgMSAxMy40Nzc1ODgsMC4wMzkyNCBsIDY2LjExODMxNSwwIGEgNS4zNjQ4MTU4LDUuMDAwNzM3IDAgMCAxIDUuMzY0ODIzLDUuMDAwNzMgbCAwLDc5Ljg3OTMxIHoiIC8+PHBhdGggZD0ibSA0MjAuMTU1MzUsMTc3Ljg5MTE5IGEgMTMuNDEyMDM4LDEyLjUwMTg0MiAwIDAgMSAtOC42MzI5NSwyMi4wNjk1MSBsIC02Ni4xMTgzMiwwIGEgNS4zNjQ4MTUyLDUuMDAwNzM3IDAgMCAxIC01LjM2NDgyLC01LjAwMDc0IGwgMCwtNzkuODc5MzEgeiIgLz48L3N2Zz48IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT48IS0tIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LXNhLzQuMC8gLS0+);background-size:70% 70%;background-position:center;background-repeat:no-repeat}.theme-abductor .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-abductor .Button:last-child{margin-right:0;margin-bottom:0}.theme-abductor .Button .fa,.theme-abductor .Button .fas,.theme-abductor .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-abductor .Button--hasContent .fa,.theme-abductor .Button--hasContent .fas,.theme-abductor .Button--hasContent .far{margin-right:.25em}.theme-abductor .Button--hasContent.Button--iconRight .fa,.theme-abductor .Button--hasContent.Button--iconRight .fas,.theme-abductor .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-abductor .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-abductor .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-abductor .Button--circular{border-radius:50%}.theme-abductor .Button--compact{padding:0 .25em;line-height:1.333em}.theme-abductor .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-abductor .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-abductor .Button--color--transparent{background-color:rgba(42,49,74,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-abductor .Button--color--transparent:hover{background-color:rgba(62,70,100,.81);color:#fff}.theme-abductor .Button--color--default{background-color:#ad2350;color:#fff;transition:color .2s,background-color .2s}.theme-abductor .Button--color--default:hover{background-color:#d03a6b;color:#fff}.theme-abductor .Button--color--default--translucent{background-color:rgba(50,58,84,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-abductor .Button--color--default--translucent:hover{background-color:rgba(73,82,111,.5);color:#fff}.theme-abductor .Button--color--caution{background-color:#be6209;color:#fff;transition:color .2s,background-color .2s}.theme-abductor .Button--color--caution:hover{background-color:#e67f1a;color:#fff}.theme-abductor .Button--color--caution--translucent{background-color:rgba(190,98,9,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-abductor .Button--color--caution--translucent:hover{background-color:rgba(230,127,26,.5);color:#fff}.theme-abductor .Button--color--danger{background-color:#9a9d00;color:#fff;transition:color .2s,background-color .2s}.theme-abductor .Button--color--danger:hover{background-color:#bec110;color:#fff}.theme-abductor .Button--color--danger--translucent{background-color:rgba(154,157,0,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-abductor .Button--color--danger--translucent:hover{background-color:rgba(190,193,16,.5);color:#fff}.theme-abductor .Button--disabled{background-color:#363636!important;color:rgba(255,255,255,.75)!important}.theme-abductor .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-abductor .Button--selected,.theme-abductor .Button--selected--translucent{background-color:#465899;color:#fff;transition:color .2s,background-color .2s}.theme-abductor .Button--selected:hover,.theme-abductor .Button--selected--translucent:hover{background-color:#6577b5;color:#fff}.theme-abductor .Divider--horizontal{margin:.5em 0}.theme-abductor .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-abductor .Divider--vertical{height:100%;margin:0 .5em}.theme-abductor .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-abductor .color__default{background-color:rgba(180,80,112,.2);color:#fff;border:solid rgba(219,170,186,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-abductor .color__default:hover{background-color:rgba(219,170,186,.2)}.theme-abductor .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-abductor .selected{background-color:rgba(70,88,153,.2);color:#fff;border:solid rgba(70,88,153,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-abductor .selected:hover{background-color:rgba(142,155,201,.2)}.theme-abductor .contentColor__default{background-color:#af4c6c;color:#fff;border:solid #c45b7d;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-abductor .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-abductor .contentSelected{background-color:#465899;color:#fff;border:solid #6577b5;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-abductor .buttonsContainerColor__default{background-color:rgba(180,80,112,.2);color:#fff;border:solid rgba(219,170,186,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-abductor .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-abductor .ImageButton .noAction{pointer-events:none}.theme-abductor .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-abductor .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-abductor .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-abductor .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-abductor .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-abductor .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-abductor .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-abductor .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-abductor .fluid:last-of-type{margin-bottom:0}.theme-abductor .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-abductor .fluid .title{font-weight:700;padding:.5em}.theme-abductor .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-abductor .fluid .contentFluid{padding:.5em;color:#fff}.theme-abductor .fluid .container{flex-direction:row;flex:1}.theme-abductor .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-abductor .fluid .image{padding:0}.theme-abductor .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-abductor .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-abductor .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-abductor .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-abductor .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-abductor .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-abductor .NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:700;font-style:italic;color:#fff;background-color:#a82d55;background-image:repeating-linear-gradient(-45deg,transparent,transparent .8333333333em,rgba(0,0,0,.1) .8333333333em,rgba(0,0,0,.1) 1.6666666667em)}.theme-abductor .NoticeBox--type--info{color:#fff;background-color:#235982}.theme-abductor .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-abductor .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-abductor .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-abductor .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #404b6e;border:.0833333333em solid rgba(64,75,110,.75);border-radius:2px;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-abductor .Input--disabled{color:#777;border-color:#171717;border-color:rgba(23,23,23,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-abductor .Input--fluid{display:block;width:auto}.theme-abductor .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-abductor .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-abductor .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-abductor .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-abductor .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-abductor .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-abductor .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-abductor .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-abductor .NumberInput{position:relative;display:inline-block;border:.0833333333em solid #404b6e;border:.0833333333em solid rgba(64,75,110,.75);border-radius:2px;color:#404b6e;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.theme-abductor .NumberInput--fluid{display:block}.theme-abductor .NumberInput__content{margin-left:.5em}.theme-abductor .NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.theme-abductor .NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #404b6e;background-color:#404b6e}.theme-abductor .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#0a0a0a;color:#fff;text-align:right}.theme-abductor .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:2px;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-abductor .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-abductor .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-abductor .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-abductor .ProgressBar--color--default{border:.0833333333em solid #931e44}.theme-abductor .ProgressBar--color--default .ProgressBar__fill{background-color:#931e44}.theme-abductor .ProgressBar--color--disabled{border:1px solid #363636}.theme-abductor .ProgressBar--color--disabled .ProgressBar__fill{background-color:#363636}.theme-abductor .Section{position:relative;margin-bottom:.5em;background-color:#1c2132;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-abductor .Section:last-child{margin-bottom:0}.theme-abductor .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #ad2350}.theme-abductor .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-abductor .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-abductor .Section__rest{position:relative}.theme-abductor .Section__content{padding:.66em .5em}.theme-abductor .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-abductor .Section--fill{display:flex;flex-direction:column;height:100%}.theme-abductor .Section--fill>.Section__rest{flex-grow:1}.theme-abductor .Section--fill>.Section__rest>.Section__content{height:100%}.theme-abductor .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-abductor .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-abductor .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-abductor .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-abductor .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-abductor .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-abductor .Section .Section:first-child{margin-top:-.5em}.theme-abductor .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-abductor .Section .Section .Section .Section__titleText{font-size:1em}.theme-abductor .Tooltip{z-index:999;padding:.5em .75em;pointer-events:none;text-align:left;transition:opacity .15s ease-out;background-color:#a82d55;color:#fff;box-shadow:.1em .1em 1.25em -.1em rgba(0,0,0,.5);border-radius:2px;max-width:20.8333333333em}.theme-abductor html,.theme-abductor body{scrollbar-color:#384263 #202538}.theme-abductor .Layout,.theme-abductor .Layout *{scrollbar-base-color:#202538;scrollbar-face-color:#384263;scrollbar-3dlight-color:#2a314a;scrollbar-highlight-color:#2a314a;scrollbar-track-color:#202538;scrollbar-arrow-color:#818db8;scrollbar-shadow-color:#384263}.theme-abductor .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-abductor .Layout__content--flexRow{display:flex;flex-flow:row}.theme-abductor .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-abductor .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-abductor .Layout__content--noMargin{margin:0}.theme-abductor .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#2a314a;background-image:linear-gradient(to bottom,#353e5e,#1f2436)}.theme-abductor .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-abductor .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-abductor .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-abductor .Window__contentPadding:after{height:0}.theme-abductor .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-abductor .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(68,76,104,.25);pointer-events:none}.theme-abductor .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-abductor .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-abductor .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-abductor .TitleBar{background-color:#9e1b46;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-abductor .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#9e1b46;transition:color .25s,background-color .25s}.theme-abductor .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-abductor .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-abductor .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-abductor .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-abductor .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-abductor .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-abductor .Layout__content{background-image:none}.theme-cardtable .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:0;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-cardtable .Button:last-child{margin-right:0;margin-bottom:0}.theme-cardtable .Button .fa,.theme-cardtable .Button .fas,.theme-cardtable .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-cardtable .Button--hasContent .fa,.theme-cardtable .Button--hasContent .fas,.theme-cardtable .Button--hasContent .far{margin-right:.25em}.theme-cardtable .Button--hasContent.Button--iconRight .fa,.theme-cardtable .Button--hasContent.Button--iconRight .fas,.theme-cardtable .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-cardtable .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-cardtable .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-cardtable .Button--circular{border-radius:50%}.theme-cardtable .Button--compact{padding:0 .25em;line-height:1.333em}.theme-cardtable .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-cardtable .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-cardtable .Button--color--transparent{background-color:rgba(17,112,57,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-cardtable .Button--color--transparent:hover{background-color:rgba(32,145,79,.81);color:#fff}.theme-cardtable .Button--color--default{background-color:#117039;color:#fff;transition:color .2s,background-color .2s}.theme-cardtable .Button--color--default:hover{background-color:#238e50;color:#fff}.theme-cardtable .Button--color--default--translucent{background-color:rgba(25,124,67,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-cardtable .Button--color--default--translucent:hover{background-color:rgba(44,156,92,.5);color:#fff}.theme-cardtable .Button--color--caution{background-color:#be6209;color:#fff;transition:color .2s,background-color .2s}.theme-cardtable .Button--color--caution:hover{background-color:#e67f1a;color:#fff}.theme-cardtable .Button--color--caution--translucent{background-color:rgba(190,98,9,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-cardtable .Button--color--caution--translucent:hover{background-color:rgba(230,127,26,.5);color:#fff}.theme-cardtable .Button--color--danger{background-color:#9a9d00;color:#fff;transition:color .2s,background-color .2s}.theme-cardtable .Button--color--danger:hover{background-color:#bec110;color:#fff}.theme-cardtable .Button--color--danger--translucent{background-color:rgba(154,157,0,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-cardtable .Button--color--danger--translucent:hover{background-color:rgba(190,193,16,.5);color:#fff}.theme-cardtable .Button--disabled{background-color:#363636!important;color:rgba(255,255,255,.75)!important}.theme-cardtable .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-cardtable .Button--selected,.theme-cardtable .Button--selected--translucent{background-color:#9d0808;color:#fff;transition:color .2s,background-color .2s}.theme-cardtable .Button--selected:hover,.theme-cardtable .Button--selected--translucent:hover{background-color:#c11919;color:#fff}.theme-cardtable .Divider--horizontal{margin:.5em 0}.theme-cardtable .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-cardtable .Divider--vertical{height:100%;margin:0 .5em}.theme-cardtable .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-cardtable .color__default{background-color:rgba(78,214,135,.2);color:#000;border:solid rgba(190,240,210,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-cardtable .color__default:hover{background-color:rgba(190,240,210,.2)}.theme-cardtable .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-cardtable .selected{background-color:rgba(157,8,8,.2);color:#fff;border:solid rgba(157,8,8,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-cardtable .selected:hover{background-color:rgba(229,42,42,.2)}.theme-cardtable .contentColor__default{background-color:#4bd083;color:#000;border:solid #5be695;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-cardtable .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-cardtable .contentSelected{background-color:#9d0808;color:#fff;border:solid #c11919;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-cardtable .buttonsContainerColor__default{background-color:rgba(78,214,135,.2);color:#000;border:solid rgba(190,240,210,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-cardtable .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-cardtable .ImageButton .noAction{pointer-events:none}.theme-cardtable .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-cardtable .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-cardtable .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-cardtable .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-cardtable .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-cardtable .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-cardtable .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-cardtable .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-cardtable .fluid:last-of-type{margin-bottom:0}.theme-cardtable .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-cardtable .fluid .title{font-weight:700;padding:.5em}.theme-cardtable .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-cardtable .fluid .contentFluid{padding:.5em;color:#fff}.theme-cardtable .fluid .container{flex-direction:row;flex:1}.theme-cardtable .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-cardtable .fluid .image{padding:0}.theme-cardtable .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-cardtable .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-cardtable .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-cardtable .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-cardtable .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-cardtable .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-cardtable .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:0;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-cardtable .Input--disabled{color:#777;border-color:#848484;border-color:rgba(132,132,132,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-cardtable .Input--fluid{display:block;width:auto}.theme-cardtable .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-cardtable .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-cardtable .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-cardtable .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-cardtable .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-cardtable .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-cardtable .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-cardtable .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-cardtable .NumberInput{position:relative;display:inline-block;border:.0833333333em solid #fff;border:.0833333333em solid rgba(255,255,255,.75);border-radius:0;color:#fff;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.theme-cardtable .NumberInput--fluid{display:block}.theme-cardtable .NumberInput__content{margin-left:.5em}.theme-cardtable .NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.theme-cardtable .NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #fff;background-color:#fff}.theme-cardtable .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#0a0a0a;color:#fff;text-align:right}.theme-cardtable .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:0;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-cardtable .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-cardtable .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-cardtable .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-cardtable .ProgressBar--color--default{border:.0833333333em solid #000}.theme-cardtable .ProgressBar--color--default .ProgressBar__fill{background-color:#000}.theme-cardtable .ProgressBar--color--disabled{border:1px solid #363636}.theme-cardtable .ProgressBar--color--disabled .ProgressBar__fill{background-color:#363636}.theme-cardtable .Section{position:relative;margin-bottom:.5em;background-color:#0b4b26;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-cardtable .Section:last-child{margin-bottom:0}.theme-cardtable .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #000}.theme-cardtable .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-cardtable .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-cardtable .Section__rest{position:relative}.theme-cardtable .Section__content{padding:.66em .5em}.theme-cardtable .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-cardtable .Section--fill{display:flex;flex-direction:column;height:100%}.theme-cardtable .Section--fill>.Section__rest{flex-grow:1}.theme-cardtable .Section--fill>.Section__rest>.Section__content{height:100%}.theme-cardtable .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-cardtable .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-cardtable .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-cardtable .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-cardtable .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-cardtable .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-cardtable .Section .Section:first-child{margin-top:-.5em}.theme-cardtable .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-cardtable .Section .Section .Section .Section__titleText{font-size:1em}.theme-cardtable html,.theme-cardtable body{scrollbar-color:#20d36c #0d542b}.theme-cardtable .Layout,.theme-cardtable .Layout *{scrollbar-base-color:#0d542b;scrollbar-face-color:#16914a;scrollbar-3dlight-color:#117039;scrollbar-highlight-color:#117039;scrollbar-track-color:#0d542b;scrollbar-arrow-color:#5ae695;scrollbar-shadow-color:#16914a}.theme-cardtable .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-cardtable .Layout__content--flexRow{display:flex;flex-flow:row}.theme-cardtable .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-cardtable .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-cardtable .Layout__content--noMargin{margin:0}.theme-cardtable .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#117039;background-image:linear-gradient(to bottom,#117039,#117039)}.theme-cardtable .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-cardtable .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-cardtable .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-cardtable .Window__contentPadding:after{height:0}.theme-cardtable .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-cardtable .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(39,148,85,.25);pointer-events:none}.theme-cardtable .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-cardtable .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-cardtable .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-cardtable .TitleBar{background-color:#381608;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-cardtable .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#381608;transition:color .25s,background-color .25s}.theme-cardtable .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-cardtable .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-cardtable .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-cardtable .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-cardtable .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-cardtable .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-cardtable .Button{border:.1666666667em solid #fff}.theme-changeling .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-changeling .Button:last-child{margin-right:0;margin-bottom:0}.theme-changeling .Button .fa,.theme-changeling .Button .fas,.theme-changeling .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-changeling .Button--hasContent .fa,.theme-changeling .Button--hasContent .fas,.theme-changeling .Button--hasContent .far{margin-right:.25em}.theme-changeling .Button--hasContent.Button--iconRight .fa,.theme-changeling .Button--hasContent.Button--iconRight .fas,.theme-changeling .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-changeling .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-changeling .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-changeling .Button--circular{border-radius:50%}.theme-changeling .Button--compact{padding:0 .25em;line-height:1.333em}.theme-changeling .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-changeling .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-changeling .Button--color--transparent{background-color:rgba(46,38,51,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-changeling .Button--color--transparent:hover{background-color:rgba(67,57,73,.81);color:#fff}.theme-changeling .Button--color--default{background-color:#563d6b;color:#fff;transition:color .2s,background-color .2s}.theme-changeling .Button--color--default:hover{background-color:#715589;color:#fff}.theme-changeling .Button--color--default--translucent{background-color:rgba(55,47,60,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-changeling .Button--color--default--translucent:hover{background-color:rgba(78,69,84,.5);color:#fff}.theme-changeling .Button--color--caution{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.theme-changeling .Button--color--caution:hover{background-color:#f5d523;color:#000}.theme-changeling .Button--color--caution--translucent{background-color:rgba(217,184,4,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-changeling .Button--color--caution--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.theme-changeling .Button--color--danger{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.theme-changeling .Button--color--danger:hover{background-color:#d93f3f;color:#fff}.theme-changeling .Button--color--danger--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-changeling .Button--color--danger--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.theme-changeling .Button--disabled{background-color:#999!important;color:rgba(255,255,255,.75)!important}.theme-changeling .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-changeling .Button--selected,.theme-changeling .Button--selected--translucent{background-color:#188552;color:#fff;transition:color .2s,background-color .2s}.theme-changeling .Button--selected:hover,.theme-changeling .Button--selected--translucent:hover{background-color:#2ba66d;color:#fff}.theme-changeling .Divider--horizontal{margin:.5em 0}.theme-changeling .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-changeling .Divider--vertical{height:100%;margin:0 .5em}.theme-changeling .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-changeling .color__default{background-color:rgba(103,88,114,.2);color:#fff;border:solid rgba(160,147,170,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-changeling .color__default:hover{background-color:rgba(160,147,170,.2)}.theme-changeling .disabled{background-color:rgba(99,29,29,.25)!important;border-color:rgba(99,29,29,.25)!important}.theme-changeling .selected{background-color:rgba(24,133,82,.2);color:#fff;border:solid rgba(24,133,82,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-changeling .selected:hover{background-color:rgba(62,199,135,.2)}.theme-changeling .contentColor__default{background-color:#63556e;color:#fff;border:solid #73647f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-changeling .contentDisabled{background-color:#631d1d!important;border-top:1px solid #803131!important}.theme-changeling .contentSelected{background-color:#188552;color:#fff;border:solid #2ba66d;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-changeling .buttonsContainerColor__default{background-color:rgba(103,88,114,.2);color:#fff;border:solid rgba(160,147,170,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-changeling .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-changeling .ImageButton .noAction{pointer-events:none}.theme-changeling .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-changeling .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-changeling .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-changeling .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-changeling .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-changeling .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-changeling .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-changeling .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-changeling .fluid:last-of-type{margin-bottom:0}.theme-changeling .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-changeling .fluid .title{font-weight:700;padding:.5em}.theme-changeling .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-changeling .fluid .contentFluid{padding:.5em;color:#fff}.theme-changeling .fluid .container{flex-direction:row;flex:1}.theme-changeling .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-changeling .fluid .image{padding:0}.theme-changeling .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-changeling .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-changeling .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-changeling .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-changeling .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-changeling .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-changeling .Section{position:relative;margin-bottom:.5em;background-color:#1f1922;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-changeling .Section:last-child{margin-bottom:0}.theme-changeling .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #563d6b}.theme-changeling .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-changeling .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-changeling .Section__rest{position:relative}.theme-changeling .Section__content{padding:.66em .5em}.theme-changeling .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-changeling .Section--fill{display:flex;flex-direction:column;height:100%}.theme-changeling .Section--fill>.Section__rest{flex-grow:1}.theme-changeling .Section--fill>.Section__rest>.Section__content{height:100%}.theme-changeling .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-changeling .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-changeling .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-changeling .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-changeling .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-changeling .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-changeling .Section .Section:first-child{margin-top:-.5em}.theme-changeling .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-changeling .Section .Section .Section .Section__titleText{font-size:1em}.theme-changeling .Tabs{display:flex;align-items:stretch;overflow:hidden;background-color:rgba(0,0,0,.33)}.theme-changeling .Tabs--fill{height:100%}.theme-changeling .Section .Tabs{background-color:rgba(0,0,0,0)}.theme-changeling .Section:not(.Section--fitted) .Tabs{margin:0 -.5em .5em}.theme-changeling .Section:not(.Section--fitted) .Tabs:first-child{margin-top:-.5em}.theme-changeling .Tabs--vertical{flex-direction:column;padding:.25em .25em .25em 0}.theme-changeling .Tabs--horizontal{margin-bottom:.5em;padding:.25em .25em 0}.theme-changeling .Tabs--horizontal:last-child{margin-bottom:0}.theme-changeling .Tabs__Tab{flex-grow:0}.theme-changeling .Tabs--fluid .Tabs__Tab{flex-grow:1}.theme-changeling .Tab{display:flex;align-items:center;justify-content:space-between;background-color:rgba(0,0,0,0);color:rgba(255,255,255,.5);min-height:2.25em;min-width:4em;transition:background-color 50ms ease-out}.theme-changeling .Tab:not(.Tab--selected):hover{background-color:rgba(255,255,255,.075);transition:background-color 0}.theme-changeling .Tab--selected{background-color:#563d6b;color:#e3daea}.theme-changeling .Tab__text{flex-grow:1;margin:0 .5em}.theme-changeling .Tab__left{min-width:1.5em;text-align:center;margin-left:.25em}.theme-changeling .Tab__right{min-width:1.5em;text-align:center;margin-right:.25em}.theme-changeling .Tabs--horizontal .Tab{border-top:.1666666667em solid rgba(0,0,0,0);border-bottom:.1666666667em solid rgba(0,0,0,0);border-top-left-radius:.25em;border-top-right-radius:.25em}.theme-changeling .Tabs--horizontal .Tab--selected{border-bottom:.1666666667em solid #d9cee3}.theme-changeling .Tabs--vertical .Tab{min-height:2em;border-left:.1666666667em solid rgba(0,0,0,0);border-right:.1666666667em solid rgba(0,0,0,0);border-top-right-radius:.25em;border-bottom-right-radius:.25em}.theme-changeling .Tabs--vertical .Tab--selected{border-left:.1666666667em solid #d9cee3}.theme-changeling html,.theme-changeling body{scrollbar-color:#44384b #231d26}.theme-changeling .Layout,.theme-changeling .Layout *{scrollbar-base-color:#231d26;scrollbar-face-color:#44384b;scrollbar-3dlight-color:#2e2633;scrollbar-highlight-color:#2e2633;scrollbar-track-color:#231d26;scrollbar-arrow-color:#9986a5;scrollbar-shadow-color:#44384b}.theme-changeling .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-changeling .Layout__content--flexRow{display:flex;flex-flow:row}.theme-changeling .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-changeling .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-changeling .Layout__content--noMargin{margin:0}.theme-changeling .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#2e2633;background-image:linear-gradient(to bottom,#3e3345,#1e1921)}.theme-changeling .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-changeling .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-changeling .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-changeling .Window__contentPadding:after{height:0}.theme-changeling .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-changeling .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(72,63,78,.25);pointer-events:none}.theme-changeling .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-changeling .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-changeling .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-changeling .TitleBar{background-color:#352d3b;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-changeling .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#352d3b;transition:color .25s,background-color .25s}.theme-changeling .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-changeling .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-changeling .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-changeling .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-changeling .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-changeling .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-changeling .Layout__content{background-image:none}.theme-hackerman .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-hackerman .Button:last-child{margin-right:0;margin-bottom:0}.theme-hackerman .Button .fa,.theme-hackerman .Button .fas,.theme-hackerman .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-hackerman .Button--hasContent .fa,.theme-hackerman .Button--hasContent .fas,.theme-hackerman .Button--hasContent .far{margin-right:.25em}.theme-hackerman .Button--hasContent.Button--iconRight .fa,.theme-hackerman .Button--hasContent.Button--iconRight .fas,.theme-hackerman .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-hackerman .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-hackerman .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-hackerman .Button--circular{border-radius:50%}.theme-hackerman .Button--compact{padding:0 .25em;line-height:1.333em}.theme-hackerman .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-hackerman .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-hackerman .Button--color--transparent{background-color:rgba(18,27,18,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hackerman .Button--color--transparent:hover{background-color:rgba(34,44,34,.81);color:#fff}.theme-hackerman .Button--color--default{background-color:#0f0;color:#000;transition:color .2s,background-color .2s}.theme-hackerman .Button--color--default:hover{background-color:#40ff40;color:#000}.theme-hackerman .Button--color--default--translucent{background-color:rgba(26,35,26,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hackerman .Button--color--default--translucent:hover{background-color:rgba(46,56,46,.5);color:#fff}.theme-hackerman .Button--color--caution{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.theme-hackerman .Button--color--caution:hover{background-color:#f5d523;color:#000}.theme-hackerman .Button--color--caution--translucent{background-color:rgba(217,184,4,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hackerman .Button--color--caution--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.theme-hackerman .Button--color--danger{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.theme-hackerman .Button--color--danger:hover{background-color:#d93f3f;color:#fff}.theme-hackerman .Button--color--danger--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hackerman .Button--color--danger--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.theme-hackerman .Button--disabled{background-color:#363636!important;color:rgba(255,255,255,.75)!important}.theme-hackerman .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-hackerman .Button--selected,.theme-hackerman .Button--selected--translucent{background-color:#0f0;color:#000;transition:color .2s,background-color .2s}.theme-hackerman .Button--selected:hover,.theme-hackerman .Button--selected--translucent:hover{background-color:#40ff40;color:#000}.theme-hackerman .Divider--horizontal{margin:.5em 0}.theme-hackerman .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-hackerman .Divider--vertical{height:100%;margin:0 .5em}.theme-hackerman .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-hackerman .color__default{background-color:rgba(54,236,54,.2);color:#000;border:solid rgba(178,248,178,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-hackerman .color__default:hover{background-color:rgba(178,248,178,.2)}.theme-hackerman .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-hackerman .selected{background-color:rgba(128,255,128,.2);color:#000;border:solid rgba(128,255,128,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-hackerman .selected:hover{background-color:rgba(239,255,239,.2)}.theme-hackerman .contentColor__default{background-color:#33e633;color:#000;border:solid #40ff40;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-hackerman .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-hackerman .contentSelected{background-color:#80ff80;color:#000;border:solid #cfffcf;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-hackerman .buttonsContainerColor__default{background-color:rgba(54,236,54,.2);color:#000;border:solid rgba(178,248,178,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-hackerman .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-hackerman .ImageButton .noAction{pointer-events:none}.theme-hackerman .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-hackerman .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-hackerman .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-hackerman .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-hackerman .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-hackerman .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-hackerman .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-hackerman .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-hackerman .fluid:last-of-type{margin-bottom:0}.theme-hackerman .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-hackerman .fluid .title{font-weight:700;padding:.5em}.theme-hackerman .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-hackerman .fluid .contentFluid{padding:.5em;color:#fff}.theme-hackerman .fluid .container{flex-direction:row;flex:1}.theme-hackerman .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-hackerman .fluid .image{padding:0}.theme-hackerman .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-hackerman .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-hackerman .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-hackerman .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-hackerman .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-hackerman .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-hackerman .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid lime;border:.0833333333em solid rgba(0,255,0,.75);border-radius:.16em;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-hackerman .Input--disabled{color:#777;border-color:#404040;border-color:rgba(64,64,64,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-hackerman .Input--fluid{display:block;width:auto}.theme-hackerman .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-hackerman .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-hackerman .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hackerman .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hackerman .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-hackerman .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hackerman .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hackerman .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-hackerman .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:.16em;background-color:rgba(0,0,0,0);transition:border-color .5s}.theme-hackerman .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-hackerman .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-hackerman .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-hackerman .ProgressBar--color--default{border:.0833333333em solid #00d900}.theme-hackerman .ProgressBar--color--default .ProgressBar__fill{background-color:#00d900}.theme-hackerman .ProgressBar--color--disabled{border:1px solid #363636}.theme-hackerman .ProgressBar--color--disabled .ProgressBar__fill{background-color:#363636}.theme-hackerman .Modal{background-color:#121b12;max-width:calc(100% - 1rem);padding:1rem;scrollbar-base-color:#0e140e;scrollbar-face-color:#253725;scrollbar-3dlight-color:#121b12;scrollbar-highlight-color:#121b12;scrollbar-track-color:#0e140e;scrollbar-arrow-color:#74a274;scrollbar-shadow-color:#253725}.theme-hackerman .Section{position:relative;margin-bottom:.5em;background-color:#0c120c;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-hackerman .Section:last-child{margin-bottom:0}.theme-hackerman .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid lime}.theme-hackerman .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-hackerman .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-hackerman .Section__rest{position:relative}.theme-hackerman .Section__content{padding:.66em .5em}.theme-hackerman .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-hackerman .Section--fill{display:flex;flex-direction:column;height:100%}.theme-hackerman .Section--fill>.Section__rest{flex-grow:1}.theme-hackerman .Section--fill>.Section__rest>.Section__content{height:100%}.theme-hackerman .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-hackerman .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-hackerman .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-hackerman .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-hackerman .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-hackerman .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-hackerman .Section .Section:first-child{margin-top:-.5em}.theme-hackerman .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-hackerman .Section .Section .Section .Section__titleText{font-size:1em}.theme-hackerman html,.theme-hackerman body{scrollbar-color:#253725 #0e140e}.theme-hackerman .Layout,.theme-hackerman .Layout *{scrollbar-base-color:#0e140e;scrollbar-face-color:#253725;scrollbar-3dlight-color:#121b12;scrollbar-highlight-color:#121b12;scrollbar-track-color:#0e140e;scrollbar-arrow-color:#74a274;scrollbar-shadow-color:#253725}.theme-hackerman .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-hackerman .Layout__content--flexRow{display:flex;flex-flow:row}.theme-hackerman .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-hackerman .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-hackerman .Layout__content--noMargin{margin:0}.theme-hackerman .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#121b12;background-image:linear-gradient(to bottom,#121b12,#121b12)}.theme-hackerman .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-hackerman .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-hackerman .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-hackerman .Window__contentPadding:after{height:0}.theme-hackerman .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-hackerman .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(40,50,40,.25);pointer-events:none}.theme-hackerman .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-hackerman .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-hackerman .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-hackerman .TitleBar{background-color:#223d22;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-hackerman .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#223d22;transition:color .25s,background-color .25s}.theme-hackerman .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-hackerman .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-hackerman .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-hackerman .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-hackerman .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-hackerman .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-hackerman .Layout__content{background-image:none}.theme-hackerman .Button{font-family:monospace;border-width:.1666666667em;border-style:outset;border-color:#0a0;outline:.0833333333em solid #007a00}.theme-hackerman .candystripe:nth-child(odd){background-color:rgba(0,100,0,.5)}.theme-hydroponics .color-label{color:#8bb08b!important}.theme-hydroponics .color-bg-good{background-color:#4d9121!important}.theme-hydroponics .color-border-label{border-color:#8bb08b!important}.theme-hydroponics .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-hydroponics .Button:last-child{margin-right:0;margin-bottom:0}.theme-hydroponics .Button .fa,.theme-hydroponics .Button .fas,.theme-hydroponics .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-hydroponics .Button--hasContent .fa,.theme-hydroponics .Button--hasContent .fas,.theme-hydroponics .Button--hasContent .far{margin-right:.25em}.theme-hydroponics .Button--hasContent.Button--iconRight .fa,.theme-hydroponics .Button--hasContent.Button--iconRight .fas,.theme-hydroponics .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-hydroponics .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-hydroponics .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-hydroponics .Button--circular{border-radius:50%}.theme-hydroponics .Button--compact{padding:0 .25em;line-height:1.333em}.theme-hydroponics .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-hydroponics .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-hydroponics .Button--color--good{background-color:#4d9121;color:#fff;transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--good:hover{background-color:#67b335;color:#fff}.theme-hydroponics .Button--color--good--translucent{background-color:rgba(77,145,33,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--good--translucent:hover{background-color:rgba(103,179,53,.5);color:#fff}.theme-hydroponics .Button--color--transparent{background-color:rgba(37,37,37,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--transparent:hover{background-color:rgba(56,56,56,.81);color:#fff}.theme-hydroponics .Button--color--default{background-color:#49a149;color:#fff;transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--default:hover{background-color:#6dbb6d;color:#fff}.theme-hydroponics .Button--color--default--translucent{background-color:rgba(46,46,46,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--default--translucent:hover{background-color:rgba(68,68,68,.5);color:#fff}.theme-hydroponics .Button--color--caution{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--caution:hover{background-color:#f5d523;color:#000}.theme-hydroponics .Button--color--caution--translucent{background-color:rgba(217,184,4,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--caution--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.theme-hydroponics .Button--color--danger{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--danger:hover{background-color:#d93f3f;color:#fff}.theme-hydroponics .Button--color--danger--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--danger--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.theme-hydroponics .Button--disabled{background-color:#999!important;color:rgba(255,255,255,.75)!important}.theme-hydroponics .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-hydroponics .Button--selected,.theme-hydroponics .Button--selected--translucent{background-color:#1b9638;color:#fff;transition:color .2s,background-color .2s}.theme-hydroponics .Button--selected:hover,.theme-hydroponics .Button--selected--translucent:hover{background-color:#2fb94f;color:#fff}.theme-hydroponics .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #8f8;border:.0833333333em solid rgba(136,255,136,.75);border-radius:.16em;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-hydroponics .Input--disabled{color:#777;border-color:#848484;border-color:rgba(132,132,132,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-hydroponics .Input--fluid{display:block;width:auto}.theme-hydroponics .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-hydroponics .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-hydroponics .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hydroponics .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hydroponics .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-hydroponics .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hydroponics .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hydroponics .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-hydroponics .NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:700;font-style:italic;color:#000;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,transparent,transparent .8333333333em,rgba(0,0,0,.1) .8333333333em,rgba(0,0,0,.1) 1.6666666667em)}.theme-hydroponics .NoticeBox--color--good{color:#fff;background-color:#2e4b1a}.theme-hydroponics .NoticeBox--type--info{color:#000;background-color:#238223}.theme-hydroponics .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-hydroponics .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-hydroponics .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-hydroponics .Section{position:relative;margin-bottom:.5em;background-color:#191919;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-hydroponics .Section:last-child{margin-bottom:0}.theme-hydroponics .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #49a149}.theme-hydroponics .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-hydroponics .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-hydroponics .Section__rest{position:relative}.theme-hydroponics .Section__content{padding:.66em .5em}.theme-hydroponics .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-hydroponics .Section--fill{display:flex;flex-direction:column;height:100%}.theme-hydroponics .Section--fill>.Section__rest{flex-grow:1}.theme-hydroponics .Section--fill>.Section__rest>.Section__content{height:100%}.theme-hydroponics .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-hydroponics .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-hydroponics .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-hydroponics .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-hydroponics .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-hydroponics .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-hydroponics .Section .Section:first-child{margin-top:-.5em}.theme-hydroponics .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-hydroponics .Section .Section .Section .Section__titleText{font-size:1em}.theme-hydroponics .Newscaster__menu{width:40px;height:100%;margin-right:.5rem;flex-basis:content}.theme-hydroponics .Newscaster__menu .Section__content{padding-left:0}.theme-hydroponics .Newscaster__menuButton{color:#767676;cursor:pointer;position:relative;margin-left:6px;margin-right:1rem;white-space:nowrap;transition:color .1s}.theme-hydroponics .Newscaster__menuButton--title{width:80%;display:none;overflow:hidden;text-overflow:ellipsis}.theme-hydroponics .Newscaster__menuButton--unread{background-color:#e45e5e;color:#fff;font-size:10px;text-align:center;border-radius:32px;display:inline-block;width:12px;position:absolute;left:16px;margin-top:14px}.theme-hydroponics .Newscaster__menuButton--selected{color:#fff}.theme-hydroponics .Newscaster__menuButton--selected:after{content:"";background-color:#49a149;width:2px;height:24px;position:absolute;left:-6px}.theme-hydroponics .Newscaster__menuButton--security{color:#49a149}.theme-hydroponics .Newscaster__menuButton i{width:30px;text-align:center;vertical-align:middle;margin-left:-1px;margin-right:.5rem;margin-top:1px}.theme-hydroponics .Newscaster__menuButton:hover{color:#fff}.theme-hydroponics .Newscaster__menuButton:hover:before{background-color:#fff}.theme-hydroponics .Newscaster__menuButton:not(:last-of-type){margin-bottom:.5rem}.theme-hydroponics .Newscaster__menu--open{width:175px}.theme-hydroponics .Newscaster__menu--open .Newscaster__menuButton--title{display:inline-block}.theme-hydroponics .Newscaster__jobCategory--security .Section__title{color:#a14c49;border-bottom:2px solid #a14c49!important}.theme-hydroponics .Newscaster__jobCategory--engineering .Section__title{color:#a17849;border-bottom:2px solid #a17849!important}.theme-hydroponics .Newscaster__jobCategory--medical .Section__title{color:#499ea1;border-bottom:2px solid #499ea1!important}.theme-hydroponics .Newscaster__jobCategory--science .Section__title{color:#a14972;border-bottom:2px solid #a14972!important}.theme-hydroponics .Newscaster__jobCategory--service .Section__title{color:#a1499e;border-bottom:2px solid #a1499e!important}.theme-hydroponics .Newscaster__jobCategory--supply .Section__title{color:#9ea149;border-bottom:2px solid #9ea149!important}.theme-hydroponics .Newscaster__jobCategory:last-child{margin-bottom:.5rem}.theme-hydroponics .Newscaster__jobOpening--command{font-weight:700}.theme-hydroponics .Newscaster__jobOpening:not(:last-child){margin-bottom:.5rem}.theme-hydroponics .Newscaster__emptyNotice{color:#7ea77e;text-align:center;position:absolute;top:50%;left:50%;transform:translateY(-50%) translate(-50%)}.theme-hydroponics .Newscaster__emptyNotice i{margin-bottom:.25rem}.theme-hydroponics .Newscaster__photo{cursor:pointer;width:100px;border:1px solid #000;transition:border-color .3s;-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.theme-hydroponics .Newscaster__photo:hover{border-color:gray}.theme-hydroponics .Newscaster__photoZoom{text-align:center}.theme-hydroponics .Newscaster__photoZoom>img{transform:scale(2);-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.theme-hydroponics .Newscaster__photoZoom>.Button{position:absolute;width:64px;left:50%;margin-left:-32px;bottom:1rem}.theme-hydroponics .Newscaster__story--wanted{background-color:rgba(219,40,40,.1)}.theme-hydroponics .Newscaster__story--wanted .Section__title{color:#db2828;border-bottom:2px solid #a14c49!important}.theme-hydroponics .Newscaster__story:last-child{margin-bottom:.5rem}.theme-malfunction .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-malfunction .Button:last-child{margin-right:0;margin-bottom:0}.theme-malfunction .Button .fa,.theme-malfunction .Button .fas,.theme-malfunction .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-malfunction .Button--hasContent .fa,.theme-malfunction .Button--hasContent .fas,.theme-malfunction .Button--hasContent .far{margin-right:.25em}.theme-malfunction .Button--hasContent.Button--iconRight .fa,.theme-malfunction .Button--hasContent.Button--iconRight .fas,.theme-malfunction .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-malfunction .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-malfunction .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-malfunction .Button--circular{border-radius:50%}.theme-malfunction .Button--compact{padding:0 .25em;line-height:1.333em}.theme-malfunction .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-malfunction .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-malfunction .Button--color--transparent{background-color:rgba(27,52,67,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-malfunction .Button--color--transparent:hover{background-color:rgba(44,74,92,.81);color:#fff}.theme-malfunction .Button--color--default{background-color:#910101;color:#fff;transition:color .2s,background-color .2s}.theme-malfunction .Button--color--default:hover{background-color:#b31111;color:#fff}.theme-malfunction .Button--color--default--translucent{background-color:rgba(35,61,77,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-malfunction .Button--color--default--translucent:hover{background-color:rgba(56,85,103,.5);color:#fff}.theme-malfunction .Button--color--caution{background-color:#be6209;color:#fff;transition:color .2s,background-color .2s}.theme-malfunction .Button--color--caution:hover{background-color:#e67f1a;color:#fff}.theme-malfunction .Button--color--caution--translucent{background-color:rgba(190,98,9,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-malfunction .Button--color--caution--translucent:hover{background-color:rgba(230,127,26,.5);color:#fff}.theme-malfunction .Button--color--danger{background-color:#9a9d00;color:#fff;transition:color .2s,background-color .2s}.theme-malfunction .Button--color--danger:hover{background-color:#bec110;color:#fff}.theme-malfunction .Button--color--danger--translucent{background-color:rgba(154,157,0,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-malfunction .Button--color--danger--translucent:hover{background-color:rgba(190,193,16,.5);color:#fff}.theme-malfunction .Button--disabled{background-color:#363636!important;color:rgba(255,255,255,.75)!important}.theme-malfunction .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-malfunction .Button--selected,.theme-malfunction .Button--selected--translucent{background-color:#1e5881;color:#fff;transition:color .2s,background-color .2s}.theme-malfunction .Button--selected:hover,.theme-malfunction .Button--selected--translucent:hover{background-color:#3273a1;color:#fff}.theme-malfunction .Divider--horizontal{margin:.5em 0}.theme-malfunction .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-malfunction .Divider--vertical{height:100%;margin:0 .5em}.theme-malfunction .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-malfunction .color__default{background-color:rgba(117,55,55,.2);color:#fff;border:solid rgba(177,102,102,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-malfunction .color__default:hover{background-color:rgba(177,102,102,.2)}.theme-malfunction .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-malfunction .selected{background-color:rgba(30,88,129,.2);color:#fff;border:solid rgba(30,88,129,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-malfunction .selected:hover{background-color:rgba(70,142,194,.2)}.theme-malfunction .contentColor__default{background-color:#713434;color:#fff;border:solid #814141;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-malfunction .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-malfunction .contentSelected{background-color:#1e5881;color:#fff;border:solid #3273a1;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-malfunction .buttonsContainerColor__default{background-color:rgba(117,55,55,.2);color:#fff;border:solid rgba(177,102,102,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-malfunction .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-malfunction .ImageButton .noAction{pointer-events:none}.theme-malfunction .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-malfunction .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-malfunction .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-malfunction .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-malfunction .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-malfunction .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-malfunction .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-malfunction .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-malfunction .fluid:last-of-type{margin-bottom:0}.theme-malfunction .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-malfunction .fluid .title{font-weight:700;padding:.5em}.theme-malfunction .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-malfunction .fluid .contentFluid{padding:.5em;color:#fff}.theme-malfunction .fluid .container{flex-direction:row;flex:1}.theme-malfunction .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-malfunction .fluid .image{padding:0}.theme-malfunction .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-malfunction .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-malfunction .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-malfunction .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-malfunction .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-malfunction .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-malfunction .NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:700;font-style:italic;color:#fff;background-color:#1a3f57;background-image:repeating-linear-gradient(-45deg,transparent,transparent .8333333333em,rgba(0,0,0,.1) .8333333333em,rgba(0,0,0,.1) 1.6666666667em)}.theme-malfunction .NoticeBox--type--info{color:#fff;background-color:#235982}.theme-malfunction .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-malfunction .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-malfunction .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-malfunction .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #910101;border:.0833333333em solid rgba(145,1,1,.75);border-radius:.16em;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-malfunction .Input--disabled{color:#777;border-color:#090909;border-color:rgba(9,9,9,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-malfunction .Input--fluid{display:block;width:auto}.theme-malfunction .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-malfunction .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-malfunction .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-malfunction .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-malfunction .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-malfunction .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-malfunction .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-malfunction .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-malfunction .NumberInput{position:relative;display:inline-block;border:.0833333333em solid #910101;border:.0833333333em solid rgba(145,1,1,.75);border-radius:.16em;color:#910101;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.theme-malfunction .NumberInput--fluid{display:block}.theme-malfunction .NumberInput__content{margin-left:.5em}.theme-malfunction .NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.theme-malfunction .NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #910101;background-color:#910101}.theme-malfunction .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#0a0a0a;color:#fff;text-align:right}.theme-malfunction .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:.16em;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-malfunction .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-malfunction .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-malfunction .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-malfunction .ProgressBar--color--default{border:.0833333333em solid #7b0101}.theme-malfunction .ProgressBar--color--default .ProgressBar__fill{background-color:#7b0101}.theme-malfunction .ProgressBar--color--disabled{border:1px solid #363636}.theme-malfunction .ProgressBar--color--disabled .ProgressBar__fill{background-color:#363636}.theme-malfunction .Section{position:relative;margin-bottom:.5em;background-color:#12232d;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-malfunction .Section:last-child{margin-bottom:0}.theme-malfunction .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #910101}.theme-malfunction .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-malfunction .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-malfunction .Section__rest{position:relative}.theme-malfunction .Section__content{padding:.66em .5em}.theme-malfunction .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-malfunction .Section--fill{display:flex;flex-direction:column;height:100%}.theme-malfunction .Section--fill>.Section__rest{flex-grow:1}.theme-malfunction .Section--fill>.Section__rest>.Section__content{height:100%}.theme-malfunction .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-malfunction .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-malfunction .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-malfunction .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-malfunction .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-malfunction .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-malfunction .Section .Section:first-child{margin-top:-.5em}.theme-malfunction .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-malfunction .Section .Section .Section .Section__titleText{font-size:1em}.theme-malfunction .Tooltip{z-index:999;padding:.5em .75em;pointer-events:none;text-align:left;transition:opacity .15s ease-out;background-color:#235577;color:#fff;box-shadow:.1em .1em 1.25em -.1em rgba(0,0,0,.5);border-radius:.16em;max-width:20.8333333333em}.theme-malfunction html,.theme-malfunction body{scrollbar-color:#274b61 #142732}.theme-malfunction .Layout,.theme-malfunction .Layout *{scrollbar-base-color:#142732;scrollbar-face-color:#274b61;scrollbar-3dlight-color:#1b3443;scrollbar-highlight-color:#1b3443;scrollbar-track-color:#142732;scrollbar-arrow-color:#6ba2c3;scrollbar-shadow-color:#274b61}.theme-malfunction .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-malfunction .Layout__content--flexRow{display:flex;flex-flow:row}.theme-malfunction .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-malfunction .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-malfunction .Layout__content--noMargin{margin:0}.theme-malfunction .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#1b3443;background-image:linear-gradient(to bottom,#244559,#12232d)}.theme-malfunction .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-malfunction .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-malfunction .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-malfunction .Window__contentPadding:after{height:0}.theme-malfunction .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-malfunction .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(50,79,96,.25);pointer-events:none}.theme-malfunction .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-malfunction .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-malfunction .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-malfunction .TitleBar{background-color:#1a3f57;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-malfunction .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#1a3f57;transition:color .25s,background-color .25s}.theme-malfunction .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-malfunction .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-malfunction .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-malfunction .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-malfunction .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-malfunction .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-malfunction .Layout__content{background-image:none}.theme-ntos .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-ntos .Button:last-child{margin-right:0;margin-bottom:0}.theme-ntos .Button .fa,.theme-ntos .Button .fas,.theme-ntos .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-ntos .Button--hasContent .fa,.theme-ntos .Button--hasContent .fas,.theme-ntos .Button--hasContent .far{margin-right:.25em}.theme-ntos .Button--hasContent.Button--iconRight .fa,.theme-ntos .Button--hasContent.Button--iconRight .fas,.theme-ntos .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-ntos .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-ntos .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-ntos .Button--circular{border-radius:50%}.theme-ntos .Button--compact{padding:0 .25em;line-height:1.333em}.theme-ntos .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-ntos .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-ntos .Button--color--transparent{background-color:rgba(31,43,57,0);color:rgba(227,240,255,.75);transition:color .2s,background-color .2s}.theme-ntos .Button--color--transparent:hover{background-color:rgba(49,63,80,.81);color:#fff}.theme-ntos .Button--color--default{background-color:#384e68;color:#fff;transition:color .2s,background-color .2s}.theme-ntos .Button--color--default:hover{background-color:#4f6885;color:#fff}.theme-ntos .Button--color--default--translucent{background-color:rgba(39,51,67,.33);color:rgba(227,240,255,.75);transition:color .2s,background-color .2s}.theme-ntos .Button--color--default--translucent:hover{background-color:rgba(60,74,92,.5);color:#fff}.theme-ntos .Button--color--caution{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.theme-ntos .Button--color--caution:hover{background-color:#f5d523;color:#000}.theme-ntos .Button--color--caution--translucent{background-color:rgba(217,184,4,.33);color:rgba(227,240,255,.75);transition:color .2s,background-color .2s}.theme-ntos .Button--color--caution--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.theme-ntos .Button--color--danger{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.theme-ntos .Button--color--danger:hover{background-color:#d93f3f;color:#fff}.theme-ntos .Button--color--danger--translucent{background-color:rgba(189,32,32,.33);color:rgba(227,240,255,.75);transition:color .2s,background-color .2s}.theme-ntos .Button--color--danger--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.theme-ntos .Button--disabled{background-color:#999!important;color:rgba(227,240,255,.75)!important}.theme-ntos .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(227,240,255,.75)!important}.theme-ntos .Button--selected,.theme-ntos .Button--selected--translucent{background-color:#1b9638;color:#fff;transition:color .2s,background-color .2s}.theme-ntos .Button--selected:hover,.theme-ntos .Button--selected--translucent:hover{background-color:#2fb94f;color:#fff}.theme-ntos .Divider--horizontal{margin:.5em 0}.theme-ntos .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-ntos .Divider--vertical{height:100%;margin:0 .5em}.theme-ntos .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-ntos .color__default{background-color:rgba(96,112,131,.2);color:#fff;border:solid rgba(162,173,186,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-ntos .color__default:hover{background-color:rgba(162,173,186,.2)}.theme-ntos .disabled{background-color:rgba(99,29,29,.25)!important;border-color:rgba(99,29,29,.25)!important}.theme-ntos .selected{background-color:rgba(27,150,56,.2);color:#fff;border:solid rgba(27,150,56,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-ntos .selected:hover{background-color:rgba(72,214,105,.2)}.theme-ntos .contentColor__default{background-color:#5c6c7f;color:#fff;border:solid #6b7d92;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-ntos .contentDisabled{background-color:#631d1d!important;border-top:1px solid #803131!important}.theme-ntos .contentSelected{background-color:#1b9638;color:#fff;border:solid #2fb94f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-ntos .buttonsContainerColor__default{background-color:rgba(96,112,131,.2);color:#fff;border:solid rgba(162,173,186,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-ntos .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-ntos .ImageButton .noAction{pointer-events:none}.theme-ntos .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-ntos .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-ntos .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-ntos .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-ntos .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-ntos .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-ntos .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-ntos .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-ntos .fluid:last-of-type{margin-bottom:0}.theme-ntos .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-ntos .fluid .title{font-weight:700;padding:.5em}.theme-ntos .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-ntos .fluid .contentFluid{padding:.5em;color:#fff}.theme-ntos .fluid .container{flex-direction:row;flex:1}.theme-ntos .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-ntos .fluid .image{padding:0}.theme-ntos .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-ntos .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-ntos .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-ntos .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-ntos .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-ntos .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-ntos .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:.16em;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-ntos .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-ntos .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-ntos .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-ntos .ProgressBar--color--default{border:.0833333333em solid #384e68}.theme-ntos .ProgressBar--color--default .ProgressBar__fill{background-color:#384e68}.theme-ntos .ProgressBar--color--disabled{border:1px solid #999}.theme-ntos .ProgressBar--color--disabled .ProgressBar__fill{background-color:#999}.theme-ntos .Section{position:relative;margin-bottom:.5em;background-color:#151d26;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-ntos .Section:last-child{margin-bottom:0}.theme-ntos .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #4972a1}.theme-ntos .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-ntos .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-ntos .Section__rest{position:relative}.theme-ntos .Section__content{padding:.66em .5em}.theme-ntos .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-ntos .Section--fill{display:flex;flex-direction:column;height:100%}.theme-ntos .Section--fill>.Section__rest{flex-grow:1}.theme-ntos .Section--fill>.Section__rest>.Section__content{height:100%}.theme-ntos .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-ntos .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-ntos .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-ntos .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-ntos .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-ntos .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-ntos .Section .Section:first-child{margin-top:-.5em}.theme-ntos .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-ntos .Section .Section .Section .Section__titleText{font-size:1em}.theme-ntos html,.theme-ntos body{scrollbar-color:#2e3f55 #17202b}.theme-ntos .Layout,.theme-ntos .Layout *{scrollbar-base-color:#17202b;scrollbar-face-color:#2e3f55;scrollbar-3dlight-color:#1f2b39;scrollbar-highlight-color:#1f2b39;scrollbar-track-color:#17202b;scrollbar-arrow-color:#7693b5;scrollbar-shadow-color:#2e3f55}.theme-ntos .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-ntos .Layout__content--flexRow{display:flex;flex-flow:row}.theme-ntos .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-ntos .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-ntos .Layout__content--noMargin{margin:0}.theme-ntos .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#1f2b39;background-image:linear-gradient(to bottom,#223040,#1b2633)}.theme-ntos .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-ntos .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-ntos .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-ntos .Window__contentPadding:after{height:0}.theme-ntos .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-ntos .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(55,69,85,.25);pointer-events:none}.theme-ntos .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-ntos .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-ntos .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-ntos .TitleBar{background-color:#2a3b4e;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-ntos .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#2a3b4e;transition:color .25s,background-color .25s}.theme-ntos .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-ntos .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-ntos .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-ntos .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-ntos .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-ntos .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-paper .Tabs{display:flex;align-items:stretch;overflow:hidden;background-color:rgba(0,0,0,.33)}.theme-paper .Tabs--fill{height:100%}.theme-paper .Section .Tabs{background-color:rgba(0,0,0,0)}.theme-paper .Section:not(.Section--fitted) .Tabs{margin:0 -.5em .5em}.theme-paper .Section:not(.Section--fitted) .Tabs:first-child{margin-top:-.5em}.theme-paper .Tabs--vertical{flex-direction:column;padding:.25em .25em .25em 0}.theme-paper .Tabs--horizontal{margin-bottom:.5em;padding:.25em .25em 0}.theme-paper .Tabs--horizontal:last-child{margin-bottom:0}.theme-paper .Tabs__Tab{flex-grow:0}.theme-paper .Tabs--fluid .Tabs__Tab{flex-grow:1}.theme-paper .Tab{display:flex;align-items:center;justify-content:space-between;background-color:rgba(0,0,0,0);color:rgba(255,255,255,.5);min-height:2.25em;min-width:4em;transition:background-color 50ms ease-out}.theme-paper .Tab:not(.Tab--selected):hover{background-color:rgba(255,255,255,.075);transition:background-color 0}.theme-paper .Tab--selected{background-color:rgba(255,255,255,.125);color:#fafafa}.theme-paper .Tab__text{flex-grow:1;margin:0 .5em}.theme-paper .Tab__left{min-width:1.5em;text-align:center;margin-left:.25em}.theme-paper .Tab__right{min-width:1.5em;text-align:center;margin-right:.25em}.theme-paper .Tabs--horizontal .Tab{border-top:.1666666667em solid rgba(0,0,0,0);border-bottom:.1666666667em solid rgba(0,0,0,0);border-top-left-radius:.25em;border-top-right-radius:.25em}.theme-paper .Tabs--horizontal .Tab--selected{border-bottom:.1666666667em solid #f9f9f9}.theme-paper .Tabs--vertical .Tab{min-height:2em;border-left:.1666666667em solid rgba(0,0,0,0);border-right:.1666666667em solid rgba(0,0,0,0);border-top-right-radius:.25em;border-bottom-right-radius:.25em}.theme-paper .Tabs--vertical .Tab--selected{border-left:.1666666667em solid #f9f9f9}.theme-paper .Section{position:relative;margin-bottom:.5em;background-color:#e6e6e6;background-color:rgba(0,0,0,.1);box-sizing:border-box}.theme-paper .Section:last-child{margin-bottom:0}.theme-paper .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #fff}.theme-paper .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#000}.theme-paper .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-paper .Section__rest{position:relative}.theme-paper .Section__content{padding:.66em .5em}.theme-paper .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-paper .Section--fill{display:flex;flex-direction:column;height:100%}.theme-paper .Section--fill>.Section__rest{flex-grow:1}.theme-paper .Section--fill>.Section__rest>.Section__content{height:100%}.theme-paper .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-paper .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-paper .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-paper .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-paper .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-paper .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-paper .Section .Section:first-child{margin-top:-.5em}.theme-paper .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-paper .Section .Section .Section .Section__titleText{font-size:1em}.theme-paper .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-paper .Button:last-child{margin-right:0;margin-bottom:0}.theme-paper .Button .fa,.theme-paper .Button .fas,.theme-paper .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-paper .Button--hasContent .fa,.theme-paper .Button--hasContent .fas,.theme-paper .Button--hasContent .far{margin-right:.25em}.theme-paper .Button--hasContent.Button--iconRight .fa,.theme-paper .Button--hasContent.Button--iconRight .fas,.theme-paper .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-paper .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-paper .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-paper .Button--circular{border-radius:50%}.theme-paper .Button--compact{padding:0 .25em;line-height:1.333em}.theme-paper .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-paper .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-paper .Button--color--transparent{background-color:rgba(255,255,255,0);color:rgba(0,0,0,.5);transition:color .2s,background-color .2s}.theme-paper .Button--color--transparent:hover{background-color:rgba(255,255,255,.81);color:#000}.theme-paper .Button--color--default{background-color:#e8e4c9;color:#000;transition:color .2s,background-color .2s}.theme-paper .Button--color--default:hover{background-color:#fbfaf5;color:#000}.theme-paper .Button--color--default--translucent{background-color:rgba(255,255,255,.33);color:rgba(0,0,0,.5);transition:color .2s,background-color .2s}.theme-paper .Button--color--default--translucent:hover{background-color:rgba(255,255,255,.5);color:#fff}.theme-paper .Button--color--caution{background-color:#be6209;color:#fff;transition:color .2s,background-color .2s}.theme-paper .Button--color--caution:hover{background-color:#e67f1a;color:#fff}.theme-paper .Button--color--caution--translucent{background-color:rgba(190,98,9,.33);color:rgba(0,0,0,.5);transition:color .2s,background-color .2s}.theme-paper .Button--color--caution--translucent:hover{background-color:rgba(230,127,26,.5);color:#fff}.theme-paper .Button--color--danger{background-color:#9a9d00;color:#fff;transition:color .2s,background-color .2s}.theme-paper .Button--color--danger:hover{background-color:#bec110;color:#fff}.theme-paper .Button--color--danger--translucent{background-color:rgba(154,157,0,.33);color:rgba(0,0,0,.5);transition:color .2s,background-color .2s}.theme-paper .Button--color--danger--translucent:hover{background-color:rgba(190,193,16,.5);color:#fff}.theme-paper .Button--disabled{background-color:#363636!important;color:rgba(0,0,0,.75)!important}.theme-paper .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(0,0,0,.5)!important}.theme-paper .Button--selected,.theme-paper .Button--selected--translucent{background-color:#9d0808;color:#fff;transition:color .2s,background-color .2s}.theme-paper .Button--selected:hover,.theme-paper .Button--selected--translucent:hover{background-color:#c11919;color:#fff}.theme-paper .Divider--horizontal{margin:.5em 0}.theme-paper .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-paper .Divider--vertical{height:100%;margin:0 .5em}.theme-paper .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-paper .color__default{background-color:rgba(232,229,202,.2);color:#000;border:solid rgba(252,252,249,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-paper .color__default:hover{background-color:rgba(252,252,249,.2)}.theme-paper .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-paper .selected{background-color:rgba(157,8,8,.2);color:#fff;border:solid rgba(157,8,8,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-paper .selected:hover{background-color:rgba(229,42,42,.2)}.theme-paper .contentColor__default{background-color:#e5e0c2;color:#000;border:solid #f3f2e4;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-paper .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-paper .contentSelected{background-color:#9d0808;color:#fff;border:solid #c11919;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-paper .buttonsContainerColor__default{background-color:rgba(232,229,202,.2);color:#000;border:solid rgba(252,252,249,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-paper .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-paper .ImageButton .noAction{pointer-events:none}.theme-paper .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-paper .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-paper .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-paper .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-paper .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-paper .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-paper .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-paper .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-paper .fluid:last-of-type{margin-bottom:0}.theme-paper .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-paper .fluid .title{font-weight:700;padding:.5em}.theme-paper .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-paper .fluid .contentFluid{padding:.5em;color:#fff}.theme-paper .fluid .container{flex-direction:row;flex:1}.theme-paper .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-paper .fluid .image{padding:0}.theme-paper .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-paper .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-paper .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-paper .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-paper .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-paper .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-paper .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:.16em;background-color:rgba(0,0,0,0);transition:border-color .5s}.theme-paper .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-paper .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-paper .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-paper .ProgressBar--color--default{border:.0833333333em solid #bfbfbf}.theme-paper .ProgressBar--color--default .ProgressBar__fill{background-color:#bfbfbf}.theme-paper .ProgressBar--color--disabled{border:1px solid #363636}.theme-paper .ProgressBar--color--disabled .ProgressBar__fill{background-color:#363636}.theme-paper html,.theme-paper body{scrollbar-color:#fff #bfbfbf}.theme-paper .Layout,.theme-paper .Layout *{scrollbar-base-color:#bfbfbf;scrollbar-face-color:#fff;scrollbar-3dlight-color:#fff;scrollbar-highlight-color:#fff;scrollbar-track-color:#bfbfbf;scrollbar-arrow-color:#fff;scrollbar-shadow-color:#fff}.theme-paper .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-paper .Layout__content--flexRow{display:flex;flex-flow:row}.theme-paper .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-paper .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-paper .Layout__content--noMargin{margin:0}.theme-paper .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#000;background-color:#fff;background-image:linear-gradient(to bottom,#fff,#fff)}.theme-paper .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-paper .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-paper .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-paper .Window__contentPadding:after{height:0}.theme-paper .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-paper .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(255,255,255,.25);pointer-events:none}.theme-paper .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-paper .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-paper .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-paper .TitleBar{background-color:#fff;border-bottom:1px solid rgba(0,0,0,.25);box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-paper .TitleBar__clickable{color:rgba(0,0,0,.5);background-color:#fff;transition:color .25s,background-color .25s}.theme-paper .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-paper .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(0,0,0,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-paper .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-paper .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-paper .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-paper .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-paper .PaperInput{position:relative;display:inline-block;width:120px;border:none;background:rgba(0,0,0,0);border-bottom:1px solid #000;outline:none;background-color:rgba(255,255,62,.8);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-paper .PaperInput__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-paper .PaperInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-paper .PaperInput__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-paper .PaperInput__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-paper .Layout__content{background-image:none}.theme-paper .Window{background-image:none;color:#000}.theme-paper .paper-text input:disabled{position:relative;display:inline-block;border:none;background:rgba(0,0,0,0);border-bottom:1px solid #000;outline:none;background-color:rgba(255,255,62,.8);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-paper .paper-text input,.theme-paper .paper-field{position:relative;display:inline-block;border:none;background:rgba(0,0,0,0);border-bottom:1px solid #000;outline:none;background-color:rgba(255,255,62,.8);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-paper .paper-field input:disabled{position:relative;display:inline-block;border:none;background:rgba(0,0,0,0);border-bottom:1px solid #000;outline:none;background-color:rgba(255,255,62,.8);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-retro .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:0;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-retro .Button:last-child{margin-right:0;margin-bottom:0}.theme-retro .Button .fa,.theme-retro .Button .fas,.theme-retro .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-retro .Button--hasContent .fa,.theme-retro .Button--hasContent .fas,.theme-retro .Button--hasContent .far{margin-right:.25em}.theme-retro .Button--hasContent.Button--iconRight .fa,.theme-retro .Button--hasContent.Button--iconRight .fas,.theme-retro .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-retro .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-retro .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-retro .Button--circular{border-radius:50%}.theme-retro .Button--compact{padding:0 .25em;line-height:1.333em}.theme-retro .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-retro .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-retro .Button--color--transparent{background-color:rgba(232,228,201,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-retro .Button--color--transparent:hover{background-color:rgba(255,255,255,.81);color:#000}.theme-retro .Button--color--default{background-color:#e8e4c9;color:#000;transition:color .2s,background-color .2s}.theme-retro .Button--color--default:hover{background-color:#fbfaf5;color:#000}.theme-retro .Button--color--default--translucent{background-color:rgba(242,240,225,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-retro .Button--color--default--translucent:hover{background-color:rgba(253,252,250,.5);color:#fff}.theme-retro .Button--color--caution{background-color:#be6209;color:#fff;transition:color .2s,background-color .2s}.theme-retro .Button--color--caution:hover{background-color:#e67f1a;color:#fff}.theme-retro .Button--color--caution--translucent{background-color:rgba(190,98,9,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-retro .Button--color--caution--translucent:hover{background-color:rgba(230,127,26,.5);color:#fff}.theme-retro .Button--color--danger{background-color:#9a9d00;color:#fff;transition:color .2s,background-color .2s}.theme-retro .Button--color--danger:hover{background-color:#bec110;color:#fff}.theme-retro .Button--color--danger--translucent{background-color:rgba(154,157,0,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-retro .Button--color--danger--translucent:hover{background-color:rgba(190,193,16,.5);color:#fff}.theme-retro .Button--disabled{background-color:#363636!important;color:rgba(255,255,255,.75)!important}.theme-retro .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-retro .Button--selected,.theme-retro .Button--selected--translucent{background-color:#9d0808;color:#fff;transition:color .2s,background-color .2s}.theme-retro .Button--selected:hover,.theme-retro .Button--selected--translucent:hover{background-color:#c11919;color:#fff}.theme-retro .Divider--horizontal{margin:.5em 0}.theme-retro .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-retro .Divider--vertical{height:100%;margin:0 .5em}.theme-retro .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-retro .color__default{background-color:rgba(232,229,202,.2);color:#000;border:solid rgba(252,252,249,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-retro .color__default:hover{background-color:rgba(252,252,249,.2)}.theme-retro .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-retro .selected{background-color:rgba(157,8,8,.2);color:#fff;border:solid rgba(157,8,8,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-retro .selected:hover{background-color:rgba(229,42,42,.2)}.theme-retro .contentColor__default{background-color:#e5e0c2;color:#000;border:solid #f3f2e4;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-retro .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-retro .contentSelected{background-color:#9d0808;color:#fff;border:solid #c11919;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-retro .buttonsContainerColor__default{background-color:rgba(232,229,202,.2);color:#000;border:solid rgba(252,252,249,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-retro .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-retro .ImageButton .noAction{pointer-events:none}.theme-retro .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-retro .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-retro .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-retro .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-retro .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-retro .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-retro .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-retro .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-retro .fluid:last-of-type{margin-bottom:0}.theme-retro .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-retro .fluid .title{font-weight:700;padding:.5em}.theme-retro .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-retro .fluid .contentFluid{padding:.5em;color:#fff}.theme-retro .fluid .container{flex-direction:row;flex:1}.theme-retro .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-retro .fluid .image{padding:0}.theme-retro .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-retro .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-retro .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-retro .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-retro .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-retro .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-retro .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:0;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-retro .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-retro .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-retro .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-retro .ProgressBar--color--default{border:.0833333333em solid #000}.theme-retro .ProgressBar--color--default .ProgressBar__fill{background-color:#000}.theme-retro .ProgressBar--color--disabled{border:1px solid #999}.theme-retro .ProgressBar--color--disabled .ProgressBar__fill{background-color:#999}.theme-retro .Section{position:relative;margin-bottom:.5em;background-color:#9b9987;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-retro .Section:last-child{margin-bottom:0}.theme-retro .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #000}.theme-retro .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-retro .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-retro .Section__rest{position:relative}.theme-retro .Section__content{padding:.66em .5em}.theme-retro .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-retro .Section--fill{display:flex;flex-direction:column;height:100%}.theme-retro .Section--fill>.Section__rest{flex-grow:1}.theme-retro .Section--fill>.Section__rest>.Section__content{height:100%}.theme-retro .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-retro .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-retro .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-retro .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-retro .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-retro .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-retro .Section .Section:first-child{margin-top:-.5em}.theme-retro .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-retro .Section .Section .Section .Section__titleText{font-size:1em}.theme-retro html,.theme-retro body{scrollbar-color:#efecd9 #c8be7d}.theme-retro .Layout,.theme-retro .Layout *{scrollbar-base-color:#c8be7d;scrollbar-face-color:#eae7ce;scrollbar-3dlight-color:#e8e4c9;scrollbar-highlight-color:#e8e4c9;scrollbar-track-color:#c8be7d;scrollbar-arrow-color:#f4f2e4;scrollbar-shadow-color:#eae7ce}.theme-retro .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-retro .Layout__content--flexRow{display:flex;flex-flow:row}.theme-retro .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-retro .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-retro .Layout__content--noMargin{margin:0}.theme-retro .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#e8e4c9;background-image:linear-gradient(to bottom,#e8e4c9,#e8e4c9)}.theme-retro .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-retro .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-retro .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-retro .Window__contentPadding:after{height:0}.theme-retro .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-retro .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(251,250,246,.25);pointer-events:none}.theme-retro .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-retro .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-retro .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-retro .TitleBar{background-color:#585337;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-retro .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#585337;transition:color .25s,background-color .25s}.theme-retro .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-retro .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-retro .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-retro .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-retro .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-retro .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-retro .Button{font-family:monospace;color:#161613;border:.1666666667em outset #e8e4c9;outline:.0833333333em solid #161613}.theme-retro .Layout__content{background-image:none}.theme-safe .Section{position:relative;margin-bottom:.5em;background-color:#b2ae74;box-sizing:border-box}.theme-safe .Section:last-child{margin-bottom:0}.theme-safe .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #3d566b}.theme-safe .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-safe .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-safe .Section__rest{position:relative}.theme-safe .Section__content{padding:.66em .5em}.theme-safe .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-safe .Section--fill{display:flex;flex-direction:column;height:100%}.theme-safe .Section--fill>.Section__rest{flex-grow:1}.theme-safe .Section--fill>.Section__rest>.Section__content{height:100%}.theme-safe .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-safe .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-safe .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-safe .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-safe .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-safe .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-safe .Section .Section:first-child{margin-top:-.5em}.theme-safe .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-safe .Section .Section .Section .Section__titleText{font-size:1em}.theme-safe .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#222b3a;background-image:linear-gradient(to bottom,#242d3d,#202937)}.theme-safe .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-safe .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-safe .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-safe .Window__contentPadding:after{height:0}.theme-safe .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-safe .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(58,69,86,.25);pointer-events:none}.theme-safe .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-safe .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-safe .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-safe .TitleBar{background-color:#35435a;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-safe .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#35435a;transition:color .25s,background-color .25s}.theme-safe .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-safe .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-safe .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-safe .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-safe .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-safe .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-safe .Safe--engraving{position:absolute;width:95%;height:96%;left:2.5%;top:2%;border:5px outset #364963;padding:5px;text-align:center}.theme-safe .Safe--engraving--arrow{color:#35435a}.theme-safe .Safe--engraving--hinge{content:" ";background-color:#191f2a;width:25px;height:40px;position:absolute;right:-15px;margin-top:-20px}.theme-safe .Safe--dialer{margin-bottom:.5rem}.theme-safe .Safe--dialer--number{color:#bbb;display:inline;background-color:#191f2a;font-size:1.5rem;font-weight:700;padding:0 .5rem}.theme-safe .Safe--dialer--right .Button i{z-index:-100}.theme-safe .Safe--dialer .Button{width:80px}.theme-safe .Safe--contents{border:10px solid #191f2a;background-color:#0f131a;height:calc(85% + 7.5px);text-align:left;padding:5px}.theme-safe .Safe--help{position:absolute;bottom:30px;left:25px;width:50%}.theme-safe .Layout__content{background-image:none}.theme-safe .Section{font-family:Comic Sans MS,cursive,sans-serif;font-style:italic;color:#000;box-shadow:5px 5px #111;background-image:linear-gradient(to bottom,#b2ae74,#8e8b5d);transform:rotate(-1deg)}.theme-safe .Section__title{padding-bottom:0;border:0}.theme-safe .Section:before{content:" ";display:block;width:24px;height:40px;background-image:linear-gradient(to bottom,transparent 0%,#ffffff 100%);box-shadow:1px 1px #111;opacity:.2;position:absolute;top:-30px;left:calc(50% - 12px);transform:rotate(-5deg)}.theme-securestorage .TitleBar{background-color:#e8e4c9;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-securestorage .TitleBar__clickable{color:rgba(25,25,22,.5);background-color:#e8e4c9;transition:color .25s,background-color .25s}.theme-securestorage .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-securestorage .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:#191916;font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-securestorage .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-securestorage .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-securestorage .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-securestorage .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-securestorage html,.theme-securestorage body{scrollbar-color:#efecd9 #c8be7d}.theme-securestorage .Layout,.theme-securestorage .Layout *{scrollbar-base-color:#c8be7d;scrollbar-face-color:#eae7ce;scrollbar-3dlight-color:#e8e4c9;scrollbar-highlight-color:#e8e4c9;scrollbar-track-color:#c8be7d;scrollbar-arrow-color:#f4f2e4;scrollbar-shadow-color:#eae7ce}.theme-securestorage .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-securestorage .Layout__content--flexRow{display:flex;flex-flow:row}.theme-securestorage .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-securestorage .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-securestorage .Layout__content--noMargin{margin:0}.theme-securestorage .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#e8e4c9;background-image:linear-gradient(to bottom,#f1efde,#dfd9b4)}.theme-securestorage .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-securestorage .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-securestorage .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-securestorage .Window__contentPadding:after{height:0}.theme-securestorage .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-securestorage .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(251,250,246,.25);pointer-events:none}.theme-securestorage .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-securestorage .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-securestorage .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-securestorage .Section{position:relative;margin-bottom:.5em;background-color:#9b9987;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-securestorage .Section:last-child{margin-bottom:0}.theme-securestorage .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #397439}.theme-securestorage .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-securestorage .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-securestorage .Section__rest{position:relative}.theme-securestorage .Section__content{padding:.66em .5em}.theme-securestorage .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-securestorage .Section--fill{display:flex;flex-direction:column;height:100%}.theme-securestorage .Section--fill>.Section__rest{flex-grow:1}.theme-securestorage .Section--fill>.Section__rest>.Section__content{height:100%}.theme-securestorage .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-securestorage .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-securestorage .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-securestorage .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-securestorage .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-securestorage .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-securestorage .Section .Section:first-child{margin-top:-.5em}.theme-securestorage .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-securestorage .Section .Section .Section .Section__titleText{font-size:1em}.theme-securestorage .Layout__content{background-image:none}.theme-security .color-label{color:#b08e8b!important}.theme-security .color-bg-good{background-color:#4d9121!important}.theme-security .color-border-label{border-color:#b08e8b!important}.theme-security .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-security .Button:last-child{margin-right:0;margin-bottom:0}.theme-security .Button .fa,.theme-security .Button .fas,.theme-security .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-security .Button--hasContent .fa,.theme-security .Button--hasContent .fas,.theme-security .Button--hasContent .far{margin-right:.25em}.theme-security .Button--hasContent.Button--iconRight .fa,.theme-security .Button--hasContent.Button--iconRight .fas,.theme-security .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-security .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-security .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-security .Button--circular{border-radius:50%}.theme-security .Button--compact{padding:0 .25em;line-height:1.333em}.theme-security .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-security .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-security .Button--color--good{background-color:#4d9121;color:#fff;transition:color .2s,background-color .2s}.theme-security .Button--color--good:hover{background-color:#67b335;color:#fff}.theme-security .Button--color--good--translucent{background-color:rgba(77,145,33,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-security .Button--color--good--translucent:hover{background-color:rgba(103,179,53,.5);color:#fff}.theme-security .Button--color--transparent{background-color:rgba(37,37,37,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-security .Button--color--transparent:hover{background-color:rgba(56,56,56,.81);color:#fff}.theme-security .Button--color--default{background-color:#a14c49;color:#fff;transition:color .2s,background-color .2s}.theme-security .Button--color--default:hover{background-color:#bb6f6d;color:#fff}.theme-security .Button--color--default--translucent{background-color:rgba(46,46,46,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-security .Button--color--default--translucent:hover{background-color:rgba(68,68,68,.5);color:#fff}.theme-security .Button--color--caution{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.theme-security .Button--color--caution:hover{background-color:#f5d523;color:#000}.theme-security .Button--color--caution--translucent{background-color:rgba(217,184,4,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-security .Button--color--caution--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.theme-security .Button--color--danger{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.theme-security .Button--color--danger:hover{background-color:#d93f3f;color:#fff}.theme-security .Button--color--danger--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-security .Button--color--danger--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.theme-security .Button--disabled{background-color:#999!important;color:rgba(255,255,255,.75)!important}.theme-security .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-security .Button--selected,.theme-security .Button--selected--translucent{background-color:#1b9638;color:#fff;transition:color .2s,background-color .2s}.theme-security .Button--selected:hover,.theme-security .Button--selected--translucent:hover{background-color:#2fb94f;color:#fff}.theme-security .Divider--horizontal{margin:.5em 0}.theme-security .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-security .Divider--vertical{height:100%;margin:0 .5em}.theme-security .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-security .color__good{background-color:rgba(77,145,33,.2);color:#fff;border:solid rgba(130,208,79,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-security .color__good:hover{background-color:rgba(130,208,79,.2)}.theme-security .contentColor__good{background-color:#4d9121;color:#fff;border:solid #67b335;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-security .buttonsContainerColor__good{background-color:rgba(77,145,33,.33);color:#fff;border:solid rgba(130,208,79,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-security .color__default{background-color:rgba(169,108,106,.2);color:#fff;border:solid rgba(217,191,190,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-security .color__default:hover{background-color:rgba(217,191,190,.2)}.theme-security .disabled{background-color:rgba(99,29,29,.25)!important;border-color:rgba(99,29,29,.25)!important}.theme-security .selected{background-color:rgba(27,150,56,.2);color:#fff;border:solid rgba(27,150,56,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-security .selected:hover{background-color:rgba(72,214,105,.2)}.theme-security .contentColor__default{background-color:#a46866;color:#fff;border:solid #b97977;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-security .contentDisabled{background-color:#631d1d!important;border-top:1px solid #803131!important}.theme-security .contentSelected{background-color:#1b9638;color:#fff;border:solid #2fb94f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-security .buttonsContainerColor__default{background-color:rgba(169,108,106,.2);color:#fff;border:solid rgba(217,191,190,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-security .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-security .ImageButton .noAction{pointer-events:none}.theme-security .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-security .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-security .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-security .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-security .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-security .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-security .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-security .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-security .fluid:last-of-type{margin-bottom:0}.theme-security .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-security .fluid .title{font-weight:700;padding:.5em}.theme-security .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-security .fluid .contentFluid{padding:.5em;color:#fff}.theme-security .fluid .container{flex-direction:row;flex:1}.theme-security .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-security .fluid .image{padding:0}.theme-security .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-security .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-security .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-security .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-security .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-security .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-security .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #ff8d88;border:.0833333333em solid rgba(255,141,136,.75);border-radius:.16em;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-security .Input--disabled{color:#777;border-color:#848484;border-color:rgba(132,132,132,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-security .Input--fluid{display:block;width:auto}.theme-security .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-security .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-security .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-security .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-security .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-security .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-security .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-security .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-security .NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:700;font-style:italic;color:#000;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,transparent,transparent .8333333333em,rgba(0,0,0,.1) .8333333333em,rgba(0,0,0,.1) 1.6666666667em)}.theme-security .NoticeBox--color--good{color:#fff;background-color:#2e4b1a}.theme-security .NoticeBox--type--info{color:#fff;background-color:#822329}.theme-security .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-security .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-security .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-security .Section{position:relative;margin-bottom:.5em;background-color:#191919;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-security .Section:last-child{margin-bottom:0}.theme-security .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #a14c49}.theme-security .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-security .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-security .Section__rest{position:relative}.theme-security .Section__content{padding:.66em .5em}.theme-security .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-security .Section--fill{display:flex;flex-direction:column;height:100%}.theme-security .Section--fill>.Section__rest{flex-grow:1}.theme-security .Section--fill>.Section__rest>.Section__content{height:100%}.theme-security .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-security .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-security .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-security .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-security .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-security .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-security .Section .Section:first-child{margin-top:-.5em}.theme-security .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-security .Section .Section .Section .Section__titleText{font-size:1em}.theme-security .Newscaster__menu{width:40px;height:100%;margin-right:.5rem;flex-basis:content}.theme-security .Newscaster__menu .Section__content{padding-left:0}.theme-security .Newscaster__menuButton{color:#767676;cursor:pointer;position:relative;margin-left:6px;margin-right:1rem;white-space:nowrap;transition:color .1s}.theme-security .Newscaster__menuButton--title{width:80%;display:none;overflow:hidden;text-overflow:ellipsis}.theme-security .Newscaster__menuButton--unread{background-color:#e45e5e;color:#fff;font-size:10px;text-align:center;border-radius:32px;display:inline-block;width:12px;position:absolute;left:16px;margin-top:14px}.theme-security .Newscaster__menuButton--selected{color:#fff}.theme-security .Newscaster__menuButton--selected:after{content:"";background-color:#a14c49;width:2px;height:24px;position:absolute;left:-6px}.theme-security .Newscaster__menuButton--security{color:#a14c49}.theme-security .Newscaster__menuButton i{width:30px;text-align:center;vertical-align:middle;margin-left:-1px;margin-right:.5rem;margin-top:1px}.theme-security .Newscaster__menuButton:hover{color:#fff}.theme-security .Newscaster__menuButton:hover:before{background-color:#fff}.theme-security .Newscaster__menuButton:not(:last-of-type){margin-bottom:.5rem}.theme-security .Newscaster__menu--open{width:175px}.theme-security .Newscaster__menu--open .Newscaster__menuButton--title{display:inline-block}.theme-security .Newscaster__jobCategory--security .Section__title{color:#a14c49;border-bottom:2px solid #a14c49!important}.theme-security .Newscaster__jobCategory--engineering .Section__title{color:#a17849;border-bottom:2px solid #a17849!important}.theme-security .Newscaster__jobCategory--medical .Section__title{color:#499ea1;border-bottom:2px solid #499ea1!important}.theme-security .Newscaster__jobCategory--science .Section__title{color:#a14972;border-bottom:2px solid #a14972!important}.theme-security .Newscaster__jobCategory--service .Section__title{color:#a1499e;border-bottom:2px solid #a1499e!important}.theme-security .Newscaster__jobCategory--supply .Section__title{color:#9ea149;border-bottom:2px solid #9ea149!important}.theme-security .Newscaster__jobCategory:last-child{margin-bottom:.5rem}.theme-security .Newscaster__jobOpening--command{font-weight:700}.theme-security .Newscaster__jobOpening:not(:last-child){margin-bottom:.5rem}.theme-security .Newscaster__emptyNotice{color:#a7817e;text-align:center;position:absolute;top:50%;left:50%;transform:translateY(-50%) translate(-50%)}.theme-security .Newscaster__emptyNotice i{margin-bottom:.25rem}.theme-security .Newscaster__photo{cursor:pointer;width:100px;border:1px solid #000;transition:border-color .3s;-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.theme-security .Newscaster__photo:hover{border-color:gray}.theme-security .Newscaster__photoZoom{text-align:center}.theme-security .Newscaster__photoZoom>img{transform:scale(2);-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.theme-security .Newscaster__photoZoom>.Button{position:absolute;width:64px;left:50%;margin-left:-32px;bottom:1rem}.theme-security .Newscaster__story--wanted{background-color:rgba(219,40,40,.1)}.theme-security .Newscaster__story--wanted .Section__title{color:#db2828;border-bottom:2px solid #a14c49!important}.theme-security .Newscaster__story:last-child{margin-bottom:.5rem}.theme-syndicate .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-syndicate .Button:last-child{margin-right:0;margin-bottom:0}.theme-syndicate .Button .fa,.theme-syndicate .Button .fas,.theme-syndicate .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-syndicate .Button--hasContent .fa,.theme-syndicate .Button--hasContent .fas,.theme-syndicate .Button--hasContent .far{margin-right:.25em}.theme-syndicate .Button--hasContent.Button--iconRight .fa,.theme-syndicate .Button--hasContent.Button--iconRight .fas,.theme-syndicate .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-syndicate .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-syndicate .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-syndicate .Button--circular{border-radius:50%}.theme-syndicate .Button--compact{padding:0 .25em;line-height:1.333em}.theme-syndicate .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-syndicate .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-syndicate .Button--color--transparent{background-color:rgba(85,2,2,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-syndicate .Button--color--transparent:hover{background-color:rgba(113,14,14,.81);color:#fff}.theme-syndicate .Button--color--default{background-color:#397439;color:#fff;transition:color .2s,background-color .2s}.theme-syndicate .Button--color--default:hover{background-color:#509350;color:#fff}.theme-syndicate .Button--color--default--translucent{background-color:rgba(96,8,8,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-syndicate .Button--color--default--translucent:hover{background-color:rgba(124,25,25,.5);color:#fff}.theme-syndicate .Button--color--caution{background-color:#be6209;color:#fff;transition:color .2s,background-color .2s}.theme-syndicate .Button--color--caution:hover{background-color:#e67f1a;color:#fff}.theme-syndicate .Button--color--caution--translucent{background-color:rgba(190,98,9,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-syndicate .Button--color--caution--translucent:hover{background-color:rgba(230,127,26,.5);color:#fff}.theme-syndicate .Button--color--danger{background-color:#9a9d00;color:#fff;transition:color .2s,background-color .2s}.theme-syndicate .Button--color--danger:hover{background-color:#bec110;color:#fff}.theme-syndicate .Button--color--danger--translucent{background-color:rgba(154,157,0,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-syndicate .Button--color--danger--translucent:hover{background-color:rgba(190,193,16,.5);color:#fff}.theme-syndicate .Button--disabled{background-color:#363636!important;color:rgba(255,255,255,.75)!important}.theme-syndicate .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-syndicate .Button--selected,.theme-syndicate .Button--selected--translucent{background-color:#9d0808;color:#fff;transition:color .2s,background-color .2s}.theme-syndicate .Button--selected:hover,.theme-syndicate .Button--selected--translucent:hover{background-color:#c11919;color:#fff}.theme-syndicate .Divider--horizontal{margin:.5em 0}.theme-syndicate .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-syndicate .Divider--vertical{height:100%;margin:0 .5em}.theme-syndicate .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-syndicate .color__default{background-color:rgba(87,122,87,.2);color:#fff;border:solid rgba(148,177,148,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-syndicate .color__default:hover{background-color:rgba(148,177,148,.2)}.theme-syndicate .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-syndicate .selected{background-color:rgba(157,8,8,.2);color:#fff;border:solid rgba(157,8,8,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-syndicate .selected:hover{background-color:rgba(229,42,42,.2)}.theme-syndicate .contentColor__default{background-color:#547654;color:#fff;border:solid #638763;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-syndicate .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-syndicate .contentSelected{background-color:#9d0808;color:#fff;border:solid #c11919;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-syndicate .buttonsContainerColor__default{background-color:rgba(87,122,87,.2);color:#fff;border:solid rgba(148,177,148,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-syndicate .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-syndicate .ImageButton .noAction{pointer-events:none}.theme-syndicate .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-syndicate .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-syndicate .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-syndicate .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-syndicate .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-syndicate .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-syndicate .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-syndicate .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-syndicate .fluid:last-of-type{margin-bottom:0}.theme-syndicate .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-syndicate .fluid .title{font-weight:700;padding:.5em}.theme-syndicate .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-syndicate .fluid .contentFluid{padding:.5em;color:#fff}.theme-syndicate .fluid .container{flex-direction:row;flex:1}.theme-syndicate .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-syndicate .fluid .image{padding:0}.theme-syndicate .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-syndicate .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-syndicate .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-syndicate .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-syndicate .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-syndicate .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-syndicate .NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:700;font-style:italic;color:#fff;background-color:#910101;background-image:repeating-linear-gradient(-45deg,transparent,transparent .8333333333em,rgba(0,0,0,.1) .8333333333em,rgba(0,0,0,.1) 1.6666666667em)}.theme-syndicate .NoticeBox--type--info{color:#fff;background-color:#235982}.theme-syndicate .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-syndicate .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-syndicate .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-syndicate .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #87ce87;border:.0833333333em solid rgba(135,206,135,.75);border-radius:.16em;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-syndicate .Input--disabled{color:#777;border-color:#6b6b6b;border-color:rgba(107,107,107,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-syndicate .Input--fluid{display:block;width:auto}.theme-syndicate .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-syndicate .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-syndicate .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-syndicate .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-syndicate .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-syndicate .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-syndicate .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-syndicate .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-syndicate .NumberInput{position:relative;display:inline-block;border:.0833333333em solid #87ce87;border:.0833333333em solid rgba(135,206,135,.75);border-radius:.16em;color:#87ce87;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.theme-syndicate .NumberInput--fluid{display:block}.theme-syndicate .NumberInput__content{margin-left:.5em}.theme-syndicate .NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.theme-syndicate .NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #87ce87;background-color:#87ce87}.theme-syndicate .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#0a0a0a;color:#fff;text-align:right}.theme-syndicate .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:.16em;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-syndicate .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-syndicate .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-syndicate .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-syndicate .ProgressBar--color--default{border:.0833333333em solid #306330}.theme-syndicate .ProgressBar--color--default .ProgressBar__fill{background-color:#306330}.theme-syndicate .ProgressBar--color--disabled{border:1px solid #999}.theme-syndicate .ProgressBar--color--disabled .ProgressBar__fill{background-color:#999}.theme-syndicate .Section{position:relative;margin-bottom:.5em;background-color:#390101;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-syndicate .Section:last-child{margin-bottom:0}.theme-syndicate .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #397439}.theme-syndicate .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-syndicate .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-syndicate .Section__rest{position:relative}.theme-syndicate .Section__content{padding:.66em .5em}.theme-syndicate .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-syndicate .Section--fill{display:flex;flex-direction:column;height:100%}.theme-syndicate .Section--fill>.Section__rest{flex-grow:1}.theme-syndicate .Section--fill>.Section__rest>.Section__content{height:100%}.theme-syndicate .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-syndicate .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-syndicate .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-syndicate .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-syndicate .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-syndicate .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-syndicate .Section .Section:first-child{margin-top:-.5em}.theme-syndicate .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-syndicate .Section .Section .Section .Section__titleText{font-size:1em}.theme-syndicate .Tooltip{z-index:999;padding:.5em .75em;pointer-events:none;text-align:left;transition:opacity .15s ease-out;background-color:#4a0202;color:#fff;box-shadow:.1em .1em 1.25em -.1em rgba(0,0,0,.5);border-radius:.16em;max-width:20.8333333333em}.theme-syndicate html,.theme-syndicate body{scrollbar-color:#7e0303 #400202}.theme-syndicate .Layout,.theme-syndicate .Layout *{scrollbar-base-color:#400202;scrollbar-face-color:#7e0303;scrollbar-3dlight-color:#550202;scrollbar-highlight-color:#550202;scrollbar-track-color:#400202;scrollbar-arrow-color:#fa3030;scrollbar-shadow-color:#7e0303}.theme-syndicate .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-syndicate .Layout__content--flexRow{display:flex;flex-flow:row}.theme-syndicate .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-syndicate .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-syndicate .Layout__content--noMargin{margin:0}.theme-syndicate .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#550202;background-image:linear-gradient(to bottom,#730303,#370101)}.theme-syndicate .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-syndicate .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-syndicate .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-syndicate .Window__contentPadding:after{height:0}.theme-syndicate .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-syndicate .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(117,22,22,.25);pointer-events:none}.theme-syndicate .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-syndicate .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-syndicate .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-syndicate .TitleBar{background-color:#910101;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-syndicate .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#910101;transition:color .25s,background-color .25s}.theme-syndicate .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-syndicate .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-syndicate .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-syndicate .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-syndicate .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-syndicate .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-syndicate .Layout__content{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMCIgdmlld0JveD0iMCAwIDIwMCAyODkuNzQyIiBvcGFjaXR5PSIuMzMiPjxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPjwvc3ZnPjwhLS0gVGhpcyB3b3JrIGlzIGxpY2Vuc2VkIHVuZGVyIGEgQ3JlYXRpdmUgQ29tbW9ucyBBdHRyaWJ1dGlvbi1TaGFyZUFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UuIC0tPjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4=)}.theme-syndicate .candystripe:nth-child(odd){background-color:rgba(0,0,0,.4)}.theme-syndicate .candystripe:nth-child(2n){background-color:rgba(0,0,0,.25)}.theme-nologo .Layout__content{background-image:none}.theme-noticeboard .color-black{color:#1a1a1a!important}.theme-noticeboard .color-white{color:#fff!important}.theme-noticeboard .color-red{color:#df3e3e!important}.theme-noticeboard .color-orange{color:#f37f33!important}.theme-noticeboard .color-yellow{color:#fbda21!important}.theme-noticeboard .color-olive{color:#cbe41c!important}.theme-noticeboard .color-green{color:#25ca4c!important}.theme-noticeboard .color-teal{color:#00d6cc!important}.theme-noticeboard .color-blue{color:#2e93de!important}.theme-noticeboard .color-violet{color:#7349cf!important}.theme-noticeboard .color-purple{color:#ad45d0!important}.theme-noticeboard .color-pink{color:#e34da1!important}.theme-noticeboard .color-brown{color:#b97447!important}.theme-noticeboard .color-grey{color:#848484!important}.theme-noticeboard .color-good{color:#68c22d!important}.theme-noticeboard .color-average{color:#f29a29!important}.theme-noticeboard .color-bad{color:#df3e3e!important}.theme-noticeboard .color-label{color:#8b9bb0!important}.theme-noticeboard .color-gold{color:#f3b22f!important}.theme-noticeboard .color-bg-black{background-color:#000!important}.theme-noticeboard .color-bg-white{background-color:#d9d9d9!important}.theme-noticeboard .color-bg-red{background-color:#bd2020!important}.theme-noticeboard .color-bg-orange{background-color:#d95e0c!important}.theme-noticeboard .color-bg-yellow{background-color:#d9b804!important}.theme-noticeboard .color-bg-olive{background-color:#9aad14!important}.theme-noticeboard .color-bg-green{background-color:#1b9638!important}.theme-noticeboard .color-bg-teal{background-color:#009a93!important}.theme-noticeboard .color-bg-blue{background-color:#1c71b1!important}.theme-noticeboard .color-bg-violet{background-color:#552dab!important}.theme-noticeboard .color-bg-purple{background-color:#8b2baa!important}.theme-noticeboard .color-bg-pink{background-color:#cf2082!important}.theme-noticeboard .color-bg-brown{background-color:#8c5836!important}.theme-noticeboard .color-bg-grey{background-color:#646464!important}.theme-noticeboard .color-bg-good{background-color:#4d9121!important}.theme-noticeboard .color-bg-average{background-color:#cd7a0d!important}.theme-noticeboard .color-bg-bad{background-color:#bd2020!important}.theme-noticeboard .color-bg-label{background-color:#657a94!important}.theme-noticeboard .color-bg-gold{background-color:#d6920c!important}.theme-noticeboard .color-border-black{border-color:#1a1a1a!important}.theme-noticeboard .color-border-white{border-color:#fff!important}.theme-noticeboard .color-border-red{border-color:#df3e3e!important}.theme-noticeboard .color-border-orange{border-color:#f37f33!important}.theme-noticeboard .color-border-yellow{border-color:#fbda21!important}.theme-noticeboard .color-border-olive{border-color:#cbe41c!important}.theme-noticeboard .color-border-green{border-color:#25ca4c!important}.theme-noticeboard .color-border-teal{border-color:#00d6cc!important}.theme-noticeboard .color-border-blue{border-color:#2e93de!important}.theme-noticeboard .color-border-violet{border-color:#7349cf!important}.theme-noticeboard .color-border-purple{border-color:#ad45d0!important}.theme-noticeboard .color-border-pink{border-color:#e34da1!important}.theme-noticeboard .color-border-brown{border-color:#b97447!important}.theme-noticeboard .color-border-grey{border-color:#848484!important}.theme-noticeboard .color-border-good{border-color:#68c22d!important}.theme-noticeboard .color-border-average{border-color:#f29a29!important}.theme-noticeboard .color-border-bad{border-color:#df3e3e!important}.theme-noticeboard .color-border-label{border-color:#8b9bb0!important}.theme-noticeboard .color-border-gold{border-color:#f3b22f!important}.theme-noticeboard .Section{position:relative;margin-bottom:.5em;background-color:#f2f2f2;box-sizing:border-box}.theme-noticeboard .Section:last-child{margin-bottom:0}.theme-noticeboard .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #4972a1}.theme-noticeboard .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-noticeboard .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-noticeboard .Section__rest{position:relative}.theme-noticeboard .Section__content{padding:.66em .5em}.theme-noticeboard .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-noticeboard .Section--fill{display:flex;flex-direction:column;height:100%}.theme-noticeboard .Section--fill>.Section__rest{flex-grow:1}.theme-noticeboard .Section--fill>.Section__rest>.Section__content{height:100%}.theme-noticeboard .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-noticeboard .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-noticeboard .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-noticeboard .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-noticeboard .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-noticeboard .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-noticeboard .Section .Section:first-child{margin-top:-.5em}.theme-noticeboard .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-noticeboard .Section .Section .Section .Section__titleText{font-size:1em}.theme-noticeboard .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#2b0f0c;background-image:linear-gradient(to bottom,#2b0f0c,#2b0f0c)}.theme-noticeboard .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-noticeboard .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-noticeboard .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-noticeboard .Window__contentPadding:after{height:0}.theme-noticeboard .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-noticeboard .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(69,37,33,.25);pointer-events:none}.theme-noticeboard .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-noticeboard .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-noticeboard .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-noticeboard .TitleBar{background-color:#2b0f0c;border-bottom:1px solid #2b0f0c;box-shadow:0 2px 2px #2b0f0c;box-shadow:0 .1666666667rem .1666666667rem #2b0f0c;user-select:none;-ms-user-select:none}.theme-noticeboard .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#2b0f0c;transition:color .25s,background-color .25s}.theme-noticeboard .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-noticeboard .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-noticeboard .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-noticeboard .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-noticeboard .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-noticeboard .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-noticeboard .Layout,.theme-noticeboard .Layout *{scrollbar-base-color:#f2f2f2;scrollbar-face-color:#e1e1e1;scrollbar-3dlight-color:#f2f2f2;scrollbar-highlight-color:#c8c8c8;scrollbar-track-color:#f2f2f2;scrollbar-arrow-color:#969696;scrollbar-shadow-color:#f2f2f2}.theme-noticeboard .Layout__content{background-image:none}.theme-noticeboard .Window__contentPadding{background-color:#824b28;box-shadow:inset 0 0 10px 1px rgba(0,0,0,.75);border-radius:1em}.theme-noticeboard .Stack--horizontal>.Stack__item{margin-left:1em}.theme-noticeboard .Stack--horizontal>.Stack__item:last-child{margin-right:1em}.theme-noticeboard .Section{font-family:Comic Sans MS,cursive,sans-serif;font-style:italic;white-space:pre-wrap;color:#000;box-shadow:5px 5px 5px rgba(0,0,0,.5);border-radius:100px 100px 200px 200px/10px;transition:all .1s ease-in-out}.theme-noticeboard .Section>.Section__rest>.Section__content{overflow-y:hidden;overflow-x:hidden}.theme-noticeboard .Section__content{margin-top:.25em}.theme-noticeboard .Section__title{margin-top:.5em;padding-bottom:0;border:0}.theme-noticeboard .Section__titleText{color:#000}.theme-noticeboard .Section:hover{transform:scale(1.15);border-radius:1em;box-shadow:0 0 20px 10px rgba(0,0,0,.33);z-index:2}.theme-noticeboard .Section:before{content:" ";display:block;width:10px;height:10px;background:linear-gradient(300deg,#640000,red 75%,#ff7d7d);box-shadow:1.5px 1.5px 5px rgba(0,0,0,.6);border-radius:100%;position:absolute;left:calc(50% - 12px);margin-top:.25em;transform:matrix(1,0,.4,.9,0,0)} +html,body{box-sizing:border-box;height:100%;margin:0;font-size:12px}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif}*,*:before,*:after{box-sizing:inherit}h1,h2,h3,h4,h5,h6{display:block;margin:0;padding:6px 0;padding:.5rem 0}h1{font-size:18px;font-size:1.5rem}h2{font-size:16px;font-size:1.333rem}h3{font-size:14px;font-size:1.167rem}h4{font-size:12px;font-size:1rem}td,th{vertical-align:baseline;text-align:left}.candystripe:nth-child(odd){background-color:rgba(0,0,0,.25)}.color-black{color:#1a1a1a!important}.color-white{color:#fff!important}.color-red{color:#df3e3e!important}.color-orange{color:#f37f33!important}.color-yellow{color:#fbda21!important}.color-olive{color:#cbe41c!important}.color-green{color:#25ca4c!important}.color-teal{color:#00d6cc!important}.color-blue{color:#2e93de!important}.color-violet{color:#7349cf!important}.color-purple{color:#ad45d0!important}.color-pink{color:#e34da1!important}.color-brown{color:#b97447!important}.color-grey{color:#848484!important}.color-good{color:#68c22d!important}.color-average{color:#f29a29!important}.color-bad{color:#df3e3e!important}.color-label{color:#8b9bb0!important}.color-gold{color:#f3b22f!important}.color-bg-black{background-color:#000!important}.color-bg-white{background-color:#d9d9d9!important}.color-bg-red{background-color:#bd2020!important}.color-bg-orange{background-color:#d95e0c!important}.color-bg-yellow{background-color:#d9b804!important}.color-bg-olive{background-color:#9aad14!important}.color-bg-green{background-color:#1b9638!important}.color-bg-teal{background-color:#009a93!important}.color-bg-blue{background-color:#1c71b1!important}.color-bg-violet{background-color:#552dab!important}.color-bg-purple{background-color:#8b2baa!important}.color-bg-pink{background-color:#cf2082!important}.color-bg-brown{background-color:#8c5836!important}.color-bg-grey{background-color:#646464!important}.color-bg-good{background-color:#4d9121!important}.color-bg-average{background-color:#cd7a0d!important}.color-bg-bad{background-color:#bd2020!important}.color-bg-label{background-color:#657a94!important}.color-bg-gold{background-color:#d6920c!important}.color-border-black{border-color:#1a1a1a!important}.color-border-white{border-color:#fff!important}.color-border-red{border-color:#df3e3e!important}.color-border-orange{border-color:#f37f33!important}.color-border-yellow{border-color:#fbda21!important}.color-border-olive{border-color:#cbe41c!important}.color-border-green{border-color:#25ca4c!important}.color-border-teal{border-color:#00d6cc!important}.color-border-blue{border-color:#2e93de!important}.color-border-violet{border-color:#7349cf!important}.color-border-purple{border-color:#ad45d0!important}.color-border-pink{border-color:#e34da1!important}.color-border-brown{border-color:#b97447!important}.color-border-grey{border-color:#848484!important}.color-border-good{border-color:#68c22d!important}.color-border-average{border-color:#f29a29!important}.color-border-bad{border-color:#df3e3e!important}.color-border-label{border-color:#8b9bb0!important}.color-border-gold{border-color:#f3b22f!important}.debug-layout,.debug-layout *:not(g):not(path){color:rgba(255,255,255,.9)!important;background:rgba(0,0,0,0)!important;outline:1px solid rgba(255,255,255,.5)!important;box-shadow:none!important;filter:none!important}.debug-layout:hover,.debug-layout *:not(g):not(path):hover{outline-color:rgba(255,255,255,.8)!important}.outline-dotted{outline-style:dotted!important}.outline-dashed{outline-style:dashed!important}.outline-solid{outline-style:solid!important}.outline-double{outline-style:double!important}.outline-groove{outline-style:groove!important}.outline-ridge{outline-style:ridge!important}.outline-inset{outline-style:inset!important}.outline-outset{outline-style:outset!important}.outline-color-black{outline:.167rem solid #1a1a1a!important}.outline-color-white{outline:.167rem solid #fff!important}.outline-color-red{outline:.167rem solid #df3e3e!important}.outline-color-orange{outline:.167rem solid #f37f33!important}.outline-color-yellow{outline:.167rem solid #fbda21!important}.outline-color-olive{outline:.167rem solid #cbe41c!important}.outline-color-green{outline:.167rem solid #25ca4c!important}.outline-color-teal{outline:.167rem solid #00d6cc!important}.outline-color-blue{outline:.167rem solid #2e93de!important}.outline-color-violet{outline:.167rem solid #7349cf!important}.outline-color-purple{outline:.167rem solid #ad45d0!important}.outline-color-pink{outline:.167rem solid #e34da1!important}.outline-color-brown{outline:.167rem solid #b97447!important}.outline-color-grey{outline:.167rem solid #848484!important}.outline-color-good{outline:.167rem solid #68c22d!important}.outline-color-average{outline:.167rem solid #f29a29!important}.outline-color-bad{outline:.167rem solid #df3e3e!important}.outline-color-label{outline:.167rem solid #8b9bb0!important}.outline-color-gold{outline:.167rem solid #f3b22f!important}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-baseline{text-align:baseline}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-pre{white-space:pre}.text-bold{font-weight:700}.text-italic{font-style:italic}.text-underline{text-decoration:underline}.BlockQuote{color:#8b9bb0;border-left:.1666666667em solid #8b9bb0;padding-left:.5em;margin-bottom:.5em}.BlockQuote:last-child{margin-bottom:0}.Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.Button:last-child{margin-right:0;margin-bottom:0}.Button .fa,.Button .fas,.Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.Button--hasContent .fa,.Button--hasContent .fas,.Button--hasContent .far{margin-right:.25em}.Button--hasContent.Button--iconRight .fa,.Button--hasContent.Button--iconRight .fas,.Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.Button--fluid{display:block;margin-left:0;margin-right:0}.Button--circular{border-radius:50%}.Button--compact{padding:0 .25em;line-height:1.333em}.Button--multiLine{white-space:normal;word-wrap:break-word}.Button--modal{float:right;z-index:1;margin-top:-.5rem}.Button--color--black{background-color:#000;color:#fff;transition:color .2s,background-color .2s}.Button--color--black:hover{background-color:#101010;color:#fff}.Button--color--black--translucent{background-color:rgba(0,0,0,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--black--translucent:hover{background-color:rgba(16,16,16,.5);color:#fff}.Button--color--white{background-color:#d9d9d9;color:#000;transition:color .2s,background-color .2s}.Button--color--white:hover{background-color:#f8f8f8;color:#000}.Button--color--white--translucent{background-color:rgba(217,217,217,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--white--translucent:hover{background-color:rgba(248,248,248,.5);color:#fff}.Button--color--red{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.Button--color--red:hover{background-color:#d93f3f;color:#fff}.Button--color--red--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--red--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.Button--color--orange{background-color:#d95e0c;color:#fff;transition:color .2s,background-color .2s}.Button--color--orange:hover{background-color:#ef7e33;color:#fff}.Button--color--orange--translucent{background-color:rgba(217,94,12,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--orange--translucent:hover{background-color:rgba(239,126,51,.5);color:#fff}.Button--color--yellow{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.Button--color--yellow:hover{background-color:#f5d523;color:#000}.Button--color--yellow--translucent{background-color:rgba(217,184,4,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--yellow--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.Button--color--olive{background-color:#9aad14;color:#fff;transition:color .2s,background-color .2s}.Button--color--olive:hover{background-color:#bdd327;color:#fff}.Button--color--olive--translucent{background-color:rgba(154,173,20,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--olive--translucent:hover{background-color:rgba(189,211,39,.5);color:#fff}.Button--color--green{background-color:#1b9638;color:#fff;transition:color .2s,background-color .2s}.Button--color--green:hover{background-color:#2fb94f;color:#fff}.Button--color--green--translucent{background-color:rgba(27,150,56,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--green--translucent:hover{background-color:rgba(47,185,79,.5);color:#fff}.Button--color--teal{background-color:#009a93;color:#fff;transition:color .2s,background-color .2s}.Button--color--teal:hover{background-color:#10bdb6;color:#fff}.Button--color--teal--translucent{background-color:rgba(0,154,147,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--teal--translucent:hover{background-color:rgba(16,189,182,.5);color:#fff}.Button--color--blue{background-color:#1c71b1;color:#fff;transition:color .2s,background-color .2s}.Button--color--blue:hover{background-color:#308fd6;color:#fff}.Button--color--blue--translucent{background-color:rgba(28,113,177,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--blue--translucent:hover{background-color:rgba(48,143,214,.5);color:#fff}.Button--color--violet{background-color:#552dab;color:#fff;transition:color .2s,background-color .2s}.Button--color--violet:hover{background-color:#7249ca;color:#fff}.Button--color--violet--translucent{background-color:rgba(85,45,171,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--violet--translucent:hover{background-color:rgba(114,73,202,.5);color:#fff}.Button--color--purple{background-color:#8b2baa;color:#fff;transition:color .2s,background-color .2s}.Button--color--purple:hover{background-color:#aa46ca;color:#fff}.Button--color--purple--translucent{background-color:rgba(139,43,170,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--purple--translucent:hover{background-color:rgba(170,70,202,.5);color:#fff}.Button--color--pink{background-color:#cf2082;color:#fff;transition:color .2s,background-color .2s}.Button--color--pink:hover{background-color:#e04ca0;color:#fff}.Button--color--pink--translucent{background-color:rgba(207,32,130,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--pink--translucent:hover{background-color:rgba(224,76,160,.5);color:#fff}.Button--color--brown{background-color:#8c5836;color:#fff;transition:color .2s,background-color .2s}.Button--color--brown:hover{background-color:#ae724c;color:#fff}.Button--color--brown--translucent{background-color:rgba(140,88,54,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--brown--translucent:hover{background-color:rgba(174,114,76,.5);color:#fff}.Button--color--grey{background-color:#646464;color:#fff;transition:color .2s,background-color .2s}.Button--color--grey:hover{background-color:#818181;color:#fff}.Button--color--grey--translucent{background-color:rgba(100,100,100,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--grey--translucent:hover{background-color:rgba(129,129,129,.5);color:#fff}.Button--color--good{background-color:#4d9121;color:#fff;transition:color .2s,background-color .2s}.Button--color--good:hover{background-color:#67b335;color:#fff}.Button--color--good--translucent{background-color:rgba(77,145,33,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--good--translucent:hover{background-color:rgba(103,179,53,.5);color:#fff}.Button--color--average{background-color:#cd7a0d;color:#fff;transition:color .2s,background-color .2s}.Button--color--average:hover{background-color:#eb972b;color:#fff}.Button--color--average--translucent{background-color:rgba(205,122,13,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--average--translucent:hover{background-color:rgba(235,151,43,.5);color:#fff}.Button--color--bad{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.Button--color--bad:hover{background-color:#d93f3f;color:#fff}.Button--color--bad--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--bad--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.Button--color--label{background-color:#657a94;color:#fff;transition:color .2s,background-color .2s}.Button--color--label:hover{background-color:#8a9aae;color:#fff}.Button--color--label--translucent{background-color:rgba(101,122,148,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--label--translucent:hover{background-color:rgba(138,154,174,.5);color:#fff}.Button--color--gold{background-color:#d6920c;color:#fff;transition:color .2s,background-color .2s}.Button--color--gold:hover{background-color:#eeaf30;color:#fff}.Button--color--gold--translucent{background-color:rgba(214,146,12,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--gold--translucent:hover{background-color:rgba(238,175,48,.5);color:#fff}.Button--color--transparent{background-color:rgba(37,37,37,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--transparent:hover{background-color:rgba(56,56,56,.81);color:#fff}.Button--color--default{background-color:#3e6189;color:#fff;transition:color .2s,background-color .2s}.Button--color--default:hover{background-color:#567daa;color:#fff}.Button--color--default--translucent{background-color:rgba(46,46,46,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--default--translucent:hover{background-color:rgba(68,68,68,.5);color:#fff}.Button--color--caution{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.Button--color--caution:hover{background-color:#f5d523;color:#000}.Button--color--caution--translucent{background-color:rgba(217,184,4,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--caution--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.Button--color--danger{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.Button--color--danger:hover{background-color:#d93f3f;color:#fff}.Button--color--danger--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.Button--color--danger--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.Button--disabled{background-color:#999!important;color:rgba(255,255,255,.75)!important}.Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.Button--selected,.Button--selected--translucent{background-color:#1b9638;color:#fff;transition:color .2s,background-color .2s}.Button--selected:hover,.Button--selected--translucent:hover{background-color:#2fb94f;color:#fff}.Collapsible{margin-bottom:.5rem}.Collapsible:last-child{margin-bottom:0}.ColorBox{display:inline-block;width:1em;height:1em;line-height:1em;text-align:center}.Dimmer{display:flex;justify-content:center;align-items:center;position:absolute;top:0;bottom:0;left:0;right:0;background-color:rgba(0,0,0,.75);z-index:5}.Dropdown{position:relative;align-items:center}.Dropdown__control{display:inline-block;align-items:center;font-family:Verdana,sans-serif;font-size:1em;width:8.3333333333em;line-height:1.3333333333em;-ms-user-select:none;user-select:none}.Dropdown__arrow-button{float:right;padding-left:.35em;width:1.2em;height:1.8333333333em;border-left:.0833333333em solid #000;border-left:.0833333333em solid rgba(0,0,0,.25)}.Dropdown__menu{overflow-y:auto;align-items:center;z-index:5;max-height:16.6666666667em;border-radius:0 0 .1666666667em .1666666667em;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75)}.Dropdown__menu-scroll{overflow-y:scroll}.Dropdown__menuentry{padding:.1666666667em .3333333333em;font-family:Verdana,sans-serif;font-size:1em;line-height:1.4166666667em;transition:background-color .1s ease-out}.Dropdown__menuentry.selected{background-color:rgba(255,255,255,.5)!important;transition:background-color 0ms}.Dropdown__menuentry:hover{background-color:rgba(255,255,255,.2);transition:background-color 0ms}.Dropdown__over{top:auto;bottom:100%}.Dropdown__selected-text{display:inline-block;text-overflow:ellipsis;white-space:nowrap;height:1.4166666667em;width:calc(100% - 1.2em);text-align:left;padding-top:2.5px}.Flex{display:-ms-flexbox;display:flex}.Flex--inline{display:inline-flex}.Flex--iefix{display:block}.Flex--iefix.Flex--inline,.Flex__item--iefix{display:inline-block}.Flex--iefix--column>.Flex__item--iefix{display:block}.IconStack>.Icon{position:absolute;width:100%;text-align:center}.IconStack{position:relative;display:inline-block;height:7em;width:10em;line-height:2em;vertical-align:middle}.IconStack:after{color:rgba(0,0,0,0);content:"."}.color__black{background-color:rgba(0,0,0,.2);color:#fff;border:solid rgba(32,32,32,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__black:hover{background-color:rgba(32,32,32,.2)}.contentColor__black{background-color:#000;color:#fff;border:solid #101010;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__black{background-color:rgba(0,0,0,.33);color:#fff;border:solid rgba(32,32,32,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__white{background-color:rgba(217,217,217,.2);color:#000;border:solid rgba(250,250,250,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__white:hover{background-color:rgba(250,250,250,.2)}.contentColor__white{background-color:#d9d9d9;color:#000;border:solid #f8f8f8;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__white{background-color:rgba(217,217,217,.33);color:#000;border:solid rgba(250,250,250,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__red{background-color:rgba(189,32,32,.2);color:#fff;border:solid rgba(227,112,112,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__red:hover{background-color:rgba(227,112,112,.2)}.contentColor__red{background-color:#bd2020;color:#fff;border:solid #d93f3f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__red{background-color:rgba(189,32,32,.33);color:#fff;border:solid rgba(227,112,112,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__orange{background-color:rgba(217,94,12,.2);color:#fff;border:solid rgba(244,162,107,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__orange:hover{background-color:rgba(244,162,107,.2)}.contentColor__orange{background-color:#d95e0c;color:#fff;border:solid #ef7e33;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__orange{background-color:rgba(217,94,12,.33);color:#fff;border:solid rgba(244,162,107,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__yellow{background-color:rgba(217,184,4,.2);color:#000;border:solid rgba(248,225,91,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__yellow:hover{background-color:rgba(248,225,91,.2)}.contentColor__yellow{background-color:#d9b804;color:#000;border:solid #f5d523;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__yellow{background-color:rgba(217,184,4,.33);color:#000;border:solid rgba(248,225,91,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__olive{background-color:rgba(154,173,20,.2);color:#000;border:solid rgba(209,228,79,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__olive:hover{background-color:rgba(209,228,79,.2)}.contentColor__olive{background-color:#9aad14;color:#000;border:solid #bdd327;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__olive{background-color:rgba(154,173,20,.33);color:#000;border:solid rgba(209,228,79,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__green{background-color:rgba(27,150,56,.2);color:#fff;border:solid rgba(72,214,105,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__green:hover{background-color:rgba(72,214,105,.2)}.contentColor__green{background-color:#1b9638;color:#fff;border:solid #2fb94f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__green{background-color:rgba(27,150,56,.33);color:#fff;border:solid rgba(72,214,105,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__teal{background-color:rgba(0,154,147,.2);color:#fff;border:solid rgba(32,225,216,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__teal:hover{background-color:rgba(32,225,216,.2)}.contentColor__teal{background-color:#009a93;color:#fff;border:solid #10bdb6;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__teal{background-color:rgba(0,154,147,.33);color:#fff;border:solid rgba(32,225,216,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__blue{background-color:rgba(28,113,177,.2);color:#fff;border:solid rgba(96,169,224,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__blue:hover{background-color:rgba(96,169,224,.2)}.contentColor__blue{background-color:#1c71b1;color:#fff;border:solid #308fd6;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__blue{background-color:rgba(28,113,177,.33);color:#fff;border:solid rgba(96,169,224,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__violet{background-color:rgba(85,45,171,.2);color:#fff;border:solid rgba(149,119,215,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__violet:hover{background-color:rgba(149,119,215,.2)}.contentColor__violet{background-color:#552dab;color:#fff;border:solid #7249ca;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__violet{background-color:rgba(85,45,171,.33);color:#fff;border:solid rgba(149,119,215,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__purple{background-color:rgba(139,43,170,.2);color:#fff;border:solid rgba(190,115,215,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__purple:hover{background-color:rgba(190,115,215,.2)}.contentColor__purple{background-color:#8b2baa;color:#fff;border:solid #aa46ca;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__purple{background-color:rgba(139,43,170,.33);color:#fff;border:solid rgba(190,115,215,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__pink{background-color:rgba(207,32,130,.2);color:#fff;border:solid rgba(233,129,188,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__pink:hover{background-color:rgba(233,129,188,.2)}.contentColor__pink{background-color:#cf2082;color:#fff;border:solid #e04ca0;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__pink{background-color:rgba(207,32,130,.33);color:#fff;border:solid rgba(233,129,188,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__brown{background-color:rgba(140,88,54,.2);color:#fff;border:solid rgba(195,144,111,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__brown:hover{background-color:rgba(195,144,111,.2)}.contentColor__brown{background-color:#8c5836;color:#fff;border:solid #ae724c;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__brown{background-color:rgba(140,88,54,.33);color:#fff;border:solid rgba(195,144,111,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__grey{background-color:rgba(100,100,100,.2);color:#fff;border:solid rgba(157,157,157,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__grey:hover{background-color:rgba(157,157,157,.2)}.contentColor__grey{background-color:#646464;color:#fff;border:solid #818181;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__grey{background-color:rgba(100,100,100,.33);color:#fff;border:solid rgba(157,157,157,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__good{background-color:rgba(77,145,33,.2);color:#fff;border:solid rgba(130,208,79,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__good:hover{background-color:rgba(130,208,79,.2)}.contentColor__good{background-color:#4d9121;color:#fff;border:solid #67b335;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__good{background-color:rgba(77,145,33,.33);color:#fff;border:solid rgba(130,208,79,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__average{background-color:rgba(205,122,13,.2);color:#fff;border:solid rgba(241,178,96,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__average:hover{background-color:rgba(241,178,96,.2)}.contentColor__average{background-color:#cd7a0d;color:#fff;border:solid #eb972b;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__average{background-color:rgba(205,122,13,.33);color:#fff;border:solid rgba(241,178,96,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__bad{background-color:rgba(189,32,32,.2);color:#fff;border:solid rgba(227,112,112,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__bad:hover{background-color:rgba(227,112,112,.2)}.contentColor__bad{background-color:#bd2020;color:#fff;border:solid #d93f3f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__bad{background-color:rgba(189,32,32,.33);color:#fff;border:solid rgba(227,112,112,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__label{background-color:rgba(101,122,148,.2);color:#fff;border:solid rgba(175,186,201,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__label:hover{background-color:rgba(175,186,201,.2)}.contentColor__label{background-color:#657a94;color:#fff;border:solid #8a9aae;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__label{background-color:rgba(101,122,148,.33);color:#fff;border:solid rgba(175,186,201,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__gold{background-color:rgba(214,146,12,.2);color:#000;border:solid rgba(243,197,103,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__gold:hover{background-color:rgba(243,197,103,.2)}.contentColor__gold{background-color:#d6920c;color:#000;border:solid #eeaf30;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__gold{background-color:rgba(214,146,12,.33);color:#000;border:solid rgba(243,197,103,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.color__default{background-color:rgba(53,53,53,.2);color:#fff;border:solid rgba(99,99,99,.2);border-width:1px;transition:background-color .2s,border-color .2s}.color__default:hover{background-color:rgba(99,99,99,.2)}.disabled{background-color:rgba(99,29,29,.25)!important;border-color:rgba(99,29,29,.25)!important}.selected{background-color:rgba(27,150,56,.2);color:#fff;border:solid rgba(27,150,56,.25);border-width:1px;transition:background-color .2s,border-color .2s}.selected:hover{background-color:rgba(72,214,105,.2)}.contentColor__default{background-color:#313131;color:#fff;border:solid #404040;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.contentDisabled{background-color:#631d1d!important;border-top:1px solid #803131!important}.contentSelected{background-color:#1b9638;color:#fff;border:solid #2fb94f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.buttonsContainerColor__default{background-color:rgba(53,53,53,.2);color:#fff;border:solid rgba(99,99,99,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.ImageButton .noAction{pointer-events:none}.ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.fluid:last-of-type{margin-bottom:0}.fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.fluid .title{font-weight:700;padding:.5em}.fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.fluid .contentFluid{padding:.5em;color:#fff}.fluid .container{flex-direction:row;flex:1}.fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.fluid .image{padding:0}.fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.Knob{position:relative;font-size:1rem;width:2.6em;height:2.6em;margin:0 auto -.2em;cursor:n-resize}.Knob:after{content:".";color:rgba(0,0,0,0);line-height:2.5em}.Knob__circle{position:absolute;top:.1em;bottom:.1em;left:.1em;right:.1em;margin:.3em;background-color:#333;background-image:linear-gradient(to bottom,rgba(255,255,255,.15),rgba(255,255,255,0));border-radius:50%;box-shadow:0 .05em .5em rgba(0,0,0,.5)}.Knob__cursorBox{position:absolute;top:0;bottom:0;left:0;right:0}.Knob__cursor{position:relative;top:.05em;margin:0 auto;width:.2em;height:.8em;background-color:rgba(255,255,255,.9)}.Knob__popupValue,.Knob__popupValue--right{position:absolute;top:-2rem;right:50%;font-size:1rem;text-align:center;padding:.25rem .5rem;color:#fff;background-color:#000;transform:translate(50%);white-space:nowrap}.Knob__popupValue--right{top:.25rem;right:-50%}.Knob__ring{position:absolute;top:0;bottom:0;left:0;right:0;padding:.1em}.Knob__ringTrackPivot{transform:rotate(135deg)}.Knob__ringTrack{fill:rgba(0,0,0,0);stroke:rgba(255,255,255,.1);stroke-width:8;stroke-linecap:round;stroke-dasharray:235.62}.Knob__ringFillPivot{transform:rotate(135deg)}.Knob--bipolar .Knob__ringFillPivot{transform:rotate(270deg)}.Knob__ringFill{fill:rgba(0,0,0,0);stroke:#6a96c9;stroke-width:8;stroke-linecap:round;stroke-dasharray:314.16;transition:stroke 50ms}.Knob--color--black .Knob__ringFill{stroke:#1a1a1a}.Knob--color--white .Knob__ringFill{stroke:#fff}.Knob--color--red .Knob__ringFill{stroke:#df3e3e}.Knob--color--orange .Knob__ringFill{stroke:#f37f33}.Knob--color--yellow .Knob__ringFill{stroke:#fbda21}.Knob--color--olive .Knob__ringFill{stroke:#cbe41c}.Knob--color--green .Knob__ringFill{stroke:#25ca4c}.Knob--color--teal .Knob__ringFill{stroke:#00d6cc}.Knob--color--blue .Knob__ringFill{stroke:#2e93de}.Knob--color--violet .Knob__ringFill{stroke:#7349cf}.Knob--color--purple .Knob__ringFill{stroke:#ad45d0}.Knob--color--pink .Knob__ringFill{stroke:#e34da1}.Knob--color--brown .Knob__ringFill{stroke:#b97447}.Knob--color--grey .Knob__ringFill{stroke:#848484}.Knob--color--good .Knob__ringFill{stroke:#68c22d}.Knob--color--average .Knob__ringFill{stroke:#f29a29}.Knob--color--bad .Knob__ringFill{stroke:#df3e3e}.Knob--color--label .Knob__ringFill{stroke:#8b9bb0}.Knob--color--gold .Knob__ringFill{stroke:#f3b22f}.LabeledList{display:table;width:100%;width:calc(100% + 1em);border-collapse:collapse;border-spacing:0;margin:-.25em -.5em 0;padding:0}.LabeledList__row{display:table-row}.LabeledList__row:last-child .LabeledList__cell{padding-bottom:0}.LabeledList__cell{display:table-cell;margin:0;padding:.25em .5em;border:0;text-align:left;vertical-align:baseline}.LabeledList__label{width:1%;white-space:nowrap;min-width:5em}.LabeledList__buttons{width:.1%;white-space:nowrap;text-align:right;padding-top:.0833333333em;padding-bottom:0}.LabeledList__breakContents{word-break:break-all;word-wrap:break-word}.Modal{background-color:#252525;max-width:calc(100% - 1rem);padding:1rem;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}.NanoMap__container{overflow:hidden;width:100%;height:100%;z-index:1}.NanoMap__marker{z-index:10;padding:0;margin:0}.NanoMap__zoomer{z-index:20;background-color:rgba(0,0,0,.33);position:absolute;top:30px;left:0;padding:.5rem;width:24%}.NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:700;font-style:italic;color:#000;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,transparent,transparent .8333333333em,rgba(0,0,0,.1) .8333333333em,rgba(0,0,0,.1) 1.6666666667em)}.NoticeBox--color--black{color:#fff;background-color:#000}.NoticeBox--color--white{color:#000;background-color:#b3b3b3}.NoticeBox--color--red{color:#fff;background-color:#701f1f}.NoticeBox--color--orange{color:#fff;background-color:#854114}.NoticeBox--color--yellow{color:#000;background-color:#83710d}.NoticeBox--color--olive{color:#000;background-color:#576015}.NoticeBox--color--green{color:#fff;background-color:#174e24}.NoticeBox--color--teal{color:#fff;background-color:#064845}.NoticeBox--color--blue{color:#fff;background-color:#1b4565}.NoticeBox--color--violet{color:#fff;background-color:#3b2864}.NoticeBox--color--purple{color:#fff;background-color:#542663}.NoticeBox--color--pink{color:#fff;background-color:#802257}.NoticeBox--color--brown{color:#fff;background-color:#4c3729}.NoticeBox--color--grey{color:#fff;background-color:#3e3e3e}.NoticeBox--color--good{color:#fff;background-color:#2e4b1a}.NoticeBox--color--average{color:#fff;background-color:#7b4e13}.NoticeBox--color--bad{color:#fff;background-color:#701f1f}.NoticeBox--color--label{color:#fff;background-color:#53565a}.NoticeBox--color--gold{color:#fff;background-color:#825d13}.NoticeBox--type--info{color:#fff;background-color:#235982}.NoticeBox--type--success{color:#fff;background-color:#1e662f}.NoticeBox--type--warning{color:#fff;background-color:#a95219}.NoticeBox--type--danger{color:#fff;background-color:#8f2828}.NumberInput{position:relative;display:inline-block;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;color:#88bfff;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.NumberInput--fluid{display:block}.NumberInput__content{margin-left:.5em}.NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #88bfff;background-color:#88bfff}.NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#0a0a0a;color:#fff;text-align:right}.ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:.16em;background-color:rgba(0,0,0,0);transition:border-color .5s}.ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.ProgressBar__fill--animated{transition:background-color .5s,width .5s}.ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.ProgressBar--color--default{border:.0833333333em solid #3e6189}.ProgressBar--color--default .ProgressBar__fill{background-color:#3e6189}.ProgressBar--color--disabled{border:1px solid #999}.ProgressBar--color--disabled .ProgressBar__fill{background-color:#999}.ProgressBar--color--black{border:.0833333333em solid #000!important}.ProgressBar--color--black .ProgressBar__fill{background-color:#000}.ProgressBar--color--white{border:.0833333333em solid #d9d9d9!important}.ProgressBar--color--white .ProgressBar__fill{background-color:#d9d9d9}.ProgressBar--color--red{border:.0833333333em solid #bd2020!important}.ProgressBar--color--red .ProgressBar__fill{background-color:#bd2020}.ProgressBar--color--orange{border:.0833333333em solid #d95e0c!important}.ProgressBar--color--orange .ProgressBar__fill{background-color:#d95e0c}.ProgressBar--color--yellow{border:.0833333333em solid #d9b804!important}.ProgressBar--color--yellow .ProgressBar__fill{background-color:#d9b804}.ProgressBar--color--olive{border:.0833333333em solid #9aad14!important}.ProgressBar--color--olive .ProgressBar__fill{background-color:#9aad14}.ProgressBar--color--green{border:.0833333333em solid #1b9638!important}.ProgressBar--color--green .ProgressBar__fill{background-color:#1b9638}.ProgressBar--color--teal{border:.0833333333em solid #009a93!important}.ProgressBar--color--teal .ProgressBar__fill{background-color:#009a93}.ProgressBar--color--blue{border:.0833333333em solid #1c71b1!important}.ProgressBar--color--blue .ProgressBar__fill{background-color:#1c71b1}.ProgressBar--color--violet{border:.0833333333em solid #552dab!important}.ProgressBar--color--violet .ProgressBar__fill{background-color:#552dab}.ProgressBar--color--purple{border:.0833333333em solid #8b2baa!important}.ProgressBar--color--purple .ProgressBar__fill{background-color:#8b2baa}.ProgressBar--color--pink{border:.0833333333em solid #cf2082!important}.ProgressBar--color--pink .ProgressBar__fill{background-color:#cf2082}.ProgressBar--color--brown{border:.0833333333em solid #8c5836!important}.ProgressBar--color--brown .ProgressBar__fill{background-color:#8c5836}.ProgressBar--color--grey{border:.0833333333em solid #646464!important}.ProgressBar--color--grey .ProgressBar__fill{background-color:#646464}.ProgressBar--color--good{border:.0833333333em solid #4d9121!important}.ProgressBar--color--good .ProgressBar__fill{background-color:#4d9121}.ProgressBar--color--average{border:.0833333333em solid #cd7a0d!important}.ProgressBar--color--average .ProgressBar__fill{background-color:#cd7a0d}.ProgressBar--color--bad{border:.0833333333em solid #bd2020!important}.ProgressBar--color--bad .ProgressBar__fill{background-color:#bd2020}.ProgressBar--color--label{border:.0833333333em solid #657a94!important}.ProgressBar--color--label .ProgressBar__fill{background-color:#657a94}.ProgressBar--color--gold{border:.0833333333em solid #d6920c!important}.ProgressBar--color--gold .ProgressBar__fill{background-color:#d6920c}.RoundGauge{font-size:1rem;width:2.6em;height:1.3em;margin:0 auto .2em}.RoundGauge__ringTrack{fill:rgba(0,0,0,0);stroke:rgba(255,255,255,.1);stroke-width:10;stroke-dasharray:157.08;stroke-dashoffset:157.08}.RoundGauge__ringFill{fill:rgba(0,0,0,0);stroke:#6a96c9;stroke-width:10;stroke-dasharray:314.16;transition:stroke 50ms}.RoundGauge__needle,.RoundGauge__ringFill{transition:transform 50ms ease-in-out}.RoundGauge__needleLine,.RoundGauge__needleMiddle{fill:#db2828}.RoundGauge__alert{fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;fill:rgba(255,255,255,.1)}.RoundGauge__alert.max{fill:#db2828}.RoundGauge--color--black.RoundGauge__ringFill{stroke:#1a1a1a}.RoundGauge--color--white.RoundGauge__ringFill{stroke:#fff}.RoundGauge--color--red.RoundGauge__ringFill{stroke:#df3e3e}.RoundGauge--color--orange.RoundGauge__ringFill{stroke:#f37f33}.RoundGauge--color--yellow.RoundGauge__ringFill{stroke:#fbda21}.RoundGauge--color--olive.RoundGauge__ringFill{stroke:#cbe41c}.RoundGauge--color--green.RoundGauge__ringFill{stroke:#25ca4c}.RoundGauge--color--teal.RoundGauge__ringFill{stroke:#00d6cc}.RoundGauge--color--blue.RoundGauge__ringFill{stroke:#2e93de}.RoundGauge--color--violet.RoundGauge__ringFill{stroke:#7349cf}.RoundGauge--color--purple.RoundGauge__ringFill{stroke:#ad45d0}.RoundGauge--color--pink.RoundGauge__ringFill{stroke:#e34da1}.RoundGauge--color--brown.RoundGauge__ringFill{stroke:#b97447}.RoundGauge--color--grey.RoundGauge__ringFill{stroke:#848484}.RoundGauge--color--good.RoundGauge__ringFill{stroke:#68c22d}.RoundGauge--color--average.RoundGauge__ringFill{stroke:#f29a29}.RoundGauge--color--bad.RoundGauge__ringFill{stroke:#df3e3e}.RoundGauge--color--label.RoundGauge__ringFill{stroke:#8b9bb0}.RoundGauge--color--gold.RoundGauge__ringFill{stroke:#f3b22f}.RoundGauge__alert--black{fill:#1a1a1a;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--white{fill:#fff;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--red{fill:#df3e3e;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--orange{fill:#f37f33;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--yellow{fill:#fbda21;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--olive{fill:#cbe41c;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--green{fill:#25ca4c;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--teal{fill:#00d6cc;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--blue{fill:#2e93de;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--violet{fill:#7349cf;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--purple{fill:#ad45d0;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--pink{fill:#e34da1;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--brown{fill:#b97447;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--grey{fill:#848484;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--good{fill:#68c22d;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--average{fill:#f29a29;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--bad{fill:#df3e3e;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--label{fill:#8b9bb0;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}.RoundGauge__alert--gold{fill:#f3b22f;transition:opacity .6s cubic-bezier(.25,1,.5,1);animation:RoundGauge__alertAnim 1s cubic-bezier(.34,1.56,.64,1) infinite}@keyframes RoundGauge__alertAnim{0%{opacity:.1}50%{opacity:1}to{opacity:.1}}.Section{position:relative;margin-bottom:.5em;background-color:#191919;background-color:rgba(0,0,0,.33);box-sizing:border-box}.Section:last-child{margin-bottom:0}.Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #4972a1}.Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.Section__rest{position:relative}.Section__content{padding:.66em .5em}.Section--fitted>.Section__rest>.Section__content{padding:0}.Section--fill{display:flex;flex-direction:column;height:100%}.Section--fill>.Section__rest{flex-grow:1}.Section--fill>.Section__rest>.Section__content{height:100%}.Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.Section--scrollable{overflow-x:hidden;overflow-y:hidden}.Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.Section .Section:first-child{margin-top:-.5em}.Section .Section .Section__titleText{font-size:1.0833333333em}.Section .Section .Section .Section__titleText{font-size:1em}.Slider:not(.Slider__disabled){cursor:e-resize}.Slider__cursorOffset{position:absolute;top:0;left:0;bottom:0;transition:none!important}.Slider__cursor{position:absolute;top:0;right:-.0833333333em;bottom:0;width:0;border-left:.1666666667em solid #fff}.Slider__pointer{position:absolute;right:-.4166666667em;bottom:-.3333333333em;width:0;height:0;border-left:.4166666667em solid rgba(0,0,0,0);border-right:.4166666667em solid rgba(0,0,0,0);border-bottom:.4166666667em solid #fff}.Slider__popupValue{position:absolute;right:0;top:-2rem;font-size:1rem;padding:.25rem .5rem;color:#fff;background-color:#000;transform:translate(50%);white-space:nowrap}.Divider--horizontal{margin:.5em 0}.Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.Divider--vertical{height:100%;margin:0 .5em}.Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.Stack--fill{height:100%}.Stack--horizontal>.Stack__item{margin-left:.5em}.Stack--horizontal>.Stack__item:first-child{margin-left:0}.Stack--vertical>.Stack__item{margin-top:.5em}.Stack--vertical>.Stack__item:first-child{margin-top:0}.Stack--zebra>.Stack__item:nth-child(2n){background-color:rgba(0,0,0,.33)}.Stack--horizontal>.Stack__divider:not(.Stack__divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.Stack--vertical>.Stack__divider:not(.Stack__divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.Table{display:table;width:100%;border-collapse:collapse;border-spacing:0;margin:0}.Table--collapsing{width:auto}.Table__row{display:table-row}.Table__cell{display:table-cell;padding:0 .25em}.Table__cell:first-child{padding-left:0}.Table__cell:last-child{padding-right:0}.Table__row--header .Table__cell,.Table__cell--header{font-weight:700;padding-bottom:.5em}.Table__cell--collapsing{width:1%;white-space:nowrap}.Tabs{display:flex;align-items:stretch;overflow:hidden;background-color:rgba(0,0,0,.33)}.Tabs--fill{height:100%}.Section .Tabs{background-color:rgba(0,0,0,0)}.Section:not(.Section--fitted) .Tabs{margin:0 -.5em .5em}.Section:not(.Section--fitted) .Tabs:first-child{margin-top:-.5em}.Tabs--vertical{flex-direction:column;padding:.25em .25em .25em 0}.Tabs--horizontal{margin-bottom:.5em;padding:.25em .25em 0}.Tabs--horizontal:last-child{margin-bottom:0}.Tabs__Tab{flex-grow:0}.Tabs--fluid .Tabs__Tab{flex-grow:1}.Tab{display:flex;align-items:center;justify-content:space-between;background-color:rgba(0,0,0,0);color:rgba(255,255,255,.5);min-height:2.25em;min-width:4em;transition:background-color 50ms ease-out}.Tab:not(.Tab--selected):hover{background-color:rgba(255,255,255,.075);transition:background-color 0}.Tab--selected{background-color:rgba(255,255,255,.125);color:#dfe7f0}.Tab__text{flex-grow:1;margin:0 .5em}.Tab__left{min-width:1.5em;text-align:center;margin-left:.25em}.Tab__right{min-width:1.5em;text-align:center;margin-right:.25em}.Tabs--horizontal .Tab{border-top:.1666666667em solid rgba(0,0,0,0);border-bottom:.1666666667em solid rgba(0,0,0,0);border-top-left-radius:.25em;border-top-right-radius:.25em}.Tabs--horizontal .Tab--selected{border-bottom:.1666666667em solid #d4dfec}.Tabs--vertical .Tab{min-height:2em;border-left:.1666666667em solid rgba(0,0,0,0);border-right:.1666666667em solid rgba(0,0,0,0);border-top-right-radius:.25em;border-bottom-right-radius:.25em}.Tabs--vertical .Tab--selected{border-left:.1666666667em solid #d4dfec}.Tab--selected.Tab--color--black{color:#535353}.Tabs--horizontal .Tab--selected.Tab--color--black{border-bottom-color:#1a1a1a}.Tabs--vertical .Tab--selected.Tab--color--black{border-left-color:#1a1a1a}.Tab--selected.Tab--color--white{color:#fff}.Tabs--horizontal .Tab--selected.Tab--color--white{border-bottom-color:#fff}.Tabs--vertical .Tab--selected.Tab--color--white{border-left-color:#fff}.Tab--selected.Tab--color--red{color:#e76e6e}.Tabs--horizontal .Tab--selected.Tab--color--red{border-bottom-color:#df3e3e}.Tabs--vertical .Tab--selected.Tab--color--red{border-left-color:#df3e3e}.Tab--selected.Tab--color--orange{color:#f69f66}.Tabs--horizontal .Tab--selected.Tab--color--orange{border-bottom-color:#f37f33}.Tabs--vertical .Tab--selected.Tab--color--orange{border-left-color:#f37f33}.Tab--selected.Tab--color--yellow{color:#fce358}.Tabs--horizontal .Tab--selected.Tab--color--yellow{border-bottom-color:#fbda21}.Tabs--vertical .Tab--selected.Tab--color--yellow{border-left-color:#fbda21}.Tab--selected.Tab--color--olive{color:#d8eb55}.Tabs--horizontal .Tab--selected.Tab--color--olive{border-bottom-color:#cbe41c}.Tabs--vertical .Tab--selected.Tab--color--olive{border-left-color:#cbe41c}.Tab--selected.Tab--color--green{color:#53e074}.Tabs--horizontal .Tab--selected.Tab--color--green{border-bottom-color:#25ca4c}.Tabs--vertical .Tab--selected.Tab--color--green{border-left-color:#25ca4c}.Tab--selected.Tab--color--teal{color:#21fff5}.Tabs--horizontal .Tab--selected.Tab--color--teal{border-bottom-color:#00d6cc}.Tabs--vertical .Tab--selected.Tab--color--teal{border-left-color:#00d6cc}.Tab--selected.Tab--color--blue{color:#62aee6}.Tabs--horizontal .Tab--selected.Tab--color--blue{border-bottom-color:#2e93de}.Tabs--vertical .Tab--selected.Tab--color--blue{border-left-color:#2e93de}.Tab--selected.Tab--color--violet{color:#9676db}.Tabs--horizontal .Tab--selected.Tab--color--violet{border-bottom-color:#7349cf}.Tabs--vertical .Tab--selected.Tab--color--violet{border-left-color:#7349cf}.Tab--selected.Tab--color--purple{color:#c274db}.Tabs--horizontal .Tab--selected.Tab--color--purple{border-bottom-color:#ad45d0}.Tabs--vertical .Tab--selected.Tab--color--purple{border-left-color:#ad45d0}.Tab--selected.Tab--color--pink{color:#ea79b9}.Tabs--horizontal .Tab--selected.Tab--color--pink{border-bottom-color:#e34da1}.Tabs--vertical .Tab--selected.Tab--color--pink{border-left-color:#e34da1}.Tab--selected.Tab--color--brown{color:#ca9775}.Tabs--horizontal .Tab--selected.Tab--color--brown{border-bottom-color:#b97447}.Tabs--vertical .Tab--selected.Tab--color--brown{border-left-color:#b97447}.Tab--selected.Tab--color--grey{color:#a3a3a3}.Tabs--horizontal .Tab--selected.Tab--color--grey{border-bottom-color:#848484}.Tabs--vertical .Tab--selected.Tab--color--grey{border-left-color:#848484}.Tab--selected.Tab--color--good{color:#8cd95a}.Tabs--horizontal .Tab--selected.Tab--color--good{border-bottom-color:#68c22d}.Tabs--vertical .Tab--selected.Tab--color--good{border-left-color:#68c22d}.Tab--selected.Tab--color--average{color:#f5b35e}.Tabs--horizontal .Tab--selected.Tab--color--average{border-bottom-color:#f29a29}.Tabs--vertical .Tab--selected.Tab--color--average{border-left-color:#f29a29}.Tab--selected.Tab--color--bad{color:#e76e6e}.Tabs--horizontal .Tab--selected.Tab--color--bad{border-bottom-color:#df3e3e}.Tabs--vertical .Tab--selected.Tab--color--bad{border-left-color:#df3e3e}.Tab--selected.Tab--color--label{color:#a8b4c4}.Tabs--horizontal .Tab--selected.Tab--color--label{border-bottom-color:#8b9bb0}.Tabs--vertical .Tab--selected.Tab--color--label{border-left-color:#8b9bb0}.Tab--selected.Tab--color--gold{color:#f6c563}.Tabs--horizontal .Tab--selected.Tab--color--gold{border-bottom-color:#f3b22f}.Tabs--vertical .Tab--selected.Tab--color--gold{border-left-color:#f3b22f}.Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.Input--disabled{color:#777;border-color:#848484;border-color:rgba(132,132,132,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.Input--fluid{display:block;width:auto}.Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input--monospace .Input__input{font-family:Consolas,monospace}.TextArea{position:relative;display:inline-block;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;background-color:#0a0a0a;margin-right:.1666666667em;line-height:1.4166666667em;box-sizing:border-box;width:100%}.TextArea--fluid{display:block;width:auto;height:auto}.TextArea__textarea{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;height:100%;font-size:1em;line-height:1.4166666667em;min-height:1.4166666667em;margin:0;padding:0 .5em;font-family:inherit;background-color:rgba(0,0,0,0);color:inherit;box-sizing:border-box;word-wrap:break-word;overflow:hidden}.TextArea__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.TextArea__textarea:-ms-input-placeholder{font-style:italic;color:rgba(125,125,125,.75)}.Tooltip{z-index:999;padding:.5em .75em;pointer-events:none;text-align:left;transition:opacity .15s ease-out;background-color:#000;color:#fff;box-shadow:.1em .1em 1.25em -.1em rgba(0,0,0,.5);border-radius:.16em;max-width:20.8333333333em}.AccountsUplinkTerminal__list tr>td{text-align:center}.AccountsUplinkTerminal__list tr:not(:first-child){height:24px;line-height:24px;cursor:pointer;transition:background-color 50ms}.AccountsUplinkTerminal__list tr:not(:first-child):hover,.AccountsUplinkTerminal__list tr:not(:first-child):focus{background-color:#252525}.AccountsUplinkTerminal__listRow--SUSPENDED{background-color:#740c20}.AlertModal__Message{text-align:center;justify-content:center}.AlertModal__Buttons{justify-content:center}.AlertModal__Loader{width:100%;position:relative;height:4px}.AlertModal__LoaderProgress{position:absolute;transition:background-color .5s ease-out,width .5s ease-out;background-color:#3e6189;height:100%}.BrigCells__list .Table__row--header,.BrigCells__list .Table__cell{text-align:center}.BrigCells__list .BrigCells__listRow--active .Table__cell{background-color:#890e26}.CameraConsole__left{position:absolute;top:0;bottom:0;left:0;width:18.3333333333em}.CameraConsole__right{position:absolute;top:0;bottom:0;left:18.3333333333em;right:0;background-color:rgba(0,0,0,.33)}.CameraConsole__toolbar{position:absolute;top:0;left:0;right:0;height:2em;line-height:2em;margin:.25em 1em 0}.CameraConsole__toolbarRight{position:absolute;top:0;right:0;height:2em;line-height:2em;margin:.33em .5em 0}.CameraConsole__map{position:absolute;top:2.1666666667em;bottom:0;left:0;right:0;margin:.5em;text-align:center}.CameraConsole__map .NoticeBox{margin-top:calc(50% - 2em)}.react-colorful{position:relative;display:flex;flex-direction:column;width:200px;height:200px;-ms-user-select:none;user-select:none;cursor:default}.react-colorful__saturation_value{position:relative;flex-grow:1;border-color:rgba(0,0,0,0);border-bottom:12px solid #000;border-radius:8px 8px 0 0;background-image:linear-gradient(to top,#000,rgba(0,0,0,0)),linear-gradient(to right,#fff,rgba(255,255,255,0))}.react-colorful__pointer-fill,.react-colorful__alpha-gradient{content:"";position:absolute;left:0;top:0;right:0;bottom:0;pointer-events:none;border-radius:inherit}.react-colorful__alpha-gradient,.react-colorful__saturation_value{box-shadow:inset 0 0 0 1px rgba(0,0,0,.05)}.react-colorful__hue,.react-colorful__r,.react-colorful__g,.react-colorful__b,.react-colorful__alpha,.react-colorful__saturation,.react-colorful__value{position:relative;height:24px}.react-colorful__hue{background:linear-gradient(to right,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red)}.react-colorful__r{background:linear-gradient(to right,#000,red)}.react-colorful__g{background:linear-gradient(to right,#000,#0f0)}.react-colorful__b{background:linear-gradient(to right,#000,#00f)}.react-colorful__last-control{border-radius:0 0 8px 8px}.react-colorful__interactive{position:absolute;left:0;top:0;right:0;bottom:0;border-radius:inherit;outline:none;touch-action:none}.react-colorful__pointer{position:absolute;z-index:1;box-sizing:border-box;width:28px;height:28px;transform:translate(-50%,-50%);background-color:#cfcfcf;border:2px solid #cfcfcf;border-radius:50%;box-shadow:0 2px 5px rgba(0,0,0,.4)}.react-colorful__interactive:focus .react-colorful__pointer{transform:translate(-50%,-50%) scale(1.1);background-color:#fff;border-color:#fff}.react-colorful__alpha,.react-colorful__alpha-pointer{background-color:#fff;background-image:url('data:image/svg+xml,')}.react-colorful__saturation-pointer,.react-colorful__value-pointer,.react-colorful__hue-pointer,.react-colorful__r-pointer,.react-colorful__g-pointer,.react-colorful__b-pointer{z-index:1;width:20px;height:20px}.react-colorful__saturation_value-pointer{z-index:3}.Contractor *{font-family:Courier New,Courier,monospace}.Contractor .Section__titleText{display:inline-block;max-width:70%}.Contractor .Section__titleText>.Flex{width:100%}.Contractor .Section__titleText>.Flex>.Flex__item:first-of-type{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.Contractor__Contract .Button{font-size:11px;white-space:normal!important}.Contractor__photoZoom{text-align:center}.Contractor__photoZoom>img{width:96px;-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.Contractor__photoZoom>.Button{position:absolute}.highlighted-marker{box-sizing:content-box;display:inline-block;position:relative;top:50%;left:50%;transform:translate(-50%,-50%);border-style:solid;border-width:50%;border-radius:50%;animation:1s infinite mark-shrink}@keyframes mark-shrink{0%{width:200%;height:200%}to{width:0%;height:0%}}.Exofab .Dropdown__control{margin-bottom:-1px}.Exofab .Dropdown__selected-text{overflow:hidden;text-overflow:ellipsis;width:80%;display:inline-block;margin-bottom:-3px}.Exofab__materials{height:100%;overflow:auto}.Exofab__materials .Section__content{height:calc(100% - 31px)}.Exofab__material:not(.Exofab__material--line){margin-bottom:.25rem}.Exofab__material:not(.Exofab__material--line) .Button{width:28px;margin-right:.5rem}.Exofab__material--line .Button{background-color:rgba(0,0,0,0);width:14px}.Exofab__material--name{color:#7e90a7;text-transform:capitalize}.Exofab__material .Button{margin-bottom:0;padding:0;vertical-align:middle}.Exofab__queue{height:100%}.Exofab__queue--queue .Button{margin:0;transform:scale(.75)}.Exofab__queue--queue .Button:first-of-type{margin-left:.25rem}.Exofab__queue--time{text-align:center;color:#7e90a7}.Exofab__queue--deficit{text-align:center;color:#db2828;font-weight:700}.Exofab__queue--deficit>div:not(.Divider){display:inline-block;margin-bottom:-.75rem}.Exofab__queue .Section__content{height:calc(100% - 31px)}.Exofab__queue .Exofab__material--amount{margin-right:.25rem}.Exofab__design--cost{display:inline-block;vertical-align:middle;margin-top:.25rem}.Exofab__design--cost>div{display:inline-block}.Exofab__design--cost .Exofab__material{margin-left:.25rem}.Exofab__design--time{display:inline-block;margin-left:.5rem;color:#7e90a7}.Exofab__design--time i{margin-right:.25rem}.Exofab__designs .Section__content{height:calc(100% - 31px);overflow:auto}.Exofab__building{height:45px}.Exofab__building .ProgressBar{width:100%;height:75%}.Exofab__building .ProgressBar__content{line-height:26px;text-align:right;font-size:12px;font-weight:700;display:flex;justify-content:flex-end}.Exofab__dropdown{line-height:14px;font-size:12px;width:225px;height:85%;margin-top:1.5px}.GeneModder__left{position:absolute;top:0;bottom:0;left:0;width:40.8333333333em}.GeneModder__right{position:absolute;top:0;bottom:0;left:40.8333333333em;right:0;background-color:rgba(0,0,0,.33)}.Ingredient__Table tr:nth-child(2n){background-color:#333}.Ingredient__Table td{padding:3px}.Library__Booklist tr>td{text-align:center}.Library__Booklist tr:not(:first-child){height:24px;line-height:24px;transition:background-color 50ms}.Library__Booklist tr:not(:first-child):hover,.Library__Booklist tr:not(:first-child):focus{background-color:#252525}.Library__SearchContainer{background-color:rgba(37,37,37,.5)}.Library__SearchContainer tr td:first-child{width:60%}.ListInput__Section .Section__title{flex-shrink:0}.ListInput__Section .Section__titleText{font-size:12px}.ListInput__Loader{width:100%;position:relative;height:4px}.ListInput__LoaderProgress{position:absolute;transition:background-color .5s,width .5s;background-color:#3e6189;height:100%}.Loadout-Modal__background{padding:.5em;background-color:#252525}.Loadout-InfoBox{display:flex;line-height:1.2rem;text-shadow:0 1px 0 2px rgba(0,0,0,.66);text-align:left}.Newscaster__menu{width:40px;height:100%;margin-right:.5rem;flex-basis:content}.Newscaster__menu .Section__content{padding-left:0}.Newscaster__menuButton{color:#767676;cursor:pointer;position:relative;margin-left:6px;margin-right:1rem;white-space:nowrap;transition:color .1s}.Newscaster__menuButton--title{width:80%;display:none;overflow:hidden;text-overflow:ellipsis}.Newscaster__menuButton--unread{background-color:#e45e5e;color:#fff;font-size:10px;text-align:center;border-radius:32px;display:inline-block;width:12px;position:absolute;left:16px;margin-top:14px}.Newscaster__menuButton--selected{color:#fff}.Newscaster__menuButton--selected:after{content:"";background-color:#4972a1;width:2px;height:24px;position:absolute;left:-6px}.Newscaster__menuButton--security{color:#4972a1}.Newscaster__menuButton i{width:30px;text-align:center;vertical-align:middle;margin-left:-1px;margin-right:.5rem;margin-top:1px}.Newscaster__menuButton:hover{color:#fff}.Newscaster__menuButton:hover:before{background-color:#fff}.Newscaster__menuButton:not(:last-of-type){margin-bottom:.5rem}.Newscaster__menu--open{width:175px}.Newscaster__menu--open .Newscaster__menuButton--title{display:inline-block}.Newscaster__jobCategory--security .Section__title{color:#a14c49;border-bottom:2px solid #a14c49!important}.Newscaster__jobCategory--engineering .Section__title{color:#a17849;border-bottom:2px solid #a17849!important}.Newscaster__jobCategory--medical .Section__title{color:#499ea1;border-bottom:2px solid #499ea1!important}.Newscaster__jobCategory--science .Section__title{color:#a14972;border-bottom:2px solid #a14972!important}.Newscaster__jobCategory--service .Section__title{color:#a1499e;border-bottom:2px solid #a1499e!important}.Newscaster__jobCategory--supply .Section__title{color:#9ea149;border-bottom:2px solid #9ea149!important}.Newscaster__jobCategory:last-child{margin-bottom:.5rem}.Newscaster__jobOpening--command{font-weight:700}.Newscaster__jobOpening:not(:last-child){margin-bottom:.5rem}.Newscaster__emptyNotice{color:#7e90a7;text-align:center;position:absolute;top:50%;left:50%;transform:translateY(-50%) translate(-50%)}.Newscaster__emptyNotice i{margin-bottom:.25rem}.Newscaster__photo{cursor:pointer;width:100px;border:1px solid #000;transition:border-color .3s;-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.Newscaster__photo:hover{border-color:gray}.Newscaster__photoZoom{text-align:center}.Newscaster__photoZoom>img{transform:scale(2);-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.Newscaster__photoZoom>.Button{position:absolute;width:64px;left:50%;margin-left:-32px;bottom:1rem}.Newscaster__story--wanted{background-color:rgba(219,40,40,.1)}.Newscaster__story--wanted .Section__title{color:#db2828;border-bottom:2px solid #a14c49!important}.Newscaster__story:last-child{margin-bottom:.5rem}.NuclearBomb__displayBox{background-color:#002003;border:.167em inset #e8e4c9;color:#03e017;font-size:2em;font-family:monospace;padding:.25em}.NuclearBomb__Button{outline-width:.25rem!important;border-width:.65rem!important;padding-left:0!important;padding-right:0!important}.NuclearBomb__Button--keypad{background-color:#e8e4c9;border-color:#e8e4c9}.NuclearBomb__Button--keypad:hover{background-color:#f7f6ee!important;border-color:#f7f6ee!important}.NuclearBomb__Button--1{background-color:#d3cfb7!important;border-color:#d3cfb7!important;color:#a9a692!important}.NuclearBomb__Button--E{background-color:#d9b804!important;border-color:#d9b804!important}.NuclearBomb__Button--E:hover{background-color:#f3d00e!important;border-color:#f3d00e!important}.NuclearBomb__Button--C{background-color:#bd2020!important;border-color:#bd2020!important}.NuclearBomb__Button--C:hover{background-color:#d52b2b!important;border-color:#d52b2b!important}.OreRedemption__Ores .OreLine,.OreRedemption__Ores .OreHeader{min-height:32px;padding:0 .5rem}.OreRedemption__Ores .OreHeader{line-height:32px;background-color:rgba(0,0,0,.33);font-weight:700}.OreRedemption__Ores .OreLine:last-of-type{margin-bottom:.5rem}.OreRedemption__Ores .Section__content{padding:0;height:100%;overflow:auto}.symptoms-table{border-collapse:separate;border-spacing:0 .5ex;height:100%}.symptoms-table>tbody>tr:first-child{width:100%;font-weight:700}.symptoms-table>tbody>tr:nth-child(2)>td:first-child{padding-top:.5ex}.symptoms-table>tbody>tr>td:nth-child(n+2){text-align:center}.common-name-label>.LabeledList__cell{vertical-align:middle}.table-spacer{height:100%}.remove-section-bottom-padding .Section__content{padding-bottom:0}.PDA__footer{position:fixed;bottom:0%;left:0%;right:0%;height:30px}.PDA__footer__button{text-align:center;padding-top:4px;padding-bottom:2px;font-size:24px}.Minesweeper__closed{vertical-align:middle;background-color:#353535;border:.1666666667em outset #676767}.Minesweeper__open{vertical-align:middle;text-align:center;font-size:medium;background-color:#4f4f4f!important}.Minesweeper__list tr>td{text-align:center}.Minesweeper__list tr:not(:first-child){height:2em;line-height:1.75em;transition:background-color 50ms;cursor:pointer}.Minesweeper__list tr:not(:first-child):hover,.Minesweeper__list tr:not(:first-child):focus{background-color:#252525}.Minesweeper__infobox{max-height:8em;border:.25em outset #3a3a3a;user-select:none;-ms-user-select:none}.PdaPainter__list tr>td{text-align:center}.PdaPainter__list tr{height:24px;line-height:24px;cursor:pointer;transition:background-color 50ms}.PdaPainter__list tr:hover,.PdaPainter__list tr:focus{background-color:#252525}.PoolController__Buttons .Button:not(:last-child){margin-bottom:8px}.reagents-table{border-collapse:separate;border-spacing:0 .3em}.volume-cell{min-width:3em;text-align:right;vertical-align:middle}.volume-cell:not(:hover) .volume-actions-wrapper{display:none}.volume-cell:hover .volume-label{display:none}.reagent-absent-name-cell{color:#767676}.reagent-row>*:last-child{padding-right:.5em}.absent-row:not(:hover) .add-reagent-button{visibility:hidden}.condensed-button{margin:0;padding:0;min-height:0;line-height:0;background:none}.RndConsole{position:relative}.RndConsole__Overlay{position:absolute;display:flex;align-items:stretch;justify-content:stretch;top:0;left:0;width:100%;height:100vh}.RndConsole__LatheCategory__MatchingDesigns .Table__cell{padding-bottom:4px}.RndConsole__LatheMaterials .Table__cell:nth-child(2){padding-left:16px}.RndConsole__LatheMaterialStorage .Table__cell{padding:4px 0;border-bottom:1px solid #767676}.RndConsole__Overlay__Wrapper{display:flex;align-items:center;justify-content:stretch;flex-grow:1;padding:24px;background-color:rgba(255,255,255,0)}.RndConsole__Overlay__Wrapper .NoticeBox{flex-grow:1;margin-bottom:80px;font-size:18pt;padding:.3em .75em}.RndConsole__RndNavbar .Button{margin-bottom:10px}#research-levels tr>*:first-child{width:2em}#research-levels tr>*:nth-child(3),#research-levels tr>*:nth-child(4),#research-levels tr>*:nth-child(5){text-align:center}#research-levels tr:not(:first-child)>*:first-child{height:2em}.upgraded-level{color:#55d355}.research-level-no-effect{color:#888}.Roulette{font-family:Palatino}.Roulette__board{display:table;width:100%;border-collapse:collapse;border:2px solid #fff;margin:0}.Roulette__board-row{padding:0;margin:0}.Roulette__board-cell{display:table-cell;padding:0;margin:0;border:2px solid #fff;font-family:Palatino}.Roulette__board-cell:first-child{padding-left:0}.Roulette__board-cell:last-child{padding-right:0}.Roulette__board-extrabutton{text-align:center;font-size:20px;font-weight:700;height:28px;border:none!important;margin:0!important;padding-top:4px!important;color:#fff!important}.Roulette__lowertable{margin-top:8px;margin-left:80px;margin-right:80px;border-collapse:collapse;border:2px solid #fff;border-spacing:0}.Roulette__lowertable--cell{border:2px solid #fff;padding:0;margin:0}.Roulette__lowertable--betscell{vertical-align:top}.Roulette__lowertable--spinresult{text-align:center;font-size:100px;font-weight:700;vertical-align:middle}.Roulette__lowertable--spinresult-black{background-color:#000}.Roulette__lowertable--spinresult-red{background-color:#db2828}.Roulette__lowertable--spinresult-green{background-color:#20b142}.Roulette__lowertable--spinbutton{margin:0!important;border:none!important;font-size:50px;line-height:60px!important;text-align:center;font-weight:700}.Roulette__lowertable--header{width:1%;text-align:center;font-size:20px;font-weight:700}.Safe--engraving{position:absolute;width:95%;height:96%;left:2.5%;top:2%;border:5px outset #364963;padding:5px;text-align:center}.Safe--engraving--arrow{color:#35435a}.Safe--engraving--hinge{content:" ";background-color:#191f2a;width:25px;height:40px;position:absolute;right:-15px;margin-top:-20px}.Safe--dialer{margin-bottom:.5rem}.Safe--dialer--number{color:#bbb;display:inline;background-color:#191f2a;font-size:1.5rem;font-weight:700;padding:0 .5rem}.Safe--dialer--right .Button i{z-index:-100}.Safe--dialer .Button{width:80px}.Safe--contents{border:10px solid #191f2a;background-color:#0f131a;height:calc(85% + 7.5px);text-align:left;padding:5px}.Safe--help{position:absolute;bottom:30px;left:25px;width:50%}.SecureStorage__displayBox{background-color:#212121;color:#8b8b8b;border:.167em inset #e8e4c9;font-size:375%;font-family:monospace;padding:.25em}.SecureStorage__displayBox--good{background-color:#002003;color:#03e017}.SecureStorage__displayBox--bad{background-color:#210000;color:#e00202}.SecureStorage__Button{outline-width:.25rem!important;border-width:.3rem!important;border:.167em outset #e8e4c9;padding-left:0!important;padding-right:0!important}.SecureStorage__Button--keypad{background-color:#e8e4c9;border-color:#e8e4c9;color:#a9a692}.SecureStorage__Button--keypad:hover{background-color:#f7f6ee;border-color:#f7f6ee;color:#a9a692}.SecureStorage__Button--E{background-color:#d9b804;border-color:#d9b804;color:#fff}.SecureStorage__Button--E:hover{background-color:#f5d317;border-color:#f5d317;color:#fff}.SecureStorage__Button--C{background-color:#bd2020;border-color:#bd2020;color:#fff}.SecureStorage__Button--C:hover{background-color:#d83434;border-color:#d83434;color:#fff}.SecurityRecords__list tr>td{text-align:center}.SecurityRecords__list tr:not(:first-child){height:24px;line-height:24px;cursor:pointer;transition:background-color 50ms}.SecurityRecords__list tr:not(:first-child):hover,.SecurityRecords__list tr:not(:first-child):focus{background-color:#252525}.SecurityRecords__listRow--arrest{background-color:#740c20}.SecurityRecords__listRow--execute{background-color:#683e8c}.SecurityRecords__listRow--incarcerated{background-color:#633203}.SecurityRecords__listRow--parolled{background-color:#006d7b}.SecurityRecords__listRow--released{background-color:#1c5574}.SecurityRecords__listRow--demote{background-color:#155500}.SecurityRecords__listRow--search{background-color:#987a00}.SecurityRecords__listRow--monitor{background-color:#1f1180}.SeedExtractor__list tr:not(:first-child){height:24px;line-height:24px;cursor:pointer;transition:background-color 50ms}.SeedExtractor__list tr:not(:first-child):hover,.SeedExtractor__list tr:not(:first-child):focus{background-color:#252525}.MedicalRecords__list tr>td{text-align:center}.MedicalRecords__list tr:not(:first-child){height:24px;line-height:24px;cursor:pointer;transition:background-color 50ms}.MedicalRecords__list tr:not(:first-child):hover,.MedicalRecords__list tr:not(:first-child):focus{background-color:#252525}.MedicalRecords__listRow--deceased{background-color:#740c20}.MedicalRecords__listRow--ssd{background-color:#006d7b}.MedicalRecords__listRow--physically_unfit{background-color:#987a00}.MedicalRecords__listRow--disabled{background-color:#1f1180}.MedicalRecords__listMedbot--0{background-color:#2b1414}html,body{scrollbar-color:#3b3b3b #1c1c1c}.Layout,.Layout *{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}.Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.Layout__content--flexRow{display:flex;flex-flow:row}.Layout__content--flexColumn{display:flex;flex-flow:column}.Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.Layout__content--noMargin{margin:0}.TitleBar{background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#363636;transition:color .25s,background-color .25s}.TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#252525;background-image:linear-gradient(to bottom,#2a2a2a,#202020)}.Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.Window__contentPadding:after{height:0}.Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(62,62,62,.25);pointer-events:none}.Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.Layout__content{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMCIgdmlld0JveD0iMCAwIDQyNSAyMDAiIG9wYWNpdHk9Ii4zMyI+PHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPjxwYXRoIGQ9Ik0gNC44NDQ2MzMzLDIyLjEwODc1IEEgMTMuNDEyMDM5LDEyLjUwMTg0MiAwIDAgMSAxMy40Nzc1ODgsMC4wMzkyNCBsIDY2LjExODMxNSwwIGEgNS4zNjQ4MTU4LDUuMDAwNzM3IDAgMCAxIDUuMzY0ODIzLDUuMDAwNzMgbCAwLDc5Ljg3OTMxIHoiIC8+PHBhdGggZD0ibSA0MjAuMTU1MzUsMTc3Ljg5MTE5IGEgMTMuNDEyMDM4LDEyLjUwMTg0MiAwIDAgMSAtOC42MzI5NSwyMi4wNjk1MSBsIC02Ni4xMTgzMiwwIGEgNS4zNjQ4MTUyLDUuMDAwNzM3IDAgMCAxIC01LjM2NDgyLC01LjAwMDc0IGwgMCwtNzkuODc5MzEgeiIgLz48L3N2Zz48IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT48IS0tIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LXNhLzQuMC8gLS0+);background-size:70% 70%;background-position:center;background-repeat:no-repeat}.theme-abductor .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-abductor .Button:last-child{margin-right:0;margin-bottom:0}.theme-abductor .Button .fa,.theme-abductor .Button .fas,.theme-abductor .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-abductor .Button--hasContent .fa,.theme-abductor .Button--hasContent .fas,.theme-abductor .Button--hasContent .far{margin-right:.25em}.theme-abductor .Button--hasContent.Button--iconRight .fa,.theme-abductor .Button--hasContent.Button--iconRight .fas,.theme-abductor .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-abductor .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-abductor .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-abductor .Button--circular{border-radius:50%}.theme-abductor .Button--compact{padding:0 .25em;line-height:1.333em}.theme-abductor .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-abductor .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-abductor .Button--color--transparent{background-color:rgba(42,49,74,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-abductor .Button--color--transparent:hover{background-color:rgba(62,70,100,.81);color:#fff}.theme-abductor .Button--color--default{background-color:#ad2350;color:#fff;transition:color .2s,background-color .2s}.theme-abductor .Button--color--default:hover{background-color:#d03a6b;color:#fff}.theme-abductor .Button--color--default--translucent{background-color:rgba(50,58,84,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-abductor .Button--color--default--translucent:hover{background-color:rgba(73,82,111,.5);color:#fff}.theme-abductor .Button--color--caution{background-color:#be6209;color:#fff;transition:color .2s,background-color .2s}.theme-abductor .Button--color--caution:hover{background-color:#e67f1a;color:#fff}.theme-abductor .Button--color--caution--translucent{background-color:rgba(190,98,9,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-abductor .Button--color--caution--translucent:hover{background-color:rgba(230,127,26,.5);color:#fff}.theme-abductor .Button--color--danger{background-color:#9a9d00;color:#fff;transition:color .2s,background-color .2s}.theme-abductor .Button--color--danger:hover{background-color:#bec110;color:#fff}.theme-abductor .Button--color--danger--translucent{background-color:rgba(154,157,0,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-abductor .Button--color--danger--translucent:hover{background-color:rgba(190,193,16,.5);color:#fff}.theme-abductor .Button--disabled{background-color:#363636!important;color:rgba(255,255,255,.75)!important}.theme-abductor .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-abductor .Button--selected,.theme-abductor .Button--selected--translucent{background-color:#465899;color:#fff;transition:color .2s,background-color .2s}.theme-abductor .Button--selected:hover,.theme-abductor .Button--selected--translucent:hover{background-color:#6577b5;color:#fff}.theme-abductor .Divider--horizontal{margin:.5em 0}.theme-abductor .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-abductor .Divider--vertical{height:100%;margin:0 .5em}.theme-abductor .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-abductor .color__default{background-color:rgba(180,80,112,.2);color:#fff;border:solid rgba(219,170,186,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-abductor .color__default:hover{background-color:rgba(219,170,186,.2)}.theme-abductor .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-abductor .selected{background-color:rgba(70,88,153,.2);color:#fff;border:solid rgba(70,88,153,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-abductor .selected:hover{background-color:rgba(142,155,201,.2)}.theme-abductor .contentColor__default{background-color:#af4c6c;color:#fff;border:solid #c45b7d;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-abductor .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-abductor .contentSelected{background-color:#465899;color:#fff;border:solid #6577b5;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-abductor .buttonsContainerColor__default{background-color:rgba(180,80,112,.2);color:#fff;border:solid rgba(219,170,186,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-abductor .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-abductor .ImageButton .noAction{pointer-events:none}.theme-abductor .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-abductor .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-abductor .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-abductor .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-abductor .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-abductor .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-abductor .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-abductor .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-abductor .fluid:last-of-type{margin-bottom:0}.theme-abductor .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-abductor .fluid .title{font-weight:700;padding:.5em}.theme-abductor .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-abductor .fluid .contentFluid{padding:.5em;color:#fff}.theme-abductor .fluid .container{flex-direction:row;flex:1}.theme-abductor .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-abductor .fluid .image{padding:0}.theme-abductor .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-abductor .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-abductor .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-abductor .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-abductor .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-abductor .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-abductor .NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:700;font-style:italic;color:#fff;background-color:#a82d55;background-image:repeating-linear-gradient(-45deg,transparent,transparent .8333333333em,rgba(0,0,0,.1) .8333333333em,rgba(0,0,0,.1) 1.6666666667em)}.theme-abductor .NoticeBox--type--info{color:#fff;background-color:#235982}.theme-abductor .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-abductor .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-abductor .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-abductor .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #404b6e;border:.0833333333em solid rgba(64,75,110,.75);border-radius:2px;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-abductor .Input--disabled{color:#777;border-color:#171717;border-color:rgba(23,23,23,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-abductor .Input--fluid{display:block;width:auto}.theme-abductor .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-abductor .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-abductor .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-abductor .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-abductor .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-abductor .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-abductor .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-abductor .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-abductor .NumberInput{position:relative;display:inline-block;border:.0833333333em solid #404b6e;border:.0833333333em solid rgba(64,75,110,.75);border-radius:2px;color:#404b6e;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.theme-abductor .NumberInput--fluid{display:block}.theme-abductor .NumberInput__content{margin-left:.5em}.theme-abductor .NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.theme-abductor .NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #404b6e;background-color:#404b6e}.theme-abductor .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#0a0a0a;color:#fff;text-align:right}.theme-abductor .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:2px;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-abductor .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-abductor .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-abductor .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-abductor .ProgressBar--color--default{border:.0833333333em solid #931e44}.theme-abductor .ProgressBar--color--default .ProgressBar__fill{background-color:#931e44}.theme-abductor .ProgressBar--color--disabled{border:1px solid #363636}.theme-abductor .ProgressBar--color--disabled .ProgressBar__fill{background-color:#363636}.theme-abductor .Section{position:relative;margin-bottom:.5em;background-color:#1c2132;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-abductor .Section:last-child{margin-bottom:0}.theme-abductor .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #ad2350}.theme-abductor .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-abductor .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-abductor .Section__rest{position:relative}.theme-abductor .Section__content{padding:.66em .5em}.theme-abductor .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-abductor .Section--fill{display:flex;flex-direction:column;height:100%}.theme-abductor .Section--fill>.Section__rest{flex-grow:1}.theme-abductor .Section--fill>.Section__rest>.Section__content{height:100%}.theme-abductor .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-abductor .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-abductor .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-abductor .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-abductor .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-abductor .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-abductor .Section .Section:first-child{margin-top:-.5em}.theme-abductor .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-abductor .Section .Section .Section .Section__titleText{font-size:1em}.theme-abductor .Tooltip{z-index:999;padding:.5em .75em;pointer-events:none;text-align:left;transition:opacity .15s ease-out;background-color:#a82d55;color:#fff;box-shadow:.1em .1em 1.25em -.1em rgba(0,0,0,.5);border-radius:2px;max-width:20.8333333333em}.theme-abductor html,.theme-abductor body{scrollbar-color:#384263 #202538}.theme-abductor .Layout,.theme-abductor .Layout *{scrollbar-base-color:#202538;scrollbar-face-color:#384263;scrollbar-3dlight-color:#2a314a;scrollbar-highlight-color:#2a314a;scrollbar-track-color:#202538;scrollbar-arrow-color:#818db8;scrollbar-shadow-color:#384263}.theme-abductor .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-abductor .Layout__content--flexRow{display:flex;flex-flow:row}.theme-abductor .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-abductor .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-abductor .Layout__content--noMargin{margin:0}.theme-abductor .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#2a314a;background-image:linear-gradient(to bottom,#353e5e,#1f2436)}.theme-abductor .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-abductor .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-abductor .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-abductor .Window__contentPadding:after{height:0}.theme-abductor .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-abductor .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(68,76,104,.25);pointer-events:none}.theme-abductor .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-abductor .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-abductor .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-abductor .TitleBar{background-color:#9e1b46;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-abductor .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#9e1b46;transition:color .25s,background-color .25s}.theme-abductor .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-abductor .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-abductor .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-abductor .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-abductor .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-abductor .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-abductor .Layout__content{background-image:none}.theme-cardtable .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:0;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-cardtable .Button:last-child{margin-right:0;margin-bottom:0}.theme-cardtable .Button .fa,.theme-cardtable .Button .fas,.theme-cardtable .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-cardtable .Button--hasContent .fa,.theme-cardtable .Button--hasContent .fas,.theme-cardtable .Button--hasContent .far{margin-right:.25em}.theme-cardtable .Button--hasContent.Button--iconRight .fa,.theme-cardtable .Button--hasContent.Button--iconRight .fas,.theme-cardtable .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-cardtable .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-cardtable .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-cardtable .Button--circular{border-radius:50%}.theme-cardtable .Button--compact{padding:0 .25em;line-height:1.333em}.theme-cardtable .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-cardtable .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-cardtable .Button--color--transparent{background-color:rgba(17,112,57,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-cardtable .Button--color--transparent:hover{background-color:rgba(32,145,79,.81);color:#fff}.theme-cardtable .Button--color--default{background-color:#117039;color:#fff;transition:color .2s,background-color .2s}.theme-cardtable .Button--color--default:hover{background-color:#238e50;color:#fff}.theme-cardtable .Button--color--default--translucent{background-color:rgba(25,124,67,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-cardtable .Button--color--default--translucent:hover{background-color:rgba(44,156,92,.5);color:#fff}.theme-cardtable .Button--color--caution{background-color:#be6209;color:#fff;transition:color .2s,background-color .2s}.theme-cardtable .Button--color--caution:hover{background-color:#e67f1a;color:#fff}.theme-cardtable .Button--color--caution--translucent{background-color:rgba(190,98,9,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-cardtable .Button--color--caution--translucent:hover{background-color:rgba(230,127,26,.5);color:#fff}.theme-cardtable .Button--color--danger{background-color:#9a9d00;color:#fff;transition:color .2s,background-color .2s}.theme-cardtable .Button--color--danger:hover{background-color:#bec110;color:#fff}.theme-cardtable .Button--color--danger--translucent{background-color:rgba(154,157,0,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-cardtable .Button--color--danger--translucent:hover{background-color:rgba(190,193,16,.5);color:#fff}.theme-cardtable .Button--disabled{background-color:#363636!important;color:rgba(255,255,255,.75)!important}.theme-cardtable .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-cardtable .Button--selected,.theme-cardtable .Button--selected--translucent{background-color:#9d0808;color:#fff;transition:color .2s,background-color .2s}.theme-cardtable .Button--selected:hover,.theme-cardtable .Button--selected--translucent:hover{background-color:#c11919;color:#fff}.theme-cardtable .Divider--horizontal{margin:.5em 0}.theme-cardtable .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-cardtable .Divider--vertical{height:100%;margin:0 .5em}.theme-cardtable .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-cardtable .color__default{background-color:rgba(78,214,135,.2);color:#000;border:solid rgba(190,240,210,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-cardtable .color__default:hover{background-color:rgba(190,240,210,.2)}.theme-cardtable .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-cardtable .selected{background-color:rgba(157,8,8,.2);color:#fff;border:solid rgba(157,8,8,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-cardtable .selected:hover{background-color:rgba(229,42,42,.2)}.theme-cardtable .contentColor__default{background-color:#4bd083;color:#000;border:solid #5be695;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-cardtable .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-cardtable .contentSelected{background-color:#9d0808;color:#fff;border:solid #c11919;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-cardtable .buttonsContainerColor__default{background-color:rgba(78,214,135,.2);color:#000;border:solid rgba(190,240,210,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-cardtable .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-cardtable .ImageButton .noAction{pointer-events:none}.theme-cardtable .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-cardtable .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-cardtable .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-cardtable .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-cardtable .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-cardtable .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-cardtable .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-cardtable .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-cardtable .fluid:last-of-type{margin-bottom:0}.theme-cardtable .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-cardtable .fluid .title{font-weight:700;padding:.5em}.theme-cardtable .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-cardtable .fluid .contentFluid{padding:.5em;color:#fff}.theme-cardtable .fluid .container{flex-direction:row;flex:1}.theme-cardtable .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-cardtable .fluid .image{padding:0}.theme-cardtable .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-cardtable .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-cardtable .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-cardtable .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-cardtable .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-cardtable .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-cardtable .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:0;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-cardtable .Input--disabled{color:#777;border-color:#848484;border-color:rgba(132,132,132,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-cardtable .Input--fluid{display:block;width:auto}.theme-cardtable .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-cardtable .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-cardtable .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-cardtable .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-cardtable .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-cardtable .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-cardtable .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-cardtable .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-cardtable .NumberInput{position:relative;display:inline-block;border:.0833333333em solid #fff;border:.0833333333em solid rgba(255,255,255,.75);border-radius:0;color:#fff;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.theme-cardtable .NumberInput--fluid{display:block}.theme-cardtable .NumberInput__content{margin-left:.5em}.theme-cardtable .NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.theme-cardtable .NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #fff;background-color:#fff}.theme-cardtable .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#0a0a0a;color:#fff;text-align:right}.theme-cardtable .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:0;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-cardtable .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-cardtable .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-cardtable .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-cardtable .ProgressBar--color--default{border:.0833333333em solid #000}.theme-cardtable .ProgressBar--color--default .ProgressBar__fill{background-color:#000}.theme-cardtable .ProgressBar--color--disabled{border:1px solid #363636}.theme-cardtable .ProgressBar--color--disabled .ProgressBar__fill{background-color:#363636}.theme-cardtable .Section{position:relative;margin-bottom:.5em;background-color:#0b4b26;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-cardtable .Section:last-child{margin-bottom:0}.theme-cardtable .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #000}.theme-cardtable .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-cardtable .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-cardtable .Section__rest{position:relative}.theme-cardtable .Section__content{padding:.66em .5em}.theme-cardtable .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-cardtable .Section--fill{display:flex;flex-direction:column;height:100%}.theme-cardtable .Section--fill>.Section__rest{flex-grow:1}.theme-cardtable .Section--fill>.Section__rest>.Section__content{height:100%}.theme-cardtable .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-cardtable .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-cardtable .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-cardtable .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-cardtable .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-cardtable .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-cardtable .Section .Section:first-child{margin-top:-.5em}.theme-cardtable .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-cardtable .Section .Section .Section .Section__titleText{font-size:1em}.theme-cardtable html,.theme-cardtable body{scrollbar-color:#20d36c #0d542b}.theme-cardtable .Layout,.theme-cardtable .Layout *{scrollbar-base-color:#0d542b;scrollbar-face-color:#16914a;scrollbar-3dlight-color:#117039;scrollbar-highlight-color:#117039;scrollbar-track-color:#0d542b;scrollbar-arrow-color:#5ae695;scrollbar-shadow-color:#16914a}.theme-cardtable .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-cardtable .Layout__content--flexRow{display:flex;flex-flow:row}.theme-cardtable .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-cardtable .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-cardtable .Layout__content--noMargin{margin:0}.theme-cardtable .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#117039;background-image:linear-gradient(to bottom,#117039,#117039)}.theme-cardtable .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-cardtable .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-cardtable .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-cardtable .Window__contentPadding:after{height:0}.theme-cardtable .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-cardtable .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(39,148,85,.25);pointer-events:none}.theme-cardtable .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-cardtable .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-cardtable .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-cardtable .TitleBar{background-color:#381608;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-cardtable .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#381608;transition:color .25s,background-color .25s}.theme-cardtable .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-cardtable .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-cardtable .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-cardtable .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-cardtable .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-cardtable .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-cardtable .Button{border:.1666666667em solid #fff}.theme-changeling .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-changeling .Button:last-child{margin-right:0;margin-bottom:0}.theme-changeling .Button .fa,.theme-changeling .Button .fas,.theme-changeling .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-changeling .Button--hasContent .fa,.theme-changeling .Button--hasContent .fas,.theme-changeling .Button--hasContent .far{margin-right:.25em}.theme-changeling .Button--hasContent.Button--iconRight .fa,.theme-changeling .Button--hasContent.Button--iconRight .fas,.theme-changeling .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-changeling .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-changeling .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-changeling .Button--circular{border-radius:50%}.theme-changeling .Button--compact{padding:0 .25em;line-height:1.333em}.theme-changeling .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-changeling .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-changeling .Button--color--transparent{background-color:rgba(46,38,51,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-changeling .Button--color--transparent:hover{background-color:rgba(67,57,73,.81);color:#fff}.theme-changeling .Button--color--default{background-color:#563d6b;color:#fff;transition:color .2s,background-color .2s}.theme-changeling .Button--color--default:hover{background-color:#715589;color:#fff}.theme-changeling .Button--color--default--translucent{background-color:rgba(55,47,60,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-changeling .Button--color--default--translucent:hover{background-color:rgba(78,69,84,.5);color:#fff}.theme-changeling .Button--color--caution{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.theme-changeling .Button--color--caution:hover{background-color:#f5d523;color:#000}.theme-changeling .Button--color--caution--translucent{background-color:rgba(217,184,4,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-changeling .Button--color--caution--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.theme-changeling .Button--color--danger{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.theme-changeling .Button--color--danger:hover{background-color:#d93f3f;color:#fff}.theme-changeling .Button--color--danger--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-changeling .Button--color--danger--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.theme-changeling .Button--disabled{background-color:#999!important;color:rgba(255,255,255,.75)!important}.theme-changeling .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-changeling .Button--selected,.theme-changeling .Button--selected--translucent{background-color:#188552;color:#fff;transition:color .2s,background-color .2s}.theme-changeling .Button--selected:hover,.theme-changeling .Button--selected--translucent:hover{background-color:#2ba66d;color:#fff}.theme-changeling .Divider--horizontal{margin:.5em 0}.theme-changeling .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-changeling .Divider--vertical{height:100%;margin:0 .5em}.theme-changeling .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-changeling .color__default{background-color:rgba(103,88,114,.2);color:#fff;border:solid rgba(160,147,170,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-changeling .color__default:hover{background-color:rgba(160,147,170,.2)}.theme-changeling .disabled{background-color:rgba(99,29,29,.25)!important;border-color:rgba(99,29,29,.25)!important}.theme-changeling .selected{background-color:rgba(24,133,82,.2);color:#fff;border:solid rgba(24,133,82,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-changeling .selected:hover{background-color:rgba(62,199,135,.2)}.theme-changeling .contentColor__default{background-color:#63556e;color:#fff;border:solid #73647f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-changeling .contentDisabled{background-color:#631d1d!important;border-top:1px solid #803131!important}.theme-changeling .contentSelected{background-color:#188552;color:#fff;border:solid #2ba66d;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-changeling .buttonsContainerColor__default{background-color:rgba(103,88,114,.2);color:#fff;border:solid rgba(160,147,170,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-changeling .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-changeling .ImageButton .noAction{pointer-events:none}.theme-changeling .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-changeling .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-changeling .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-changeling .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-changeling .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-changeling .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-changeling .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-changeling .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-changeling .fluid:last-of-type{margin-bottom:0}.theme-changeling .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-changeling .fluid .title{font-weight:700;padding:.5em}.theme-changeling .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-changeling .fluid .contentFluid{padding:.5em;color:#fff}.theme-changeling .fluid .container{flex-direction:row;flex:1}.theme-changeling .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-changeling .fluid .image{padding:0}.theme-changeling .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-changeling .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-changeling .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-changeling .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-changeling .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-changeling .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-changeling .Section{position:relative;margin-bottom:.5em;background-color:#1f1922;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-changeling .Section:last-child{margin-bottom:0}.theme-changeling .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #563d6b}.theme-changeling .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-changeling .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-changeling .Section__rest{position:relative}.theme-changeling .Section__content{padding:.66em .5em}.theme-changeling .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-changeling .Section--fill{display:flex;flex-direction:column;height:100%}.theme-changeling .Section--fill>.Section__rest{flex-grow:1}.theme-changeling .Section--fill>.Section__rest>.Section__content{height:100%}.theme-changeling .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-changeling .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-changeling .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-changeling .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-changeling .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-changeling .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-changeling .Section .Section:first-child{margin-top:-.5em}.theme-changeling .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-changeling .Section .Section .Section .Section__titleText{font-size:1em}.theme-changeling .Tabs{display:flex;align-items:stretch;overflow:hidden;background-color:rgba(0,0,0,.33)}.theme-changeling .Tabs--fill{height:100%}.theme-changeling .Section .Tabs{background-color:rgba(0,0,0,0)}.theme-changeling .Section:not(.Section--fitted) .Tabs{margin:0 -.5em .5em}.theme-changeling .Section:not(.Section--fitted) .Tabs:first-child{margin-top:-.5em}.theme-changeling .Tabs--vertical{flex-direction:column;padding:.25em .25em .25em 0}.theme-changeling .Tabs--horizontal{margin-bottom:.5em;padding:.25em .25em 0}.theme-changeling .Tabs--horizontal:last-child{margin-bottom:0}.theme-changeling .Tabs__Tab{flex-grow:0}.theme-changeling .Tabs--fluid .Tabs__Tab{flex-grow:1}.theme-changeling .Tab{display:flex;align-items:center;justify-content:space-between;background-color:rgba(0,0,0,0);color:rgba(255,255,255,.5);min-height:2.25em;min-width:4em;transition:background-color 50ms ease-out}.theme-changeling .Tab:not(.Tab--selected):hover{background-color:rgba(255,255,255,.075);transition:background-color 0}.theme-changeling .Tab--selected{background-color:#563d6b;color:#e3daea}.theme-changeling .Tab__text{flex-grow:1;margin:0 .5em}.theme-changeling .Tab__left{min-width:1.5em;text-align:center;margin-left:.25em}.theme-changeling .Tab__right{min-width:1.5em;text-align:center;margin-right:.25em}.theme-changeling .Tabs--horizontal .Tab{border-top:.1666666667em solid rgba(0,0,0,0);border-bottom:.1666666667em solid rgba(0,0,0,0);border-top-left-radius:.25em;border-top-right-radius:.25em}.theme-changeling .Tabs--horizontal .Tab--selected{border-bottom:.1666666667em solid #d9cee3}.theme-changeling .Tabs--vertical .Tab{min-height:2em;border-left:.1666666667em solid rgba(0,0,0,0);border-right:.1666666667em solid rgba(0,0,0,0);border-top-right-radius:.25em;border-bottom-right-radius:.25em}.theme-changeling .Tabs--vertical .Tab--selected{border-left:.1666666667em solid #d9cee3}.theme-changeling html,.theme-changeling body{scrollbar-color:#44384b #231d26}.theme-changeling .Layout,.theme-changeling .Layout *{scrollbar-base-color:#231d26;scrollbar-face-color:#44384b;scrollbar-3dlight-color:#2e2633;scrollbar-highlight-color:#2e2633;scrollbar-track-color:#231d26;scrollbar-arrow-color:#9986a5;scrollbar-shadow-color:#44384b}.theme-changeling .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-changeling .Layout__content--flexRow{display:flex;flex-flow:row}.theme-changeling .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-changeling .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-changeling .Layout__content--noMargin{margin:0}.theme-changeling .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#2e2633;background-image:linear-gradient(to bottom,#3e3345,#1e1921)}.theme-changeling .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-changeling .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-changeling .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-changeling .Window__contentPadding:after{height:0}.theme-changeling .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-changeling .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(72,63,78,.25);pointer-events:none}.theme-changeling .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-changeling .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-changeling .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-changeling .TitleBar{background-color:#352d3b;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-changeling .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#352d3b;transition:color .25s,background-color .25s}.theme-changeling .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-changeling .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-changeling .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-changeling .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-changeling .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-changeling .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-changeling .Layout__content{background-image:none}.theme-hackerman .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-hackerman .Button:last-child{margin-right:0;margin-bottom:0}.theme-hackerman .Button .fa,.theme-hackerman .Button .fas,.theme-hackerman .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-hackerman .Button--hasContent .fa,.theme-hackerman .Button--hasContent .fas,.theme-hackerman .Button--hasContent .far{margin-right:.25em}.theme-hackerman .Button--hasContent.Button--iconRight .fa,.theme-hackerman .Button--hasContent.Button--iconRight .fas,.theme-hackerman .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-hackerman .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-hackerman .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-hackerman .Button--circular{border-radius:50%}.theme-hackerman .Button--compact{padding:0 .25em;line-height:1.333em}.theme-hackerman .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-hackerman .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-hackerman .Button--color--transparent{background-color:rgba(18,27,18,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hackerman .Button--color--transparent:hover{background-color:rgba(34,44,34,.81);color:#fff}.theme-hackerman .Button--color--default{background-color:#0f0;color:#000;transition:color .2s,background-color .2s}.theme-hackerman .Button--color--default:hover{background-color:#40ff40;color:#000}.theme-hackerman .Button--color--default--translucent{background-color:rgba(26,35,26,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hackerman .Button--color--default--translucent:hover{background-color:rgba(46,56,46,.5);color:#fff}.theme-hackerman .Button--color--caution{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.theme-hackerman .Button--color--caution:hover{background-color:#f5d523;color:#000}.theme-hackerman .Button--color--caution--translucent{background-color:rgba(217,184,4,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hackerman .Button--color--caution--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.theme-hackerman .Button--color--danger{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.theme-hackerman .Button--color--danger:hover{background-color:#d93f3f;color:#fff}.theme-hackerman .Button--color--danger--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hackerman .Button--color--danger--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.theme-hackerman .Button--disabled{background-color:#363636!important;color:rgba(255,255,255,.75)!important}.theme-hackerman .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-hackerman .Button--selected,.theme-hackerman .Button--selected--translucent{background-color:#0f0;color:#000;transition:color .2s,background-color .2s}.theme-hackerman .Button--selected:hover,.theme-hackerman .Button--selected--translucent:hover{background-color:#40ff40;color:#000}.theme-hackerman .Divider--horizontal{margin:.5em 0}.theme-hackerman .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-hackerman .Divider--vertical{height:100%;margin:0 .5em}.theme-hackerman .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-hackerman .color__default{background-color:rgba(54,236,54,.2);color:#000;border:solid rgba(178,248,178,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-hackerman .color__default:hover{background-color:rgba(178,248,178,.2)}.theme-hackerman .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-hackerman .selected{background-color:rgba(128,255,128,.2);color:#000;border:solid rgba(128,255,128,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-hackerman .selected:hover{background-color:rgba(239,255,239,.2)}.theme-hackerman .contentColor__default{background-color:#33e633;color:#000;border:solid #40ff40;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-hackerman .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-hackerman .contentSelected{background-color:#80ff80;color:#000;border:solid #cfffcf;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-hackerman .buttonsContainerColor__default{background-color:rgba(54,236,54,.2);color:#000;border:solid rgba(178,248,178,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-hackerman .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-hackerman .ImageButton .noAction{pointer-events:none}.theme-hackerman .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-hackerman .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-hackerman .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-hackerman .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-hackerman .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-hackerman .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-hackerman .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-hackerman .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-hackerman .fluid:last-of-type{margin-bottom:0}.theme-hackerman .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-hackerman .fluid .title{font-weight:700;padding:.5em}.theme-hackerman .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-hackerman .fluid .contentFluid{padding:.5em;color:#fff}.theme-hackerman .fluid .container{flex-direction:row;flex:1}.theme-hackerman .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-hackerman .fluid .image{padding:0}.theme-hackerman .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-hackerman .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-hackerman .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-hackerman .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-hackerman .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-hackerman .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-hackerman .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid lime;border:.0833333333em solid rgba(0,255,0,.75);border-radius:.16em;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-hackerman .Input--disabled{color:#777;border-color:#404040;border-color:rgba(64,64,64,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-hackerman .Input--fluid{display:block;width:auto}.theme-hackerman .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-hackerman .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-hackerman .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hackerman .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hackerman .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-hackerman .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hackerman .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hackerman .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-hackerman .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:.16em;background-color:rgba(0,0,0,0);transition:border-color .5s}.theme-hackerman .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-hackerman .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-hackerman .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-hackerman .ProgressBar--color--default{border:.0833333333em solid #00d900}.theme-hackerman .ProgressBar--color--default .ProgressBar__fill{background-color:#00d900}.theme-hackerman .ProgressBar--color--disabled{border:1px solid #363636}.theme-hackerman .ProgressBar--color--disabled .ProgressBar__fill{background-color:#363636}.theme-hackerman .Modal{background-color:#121b12;max-width:calc(100% - 1rem);padding:1rem;scrollbar-base-color:#0e140e;scrollbar-face-color:#253725;scrollbar-3dlight-color:#121b12;scrollbar-highlight-color:#121b12;scrollbar-track-color:#0e140e;scrollbar-arrow-color:#74a274;scrollbar-shadow-color:#253725}.theme-hackerman .Section{position:relative;margin-bottom:.5em;background-color:#0c120c;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-hackerman .Section:last-child{margin-bottom:0}.theme-hackerman .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid lime}.theme-hackerman .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-hackerman .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-hackerman .Section__rest{position:relative}.theme-hackerman .Section__content{padding:.66em .5em}.theme-hackerman .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-hackerman .Section--fill{display:flex;flex-direction:column;height:100%}.theme-hackerman .Section--fill>.Section__rest{flex-grow:1}.theme-hackerman .Section--fill>.Section__rest>.Section__content{height:100%}.theme-hackerman .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-hackerman .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-hackerman .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-hackerman .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-hackerman .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-hackerman .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-hackerman .Section .Section:first-child{margin-top:-.5em}.theme-hackerman .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-hackerman .Section .Section .Section .Section__titleText{font-size:1em}.theme-hackerman html,.theme-hackerman body{scrollbar-color:#253725 #0e140e}.theme-hackerman .Layout,.theme-hackerman .Layout *{scrollbar-base-color:#0e140e;scrollbar-face-color:#253725;scrollbar-3dlight-color:#121b12;scrollbar-highlight-color:#121b12;scrollbar-track-color:#0e140e;scrollbar-arrow-color:#74a274;scrollbar-shadow-color:#253725}.theme-hackerman .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-hackerman .Layout__content--flexRow{display:flex;flex-flow:row}.theme-hackerman .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-hackerman .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-hackerman .Layout__content--noMargin{margin:0}.theme-hackerman .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#121b12;background-image:linear-gradient(to bottom,#121b12,#121b12)}.theme-hackerman .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-hackerman .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-hackerman .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-hackerman .Window__contentPadding:after{height:0}.theme-hackerman .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-hackerman .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(40,50,40,.25);pointer-events:none}.theme-hackerman .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-hackerman .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-hackerman .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-hackerman .TitleBar{background-color:#223d22;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-hackerman .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#223d22;transition:color .25s,background-color .25s}.theme-hackerman .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-hackerman .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-hackerman .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-hackerman .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-hackerman .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-hackerman .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-hackerman .Layout__content{background-image:none}.theme-hackerman .Button{font-family:monospace;border-width:.1666666667em;border-style:outset;border-color:#0a0;outline:.0833333333em solid #007a00}.theme-hackerman .candystripe:nth-child(odd){background-color:rgba(0,100,0,.5)}.theme-hydroponics .color-label{color:#8bb08b!important}.theme-hydroponics .color-bg-good{background-color:#4d9121!important}.theme-hydroponics .color-border-label{border-color:#8bb08b!important}.theme-hydroponics .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-hydroponics .Button:last-child{margin-right:0;margin-bottom:0}.theme-hydroponics .Button .fa,.theme-hydroponics .Button .fas,.theme-hydroponics .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-hydroponics .Button--hasContent .fa,.theme-hydroponics .Button--hasContent .fas,.theme-hydroponics .Button--hasContent .far{margin-right:.25em}.theme-hydroponics .Button--hasContent.Button--iconRight .fa,.theme-hydroponics .Button--hasContent.Button--iconRight .fas,.theme-hydroponics .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-hydroponics .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-hydroponics .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-hydroponics .Button--circular{border-radius:50%}.theme-hydroponics .Button--compact{padding:0 .25em;line-height:1.333em}.theme-hydroponics .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-hydroponics .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-hydroponics .Button--color--good{background-color:#4d9121;color:#fff;transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--good:hover{background-color:#67b335;color:#fff}.theme-hydroponics .Button--color--good--translucent{background-color:rgba(77,145,33,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--good--translucent:hover{background-color:rgba(103,179,53,.5);color:#fff}.theme-hydroponics .Button--color--transparent{background-color:rgba(37,37,37,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--transparent:hover{background-color:rgba(56,56,56,.81);color:#fff}.theme-hydroponics .Button--color--default{background-color:#49a149;color:#fff;transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--default:hover{background-color:#6dbb6d;color:#fff}.theme-hydroponics .Button--color--default--translucent{background-color:rgba(46,46,46,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--default--translucent:hover{background-color:rgba(68,68,68,.5);color:#fff}.theme-hydroponics .Button--color--caution{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--caution:hover{background-color:#f5d523;color:#000}.theme-hydroponics .Button--color--caution--translucent{background-color:rgba(217,184,4,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--caution--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.theme-hydroponics .Button--color--danger{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--danger:hover{background-color:#d93f3f;color:#fff}.theme-hydroponics .Button--color--danger--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-hydroponics .Button--color--danger--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.theme-hydroponics .Button--disabled{background-color:#999!important;color:rgba(255,255,255,.75)!important}.theme-hydroponics .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-hydroponics .Button--selected,.theme-hydroponics .Button--selected--translucent{background-color:#1b9638;color:#fff;transition:color .2s,background-color .2s}.theme-hydroponics .Button--selected:hover,.theme-hydroponics .Button--selected--translucent:hover{background-color:#2fb94f;color:#fff}.theme-hydroponics .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #8f8;border:.0833333333em solid rgba(136,255,136,.75);border-radius:.16em;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-hydroponics .Input--disabled{color:#777;border-color:#848484;border-color:rgba(132,132,132,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-hydroponics .Input--fluid{display:block;width:auto}.theme-hydroponics .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-hydroponics .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-hydroponics .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hydroponics .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hydroponics .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-hydroponics .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hydroponics .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-hydroponics .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-hydroponics .NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:700;font-style:italic;color:#000;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,transparent,transparent .8333333333em,rgba(0,0,0,.1) .8333333333em,rgba(0,0,0,.1) 1.6666666667em)}.theme-hydroponics .NoticeBox--color--good{color:#fff;background-color:#2e4b1a}.theme-hydroponics .NoticeBox--type--info{color:#000;background-color:#238223}.theme-hydroponics .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-hydroponics .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-hydroponics .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-hydroponics .Section{position:relative;margin-bottom:.5em;background-color:#191919;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-hydroponics .Section:last-child{margin-bottom:0}.theme-hydroponics .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #49a149}.theme-hydroponics .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-hydroponics .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-hydroponics .Section__rest{position:relative}.theme-hydroponics .Section__content{padding:.66em .5em}.theme-hydroponics .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-hydroponics .Section--fill{display:flex;flex-direction:column;height:100%}.theme-hydroponics .Section--fill>.Section__rest{flex-grow:1}.theme-hydroponics .Section--fill>.Section__rest>.Section__content{height:100%}.theme-hydroponics .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-hydroponics .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-hydroponics .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-hydroponics .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-hydroponics .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-hydroponics .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-hydroponics .Section .Section:first-child{margin-top:-.5em}.theme-hydroponics .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-hydroponics .Section .Section .Section .Section__titleText{font-size:1em}.theme-hydroponics .Newscaster__menu{width:40px;height:100%;margin-right:.5rem;flex-basis:content}.theme-hydroponics .Newscaster__menu .Section__content{padding-left:0}.theme-hydroponics .Newscaster__menuButton{color:#767676;cursor:pointer;position:relative;margin-left:6px;margin-right:1rem;white-space:nowrap;transition:color .1s}.theme-hydroponics .Newscaster__menuButton--title{width:80%;display:none;overflow:hidden;text-overflow:ellipsis}.theme-hydroponics .Newscaster__menuButton--unread{background-color:#e45e5e;color:#fff;font-size:10px;text-align:center;border-radius:32px;display:inline-block;width:12px;position:absolute;left:16px;margin-top:14px}.theme-hydroponics .Newscaster__menuButton--selected{color:#fff}.theme-hydroponics .Newscaster__menuButton--selected:after{content:"";background-color:#49a149;width:2px;height:24px;position:absolute;left:-6px}.theme-hydroponics .Newscaster__menuButton--security{color:#49a149}.theme-hydroponics .Newscaster__menuButton i{width:30px;text-align:center;vertical-align:middle;margin-left:-1px;margin-right:.5rem;margin-top:1px}.theme-hydroponics .Newscaster__menuButton:hover{color:#fff}.theme-hydroponics .Newscaster__menuButton:hover:before{background-color:#fff}.theme-hydroponics .Newscaster__menuButton:not(:last-of-type){margin-bottom:.5rem}.theme-hydroponics .Newscaster__menu--open{width:175px}.theme-hydroponics .Newscaster__menu--open .Newscaster__menuButton--title{display:inline-block}.theme-hydroponics .Newscaster__jobCategory--security .Section__title{color:#a14c49;border-bottom:2px solid #a14c49!important}.theme-hydroponics .Newscaster__jobCategory--engineering .Section__title{color:#a17849;border-bottom:2px solid #a17849!important}.theme-hydroponics .Newscaster__jobCategory--medical .Section__title{color:#499ea1;border-bottom:2px solid #499ea1!important}.theme-hydroponics .Newscaster__jobCategory--science .Section__title{color:#a14972;border-bottom:2px solid #a14972!important}.theme-hydroponics .Newscaster__jobCategory--service .Section__title{color:#a1499e;border-bottom:2px solid #a1499e!important}.theme-hydroponics .Newscaster__jobCategory--supply .Section__title{color:#9ea149;border-bottom:2px solid #9ea149!important}.theme-hydroponics .Newscaster__jobCategory:last-child{margin-bottom:.5rem}.theme-hydroponics .Newscaster__jobOpening--command{font-weight:700}.theme-hydroponics .Newscaster__jobOpening:not(:last-child){margin-bottom:.5rem}.theme-hydroponics .Newscaster__emptyNotice{color:#7ea77e;text-align:center;position:absolute;top:50%;left:50%;transform:translateY(-50%) translate(-50%)}.theme-hydroponics .Newscaster__emptyNotice i{margin-bottom:.25rem}.theme-hydroponics .Newscaster__photo{cursor:pointer;width:100px;border:1px solid #000;transition:border-color .3s;-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.theme-hydroponics .Newscaster__photo:hover{border-color:gray}.theme-hydroponics .Newscaster__photoZoom{text-align:center}.theme-hydroponics .Newscaster__photoZoom>img{transform:scale(2);-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.theme-hydroponics .Newscaster__photoZoom>.Button{position:absolute;width:64px;left:50%;margin-left:-32px;bottom:1rem}.theme-hydroponics .Newscaster__story--wanted{background-color:rgba(219,40,40,.1)}.theme-hydroponics .Newscaster__story--wanted .Section__title{color:#db2828;border-bottom:2px solid #a14c49!important}.theme-hydroponics .Newscaster__story:last-child{margin-bottom:.5rem}.theme-malfunction .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-malfunction .Button:last-child{margin-right:0;margin-bottom:0}.theme-malfunction .Button .fa,.theme-malfunction .Button .fas,.theme-malfunction .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-malfunction .Button--hasContent .fa,.theme-malfunction .Button--hasContent .fas,.theme-malfunction .Button--hasContent .far{margin-right:.25em}.theme-malfunction .Button--hasContent.Button--iconRight .fa,.theme-malfunction .Button--hasContent.Button--iconRight .fas,.theme-malfunction .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-malfunction .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-malfunction .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-malfunction .Button--circular{border-radius:50%}.theme-malfunction .Button--compact{padding:0 .25em;line-height:1.333em}.theme-malfunction .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-malfunction .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-malfunction .Button--color--transparent{background-color:rgba(27,52,67,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-malfunction .Button--color--transparent:hover{background-color:rgba(44,74,92,.81);color:#fff}.theme-malfunction .Button--color--default{background-color:#910101;color:#fff;transition:color .2s,background-color .2s}.theme-malfunction .Button--color--default:hover{background-color:#b31111;color:#fff}.theme-malfunction .Button--color--default--translucent{background-color:rgba(35,61,77,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-malfunction .Button--color--default--translucent:hover{background-color:rgba(56,85,103,.5);color:#fff}.theme-malfunction .Button--color--caution{background-color:#be6209;color:#fff;transition:color .2s,background-color .2s}.theme-malfunction .Button--color--caution:hover{background-color:#e67f1a;color:#fff}.theme-malfunction .Button--color--caution--translucent{background-color:rgba(190,98,9,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-malfunction .Button--color--caution--translucent:hover{background-color:rgba(230,127,26,.5);color:#fff}.theme-malfunction .Button--color--danger{background-color:#9a9d00;color:#fff;transition:color .2s,background-color .2s}.theme-malfunction .Button--color--danger:hover{background-color:#bec110;color:#fff}.theme-malfunction .Button--color--danger--translucent{background-color:rgba(154,157,0,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-malfunction .Button--color--danger--translucent:hover{background-color:rgba(190,193,16,.5);color:#fff}.theme-malfunction .Button--disabled{background-color:#363636!important;color:rgba(255,255,255,.75)!important}.theme-malfunction .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-malfunction .Button--selected,.theme-malfunction .Button--selected--translucent{background-color:#1e5881;color:#fff;transition:color .2s,background-color .2s}.theme-malfunction .Button--selected:hover,.theme-malfunction .Button--selected--translucent:hover{background-color:#3273a1;color:#fff}.theme-malfunction .Divider--horizontal{margin:.5em 0}.theme-malfunction .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-malfunction .Divider--vertical{height:100%;margin:0 .5em}.theme-malfunction .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-malfunction .color__default{background-color:rgba(117,55,55,.2);color:#fff;border:solid rgba(177,102,102,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-malfunction .color__default:hover{background-color:rgba(177,102,102,.2)}.theme-malfunction .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-malfunction .selected{background-color:rgba(30,88,129,.2);color:#fff;border:solid rgba(30,88,129,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-malfunction .selected:hover{background-color:rgba(70,142,194,.2)}.theme-malfunction .contentColor__default{background-color:#713434;color:#fff;border:solid #814141;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-malfunction .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-malfunction .contentSelected{background-color:#1e5881;color:#fff;border:solid #3273a1;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-malfunction .buttonsContainerColor__default{background-color:rgba(117,55,55,.2);color:#fff;border:solid rgba(177,102,102,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-malfunction .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-malfunction .ImageButton .noAction{pointer-events:none}.theme-malfunction .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-malfunction .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-malfunction .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-malfunction .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-malfunction .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-malfunction .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-malfunction .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-malfunction .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-malfunction .fluid:last-of-type{margin-bottom:0}.theme-malfunction .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-malfunction .fluid .title{font-weight:700;padding:.5em}.theme-malfunction .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-malfunction .fluid .contentFluid{padding:.5em;color:#fff}.theme-malfunction .fluid .container{flex-direction:row;flex:1}.theme-malfunction .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-malfunction .fluid .image{padding:0}.theme-malfunction .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-malfunction .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-malfunction .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-malfunction .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-malfunction .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-malfunction .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-malfunction .NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:700;font-style:italic;color:#fff;background-color:#1a3f57;background-image:repeating-linear-gradient(-45deg,transparent,transparent .8333333333em,rgba(0,0,0,.1) .8333333333em,rgba(0,0,0,.1) 1.6666666667em)}.theme-malfunction .NoticeBox--type--info{color:#fff;background-color:#235982}.theme-malfunction .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-malfunction .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-malfunction .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-malfunction .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #910101;border:.0833333333em solid rgba(145,1,1,.75);border-radius:.16em;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-malfunction .Input--disabled{color:#777;border-color:#090909;border-color:rgba(9,9,9,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-malfunction .Input--fluid{display:block;width:auto}.theme-malfunction .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-malfunction .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-malfunction .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-malfunction .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-malfunction .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-malfunction .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-malfunction .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-malfunction .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-malfunction .NumberInput{position:relative;display:inline-block;border:.0833333333em solid #910101;border:.0833333333em solid rgba(145,1,1,.75);border-radius:.16em;color:#910101;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.theme-malfunction .NumberInput--fluid{display:block}.theme-malfunction .NumberInput__content{margin-left:.5em}.theme-malfunction .NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.theme-malfunction .NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #910101;background-color:#910101}.theme-malfunction .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#0a0a0a;color:#fff;text-align:right}.theme-malfunction .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:.16em;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-malfunction .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-malfunction .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-malfunction .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-malfunction .ProgressBar--color--default{border:.0833333333em solid #7b0101}.theme-malfunction .ProgressBar--color--default .ProgressBar__fill{background-color:#7b0101}.theme-malfunction .ProgressBar--color--disabled{border:1px solid #363636}.theme-malfunction .ProgressBar--color--disabled .ProgressBar__fill{background-color:#363636}.theme-malfunction .Section{position:relative;margin-bottom:.5em;background-color:#12232d;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-malfunction .Section:last-child{margin-bottom:0}.theme-malfunction .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #910101}.theme-malfunction .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-malfunction .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-malfunction .Section__rest{position:relative}.theme-malfunction .Section__content{padding:.66em .5em}.theme-malfunction .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-malfunction .Section--fill{display:flex;flex-direction:column;height:100%}.theme-malfunction .Section--fill>.Section__rest{flex-grow:1}.theme-malfunction .Section--fill>.Section__rest>.Section__content{height:100%}.theme-malfunction .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-malfunction .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-malfunction .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-malfunction .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-malfunction .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-malfunction .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-malfunction .Section .Section:first-child{margin-top:-.5em}.theme-malfunction .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-malfunction .Section .Section .Section .Section__titleText{font-size:1em}.theme-malfunction .Tooltip{z-index:999;padding:.5em .75em;pointer-events:none;text-align:left;transition:opacity .15s ease-out;background-color:#235577;color:#fff;box-shadow:.1em .1em 1.25em -.1em rgba(0,0,0,.5);border-radius:.16em;max-width:20.8333333333em}.theme-malfunction html,.theme-malfunction body{scrollbar-color:#274b61 #142732}.theme-malfunction .Layout,.theme-malfunction .Layout *{scrollbar-base-color:#142732;scrollbar-face-color:#274b61;scrollbar-3dlight-color:#1b3443;scrollbar-highlight-color:#1b3443;scrollbar-track-color:#142732;scrollbar-arrow-color:#6ba2c3;scrollbar-shadow-color:#274b61}.theme-malfunction .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-malfunction .Layout__content--flexRow{display:flex;flex-flow:row}.theme-malfunction .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-malfunction .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-malfunction .Layout__content--noMargin{margin:0}.theme-malfunction .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#1b3443;background-image:linear-gradient(to bottom,#244559,#12232d)}.theme-malfunction .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-malfunction .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-malfunction .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-malfunction .Window__contentPadding:after{height:0}.theme-malfunction .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-malfunction .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(50,79,96,.25);pointer-events:none}.theme-malfunction .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-malfunction .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-malfunction .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-malfunction .TitleBar{background-color:#1a3f57;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-malfunction .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#1a3f57;transition:color .25s,background-color .25s}.theme-malfunction .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-malfunction .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-malfunction .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-malfunction .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-malfunction .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-malfunction .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-malfunction .Layout__content{background-image:none}.theme-ntos .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-ntos .Button:last-child{margin-right:0;margin-bottom:0}.theme-ntos .Button .fa,.theme-ntos .Button .fas,.theme-ntos .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-ntos .Button--hasContent .fa,.theme-ntos .Button--hasContent .fas,.theme-ntos .Button--hasContent .far{margin-right:.25em}.theme-ntos .Button--hasContent.Button--iconRight .fa,.theme-ntos .Button--hasContent.Button--iconRight .fas,.theme-ntos .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-ntos .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-ntos .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-ntos .Button--circular{border-radius:50%}.theme-ntos .Button--compact{padding:0 .25em;line-height:1.333em}.theme-ntos .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-ntos .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-ntos .Button--color--transparent{background-color:rgba(31,43,57,0);color:rgba(227,240,255,.75);transition:color .2s,background-color .2s}.theme-ntos .Button--color--transparent:hover{background-color:rgba(49,63,80,.81);color:#fff}.theme-ntos .Button--color--default{background-color:#384e68;color:#fff;transition:color .2s,background-color .2s}.theme-ntos .Button--color--default:hover{background-color:#4f6885;color:#fff}.theme-ntos .Button--color--default--translucent{background-color:rgba(39,51,67,.33);color:rgba(227,240,255,.75);transition:color .2s,background-color .2s}.theme-ntos .Button--color--default--translucent:hover{background-color:rgba(60,74,92,.5);color:#fff}.theme-ntos .Button--color--caution{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.theme-ntos .Button--color--caution:hover{background-color:#f5d523;color:#000}.theme-ntos .Button--color--caution--translucent{background-color:rgba(217,184,4,.33);color:rgba(227,240,255,.75);transition:color .2s,background-color .2s}.theme-ntos .Button--color--caution--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.theme-ntos .Button--color--danger{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.theme-ntos .Button--color--danger:hover{background-color:#d93f3f;color:#fff}.theme-ntos .Button--color--danger--translucent{background-color:rgba(189,32,32,.33);color:rgba(227,240,255,.75);transition:color .2s,background-color .2s}.theme-ntos .Button--color--danger--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.theme-ntos .Button--disabled{background-color:#999!important;color:rgba(227,240,255,.75)!important}.theme-ntos .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(227,240,255,.75)!important}.theme-ntos .Button--selected,.theme-ntos .Button--selected--translucent{background-color:#1b9638;color:#fff;transition:color .2s,background-color .2s}.theme-ntos .Button--selected:hover,.theme-ntos .Button--selected--translucent:hover{background-color:#2fb94f;color:#fff}.theme-ntos .Divider--horizontal{margin:.5em 0}.theme-ntos .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-ntos .Divider--vertical{height:100%;margin:0 .5em}.theme-ntos .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-ntos .color__default{background-color:rgba(96,112,131,.2);color:#fff;border:solid rgba(162,173,186,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-ntos .color__default:hover{background-color:rgba(162,173,186,.2)}.theme-ntos .disabled{background-color:rgba(99,29,29,.25)!important;border-color:rgba(99,29,29,.25)!important}.theme-ntos .selected{background-color:rgba(27,150,56,.2);color:#fff;border:solid rgba(27,150,56,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-ntos .selected:hover{background-color:rgba(72,214,105,.2)}.theme-ntos .contentColor__default{background-color:#5c6c7f;color:#fff;border:solid #6b7d92;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-ntos .contentDisabled{background-color:#631d1d!important;border-top:1px solid #803131!important}.theme-ntos .contentSelected{background-color:#1b9638;color:#fff;border:solid #2fb94f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-ntos .buttonsContainerColor__default{background-color:rgba(96,112,131,.2);color:#fff;border:solid rgba(162,173,186,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-ntos .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-ntos .ImageButton .noAction{pointer-events:none}.theme-ntos .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-ntos .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-ntos .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-ntos .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-ntos .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-ntos .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-ntos .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-ntos .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-ntos .fluid:last-of-type{margin-bottom:0}.theme-ntos .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-ntos .fluid .title{font-weight:700;padding:.5em}.theme-ntos .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-ntos .fluid .contentFluid{padding:.5em;color:#fff}.theme-ntos .fluid .container{flex-direction:row;flex:1}.theme-ntos .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-ntos .fluid .image{padding:0}.theme-ntos .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-ntos .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-ntos .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-ntos .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-ntos .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-ntos .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-ntos .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:.16em;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-ntos .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-ntos .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-ntos .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-ntos .ProgressBar--color--default{border:.0833333333em solid #384e68}.theme-ntos .ProgressBar--color--default .ProgressBar__fill{background-color:#384e68}.theme-ntos .ProgressBar--color--disabled{border:1px solid #999}.theme-ntos .ProgressBar--color--disabled .ProgressBar__fill{background-color:#999}.theme-ntos .Section{position:relative;margin-bottom:.5em;background-color:#151d26;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-ntos .Section:last-child{margin-bottom:0}.theme-ntos .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #4972a1}.theme-ntos .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-ntos .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-ntos .Section__rest{position:relative}.theme-ntos .Section__content{padding:.66em .5em}.theme-ntos .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-ntos .Section--fill{display:flex;flex-direction:column;height:100%}.theme-ntos .Section--fill>.Section__rest{flex-grow:1}.theme-ntos .Section--fill>.Section__rest>.Section__content{height:100%}.theme-ntos .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-ntos .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-ntos .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-ntos .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-ntos .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-ntos .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-ntos .Section .Section:first-child{margin-top:-.5em}.theme-ntos .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-ntos .Section .Section .Section .Section__titleText{font-size:1em}.theme-ntos html,.theme-ntos body{scrollbar-color:#2e3f55 #17202b}.theme-ntos .Layout,.theme-ntos .Layout *{scrollbar-base-color:#17202b;scrollbar-face-color:#2e3f55;scrollbar-3dlight-color:#1f2b39;scrollbar-highlight-color:#1f2b39;scrollbar-track-color:#17202b;scrollbar-arrow-color:#7693b5;scrollbar-shadow-color:#2e3f55}.theme-ntos .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-ntos .Layout__content--flexRow{display:flex;flex-flow:row}.theme-ntos .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-ntos .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-ntos .Layout__content--noMargin{margin:0}.theme-ntos .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#1f2b39;background-image:linear-gradient(to bottom,#223040,#1b2633)}.theme-ntos .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-ntos .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-ntos .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-ntos .Window__contentPadding:after{height:0}.theme-ntos .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-ntos .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(55,69,85,.25);pointer-events:none}.theme-ntos .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-ntos .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-ntos .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-ntos .TitleBar{background-color:#2a3b4e;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-ntos .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#2a3b4e;transition:color .25s,background-color .25s}.theme-ntos .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-ntos .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-ntos .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-ntos .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-ntos .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-ntos .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-paper .Tabs{display:flex;align-items:stretch;overflow:hidden;background-color:rgba(0,0,0,.33)}.theme-paper .Tabs--fill{height:100%}.theme-paper .Section .Tabs{background-color:rgba(0,0,0,0)}.theme-paper .Section:not(.Section--fitted) .Tabs{margin:0 -.5em .5em}.theme-paper .Section:not(.Section--fitted) .Tabs:first-child{margin-top:-.5em}.theme-paper .Tabs--vertical{flex-direction:column;padding:.25em .25em .25em 0}.theme-paper .Tabs--horizontal{margin-bottom:.5em;padding:.25em .25em 0}.theme-paper .Tabs--horizontal:last-child{margin-bottom:0}.theme-paper .Tabs__Tab{flex-grow:0}.theme-paper .Tabs--fluid .Tabs__Tab{flex-grow:1}.theme-paper .Tab{display:flex;align-items:center;justify-content:space-between;background-color:rgba(0,0,0,0);color:rgba(255,255,255,.5);min-height:2.25em;min-width:4em;transition:background-color 50ms ease-out}.theme-paper .Tab:not(.Tab--selected):hover{background-color:rgba(255,255,255,.075);transition:background-color 0}.theme-paper .Tab--selected{background-color:rgba(255,255,255,.125);color:#fafafa}.theme-paper .Tab__text{flex-grow:1;margin:0 .5em}.theme-paper .Tab__left{min-width:1.5em;text-align:center;margin-left:.25em}.theme-paper .Tab__right{min-width:1.5em;text-align:center;margin-right:.25em}.theme-paper .Tabs--horizontal .Tab{border-top:.1666666667em solid rgba(0,0,0,0);border-bottom:.1666666667em solid rgba(0,0,0,0);border-top-left-radius:.25em;border-top-right-radius:.25em}.theme-paper .Tabs--horizontal .Tab--selected{border-bottom:.1666666667em solid #f9f9f9}.theme-paper .Tabs--vertical .Tab{min-height:2em;border-left:.1666666667em solid rgba(0,0,0,0);border-right:.1666666667em solid rgba(0,0,0,0);border-top-right-radius:.25em;border-bottom-right-radius:.25em}.theme-paper .Tabs--vertical .Tab--selected{border-left:.1666666667em solid #f9f9f9}.theme-paper .Section{position:relative;margin-bottom:.5em;background-color:#e6e6e6;background-color:rgba(0,0,0,.1);box-sizing:border-box}.theme-paper .Section:last-child{margin-bottom:0}.theme-paper .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #fff}.theme-paper .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#000}.theme-paper .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-paper .Section__rest{position:relative}.theme-paper .Section__content{padding:.66em .5em}.theme-paper .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-paper .Section--fill{display:flex;flex-direction:column;height:100%}.theme-paper .Section--fill>.Section__rest{flex-grow:1}.theme-paper .Section--fill>.Section__rest>.Section__content{height:100%}.theme-paper .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-paper .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-paper .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-paper .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-paper .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-paper .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-paper .Section .Section:first-child{margin-top:-.5em}.theme-paper .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-paper .Section .Section .Section .Section__titleText{font-size:1em}.theme-paper .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-paper .Button:last-child{margin-right:0;margin-bottom:0}.theme-paper .Button .fa,.theme-paper .Button .fas,.theme-paper .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-paper .Button--hasContent .fa,.theme-paper .Button--hasContent .fas,.theme-paper .Button--hasContent .far{margin-right:.25em}.theme-paper .Button--hasContent.Button--iconRight .fa,.theme-paper .Button--hasContent.Button--iconRight .fas,.theme-paper .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-paper .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-paper .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-paper .Button--circular{border-radius:50%}.theme-paper .Button--compact{padding:0 .25em;line-height:1.333em}.theme-paper .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-paper .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-paper .Button--color--transparent{background-color:rgba(255,255,255,0);color:rgba(0,0,0,.5);transition:color .2s,background-color .2s}.theme-paper .Button--color--transparent:hover{background-color:rgba(255,255,255,.81);color:#000}.theme-paper .Button--color--default{background-color:#e8e4c9;color:#000;transition:color .2s,background-color .2s}.theme-paper .Button--color--default:hover{background-color:#fbfaf5;color:#000}.theme-paper .Button--color--default--translucent{background-color:rgba(255,255,255,.33);color:rgba(0,0,0,.5);transition:color .2s,background-color .2s}.theme-paper .Button--color--default--translucent:hover{background-color:rgba(255,255,255,.5);color:#fff}.theme-paper .Button--color--caution{background-color:#be6209;color:#fff;transition:color .2s,background-color .2s}.theme-paper .Button--color--caution:hover{background-color:#e67f1a;color:#fff}.theme-paper .Button--color--caution--translucent{background-color:rgba(190,98,9,.33);color:rgba(0,0,0,.5);transition:color .2s,background-color .2s}.theme-paper .Button--color--caution--translucent:hover{background-color:rgba(230,127,26,.5);color:#fff}.theme-paper .Button--color--danger{background-color:#9a9d00;color:#fff;transition:color .2s,background-color .2s}.theme-paper .Button--color--danger:hover{background-color:#bec110;color:#fff}.theme-paper .Button--color--danger--translucent{background-color:rgba(154,157,0,.33);color:rgba(0,0,0,.5);transition:color .2s,background-color .2s}.theme-paper .Button--color--danger--translucent:hover{background-color:rgba(190,193,16,.5);color:#fff}.theme-paper .Button--disabled{background-color:#363636!important;color:rgba(0,0,0,.75)!important}.theme-paper .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(0,0,0,.5)!important}.theme-paper .Button--selected,.theme-paper .Button--selected--translucent{background-color:#9d0808;color:#fff;transition:color .2s,background-color .2s}.theme-paper .Button--selected:hover,.theme-paper .Button--selected--translucent:hover{background-color:#c11919;color:#fff}.theme-paper .Divider--horizontal{margin:.5em 0}.theme-paper .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-paper .Divider--vertical{height:100%;margin:0 .5em}.theme-paper .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-paper .color__default{background-color:rgba(232,229,202,.2);color:#000;border:solid rgba(252,252,249,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-paper .color__default:hover{background-color:rgba(252,252,249,.2)}.theme-paper .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-paper .selected{background-color:rgba(157,8,8,.2);color:#fff;border:solid rgba(157,8,8,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-paper .selected:hover{background-color:rgba(229,42,42,.2)}.theme-paper .contentColor__default{background-color:#e5e0c2;color:#000;border:solid #f3f2e4;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-paper .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-paper .contentSelected{background-color:#9d0808;color:#fff;border:solid #c11919;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-paper .buttonsContainerColor__default{background-color:rgba(232,229,202,.2);color:#000;border:solid rgba(252,252,249,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-paper .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-paper .ImageButton .noAction{pointer-events:none}.theme-paper .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-paper .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-paper .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-paper .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-paper .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-paper .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-paper .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-paper .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-paper .fluid:last-of-type{margin-bottom:0}.theme-paper .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-paper .fluid .title{font-weight:700;padding:.5em}.theme-paper .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-paper .fluid .contentFluid{padding:.5em;color:#fff}.theme-paper .fluid .container{flex-direction:row;flex:1}.theme-paper .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-paper .fluid .image{padding:0}.theme-paper .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-paper .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-paper .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-paper .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-paper .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-paper .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-paper .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:.16em;background-color:rgba(0,0,0,0);transition:border-color .5s}.theme-paper .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-paper .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-paper .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-paper .ProgressBar--color--default{border:.0833333333em solid #bfbfbf}.theme-paper .ProgressBar--color--default .ProgressBar__fill{background-color:#bfbfbf}.theme-paper .ProgressBar--color--disabled{border:1px solid #363636}.theme-paper .ProgressBar--color--disabled .ProgressBar__fill{background-color:#363636}.theme-paper html,.theme-paper body{scrollbar-color:#fff #bfbfbf}.theme-paper .Layout,.theme-paper .Layout *{scrollbar-base-color:#bfbfbf;scrollbar-face-color:#fff;scrollbar-3dlight-color:#fff;scrollbar-highlight-color:#fff;scrollbar-track-color:#bfbfbf;scrollbar-arrow-color:#fff;scrollbar-shadow-color:#fff}.theme-paper .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-paper .Layout__content--flexRow{display:flex;flex-flow:row}.theme-paper .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-paper .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-paper .Layout__content--noMargin{margin:0}.theme-paper .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#000;background-color:#fff;background-image:linear-gradient(to bottom,#fff,#fff)}.theme-paper .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-paper .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-paper .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-paper .Window__contentPadding:after{height:0}.theme-paper .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-paper .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(255,255,255,.25);pointer-events:none}.theme-paper .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-paper .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-paper .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-paper .TitleBar{background-color:#fff;border-bottom:1px solid rgba(0,0,0,.25);box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-paper .TitleBar__clickable{color:rgba(0,0,0,.5);background-color:#fff;transition:color .25s,background-color .25s}.theme-paper .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-paper .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(0,0,0,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-paper .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-paper .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-paper .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-paper .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-paper .PaperInput{position:relative;display:inline-block;width:120px;border:none;background:rgba(0,0,0,0);border-bottom:1px solid #000;outline:none;background-color:rgba(255,255,62,.8);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-paper .PaperInput__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-paper .PaperInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-paper .PaperInput__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-paper .PaperInput__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-paper .Layout__content{background-image:none}.theme-paper .Window{background-image:none;color:#000}.theme-paper .paper-text input:disabled{position:relative;display:inline-block;border:none;background:rgba(0,0,0,0);border-bottom:1px solid #000;outline:none;background-color:rgba(255,255,62,.8);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-paper .paper-text input,.theme-paper .paper-field{position:relative;display:inline-block;border:none;background:rgba(0,0,0,0);border-bottom:1px solid #000;outline:none;background-color:rgba(255,255,62,.8);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-paper .paper-field input:disabled{position:relative;display:inline-block;border:none;background:rgba(0,0,0,0);border-bottom:1px solid #000;outline:none;background-color:rgba(255,255,62,.8);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-retro .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:0;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-retro .Button:last-child{margin-right:0;margin-bottom:0}.theme-retro .Button .fa,.theme-retro .Button .fas,.theme-retro .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-retro .Button--hasContent .fa,.theme-retro .Button--hasContent .fas,.theme-retro .Button--hasContent .far{margin-right:.25em}.theme-retro .Button--hasContent.Button--iconRight .fa,.theme-retro .Button--hasContent.Button--iconRight .fas,.theme-retro .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-retro .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-retro .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-retro .Button--circular{border-radius:50%}.theme-retro .Button--compact{padding:0 .25em;line-height:1.333em}.theme-retro .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-retro .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-retro .Button--color--transparent{background-color:rgba(232,228,201,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-retro .Button--color--transparent:hover{background-color:rgba(255,255,255,.81);color:#000}.theme-retro .Button--color--default{background-color:#e8e4c9;color:#000;transition:color .2s,background-color .2s}.theme-retro .Button--color--default:hover{background-color:#fbfaf5;color:#000}.theme-retro .Button--color--default--translucent{background-color:rgba(242,240,225,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-retro .Button--color--default--translucent:hover{background-color:rgba(253,252,250,.5);color:#fff}.theme-retro .Button--color--caution{background-color:#be6209;color:#fff;transition:color .2s,background-color .2s}.theme-retro .Button--color--caution:hover{background-color:#e67f1a;color:#fff}.theme-retro .Button--color--caution--translucent{background-color:rgba(190,98,9,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-retro .Button--color--caution--translucent:hover{background-color:rgba(230,127,26,.5);color:#fff}.theme-retro .Button--color--danger{background-color:#9a9d00;color:#fff;transition:color .2s,background-color .2s}.theme-retro .Button--color--danger:hover{background-color:#bec110;color:#fff}.theme-retro .Button--color--danger--translucent{background-color:rgba(154,157,0,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-retro .Button--color--danger--translucent:hover{background-color:rgba(190,193,16,.5);color:#fff}.theme-retro .Button--disabled{background-color:#363636!important;color:rgba(255,255,255,.75)!important}.theme-retro .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-retro .Button--selected,.theme-retro .Button--selected--translucent{background-color:#9d0808;color:#fff;transition:color .2s,background-color .2s}.theme-retro .Button--selected:hover,.theme-retro .Button--selected--translucent:hover{background-color:#c11919;color:#fff}.theme-retro .Divider--horizontal{margin:.5em 0}.theme-retro .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-retro .Divider--vertical{height:100%;margin:0 .5em}.theme-retro .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-retro .color__default{background-color:rgba(232,229,202,.2);color:#000;border:solid rgba(252,252,249,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-retro .color__default:hover{background-color:rgba(252,252,249,.2)}.theme-retro .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-retro .selected{background-color:rgba(157,8,8,.2);color:#fff;border:solid rgba(157,8,8,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-retro .selected:hover{background-color:rgba(229,42,42,.2)}.theme-retro .contentColor__default{background-color:#e5e0c2;color:#000;border:solid #f3f2e4;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-retro .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-retro .contentSelected{background-color:#9d0808;color:#fff;border:solid #c11919;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-retro .buttonsContainerColor__default{background-color:rgba(232,229,202,.2);color:#000;border:solid rgba(252,252,249,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-retro .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-retro .ImageButton .noAction{pointer-events:none}.theme-retro .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-retro .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-retro .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-retro .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-retro .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-retro .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-retro .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-retro .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-retro .fluid:last-of-type{margin-bottom:0}.theme-retro .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-retro .fluid .title{font-weight:700;padding:.5em}.theme-retro .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-retro .fluid .contentFluid{padding:.5em;color:#fff}.theme-retro .fluid .container{flex-direction:row;flex:1}.theme-retro .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-retro .fluid .image{padding:0}.theme-retro .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-retro .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-retro .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-retro .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-retro .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-retro .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-retro .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:0;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-retro .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-retro .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-retro .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-retro .ProgressBar--color--default{border:.0833333333em solid #000}.theme-retro .ProgressBar--color--default .ProgressBar__fill{background-color:#000}.theme-retro .ProgressBar--color--disabled{border:1px solid #999}.theme-retro .ProgressBar--color--disabled .ProgressBar__fill{background-color:#999}.theme-retro .Section{position:relative;margin-bottom:.5em;background-color:#9b9987;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-retro .Section:last-child{margin-bottom:0}.theme-retro .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #000}.theme-retro .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-retro .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-retro .Section__rest{position:relative}.theme-retro .Section__content{padding:.66em .5em}.theme-retro .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-retro .Section--fill{display:flex;flex-direction:column;height:100%}.theme-retro .Section--fill>.Section__rest{flex-grow:1}.theme-retro .Section--fill>.Section__rest>.Section__content{height:100%}.theme-retro .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-retro .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-retro .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-retro .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-retro .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-retro .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-retro .Section .Section:first-child{margin-top:-.5em}.theme-retro .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-retro .Section .Section .Section .Section__titleText{font-size:1em}.theme-retro html,.theme-retro body{scrollbar-color:#efecd9 #c8be7d}.theme-retro .Layout,.theme-retro .Layout *{scrollbar-base-color:#c8be7d;scrollbar-face-color:#eae7ce;scrollbar-3dlight-color:#e8e4c9;scrollbar-highlight-color:#e8e4c9;scrollbar-track-color:#c8be7d;scrollbar-arrow-color:#f4f2e4;scrollbar-shadow-color:#eae7ce}.theme-retro .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-retro .Layout__content--flexRow{display:flex;flex-flow:row}.theme-retro .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-retro .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-retro .Layout__content--noMargin{margin:0}.theme-retro .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#e8e4c9;background-image:linear-gradient(to bottom,#e8e4c9,#e8e4c9)}.theme-retro .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-retro .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-retro .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-retro .Window__contentPadding:after{height:0}.theme-retro .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-retro .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(251,250,246,.25);pointer-events:none}.theme-retro .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-retro .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-retro .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-retro .TitleBar{background-color:#585337;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-retro .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#585337;transition:color .25s,background-color .25s}.theme-retro .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-retro .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-retro .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-retro .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-retro .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-retro .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-retro .Button{font-family:monospace;color:#161613;border:.1666666667em outset #e8e4c9;outline:.0833333333em solid #161613}.theme-retro .Layout__content{background-image:none}.theme-safe .Section{position:relative;margin-bottom:.5em;background-color:#b2ae74;box-sizing:border-box}.theme-safe .Section:last-child{margin-bottom:0}.theme-safe .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #3d566b}.theme-safe .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-safe .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-safe .Section__rest{position:relative}.theme-safe .Section__content{padding:.66em .5em}.theme-safe .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-safe .Section--fill{display:flex;flex-direction:column;height:100%}.theme-safe .Section--fill>.Section__rest{flex-grow:1}.theme-safe .Section--fill>.Section__rest>.Section__content{height:100%}.theme-safe .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-safe .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-safe .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-safe .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-safe .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-safe .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-safe .Section .Section:first-child{margin-top:-.5em}.theme-safe .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-safe .Section .Section .Section .Section__titleText{font-size:1em}.theme-safe .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#222b3a;background-image:linear-gradient(to bottom,#242d3d,#202937)}.theme-safe .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-safe .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-safe .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-safe .Window__contentPadding:after{height:0}.theme-safe .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-safe .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(58,69,86,.25);pointer-events:none}.theme-safe .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-safe .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-safe .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-safe .TitleBar{background-color:#35435a;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-safe .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#35435a;transition:color .25s,background-color .25s}.theme-safe .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-safe .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-safe .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-safe .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-safe .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-safe .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-safe .Safe--engraving{position:absolute;width:95%;height:96%;left:2.5%;top:2%;border:5px outset #364963;padding:5px;text-align:center}.theme-safe .Safe--engraving--arrow{color:#35435a}.theme-safe .Safe--engraving--hinge{content:" ";background-color:#191f2a;width:25px;height:40px;position:absolute;right:-15px;margin-top:-20px}.theme-safe .Safe--dialer{margin-bottom:.5rem}.theme-safe .Safe--dialer--number{color:#bbb;display:inline;background-color:#191f2a;font-size:1.5rem;font-weight:700;padding:0 .5rem}.theme-safe .Safe--dialer--right .Button i{z-index:-100}.theme-safe .Safe--dialer .Button{width:80px}.theme-safe .Safe--contents{border:10px solid #191f2a;background-color:#0f131a;height:calc(85% + 7.5px);text-align:left;padding:5px}.theme-safe .Safe--help{position:absolute;bottom:30px;left:25px;width:50%}.theme-safe .Layout__content{background-image:none}.theme-safe .Section{font-family:Comic Sans MS,cursive,sans-serif;font-style:italic;color:#000;box-shadow:5px 5px #111;background-image:linear-gradient(to bottom,#b2ae74,#8e8b5d);transform:rotate(-1deg)}.theme-safe .Section__title{padding-bottom:0;border:0}.theme-safe .Section:before{content:" ";display:block;width:24px;height:40px;background-image:linear-gradient(to bottom,transparent 0%,#ffffff 100%);box-shadow:1px 1px #111;opacity:.2;position:absolute;top:-30px;left:calc(50% - 12px);transform:rotate(-5deg)}.theme-securestorage .TitleBar{background-color:#e8e4c9;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-securestorage .TitleBar__clickable{color:rgba(25,25,22,.5);background-color:#e8e4c9;transition:color .25s,background-color .25s}.theme-securestorage .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-securestorage .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:#191916;font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-securestorage .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-securestorage .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-securestorage .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-securestorage .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-securestorage html,.theme-securestorage body{scrollbar-color:#efecd9 #c8be7d}.theme-securestorage .Layout,.theme-securestorage .Layout *{scrollbar-base-color:#c8be7d;scrollbar-face-color:#eae7ce;scrollbar-3dlight-color:#e8e4c9;scrollbar-highlight-color:#e8e4c9;scrollbar-track-color:#c8be7d;scrollbar-arrow-color:#f4f2e4;scrollbar-shadow-color:#eae7ce}.theme-securestorage .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-securestorage .Layout__content--flexRow{display:flex;flex-flow:row}.theme-securestorage .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-securestorage .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-securestorage .Layout__content--noMargin{margin:0}.theme-securestorage .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#e8e4c9;background-image:linear-gradient(to bottom,#f1efde,#dfd9b4)}.theme-securestorage .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-securestorage .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-securestorage .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-securestorage .Window__contentPadding:after{height:0}.theme-securestorage .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-securestorage .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(251,250,246,.25);pointer-events:none}.theme-securestorage .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-securestorage .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-securestorage .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-securestorage .Section{position:relative;margin-bottom:.5em;background-color:#9b9987;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-securestorage .Section:last-child{margin-bottom:0}.theme-securestorage .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #397439}.theme-securestorage .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-securestorage .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-securestorage .Section__rest{position:relative}.theme-securestorage .Section__content{padding:.66em .5em}.theme-securestorage .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-securestorage .Section--fill{display:flex;flex-direction:column;height:100%}.theme-securestorage .Section--fill>.Section__rest{flex-grow:1}.theme-securestorage .Section--fill>.Section__rest>.Section__content{height:100%}.theme-securestorage .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-securestorage .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-securestorage .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-securestorage .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-securestorage .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-securestorage .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-securestorage .Section .Section:first-child{margin-top:-.5em}.theme-securestorage .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-securestorage .Section .Section .Section .Section__titleText{font-size:1em}.theme-securestorage .Layout__content{background-image:none}.theme-security .color-label{color:#b08e8b!important}.theme-security .color-bg-good{background-color:#4d9121!important}.theme-security .color-border-label{border-color:#b08e8b!important}.theme-security .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-security .Button:last-child{margin-right:0;margin-bottom:0}.theme-security .Button .fa,.theme-security .Button .fas,.theme-security .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-security .Button--hasContent .fa,.theme-security .Button--hasContent .fas,.theme-security .Button--hasContent .far{margin-right:.25em}.theme-security .Button--hasContent.Button--iconRight .fa,.theme-security .Button--hasContent.Button--iconRight .fas,.theme-security .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-security .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-security .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-security .Button--circular{border-radius:50%}.theme-security .Button--compact{padding:0 .25em;line-height:1.333em}.theme-security .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-security .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-security .Button--color--good{background-color:#4d9121;color:#fff;transition:color .2s,background-color .2s}.theme-security .Button--color--good:hover{background-color:#67b335;color:#fff}.theme-security .Button--color--good--translucent{background-color:rgba(77,145,33,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-security .Button--color--good--translucent:hover{background-color:rgba(103,179,53,.5);color:#fff}.theme-security .Button--color--transparent{background-color:rgba(37,37,37,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-security .Button--color--transparent:hover{background-color:rgba(56,56,56,.81);color:#fff}.theme-security .Button--color--default{background-color:#a14c49;color:#fff;transition:color .2s,background-color .2s}.theme-security .Button--color--default:hover{background-color:#bb6f6d;color:#fff}.theme-security .Button--color--default--translucent{background-color:rgba(46,46,46,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-security .Button--color--default--translucent:hover{background-color:rgba(68,68,68,.5);color:#fff}.theme-security .Button--color--caution{background-color:#d9b804;color:#000;transition:color .2s,background-color .2s}.theme-security .Button--color--caution:hover{background-color:#f5d523;color:#000}.theme-security .Button--color--caution--translucent{background-color:rgba(217,184,4,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-security .Button--color--caution--translucent:hover{background-color:rgba(245,213,35,.5);color:#fff}.theme-security .Button--color--danger{background-color:#bd2020;color:#fff;transition:color .2s,background-color .2s}.theme-security .Button--color--danger:hover{background-color:#d93f3f;color:#fff}.theme-security .Button--color--danger--translucent{background-color:rgba(189,32,32,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-security .Button--color--danger--translucent:hover{background-color:rgba(217,63,63,.5);color:#fff}.theme-security .Button--disabled{background-color:#999!important;color:rgba(255,255,255,.75)!important}.theme-security .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-security .Button--selected,.theme-security .Button--selected--translucent{background-color:#1b9638;color:#fff;transition:color .2s,background-color .2s}.theme-security .Button--selected:hover,.theme-security .Button--selected--translucent:hover{background-color:#2fb94f;color:#fff}.theme-security .Divider--horizontal{margin:.5em 0}.theme-security .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-security .Divider--vertical{height:100%;margin:0 .5em}.theme-security .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-security .color__good{background-color:rgba(77,145,33,.2);color:#fff;border:solid rgba(130,208,79,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-security .color__good:hover{background-color:rgba(130,208,79,.2)}.theme-security .contentColor__good{background-color:#4d9121;color:#fff;border:solid #67b335;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-security .buttonsContainerColor__good{background-color:rgba(77,145,33,.33);color:#fff;border:solid rgba(130,208,79,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-security .color__default{background-color:rgba(169,108,106,.2);color:#fff;border:solid rgba(217,191,190,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-security .color__default:hover{background-color:rgba(217,191,190,.2)}.theme-security .disabled{background-color:rgba(99,29,29,.25)!important;border-color:rgba(99,29,29,.25)!important}.theme-security .selected{background-color:rgba(27,150,56,.2);color:#fff;border:solid rgba(27,150,56,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-security .selected:hover{background-color:rgba(72,214,105,.2)}.theme-security .contentColor__default{background-color:#a46866;color:#fff;border:solid #b97977;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-security .contentDisabled{background-color:#631d1d!important;border-top:1px solid #803131!important}.theme-security .contentSelected{background-color:#1b9638;color:#fff;border:solid #2fb94f;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-security .buttonsContainerColor__default{background-color:rgba(169,108,106,.2);color:#fff;border:solid rgba(217,191,190,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-security .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-security .ImageButton .noAction{pointer-events:none}.theme-security .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-security .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-security .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-security .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-security .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-security .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-security .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-security .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-security .fluid:last-of-type{margin-bottom:0}.theme-security .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-security .fluid .title{font-weight:700;padding:.5em}.theme-security .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-security .fluid .contentFluid{padding:.5em;color:#fff}.theme-security .fluid .container{flex-direction:row;flex:1}.theme-security .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-security .fluid .image{padding:0}.theme-security .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-security .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-security .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-security .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-security .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-security .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-security .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #ff8d88;border:.0833333333em solid rgba(255,141,136,.75);border-radius:.16em;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-security .Input--disabled{color:#777;border-color:#848484;border-color:rgba(132,132,132,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-security .Input--fluid{display:block;width:auto}.theme-security .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-security .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-security .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-security .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-security .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-security .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-security .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-security .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-security .NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:700;font-style:italic;color:#000;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,transparent,transparent .8333333333em,rgba(0,0,0,.1) .8333333333em,rgba(0,0,0,.1) 1.6666666667em)}.theme-security .NoticeBox--color--good{color:#fff;background-color:#2e4b1a}.theme-security .NoticeBox--type--info{color:#fff;background-color:#822329}.theme-security .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-security .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-security .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-security .Section{position:relative;margin-bottom:.5em;background-color:#191919;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-security .Section:last-child{margin-bottom:0}.theme-security .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #a14c49}.theme-security .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-security .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-security .Section__rest{position:relative}.theme-security .Section__content{padding:.66em .5em}.theme-security .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-security .Section--fill{display:flex;flex-direction:column;height:100%}.theme-security .Section--fill>.Section__rest{flex-grow:1}.theme-security .Section--fill>.Section__rest>.Section__content{height:100%}.theme-security .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-security .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-security .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-security .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-security .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-security .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-security .Section .Section:first-child{margin-top:-.5em}.theme-security .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-security .Section .Section .Section .Section__titleText{font-size:1em}.theme-security .Newscaster__menu{width:40px;height:100%;margin-right:.5rem;flex-basis:content}.theme-security .Newscaster__menu .Section__content{padding-left:0}.theme-security .Newscaster__menuButton{color:#767676;cursor:pointer;position:relative;margin-left:6px;margin-right:1rem;white-space:nowrap;transition:color .1s}.theme-security .Newscaster__menuButton--title{width:80%;display:none;overflow:hidden;text-overflow:ellipsis}.theme-security .Newscaster__menuButton--unread{background-color:#e45e5e;color:#fff;font-size:10px;text-align:center;border-radius:32px;display:inline-block;width:12px;position:absolute;left:16px;margin-top:14px}.theme-security .Newscaster__menuButton--selected{color:#fff}.theme-security .Newscaster__menuButton--selected:after{content:"";background-color:#a14c49;width:2px;height:24px;position:absolute;left:-6px}.theme-security .Newscaster__menuButton--security{color:#a14c49}.theme-security .Newscaster__menuButton i{width:30px;text-align:center;vertical-align:middle;margin-left:-1px;margin-right:.5rem;margin-top:1px}.theme-security .Newscaster__menuButton:hover{color:#fff}.theme-security .Newscaster__menuButton:hover:before{background-color:#fff}.theme-security .Newscaster__menuButton:not(:last-of-type){margin-bottom:.5rem}.theme-security .Newscaster__menu--open{width:175px}.theme-security .Newscaster__menu--open .Newscaster__menuButton--title{display:inline-block}.theme-security .Newscaster__jobCategory--security .Section__title{color:#a14c49;border-bottom:2px solid #a14c49!important}.theme-security .Newscaster__jobCategory--engineering .Section__title{color:#a17849;border-bottom:2px solid #a17849!important}.theme-security .Newscaster__jobCategory--medical .Section__title{color:#499ea1;border-bottom:2px solid #499ea1!important}.theme-security .Newscaster__jobCategory--science .Section__title{color:#a14972;border-bottom:2px solid #a14972!important}.theme-security .Newscaster__jobCategory--service .Section__title{color:#a1499e;border-bottom:2px solid #a1499e!important}.theme-security .Newscaster__jobCategory--supply .Section__title{color:#9ea149;border-bottom:2px solid #9ea149!important}.theme-security .Newscaster__jobCategory:last-child{margin-bottom:.5rem}.theme-security .Newscaster__jobOpening--command{font-weight:700}.theme-security .Newscaster__jobOpening:not(:last-child){margin-bottom:.5rem}.theme-security .Newscaster__emptyNotice{color:#a7817e;text-align:center;position:absolute;top:50%;left:50%;transform:translateY(-50%) translate(-50%)}.theme-security .Newscaster__emptyNotice i{margin-bottom:.25rem}.theme-security .Newscaster__photo{cursor:pointer;width:100px;border:1px solid #000;transition:border-color .3s;-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.theme-security .Newscaster__photo:hover{border-color:gray}.theme-security .Newscaster__photoZoom{text-align:center}.theme-security .Newscaster__photoZoom>img{transform:scale(2);-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.theme-security .Newscaster__photoZoom>.Button{position:absolute;width:64px;left:50%;margin-left:-32px;bottom:1rem}.theme-security .Newscaster__story--wanted{background-color:rgba(219,40,40,.1)}.theme-security .Newscaster__story--wanted .Section__title{color:#db2828;border-bottom:2px solid #a14c49!important}.theme-security .Newscaster__story:last-child{margin-bottom:.5rem}.theme-syndicate .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-syndicate .Button:last-child{margin-right:0;margin-bottom:0}.theme-syndicate .Button .fa,.theme-syndicate .Button .fas,.theme-syndicate .Button .far{margin-left:-.25em;margin-right:-.25em;min-width:1.333em;text-align:center}.theme-syndicate .Button--hasContent .fa,.theme-syndicate .Button--hasContent .fas,.theme-syndicate .Button--hasContent .far{margin-right:.25em}.theme-syndicate .Button--hasContent.Button--iconRight .fa,.theme-syndicate .Button--hasContent.Button--iconRight .fas,.theme-syndicate .Button--hasContent.Button--iconRight .far{margin-right:0;margin-left:.25em}.theme-syndicate .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-syndicate .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-syndicate .Button--circular{border-radius:50%}.theme-syndicate .Button--compact{padding:0 .25em;line-height:1.333em}.theme-syndicate .Button--multiLine{white-space:normal;word-wrap:break-word}.theme-syndicate .Button--modal{float:right;z-index:1;margin-top:-.5rem}.theme-syndicate .Button--color--transparent{background-color:rgba(85,2,2,0);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-syndicate .Button--color--transparent:hover{background-color:rgba(113,14,14,.81);color:#fff}.theme-syndicate .Button--color--default{background-color:#397439;color:#fff;transition:color .2s,background-color .2s}.theme-syndicate .Button--color--default:hover{background-color:#509350;color:#fff}.theme-syndicate .Button--color--default--translucent{background-color:rgba(96,8,8,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-syndicate .Button--color--default--translucent:hover{background-color:rgba(124,25,25,.5);color:#fff}.theme-syndicate .Button--color--caution{background-color:#be6209;color:#fff;transition:color .2s,background-color .2s}.theme-syndicate .Button--color--caution:hover{background-color:#e67f1a;color:#fff}.theme-syndicate .Button--color--caution--translucent{background-color:rgba(190,98,9,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-syndicate .Button--color--caution--translucent:hover{background-color:rgba(230,127,26,.5);color:#fff}.theme-syndicate .Button--color--danger{background-color:#9a9d00;color:#fff;transition:color .2s,background-color .2s}.theme-syndicate .Button--color--danger:hover{background-color:#bec110;color:#fff}.theme-syndicate .Button--color--danger--translucent{background-color:rgba(154,157,0,.33);color:rgba(255,255,255,.5);transition:color .2s,background-color .2s}.theme-syndicate .Button--color--danger--translucent:hover{background-color:rgba(190,193,16,.5);color:#fff}.theme-syndicate .Button--disabled{background-color:#363636!important;color:rgba(255,255,255,.75)!important}.theme-syndicate .Button--disabled--translucent{background-color:rgba(77,23,23,.5)!important;color:rgba(255,255,255,.5)!important}.theme-syndicate .Button--selected,.theme-syndicate .Button--selected--translucent{background-color:#9d0808;color:#fff;transition:color .2s,background-color .2s}.theme-syndicate .Button--selected:hover,.theme-syndicate .Button--selected--translucent:hover{background-color:#c11919;color:#fff}.theme-syndicate .Divider--horizontal{margin:.5em 0}.theme-syndicate .Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.theme-syndicate .Divider--vertical{height:100%;margin:0 .5em}.theme-syndicate .Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.theme-syndicate .color__default{background-color:rgba(87,122,87,.2);color:#fff;border:solid rgba(148,177,148,.2);border-width:1px;transition:background-color .2s,border-color .2s}.theme-syndicate .color__default:hover{background-color:rgba(148,177,148,.2)}.theme-syndicate .disabled{background-color:rgba(54,54,54,.25)!important;border-color:rgba(54,54,54,.25)!important}.theme-syndicate .selected{background-color:rgba(157,8,8,.2);color:#fff;border:solid rgba(157,8,8,.25);border-width:1px;transition:background-color .2s,border-color .2s}.theme-syndicate .selected:hover{background-color:rgba(229,42,42,.2)}.theme-syndicate .contentColor__default{background-color:#547654;color:#fff;border:solid #638763;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-syndicate .contentDisabled{background-color:#363636!important;border-top:1px solid #4d4d4d!important}.theme-syndicate .contentSelected{background-color:#9d0808;color:#fff;border:solid #c11919;border-width:1px 0 0 0;transition:background-color .2s,border-color .2s}.theme-syndicate .buttonsContainerColor__default{background-color:rgba(87,122,87,.2);color:#fff;border:solid rgba(148,177,148,.2);border-width:1px 1px 1px 0;transition:background-color 0,border-color 0}.theme-syndicate .ImageButton{display:inline-table;position:relative;text-align:center;margin:.25em;user-select:none;-ms-user-select:none}.theme-syndicate .ImageButton .noAction{pointer-events:none}.theme-syndicate .ImageButton .container{display:flex;flex-direction:column;border-radius:.33em}.theme-syndicate .ImageButton .image{position:relative;align-self:center;pointer-events:none;overflow:hidden;line-height:0;padding:.25em;border-radius:.33em}.theme-syndicate .ImageButton .buttonsContainer{display:flex;position:absolute;overflow:hidden;left:1px;bottom:1.8em;max-width:100%;z-index:1}.theme-syndicate .ImageButton .buttonsContainer.buttonsAltContainer{overflow:visible;flex-direction:column;pointer-events:none;top:1px;bottom:inherit!important}.theme-syndicate .ImageButton .buttonsContainer.buttonsEmpty{bottom:1px}.theme-syndicate .ImageButton .buttonsContainer>*{margin:0!important;padding:0 .2em!important;border-radius:0!important}.theme-syndicate .ImageButton .content{-ms-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:.25em .5em;margin:-1px;border-radius:0 0 .33em .33em;z-index:2}.theme-syndicate .fluid{display:flex;flex-direction:row;position:relative;text-align:center;margin:0 0 .5em;user-select:none;-ms-user-select:none}.theme-syndicate .fluid:last-of-type{margin-bottom:0}.theme-syndicate .fluid .info{display:flex;flex-direction:column;justify-content:center;flex:1}.theme-syndicate .fluid .title{font-weight:700;padding:.5em}.theme-syndicate .fluid .title.divider{margin:0 .5em;border-bottom:.1666666667em solid rgba(255,255,255,.1)}.theme-syndicate .fluid .contentFluid{padding:.5em;color:#fff}.theme-syndicate .fluid .container{flex-direction:row;flex:1}.theme-syndicate .fluid .container.hasButtons{border-radius:.33em 0 0 .33em;border-width:1px 0 1px 1px}.theme-syndicate .fluid .image{padding:0}.theme-syndicate .fluid .buttonsContainer{position:relative;left:inherit;bottom:inherit;border-radius:0 .33em .33em 0}.theme-syndicate .fluid .buttonsContainer.buttonsEmpty{bottom:inherit}.theme-syndicate .fluid .buttonsContainer.buttonsAltContainer{overflow:hidden;pointer-events:auto;top:inherit}.theme-syndicate .fluid .buttonsContainer.buttonsAltContainer>*{border-top:1px solid rgba(255,255,255,.075)}.theme-syndicate .fluid .buttonsContainer.buttonsAltContainer>*:first-child{border-top:0}.theme-syndicate .fluid .buttonsContainer>*{display:inline-flex;flex-direction:column;justify-content:center;text-align:center;white-space:pre-wrap;line-height:1.1666666667em;height:100%;border-left:1px solid rgba(255,255,255,.075)}.theme-syndicate .NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:700;font-style:italic;color:#fff;background-color:#910101;background-image:repeating-linear-gradient(-45deg,transparent,transparent .8333333333em,rgba(0,0,0,.1) .8333333333em,rgba(0,0,0,.1) 1.6666666667em)}.theme-syndicate .NoticeBox--type--info{color:#fff;background-color:#235982}.theme-syndicate .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-syndicate .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-syndicate .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-syndicate .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #87ce87;border:.0833333333em solid rgba(135,206,135,.75);border-radius:.16em;background-color:#0a0a0a;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible;white-space:nowrap}.theme-syndicate .Input--disabled{color:#777;border-color:#6b6b6b;border-color:rgba(107,107,107,.75);background-color:#333;background-color:rgba(0,0,0,.25)}.theme-syndicate .Input--fluid{display:block;width:auto}.theme-syndicate .Input__baseline{display:inline-block;color:rgba(0,0,0,0)}.theme-syndicate .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit}.theme-syndicate .Input__input::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-syndicate .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-syndicate .Input__textarea{border:0;width:calc(100% + 4px);font-size:1em;line-height:1.4166666667em;margin-left:-.3333333333em;font-family:Verdana,sans-serif;background-color:rgba(0,0,0,0);color:#fff;color:inherit;resize:both;overflow:auto;white-space:pre-wrap}.theme-syndicate .Input__textarea::placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-syndicate .Input__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-syndicate .Input--monospace .Input__input{font-family:Consolas,monospace}.theme-syndicate .NumberInput{position:relative;display:inline-block;border:.0833333333em solid #87ce87;border:.0833333333em solid rgba(135,206,135,.75);border-radius:.16em;color:#87ce87;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.theme-syndicate .NumberInput--fluid{display:block}.theme-syndicate .NumberInput__content{margin-left:.5em}.theme-syndicate .NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.theme-syndicate .NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #87ce87;background-color:#87ce87}.theme-syndicate .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#0a0a0a;color:#fff;text-align:right}.theme-syndicate .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-radius:.16em;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-syndicate .ProgressBar__fill{position:absolute;top:-.5px;left:0;bottom:-.5px}.theme-syndicate .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-syndicate .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-syndicate .ProgressBar--color--default{border:.0833333333em solid #306330}.theme-syndicate .ProgressBar--color--default .ProgressBar__fill{background-color:#306330}.theme-syndicate .ProgressBar--color--disabled{border:1px solid #999}.theme-syndicate .ProgressBar--color--disabled .ProgressBar__fill{background-color:#999}.theme-syndicate .Section{position:relative;margin-bottom:.5em;background-color:#390101;background-color:rgba(0,0,0,.33);box-sizing:border-box}.theme-syndicate .Section:last-child{margin-bottom:0}.theme-syndicate .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #397439}.theme-syndicate .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-syndicate .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-syndicate .Section__rest{position:relative}.theme-syndicate .Section__content{padding:.66em .5em}.theme-syndicate .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-syndicate .Section--fill{display:flex;flex-direction:column;height:100%}.theme-syndicate .Section--fill>.Section__rest{flex-grow:1}.theme-syndicate .Section--fill>.Section__rest>.Section__content{height:100%}.theme-syndicate .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-syndicate .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-syndicate .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-syndicate .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-syndicate .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-syndicate .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-syndicate .Section .Section:first-child{margin-top:-.5em}.theme-syndicate .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-syndicate .Section .Section .Section .Section__titleText{font-size:1em}.theme-syndicate .Tooltip{z-index:999;padding:.5em .75em;pointer-events:none;text-align:left;transition:opacity .15s ease-out;background-color:#4a0202;color:#fff;box-shadow:.1em .1em 1.25em -.1em rgba(0,0,0,.5);border-radius:.16em;max-width:20.8333333333em}.theme-syndicate html,.theme-syndicate body{scrollbar-color:#7e0303 #400202}.theme-syndicate .Layout,.theme-syndicate .Layout *{scrollbar-base-color:#400202;scrollbar-face-color:#7e0303;scrollbar-3dlight-color:#550202;scrollbar-highlight-color:#550202;scrollbar-track-color:#400202;scrollbar-arrow-color:#fa3030;scrollbar-shadow-color:#7e0303}.theme-syndicate .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden}.theme-syndicate .Layout__content--flexRow{display:flex;flex-flow:row}.theme-syndicate .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-syndicate .Layout__content--scrollable{overflow-y:auto;margin-bottom:0}.theme-syndicate .Layout__content--noMargin{margin:0}.theme-syndicate .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#550202;background-image:linear-gradient(to bottom,#730303,#370101)}.theme-syndicate .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-syndicate .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-syndicate .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-syndicate .Window__contentPadding:after{height:0}.theme-syndicate .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-syndicate .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(117,22,22,.25);pointer-events:none}.theme-syndicate .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-syndicate .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-syndicate .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-syndicate .TitleBar{background-color:#910101;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-syndicate .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#910101;transition:color .25s,background-color .25s}.theme-syndicate .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-syndicate .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-syndicate .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-syndicate .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-syndicate .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-syndicate .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-syndicate .Layout__content{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMCIgdmlld0JveD0iMCAwIDIwMCAyODkuNzQyIiBvcGFjaXR5PSIuMzMiPjxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPjwvc3ZnPjwhLS0gVGhpcyB3b3JrIGlzIGxpY2Vuc2VkIHVuZGVyIGEgQ3JlYXRpdmUgQ29tbW9ucyBBdHRyaWJ1dGlvbi1TaGFyZUFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UuIC0tPjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4=)}.theme-syndicate .candystripe:nth-child(odd){background-color:rgba(0,0,0,.4)}.theme-syndicate .candystripe:nth-child(2n){background-color:rgba(0,0,0,.25)}.theme-nologo .Layout__content{background-image:none}.theme-noticeboard .color-black{color:#1a1a1a!important}.theme-noticeboard .color-white{color:#fff!important}.theme-noticeboard .color-red{color:#df3e3e!important}.theme-noticeboard .color-orange{color:#f37f33!important}.theme-noticeboard .color-yellow{color:#fbda21!important}.theme-noticeboard .color-olive{color:#cbe41c!important}.theme-noticeboard .color-green{color:#25ca4c!important}.theme-noticeboard .color-teal{color:#00d6cc!important}.theme-noticeboard .color-blue{color:#2e93de!important}.theme-noticeboard .color-violet{color:#7349cf!important}.theme-noticeboard .color-purple{color:#ad45d0!important}.theme-noticeboard .color-pink{color:#e34da1!important}.theme-noticeboard .color-brown{color:#b97447!important}.theme-noticeboard .color-grey{color:#848484!important}.theme-noticeboard .color-good{color:#68c22d!important}.theme-noticeboard .color-average{color:#f29a29!important}.theme-noticeboard .color-bad{color:#df3e3e!important}.theme-noticeboard .color-label{color:#8b9bb0!important}.theme-noticeboard .color-gold{color:#f3b22f!important}.theme-noticeboard .color-bg-black{background-color:#000!important}.theme-noticeboard .color-bg-white{background-color:#d9d9d9!important}.theme-noticeboard .color-bg-red{background-color:#bd2020!important}.theme-noticeboard .color-bg-orange{background-color:#d95e0c!important}.theme-noticeboard .color-bg-yellow{background-color:#d9b804!important}.theme-noticeboard .color-bg-olive{background-color:#9aad14!important}.theme-noticeboard .color-bg-green{background-color:#1b9638!important}.theme-noticeboard .color-bg-teal{background-color:#009a93!important}.theme-noticeboard .color-bg-blue{background-color:#1c71b1!important}.theme-noticeboard .color-bg-violet{background-color:#552dab!important}.theme-noticeboard .color-bg-purple{background-color:#8b2baa!important}.theme-noticeboard .color-bg-pink{background-color:#cf2082!important}.theme-noticeboard .color-bg-brown{background-color:#8c5836!important}.theme-noticeboard .color-bg-grey{background-color:#646464!important}.theme-noticeboard .color-bg-good{background-color:#4d9121!important}.theme-noticeboard .color-bg-average{background-color:#cd7a0d!important}.theme-noticeboard .color-bg-bad{background-color:#bd2020!important}.theme-noticeboard .color-bg-label{background-color:#657a94!important}.theme-noticeboard .color-bg-gold{background-color:#d6920c!important}.theme-noticeboard .color-border-black{border-color:#1a1a1a!important}.theme-noticeboard .color-border-white{border-color:#fff!important}.theme-noticeboard .color-border-red{border-color:#df3e3e!important}.theme-noticeboard .color-border-orange{border-color:#f37f33!important}.theme-noticeboard .color-border-yellow{border-color:#fbda21!important}.theme-noticeboard .color-border-olive{border-color:#cbe41c!important}.theme-noticeboard .color-border-green{border-color:#25ca4c!important}.theme-noticeboard .color-border-teal{border-color:#00d6cc!important}.theme-noticeboard .color-border-blue{border-color:#2e93de!important}.theme-noticeboard .color-border-violet{border-color:#7349cf!important}.theme-noticeboard .color-border-purple{border-color:#ad45d0!important}.theme-noticeboard .color-border-pink{border-color:#e34da1!important}.theme-noticeboard .color-border-brown{border-color:#b97447!important}.theme-noticeboard .color-border-grey{border-color:#848484!important}.theme-noticeboard .color-border-good{border-color:#68c22d!important}.theme-noticeboard .color-border-average{border-color:#f29a29!important}.theme-noticeboard .color-border-bad{border-color:#df3e3e!important}.theme-noticeboard .color-border-label{border-color:#8b9bb0!important}.theme-noticeboard .color-border-gold{border-color:#f3b22f!important}.theme-noticeboard .Section{position:relative;margin-bottom:.5em;background-color:#f2f2f2;box-sizing:border-box}.theme-noticeboard .Section:last-child{margin-bottom:0}.theme-noticeboard .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #4972a1}.theme-noticeboard .Section__titleText{font-size:1.1666666667em;font-weight:700;color:#fff}.theme-noticeboard .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-noticeboard .Section__rest{position:relative}.theme-noticeboard .Section__content{padding:.66em .5em}.theme-noticeboard .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-noticeboard .Section--fill{display:flex;flex-direction:column;height:100%}.theme-noticeboard .Section--fill>.Section__rest{flex-grow:1}.theme-noticeboard .Section--fill>.Section__rest>.Section__content{height:100%}.theme-noticeboard .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-noticeboard .Section--fill.Section--iefix{display:table!important;width:100%!important;height:100%!important;border-collapse:collapse;border-spacing:0}.theme-noticeboard .Section--fill.Section--iefix>.Section__rest{display:table-row!important;height:100%!important}.theme-noticeboard .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-noticeboard .Section--scrollable>.Section__rest>.Section__content{overflow-y:auto;overflow-x:hidden}.theme-noticeboard .Section .Section{background-color:rgba(0,0,0,0);margin-left:-.5em;margin-right:-.5em}.theme-noticeboard .Section .Section:first-child{margin-top:-.5em}.theme-noticeboard .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-noticeboard .Section .Section .Section .Section__titleText{font-size:1em}.theme-noticeboard .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#2b0f0c;background-image:linear-gradient(to bottom,#2b0f0c,#2b0f0c)}.theme-noticeboard .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-noticeboard .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-noticeboard .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-noticeboard .Window__contentPadding:after{height:0}.theme-noticeboard .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-noticeboard .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(69,37,33,.25);pointer-events:none}.theme-noticeboard .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-noticeboard .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-noticeboard .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-noticeboard .TitleBar{background-color:#2b0f0c;border-bottom:1px solid #2b0f0c;box-shadow:0 2px 2px #2b0f0c;box-shadow:0 .1666666667rem .1666666667rem #2b0f0c;user-select:none;-ms-user-select:none}.theme-noticeboard .TitleBar__clickable{color:rgba(255,255,255,.5);background-color:#2b0f0c;transition:color .25s,background-color .25s}.theme-noticeboard .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-noticeboard .TitleBar__title{position:absolute;top:0;left:46px;left:3.8333333333rem;color:rgba(255,255,255,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap}.theme-noticeboard .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-noticeboard .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px!important;line-height:2.6666666667rem!important}.theme-noticeboard .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-noticeboard .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-noticeboard .Layout,.theme-noticeboard .Layout *{scrollbar-base-color:#f2f2f2;scrollbar-face-color:#e1e1e1;scrollbar-3dlight-color:#f2f2f2;scrollbar-highlight-color:#c8c8c8;scrollbar-track-color:#f2f2f2;scrollbar-arrow-color:#969696;scrollbar-shadow-color:#f2f2f2}.theme-noticeboard .Layout__content{background-image:none}.theme-noticeboard .Window__contentPadding{background-color:#824b28;box-shadow:inset 0 0 10px 1px rgba(0,0,0,.75);border-radius:1em}.theme-noticeboard .Stack--horizontal>.Stack__item{margin-left:1em}.theme-noticeboard .Stack--horizontal>.Stack__item:last-child{margin-right:1em}.theme-noticeboard .Section{font-family:Comic Sans MS,cursive,sans-serif;font-style:italic;white-space:pre-wrap;color:#000;box-shadow:5px 5px 5px rgba(0,0,0,.5);border-radius:100px 100px 200px 200px/10px;transition:all .1s ease-in-out}.theme-noticeboard .Section>.Section__rest>.Section__content{overflow-y:hidden;overflow-x:hidden}.theme-noticeboard .Section__content{margin-top:.25em}.theme-noticeboard .Section__title{margin-top:.5em;padding-bottom:0;border:0}.theme-noticeboard .Section__titleText{color:#000}.theme-noticeboard .Section:hover{transform:scale(1.15);border-radius:1em;box-shadow:0 0 20px 10px rgba(0,0,0,.33);z-index:2}.theme-noticeboard .Section:before{content:" ";display:block;width:10px;height:10px;background:linear-gradient(300deg,#640000,red 75%,#ff7d7d);box-shadow:1.5px 1.5px 5px rgba(0,0,0,.6);border-radius:100%;position:absolute;left:calc(50% - 12px);margin-top:.25em;transform:matrix(1,0,.4,.9,0,0)} diff --git a/tgui/public/tgui.bundle.js b/tgui/public/tgui.bundle.js index 013f3f6e8f955..7802046e0ac58 100644 --- a/tgui/public/tgui.bundle.js +++ b/tgui/public/tgui.bundle.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD (function(){(function(){var Jt={96376:function(T,r,n){"use strict";r.__esModule=!0,r.createPopper=void 0,r.popperGenerator=m;var e=g(n(74758)),a=g(n(28811)),t=g(n(98309)),o=g(n(44896)),f=g(n(33118)),b=g(n(10579)),y=g(n(56500)),I=g(n(17633));r.detectOverflow=I.default;var k=n(75573);function g(u){return u&&u.__esModule?u:{default:u}}var l={placement:"bottom",modifiers:[],strategy:"absolute"};function c(){for(var u=arguments.length,s=new Array(u),d=0;d0&&(0,a.round)(g.width)/y.offsetWidth||1,c=y.offsetHeight>0&&(0,a.round)(g.height)/y.offsetHeight||1);var m=(0,e.isElement)(y)?(0,t.default)(y):window,i=m.visualViewport,u=!(0,o.default)()&&k,s=(g.left+(u&&i?i.offsetLeft:0))/l,d=(g.top+(u&&i?i.offsetTop:0))/c,v=g.width/l,h=g.height/c;return{width:v,height:h,top:d,right:s+v,bottom:d+h,left:s,x:s,y:d}}},49035:function(T,r,n){"use strict";r.__esModule=!0,r.default=h;var e=n(46206),a=u(n(87991)),t=u(n(79752)),o=u(n(98309)),f=u(n(44896)),b=u(n(40600)),y=u(n(16599)),I=n(75573),k=u(n(37786)),g=u(n(57819)),l=u(n(4206)),c=u(n(12972)),m=u(n(81666)),i=n(63618);function u(C){return C&&C.__esModule?C:{default:C}}function s(C,p){var N=(0,k.default)(C,!1,p==="fixed");return N.top=N.top+C.clientTop,N.left=N.left+C.clientLeft,N.bottom=N.top+C.clientHeight,N.right=N.left+C.clientWidth,N.width=C.clientWidth,N.height=C.clientHeight,N.x=N.left,N.y=N.top,N}function d(C,p,N){return p===e.viewport?(0,m.default)((0,a.default)(C,N)):(0,I.isElement)(p)?s(p,N):(0,m.default)((0,t.default)((0,b.default)(C)))}function v(C){var p=(0,o.default)((0,g.default)(C)),N=["absolute","fixed"].indexOf((0,y.default)(C).position)>=0,V=N&&(0,I.isHTMLElement)(C)?(0,f.default)(C):C;return(0,I.isElement)(V)?p.filter(function(S){return(0,I.isElement)(S)&&(0,l.default)(S,V)&&(0,c.default)(S)!=="body"}):[]}function h(C,p,N,V){var S=p==="clippingParents"?v(C):[].concat(p),B=[].concat(S,[N]),L=B[0],w=B.reduce(function(A,x){var E=d(C,x,V);return A.top=(0,i.max)(E.top,A.top),A.right=(0,i.min)(E.right,A.right),A.bottom=(0,i.min)(E.bottom,A.bottom),A.left=(0,i.max)(E.left,A.left),A},d(C,L,V));return w.width=w.right-w.left,w.height=w.bottom-w.top,w.x=w.left,w.y=w.top,w}},74758:function(T,r,n){"use strict";r.__esModule=!0,r.default=l;var e=k(n(37786)),a=k(n(13390)),t=k(n(12972)),o=n(75573),f=k(n(79697)),b=k(n(40600)),y=k(n(10798)),I=n(63618);function k(c){return c&&c.__esModule?c:{default:c}}function g(c){var m=c.getBoundingClientRect(),i=(0,I.round)(m.width)/c.offsetWidth||1,u=(0,I.round)(m.height)/c.offsetHeight||1;return i!==1||u!==1}function l(c,m,i){i===void 0&&(i=!1);var u=(0,o.isHTMLElement)(m),s=(0,o.isHTMLElement)(m)&&g(m),d=(0,b.default)(m),v=(0,e.default)(c,s,i),h={scrollLeft:0,scrollTop:0},C={x:0,y:0};return(u||!u&&!i)&&(((0,t.default)(m)!=="body"||(0,y.default)(d))&&(h=(0,a.default)(m)),(0,o.isHTMLElement)(m)?(C=(0,e.default)(m,!0),C.x+=m.clientLeft,C.y+=m.clientTop):d&&(C.x=(0,f.default)(d))),{x:v.left+h.scrollLeft-C.x,y:v.top+h.scrollTop-C.y,width:v.width,height:v.height}}},16599:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(95115));function a(o){return o&&o.__esModule?o:{default:o}}function t(o){return(0,e.default)(o).getComputedStyle(o)}},40600:function(T,r,n){"use strict";r.__esModule=!0,r.default=a;var e=n(75573);function a(t){return(((0,e.isElement)(t)?t.ownerDocument:t.document)||window.document).documentElement}},79752:function(T,r,n){"use strict";r.__esModule=!0,r.default=y;var e=b(n(40600)),a=b(n(16599)),t=b(n(79697)),o=b(n(43750)),f=n(63618);function b(I){return I&&I.__esModule?I:{default:I}}function y(I){var k,g=(0,e.default)(I),l=(0,o.default)(I),c=(k=I.ownerDocument)==null?void 0:k.body,m=(0,f.max)(g.scrollWidth,g.clientWidth,c?c.scrollWidth:0,c?c.clientWidth:0),i=(0,f.max)(g.scrollHeight,g.clientHeight,c?c.scrollHeight:0,c?c.clientHeight:0),u=-l.scrollLeft+(0,t.default)(I),s=-l.scrollTop;return(0,a.default)(c||g).direction==="rtl"&&(u+=(0,f.max)(g.clientWidth,c?c.clientWidth:0)-m),{width:m,height:i,x:u,y:s}}},3073:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){return{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}}},28811:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(37786));function a(o){return o&&o.__esModule?o:{default:o}}function t(o){var f=(0,e.default)(o),b=o.offsetWidth,y=o.offsetHeight;return Math.abs(f.width-b)<=1&&(b=f.width),Math.abs(f.height-y)<=1&&(y=f.height),{x:o.offsetLeft,y:o.offsetTop,width:b,height:y}}},12972:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){return e?(e.nodeName||"").toLowerCase():null}},13390:function(T,r,n){"use strict";r.__esModule=!0,r.default=b;var e=f(n(43750)),a=f(n(95115)),t=n(75573),o=f(n(3073));function f(y){return y&&y.__esModule?y:{default:y}}function b(y){return y===(0,a.default)(y)||!(0,t.isHTMLElement)(y)?(0,e.default)(y):(0,o.default)(y)}},44896:function(T,r,n){"use strict";r.__esModule=!0,r.default=l;var e=I(n(95115)),a=I(n(12972)),t=I(n(16599)),o=n(75573),f=I(n(87031)),b=I(n(57819)),y=I(n(35366));function I(c){return c&&c.__esModule?c:{default:c}}function k(c){return!(0,o.isHTMLElement)(c)||(0,t.default)(c).position==="fixed"?null:c.offsetParent}function g(c){var m=/firefox/i.test((0,y.default)()),i=/Trident/i.test((0,y.default)());if(i&&(0,o.isHTMLElement)(c)){var u=(0,t.default)(c);if(u.position==="fixed")return null}var s=(0,b.default)(c);for((0,o.isShadowRoot)(s)&&(s=s.host);(0,o.isHTMLElement)(s)&&["html","body"].indexOf((0,a.default)(s))<0;){var d=(0,t.default)(s);if(d.transform!=="none"||d.perspective!=="none"||d.contain==="paint"||["transform","perspective"].indexOf(d.willChange)!==-1||m&&d.willChange==="filter"||m&&d.filter&&d.filter!=="none")return s;s=s.parentNode}return null}function l(c){for(var m=(0,e.default)(c),i=k(c);i&&(0,f.default)(i)&&(0,t.default)(i).position==="static";)i=k(i);return i&&((0,a.default)(i)==="html"||(0,a.default)(i)==="body"&&(0,t.default)(i).position==="static")?m:i||g(c)||m}},57819:function(T,r,n){"use strict";r.__esModule=!0,r.default=f;var e=o(n(12972)),a=o(n(40600)),t=n(75573);function o(b){return b&&b.__esModule?b:{default:b}}function f(b){return(0,e.default)(b)==="html"?b:b.assignedSlot||b.parentNode||((0,t.isShadowRoot)(b)?b.host:null)||(0,a.default)(b)}},24426:function(T,r,n){"use strict";r.__esModule=!0,r.default=b;var e=f(n(57819)),a=f(n(10798)),t=f(n(12972)),o=n(75573);function f(y){return y&&y.__esModule?y:{default:y}}function b(y){return["html","body","#document"].indexOf((0,t.default)(y))>=0?y.ownerDocument.body:(0,o.isHTMLElement)(y)&&(0,a.default)(y)?y:b((0,e.default)(y))}},87991:function(T,r,n){"use strict";r.__esModule=!0,r.default=b;var e=f(n(95115)),a=f(n(40600)),t=f(n(79697)),o=f(n(89331));function f(y){return y&&y.__esModule?y:{default:y}}function b(y,I){var k=(0,e.default)(y),g=(0,a.default)(y),l=k.visualViewport,c=g.clientWidth,m=g.clientHeight,i=0,u=0;if(l){c=l.width,m=l.height;var s=(0,o.default)();(s||!s&&I==="fixed")&&(i=l.offsetLeft,u=l.offsetTop)}return{width:c,height:m,x:i+(0,t.default)(y),y:u}}},95115:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){if(e==null)return window;if(e.toString()!=="[object Window]"){var a=e.ownerDocument;return a&&a.defaultView||window}return e}},43750:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(95115));function a(o){return o&&o.__esModule?o:{default:o}}function t(o){var f=(0,e.default)(o),b=f.pageXOffset,y=f.pageYOffset;return{scrollLeft:b,scrollTop:y}}},79697:function(T,r,n){"use strict";r.__esModule=!0,r.default=f;var e=o(n(37786)),a=o(n(40600)),t=o(n(43750));function o(b){return b&&b.__esModule?b:{default:b}}function f(b){return(0,e.default)((0,a.default)(b)).left+(0,t.default)(b).scrollLeft}},75573:function(T,r,n){"use strict";r.__esModule=!0,r.isElement=t,r.isHTMLElement=o,r.isShadowRoot=f;var e=a(n(95115));function a(b){return b&&b.__esModule?b:{default:b}}function t(b){var y=(0,e.default)(b).Element;return b instanceof y||b instanceof Element}function o(b){var y=(0,e.default)(b).HTMLElement;return b instanceof y||b instanceof HTMLElement}function f(b){if(typeof ShadowRoot=="undefined")return!1;var y=(0,e.default)(b).ShadowRoot;return b instanceof y||b instanceof ShadowRoot}},89331:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(35366));function a(o){return o&&o.__esModule?o:{default:o}}function t(){return!/^((?!chrome|android).)*safari/i.test((0,e.default)())}},10798:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(16599));function a(o){return o&&o.__esModule?o:{default:o}}function t(o){var f=(0,e.default)(o),b=f.overflow,y=f.overflowX,I=f.overflowY;return/auto|scroll|overlay|hidden/.test(b+I+y)}},87031:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(12972));function a(o){return o&&o.__esModule?o:{default:o}}function t(o){return["table","td","th"].indexOf((0,e.default)(o))>=0}},98309:function(T,r,n){"use strict";r.__esModule=!0,r.default=b;var e=f(n(24426)),a=f(n(57819)),t=f(n(95115)),o=f(n(10798));function f(y){return y&&y.__esModule?y:{default:y}}function b(y,I){var k;I===void 0&&(I=[]);var g=(0,e.default)(y),l=g===((k=y.ownerDocument)==null?void 0:k.body),c=(0,t.default)(g),m=l?[c].concat(c.visualViewport||[],(0,o.default)(g)?g:[]):g,i=I.concat(m);return l?i:i.concat(b((0,a.default)(m)))}},46206:function(T,r){"use strict";r.__esModule=!0,r.write=r.viewport=r.variationPlacements=r.top=r.start=r.right=r.reference=r.read=r.popper=r.placements=r.modifierPhases=r.main=r.left=r.end=r.clippingParents=r.bottom=r.beforeWrite=r.beforeRead=r.beforeMain=r.basePlacements=r.auto=r.afterWrite=r.afterRead=r.afterMain=void 0;var n=r.top="top",e=r.bottom="bottom",a=r.right="right",t=r.left="left",o=r.auto="auto",f=r.basePlacements=[n,e,a,t],b=r.start="start",y=r.end="end",I=r.clippingParents="clippingParents",k=r.viewport="viewport",g=r.popper="popper",l=r.reference="reference",c=r.variationPlacements=f.reduce(function(S,B){return S.concat([B+"-"+b,B+"-"+y])},[]),m=r.placements=[].concat(f,[o]).reduce(function(S,B){return S.concat([B,B+"-"+b,B+"-"+y])},[]),i=r.beforeRead="beforeRead",u=r.read="read",s=r.afterRead="afterRead",d=r.beforeMain="beforeMain",v=r.main="main",h=r.afterMain="afterMain",C=r.beforeWrite="beforeWrite",p=r.write="write",N=r.afterWrite="afterWrite",V=r.modifierPhases=[i,u,s,d,v,h,C,p,N]},95996:function(T,r,n){"use strict";r.__esModule=!0;var e={popperGenerator:!0,detectOverflow:!0,createPopperBase:!0,createPopper:!0,createPopperLite:!0};r.popperGenerator=r.detectOverflow=r.createPopperLite=r.createPopperBase=r.createPopper=void 0;var a=n(46206);Object.keys(a).forEach(function(y){y==="default"||y==="__esModule"||Object.prototype.hasOwnProperty.call(e,y)||y in r&&r[y]===a[y]||(r[y]=a[y])});var t=n(39805);Object.keys(t).forEach(function(y){y==="default"||y==="__esModule"||Object.prototype.hasOwnProperty.call(e,y)||y in r&&r[y]===t[y]||(r[y]=t[y])});var o=n(96376);r.popperGenerator=o.popperGenerator,r.detectOverflow=o.detectOverflow,r.createPopperBase=o.createPopper;var f=n(83312);r.createPopper=f.createPopper;var b=n(2473);r.createPopperLite=b.createPopper},19975:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=t(n(12972)),a=n(75573);function t(y){return y&&y.__esModule?y:{default:y}}function o(y){var I=y.state;Object.keys(I.elements).forEach(function(k){var g=I.styles[k]||{},l=I.attributes[k]||{},c=I.elements[k];!(0,a.isHTMLElement)(c)||!(0,e.default)(c)||(Object.assign(c.style,g),Object.keys(l).forEach(function(m){var i=l[m];i===!1?c.removeAttribute(m):c.setAttribute(m,i===!0?"":i)}))})}function f(y){var I=y.state,k={popper:{position:I.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(I.elements.popper.style,k.popper),I.styles=k,I.elements.arrow&&Object.assign(I.elements.arrow.style,k.arrow),function(){Object.keys(I.elements).forEach(function(g){var l=I.elements[g],c=I.attributes[g]||{},m=Object.keys(I.styles.hasOwnProperty(g)?I.styles[g]:k[g]),i=m.reduce(function(u,s){return u[s]="",u},{});!(0,a.isHTMLElement)(l)||!(0,e.default)(l)||(Object.assign(l.style,i),Object.keys(c).forEach(function(u){l.removeAttribute(u)}))})}}var b=r.default={name:"applyStyles",enabled:!0,phase:"write",fn:o,effect:f,requires:["computeStyles"]}},52744:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=g(n(83104)),a=g(n(28811)),t=g(n(4206)),o=g(n(44896)),f=g(n(41199)),b=n(28595),y=g(n(43286)),I=g(n(81447)),k=n(46206);function g(u){return u&&u.__esModule?u:{default:u}}var l=function(){function u(s,d){return s=typeof s=="function"?s(Object.assign({},d.rects,{placement:d.placement})):s,(0,y.default)(typeof s!="number"?s:(0,I.default)(s,k.basePlacements))}return u}();function c(u){var s,d=u.state,v=u.name,h=u.options,C=d.elements.arrow,p=d.modifiersData.popperOffsets,N=(0,e.default)(d.placement),V=(0,f.default)(N),S=[k.left,k.right].indexOf(N)>=0,B=S?"height":"width";if(!(!C||!p)){var L=l(h.padding,d),w=(0,a.default)(C),A=V==="y"?k.top:k.left,x=V==="y"?k.bottom:k.right,E=d.rects.reference[B]+d.rects.reference[V]-p[V]-d.rects.popper[B],P=p[V]-d.rects.reference[V],D=(0,o.default)(C),M=D?V==="y"?D.clientHeight||0:D.clientWidth||0:0,R=E/2-P/2,O=L[A],F=M-w[B]-L[x],_=M/2-w[B]/2+R,U=(0,b.within)(O,_,F),z=V;d.modifiersData[v]=(s={},s[z]=U,s.centerOffset=U-_,s)}}function m(u){var s=u.state,d=u.options,v=d.element,h=v===void 0?"[data-popper-arrow]":v;h!=null&&(typeof h=="string"&&(h=s.elements.popper.querySelector(h),!h)||(0,t.default)(s.elements.popper,h)&&(s.elements.arrow=h))}var i=r.default={name:"arrow",enabled:!0,phase:"main",fn:c,effect:m,requires:["popperOffsets"],requiresIfExists:["preventOverflow"]}},59894:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0,r.mapToStyles=c;var e=n(46206),a=k(n(44896)),t=k(n(95115)),o=k(n(40600)),f=k(n(16599)),b=k(n(83104)),y=k(n(45)),I=n(63618);function k(u){return u&&u.__esModule?u:{default:u}}var g={top:"auto",right:"auto",bottom:"auto",left:"auto"};function l(u,s){var d=u.x,v=u.y,h=s.devicePixelRatio||1;return{x:(0,I.round)(d*h)/h||0,y:(0,I.round)(v*h)/h||0}}function c(u){var s,d=u.popper,v=u.popperRect,h=u.placement,C=u.variation,p=u.offsets,N=u.position,V=u.gpuAcceleration,S=u.adaptive,B=u.roundOffsets,L=u.isFixed,w=p.x,A=w===void 0?0:w,x=p.y,E=x===void 0?0:x,P=typeof B=="function"?B({x:A,y:E}):{x:A,y:E};A=P.x,E=P.y;var D=p.hasOwnProperty("x"),M=p.hasOwnProperty("y"),R=e.left,O=e.top,F=window;if(S){var _=(0,a.default)(d),U="clientHeight",z="clientWidth";if(_===(0,t.default)(d)&&(_=(0,o.default)(d),(0,f.default)(_).position!=="static"&&N==="absolute"&&(U="scrollHeight",z="scrollWidth")),_=_,h===e.top||(h===e.left||h===e.right)&&C===e.end){O=e.bottom;var $=L&&_===F&&F.visualViewport?F.visualViewport.height:_[U];E-=$-v.height,E*=V?1:-1}if(h===e.left||(h===e.top||h===e.bottom)&&C===e.end){R=e.right;var G=L&&_===F&&F.visualViewport?F.visualViewport.width:_[z];A-=G-v.width,A*=V?1:-1}}var X=Object.assign({position:N},S&&g),J=B===!0?l({x:A,y:E},(0,t.default)(d)):{x:A,y:E};if(A=J.x,E=J.y,V){var se;return Object.assign({},X,(se={},se[O]=M?"0":"",se[R]=D?"0":"",se.transform=(F.devicePixelRatio||1)<=1?"translate("+A+"px, "+E+"px)":"translate3d("+A+"px, "+E+"px, 0)",se))}return Object.assign({},X,(s={},s[O]=M?E+"px":"",s[R]=D?A+"px":"",s.transform="",s))}function m(u){var s=u.state,d=u.options,v=d.gpuAcceleration,h=v===void 0?!0:v,C=d.adaptive,p=C===void 0?!0:C,N=d.roundOffsets,V=N===void 0?!0:N,S={placement:(0,b.default)(s.placement),variation:(0,y.default)(s.placement),popper:s.elements.popper,popperRect:s.rects.popper,gpuAcceleration:h,isFixed:s.options.strategy==="fixed"};s.modifiersData.popperOffsets!=null&&(s.styles.popper=Object.assign({},s.styles.popper,c(Object.assign({},S,{offsets:s.modifiersData.popperOffsets,position:s.options.strategy,adaptive:p,roundOffsets:V})))),s.modifiersData.arrow!=null&&(s.styles.arrow=Object.assign({},s.styles.arrow,c(Object.assign({},S,{offsets:s.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:V})))),s.attributes.popper=Object.assign({},s.attributes.popper,{"data-popper-placement":s.placement})}var i=r.default={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:m,data:{}}},36692:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=a(n(95115));function a(b){return b&&b.__esModule?b:{default:b}}var t={passive:!0};function o(b){var y=b.state,I=b.instance,k=b.options,g=k.scroll,l=g===void 0?!0:g,c=k.resize,m=c===void 0?!0:c,i=(0,e.default)(y.elements.popper),u=[].concat(y.scrollParents.reference,y.scrollParents.popper);return l&&u.forEach(function(s){s.addEventListener("scroll",I.update,t)}),m&&i.addEventListener("resize",I.update,t),function(){l&&u.forEach(function(s){s.removeEventListener("scroll",I.update,t)}),m&&i.removeEventListener("resize",I.update,t)}}var f=r.default={name:"eventListeners",enabled:!0,phase:"write",fn:function(){function b(){}return b}(),effect:o,data:{}}},23798:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=I(n(71376)),a=I(n(83104)),t=I(n(86459)),o=I(n(17633)),f=I(n(9041)),b=n(46206),y=I(n(45));function I(c){return c&&c.__esModule?c:{default:c}}function k(c){if((0,a.default)(c)===b.auto)return[];var m=(0,e.default)(c);return[(0,t.default)(c),m,(0,t.default)(m)]}function g(c){var m=c.state,i=c.options,u=c.name;if(!m.modifiersData[u]._skip){for(var s=i.mainAxis,d=s===void 0?!0:s,v=i.altAxis,h=v===void 0?!0:v,C=i.fallbackPlacements,p=i.padding,N=i.boundary,V=i.rootBoundary,S=i.altBoundary,B=i.flipVariations,L=B===void 0?!0:B,w=i.allowedAutoPlacements,A=m.options.placement,x=(0,a.default)(A),E=x===A,P=C||(E||!L?[(0,e.default)(A)]:k(A)),D=[A].concat(P).reduce(function(ne,te){return ne.concat((0,a.default)(te)===b.auto?(0,f.default)(m,{placement:te,boundary:N,rootBoundary:V,padding:p,flipVariations:L,allowedAutoPlacements:w}):te)},[]),M=m.rects.reference,R=m.rects.popper,O=new Map,F=!0,_=D[0],U=0;U=0,J=X?"width":"height",se=(0,o.default)(m,{placement:z,boundary:N,rootBoundary:V,altBoundary:S,padding:p}),ie=X?G?b.right:b.left:G?b.bottom:b.top;M[J]>R[J]&&(ie=(0,e.default)(ie));var me=(0,e.default)(ie),q=[];if(d&&q.push(se[$]<=0),h&&q.push(se[ie]<=0,se[me]<=0),q.every(function(ne){return ne})){_=z,F=!1;break}O.set(z,q)}if(F)for(var re=L?3:1,ae=function(){function ne(te){var fe=D.find(function(pe){var ce=O.get(pe);if(ce)return ce.slice(0,te).every(function(Ve){return Ve})});if(fe)return _=fe,"break"}return ne}(),le=re;le>0;le--){var Z=ae(le);if(Z==="break")break}m.placement!==_&&(m.modifiersData[u]._skip=!0,m.placement=_,m.reset=!0)}}var l=r.default={name:"flip",enabled:!0,phase:"main",fn:g,requiresIfExists:["offset"],data:{_skip:!1}}},83761:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=n(46206),a=t(n(17633));function t(I){return I&&I.__esModule?I:{default:I}}function o(I,k,g){return g===void 0&&(g={x:0,y:0}),{top:I.top-k.height-g.y,right:I.right-k.width+g.x,bottom:I.bottom-k.height+g.y,left:I.left-k.width-g.x}}function f(I){return[e.top,e.right,e.bottom,e.left].some(function(k){return I[k]>=0})}function b(I){var k=I.state,g=I.name,l=k.rects.reference,c=k.rects.popper,m=k.modifiersData.preventOverflow,i=(0,a.default)(k,{elementContext:"reference"}),u=(0,a.default)(k,{altBoundary:!0}),s=o(i,l),d=o(u,c,m),v=f(s),h=f(d);k.modifiersData[g]={referenceClippingOffsets:s,popperEscapeOffsets:d,isReferenceHidden:v,hasPopperEscaped:h},k.attributes.popper=Object.assign({},k.attributes.popper,{"data-popper-reference-hidden":v,"data-popper-escaped":h})}var y=r.default={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:b}},39805:function(T,r,n){"use strict";r.__esModule=!0,r.preventOverflow=r.popperOffsets=r.offset=r.hide=r.flip=r.eventListeners=r.computeStyles=r.arrow=r.applyStyles=void 0;var e=g(n(19975));r.applyStyles=e.default;var a=g(n(52744));r.arrow=a.default;var t=g(n(59894));r.computeStyles=t.default;var o=g(n(36692));r.eventListeners=o.default;var f=g(n(23798));r.flip=f.default;var b=g(n(83761));r.hide=b.default;var y=g(n(61410));r.offset=y.default;var I=g(n(40107));r.popperOffsets=I.default;var k=g(n(75137));r.preventOverflow=k.default;function g(l){return l&&l.__esModule?l:{default:l}}},61410:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0,r.distanceAndSkiddingToXY=o;var e=t(n(83104)),a=n(46206);function t(y){return y&&y.__esModule?y:{default:y}}function o(y,I,k){var g=(0,e.default)(y),l=[a.left,a.top].indexOf(g)>=0?-1:1,c=typeof k=="function"?k(Object.assign({},I,{placement:y})):k,m=c[0],i=c[1];return m=m||0,i=(i||0)*l,[a.left,a.right].indexOf(g)>=0?{x:i,y:m}:{x:m,y:i}}function f(y){var I=y.state,k=y.options,g=y.name,l=k.offset,c=l===void 0?[0,0]:l,m=a.placements.reduce(function(d,v){return d[v]=o(v,I.rects,c),d},{}),i=m[I.placement],u=i.x,s=i.y;I.modifiersData.popperOffsets!=null&&(I.modifiersData.popperOffsets.x+=u,I.modifiersData.popperOffsets.y+=s),I.modifiersData[g]=m}var b=r.default={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:f}},40107:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=a(n(89951));function a(f){return f&&f.__esModule?f:{default:f}}function t(f){var b=f.state,y=f.name;b.modifiersData[y]=(0,e.default)({reference:b.rects.reference,element:b.rects.popper,strategy:"absolute",placement:b.placement})}var o=r.default={name:"popperOffsets",enabled:!0,phase:"read",fn:t,data:{}}},75137:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=n(46206),a=c(n(83104)),t=c(n(41199)),o=c(n(28066)),f=n(28595),b=c(n(28811)),y=c(n(44896)),I=c(n(17633)),k=c(n(45)),g=c(n(34780)),l=n(63618);function c(u){return u&&u.__esModule?u:{default:u}}function m(u){var s=u.state,d=u.options,v=u.name,h=d.mainAxis,C=h===void 0?!0:h,p=d.altAxis,N=p===void 0?!1:p,V=d.boundary,S=d.rootBoundary,B=d.altBoundary,L=d.padding,w=d.tether,A=w===void 0?!0:w,x=d.tetherOffset,E=x===void 0?0:x,P=(0,I.default)(s,{boundary:V,rootBoundary:S,padding:L,altBoundary:B}),D=(0,a.default)(s.placement),M=(0,k.default)(s.placement),R=!M,O=(0,t.default)(D),F=(0,o.default)(O),_=s.modifiersData.popperOffsets,U=s.rects.reference,z=s.rects.popper,$=typeof E=="function"?E(Object.assign({},s.rects,{placement:s.placement})):E,G=typeof $=="number"?{mainAxis:$,altAxis:$}:Object.assign({mainAxis:0,altAxis:0},$),X=s.modifiersData.offset?s.modifiersData.offset[s.placement]:null,J={x:0,y:0};if(_){if(C){var se,ie=O==="y"?e.top:e.left,me=O==="y"?e.bottom:e.right,q=O==="y"?"height":"width",re=_[O],ae=re+P[ie],le=re-P[me],Z=A?-z[q]/2:0,ne=M===e.start?U[q]:z[q],te=M===e.start?-z[q]:-U[q],fe=s.elements.arrow,pe=A&&fe?(0,b.default)(fe):{width:0,height:0},ce=s.modifiersData["arrow#persistent"]?s.modifiersData["arrow#persistent"].padding:(0,g.default)(),Ve=ce[ie],Ce=ce[me],Ne=(0,f.within)(0,U[q],pe[q]),Be=R?U[q]/2-Z-Ne-Ve-G.mainAxis:ne-Ne-Ve-G.mainAxis,be=R?-U[q]/2+Z+Ne+Ce+G.mainAxis:te+Ne+Ce+G.mainAxis,Le=s.elements.arrow&&(0,y.default)(s.elements.arrow),we=Le?O==="y"?Le.clientTop||0:Le.clientLeft||0:0,xe=(se=X==null?void 0:X[O])!=null?se:0,Re=re+Be-xe-we,He=re+be-xe,ye=(0,f.within)(A?(0,l.min)(ae,Re):ae,re,A?(0,l.max)(le,He):le);_[O]=ye,J[O]=ye-re}if(N){var de,he=O==="x"?e.top:e.left,ke=O==="x"?e.bottom:e.right,ve=_[F],Se=F==="y"?"height":"width",Pe=ve+P[he],je=ve-P[ke],Fe=[e.top,e.left].indexOf(D)!==-1,ze=(de=X==null?void 0:X[F])!=null?de:0,We=Fe?Pe:ve-U[Se]-z[Se]-ze+G.altAxis,Ue=Fe?ve+U[Se]+z[Se]-ze-G.altAxis:je,Xe=A&&Fe?(0,f.withinMaxClamp)(We,ve,Ue):(0,f.within)(A?We:Pe,ve,A?Ue:je);_[F]=Xe,J[F]=Xe-ve}s.modifiersData[v]=J}}var i=r.default={name:"preventOverflow",enabled:!0,phase:"main",fn:m,requiresIfExists:["offset"]}},2473:function(T,r,n){"use strict";r.__esModule=!0,r.defaultModifiers=r.createPopper=void 0;var e=n(96376);r.popperGenerator=e.popperGenerator,r.detectOverflow=e.detectOverflow;var a=b(n(36692)),t=b(n(40107)),o=b(n(59894)),f=b(n(19975));function b(k){return k&&k.__esModule?k:{default:k}}var y=r.defaultModifiers=[a.default,t.default,o.default,f.default],I=r.createPopper=(0,e.popperGenerator)({defaultModifiers:y})},83312:function(T,r,n){"use strict";r.__esModule=!0;var e={createPopper:!0,createPopperLite:!0,defaultModifiers:!0,popperGenerator:!0,detectOverflow:!0};r.defaultModifiers=r.createPopperLite=r.createPopper=void 0;var a=n(96376);r.popperGenerator=a.popperGenerator,r.detectOverflow=a.detectOverflow;var t=i(n(36692)),o=i(n(40107)),f=i(n(59894)),b=i(n(19975)),y=i(n(61410)),I=i(n(23798)),k=i(n(75137)),g=i(n(52744)),l=i(n(83761)),c=n(2473);r.createPopperLite=c.createPopper;var m=n(39805);Object.keys(m).forEach(function(d){d==="default"||d==="__esModule"||Object.prototype.hasOwnProperty.call(e,d)||d in r&&r[d]===m[d]||(r[d]=m[d])});function i(d){return d&&d.__esModule?d:{default:d}}var u=r.defaultModifiers=[t.default,o.default,f.default,b.default,y.default,I.default,k.default,g.default,l.default],s=r.createPopperLite=r.createPopper=(0,a.popperGenerator)({defaultModifiers:u})},9041:function(T,r,n){"use strict";r.__esModule=!0,r.default=b;var e=f(n(45)),a=n(46206),t=f(n(17633)),o=f(n(83104));function f(y){return y&&y.__esModule?y:{default:y}}function b(y,I){I===void 0&&(I={});var k=I,g=k.placement,l=k.boundary,c=k.rootBoundary,m=k.padding,i=k.flipVariations,u=k.allowedAutoPlacements,s=u===void 0?a.placements:u,d=(0,e.default)(g),v=d?i?a.variationPlacements:a.variationPlacements.filter(function(p){return(0,e.default)(p)===d}):a.basePlacements,h=v.filter(function(p){return s.indexOf(p)>=0});h.length===0&&(h=v);var C=h.reduce(function(p,N){return p[N]=(0,t.default)(y,{placement:N,boundary:l,rootBoundary:c,padding:m})[(0,o.default)(N)],p},{});return Object.keys(C).sort(function(p,N){return C[p]-C[N]})}},89951:function(T,r,n){"use strict";r.__esModule=!0,r.default=b;var e=f(n(83104)),a=f(n(45)),t=f(n(41199)),o=n(46206);function f(y){return y&&y.__esModule?y:{default:y}}function b(y){var I=y.reference,k=y.element,g=y.placement,l=g?(0,e.default)(g):null,c=g?(0,a.default)(g):null,m=I.x+I.width/2-k.width/2,i=I.y+I.height/2-k.height/2,u;switch(l){case o.top:u={x:m,y:I.y-k.height};break;case o.bottom:u={x:m,y:I.y+I.height};break;case o.right:u={x:I.x+I.width,y:i};break;case o.left:u={x:I.x-k.width,y:i};break;default:u={x:I.x,y:I.y}}var s=l?(0,t.default)(l):null;if(s!=null){var d=s==="y"?"height":"width";switch(c){case o.start:u[s]=u[s]-(I[d]/2-k[d]/2);break;case o.end:u[s]=u[s]+(I[d]/2-k[d]/2);break;default:}}return u}},10579:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){var a;return function(){return a||(a=new Promise(function(t){Promise.resolve().then(function(){a=void 0,t(e())})})),a}}},17633:function(T,r,n){"use strict";r.__esModule=!0,r.default=l;var e=g(n(49035)),a=g(n(40600)),t=g(n(37786)),o=g(n(89951)),f=g(n(81666)),b=n(46206),y=n(75573),I=g(n(43286)),k=g(n(81447));function g(c){return c&&c.__esModule?c:{default:c}}function l(c,m){m===void 0&&(m={});var i=m,u=i.placement,s=u===void 0?c.placement:u,d=i.strategy,v=d===void 0?c.strategy:d,h=i.boundary,C=h===void 0?b.clippingParents:h,p=i.rootBoundary,N=p===void 0?b.viewport:p,V=i.elementContext,S=V===void 0?b.popper:V,B=i.altBoundary,L=B===void 0?!1:B,w=i.padding,A=w===void 0?0:w,x=(0,I.default)(typeof A!="number"?A:(0,k.default)(A,b.basePlacements)),E=S===b.popper?b.reference:b.popper,P=c.rects.popper,D=c.elements[L?E:S],M=(0,e.default)((0,y.isElement)(D)?D:D.contextElement||(0,a.default)(c.elements.popper),C,N,v),R=(0,t.default)(c.elements.reference),O=(0,o.default)({reference:R,element:P,strategy:"absolute",placement:s}),F=(0,f.default)(Object.assign({},P,O)),_=S===b.popper?F:R,U={top:M.top-_.top+x.top,bottom:_.bottom-M.bottom+x.bottom,left:M.left-_.left+x.left,right:_.right-M.right+x.right},z=c.modifiersData.offset;if(S===b.popper&&z){var $=z[s];Object.keys(U).forEach(function(G){var X=[b.right,b.bottom].indexOf(G)>=0?1:-1,J=[b.top,b.bottom].indexOf(G)>=0?"y":"x";U[G]+=$[J]*X})}return U}},81447:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e,a){return a.reduce(function(t,o){return t[o]=e,t},{})}},28066:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){return e==="x"?"y":"x"}},83104:function(T,r,n){"use strict";r.__esModule=!0,r.default=a;var e=n(46206);function a(t){return t.split("-")[0]}},34780:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(){return{top:0,right:0,bottom:0,left:0}}},41199:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}},71376:function(T,r){"use strict";r.__esModule=!0,r.default=e;var n={left:"right",right:"left",bottom:"top",top:"bottom"};function e(a){return a.replace(/left|right|bottom|top/g,function(t){return n[t]})}},86459:function(T,r){"use strict";r.__esModule=!0,r.default=e;var n={start:"end",end:"start"};function e(a){return a.replace(/start|end/g,function(t){return n[t]})}},45:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){return e.split("-")[1]}},63618:function(T,r){"use strict";r.__esModule=!0,r.round=r.min=r.max=void 0;var n=r.max=Math.max,e=r.min=Math.min,a=r.round=Math.round},56500:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){var a=e.reduce(function(t,o){var f=t[o.name];return t[o.name]=f?Object.assign({},f,o,{options:Object.assign({},f.options,o.options),data:Object.assign({},f.data,o.data)}):o,t},{});return Object.keys(a).map(function(t){return a[t]})}},43286:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(34780));function a(o){return o&&o.__esModule?o:{default:o}}function t(o){return Object.assign({},(0,e.default)(),o)}},33118:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=n(46206);function a(o){var f=new Map,b=new Set,y=[];o.forEach(function(k){f.set(k.name,k)});function I(k){b.add(k.name);var g=[].concat(k.requires||[],k.requiresIfExists||[]);g.forEach(function(l){if(!b.has(l)){var c=f.get(l);c&&I(c)}}),y.push(k)}return o.forEach(function(k){b.has(k.name)||I(k)}),y}function t(o){var f=a(o);return e.modifierPhases.reduce(function(b,y){return b.concat(f.filter(function(I){return I.phase===y}))},[])}},81666:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}},35366:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(){var e=navigator.userAgentData;return e!=null&&e.brands&&Array.isArray(e.brands)?e.brands.map(function(a){return a.brand+"/"+a.version}).join(" "):navigator.userAgent}},28595:function(T,r,n){"use strict";r.__esModule=!0,r.within=a,r.withinMaxClamp=t;var e=n(63618);function a(o,f,b){return(0,e.max)(o,(0,e.min)(f,b))}function t(o,f,b){var y=a(o,f,b);return y>b?b:y}},15875:function(T,r){"use strict";r.__esModule=!0,r.VNodeFlags=r.ChildFlags=void 0;var n;(function(a){a[a.Unknown=0]="Unknown",a[a.HtmlElement=1]="HtmlElement",a[a.ComponentUnknown=2]="ComponentUnknown",a[a.ComponentClass=4]="ComponentClass",a[a.ComponentFunction=8]="ComponentFunction",a[a.Text=16]="Text",a[a.SvgElement=32]="SvgElement",a[a.InputElement=64]="InputElement",a[a.TextareaElement=128]="TextareaElement",a[a.SelectElement=256]="SelectElement",a[a.Portal=1024]="Portal",a[a.ReCreate=2048]="ReCreate",a[a.ContentEditable=4096]="ContentEditable",a[a.Fragment=8192]="Fragment",a[a.InUse=16384]="InUse",a[a.ForwardRef=32768]="ForwardRef",a[a.Normalized=65536]="Normalized",a[a.ForwardRefComponent=32776]="ForwardRefComponent",a[a.FormElement=448]="FormElement",a[a.Element=481]="Element",a[a.Component=14]="Component",a[a.DOMRef=1521]="DOMRef",a[a.InUseOrNormalized=81920]="InUseOrNormalized",a[a.ClearInUse=-16385]="ClearInUse",a[a.ComponentKnown=12]="ComponentKnown"})(n||(r.VNodeFlags=n={}));var e;(function(a){a[a.UnknownChildren=0]="UnknownChildren",a[a.HasInvalidChildren=1]="HasInvalidChildren",a[a.HasVNodeChildren=2]="HasVNodeChildren",a[a.HasNonKeyedChildren=4]="HasNonKeyedChildren",a[a.HasKeyedChildren=8]="HasKeyedChildren",a[a.HasTextChildren=16]="HasTextChildren",a[a.MultipleChildren=12]="MultipleChildren"})(e||(r.ChildFlags=e={}))},89292:function(T,r){"use strict";r.__esModule=!0,r.Fragment=r.EMPTY_OBJ=r.Component=r.AnimationQueues=void 0,r._CI=Ot,r._HI=pe,r._M=Ke,r._MCCC=Ft,r._ME=Dt,r._MFCC=_t,r._MP=Mt,r._MR=at,r._RFC=gt,r.__render=Ht,r.createComponentVNode=se,r.createFragment=me,r.createPortal=Z,r.createRef=nn,r.createRenderer=En,r.createTextVNode=ie,r.createVNode=$,r.directClone=ae,r.findDOMFromVNode=V,r.forwardRef=on,r.getFlagsForElementVnode=te,r.linkEvent=g,r.normalizeProps=q,r.options=void 0,r.render=zt,r.rerender=$t,r.version=void 0;var n=Array.isArray;function e(j){var W=typeof j;return W==="string"||W==="number"}function a(j){return j==null}function t(j){return j===null||j===!1||j===!0||j===void 0}function o(j){return typeof j=="function"}function f(j){return typeof j=="string"}function b(j){return typeof j=="number"}function y(j){return j===null}function I(j){return j===void 0}function k(j,W){var H={};if(j)for(var K in j)H[K]=j[K];if(W)for(var Q in W)H[Q]=W[Q];return H}function g(j,W){return o(W)?{data:j,event:W}:null}function l(j){return!y(j)&&typeof j=="object"}var c=r.EMPTY_OBJ={},m=r.Fragment="$F",i=r.AnimationQueues=function(){function j(){this.componentDidAppear=[],this.componentWillDisappear=[],this.componentWillMove=[]}return j}();function u(j){return j.substring(2).toLowerCase()}function s(j,W){j.appendChild(W)}function d(j,W,H){y(H)?s(j,W):j.insertBefore(W,H)}function v(j,W){return W?document.createElementNS("http://www.w3.org/2000/svg",j):document.createElement(j)}function h(j,W,H){j.replaceChild(W,H)}function C(j,W){j.removeChild(W)}function p(j){for(var W=0;W0?S(H.componentWillDisappear,w(j,W)):L(j,W,!1)}function x(j,W,H,K,Q,ee,oe,ue){j.componentWillMove.push({dom:K,fn:function(){function ge(){oe&4?H.componentWillMove(W,Q,K):oe&8&&H.onComponentWillMove(W,Q,K,ue)}return ge}(),next:ee,parent:Q})}function E(j,W,H,K,Q){var ee,oe,ue=W.flags;do{var ge=W.flags;if(ge&1521){!a(ee)&&(o(ee.componentWillMove)||o(ee.onComponentWillMove))?x(Q,j,ee,W.dom,H,K,ue,oe):d(H,W.dom,K);return}var Te=W.children;if(ge&4)ee=W.children,oe=W.props,W=Te.$LI;else if(ge&8)ee=W.ref,oe=W.props,W=Te;else if(ge&8192)if(W.childFlags===2)W=Te;else{for(var Ie=0,Ee=Te.length;Ie0,Te=y(ue),Ie=f(ue)&&ue[0]===U;ge||Te||Ie?(H=H||W.slice(0,ee),(ge||Ie)&&(oe=ae(oe)),(Te||Ie)&&(oe.key=U+ee),H.push(oe)):H&&H.push(oe),oe.flags|=65536}}H=H||W,H.length===0?K=1:K=8}else H=W,H.flags|=65536,W.flags&81920&&(H=ae(W)),K=2;return j.children=H,j.childFlags=K,j}function pe(j){return t(j)||e(j)?ie(j,null):n(j)?me(j,0,null):j.flags&16384?ae(j):j}var ce="http://www.w3.org/1999/xlink",Ve="http://www.w3.org/XML/1998/namespace",Ce={"xlink:actuate":ce,"xlink:arcrole":ce,"xlink:href":ce,"xlink:role":ce,"xlink:show":ce,"xlink:title":ce,"xlink:type":ce,"xml:base":Ve,"xml:lang":Ve,"xml:space":Ve};function Ne(j){return{onClick:j,onDblClick:j,onFocusIn:j,onFocusOut:j,onKeyDown:j,onKeyPress:j,onKeyUp:j,onMouseDown:j,onMouseMove:j,onMouseUp:j,onTouchEnd:j,onTouchMove:j,onTouchStart:j}}var Be=Ne(0),be=Ne(null),Le=Ne(!0);function we(j,W){var H=W.$EV;return H||(H=W.$EV=Ne(null)),H[j]||++Be[j]===1&&(be[j]=je(j)),H}function xe(j,W){var H=W.$EV;H&&H[j]&&(--Be[j]===0&&(document.removeEventListener(u(j),be[j]),be[j]=null),H[j]=null)}function Re(j,W,H,K){if(o(H))we(j,K)[j]=H;else if(l(H)){if(O(W,H))return;we(j,K)[j]=H}else xe(j,K)}function He(j){return o(j.composedPath)?j.composedPath()[0]:j.target}function ye(j,W,H,K){var Q=He(j);do{if(W&&Q.disabled)return;var ee=Q.$EV;if(ee){var oe=ee[H];if(oe&&(K.dom=Q,oe.event?oe.event(oe.data,j):oe(j),j.cancelBubble))return}Q=Q.parentNode}while(!y(Q))}function de(){this.cancelBubble=!0,this.immediatePropagationStopped||this.stopImmediatePropagation()}function he(){return this.defaultPrevented}function ke(){return this.cancelBubble}function ve(j){var W={dom:document};return j.isDefaultPrevented=he,j.isPropagationStopped=ke,j.stopPropagation=de,Object.defineProperty(j,"currentTarget",{configurable:!0,get:function(){function H(){return W.dom}return H}()}),W}function Se(j){return function(W){if(W.button!==0){W.stopPropagation();return}ye(W,!0,j,ve(W))}}function Pe(j){return function(W){ye(W,!1,j,ve(W))}}function je(j){var W=j==="onClick"||j==="onDblClick"?Se(j):Pe(j);return document.addEventListener(u(j),W),W}function Fe(j,W){var H=document.createElement("i");return H.innerHTML=W,H.innerHTML===j.innerHTML}function ze(j,W,H){if(j[W]){var K=j[W];K.event?K.event(K.data,H):K(H)}else{var Q=W.toLowerCase();j[Q]&&j[Q](H)}}function We(j,W){var H=function(){function K(Q){var ee=this.$V;if(ee){var oe=ee.props||c,ue=ee.dom;if(f(j))ze(oe,j,Q);else for(var ge=0;ge-1&&W.options[ee]&&(ue=W.options[ee].value),H&&a(ue)&&(ue=j.defaultValue),rt(K,ue)}}var Zt=We("onInput",Tt),qt=We("onChange");function en(j,W){Ue(j,"input",Zt),W.onChange&&Ue(j,"change",qt)}function Tt(j,W,H){var K=j.value,Q=W.value;if(a(K)){if(H){var ee=j.defaultValue;!a(ee)&&ee!==Q&&(W.defaultValue=ee,W.value=ee)}}else Q!==K&&(W.defaultValue=K,W.value=K)}function xt(j,W,H,K,Q,ee){j&64?ut(K,H):j&256?wt(K,H,Q,W):j&128&&Tt(K,H,Q),ee&&(H.$V=W)}function tn(j,W,H){j&64?Bt(W,H):j&256?Qt(W):j&128&&en(W,H)}function At(j){return j.type&&Xe(j.type)?!a(j.checked):!a(j.value)}function nn(){return{current:null}}function on(j){var W={render:j};return W}function st(j){j&&!_(j,null)&&j.current&&(j.current=null)}function at(j,W,H){j&&(o(j)||j.current!==void 0)&&H.push(function(){!_(j,W)&&j.current!==void 0&&(j.current=W)})}function Je(j,W,H){Ze(j,H),A(j,W,H)}function Ze(j,W){var H=j.flags,K=j.children,Q;if(H&481){Q=j.ref;var ee=j.props;st(Q);var oe=j.childFlags;if(!y(ee))for(var ue=Object.keys(ee),ge=0,Te=ue.length;ge0?S(H.componentWillDisappear,rn(W,j)):j.textContent=""}function pt(j,W,H,K){ct(H,K),W.flags&8192?A(W,j,K):mt(j,H,K)}function Et(j,W,H,K,Q){j.componentWillDisappear.push(function(ee){K&4?W.componentWillDisappear(H,ee):K&8&&W.onComponentWillDisappear(H,Q,ee)})}function an(j){var W=j.event;return function(H){W(j.data,H)}}function cn(j,W,H,K){if(l(H)){if(O(W,H))return;H=an(H)}Ue(K,u(j),H)}function ln(j,W,H){if(a(W)){H.removeAttribute("style");return}var K=H.style,Q,ee;if(f(W)){K.cssText=W;return}if(!a(j)&&!f(j)){for(Q in W)ee=W[Q],ee!==j[Q]&&K.setProperty(Q,ee);for(Q in j)a(W[Q])&&K.removeProperty(Q)}else for(Q in W)ee=W[Q],K.setProperty(Q,ee)}function dn(j,W,H,K,Q){var ee=j&&j.__html||"",oe=W&&W.__html||"";ee!==oe&&!a(oe)&&!Fe(K,oe)&&(y(H)||(H.childFlags&12?ct(H.children,Q):H.childFlags===2&&Ze(H.children,Q),H.children=null,H.childFlags=1),K.innerHTML=oe)}function vt(j,W,H,K,Q,ee,oe,ue){switch(j){case"children":case"childrenType":case"className":case"defaultValue":case"key":case"multiple":case"ref":case"selectedIndex":break;case"autoFocus":K.autofocus=!!H;break;case"allowfullscreen":case"autoplay":case"capture":case"checked":case"controls":case"default":case"disabled":case"hidden":case"indeterminate":case"loop":case"muted":case"novalidate":case"open":case"readOnly":case"required":case"reversed":case"scoped":case"seamless":case"selected":K[j]=!!H;break;case"defaultChecked":case"value":case"volume":if(ee&&j==="value")break;var ge=a(H)?"":H;K[j]!==ge&&(K[j]=ge);break;case"style":ln(W,H,K);break;case"dangerouslySetInnerHTML":dn(W,H,oe,K,ue);break;default:Le[j]?Re(j,W,H,K):j.charCodeAt(0)===111&&j.charCodeAt(1)===110?cn(j,W,H,K):a(H)?K.removeAttribute(j):Q&&Ce[j]?K.setAttributeNS(Ce[j],j,H):K.setAttribute(j,H);break}}function Mt(j,W,H,K,Q,ee){var oe=!1,ue=(W&448)>0;ue&&(oe=At(H),oe&&tn(W,K,H));for(var ge in H)vt(ge,null,H[ge],K,Q,oe,null,ee);ue&&xt(W,j,K,H,!0,oe)}function Pt(j,W,H){var K=pe(j.render(W,j.state,H)),Q=H;return o(j.getChildContext)&&(Q=k(H,j.getChildContext())),j.$CX=Q,K}function Ot(j,W,H,K,Q,ee){var oe=new W(H,K),ue=oe.$N=!!(W.getDerivedStateFromProps||oe.getSnapshotBeforeUpdate);if(oe.$SVG=Q,oe.$L=ee,j.children=oe,oe.$BS=!1,oe.context=K,oe.props===c&&(oe.props=H),ue)oe.state=P(oe,H,oe.state);else if(o(oe.componentWillMount)){oe.$BR=!0,oe.componentWillMount();var ge=oe.$PS;if(!y(ge)){var Te=oe.state;if(y(Te))oe.state=ge;else for(var Ie in ge)Te[Ie]=ge[Ie];oe.$PS=null}oe.$BR=!1}return oe.$LI=Pt(oe,H,K),oe}function gt(j,W){var H=j.props||c;return j.flags&32768?j.type.render(H,j.ref,W):j.type(H,W)}function Ke(j,W,H,K,Q,ee,oe){var ue=j.flags|=16384;ue&481?Dt(j,W,H,K,Q,ee,oe):ue&4?mn(j,W,H,K,Q,ee,oe):ue&8?pn(j,W,H,K,Q,ee,oe):ue&16?Rt(j,W,Q):ue&8192?sn(j,H,W,K,Q,ee,oe):ue&1024&&un(j,H,W,Q,ee,oe)}function un(j,W,H,K,Q,ee){Ke(j.children,j.ref,W,!1,null,Q,ee);var oe=le();Rt(oe,H,K),j.dom=oe.dom}function sn(j,W,H,K,Q,ee,oe){var ue=j.children,ge=j.childFlags;ge&12&&ue.length===0&&(ge=j.childFlags=2,ue=j.children=le()),ge===2?Ke(ue,H,W,K,Q,ee,oe):ot(ue,H,W,K,Q,ee,oe)}function Rt(j,W,H){var K=j.dom=document.createTextNode(j.children);y(W)||d(W,K,H)}function Dt(j,W,H,K,Q,ee,oe){var ue=j.flags,ge=j.props,Te=j.className,Ie=j.childFlags,Ee=j.dom=v(j.type,K=K||(ue&32)>0),Ae=j.children;if(!a(Te)&&Te!==""&&(K?Ee.setAttribute("class",Te):Ee.className=Te),Ie===16)R(Ee,Ae);else if(Ie!==1){var Me=K&&j.type!=="foreignObject";Ie===2?(Ae.flags&16384&&(j.children=Ae=ae(Ae)),Ke(Ae,Ee,H,Me,null,ee,oe)):(Ie===8||Ie===4)&&ot(Ae,Ee,H,Me,null,ee,oe)}y(W)||d(W,Ee,Q),y(ge)||Mt(j,ue,ge,Ee,K,oe),at(j.ref,Ee,ee)}function ot(j,W,H,K,Q,ee,oe){for(var ue=0;ueMe)&&(Ee=V(ue[Me-1],!1).nextSibling)}Nt(Te,Ie,ue,ge,H,K,Q,Ee,j,ee,oe)}function Vn(j,W,H,K,Q){var ee=j.ref,oe=W.ref,ue=W.children;if(Nt(j.childFlags,W.childFlags,j.children,ue,ee,H,!1,null,j,K,Q),W.dom=j.dom,ee!==oe&&!t(ue)){var ge=ue.dom;C(ee,ge),s(oe,ge)}}function bn(j,W,H,K,Q,ee,oe){var ue=W.dom=j.dom,ge=j.props,Te=W.props,Ie=!1,Ee=!1,Ae;if(K=K||(Q&32)>0,ge!==Te){var Me=ge||c;if(Ae=Te||c,Ae!==c){Ie=(Q&448)>0,Ie&&(Ee=At(Ae));for(var _e in Ae){var Oe=Me[_e],$e=Ae[_e];Oe!==$e&&vt(_e,Oe,$e,ue,K,Ee,j,oe)}}if(Me!==c)for(var De in Me)a(Ae[De])&&!a(Me[De])&&vt(De,Me[De],null,ue,K,Ee,j,oe)}var tt=W.children,Ye=W.className;j.className!==Ye&&(a(Ye)?ue.removeAttribute("class"):K?ue.setAttribute("class",Ye):ue.className=Ye),Q&4096?gn(ue,tt):Nt(j.childFlags,W.childFlags,j.children,tt,ue,H,K&&W.type!=="foreignObject",null,j,ee,oe),Ie&&xt(Q,W,ue,Ae,!1,Ee);var it=W.ref,Qe=j.ref;Qe!==it&&(st(Qe),at(it,ue,ee))}function kn(j,W,H,K,Q,ee,oe){Ze(j,oe),ot(W,H,K,Q,V(j,!0),ee,oe),A(j,H,oe)}function Nt(j,W,H,K,Q,ee,oe,ue,ge,Te,Ie){switch(j){case 2:switch(W){case 2:qe(H,K,Q,ee,oe,ue,Te,Ie);break;case 1:Je(H,Q,Ie);break;case 16:Ze(H,Ie),R(Q,K);break;default:kn(H,K,Q,ee,oe,Te,Ie);break}break;case 1:switch(W){case 2:Ke(K,Q,ee,oe,ue,Te,Ie);break;case 1:break;case 16:R(Q,K);break;default:ot(K,Q,ee,oe,ue,Te,Ie);break}break;case 16:switch(W){case 16:vn(H,K,Q);break;case 2:mt(Q,H,Ie),Ke(K,Q,ee,oe,ue,Te,Ie);break;case 1:mt(Q,H,Ie);break;default:mt(Q,H,Ie),ot(K,Q,ee,oe,ue,Te,Ie);break}break;default:switch(W){case 16:ct(H,Ie),R(Q,K);break;case 2:pt(Q,ge,H,Ie),Ke(K,Q,ee,oe,ue,Te,Ie);break;case 1:pt(Q,ge,H,Ie);break;default:var Ee=H.length|0,Ae=K.length|0;Ee===0?Ae>0&&ot(K,Q,ee,oe,ue,Te,Ie):Ae===0?pt(Q,ge,H,Ie):W===8&&j===8?wn(H,K,Q,ee,oe,Ee,Ae,ue,ge,Te,Ie):Ln(H,K,Q,ee,oe,Ee,Ae,ue,Te,Ie);break}break}}function yn(j,W,H,K,Q){Q.push(function(){j.componentDidUpdate(W,H,K)})}function Wt(j,W,H,K,Q,ee,oe,ue,ge,Te){var Ie=j.state,Ee=j.props,Ae=!!j.$N,Me=o(j.shouldComponentUpdate);if(Ae&&(W=P(j,H,W!==Ie?k(Ie,W):W)),oe||!Me||Me&&j.shouldComponentUpdate(H,W,Q)){!Ae&&o(j.componentWillUpdate)&&j.componentWillUpdate(H,W,Q),j.props=H,j.state=W,j.context=Q;var _e=null,Oe=Pt(j,H,Q);Ae&&o(j.getSnapshotBeforeUpdate)&&(_e=j.getSnapshotBeforeUpdate(Ee,Ie)),qe(j.$LI,Oe,K,j.$CX,ee,ue,ge,Te),j.$LI=Oe,o(j.componentDidUpdate)&&yn(j,Ee,Ie,_e,ge)}else j.props=H,j.state=W,j.context=Q}function Sn(j,W,H,K,Q,ee,oe,ue){var ge=W.children=j.children;if(!y(ge)){ge.$L=oe;var Te=W.props||c,Ie=W.ref,Ee=j.ref,Ae=ge.state;if(!ge.$N){if(o(ge.componentWillReceiveProps)){if(ge.$BR=!0,ge.componentWillReceiveProps(Te,K),ge.$UN)return;ge.$BR=!1}y(ge.$PS)||(Ae=k(Ae,ge.$PS),ge.$PS=null)}Wt(ge,Ae,Te,H,K,Q,!1,ee,oe,ue),Ee!==Ie&&(st(Ee),at(Ie,ge,oe))}}function Bn(j,W,H,K,Q,ee,oe,ue){var ge=!0,Te=W.props||c,Ie=W.ref,Ee=j.props,Ae=!a(Ie),Me=j.children;if(Ae&&o(Ie.onComponentShouldUpdate)&&(ge=Ie.onComponentShouldUpdate(Ee,Te)),ge!==!1){Ae&&o(Ie.onComponentWillUpdate)&&Ie.onComponentWillUpdate(Ee,Te);var _e=pe(gt(W,K));qe(Me,_e,H,K,Q,ee,oe,ue),W.children=_e,Ae&&o(Ie.onComponentDidUpdate)&&Ie.onComponentDidUpdate(Ee,Te)}else W.children=Me}function In(j,W){var H=W.children,K=W.dom=j.dom;H!==j.children&&(K.nodeValue=H)}function Ln(j,W,H,K,Q,ee,oe,ue,ge,Te){for(var Ie=ee>oe?oe:ee,Ee=0,Ae,Me;Eeoe)for(Ee=Ie;EeEe||Me>Ae)break e;_e=j[Me],Oe=W[Me]}for(_e=j[Ee],Oe=W[Ae];_e.key===Oe.key;){if(Oe.flags&16384&&(W[Ae]=Oe=ae(Oe)),qe(_e,Oe,H,K,Q,ue,Te,Ie),j[Ee]=Oe,Ee--,Ae--,Me>Ee||Me>Ae)break e;_e=j[Ee],Oe=W[Ae]}}if(Me>Ee){if(Me<=Ae)for($e=Ae+1,De=$eAe)for(;Me<=Ee;)Je(j[Me++],H,Ie);else Tn(j,W,K,ee,oe,Ee,Ae,Me,H,Q,ue,ge,Te,Ie)}function Tn(j,W,H,K,Q,ee,oe,ue,ge,Te,Ie,Ee,Ae,Me){var _e,Oe,$e=0,De=0,tt=ue,Ye=ue,it=ee-ue+1,Qe=oe-ue+1,lt=new Int32Array(Qe+1),nt=it===K,bt=!1,Ge=0,dt=0;if(Q<4||(it|Qe)<32)for(De=tt;De<=ee;++De)if(_e=j[De],dtue?bt=!0:Ge=ue,Oe.flags&16384&&(W[ue]=Oe=ae(Oe)),qe(_e,Oe,ge,H,Te,Ie,Ae,Me),++dt;break}!nt&&ue>oe&&Je(_e,ge,Me)}else nt||Je(_e,ge,Me);else{var Yt={};for(De=Ye;De<=oe;++De)Yt[W[De].key]=De;for(De=tt;De<=ee;++De)if(_e=j[De],dttt;)Je(j[tt++],ge,Me);lt[ue-Ye]=De+1,Ge>ue?bt=!0:Ge=ue,Oe=W[ue],Oe.flags&16384&&(W[ue]=Oe=ae(Oe)),qe(_e,Oe,ge,H,Te,Ie,Ae,Me),++dt}else nt||Je(_e,ge,Me);else nt||Je(_e,ge,Me)}if(nt)pt(ge,Ee,j,Me),ot(W,ge,H,Te,Ie,Ae,Me);else if(bt){var Xt=xn(lt);for(ue=Xt.length-1,De=Qe-1;De>=0;De--)lt[De]===0?(Ge=De+Ye,Oe=W[Ge],Oe.flags&16384&&(W[Ge]=Oe=ae(Oe)),$e=Ge+1,Ke(Oe,ge,H,Te,$e0&&B(Me.componentWillMove)}else if(dt!==Qe)for(De=Qe-1;De>=0;De--)lt[De]===0&&(Ge=De+Ye,Oe=W[Ge],Oe.flags&16384&&(W[Ge]=Oe=ae(Oe)),$e=Ge+1,Ke(Oe,ge,H,Te,$eUt&&(Ut=ge,et=new Int32Array(ge),ft=new Int32Array(ge));H>1,j[et[ue]]0&&(ft[H]=et[ee-1]),et[ee]=H)}ee=Q+1;var Te=new Int32Array(ee);for(oe=et[ee-1];ee-- >0;)Te[ee]=oe,oe=ft[oe],et[ee]=0;return Te}var An=typeof document!="undefined";An&&window.Node&&(Node.prototype.$EV=null,Node.prototype.$V=null);function Ht(j,W,H,K){var Q=[],ee=new i,oe=W.$V;D.v=!0,a(oe)?a(j)||(j.flags&16384&&(j=ae(j)),Ke(j,W,K,!1,null,Q,ee),W.$V=j,oe=j):a(j)?(Je(oe,W,ee),W.$V=null):(j.flags&16384&&(j=ae(j)),qe(oe,j,W,K,!1,null,Q,ee),oe=W.$V=j),p(Q),S(ee.componentDidAppear),D.v=!1,o(H)&&H(),o(M.renderComplete)&&M.renderComplete(oe,W)}function zt(j,W,H,K){H===void 0&&(H=null),K===void 0&&(K=c),Ht(j,W,H,K)}function En(j){return function(){function W(H,K,Q,ee){j||(j=H),zt(K,j,Q,ee)}return W}()}var ht=[],Mn=typeof Promise!="undefined"?Promise.resolve().then.bind(Promise.resolve()):function(j){window.setTimeout(j,0)},Vt=!1;function Kt(j,W,H,K){var Q=j.$PS;if(o(W)&&(W=W(Q?k(j.state,Q):j.state,j.props,j.context)),a(Q))j.$PS=W;else for(var ee in W)Q[ee]=W[ee];if(j.$BR)o(H)&&j.$L.push(H.bind(j));else{if(!D.v&&ht.length===0){Gt(j,K),o(H)&&H.call(j);return}if(ht.indexOf(j)===-1&&ht.push(j),K&&(j.$F=!0),Vt||(Vt=!0,Mn($t)),o(H)){var oe=j.$QU;oe||(oe=j.$QU=[]),oe.push(H)}}}function Pn(j){for(var W=j.$QU,H=0;H=0;--_){var U=this.tryEntries[_],z=U.completion;if(U.tryLoc==="root")return F("end");if(U.tryLoc<=this.prev){var $=a.call(U,"catchLoc"),G=a.call(U,"finallyLoc");if($&&G){if(this.prev=0;--F){var _=this.tryEntries[F];if(_.tryLoc<=this.prev&&a.call(_,"finallyLoc")&&this.prev<_.finallyLoc){var U=_;break}}U&&(R==="break"||R==="continue")&&U.tryLoc<=O&&O<=U.finallyLoc&&(U=null);var z=U?U.completion:{};return z.type=R,z.arg=O,U?(this.method="next",this.next=U.finallyLoc,s):this.complete(z)}return M}(),complete:function(){function M(R,O){if(R.type==="throw")throw R.arg;return R.type==="break"||R.type==="continue"?this.next=R.arg:R.type==="return"?(this.rval=this.arg=R.arg,this.method="return",this.next="end"):R.type==="normal"&&O&&(this.next=O),s}return M}(),finish:function(){function M(R){for(var O=this.tryEntries.length-1;O>=0;--O){var F=this.tryEntries[O];if(F.finallyLoc===R)return this.complete(F.completion,F.afterLoc),x(F),s}}return M}(),catch:function(){function M(R){for(var O=this.tryEntries.length-1;O>=0;--O){var F=this.tryEntries[O];if(F.tryLoc===R){var _=F.completion;if(_.type==="throw"){var U=_.arg;x(F)}return U}}throw new Error("illegal catch attempt")}return M}(),delegateYield:function(){function M(R,O,F){return this.delegate={iterator:P(R),resultName:O,nextLoc:F},this.method==="next"&&(this.arg=o),s}return M}()},n}(T.exports);try{regeneratorRuntime=r}catch(n){typeof globalThis=="object"?globalThis.regeneratorRuntime=r:Function("r","regeneratorRuntime = r")(r)}},30236:function(){"use strict";self.fetch||(self.fetch=function(T,r){return r=r||{},new Promise(function(n,e){var a=new XMLHttpRequest,t=[],o={},f=function(){function y(){return{ok:(a.status/100|0)==2,statusText:a.statusText,status:a.status,url:a.responseURL,text:function(){function I(){return Promise.resolve(a.responseText)}return I}(),json:function(){function I(){return Promise.resolve(a.responseText).then(JSON.parse)}return I}(),blob:function(){function I(){return Promise.resolve(new Blob([a.response]))}return I}(),clone:y,headers:{keys:function(){function I(){return t}return I}(),entries:function(){function I(){return t.map(function(k){return[k,a.getResponseHeader(k)]})}return I}(),get:function(){function I(k){return a.getResponseHeader(k)}return I}(),has:function(){function I(k){return a.getResponseHeader(k)!=null}return I}()}}}return y}();for(var b in a.open(r.method||"get",T,!0),a.onload=function(){a.getAllResponseHeaders().toLowerCase().replace(/^(.+?):/gm,function(y,I){o[I]||t.push(o[I]=I)}),n(f())},a.onerror=e,a.withCredentials=r.credentials=="include",r.headers)a.setRequestHeader(b,r.headers[b]);a.send(r.body||null)})})},88510:function(T,r){"use strict";r.__esModule=!0,r.zipWith=r.zip=r.uniqBy=r.uniq=r.toKeyedArray=r.toArray=r.sortBy=r.sort=r.reduce=r.range=r.map=r.filterMap=r.filter=void 0;function n(d,v){var h=typeof Symbol!="undefined"&&d[Symbol.iterator]||d["@@iterator"];if(h)return(h=h.call(d)).next.bind(h);if(Array.isArray(d)||(h=e(d))||v&&d&&typeof d.length=="number"){h&&(d=h);var C=0;return function(){return C>=d.length?{done:!0}:{done:!1,value:d[C++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function e(d,v){if(d){if(typeof d=="string")return a(d,v);var h={}.toString.call(d).slice(8,-1);return h==="Object"&&d.constructor&&(h=d.constructor.name),h==="Map"||h==="Set"?Array.from(d):h==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(h)?a(d,v):void 0}}function a(d,v){(v==null||v>d.length)&&(v=d.length);for(var h=0,C=Array(v);h1?I-1:0),g=1;g1?k-1:0),l=1;l0&&(0,a.round)(h.width)/y.offsetWidth||1,c=y.offsetHeight>0&&(0,a.round)(h.height)/y.offsetHeight||1);var m=(0,e.isElement)(y)?(0,t.default)(y):window,l=m.visualViewport,u=!(0,o.default)()&&k,s=(h.left+(u&&l?l.offsetLeft:0))/i,d=(h.top+(u&&l?l.offsetTop:0))/c,v=h.width/i,g=h.height/c;return{width:v,height:g,top:d,right:s+v,bottom:d+g,left:s,x:s,y:d}}},49035:function(T,r,n){"use strict";r.__esModule=!0,r.default=g;var e=n(46206),a=u(n(87991)),t=u(n(79752)),o=u(n(98309)),p=u(n(44896)),b=u(n(40600)),y=u(n(16599)),S=n(75573),k=u(n(37786)),h=u(n(57819)),i=u(n(4206)),c=u(n(12972)),m=u(n(81666)),l=n(63618);function u(C){return C&&C.__esModule?C:{default:C}}function s(C,f){var N=(0,k.default)(C,!1,f==="fixed");return N.top=N.top+C.clientTop,N.left=N.left+C.clientLeft,N.bottom=N.top+C.clientHeight,N.right=N.left+C.clientWidth,N.width=C.clientWidth,N.height=C.clientHeight,N.x=N.left,N.y=N.top,N}function d(C,f,N){return f===e.viewport?(0,m.default)((0,a.default)(C,N)):(0,S.isElement)(f)?s(f,N):(0,m.default)((0,t.default)((0,b.default)(C)))}function v(C){var f=(0,o.default)((0,h.default)(C)),N=["absolute","fixed"].indexOf((0,y.default)(C).position)>=0,V=N&&(0,S.isHTMLElement)(C)?(0,p.default)(C):C;return(0,S.isElement)(V)?f.filter(function(B){return(0,S.isElement)(B)&&(0,i.default)(B,V)&&(0,c.default)(B)!=="body"}):[]}function g(C,f,N,V){var B=f==="clippingParents"?v(C):[].concat(f),I=[].concat(B,[N]),L=I[0],w=I.reduce(function(A,x){var E=d(C,x,V);return A.top=(0,l.max)(E.top,A.top),A.right=(0,l.min)(E.right,A.right),A.bottom=(0,l.min)(E.bottom,A.bottom),A.left=(0,l.max)(E.left,A.left),A},d(C,L,V));return w.width=w.right-w.left,w.height=w.bottom-w.top,w.x=w.left,w.y=w.top,w}},74758:function(T,r,n){"use strict";r.__esModule=!0,r.default=i;var e=k(n(37786)),a=k(n(13390)),t=k(n(12972)),o=n(75573),p=k(n(79697)),b=k(n(40600)),y=k(n(10798)),S=n(63618);function k(c){return c&&c.__esModule?c:{default:c}}function h(c){var m=c.getBoundingClientRect(),l=(0,S.round)(m.width)/c.offsetWidth||1,u=(0,S.round)(m.height)/c.offsetHeight||1;return l!==1||u!==1}function i(c,m,l){l===void 0&&(l=!1);var u=(0,o.isHTMLElement)(m),s=(0,o.isHTMLElement)(m)&&h(m),d=(0,b.default)(m),v=(0,e.default)(c,s,l),g={scrollLeft:0,scrollTop:0},C={x:0,y:0};return(u||!u&&!l)&&(((0,t.default)(m)!=="body"||(0,y.default)(d))&&(g=(0,a.default)(m)),(0,o.isHTMLElement)(m)?(C=(0,e.default)(m,!0),C.x+=m.clientLeft,C.y+=m.clientTop):d&&(C.x=(0,p.default)(d))),{x:v.left+g.scrollLeft-C.x,y:v.top+g.scrollTop-C.y,width:v.width,height:v.height}}},16599:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(95115));function a(o){return o&&o.__esModule?o:{default:o}}function t(o){return(0,e.default)(o).getComputedStyle(o)}},40600:function(T,r,n){"use strict";r.__esModule=!0,r.default=a;var e=n(75573);function a(t){return(((0,e.isElement)(t)?t.ownerDocument:t.document)||window.document).documentElement}},79752:function(T,r,n){"use strict";r.__esModule=!0,r.default=y;var e=b(n(40600)),a=b(n(16599)),t=b(n(79697)),o=b(n(43750)),p=n(63618);function b(S){return S&&S.__esModule?S:{default:S}}function y(S){var k,h=(0,e.default)(S),i=(0,o.default)(S),c=(k=S.ownerDocument)==null?void 0:k.body,m=(0,p.max)(h.scrollWidth,h.clientWidth,c?c.scrollWidth:0,c?c.clientWidth:0),l=(0,p.max)(h.scrollHeight,h.clientHeight,c?c.scrollHeight:0,c?c.clientHeight:0),u=-i.scrollLeft+(0,t.default)(S),s=-i.scrollTop;return(0,a.default)(c||h).direction==="rtl"&&(u+=(0,p.max)(h.clientWidth,c?c.clientWidth:0)-m),{width:m,height:l,x:u,y:s}}},3073:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){return{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}}},28811:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(37786));function a(o){return o&&o.__esModule?o:{default:o}}function t(o){var p=(0,e.default)(o),b=o.offsetWidth,y=o.offsetHeight;return Math.abs(p.width-b)<=1&&(b=p.width),Math.abs(p.height-y)<=1&&(y=p.height),{x:o.offsetLeft,y:o.offsetTop,width:b,height:y}}},12972:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){return e?(e.nodeName||"").toLowerCase():null}},13390:function(T,r,n){"use strict";r.__esModule=!0,r.default=b;var e=p(n(43750)),a=p(n(95115)),t=n(75573),o=p(n(3073));function p(y){return y&&y.__esModule?y:{default:y}}function b(y){return y===(0,a.default)(y)||!(0,t.isHTMLElement)(y)?(0,e.default)(y):(0,o.default)(y)}},44896:function(T,r,n){"use strict";r.__esModule=!0,r.default=i;var e=S(n(95115)),a=S(n(12972)),t=S(n(16599)),o=n(75573),p=S(n(87031)),b=S(n(57819)),y=S(n(35366));function S(c){return c&&c.__esModule?c:{default:c}}function k(c){return!(0,o.isHTMLElement)(c)||(0,t.default)(c).position==="fixed"?null:c.offsetParent}function h(c){var m=/firefox/i.test((0,y.default)()),l=/Trident/i.test((0,y.default)());if(l&&(0,o.isHTMLElement)(c)){var u=(0,t.default)(c);if(u.position==="fixed")return null}var s=(0,b.default)(c);for((0,o.isShadowRoot)(s)&&(s=s.host);(0,o.isHTMLElement)(s)&&["html","body"].indexOf((0,a.default)(s))<0;){var d=(0,t.default)(s);if(d.transform!=="none"||d.perspective!=="none"||d.contain==="paint"||["transform","perspective"].indexOf(d.willChange)!==-1||m&&d.willChange==="filter"||m&&d.filter&&d.filter!=="none")return s;s=s.parentNode}return null}function i(c){for(var m=(0,e.default)(c),l=k(c);l&&(0,p.default)(l)&&(0,t.default)(l).position==="static";)l=k(l);return l&&((0,a.default)(l)==="html"||(0,a.default)(l)==="body"&&(0,t.default)(l).position==="static")?m:l||h(c)||m}},57819:function(T,r,n){"use strict";r.__esModule=!0,r.default=p;var e=o(n(12972)),a=o(n(40600)),t=n(75573);function o(b){return b&&b.__esModule?b:{default:b}}function p(b){return(0,e.default)(b)==="html"?b:b.assignedSlot||b.parentNode||((0,t.isShadowRoot)(b)?b.host:null)||(0,a.default)(b)}},24426:function(T,r,n){"use strict";r.__esModule=!0,r.default=b;var e=p(n(57819)),a=p(n(10798)),t=p(n(12972)),o=n(75573);function p(y){return y&&y.__esModule?y:{default:y}}function b(y){return["html","body","#document"].indexOf((0,t.default)(y))>=0?y.ownerDocument.body:(0,o.isHTMLElement)(y)&&(0,a.default)(y)?y:b((0,e.default)(y))}},87991:function(T,r,n){"use strict";r.__esModule=!0,r.default=b;var e=p(n(95115)),a=p(n(40600)),t=p(n(79697)),o=p(n(89331));function p(y){return y&&y.__esModule?y:{default:y}}function b(y,S){var k=(0,e.default)(y),h=(0,a.default)(y),i=k.visualViewport,c=h.clientWidth,m=h.clientHeight,l=0,u=0;if(i){c=i.width,m=i.height;var s=(0,o.default)();(s||!s&&S==="fixed")&&(l=i.offsetLeft,u=i.offsetTop)}return{width:c,height:m,x:l+(0,t.default)(y),y:u}}},95115:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){if(e==null)return window;if(e.toString()!=="[object Window]"){var a=e.ownerDocument;return a&&a.defaultView||window}return e}},43750:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(95115));function a(o){return o&&o.__esModule?o:{default:o}}function t(o){var p=(0,e.default)(o),b=p.pageXOffset,y=p.pageYOffset;return{scrollLeft:b,scrollTop:y}}},79697:function(T,r,n){"use strict";r.__esModule=!0,r.default=p;var e=o(n(37786)),a=o(n(40600)),t=o(n(43750));function o(b){return b&&b.__esModule?b:{default:b}}function p(b){return(0,e.default)((0,a.default)(b)).left+(0,t.default)(b).scrollLeft}},75573:function(T,r,n){"use strict";r.__esModule=!0,r.isElement=t,r.isHTMLElement=o,r.isShadowRoot=p;var e=a(n(95115));function a(b){return b&&b.__esModule?b:{default:b}}function t(b){var y=(0,e.default)(b).Element;return b instanceof y||b instanceof Element}function o(b){var y=(0,e.default)(b).HTMLElement;return b instanceof y||b instanceof HTMLElement}function p(b){if(typeof ShadowRoot=="undefined")return!1;var y=(0,e.default)(b).ShadowRoot;return b instanceof y||b instanceof ShadowRoot}},89331:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(35366));function a(o){return o&&o.__esModule?o:{default:o}}function t(){return!/^((?!chrome|android).)*safari/i.test((0,e.default)())}},10798:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(16599));function a(o){return o&&o.__esModule?o:{default:o}}function t(o){var p=(0,e.default)(o),b=p.overflow,y=p.overflowX,S=p.overflowY;return/auto|scroll|overlay|hidden/.test(b+S+y)}},87031:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(12972));function a(o){return o&&o.__esModule?o:{default:o}}function t(o){return["table","td","th"].indexOf((0,e.default)(o))>=0}},98309:function(T,r,n){"use strict";r.__esModule=!0,r.default=b;var e=p(n(24426)),a=p(n(57819)),t=p(n(95115)),o=p(n(10798));function p(y){return y&&y.__esModule?y:{default:y}}function b(y,S){var k;S===void 0&&(S=[]);var h=(0,e.default)(y),i=h===((k=y.ownerDocument)==null?void 0:k.body),c=(0,t.default)(h),m=i?[c].concat(c.visualViewport||[],(0,o.default)(h)?h:[]):h,l=S.concat(m);return i?l:l.concat(b((0,a.default)(m)))}},46206:function(T,r){"use strict";r.__esModule=!0,r.write=r.viewport=r.variationPlacements=r.top=r.start=r.right=r.reference=r.read=r.popper=r.placements=r.modifierPhases=r.main=r.left=r.end=r.clippingParents=r.bottom=r.beforeWrite=r.beforeRead=r.beforeMain=r.basePlacements=r.auto=r.afterWrite=r.afterRead=r.afterMain=void 0;var n=r.top="top",e=r.bottom="bottom",a=r.right="right",t=r.left="left",o=r.auto="auto",p=r.basePlacements=[n,e,a,t],b=r.start="start",y=r.end="end",S=r.clippingParents="clippingParents",k=r.viewport="viewport",h=r.popper="popper",i=r.reference="reference",c=r.variationPlacements=p.reduce(function(B,I){return B.concat([I+"-"+b,I+"-"+y])},[]),m=r.placements=[].concat(p,[o]).reduce(function(B,I){return B.concat([I,I+"-"+b,I+"-"+y])},[]),l=r.beforeRead="beforeRead",u=r.read="read",s=r.afterRead="afterRead",d=r.beforeMain="beforeMain",v=r.main="main",g=r.afterMain="afterMain",C=r.beforeWrite="beforeWrite",f=r.write="write",N=r.afterWrite="afterWrite",V=r.modifierPhases=[l,u,s,d,v,g,C,f,N]},95996:function(T,r,n){"use strict";r.__esModule=!0;var e={popperGenerator:!0,detectOverflow:!0,createPopperBase:!0,createPopper:!0,createPopperLite:!0};r.popperGenerator=r.detectOverflow=r.createPopperLite=r.createPopperBase=r.createPopper=void 0;var a=n(46206);Object.keys(a).forEach(function(y){y==="default"||y==="__esModule"||Object.prototype.hasOwnProperty.call(e,y)||y in r&&r[y]===a[y]||(r[y]=a[y])});var t=n(39805);Object.keys(t).forEach(function(y){y==="default"||y==="__esModule"||Object.prototype.hasOwnProperty.call(e,y)||y in r&&r[y]===t[y]||(r[y]=t[y])});var o=n(96376);r.popperGenerator=o.popperGenerator,r.detectOverflow=o.detectOverflow,r.createPopperBase=o.createPopper;var p=n(83312);r.createPopper=p.createPopper;var b=n(2473);r.createPopperLite=b.createPopper},19975:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=t(n(12972)),a=n(75573);function t(y){return y&&y.__esModule?y:{default:y}}function o(y){var S=y.state;Object.keys(S.elements).forEach(function(k){var h=S.styles[k]||{},i=S.attributes[k]||{},c=S.elements[k];!(0,a.isHTMLElement)(c)||!(0,e.default)(c)||(Object.assign(c.style,h),Object.keys(i).forEach(function(m){var l=i[m];l===!1?c.removeAttribute(m):c.setAttribute(m,l===!0?"":l)}))})}function p(y){var S=y.state,k={popper:{position:S.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(S.elements.popper.style,k.popper),S.styles=k,S.elements.arrow&&Object.assign(S.elements.arrow.style,k.arrow),function(){Object.keys(S.elements).forEach(function(h){var i=S.elements[h],c=S.attributes[h]||{},m=Object.keys(S.styles.hasOwnProperty(h)?S.styles[h]:k[h]),l=m.reduce(function(u,s){return u[s]="",u},{});!(0,a.isHTMLElement)(i)||!(0,e.default)(i)||(Object.assign(i.style,l),Object.keys(c).forEach(function(u){i.removeAttribute(u)}))})}}var b=r.default={name:"applyStyles",enabled:!0,phase:"write",fn:o,effect:p,requires:["computeStyles"]}},52744:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=h(n(83104)),a=h(n(28811)),t=h(n(4206)),o=h(n(44896)),p=h(n(41199)),b=n(28595),y=h(n(43286)),S=h(n(81447)),k=n(46206);function h(u){return u&&u.__esModule?u:{default:u}}var i=function(){function u(s,d){return s=typeof s=="function"?s(Object.assign({},d.rects,{placement:d.placement})):s,(0,y.default)(typeof s!="number"?s:(0,S.default)(s,k.basePlacements))}return u}();function c(u){var s,d=u.state,v=u.name,g=u.options,C=d.elements.arrow,f=d.modifiersData.popperOffsets,N=(0,e.default)(d.placement),V=(0,p.default)(N),B=[k.left,k.right].indexOf(N)>=0,I=B?"height":"width";if(!(!C||!f)){var L=i(g.padding,d),w=(0,a.default)(C),A=V==="y"?k.top:k.left,x=V==="y"?k.bottom:k.right,E=d.rects.reference[I]+d.rects.reference[V]-f[V]-d.rects.popper[I],P=f[V]-d.rects.reference[V],D=(0,o.default)(C),M=D?V==="y"?D.clientHeight||0:D.clientWidth||0:0,O=E/2-P/2,R=L[A],F=M-w[I]-L[x],W=M/2-w[I]/2+O,U=(0,b.within)(R,W,F),z=V;d.modifiersData[v]=(s={},s[z]=U,s.centerOffset=U-W,s)}}function m(u){var s=u.state,d=u.options,v=d.element,g=v===void 0?"[data-popper-arrow]":v;g!=null&&(typeof g=="string"&&(g=s.elements.popper.querySelector(g),!g)||(0,t.default)(s.elements.popper,g)&&(s.elements.arrow=g))}var l=r.default={name:"arrow",enabled:!0,phase:"main",fn:c,effect:m,requires:["popperOffsets"],requiresIfExists:["preventOverflow"]}},59894:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0,r.mapToStyles=c;var e=n(46206),a=k(n(44896)),t=k(n(95115)),o=k(n(40600)),p=k(n(16599)),b=k(n(83104)),y=k(n(45)),S=n(63618);function k(u){return u&&u.__esModule?u:{default:u}}var h={top:"auto",right:"auto",bottom:"auto",left:"auto"};function i(u,s){var d=u.x,v=u.y,g=s.devicePixelRatio||1;return{x:(0,S.round)(d*g)/g||0,y:(0,S.round)(v*g)/g||0}}function c(u){var s,d=u.popper,v=u.popperRect,g=u.placement,C=u.variation,f=u.offsets,N=u.position,V=u.gpuAcceleration,B=u.adaptive,I=u.roundOffsets,L=u.isFixed,w=f.x,A=w===void 0?0:w,x=f.y,E=x===void 0?0:x,P=typeof I=="function"?I({x:A,y:E}):{x:A,y:E};A=P.x,E=P.y;var D=f.hasOwnProperty("x"),M=f.hasOwnProperty("y"),O=e.left,R=e.top,F=window;if(B){var W=(0,a.default)(d),U="clientHeight",z="clientWidth";if(W===(0,t.default)(d)&&(W=(0,o.default)(d),(0,p.default)(W).position!=="static"&&N==="absolute"&&(U="scrollHeight",z="scrollWidth")),W=W,g===e.top||(g===e.left||g===e.right)&&C===e.end){R=e.bottom;var $=L&&W===F&&F.visualViewport?F.visualViewport.height:W[U];E-=$-v.height,E*=V?1:-1}if(g===e.left||(g===e.top||g===e.bottom)&&C===e.end){O=e.right;var G=L&&W===F&&F.visualViewport?F.visualViewport.width:W[z];A-=G-v.width,A*=V?1:-1}}var X=Object.assign({position:N},B&&h),J=I===!0?i({x:A,y:E},(0,t.default)(d)):{x:A,y:E};if(A=J.x,E=J.y,V){var se;return Object.assign({},X,(se={},se[R]=M?"0":"",se[O]=D?"0":"",se.transform=(F.devicePixelRatio||1)<=1?"translate("+A+"px, "+E+"px)":"translate3d("+A+"px, "+E+"px, 0)",se))}return Object.assign({},X,(s={},s[R]=M?E+"px":"",s[O]=D?A+"px":"",s.transform="",s))}function m(u){var s=u.state,d=u.options,v=d.gpuAcceleration,g=v===void 0?!0:v,C=d.adaptive,f=C===void 0?!0:C,N=d.roundOffsets,V=N===void 0?!0:N,B={placement:(0,b.default)(s.placement),variation:(0,y.default)(s.placement),popper:s.elements.popper,popperRect:s.rects.popper,gpuAcceleration:g,isFixed:s.options.strategy==="fixed"};s.modifiersData.popperOffsets!=null&&(s.styles.popper=Object.assign({},s.styles.popper,c(Object.assign({},B,{offsets:s.modifiersData.popperOffsets,position:s.options.strategy,adaptive:f,roundOffsets:V})))),s.modifiersData.arrow!=null&&(s.styles.arrow=Object.assign({},s.styles.arrow,c(Object.assign({},B,{offsets:s.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:V})))),s.attributes.popper=Object.assign({},s.attributes.popper,{"data-popper-placement":s.placement})}var l=r.default={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:m,data:{}}},36692:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=a(n(95115));function a(b){return b&&b.__esModule?b:{default:b}}var t={passive:!0};function o(b){var y=b.state,S=b.instance,k=b.options,h=k.scroll,i=h===void 0?!0:h,c=k.resize,m=c===void 0?!0:c,l=(0,e.default)(y.elements.popper),u=[].concat(y.scrollParents.reference,y.scrollParents.popper);return i&&u.forEach(function(s){s.addEventListener("scroll",S.update,t)}),m&&l.addEventListener("resize",S.update,t),function(){i&&u.forEach(function(s){s.removeEventListener("scroll",S.update,t)}),m&&l.removeEventListener("resize",S.update,t)}}var p=r.default={name:"eventListeners",enabled:!0,phase:"write",fn:function(){function b(){}return b}(),effect:o,data:{}}},23798:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=S(n(71376)),a=S(n(83104)),t=S(n(86459)),o=S(n(17633)),p=S(n(9041)),b=n(46206),y=S(n(45));function S(c){return c&&c.__esModule?c:{default:c}}function k(c){if((0,a.default)(c)===b.auto)return[];var m=(0,e.default)(c);return[(0,t.default)(c),m,(0,t.default)(m)]}function h(c){var m=c.state,l=c.options,u=c.name;if(!m.modifiersData[u]._skip){for(var s=l.mainAxis,d=s===void 0?!0:s,v=l.altAxis,g=v===void 0?!0:v,C=l.fallbackPlacements,f=l.padding,N=l.boundary,V=l.rootBoundary,B=l.altBoundary,I=l.flipVariations,L=I===void 0?!0:I,w=l.allowedAutoPlacements,A=m.options.placement,x=(0,a.default)(A),E=x===A,P=C||(E||!L?[(0,e.default)(A)]:k(A)),D=[A].concat(P).reduce(function(ne,te){return ne.concat((0,a.default)(te)===b.auto?(0,p.default)(m,{placement:te,boundary:N,rootBoundary:V,padding:f,flipVariations:L,allowedAutoPlacements:w}):te)},[]),M=m.rects.reference,O=m.rects.popper,R=new Map,F=!0,W=D[0],U=0;U=0,J=X?"width":"height",se=(0,o.default)(m,{placement:z,boundary:N,rootBoundary:V,altBoundary:B,padding:f}),ie=X?G?b.right:b.left:G?b.bottom:b.top;M[J]>O[J]&&(ie=(0,e.default)(ie));var me=(0,e.default)(ie),q=[];if(d&&q.push(se[$]<=0),g&&q.push(se[ie]<=0,se[me]<=0),q.every(function(ne){return ne})){W=z,F=!1;break}R.set(z,q)}if(F)for(var re=L?3:1,ae=function(){function ne(te){var fe=D.find(function(pe){var ce=R.get(pe);if(ce)return ce.slice(0,te).every(function(Ve){return Ve})});if(fe)return W=fe,"break"}return ne}(),le=re;le>0;le--){var Z=ae(le);if(Z==="break")break}m.placement!==W&&(m.modifiersData[u]._skip=!0,m.placement=W,m.reset=!0)}}var i=r.default={name:"flip",enabled:!0,phase:"main",fn:h,requiresIfExists:["offset"],data:{_skip:!1}}},83761:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=n(46206),a=t(n(17633));function t(S){return S&&S.__esModule?S:{default:S}}function o(S,k,h){return h===void 0&&(h={x:0,y:0}),{top:S.top-k.height-h.y,right:S.right-k.width+h.x,bottom:S.bottom-k.height+h.y,left:S.left-k.width-h.x}}function p(S){return[e.top,e.right,e.bottom,e.left].some(function(k){return S[k]>=0})}function b(S){var k=S.state,h=S.name,i=k.rects.reference,c=k.rects.popper,m=k.modifiersData.preventOverflow,l=(0,a.default)(k,{elementContext:"reference"}),u=(0,a.default)(k,{altBoundary:!0}),s=o(l,i),d=o(u,c,m),v=p(s),g=p(d);k.modifiersData[h]={referenceClippingOffsets:s,popperEscapeOffsets:d,isReferenceHidden:v,hasPopperEscaped:g},k.attributes.popper=Object.assign({},k.attributes.popper,{"data-popper-reference-hidden":v,"data-popper-escaped":g})}var y=r.default={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:b}},39805:function(T,r,n){"use strict";r.__esModule=!0,r.preventOverflow=r.popperOffsets=r.offset=r.hide=r.flip=r.eventListeners=r.computeStyles=r.arrow=r.applyStyles=void 0;var e=h(n(19975));r.applyStyles=e.default;var a=h(n(52744));r.arrow=a.default;var t=h(n(59894));r.computeStyles=t.default;var o=h(n(36692));r.eventListeners=o.default;var p=h(n(23798));r.flip=p.default;var b=h(n(83761));r.hide=b.default;var y=h(n(61410));r.offset=y.default;var S=h(n(40107));r.popperOffsets=S.default;var k=h(n(75137));r.preventOverflow=k.default;function h(i){return i&&i.__esModule?i:{default:i}}},61410:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0,r.distanceAndSkiddingToXY=o;var e=t(n(83104)),a=n(46206);function t(y){return y&&y.__esModule?y:{default:y}}function o(y,S,k){var h=(0,e.default)(y),i=[a.left,a.top].indexOf(h)>=0?-1:1,c=typeof k=="function"?k(Object.assign({},S,{placement:y})):k,m=c[0],l=c[1];return m=m||0,l=(l||0)*i,[a.left,a.right].indexOf(h)>=0?{x:l,y:m}:{x:m,y:l}}function p(y){var S=y.state,k=y.options,h=y.name,i=k.offset,c=i===void 0?[0,0]:i,m=a.placements.reduce(function(d,v){return d[v]=o(v,S.rects,c),d},{}),l=m[S.placement],u=l.x,s=l.y;S.modifiersData.popperOffsets!=null&&(S.modifiersData.popperOffsets.x+=u,S.modifiersData.popperOffsets.y+=s),S.modifiersData[h]=m}var b=r.default={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:p}},40107:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=a(n(89951));function a(p){return p&&p.__esModule?p:{default:p}}function t(p){var b=p.state,y=p.name;b.modifiersData[y]=(0,e.default)({reference:b.rects.reference,element:b.rects.popper,strategy:"absolute",placement:b.placement})}var o=r.default={name:"popperOffsets",enabled:!0,phase:"read",fn:t,data:{}}},75137:function(T,r,n){"use strict";r.__esModule=!0,r.default=void 0;var e=n(46206),a=c(n(83104)),t=c(n(41199)),o=c(n(28066)),p=n(28595),b=c(n(28811)),y=c(n(44896)),S=c(n(17633)),k=c(n(45)),h=c(n(34780)),i=n(63618);function c(u){return u&&u.__esModule?u:{default:u}}function m(u){var s=u.state,d=u.options,v=u.name,g=d.mainAxis,C=g===void 0?!0:g,f=d.altAxis,N=f===void 0?!1:f,V=d.boundary,B=d.rootBoundary,I=d.altBoundary,L=d.padding,w=d.tether,A=w===void 0?!0:w,x=d.tetherOffset,E=x===void 0?0:x,P=(0,S.default)(s,{boundary:V,rootBoundary:B,padding:L,altBoundary:I}),D=(0,a.default)(s.placement),M=(0,k.default)(s.placement),O=!M,R=(0,t.default)(D),F=(0,o.default)(R),W=s.modifiersData.popperOffsets,U=s.rects.reference,z=s.rects.popper,$=typeof E=="function"?E(Object.assign({},s.rects,{placement:s.placement})):E,G=typeof $=="number"?{mainAxis:$,altAxis:$}:Object.assign({mainAxis:0,altAxis:0},$),X=s.modifiersData.offset?s.modifiersData.offset[s.placement]:null,J={x:0,y:0};if(W){if(C){var se,ie=R==="y"?e.top:e.left,me=R==="y"?e.bottom:e.right,q=R==="y"?"height":"width",re=W[R],ae=re+P[ie],le=re-P[me],Z=A?-z[q]/2:0,ne=M===e.start?U[q]:z[q],te=M===e.start?-z[q]:-U[q],fe=s.elements.arrow,pe=A&&fe?(0,b.default)(fe):{width:0,height:0},ce=s.modifiersData["arrow#persistent"]?s.modifiersData["arrow#persistent"].padding:(0,h.default)(),Ve=ce[ie],Ce=ce[me],Ne=(0,p.within)(0,U[q],pe[q]),Be=O?U[q]/2-Z-Ne-Ve-G.mainAxis:ne-Ne-Ve-G.mainAxis,be=O?-U[q]/2+Z+Ne+Ce+G.mainAxis:te+Ne+Ce+G.mainAxis,Le=s.elements.arrow&&(0,y.default)(s.elements.arrow),we=Le?R==="y"?Le.clientTop||0:Le.clientLeft||0:0,xe=(se=X==null?void 0:X[R])!=null?se:0,Re=re+Be-xe-we,He=re+be-xe,ye=(0,p.within)(A?(0,i.min)(ae,Re):ae,re,A?(0,i.max)(le,He):le);W[R]=ye,J[R]=ye-re}if(N){var de,he=R==="x"?e.top:e.left,ke=R==="x"?e.bottom:e.right,ve=W[F],Se=F==="y"?"height":"width",Pe=ve+P[he],je=ve-P[ke],Fe=[e.top,e.left].indexOf(D)!==-1,ze=(de=X==null?void 0:X[F])!=null?de:0,We=Fe?Pe:ve-U[Se]-z[Se]-ze+G.altAxis,Ue=Fe?ve+U[Se]+z[Se]-ze-G.altAxis:je,Xe=A&&Fe?(0,p.withinMaxClamp)(We,ve,Ue):(0,p.within)(A?We:Pe,ve,A?Ue:je);W[F]=Xe,J[F]=Xe-ve}s.modifiersData[v]=J}}var l=r.default={name:"preventOverflow",enabled:!0,phase:"main",fn:m,requiresIfExists:["offset"]}},2473:function(T,r,n){"use strict";r.__esModule=!0,r.defaultModifiers=r.createPopper=void 0;var e=n(96376);r.popperGenerator=e.popperGenerator,r.detectOverflow=e.detectOverflow;var a=b(n(36692)),t=b(n(40107)),o=b(n(59894)),p=b(n(19975));function b(k){return k&&k.__esModule?k:{default:k}}var y=r.defaultModifiers=[a.default,t.default,o.default,p.default],S=r.createPopper=(0,e.popperGenerator)({defaultModifiers:y})},83312:function(T,r,n){"use strict";r.__esModule=!0;var e={createPopper:!0,createPopperLite:!0,defaultModifiers:!0,popperGenerator:!0,detectOverflow:!0};r.defaultModifiers=r.createPopperLite=r.createPopper=void 0;var a=n(96376);r.popperGenerator=a.popperGenerator,r.detectOverflow=a.detectOverflow;var t=l(n(36692)),o=l(n(40107)),p=l(n(59894)),b=l(n(19975)),y=l(n(61410)),S=l(n(23798)),k=l(n(75137)),h=l(n(52744)),i=l(n(83761)),c=n(2473);r.createPopperLite=c.createPopper;var m=n(39805);Object.keys(m).forEach(function(d){d==="default"||d==="__esModule"||Object.prototype.hasOwnProperty.call(e,d)||d in r&&r[d]===m[d]||(r[d]=m[d])});function l(d){return d&&d.__esModule?d:{default:d}}var u=r.defaultModifiers=[t.default,o.default,p.default,b.default,y.default,S.default,k.default,h.default,i.default],s=r.createPopperLite=r.createPopper=(0,a.popperGenerator)({defaultModifiers:u})},9041:function(T,r,n){"use strict";r.__esModule=!0,r.default=b;var e=p(n(45)),a=n(46206),t=p(n(17633)),o=p(n(83104));function p(y){return y&&y.__esModule?y:{default:y}}function b(y,S){S===void 0&&(S={});var k=S,h=k.placement,i=k.boundary,c=k.rootBoundary,m=k.padding,l=k.flipVariations,u=k.allowedAutoPlacements,s=u===void 0?a.placements:u,d=(0,e.default)(h),v=d?l?a.variationPlacements:a.variationPlacements.filter(function(f){return(0,e.default)(f)===d}):a.basePlacements,g=v.filter(function(f){return s.indexOf(f)>=0});g.length===0&&(g=v);var C=g.reduce(function(f,N){return f[N]=(0,t.default)(y,{placement:N,boundary:i,rootBoundary:c,padding:m})[(0,o.default)(N)],f},{});return Object.keys(C).sort(function(f,N){return C[f]-C[N]})}},89951:function(T,r,n){"use strict";r.__esModule=!0,r.default=b;var e=p(n(83104)),a=p(n(45)),t=p(n(41199)),o=n(46206);function p(y){return y&&y.__esModule?y:{default:y}}function b(y){var S=y.reference,k=y.element,h=y.placement,i=h?(0,e.default)(h):null,c=h?(0,a.default)(h):null,m=S.x+S.width/2-k.width/2,l=S.y+S.height/2-k.height/2,u;switch(i){case o.top:u={x:m,y:S.y-k.height};break;case o.bottom:u={x:m,y:S.y+S.height};break;case o.right:u={x:S.x+S.width,y:l};break;case o.left:u={x:S.x-k.width,y:l};break;default:u={x:S.x,y:S.y}}var s=i?(0,t.default)(i):null;if(s!=null){var d=s==="y"?"height":"width";switch(c){case o.start:u[s]=u[s]-(S[d]/2-k[d]/2);break;case o.end:u[s]=u[s]+(S[d]/2-k[d]/2);break;default:}}return u}},10579:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){var a;return function(){return a||(a=new Promise(function(t){Promise.resolve().then(function(){a=void 0,t(e())})})),a}}},17633:function(T,r,n){"use strict";r.__esModule=!0,r.default=i;var e=h(n(49035)),a=h(n(40600)),t=h(n(37786)),o=h(n(89951)),p=h(n(81666)),b=n(46206),y=n(75573),S=h(n(43286)),k=h(n(81447));function h(c){return c&&c.__esModule?c:{default:c}}function i(c,m){m===void 0&&(m={});var l=m,u=l.placement,s=u===void 0?c.placement:u,d=l.strategy,v=d===void 0?c.strategy:d,g=l.boundary,C=g===void 0?b.clippingParents:g,f=l.rootBoundary,N=f===void 0?b.viewport:f,V=l.elementContext,B=V===void 0?b.popper:V,I=l.altBoundary,L=I===void 0?!1:I,w=l.padding,A=w===void 0?0:w,x=(0,S.default)(typeof A!="number"?A:(0,k.default)(A,b.basePlacements)),E=B===b.popper?b.reference:b.popper,P=c.rects.popper,D=c.elements[L?E:B],M=(0,e.default)((0,y.isElement)(D)?D:D.contextElement||(0,a.default)(c.elements.popper),C,N,v),O=(0,t.default)(c.elements.reference),R=(0,o.default)({reference:O,element:P,strategy:"absolute",placement:s}),F=(0,p.default)(Object.assign({},P,R)),W=B===b.popper?F:O,U={top:M.top-W.top+x.top,bottom:W.bottom-M.bottom+x.bottom,left:M.left-W.left+x.left,right:W.right-M.right+x.right},z=c.modifiersData.offset;if(B===b.popper&&z){var $=z[s];Object.keys(U).forEach(function(G){var X=[b.right,b.bottom].indexOf(G)>=0?1:-1,J=[b.top,b.bottom].indexOf(G)>=0?"y":"x";U[G]+=$[J]*X})}return U}},81447:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e,a){return a.reduce(function(t,o){return t[o]=e,t},{})}},28066:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){return e==="x"?"y":"x"}},83104:function(T,r,n){"use strict";r.__esModule=!0,r.default=a;var e=n(46206);function a(t){return t.split("-")[0]}},34780:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(){return{top:0,right:0,bottom:0,left:0}}},41199:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}},71376:function(T,r){"use strict";r.__esModule=!0,r.default=e;var n={left:"right",right:"left",bottom:"top",top:"bottom"};function e(a){return a.replace(/left|right|bottom|top/g,function(t){return n[t]})}},86459:function(T,r){"use strict";r.__esModule=!0,r.default=e;var n={start:"end",end:"start"};function e(a){return a.replace(/start|end/g,function(t){return n[t]})}},45:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){return e.split("-")[1]}},63618:function(T,r){"use strict";r.__esModule=!0,r.round=r.min=r.max=void 0;var n=r.max=Math.max,e=r.min=Math.min,a=r.round=Math.round},56500:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){var a=e.reduce(function(t,o){var p=t[o.name];return t[o.name]=p?Object.assign({},p,o,{options:Object.assign({},p.options,o.options),data:Object.assign({},p.data,o.data)}):o,t},{});return Object.keys(a).map(function(t){return a[t]})}},43286:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=a(n(34780));function a(o){return o&&o.__esModule?o:{default:o}}function t(o){return Object.assign({},(0,e.default)(),o)}},33118:function(T,r,n){"use strict";r.__esModule=!0,r.default=t;var e=n(46206);function a(o){var p=new Map,b=new Set,y=[];o.forEach(function(k){p.set(k.name,k)});function S(k){b.add(k.name);var h=[].concat(k.requires||[],k.requiresIfExists||[]);h.forEach(function(i){if(!b.has(i)){var c=p.get(i);c&&S(c)}}),y.push(k)}return o.forEach(function(k){b.has(k.name)||S(k)}),y}function t(o){var p=a(o);return e.modifierPhases.reduce(function(b,y){return b.concat(p.filter(function(S){return S.phase===y}))},[])}},81666:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}},35366:function(T,r){"use strict";r.__esModule=!0,r.default=n;function n(){var e=navigator.userAgentData;return e!=null&&e.brands&&Array.isArray(e.brands)?e.brands.map(function(a){return a.brand+"/"+a.version}).join(" "):navigator.userAgent}},28595:function(T,r,n){"use strict";r.__esModule=!0,r.within=a,r.withinMaxClamp=t;var e=n(63618);function a(o,p,b){return(0,e.max)(o,(0,e.min)(p,b))}function t(o,p,b){var y=a(o,p,b);return y>b?b:y}},15875:function(T,r){"use strict";r.__esModule=!0,r.VNodeFlags=r.ChildFlags=void 0;var n;(function(a){a[a.Unknown=0]="Unknown",a[a.HtmlElement=1]="HtmlElement",a[a.ComponentUnknown=2]="ComponentUnknown",a[a.ComponentClass=4]="ComponentClass",a[a.ComponentFunction=8]="ComponentFunction",a[a.Text=16]="Text",a[a.SvgElement=32]="SvgElement",a[a.InputElement=64]="InputElement",a[a.TextareaElement=128]="TextareaElement",a[a.SelectElement=256]="SelectElement",a[a.Portal=1024]="Portal",a[a.ReCreate=2048]="ReCreate",a[a.ContentEditable=4096]="ContentEditable",a[a.Fragment=8192]="Fragment",a[a.InUse=16384]="InUse",a[a.ForwardRef=32768]="ForwardRef",a[a.Normalized=65536]="Normalized",a[a.ForwardRefComponent=32776]="ForwardRefComponent",a[a.FormElement=448]="FormElement",a[a.Element=481]="Element",a[a.Component=14]="Component",a[a.DOMRef=1521]="DOMRef",a[a.InUseOrNormalized=81920]="InUseOrNormalized",a[a.ClearInUse=-16385]="ClearInUse",a[a.ComponentKnown=12]="ComponentKnown"})(n||(r.VNodeFlags=n={}));var e;(function(a){a[a.UnknownChildren=0]="UnknownChildren",a[a.HasInvalidChildren=1]="HasInvalidChildren",a[a.HasVNodeChildren=2]="HasVNodeChildren",a[a.HasNonKeyedChildren=4]="HasNonKeyedChildren",a[a.HasKeyedChildren=8]="HasKeyedChildren",a[a.HasTextChildren=16]="HasTextChildren",a[a.MultipleChildren=12]="MultipleChildren"})(e||(r.ChildFlags=e={}))},89292:function(T,r){"use strict";r.__esModule=!0,r.Fragment=r.EMPTY_OBJ=r.Component=r.AnimationQueues=void 0,r._CI=Ot,r._HI=pe,r._M=Ke,r._MCCC=Ft,r._ME=Dt,r._MFCC=_t,r._MP=Mt,r._MR=at,r._RFC=gt,r.__render=Ht,r.createComponentVNode=se,r.createFragment=me,r.createPortal=Z,r.createRef=nn,r.createRenderer=En,r.createTextVNode=ie,r.createVNode=$,r.directClone=ae,r.findDOMFromVNode=V,r.forwardRef=on,r.getFlagsForElementVnode=te,r.linkEvent=h,r.normalizeProps=q,r.options=void 0,r.render=zt,r.rerender=$t,r.version=void 0;var n=Array.isArray;function e(j){var _=typeof j;return _==="string"||_==="number"}function a(j){return j==null}function t(j){return j===null||j===!1||j===!0||j===void 0}function o(j){return typeof j=="function"}function p(j){return typeof j=="string"}function b(j){return typeof j=="number"}function y(j){return j===null}function S(j){return j===void 0}function k(j,_){var H={};if(j)for(var K in j)H[K]=j[K];if(_)for(var Q in _)H[Q]=_[Q];return H}function h(j,_){return o(_)?{data:j,event:_}:null}function i(j){return!y(j)&&typeof j=="object"}var c=r.EMPTY_OBJ={},m=r.Fragment="$F",l=r.AnimationQueues=function(){function j(){this.componentDidAppear=[],this.componentWillDisappear=[],this.componentWillMove=[]}return j}();function u(j){return j.substring(2).toLowerCase()}function s(j,_){j.appendChild(_)}function d(j,_,H){y(H)?s(j,_):j.insertBefore(_,H)}function v(j,_){return _?document.createElementNS("http://www.w3.org/2000/svg",j):document.createElement(j)}function g(j,_,H){j.replaceChild(_,H)}function C(j,_){j.removeChild(_)}function f(j){for(var _=0;_0?B(H.componentWillDisappear,w(j,_)):L(j,_,!1)}function x(j,_,H,K,Q,ee,oe,ue){j.componentWillMove.push({dom:K,fn:function(){function ge(){oe&4?H.componentWillMove(_,Q,K):oe&8&&H.onComponentWillMove(_,Q,K,ue)}return ge}(),next:ee,parent:Q})}function E(j,_,H,K,Q){var ee,oe,ue=_.flags;do{var ge=_.flags;if(ge&1521){!a(ee)&&(o(ee.componentWillMove)||o(ee.onComponentWillMove))?x(Q,j,ee,_.dom,H,K,ue,oe):d(H,_.dom,K);return}var Te=_.children;if(ge&4)ee=_.children,oe=_.props,_=Te.$LI;else if(ge&8)ee=_.ref,oe=_.props,_=Te;else if(ge&8192)if(_.childFlags===2)_=Te;else{for(var Ie=0,Ee=Te.length;Ie0,Te=y(ue),Ie=p(ue)&&ue[0]===U;ge||Te||Ie?(H=H||_.slice(0,ee),(ge||Ie)&&(oe=ae(oe)),(Te||Ie)&&(oe.key=U+ee),H.push(oe)):H&&H.push(oe),oe.flags|=65536}}H=H||_,H.length===0?K=1:K=8}else H=_,H.flags|=65536,_.flags&81920&&(H=ae(_)),K=2;return j.children=H,j.childFlags=K,j}function pe(j){return t(j)||e(j)?ie(j,null):n(j)?me(j,0,null):j.flags&16384?ae(j):j}var ce="http://www.w3.org/1999/xlink",Ve="http://www.w3.org/XML/1998/namespace",Ce={"xlink:actuate":ce,"xlink:arcrole":ce,"xlink:href":ce,"xlink:role":ce,"xlink:show":ce,"xlink:title":ce,"xlink:type":ce,"xml:base":Ve,"xml:lang":Ve,"xml:space":Ve};function Ne(j){return{onClick:j,onDblClick:j,onFocusIn:j,onFocusOut:j,onKeyDown:j,onKeyPress:j,onKeyUp:j,onMouseDown:j,onMouseMove:j,onMouseUp:j,onTouchEnd:j,onTouchMove:j,onTouchStart:j}}var Be=Ne(0),be=Ne(null),Le=Ne(!0);function we(j,_){var H=_.$EV;return H||(H=_.$EV=Ne(null)),H[j]||++Be[j]===1&&(be[j]=je(j)),H}function xe(j,_){var H=_.$EV;H&&H[j]&&(--Be[j]===0&&(document.removeEventListener(u(j),be[j]),be[j]=null),H[j]=null)}function Re(j,_,H,K){if(o(H))we(j,K)[j]=H;else if(i(H)){if(R(_,H))return;we(j,K)[j]=H}else xe(j,K)}function He(j){return o(j.composedPath)?j.composedPath()[0]:j.target}function ye(j,_,H,K){var Q=He(j);do{if(_&&Q.disabled)return;var ee=Q.$EV;if(ee){var oe=ee[H];if(oe&&(K.dom=Q,oe.event?oe.event(oe.data,j):oe(j),j.cancelBubble))return}Q=Q.parentNode}while(!y(Q))}function de(){this.cancelBubble=!0,this.immediatePropagationStopped||this.stopImmediatePropagation()}function he(){return this.defaultPrevented}function ke(){return this.cancelBubble}function ve(j){var _={dom:document};return j.isDefaultPrevented=he,j.isPropagationStopped=ke,j.stopPropagation=de,Object.defineProperty(j,"currentTarget",{configurable:!0,get:function(){function H(){return _.dom}return H}()}),_}function Se(j){return function(_){if(_.button!==0){_.stopPropagation();return}ye(_,!0,j,ve(_))}}function Pe(j){return function(_){ye(_,!1,j,ve(_))}}function je(j){var _=j==="onClick"||j==="onDblClick"?Se(j):Pe(j);return document.addEventListener(u(j),_),_}function Fe(j,_){var H=document.createElement("i");return H.innerHTML=_,H.innerHTML===j.innerHTML}function ze(j,_,H){if(j[_]){var K=j[_];K.event?K.event(K.data,H):K(H)}else{var Q=_.toLowerCase();j[Q]&&j[Q](H)}}function We(j,_){var H=function(){function K(Q){var ee=this.$V;if(ee){var oe=ee.props||c,ue=ee.dom;if(p(j))ze(oe,j,Q);else for(var ge=0;ge-1&&_.options[ee]&&(ue=_.options[ee].value),H&&a(ue)&&(ue=j.defaultValue),rt(K,ue)}}var Zt=We("onInput",Tt),qt=We("onChange");function en(j,_){Ue(j,"input",Zt),_.onChange&&Ue(j,"change",qt)}function Tt(j,_,H){var K=j.value,Q=_.value;if(a(K)){if(H){var ee=j.defaultValue;!a(ee)&&ee!==Q&&(_.defaultValue=ee,_.value=ee)}}else Q!==K&&(_.defaultValue=K,_.value=K)}function xt(j,_,H,K,Q,ee){j&64?ut(K,H):j&256?wt(K,H,Q,_):j&128&&Tt(K,H,Q),ee&&(H.$V=_)}function tn(j,_,H){j&64?Bt(_,H):j&256?Qt(_):j&128&&en(_,H)}function At(j){return j.type&&Xe(j.type)?!a(j.checked):!a(j.value)}function nn(){return{current:null}}function on(j){var _={render:j};return _}function st(j){j&&!W(j,null)&&j.current&&(j.current=null)}function at(j,_,H){j&&(o(j)||j.current!==void 0)&&H.push(function(){!W(j,_)&&j.current!==void 0&&(j.current=_)})}function Je(j,_,H){Ze(j,H),A(j,_,H)}function Ze(j,_){var H=j.flags,K=j.children,Q;if(H&481){Q=j.ref;var ee=j.props;st(Q);var oe=j.childFlags;if(!y(ee))for(var ue=Object.keys(ee),ge=0,Te=ue.length;ge0?B(H.componentWillDisappear,rn(_,j)):j.textContent=""}function pt(j,_,H,K){ct(H,K),_.flags&8192?A(_,j,K):mt(j,H,K)}function Et(j,_,H,K,Q){j.componentWillDisappear.push(function(ee){K&4?_.componentWillDisappear(H,ee):K&8&&_.onComponentWillDisappear(H,Q,ee)})}function an(j){var _=j.event;return function(H){_(j.data,H)}}function cn(j,_,H,K){if(i(H)){if(R(_,H))return;H=an(H)}Ue(K,u(j),H)}function ln(j,_,H){if(a(_)){H.removeAttribute("style");return}var K=H.style,Q,ee;if(p(_)){K.cssText=_;return}if(!a(j)&&!p(j)){for(Q in _)ee=_[Q],ee!==j[Q]&&K.setProperty(Q,ee);for(Q in j)a(_[Q])&&K.removeProperty(Q)}else for(Q in _)ee=_[Q],K.setProperty(Q,ee)}function dn(j,_,H,K,Q){var ee=j&&j.__html||"",oe=_&&_.__html||"";ee!==oe&&!a(oe)&&!Fe(K,oe)&&(y(H)||(H.childFlags&12?ct(H.children,Q):H.childFlags===2&&Ze(H.children,Q),H.children=null,H.childFlags=1),K.innerHTML=oe)}function vt(j,_,H,K,Q,ee,oe,ue){switch(j){case"children":case"childrenType":case"className":case"defaultValue":case"key":case"multiple":case"ref":case"selectedIndex":break;case"autoFocus":K.autofocus=!!H;break;case"allowfullscreen":case"autoplay":case"capture":case"checked":case"controls":case"default":case"disabled":case"hidden":case"indeterminate":case"loop":case"muted":case"novalidate":case"open":case"readOnly":case"required":case"reversed":case"scoped":case"seamless":case"selected":K[j]=!!H;break;case"defaultChecked":case"value":case"volume":if(ee&&j==="value")break;var ge=a(H)?"":H;K[j]!==ge&&(K[j]=ge);break;case"style":ln(_,H,K);break;case"dangerouslySetInnerHTML":dn(_,H,oe,K,ue);break;default:Le[j]?Re(j,_,H,K):j.charCodeAt(0)===111&&j.charCodeAt(1)===110?cn(j,_,H,K):a(H)?K.removeAttribute(j):Q&&Ce[j]?K.setAttributeNS(Ce[j],j,H):K.setAttribute(j,H);break}}function Mt(j,_,H,K,Q,ee){var oe=!1,ue=(_&448)>0;ue&&(oe=At(H),oe&&tn(_,K,H));for(var ge in H)vt(ge,null,H[ge],K,Q,oe,null,ee);ue&&xt(_,j,K,H,!0,oe)}function Pt(j,_,H){var K=pe(j.render(_,j.state,H)),Q=H;return o(j.getChildContext)&&(Q=k(H,j.getChildContext())),j.$CX=Q,K}function Ot(j,_,H,K,Q,ee){var oe=new _(H,K),ue=oe.$N=!!(_.getDerivedStateFromProps||oe.getSnapshotBeforeUpdate);if(oe.$SVG=Q,oe.$L=ee,j.children=oe,oe.$BS=!1,oe.context=K,oe.props===c&&(oe.props=H),ue)oe.state=P(oe,H,oe.state);else if(o(oe.componentWillMount)){oe.$BR=!0,oe.componentWillMount();var ge=oe.$PS;if(!y(ge)){var Te=oe.state;if(y(Te))oe.state=ge;else for(var Ie in ge)Te[Ie]=ge[Ie];oe.$PS=null}oe.$BR=!1}return oe.$LI=Pt(oe,H,K),oe}function gt(j,_){var H=j.props||c;return j.flags&32768?j.type.render(H,j.ref,_):j.type(H,_)}function Ke(j,_,H,K,Q,ee,oe){var ue=j.flags|=16384;ue&481?Dt(j,_,H,K,Q,ee,oe):ue&4?mn(j,_,H,K,Q,ee,oe):ue&8?pn(j,_,H,K,Q,ee,oe):ue&16?Rt(j,_,Q):ue&8192?sn(j,H,_,K,Q,ee,oe):ue&1024&&un(j,H,_,Q,ee,oe)}function un(j,_,H,K,Q,ee){Ke(j.children,j.ref,_,!1,null,Q,ee);var oe=le();Rt(oe,H,K),j.dom=oe.dom}function sn(j,_,H,K,Q,ee,oe){var ue=j.children,ge=j.childFlags;ge&12&&ue.length===0&&(ge=j.childFlags=2,ue=j.children=le()),ge===2?Ke(ue,H,_,K,Q,ee,oe):ot(ue,H,_,K,Q,ee,oe)}function Rt(j,_,H){var K=j.dom=document.createTextNode(j.children);y(_)||d(_,K,H)}function Dt(j,_,H,K,Q,ee,oe){var ue=j.flags,ge=j.props,Te=j.className,Ie=j.childFlags,Ee=j.dom=v(j.type,K=K||(ue&32)>0),Ae=j.children;if(!a(Te)&&Te!==""&&(K?Ee.setAttribute("class",Te):Ee.className=Te),Ie===16)O(Ee,Ae);else if(Ie!==1){var Me=K&&j.type!=="foreignObject";Ie===2?(Ae.flags&16384&&(j.children=Ae=ae(Ae)),Ke(Ae,Ee,H,Me,null,ee,oe)):(Ie===8||Ie===4)&&ot(Ae,Ee,H,Me,null,ee,oe)}y(_)||d(_,Ee,Q),y(ge)||Mt(j,ue,ge,Ee,K,oe),at(j.ref,Ee,ee)}function ot(j,_,H,K,Q,ee,oe){for(var ue=0;ueMe)&&(Ee=V(ue[Me-1],!1).nextSibling)}Nt(Te,Ie,ue,ge,H,K,Q,Ee,j,ee,oe)}function Vn(j,_,H,K,Q){var ee=j.ref,oe=_.ref,ue=_.children;if(Nt(j.childFlags,_.childFlags,j.children,ue,ee,H,!1,null,j,K,Q),_.dom=j.dom,ee!==oe&&!t(ue)){var ge=ue.dom;C(ee,ge),s(oe,ge)}}function bn(j,_,H,K,Q,ee,oe){var ue=_.dom=j.dom,ge=j.props,Te=_.props,Ie=!1,Ee=!1,Ae;if(K=K||(Q&32)>0,ge!==Te){var Me=ge||c;if(Ae=Te||c,Ae!==c){Ie=(Q&448)>0,Ie&&(Ee=At(Ae));for(var _e in Ae){var Oe=Me[_e],$e=Ae[_e];Oe!==$e&&vt(_e,Oe,$e,ue,K,Ee,j,oe)}}if(Me!==c)for(var De in Me)a(Ae[De])&&!a(Me[De])&&vt(De,Me[De],null,ue,K,Ee,j,oe)}var tt=_.children,Ye=_.className;j.className!==Ye&&(a(Ye)?ue.removeAttribute("class"):K?ue.setAttribute("class",Ye):ue.className=Ye),Q&4096?gn(ue,tt):Nt(j.childFlags,_.childFlags,j.children,tt,ue,H,K&&_.type!=="foreignObject",null,j,ee,oe),Ie&&xt(Q,_,ue,Ae,!1,Ee);var it=_.ref,Qe=j.ref;Qe!==it&&(st(Qe),at(it,ue,ee))}function kn(j,_,H,K,Q,ee,oe){Ze(j,oe),ot(_,H,K,Q,V(j,!0),ee,oe),A(j,H,oe)}function Nt(j,_,H,K,Q,ee,oe,ue,ge,Te,Ie){switch(j){case 2:switch(_){case 2:qe(H,K,Q,ee,oe,ue,Te,Ie);break;case 1:Je(H,Q,Ie);break;case 16:Ze(H,Ie),O(Q,K);break;default:kn(H,K,Q,ee,oe,Te,Ie);break}break;case 1:switch(_){case 2:Ke(K,Q,ee,oe,ue,Te,Ie);break;case 1:break;case 16:O(Q,K);break;default:ot(K,Q,ee,oe,ue,Te,Ie);break}break;case 16:switch(_){case 16:vn(H,K,Q);break;case 2:mt(Q,H,Ie),Ke(K,Q,ee,oe,ue,Te,Ie);break;case 1:mt(Q,H,Ie);break;default:mt(Q,H,Ie),ot(K,Q,ee,oe,ue,Te,Ie);break}break;default:switch(_){case 16:ct(H,Ie),O(Q,K);break;case 2:pt(Q,ge,H,Ie),Ke(K,Q,ee,oe,ue,Te,Ie);break;case 1:pt(Q,ge,H,Ie);break;default:var Ee=H.length|0,Ae=K.length|0;Ee===0?Ae>0&&ot(K,Q,ee,oe,ue,Te,Ie):Ae===0?pt(Q,ge,H,Ie):_===8&&j===8?wn(H,K,Q,ee,oe,Ee,Ae,ue,ge,Te,Ie):Ln(H,K,Q,ee,oe,Ee,Ae,ue,Te,Ie);break}break}}function yn(j,_,H,K,Q){Q.push(function(){j.componentDidUpdate(_,H,K)})}function Wt(j,_,H,K,Q,ee,oe,ue,ge,Te){var Ie=j.state,Ee=j.props,Ae=!!j.$N,Me=o(j.shouldComponentUpdate);if(Ae&&(_=P(j,H,_!==Ie?k(Ie,_):_)),oe||!Me||Me&&j.shouldComponentUpdate(H,_,Q)){!Ae&&o(j.componentWillUpdate)&&j.componentWillUpdate(H,_,Q),j.props=H,j.state=_,j.context=Q;var _e=null,Oe=Pt(j,H,Q);Ae&&o(j.getSnapshotBeforeUpdate)&&(_e=j.getSnapshotBeforeUpdate(Ee,Ie)),qe(j.$LI,Oe,K,j.$CX,ee,ue,ge,Te),j.$LI=Oe,o(j.componentDidUpdate)&&yn(j,Ee,Ie,_e,ge)}else j.props=H,j.state=_,j.context=Q}function Sn(j,_,H,K,Q,ee,oe,ue){var ge=_.children=j.children;if(!y(ge)){ge.$L=oe;var Te=_.props||c,Ie=_.ref,Ee=j.ref,Ae=ge.state;if(!ge.$N){if(o(ge.componentWillReceiveProps)){if(ge.$BR=!0,ge.componentWillReceiveProps(Te,K),ge.$UN)return;ge.$BR=!1}y(ge.$PS)||(Ae=k(Ae,ge.$PS),ge.$PS=null)}Wt(ge,Ae,Te,H,K,Q,!1,ee,oe,ue),Ee!==Ie&&(st(Ee),at(Ie,ge,oe))}}function Bn(j,_,H,K,Q,ee,oe,ue){var ge=!0,Te=_.props||c,Ie=_.ref,Ee=j.props,Ae=!a(Ie),Me=j.children;if(Ae&&o(Ie.onComponentShouldUpdate)&&(ge=Ie.onComponentShouldUpdate(Ee,Te)),ge!==!1){Ae&&o(Ie.onComponentWillUpdate)&&Ie.onComponentWillUpdate(Ee,Te);var _e=pe(gt(_,K));qe(Me,_e,H,K,Q,ee,oe,ue),_.children=_e,Ae&&o(Ie.onComponentDidUpdate)&&Ie.onComponentDidUpdate(Ee,Te)}else _.children=Me}function In(j,_){var H=_.children,K=_.dom=j.dom;H!==j.children&&(K.nodeValue=H)}function Ln(j,_,H,K,Q,ee,oe,ue,ge,Te){for(var Ie=ee>oe?oe:ee,Ee=0,Ae,Me;Eeoe)for(Ee=Ie;EeEe||Me>Ae)break e;_e=j[Me],Oe=_[Me]}for(_e=j[Ee],Oe=_[Ae];_e.key===Oe.key;){if(Oe.flags&16384&&(_[Ae]=Oe=ae(Oe)),qe(_e,Oe,H,K,Q,ue,Te,Ie),j[Ee]=Oe,Ee--,Ae--,Me>Ee||Me>Ae)break e;_e=j[Ee],Oe=_[Ae]}}if(Me>Ee){if(Me<=Ae)for($e=Ae+1,De=$eAe)for(;Me<=Ee;)Je(j[Me++],H,Ie);else Tn(j,_,K,ee,oe,Ee,Ae,Me,H,Q,ue,ge,Te,Ie)}function Tn(j,_,H,K,Q,ee,oe,ue,ge,Te,Ie,Ee,Ae,Me){var _e,Oe,$e=0,De=0,tt=ue,Ye=ue,it=ee-ue+1,Qe=oe-ue+1,lt=new Int32Array(Qe+1),nt=it===K,bt=!1,Ge=0,dt=0;if(Q<4||(it|Qe)<32)for(De=tt;De<=ee;++De)if(_e=j[De],dtue?bt=!0:Ge=ue,Oe.flags&16384&&(_[ue]=Oe=ae(Oe)),qe(_e,Oe,ge,H,Te,Ie,Ae,Me),++dt;break}!nt&&ue>oe&&Je(_e,ge,Me)}else nt||Je(_e,ge,Me);else{var Yt={};for(De=Ye;De<=oe;++De)Yt[_[De].key]=De;for(De=tt;De<=ee;++De)if(_e=j[De],dttt;)Je(j[tt++],ge,Me);lt[ue-Ye]=De+1,Ge>ue?bt=!0:Ge=ue,Oe=_[ue],Oe.flags&16384&&(_[ue]=Oe=ae(Oe)),qe(_e,Oe,ge,H,Te,Ie,Ae,Me),++dt}else nt||Je(_e,ge,Me);else nt||Je(_e,ge,Me)}if(nt)pt(ge,Ee,j,Me),ot(_,ge,H,Te,Ie,Ae,Me);else if(bt){var Xt=xn(lt);for(ue=Xt.length-1,De=Qe-1;De>=0;De--)lt[De]===0?(Ge=De+Ye,Oe=_[Ge],Oe.flags&16384&&(_[Ge]=Oe=ae(Oe)),$e=Ge+1,Ke(Oe,ge,H,Te,$e0&&I(Me.componentWillMove)}else if(dt!==Qe)for(De=Qe-1;De>=0;De--)lt[De]===0&&(Ge=De+Ye,Oe=_[Ge],Oe.flags&16384&&(_[Ge]=Oe=ae(Oe)),$e=Ge+1,Ke(Oe,ge,H,Te,$eUt&&(Ut=ge,et=new Int32Array(ge),ft=new Int32Array(ge));H>1,j[et[ue]]<_?ee=ue+1:oe=ue;_0&&(ft[H]=et[ee-1]),et[ee]=H)}ee=Q+1;var Te=new Int32Array(ee);for(oe=et[ee-1];ee-- >0;)Te[ee]=oe,oe=ft[oe],et[ee]=0;return Te}var An=typeof document!="undefined";An&&window.Node&&(Node.prototype.$EV=null,Node.prototype.$V=null);function Ht(j,_,H,K){var Q=[],ee=new l,oe=_.$V;D.v=!0,a(oe)?a(j)||(j.flags&16384&&(j=ae(j)),Ke(j,_,K,!1,null,Q,ee),_.$V=j,oe=j):a(j)?(Je(oe,_,ee),_.$V=null):(j.flags&16384&&(j=ae(j)),qe(oe,j,_,K,!1,null,Q,ee),oe=_.$V=j),f(Q),B(ee.componentDidAppear),D.v=!1,o(H)&&H(),o(M.renderComplete)&&M.renderComplete(oe,_)}function zt(j,_,H,K){H===void 0&&(H=null),K===void 0&&(K=c),Ht(j,_,H,K)}function En(j){return function(){function _(H,K,Q,ee){j||(j=H),zt(K,j,Q,ee)}return _}()}var ht=[],Mn=typeof Promise!="undefined"?Promise.resolve().then.bind(Promise.resolve()):function(j){window.setTimeout(j,0)},Vt=!1;function Kt(j,_,H,K){var Q=j.$PS;if(o(_)&&(_=_(Q?k(j.state,Q):j.state,j.props,j.context)),a(Q))j.$PS=_;else for(var ee in _)Q[ee]=_[ee];if(j.$BR)o(H)&&j.$L.push(H.bind(j));else{if(!D.v&&ht.length===0){Gt(j,K),o(H)&&H.call(j);return}if(ht.indexOf(j)===-1&&ht.push(j),K&&(j.$F=!0),Vt||(Vt=!0,Mn($t)),o(H)){var oe=j.$QU;oe||(oe=j.$QU=[]),oe.push(H)}}}function Pn(j){for(var _=j.$QU,H=0;H<_.length;++H)_[H].call(j);j.$QU=null}function $t(){var j;for(Vt=!1;j=ht.shift();)if(!j.$UN){var _=j.$F;j.$F=!1,Gt(j,_),j.$QU&&Pn(j)}}function Gt(j,_){if(_||!j.$BR){var H=j.$PS;j.$PS=null;var K=[],Q=new l;D.v=!0,Wt(j,k(j.state,H),j.props,V(j.$LI,!0).parentNode,j.context,j.$SVG,_,null,K,Q),f(K),B(Q.componentDidAppear),D.v=!1}else j.state=j.$PS,j.$PS=null}var On=r.Component=function(){function j(H,K){this.state=null,this.props=void 0,this.context=void 0,this.displayName=void 0,this.$BR=!1,this.$BS=!0,this.$PS=null,this.$LI=null,this.$UN=!1,this.$CX=null,this.$QU=null,this.$N=!1,this.$SSR=void 0,this.$L=null,this.$SVG=!1,this.$F=!1,this.props=H||c,this.context=K||c}var _=j.prototype;return _.forceUpdate=function(){function H(K){this.$UN||Kt(this,{},K,!0)}return H}(),_.setState=function(){function H(K,Q){this.$UN||this.$BS||Kt(this,K,Q,!1)}return H}(),_.render=function(){function H(K,Q,ee){return null}return H}(),j}();On.defaultProps=null;var Dn=r.version="8.2.3"},89005:function(T,r,n){"use strict";r.__esModule=!0;var e=n(89292);Object.keys(e).forEach(function(a){a==="default"||a==="__esModule"||a in r&&r[a]===e[a]||(r[a]=e[a])})},71614:function(T,r,n){"use strict";var e=n(21285);function a(){}function t(){}t.resetWarningCache=a,T.exports=function(){function o(y,S,k,h,i,c){if(c!==e){var m=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw m.name="Invariant Violation",m}}o.isRequired=o;function p(){return o}var b={array:o,bigint:o,bool:o,func:o,number:o,object:o,string:o,symbol:o,any:o,arrayOf:p,element:o,elementType:o,instanceOf:p,node:o,objectOf:p,oneOf:p,oneOfType:p,shape:p,exact:p,checkPropTypes:t,resetWarningCache:a};return b.PropTypes=b,b}},15964:function(T,r,n){"use strict";if(0)var e,a;else T.exports=n(71614)()},21285:function(T){"use strict";var r="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";T.exports=r},95012:function(T){"use strict";var r=function(n){"use strict";var e=Object.prototype,a=e.hasOwnProperty,t=Object.defineProperty||function(M,O,R){M[O]=R.value},o,p=typeof Symbol=="function"?Symbol:{},b=p.iterator||"@@iterator",y=p.asyncIterator||"@@asyncIterator",S=p.toStringTag||"@@toStringTag";function k(M,O,R){return Object.defineProperty(M,O,{value:R,enumerable:!0,configurable:!0,writable:!0}),M[O]}try{k({},"")}catch(M){k=function(R,F,W){return R[F]=W}}function h(M,O,R,F){var W=O&&O.prototype instanceof d?O:d,U=Object.create(W.prototype),z=new E(F||[]);return t(U,"_invoke",{value:L(M,R,z)}),U}n.wrap=h;function i(M,O,R){try{return{type:"normal",arg:M.call(O,R)}}catch(F){return{type:"throw",arg:F}}}var c="suspendedStart",m="suspendedYield",l="executing",u="completed",s={};function d(){}function v(){}function g(){}var C={};k(C,b,function(){return this});var f=Object.getPrototypeOf,N=f&&f(f(P([])));N&&N!==e&&a.call(N,b)&&(C=N);var V=g.prototype=d.prototype=Object.create(C);v.prototype=g,t(V,"constructor",{value:g,configurable:!0}),t(g,"constructor",{value:v,configurable:!0}),v.displayName=k(g,S,"GeneratorFunction");function B(M){["next","throw","return"].forEach(function(O){k(M,O,function(R){return this._invoke(O,R)})})}n.isGeneratorFunction=function(M){var O=typeof M=="function"&&M.constructor;return O?O===v||(O.displayName||O.name)==="GeneratorFunction":!1},n.mark=function(M){return Object.setPrototypeOf?Object.setPrototypeOf(M,g):(M.__proto__=g,k(M,S,"GeneratorFunction")),M.prototype=Object.create(V),M},n.awrap=function(M){return{__await:M}};function I(M,O){function R(U,z,$,G){var X=i(M[U],M,z);if(X.type==="throw")G(X.arg);else{var J=X.arg,se=J.value;return se&&typeof se=="object"&&a.call(se,"__await")?O.resolve(se.__await).then(function(ie){R("next",ie,$,G)},function(ie){R("throw",ie,$,G)}):O.resolve(se).then(function(ie){J.value=ie,$(J)},function(ie){return R("throw",ie,$,G)})}}var F;function W(U,z){function $(){return new O(function(G,X){R(U,z,G,X)})}return F=F?F.then($,$):$()}t(this,"_invoke",{value:W})}B(I.prototype),k(I.prototype,y,function(){return this}),n.AsyncIterator=I,n.async=function(M,O,R,F,W){W===void 0&&(W=Promise);var U=new I(h(M,O,R,F),W);return n.isGeneratorFunction(O)?U:U.next().then(function(z){return z.done?z.value:U.next()})};function L(M,O,R){var F=c;return function(){function W(U,z){if(F===l)throw new Error("Generator is already running");if(F===u){if(U==="throw")throw z;return D()}for(R.method=U,R.arg=z;;){var $=R.delegate;if($){var G=w($,R);if(G){if(G===s)continue;return G}}if(R.method==="next")R.sent=R._sent=R.arg;else if(R.method==="throw"){if(F===c)throw F=u,R.arg;R.dispatchException(R.arg)}else R.method==="return"&&R.abrupt("return",R.arg);F=l;var X=i(M,O,R);if(X.type==="normal"){if(F=R.done?u:m,X.arg===s)continue;return{value:X.arg,done:R.done}}else X.type==="throw"&&(F=u,R.method="throw",R.arg=X.arg)}}return W}()}function w(M,O){var R=O.method,F=M.iterator[R];if(F===o)return O.delegate=null,R==="throw"&&M.iterator.return&&(O.method="return",O.arg=o,w(M,O),O.method==="throw")||R!=="return"&&(O.method="throw",O.arg=new TypeError("The iterator does not provide a '"+R+"' method")),s;var W=i(F,M.iterator,O.arg);if(W.type==="throw")return O.method="throw",O.arg=W.arg,O.delegate=null,s;var U=W.arg;if(!U)return O.method="throw",O.arg=new TypeError("iterator result is not an object"),O.delegate=null,s;if(U.done)O[M.resultName]=U.value,O.next=M.nextLoc,O.method!=="return"&&(O.method="next",O.arg=o);else return U;return O.delegate=null,s}B(V),k(V,S,"Generator"),k(V,b,function(){return this}),k(V,"toString",function(){return"[object Generator]"});function A(M){var O={tryLoc:M[0]};1 in M&&(O.catchLoc=M[1]),2 in M&&(O.finallyLoc=M[2],O.afterLoc=M[3]),this.tryEntries.push(O)}function x(M){var O=M.completion||{};O.type="normal",delete O.arg,M.completion=O}function E(M){this.tryEntries=[{tryLoc:"root"}],M.forEach(A,this),this.reset(!0)}n.keys=function(M){var O=Object(M),R=[];for(var F in O)R.push(F);return R.reverse(),function(){function W(){for(;R.length;){var U=R.pop();if(U in O)return W.value=U,W.done=!1,W}return W.done=!0,W}return W}()};function P(M){if(M!=null){var O=M[b];if(O)return O.call(M);if(typeof M.next=="function")return M;if(!isNaN(M.length)){var R=-1,F=function(){function W(){for(;++R=0;--W){var U=this.tryEntries[W],z=U.completion;if(U.tryLoc==="root")return F("end");if(U.tryLoc<=this.prev){var $=a.call(U,"catchLoc"),G=a.call(U,"finallyLoc");if($&&G){if(this.prev=0;--F){var W=this.tryEntries[F];if(W.tryLoc<=this.prev&&a.call(W,"finallyLoc")&&this.prev=0;--R){var F=this.tryEntries[R];if(F.finallyLoc===O)return this.complete(F.completion,F.afterLoc),x(F),s}}return M}(),catch:function(){function M(O){for(var R=this.tryEntries.length-1;R>=0;--R){var F=this.tryEntries[R];if(F.tryLoc===O){var W=F.completion;if(W.type==="throw"){var U=W.arg;x(F)}return U}}throw new Error("illegal catch attempt")}return M}(),delegateYield:function(){function M(O,R,F){return this.delegate={iterator:P(O),resultName:R,nextLoc:F},this.method==="next"&&(this.arg=o),s}return M}()},n}(T.exports);try{regeneratorRuntime=r}catch(n){typeof globalThis=="object"?globalThis.regeneratorRuntime=r:Function("r","regeneratorRuntime = r")(r)}},30236:function(){"use strict";self.fetch||(self.fetch=function(T,r){return r=r||{},new Promise(function(n,e){var a=new XMLHttpRequest,t=[],o={},p=function(){function y(){return{ok:(a.status/100|0)==2,statusText:a.statusText,status:a.status,url:a.responseURL,text:function(){function S(){return Promise.resolve(a.responseText)}return S}(),json:function(){function S(){return Promise.resolve(a.responseText).then(JSON.parse)}return S}(),blob:function(){function S(){return Promise.resolve(new Blob([a.response]))}return S}(),clone:y,headers:{keys:function(){function S(){return t}return S}(),entries:function(){function S(){return t.map(function(k){return[k,a.getResponseHeader(k)]})}return S}(),get:function(){function S(k){return a.getResponseHeader(k)}return S}(),has:function(){function S(k){return a.getResponseHeader(k)!=null}return S}()}}}return y}();for(var b in a.open(r.method||"get",T,!0),a.onload=function(){a.getAllResponseHeaders().toLowerCase().replace(/^(.+?):/gm,function(y,S){o[S]||t.push(o[S]=S)}),n(p())},a.onerror=e,a.withCredentials=r.credentials=="include",r.headers)a.setRequestHeader(b,r.headers[b]);a.send(r.body||null)})})},88510:function(T,r){"use strict";r.__esModule=!0,r.zipWith=r.zip=r.uniqBy=r.uniq=r.toKeyedArray=r.toArray=r.sortBy=r.sort=r.reduce=r.range=r.map=r.filterMap=r.filter=void 0;function n(d,v){var g=typeof Symbol!="undefined"&&d[Symbol.iterator]||d["@@iterator"];if(g)return(g=g.call(d)).next.bind(g);if(Array.isArray(d)||(g=e(d))||v&&d&&typeof d.length=="number"){g&&(d=g);var C=0;return function(){return C>=d.length?{done:!0}:{done:!1,value:d[C++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function e(d,v){if(d){if(typeof d=="string")return a(d,v);var g={}.toString.call(d).slice(8,-1);return g==="Object"&&d.constructor&&(g=d.constructor.name),g==="Map"||g==="Set"?Array.from(d):g==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(g)?a(d,v):void 0}}function a(d,v){(v==null||v>d.length)&&(v=d.length);for(var g=0,C=Array(v);gI)return 1}return 0},k=r.sortBy=function(){function d(){for(var v=arguments.length,g=new Array(v),C=0;C=1-n)return F[W-1];var z=U%1,$=U|0;return D.lerp(F[$],F[$+1],z)}return O}(),D}(),a=function(M,O,R){return O===void 0&&(O=0),R===void 0&&(R=Math.pow(10,O)),Math.round(R*M)/R},t={grad:360/400,turn:360,rad:360/(Math.PI*2)},o=r.hexToHsva=function(){function D(M){return I(p(M))}return D}(),p=r.hexToRgba=function(){function D(M){return M[0]==="#"&&(M=M.substring(1)),M.length<6?{r:parseInt(M[0]+M[0],16),g:parseInt(M[1]+M[1],16),b:parseInt(M[2]+M[2],16),a:M.length===4?a(parseInt(M[3]+M[3],16)/255,2):1}:{r:parseInt(M.substring(0,2),16),g:parseInt(M.substring(2,4),16),b:parseInt(M.substring(4,6),16),a:M.length===8?a(parseInt(M.substring(6,8),16)/255,2):1}}return D}(),b=r.parseHue=function(){function D(M,O){return O===void 0&&(O="deg"),Number(M)*(t[O]||1)}return D}(),y=r.hslaStringToHsva=function(){function D(M){var O=/hsla?\(?\s*(-?\d*\.?\d+)(deg|rad|grad|turn)?[,\s]+(-?\d*\.?\d+)%?[,\s]+(-?\d*\.?\d+)%?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i,R=O.exec(M);return R?k({h:b(R[1],R[2]),s:Number(R[3]),l:Number(R[4]),a:R[5]===void 0?1:Number(R[5])/(R[6]?100:1)}):{h:0,s:0,v:0,a:1}}return D}(),S=r.hslStringToHsva=y,k=r.hslaToHsva=function(){function D(M){var O=M.h,R=M.s,F=M.l,W=M.a;return R*=(F<50?F:100-F)/100,{h:O,s:R>0?2*R/(F+R)*100:0,v:F+R,a:W}}return D}(),h=r.hsvaToHex=function(){function D(M){return B(s(M))}return D}(),i=r.hsvaToHsla=function(){function D(M){var O=M.h,R=M.s,F=M.v,W=M.a,U=(200-R)*F/100;return{h:a(O),s:a(U>0&&U<200?R*F/100/(U<=100?U:200-U)*100:0),l:a(U/2),a:a(W,2)}}return D}(),c=r.hsvaToHslString=function(){function D(M){var O=i(M),R=O.h,F=O.s,W=O.l;return"hsl("+R+", "+F+"%, "+W+"%)"}return D}(),m=r.hsvaToHsvString=function(){function D(M){var O=L(M),R=O.h,F=O.s,W=O.v;return"hsv("+R+", "+F+"%, "+W+"%)"}return D}(),l=r.hsvaToHsvaString=function(){function D(M){var O=L(M),R=O.h,F=O.s,W=O.v,U=O.a;return"hsva("+R+", "+F+"%, "+W+"%, "+U+")"}return D}(),u=r.hsvaToHslaString=function(){function D(M){var O=i(M),R=O.h,F=O.s,W=O.l,U=O.a;return"hsla("+R+", "+F+"%, "+W+"%, "+U+")"}return D}(),s=r.hsvaToRgba=function(){function D(M){var O=M.h,R=M.s,F=M.v,W=M.a;O=O/360*6,R=R/100,F=F/100;var U=Math.floor(O),z=F*(1-R),$=F*(1-(O-U)*R),G=F*(1-(1-O+U)*R),X=U%6;return{r:[F,$,z,z,G,F][X]*255,g:[G,F,F,$,z,z][X]*255,b:[z,z,G,F,F,$][X]*255,a:a(W,2)}}return D}(),d=r.hsvaToRgbString=function(){function D(M){var O=s(M),R=O.r,F=O.g,W=O.b;return"rgb("+a(R)+", "+a(F)+", "+a(W)+")"}return D}(),v=r.hsvaToRgbaString=function(){function D(M){var O=s(M),R=O.r,F=O.g,W=O.b,U=O.a;return"rgba("+a(R)+", "+a(F)+", "+a(W)+", "+a(U,2)+")"}return D}(),g=r.hsvaStringToHsva=function(){function D(M){var O=/hsva?\(?\s*(-?\d*\.?\d+)(deg|rad|grad|turn)?[,\s]+(-?\d*\.?\d+)%?[,\s]+(-?\d*\.?\d+)%?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i,R=O.exec(M);return R?L({h:b(R[1],R[2]),s:Number(R[3]),v:Number(R[4]),a:R[5]===void 0?1:Number(R[5])/(R[6]?100:1)}):{h:0,s:0,v:0,a:1}}return D}(),C=r.hsvStringToHsva=g,f=r.rgbaStringToHsva=function(){function D(M){var O=/rgba?\(?\s*(-?\d*\.?\d+)(%)?[,\s]+(-?\d*\.?\d+)(%)?[,\s]+(-?\d*\.?\d+)(%)?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i,R=O.exec(M);return R?I({r:Number(R[1])/(R[2]?100/255:1),g:Number(R[3])/(R[4]?100/255:1),b:Number(R[5])/(R[6]?100/255:1),a:R[7]===void 0?1:Number(R[7])/(R[8]?100:1)}):{h:0,s:0,v:0,a:1}}return D}(),N=r.rgbStringToHsva=f,V=function(M){var O=M.toString(16);return O.length<2?"0"+O:O},B=r.rgbaToHex=function(){function D(M){var O=M.r,R=M.g,F=M.b,W=M.a,U=W<1?V(a(W*255)):"";return"#"+V(a(O))+V(a(R))+V(a(F))+U}return D}(),I=r.rgbaToHsva=function(){function D(M){var O=M.r,R=M.g,F=M.b,W=M.a,U=Math.max(O,R,F),z=U-Math.min(O,R,F),$=z?U===O?(R-F)/z:U===R?2+(F-O)/z:4+(O-R)/z:0;return{h:60*($<0?$+6:$),s:U?z/U*100:0,v:U/255*100,a:W}}return D}(),L=r.roundHsva=function(){function D(M){return{h:a(M.h),s:a(M.s),v:a(M.v),a:a(M.a,2)}}return D}(),w=r.rgbaToRgb=function(){function D(M){var O=M.r,R=M.g,F=M.b;return{r:O,g:R,b:F}}return D}(),A=r.hslaToHsl=function(){function D(M){var O=M.h,R=M.s,F=M.l;return{h:O,s:R,l:F}}return D}(),x=r.hsvaToHsv=function(){function D(M){var O=L(M),R=O.h,F=O.s,W=O.v;return{h:R,s:F,v:W}}return D}(),E=/^#?([0-9A-F]{3,8})$/i,P=r.validHex=function(){function D(M,O){var R=E.exec(M),F=R?R[1].length:0;return F===3||F===6||!!O&&F===4||!!O&&F===8}return D}()},92868:function(T,r){"use strict";r.__esModule=!0,r.EventEmitter=void 0;/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */var n=r.EventEmitter=function(){function e(){this.listeners={}}var a=e.prototype;return a.on=function(){function t(o,p){this.listeners[o]=this.listeners[o]||[],this.listeners[o].push(p)}return t}(),a.off=function(){function t(o,p){var b=this.listeners[o];if(!b)throw new Error('There is no listeners for "'+o+'"');this.listeners[o]=b.filter(function(y){return y!==p})}return t}(),a.emit=function(){function t(o){var p=this.listeners[o];if(p){for(var b=arguments.length,y=new Array(b>1?b-1:0),S=1;S1?S-1:0),h=1;h1?k-1:0),i=1;i>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * All possible browser keycodes, in one file. * * @file * @copyright 2020 Aleksej Komarov * @license MIT +<<<<<<< HEAD */var n=r.KEY_BACKSPACE=8,e=r.KEY_TAB=9,a=r.KEY_ENTER=13,t=r.KEY_SHIFT=16,o=r.KEY_CTRL=17,f=r.KEY_ALT=18,b=r.KEY_PAUSE=19,y=r.KEY_CAPSLOCK=20,I=r.KEY_ESCAPE=27,k=r.KEY_SPACE=32,g=r.KEY_PAGEUP=33,l=r.KEY_PAGEDOWN=34,c=r.KEY_END=35,m=r.KEY_HOME=36,i=r.KEY_LEFT=37,u=r.KEY_UP=38,s=r.KEY_RIGHT=39,d=r.KEY_DOWN=40,v=r.KEY_INSERT=45,h=r.KEY_DELETE=46,C=r.KEY_0=48,p=r.KEY_1=49,N=r.KEY_2=50,V=r.KEY_3=51,S=r.KEY_4=52,B=r.KEY_5=53,L=r.KEY_6=54,w=r.KEY_7=55,A=r.KEY_8=56,x=r.KEY_9=57,E=r.KEY_A=65,P=r.KEY_B=66,D=r.KEY_C=67,M=r.KEY_D=68,R=r.KEY_E=69,O=r.KEY_F=70,F=r.KEY_G=71,_=r.KEY_H=72,U=r.KEY_I=73,z=r.KEY_J=74,$=r.KEY_K=75,G=r.KEY_L=76,X=r.KEY_M=77,J=r.KEY_N=78,se=r.KEY_O=79,ie=r.KEY_P=80,me=r.KEY_Q=81,q=r.KEY_R=82,re=r.KEY_S=83,ae=r.KEY_T=84,le=r.KEY_U=85,Z=r.KEY_V=86,ne=r.KEY_W=87,te=r.KEY_X=88,fe=r.KEY_Y=89,pe=r.KEY_Z=90,ce=r.KEY_NUMPAD_0=96,Ve=r.KEY_NUMPAD_1=97,Ce=r.KEY_NUMPAD_2=98,Ne=r.KEY_NUMPAD_3=99,Be=r.KEY_NUMPAD_4=100,be=r.KEY_NUMPAD_5=101,Le=r.KEY_NUMPAD_6=102,we=r.KEY_NUMPAD_7=103,xe=r.KEY_NUMPAD_8=104,Re=r.KEY_NUMPAD_9=105,He=r.KEY_F1=112,ye=r.KEY_F2=113,de=r.KEY_F3=114,he=r.KEY_F4=115,ke=r.KEY_F5=116,ve=r.KEY_F6=117,Se=r.KEY_F7=118,Pe=r.KEY_F8=119,je=r.KEY_F9=120,Fe=r.KEY_F10=121,ze=r.KEY_F11=122,We=r.KEY_F12=123,Ue=r.KEY_SEMICOLON=186,Xe=r.KEY_EQUAL=187,yt=r.KEY_COMMA=188,St=r.KEY_MINUS=189,Ct=r.KEY_PERIOD=190,Bt=r.KEY_SLASH=191,ut=r.KEY_LEFT_BRACKET=219,rt=r.KEY_BACKSLASH=220,It=r.KEY_RIGHT_BRACKET=221,Lt=r.KEY_QUOTE=222},70611:function(T,r){"use strict";r.__esModule=!0,r.isEscape=r.KEY=void 0;var n=r.KEY=function(a){return a.Alt="Alt",a.Backspace="Backspace",a.Control="Control",a.Delete="Delete",a.Down="Down",a.End="End",a.Enter="Enter",a.Esc="Esc",a.Escape="Escape",a.Home="Home",a.Insert="Insert",a.Left="Left",a.PageDown="PageDown",a.PageUp="PageUp",a.Right="Right",a.Shift="Shift",a.Space=" ",a.Tab="Tab",a.Up="Up",a}({}),e=r.isEscape=function(){function a(t){return t===n.Esc||t===n.Escape}return a}()},44879:function(T,r){"use strict";r.__esModule=!0,r.toFixed=r.scale=r.round=r.rad2deg=r.keyOfMatchingRange=r.inRange=r.clamp01=r.clamp=void 0;/** * @file * @copyright 2020 Aleksej Komarov * @license MIT */var n=r.clamp=function(){function I(k,g,l){return kl?l:k}return I}(),e=r.clamp01=function(){function I(k){return k<0?0:k>1?1:k}return I}(),a=r.scale=function(){function I(k,g,l){return(k-g)/(l-g)}return I}(),t=r.round=function(){function I(k,g){if(!k||isNaN(k))return k;var l,c,m,i;return g|=0,l=Math.pow(10,g),k*=l,i=+(k>0)|-(k<0),m=Math.abs(k%1)>=.4999999999854481,c=Math.floor(k),m&&(k=c+(i>0)),(m?k:Math.round(k))/l}return I}(),o=r.toFixed=function(){function I(k,g){return g===void 0&&(g=0),Number(k).toFixed(Math.max(g,0))}return I}(),f=r.inRange=function(){function I(k,g){return g&&k>=g[0]&&k<=g[1]}return I}(),b=r.keyOfMatchingRange=function(){function I(k,g){for(var l=0,c=Object.keys(g);li?i:k}return S}(),e=r.clamp01=function(){function S(k){return k<0?0:k>1?1:k}return S}(),a=r.scale=function(){function S(k,h,i){return(k-h)/(i-h)}return S}(),t=r.round=function(){function S(k,h){if(!k||isNaN(k))return k;var i,c,m,l;return h|=0,i=Math.pow(10,h),k*=i,l=+(k>0)|-(k<0),m=Math.abs(k%1)>=.4999999999854481,c=Math.floor(k),m&&(k=c+(l>0)),(m?k:Math.round(k))/i}return S}(),o=r.toFixed=function(){function S(k,h){return h===void 0&&(h=0),Number(k).toFixed(Math.max(h,0))}return S}(),p=r.inRange=function(){function S(k,h){return h&&k>=h[0]&&k<=h[1]}return S}(),b=r.keyOfMatchingRange=function(){function S(k,h){for(var i=0,c=Object.keys(h);i>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * Ghetto performance measurement tools. * * Uses NODE_ENV to remove itself from production builds. @@ -32,6 +60,7 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT +<<<<<<< HEAD */var e=60,a=1e3/e,t=!!((n=window.performance)!=null&&n.now),o={},f={},b=function(l,c){},y=function(l,c){if(0)var m,i,u},I=function(l){var c=l/a;return l.toFixed(l<10?1:0)+"ms ("+c.toFixed(2)+" frames)"},k=r.perf={mark:b,measure:y}},35840:function(T,r){"use strict";r.__esModule=!0,r.shallowDiffers=r.pureComponentHooks=r.normalizeChildren=r.classes=r.canRender=void 0;/** * @file * @copyright 2020 Aleksej Komarov @@ -41,11 +70,23 @@ * @copyright 2020 Aleksej Komarov * @license MIT */var a=r.createStore=function(){function I(k,g){if(g)return g(I)(k);var l,c=[],m=function(){function s(){return l}return s}(),i=function(){function s(d){c.push(d)}return s}(),u=function(){function s(d){l=k(l,d);for(var v=0;v1?i-1:0),s=1;s1?V-1:0),B=1;B=0;--pe){var ce=this.tryEntries[pe],Ve=ce.completion;if(ce.tryLoc==="root")return fe("end");if(ce.tryLoc<=this.prev){var Ce=N.call(ce,"catchLoc"),Ne=N.call(ce,"finallyLoc");if(Ce&&Ne){if(this.prev=0;--fe){var pe=this.tryEntries[fe];if(pe.tryLoc<=this.prev&&N.call(pe,"finallyLoc")&&this.prev=0;--te){var fe=this.tryEntries[te];if(fe.finallyLoc===ne)return this.complete(fe.completion,fe.afterLoc),re(fe),O}}return Z}(),catch:function(){function Z(ne){for(var te=this.tryEntries.length-1;te>=0;--te){var fe=this.tryEntries[te];if(fe.tryLoc===ne){var pe=fe.completion;if(pe.type==="throw"){var ce=pe.arg;re(fe)}return ce}}throw Error("illegal catch attempt")}return Z}(),delegateYield:function(){function Z(ne,te,fe){return this.delegate={iterator:le(ne),resultName:te,nextLoc:fe},this.method==="next"&&(this.arg=h),O}return Z}()},C}function e(h,C,p,N,V,S,B){try{var L=h[S](B),w=L.value}catch(A){return void p(A)}L.done?C(w):Promise.resolve(w).then(N,V)}function a(h){return function(){var C=this,p=arguments;return new Promise(function(N,V){var S=h.apply(C,p);function B(w){e(S,N,V,B,L,"next",w)}function L(w){e(S,N,V,B,L,"throw",w)}B(void 0)})}}/** +======= + */var e=60,a=1e3/e,t=!!((n=window.performance)!=null&&n.now),o={},p={},b=function(i,c){},y=function(i,c){if(0)var m,l,u},S=function(i){var c=i/a;return i.toFixed(i<10?1:0)+"ms ("+c.toFixed(2)+" frames)"},k=r.perf={mark:b,measure:y}},35840:function(T,r){"use strict";r.__esModule=!0,r.shallowDiffers=r.pureComponentHooks=r.normalizeChildren=r.classes=r.canRender=void 0;/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */var n=r.classes=function(){function p(b){for(var y="",S=0;S1?l-1:0),s=1;s1?V-1:0),I=1;I=0;--pe){var ce=this.tryEntries[pe],Ve=ce.completion;if(ce.tryLoc==="root")return fe("end");if(ce.tryLoc<=this.prev){var Ce=N.call(ce,"catchLoc"),Ne=N.call(ce,"finallyLoc");if(Ce&&Ne){if(this.prev=0;--fe){var pe=this.tryEntries[fe];if(pe.tryLoc<=this.prev&&N.call(pe,"finallyLoc")&&this.prev=0;--te){var fe=this.tryEntries[te];if(fe.finallyLoc===ne)return this.complete(fe.completion,fe.afterLoc),re(fe),R}}return Z}(),catch:function(){function Z(ne){for(var te=this.tryEntries.length-1;te>=0;--te){var fe=this.tryEntries[te];if(fe.tryLoc===ne){var pe=fe.completion;if(pe.type==="throw"){var ce=pe.arg;re(fe)}return ce}}throw Error("illegal catch attempt")}return Z}(),delegateYield:function(){function Z(ne,te,fe){return this.delegate={iterator:le(ne),resultName:te,nextLoc:fe},this.method==="next"&&(this.arg=g),R}return Z}()},C}function e(g,C,f,N,V,B,I){try{var L=g[B](I),w=L.value}catch(A){return void f(A)}L.done?C(w):Promise.resolve(w).then(N,V)}function a(g){return function(){var C=this,f=arguments;return new Promise(function(N,V){var B=g.apply(C,f);function I(w){e(B,N,V,I,L,"next",w)}function L(w){e(B,N,V,I,L,"throw",w)}I(void 0)})}}/** +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * Browser-agnostic abstraction of key-value web storage. * * @file * @copyright 2020 Aleksej Komarov * @license MIT +<<<<<<< HEAD */var t=r.IMPL_MEMORY=0,o=r.IMPL_HUB_STORAGE=1,f=r.IMPL_INDEXED_DB=2,b=1,y="para-tgui",I="storage-v1",k="readonly",g="readwrite",l=function(C){return function(){try{return!!C()}catch(p){return!1}}},c=l(function(){return window.hubStorage&&window.hubStorage.getItem}),m=l(function(){return(window.indexedDB||window.msIndexedDB)&&(window.IDBTransaction||window.msIDBTransaction)}),i=function(){function h(){this.impl=t,this.store={}}var C=h.prototype;return C.get=function(){var p=a(n().mark(function(){function V(S){return n().wrap(function(){function B(L){for(;;)switch(L.prev=L.next){case 0:return L.abrupt("return",this.store[S]);case 1:case"end":return L.stop()}}return B}(),V,this)}return V}()));function N(V){return p.apply(this,arguments)}return N}(),C.set=function(){var p=a(n().mark(function(){function V(S,B){return n().wrap(function(){function L(w){for(;;)switch(w.prev=w.next){case 0:this.store[S]=B;case 1:case"end":return w.stop()}}return L}(),V,this)}return V}()));function N(V,S){return p.apply(this,arguments)}return N}(),C.remove=function(){var p=a(n().mark(function(){function V(S){return n().wrap(function(){function B(L){for(;;)switch(L.prev=L.next){case 0:this.store[S]=void 0;case 1:case"end":return L.stop()}}return B}(),V,this)}return V}()));function N(V){return p.apply(this,arguments)}return N}(),C.clear=function(){var p=a(n().mark(function(){function V(){return n().wrap(function(){function S(B){for(;;)switch(B.prev=B.next){case 0:this.store={};case 1:case"end":return B.stop()}}return S}(),V,this)}return V}()));function N(){return p.apply(this,arguments)}return N}(),h}(),u=function(){function h(){this.impl=o}var C=h.prototype;return C.get=function(){var p=a(n().mark(function(){function V(S){var B;return n().wrap(function(){function L(w){for(;;)switch(w.prev=w.next){case 0:return w.next=2,window.hubStorage.getItem("paradise-"+S);case 2:if(B=w.sent,typeof B!="string"){w.next=5;break}return w.abrupt("return",JSON.parse(B));case 5:case"end":return w.stop()}}return L}(),V)}return V}()));function N(V){return p.apply(this,arguments)}return N}(),C.set=function(){function p(N,V){window.hubStorage.setItem("paradise-"+N,JSON.stringify(V))}return p}(),C.remove=function(){function p(N){window.hubStorage.removeItem("paradise-"+N)}return p}(),C.clear=function(){function p(){window.hubStorage.clear()}return p}(),h}(),s=function(){function h(){this.impl=f,this.dbPromise=new Promise(function(p,N){var V=window.indexedDB||window.msIndexedDB,S=V.open(y,b);S.onupgradeneeded=function(){try{S.result.createObjectStore(I)}catch(B){N(new Error("Failed to upgrade IDB: "+S.error))}},S.onsuccess=function(){return p(S.result)},S.onerror=function(){N(new Error("Failed to open IDB: "+S.error))}})}var C=h.prototype;return C.getStore=function(){var p=a(n().mark(function(){function V(S){return n().wrap(function(){function B(L){for(;;)switch(L.prev=L.next){case 0:return L.abrupt("return",this.dbPromise.then(function(w){return w.transaction(I,S).objectStore(I)}));case 1:case"end":return L.stop()}}return B}(),V,this)}return V}()));function N(V){return p.apply(this,arguments)}return N}(),C.get=function(){var p=a(n().mark(function(){function V(S){var B;return n().wrap(function(){function L(w){for(;;)switch(w.prev=w.next){case 0:return w.next=2,this.getStore(k);case 2:return B=w.sent,w.abrupt("return",new Promise(function(A,x){var E=B.get(S);E.onsuccess=function(){return A(E.result)},E.onerror=function(){return x(E.error)}}));case 4:case"end":return w.stop()}}return L}(),V,this)}return V}()));function N(V){return p.apply(this,arguments)}return N}(),C.set=function(){var p=a(n().mark(function(){function V(S,B){var L;return n().wrap(function(){function w(A){for(;;)switch(A.prev=A.next){case 0:return A.next=2,this.getStore(g);case 2:L=A.sent,L.put(B,S);case 4:case"end":return A.stop()}}return w}(),V,this)}return V}()));function N(V,S){return p.apply(this,arguments)}return N}(),C.remove=function(){var p=a(n().mark(function(){function V(S){var B;return n().wrap(function(){function L(w){for(;;)switch(w.prev=w.next){case 0:return w.next=2,this.getStore(g);case 2:B=w.sent,B.delete(S);case 4:case"end":return w.stop()}}return L}(),V,this)}return V}()));function N(V){return p.apply(this,arguments)}return N}(),C.clear=function(){var p=a(n().mark(function(){function V(){var S;return n().wrap(function(){function B(L){for(;;)switch(L.prev=L.next){case 0:return L.next=2,this.getStore(g);case 2:S=L.sent,S.clear();case 4:case"end":return L.stop()}}return B}(),V,this)}return V}()));function N(){return p.apply(this,arguments)}return N}(),h}(),d=function(){function h(){this.backendPromise=a(n().mark(function(){function p(){var N;return n().wrap(function(){function V(S){for(;;)switch(S.prev=S.next){case 0:if(!(!Byond.TRIDENT&&c())){S.next=2;break}return S.abrupt("return",new u);case 2:if(!m()){S.next=12;break}return S.prev=3,N=new s,S.next=7,N.dbPromise;case 7:return S.abrupt("return",N);case 10:S.prev=10,S.t0=S.catch(3);case 12:return S.abrupt("return",new i);case 13:case"end":return S.stop()}}return V}(),p,null,[[3,10]])}return p}()))()}var C=h.prototype;return C.get=function(){var p=a(n().mark(function(){function V(S){var B;return n().wrap(function(){function L(w){for(;;)switch(w.prev=w.next){case 0:return w.next=2,this.backendPromise;case 2:return B=w.sent,w.abrupt("return",B.get(S));case 4:case"end":return w.stop()}}return L}(),V,this)}return V}()));function N(V){return p.apply(this,arguments)}return N}(),C.set=function(){var p=a(n().mark(function(){function V(S,B){var L;return n().wrap(function(){function w(A){for(;;)switch(A.prev=A.next){case 0:return A.next=2,this.backendPromise;case 2:return L=A.sent,A.abrupt("return",L.set(S,B));case 4:case"end":return A.stop()}}return w}(),V,this)}return V}()));function N(V,S){return p.apply(this,arguments)}return N}(),C.remove=function(){var p=a(n().mark(function(){function V(S){var B;return n().wrap(function(){function L(w){for(;;)switch(w.prev=w.next){case 0:return w.next=2,this.backendPromise;case 2:return B=w.sent,w.abrupt("return",B.remove(S));case 4:case"end":return w.stop()}}return L}(),V,this)}return V}()));function N(V){return p.apply(this,arguments)}return N}(),C.clear=function(){var p=a(n().mark(function(){function V(){var S;return n().wrap(function(){function B(L){for(;;)switch(L.prev=L.next){case 0:return L.next=2,this.backendPromise;case 2:return S=L.sent,L.abrupt("return",S.clear());case 4:case"end":return L.stop()}}return B}(),V,this)}return V}()));function N(){return p.apply(this,arguments)}return N}(),h}(),v=r.storage=new d},25328:function(T,r){"use strict";r.__esModule=!0,r.toTitleCase=r.multiline=r.decodeHtmlEntities=r.createSearch=r.createGlobPattern=r.capitalize=r.buildQueryString=void 0;function n(g,l){var c=typeof Symbol!="undefined"&&g[Symbol.iterator]||g["@@iterator"];if(c)return(c=c.call(g)).next.bind(c);if(Array.isArray(g)||(c=e(g))||l&&g&&typeof g.length=="number"){c&&(g=c);var m=0;return function(){return m>=g.length?{done:!0}:{done:!1,value:g[m++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function e(g,l){if(g){if(typeof g=="string")return a(g,l);var c={}.toString.call(g).slice(8,-1);return c==="Object"&&g.constructor&&(c=g.constructor.name),c==="Map"||c==="Set"?Array.from(g):c==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c)?a(g,l):void 0}}function a(g,l){(l==null||l>g.length)&&(l=g.length);for(var c=0,m=Array(l);c=f)o.apply(null,g),b=c;else{var m;y=setTimeout(function(){return I.apply(void 0,g)},f-(c-((m=b)!=null?m:0)))}}return I}()}return t}()},97450:function(T,r,n){"use strict";r.__esModule=!0,r.vecSubtract=r.vecScale=r.vecNormalize=r.vecMultiply=r.vecLength=r.vecInverse=r.vecDivide=r.vecAdd=void 0;var e=n(88510);/** +======= + */var t=r.IMPL_MEMORY=0,o=r.IMPL_HUB_STORAGE=1,p=r.IMPL_INDEXED_DB=2,b=1,y="para-tgui",S="storage-v1",k="readonly",h="readwrite",i=function(C){return function(){try{return!!C()}catch(f){return!1}}},c=i(function(){return window.hubStorage&&window.hubStorage.getItem}),m=i(function(){return(window.indexedDB||window.msIndexedDB)&&(window.IDBTransaction||window.msIDBTransaction)}),l=function(){function g(){this.impl=t,this.store={}}var C=g.prototype;return C.get=function(){var f=a(n().mark(function(){function V(B){return n().wrap(function(){function I(L){for(;;)switch(L.prev=L.next){case 0:return L.abrupt("return",this.store[B]);case 1:case"end":return L.stop()}}return I}(),V,this)}return V}()));function N(V){return f.apply(this,arguments)}return N}(),C.set=function(){var f=a(n().mark(function(){function V(B,I){return n().wrap(function(){function L(w){for(;;)switch(w.prev=w.next){case 0:this.store[B]=I;case 1:case"end":return w.stop()}}return L}(),V,this)}return V}()));function N(V,B){return f.apply(this,arguments)}return N}(),C.remove=function(){var f=a(n().mark(function(){function V(B){return n().wrap(function(){function I(L){for(;;)switch(L.prev=L.next){case 0:this.store[B]=void 0;case 1:case"end":return L.stop()}}return I}(),V,this)}return V}()));function N(V){return f.apply(this,arguments)}return N}(),C.clear=function(){var f=a(n().mark(function(){function V(){return n().wrap(function(){function B(I){for(;;)switch(I.prev=I.next){case 0:this.store={};case 1:case"end":return I.stop()}}return B}(),V,this)}return V}()));function N(){return f.apply(this,arguments)}return N}(),g}(),u=function(){function g(){this.impl=o}var C=g.prototype;return C.get=function(){var f=a(n().mark(function(){function V(B){var I;return n().wrap(function(){function L(w){for(;;)switch(w.prev=w.next){case 0:return w.next=2,window.hubStorage.getItem("paradise-"+B);case 2:if(I=w.sent,typeof I!="string"){w.next=5;break}return w.abrupt("return",JSON.parse(I));case 5:case"end":return w.stop()}}return L}(),V)}return V}()));function N(V){return f.apply(this,arguments)}return N}(),C.set=function(){function f(N,V){window.hubStorage.setItem("paradise-"+N,JSON.stringify(V))}return f}(),C.remove=function(){function f(N){window.hubStorage.removeItem("paradise-"+N)}return f}(),C.clear=function(){function f(){window.hubStorage.clear()}return f}(),g}(),s=function(){function g(){this.impl=p,this.dbPromise=new Promise(function(f,N){var V=window.indexedDB||window.msIndexedDB,B=V.open(y,b);B.onupgradeneeded=function(){try{B.result.createObjectStore(S)}catch(I){N(new Error("Failed to upgrade IDB: "+B.error))}},B.onsuccess=function(){return f(B.result)},B.onerror=function(){N(new Error("Failed to open IDB: "+B.error))}})}var C=g.prototype;return C.getStore=function(){var f=a(n().mark(function(){function V(B){return n().wrap(function(){function I(L){for(;;)switch(L.prev=L.next){case 0:return L.abrupt("return",this.dbPromise.then(function(w){return w.transaction(S,B).objectStore(S)}));case 1:case"end":return L.stop()}}return I}(),V,this)}return V}()));function N(V){return f.apply(this,arguments)}return N}(),C.get=function(){var f=a(n().mark(function(){function V(B){var I;return n().wrap(function(){function L(w){for(;;)switch(w.prev=w.next){case 0:return w.next=2,this.getStore(k);case 2:return I=w.sent,w.abrupt("return",new Promise(function(A,x){var E=I.get(B);E.onsuccess=function(){return A(E.result)},E.onerror=function(){return x(E.error)}}));case 4:case"end":return w.stop()}}return L}(),V,this)}return V}()));function N(V){return f.apply(this,arguments)}return N}(),C.set=function(){var f=a(n().mark(function(){function V(B,I){var L;return n().wrap(function(){function w(A){for(;;)switch(A.prev=A.next){case 0:return A.next=2,this.getStore(h);case 2:L=A.sent,L.put(I,B);case 4:case"end":return A.stop()}}return w}(),V,this)}return V}()));function N(V,B){return f.apply(this,arguments)}return N}(),C.remove=function(){var f=a(n().mark(function(){function V(B){var I;return n().wrap(function(){function L(w){for(;;)switch(w.prev=w.next){case 0:return w.next=2,this.getStore(h);case 2:I=w.sent,I.delete(B);case 4:case"end":return w.stop()}}return L}(),V,this)}return V}()));function N(V){return f.apply(this,arguments)}return N}(),C.clear=function(){var f=a(n().mark(function(){function V(){var B;return n().wrap(function(){function I(L){for(;;)switch(L.prev=L.next){case 0:return L.next=2,this.getStore(h);case 2:B=L.sent,B.clear();case 4:case"end":return L.stop()}}return I}(),V,this)}return V}()));function N(){return f.apply(this,arguments)}return N}(),g}(),d=function(){function g(){this.backendPromise=a(n().mark(function(){function f(){var N;return n().wrap(function(){function V(B){for(;;)switch(B.prev=B.next){case 0:if(!(!Byond.TRIDENT&&c())){B.next=2;break}return B.abrupt("return",new u);case 2:if(!m()){B.next=12;break}return B.prev=3,N=new s,B.next=7,N.dbPromise;case 7:return B.abrupt("return",N);case 10:B.prev=10,B.t0=B.catch(3);case 12:return B.abrupt("return",new l);case 13:case"end":return B.stop()}}return V}(),f,null,[[3,10]])}return f}()))()}var C=g.prototype;return C.get=function(){var f=a(n().mark(function(){function V(B){var I;return n().wrap(function(){function L(w){for(;;)switch(w.prev=w.next){case 0:return w.next=2,this.backendPromise;case 2:return I=w.sent,w.abrupt("return",I.get(B));case 4:case"end":return w.stop()}}return L}(),V,this)}return V}()));function N(V){return f.apply(this,arguments)}return N}(),C.set=function(){var f=a(n().mark(function(){function V(B,I){var L;return n().wrap(function(){function w(A){for(;;)switch(A.prev=A.next){case 0:return A.next=2,this.backendPromise;case 2:return L=A.sent,A.abrupt("return",L.set(B,I));case 4:case"end":return A.stop()}}return w}(),V,this)}return V}()));function N(V,B){return f.apply(this,arguments)}return N}(),C.remove=function(){var f=a(n().mark(function(){function V(B){var I;return n().wrap(function(){function L(w){for(;;)switch(w.prev=w.next){case 0:return w.next=2,this.backendPromise;case 2:return I=w.sent,w.abrupt("return",I.remove(B));case 4:case"end":return w.stop()}}return L}(),V,this)}return V}()));function N(V){return f.apply(this,arguments)}return N}(),C.clear=function(){var f=a(n().mark(function(){function V(){var B;return n().wrap(function(){function I(L){for(;;)switch(L.prev=L.next){case 0:return L.next=2,this.backendPromise;case 2:return B=L.sent,L.abrupt("return",B.clear());case 4:case"end":return L.stop()}}return I}(),V,this)}return V}()));function N(){return f.apply(this,arguments)}return N}(),g}(),v=r.storage=new d},25328:function(T,r){"use strict";r.__esModule=!0,r.toTitleCase=r.multiline=r.decodeHtmlEntities=r.createSearch=r.createGlobPattern=r.capitalize=r.buildQueryString=void 0;function n(h,i){var c=typeof Symbol!="undefined"&&h[Symbol.iterator]||h["@@iterator"];if(c)return(c=c.call(h)).next.bind(c);if(Array.isArray(h)||(c=e(h))||i&&h&&typeof h.length=="number"){c&&(h=c);var m=0;return function(){return m>=h.length?{done:!0}:{done:!1,value:h[m++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function e(h,i){if(h){if(typeof h=="string")return a(h,i);var c={}.toString.call(h).slice(8,-1);return c==="Object"&&h.constructor&&(c=h.constructor.name),c==="Map"||c==="Set"?Array.from(h):c==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c)?a(h,i):void 0}}function a(h,i){(i==null||i>h.length)&&(i=h.length);for(var c=0,m=Array(i);c",apos:"'"};return i.replace(/
    /gi,"\n").replace(/<\/?[a-z0-9-_]+[^>]*>/gi,"").replace(c,function(l,u){return m[u]}).replace(/&#?([0-9]+);/gi,function(l,u){var s=parseInt(u,10);return String.fromCharCode(s)}).replace(/&#x?([0-9a-f]+);/gi,function(l,u){var s=parseInt(u,16);return String.fromCharCode(s)})}return h}(),k=r.buildQueryString=function(){function h(i){return Object.keys(i).map(function(c){return encodeURIComponent(c)+"="+encodeURIComponent(i[c])}).join("&")}return h}()},69214:function(T,r){"use strict";r.__esModule=!0,r.throttle=r.sleep=r.debounce=void 0;/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */var n=r.debounce=function(){function t(o,p,b){b===void 0&&(b=!1);var y;return function(){for(var S=arguments.length,k=new Array(S),h=0;h=p)o.apply(null,h),b=c;else{var m;y=setTimeout(function(){return S.apply(void 0,h)},p-(c-((m=b)!=null?m:0)))}}return S}()}return t}()},97450:function(T,r,n){"use strict";r.__esModule=!0,r.vecSubtract=r.vecScale=r.vecNormalize=r.vecMultiply=r.vecLength=r.vecInverse=r.vecDivide=r.vecAdd=void 0;var e=n(88510);/** +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * N-dimensional vector manipulation functions. * * Vectors are plain number arrays, i.e. [x, y, z]. @@ -62,11 +114,19 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT +<<<<<<< HEAD */var a=function(u,s){return u+s},t=function(u,s){return u-s},o=function(u,s){return u*s},f=function(u,s){return u/s},b=r.vecAdd=function(){function i(){for(var u=arguments.length,s=new Array(u),d=0;d>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * This file provides a clear separation layer between backend updates * and what state our React app sees. * @@ -77,6 +137,7 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT +<<<<<<< HEAD */var y=(0,f.createLogger)("backend"),I=r.backendUpdate=(0,a.createAction)("backend/update"),k=r.backendSetSharedState=(0,a.createAction)("backend/setSharedState"),g=r.backendSuspendStart=(0,a.createAction)("backend/suspendStart"),l=r.backendSuspendSuccess=function(){function C(){return{type:"backend/suspendSuccess",payload:{timestamp:Date.now()}}}return C}(),c={config:{},data:{},shared:{},suspended:Date.now(),suspending:!1},m=r.backendReducer=function(){function C(p,N){p===void 0&&(p=c);var V=N.type,S=N.payload;if(V==="backend/update"){var B=Object.assign({},p.config,S.config),L=Object.assign({},p.data,S.static_data,S.data),w=Object.assign({},p.shared);if(S.shared)for(var A=0,x=Object.keys(S.shared);A0&&(N.style=x),N}return C}(),v=r.computeBoxClassName=function(){function C(f){var N=f.textColor||f.color,V=f.backgroundColor;return(0,e.classes)([h(N)&&"color-"+N,h(V)&&"color-bg-"+V])}return C}(),g=r.Box=function(){function C(f){var N=f.as,V=N===void 0?"div":N,B=f.className,I=f.children,L=b(f,p);if(typeof I=="function")return I(d(f));var w=typeof B=="string"?B+" "+v(L):v(L),A=d(L);return(0,a.createVNode)(t.VNodeFlags.HtmlElement,V,w,I,t.ChildFlags.UnknownChildren,A)}return C}();g.defaultHooks=e.pureComponentHooks},96184:function(T,r,n){"use strict";r.__esModule=!0,r.ButtonInput=r.ButtonConfirm=r.ButtonCheckbox=r.Button=void 0;var e=n(89005),a=n(35840),t=n(92986),o=n(9394),p=n(55937),b=n(1331),y=n(62147),S=["className","fluid","translucent","icon","iconRotation","iconSpin","color","textColor","disabled","selected","tooltip","tooltipPosition","ellipsis","compact","circular","content","iconColor","iconRight","iconStyle","children","onclick","onClick","multiLine"],k=["checked"],h=["confirmContent","confirmColor","confirmIcon","icon","color","content","onClick"],i=["fluid","content","icon","iconRotation","iconSpin","tooltip","tooltipPosition","color","disabled","multiLine"];/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */function c(C,f){C.prototype=Object.create(f.prototype),C.prototype.constructor=C,m(C,f)}function m(C,f){return m=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(N,V){return N.__proto__=V,N},m(C,f)}function l(C,f){if(C==null)return{};var N={};for(var V in C)if({}.hasOwnProperty.call(C,V)){if(f.includes(V))continue;N[V]=C[V]}return N}var u=(0,o.createLogger)("Button"),s=r.Button=function(){function C(f){var N=f.className,V=f.fluid,B=f.translucent,I=f.icon,L=f.iconRotation,w=f.iconSpin,A=f.color,x=f.textColor,E=f.disabled,P=f.selected,D=f.tooltip,M=f.tooltipPosition,O=f.ellipsis,R=f.compact,F=f.circular,W=f.content,U=f.iconColor,z=f.iconRight,$=f.iconStyle,G=f.children,X=f.onclick,J=f.onClick,se=f.multiLine,ie=l(f,S),me=!!(W||G);X&&u.warn("Lowercase 'onclick' is not supported on Button and lowercase prop names are discouraged in general. Please use a camelCase'onClick' instead and read: https://infernojs.org/docs/guides/event-handling"),ie.onClick=function(re){!E&&J&&J(re)};var q=(0,e.normalizeProps)((0,e.createComponentVNode)(2,p.Box,Object.assign({className:(0,a.classes)(["Button",V&&"Button--fluid",E&&"Button--disabled"+(B?"--translucent":""),P&&"Button--selected"+(B?"--translucent":""),me&&"Button--hasContent",O&&"Button--ellipsis",F&&"Button--circular",R&&"Button--compact",z&&"Button--iconRight",se&&"Button--multiLine",A&&typeof A=="string"?"Button--color--"+A+(B?"--translucent":""):"Button--color--default"+(B?"--translucent":""),N]),tabIndex:!E&&"0",color:x,onKeyDown:function(){function re(ae){var le=window.event?ae.which:ae.keyCode;if(le===t.KEY_SPACE||le===t.KEY_ENTER){ae.preventDefault(),!E&&J&&J(ae);return}if(le===t.KEY_ESCAPE){ae.preventDefault();return}}return re}()},ie,{children:[I&&!z&&(0,e.createComponentVNode)(2,b.Icon,{name:I,color:U,rotation:L,spin:w,style:$}),W,G,I&&z&&(0,e.createComponentVNode)(2,b.Icon,{name:I,color:U,rotation:L,spin:w,style:$})]})));return D&&(q=(0,e.createComponentVNode)(2,y.Tooltip,{content:D,position:M,children:q})),q}return C}();s.defaultHooks=a.pureComponentHooks;var d=r.ButtonCheckbox=function(){function C(f){var N=f.checked,V=l(f,k);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,s,Object.assign({color:"transparent",icon:N?"check-square-o":"square-o",selected:N},V)))}return C}();s.Checkbox=d;var v=r.ButtonConfirm=function(C){function f(){var V;return V=C.call(this)||this,V.handleClick=function(){V.state.clickedOnce&&V.setClickedOnce(!1)},V.state={clickedOnce:!1},V}c(f,C);var N=f.prototype;return N.setClickedOnce=function(){function V(B){var I=this;this.setState({clickedOnce:B}),B?setTimeout(function(){return window.addEventListener("click",I.handleClick)}):window.removeEventListener("click",this.handleClick)}return V}(),N.render=function(){function V(){var B=this,I=this.props,L=I.confirmContent,w=L===void 0?"Confirm?":L,A=I.confirmColor,x=A===void 0?"bad":A,E=I.confirmIcon,P=I.icon,D=I.color,M=I.content,O=I.onClick,R=l(I,h);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,s,Object.assign({content:this.state.clickedOnce?w:M,icon:this.state.clickedOnce?E:P,color:this.state.clickedOnce?x:D,onClick:function(){function F(W){return B.state.clickedOnce?O==null?void 0:O(W):B.setClickedOnce(!0)}return F}()},R)))}return V}(),f}(e.Component);s.Confirm=v;var g=r.ButtonInput=function(C){function f(){var V;return V=C.call(this)||this,V.inputRef=void 0,V.inputRef=(0,e.createRef)(),V.state={inInput:!1},V}c(f,C);var N=f.prototype;return N.setInInput=function(){function V(B){var I=this.props.disabled;if(!I&&(this.setState({inInput:B}),this.inputRef)){var L=this.inputRef.current;if(B){L.value=this.props.currentValue||"";try{L.focus(),L.select()}catch(w){}}}}return V}(),N.commitResult=function(){function V(B){if(this.inputRef){var I=this.inputRef.current,L=I.value!=="";if(L){this.props.onCommit(B,I.value);return}else{if(!this.props.defaultValue)return;this.props.onCommit(B,this.props.defaultValue)}}}return V}(),N.render=function(){function V(){var B=this,I=this.props,L=I.fluid,w=I.content,A=I.icon,x=I.iconRotation,E=I.iconSpin,P=I.tooltip,D=I.tooltipPosition,M=I.color,O=M===void 0?"default":M,R=I.disabled,F=I.multiLine,W=l(I,i),U=(0,e.normalizeProps)((0,e.createComponentVNode)(2,p.Box,Object.assign({className:(0,a.classes)(["Button",L&&"Button--fluid",R&&"Button--disabled","Button--color--"+O,F+"Button--multiLine"])},W,{onClick:function(){function z(){return B.setInInput(!0)}return z}(),children:[A&&(0,e.createComponentVNode)(2,b.Icon,{name:A,rotation:x,spin:E}),(0,e.createVNode)(1,"div",null,w,0),(0,e.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:this.state.inInput?void 0:"none","text-align":"left"},onBlur:function(){function z($){B.state.inInput&&(B.setInInput(!1),B.commitResult($))}return z}(),onKeyDown:function(){function z($){if($.keyCode===t.KEY_ENTER){B.setInInput(!1),B.commitResult($);return}$.keyCode===t.KEY_ESCAPE&&B.setInInput(!1)}return z}()},null,this.inputRef)]})));return P&&(U=(0,e.createComponentVNode)(2,y.Tooltip,{content:P,position:D,children:U})),U}return V}(),f}(e.Component);s.Input=g},18982:function(T,r,n){"use strict";r.__esModule=!0,r.ByondUi=void 0;var e=n(89005),a=n(35840),t=n(69214),o=n(9394),p=n(55937),b=["params"],y=["params"],S=["parent","params"];function k(v,g){if(v==null)return{};var C={};for(var f in v)if({}.hasOwnProperty.call(v,f)){if(g.includes(f))continue;C[f]=v[f]}return C}function h(v,g){v.prototype=Object.create(g.prototype),v.prototype.constructor=v,i(v,g)}function i(v,g){return i=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(C,f){return C.__proto__=f,C},i(v,g)}/** +* @file +* @copyright 2020 Aleksej Komarov +* @license MIT +*/var c=(0,o.createLogger)("ByondUi"),m=[],l=function(g){var C=m.length;m.push(null);var f=g||"byondui_"+C;return c.log("allocated '"+f+"'"),{render:function(){function N(V){c.log("rendering '"+f+"'"),m[C]=f,Byond.winset(f,V)}return N}(),unmount:function(){function N(){c.log("unmounting '"+f+"'"),m[C]=null,Byond.winset(f,{parent:""})}return N}()}};window.addEventListener("beforeunload",function(){for(var v=0;v0){var M=D[0],O=D[D.length-1];D.push([P[0]+x,O[1]]),D.push([P[0]+x,-x]),D.push([-x,-x]),D.push([-x,M[1]])}var R=h(D);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Box,Object.assign({position:"relative"},E,{children:function(){function F(W){return(0,e.normalizeProps)((0,e.createVNode)(1,"div",null,(0,e.createVNode)(32,"svg",null,(0,e.createVNode)(32,"polyline",null,null,1,{transform:"scale(1, -1) translate(0, -"+P[1]+")",fill:I,stroke:w,"stroke-width":x,points:R}),2,{viewBox:"0 0 "+P[0]+" "+P[1],preserveAspectRatio:"none",style:{position:"absolute",top:0,left:0,right:0,bottom:0,overflow:"hidden"}}),2,Object.assign({},W),null,v.ref))}return F}()})))}return d}(),u}(e.Component);i.defaultHooks=t.pureComponentHooks;var c=function(u){return null},m=r.Chart={Line:i}},4796:function(T,r,n){"use strict";r.__esModule=!0,r.Collapsible=void 0;var e=n(89005),a=n(55937),t=n(96184),o=["children","color","title","buttons","contentStyle"];function p(k,h){if(k==null)return{};var i={};for(var c in k)if({}.hasOwnProperty.call(k,c)){if(h.includes(c))continue;i[c]=k[c]}return i}function b(k,h){k.prototype=Object.create(h.prototype),k.prototype.constructor=k,y(k,h)}function y(k,h){return y=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(i,c){return i.__proto__=c,i},y(k,h)}/** +* @file +* @copyright 2020 Aleksej Komarov +* @license MIT +*/var S=r.Collapsible=function(k){function h(c){var m;m=k.call(this,c)||this;var l=c.open;return m.state={open:l||!1},m}b(h,k);var i=h.prototype;return i.render=function(){function c(){var m=this,l=this.props,u=this.state.open,s=l.children,d=l.color,v=d===void 0?"default":d,g=l.title,C=l.buttons,f=l.contentStyle,N=p(l,o);return(0,e.createComponentVNode)(2,a.Box,{className:"Collapsible",children:[(0,e.createVNode)(1,"div","Table",[(0,e.createVNode)(1,"div","Table__cell",(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.Button,Object.assign({fluid:!0,color:v,icon:u?"chevron-down":"chevron-right",onClick:function(){function V(){return m.setState({open:!u})}return V}()},N,{children:g}))),2),C&&(0,e.createVNode)(1,"div","Table__cell Table__cell--collapsing",C,0)],0),u&&(0,e.createComponentVNode)(2,a.Box,{mt:1,style:f,children:s})]})}return c}(),h}(e.Component)},88894:function(T,r,n){"use strict";r.__esModule=!0,r.ColorBox=void 0;var e=n(89005),a=n(35840),t=n(55937),o=["content","children","className","color","backgroundColor"];/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */function p(y,S){if(y==null)return{};var k={};for(var h in y)if({}.hasOwnProperty.call(y,h)){if(S.includes(h))continue;k[h]=y[h]}return k}var b=r.ColorBox=function(){function y(S){var k=S.content,h=S.children,i=S.className,c=S.color,m=S.backgroundColor,l=p(S,o);return l.color=k?null:"transparent",l.backgroundColor=c||m,(0,e.normalizeProps)((0,e.createVNode)(1,"div",(0,a.classes)(["ColorBox",i,(0,t.computeBoxClassName)(l)]),k||".",0,Object.assign({},(0,t.computeBoxProps)(l))))}return y}();b.defaultHooks=a.pureComponentHooks},73379:function(T,r,n){"use strict";r.__esModule=!0,r.Countdown=void 0;var e=n(89005),a=n(55937),t=["format"];function o(S,k){if(S==null)return{};var h={};for(var i in S)if({}.hasOwnProperty.call(S,i)){if(k.includes(i))continue;h[i]=S[i]}return h}function p(S,k){S.prototype=Object.create(k.prototype),S.prototype.constructor=S,b(S,k)}function b(S,k){return b=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(h,i){return h.__proto__=i,h},b(S,k)}var y=r.Countdown=function(S){function k(i){var c;return c=S.call(this,i)||this,c.timer=null,c.state={value:Math.max(i.timeLeft*100,0)},c}p(k,S);var h=k.prototype;return h.tick=function(){function i(){var c=Math.max(this.state.value-this.props.rate,0);c<=0&&clearInterval(this.timer),this.setState(function(m){return{value:c}})}return i}(),h.componentDidMount=function(){function i(){var c=this;this.timer=setInterval(function(){return c.tick()},this.props.rate)}return i}(),h.componentWillUnmount=function(){function i(){clearInterval(this.timer)}return i}(),h.componentDidUpdate=function(){function i(c){var m=this;this.props.current!==c.current&&this.setState(function(l){return{value:Math.max(m.props.timeLeft*100,0)}}),this.timer||this.componentDidMount()}return i}(),h.render=function(){function i(){var c=this.props,m=c.format,l=o(c,t),u=new Date(this.state.value).toISOString().slice(11,19);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,a.Box,Object.assign({as:"span"},l,{children:m?m(this.state.value,u):u})))}return i}(),k}(e.Component);y.defaultProps={rate:1e3}},61940:function(T,r,n){"use strict";r.__esModule=!0,r.Dimmer=void 0;var e=n(89005),a=n(35840),t=n(55937),o=["className","children"];/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */function p(y,S){if(y==null)return{};var k={};for(var h in y)if({}.hasOwnProperty.call(y,h)){if(S.includes(h))continue;k[h]=y[h]}return k}var b=r.Dimmer=function(){function y(S){var k=S.className,h=S.children,i=p(S,o);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.Box,Object.assign({className:(0,a.classes)(["Dimmer"].concat(k))},i,{children:(0,e.createVNode)(1,"div","Dimmer__inner",h,0)})))}return y}()},13605:function(T,r,n){"use strict";r.__esModule=!0,r.Divider=void 0;var e=n(89005),a=n(35840);/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */var t=r.Divider=function(){function o(p){var b=p.vertical,y=p.hidden;return(0,e.createVNode)(1,"div",(0,a.classes)(["Divider",y&&"Divider--hidden",b?"Divider--vertical":"Divider--horizontal"]))}return o}()},60218:function(T,r,n){"use strict";r.__esModule=!0,r.DmIcon=void 0;var e=n(89005),a=n(79140),t=n(46085),o=n(91225),p=["className","direction","fallback","frame","icon_state","movement"];function b(u,s){if(u==null)return{};var d={};for(var v in u)if({}.hasOwnProperty.call(u,v)){if(s.includes(v))continue;d[v]=u[v]}return d}function y(){"use strict";/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */y=function(){return s};var u,s={},d=Object.prototype,v=d.hasOwnProperty,g=Object.defineProperty||function(q,re,ae){q[re]=ae.value},C=typeof Symbol=="function"?Symbol:{},f=C.iterator||"@@iterator",N=C.asyncIterator||"@@asyncIterator",V=C.toStringTag||"@@toStringTag";function B(q,re,ae){return Object.defineProperty(q,re,{value:ae,enumerable:!0,configurable:!0,writable:!0}),q[re]}try{B({},"")}catch(q){B=function(ae,le,Z){return ae[le]=Z}}function I(q,re,ae,le){var Z=re&&re.prototype instanceof D?re:D,ne=Object.create(Z.prototype),te=new ie(le||[]);return g(ne,"_invoke",{value:G(q,ae,te)}),ne}function L(q,re,ae){try{return{type:"normal",arg:q.call(re,ae)}}catch(le){return{type:"throw",arg:le}}}s.wrap=I;var w="suspendedStart",A="suspendedYield",x="executing",E="completed",P={};function D(){}function M(){}function O(){}var R={};B(R,f,function(){return this});var F=Object.getPrototypeOf,W=F&&F(F(me([])));W&&W!==d&&v.call(W,f)&&(R=W);var U=O.prototype=D.prototype=Object.create(R);function z(q){["next","throw","return"].forEach(function(re){B(q,re,function(ae){return this._invoke(re,ae)})})}function $(q,re){function ae(Z,ne,te,fe){var pe=L(q[Z],q,ne);if(pe.type!=="throw"){var ce=pe.arg,Ve=ce.value;return Ve&&typeof Ve=="object"&&v.call(Ve,"__await")?re.resolve(Ve.__await).then(function(Ce){ae("next",Ce,te,fe)},function(Ce){ae("throw",Ce,te,fe)}):re.resolve(Ve).then(function(Ce){ce.value=Ce,te(ce)},function(Ce){return ae("throw",Ce,te,fe)})}fe(pe.arg)}var le;g(this,"_invoke",{value:function(){function Z(ne,te){function fe(){return new re(function(pe,ce){ae(ne,te,pe,ce)})}return le=le?le.then(fe,fe):fe()}return Z}()})}function G(q,re,ae){var le=w;return function(Z,ne){if(le===x)throw Error("Generator is already running");if(le===E){if(Z==="throw")throw ne;return{value:u,done:!0}}for(ae.method=Z,ae.arg=ne;;){var te=ae.delegate;if(te){var fe=X(te,ae);if(fe){if(fe===P)continue;return fe}}if(ae.method==="next")ae.sent=ae._sent=ae.arg;else if(ae.method==="throw"){if(le===w)throw le=E,ae.arg;ae.dispatchException(ae.arg)}else ae.method==="return"&&ae.abrupt("return",ae.arg);le=x;var pe=L(q,re,ae);if(pe.type==="normal"){if(le=ae.done?E:A,pe.arg===P)continue;return{value:pe.arg,done:ae.done}}pe.type==="throw"&&(le=E,ae.method="throw",ae.arg=pe.arg)}}}function X(q,re){var ae=re.method,le=q.iterator[ae];if(le===u)return re.delegate=null,ae==="throw"&&q.iterator.return&&(re.method="return",re.arg=u,X(q,re),re.method==="throw")||ae!=="return"&&(re.method="throw",re.arg=new TypeError("The iterator does not provide a '"+ae+"' method")),P;var Z=L(le,q.iterator,re.arg);if(Z.type==="throw")return re.method="throw",re.arg=Z.arg,re.delegate=null,P;var ne=Z.arg;return ne?ne.done?(re[q.resultName]=ne.value,re.next=q.nextLoc,re.method!=="return"&&(re.method="next",re.arg=u),re.delegate=null,P):ne:(re.method="throw",re.arg=new TypeError("iterator result is not an object"),re.delegate=null,P)}function J(q){var re={tryLoc:q[0]};1 in q&&(re.catchLoc=q[1]),2 in q&&(re.finallyLoc=q[2],re.afterLoc=q[3]),this.tryEntries.push(re)}function se(q){var re=q.completion||{};re.type="normal",delete re.arg,q.completion=re}function ie(q){this.tryEntries=[{tryLoc:"root"}],q.forEach(J,this),this.reset(!0)}function me(q){if(q||q===""){var re=q[f];if(re)return re.call(q);if(typeof q.next=="function")return q;if(!isNaN(q.length)){var ae=-1,le=function(){function Z(){for(;++ae=0;--Z){var ne=this.tryEntries[Z],te=ne.completion;if(ne.tryLoc==="root")return le("end");if(ne.tryLoc<=this.prev){var fe=v.call(ne,"catchLoc"),pe=v.call(ne,"finallyLoc");if(fe&&pe){if(this.prev=0;--le){var Z=this.tryEntries[le];if(Z.tryLoc<=this.prev&&v.call(Z,"finallyLoc")&&this.prev=0;--ae){var le=this.tryEntries[ae];if(le.finallyLoc===re)return this.complete(le.completion,le.afterLoc),se(le),P}}return q}(),catch:function(){function q(re){for(var ae=this.tryEntries.length-1;ae>=0;--ae){var le=this.tryEntries[ae];if(le.tryLoc===re){var Z=le.completion;if(Z.type==="throw"){var ne=Z.arg;se(le)}return ne}}throw Error("illegal catch attempt")}return q}(),delegateYield:function(){function q(re,ae,le){return this.delegate={iterator:me(re),resultName:ae,nextLoc:le},this.method==="next"&&(this.arg=u),P}return q}()},s}function S(u,s,d,v,g,C,f){try{var N=u[C](f),V=N.value}catch(B){return void d(B)}N.done?s(V):Promise.resolve(V).then(v,g)}function k(u){return function(){var s=this,d=arguments;return new Promise(function(v,g){var C=u.apply(s,d);function f(V){S(C,v,g,f,N,"next",V)}function N(V){S(C,v,g,f,N,"throw",V)}f(void 0)})}}function h(u,s){u.prototype=Object.create(s.prototype),u.prototype.constructor=u,i(u,s)}function i(u,s){return i=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(d,v){return d.__proto__=v,d},i(u,s)}var c=function(u){return u[u.NORTH=1]="NORTH",u[u.SOUTH=2]="SOUTH",u[u.EAST=4]="EAST",u[u.WEST=8]="WEST",u[u.NORTHEAST=5]="NORTHEAST",u[u.NORTHWEST=9]="NORTHWEST",u[u.SOUTHEAST=6]="SOUTHEAST",u[u.SOUTHWEST=10]="SOUTHWEST",u}(c||{}),m,l=r.DmIcon=function(u){function s(v){var g;return g=u.call(this,v)||this,g.state={iconRef:""},g}h(s,u);var d=s.prototype;return d.fetchRefMap=function(){var v=k(y().mark(function(){function C(){var f,N;return y().wrap(function(){function V(B){for(;;)switch(B.prev=B.next){case 0:return B.prev=0,B.next=3,(0,t.fetchRetry)((0,a.resolveAsset)("icon_ref_map.json"));case 3:return f=B.sent,B.next=6,f.json();case 6:N=B.sent,m=N,this.setState({iconRef:N[this.props.icon]||""}),B.next=14;break;case 11:return B.prev=11,B.t0=B.catch(0),B.abrupt("return");case 14:case"end":return B.stop()}}return V}(),C,this,[[0,11]])}return C}()));function g(){return v.apply(this,arguments)}return g}(),d.componentDidMount=function(){function v(){m?this.setState({iconRef:m[this.props.icon]}):this.fetchRefMap()}return v}(),d.componentDidUpdate=function(){function v(g){g.icon!==this.props.icon&&(m?this.setState({iconRef:m[this.props.icon]}):this.fetchRefMap())}return v}(),d.render=function(){function v(){var g=this.props,C=g.className,f=g.direction,N=f===void 0?c.SOUTH:f,V=g.fallback,B=g.frame,I=B===void 0?1:B,L=g.icon_state,w=g.movement,A=w===void 0?!1:w,x=b(g,p),E=this.state.iconRef,P=E+"?state="+L+"&dir="+N+"&movement="+!!A+"&frame="+I;return E?(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Image,Object.assign({fixErrors:!0,src:P},x))):V||null}return v}(),s}(e.Component)},20342:function(T,r,n){"use strict";r.__esModule=!0,r.DraggableControl=void 0;var e=n(89005),a=n(44879),t=n(35840),o=n(9474);function p(h,i){h.prototype=Object.create(i.prototype),h.prototype.constructor=h,b(h,i)}function b(h,i){return b=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(c,m){return c.__proto__=m,c},b(h,i)}var y=400,S=function(i,c){return i.screenX*c[0]+i.screenY*c[1]},k=r.DraggableControl=function(h){function i(m){var l;return l=h.call(this,m)||this,l.inputRef=(0,e.createRef)(),l.state={originalValue:m.value,value:m.value,dragging:!1,editing:!1,origin:null,suppressingFlicker:!1},l.flickerTimer=null,l.suppressFlicker=function(){var u=l.props.suppressFlicker;u>0&&(l.setState({suppressingFlicker:!0}),clearTimeout(l.flickerTimer),l.flickerTimer=setTimeout(function(){return l.setState({suppressingFlicker:!1})},u))},l.handleDragStart=function(u){var s=l.props,d=s.value,v=s.dragMatrix,g=s.disabled,C=l.state.editing;C||g||(document.body.style["pointer-events"]="none",l.ref=u.currentTarget,l.setState({originalValue:d,dragging:!1,value:d,origin:S(u,v)}),l.timer=setTimeout(function(){l.setState({dragging:!0})},250),l.dragInterval=setInterval(function(){var f=l.state,N=f.dragging,V=f.value,B=l.props.onDrag;N&&B&&B(u,V)},l.props.updateRate||y),document.addEventListener("mousemove",l.handleDragMove),document.addEventListener("mouseup",l.handleDragEnd))},l.handleDragMove=function(u){var s,d=l.props,v=d.minValue,g=d.maxValue,C=d.step,f=d.dragMatrix,N=d.disabled;if(!N){var V=l.ref.offsetWidth/((g-v)/C),B=(s=l.props.stepPixelSize)!=null?s:V;typeof B=="function"&&(B=B(V)),l.setState(function(I){var L=Object.assign({},I),w=I.origin,A=S(u,f)-w;if(I.dragging){var x=Math.trunc(A/B);L.value=(0,a.clamp)(Math.floor(L.originalValue/C)*C+x*C,v,g)}else Math.abs(A)>4&&(L.dragging=!0);return L})}},l.handleDragEnd=function(u){var s=l.props,d=s.onChange,v=s.onDrag,g=l.state,C=g.dragging,f=g.value;if(document.body.style["pointer-events"]="auto",clearTimeout(l.timer),clearInterval(l.dragInterval),l.setState({originalValue:null,dragging:!1,editing:!C,origin:null}),document.removeEventListener("mousemove",l.handleDragMove),document.removeEventListener("mouseup",l.handleDragEnd),C)l.suppressFlicker(),d&&d(u,f),v&&v(u,f);else if(l.inputRef){var N=l.inputRef.current;N.value=f;try{N.focus(),N.select()}catch(V){}}},l}p(i,h);var c=i.prototype;return c.render=function(){function m(){var l=this,u=this.state,s=u.dragging,d=u.editing,v=u.value,g=u.suppressingFlicker,C=this.props,f=C.animated,N=C.value,V=C.unit,B=C.minValue,I=C.maxValue,L=C.format,w=C.onChange,A=C.onDrag,x=C.children,E=C.height,P=C.lineHeight,D=C.fontSize,M=C.disabled,O=N;(s||g)&&(O=v);var R=function(){function U(z){return z+(V?" "+V:"")}return U}(),F=f&&!s&&!g&&(0,e.createComponentVNode)(2,o.AnimatedNumber,{value:O,format:L,children:R})||R(L?L(O):O),W=(0,e.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:!d||M?"none":void 0,height:E,"line-height":P,"font-size":D},onBlur:function(){function U(z){if(d){var $=(0,a.clamp)(parseFloat(z.target.value),B,I);if(Number.isNaN($)){l.setState({editing:!1});return}l.setState({editing:!1,value:$}),l.suppressFlicker(),w&&w(z,$),A&&A(z,$)}}return U}(),onKeyDown:function(){function U(z){if(z.keyCode===13){var $=(0,a.clamp)(parseFloat(z.target.value),B,I);if(Number.isNaN($)){l.setState({editing:!1});return}l.setState({editing:!1,value:$}),l.suppressFlicker(),w&&w(z,$),A&&A(z,$);return}if(z.keyCode===27){l.setState({editing:!1});return}}return U}(),disabled:M},null,this.inputRef);return x({dragging:s,editing:d,value:N,displayValue:O,displayElement:F,inputElement:W,handleDragStart:this.handleDragStart})}return m}(),i}(e.Component);k.defaultHooks=t.pureComponentHooks,k.defaultProps={minValue:-1/0,maxValue:1/0,step:1,suppressFlicker:50,dragMatrix:[1,0]}},87099:function(T,r,n){"use strict";r.__esModule=!0,r.Dropdown=void 0;var e=n(89005),a=n(95996),t=n(35840),o=n(55937),p=n(96184),b=n(1331),y=n(96690),S=["icon","iconRotation","iconSpin","clipSelectedText","color","dropdownStyle","over","nochevron","width","onClick","onSelected","selected","disabled","displayText","buttons"],k=["className"],h;function i(g,C){if(g==null)return{};var f={};for(var N in g)if({}.hasOwnProperty.call(g,N)){if(C.includes(N))continue;f[N]=g[N]}return f}function c(g,C){g.prototype=Object.create(C.prototype),g.prototype.constructor=g,m(g,C)}function m(g,C){return m=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(f,N){return f.__proto__=N,f},m(g,C)}var l={placement:"left-start",modifiers:[{name:"eventListeners",enabled:!1}]},u={width:0,height:0,top:0,right:0,bottom:0,left:0,x:0,y:0,toJSON:function(){function g(){return null}return g}()},s="Layout Dropdown__menu",d="Layout Dropdown__menu-scroll",v=r.Dropdown=function(g){function C(N){var V;return V=g.call(this,N)||this,V.menuContents=void 0,V.handleClick=function(){V.state.open&&V.setOpen(!1)},V.state={open:!1,selected:V.props.selected},V.menuContents=null,V}c(C,g);var f=C.prototype;return f.getDOMNode=function(){function N(){return(0,e.findDOMFromVNode)(this.$LI,!0)}return N}(),f.componentDidMount=function(){function N(){var V=this.getDOMNode()}return N}(),f.openMenu=function(){function N(){var V=C.renderedMenu;V===void 0&&(V=document.createElement("div"),V.className=s,document.body.appendChild(V),C.renderedMenu=V);var B=this.getDOMNode();C.currentOpenMenu=B,V.scrollTop=0,V.style.width=this.props.menuWidth||B.offsetWidth+"px",V.style.opacity="1",V.style.pointerEvents="auto",setTimeout(function(){var I;(I=C.renderedMenu)==null||I.focus()},400),this.renderMenuContent()}return N}(),f.closeMenu=function(){function N(){C.currentOpenMenu===this.getDOMNode()&&(C.currentOpenMenu=void 0,C.renderedMenu.style.opacity="0",C.renderedMenu.style.pointerEvents="none")}return N}(),f.componentWillUnmount=function(){function N(){this.closeMenu(),this.setOpen(!1)}return N}(),f.renderMenuContent=function(){function N(){var V=this,B=C.renderedMenu;if(B){B.offsetHeight>200?B.className=d:B.className=s;var I=this.props.options,L=I===void 0?[]:I,w=L.map(function(x){var E,P;return typeof x=="string"?(P=x,E=x):x!==null&&(P=x.displayText,E=x.value),(0,e.createVNode)(1,"div",(0,t.classes)(["Dropdown__menuentry",V.state.selected===E&&"selected"]),P,0,{onClick:function(){function D(){V.setSelected(E)}return D}()},E)}),A=w.length?w:"No Options Found";(0,e.render)((0,e.createVNode)(1,"div",null,A,0),B,function(){var x=C.singletonPopper;x===void 0?(x=(0,a.createPopper)(C.virtualElement,B,Object.assign({},l,{placement:"bottom-start"})),C.singletonPopper=x):(x.setOptions(Object.assign({},l,{placement:"bottom-start"})),x.update())},this.context)}}return N}(),f.setOpen=function(){function N(V){var B=this;this.setState(function(I){return Object.assign({},I,{open:V})}),V?setTimeout(function(){B.openMenu(),window.addEventListener("click",B.handleClick)}):(this.closeMenu(),window.removeEventListener("click",this.handleClick))}return N}(),f.setSelected=function(){function N(V){this.setState(function(B){return Object.assign({},B,{selected:V})}),this.setOpen(!1),this.props.onSelected&&this.props.onSelected(V)}return N}(),f.getOptionValue=function(){function N(V){return typeof V=="string"?V:V.value}return N}(),f.getSelectedIndex=function(){function N(){var V=this,B=this.state.selected||this.props.selected,I=this.props.options,L=I===void 0?[]:I;return L.findIndex(function(w){return V.getOptionValue(w)===B})}return N}(),f.toPrevious=function(){function N(){if(!(this.props.options.length<1)){var V=this.getSelectedIndex(),B=0,I=this.props.options.length-1,L=V>=0;L||(V=B);var w=V===B?I:V-1;this.setSelected(this.getOptionValue(this.props.options[w]))}}return N}(),f.toNext=function(){function N(){if(!(this.props.options.length<1)){var V=this.getSelectedIndex(),B=0,I=this.props.options.length-1,L=V>=0;L||(V=I);var w=V===I?B:V+1;this.setSelected(this.getOptionValue(this.props.options[w]))}}return N}(),f.render=function(){function N(){var V=this,B=this.props,I=B.icon,L=B.iconRotation,w=B.iconSpin,A=B.clipSelectedText,x=A===void 0?!0:A,E=B.color,P=E===void 0?"default":E,D=B.dropdownStyle,M=B.over,O=B.nochevron,R=B.width,F=B.onClick,W=B.onSelected,U=B.selected,z=B.disabled,$=B.displayText,G=B.buttons,X=i(B,S),J=X.className,se=i(X,k),ie=M?!this.state.open:this.state.open;return(0,e.createComponentVNode)(2,y.Stack,{inline:!0,fill:!0,width:R,children:[(0,e.createComponentVNode)(2,y.Stack.Item,{grow:!0,children:(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Box,Object.assign({width:"100%",className:(0,t.classes)(["Dropdown__control","Button","Button--color--"+P,z&&"Button--disabled",J]),onClick:function(){function me(q){z&&!V.state.open||(V.setOpen(!V.state.open),F&&F(q))}return me}()},se,{children:[I&&(0,e.createComponentVNode)(2,b.Icon,{name:I,rotation:L,spin:w,mr:1}),(0,e.createVNode)(1,"span","Dropdown__selected-text",$||this.state.selected,0,{style:{overflow:x?"hidden":"visible"}}),O||(0,e.createVNode)(1,"span","Dropdown__arrow-button",(0,e.createComponentVNode)(2,b.Icon,{name:ie?"chevron-up":"chevron-down"}),2)]})))}),G&&(0,e.createFragment)([(0,e.createComponentVNode)(2,y.Stack.Item,{height:"100%",children:(0,e.createComponentVNode)(2,p.Button,{height:"100%",icon:"chevron-left",disabled:z,onClick:function(){function me(){z||V.toPrevious()}return me}()})}),(0,e.createComponentVNode)(2,y.Stack.Item,{height:"100%",children:(0,e.createComponentVNode)(2,p.Button,{height:"100%",icon:"chevron-right",disabled:z,onClick:function(){function me(){z||V.toNext()}return me}()})})],4)]})}return N}(),C}(e.Component);h=v,v.renderedMenu=void 0,v.singletonPopper=void 0,v.currentOpenMenu=void 0,v.virtualElement={getBoundingClientRect:function(){function g(){var C,f;return(C=(f=h.currentOpenMenu)==null?void 0:f.getBoundingClientRect())!=null?C:u}return g}()}},39473:function(T,r,n){"use strict";r.__esModule=!0,r.computeFlexProps=r.computeFlexItemProps=r.computeFlexItemClassName=r.computeFlexClassName=r.Flex=void 0;var e=n(89005),a=n(35840),t=n(55937),o=["className","direction","wrap","align","justify","inline","style"],p=["className"],b=["className","style","grow","order","shrink","basis","align"],y=["className"];/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */function S(u,s){if(u==null)return{};var d={};for(var v in u)if({}.hasOwnProperty.call(u,v)){if(s.includes(v))continue;d[v]=u[v]}return d}var k=r.computeFlexClassName=function(){function u(s){return(0,a.classes)(["Flex",s.inline&&"Flex--inline",(0,t.computeBoxClassName)(s)])}return u}(),h=r.computeFlexProps=function(){function u(s){var d=s.className,v=s.direction,g=s.wrap,C=s.align,f=s.justify,N=s.inline,V=s.style,B=S(s,o);return(0,t.computeBoxProps)(Object.assign({style:Object.assign({},V,{"flex-direction":v,"flex-wrap":g===!0?"wrap":g,"align-items":C,"justify-content":f})},B))}return u}(),i=r.Flex=function(){function u(s){var d=s.className,v=S(s,p);return(0,e.normalizeProps)((0,e.createVNode)(1,"div",(0,a.classes)([d,k(v)]),null,1,Object.assign({},h(v))))}return u}();i.defaultHooks=a.pureComponentHooks;var c=r.computeFlexItemClassName=function(){function u(s){return(0,a.classes)(["Flex__item",(0,t.computeBoxClassName)(s)])}return u}(),m=r.computeFlexItemProps=function(){function u(s){var d=s.className,v=s.style,g=s.grow,C=s.order,f=s.shrink,N=s.basis,V=N===void 0?s.width:N,B=s.align,I=S(s,b);return(0,t.computeBoxProps)(Object.assign({style:Object.assign({},v,{"flex-grow":g!==void 0&&Number(g),"flex-shrink":f!==void 0&&Number(f),"flex-basis":(0,t.unit)(V),order:C,"align-self":B})},I))}return u}(),l=function(s){var d=s.className,v=S(s,y);return(0,e.normalizeProps)((0,e.createVNode)(1,"div",(0,a.classes)([d,c(s)]),null,1,Object.assign({},m(v))))};l.defaultHooks=a.pureComponentHooks,i.Item=l},79646:function(T,r,n){"use strict";r.__esModule=!0,r.GridColumn=r.Grid=void 0;var e=n(89005),a=n(36352),t=n(35840),o=["children"],p=["size","style"];/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */function b(k,h){if(k==null)return{};var i={};for(var c in k)if({}.hasOwnProperty.call(k,c)){if(h.includes(c))continue;i[c]=k[c]}return i}var y=r.Grid=function(){function k(h){var i=h.children,c=b(h,o);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,a.Table,Object.assign({},c,{children:(0,e.createComponentVNode)(2,a.Table.Row,{children:i})})))}return k}();y.defaultHooks=t.pureComponentHooks;var S=r.GridColumn=function(){function k(h){var i=h.size,c=i===void 0?1:i,m=h.style,l=b(h,p);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,a.Table.Cell,Object.assign({style:Object.assign({width:c+"%"},m)},l)))}return k}();y.defaultHooks=t.pureComponentHooks,y.Column=S},1331:function(T,r,n){"use strict";r.__esModule=!0,r.IconStack=r.Icon=void 0;var e=n(89005),a=n(35840),t=n(55937),o=["name","size","spin","className","style","rotation","inverse"],p=["className","style","children"];/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */function b(h,i){if(h==null)return{};var c={};for(var m in h)if({}.hasOwnProperty.call(h,m)){if(i.includes(m))continue;c[m]=h[m]}return c}var y=/-o$/,S=r.Icon=function(){function h(i){var c=i.name,m=i.size,l=i.spin,u=i.className,s=i.style,d=s===void 0?{}:s,v=i.rotation,g=i.inverse,C=b(i,o);m&&(d["font-size"]=m*100+"%"),typeof v=="number"&&(d.transform="rotate("+v+"deg)");var f=y.test(c),N=c.replace(y,"");return(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.Box,Object.assign({as:"i",className:(0,a.classes)(["Icon",u,f?"far":"fas","fa-"+N,l&&"fa-spin"]),style:d},C)))}return h}();S.defaultHooks=a.pureComponentHooks;var k=r.IconStack=function(){function h(i){var c=i.className,m=i.style,l=m===void 0?{}:m,u=i.children,s=b(i,p);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.Box,Object.assign({as:"span",class:(0,a.classes)(["IconStack",c]),style:l},s,{children:u})))}return h}();S.Stack=k},91225:function(T,r,n){"use strict";r.__esModule=!0,r.Image=void 0;var e=n(89005),a=n(55937),t=["fixBlur","fixErrors","objectFit","src"];function o(k,h){if(k==null)return{};var i={};for(var c in k)if({}.hasOwnProperty.call(k,c)){if(h.includes(c))continue;i[c]=k[c]}return i}function p(k,h){k.prototype=Object.create(h.prototype),k.prototype.constructor=k,b(k,h)}function b(k,h){return b=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(i,c){return i.__proto__=c,i},b(k,h)}var y=5,S=r.Image=function(k){function h(){for(var c,m=arguments.length,l=new Array(m),u=0;u0;u&&(l=c.containerRef)!=null&&l.current?c.props.onMove(b(c.containerRef.current,m)):c.toggleDocumentEvents(!1)},c.handleMoveEnd=function(){c.toggleDocumentEvents(!1)},c.handleKeyDown=function(m){var l=m.which||m.keyCode;l<37||l>40||(m.preventDefault(),c.props.onKey({left:l===39?.05:l===37?-.05:0,top:l===40?.05:l===38?-.05:0}))},c.props=i,c.containerRef=(0,e.createRef)(),c}t(k,S);var h=k.prototype;return h.toggleDocumentEvents=function(){function i(c){var m,l=(m=this.containerRef)==null?void 0:m.current,u=p(l),s=c?u.addEventListener:u.removeEventListener;s("mousemove",this.handleMove),s("mouseup",this.handleMoveEnd)}return i}(),h.componentDidMount=function(){function i(){this.toggleDocumentEvents(!0)}return i}(),h.componentWillUnmount=function(){function i(){this.toggleDocumentEvents(!1)}return i}(),h.render=function(){function i(){return(0,e.normalizeProps)((0,e.createVNode)(1,"div","react-colorful__interactive",this.props.children,0,Object.assign({},this.props,{style:this.props.style,onMouseDown:this.handleMoveStart,onKeyDown:this.handleKeyDown,tabIndex:0,role:"slider"}),null,this.containerRef))}return i}(),k}(e.Component)},76334:function(T,r,n){"use strict";r.__esModule=!0,r.Knob=void 0;var e=n(89005),a=n(44879),t=n(35840),o=n(55937),p=n(20342),b=n(59263),y=["animated","format","maxValue","minValue","onChange","onDrag","step","stepPixelSize","suppressFlicker","unit","value","className","style","fillValue","color","ranges","size","bipolar","children","popUpPosition"];/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */function S(h,i){if(h==null)return{};var c={};for(var m in h)if({}.hasOwnProperty.call(h,m)){if(i.includes(m))continue;c[m]=h[m]}return c}var k=r.Knob=function(){function h(i){var c=i.animated,m=i.format,l=i.maxValue,u=i.minValue,s=i.onChange,d=i.onDrag,v=i.step,g=i.stepPixelSize,C=i.suppressFlicker,f=i.unit,N=i.value,V=i.className,B=i.style,I=i.fillValue,L=i.color,w=i.ranges,A=w===void 0?{}:w,x=i.size,E=x===void 0?1:x,P=i.bipolar,D=i.children,M=i.popUpPosition,O=S(i,y);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,p.DraggableControl,Object.assign({dragMatrix:[0,-1]},{animated:c,format:m,maxValue:l,minValue:u,onChange:s,onDrag:d,step:v,stepPixelSize:g,suppressFlicker:C,unit:f,value:N},{children:function(){function R(F){var W=F.dragging,U=F.editing,z=F.value,$=F.displayValue,G=F.displayElement,X=F.inputElement,J=F.handleDragStart,se=(0,a.scale)(I!=null?I:$,u,l),ie=(0,a.scale)($,u,l),me=L||(0,a.keyOfMatchingRange)(I!=null?I:z,A)||"default",q=(ie-.5)*270;return(0,e.normalizeProps)((0,e.createVNode)(1,"div",(0,t.classes)(["Knob","Knob--color--"+me,P&&"Knob--bipolar",V,(0,o.computeBoxClassName)(O)]),[(0,e.createVNode)(1,"div","Knob__circle",(0,e.createVNode)(1,"div","Knob__cursorBox",(0,e.createVNode)(1,"div","Knob__cursor"),2,{style:{transform:"rotate("+q+"deg)"}}),2),W&&(0,e.createVNode)(1,"div",(0,t.classes)(["Knob__popupValue",M&&"Knob__popupValue--"+M]),G,0),(0,e.createVNode)(32,"svg","Knob__ring Knob__ringTrackPivot",(0,e.createVNode)(32,"circle","Knob__ringTrack",null,1,{cx:"50",cy:"50",r:"50"}),2,{viewBox:"0 0 100 100"}),(0,e.createVNode)(32,"svg","Knob__ring Knob__ringFillPivot",(0,e.createVNode)(32,"circle","Knob__ringFill",null,1,{style:{"stroke-dashoffset":((P?2.75:2)-se*1.5)*Math.PI*50},cx:"50",cy:"50",r:"50"}),2,{viewBox:"0 0 100 100"}),X],0,Object.assign({},(0,o.computeBoxProps)(Object.assign({style:Object.assign({"font-size":E+"em"},B)},O)),{onMouseDown:J})))}return R}()})))}return h}()},78621:function(T,r,n){"use strict";r.__esModule=!0,r.LabeledControls=void 0;var e=n(89005),a=n(39473),t=["children"],o=["label","children"];/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */function p(S,k){if(S==null)return{};var h={};for(var i in S)if({}.hasOwnProperty.call(S,i)){if(k.includes(i))continue;h[i]=S[i]}return h}var b=r.LabeledControls=function(){function S(k){var h=k.children,i=p(k,t);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,a.Flex,Object.assign({mx:-.5,align:"stretch",justify:"space-between"},i,{children:h})))}return S}(),y=function(k){var h=k.label,i=k.children,c=p(k,o);return(0,e.createComponentVNode)(2,a.Flex.Item,{mx:1,children:(0,e.normalizeProps)((0,e.createComponentVNode)(2,a.Flex,Object.assign({minWidth:"52px",height:"100%",direction:"column",align:"center",textAlign:"center",justify:"space-between"},c,{children:[(0,e.createComponentVNode)(2,a.Flex.Item),(0,e.createComponentVNode)(2,a.Flex.Item,{children:i}),(0,e.createComponentVNode)(2,a.Flex.Item,{color:"label",children:h})]})))})};b.Item=y},29319:function(T,r,n){"use strict";r.__esModule=!0,r.LabeledList=void 0;var e=n(89005),a=n(35840),t=n(55937),o=n(13605),p=n(62147);/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */var b=r.LabeledList=function(){function k(h){var i=h.children;return(0,e.createVNode)(1,"table","LabeledList",i,0)}return k}();b.defaultHooks=a.pureComponentHooks;var y=function(h){var i=h.className,c=h.label,m=h.labelColor,l=m===void 0?"label":m,u=h.color,s=h.textAlign,d=h.buttons,v=h.tooltip,g=h.content,C=h.children,f=h.preserveWhitespace,N=h.labelStyle,V=(0,e.createVNode)(1,"tr",(0,a.classes)(["LabeledList__row",i]),[(0,e.createComponentVNode)(2,t.Box,{as:"td",color:l,className:(0,a.classes)(["LabeledList__cell","LabeledList__label"]),style:N,children:c?c+":":null}),(0,e.createComponentVNode)(2,t.Box,{as:"td",color:u,textAlign:s,className:(0,a.classes)(["LabeledList__cell","LabeledList__content"]),colSpan:d?void 0:2,preserveWhitespace:f,children:[g,C]}),d&&(0,e.createVNode)(1,"td","LabeledList__cell LabeledList__buttons",d,0)],0);return v&&(V=(0,e.createComponentVNode)(2,p.Tooltip,{content:v,children:V})),V};y.defaultHooks=a.pureComponentHooks;var S=function(h){var i=h.size?(0,t.unit)(Math.max(0,h.size-1)):0;return(0,e.createVNode)(1,"tr","LabeledList__row",(0,e.createVNode)(1,"td",null,(0,e.createComponentVNode)(2,o.Divider),2,{colSpan:3,style:{"padding-top":i,"padding-bottom":i}}),2)};S.defaultHooks=a.pureComponentHooks,b.Item=y,b.Divider=S},36077:function(T,r,n){"use strict";r.__esModule=!0,r.Modal=void 0;var e=n(89005),a=n(35840),t=n(55937),o=n(61940),p=["className","children","onEnter"];/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */function b(S,k){if(S==null)return{};var h={};for(var i in S)if({}.hasOwnProperty.call(S,i)){if(k.includes(i))continue;h[i]=S[i]}return h}var y=r.Modal=function(){function S(k){var h=k.className,i=k.children,c=k.onEnter,m=b(k,p),l;return c&&(l=function(){function u(s){s.keyCode===13&&c(s)}return u}()),(0,e.createComponentVNode)(2,o.Dimmer,{onKeyDown:l,children:(0,e.normalizeProps)((0,e.createVNode)(1,"div",(0,a.classes)(["Modal",h,(0,t.computeBoxClassName)(m)]),i,0,Object.assign({},(0,t.computeBoxProps)(m))))})}return S}()},73280:function(T,r,n){"use strict";r.__esModule=!0,r.NanoMap=void 0;var e=n(89005),a=n(36036),t=n(72253),o=n(29319),p=n(79911),b=n(79140),y=["x","y","icon","tooltip","color","children"],S=["icon","color"];function k(g,C){if(g==null)return{};var f={};for(var N in g)if({}.hasOwnProperty.call(g,N)){if(C.includes(N))continue;f[N]=g[N]}return f}function h(g,C){g.prototype=Object.create(C.prototype),g.prototype.constructor=g,i(g,C)}function i(g,C){return i=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(f,N){return f.__proto__=N,f},i(g,C)}var c=510,m=2,l=function(C){return C.stopPropagation&&C.stopPropagation(),C.preventDefault&&C.preventDefault(),C.cancelBubble=!0,C.returnValue=!1,!1},u=r.NanoMap=function(g){function C(N){var V,B,I,L;L=g.call(this,N)||this;var w=window.innerWidth/2-256,A=window.innerHeight/2-256;return L.state={offsetX:(V=N.offsetX)!=null?V:0,offsetY:(B=N.offsetY)!=null?B:0,dragging:!1,originX:null,originY:null,zoom:(I=N.zoom)!=null?I:1},L.handleDragStart=function(x){L.ref=x.target,L.setState({dragging:!1,originX:x.screenX,originY:x.screenY}),document.addEventListener("mousemove",L.handleDragMove),document.addEventListener("mouseup",L.handleDragEnd),l(x)},L.handleDragMove=function(x){L.setState(function(E){var P=Object.assign({},E),D=x.screenX-P.originX,M=x.screenY-P.originY;return E.dragging?(P.offsetX+=D/P.zoom,P.offsetY+=M/P.zoom,P.originX=x.screenX,P.originY=x.screenY):P.dragging=!0,P}),l(x)},L.handleDragEnd=function(x){L.setState({dragging:!1,originX:null,originY:null}),document.removeEventListener("mousemove",L.handleDragMove),document.removeEventListener("mouseup",L.handleDragEnd),N.onOffsetChange==null||N.onOffsetChange(x,L.state),l(x)},L.handleZoom=function(x,E){L.setState(function(P){var D=Math.min(Math.max(E,1),8);return P.zoom=D,N.onZoom&&N.onZoom(P.zoom),P})},L.handleReset=function(x){L.setState(function(E){E.offsetX=0,E.offsetY=0,E.zoom=1,L.handleZoom(x,1),N.onOffsetChange==null||N.onOffsetChange(x,E)})},L}h(C,g);var f=C.prototype;return f.getChildContext=function(){function N(){return{map:{zoom:this.state.zoom}}}return N}(),f.render=function(){function N(){var V=(0,t.useBackend)(this.context),B=V.config,I=this.state,L=I.dragging,w=I.offsetX,A=I.offsetY,x=I.zoom,E=x===void 0?1:x,P=this.props.children,D=B.map+"_nanomap_z1.png",M=c*E+"px",O={width:M,height:M,"margin-top":A*E+"px","margin-left":w*E+"px",overflow:"hidden",position:"relative",top:"50%",left:"50%",transform:"translate(-50%, -50%)","background-size":"cover","background-repeat":"no-repeat","text-align":"center",cursor:L?"move":"auto"},R={width:"100%",height:"100%",position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"};return(0,e.createComponentVNode)(2,a.Box,{className:"NanoMap__container",children:[(0,e.createComponentVNode)(2,a.Box,{style:O,onMouseDown:this.handleDragStart,children:[(0,e.createVNode)(1,"img",null,null,1,{src:(0,b.resolveAsset)(D),style:R}),(0,e.createComponentVNode)(2,a.Box,{children:P})]}),(0,e.createComponentVNode)(2,v,{zoom:E,onZoom:this.handleZoom,onReset:this.handleReset})]})}return N}(),C}(e.Component),s=function(C,f){var N=f.map.zoom,V=C.x,B=C.y,I=C.icon,L=C.tooltip,w=C.color,A=C.children,x=k(C,y),E=m*N,P=(V-1)*E,D=(B-1)*E;return(0,e.createVNode)(1,"div",null,(0,e.createComponentVNode)(2,a.Tooltip,{content:L,children:(0,e.normalizeProps)((0,e.createComponentVNode)(2,a.Box,Object.assign({position:"absolute",className:"NanoMap__marker",lineHeight:"0",bottom:D+"px",left:P+"px",width:E+"px",height:E+"px"},x,{children:A})))}),2)};u.Marker=s;var d=function(C,f){var N=f.map.zoom,V=C.icon,B=C.color,I=k(C,S),L=m*N+4/Math.ceil(N/4);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,s,Object.assign({},I,{children:(0,e.createComponentVNode)(2,a.Icon,{name:V,color:B,fontSize:L+"px",style:{position:"relative",top:"50%",left:"50%",transform:"translate(-50%, -50%)"}})})))};u.MarkerIcon=d;var v=function(C,f){return(0,e.createComponentVNode)(2,a.Box,{className:"NanoMap__zoomer",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Zoom",labelStyle:{"vertical-align":"middle"},children:(0,e.createComponentVNode)(2,a.Flex,{direction:"row",children:[(0,e.createComponentVNode)(2,p.Slider,{minValue:1,maxValue:8,stepPixelSize:10,format:function(){function N(V){return V+"x"}return N}(),value:C.zoom,onDrag:function(){function N(V,B){return C.onZoom(V,B)}return N}()}),(0,e.createComponentVNode)(2,a.Button,{ml:"0.5em",float:"right",icon:"sync",tooltip:"Reset View",onClick:function(){function N(V){return C.onReset==null?void 0:C.onReset(V)}return N}()})]})})})})};u.Zoomer=v},74733:function(T,r,n){"use strict";r.__esModule=!0,r.NoticeBox=void 0;var e=n(89005),a=n(35840),t=n(55937),o=["className","color","info","warning","success","danger"];/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */function p(y,S){if(y==null)return{};var k={};for(var h in y)if({}.hasOwnProperty.call(y,h)){if(S.includes(h))continue;k[h]=y[h]}return k}var b=r.NoticeBox=function(){function y(S){var k=S.className,h=S.color,i=S.info,c=S.warning,m=S.success,l=S.danger,u=p(S,o);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.Box,Object.assign({className:(0,a.classes)(["NoticeBox",h&&"NoticeBox--color--"+h,i&&"NoticeBox--type--info",m&&"NoticeBox--type--success",l&&"NoticeBox--type--danger",k])},u)))}return y}();b.defaultHooks=a.pureComponentHooks},59263:function(T,r,n){"use strict";r.__esModule=!0,r.NumberInput=void 0;var e=n(89005),a=n(44879),t=n(35840),o=n(9474),p=n(55937);function b(h,i){h.prototype=Object.create(i.prototype),h.prototype.constructor=h,y(h,i)}function y(h,i){return y=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(c,m){return c.__proto__=m,c},y(h,i)}/** +* @file +* @copyright 2020 Aleksej Komarov +* @license MIT +*/var S=400,k=r.NumberInput=function(h){function i(m){var l;l=h.call(this,m)||this;var u=m.value;return l.inputRef=(0,e.createRef)(),l.state={value:u,dragging:!1,editing:!1,internalValue:null,origin:null,suppressingFlicker:!1},l.flickerTimer=null,l.suppressFlicker=function(){var s=l.props.suppressFlicker;s>0&&(l.setState({suppressingFlicker:!0}),clearTimeout(l.flickerTimer),l.flickerTimer=setTimeout(function(){return l.setState({suppressingFlicker:!1})},s))},l.handleDragStart=function(s){var d=l.props.value,v=l.state.editing;v||(document.body.style["pointer-events"]="none",l.ref=s.target,l.setState({dragging:!1,origin:s.screenY,value:d,internalValue:d}),l.timer=setTimeout(function(){l.setState({dragging:!0})},250),l.dragInterval=setInterval(function(){var g=l.state,C=g.dragging,f=g.value,N=l.props.onDrag;C&&N&&N(s,f)},l.props.updateRate||S),document.addEventListener("mousemove",l.handleDragMove),document.addEventListener("mouseup",l.handleDragEnd))},l.handleDragMove=function(s){var d=l.props,v=d.minValue,g=d.maxValue,C=d.step,f=d.stepPixelSize;l.setState(function(N){var V=Object.assign({},N),B=V.origin-s.screenY;if(N.dragging){var I=Number.isFinite(v)?v%C:0;V.internalValue=(0,a.clamp)(V.internalValue+B*C/f,v-C,g+C),V.value=(0,a.clamp)(V.internalValue-V.internalValue%C+I,v,g),V.origin=s.screenY}else Math.abs(B)>4&&(V.dragging=!0);return V})},l.handleDragEnd=function(s){var d=l.props,v=d.onChange,g=d.onDrag,C=l.state,f=C.dragging,N=C.value,V=C.internalValue;if(document.body.style["pointer-events"]="auto",clearTimeout(l.timer),clearInterval(l.dragInterval),l.setState({dragging:!1,editing:!f,origin:null}),document.removeEventListener("mousemove",l.handleDragMove),document.removeEventListener("mouseup",l.handleDragEnd),f)l.suppressFlicker(),v&&v(s,N),g&&g(s,N);else if(l.inputRef){var B=l.inputRef.current;B.value=V;try{B.focus(),B.select()}catch(I){}}},l}b(i,h);var c=i.prototype;return c.render=function(){function m(){var l=this,u=this.state,s=u.dragging,d=u.editing,v=u.value,g=u.suppressingFlicker,C=this.props,f=C.className,N=C.fluid,V=C.animated,B=C.value,I=C.unit,L=C.minValue,w=C.maxValue,A=C.height,x=C.width,E=C.lineHeight,P=C.fontSize,D=C.format,M=C.onChange,O=C.onDrag,R=B;(s||g)&&(R=v);var F=(0,e.createVNode)(1,"div","NumberInput__content",[V&&!s&&!g?(0,e.createComponentVNode)(2,o.AnimatedNumber,{value:R,format:D}):D?D(R):R,I?" "+I:""],0);return(0,e.createComponentVNode)(2,p.Box,{className:(0,t.classes)(["NumberInput",N&&"NumberInput--fluid",f]),minWidth:x,minHeight:A,lineHeight:E,fontSize:P,onMouseDown:this.handleDragStart,children:[(0,e.createVNode)(1,"div","NumberInput__barContainer",(0,e.createVNode)(1,"div","NumberInput__bar",null,1,{style:{height:(0,a.clamp)((R-L)/(w-L)*100,0,100)+"%"}}),2),F,(0,e.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:d?void 0:"none",height:A,"line-height":E,"font-size":P},onBlur:function(){function W(U){if(d){var z=(0,a.clamp)(parseFloat(U.target.value),L,w);if(Number.isNaN(z)){l.setState({editing:!1});return}l.setState({editing:!1,value:z}),l.suppressFlicker(),M&&M(U,z),O&&O(U,z)}}return W}(),onKeyDown:function(){function W(U){if(U.keyCode===13){var z=(0,a.clamp)(parseFloat(U.target.value),L,w);if(Number.isNaN(z)){l.setState({editing:!1});return}l.setState({editing:!1,value:z}),l.suppressFlicker(),M&&M(U,z),O&&O(U,z);return}if(U.keyCode===27){l.setState({editing:!1});return}}return W}()},null,this.inputRef)]})}return m}(),i}(e.Component);k.defaultHooks=t.pureComponentHooks,k.defaultProps={minValue:-1/0,maxValue:1/0,step:1,stepPixelSize:1,suppressFlicker:50}},33337:function(T,r,n){"use strict";r.__esModule=!0,r.Pointer=void 0;var e=n(89005),a=n(35840),t=r.Pointer=function(){function o(p){var b=p.className,y=p.color,S=p.left,k=p.top,h=k===void 0?.5:k,i=(0,a.classes)(["react-colorful__pointer",b]),c={top:h*100+"%",left:S*100+"%"};return(0,e.createVNode)(1,"div",i,(0,e.createVNode)(1,"div","react-colorful__pointer-fill",null,1,{style:{"background-color":y}}),2,{style:c})}return o}()},50186:function(T,r,n){"use strict";r.__esModule=!0,r.Popper=void 0;var e=n(95996),a=n(89005);function t(b,y){b.prototype=Object.create(y.prototype),b.prototype.constructor=b,o(b,y)}function o(b,y){return o=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(S,k){return S.__proto__=k,S},o(b,y)}var p=r.Popper=function(b){function y(){var k;return k=b.call(this)||this,k.renderedContent=void 0,k.popperInstance=void 0,y.id+=1,k}t(y,b);var S=y.prototype;return S.componentDidMount=function(){function k(){var h=this,i=this.props,c=i.additionalStyles,m=i.options;if(this.renderedContent=document.createElement("div"),c)for(var l=0,u=Object.entries(c);l>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * @file * @copyright 2020 Aleksej Komarov * @author Warlockd * @license MIT +<<<<<<< HEAD */var l=r.TextArea=function(c){function m(u,s){var d;d=c.call(this,u,s)||this,d.textareaRef=u.innerRef||(0,e.createRef)(),d.fillerRef=(0,e.createRef)(),d.state={editing:!1};var v=u.dontUseTabForIndent,h=v===void 0?!1:v;return d.handleOnInput=function(C){var p=d.state.editing,N=d.props.onInput;p||d.setEditing(!0),N&&N(C,C.target.value)},d.handleOnChange=function(C){var p=d.state.editing,N=d.props.onChange;N&&N(C,C.target.value)},d.handleKeyPress=function(C){var p=d.state.editing,N=d.props.onKeyPress;p||d.setEditing(!0),N&&N(C,C.target.value)},d.handleKeyDown=function(C){var p=d.state.editing,N=d.props,V=N.onChange,S=N.onInput,B=N.onEnter,L=N.onKeyDown;if(C.keyCode===f.KEY_ENTER){d.setEditing(!1),V&&V(C,C.target.value),S&&S(C,C.target.value),B&&B(C,C.target.value),d.props.selfClear&&(C.target.value="",C.target.blur());return}if(C.keyCode===f.KEY_ESCAPE){d.props.onEscape&&d.props.onEscape(C),d.setEditing(!1),d.props.selfClear?C.target.value="":(C.target.value=(0,o.toInputValue)(d.props.value),C.target.blur());return}if(p||d.setEditing(!0),L&&L(C,C.target.value),!h){var w=C.keyCode||C.which;if(w===f.KEY_TAB){C.preventDefault();var A=C.target,x=A.value,E=A.selectionStart,P=A.selectionEnd;C.target.value=x.substring(0,E)+" "+x.substring(P),C.target.selectionEnd=E+1}}},d.handleFocus=function(C){var p=d.state.editing;p||d.setEditing(!0)},d.handleBlur=function(C){var p=d.state.editing,N=d.props.onChange;p&&(d.setEditing(!1),N&&N(C,C.target.value))},d}k(m,c);var i=m.prototype;return i.componentDidMount=function(){function u(){var s=this,d=this.props.value,v=this.textareaRef.current;v&&(v.value=(0,o.toInputValue)(d)),(this.props.autoFocus||this.props.autoSelect)&&setTimeout(function(){v.focus(),s.props.autoSelect&&v.select()},1)}return u}(),i.componentDidUpdate=function(){function u(s,d){var v=s.value,h=this.props.value,C=this.textareaRef.current;C&&typeof h=="string"&&v!==h&&(C.value=(0,o.toInputValue)(h))}return u}(),i.setEditing=function(){function u(s){this.setState({editing:s})}return u}(),i.getValue=function(){function u(){return this.textareaRef.current&&this.textareaRef.current.value}return u}(),i.render=function(){function u(){var s=this.props,d=s.onChange,v=s.onKeyDown,h=s.onKeyPress,C=s.onInput,p=s.onFocus,N=s.onBlur,V=s.onEnter,S=s.value,B=s.maxLength,L=s.placeholder,w=I(s,b),A=w.className,x=w.fluid,E=I(w,y);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.Box,Object.assign({className:(0,a.classes)(["TextArea",x&&"TextArea--fluid",A])},E,{children:(0,e.createVNode)(128,"textarea","TextArea__textarea",null,1,{placeholder:L,onChange:this.handleOnChange,onKeyDown:this.handleKeyDown,onKeyPress:this.handleKeyPress,onInput:this.handleOnInput,onFocus:this.handleFocus,onBlur:this.handleBlur,maxLength:B},null,this.textareaRef)})))}return u}(),m}(e.Component)},5169:function(T,r){"use strict";r.__esModule=!0,r.TimeDisplay=void 0;var n=function(t){(!t||t<0)&&(t=0);var o=Math.floor(t/60).toString(10),f=(Math.floor(t)%60).toString(10);return[o,f].map(function(b){return b.length<2?"0"+b:b}).join(":")},e=r.TimeDisplay=function(){function a(t){var o=t.totalSeconds,f=o===void 0?0:o;return n(f)}return a}()},62147:function(T,r,n){"use strict";r.__esModule=!0,r.Tooltip=void 0;var e=n(89005),a=n(95996),t;function o(k,g){k.prototype=Object.create(g.prototype),k.prototype.constructor=k,f(k,g)}function f(k,g){return f=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(l,c){return l.__proto__=c,l},f(k,g)}var b={modifiers:[{name:"eventListeners",enabled:!1}]},y={width:0,height:0,top:0,right:0,bottom:0,left:0,x:0,y:0,toJSON:function(){function k(){return null}return k}()},I=r.Tooltip=function(k){function g(){return k.apply(this,arguments)||this}o(g,k);var l=g.prototype;return l.getDOMNode=function(){function c(){return(0,e.findDOMFromVNode)(this.$LI,!0)}return c}(),l.componentDidMount=function(){function c(){var m=this,i=this.getDOMNode();i&&(i.addEventListener("mouseenter",function(){var u=g.renderedTooltip;u===void 0&&(u=document.createElement("div"),u.className="Tooltip",document.body.appendChild(u),g.renderedTooltip=u),g.currentHoveredElement=i,u.style.opacity="1",m.renderPopperContent()}),i.addEventListener("mouseleave",function(){m.fadeOut()}))}return c}(),l.fadeOut=function(){function c(){g.currentHoveredElement===this.getDOMNode()&&(g.currentHoveredElement=void 0,g.renderedTooltip.style.opacity="0")}return c}(),l.renderPopperContent=function(){function c(){var m=this,i=g.renderedTooltip;i&&(0,e.render)((0,e.createVNode)(1,"span",null,this.props.content,0),i,function(){var u=g.singletonPopper;u===void 0?(u=(0,a.createPopper)(g.virtualElement,i,Object.assign({},b,{placement:m.props.position||"auto"})),g.singletonPopper=u):(u.setOptions(Object.assign({},b,{placement:m.props.position||"auto"})),u.update())},this.context)}return c}(),l.componentDidUpdate=function(){function c(){g.currentHoveredElement===this.getDOMNode()&&this.renderPopperContent()}return c}(),l.componentWillUnmount=function(){function c(){this.fadeOut()}return c}(),l.render=function(){function c(){return this.props.children}return c}(),g}(e.Component);t=I,I.renderedTooltip=void 0,I.singletonPopper=void 0,I.currentHoveredElement=void 0,I.virtualElement={getBoundingClientRect:function(){function k(){var g,l;return(g=(l=t.currentHoveredElement)==null?void 0:l.getBoundingClientRect())!=null?g:y}return k}()}},36036:function(T,r,n){"use strict";r.__esModule=!0,r.Tooltip=r.TimeDisplay=r.TextArea=r.Tabs=r.Table=r.Stack=r.Slider=r.Section=r.RoundGauge=r.RestrictedInput=r.ProgressBar=r.Popper=r.Pointer=r.NumberInput=r.NoticeBox=r.NanoMap=r.Modal=r.LabeledList=r.LabeledControls=r.Knob=r.Interactive=r.Input=r.ImageButton=r.Image=r.Icon=r.Grid=r.Flex=r.Dropdown=r.DraggableControl=r.DmIcon=r.Divider=r.Dimmer=r.Countdown=r.ColorBox=r.Collapsible=r.Chart=r.ByondUi=r.Button=r.Box=r.BlockQuote=r.Blink=r.Autofocus=r.AnimatedNumber=void 0;var e=n(9474);r.AnimatedNumber=e.AnimatedNumber;var a=n(27185);r.Autofocus=a.Autofocus;var t=n(5814);r.Blink=t.Blink;var o=n(61773);r.BlockQuote=o.BlockQuote;var f=n(55937);r.Box=f.Box;var b=n(96184);r.Button=b.Button;var y=n(18982);r.ByondUi=y.ByondUi;var I=n(66820);r.Chart=I.Chart;var k=n(4796);r.Collapsible=k.Collapsible;var g=n(88894);r.ColorBox=g.ColorBox;var l=n(73379);r.Countdown=l.Countdown;var c=n(61940);r.Dimmer=c.Dimmer;var m=n(13605);r.Divider=m.Divider;var i=n(20342);r.DraggableControl=i.DraggableControl;var u=n(87099);r.Dropdown=u.Dropdown;var s=n(39473);r.Flex=s.Flex;var d=n(79646);r.Grid=d.Grid;var v=n(4454);r.Interactive=v.Interactive;var h=n(91225);r.Image=h.Image;var C=n(60218);r.DmIcon=C.DmIcon;var p=n(1331);r.Icon=p.Icon;var N=n(79825);r.ImageButton=N.ImageButton;var V=n(79652);r.Input=V.Input;var S=n(76334);r.Knob=S.Knob;var B=n(78621);r.LabeledControls=B.LabeledControls;var L=n(29319);r.LabeledList=L.LabeledList;var w=n(36077);r.Modal=w.Modal;var A=n(73280);r.NanoMap=A.NanoMap;var x=n(74733);r.NoticeBox=x.NoticeBox;var E=n(59263);r.NumberInput=E.NumberInput;var P=n(33337);r.Pointer=P.Pointer;var D=n(50186);r.Popper=D.Popper;var M=n(92704);r.ProgressBar=M.ProgressBar;var R=n(9075);r.RestrictedInput=R.RestrictedInput;var O=n(11441);r.RoundGauge=O.RoundGauge;var F=n(97079);r.Section=F.Section;var _=n(79911);r.Slider=_.Slider;var U=n(96690);r.Stack=U.Stack;var z=n(36352);r.Table=z.Table;var $=n(85138);r.Tabs=$.Tabs;var G=n(44868);r.TextArea=G.TextArea;var X=n(5169);r.TimeDisplay=X.TimeDisplay;var J=n(62147);r.Tooltip=J.Tooltip},76910:function(T,r){"use strict";r.__esModule=!0,r.timeAgo=r.getGasLabel=r.getGasColor=r.UI_UPDATE=r.UI_INTERACTIVE=r.UI_DISABLED=r.UI_CLOSE=r.RADIO_CHANNELS=r.CSS_COLORS=r.COLORS=void 0;var n=r.UI_INTERACTIVE=2,e=r.UI_UPDATE=1,a=r.UI_DISABLED=0,t=r.UI_CLOSE=-1,o=r.COLORS={department:{command:"#526aff",security:"#CF0000",medical:"#009190",science:"#993399",engineering:"#A66300",supply:"#9F8545",service:"#80A000",centcom:"#78789B",other:"#C38312"},damageType:{oxy:"#3498db",toxin:"#2ecc71",burn:"#e67e22",brute:"#e74c3c"}},f=r.CSS_COLORS=["black","white","red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey","good","average","bad","label"],b=r.RADIO_CHANNELS=[{name:"Syndicate",freq:1213,color:"#a52a2a"},{name:"SyndTeam",freq:1244,color:"#a52a2a"},{name:"Red Team",freq:1215,color:"#ff4444"},{name:"Blue Team",freq:1217,color:"#3434fd"},{name:"Response Team",freq:1345,color:"#2681a5"},{name:"Special Ops",freq:1341,color:"#2681a5"},{name:"Supply",freq:1347,color:"#b88646"},{name:"Service",freq:1349,color:"#6ca729"},{name:"Science",freq:1351,color:"#c68cfa"},{name:"Command",freq:1353,color:"#5177ff"},{name:"Procedure",freq:1339,color:"#F70285"},{name:"Medical",freq:1355,color:"#57b8f0"},{name:"Medical(I)",freq:1485,color:"#57b8f0"},{name:"Engineering",freq:1357,color:"#f37746"},{name:"Security",freq:1359,color:"#dd3535"},{name:"Security(I)",freq:1475,color:"#dd3535"},{name:"AI Private",freq:1343,color:"#d65d95"},{name:"Common",freq:1459,color:"#1ecc43"}],y=[{id:"o2",name:"Oxygen",label:"O\u2082",color:"blue"},{id:"n2",name:"Nitrogen",label:"N\u2082",color:"red"},{id:"co2",name:"Carbon Dioxide",label:"CO\u2082",color:"grey"},{id:"plasma",name:"Plasma",label:"Plasma",color:"pink"},{id:"water_vapor",name:"Water Vapor",label:"H\u2082O",color:"grey"},{id:"nob",name:"Hyper-noblium",label:"Hyper-nob",color:"teal"},{id:"n2o",name:"Nitrous Oxide",label:"N\u2082O",color:"red"},{id:"no2",name:"Nitryl",label:"NO\u2082",color:"brown"},{id:"tritium",name:"Tritium",label:"Tritium",color:"green"},{id:"bz",name:"BZ",label:"BZ",color:"purple"},{id:"stim",name:"Stimulum",label:"Stimulum",color:"purple"},{id:"pluox",name:"Pluoxium",label:"Pluoxium",color:"blue"},{id:"miasma",name:"Miasma",label:"Miasma",color:"olive"},{id:"hydrogen",name:"Hydrogen",label:"H\u2082",color:"white"},{id:"ab",name:"Agent B",label:"Agent B",color:"purple"}],I=r.getGasLabel=function(){function l(c,m){var i=String(c).toLowerCase(),u=y.find(function(s){return s.id===i||s.name.toLowerCase()===i});return u&&u.label||m||c}return l}(),k=r.getGasColor=function(){function l(c){var m=String(c).toLowerCase(),i=y.find(function(u){return u.id===m||u.name.toLowerCase()===m});return i&&i.color}return l}(),g=r.timeAgo=function(){function l(c,m){if(c>m)return"in the future";c=c/10,m=m/10;var i=m-c;if(i>3600){var u=Math.round(i/3600);return u+" hour"+(u===1?"":"s")+" ago"}else if(i>60){var s=Math.round(i/60);return s+" minute"+(s===1?"":"s")+" ago"}else{var d=Math.round(i);return d+" second"+(d===1?"":"s")+" ago"}return"just now"}return l}()},40944:function(T,r,n){"use strict";r.__esModule=!0,r.KitchenSink=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595);/** * @file * @copyright 2020 Aleksej Komarov * @license MIT */var f=n(4085),b=function(){return f.keys().map(function(k){return f(k)})},y=r.KitchenSink=function(){function I(k,g){var l=k.panel,c=(0,a.useLocalState)(g,"kitchenSinkTheme"),m=c[0],i=(0,a.useLocalState)(g,"pageIndex",0),u=i[0],s=i[1],d=b(),v=d[u],h=l?o.Pane:o.Window;return(0,e.createComponentVNode)(2,h,{title:"Kitchen Sink",width:600,height:500,theme:m,children:(0,e.createComponentVNode)(2,t.Flex,{height:"100%",children:[(0,e.createComponentVNode)(2,t.Flex.Item,{m:1,mr:0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,fitted:!0,children:(0,e.createComponentVNode)(2,t.Tabs,{vertical:!0,children:d.map(function(C,p){return(0,e.createComponentVNode)(2,t.Tabs.Tab,{color:"transparent",selected:p===u,onClick:function(){function N(){return s(p)}return N}(),children:C.meta.title},p)})})})}),(0,e.createComponentVNode)(2,t.Flex.Item,{position:"relative",grow:1,children:(0,e.createComponentVNode)(2,h.Content,{scrollable:!0,children:v.meta.render()})})]})})}return I}()},77384:function(T,r,n){"use strict";r.__esModule=!0,r.toggleKitchenSink=r.toggleDebugLayout=r.openExternalBrowser=void 0;var e=n(85307);/** +======= +*/var i=r.TextArea=function(c){function m(u,s){var d;d=c.call(this,u,s)||this,d.textareaRef=u.innerRef||(0,e.createRef)(),d.fillerRef=(0,e.createRef)(),d.state={editing:!1};var v=u.dontUseTabForIndent,g=v===void 0?!1:v;return d.handleOnInput=function(C){var f=d.state.editing,N=d.props.onInput;f||d.setEditing(!0),N&&N(C,C.target.value)},d.handleOnChange=function(C){var f=d.state.editing,N=d.props.onChange;f&&d.setEditing(!1),N&&N(C,C.target.value)},d.handleKeyPress=function(C){var f=d.state.editing,N=d.props.onKeyPress;f||d.setEditing(!0),N&&N(C,C.target.value)},d.handleKeyDown=function(C){var f=d.state.editing,N=d.props,V=N.onChange,B=N.onInput,I=N.onEnter,L=N.onKeyDown;if(C.keyCode===p.KEY_ENTER){d.setEditing(!1),V&&V(C,C.target.value),B&&B(C,C.target.value),I&&I(C,C.target.value),d.props.selfClear&&(C.target.value="",C.target.blur());return}if(C.keyCode===p.KEY_ESCAPE){d.props.onEscape&&d.props.onEscape(C),d.setEditing(!1),d.props.selfClear?C.target.value="":(C.target.value=(0,o.toInputValue)(d.props.value),C.target.blur());return}if(f||d.setEditing(!0),L&&L(C,C.target.value),!g){var w=C.keyCode||C.which;if(w===p.KEY_TAB){C.preventDefault();var A=C.target,x=A.value,E=A.selectionStart,P=A.selectionEnd;C.target.value=x.substring(0,E)+" "+x.substring(P),C.target.selectionEnd=E+1}}},d.handleFocus=function(C){var f=d.state.editing;f||d.setEditing(!0)},d.handleBlur=function(C){var f=d.state.editing,N=d.props.onChange;f&&(d.setEditing(!1),N&&N(C,C.target.value))},d}k(m,c);var l=m.prototype;return l.componentDidMount=function(){function u(){var s=this,d=this.props.value,v=this.textareaRef.current;v&&(v.value=(0,o.toInputValue)(d)),(this.props.autoFocus||this.props.autoSelect)&&setTimeout(function(){v.focus(),s.props.autoSelect&&v.select()},1)}return u}(),l.componentDidUpdate=function(){function u(s,d){var v=s.value,g=this.props.value,C=this.textareaRef.current;C&&typeof g=="string"&&v!==g&&(C.value=(0,o.toInputValue)(g))}return u}(),l.setEditing=function(){function u(s){this.setState({editing:s})}return u}(),l.getValue=function(){function u(){return this.textareaRef.current&&this.textareaRef.current.value}return u}(),l.render=function(){function u(){var s=this.props,d=s.onChange,v=s.onKeyDown,g=s.onKeyPress,C=s.onInput,f=s.onFocus,N=s.onBlur,V=s.onEnter,B=s.value,I=s.maxLength,L=s.placeholder,w=S(s,b),A=w.className,x=w.fluid,E=S(w,y);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.Box,Object.assign({className:(0,a.classes)(["TextArea",x&&"TextArea--fluid",A])},E,{children:(0,e.createVNode)(128,"textarea","TextArea__textarea",null,1,{placeholder:L,onChange:this.handleOnChange,onKeyDown:this.handleKeyDown,onKeyPress:this.handleKeyPress,onInput:this.handleOnInput,onFocus:this.handleFocus,onBlur:this.handleBlur,maxLength:I},null,this.textareaRef)})))}return u}(),m}(e.Component)},5169:function(T,r){"use strict";r.__esModule=!0,r.TimeDisplay=void 0;var n=function(t){(!t||t<0)&&(t=0);var o=Math.floor(t/60).toString(10),p=(Math.floor(t)%60).toString(10);return[o,p].map(function(b){return b.length<2?"0"+b:b}).join(":")},e=r.TimeDisplay=function(){function a(t){var o=t.totalSeconds,p=o===void 0?0:o;return n(p)}return a}()},62147:function(T,r,n){"use strict";r.__esModule=!0,r.Tooltip=void 0;var e=n(89005),a=n(95996),t;function o(k,h){k.prototype=Object.create(h.prototype),k.prototype.constructor=k,p(k,h)}function p(k,h){return p=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(i,c){return i.__proto__=c,i},p(k,h)}var b={modifiers:[{name:"eventListeners",enabled:!1}]},y={width:0,height:0,top:0,right:0,bottom:0,left:0,x:0,y:0,toJSON:function(){function k(){return null}return k}()},S=r.Tooltip=function(k){function h(){return k.apply(this,arguments)||this}o(h,k);var i=h.prototype;return i.getDOMNode=function(){function c(){return(0,e.findDOMFromVNode)(this.$LI,!0)}return c}(),i.componentDidMount=function(){function c(){var m=this,l=this.getDOMNode();l&&(l.addEventListener("mouseenter",function(){var u=h.renderedTooltip;u===void 0&&(u=document.createElement("div"),u.className="Tooltip",document.body.appendChild(u),h.renderedTooltip=u),h.currentHoveredElement=l,u.style.opacity="1",m.renderPopperContent()}),l.addEventListener("mouseleave",function(){m.fadeOut()}))}return c}(),i.fadeOut=function(){function c(){h.currentHoveredElement===this.getDOMNode()&&(h.currentHoveredElement=void 0,h.renderedTooltip.style.opacity="0")}return c}(),i.renderPopperContent=function(){function c(){var m=this,l=h.renderedTooltip;l&&(0,e.render)((0,e.createVNode)(1,"span",null,this.props.content,0),l,function(){var u=h.singletonPopper;u===void 0?(u=(0,a.createPopper)(h.virtualElement,l,Object.assign({},b,{placement:m.props.position||"auto"})),h.singletonPopper=u):(u.setOptions(Object.assign({},b,{placement:m.props.position||"auto"})),u.update())},this.context)}return c}(),i.componentDidUpdate=function(){function c(){h.currentHoveredElement===this.getDOMNode()&&this.renderPopperContent()}return c}(),i.componentWillUnmount=function(){function c(){this.fadeOut()}return c}(),i.render=function(){function c(){return this.props.children}return c}(),h}(e.Component);t=S,S.renderedTooltip=void 0,S.singletonPopper=void 0,S.currentHoveredElement=void 0,S.virtualElement={getBoundingClientRect:function(){function k(){var h,i;return(h=(i=t.currentHoveredElement)==null?void 0:i.getBoundingClientRect())!=null?h:y}return k}()}},36036:function(T,r,n){"use strict";r.__esModule=!0,r.Tooltip=r.TimeDisplay=r.TextArea=r.Tabs=r.Table=r.Stack=r.Slider=r.Section=r.RoundGauge=r.RestrictedInput=r.ProgressBar=r.Popper=r.Pointer=r.NumberInput=r.NoticeBox=r.NanoMap=r.Modal=r.LabeledList=r.LabeledControls=r.Knob=r.Interactive=r.Input=r.ImageButton=r.Image=r.Icon=r.Grid=r.Flex=r.Dropdown=r.DraggableControl=r.DmIcon=r.Divider=r.Dimmer=r.Countdown=r.ColorBox=r.Collapsible=r.Chart=r.ByondUi=r.Button=r.Box=r.BlockQuote=r.Blink=r.Autofocus=r.AnimatedNumber=void 0;var e=n(9474);r.AnimatedNumber=e.AnimatedNumber;var a=n(27185);r.Autofocus=a.Autofocus;var t=n(5814);r.Blink=t.Blink;var o=n(61773);r.BlockQuote=o.BlockQuote;var p=n(55937);r.Box=p.Box;var b=n(96184);r.Button=b.Button;var y=n(18982);r.ByondUi=y.ByondUi;var S=n(66820);r.Chart=S.Chart;var k=n(4796);r.Collapsible=k.Collapsible;var h=n(88894);r.ColorBox=h.ColorBox;var i=n(73379);r.Countdown=i.Countdown;var c=n(61940);r.Dimmer=c.Dimmer;var m=n(13605);r.Divider=m.Divider;var l=n(20342);r.DraggableControl=l.DraggableControl;var u=n(87099);r.Dropdown=u.Dropdown;var s=n(39473);r.Flex=s.Flex;var d=n(79646);r.Grid=d.Grid;var v=n(4454);r.Interactive=v.Interactive;var g=n(91225);r.Image=g.Image;var C=n(60218);r.DmIcon=C.DmIcon;var f=n(1331);r.Icon=f.Icon;var N=n(79825);r.ImageButton=N.ImageButton;var V=n(79652);r.Input=V.Input;var B=n(76334);r.Knob=B.Knob;var I=n(78621);r.LabeledControls=I.LabeledControls;var L=n(29319);r.LabeledList=L.LabeledList;var w=n(36077);r.Modal=w.Modal;var A=n(73280);r.NanoMap=A.NanoMap;var x=n(74733);r.NoticeBox=x.NoticeBox;var E=n(59263);r.NumberInput=E.NumberInput;var P=n(33337);r.Pointer=P.Pointer;var D=n(50186);r.Popper=D.Popper;var M=n(92704);r.ProgressBar=M.ProgressBar;var O=n(9075);r.RestrictedInput=O.RestrictedInput;var R=n(11441);r.RoundGauge=R.RoundGauge;var F=n(97079);r.Section=F.Section;var W=n(79911);r.Slider=W.Slider;var U=n(96690);r.Stack=U.Stack;var z=n(36352);r.Table=z.Table;var $=n(85138);r.Tabs=$.Tabs;var G=n(44868);r.TextArea=G.TextArea;var X=n(5169);r.TimeDisplay=X.TimeDisplay;var J=n(62147);r.Tooltip=J.Tooltip},76910:function(T,r){"use strict";r.__esModule=!0,r.timeAgo=r.getGasLabel=r.getGasColor=r.UI_UPDATE=r.UI_INTERACTIVE=r.UI_DISABLED=r.UI_CLOSE=r.RADIO_CHANNELS=r.CSS_COLORS=r.COLORS=void 0;var n=r.UI_INTERACTIVE=2,e=r.UI_UPDATE=1,a=r.UI_DISABLED=0,t=r.UI_CLOSE=-1,o=r.COLORS={department:{command:"#526aff",security:"#CF0000",medical:"#009190",science:"#993399",engineering:"#A66300",supply:"#9F8545",service:"#80A000",centcom:"#78789B",other:"#C38312"},damageType:{oxy:"#3498db",toxin:"#2ecc71",burn:"#e67e22",brute:"#e74c3c"}},p=r.CSS_COLORS=["black","white","red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey","good","average","bad","label"],b=r.RADIO_CHANNELS=[{name:"Syndicate",freq:1213,color:"#a52a2a"},{name:"SyndTeam",freq:1244,color:"#a52a2a"},{name:"Red Team",freq:1215,color:"#ff4444"},{name:"Blue Team",freq:1217,color:"#3434fd"},{name:"Response Team",freq:1345,color:"#2681a5"},{name:"Special Ops",freq:1341,color:"#2681a5"},{name:"Supply",freq:1347,color:"#b88646"},{name:"Service",freq:1349,color:"#6ca729"},{name:"Science",freq:1351,color:"#c68cfa"},{name:"Command",freq:1353,color:"#5177ff"},{name:"Procedure",freq:1339,color:"#F70285"},{name:"Medical",freq:1355,color:"#57b8f0"},{name:"Medical(I)",freq:1485,color:"#57b8f0"},{name:"Engineering",freq:1357,color:"#f37746"},{name:"Security",freq:1359,color:"#dd3535"},{name:"Security(I)",freq:1475,color:"#dd3535"},{name:"AI Private",freq:1343,color:"#d65d95"},{name:"Common",freq:1459,color:"#1ecc43"}],y=[{id:"o2",name:"Oxygen",label:"O\u2082",color:"blue"},{id:"n2",name:"Nitrogen",label:"N\u2082",color:"red"},{id:"co2",name:"Carbon Dioxide",label:"CO\u2082",color:"grey"},{id:"plasma",name:"Plasma",label:"Plasma",color:"pink"},{id:"water_vapor",name:"Water Vapor",label:"H\u2082O",color:"grey"},{id:"nob",name:"Hyper-noblium",label:"Hyper-nob",color:"teal"},{id:"n2o",name:"Nitrous Oxide",label:"N\u2082O",color:"red"},{id:"no2",name:"Nitryl",label:"NO\u2082",color:"brown"},{id:"tritium",name:"Tritium",label:"Tritium",color:"green"},{id:"bz",name:"BZ",label:"BZ",color:"purple"},{id:"stim",name:"Stimulum",label:"Stimulum",color:"purple"},{id:"pluox",name:"Pluoxium",label:"Pluoxium",color:"blue"},{id:"miasma",name:"Miasma",label:"Miasma",color:"olive"},{id:"hydrogen",name:"Hydrogen",label:"H\u2082",color:"white"},{id:"ab",name:"Agent B",label:"Agent B",color:"purple"}],S=r.getGasLabel=function(){function i(c,m){var l=String(c).toLowerCase(),u=y.find(function(s){return s.id===l||s.name.toLowerCase()===l});return u&&u.label||m||c}return i}(),k=r.getGasColor=function(){function i(c){var m=String(c).toLowerCase(),l=y.find(function(u){return u.id===m||u.name.toLowerCase()===m});return l&&l.color}return i}(),h=r.timeAgo=function(){function i(c,m){if(c>m)return"in the future";c=c/10,m=m/10;var l=m-c;if(l>3600){var u=Math.round(l/3600);return u+" hour"+(u===1?"":"s")+" ago"}else if(l>60){var s=Math.round(l/60);return s+" minute"+(s===1?"":"s")+" ago"}else{var d=Math.round(l);return d+" second"+(d===1?"":"s")+" ago"}return"just now"}return i}()},40944:function(T,r,n){"use strict";r.__esModule=!0,r.KitchenSink=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595);/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */var p=n(4085),b=function(){return p.keys().map(function(k){return p(k)})},y=r.KitchenSink=function(){function S(k,h){var i=k.panel,c=(0,a.useLocalState)(h,"kitchenSinkTheme"),m=c[0],l=(0,a.useLocalState)(h,"pageIndex",0),u=l[0],s=l[1],d=b(),v=d[u],g=i?o.Pane:o.Window;return(0,e.createComponentVNode)(2,g,{title:"Kitchen Sink",width:600,height:500,theme:m,children:(0,e.createComponentVNode)(2,t.Flex,{height:"100%",children:[(0,e.createComponentVNode)(2,t.Flex.Item,{m:1,mr:0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,fitted:!0,children:(0,e.createComponentVNode)(2,t.Tabs,{vertical:!0,children:d.map(function(C,f){return(0,e.createComponentVNode)(2,t.Tabs.Tab,{color:"transparent",selected:f===u,onClick:function(){function N(){return s(f)}return N}(),children:C.meta.title},f)})})})}),(0,e.createComponentVNode)(2,t.Flex.Item,{position:"relative",grow:1,children:(0,e.createComponentVNode)(2,g.Content,{scrollable:!0,children:v.meta.render()})})]})})}return S}()},77384:function(T,r,n){"use strict";r.__esModule=!0,r.toggleKitchenSink=r.toggleDebugLayout=r.openExternalBrowser=void 0;var e=n(85307);/** +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * @file * @copyright 2020 Aleksej Komarov * @license MIT @@ -206,29 +390,41 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var t=r.useDebug=function(){function o(f){return(0,e.useSelector)(f,a.selectDebug)}return o}()},99851:function(T,r,n){"use strict";r.__esModule=!0,r.useDebug=r.relayMiddleware=r.debugReducer=r.debugMiddleware=r.KitchenSink=void 0;var e=n(92731);r.useDebug=e.useDebug;var a=n(40944);r.KitchenSink=a.KitchenSink;var t=n(3583);r.debugMiddleware=t.debugMiddleware,r.relayMiddleware=t.relayMiddleware;var o=n(19147);r.debugReducer=o.debugReducer},3583:function(T,r,n){"use strict";r.__esModule=!0,r.relayMiddleware=r.debugMiddleware=void 0;var e=n(92986),a=n(24826),t=n(56518),o=n(77384);/** + */var t=r.useDebug=function(){function o(p){return(0,e.useSelector)(p,a.selectDebug)}return o}()},99851:function(T,r,n){"use strict";r.__esModule=!0,r.useDebug=r.relayMiddleware=r.debugReducer=r.debugMiddleware=r.KitchenSink=void 0;var e=n(92731);r.useDebug=e.useDebug;var a=n(40944);r.KitchenSink=a.KitchenSink;var t=n(3583);r.debugMiddleware=t.debugMiddleware,r.relayMiddleware=t.relayMiddleware;var o=n(19147);r.debugReducer=o.debugReducer},3583:function(T,r,n){"use strict";r.__esModule=!0,r.relayMiddleware=r.debugMiddleware=void 0;var e=n(92986),a=n(24826),t=n(56518),o=n(77384);/** * @file * @copyright 2020 Aleksej Komarov * @license MIT +<<<<<<< HEAD */var f=["backend/update","chat/message"],b=r.debugMiddleware=function(){function I(k){return(0,t.acquireHotKey)(e.KEY_F11),(0,t.acquireHotKey)(e.KEY_F12),a.globalEvents.on("keydown",function(g){g.code===e.KEY_F11&&k.dispatch((0,o.toggleDebugLayout)()),g.code===e.KEY_F12&&k.dispatch((0,o.toggleKitchenSink)()),g.ctrl&&g.alt&&g.code===e.KEY_BACKSPACE&&setTimeout(function(){throw new Error("OOPSIE WOOPSIE!! UwU We made a fucky wucky!! A wittle fucko boingo! The code monkeys at our headquarters are working VEWY HAWD to fix this!")})}),function(g){return function(l){return g(l)}}}return I}(),y=r.relayMiddleware=function(){function I(k){var g=n(7435),l=location.search==="?external";return l?g.subscribe(function(c){var m=c.type,i=c.payload;m==="relay"&&i.windowId===Byond.windowId&&k.dispatch(Object.assign({},i.action,{relayed:!0}))}):((0,t.acquireHotKey)(e.KEY_F10),a.globalEvents.on("keydown",function(c){c===e.KEY_F10&&k.dispatch((0,o.openExternalBrowser)())})),function(c){return function(m){var i=m.type,u=m.payload,s=m.relayed;if(i===o.openExternalBrowser.type){window.open(location.href+"?external","_blank");return}return f.includes(i)&&!s&&!l&&g.sendMessage({type:"relay",payload:{windowId:Byond.windowId,action:m}}),c(m)}}}return I}()},19147:function(T,r){"use strict";r.__esModule=!0,r.debugReducer=void 0;/** +======= + */var p=["backend/update","chat/message"],b=r.debugMiddleware=function(){function S(k){return(0,t.acquireHotKey)(e.KEY_F11),(0,t.acquireHotKey)(e.KEY_F12),a.globalEvents.on("keydown",function(h){h.code===e.KEY_F11&&k.dispatch((0,o.toggleDebugLayout)()),h.code===e.KEY_F12&&k.dispatch((0,o.toggleKitchenSink)()),h.ctrl&&h.alt&&h.code===e.KEY_BACKSPACE&&setTimeout(function(){throw new Error("OOPSIE WOOPSIE!! UwU We made a fucky wucky!! A wittle fucko boingo! The code monkeys at our headquarters are working VEWY HAWD to fix this!")})}),function(h){return function(i){return h(i)}}}return S}(),y=r.relayMiddleware=function(){function S(k){var h=n(7435),i=location.search==="?external";return i?h.subscribe(function(c){var m=c.type,l=c.payload;m==="relay"&&l.windowId===Byond.windowId&&k.dispatch(Object.assign({},l.action,{relayed:!0}))}):((0,t.acquireHotKey)(e.KEY_F10),a.globalEvents.on("keydown",function(c){c===e.KEY_F10&&k.dispatch((0,o.openExternalBrowser)())})),function(c){return function(m){var l=m.type,u=m.payload,s=m.relayed;if(l===o.openExternalBrowser.type){window.open(location.href+"?external","_blank");return}return p.includes(l)&&!s&&!i&&h.sendMessage({type:"relay",payload:{windowId:Byond.windowId,action:m}}),c(m)}}}return S}()},19147:function(T,r){"use strict";r.__esModule=!0,r.debugReducer=void 0;/** +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var n=r.debugReducer=function(){function e(a,t){a===void 0&&(a={});var o=t.type,f=t.payload;return o==="debug/toggleKitchenSink"?Object.assign({},a,{kitchenSink:!a.kitchenSink}):o==="debug/toggleDebugLayout"?Object.assign({},a,{debugLayout:!a.debugLayout}):a}return e}()},27709:function(T,r){"use strict";r.__esModule=!0,r.selectDebug=void 0;/** + */var n=r.debugReducer=function(){function e(a,t){a===void 0&&(a={});var o=t.type,p=t.payload;return o==="debug/toggleKitchenSink"?Object.assign({},a,{kitchenSink:!a.kitchenSink}):o==="debug/toggleDebugLayout"?Object.assign({},a,{debugLayout:!a.debugLayout}):a}return e}()},27709:function(T,r){"use strict";r.__esModule=!0,r.selectDebug=void 0;/** * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var n=r.selectDebug=function(){function e(a){return a.debug}return e}()},35421:function(T,r,n){"use strict";r.__esModule=!0,r.storeWindowGeometry=r.setupDrag=r.setWindowSize=r.setWindowPosition=r.setWindowKey=r.resizeStartHandler=r.recallWindowGeometry=r.getWindowSize=r.getWindowPosition=r.getScreenSize=r.getScreenPosition=r.dragStartHandler=void 0;var e=n(27108),a=n(97450),t=n(9394);function o(){"use strict";/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */o=function(){return F};var O,F={},_=Object.prototype,U=_.hasOwnProperty,z=Object.defineProperty||function(ye,de,he){ye[de]=he.value},$=typeof Symbol=="function"?Symbol:{},G=$.iterator||"@@iterator",X=$.asyncIterator||"@@asyncIterator",J=$.toStringTag||"@@toStringTag";function se(ye,de,he){return Object.defineProperty(ye,de,{value:he,enumerable:!0,configurable:!0,writable:!0}),ye[de]}try{se({},"")}catch(ye){se=function(he,ke,ve){return he[ke]=ve}}function ie(ye,de,he,ke){var ve=de&&de.prototype instanceof ne?de:ne,Se=Object.create(ve.prototype),Pe=new Re(ke||[]);return z(Se,"_invoke",{value:be(ye,he,Pe)}),Se}function me(ye,de,he){try{return{type:"normal",arg:ye.call(de,he)}}catch(ke){return{type:"throw",arg:ke}}}F.wrap=ie;var q="suspendedStart",re="suspendedYield",ae="executing",le="completed",Z={};function ne(){}function te(){}function fe(){}var pe={};se(pe,G,function(){return this});var ce=Object.getPrototypeOf,Ve=ce&&ce(ce(He([])));Ve&&Ve!==_&&U.call(Ve,G)&&(pe=Ve);var Ce=fe.prototype=ne.prototype=Object.create(pe);function Ne(ye){["next","throw","return"].forEach(function(de){se(ye,de,function(he){return this._invoke(de,he)})})}function Be(ye,de){function he(ve,Se,Pe,je){var Fe=me(ye[ve],ye,Se);if(Fe.type!=="throw"){var ze=Fe.arg,We=ze.value;return We&&typeof We=="object"&&U.call(We,"__await")?de.resolve(We.__await).then(function(Ue){he("next",Ue,Pe,je)},function(Ue){he("throw",Ue,Pe,je)}):de.resolve(We).then(function(Ue){ze.value=Ue,Pe(ze)},function(Ue){return he("throw",Ue,Pe,je)})}je(Fe.arg)}var ke;z(this,"_invoke",{value:function(){function ve(Se,Pe){function je(){return new de(function(Fe,ze){he(Se,Pe,Fe,ze)})}return ke=ke?ke.then(je,je):je()}return ve}()})}function be(ye,de,he){var ke=q;return function(ve,Se){if(ke===ae)throw Error("Generator is already running");if(ke===le){if(ve==="throw")throw Se;return{value:O,done:!0}}for(he.method=ve,he.arg=Se;;){var Pe=he.delegate;if(Pe){var je=Le(Pe,he);if(je){if(je===Z)continue;return je}}if(he.method==="next")he.sent=he._sent=he.arg;else if(he.method==="throw"){if(ke===q)throw ke=le,he.arg;he.dispatchException(he.arg)}else he.method==="return"&&he.abrupt("return",he.arg);ke=ae;var Fe=me(ye,de,he);if(Fe.type==="normal"){if(ke=he.done?le:re,Fe.arg===Z)continue;return{value:Fe.arg,done:he.done}}Fe.type==="throw"&&(ke=le,he.method="throw",he.arg=Fe.arg)}}}function Le(ye,de){var he=de.method,ke=ye.iterator[he];if(ke===O)return de.delegate=null,he==="throw"&&ye.iterator.return&&(de.method="return",de.arg=O,Le(ye,de),de.method==="throw")||he!=="return"&&(de.method="throw",de.arg=new TypeError("The iterator does not provide a '"+he+"' method")),Z;var ve=me(ke,ye.iterator,de.arg);if(ve.type==="throw")return de.method="throw",de.arg=ve.arg,de.delegate=null,Z;var Se=ve.arg;return Se?Se.done?(de[ye.resultName]=Se.value,de.next=ye.nextLoc,de.method!=="return"&&(de.method="next",de.arg=O),de.delegate=null,Z):Se:(de.method="throw",de.arg=new TypeError("iterator result is not an object"),de.delegate=null,Z)}function we(ye){var de={tryLoc:ye[0]};1 in ye&&(de.catchLoc=ye[1]),2 in ye&&(de.finallyLoc=ye[2],de.afterLoc=ye[3]),this.tryEntries.push(de)}function xe(ye){var de=ye.completion||{};de.type="normal",delete de.arg,ye.completion=de}function Re(ye){this.tryEntries=[{tryLoc:"root"}],ye.forEach(we,this),this.reset(!0)}function He(ye){if(ye||ye===""){var de=ye[G];if(de)return de.call(ye);if(typeof ye.next=="function")return ye;if(!isNaN(ye.length)){var he=-1,ke=function(){function ve(){for(;++he=0;--ve){var Se=this.tryEntries[ve],Pe=Se.completion;if(Se.tryLoc==="root")return ke("end");if(Se.tryLoc<=this.prev){var je=U.call(Se,"catchLoc"),Fe=U.call(Se,"finallyLoc");if(je&&Fe){if(this.prev=0;--ke){var ve=this.tryEntries[ke];if(ve.tryLoc<=this.prev&&U.call(ve,"finallyLoc")&&this.prev=0;--he){var ke=this.tryEntries[he];if(ke.finallyLoc===de)return this.complete(ke.completion,ke.afterLoc),xe(ke),Z}}return ye}(),catch:function(){function ye(de){for(var he=this.tryEntries.length-1;he>=0;--he){var ke=this.tryEntries[he];if(ke.tryLoc===de){var ve=ke.completion;if(ve.type==="throw"){var Se=ve.arg;xe(ke)}return Se}}throw Error("illegal catch attempt")}return ye}(),delegateYield:function(){function ye(de,he,ke){return this.delegate={iterator:He(de),resultName:he,nextLoc:ke},this.method==="next"&&(this.arg=O),Z}return ye}()},F}function f(O,F,_,U,z,$,G){try{var X=O[$](G),J=X.value}catch(se){return void _(se)}X.done?F(J):Promise.resolve(J).then(U,z)}function b(O){return function(){var F=this,_=arguments;return new Promise(function(U,z){var $=O.apply(F,_);function G(J){f($,U,z,G,X,"next",J)}function X(J){f($,U,z,G,X,"throw",J)}G(void 0)})}}/** + */var n=r.selectDebug=function(){function e(a){return a.debug}return e}()},35421:function(T,r,n){"use strict";r.__esModule=!0,r.storeWindowGeometry=r.setupDrag=r.setWindowSize=r.setWindowPosition=r.setWindowKey=r.resizeStartHandler=r.recallWindowGeometry=r.getWindowSize=r.getWindowPosition=r.getScreenSize=r.getScreenPosition=r.dragStartHandler=void 0;var e=n(27108),a=n(97450),t=n(9394);function o(){"use strict";/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */o=function(){return F};var R,F={},W=Object.prototype,U=W.hasOwnProperty,z=Object.defineProperty||function(ye,de,he){ye[de]=he.value},$=typeof Symbol=="function"?Symbol:{},G=$.iterator||"@@iterator",X=$.asyncIterator||"@@asyncIterator",J=$.toStringTag||"@@toStringTag";function se(ye,de,he){return Object.defineProperty(ye,de,{value:he,enumerable:!0,configurable:!0,writable:!0}),ye[de]}try{se({},"")}catch(ye){se=function(he,ke,ve){return he[ke]=ve}}function ie(ye,de,he,ke){var ve=de&&de.prototype instanceof ne?de:ne,Se=Object.create(ve.prototype),Pe=new Re(ke||[]);return z(Se,"_invoke",{value:be(ye,he,Pe)}),Se}function me(ye,de,he){try{return{type:"normal",arg:ye.call(de,he)}}catch(ke){return{type:"throw",arg:ke}}}F.wrap=ie;var q="suspendedStart",re="suspendedYield",ae="executing",le="completed",Z={};function ne(){}function te(){}function fe(){}var pe={};se(pe,G,function(){return this});var ce=Object.getPrototypeOf,Ve=ce&&ce(ce(He([])));Ve&&Ve!==W&&U.call(Ve,G)&&(pe=Ve);var Ce=fe.prototype=ne.prototype=Object.create(pe);function Ne(ye){["next","throw","return"].forEach(function(de){se(ye,de,function(he){return this._invoke(de,he)})})}function Be(ye,de){function he(ve,Se,Pe,je){var Fe=me(ye[ve],ye,Se);if(Fe.type!=="throw"){var ze=Fe.arg,We=ze.value;return We&&typeof We=="object"&&U.call(We,"__await")?de.resolve(We.__await).then(function(Ue){he("next",Ue,Pe,je)},function(Ue){he("throw",Ue,Pe,je)}):de.resolve(We).then(function(Ue){ze.value=Ue,Pe(ze)},function(Ue){return he("throw",Ue,Pe,je)})}je(Fe.arg)}var ke;z(this,"_invoke",{value:function(){function ve(Se,Pe){function je(){return new de(function(Fe,ze){he(Se,Pe,Fe,ze)})}return ke=ke?ke.then(je,je):je()}return ve}()})}function be(ye,de,he){var ke=q;return function(ve,Se){if(ke===ae)throw Error("Generator is already running");if(ke===le){if(ve==="throw")throw Se;return{value:R,done:!0}}for(he.method=ve,he.arg=Se;;){var Pe=he.delegate;if(Pe){var je=Le(Pe,he);if(je){if(je===Z)continue;return je}}if(he.method==="next")he.sent=he._sent=he.arg;else if(he.method==="throw"){if(ke===q)throw ke=le,he.arg;he.dispatchException(he.arg)}else he.method==="return"&&he.abrupt("return",he.arg);ke=ae;var Fe=me(ye,de,he);if(Fe.type==="normal"){if(ke=he.done?le:re,Fe.arg===Z)continue;return{value:Fe.arg,done:he.done}}Fe.type==="throw"&&(ke=le,he.method="throw",he.arg=Fe.arg)}}}function Le(ye,de){var he=de.method,ke=ye.iterator[he];if(ke===R)return de.delegate=null,he==="throw"&&ye.iterator.return&&(de.method="return",de.arg=R,Le(ye,de),de.method==="throw")||he!=="return"&&(de.method="throw",de.arg=new TypeError("The iterator does not provide a '"+he+"' method")),Z;var ve=me(ke,ye.iterator,de.arg);if(ve.type==="throw")return de.method="throw",de.arg=ve.arg,de.delegate=null,Z;var Se=ve.arg;return Se?Se.done?(de[ye.resultName]=Se.value,de.next=ye.nextLoc,de.method!=="return"&&(de.method="next",de.arg=R),de.delegate=null,Z):Se:(de.method="throw",de.arg=new TypeError("iterator result is not an object"),de.delegate=null,Z)}function we(ye){var de={tryLoc:ye[0]};1 in ye&&(de.catchLoc=ye[1]),2 in ye&&(de.finallyLoc=ye[2],de.afterLoc=ye[3]),this.tryEntries.push(de)}function xe(ye){var de=ye.completion||{};de.type="normal",delete de.arg,ye.completion=de}function Re(ye){this.tryEntries=[{tryLoc:"root"}],ye.forEach(we,this),this.reset(!0)}function He(ye){if(ye||ye===""){var de=ye[G];if(de)return de.call(ye);if(typeof ye.next=="function")return ye;if(!isNaN(ye.length)){var he=-1,ke=function(){function ve(){for(;++he=0;--ve){var Se=this.tryEntries[ve],Pe=Se.completion;if(Se.tryLoc==="root")return ke("end");if(Se.tryLoc<=this.prev){var je=U.call(Se,"catchLoc"),Fe=U.call(Se,"finallyLoc");if(je&&Fe){if(this.prev=0;--ke){var ve=this.tryEntries[ke];if(ve.tryLoc<=this.prev&&U.call(ve,"finallyLoc")&&this.prev=0;--he){var ke=this.tryEntries[he];if(ke.finallyLoc===de)return this.complete(ke.completion,ke.afterLoc),xe(ke),Z}}return ye}(),catch:function(){function ye(de){for(var he=this.tryEntries.length-1;he>=0;--he){var ke=this.tryEntries[he];if(ke.tryLoc===de){var ve=ke.completion;if(ve.type==="throw"){var Se=ve.arg;xe(ke)}return Se}}throw Error("illegal catch attempt")}return ye}(),delegateYield:function(){function ye(de,he,ke){return this.delegate={iterator:He(de),resultName:he,nextLoc:ke},this.method==="next"&&(this.arg=R),Z}return ye}()},F}function p(R,F,W,U,z,$,G){try{var X=R[$](G),J=X.value}catch(se){return void W(se)}X.done?F(J):Promise.resolve(J).then(U,z)}function b(R){return function(){var F=this,W=arguments;return new Promise(function(U,z){var $=R.apply(F,W);function G(J){p($,U,z,G,X,"next",J)}function X(J){p($,U,z,G,X,"throw",J)}G(void 0)})}}/** * @file * @copyright 2020 Aleksej Komarov * @license MIT +<<<<<<< HEAD */var y=(0,t.createLogger)("drag"),I=Byond.windowId,k=!1,g=!1,l=[0,0],c,m,i,u,s,d=r.setWindowKey=function(){function O(F){I=F}return O}(),v=r.getWindowPosition=function(){function O(){return[window.screenLeft,window.screenTop]}return O}(),h=r.getWindowSize=function(){function O(){return[window.innerWidth,window.innerHeight]}return O}(),C=r.setWindowPosition=function(){function O(F){var _=(0,a.vecAdd)(F,l);return Byond.winset(Byond.windowId,{pos:_[0]+","+_[1]})}return O}(),p=r.setWindowSize=function(){function O(F){return Byond.winset(Byond.windowId,{size:F[0]+"x"+F[1]})}return O}(),N=r.getScreenPosition=function(){function O(){return[0-l[0],0-l[1]]}return O}(),V=r.getScreenSize=function(){function O(){return[window.screen.availWidth,window.screen.availHeight]}return O}(),S=function(F,_,U){U===void 0&&(U=50);for(var z=[_],$,G=0;Gse&&($[X]=se-_[X],G=!0)}return[G,$]},x=r.dragStartHandler=function(){function O(F){y.log("drag start"),k=!0,m=[window.screenLeft-F.screenX,window.screenTop-F.screenY],document.addEventListener("mousemove",P),document.addEventListener("mouseup",E),P(F)}return O}(),E=function O(F){y.log("drag end"),P(F),document.removeEventListener("mousemove",P),document.removeEventListener("mouseup",O),k=!1,B()},P=function(F){k&&(F.preventDefault(),C((0,a.vecAdd)([F.screenX,F.screenY],m)))},D=r.resizeStartHandler=function(){function O(F,_){return function(U){i=[F,_],y.log("resize start",i),g=!0,m=[window.screenLeft-U.screenX,window.screenTop-U.screenY],u=[window.innerWidth,window.innerHeight],document.addEventListener("mousemove",R),document.addEventListener("mouseup",M),R(U)}}return O}(),M=function O(F){y.log("resize end",s),R(F),document.removeEventListener("mousemove",R),document.removeEventListener("mouseup",O),g=!1,B()},R=function(F){g&&(F.preventDefault(),s=(0,a.vecAdd)(u,(0,a.vecMultiply)(i,(0,a.vecAdd)([F.screenX,F.screenY],(0,a.vecInverse)([window.screenLeft,window.screenTop]),m,[1,1]))),s[0]=Math.max(s[0],150),s[1]=Math.max(s[1],50),p(s))}},24826:function(T,r,n){"use strict";r.__esModule=!0,r.setupGlobalEvents=r.removeScrollableNode=r.globalEvents=r.canStealFocus=r.addScrollableNode=r.KeyEvent=void 0;var e=n(92868),a=n(92986);/** +======= +*/var y=(0,t.createLogger)("drag"),S=Byond.windowId,k=!1,h=!1,i=[0,0],c,m,l,u,s,d=r.setWindowKey=function(){function R(F){S=F}return R}(),v=r.getWindowPosition=function(){function R(){return[window.screenLeft,window.screenTop]}return R}(),g=r.getWindowSize=function(){function R(){return[window.innerWidth,window.innerHeight]}return R}(),C=r.setWindowPosition=function(){function R(F){var W=(0,a.vecAdd)(F,i);return Byond.winset(Byond.windowId,{pos:W[0]+","+W[1]})}return R}(),f=r.setWindowSize=function(){function R(F){return Byond.winset(Byond.windowId,{size:F[0]+"x"+F[1]})}return R}(),N=r.getScreenPosition=function(){function R(){return[0-i[0],0-i[1]]}return R}(),V=r.getScreenSize=function(){function R(){return[window.screen.availWidth,window.screen.availHeight]}return R}(),B=function(F,W,U){U===void 0&&(U=50);for(var z=[W],$,G=0;Gse&&($[X]=se-W[X],G=!0)}return[G,$]},x=r.dragStartHandler=function(){function R(F){y.log("drag start"),k=!0,m=[window.screenLeft-F.screenX,window.screenTop-F.screenY],document.addEventListener("mousemove",P),document.addEventListener("mouseup",E),P(F)}return R}(),E=function R(F){y.log("drag end"),P(F),document.removeEventListener("mousemove",P),document.removeEventListener("mouseup",R),k=!1,I()},P=function(F){k&&(F.preventDefault(),C((0,a.vecAdd)([F.screenX,F.screenY],m)))},D=r.resizeStartHandler=function(){function R(F,W){return function(U){l=[F,W],y.log("resize start",l),h=!0,m=[window.screenLeft-U.screenX,window.screenTop-U.screenY],u=[window.innerWidth,window.innerHeight],document.addEventListener("mousemove",O),document.addEventListener("mouseup",M),O(U)}}return R}(),M=function R(F){y.log("resize end",s),O(F),document.removeEventListener("mousemove",O),document.removeEventListener("mouseup",R),h=!1,I()},O=function(F){h&&(F.preventDefault(),s=(0,a.vecAdd)(u,(0,a.vecMultiply)(l,(0,a.vecAdd)([F.screenX,F.screenY],(0,a.vecInverse)([window.screenLeft,window.screenTop]),m,[1,1]))),s[0]=Math.max(s[0],150),s[1]=Math.max(s[1],50),f(s))}},24826:function(T,r,n){"use strict";r.__esModule=!0,r.setupGlobalEvents=r.removeScrollableNode=r.globalEvents=r.canStealFocus=r.addScrollableNode=r.KeyEvent=void 0;var e=n(92868),a=n(92986);/** +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * Normalized browser focus events and BYOND-specific focus helpers. * * @file * @copyright 2020 Aleksej Komarov * @license MIT +<<<<<<< HEAD */var t=r.globalEvents=new e.EventEmitter,o=!1,f=r.setupGlobalEvents=function(){function p(N){N===void 0&&(N={}),o=!!N.ignoreWindowFocus}return p}(),b,y=!0,I=function p(N,V){if(o){y=!0;return}if(b&&(clearTimeout(b),b=null),V){b=setTimeout(function(){return p(N)});return}y!==N&&(y=N,t.emit(N?"window-focus":"window-blur"),t.emit("window-focus-change",N))},k=null,g=r.canStealFocus=function(){function p(N){var V=String(N.tagName).toLowerCase();return V==="input"||V==="textarea"}return p}(),l=function(N){c(),k=N,k.addEventListener("blur",c)},c=function p(){k&&(k.removeEventListener("blur",p),k=null)},m=null,i=null,u=[],s=r.addScrollableNode=function(){function p(N){u.push(N)}return p}(),d=r.removeScrollableNode=function(){function p(N){var V=u.indexOf(N);V>=0&&u.splice(V,1)}return p}(),v=function(N){if(!(k||!y))for(var V=document.body;N&&N!==V;){if(u.includes(N)){if(N.contains(m))return;m=N,N.focus();return}N=N.parentNode}};window.addEventListener("mousemove",function(p){var N=p.target;N!==i&&(i=N,v(N))}),window.addEventListener("focusin",function(p){if(i=null,m=p.target,I(!0),g(p.target)){l(p.target);return}}),window.addEventListener("focusout",function(p){i=null,I(!1,!0)}),window.addEventListener("blur",function(p){i=null,I(!1,!0)}),window.addEventListener("beforeunload",function(p){I(!1)});var h={},C=r.KeyEvent=function(){function p(V,S,B){this.event=V,this.type=S,this.code=window.event?V.which:V.keyCode,this.ctrl=V.ctrlKey,this.shift=V.shiftKey,this.alt=V.altKey,this.repeat=!!B}var N=p.prototype;return N.hasModifierKeys=function(){function V(){return this.ctrl||this.alt||this.shift}return V}(),N.isModifierKey=function(){function V(){return this.code===a.KEY_CTRL||this.code===a.KEY_SHIFT||this.code===a.KEY_ALT}return V}(),N.isDown=function(){function V(){return this.type==="keydown"}return V}(),N.isUp=function(){function V(){return this.type==="keyup"}return V}(),N.toString=function(){function V(){return this._str?this._str:(this._str="",this.ctrl&&(this._str+="Ctrl+"),this.alt&&(this._str+="Alt+"),this.shift&&(this._str+="Shift+"),this.code>=48&&this.code<=90?this._str+=String.fromCharCode(this.code):this.code>=a.KEY_F1&&this.code<=a.KEY_F12?this._str+="F"+(this.code-111):this._str+="["+this.code+"]",this._str)}return V}(),p}();document.addEventListener("keydown",function(p){if(!g(p.target)){var N=p.keyCode,V=new C(p,"keydown",h[N]);t.emit("keydown",V),t.emit("key",V),h[N]=!0}}),document.addEventListener("keyup",function(p){if(!g(p.target)){var N=p.keyCode,V=new C(p,"keyup");t.emit("keyup",V),t.emit("key",V),h[N]=!1}})},87695:function(T,r){"use strict";r.__esModule=!0,r.focusWindow=r.focusMap=void 0;/** +======= + */var t=r.globalEvents=new e.EventEmitter,o=!1,p=r.setupGlobalEvents=function(){function f(N){N===void 0&&(N={}),o=!!N.ignoreWindowFocus}return f}(),b,y=!0,S=function f(N,V){if(o){y=!0;return}if(b&&(clearTimeout(b),b=null),V){b=setTimeout(function(){return f(N)});return}y!==N&&(y=N,t.emit(N?"window-focus":"window-blur"),t.emit("window-focus-change",N))},k=null,h=r.canStealFocus=function(){function f(N){var V=String(N.tagName).toLowerCase();return V==="input"||V==="textarea"}return f}(),i=function(N){c(),k=N,k.addEventListener("blur",c)},c=function f(){k&&(k.removeEventListener("blur",f),k=null)},m=null,l=null,u=[],s=r.addScrollableNode=function(){function f(N){u.push(N)}return f}(),d=r.removeScrollableNode=function(){function f(N){var V=u.indexOf(N);V>=0&&u.splice(V,1)}return f}(),v=function(N){if(!(k||!y))for(var V=document.body;N&&N!==V;){if(u.includes(N)){if(N.contains(m))return;m=N,N.focus();return}N=N.parentNode}};window.addEventListener("mousemove",function(f){var N=f.target;N!==l&&(l=N,v(N))}),window.addEventListener("focusin",function(f){if(l=null,m=f.target,S(!0),h(f.target)){i(f.target);return}}),window.addEventListener("focusout",function(f){l=null,S(!1,!0)}),window.addEventListener("blur",function(f){l=null,S(!1,!0)}),window.addEventListener("beforeunload",function(f){S(!1)});var g={},C=r.KeyEvent=function(){function f(V,B,I){this.event=V,this.type=B,this.code=window.event?V.which:V.keyCode,this.ctrl=V.ctrlKey,this.shift=V.shiftKey,this.alt=V.altKey,this.repeat=!!I}var N=f.prototype;return N.hasModifierKeys=function(){function V(){return this.ctrl||this.alt||this.shift}return V}(),N.isModifierKey=function(){function V(){return this.code===a.KEY_CTRL||this.code===a.KEY_SHIFT||this.code===a.KEY_ALT}return V}(),N.isDown=function(){function V(){return this.type==="keydown"}return V}(),N.isUp=function(){function V(){return this.type==="keyup"}return V}(),N.toString=function(){function V(){return this._str?this._str:(this._str="",this.ctrl&&(this._str+="Ctrl+"),this.alt&&(this._str+="Alt+"),this.shift&&(this._str+="Shift+"),this.code>=48&&this.code<=90?this._str+=String.fromCharCode(this.code):this.code>=a.KEY_F1&&this.code<=a.KEY_F12?this._str+="F"+(this.code-111):this._str+="["+this.code+"]",this._str)}return V}(),f}();document.addEventListener("keydown",function(f){if(!h(f.target)){var N=f.keyCode,V=new C(f,"keydown",g[N]);t.emit("keydown",V),t.emit("key",V),g[N]=!0}}),document.addEventListener("keyup",function(f){if(!h(f.target)){var N=f.keyCode,V=new C(f,"keyup");t.emit("keyup",V),t.emit("key",V),g[N]=!1}})},87695:function(T,r){"use strict";r.__esModule=!0,r.focusWindow=r.focusMap=void 0;/** +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * Various focus helpers. * * @file @@ -238,6 +434,7 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT +<<<<<<< HEAD */var a=["f","p","n","\u03BC","m"," ","k","M","G","T","P","E","Z","Y"],t=a.indexOf(" "),o=r.formatSiUnit=function(){function I(k,g,l){if(g===void 0&&(g=-t),l===void 0&&(l=""),typeof k!="number"||!Number.isFinite(k))return k;var c=Math.floor(Math.log10(k)),m=Math.floor(Math.max(g*3,c)),i=Math.floor(c/3),u=Math.floor(m/3),s=(0,e.clamp)(t+u,0,a.length),d=a[s],v=k/Math.pow(1e3,u),h=i>g?2+u*3-m:0,C=(0,e.toFixed)(v,h)+" "+d+l;return C.trim()}return I}(),f=r.formatPower=function(){function I(k,g){return g===void 0&&(g=0),o(k,g,"W")}return I}(),b=r.formatMoney=function(){function I(k,g){if(g===void 0&&(g=0),!Number.isFinite(k))return k;var l=(0,e.round)(k,g);g>0&&(l=(0,e.toFixed)(k,g)),l=String(l);var c=l.length,m=l.indexOf(".");m===-1&&(m=c);for(var i="",u=0;u0&&u=0?"+":g<0?"\u2013":"",c=Math.abs(g);return c===1/0?c="Inf":c=(0,e.toFixed)(c,2),l+c+" dB"}return I}()},56518:function(T,r,n){"use strict";r.__esModule=!0,r.setupHotKeys=r.releaseHotKey=r.releaseHeldKeys=r.acquireHotKey=void 0;var e=f(n(92986)),a=n(24826),t=n(9394);function o(s){if(typeof WeakMap!="function")return null;var d=new WeakMap,v=new WeakMap;return(o=function(C){return C?v:d})(s)}function f(s,d){if(!d&&s&&s.__esModule)return s;if(s===null||typeof s!="object"&&typeof s!="function")return{default:s};var v=o(d);if(v&&v.has(s))return v.get(s);var h={__proto__:null},C=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var p in s)if(p!=="default"&&{}.hasOwnProperty.call(s,p)){var N=C?Object.getOwnPropertyDescriptor(s,p):null;N&&(N.get||N.set)?Object.defineProperty(h,p,N):h[p]=s[p]}return h.default=s,v&&v.set(s,h),h}/** * @file * @copyright 2020 Aleksej Komarov @@ -247,10 +444,22 @@ * @copyright 2023 itsmeow * @license MIT */function m(w,A){w.prototype=Object.create(A.prototype),w.prototype.constructor=w,i(w,A)}function i(w,A){return i=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(x,E){return x.__proto__=E,x},i(w,A)}function u(w,A){if(w==null)return{};var x={};for(var E in w)if({}.hasOwnProperty.call(w,E)){if(A.includes(E))continue;x[E]=w[E]}return x}var s=r.ColorPickerModal=function(){function w(A,x){var E=(0,t.useBackend)(x),P=E.data,D=P.timeout,M=P.message,R=P.title,O=P.autofocus,F=P.default_color,_=F===void 0?"#000000":F,U=(0,t.useLocalState)(x,"color_picker_choice",(0,y.hexToHsva)(_)),z=U[0],$=U[1];return(0,e.createComponentVNode)(2,f.Window,{height:400,title:R,width:600,theme:"generic",children:[!!D&&(0,e.createComponentVNode)(2,a.Loader,{value:D}),(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[M&&(0,e.createComponentVNode)(2,o.Stack.Item,{m:1,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:(0,e.createComponentVNode)(2,o.Box,{color:"label",overflow:"hidden",children:M})})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:[!!O&&(0,e.createComponentVNode)(2,o.Autofocus),(0,e.createComponentVNode)(2,d,{color:z,setColor:$,defaultColor:_})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,l.InputButtons,{input:(0,y.hsvaToHex)(z)})})]})})]})}return w}(),d=r.ColorSelector=function(){function w(A,x){var E=A.color,P=A.setColor,D=A.defaultColor,M=function(){function F(_){P(function(U){return Object.assign({},U,_)})}return F}(),R=(0,y.hsvaToRgba)(E),O=(0,y.hsvaToHex)(E);return(0,e.createComponentVNode)(2,o.Flex,{direction:"row",children:[(0,e.createComponentVNode)(2,o.Flex.Item,{mr:2,children:(0,e.createComponentVNode)(2,o.Stack,{vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createVNode)(1,"div","react-colorful",[(0,e.createComponentVNode)(2,N,{hsva:E,onChange:M}),(0,e.createComponentVNode)(2,V,{hue:E.h,onChange:M,className:"react-colorful__last-control"})],4)}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:[(0,e.createComponentVNode)(2,o.Box,{inline:!0,width:"100px",height:"20px",textAlign:"center",children:"Current"}),(0,e.createComponentVNode)(2,o.Box,{inline:!0,width:"100px",height:"20px",textAlign:"center",children:"Previous"}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.Tooltip,{content:O,position:"bottom",children:(0,e.createComponentVNode)(2,o.Box,{inline:!0,width:"100px",height:"30px",backgroundColor:O})}),(0,e.createComponentVNode)(2,o.Tooltip,{content:D,position:"bottom",children:(0,e.createComponentVNode)(2,o.Box,{inline:!0,width:"100px",height:"30px",backgroundColor:D})})]})]})}),(0,e.createComponentVNode)(2,o.Flex.Item,{grow:!0,fontSize:"15px",lineHeight:"24px",children:(0,e.createComponentVNode)(2,o.Stack,{vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"Hex:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,height:"24px",children:(0,e.createComponentVNode)(2,C,{fluid:!0,color:(0,y.hsvaToHex)(E).substring(1),onChange:function(){function F(_){g.logger.info(_),P((0,y.hexToHsva)(_))}return F}(),prefixed:!0})})]})}),(0,e.createComponentVNode)(2,o.Stack.Divider),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{width:"25px",children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"H:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,V,{hue:E.h,onChange:M})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,v,{value:E.h,callback:function(){function F(_,U){return M({h:U})}return F}(),max:360,unit:"\xB0"})})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{width:"25px",children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"S:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,S,{color:E,onChange:M})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,v,{value:E.s,callback:function(){function F(_,U){return M({s:U})}return F}(),unit:"%"})})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{width:"25px",children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"V:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,B,{color:E,onChange:M})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,v,{value:E.v,callback:function(){function F(_,U){return M({v:U})}return F}(),unit:"%"})})]})}),(0,e.createComponentVNode)(2,o.Stack.Divider),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{width:"25px",children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"R:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,L,{color:E,onChange:M,target:"r"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,v,{value:R.r,callback:function(){function F(_,U){R.r=U,M((0,y.rgbaToHsva)(R))}return F}(),max:255})})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{width:"25px",children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"G:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,L,{color:E,onChange:M,target:"g"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,v,{value:R.g,callback:function(){function F(_,U){R.g=U,M((0,y.rgbaToHsva)(R))}return F}(),max:255})})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{width:"25px",children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"B:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,L,{color:E,onChange:M,target:"b"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,v,{value:R.b,callback:function(){function F(_,U){R.b=U,M((0,y.rgbaToHsva)(R))}return F}(),max:255})})]})})]})})]})}return w}(),v=function(A){var x=A.value,E=A.callback,P=A.min,D=P===void 0?0:P,M=A.max,R=M===void 0?100:M,O=A.unit;return(0,e.createComponentVNode)(2,o.NumberInput,{width:"70px",value:Math.round(x),step:1,minValue:D,maxValue:R,onChange:E,unit:O})},h=function(A){return"#"+A},C=r.HexColorInput=function(){function w(A){var x=A.prefixed,E=A.alpha,P=A.color,D=A.fluid,M=A.onChange,R=u(A,c),O=function(){function _(U){return U.replace(/([^0-9A-F]+)/gi,"").substring(0,E?8:6)}return _}(),F=function(){function _(U){return(0,y.validHex)(U,E)}return _}();return(0,e.normalizeProps)((0,e.createComponentVNode)(2,p,Object.assign({},R,{fluid:D,color:P,onChange:M,escape:O,format:x?h:void 0,validate:F})))}return w}(),p=r.ColorInput=function(w){function A(E){var P;return P=w.call(this)||this,P.props=void 0,P.state=void 0,P.handleInput=function(D){var M=P.props.escape(D.currentTarget.value);P.setState({localValue:M})},P.handleBlur=function(D){D.currentTarget&&(P.props.validate(D.currentTarget.value)?P.props.onChange(P.props.escape?P.props.escape(D.currentTarget.value):D.currentTarget.value):P.setState({localValue:P.props.escape(P.props.color)}))},P.props=E,P.state={localValue:P.props.escape(P.props.color)},P}m(A,w);var x=A.prototype;return x.componentDidUpdate=function(){function E(P,D){P.color!==this.props.color&&this.setState({localValue:this.props.escape(this.props.color)})}return E}(),x.render=function(){function E(){return(0,e.createComponentVNode)(2,o.Box,{className:(0,k.classes)(["Input",this.props.fluid&&"Input--fluid"]),children:[(0,e.createVNode)(1,"div","Input__baseline",".",16),(0,e.createVNode)(64,"input","Input__input",null,1,{value:this.props.format?this.props.format(this.state.localValue):this.state.localValue,spellCheck:"false",onInput:this.handleInput,onBlur:this.handleBlur})]})}return E}(),A}(e.Component),N=function(A){var x=A.hsva,E=A.onChange,P=function(O){E({s:O.left*100,v:100-O.top*100})},D=function(O){E({s:(0,b.clamp)(x.s+O.left*100,0,100),v:(0,b.clamp)(x.v-O.top*100,0,100)})},M={"background-color":(0,y.hsvaToHslString)({h:x.h,s:100,v:100,a:1})+" !important"};return(0,e.createVNode)(1,"div","react-colorful__saturation_value",(0,e.createComponentVNode)(2,I.Interactive,{onMove:P,onKey:D,"aria-label":"Color","aria-valuetext":"Saturation "+Math.round(x.s)+"%, Brightness "+Math.round(x.v)+"%",children:(0,e.createComponentVNode)(2,o.Pointer,{className:"react-colorful__saturation_value-pointer",top:1-x.v/100,left:x.s/100,color:(0,y.hsvaToHslString)(x)})}),2,{style:M})},V=function(A){var x=A.className,E=A.hue,P=A.onChange,D=function(F){P({h:360*F.left})},M=function(F){P({h:(0,b.clamp)(E+F.left*360,0,360)})},R=(0,k.classes)(["react-colorful__hue",x]);return(0,e.createVNode)(1,"div",R,(0,e.createComponentVNode)(2,I.Interactive,{onMove:D,onKey:M,"aria-label":"Hue","aria-valuenow":Math.round(E),"aria-valuemax":"360","aria-valuemin":"0",children:(0,e.createComponentVNode)(2,o.Pointer,{className:"react-colorful__hue-pointer",left:E/360,color:(0,y.hsvaToHslString)({h:E,s:100,v:100,a:1})})}),2)},S=function(A){var x=A.className,E=A.color,P=A.onChange,D=function(F){P({s:100*F.left})},M=function(F){P({s:(0,b.clamp)(E.s+F.left*100,0,100)})},R=(0,k.classes)(["react-colorful__saturation",x]);return(0,e.createVNode)(1,"div",R,(0,e.createComponentVNode)(2,I.Interactive,{style:{background:"linear-gradient(to right, "+(0,y.hsvaToHslString)({h:E.h,s:0,v:E.v,a:1})+", "+(0,y.hsvaToHslString)({h:E.h,s:100,v:E.v,a:1})+")"},onMove:D,onKey:M,"aria-label":"Saturation","aria-valuenow":Math.round(E.s),"aria-valuemax":"100","aria-valuemin":"0",children:(0,e.createComponentVNode)(2,o.Pointer,{className:"react-colorful__saturation-pointer",left:E.s/100,color:(0,y.hsvaToHslString)({h:E.h,s:E.s,v:E.v,a:1})})}),2)},B=function(A){var x=A.className,E=A.color,P=A.onChange,D=function(F){P({v:100*F.left})},M=function(F){P({v:(0,b.clamp)(E.v+F.left*100,0,100)})},R=(0,k.classes)(["react-colorful__value",x]);return(0,e.createVNode)(1,"div",R,(0,e.createComponentVNode)(2,I.Interactive,{style:{background:"linear-gradient(to right, "+(0,y.hsvaToHslString)({h:E.h,s:E.s,v:0,a:1})+", "+(0,y.hsvaToHslString)({h:E.h,s:E.s,v:100,a:1})+")"},onMove:D,onKey:M,"aria-label":"Value","aria-valuenow":Math.round(E.s),"aria-valuemax":"100","aria-valuemin":"0",children:(0,e.createComponentVNode)(2,o.Pointer,{className:"react-colorful__value-pointer",left:E.v/100,color:(0,y.hsvaToHslString)({h:E.h,s:E.s,v:E.v,a:1})})}),2)},L=function(A){var x=A.className,E=A.color,P=A.onChange,D=A.target,M=(0,y.hsvaToRgba)(E),R=function($){M[D]=$,P((0,y.rgbaToHsva)(M))},O=function($){R(255*$.left)},F=function($){R((0,b.clamp)(M[D]+$.left*255,0,255))},_=(0,k.classes)(["react-colorful__"+D,x]),U=D==="r"?"rgb("+Math.round(M.r)+",0,0)":D==="g"?"rgb(0,"+Math.round(M.g)+",0)":"rgb(0,0,"+Math.round(M.b)+")";return(0,e.createVNode)(1,"div",_,(0,e.createComponentVNode)(2,I.Interactive,{onMove:O,onKey:F,"aria-valuenow":M[D],"aria-valuemax":"100","aria-valuemin":"0",children:(0,e.createComponentVNode)(2,o.Pointer,{className:"react-colorful__"+D+"-pointer",left:M[D]/255,color:U})}),2)}},8444:function(T,r,n){"use strict";r.__esModule=!0,r.ColourMatrixTester=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.ColourMatrixTester=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.colour_data,m=[[{name:"RR",idx:0},{name:"RG",idx:1},{name:"RB",idx:2},{name:"RA",idx:3}],[{name:"GR",idx:4},{name:"GG",idx:5},{name:"GB",idx:6},{name:"GA",idx:7}],[{name:"BR",idx:8},{name:"BG",idx:9},{name:"BB",idx:10},{name:"BA",idx:11}],[{name:"AR",idx:12},{name:"AG",idx:13},{name:"AB",idx:14},{name:"AA",idx:15}]];return(0,e.createComponentVNode)(2,o.Window,{width:360,height:190,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Modify Matrix",children:m.map(function(i){return(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",textColor:"label",children:i.map(function(u){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,mt:1,children:[u.name,":\xA0",(0,e.createComponentVNode)(2,t.NumberInput,{width:4,value:c[u.idx],step:.05,minValue:-5,maxValue:5,stepPixelSize:5,onChange:function(){function s(d,v){return g("setvalue",{idx:u.idx+1,value:v})}return s}()})]},u.name)})},i)})})})})})}return b}()},63818:function(T,r,n){"use strict";r.__esModule=!0,r.CommunicationsComputer=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=function(s){switch(s){case 1:return(0,e.createComponentVNode)(2,I);case 2:return(0,e.createComponentVNode)(2,l);case 3:return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:(0,e.createComponentVNode)(2,c)})});case 4:return(0,e.createComponentVNode)(2,i);default:return"ERROR. Unknown menu_state. Please contact NT Technical Support."}},b=r.CommunicationsComputer=function(){function u(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=C.menu_state;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:600,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,y),f(p)]})})})}return u}(),y=function(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=C.authenticated,N=C.noauthbutton,V=C.esc_section,S=C.esc_callable,B=C.esc_recallable,L=C.esc_status,w=C.authhead,A=C.is_ai,x=C.lastCallLoc,E=!1,P;return p?p===1?P="Command":p===2?P="Captain":p===3?P="CentComm Officer":p===4?(P="CentComm Secure Connection",E=!0):P="ERROR: Report This Bug!":P="Not Logged In",(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Authentication",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:E&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Access",children:P})||(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Actions",children:(0,e.createComponentVNode)(2,t.Button,{icon:p?"sign-out-alt":"id-card",selected:p,disabled:N,content:p?"Log Out ("+P+")":"Log In",onClick:function(){function D(){return h("auth")}return D}()})})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:!!V&&(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Escape Shuttle",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[!!L&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:L}),!!S&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Options",children:(0,e.createComponentVNode)(2,t.Button,{icon:"rocket",content:"Call Shuttle",disabled:!w,onClick:function(){function D(){return h("callshuttle")}return D}()})}),!!B&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Options",children:(0,e.createComponentVNode)(2,t.Button,{icon:"times",content:"Recall Shuttle",disabled:!w||A,onClick:function(){function D(){return h("cancelshuttle")}return D}()})}),!!x&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Last Call/Recall From",children:x})]})})})],4)},I=function(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=C.is_admin;return p?(0,e.createComponentVNode)(2,k):(0,e.createComponentVNode)(2,g)},k=function(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=C.is_admin,N=C.gamma_armory_location,V=C.admin_levels,S=C.authenticated,B=C.ert_allowed;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"CentComm Actions",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Change Alert",children:(0,e.createComponentVNode)(2,m,{levels:V,required_access:p,use_confirm:1})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Announcement",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"bullhorn",content:"Make Central Announcement",disabled:!p,onClick:function(){function L(){return h("send_to_cc_announcement_page")}return L}()}),S===4&&(0,e.createComponentVNode)(2,t.Button,{icon:"plus",content:"Make Other Announcement",disabled:!p,onClick:function(){function L(){return h("make_other_announcement")}return L}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Response Team",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"ambulance",content:"Dispatch ERT",disabled:!p,onClick:function(){function L(){return h("dispatch_ert")}return L}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:B,content:B?"ERT calling enabled":"ERT calling disabled",tooltip:B?"Command can request an ERT":"ERTs cannot be requested",disabled:!p,onClick:function(){function L(){return h("toggle_ert_allowed")}return L}(),selected:null})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Nuclear Device",children:(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"bomb",content:"Get Authentication Codes",disabled:!p,onClick:function(){function L(){return h("send_nuke_codes")}return L}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Gamma Armory",children:(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"biohazard",content:N?"Send Gamma Armory":"Recall Gamma Armory",disabled:!p,onClick:function(){function L(){return h("move_gamma_armory")}return L}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Other",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"coins",content:"View Economy",disabled:!p,onClick:function(){function L(){return h("view_econ")}return L}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fax",content:"Fax Manager",disabled:!p,onClick:function(){function L(){return h("view_fax")}return L}()})]})]})}),(0,e.createComponentVNode)(2,t.Collapsible,{title:"View Command accessible controls",children:(0,e.createComponentVNode)(2,g)})]})},g=function(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=C.msg_cooldown,N=C.emagged,V=C.cc_cooldown,S=C.security_level_color,B=C.str_security_level,L=C.levels,w=C.authcapt,A=C.authhead,x=C.messages,E="Make Priority Announcement";p>0&&(E+=" ("+p+"s)");var P=N?"Message [UNKNOWN]":"Message CentComm",D="Request Authentication Codes";return V>0&&(P+=" ("+V+"s)",D+=" ("+V+"s)"),(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Captain-Only Actions",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Alert",color:S,children:B}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Change Alert",children:(0,e.createComponentVNode)(2,m,{levels:L,required_access:w})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Announcement",children:(0,e.createComponentVNode)(2,t.Button,{icon:"bullhorn",content:E,disabled:!w||p>0,onClick:function(){function M(){return h("announce")}return M}()})}),!!N&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Transmit",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"broadcast-tower",color:"red",content:P,disabled:!w||V>0,onClick:function(){function M(){return h("MessageSyndicate")}return M}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"sync-alt",content:"Reset Relays",disabled:!w,onClick:function(){function M(){return h("RestoreBackup")}return M}()})]})||(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Transmit",children:(0,e.createComponentVNode)(2,t.Button,{icon:"broadcast-tower",content:P,disabled:!w||V>0,onClick:function(){function M(){return h("MessageCentcomm")}return M}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Nuclear Device",children:(0,e.createComponentVNode)(2,t.Button,{icon:"bomb",content:D,disabled:!w||V>0,onClick:function(){function M(){return h("nukerequest")}return M}()})})]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Command Staff Actions",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Displays",children:(0,e.createComponentVNode)(2,t.Button,{icon:"tv",content:"Change Status Displays",disabled:!A,onClick:function(){function M(){return h("status")}return M}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Incoming Messages",children:(0,e.createComponentVNode)(2,t.Button,{icon:"folder-open",content:"View ("+x.length+")",disabled:!A,onClick:function(){function M(){return h("messagelist")}return M}()})})]})})})],4)},l=function(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=C.stat_display,N=C.authhead,V=C.current_message_title,S=p.presets.map(function(L){return(0,e.createComponentVNode)(2,t.Button,{content:L.label,selected:L.name===p.type,disabled:!N,onClick:function(){function w(){return h("setstat",{statdisp:L.name})}return w}()},L.name)}),B=p.alerts.map(function(L){return(0,e.createComponentVNode)(2,t.Button,{content:L.label,selected:L.alert===p.icon,disabled:!N,onClick:function(){function w(){return h("setstat",{statdisp:3,alert:L.alert})}return w}()},L.alert)});return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Modify Status Screens",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-left",content:"Back To Main Menu",onClick:function(){function L(){return h("main")}return L}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Presets",children:S}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Alerts",children:B}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Message Line 1",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:p.line_1,disabled:!N,onClick:function(){function L(){return h("setmsg1")}return L}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Message Line 2",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:p.line_2,disabled:!N,onClick:function(){function L(){return h("setmsg2")}return L}()})})]})})})},c=function(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=C.authhead,N=C.current_message_title,V=C.current_message,S=C.messages,B=C.security_level,L;if(N)L=(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:N,buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"times",content:"Return To Message List",disabled:!p,onClick:function(){function A(){return h("messagelist")}return A}()}),children:(0,e.createComponentVNode)(2,t.Box,{children:V})})});else{var w=S.map(function(A){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:A.title,children:[(0,e.createComponentVNode)(2,t.Button,{icon:"eye",content:"View",disabled:!p||N===A.title,onClick:function(){function x(){return h("messagelist",{msgid:A.id})}return x}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"times",content:"Delete",disabled:!p,onClick:function(){function x(){return h("delmessage",{msgid:A.id})}return x}()})]},A.id)});L=(0,e.createComponentVNode)(2,t.Section,{title:"Messages Received",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-left",content:"Back To Main Menu",onClick:function(){function A(){return h("main")}return A}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:w})})}return(0,e.createComponentVNode)(2,t.Box,{children:L})},m=function(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=s.levels,N=s.required_access,V=s.use_confirm,S=C.security_level;return V?p.map(function(B){return(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:B.icon,content:B.name,disabled:!N||B.id===S,tooltip:B.tooltip,onClick:function(){function L(){return h("newalertlevel",{level:B.id})}return L}()},B.name)}):p.map(function(B){return(0,e.createComponentVNode)(2,t.Button,{icon:B.icon,content:B.name,disabled:!N||B.id===S,tooltip:B.tooltip,onClick:function(){function L(){return h("newalertlevel",{level:B.id})}return L}()},B.name)})},i=function(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=C.is_admin,N=C.possible_cc_sounds;if(!p)return h("main");var V=(0,a.useLocalState)(d,"subtitle",""),S=V[0],B=V[1],L=(0,a.useLocalState)(d,"text",""),w=L[0],A=L[1],x=(0,a.useLocalState)(d,"classified",0),E=x[0],P=x[1],D=(0,a.useLocalState)(d,"beepsound","Beep"),M=D[0],R=D[1];return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Central Command Report",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-left",content:"Back To Main Menu",onClick:function(){function O(){return h("main")}return O}()}),children:[(0,e.createComponentVNode)(2,t.Input,{placeholder:"Enter Subtitle here.",fluid:!0,value:S,onChange:function(){function O(F,_){return B(_)}return O}(),mb:"5px"}),(0,e.createComponentVNode)(2,t.Input,{placeholder:"Enter Announcement here,\nMultiline input is accepted.",rows:10,fluid:!0,multiline:1,value:w,onChange:function(){function O(F,_){return A(_)}return O}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{content:"Send Announcement",fluid:!0,icon:"paper-plane",center:!0,mt:"5px",textAlign:"center",onClick:function(){function O(){return h("make_cc_announcement",{subtitle:S,text:w,classified:E,beepsound:M})}return O}()}),(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Dropdown,{width:"260px",height:"20px",options:N,selected:M,onSelected:function(){function O(F){return R(F)}return O}(),disabled:E})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"volume-up",mx:"5px",disabled:E,tooltip:"Test sound",onClick:function(){function O(){return h("test_sound",{sound:M})}return O}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:E,content:"Classified",fluid:!0,tooltip:E?"Sent to station communications consoles":"Publically announced",onClick:function(){function O(){return P(!E)}return O}()})})]})]})})}},20562:function(T,r,n){"use strict";r.__esModule=!0,r.CompostBin=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.CompostBin=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.biomass,m=l.compost,i=l.biomass_capacity,u=l.compost_capacity,s=l.potassium,d=l.potassium_capacity,v=l.potash,h=l.potash_capacity,C=(0,a.useSharedState)(I,"vendAmount",1),p=C[0],N=C[1];return(0,e.createComponentVNode)(2,o.Window,{width:360,height:250,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Section,{label:"Resources",children:(0,e.createComponentVNode)(2,t.Stack,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Biomass",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ml:.5,mt:1,width:20,value:c,minValue:0,maxValue:i,ranges:{good:[i*.5,1/0],average:[i*.25,i*.5],bad:[-1/0,i*.25]},children:[c," / ",i," Units"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Compost",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ml:.5,mt:1,width:20,value:m,minValue:0,maxValue:u,ranges:{good:[u*.5,1/0],average:[u*.25,u*.5],bad:[-1/0,u*.25]},children:[m," / ",u," Units"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Potassium",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ml:.5,mt:1,width:20,value:s,minValue:0,maxValue:d,ranges:{good:[d*.5,1/0],average:[d*.25,d*.5],bad:[-1/0,d*.25]},children:[s," / ",d," Units"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Potash",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ml:.5,mt:1,width:20,value:v,minValue:0,maxValue:h,ranges:{good:[h*.5,1/0],average:[h*.25,h*.5],bad:[-1/0,h*.25]},children:[v," / ",h," Units"]})})]})})}),(0,e.createComponentVNode)(2,t.Section,{title:"Controls",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{inline:!0,mr:"5px",color:"silver",children:"Soil clumps to make:"}),(0,e.createComponentVNode)(2,t.NumberInput,{animated:!0,value:p,width:"32px",minValue:1,maxValue:10,stepPixelSize:7,onChange:function(){function V(S,B){return N(B)}return V}()})],4),children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,align:"center",content:"Make Soil",disabled:m<25*p,icon:"arrow-circle-down",onClick:function(){function V(){return g("create",{amount:p})}return V}()})})})]})})})}return b}()},21813:function(T,r,n){"use strict";r.__esModule=!0,r.Contractor=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),f=n(73379),b=n(98595);function y(h,C){h.prototype=Object.create(C.prototype),h.prototype.constructor=h,I(h,C)}function I(h,C){return I=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(p,N){return p.__proto__=N,p},I(h,C)}var k={1:["ACTIVE","good"],2:["COMPLETED","good"],3:["FAILED","bad"]},g=["Recording biometric data...","Analyzing embedded syndicate info...","STATUS CONFIRMED","Contacting Syndicate database...","Awaiting response...","Awaiting response...","Awaiting response...","Awaiting response...","Awaiting response...","Awaiting response...","Response received, ack 4851234...","CONFIRM ACC "+Math.round(Math.random()*2e4),"Setting up private accounts...","CONTRACTOR ACCOUNT CREATED","Searching for available contracts...","Searching for available contracts...","Searching for available contracts...","Searching for available contracts...","CONTRACTS FOUND","WELCOME, AGENT"],l=r.Contractor=function(){function h(C,p){var N=(0,t.useBackend)(p),V=N.act,S=N.data,B;S.unauthorized?B=(0,e.createComponentVNode)(2,o.Flex.Item,{grow:"1",backgroundColor:"rgba(0, 0, 0, 0.8)",children:(0,e.createComponentVNode)(2,d,{height:"100%",allMessages:["ERROR: UNAUTHORIZED USER"],finishedTimeout:100,onFinished:function(){function x(){}return x}()})}):S.load_animation_completed?B=(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Flex.Item,{basis:"content",children:(0,e.createComponentVNode)(2,c)}),(0,e.createComponentVNode)(2,o.Flex.Item,{basis:"content",mt:"0.5rem",children:(0,e.createComponentVNode)(2,m)}),(0,e.createComponentVNode)(2,o.Flex.Item,{grow:"1",overflow:"hidden",children:S.page===1?(0,e.createComponentVNode)(2,i,{height:"100%"}):(0,e.createComponentVNode)(2,s,{height:"100%"})})],4):B=(0,e.createComponentVNode)(2,o.Flex.Item,{grow:"1",backgroundColor:"rgba(0, 0, 0, 0.8)",children:(0,e.createComponentVNode)(2,d,{height:"100%",allMessages:g,finishedTimeout:3e3,onFinished:function(){function x(){return V("complete_load_animation")}return x}()})});var L=(0,t.useLocalState)(p,"viewingPhoto",""),w=L[0],A=L[1];return(0,e.createComponentVNode)(2,b.Window,{theme:"syndicate",width:500,height:600,children:[w&&(0,e.createComponentVNode)(2,v),(0,e.createComponentVNode)(2,b.Window.Content,{className:"Contractor",children:(0,e.createComponentVNode)(2,o.Flex,{direction:"column",height:"100%",children:B})})]})}return h}(),c=function(C,p){var N=(0,t.useBackend)(p),V=N.act,S=N.data,B=S.tc_available,L=S.tc_paid_out,w=S.completed_contracts,A=S.rep;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({title:"Summary",buttons:(0,e.createComponentVNode)(2,o.Box,{verticalAlign:"middle",mt:"0.25rem",children:[A," Rep"]})},C,{children:(0,e.createComponentVNode)(2,o.Flex,{children:[(0,e.createComponentVNode)(2,o.Box,{flexBasis:"50%",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"TC Available",verticalAlign:"middle",children:(0,e.createComponentVNode)(2,o.Flex,{align:"center",children:[(0,e.createComponentVNode)(2,o.Flex.Item,{grow:"1",children:[B," TC"]}),(0,e.createComponentVNode)(2,o.Button,{disabled:B<=0,content:"Claim",mx:"0.75rem",mb:"0",flexBasis:"content",onClick:function(){function x(){return V("claim")}return x}()})]})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"TC Earned",children:[L," TC"]})]})}),(0,e.createComponentVNode)(2,o.Box,{flexBasis:"50%",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Contracts Completed",verticalAlign:"middle",children:(0,e.createComponentVNode)(2,o.Box,{height:"20px",lineHeight:"20px",inline:!0,children:w})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Contractor Status",verticalAlign:"middle",children:"ACTIVE"})]})})]})})))},m=function(C,p){var N=(0,t.useBackend)(p),V=N.act,S=N.data,B=S.page;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Tabs,Object.assign({},C,{children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:B===1,onClick:function(){function L(){return V("page",{page:1})}return L}(),children:[(0,e.createComponentVNode)(2,o.Icon,{name:"suitcase"}),"Contracts"]}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:B===2,onClick:function(){function L(){return V("page",{page:2})}return L}(),children:[(0,e.createComponentVNode)(2,o.Icon,{name:"shopping-cart"}),"Hub"]})]})))},i=function(C,p){var N=(0,t.useBackend)(p),V=N.act,S=N.data,B=S.contracts,L=S.contract_active,w=S.can_extract,A=!!L&&B.filter(function(M){return M.status===1})[0],x=A&&A.time_left>0,E=(0,t.useLocalState)(p,"viewingPhoto",""),P=E[0],D=E[1];return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({title:"Available Contracts",overflow:"auto",buttons:(0,e.createComponentVNode)(2,o.Button,{disabled:!w||x,icon:"parachute-box",content:["Call Extraction",x&&(0,e.createComponentVNode)(2,f.Countdown,{timeLeft:A.time_left,format:function(){function M(R,O){return" ("+O.substr(3)+")"}return M}()})],onClick:function(){function M(){return V("extract")}return M}()})},C,{children:B.slice().sort(function(M,R){return M.status===1?-1:R.status===1?1:M.status-R.status}).map(function(M){var R;return(0,e.createComponentVNode)(2,o.Section,{title:(0,e.createComponentVNode)(2,o.Flex,{children:[(0,e.createComponentVNode)(2,o.Flex.Item,{grow:"1",color:M.status===1&&"good",children:M.target_name}),(0,e.createComponentVNode)(2,o.Flex.Item,{basis:"content",children:M.has_photo&&(0,e.createComponentVNode)(2,o.Button,{icon:"camera",mb:"-0.5rem",ml:"0.5rem",onClick:function(){function O(){return D("target_photo_"+M.uid+".png")}return O}()})})]}),className:"Contractor__Contract",buttons:(0,e.createComponentVNode)(2,o.Box,{width:"100%",children:[!!k[M.status]&&(0,e.createComponentVNode)(2,o.Box,{color:k[M.status][1],inline:!0,mt:M.status!==1&&"0.125rem",mr:"0.25rem",lineHeight:"20px",children:k[M.status][0]}),M.status===1&&(0,e.createComponentVNode)(2,o.Button.Confirm,{icon:"ban",color:"bad",content:"Abort",ml:"0.5rem",onClick:function(){function O(){return V("abort")}return O}()})]}),children:(0,e.createComponentVNode)(2,o.Flex,{children:[(0,e.createComponentVNode)(2,o.Flex.Item,{grow:"2",mr:"0.5rem",children:[M.fluff_message,!!M.completed_time&&(0,e.createComponentVNode)(2,o.Box,{color:"good",children:[(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.Icon,{name:"check",mr:"0.5rem"}),"Contract completed at ",M.completed_time]}),!!M.dead_extraction&&(0,e.createComponentVNode)(2,o.Box,{color:"bad",mt:"0.5rem",bold:!0,children:[(0,e.createComponentVNode)(2,o.Icon,{name:"exclamation-triangle",mr:"0.5rem"}),"Telecrystals reward reduced drastically as the target was dead during extraction."]}),!!M.fail_reason&&(0,e.createComponentVNode)(2,o.Box,{color:"bad",children:[(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.Icon,{name:"times",mr:"0.5rem"}),"Contract failed: ",M.fail_reason]})]}),(0,e.createComponentVNode)(2,o.Flex.Item,{flexBasis:"100%",children:[(0,e.createComponentVNode)(2,o.Flex,{mb:"0.5rem",color:"label",children:["Extraction Zone:\xA0",u(M)]}),(R=M.difficulties)==null?void 0:R.map(function(O,F){return(0,e.createComponentVNode)(2,o.Button.Confirm,{disabled:!!L,content:O.name+" ("+O.reward+" TC)",onClick:function(){function _(){return V("activate",{uid:M.uid,difficulty:F+1})}return _}()},F)}),!!M.objective&&(0,e.createComponentVNode)(2,o.Box,{color:"white",bold:!0,children:[M.objective.extraction_name,(0,e.createVNode)(1,"br"),"(",(M.objective.rewards.tc||0)+" TC",",\xA0",(M.objective.rewards.credits||0)+" Credits",")"]})]})]})},M.uid)})})))},u=function(C){if(!(!C.objective||C.status>1)){var p=C.objective.locs.user_area_id,N=C.objective.locs.user_coords,V=C.objective.locs.target_area_id,S=C.objective.locs.target_coords,B=p===V;return(0,e.createComponentVNode)(2,o.Flex.Item,{children:(0,e.createComponentVNode)(2,o.Icon,{name:B?"dot-circle-o":"arrow-alt-circle-right-o",color:B?"green":"yellow",rotation:B?null:-(0,a.rad2deg)(Math.atan2(S[1]-N[1],S[0]-N[0])),lineHeight:B?null:"0.85",size:"1.5"})})}},s=function(C,p){var N=(0,t.useBackend)(p),V=N.act,S=N.data,B=S.rep,L=S.buyables;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({title:"Available Purchases",overflow:"auto"},C,{children:L.map(function(w){return(0,e.createComponentVNode)(2,o.Section,{title:w.name,children:[w.description,(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.Button.Confirm,{disabled:B-1&&(0,e.createComponentVNode)(2,o.Box,{as:"span",color:w.stock===0?"bad":"good",ml:"0.5rem",children:[w.stock," in stock"]})]},w.uid)})})))},d=function(h){function C(N){var V;return V=h.call(this,N)||this,V.timer=null,V.state={currentIndex:0,currentDisplay:[]},V}y(C,h);var p=C.prototype;return p.tick=function(){function N(){var V=this.props,S=this.state;if(S.currentIndex<=V.allMessages.length){this.setState(function(L){return{currentIndex:L.currentIndex+1}});var B=S.currentDisplay;B.push(V.allMessages[S.currentIndex])}else clearTimeout(this.timer),setTimeout(V.onFinished,V.finishedTimeout)}return N}(),p.componentDidMount=function(){function N(){var V=this,S=this.props.linesPerSecond,B=S===void 0?2.5:S;this.timer=setInterval(function(){return V.tick()},1e3/B)}return N}(),p.componentWillUnmount=function(){function N(){clearTimeout(this.timer)}return N}(),p.render=function(){function N(){return(0,e.createComponentVNode)(2,o.Box,{m:1,children:this.state.currentDisplay.map(function(V){return(0,e.createFragment)([V,(0,e.createVNode)(1,"br")],0,V)})})}return N}(),C}(e.Component),v=function(C,p){var N=(0,t.useLocalState)(p,"viewingPhoto",""),V=N[0],S=N[1];return(0,e.createComponentVNode)(2,o.Modal,{className:"Contractor__photoZoom",children:[(0,e.createComponentVNode)(2,o.Box,{as:"img",src:V}),(0,e.createComponentVNode)(2,o.Button,{icon:"times",content:"Close",color:"grey",mt:"1rem",onClick:function(){function B(){return S("")}return B}()})]})}},54151:function(T,r,n){"use strict";r.__esModule=!0,r.ConveyorSwitch=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.ConveyorSwitch=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.slowFactor,m=l.oneWay,i=l.position;return(0,e.createComponentVNode)(2,o.Window,{width:350,height:135,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Lever position",children:i>0?"forward":i<0?"reverse":"neutral"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Allow reverse",children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:!m,onClick:function(){function u(){return g("toggleOneWay")}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Slowdown factor",children:(0,e.createComponentVNode)(2,t.Flex,{children:[(0,e.createComponentVNode)(2,t.Flex.Item,{mx:"1px",children:[" ",(0,e.createComponentVNode)(2,t.Button,{icon:"angle-double-left",onClick:function(){function u(){return g("slowFactor",{value:c-5})}return u}()})," "]}),(0,e.createComponentVNode)(2,t.Flex.Item,{mx:"1px",children:[" ",(0,e.createComponentVNode)(2,t.Button,{icon:"angle-left",onClick:function(){function u(){return g("slowFactor",{value:c-1})}return u}()})," "]}),(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,t.Slider,{width:"100px",mx:"1px",value:c,fillValue:c,minValue:1,maxValue:50,step:1,format:function(){function u(s){return s+"x"}return u}(),onChange:function(){function u(s,d){return g("slowFactor",{value:d})}return u}()})}),(0,e.createComponentVNode)(2,t.Flex.Item,{mx:"1px",children:[" ",(0,e.createComponentVNode)(2,t.Button,{icon:"angle-right",onClick:function(){function u(){return g("slowFactor",{value:c+1})}return u}()})," "]}),(0,e.createComponentVNode)(2,t.Flex.Item,{mx:"1px",children:[" ",(0,e.createComponentVNode)(2,t.Button,{icon:"angle-double-right",onClick:function(){function u(){return g("slowFactor",{value:c+5})}return u}()})," "]})]})})]})})})})}return b}()},73169:function(T,r,n){"use strict";r.__esModule=!0,r.CrewMonitor=void 0;var e=n(89005),a=n(88510),t=n(25328),o=n(72253),f=n(36036),b=n(36352),y=n(76910),I=n(98595),k=n(96184),g=["color"];function l(v,h){if(v==null)return{};var C={};for(var p in v)if({}.hasOwnProperty.call(v,p)){if(h.includes(p))continue;C[p]=v[p]}return C}var c=function(h,C){return h.dead?"Deceased":parseInt(h.health,10)<=C?"Critical":parseInt(h.stat,10)===1?"Unconscious":"Living"},m=function(h,C){return h.dead?"red":parseInt(h.health,10)<=C?"orange":parseInt(h.stat,10)===1?"blue":"green"},i=r.CrewMonitor=function(){function v(h,C){var p=(0,o.useBackend)(C),N=p.act,V=p.data,S=(0,o.useLocalState)(C,"tabIndex",V.tabIndex),B=S[0],L=S[1],w=function(){function x(E){L(E),N("set_tab_index",{tab_index:E})}return x}(),A=function(){function x(E){switch(E){case 0:return(0,e.createComponentVNode)(2,u);case 1:return(0,e.createComponentVNode)(2,d);default:return"WE SHOULDN'T BE HERE!"}}return x}();return(0,e.createComponentVNode)(2,I.Window,{width:800,height:600,children:(0,e.createComponentVNode)(2,I.Window.Content,{children:(0,e.createComponentVNode)(2,f.Stack,{fill:!0,vertical:!0,fillPositionedParent:!0,children:[(0,e.createComponentVNode)(2,f.Stack.Item,{children:(0,e.createComponentVNode)(2,f.Tabs,{children:[(0,e.createComponentVNode)(2,f.Tabs.Tab,{icon:"table",selected:B===0,onClick:function(){function x(){return w(0)}return x}(),children:"Data View"},"DataView"),(0,e.createComponentVNode)(2,f.Tabs.Tab,{icon:"map-marked-alt",selected:B===1,onClick:function(){function x(){return w(1)}return x}(),children:"Map View"},"MapView")]})}),A(B)]})})})}return v}(),u=function(h,C){var p=(0,o.useBackend)(C),N=p.act,V=p.data,S=V.possible_levels,B=V.viewing_current_z_level,L=V.is_advanced,w=V.highlightedNames,A=(0,a.sortBy)(function(M){return!w.includes(M.name)},function(M){return M.name})(V.crewmembers||[]),x=(0,o.useLocalState)(C,"search",""),E=x[0],P=x[1],D=(0,t.createSearch)(E,function(M){return M.name+"|"+M.assignment+"|"+M.area});return(0,e.createComponentVNode)(2,f.Section,{fill:!0,scrollable:!0,backgroundColor:"transparent",children:[(0,e.createComponentVNode)(2,f.Stack,{children:[(0,e.createComponentVNode)(2,f.Stack.Item,{width:"100%",ml:"5px",children:(0,e.createComponentVNode)(2,f.Input,{placeholder:"Search by name, assignment or location..",width:"100%",onInput:function(){function M(R,O){return P(O)}return M}()})}),(0,e.createComponentVNode)(2,f.Stack.Item,{children:L?(0,e.createComponentVNode)(2,f.Dropdown,{mr:"5px",width:"50px",options:S,selected:B,onSelected:function(){function M(R){return N("switch_level",{new_level:R})}return M}()}):null})]}),(0,e.createComponentVNode)(2,f.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,f.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,f.Table.Cell,{children:(0,e.createComponentVNode)(2,f.Button,{tooltip:"Clear highlights",icon:"square-xmark",onClick:function(){function M(){return N("clear_highlighted_names")}return M}()})}),(0,e.createComponentVNode)(2,f.Table.Cell,{children:"Name"}),(0,e.createComponentVNode)(2,f.Table.Cell,{children:"Status"}),(0,e.createComponentVNode)(2,f.Table.Cell,{children:"Location"})]}),A.filter(D).map(function(M,R){var O=w.includes(M.name);return(0,e.createComponentVNode)(2,f.Table.Row,{bold:!!M.is_command,children:[(0,e.createComponentVNode)(2,b.TableCell,{children:(0,e.createComponentVNode)(2,k.ButtonCheckbox,{checked:O,tooltip:"Mark on map",onClick:function(){function F(){return N(O?"remove_highlighted_name":"add_highlighted_name",{name:M.name})}return F}()})}),(0,e.createComponentVNode)(2,b.TableCell,{children:[M.name," (",M.assignment,")"]}),(0,e.createComponentVNode)(2,b.TableCell,{children:[(0,e.createComponentVNode)(2,f.Box,{inline:!0,color:m(M,V.critThreshold),children:c(M,V.critThreshold)}),M.sensor_type>=2||V.ignoreSensors?(0,e.createComponentVNode)(2,f.Box,{inline:!0,ml:1,children:["(",(0,e.createComponentVNode)(2,f.Box,{inline:!0,color:y.COLORS.damageType.oxy,children:M.oxy}),"|",(0,e.createComponentVNode)(2,f.Box,{inline:!0,color:y.COLORS.damageType.toxin,children:M.tox}),"|",(0,e.createComponentVNode)(2,f.Box,{inline:!0,color:y.COLORS.damageType.burn,children:M.fire}),"|",(0,e.createComponentVNode)(2,f.Box,{inline:!0,color:y.COLORS.damageType.brute,children:M.brute}),")"]}):null]}),(0,e.createComponentVNode)(2,b.TableCell,{children:M.sensor_type===3||V.ignoreSensors?V.isAI||V.isObserver?(0,e.createComponentVNode)(2,f.Button,{fluid:!0,icon:"location-arrow",content:M.area+" ("+M.x+", "+M.y+")",onClick:function(){function F(){return N("track",{track:M.ref})}return F}()}):M.area+" ("+M.x+", "+M.y+")":(0,e.createComponentVNode)(2,f.Box,{inline:!0,color:"grey",children:"Not Available"})})]},R)})]})]})},s=function(h,C){var p=h.color,N=l(h,g);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,f.NanoMap.Marker,Object.assign({},N,{children:(0,e.createVNode)(1,"span","highlighted-marker color-border-"+p)})))},d=function(h,C){var p=(0,o.useBackend)(C),N=p.act,V=p.data,S=V.highlightedNames;return(0,e.createComponentVNode)(2,f.Box,{height:"100vh",mb:"0.5rem",overflow:"hidden",children:(0,e.createComponentVNode)(2,f.NanoMap,{zoom:V.zoom,offsetX:V.offsetX,offsetY:V.offsetY,onZoom:function(){function B(L){return N("set_zoom",{zoom:L})}return B}(),onOffsetChange:function(){function B(L,w){return N("set_offset",{offset_x:w.offsetX,offset_y:w.offsetY})}return B}(),children:V.crewmembers.filter(function(B){return B.sensor_type===3||V.ignoreSensors}).map(function(B){var L=m(B,V.critThreshold),w=S.includes(B.name),A=function(){return V.isObserver?N("track",{track:B.ref}):null},x=function(){return N(w?"remove_highlighted_name":"add_highlighted_name",{name:B.name})},E=B.name+" ("+B.assignment+")";return w?(0,e.createComponentVNode)(2,s,{x:B.x,y:B.y,tooltip:E,color:L,onClick:A,onDblClick:x},B.ref):(0,e.createComponentVNode)(2,f.NanoMap.MarkerIcon,{x:B.x,y:B.y,icon:"circle",tooltip:E,color:L,onClick:A,onDblClick:x},B.ref)})})})}},63987:function(T,r,n){"use strict";r.__esModule=!0,r.Cryo=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=[{label:"Resp.",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Brute",type:"bruteLoss"},{label:"Burn",type:"fireLoss"}],b=[["good","Conscious"],["average","Unconscious"],["bad","DEAD"]],y=r.Cryo=function(){function g(l,c){return(0,e.createComponentVNode)(2,o.Window,{width:520,height:500,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,I)})})})}return g}(),I=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.isOperating,d=u.hasOccupant,v=u.occupant,h=v===void 0?[]:v,C=u.cellTemperature,p=u.cellTemperatureStatus,N=u.isBeakerLoaded,V=u.cooldownProgress,S=u.auto_eject_healthy,B=u.auto_eject_dead;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Occupant",fill:!0,scrollable:!0,buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"user-slash",onClick:function(){function L(){return i("ejectOccupant")}return L}(),disabled:!d,children:"Eject"}),children:d?(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Occupant",children:h.name||"Unknown"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Health",children:(0,e.createComponentVNode)(2,t.ProgressBar,{min:h.health,max:h.maxHealth,value:h.health/h.maxHealth,color:h.health>0?"good":"average",children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:Math.round(h.health)})})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",color:b[h.stat][0],children:b[h.stat][1]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Temperature",children:[(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:Math.round(h.bodyTemperature)})," K"]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),f.map(function(L){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:L.label,children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:h[L.type]/100,ranges:{bad:[.01,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:Math.round(h[L.type])})})},L.id)})]}):(0,e.createComponentVNode)(2,t.Stack,{fill:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),"No occupant detected."]})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Cell",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"eject",onClick:function(){function L(){return i("ejectBeaker")}return L}(),disabled:!N,children:"Eject Beaker"}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:(0,e.createComponentVNode)(2,t.Button,{icon:"power-off",onClick:function(){function L(){return i(s?"switchOff":"switchOn")}return L}(),selected:s,children:s?"On":"Off"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Temperature",color:p,children:[(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:C})," K"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Beaker",children:(0,e.createComponentVNode)(2,k)}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Dosage interval",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ranges:{average:[-1/0,99],good:[99,1/0]},color:!N&&"average",value:V,minValue:0,maxValue:100})}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Auto-eject healthy occupants",children:(0,e.createComponentVNode)(2,t.Button,{icon:S?"toggle-on":"toggle-off",selected:S,onClick:function(){function L(){return i(S?"auto_eject_healthy_off":"auto_eject_healthy_on")}return L}(),children:S?"On":"Off"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Auto-eject dead occupants",children:(0,e.createComponentVNode)(2,t.Button,{icon:B?"toggle-on":"toggle-off",selected:B,onClick:function(){function L(){return i(B?"auto_eject_dead_off":"auto_eject_dead_on")}return L}(),children:B?"On":"Off"})})]})})})],4)},k=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.isBeakerLoaded,d=u.beakerLabel,v=u.beakerVolume;return s?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:!d&&"average",children:[d||"No label",":"]}),(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:!v&&"bad",ml:1,children:v?(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:v,format:function(){function h(C){return Math.round(C)+" units remaining"}return h}()}):"Beaker is empty"})],4):(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:"bad",children:"No beaker loaded"})}},86099:function(T,r,n){"use strict";r.__esModule=!0,r.CryopodConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(25328),b=r.CryopodConsole=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.data,i=m.account_name,u=m.allow_items;return(0,e.createComponentVNode)(2,o.Window,{title:"Cryopod Console",width:400,height:480,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Hello, "+(i||"[REDACTED]")+"!",children:"This automated cryogenic freezing unit will safely store your corporeal form until your next assignment."}),(0,e.createComponentVNode)(2,y),!!u&&(0,e.createComponentVNode)(2,I)]})})}return k}(),y=function(g,l){var c=(0,a.useBackend)(l),m=c.data,i=m.frozen_crew;return(0,e.createComponentVNode)(2,t.Collapsible,{title:"Stored Crew",children:i.length?(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:i.map(function(u,s){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:u.name,children:u.rank},s)})})}):(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No stored crew!"})})},I=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.frozen_items,s=function(v){var h=v.toString();return h.startsWith("the ")&&(h=h.slice(4,h.length)),(0,f.toTitleCase)(h)};return(0,e.createComponentVNode)(2,t.Collapsible,{title:"Stored Items",children:u.length?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:u.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:s(d.name),buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-down",content:"Drop",mr:1,onClick:function(){function v(){return m("one_item",{item:d.uid})}return v}()})},d)})})}),(0,e.createComponentVNode)(2,t.Button,{content:"Drop All Items",color:"red",onClick:function(){function d(){return m("all_items")}return d}()})],4):(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No stored items!"})})}},12692:function(T,r,n){"use strict";r.__esModule=!0,r.DNAModifier=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(3939),b=[["good","Alive"],["average","Critical"],["bad","DEAD"]],y=[["ui","Modify U.I.","dna"],["se","Modify S.E.","dna"],["buffer","Transfer Buffers","syringe"],["rejuvenators","Rejuvenators","flask"]],I=[5,10,20,30,50],k=r.DNAModifier=function(){function p(N,V){var S=(0,a.useBackend)(V),B=S.act,L=S.data,w=L.irradiating,A=L.dnaBlockSize,x=L.occupant;V.dnaBlockSize=A,V.isDNAInvalid=!x.isViableSubject||!x.uniqueIdentity||!x.structuralEnzymes;var E;return w&&(E=(0,e.createComponentVNode)(2,h,{duration:w})),(0,e.createComponentVNode)(2,o.Window,{width:660,height:775,children:[(0,e.createComponentVNode)(2,f.ComplexModal),E,(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,g)}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,l)})]})})]})}return p}(),g=function(N,V){var S=(0,a.useBackend)(V),B=S.act,L=S.data,w=L.locked,A=L.hasOccupant,x=L.occupant;return(0,e.createComponentVNode)(2,t.Section,{title:"Occupant",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{color:"label",inline:!0,mr:"0.5rem",children:"Door Lock:"}),(0,e.createComponentVNode)(2,t.Button,{disabled:!A,selected:w,icon:w?"toggle-on":"toggle-off",content:w?"Engaged":"Disengaged",onClick:function(){function E(){return B("toggleLock")}return E}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:!A||w,icon:"user-slash",content:"Eject",onClick:function(){function E(){return B("ejectOccupant")}return E}()})],4),children:A?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Name",children:x.name}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Health",children:(0,e.createComponentVNode)(2,t.ProgressBar,{min:x.minHealth,max:x.maxHealth,value:x.health/x.maxHealth,ranges:{good:[.5,1/0],average:[0,.5],bad:[-1/0,0]}})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",color:b[x.stat][0],children:b[x.stat][1]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider)]})}),V.isDNAInvalid?(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"exclamation-circle"}),"\xA0 The occupant's DNA structure is ruined beyond recognition, please insert a subject with an intact DNA structure."]}):(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Radiation",children:(0,e.createComponentVNode)(2,t.ProgressBar,{min:"0",max:"100",value:x.radiationLevel/100,color:"average"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Unique Enzymes",children:L.occupant.uniqueEnzymes?L.occupant.uniqueEnzymes:(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"exclamation-circle"}),"\xA0 Unknown"]})})]})],0):(0,e.createComponentVNode)(2,t.Box,{color:"label",children:"Cell unoccupied."})})},l=function(N,V){var S=(0,a.useBackend)(V),B=S.act,L=S.data,w=L.selectedMenuKey,A=L.hasOccupant,x=L.occupant;if(A){if(V.isDNAInvalid)return(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,align:"center",textAlign:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),"No operation possible on this subject."]})})})}else return(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,align:"center",textAlign:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),"No occupant in DNA modifier."]})})});var E;return w==="ui"?E=(0,e.createFragment)([(0,e.createComponentVNode)(2,c),(0,e.createComponentVNode)(2,i)],4):w==="se"?E=(0,e.createFragment)([(0,e.createComponentVNode)(2,m),(0,e.createComponentVNode)(2,i)],4):w==="buffer"?E=(0,e.createComponentVNode)(2,u):w==="rejuvenators"&&(E=(0,e.createComponentVNode)(2,v)),(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:[(0,e.createComponentVNode)(2,t.Tabs,{children:y.map(function(P,D){return(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:P[2],selected:w===P[0],onClick:function(){function M(){return B("selectMenuKey",{key:P[0]})}return M}(),children:P[1]},D)})}),E]})},c=function(N,V){var S=(0,a.useBackend)(V),B=S.act,L=S.data,w=L.selectedUIBlock,A=L.selectedUISubBlock,x=L.selectedUITarget,E=L.occupant;return(0,e.createComponentVNode)(2,t.Section,{title:"Modify Unique Identifier",children:[(0,e.createComponentVNode)(2,C,{dnaString:E.uniqueIdentity,selectedBlock:w,selectedSubblock:A,blockSize:V.dnaBlockSize,action:"selectUIBlock"}),(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Target",children:(0,e.createComponentVNode)(2,t.Knob,{minValue:1,maxValue:15,stepPixelSize:"20",value:x,format:function(){function P(D){return D.toString(16).toUpperCase()}return P}(),ml:"0",onChange:function(){function P(D,M){return B("changeUITarget",{value:M})}return P}()})})}),(0,e.createComponentVNode)(2,t.Button,{icon:"radiation",content:"Irradiate Block",mt:"0.5rem",onClick:function(){function P(){return B("pulseUIRadiation")}return P}()})]})},m=function(N,V){var S=(0,a.useBackend)(V),B=S.act,L=S.data,w=L.selectedSEBlock,A=L.selectedSESubBlock,x=L.occupant;return(0,e.createComponentVNode)(2,t.Section,{title:"Modify Structural Enzymes",children:[(0,e.createComponentVNode)(2,C,{dnaString:x.structuralEnzymes,selectedBlock:w,selectedSubblock:A,blockSize:V.dnaBlockSize,action:"selectSEBlock"}),(0,e.createComponentVNode)(2,t.Button,{icon:"radiation",content:"Irradiate Block",onClick:function(){function E(){return B("pulseSERadiation")}return E}()})]})},i=function(N,V){var S=(0,a.useBackend)(V),B=S.act,L=S.data,w=L.radiationIntensity,A=L.radiationDuration;return(0,e.createComponentVNode)(2,t.Section,{title:"Radiation Emitter",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Intensity",children:(0,e.createComponentVNode)(2,t.Knob,{minValue:1,maxValue:10,stepPixelSize:20,value:w,popUpPosition:"right",ml:"0",onChange:function(){function x(E,P){return B("radiationIntensity",{value:P})}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Duration",children:(0,e.createComponentVNode)(2,t.Knob,{minValue:1,maxValue:20,stepPixelSize:10,unit:"s",value:A,popUpPosition:"right",ml:"0",onChange:function(){function x(E,P){return B("radiationDuration",{value:P})}return x}()})})]}),(0,e.createComponentVNode)(2,t.Button,{icon:"radiation",content:"Pulse Radiation",tooltip:"Mutates a random block of either the occupant's UI or SE.",tooltipPosition:"top-start",mt:"0.5rem",onClick:function(){function x(){return B("pulseRadiation")}return x}()})]})},u=function(N,V){var S=(0,a.useBackend)(V),B=S.act,L=S.data,w=L.buffers,A=w.map(function(x,E){return(0,e.createComponentVNode)(2,s,{id:E+1,name:"Buffer "+(E+1),buffer:x},E)});return(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{height:"75%",mt:1,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Buffers",children:A})}),(0,e.createComponentVNode)(2,t.Stack.Item,{height:"25%",children:(0,e.createComponentVNode)(2,d)})]})},s=function(N,V){var S=(0,a.useBackend)(V),B=S.act,L=S.data,w=N.id,A=N.name,x=N.buffer,E=L.isInjectorReady,P=A+(x.data?" - "+x.label:"");return(0,e.createComponentVNode)(2,t.Box,{backgroundColor:"rgba(0, 0, 0, 0.33)",mb:"0.5rem",children:(0,e.createComponentVNode)(2,t.Section,{title:P,mx:"0",lineHeight:"18px",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button.Confirm,{disabled:!x.data,icon:"trash",content:"Clear",onClick:function(){function D(){return B("bufferOption",{option:"clear",id:w})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:!x.data,icon:"pen",content:"Rename",onClick:function(){function D(){return B("bufferOption",{option:"changeLabel",id:w})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:!x.data||!L.hasDisk,icon:"save",content:"Export",tooltip:"Exports this buffer to the currently loaded data disk.",tooltipPosition:"bottom-start",onClick:function(){function D(){return B("bufferOption",{option:"saveDisk",id:w})}return D}()})],4),children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Write",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-down",content:"Subject U.I",mb:"0",onClick:function(){function D(){return B("bufferOption",{option:"saveUI",id:w})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-down",content:"Subject U.I and U.E.",mb:"0",onClick:function(){function D(){return B("bufferOption",{option:"saveUIAndUE",id:w})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-down",content:"Subject S.E.",mb:"0",onClick:function(){function D(){return B("bufferOption",{option:"saveSE",id:w})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:!L.hasDisk||!L.disk.data,icon:"arrow-circle-down",content:"From Disk",mb:"0",onClick:function(){function D(){return B("bufferOption",{option:"loadDisk",id:w})}return D}()})]}),!!x.data&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Subject",children:x.owner||(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"Unknown"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Data Type",children:[x.type==="ui"?"Unique Identifiers":"Structural Enzymes",!!x.ue&&" and Unique Enzymes"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Transfer to",children:[(0,e.createComponentVNode)(2,t.Button,{disabled:!E,icon:E?"syringe":"spinner",iconSpin:!E,content:"Injector",mb:"0",onClick:function(){function D(){return B("bufferOption",{option:"createInjector",id:w})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:!E,icon:E?"syringe":"spinner",iconSpin:!E,content:"Block Injector",mb:"0",onClick:function(){function D(){return B("bufferOption",{option:"createInjector",id:w,block:1})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"user",content:"Subject",mb:"0",onClick:function(){function D(){return B("bufferOption",{option:"transfer",id:w})}return D}()})]})],4)]}),!x.data&&(0,e.createComponentVNode)(2,t.Box,{color:"label",mt:"0.5rem",children:"This buffer is empty."})]})})},d=function(N,V){var S=(0,a.useBackend)(V),B=S.act,L=S.data,w=L.hasDisk,A=L.disk;return(0,e.createComponentVNode)(2,t.Section,{title:"Data Disk",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button.Confirm,{disabled:!w||!A.data,icon:"trash",content:"Wipe",onClick:function(){function x(){return B("wipeDisk")}return x}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:!w,icon:"eject",content:"Eject",onClick:function(){function x(){return B("ejectDisk")}return x}()})],4),children:w?A.data?(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Label",children:A.label?A.label:"No label"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Subject",children:A.owner?A.owner:(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"Unknown"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Data Type",children:[A.type==="ui"?"Unique Identifiers":"Structural Enzymes",!!A.ue&&" and Unique Enzymes"]})]}):(0,e.createComponentVNode)(2,t.Box,{color:"label",children:"Disk is blank."}):(0,e.createComponentVNode)(2,t.Box,{color:"label",textAlign:"center",my:"1rem",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"save-o",size:"4"}),(0,e.createVNode)(1,"br"),"No disk inserted."]})})},v=function(N,V){var S=(0,a.useBackend)(V),B=S.act,L=S.data,w=L.isBeakerLoaded,A=L.beakerVolume,x=L.beakerLabel;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Rejuvenators and Beaker",buttons:(0,e.createComponentVNode)(2,t.Button,{disabled:!w,icon:"eject",content:"Eject",onClick:function(){function E(){return B("ejectBeaker")}return E}()}),children:w?(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Inject",children:[I.map(function(E,P){return(0,e.createComponentVNode)(2,t.Button,{disabled:E>A,icon:"syringe",content:E,onClick:function(){function D(){return B("injectRejuvenators",{amount:E})}return D}()},P)}),(0,e.createComponentVNode)(2,t.Button,{disabled:A<=0,icon:"syringe",content:"All",onClick:function(){function E(){return B("injectRejuvenators",{amount:A})}return E}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Beaker",children:[(0,e.createComponentVNode)(2,t.Box,{mb:"0.5rem",children:x||"No label"}),A?(0,e.createComponentVNode)(2,t.Box,{color:"good",children:[A," unit",A===1?"":"s"," remaining"]}):(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:"Empty"})]})]}):(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,textAlign:"center",align:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon.Stack,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"flask",size:5,color:"silver"}),(0,e.createComponentVNode)(2,t.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"h3",null,"No beaker loaded.",16)]})})})},h=function(N,V){return(0,e.createComponentVNode)(2,t.Dimmer,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"spinner",size:"5",spin:!0}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Box,{color:"average",children:(0,e.createVNode)(1,"h1",null,[(0,e.createComponentVNode)(2,t.Icon,{name:"radiation"}),(0,e.createTextVNode)("\xA0Irradiating occupant\xA0"),(0,e.createComponentVNode)(2,t.Icon,{name:"radiation"})],4)}),(0,e.createComponentVNode)(2,t.Box,{color:"label",children:(0,e.createVNode)(1,"h3",null,[(0,e.createTextVNode)("For "),N.duration,(0,e.createTextVNode)(" second"),N.duration===1?"":"s"],0)})]})},C=function(N,V){for(var S=(0,a.useBackend)(V),B=S.act,L=S.data,w=N.dnaString,A=N.selectedBlock,x=N.selectedSubblock,E=N.blockSize,P=N.action,D=w.split(""),M=0,R=[],O=function(){for(var U=F/E+1,z=[],$=function(){var J=G+1;z.push((0,e.createComponentVNode)(2,t.Button,{selected:A===U&&x===J,content:D[F+G],mb:"0",onClick:function(){function se(){return B(P,{block:U,subblock:J})}return se}()}))},G=0;Gd.spawnpoints?"red":"green",children:[d.total," total, versus ",d.spawnpoints," spawnpoints"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Dispatch",children:(0,e.createComponentVNode)(2,t.Button,{width:10.5,textAlign:"center",icon:"ambulance",content:"Send ERT",onClick:function(){function N(){return s("dispatch_ert",{silent:C})}return N}()})})]})})})},g=function(m,i){var u=(0,a.useBackend)(i),s=u.act,d=u.data,v=d.ert_request_messages;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:v&&v.length?v.map(function(h){return(0,e.createComponentVNode)(2,t.Section,{title:h.time,buttons:(0,e.createComponentVNode)(2,t.Button,{content:h.sender_real_name,onClick:function(){function C(){return s("view_player_panel",{uid:h.sender_uid})}return C}(),tooltip:"View player panel"}),children:h.message},(0,f.decodeHtmlEntities)(h.time))}):(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,textAlign:"center",align:"center",color:"average",children:[(0,e.createComponentVNode)(2,t.Icon.Stack,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"broadcast-tower",size:5,color:"gray"}),(0,e.createComponentVNode)(2,t.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"No ERT requests."]})})})})},l=function(m,i){var u=(0,a.useBackend)(i),s=u.act,d=u.data,v=(0,a.useLocalState)(i,"text",""),h=v[0],C=v[1];return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:[(0,e.createComponentVNode)(2,t.Input,{placeholder:"Enter ERT denial reason here,\nMultiline input is accepted.",rows:19,fluid:!0,multiline:1,value:h,onChange:function(){function p(N,V){return C(V)}return p}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{content:"Deny ERT",fluid:!0,icon:"times",center:!0,mt:2,textAlign:"center",onClick:function(){function p(){return s("deny_ert",{reason:h})}return p}()})]})})}},90217:function(T,r,n){"use strict";r.__esModule=!0,r.EconomyManager=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(3939),b=r.EconomyManager=function(){function I(k,g){return(0,e.createComponentVNode)(2,o.Window,{width:600,height:325,children:[(0,e.createComponentVNode)(2,f.ComplexModal),(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,className:"Layout__content--flexColumn",children:(0,e.createComponentVNode)(2,y)})]})}return I}(),y=function(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.next_payroll_time;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.4rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"coins",verticalAlign:"middle",size:3,mr:"1rem"}),"Economy Manager"]}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.LabeledList,{label:"Pay Bonuses and Deductions",children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Global",children:(0,e.createComponentVNode)(2,t.Button,{icon:"dollar-sign",width:"auto",content:"Global Payroll Modification",onClick:function(){function u(){return c("payroll_modification",{mod_type:"global"})}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Department Accounts",children:(0,e.createComponentVNode)(2,t.Button,{icon:"dollar-sign",width:"auto",content:"Department Account Payroll Modification",onClick:function(){function u(){return c("payroll_modification",{mod_type:"department"})}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Department Members",children:(0,e.createComponentVNode)(2,t.Button,{icon:"dollar-sign",width:"auto",content:"Department Members Payroll Modification",onClick:function(){function u(){return c("payroll_modification",{mod_type:"department_members"})}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Single Accounts",children:(0,e.createComponentVNode)(2,t.Button,{icon:"dollar-sign",width:"auto",content:"Crew Member Payroll Modification",onClick:function(){function u(){return c("payroll_modification",{mod_type:"crew_member"})}return u}()})})]}),(0,e.createVNode)(1,"hr"),(0,e.createComponentVNode)(2,t.Box,{mb:.5,children:["Next Payroll in: ",i," Minutes"]}),(0,e.createComponentVNode)(2,t.Button,{icon:"angle-double-left",width:"auto",color:"bad",content:"Delay Payroll",onClick:function(){function u(){return c("delay_payroll")}return u}()}),(0,e.createComponentVNode)(2,t.Button,{width:"auto",content:"Set Payroll Time",onClick:function(){function u(){return c("set_payroll")}return u}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"angle-double-right",width:"auto",color:"good",content:"Accelerate Payroll",onClick:function(){function u(){return c("accelerate_payroll")}return u}()})]}),(0,e.createComponentVNode)(2,t.NoticeBox,{children:[(0,e.createVNode)(1,"b",null,"WARNING:",16)," You take full responsibility for unbalancing the economy with these buttons!"]})],4)}},82565:function(T,r,n){"use strict";r.__esModule=!0,r.Electropack=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),f=n(98595),b=r.Electropack=function(){function y(I,k){var g=(0,t.useBackend)(k),l=g.act,c=g.data,m=c.power,i=c.code,u=c.frequency,s=c.minFrequency,d=c.maxFrequency;return(0,e.createComponentVNode)(2,f.Window,{width:360,height:135,children:(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Power",children:(0,e.createComponentVNode)(2,o.Button,{icon:m?"power-off":"times",content:m?"On":"Off",selected:m,onClick:function(){function v(){return l("power")}return v}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Frequency",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"sync",content:"Reset",onClick:function(){function v(){return l("reset",{reset:"freq"})}return v}()}),children:(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,unit:"kHz",step:.2,stepPixelSize:6,minValue:s/10,maxValue:d/10,value:u/10,format:function(){function v(h){return(0,a.toFixed)(h,1)}return v}(),width:"80px",onChange:function(){function v(h,C){return l("freq",{freq:C})}return v}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Code",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"sync",content:"Reset",onClick:function(){function v(){return l("reset",{reset:"code"})}return v}()}),children:(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,step:1,stepPixelSize:6,minValue:1,maxValue:100,value:i,width:"80px",onChange:function(){function v(h,C){return l("code",{code:C})}return v}()})})]})})})})}return y}()},11243:function(T,r,n){"use strict";r.__esModule=!0,r.Emojipedia=void 0;var e=n(89005),a=n(35840),t=n(72253),o=n(36036),f=n(98595),b=r.Emojipedia=function(){function I(k,g){var l=(0,t.useBackend)(g),c=l.data,m=c.emoji_list,i=(0,t.useLocalState)(g,"searchText",""),u=i[0],s=i[1],d=m.filter(function(v){return v.name.toLowerCase().includes(u.toLowerCase())});return(0,e.createComponentVNode)(2,f.Window,{width:325,height:400,children:(0,e.createComponentVNode)(2,f.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Emojipedia v1.0.1",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Input,{placeholder:"Search by name",value:u,onInput:function(){function v(h,C){return s(C)}return v}()}),(0,e.createComponentVNode)(2,o.Button,{tooltip:"Click on an emoji to copy its tag!",tooltipPosition:"bottom",icon:"circle-question"})],4),children:d.map(function(v){return(0,e.createComponentVNode)(2,o.Button,{m:1,color:"transparent",className:(0,a.classes)(["emoji16x16","emoji-"+v.name]),style:{transform:"scale(1.5)"},tooltip:v.name,onClick:function(){function h(){y(v.name)}return h}()},v.name)})})})})}return I}(),y=function(k){var g=document.createElement("input"),l=":"+k+":";g.value=l,document.body.appendChild(g),g.select(),document.execCommand("copy"),document.body.removeChild(g)}},36730:function(T,r,n){"use strict";r.__esModule=!0,r.EvolutionMenu=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),f=n(98595),b=n(64795),y=n(88510),I=r.EvolutionMenu=function(){function l(c,m){return(0,e.createComponentVNode)(2,f.Window,{width:480,height:580,theme:"changeling",children:(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,k),(0,e.createComponentVNode)(2,g)]})})})}return l}(),k=function(c,m){var i=(0,t.useBackend)(m),u=i.act,s=i.data,d=s.evo_points,v=s.can_respec;return(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{title:"Evolution Points",height:5.5,children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{mt:.5,color:"label",children:"Points remaining:"}),(0,e.createComponentVNode)(2,o.Stack.Item,{mt:.5,ml:2,bold:!0,color:"#1b945c",children:d}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:[(0,e.createComponentVNode)(2,o.Button,{ml:2.5,disabled:!v,content:"Readapt",icon:"sync",onClick:function(){function h(){return u("readapt")}return h}()}),(0,e.createComponentVNode)(2,o.Button,{tooltip:"By transforming a humanoid into a husk, we gain the ability to readapt our chosen evolutions.",tooltipPosition:"bottom",icon:"question-circle"})]})]})})})},g=function(c,m){var i=(0,t.useBackend)(m),u=i.act,s=i.data,d=s.evo_points,v=s.ability_tabs,h=s.purchased_abilities,C=s.view_mode,p=(0,t.useLocalState)(m,"selectedTab",v[0]),N=p[0],V=p[1],S=(0,t.useLocalState)(m,"searchText",""),B=S[0],L=S[1],w=(0,t.useLocalState)(m,"ability_tabs",v[0].abilities),A=w[0],x=w[1],E=function(R,O){if(O===void 0&&(O=""),!R||R.length===0)return[];var F=(0,a.createSearch)(O,function(_){return _.name+"|"+_.description});return(0,b.flow)([(0,y.filter)(function(_){return _==null?void 0:_.name}),(0,y.filter)(F),(0,y.sortBy)(function(_){return _==null?void 0:_.name})])(R)},P=function(R){if(L(R),R==="")return x(N.abilities);x(E(v.map(function(O){return O.abilities}).flat(),R))},D=function(R){V(R),x(R.abilities),L("")};return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Abilities",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Input,{width:"200px",placeholder:"Search Abilities",onInput:function(){function M(R,O){P(O)}return M}(),value:B}),(0,e.createComponentVNode)(2,o.Button,{icon:C?"square-o":"check-square-o",selected:!C,content:"Compact",onClick:function(){function M(){return u("set_view_mode",{mode:0})}return M}()}),(0,e.createComponentVNode)(2,o.Button,{icon:C?"check-square-o":"square-o",selected:C,content:"Expanded",onClick:function(){function M(){return u("set_view_mode",{mode:1})}return M}()})],4),children:[(0,e.createComponentVNode)(2,o.Tabs,{children:v.map(function(M){return(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:B===""&&N===M,onClick:function(){function R(){D(M)}return R}(),children:M.category},M)})}),A.map(function(M,R){return(0,e.createComponentVNode)(2,o.Box,{p:.5,mx:-1,className:"candystripe",children:[(0,e.createComponentVNode)(2,o.Stack,{align:"center",children:[(0,e.createComponentVNode)(2,o.Stack.Item,{ml:.5,color:"#dedede",children:M.name}),h.includes(M.power_path)&&(0,e.createComponentVNode)(2,o.Stack.Item,{ml:2,bold:!0,color:"#1b945c",children:"(Purchased)"}),(0,e.createComponentVNode)(2,o.Stack.Item,{mr:3,textAlign:"right",grow:1,children:[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:["Cost:"," "]}),(0,e.createComponentVNode)(2,o.Box,{as:"span",bold:!0,color:"#1b945c",children:M.cost})]}),(0,e.createComponentVNode)(2,o.Stack.Item,{textAlign:"right",children:(0,e.createComponentVNode)(2,o.Button,{mr:.5,disabled:M.cost>d||h.includes(M.power_path),content:"Evolve",onClick:function(){function O(){return u("purchase",{power_path:M.power_path})}return O}()})})]}),!!C&&(0,e.createComponentVNode)(2,o.Stack,{color:"#8a8a8a",my:1,ml:1.5,width:"95%",children:M.description+" "+M.helptext})]},R)})]})})}},17370:function(T,r,n){"use strict";r.__esModule=!0,r.ExosuitFabricator=void 0;var e=n(89005),a=n(35840),t=n(25328),o=n(72253),f=n(36036),b=n(73379),y=n(98595),I=["id","amount","lineDisplay","onClick"];function k(p,N){if(p==null)return{};var V={};for(var S in p)if({}.hasOwnProperty.call(p,S)){if(N.includes(S))continue;V[S]=p[S]}return V}var g=2e3,l={bananium:"clown",tranquillite:"mime"},c=r.ExosuitFabricator=function(){function p(N,V){var S=(0,o.useBackend)(V),B=S.act,L=S.data,w=L.building,A=L.linked;return A?(0,e.createComponentVNode)(2,y.Window,{width:950,height:625,children:(0,e.createComponentVNode)(2,y.Window.Content,{className:"Exofab",children:[(0,e.createComponentVNode)(2,C),(0,e.createComponentVNode)(2,f.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,f.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,f.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,f.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,i)}),w&&(0,e.createComponentVNode)(2,f.Stack.Item,{children:(0,e.createComponentVNode)(2,u)})]})}),(0,e.createComponentVNode)(2,f.Stack.Item,{width:"30%",children:(0,e.createComponentVNode)(2,f.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,f.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,m)}),(0,e.createComponentVNode)(2,f.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,s)})]})})]})]})}):(0,e.createComponentVNode)(2,h)}return p}(),m=function(N,V){var S=(0,o.useBackend)(V),B=S.act,L=S.data,w=L.materials,A=L.capacity,x=Object.values(w).reduce(function(E,P){return E+P},0);return(0,e.createComponentVNode)(2,f.Section,{fill:!0,scrollable:!0,title:"Materials",className:"Exofab__materials",buttons:(0,e.createComponentVNode)(2,f.Box,{color:"label",mt:"0.25rem",children:[(x/A*100).toPrecision(3),"% full"]}),children:["metal","glass","silver","gold","uranium","titanium","plasma","diamond","bluespace","bananium","tranquillite","plastic"].map(function(E){return(0,e.createComponentVNode)(2,d,{mt:-2,id:E,bold:E==="metal"||E==="glass",onClick:function(){function P(){return B("withdraw",{id:E})}return P}()},E)})})},i=function(N,V){var S=(0,o.useBackend)(V),B=S.act,L=S.data,w=L.curCategory,A=L.categories,x=L.designs,E=L.syncing,P=(0,o.useLocalState)(V,"searchText",""),D=P[0],M=P[1],R=(0,t.createSearch)(D,function(z){return z.name}),O=x.filter(R),F=(0,o.useLocalState)(V,"levelsModal",!1),_=F[0],U=F[1];return(0,e.createComponentVNode)(2,f.Section,{fill:!0,scrollable:!0,className:"Exofab__designs",title:(0,e.createComponentVNode)(2,f.Dropdown,{width:"19rem",className:"Exofab__dropdown",selected:w,options:A,onSelected:function(){function z($){return B("category",{cat:$})}return z}()}),buttons:(0,e.createComponentVNode)(2,f.Box,{mt:"2px",children:[(0,e.createComponentVNode)(2,f.Button,{icon:"plus",content:"Queue all",onClick:function(){function z(){return B("queueall")}return z}()}),(0,e.createComponentVNode)(2,f.Button,{icon:"info",content:"Show current tech levels",onClick:function(){function z(){return U(!0)}return z}()}),(0,e.createComponentVNode)(2,f.Button,{icon:"unlink",color:"red",tooltip:"Disconnect from R&D network",onClick:function(){function z(){return B("unlink")}return z}()})]}),children:[(0,e.createComponentVNode)(2,f.Input,{placeholder:"Search by name...",mb:"0.5rem",width:"100%",onInput:function(){function z($,G){return M(G)}return z}()}),O.map(function(z){return(0,e.createComponentVNode)(2,v,{design:z},z.id)}),O.length===0&&(0,e.createComponentVNode)(2,f.Box,{color:"label",children:"No designs found."})]})},u=function(N,V){var S=(0,o.useBackend)(V),B=S.act,L=S.data,w=L.building,A=L.buildStart,x=L.buildEnd,E=L.worldTime;return(0,e.createComponentVNode)(2,f.Section,{className:"Exofab__building",stretchContents:!0,children:(0,e.createComponentVNode)(2,f.ProgressBar.Countdown,{start:A,current:E,end:x,children:(0,e.createComponentVNode)(2,f.Stack,{children:[(0,e.createComponentVNode)(2,f.Stack.Item,{children:(0,e.createComponentVNode)(2,f.Icon,{name:"cog",spin:!0})}),(0,e.createComponentVNode)(2,f.Stack.Item,{children:["Building ",w,"\xA0(",(0,e.createComponentVNode)(2,b.Countdown,{current:E,timeLeft:x-E,format:function(){function P(D,M){return M.substr(3)}return P}()}),")"]})]})})})},s=function(N,V){var S=(0,o.useBackend)(V),B=S.act,L=S.data,w=L.queue,A=L.processingQueue,x=Object.entries(L.queueDeficit).filter(function(P){return P[1]<0}),E=w.reduce(function(P,D){return P+D.time},0);return(0,e.createComponentVNode)(2,f.Section,{fill:!0,scrollable:!0,className:"Exofab__queue",title:"Queue",buttons:(0,e.createComponentVNode)(2,f.Box,{children:[(0,e.createComponentVNode)(2,f.Button,{selected:A,icon:A?"toggle-on":"toggle-off",content:"Process",onClick:function(){function P(){return B("process")}return P}()}),(0,e.createComponentVNode)(2,f.Button,{disabled:w.length===0,icon:"eraser",content:"Clear",onClick:function(){function P(){return B("unqueueall")}return P}()})]}),children:(0,e.createComponentVNode)(2,f.Stack,{fill:!0,vertical:!0,children:w.length===0?(0,e.createComponentVNode)(2,f.Box,{color:"label",children:"The queue is empty."}):(0,e.createFragment)([(0,e.createComponentVNode)(2,f.Stack.Item,{className:"Exofab__queue--queue",grow:!0,overflow:"auto",children:w.map(function(P,D){return(0,e.createComponentVNode)(2,f.Box,{color:P.notEnough&&"bad",children:[D+1,". ",P.name,D>0&&(0,e.createComponentVNode)(2,f.Button,{icon:"arrow-up",onClick:function(){function M(){return B("queueswap",{from:D+1,to:D})}return M}()}),D0&&(0,e.createComponentVNode)(2,f.Stack.Item,{className:"Exofab__queue--time",children:[(0,e.createComponentVNode)(2,f.Divider),"Processing time:",(0,e.createComponentVNode)(2,f.Icon,{name:"clock",mx:"0.5rem"}),(0,e.createComponentVNode)(2,f.Box,{inline:!0,bold:!0,children:new Date(E/10*1e3).toISOString().substr(14,5)})]}),Object.keys(x).length>0&&(0,e.createComponentVNode)(2,f.Stack.Item,{className:"Exofab__queue--deficit",shrink:"0",children:[(0,e.createComponentVNode)(2,f.Divider),"Lacking materials to complete:",x.map(function(P){return(0,e.createComponentVNode)(2,f.Box,{children:(0,e.createComponentVNode)(2,d,{id:P[0],amount:-P[1],lineDisplay:!0})},P[0])})]})],0)})})},d=function(N,V){var S=(0,o.useBackend)(V),B=S.act,L=S.data,w=N.id,A=N.amount,x=N.lineDisplay,E=N.onClick,P=k(N,I),D=L.materials[w]||0,M=A||D;if(!(M<=0&&!(w==="metal"||w==="glass"))){var R=A&&A>D;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,f.Stack,Object.assign({align:"center",className:(0,a.classes)(["Exofab__material",x&&"Exofab__material--line"])},P,{children:x?(0,e.createFragment)([(0,e.createComponentVNode)(2,f.Stack.Item,{className:(0,a.classes)(["materials32x32",w])}),(0,e.createComponentVNode)(2,f.Stack.Item,{className:"Exofab__material--amount",color:R&&"bad",ml:0,mr:1,children:M.toLocaleString("en-US")})],4):(0,e.createFragment)([(0,e.createComponentVNode)(2,f.Stack.Item,{basis:"content",children:(0,e.createComponentVNode)(2,f.Button,{width:"85%",color:"transparent",onClick:E,children:(0,e.createComponentVNode)(2,f.Box,{mt:1,className:(0,a.classes)(["materials32x32",w])})})}),(0,e.createComponentVNode)(2,f.Stack.Item,{grow:"1",children:[(0,e.createComponentVNode)(2,f.Box,{className:"Exofab__material--name",children:w}),(0,e.createComponentVNode)(2,f.Box,{className:"Exofab__material--amount",children:[M.toLocaleString("en-US")," cm\xB3 (",Math.round(M/g*10)/10," ","sheets)"]})]})],4)})))}},v=function(N,V){var S=(0,o.useBackend)(V),B=S.act,L=S.data,w=N.design;return(0,e.createComponentVNode)(2,f.Box,{className:"Exofab__design",children:[(0,e.createComponentVNode)(2,f.Button,{disabled:w.notEnough||L.building,icon:"cog",content:w.name,onClick:function(){function A(){return B("build",{id:w.id})}return A}()}),(0,e.createComponentVNode)(2,f.Button,{icon:"plus-circle",onClick:function(){function A(){return B("queue",{id:w.id})}return A}()}),(0,e.createComponentVNode)(2,f.Box,{className:"Exofab__design--cost",children:Object.entries(w.cost).map(function(A){return(0,e.createComponentVNode)(2,f.Box,{children:(0,e.createComponentVNode)(2,d,{id:A[0],amount:A[1],lineDisplay:!0})},A[0])})}),(0,e.createComponentVNode)(2,f.Stack,{className:"Exofab__design--time",children:(0,e.createComponentVNode)(2,f.Stack.Item,{children:[(0,e.createComponentVNode)(2,f.Icon,{name:"clock"}),w.time>0?(0,e.createFragment)([w.time/10,(0,e.createTextVNode)(" seconds")],0):"Instant"]})})]})},h=function(N,V){var S=(0,o.useBackend)(V),B=S.act,L=S.data,w=L.controllers;return(0,e.createComponentVNode)(2,y.Window,{children:(0,e.createComponentVNode)(2,y.Window.Content,{children:(0,e.createComponentVNode)(2,f.Section,{title:"Setup Linkage",children:(0,e.createComponentVNode)(2,f.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,f.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,f.Table.Cell,{children:"Network Address"}),(0,e.createComponentVNode)(2,f.Table.Cell,{children:"Network ID"}),(0,e.createComponentVNode)(2,f.Table.Cell,{children:"Link"})]}),w.map(function(A){return(0,e.createComponentVNode)(2,f.Table.Row,{children:[(0,e.createComponentVNode)(2,f.Table.Cell,{children:A.addr}),(0,e.createComponentVNode)(2,f.Table.Cell,{children:A.net_id}),(0,e.createComponentVNode)(2,f.Table.Cell,{children:(0,e.createComponentVNode)(2,f.Button,{content:"Link",icon:"link",onClick:function(){function x(){return B("linktonetworkcontroller",{target_controller:A.addr})}return x}()})})]},A.addr)})]})})})})},C=function(N,V){var S=(0,o.useBackend)(V),B=S.act,L=S.data,w=L.tech_levels,A=(0,o.useLocalState)(V,"levelsModal",!1),x=A[0],E=A[1];return x?(0,e.createComponentVNode)(2,f.Modal,{maxWidth:"75%",width:window.innerWidth+"px",maxHeight:window.innerHeight*.75+"px",mx:"auto",children:(0,e.createComponentVNode)(2,f.Section,{title:"Current tech levels",buttons:(0,e.createComponentVNode)(2,f.Button,{content:"Close",onClick:function(){function P(){E(!1)}return P}()}),children:(0,e.createComponentVNode)(2,f.LabeledList,{children:w.map(function(P){var D=P.name,M=P.level;return(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:D,children:M},D)})})})}):null}},59128:function(T,r,n){"use strict";r.__esModule=!0,r.ExperimentConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=new Map([[0,{text:"Conscious",color:"good"}],[1,{text:"Unconscious",color:"average"}],[2,{text:"Deceased",color:"bad"}]]),b=new Map([[0,{label:"Probe",icon:"thermometer"}],[1,{label:"Dissect",icon:"brain"}],[2,{label:"Analyze",icon:"search"}]]),y=r.ExperimentConsole=function(){function I(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.open,u=m.feedback,s=m.occupant,d=m.occupant_name,v=m.occupant_status,h=function(){function p(){if(!s)return(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No specimen detected."});var N=function(){function S(){return f.get(v)}return S}(),V=N();return(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Name",children:d}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",color:V.color,children:V.text}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Experiments",children:[0,1,2].map(function(S){return(0,e.createComponentVNode)(2,t.Button,{icon:b.get(S).icon,content:b.get(S).label,onClick:function(){function B(){return c("experiment",{experiment_type:S})}return B}()},S)})})]})}return p}(),C=h();return(0,e.createComponentVNode)(2,o.Window,{theme:"abductor",width:350,height:200,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:u})})}),(0,e.createComponentVNode)(2,t.Section,{title:"Scanner",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:"Eject",disabled:!i,onClick:function(){function p(){return c("door")}return p}()}),children:C})]})})}return I}()},97086:function(T,r,n){"use strict";r.__esModule=!0,r.ExternalAirlockController=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=0,b=1013,y=function(g){var l="good",c=80,m=95,i=110,u=120;return gi?l="average":g>u&&(l="bad"),l},I=r.ExternalAirlockController=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.chamber_pressure,s=i.exterior_status,d=i.interior_status,v=i.processing;return(0,e.createComponentVNode)(2,o.Window,{width:330,height:205,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Information",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Chamber Pressure",children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:y(u),value:u,minValue:f,maxValue:b,children:[u," kPa"]})})})}),(0,e.createComponentVNode)(2,t.Section,{title:"Actions",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Abort",icon:"ban",color:"red",disabled:!v,onClick:function(){function h(){return m("abort")}return h}()}),children:[(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Button,{width:"49%",content:"Cycle to Exterior",icon:"arrow-circle-left",disabled:v,onClick:function(){function h(){return m("cycle_ext")}return h}()}),(0,e.createComponentVNode)(2,t.Button,{width:"50%",content:"Cycle to Interior",icon:"arrow-circle-right",disabled:v,onClick:function(){function h(){return m("cycle_int")}return h}()})]}),(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Button,{width:"49%",content:"Force Exterior Door",icon:"exclamation-triangle",color:d==="open"?"red":v?"yellow":null,onClick:function(){function h(){return m("force_ext")}return h}()}),(0,e.createComponentVNode)(2,t.Button,{width:"50%",content:"Force Interior Door",icon:"exclamation-triangle",color:d==="open"?"red":v?"yellow":null,onClick:function(){function h(){return m("force_int")}return h}()})]})]})]})})}return k}()},96142:function(T,r,n){"use strict";r.__esModule=!0,r.FaxMachine=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.FaxMachine=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data;return(0,e.createComponentVNode)(2,o.Window,{width:540,height:295,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Authorization",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"ID Card",children:(0,e.createComponentVNode)(2,t.Button,{icon:l.scan_name?"eject":"id-card",selected:l.scan_name,content:l.scan_name?l.scan_name:"-----",tooltip:l.scan_name?"Eject ID":"Insert ID",onClick:function(){function c(){return g("scan")}return c}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Authorize",children:(0,e.createComponentVNode)(2,t.Button,{icon:l.authenticated?"sign-out-alt":"id-card",selected:l.authenticated,disabled:l.nologin,content:l.realauth?"Log Out":"Log In",onClick:function(){function c(){return g("auth")}return c}()})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Fax Menu",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Network",children:l.network}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Document",children:[(0,e.createComponentVNode)(2,t.Button,{icon:l.paper?"eject":"paperclip",disabled:!l.authenticated&&!l.paper,content:l.paper?l.paper:"-----",onClick:function(){function c(){return g("paper")}return c}()}),!!l.paper&&(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:"Rename",onClick:function(){function c(){return g("rename")}return c}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Sending To",children:(0,e.createComponentVNode)(2,t.Button,{icon:"print",content:l.destination?l.destination:"-----",disabled:!l.authenticated,onClick:function(){function c(){return g("dept")}return c}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Action",children:(0,e.createComponentVNode)(2,t.Button,{icon:"envelope",content:l.sendError?l.sendError:"Send",disabled:!l.paper||!l.destination||!l.authenticated||l.sendError,onClick:function(){function c(){return g("send")}return c}()})})]})})]})})}return b}()},74123:function(T,r,n){"use strict";r.__esModule=!0,r.FilingCabinet=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.FilingCabinet=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=k.config,m=l.contents,i=c.title;return(0,e.createComponentVNode)(2,o.Window,{width:400,height:300,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Contents",children:[!m&&(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,textAlign:"center",align:"center",color:"average",children:[(0,e.createComponentVNode)(2,t.Icon.Stack,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"folder-open",size:5,color:"gray"}),(0,e.createComponentVNode)(2,t.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"The ",i," is empty."]})}),!!m&&m.slice().map(function(u){return(0,e.createComponentVNode)(2,t.Stack,{mt:.5,className:"candystripe",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"80%",children:u.display_name}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-down",content:"Retrieve",onClick:function(){function s(){return g("retrieve",{index:u.index})}return s}()})})]},u)})]})})})})}return b}()},83767:function(T,r,n){"use strict";r.__esModule=!0,r.FloorPainter=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=function(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=k.icon_state,u=k.direction,s=k.isSelected,d=k.onSelect;return(0,e.createComponentVNode)(2,t.DmIcon,{icon:m.icon,icon_state:i,direction:u,onClick:d,style:{"border-style":s&&"solid"||"none","border-width":"2px","border-color":"orange",padding:s&&"0px"||"2px"}})},b={NORTH:1,SOUTH:2,EAST:4,WEST:8},y=r.FloorPainter=function(){function I(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.availableStyles,u=m.selectedStyle,s=m.selectedDir;return(0,e.createComponentVNode)(2,o.Window,{width:405,height:475,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Decal setup",children:[(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-left",onClick:function(){function d(){return c("cycle_style",{offset:-1})}return d}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Dropdown,{options:i,selected:u,width:"150px",nochevron:!0,onSelected:function(){function d(v){return c("select_style",{style:v})}return d}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-right",onClick:function(){function d(){return c("cycle_style",{offset:1})}return d}()})})]}),(0,e.createComponentVNode)(2,t.Box,{mt:"5px",mb:"5px",children:(0,e.createComponentVNode)(2,t.Flex,{overflowY:"auto",maxHeight:"239px",wrap:"wrap",children:i.map(function(d){return(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,f,{icon_state:d,isSelected:u===d,onSelect:function(){function v(){return c("select_style",{style:d})}return v}()})},d)})})}),(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Direction",children:(0,e.createComponentVNode)(2,t.Table,{style:{display:"inline"},children:[b.NORTH,null,b.SOUTH].map(function(d){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[d+b.WEST,d,d+b.EAST].map(function(v){return(0,e.createComponentVNode)(2,t.Table.Cell,{style:{"vertical-align":"middle","text-align":"center"},children:v===null?(0,e.createComponentVNode)(2,t.Icon,{name:"arrows-alt",size:3}):(0,e.createComponentVNode)(2,f,{icon_state:u,direction:v,isSelected:v===s,onSelect:function(){function h(){return c("select_direction",{direction:v})}return h}()})},v)})},d)})})})})]})})})}return I}()},53424:function(T,r,n){"use strict";r.__esModule=!0,r.GPS=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),f=n(98595),b=function(i){return i?"("+i.join(", ")+")":"ERROR"},y=function(i,u){if(!(!i||!u)){if(i[2]!==u[2])return null;var s=Math.atan2(u[1]-i[1],u[0]-i[0]),d=Math.sqrt(Math.pow(u[1]-i[1],2)+Math.pow(u[0]-i[0],2));return{angle:(0,a.rad2deg)(s),distance:d}}},I=r.GPS=function(){function m(i,u){var s=(0,t.useBackend)(u),d=s.data,v=d.emped,h=d.active,C=d.area,p=d.position,N=d.saved;return(0,e.createComponentVNode)(2,f.Window,{width:400,height:600,children:(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:v?(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,basis:"0",children:(0,e.createComponentVNode)(2,k,{emp:!0})}):(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,g)}),h?(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,l,{area:C,position:p})}),N&&(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,l,{title:"Saved Position",position:N})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,basis:"0",children:(0,e.createComponentVNode)(2,c,{height:"100%"})})],0):(0,e.createComponentVNode)(2,k)],0)})})})}return m}(),k=function(i,u){var s=i.emp;return(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:(0,e.createComponentVNode)(2,o.Box,{width:"100%",height:"100%",color:"label",textAlign:"center",children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,o.Icon,{name:s?"ban":"power-off",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),s?"ERROR: Device temporarily lost signal.":"Device is disabled."]})})})})},g=function(i,u){var s=(0,t.useBackend)(u),d=s.act,v=s.data,h=v.active,C=v.tag,p=v.same_z,N=(0,t.useLocalState)(u,"newTag",C),V=N[0],S=N[1];return(0,e.createComponentVNode)(2,o.Section,{title:"Settings",buttons:(0,e.createComponentVNode)(2,o.Button,{selected:h,icon:h?"toggle-on":"toggle-off",content:h?"On":"Off",onClick:function(){function B(){return d("toggle")}return B}()}),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Tag",children:[(0,e.createComponentVNode)(2,o.Input,{width:"5rem",value:C,onEnter:function(){function B(){return d("tag",{newtag:V})}return B}(),onInput:function(){function B(L,w){return S(w)}return B}()}),(0,e.createComponentVNode)(2,o.Button,{disabled:C===V,width:"20px",mb:"0",ml:"0.25rem",onClick:function(){function B(){return d("tag",{newtag:V})}return B}(),children:(0,e.createComponentVNode)(2,o.Icon,{name:"pen"})})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Range",children:(0,e.createComponentVNode)(2,o.Button,{selected:!p,icon:p?"compress":"expand",content:p?"Local Sector":"Global",onClick:function(){function B(){return d("same_z")}return B}()})})]})})},l=function(i,u){var s=i.title,d=i.area,v=i.position;return(0,e.createComponentVNode)(2,o.Section,{title:s||"Position",children:(0,e.createComponentVNode)(2,o.Box,{fontSize:"1.5rem",children:[d&&(0,e.createFragment)([d,(0,e.createVNode)(1,"br")],0),b(v)]})})},c=function(i,u){var s=(0,t.useBackend)(u),d=s.data,v=d.position,h=d.signals;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({fill:!0,scrollable:!0,title:"Signals"},i,{children:(0,e.createComponentVNode)(2,o.Table,{children:h.map(function(C){return Object.assign({},C,y(v,C.position))}).map(function(C,p){return(0,e.createComponentVNode)(2,o.Table.Row,{backgroundColor:p%2===0&&"rgba(255, 255, 255, 0.05)",children:[(0,e.createComponentVNode)(2,o.Table.Cell,{width:"30%",verticalAlign:"middle",color:"label",p:"0.25rem",bold:!0,children:C.tag}),(0,e.createComponentVNode)(2,o.Table.Cell,{verticalAlign:"middle",color:"grey",children:C.area}),(0,e.createComponentVNode)(2,o.Table.Cell,{verticalAlign:"middle",collapsing:!0,children:C.distance!==void 0&&(0,e.createComponentVNode)(2,o.Box,{opacity:Math.max(1-Math.min(C.distance,100)/100,.5),children:[(0,e.createComponentVNode)(2,o.Icon,{name:C.distance>0?"arrow-right":"circle",rotation:-C.angle}),"\xA0",Math.floor(C.distance)+"m"]})}),(0,e.createComponentVNode)(2,o.Table.Cell,{verticalAlign:"middle",pr:"0.25rem",collapsing:!0,children:b(C.position)})]},p)})})})))}},89124:function(T,r,n){"use strict";r.__esModule=!0,r.GeneModder=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(3939),f=n(98595),b=r.GeneModder=function(){function u(s,d){var v=(0,a.useBackend)(d),h=v.data,C=h.has_seed;return(0,e.createComponentVNode)(2,f.Window,{width:950,height:650,children:[(0,e.createVNode)(1,"div","GeneModder__left",(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,i,{scrollable:!0})}),2),(0,e.createVNode)(1,"div","GeneModder__right",(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,scrollable:!0,children:[(0,e.createComponentVNode)(2,k),(0,e.createComponentVNode)(2,o.ComplexModal,{maxWidth:"75%",maxHeight:"75%"}),C===0?(0,e.createComponentVNode)(2,I):(0,e.createComponentVNode)(2,y)]})}),2)]})}return u}(),y=function(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=C.disk;return(0,e.createComponentVNode)(2,t.Section,{title:"Genes",fill:!0,scrollable:!0,children:[(0,e.createComponentVNode)(2,g),(0,e.createComponentVNode)(2,l),(0,e.createComponentVNode)(2,c)]})},I=function(s,d){return(0,e.createComponentVNode)(2,t.Section,{fill:!0,height:"85%",children:(0,e.createComponentVNode)(2,t.Stack,{height:"100%",children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:"1",textAlign:"center",align:"center",color:"green",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"leaf",size:5,mb:"10px"}),(0,e.createVNode)(1,"br"),"The plant DNA manipulator is missing a seed."]})})})},k=function(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=C.has_seed,N=C.seed,V=C.has_disk,S=C.disk,B,L;return p?B=(0,e.createComponentVNode)(2,t.Stack.Item,{mb:"-6px",mt:"-4px",children:[(0,e.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+N.image,style:{"vertical-align":"middle",width:"32px",margin:"-1px","margin-left":"-11px"}}),(0,e.createComponentVNode)(2,t.Button,{content:N.name,onClick:function(){function w(){return h("eject_seed")}return w}()}),(0,e.createComponentVNode)(2,t.Button,{ml:"3px",icon:"pen",tooltip:"Name Variant",onClick:function(){function w(){return h("variant_name")}return w}()})]}):B=(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{ml:3.3,content:"None",onClick:function(){function w(){return h("eject_seed")}return w}()})}),V?L=S.name:L="None",(0,e.createComponentVNode)(2,t.Section,{title:"Storage",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Plant Sample",children:B}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Data Disk",children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{ml:3.3,content:L,tooltip:"Select Empty Disk",onClick:function(){function w(){return h("select_empty_disk")}return w}()})})})]})})},g=function(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=C.disk,N=C.core_genes;return(0,e.createComponentVNode)(2,t.Collapsible,{title:"Core Genes",open:!0,children:[N.map(function(V){return(0,e.createComponentVNode)(2,t.Stack,{py:"2px",className:"candystripe",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"100%",ml:"2px",children:V.name}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Extract",disabled:!(p!=null&&p.can_extract),icon:"save",onClick:function(){function S(){return h("extract",{id:V.id})}return S}()})})]},V)})," ",(0,e.createComponentVNode)(2,t.Stack,{children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Extract All",disabled:!(p!=null&&p.can_extract),icon:"save",onClick:function(){function V(){return h("bulk_extract_core")}return V}()})})})]},"Core Genes")},l=function(s,d){var v=(0,a.useBackend)(d),h=v.data,C=h.reagent_genes,p=h.has_reagent;return(0,e.createComponentVNode)(2,m,{title:"Reagent Genes",gene_set:C,do_we_show:p})},c=function(s,d){var v=(0,a.useBackend)(d),h=v.data,C=h.trait_genes,p=h.has_trait;return(0,e.createComponentVNode)(2,m,{title:"Trait Genes",gene_set:C,do_we_show:p})},m=function(s,d){var v=s.title,h=s.gene_set,C=s.do_we_show,p=(0,a.useBackend)(d),N=p.act,V=p.data,S=V.disk;return(0,e.createComponentVNode)(2,t.Collapsible,{title:v,open:!0,children:C?h.map(function(B){return(0,e.createComponentVNode)(2,t.Stack,{py:"2px",className:"candystripe",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"100%",ml:"2px",children:B.name}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Extract",disabled:!(S!=null&&S.can_extract),icon:"save",onClick:function(){function L(){return N("extract",{id:B.id})}return L}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Remove",icon:"times",onClick:function(){function L(){return N("remove",{id:B.id})}return L}()})})]},B)}):(0,e.createComponentVNode)(2,t.Stack.Item,{children:"No Genes Detected"})},v)},i=function(s,d){var v=s.title,h=s.gene_set,C=s.do_we_show,p=(0,a.useBackend)(d),N=p.act,V=p.data,S=V.has_seed,B=V.empty_disks,L=V.stat_disks,w=V.trait_disks,A=V.reagent_disks;return(0,e.createComponentVNode)(2,t.Section,{title:"Disks",children:[(0,e.createVNode)(1,"br"),"Empty Disks: ",B,(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{width:12,icon:"arrow-down",tooltip:"Eject an Empty disk",content:"Eject Empty Disk",onClick:function(){function x(){return N("eject_empty_disk")}return x}()}),(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Stats",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,scrollable:!0,children:[L.slice().sort(function(x,E){return x.display_name.localeCompare(E.display_name)}).map(function(x){return(0,e.createComponentVNode)(2,t.Stack,{mr:2,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"49%",children:x.display_name}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:25,children:[x.stat==="All"?(0,e.createComponentVNode)(2,t.Button,{content:"Replace All",tooltip:"Write disk stats to seed",disabled:!(x!=null&&x.ready)||!S,icon:"arrow-circle-down",onClick:function(){function E(){return N("bulk_replace_core",{index:x.index})}return E}()}):(0,e.createComponentVNode)(2,t.Button,{width:6,icon:"arrow-circle-down",tooltip:"Write disk stat to seed",disabled:!x||!S,content:"Replace",onClick:function(){function E(){return N("replace",{index:x.index,stat:x.stat})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:6,icon:"arrow-right",content:"Select",tooltip:"Choose as target for extracted genes",tooltipPosition:"bottom-start",onClick:function(){function E(){return N("select",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:5,icon:"arrow-down",content:"Eject",tooltip:"Eject Disk",tooltipPosition:"bottom-start",onClick:function(){function E(){return N("eject_disk",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:2,icon:x.read_only?"lock":"lock-open",content:"",tool_tip:"Set/unset Read Only",onClick:function(){function E(){return N("set_read_only",{index:x.index,read_only:x.read_only})}return E}()})]})]},x)}),(0,e.createComponentVNode)(2,t.Button)]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Traits",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,scrollable:!0,children:[w.slice().sort(function(x,E){return x.display_name.localeCompare(E.display_name)}).map(function(x){return(0,e.createComponentVNode)(2,t.Stack,{mr:2,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"49%",children:x.display_name}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:25,children:[(0,e.createComponentVNode)(2,t.Button,{width:6,icon:"arrow-circle-down",disabled:!x||!x.can_insert,tooltip:"Add disk trait to seed",content:"Insert",onClick:function(){function E(){return N("insert",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:6,icon:"arrow-right",content:"Select",tooltip:"Choose as target for extracted genes",tooltipPosition:"bottom-start",onClick:function(){function E(){return N("select",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:5,icon:"arrow-down",content:"Eject",tooltip:"Eject Disk",tooltipPosition:"bottom-start",onClick:function(){function E(){return N("eject_disk",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:2,icon:x.read_only?"lock":"lock-open",content:"",tool_tip:"Set/unset Read Only",onClick:function(){function E(){return N("set_read_only",{index:x.index,read_only:x.read_only})}return E}()})]})]},x)}),(0,e.createComponentVNode)(2,t.Button)]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Reagents",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,scrollable:!0,children:[A.slice().sort(function(x,E){return x.display_name.localeCompare(E.display_name)}).map(function(x){return(0,e.createComponentVNode)(2,t.Stack,{mr:2,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"49%",children:x.display_name}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:25,children:[(0,e.createComponentVNode)(2,t.Button,{width:6,icon:"arrow-circle-down",disabled:!x||!x.can_insert,tooltip:"Add disk reagent to seed",content:"Insert",onClick:function(){function E(){return N("insert",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:6,icon:"arrow-right",content:"Select",tooltip:"Choose as target for extracted genes",tooltipPosition:"bottom-start",onClick:function(){function E(){return N("select",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:5,icon:"arrow-down",content:"Eject",tooltip:"Eject Disk",tooltipPosition:"bottom-start",onClick:function(){function E(){return N("eject_disk",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:2,icon:x.read_only?"lock":"lock-open",content:"",tool_tip:"Set/unset Read Only",onClick:function(){function E(){return N("set_read_only",{index:x.index,read_only:x.read_only})}return E}()})]})]},x)}),(0,e.createComponentVNode)(2,t.Button)]})})]})]})}},73053:function(T,r,n){"use strict";r.__esModule=!0,r.GenericCrewManifest=void 0;var e=n(89005),a=n(36036),t=n(98595),o=n(41874),f=r.GenericCrewManifest=function(){function b(y,I){return(0,e.createComponentVNode)(2,t.Window,{theme:"nologo",width:588,height:510,children:(0,e.createComponentVNode)(2,t.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,a.Section,{noTopPadding:!0,children:(0,e.createComponentVNode)(2,o.CrewManifest)})})})}return b}()},42914:function(T,r,n){"use strict";r.__esModule=!0,r.GhostHudPanel=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.GhostHudPanel=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.data,c=l.security,m=l.medical,i=l.diagnostic,u=l.pressure,s=l.radioactivity,d=l.ahud;return(0,e.createComponentVNode)(2,o.Window,{width:250,height:217,theme:"nologo",children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,b,{label:"Medical",type:"medical",is_active:m}),(0,e.createComponentVNode)(2,b,{label:"Security",type:"security",is_active:c}),(0,e.createComponentVNode)(2,b,{label:"Diagnostic",type:"diagnostic",is_active:i}),(0,e.createComponentVNode)(2,b,{label:"Pressure",type:"pressure",is_active:u}),(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,b,{label:"Radioactivity",type:"radioactivity",is_active:s,act_on:"rads_on",act_off:"rads_off"}),(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,b,{label:"Antag HUD",is_active:d,act_on:"ahud_on",act_off:"ahud_off"})]})})})}return y}(),b=function(I,k){var g=(0,a.useBackend)(k),l=g.act,c=I.label,m=I.type,i=m===void 0?null:m,u=I.is_active,s=I.act_on,d=s===void 0?"hud_on":s,v=I.act_off,h=v===void 0?"hud_off":v;return(0,e.createComponentVNode)(2,t.Flex,{pt:.3,color:"label",children:[(0,e.createComponentVNode)(2,t.Flex.Item,{pl:.5,align:"center",width:"80%",children:c}),(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,t.Button,{mr:.6,content:u?"On":"Off",icon:u?"toggle-on":"toggle-off",selected:u,onClick:function(){function C(){return l(u?h:d,{hud_type:i})}return C}()})})]})}},25825:function(T,r,n){"use strict";r.__esModule=!0,r.GlandDispenser=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.GlandDispenser=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.glands,m=c===void 0?[]:c;return(0,e.createComponentVNode)(2,o.Window,{width:300,height:338,theme:"abductor",children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:m.map(function(i){return(0,e.createComponentVNode)(2,t.Button,{width:"60px",height:"60px",m:.75,textAlign:"center",fontSize:"17px",lineHeight:"55px",icon:"eject",backgroundColor:i.color,content:i.amount||"0",disabled:!i.amount,onClick:function(){function u(){return g("dispense",{gland_id:i.id})}return u}()},i.id)})})})})}return b}()},10270:function(T,r,n){"use strict";r.__esModule=!0,r.GravityGen=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.GravityGen=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.charging_state,m=l.charge_count,i=l.breaker,u=l.ext_power,s=function(){function v(h){return h>0?(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:"average",children:["[ ",h===1?"Charging":"Discharging"," ]"]}):(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:u?"good":"bad",children:["[ ",u?"Powered":"Unpowered"," ]"]})}return v}(),d=function(){function v(h){if(h>0)return(0,e.createComponentVNode)(2,t.NoticeBox,{danger:!0,p:1.5,children:[(0,e.createVNode)(1,"b",null,"WARNING:",16)," Radiation Detected!"]})}return v}();return(0,e.createComponentVNode)(2,o.Window,{width:350,height:170,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[d(c),(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Generator Status",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:i?"power-off":"times",content:i?"Online":"Offline",color:i?"green":"red",px:1.5,onClick:function(){function v(){return g("breaker")}return v}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power Status",color:u?"good":"bad",children:s(c)}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Gravity Charge",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:m/100,ranges:{good:[.9,1/0],average:[.5,.9],bad:[-1/0,.5]}})})]})})]})})})}return b}()},48657:function(T,r,n){"use strict";r.__esModule=!0,r.GuestPass=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(49148),b=r.GuestPass=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:690,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"id-card",selected:!c.showlogs,onClick:function(){function m(){return l("mode",{mode:0})}return m}(),children:"Issue Pass"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"scroll",selected:c.showlogs,onClick:function(){function m(){return l("mode",{mode:1})}return m}(),children:["Records (",c.issue_log.length,")"]})]})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Authorization",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"ID Card",children:(0,e.createComponentVNode)(2,t.Button,{icon:c.scan_name?"eject":"id-card",selected:c.scan_name,content:c.scan_name?c.scan_name:"-----",tooltip:c.scan_name?"Eject ID":"Insert ID",onClick:function(){function m(){return l("scan")}return m}()})})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:!c.showlogs&&(0,e.createComponentVNode)(2,t.Section,{title:"Issue Guest Pass",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Issue To",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:c.giv_name?c.giv_name:"-----",disabled:!c.scan_name,onClick:function(){function m(){return l("giv_name")}return m}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Reason",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:c.reason?c.reason:"-----",disabled:!c.scan_name,onClick:function(){function m(){return l("reason")}return m}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Duration",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:c.duration?c.duration:"-----",disabled:!c.scan_name,onClick:function(){function m(){return l("duration")}return m}()})})]})})}),!c.showlogs&&(c.scan_name?(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,f.AccessList,{sectionButtons:(0,e.createComponentVNode)(2,t.Button,{icon:"id-card",content:c.printmsg,disabled:!c.canprint,onClick:function(){function m(){return l("issue")}return m}()}),grantableList:c.grantableList,accesses:c.regions,selectedList:c.selectedAccess,accessMod:function(){function m(i){return l("access",{access:i})}return m}(),grantAll:function(){function m(){return l("grant_all")}return m}(),denyAll:function(){function m(){return l("clear_all")}return m}(),grantDep:function(){function m(i){return l("grant_region",{region:i})}return m}(),denyDep:function(){function m(i){return l("deny_region",{region:i})}return m}()})}):(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,fontSize:1.5,textAlign:"center",align:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"id-card",size:5,color:"gray",mb:5}),(0,e.createVNode)(1,"br"),"Please, insert ID Card"]})})})})),!!c.showlogs&&(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,m:0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Issuance Log",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"print",content:"Print",disabled:!c.scan_name,onClick:function(){function m(){return l("print")}return m}()}),children:!!c.issue_log.length&&(0,e.createComponentVNode)(2,t.LabeledList,{children:c.issue_log.map(function(m,i){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{children:m},i)})})||(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,fontSize:1.5,textAlign:"center",align:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon.Stack,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"scroll",size:5,color:"gray"}),(0,e.createComponentVNode)(2,t.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"No logs"]})})})})]})})})}return y}()},67834:function(T,r,n){"use strict";r.__esModule=!0,r.HandheldChemDispenser=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=[1,5,10,20,30,50],b=null,y=r.HandheldChemDispenser=function(){function g(l,c){return(0,e.createComponentVNode)(2,o.Window,{width:390,height:430,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,I),(0,e.createComponentVNode)(2,k)]})})})}return g}(),I=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.amount,d=u.energy,v=u.maxEnergy,h=u.mode;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Settings",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Energy",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:d,minValue:0,maxValue:v,ranges:{good:[v*.5,1/0],average:[v*.25,v*.5],bad:[-1/0,v*.25]},children:[d," / ",v," Units"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Amount",verticalAlign:"middle",children:(0,e.createComponentVNode)(2,t.Stack,{children:f.map(function(C,p){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,width:"15%",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"cog",selected:s===C,content:C,onClick:function(){function N(){return i("amount",{amount:C})}return N}()})},p)})})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Mode",verticalAlign:"middle",children:(0,e.createComponentVNode)(2,t.Stack,{justify:"space-between",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"cog",selected:h==="dispense",content:"Dispense",m:"0",width:"32%",onClick:function(){function C(){return i("mode",{mode:"dispense"})}return C}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"cog",selected:h==="remove",content:"Remove",m:"0",width:"32%",onClick:function(){function C(){return i("mode",{mode:"remove"})}return C}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"cog",selected:h==="isolate",content:"Isolate",m:"0",width:"32%",onClick:function(){function C(){return i("mode",{mode:"isolate"})}return C}()})]})})]})})})},k=function(l,c){for(var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.chemicals,d=s===void 0?[]:s,v=u.current_reagent,h=[],C=0;C<(d.length+1)%3;C++)h.push(!0);return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,height:"18%",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:u.glass?"Drink Selector":"Chemical Selector",children:[d.map(function(p,N){return(0,e.createComponentVNode)(2,t.Button,{width:"32%",icon:"arrow-circle-down",overflow:"hidden",textOverflow:"ellipsis",selected:v===p.id,content:p.title,style:{"margin-left":"2px"},onClick:function(){function V(){return i("dispense",{reagent:p.id})}return V}()},N)}),h.map(function(p,N){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:"1",basis:"25%"},N)})]})})}},46098:function(T,r,n){"use strict";r.__esModule=!0,r.HealthSensor=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),f=n(98595),b=r.HealthSensor=function(){function I(k,g){var l=(0,t.useBackend)(g),c=l.act,m=l.data,i=m.on,u=m.user_health,s=m.minHealth,d=m.maxHealth,v=m.alarm_health;return(0,e.createComponentVNode)(2,f.Window,{width:300,height:125,children:(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Scanning",children:(0,e.createComponentVNode)(2,o.Button,{icon:"power-off",content:i?"On":"Off",color:i?null:"red",selected:i,onClick:function(){function h(){return c("scan_toggle")}return h}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Health activation",children:(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,step:2,stepPixelSize:6,minValue:s,maxValue:d,value:v,format:function(){function h(C){return(0,a.toFixed)(C,1)}return h}(),width:"80px",onDrag:function(){function h(C,p){return c("alarm_health",{alarm_health:p})}return h}()})}),u!==null&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"User health",children:(0,e.createComponentVNode)(2,o.Box,{color:y(u),bold:u>=100,children:(0,e.createComponentVNode)(2,o.AnimatedNumber,{value:u})})})]})})})})}return I}(),y=function(k){return k>50?"green":k>0?"orange":"red"}},36771:function(T,r,n){"use strict";r.__esModule=!0,r.Holodeck=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.Holodeck=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=(0,a.useLocalState)(k,"currentDeck",""),i=m[0],u=m[1],s=(0,a.useLocalState)(k,"showReload",!1),d=s[0],v=s[1],h=c.decks,C=c.ai_override,p=c.emagged,N=function(){function V(S){l("select_deck",{deck:S}),u(S),v(!0),setTimeout(function(){v(!1)},3e3)}return V}();return(0,e.createComponentVNode)(2,o.Window,{width:400,height:320,children:[d&&(0,e.createComponentVNode)(2,b),(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Holodeck Control System",children:(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createVNode)(1,"b",null,"Currently Loaded Program:",16)," ",i]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Available Programs",children:[h.map(function(V){return(0,e.createComponentVNode)(2,t.Button,{width:15.5,color:"transparent",content:V,selected:V===i,onClick:function(){function S(){return N(V)}return S}()},V)}),(0,e.createVNode)(1,"hr",null,null,1,{color:"gray"}),(0,e.createComponentVNode)(2,t.LabeledList,{children:[!!C&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Override Protocols",children:(0,e.createComponentVNode)(2,t.Button,{content:p?"Turn On":"Turn Off",color:p?"good":"bad",onClick:function(){function V(){return l("ai_override")}return V}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Safety Protocols",children:(0,e.createComponentVNode)(2,t.Box,{color:p?"bad":"good",children:[p?"Off":"On",!!p&&(0,e.createComponentVNode)(2,t.Button,{ml:9.5,width:15.5,color:"red",content:"Wildlife Simulation",onClick:function(){function V(){return l("wildlifecarp")}return V}()})]})})]})]})})]})})]})}return y}(),b=function(I,k){return(0,e.createComponentVNode)(2,t.Dimmer,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"spinner",size:"5",spin:!0}),(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Box,{color:"white",children:(0,e.createVNode)(1,"h1",null,"\xA0Recalibrating projection apparatus.\xA0",16)}),(0,e.createComponentVNode)(2,t.Box,{color:"label",children:(0,e.createVNode)(1,"h3",null,"Please, wait for 3 seconds.",16)})]})}},25471:function(T,r,n){"use strict";r.__esModule=!0,r.Instrument=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),f=n(98595),b=r.Instrument=function(){function l(c,m){var i=(0,t.useBackend)(m),u=i.act,s=i.data;return(0,e.createComponentVNode)(2,f.Window,{width:600,height:505,children:[(0,e.createComponentVNode)(2,y),(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,I),(0,e.createComponentVNode)(2,g)]})})]})}return l}(),y=function(c,m){var i=(0,t.useBackend)(m),u=i.act,s=i.data,d=s.help;if(d)return(0,e.createComponentVNode)(2,o.Modal,{maxWidth:"75%",height:window.innerHeight*.75+"px",mx:"auto",py:"0",px:"0.5rem",children:(0,e.createComponentVNode)(2,o.Section,{height:"100%",title:"Help",level:"2",overflow:"auto",children:(0,e.createComponentVNode)(2,o.Box,{px:"0.5rem",mt:"-0.5rem",children:[(0,e.createVNode)(1,"h1",null,"Making a Song",16),(0,e.createVNode)(1,"p",null,[(0,e.createTextVNode)("Lines are a series of chords, separated by commas\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"(,)"}),(0,e.createTextVNode)(", each with notes separated by hyphens\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"(-)"}),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Every note in a chord will play together, with the chord timed by the\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"tempo"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("as defined above.")],0),(0,e.createVNode)(1,"p",null,[(0,e.createTextVNode)("Notes are played by the\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"good",children:"names of the note"}),(0,e.createTextVNode)(", and optionally, the\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"accidental"}),(0,e.createTextVNode)(", and/or the"),(0,e.createTextVNode)(" "),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"bad",children:"octave number"}),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("By default, every note is\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"natural"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("and in\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"bad",children:"octave 3"}),(0,e.createTextVNode)(". Defining a different state for either is remembered for each"),(0,e.createTextVNode)(" "),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"good",children:"note"}),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"ul",null,[(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"Example:"}),(0,e.createTextVNode)("\xA0"),(0,e.createVNode)(1,"i",null,"C,D,E,F,G,A,B",16),(0,e.createTextVNode)(" will play a\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"good",children:"C"}),(0,e.createTextVNode)("\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"major"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("scale.")],0),(0,e.createVNode)(1,"li",null,[(0,e.createTextVNode)("After a note has an\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"accidental"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("or\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"bad",children:"octave"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("placed, it will be remembered:\xA0"),(0,e.createVNode)(1,"i",null,"C,C4,C#,C3",16),(0,e.createTextVNode)(" is "),(0,e.createVNode)(1,"i",null,"C3,C4,C4#,C3#",16)],0)],4)],0),(0,e.createVNode)(1,"p",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"Chords"}),(0,e.createTextVNode)("\xA0can be played simply by seperating each note with a hyphen: "),(0,e.createVNode)(1,"i",null,"A-C#,Cn-E,E-G#,Gn-B",16),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("A"),(0,e.createTextVNode)(" "),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"pause"}),(0,e.createTextVNode)("\xA0may be denoted by an empty chord: "),(0,e.createVNode)(1,"i",null,"C,E,,C,G",16),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("To make a chord be a different time, end it with /x, where the chord length will be length defined by\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"tempo / x"}),(0,e.createTextVNode)(",\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"eg:"}),(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"i",null,"C,G/2,E/4",16),(0,e.createTextVNode)(".")],0),(0,e.createVNode)(1,"p",null,[(0,e.createTextVNode)("Combined, an example line is: "),(0,e.createVNode)(1,"i",null,"E-E4/4,F#/2,G#/8,B/8,E3-E4/4",16),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"ul",null,[(0,e.createVNode)(1,"li",null,"Lines may be up to 300 characters.",16),(0,e.createVNode)(1,"li",null,"A song may only contain up to 1,000 lines.",16)],4)],4),(0,e.createVNode)(1,"p",null,[(0,e.createTextVNode)("Lines are a series of chords, separated by commas\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"(,)"}),(0,e.createTextVNode)(", each with notes separated by hyphens\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"(-)"}),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Every note in a chord will play together, with the chord timed by the\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"tempo"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("as defined above.")],0),(0,e.createVNode)(1,"p",null,[(0,e.createTextVNode)("Notes are played by the\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"good",children:"names of the note"}),(0,e.createTextVNode)(", and optionally, the\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"accidental"}),(0,e.createTextVNode)(", and/or the"),(0,e.createTextVNode)(" "),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"bad",children:"octave number"}),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("By default, every note is\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"natural"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("and in\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"bad",children:"octave 3"}),(0,e.createTextVNode)(". Defining a different state for either is remembered for each"),(0,e.createTextVNode)(" "),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"good",children:"note"}),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"ul",null,[(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"Example:"}),(0,e.createTextVNode)("\xA0"),(0,e.createVNode)(1,"i",null,"C,D,E,F,G,A,B",16),(0,e.createTextVNode)(" will play a\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"good",children:"C"}),(0,e.createTextVNode)("\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"major"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("scale.")],0),(0,e.createVNode)(1,"li",null,[(0,e.createTextVNode)("After a note has an\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"accidental"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("or\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"bad",children:"octave"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("placed, it will be remembered:\xA0"),(0,e.createVNode)(1,"i",null,"C,C4,C#,C3",16),(0,e.createTextVNode)(" is "),(0,e.createVNode)(1,"i",null,"C3,C4,C4#,C3#",16)],0)],4)],0),(0,e.createVNode)(1,"p",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"Chords"}),(0,e.createTextVNode)("\xA0can be played simply by seperating each note with a hyphen: "),(0,e.createVNode)(1,"i",null,"A-C#,Cn-E,E-G#,Gn-B",16),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("A"),(0,e.createTextVNode)(" "),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"pause"}),(0,e.createTextVNode)("\xA0may be denoted by an empty chord: "),(0,e.createVNode)(1,"i",null,"C,E,,C,G",16),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("To make a chord be a different time, end it with /x, where the chord length will be length defined by\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"tempo / x"}),(0,e.createTextVNode)(",\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"eg:"}),(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"i",null,"C,G/2,E/4",16),(0,e.createTextVNode)(".")],0),(0,e.createVNode)(1,"p",null,[(0,e.createTextVNode)("Combined, an example line is: "),(0,e.createVNode)(1,"i",null,"E-E4/4,F#/2,G#/8,B/8,E3-E4/4",16),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"ul",null,[(0,e.createVNode)(1,"li",null,"Lines may be up to 300 characters.",16),(0,e.createVNode)(1,"li",null,"A song may only contain up to 1,000 lines.",16)],4)],4),(0,e.createVNode)(1,"h1",null,"Instrument Advanced Settings",16),(0,e.createVNode)(1,"ul",null,[(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:"Type:"}),(0,e.createTextVNode)("\xA0Whether the instrument is legacy or synthesized."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Legacy instruments have a collection of sounds that are selectively used depending on the note to play."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Synthesized instruments use a base sound and change its pitch to match the note to play.")],4),(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:"Current:"}),(0,e.createTextVNode)("\xA0Which instrument sample to play. Some instruments can be tuned to play different samples. Experiment!")],4),(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:"Note Shift/Note Transpose:"}),(0,e.createTextVNode)("\xA0The pitch to apply to all notes of the song.")],4),(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:"Sustain Mode:"}),(0,e.createTextVNode)("\xA0How a played note fades out."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Linear sustain means a note will fade out at a constant rate."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Exponential sustain means a note will fade out at an exponential rate, sounding smoother.")],4),(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:"Volume Dropoff Threshold:"}),(0,e.createTextVNode)("\xA0The volume threshold at which a note is fully stopped.")],4),(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:"Sustain indefinitely last held note:"}),(0,e.createTextVNode)("\xA0Whether the last note should be sustained indefinitely.")],4)],4),(0,e.createComponentVNode)(2,o.Button,{color:"grey",content:"Close",onClick:function(){function v(){return u("help")}return v}()})]})})})},I=function(c,m){var i=(0,t.useBackend)(m),u=i.act,s=i.data,d=s.lines,v=s.playing,h=s.repeat,C=s.maxRepeats,p=s.tempo,N=s.minTempo,V=s.maxTempo,S=s.tickLag,B=s.volume,L=s.minVolume,w=s.maxVolume,A=s.ready;return(0,e.createComponentVNode)(2,o.Section,{title:"Instrument",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{icon:"info",content:"Help",onClick:function(){function x(){return u("help")}return x}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"file",content:"New",onClick:function(){function x(){return u("newsong")}return x}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"upload",content:"Import",onClick:function(){function x(){return u("import")}return x}()})],4),children:[(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Playback",children:[(0,e.createComponentVNode)(2,o.Button,{selected:v,disabled:d.length===0||h<0,icon:"play",content:"Play",onClick:function(){function x(){return u("play")}return x}()}),(0,e.createComponentVNode)(2,o.Button,{disabled:!v,icon:"stop",content:"Stop",onClick:function(){function x(){return u("stop")}return x}()})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Repeat",children:(0,e.createComponentVNode)(2,o.Slider,{animated:!0,minValue:0,maxValue:C,value:h,stepPixelSize:59,onChange:function(){function x(E,P){return u("repeat",{new:P})}return x}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Tempo",children:(0,e.createComponentVNode)(2,o.Box,{children:[(0,e.createComponentVNode)(2,o.Button,{disabled:p>=V,content:"-",as:"span",mr:"0.5rem",onClick:function(){function x(){return u("tempo",{new:p+S})}return x}()}),(0,a.round)(600/p)," BPM",(0,e.createComponentVNode)(2,o.Button,{disabled:p<=N,content:"+",as:"span",ml:"0.5rem",onClick:function(){function x(){return u("tempo",{new:p-S})}return x}()})]})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Volume",children:(0,e.createComponentVNode)(2,o.Slider,{animated:!0,minValue:L,maxValue:w,value:B,stepPixelSize:6,onDrag:function(){function x(E,P){return u("setvolume",{new:P})}return x}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Status",children:A?(0,e.createComponentVNode)(2,o.Box,{color:"good",children:"Ready"}):(0,e.createComponentVNode)(2,o.Box,{color:"bad",children:"Instrument Definition Error!"})})]}),(0,e.createComponentVNode)(2,k)]})},k=function(c,m){var i=(0,t.useBackend)(m),u=i.act,s=i.data,d=s.allowedInstrumentNames,v=s.instrumentLoaded,h=s.instrument,C=s.canNoteShift,p=s.noteShift,N=s.noteShiftMin,V=s.noteShiftMax,S=s.sustainMode,B=s.sustainLinearDuration,L=s.sustainExponentialDropoff,w=s.legacy,A=s.sustainDropoffVolume,x=s.sustainHeldNote,E,P;return S===1?(E="Linear",P=(0,e.createComponentVNode)(2,o.Slider,{minValue:.1,maxValue:5,value:B,step:.5,stepPixelSize:85,format:function(){function D(M){return(0,a.round)(M*100)/100+" seconds"}return D}(),onChange:function(){function D(M,R){return u("setlinearfalloff",{new:R/10})}return D}()})):S===2&&(E="Exponential",P=(0,e.createComponentVNode)(2,o.Slider,{minValue:1.025,maxValue:10,value:L,step:.01,format:function(){function D(M){return(0,a.round)(M*1e3)/1e3+"% per decisecond"}return D}(),onChange:function(){function D(M,R){return u("setexpfalloff",{new:R})}return D}()})),d.sort(),(0,e.createComponentVNode)(2,o.Box,{my:-1,children:(0,e.createComponentVNode)(2,o.Collapsible,{mt:"1rem",mb:"0",title:"Advanced",children:(0,e.createComponentVNode)(2,o.Section,{mt:-1,children:[(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Type",children:w?"Legacy":"Synthesized"}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Current",children:v?(0,e.createComponentVNode)(2,o.Dropdown,{options:d,selected:h,width:"50%",onSelected:function(){function D(M){return u("switchinstrument",{name:M})}return D}()}):(0,e.createComponentVNode)(2,o.Box,{color:"bad",children:"None!"})}),!!(!w&&C)&&(0,e.createFragment)([(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Note Shift/Note Transpose",children:(0,e.createComponentVNode)(2,o.Slider,{minValue:N,maxValue:V,value:p,stepPixelSize:2,format:function(){function D(M){return M+" keys / "+(0,a.round)(M/12*100)/100+" octaves"}return D}(),onChange:function(){function D(M,R){return u("setnoteshift",{new:R})}return D}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Sustain Mode",children:[(0,e.createComponentVNode)(2,o.Dropdown,{options:["Linear","Exponential"],selected:E,mb:"0.4rem",onSelected:function(){function D(M){return u("setsustainmode",{new:M})}return D}()}),P]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Volume Dropoff Threshold",children:(0,e.createComponentVNode)(2,o.Slider,{animated:!0,minValue:.01,maxValue:100,value:A,stepPixelSize:6,onChange:function(){function D(M,R){return u("setdropoffvolume",{new:R})}return D}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Sustain indefinitely last held note",children:(0,e.createComponentVNode)(2,o.Button,{selected:x,icon:x?"toggle-on":"toggle-off",content:x?"Yes":"No",onClick:function(){function D(){return u("togglesustainhold")}return D}()})})],4)]}),(0,e.createComponentVNode)(2,o.Button,{icon:"redo",content:"Reset to Default",mt:"0.5rem",onClick:function(){function D(){return u("reset")}return D}()})]})})})},g=function(c,m){var i=(0,t.useBackend)(m),u=i.act,s=i.data,d=s.playing,v=s.lines,h=s.editing;return(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Editor",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{disabled:!h||d,icon:"plus",content:"Add Line",onClick:function(){function C(){return u("newline",{line:v.length+1})}return C}()}),(0,e.createComponentVNode)(2,o.Button,{selected:!h,icon:h?"chevron-up":"chevron-down",onClick:function(){function C(){return u("edit")}return C}()})],4),children:!!h&&(v.length>0?(0,e.createComponentVNode)(2,o.LabeledList,{children:v.map(function(C,p){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:p+1,buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{disabled:d,icon:"pen",onClick:function(){function N(){return u("modifyline",{line:p+1})}return N}()}),(0,e.createComponentVNode)(2,o.Button,{disabled:d,icon:"trash",onClick:function(){function N(){return u("deleteline",{line:p+1})}return N}()})],4),children:C},p)})}):(0,e.createComponentVNode)(2,o.Box,{color:"label",children:"Song is empty."}))})}},13618:function(T,r,n){"use strict";r.__esModule=!0,r.KeyComboModal=void 0;var e=n(89005),a=n(70611),t=n(72253),o=n(36036),f=n(98595),b=n(19203),y=n(51057),I=function(i){return i.key!==a.KEY.Alt&&i.key!==a.KEY.Control&&i.key!==a.KEY.Shift&&i.key!==a.KEY.Escape},k={DEL:"Delete",DOWN:"South",END:"Southwest",HOME:"Northwest",INSERT:"Insert",LEFT:"West",PAGEDOWN:"Southeast",PAGEUP:"Northeast",RIGHT:"East",SPACEBAR:"Space",UP:"North"},g=3,l=function(i){var u="";if(i.altKey&&(u+="Alt"),i.ctrlKey&&(u+="Ctrl"),i.shiftKey&&!(i.keyCode>=48&&i.keyCode<=57)&&(u+="Shift"),i.location===g&&(u+="Numpad"),I(i))if(i.shiftKey&&i.keyCode>=48&&i.keyCode<=57){var s=i.keyCode-48;u+="Shift"+s}else{var d=i.key.toUpperCase();u+=k[d]||d}return u},c=r.KeyComboModal=function(){function m(i,u){var s=(0,t.useBackend)(u),d=s.act,v=s.data,h=v.init_value,C=v.large_buttons,p=v.message,N=p===void 0?"":p,V=v.title,S=v.timeout,B=(0,t.useLocalState)(u,"input",h),L=B[0],w=B[1],A=(0,t.useLocalState)(u,"binding",!0),x=A[0],E=A[1],P=function(){function R(O){if(!x){O.key===a.KEY.Enter&&d("submit",{entry:L}),(0,a.isEscape)(O.key)&&d("cancel");return}if(O.preventDefault(),I(O)){D(l(O)),E(!1);return}else if(O.key===a.KEY.Escape){D(h),E(!1);return}}return R}(),D=function(){function R(O){O!==L&&w(O)}return R}(),M=130+(N.length>30?Math.ceil(N.length/3):0)+(N.length&&C?5:0);return(0,e.createComponentVNode)(2,f.Window,{title:V,width:240,height:M,children:[S&&(0,e.createComponentVNode)(2,y.Loader,{value:S}),(0,e.createComponentVNode)(2,f.Window.Content,{onKeyDown:function(){function R(O){P(O)}return R}(),children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Autofocus),(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Box,{color:"label",children:N})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{disabled:x,content:x&&x!==null?"Awaiting input...":""+L,width:"100%",textAlign:"center",onClick:function(){function R(){D(h),E(!0)}return R}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,b.InputButtons,{input:L})})]})]})})]})}return m}()},35655:function(T,r,n){"use strict";r.__esModule=!0,r.KeycardAuth=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.KeycardAuth=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=(0,e.createComponentVNode)(2,t.Section,{title:"Keycard Authentication Device",children:(0,e.createComponentVNode)(2,t.Box,{children:"This device is used to trigger certain high security events. It requires the simultaneous swipe of two high-level ID cards."})});if(!l.swiping&&!l.busy)return(0,e.createComponentVNode)(2,o.Window,{width:540,height:280,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[c,(0,e.createComponentVNode)(2,t.Section,{title:"Choose Action",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Red Alert",children:(0,e.createComponentVNode)(2,t.Button,{icon:"exclamation-triangle",disabled:!l.redAvailable,onClick:function(){function i(){return g("triggerevent",{triggerevent:"Red Alert"})}return i}(),content:"Red Alert"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"ERT",children:(0,e.createComponentVNode)(2,t.Button,{icon:"broadcast-tower",onClick:function(){function i(){return g("triggerevent",{triggerevent:"Emergency Response Team"})}return i}(),content:"Call ERT"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Emergency Maint Access",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"door-open",onClick:function(){function i(){return g("triggerevent",{triggerevent:"Grant Emergency Maintenance Access"})}return i}(),content:"Grant"}),(0,e.createComponentVNode)(2,t.Button,{icon:"door-closed",onClick:function(){function i(){return g("triggerevent",{triggerevent:"Revoke Emergency Maintenance Access"})}return i}(),content:"Revoke"})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Emergency Station-Wide Access",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"door-open",onClick:function(){function i(){return g("triggerevent",{triggerevent:"Activate Station-Wide Emergency Access"})}return i}(),content:"Grant"}),(0,e.createComponentVNode)(2,t.Button,{icon:"door-closed",onClick:function(){function i(){return g("triggerevent",{triggerevent:"Deactivate Station-Wide Emergency Access"})}return i}(),content:"Revoke"})]})]})})]})});var m=(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Waiting for YOU to swipe your ID..."});return!l.hasSwiped&&!l.ertreason&&l.event==="Emergency Response Team"?m=(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Fill out the reason for your ERT request."}):l.hasConfirm?m=(0,e.createComponentVNode)(2,t.Box,{color:"green",children:"Request Confirmed!"}):l.isRemote?m=(0,e.createComponentVNode)(2,t.Box,{color:"orange",children:"Swipe your card to CONFIRM the remote request."}):l.hasSwiped&&(m=(0,e.createComponentVNode)(2,t.Box,{color:"orange",children:"Waiting for second person to confirm..."})),(0,e.createComponentVNode)(2,o.Window,{width:540,height:265,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[c,l.event==="Emergency Response Team"&&(0,e.createComponentVNode)(2,t.Section,{title:"Reason for ERT Call",children:(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{color:l.ertreason?"":"red",icon:l.ertreason?"check":"pencil-alt",content:l.ertreason?l.ertreason:"-----",disabled:l.busy,onClick:function(){function i(){return g("ert")}return i}()})})}),(0,e.createComponentVNode)(2,t.Section,{title:l.event,buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-left",content:"Back",disabled:l.busy||l.hasConfirm,onClick:function(){function i(){return g("reset")}return i}()}),children:m})]})})}return b}()},62955:function(T,r,n){"use strict";r.__esModule=!0,r.KitchenMachine=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(62411),b=r.KitchenMachine=function(){function I(k,g){var l=(0,a.useBackend)(g),c=l.data,m=l.config,i=c.ingredients,u=c.operating,s=m.title;return(0,e.createComponentVNode)(2,o.Window,{width:400,height:320,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,f.Operating,{operating:u,name:s}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,y)}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Ingredients",children:(0,e.createComponentVNode)(2,t.Table,{className:"Ingredient__Table",children:i.map(function(d){return(0,e.createComponentVNode)(2,t.Table.Row,{tr:5,children:[(0,e.createVNode)(1,"td",null,(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:d.name}),2),(0,e.createVNode)(1,"td",null,(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,textAlign:"center",children:[d.amount," ",d.units]}),2)]},d.name)})})})})]})})})}return I}(),y=function(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.inactive,u=m.tooltip;return(0,e.createComponentVNode)(2,t.Section,{title:"Controls",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"50%",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"power-off",disabled:i,tooltip:i?u:"",tooltipPosition:"bottom",content:"Activate",onClick:function(){function s(){return c("cook")}return s}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"50%",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"eject",disabled:i,tooltip:i?u:"",tooltipPosition:"bottom",content:"Eject Contents",onClick:function(){function s(){return c("eject")}return s}()})})]})})}},9525:function(T,r,n){"use strict";r.__esModule=!0,r.LawManager=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.LawManager=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.isAdmin,s=i.isSlaved,d=i.isMalf,v=i.isAIMalf,h=i.view;return(0,e.createComponentVNode)(2,o.Window,{width:800,height:d?620:365,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[!!(u&&s)&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:["This unit is slaved to ",s,"."]}),!!(d||v)&&(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Button,{content:"Law Management",selected:h===0,onClick:function(){function C(){return m("set_view",{set_view:0})}return C}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Lawsets",selected:h===1,onClick:function(){function C(){return m("set_view",{set_view:1})}return C}()})]}),h===0&&(0,e.createComponentVNode)(2,b),h===1&&(0,e.createComponentVNode)(2,y)]})})}return k}(),b=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.has_zeroth_laws,s=i.zeroth_laws,d=i.has_ion_laws,v=i.ion_laws,h=i.ion_law_nr,C=i.has_inherent_laws,p=i.inherent_laws,N=i.has_supplied_laws,V=i.supplied_laws,S=i.channels,B=i.channel,L=i.isMalf,w=i.isAdmin,A=i.zeroth_law,x=i.ion_law,E=i.inherent_law,P=i.supplied_law,D=i.supplied_law_position;return(0,e.createFragment)([!!u&&(0,e.createComponentVNode)(2,I,{title:"ERR_NULL_VALUE",laws:s,ctx:l}),!!d&&(0,e.createComponentVNode)(2,I,{title:h,laws:v,ctx:l}),!!C&&(0,e.createComponentVNode)(2,I,{title:"Inherent",laws:p,ctx:l}),!!N&&(0,e.createComponentVNode)(2,I,{title:"Supplied",laws:V,ctx:l}),(0,e.createComponentVNode)(2,t.Section,{title:"Statement Settings",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Statement Channel",children:S.map(function(M){return(0,e.createComponentVNode)(2,t.Button,{content:M.channel,selected:M.channel===B,onClick:function(){function R(){return m("law_channel",{law_channel:M.channel})}return R}()},M.channel)})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"State Laws",children:(0,e.createComponentVNode)(2,t.Button,{content:"State Laws",onClick:function(){function M(){return m("state_laws")}return M}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Law Notification",children:(0,e.createComponentVNode)(2,t.Button,{content:"Notify",onClick:function(){function M(){return m("notify_laws")}return M}()})})]})}),!!L&&(0,e.createComponentVNode)(2,t.Section,{title:"Add Laws",children:(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{width:"10%",children:"Type"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"60%",children:"Law"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"10%",children:"Index"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"20%",children:"Actions"})]}),!!(w&&!u)&&(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Zero"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:A}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"N/A"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button,{content:"Edit",icon:"pencil-alt",onClick:function(){function M(){return m("change_zeroth_law")}return M}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Add",icon:"plus",onClick:function(){function M(){return m("add_zeroth_law")}return M}()})]})]}),(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Ion"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:x}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"N/A"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button,{content:"Edit",icon:"pencil-alt",onClick:function(){function M(){return m("change_ion_law")}return M}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Add",icon:"plus",onClick:function(){function M(){return m("add_ion_law")}return M}()})]})]}),(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Inherent"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:E}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"N/A"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button,{content:"Edit",icon:"pencil-alt",onClick:function(){function M(){return m("change_inherent_law")}return M}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Add",icon:"plus",onClick:function(){function M(){return m("add_inherent_law")}return M}()})]})]}),(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Supplied"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:P}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:D,onClick:function(){function M(){return m("change_supplied_law_position")}return M}()})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button,{content:"Edit",icon:"pencil-alt",onClick:function(){function M(){return m("change_supplied_law")}return M}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Add",icon:"plus",onClick:function(){function M(){return m("add_supplied_law")}return M}()})]})]})]})})],0)},y=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.law_sets;return(0,e.createComponentVNode)(2,t.Box,{children:u.map(function(s){return(0,e.createComponentVNode)(2,t.Section,{title:s.name+" - "+s.header,buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Load Laws",icon:"download",onClick:function(){function d(){return m("transfer_laws",{transfer_laws:s.ref})}return d}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[s.laws.has_ion_laws>0&&s.laws.ion_laws.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:d.index,children:d.law},d.index)}),s.laws.has_zeroth_laws>0&&s.laws.zeroth_laws.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:d.index,children:d.law},d.index)}),s.laws.has_inherent_laws>0&&s.laws.inherent_laws.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:d.index,children:d.law},d.index)}),s.laws.has_supplied_laws>0&&s.laws.inherent_laws.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:d.index,children:d.law},d.index)})]})},s.name)})})},I=function(g,l){var c=(0,a.useBackend)(g.ctx),m=c.act,i=c.data,u=i.isMalf;return(0,e.createComponentVNode)(2,t.Section,{title:g.title+" Laws",children:(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{width:"10%",children:"Index"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"69%",children:"Law"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"21%",children:"State?"})]}),g.laws.map(function(s){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:s.index}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:s.law}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button,{content:s.state?"Yes":"No",selected:s.state,onClick:function(){function d(){return m("state_law",{ref:s.ref,state_law:s.state?0:1})}return d}()}),!!u&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:"Edit",icon:"pencil-alt",onClick:function(){function d(){return m("edit_law",{edit_law:s.ref})}return d}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Delete",icon:"trash",color:"red",onClick:function(){function d(){return m("delete_law",{delete_law:s.ref})}return d}()})],4)]})]},s.law)})]})})}},85066:function(T,r,n){"use strict";r.__esModule=!0,r.LibraryComputer=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(3939),b=r.LibraryComputer=function(){function h(C,p){return(0,e.createComponentVNode)(2,o.Window,{width:1050,height:600,children:[(0,e.createComponentVNode)(2,f.ComplexModal),(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,l),(0,e.createComponentVNode)(2,c)]})})]})}return h}(),y=function(C,p){var N=(0,a.useBackend)(p),V=N.act,S=N.data,B=C.args,L=S.user_ckey;return(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Title",children:B.title}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Author",children:B.author}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Summary",children:B.summary}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Rating",children:[B.rating,(0,e.createComponentVNode)(2,t.Icon,{name:"star",color:"yellow",verticalAlign:"top"})]}),!B.isProgrammatic&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Categories",children:B.categories.join(", ")})]}),(0,e.createVNode)(1,"br"),L===B.ckey&&(0,e.createComponentVNode)(2,t.Button,{content:"Delete Book",icon:"trash",color:"red",disabled:B.isProgrammatic,onClick:function(){function w(){return V("delete_book",{bookid:B.id,user_ckey:L})}return w}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Report Book",icon:"flag",color:"red",disabled:B.isProgrammatic,onClick:function(){function w(){return(0,f.modalOpen)(p,"report_book",{bookid:B.id})}return w}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Rate Book",icon:"star",color:"caution",disabled:B.isProgrammatic,onClick:function(){function w(){return(0,f.modalOpen)(p,"rate_info",{bookid:B.id})}return w}()})]})},I=function(C,p){var N=(0,a.useBackend)(p),V=N.act,S=N.data,B=C.args,L=S.selected_report,w=S.report_categories,A=S.user_ckey;return(0,e.createComponentVNode)(2,t.Section,{level:2,m:"-1rem",pb:"1.5rem",title:"Report this book for Rule Violations",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Title",children:B.title}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Reasons",children:(0,e.createComponentVNode)(2,t.Box,{children:w.map(function(x,E){return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:x.description,selected:x.category_id===L,onClick:function(){function P(){return V("set_report",{report_type:x.category_id})}return P}()}),(0,e.createVNode)(1,"br")],4,E)})})})]}),(0,e.createComponentVNode)(2,t.Button.Confirm,{bold:!0,icon:"paper-plane",content:"Submit Report",onClick:function(){function x(){return V("submit_report",{bookid:B.id,user_ckey:A})}return x}()})]})},k=function(C,p){var N=(0,a.useBackend)(p),V=N.act,S=N.data,B=S.selected_rating,L=Array(10).fill().map(function(w,A){return 1+A});return(0,e.createComponentVNode)(2,t.Stack,{children:[L.map(function(w,A){return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{bold:!0,icon:"star",color:B>=w?"caution":"default",onClick:function(){function x(){return V("set_rating",{rating_value:w})}return x}()})},A)}),(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,ml:2,fontSize:"150%",children:[B+"/10",(0,e.createComponentVNode)(2,t.Icon,{name:"star",color:"yellow",ml:.5,verticalAlign:"top"})]})]})},g=function(C,p){var N=(0,a.useBackend)(p),V=N.act,S=N.data,B=C.args,L=S.user_ckey;return(0,e.createComponentVNode)(2,t.Section,{level:2,m:"-1rem",pb:"1.5rem",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Title",children:B.title}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Author",children:B.author}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Rating",children:[B.current_rating?B.current_rating:0,(0,e.createComponentVNode)(2,t.Icon,{name:"star",color:"yellow",ml:.5,verticalAlign:"middle"})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Total Ratings",children:B.total_ratings?B.total_ratings:0})]}),(0,e.createComponentVNode)(2,k),(0,e.createComponentVNode)(2,t.Button.Confirm,{mt:2,content:"Submit",icon:"paper-plane",onClick:function(){function w(){return V("rate_book",{bookid:B.id,user_ckey:L})}return w}()})]})},l=function(C,p){var N=(0,a.useBackend)(p),V=N.data,S=(0,a.useLocalState)(p,"tabIndex",0),B=S[0],L=S[1],w=V.login_state;return(0,e.createComponentVNode)(2,t.Stack.Item,{mb:1,children:(0,e.createComponentVNode)(2,t.Tabs,{fluid:!0,textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:B===0,onClick:function(){function A(){return L(0)}return A}(),children:"Book Archives"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:B===1,onClick:function(){function A(){return L(1)}return A}(),children:"Corporate Literature"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:B===2,onClick:function(){function A(){return L(2)}return A}(),children:"Upload Book"}),w===1&&(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:B===3,onClick:function(){function A(){return L(3)}return A}(),children:"Patron Manager"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:B===4,onClick:function(){function A(){return L(4)}return A}(),children:"Inventory"})]})})},c=function(C,p){var N=(0,a.useLocalState)(p,"tabIndex",0),V=N[0];switch(V){case 0:return(0,e.createComponentVNode)(2,i);case 1:return(0,e.createComponentVNode)(2,u);case 2:return(0,e.createComponentVNode)(2,s);case 3:return(0,e.createComponentVNode)(2,d);case 4:return(0,e.createComponentVNode)(2,v);default:return"You are somehow on a tab that doesn't exist! Please let a coder know."}},m=function(C,p){var N=(0,a.useBackend)(p),V=N.act,S=N.data,B=S.searchcontent,L=S.book_categories,w=S.user_ckey,A=[];return L.map(function(x){return A[x.description]=x.category_id}),(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"35%",children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.2rem",m:".5em",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"edit",verticalAlign:"middle",size:1.5,mr:"1rem"}),"Search Inputs"]}),(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Title",children:(0,e.createComponentVNode)(2,t.Button,{textAlign:"left",icon:"pen",width:20,content:B.title||"Input Title",onClick:function(){function x(){return(0,f.modalOpen)(p,"edit_search_title")}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Author",children:(0,e.createComponentVNode)(2,t.Button,{textAlign:"left",icon:"pen",width:20,content:B.author||"Input Author",onClick:function(){function x(){return(0,f.modalOpen)(p,"edit_search_author")}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Ratings",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{mr:1,width:"min-content",content:B.ratingmin,onClick:function(){function x(){return(0,f.modalOpen)(p,"edit_search_ratingmin")}return x}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:"To"}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{ml:1,width:"min-content",content:B.ratingmax,onClick:function(){function x(){return(0,f.modalOpen)(p,"edit_search_ratingmax")}return x}()})})]})})]})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"40%",children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.2rem",m:".5em",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"clipboard-list",verticalAlign:"middle",size:1.5,mr:"1rem"}),"Book Categories"]}),(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Select Categories",children:(0,e.createComponentVNode)(2,t.Box,{mt:2,children:(0,e.createComponentVNode)(2,t.Dropdown,{mt:.6,width:"190px",options:L.map(function(x){return x.description}),onSelected:function(){function x(E){return V("toggle_search_category",{category_id:A[E]})}return x}()})})})}),(0,e.createVNode)(1,"br"),L.filter(function(x){return B.categories.includes(x.category_id)}).map(function(x){return(0,e.createComponentVNode)(2,t.Button,{content:x.description,selected:!0,icon:"unlink",onClick:function(){function E(){return V("toggle_search_category",{category_id:x.category_id})}return E}()},x.category_id)})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.2rem",m:".5em",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"search-plus",verticalAlign:"middle",size:1.5,mr:"1rem"}),"Search Actions"]}),(0,e.createComponentVNode)(2,t.Button,{content:"Clear Search",icon:"eraser",onClick:function(){function x(){return V("clear_search")}return x}()}),B.ckey?(0,e.createComponentVNode)(2,t.Button,{mb:.5,content:"Stop Showing My Books",color:"bad",icon:"search",onClick:function(){function x(){return V("clear_ckey_search")}return x}()}):(0,e.createComponentVNode)(2,t.Button,{content:"Find My Books",icon:"search",onClick:function(){function x(){return V("find_users_books",{user_ckey:w})}return x}()})]})]})},i=function(C,p){var N=(0,a.useBackend)(p),V=N.act,S=N.data,B=S.external_booklist,L=S.archive_pagenumber,w=S.num_pages,A=S.login_state;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Book System Access",buttons:(0,e.createVNode)(1,"div",null,[(0,e.createComponentVNode)(2,t.Button,{icon:"angle-double-left",disabled:L===1,onClick:function(){function x(){return V("deincrementpagemax")}return x}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-left",disabled:L===1,onClick:function(){function x(){return V("deincrementpage")}return x}()}),(0,e.createComponentVNode)(2,t.Button,{bold:!0,content:L,onClick:function(){function x(){return(0,f.modalOpen)(p,"setpagenumber")}return x}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-right",disabled:L===w,onClick:function(){function x(){return V("incrementpage")}return x}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"angle-double-right",disabled:L===w,onClick:function(){function x(){return V("incrementpagemax")}return x}()})],4),children:[(0,e.createComponentVNode)(2,m),(0,e.createVNode)(1,"hr"),(0,e.createComponentVNode)(2,t.Table,{className:"Library__Booklist",children:[(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"SSID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Title"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Author"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Ratings"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Category"}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"middle",children:"Actions"})]}),B.map(function(x){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:x.id}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"book",mr:.5}),x.title.length>45?x.title.substr(0,45)+"...":x.title]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:x.author.length>30?x.author.substr(0,30)+"...":x.author}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[x.rating,(0,e.createComponentVNode)(2,t.Icon,{name:"star",ml:.5,color:"yellow",verticalAlign:"middle"})]}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:x.categories.join(", ").substr(0,45)}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"right",children:[A===1&&(0,e.createComponentVNode)(2,t.Button,{content:"Order",icon:"print",onClick:function(){function E(){return V("order_external_book",{bookid:x.id})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{content:"More...",onClick:function(){function E(){return(0,f.modalOpen)(p,"expand_info",{bookid:x.id})}return E}()})]})]},x.id)})]})]})},u=function(C,p){var N=(0,a.useBackend)(p),V=N.act,S=N.data,B=S.programmatic_booklist,L=S.login_state;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Corporate Book Catalog",children:(0,e.createComponentVNode)(2,t.Table,{className:"Library__Booklist",children:[(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"SSID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Title"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Author"}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"middle",children:"Actions"})]}),B.map(function(w,A){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:w.id}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"book",mr:2}),w.title]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:w.author}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"right",children:[L===1&&(0,e.createComponentVNode)(2,t.Button,{content:"Order",icon:"print",onClick:function(){function x(){return V("order_programmatic_book",{bookid:w.id})}return x}()}),(0,e.createComponentVNode)(2,t.Button,{content:"More...",onClick:function(){function x(){return(0,f.modalOpen)(p,"expand_info",{bookid:w.id})}return x}()})]})]},A)})]})})},s=function(C,p){var N=(0,a.useBackend)(p),V=N.act,S=N.data,B=S.selectedbook,L=S.book_categories,w=S.user_ckey,A=[];return L.map(function(x){return A[x.description]=x.category_id}),(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Book System Upload",buttons:(0,e.createComponentVNode)(2,t.Button.Confirm,{bold:!0,width:9.5,icon:"upload",disabled:B.copyright,content:"Upload Book",onClick:function(){function x(){return V("uploadbook",{user_ckey:w})}return x}()}),children:[B.copyright?(0,e.createComponentVNode)(2,t.NoticeBox,{color:"red",children:"WARNING: You cannot upload or modify the attributes of a copyrighted book"}):(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Box,{ml:15,mb:3,fontSize:"1.2rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"search-plus",verticalAlign:"middle",size:3,mr:2}),"Book Uploader"]}),(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Title",children:(0,e.createComponentVNode)(2,t.Button,{width:20,textAlign:"left",icon:"pen",disabled:B.copyright,content:B.title,onClick:function(){function x(){return(0,f.modalOpen)(p,"edit_selected_title")}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Author",children:(0,e.createComponentVNode)(2,t.Button,{width:20,textAlign:"left",icon:"pen",disabled:B.copyright,content:B.author,onClick:function(){function x(){return(0,f.modalOpen)(p,"edit_selected_author")}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Select Categories",children:(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Dropdown,{width:"240px",options:L.map(function(x){return x.description}),onSelected:function(){function x(E){return V("toggle_upload_category",{category_id:A[E]})}return x}()})})})]}),(0,e.createVNode)(1,"br"),L.filter(function(x){return B.categories.includes(x.category_id)}).map(function(x){return(0,e.createComponentVNode)(2,t.Button,{content:x.description,disabled:B.copyright,selected:!0,icon:"unlink",onClick:function(){function E(){return V("toggle_upload_category",{category_id:x.category_id})}return E}()},x.category_id)})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{mr:75,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Summary",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pen",width:"auto",disabled:B.copyright,content:"Edit Summary",onClick:function(){function x(){return(0,f.modalOpen)(p,"edit_selected_summary")}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{children:B.summary})]})})]})]})},d=function(C,p){var N=(0,a.useBackend)(p),V=N.act,S=N.data,B=S.checkout_data;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Checked Out Books",children:(0,e.createComponentVNode)(2,t.Table,{className:"Library__Booklist",children:[(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Patron"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Title"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Time Left"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Actions"})]}),B.map(function(L,w){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-tag"}),L.patron_name]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:L.title}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:L.timeleft>=0?L.timeleft:"LATE"}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:(0,e.createComponentVNode)(2,t.Button,{content:"Mark Lost",icon:"flag",color:"bad",disabled:L.timeleft>=0,onClick:function(){function A(){return V("reportlost",{libraryid:L.libraryid})}return A}()})})]},w)})]})})},v=function(C,p){var N=(0,a.useBackend)(p),V=N.act,S=N.data,B=S.inventory_list;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Library Inventory",children:(0,e.createComponentVNode)(2,t.Table,{className:"Library__Booklist",children:[(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"LIB ID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Title"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Author"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Status"})]}),B.map(function(L,w){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:L.libraryid}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"book"})," ",L.title]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:L.author}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:L.checked_out?"Checked Out":"Available"})]},w)})]})})};(0,f.modalRegisterBodyOverride)("expand_info",y),(0,f.modalRegisterBodyOverride)("report_book",I),(0,f.modalRegisterBodyOverride)("rate_info",g)},9516:function(T,r,n){"use strict";r.__esModule=!0,r.LibraryManager=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(3939),b=r.LibraryManager=function(){function l(c,m){return(0,e.createComponentVNode)(2,o.Window,{width:600,height:600,children:[(0,e.createComponentVNode)(2,f.ComplexModal),(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,className:"Layout__content--flexColumn",children:(0,e.createComponentVNode)(2,y)})]})}return l}(),y=function(c,m){var i=(0,a.useBackend)(m),u=i.act,s=i.data,d=s.pagestate;switch(d){case 1:return(0,e.createComponentVNode)(2,I);case 2:return(0,e.createComponentVNode)(2,g);case 3:return(0,e.createComponentVNode)(2,k);default:return"WE SHOULDN'T BE HERE!"}},I=function(c,m){var i=(0,a.useBackend)(m),u=i.act,s=i.data;return(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.4rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-shield",verticalAlign:"middle",size:3,mr:"1rem"}),"Library Manager"]}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{icon:"trash",width:"auto",color:"danger",content:"Delete Book by SSID",onClick:function(){function d(){return(0,f.modalOpen)(m,"specify_ssid_delete")}return d}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"user-slash",width:"auto",color:"danger",content:"Delete All Books By CKEY",onClick:function(){function d(){return(0,f.modalOpen)(m,"specify_ckey_delete")}return d}()}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{icon:"search",width:"auto",content:"View All Books By CKEY",onClick:function(){function d(){return(0,f.modalOpen)(m,"specify_ckey_search")}return d}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"search",width:"auto",content:"View All Reported Books",onClick:function(){function d(){return u("view_reported_books")}return d}()})]})},k=function(c,m){var i=(0,a.useBackend)(m),u=i.act,s=i.data,d=s.reports;return(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.Table,{className:"Library__Booklist",children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.2rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-secret",verticalAlign:"middle",size:2,mr:"1rem"}),(0,e.createVNode)(1,"br"),"All Reported Books",(0,e.createVNode)(1,"br")]}),(0,e.createComponentVNode)(2,t.Button,{content:"Return to Main",icon:"arrow-alt-circle-left",onClick:function(){function v(){return u("return")}return v}()}),(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Uploader CKEY"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"SSID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Title"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Author"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Report Type"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Reporter Ckey"}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"middle",children:"Administrative Actions"})]}),d.map(function(v){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:v.uploader_ckey}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:v.id}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"book"}),v.title]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:v.author}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:v.report_description}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:v.reporter_ckey}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button.Confirm,{content:"Delete",icon:"trash",onClick:function(){function h(){return u("delete_book",{bookid:v.id})}return h}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Unflag",icon:"flag",color:"caution",onClick:function(){function h(){return u("unflag_book",{bookid:v.id})}return h}()}),(0,e.createComponentVNode)(2,t.Button,{content:"View",onClick:function(){function h(){return u("view_book",{bookid:v.id})}return h}()})]})]},v.id)})]})})},g=function(c,m){var i=(0,a.useBackend)(m),u=i.act,s=i.data,d=s.ckey,v=s.booklist;return(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.Table,{className:"Library__Booklist",children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.2rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user",verticalAlign:"middle",size:2,mr:"1rem"}),(0,e.createVNode)(1,"br"),"Books uploaded by ",d,(0,e.createVNode)(1,"br")]}),(0,e.createComponentVNode)(2,t.Button,{mt:1,content:"Return to Main",icon:"arrow-alt-circle-left",onClick:function(){function h(){return u("return")}return h}()}),(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"SSID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Title"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Author"}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"middle",children:"Administrative Actions"})]}),v.map(function(h){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:h.id}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"book"}),h.title]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:h.author}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"right",children:[(0,e.createComponentVNode)(2,t.Button.Confirm,{content:"Delete",icon:"trash",color:"bad",onClick:function(){function C(){return u("delete_book",{bookid:h.id})}return C}()}),(0,e.createComponentVNode)(2,t.Button,{content:"View",onClick:function(){function C(){return u("view_book",{bookid:h.id})}return C}()})]})]},h.id)})]})})}},90447:function(T,r,n){"use strict";r.__esModule=!0,r.ListInputModal=void 0;var e=n(89005),a=n(51057),t=n(19203),o=n(36036),f=n(72253),b=n(92986),y=n(98595),I=r.ListInputModal=function(){function l(c,m){var i=(0,f.useBackend)(m),u=i.act,s=i.data,d=s.items,v=d===void 0?[]:d,h=s.message,C=h===void 0?"":h,p=s.init_value,N=s.timeout,V=s.title,S=(0,f.useLocalState)(m,"selected",v.indexOf(p)),B=S[0],L=S[1],w=(0,f.useLocalState)(m,"searchBarVisible",v.length>10),A=w[0],x=w[1],E=(0,f.useLocalState)(m,"searchQuery",""),P=E[0],D=E[1],M=function(){function G(X){var J=z.length-1;if(X===b.KEY_DOWN)if(B===null||B===J){var se;L(0),(se=document.getElementById("0"))==null||se.scrollIntoView()}else{var ie;L(B+1),(ie=document.getElementById((B+1).toString()))==null||ie.scrollIntoView()}else if(X===b.KEY_UP)if(B===null||B===0){var me;L(J),(me=document.getElementById(J.toString()))==null||me.scrollIntoView()}else{var q;L(B-1),(q=document.getElementById((B-1).toString()))==null||q.scrollIntoView()}}return G}(),R=function(){function G(X){X!==B&&L(X)}return G}(),O=function(){function G(){x(!1),x(!0)}return G}(),F=function(){function G(X){var J=String.fromCharCode(X),se=v.find(function(q){return q==null?void 0:q.toLowerCase().startsWith(J==null?void 0:J.toLowerCase())});if(se){var ie,me=v.indexOf(se);L(me),(ie=document.getElementById(me.toString()))==null||ie.scrollIntoView()}}return G}(),_=function(){function G(X){var J;X!==P&&(D(X),L(0),(J=document.getElementById("0"))==null||J.scrollIntoView())}return G}(),U=function(){function G(){x(!A),D("")}return G}(),z=v.filter(function(G){return G==null?void 0:G.toLowerCase().includes(P.toLowerCase())}),$=330+Math.ceil(C.length/3);return A||setTimeout(function(){var G;return(G=document.getElementById(B.toString()))==null?void 0:G.focus()},1),(0,e.createComponentVNode)(2,y.Window,{title:V,width:325,height:$,children:[N&&(0,e.createComponentVNode)(2,a.Loader,{value:N}),(0,e.createComponentVNode)(2,y.Window.Content,{onKeyDown:function(){function G(X){var J=window.event?X.which:X.keyCode;(J===b.KEY_DOWN||J===b.KEY_UP)&&(X.preventDefault(),M(J)),J===b.KEY_ENTER&&(X.preventDefault(),u("submit",{entry:z[B]})),!A&&J>=b.KEY_A&&J<=b.KEY_Z&&(X.preventDefault(),F(J)),J===b.KEY_ESCAPE&&(X.preventDefault(),u("cancel"))}return G}(),children:(0,e.createComponentVNode)(2,o.Section,{buttons:(0,e.createComponentVNode)(2,o.Button,{compact:!0,icon:A?"search":"font",selected:!0,tooltip:A?"Search Mode. Type to search or use arrow keys to select manually.":"Hotkey Mode. Type a letter to jump to the first match. Enter to select.",tooltipPosition:"left",onClick:function(){function G(){return U()}return G}()}),className:"ListInput__Section",fill:!0,title:C,children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,k,{filteredItems:z,onClick:R,onFocusSearch:O,searchBarVisible:A,selected:B})}),(0,e.createComponentVNode)(2,o.Stack.Item,{m:0,children:A&&(0,e.createComponentVNode)(2,g,{filteredItems:z,onSearch:_,searchQuery:P,selected:B})}),(0,e.createComponentVNode)(2,o.Stack.Item,{mt:.5,children:(0,e.createComponentVNode)(2,t.InputButtons,{input:z[B]})})]})})})]})}return l}(),k=function(c,m){var i=(0,f.useBackend)(m),u=i.act,s=c.filteredItems,d=c.onClick,v=c.onFocusSearch,h=c.searchBarVisible,C=c.selected;return(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,tabIndex:0,children:s.map(function(p,N){return(0,e.createComponentVNode)(2,o.Button,{fluid:!0,color:"transparent",id:N,onClick:function(){function V(){return d(N)}return V}(),onDblClick:function(){function V(S){S.preventDefault(),u("submit",{entry:s[C]})}return V}(),onKeyDown:function(){function V(S){var B=window.event?S.which:S.keyCode;h&&B>=b.KEY_A&&B<=b.KEY_Z&&(S.preventDefault(),v())}return V}(),selected:N===C,style:{animation:"none",transition:"none"},children:p.replace(/^\w/,function(V){return V.toUpperCase()})},N)})})},g=function(c,m){var i=(0,f.useBackend)(m),u=i.act,s=c.filteredItems,d=c.onSearch,v=c.searchQuery,h=c.selected;return(0,e.createComponentVNode)(2,o.Input,{width:"100%",autoFocus:!0,autoSelect:!0,onEnter:function(){function C(p){p.preventDefault(),u("submit",{entry:s[h]})}return C}(),onInput:function(){function C(p,N){return d(N)}return C}(),placeholder:"Search...",value:v})}},26826:function(T,r,n){"use strict";r.__esModule=!0,r.Loadout=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),f=n(98595),b={Default:function(){function c(m,i){return m.gear.gear_tier-i.gear.gear_tier}return c}(),Alphabetical:function(){function c(m,i){return m.gear.name.toLowerCase().localeCompare(i.gear.name.toLowerCase())}return c}(),Cost:function(){function c(m,i){return m.gear.cost-i.gear.cost}return c}()},y=r.Loadout=function(){function c(m,i){var u=(0,t.useBackend)(i),s=u.act,d=u.data,v=(0,t.useLocalState)(i,"search",!1),h=v[0],C=v[1],p=(0,t.useLocalState)(i,"searchText",""),N=p[0],V=p[1],S=(0,t.useLocalState)(i,"category",Object.keys(d.gears)[0]),B=S[0],L=S[1],w=(0,t.useLocalState)(i,"tweakedGear",""),A=w[0],x=w[1];return(0,e.createComponentVNode)(2,f.Window,{width:1105,height:650,children:[A&&(0,e.createComponentVNode)(2,l,{tweakedGear:A,setTweakedGear:x}),(0,e.createComponentVNode)(2,f.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,I,{category:B,setCategory:L})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"25%",children:(0,e.createComponentVNode)(2,g,{setTweakedGear:x})}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"75%",children:(0,e.createComponentVNode)(2,k,{category:B,search:h,setSearch:C,searchText:N,setSearchText:V})})]})})]})})]})}return c}(),I=function(m,i){var u=(0,t.useBackend)(i),s=u.act,d=u.data,v=m.category,h=m.setCategory;return(0,e.createComponentVNode)(2,o.Tabs,{fluid:!0,textAlign:"center",style:{"flex-wrap":"wrap-reverse"},children:Object.keys(d.gears).map(function(C){return(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:C===v,style:{"white-space":"nowrap"},onClick:function(){function p(){return h(C)}return p}(),children:C},C)})})},k=function(m,i){var u=(0,t.useBackend)(i),s=u.act,d=u.data,v=d.user_tier,h=d.gear_slots,C=d.max_gear_slots,p=m.category,N=m.search,V=m.setSearch,S=m.searchText,B=m.setSearchText,L=(0,t.useLocalState)(i,"sortType","Default"),w=L[0],A=L[1],x=(0,t.useLocalState)(i,"sortReverse",!1),E=x[0],P=x[1],D=(0,a.createSearch)(S,function(R){return R.name}),M;return S.length>2?M=Object.entries(d.gears).reduce(function(R,O){var F=O[0],_=O[1];return R.concat(Object.entries(_).map(function(U){var z=U[0],$=U[1];return{key:z,gear:$}}))},[]).filter(function(R){var O=R.gear;return D(O)}):M=Object.entries(d.gears[p]).map(function(R){var O=R[0],F=R[1];return{key:O,gear:F}}),M.sort(b[w]),E&&(M=M.reverse()),(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:p,buttons:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Dropdown,{height:1.66,selected:w,options:Object.keys(b),onSelected:function(){function R(O){return A(O)}return R}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{icon:E?"arrow-down-wide-short":"arrow-down-short-wide",tooltip:E?"Ascending order":"Descending order",tooltipPosition:"bottom-end",onClick:function(){function R(){return P(!E)}return R}()})}),N&&(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Input,{width:20,placeholder:"Search...",value:S,onInput:function(){function R(O){return B(O.target.value)}return R}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{icon:"magnifying-glass",selected:N,tooltip:"Toggle search field",tooltipPosition:"bottom-end",onClick:function(){function R(){V(!N),B("")}return R}()})})]}),children:M.map(function(R){var O=R.key,F=R.gear,_=12,U=Object.keys(d.selected_gears).includes(O),z=F.cost===1?F.cost+" Point":F.cost+" Points",$=(0,e.createComponentVNode)(2,o.Box,{children:[F.name.length>_&&(0,e.createComponentVNode)(2,o.Box,{children:F.name}),F.gear_tier>v&&(0,e.createComponentVNode)(2,o.Box,{mt:F.name.length>_&&1.5,textColor:"red",children:"That gear is only available at a higher donation tier than you are on."})]}),G=(0,e.createFragment)([F.allowed_roles&&(0,e.createComponentVNode)(2,o.Button,{width:"22px",color:"transparent",icon:"user",tooltip:(0,e.createComponentVNode)(2,o.Section,{m:-1,title:"Allowed Roles",children:F.allowed_roles.map(function(J){return(0,e.createComponentVNode)(2,o.Box,{children:J},J)})}),tooltipPosition:"left"}),Object.entries(F.tweaks).map(function(J){var se=J[0],ie=J[1];return ie.map(function(me){return(0,e.createComponentVNode)(2,o.Button,{width:"22px",color:"transparent",icon:me.icon,tooltip:me.tooltip,tooltipPosition:"top"},se)})}),(0,e.createComponentVNode)(2,o.Button,{width:"22px",color:"transparent",icon:"info",tooltip:F.desc,tooltipPosition:"top"})],0),X=(0,e.createComponentVNode)(2,o.Box,{class:"Loadout-InfoBox",children:[(0,e.createComponentVNode)(2,o.Box,{style:{"flex-grow":1},fontSize:1,color:"gold",opacity:.75,children:F.gear_tier>0&&"Tier "+F.gear_tier}),(0,e.createComponentVNode)(2,o.Box,{fontSize:.75,opacity:.66,children:z})]});return(0,e.createComponentVNode)(2,o.ImageButton,{m:.5,imageSize:84,dmIcon:F.icon,dmIconState:F.icon_state,tooltip:(F.name.length>_||F.gear_tier>0)&&$,tooltipPosition:"bottom",selected:U,disabled:F.gear_tier>v||h+F.cost>C&&!U,buttons:G,buttonsAlt:X,onClick:function(){function J(){return s("toggle_gear",{gear:O})}return J}(),children:F.name},O)})})},g=function(m,i){var u=(0,t.useBackend)(i),s=u.act,d=u.data,v=m.setTweakedGear,h=Object.entries(d.gears).reduce(function(C,p){var N=p[0],V=p[1],S=Object.entries(V).filter(function(B){var L=B[0];return Object.keys(d.selected_gears).includes(L)}).map(function(B){var L=B[0],w=B[1];return Object.assign({key:L},w)});return C.concat(S)},[]);return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Selected Equipment",buttons:(0,e.createComponentVNode)(2,o.Button.Confirm,{icon:"trash",tooltip:"Clear Loadout",tooltipPosition:"bottom-end",onClick:function(){function C(){return s("clear_loadout")}return C}()}),children:h.map(function(C){return(0,e.createComponentVNode)(2,o.ImageButton,{fluid:!0,imageSize:32,dmIcon:C.icon,dmIconState:C.icon_state,buttons:(0,e.createFragment)([Object.entries(C.tweaks).length>0&&(0,e.createComponentVNode)(2,o.Button,{translucent:!0,icon:"gears",iconColor:"gray",width:"33px",onClick:function(){function p(){return v(C)}return p}()}),(0,e.createComponentVNode)(2,o.Button,{translucent:!0,icon:"times",iconColor:"red",width:"32px",onClick:function(){function p(){return s("toggle_gear",{gear:C.key})}return p}()})],0),children:C.name},C.key)})})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.ProgressBar,{value:d.gear_slots,maxValue:d.max_gear_slots,ranges:{bad:[d.max_gear_slots,1/0],average:[d.max_gear_slots*.66,d.max_gear_slots],good:[0,d.max_gear_slots*.66]},children:(0,e.createComponentVNode)(2,o.Box,{textAlign:"center",children:["Used points ",d.gear_slots,"/",d.max_gear_slots]})})})})]})},l=function(m,i){var u=(0,t.useBackend)(i),s=u.act,d=u.data,v=m.tweakedGear,h=m.setTweakedGear;return(0,e.createComponentVNode)(2,o.Dimmer,{children:(0,e.createComponentVNode)(2,o.Box,{className:"Loadout-Modal__background",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,width:20,height:20,title:v.name,buttons:(0,e.createComponentVNode)(2,o.Button,{color:"red",icon:"times",tooltip:"Close",tooltipPosition:"top",onClick:function(){function C(){return h("")}return C}()}),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:Object.entries(v.tweaks).map(function(C){var p=C[0],N=C[1];return N.map(function(V){var S=d.selected_gears[v.key][p];return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:V.name,color:S?"":"gray",buttons:(0,e.createComponentVNode)(2,o.Button,{color:"transparent",icon:"pen",onClick:function(){function B(){return s("set_tweak",{gear:v.key,tweak:p})}return B}()}),children:[S||"Default",(0,e.createComponentVNode)(2,o.Box,{inline:!0,ml:1,width:1,height:1,verticalAlign:"middle",style:{"background-color":""+S}})]},p)})})})})})})}},77613:function(T,r,n){"use strict";r.__esModule=!0,r.MODsuitContent=r.MODsuit=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=function(B,L){var w=B.name,A=B.value,x=B.module_ref,E=(0,a.useBackend)(L),P=E.act;return(0,e.createComponentVNode)(2,t.NumberInput,{value:A,minValue:-50,maxValue:50,stepPixelSize:5,width:"39px",onChange:function(){function D(M,R){return P("configure",{key:w,value:R,ref:x})}return D}()})},b=function(B,L){var w=B.name,A=B.value,x=B.module_ref,E=(0,a.useBackend)(L),P=E.act;return(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:A,onClick:function(){function D(){return P("configure",{key:w,value:!A,ref:x})}return D}()})},y=function(B,L){var w=B.name,A=B.value,x=B.module_ref,E=(0,a.useBackend)(L),P=E.act;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{icon:"paint-brush",onClick:function(){function D(){return P("configure",{key:w,ref:x})}return D}()}),(0,e.createComponentVNode)(2,t.ColorBox,{color:A,mr:.5})],4)},I=function(B,L){var w=B.name,A=B.value,x=B.values,E=B.module_ref,P=(0,a.useBackend)(L),D=P.act;return(0,e.createComponentVNode)(2,t.Dropdown,{displayText:A,options:x,onSelected:function(){function M(R){return D("configure",{key:w,value:R,ref:E})}return M}()})},k=function(B,L){var w=B.name,A=B.display_name,x=B.type,E=B.value,P=B.values,D=B.module_ref,M={number:(0,e.normalizeProps)((0,e.createComponentVNode)(2,f,Object.assign({},B))),bool:(0,e.normalizeProps)((0,e.createComponentVNode)(2,b,Object.assign({},B))),color:(0,e.normalizeProps)((0,e.createComponentVNode)(2,y,Object.assign({},B))),list:(0,e.normalizeProps)((0,e.createComponentVNode)(2,I,Object.assign({},B)))};return(0,e.createComponentVNode)(2,t.Box,{children:[A,": ",M[x]]})},g=function(B,L){var w=B.active,A=B.userradiated,x=B.usertoxins,E=B.usermaxtoxins,P=B.threatlevel;return(0,e.createComponentVNode)(2,t.Stack,{fill:!0,textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Radiation Level",color:w&&A?"bad":"good",children:w&&A?"IRRADIATED!":"RADIATION-FREE"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Toxins Level",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?x/E:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:x})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Hazard Level",color:w&&P?"bad":"good",bold:!0,children:w&&P?P:0})})]})},l=function(B,L){var w=B.active,A=B.userhealth,x=B.usermaxhealth,E=B.userbrute,P=B.userburn,D=B.usertoxin,M=B.useroxy;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{title:"Health",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?A/x:0,ranges:{good:[.5,1/0],average:[.2,.5],bad:[-1/0,.2]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?A:0})})}),(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Brute",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?E/x:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?E:0})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Burn",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?P/x:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?P:0})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Toxin",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?D/x:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?D:0})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Suffocation",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?M/x:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?M:0})})})})]})],4)},c=function(B,L){var w=B.active,A=B.statustime,x=B.statusid,E=B.statushealth,P=B.statusmaxhealth,D=B.statusbrute,M=B.statusburn,R=B.statustoxin,O=B.statusoxy,F=B.statustemp,_=B.statusnutrition,U=B.statusfingerprints,z=B.statusdna,$=B.statusviruses;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Operation Time",children:w?A:"00:00:00"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Operation Number",children:w?x||"0":"???"})})]}),(0,e.createComponentVNode)(2,t.Section,{title:"Health",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?E/P:0,ranges:{good:[.5,1/0],average:[.2,.5],bad:[-1/0,.2]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?E:0})})}),(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Brute",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?D/P:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?D:0})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Burn",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?M/P:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?M:0})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Toxin",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?R/P:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:R})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Suffocation",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?O/P:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:O})})})})]}),(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Body Temperature",children:w?F:0})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Nutrition Status",children:w?_:0})})]}),(0,e.createComponentVNode)(2,t.Section,{title:"DNA",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Fingerprints",children:w?U:"???"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Unique Enzymes",children:w?z:"???"})]})}),!!w&&!!$&&(0,e.createComponentVNode)(2,t.Section,{title:"Diseases",children:(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"signature",tooltip:"Name",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"wind",tooltip:"Type",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"bolt",tooltip:"Stage",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"flask",tooltip:"Cure",tooltipPosition:"top"})})]}),$.map(function(G){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:G.name}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:G.type}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:[G.stage,"/",G.maxstage]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:G.cure})]},G.name)})]})})],0)},m={rad_counter:g,health_analyzer:l,status_readout:c},i=function(){return(0,e.createComponentVNode)(2,t.Section,{align:"center",fill:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{color:"red",name:"exclamation-triangle",size:15}),(0,e.createComponentVNode)(2,t.Box,{fontSize:"30px",color:"red",children:"ERROR: INTERFACE UNRESPONSIVE"})]})},u=function(B,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data;return(0,e.createComponentVNode)(2,t.Dimmer,{children:(0,e.createComponentVNode)(2,t.Stack,{children:(0,e.createComponentVNode)(2,t.Stack.Item,{fontSize:"16px",color:"blue",children:"SUIT UNPOWERED"})})})},s=function(B,L){var w=B.configuration_data,A=B.module_ref,x=Object.keys(w);return(0,e.createComponentVNode)(2,t.Dimmer,{backgroundColor:"rgba(0, 0, 0, 0.8)",children:(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:[x.map(function(E){var P=w[E];return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,k,{name:E,display_name:P.display_name,type:P.type,value:P.value,values:P.values,module_ref:A})},P.key)}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,onClick:B.onExit,icon:"times",textAlign:"center",children:"Exit"})})})]})})},d=function(B){switch(B){case 1:return"Use";case 2:return"Toggle";case 3:return"Select"}},v=function(B,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data,E=x.active,P=x.malfunctioning,D=x.locked,M=x.open,R=x.selected_module,O=x.complexity,F=x.complexity_max,_=x.wearer_name,U=x.wearer_job,z=P?"Malfunctioning":E?"Active":"Inactive";return(0,e.createComponentVNode)(2,t.Section,{title:"Parameters",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"power-off",content:E?"Deactivate":"Activate",onClick:function(){function $(){return A("activate")}return $}()}),children:z}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"ID Lock",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:D?"lock-open":"lock",content:D?"Unlock":"Lock",onClick:function(){function $(){return A("lock")}return $}()}),children:D?"Locked":"Unlocked"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cover",children:M?"Open":"Closed"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Selected Module",children:R||"None"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Complexity",children:[O," (",F,")"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Occupant",children:[_,", ",U]})]})})},h=function(B,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data,E=x.active,P=x.control,D=x.helmet,M=x.chestplate,R=x.gauntlets,O=x.boots,F=x.core,_=x.charge;return(0,e.createComponentVNode)(2,t.Section,{title:"Hardware",children:[(0,e.createComponentVNode)(2,t.Collapsible,{title:"Parts",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Control Unit",children:P}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Helmet",children:D||"None"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Chestplate",children:M||"None"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Gauntlets",children:R||"None"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Boots",children:O||"None"})]})}),(0,e.createComponentVNode)(2,t.Collapsible,{title:"Core",children:F&&(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Core Type",children:F}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Core Charge",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:_/100,content:_+"%",ranges:{good:[.6,1/0],average:[.3,.6],bad:[-1/0,.3]}})})]})||(0,e.createComponentVNode)(2,t.Box,{color:"bad",textAlign:"center",children:"No Core Detected"})})]})},C=function(B,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data,E=x.active,P=x.modules,D=P.filter(function(M){return!!M.id});return(0,e.createComponentVNode)(2,t.Section,{title:"Info",children:(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:D.length!==0&&D.map(function(M){var R=m[M.id];return(0,e.createComponentVNode)(2,t.Stack.Item,{children:[!E&&(0,e.createComponentVNode)(2,u),(0,e.normalizeProps)((0,e.createComponentVNode)(2,R,Object.assign({},M,{active:E})))]},M.ref)})||(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",children:"No Info Modules Detected"})})})},p=function(B,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data,E=x.complexity_max,P=x.modules,D=(0,a.useLocalState)(L,"module_configuration",null),M=D[0],R=D[1];return(0,e.createComponentVNode)(2,t.Section,{title:"Modules",fill:!0,children:(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:P.length!==0&&P.map(function(O){return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Collapsible,{title:O.module_name,children:(0,e.createComponentVNode)(2,t.Section,{children:[M===O.ref&&(0,e.createComponentVNode)(2,s,{configuration_data:O.configuration_data,module_ref:O.ref,onExit:function(){function F(){return R(null)}return F}()}),(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"save",tooltip:"Complexity",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"plug",tooltip:"Idle Power Cost",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"lightbulb",tooltip:"Active Power Cost",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"bolt",tooltip:"Use Power Cost",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"hourglass-half",tooltip:"Cooldown",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"tasks",tooltip:"Actions",tooltipPosition:"top"})})]}),(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:[O.module_complexity,"/",E]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:O.idle_power}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:O.active_power}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:O.use_power}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:[O.cooldown>0&&O.cooldown/10||"0","/",O.cooldown_time/10,"s"]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Button,{onClick:function(){function F(){return A("select",{ref:O.ref})}return F}(),icon:"bullseye",selected:O.module_active,tooltip:d(O.module_type),tooltipPosition:"left",disabled:!O.module_type}),(0,e.createComponentVNode)(2,t.Button,{onClick:function(){function F(){return R(O.ref)}return F}(),icon:"cog",selected:M===O.ref,tooltip:"Configure",tooltipPosition:"left",disabled:O.configuration_data.length===0}),(0,e.createComponentVNode)(2,t.Button,{onClick:function(){function F(){return A("pin",{ref:O.ref})}return F}(),icon:"thumbtack",selected:O.pinned,tooltip:"Pin",tooltipPosition:"left",disabled:!O.module_type})]})]})]}),(0,e.createComponentVNode)(2,t.Box,{children:O.description})]})})},O.ref)})||(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",children:"No Modules Detected"})})})})},N=r.MODsuitContent=function(){function S(B,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data,E=x.ui_theme,P=x.interface_break;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!P,children:!!P&&(0,e.createComponentVNode)(2,i)||(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,v)}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,h)}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,C)}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,p)})]})})}return S}(),V=r.MODsuit=function(){function S(B,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data,E=x.ui_theme,P=x.interface_break;return(0,e.createComponentVNode)(2,o.Window,{theme:E,width:400,height:620,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,N)})})})}return S}()},78624:function(T,r,n){"use strict";r.__esModule=!0,r.MagnetController=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),f=n(98595),b=n(3939),y=new Map([["n",{icon:"arrow-up",tooltip:"Move North"}],["e",{icon:"arrow-right",tooltip:"Move East"}],["s",{icon:"arrow-down",tooltip:"Move South"}],["w",{icon:"arrow-left",tooltip:"Move West"}],["c",{icon:"crosshairs",tooltip:"Move to Magnet"}],["r",{icon:"dice",tooltip:"Move Randomly"}]]),I=r.MagnetController=function(){function k(g,l){var c=(0,t.useBackend)(l),m=c.act,i=c.data,u=i.autolink,s=i.code,d=i.frequency,v=i.linkedMagnets,h=i.magnetConfiguration,C=i.path,p=i.pathPosition,N=i.probing,V=i.powerState,S=i.speed;return(0,e.createComponentVNode)(2,f.Window,{width:400,height:600,children:[(0,e.createComponentVNode)(2,b.ComplexModal),(0,e.createComponentVNode)(2,f.Window.Content,{scrollable:!0,children:[!u&&(0,e.createComponentVNode)(2,o.Section,{buttons:(0,e.createComponentVNode)(2,o.Button,{content:"Probe",icon:N?"spinner":"sync",iconSpin:!!N,disabled:N,onClick:function(){function B(){return m("probe_magnets")}return B}()}),title:"Magnet Linking",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Frequency",children:(0,a.toFixed)(d/10,1)}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Code",children:s})]})}),(0,e.createComponentVNode)(2,o.Section,{buttons:(0,e.createComponentVNode)(2,o.Button,{icon:V?"power-off":"times",content:V?"On":"Off",selected:V,onClick:function(){function B(){return m("toggle_power")}return B}()}),title:"Controller Configuration",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Speed",children:(0,e.createComponentVNode)(2,o.Slider,{value:S.value,minValue:S.min,maxValue:S.max,onChange:function(){function B(L,w){return m("set_speed",{speed:w})}return B}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Path",children:[Array.from(y.entries()).map(function(B){var L=B[0],w=B[1],A=w.icon,x=w.tooltip;return(0,e.createComponentVNode)(2,o.Button,{icon:A,tooltip:x,onClick:function(){function E(){return m("path_add",{code:L})}return E}()},L)}),(0,e.createComponentVNode)(2,o.Button.Confirm,{icon:"trash",confirmIcon:"trash",confirmContent:"",float:"right",tooltip:"Reset Path",tooltipPosition:"left",onClick:function(){function B(){return m("path_clear")}return B}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"file-import",float:"right",tooltip:"Manually input path",tooltipPosition:"left",onClick:function(){function B(){return(0,b.modalOpen)(l,"path_custom_input")}return B}()}),(0,e.createComponentVNode)(2,o.BlockQuote,{children:C.map(function(B,L){var w=y.get(B)||{icon:"question"},A=w.icon,x=w.tooltip;return(0,e.createComponentVNode)(2,o.Button.Confirm,{selected:L+2===p,icon:A,confirmIcon:A,confirmContent:"",tooltip:x,onClick:function(){function E(){return m("path_remove",{index:L+1,code:B})}return E}()},L)})})]})]})}),v.map(function(B,L){var w=B.uid,A=B.powerState,x=B.electricityLevel,E=B.magneticField;return(0,e.createComponentVNode)(2,o.Section,{title:"Magnet #"+(L+1)+" Configuration",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:A?"power-off":"times",content:A?"On":"Off",selected:A,onClick:function(){function P(){return m("toggle_magnet_power",{id:w})}return P}()}),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Move Speed",children:(0,e.createComponentVNode)(2,o.Slider,{value:x,minValue:h.electricityLevel.min,maxValue:h.electricityLevel.max,onChange:function(){function P(D,M){return m("set_electricity_level",{id:w,electricityLevel:M})}return P}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Field Size",children:(0,e.createComponentVNode)(2,o.Slider,{value:E,minValue:h.magneticField.min,maxValue:h.magneticField.max,onChange:function(){function P(D,M){return m("set_magnetic_field",{id:w,magneticField:M})}return P}()})})]})},w)})]})]})}return k}()},72106:function(T,r,n){"use strict";r.__esModule=!0,r.MechBayConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.MechBayConsole=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.recharge_port,m=c&&c.mech,i=m&&m.cell,u=m&&m.name;return(0,e.createComponentVNode)(2,o.Window,{width:400,height:155,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:u?"Mech status: "+u:"Mech status",textAlign:"center",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"sync",content:"Sync",onClick:function(){function s(){return g("reconnect")}return s}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Integrity",children:!c&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No power port detected. Please re-sync."})||!m&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No mech detected."})||(0,e.createComponentVNode)(2,t.ProgressBar,{value:m.health/m.maxhealth,ranges:{good:[.7,1/0],average:[.3,.7],bad:[-1/0,.3]}})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:!c&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No power port detected. Please re-sync."})||!m&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No mech detected."})||!i&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No cell is installed."})||(0,e.createComponentVNode)(2,t.ProgressBar,{value:i.charge/i.maxcharge,ranges:{good:[.7,1/0],average:[.3,.7],bad:[-1/0,.3]},children:[(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:i.charge})," / "+i.maxcharge]})})]})})})})}return b}()},7466:function(T,r,n){"use strict";r.__esModule=!0,r.MechaControlConsole=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),f=n(98595),b=n(25328),y=r.MechaControlConsole=function(){function I(k,g){var l=(0,t.useBackend)(g),c=l.act,m=l.data,i=m.beacons,u=m.stored_data;return u.length?(0,e.createComponentVNode)(2,f.Window,{width:420,height:500,children:(0,e.createComponentVNode)(2,f.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,o.Section,{title:"Log",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"window-close",onClick:function(){function s(){return c("clear_log")}return s}()}),children:u.map(function(s){return(0,e.createComponentVNode)(2,o.Box,{children:[(0,e.createComponentVNode)(2,o.Box,{color:"label",children:["(",s.time,")"]}),(0,e.createComponentVNode)(2,o.Box,{children:(0,b.decodeHtmlEntities)(s.message)})]},s.time)})})})}):(0,e.createComponentVNode)(2,f.Window,{width:420,height:500,children:(0,e.createComponentVNode)(2,f.Window.Content,{scrollable:!0,children:i.length&&i.map(function(s){return(0,e.createComponentVNode)(2,o.Section,{title:s.name,buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{icon:"comment",onClick:function(){function d(){return c("send_message",{mt:s.uid})}return d}(),children:"Message"}),(0,e.createComponentVNode)(2,o.Button,{icon:"eye",onClick:function(){function d(){return c("get_log",{mt:s.uid})}return d}(),children:"View Log"}),(0,e.createComponentVNode)(2,o.Button.Confirm,{color:"red",content:"Sabotage",icon:"bomb",onClick:function(){function d(){return c("shock",{mt:s.uid})}return d}()})],4),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Health",children:(0,e.createComponentVNode)(2,o.ProgressBar,{ranges:{good:[s.maxHealth*.75,1/0],average:[s.maxHealth*.5,s.maxHealth*.75],bad:[-1/0,s.maxHealth*.5]},value:s.health,maxValue:s.maxHealth})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Cell Charge",children:s.cell&&(0,e.createComponentVNode)(2,o.ProgressBar,{ranges:{good:[s.cellMaxCharge*.75,1/0],average:[s.cellMaxCharge*.5,s.cellMaxCharge*.75],bad:[-1/0,s.cellMaxCharge*.5]},value:s.cellCharge,maxValue:s.cellMaxCharge})||(0,e.createComponentVNode)(2,o.NoticeBox,{children:"No Cell Installed"})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Air Tank",children:[s.airtank,"kPa"]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Pilot",children:s.pilot||"Unoccupied"}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Location",children:(0,b.toTitleCase)(s.location)||"Unknown"}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Active Equipment",children:s.active||"None"}),s.cargoMax&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Cargo Space",children:(0,e.createComponentVNode)(2,o.ProgressBar,{ranges:{bad:[s.cargoMax*.75,1/0],average:[s.cargoMax*.5,s.cargoMax*.75],good:[-1/0,s.cargoMax*.5]},value:s.cargoUsed,maxValue:s.cargoMax})})||null]})},s.name)})||(0,e.createComponentVNode)(2,o.NoticeBox,{children:"No mecha beacons found."})})})}return I}()},79625:function(T,r,n){"use strict";r.__esModule=!0,r.MedicalRecords=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),f=n(3939),b=n(98595),y=n(321),I=n(5485),k=n(22091),g={Minor:"lightgray",Medium:"good",Harmful:"average","Dangerous!":"bad","BIOHAZARD THREAT!":"darkred"},l={"*Deceased*":"deceased","*SSD*":"ssd","Physically Unfit":"physically_unfit",Disabled:"disabled"},c=function(A,x){(0,f.modalOpen)(A,"edit",{field:x.edit,value:x.value})},m=function(A,x){var E=A.args;return(0,e.createComponentVNode)(2,o.Section,{m:"-1rem",pb:"1.5rem",title:E.name||"Virus",children:(0,e.createComponentVNode)(2,o.Box,{mx:"0.5rem",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Number of stages",children:E.max_stages}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Spread",children:[E.spread_text," Transmission"]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Possible cure",children:E.cure}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Notes",children:E.desc}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Severity",color:g[E.severity],children:E.severity})]})})})},i=r.MedicalRecords=function(){function w(A,x){var E=(0,t.useBackend)(x),P=E.data,D=P.loginState,M=P.screen;if(!D.logged_in)return(0,e.createComponentVNode)(2,b.Window,{width:800,height:900,children:(0,e.createComponentVNode)(2,b.Window.Content,{children:(0,e.createComponentVNode)(2,I.LoginScreen)})});var R;return M===2?R=(0,e.createComponentVNode)(2,u):M===3?R=(0,e.createComponentVNode)(2,s):M===4?R=(0,e.createComponentVNode)(2,d):M===5?R=(0,e.createComponentVNode)(2,p):M===6?R=(0,e.createComponentVNode)(2,N):M===7&&(R=(0,e.createComponentVNode)(2,V)),(0,e.createComponentVNode)(2,b.Window,{width:800,height:900,children:[(0,e.createComponentVNode)(2,f.ComplexModal),(0,e.createComponentVNode)(2,b.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,y.LoginInfo),(0,e.createComponentVNode)(2,k.TemporaryNotice),(0,e.createComponentVNode)(2,L),R]})})]})}return w}(),u=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.records,R=(0,t.useLocalState)(x,"searchText",""),O=R[0],F=R[1],_=(0,t.useLocalState)(x,"sortId","name"),U=_[0],z=_[1],$=(0,t.useLocalState)(x,"sortOrder",!0),G=$[0],X=$[1];return(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{content:"Manage Records",icon:"wrench",ml:"0.25rem",onClick:function(){function J(){return P("screen",{screen:3})}return J}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Input,{fluid:!0,placeholder:"Search by Name, ID, Physical Status, or Mental Status",onInput:function(){function J(se,ie){return F(ie)}return J}()})})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,mt:.5,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,o.Table,{className:"MedicalRecords__list",children:[(0,e.createComponentVNode)(2,o.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,S,{id:"name",children:"Name"}),(0,e.createComponentVNode)(2,S,{id:"id",children:"ID"}),(0,e.createComponentVNode)(2,S,{id:"rank",children:"Assignment"}),(0,e.createComponentVNode)(2,S,{id:"p_stat",children:"Patient Status"}),(0,e.createComponentVNode)(2,S,{id:"m_stat",children:"Mental Status"})]}),M.filter((0,a.createSearch)(O,function(J){return J.name+"|"+J.id+"|"+J.rank+"|"+J.p_stat+"|"+J.m_stat})).sort(function(J,se){var ie=G?1:-1;return J[U].localeCompare(se[U])*ie}).map(function(J){return(0,e.createComponentVNode)(2,o.Table.Row,{className:"MedicalRecords__listRow--"+l[J.p_stat],onClick:function(){function se(){return P("view_record",{view_record:J.ref})}return se}(),children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"user"})," ",J.name]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:J.id}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:J.rank}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:J.p_stat}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:J.m_stat})]},J.id)})]})})})],4)},s=function(A,x){var E=(0,t.useBackend)(x),P=E.act;return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Button,{fluid:!0,translucent:!0,lineHeight:3,icon:"download",content:"Backup to Disk",disabled:!0})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:[(0,e.createComponentVNode)(2,o.Button,{fluid:!0,translucent:!0,lineHeight:3,icon:"upload",content:"Upload from Disk",my:"0.5rem",disabled:!0})," "]}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Button.Confirm,{fluid:!0,translucent:!0,lineHeight:3,icon:"trash",content:"Delete All Medical Records",onClick:function(){function D(){return P("del_all_med_records")}return D}()})})]})})},d=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.medical,R=D.printing;return(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{height:"235px",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"General Data",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:R?"spinner":"print",disabled:R,iconSpin:!!R,content:"Print Record",ml:"0.5rem",onClick:function(){function O(){return P("print_record")}return O}()}),children:(0,e.createComponentVNode)(2,v)})}),!M||!M.fields?(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,color:"bad",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,title:"Medical Data",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"pen",content:"Create New Record",onClick:function(){function O(){return P("new_med_record")}return O}()}),children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{bold:!0,grow:!0,textAlign:"center",fontSize:1.75,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,o.Icon.Stack,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"scroll",size:5,color:"gray"}),(0,e.createComponentVNode)(2,o.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"Medical records lost!"]})})})}):(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Medical Data",buttons:(0,e.createComponentVNode)(2,o.Button.Confirm,{icon:"trash",disabled:!!M.empty,content:"Delete Medical Record",onClick:function(){function O(){return P("del_med_record")}return O}()}),children:(0,e.createComponentVNode)(2,h)})}),(0,e.createComponentVNode)(2,C)],4)],0)},v=function(A,x){var E=(0,t.useBackend)(x),P=E.data,D=P.general;return!D||!D.fields?(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,color:"bad",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:"General records lost!"})})}):(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.LabeledList,{children:D.fields.map(function(M,R){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:M.field,children:[(0,e.createComponentVNode)(2,o.Box,{height:"20px",inline:!0,children:M.value}),!!M.edit&&(0,e.createComponentVNode)(2,o.Button,{icon:"pen",ml:"0.5rem",onClick:function(){function O(){return c(x,M)}return O}()})]},R)})})}),!!D.has_photos&&D.photos.map(function(M,R){return(0,e.createComponentVNode)(2,o.Stack.Item,{inline:!0,textAlign:"center",color:"label",ml:0,children:[(0,e.createVNode)(1,"img",null,null,1,{src:M,style:{width:"96px","margin-top":"2.5rem","margin-bottom":"0.5rem","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"}}),(0,e.createVNode)(1,"br"),"Photo #",R+1]},R)})]})},h=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.medical;return!M||!M.fields?(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,color:"bad",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:"Medical records lost!"})})}):(0,e.createComponentVNode)(2,o.Stack,{children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.LabeledList,{children:M.fields.map(function(R,O){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:R.field,preserveWhitespace:!0,children:[(0,a.decodeHtmlEntities)(R.value),!!R.edit&&(0,e.createComponentVNode)(2,o.Button,{icon:"pen",ml:"0.5rem",mb:R.line_break?"1rem":"initial",onClick:function(){function F(){return c(x,R)}return F}()})]},O)})})})})},C=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.medical;return(0,e.createComponentVNode)(2,o.Stack.Item,{height:"150px",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Comments/Log",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"comment",content:"Add Entry",onClick:function(){function R(){return(0,f.modalOpen)(x,"add_comment")}return R}()}),children:M.comments.length===0?(0,e.createComponentVNode)(2,o.Box,{color:"label",children:"No comments found."}):M.comments.map(function(R,O){return(0,e.createComponentVNode)(2,o.Box,{children:[(0,e.createComponentVNode)(2,o.Box,{color:"label",inline:!0,children:R.header}),(0,e.createVNode)(1,"br"),R.text,(0,e.createComponentVNode)(2,o.Button,{icon:"comment-slash",color:"bad",ml:"0.5rem",onClick:function(){function F(){return P("del_comment",{del_comment:O+1})}return F}()})]},O)})})})},p=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.virus,R=(0,t.useLocalState)(x,"searchText",""),O=R[0],F=R[1],_=(0,t.useLocalState)(x,"sortId2","name"),U=_[0],z=_[1],$=(0,t.useLocalState)(x,"sortOrder2",!0),G=$[0],X=$[1];return(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Input,{ml:"0.25rem",fluid:!0,placeholder:"Search by Name, Max Stages, or Severity",onInput:function(){function J(se,ie){return F(ie)}return J}()})}),(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,mt:.5,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,o.Table,{className:"MedicalRecords__list",children:[(0,e.createComponentVNode)(2,o.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,B,{id:"name",children:"Name"}),(0,e.createComponentVNode)(2,B,{id:"max_stages",children:"Max Stages"}),(0,e.createComponentVNode)(2,B,{id:"severity",children:"Severity"})]}),M.filter((0,a.createSearch)(O,function(J){return J.name+"|"+J.max_stages+"|"+J.severity})).sort(function(J,se){var ie=G?1:-1;return J[U].localeCompare(se[U])*ie}).map(function(J){return(0,e.createComponentVNode)(2,o.Table.Row,{className:"MedicalRecords__listVirus--"+J.severity,onClick:function(){function se(){return P("vir",{vir:J.D})}return se}(),children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"virus"})," ",J.name]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:J.max_stages}),(0,e.createComponentVNode)(2,o.Table.Cell,{color:g[J.severity],children:J.severity})]},J.id)})]})})})})],4)},N=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.goals;return(0,e.createComponentVNode)(2,o.Section,{title:"Virology Goals",fill:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:M.length!==0&&M.map(function(R){return(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{title:R.name,children:[(0,e.createComponentVNode)(2,o.Table,{children:(0,e.createComponentVNode)(2,o.Table.Row,{header:!0,children:(0,e.createComponentVNode)(2,o.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,o.ProgressBar,{value:R.delivered,minValue:0,maxValue:R.deliverygoal,ranges:{good:[R.deliverygoal*.5,1/0],average:[R.deliverygoal*.25,R.deliverygoal*.5],bad:[-1/0,R.deliverygoal*.25]},children:[R.delivered," / ",R.deliverygoal," Units"]})})})}),(0,e.createComponentVNode)(2,o.Box,{children:R.report})]})},R.id)})||(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Box,{textAlign:"center",children:"No Goals Detected"})})})})},V=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.medbots;return M.length===0?(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,color:"bad",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{bold:!0,grow:!0,textAlign:"center",fontSize:1.75,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,o.Icon.Stack,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"robot",size:5,color:"gray"}),(0,e.createComponentVNode)(2,o.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"There are no Medibots."]})})})}):(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,o.Table,{className:"MedicalRecords__list",children:[(0,e.createComponentVNode)(2,o.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Name"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Area"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Status"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Chemicals"})]}),M.map(function(R){return(0,e.createComponentVNode)(2,o.Table.Row,{className:"MedicalRecords__listMedbot--"+R.on,children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"medical"})," ",R.name]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:[R.area||"Unknown"," (",R.x,", ",R.y,")"]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:R.on?(0,e.createComponentVNode)(2,o.Box,{color:"good",children:"Online"}):(0,e.createComponentVNode)(2,o.Box,{color:"average",children:"Offline"})}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:R.use_beaker?"Reservoir: "+R.total_volume+"/"+R.maximum_volume:"Using internal synthesizer"})]},R.id)})]})})})},S=function(A,x){var E=(0,t.useLocalState)(x,"sortId","name"),P=E[0],D=E[1],M=(0,t.useLocalState)(x,"sortOrder",!0),R=M[0],O=M[1],F=A.id,_=A.children;return(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{fluid:!0,color:P!==F&&"transparent",onClick:function(){function U(){P===F?O(!R):(D(F),O(!0))}return U}(),children:[_,P===F&&(0,e.createComponentVNode)(2,o.Icon,{name:R?"sort-up":"sort-down",ml:"0.25rem;"})]})})},B=function(A,x){var E=(0,t.useLocalState)(x,"sortId2","name"),P=E[0],D=E[1],M=(0,t.useLocalState)(x,"sortOrder2",!0),R=M[0],O=M[1],F=A.id,_=A.children;return(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{fluid:!0,color:P!==F&&"transparent",onClick:function(){function U(){P===F?O(!R):(D(F),O(!0))}return U}(),children:[_,P===F&&(0,e.createComponentVNode)(2,o.Icon,{name:R?"sort-up":"sort-down",ml:"0.25rem;"})]})})},L=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.screen,R=D.general;return(0,e.createComponentVNode)(2,o.Stack.Item,{m:0,children:(0,e.createComponentVNode)(2,o.Tabs,{children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"list",selected:M===2,onClick:function(){function O(){P("screen",{screen:2})}return O}(),children:"List Records"}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"database",selected:M===5,onClick:function(){function O(){P("screen",{screen:5})}return O}(),children:"Virus Database"}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"vial",selected:M===6,onClick:function(){function O(){P("screen",{screen:6})}return O}(),children:"Virology Goals"}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"plus-square",selected:M===7,onClick:function(){function O(){return P("screen",{screen:7})}return O}(),children:"Medibot Tracking"}),M===3&&(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"wrench",selected:M===3,children:"Record Maintenance"}),M===4&&R&&!R.empty&&(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"file",selected:M===4,children:["Record: ",R.fields[0].value]})]})})};(0,f.modalRegisterBodyOverride)("virus",m)},54989:function(T,r,n){"use strict";r.__esModule=!0,r.MerchVendor=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=g.product,s=g.productImage,d=g.productCategory,v=i.user_money;return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,children:(0,e.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+s,style:{"vertical-align":"middle",width:"32px",margin:"0px","margin-left":"0px"}})}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:u.name}),(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{disabled:u.price>v,icon:"shopping-cart",content:u.price,textAlign:"left",onClick:function(){function h(){return m("purchase",{name:u.name,category:d})}return h}()})})]})},b=function(g,l){var c=(0,a.useBackend)(l),m=c.data,i=(0,a.useLocalState)(l,"tabIndex",1),u=i[0],s=m.products,d=m.imagelist,v=["apparel","toy","decoration"];return(0,e.createComponentVNode)(2,t.Table,{children:s[v[u]].map(function(h){return(0,e.createComponentVNode)(2,f,{product:h,productImage:d[h.path],productCategory:v[u]},h.name)})})},y=r.MerchVendor=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.user_cash,s=i.inserted_cash;return(0,e.createComponentVNode)(2,o.Window,{title:"Merch Computer",width:450,height:600,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"User",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{color:"light-grey",inline:!0,mr:"0.5rem",children:["There is ",(0,e.createVNode)(1,"b",null,s,0)," credits inserted."]}),(0,e.createComponentVNode)(2,t.Button,{disabled:!s,icon:"money-bill-wave-alt",content:"Dispense Change",textAlign:"left",onClick:function(){function d(){return m("change")}return d}()})],4),children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:["Doing your job and not getting any recognition at work? Well, welcome to the merch shop! Here, you can buy cool things in exchange for money you earn when you have completed your Job Objectives.",u!==null&&(0,e.createComponentVNode)(2,t.Box,{mt:"0.5rem",children:["Your balance is ",(0,e.createVNode)(1,"b",null,[u||0,(0,e.createTextVNode)(" credits")],0),"."]})]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Products",children:[(0,e.createComponentVNode)(2,I),(0,e.createComponentVNode)(2,b)]})})]})})})}return k}(),I=function(g,l){var c=(0,a.useBackend)(l),m=c.data,i=(0,a.useLocalState)(l,"tabIndex",1),u=i[0],s=i[1],d=m.login_state;return(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"dice",selected:u===1,onClick:function(){function v(){return s(1)}return v}(),children:"Toys"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"flag",selected:u===2,onClick:function(){function v(){return s(2)}return v}(),children:"Decorations"})]})}},87684:function(T,r,n){"use strict";r.__esModule=!0,r.MiningVendor=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),f=n(98595),b=["title","items","gridLayout"];function y(i,u){if(i==null)return{};var s={};for(var d in i)if({}.hasOwnProperty.call(i,d)){if(u.includes(d))continue;s[d]=i[d]}return s}var I={Alphabetical:function(){function i(u,s){return u-s}return i}(),Availability:function(){function i(u,s){return-(u.affordable-s.affordable)}return i}(),Price:function(){function i(u,s){return u.price-s.price}return i}()},k=r.MiningVendor=function(){function i(u,s){var d=(0,t.useLocalState)(s,"gridLayout",!1),v=d[0],h=d[1];return(0,e.createComponentVNode)(2,f.Window,{width:400,height:525,children:(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,g),(0,e.createComponentVNode)(2,c,{gridLayout:v,setGridLayout:h}),(0,e.createComponentVNode)(2,l,{gridLayout:v})]})})})}return i}(),g=function(u,s){var d=(0,t.useBackend)(s),v=d.act,h=d.data,C=h.has_id,p=h.id;return(0,e.createComponentVNode)(2,o.NoticeBox,{success:C,children:C?(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Box,{inline:!0,verticalAlign:"middle",style:{float:"left"},children:["Logged in as ",p.name,".",(0,e.createVNode)(1,"br"),"You have ",p.points.toLocaleString("en-US")," points."]}),(0,e.createComponentVNode)(2,o.Button,{icon:"eject",content:"Eject ID",style:{float:"right"},onClick:function(){function N(){return v("logoff")}return N}()}),(0,e.createComponentVNode)(2,o.Box,{style:{clear:"both"}})],4):"Please insert an ID in order to make purchases."})},l=function(u,s){var d=(0,t.useBackend)(s),v=d.act,h=d.data,C=h.has_id,p=h.id,N=h.items,V=u.gridLayout,S=(0,t.useLocalState)(s,"search",""),B=S[0],L=S[1],w=(0,t.useLocalState)(s,"sort","Alphabetical"),A=w[0],x=w[1],E=(0,t.useLocalState)(s,"descending",!1),P=E[0],D=E[1],M=(0,a.createSearch)(B,function(F){return F[0]}),R=!1,O=Object.entries(N).map(function(F,_){var U=Object.entries(F[1]).filter(M).map(function(z){return z[1].affordable=C&&p.points>=z[1].price,z[1]}).sort(I[A]);if(U.length!==0)return P&&(U=U.reverse()),R=!0,(0,e.createComponentVNode)(2,m,{title:F[0],items:U,gridLayout:V},F[0])});return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,mt:.5,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,children:R?O:(0,e.createComponentVNode)(2,o.Box,{color:"label",children:"No items matching your criteria was found!"})})})},c=function(u,s){var d=u.gridLayout,v=u.setGridLayout,h=(0,t.useLocalState)(s,"search",""),C=h[0],p=h[1],N=(0,t.useLocalState)(s,"sort",""),V=N[0],S=N[1],B=(0,t.useLocalState)(s,"descending",!1),L=B[0],w=B[1];return(0,e.createComponentVNode)(2,o.Box,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Input,{mt:.2,placeholder:"Search by item name..",width:"100%",onInput:function(){function A(x,E){return p(E)}return A}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{icon:d?"list":"table-cells-large",height:1.75,tooltip:d?"Toggle List Layout":"Toggle Grid Layout",tooltipPosition:"bottom-start",onClick:function(){function A(){return v(!d)}return A}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"30%",children:(0,e.createComponentVNode)(2,o.Dropdown,{selected:"Alphabetical",options:Object.keys(I),width:"100%",onSelected:function(){function A(x){return S(x)}return A}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{icon:L?"arrow-down":"arrow-up",height:1.75,tooltip:L?"Descending order":"Ascending order",tooltipPosition:"bottom-start",onClick:function(){function A(){return w(!L)}return A}()})})]})})},m=function(u,s){var d=(0,t.useBackend)(s),v=d.act,h=d.data,C=u.title,p=u.items,N=u.gridLayout,V=y(u,b);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Collapsible,Object.assign({open:!0,title:C},V,{children:p.map(function(S){return N?(0,e.createComponentVNode)(2,o.ImageButton,{mb:.5,imageSize:57.5,dmIcon:S.icon,dmIconState:S.icon_state,disabled:!h.has_id||h.id.points0&&(0,e.createComponentVNode)(2,o.Box,{className:"Newscaster__menuButton--unread",children:ae>=10?"9+":ae})}),(0,e.createComponentVNode)(2,s,{icon:"briefcase",title:"Job Openings",selected:O===1,onClick:function(){function le(){return x("jobs")}return le}()}),(0,e.createComponentVNode)(2,o.Divider)]}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:F.map(function(le){return(0,e.createComponentVNode)(2,s,{icon:le.icon,title:le.name,selected:O===2&&F[U-1]===le,onClick:function(){function Z(){return x("channel",{uid:le.uid})}return Z}(),children:le.unread>0&&(0,e.createComponentVNode)(2,o.Box,{className:"Newscaster__menuButton--unread",children:le.unread>=10?"9+":le.unread})},le)})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:[(0,e.createComponentVNode)(2,o.Divider),(!!P||!!D)&&(0,e.createFragment)([(0,e.createComponentVNode)(2,s,{security:!0,icon:"exclamation-circle",title:"Edit Wanted Notice",mb:"0.5rem",onClick:function(){function le(){return(0,y.modalOpen)(w,"wanted_notice")}return le}()}),(0,e.createComponentVNode)(2,s,{security:!0,icon:me?"minus-square":"minus-square-o",title:"Censor Mode: "+(me?"On":"Off"),mb:"0.5rem",onClick:function(){function le(){return q(!me)}return le}()}),(0,e.createComponentVNode)(2,o.Divider)],4),(0,e.createComponentVNode)(2,s,{icon:"pen-alt",title:"New Story",mb:"0.5rem",onClick:function(){function le(){return(0,y.modalOpen)(w,"create_story")}return le}()}),(0,e.createComponentVNode)(2,s,{icon:"plus-circle",title:"New Channel",onClick:function(){function le(){return(0,y.modalOpen)(w,"create_channel")}return le}()}),(0,e.createComponentVNode)(2,o.Divider),(0,e.createComponentVNode)(2,s,{icon:R?"spinner":"print",iconSpin:R,title:R?"Printing...":"Print Newspaper",onClick:function(){function le(){return x("print_newspaper")}return le}()}),(0,e.createComponentVNode)(2,s,{icon:M?"volume-mute":"volume-up",title:"Mute: "+(M?"On":"Off"),onClick:function(){function le(){return x("toggle_mute")}return le}()})]})]})}),(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,width:"100%",children:[(0,e.createComponentVNode)(2,I.TemporaryNotice),re]})]})})]})}return B}(),s=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=L.icon,P=E===void 0?"":E,D=L.iconSpin,M=L.selected,R=M===void 0?!1:M,O=L.security,F=O===void 0?!1:O,_=L.onClick,U=L.title,z=L.children,$=l(L,k);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Box,Object.assign({className:(0,a.classes)(["Newscaster__menuButton",R&&"Newscaster__menuButton--selected",F&&"Newscaster__menuButton--security"]),onClick:_},$,{children:[R&&(0,e.createComponentVNode)(2,o.Box,{className:"Newscaster__menuButton--selectedBar"}),(0,e.createComponentVNode)(2,o.Icon,{name:P,spin:D,size:"2"}),(0,e.createComponentVNode)(2,o.Box,{className:"Newscaster__menuButton--title",children:U}),z]})))},d=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=A.data,P=E.screen,D=E.is_admin,M=E.channel_idx,R=E.channel_can_manage,O=E.channels,F=E.stories,_=E.wanted,U=(0,t.useLocalState)(w,"fullStories",[]),z=U[0],$=U[1],G=(0,t.useLocalState)(w,"censorMode",!1),X=G[0],J=G[1],se=P===2&&M>-1?O[M-1]:null;return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[!!_&&(0,e.createComponentVNode)(2,h,{story:_,wanted:!0}),(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Icon,{name:se?se.icon:"newspaper",mr:"0.5rem"}),se?se.name:"Headlines"],0),children:F.length>0?F.slice().reverse().map(function(ie){return!z.includes(ie.uid)&&ie.body.length+3>c?Object.assign({},ie,{body_short:ie.body.substr(0,c-4)+"..."}):ie}).map(function(ie,me){return(0,e.createComponentVNode)(2,h,{story:ie},me)}):(0,e.createComponentVNode)(2,o.Box,{className:"Newscaster__emptyNotice",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"times",size:"3"}),(0,e.createVNode)(1,"br"),"There are no stories at this time."]})}),!!se&&(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,height:"40%",title:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Icon,{name:"info-circle",mr:"0.5rem"}),(0,e.createTextVNode)("About")],4),buttons:(0,e.createFragment)([X&&(0,e.createComponentVNode)(2,o.Button,{disabled:!!se.admin&&!D,selected:se.censored,icon:se.censored?"comment-slash":"comment",content:se.censored?"Uncensor Channel":"Censor Channel",mr:"0.5rem",onClick:function(){function ie(){return x("censor_channel",{uid:se.uid})}return ie}()}),(0,e.createComponentVNode)(2,o.Button,{disabled:!R,icon:"cog",content:"Manage",onClick:function(){function ie(){return(0,y.modalOpen)(w,"manage_channel",{uid:se.uid})}return ie}()})],0),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Description",children:se.description||"N/A"}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Owner",children:se.author||"N/A"}),!!D&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Ckey",children:se.author_ckey}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Public",children:se.public?"Yes":"No"}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Total Views",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"eye",mr:"0.5rem"}),F.reduce(function(ie,me){return ie+me.view_count},0).toLocaleString()]})]})})]})},v=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=A.data,P=E.jobs,D=E.wanted,M=Object.entries(P).reduce(function(R,O){var F=O[0],_=O[1];return R+_.length},0);return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[!!D&&(0,e.createComponentVNode)(2,h,{story:D,wanted:!0}),(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Icon,{name:"briefcase",mr:"0.5rem"}),(0,e.createTextVNode)("Job Openings")],4),buttons:(0,e.createComponentVNode)(2,o.Box,{mt:"0.25rem",color:"label",children:"Work for a better future at Nanotrasen"}),children:M>0?m.map(function(R){return Object.assign({},i[R],{id:R,jobs:P[R]})}).filter(function(R){return!!R&&R.jobs.length>0}).map(function(R){return(0,e.createComponentVNode)(2,o.Section,{className:(0,a.classes)(["Newscaster__jobCategory","Newscaster__jobCategory--"+R.id]),title:R.title,buttons:(0,e.createComponentVNode)(2,o.Box,{mt:"0.25rem",color:"label",children:R.fluff_text}),children:R.jobs.map(function(O){return(0,e.createComponentVNode)(2,o.Box,{class:(0,a.classes)(["Newscaster__jobOpening",!!O.is_command&&"Newscaster__jobOpening--command"]),children:["\u2022 ",O.title]},O.title)})},R.id)}):(0,e.createComponentVNode)(2,o.Box,{className:"Newscaster__emptyNotice",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"times",size:"3"}),(0,e.createVNode)(1,"br"),"There are no openings at this time."]})}),(0,e.createComponentVNode)(2,o.Section,{height:"17%",children:["Interested in serving Nanotrasen?",(0,e.createVNode)(1,"br"),"Sign up for any of the above position now at the ",(0,e.createVNode)(1,"b",null,"Head of Personnel's Office!",16),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.Box,{as:"small",color:"label",children:"By signing up for a job at Nanotrasen, you agree to transfer your soul to the loyalty department of the omnipresent and helpful watcher of humanity."})]})]})},h=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=A.data,P=L.story,D=L.wanted,M=D===void 0?!1:D,R=E.is_admin,O=(0,t.useLocalState)(w,"fullStories",[]),F=O[0],_=O[1],U=(0,t.useLocalState)(w,"censorMode",!1),z=U[0],$=U[1];return(0,e.createComponentVNode)(2,o.Section,{className:(0,a.classes)(["Newscaster__story",M&&"Newscaster__story--wanted"]),title:(0,e.createFragment)([M&&(0,e.createComponentVNode)(2,o.Icon,{name:"exclamation-circle",mr:"0.5rem"}),P.censor_flags&2&&"[REDACTED]"||P.title||"News from "+P.author],0),buttons:(0,e.createComponentVNode)(2,o.Box,{mt:"0.25rem",children:(0,e.createComponentVNode)(2,o.Box,{color:"label",children:[!M&&z&&(0,e.createComponentVNode)(2,o.Box,{inline:!0,children:(0,e.createComponentVNode)(2,o.Button,{enabled:P.censor_flags&2,icon:P.censor_flags&2?"comment-slash":"comment",content:P.censor_flags&2?"Uncensor":"Censor",mr:"0.5rem",mt:"-0.25rem",onClick:function(){function G(){return x("censor_story",{uid:P.uid})}return G}()})}),(0,e.createComponentVNode)(2,o.Box,{inline:!0,children:[(0,e.createComponentVNode)(2,o.Icon,{name:"user"})," ",P.author," |\xA0",!!R&&(0,e.createFragment)([(0,e.createTextVNode)("ckey: "),P.author_ckey,(0,e.createTextVNode)(" |\xA0")],0),!M&&(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Icon,{name:"eye"}),(0,e.createTextVNode)(" "),P.view_count.toLocaleString(),(0,e.createTextVNode)(" |\xA0")],0),(0,e.createComponentVNode)(2,o.Icon,{name:"clock"})," ",(0,f.timeAgo)(P.publish_time,E.world_time)]})]})}),children:(0,e.createComponentVNode)(2,o.Box,{children:P.censor_flags&2?"[REDACTED]":(0,e.createFragment)([!!P.has_photo&&(0,e.createComponentVNode)(2,C,{name:"story_photo_"+P.uid+".png",float:"right",ml:"0.5rem"}),(P.body_short||P.body).split("\n").map(function(G,X){return(0,e.createComponentVNode)(2,o.Box,{children:G||(0,e.createVNode)(1,"br")},X)}),P.body_short&&(0,e.createComponentVNode)(2,o.Button,{content:"Read more..",mt:"0.5rem",onClick:function(){function G(){return _([].concat(F,[P.uid]))}return G}()}),(0,e.createComponentVNode)(2,o.Box,{clear:"right"})],0)})})},C=function(L,w){var A=L.name,x=l(L,g),E=(0,t.useLocalState)(w,"viewingPhoto",""),P=E[0],D=E[1];return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Box,Object.assign({as:"img",className:"Newscaster__photo",src:A,onClick:function(){function M(){return D(A)}return M}()},x)))},p=function(L,w){var A=(0,t.useLocalState)(w,"viewingPhoto",""),x=A[0],E=A[1];return(0,e.createComponentVNode)(2,o.Modal,{className:"Newscaster__photoZoom",children:[(0,e.createComponentVNode)(2,o.Box,{as:"img",src:x}),(0,e.createComponentVNode)(2,o.Button,{icon:"times",content:"Close",color:"grey",mt:"1rem",onClick:function(){function P(){return E("")}return P}()})]})},N=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=A.data,P=!!L.args.uid&&E.channels.filter(function(te){return te.uid===L.args.uid}).pop();if(L.id==="manage_channel"&&!P){(0,y.modalClose)(w);return}var D=L.id==="manage_channel",M=!!L.args.is_admin,R=L.args.scanned_user,O=(0,t.useLocalState)(w,"author",(P==null?void 0:P.author)||R||"Unknown"),F=O[0],_=O[1],U=(0,t.useLocalState)(w,"name",(P==null?void 0:P.name)||""),z=U[0],$=U[1],G=(0,t.useLocalState)(w,"description",(P==null?void 0:P.description)||""),X=G[0],J=G[1],se=(0,t.useLocalState)(w,"icon",(P==null?void 0:P.icon)||"newspaper"),ie=se[0],me=se[1],q=(0,t.useLocalState)(w,"isPublic",D?!!(P!=null&&P.public):!1),re=q[0],ae=q[1],le=(0,t.useLocalState)(w,"adminLocked",(P==null?void 0:P.admin)===1||!1),Z=le[0],ne=le[1];return(0,e.createComponentVNode)(2,o.Section,{m:"-1rem",pb:"1.5rem",title:D?"Manage "+P.name:"Create New Channel",children:[(0,e.createComponentVNode)(2,o.Box,{mx:"0.5rem",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Owner",children:(0,e.createComponentVNode)(2,o.Input,{disabled:!M,width:"100%",value:F,onInput:function(){function te(fe,pe){return _(pe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Name",children:(0,e.createComponentVNode)(2,o.Input,{width:"100%",placeholder:"50 characters max.",maxLength:"50",value:z,onInput:function(){function te(fe,pe){return $(pe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Description (optional)",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Input,{multiline:!0,width:"100%",placeholder:"128 characters max.",maxLength:"128",value:X,onInput:function(){function te(fe,pe){return J(pe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Icon",children:[(0,e.createComponentVNode)(2,o.Input,{disabled:!M,value:ie,width:"35%",mr:"0.5rem",onInput:function(){function te(fe,pe){return me(pe)}return te}()}),(0,e.createComponentVNode)(2,o.Icon,{name:ie,size:"2",verticalAlign:"middle",mr:"0.5rem"})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Accept Public Stories?",children:(0,e.createComponentVNode)(2,o.Button,{selected:re,icon:re?"toggle-on":"toggle-off",content:re?"Yes":"No",onClick:function(){function te(){return ae(!re)}return te}()})}),M&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"CentComm Lock",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Button,{selected:Z,icon:Z?"lock":"lock-open",content:Z?"On":"Off",tooltip:"Locking this channel will make it editable by nobody but CentComm officers.",tooltipPosition:"top",onClick:function(){function te(){return ne(!Z)}return te}()})})]})}),(0,e.createComponentVNode)(2,o.Button.Confirm,{disabled:F.trim().length===0||z.trim().length===0,icon:"check",color:"good",content:"Submit",position:"absolute",right:"1rem",bottom:"-0.75rem",onClick:function(){function te(){(0,y.modalAnswer)(w,L.id,"",{author:F,name:z.substr(0,49),description:X.substr(0,128),icon:ie,public:re?1:0,admin_locked:Z?1:0})}return te}()})]})},V=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=A.data,P=E.photo,D=E.channels,M=E.channel_idx,R=M===void 0?-1:M,O=!!L.args.is_admin,F=L.args.scanned_user,_=D.slice().sort(function(te,fe){if(R<0)return 0;var pe=D[R-1];if(pe.uid===te.uid)return-1;if(pe.uid===fe.uid)return 1}).filter(function(te){return O||!te.frozen&&(te.author===F||!!te.public)}),U=(0,t.useLocalState)(w,"author",F||"Unknown"),z=U[0],$=U[1],G=(0,t.useLocalState)(w,"channel",_.length>0?_[0].name:""),X=G[0],J=G[1],se=(0,t.useLocalState)(w,"title",""),ie=se[0],me=se[1],q=(0,t.useLocalState)(w,"body",""),re=q[0],ae=q[1],le=(0,t.useLocalState)(w,"adminLocked",!1),Z=le[0],ne=le[1];return(0,e.createComponentVNode)(2,o.Section,{m:"-1rem",pb:"1.5rem",title:"Create New Story",children:[(0,e.createComponentVNode)(2,o.Box,{mx:"0.5rem",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Author",children:(0,e.createComponentVNode)(2,o.Input,{disabled:!O,width:"100%",value:z,onInput:function(){function te(fe,pe){return $(pe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Channel",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Dropdown,{selected:X,options:_.map(function(te){return te.name}),mb:"0",width:"100%",onSelected:function(){function te(fe){return J(fe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Divider),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Title",children:(0,e.createComponentVNode)(2,o.Input,{width:"100%",placeholder:"128 characters max.",maxLength:"128",value:ie,onInput:function(){function te(fe,pe){return me(pe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Story Text",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Input,{fluid:!0,multiline:!0,placeholder:"1024 characters max.",maxLength:"1024",rows:"8",width:"100%",value:re,onInput:function(){function te(fe,pe){return ae(pe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Photo (optional)",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Button,{icon:"image",selected:P,content:P?"Eject: "+P.name:"Insert Photo",tooltip:!P&&"Attach a photo to this story by holding the photograph in your hand.",onClick:function(){function te(){return x(P?"eject_photo":"attach_photo")}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Preview",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Section,{noTopPadding:!0,title:ie,maxHeight:"13.5rem",overflow:"auto",children:(0,e.createComponentVNode)(2,o.Box,{mt:"0.5rem",children:[!!P&&(0,e.createComponentVNode)(2,C,{name:"inserted_photo_"+P.uid+".png",float:"right"}),re.split("\n").map(function(te,fe){return(0,e.createComponentVNode)(2,o.Box,{children:te||(0,e.createVNode)(1,"br")},fe)}),(0,e.createComponentVNode)(2,o.Box,{clear:"right"})]})})}),O&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"CentComm Lock",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Button,{selected:Z,icon:Z?"lock":"lock-open",content:Z?"On":"Off",tooltip:"Locking this story will make it censorable by nobody but CentComm officers.",tooltipPosition:"top",onClick:function(){function te(){return ne(!Z)}return te}()})})]})}),(0,e.createComponentVNode)(2,o.Button.Confirm,{disabled:z.trim().length===0||X.trim().length===0||ie.trim().length===0||re.trim().length===0,icon:"check",color:"good",content:"Submit",position:"absolute",right:"1rem",bottom:"-0.75rem",onClick:function(){function te(){(0,y.modalAnswer)(w,"create_story","",{author:z,channel:X,title:ie.substr(0,127),body:re.substr(0,1023),admin_locked:Z?1:0})}return te}()})]})},S=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=A.data,P=E.photo,D=E.wanted,M=!!L.args.is_admin,R=L.args.scanned_user,O=(0,t.useLocalState)(w,"author",(D==null?void 0:D.author)||R||"Unknown"),F=O[0],_=O[1],U=(0,t.useLocalState)(w,"name",(D==null?void 0:D.title.substr(8))||""),z=U[0],$=U[1],G=(0,t.useLocalState)(w,"description",(D==null?void 0:D.body)||""),X=G[0],J=G[1],se=(0,t.useLocalState)(w,"adminLocked",(D==null?void 0:D.admin_locked)===1||!1),ie=se[0],me=se[1];return(0,e.createComponentVNode)(2,o.Section,{m:"-1rem",pb:"1.5rem",title:"Manage Wanted Notice",children:[(0,e.createComponentVNode)(2,o.Box,{mx:"0.5rem",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Authority",children:(0,e.createComponentVNode)(2,o.Input,{disabled:!M,width:"100%",value:F,onInput:function(){function q(re,ae){return _(ae)}return q}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Name",children:(0,e.createComponentVNode)(2,o.Input,{width:"100%",value:z,maxLength:"128",onInput:function(){function q(re,ae){return $(ae)}return q}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Description",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Input,{multiline:!0,width:"100%",value:X,maxLength:"512",rows:"4",onInput:function(){function q(re,ae){return J(ae)}return q}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Photo (optional)",verticalAlign:"top",children:[(0,e.createComponentVNode)(2,o.Button,{icon:"image",selected:P,content:P?"Eject: "+P.name:"Insert Photo",tooltip:!P&&"Attach a photo to this wanted notice by holding the photograph in your hand.",tooltipPosition:"top",onClick:function(){function q(){return x(P?"eject_photo":"attach_photo")}return q}()}),!!P&&(0,e.createComponentVNode)(2,C,{name:"inserted_photo_"+P.uid+".png",float:"right"})]}),M&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"CentComm Lock",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Button,{selected:ie,icon:ie?"lock":"lock-open",content:ie?"On":"Off",tooltip:"Locking this wanted notice will make it editable by nobody but CentComm officers.",tooltipPosition:"top",onClick:function(){function q(){return me(!ie)}return q}()})})]})}),(0,e.createComponentVNode)(2,o.Button.Confirm,{disabled:!D,icon:"eraser",color:"danger",content:"Clear",position:"absolute",right:"7.25rem",bottom:"-0.75rem",onClick:function(){function q(){x("clear_wanted_notice"),(0,y.modalClose)(w)}return q}()}),(0,e.createComponentVNode)(2,o.Button.Confirm,{disabled:F.trim().length===0||z.trim().length===0||X.trim().length===0,icon:"check",color:"good",content:"Submit",position:"absolute",right:"1rem",bottom:"-0.75rem",onClick:function(){function q(){(0,y.modalAnswer)(w,L.id,"",{author:F,name:z.substr(0,127),description:X.substr(0,511),admin_locked:ie?1:0})}return q}()})]})};(0,y.modalRegisterBodyOverride)("create_channel",N),(0,y.modalRegisterBodyOverride)("manage_channel",N),(0,y.modalRegisterBodyOverride)("create_story",V),(0,y.modalRegisterBodyOverride)("wanted_notice",S)},48286:function(T,r,n){"use strict";r.__esModule=!0,r.Noticeboard=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),f=n(98595),b=r.Noticeboard=function(){function y(I,k){var g=(0,t.useBackend)(k),l=g.act,c=g.data,m=c.papers;return(0,e.createComponentVNode)(2,f.Window,{width:600,height:300,theme:"noticeboard",children:(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:m.map(function(i){return(0,e.createComponentVNode)(2,o.Stack.Item,{align:"center",width:"22.45%",height:"85%",onClick:function(){function u(){return l("interact",{paper:i.ref})}return u}(),onContextMenu:function(){function u(s){s.preventDefault(),l("showFull",{paper:i.ref})}return u}(),children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,fontSize:.75,title:i.name,children:(0,a.decodeHtmlEntities)(i.contents)})},i.ref)})})})})}return y}()},41166:function(T,r,n){"use strict";r.__esModule=!0,r.NuclearBomb=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.NuclearBomb=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data;return l.extended?(0,e.createComponentVNode)(2,o.Window,{width:350,height:290,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Authorization",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Auth Disk",children:(0,e.createComponentVNode)(2,t.Button,{icon:l.authdisk?"eject":"id-card",selected:l.authdisk,content:l.diskname?l.diskname:"-----",tooltip:l.authdisk?"Eject Disk":"Insert Disk",onClick:function(){function c(){return g("auth")}return c}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Auth Code",children:(0,e.createComponentVNode)(2,t.Button,{icon:"key",disabled:!l.authdisk,selected:l.authcode,content:l.codemsg,onClick:function(){function c(){return g("code")}return c}()})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Arming & Disarming",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Bolted to floor",children:(0,e.createComponentVNode)(2,t.Button,{icon:l.anchored?"check":"times",selected:l.anchored,disabled:!l.authdisk,content:l.anchored?"YES":"NO",onClick:function(){function c(){return g("toggle_anchor")}return c}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Time Left",children:(0,e.createComponentVNode)(2,t.Button,{icon:"stopwatch",content:l.time,disabled:!l.authfull,tooltip:"Set Timer",onClick:function(){function c(){return g("set_time")}return c}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Safety",children:(0,e.createComponentVNode)(2,t.Button,{icon:l.safety?"check":"times",selected:l.safety,disabled:!l.authfull,content:l.safety?"ON":"OFF",tooltip:l.safety?"Disable Safety":"Enable Safety",onClick:function(){function c(){return g("toggle_safety")}return c}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Arm/Disarm",children:(0,e.createComponentVNode)(2,t.Button,{icon:(l.timer,"bomb"),disabled:l.safety||!l.authfull,color:"red",content:l.timer?"DISARM THE NUKE":"ARM THE NUKE",onClick:function(){function c(){return g("toggle_armed")}return c}()})})]})})]})}):(0,e.createComponentVNode)(2,o.Window,{width:350,height:115,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Deployment",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"exclamation-triangle",content:"Deploy Nuclear Device (will bolt device to floor)",onClick:function(){function c(){return g("deploy")}return c}()})})})})}return b}()},52416:function(T,r,n){"use strict";r.__esModule=!0,r.NumberInputModal=void 0;var e=n(89005),a=n(51057),t=n(19203),o=n(92986),f=n(72253),b=n(36036),y=n(98595),I=r.NumberInputModal=function(){function g(l,c){var m=(0,f.useBackend)(c),i=m.act,u=m.data,s=u.init_value,d=u.large_buttons,v=u.message,h=v===void 0?"":v,C=u.timeout,p=u.title,N=(0,f.useLocalState)(c,"input",s),V=N[0],S=N[1],B=function(){function A(x){x!==V&&S(x)}return A}(),L=function(){function A(x){x!==V&&S(x)}return A}(),w=140+Math.max(Math.ceil(h.length/3),h.length>0&&d?5:0);return(0,e.createComponentVNode)(2,y.Window,{title:p,width:270,height:w,children:[C&&(0,e.createComponentVNode)(2,a.Loader,{value:C}),(0,e.createComponentVNode)(2,y.Window.Content,{onKeyDown:function(){function A(x){var E=window.event?x.which:x.keyCode;E===o.KEY_ENTER&&i("submit",{entry:V}),E===o.KEY_ESCAPE&&i("cancel")}return A}(),children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,children:(0,e.createComponentVNode)(2,b.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.Box,{color:"label",children:h})}),(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,k,{input:V,onClick:L,onChange:B})}),(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,t.InputButtons,{input:V})})]})})})]})}return g}(),k=function(l,c){var m=(0,f.useBackend)(c),i=m.act,u=m.data,s=u.min_value,d=u.max_value,v=u.init_value,h=u.round_value,C=l.input,p=l.onClick,N=l.onChange,V=Math.round(C!==s?Math.max(C/2,s):d/2),S=C===s&&s>0||C===1;return(0,e.createComponentVNode)(2,b.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Button,{disabled:C===s,icon:"angle-double-left",onClick:function(){function B(){return p(s)}return B}(),tooltip:C===s?"Min":"Min ("+s+")"})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.RestrictedInput,{autoFocus:!0,autoSelect:!0,fluid:!0,allowFloats:!h,minValue:s,maxValue:d,onChange:function(){function B(L,w){return N(w)}return B}(),onEnter:function(){function B(L,w){return i("submit",{entry:w})}return B}(),value:C})}),(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Button,{disabled:C===d,icon:"angle-double-right",onClick:function(){function B(){return p(d)}return B}(),tooltip:C===d?"Max":"Max ("+d+")"})}),(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Button,{disabled:S,icon:"divide",onClick:function(){function B(){return p(V)}return B}(),tooltip:S?"Split":"Split ("+V+")"})}),(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Button,{disabled:C===v,icon:"redo",onClick:function(){function B(){return p(v)}return B}(),tooltip:v?"Reset ("+v+")":"Reset"})})]})}},1218:function(T,r,n){"use strict";r.__esModule=!0,r.OperatingComputer=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(98595),f=n(36036),b=[["good","Conscious"],["average","Unconscious"],["bad","DEAD"]],y=[["Resp.","oxyLoss"],["Toxin","toxLoss"],["Brute","bruteLoss"],["Burn","fireLoss"]],I={average:[.25,.5],bad:[.5,1/0]},k=["bad","average","average","good","average","average","bad"],g=r.OperatingComputer=function(){function i(u,s){var d=(0,t.useBackend)(s),v=d.act,h=d.data,C=h.hasOccupant,p=h.choice,N;return p?N=(0,e.createComponentVNode)(2,m):N=C?(0,e.createComponentVNode)(2,l):(0,e.createComponentVNode)(2,c),(0,e.createComponentVNode)(2,o.Window,{width:650,height:455,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,f.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,f.Stack.Item,{children:(0,e.createComponentVNode)(2,f.Tabs,{children:[(0,e.createComponentVNode)(2,f.Tabs.Tab,{selected:!p,icon:"user",onClick:function(){function V(){return v("choiceOff")}return V}(),children:"Patient"}),(0,e.createComponentVNode)(2,f.Tabs.Tab,{selected:!!p,icon:"cog",onClick:function(){function V(){return v("choiceOn")}return V}(),children:"Options"})]})}),(0,e.createComponentVNode)(2,f.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,f.Section,{fill:!0,scrollable:!0,children:N})})]})})})}return i}(),l=function(u,s){var d=(0,t.useBackend)(s),v=d.data,h=v.occupant,C=h.activeSurgeries;return(0,e.createComponentVNode)(2,f.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,f.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,f.Section,{fill:!0,title:"Patient",children:(0,e.createComponentVNode)(2,f.LabeledList,{children:[(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Name",children:h.name}),(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Status",color:b[h.stat][0],children:b[h.stat][1]}),(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Health",children:(0,e.createComponentVNode)(2,f.ProgressBar,{min:"0",max:h.maxHealth,value:h.health/h.maxHealth,ranges:{good:[.5,1/0],average:[0,.5],bad:[-1/0,0]}})}),y.map(function(p,N){return(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:p[0]+" Damage",children:(0,e.createComponentVNode)(2,f.ProgressBar,{min:"0",max:"100",value:h[p[1]]/100,ranges:I,children:(0,a.round)(h[p[1]])},N)},N)}),(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Temperature",children:(0,e.createComponentVNode)(2,f.ProgressBar,{min:"0",max:h.maxTemp,value:h.bodyTemperature/h.maxTemp,color:k[h.temperatureSuitability+3],children:[(0,a.round)(h.btCelsius),"\xB0C, ",(0,a.round)(h.btFaren),"\xB0F"]})}),!!h.hasBlood&&(0,e.createFragment)([(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Blood Level",children:(0,e.createComponentVNode)(2,f.ProgressBar,{min:"0",max:h.bloodMax,value:h.bloodLevel/h.bloodMax,ranges:{bad:[-1/0,.6],average:[.6,.9],good:[.6,1/0]},children:[h.bloodPercent,"%, ",h.bloodLevel,"cl"]})}),(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Pulse",children:[h.pulse," BPM"]})],4)]})})}),(0,e.createComponentVNode)(2,f.Stack.Item,{children:(0,e.createComponentVNode)(2,f.Section,{title:"Active surgeries",level:"2",children:h.inSurgery&&C?C.map(function(p,N){return(0,e.createComponentVNode)(2,f.Section,{style:{textTransform:"capitalize"},title:p.name+" ("+p.location+")",children:(0,e.createComponentVNode)(2,f.LabeledList,{children:(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Next Step",children:p.step},N)},N)},N)}):(0,e.createComponentVNode)(2,f.Box,{color:"label",children:"No procedure ongoing."})})})]})},c=function(){return(0,e.createComponentVNode)(2,f.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,f.Stack.Item,{grow:!0,align:"center",textAlign:"center",color:"label",children:[(0,e.createComponentVNode)(2,f.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),"No patient detected."]})})},m=function(u,s){var d=(0,t.useBackend)(s),v=d.act,h=d.data,C=h.verbose,p=h.health,N=h.healthAlarm,V=h.oxy,S=h.oxyAlarm,B=h.crit;return(0,e.createComponentVNode)(2,f.LabeledList,{children:[(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Loudspeaker",children:(0,e.createComponentVNode)(2,f.Button,{selected:C,icon:C?"toggle-on":"toggle-off",content:C?"On":"Off",onClick:function(){function L(){return v(C?"verboseOff":"verboseOn")}return L}()})}),(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Health Announcer",children:(0,e.createComponentVNode)(2,f.Button,{selected:p,icon:p?"toggle-on":"toggle-off",content:p?"On":"Off",onClick:function(){function L(){return v(p?"healthOff":"healthOn")}return L}()})}),(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Health Announcer Threshold",children:(0,e.createComponentVNode)(2,f.Knob,{bipolar:!0,minValue:-100,maxValue:100,value:N,stepPixelSize:5,ml:"0",onChange:function(){function L(w,A){return v("health_adj",{new:A})}return L}()})}),(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Oxygen Alarm",children:(0,e.createComponentVNode)(2,f.Button,{selected:V,icon:V?"toggle-on":"toggle-off",content:V?"On":"Off",onClick:function(){function L(){return v(V?"oxyOff":"oxyOn")}return L}()})}),(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Oxygen Alarm Threshold",children:(0,e.createComponentVNode)(2,f.Knob,{bipolar:!0,minValue:-100,maxValue:100,value:S,stepPixelSize:5,ml:"0",onChange:function(){function L(w,A){return v("oxy_adj",{new:A})}return L}()})}),(0,e.createComponentVNode)(2,f.LabeledList.Item,{label:"Critical Alert",children:(0,e.createComponentVNode)(2,f.Button,{selected:B,icon:B?"toggle-on":"toggle-off",content:B?"On":"Off",onClick:function(){function L(){return v(B?"critOff":"critOn")}return L}()})})]})}},46892:function(T,r,n){"use strict";r.__esModule=!0,r.Orbit=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),f=n(98595),b=n(35840);function y(d,v){var h=typeof Symbol!="undefined"&&d[Symbol.iterator]||d["@@iterator"];if(h)return(h=h.call(d)).next.bind(h);if(Array.isArray(d)||(h=I(d))||v&&d&&typeof d.length=="number"){h&&(d=h);var C=0;return function(){return C>=d.length?{done:!0}:{done:!1,value:d[C++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function I(d,v){if(d){if(typeof d=="string")return k(d,v);var h={}.toString.call(d).slice(8,-1);return h==="Object"&&d.constructor&&(h=d.constructor.name),h==="Map"||h==="Set"?Array.from(d):h==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(h)?k(d,v):void 0}}function k(d,v){(v==null||v>d.length)&&(v=d.length);for(var h=0,C=Array(v);hh},m=function(v,h){var C=v.name,p=h.name;if(!C||!p)return 0;var N=C.match(g),V=p.match(g);if(N&&V&&C.replace(g,"")===p.replace(g,"")){var S=parseInt(N[1],10),B=parseInt(V[1],10);return S-B}return c(C,p)},i=function(v,h){var C=v.searchText,p=v.source,N=v.title,V=v.color,S=v.sorted,B=p.filter(l(C));return S&&B.sort(m),p.length>0&&(0,e.createComponentVNode)(2,o.Section,{title:N+" - ("+p.length+")",children:B.map(function(L){return(0,e.createComponentVNode)(2,u,{thing:L,color:V},L.name)})})},u=function(v,h){var C=(0,t.useBackend)(h),p=C.act,N=v.color,V=v.thing;return(0,e.createComponentVNode)(2,o.Button,{color:N,tooltip:V.assigned_role?(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Box,{as:"img",mr:"0.5em",className:(0,b.classes)(["job_icons16x16",V.assigned_role_sprite])})," ",V.assigned_role]}):"",tooltipPosition:"bottom",onClick:function(){function S(){return p("orbit",{ref:V.ref})}return S}(),children:[V.name,V.orbiters&&(0,e.createComponentVNode)(2,o.Box,{inline:!0,ml:1,children:["(",V.orbiters," ",(0,e.createComponentVNode)(2,o.Icon,{name:"eye"}),")"]})]})},s=r.Orbit=function(){function d(v,h){for(var C=(0,t.useBackend)(h),p=C.act,N=C.data,V=N.alive,S=N.antagonists,B=N.highlights,L=N.response_teams,w=N.tourist,A=N.auto_observe,x=N.dead,E=N.ssd,P=N.ghosts,D=N.misc,M=N.npcs,R=(0,t.useLocalState)(h,"searchText",""),O=R[0],F=R[1],_={},U=y(S),z;!(z=U()).done;){var $=z.value;_[$.antag]===void 0&&(_[$.antag]=[]),_[$.antag].push($)}var G=Object.entries(_);G.sort(function(J,se){return c(J[0],se[0])});var X=function(){function J(se){for(var ie=0,me=[G.map(function(ae){var le=ae[0],Z=ae[1];return Z}),w,B,V,P,E,x,M,D];ie0&&(0,e.createComponentVNode)(2,o.Section,{title:"Antagonists",children:G.map(function(J){var se=J[0],ie=J[1];return(0,e.createComponentVNode)(2,o.Section,{title:se+" - ("+ie.length+")",level:2,children:ie.filter(l(O)).sort(m).map(function(me){return(0,e.createComponentVNode)(2,u,{color:"bad",thing:me},me.name)})},se)})}),B.length>0&&(0,e.createComponentVNode)(2,i,{title:"Highlights",source:B,searchText:O,color:"teal"}),(0,e.createComponentVNode)(2,i,{title:"Response Teams",source:L,searchText:O,color:"purple"}),(0,e.createComponentVNode)(2,i,{title:"Tourists",source:w,searchText:O,color:"violet"}),(0,e.createComponentVNode)(2,i,{title:"Alive",source:V,searchText:O,color:"good"}),(0,e.createComponentVNode)(2,i,{title:"Ghosts",source:P,searchText:O,color:"grey"}),(0,e.createComponentVNode)(2,i,{title:"SSD",source:E,searchText:O,color:"grey"}),(0,e.createComponentVNode)(2,i,{title:"Dead",source:x,searchText:O,sorted:!1}),(0,e.createComponentVNode)(2,i,{title:"NPCs",source:M,searchText:O,sorted:!1}),(0,e.createComponentVNode)(2,i,{title:"Misc",source:D,searchText:O,sorted:!1})]})})}return d}()},15421:function(T,r,n){"use strict";r.__esModule=!0,r.OreRedemption=void 0;var e=n(89005),a=n(35840),t=n(72253),o=n(36036),f=n(98595),b=n(9394);function y(d){if(d==null)throw new TypeError("Cannot destructure "+d)}var I=(0,b.createLogger)("OreRedemption"),k=function(v){return v.toLocaleString("en-US")+" pts"},g=r.OreRedemption=function(){function d(v,h){return(0,e.createComponentVNode)(2,f.Window,{width:490,height:750,children:(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,l,{height:"100%"})}),(0,e.createComponentVNode)(2,c),(0,e.createComponentVNode)(2,m)]})})})}return d}(),l=function(v,h){var C=(0,t.useBackend)(h),p=C.act,N=C.data,V=N.id,S=N.points,B=N.disk,L=Object.assign({},(y(v),v));return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({},L,{children:[(0,e.createComponentVNode)(2,o.Box,{color:"average",textAlign:"center",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"exclamation-triangle",mr:"0.5rem"}),"This machine only accepts ore. Gibtonite is not accepted."]}),(0,e.createComponentVNode)(2,o.Divider),(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Unclaimed Points",color:S>0?"good":"grey",bold:S>0&&"good",children:k(S)})}),(0,e.createComponentVNode)(2,o.Divider),B?(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Design disk",children:[(0,e.createComponentVNode)(2,o.Button,{selected:!0,bold:!0,icon:"eject",content:B.name,tooltip:"Ejects the design disk.",onClick:function(){function w(){return p("eject_disk")}return w}()}),(0,e.createComponentVNode)(2,o.Button,{disabled:!B.design||!B.compatible,icon:"upload",content:"Download",tooltip:"Downloads the design on the disk into the machine.",onClick:function(){function w(){return p("download")}return w}()})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Stored design",children:(0,e.createComponentVNode)(2,o.Box,{color:B.design&&(B.compatible?"good":"bad"),children:B.design||"N/A"})})]}):(0,e.createComponentVNode)(2,o.Box,{color:"label",children:"No design disk inserted."})]})))},c=function(v,h){var C=(0,t.useBackend)(h),p=C.act,N=C.data,V=N.sheets,S=Object.assign({},(y(v),v));return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,height:"20%",children:(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({fill:!0,scrollable:!0,className:"OreRedemption__Ores",p:"0"},S,{children:[(0,e.createComponentVNode)(2,i,{title:"Sheets",columns:[["Available","25%"],["Ore Value","15%"],["Smelt","20%"]]}),V.map(function(B){return(0,e.createComponentVNode)(2,u,{ore:B},B.id)})]})))})},m=function(v,h){var C=(0,t.useBackend)(h),p=C.act,N=C.data,V=N.alloys,S=Object.assign({},(y(v),v));return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({fill:!0,scrollable:!0,className:"OreRedemption__Ores",p:"0"},S,{children:[(0,e.createComponentVNode)(2,i,{title:"Alloys",columns:[["Recipe","50%"],["Available","11%"],["Smelt","20%"]]}),V.map(function(B){return(0,e.createComponentVNode)(2,s,{ore:B},B.id)})]})))})},i=function(v,h){var C;return(0,e.createComponentVNode)(2,o.Box,{className:"OreHeader",children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:v.title}),(C=v.columns)==null?void 0:C.map(function(p){return(0,e.createComponentVNode)(2,o.Stack.Item,{basis:p[1],textAlign:"center",color:"label",bold:!0,children:p[0]},p)})]})})},u=function(v,h){var C=(0,t.useBackend)(h),p=C.act,N=v.ore;if(!(N.value&&N.amount<=0&&!(["metal","glass"].indexOf(N.id)>-1)))return(0,e.createComponentVNode)(2,o.Box,{className:"SheetLine",children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"45%",align:"middle",children:(0,e.createComponentVNode)(2,o.Stack,{align:"center",children:[(0,e.createComponentVNode)(2,o.Stack.Item,{className:(0,a.classes)(["materials32x32",N.id])}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:N.name})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"20%",textAlign:"center",color:N.amount>=1?"good":"gray",bold:N.amount>=1,align:"center",children:N.amount.toLocaleString("en-US")}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"20%",textAlign:"center",align:"center",children:N.value}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"20%",textAlign:"center",align:"center",lineHeight:"32px",children:(0,e.createComponentVNode)(2,o.NumberInput,{width:"40%",value:0,minValue:0,maxValue:Math.min(N.amount,50),stepPixelSize:6,onChange:function(){function V(S,B){return p(N.value?"sheet":"alloy",{id:N.id,amount:B})}return V}()})})]})})},s=function(v,h){var C=(0,t.useBackend)(h),p=C.act,N=v.ore;return(0,e.createComponentVNode)(2,o.Box,{className:"SheetLine",children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"7%",align:"middle",children:(0,e.createComponentVNode)(2,o.Box,{className:(0,a.classes)(["alloys32x32",N.id])})}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"30%",textAlign:"middle",align:"center",children:N.name}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"35%",textAlign:"middle",color:N.amount>=1?"good":"gray",align:"center",children:N.description}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"10%",textAlign:"center",color:N.amount>=1?"good":"gray",bold:N.amount>=1,align:"center",children:N.amount.toLocaleString("en-US")}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"20%",textAlign:"center",align:"center",lineHeight:"32px",children:(0,e.createComponentVNode)(2,o.NumberInput,{width:"40%",value:0,minValue:0,maxValue:Math.min(N.amount,50),stepPixelSize:6,onChange:function(){function V(S,B){return p(N.value?"sheet":"alloy",{id:N.id,amount:B})}return V}()})})]})})}},52754:function(T,r,n){"use strict";r.__esModule=!0,r.PAI=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(71253),b=n(70752),y=function(g){var l;try{l=b("./"+g+".js")}catch(m){if(m.code==="MODULE_NOT_FOUND")return(0,f.routingError)("notFound",g);throw m}var c=l[g];return c||(0,f.routingError)("missingExport",g)},I=r.PAI=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.app_template,s=i.app_icon,d=i.app_title,v=y(u);return(0,e.createComponentVNode)(2,o.Window,{width:600,height:650,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{p:1,fill:!0,scrollable:!0,title:(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:s,mr:1}),d,u!=="pai_main_menu"&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{ml:2,mb:0,content:"Back",icon:"arrow-left",onClick:function(){function h(){return m("Back")}return h}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Home",icon:"arrow-up",onClick:function(){function h(){return m("MASTER_back")}return h}()})],4)]}),children:(0,e.createComponentVNode)(2,v)})})})})})}return k}()},85175:function(T,r,n){"use strict";r.__esModule=!0,r.PDA=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(71253),b=n(59395),y=function(c){var m;try{m=b("./"+c+".js")}catch(u){if(u.code==="MODULE_NOT_FOUND")return(0,f.routingError)("notFound",c);throw u}var i=m[c];return i||(0,f.routingError)("missingExport",c)},I=r.PDA=function(){function l(c,m){var i=(0,a.useBackend)(m),u=i.act,s=i.data,d=s.app,v=s.owner;if(!v)return(0,e.createComponentVNode)(2,o.Window,{width:350,height:105,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Error",children:"No user data found. Please swipe an ID card."})})});var h=y(d.template);return(0,e.createComponentVNode)(2,o.Window,{width:600,height:650,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,k)}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,p:1,pb:0,title:(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:d.icon,mr:1}),d.name]}),children:(0,e.createComponentVNode)(2,h)})}),(0,e.createComponentVNode)(2,t.Stack.Item,{mt:7.5,children:(0,e.createComponentVNode)(2,g)})]})})})}return l}(),k=function(c,m){var i=(0,a.useBackend)(m),u=i.act,s=i.data,d=s.idInserted,v=s.idLink,h=s.stationTime,C=s.cartridge_name;return(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{ml:.5,children:(0,e.createComponentVNode)(2,t.Button,{icon:"id-card",color:"transparent",onClick:function(){function p(){return u("Authenticate")}return p}(),content:d?v:"No ID Inserted"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"sd-card",color:"transparent",onClick:function(){function p(){return u("Eject")}return p}(),content:C?["Eject "+C]:"No Cartridge Inserted"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"right",bold:!0,mr:1,mt:.5,children:h})]})},g=function(c,m){var i=(0,a.useBackend)(m),u=i.act,s=i.data,d=s.app;return(0,e.createComponentVNode)(2,t.Box,{height:"45px",className:"PDA__footer",backgroundColor:"#1b1b1b",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:[!!d.has_back&&(0,e.createComponentVNode)(2,t.Stack.Item,{basis:"33%",mr:-.5,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,className:"PDA__footer__button",color:"transparent",iconColor:d.has_back?"white":"disabled",icon:"arrow-alt-circle-left-o",onClick:function(){function v(){return u("Back")}return v}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{basis:d.has_back?"33%":"100%",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,className:"PDA__footer__button",color:"transparent",iconColor:d.is_home?"disabled":"white",icon:"home",onClick:function(){function v(){u("Home")}return v}()})})]})})}},68654:function(T,r,n){"use strict";r.__esModule=!0,r.Pacman=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(49968),b=r.Pacman=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=c.active,i=c.anchored,u=c.broken,s=c.emagged,d=c.fuel_type,v=c.fuel_usage,h=c.fuel_stored,C=c.fuel_cap,p=c.is_ai,N=c.tmp_current,V=c.tmp_max,S=c.tmp_overheat,B=c.output_max,L=c.power_gen,w=c.output_set,A=c.has_fuel,x=h/C,E=N/V,P=w*L,D=Math.round(h/v*2),M=Math.round(D/60),R=D>120?M+" minutes":D+" seconds";return(0,e.createComponentVNode)(2,o.Window,{width:500,height:225,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(u||!i)&&(0,e.createComponentVNode)(2,t.Section,{title:"Status",children:[!!u&&(0,e.createComponentVNode)(2,t.Box,{color:"orange",children:"The generator is malfunctioning!"}),!u&&!i&&(0,e.createComponentVNode)(2,t.Box,{color:"orange",children:"The generator needs to be anchored to the floor with a wrench."})]}),!u&&!!i&&(0,e.createVNode)(1,"div",null,[(0,e.createComponentVNode)(2,t.Section,{title:"Status",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:m?"power-off":"times",content:m?"On":"Off",tooltip:"Toggles the generator on/off. Requires fuel.",tooltipPosition:"left",disabled:!A,selected:m,onClick:function(){function O(){return l("toggle_power")}return O}()}),children:(0,e.createComponentVNode)(2,t.Flex,{direction:"row",children:[(0,e.createComponentVNode)(2,t.Flex.Item,{width:"50%",className:"ml-1",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power setting",children:[(0,e.createComponentVNode)(2,t.NumberInput,{value:w,minValue:1,maxValue:B*(s?2.5:1),step:1,className:"mt-1",onDrag:function(){function O(F,_){return l("change_power",{change_power:_})}return O}()}),"(",(0,f.formatPower)(P),")"]})})}),(0,e.createComponentVNode)(2,t.Flex.Item,{width:"50%",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Temperature",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:E,ranges:{green:[-1/0,.33],orange:[.33,.66],red:[.66,1/0]},children:[N," \u2103"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:[S>50&&(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"CRITICAL OVERHEAT!"}),S>20&&S<=50&&(0,e.createComponentVNode)(2,t.Box,{color:"orange",children:"WARNING: Overheating!"}),S>1&&S<=20&&(0,e.createComponentVNode)(2,t.Box,{color:"orange",children:"Temperature High"}),S===0&&(0,e.createComponentVNode)(2,t.Box,{color:"green",children:"Optimal"})]})]})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Fuel",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:"Eject Fuel",tooltip:"Ejects fuel. Generator needs to be offline.",tooltipPosition:"left",disabled:m||p||!A,onClick:function(){function O(){return l("eject_fuel")}return O}()}),children:(0,e.createComponentVNode)(2,t.Grid,{children:[(0,e.createComponentVNode)(2,t.Grid.Column,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Type",children:d}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Fuel level",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:x,ranges:{red:[-1/0,.33],orange:[.33,.66],green:[.66,1/0]},children:[Math.round(h/1e3)," dm\xB3"]})})]})}),(0,e.createComponentVNode)(2,t.Grid.Column,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Fuel usage",children:[v/1e3," dm\xB3/s"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Fuel depletion",children:[!!A&&(v?R:"N/A"),!A&&(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Out of fuel"})]})]})})]})})],4)]})})}return y}()},1701:function(T,r,n){"use strict";r.__esModule=!0,r.PanDEMIC=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.PanDEMIC=function(){function i(u,s){var d=(0,a.useBackend)(s),v=d.data,h=v.beakerLoaded,C=v.beakerContainsBlood,p=v.beakerContainsVirus,N=v.resistances,V=N===void 0?[]:N,S;return h?C?C&&!p&&(S=(0,e.createFragment)([(0,e.createTextVNode)("No disease detected in provided blood sample.")],4)):S=(0,e.createFragment)([(0,e.createTextVNode)("No blood sample found in the loaded container.")],4):S=(0,e.createFragment)([(0,e.createTextVNode)("No container loaded.")],4),(0,e.createComponentVNode)(2,o.Window,{width:575,height:510,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[S&&!p?(0,e.createComponentVNode)(2,t.Section,{title:"Container Information",buttons:(0,e.createComponentVNode)(2,b,{fill:!0,vertical:!0}),children:(0,e.createComponentVNode)(2,t.NoticeBox,{children:S})}):(0,e.createComponentVNode)(2,k),(V==null?void 0:V.length)>0&&(0,e.createComponentVNode)(2,m,{align:"bottom"})]})})})}return i}(),b=function(u,s){var d=(0,a.useBackend)(s),v=d.act,h=d.data,C=h.beakerLoaded;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:"Eject",disabled:!C,onClick:function(){function p(){return v("eject_beaker")}return p}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"trash-alt",confirmIcon:"eraser",content:"Destroy",confirmContent:"Destroy",disabled:!C,onClick:function(){function p(){return v("destroy_eject_beaker")}return p}()})],4)},y=function(u,s){var d=(0,a.useBackend)(s),v=d.act,h=d.data,C=h.beakerContainsVirus,p=u.strain,N=p.commonName,V=p.description,S=p.diseaseAgent,B=p.bloodDNA,L=p.bloodType,w=p.possibleTreatments,A=p.transmissionRoute,x=p.isAdvanced,E=(0,e.createFragment)([(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Blood DNA",children:B?(0,e.createVNode)(1,"span",null,B,0,{style:{"font-family":"'Courier New', monospace"}}):"Undetectable"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Blood Type",children:(0,e.createVNode)(1,"div",null,null,1,{dangerouslySetInnerHTML:{__html:L!=null?L:"Undetectable"}})})],4);if(!C)return(0,e.createComponentVNode)(2,t.LabeledList,{children:E});var P;return x&&(N!=null&&N!=="Unknown"?P=(0,e.createComponentVNode)(2,t.Button,{icon:"print",content:"Print Release Forms",onClick:function(){function D(){return v("print_release_forms",{strain_index:u.strainIndex})}return D}(),style:{"margin-left":"auto"}}):P=(0,e.createComponentVNode)(2,t.Button,{icon:"pen",content:"Name Disease",onClick:function(){function D(){return v("name_strain",{strain_index:u.strainIndex})}return D}(),style:{"margin-left":"auto"}})),(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Common Name",className:"common-name-label",children:(0,e.createComponentVNode)(2,t.Stack,{horizontal:!0,align:"center",children:[N!=null?N:"Unknown",P]})}),V&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Description",children:V}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Disease Agent",children:S}),E,(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Spread Vector",children:A!=null?A:"None"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Possible Cures",children:w!=null?w:"None"})]})},I=function(u,s){var d,v=(0,a.useBackend)(s),h=v.act,C=v.data,p=!!C.synthesisCooldown,N=(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{icon:p?"spinner":"clone",iconSpin:p,content:"Clone",disabled:p,onClick:function(){function V(){return h("clone_strain",{strain_index:u.strainIndex})}return V}()}),u.sectionButtons],0);return(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:(d=u.sectionTitle)!=null?d:"Strain Information",buttons:N,children:(0,e.createComponentVNode)(2,y,{strain:u.strain,strainIndex:u.strainIndex})})})},k=function(u,s){var d,v=(0,a.useBackend)(s),h=v.act,C=v.data,p=C.selectedStrainIndex,N=C.strains,V=N[p-1];if(N.length===0)return(0,e.createComponentVNode)(2,t.Section,{title:"Container Information",buttons:(0,e.createComponentVNode)(2,b),children:(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No disease detected in provided blood sample."})});if(N.length===1){var S;return(0,e.createFragment)([(0,e.createComponentVNode)(2,I,{strain:N[0],strainIndex:1,sectionButtons:(0,e.createComponentVNode)(2,b)}),((S=N[0].symptoms)==null?void 0:S.length)>0&&(0,e.createComponentVNode)(2,l,{strain:N[0]})],0)}var B=(0,e.createComponentVNode)(2,b);return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Culture Information",fill:!0,buttons:B,children:(0,e.createComponentVNode)(2,t.Flex,{direction:"column",style:{height:"100%"},children:[(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,t.Tabs,{children:N.map(function(L,w){var A;return(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"virus",selected:p-1===w,onClick:function(){function x(){return h("switch_strain",{strain_index:w+1})}return x}(),children:(A=L.commonName)!=null?A:"Unknown"},w)})})}),(0,e.createComponentVNode)(2,I,{strain:V,strainIndex:p}),((d=V.symptoms)==null?void 0:d.length)>0&&(0,e.createComponentVNode)(2,l,{className:"remove-section-bottom-padding",strain:V})]})})})},g=function(u){return u.reduce(function(s,d){return s+d},0)},l=function(u){var s=u.strain.symptoms;return(0,e.createComponentVNode)(2,t.Flex.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Infection Symptoms",fill:!0,className:u.className,children:(0,e.createComponentVNode)(2,t.Table,{className:"symptoms-table",children:[(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Name"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Stealth"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Resistance"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Stage Speed"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Transmissibility"})]}),s.map(function(d,v){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.name}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.stealth}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.resistance}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.stageSpeed}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.transmissibility})]},v)}),(0,e.createComponentVNode)(2,t.Table.Row,{className:"table-spacer"}),(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{style:{"font-weight":"bold"},children:"Total"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:g(s.map(function(d){return d.stealth}))}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:g(s.map(function(d){return d.resistance}))}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:g(s.map(function(d){return d.stageSpeed}))}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:g(s.map(function(d){return d.transmissibility}))})]})]})})})},c=["flask","vial","eye-dropper"],m=function(u,s){var d=(0,a.useBackend)(s),v=d.act,h=d.data,C=h.synthesisCooldown,p=h.beakerContainsVirus,N=h.resistances;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Antibodies",fill:!0,children:(0,e.createComponentVNode)(2,t.Stack,{horizontal:!0,wrap:!0,children:N.map(function(V,S){return(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:c[S%c.length],disabled:!!C,onClick:function(){function B(){return v("clone_vaccine",{resistance_index:S+1})}return B}(),mr:"0.5em"}),V]},S)})})})})}},67921:function(T,r,n){"use strict";r.__esModule=!0,r.ParticleAccelerator=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(25328),f=n(79646),b=n(36352),y=n(98595),I=n(35840),k=n(38307),g=function(u){switch(u){case 1:return"north";case 2:return"south";case 4:return"east";case 8:return"west";case 5:return"northeast";case 6:return"southeast";case 9:return"northwest";case 10:return"southwest"}return""},l=r.ParticleAccelerator=function(){function i(u,s){var d=(0,a.useBackend)(s),v=d.act,h=d.data,C=h.assembled,p=h.power,N=h.strength,V=h.max_strength,S=h.icon,B=h.layout_1,L=h.layout_2,w=h.layout_3,A=h.orientation;return(0,e.createComponentVNode)(2,y.Window,{width:395,height:C?160:A==="north"||A==="south"?540:465,children:(0,e.createComponentVNode)(2,y.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Control Panel",buttons:(0,e.createComponentVNode)(2,t.Button,{dmIcon:"sync",content:"Connect",onClick:function(){function x(){return v("scan")}return x}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",mb:"5px",children:(0,e.createComponentVNode)(2,t.Box,{color:C?"good":"bad",children:C?"Operational":"Error: Verify Configuration"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:(0,e.createComponentVNode)(2,t.Button,{icon:p?"power-off":"times",content:p?"On":"Off",selected:p,disabled:!C,onClick:function(){function x(){return v("power")}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Strength",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"backward",disabled:!C||N===0,onClick:function(){function x(){return v("remove_strength")}return x}(),mr:"4px"}),N,(0,e.createComponentVNode)(2,t.Button,{icon:"forward",disabled:!C||N===V,onClick:function(){function x(){return v("add_strength")}return x}(),ml:"4px"})]})]})}),C?"":(0,e.createComponentVNode)(2,t.Section,{title:A?"EM Acceleration Chamber Orientation: "+(0,o.capitalize)(A):"Place EM Acceleration Chamber Next To Console",children:A===0?"":A==="north"||A==="south"?(0,e.createComponentVNode)(2,m):(0,e.createComponentVNode)(2,c)})]})})}return i}(),c=function(u,s){var d=(0,a.useBackend)(s),v=d.act,h=d.data,C=h.assembled,p=h.power,N=h.strength,V=h.max_strength,S=h.icon,B=h.layout_1,L=h.layout_2,w=h.layout_3,A=h.orientation;return(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,b.TableRow,{width:"40px",children:(A==="east"?B:w).slice().map(function(x){return(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Tooltip,{content:(0,e.createVNode)(1,"span",null,[x.name,(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)(" "),"Status: "+x.status,(0,e.createVNode)(1,"br"),"Direction: "+g(x.dir)],0,{style:{wordWrap:"break-word"}}),children:(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:S,dmIconState:x.icon_state,dmDirection:x.dir,style:{"border-style":"solid","border-width":"2px","border-color":x.status==="good"?"green":x.status==="Incomplete"?"orange":"red",padding:"2px"}})})},x.name)})}),(0,e.createComponentVNode)(2,b.TableRow,{width:"40px",children:L.slice().map(function(x){return(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Tooltip,{content:(0,e.createVNode)(1,"span",null,[x.name,(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)(" "),"Status: "+x.status,(0,e.createVNode)(1,"br"),"Direction: "+g(x.dir)],0,{style:{wordWrap:"break-word"}}),children:(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:S,dmIconState:x.icon_state,dmDirection:x.dir,style:{"border-style":"solid","border-width":"2px","border-color":x.status==="good"?"green":x.status==="Incomplete"?"orange":"red",padding:"2px"}})})},x.name)})}),(0,e.createComponentVNode)(2,b.TableRow,{width:"40px",children:(A==="east"?w:B).slice().map(function(x){return(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Tooltip,{content:(0,e.createVNode)(1,"span",null,[x.name,(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)(" "),"Status: "+x.status,(0,e.createVNode)(1,"br"),"Direction: "+g(x.dir)],0,{style:{wordWrap:"break-word"}}),children:(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:S,dmIconState:x.icon_state,dmDirection:x.dir,style:{"border-style":"solid","border-width":"2px","border-color":x.status==="good"?"green":x.status==="Incomplete"?"orange":"red",padding:"2px"}})})},x.name)})})]})},m=function(u,s){var d=(0,a.useBackend)(s),v=d.act,h=d.data,C=h.assembled,p=h.power,N=h.strength,V=h.max_strength,S=h.icon,B=h.layout_1,L=h.layout_2,w=h.layout_3,A=h.orientation;return(0,e.createComponentVNode)(2,t.Grid,{children:[(0,e.createComponentVNode)(2,f.GridColumn,{width:"40px",children:(A==="north"?B:w).slice().map(function(x){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Tooltip,{content:(0,e.createVNode)(1,"span",null,[x.name,(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)(" "),"Status: "+x.status,(0,e.createVNode)(1,"br"),"Direction: "+g(x.dir)],0,{style:{wordWrap:"break-word"}}),children:(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:S,dmIconState:x.icon_state,dmDirection:x.dir,style:{"border-style":"solid","border-width":"2px","border-color":x.status==="good"?"green":x.status==="Incomplete"?"orange":"red",padding:"2px"}})})},x.name)})}),(0,e.createComponentVNode)(2,f.GridColumn,{children:L.slice().map(function(x){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Tooltip,{content:(0,e.createVNode)(1,"span",null,[x.name,(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)(" "),"Status: "+x.status,(0,e.createVNode)(1,"br"),"Direction: "+g(x.dir)],0,{style:{wordWrap:"break-word"}}),children:(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:S,dmIconState:x.icon_state,dmDirection:x.dir,style:{"border-style":"solid","border-width":"2px","border-color":x.status==="good"?"green":x.status==="Incomplete"?"orange":"red",padding:"2px"}})})},x.name)})}),(0,e.createComponentVNode)(2,f.GridColumn,{width:"40px",children:(A==="north"?w:B).slice().map(function(x){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,tooltip:x.status,children:(0,e.createComponentVNode)(2,t.Tooltip,{content:(0,e.createVNode)(1,"span",null,[x.name,(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)(" "),"Status: "+x.status,(0,e.createVNode)(1,"br"),"Direction: "+g(x.dir)],0,{style:{wordWrap:"break-word"}}),children:(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:S,dmIconState:x.icon_state,dmDirection:x.dir,style:{"border-style":"solid","border-width":"2px","border-color":x.status==="good"?"green":x.status==="Incomplete"?"orange":"red",padding:"2px"}})})},x.name)})})]})}},71432:function(T,r,n){"use strict";r.__esModule=!0,r.PdaPainter=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.PdaPainter=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.data,i=m.has_pda;return(0,e.createComponentVNode)(2,o.Window,{width:510,height:505,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:i?(0,e.createComponentVNode)(2,y):(0,e.createComponentVNode)(2,b)})})}return k}(),b=function(g,l){var c=(0,a.useBackend)(l),m=c.act;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,textAlign:"center",align:"center",color:"silver",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"download",size:5,mb:"10px"}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{width:"160px",textAlign:"center",content:"Insert PDA",onClick:function(){function i(){return m("insert_pda")}return i}()})]})})})},y=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.pda_colors;return(0,e.createComponentVNode)(2,t.Stack,{fill:!0,horizontal:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,I)}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,t.Table,{className:"PdaPainter__list",children:Object.keys(u).map(function(s){return(0,e.createComponentVNode)(2,t.Table.Row,{onClick:function(){function d(){return m("choose_pda",{selectedPda:s})}return d}(),children:[(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,children:(0,e.createVNode)(1,"img",null,null,1,{src:"data:image/png;base64,"+u[s][0],style:{"vertical-align":"middle",width:"32px",margin:"0px","margin-left":"0px","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"}})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:s})]},s)})})})})]})},I=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.current_appearance,s=i.preview_appearance;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Current PDA",children:[(0,e.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+u,style:{"vertical-align":"middle",width:"160px",margin:"0px","margin-left":"0px","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"}}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"eject",content:"Eject",color:"green",onClick:function(){function d(){return m("eject_pda")}return d}()}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"paint-roller",content:"Paint PDA",onClick:function(){function d(){return m("paint_pda")}return d}()})]}),(0,e.createComponentVNode)(2,t.Section,{title:"Preview",children:(0,e.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+s,style:{"vertical-align":"middle",width:"160px",margin:"0px","margin-left":"0px","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"}})})]})}},33388:function(T,r,n){"use strict";r.__esModule=!0,r.PersonalCrafting=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.PersonalCrafting=function(){function I(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.busy,u=m.category,s=m.display_craftable_only,d=m.display_compact,v=m.prev_cat,h=m.next_cat,C=m.subcategory,p=m.prev_subcat,N=m.next_subcat;return(0,e.createComponentVNode)(2,o.Window,{width:700,height:800,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[!!i&&(0,e.createComponentVNode)(2,t.Dimmer,{fontSize:"32px",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"cog",spin:1})," Crafting..."]}),(0,e.createComponentVNode)(2,t.Section,{title:u,buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:"Show Craftable Only",icon:s?"check-square-o":"square-o",selected:s,onClick:function(){function V(){return c("toggle_recipes")}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Compact Mode",icon:d?"check-square-o":"square-o",selected:d,onClick:function(){function V(){return c("toggle_compact")}return V}()})],4),children:[(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Button,{content:v,icon:"arrow-left",onClick:function(){function V(){return c("backwardCat")}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:h,icon:"arrow-right",onClick:function(){function V(){return c("forwardCat")}return V}()})]}),C&&(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Button,{content:p,icon:"arrow-left",onClick:function(){function V(){return c("backwardSubCat")}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:N,icon:"arrow-right",onClick:function(){function V(){return c("forwardSubCat")}return V}()})]}),d?(0,e.createComponentVNode)(2,b):(0,e.createComponentVNode)(2,y)]})]})})}return I}(),b=function(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.display_craftable_only,u=m.can_craft,s=m.cant_craft;return(0,e.createComponentVNode)(2,t.Box,{mt:1,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[u.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:d.name,children:[(0,e.createComponentVNode)(2,t.Button,{icon:"hammer",content:"Craft",onClick:function(){function v(){return c("make",{make:d.ref})}return v}()}),d.catalyst_text&&(0,e.createComponentVNode)(2,t.Button,{tooltip:d.catalyst_text,content:"Catalysts",color:"transparent"}),(0,e.createComponentVNode)(2,t.Button,{tooltip:d.req_text,content:"Requirements",color:"transparent"}),d.tool_text&&(0,e.createComponentVNode)(2,t.Button,{tooltip:d.tool_text,content:"Tools",color:"transparent"})]},d.name)}),!i&&s.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:d.name,children:[(0,e.createComponentVNode)(2,t.Button,{icon:"hammer",content:"Craft",disabled:!0}),d.catalyst_text&&(0,e.createComponentVNode)(2,t.Button,{tooltip:d.catalyst_text,content:"Catalysts",color:"transparent"}),(0,e.createComponentVNode)(2,t.Button,{tooltip:d.req_text,content:"Requirements",color:"transparent"}),d.tool_text&&(0,e.createComponentVNode)(2,t.Button,{tooltip:d.tool_text,content:"Tools",color:"transparent"})]},d.name)})]})})},y=function(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.display_craftable_only,u=m.can_craft,s=m.cant_craft;return(0,e.createComponentVNode)(2,t.Box,{mt:1,children:[u.map(function(d){return(0,e.createComponentVNode)(2,t.Section,{title:d.name,buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"hammer",content:"Craft",onClick:function(){function v(){return c("make",{make:d.ref})}return v}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[d.catalyst_text&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Catalysts",children:d.catalyst_text}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Requirements",children:d.req_text}),d.tool_text&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tools",children:d.tool_text})]})},d.name)}),!i&&s.map(function(d){return(0,e.createComponentVNode)(2,t.Section,{title:d.name,buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"hammer",content:"Craft",disabled:!0}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[d.catalyst_text&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Catalysts",children:d.catalyst_text}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Requirements",children:d.req_text}),d.tool_text&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tools",children:d.tool_text})]})},d.name)})]})}},56150:function(T,r,n){"use strict";r.__esModule=!0,r.Photocopier=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.Photocopier=function(){function I(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data;return(0,e.createComponentVNode)(2,o.Window,{width:400,height:440,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Photocopier",color:"silver",children:[(0,e.createComponentVNode)(2,t.Stack,{mb:1,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:12,children:"Copies:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"2em",bold:!0,children:m.copynumber}),(0,e.createComponentVNode)(2,t.Stack.Item,{float:"right",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"minus",textAlign:"center",content:"",onClick:function(){function i(){return c("minus")}return i}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"plus",textAlign:"center",content:"",onClick:function(){function i(){return c("add")}return i}()})]})]}),(0,e.createComponentVNode)(2,t.Stack,{mb:2,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:12,children:"Toner:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,children:m.toner})]}),(0,e.createComponentVNode)(2,t.Stack,{mb:1,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:12,children:"Inserted Document:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",disabled:!m.copyitem&&!m.mob,content:m.copyitem?m.copyitem:m.mob?m.mob+"'s ass!":"document",onClick:function(){function i(){return c("removedocument")}return i}()})})]}),(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:12,children:"Inserted Folder:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",disabled:!m.folder,content:m.folder?m.folder:"folder",onClick:function(){function i(){return c("removefolder")}return i}()})})]})]}),(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,b)}),(0,e.createComponentVNode)(2,y)]})})})}return I}(),b=function(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.issilicon;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"copy",float:"center",textAlign:"center",content:"Copy",onClick:function(){function u(){return c("copy")}return u}()}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"file-import",float:"center",textAlign:"center",content:"Scan",onClick:function(){function u(){return c("scandocument")}return u}()}),!!i&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"file",color:"green",float:"center",textAlign:"center",content:"Print Text",onClick:function(){function u(){return c("ai_text")}return u}()}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"image",color:"green",float:"center",textAlign:"center",content:"Print Image",onClick:function(){function u(){return c("ai_pic")}return u}()})],4)],0)},y=function(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Scanned Files",children:m.files.map(function(i){return(0,e.createComponentVNode)(2,t.Section,{title:i.name,buttons:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"print",content:"Print",disabled:m.toner<=0,onClick:function(){function u(){return c("filecopy",{uid:i.uid})}return u}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"trash-alt",content:"Delete",color:"bad",onClick:function(){function u(){return c("deletefile",{uid:i.uid})}return u}()})]})},i.name)})})}},84676:function(T,r,n){"use strict";r.__esModule=!0,r.PoolController=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=["tempKey"];function b(g,l){if(g==null)return{};var c={};for(var m in g)if({}.hasOwnProperty.call(g,m)){if(l.includes(m))continue;c[m]=g[m]}return c}var y={scalding:{label:"Scalding",color:"#FF0000",icon:"fa fa-arrow-circle-up",requireEmag:!0},warm:{label:"Warm",color:"#990000",icon:"fa fa-arrow-circle-up"},normal:{label:"Normal",color:null,icon:"fa fa-arrow-circle-right"},cool:{label:"Cool",color:"#009999",icon:"fa fa-arrow-circle-down"},frigid:{label:"Frigid",color:"#00CCCC",icon:"fa fa-arrow-circle-down",requireEmag:!0}},I=function(l,c){var m=l.tempKey,i=b(l,f),u=y[m];if(!u)return null;var s=(0,a.useBackend)(c),d=s.data,v=s.act,h=d.currentTemp,C=u.label,p=u.icon,N=m===h,V=function(){v("setTemp",{temp:m})};return(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.Button,Object.assign({color:"transparent",selected:N,onClick:V},i,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:p}),C]})))},k=r.PoolController=function(){function g(l,c){for(var m=(0,a.useBackend)(c),i=m.data,u=i.emagged,s=i.currentTemp,d=y[s]||y.normal,v=d.label,h=d.color,C=[],p=0,N=Object.entries(y);p50?"battery-half":"battery-quarter")||h==="C"&&"bolt"||h==="F"&&"battery-full"||h==="M"&&"slash",color:h==="N"&&(C>50?"yellow":"red")||h==="C"&&"yellow"||h==="F"&&"green"||h==="M"&&"orange"}),(0,e.createComponentVNode)(2,I.Box,{inline:!0,width:"36px",textAlign:"right",children:(0,o.toFixed)(C)+"%"})],4)};u.defaultHooks=f.pureComponentHooks;var s=function(v){var h,C,p=v.status;switch(p){case"AOn":h=!0,C=!0;break;case"AOff":h=!0,C=!1;break;case"On":h=!1,C=!0;break;case"Off":h=!1,C=!1;break}var N=(C?"On":"Off")+(" ["+(h?"auto":"manual")+"]");return(0,e.createComponentVNode)(2,I.ColorBox,{color:C?"good":"bad",content:h?void 0:"M",title:N})};s.defaultHooks=f.pureComponentHooks},50992:function(T,r,n){"use strict";r.__esModule=!0,r.PrisonerImplantManager=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(29319),f=n(3939),b=n(321),y=n(5485),I=n(98595),k=r.PrisonerImplantManager=function(){function g(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.loginState,d=u.prisonerInfo,v=u.chemicalInfo,h=u.trackingInfo,C;if(!s.logged_in)return(0,e.createComponentVNode)(2,I.Window,{theme:"security",width:500,height:850,children:(0,e.createComponentVNode)(2,I.Window.Content,{children:(0,e.createComponentVNode)(2,y.LoginScreen)})});var p=[1,5,10];return(0,e.createComponentVNode)(2,I.Window,{theme:"security",width:500,height:850,children:[(0,e.createComponentVNode)(2,f.ComplexModal),(0,e.createComponentVNode)(2,I.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.LoginInfo),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Prisoner Points Manager System",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Prisoner",children:(0,e.createComponentVNode)(2,t.Button,{icon:d.name?"eject":"id-card",selected:d.name,content:d.name?d.name:"-----",tooltip:d.name?"Eject ID":"Insert ID",onClick:function(){function N(){return i("id_card")}return N}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Points",children:[d.points!==null?d.points:"-/-",(0,e.createComponentVNode)(2,t.Button,{ml:2,icon:"minus-square",disabled:d.points===null,content:"Reset",onClick:function(){function N(){return i("reset_points")}return N}()})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Point Goal",children:[d.goal!==null?d.goal:"-/-",(0,e.createComponentVNode)(2,t.Button,{ml:2,icon:"pen",disabled:d.goal===null,content:"Edit",onClick:function(){function N(){return(0,f.modalOpen)(c,"set_points")}return N}()})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{children:(0,e.createVNode)(1,"box",null,[(0,e.createTextVNode)("1 minute of prison time should roughly equate to 150 points."),(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Sentences should not exceed 5000 points."),(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Permanent prisoners should not be given a point goal."),(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Prisoners who meet their point goal will be able to automatically access their locker and return to the station using the shuttle.")],4,{hidden:d.goal===null})})]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Tracking Implants",children:h.map(function(N){return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{p:1,backgroundColor:"rgba(255, 255, 255, 0.05)",children:[(0,e.createComponentVNode)(2,t.Box,{bold:!0,children:["Subject: ",N.subject]}),(0,e.createComponentVNode)(2,t.Box,{children:[" ",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Location",children:N.location}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Health",children:N.health}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Prisoner",children:(0,e.createComponentVNode)(2,t.Button,{icon:"exclamation-triangle",content:"Warn",tooltip:"Broadcast a message to this poor sod",onClick:function(){function V(){return(0,f.modalOpen)(c,"warn",{uid:N.uid})}return V}()})})]})]},N.subject)]}),(0,e.createVNode)(1,"br")],4)})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Chemical Implants",children:v.map(function(N){return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{p:1,backgroundColor:"rgba(255, 255, 255, 0.05)",children:[(0,e.createComponentVNode)(2,t.Box,{bold:!0,children:["Subject: ",N.name]}),(0,e.createComponentVNode)(2,t.Box,{children:[" ",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Remaining Reagents",children:N.volume})}),p.map(function(V){return(0,e.createComponentVNode)(2,t.Button,{mt:2,disabled:N.volumec;return(0,e.createComponentVNode)(2,t.ImageButton,{fluid:!0,title:N.name,dmIcon:N.icon,dmIconState:N.icon_state,buttonsAlt:(0,e.createComponentVNode)(2,t.Button,{bold:!0,translucent:!0,fontSize:1.5,tooltip:V&&"Not enough tickets",disabled:V,onClick:function(){function S(){return g("purchase",{purchase:N.itemID})}return S}(),children:[N.cost,(0,e.createComponentVNode)(2,t.Icon,{m:0,mt:.25,name:"ticket",color:V?"bad":"good",size:1.6})]}),children:N.desc},N.name)})})})})})})}return b}()},94813:function(T,r,n){"use strict";r.__esModule=!0,r.RCD=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(3939),b=n(49148),y=r.RCD=function(){function i(u,s){return(0,e.createComponentVNode)(2,o.Window,{width:480,height:670,children:[(0,e.createComponentVNode)(2,f.ComplexModal),(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,I),(0,e.createComponentVNode)(2,k),(0,e.createComponentVNode)(2,l),(0,e.createComponentVNode)(2,c)]})})]})}return i}(),I=function(u,s){var d=(0,a.useBackend)(s),v=d.data,h=v.matter,C=v.max_matter,p=C*.7,N=C*.25;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Matter Storage",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ranges:{good:[p,1/0],average:[N,p],bad:[-1/0,N]},value:h,maxValue:C,children:(0,e.createComponentVNode)(2,t.Stack.Item,{textAlign:"center",children:h+" / "+C+" units"})})})})},k=function(){return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Construction Type",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,g,{mode_type:"Floors and Walls"}),(0,e.createComponentVNode)(2,g,{mode_type:"Airlocks"}),(0,e.createComponentVNode)(2,g,{mode_type:"Windows"}),(0,e.createComponentVNode)(2,g,{mode_type:"Deconstruction"})]})})})},g=function(u,s){var d=(0,a.useBackend)(s),v=d.act,h=d.data,C=u.mode_type,p=h.mode;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,color:"transparent",content:C,selected:p===C?1:0,onClick:function(){function N(){return v("mode",{mode:C})}return N}()})})},l=function(u,s){var d=(0,a.useBackend)(s),v=d.act,h=d.data,C=h.door_name,p=h.electrochromic,N=h.airlock_glass;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Airlock Settings",children:(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,color:"transparent",icon:"pen-alt",content:(0,e.createFragment)([(0,e.createTextVNode)("Rename: "),(0,e.createVNode)(1,"b",null,C,0)],0),onClick:function(){function V(){return(0,f.modalOpen)(s,"renameAirlock")}return V}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:N===1&&(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:p?"toggle-on":"toggle-off",content:"Electrochromic",selected:p,onClick:function(){function V(){return v("electrochromic")}return V}()})})]})})})},c=function(u,s){var d=(0,a.useBackend)(s),v=d.act,h=d.data,C=h.tab,p=h.locked,N=h.one_access,V=h.selected_accesses,S=h.regions;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Tabs,{fluid:!0,children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"cog",selected:C===1,onClick:function(){function B(){return v("set_tab",{tab:1})}return B}(),children:"Airlock Types"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:C===2,icon:"list",onClick:function(){function B(){return v("set_tab",{tab:2})}return B}(),children:"Airlock Access"})]})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:C===1?(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Types",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,m,{check_number:0})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,m,{check_number:1})})]})}):C===2&&p?(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Access",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"lock-open",content:"Unlock",onClick:function(){function B(){return v("set_lock",{new_lock:"unlock"})}return B}()}),children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",align:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"lock",size:"5",mb:3}),(0,e.createVNode)(1,"br"),"Airlock access selection is currently locked."]})})}):(0,e.createComponentVNode)(2,b.AccessList,{sectionButtons:(0,e.createComponentVNode)(2,t.Button,{icon:"lock",content:"Lock",onClick:function(){function B(){return v("set_lock",{new_lock:"lock"})}return B}()}),usedByRcd:1,rcdButtons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:N,content:"One",onClick:function(){function B(){return v("set_one_access",{access:"one"})}return B}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:!N,width:4,content:"All",onClick:function(){function B(){return v("set_one_access",{access:"all"})}return B}()})],4),accesses:S,selectedList:V,accessMod:function(){function B(L){return v("set",{access:L})}return B}(),grantAll:function(){function B(){return v("grant_all")}return B}(),denyAll:function(){function B(){return v("clear_all")}return B}(),grantDep:function(){function B(L){return v("grant_region",{region:L})}return B}(),denyDep:function(){function B(L){return v("deny_region",{region:L})}return B}()})})],4)},m=function(u,s){for(var d=(0,a.useBackend)(s),v=d.act,h=d.data,C=h.door_types_ui_list,p=h.door_type,N=u.check_number,V=[],S=0;Sf?w=(0,e.createComponentVNode)(2,t.Box,{color:"red",bold:!0,mb:1,children:"There are new messages"}):w=(0,e.createComponentVNode)(2,t.Box,{color:"label",mb:1,children:"There are no new messages"}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Main Menu",buttons:(0,e.createComponentVNode)(2,t.Button,{width:9,content:L?"Speaker Off":"Speaker On",selected:!L,icon:L?"volume-mute":"volume-up",onClick:function(){function A(){return N("toggleSilent")}return A}()}),children:[w,(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"View Messages",icon:S>f?"envelope-open-text":"envelope",onClick:function(){function A(){return N("setScreen",{setScreen:6})}return A}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{mt:1,children:[(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"Request Assistance",icon:"hand-paper",onClick:function(){function A(){return N("setScreen",{setScreen:1})}return A}()}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"Request Supplies",icon:"box",onClick:function(){function A(){return N("setScreen",{setScreen:2})}return A}()}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"Request Secondary Goal",icon:"clipboard-list",onClick:function(){function A(){return N("setScreen",{setScreen:11})}return A}()}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"Relay Anonymous Information",icon:"comment",onClick:function(){function A(){return N("setScreen",{setScreen:3})}return A}()})]})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{mt:1,children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"Print Shipping Label",icon:"tag",onClick:function(){function A(){return N("setScreen",{setScreen:9})}return A}()}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"View Shipping Logs",icon:"clipboard-list",onClick:function(){function A(){return N("setScreen",{setScreen:10})}return A}()})]})}),!!B&&(0,e.createComponentVNode)(2,t.Stack.Item,{mt:1,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"Send Station-Wide Announcement",icon:"bullhorn",onClick:function(){function A(){return N("setScreen",{setScreen:8})}return A}()})})]})})},l=function(h,C){var p=(0,a.useBackend)(C),N=p.act,V=p.data,S=V.department,B=[],L;switch(h.purpose){case"ASSISTANCE":B=V.assist_dept,L="Request assistance from another department";break;case"SUPPLIES":B=V.supply_dept,L="Request supplies from another department";break;case"INFO":B=V.info_dept,L="Relay information to another department";break}return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:L,buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function w(){return N("setScreen",{setScreen:0})}return w}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:B.filter(function(w){return w!==S}).map(function(w){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:w,textAlign:"right",className:"candystripe",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Message",icon:"envelope",onClick:function(){function A(){return N("writeInput",{write:w,priority:y})}return A}()}),(0,e.createComponentVNode)(2,t.Button,{content:"High Priority",icon:"exclamation-circle",onClick:function(){function A(){return N("writeInput",{write:w,priority:I})}return A}()})]},w)})})})})},c=function(h,C){var p=(0,a.useBackend)(C),N=p.act,V=p.data,S;switch(h.type){case"SUCCESS":S="Message sent successfully";break;case"FAIL":S="Unable to contact messaging server";break}return(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:S,buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function B(){return N("setScreen",{setScreen:0})}return B}()})})},m=function(h,C){var p=(0,a.useBackend)(C),N=p.act,V=p.data,S,B;switch(h.type){case"MESSAGES":S=V.message_log,B="Message Log";break;case"SHIPPING":S=V.shipping_log,B="Shipping label print log";break}return S.reverse(),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:B,buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function L(){return N("setScreen",{setScreen:0})}return L}()}),children:S.map(function(L){return(0,e.createComponentVNode)(2,t.Box,{textAlign:"left",children:[L.map(function(w,A){return(0,e.createVNode)(1,"div",null,w,0,null,A)}),(0,e.createVNode)(1,"hr")]},L)})})})},i=function(h,C){var p=(0,a.useBackend)(C),N=p.act,V=p.data,S=V.recipient,B=V.message,L=V.msgVerified,w=V.msgStamped;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Message Authentication",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function A(){return N("setScreen",{setScreen:0})}return A}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Recipient",children:S}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Message",children:B}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Validated by",color:"green",children:L}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Stamped by",color:"blue",children:w})]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",content:"Send Message",icon:"envelope",onClick:function(){function A(){return N("department",{department:S})}return A}()})})})],4)},u=function(h,C){var p=(0,a.useBackend)(C),N=p.act,V=p.data,S=V.message,B=V.announceAuth;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Station-Wide Announcement",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function L(){return N("setScreen",{setScreen:0})}return L}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Edit Message",icon:"edit",onClick:function(){function L(){return N("writeAnnouncement")}return L}()})],4),children:S})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{children:[B?(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",color:"green",children:"ID verified. Authentication accepted."}):(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",color:"label",children:"Swipe your ID card to authenticate yourself"}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,mt:2,textAlign:"center",content:"Send Announcement",icon:"bullhorn",disabled:!(B&&S),onClick:function(){function L(){return N("sendAnnouncement")}return L}()})]})})],4)},s=function(h,C){var p=(0,a.useBackend)(C),N=p.act,V=p.data,S=V.shipDest,B=V.msgVerified,L=V.ship_dept;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Section,{title:"Print Shipping Label",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function w(){return N("setScreen",{setScreen:0})}return w}()}),children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Destination",children:S}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Validated by",children:B})]}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,mt:1,textAlign:"center",content:"Print Label",icon:"print",disabled:!(S&&B),onClick:function(){function w(){return N("printLabel")}return w}()})]})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Destinations",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:L.map(function(w){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:w,textAlign:"right",className:"candystripe",children:(0,e.createComponentVNode)(2,t.Button,{content:S===w?"Selected":"Select",selected:S===w,onClick:function(){function A(){return N("shipSelect",{shipSelect:w})}return A}()})},w)})})})})],4)},d=function(h,C){var p=(0,a.useBackend)(C),N=p.act,V=p.data,S=V.secondaryGoalAuth,B=V.secondaryGoalEnabled;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Request Secondary Goal",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function L(){return N("setScreen",{setScreen:0})}return L}()})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{children:[B?S?(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",color:"green",children:"ID verified. Authentication accepted."}):(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",color:"label",children:"Swipe your ID card to authenticate yourself"}):(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",color:"label",children:"Complete your current goal first!"}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,mt:2,textAlign:"center",content:"Request Secondary Goal",icon:"clipboard-list",disabled:!(S&&B),onClick:function(){function L(){return N("requestSecondaryGoal")}return L}()})]})})],4)}},9861:function(T,r,n){"use strict";r.__esModule=!0,r.RndBackupConsole=r.LinkMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.RndBackupConsole=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=c.network_name,i=c.has_disk,u=c.disk_name,s=c.linked,d=c.techs,v=c.last_timestamp;return(0,e.createComponentVNode)(2,o.Window,{width:900,height:600,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Device Info",children:[(0,e.createComponentVNode)(2,t.Box,{mb:2,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Network",children:s?(0,e.createComponentVNode)(2,t.Button,{content:m,icon:"unlink",selected:1,onClick:function(){function h(){return l("unlink")}return h}()}):"None"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Loaded Disk",children:i?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:u+" (Last backup: "+v+")",icon:"save",selected:1,onClick:function(){function h(){return l("eject_disk")}return h}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"sign-in-alt",content:"Save all",onClick:function(){function h(){return l("saveall2disk")}return h}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"sign-out-alt",content:"Load all",onClick:function(){function h(){return l("saveall2network")}return h}()})],4):"None"})]})}),!!s||(0,e.createComponentVNode)(2,b)]}),(0,e.createComponentVNode)(2,t.Box,{mt:2,children:(0,e.createComponentVNode)(2,t.Section,{title:"Tech Info",children:(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Tech Name"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network Level"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Disk Level"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Actions"})]}),Object.keys(d).map(function(h){return!(d[h].network_level>0||d[h].disk_level>0)||(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:d[h].name}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d[h].network_level||"None"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d[h].disk_level||"None"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"sign-in-alt",content:"Load to network",disabled:!i||!s,onClick:function(){function C(){return l("savetech2network",{tech:h})}return C}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"sign-out-alt",content:"Load to disk",disabled:!i||!s,onClick:function(){function C(){return l("savetech2disk",{tech:h})}return C}()})]})]},h)})]})})})]})})}return y}(),b=r.LinkMenu=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=c.controllers;return(0,e.createComponentVNode)(2,t.Section,{title:"Setup Linkage",children:(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network Address"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network ID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Link"})]}),m.map(function(i){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:i.addr}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:i.net_id}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Link",icon:"link",onClick:function(){function u(){return l("linktonetworkcontroller",{target_controller:i.addr})}return u}()})})]},i.addr)})]})})}return y}()},68303:function(T,r,n){"use strict";r.__esModule=!0,r.AnalyzerMenu=void 0;var e=n(89005),a=n(35840),t=n(72253),o=n(36036),f=r.AnalyzerMenu=function(){function y(I,k){var g=(0,t.useBackend)(k),l=g.data,c=g.act,m=l.tech_levels,i=l.loaded_item,u=l.linked_analyzer,s=l.can_discover;return u?i?(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Section,{title:"Object Analysis",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{content:"Deconstruct",icon:"microscope",onClick:function(){function d(){c("deconstruct")}return d}()}),(0,e.createComponentVNode)(2,o.Button,{content:"Eject",icon:"eject",onClick:function(){function d(){c("eject_item")}return d}()}),!s||(0,e.createComponentVNode)(2,o.Button,{content:"Discover",icon:"atom",onClick:function(){function d(){c("discover")}return d}()})],0),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Name",children:i.name})})}),(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.Table,{id:"research-levels",children:[(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell),(0,e.createComponentVNode)(2,o.Table.Cell,{header:!0,children:"Research Field"}),(0,e.createComponentVNode)(2,o.Table.Cell,{header:!0,children:"Current Level"}),(0,e.createComponentVNode)(2,o.Table.Cell,{header:!0,children:"Object Level"}),(0,e.createComponentVNode)(2,o.Table.Cell,{header:!0,children:"New Level"})]}),m.map(function(d){return(0,e.createComponentVNode)(2,b,{techLevel:d},d.id)})]})})],4):(0,e.createComponentVNode)(2,o.Section,{title:"Analysis Menu",children:"No item loaded. Standing by..."}):(0,e.createComponentVNode)(2,o.Section,{title:"Analysis Menu",children:"NO SCIENTIFIC ANALYZER LINKED TO CONSOLE"})}return y}(),b=function(I,k){var g=I.techLevel,l=g.name,c=g.desc,m=g.level,i=g.object_level,u=g.ui_icon,s=i!=null,d=s&&i>=m?Math.max(i,m+1):m;return(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{icon:"circle-info",tooltip:c})}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:u})," ",l]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:m}),s?(0,e.createComponentVNode)(2,o.Table.Cell,{children:i}):(0,e.createComponentVNode)(2,o.Table.Cell,{className:"research-level-no-effect",children:"-"}),(0,e.createComponentVNode)(2,o.Table.Cell,{className:(0,a.classes)([d!==m&&"upgraded-level"]),children:d})]})}},37556:function(T,r,n){"use strict";r.__esModule=!0,r.DataDiskMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o="design",f="tech",b=function(c,m){var i=(0,a.useBackend)(m),u=i.data,s=i.act,d=u.disk_data;return d?(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Name",children:d.name}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Level",children:d.level}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Description",children:d.desc})]}),(0,e.createComponentVNode)(2,t.Box,{mt:"10px",children:(0,e.createComponentVNode)(2,t.Button,{content:"Upload to Database",icon:"arrow-up",onClick:function(){function v(){return s("updt_tech")}return v}()})})]}):null},y=function(c,m){var i=(0,a.useBackend)(m),u=i.data,s=i.act,d=u.disk_data;if(!d)return null;var v=d.name,h=d.lathe_types,C=d.materials,p=h.join(", ");return(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Name",children:v}),p?(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Lathe Types",children:p}):null,(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Required Materials"})]}),C.map(function(N){return(0,e.createComponentVNode)(2,t.Box,{children:["- ",(0,e.createVNode)(1,"span",null,N.name,0,{style:{"text-transform":"capitalize"}})," x ",N.amount]},N.name)}),(0,e.createComponentVNode)(2,t.Box,{mt:"10px",children:(0,e.createComponentVNode)(2,t.Button,{content:"Upload to Database",icon:"arrow-up",onClick:function(){function N(){return s("updt_design")}return N}()})})]})},I=function(c,m){var i=(0,a.useBackend)(m),u=i.act,s=i.data,d=s.disk_data;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.Section,Object.assign({buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button.Confirm,{content:"Erase",icon:"eraser",disabled:!d,onClick:function(){function v(){return u("erase_disk")}return v}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Eject",icon:"eject",onClick:function(){function v(){u("eject_disk")}return v}()})],4)},c)))},k=function(c,m){var i=(0,a.useBackend)(m),u=i.data,s=i.act,d=u.disk_type,v=u.to_copy,h=c.title;return(0,e.createComponentVNode)(2,I,{title:h,children:(0,e.createComponentVNode)(2,t.Box,{overflowY:"auto",overflowX:"hidden",maxHeight:"450px",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:v.sort(function(C,p){return C.name.localeCompare(p.name)}).map(function(C){var p=C.name,N=C.id;return(0,e.createComponentVNode)(2,t.LabeledList.Item,{noColon:!0,label:p,children:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-down",content:"Copy to Disk",onClick:function(){function V(){d===f?s("copy_tech",{id:N}):s("copy_design",{id:N})}return V}()})},N)})})})})},g=r.DataDiskMenu=function(){function l(c,m){var i=(0,a.useBackend)(m),u=i.data,s=u.disk_type,d=u.disk_data;if(!s)return(0,e.createComponentVNode)(2,t.Section,{title:"Data Disk",children:"No disk loaded."});switch(s){case o:return d?(0,e.createComponentVNode)(2,I,{title:"Design Disk",children:(0,e.createComponentVNode)(2,y)}):(0,e.createComponentVNode)(2,k,{title:"Design Disk"});case f:return d?(0,e.createComponentVNode)(2,I,{title:"Technology Disk",children:(0,e.createComponentVNode)(2,b)}):(0,e.createComponentVNode)(2,k,{title:"Technology Disk"});default:return(0,e.createFragment)([(0,e.createTextVNode)("UNRECOGNIZED DISK TYPE")],4)}}return l}()},16830:function(T,r,n){"use strict";r.__esModule=!0,r.LatheCategory=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(52662),f=r.LatheCategory=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.data,l=k.act,c=g.category,m=g.matching_designs,i=g.menu,u=i===4,s=u?"build":"imprint";return(0,e.createComponentVNode)(2,t.Section,{title:c,children:[(0,e.createComponentVNode)(2,o.LatheMaterials),(0,e.createComponentVNode)(2,t.Table,{className:"RndConsole__LatheCategory__MatchingDesigns",children:m.map(function(d){var v=d.id,h=d.name,C=d.can_build,p=d.materials;return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"print",content:h,disabled:C<1,onClick:function(){function N(){return l(s,{id:v,amount:1})}return N}()})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:C>=5?(0,e.createComponentVNode)(2,t.Button,{content:"x5",onClick:function(){function N(){return l(s,{id:v,amount:5})}return N}()}):null}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:C>=10?(0,e.createComponentVNode)(2,t.Button,{content:"x10",onClick:function(){function N(){return l(s,{id:v,amount:10})}return N}()}):null}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:p.map(function(N){return(0,e.createFragment)([" | ",(0,e.createVNode)(1,"span",N.is_red?"color-red":null,[N.amount,(0,e.createTextVNode)(" "),N.name],0)],0)})})]},v)})})]})}return b}()},70497:function(T,r,n){"use strict";r.__esModule=!0,r.LatheChemicalStorage=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.LatheChemicalStorage=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.data,g=I.act,l=k.loaded_chemicals,c=k.menu===4;return(0,e.createComponentVNode)(2,t.Section,{title:"Chemical Storage",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Purge All",icon:"trash",onClick:function(){function m(){var i=c?"disposeallP":"disposeallI";g(i)}return m}()}),(0,e.createComponentVNode)(2,t.LabeledList,{children:l.map(function(m){var i=m.volume,u=m.name,s=m.id;return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"* "+i+" of "+u,children:(0,e.createComponentVNode)(2,t.Button,{content:"Purge",icon:"trash",onClick:function(){function d(){var v=c?"disposeP":"disposeI";g(v,{id:s})}return d}()})},s)})})]})}return f}()},70864:function(T,r,n){"use strict";r.__esModule=!0,r.LatheMainMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(52662),f=n(68198),b=r.LatheMainMenu=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.data,c=g.act,m=l.menu,i=l.categories,u=m===4?"Protolathe":"Circuit Imprinter";return(0,e.createComponentVNode)(2,t.Section,{title:u+" Menu",children:[(0,e.createComponentVNode)(2,o.LatheMaterials),(0,e.createComponentVNode)(2,f.LatheSearch),(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,t.Flex,{wrap:"wrap",children:i.map(function(s){return(0,e.createComponentVNode)(2,t.Flex,{style:{"flex-basis":"50%","margin-bottom":"6px"},children:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-right",content:s,onClick:function(){function d(){c("setCategory",{category:s})}return d}()})},s)})})]})}return y}()},42878:function(T,r,n){"use strict";r.__esModule=!0,r.LatheMaterialStorage=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.LatheMaterialStorage=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.data,g=I.act,l=k.loaded_materials;return(0,e.createComponentVNode)(2,t.Section,{className:"RndConsole__LatheMaterialStorage",title:"Material Storage",children:(0,e.createComponentVNode)(2,t.Table,{children:l.map(function(c){var m=c.id,i=c.amount,u=c.name,s=function(){function C(p){var N=k.menu===4?"lathe_ejectsheet":"imprinter_ejectsheet";g(N,{id:m,amount:p})}return C}(),d=Math.floor(i/2e3),v=i<1,h=d===1?"":"s";return(0,e.createComponentVNode)(2,t.Table.Row,{className:v?"color-grey":"color-yellow",children:[(0,e.createComponentVNode)(2,t.Table.Cell,{minWidth:"210px",children:["* ",i," of ",u]}),(0,e.createComponentVNode)(2,t.Table.Cell,{minWidth:"110px",children:["(",d," sheet",h,")"]}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:i>=2e3?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:"1x",icon:"eject",onClick:function(){function C(){return s(1)}return C}()}),(0,e.createComponentVNode)(2,t.Button,{content:"C",icon:"eject",onClick:function(){function C(){return s("custom")}return C}()}),i>=2e3*5?(0,e.createComponentVNode)(2,t.Button,{content:"5x",icon:"eject",onClick:function(){function C(){return s(5)}return C}()}):null,(0,e.createComponentVNode)(2,t.Button,{content:"All",icon:"eject",onClick:function(){function C(){return s(50)}return C}()})],0):null})]},m)})})})}return f}()},52662:function(T,r,n){"use strict";r.__esModule=!0,r.LatheMaterials=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.LatheMaterials=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.data,g=k.total_materials,l=k.max_materials,c=k.max_chemicals,m=k.total_chemicals;return(0,e.createComponentVNode)(2,t.Box,{className:"RndConsole__LatheMaterials",mb:"10px",children:(0,e.createComponentVNode)(2,t.Table,{width:"auto",children:[(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Material Amount:"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:g}),l?(0,e.createComponentVNode)(2,t.Table.Cell,{children:" / "+l}):null]}),(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Chemical Amount:"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:m}),c?(0,e.createComponentVNode)(2,t.Table.Cell,{children:" / "+c}):null]})]})})}return f}()},9681:function(T,r,n){"use strict";r.__esModule=!0,r.LatheMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(12644),f=n(70864),b=n(16830),y=n(42878),I=n(70497),k=["menu"];function g(u,s){if(u==null)return{};var d={};for(var v in u)if({}.hasOwnProperty.call(u,v)){if(s.includes(v))continue;d[v]=u[v]}return d}var l=t.Tabs.Tab,c=function(s,d){var v=(0,a.useBackend)(d),h=v.act,C=v.data,p=C.menu===o.MENU.LATHE?["nav_protolathe",C.submenu_protolathe]:["nav_imprinter",C.submenu_imprinter],N=p[0],V=p[1],S=s.menu,B=g(s,k);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,l,Object.assign({selected:V===S,onClick:function(){function L(){return h(N,{menu:S})}return L}()},B)))},m=function(s){switch(s){case o.PRINTER_MENU.MAIN:return(0,e.createComponentVNode)(2,f.LatheMainMenu);case o.PRINTER_MENU.SEARCH:return(0,e.createComponentVNode)(2,b.LatheCategory);case o.PRINTER_MENU.MATERIALS:return(0,e.createComponentVNode)(2,y.LatheMaterialStorage);case o.PRINTER_MENU.CHEMICALS:return(0,e.createComponentVNode)(2,I.LatheChemicalStorage)}},i=r.LatheMenu=function(){function u(s,d){var v=(0,a.useBackend)(d),h=v.data,C=h.menu,p=h.linked_lathe,N=h.linked_imprinter;return C===o.MENU.LATHE&&!p?(0,e.createComponentVNode)(2,t.Box,{children:"NO PROTOLATHE LINKED TO CONSOLE"}):C===o.MENU.IMPRINTER&&!N?(0,e.createComponentVNode)(2,t.Box,{children:"NO CIRCUIT IMPRITER LINKED TO CONSOLE"}):(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,c,{menu:o.PRINTER_MENU.MAIN,icon:"bars",children:"Main Menu"}),(0,e.createComponentVNode)(2,c,{menu:o.PRINTER_MENU.MATERIALS,icon:"layer-group",children:"Materials"}),(0,e.createComponentVNode)(2,c,{menu:o.PRINTER_MENU.CHEMICALS,icon:"flask-vial",children:"Chemicals"})]}),m(h.menu===o.MENU.LATHE?h.submenu_protolathe:h.submenu_imprinter)]})}return u}()},68198:function(T,r,n){"use strict";r.__esModule=!0,r.LatheSearch=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.LatheSearch=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.act;return(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Input,{placeholder:"Search...",onEnter:function(){function g(l,c){return k("search",{to_search:c})}return g}()})})}return f}()},81421:function(T,r,n){"use strict";r.__esModule=!0,r.LinkMenu=void 0;var e=n(89005),a=n(72253),t=n(98595),o=n(36036),f=r.LinkMenu=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.controllers;return(0,e.createComponentVNode)(2,t.Window,{width:800,height:550,children:(0,e.createComponentVNode)(2,t.Window.Content,{children:(0,e.createComponentVNode)(2,o.Section,{title:"Setup Linkage",children:(0,e.createComponentVNode)(2,o.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,o.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Network Address"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Network ID"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Link"})]}),c.map(function(m){return(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:m.addr}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:m.net_id}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{content:"Link",icon:"link",onClick:function(){function i(){return g("linktonetworkcontroller",{target_controller:m.addr})}return i}()})})]},m.addr)})]})})})})}return b}()},6256:function(T,r,n){"use strict";r.__esModule=!0,r.SettingsMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.SettingsMenu=function(){function y(I,k){return(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,f),(0,e.createComponentVNode)(2,b)]})}return y}(),f=function(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=c.sync,i=c.admin;return(0,e.createComponentVNode)(2,t.Section,{title:"Settings",children:(0,e.createComponentVNode)(2,t.Flex,{direction:"column",align:"flex-start",children:[(0,e.createComponentVNode)(2,t.Button,{color:"red",icon:"unlink",content:"Disconnect from Research Network",onClick:function(){function u(){l("unlink")}return u}()}),i===1?(0,e.createComponentVNode)(2,t.Button,{icon:"gears",color:"red",content:"[ADMIN] Maximize research levels",onClick:function(){function u(){return l("maxresearch")}return u}()}):null]})})},b=function(I,k){var g=(0,a.useBackend)(k),l=g.data,c=g.act,m=l.linked_analyzer,i=l.linked_lathe,u=l.linked_imprinter;return(0,e.createComponentVNode)(2,t.Section,{title:"Linked Devices",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"link",content:"Re-sync with Nearby Devices",onClick:function(){function s(){return c("find_device")}return s}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Scientific Analyzer",children:(0,e.createComponentVNode)(2,t.Button,{icon:"unlink",disabled:!m,content:m?"Unlink":"Undetected",onClick:function(){function s(){return c("disconnect",{item:"analyze"})}return s}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Protolathe",children:(0,e.createComponentVNode)(2,t.Button,{icon:"unlink",disabled:!i,content:i?"Unlink":"Undetected",onClick:function(){function s(){c("disconnect",{item:"lathe"})}return s}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Circuit Imprinter",children:(0,e.createComponentVNode)(2,t.Button,{icon:"unlink",disabled:!u,content:u?"Unlink":"Undetected",onClick:function(){function s(){return c("disconnect",{item:"imprinter"})}return s}()})})]})})}},12644:function(T,r,n){"use strict";r.__esModule=!0,r.RndConsole=r.PRINTER_MENU=r.MENU=void 0;var e=n(89005),a=n(72253),t=n(98595),o=n(36036),f=n(35840),b=n(37556),y=n(9681),I=n(81421),k=n(6256),g=n(68303),l=["menu"];function c(p,N){if(p==null)return{};var V={};for(var S in p)if({}.hasOwnProperty.call(p,S)){if(N.includes(S))continue;V[S]=p[S]}return V}var m=o.Tabs.Tab,i=r.MENU={MAIN:0,DISK:2,ANALYZE:3,LATHE:4,IMPRINTER:5,SETTINGS:6},u=r.PRINTER_MENU={MAIN:0,SEARCH:1,MATERIALS:2,CHEMICALS:3},s=function(N){switch(N){case i.MAIN:return(0,e.createComponentVNode)(2,C);case i.DISK:return(0,e.createComponentVNode)(2,b.DataDiskMenu);case i.ANALYZE:return(0,e.createComponentVNode)(2,g.AnalyzerMenu);case i.LATHE:case i.IMPRINTER:return(0,e.createComponentVNode)(2,y.LatheMenu);case i.SETTINGS:return(0,e.createComponentVNode)(2,k.SettingsMenu);default:return"UNKNOWN MENU"}},d=function(N,V){var S=(0,a.useBackend)(V),B=S.act,L=S.data,w=L.menu,A=N.menu,x=c(N,l);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,m,Object.assign({selected:w===A,onClick:function(){function E(){return B("nav",{menu:A})}return E}()},x)))},v=r.RndConsole=function(){function p(N,V){var S=(0,a.useBackend)(V),B=S.act,L=S.data;if(!L.linked)return(0,e.createComponentVNode)(2,I.LinkMenu);var w=L.menu,A=L.linked_analyzer,x=L.linked_lathe,E=L.linked_imprinter,P=L.wait_message;return(0,e.createComponentVNode)(2,t.Window,{width:800,height:550,children:(0,e.createComponentVNode)(2,t.Window.Content,{children:(0,e.createComponentVNode)(2,o.Box,{className:"RndConsole",children:[(0,e.createComponentVNode)(2,o.Tabs,{children:[(0,e.createComponentVNode)(2,d,{icon:"flask",menu:i.MAIN,children:"Research"}),!!A&&(0,e.createComponentVNode)(2,d,{icon:"microscope",menu:i.ANALYZE,children:"Analyze"}),!!x&&(0,e.createComponentVNode)(2,d,{icon:"print",menu:i.LATHE,children:"Protolathe"}),!!E&&(0,e.createComponentVNode)(2,d,{icon:"memory",menu:i.IMPRINTER,children:"Imprinter"}),(0,e.createComponentVNode)(2,d,{icon:"floppy-disk",menu:i.DISK,children:"Disk"}),(0,e.createComponentVNode)(2,d,{icon:"cog",menu:i.SETTINGS,children:"Settings"})]}),s(w),(0,e.createComponentVNode)(2,h)]})})})}return p}(),h=function(N,V){var S=(0,a.useBackend)(V),B=S.data,L=B.wait_message;return L?(0,e.createComponentVNode)(2,o.Box,{className:"RndConsole__Overlay",children:(0,e.createComponentVNode)(2,o.Box,{className:"RndConsole__Overlay__Wrapper",children:(0,e.createComponentVNode)(2,o.NoticeBox,{color:"black",children:L})})}):null},C=function(N,V){var S=(0,a.useBackend)(V),B=S.data,L=B.tech_levels;return(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.Table,{id:"research-levels",children:[(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell),(0,e.createComponentVNode)(2,o.Table.Cell,{header:!0,children:"Research Field"}),(0,e.createComponentVNode)(2,o.Table.Cell,{header:!0,children:"Level"})]}),L.map(function(w){var A=w.id,x=w.name,E=w.desc,P=w.level,D=w.ui_icon;return(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{icon:"circle-info",tooltip:E})}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:D})," ",x]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:P})]},A)})]})})}},29205:function(T,r,n){"use strict";r.__esModule=!0,r.RndNetController=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),f=n(98595),b=r.RndNetController=function(){function k(g,l){var c=(0,t.useBackend)(l),m=c.act,i=c.data,u=i.ion,s=(0,t.useLocalState)(l,"mainTabIndex",0),d=s[0],v=s[1],h=function(){function C(p){switch(p){case 0:return(0,e.createComponentVNode)(2,y);case 1:return(0,e.createComponentVNode)(2,I);default:return"SOMETHING WENT VERY WRONG PLEASE AHELP"}}return C}();return(0,e.createComponentVNode)(2,f.Window,{width:900,height:600,children:(0,e.createComponentVNode)(2,f.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,o.Tabs,{children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"wrench",selected:d===0,onClick:function(){function C(){return v(0)}return C}(),children:"Network Management"},"ConfigPage"),(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"floppy-disk",selected:d===1,onClick:function(){function C(){return v(1)}return C}(),children:"Design Management"},"DesignPage")]}),h(d)]})})}return k}(),y=function(g,l){var c=(0,t.useBackend)(l),m=c.act,i=c.data,u=(0,t.useLocalState)(l,"filterType","ALL"),s=u[0],d=u[1],v=i.network_password,h=i.network_name,C=i.devices,p=[];p.push(s),s==="MSC"&&(p.push("BCK"),p.push("PGN"));var N=s==="ALL"?C:C.filter(function(V){return p.indexOf(V.dclass)>-1});return(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Section,{title:"Network Configuration",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Network Name",children:(0,e.createComponentVNode)(2,o.Button,{content:h||"Unset",selected:h,icon:"edit",onClick:function(){function V(){return m("network_name")}return V}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Network Password",children:(0,e.createComponentVNode)(2,o.Button,{content:v||"Unset",selected:v,icon:"lock",onClick:function(){function V(){return m("network_password")}return V}()})})]})}),(0,e.createComponentVNode)(2,o.Section,{title:"Connected Devices",children:[(0,e.createComponentVNode)(2,o.Tabs,{children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:s==="ALL",onClick:function(){function V(){return d("ALL")}return V}(),icon:"network-wired",children:"All Devices"},"AllDevices"),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:s==="SRV",onClick:function(){function V(){return d("SRV")}return V}(),icon:"server",children:"R&D Servers"},"RNDServers"),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:s==="RDC",onClick:function(){function V(){return d("RDC")}return V}(),icon:"desktop",children:"R&D Consoles"},"RDConsoles"),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:s==="MFB",onClick:function(){function V(){return d("MFB")}return V}(),icon:"industry",children:"Exosuit Fabricators"},"Mechfabs"),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:s==="MSC",onClick:function(){function V(){return d("MSC")}return V}(),icon:"microchip",children:"Miscellaneous Devices"},"Misc")]}),(0,e.createComponentVNode)(2,o.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,o.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Device Name"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Device ID"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Unlink"})]}),N.map(function(V){return(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:V.name}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:V.id}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{content:"Unlink",icon:"unlink",color:"red",onClick:function(){function S(){return m("unlink_device",{dclass:V.dclass,uid:V.id})}return S}()})})]},V.id)})]})]})],4)},I=function(g,l){var c=(0,t.useBackend)(l),m=c.act,i=c.data,u=i.designs,s=(0,t.useLocalState)(l,"searchText",""),d=s[0],v=s[1];return(0,e.createComponentVNode)(2,o.Section,{title:"Design Management",children:[(0,e.createComponentVNode)(2,o.Input,{fluid:!0,placeholder:"Search for designs",mb:2,onInput:function(){function h(C,p){return v(p)}return h}()}),u.filter((0,a.createSearch)(d,function(h){return h.name})).map(function(h){return(0,e.createComponentVNode)(2,o.Button.Checkbox,{fluid:!0,content:h.name,checked:!h.blacklisted,onClick:function(){function C(){return m(h.blacklisted?"unblacklist_design":"blacklist_design",{d_uid:h.uid})}return C}()},h.name)})]})}},63315:function(T,r,n){"use strict";r.__esModule=!0,r.RndServer=void 0;var e=n(89005),a=n(72253),t=n(44879),o=n(36036),f=n(98595),b=r.RndServer=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.active,s=i.network_name;return(0,e.createComponentVNode)(2,f.Window,{width:600,height:500,resizable:!0,children:(0,e.createComponentVNode)(2,f.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,o.Section,{title:"Server Configuration",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Machine power",children:(0,e.createComponentVNode)(2,o.Button,{content:u?"On":"Off",selected:u,icon:"power-off",onClick:function(){function d(){return m("toggle_active")}return d}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Link status",children:s===null?(0,e.createComponentVNode)(2,o.Box,{color:"red",children:"Unlinked"}):(0,e.createComponentVNode)(2,o.Box,{color:"green",children:"Linked"})})]})}),s===null?(0,e.createComponentVNode)(2,I):(0,e.createComponentVNode)(2,y)]})})}return k}(),y=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.network_name;return(0,e.createComponentVNode)(2,o.Section,{title:"Network Info",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Connected network ID",children:u}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Unlink",children:(0,e.createComponentVNode)(2,o.Button,{content:"Unlink",icon:"unlink",color:"red",onClick:function(){function s(){return m("unlink")}return s}()})})]})})},I=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.controllers;return(0,e.createComponentVNode)(2,o.Section,{title:"Detected Cores",children:(0,e.createComponentVNode)(2,o.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,o.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Network ID"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Link"})]}),u.map(function(s){return(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:s.netname}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{content:"Link",icon:"link",onClick:function(){function d(){return m("link",{addr:s.addr})}return d}()})})]},s.addr)})]})})}},26109:function(T,r,n){"use strict";r.__esModule=!0,r.RobotSelfDiagnosis=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(25328),b=function(k,g){var l=k/g;return l<=.2?"good":l<=.5?"average":"bad"},y=r.RobotSelfDiagnosis=function(){function I(k,g){var l=(0,a.useBackend)(g),c=l.data,m=c.component_data;return(0,e.createComponentVNode)(2,o.Window,{width:280,height:480,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:m.map(function(i,u){return(0,e.createComponentVNode)(2,t.Section,{title:(0,f.capitalize)(i.name),children:i.installed<=0?(0,e.createComponentVNode)(2,t.NoticeBox,{m:-.5,height:3.5,color:"red",style:{"font-style":"normal"},children:(0,e.createComponentVNode)(2,t.Flex,{height:"100%",children:(0,e.createComponentVNode)(2,t.Flex.Item,{grow:1,textAlign:"center",align:"center",color:"#e8e8e8",children:i.installed===-1?"Destroyed":"Missing"})})}):(0,e.createComponentVNode)(2,t.Flex,{children:[(0,e.createComponentVNode)(2,t.Flex.Item,{width:"72%",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Brute Damage",color:b(i.brute_damage,i.max_damage),children:i.brute_damage}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Burn Damage",color:b(i.electronic_damage,i.max_damage),children:i.electronic_damage})]})}),(0,e.createComponentVNode)(2,t.Flex.Item,{width:"50%",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Powered",color:i.powered?"good":"bad",children:i.powered?"Yes":"No"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Enabled",color:i.status?"good":"bad",children:i.status?"Yes":"No"})]})})]})},u)})})})}return I}()},97997:function(T,r,n){"use strict";r.__esModule=!0,r.RoboticsControlConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.RoboticsControlConsole=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=c.can_hack,i=c.safety,u=c.show_lock_all,s=c.cyborgs,d=s===void 0?[]:s;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:460,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[!!u&&(0,e.createComponentVNode)(2,t.Section,{title:"Emergency Lock Down",children:[(0,e.createComponentVNode)(2,t.Button,{icon:i?"lock":"unlock",content:i?"Disable Safety":"Enable Safety",selected:i,onClick:function(){function v(){return l("arm",{})}return v}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"lock",disabled:i,content:"Lock ALL Cyborgs",color:"bad",onClick:function(){function v(){return l("masslock",{})}return v}()})]}),(0,e.createComponentVNode)(2,b,{cyborgs:d,can_hack:m})]})})}return y}(),b=function(I,k){var g=I.cyborgs,l=I.can_hack,c=(0,a.useBackend)(k),m=c.act,i=c.data,u="Detonate";return i.detonate_cooldown>0&&(u+=" ("+i.detonate_cooldown+"s)"),g.length?g.map(function(s){return(0,e.createComponentVNode)(2,t.Section,{title:s.name,buttons:(0,e.createFragment)([!!s.hackable&&!s.emagged&&(0,e.createComponentVNode)(2,t.Button,{icon:"terminal",content:"Hack",color:"bad",onClick:function(){function d(){return m("hackbot",{uid:s.uid})}return d}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:s.locked_down?"unlock":"lock",color:s.locked_down?"good":"default",content:s.locked_down?"Release":"Lockdown",disabled:!i.auth,onClick:function(){function d(){return m("stopbot",{uid:s.uid})}return d}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"bomb",content:u,disabled:!i.auth||i.detonate_cooldown>0,color:"bad",onClick:function(){function d(){return m("killbot",{uid:s.uid})}return d}()})],0),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:(0,e.createComponentVNode)(2,t.Box,{color:s.status?"bad":s.locked_down?"average":"good",children:s.status?"Not Responding":s.locked_down?"Locked Down":"Nominal"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Location",children:(0,e.createComponentVNode)(2,t.Box,{children:s.locstring})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Integrity",children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:s.health>50?"good":"bad",value:s.health/100})}),typeof s.charge=="number"&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cell Charge",children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:s.charge>30?"good":"bad",value:s.charge/100})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cell Capacity",children:(0,e.createComponentVNode)(2,t.Box,{color:s.cell_capacity<3e4?"average":"good",children:s.cell_capacity})})],4)||(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cell",children:(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:"No Power Cell"})}),!!s.is_hacked&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Safeties",children:(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:"DISABLED"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Module",children:s.module}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Master AI",children:(0,e.createComponentVNode)(2,t.Box,{color:s.synchronization?"default":"average",children:s.synchronization||"None"})})]})},s.uid)}):(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No cyborg units detected within access parameters."})}},54431:function(T,r,n){"use strict";r.__esModule=!0,r.Safe=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.Safe=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.dial,s=i.open,d=i.locked,v=i.contents;return(0,e.createComponentVNode)(2,o.Window,{theme:"safe",width:600,height:800,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Box,{className:"Safe--engraving",children:[(0,e.createComponentVNode)(2,b),(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Box,{className:"Safe--engraving--hinge",top:"25%"}),(0,e.createComponentVNode)(2,t.Box,{className:"Safe--engraving--hinge",top:"75%"})]}),(0,e.createComponentVNode)(2,t.Icon,{className:"Safe--engraving--arrow",name:"long-arrow-alt-down",size:"3"}),(0,e.createVNode)(1,"br"),s?(0,e.createComponentVNode)(2,y):(0,e.createComponentVNode)(2,t.Box,{as:"img",className:"Safe--dial",src:"safe_dial.png",style:{transform:"rotate(-"+3.6*u+"deg)","z-index":0}})]}),!s&&(0,e.createComponentVNode)(2,I)]})})}return k}(),b=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.dial,s=i.open,d=i.locked,v=function(C,p){return(0,e.createComponentVNode)(2,t.Button,{disabled:s||p&&!d,icon:"arrow-"+(p?"right":"left"),content:(p?"Right":"Left")+" "+C,iconRight:p,onClick:function(){function N(){return m(p?"turnleft":"turnright",{num:C})}return N}(),style:{"z-index":10}})};return(0,e.createComponentVNode)(2,t.Box,{className:"Safe--dialer",children:[(0,e.createComponentVNode)(2,t.Button,{disabled:d,icon:s?"lock":"lock-open",content:s?"Close":"Open",mb:"0.5rem",onClick:function(){function h(){return m("open")}return h}()}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Box,{position:"absolute",children:[v(50),v(10),v(1)]}),(0,e.createComponentVNode)(2,t.Box,{className:"Safe--dialer--right",position:"absolute",right:"5px",children:[v(1,!0),v(10,!0),v(50,!0)]}),(0,e.createComponentVNode)(2,t.Box,{className:"Safe--dialer--number",children:u})]})},y=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.contents;return(0,e.createComponentVNode)(2,t.Box,{className:"Safe--contents",overflow:"auto",children:u.map(function(s,d){return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{mb:"0.5rem",onClick:function(){function v(){return m("retrieve",{index:d+1})}return v}(),children:[(0,e.createComponentVNode)(2,t.Box,{as:"img",src:s.sprite+".png",verticalAlign:"middle",ml:"-6px",mr:"0.5rem"}),s.name]}),(0,e.createVNode)(1,"br")],4,s)})})},I=function(g,l){return(0,e.createComponentVNode)(2,t.Section,{className:"Safe--help",title:"Safe opening instructions (because you all keep forgetting)",children:[(0,e.createComponentVNode)(2,t.Box,{children:["1. Turn the dial left to the first number.",(0,e.createVNode)(1,"br"),"2. Turn the dial right to the second number.",(0,e.createVNode)(1,"br"),"3. Continue repeating this process for each number, switching between left and right each time.",(0,e.createVNode)(1,"br"),"4. Open the safe."]}),(0,e.createComponentVNode)(2,t.Box,{bold:!0,children:"To lock fully, turn the dial to the left after closing the safe."})]})}},29740:function(T,r,n){"use strict";r.__esModule=!0,r.SatelliteControlSatellitesList=r.SatelliteControlMapView=r.SatelliteControlFooter=r.SatelliteControl=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.SatelliteControl=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=(0,a.useLocalState)(l,"tabIndex",i.tabIndex),s=u[0],d=u[1],v=function(){function C(p){d(p),m("set_tab_index",{tab_index:p})}return C}(),h=function(){function C(p){switch(p){case 0:return(0,e.createComponentVNode)(2,b);case 1:return(0,e.createComponentVNode)(2,y);default:return"WE SHOULDN'T BE HERE!"}}return C}();return(0,e.createComponentVNode)(2,o.Window,{width:800,height:600,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"table",selected:s===0,onClick:function(){function C(){return v(0)}return C}(),children:"Satellites"},"Satellites"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"map-marked-alt",selected:s===1,onClick:function(){function C(){return v(1)}return C}(),children:"Map View"},"MapView")]})}),h(s),(0,e.createComponentVNode)(2,I)]})})})}return k}(),b=r.SatelliteControlSatellitesList=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.satellites;return(0,e.createComponentVNode)(2,t.Section,{title:"Satellite Network Control",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:u.map(function(s){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"#"+s.id,children:[s.mode," ",(0,e.createComponentVNode)(2,t.Button,{content:s.active?"Deactivate":"Activate",icon:"arrow-circle-right",onClick:function(){function d(){return m("toggle",{id:s.id})}return d}()})]},s.id)})})})}return k}(),y=r.SatelliteControlMapView=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.satellites,s=i.has_goal,d=i.defended,v=i.collisions,h=i.fake_meteors,C=i.zoom,p=i.offsetX,N=i.offsetY,V=0;return(0,e.createComponentVNode)(2,t.Box,{height:"100vh",mb:"0.5rem",overflow:"hidden",children:(0,e.createComponentVNode)(2,t.NanoMap,{zoom:C,offsetX:p,offsetY:N,onZoom:function(){function S(B){return m("set_zoom",{zoom:B})}return S}(),onOffsetChange:function(){function S(B,L){return m("set_offset",{offset_x:L.offsetX,offset_y:L.offsetY})}return S}(),children:[u.map(function(S){return(0,e.createComponentVNode)(2,t.NanoMap.MarkerIcon,{x:S.x,y:S.y,icon:"satellite",tooltip:S.active?"Shield Satellite":"Inactive Shield Satellite",color:S.active?"white":"grey",onClick:function(){function B(){return m("toggle",{id:S.id})}return B}()},V++)}),s&&d.map(function(S){return(0,e.createComponentVNode)(2,t.NanoMap.MarkerIcon,{x:S.x,y:S.y,icon:"circle",tooltip:"Successful Defense",color:"blue"},V++)}),s&&v.map(function(S){return(0,e.createComponentVNode)(2,t.NanoMap.MarkerIcon,{x:S.x,y:S.y,icon:"x",tooltip:"Meteor Hit",color:"red"},V++)}),s&&h.map(function(S){return(0,e.createComponentVNode)(2,t.NanoMap.MarkerIcon,{x:S.x,y:S.y,icon:"meteor",tooltip:"Incoming Meteor",color:"white"},V++)})]})})}return k}(),I=r.SatelliteControlFooter=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.notice,s=i.notice_color,d=i.has_goal,v=i.coverage,h=i.coverage_goal,C=i.testing;return(0,e.createFragment)([d&&(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Station Shield Coverage",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,horizontal:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:1,children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:v>=h?"good":"average",value:v,maxValue:100,children:[v,"%"]})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Check coverage",disabled:C,onClick:function(){function p(){return m("begin_test")}return p}()})})]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{color:s,children:u})],0)}return k}()},44162:function(T,r,n){"use strict";r.__esModule=!0,r.SecureStorage=void 0;var e=n(89005),a=n(35840),t=n(72253),o=n(36036),f=n(98595),b=n(36352),y=n(92986),I=r.SecureStorage=function(){function c(m,i){return(0,e.createComponentVNode)(2,f.Window,{theme:"securestorage",height:500,width:280,children:(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,g)})})})})}return c}(),k=function(m,i){var u=(0,t.useBackend)(i),s=u.act,d=window.event?m.which:m.keyCode;if(d===y.KEY_ENTER){m.preventDefault(),s("keypad",{digit:"E"});return}if(d===y.KEY_ESCAPE){m.preventDefault(),s("keypad",{digit:"C"});return}if(d===y.KEY_BACKSPACE){m.preventDefault(),s("backspace");return}if(d>=y.KEY_0&&d<=y.KEY_9){m.preventDefault(),s("keypad",{digit:d-y.KEY_0});return}if(d>=y.KEY_NUMPAD_0&&d<=y.KEY_NUMPAD_9){m.preventDefault(),s("keypad",{digit:d-y.KEY_NUMPAD_0});return}},g=function(m,i){var u=(0,t.useBackend)(i),s=u.act,d=u.data,v=d.locked,h=d.no_passcode,C=d.emagged,p=d.user_entered_code,N=[["1","2","3"],["4","5","6"],["7","8","9"],["C","0","E"]],V=h?"":v?"bad":"good";return(0,e.createComponentVNode)(2,o.Section,{fill:!0,onKeyDown:function(){function S(B){return k(B,i)}return S}(),children:[(0,e.createComponentVNode)(2,o.Stack.Item,{height:7.3,children:(0,e.createComponentVNode)(2,o.Box,{className:(0,a.classes)(["SecureStorage__displayBox","SecureStorage__displayBox--"+V]),height:"100%",children:C?"ERROR":p})}),(0,e.createComponentVNode)(2,o.Table,{children:N.map(function(S){return(0,e.createComponentVNode)(2,b.TableRow,{children:S.map(function(B){return(0,e.createComponentVNode)(2,b.TableCell,{children:(0,e.createComponentVNode)(2,l,{number:B})},B)})},S[0])})})]})},l=function(m,i){var u=(0,t.useBackend)(i),s=u.act,d=u.data,v=m.number;return(0,e.createComponentVNode)(2,o.Button,{fluid:!0,bold:!0,mb:"6px",content:v,textAlign:"center",fontSize:"60px",lineHeight:1.25,width:"80px",className:(0,a.classes)(["SecureStorage__Button","SecureStorage__Button--keypad","SecureStorage__Button--"+v]),onClick:function(){function h(){return s("keypad",{digit:v})}return h}()})}},6272:function(T,r,n){"use strict";r.__esModule=!0,r.SecurityRecords=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),f=n(98595),b=n(3939),y=n(321),I=n(5485),k=n(22091),g={"*Execute*":"execute","*Arrest*":"arrest",Incarcerated:"incarcerated",Parolled:"parolled",Released:"released",Demote:"demote",Search:"search",Monitor:"monitor"},l=function(p,N){(0,b.modalOpen)(p,"edit",{field:N.edit,value:N.value})},c=r.SecurityRecords=function(){function C(p,N){var V=(0,t.useBackend)(N),S=V.act,B=V.data,L=B.loginState,w=B.currentPage,A;if(L.logged_in)w===1?A=(0,e.createComponentVNode)(2,i):w===2&&(A=(0,e.createComponentVNode)(2,d));else return(0,e.createComponentVNode)(2,f.Window,{theme:"security",width:800,height:900,children:(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,I.LoginScreen)})});return(0,e.createComponentVNode)(2,f.Window,{theme:"security",width:800,height:900,children:[(0,e.createComponentVNode)(2,b.ComplexModal),(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,y.LoginInfo),(0,e.createComponentVNode)(2,k.TemporaryNotice),(0,e.createComponentVNode)(2,m),A]})})]})}return C}(),m=function(p,N){var V=(0,t.useBackend)(N),S=V.act,B=V.data,L=B.currentPage,w=B.general;return(0,e.createComponentVNode)(2,o.Stack.Item,{m:0,children:(0,e.createComponentVNode)(2,o.Tabs,{children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"list",selected:L===1,onClick:function(){function A(){return S("page",{page:1})}return A}(),children:"List Records"}),L===2&&w&&!w.empty&&(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"file",selected:L===2,children:["Record: ",w.fields[0].value]})]})})},i=function(p,N){var V=(0,t.useBackend)(N),S=V.act,B=V.data,L=B.records,w=(0,t.useLocalState)(N,"searchText",""),A=w[0],x=w[1],E=(0,t.useLocalState)(N,"sortId","name"),P=E[0],D=E[1],M=(0,t.useLocalState)(N,"sortOrder",!0),R=M[0],O=M[1];return(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,s)}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,mt:.5,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,o.Table,{className:"SecurityRecords__list",children:[(0,e.createComponentVNode)(2,o.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,u,{id:"name",children:"Name"}),(0,e.createComponentVNode)(2,u,{id:"id",children:"ID"}),(0,e.createComponentVNode)(2,u,{id:"rank",children:"Assignment"}),(0,e.createComponentVNode)(2,u,{id:"fingerprint",children:"Fingerprint"}),(0,e.createComponentVNode)(2,u,{id:"status",children:"Criminal Status"})]}),L.filter((0,a.createSearch)(A,function(F){return F.name+"|"+F.id+"|"+F.rank+"|"+F.fingerprint+"|"+F.status})).sort(function(F,_){var U=R?1:-1;return F[P].localeCompare(_[P])*U}).map(function(F){return(0,e.createComponentVNode)(2,o.Table.Row,{className:"SecurityRecords__listRow--"+g[F.status],onClick:function(){function _(){return S("view",{uid_gen:F.uid_gen,uid_sec:F.uid_sec})}return _}(),children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"user"})," ",F.name]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:F.id}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:F.rank}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:F.fingerprint}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:F.status})]},F.id)})]})})})],4)},u=function(p,N){var V=(0,t.useLocalState)(N,"sortId","name"),S=V[0],B=V[1],L=(0,t.useLocalState)(N,"sortOrder",!0),w=L[0],A=L[1],x=p.id,E=p.children;return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{color:S!==x&&"transparent",fluid:!0,onClick:function(){function P(){S===x?A(!w):(B(x),A(!0))}return P}(),children:[E,S===x&&(0,e.createComponentVNode)(2,o.Icon,{name:w?"sort-up":"sort-down",ml:"0.25rem;"})]})})})},s=function(p,N){var V=(0,t.useBackend)(N),S=V.act,B=V.data,L=B.isPrinting,w=(0,t.useLocalState)(N,"searchText",""),A=w[0],x=w[1];return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{ml:"0.25rem",content:"New Record",icon:"plus",onClick:function(){function E(){return S("new_general")}return E}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{disabled:L,icon:L?"spinner":"print",iconSpin:!!L,content:"Print Cell Log",onClick:function(){function E(){return(0,b.modalOpen)(N,"print_cell_log")}return E}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Input,{placeholder:"Search by Name, ID, Assignment, Fingerprint, Status",fluid:!0,onInput:function(){function E(P,D){return x(D)}return E}()})})]})},d=function(p,N){var V=(0,t.useBackend)(N),S=V.act,B=V.data,L=B.isPrinting,w=B.general,A=B.security;return!w||!w.fields?(0,e.createComponentVNode)(2,o.Box,{color:"bad",children:"General records lost!"}):(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"General Data",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{disabled:L,icon:L?"spinner":"print",iconSpin:!!L,content:"Print Record",onClick:function(){function x(){return S("print_record")}return x}()}),(0,e.createComponentVNode)(2,o.Button.Confirm,{icon:"trash",tooltip:"WARNING: This will also delete the Security and Medical records associated with this crew member!",tooltipPosition:"bottom-start",content:"Delete Record",onClick:function(){function x(){return S("delete_general")}return x}()})],4),children:(0,e.createComponentVNode)(2,v)})}),!A||!A.fields?(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,color:"bad",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,title:"Security Data",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"pen",content:"Create New Record",onClick:function(){function x(){return S("new_security")}return x}()}),children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{bold:!0,grow:!0,textAlign:"center",fontSize:1.75,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,o.Icon.Stack,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"scroll",size:5,color:"gray"}),(0,e.createComponentVNode)(2,o.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"Security records lost!"]})})})}):(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Security Data",buttons:(0,e.createComponentVNode)(2,o.Button.Confirm,{icon:"trash",disabled:A.empty,content:"Delete Record",onClick:function(){function x(){return S("delete_security")}return x}()}),children:(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:A.fields.map(function(x,E){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:x.field,preserveWhitespace:!0,children:[(0,a.decodeHtmlEntities)(x.value),!!x.edit&&(0,e.createComponentVNode)(2,o.Button,{icon:"pen",ml:"0.5rem",mb:x.line_break?"1rem":"initial",onClick:function(){function P(){return l(N,x)}return P}()})]},E)})})})})}),(0,e.createComponentVNode)(2,h)],4)],0)},v=function(p,N){var V=(0,t.useBackend)(N),S=V.data,B=S.general;return!B||!B.fields?(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,color:"bad",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:"General records lost!"})})}):(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.LabeledList,{children:B.fields.map(function(L,w){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:L.field,preserveWhitespace:!0,children:[(0,a.decodeHtmlEntities)(""+L.value),!!L.edit&&(0,e.createComponentVNode)(2,o.Button,{icon:"pen",ml:"0.5rem",mb:L.line_break?"1rem":"initial",onClick:function(){function A(){return l(N,L)}return A}()})]},w)})})}),!!B.has_photos&&B.photos.map(function(L,w){return(0,e.createComponentVNode)(2,o.Stack.Item,{inline:!0,textAlign:"center",color:"label",ml:0,children:[(0,e.createVNode)(1,"img",null,null,1,{src:L,style:{width:"96px","margin-top":"5rem","margin-bottom":"0.5rem","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"}}),(0,e.createVNode)(1,"br"),"Photo #",w+1]},w)})]})},h=function(p,N){var V=(0,t.useBackend)(N),S=V.act,B=V.data,L=B.security;return(0,e.createComponentVNode)(2,o.Stack.Item,{height:"150px",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Comments/Log",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"comment",content:"Add Entry",onClick:function(){function w(){return(0,b.modalOpen)(N,"comment_add")}return w}()}),children:L.comments.length===0?(0,e.createComponentVNode)(2,o.Box,{color:"label",children:"No comments found."}):L.comments.map(function(w,A){return(0,e.createComponentVNode)(2,o.Box,{preserveWhitespace:!0,children:[(0,e.createComponentVNode)(2,o.Box,{color:"label",inline:!0,children:w.header||"Auto-generated"}),(0,e.createVNode)(1,"br"),w.text||w,(0,e.createComponentVNode)(2,o.Button,{icon:"comment-slash",color:"bad",ml:"0.5rem",onClick:function(){function x(){return S("comment_delete",{id:A+1})}return x}()})]},A)})})})}},5099:function(T,r,n){"use strict";r.__esModule=!0,r.SeedExtractor=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),f=n(98595),b=n(3939);function y(u,s){var d=typeof Symbol!="undefined"&&u[Symbol.iterator]||u["@@iterator"];if(d)return(d=d.call(u)).next.bind(d);if(Array.isArray(u)||(d=I(u))||s&&u&&typeof u.length=="number"){d&&(u=d);var v=0;return function(){return v>=u.length?{done:!0}:{done:!1,value:u[v++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function I(u,s){if(u){if(typeof u=="string")return k(u,s);var d={}.toString.call(u).slice(8,-1);return d==="Object"&&u.constructor&&(d=u.constructor.name),d==="Map"||d==="Set"?Array.from(u):d==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(d)?k(u,s):void 0}}function k(u,s){(s==null||s>u.length)&&(s=u.length);for(var d=0,v=Array(s);d=A},h=function(w,A){return w<=A},C=s.split(" "),p=[],N=function(){var w=B.value,A=w.split(":");if(A.length===0)return 0;if(A.length===1)return p.push(function(P){return(P.name+" ("+P.variant+")").toLocaleLowerCase().includes(A[0].toLocaleLowerCase())}),0;if(A.length>2)return{v:function(){function P(D){return!1}return P}()};var x,E=d;if(A[1][A[1].length-1]==="-"?(E=h,x=Number(A[1].substring(0,A[1].length-1))):A[1][A[1].length-1]==="+"?(E=v,x=Number(A[1].substring(0,A[1].length-1))):x=Number(A[1]),isNaN(x))return{v:function(){function P(D){return!1}return P}()};switch(A[0].toLocaleLowerCase()){case"l":case"life":case"lifespan":p.push(function(P){return E(P.lifespan,x)});break;case"e":case"end":case"endurance":p.push(function(P){return E(P.endurance,x)});break;case"m":case"mat":case"maturation":p.push(function(P){return E(P.maturation,x)});break;case"pr":case"prod":case"production":p.push(function(P){return E(P.production,x)});break;case"y":case"yield":p.push(function(P){return E(P.yield,x)});break;case"po":case"pot":case"potency":p.push(function(P){return E(P.potency,x)});break;case"s":case"stock":case"c":case"count":case"a":case"amount":p.push(function(P){return E(P.amount,x)});break;default:return{v:function(){function P(D){return!1}return P}()}}},V,S=y(C),B;!(B=S()).done;)if(V=N(),V!==0&&V)return V.v;return function(L){for(var w=0,A=p;w=1?Number(E):1)}return A}()})]})]})}},2916:function(T,r,n){"use strict";r.__esModule=!0,r.ShuttleConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.ShuttleConsole=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data;return(0,e.createComponentVNode)(2,o.Window,{width:350,height:150,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Location",children:l.status?l.status:(0,e.createComponentVNode)(2,t.NoticeBox,{color:"red",children:"Shuttle Missing"})}),!!l.shuttle&&(!!l.docking_ports_len&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Send to ",children:l.docking_ports.map(function(c){return(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-right",content:c.name,onClick:function(){function m(){return g("move",{move:c.id})}return m}()},c.name)})})||(0,e.createFragment)([(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",color:"red",children:(0,e.createComponentVNode)(2,t.NoticeBox,{color:"red",children:"Shuttle Locked"})}),!!l.admin_controlled&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Authorization",children:(0,e.createComponentVNode)(2,t.Button,{icon:"exclamation-circle",content:"Request Authorization",disabled:!l.status,onClick:function(){function c(){return g("request")}return c}()})})],0))]})})})})}return b}()},39401:function(T,r,n){"use strict";r.__esModule=!0,r.ShuttleManipulator=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.ShuttleManipulator=function(){function k(g,l){var c=(0,a.useLocalState)(l,"tabIndex",0),m=c[0],i=c[1],u=function(){function s(d){switch(d){case 0:return(0,e.createComponentVNode)(2,b);case 1:return(0,e.createComponentVNode)(2,y);case 2:return(0,e.createComponentVNode)(2,I);default:return"WE SHOULDN'T BE HERE!"}}return s}();return(0,e.createComponentVNode)(2,o.Window,{width:650,height:700,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Box,{fillPositionedParent:!0,children:[(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:m===0,onClick:function(){function s(){return i(0)}return s}(),icon:"info-circle",children:"Status"},"Status"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:m===1,onClick:function(){function s(){return i(1)}return s}(),icon:"file-import",children:"Templates"},"Templates"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:m===2,onClick:function(){function s(){return i(2)}return s}(),icon:"tools",children:"Modification"},"Modification")]}),u(m)]})})})}return k}(),b=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.shuttles;return(0,e.createComponentVNode)(2,t.Box,{children:u.map(function(s){return(0,e.createComponentVNode)(2,t.Section,{title:s.name,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"ID",children:s.id}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Shuttle Timer",children:s.timeleft}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Shuttle Mode",children:s.mode}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Shuttle Status",children:s.status}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Actions",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Jump To",icon:"location-arrow",onClick:function(){function d(){return m("jump_to",{type:"mobile",id:s.id})}return d}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Fast Travel",icon:"fast-forward",onClick:function(){function d(){return m("fast_travel",{id:s.id})}return d}()})]})]})},s.name)})})},y=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.templates_tabs,s=i.existing_shuttle,d=i.templates;return(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Tabs,{children:u.map(function(v){return(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:v===s.id,icon:"file",onClick:function(){function h(){return m("select_template_category",{cat:v})}return h}(),children:v},v)})}),!!s&&d[s.id].templates.map(function(v){return(0,e.createComponentVNode)(2,t.Section,{title:v.name,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[v.description&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Description",children:v.description}),v.admin_notes&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Admin Notes",children:v.admin_notes}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Actions",children:(0,e.createComponentVNode)(2,t.Button,{content:"Load Template",icon:"download",onClick:function(){function h(){return m("select_template",{shuttle_id:v.shuttle_id})}return h}()})})]})},v.name)})]})},I=function(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.existing_shuttle,s=i.selected;return(0,e.createComponentVNode)(2,t.Box,{children:[u?(0,e.createComponentVNode)(2,t.Section,{title:"Selected Shuttle: "+u.name,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:u.status}),u.timer&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Timer",children:u.timeleft}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Actions",children:(0,e.createComponentVNode)(2,t.Button,{content:"Jump To",icon:"location-arrow",onClick:function(){function d(){return m("jump_to",{type:"mobile",id:u.id})}return d}()})})]})}):(0,e.createComponentVNode)(2,t.Section,{title:"Selected Shuttle: None"}),s?(0,e.createComponentVNode)(2,t.Section,{title:"Selected Template: "+s.name,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[s.description&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Description",children:s.description}),s.admin_notes&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Admin Notes",children:s.admin_notes}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Actions",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Preview",icon:"eye",onClick:function(){function d(){return m("preview",{shuttle_id:s.shuttle_id})}return d}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Load",icon:"download",onClick:function(){function d(){return m("load",{shuttle_id:s.shuttle_id})}return d}()})]})]})}):(0,e.createComponentVNode)(2,t.Section,{title:"Selected Template: None"})]})}},86013:function(T,r,n){"use strict";r.__esModule=!0,r.SingularityMonitor=void 0;var e=n(89005),a=n(88510),t=n(64795),o=n(44879),f=n(72253),b=n(36036),y=n(76910),I=n(98595),k=n(36352),g=r.SingularityMonitor=function(){function i(u,s){var d=(0,f.useBackend)(s),v=d.act,h=d.data;return h.active===0?(0,e.createComponentVNode)(2,c):(0,e.createComponentVNode)(2,m)}return i}(),l=function(u){return Math.log2(16+Math.max(0,u))-4},c=function(u,s){var d=(0,f.useBackend)(s),v=d.act,h=d.data,C=h.singularities,p=C===void 0?[]:C;return(0,e.createComponentVNode)(2,I.Window,{width:450,height:185,children:(0,e.createComponentVNode)(2,I.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,title:"Detected Singularities",buttons:(0,e.createComponentVNode)(2,b.Button,{icon:"sync",content:"Refresh",onClick:function(){function N(){return v("refresh")}return N}()}),children:(0,e.createComponentVNode)(2,b.Table,{children:p.map(function(N){return(0,e.createComponentVNode)(2,b.Table.Row,{children:[(0,e.createComponentVNode)(2,b.Table.Cell,{children:N.singularity_id+". "+N.area_name}),(0,e.createComponentVNode)(2,b.Table.Cell,{collapsing:!0,color:"label",children:"Stage:"}),(0,e.createComponentVNode)(2,b.Table.Cell,{collapsing:!0,width:"120px",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:N.stage,minValue:0,maxValue:6,ranges:{good:[1,2],average:[3,4],bad:[5,6]},children:(0,o.toFixed)(N.stage)})}),(0,e.createComponentVNode)(2,b.Table.Cell,{collapsing:!0,children:(0,e.createComponentVNode)(2,b.Button,{content:"Details",onClick:function(){function V(){return v("view",{view:N.singularity_id})}return V}()})})]},N.singularity_id)})})})})})},m=function(u,s){var d=(0,f.useBackend)(s),v=d.act,h=d.data,C=h.active,p=h.singulo_stage,N=h.singulo_potential_stage,V=h.singulo_energy,S=h.singulo_high,B=h.singulo_low,L=h.generators,w=L===void 0?[]:L;return(0,e.createComponentVNode)(2,I.Window,{width:550,height:185,children:(0,e.createComponentVNode)(2,I.Window.Content,{children:(0,e.createComponentVNode)(2,b.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{width:"270px",children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Metrics",children:(0,e.createComponentVNode)(2,b.LabeledList,{children:[(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Stage",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:p,minValue:0,maxValue:6,ranges:{good:[1,2],average:[3,4],bad:[5,6]},children:(0,o.toFixed)(p)})}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Potential Stage",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:N,minValue:0,maxValue:6,ranges:{good:[1,p+.5],average:[p+.5,p+1.5],bad:[p+1.5,p+2]},children:(0,o.toFixed)(N)})}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Energy",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:V,minValue:B,maxValue:S,ranges:{good:[.67*S+.33*B,S],average:[.33*S+.67*B,.67*S+.33*B],bad:[B,.33*S+.67*B]},children:(0,o.toFixed)(V)+"MJ"})})]})})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,basis:0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Field Generators",buttons:(0,e.createComponentVNode)(2,b.Button,{icon:"arrow-left",content:"Back",onClick:function(){function A(){return v("back")}return A}()}),children:(0,e.createComponentVNode)(2,b.LabeledList,{children:w.map(function(A){return(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Remaining Charge",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:A.charge,minValue:0,maxValue:125,ranges:{good:[80,125],average:[30,80],bad:[0,30]},children:(0,o.toFixed)(A.charge)})},A.gen_index)})})})})]})})})}},88284:function(T,r,n){"use strict";r.__esModule=!0,r.Sleeper=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),f=n(98595),b=[["good","Alive"],["average","Critical"],["bad","DEAD"]],y=[["Resp.","oxyLoss"],["Toxin","toxLoss"],["Brute","bruteLoss"],["Burn","fireLoss"]],I={average:[.25,.5],bad:[.5,1/0]},k=["bad","average","average","good","average","average","bad"],g=r.Sleeper=function(){function d(v,h){var C=(0,t.useBackend)(h),p=C.act,N=C.data,V=N.hasOccupant,S=V?(0,e.createComponentVNode)(2,l):(0,e.createComponentVNode)(2,s);return(0,e.createComponentVNode)(2,f.Window,{width:550,height:760,children:(0,e.createComponentVNode)(2,f.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:S}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,i)})]})})})}return d}(),l=function(v,h){var C=(0,t.useBackend)(h),p=C.act,N=C.data,V=N.occupant;return(0,e.createFragment)([(0,e.createComponentVNode)(2,c),(0,e.createComponentVNode)(2,m),(0,e.createComponentVNode)(2,u)],4)},c=function(v,h){var C=(0,t.useBackend)(h),p=C.act,N=C.data,V=N.occupant,S=N.auto_eject_dead;return(0,e.createComponentVNode)(2,o.Section,{title:"Occupant",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Box,{color:"label",inline:!0,children:"Auto-eject if dead:\xA0"}),(0,e.createComponentVNode)(2,o.Button,{icon:S?"toggle-on":"toggle-off",selected:S,content:S?"On":"Off",onClick:function(){function B(){return p("auto_eject_dead_"+(S?"off":"on"))}return B}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"user-slash",content:"Eject",onClick:function(){function B(){return p("ejectify")}return B}()})],4),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Name",children:V.name}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Health",children:(0,e.createComponentVNode)(2,o.ProgressBar,{min:"0",max:V.maxHealth,value:V.health/V.maxHealth,ranges:{good:[.5,1/0],average:[0,.5],bad:[-1/0,0]},children:(0,a.round)(V.health,0)})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Status",color:b[V.stat][0],children:b[V.stat][1]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Temperature",children:(0,e.createComponentVNode)(2,o.ProgressBar,{min:"0",max:V.maxTemp,value:V.bodyTemperature/V.maxTemp,color:k[V.temperatureSuitability+3],children:[(0,a.round)(V.btCelsius,0),"\xB0C,",(0,a.round)(V.btFaren,0),"\xB0F"]})}),!!V.hasBlood&&(0,e.createFragment)([(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Blood Level",children:(0,e.createComponentVNode)(2,o.ProgressBar,{min:"0",max:V.bloodMax,value:V.bloodLevel/V.bloodMax,ranges:{bad:[-1/0,.6],average:[.6,.9],good:[.6,1/0]},children:[V.bloodPercent,"%, ",V.bloodLevel,"cl"]})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Pulse",verticalAlign:"middle",children:[V.pulse," BPM"]})],4)]})})},m=function(v,h){var C=(0,t.useBackend)(h),p=C.data,N=p.occupant;return(0,e.createComponentVNode)(2,o.Section,{title:"Occupant Damage",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:y.map(function(V,S){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:V[0],children:(0,e.createComponentVNode)(2,o.ProgressBar,{min:"0",max:"100",value:N[V[1]]/100,ranges:I,children:(0,a.round)(N[V[1]],0)},S)},S)})})})},i=function(v,h){var C=(0,t.useBackend)(h),p=C.act,N=C.data,V=N.hasOccupant,S=N.isBeakerLoaded,B=N.beakerMaxSpace,L=N.beakerFreeSpace,w=N.dialysis,A=w&&L>0;return(0,e.createComponentVNode)(2,o.Section,{title:"Dialysis",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{disabled:!S||L<=0||!V,selected:A,icon:A?"toggle-on":"toggle-off",content:A?"Active":"Inactive",onClick:function(){function x(){return p("togglefilter")}return x}()}),(0,e.createComponentVNode)(2,o.Button,{disabled:!S,icon:"eject",content:"Eject",onClick:function(){function x(){return p("removebeaker")}return x}()})],4),children:S?(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Remaining Space",children:(0,e.createComponentVNode)(2,o.ProgressBar,{min:"0",max:B,value:L/B,ranges:{good:[.5,1/0],average:[.25,.5],bad:[-1/0,.25]},children:[L,"u"]})})}):(0,e.createComponentVNode)(2,o.Box,{color:"label",children:"No beaker loaded."})})},u=function(v,h){var C=(0,t.useBackend)(h),p=C.act,N=C.data,V=N.occupant,S=N.chemicals,B=N.maxchem,L=N.amounts;return(0,e.createComponentVNode)(2,o.Section,{title:"Occupant Chemicals",children:S.map(function(w,A){var x="",E;return w.overdosing?(x="bad",E=(0,e.createComponentVNode)(2,o.Box,{color:"bad",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"exclamation-circle"}),"\xA0 Overdosing!"]})):w.od_warning&&(x="average",E=(0,e.createComponentVNode)(2,o.Box,{color:"average",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"exclamation-triangle"}),"\xA0 Close to overdosing"]})),(0,e.createComponentVNode)(2,o.Box,{backgroundColor:"rgba(0, 0, 0, 0.33)",mb:"0.5rem",children:(0,e.createComponentVNode)(2,o.Section,{title:w.title,level:"3",mx:"0",lineHeight:"18px",buttons:E,children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.ProgressBar,{min:"0",max:B,value:w.occ_amount/B,color:x,title:"Amount of chemicals currently inside the occupant / Total amount injectable by this machine",mr:"0.5rem",children:[w.pretty_amount,"/",B,"u"]}),L.map(function(P,D){return(0,e.createComponentVNode)(2,o.Button,{disabled:!w.injectable||w.occ_amount+P>B||V.stat===2,icon:"syringe",content:"Inject "+P+"u",title:"Inject "+P+"u of "+w.title+" into the occupant",mb:"0",height:"19px",onClick:function(){function M(){return p("chemical",{chemid:w.id,amount:P})}return M}()},D)})]})})},A)})})},s=function(v,h){return(0,e.createComponentVNode)(2,o.Section,{fill:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),"No occupant detected."]})})})}},21597:function(T,r,n){"use strict";r.__esModule=!0,r.SlotMachine=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.SlotMachine=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data;if(l.money===null)return(0,e.createComponentVNode)(2,o.Window,{width:350,height:90,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Box,{children:"Could not scan your card or could not find account!"}),(0,e.createComponentVNode)(2,t.Box,{children:"Please wear or hold your ID and try again."})]})})});var c;return l.plays===1?c=l.plays+" player has tried their luck today!":c=l.plays+" players have tried their luck today!",(0,e.createComponentVNode)(2,o.Window,{width:300,height:151,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Box,{lineHeight:2,children:c}),(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Credits Remaining",children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:l.money})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"10 credits to spin",children:(0,e.createComponentVNode)(2,t.Button,{icon:"coins",disabled:l.working,content:l.working?"Spinning...":"Spin",onClick:function(){function m(){return g("spin")}return m}()})})]}),(0,e.createComponentVNode)(2,t.Box,{bold:!0,lineHeight:2,color:l.resultlvl,children:l.result})]})})})}return b}()},46348:function(T,r,n){"use strict";r.__esModule=!0,r.Smartfridge=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.Smartfridge=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.secure,m=l.can_dry,i=l.drying,u=l.contents;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:500,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[!!c&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:"Secure Access: Please have your identification ready."}),(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:m?"Drying rack":"Contents",buttons:!!m&&(0,e.createComponentVNode)(2,t.Button,{width:4,icon:i?"power-off":"times",content:i?"On":"Off",selected:i,onClick:function(){function s(){return g("drying")}return s}()}),children:[!u&&(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,textAlign:"center",align:"center",color:"average",children:[(0,e.createComponentVNode)(2,t.Icon.Stack,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"cookie-bite",size:5,color:"brown"}),(0,e.createComponentVNode)(2,t.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"No products loaded."]})}),!!u&&u.slice().sort(function(s,d){return s.display_name.localeCompare(d.display_name)}).map(function(s){return(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"55%",children:s.display_name}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"25%",children:["(",s.quantity," in stock)"]}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:13,children:[(0,e.createComponentVNode)(2,t.Button,{width:3,icon:"arrow-down",tooltip:"Dispense one.",content:"1",onClick:function(){function d(){return g("vend",{index:s.vend,amount:1})}return d}()}),(0,e.createComponentVNode)(2,t.NumberInput,{width:"40px",minValue:0,value:0,maxValue:s.quantity,step:1,stepPixelSize:3,onChange:function(){function d(v,h){return g("vend",{index:s.vend,amount:h})}return d}()}),(0,e.createComponentVNode)(2,t.Button,{width:4,icon:"arrow-down",content:"All",tooltip:"Dispense all.",tooltipPosition:"bottom-start",onClick:function(){function d(){return g("vend",{index:s.vend,amount:s.quantity})}return d}()})]})]},s)})]})]})})})}return b}()},86162:function(T,r,n){"use strict";r.__esModule=!0,r.Smes=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(49968),f=n(98595),b=1e3,y=r.Smes=function(){function I(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.capacityPercent,u=m.capacity,s=m.charge,d=m.inputAttempt,v=m.inputting,h=m.inputLevel,C=m.inputLevelMax,p=m.inputAvailable,N=m.outputPowernet,V=m.outputAttempt,S=m.outputting,B=m.outputLevel,L=m.outputLevelMax,w=m.outputUsed,A=i>=100&&"good"||v&&"average"||"bad",x=S&&"good"||s>0&&"average"||"bad";return(0,e.createComponentVNode)(2,f.Window,{width:340,height:345,children:(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Stored Energy",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:i*.01,ranges:{good:[.5,1/0],average:[.15,.5],bad:[-1/0,.15]}})}),(0,e.createComponentVNode)(2,t.Section,{title:"Input",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Charge Mode",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:d?"sync-alt":"times",selected:d,onClick:function(){function E(){return c("tryinput")}return E}(),children:d?"Auto":"Off"}),children:(0,e.createComponentVNode)(2,t.Box,{color:A,children:i>=100&&"Fully Charged"||v&&"Charging"||"Not Charging"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Target Input",children:(0,e.createComponentVNode)(2,t.Stack,{inline:!0,width:"100%",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"fast-backward",disabled:h===0,onClick:function(){function E(){return c("input",{target:"min"})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"backward",disabled:h===0,onClick:function(){function E(){return c("input",{adjust:-1e4})}return E}()})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Slider,{value:h/b,fillValue:p/b,minValue:0,maxValue:C/b,step:5,stepPixelSize:4,format:function(){function E(P){return(0,o.formatPower)(P*b,1)}return E}(),onChange:function(){function E(P,D){return c("input",{target:D*b})}return E}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"forward",disabled:h===C,onClick:function(){function E(){return c("input",{adjust:1e4})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fast-forward",disabled:h===C,onClick:function(){function E(){return c("input",{target:"max"})}return E}()})]})]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Available",children:(0,o.formatPower)(p)})]})}),(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Output",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Output Mode",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:V?"power-off":"times",selected:V,onClick:function(){function E(){return c("tryoutput")}return E}(),children:V?"On":"Off"}),children:(0,e.createComponentVNode)(2,t.Box,{color:x,children:N?S?"Sending":s>0?"Not Sending":"No Charge":"Not Connected"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Target Output",children:(0,e.createComponentVNode)(2,t.Stack,{inline:!0,width:"100%",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"fast-backward",disabled:B===0,onClick:function(){function E(){return c("output",{target:"min"})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"backward",disabled:B===0,onClick:function(){function E(){return c("output",{adjust:-1e4})}return E}()})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Slider,{value:B/b,minValue:0,maxValue:L/b,step:5,stepPixelSize:4,format:function(){function E(P){return(0,o.formatPower)(P*b,1)}return E}(),onChange:function(){function E(P,D){return c("output",{target:D*b})}return E}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"forward",disabled:B===L,onClick:function(){function E(){return c("output",{adjust:1e4})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fast-forward",disabled:B===L,onClick:function(){function E(){return c("output",{target:"max"})}return E}()})]})]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Outputting",children:(0,o.formatPower)(w)})]})})]})})})}return I}()},63584:function(T,r,n){"use strict";r.__esModule=!0,r.SolarControl=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.SolarControl=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=0,m=1,i=2,u=l.generated,s=l.generated_ratio,d=l.tracking_state,v=l.tracking_rate,h=l.connected_panels,C=l.connected_tracker,p=l.cdir,N=l.direction,V=l.rotating_direction;return(0,e.createComponentVNode)(2,o.Window,{width:490,height:277,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Status",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"sync",content:"Scan for new hardware",onClick:function(){function S(){return g("refresh")}return S}()}),children:(0,e.createComponentVNode)(2,t.Grid,{children:[(0,e.createComponentVNode)(2,t.Grid.Column,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Solar tracker",color:C?"good":"bad",children:C?"OK":"N/A"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Solar panels",color:h>0?"good":"bad",children:h})]})}),(0,e.createComponentVNode)(2,t.Grid.Column,{size:2,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power output",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ranges:{good:[.66,1/0],average:[.33,.66],bad:[-1/0,.33]},minValue:0,maxValue:1,value:s,children:u+" W"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Panel orientation",children:[p,"\xB0 (",N,")"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tracker rotation",children:[d===i&&(0,e.createComponentVNode)(2,t.Box,{children:" Automated "}),d===m&&(0,e.createComponentVNode)(2,t.Box,{children:[" ",v,"\xB0/h (",V,")"," "]}),d===c&&(0,e.createComponentVNode)(2,t.Box,{children:" Tracker offline "})]})]})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Controls",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Panel orientation",children:[d!==i&&(0,e.createComponentVNode)(2,t.NumberInput,{unit:"\xB0",step:1,stepPixelSize:1,minValue:0,maxValue:359,value:p,onDrag:function(){function S(B,L){return g("cdir",{cdir:L})}return S}()}),d===i&&(0,e.createComponentVNode)(2,t.Box,{lineHeight:"19px",children:" Automated "})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tracker status",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"times",content:"Off",selected:d===c,onClick:function(){function S(){return g("track",{track:c})}return S}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"clock-o",content:"Timed",selected:d===m,onClick:function(){function S(){return g("track",{track:m})}return S}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"sync",content:"Auto",selected:d===i,disabled:!C,onClick:function(){function S(){return g("track",{track:i})}return S}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tracker rotation",children:[d===m&&(0,e.createComponentVNode)(2,t.NumberInput,{unit:"\xB0/h",step:1,stepPixelSize:1,minValue:-7200,maxValue:7200,value:v,format:function(){function S(B){var L=Math.sign(B)>0?"+":"-";return L+Math.abs(B)}return S}(),onDrag:function(){function S(B,L){return g("tdir",{tdir:L})}return S}()}),d===c&&(0,e.createComponentVNode)(2,t.Box,{lineHeight:"19px",children:" Tracker offline "}),d===i&&(0,e.createComponentVNode)(2,t.Box,{lineHeight:"19px",children:" Automated "})]})]})})]})})}return b}()},38096:function(T,r,n){"use strict";r.__esModule=!0,r.SpawnersMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.SpawnersMenu=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.spawners||[];return(0,e.createComponentVNode)(2,o.Window,{width:700,height:600,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Section,{children:c.map(function(m){return(0,e.createComponentVNode)(2,t.Section,{mb:.5,title:m.name+" ("+m.amount_left+" left)",level:2,buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-circle-right",content:"Jump",onClick:function(){function i(){return g("jump",{ID:m.uids})}return i}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-circle-right",content:"Spawn",onClick:function(){function i(){return g("spawn",{ID:m.uids})}return i}()})],4),children:[(0,e.createComponentVNode)(2,t.Box,{style:{"white-space":"pre-wrap"},mb:1,fontSize:"16px",children:m.desc}),!!m.fluff&&(0,e.createComponentVNode)(2,t.Box,{style:{"white-space":"pre-wrap"},textColor:"#878787",fontSize:"14px",children:m.fluff}),!!m.important_info&&(0,e.createComponentVNode)(2,t.Box,{style:{"white-space":"pre-wrap"},mt:1,bold:!0,color:"red",fontSize:"18px",children:m.important_info})]},m.name)})})})})}return b}()},30586:function(T,r,n){"use strict";r.__esModule=!0,r.SpecMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.SpecMenu=function(){function g(l,c){return(0,e.createComponentVNode)(2,o.Window,{width:1100,height:600,theme:"nologo",children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,b),(0,e.createComponentVNode)(2,y),(0,e.createComponentVNode)(2,I),(0,e.createComponentVNode)(2,k)]})})})}return g}(),b=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.subclasses;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,basis:"25%",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Hemomancer",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Choose",onClick:function(){function d(){return i("hemomancer")}return d}()}),children:[(0,e.createVNode)(1,"h3",null,"Focuses on blood magic and the manipulation of blood around you.",16),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Vampiric claws",16),(0,e.createTextVNode)(": Unlocked at 150 blood, allows you to summon a robust pair of claws that attack rapidly, drain a targets blood, and heal you.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood Barrier",16),(0,e.createTextVNode)(": Unlocked at 250 blood, allows you to select two turfs and create a wall between them.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood tendrils",16),(0,e.createTextVNode)(": Unlocked at 250 blood, allows you to slow everyone in a targeted 3x3 area after a short delay.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Sanguine pool",16),(0,e.createTextVNode)(": Unlocked at 400 blood, allows you to travel at high speeds for a short duration. Doing this leaves behind blood splatters. You can move through anything but walls and space when doing this.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Predator senses",16),(0,e.createTextVNode)(": Unlocked at 600 blood, allows you to sniff out anyone within the same sector as you.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood eruption",16),(0,e.createTextVNode)(": Unlocked at 800 blood, allows you to manipulate all nearby blood splatters, in 4 tiles around you, into spikes that impale anyone stood ontop of them.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Full power",16),(0,e.createComponentVNode)(2,t.Divider),(0,e.createVNode)(1,"b",null,"The blood bringers rite",16),(0,e.createTextVNode)(": When toggled you will rapidly drain the blood of everyone who is nearby and use it to heal yourself slightly and remove any incapacitating effects rapidly.")],4)]})})},y=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.subclasses;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,basis:"25%",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Umbrae",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Choose",onClick:function(){function d(){return i("umbrae")}return d}()}),children:[(0,e.createVNode)(1,"h3",null,"Focuses on darkness, stealth ambushing and mobility.",16),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Cloak of darkness",16),(0,e.createTextVNode)(": Unlocked at 150 blood, when toggled, allows you to become nearly invisible and move rapidly when in dark regions. While active, burn damage is more effective against you.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Shadow anchor",16),(0,e.createTextVNode)(": Unlocked at 250 blood, casting it will create an anchor at the cast location after a short delay. If you then cast the ability again, you are teleported back to the anchor. If you do not cast again within 2 minutes, you will do a fake recall, causing a clone to appear at the anchor and making yourself invisible. It will not teleport you between Z levels.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Shadow snare",16),(0,e.createTextVNode)(": Unlocked at 250 blood, allows you to summon a trap that when crossed blinds and ensnares the victim. This trap is hard to see, but withers in the light.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Dark passage",16),(0,e.createTextVNode)(": Unlocked at 400 blood, allows you to target a turf on screen, you will then teleport to that turf.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Extinguish",16),(0,e.createTextVNode)(": Unlocked at 600 blood, allows you to snuff out nearby electronic light sources and glowshrooms.")],4),(0,e.createVNode)(1,"b",null,"Shadow boxing",16),": Unlocked at 800 blood, sends out shadow clones towards a target, damaging them while you remain in range.",(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Full power",16),(0,e.createComponentVNode)(2,t.Divider),(0,e.createVNode)(1,"b",null,"Eternal darkness",16),(0,e.createTextVNode)(": When toggled, you consume yourself in unholy darkness, only the strongest of lights will be able to see through it. Inside the radius, nearby creatures will freeze and energy projectiles will deal less damage.")],4),(0,e.createVNode)(1,"p",null,"In addition, you also gain permanent X-ray vision.",16)]})})},I=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.subclasses;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,basis:"25%",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Gargantua",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Choose",onClick:function(){function d(){return i("gargantua")}return d}()}),children:[(0,e.createVNode)(1,"h3",null,"Focuses on tenacity and melee damage.",16),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Rejuvenate",16),(0,e.createTextVNode)(": Will heal you at an increased rate based on how much damage you have taken.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood swell",16),(0,e.createTextVNode)(": Unlocked at 150 blood, increases your resistance to physical damage, stuns and stamina for 30 seconds. While it is active you cannot fire guns.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Seismic stomp",16),(0,e.createTextVNode)(": Unlocked at 250 blood, allows you to stomp the ground to send out a shockwave, knocking people back.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood rush",16),(0,e.createTextVNode)(": Unlocked at 250 blood, gives you a short speed boost when cast.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood swell II",16),(0,e.createTextVNode)(": Unlocked at 400 blood, increases all melee damage by 10.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Overwhelming force",16),(0,e.createTextVNode)(": Unlocked at 600 blood, when toggled, if you bump into a door that you do not have access to, it will force it open. In addition, you cannot be pushed or pulled while it is active.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Demonic grasp",16),(0,e.createTextVNode)(": Unlocked at 800 blood, allows you to send out a demonic hand to snare someone. If you are on disarm/grab intent you will push/pull the target, respectively.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Charge",16),(0,e.createTextVNode)(": Unlocked at 800 blood, you gain the ability to charge at a target. Destroying and knocking back pretty much anything you collide with.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Full Power",16),(0,e.createComponentVNode)(2,t.Divider),(0,e.createVNode)(1,"b",null,"Desecrated Duel",16),(0,e.createTextVNode)(": Leap towards a visible enemy, creating an arena upon landing, infusing you with increased regeneration, and granting you resistance to internal damages.")],4)]})})},k=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.subclasses;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,basis:"25%",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Dantalion",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Choose",onClick:function(){function d(){return i("dantalion")}return d}()}),children:[(0,e.createVNode)(1,"h3",null,"Focuses on thralling and illusions.",16),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Enthrall",16),(0,e.createTextVNode)(": Unlocked at 150 blood, Thralls your target to your will, requires you to stand still. Does not work on mindshielded or already enthralled/mindslaved people.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Thrall cap",16),(0,e.createTextVNode)(": You can only thrall a max of 1 person at a time. This can be increased at 400 blood, 600 blood and at full power to a max of 4 thralls.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Thrall commune",16),(0,e.createTextVNode)(": Unlocked at 150 blood, Allows you to talk to your thralls, your thralls can talk back in the same way.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Subspace swap",16),(0,e.createTextVNode)(": Unlocked at 250 blood, allows you to swap positions with a target.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Pacify",16),(0,e.createTextVNode)(": Unlocked at 250 blood, allows you to pacify a target, preventing them from causing harm for 40 seconds.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Decoy",16),(0,e.createTextVNode)(": Unlocked at 400 blood, briefly turn invisible and send out an illusion to fool everyone nearby.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Rally thralls",16),(0,e.createTextVNode)(": Unlocked at 600 blood, removes all incapacitating effects from nearby thralls.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood bond",16),(0,e.createTextVNode)(": Unlocked at 800 blood, when cast, all nearby thralls become linked to you. If anyone in the network takes damage, it is shared equally between everyone in the network. If a thrall goes out of range, they will be removed from the network.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Full Power",16),(0,e.createComponentVNode)(2,t.Divider),(0,e.createVNode)(1,"b",null,"Mass Hysteria",16),(0,e.createTextVNode)(": Casts a powerful illusion that blinds and then makes everyone nearby perceive others as random animals.")],4)]})})}},95152:function(T,r,n){"use strict";r.__esModule=!0,r.StackCraft=void 0;var e=n(89005),a=n(72253),t=n(88510),o=n(64795),f=n(25328),b=n(98595),y=n(36036),I=r.StackCraft=function(){function s(){return(0,e.createComponentVNode)(2,b.Window,{width:350,height:500,children:(0,e.createComponentVNode)(2,b.Window.Content,{children:(0,e.createComponentVNode)(2,k)})})}return s}(),k=function(d,v){var h=(0,a.useBackend)(v),C=h.data,p=C.amount,N=C.recipes,V=(0,a.useLocalState)(v,"searchText",""),S=V[0],B=V[1],L=g(N,(0,f.createSearch)(S)),w=(0,a.useLocalState)(v,"",!1),A=w[0],x=w[1];return(0,e.createComponentVNode)(2,y.Section,{fill:!0,scrollable:!0,title:"Amount: "+p,buttons:(0,e.createFragment)([A&&(0,e.createComponentVNode)(2,y.Input,{width:12.5,value:S,placeholder:"Find recipe",onInput:function(){function E(P,D){return B(D)}return E}()}),(0,e.createComponentVNode)(2,y.Button,{ml:.5,tooltip:"Search",tooltipPosition:"bottom-end",icon:"magnifying-glass",selected:A,onClick:function(){function E(){return x(!A)}return E}()})],0),children:L?(0,e.createComponentVNode)(2,i,{recipes:L}):(0,e.createComponentVNode)(2,y.NoticeBox,{children:"No recipes found!"})})},g=function s(d,v){var h=(0,o.flow)([(0,t.map)(function(C){var p=C[0],N=C[1];return l(N)?v(p)?C:[p,s(N,v)]:v(p)?C:[p,void 0]}),(0,t.filter)(function(C){var p=C[0],N=C[1];return N!==void 0}),(0,t.sortBy)(function(C){var p=C[0],N=C[1];return p}),(0,t.sortBy)(function(C){var p=C[0],N=C[1];return!l(N)}),(0,t.reduce)(function(C,p){var N=p[0],V=p[1];return C[N]=V,C},{})])(Object.entries(d));return Object.keys(h).length?h:void 0},l=function(d){return d.uid===void 0},c=function(d,v){return d.required_amount>v?0:Math.floor(v/d.required_amount)},m=function(d,v){for(var h=(0,a.useBackend)(v),C=h.act,p=d.recipe,N=d.max_possible_multiplier,V=Math.min(N,Math.floor(p.max_result_amount/p.result_amount)),S=[5,10,25],B=[],L=function(){var E=A[w];V>=E&&B.push((0,e.createComponentVNode)(2,y.Button,{bold:!0,translucent:!0,fontSize:.85,width:"32px",content:E*p.result_amount+"x",onClick:function(){function P(){return C("make",{recipe_uid:p.uid,multiplier:E})}return P}()}))},w=0,A=S;w1?B+"x ":"",M=L>1?"s":"",R=""+D+V,O=L+" sheet"+M,F=c(S,N);return(0,e.createComponentVNode)(2,y.ImageButton,{fluid:!0,base64:P,dmIcon:x,dmIconState:E,imageSize:32,disabled:!F,tooltip:O,buttons:w>1&&F>1&&(0,e.createComponentVNode)(2,m,{recipe:S,max_possible_multiplier:F}),onClick:function(){function _(){return C("make",{recipe_uid:A,multiplier:1})}return _}(),children:R})}},38307:function(T,r,n){"use strict";r.__esModule=!0,r.StationAlertConsoleContent=r.StationAlertConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.StationAlertConsole=function(){function y(){return(0,e.createComponentVNode)(2,o.Window,{width:325,height:500,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,b)})})}return y}(),b=r.StationAlertConsoleContent=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.data,c=l.alarms||[],m=c.Fire||[],i=c.Atmosphere||[],u=c.Power||[];return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{title:"Fire Alarms",children:(0,e.createVNode)(1,"ul",null,[m.length===0&&(0,e.createVNode)(1,"li","color-good","Systems Nominal",16),m.map(function(s){return(0,e.createVNode)(1,"li","color-average",s,0,null,s)})],0)}),(0,e.createComponentVNode)(2,t.Section,{title:"Atmospherics Alarms",children:(0,e.createVNode)(1,"ul",null,[i.length===0&&(0,e.createVNode)(1,"li","color-good","Systems Nominal",16),i.map(function(s){return(0,e.createVNode)(1,"li","color-average",s,0,null,s)})],0)}),(0,e.createComponentVNode)(2,t.Section,{title:"Power Alarms",children:(0,e.createVNode)(1,"ul",null,[u.length===0&&(0,e.createVNode)(1,"li","color-good","Systems Nominal",16),u.map(function(s){return(0,e.createVNode)(1,"li","color-average",s,0,null,s)})],0)})],4)}return y}()},96091:function(T,r,n){"use strict";r.__esModule=!0,r.StationTraitsPanel=void 0;var e=n(89005),a=n(88510),t=n(42127),o=n(72253),f=n(36036),b=n(98595),y=function(l){return l[l.SetupFutureStationTraits=0]="SetupFutureStationTraits",l[l.ViewStationTraits=1]="ViewStationTraits",l}(y||{}),I=function(c,m){var i=(0,o.useBackend)(m),u=i.act,s=i.data,d=s.future_station_traits,v=(0,o.useLocalState)(m,"selectedFutureTrait",null),h=v[0],C=v[1],p=Object.fromEntries(s.valid_station_traits.map(function(V){return[V.name,V.path]})),N=Object.keys(p);return N.sort(),(0,e.createComponentVNode)(2,f.Box,{children:[(0,e.createComponentVNode)(2,f.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,f.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,f.Dropdown,{displayText:!h&&"Select trait to add...",onSelected:C,options:N,selected:h,width:"100%"})}),(0,e.createComponentVNode)(2,f.Stack.Item,{children:(0,e.createComponentVNode)(2,f.Button,{color:"green",icon:"plus",onClick:function(){function V(){if(h){var S=p[h],B=[S];if(d){var L,w=d.map(function(A){return A.path});if(w.indexOf(S)!==-1)return;B=(L=B).concat.apply(L,w)}u("setup_future_traits",{station_traits:B})}}return V}(),children:"Add"})})]}),(0,e.createComponentVNode)(2,f.Divider),Array.isArray(d)?d.length>0?(0,e.createComponentVNode)(2,f.Stack,{vertical:!0,fill:!0,children:d.map(function(V){return(0,e.createComponentVNode)(2,f.Stack.Item,{children:(0,e.createComponentVNode)(2,f.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,f.Stack.Item,{grow:!0,children:V.name}),(0,e.createComponentVNode)(2,f.Stack.Item,{children:(0,e.createComponentVNode)(2,f.Button,{color:"red",icon:"times",onClick:function(){function S(){u("setup_future_traits",{station_traits:(0,a.filterMap)(d,function(B){if(B.path!==V.path)return B.path})})}return S}(),children:"Delete"})})]})},V.path)})}):(0,e.createComponentVNode)(2,f.Box,{textAlign:"center",children:[(0,e.createComponentVNode)(2,f.Box,{children:"No station traits will run next round."}),(0,e.createComponentVNode)(2,f.Button,{mt:1,fluid:!0,color:"good",icon:"times",tooltip:"The next round will roll station traits randomly, just like normal",onClick:function(){function V(){return u("clear_future_traits")}return V}(),children:"Run Station Traits Normally"})]}):(0,e.createComponentVNode)(2,f.Box,{textAlign:"center",children:[(0,e.createComponentVNode)(2,f.Box,{children:"No future station traits are planned."}),(0,e.createComponentVNode)(2,f.Button,{mt:1,fluid:!0,color:"red",icon:"times",onClick:function(){function V(){return u("setup_future_traits",{station_traits:[]})}return V}(),children:"Prevent station traits from running next round"})]})]})},k=function(c,m){var i=(0,o.useBackend)(m),u=i.act,s=i.data;return s.current_traits.length>0?(0,e.createComponentVNode)(2,f.Stack,{vertical:!0,fill:!0,children:s.current_traits.map(function(d){return(0,e.createComponentVNode)(2,f.Stack.Item,{children:(0,e.createComponentVNode)(2,f.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,f.Stack.Item,{grow:!0,children:d.name}),(0,e.createComponentVNode)(2,f.Stack.Item,{children:(0,e.createComponentVNode)(2,f.Button.Confirm,{content:"Revert",color:"red",disabled:s.too_late_to_revert||!d.can_revert,tooltip:!d.can_revert&&"This trait is not revertable."||s.too_late_to_revert&&"It's too late to revert station traits, the round has already started.",icon:"times",onClick:function(){function v(){return u("revert",{ref:d.ref})}return v}()})})]})},d.ref)})}):(0,e.createComponentVNode)(2,f.Box,{textAlign:"center",children:"There are no active station traits."})},g=r.StationTraitsPanel=function(){function l(c,m){var i=(0,o.useLocalState)(m,"station_traits_tab",y.ViewStationTraits),u=i[0],s=i[1],d;switch(u){case y.SetupFutureStationTraits:d=(0,e.createComponentVNode)(2,I);break;case y.ViewStationTraits:d=(0,e.createComponentVNode)(2,k);break;default:(0,t.exhaustiveCheck)(u)}return(0,e.createComponentVNode)(2,b.Window,{title:"Modify Station Traits",height:350,width:350,children:(0,e.createComponentVNode)(2,b.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,f.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,f.Stack.Item,{children:(0,e.createComponentVNode)(2,f.Tabs,{children:[(0,e.createComponentVNode)(2,f.Tabs.Tab,{icon:"eye",selected:u===y.ViewStationTraits,onClick:function(){function v(){return s(y.ViewStationTraits)}return v}(),children:"View"}),(0,e.createComponentVNode)(2,f.Tabs.Tab,{icon:"edit",selected:u===y.SetupFutureStationTraits,onClick:function(){function v(){return s(y.SetupFutureStationTraits)}return v}(),children:"Edit"})]})}),(0,e.createComponentVNode)(2,f.Stack.Item,{m:0,children:[(0,e.createComponentVNode)(2,f.Divider),d]})]})})})}return l}()},39409:function(T,r,n){"use strict";r.__esModule=!0,r.StripMenu=void 0;var e=n(89005),a=n(88510),t=n(79140),o=n(72253),f=n(36036),b=n(98595),y=5,I=9,k=function(h){return h===0?5:9},g="64px",l=function(h){return h[0]+"/"+h[1]},c=function(h){var C=h.align,p=h.children;return(0,e.createComponentVNode)(2,f.Box,{style:{position:"absolute",left:C==="left"?"6px":"48px","text-align":C,"text-shadow":"2px 2px 2px #000",top:"2px"},children:p})},m={enable_internals:{icon:"lungs",text:"Enable internals"},disable_internals:{icon:"lungs",text:"Disable internals"},enable_lock:{icon:"lock",text:"Enable lock"},disable_lock:{icon:"unlock",text:"Disable lock"},suit_sensors:{icon:"tshirt",text:"Adjust suit sensors"},remove_accessory:{icon:"medal",text:"Remove accessory"},dislodge_headpocket:{icon:"head-side-virus",text:"Dislodge headpocket"}},i={eyes:{displayName:"eyewear",gridSpot:l([0,0]),image:"inventory-glasses.png"},head:{displayName:"headwear",gridSpot:l([0,1]),image:"inventory-head.png"},mask:{displayName:"mask",gridSpot:l([1,1]),image:"inventory-mask.png"},neck:{displayName:"neck",gridSpot:l([1,0]),image:"inventory-neck.png"},pet_collar:{displayName:"collar",gridSpot:l([1,1]),image:"inventory-collar.png"},right_ear:{displayName:"right ear",gridSpot:l([0,2]),image:"inventory-ears.png"},left_ear:{displayName:"left ear",gridSpot:l([1,2]),image:"inventory-ears.png"},parrot_headset:{displayName:"headset",gridSpot:l([1,2]),image:"inventory-ears.png"},handcuffs:{displayName:"handcuffs",gridSpot:l([1,3])},legcuffs:{displayName:"legcuffs",gridSpot:l([1,4])},jumpsuit:{displayName:"uniform",gridSpot:l([2,0]),image:"inventory-uniform.png"},suit:{displayName:"suit",gridSpot:l([2,1]),image:"inventory-suit.png"},gloves:{displayName:"gloves",gridSpot:l([2,2]),image:"inventory-gloves.png"},right_hand:{displayName:"right hand",gridSpot:l([2,3]),image:"inventory-hand_r.png",additionalComponent:(0,e.createComponentVNode)(2,c,{align:"left",children:"R"})},left_hand:{displayName:"left hand",gridSpot:l([2,4]),image:"inventory-hand_l.png",additionalComponent:(0,e.createComponentVNode)(2,c,{align:"right",children:"L"})},shoes:{displayName:"shoes",gridSpot:l([3,1]),image:"inventory-shoes.png"},suit_storage:{displayName:"suit storage",gridSpot:l([4,0]),image:"inventory-suit_storage.png"},id:{displayName:"ID",gridSpot:l([4,1]),image:"inventory-id.png"},belt:{displayName:"belt",gridSpot:l([4,2]),image:"inventory-belt.png"},back:{displayName:"backpack",gridSpot:l([4,3]),image:"inventory-back.png"},left_pocket:{displayName:"left pocket",gridSpot:l([3,4]),image:"inventory-pocket.png"},right_pocket:{displayName:"right pocket",gridSpot:l([3,3]),image:"inventory-pocket.png"},pda:{displayName:"PDA",gridSpot:l([4,4]),image:"inventory-pda.png"}},u={eyes:{displayName:"eyewear",gridSpot:l([0,0]),image:"inventory-glasses.png"},head:{displayName:"headwear",gridSpot:l([0,1]),image:"inventory-head.png"},mask:{displayName:"mask",gridSpot:l([1,1]),image:"inventory-mask.png"},neck:{displayName:"neck",gridSpot:l([1,0]),image:"inventory-neck.png"},pet_collar:{displayName:"collar",gridSpot:l([1,1]),image:"inventory-collar.png"},right_ear:{displayName:"right ear",gridSpot:l([0,2]),image:"inventory-ears.png"},left_ear:{displayName:"left ear",gridSpot:l([1,2]),image:"inventory-ears.png"},parrot_headset:{displayName:"headset",gridSpot:l([1,2]),image:"inventory-ears.png"},handcuffs:{displayName:"handcuffs",gridSpot:l([1,3])},legcuffs:{displayName:"legcuffs",gridSpot:l([1,4])},jumpsuit:{displayName:"uniform",gridSpot:l([2,0]),image:"inventory-uniform.png"},suit:{displayName:"suit",gridSpot:l([2,1]),image:"inventory-suit.png"},gloves:{displayName:"gloves",gridSpot:l([2,2]),image:"inventory-gloves.png"},right_hand:{displayName:"right hand",gridSpot:l([4,4]),image:"inventory-hand_r.png",additionalComponent:(0,e.createComponentVNode)(2,c,{align:"left",children:"R"})},left_hand:{displayName:"left hand",gridSpot:l([4,5]),image:"inventory-hand_l.png",additionalComponent:(0,e.createComponentVNode)(2,c,{align:"right",children:"L"})},shoes:{displayName:"shoes",gridSpot:l([3,1]),image:"inventory-shoes.png"},suit_storage:{displayName:"suit storage",gridSpot:l([4,0]),image:"inventory-suit_storage.png"},id:{displayName:"ID",gridSpot:l([4,1]),image:"inventory-id.png"},belt:{displayName:"belt",gridSpot:l([4,2]),image:"inventory-belt.png"},back:{displayName:"backpack",gridSpot:l([4,3]),image:"inventory-back.png"},left_pocket:{displayName:"left pocket",gridSpot:l([4,7]),image:"inventory-pocket.png"},right_pocket:{displayName:"right pocket",gridSpot:l([4,6]),image:"inventory-pocket.png"},pda:{displayName:"PDA",gridSpot:l([4,8]),image:"inventory-pda.png"}},s=function(v){return v[v.Completely=1]="Completely",v[v.Hidden=2]="Hidden",v}(s||{}),d=r.StripMenu=function(){function v(h,C){var p=(0,o.useBackend)(C),N=p.act,V=p.data,S=new Map;if(V.show_mode===0)for(var B=0,L=Object.keys(V.items);B=.01})},(0,a.sortBy)(function(x){return-x.amount})])(h.gases||[]),A=Math.max.apply(Math,[1].concat(w.map(function(x){return x.portion})));return(0,e.createComponentVNode)(2,I.Window,{width:550,height:250,children:(0,e.createComponentVNode)(2,I.Window.Content,{children:(0,e.createComponentVNode)(2,b.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{width:"270px",children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Metrics",children:(0,e.createComponentVNode)(2,b.LabeledList,{children:[(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Integrity",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:p/100,ranges:{good:[.9,1/0],average:[.5,.9],bad:[-1/0,.5]}})}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Relative EER",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:N,minValue:0,maxValue:5e3,ranges:{good:[-1/0,5e3],average:[5e3,7e3],bad:[7e3,1/0]},children:(0,o.toFixed)(N)+" MeV/cm3"})}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Gas Coefficient",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:L,minValue:1,maxValue:5.25,ranges:{bad:[1,1.55],average:[1.55,5.25],good:[5.25,1/0]},children:L.toFixed(2)})}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Temperature",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:l(V),minValue:0,maxValue:l(1e4),ranges:{teal:[-1/0,l(80)],good:[l(80),l(373)],average:[l(373),l(1e3)],bad:[l(1e3),1/0]},children:(0,o.toFixed)(V)+" K"})}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Mole Per Tile",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:B,minValue:0,maxValue:12e3,ranges:{teal:[-1/0,100],average:[100,11333],good:[11333,12e3],bad:[12e3,1/0]},children:(0,o.toFixed)(B)+" mol"})}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Pressure",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:l(S),minValue:0,maxValue:l(5e4),ranges:{good:[l(1),l(300)],average:[-1/0,l(1e3)],bad:[l(1e3),1/0]},children:(0,o.toFixed)(S)+" kPa"})})]})})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,basis:0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Gases",buttons:(0,e.createComponentVNode)(2,b.Button,{icon:"arrow-left",content:"Back",onClick:function(){function x(){return v("back")}return x}()}),children:(0,e.createComponentVNode)(2,b.LabeledList,{children:w.map(function(x){return(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:(0,y.getGasLabel)(x.name),children:(0,e.createComponentVNode)(2,b.ProgressBar,{color:(0,y.getGasColor)(x.name),value:x.portion,minValue:0,maxValue:A,children:(0,o.toFixed)(x.amount)+" mol ("+x.portion+"%)"})},x.name)})})})})]})})})}},46029:function(T,r,n){"use strict";r.__esModule=!0,r.SyndicateComputerSimple=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.SyndicateComputerSimple=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data;return(0,e.createComponentVNode)(2,o.Window,{theme:"syndicate",width:400,height:400,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:l.rows.map(function(c){return(0,e.createComponentVNode)(2,t.Section,{title:c.title,buttons:(0,e.createComponentVNode)(2,t.Button,{content:c.buttontitle,disabled:c.buttondisabled,tooltip:c.buttontooltip,tooltipPosition:"left",onClick:function(){function m(){return g(c.buttonact)}return m}()}),children:[c.status,!!c.bullets&&(0,e.createComponentVNode)(2,t.Box,{children:c.bullets.map(function(m){return(0,e.createComponentVNode)(2,t.Box,{children:m},m)})})]},c.title)})})})}return b}()},36372:function(T,r,n){"use strict";r.__esModule=!0,r.TEG=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=function(I){return I.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,")},b=r.TEG=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data;return c.error?(0,e.createComponentVNode)(2,o.Window,{width:500,height:400,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Error",children:[c.error,(0,e.createComponentVNode)(2,t.Button,{icon:"circle",content:"Recheck",onClick:function(){function m(){return l("check")}return m}()})]})})}):(0,e.createComponentVNode)(2,o.Window,{width:500,height:400,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Cold Loop ("+c.cold_dir+")",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cold Inlet",children:[f(c.cold_inlet_temp)," K, ",f(c.cold_inlet_pressure)," kPa"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cold Outlet",children:[f(c.cold_outlet_temp)," K, ",f(c.cold_outlet_pressure)," kPa"]})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Hot Loop ("+c.hot_dir+")",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Hot Inlet",children:[f(c.hot_inlet_temp)," K, ",f(c.hot_inlet_pressure)," kPa"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Hot Outlet",children:[f(c.hot_outlet_temp)," K, ",f(c.hot_outlet_pressure)," kPa"]})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Power Output",children:[f(c.output_power)," W",!!c.warning_switched&&(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Warning: Cold inlet temperature exceeds hot inlet temperature."}),!!c.warning_cold_pressure&&(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Warning: Cold circulator inlet pressure is under 1,000 kPa."}),!!c.warning_hot_pressure&&(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Warning: Hot circulator inlet pressure is under 1,000 kPa."})]})]})})}return y}()},56441:function(T,r,n){"use strict";r.__esModule=!0,r.TachyonArrayContent=r.TachyonArray=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.TachyonArray=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=c.records,i=m===void 0?[]:m,u=c.explosion_target,s=c.toxins_tech,d=c.printing;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:600,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Shift's Target",children:u}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Toxins Level",children:s}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Administration",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"print",content:"Print All Logs",disabled:!i.length||d,align:"center",onClick:function(){function v(){return l("print_logs")}return v}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"trash",content:"Delete All Logs",disabled:!i.length,color:"bad",align:"center",onClick:function(){function v(){return l("delete_logs")}return v}()})]})]})}),i.length?(0,e.createComponentVNode)(2,b):(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No Records"})]})})}return y}(),b=r.TachyonArrayContent=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=c.records,i=m===void 0?[]:m;return(0,e.createComponentVNode)(2,t.Section,{title:"Logged Explosions",children:(0,e.createComponentVNode)(2,t.Flex,{children:(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Time"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Epicenter"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Actual Size"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Theoretical Size"})]}),i.map(function(u){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.logged_time}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.epicenter}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.actual_size_message}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.theoretical_size_message}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"trash",content:"Delete",color:"bad",onClick:function(){function s(){return l("delete_record",{index:u.index})}return s}()})})]},u.index)})]})})})})}return y}()},1754:function(T,r,n){"use strict";r.__esModule=!0,r.Tank=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.Tank=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c;return l.has_mask?c=(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Mask",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,width:"76%",icon:l.connected?"check":"times",content:l.connected?"Internals On":"Internals Off",selected:l.connected,onClick:function(){function m(){return g("internals")}return m}()})}):c=(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Mask",color:"red",children:"No Mask Equipped"}),(0,e.createComponentVNode)(2,o.Window,{width:325,height:135,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tank Pressure",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:l.tankPressure/1013,ranges:{good:[.35,1/0],average:[.15,.35],bad:[-1/0,.15]},children:l.tankPressure+" kPa"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Release Pressure",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"fast-backward",disabled:l.ReleasePressure===l.minReleasePressure,tooltip:"Min",onClick:function(){function m(){return g("pressure",{pressure:"min"})}return m}()}),(0,e.createComponentVNode)(2,t.NumberInput,{animated:!0,value:parseFloat(l.releasePressure),width:"65px",unit:"kPa",minValue:l.minReleasePressure,maxValue:l.maxReleasePressure,onChange:function(){function m(i,u){return g("pressure",{pressure:u})}return m}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fast-forward",disabled:l.ReleasePressure===l.maxReleasePressure,tooltip:"Max",onClick:function(){function m(){return g("pressure",{pressure:"max"})}return m}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"undo",content:"",disabled:l.ReleasePressure===l.defaultReleasePressure,tooltip:"Reset",onClick:function(){function m(){return g("pressure",{pressure:"reset"})}return m}()})]}),c]})})})})}return b}()},7579:function(T,r,n){"use strict";r.__esModule=!0,r.TankDispenser=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.TankDispenser=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.o_tanks,m=l.p_tanks;return(0,e.createComponentVNode)(2,o.Window,{width:250,height:105,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,content:"Dispense Oxygen Tank ("+c+")",disabled:c===0,icon:"arrow-circle-down",onClick:function(){function i(){return g("oxygen")}return i}()})}),(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{mt:1,fluid:!0,content:"Dispense Plasma Tank ("+m+")",disabled:m===0,icon:"arrow-circle-down",onClick:function(){function i(){return g("plasma")}return i}()})})]})})})}return b}()},16136:function(T,r,n){"use strict";r.__esModule=!0,r.TcommsCore=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.TcommsCore=function(){function g(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.ion,d=(0,a.useLocalState)(c,"tabIndex",0),v=d[0],h=d[1],C=function(){function p(N){switch(N){case 0:return(0,e.createComponentVNode)(2,y);case 1:return(0,e.createComponentVNode)(2,I);case 2:return(0,e.createComponentVNode)(2,k);default:return"SOMETHING WENT VERY WRONG PLEASE AHELP"}}return p}();return(0,e.createComponentVNode)(2,o.Window,{width:900,height:520,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[s===1&&(0,e.createComponentVNode)(2,b),(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"wrench",selected:v===0,onClick:function(){function p(){return h(0)}return p}(),children:"Configuration"},"ConfigPage"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"link",selected:v===1,onClick:function(){function p(){return h(1)}return p}(),children:"Device Linkage"},"LinkagePage"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"user-times",selected:v===2,onClick:function(){function p(){return h(2)}return p}(),children:"User Filtering"},"FilterPage")]}),C(v)]})})}return g}(),b=function(){return(0,e.createComponentVNode)(2,t.NoticeBox,{children:"ERROR: An Ionospheric overload has occured. Please wait for the machine to reboot. This cannot be manually done."})},y=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.active,d=u.sectors_available,v=u.nttc_toggle_jobs,h=u.nttc_toggle_job_color,C=u.nttc_toggle_name_color,p=u.nttc_toggle_command_bold,N=u.nttc_job_indicator_type,V=u.nttc_setting_language,S=u.network_id;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{title:"Status",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Machine Power",children:(0,e.createComponentVNode)(2,t.Button,{content:s?"On":"Off",selected:s,icon:"power-off",onClick:function(){function B(){return i("toggle_active")}return B}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Sector Coverage",children:d})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Radio Configuration",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Job Announcements",children:(0,e.createComponentVNode)(2,t.Button,{content:v?"On":"Off",selected:v,icon:"user-tag",onClick:function(){function B(){return i("nttc_toggle_jobs")}return B}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Job Departmentalisation",children:(0,e.createComponentVNode)(2,t.Button,{content:h?"On":"Off",selected:h,icon:"clipboard-list",onClick:function(){function B(){return i("nttc_toggle_job_color")}return B}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Name Departmentalisation",children:(0,e.createComponentVNode)(2,t.Button,{content:C?"On":"Off",selected:C,icon:"user-tag",onClick:function(){function B(){return i("nttc_toggle_name_color")}return B}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Command Amplification",children:(0,e.createComponentVNode)(2,t.Button,{content:p?"On":"Off",selected:p,icon:"volume-up",onClick:function(){function B(){return i("nttc_toggle_command_bold")}return B}()})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Advanced",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Job Announcement Format",children:(0,e.createComponentVNode)(2,t.Button,{content:N||"Unset",selected:N,icon:"pencil-alt",onClick:function(){function B(){return i("nttc_job_indicator_type")}return B}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Language Conversion",children:(0,e.createComponentVNode)(2,t.Button,{content:V||"Unset",selected:V,icon:"globe",onClick:function(){function B(){return i("nttc_setting_language")}return B}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Network ID",children:(0,e.createComponentVNode)(2,t.Button,{content:S||"Unset",selected:S,icon:"server",onClick:function(){function B(){return i("network_id")}return B}()})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Maintenance",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Import Configuration",icon:"file-import",onClick:function(){function B(){return i("import")}return B}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Export Configuration",icon:"file-export",onClick:function(){function B(){return i("export")}return B}()})]})],4)},I=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.link_password,d=u.relay_entries;return(0,e.createComponentVNode)(2,t.Section,{title:"Device Linkage",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Linkage Password",children:(0,e.createComponentVNode)(2,t.Button,{content:s||"Unset",selected:s,icon:"lock",onClick:function(){function v(){return i("change_password")}return v}()})})}),(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network Address"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network ID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Sector"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Status"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Unlink"})]}),d.map(function(v){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:v.addr}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:v.net_id}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:v.sector}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:v.status===1?(0,e.createComponentVNode)(2,t.Box,{color:"green",children:"Online"}):(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Offline"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Unlink",icon:"unlink",onClick:function(){function h(){return i("unlink",{addr:v.addr})}return h}()})})]},v.addr)})]})]})},k=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.filtered_users;return(0,e.createComponentVNode)(2,t.Section,{title:"User Filtering",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Add User",icon:"user-plus",onClick:function(){function d(){return i("add_filter")}return d}()}),children:(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{style:{width:"90%"},children:"User"}),(0,e.createComponentVNode)(2,t.Table.Cell,{style:{width:"10%"},children:"Actions"})]}),s.map(function(d){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:d}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Remove",icon:"user-times",onClick:function(){function v(){return i("remove_filter",{user:d})}return v}()})})]},d)})]})})}},88046:function(T,r,n){"use strict";r.__esModule=!0,r.TcommsRelay=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.TcommsRelay=function(){function I(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.linked,u=m.active,s=m.network_id;return(0,e.createComponentVNode)(2,o.Window,{width:600,height:292,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Relay Configuration",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Machine Power",children:(0,e.createComponentVNode)(2,t.Button,{content:u?"On":"Off",selected:u,icon:"power-off",onClick:function(){function d(){return c("toggle_active")}return d}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Network ID",children:(0,e.createComponentVNode)(2,t.Button,{content:s||"Unset",selected:s,icon:"server",onClick:function(){function d(){return c("network_id")}return d}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Link Status",children:i===1?(0,e.createComponentVNode)(2,t.Box,{color:"green",children:"Linked"}):(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Unlinked"})})]})}),i===1?(0,e.createComponentVNode)(2,b):(0,e.createComponentVNode)(2,y)]})})}return I}(),b=function(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.linked_core_id,u=m.linked_core_addr,s=m.hidden_link;return(0,e.createComponentVNode)(2,t.Section,{title:"Link Status",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Linked Core ID",children:i}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Linked Core Address",children:u}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Hidden Link",children:(0,e.createComponentVNode)(2,t.Button,{content:s?"Yes":"No",icon:s?"eye-slash":"eye",selected:s,onClick:function(){function d(){return c("toggle_hidden_link")}return d}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Unlink",children:(0,e.createComponentVNode)(2,t.Button,{content:"Unlink",icon:"unlink",color:"red",onClick:function(){function d(){return c("unlink")}return d}()})})]})})},y=function(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.cores;return(0,e.createComponentVNode)(2,t.Section,{title:"Detected Cores",children:(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network Address"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network ID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Sector"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Link"})]}),i.map(function(u){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.addr}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.net_id}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.sector}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Link",icon:"link",onClick:function(){function s(){return c("link",{addr:u.addr})}return s}()})})]},u.addr)})]})})}},20802:function(T,r,n){"use strict";r.__esModule=!0,r.Teleporter=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.Teleporter=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.targetsTeleport?l.targetsTeleport:{},m=0,i=1,u=2,s=l.calibrated,d=l.calibrating,v=l.powerstation,h=l.regime,C=l.teleporterhub,p=l.target,N=l.locked,V=l.adv_beacon_allowed,S=l.advanced_beacon_locking;return(0,e.createComponentVNode)(2,o.Window,{width:350,height:270,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:[(!v||!C)&&(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Error",children:[C,!v&&(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:" Powerstation not linked "}),v&&!C&&(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:" Teleporter hub not linked "})]}),v&&C&&(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Status",buttons:(0,e.createFragment)(!!V&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:"label",children:"Advanced Beacon Locking:\xA0"}),(0,e.createComponentVNode)(2,t.Button,{selected:S,icon:S?"toggle-on":"toggle-off",content:S?"Enabled":"Disabled",onClick:function(){function B(){return g("advanced_beacon_locking",{on:S?0:1})}return B}()})],4),0),children:[(0,e.createComponentVNode)(2,t.Stack,{mb:1,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:8.5,color:"label",children:"Teleport target:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[h===m&&(0,e.createComponentVNode)(2,t.Dropdown,{width:18.2,selected:p,disabled:d,options:Object.keys(c),color:p!=="None"?"default":"bad",onSelected:function(){function B(L){return g("settarget",{x:c[L].x,y:c[L].y,z:c[L].z,tptarget:c[L].pretarget})}return B}()}),h===i&&(0,e.createComponentVNode)(2,t.Dropdown,{width:18.2,selected:p,disabled:d,options:Object.keys(c),color:p!=="None"?"default":"bad",onSelected:function(){function B(L){return g("settarget",{x:c[L].x,y:c[L].y,z:c[L].z,tptarget:c[L].pretarget})}return B}()}),h===u&&(0,e.createComponentVNode)(2,t.Box,{children:p})]})]}),(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:8.5,color:"label",children:"Regime:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,content:"Gate",tooltip:"Teleport to another teleport hub.",tooltipPosition:"top",color:h===i?"good":null,onClick:function(){function B(){return g("setregime",{regime:i})}return B}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,content:"Teleporter",tooltip:"One-way teleport.",tooltipPosition:"top",color:h===m?"good":null,onClick:function(){function B(){return g("setregime",{regime:m})}return B}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,content:"GPS",tooltip:"Teleport to a location stored in a GPS device.",tooltipPosition:"top-end",color:h===u?"good":null,disabled:!N,onClick:function(){function B(){return g("setregime",{regime:u})}return B}()})})]}),(0,e.createComponentVNode)(2,t.Stack,{label:"Calibration",mt:1,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:8.5,color:"label",children:"Calibration:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[p!=="None"&&(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:15.8,textAlign:"center",mt:.5,children:d&&(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"In Progress"})||s&&(0,e.createComponentVNode)(2,t.Box,{color:"good",children:"Optimal"})||(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:"Sub-Optimal"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{icon:"sync-alt",tooltip:"Calibrates the hub. Accidents may occur when the calibration is not optimal.",tooltipPosition:"bottom-end",disabled:!!(s||d),onClick:function(){function B(){return g("calibrate")}return B}()})})]}),p==="None"&&(0,e.createComponentVNode)(2,t.Box,{lineHeight:"21px",children:"No target set"})]})]})]}),!!(N&&v&&C&&h===u)&&(0,e.createComponentVNode)(2,t.Section,{title:"GPS",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Button,{content:"Upload GPS data",tooltip:"Loads the GPS data from the device.",icon:"upload",onClick:function(){function B(){return g("load")}return B}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Eject",tooltip:"Ejects the GPS device",icon:"eject",onClick:function(){function B(){return g("eject")}return B}()})]})})]})})})})}return b}()},48517:function(T,r,n){"use strict";r.__esModule=!0,r.TelescienceConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.TelescienceConsole=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.last_msg,m=l.linked_pad,i=l.held_gps,u=l.lastdata,s=l.power_levels,d=l.current_max_power,v=l.current_power,h=l.current_bearing,C=l.current_elevation,p=l.current_sector,N=l.working,V=l.max_z,S=(0,a.useLocalState)(I,"dummyrot",h),B=S[0],L=S[1];return(0,e.createComponentVNode)(2,o.Window,{width:400,height:500,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Status",children:(0,e.createFragment)([c,!(u.length>0)||(0,e.createVNode)(1,"ul",null,u.map(function(w){return(0,e.createVNode)(1,"li",null,w,0,null,w)}),0)],0)}),(0,e.createComponentVNode)(2,t.Section,{title:"Telepad Status",children:m===1?(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Bearing",children:(0,e.createComponentVNode)(2,t.Box,{inline:!0,position:"relative",children:[(0,e.createComponentVNode)(2,t.NumberInput,{unit:"\xB0",width:6.1,lineHeight:1.5,step:.1,minValue:0,maxValue:360,disabled:N,value:h,onDrag:function(){function w(A,x){return L(x)}return w}(),onChange:function(){function w(A,x){return g("setbear",{bear:x})}return w}()}),(0,e.createComponentVNode)(2,t.Icon,{ml:1,size:1,name:"arrow-up",rotation:B})]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Elevation",children:(0,e.createComponentVNode)(2,t.NumberInput,{width:6.1,lineHeight:1.5,step:.1,minValue:0,maxValue:100,disabled:N,value:C,onChange:function(){function w(A,x){return g("setelev",{elev:x})}return w}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power Level",children:s.map(function(w,A){return(0,e.createComponentVNode)(2,t.Button,{content:w,selected:v===w,disabled:A>=d-1||N,onClick:function(){function x(){return g("setpwr",{pwr:A+1})}return x}()},w)})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Target Sector",children:(0,e.createComponentVNode)(2,t.NumberInput,{width:6.1,lineHeight:1.5,step:1,minValue:2,maxValue:V,value:p,disabled:N,onChange:function(){function w(A,x){return g("setz",{newz:x})}return w}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Telepad Actions",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Send",disabled:N,onClick:function(){function w(){return g("pad_send")}return w}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Receive",disabled:N,onClick:function(){function w(){return g("pad_receive")}return w}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Crystal Maintenance",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Recalibrate Crystals",disabled:N,onClick:function(){function w(){return g("recal_crystals")}return w}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Eject Crystals",disabled:N,onClick:function(){function w(){return g("eject_crystals")}return w}()})]})]}):(0,e.createFragment)([(0,e.createTextVNode)("No pad linked to console. Please use a multitool to link a pad.")],4)}),(0,e.createComponentVNode)(2,t.Section,{title:"GPS Actions",children:i===1?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{disabled:i===0||N,content:"Eject GPS",onClick:function(){function w(){return g("eject_gps")}return w}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:i===0||N,content:"Store Coordinates",onClick:function(){function w(){return g("store_to_gps")}return w}()})],4):(0,e.createFragment)([(0,e.createTextVNode)("Please insert a GPS to store coordinates to it.")],4)})]})})}return b}()},21800:function(T,r,n){"use strict";r.__esModule=!0,r.TempGun=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),f=n(98595),b=r.TempGun=function(){function g(l,c){var m=(0,t.useBackend)(c),i=m.act,u=m.data,s=u.target_temperature,d=u.temperature,v=u.max_temp,h=u.min_temp;return(0,e.createComponentVNode)(2,f.Window,{width:250,height:121,children:(0,e.createComponentVNode)(2,f.Window.Content,{children:(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Target Temperature",children:[(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,step:10,stepPixelSize:6,minValue:h,maxValue:v,value:s,format:function(){function C(p){return(0,a.toFixed)(p,2)}return C}(),width:"50px",onDrag:function(){function C(p,N){return i("target_temperature",{target_temperature:N})}return C}()}),"\xB0C"]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Current Temperature",children:(0,e.createComponentVNode)(2,o.Box,{color:y(d),bold:d>500-273.15,children:[(0,e.createComponentVNode)(2,o.AnimatedNumber,{value:(0,a.round)(d,2)}),"\xB0C"]})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Power Cost",children:(0,e.createComponentVNode)(2,o.Box,{color:k(d),children:I(d)})})]})})})})}return g}(),y=function(l){return l<=-100?"blue":l<=0?"teal":l<=100?"green":l<=200?"orange":"red"},I=function(l){return l<=100-273.15?"High":l<=250-273.15?"Medium":l<=300-273.15?"Low":l<=400-273.15?"Medium":"High"},k=function(l){return l<=100-273.15?"red":l<=250-273.15?"orange":l<=300-273.15?"green":l<=400-273.15?"orange":"red"}},24410:function(T,r,n){"use strict";r.__esModule=!0,r.sanitizeMultiline=r.removeAllSkiplines=r.TextInputModal=void 0;var e=n(89005),a=n(51057),t=n(19203),o=n(72253),f=n(92986),b=n(36036),y=n(98595),I=r.sanitizeMultiline=function(){function c(m){return m.replace(/(\n|\r\n){3,}/,"\n\n")}return c}(),k=r.removeAllSkiplines=function(){function c(m){return m.replace(/[\r\n]+/,"")}return c}(),g=r.TextInputModal=function(){function c(m,i){var u=(0,o.useBackend)(i),s=u.act,d=u.data,v=d.max_length,h=d.message,C=h===void 0?"":h,p=d.multiline,N=d.placeholder,V=d.timeout,S=d.title,B=(0,o.useLocalState)(i,"input",N||""),L=B[0],w=B[1],A=function(){function P(D){if(D!==L){var M=p?I(D):k(D);w(M)}}return P}(),x=p||L.length>=40,E=130+(C.length>40?Math.ceil(C.length/4):0)+(x?80:0);return(0,e.createComponentVNode)(2,y.Window,{title:S,width:325,height:E,children:[V&&(0,e.createComponentVNode)(2,a.Loader,{value:V}),(0,e.createComponentVNode)(2,y.Window.Content,{onKeyDown:function(){function P(D){var M=window.event?D.which:D.keyCode;M===f.KEY_ENTER&&(!x||!D.shiftKey)&&s("submit",{entry:L}),M===f.KEY_ESCAPE&&s("cancel")}return P}(),children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,children:(0,e.createComponentVNode)(2,b.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Box,{color:"label",children:C})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,l,{input:L,onChange:A})}),(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,t.InputButtons,{input:L,message:L.length+"/"+v})})]})})})]})}return c}(),l=function(m,i){var u=(0,o.useBackend)(i),s=u.act,d=u.data,v=d.max_length,h=d.multiline,C=m.input,p=m.onChange,N=h||C.length>=40;return(0,e.createComponentVNode)(2,b.TextArea,{autoFocus:!0,autoSelect:!0,height:h||C.length>=40?"100%":"1.8rem",maxLength:v,onEscape:function(){function V(){return s("cancel")}return V}(),onEnter:function(){function V(S,B){N&&S.shiftKey||(S.preventDefault(),s("submit",{entry:B}))}return V}(),onChange:function(){function V(S,B){return p(B)}return V}(),placeholder:"Type something...",value:C})}},25036:function(T,r,n){"use strict";r.__esModule=!0,r.ThermoMachine=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),f=n(98595),b=r.ThermoMachine=function(){function y(I,k){var g=(0,t.useBackend)(k),l=g.act,c=g.data;return(0,e.createComponentVNode)(2,f.Window,{width:300,height:225,children:(0,e.createComponentVNode)(2,f.Window.Content,{children:[(0,e.createComponentVNode)(2,o.Section,{title:"Status",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Temperature",children:[(0,e.createComponentVNode)(2,o.AnimatedNumber,{value:c.temperature,format:function(){function m(i){return(0,a.toFixed)(i,2)}return m}()})," K"]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Pressure",children:[(0,e.createComponentVNode)(2,o.AnimatedNumber,{value:c.pressure,format:function(){function m(i){return(0,a.toFixed)(i,2)}return m}()})," kPa"]})]})}),(0,e.createComponentVNode)(2,o.Section,{title:"Controls",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:c.on?"power-off":"times",content:c.on?"On":"Off",selected:c.on,onClick:function(){function m(){return l("power")}return m}()}),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Setting",textAlign:"center",children:(0,e.createComponentVNode)(2,o.Button,{fluid:!0,icon:c.cooling?"temperature-low":"temperature-high",content:c.cooling?"Cooling":"Heating",selected:c.cooling,onClick:function(){function m(){return l("cooling")}return m}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Target Temperature",children:[(0,e.createComponentVNode)(2,o.Button,{icon:"fast-backward",disabled:c.target===c.min,title:"Minimum temperature",onClick:function(){function m(){return l("target",{target:c.min})}return m}()}),(0,e.createComponentVNode)(2,o.NumberInput,{animated:!0,value:Math.round(c.target),unit:"K",width:5.4,lineHeight:1.4,minValue:Math.round(c.min),maxValue:Math.round(c.max),step:5,stepPixelSize:3,onDrag:function(){function m(i,u){return l("target",{target:u})}return m}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"fast-forward",disabled:c.target===c.max,title:"Maximum Temperature",onClick:function(){function m(){return l("target",{target:c.max})}return m}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"sync",disabled:c.target===c.initial,title:"Room Temperature",onClick:function(){function m(){return l("target",{target:c.initial})}return m}()})]})]})})]})})}return y}()},20035:function(T,r,n){"use strict";r.__esModule=!0,r.TransferValve=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.TransferValve=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.tank_one,m=l.tank_two,i=l.attached_device,u=l.valve;return(0,e.createComponentVNode)(2,o.Window,{width:460,height:285,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Valve Status",children:(0,e.createComponentVNode)(2,t.Button,{icon:u?"unlock":"lock",content:u?"Open":"Closed",disabled:!c||!m,onClick:function(){function s(){return g("toggle")}return s}()})})})}),(0,e.createComponentVNode)(2,t.Section,{title:"Assembly",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"cog",content:"Configure Assembly",disabled:!i,onClick:function(){function s(){return g("device")}return s}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Attachment",children:i?(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:i,disabled:!i,onClick:function(){function s(){return g("remove_device")}return s}()}):(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"No Assembly"})})})}),(0,e.createComponentVNode)(2,t.Section,{title:"Attachment One",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Attachment",children:c?(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:c,disabled:!c,onClick:function(){function s(){return g("tankone")}return s}()}):(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"No Tank"})})})}),(0,e.createComponentVNode)(2,t.Section,{title:"Attachment Two",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Attachment",children:m?(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:m,disabled:!m,onClick:function(){function s(){return g("tanktwo")}return s}()}):(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"No Tank"})})})})]})})}return b}()},78166:function(T,r,n){"use strict";r.__esModule=!0,r.TurbineComputer=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=n(44879),b=r.TurbineComputer=function(){function k(g,l){var c=(0,a.useBackend)(l),m=c.act,i=c.data,u=i.compressor,s=i.compressor_broken,d=i.turbine,v=i.turbine_broken,h=i.online,C=!!(u&&!s&&d&&!v);return(0,e.createComponentVNode)(2,o.Window,{width:400,height:200,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Status",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{icon:h?"power-off":"times",content:h?"Online":"Offline",selected:h,disabled:!C,onClick:function(){function p(){return m("toggle_power")}return p}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"times",content:"Disconnect",onClick:function(){function p(){return m("disconnect")}return p}()})],4),children:C?(0,e.createComponentVNode)(2,I):(0,e.createComponentVNode)(2,y)})})})}return k}(),y=function(g,l){var c=(0,a.useBackend)(l),m=c.data,i=m.compressor,u=m.compressor_broken,s=m.turbine,d=m.turbine_broken,v=m.online;return(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Compressor Status",color:!i||u?"bad":"good",children:u?i?"Offline":"Missing":"Online"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Turbine Status",color:!s||d?"bad":"good",children:d?s?"Offline":"Missing":"Online"})]})},I=function(g,l){var c=(0,a.useBackend)(l),m=c.data,i=m.rpm,u=m.temperature,s=m.power,d=m.bearing_heat;return(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Turbine Speed",children:[i," RPM"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Internal Temp",children:[u," K"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Generated Power",children:[s," W"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Bearing Heat",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:d,minValue:0,maxValue:100,ranges:{good:[-1/0,60],average:[60,90],bad:[90,1/0]},children:(0,f.toFixed)(d)+"%"})})]})}},52847:function(T,r,n){"use strict";r.__esModule=!0,r.Uplink=void 0;var e=n(89005),a=n(88510),t=n(64795),o=n(25328),f=n(72253),b=n(36036),y=n(98595),I=n(3939),k=function(h){switch(h){case 0:return(0,e.createComponentVNode)(2,l);case 1:return(0,e.createComponentVNode)(2,c);case 2:return(0,e.createComponentVNode)(2,d);default:return"SOMETHING WENT VERY WRONG PLEASE AHELP"}},g=r.Uplink=function(){function v(h,C){var p=(0,f.useBackend)(C),N=p.act,V=p.data,S=V.cart,B=(0,f.useLocalState)(C,"tabIndex",0),L=B[0],w=B[1],A=(0,f.useLocalState)(C,"searchText",""),x=A[0],E=A[1];return(0,e.createComponentVNode)(2,y.Window,{width:900,height:600,theme:"syndicate",children:[(0,e.createComponentVNode)(2,I.ComplexModal),(0,e.createComponentVNode)(2,y.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,b.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Tabs,{children:[(0,e.createComponentVNode)(2,b.Tabs.Tab,{selected:L===0,onClick:function(){function P(){w(0),E("")}return P}(),icon:"store",children:"View Market"},"PurchasePage"),(0,e.createComponentVNode)(2,b.Tabs.Tab,{selected:L===1,onClick:function(){function P(){w(1),E("")}return P}(),icon:"shopping-cart",children:["View Shopping Cart ",S&&S.length?"("+S.length+")":""]},"Cart"),(0,e.createComponentVNode)(2,b.Tabs.Tab,{selected:L===2,onClick:function(){function P(){w(2),E("")}return P}(),icon:"user",children:"Exploitable Information"},"ExploitableInfo"),(0,e.createComponentVNode)(2,b.Tabs.Tab,{onClick:function(){function P(){return N("lock")}return P}(),icon:"lock",children:"Lock Uplink"},"LockUplink")]})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:k(L)})]})})]})}return v}(),l=function(h,C){var p=(0,f.useBackend)(C),N=p.act,V=p.data,S=V.crystals,B=V.cats,L=(0,f.useLocalState)(C,"uplinkItems",B[0].items),w=L[0],A=L[1],x=(0,f.useLocalState)(C,"searchText",""),E=x[0],P=x[1],D=function(U,z){z===void 0&&(z="");var $=(0,o.createSearch)(z,function(G){var X=G.hijack_only===1?"|hijack":"";return G.name+"|"+G.desc+"|"+G.cost+"tc"+X});return(0,t.flow)([(0,a.filter)(function(G){return G==null?void 0:G.name}),z&&(0,a.filter)($),(0,a.sortBy)(function(G){return G==null?void 0:G.name})])(U)},M=function(U){if(P(U),U==="")return A(B[0].items);A(D(B.map(function(z){return z.items}).flat(),U))},R=(0,f.useLocalState)(C,"showDesc",1),O=R[0],F=R[1];return(0,e.createComponentVNode)(2,b.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.Stack,{vertical:!0,children:(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Section,{title:"Current Balance: "+S+"TC",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,b.Button.Checkbox,{content:"Show Descriptions",checked:O,onClick:function(){function _(){return F(!O)}return _}()}),(0,e.createComponentVNode)(2,b.Button,{content:"Random Item",icon:"question",onClick:function(){function _(){return N("buyRandom")}return _}()}),(0,e.createComponentVNode)(2,b.Button,{content:"Refund Currently Held Item",icon:"undo",onClick:function(){function _(){return N("refund")}return _}()})],4),children:(0,e.createComponentVNode)(2,b.Input,{fluid:!0,placeholder:"Search Equipment",onInput:function(){function _(U,z){M(z)}return _}(),value:E})})})}),(0,e.createComponentVNode)(2,b.Stack,{fill:!0,mt:.3,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{width:"30%",children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,b.Tabs,{vertical:!0,children:B.map(function(_){return(0,e.createComponentVNode)(2,b.Tabs.Tab,{selected:E!==""?!1:_.items===w,onClick:function(){function U(){A(_.items),P("")}return U}(),children:_.cat},_)})})})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,b.Stack,{vertical:!0,children:w.map(function(_){return(0,e.createComponentVNode)(2,b.Stack.Item,{p:1,backgroundColor:"rgba(255, 0, 0, 0.1)",children:(0,e.createComponentVNode)(2,i,{i:_,showDecription:O},(0,o.decodeHtmlEntities)(_.name))},(0,o.decodeHtmlEntities)(_.name))})})})})]})]})},c=function(h,C){var p=(0,f.useBackend)(C),N=p.act,V=p.data,S=V.cart,B=V.crystals,L=V.cart_price,w=(0,f.useLocalState)(C,"showDesc",0),A=w[0],x=w[1];return(0,e.createComponentVNode)(2,b.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Current Balance: "+B+"TC",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,b.Button.Checkbox,{content:"Show Descriptions",checked:A,onClick:function(){function E(){return x(!A)}return E}()}),(0,e.createComponentVNode)(2,b.Button,{content:"Empty Cart",icon:"trash",onClick:function(){function E(){return N("empty_cart")}return E}(),disabled:!S}),(0,e.createComponentVNode)(2,b.Button,{content:"Purchase Cart ("+L+"TC)",icon:"shopping-cart",onClick:function(){function E(){return N("purchase_cart")}return E}(),disabled:!S||L>B})],4),children:(0,e.createComponentVNode)(2,b.Stack,{vertical:!0,children:S?S.map(function(E){return(0,e.createComponentVNode)(2,b.Stack.Item,{p:1,mr:1,backgroundColor:"rgba(255, 0, 0, 0.1)",children:(0,e.createComponentVNode)(2,i,{i:E,showDecription:A,buttons:(0,e.createComponentVNode)(2,s,{i:E})})},(0,o.decodeHtmlEntities)(E.name))}):(0,e.createComponentVNode)(2,b.Box,{italic:!0,children:"Your Shopping Cart is empty!"})})})}),(0,e.createComponentVNode)(2,m)]})},m=function(h,C){var p=(0,f.useBackend)(C),N=p.act,V=p.data,S=V.cats,B=V.lucky_numbers;return(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Suggested Purchases",buttons:(0,e.createComponentVNode)(2,b.Button,{icon:"dice",content:"See more suggestions",onClick:function(){function L(){return N("shuffle_lucky_numbers")}return L}()}),children:(0,e.createComponentVNode)(2,b.Stack,{wrap:!0,children:B.map(function(L){return S[L.cat].items[L.item]}).filter(function(L){return L!=null}).map(function(L,w){return(0,e.createComponentVNode)(2,b.Stack.Item,{p:1,mb:1,ml:1,width:34,backgroundColor:"rgba(255, 0, 0, 0.15)",children:(0,e.createComponentVNode)(2,i,{grow:!0,i:L})},w)})})})})},i=function(h,C){var p=h.i,N=h.showDecription,V=N===void 0?1:N,S=h.buttons,B=S===void 0?(0,e.createComponentVNode)(2,u,{i:p}):S;return(0,e.createComponentVNode)(2,b.Section,{title:(0,o.decodeHtmlEntities)(p.name),showBottom:V,buttons:B,children:V?(0,e.createComponentVNode)(2,b.Box,{italic:!0,children:(0,o.decodeHtmlEntities)(p.desc)}):null})},u=function(h,C){var p=(0,f.useBackend)(C),N=p.act,V=p.data,S=h.i,B=V.crystals;return(0,e.createFragment)([(0,e.createComponentVNode)(2,b.Button,{icon:"shopping-cart",color:S.hijack_only===1&&"red",tooltip:"Add to cart.",tooltipPosition:"left",onClick:function(){function L(){return N("add_to_cart",{item:S.obj_path})}return L}(),disabled:S.cost>B}),(0,e.createComponentVNode)(2,b.Button,{content:"Buy ("+S.cost+"TC)"+(S.refundable?" [Refundable]":""),color:S.hijack_only===1&&"red",tooltip:S.hijack_only===1&&"Hijack Agents Only!",tooltipPosition:"left",onClick:function(){function L(){return N("buyItem",{item:S.obj_path})}return L}(),disabled:S.cost>B})],4)},s=function(h,C){var p=(0,f.useBackend)(C),N=p.act,V=p.data,S=h.i,B=V.exploitable;return(0,e.createComponentVNode)(2,b.Stack,{children:[(0,e.createComponentVNode)(2,b.Button,{icon:"times",content:"("+S.cost*S.amount+"TC)",tooltip:"Remove from cart.",tooltipPosition:"left",onClick:function(){function L(){return N("remove_from_cart",{item:S.obj_path})}return L}()}),(0,e.createComponentVNode)(2,b.Button,{icon:"minus",tooltip:S.limit===0&&"Discount already redeemed!",ml:"5px",onClick:function(){function L(){return N("set_cart_item_quantity",{item:S.obj_path,quantity:--S.amount})}return L}(),disabled:S.amount<=0}),(0,e.createComponentVNode)(2,b.Button.Input,{content:S.amount,width:"45px",tooltipPosition:"bottom-end",tooltip:S.limit===0&&"Discount already redeemed!",onCommit:function(){function L(w,A){return N("set_cart_item_quantity",{item:S.obj_path,quantity:A})}return L}(),disabled:S.limit!==-1&&S.amount>=S.limit&&S.amount<=0}),(0,e.createComponentVNode)(2,b.Button,{mb:.3,icon:"plus",tooltipPosition:"bottom-start",tooltip:S.limit===0&&"Discount already redeemed!",onClick:function(){function L(){return N("set_cart_item_quantity",{item:S.obj_path,quantity:++S.amount})}return L}(),disabled:S.limit!==-1&&S.amount>=S.limit})]})},d=function(h,C){var p=(0,f.useBackend)(C),N=p.act,V=p.data,S=V.exploitable,B=(0,f.useLocalState)(C,"selectedRecord",S[0]),L=B[0],w=B[1],A=(0,f.useLocalState)(C,"searchText",""),x=A[0],E=A[1],P=function(R,O){O===void 0&&(O="");var F=(0,o.createSearch)(O,function(_){return _.name});return(0,t.flow)([(0,a.filter)(function(_){return _==null?void 0:_.name}),O&&(0,a.filter)(F),(0,a.sortBy)(function(_){return _.name})])(R)},D=P(S,x);return(0,e.createComponentVNode)(2,b.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{width:"30%",children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Exploitable Records",children:[(0,e.createComponentVNode)(2,b.Input,{fluid:!0,mb:1,placeholder:"Search Crew",onInput:function(){function M(R,O){return E(O)}return M}()}),(0,e.createComponentVNode)(2,b.Tabs,{vertical:!0,children:D.map(function(M){return(0,e.createComponentVNode)(2,b.Tabs.Tab,{selected:M===L,onClick:function(){function R(){return w(M)}return R}(),children:M.name},M)})})]})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:L.name,children:(0,e.createComponentVNode)(2,b.LabeledList,{children:[(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Age",children:L.age}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Fingerprint",children:L.fingerprint}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Rank",children:L.rank}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Sex",children:L.sex}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Species",children:L.species})]})})})]})}},12261:function(T,r,n){"use strict";r.__esModule=!0,r.Vending=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=function(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=I.product,i=I.productStock,u=I.productIcon,s=I.productIconState,d=c.chargesMoney,v=c.user,h=c.usermoney,C=c.inserted_cash,p=c.vend_ready,N=c.inserted_item_name,V=!d||m.price===0,S="ERROR!",B="";V?(S="FREE",B="arrow-circle-down"):(S=m.price,B="shopping-cart");var L=!p||i===0||!V&&m.price>h&&m.price>C;return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,children:(0,e.createComponentVNode)(2,t.DmIcon,{verticalAlign:"middle",icon:u,icon_state:s,fallback:(0,e.createComponentVNode)(2,t.Icon,{p:.66,name:"spinner",size:2,spin:!0})})}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:m.name}),(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Box,{color:i<=0&&"bad"||i<=m.max_amount/2&&"average"||"good",children:[i," in stock"]})}),(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,disabled:L,icon:B,content:S,textAlign:"left",onClick:function(){function w(){return l("vend",{inum:m.inum})}return w}()})})]})},b=r.Vending=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=c.user,i=c.usermoney,u=c.inserted_cash,s=c.chargesMoney,d=c.product_records,v=d===void 0?[]:d,h=c.hidden_records,C=h===void 0?[]:h,p=c.stock,N=c.vend_ready,V=c.inserted_item_name,S=c.panel_open,B=c.speaker,L=c.locked,w;return w=[].concat(v),c.extended_inventory&&(w=[].concat(w,C)),w=w.filter(function(A){return!!A}),(0,e.createComponentVNode)(2,o.Window,{title:"Vending Machine",width:450,height:Math.min((s?171:89)+w.length*32,585),children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[!L&&(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Configuration",children:(0,e.createComponentVNode)(2,t.Stack,{horizontal:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"pen-to-square",content:"Rename Vendor",onClick:function(){function A(){return l("rename",{})}return A}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"pen-to-square",content:"Change Vendor Appearance",onClick:function(){function A(){return l("change_appearance",{})}return A}()})})]})})}),!!s&&(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"User",buttons:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:!!V&&(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"eject",content:(0,e.createVNode)(1,"span",null,V,0,{style:{"text-transform":"capitalize"}}),onClick:function(){function A(){return l("eject_item",{})}return A}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{disabled:!u,icon:"money-bill-wave-alt",content:u?(0,e.createFragment)([(0,e.createVNode)(1,"b",null,u,0),(0,e.createTextVNode)(" credits")],0):"Dispense Change",tooltip:u?"Dispense Change":null,textAlign:"left",onClick:function(){function A(){return l("change")}return A}()})})]}),children:m&&(0,e.createComponentVNode)(2,t.Box,{children:["Welcome, ",(0,e.createVNode)(1,"b",null,m.name,0),", ",(0,e.createVNode)(1,"b",null,m.job||"Unemployed",0),"!",(0,e.createVNode)(1,"br"),"Your balance is ",(0,e.createVNode)(1,"b",null,[i,(0,e.createTextVNode)(" credits")],0),".",(0,e.createVNode)(1,"br")]})})}),!!S&&(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Maintenance",children:(0,e.createComponentVNode)(2,t.Button,{icon:B?"check":"volume-mute",selected:B,content:"Speaker",textAlign:"left",onClick:function(){function A(){return l("toggle_voice",{})}return A}()})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Products",children:(0,e.createComponentVNode)(2,t.Table,{children:w.map(function(A){return(0,e.createComponentVNode)(2,f,{product:A,productStock:p[A.name],productIcon:A.icon,productIconState:A.icon_state},A.name)})})})})]})})})}return y}()},68971:function(T,r,n){"use strict";r.__esModule=!0,r.VolumeMixer=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.VolumeMixer=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.channels;return(0,e.createComponentVNode)(2,o.Window,{width:350,height:Math.min(95+c.length*50,565),children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,children:c.map(function(m,i){return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.25rem",color:"label",mt:i>0&&"0.5rem",children:m.name}),(0,e.createComponentVNode)(2,t.Box,{mt:"0.5rem",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{mr:.5,children:(0,e.createComponentVNode)(2,t.Button,{width:"24px",color:"transparent",children:(0,e.createComponentVNode)(2,t.Icon,{name:"volume-off",size:"1.5",mt:"0.1rem",onClick:function(){function u(){return g("volume",{channel:m.num,volume:0})}return u}()})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,mx:"0.5rem",children:(0,e.createComponentVNode)(2,t.Slider,{minValue:0,maxValue:100,stepPixelSize:3.13,value:m.volume,onChange:function(){function u(s,d){return g("volume",{channel:m.num,volume:d})}return u}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{width:"24px",color:"transparent",children:(0,e.createComponentVNode)(2,t.Icon,{name:"volume-up",size:"1.5",mt:"0.1rem",onClick:function(){function u(){return g("volume",{channel:m.num,volume:100})}return u}()})})})]})})],4,m.num)})})})})}return b}()},2510:function(T,r,n){"use strict";r.__esModule=!0,r.VotePanel=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.VotePanel=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.remaining,m=l.question,i=l.choices,u=l.user_vote,s=l.counts,d=l.show_counts;return(0,e.createComponentVNode)(2,o.Window,{width:400,height:360,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:m,children:[(0,e.createComponentVNode)(2,t.Box,{mb:1.5,ml:.5,children:["Time remaining: ",Math.round(c/10),"s"]}),i.map(function(v){return(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{mb:1,fluid:!0,translucent:!0,lineHeight:3,multiLine:v,content:v+(d?" ("+(s[v]||0)+")":""),onClick:function(){function h(){return g("vote",{target:v})}return h}(),selected:v===u})},v)})]})})})}return b}()},30138:function(T,r,n){"use strict";r.__esModule=!0,r.Wires=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.Wires=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.wires||[],m=l.status||[],i=56+c.length*23+(status?0:15+m.length*17);return(0,e.createComponentVNode)(2,o.Window,{width:350,height:i,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:c.map(function(u){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{className:"candystripe",label:u.color_name,labelColor:u.seen_color,color:u.seen_color,buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:u.cut?"Mend":"Cut",onClick:function(){function s(){return g("cut",{wire:u.color})}return s}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Pulse",onClick:function(){function s(){return g("pulse",{wire:u.color})}return s}()}),(0,e.createComponentVNode)(2,t.Button,{content:u.attached?"Detach":"Attach",onClick:function(){function s(){return g("attach",{wire:u.color})}return s}()})],4),children:!!u.wire&&(0,e.createVNode)(1,"i",null,[(0,e.createTextVNode)("("),u.wire,(0,e.createTextVNode)(")")],0)},u.seen_color)})})})}),!!m.length&&(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{children:m.map(function(u){return(0,e.createComponentVNode)(2,t.Box,{color:"lightgray",children:u},u)})})})]})})})}return b}()},21400:function(T,r,n){"use strict";r.__esModule=!0,r.WizardApprenticeContract=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),f=r.WizardApprenticeContract=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.used;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:555,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Contract of Apprenticeship",children:["Using this contract, you may summon an apprentice to aid you on your mission.",(0,e.createVNode)(1,"p",null,"If you are unable to establish contact with your apprentice, you can feed the contract back to the spellbook to refund your points.",16),c?(0,e.createComponentVNode)(2,t.Box,{bold:!0,color:"red",children:"You've already summoned an apprentice or you are in process of summoning one."}):""]}),(0,e.createComponentVNode)(2,t.Section,{title:"Which school of magic is your apprentice studying?",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Fire",children:["Your apprentice is skilled in bending fire. ",(0,e.createVNode)(1,"br"),"They know Fireball, Sacred Flame, and Ethereal Jaunt.",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{content:"Select",disabled:c,onClick:function(){function m(){return g("fire")}return m}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Translocation",children:["Your apprentice is able to defy physics, learning how to move through bluespace. ",(0,e.createVNode)(1,"br"),"They know Teleport, Blink and Ethereal Jaunt.",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{content:"Select",disabled:c,onClick:function(){function m(){return g("translocation")}return m}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Restoration",children:["Your apprentice is dedicated to supporting your magical prowess.",(0,e.createVNode)(1,"br"),"They come equipped with a Staff of Healing, have the unique ability to teleport back to you, and know Charge and Knock.",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{content:"Select",disabled:c,onClick:function(){function m(){return g("restoration")}return m}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Stealth",children:["Your apprentice is learning the art of infiltrating mundane facilities. ",(0,e.createVNode)(1,"br"),"They know Mindswap, Knock, Homing Toolbox, and Disguise Self, all of which can be cast without robes. They also join you in a Maintenance Dweller disguise, complete with Gloves of Shock Immunity and a Belt of Tools.",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{content:"Select",disabled:c,onClick:function(){function m(){return g("stealth")}return m}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Honk",children:["Your apprentice is here to spread the Honkmother's blessings.",(0,e.createVNode)(1,"br"),"They know Banana Touch, Instant Summons, Ethereal Jaunt, and come equipped with a Staff of Slipping."," ",(0,e.createVNode)(1,"br"),"While under your tutelage, they have been 'blessed' with clown shoes that are impossible to remove.",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{content:"Select",disabled:c,onClick:function(){function m(){return g("honk")}return m}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider)]})})]})})}return b}()},49148:function(T,r,n){"use strict";r.__esModule=!0,r.AccessList=void 0;var e=n(89005),a=n(88510),t=n(72253),o=n(36036);function f(g,l){var c=typeof Symbol!="undefined"&&g[Symbol.iterator]||g["@@iterator"];if(c)return(c=c.call(g)).next.bind(c);if(Array.isArray(g)||(c=b(g))||l&&g&&typeof g.length=="number"){c&&(g=c);var m=0;return function(){return m>=g.length?{done:!0}:{done:!1,value:g[m++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function b(g,l){if(g){if(typeof g=="string")return y(g,l);var c={}.toString.call(g).slice(8,-1);return c==="Object"&&g.constructor&&(c=g.constructor.name),c==="Map"||c==="Set"?Array.from(g):c==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c)?y(g,l):void 0}}function y(g,l){(l==null||l>g.length)&&(l=g.length);for(var c=0,m=Array(l);c0&&!V.includes(O.ref)&&!p.includes(O.ref),checked:p.includes(O.ref),onClick:function(){function F(){return S(O.ref)}return F}()},O.desc)})]})]})})}return g}()},26991:function(T,r,n){"use strict";r.__esModule=!0,r.AtmosScan=void 0;var e=n(89005),a=n(88510),t=n(72253),o=n(36036),f=function(I,k,g,l,c){return Il?"average":I>c?"bad":"good"},b=r.AtmosScan=function(){function y(I,k){var g=I.data.aircontents;return(0,e.createComponentVNode)(2,o.Box,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,a.filter)(function(l){return l.val!=="0"||l.entry==="Pressure"||l.entry==="Temperature"})(g).map(function(l){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:l.entry,color:f(l.val,l.bad_low,l.poor_low,l.poor_high,l.bad_high),children:[l.val,l.units]},l.entry)})})})}return y}()},85870:function(T,r,n){"use strict";r.__esModule=!0,r.BeakerContents=void 0;var e=n(89005),a=n(36036),t=n(15964),o=function(y){return y+" unit"+(y===1?"":"s")},f=r.BeakerContents=function(){function b(y){var I=y.beakerLoaded,k=y.beakerContents,g=k===void 0?[]:k,l=y.buttons;return(0,e.createComponentVNode)(2,a.Stack,{vertical:!0,children:[!I&&(0,e.createComponentVNode)(2,a.Stack.Item,{color:"label",children:"No beaker loaded."})||g.length===0&&(0,e.createComponentVNode)(2,a.Stack.Item,{color:"label",children:"Beaker is empty."}),g.map(function(c,m){return(0,e.createComponentVNode)(2,a.Stack,{children:[(0,e.createComponentVNode)(2,a.Stack.Item,{color:"label",grow:!0,children:[o(c.volume)," of ",c.name]},c.name),!!l&&(0,e.createComponentVNode)(2,a.Stack.Item,{children:l(c,m)})]},c.name)})]})}return b}();f.propTypes={beakerLoaded:t.bool,beakerContents:t.array,buttons:t.arrayOf(t.element)}},92963:function(T,r,n){"use strict";r.__esModule=!0,r.BotStatus=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.BotStatus=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.act,g=I.data,l=g.locked,c=g.noaccess,m=g.maintpanel,i=g.on,u=g.autopatrol,s=g.canhack,d=g.emagged,v=g.remote_disabled;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.NoticeBox,{children:["Swipe an ID card to ",l?"unlock":"lock"," this interface."]}),(0,e.createComponentVNode)(2,t.Section,{title:"General Settings",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:(0,e.createComponentVNode)(2,t.Button,{icon:i?"power-off":"times",content:i?"On":"Off",selected:i,disabled:c,onClick:function(){function h(){return k("power")}return h}()})}),u!==null&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Patrol",children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:u,content:"Auto Patrol",disabled:c,onClick:function(){function h(){return k("autopatrol")}return h}()})}),!!m&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Maintenance Panel",children:(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:"Panel Open!"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Safety System",children:(0,e.createComponentVNode)(2,t.Box,{color:d?"bad":"good",children:d?"DISABLED!":"Enabled"})}),!!s&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Hacking",children:(0,e.createComponentVNode)(2,t.Button,{icon:"terminal",content:d?"Restore Safties":"Hack",disabled:c,color:"bad",onClick:function(){function h(){return k("hack")}return h}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Remote Access",children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:!v,content:"AI Remote Control",disabled:c,onClick:function(){function h(){return k("disableremote")}return h}()})})]})})],4)}return f}()},3939:function(T,r,n){"use strict";r.__esModule=!0,r.modalRegisterBodyOverride=r.modalOpen=r.modalClose=r.modalAnswer=r.ComplexModal=void 0;var e=n(89005),a=n(72253),t=n(36036),o={},f=r.modalOpen=function(){function g(l,c,m){var i=(0,a.useBackend)(l),u=i.act,s=i.data,d=Object.assign(s.modal?s.modal.args:{},m||{});u("modal_open",{id:c,arguments:JSON.stringify(d)})}return g}(),b=r.modalRegisterBodyOverride=function(){function g(l,c){o[l]=c}return g}(),y=r.modalAnswer=function(){function g(l,c,m,i){var u=(0,a.useBackend)(l),s=u.act,d=u.data;if(d.modal){var v=Object.assign(d.modal.args||{},i||{});s("modal_answer",{id:c,answer:m,arguments:JSON.stringify(v)})}}return g}(),I=r.modalClose=function(){function g(l,c){var m=(0,a.useBackend)(l),i=m.act;i("modal_close",{id:c})}return g}(),k=r.ComplexModal=function(){function g(l,c){var m=(0,a.useBackend)(c),i=m.data;if(i.modal){var u=i.modal,s=u.id,d=u.text,v=u.type,h,C=(0,e.createComponentVNode)(2,t.Button,{className:"Button--modal",icon:"arrow-left",content:"Cancel",onClick:function(){function L(){return I(c)}return L}()}),p,N,V="auto";if(o[s])p=o[s](i.modal,c);else if(v==="input"){var S=i.modal.value;h=function(){function L(w){return y(c,s,S)}return L}(),p=(0,e.createComponentVNode)(2,t.Input,{value:i.modal.value,placeholder:"ENTER to submit",width:"100%",my:"0.5rem",autofocus:!0,onChange:function(){function L(w,A){S=A}return L}()}),N=(0,e.createComponentVNode)(2,t.Box,{mt:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-left",content:"Cancel",color:"grey",onClick:function(){function L(){return I(c)}return L}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"check",content:"Confirm",color:"good",float:"right",m:"0",onClick:function(){function L(){return y(c,s,S)}return L}()}),(0,e.createComponentVNode)(2,t.Box,{clear:"both"})]})}else if(v==="choice"){var B=typeof i.modal.choices=="object"?Object.values(i.modal.choices):i.modal.choices;p=(0,e.createComponentVNode)(2,t.Dropdown,{options:B,selected:i.modal.value,width:"100%",my:"0.5rem",onSelected:function(){function L(w){return y(c,s,w)}return L}()}),V="initial"}else v==="bento"?p=(0,e.createComponentVNode)(2,t.Stack,{spacingPrecise:"1",wrap:"wrap",my:"0.5rem",maxHeight:"1%",children:i.modal.choices.map(function(L,w){return(0,e.createComponentVNode)(2,t.Stack.Item,{flex:"1 1 auto",children:(0,e.createComponentVNode)(2,t.Button,{selected:w+1===parseInt(i.modal.value,10),onClick:function(){function A(){return y(c,s,w+1)}return A}(),children:(0,e.createVNode)(1,"img",null,null,1,{src:L})})},w)})}):v==="boolean"&&(N=(0,e.createComponentVNode)(2,t.Box,{mt:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"times",content:i.modal.no_text,color:"bad",float:"left",mb:"0",onClick:function(){function L(){return y(c,s,0)}return L}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"check",content:i.modal.yes_text,color:"good",float:"right",m:"0",onClick:function(){function L(){return y(c,s,1)}return L}()}),(0,e.createComponentVNode)(2,t.Box,{clear:"both"})]}));return(0,e.createComponentVNode)(2,t.Modal,{maxWidth:l.maxWidth||window.innerWidth/2+"px",maxHeight:l.maxHeight||window.innerHeight/2+"px",onEnter:h,mx:"auto",overflowY:V,"padding-bottom":"5px",children:[d&&(0,e.createComponentVNode)(2,t.Box,{inline:!0,children:d}),o[s]&&C,p,N]})}}return g}()},41874:function(T,r,n){"use strict";r.__esModule=!0,r.CrewManifest=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(25328),f=n(76910),b=f.COLORS.department,y=["Captain","Head of Security","Chief Engineer","Chief Medical Officer","Research Director","Head of Personnel","Quartermaster"],I=function(m){return y.indexOf(m)!==-1?"green":"orange"},k=function(m){if(y.indexOf(m)!==-1)return!0},g=function(m){return m.length>0&&(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,color:"white",children:[(0,e.createComponentVNode)(2,t.Table.Cell,{width:"50%",children:"Name"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"35%",children:"Rank"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"15%",children:"Active"})]}),m.map(function(i){return(0,e.createComponentVNode)(2,t.Table.Row,{color:I(i.rank),bold:k(i.rank),children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,o.decodeHtmlEntities)(i.name)}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,o.decodeHtmlEntities)(i.rank)}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:i.active})]},i.name+i.rank)})]})},l=r.CrewManifest=function(){function c(m,i){var u=(0,a.useBackend)(i),s=u.act,d;if(m.data)d=m.data;else{var v=(0,a.useBackend)(i),h=v.data;d=h}var C=d,p=C.manifest,N=p.heads,V=p.sec,S=p.eng,B=p.med,L=p.sci,w=p.ser,A=p.sup,x=p.misc;return(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.command,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Command"})}),level:2,children:g(N)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.security,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Security"})}),level:2,children:g(V)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.engineering,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Engineering"})}),level:2,children:g(S)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.medical,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Medical"})}),level:2,children:g(B)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.science,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Science"})}),level:2,children:g(L)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.service,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Service"})}),level:2,children:g(w)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.supply,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Supply"})}),level:2,children:g(A)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Misc"})}),level:2,children:g(x)})]})}return c}()},19203:function(T,r,n){"use strict";r.__esModule=!0,r.InputButtons=void 0;var e=n(89005),a=n(36036),t=n(72253),o=r.InputButtons=function(){function f(b,y){var I=(0,t.useBackend)(y),k=I.act,g=I.data,l=g.large_buttons,c=g.swapped_buttons,m=b.input,i=b.message,u=b.disabled,s=(0,e.createComponentVNode)(2,a.Button,{color:"good",content:"Submit",bold:!!l,fluid:!!l,onClick:function(){function v(){return k("submit",{entry:m})}return v}(),textAlign:"center",tooltip:l&&i,disabled:u,width:!l&&6}),d=(0,e.createComponentVNode)(2,a.Button,{color:"bad",content:"Cancel",bold:!!l,fluid:!!l,onClick:function(){function v(){return k("cancel")}return v}(),textAlign:"center",width:!l&&6});return(0,e.createComponentVNode)(2,a.Flex,{fill:!0,align:"center",direction:c?"row-reverse":"row",justify:"space-around",children:[l?(0,e.createComponentVNode)(2,a.Flex.Item,{grow:!0,ml:c?.5:0,mr:c?0:.5,children:d}):(0,e.createComponentVNode)(2,a.Flex.Item,{children:d}),!l&&i&&(0,e.createComponentVNode)(2,a.Flex.Item,{children:(0,e.createComponentVNode)(2,a.Box,{color:"label",textAlign:"center",children:i})}),l?(0,e.createComponentVNode)(2,a.Flex.Item,{grow:!0,mr:c?.5:0,ml:c?0:.5,children:s}):(0,e.createComponentVNode)(2,a.Flex.Item,{children:s})]})}return f}()},195:function(T,r,n){"use strict";r.__esModule=!0,r.InterfaceLockNoticeBox=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.InterfaceLockNoticeBox=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.act,g=I.data,l=b.siliconUser,c=l===void 0?g.siliconUser:l,m=b.locked,i=m===void 0?g.locked:m,u=b.normallyLocked,s=u===void 0?g.normallyLocked:u,d=b.onLockStatusChange,v=d===void 0?function(){return k("lock")}:d,h=b.accessText,C=h===void 0?"an ID card":h;return c?(0,e.createComponentVNode)(2,t.NoticeBox,{color:c&&"grey",children:(0,e.createComponentVNode)(2,t.Flex,{align:"center",children:[(0,e.createComponentVNode)(2,t.Flex.Item,{children:"Interface lock status:"}),(0,e.createComponentVNode)(2,t.Flex.Item,{grow:"1"}),(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,t.Button,{m:"0",color:s?"red":"green",icon:s?"lock":"unlock",content:s?"Locked":"Unlocked",onClick:function(){function p(){v&&v(!i)}return p}()})})]})}):(0,e.createComponentVNode)(2,t.NoticeBox,{children:["Swipe ",C," to ",i?"unlock":"lock"," this interface."]})}return f}()},51057:function(T,r,n){"use strict";r.__esModule=!0,r.Loader=void 0;var e=n(89005),a=n(44879),t=n(36036),o=r.Loader=function(){function f(b){var y=b.value;return(0,e.createVNode)(1,"div","AlertModal__Loader",(0,e.createComponentVNode)(2,t.Box,{className:"AlertModal__LoaderProgress",style:{width:(0,a.clamp01)(y)*100+"%"}}),2)}return f}()},321:function(T,r,n){"use strict";r.__esModule=!0,r.LoginInfo=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.LoginInfo=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.act,g=I.data,l=g.loginState;if(g)return(0,e.createComponentVNode)(2,t.NoticeBox,{info:!0,children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,mt:.5,children:["Logged in as: ",l.name," (",l.rank,")"]}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"eject",disabled:!l.id,content:"Eject ID",color:"good",onClick:function(){function c(){return k("login_eject")}return c}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"sign-out-alt",content:"Logout",color:"good",onClick:function(){function c(){return k("login_logout")}return c}()})]})]})})}return f}()},5485:function(T,r,n){"use strict";r.__esModule=!0,r.LoginScreen=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.LoginScreen=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.act,g=I.data,l=g.loginState,c=g.isAI,m=g.isRobot,i=g.isAdmin;return(0,e.createComponentVNode)(2,t.Section,{title:"Welcome",fill:!0,stretchContents:!0,children:(0,e.createComponentVNode)(2,t.Flex,{height:"100%",align:"center",justify:"center",children:(0,e.createComponentVNode)(2,t.Flex.Item,{textAlign:"center",mt:"-2rem",children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.5rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-circle",verticalAlign:"middle",size:3,mr:"1rem"}),"Guest"]}),(0,e.createComponentVNode)(2,t.Box,{color:"label",my:"1rem",children:["ID:",(0,e.createComponentVNode)(2,t.Button,{icon:"id-card",content:l.id?l.id:"----------",ml:"0.5rem",onClick:function(){function u(){return k("login_insert")}return u}()})]}),(0,e.createComponentVNode)(2,t.Button,{icon:"sign-in-alt",disabled:!l.id,content:"Login",onClick:function(){function u(){return k("login_login",{login_type:1})}return u}()}),!!c&&(0,e.createComponentVNode)(2,t.Button,{icon:"sign-in-alt",content:"Login as AI",onClick:function(){function u(){return k("login_login",{login_type:2})}return u}()}),!!m&&(0,e.createComponentVNode)(2,t.Button,{icon:"sign-in-alt",content:"Login as Cyborg",onClick:function(){function u(){return k("login_login",{login_type:3})}return u}()}),!!i&&(0,e.createComponentVNode)(2,t.Button,{icon:"sign-in-alt",content:"CentComm Secure Login",onClick:function(){function u(){return k("login_login",{login_type:4})}return u}()})]})})})}return f}()},62411:function(T,r,n){"use strict";r.__esModule=!0,r.Operating=void 0;var e=n(89005),a=n(36036),t=n(15964),o=r.Operating=function(){function f(b){var y=b.operating,I=b.name;if(y)return(0,e.createComponentVNode)(2,a.Dimmer,{children:(0,e.createComponentVNode)(2,a.Flex,{mb:"30px",children:(0,e.createComponentVNode)(2,a.Flex.Item,{bold:!0,color:"silver",textAlign:"center",children:[(0,e.createComponentVNode)(2,a.Icon,{name:"spinner",spin:!0,size:4,mb:"15px"}),(0,e.createVNode)(1,"br"),"The ",I," is processing..."]})})})}return f}();o.propTypes={operating:t.bool,name:t.string}},13545:function(T,r,n){"use strict";r.__esModule=!0,r.Signaler=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),f=r.Signaler=function(){function b(y,I){var k=(0,t.useBackend)(I),g=k.act,l=y.data,c=l.code,m=l.frequency,i=l.minFrequency,u=l.maxFrequency;return(0,e.createComponentVNode)(2,o.Section,{children:[(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Frequency",children:(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,step:.2,stepPixelSize:6,minValue:i/10,maxValue:u/10,value:m/10,format:function(){function s(d){return(0,a.toFixed)(d,1)}return s}(),width:"80px",onDrag:function(){function s(d,v){return g("freq",{freq:v})}return s}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Code",children:(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,step:1,stepPixelSize:6,minValue:1,maxValue:100,value:c,width:"80px",onDrag:function(){function s(d,v){return g("code",{code:v})}return s}()})})]}),(0,e.createComponentVNode)(2,o.Button,{mt:1,fluid:!0,icon:"arrow-up",content:"Send Signal",textAlign:"center",onClick:function(){function s(){return g("signal")}return s}()})]})}return b}()},41984:function(T,r,n){"use strict";r.__esModule=!0,r.SimpleRecords=void 0;var e=n(89005),a=n(72253),t=n(25328),o=n(64795),f=n(88510),b=n(36036),y=r.SimpleRecords=function(){function g(l,c){var m=l.data.records;return(0,e.createComponentVNode)(2,b.Box,{children:m?(0,e.createComponentVNode)(2,k,{data:l.data,recordType:l.recordType}):(0,e.createComponentVNode)(2,I,{data:l.data})})}return g}(),I=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=l.data.recordsList,s=(0,a.useLocalState)(c,"searchText",""),d=s[0],v=s[1],h=function(N,V){V===void 0&&(V="");var S=(0,t.createSearch)(V,function(B){return B.Name});return(0,o.flow)([(0,f.filter)(function(B){return B==null?void 0:B.Name}),V&&(0,f.filter)(S),(0,f.sortBy)(function(B){return B.Name})])(u)},C=h(u,d);return(0,e.createComponentVNode)(2,b.Box,{children:[(0,e.createComponentVNode)(2,b.Input,{fluid:!0,mb:1,placeholder:"Search records...",onInput:function(){function p(N,V){return v(V)}return p}()}),C.map(function(p){return(0,e.createComponentVNode)(2,b.Box,{children:(0,e.createComponentVNode)(2,b.Button,{mb:.5,content:p.Name,icon:"user",onClick:function(){function N(){return i("Records",{target:p.uid})}return N}()})},p)})]})},k=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=l.data.records,s=u.general,d=u.medical,v=u.security,h;switch(l.recordType){case"MED":h=(0,e.createComponentVNode)(2,b.Section,{level:2,title:"Medical Data",children:d?(0,e.createComponentVNode)(2,b.LabeledList,{children:[(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Blood Type",children:d.blood_type}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Minor Disabilities",children:d.mi_dis}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Details",children:d.mi_dis_d}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Major Disabilities",children:d.ma_dis}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Details",children:d.ma_dis_d}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Allergies",children:d.alg}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Details",children:d.alg_d}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Current Diseases",children:d.cdi}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Details",children:d.cdi_d}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Important Notes",preserveWhitespace:!0,children:d.notes})]}):(0,e.createComponentVNode)(2,b.Box,{color:"red",bold:!0,children:"Medical record lost!"})});break;case"SEC":h=(0,e.createComponentVNode)(2,b.Section,{level:2,title:"Security Data",children:v?(0,e.createComponentVNode)(2,b.LabeledList,{children:[(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Criminal Status",children:v.criminal}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Minor Crimes",children:v.mi_crim}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Details",children:v.mi_crim_d}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Major Crimes",children:v.ma_crim}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Details",children:v.ma_crim_d}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Important Notes",preserveWhitespace:!0,children:v.notes})]}):(0,e.createComponentVNode)(2,b.Box,{color:"red",bold:!0,children:"Security record lost!"})});break}return(0,e.createComponentVNode)(2,b.Box,{children:[(0,e.createComponentVNode)(2,b.Section,{title:"General Data",children:s?(0,e.createComponentVNode)(2,b.LabeledList,{children:[(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Name",children:s.name}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Sex",children:s.sex}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Species",children:s.species}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Age",children:s.age}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Rank",children:s.rank}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Fingerprint",children:s.fingerprint}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Physical Status",children:s.p_stat}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Mental Status",children:s.m_stat})]}):(0,e.createComponentVNode)(2,b.Box,{color:"red",bold:!0,children:"General record lost!"})}),h]})}},22091:function(T,r,n){"use strict";r.__esModule=!0,r.TemporaryNotice=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.TemporaryNotice=function(){function f(b,y){var I,k=(0,a.useBackend)(y),g=k.act,l=k.data,c=l.temp;if(c){var m=(I={},I[c.style]=!0,I);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.NoticeBox,Object.assign({},m,{children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,mt:.5,children:c.text}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"times-circle",onClick:function(){function i(){return g("cleartemp")}return i}()})})]})})))}}return f}()},95213:function(T,r,n){"use strict";r.__esModule=!0,r.goonstation_PTL=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(49968),f=n(98595);/** +======= + */var a=["f","p","n","\u03BC","m"," ","k","M","G","T","P","E","Z","Y"],t=a.indexOf(" "),o=r.formatSiUnit=function(){function S(k,h,i){if(h===void 0&&(h=-t),i===void 0&&(i=""),typeof k!="number"||!Number.isFinite(k))return k;var c=Math.floor(Math.log10(k)),m=Math.floor(Math.max(h*3,c)),l=Math.floor(c/3),u=Math.floor(m/3),s=(0,e.clamp)(t+u,0,a.length),d=a[s],v=k/Math.pow(1e3,u),g=l>h?2+u*3-m:0,C=(0,e.toFixed)(v,g)+" "+d+i;return C.trim()}return S}(),p=r.formatPower=function(){function S(k,h){return h===void 0&&(h=0),o(k,h,"W")}return S}(),b=r.formatMoney=function(){function S(k,h){if(h===void 0&&(h=0),!Number.isFinite(k))return k;var i=(0,e.round)(k,h);h>0&&(i=(0,e.toFixed)(k,h)),i=String(i);var c=i.length,m=i.indexOf(".");m===-1&&(m=c);for(var l="",u=0;u0&&u=0?"+":h<0?"\u2013":"",c=Math.abs(h);return c===1/0?c="Inf":c=(0,e.toFixed)(c,2),i+c+" dB"}return S}()},56518:function(T,r,n){"use strict";r.__esModule=!0,r.setupHotKeys=r.releaseHotKey=r.releaseHeldKeys=r.acquireHotKey=void 0;var e=p(n(92986)),a=n(24826),t=n(9394);function o(s){if(typeof WeakMap!="function")return null;var d=new WeakMap,v=new WeakMap;return(o=function(C){return C?v:d})(s)}function p(s,d){if(!d&&s&&s.__esModule)return s;if(s===null||typeof s!="object"&&typeof s!="function")return{default:s};var v=o(d);if(v&&v.has(s))return v.get(s);var g={__proto__:null},C=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var f in s)if(f!=="default"&&{}.hasOwnProperty.call(s,f)){var N=C?Object.getOwnPropertyDescriptor(s,f):null;N&&(N.get||N.set)?Object.defineProperty(g,f,N):g[f]=s[f]}return g.default=s,v&&v.set(s,g),g}/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */var b=(0,t.createLogger)("hotkeys"),y={},S=[e.KEY_ESCAPE,e.KEY_ENTER,e.KEY_SPACE,e.KEY_TAB,e.KEY_CTRL,e.KEY_SHIFT,e.KEY_UP,e.KEY_DOWN,e.KEY_LEFT,e.KEY_RIGHT],k={},h=function(d){if(d===16)return"Shift";if(d===17)return"Ctrl";if(d===18)return"Alt";if(d===33)return"Northeast";if(d===34)return"Southeast";if(d===35)return"Southwest";if(d===36)return"Northwest";if(d===37)return"West";if(d===38)return"North";if(d===39)return"East";if(d===40)return"South";if(d===45)return"Insert";if(d===46)return"Delete";if(d>=48&&d<=57||d>=65&&d<=90)return String.fromCharCode(d);if(d>=96&&d<=105)return"Numpad"+(d-96);if(d>=112&&d<=123)return"F"+(d-111);if(d===188)return",";if(d===189)return"-";if(d===190)return"."},i=function(d){var v=String(d);if(v==="Ctrl+F5"||v==="Ctrl+R"){location.reload();return}if(v!=="Ctrl+F"&&!(d.event.defaultPrevented||d.isModifierKey()||S.includes(d.code))){v==="F5"&&(d.event.preventDefault(),d.event.returnValue=!1);var g=h(d.code);if(g){var C=y[g];if(C)return b.debug("macro",C),Byond.command(C);if(d.isDown()&&!k[g]){k[g]=!0;var f='Key_Down "'+g+'"';return b.debug(f),Byond.command(f)}if(d.isUp()&&k[g]){k[g]=!1;var N='Key_Up "'+g+'"';return b.debug(N),Byond.command(N)}}}},c=r.acquireHotKey=function(){function s(d){S.push(d)}return s}(),m=r.releaseHotKey=function(){function s(d){var v=S.indexOf(d);v>=0&&S.splice(v,1)}return s}(),l=r.releaseHeldKeys=function(){function s(){for(var d=0,v=Object.keys(k);d0||(0,a.fetchRetry)((0,e.resolveAsset)("icon_ref_map.json")).then(function(b){return b.json()}).then(function(b){return Byond.iconRefMap=b}).catch(function(b){return t.logger.log(b)})}return p}()},1090:function(T,r,n){"use strict";r.__esModule=!0,r.AICard=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.AICard=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data;if(i.has_ai===0)return(0,e.createComponentVNode)(2,o.Window,{width:250,height:120,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Stored AI",children:(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createVNode)(1,"h3",null,"No AI detected.",16)})})})});var c=null;return i.integrity>=75?c="green":i.integrity>=25?c="yellow":c="red",(0,e.createComponentVNode)(2,o.Window,{width:600,height:420,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:i.name,children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Integrity",children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:c,value:i.integrity/100})})}),(0,e.createComponentVNode)(2,t.Box,{color:"red",children:(0,e.createVNode)(1,"h2",null,i.flushing===1?"Wipe of AI in progress...":"",0)})]})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Laws",children:!!i.has_laws&&(0,e.createComponentVNode)(2,t.Box,{children:i.laws.map(function(m,l){return(0,e.createComponentVNode)(2,t.Box,{children:m},l)})})||(0,e.createComponentVNode)(2,t.Box,{color:"red",children:(0,e.createVNode)(1,"h3",null,"No laws detected.",16)})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Actions",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Wireless Activity",children:(0,e.createComponentVNode)(2,t.Button,{width:10,icon:i.wireless?"check":"times",content:i.wireless?"Enabled":"Disabled",color:i.wireless?"green":"red",onClick:function(){function m(){return h("wireless")}return m}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Subspace Transceiver",children:(0,e.createComponentVNode)(2,t.Button,{width:10,icon:i.radio?"check":"times",content:i.radio?"Enabled":"Disabled",color:i.radio?"green":"red",onClick:function(){function m(){return h("radio")}return m}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Wipe",children:(0,e.createComponentVNode)(2,t.Button.Confirm,{width:10,icon:"trash-alt",confirmIcon:"trash-alt",disabled:i.flushing||i.integrity===0,confirmColor:"red",content:"Wipe AI",onClick:function(){function m(){return h("wipe")}return m}()})})]})})})]})})})}return b}()},39454:function(T,r,n){"use strict";r.__esModule=!0,r.AIFixer=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.AIFixer=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data;if(i.occupant===null)return(0,e.createComponentVNode)(2,o.Window,{width:550,height:500,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Stored AI",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,textAlign:"center",align:"center",color:"average",children:[(0,e.createComponentVNode)(2,t.Icon.Stack,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"robot",size:5,color:"silver"}),(0,e.createComponentVNode)(2,t.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"h3",null,"No Artificial Intelligence detected.",16)]})})})})});var c=!0;(i.stat===2||i.stat===null)&&(c=!1);var m=null;i.integrity>=75?m="green":i.integrity>=25?m="yellow":m="red";var l=!0;return i.integrity>=100&&i.stat!==2&&(l=!1),(0,e.createComponentVNode)(2,o.Window,{scrollable:!0,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:i.occupant,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Integrity",children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:m,value:i.integrity/100})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",color:c?"green":"red",children:c?"Functional":"Non-Functional"})]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Laws",children:!!i.has_laws&&(0,e.createComponentVNode)(2,t.Box,{children:i.laws.map(function(u,s){return(0,e.createComponentVNode)(2,t.Box,{inline:!0,children:u},s)})})||(0,e.createComponentVNode)(2,t.Box,{color:"red",children:(0,e.createVNode)(1,"h3",null,"No laws detected.",16)})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Actions",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Wireless Activity",children:(0,e.createComponentVNode)(2,t.Button,{icon:i.wireless?"times":"check",content:i.wireless?"Disabled":"Enabled",color:i.wireless?"red":"green",onClick:function(){function u(){return h("wireless")}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Subspace Transceiver",children:(0,e.createComponentVNode)(2,t.Button,{icon:i.radio?"times":"check",content:i.radio?"Disabled":"Enabled",color:i.radio?"red":"green",onClick:function(){function u(){return h("radio")}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Start Repairs",children:(0,e.createComponentVNode)(2,t.Button,{icon:"wrench",disabled:!l||i.active,content:!l||i.active?"Already Repaired":"Repair",onClick:function(){function u(){return h("fix")}return u}()})})]}),(0,e.createComponentVNode)(2,t.Box,{color:"green",lineHeight:2,children:i.active?"Reconstruction in progress.":""})]})})]})})})}return b}()},88422:function(T,r,n){"use strict";r.__esModule=!0,r.APC=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(195),b=r.APC=function(){function h(i,c){return(0,e.createComponentVNode)(2,o.Window,{width:510,height:435,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,k)})})}return h}(),y={2:{color:"good",externalPowerText:"External Power",chargingText:"Fully Charged"},1:{color:"average",externalPowerText:"Low External Power",chargingText:"Charging"},0:{color:"bad",externalPowerText:"No External Power",chargingText:"Not Charging"}},S={1:{icon:"terminal",content:"Override Programming",action:"hack"},2:{icon:"caret-square-down",content:"Shunt Core Process",action:"occupy"},3:{icon:"caret-square-left",content:"Return to Main Core",action:"deoccupy"},4:{icon:"caret-square-down",content:"Shunt Core Process",action:"occupy"}},k=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.locked&&!u.siliconUser,d=u.normallyLocked,v=y[u.externalPower]||y[0],g=y[u.chargingStatus]||y[0],C=u.powerChannels||[],f=S[u.malfStatus]||S[0],N=u.powerCellStatus/100;return(0,e.createFragment)([(0,e.createComponentVNode)(2,p.InterfaceLockNoticeBox),(0,e.createComponentVNode)(2,t.Section,{title:"Power Status",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Main Breaker",color:v.color,buttons:(0,e.createComponentVNode)(2,t.Button,{icon:u.isOperating?"power-off":"times",content:u.isOperating?"On":"Off",selected:u.isOperating&&!s,color:u.isOperating?"":"bad",disabled:s,onClick:function(){function V(){return l("breaker")}return V}()}),children:["[ ",v.externalPowerText," ]"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power Cell",children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:"good",value:N})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Charge Mode",color:g.color,buttons:(0,e.createComponentVNode)(2,t.Button,{icon:u.chargeMode?"sync":"times",content:u.chargeMode?"Auto":"Off",selected:u.chargeMode,disabled:s,onClick:function(){function V(){return l("charge")}return V}()}),children:["[ ",g.chargingText," ]"]})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Power Channels",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[C.map(function(V){var B=V.topicParams;return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:V.title,buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{inline:!0,mx:2,color:V.status>=2?"good":"bad",children:V.status>=2?"On":"Off"}),(0,e.createComponentVNode)(2,t.Button,{icon:"sync",content:"Auto",selected:!s&&(V.status===1||V.status===3),disabled:s,onClick:function(){function I(){return l("channel",B.auto)}return I}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"power-off",content:"On",selected:!s&&V.status===2,disabled:s,onClick:function(){function I(){return l("channel",B.on)}return I}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"times",content:"Off",selected:!s&&V.status===0,disabled:s,onClick:function(){function I(){return l("channel",B.off)}return I}()})],4),children:[V.powerLoad," W"]},V.title)}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Total Load",children:(0,e.createVNode)(1,"b",null,[u.totalLoad,(0,e.createTextVNode)(" W")],0)})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Misc",buttons:!!u.siliconUser&&(0,e.createFragment)([!!u.malfStatus&&(0,e.createComponentVNode)(2,t.Button,{icon:f.icon,content:f.content,color:"bad",onClick:function(){function V(){return l(f.action)}return V}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"lightbulb-o",content:"Overload",onClick:function(){function V(){return l("overload")}return V}()})],0),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cover Lock",buttons:(0,e.createComponentVNode)(2,t.Button,{mb:.4,icon:u.coverLocked?"lock":"unlock",content:u.coverLocked?"Engaged":"Disengaged",disabled:s,onClick:function(){function V(){return l("cover")}return V}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Emergency Lighting",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"lightbulb-o",content:u.emergencyLights?"Enabled":"Disabled",disabled:s,onClick:function(){function V(){return l("emergency_lighting")}return V}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Night Shift Lighting",buttons:(0,e.createComponentVNode)(2,t.Button,{mt:.4,icon:"lightbulb-o",content:u.nightshiftLights?"Enabled":"Disabled",onClick:function(){function V(){return l("toggle_nightshift")}return V}()})})]})})],4)}},99660:function(T,r,n){"use strict";r.__esModule=!0,r.ATM=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.ATM=function(){function m(l,u){var s=(0,a.useBackend)(u),d=s.act,v=s.data,g=v.view_screen,C=v.authenticated_account,f=v.ticks_left_locked_down,N=v.linked_db,V;if(f>0)V=(0,e.createComponentVNode)(2,t.Box,{bold:!0,color:"bad",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"exclamation-triangle"}),"Maximum number of pin attempts exceeded! Access to this ATM has been temporarily disabled."]});else if(!N)V=(0,e.createComponentVNode)(2,t.Box,{bold:!0,color:"bad",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"exclamation-triangle"}),"Unable to connect to accounts database, please retry and if the issue persists contact Nanotrasen IT support."]});else if(C)switch(g){case 1:V=(0,e.createComponentVNode)(2,y);break;case 2:V=(0,e.createComponentVNode)(2,S);break;case 3:V=(0,e.createComponentVNode)(2,i);break;default:V=(0,e.createComponentVNode)(2,k)}else V=(0,e.createComponentVNode)(2,h);return(0,e.createComponentVNode)(2,o.Window,{width:550,height:650,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,b),(0,e.createComponentVNode)(2,t.Section,{children:V})]})})}return m}(),b=function(l,u){var s=(0,a.useBackend)(u),d=s.act,v=s.data,g=v.machine_id,C=v.held_card_name;return(0,e.createComponentVNode)(2,t.Section,{title:"Nanotrasen Automatic Teller Machine",children:[(0,e.createComponentVNode)(2,t.Box,{children:"For all your monetary needs!"}),(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Card",children:(0,e.createComponentVNode)(2,t.Button,{content:C,icon:"eject",onClick:function(){function f(){return d("insert_card")}return f}()})})})]})},y=function(l,u){var s=(0,a.useBackend)(u),d=s.act,v=s.data,g=v.security_level;return(0,e.createComponentVNode)(2,t.Section,{title:"Select a new security level for this account",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Level",children:(0,e.createComponentVNode)(2,t.Button,{content:"Account Number",icon:"unlock",selected:g===0,onClick:function(){function C(){return d("change_security_level",{new_security_level:1})}return C}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Description",children:"Either the account number or card is required to access this account. EFTPOS transactions will require a card."}),(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Level",children:(0,e.createComponentVNode)(2,t.Button,{content:"Account Pin",icon:"unlock",selected:g===2,onClick:function(){function C(){return d("change_security_level",{new_security_level:2})}return C}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Description",children:"An account number and pin must be manually entered to access this account and process transactions."})]}),(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,c)]})},S=function(l,u){var s=(0,a.useBackend)(u),d=s.act,v=s.data,g=(0,a.useLocalState)(u,"targetAccNumber",0),C=g[0],f=g[1],N=(0,a.useLocalState)(u,"fundsAmount",0),V=N[0],B=N[1],I=(0,a.useLocalState)(u,"purpose",0),L=I[0],w=I[1],A=v.money;return(0,e.createComponentVNode)(2,t.Section,{title:"Transfer Fund",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Account Balance",children:["$",A]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Target Account Number",children:(0,e.createComponentVNode)(2,t.Input,{placeholder:"7 Digit Number",onInput:function(){function x(E,P){return f(P)}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Funds to Transfer",children:(0,e.createComponentVNode)(2,t.Input,{onInput:function(){function x(E,P){return B(P)}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Transaction Purpose",children:(0,e.createComponentVNode)(2,t.Input,{fluid:!0,onInput:function(){function x(E,P){return w(P)}return x}()})})]}),(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,t.Button,{content:"Transfer",icon:"sign-out-alt",onClick:function(){function x(){return d("transfer",{target_acc_number:C,funds_amount:V,purpose:L})}return x}()}),(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,c)]})},k=function(l,u){var s=(0,a.useBackend)(u),d=s.act,v=s.data,g=(0,a.useLocalState)(u,"fundsAmount",0),C=g[0],f=g[1],N=v.owner_name,V=v.money;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{title:"Welcome, "+N,buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Logout",icon:"sign-out-alt",onClick:function(){function B(){return d("logout")}return B}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Account Balance",children:["$",V]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Withdrawal Amount",children:(0,e.createComponentVNode)(2,t.Input,{onInput:function(){function B(I,L){return f(L)}return B}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Withdraw Funds",icon:"sign-out-alt",onClick:function(){function B(){return d("withdrawal",{funds_amount:C})}return B}()})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Menu",children:[(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Change account security level",icon:"lock",onClick:function(){function B(){return d("view_screen",{view_screen:1})}return B}()})}),(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Make transfer",icon:"exchange-alt",onClick:function(){function B(){return d("view_screen",{view_screen:2})}return B}()})}),(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{content:"View transaction log",icon:"list",onClick:function(){function B(){return d("view_screen",{view_screen:3})}return B}()})}),(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Print balance statement",icon:"print",onClick:function(){function B(){return d("balance_statement")}return B}()})})]})],4)},h=function(l,u){var s=(0,a.useBackend)(u),d=s.act,v=s.data,g=(0,a.useLocalState)(u,"accountID",null),C=g[0],f=g[1],N=(0,a.useLocalState)(u,"accountPin",null),V=N[0],B=N[1],I=v.machine_id,L=v.held_card_name;return(0,e.createComponentVNode)(2,t.Section,{title:"Insert card or enter ID and pin to login",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Account ID",children:(0,e.createComponentVNode)(2,t.Input,{placeholder:"6 Digit Number",onInput:function(){function w(A,x){return f(x)}return w}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Pin",children:(0,e.createComponentVNode)(2,t.Input,{placeholder:"6 Digit Number",onInput:function(){function w(A,x){return B(x)}return w}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Login",icon:"sign-in-alt",onClick:function(){function w(){return d("attempt_auth",{account_num:C,account_pin:V})}return w}()})})]})})},i=function(l,u){var s=(0,a.useBackend)(u),d=s.act,v=s.data,g=v.transaction_log;return(0,e.createComponentVNode)(2,t.Section,{title:"Transactions",children:[(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Timestamp"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Reason"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Value"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Terminal"})]}),g.map(function(C){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:C.time}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:C.purpose}),(0,e.createComponentVNode)(2,t.Table.Cell,{color:C.is_deposit?"green":"red",children:["$",C.amount]}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:C.target_name})]},C)})]}),(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,c)]})},c=function(l,u){var s=(0,a.useBackend)(u),d=s.act,v=s.data;return(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"sign-out-alt",onClick:function(){function g(){return d("view_screen",{view_screen:0})}return g}()})}},86423:function(T,r,n){"use strict";r.__esModule=!0,r.AccountsUplinkTerminal=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),p=n(36352),b=n(98595),y=n(321),S=n(5485),k=r.AccountsUplinkTerminal=function(){function v(g,C){var f=(0,t.useBackend)(C),N=f.act,V=f.data,B=V.loginState,I=V.currentPage,L;if(B.logged_in)I===1?L=(0,e.createComponentVNode)(2,i):I===2?L=(0,e.createComponentVNode)(2,s):I===3&&(L=(0,e.createComponentVNode)(2,d));else return(0,e.createComponentVNode)(2,b.Window,{width:800,height:600,children:(0,e.createComponentVNode)(2,b.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,S.LoginScreen)})})});return(0,e.createComponentVNode)(2,b.Window,{width:800,height:600,children:(0,e.createComponentVNode)(2,b.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,y.LoginInfo),(0,e.createComponentVNode)(2,h),(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,children:L})]})})})}return v}(),h=function(g,C){var f=(0,t.useBackend)(C),N=f.data,V=(0,t.useLocalState)(C,"tabIndex",0),B=V[0],I=V[1],L=N.login_state;return(0,e.createComponentVNode)(2,o.Stack,{vertical:!0,mb:1,children:(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Tabs,{children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"list",selected:B===0,onClick:function(){function w(){return I(0)}return w}(),children:"User Accounts"}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"list",selected:B===1,onClick:function(){function w(){return I(1)}return w}(),children:"Department Accounts"})]})})})},i=function(g,C){var f=(0,t.useLocalState)(C,"tabIndex",0),N=f[0];switch(N){case 0:return(0,e.createComponentVNode)(2,c);case 1:return(0,e.createComponentVNode)(2,m);default:return"You are somehow on a tab that doesn't exist! Please let a coder know."}},c=function(g,C){var f=(0,t.useBackend)(C),N=f.act,V=f.data,B=V.accounts,I=(0,t.useLocalState)(C,"searchText",""),L=I[0],w=I[1],A=(0,t.useLocalState)(C,"sortId","owner_name"),x=A[0],E=A[1],P=(0,t.useLocalState)(C,"sortOrder",!0),D=P[0],M=P[1];return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,u),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,o.Table,{className:"AccountsUplinkTerminal__list",children:[(0,e.createComponentVNode)(2,o.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,l,{id:"owner_name",children:"Account Holder"}),(0,e.createComponentVNode)(2,l,{id:"account_number",children:"Account Number"}),(0,e.createComponentVNode)(2,l,{id:"suspended",children:"Account Status"}),(0,e.createComponentVNode)(2,l,{id:"money",children:"Account Balance"})]}),B.filter((0,a.createSearch)(L,function(O){return O.owner_name+"|"+O.account_number+"|"+O.suspended+"|"+O.money})).sort(function(O,R){var F=D?1:-1;return O[x].localeCompare(R[x])*F}).map(function(O){return(0,e.createComponentVNode)(2,o.Table.Row,{className:"AccountsUplinkTerminal__listRow--"+O.suspended,onClick:function(){function R(){return N("view_account_detail",{account_num:O.account_number})}return R}(),children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"user"})," ",O.owner_name]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:["#",O.account_number]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:O.suspended}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:O.money})]},O.account_number)})]})})})]})},m=function(g,C){var f=(0,t.useBackend)(C),N=f.act,V=f.data,B=V.department_accounts;return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.Table,{className:"AccountsUplinkTerminal__list",children:[(0,e.createComponentVNode)(2,o.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,p.TableCell,{children:"Department Name"}),(0,e.createComponentVNode)(2,p.TableCell,{children:"Account Number"}),(0,e.createComponentVNode)(2,p.TableCell,{children:"Account Status"}),(0,e.createComponentVNode)(2,p.TableCell,{children:"Account Balance"})]}),B.map(function(I){return(0,e.createComponentVNode)(2,o.Table.Row,{className:"AccountsUplinkTerminal__listRow--"+I.suspended,onClick:function(){function L(){return N("view_account_detail",{account_num:I.account_number})}return L}(),children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"wallet"})," ",I.name]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:["#",I.account_number]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:I.suspended}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:I.money})]},I.account_number)})]})})})})},l=function(g,C){var f=(0,t.useLocalState)(C,"sortId","name"),N=f[0],V=f[1],B=(0,t.useLocalState)(C,"sortOrder",!0),I=B[0],L=B[1],w=g.id,A=g.children;return(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{color:N!==w&&"transparent",width:"100%",onClick:function(){function x(){N===w?L(!I):(V(w),L(!0))}return x}(),children:[A,N===w&&(0,e.createComponentVNode)(2,o.Icon,{name:I?"sort-up":"sort-down",ml:"0.25rem;"})]})})},u=function(g,C){var f=(0,t.useBackend)(C),N=f.act,V=f.data,B=V.is_printing,I=(0,t.useLocalState)(C,"searchText",""),L=I[0],w=I[1];return(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{content:"New Account",icon:"plus",onClick:function(){function A(){return N("create_new_account")}return A}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Input,{placeholder:"Search by account holder, number, status",width:"100%",onInput:function(){function A(x,E){return w(E)}return A}()})})]})},s=function(g,C){var f=(0,t.useBackend)(C),N=f.act,V=f.data,B=V.account_number,I=V.owner_name,L=V.money,w=V.suspended,A=V.transactions,x=V.account_pin,E=V.is_department_account;return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{title:"#"+B+" / "+I,buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"arrow-left",content:"Back",onClick:function(){function P(){return N("back")}return P}()}),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account Number",children:["#",B]}),!!E&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account Pin",children:x}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account Pin Actions",children:(0,e.createComponentVNode)(2,o.Button,{ml:1,icon:"user-cog",content:"Set New Pin",disabled:!!E,onClick:function(){function P(){return N("set_account_pin",{account_number:B})}return P}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account Holder",children:I}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account Balance",children:L}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account Status",color:w?"red":"green",children:[w?"Suspended":"Active",(0,e.createComponentVNode)(2,o.Button,{ml:1,content:w?"Unsuspend":"Suspend",icon:w?"unlock":"lock",onClick:function(){function P(){return N("toggle_suspension")}return P}()})]})]})})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,title:"Transactions",children:(0,e.createComponentVNode)(2,o.Table,{children:[(0,e.createComponentVNode)(2,o.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Timestamp"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Reason"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Value"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Terminal"})]}),A.map(function(P){return(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:P.time}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:P.purpose}),(0,e.createComponentVNode)(2,o.Table.Cell,{color:P.is_deposit?"green":"red",children:["$",P.amount]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:P.target_name})]},P)})]})})})]})},d=function(g,C){var f=(0,t.useBackend)(C),N=f.act,V=f.data,B=(0,t.useLocalState)(C,"accName",""),I=B[0],L=B[1],w=(0,t.useLocalState)(C,"accDeposit",""),A=w[0],x=w[1];return(0,e.createComponentVNode)(2,o.Section,{title:"Create Account",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"arrow-left",content:"Back",onClick:function(){function E(){return N("back")}return E}()}),children:[(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account Holder",children:(0,e.createComponentVNode)(2,o.Input,{placeholder:"Name Here",onChange:function(){function E(P,D){return L(D)}return E}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Initial Deposit",children:(0,e.createComponentVNode)(2,o.Input,{placeholder:"0",onChange:function(){function E(P,D){return x(D)}return E}()})})]}),(0,e.createComponentVNode)(2,o.Button,{mt:1,fluid:!0,content:"Create Account",onClick:function(){function E(){return N("finalise_create_account",{holder_name:I,starting_funds:A})}return E}()})]})}},39683:function(T,r,n){"use strict";r.__esModule=!0,r.AgentCardInfo=r.AgentCardAppearances=r.AgentCard=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=[{name:"Male",icon:"mars"},{name:"Female",icon:"venus"},{name:"Genderless",icon:"genderless"}],b=["A+","A-","B+","B-","AB+","AB-","O+","O-"],y="Empty",S=function(m){var l=m.label,u=m.value,s=m.onCommit,d=m.onClick,v=m.onRClick,g=m.tooltip;return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:l,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,mb:-.5,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button.Input,{fluid:!0,textAlign:"center",content:u||y,onCommit:s})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"file-signature",tooltip:g,tooltipPosition:"bottom-end",onClick:d,onContextMenu:v})})]})})},k=r.AgentCard=function(){function c(m,l){var u=(0,a.useLocalState)(l,"tabIndex",0),s=u[0],d=u[1],v=function(){function g(C){switch(C){case 0:return(0,e.createComponentVNode)(2,h);case 1:return(0,e.createComponentVNode)(2,i);default:return(0,e.createComponentVNode)(2,h)}}return g}();return(0,e.createComponentVNode)(2,o.Window,{width:435,height:500,theme:"syndicate",children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Tabs,{fluid:!0,children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:s===0,onClick:function(){function g(){return d(0)}return g}(),children:[(0,e.createComponentVNode)(2,t.Icon,{name:"table"})," Card Info"]},"Card Info"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:s===1,onClick:function(){function g(){return d(1)}return g}(),children:[(0,e.createComponentVNode)(2,t.Icon,{name:"id-card"})," Appearance"]},"Appearance")]})}),v(s)]})})})}return c}(),h=r.AgentCardInfo=function(){function c(m,l){var u=(0,a.useBackend)(l),s=u.act,d=u.data,v=d.registered_name,g=d.sex,C=d.age,f=d.assignment,N=d.job_icon,V=d.associated_account_number,B=d.blood_type,I=d.dna_hash,L=d.fingerprint_hash,w=d.photo,A=d.ai_tracking,x=d.photo_cooldown,E=(0,e.createVNode)(1,"span",null,[(0,e.createTextVNode)("Autofill options."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("LMB - Autofill your own data."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("RMB - Autofill someone else data.")],4),P=(0,e.createVNode)(1,"span",null,[(0,e.createTextVNode)("Autofill options."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("LMB - Autofill your own data."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("RMB - Autofill with random data.")],4);return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Card Info",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,S,{label:"Name",value:v,tooltip:E,onCommit:function(){function D(M,O){return s("change_name",{name:O})}return D}(),onClick:function(){function D(){return s("change_name",{option:"Primary"})}return D}(),onRClick:function(){function D(M){M.preventDefault(),s("change_name",{option:"Secondary"})}return D}()}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Sex",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,mb:-.5,children:p.map(function(D){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:D.icon,content:D.name,selected:g===D.name,onClick:function(){function M(){return s("change_sex",{sex:D.name})}return M}()})},D.name)})})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Age",children:(0,e.createComponentVNode)(2,t.Slider,{fluid:!0,minValue:17,value:C||0,maxValue:300,onChange:function(){function D(M,O){return s("change_age",{age:O})}return D}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Rank",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,mb:-.5,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,onClick:function(){function D(){return s("change_occupation")}return D}(),textAlign:"middle",children:f||"[UNSET]"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{tooltip:"Change HUD icon",tooltipPosition:"bottom-end",onClick:function(){function D(){return s("change_occupation",{option:"Primary"})}return D}(),children:[(0,e.createComponentVNode)(2,t.DmIcon,{fill:!0,icon:"icons/mob/hud/job_assets.dmi",icon_state:N,verticalAlign:"bottom",my:"2px",width:"16px"})," "]})})]})}),(0,e.createComponentVNode)(2,S,{label:"Fingerprint",value:L,onCommit:function(){function D(M,O){return s("change_fingerprints",{new_fingerprints:O})}return D}(),onClick:function(){function D(){return s("change_fingerprints",{option:"Primary"})}return D}(),onRClick:function(){function D(M){M.preventDefault(),s("change_fingerprints",{option:"Secondary"})}return D}(),tooltip:P}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Blood Type",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,mb:-.5,children:b.map(function(D){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,content:D,selected:B===D,onClick:function(){function M(){return s("change_blood_type",{new_type:D})}return M}()})},D)})})}),(0,e.createComponentVNode)(2,S,{label:"DNA",value:I,onCommit:function(){function D(M,O){return s("change_dna_hash",{new_dna:O})}return D}(),onClick:function(){function D(){return s("change_dna_hash",{option:"Primary"})}return D}(),onRClick:function(){function D(M){M.preventDefault(),s("change_dna_hash",{option:"Secondary"})}return D}(),tooltip:P}),(0,e.createComponentVNode)(2,S,{label:"Account",value:V||0,onCommit:function(){function D(M,O){return s("change_money_account",{new_account:O})}return D}(),onClick:function(){function D(){return s("change_money_account",{option:"Primary"})}return D}(),onRClick:function(){function D(M){M.preventDefault(),s("change_money_account",{option:"Secondary"})}return D}(),tooltip:P}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Photo",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",disabled:!x,tooltip:x?"":"You can't generate a new photo yet.",onClick:function(){function D(){return s("change_photo")}return D}(),children:w?"Update":y})})]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Card Settings",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Card Info",children:(0,e.createComponentVNode)(2,t.Button.Confirm,{fluid:!0,textAlign:"center",content:"Delete Card Info",confirmContent:"Are you sure?",onClick:function(){function D(){return s("delete_info")}return D}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Access",children:(0,e.createComponentVNode)(2,t.Button.Confirm,{fluid:!0,textAlign:"center",content:"Reset Access",confirmContent:"Are you sure?",onClick:function(){function D(){return s("clear_access")}return D}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"AI Tracking",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",onClick:function(){function D(){return s("change_ai_tracking")}return D}(),children:A?"Untrackable":"Trackable"})})]})})})],4)}return c}(),i=r.AgentCardAppearances=function(){function c(m,l){var u=(0,a.useBackend)(l),s=u.act,d=u.data,v=(0,a.useSharedState)(l,"selectedAppearance",null),g=v[0],C=v[1],f=d.appearances,N=d.id_icon;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Card Appearance",children:f.map(function(V){return(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:N,dmIconState:V,imageSize:64,compact:!0,selected:V===g,tooltip:V,style:{opacity:V===g&&"1"||"0.5"},onClick:function(){function B(){C(V),s("change_appearance",{new_appearance:V})}return B}()},V)})})})}return c}()},56793:function(T,r,n){"use strict";r.__esModule=!0,r.AiAirlock=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p={2:{color:"good",localStatusText:"Offline"},1:{color:"average",localStatusText:"Caution"},0:{color:"bad",localStatusText:"Optimal"}},b=r.AiAirlock=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=p[c.power.main]||p[0],l=p[c.power.backup]||p[0],u=p[c.shock]||p[0];return(0,e.createComponentVNode)(2,o.Window,{width:500,height:400,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Power Status",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Main",color:m.color,buttons:(0,e.createComponentVNode)(2,t.Button,{mb:.5,icon:"lightbulb-o",disabled:!c.power.main,content:"Disrupt",onClick:function(){function s(){return i("disrupt-main")}return s}()}),children:[c.power.main?"Online":"Offline"," ",!c.wires.main_power&&"[Wires have been cut!]"||c.power.main_timeleft>0&&"["+c.power.main_timeleft+"s]"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Backup",color:l.color,buttons:(0,e.createComponentVNode)(2,t.Button,{mb:.5,icon:"lightbulb-o",disabled:!c.power.backup,content:"Disrupt",onClick:function(){function s(){return i("disrupt-backup")}return s}()}),children:[c.power.backup?"Online":"Offline"," ",!c.wires.backup_power&&"[Wires have been cut!]"||c.power.backup_timeleft>0&&"["+c.power.backup_timeleft+"s]"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Electrify",color:u.color,buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{mr:.5,icon:"wrench",disabled:!(c.wires.shock&&c.shock!==2),content:"Restore",onClick:function(){function s(){return i("shock-restore")}return s}()}),(0,e.createComponentVNode)(2,t.Button,{mr:.5,icon:"bolt",disabled:!c.wires.shock,content:"Temporary",onClick:function(){function s(){return i("shock-temp")}return s}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"bolt",disabled:!c.wires.shock||c.shock===0,content:"Permanent",onClick:function(){function s(){return i("shock-perm")}return s}()})],4),children:[c.shock===2?"Safe":"Electrified"," ",!c.wires.shock&&"[Wires have been cut!]"||c.shock_timeleft>0&&"["+c.shock_timeleft+"s]"||c.shock_timeleft===-1&&"[Permanent]"]})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Access and Door Control",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"ID Scan",color:"bad",buttons:(0,e.createComponentVNode)(2,t.Button,{mb:.5,width:6.5,icon:c.id_scanner?"power-off":"times",content:c.id_scanner?"Enabled":"Disabled",selected:c.id_scanner,disabled:!c.wires.id_scanner,onClick:function(){function s(){return i("idscan-toggle")}return s}()}),children:!c.wires.id_scanner&&"[Wires have been cut!]"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Emergency Access",buttons:(0,e.createComponentVNode)(2,t.Button,{width:6.5,icon:c.emergency?"power-off":"times",content:c.emergency?"Enabled":"Disabled",selected:c.emergency,onClick:function(){function s(){return i("emergency-toggle")}return s}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Door Bolts",color:"bad",buttons:(0,e.createComponentVNode)(2,t.Button,{mb:.5,icon:c.locked?"lock":"unlock",content:c.locked?"Lowered":"Raised",selected:c.locked,disabled:!c.wires.bolts,onClick:function(){function s(){return i("bolt-toggle")}return s}()}),children:!c.wires.bolts&&"[Wires have been cut!]"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Door Bolt Lights",color:"bad",buttons:(0,e.createComponentVNode)(2,t.Button,{mb:.5,width:6.5,icon:c.lights?"power-off":"times",content:c.lights?"Enabled":"Disabled",selected:c.lights,disabled:!c.wires.lights,onClick:function(){function s(){return i("light-toggle")}return s}()}),children:!c.wires.lights&&"[Wires have been cut!]"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Door Force Sensors",color:"bad",buttons:(0,e.createComponentVNode)(2,t.Button,{mb:.5,width:6.5,icon:c.safe?"power-off":"times",content:c.safe?"Enabled":"Disabled",selected:c.safe,disabled:!c.wires.safe,onClick:function(){function s(){return i("safe-toggle")}return s}()}),children:!c.wires.safe&&"[Wires have been cut!]"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Door Timing Safety",color:"bad",buttons:(0,e.createComponentVNode)(2,t.Button,{mb:.5,width:6.5,icon:c.speed?"power-off":"times",content:c.speed?"Enabled":"Disabled",selected:c.speed,disabled:!c.wires.timing,onClick:function(){function s(){return i("speed-toggle")}return s}()}),children:!c.wires.timing&&"[Wires have been cut!]"}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Door Control",color:"bad",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:c.opened?"sign-out-alt":"sign-in-alt",content:c.opened?"Open":"Closed",selected:c.opened,disabled:c.locked||c.welded,onClick:function(){function s(){return i("open-close")}return s}()}),children:!!(c.locked||c.welded)&&(0,e.createVNode)(1,"span",null,[(0,e.createTextVNode)("[Door is "),c.locked?"bolted":"",c.locked&&c.welded?" and ":"",c.welded?"welded":"",(0,e.createTextVNode)("!]")],0)})]})})]})})}return y}()},72475:function(T,r,n){"use strict";r.__esModule=!0,r.AirAlarm=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(195),b=r.AirAlarm=function(){function u(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.locked;return(0,e.createComponentVNode)(2,o.Window,{width:570,height:f?310:755,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,p.InterfaceLockNoticeBox),(0,e.createComponentVNode)(2,S),!f&&(0,e.createFragment)([(0,e.createComponentVNode)(2,k),(0,e.createComponentVNode)(2,h)],4)]})})}return u}(),y=function(s){return s===0?"green":s===1?"orange":"red"},S=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.air,N=C.mode,V=C.atmos_alarm,B=C.locked,I=C.alarmActivated,L=C.rcon,w=C.target_temp,A;return f.danger.overall===0?V===0?A="Optimal":A="Caution: Atmos alert in area":f.danger.overall===1?A="Caution":A="DANGER: Internals Required",(0,e.createComponentVNode)(2,t.Section,{title:"Air Status",children:f?(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Pressure",children:(0,e.createComponentVNode)(2,t.Box,{color:y(f.danger.pressure),children:[(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:f.pressure})," kPa",!B&&(0,e.createFragment)([(0,e.createTextVNode)("\xA0"),(0,e.createComponentVNode)(2,t.Button,{content:N===3?"Deactivate Panic Siphon":"Activate Panic Siphon",selected:N===3,icon:"exclamation-triangle",onClick:function(){function x(){return g("mode",{mode:N===3?1:3})}return x}()})],4)]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Oxygen",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:f.contents.oxygen/100,fractionDigits:"1",color:y(f.danger.oxygen)})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Nitrogen",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:f.contents.nitrogen/100,fractionDigits:"1",color:y(f.danger.nitrogen)})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Carbon Dioxide",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:f.contents.co2/100,fractionDigits:"1",color:y(f.danger.co2)})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Toxins",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:f.contents.plasma/100,fractionDigits:"1",color:y(f.danger.plasma)})}),f.contents.n2o>.1&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Nitrous Oxide",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:f.contents.n2o/100,fractionDigits:"1",color:y(f.danger.n2o)})}),f.contents.other>.1&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Other",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:f.contents.other/100,fractionDigits:"1",color:y(f.danger.other)})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Temperature",children:(0,e.createComponentVNode)(2,t.Box,{color:y(f.danger.temperature),children:[(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:f.temperature})," K / ",(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:f.temperature_c})," C\xA0",(0,e.createComponentVNode)(2,t.Button,{icon:"thermometer-full",content:w+" C",onClick:function(){function x(){return g("temperature")}return x}()}),(0,e.createComponentVNode)(2,t.Button,{content:f.thermostat_state?"On":"Off",selected:f.thermostat_state,icon:"power-off",onClick:function(){function x(){return g("thermostat_state")}return x}()})]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Local Status",children:(0,e.createComponentVNode)(2,t.Box,{color:y(f.danger.overall),children:[A,!B&&(0,e.createFragment)([(0,e.createTextVNode)("\xA0"),(0,e.createComponentVNode)(2,t.Button,{content:I?"Reset Alarm":"Activate Alarm",selected:I,onClick:function(){function x(){return g(I?"atmos_reset":"atmos_alarm")}return x}()})],4)]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Remote Control Settings",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Off",selected:L===1,onClick:function(){function x(){return g("set_rcon",{rcon:1})}return x}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Auto",selected:L===2,onClick:function(){function x(){return g("set_rcon",{rcon:2})}return x}()}),(0,e.createComponentVNode)(2,t.Button,{content:"On",selected:L===3,onClick:function(){function x(){return g("set_rcon",{rcon:3})}return x}()})]})]}):(0,e.createComponentVNode)(2,t.Box,{children:"Unable to acquire air sample!"})})},k=function(s,d){var v=(0,a.useLocalState)(d,"tabIndex",0),g=v[0],C=v[1];return(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:g===0,onClick:function(){function f(){return C(0)}return f}(),children:[(0,e.createComponentVNode)(2,t.Icon,{name:"sign-out-alt"})," Vent Control"]},"Vents"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:g===1,onClick:function(){function f(){return C(1)}return f}(),children:[(0,e.createComponentVNode)(2,t.Icon,{name:"sign-in-alt"})," Scrubber Control"]},"Scrubbers"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:g===2,onClick:function(){function f(){return C(2)}return f}(),children:[(0,e.createComponentVNode)(2,t.Icon,{name:"cog"})," Mode"]},"Mode"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:g===3,onClick:function(){function f(){return C(3)}return f}(),children:[(0,e.createComponentVNode)(2,t.Icon,{name:"tachometer-alt"})," Thresholds"]},"Thresholds")]})},h=function(s,d){var v=(0,a.useLocalState)(d,"tabIndex",0),g=v[0],C=v[1];switch(g){case 0:return(0,e.createComponentVNode)(2,i);case 1:return(0,e.createComponentVNode)(2,c);case 2:return(0,e.createComponentVNode)(2,m);case 3:return(0,e.createComponentVNode)(2,l);default:return"WE SHOULDN'T BE HERE!"}},i=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.vents;return f.map(function(N){return(0,e.createComponentVNode)(2,t.Section,{title:N.name,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:[(0,e.createComponentVNode)(2,t.Button,{content:N.power?"On":"Off",selected:N.power,icon:"power-off",onClick:function(){function V(){return g("command",{cmd:"power",val:!N.power,id_tag:N.id_tag})}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:N.direction?"Blowing":"Siphoning",icon:N.direction?"sign-out-alt":"sign-in-alt",onClick:function(){function V(){return g("command",{cmd:"direction",val:!N.direction,id_tag:N.id_tag})}return V}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Pressure Checks",children:[(0,e.createComponentVNode)(2,t.Button,{content:"External",selected:N.checks===1,onClick:function(){function V(){return g("command",{cmd:"checks",val:1,id_tag:N.id_tag})}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Internal",selected:N.checks===2,onClick:function(){function V(){return g("command",{cmd:"checks",val:2,id_tag:N.id_tag})}return V}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"External Pressure Target",children:[(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:N.external})," kPa\xA0",(0,e.createComponentVNode)(2,t.Button,{content:"Set",icon:"cog",onClick:function(){function V(){return g("command",{cmd:"set_external_pressure",id_tag:N.id_tag})}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Reset",icon:"redo-alt",onClick:function(){function V(){return g("command",{cmd:"set_external_pressure",val:101.325,id_tag:N.id_tag})}return V}()})]})]})},N.name)})},c=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.scrubbers;return f.map(function(N){return(0,e.createComponentVNode)(2,t.Section,{title:N.name,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:[(0,e.createComponentVNode)(2,t.Button,{content:N.power?"On":"Off",selected:N.power,icon:"power-off",onClick:function(){function V(){return g("command",{cmd:"power",val:!N.power,id_tag:N.id_tag})}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:N.scrubbing?"Scrubbing":"Siphoning",icon:N.scrubbing?"filter":"sign-in-alt",onClick:function(){function V(){return g("command",{cmd:"scrubbing",val:!N.scrubbing,id_tag:N.id_tag})}return V}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Range",children:(0,e.createComponentVNode)(2,t.Button,{content:N.widenet?"Extended":"Normal",selected:N.widenet,icon:"expand-arrows-alt",onClick:function(){function V(){return g("command",{cmd:"widenet",val:!N.widenet,id_tag:N.id_tag})}return V}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Filtering",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Carbon Dioxide",selected:N.filter_co2,onClick:function(){function V(){return g("command",{cmd:"co2_scrub",val:!N.filter_co2,id_tag:N.id_tag})}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Plasma",selected:N.filter_toxins,onClick:function(){function V(){return g("command",{cmd:"tox_scrub",val:!N.filter_toxins,id_tag:N.id_tag})}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Nitrous Oxide",selected:N.filter_n2o,onClick:function(){function V(){return g("command",{cmd:"n2o_scrub",val:!N.filter_n2o,id_tag:N.id_tag})}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Oxygen",selected:N.filter_o2,onClick:function(){function V(){return g("command",{cmd:"o2_scrub",val:!N.filter_o2,id_tag:N.id_tag})}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Nitrogen",selected:N.filter_n2,onClick:function(){function V(){return g("command",{cmd:"n2_scrub",val:!N.filter_n2,id_tag:N.id_tag})}return V}()})]})]})},N.name)})},m=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.modes,N=C.presets,V=C.emagged,B=C.mode,I=C.preset;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{title:"System Mode",children:(0,e.createComponentVNode)(2,t.Table,{children:f.map(function(L){return(!L.emagonly||L.emagonly&&!!V)&&(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"right",width:1,children:(0,e.createComponentVNode)(2,t.Button,{content:L.name,icon:"cog",selected:L.id===B,onClick:function(){function w(){return g("mode",{mode:L.id})}return w}()})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:L.desc})]},L.name)})})}),(0,e.createComponentVNode)(2,t.Section,{title:"System Presets",children:[(0,e.createComponentVNode)(2,t.Box,{italic:!0,children:"After making a selection, the system will automatically cycle in order to remove contaminants."}),(0,e.createComponentVNode)(2,t.Table,{mt:1,children:N.map(function(L){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"right",width:1,children:(0,e.createComponentVNode)(2,t.Button,{content:L.name,icon:"cog",selected:L.id===I,onClick:function(){function w(){return g("preset",{preset:L.id})}return w}()})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:L.desc})]},L.name)})})]})],4)},l=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.thresholds;return(0,e.createComponentVNode)(2,t.Section,{title:"Alarm Thresholds",children:(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{width:"20%",children:"Value"}),(0,e.createComponentVNode)(2,t.Table.Cell,{color:"red",width:"20%",children:"Danger Min"}),(0,e.createComponentVNode)(2,t.Table.Cell,{color:"orange",width:"20%",children:"Warning Min"}),(0,e.createComponentVNode)(2,t.Table.Cell,{color:"orange",width:"20%",children:"Warning Max"}),(0,e.createComponentVNode)(2,t.Table.Cell,{color:"red",width:"20%",children:"Danger Max"})]}),f.map(function(N){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:N.name}),N.settings.map(function(V){return(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:V.selected===-1?"Off":V.selected,onClick:function(){function B(){return g("command",{cmd:"set_threshold",env:V.env,var:V.val})}return B}()})},V.val)})]},N.name)})]})})}},12333:function(T,r,n){"use strict";r.__esModule=!0,r.AirlockAccessController=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.AirlockAccessController=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.exterior_status,m=i.interior_status,l=i.processing,u,s;return c==="open"?u=(0,e.createComponentVNode)(2,t.Button,{width:"50%",content:"Lock Exterior Door",icon:"exclamation-triangle",disabled:l,onClick:function(){function d(){return h("force_ext")}return d}()}):u=(0,e.createComponentVNode)(2,t.Button,{width:"50%",content:"Cycle to Exterior",icon:"arrow-circle-left",disabled:l,onClick:function(){function d(){return h("cycle_ext_door")}return d}()}),m==="open"?s=(0,e.createComponentVNode)(2,t.Button,{width:"49%",content:"Lock Interior Door",icon:"exclamation-triangle",disabled:l,color:m==="open"?"red":l?"yellow":null,onClick:function(){function d(){return h("force_int")}return d}()}):s=(0,e.createComponentVNode)(2,t.Button,{width:"49%",content:"Cycle to Interior",icon:"arrow-circle-right",disabled:l,onClick:function(){function d(){return h("cycle_int_door")}return d}()}),(0,e.createComponentVNode)(2,o.Window,{width:330,height:200,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Information",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"External Door Status",children:c==="closed"?"Locked":"Open"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Internal Door Status",children:m==="closed"?"Locked":"Open"})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Actions",children:(0,e.createComponentVNode)(2,t.Box,{children:[u,s]})})]})})}return b}()},28736:function(T,r,n){"use strict";r.__esModule=!0,r.AirlockElectronics=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(49148),b=1,y=2,S=4,k=8,h=r.AirlockElectronics=function(){function m(l,u){return(0,e.createComponentVNode)(2,o.Window,{width:450,height:565,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,i),(0,e.createComponentVNode)(2,c)]})})})}return m}(),i=function(l,u){var s=(0,a.useBackend)(u),d=s.act,v=s.data,g=v.unrestricted_dir;return(0,e.createComponentVNode)(2,t.Section,{title:"Access Control",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,mb:1,children:"Unrestricted Access From:"}),(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"arrow-left",content:"East",selected:g&S,onClick:function(){function C(){return d("unrestricted_access",{unres_dir:S})}return C}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"arrow-up",content:"South",selected:g&y,onClick:function(){function C(){return d("unrestricted_access",{unres_dir:y})}return C}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"arrow-right",content:"West",selected:g&k,onClick:function(){function C(){return d("unrestricted_access",{unres_dir:k})}return C}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"arrow-down",content:"North",selected:g&b,onClick:function(){function C(){return d("unrestricted_access",{unres_dir:b})}return C}()})})]})]})})},c=function(l,u){var s=(0,a.useBackend)(u),d=s.act,v=s.data,g=v.selected_accesses,C=v.one_access,f=v.regions;return(0,e.createComponentVNode)(2,p.AccessList,{usedByRcd:1,rcdButtons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:C,content:"One",onClick:function(){function N(){return d("set_one_access",{access:"one"})}return N}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:!C,content:"All",onClick:function(){function N(){return d("set_one_access",{access:"all"})}return N}()})],4),accesses:f,selectedList:g,accessMod:function(){function N(V){return d("set",{access:V})}return N}(),grantAll:function(){function N(){return d("grant_all")}return N}(),denyAll:function(){function N(){return d("clear_all")}return N}(),grantDep:function(){function N(V){return d("grant_region",{region:V})}return N}(),denyDep:function(){function N(V){return d("deny_region",{region:V})}return N}()})}},47365:function(T,r,n){"use strict";r.__esModule=!0,r.AlertModal=void 0;var e=n(89005),a=n(51057),t=n(72253),o=n(92986),p=n(36036),b=n(98595),y=-1,S=1,k=r.AlertModal=function(){function c(m,l){var u=(0,t.useBackend)(l),s=u.act,d=u.data,v=d.autofocus,g=d.buttons,C=g===void 0?[]:g,f=d.large_buttons,N=d.message,V=N===void 0?"":N,B=d.timeout,I=d.title,L=(0,t.useLocalState)(l,"selected",0),w=L[0],A=L[1],x=110+(V.length>30?Math.ceil(V.length/4):0)+(V.length&&f?5:0),E=325+(C.length>2?100:0),P=function(){function D(M){w===0&&M===y?A(C.length-1):w===C.length-1&&M===S?A(0):A(w+M)}return D}();return(0,e.createComponentVNode)(2,b.Window,{title:I,height:x,width:E,children:[!!B&&(0,e.createComponentVNode)(2,a.Loader,{value:B}),(0,e.createComponentVNode)(2,b.Window.Content,{onKeyDown:function(){function D(M){var O=window.event?M.which:M.keyCode;O===o.KEY_SPACE||O===o.KEY_ENTER?s("choose",{choice:C[w]}):O===o.KEY_ESCAPE?s("cancel"):O===o.KEY_LEFT?(M.preventDefault(),P(y)):(O===o.KEY_TAB||O===o.KEY_RIGHT)&&(M.preventDefault(),P(S))}return D}(),children:(0,e.createComponentVNode)(2,p.Section,{fill:!0,children:(0,e.createComponentVNode)(2,p.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,m:1,children:(0,e.createComponentVNode)(2,p.Box,{color:"label",overflow:"hidden",children:V})}),(0,e.createComponentVNode)(2,p.Stack.Item,{children:[!!v&&(0,e.createComponentVNode)(2,p.Autofocus),(0,e.createComponentVNode)(2,h,{selected:w})]})]})})})]})}return c}(),h=function(m,l){var u=(0,t.useBackend)(l),s=u.data,d=s.buttons,v=d===void 0?[]:d,g=s.large_buttons,C=s.swapped_buttons,f=m.selected;return(0,e.createComponentVNode)(2,p.Flex,{fill:!0,align:"center",direction:C?"row":"row-reverse",justify:"space-around",wrap:!0,children:v==null?void 0:v.map(function(N,V){return g&&v.length<3?(0,e.createComponentVNode)(2,p.Flex.Item,{grow:!0,children:(0,e.createComponentVNode)(2,i,{button:N,id:V.toString(),selected:f===V})},V):(0,e.createComponentVNode)(2,p.Flex.Item,{grow:g?1:0,children:(0,e.createComponentVNode)(2,i,{button:N,id:V.toString(),selected:f===V})},V)})})},i=function(m,l){var u=(0,t.useBackend)(l),s=u.act,d=u.data,v=d.large_buttons,g=m.button,C=m.selected,f=g.length>7?"100%":7;return(0,e.createComponentVNode)(2,p.Button,{mx:v?1:0,pt:v?.33:0,content:g,fluid:!!v,onClick:function(){function N(){return s("choose",{choice:g})}return N}(),selected:C,textAlign:"center",height:!!v&&2,width:!v&&f})}},71824:function(T,r,n){"use strict";r.__esModule=!0,r.AppearanceChanger=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.AppearanceChanger=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.change_race,l=c.species,u=c.specimen,s=c.change_gender,d=c.gender,v=c.change_eye_color,g=c.change_skin_tone,C=c.change_skin_color,f=c.change_runechat_color,N=c.change_head_accessory_color,V=c.change_hair_color,B=c.change_secondary_hair_color,I=c.change_facial_hair_color,L=c.change_secondary_facial_hair_color,w=c.change_head_marking_color,A=c.change_body_marking_color,x=c.change_tail_marking_color,E=c.change_head_accessory,P=c.head_accessory_styles,D=c.head_accessory_style,M=c.change_hair,O=c.hair_styles,R=c.hair_style,F=c.change_hair_gradient,W=c.change_facial_hair,U=c.facial_hair_styles,z=c.facial_hair_style,$=c.change_head_markings,G=c.head_marking_styles,X=c.head_marking_style,J=c.change_body_markings,se=c.body_marking_styles,ie=c.body_marking_style,me=c.change_tail_markings,q=c.tail_marking_styles,re=c.tail_marking_style,ae=c.change_body_accessory,le=c.body_accessory_styles,Z=c.body_accessory_style,ne=c.change_alt_head,te=c.alt_head_styles,fe=c.alt_head_style,pe=!1;return(v||g||C||N||f||V||B||I||L||w||A||x)&&(pe=!0),(0,e.createComponentVNode)(2,o.Window,{width:800,height:450,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[!!m&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Species",children:l.map(function(ce){return(0,e.createComponentVNode)(2,t.Button,{content:ce.specimen,selected:ce.specimen===u,onClick:function(){function Ve(){return i("race",{race:ce.specimen})}return Ve}()},ce.specimen)})}),!!s&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Gender",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Male",selected:d==="male",onClick:function(){function ce(){return i("gender",{gender:"male"})}return ce}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Female",selected:d==="female",onClick:function(){function ce(){return i("gender",{gender:"female"})}return ce}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Genderless",selected:d==="plural",onClick:function(){function ce(){return i("gender",{gender:"plural"})}return ce}()})]}),!!pe&&(0,e.createComponentVNode)(2,b),!!E&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Head accessory",children:P.map(function(ce){return(0,e.createComponentVNode)(2,t.Button,{content:ce.headaccessorystyle,selected:ce.headaccessorystyle===D,onClick:function(){function Ve(){return i("head_accessory",{head_accessory:ce.headaccessorystyle})}return Ve}()},ce.headaccessorystyle)})}),!!M&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Hair",children:O.map(function(ce){return(0,e.createComponentVNode)(2,t.Button,{content:ce.hairstyle,selected:ce.hairstyle===R,onClick:function(){function Ve(){return i("hair",{hair:ce.hairstyle})}return Ve}()},ce.hairstyle)})}),!!F&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Hair Gradient",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Change Style",onClick:function(){function ce(){return i("hair_gradient")}return ce}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Change Offset",onClick:function(){function ce(){return i("hair_gradient_offset")}return ce}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Change Color",onClick:function(){function ce(){return i("hair_gradient_colour")}return ce}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Change Alpha",onClick:function(){function ce(){return i("hair_gradient_alpha")}return ce}()})]}),!!W&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Facial hair",children:U.map(function(ce){return(0,e.createComponentVNode)(2,t.Button,{content:ce.facialhairstyle,selected:ce.facialhairstyle===z,onClick:function(){function Ve(){return i("facial_hair",{facial_hair:ce.facialhairstyle})}return Ve}()},ce.facialhairstyle)})}),!!$&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Head markings",children:G.map(function(ce){return(0,e.createComponentVNode)(2,t.Button,{content:ce.headmarkingstyle,selected:ce.headmarkingstyle===X,onClick:function(){function Ve(){return i("head_marking",{head_marking:ce.headmarkingstyle})}return Ve}()},ce.headmarkingstyle)})}),!!J&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Body markings",children:se.map(function(ce){return(0,e.createComponentVNode)(2,t.Button,{content:ce.bodymarkingstyle,selected:ce.bodymarkingstyle===ie,onClick:function(){function Ve(){return i("body_marking",{body_marking:ce.bodymarkingstyle})}return Ve}()},ce.bodymarkingstyle)})}),!!me&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tail markings",children:q.map(function(ce){return(0,e.createComponentVNode)(2,t.Button,{content:ce.tailmarkingstyle,selected:ce.tailmarkingstyle===re,onClick:function(){function Ve(){return i("tail_marking",{tail_marking:ce.tailmarkingstyle})}return Ve}()},ce.tailmarkingstyle)})}),!!ae&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Body accessory",children:le.map(function(ce){return(0,e.createComponentVNode)(2,t.Button,{content:ce.bodyaccessorystyle,selected:ce.bodyaccessorystyle===Z,onClick:function(){function Ve(){return i("body_accessory",{body_accessory:ce.bodyaccessorystyle})}return Ve}()},ce.bodyaccessorystyle)})}),!!ne&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Alternate head",children:te.map(function(ce){return(0,e.createComponentVNode)(2,t.Button,{content:ce.altheadstyle,selected:ce.altheadstyle===fe,onClick:function(){function Ve(){return i("alt_head",{alt_head:ce.altheadstyle})}return Ve}()},ce.altheadstyle)})})]})})})}return y}(),b=function(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=[{key:"change_eye_color",text:"Change eye color",action:"eye_color"},{key:"change_skin_tone",text:"Change skin tone",action:"skin_tone"},{key:"change_skin_color",text:"Change skin color",action:"skin_color"},{key:"change_runechat_color",text:"Change runechat color",action:"runechat_color"},{key:"change_head_accessory_color",text:"Change head accessory color",action:"head_accessory_color"},{key:"change_hair_color",text:"Change hair color",action:"hair_color"},{key:"change_secondary_hair_color",text:"Change secondary hair color",action:"secondary_hair_color"},{key:"change_facial_hair_color",text:"Change facial hair color",action:"facial_hair_color"},{key:"change_secondary_facial_hair_color",text:"Change secondary facial hair color",action:"secondary_facial_hair_color"},{key:"change_head_marking_color",text:"Change head marking color",action:"head_marking_color"},{key:"change_body_marking_color",text:"Change body marking color",action:"body_marking_color"},{key:"change_tail_marking_color",text:"Change tail marking color",action:"tail_marking_color"}];return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Colors",children:m.map(function(l){return!!c[l.key]&&(0,e.createComponentVNode)(2,t.Button,{content:l.text,onClick:function(){function u(){return i(l.action)}return u}()},l.key)})})}},72285:function(T,r,n){"use strict";r.__esModule=!0,r.AtmosAlertConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.AtmosAlertConsole=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.priority||[],m=i.minor||[];return(0,e.createComponentVNode)(2,o.Window,{width:350,height:300,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Alarms",children:(0,e.createVNode)(1,"ul",null,[c.length===0&&(0,e.createVNode)(1,"li","color-good","No Priority Alerts",16),c.map(function(l){return(0,e.createVNode)(1,"li","color-bad",l,0,null,l)}),m.length===0&&(0,e.createVNode)(1,"li","color-good","No Minor Alerts",16),m.map(function(l){return(0,e.createVNode)(1,"li","color-average",l,0,null,l)})],0)})})})}return b}()},65805:function(T,r,n){"use strict";r.__esModule=!0,r.AtmosControl=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(36352),p=n(98595),b=function(c){if(c===0)return(0,e.createComponentVNode)(2,t.Box,{color:"green",children:"Good"});if(c===1)return(0,e.createComponentVNode)(2,t.Box,{color:"orange",bold:!0,children:"Warning"});if(c===2)return(0,e.createComponentVNode)(2,t.Box,{color:"red",bold:!0,children:"DANGER"})},y=function(c){if(c===0)return"green";if(c===1)return"orange";if(c===2)return"red"},S=r.AtmosControl=function(){function i(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=(0,a.useLocalState)(m,"tabIndex",0),v=d[0],g=d[1],C=function(){function f(N){switch(N){case 0:return(0,e.createComponentVNode)(2,k);case 1:return(0,e.createComponentVNode)(2,h);default:return"WE SHOULDN'T BE HERE!"}}return f}();return(0,e.createComponentVNode)(2,p.Window,{width:800,height:600,children:(0,e.createComponentVNode)(2,p.Window.Content,{scrollable:v===0,children:(0,e.createComponentVNode)(2,t.Box,{fillPositionedParent:!0,children:[(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:v===0,onClick:function(){function f(){return g(0)}return f}(),children:[(0,e.createComponentVNode)(2,t.Icon,{name:"table"})," Data View"]},"DataView"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:v===1,onClick:function(){function f(){return g(1)}return f}(),children:[(0,e.createComponentVNode)(2,t.Icon,{name:"map-marked-alt"})," Map View"]},"MapView")]}),C(v)]})})})}return i}(),k=function(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=s.alarms;return(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Name"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Status"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Access"})]}),d.map(function(v){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,o.TableCell,{children:v.name}),(0,e.createComponentVNode)(2,o.TableCell,{children:b(v.danger)}),(0,e.createComponentVNode)(2,o.TableCell,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"cog",content:"Access",onClick:function(){function g(){return u("open_alarm",{aref:v.ref})}return g}()})})]},v.name)})]})})},h=function(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=s.alarms;return(0,e.createComponentVNode)(2,t.Box,{height:"526px",mb:"0.5rem",overflow:"hidden",children:(0,e.createComponentVNode)(2,t.NanoMap,{children:d.filter(function(v){return v.z===2}).map(function(v){return(0,e.createComponentVNode)(2,t.NanoMap.MarkerIcon,{x:v.x,y:v.y,icon:"circle",tooltip:v.name,color:y(v.danger),onClick:function(){function g(){return u("open_alarm",{aref:v.ref})}return g}()},v.ref)})})})}},87816:function(T,r,n){"use strict";r.__esModule=!0,r.AtmosFilter=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.AtmosFilter=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.on,m=i.pressure,l=i.max_pressure,u=i.filter_type,s=i.filter_type_list;return(0,e.createComponentVNode)(2,o.Window,{width:380,height:140,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:(0,e.createComponentVNode)(2,t.Button,{icon:"power-off",content:c?"On":"Off",color:c?null:"red",selected:c,onClick:function(){function d(){return h("power")}return d}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Rate",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"fast-backward",textAlign:"center",disabled:m===0,width:2.2,onClick:function(){function d(){return h("min_pressure")}return d}()}),(0,e.createComponentVNode)(2,t.NumberInput,{animated:!0,unit:"kPa",width:6.1,lineHeight:1.5,step:10,minValue:0,maxValue:l,value:m,onDrag:function(){function d(v,g){return h("custom_pressure",{pressure:g})}return d}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fast-forward",textAlign:"center",disabled:m===l,width:2.2,onClick:function(){function d(){return h("max_pressure")}return d}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Filter",children:s.map(function(d){return(0,e.createComponentVNode)(2,t.Button,{selected:d.gas_type===u,content:d.label,onClick:function(){function v(){return h("set_filter",{filter:d.gas_type})}return v}()},d.label)})})]})})})})}return b}()},52977:function(T,r,n){"use strict";r.__esModule=!0,r.AtmosMixer=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.AtmosMixer=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.on,l=c.pressure,u=c.max_pressure,s=c.node1_concentration,d=c.node2_concentration;return(0,e.createComponentVNode)(2,o.Window,{width:330,height:165,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:(0,e.createComponentVNode)(2,t.Button,{icon:"power-off",content:m?"On":"Off",color:m?null:"red",selected:m,onClick:function(){function v(){return i("power")}return v}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Rate",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"fast-backward",textAlign:"center",disabled:l===0,width:2.2,onClick:function(){function v(){return i("min_pressure")}return v}()}),(0,e.createComponentVNode)(2,t.NumberInput,{animated:!0,unit:"kPa",width:6.1,lineHeight:1.5,step:10,minValue:0,maxValue:u,value:l,onDrag:function(){function v(g,C){return i("custom_pressure",{pressure:C})}return v}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fast-forward",textAlign:"center",disabled:l===u,width:2.2,onClick:function(){function v(){return i("max_pressure")}return v}()})]}),(0,e.createComponentVNode)(2,b,{node_name:"Node 1",node_ref:s}),(0,e.createComponentVNode)(2,b,{node_name:"Node 2",node_ref:d})]})})})})}return y}(),b=function(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=S.node_name,l=S.node_ref;return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:m,children:[(0,e.createComponentVNode)(2,t.Button,{icon:"fast-backward",textAlign:"center",width:2.2,disabled:l===0,onClick:function(){function u(){return i("set_node",{node_name:m,concentration:(l-10)/100})}return u}()}),(0,e.createComponentVNode)(2,t.NumberInput,{animated:!0,unit:"%",width:6.1,lineHeight:1.5,stepPixelSize:10,minValue:0,maxValue:100,value:l,onChange:function(){function u(s,d){return i("set_node",{node_name:m,concentration:d/100})}return u}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fast-forward",textAlign:"center",width:2.2,disabled:l===100,onClick:function(){function u(){return i("set_node",{node_name:m,concentration:(l+10)/100})}return u}()})]})}},11748:function(T,r,n){"use strict";r.__esModule=!0,r.AtmosPump=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.AtmosPump=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.on,m=i.rate,l=i.max_rate,u=i.gas_unit,s=i.step;return(0,e.createComponentVNode)(2,o.Window,{width:330,height:110,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:(0,e.createComponentVNode)(2,t.Button,{icon:"power-off",content:c?"On":"Off",color:c?null:"red",selected:c,onClick:function(){function d(){return h("power")}return d}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Rate",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"fast-backward",textAlign:"center",disabled:m===0,width:2.2,onClick:function(){function d(){return h("min_rate")}return d}()}),(0,e.createComponentVNode)(2,t.NumberInput,{animated:!0,unit:u,width:6.1,lineHeight:1.5,step:s,minValue:0,maxValue:l,value:m,onDrag:function(){function d(v,g){return h("custom_rate",{rate:g})}return d}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fast-forward",textAlign:"center",disabled:m===l,width:2.2,onClick:function(){function d(){return h("max_rate")}return d}()})]})]})})})})}return b}()},69321:function(T,r,n){"use strict";r.__esModule=!0,r.AtmosTankControl=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(44879),p=n(76910),b=n(98595),y=r.AtmosTankControl=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.sensors||{};return(0,e.createComponentVNode)(2,b.Window,{width:400,height:400,children:(0,e.createComponentVNode)(2,b.Window.Content,{scrollable:!0,children:[Object.keys(l).map(function(u){return(0,e.createComponentVNode)(2,t.Section,{title:u,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[Object.keys(l[u]).indexOf("pressure")>-1?(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Pressure",children:[l[u].pressure," kpa"]}):"",Object.keys(l[u]).indexOf("temperature")>-1?(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Temperature",children:[l[u].temperature," K"]}):"",["o2","n2","plasma","co2","n2o"].map(function(s){return Object.keys(l[u]).indexOf(s)>-1?(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:(0,p.getGasLabel)(s),children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:(0,p.getGasColor)(s),value:l[u][s],minValue:0,maxValue:100,children:(0,o.toFixed)(l[u][s],2)+"%"})},(0,p.getGasLabel)(s)):""})]})},u)}),m.inlet&&Object.keys(m.inlet).length>0?(0,e.createComponentVNode)(2,t.Section,{title:"Inlet Control",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:(0,e.createComponentVNode)(2,t.Button,{icon:(m.inlet.on,"power-off"),content:m.inlet.on?"On":"Off",color:m.inlet.on?null:"red",selected:m.inlet.on,onClick:function(){function u(){return c("toggle_active",{dev:"inlet"})}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Rate",children:(0,e.createComponentVNode)(2,t.NumberInput,{animated:!0,unit:"L/s",width:6.1,lineHeight:1.5,step:1,minValue:0,maxValue:50,value:m.inlet.rate,onDrag:function(){function u(s,d){return c("set_pressure",{dev:"inlet",val:d})}return u}()})})]})}):"",m.outlet&&Object.keys(m.outlet).length>0?(0,e.createComponentVNode)(2,t.Section,{title:"Outlet Control",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:(0,e.createComponentVNode)(2,t.Button,{icon:(m.outlet.on,"power-off"),content:m.outlet.on?"On":"Off",color:m.outlet.on?null:"red",selected:m.outlet.on,onClick:function(){function u(){return c("toggle_active",{dev:"outlet"})}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Rate",children:(0,e.createComponentVNode)(2,t.NumberInput,{animated:!0,unit:"kPa",width:6.1,lineHeight:1.5,step:10,minValue:0,maxValue:5066,value:m.outlet.rate,onDrag:function(){function u(s,d){return c("set_pressure",{dev:"outlet",val:d})}return u}()})})]})}):""]})})}return S}()},92444:function(T,r,n){"use strict";r.__esModule=!0,r.AugmentMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(25328),b=r.AugmentMenu=function(){function k(h,i){return(0,e.createComponentVNode)(2,o.Window,{width:700,height:660,theme:"malfunction",children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:(0,e.createComponentVNode)(2,y,{context:i})})})})}return k}(),y=function(h){var i=h.context,c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.usable_swarms,s=l.ability_tabs,d=l.known_abilities,v=(0,a.useLocalState)(i,"selectedTab",s[0]),g=v[0],C=v[1],f=(0,a.useLocalState)(i,"searchText",""),N=f[0],V=f[1],B=function(){var E=s.find(function(D){return D.category_name===g.category_name});if(!E)return[];var P=Math.min(E.category_stage,4);return E.abilities.filter(function(D){return D.stage<=P&&(!N||D.name.toLowerCase().includes(N.toLowerCase()))}).sort(function(D,M){return["intruder","destroyer"].includes(g.category_name.toLowerCase())?D.stage-M.stage:0})},I=B(),L=s.find(function(x){return x.category_name===g.category_name}),w=["intruder","destroyer"].includes(g.category_name.toLowerCase()),A=function(E){var P=d.find(function(O){return O.ability_path===E.ability_path}),D=P?P.cost:E.cost,M=P&&P.current_level>0?P.current_level+" / "+P.max_level:"0 / "+E.max_level;return(0,e.createComponentVNode)(2,t.Stack.Item,{direction:"row",children:[(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Button,{height:"20px",width:"35px",mb:1,textAlign:"center",content:D,disabled:D>u||P&&P.current_level===P.max_level,tooltip:"Purchase this ability?",onClick:function(){function O(){m("purchase",{ability_path:E.ability_path}),C(g)}return O}()}),(0,e.createComponentVNode)(2,t.Stack.Item,{fontSize:"16px",children:E.name})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{fontSize:"13px",children:E.desc||"Description not available"}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:["Level: ",(0,e.createVNode)(1,"span",null,M,0,{style:{color:"green"}}),w&&E.stage>0&&(0,e.createVNode)(1,"span",null,[(0,e.createTextVNode)(" (Stage: "),E.stage,(0,e.createTextVNode)(")")],0)]}),(0,e.createComponentVNode)(2,t.Stack.Divider)]})})]},E.name)};return(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createVNode)(1,"div",null,[(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,style:{marginRight:"10px"},children:[(0,e.createVNode)(1,"span",null,[(0,e.createTextVNode)("Swarms: "),(0,e.createVNode)(1,"span",null,u,0,{style:{color:"green"}})],4),w&&L&&(0,e.createVNode)(1,"span",null,[(0,e.createTextVNode)("Category Stage: "),(0,e.createVNode)(1,"span",null,Math.min(L.category_stage,4),0,{style:{color:"green"}})],4)]}),(0,e.createVNode)(1,"div","Section__buttons",(0,e.createComponentVNode)(2,t.Input,{width:"200px",placeholder:"Search Abilities",onInput:function(){function x(E,P){return V(P)}return x}(),value:N}),2)],4,{style:{display:"flex",alignItems:"center"}}),children:[(0,e.createComponentVNode)(2,t.Tabs,{children:[s.map(function(x){return(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:g.category_name===x.category_name,onClick:function(){function E(){C(x),V("")}return E}(),children:(0,p.capitalize)(x.category_name)},x.category_name)}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:g.category_name==="upgrades",onClick:function(){function x(){return C({category_name:"upgrades"})}return x}(),children:"Upgrades"},"upgrades")]}),g.category_name==="upgrades"?(0,e.createComponentVNode)(2,S,{act:m,abilityTabs:s,knownAbilities:d,usableSwarms:u}):(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:I.map(A)})]})},S=function(h){var i=h.act,c=h.abilityTabs,m=h.knownAbilities,l=h.usableSwarms,u=m.filter(function(d){return d.current_levell,tooltip:"Upgrade this ability?",onClick:function(){function C(){return i("purchase",{ability_path:v.ability_path})}return C}()}),(0,e.createComponentVNode)(2,t.Stack.Item,{fontSize:"16px",children:v.name})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{fontSize:"13px",children:v.upgrade_text}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:["Level:"," ",(0,e.createVNode)(1,"span",null,v.current_level+" / "+v.max_level,0,{style:{color:"green"}}),g&&g.stage>0&&(0,e.createVNode)(1,"span",null,[(0,e.createTextVNode)(" (Stage: "),g.stage,(0,e.createTextVNode)(")")],0)]}),(0,e.createComponentVNode)(2,t.Stack.Divider)]})})]},v.name)};return(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:u.map(s)})}},59179:function(T,r,n){"use strict";r.__esModule=!0,r.Autolathe=void 0;var e=n(89005),a=n(64795),t=n(88510),o=n(72253),p=n(36036),b=n(98595),y=n(25328),S=function(i,c,m,l){return i.requirements===null?!0:!(i.requirements.metal*l>c||i.requirements.glass*l>m)},k=r.Autolathe=function(){function h(i,c){var m=(0,o.useBackend)(c),l=m.act,u=m.data,s=u.total_amount,d=u.max_amount,v=u.metal_amount,g=u.glass_amount,C=u.busyname,f=u.busyamt,N=u.showhacked,V=u.buildQueue,B=u.buildQueueLen,I=u.recipes,L=u.categories,w=(0,o.useSharedState)(c,"category",0),A=w[0],x=w[1];A===0&&(A="Tools");var E=v.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,"),P=g.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,"),D=s.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,"),M=(0,o.useSharedState)(c,"search_text",""),O=M[0],R=M[1],F=(0,y.createSearch)(O,function($){return $.name}),W="";B>0&&(W=V.map(function($,G){return(0,e.createComponentVNode)(2,p.Box,{children:(0,e.createComponentVNode)(2,p.Button,{fluid:!0,icon:"times",color:"transparent",content:V[G][0],onClick:function(){function X(){return l("remove_from_queue",{remove_from_queue:V.indexOf($)+1})}return X}()},$)},G)}));var U=(0,a.flow)([(0,t.filter)(function($){return($.category.indexOf(A)>-1||O)&&(u.showhacked||!$.hacked)}),O&&(0,t.filter)(F),(0,t.sortBy)(function($){return $.name.toLowerCase()})])(I),z="Build";return O?z="Results for: '"+O+"':":A&&(z="Build ("+A+")"),(0,e.createComponentVNode)(2,b.Window,{width:750,height:525,children:(0,e.createComponentVNode)(2,b.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,p.Stack,{fill:!0,horizontal:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{width:"70%",children:(0,e.createComponentVNode)(2,p.Section,{fill:!0,scrollable:!0,title:z,buttons:(0,e.createComponentVNode)(2,p.Dropdown,{width:"150px",options:L,selected:A,onSelected:function(){function $(G){return x(G)}return $}()}),children:[(0,e.createComponentVNode)(2,p.Input,{fluid:!0,placeholder:"Search for...",onInput:function(){function $(G,X){return R(X)}return $}(),mb:1}),U.map(function($){return(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,children:[(0,e.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+$.image,style:{"vertical-align":"middle",width:"32px",margin:"0px","margin-left":"0px"}}),(0,e.createComponentVNode)(2,p.Button,{mr:1,icon:"hammer",selected:u.busyname===$.name&&u.busyamt===1,disabled:!S($,u.metal_amount,u.glass_amount,1),onClick:function(){function G(){return l("make",{make:$.uid,multiplier:1})}return G}(),children:(0,y.toTitleCase)($.name)}),$.max_multiplier>=10&&(0,e.createComponentVNode)(2,p.Button,{mr:1,icon:"hammer",selected:u.busyname===$.name&&u.busyamt===10,disabled:!S($,u.metal_amount,u.glass_amount,10),onClick:function(){function G(){return l("make",{make:$.uid,multiplier:10})}return G}(),children:"10x"}),$.max_multiplier>=25&&(0,e.createComponentVNode)(2,p.Button,{mr:1,icon:"hammer",selected:u.busyname===$.name&&u.busyamt===25,disabled:!S($,u.metal_amount,u.glass_amount,25),onClick:function(){function G(){return l("make",{make:$.uid,multiplier:25})}return G}(),children:"25x"}),$.max_multiplier>25&&(0,e.createComponentVNode)(2,p.Button,{mr:1,icon:"hammer",selected:u.busyname===$.name&&u.busyamt===$.max_multiplier,disabled:!S($,u.metal_amount,u.glass_amount,$.max_multiplier),onClick:function(){function G(){return l("make",{make:$.uid,multiplier:$.max_multiplier})}return G}(),children:[$.max_multiplier,"x"]}),$.requirements&&Object.keys($.requirements).map(function(G){return(0,y.toTitleCase)(G)+": "+$.requirements[G]}).join(", ")||(0,e.createComponentVNode)(2,p.Box,{children:"No resources required."})]},$.ref)})]})}),(0,e.createComponentVNode)(2,p.Stack.Item,{width:"30%",children:[(0,e.createComponentVNode)(2,p.Section,{title:"Materials",children:(0,e.createComponentVNode)(2,p.LabeledList,{children:[(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Metal",children:E}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Glass",children:P}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Total",children:D}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Storage",children:[u.fill_percent,"% Full"]})]})}),(0,e.createComponentVNode)(2,p.Section,{title:"Building",children:(0,e.createComponentVNode)(2,p.Box,{color:C?"green":"",children:C||"Nothing"})}),(0,e.createComponentVNode)(2,p.Section,{title:"Build Queue",height:23.7,children:[W,(0,e.createComponentVNode)(2,p.Button,{mt:.5,fluid:!0,icon:"times",content:"Clear All",color:"red",disabled:!u.buildQueueLen,onClick:function(){function $(){return l("clear_queue")}return $}()})]})]})]})})})}return h}()},5147:function(T,r,n){"use strict";r.__esModule=!0,r.BioChipPad=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.BioChipPad=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.implant,m=i.contains_case,l=i.gps,u=i.tag,s=(0,a.useLocalState)(S,"newTag",u),d=s[0],v=s[1];return(0,e.createComponentVNode)(2,o.Window,{width:410,height:325,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Bio-chip Mini-Computer",buttons:(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Eject Case",icon:"eject",disabled:!m,onClick:function(){function g(){return h("eject_case")}return g}()})}),children:c&&m?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{bold:!0,mb:2,children:[(0,e.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+c.image,ml:0,mr:2,style:{"vertical-align":"middle",width:"32px"}}),c.name]}),(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Life",children:c.life}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Notes",children:c.notes}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Function",children:c.function}),!!l&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tag",children:[(0,e.createComponentVNode)(2,t.Input,{width:"5.5rem",value:u,onEnter:function(){function g(){return h("tag",{newtag:d})}return g}(),onInput:function(){function g(C,f){return v(f)}return g}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:u===d,width:"20px",mb:"0",ml:"0.25rem",onClick:function(){function g(){return h("tag",{newtag:d})}return g}(),children:(0,e.createComponentVNode)(2,t.Icon,{name:"pen"})})]})]})],4):m?(0,e.createComponentVNode)(2,t.Box,{children:"This bio-chip case has no implant!"}):(0,e.createComponentVNode)(2,t.Box,{children:"Please insert a bio-chip casing!"})})})})}return b}()},64273:function(T,r,n){"use strict";r.__esModule=!0,r.Biogenerator=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(62411),b=r.Biogenerator=function(){function i(c,m){var l=(0,a.useBackend)(m),u=l.data,s=l.config,d=u.container,v=u.processing,g=s.title;return(0,e.createComponentVNode)(2,o.Window,{width:390,height:595,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,p.Operating,{operating:v,name:g}),(0,e.createComponentVNode)(2,S),(0,e.createComponentVNode)(2,k),d?(0,e.createComponentVNode)(2,h):(0,e.createComponentVNode)(2,y)]})})})}return i}(),y=function(c,m){return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,textAlign:"center",align:"center",color:"silver",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"flask",size:5,mb:"10px"}),(0,e.createVNode)(1,"br"),"The biogenerator is missing a container."]})})})},S=function(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=s.biomass,v=s.container,g=s.container_curr_reagents,C=s.container_max_reagents;return(0,e.createComponentVNode)(2,t.Section,{title:"Storage",children:[(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{mr:"20px",color:"silver",children:"Biomass:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{mr:"5px",children:d}),(0,e.createComponentVNode)(2,t.Icon,{name:"leaf",size:1.2,color:"#3d8c40"})]}),(0,e.createComponentVNode)(2,t.Stack,{height:"21px",mt:"8px",align:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{mr:"10px",color:"silver",children:"Container:"}),v?(0,e.createComponentVNode)(2,t.ProgressBar,{value:g,maxValue:C,children:(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",children:g+" / "+C+" units"})}):(0,e.createComponentVNode)(2,t.Stack.Item,{children:"None"})]})]})},k=function(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=s.has_plants,v=s.container;return(0,e.createComponentVNode)(2,t.Section,{title:"Controls",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"30%",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"power-off",disabled:!d,tooltip:d?"":"There are no plants in the biogenerator.",tooltipPosition:"top-start",content:"Activate",onClick:function(){function g(){return u("activate")}return g}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"40%",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"flask",disabled:!v,tooltip:v?"":"The biogenerator does not have a container.",tooltipPosition:"top",content:"Detach Container",onClick:function(){function g(){return u("detach_container")}return g}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"30%",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"eject",disabled:!d,tooltip:d?"":"There are no stored plants to eject.",tooltipPosition:"top-end",content:"Eject Plants",onClick:function(){function g(){return u("eject_plants")}return g}()})})]})})},h=function(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=s.biomass,v=s.product_list,g=(0,a.useSharedState)(m,"vendAmount",1),C=g[0],f=g[1],N=Object.entries(v).map(function(V,B){var I=Object.entries(V[1]).map(function(L){return L[1]});return(0,e.createComponentVNode)(2,t.Collapsible,{title:V[0],open:!0,children:I.map(function(L){return(0,e.createComponentVNode)(2,t.Stack,{py:"2px",className:"candystripe",align:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"50%",ml:"2px",children:L.name}),(0,e.createComponentVNode)(2,t.Stack.Item,{textAlign:"right",width:"20%",children:[L.cost*C,(0,e.createComponentVNode)(2,t.Icon,{ml:"5px",name:"leaf",size:1.2,color:"#3d8c40"})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{textAlign:"right",width:"40%",children:(0,e.createComponentVNode)(2,t.Button,{content:"Vend",disabled:d.25?750+400*Math.random():290+150*Math.random(),time:60+150*Math.random(),children:(0,e.createComponentVNode)(2,t.Stack,{mb:"30px",fontsize:"256px",children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,color:"red",fontsize:"256px",textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"skull",size:14,mb:"64px"}),(0,e.createVNode)(1,"br"),"E$#OR:& U#KN!WN IN%ERF#R_NCE"]})})})})}return k}(),y=r.BluespaceTap=function(){function k(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.product||[],s=l.desiredMiningPower,d=l.miningPower,v=l.points,g=l.totalPoints,C=l.powerUse,f=l.availablePower,N=l.emagged,V=l.autoShutown,B=l.stabilizers,I=l.stabilizerPower,L=l.stabilizerPriority,w=s>d&&"bad"||"good";return(0,e.createComponentVNode)(2,o.Window,{width:650,height:450,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b),(0,e.createComponentVNode)(2,S),(0,e.createComponentVNode)(2,t.Collapsible,{title:"Input Management",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Input",children:[(0,e.createComponentVNode)(2,t.Button,{icon:V&&!N?"toggle-on":"toggle-off",content:"Auto shutdown",color:V&&!N?"green":"red",disabled:!!N,tooltip:"Turn auto shutdown on or off",tooltipPosition:"top",onClick:function(){function A(){return m("auto_shutdown")}return A}()}),(0,e.createComponentVNode)(2,t.Button,{icon:B&&!N?"toggle-on":"toggle-off",content:"Stabilizers",color:B&&!N?"green":"red",disabled:!!N,tooltip:"Turn stabilizers on or off",tooltipPosition:"top",onClick:function(){function A(){return m("stabilizers")}return A}()}),(0,e.createComponentVNode)(2,t.Button,{icon:L&&!N?"toggle-on":"toggle-off",content:"Stabilizer priority",color:L&&!N?"green":"red",disabled:!!N,tooltip:"On: Mining power will not exceed what can be stabilized",tooltipPosition:"top",onClick:function(){function A(){return m("stabilizer_priority")}return A}()}),(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Desired Mining Power",children:(0,p.formatPower)(s)}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{labelStyle:{"vertical-align":"top"},label:"Set Desired Mining Power",children:(0,e.createComponentVNode)(2,t.Stack,{width:"100%",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"step-backward",disabled:s===0||N,tooltip:"Set to 0",tooltipPosition:"bottom",onClick:function(){function A(){return m("set",{set_power:0})}return A}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fast-backward",tooltip:"Decrease by 10 MW",tooltipPosition:"bottom",disabled:s===0||N,onClick:function(){function A(){return m("set",{set_power:s-1e7})}return A}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"backward",disabled:s===0||N,tooltip:"Decrease by 1 MW",tooltipPosition:"bottom",onClick:function(){function A(){return m("set",{set_power:s-1e6})}return A}()})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{mx:1,children:(0,e.createComponentVNode)(2,t.NumberInput,{disabled:N,minvalue:0,value:s,maxvalue:1/0,step:1,onChange:function(){function A(x,E){return m("set",{set_power:E})}return A}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"forward",disabled:N,tooltip:"Increase by one MW",tooltipPosition:"bottom",onClick:function(){function A(){return m("set",{set_power:s+1e6})}return A}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fast-forward",disabled:N,tooltip:"Increase by 10MW",tooltipPosition:"bottom",onClick:function(){function A(){return m("set",{set_power:s+1e7})}return A}()})]})]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Total Power Use",children:(0,p.formatPower)(C)}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Mining Power Use",children:(0,p.formatPower)(d)}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Stabilizer Power Use",children:(0,p.formatPower)(I)}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Surplus Power",children:(0,p.formatPower)(f)})]})]})}),(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Output",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Available Points",children:v}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Total Points",children:g})]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{align:"end",children:(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:u.map(function(A){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:A.name,children:(0,e.createComponentVNode)(2,t.Button,{disabled:A.price>=v,onClick:function(){function x(){return m("vend",{target:A.key})}return x}(),content:A.price})},A.key)})})})})]})})]})})})}return k}(),S=r.Alerts=function(){function k(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.product||[],s=l.miningPower,d=l.stabilizerPower,v=l.emagged,g=l.safeLevels,C=l.autoShutown,f=l.stabilizers,N=l.overhead;return(0,e.createFragment)([!C&&!v&&(0,e.createComponentVNode)(2,t.NoticeBox,{danger:1,children:"Auto shutdown disabled"}),v?(0,e.createComponentVNode)(2,t.NoticeBox,{danger:1,children:"All safeties disabled"}):s<=15e6?"":f?s>d+15e6?(0,e.createComponentVNode)(2,t.NoticeBox,{danger:1,children:"Stabilizers overwhelmed, Instability likely"}):(0,e.createComponentVNode)(2,t.NoticeBox,{children:"High Power, engaging stabilizers"}):(0,e.createComponentVNode)(2,t.NoticeBox,{danger:1,children:"Stabilizers disabled, Instability likely"})],0)}return k}()},33758:function(T,r,n){"use strict";r.__esModule=!0,r.BodyScanner=void 0;var e=n(89005),a=n(44879),t=n(25328),o=n(72253),p=n(36036),b=n(98595),y=[["good","Alive"],["average","Critical"],["bad","DEAD"]],S=[["hasVirus","bad","Viral pathogen detected in blood stream."],["blind","average","Cataracts detected."],["colourblind","average","Photoreceptor abnormalities detected."],["nearsighted","average","Retinal misalignment detected."]],k=[["Respiratory","oxyLoss"],["Brain","brainLoss"],["Toxin","toxLoss"],["Radiation","radLoss"],["Brute","bruteLoss"],["Cellular","cloneLoss"],["Burn","fireLoss"],["Inebriation","drunkenness"]],h={average:[.25,.5],bad:[.5,1/0]},i=function(B,I){for(var L=[],w=0;w0?B.filter(function(I){return!!I}).reduce(function(I,L){return(0,e.createFragment)([I,(0,e.createComponentVNode)(2,p.Box,{children:L},L)],0)},null):null},m=function(B){if(B>100){if(B<300)return"mild infection";if(B<400)return"mild infection+";if(B<500)return"mild infection++";if(B<700)return"acute infection";if(B<800)return"acute infection+";if(B<900)return"acute infection++";if(B>=900)return"septic"}return""},l=r.BodyScanner=function(){function V(B,I){var L=(0,o.useBackend)(I),w=L.data,A=w.occupied,x=w.occupant,E=x===void 0?{}:x,P=A?(0,e.createComponentVNode)(2,u,{occupant:E}):(0,e.createComponentVNode)(2,N);return(0,e.createComponentVNode)(2,b.Window,{width:700,height:600,title:"Body Scanner",children:(0,e.createComponentVNode)(2,b.Window.Content,{scrollable:!0,children:P})})}return V}(),u=function(B){var I=B.occupant;return(0,e.createComponentVNode)(2,p.Box,{children:[(0,e.createComponentVNode)(2,s,{occupant:I}),(0,e.createComponentVNode)(2,d,{occupant:I}),(0,e.createComponentVNode)(2,v,{occupant:I}),(0,e.createComponentVNode)(2,C,{organs:I.extOrgan}),(0,e.createComponentVNode)(2,f,{organs:I.intOrgan})]})},s=function(B,I){var L=(0,o.useBackend)(I),w=L.act,A=L.data,x=A.occupant;return(0,e.createComponentVNode)(2,p.Section,{title:"Occupant",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,p.Button,{icon:"print",onClick:function(){function E(){return w("print_p")}return E}(),children:"Print Report"}),(0,e.createComponentVNode)(2,p.Button,{icon:"user-slash",onClick:function(){function E(){return w("ejectify")}return E}(),children:"Eject"})],4),children:(0,e.createComponentVNode)(2,p.LabeledList,{children:[(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Name",children:x.name}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Health",children:(0,e.createComponentVNode)(2,p.ProgressBar,{min:"0",max:x.maxHealth,value:x.health/x.maxHealth,ranges:{good:[.5,1/0],average:[0,.5],bad:[-1/0,0]}})}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Status",color:y[x.stat][0],children:y[x.stat][1]}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Temperature",children:[(0,e.createComponentVNode)(2,p.AnimatedNumber,{value:(0,a.round)(x.bodyTempC)}),"\xB0C,\xA0",(0,e.createComponentVNode)(2,p.AnimatedNumber,{value:(0,a.round)(x.bodyTempF)}),"\xB0F"]}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Implants",children:x.implant_len?(0,e.createComponentVNode)(2,p.Box,{children:x.implant.map(function(E){return E.name}).join(", ")}):(0,e.createComponentVNode)(2,p.Box,{color:"label",children:"None"})})]})})},d=function(B){var I=B.occupant;return I.hasBorer||I.blind||I.colourblind||I.nearsighted||I.hasVirus?(0,e.createComponentVNode)(2,p.Section,{title:"Abnormalities",children:S.map(function(L,w){if(I[L[0]])return(0,e.createComponentVNode)(2,p.Box,{color:L[1],bold:L[1]==="bad",children:L[2]},L[2])})}):(0,e.createComponentVNode)(2,p.Section,{title:"Abnormalities",children:(0,e.createComponentVNode)(2,p.Box,{color:"label",children:"No abnormalities found."})})},v=function(B){var I=B.occupant;return(0,e.createComponentVNode)(2,p.Section,{title:"Damage",children:(0,e.createComponentVNode)(2,p.Table,{children:i(k,function(L,w,A){return(0,e.createFragment)([(0,e.createComponentVNode)(2,p.Table.Row,{color:"label",children:[(0,e.createComponentVNode)(2,p.Table.Cell,{children:[L[0],":"]}),(0,e.createComponentVNode)(2,p.Table.Cell,{children:!!w&&w[0]+":"})]}),(0,e.createComponentVNode)(2,p.Table.Row,{children:[(0,e.createComponentVNode)(2,p.Table.Cell,{children:(0,e.createComponentVNode)(2,g,{value:I[L[1]],marginBottom:A100)&&"average"||!!I.status.robotic&&"label",width:"33%",children:(0,t.capitalize)(I.name)}),(0,e.createComponentVNode)(2,p.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,p.ProgressBar,{m:-.5,min:"0",max:I.maxHealth,mt:L>0&&"0.5rem",value:I.totalLoss/I.maxHealth,ranges:h,children:(0,e.createComponentVNode)(2,p.Stack,{children:[(0,e.createComponentVNode)(2,p.Tooltip,{content:"Total damage",children:(0,e.createComponentVNode)(2,p.Stack.Item,{children:[(0,e.createComponentVNode)(2,p.Icon,{name:"heartbeat",mr:.5}),(0,a.round)(I.totalLoss)]})}),!!I.bruteLoss&&(0,e.createComponentVNode)(2,p.Tooltip,{content:"Brute damage",children:(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,children:[(0,e.createComponentVNode)(2,p.Icon,{name:"bone",mr:.5}),(0,a.round)(I.bruteLoss)]})}),!!I.fireLoss&&(0,e.createComponentVNode)(2,p.Tooltip,{content:"Burn damage",children:(0,e.createComponentVNode)(2,p.Stack.Item,{children:[(0,e.createComponentVNode)(2,p.Icon,{name:"fire",mr:.5}),(0,a.round)(I.fireLoss)]})})]})})}),(0,e.createComponentVNode)(2,p.Table.Cell,{textAlign:"right",verticalAlign:"top",width:"33%",pt:L>0&&"calc(0.5rem + 2px)",children:[(0,e.createComponentVNode)(2,p.Box,{color:"average",inline:!0,children:c([!!I.internalBleeding&&"Internal bleeding",!!I.burnWound&&"Critical tissue burns",!!I.lungRuptured&&"Ruptured lung",!!I.status.broken&&I.status.broken,m(I.germ_level),!!I.open&&"Open incision"])}),(0,e.createComponentVNode)(2,p.Box,{inline:!0,children:[c([!!I.status.splinted&&(0,e.createComponentVNode)(2,p.Box,{color:"good",children:"Splinted"}),!!I.status.robotic&&(0,e.createComponentVNode)(2,p.Box,{color:"label",children:"Robotic"}),!!I.status.dead&&(0,e.createComponentVNode)(2,p.Box,{color:"bad",bold:!0,children:"DEAD"})]),c(I.shrapnel.map(function(w){return w.known?w.name:"Unknown object"}))]})]})]},L)})]})})},f=function(B){return B.organs.length===0?(0,e.createComponentVNode)(2,p.Section,{title:"Internal Organs",children:(0,e.createComponentVNode)(2,p.Box,{color:"label",children:"N/A"})}):(0,e.createComponentVNode)(2,p.Section,{title:"Internal Organs",children:(0,e.createComponentVNode)(2,p.Table,{children:[(0,e.createComponentVNode)(2,p.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,p.Table.Cell,{children:"Name"}),(0,e.createComponentVNode)(2,p.Table.Cell,{textAlign:"center",children:"Damage"}),(0,e.createComponentVNode)(2,p.Table.Cell,{textAlign:"right",children:"Injuries"})]}),B.organs.map(function(I,L){return(0,e.createComponentVNode)(2,p.Table.Row,{children:[(0,e.createComponentVNode)(2,p.Table.Cell,{color:!!I.dead&&"bad"||I.germ_level>100&&"average"||I.robotic>0&&"label",width:"33%",children:(0,t.capitalize)(I.name)}),(0,e.createComponentVNode)(2,p.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,p.ProgressBar,{min:"0",max:I.maxHealth,value:I.damage/I.maxHealth,mt:L>0&&"0.5rem",ranges:h,children:(0,a.round)(I.damage)})}),(0,e.createComponentVNode)(2,p.Table.Cell,{textAlign:"right",verticalAlign:"top",width:"33%",pt:L>0&&"calc(0.5rem + 2px)",children:[(0,e.createComponentVNode)(2,p.Box,{color:"average",inline:!0,children:c([m(I.germ_level)])}),(0,e.createComponentVNode)(2,p.Box,{inline:!0,children:c([I.robotic===1&&(0,e.createComponentVNode)(2,p.Box,{color:"label",children:"Robotic"}),I.robotic===2&&(0,e.createComponentVNode)(2,p.Box,{color:"label",children:"Assisted"}),!!I.dead&&(0,e.createComponentVNode)(2,p.Box,{color:"bad",bold:!0,children:"DEAD"})])})]})]},L)})]})})},N=function(){return(0,e.createComponentVNode)(2,p.Section,{fill:!0,children:(0,e.createComponentVNode)(2,p.Stack,{fill:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,p.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),"No occupant detected."]})})})}},67963:function(T,r,n){"use strict";r.__esModule=!0,r.BookBinder=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(3939),b=n(39473),y=r.BookBinder=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.selectedbook,u=m.book_categories,s=[];return u.map(function(d){return s[d.description]=d.category_id}),(0,e.createComponentVNode)(2,o.Window,{width:600,height:400,children:[(0,e.createComponentVNode)(2,p.ComplexModal),(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Book Binder",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"print",width:"auto",content:"Print Book",onClick:function(){function d(){return c("print_book")}return d}()}),children:[(0,e.createComponentVNode)(2,t.Box,{ml:10,fontSize:"1.2rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"search-plus",verticalAlign:"middle",size:3,mr:"1rem"}),"Book Binder"]}),(0,e.createComponentVNode)(2,t.Stack,{children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Title",children:(0,e.createComponentVNode)(2,t.Button,{textAlign:"left",icon:"pen",width:"auto",content:l.title,onClick:function(){function d(){return(0,p.modalOpen)(h,"edit_selected_title")}return d}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Author",children:(0,e.createComponentVNode)(2,t.Button,{textAlign:"left",icon:"pen",width:"auto",content:l.author,onClick:function(){function d(){return(0,p.modalOpen)(h,"edit_selected_author")}return d}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Select Categories",children:(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Dropdown,{width:"190px",options:u.map(function(d){return d.description}),onSelected:function(){function d(v){return c("toggle_binder_category",{category_id:s[v]})}return d}()})})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Summary",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pen",width:"auto",content:"Edit Summary",onClick:function(){function d(){return(0,p.modalOpen)(h,"edit_selected_summary")}return d}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{children:l.summary})]}),(0,e.createVNode)(1,"br"),u.filter(function(d){return l.categories.includes(d.category_id)}).map(function(d){return(0,e.createComponentVNode)(2,t.Button,{content:d.description,selected:!0,icon:"unlink",onClick:function(){function v(){return c("toggle_binder_category",{category_id:d.category_id})}return v}()},d.category_id)})]})})]})})})]})}return S}()},61925:function(T,r,n){"use strict";r.__esModule=!0,r.BotCall=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=function(i){var c=[{modes:[0],label:"Idle",color:"green"},{modes:[1,2,3],label:"Arresting",color:"yellow"},{modes:[4,5],label:"Patrolling",color:"average"},{modes:[9],label:"Moving",color:"average"},{modes:[6,11],label:"Responding",color:"green"},{modes:[12],label:"Delivering Cargo",color:"blue"},{modes:[13],label:"Returning Home",color:"blue"},{modes:[7,8,10,14,15,16,17,18,19],label:"Working",color:"blue"}],m=c.find(function(l){return l.modes.includes(i)});return(0,e.createComponentVNode)(2,t.Box,{color:m.color,children:[" ",m.label," "]})},b=r.BotCall=function(){function h(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=(0,a.useLocalState)(c,"tabIndex",0),d=s[0],v=s[1],g={0:"Security",1:"Medibot",2:"Cleanbot",3:"Floorbot",4:"Mule",5:"Honkbot"},C=function(){function f(N){return g[N]?(0,e.createComponentVNode)(2,y,{model:g[N]}):"This should not happen. Report on Paradise Github"}return f}();return(0,e.createComponentVNode)(2,o.Window,{width:700,height:400,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:d===0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Tabs,{fluid:!0,textAlign:"center",children:Array.from({length:6}).map(function(f,N){return(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:d===N,onClick:function(){function V(){return v(N)}return V}(),children:g[N]},N)})})}),C(d)]})})})}return h}(),y=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.bots;return s[i.model]!==void 0?(0,e.createComponentVNode)(2,k,{model:[i.model]}):(0,e.createComponentVNode)(2,S,{model:[i.model]})},S=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data;return(0,e.createComponentVNode)(2,t.Stack,{justify:"center",align:"center",fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,t.Box,{bold:1,color:"bad",children:["No ",[i.model]," detected"]})})},k=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.bots;return(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Name"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Model"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Status"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Location"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Interface"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Call"})]}),s[i.model].map(function(d){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.name}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.model}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.on?p(d.status):(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Off"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.location}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Interface",onClick:function(){function v(){return l("interface",{botref:d.UID})}return v}()})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Call",onClick:function(){function v(){return l("call",{botref:d.UID})}return v}()})})]},d.UID)})]})})})}},20464:function(T,r,n){"use strict";r.__esModule=!0,r.BotClean=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(92963),b=r.BotClean=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.locked,l=c.noaccess,u=c.maintpanel,s=c.on,d=c.autopatrol,v=c.canhack,g=c.emagged,C=c.remote_disabled,f=c.painame,N=c.cleanblood,V=c.area;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:400,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,p.BotStatus),(0,e.createComponentVNode)(2,t.Section,{title:"Cleaning Settings",children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:N,content:"Clean Blood",disabled:l,onClick:function(){function B(){return i("blood")}return B}()})}),(0,e.createComponentVNode)(2,t.Section,{title:"Misc Settings",children:[(0,e.createComponentVNode)(2,t.Button,{fluid:!0,content:V?"Reset Area Selection":"Restrict to Current Area",onClick:function(){function B(){return i("area")}return B}()}),V!==null&&(0,e.createComponentVNode)(2,t.LabeledList,{mb:1,children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Locked Area",children:V})})]}),f&&(0,e.createComponentVNode)(2,t.Section,{title:"pAI",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"eject",content:f,disabled:l,onClick:function(){function B(){return i("ejectpai")}return B}()})})]})})}return y}()},69479:function(T,r,n){"use strict";r.__esModule=!0,r.BotFloor=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(92963),b=r.BotFloor=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.noaccess,l=c.painame,u=c.hullplating,s=c.replace,d=c.eat,v=c.make,g=c.fixfloor,C=c.nag_empty,f=c.magnet,N=c.tiles_amount;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:510,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,p.BotStatus),(0,e.createComponentVNode)(2,t.Section,{title:"Floor Settings",children:[(0,e.createComponentVNode)(2,t.Box,{mb:"5px",children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tiles Left",children:N})}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:u,content:"Add tiles to new hull plating",tooltip:"Fixing a plating requires the removal of floor tile. This will place it back after repairing. Same goes for hull breaches",disabled:m,onClick:function(){function V(){return i("autotile")}return V}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:s,content:"Add floor tiles on exposed hull plating",tooltip:"Example: It will add tiles to maintenance",disabled:m,onClick:function(){function V(){return i("replacetiles")}return V}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:g,content:"Repair damaged tiles and platings",disabled:m,onClick:function(){function V(){return i("fixfloors")}return V}()})]}),(0,e.createComponentVNode)(2,t.Section,{title:"Miscellaneous",children:[(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:d,content:"Finds tiles",disabled:m,onClick:function(){function V(){return i("eattiles")}return V}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:v,content:"Make pieces of metal into tiles when empty",disabled:m,onClick:function(){function V(){return i("maketiles")}return V}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:C,content:"Transmit notice when empty",disabled:m,onClick:function(){function V(){return i("nagonempty")}return V}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:f,content:"Traction Magnets",disabled:m,onClick:function(){function V(){return i("anchored")}return V}()})]}),l&&(0,e.createComponentVNode)(2,t.Section,{title:"pAI",children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,icon:"eject",content:l,disabled:m,onClick:function(){function V(){return i("ejectpai")}return V}()})})]})})}return y}()},59887:function(T,r,n){"use strict";r.__esModule=!0,r.BotHonk=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(92963),b=r.BotHonk=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:220,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,p.BotStatus)})})}return y}()},80063:function(T,r,n){"use strict";r.__esModule=!0,r.BotMed=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(92963),b=r.BotMed=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.locked,l=c.noaccess,u=c.maintpanel,s=c.on,d=c.autopatrol,v=c.canhack,g=c.emagged,C=c.remote_disabled,f=c.painame,N=c.shut_up,V=c.declare_crit,B=c.stationary_mode,I=c.heal_threshold,L=c.injection_amount,w=c.use_beaker,A=c.treat_virus,x=c.reagent_glass;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:500,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,p.BotStatus),(0,e.createComponentVNode)(2,t.Section,{title:"Communication Settings",children:[(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,content:"Speaker",checked:!N,disabled:l,onClick:function(){function E(){return i("toggle_speaker")}return E}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,content:"Critical Patient Alerts",checked:V,disabled:l,onClick:function(){function E(){return i("toggle_critical_alerts")}return E}()})]}),(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Treatment Settings",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Healing Threshold",children:(0,e.createComponentVNode)(2,t.Slider,{value:I.value,minValue:I.min,maxValue:I.max,step:5,disabled:l,onChange:function(){function E(P,D){return i("set_heal_threshold",{target:D})}return E}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Injection Level",children:(0,e.createComponentVNode)(2,t.Slider,{value:L.value,minValue:L.min,maxValue:L.max,step:5,format:function(){function E(P){return P+"u"}return E}(),disabled:l,onChange:function(){function E(P,D){return i("set_injection_amount",{target:D})}return E}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Reagent Source",children:(0,e.createComponentVNode)(2,t.Button,{content:w?"Beaker":"Internal Synthesizer",icon:w?"flask":"cogs",disabled:l,onClick:function(){function E(){return i("toggle_use_beaker")}return E}()})}),x&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Beaker",children:(0,e.createComponentVNode)(2,t.Stack,{inline:!0,width:"100%",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:1,children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:x.amount,minValue:0,maxValue:x.max_amount,children:[x.amount," / ",x.max_amount]})}),(0,e.createComponentVNode)(2,t.Stack.Item,{ml:1,children:(0,e.createComponentVNode)(2,t.Button,{content:"Eject",disabled:l,onClick:function(){function E(){return i("eject_reagent_glass")}return E}()})})]})})]}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{mt:1,fluid:!0,content:"Treat Viral Infections",checked:A,disabled:l,onClick:function(){function E(){return i("toggle_treat_viral")}return E}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,content:"Stationary Mode",checked:B,disabled:l,onClick:function(){function E(){return i("toggle_stationary_mode")}return E}()})]}),f&&(0,e.createComponentVNode)(2,t.Section,{title:"pAI",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"eject",content:f,disabled:l,onClick:function(){function E(){return i("ejectpai")}return E}()})})]})})})}return y}()},74439:function(T,r,n){"use strict";r.__esModule=!0,r.BotSecurity=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(92963),b=r.BotSecurity=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.noaccess,l=c.painame,u=c.check_id,s=c.check_weapons,d=c.check_warrant,v=c.arrest_mode,g=c.arrest_declare;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:445,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,p.BotStatus),(0,e.createComponentVNode)(2,t.Section,{title:"Who To Arrest",children:[(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:u,content:"Unidentifiable Persons",disabled:m,onClick:function(){function C(){return i("authid")}return C}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:s,content:"Unauthorized Weapons",disabled:m,onClick:function(){function C(){return i("authweapon")}return C}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:d,content:"Wanted Criminals",disabled:m,onClick:function(){function C(){return i("authwarrant")}return C}()})]}),(0,e.createComponentVNode)(2,t.Section,{title:"Arrest Procedure",children:[(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:v,content:"Detain Targets Indefinitely",disabled:m,onClick:function(){function C(){return i("arrtype")}return C}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:g,content:"Announce Arrests On Radio",disabled:m,onClick:function(){function C(){return i("arrdeclare")}return C}()})]}),l&&(0,e.createComponentVNode)(2,t.Section,{title:"pAI",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"eject",content:l,disabled:m,onClick:function(){function C(){return i("ejectpai")}return C}()})})]})})}return y}()},10833:function(T,r,n){"use strict";r.__esModule=!0,r.BrigCells=void 0;var e=n(89005),a=n(98595),t=n(36036),o=n(72253),p=function(k,h){var i=k.cell,c=(0,o.useBackend)(h),m=c.act,l=i.cell_id,u=i.occupant,s=i.crimes,d=i.brigged_by,v=i.time_left_seconds,g=i.time_set_seconds,C=i.ref,f="";v>0&&(f+=" BrigCells__listRow--active");var N=function(){m("release",{ref:C})};return(0,e.createComponentVNode)(2,t.Table.Row,{className:f,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:l}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:u}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:s}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.TimeDisplay,{totalSeconds:g})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.TimeDisplay,{totalSeconds:v})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{type:"button",onClick:N,children:"Release"})})]})},b=function(k){var h=k.cells;return(0,e.createComponentVNode)(2,t.Table,{className:"BrigCells__list",children:[(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{header:!0,children:"Cell"}),(0,e.createComponentVNode)(2,t.Table.Cell,{header:!0,children:"Occupant"}),(0,e.createComponentVNode)(2,t.Table.Cell,{header:!0,children:"Crimes"}),(0,e.createComponentVNode)(2,t.Table.Cell,{header:!0,children:"Brigged By"}),(0,e.createComponentVNode)(2,t.Table.Cell,{header:!0,children:"Time Brigged For"}),(0,e.createComponentVNode)(2,t.Table.Cell,{header:!0,children:"Time Left"}),(0,e.createComponentVNode)(2,t.Table.Cell,{header:!0,children:"Release"})]}),h.map(function(i){return(0,e.createComponentVNode)(2,p,{cell:i},i.ref)})]})},y=r.BrigCells=function(){function S(k,h){var i=(0,o.useBackend)(h),c=i.act,m=i.data,l=m.cells;return(0,e.createComponentVNode)(2,a.Window,{theme:"security",width:800,height:400,children:(0,e.createComponentVNode)(2,a.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,b,{cells:l})})})})})}return S}()},45761:function(T,r,n){"use strict";r.__esModule=!0,r.BrigTimer=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.BrigTimer=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data;i.nameText=i.occupant,i.timing&&(i.prisoner_hasrec?i.nameText=(0,e.createComponentVNode)(2,t.Box,{color:"green",children:i.occupant}):i.nameText=(0,e.createComponentVNode)(2,t.Box,{color:"red",children:i.occupant}));var c="pencil-alt";i.prisoner_name&&(i.prisoner_hasrec||(c="exclamation-triangle"));var m=[],l=0;for(l=0;lm?this.substring(0,m)+"...":this};var k=function(l,u){var s,d;if(!u)return[];var v=l.findIndex(function(g){return g.name===u.name});return[(s=l[v-1])==null?void 0:s.name,(d=l[v+1])==null?void 0:d.name]},h=function(l,u){u===void 0&&(u="");var s=(0,p.createSearch)(u,function(d){return d.name});return(0,t.flow)([(0,a.filter)(function(d){return d==null?void 0:d.name}),u&&(0,a.filter)(s),(0,a.sortBy)(function(d){return d.name})])(l)},i=r.CameraConsole=function(){function m(l,u){var s=(0,b.useBackend)(u),d=s.act,v=s.data,g=s.config,C=v.mapRef,f=v.activeCamera,N=h(v.cameras),V=k(N,f),B=V[0],I=V[1];return(0,e.createComponentVNode)(2,S.Window,{width:870,height:708,children:[(0,e.createVNode)(1,"div","CameraConsole__left",(0,e.createComponentVNode)(2,S.Window.Content,{children:(0,e.createComponentVNode)(2,y.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,c)})}),2),(0,e.createVNode)(1,"div","CameraConsole__right",[(0,e.createVNode)(1,"div","CameraConsole__toolbar",[(0,e.createVNode)(1,"b",null,"Camera: ",16),f&&f.name||"\u2014"],0),(0,e.createVNode)(1,"div","CameraConsole__toolbarRight",[(0,e.createComponentVNode)(2,y.Button,{icon:"chevron-left",disabled:!B,onClick:function(){function L(){return d("switch_camera",{name:B})}return L}()}),(0,e.createComponentVNode)(2,y.Button,{icon:"chevron-right",disabled:!I,onClick:function(){function L(){return d("switch_camera",{name:I})}return L}()})],4),(0,e.createComponentVNode)(2,y.ByondUi,{className:"CameraConsole__map",params:{id:C,type:"map"}})],4)]})}return m}(),c=r.CameraConsoleContent=function(){function m(l,u){var s=(0,b.useBackend)(u),d=s.act,v=s.data,g=(0,b.useLocalState)(u,"searchText",""),C=g[0],f=g[1],N=v.activeCamera,V=h(v.cameras,C);return(0,e.createComponentVNode)(2,y.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,y.Stack.Item,{children:(0,e.createComponentVNode)(2,y.Input,{fluid:!0,placeholder:"Search for a camera",onInput:function(){function B(I,L){return f(L)}return B}()})}),(0,e.createComponentVNode)(2,y.Stack.Item,{grow:!0,m:0,children:(0,e.createComponentVNode)(2,y.Section,{fill:!0,scrollable:!0,children:V.map(function(B){return(0,e.createVNode)(1,"div",(0,o.classes)(["Button","Button--fluid","Button--color--transparent",N&&B.name===N.name&&"Button--selected"]),B.name.trimLongStr(23),0,{title:B.name,onClick:function(){function I(){return d("switch_camera",{name:B.name})}return I}()},B.name)})})})]})}return m}()},52927:function(T,r,n){"use strict";r.__esModule=!0,r.Canister=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=n(49968),b=n(98595),y=r.Canister=function(){function S(k,h){var i=(0,t.useBackend)(h),c=i.act,m=i.data,l=m.portConnected,u=m.tankPressure,s=m.releasePressure,d=m.defaultReleasePressure,v=m.minReleasePressure,g=m.maxReleasePressure,C=m.valveOpen,f=m.name,N=m.canLabel,V=m.colorContainer,B=m.color_index,I=m.hasHoldingTank,L=m.holdingTank,w="";B.prim&&(w=V.prim.options[B.prim].name);var A="";B.sec&&(A=V.sec.options[B.sec].name);var x="";B.ter&&(x=V.ter.options[B.ter].name);var E="";B.quart&&(E=V.quart.options[B.quart].name);var P=[],D=[],M=[],O=[],R=0;for(R=0;Rf.current_positions&&(0,e.createComponentVNode)(2,t.Box,{color:"green",children:f.total_positions-f.current_positions})||(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"0"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{content:"-",disabled:d.cooldown_time||!f.can_close,onClick:function(){function N(){return s("make_job_unavailable",{job:f.title})}return N}()})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{content:"+",disabled:d.cooldown_time||!f.can_open,onClick:function(){function N(){return s("make_job_available",{job:f.title})}return N}()})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:d.target_dept&&(0,e.createComponentVNode)(2,t.Box,{color:"green",children:d.priority_jobs.indexOf(f.title)>-1?"Yes":""})||(0,e.createComponentVNode)(2,t.Button,{content:f.is_priority?"Yes":"No",selected:f.is_priority,disabled:d.cooldown_time||!f.can_prioritize,onClick:function(){function N(){return s("prioritize_job",{job:f.title})}return N}()})})]},f.title)})]})})]}):C=(0,e.createComponentVNode)(2,S);break;case 2:!d.authenticated||!d.scan_name?C=(0,e.createComponentVNode)(2,S):d.modify_name?C=(0,e.createComponentVNode)(2,p.AccessList,{accesses:d.regions,selectedList:d.selectedAccess,accessMod:function(){function f(N){return s("set",{access:N})}return f}(),grantAll:function(){function f(){return s("grant_all")}return f}(),denyAll:function(){function f(){return s("clear_all")}return f}(),grantDep:function(){function f(N){return s("grant_region",{region:N})}return f}(),denyDep:function(){function f(N){return s("deny_region",{region:N})}return f}()}):C=(0,e.createComponentVNode)(2,k);break;case 3:d.authenticated?d.records.length?C=(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Records",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"times",content:"Delete All Records",disabled:!d.authenticated||d.records.length===0||d.target_dept,onClick:function(){function f(){return s("wipe_all_logs")}return f}()}),children:[(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{height:2,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Crewman"}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Old Rank"}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"New Rank"}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Authorized By"}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Time"}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Reason"}),!!d.iscentcom&&(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Deleted By"})]}),d.records.map(function(f){return(0,e.createComponentVNode)(2,t.Table.Row,{height:2,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.transferee}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.oldvalue}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.newvalue}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.whodidit}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.timestamp}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.reason}),!!d.iscentcom&&(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.deletedby})]},f.timestamp)})]}),!!d.iscentcom&&(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:"Delete MY Records",color:"purple",disabled:!d.authenticated||d.records.length===0,onClick:function(){function f(){return s("wipe_my_logs")}return f}()})})]}):C=(0,e.createComponentVNode)(2,h):C=(0,e.createComponentVNode)(2,S);break;case 4:!d.authenticated||!d.scan_name?C=(0,e.createComponentVNode)(2,S):C=(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Your Team",children:(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{height:2,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Name"}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Rank"}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Sec Status"}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Actions"})]}),d.people_dept.map(function(f){return(0,e.createComponentVNode)(2,t.Table.Row,{height:2,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.name}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.title}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.crimstat}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:f.buttontext,disabled:!f.demotable,onClick:function(){function N(){return s("remote_demote",{remote_demote:f.name})}return N}()})})]},f.title)})]})});break;default:C=(0,e.createComponentVNode)(2,t.Section,{title:"Warning",color:"red",children:"ERROR: Unknown Mode."})}return(0,e.createComponentVNode)(2,o.Window,{width:800,height:800,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:g}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:v}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:C})]})})})}return c}()},64083:function(T,r,n){"use strict";r.__esModule=!0,r.CargoConsole=void 0;var e=n(89005),a=n(64795),t=n(88510),o=n(72253),p=n(36036),b=n(98595),y=n(25328),S=r.CargoConsole=function(){function u(s,d){return(0,e.createComponentVNode)(2,b.Window,{width:900,height:800,children:(0,e.createComponentVNode)(2,b.Window.Content,{children:(0,e.createComponentVNode)(2,p.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,k),(0,e.createComponentVNode)(2,h),(0,e.createComponentVNode)(2,i),(0,e.createComponentVNode)(2,c),(0,e.createComponentVNode)(2,l)]})})})}return u}(),k=function(s,d){var v=(0,o.useLocalState)(d,"contentsModal",null),g=v[0],C=v[1],f=(0,o.useLocalState)(d,"contentsModalTitle",null),N=f[0],V=f[1];if(g!==null&&N!==null)return(0,e.createComponentVNode)(2,p.Modal,{maxWidth:"75%",width:window.innerWidth+"px",maxHeight:window.innerHeight*.75+"px",mx:"auto",children:[(0,e.createComponentVNode)(2,p.Box,{width:"100%",bold:!0,children:(0,e.createVNode)(1,"h1",null,[N,(0,e.createTextVNode)(" contents:")],0)}),(0,e.createComponentVNode)(2,p.Box,{children:g.map(function(B){return(0,e.createComponentVNode)(2,p.Box,{children:["- ",B]},B)})}),(0,e.createComponentVNode)(2,p.Box,{m:2,children:(0,e.createComponentVNode)(2,p.Button,{content:"Close",onClick:function(){function B(){C(null),V(null)}return B}()})})]})},h=function(s,d){var v=(0,o.useBackend)(d),g=v.act,C=v.data,f=C.is_public,N=C.timeleft,V=C.moving,B=C.at_station,I,L;return!V&&!B?(I="Docked off-station",L="Call Shuttle"):!V&&B?(I="Docked at the station",L="Return Shuttle"):V&&(L="In Transit...",N!==1?I="Shuttle is en route (ETA: "+N+" minutes)":I="Shuttle is en route (ETA: "+N+" minute)"),(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Section,{title:"Status",children:(0,e.createComponentVNode)(2,p.LabeledList,{children:[(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Shuttle Status",children:I}),f===0&&(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Controls",children:[(0,e.createComponentVNode)(2,p.Button,{content:L,disabled:V,onClick:function(){function w(){return g("moveShuttle")}return w}()}),(0,e.createComponentVNode)(2,p.Button,{content:"View Central Command Messages",onClick:function(){function w(){return g("showMessages")}return w}()})]})]})})})},i=function(s,d){var v,g=(0,o.useBackend)(d),C=g.act,f=g.data,N=f.accounts,V=(0,o.useLocalState)(d,"selectedAccount"),B=V[0],I=V[1],L=[];return N.map(function(w){return L[w.name]=w.account_UID}),(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Section,{title:"Payment",children:[(0,e.createComponentVNode)(2,p.Dropdown,{width:"190px",options:N.map(function(w){return w.name}),selected:(v=N.filter(function(w){return w.account_UID===B})[0])==null?void 0:v.name,onSelected:function(){function w(A){return I(L[A])}return w}()}),N.filter(function(w){return w.account_UID===B}).map(function(w){return(0,e.createComponentVNode)(2,p.LabeledList,{children:[(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Account Name",children:(0,e.createComponentVNode)(2,p.Stack.Item,{mt:1,children:w.name})}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Balance",children:(0,e.createComponentVNode)(2,p.Stack.Item,{children:w.balance})})]},w.account_UID)})]})})},c=function(s,d){var v=(0,o.useBackend)(d),g=v.act,C=v.data,f=C.requests,N=C.categories,V=C.supply_packs,B=(0,o.useSharedState)(d,"category","Emergency"),I=B[0],L=B[1],w=(0,o.useSharedState)(d,"search_text",""),A=w[0],x=w[1],E=(0,o.useLocalState)(d,"contentsModal",null),P=E[0],D=E[1],M=(0,o.useLocalState)(d,"contentsModalTitle",null),O=M[0],R=M[1],F=(0,y.createSearch)(A,function(X){return X.name}),W=(0,o.useLocalState)(d,"selectedAccount"),U=W[0],z=W[1],$=(0,a.flow)([(0,t.filter)(function(X){return X.cat===N.filter(function(J){return J.name===I})[0].category||A}),A&&(0,t.filter)(F),(0,t.sortBy)(function(X){return X.name.toLowerCase()})])(V),G="Crate Catalogue";return A?G="Results for '"+A+"':":I&&(G="Browsing "+I),(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Section,{title:G,buttons:(0,e.createComponentVNode)(2,p.Dropdown,{width:"190px",options:N.map(function(X){return X.name}),selected:I,onSelected:function(){function X(J){return L(J)}return X}()}),children:[(0,e.createComponentVNode)(2,p.Input,{fluid:!0,placeholder:"Search for...",onInput:function(){function X(J,se){return x(se)}return X}(),mb:1}),(0,e.createComponentVNode)(2,p.Box,{maxHeight:25,overflowY:"auto",overflowX:"hidden",children:(0,e.createComponentVNode)(2,p.Table,{m:"0.5rem",children:$.map(function(X){return(0,e.createComponentVNode)(2,p.Table.Row,{children:[(0,e.createComponentVNode)(2,p.Table.Cell,{bold:!0,children:[X.name," (",X.cost," Credits)"]}),(0,e.createComponentVNode)(2,p.Table.Cell,{textAlign:"right",pr:1,children:[(0,e.createComponentVNode)(2,p.Button,{content:"Order 1",icon:"shopping-cart",disabled:!U,onClick:function(){function J(){return g("order",{crate:X.ref,multiple:!1,account:U})}return J}()}),(0,e.createComponentVNode)(2,p.Button,{content:"Order Multiple",icon:"cart-plus",disabled:!U||X.singleton,onClick:function(){function J(){return g("order",{crate:X.ref,multiple:!0,account:U})}return J}()}),(0,e.createComponentVNode)(2,p.Button,{content:"View Contents",icon:"search",onClick:function(){function J(){D(X.contents),R(X.name)}return J}()})]})]},X.name)})})})]})})},m=function(s,d){var v=s.request,g,C;switch(v.department){case"Engineering":C="CE",g="orange";break;case"Medical":C="CMO",g="teal";break;case"Science":C="RD",g="purple";break;case"Supply":C="CT",g="brown";break;case"Service":C="HOP",g="olive";break;case"Security":C="HOS",g="red";break;case"Command":C="CAP",g="blue";break;case"Assistant":C="Any Head",g="grey";break}return(0,e.createComponentVNode)(2,p.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{mt:.5,children:"Approval Required:"}),!!v.req_cargo_approval&&(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Button,{color:"brown",content:"QM",icon:"user-tie",tooltip:"This Order requires approval from the QM still"})}),!!v.req_head_approval&&(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Button,{color:g,content:C,disabled:v.req_cargo_approval,icon:"user-tie",tooltip:v.req_cargo_approval?"This Order first requires approval from the QM before the "+C+" can approve it":"This Order requires approval from the "+C+" still"})})]})},l=function(s,d){var v=(0,o.useBackend)(d),g=v.act,C=v.data,f=C.requests,N=C.orders,V=C.shipments;return(0,e.createComponentVNode)(2,p.Section,{fill:!0,scrollable:!0,title:"Orders",children:[(0,e.createComponentVNode)(2,p.Box,{bold:!0,children:"Requests"}),(0,e.createComponentVNode)(2,p.Table,{children:f.map(function(B){return(0,e.createComponentVNode)(2,p.Table.Row,{className:"Cargo_RequestList",children:[(0,e.createComponentVNode)(2,p.Table.Cell,{mb:1,children:[(0,e.createComponentVNode)(2,p.Box,{children:["Order #",B.ordernum,": ",B.supply_type," (",B.cost," credits) for ",(0,e.createVNode)(1,"b",null,B.orderedby,0)," with"," ",B.department?"The "+B.department+" Department":"Their Personal"," Account"]}),(0,e.createComponentVNode)(2,p.Box,{italic:!0,children:["Reason: ",B.comment]}),(0,e.createComponentVNode)(2,m,{request:B})]}),(0,e.createComponentVNode)(2,p.Stack.Item,{textAlign:"right",children:[(0,e.createComponentVNode)(2,p.Button,{content:"Approve",color:"green",disabled:!B.can_approve,onClick:function(){function I(){return g("approve",{ordernum:B.ordernum})}return I}()}),(0,e.createComponentVNode)(2,p.Button,{content:"Deny",color:"red",disabled:!B.can_deny,onClick:function(){function I(){return g("deny",{ordernum:B.ordernum})}return I}()})]})]},B.ordernum)})}),(0,e.createComponentVNode)(2,p.Box,{bold:!0,children:"Orders Awaiting Delivery"}),(0,e.createComponentVNode)(2,p.Table,{m:"0.5rem",children:N.map(function(B){return(0,e.createComponentVNode)(2,p.Table.Row,{children:(0,e.createComponentVNode)(2,p.Table.Cell,{children:[(0,e.createComponentVNode)(2,p.Box,{children:["- #",B.ordernum,": ",B.supply_type," for ",(0,e.createVNode)(1,"b",null,B.orderedby,0)]}),(0,e.createComponentVNode)(2,p.Box,{italic:!0,children:["Reason: ",B.comment]})]})},B.ordernum)})}),(0,e.createComponentVNode)(2,p.Box,{bold:!0,children:"Order in Transit"}),(0,e.createComponentVNode)(2,p.Table,{m:"0.5rem",children:V.map(function(B){return(0,e.createComponentVNode)(2,p.Table.Row,{children:(0,e.createComponentVNode)(2,p.Table.Cell,{children:[(0,e.createComponentVNode)(2,p.Box,{children:["- #",B.ordernum,": ",B.supply_type," for ",(0,e.createVNode)(1,"b",null,B.orderedby,0)]}),(0,e.createComponentVNode)(2,p.Box,{italic:!0,children:["Reason: ",B.comment]})]})},B.ordernum)})})]})}},36232:function(T,r,n){"use strict";r.__esModule=!0,r.ChameleonAppearances=r.Chameleon=void 0;var e=n(89005),a=n(25328),t=n(64795),o=n(88510),p=n(72253),b=n(36036),y=n(98595),S=r.Chameleon=function(){function i(c,m){return(0,e.createComponentVNode)(2,y.Window,{width:431,height:500,theme:"syndicate",children:(0,e.createComponentVNode)(2,y.Window.Content,{children:(0,e.createComponentVNode)(2,h)})})}return i}(),k=function(c,m){m===void 0&&(m="");var l=(0,a.createSearch)(m,function(u){return u.name});return(0,t.flow)([(0,o.filter)(function(u){return u==null?void 0:u.name}),m&&(0,o.filter)(l)])(c)},h=r.ChameleonAppearances=function(){function i(c,m){var l=(0,p.useBackend)(m),u=l.act,s=l.data,d=(0,p.useLocalState)(m,"searchText",""),v=d[0],g=d[1],C=k(s.chameleon_skins,v),f=s.selected_appearance;return(0,e.createComponentVNode)(2,b.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Input,{fluid:!0,placeholder:"Search for an appearance",onInput:function(){function N(V,B){return g(B)}return N}()})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Item Appearance",children:C.map(function(N){var V=N.name+"_"+N.icon_state;return(0,e.createComponentVNode)(2,b.ImageButton,{dmIcon:N.icon,dmIconState:N.icon_state,imageSize:64,m:.5,compact:!0,selected:V===f,tooltip:N.name,style:{opacity:V===f&&"1"||"0.5"},onClick:function(){function B(){u("change_appearance",{new_appearance:V})}return B}()},V)})})})]})}return i}()},87331:function(T,r,n){"use strict";r.__esModule=!0,r.ChangelogView=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.ChangelogView=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=(0,a.useLocalState)(S,"onlyRecent",0),m=c[0],l=c[1],u=i.cl_data,s=i.last_cl,d={FIX:(0,e.createComponentVNode)(2,t.Icon,{name:"tools",title:"Fix"}),WIP:(0,e.createComponentVNode)(2,t.Icon,{name:"hard-hat",title:"WIP",color:"orange"}),TWEAK:(0,e.createComponentVNode)(2,t.Icon,{name:"sliders-h",title:"Tweak"}),SOUNDADD:(0,e.createComponentVNode)(2,t.Icon,{name:"volume-up",title:"Sound Added",color:"green"}),SOUNDDEL:(0,e.createComponentVNode)(2,t.Icon,{name:"volume-mute",title:"Sound Removed",color:"red"}),CODEADD:(0,e.createComponentVNode)(2,t.Icon,{name:"plus",title:"Code Addition",color:"green"}),CODEDEL:(0,e.createComponentVNode)(2,t.Icon,{name:"minus",title:"Code Removal",color:"red"}),IMAGEADD:(0,e.createComponentVNode)(2,t.Icon,{name:"folder-plus",title:"Sprite Addition",color:"green"}),IMAGEDEL:(0,e.createComponentVNode)(2,t.Icon,{name:"folder-minus",title:"Sprite Removal",color:"red"}),SPELLCHECK:(0,e.createComponentVNode)(2,t.Icon,{name:"font",title:"Spelling/Grammar Fix"}),EXPERIMENT:(0,e.createComponentVNode)(2,t.Icon,{name:"exclamation-triangle",title:"Experimental",color:"orange"})},v=function(){function g(C){return C in d?d[C]:(0,e.createComponentVNode)(2,t.Icon,{name:"plus",color:"green"})}return g}();return(0,e.createComponentVNode)(2,o.Window,{width:750,height:800,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"ParadiseSS13 Changelog",mt:2,buttons:(0,e.createComponentVNode)(2,t.Button,{content:m?"Showing all changes":"Showing changes since last connection",onClick:function(){function g(){return l(!m)}return g}()}),children:u.map(function(g){return!m&&g.merge_ts<=s||(0,e.createComponentVNode)(2,t.Section,{mb:2,title:g.author+" - Merged on "+g.merge_date,buttons:(0,e.createComponentVNode)(2,t.Button,{content:"#"+g.num,onClick:function(){function C(){return h("open_pr",{pr_number:g.num})}return C}()}),children:g.entries.map(function(C){return(0,e.createComponentVNode)(2,t.Box,{m:1,children:[v(C.etype)," ",C.etext]},C)})},g)})})})})}return b}()},91360:function(T,r,n){"use strict";r.__esModule=!0,r.CheckboxListInputModal=void 0;var e=n(89005),a=n(51057),t=n(19203),o=n(36036),p=n(72253),b=n(98595),y=r.CheckboxListInputModal=function(){function k(h,i){var c=(0,p.useBackend)(i),m=c.act,l=c.data,u=l.items,s=u===void 0?[]:u,d=l.message,v=d===void 0?"":d,g=l.init_value,C=l.timeout,f=l.title,N=(0,p.useLocalState)(i,"edittedItems",s),V=N[0],B=N[1],I=330+Math.ceil(v.length/3),L=function(){function w(A){A===void 0&&(A=null);var x=[].concat(V);x=x.map(function(E){return E.key===A.key?Object.assign({},E,{checked:!A.checked}):E}),B(x)}return w}();return(0,e.createComponentVNode)(2,b.Window,{title:f,width:325,height:I,children:[C&&(0,e.createComponentVNode)(2,a.Loader,{value:C}),(0,e.createComponentVNode)(2,b.Window.Content,{children:(0,e.createComponentVNode)(2,o.Section,{className:"ListInput__Section",fill:!0,title:v,children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,S,{filteredItems:V,onClick:L})}),(0,e.createComponentVNode)(2,o.Stack.Item,{mt:.5,children:(0,e.createComponentVNode)(2,t.InputButtons,{input:V})})]})})})]})}return k}(),S=function(h,i){var c=h.filteredItems,m=h.onClick;return(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,tabIndex:0,children:c.map(function(l,u){return(0,e.createComponentVNode)(2,o.Button.Checkbox,{fluid:!0,id:u,onClick:function(){function s(){return m(l)}return s}(),checked:l.checked,style:{animation:"none",transition:"none"},children:l.key.replace(/^\w/,function(s){return s.toUpperCase()})},u)})})}},36108:function(T,r,n){"use strict";r.__esModule=!0,r.ChemDispenser=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(85870),p=n(98595),b=[1,5,10,20,30,50],y=[1,5,10],S=r.ChemDispenser=function(){function c(m,l){var u=(0,a.useBackend)(l),s=u.act,d=u.data,v=d.chemicals;return(0,e.createComponentVNode)(2,p.Window,{width:400,height:400+v.length*8,children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,k),(0,e.createComponentVNode)(2,h),(0,e.createComponentVNode)(2,i)]})})})}return c}(),k=function(m,l){var u=(0,a.useBackend)(l),s=u.act,d=u.data,v=d.amount,g=d.energy,C=d.maxEnergy;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Settings",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Energy",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:g,minValue:0,maxValue:C,ranges:{good:[C*.5,1/0],average:[C*.25,C*.5],bad:[-1/0,C*.25]},children:[g," / ",C," Units"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Dispense",verticalAlign:"middle",children:(0,e.createComponentVNode)(2,t.Stack,{children:b.map(function(f,N){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,width:"15%",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"cog",selected:v===f,content:f,onClick:function(){function V(){return s("amount",{amount:f})}return V}()})},N)})})})]})})})},h=function(m,l){for(var u=(0,a.useBackend)(l),s=u.act,d=u.data,v=d.chemicals,g=v===void 0?[]:v,C=[],f=0;f<(g.length+1)%3;f++)C.push(!0);return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:d.glass?"Drink Dispenser":"Chemical Dispenser",children:[g.map(function(N,V){return(0,e.createComponentVNode)(2,t.Button,{m:.1,width:"32.5%",icon:"arrow-circle-down",overflow:"hidden",textOverflow:"ellipsis",content:N.title,style:{"margin-left":"2px"},onClick:function(){function B(){return s("dispense",{reagent:N.id})}return B}()},V)}),C.map(function(N,V){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,basis:"25%"},V)})]})})},i=function(m,l){var u=(0,a.useBackend)(l),s=u.act,d=u.data,v=d.isBeakerLoaded,g=d.beakerCurrentVolume,C=d.beakerMaxVolume,f=d.beakerContents,N=f===void 0?[]:f;return(0,e.createComponentVNode)(2,t.Stack.Item,{height:16,children:(0,e.createComponentVNode)(2,t.Section,{title:d.glass?"Glass":"Beaker",fill:!0,scrollable:!0,buttons:(0,e.createComponentVNode)(2,t.Box,{children:[!!v&&(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:"label",mr:2,children:[g," / ",C," units"]}),(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:"Eject",disabled:!v,onClick:function(){function V(){return s("ejectBeaker")}return V}()})]}),children:(0,e.createComponentVNode)(2,o.BeakerContents,{beakerLoaded:v,beakerContents:N,buttons:function(){function V(B){return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:"Isolate",icon:"compress-arrows-alt",onClick:function(){function I(){return s("remove",{reagent:B.id,amount:-1})}return I}()}),y.map(function(I,L){return(0,e.createComponentVNode)(2,t.Button,{content:I,onClick:function(){function w(){return s("remove",{reagent:B.id,amount:I})}return w}()},L)}),(0,e.createComponentVNode)(2,t.Button,{content:"ALL",onClick:function(){function I(){return s("remove",{reagent:B.id,amount:B.volume})}return I}()})],0)}return V}()})})})}},13146:function(T,r,n){"use strict";r.__esModule=!0,r.ChemHeater=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=n(85870),b=n(98595),y=r.ChemHeater=function(){function h(i,c){return(0,e.createComponentVNode)(2,b.Window,{width:350,height:275,children:(0,e.createComponentVNode)(2,b.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,S),(0,e.createComponentVNode)(2,k)]})})})}return h}(),S=function(i,c){var m=(0,t.useBackend)(c),l=m.act,u=m.data,s=u.targetTemp,d=u.targetTempReached,v=u.autoEject,g=u.isActive,C=u.currentTemp,f=u.isBeakerLoaded;return(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,title:"Settings",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{content:"Auto-eject",icon:v?"toggle-on":"toggle-off",selected:v,onClick:function(){function N(){return l("toggle_autoeject")}return N}()}),(0,e.createComponentVNode)(2,o.Button,{content:g?"On":"Off",icon:"power-off",selected:g,disabled:!f,onClick:function(){function N(){return l("toggle_on")}return N}()})],4),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Target",children:(0,e.createComponentVNode)(2,o.NumberInput,{width:"65px",unit:"K",step:10,stepPixelSize:3,value:(0,a.round)(s,0),minValue:0,maxValue:1e3,onDrag:function(){function N(V,B){return l("adjust_temperature",{target:B})}return N}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Reading",color:d?"good":"average",children:f&&(0,e.createComponentVNode)(2,o.AnimatedNumber,{value:C,format:function(){function N(V){return(0,a.toFixed)(V)+" K"}return N}()})||"\u2014"})]})})})},k=function(i,c){var m=(0,t.useBackend)(c),l=m.act,u=m.data,s=u.isBeakerLoaded,d=u.beakerCurrentVolume,v=u.beakerMaxVolume,g=u.beakerContents;return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{title:"Beaker",fill:!0,scrollable:!0,buttons:!!s&&(0,e.createComponentVNode)(2,o.Box,{children:[(0,e.createComponentVNode)(2,o.Box,{inline:!0,color:"label",mr:2,children:[d," / ",v," units"]}),(0,e.createComponentVNode)(2,o.Button,{icon:"eject",content:"Eject",onClick:function(){function C(){return l("eject_beaker")}return C}()})]}),children:(0,e.createComponentVNode)(2,p.BeakerContents,{beakerLoaded:s,beakerContents:g})})})}},56541:function(T,r,n){"use strict";r.__esModule=!0,r.ChemMaster=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(85870),b=n(3939),y=n(35840),S=["icon"];function k(I,L){if(I==null)return{};var w={};for(var A in I)if({}.hasOwnProperty.call(I,A)){if(L.includes(A))continue;w[A]=I[A]}return w}function h(I,L){I.prototype=Object.create(L.prototype),I.prototype.constructor=I,i(I,L)}function i(I,L){return i=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(w,A){return w.__proto__=A,w},i(I,L)}var c=[1,5,10],m=function(L,w){var A=(0,a.useBackend)(w),x=A.act,E=A.data,P=L.args.analysis;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:E.condi?"Condiment Analysis":"Reagent Analysis",children:(0,e.createComponentVNode)(2,t.Box,{mx:"0.5rem",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Name",children:P.name}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Description",children:(P.desc||"").length>0?P.desc:"N/A"}),P.blood_type&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Blood type",children:P.blood_type}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Blood DNA",className:"LabeledList__breakContents",children:P.blood_dna})],4),!E.condi&&(0,e.createComponentVNode)(2,t.Button,{icon:E.printing?"spinner":"print",disabled:E.printing,iconSpin:!!E.printing,ml:"0.5rem",content:"Print",onClick:function(){function D(){return x("print",{idx:P.idx,beaker:L.args.beaker})}return D}()})]})})})})},l=function(I){return I[I.ToDisposals=0]="ToDisposals",I[I.ToBeaker=1]="ToBeaker",I}(l||{}),u=r.ChemMaster=function(){function I(L,w){return(0,e.createComponentVNode)(2,o.Window,{width:575,height:650,children:[(0,e.createComponentVNode)(2,b.ComplexModal),(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,s),(0,e.createComponentVNode)(2,d),(0,e.createComponentVNode)(2,v),(0,e.createComponentVNode)(2,B)]})})]})}return I}(),s=function(L,w){var A=(0,a.useBackend)(w),x=A.act,E=A.data,P=E.beaker,D=E.beaker_reagents,M=E.buffer_reagents,O=M.length>0;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Beaker",fill:!0,scrollable:!0,buttons:O?(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"eject",disabled:!P,content:"Eject and Clear Buffer",onClick:function(){function R(){return x("eject")}return R}()}):(0,e.createComponentVNode)(2,t.Button,{icon:"eject",disabled:!P,content:"Eject and Clear Buffer",onClick:function(){function R(){return x("eject")}return R}()}),children:P?(0,e.createComponentVNode)(2,p.BeakerContents,{beakerLoaded:!0,beakerContents:D,buttons:function(){function R(F,W){return(0,e.createComponentVNode)(2,t.Box,{mb:W0?(0,e.createComponentVNode)(2,p.BeakerContents,{beakerLoaded:!0,beakerContents:D,buttons:function(){function M(O,R){return(0,e.createComponentVNode)(2,t.Box,{mb:R0&&(O=M.map(function(R){var F=R.id,W=R.sprite;return(0,e.createComponentVNode)(2,N,{icon:W,translucent:!0,onClick:function(){function U(){return x("set_sprite_style",{production_mode:P,style:F})}return U}(),selected:D===F},F)})),(0,e.createComponentVNode)(2,f,{productionData:L.productionData,children:O&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Style",children:O})})},B=function(L,w){var A=(0,a.useBackend)(w),x=A.act,E=A.data,P=E.loaded_pill_bottle_style,D=E.containerstyles,M=E.loaded_pill_bottle,O={width:"20px",height:"20px"},R=D.map(function(F){var W=F.color,U=F.name,z=P===W;return(0,e.createComponentVNode)(2,t.Button,{style:{position:"relative",width:O.width,height:O.height},onClick:function(){function $(){return x("set_container_style",{style:W})}return $}(),icon:z&&"check",iconStyle:{position:"relative","z-index":1},tooltip:U,tooltipPosition:"top",children:[!z&&(0,e.createVNode)(1,"div",null,null,1,{style:{display:"inline-block"}}),(0,e.createVNode)(1,"span","Button",null,1,{style:{display:"inline-block",position:"absolute",top:0,left:0,margin:0,padding:0,width:O.width,height:O.height,"background-color":W,opacity:.6,filter:"alpha(opacity=60)"}})]},W)});return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Container Customization",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"eject",disabled:!M,content:"Eject Container",onClick:function(){function F(){return x("ejectp")}return F}()}),children:M?(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Style",children:[(0,e.createComponentVNode)(2,t.Button,{style:{width:O.width,height:O.height},icon:"tint-slash",onClick:function(){function F(){return x("clear_container_style")}return F}(),selected:!P,tooltip:"Default",tooltipPosition:"top"}),R]})}):(0,e.createComponentVNode)(2,t.Box,{color:"label",children:"No pill bottle or patch pack loaded."})})})};(0,b.modalRegisterBodyOverride)("analyze",m)},37173:function(T,r,n){"use strict";r.__esModule=!0,r.CloningConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(79140),b=1,y=32,S=128,k=r.CloningConsole=function(){function u(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.tab,N=C.has_scanner,V=C.pod_amount;return(0,e.createComponentVNode)(2,o.Window,{width:640,height:520,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Cloning Console",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Connected scanner",children:N?"Online":"Missing"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Connected pods",children:V})]})}),(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:f===1,icon:"home",onClick:function(){function B(){return g("menu",{tab:1})}return B}(),children:"Main Menu"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:f===2,icon:"user",onClick:function(){function B(){return g("menu",{tab:2})}return B}(),children:"Damage Configuration"})]}),(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,h)})]})})}return u}(),h=function(s,d){var v=(0,a.useBackend)(d),g=v.data,C=g.tab,f;return C===1?f=(0,e.createComponentVNode)(2,i):C===2&&(f=(0,e.createComponentVNode)(2,c)),f},i=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.pods,N=C.pod_amount,V=C.selected_pod_UID;return(0,e.createComponentVNode)(2,t.Box,{children:[!N&&(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"Notice: No pods connected."}),!!N&&f.map(function(B,I){return(0,e.createComponentVNode)(2,t.Section,{layer:2,title:"Pod "+(I+1),children:(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{basis:"96px",shrink:0,children:[(0,e.createVNode)(1,"img",null,null,1,{src:(0,p.resolveAsset)("pod_"+(B.cloning?"cloning":"idle")+".gif"),style:{width:"100%","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"}}),(0,e.createComponentVNode)(2,t.Button,{selected:V===B.uid,onClick:function(){function L(){return g("select_pod",{uid:B.uid})}return L}(),children:"Select"})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Progress",children:[!B.cloning&&(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"Pod is inactive."}),!!B.cloning&&(0,e.createComponentVNode)(2,t.ProgressBar,{value:B.clone_progress,maxValue:100,color:"good"})]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Biomass",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:B.biomass,ranges:{good:[2*B.biomass_storage_capacity/3,B.biomass_storage_capacity],average:[B.biomass_storage_capacity/3,2*B.biomass_storage_capacity/3],bad:[0,B.biomass_storage_capacity/3]},minValue:0,maxValue:B.biomass_storage_capacity,children:[B.biomass,"/",B.biomass_storage_capacity+" ("+100*B.biomass/B.biomass_storage_capacity+"%)"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Sanguine Reagent",children:B.sanguine_reagent}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Osseous Reagent",children:B.osseous_reagent})]})})]})},B)})]})},c=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.selected_pod_data,N=C.has_scanned,V=C.scanner_has_patient,B=C.feedback,I=C.scan_successful,L=C.cloning_cost,w=C.has_scanner,A=C.currently_scanning;return(0,e.createComponentVNode)(2,t.Box,{children:[!w&&(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"Notice: No scanner connected."}),!!w&&(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Section,{layer:2,title:"Scanner Info",buttons:(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"hourglass-half",onClick:function(){function x(){return g("scan")}return x}(),disabled:!V||A,children:"Scan"}),(0,e.createComponentVNode)(2,t.Button,{icon:"eject",onClick:function(){function x(){return g("eject")}return x}(),disabled:!V||A,children:"Eject Patient"})]}),children:[!N&&!A&&(0,e.createComponentVNode)(2,t.Box,{color:"average",children:V?"No scan detected for current patient.":"No patient is in the scanner."}),(!!N||!!A)&&(0,e.createComponentVNode)(2,t.Box,{color:B.color,children:B.text})]}),(0,e.createComponentVNode)(2,t.Section,{layer:2,title:"Damages Breakdown",children:(0,e.createComponentVNode)(2,t.Box,{children:[(!I||!N)&&(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"No valid scan detected."}),!!I&&!!N&&(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{onClick:function(){function x(){return g("fix_all")}return x}(),children:"Repair All Damages"}),(0,e.createComponentVNode)(2,t.Button,{onClick:function(){function x(){return g("fix_none")}return x}(),children:"Repair No Damages"})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:1}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{onClick:function(){function x(){return g("clone")}return x}(),children:"Clone"})})]}),(0,e.createComponentVNode)(2,t.Stack,{height:"25px",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"40%",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:L[0],maxValue:f.biomass_storage_capacity,ranges:{bad:[2*f.biomass_storage_capacity/3,f.biomass_storage_capacity],average:[f.biomass_storage_capacity/3,2*f.biomass_storage_capacity/3],good:[0,f.biomass_storage_capacity/3]},color:L[0]>f.biomass?"bad":null,children:["Biomass: ",L[0],"/",f.biomass,"/",f.biomass_storage_capacity]})}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"30%",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:L[1],maxValue:f.max_reagent_capacity,ranges:{bad:[2*f.max_reagent_capacity/3,f.max_reagent_capacity],average:[f.max_reagent_capacity/3,2*f.max_reagent_capacity/3],good:[0,f.max_reagent_capacity/3]},color:L[1]>f.sanguine_reagent?"bad":"good",children:["Sanguine: ",L[1],"/",f.sanguine_reagent,"/",f.max_reagent_capacity]})}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"30%",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:L[2],maxValue:f.max_reagent_capacity,ranges:{bad:[2*f.max_reagent_capacity/3,f.max_reagent_capacity],average:[f.max_reagent_capacity/3,2*f.max_reagent_capacity/3],good:[0,f.max_reagent_capacity/3]},color:L[2]>f.osseous_reagent?"bad":"good",children:["Osseous: ",L[2],"/",f.osseous_reagent,"/",f.max_reagent_capacity]})})]}),(0,e.createComponentVNode)(2,m),(0,e.createComponentVNode)(2,l)]})]})})]})]})},m=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.patient_limb_data,N=C.limb_list,V=C.desired_limb_data;return(0,e.createComponentVNode)(2,t.Collapsible,{title:"Limbs",children:N.map(function(B,I){return(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Stack,{align:"baseline",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{color:"label",width:"15%",height:"20px",children:[f[B][4],":"," "]}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:1}),f[B][3]===0&&(0,e.createComponentVNode)(2,t.Stack.Item,{width:"60%",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:V[B][0]+V[B][1],maxValue:f[B][5],ranges:{good:[0,f[B][5]/3],average:[f[B][5]/3,2*f[B][5]/3],bad:[2*f[B][5]/3,f[B][5]]},children:["Post-Cloning Damage: ",(0,e.createComponentVNode)(2,t.Icon,{name:"bone"})," "+V[B][0]+" / ",(0,e.createComponentVNode)(2,t.Icon,{name:"fire"})," "+V[B][1]]})}),f[B][3]!==0&&(0,e.createComponentVNode)(2,t.Stack.Item,{width:"60%",children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:"bad",value:0,children:["The patient's ",f[B][4]," is missing!"]})})]}),(0,e.createComponentVNode)(2,t.Stack,{children:[!!f[B][3]&&(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:!V[B][3],onClick:function(){function L(){return g("toggle_limb_repair",{limb:B,type:"replace"})}return L}(),children:"Replace Limb"})}),!f[B][3]&&(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button.Checkbox,{disabled:!(f[B][0]||f[B][1]),checked:!(V[B][0]||V[B][1]),onClick:function(){function L(){return g("toggle_limb_repair",{limb:B,type:"damage"})}return L}(),children:"Repair Damages"}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{disabled:!(f[B][2]&b),checked:!(V[B][2]&b),onClick:function(){function L(){return g("toggle_limb_repair",{limb:B,type:"bone"})}return L}(),children:"Mend Bone"}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{disabled:!(f[B][2]&y),checked:!(V[B][2]&y),onClick:function(){function L(){return g("toggle_limb_repair",{limb:B,type:"ib"})}return L}(),children:"Mend IB"}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{disabled:!(f[B][2]&S),checked:!(V[B][2]&S),onClick:function(){function L(){return g("toggle_limb_repair",{limb:B,type:"critburn"})}return L}(),children:"Mend Critical Burn"})]})]})]},B)})})},l=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.patient_organ_data,N=C.organ_list,V=C.desired_organ_data;return(0,e.createComponentVNode)(2,t.Collapsible,{title:"Organs",children:N.map(function(B,I){return(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Stack,{align:"baseline",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{color:"label",width:"20%",height:"20px",children:[f[B][3],":"," "]}),f[B][5]!=="heart"&&(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:[!!f[B][2]&&(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:!V[B][2]&&!V[B][1],onClick:function(){function L(){return g("toggle_organ_repair",{organ:B,type:"replace"})}return L}(),children:"Replace Organ"}),!f[B][2]&&(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{disabled:!f[B][0],checked:!V[B][0],onClick:function(){function L(){return g("toggle_organ_repair",{organ:B,type:"damage"})}return L}(),children:"Repair Damages"})})]})}),f[B][5]==="heart"&&(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"Heart replacement is required for cloning."}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:1}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"35%",children:[!!f[B][2]&&(0,e.createComponentVNode)(2,t.ProgressBar,{color:"bad",value:0,children:["The patient's ",f[B][3]," is missing!"]}),!f[B][2]&&(0,e.createComponentVNode)(2,t.ProgressBar,{value:V[B][0],maxValue:f[B][4],ranges:{good:[0,f[B][4]/3],average:[f[B][4]/3,2*f[B][4]/3],bad:[2*f[B][4]/3,f[B][4]]},children:"Post-Cloning Damage: "+V[B][0]})]})]})},B)})})}},98723:function(T,r,n){"use strict";r.__esModule=!0,r.CloningPod=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.CloningPod=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.biomass,m=i.biomass_storage_capacity,l=i.sanguine_reagent,u=i.osseous_reagent,s=i.organs,d=i.currently_cloning;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:500,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Liquid Storage",children:[(0,e.createComponentVNode)(2,t.Stack,{height:"25px",align:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{color:"label",width:"25%",children:["Biomass:"," "]}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:1,children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:c,ranges:{good:[2*m/3,m],average:[m/3,2*m/3],bad:[0,m/3]},minValue:0,maxValue:m})})]}),(0,e.createComponentVNode)(2,t.Stack,{height:"25px",align:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{color:"label",width:"25%",children:["Sanguine Reagent:"," "]}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:l+" units"}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:1}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.NumberInput,{value:0,minValue:0,maxValue:l,step:1,unit:"units",onChange:function(){function v(g,C){return h("remove_reagent",{reagent:"sanguine_reagent",amount:C})}return v}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Remove All",onClick:function(){function v(){return h("purge_reagent",{reagent:"sanguine_reagent"})}return v}()})})]}),(0,e.createComponentVNode)(2,t.Stack,{height:"25px",align:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{color:"label",width:"25%",children:["Osseous Reagent:"," "]}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:u+" units"}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:1}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.NumberInput,{value:0,minValue:0,maxValue:u,step:1,unit:"units",onChange:function(){function v(g,C){return h("remove_reagent",{reagent:"osseous_reagent",amount:C})}return v}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Remove All",onClick:function(){function v(){return h("purge_reagent",{reagent:"osseous_reagent"})}return v}()})})]})]}),(0,e.createComponentVNode)(2,t.Section,{title:"Organ Storage",children:[!d&&(0,e.createComponentVNode)(2,t.Box,{children:[!s&&(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"Notice: No organs loaded."}),!!s&&s.map(function(v){return(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:v.name}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:1}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Eject",onClick:function(){function g(){return h("eject_organ",{organ_ref:v.ref})}return g}()})})]},v)})]}),!!d&&(0,e.createComponentVNode)(2,t.Stack,{height:"100%",children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:"1",textAlign:"center",align:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"lock",size:"5",mb:3}),(0,e.createVNode)(1,"br"),"Unable to access organ storage while cloning."]})})]})]})})}return b}()},18259:function(T,r,n){"use strict";r.__esModule=!0,r.CoinMint=void 0;var e=n(89005),a=n(35840),t=n(72253),o=n(36036),p=n(98595),b=r.CoinMint=function(){function y(S,k){var h=(0,t.useBackend)(k),i=h.act,c=h.data,m=c.materials,l=c.moneyBag,u=c.moneyBagContent,s=c.moneyBagMaxContent,d=(l?210:138)+Math.ceil(m.length/4)*64;return(0,e.createComponentVNode)(2,p.Window,{width:210,height:d,children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.NoticeBox,{m:0,info:!0,children:["Total coins produced: ",c.totalCoins]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,title:"Coin Type",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"power-off",color:c.active&&"bad",tooltip:!l&&"Need a money bag",disabled:!l,onClick:function(){function v(){return i("activate")}return v}()}),children:(0,e.createComponentVNode)(2,o.Stack,{vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.ProgressBar,{minValue:0,maxValue:c.maxMaterials,value:c.totalMaterials})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{icon:"eject",tooltip:"Eject selected material",onClick:function(){function v(){return i("ejectMat")}return v}()})})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:m.map(function(v){return(0,e.createComponentVNode)(2,o.Button,{bold:!0,inline:!0,translucent:!0,m:.2,textAlign:"center",selected:v.id===c.chosenMaterial,tooltip:v.name,content:(0,e.createComponentVNode)(2,o.Stack,{vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{className:(0,a.classes)(["materials32x32",v.id])}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:v.amount})]}),onClick:function(){function g(){return i("selectMaterial",{material:v.id})}return g}()},v.id)})})]})})}),!!l&&(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{title:"Money Bag",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"eject",content:"Eject",disabled:c.active,onClick:function(){function v(){return i("ejectBag")}return v}()}),children:(0,e.createComponentVNode)(2,o.ProgressBar,{width:"100%",minValue:0,maxValue:s,value:u,children:[u," / ",s]})})})]})})})}return y}()},93858:function(T,r,n){"use strict";r.__esModule=!0,r.HexColorInput=r.ColorSelector=r.ColorPickerModal=r.ColorInput=void 0;var e=n(89005),a=n(51057),t=n(72253),o=n(36036),p=n(98595),b=n(44879),y=n(14448),S=n(4454),k=n(35840),h=n(9394),i=n(19203),c=["prefixed","alpha","color","fluid","onChange"];/** + * @file + * @copyright 2023 itsmeow + * @license MIT + */function m(w,A){w.prototype=Object.create(A.prototype),w.prototype.constructor=w,l(w,A)}function l(w,A){return l=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(x,E){return x.__proto__=E,x},l(w,A)}function u(w,A){if(w==null)return{};var x={};for(var E in w)if({}.hasOwnProperty.call(w,E)){if(A.includes(E))continue;x[E]=w[E]}return x}var s=r.ColorPickerModal=function(){function w(A,x){var E=(0,t.useBackend)(x),P=E.data,D=P.timeout,M=P.message,O=P.title,R=P.autofocus,F=P.default_color,W=F===void 0?"#000000":F,U=(0,t.useLocalState)(x,"color_picker_choice",(0,y.hexToHsva)(W)),z=U[0],$=U[1];return(0,e.createComponentVNode)(2,p.Window,{height:400,title:O,width:600,theme:"generic",children:[!!D&&(0,e.createComponentVNode)(2,a.Loader,{value:D}),(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[M&&(0,e.createComponentVNode)(2,o.Stack.Item,{m:1,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:(0,e.createComponentVNode)(2,o.Box,{color:"label",overflow:"hidden",children:M})})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:[!!R&&(0,e.createComponentVNode)(2,o.Autofocus),(0,e.createComponentVNode)(2,d,{color:z,setColor:$,defaultColor:W})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,i.InputButtons,{input:(0,y.hsvaToHex)(z)})})]})})]})}return w}(),d=r.ColorSelector=function(){function w(A,x){var E=A.color,P=A.setColor,D=A.defaultColor,M=function(){function F(W){P(function(U){return Object.assign({},U,W)})}return F}(),O=(0,y.hsvaToRgba)(E),R=(0,y.hsvaToHex)(E);return(0,e.createComponentVNode)(2,o.Flex,{direction:"row",children:[(0,e.createComponentVNode)(2,o.Flex.Item,{mr:2,children:(0,e.createComponentVNode)(2,o.Stack,{vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createVNode)(1,"div","react-colorful",[(0,e.createComponentVNode)(2,N,{hsva:E,onChange:M}),(0,e.createComponentVNode)(2,V,{hue:E.h,onChange:M,className:"react-colorful__last-control"})],4)}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:[(0,e.createComponentVNode)(2,o.Box,{inline:!0,width:"100px",height:"20px",textAlign:"center",children:"Current"}),(0,e.createComponentVNode)(2,o.Box,{inline:!0,width:"100px",height:"20px",textAlign:"center",children:"Previous"}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.Tooltip,{content:R,position:"bottom",children:(0,e.createComponentVNode)(2,o.Box,{inline:!0,width:"100px",height:"30px",backgroundColor:R})}),(0,e.createComponentVNode)(2,o.Tooltip,{content:D,position:"bottom",children:(0,e.createComponentVNode)(2,o.Box,{inline:!0,width:"100px",height:"30px",backgroundColor:D})})]})]})}),(0,e.createComponentVNode)(2,o.Flex.Item,{grow:!0,fontSize:"15px",lineHeight:"24px",children:(0,e.createComponentVNode)(2,o.Stack,{vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"Hex:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,height:"24px",children:(0,e.createComponentVNode)(2,C,{fluid:!0,color:(0,y.hsvaToHex)(E).substring(1),onChange:function(){function F(W){h.logger.info(W),P((0,y.hexToHsva)(W))}return F}(),prefixed:!0})})]})}),(0,e.createComponentVNode)(2,o.Stack.Divider),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{width:"25px",children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"H:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,V,{hue:E.h,onChange:M})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,v,{value:E.h,callback:function(){function F(W,U){return M({h:U})}return F}(),max:360,unit:"\xB0"})})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{width:"25px",children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"S:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,B,{color:E,onChange:M})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,v,{value:E.s,callback:function(){function F(W,U){return M({s:U})}return F}(),unit:"%"})})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{width:"25px",children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"V:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,I,{color:E,onChange:M})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,v,{value:E.v,callback:function(){function F(W,U){return M({v:U})}return F}(),unit:"%"})})]})}),(0,e.createComponentVNode)(2,o.Stack.Divider),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{width:"25px",children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"R:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,L,{color:E,onChange:M,target:"r"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,v,{value:O.r,callback:function(){function F(W,U){O.r=U,M((0,y.rgbaToHsva)(O))}return F}(),max:255})})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{width:"25px",children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"G:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,L,{color:E,onChange:M,target:"g"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,v,{value:O.g,callback:function(){function F(W,U){O.g=U,M((0,y.rgbaToHsva)(O))}return F}(),max:255})})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{width:"25px",children:(0,e.createComponentVNode)(2,o.Box,{textColor:"label",children:"B:"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,L,{color:E,onChange:M,target:"b"})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,v,{value:O.b,callback:function(){function F(W,U){O.b=U,M((0,y.rgbaToHsva)(O))}return F}(),max:255})})]})})]})})]})}return w}(),v=function(A){var x=A.value,E=A.callback,P=A.min,D=P===void 0?0:P,M=A.max,O=M===void 0?100:M,R=A.unit;return(0,e.createComponentVNode)(2,o.NumberInput,{width:"70px",value:Math.round(x),step:1,minValue:D,maxValue:O,onChange:E,unit:R})},g=function(A){return"#"+A},C=r.HexColorInput=function(){function w(A){var x=A.prefixed,E=A.alpha,P=A.color,D=A.fluid,M=A.onChange,O=u(A,c),R=function(){function W(U){return U.replace(/([^0-9A-F]+)/gi,"").substring(0,E?8:6)}return W}(),F=function(){function W(U){return(0,y.validHex)(U,E)}return W}();return(0,e.normalizeProps)((0,e.createComponentVNode)(2,f,Object.assign({},O,{fluid:D,color:P,onChange:M,escape:R,format:x?g:void 0,validate:F})))}return w}(),f=r.ColorInput=function(w){function A(E){var P;return P=w.call(this)||this,P.props=void 0,P.state=void 0,P.handleInput=function(D){var M=P.props.escape(D.currentTarget.value);P.setState({localValue:M})},P.handleBlur=function(D){D.currentTarget&&(P.props.validate(D.currentTarget.value)?P.props.onChange(P.props.escape?P.props.escape(D.currentTarget.value):D.currentTarget.value):P.setState({localValue:P.props.escape(P.props.color)}))},P.props=E,P.state={localValue:P.props.escape(P.props.color)},P}m(A,w);var x=A.prototype;return x.componentDidUpdate=function(){function E(P,D){P.color!==this.props.color&&this.setState({localValue:this.props.escape(this.props.color)})}return E}(),x.render=function(){function E(){return(0,e.createComponentVNode)(2,o.Box,{className:(0,k.classes)(["Input",this.props.fluid&&"Input--fluid"]),children:[(0,e.createVNode)(1,"div","Input__baseline",".",16),(0,e.createVNode)(64,"input","Input__input",null,1,{value:this.props.format?this.props.format(this.state.localValue):this.state.localValue,spellCheck:"false",onInput:this.handleInput,onBlur:this.handleBlur})]})}return E}(),A}(e.Component),N=function(A){var x=A.hsva,E=A.onChange,P=function(R){E({s:R.left*100,v:100-R.top*100})},D=function(R){E({s:(0,b.clamp)(x.s+R.left*100,0,100),v:(0,b.clamp)(x.v-R.top*100,0,100)})},M={"background-color":(0,y.hsvaToHslString)({h:x.h,s:100,v:100,a:1})+" !important"};return(0,e.createVNode)(1,"div","react-colorful__saturation_value",(0,e.createComponentVNode)(2,S.Interactive,{onMove:P,onKey:D,"aria-label":"Color","aria-valuetext":"Saturation "+Math.round(x.s)+"%, Brightness "+Math.round(x.v)+"%",children:(0,e.createComponentVNode)(2,o.Pointer,{className:"react-colorful__saturation_value-pointer",top:1-x.v/100,left:x.s/100,color:(0,y.hsvaToHslString)(x)})}),2,{style:M})},V=function(A){var x=A.className,E=A.hue,P=A.onChange,D=function(F){P({h:360*F.left})},M=function(F){P({h:(0,b.clamp)(E+F.left*360,0,360)})},O=(0,k.classes)(["react-colorful__hue",x]);return(0,e.createVNode)(1,"div",O,(0,e.createComponentVNode)(2,S.Interactive,{onMove:D,onKey:M,"aria-label":"Hue","aria-valuenow":Math.round(E),"aria-valuemax":"360","aria-valuemin":"0",children:(0,e.createComponentVNode)(2,o.Pointer,{className:"react-colorful__hue-pointer",left:E/360,color:(0,y.hsvaToHslString)({h:E,s:100,v:100,a:1})})}),2)},B=function(A){var x=A.className,E=A.color,P=A.onChange,D=function(F){P({s:100*F.left})},M=function(F){P({s:(0,b.clamp)(E.s+F.left*100,0,100)})},O=(0,k.classes)(["react-colorful__saturation",x]);return(0,e.createVNode)(1,"div",O,(0,e.createComponentVNode)(2,S.Interactive,{style:{background:"linear-gradient(to right, "+(0,y.hsvaToHslString)({h:E.h,s:0,v:E.v,a:1})+", "+(0,y.hsvaToHslString)({h:E.h,s:100,v:E.v,a:1})+")"},onMove:D,onKey:M,"aria-label":"Saturation","aria-valuenow":Math.round(E.s),"aria-valuemax":"100","aria-valuemin":"0",children:(0,e.createComponentVNode)(2,o.Pointer,{className:"react-colorful__saturation-pointer",left:E.s/100,color:(0,y.hsvaToHslString)({h:E.h,s:E.s,v:E.v,a:1})})}),2)},I=function(A){var x=A.className,E=A.color,P=A.onChange,D=function(F){P({v:100*F.left})},M=function(F){P({v:(0,b.clamp)(E.v+F.left*100,0,100)})},O=(0,k.classes)(["react-colorful__value",x]);return(0,e.createVNode)(1,"div",O,(0,e.createComponentVNode)(2,S.Interactive,{style:{background:"linear-gradient(to right, "+(0,y.hsvaToHslString)({h:E.h,s:E.s,v:0,a:1})+", "+(0,y.hsvaToHslString)({h:E.h,s:E.s,v:100,a:1})+")"},onMove:D,onKey:M,"aria-label":"Value","aria-valuenow":Math.round(E.s),"aria-valuemax":"100","aria-valuemin":"0",children:(0,e.createComponentVNode)(2,o.Pointer,{className:"react-colorful__value-pointer",left:E.v/100,color:(0,y.hsvaToHslString)({h:E.h,s:E.s,v:E.v,a:1})})}),2)},L=function(A){var x=A.className,E=A.color,P=A.onChange,D=A.target,M=(0,y.hsvaToRgba)(E),O=function($){M[D]=$,P((0,y.rgbaToHsva)(M))},R=function($){O(255*$.left)},F=function($){O((0,b.clamp)(M[D]+$.left*255,0,255))},W=(0,k.classes)(["react-colorful__"+D,x]),U=D==="r"?"rgb("+Math.round(M.r)+",0,0)":D==="g"?"rgb(0,"+Math.round(M.g)+",0)":"rgb(0,0,"+Math.round(M.b)+")";return(0,e.createVNode)(1,"div",W,(0,e.createComponentVNode)(2,S.Interactive,{onMove:R,onKey:F,"aria-valuenow":M[D],"aria-valuemax":"100","aria-valuemin":"0",children:(0,e.createComponentVNode)(2,o.Pointer,{className:"react-colorful__"+D+"-pointer",left:M[D]/255,color:U})}),2)}},8444:function(T,r,n){"use strict";r.__esModule=!0,r.ColourMatrixTester=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.ColourMatrixTester=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.colour_data,m=[[{name:"RR",idx:0},{name:"RG",idx:1},{name:"RB",idx:2},{name:"RA",idx:3}],[{name:"GR",idx:4},{name:"GG",idx:5},{name:"GB",idx:6},{name:"GA",idx:7}],[{name:"BR",idx:8},{name:"BG",idx:9},{name:"BB",idx:10},{name:"BA",idx:11}],[{name:"AR",idx:12},{name:"AG",idx:13},{name:"AB",idx:14},{name:"AA",idx:15}]];return(0,e.createComponentVNode)(2,o.Window,{width:360,height:190,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Modify Matrix",children:m.map(function(l){return(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",textColor:"label",children:l.map(function(u){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,mt:1,children:[u.name,":\xA0",(0,e.createComponentVNode)(2,t.NumberInput,{width:4,value:c[u.idx],step:.05,minValue:-5,maxValue:5,stepPixelSize:5,onChange:function(){function s(d,v){return h("setvalue",{idx:u.idx+1,value:v})}return s}()})]},u.name)})},l)})})})})})}return b}()},63818:function(T,r,n){"use strict";r.__esModule=!0,r.CommunicationsComputer=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=function(s){switch(s){case 1:return(0,e.createComponentVNode)(2,S);case 2:return(0,e.createComponentVNode)(2,i);case 3:return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:(0,e.createComponentVNode)(2,c)})});case 4:return(0,e.createComponentVNode)(2,l);default:return"ERROR. Unknown menu_state. Please contact NT Technical Support."}},b=r.CommunicationsComputer=function(){function u(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.menu_state;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:600,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,y),p(f)]})})})}return u}(),y=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.authenticated,N=C.noauthbutton,V=C.esc_section,B=C.esc_callable,I=C.esc_recallable,L=C.esc_status,w=C.authhead,A=C.is_ai,x=C.lastCallLoc,E=!1,P;return f?f===1?P="Command":f===2?P="Captain":f===3?P="CentComm Officer":f===4?(P="CentComm Secure Connection",E=!0):P="ERROR: Report This Bug!":P="Not Logged In",(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Authentication",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:E&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Access",children:P})||(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Actions",children:(0,e.createComponentVNode)(2,t.Button,{icon:f?"sign-out-alt":"id-card",selected:f,disabled:N,content:f?"Log Out ("+P+")":"Log In",onClick:function(){function D(){return g("auth")}return D}()})})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:!!V&&(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Escape Shuttle",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[!!L&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:L}),!!B&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Options",children:(0,e.createComponentVNode)(2,t.Button,{icon:"rocket",content:"Call Shuttle",disabled:!w,onClick:function(){function D(){return g("callshuttle")}return D}()})}),!!I&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Options",children:(0,e.createComponentVNode)(2,t.Button,{icon:"times",content:"Recall Shuttle",disabled:!w||A,onClick:function(){function D(){return g("cancelshuttle")}return D}()})}),!!x&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Last Call/Recall From",children:x})]})})})],4)},S=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.is_admin;return f?(0,e.createComponentVNode)(2,k):(0,e.createComponentVNode)(2,h)},k=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.is_admin,N=C.gamma_armory_location,V=C.admin_levels,B=C.authenticated,I=C.ert_allowed;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"CentComm Actions",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Change Alert",children:(0,e.createComponentVNode)(2,m,{levels:V,required_access:f,use_confirm:1})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Announcement",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"bullhorn",content:"Make Central Announcement",disabled:!f,onClick:function(){function L(){return g("send_to_cc_announcement_page")}return L}()}),B===4&&(0,e.createComponentVNode)(2,t.Button,{icon:"plus",content:"Make Other Announcement",disabled:!f,onClick:function(){function L(){return g("make_other_announcement")}return L}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Response Team",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"ambulance",content:"Dispatch ERT",disabled:!f,onClick:function(){function L(){return g("dispatch_ert")}return L}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:I,content:I?"ERT calling enabled":"ERT calling disabled",tooltip:I?"Command can request an ERT":"ERTs cannot be requested",disabled:!f,onClick:function(){function L(){return g("toggle_ert_allowed")}return L}(),selected:null})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Nuclear Device",children:(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"bomb",content:"Get Authentication Codes",disabled:!f,onClick:function(){function L(){return g("send_nuke_codes")}return L}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Gamma Armory",children:(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"biohazard",content:N?"Send Gamma Armory":"Recall Gamma Armory",disabled:!f,onClick:function(){function L(){return g("move_gamma_armory")}return L}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Other",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"coins",content:"View Economy",disabled:!f,onClick:function(){function L(){return g("view_econ")}return L}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fax",content:"Fax Manager",disabled:!f,onClick:function(){function L(){return g("view_fax")}return L}()})]})]})}),(0,e.createComponentVNode)(2,t.Collapsible,{title:"View Command accessible controls",children:(0,e.createComponentVNode)(2,h)})]})},h=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.msg_cooldown,N=C.emagged,V=C.cc_cooldown,B=C.security_level_color,I=C.str_security_level,L=C.levels,w=C.authcapt,A=C.authhead,x=C.messages,E="Make Priority Announcement";f>0&&(E+=" ("+f+"s)");var P=N?"Message [UNKNOWN]":"Message CentComm",D="Request Authentication Codes";return V>0&&(P+=" ("+V+"s)",D+=" ("+V+"s)"),(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Captain-Only Actions",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Alert",color:B,children:I}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Change Alert",children:(0,e.createComponentVNode)(2,m,{levels:L,required_access:w})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Announcement",children:(0,e.createComponentVNode)(2,t.Button,{icon:"bullhorn",content:E,disabled:!w||f>0,onClick:function(){function M(){return g("announce")}return M}()})}),!!N&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Transmit",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"broadcast-tower",color:"red",content:P,disabled:!w||V>0,onClick:function(){function M(){return g("MessageSyndicate")}return M}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"sync-alt",content:"Reset Relays",disabled:!w,onClick:function(){function M(){return g("RestoreBackup")}return M}()})]})||(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Transmit",children:(0,e.createComponentVNode)(2,t.Button,{icon:"broadcast-tower",content:P,disabled:!w||V>0,onClick:function(){function M(){return g("MessageCentcomm")}return M}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Nuclear Device",children:(0,e.createComponentVNode)(2,t.Button,{icon:"bomb",content:D,disabled:!w||V>0,onClick:function(){function M(){return g("nukerequest")}return M}()})})]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Command Staff Actions",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Displays",children:(0,e.createComponentVNode)(2,t.Button,{icon:"tv",content:"Change Status Displays",disabled:!A,onClick:function(){function M(){return g("status")}return M}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Incoming Messages",children:(0,e.createComponentVNode)(2,t.Button,{icon:"folder-open",content:"View ("+x.length+")",disabled:!A,onClick:function(){function M(){return g("messagelist")}return M}()})})]})})})],4)},i=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.stat_display,N=C.authhead,V=C.current_message_title,B=f.presets.map(function(L){return(0,e.createComponentVNode)(2,t.Button,{content:L.label,selected:L.name===f.type,disabled:!N,onClick:function(){function w(){return g("setstat",{statdisp:L.name})}return w}()},L.name)}),I=f.alerts.map(function(L){return(0,e.createComponentVNode)(2,t.Button,{content:L.label,selected:L.alert===f.icon,disabled:!N,onClick:function(){function w(){return g("setstat",{statdisp:3,alert:L.alert})}return w}()},L.alert)});return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Modify Status Screens",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-left",content:"Back To Main Menu",onClick:function(){function L(){return g("main")}return L}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Presets",children:B}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Alerts",children:I}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Message Line 1",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:f.line_1,disabled:!N,onClick:function(){function L(){return g("setmsg1")}return L}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Message Line 2",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:f.line_2,disabled:!N,onClick:function(){function L(){return g("setmsg2")}return L}()})})]})})})},c=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.authhead,N=C.current_message_title,V=C.current_message,B=C.messages,I=C.security_level,L;if(N)L=(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:N,buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"times",content:"Return To Message List",disabled:!f,onClick:function(){function A(){return g("messagelist")}return A}()}),children:(0,e.createComponentVNode)(2,t.Box,{children:V})})});else{var w=B.map(function(A){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:A.title,children:[(0,e.createComponentVNode)(2,t.Button,{icon:"eye",content:"View",disabled:!f||N===A.title,onClick:function(){function x(){return g("messagelist",{msgid:A.id})}return x}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"times",content:"Delete",disabled:!f,onClick:function(){function x(){return g("delmessage",{msgid:A.id})}return x}()})]},A.id)});L=(0,e.createComponentVNode)(2,t.Section,{title:"Messages Received",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-left",content:"Back To Main Menu",onClick:function(){function A(){return g("main")}return A}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:w})})}return(0,e.createComponentVNode)(2,t.Box,{children:L})},m=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=s.levels,N=s.required_access,V=s.use_confirm,B=C.security_level;return V?f.map(function(I){return(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:I.icon,content:I.name,disabled:!N||I.id===B,tooltip:I.tooltip,onClick:function(){function L(){return g("newalertlevel",{level:I.id})}return L}()},I.name)}):f.map(function(I){return(0,e.createComponentVNode)(2,t.Button,{icon:I.icon,content:I.name,disabled:!N||I.id===B,tooltip:I.tooltip,onClick:function(){function L(){return g("newalertlevel",{level:I.id})}return L}()},I.name)})},l=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.is_admin,N=C.possible_cc_sounds;if(!f)return g("main");var V=(0,a.useLocalState)(d,"subtitle",""),B=V[0],I=V[1],L=(0,a.useLocalState)(d,"text",""),w=L[0],A=L[1],x=(0,a.useLocalState)(d,"classified",0),E=x[0],P=x[1],D=(0,a.useLocalState)(d,"beepsound","Beep"),M=D[0],O=D[1];return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Central Command Report",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-left",content:"Back To Main Menu",onClick:function(){function R(){return g("main")}return R}()}),children:[(0,e.createComponentVNode)(2,t.Input,{placeholder:"Enter Subtitle here.",fluid:!0,value:B,onChange:function(){function R(F,W){return I(W)}return R}(),mb:"5px"}),(0,e.createComponentVNode)(2,t.Input,{placeholder:"Enter Announcement here,\nMultiline input is accepted.",rows:10,fluid:!0,multiline:1,value:w,onChange:function(){function R(F,W){return A(W)}return R}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{content:"Send Announcement",fluid:!0,icon:"paper-plane",center:!0,mt:"5px",textAlign:"center",onClick:function(){function R(){return g("make_cc_announcement",{subtitle:B,text:w,classified:E,beepsound:M})}return R}()}),(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Dropdown,{width:"260px",height:"20px",options:N,selected:M,onSelected:function(){function R(F){return O(F)}return R}(),disabled:E})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"volume-up",mx:"5px",disabled:E,tooltip:"Test sound",onClick:function(){function R(){return g("test_sound",{sound:M})}return R}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:E,content:"Classified",fluid:!0,tooltip:E?"Sent to station communications consoles":"Publically announced",onClick:function(){function R(){return P(!E)}return R}()})})]})]})})}},20562:function(T,r,n){"use strict";r.__esModule=!0,r.CompostBin=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.CompostBin=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.biomass,m=i.compost,l=i.biomass_capacity,u=i.compost_capacity,s=i.potassium,d=i.potassium_capacity,v=i.potash,g=i.potash_capacity,C=(0,a.useSharedState)(S,"vendAmount",1),f=C[0],N=C[1];return(0,e.createComponentVNode)(2,o.Window,{width:360,height:250,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Section,{label:"Resources",children:(0,e.createComponentVNode)(2,t.Stack,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Biomass",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ml:.5,mt:1,width:20,value:c,minValue:0,maxValue:l,ranges:{good:[l*.5,1/0],average:[l*.25,l*.5],bad:[-1/0,l*.25]},children:[c," / ",l," Units"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Compost",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ml:.5,mt:1,width:20,value:m,minValue:0,maxValue:u,ranges:{good:[u*.5,1/0],average:[u*.25,u*.5],bad:[-1/0,u*.25]},children:[m," / ",u," Units"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Potassium",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ml:.5,mt:1,width:20,value:s,minValue:0,maxValue:d,ranges:{good:[d*.5,1/0],average:[d*.25,d*.5],bad:[-1/0,d*.25]},children:[s," / ",d," Units"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Potash",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ml:.5,mt:1,width:20,value:v,minValue:0,maxValue:g,ranges:{good:[g*.5,1/0],average:[g*.25,g*.5],bad:[-1/0,g*.25]},children:[v," / ",g," Units"]})})]})})}),(0,e.createComponentVNode)(2,t.Section,{title:"Controls",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{inline:!0,mr:"5px",color:"silver",children:"Soil clumps to make:"}),(0,e.createComponentVNode)(2,t.NumberInput,{animated:!0,value:f,width:"32px",minValue:1,maxValue:10,stepPixelSize:7,onChange:function(){function V(B,I){return N(I)}return V}()})],4),children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,align:"center",content:"Make Soil",disabled:m<25*f,icon:"arrow-circle-down",onClick:function(){function V(){return h("create",{amount:f})}return V}()})})})]})})})}return b}()},21813:function(T,r,n){"use strict";r.__esModule=!0,r.Contractor=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=n(73379),b=n(98595);function y(g,C){g.prototype=Object.create(C.prototype),g.prototype.constructor=g,S(g,C)}function S(g,C){return S=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(f,N){return f.__proto__=N,f},S(g,C)}var k={1:["ACTIVE","good"],2:["COMPLETED","good"],3:["FAILED","bad"]},h=["Recording biometric data...","Analyzing embedded syndicate info...","STATUS CONFIRMED","Contacting Syndicate database...","Awaiting response...","Awaiting response...","Awaiting response...","Awaiting response...","Awaiting response...","Awaiting response...","Response received, ack 4851234...","CONFIRM ACC "+Math.round(Math.random()*2e4),"Setting up private accounts...","CONTRACTOR ACCOUNT CREATED","Searching for available contracts...","Searching for available contracts...","Searching for available contracts...","Searching for available contracts...","CONTRACTS FOUND","WELCOME, AGENT"],i=r.Contractor=function(){function g(C,f){var N=(0,t.useBackend)(f),V=N.act,B=N.data,I;B.unauthorized?I=(0,e.createComponentVNode)(2,o.Flex.Item,{grow:"1",backgroundColor:"rgba(0, 0, 0, 0.8)",children:(0,e.createComponentVNode)(2,d,{height:"100%",allMessages:["ERROR: UNAUTHORIZED USER"],finishedTimeout:100,onFinished:function(){function x(){}return x}()})}):B.load_animation_completed?I=(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Flex.Item,{basis:"content",children:(0,e.createComponentVNode)(2,c)}),(0,e.createComponentVNode)(2,o.Flex.Item,{basis:"content",mt:"0.5rem",children:(0,e.createComponentVNode)(2,m)}),(0,e.createComponentVNode)(2,o.Flex.Item,{grow:"1",overflow:"hidden",children:B.page===1?(0,e.createComponentVNode)(2,l,{height:"100%"}):(0,e.createComponentVNode)(2,s,{height:"100%"})})],4):I=(0,e.createComponentVNode)(2,o.Flex.Item,{grow:"1",backgroundColor:"rgba(0, 0, 0, 0.8)",children:(0,e.createComponentVNode)(2,d,{height:"100%",allMessages:h,finishedTimeout:3e3,onFinished:function(){function x(){return V("complete_load_animation")}return x}()})});var L=(0,t.useLocalState)(f,"viewingPhoto",""),w=L[0],A=L[1];return(0,e.createComponentVNode)(2,b.Window,{theme:"syndicate",width:500,height:600,children:[w&&(0,e.createComponentVNode)(2,v),(0,e.createComponentVNode)(2,b.Window.Content,{className:"Contractor",children:(0,e.createComponentVNode)(2,o.Flex,{direction:"column",height:"100%",children:I})})]})}return g}(),c=function(C,f){var N=(0,t.useBackend)(f),V=N.act,B=N.data,I=B.tc_available,L=B.tc_paid_out,w=B.completed_contracts,A=B.rep;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({title:"Summary",buttons:(0,e.createComponentVNode)(2,o.Box,{verticalAlign:"middle",mt:"0.25rem",children:[A," Rep"]})},C,{children:(0,e.createComponentVNode)(2,o.Flex,{children:[(0,e.createComponentVNode)(2,o.Box,{flexBasis:"50%",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"TC Available",verticalAlign:"middle",children:(0,e.createComponentVNode)(2,o.Flex,{align:"center",children:[(0,e.createComponentVNode)(2,o.Flex.Item,{grow:"1",children:[I," TC"]}),(0,e.createComponentVNode)(2,o.Button,{disabled:I<=0,content:"Claim",mx:"0.75rem",mb:"0",flexBasis:"content",onClick:function(){function x(){return V("claim")}return x}()})]})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"TC Earned",children:[L," TC"]})]})}),(0,e.createComponentVNode)(2,o.Box,{flexBasis:"50%",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Contracts Completed",verticalAlign:"middle",children:(0,e.createComponentVNode)(2,o.Box,{height:"20px",lineHeight:"20px",inline:!0,children:w})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Contractor Status",verticalAlign:"middle",children:"ACTIVE"})]})})]})})))},m=function(C,f){var N=(0,t.useBackend)(f),V=N.act,B=N.data,I=B.page;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Tabs,Object.assign({},C,{children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:I===1,onClick:function(){function L(){return V("page",{page:1})}return L}(),children:[(0,e.createComponentVNode)(2,o.Icon,{name:"suitcase"}),"Contracts"]}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:I===2,onClick:function(){function L(){return V("page",{page:2})}return L}(),children:[(0,e.createComponentVNode)(2,o.Icon,{name:"shopping-cart"}),"Hub"]})]})))},l=function(C,f){var N=(0,t.useBackend)(f),V=N.act,B=N.data,I=B.contracts,L=B.contract_active,w=B.can_extract,A=!!L&&I.filter(function(M){return M.status===1})[0],x=A&&A.time_left>0,E=(0,t.useLocalState)(f,"viewingPhoto",""),P=E[0],D=E[1];return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({title:"Available Contracts",overflow:"auto",buttons:(0,e.createComponentVNode)(2,o.Button,{disabled:!w||x,icon:"parachute-box",content:["Call Extraction",x&&(0,e.createComponentVNode)(2,p.Countdown,{timeLeft:A.time_left,format:function(){function M(O,R){return" ("+R.substr(3)+")"}return M}()})],onClick:function(){function M(){return V("extract")}return M}()})},C,{children:I.slice().sort(function(M,O){return M.status===1?-1:O.status===1?1:M.status-O.status}).map(function(M){var O;return(0,e.createComponentVNode)(2,o.Section,{title:(0,e.createComponentVNode)(2,o.Flex,{children:[(0,e.createComponentVNode)(2,o.Flex.Item,{grow:"1",color:M.status===1&&"good",children:M.target_name}),(0,e.createComponentVNode)(2,o.Flex.Item,{basis:"content",children:M.has_photo&&(0,e.createComponentVNode)(2,o.Button,{icon:"camera",mb:"-0.5rem",ml:"0.5rem",onClick:function(){function R(){return D("target_photo_"+M.uid+".png")}return R}()})})]}),className:"Contractor__Contract",buttons:(0,e.createComponentVNode)(2,o.Box,{width:"100%",children:[!!k[M.status]&&(0,e.createComponentVNode)(2,o.Box,{color:k[M.status][1],inline:!0,mt:M.status!==1&&"0.125rem",mr:"0.25rem",lineHeight:"20px",children:k[M.status][0]}),M.status===1&&(0,e.createComponentVNode)(2,o.Button.Confirm,{icon:"ban",color:"bad",content:"Abort",ml:"0.5rem",onClick:function(){function R(){return V("abort")}return R}()})]}),children:(0,e.createComponentVNode)(2,o.Flex,{children:[(0,e.createComponentVNode)(2,o.Flex.Item,{grow:"2",mr:"0.5rem",children:[M.fluff_message,!!M.completed_time&&(0,e.createComponentVNode)(2,o.Box,{color:"good",children:[(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.Icon,{name:"check",mr:"0.5rem"}),"Contract completed at ",M.completed_time]}),!!M.dead_extraction&&(0,e.createComponentVNode)(2,o.Box,{color:"bad",mt:"0.5rem",bold:!0,children:[(0,e.createComponentVNode)(2,o.Icon,{name:"exclamation-triangle",mr:"0.5rem"}),"Telecrystals reward reduced drastically as the target was dead during extraction."]}),!!M.fail_reason&&(0,e.createComponentVNode)(2,o.Box,{color:"bad",children:[(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.Icon,{name:"times",mr:"0.5rem"}),"Contract failed: ",M.fail_reason]})]}),(0,e.createComponentVNode)(2,o.Flex.Item,{flexBasis:"100%",children:[(0,e.createComponentVNode)(2,o.Flex,{mb:"0.5rem",color:"label",children:["Extraction Zone:\xA0",u(M)]}),(O=M.difficulties)==null?void 0:O.map(function(R,F){return(0,e.createComponentVNode)(2,o.Button.Confirm,{disabled:!!L,content:R.name+" ("+R.reward+" TC)",onClick:function(){function W(){return V("activate",{uid:M.uid,difficulty:F+1})}return W}()},F)}),!!M.objective&&(0,e.createComponentVNode)(2,o.Box,{color:"white",bold:!0,children:[M.objective.extraction_name,(0,e.createVNode)(1,"br"),"(",(M.objective.rewards.tc||0)+" TC",",\xA0",(M.objective.rewards.credits||0)+" Credits",")"]})]})]})},M.uid)})})))},u=function(C){if(!(!C.objective||C.status>1)){var f=C.objective.locs.user_area_id,N=C.objective.locs.user_coords,V=C.objective.locs.target_area_id,B=C.objective.locs.target_coords,I=f===V;return(0,e.createComponentVNode)(2,o.Flex.Item,{children:(0,e.createComponentVNode)(2,o.Icon,{name:I?"dot-circle-o":"arrow-alt-circle-right-o",color:I?"green":"yellow",rotation:I?null:-(0,a.rad2deg)(Math.atan2(B[1]-N[1],B[0]-N[0])),lineHeight:I?null:"0.85",size:"1.5"})})}},s=function(C,f){var N=(0,t.useBackend)(f),V=N.act,B=N.data,I=B.rep,L=B.buyables;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({title:"Available Purchases",overflow:"auto"},C,{children:L.map(function(w){return(0,e.createComponentVNode)(2,o.Section,{title:w.name,children:[w.description,(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.Button.Confirm,{disabled:I-1&&(0,e.createComponentVNode)(2,o.Box,{as:"span",color:w.stock===0?"bad":"good",ml:"0.5rem",children:[w.stock," in stock"]})]},w.uid)})})))},d=function(g){function C(N){var V;return V=g.call(this,N)||this,V.timer=null,V.state={currentIndex:0,currentDisplay:[]},V}y(C,g);var f=C.prototype;return f.tick=function(){function N(){var V=this.props,B=this.state;if(B.currentIndex<=V.allMessages.length){this.setState(function(L){return{currentIndex:L.currentIndex+1}});var I=B.currentDisplay;I.push(V.allMessages[B.currentIndex])}else clearTimeout(this.timer),setTimeout(V.onFinished,V.finishedTimeout)}return N}(),f.componentDidMount=function(){function N(){var V=this,B=this.props.linesPerSecond,I=B===void 0?2.5:B;this.timer=setInterval(function(){return V.tick()},1e3/I)}return N}(),f.componentWillUnmount=function(){function N(){clearTimeout(this.timer)}return N}(),f.render=function(){function N(){return(0,e.createComponentVNode)(2,o.Box,{m:1,children:this.state.currentDisplay.map(function(V){return(0,e.createFragment)([V,(0,e.createVNode)(1,"br")],0,V)})})}return N}(),C}(e.Component),v=function(C,f){var N=(0,t.useLocalState)(f,"viewingPhoto",""),V=N[0],B=N[1];return(0,e.createComponentVNode)(2,o.Modal,{className:"Contractor__photoZoom",children:[(0,e.createComponentVNode)(2,o.Box,{as:"img",src:V}),(0,e.createComponentVNode)(2,o.Button,{icon:"times",content:"Close",color:"grey",mt:"1rem",onClick:function(){function I(){return B("")}return I}()})]})}},54151:function(T,r,n){"use strict";r.__esModule=!0,r.ConveyorSwitch=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.ConveyorSwitch=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.slowFactor,m=i.oneWay,l=i.position;return(0,e.createComponentVNode)(2,o.Window,{width:350,height:135,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Lever position",children:l>0?"forward":l<0?"reverse":"neutral"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Allow reverse",children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:!m,onClick:function(){function u(){return h("toggleOneWay")}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Slowdown factor",children:(0,e.createComponentVNode)(2,t.Flex,{children:[(0,e.createComponentVNode)(2,t.Flex.Item,{mx:"1px",children:[" ",(0,e.createComponentVNode)(2,t.Button,{icon:"angle-double-left",onClick:function(){function u(){return h("slowFactor",{value:c-5})}return u}()})," "]}),(0,e.createComponentVNode)(2,t.Flex.Item,{mx:"1px",children:[" ",(0,e.createComponentVNode)(2,t.Button,{icon:"angle-left",onClick:function(){function u(){return h("slowFactor",{value:c-1})}return u}()})," "]}),(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,t.Slider,{width:"100px",mx:"1px",value:c,fillValue:c,minValue:1,maxValue:50,step:1,format:function(){function u(s){return s+"x"}return u}(),onChange:function(){function u(s,d){return h("slowFactor",{value:d})}return u}()})}),(0,e.createComponentVNode)(2,t.Flex.Item,{mx:"1px",children:[" ",(0,e.createComponentVNode)(2,t.Button,{icon:"angle-right",onClick:function(){function u(){return h("slowFactor",{value:c+1})}return u}()})," "]}),(0,e.createComponentVNode)(2,t.Flex.Item,{mx:"1px",children:[" ",(0,e.createComponentVNode)(2,t.Button,{icon:"angle-double-right",onClick:function(){function u(){return h("slowFactor",{value:c+5})}return u}()})," "]})]})})]})})})})}return b}()},73169:function(T,r,n){"use strict";r.__esModule=!0,r.CrewMonitor=void 0;var e=n(89005),a=n(88510),t=n(25328),o=n(72253),p=n(36036),b=n(36352),y=n(76910),S=n(98595),k=n(96184),h=["color"];function i(v,g){if(v==null)return{};var C={};for(var f in v)if({}.hasOwnProperty.call(v,f)){if(g.includes(f))continue;C[f]=v[f]}return C}var c=function(g,C){return g.dead?"Deceased":parseInt(g.health,10)<=C?"Critical":parseInt(g.stat,10)===1?"Unconscious":"Living"},m=function(g,C){return g.dead?"red":parseInt(g.health,10)<=C?"orange":parseInt(g.stat,10)===1?"blue":"green"},l=r.CrewMonitor=function(){function v(g,C){var f=(0,o.useBackend)(C),N=f.act,V=f.data,B=(0,o.useLocalState)(C,"tabIndex",V.tabIndex),I=B[0],L=B[1],w=function(){function x(E){L(E),N("set_tab_index",{tab_index:E})}return x}(),A=function(){function x(E){switch(E){case 0:return(0,e.createComponentVNode)(2,u);case 1:return(0,e.createComponentVNode)(2,d);default:return"WE SHOULDN'T BE HERE!"}}return x}();return(0,e.createComponentVNode)(2,S.Window,{width:800,height:600,children:(0,e.createComponentVNode)(2,S.Window.Content,{children:(0,e.createComponentVNode)(2,p.Stack,{fill:!0,vertical:!0,fillPositionedParent:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Tabs,{children:[(0,e.createComponentVNode)(2,p.Tabs.Tab,{icon:"table",selected:I===0,onClick:function(){function x(){return w(0)}return x}(),children:"Data View"},"DataView"),(0,e.createComponentVNode)(2,p.Tabs.Tab,{icon:"map-marked-alt",selected:I===1,onClick:function(){function x(){return w(1)}return x}(),children:"Map View"},"MapView")]})}),A(I)]})})})}return v}(),u=function(g,C){var f=(0,o.useBackend)(C),N=f.act,V=f.data,B=V.possible_levels,I=V.viewing_current_z_level,L=V.is_advanced,w=V.highlightedNames,A=(0,a.sortBy)(function(M){return!w.includes(M.name)},function(M){return M.name})(V.crewmembers||[]),x=(0,o.useLocalState)(C,"search",""),E=x[0],P=x[1],D=(0,t.createSearch)(E,function(M){return M.name+"|"+M.assignment+"|"+M.area});return(0,e.createComponentVNode)(2,p.Section,{fill:!0,scrollable:!0,backgroundColor:"transparent",children:[(0,e.createComponentVNode)(2,p.Stack,{children:[(0,e.createComponentVNode)(2,p.Stack.Item,{width:"100%",ml:"5px",children:(0,e.createComponentVNode)(2,p.Input,{placeholder:"Search by name, assignment or location..",width:"100%",onInput:function(){function M(O,R){return P(R)}return M}()})}),(0,e.createComponentVNode)(2,p.Stack.Item,{children:L?(0,e.createComponentVNode)(2,p.Dropdown,{mr:"5px",width:"50px",options:B,selected:I,onSelected:function(){function M(O){return N("switch_level",{new_level:O})}return M}()}):null})]}),(0,e.createComponentVNode)(2,p.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,p.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,p.Table.Cell,{children:(0,e.createComponentVNode)(2,p.Button,{tooltip:"Clear highlights",icon:"square-xmark",onClick:function(){function M(){return N("clear_highlighted_names")}return M}()})}),(0,e.createComponentVNode)(2,p.Table.Cell,{children:"Name"}),(0,e.createComponentVNode)(2,p.Table.Cell,{children:"Status"}),(0,e.createComponentVNode)(2,p.Table.Cell,{children:"Location"})]}),A.filter(D).map(function(M){var O=w.includes(M.name);return(0,e.createComponentVNode)(2,p.Table.Row,{bold:!!M.is_command,children:[(0,e.createComponentVNode)(2,b.TableCell,{children:(0,e.createComponentVNode)(2,k.ButtonCheckbox,{checked:O,tooltip:"Mark on map",onClick:function(){function R(){return N(O?"remove_highlighted_name":"add_highlighted_name",{name:M.name})}return R}()})}),(0,e.createComponentVNode)(2,b.TableCell,{children:[M.name," (",M.assignment,")"]}),(0,e.createComponentVNode)(2,b.TableCell,{children:[(0,e.createComponentVNode)(2,p.Box,{inline:!0,color:m(M,V.critThreshold),children:c(M,V.critThreshold)}),M.sensor_type>=2||V.ignoreSensors?(0,e.createComponentVNode)(2,p.Box,{inline:!0,ml:1,children:["(",(0,e.createComponentVNode)(2,p.Box,{inline:!0,color:y.COLORS.damageType.oxy,children:M.oxy}),"|",(0,e.createComponentVNode)(2,p.Box,{inline:!0,color:y.COLORS.damageType.toxin,children:M.tox}),"|",(0,e.createComponentVNode)(2,p.Box,{inline:!0,color:y.COLORS.damageType.burn,children:M.fire}),"|",(0,e.createComponentVNode)(2,p.Box,{inline:!0,color:y.COLORS.damageType.brute,children:M.brute}),")"]}):null]}),(0,e.createComponentVNode)(2,b.TableCell,{children:M.sensor_type===3||V.ignoreSensors?V.isAI||V.isObserver?(0,e.createComponentVNode)(2,p.Button,{fluid:!0,icon:"location-arrow",content:M.area+" ("+M.x+", "+M.y+")",onClick:function(){function R(){return N("track",{track:M.ref})}return R}()}):M.area+" ("+M.x+", "+M.y+")":(0,e.createComponentVNode)(2,p.Box,{inline:!0,color:"grey",children:"Not Available"})})]},M.name)})]})]})},s=function(g,C){var f=g.color,N=i(g,h);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,p.NanoMap.Marker,Object.assign({},N,{children:(0,e.createVNode)(1,"span","highlighted-marker color-border-"+f)})))},d=function(g,C){var f=(0,o.useBackend)(C),N=f.act,V=f.data,B=V.highlightedNames;return(0,e.createComponentVNode)(2,p.Box,{height:"100vh",mb:"0.5rem",overflow:"hidden",children:(0,e.createComponentVNode)(2,p.NanoMap,{zoom:V.zoom,offsetX:V.offsetX,offsetY:V.offsetY,onZoom:function(){function I(L){return N("set_zoom",{zoom:L})}return I}(),onOffsetChange:function(){function I(L,w){return N("set_offset",{offset_x:w.offsetX,offset_y:w.offsetY})}return I}(),children:V.crewmembers.filter(function(I){return I.sensor_type===3||V.ignoreSensors}).map(function(I){var L=m(I,V.critThreshold),w=B.includes(I.name),A=function(){return V.isObserver?N("track",{track:I.ref}):null},x=function(){return N(w?"remove_highlighted_name":"add_highlighted_name",{name:I.name})},E=I.name+" ("+I.assignment+")";return w?(0,e.createComponentVNode)(2,s,{x:I.x,y:I.y,tooltip:E,color:L,onClick:A,onDblClick:x},I.ref):(0,e.createComponentVNode)(2,p.NanoMap.MarkerIcon,{x:I.x,y:I.y,icon:"circle",tooltip:E,color:L,onClick:A,onDblClick:x},I.ref)})})})}},63987:function(T,r,n){"use strict";r.__esModule=!0,r.Cryo=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=[{label:"Resp.",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Brute",type:"bruteLoss"},{label:"Burn",type:"fireLoss"}],b=[["good","Conscious"],["average","Unconscious"],["bad","DEAD"]],y=r.Cryo=function(){function h(i,c){return(0,e.createComponentVNode)(2,o.Window,{width:520,height:500,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,S)})})})}return h}(),S=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.isOperating,d=u.hasOccupant,v=u.occupant,g=v===void 0?[]:v,C=u.cellTemperature,f=u.cellTemperatureStatus,N=u.isBeakerLoaded,V=u.cooldownProgress,B=u.auto_eject_healthy,I=u.auto_eject_dead;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Occupant",fill:!0,scrollable:!0,buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"user-slash",onClick:function(){function L(){return l("ejectOccupant")}return L}(),disabled:!d,children:"Eject"}),children:d?(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Occupant",children:g.name||"Unknown"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Health",children:(0,e.createComponentVNode)(2,t.ProgressBar,{min:g.health,max:g.maxHealth,value:g.health/g.maxHealth,color:g.health>0?"good":"average",children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:Math.round(g.health)})})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",color:b[g.stat][0],children:b[g.stat][1]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Temperature",children:[(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:Math.round(g.bodyTemperature)})," K"]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),p.map(function(L){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:L.label,children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:g[L.type]/100,ranges:{bad:[.01,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:Math.round(g[L.type])})})},L.id)})]}):(0,e.createComponentVNode)(2,t.Stack,{fill:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),"No occupant detected."]})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Cell",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"eject",onClick:function(){function L(){return l("ejectBeaker")}return L}(),disabled:!N,children:"Eject Beaker"}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:(0,e.createComponentVNode)(2,t.Button,{icon:"power-off",onClick:function(){function L(){return l(s?"switchOff":"switchOn")}return L}(),selected:s,children:s?"On":"Off"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Temperature",color:f,children:[(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:C})," K"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Beaker",children:(0,e.createComponentVNode)(2,k)}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Dosage interval",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ranges:{average:[-1/0,99],good:[99,1/0]},color:!N&&"average",value:V,minValue:0,maxValue:100})}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Auto-eject healthy occupants",children:(0,e.createComponentVNode)(2,t.Button,{icon:B?"toggle-on":"toggle-off",selected:B,onClick:function(){function L(){return l(B?"auto_eject_healthy_off":"auto_eject_healthy_on")}return L}(),children:B?"On":"Off"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Auto-eject dead occupants",children:(0,e.createComponentVNode)(2,t.Button,{icon:I?"toggle-on":"toggle-off",selected:I,onClick:function(){function L(){return l(I?"auto_eject_dead_off":"auto_eject_dead_on")}return L}(),children:I?"On":"Off"})})]})})})],4)},k=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.isBeakerLoaded,d=u.beakerLabel,v=u.beakerVolume;return s?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:!d&&"average",children:[d||"No label",":"]}),(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:!v&&"bad",ml:1,children:v?(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:v,format:function(){function g(C){return Math.round(C)+" units remaining"}return g}()}):"Beaker is empty"})],4):(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:"bad",children:"No beaker loaded"})}},86099:function(T,r,n){"use strict";r.__esModule=!0,r.CryopodConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(25328),b=r.CryopodConsole=function(){function k(h,i){var c=(0,a.useBackend)(i),m=c.data,l=m.account_name,u=m.allow_items;return(0,e.createComponentVNode)(2,o.Window,{title:"Cryopod Console",width:400,height:480,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Hello, "+(l||"[REDACTED]")+"!",children:"This automated cryogenic freezing unit will safely store your corporeal form until your next assignment."}),(0,e.createComponentVNode)(2,y),!!u&&(0,e.createComponentVNode)(2,S)]})})}return k}(),y=function(h,i){var c=(0,a.useBackend)(i),m=c.data,l=m.frozen_crew;return(0,e.createComponentVNode)(2,t.Collapsible,{title:"Stored Crew",children:l.length?(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:l.map(function(u,s){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:u.name,children:u.rank},s)})})}):(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No stored crew!"})})},S=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.frozen_items,s=function(v){var g=v.toString();return g.startsWith("the ")&&(g=g.slice(4,g.length)),(0,p.toTitleCase)(g)};return(0,e.createComponentVNode)(2,t.Collapsible,{title:"Stored Items",children:u.length?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:u.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:s(d.name),buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-down",content:"Drop",mr:1,onClick:function(){function v(){return m("one_item",{item:d.uid})}return v}()})},d)})})}),(0,e.createComponentVNode)(2,t.Button,{content:"Drop All Items",color:"red",onClick:function(){function d(){return m("all_items")}return d}()})],4):(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No stored items!"})})}},12692:function(T,r,n){"use strict";r.__esModule=!0,r.DNAModifier=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(3939),b=[["good","Alive"],["average","Critical"],["bad","DEAD"]],y=[["ui","Modify U.I.","dna"],["se","Modify S.E.","dna"],["buffer","Transfer Buffers","syringe"],["rejuvenators","Rejuvenators","flask"]],S=[5,10,20,30,50],k=r.DNAModifier=function(){function f(N,V){var B=(0,a.useBackend)(V),I=B.act,L=B.data,w=L.irradiating,A=L.dnaBlockSize,x=L.occupant;V.dnaBlockSize=A,V.isDNAInvalid=!x.isViableSubject||!x.uniqueIdentity||!x.structuralEnzymes;var E;return w&&(E=(0,e.createComponentVNode)(2,g,{duration:w})),(0,e.createComponentVNode)(2,o.Window,{width:660,height:775,children:[(0,e.createComponentVNode)(2,p.ComplexModal),E,(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,h)}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,i)})]})})]})}return f}(),h=function(N,V){var B=(0,a.useBackend)(V),I=B.act,L=B.data,w=L.locked,A=L.hasOccupant,x=L.occupant;return(0,e.createComponentVNode)(2,t.Section,{title:"Occupant",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{color:"label",inline:!0,mr:"0.5rem",children:"Door Lock:"}),(0,e.createComponentVNode)(2,t.Button,{disabled:!A,selected:w,icon:w?"toggle-on":"toggle-off",content:w?"Engaged":"Disengaged",onClick:function(){function E(){return I("toggleLock")}return E}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:!A||w,icon:"user-slash",content:"Eject",onClick:function(){function E(){return I("ejectOccupant")}return E}()})],4),children:A?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Name",children:x.name}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Health",children:(0,e.createComponentVNode)(2,t.ProgressBar,{min:x.minHealth,max:x.maxHealth,value:x.health/x.maxHealth,ranges:{good:[.5,1/0],average:[0,.5],bad:[-1/0,0]}})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",color:b[x.stat][0],children:b[x.stat][1]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider)]})}),V.isDNAInvalid?(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"exclamation-circle"}),"\xA0 The occupant's DNA structure is ruined beyond recognition, please insert a subject with an intact DNA structure."]}):(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Radiation",children:(0,e.createComponentVNode)(2,t.ProgressBar,{min:"0",max:"100",value:x.radiationLevel/100,color:"average"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Unique Enzymes",children:L.occupant.uniqueEnzymes?L.occupant.uniqueEnzymes:(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"exclamation-circle"}),"\xA0 Unknown"]})})]})],0):(0,e.createComponentVNode)(2,t.Box,{color:"label",children:"Cell unoccupied."})})},i=function(N,V){var B=(0,a.useBackend)(V),I=B.act,L=B.data,w=L.selectedMenuKey,A=L.hasOccupant,x=L.occupant;if(A){if(V.isDNAInvalid)return(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,align:"center",textAlign:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),"No operation possible on this subject."]})})})}else return(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,align:"center",textAlign:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),"No occupant in DNA modifier."]})})});var E;return w==="ui"?E=(0,e.createFragment)([(0,e.createComponentVNode)(2,c),(0,e.createComponentVNode)(2,l)],4):w==="se"?E=(0,e.createFragment)([(0,e.createComponentVNode)(2,m),(0,e.createComponentVNode)(2,l)],4):w==="buffer"?E=(0,e.createComponentVNode)(2,u):w==="rejuvenators"&&(E=(0,e.createComponentVNode)(2,v)),(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:[(0,e.createComponentVNode)(2,t.Tabs,{children:y.map(function(P,D){return(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:P[2],selected:w===P[0],onClick:function(){function M(){return I("selectMenuKey",{key:P[0]})}return M}(),children:P[1]},D)})}),E]})},c=function(N,V){var B=(0,a.useBackend)(V),I=B.act,L=B.data,w=L.selectedUIBlock,A=L.selectedUISubBlock,x=L.selectedUITarget,E=L.occupant;return(0,e.createComponentVNode)(2,t.Section,{title:"Modify Unique Identifier",children:[(0,e.createComponentVNode)(2,C,{dnaString:E.uniqueIdentity,selectedBlock:w,selectedSubblock:A,blockSize:V.dnaBlockSize,action:"selectUIBlock"}),(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Target",children:(0,e.createComponentVNode)(2,t.Knob,{minValue:1,maxValue:15,stepPixelSize:"20",value:x,format:function(){function P(D){return D.toString(16).toUpperCase()}return P}(),ml:"0",onChange:function(){function P(D,M){return I("changeUITarget",{value:M})}return P}()})})}),(0,e.createComponentVNode)(2,t.Button,{icon:"radiation",content:"Irradiate Block",mt:"0.5rem",onClick:function(){function P(){return I("pulseUIRadiation")}return P}()})]})},m=function(N,V){var B=(0,a.useBackend)(V),I=B.act,L=B.data,w=L.selectedSEBlock,A=L.selectedSESubBlock,x=L.occupant;return(0,e.createComponentVNode)(2,t.Section,{title:"Modify Structural Enzymes",children:[(0,e.createComponentVNode)(2,C,{dnaString:x.structuralEnzymes,selectedBlock:w,selectedSubblock:A,blockSize:V.dnaBlockSize,action:"selectSEBlock"}),(0,e.createComponentVNode)(2,t.Button,{icon:"radiation",content:"Irradiate Block",onClick:function(){function E(){return I("pulseSERadiation")}return E}()})]})},l=function(N,V){var B=(0,a.useBackend)(V),I=B.act,L=B.data,w=L.radiationIntensity,A=L.radiationDuration;return(0,e.createComponentVNode)(2,t.Section,{title:"Radiation Emitter",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Intensity",children:(0,e.createComponentVNode)(2,t.Knob,{minValue:1,maxValue:10,stepPixelSize:20,value:w,popUpPosition:"right",ml:"0",onChange:function(){function x(E,P){return I("radiationIntensity",{value:P})}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Duration",children:(0,e.createComponentVNode)(2,t.Knob,{minValue:1,maxValue:20,stepPixelSize:10,unit:"s",value:A,popUpPosition:"right",ml:"0",onChange:function(){function x(E,P){return I("radiationDuration",{value:P})}return x}()})})]}),(0,e.createComponentVNode)(2,t.Button,{icon:"radiation",content:"Pulse Radiation",tooltip:"Mutates a random block of either the occupant's UI or SE.",tooltipPosition:"top-start",mt:"0.5rem",onClick:function(){function x(){return I("pulseRadiation")}return x}()})]})},u=function(N,V){var B=(0,a.useBackend)(V),I=B.act,L=B.data,w=L.buffers,A=w.map(function(x,E){return(0,e.createComponentVNode)(2,s,{id:E+1,name:"Buffer "+(E+1),buffer:x},E)});return(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{height:"75%",mt:1,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Buffers",children:A})}),(0,e.createComponentVNode)(2,t.Stack.Item,{height:"25%",children:(0,e.createComponentVNode)(2,d)})]})},s=function(N,V){var B=(0,a.useBackend)(V),I=B.act,L=B.data,w=N.id,A=N.name,x=N.buffer,E=L.isInjectorReady,P=A+(x.data?" - "+x.label:"");return(0,e.createComponentVNode)(2,t.Box,{backgroundColor:"rgba(0, 0, 0, 0.33)",mb:"0.5rem",children:(0,e.createComponentVNode)(2,t.Section,{title:P,mx:"0",lineHeight:"18px",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button.Confirm,{disabled:!x.data,icon:"trash",content:"Clear",onClick:function(){function D(){return I("bufferOption",{option:"clear",id:w})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:!x.data,icon:"pen",content:"Rename",onClick:function(){function D(){return I("bufferOption",{option:"changeLabel",id:w})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:!x.data||!L.hasDisk,icon:"save",content:"Export",tooltip:"Exports this buffer to the currently loaded data disk.",tooltipPosition:"bottom-start",onClick:function(){function D(){return I("bufferOption",{option:"saveDisk",id:w})}return D}()})],4),children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Write",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-down",content:"Subject U.I",mb:"0",onClick:function(){function D(){return I("bufferOption",{option:"saveUI",id:w})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-down",content:"Subject U.I and U.E.",mb:"0",onClick:function(){function D(){return I("bufferOption",{option:"saveUIAndUE",id:w})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-down",content:"Subject S.E.",mb:"0",onClick:function(){function D(){return I("bufferOption",{option:"saveSE",id:w})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:!L.hasDisk||!L.disk.data,icon:"arrow-circle-down",content:"From Disk",mb:"0",onClick:function(){function D(){return I("bufferOption",{option:"loadDisk",id:w})}return D}()})]}),!!x.data&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Subject",children:x.owner||(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"Unknown"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Data Type",children:[x.type==="ui"?"Unique Identifiers":"Structural Enzymes",!!x.ue&&" and Unique Enzymes"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Transfer to",children:[(0,e.createComponentVNode)(2,t.Button,{disabled:!E,icon:E?"syringe":"spinner",iconSpin:!E,content:"Injector",mb:"0",onClick:function(){function D(){return I("bufferOption",{option:"createInjector",id:w})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:!E,icon:E?"syringe":"spinner",iconSpin:!E,content:"Block Injector",mb:"0",onClick:function(){function D(){return I("bufferOption",{option:"createInjector",id:w,block:1})}return D}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"user",content:"Subject",mb:"0",onClick:function(){function D(){return I("bufferOption",{option:"transfer",id:w})}return D}()})]})],4)]}),!x.data&&(0,e.createComponentVNode)(2,t.Box,{color:"label",mt:"0.5rem",children:"This buffer is empty."})]})})},d=function(N,V){var B=(0,a.useBackend)(V),I=B.act,L=B.data,w=L.hasDisk,A=L.disk;return(0,e.createComponentVNode)(2,t.Section,{title:"Data Disk",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button.Confirm,{disabled:!w||!A.data,icon:"trash",content:"Wipe",onClick:function(){function x(){return I("wipeDisk")}return x}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:!w,icon:"eject",content:"Eject",onClick:function(){function x(){return I("ejectDisk")}return x}()})],4),children:w?A.data?(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Label",children:A.label?A.label:"No label"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Subject",children:A.owner?A.owner:(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"Unknown"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Data Type",children:[A.type==="ui"?"Unique Identifiers":"Structural Enzymes",!!A.ue&&" and Unique Enzymes"]})]}):(0,e.createComponentVNode)(2,t.Box,{color:"label",children:"Disk is blank."}):(0,e.createComponentVNode)(2,t.Box,{color:"label",textAlign:"center",my:"1rem",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"save-o",size:"4"}),(0,e.createVNode)(1,"br"),"No disk inserted."]})})},v=function(N,V){var B=(0,a.useBackend)(V),I=B.act,L=B.data,w=L.isBeakerLoaded,A=L.beakerVolume,x=L.beakerLabel;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Rejuvenators and Beaker",buttons:(0,e.createComponentVNode)(2,t.Button,{disabled:!w,icon:"eject",content:"Eject",onClick:function(){function E(){return I("ejectBeaker")}return E}()}),children:w?(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Inject",children:[S.map(function(E,P){return(0,e.createComponentVNode)(2,t.Button,{disabled:E>A,icon:"syringe",content:E,onClick:function(){function D(){return I("injectRejuvenators",{amount:E})}return D}()},P)}),(0,e.createComponentVNode)(2,t.Button,{disabled:A<=0,icon:"syringe",content:"All",onClick:function(){function E(){return I("injectRejuvenators",{amount:A})}return E}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Beaker",children:[(0,e.createComponentVNode)(2,t.Box,{mb:"0.5rem",children:x||"No label"}),A?(0,e.createComponentVNode)(2,t.Box,{color:"good",children:[A," unit",A===1?"":"s"," remaining"]}):(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:"Empty"})]})]}):(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,textAlign:"center",align:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon.Stack,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"flask",size:5,color:"silver"}),(0,e.createComponentVNode)(2,t.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"h3",null,"No beaker loaded.",16)]})})})},g=function(N,V){return(0,e.createComponentVNode)(2,t.Dimmer,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"spinner",size:"5",spin:!0}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Box,{color:"average",children:(0,e.createVNode)(1,"h1",null,[(0,e.createComponentVNode)(2,t.Icon,{name:"radiation"}),(0,e.createTextVNode)("\xA0Irradiating occupant\xA0"),(0,e.createComponentVNode)(2,t.Icon,{name:"radiation"})],4)}),(0,e.createComponentVNode)(2,t.Box,{color:"label",children:(0,e.createVNode)(1,"h3",null,[(0,e.createTextVNode)("For "),N.duration,(0,e.createTextVNode)(" second"),N.duration===1?"":"s"],0)})]})},C=function(N,V){for(var B=(0,a.useBackend)(V),I=B.act,L=B.data,w=N.dnaString,A=N.selectedBlock,x=N.selectedSubblock,E=N.blockSize,P=N.action,D=w.split(""),M=0,O=[],R=function(){for(var U=F/E+1,z=[],$=function(){var J=G+1;z.push((0,e.createComponentVNode)(2,t.Button,{selected:A===U&&x===J,content:D[F+G],mb:"0",onClick:function(){function se(){return I(P,{block:U,subblock:J})}return se}()}))},G=0;Gd.spawnpoints?"red":"green",children:[d.total," total, versus ",d.spawnpoints," spawnpoints"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Dispatch",children:(0,e.createComponentVNode)(2,t.Button,{width:10.5,textAlign:"center",icon:"ambulance",content:"Send ERT",onClick:function(){function N(){return s("dispatch_ert",{silent:C})}return N}()})})]})})})},h=function(m,l){var u=(0,a.useBackend)(l),s=u.act,d=u.data,v=d.ert_request_messages;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:v&&v.length?v.map(function(g){return(0,e.createComponentVNode)(2,t.Section,{title:g.time,buttons:(0,e.createComponentVNode)(2,t.Button,{content:g.sender_real_name,onClick:function(){function C(){return s("view_player_panel",{uid:g.sender_uid})}return C}(),tooltip:"View player panel"}),children:g.message},(0,p.decodeHtmlEntities)(g.time))}):(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,textAlign:"center",align:"center",color:"average",children:[(0,e.createComponentVNode)(2,t.Icon.Stack,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"broadcast-tower",size:5,color:"gray"}),(0,e.createComponentVNode)(2,t.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"No ERT requests."]})})})})},i=function(m,l){var u=(0,a.useBackend)(l),s=u.act,d=u.data,v=(0,a.useLocalState)(l,"text",""),g=v[0],C=v[1];return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:[(0,e.createComponentVNode)(2,t.Input,{placeholder:"Enter ERT denial reason here,\nMultiline input is accepted.",rows:19,fluid:!0,multiline:1,value:g,onChange:function(){function f(N,V){return C(V)}return f}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{content:"Deny ERT",fluid:!0,icon:"times",center:!0,mt:2,textAlign:"center",onClick:function(){function f(){return s("deny_ert",{reason:g})}return f}()})]})})}},90217:function(T,r,n){"use strict";r.__esModule=!0,r.EconomyManager=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(3939),b=r.EconomyManager=function(){function S(k,h){return(0,e.createComponentVNode)(2,o.Window,{width:600,height:325,children:[(0,e.createComponentVNode)(2,p.ComplexModal),(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,className:"Layout__content--flexColumn",children:(0,e.createComponentVNode)(2,y)})]})}return S}(),y=function(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.next_payroll_time;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.4rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"coins",verticalAlign:"middle",size:3,mr:"1rem"}),"Economy Manager"]}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.LabeledList,{label:"Pay Bonuses and Deductions",children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Global",children:(0,e.createComponentVNode)(2,t.Button,{icon:"dollar-sign",width:"auto",content:"Global Payroll Modification",onClick:function(){function u(){return c("payroll_modification",{mod_type:"global"})}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Department Accounts",children:(0,e.createComponentVNode)(2,t.Button,{icon:"dollar-sign",width:"auto",content:"Department Account Payroll Modification",onClick:function(){function u(){return c("payroll_modification",{mod_type:"department"})}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Department Members",children:(0,e.createComponentVNode)(2,t.Button,{icon:"dollar-sign",width:"auto",content:"Department Members Payroll Modification",onClick:function(){function u(){return c("payroll_modification",{mod_type:"department_members"})}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Single Accounts",children:(0,e.createComponentVNode)(2,t.Button,{icon:"dollar-sign",width:"auto",content:"Crew Member Payroll Modification",onClick:function(){function u(){return c("payroll_modification",{mod_type:"crew_member"})}return u}()})})]}),(0,e.createVNode)(1,"hr"),(0,e.createComponentVNode)(2,t.Box,{mb:.5,children:["Next Payroll in: ",l," Minutes"]}),(0,e.createComponentVNode)(2,t.Button,{icon:"angle-double-left",width:"auto",color:"bad",content:"Delay Payroll",onClick:function(){function u(){return c("delay_payroll")}return u}()}),(0,e.createComponentVNode)(2,t.Button,{width:"auto",content:"Set Payroll Time",onClick:function(){function u(){return c("set_payroll")}return u}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"angle-double-right",width:"auto",color:"good",content:"Accelerate Payroll",onClick:function(){function u(){return c("accelerate_payroll")}return u}()})]}),(0,e.createComponentVNode)(2,t.NoticeBox,{children:[(0,e.createVNode)(1,"b",null,"WARNING:",16)," You take full responsibility for unbalancing the economy with these buttons!"]})],4)}},82565:function(T,r,n){"use strict";r.__esModule=!0,r.Electropack=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=n(98595),b=r.Electropack=function(){function y(S,k){var h=(0,t.useBackend)(k),i=h.act,c=h.data,m=c.power,l=c.code,u=c.frequency,s=c.minFrequency,d=c.maxFrequency;return(0,e.createComponentVNode)(2,p.Window,{width:360,height:135,children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Power",children:(0,e.createComponentVNode)(2,o.Button,{icon:m?"power-off":"times",content:m?"On":"Off",selected:m,onClick:function(){function v(){return i("power")}return v}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Frequency",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"sync",content:"Reset",onClick:function(){function v(){return i("reset",{reset:"freq"})}return v}()}),children:(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,unit:"kHz",step:.2,stepPixelSize:6,minValue:s/10,maxValue:d/10,value:u/10,format:function(){function v(g){return(0,a.toFixed)(g,1)}return v}(),width:"80px",onChange:function(){function v(g,C){return i("freq",{freq:C})}return v}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Code",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"sync",content:"Reset",onClick:function(){function v(){return i("reset",{reset:"code"})}return v}()}),children:(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,step:1,stepPixelSize:6,minValue:1,maxValue:100,value:l,width:"80px",onChange:function(){function v(g,C){return i("code",{code:C})}return v}()})})]})})})})}return y}()},11243:function(T,r,n){"use strict";r.__esModule=!0,r.Emojipedia=void 0;var e=n(89005),a=n(35840),t=n(72253),o=n(36036),p=n(98595),b=r.Emojipedia=function(){function S(k,h){var i=(0,t.useBackend)(h),c=i.data,m=c.emoji_list,l=(0,t.useLocalState)(h,"searchText",""),u=l[0],s=l[1],d=m.filter(function(v){return v.name.toLowerCase().includes(u.toLowerCase())});return(0,e.createComponentVNode)(2,p.Window,{width:325,height:400,children:(0,e.createComponentVNode)(2,p.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Emojipedia v1.0.1",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Input,{placeholder:"Search by name",value:u,onInput:function(){function v(g,C){return s(C)}return v}()}),(0,e.createComponentVNode)(2,o.Button,{tooltip:"Click on an emoji to copy its tag!",tooltipPosition:"bottom",icon:"circle-question"})],4),children:d.map(function(v){return(0,e.createComponentVNode)(2,o.Button,{m:1,color:"transparent",className:(0,a.classes)(["emoji16x16","emoji-"+v.name]),style:{transform:"scale(1.5)"},tooltip:v.name,onClick:function(){function g(){y(v.name)}return g}()},v.name)})})})})}return S}(),y=function(k){var h=document.createElement("input"),i=":"+k+":";h.value=i,document.body.appendChild(h),h.select(),document.execCommand("copy"),document.body.removeChild(h)}},36730:function(T,r,n){"use strict";r.__esModule=!0,r.EvolutionMenu=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),p=n(98595),b=n(64795),y=n(88510),S=r.EvolutionMenu=function(){function i(c,m){return(0,e.createComponentVNode)(2,p.Window,{width:480,height:580,theme:"changeling",children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,k),(0,e.createComponentVNode)(2,h)]})})})}return i}(),k=function(c,m){var l=(0,t.useBackend)(m),u=l.act,s=l.data,d=s.evo_points,v=s.can_respec;return(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{title:"Evolution Points",height:5.5,children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{mt:.5,color:"label",children:"Points remaining:"}),(0,e.createComponentVNode)(2,o.Stack.Item,{mt:.5,ml:2,bold:!0,color:"#1b945c",children:d}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:[(0,e.createComponentVNode)(2,o.Button,{ml:2.5,disabled:!v,content:"Readapt",icon:"sync",onClick:function(){function g(){return u("readapt")}return g}()}),(0,e.createComponentVNode)(2,o.Button,{tooltip:"By transforming a humanoid into a husk, we gain the ability to readapt our chosen evolutions.",tooltipPosition:"bottom",icon:"question-circle"})]})]})})})},h=function(c,m){var l=(0,t.useBackend)(m),u=l.act,s=l.data,d=s.evo_points,v=s.ability_tabs,g=s.purchased_abilities,C=s.view_mode,f=(0,t.useLocalState)(m,"selectedTab",v[0]),N=f[0],V=f[1],B=(0,t.useLocalState)(m,"searchText",""),I=B[0],L=B[1],w=(0,t.useLocalState)(m,"ability_tabs",v[0].abilities),A=w[0],x=w[1],E=function(O,R){if(R===void 0&&(R=""),!O||O.length===0)return[];var F=(0,a.createSearch)(R,function(W){return W.name+"|"+W.description});return(0,b.flow)([(0,y.filter)(function(W){return W==null?void 0:W.name}),(0,y.filter)(F),(0,y.sortBy)(function(W){return W==null?void 0:W.name})])(O)},P=function(O){if(L(O),O==="")return x(N.abilities);x(E(v.map(function(R){return R.abilities}).flat(),O))},D=function(O){V(O),x(O.abilities),L("")};return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Abilities",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Input,{width:"200px",placeholder:"Search Abilities",onInput:function(){function M(O,R){P(R)}return M}(),value:I}),(0,e.createComponentVNode)(2,o.Button,{icon:C?"square-o":"check-square-o",selected:!C,content:"Compact",onClick:function(){function M(){return u("set_view_mode",{mode:0})}return M}()}),(0,e.createComponentVNode)(2,o.Button,{icon:C?"check-square-o":"square-o",selected:C,content:"Expanded",onClick:function(){function M(){return u("set_view_mode",{mode:1})}return M}()})],4),children:[(0,e.createComponentVNode)(2,o.Tabs,{children:v.map(function(M){return(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:I===""&&N===M,onClick:function(){function O(){D(M)}return O}(),children:M.category},M)})}),A.map(function(M,O){return(0,e.createComponentVNode)(2,o.Box,{p:.5,mx:-1,className:"candystripe",children:[(0,e.createComponentVNode)(2,o.Stack,{align:"center",children:[(0,e.createComponentVNode)(2,o.Stack.Item,{ml:.5,color:"#dedede",children:M.name}),g.includes(M.power_path)&&(0,e.createComponentVNode)(2,o.Stack.Item,{ml:2,bold:!0,color:"#1b945c",children:"(Purchased)"}),(0,e.createComponentVNode)(2,o.Stack.Item,{mr:3,textAlign:"right",grow:1,children:[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:["Cost:"," "]}),(0,e.createComponentVNode)(2,o.Box,{as:"span",bold:!0,color:"#1b945c",children:M.cost})]}),(0,e.createComponentVNode)(2,o.Stack.Item,{textAlign:"right",children:(0,e.createComponentVNode)(2,o.Button,{mr:.5,disabled:M.cost>d||g.includes(M.power_path),content:"Evolve",onClick:function(){function R(){return u("purchase",{power_path:M.power_path})}return R}()})})]}),!!C&&(0,e.createComponentVNode)(2,o.Stack,{color:"#8a8a8a",my:1,ml:1.5,width:"95%",children:M.description+" "+M.helptext})]},O)})]})})}},17370:function(T,r,n){"use strict";r.__esModule=!0,r.ExosuitFabricator=void 0;var e=n(89005),a=n(35840),t=n(25328),o=n(72253),p=n(36036),b=n(73379),y=n(98595),S=["id","amount","lineDisplay","onClick"];function k(f,N){if(f==null)return{};var V={};for(var B in f)if({}.hasOwnProperty.call(f,B)){if(N.includes(B))continue;V[B]=f[B]}return V}var h=2e3,i={bananium:"clown",tranquillite:"mime"},c=r.ExosuitFabricator=function(){function f(N,V){var B=(0,o.useBackend)(V),I=B.act,L=B.data,w=L.building,A=L.linked;return A?(0,e.createComponentVNode)(2,y.Window,{width:950,height:625,children:(0,e.createComponentVNode)(2,y.Window.Content,{className:"Exofab",children:[(0,e.createComponentVNode)(2,C),(0,e.createComponentVNode)(2,p.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,p.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,l)}),w&&(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,u)})]})}),(0,e.createComponentVNode)(2,p.Stack.Item,{width:"30%",children:(0,e.createComponentVNode)(2,p.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,m)}),(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,s)})]})})]})]})}):(0,e.createComponentVNode)(2,g)}return f}(),m=function(N,V){var B=(0,o.useBackend)(V),I=B.act,L=B.data,w=L.materials,A=L.capacity,x=Object.values(w).reduce(function(E,P){return E+P},0);return(0,e.createComponentVNode)(2,p.Section,{fill:!0,scrollable:!0,title:"Materials",className:"Exofab__materials",buttons:(0,e.createComponentVNode)(2,p.Box,{color:"label",mt:"0.25rem",children:[(x/A*100).toPrecision(3),"% full"]}),children:["metal","glass","silver","gold","uranium","titanium","plasma","diamond","bluespace","bananium","tranquillite","plastic"].map(function(E){return(0,e.createComponentVNode)(2,d,{mt:-2,id:E,bold:E==="metal"||E==="glass",onClick:function(){function P(){return I("withdraw",{id:E})}return P}()},E)})})},l=function(N,V){var B=(0,o.useBackend)(V),I=B.act,L=B.data,w=L.curCategory,A=L.categories,x=L.designs,E=L.syncing,P=(0,o.useLocalState)(V,"searchText",""),D=P[0],M=P[1],O=(0,t.createSearch)(D,function(z){return z.name}),R=x.filter(O),F=(0,o.useLocalState)(V,"levelsModal",!1),W=F[0],U=F[1];return(0,e.createComponentVNode)(2,p.Section,{fill:!0,scrollable:!0,className:"Exofab__designs",title:(0,e.createComponentVNode)(2,p.Dropdown,{width:"19rem",className:"Exofab__dropdown",selected:w,options:A,onSelected:function(){function z($){return I("category",{cat:$})}return z}()}),buttons:(0,e.createComponentVNode)(2,p.Box,{mt:"2px",children:[(0,e.createComponentVNode)(2,p.Button,{icon:"plus",content:"Queue all",onClick:function(){function z(){return I("queueall")}return z}()}),(0,e.createComponentVNode)(2,p.Button,{icon:"info",content:"Show current tech levels",onClick:function(){function z(){return U(!0)}return z}()}),(0,e.createComponentVNode)(2,p.Button,{icon:"unlink",color:"red",tooltip:"Disconnect from R&D network",onClick:function(){function z(){return I("unlink")}return z}()})]}),children:[(0,e.createComponentVNode)(2,p.Input,{placeholder:"Search by name...",mb:"0.5rem",width:"100%",onInput:function(){function z($,G){return M(G)}return z}()}),R.map(function(z){return(0,e.createComponentVNode)(2,v,{design:z},z.id)}),R.length===0&&(0,e.createComponentVNode)(2,p.Box,{color:"label",children:"No designs found."})]})},u=function(N,V){var B=(0,o.useBackend)(V),I=B.act,L=B.data,w=L.building,A=L.buildStart,x=L.buildEnd,E=L.worldTime;return(0,e.createComponentVNode)(2,p.Section,{className:"Exofab__building",stretchContents:!0,children:(0,e.createComponentVNode)(2,p.ProgressBar.Countdown,{start:A,current:E,end:x,children:(0,e.createComponentVNode)(2,p.Stack,{children:[(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Icon,{name:"cog",spin:!0})}),(0,e.createComponentVNode)(2,p.Stack.Item,{children:["Building ",w,"\xA0(",(0,e.createComponentVNode)(2,b.Countdown,{current:E,timeLeft:x-E,format:function(){function P(D,M){return M.substr(3)}return P}()}),")"]})]})})})},s=function(N,V){var B=(0,o.useBackend)(V),I=B.act,L=B.data,w=L.queue,A=L.processingQueue,x=Object.entries(L.queueDeficit).filter(function(P){return P[1]<0}),E=w.reduce(function(P,D){return P+D.time},0);return(0,e.createComponentVNode)(2,p.Section,{fill:!0,scrollable:!0,className:"Exofab__queue",title:"Queue",buttons:(0,e.createComponentVNode)(2,p.Box,{children:[(0,e.createComponentVNode)(2,p.Button,{selected:A,icon:A?"toggle-on":"toggle-off",content:"Process",onClick:function(){function P(){return I("process")}return P}()}),(0,e.createComponentVNode)(2,p.Button,{disabled:w.length===0,icon:"eraser",content:"Clear",onClick:function(){function P(){return I("unqueueall")}return P}()})]}),children:(0,e.createComponentVNode)(2,p.Stack,{fill:!0,vertical:!0,children:w.length===0?(0,e.createComponentVNode)(2,p.Box,{color:"label",children:"The queue is empty."}):(0,e.createFragment)([(0,e.createComponentVNode)(2,p.Stack.Item,{className:"Exofab__queue--queue",grow:!0,overflow:"auto",children:w.map(function(P,D){return(0,e.createComponentVNode)(2,p.Box,{color:P.notEnough&&"bad",children:[D+1,". ",P.name,D>0&&(0,e.createComponentVNode)(2,p.Button,{icon:"arrow-up",onClick:function(){function M(){return I("queueswap",{from:D+1,to:D})}return M}()}),D0&&(0,e.createComponentVNode)(2,p.Stack.Item,{className:"Exofab__queue--time",children:[(0,e.createComponentVNode)(2,p.Divider),"Processing time:",(0,e.createComponentVNode)(2,p.Icon,{name:"clock",mx:"0.5rem"}),(0,e.createComponentVNode)(2,p.Box,{inline:!0,bold:!0,children:new Date(E/10*1e3).toISOString().substr(14,5)})]}),Object.keys(x).length>0&&(0,e.createComponentVNode)(2,p.Stack.Item,{className:"Exofab__queue--deficit",shrink:"0",children:[(0,e.createComponentVNode)(2,p.Divider),"Lacking materials to complete:",x.map(function(P){return(0,e.createComponentVNode)(2,p.Box,{children:(0,e.createComponentVNode)(2,d,{id:P[0],amount:-P[1],lineDisplay:!0})},P[0])})]})],0)})})},d=function(N,V){var B=(0,o.useBackend)(V),I=B.act,L=B.data,w=N.id,A=N.amount,x=N.lineDisplay,E=N.onClick,P=k(N,S),D=L.materials[w]||0,M=A||D;if(!(M<=0&&!(w==="metal"||w==="glass"))){var O=A&&A>D;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,p.Stack,Object.assign({align:"center",className:(0,a.classes)(["Exofab__material",x&&"Exofab__material--line"])},P,{children:x?(0,e.createFragment)([(0,e.createComponentVNode)(2,p.Stack.Item,{className:(0,a.classes)(["materials32x32",w])}),(0,e.createComponentVNode)(2,p.Stack.Item,{className:"Exofab__material--amount",color:O&&"bad",ml:0,mr:1,children:M.toLocaleString("en-US")})],4):(0,e.createFragment)([(0,e.createComponentVNode)(2,p.Stack.Item,{basis:"content",children:(0,e.createComponentVNode)(2,p.Button,{width:"85%",color:"transparent",onClick:E,children:(0,e.createComponentVNode)(2,p.Box,{mt:1,className:(0,a.classes)(["materials32x32",w])})})}),(0,e.createComponentVNode)(2,p.Stack.Item,{grow:"1",children:[(0,e.createComponentVNode)(2,p.Box,{className:"Exofab__material--name",children:w}),(0,e.createComponentVNode)(2,p.Box,{className:"Exofab__material--amount",children:[M.toLocaleString("en-US")," cm\xB3 (",Math.round(M/h*10)/10," ","sheets)"]})]})],4)})))}},v=function(N,V){var B=(0,o.useBackend)(V),I=B.act,L=B.data,w=N.design;return(0,e.createComponentVNode)(2,p.Box,{className:"Exofab__design",children:[(0,e.createComponentVNode)(2,p.Button,{disabled:w.notEnough||L.building,icon:"cog",content:w.name,onClick:function(){function A(){return I("build",{id:w.id})}return A}()}),(0,e.createComponentVNode)(2,p.Button,{icon:"plus-circle",onClick:function(){function A(){return I("queue",{id:w.id})}return A}()}),(0,e.createComponentVNode)(2,p.Box,{className:"Exofab__design--cost",children:Object.entries(w.cost).map(function(A){return(0,e.createComponentVNode)(2,p.Box,{children:(0,e.createComponentVNode)(2,d,{id:A[0],amount:A[1],lineDisplay:!0})},A[0])})}),(0,e.createComponentVNode)(2,p.Stack,{className:"Exofab__design--time",children:(0,e.createComponentVNode)(2,p.Stack.Item,{children:[(0,e.createComponentVNode)(2,p.Icon,{name:"clock"}),w.time>0?(0,e.createFragment)([w.time/10,(0,e.createTextVNode)(" seconds")],0):"Instant"]})})]})},g=function(N,V){var B=(0,o.useBackend)(V),I=B.act,L=B.data,w=L.controllers;return(0,e.createComponentVNode)(2,y.Window,{children:(0,e.createComponentVNode)(2,y.Window.Content,{children:(0,e.createComponentVNode)(2,p.Section,{title:"Setup Linkage",children:(0,e.createComponentVNode)(2,p.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,p.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,p.Table.Cell,{children:"Network Address"}),(0,e.createComponentVNode)(2,p.Table.Cell,{children:"Network ID"}),(0,e.createComponentVNode)(2,p.Table.Cell,{children:"Link"})]}),w.map(function(A){return(0,e.createComponentVNode)(2,p.Table.Row,{children:[(0,e.createComponentVNode)(2,p.Table.Cell,{children:A.addr}),(0,e.createComponentVNode)(2,p.Table.Cell,{children:A.net_id}),(0,e.createComponentVNode)(2,p.Table.Cell,{children:(0,e.createComponentVNode)(2,p.Button,{content:"Link",icon:"link",onClick:function(){function x(){return I("linktonetworkcontroller",{target_controller:A.addr})}return x}()})})]},A.addr)})]})})})})},C=function(N,V){var B=(0,o.useBackend)(V),I=B.act,L=B.data,w=L.tech_levels,A=(0,o.useLocalState)(V,"levelsModal",!1),x=A[0],E=A[1];return x?(0,e.createComponentVNode)(2,p.Modal,{maxWidth:"75%",width:window.innerWidth+"px",maxHeight:window.innerHeight*.75+"px",mx:"auto",children:(0,e.createComponentVNode)(2,p.Section,{title:"Current tech levels",buttons:(0,e.createComponentVNode)(2,p.Button,{content:"Close",onClick:function(){function P(){E(!1)}return P}()}),children:(0,e.createComponentVNode)(2,p.LabeledList,{children:w.map(function(P){var D=P.name,M=P.level;return(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:D,children:M},D)})})})}):null}},59128:function(T,r,n){"use strict";r.__esModule=!0,r.ExperimentConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=new Map([[0,{text:"Conscious",color:"good"}],[1,{text:"Unconscious",color:"average"}],[2,{text:"Deceased",color:"bad"}]]),b=new Map([[0,{label:"Probe",icon:"thermometer"}],[1,{label:"Dissect",icon:"brain"}],[2,{label:"Analyze",icon:"search"}]]),y=r.ExperimentConsole=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.open,u=m.feedback,s=m.occupant,d=m.occupant_name,v=m.occupant_status,g=function(){function f(){if(!s)return(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No specimen detected."});var N=function(){function B(){return p.get(v)}return B}(),V=N();return(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Name",children:d}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",color:V.color,children:V.text}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Experiments",children:[0,1,2].map(function(B){return(0,e.createComponentVNode)(2,t.Button,{icon:b.get(B).icon,content:b.get(B).label,onClick:function(){function I(){return c("experiment",{experiment_type:B})}return I}()},B)})})]})}return f}(),C=g();return(0,e.createComponentVNode)(2,o.Window,{theme:"abductor",width:350,height:200,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:u})})}),(0,e.createComponentVNode)(2,t.Section,{title:"Scanner",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:"Eject",disabled:!l,onClick:function(){function f(){return c("door")}return f}()}),children:C})]})})}return S}()},97086:function(T,r,n){"use strict";r.__esModule=!0,r.ExternalAirlockController=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=0,b=1013,y=function(h){var i="good",c=80,m=95,l=110,u=120;return hl?i="average":h>u&&(i="bad"),i},S=r.ExternalAirlockController=function(){function k(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.chamber_pressure,s=l.exterior_status,d=l.interior_status,v=l.processing;return(0,e.createComponentVNode)(2,o.Window,{width:330,height:205,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Information",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Chamber Pressure",children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:y(u),value:u,minValue:p,maxValue:b,children:[u," kPa"]})})})}),(0,e.createComponentVNode)(2,t.Section,{title:"Actions",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Abort",icon:"ban",color:"red",disabled:!v,onClick:function(){function g(){return m("abort")}return g}()}),children:[(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Button,{width:"49%",content:"Cycle to Exterior",icon:"arrow-circle-left",disabled:v,onClick:function(){function g(){return m("cycle_ext")}return g}()}),(0,e.createComponentVNode)(2,t.Button,{width:"50%",content:"Cycle to Interior",icon:"arrow-circle-right",disabled:v,onClick:function(){function g(){return m("cycle_int")}return g}()})]}),(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Button,{width:"49%",content:"Force Exterior Door",icon:"exclamation-triangle",color:d==="open"?"red":v?"yellow":null,onClick:function(){function g(){return m("force_ext")}return g}()}),(0,e.createComponentVNode)(2,t.Button,{width:"50%",content:"Force Interior Door",icon:"exclamation-triangle",color:d==="open"?"red":v?"yellow":null,onClick:function(){function g(){return m("force_int")}return g}()})]})]})]})})}return k}()},96142:function(T,r,n){"use strict";r.__esModule=!0,r.FaxMachine=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.FaxMachine=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data;return(0,e.createComponentVNode)(2,o.Window,{width:540,height:295,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Authorization",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"ID Card",children:(0,e.createComponentVNode)(2,t.Button,{icon:i.scan_name?"eject":"id-card",selected:i.scan_name,content:i.scan_name?i.scan_name:"-----",tooltip:i.scan_name?"Eject ID":"Insert ID",onClick:function(){function c(){return h("scan")}return c}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Authorize",children:(0,e.createComponentVNode)(2,t.Button,{icon:i.authenticated?"sign-out-alt":"id-card",selected:i.authenticated,disabled:i.nologin,content:i.realauth?"Log Out":"Log In",onClick:function(){function c(){return h("auth")}return c}()})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Fax Menu",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Network",children:i.network}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Document",children:[(0,e.createComponentVNode)(2,t.Button,{icon:i.paper?"eject":"paperclip",disabled:!i.authenticated&&!i.paper,content:i.paper?i.paper:"-----",onClick:function(){function c(){return h("paper")}return c}()}),!!i.paper&&(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:"Rename",onClick:function(){function c(){return h("rename")}return c}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Sending To",children:(0,e.createComponentVNode)(2,t.Button,{icon:"print",content:i.destination?i.destination:"-----",disabled:!i.authenticated,onClick:function(){function c(){return h("dept")}return c}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Action",children:(0,e.createComponentVNode)(2,t.Button,{icon:"envelope",content:i.sendError?i.sendError:"Send",disabled:!i.paper||!i.destination||!i.authenticated||i.sendError,onClick:function(){function c(){return h("send")}return c}()})})]})})]})})}return b}()},74123:function(T,r,n){"use strict";r.__esModule=!0,r.FilingCabinet=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.FilingCabinet=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=k.config,m=i.contents,l=c.title;return(0,e.createComponentVNode)(2,o.Window,{width:400,height:300,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Contents",children:[!m&&(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,textAlign:"center",align:"center",color:"average",children:[(0,e.createComponentVNode)(2,t.Icon.Stack,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"folder-open",size:5,color:"gray"}),(0,e.createComponentVNode)(2,t.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"The ",l," is empty."]})}),!!m&&m.slice().map(function(u){return(0,e.createComponentVNode)(2,t.Stack,{mt:.5,className:"candystripe",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"80%",children:u.display_name}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-down",content:"Retrieve",onClick:function(){function s(){return h("retrieve",{index:u.index})}return s}()})})]},u)})]})})})})}return b}()},83767:function(T,r,n){"use strict";r.__esModule=!0,r.FloorPainter=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=function(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=k.icon_state,u=k.direction,s=k.isSelected,d=k.onSelect;return(0,e.createComponentVNode)(2,t.DmIcon,{icon:m.icon,icon_state:l,direction:u,onClick:d,style:{"border-style":s&&"solid"||"none","border-width":"2px","border-color":"orange",padding:s&&"0px"||"2px"}})},b={NORTH:1,SOUTH:2,EAST:4,WEST:8},y=r.FloorPainter=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.availableStyles,u=m.selectedStyle,s=m.selectedDir;return(0,e.createComponentVNode)(2,o.Window,{width:405,height:475,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Decal setup",children:[(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-left",onClick:function(){function d(){return c("cycle_style",{offset:-1})}return d}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Dropdown,{options:l,selected:u,width:"150px",nochevron:!0,onSelected:function(){function d(v){return c("select_style",{style:v})}return d}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-right",onClick:function(){function d(){return c("cycle_style",{offset:1})}return d}()})})]}),(0,e.createComponentVNode)(2,t.Box,{mt:"5px",mb:"5px",children:(0,e.createComponentVNode)(2,t.Flex,{overflowY:"auto",maxHeight:"239px",wrap:"wrap",children:l.map(function(d){return(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,p,{icon_state:d,isSelected:u===d,onSelect:function(){function v(){return c("select_style",{style:d})}return v}()})},d)})})}),(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Direction",children:(0,e.createComponentVNode)(2,t.Table,{style:{display:"inline"},children:[b.NORTH,null,b.SOUTH].map(function(d){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[d+b.WEST,d,d+b.EAST].map(function(v){return(0,e.createComponentVNode)(2,t.Table.Cell,{style:{"vertical-align":"middle","text-align":"center"},children:v===null?(0,e.createComponentVNode)(2,t.Icon,{name:"arrows-alt",size:3}):(0,e.createComponentVNode)(2,p,{icon_state:u,direction:v,isSelected:v===s,onSelect:function(){function g(){return c("select_direction",{direction:v})}return g}()})},v)})},d)})})})})]})})})}return S}()},53424:function(T,r,n){"use strict";r.__esModule=!0,r.GPS=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=n(98595),b=function(l){return l?"("+l.join(", ")+")":"ERROR"},y=function(l,u){if(!(!l||!u)){if(l[2]!==u[2])return null;var s=Math.atan2(u[1]-l[1],u[0]-l[0]),d=Math.sqrt(Math.pow(u[1]-l[1],2)+Math.pow(u[0]-l[0],2));return{angle:(0,a.rad2deg)(s),distance:d}}},S=r.GPS=function(){function m(l,u){var s=(0,t.useBackend)(u),d=s.data,v=d.emped,g=d.active,C=d.area,f=d.position,N=d.saved;return(0,e.createComponentVNode)(2,p.Window,{width:400,height:600,children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:v?(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,basis:"0",children:(0,e.createComponentVNode)(2,k,{emp:!0})}):(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,h)}),g?(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,i,{area:C,position:f})}),N&&(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,i,{title:"Saved Position",position:N})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,basis:"0",children:(0,e.createComponentVNode)(2,c,{height:"100%"})})],0):(0,e.createComponentVNode)(2,k)],0)})})})}return m}(),k=function(l,u){var s=l.emp;return(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:(0,e.createComponentVNode)(2,o.Box,{width:"100%",height:"100%",color:"label",textAlign:"center",children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,o.Icon,{name:s?"ban":"power-off",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),s?"ERROR: Device temporarily lost signal.":"Device is disabled."]})})})})},h=function(l,u){var s=(0,t.useBackend)(u),d=s.act,v=s.data,g=v.active,C=v.tag,f=v.same_z,N=(0,t.useLocalState)(u,"newTag",C),V=N[0],B=N[1];return(0,e.createComponentVNode)(2,o.Section,{title:"Settings",buttons:(0,e.createComponentVNode)(2,o.Button,{selected:g,icon:g?"toggle-on":"toggle-off",content:g?"On":"Off",onClick:function(){function I(){return d("toggle")}return I}()}),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Tag",children:[(0,e.createComponentVNode)(2,o.Input,{width:"5rem",value:C,onEnter:function(){function I(){return d("tag",{newtag:V})}return I}(),onInput:function(){function I(L,w){return B(w)}return I}()}),(0,e.createComponentVNode)(2,o.Button,{disabled:C===V,width:"20px",mb:"0",ml:"0.25rem",onClick:function(){function I(){return d("tag",{newtag:V})}return I}(),children:(0,e.createComponentVNode)(2,o.Icon,{name:"pen"})})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Range",children:(0,e.createComponentVNode)(2,o.Button,{selected:!f,icon:f?"compress":"expand",content:f?"Local Sector":"Global",onClick:function(){function I(){return d("same_z")}return I}()})})]})})},i=function(l,u){var s=l.title,d=l.area,v=l.position;return(0,e.createComponentVNode)(2,o.Section,{title:s||"Position",children:(0,e.createComponentVNode)(2,o.Box,{fontSize:"1.5rem",children:[d&&(0,e.createFragment)([d,(0,e.createVNode)(1,"br")],0),b(v)]})})},c=function(l,u){var s=(0,t.useBackend)(u),d=s.data,v=d.position,g=d.signals;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({fill:!0,scrollable:!0,title:"Signals"},l,{children:(0,e.createComponentVNode)(2,o.Table,{children:g.map(function(C){return Object.assign({},C,y(v,C.position))}).map(function(C,f){return(0,e.createComponentVNode)(2,o.Table.Row,{backgroundColor:f%2===0&&"rgba(255, 255, 255, 0.05)",children:[(0,e.createComponentVNode)(2,o.Table.Cell,{width:"30%",verticalAlign:"middle",color:"label",p:"0.25rem",bold:!0,children:C.tag}),(0,e.createComponentVNode)(2,o.Table.Cell,{verticalAlign:"middle",color:"grey",children:C.area}),(0,e.createComponentVNode)(2,o.Table.Cell,{verticalAlign:"middle",collapsing:!0,children:C.distance!==void 0&&(0,e.createComponentVNode)(2,o.Box,{opacity:Math.max(1-Math.min(C.distance,100)/100,.5),children:[(0,e.createComponentVNode)(2,o.Icon,{name:C.distance>0?"arrow-right":"circle",rotation:-C.angle}),"\xA0",Math.floor(C.distance)+"m"]})}),(0,e.createComponentVNode)(2,o.Table.Cell,{verticalAlign:"middle",pr:"0.25rem",collapsing:!0,children:b(C.position)})]},f)})})})))}},89124:function(T,r,n){"use strict";r.__esModule=!0,r.GeneModder=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(3939),p=n(98595),b=r.GeneModder=function(){function u(s,d){var v=(0,a.useBackend)(d),g=v.data,C=g.has_seed;return(0,e.createComponentVNode)(2,p.Window,{width:950,height:650,children:[(0,e.createVNode)(1,"div","GeneModder__left",(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,l,{scrollable:!0})}),2),(0,e.createVNode)(1,"div","GeneModder__right",(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,scrollable:!0,children:[(0,e.createComponentVNode)(2,k),(0,e.createComponentVNode)(2,o.ComplexModal,{maxWidth:"75%",maxHeight:"75%"}),C===0?(0,e.createComponentVNode)(2,S):(0,e.createComponentVNode)(2,y)]})}),2)]})}return u}(),y=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.disk;return(0,e.createComponentVNode)(2,t.Section,{title:"Genes",fill:!0,scrollable:!0,children:[(0,e.createComponentVNode)(2,h),(0,e.createComponentVNode)(2,i),(0,e.createComponentVNode)(2,c)]})},S=function(s,d){return(0,e.createComponentVNode)(2,t.Section,{fill:!0,height:"85%",children:(0,e.createComponentVNode)(2,t.Stack,{height:"100%",children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:"1",textAlign:"center",align:"center",color:"green",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"leaf",size:5,mb:"10px"}),(0,e.createVNode)(1,"br"),"The plant DNA manipulator is missing a seed."]})})})},k=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.has_seed,N=C.seed,V=C.has_disk,B=C.disk,I,L;return f?I=(0,e.createComponentVNode)(2,t.Stack.Item,{mb:"-6px",mt:"-4px",children:[(0,e.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+N.image,style:{"vertical-align":"middle",width:"32px",margin:"-1px","margin-left":"-11px"}}),(0,e.createComponentVNode)(2,t.Button,{content:N.name,onClick:function(){function w(){return g("eject_seed")}return w}()}),(0,e.createComponentVNode)(2,t.Button,{ml:"3px",icon:"pen",tooltip:"Name Variant",onClick:function(){function w(){return g("variant_name")}return w}()})]}):I=(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{ml:3.3,content:"None",onClick:function(){function w(){return g("eject_seed")}return w}()})}),V?L=B.name:L="None",(0,e.createComponentVNode)(2,t.Section,{title:"Storage",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Plant Sample",children:I}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Data Disk",children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{ml:3.3,content:L,tooltip:"Select Empty Disk",onClick:function(){function w(){return g("select_empty_disk")}return w}()})})})]})})},h=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.disk,N=C.core_genes;return(0,e.createComponentVNode)(2,t.Collapsible,{title:"Core Genes",open:!0,children:[N.map(function(V){return(0,e.createComponentVNode)(2,t.Stack,{py:"2px",className:"candystripe",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"100%",ml:"2px",children:V.name}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Extract",disabled:!(f!=null&&f.can_extract),icon:"save",onClick:function(){function B(){return g("extract",{id:V.id})}return B}()})})]},V)})," ",(0,e.createComponentVNode)(2,t.Stack,{children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Extract All",disabled:!(f!=null&&f.can_extract),icon:"save",onClick:function(){function V(){return g("bulk_extract_core")}return V}()})})})]},"Core Genes")},i=function(s,d){var v=(0,a.useBackend)(d),g=v.data,C=g.reagent_genes,f=g.has_reagent;return(0,e.createComponentVNode)(2,m,{title:"Reagent Genes",gene_set:C,do_we_show:f})},c=function(s,d){var v=(0,a.useBackend)(d),g=v.data,C=g.trait_genes,f=g.has_trait;return(0,e.createComponentVNode)(2,m,{title:"Trait Genes",gene_set:C,do_we_show:f})},m=function(s,d){var v=s.title,g=s.gene_set,C=s.do_we_show,f=(0,a.useBackend)(d),N=f.act,V=f.data,B=V.disk;return(0,e.createComponentVNode)(2,t.Collapsible,{title:v,open:!0,children:C?g.map(function(I){return(0,e.createComponentVNode)(2,t.Stack,{py:"2px",className:"candystripe",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"100%",ml:"2px",children:I.name}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Extract",disabled:!(B!=null&&B.can_extract),icon:"save",onClick:function(){function L(){return N("extract",{id:I.id})}return L}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Remove",icon:"times",onClick:function(){function L(){return N("remove",{id:I.id})}return L}()})})]},I)}):(0,e.createComponentVNode)(2,t.Stack.Item,{children:"No Genes Detected"})},v)},l=function(s,d){var v=s.title,g=s.gene_set,C=s.do_we_show,f=(0,a.useBackend)(d),N=f.act,V=f.data,B=V.has_seed,I=V.empty_disks,L=V.stat_disks,w=V.trait_disks,A=V.reagent_disks;return(0,e.createComponentVNode)(2,t.Section,{title:"Disks",children:[(0,e.createVNode)(1,"br"),"Empty Disks: ",I,(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{width:12,icon:"arrow-down",tooltip:"Eject an Empty disk",content:"Eject Empty Disk",onClick:function(){function x(){return N("eject_empty_disk")}return x}()}),(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Stats",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,scrollable:!0,children:[L.slice().sort(function(x,E){return x.display_name.localeCompare(E.display_name)}).map(function(x){return(0,e.createComponentVNode)(2,t.Stack,{mr:2,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"49%",children:x.display_name}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:25,children:[x.stat==="All"?(0,e.createComponentVNode)(2,t.Button,{content:"Replace All",tooltip:"Write disk stats to seed",disabled:!(x!=null&&x.ready)||!B,icon:"arrow-circle-down",onClick:function(){function E(){return N("bulk_replace_core",{index:x.index})}return E}()}):(0,e.createComponentVNode)(2,t.Button,{width:6,icon:"arrow-circle-down",tooltip:"Write disk stat to seed",disabled:!x||!B,content:"Replace",onClick:function(){function E(){return N("replace",{index:x.index,stat:x.stat})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:6,icon:"arrow-right",content:"Select",tooltip:"Choose as target for extracted genes",tooltipPosition:"bottom-start",onClick:function(){function E(){return N("select",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:5,icon:"arrow-down",content:"Eject",tooltip:"Eject Disk",tooltipPosition:"bottom-start",onClick:function(){function E(){return N("eject_disk",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:2,icon:x.read_only?"lock":"lock-open",content:"",tool_tip:"Set/unset Read Only",onClick:function(){function E(){return N("set_read_only",{index:x.index,read_only:x.read_only})}return E}()})]})]},x)}),(0,e.createComponentVNode)(2,t.Button)]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Traits",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,scrollable:!0,children:[w.slice().sort(function(x,E){return x.display_name.localeCompare(E.display_name)}).map(function(x){return(0,e.createComponentVNode)(2,t.Stack,{mr:2,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"49%",children:x.display_name}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:25,children:[(0,e.createComponentVNode)(2,t.Button,{width:6,icon:"arrow-circle-down",disabled:!x||!x.can_insert,tooltip:"Add disk trait to seed",content:"Insert",onClick:function(){function E(){return N("insert",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:6,icon:"arrow-right",content:"Select",tooltip:"Choose as target for extracted genes",tooltipPosition:"bottom-start",onClick:function(){function E(){return N("select",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:5,icon:"arrow-down",content:"Eject",tooltip:"Eject Disk",tooltipPosition:"bottom-start",onClick:function(){function E(){return N("eject_disk",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:2,icon:x.read_only?"lock":"lock-open",content:"",tool_tip:"Set/unset Read Only",onClick:function(){function E(){return N("set_read_only",{index:x.index,read_only:x.read_only})}return E}()})]})]},x)}),(0,e.createComponentVNode)(2,t.Button)]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Reagents",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,scrollable:!0,children:[A.slice().sort(function(x,E){return x.display_name.localeCompare(E.display_name)}).map(function(x){return(0,e.createComponentVNode)(2,t.Stack,{mr:2,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"49%",children:x.display_name}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:25,children:[(0,e.createComponentVNode)(2,t.Button,{width:6,icon:"arrow-circle-down",disabled:!x||!x.can_insert,tooltip:"Add disk reagent to seed",content:"Insert",onClick:function(){function E(){return N("insert",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:6,icon:"arrow-right",content:"Select",tooltip:"Choose as target for extracted genes",tooltipPosition:"bottom-start",onClick:function(){function E(){return N("select",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:5,icon:"arrow-down",content:"Eject",tooltip:"Eject Disk",tooltipPosition:"bottom-start",onClick:function(){function E(){return N("eject_disk",{index:x.index})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{width:2,icon:x.read_only?"lock":"lock-open",content:"",tool_tip:"Set/unset Read Only",onClick:function(){function E(){return N("set_read_only",{index:x.index,read_only:x.read_only})}return E}()})]})]},x)}),(0,e.createComponentVNode)(2,t.Button)]})})]})]})}},73053:function(T,r,n){"use strict";r.__esModule=!0,r.GenericCrewManifest=void 0;var e=n(89005),a=n(36036),t=n(98595),o=n(41874),p=r.GenericCrewManifest=function(){function b(y,S){return(0,e.createComponentVNode)(2,t.Window,{theme:"nologo",width:588,height:510,children:(0,e.createComponentVNode)(2,t.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,a.Section,{noTopPadding:!0,children:(0,e.createComponentVNode)(2,o.CrewManifest)})})})}return b}()},42914:function(T,r,n){"use strict";r.__esModule=!0,r.GhostHudPanel=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.GhostHudPanel=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.data,c=i.security,m=i.medical,l=i.diagnostic,u=i.radioactivity,s=i.ahud;return(0,e.createComponentVNode)(2,o.Window,{width:250,height:207,theme:"nologo",children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,b,{label:"Medical",type:"medical",is_active:m}),(0,e.createComponentVNode)(2,b,{label:"Security",type:"security",is_active:c}),(0,e.createComponentVNode)(2,b,{label:"Diagnostic",type:"diagnostic",is_active:l}),(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,b,{label:"Radioactivity",type:"radioactivity",is_active:u,act_on:"rads_on",act_off:"rads_off"}),(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,b,{label:"Antag HUD",is_active:s,act_on:"ahud_on",act_off:"ahud_off"})]})})})}return y}(),b=function(S,k){var h=(0,a.useBackend)(k),i=h.act,c=S.label,m=S.type,l=m===void 0?null:m,u=S.is_active,s=S.act_on,d=s===void 0?"hud_on":s,v=S.act_off,g=v===void 0?"hud_off":v;return(0,e.createComponentVNode)(2,t.Flex,{pt:.3,color:"label",children:[(0,e.createComponentVNode)(2,t.Flex.Item,{pl:.5,align:"center",width:"80%",children:c}),(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,t.Button,{mr:.6,content:u?"On":"Off",icon:u?"toggle-on":"toggle-off",selected:u,onClick:function(){function C(){return i(u?g:d,{hud_type:l})}return C}()})})]})}},25825:function(T,r,n){"use strict";r.__esModule=!0,r.GlandDispenser=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.GlandDispenser=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.glands,m=c===void 0?[]:c;return(0,e.createComponentVNode)(2,o.Window,{width:300,height:338,theme:"abductor",children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:m.map(function(l){return(0,e.createComponentVNode)(2,t.Button,{width:"60px",height:"60px",m:.75,textAlign:"center",fontSize:"17px",lineHeight:"55px",icon:"eject",backgroundColor:l.color,content:l.amount||"0",disabled:!l.amount,onClick:function(){function u(){return h("dispense",{gland_id:l.id})}return u}()},l.id)})})})})}return b}()},10270:function(T,r,n){"use strict";r.__esModule=!0,r.GravityGen=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.GravityGen=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.charging_state,m=i.charge_count,l=i.breaker,u=i.ext_power,s=function(){function v(g){return g>0?(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:"average",children:["[ ",g===1?"Charging":"Discharging"," ]"]}):(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:u?"good":"bad",children:["[ ",u?"Powered":"Unpowered"," ]"]})}return v}(),d=function(){function v(g){if(g>0)return(0,e.createComponentVNode)(2,t.NoticeBox,{danger:!0,p:1.5,children:[(0,e.createVNode)(1,"b",null,"WARNING:",16)," Radiation Detected!"]})}return v}();return(0,e.createComponentVNode)(2,o.Window,{width:350,height:170,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[d(c),(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Generator Status",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:l?"power-off":"times",content:l?"Online":"Offline",color:l?"green":"red",px:1.5,onClick:function(){function v(){return h("breaker")}return v}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power Status",color:u?"good":"bad",children:s(c)}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Gravity Charge",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:m/100,ranges:{good:[.9,1/0],average:[.5,.9],bad:[-1/0,.5]}})})]})})]})})})}return b}()},48657:function(T,r,n){"use strict";r.__esModule=!0,r.GuestPass=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(49148),b=r.GuestPass=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:690,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"id-card",selected:!c.showlogs,onClick:function(){function m(){return i("mode",{mode:0})}return m}(),children:"Issue Pass"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"scroll",selected:c.showlogs,onClick:function(){function m(){return i("mode",{mode:1})}return m}(),children:["Records (",c.issue_log.length,")"]})]})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Authorization",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"ID Card",children:(0,e.createComponentVNode)(2,t.Button,{icon:c.scan_name?"eject":"id-card",selected:c.scan_name,content:c.scan_name?c.scan_name:"-----",tooltip:c.scan_name?"Eject ID":"Insert ID",onClick:function(){function m(){return i("scan")}return m}()})})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:!c.showlogs&&(0,e.createComponentVNode)(2,t.Section,{title:"Issue Guest Pass",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Issue To",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:c.giv_name?c.giv_name:"-----",disabled:!c.scan_name,onClick:function(){function m(){return i("giv_name")}return m}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Reason",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:c.reason?c.reason:"-----",disabled:!c.scan_name,onClick:function(){function m(){return i("reason")}return m}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Duration",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pencil-alt",content:c.duration?c.duration:"-----",disabled:!c.scan_name,onClick:function(){function m(){return i("duration")}return m}()})})]})})}),!c.showlogs&&(c.scan_name?(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,p.AccessList,{sectionButtons:(0,e.createComponentVNode)(2,t.Button,{icon:"id-card",content:c.printmsg,disabled:!c.canprint,onClick:function(){function m(){return i("issue")}return m}()}),grantableList:c.grantableList,accesses:c.regions,selectedList:c.selectedAccess,accessMod:function(){function m(l){return i("access",{access:l})}return m}(),grantAll:function(){function m(){return i("grant_all")}return m}(),denyAll:function(){function m(){return i("clear_all")}return m}(),grantDep:function(){function m(l){return i("grant_region",{region:l})}return m}(),denyDep:function(){function m(l){return i("deny_region",{region:l})}return m}()})}):(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,fontSize:1.5,textAlign:"center",align:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"id-card",size:5,color:"gray",mb:5}),(0,e.createVNode)(1,"br"),"Please, insert ID Card"]})})})})),!!c.showlogs&&(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,m:0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Issuance Log",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"print",content:"Print",disabled:!c.scan_name,onClick:function(){function m(){return i("print")}return m}()}),children:!!c.issue_log.length&&(0,e.createComponentVNode)(2,t.LabeledList,{children:c.issue_log.map(function(m,l){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{children:m},l)})})||(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,fontSize:1.5,textAlign:"center",align:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon.Stack,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"scroll",size:5,color:"gray"}),(0,e.createComponentVNode)(2,t.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"No logs"]})})})})]})})})}return y}()},67834:function(T,r,n){"use strict";r.__esModule=!0,r.HandheldChemDispenser=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=[1,5,10,20,30,50],b=null,y=r.HandheldChemDispenser=function(){function h(i,c){return(0,e.createComponentVNode)(2,o.Window,{width:390,height:430,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,S),(0,e.createComponentVNode)(2,k)]})})})}return h}(),S=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.amount,d=u.energy,v=u.maxEnergy,g=u.mode;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Settings",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Energy",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:d,minValue:0,maxValue:v,ranges:{good:[v*.5,1/0],average:[v*.25,v*.5],bad:[-1/0,v*.25]},children:[d," / ",v," Units"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Amount",verticalAlign:"middle",children:(0,e.createComponentVNode)(2,t.Stack,{children:p.map(function(C,f){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,width:"15%",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"cog",selected:s===C,content:C,onClick:function(){function N(){return l("amount",{amount:C})}return N}()})},f)})})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Mode",verticalAlign:"middle",children:(0,e.createComponentVNode)(2,t.Stack,{justify:"space-between",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"cog",selected:g==="dispense",content:"Dispense",m:"0",width:"32%",onClick:function(){function C(){return l("mode",{mode:"dispense"})}return C}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"cog",selected:g==="remove",content:"Remove",m:"0",width:"32%",onClick:function(){function C(){return l("mode",{mode:"remove"})}return C}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"cog",selected:g==="isolate",content:"Isolate",m:"0",width:"32%",onClick:function(){function C(){return l("mode",{mode:"isolate"})}return C}()})]})})]})})})},k=function(i,c){for(var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.chemicals,d=s===void 0?[]:s,v=u.current_reagent,g=[],C=0;C<(d.length+1)%3;C++)g.push(!0);return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,height:"18%",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:u.glass?"Drink Selector":"Chemical Selector",children:[d.map(function(f,N){return(0,e.createComponentVNode)(2,t.Button,{width:"32%",icon:"arrow-circle-down",overflow:"hidden",textOverflow:"ellipsis",selected:v===f.id,content:f.title,style:{"margin-left":"2px"},onClick:function(){function V(){return l("dispense",{reagent:f.id})}return V}()},N)}),g.map(function(f,N){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:"1",basis:"25%"},N)})]})})}},46098:function(T,r,n){"use strict";r.__esModule=!0,r.HealthSensor=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=n(98595),b=r.HealthSensor=function(){function S(k,h){var i=(0,t.useBackend)(h),c=i.act,m=i.data,l=m.on,u=m.user_health,s=m.minHealth,d=m.maxHealth,v=m.alarm_health;return(0,e.createComponentVNode)(2,p.Window,{width:300,height:125,children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Scanning",children:(0,e.createComponentVNode)(2,o.Button,{icon:"power-off",content:l?"On":"Off",color:l?null:"red",selected:l,onClick:function(){function g(){return c("scan_toggle")}return g}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Health activation",children:(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,step:2,stepPixelSize:6,minValue:s,maxValue:d,value:v,format:function(){function g(C){return(0,a.toFixed)(C,1)}return g}(),width:"80px",onDrag:function(){function g(C,f){return c("alarm_health",{alarm_health:f})}return g}()})}),u!==null&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"User health",children:(0,e.createComponentVNode)(2,o.Box,{color:y(u),bold:u>=100,children:(0,e.createComponentVNode)(2,o.AnimatedNumber,{value:u})})})]})})})})}return S}(),y=function(k){return k>50?"green":k>0?"orange":"red"}},36771:function(T,r,n){"use strict";r.__esModule=!0,r.Holodeck=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.Holodeck=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=(0,a.useLocalState)(k,"currentDeck",""),l=m[0],u=m[1],s=(0,a.useLocalState)(k,"showReload",!1),d=s[0],v=s[1],g=c.decks,C=c.ai_override,f=c.emagged,N=function(){function V(B){i("select_deck",{deck:B}),u(B),v(!0),setTimeout(function(){v(!1)},3e3)}return V}();return(0,e.createComponentVNode)(2,o.Window,{width:400,height:320,children:[d&&(0,e.createComponentVNode)(2,b),(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Holodeck Control System",children:(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createVNode)(1,"b",null,"Currently Loaded Program:",16)," ",l]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Available Programs",children:[g.map(function(V){return(0,e.createComponentVNode)(2,t.Button,{width:15.5,color:"transparent",content:V,selected:V===l,onClick:function(){function B(){return N(V)}return B}()},V)}),(0,e.createVNode)(1,"hr",null,null,1,{color:"gray"}),(0,e.createComponentVNode)(2,t.LabeledList,{children:[!!C&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Override Protocols",children:(0,e.createComponentVNode)(2,t.Button,{content:f?"Turn On":"Turn Off",color:f?"good":"bad",onClick:function(){function V(){return i("ai_override")}return V}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Safety Protocols",children:(0,e.createComponentVNode)(2,t.Box,{color:f?"bad":"good",children:[f?"Off":"On",!!f&&(0,e.createComponentVNode)(2,t.Button,{ml:9.5,width:15.5,color:"red",content:"Wildlife Simulation",onClick:function(){function V(){return i("wildlifecarp")}return V}()})]})})]})]})})]})})]})}return y}(),b=function(S,k){return(0,e.createComponentVNode)(2,t.Dimmer,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"spinner",size:"5",spin:!0}),(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Box,{color:"white",children:(0,e.createVNode)(1,"h1",null,"\xA0Recalibrating projection apparatus.\xA0",16)}),(0,e.createComponentVNode)(2,t.Box,{color:"label",children:(0,e.createVNode)(1,"h3",null,"Please, wait for 3 seconds.",16)})]})}},25471:function(T,r,n){"use strict";r.__esModule=!0,r.Instrument=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=n(98595),b=r.Instrument=function(){function i(c,m){var l=(0,t.useBackend)(m),u=l.act,s=l.data;return(0,e.createComponentVNode)(2,p.Window,{width:600,height:505,children:[(0,e.createComponentVNode)(2,y),(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,S),(0,e.createComponentVNode)(2,h)]})})]})}return i}(),y=function(c,m){var l=(0,t.useBackend)(m),u=l.act,s=l.data,d=s.help;if(d)return(0,e.createComponentVNode)(2,o.Modal,{maxWidth:"75%",height:window.innerHeight*.75+"px",mx:"auto",py:"0",px:"0.5rem",children:(0,e.createComponentVNode)(2,o.Section,{height:"100%",title:"Help",level:"2",overflow:"auto",children:(0,e.createComponentVNode)(2,o.Box,{px:"0.5rem",mt:"-0.5rem",children:[(0,e.createVNode)(1,"h1",null,"Making a Song",16),(0,e.createVNode)(1,"p",null,[(0,e.createTextVNode)("Lines are a series of chords, separated by commas\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"(,)"}),(0,e.createTextVNode)(", each with notes separated by hyphens\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"(-)"}),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Every note in a chord will play together, with the chord timed by the\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"tempo"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("as defined above.")],0),(0,e.createVNode)(1,"p",null,[(0,e.createTextVNode)("Notes are played by the\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"good",children:"names of the note"}),(0,e.createTextVNode)(", and optionally, the\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"accidental"}),(0,e.createTextVNode)(", and/or the"),(0,e.createTextVNode)(" "),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"bad",children:"octave number"}),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("By default, every note is\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"natural"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("and in\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"bad",children:"octave 3"}),(0,e.createTextVNode)(". Defining a different state for either is remembered for each"),(0,e.createTextVNode)(" "),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"good",children:"note"}),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"ul",null,[(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"Example:"}),(0,e.createTextVNode)("\xA0"),(0,e.createVNode)(1,"i",null,"C,D,E,F,G,A,B",16),(0,e.createTextVNode)(" will play a\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"good",children:"C"}),(0,e.createTextVNode)("\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"major"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("scale.")],0),(0,e.createVNode)(1,"li",null,[(0,e.createTextVNode)("After a note has an\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"accidental"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("or\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"bad",children:"octave"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("placed, it will be remembered:\xA0"),(0,e.createVNode)(1,"i",null,"C,C4,C#,C3",16),(0,e.createTextVNode)(" is "),(0,e.createVNode)(1,"i",null,"C3,C4,C4#,C3#",16)],0)],4)],0),(0,e.createVNode)(1,"p",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"Chords"}),(0,e.createTextVNode)("\xA0can be played simply by seperating each note with a hyphen: "),(0,e.createVNode)(1,"i",null,"A-C#,Cn-E,E-G#,Gn-B",16),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("A"),(0,e.createTextVNode)(" "),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"pause"}),(0,e.createTextVNode)("\xA0may be denoted by an empty chord: "),(0,e.createVNode)(1,"i",null,"C,E,,C,G",16),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("To make a chord be a different time, end it with /x, where the chord length will be length defined by\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"tempo / x"}),(0,e.createTextVNode)(",\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"eg:"}),(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"i",null,"C,G/2,E/4",16),(0,e.createTextVNode)(".")],0),(0,e.createVNode)(1,"p",null,[(0,e.createTextVNode)("Combined, an example line is: "),(0,e.createVNode)(1,"i",null,"E-E4/4,F#/2,G#/8,B/8,E3-E4/4",16),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"ul",null,[(0,e.createVNode)(1,"li",null,"Lines may be up to 300 characters.",16),(0,e.createVNode)(1,"li",null,"A song may only contain up to 1,000 lines.",16)],4)],4),(0,e.createVNode)(1,"p",null,[(0,e.createTextVNode)("Lines are a series of chords, separated by commas\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"(,)"}),(0,e.createTextVNode)(", each with notes separated by hyphens\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"(-)"}),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Every note in a chord will play together, with the chord timed by the\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"tempo"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("as defined above.")],0),(0,e.createVNode)(1,"p",null,[(0,e.createTextVNode)("Notes are played by the\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"good",children:"names of the note"}),(0,e.createTextVNode)(", and optionally, the\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"accidental"}),(0,e.createTextVNode)(", and/or the"),(0,e.createTextVNode)(" "),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"bad",children:"octave number"}),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("By default, every note is\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"natural"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("and in\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"bad",children:"octave 3"}),(0,e.createTextVNode)(". Defining a different state for either is remembered for each"),(0,e.createTextVNode)(" "),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"good",children:"note"}),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"ul",null,[(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"Example:"}),(0,e.createTextVNode)("\xA0"),(0,e.createVNode)(1,"i",null,"C,D,E,F,G,A,B",16),(0,e.createTextVNode)(" will play a\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"good",children:"C"}),(0,e.createTextVNode)("\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"major"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("scale.")],0),(0,e.createVNode)(1,"li",null,[(0,e.createTextVNode)("After a note has an\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"average",children:"accidental"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("or\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"bad",children:"octave"}),(0,e.createTextVNode)(" "),(0,e.createTextVNode)("placed, it will be remembered:\xA0"),(0,e.createVNode)(1,"i",null,"C,C4,C#,C3",16),(0,e.createTextVNode)(" is "),(0,e.createVNode)(1,"i",null,"C3,C4,C4#,C3#",16)],0)],4)],0),(0,e.createVNode)(1,"p",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"Chords"}),(0,e.createTextVNode)("\xA0can be played simply by seperating each note with a hyphen: "),(0,e.createVNode)(1,"i",null,"A-C#,Cn-E,E-G#,Gn-B",16),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("A"),(0,e.createTextVNode)(" "),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"pause"}),(0,e.createTextVNode)("\xA0may be denoted by an empty chord: "),(0,e.createVNode)(1,"i",null,"C,E,,C,G",16),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("To make a chord be a different time, end it with /x, where the chord length will be length defined by\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"tempo / x"}),(0,e.createTextVNode)(",\xA0"),(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"highlight",children:"eg:"}),(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"i",null,"C,G/2,E/4",16),(0,e.createTextVNode)(".")],0),(0,e.createVNode)(1,"p",null,[(0,e.createTextVNode)("Combined, an example line is: "),(0,e.createVNode)(1,"i",null,"E-E4/4,F#/2,G#/8,B/8,E3-E4/4",16),(0,e.createTextVNode)("."),(0,e.createVNode)(1,"ul",null,[(0,e.createVNode)(1,"li",null,"Lines may be up to 300 characters.",16),(0,e.createVNode)(1,"li",null,"A song may only contain up to 1,000 lines.",16)],4)],4),(0,e.createVNode)(1,"h1",null,"Instrument Advanced Settings",16),(0,e.createVNode)(1,"ul",null,[(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:"Type:"}),(0,e.createTextVNode)("\xA0Whether the instrument is legacy or synthesized."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Legacy instruments have a collection of sounds that are selectively used depending on the note to play."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Synthesized instruments use a base sound and change its pitch to match the note to play.")],4),(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:"Current:"}),(0,e.createTextVNode)("\xA0Which instrument sample to play. Some instruments can be tuned to play different samples. Experiment!")],4),(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:"Note Shift/Note Transpose:"}),(0,e.createTextVNode)("\xA0The pitch to apply to all notes of the song.")],4),(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:"Sustain Mode:"}),(0,e.createTextVNode)("\xA0How a played note fades out."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Linear sustain means a note will fade out at a constant rate."),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Exponential sustain means a note will fade out at an exponential rate, sounding smoother.")],4),(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:"Volume Dropoff Threshold:"}),(0,e.createTextVNode)("\xA0The volume threshold at which a note is fully stopped.")],4),(0,e.createVNode)(1,"li",null,[(0,e.createComponentVNode)(2,o.Box,{as:"span",color:"label",children:"Sustain indefinitely last held note:"}),(0,e.createTextVNode)("\xA0Whether the last note should be sustained indefinitely.")],4)],4),(0,e.createComponentVNode)(2,o.Button,{color:"grey",content:"Close",onClick:function(){function v(){return u("help")}return v}()})]})})})},S=function(c,m){var l=(0,t.useBackend)(m),u=l.act,s=l.data,d=s.lines,v=s.playing,g=s.repeat,C=s.maxRepeats,f=s.tempo,N=s.minTempo,V=s.maxTempo,B=s.tickLag,I=s.volume,L=s.minVolume,w=s.maxVolume,A=s.ready;return(0,e.createComponentVNode)(2,o.Section,{title:"Instrument",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{icon:"info",content:"Help",onClick:function(){function x(){return u("help")}return x}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"file",content:"New",onClick:function(){function x(){return u("newsong")}return x}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"upload",content:"Import",onClick:function(){function x(){return u("import")}return x}()})],4),children:[(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Playback",children:[(0,e.createComponentVNode)(2,o.Button,{selected:v,disabled:d.length===0||g<0,icon:"play",content:"Play",onClick:function(){function x(){return u("play")}return x}()}),(0,e.createComponentVNode)(2,o.Button,{disabled:!v,icon:"stop",content:"Stop",onClick:function(){function x(){return u("stop")}return x}()})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Repeat",children:(0,e.createComponentVNode)(2,o.Slider,{animated:!0,minValue:0,maxValue:C,value:g,stepPixelSize:59,onChange:function(){function x(E,P){return u("repeat",{new:P})}return x}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Tempo",children:(0,e.createComponentVNode)(2,o.Box,{children:[(0,e.createComponentVNode)(2,o.Button,{disabled:f>=V,content:"-",as:"span",mr:"0.5rem",onClick:function(){function x(){return u("tempo",{new:f+B})}return x}()}),(0,a.round)(600/f)," BPM",(0,e.createComponentVNode)(2,o.Button,{disabled:f<=N,content:"+",as:"span",ml:"0.5rem",onClick:function(){function x(){return u("tempo",{new:f-B})}return x}()})]})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Volume",children:(0,e.createComponentVNode)(2,o.Slider,{animated:!0,minValue:L,maxValue:w,value:I,stepPixelSize:6,onDrag:function(){function x(E,P){return u("setvolume",{new:P})}return x}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Status",children:A?(0,e.createComponentVNode)(2,o.Box,{color:"good",children:"Ready"}):(0,e.createComponentVNode)(2,o.Box,{color:"bad",children:"Instrument Definition Error!"})})]}),(0,e.createComponentVNode)(2,k)]})},k=function(c,m){var l=(0,t.useBackend)(m),u=l.act,s=l.data,d=s.allowedInstrumentNames,v=s.instrumentLoaded,g=s.instrument,C=s.canNoteShift,f=s.noteShift,N=s.noteShiftMin,V=s.noteShiftMax,B=s.sustainMode,I=s.sustainLinearDuration,L=s.sustainExponentialDropoff,w=s.legacy,A=s.sustainDropoffVolume,x=s.sustainHeldNote,E,P;return B===1?(E="Linear",P=(0,e.createComponentVNode)(2,o.Slider,{minValue:.1,maxValue:5,value:I,step:.5,stepPixelSize:85,format:function(){function D(M){return(0,a.round)(M*100)/100+" seconds"}return D}(),onChange:function(){function D(M,O){return u("setlinearfalloff",{new:O/10})}return D}()})):B===2&&(E="Exponential",P=(0,e.createComponentVNode)(2,o.Slider,{minValue:1.025,maxValue:10,value:L,step:.01,format:function(){function D(M){return(0,a.round)(M*1e3)/1e3+"% per decisecond"}return D}(),onChange:function(){function D(M,O){return u("setexpfalloff",{new:O})}return D}()})),d.sort(),(0,e.createComponentVNode)(2,o.Box,{my:-1,children:(0,e.createComponentVNode)(2,o.Collapsible,{mt:"1rem",mb:"0",title:"Advanced",children:(0,e.createComponentVNode)(2,o.Section,{mt:-1,children:[(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Type",children:w?"Legacy":"Synthesized"}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Current",children:v?(0,e.createComponentVNode)(2,o.Dropdown,{options:d,selected:g,width:"50%",onSelected:function(){function D(M){return u("switchinstrument",{name:M})}return D}()}):(0,e.createComponentVNode)(2,o.Box,{color:"bad",children:"None!"})}),!!(!w&&C)&&(0,e.createFragment)([(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Note Shift/Note Transpose",children:(0,e.createComponentVNode)(2,o.Slider,{minValue:N,maxValue:V,value:f,stepPixelSize:2,format:function(){function D(M){return M+" keys / "+(0,a.round)(M/12*100)/100+" octaves"}return D}(),onChange:function(){function D(M,O){return u("setnoteshift",{new:O})}return D}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Sustain Mode",children:[(0,e.createComponentVNode)(2,o.Dropdown,{options:["Linear","Exponential"],selected:E,mb:"0.4rem",onSelected:function(){function D(M){return u("setsustainmode",{new:M})}return D}()}),P]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Volume Dropoff Threshold",children:(0,e.createComponentVNode)(2,o.Slider,{animated:!0,minValue:.01,maxValue:100,value:A,stepPixelSize:6,onChange:function(){function D(M,O){return u("setdropoffvolume",{new:O})}return D}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Sustain indefinitely last held note",children:(0,e.createComponentVNode)(2,o.Button,{selected:x,icon:x?"toggle-on":"toggle-off",content:x?"Yes":"No",onClick:function(){function D(){return u("togglesustainhold")}return D}()})})],4)]}),(0,e.createComponentVNode)(2,o.Button,{icon:"redo",content:"Reset to Default",mt:"0.5rem",onClick:function(){function D(){return u("reset")}return D}()})]})})})},h=function(c,m){var l=(0,t.useBackend)(m),u=l.act,s=l.data,d=s.playing,v=s.lines,g=s.editing;return(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Editor",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{disabled:!g||d,icon:"plus",content:"Add Line",onClick:function(){function C(){return u("newline",{line:v.length+1})}return C}()}),(0,e.createComponentVNode)(2,o.Button,{selected:!g,icon:g?"chevron-up":"chevron-down",onClick:function(){function C(){return u("edit")}return C}()})],4),children:!!g&&(v.length>0?(0,e.createComponentVNode)(2,o.LabeledList,{children:v.map(function(C,f){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:f+1,buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{disabled:d,icon:"pen",onClick:function(){function N(){return u("modifyline",{line:f+1})}return N}()}),(0,e.createComponentVNode)(2,o.Button,{disabled:d,icon:"trash",onClick:function(){function N(){return u("deleteline",{line:f+1})}return N}()})],4),children:C},f)})}):(0,e.createComponentVNode)(2,o.Box,{color:"label",children:"Song is empty."}))})}},13618:function(T,r,n){"use strict";r.__esModule=!0,r.KeyComboModal=void 0;var e=n(89005),a=n(70611),t=n(72253),o=n(36036),p=n(98595),b=n(19203),y=n(51057),S=function(l){return l.key!==a.KEY.Alt&&l.key!==a.KEY.Control&&l.key!==a.KEY.Shift&&l.key!==a.KEY.Escape},k={DEL:"Delete",DOWN:"South",END:"Southwest",HOME:"Northwest",INSERT:"Insert",LEFT:"West",PAGEDOWN:"Southeast",PAGEUP:"Northeast",RIGHT:"East",SPACEBAR:"Space",UP:"North"},h=3,i=function(l){var u="";if(l.altKey&&(u+="Alt"),l.ctrlKey&&(u+="Ctrl"),l.shiftKey&&!(l.keyCode>=48&&l.keyCode<=57)&&(u+="Shift"),l.location===h&&(u+="Numpad"),S(l))if(l.shiftKey&&l.keyCode>=48&&l.keyCode<=57){var s=l.keyCode-48;u+="Shift"+s}else{var d=l.key.toUpperCase();u+=k[d]||d}return u},c=r.KeyComboModal=function(){function m(l,u){var s=(0,t.useBackend)(u),d=s.act,v=s.data,g=v.init_value,C=v.large_buttons,f=v.message,N=f===void 0?"":f,V=v.title,B=v.timeout,I=(0,t.useLocalState)(u,"input",g),L=I[0],w=I[1],A=(0,t.useLocalState)(u,"binding",!0),x=A[0],E=A[1],P=function(){function O(R){if(!x){R.key===a.KEY.Enter&&d("submit",{entry:L}),(0,a.isEscape)(R.key)&&d("cancel");return}if(R.preventDefault(),S(R)){D(i(R)),E(!1);return}else if(R.key===a.KEY.Escape){D(g),E(!1);return}}return O}(),D=function(){function O(R){R!==L&&w(R)}return O}(),M=130+(N.length>30?Math.ceil(N.length/3):0)+(N.length&&C?5:0);return(0,e.createComponentVNode)(2,p.Window,{title:V,width:240,height:M,children:[B&&(0,e.createComponentVNode)(2,y.Loader,{value:B}),(0,e.createComponentVNode)(2,p.Window.Content,{onKeyDown:function(){function O(R){P(R)}return O}(),children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Autofocus),(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Box,{color:"label",children:N})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{disabled:x,content:x&&x!==null?"Awaiting input...":""+L,width:"100%",textAlign:"center",onClick:function(){function O(){D(g),E(!0)}return O}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,b.InputButtons,{input:L})})]})]})})]})}return m}()},35655:function(T,r,n){"use strict";r.__esModule=!0,r.KeycardAuth=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.KeycardAuth=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=(0,e.createComponentVNode)(2,t.Section,{title:"Keycard Authentication Device",children:(0,e.createComponentVNode)(2,t.Box,{children:"This device is used to trigger certain high security events. It requires the simultaneous swipe of two high-level ID cards."})});if(!i.swiping&&!i.busy)return(0,e.createComponentVNode)(2,o.Window,{width:540,height:280,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[c,(0,e.createComponentVNode)(2,t.Section,{title:"Choose Action",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Red Alert",children:(0,e.createComponentVNode)(2,t.Button,{icon:"exclamation-triangle",disabled:!i.redAvailable,onClick:function(){function l(){return h("triggerevent",{triggerevent:"Red Alert"})}return l}(),content:"Red Alert"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"ERT",children:(0,e.createComponentVNode)(2,t.Button,{icon:"broadcast-tower",onClick:function(){function l(){return h("triggerevent",{triggerevent:"Emergency Response Team"})}return l}(),content:"Call ERT"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Emergency Maint Access",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"door-open",onClick:function(){function l(){return h("triggerevent",{triggerevent:"Grant Emergency Maintenance Access"})}return l}(),content:"Grant"}),(0,e.createComponentVNode)(2,t.Button,{icon:"door-closed",onClick:function(){function l(){return h("triggerevent",{triggerevent:"Revoke Emergency Maintenance Access"})}return l}(),content:"Revoke"})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Emergency Station-Wide Access",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"door-open",onClick:function(){function l(){return h("triggerevent",{triggerevent:"Activate Station-Wide Emergency Access"})}return l}(),content:"Grant"}),(0,e.createComponentVNode)(2,t.Button,{icon:"door-closed",onClick:function(){function l(){return h("triggerevent",{triggerevent:"Deactivate Station-Wide Emergency Access"})}return l}(),content:"Revoke"})]})]})})]})});var m=(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Waiting for YOU to swipe your ID..."});return!i.hasSwiped&&!i.ertreason&&i.event==="Emergency Response Team"?m=(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Fill out the reason for your ERT request."}):i.hasConfirm?m=(0,e.createComponentVNode)(2,t.Box,{color:"green",children:"Request Confirmed!"}):i.isRemote?m=(0,e.createComponentVNode)(2,t.Box,{color:"orange",children:"Swipe your card to CONFIRM the remote request."}):i.hasSwiped&&(m=(0,e.createComponentVNode)(2,t.Box,{color:"orange",children:"Waiting for second person to confirm..."})),(0,e.createComponentVNode)(2,o.Window,{width:540,height:265,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[c,i.event==="Emergency Response Team"&&(0,e.createComponentVNode)(2,t.Section,{title:"Reason for ERT Call",children:(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{color:i.ertreason?"":"red",icon:i.ertreason?"check":"pencil-alt",content:i.ertreason?i.ertreason:"-----",disabled:i.busy,onClick:function(){function l(){return h("ert")}return l}()})})}),(0,e.createComponentVNode)(2,t.Section,{title:i.event,buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-circle-left",content:"Back",disabled:i.busy||i.hasConfirm,onClick:function(){function l(){return h("reset")}return l}()}),children:m})]})})}return b}()},62955:function(T,r,n){"use strict";r.__esModule=!0,r.KitchenMachine=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(62411),b=r.KitchenMachine=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.data,m=i.config,l=c.ingredients,u=c.operating,s=m.title;return(0,e.createComponentVNode)(2,o.Window,{width:400,height:320,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,p.Operating,{operating:u,name:s}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,y)}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Ingredients",children:(0,e.createComponentVNode)(2,t.Table,{className:"Ingredient__Table",children:l.map(function(d){return(0,e.createComponentVNode)(2,t.Table.Row,{tr:5,children:[(0,e.createVNode)(1,"td",null,(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:d.name}),2),(0,e.createVNode)(1,"td",null,(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,textAlign:"center",children:[d.amount," ",d.units]}),2)]},d.name)})})})})]})})})}return S}(),y=function(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.inactive,u=m.tooltip;return(0,e.createComponentVNode)(2,t.Section,{title:"Controls",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"50%",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"power-off",disabled:l,tooltip:l?u:"",tooltipPosition:"bottom",content:"Activate",onClick:function(){function s(){return c("cook")}return s}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"50%",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"eject",disabled:l,tooltip:l?u:"",tooltipPosition:"bottom",content:"Eject Contents",onClick:function(){function s(){return c("eject")}return s}()})})]})})}},9525:function(T,r,n){"use strict";r.__esModule=!0,r.LawManager=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.LawManager=function(){function k(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.isAdmin,s=l.isSlaved,d=l.isMalf,v=l.isAIMalf,g=l.view;return(0,e.createComponentVNode)(2,o.Window,{width:800,height:d?620:365,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[!!(u&&s)&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:["This unit is slaved to ",s,"."]}),!!(d||v)&&(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Button,{content:"Law Management",selected:g===0,onClick:function(){function C(){return m("set_view",{set_view:0})}return C}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Lawsets",selected:g===1,onClick:function(){function C(){return m("set_view",{set_view:1})}return C}()})]}),g===0&&(0,e.createComponentVNode)(2,b),g===1&&(0,e.createComponentVNode)(2,y)]})})}return k}(),b=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.has_zeroth_laws,s=l.zeroth_laws,d=l.has_ion_laws,v=l.ion_laws,g=l.ion_law_nr,C=l.has_inherent_laws,f=l.inherent_laws,N=l.has_supplied_laws,V=l.supplied_laws,B=l.channels,I=l.channel,L=l.isMalf,w=l.isAdmin,A=l.zeroth_law,x=l.ion_law,E=l.inherent_law,P=l.supplied_law,D=l.supplied_law_position;return(0,e.createFragment)([!!u&&(0,e.createComponentVNode)(2,S,{title:"ERR_NULL_VALUE",laws:s,ctx:i}),!!d&&(0,e.createComponentVNode)(2,S,{title:g,laws:v,ctx:i}),!!C&&(0,e.createComponentVNode)(2,S,{title:"Inherent",laws:f,ctx:i}),!!N&&(0,e.createComponentVNode)(2,S,{title:"Supplied",laws:V,ctx:i}),(0,e.createComponentVNode)(2,t.Section,{title:"Statement Settings",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Statement Channel",children:B.map(function(M){return(0,e.createComponentVNode)(2,t.Button,{content:M.channel,selected:M.channel===I,onClick:function(){function O(){return m("law_channel",{law_channel:M.channel})}return O}()},M.channel)})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"State Laws",children:(0,e.createComponentVNode)(2,t.Button,{content:"State Laws",onClick:function(){function M(){return m("state_laws")}return M}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Law Notification",children:(0,e.createComponentVNode)(2,t.Button,{content:"Notify",onClick:function(){function M(){return m("notify_laws")}return M}()})})]})}),!!L&&(0,e.createComponentVNode)(2,t.Section,{title:"Add Laws",children:(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{width:"10%",children:"Type"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"60%",children:"Law"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"10%",children:"Index"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"20%",children:"Actions"})]}),!!(w&&!u)&&(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Zero"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:A}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"N/A"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button,{content:"Edit",icon:"pencil-alt",onClick:function(){function M(){return m("change_zeroth_law")}return M}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Add",icon:"plus",onClick:function(){function M(){return m("add_zeroth_law")}return M}()})]})]}),(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Ion"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:x}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"N/A"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button,{content:"Edit",icon:"pencil-alt",onClick:function(){function M(){return m("change_ion_law")}return M}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Add",icon:"plus",onClick:function(){function M(){return m("add_ion_law")}return M}()})]})]}),(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Inherent"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:E}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"N/A"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button,{content:"Edit",icon:"pencil-alt",onClick:function(){function M(){return m("change_inherent_law")}return M}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Add",icon:"plus",onClick:function(){function M(){return m("add_inherent_law")}return M}()})]})]}),(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Supplied"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:P}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:D,onClick:function(){function M(){return m("change_supplied_law_position")}return M}()})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button,{content:"Edit",icon:"pencil-alt",onClick:function(){function M(){return m("change_supplied_law")}return M}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Add",icon:"plus",onClick:function(){function M(){return m("add_supplied_law")}return M}()})]})]})]})})],0)},y=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.law_sets;return(0,e.createComponentVNode)(2,t.Box,{children:u.map(function(s){return(0,e.createComponentVNode)(2,t.Section,{title:s.name+" - "+s.header,buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Load Laws",icon:"download",onClick:function(){function d(){return m("transfer_laws",{transfer_laws:s.ref})}return d}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[s.laws.has_ion_laws>0&&s.laws.ion_laws.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:d.index,children:d.law},d.index)}),s.laws.has_zeroth_laws>0&&s.laws.zeroth_laws.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:d.index,children:d.law},d.index)}),s.laws.has_inherent_laws>0&&s.laws.inherent_laws.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:d.index,children:d.law},d.index)}),s.laws.has_supplied_laws>0&&s.laws.inherent_laws.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:d.index,children:d.law},d.index)})]})},s.name)})})},S=function(h,i){var c=(0,a.useBackend)(h.ctx),m=c.act,l=c.data,u=l.isMalf;return(0,e.createComponentVNode)(2,t.Section,{title:h.title+" Laws",children:(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{width:"10%",children:"Index"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"69%",children:"Law"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"21%",children:"State?"})]}),h.laws.map(function(s){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:s.index}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:s.law}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button,{content:s.state?"Yes":"No",selected:s.state,onClick:function(){function d(){return m("state_law",{ref:s.ref,state_law:s.state?0:1})}return d}()}),!!u&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:"Edit",icon:"pencil-alt",onClick:function(){function d(){return m("edit_law",{edit_law:s.ref})}return d}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Delete",icon:"trash",color:"red",onClick:function(){function d(){return m("delete_law",{delete_law:s.ref})}return d}()})],4)]})]},s.law)})]})})}},85066:function(T,r,n){"use strict";r.__esModule=!0,r.LibraryComputer=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(3939),b=r.LibraryComputer=function(){function g(C,f){return(0,e.createComponentVNode)(2,o.Window,{width:1050,height:600,children:[(0,e.createComponentVNode)(2,p.ComplexModal),(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,i),(0,e.createComponentVNode)(2,c)]})})]})}return g}(),y=function(C,f){var N=(0,a.useBackend)(f),V=N.act,B=N.data,I=C.args,L=B.user_ckey;return(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Title",children:I.title}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Author",children:I.author}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Summary",children:I.summary}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Rating",children:[I.rating,(0,e.createComponentVNode)(2,t.Icon,{name:"star",color:"yellow",verticalAlign:"top"})]}),!I.isProgrammatic&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Categories",children:I.categories.join(", ")})]}),(0,e.createVNode)(1,"br"),L===I.ckey&&(0,e.createComponentVNode)(2,t.Button,{content:"Delete Book",icon:"trash",color:"red",disabled:I.isProgrammatic,onClick:function(){function w(){return V("delete_book",{bookid:I.id,user_ckey:L})}return w}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Report Book",icon:"flag",color:"red",disabled:I.isProgrammatic,onClick:function(){function w(){return(0,p.modalOpen)(f,"report_book",{bookid:I.id})}return w}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Rate Book",icon:"star",color:"caution",disabled:I.isProgrammatic,onClick:function(){function w(){return(0,p.modalOpen)(f,"rate_info",{bookid:I.id})}return w}()})]})},S=function(C,f){var N=(0,a.useBackend)(f),V=N.act,B=N.data,I=C.args,L=B.selected_report,w=B.report_categories,A=B.user_ckey;return(0,e.createComponentVNode)(2,t.Section,{level:2,m:"-1rem",pb:"1.5rem",title:"Report this book for Rule Violations",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Title",children:I.title}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Reasons",children:(0,e.createComponentVNode)(2,t.Box,{children:w.map(function(x,E){return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:x.description,selected:x.category_id===L,onClick:function(){function P(){return V("set_report",{report_type:x.category_id})}return P}()}),(0,e.createVNode)(1,"br")],4,E)})})})]}),(0,e.createComponentVNode)(2,t.Button.Confirm,{bold:!0,icon:"paper-plane",content:"Submit Report",onClick:function(){function x(){return V("submit_report",{bookid:I.id,user_ckey:A})}return x}()})]})},k=function(C,f){var N=(0,a.useBackend)(f),V=N.act,B=N.data,I=B.selected_rating,L=Array(10).fill().map(function(w,A){return 1+A});return(0,e.createComponentVNode)(2,t.Stack,{children:[L.map(function(w,A){return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{bold:!0,icon:"star",color:I>=w?"caution":"default",onClick:function(){function x(){return V("set_rating",{rating_value:w})}return x}()})},A)}),(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,ml:2,fontSize:"150%",children:[I+"/10",(0,e.createComponentVNode)(2,t.Icon,{name:"star",color:"yellow",ml:.5,verticalAlign:"top"})]})]})},h=function(C,f){var N=(0,a.useBackend)(f),V=N.act,B=N.data,I=C.args,L=B.user_ckey;return(0,e.createComponentVNode)(2,t.Section,{level:2,m:"-1rem",pb:"1.5rem",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Title",children:I.title}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Author",children:I.author}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Rating",children:[I.current_rating?I.current_rating:0,(0,e.createComponentVNode)(2,t.Icon,{name:"star",color:"yellow",ml:.5,verticalAlign:"middle"})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Total Ratings",children:I.total_ratings?I.total_ratings:0})]}),(0,e.createComponentVNode)(2,k),(0,e.createComponentVNode)(2,t.Button.Confirm,{mt:2,content:"Submit",icon:"paper-plane",onClick:function(){function w(){return V("rate_book",{bookid:I.id,user_ckey:L})}return w}()})]})},i=function(C,f){var N=(0,a.useBackend)(f),V=N.data,B=(0,a.useLocalState)(f,"tabIndex",0),I=B[0],L=B[1],w=V.login_state;return(0,e.createComponentVNode)(2,t.Stack.Item,{mb:1,children:(0,e.createComponentVNode)(2,t.Tabs,{fluid:!0,textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:I===0,onClick:function(){function A(){return L(0)}return A}(),children:"Book Archives"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:I===1,onClick:function(){function A(){return L(1)}return A}(),children:"Corporate Literature"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:I===2,onClick:function(){function A(){return L(2)}return A}(),children:"Upload Book"}),w===1&&(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:I===3,onClick:function(){function A(){return L(3)}return A}(),children:"Patron Manager"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:I===4,onClick:function(){function A(){return L(4)}return A}(),children:"Inventory"})]})})},c=function(C,f){var N=(0,a.useLocalState)(f,"tabIndex",0),V=N[0];switch(V){case 0:return(0,e.createComponentVNode)(2,l);case 1:return(0,e.createComponentVNode)(2,u);case 2:return(0,e.createComponentVNode)(2,s);case 3:return(0,e.createComponentVNode)(2,d);case 4:return(0,e.createComponentVNode)(2,v);default:return"You are somehow on a tab that doesn't exist! Please let a coder know."}},m=function(C,f){var N=(0,a.useBackend)(f),V=N.act,B=N.data,I=B.searchcontent,L=B.book_categories,w=B.user_ckey,A=[];return L.map(function(x){return A[x.description]=x.category_id}),(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"35%",children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.2rem",m:".5em",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"edit",verticalAlign:"middle",size:1.5,mr:"1rem"}),"Search Inputs"]}),(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Title",children:(0,e.createComponentVNode)(2,t.Button,{textAlign:"left",icon:"pen",width:20,content:I.title||"Input Title",onClick:function(){function x(){return(0,p.modalOpen)(f,"edit_search_title")}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Author",children:(0,e.createComponentVNode)(2,t.Button,{textAlign:"left",icon:"pen",width:20,content:I.author||"Input Author",onClick:function(){function x(){return(0,p.modalOpen)(f,"edit_search_author")}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Ratings",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{mr:1,width:"min-content",content:I.ratingmin,onClick:function(){function x(){return(0,p.modalOpen)(f,"edit_search_ratingmin")}return x}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:"To"}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{ml:1,width:"min-content",content:I.ratingmax,onClick:function(){function x(){return(0,p.modalOpen)(f,"edit_search_ratingmax")}return x}()})})]})})]})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"40%",children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.2rem",m:".5em",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"clipboard-list",verticalAlign:"middle",size:1.5,mr:"1rem"}),"Book Categories"]}),(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Select Categories",children:(0,e.createComponentVNode)(2,t.Box,{mt:2,children:(0,e.createComponentVNode)(2,t.Dropdown,{mt:.6,width:"190px",options:L.map(function(x){return x.description}),onSelected:function(){function x(E){return V("toggle_search_category",{category_id:A[E]})}return x}()})})})}),(0,e.createVNode)(1,"br"),L.filter(function(x){return I.categories.includes(x.category_id)}).map(function(x){return(0,e.createComponentVNode)(2,t.Button,{content:x.description,selected:!0,icon:"unlink",onClick:function(){function E(){return V("toggle_search_category",{category_id:x.category_id})}return E}()},x.category_id)})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.2rem",m:".5em",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"search-plus",verticalAlign:"middle",size:1.5,mr:"1rem"}),"Search Actions"]}),(0,e.createComponentVNode)(2,t.Button,{content:"Clear Search",icon:"eraser",onClick:function(){function x(){return V("clear_search")}return x}()}),I.ckey?(0,e.createComponentVNode)(2,t.Button,{mb:.5,content:"Stop Showing My Books",color:"bad",icon:"search",onClick:function(){function x(){return V("clear_ckey_search")}return x}()}):(0,e.createComponentVNode)(2,t.Button,{content:"Find My Books",icon:"search",onClick:function(){function x(){return V("find_users_books",{user_ckey:w})}return x}()})]})]})},l=function(C,f){var N=(0,a.useBackend)(f),V=N.act,B=N.data,I=B.external_booklist,L=B.archive_pagenumber,w=B.num_pages,A=B.login_state;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Book System Access",buttons:(0,e.createVNode)(1,"div",null,[(0,e.createComponentVNode)(2,t.Button,{icon:"angle-double-left",disabled:L===1,onClick:function(){function x(){return V("deincrementpagemax")}return x}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-left",disabled:L===1,onClick:function(){function x(){return V("deincrementpage")}return x}()}),(0,e.createComponentVNode)(2,t.Button,{bold:!0,content:L,onClick:function(){function x(){return(0,p.modalOpen)(f,"setpagenumber")}return x}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-right",disabled:L===w,onClick:function(){function x(){return V("incrementpage")}return x}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"angle-double-right",disabled:L===w,onClick:function(){function x(){return V("incrementpagemax")}return x}()})],4),children:[(0,e.createComponentVNode)(2,m),(0,e.createVNode)(1,"hr"),(0,e.createComponentVNode)(2,t.Table,{className:"Library__Booklist",children:[(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"SSID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Title"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Author"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Ratings"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Category"}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"middle",children:"Actions"})]}),I.map(function(x){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:x.id}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"book",mr:.5}),x.title.length>45?x.title.substr(0,45)+"...":x.title]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:x.author.length>30?x.author.substr(0,30)+"...":x.author}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[x.rating,(0,e.createComponentVNode)(2,t.Icon,{name:"star",ml:.5,color:"yellow",verticalAlign:"middle"})]}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:x.categories.join(", ").substr(0,45)}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"right",children:[A===1&&(0,e.createComponentVNode)(2,t.Button,{content:"Order",icon:"print",onClick:function(){function E(){return V("order_external_book",{bookid:x.id})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{content:"More...",onClick:function(){function E(){return(0,p.modalOpen)(f,"expand_info",{bookid:x.id})}return E}()})]})]},x.id)})]})]})},u=function(C,f){var N=(0,a.useBackend)(f),V=N.act,B=N.data,I=B.programmatic_booklist,L=B.login_state;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Corporate Book Catalog",children:(0,e.createComponentVNode)(2,t.Table,{className:"Library__Booklist",children:[(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"SSID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Title"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Author"}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"middle",children:"Actions"})]}),I.map(function(w,A){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:w.id}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"book",mr:2}),w.title]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:w.author}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"right",children:[L===1&&(0,e.createComponentVNode)(2,t.Button,{content:"Order",icon:"print",onClick:function(){function x(){return V("order_programmatic_book",{bookid:w.id})}return x}()}),(0,e.createComponentVNode)(2,t.Button,{content:"More...",onClick:function(){function x(){return(0,p.modalOpen)(f,"expand_info",{bookid:w.id})}return x}()})]})]},A)})]})})},s=function(C,f){var N=(0,a.useBackend)(f),V=N.act,B=N.data,I=B.selectedbook,L=B.book_categories,w=B.user_ckey,A=[];return L.map(function(x){return A[x.description]=x.category_id}),(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Book System Upload",buttons:(0,e.createComponentVNode)(2,t.Button.Confirm,{bold:!0,width:9.5,icon:"upload",disabled:I.copyright,content:"Upload Book",onClick:function(){function x(){return V("uploadbook",{user_ckey:w})}return x}()}),children:[I.copyright?(0,e.createComponentVNode)(2,t.NoticeBox,{color:"red",children:"WARNING: You cannot upload or modify the attributes of a copyrighted book"}):(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Box,{ml:15,mb:3,fontSize:"1.2rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"search-plus",verticalAlign:"middle",size:3,mr:2}),"Book Uploader"]}),(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Title",children:(0,e.createComponentVNode)(2,t.Button,{width:20,textAlign:"left",icon:"pen",disabled:I.copyright,content:I.title,onClick:function(){function x(){return(0,p.modalOpen)(f,"edit_selected_title")}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Author",children:(0,e.createComponentVNode)(2,t.Button,{width:20,textAlign:"left",icon:"pen",disabled:I.copyright,content:I.author,onClick:function(){function x(){return(0,p.modalOpen)(f,"edit_selected_author")}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Select Categories",children:(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Dropdown,{width:"240px",options:L.map(function(x){return x.description}),onSelected:function(){function x(E){return V("toggle_upload_category",{category_id:A[E]})}return x}()})})})]}),(0,e.createVNode)(1,"br"),L.filter(function(x){return I.categories.includes(x.category_id)}).map(function(x){return(0,e.createComponentVNode)(2,t.Button,{content:x.description,disabled:I.copyright,selected:!0,icon:"unlink",onClick:function(){function E(){return V("toggle_upload_category",{category_id:x.category_id})}return E}()},x.category_id)})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{mr:75,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Summary",children:(0,e.createComponentVNode)(2,t.Button,{icon:"pen",width:"auto",disabled:I.copyright,content:"Edit Summary",onClick:function(){function x(){return(0,p.modalOpen)(f,"edit_selected_summary")}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{children:I.summary})]})})]})]})},d=function(C,f){var N=(0,a.useBackend)(f),V=N.act,B=N.data,I=B.checkout_data;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Checked Out Books",children:(0,e.createComponentVNode)(2,t.Table,{className:"Library__Booklist",children:[(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Patron"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Title"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Time Left"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Actions"})]}),I.map(function(L,w){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-tag"}),L.patron_name]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:L.title}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:L.timeleft>=0?L.timeleft:"LATE"}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:(0,e.createComponentVNode)(2,t.Button,{content:"Mark Lost",icon:"flag",color:"bad",disabled:L.timeleft>=0,onClick:function(){function A(){return V("reportlost",{libraryid:L.libraryid})}return A}()})})]},w)})]})})},v=function(C,f){var N=(0,a.useBackend)(f),V=N.act,B=N.data,I=B.inventory_list;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Library Inventory",children:(0,e.createComponentVNode)(2,t.Table,{className:"Library__Booklist",children:[(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"LIB ID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Title"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Author"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Status"})]}),I.map(function(L,w){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:L.libraryid}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"book"})," ",L.title]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:L.author}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:L.checked_out?"Checked Out":"Available"})]},w)})]})})};(0,p.modalRegisterBodyOverride)("expand_info",y),(0,p.modalRegisterBodyOverride)("report_book",S),(0,p.modalRegisterBodyOverride)("rate_info",h)},9516:function(T,r,n){"use strict";r.__esModule=!0,r.LibraryManager=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(3939),b=r.LibraryManager=function(){function i(c,m){return(0,e.createComponentVNode)(2,o.Window,{width:600,height:600,children:[(0,e.createComponentVNode)(2,p.ComplexModal),(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,className:"Layout__content--flexColumn",children:(0,e.createComponentVNode)(2,y)})]})}return i}(),y=function(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=s.pagestate;switch(d){case 1:return(0,e.createComponentVNode)(2,S);case 2:return(0,e.createComponentVNode)(2,h);case 3:return(0,e.createComponentVNode)(2,k);default:return"WE SHOULDN'T BE HERE!"}},S=function(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data;return(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.4rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-shield",verticalAlign:"middle",size:3,mr:"1rem"}),"Library Manager"]}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{icon:"trash",width:"auto",color:"danger",content:"Delete Book by SSID",onClick:function(){function d(){return(0,p.modalOpen)(m,"specify_ssid_delete")}return d}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"user-slash",width:"auto",color:"danger",content:"Delete All Books By CKEY",onClick:function(){function d(){return(0,p.modalOpen)(m,"specify_ckey_delete")}return d}()}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{icon:"search",width:"auto",content:"View All Books By CKEY",onClick:function(){function d(){return(0,p.modalOpen)(m,"specify_ckey_search")}return d}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"search",width:"auto",content:"View All Reported Books",onClick:function(){function d(){return u("view_reported_books")}return d}()})]})},k=function(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=s.reports;return(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.Table,{className:"Library__Booklist",children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.2rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-secret",verticalAlign:"middle",size:2,mr:"1rem"}),(0,e.createVNode)(1,"br"),"All Reported Books",(0,e.createVNode)(1,"br")]}),(0,e.createComponentVNode)(2,t.Button,{content:"Return to Main",icon:"arrow-alt-circle-left",onClick:function(){function v(){return u("return")}return v}()}),(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Uploader CKEY"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"SSID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Title"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Author"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Report Type"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Reporter Ckey"}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"middle",children:"Administrative Actions"})]}),d.map(function(v){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:v.uploader_ckey}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:v.id}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"book"}),v.title]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:v.author}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:v.report_description}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:v.reporter_ckey}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button.Confirm,{content:"Delete",icon:"trash",onClick:function(){function g(){return u("delete_book",{bookid:v.id})}return g}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Unflag",icon:"flag",color:"caution",onClick:function(){function g(){return u("unflag_book",{bookid:v.id})}return g}()}),(0,e.createComponentVNode)(2,t.Button,{content:"View",onClick:function(){function g(){return u("view_book",{bookid:v.id})}return g}()})]})]},v.id)})]})})},h=function(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=s.ckey,v=s.booklist;return(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.Table,{className:"Library__Booklist",children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.2rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user",verticalAlign:"middle",size:2,mr:"1rem"}),(0,e.createVNode)(1,"br"),"Books uploaded by ",d,(0,e.createVNode)(1,"br")]}),(0,e.createComponentVNode)(2,t.Button,{mt:1,content:"Return to Main",icon:"arrow-alt-circle-left",onClick:function(){function g(){return u("return")}return g}()}),(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"SSID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Title"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Author"}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"middle",children:"Administrative Actions"})]}),v.map(function(g){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:g.id}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"book"}),g.title]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"left",children:g.author}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"right",children:[(0,e.createComponentVNode)(2,t.Button.Confirm,{content:"Delete",icon:"trash",color:"bad",onClick:function(){function C(){return u("delete_book",{bookid:g.id})}return C}()}),(0,e.createComponentVNode)(2,t.Button,{content:"View",onClick:function(){function C(){return u("view_book",{bookid:g.id})}return C}()})]})]},g.id)})]})})}},90447:function(T,r,n){"use strict";r.__esModule=!0,r.ListInputModal=void 0;var e=n(89005),a=n(51057),t=n(19203),o=n(36036),p=n(72253),b=n(92986),y=n(98595),S=r.ListInputModal=function(){function i(c,m){var l=(0,p.useBackend)(m),u=l.act,s=l.data,d=s.items,v=d===void 0?[]:d,g=s.message,C=g===void 0?"":g,f=s.init_value,N=s.timeout,V=s.title,B=(0,p.useLocalState)(m,"selected",v.indexOf(f)),I=B[0],L=B[1],w=(0,p.useLocalState)(m,"searchBarVisible",v.length>10),A=w[0],x=w[1],E=(0,p.useLocalState)(m,"searchQuery",""),P=E[0],D=E[1],M=function(){function G(X){var J=z.length-1;if(X===b.KEY_DOWN)if(I===null||I===J){var se;L(0),(se=document.getElementById("0"))==null||se.scrollIntoView()}else{var ie;L(I+1),(ie=document.getElementById((I+1).toString()))==null||ie.scrollIntoView()}else if(X===b.KEY_UP)if(I===null||I===0){var me;L(J),(me=document.getElementById(J.toString()))==null||me.scrollIntoView()}else{var q;L(I-1),(q=document.getElementById((I-1).toString()))==null||q.scrollIntoView()}}return G}(),O=function(){function G(X){X!==I&&L(X)}return G}(),R=function(){function G(){x(!1),x(!0)}return G}(),F=function(){function G(X){var J=String.fromCharCode(X),se=v.find(function(q){return q==null?void 0:q.toLowerCase().startsWith(J==null?void 0:J.toLowerCase())});if(se){var ie,me=v.indexOf(se);L(me),(ie=document.getElementById(me.toString()))==null||ie.scrollIntoView()}}return G}(),W=function(){function G(X){var J;X!==P&&(D(X),L(0),(J=document.getElementById("0"))==null||J.scrollIntoView())}return G}(),U=function(){function G(){x(!A),D("")}return G}(),z=v.filter(function(G){return G==null?void 0:G.toLowerCase().includes(P.toLowerCase())}),$=330+Math.ceil(C.length/3);return A||setTimeout(function(){var G;return(G=document.getElementById(I.toString()))==null?void 0:G.focus()},1),(0,e.createComponentVNode)(2,y.Window,{title:V,width:325,height:$,children:[N&&(0,e.createComponentVNode)(2,a.Loader,{value:N}),(0,e.createComponentVNode)(2,y.Window.Content,{onKeyDown:function(){function G(X){var J=window.event?X.which:X.keyCode;(J===b.KEY_DOWN||J===b.KEY_UP)&&(X.preventDefault(),M(J)),J===b.KEY_ENTER&&(X.preventDefault(),u("submit",{entry:z[I]})),!A&&J>=b.KEY_A&&J<=b.KEY_Z&&(X.preventDefault(),F(J)),J===b.KEY_ESCAPE&&(X.preventDefault(),u("cancel"))}return G}(),children:(0,e.createComponentVNode)(2,o.Section,{buttons:(0,e.createComponentVNode)(2,o.Button,{compact:!0,icon:A?"search":"font",selected:!0,tooltip:A?"Search Mode. Type to search or use arrow keys to select manually.":"Hotkey Mode. Type a letter to jump to the first match. Enter to select.",tooltipPosition:"left",onClick:function(){function G(){return U()}return G}()}),className:"ListInput__Section",fill:!0,title:C,children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,k,{filteredItems:z,onClick:O,onFocusSearch:R,searchBarVisible:A,selected:I})}),(0,e.createComponentVNode)(2,o.Stack.Item,{m:0,children:A&&(0,e.createComponentVNode)(2,h,{filteredItems:z,onSearch:W,searchQuery:P,selected:I})}),(0,e.createComponentVNode)(2,o.Stack.Item,{mt:.5,children:(0,e.createComponentVNode)(2,t.InputButtons,{input:z[I]})})]})})})]})}return i}(),k=function(c,m){var l=(0,p.useBackend)(m),u=l.act,s=c.filteredItems,d=c.onClick,v=c.onFocusSearch,g=c.searchBarVisible,C=c.selected;return(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,tabIndex:0,children:s.map(function(f,N){return(0,e.createComponentVNode)(2,o.Button,{fluid:!0,color:"transparent",id:N,onClick:function(){function V(){return d(N)}return V}(),onDblClick:function(){function V(B){B.preventDefault(),u("submit",{entry:s[C]})}return V}(),onKeyDown:function(){function V(B){var I=window.event?B.which:B.keyCode;g&&I>=b.KEY_A&&I<=b.KEY_Z&&(B.preventDefault(),v())}return V}(),selected:N===C,style:{animation:"none",transition:"none"},children:f.replace(/^\w/,function(V){return V.toUpperCase()})},N)})})},h=function(c,m){var l=(0,p.useBackend)(m),u=l.act,s=c.filteredItems,d=c.onSearch,v=c.searchQuery,g=c.selected;return(0,e.createComponentVNode)(2,o.Input,{width:"100%",autoFocus:!0,autoSelect:!0,onEnter:function(){function C(f){f.preventDefault(),u("submit",{entry:s[g]})}return C}(),onInput:function(){function C(f,N){return d(N)}return C}(),placeholder:"Search...",value:v})}},26826:function(T,r,n){"use strict";r.__esModule=!0,r.Loadout=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),p=n(98595),b={Default:function(){function c(m,l){return m.gear.gear_tier-l.gear.gear_tier}return c}(),Alphabetical:function(){function c(m,l){return m.gear.name.toLowerCase().localeCompare(l.gear.name.toLowerCase())}return c}(),Cost:function(){function c(m,l){return m.gear.cost-l.gear.cost}return c}()},y=r.Loadout=function(){function c(m,l){var u=(0,t.useBackend)(l),s=u.act,d=u.data,v=(0,t.useLocalState)(l,"search",!1),g=v[0],C=v[1],f=(0,t.useLocalState)(l,"searchText",""),N=f[0],V=f[1],B=(0,t.useLocalState)(l,"category",Object.keys(d.gears)[0]),I=B[0],L=B[1],w=(0,t.useLocalState)(l,"tweakedGear",""),A=w[0],x=w[1];return(0,e.createComponentVNode)(2,p.Window,{width:975,height:650,children:[A&&(0,e.createComponentVNode)(2,i,{tweakedGear:A,setTweakedGear:x}),(0,e.createComponentVNode)(2,p.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,S,{category:I,setCategory:L})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"25%",children:(0,e.createComponentVNode)(2,h,{setTweakedGear:x})}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"75%",children:(0,e.createComponentVNode)(2,k,{category:I,search:g,setSearch:C,searchText:N,setSearchText:V})})]})})]})})]})}return c}(),S=function(m,l){var u=(0,t.useBackend)(l),s=u.act,d=u.data,v=m.category,g=m.setCategory;return(0,e.createComponentVNode)(2,o.Tabs,{fluid:!0,textAlign:"center",style:{"flex-wrap":"wrap-reverse"},children:Object.keys(d.gears).map(function(C){return(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:C===v,style:{"white-space":"nowrap"},onClick:function(){function f(){return g(C)}return f}(),children:C},C)})})},k=function(m,l){var u=(0,t.useBackend)(l),s=u.act,d=u.data,v=d.user_tier,g=d.gear_slots,C=d.max_gear_slots,f=m.category,N=m.search,V=m.setSearch,B=m.searchText,I=m.setSearchText,L=(0,t.useLocalState)(l,"sortType","Default"),w=L[0],A=L[1],x=(0,t.useLocalState)(l,"sortReverse",!1),E=x[0],P=x[1],D=(0,a.createSearch)(B,function(O){return O.name}),M;return B.length>2?M=Object.entries(d.gears).reduce(function(O,R){var F=R[0],W=R[1];return O.concat(Object.entries(W).map(function(U){var z=U[0],$=U[1];return{key:z,gear:$}}))},[]).filter(function(O){var R=O.gear;return D(R)}):M=Object.entries(d.gears[f]).map(function(O){var R=O[0],F=O[1];return{key:R,gear:F}}),M.sort(b[w]),E&&(M=M.reverse()),(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:f,buttons:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Dropdown,{height:1.66,selected:w,options:Object.keys(b),onSelected:function(){function O(R){return A(R)}return O}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{icon:E?"arrow-down-wide-short":"arrow-down-short-wide",tooltip:E?"Ascending order":"Descending order",tooltipPosition:"bottom-end",onClick:function(){function O(){return P(!E)}return O}()})}),N&&(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Input,{width:20,placeholder:"Search...",value:B,onInput:function(){function O(R){return I(R.target.value)}return O}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{icon:"magnifying-glass",selected:N,tooltip:"Toggle search field",tooltipPosition:"bottom-end",onClick:function(){function O(){V(!N),I("")}return O}()})})]}),children:M.map(function(O){var R=O.key,F=O.gear,W=12,U=Object.keys(d.selected_gears).includes(R),z=F.cost===1?F.cost+" Point":F.cost+" Points",$=(0,e.createComponentVNode)(2,o.Box,{children:[F.name.length>W&&(0,e.createComponentVNode)(2,o.Box,{children:F.name}),F.gear_tier>v&&(0,e.createComponentVNode)(2,o.Box,{mt:F.name.length>W&&1.5,textColor:"red",children:"That gear is only available at a higher donation tier than you are on."})]}),G=(0,e.createFragment)([F.allowed_roles&&(0,e.createComponentVNode)(2,o.Button,{width:"22px",color:"transparent",icon:"user",tooltip:(0,e.createComponentVNode)(2,o.Section,{m:-1,title:"Allowed Roles",children:F.allowed_roles.map(function(J){return(0,e.createComponentVNode)(2,o.Box,{children:J},J)})}),tooltipPosition:"left"}),Object.entries(F.tweaks).map(function(J){var se=J[0],ie=J[1];return ie.map(function(me){return(0,e.createComponentVNode)(2,o.Button,{width:"22px",color:"transparent",icon:me.icon,tooltip:me.tooltip,tooltipPosition:"top"},se)})}),(0,e.createComponentVNode)(2,o.Button,{width:"22px",color:"transparent",icon:"info",tooltip:F.desc,tooltipPosition:"top"})],0),X=(0,e.createComponentVNode)(2,o.Box,{class:"Loadout-InfoBox",children:[(0,e.createComponentVNode)(2,o.Box,{style:{"flex-grow":1},fontSize:1,color:"gold",opacity:.75,children:F.gear_tier>0&&"Tier "+F.gear_tier}),(0,e.createComponentVNode)(2,o.Box,{fontSize:.75,opacity:.66,children:z})]});return(0,e.createComponentVNode)(2,o.ImageButton,{m:.5,imageSize:84,dmIcon:F.icon,dmIconState:F.icon_state,tooltip:(F.name.length>W||F.gear_tier>0)&&$,tooltipPosition:"bottom",selected:U,disabled:F.gear_tier>v||g+F.cost>C&&!U,buttons:G,buttonsAlt:X,onClick:function(){function J(){return s("toggle_gear",{gear:R})}return J}(),children:F.name},R)})})},h=function(m,l){var u=(0,t.useBackend)(l),s=u.act,d=u.data,v=m.setTweakedGear,g=Object.entries(d.gears).reduce(function(C,f){var N=f[0],V=f[1],B=Object.entries(V).filter(function(I){var L=I[0];return Object.keys(d.selected_gears).includes(L)}).map(function(I){var L=I[0],w=I[1];return Object.assign({key:L},w)});return C.concat(B)},[]);return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Selected Equipment",buttons:(0,e.createComponentVNode)(2,o.Button.Confirm,{icon:"trash",tooltip:"Clear Loadout",tooltipPosition:"bottom-end",onClick:function(){function C(){return s("clear_loadout")}return C}()}),children:g.map(function(C){return(0,e.createComponentVNode)(2,o.ImageButton,{fluid:!0,imageSize:32,dmIcon:C.icon,dmIconState:C.icon_state,buttons:(0,e.createFragment)([Object.entries(C.tweaks).length>0&&(0,e.createComponentVNode)(2,o.Button,{translucent:!0,icon:"gears",iconColor:"gray",width:"33px",onClick:function(){function f(){return v(C)}return f}()}),(0,e.createComponentVNode)(2,o.Button,{translucent:!0,icon:"times",iconColor:"red",width:"32px",onClick:function(){function f(){return s("toggle_gear",{gear:C.key})}return f}()})],0),children:C.name},C.key)})})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.ProgressBar,{value:d.gear_slots,maxValue:d.max_gear_slots,ranges:{bad:[d.max_gear_slots,1/0],average:[d.max_gear_slots*.66,d.max_gear_slots],good:[0,d.max_gear_slots*.66]},children:(0,e.createComponentVNode)(2,o.Box,{textAlign:"center",children:["Used points ",d.gear_slots,"/",d.max_gear_slots]})})})})]})},i=function(m,l){var u=(0,t.useBackend)(l),s=u.act,d=u.data,v=m.tweakedGear,g=m.setTweakedGear;return(0,e.createComponentVNode)(2,o.Dimmer,{children:(0,e.createComponentVNode)(2,o.Box,{className:"Loadout-Modal__background",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,width:20,height:20,title:v.name,buttons:(0,e.createComponentVNode)(2,o.Button,{color:"red",icon:"times",tooltip:"Close",tooltipPosition:"top",onClick:function(){function C(){return g("")}return C}()}),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:Object.entries(v.tweaks).map(function(C){var f=C[0],N=C[1];return N.map(function(V){var B=d.selected_gears[v.key][f];return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:V.name,color:B?"":"gray",buttons:(0,e.createComponentVNode)(2,o.Button,{color:"transparent",icon:"pen",onClick:function(){function I(){return s("set_tweak",{gear:v.key,tweak:f})}return I}()}),children:[B||"Default",(0,e.createComponentVNode)(2,o.Box,{inline:!0,ml:1,width:1,height:1,verticalAlign:"middle",style:{"background-color":""+B}})]},f)})})})})})})}},77613:function(T,r,n){"use strict";r.__esModule=!0,r.MODsuitContent=r.MODsuit=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=function(I,L){var w=I.name,A=I.value,x=I.module_ref,E=(0,a.useBackend)(L),P=E.act;return(0,e.createComponentVNode)(2,t.NumberInput,{value:A,minValue:-50,maxValue:50,stepPixelSize:5,width:"39px",onChange:function(){function D(M,O){return P("configure",{key:w,value:O,ref:x})}return D}()})},b=function(I,L){var w=I.name,A=I.value,x=I.module_ref,E=(0,a.useBackend)(L),P=E.act;return(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:A,onClick:function(){function D(){return P("configure",{key:w,value:!A,ref:x})}return D}()})},y=function(I,L){var w=I.name,A=I.value,x=I.module_ref,E=(0,a.useBackend)(L),P=E.act;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{icon:"paint-brush",onClick:function(){function D(){return P("configure",{key:w,ref:x})}return D}()}),(0,e.createComponentVNode)(2,t.ColorBox,{color:A,mr:.5})],4)},S=function(I,L){var w=I.name,A=I.value,x=I.values,E=I.module_ref,P=(0,a.useBackend)(L),D=P.act;return(0,e.createComponentVNode)(2,t.Dropdown,{displayText:A,options:x,onSelected:function(){function M(O){return D("configure",{key:w,value:O,ref:E})}return M}()})},k=function(I,L){var w=I.name,A=I.display_name,x=I.type,E=I.value,P=I.values,D=I.module_ref,M={number:(0,e.normalizeProps)((0,e.createComponentVNode)(2,p,Object.assign({},I))),bool:(0,e.normalizeProps)((0,e.createComponentVNode)(2,b,Object.assign({},I))),color:(0,e.normalizeProps)((0,e.createComponentVNode)(2,y,Object.assign({},I))),list:(0,e.normalizeProps)((0,e.createComponentVNode)(2,S,Object.assign({},I)))};return(0,e.createComponentVNode)(2,t.Box,{children:[A,": ",M[x]]})},h=function(I,L){var w=I.active,A=I.userradiated,x=I.usertoxins,E=I.usermaxtoxins,P=I.threatlevel;return(0,e.createComponentVNode)(2,t.Stack,{fill:!0,textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Radiation Level",color:w&&A?"bad":"good",children:w&&A?"IRRADIATED!":"RADIATION-FREE"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Toxins Level",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?x/E:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:x})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Hazard Level",color:w&&P?"bad":"good",bold:!0,children:w&&P?P:0})})]})},i=function(I,L){var w=I.active,A=I.userhealth,x=I.usermaxhealth,E=I.userbrute,P=I.userburn,D=I.usertoxin,M=I.useroxy;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{title:"Health",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?A/x:0,ranges:{good:[.5,1/0],average:[.2,.5],bad:[-1/0,.2]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?A:0})})}),(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Brute",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?E/x:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?E:0})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Burn",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?P/x:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?P:0})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Toxin",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?D/x:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?D:0})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Suffocation",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?M/x:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?M:0})})})})]})],4)},c=function(I,L){var w=I.active,A=I.statustime,x=I.statusid,E=I.statushealth,P=I.statusmaxhealth,D=I.statusbrute,M=I.statusburn,O=I.statustoxin,R=I.statusoxy,F=I.statustemp,W=I.statusnutrition,U=I.statusfingerprints,z=I.statusdna,$=I.statusviruses;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Operation Time",children:w?A:"00:00:00"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Operation Number",children:w?x||"0":"???"})})]}),(0,e.createComponentVNode)(2,t.Section,{title:"Health",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?E/P:0,ranges:{good:[.5,1/0],average:[.2,.5],bad:[-1/0,.2]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?E:0})})}),(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Brute",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?D/P:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?D:0})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Burn",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?M/P:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:w?M:0})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Toxin",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?O/P:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:O})})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Suffocation",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:w?R/P:0,ranges:{good:[-1/0,.2],average:[.2,.5],bad:[.5,1/0]},children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:R})})})})]}),(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Body Temperature",children:w?F:0})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Nutrition Status",children:w?W:0})})]}),(0,e.createComponentVNode)(2,t.Section,{title:"DNA",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Fingerprints",children:w?U:"???"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Unique Enzymes",children:w?z:"???"})]})}),!!w&&!!$&&(0,e.createComponentVNode)(2,t.Section,{title:"Diseases",children:(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"signature",tooltip:"Name",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"wind",tooltip:"Type",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"bolt",tooltip:"Stage",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"flask",tooltip:"Cure",tooltipPosition:"top"})})]}),$.map(function(G){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:G.name}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:G.type}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:[G.stage,"/",G.maxstage]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:G.cure})]},G.name)})]})})],0)},m={rad_counter:h,health_analyzer:i,status_readout:c},l=function(){return(0,e.createComponentVNode)(2,t.Section,{align:"center",fill:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{color:"red",name:"exclamation-triangle",size:15}),(0,e.createComponentVNode)(2,t.Box,{fontSize:"30px",color:"red",children:"ERROR: INTERFACE UNRESPONSIVE"})]})},u=function(I,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data;return(0,e.createComponentVNode)(2,t.Dimmer,{children:(0,e.createComponentVNode)(2,t.Stack,{children:(0,e.createComponentVNode)(2,t.Stack.Item,{fontSize:"16px",color:"blue",children:"SUIT UNPOWERED"})})})},s=function(I,L){var w=I.configuration_data,A=I.module_ref,x=Object.keys(w);return(0,e.createComponentVNode)(2,t.Dimmer,{backgroundColor:"rgba(0, 0, 0, 0.8)",children:(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:[x.map(function(E){var P=w[E];return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,k,{name:E,display_name:P.display_name,type:P.type,value:P.value,values:P.values,module_ref:A})},P.key)}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,onClick:I.onExit,icon:"times",textAlign:"center",children:"Exit"})})})]})})},d=function(I){switch(I){case 1:return"Use";case 2:return"Toggle";case 3:return"Select"}},v=function(I,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data,E=x.active,P=x.malfunctioning,D=x.locked,M=x.open,O=x.selected_module,R=x.complexity,F=x.complexity_max,W=x.wearer_name,U=x.wearer_job,z=P?"Malfunctioning":E?"Active":"Inactive";return(0,e.createComponentVNode)(2,t.Section,{title:"Parameters",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"power-off",content:E?"Deactivate":"Activate",onClick:function(){function $(){return A("activate")}return $}()}),children:z}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"ID Lock",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:D?"lock-open":"lock",content:D?"Unlock":"Lock",onClick:function(){function $(){return A("lock")}return $}()}),children:D?"Locked":"Unlocked"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cover",children:M?"Open":"Closed"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Selected Module",children:O||"None"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Complexity",children:[R," (",F,")"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Occupant",children:[W,", ",U]})]})})},g=function(I,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data,E=x.active,P=x.control,D=x.helmet,M=x.chestplate,O=x.gauntlets,R=x.boots,F=x.core,W=x.charge;return(0,e.createComponentVNode)(2,t.Section,{title:"Hardware",children:[(0,e.createComponentVNode)(2,t.Collapsible,{title:"Parts",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Control Unit",children:P}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Helmet",children:D||"None"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Chestplate",children:M||"None"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Gauntlets",children:O||"None"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Boots",children:R||"None"})]})}),(0,e.createComponentVNode)(2,t.Collapsible,{title:"Core",children:F&&(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Core Type",children:F}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Core Charge",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:W/100,content:W+"%",ranges:{good:[.6,1/0],average:[.3,.6],bad:[-1/0,.3]}})})]})||(0,e.createComponentVNode)(2,t.Box,{color:"bad",textAlign:"center",children:"No Core Detected"})})]})},C=function(I,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data,E=x.active,P=x.modules,D=P.filter(function(M){return!!M.id});return(0,e.createComponentVNode)(2,t.Section,{title:"Info",children:(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:D.length!==0&&D.map(function(M){var O=m[M.id];return(0,e.createComponentVNode)(2,t.Stack.Item,{children:[!E&&(0,e.createComponentVNode)(2,u),(0,e.normalizeProps)((0,e.createComponentVNode)(2,O,Object.assign({},M,{active:E})))]},M.ref)})||(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",children:"No Info Modules Detected"})})})},f=function(I,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data,E=x.complexity_max,P=x.modules,D=(0,a.useLocalState)(L,"module_configuration",null),M=D[0],O=D[1];return(0,e.createComponentVNode)(2,t.Section,{title:"Modules",fill:!0,children:(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:P.length!==0&&P.map(function(R){return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Collapsible,{title:R.module_name,children:(0,e.createComponentVNode)(2,t.Section,{children:[M===R.ref&&(0,e.createComponentVNode)(2,s,{configuration_data:R.configuration_data,module_ref:R.ref,onExit:function(){function F(){return O(null)}return F}()}),(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"save",tooltip:"Complexity",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"plug",tooltip:"Idle Power Cost",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"lightbulb",tooltip:"Active Power Cost",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"bolt",tooltip:"Use Power Cost",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"hourglass-half",tooltip:"Cooldown",tooltipPosition:"top"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{color:"transparent",icon:"tasks",tooltip:"Actions",tooltipPosition:"top"})})]}),(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:[R.module_complexity,"/",E]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:R.idle_power}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:R.active_power}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:R.use_power}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:[R.cooldown>0&&R.cooldown/10||"0","/",R.cooldown_time/10,"s"]}),(0,e.createComponentVNode)(2,t.Table.Cell,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Button,{onClick:function(){function F(){return A("select",{ref:R.ref})}return F}(),icon:"bullseye",selected:R.module_active,tooltip:d(R.module_type),tooltipPosition:"left",disabled:!R.module_type}),(0,e.createComponentVNode)(2,t.Button,{onClick:function(){function F(){return O(R.ref)}return F}(),icon:"cog",selected:M===R.ref,tooltip:"Configure",tooltipPosition:"left",disabled:R.configuration_data.length===0}),(0,e.createComponentVNode)(2,t.Button,{onClick:function(){function F(){return A("pin",{ref:R.ref})}return F}(),icon:"thumbtack",selected:R.pinned,tooltip:"Pin",tooltipPosition:"left",disabled:!R.module_type})]})]})]}),(0,e.createComponentVNode)(2,t.Box,{children:R.description})]})})},R.ref)})||(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",children:"No Modules Detected"})})})})},N=r.MODsuitContent=function(){function B(I,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data,E=x.ui_theme,P=x.interface_break;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!P,children:!!P&&(0,e.createComponentVNode)(2,l)||(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,v)}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,g)}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,C)}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,f)})]})})}return B}(),V=r.MODsuit=function(){function B(I,L){var w=(0,a.useBackend)(L),A=w.act,x=w.data,E=x.ui_theme,P=x.interface_break;return(0,e.createComponentVNode)(2,o.Window,{theme:E,width:400,height:620,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,N)})})})}return B}()},78624:function(T,r,n){"use strict";r.__esModule=!0,r.MagnetController=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=n(98595),b=n(3939),y=new Map([["n",{icon:"arrow-up",tooltip:"Move North"}],["e",{icon:"arrow-right",tooltip:"Move East"}],["s",{icon:"arrow-down",tooltip:"Move South"}],["w",{icon:"arrow-left",tooltip:"Move West"}],["c",{icon:"crosshairs",tooltip:"Move to Magnet"}],["r",{icon:"dice",tooltip:"Move Randomly"}]]),S=r.MagnetController=function(){function k(h,i){var c=(0,t.useBackend)(i),m=c.act,l=c.data,u=l.autolink,s=l.code,d=l.frequency,v=l.linkedMagnets,g=l.magnetConfiguration,C=l.path,f=l.pathPosition,N=l.probing,V=l.powerState,B=l.speed;return(0,e.createComponentVNode)(2,p.Window,{width:400,height:600,children:[(0,e.createComponentVNode)(2,b.ComplexModal),(0,e.createComponentVNode)(2,p.Window.Content,{scrollable:!0,children:[!u&&(0,e.createComponentVNode)(2,o.Section,{buttons:(0,e.createComponentVNode)(2,o.Button,{content:"Probe",icon:N?"spinner":"sync",iconSpin:!!N,disabled:N,onClick:function(){function I(){return m("probe_magnets")}return I}()}),title:"Magnet Linking",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Frequency",children:(0,a.toFixed)(d/10,1)}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Code",children:s})]})}),(0,e.createComponentVNode)(2,o.Section,{buttons:(0,e.createComponentVNode)(2,o.Button,{icon:V?"power-off":"times",content:V?"On":"Off",selected:V,onClick:function(){function I(){return m("toggle_power")}return I}()}),title:"Controller Configuration",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Speed",children:(0,e.createComponentVNode)(2,o.Slider,{value:B.value,minValue:B.min,maxValue:B.max,onChange:function(){function I(L,w){return m("set_speed",{speed:w})}return I}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Path",children:[Array.from(y.entries()).map(function(I){var L=I[0],w=I[1],A=w.icon,x=w.tooltip;return(0,e.createComponentVNode)(2,o.Button,{icon:A,tooltip:x,onClick:function(){function E(){return m("path_add",{code:L})}return E}()},L)}),(0,e.createComponentVNode)(2,o.Button.Confirm,{icon:"trash",confirmIcon:"trash",confirmContent:"",float:"right",tooltip:"Reset Path",tooltipPosition:"left",onClick:function(){function I(){return m("path_clear")}return I}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"file-import",float:"right",tooltip:"Manually input path",tooltipPosition:"left",onClick:function(){function I(){return(0,b.modalOpen)(i,"path_custom_input")}return I}()}),(0,e.createComponentVNode)(2,o.BlockQuote,{children:C.map(function(I,L){var w=y.get(I)||{icon:"question"},A=w.icon,x=w.tooltip;return(0,e.createComponentVNode)(2,o.Button.Confirm,{selected:L+2===f,icon:A,confirmIcon:A,confirmContent:"",tooltip:x,onClick:function(){function E(){return m("path_remove",{index:L+1,code:I})}return E}()},L)})})]})]})}),v.map(function(I,L){var w=I.uid,A=I.powerState,x=I.electricityLevel,E=I.magneticField;return(0,e.createComponentVNode)(2,o.Section,{title:"Magnet #"+(L+1)+" Configuration",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:A?"power-off":"times",content:A?"On":"Off",selected:A,onClick:function(){function P(){return m("toggle_magnet_power",{id:w})}return P}()}),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Move Speed",children:(0,e.createComponentVNode)(2,o.Slider,{value:x,minValue:g.electricityLevel.min,maxValue:g.electricityLevel.max,onChange:function(){function P(D,M){return m("set_electricity_level",{id:w,electricityLevel:M})}return P}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Field Size",children:(0,e.createComponentVNode)(2,o.Slider,{value:E,minValue:g.magneticField.min,maxValue:g.magneticField.max,onChange:function(){function P(D,M){return m("set_magnetic_field",{id:w,magneticField:M})}return P}()})})]})},w)})]})]})}return k}()},72106:function(T,r,n){"use strict";r.__esModule=!0,r.MechBayConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.MechBayConsole=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.recharge_port,m=c&&c.mech,l=m&&m.cell,u=m&&m.name;return(0,e.createComponentVNode)(2,o.Window,{width:400,height:155,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:u?"Mech status: "+u:"Mech status",textAlign:"center",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"sync",content:"Sync",onClick:function(){function s(){return h("reconnect")}return s}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Integrity",children:!c&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No power port detected. Please re-sync."})||!m&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No mech detected."})||(0,e.createComponentVNode)(2,t.ProgressBar,{value:m.health/m.maxhealth,ranges:{good:[.7,1/0],average:[.3,.7],bad:[-1/0,.3]}})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:!c&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No power port detected. Please re-sync."})||!m&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No mech detected."})||!l&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No cell is installed."})||(0,e.createComponentVNode)(2,t.ProgressBar,{value:l.charge/l.maxcharge,ranges:{good:[.7,1/0],average:[.3,.7],bad:[-1/0,.3]},children:[(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:l.charge})," / "+l.maxcharge]})})]})})})})}return b}()},7466:function(T,r,n){"use strict";r.__esModule=!0,r.MechaControlConsole=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=n(98595),b=n(25328),y=r.MechaControlConsole=function(){function S(k,h){var i=(0,t.useBackend)(h),c=i.act,m=i.data,l=m.beacons,u=m.stored_data;return u.length?(0,e.createComponentVNode)(2,p.Window,{width:420,height:500,children:(0,e.createComponentVNode)(2,p.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,o.Section,{title:"Log",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"window-close",onClick:function(){function s(){return c("clear_log")}return s}()}),children:u.map(function(s){return(0,e.createComponentVNode)(2,o.Box,{children:[(0,e.createComponentVNode)(2,o.Box,{color:"label",children:["(",s.time,")"]}),(0,e.createComponentVNode)(2,o.Box,{children:(0,b.decodeHtmlEntities)(s.message)})]},s.time)})})})}):(0,e.createComponentVNode)(2,p.Window,{width:420,height:500,children:(0,e.createComponentVNode)(2,p.Window.Content,{scrollable:!0,children:l.length&&l.map(function(s){return(0,e.createComponentVNode)(2,o.Section,{title:s.name,buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{icon:"comment",onClick:function(){function d(){return c("send_message",{mt:s.uid})}return d}(),children:"Message"}),(0,e.createComponentVNode)(2,o.Button,{icon:"eye",onClick:function(){function d(){return c("get_log",{mt:s.uid})}return d}(),children:"View Log"}),(0,e.createComponentVNode)(2,o.Button.Confirm,{color:"red",content:"Sabotage",icon:"bomb",onClick:function(){function d(){return c("shock",{mt:s.uid})}return d}()})],4),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Health",children:(0,e.createComponentVNode)(2,o.ProgressBar,{ranges:{good:[s.maxHealth*.75,1/0],average:[s.maxHealth*.5,s.maxHealth*.75],bad:[-1/0,s.maxHealth*.5]},value:s.health,maxValue:s.maxHealth})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Cell Charge",children:s.cell&&(0,e.createComponentVNode)(2,o.ProgressBar,{ranges:{good:[s.cellMaxCharge*.75,1/0],average:[s.cellMaxCharge*.5,s.cellMaxCharge*.75],bad:[-1/0,s.cellMaxCharge*.5]},value:s.cellCharge,maxValue:s.cellMaxCharge})||(0,e.createComponentVNode)(2,o.NoticeBox,{children:"No Cell Installed"})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Air Tank",children:[s.airtank,"kPa"]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Pilot",children:s.pilot||"Unoccupied"}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Location",children:(0,b.toTitleCase)(s.location)||"Unknown"}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Active Equipment",children:s.active||"None"}),s.cargoMax&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Cargo Space",children:(0,e.createComponentVNode)(2,o.ProgressBar,{ranges:{bad:[s.cargoMax*.75,1/0],average:[s.cargoMax*.5,s.cargoMax*.75],good:[-1/0,s.cargoMax*.5]},value:s.cargoUsed,maxValue:s.cargoMax})})||null]})},s.name)})||(0,e.createComponentVNode)(2,o.NoticeBox,{children:"No mecha beacons found."})})})}return S}()},79625:function(T,r,n){"use strict";r.__esModule=!0,r.MedicalRecords=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),p=n(3939),b=n(98595),y=n(321),S=n(5485),k=n(22091),h={Minor:"lightgray",Medium:"good",Harmful:"average","Dangerous!":"bad","BIOHAZARD THREAT!":"darkred"},i={"*Deceased*":"deceased","*SSD*":"ssd","Physically Unfit":"physically_unfit",Disabled:"disabled"},c=function(A,x){(0,p.modalOpen)(A,"edit",{field:x.edit,value:x.value})},m=function(A,x){var E=A.args;return(0,e.createComponentVNode)(2,o.Section,{m:"-1rem",pb:"1.5rem",title:E.name||"Virus",children:(0,e.createComponentVNode)(2,o.Box,{mx:"0.5rem",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Number of stages",children:E.max_stages}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Spread",children:[E.spread_text," Transmission"]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Possible cure",children:E.cure}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Notes",children:E.desc}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Severity",color:h[E.severity],children:E.severity})]})})})},l=r.MedicalRecords=function(){function w(A,x){var E=(0,t.useBackend)(x),P=E.data,D=P.loginState,M=P.screen;if(!D.logged_in)return(0,e.createComponentVNode)(2,b.Window,{width:800,height:900,children:(0,e.createComponentVNode)(2,b.Window.Content,{children:(0,e.createComponentVNode)(2,S.LoginScreen)})});var O;return M===2?O=(0,e.createComponentVNode)(2,u):M===3?O=(0,e.createComponentVNode)(2,s):M===4?O=(0,e.createComponentVNode)(2,d):M===5?O=(0,e.createComponentVNode)(2,f):M===6?O=(0,e.createComponentVNode)(2,N):M===7&&(O=(0,e.createComponentVNode)(2,V)),(0,e.createComponentVNode)(2,b.Window,{width:800,height:900,children:[(0,e.createComponentVNode)(2,p.ComplexModal),(0,e.createComponentVNode)(2,b.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,y.LoginInfo),(0,e.createComponentVNode)(2,k.TemporaryNotice),(0,e.createComponentVNode)(2,L),O]})})]})}return w}(),u=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.records,O=(0,t.useLocalState)(x,"searchText",""),R=O[0],F=O[1],W=(0,t.useLocalState)(x,"sortId","name"),U=W[0],z=W[1],$=(0,t.useLocalState)(x,"sortOrder",!0),G=$[0],X=$[1];return(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{content:"Manage Records",icon:"wrench",ml:"0.25rem",onClick:function(){function J(){return P("screen",{screen:3})}return J}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Input,{fluid:!0,placeholder:"Search by Name, ID, Physical Status, or Mental Status",onInput:function(){function J(se,ie){return F(ie)}return J}()})})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,mt:.5,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,o.Table,{className:"MedicalRecords__list",children:[(0,e.createComponentVNode)(2,o.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,B,{id:"name",children:"Name"}),(0,e.createComponentVNode)(2,B,{id:"id",children:"ID"}),(0,e.createComponentVNode)(2,B,{id:"rank",children:"Assignment"}),(0,e.createComponentVNode)(2,B,{id:"p_stat",children:"Patient Status"}),(0,e.createComponentVNode)(2,B,{id:"m_stat",children:"Mental Status"})]}),M.filter((0,a.createSearch)(R,function(J){return J.name+"|"+J.id+"|"+J.rank+"|"+J.p_stat+"|"+J.m_stat})).sort(function(J,se){var ie=G?1:-1;return J[U].localeCompare(se[U])*ie}).map(function(J){return(0,e.createComponentVNode)(2,o.Table.Row,{className:"MedicalRecords__listRow--"+i[J.p_stat],onClick:function(){function se(){return P("view_record",{view_record:J.ref})}return se}(),children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"user"})," ",J.name]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:J.id}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:J.rank}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:J.p_stat}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:J.m_stat})]},J.id)})]})})})],4)},s=function(A,x){var E=(0,t.useBackend)(x),P=E.act;return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Button,{fluid:!0,translucent:!0,lineHeight:3,icon:"download",content:"Backup to Disk",disabled:!0})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:[(0,e.createComponentVNode)(2,o.Button,{fluid:!0,translucent:!0,lineHeight:3,icon:"upload",content:"Upload from Disk",my:"0.5rem",disabled:!0})," "]}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Button.Confirm,{fluid:!0,translucent:!0,lineHeight:3,icon:"trash",content:"Delete All Medical Records",onClick:function(){function D(){return P("del_all_med_records")}return D}()})})]})})},d=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.medical,O=D.printing;return(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{height:"235px",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"General Data",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:O?"spinner":"print",disabled:O,iconSpin:!!O,content:"Print Record",ml:"0.5rem",onClick:function(){function R(){return P("print_record")}return R}()}),children:(0,e.createComponentVNode)(2,v)})}),!M||!M.fields?(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,color:"bad",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,title:"Medical Data",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"pen",content:"Create New Record",onClick:function(){function R(){return P("new_med_record")}return R}()}),children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{bold:!0,grow:!0,textAlign:"center",fontSize:1.75,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,o.Icon.Stack,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"scroll",size:5,color:"gray"}),(0,e.createComponentVNode)(2,o.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"Medical records lost!"]})})})}):(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Medical Data",buttons:(0,e.createComponentVNode)(2,o.Button.Confirm,{icon:"trash",disabled:!!M.empty,content:"Delete Medical Record",onClick:function(){function R(){return P("del_med_record")}return R}()}),children:(0,e.createComponentVNode)(2,g)})}),(0,e.createComponentVNode)(2,C)],4)],0)},v=function(A,x){var E=(0,t.useBackend)(x),P=E.data,D=P.general;return!D||!D.fields?(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,color:"bad",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:"General records lost!"})})}):(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.LabeledList,{children:D.fields.map(function(M,O){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:M.field,children:[(0,e.createComponentVNode)(2,o.Box,{height:"20px",inline:!0,children:M.value}),!!M.edit&&(0,e.createComponentVNode)(2,o.Button,{icon:"pen",ml:"0.5rem",onClick:function(){function R(){return c(x,M)}return R}()})]},O)})})}),!!D.has_photos&&D.photos.map(function(M,O){return(0,e.createComponentVNode)(2,o.Stack.Item,{inline:!0,textAlign:"center",color:"label",ml:0,children:[(0,e.createVNode)(1,"img",null,null,1,{src:M,style:{width:"96px","margin-top":"2.5rem","margin-bottom":"0.5rem","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"}}),(0,e.createVNode)(1,"br"),"Photo #",O+1]},O)})]})},g=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.medical;return!M||!M.fields?(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,color:"bad",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:"Medical records lost!"})})}):(0,e.createComponentVNode)(2,o.Stack,{children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.LabeledList,{children:M.fields.map(function(O,R){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:O.field,preserveWhitespace:!0,children:[(0,a.decodeHtmlEntities)(O.value),!!O.edit&&(0,e.createComponentVNode)(2,o.Button,{icon:"pen",ml:"0.5rem",mb:O.line_break?"1rem":"initial",onClick:function(){function F(){return c(x,O)}return F}()})]},R)})})})})},C=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.medical;return(0,e.createComponentVNode)(2,o.Stack.Item,{height:"150px",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Comments/Log",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"comment",content:"Add Entry",onClick:function(){function O(){return(0,p.modalOpen)(x,"add_comment")}return O}()}),children:M.comments.length===0?(0,e.createComponentVNode)(2,o.Box,{color:"label",children:"No comments found."}):M.comments.map(function(O,R){return(0,e.createComponentVNode)(2,o.Box,{children:[(0,e.createComponentVNode)(2,o.Box,{color:"label",inline:!0,children:O.header}),(0,e.createVNode)(1,"br"),O.text,(0,e.createComponentVNode)(2,o.Button,{icon:"comment-slash",color:"bad",ml:"0.5rem",onClick:function(){function F(){return P("del_comment",{del_comment:R+1})}return F}()})]},R)})})})},f=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.virus,O=(0,t.useLocalState)(x,"searchText",""),R=O[0],F=O[1],W=(0,t.useLocalState)(x,"sortId2","name"),U=W[0],z=W[1],$=(0,t.useLocalState)(x,"sortOrder2",!0),G=$[0],X=$[1];return(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Input,{ml:"0.25rem",fluid:!0,placeholder:"Search by Name, Max Stages, or Severity",onInput:function(){function J(se,ie){return F(ie)}return J}()})}),(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,mt:.5,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,o.Table,{className:"MedicalRecords__list",children:[(0,e.createComponentVNode)(2,o.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,I,{id:"name",children:"Name"}),(0,e.createComponentVNode)(2,I,{id:"max_stages",children:"Max Stages"}),(0,e.createComponentVNode)(2,I,{id:"severity",children:"Severity"})]}),M.filter((0,a.createSearch)(R,function(J){return J.name+"|"+J.max_stages+"|"+J.severity})).sort(function(J,se){var ie=G?1:-1;return J[U].localeCompare(se[U])*ie}).map(function(J){return(0,e.createComponentVNode)(2,o.Table.Row,{className:"MedicalRecords__listVirus--"+J.severity,onClick:function(){function se(){return P("vir",{vir:J.D})}return se}(),children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"virus"})," ",J.name]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:J.max_stages}),(0,e.createComponentVNode)(2,o.Table.Cell,{color:h[J.severity],children:J.severity})]},J.id)})]})})})})],4)},N=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.goals;return(0,e.createComponentVNode)(2,o.Section,{title:"Virology Goals",fill:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:M.length!==0&&M.map(function(O){return(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{title:O.name,children:[(0,e.createComponentVNode)(2,o.Table,{children:(0,e.createComponentVNode)(2,o.Table.Row,{header:!0,children:(0,e.createComponentVNode)(2,o.Table.Cell,{textAlign:"center",children:(0,e.createComponentVNode)(2,o.ProgressBar,{value:O.delivered,minValue:0,maxValue:O.deliverygoal,ranges:{good:[O.deliverygoal*.5,1/0],average:[O.deliverygoal*.25,O.deliverygoal*.5],bad:[-1/0,O.deliverygoal*.25]},children:[O.delivered," / ",O.deliverygoal," Units"]})})})}),(0,e.createComponentVNode)(2,o.Box,{children:O.report})]})},O.id)})||(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Box,{textAlign:"center",children:"No Goals Detected"})})})})},V=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.medbots;return M.length===0?(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,color:"bad",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{bold:!0,grow:!0,textAlign:"center",fontSize:1.75,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,o.Icon.Stack,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"robot",size:5,color:"gray"}),(0,e.createComponentVNode)(2,o.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"There are no Medibots."]})})})}):(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,o.Table,{className:"MedicalRecords__list",children:[(0,e.createComponentVNode)(2,o.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Name"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Area"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Status"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Chemicals"})]}),M.map(function(O){return(0,e.createComponentVNode)(2,o.Table.Row,{className:"MedicalRecords__listMedbot--"+O.on,children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"medical"})," ",O.name]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:[O.area||"Unknown"," (",O.x,", ",O.y,")"]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:O.on?(0,e.createComponentVNode)(2,o.Box,{color:"good",children:"Online"}):(0,e.createComponentVNode)(2,o.Box,{color:"average",children:"Offline"})}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:O.use_beaker?"Reservoir: "+O.total_volume+"/"+O.maximum_volume:"Using internal synthesizer"})]},O.id)})]})})})},B=function(A,x){var E=(0,t.useLocalState)(x,"sortId","name"),P=E[0],D=E[1],M=(0,t.useLocalState)(x,"sortOrder",!0),O=M[0],R=M[1],F=A.id,W=A.children;return(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{fluid:!0,color:P!==F&&"transparent",onClick:function(){function U(){P===F?R(!O):(D(F),R(!0))}return U}(),children:[W,P===F&&(0,e.createComponentVNode)(2,o.Icon,{name:O?"sort-up":"sort-down",ml:"0.25rem;"})]})})},I=function(A,x){var E=(0,t.useLocalState)(x,"sortId2","name"),P=E[0],D=E[1],M=(0,t.useLocalState)(x,"sortOrder2",!0),O=M[0],R=M[1],F=A.id,W=A.children;return(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{fluid:!0,color:P!==F&&"transparent",onClick:function(){function U(){P===F?R(!O):(D(F),R(!0))}return U}(),children:[W,P===F&&(0,e.createComponentVNode)(2,o.Icon,{name:O?"sort-up":"sort-down",ml:"0.25rem;"})]})})},L=function(A,x){var E=(0,t.useBackend)(x),P=E.act,D=E.data,M=D.screen,O=D.general;return(0,e.createComponentVNode)(2,o.Stack.Item,{m:0,children:(0,e.createComponentVNode)(2,o.Tabs,{children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"list",selected:M===2,onClick:function(){function R(){P("screen",{screen:2})}return R}(),children:"List Records"}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"database",selected:M===5,onClick:function(){function R(){P("screen",{screen:5})}return R}(),children:"Virus Database"}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"vial",selected:M===6,onClick:function(){function R(){P("screen",{screen:6})}return R}(),children:"Virology Goals"}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"plus-square",selected:M===7,onClick:function(){function R(){return P("screen",{screen:7})}return R}(),children:"Medibot Tracking"}),M===3&&(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"wrench",selected:M===3,children:"Record Maintenance"}),M===4&&O&&!O.empty&&(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"file",selected:M===4,children:["Record: ",O.fields[0].value]})]})})};(0,p.modalRegisterBodyOverride)("virus",m)},54989:function(T,r,n){"use strict";r.__esModule=!0,r.MerchVendor=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=h.product,s=h.productImage,d=h.productCategory,v=l.user_money;return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,children:(0,e.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+s,style:{"vertical-align":"middle",width:"32px",margin:"0px","margin-left":"0px"}})}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:u.name}),(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{disabled:u.price>v,icon:"shopping-cart",content:u.price,textAlign:"left",onClick:function(){function g(){return m("purchase",{name:u.name,category:d})}return g}()})})]})},b=function(h,i){var c=(0,a.useBackend)(i),m=c.data,l=(0,a.useLocalState)(i,"tabIndex",1),u=l[0],s=m.products,d=m.imagelist,v=["apparel","toy","decoration"];return(0,e.createComponentVNode)(2,t.Table,{children:s[v[u]].map(function(g){return(0,e.createComponentVNode)(2,p,{product:g,productImage:d[g.path],productCategory:v[u]},g.name)})})},y=r.MerchVendor=function(){function k(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.user_cash,s=l.inserted_cash;return(0,e.createComponentVNode)(2,o.Window,{title:"Merch Computer",width:450,height:600,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"User",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{color:"light-grey",inline:!0,mr:"0.5rem",children:["There is ",(0,e.createVNode)(1,"b",null,s,0)," credits inserted."]}),(0,e.createComponentVNode)(2,t.Button,{disabled:!s,icon:"money-bill-wave-alt",content:"Dispense Change",textAlign:"left",onClick:function(){function d(){return m("change")}return d}()})],4),children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:["Doing your job and not getting any recognition at work? Well, welcome to the merch shop! Here, you can buy cool things in exchange for money you earn when you have completed your Job Objectives.",u!==null&&(0,e.createComponentVNode)(2,t.Box,{mt:"0.5rem",children:["Your balance is ",(0,e.createVNode)(1,"b",null,[u||0,(0,e.createTextVNode)(" credits")],0),"."]})]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Products",children:[(0,e.createComponentVNode)(2,S),(0,e.createComponentVNode)(2,b)]})})]})})})}return k}(),S=function(h,i){var c=(0,a.useBackend)(i),m=c.data,l=(0,a.useLocalState)(i,"tabIndex",1),u=l[0],s=l[1],d=m.login_state;return(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"dice",selected:u===1,onClick:function(){function v(){return s(1)}return v}(),children:"Toys"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"flag",selected:u===2,onClick:function(){function v(){return s(2)}return v}(),children:"Decorations"})]})}},87684:function(T,r,n){"use strict";r.__esModule=!0,r.MiningVendor=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),p=n(98595),b=["title","items","gridLayout"];function y(l,u){if(l==null)return{};var s={};for(var d in l)if({}.hasOwnProperty.call(l,d)){if(u.includes(d))continue;s[d]=l[d]}return s}var S={Alphabetical:function(){function l(u,s){return u-s}return l}(),Availability:function(){function l(u,s){return-(u.affordable-s.affordable)}return l}(),Price:function(){function l(u,s){return u.price-s.price}return l}()},k=r.MiningVendor=function(){function l(u,s){var d=(0,t.useLocalState)(s,"gridLayout",!1),v=d[0],g=d[1];return(0,e.createComponentVNode)(2,p.Window,{width:400,height:525,children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,h),(0,e.createComponentVNode)(2,c,{gridLayout:v,setGridLayout:g}),(0,e.createComponentVNode)(2,i,{gridLayout:v})]})})})}return l}(),h=function(u,s){var d=(0,t.useBackend)(s),v=d.act,g=d.data,C=g.has_id,f=g.id;return(0,e.createComponentVNode)(2,o.NoticeBox,{success:C,children:C?(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Box,{inline:!0,verticalAlign:"middle",style:{float:"left"},children:["Logged in as ",f.name,".",(0,e.createVNode)(1,"br"),"You have ",f.points.toLocaleString("en-US")," points."]}),(0,e.createComponentVNode)(2,o.Button,{icon:"eject",content:"Eject ID",style:{float:"right"},onClick:function(){function N(){return v("logoff")}return N}()}),(0,e.createComponentVNode)(2,o.Box,{style:{clear:"both"}})],4):"Please insert an ID in order to make purchases."})},i=function(u,s){var d=(0,t.useBackend)(s),v=d.act,g=d.data,C=g.has_id,f=g.id,N=g.items,V=u.gridLayout,B=(0,t.useLocalState)(s,"search",""),I=B[0],L=B[1],w=(0,t.useLocalState)(s,"sort","Alphabetical"),A=w[0],x=w[1],E=(0,t.useLocalState)(s,"descending",!1),P=E[0],D=E[1],M=(0,a.createSearch)(I,function(F){return F[0]}),O=!1,R=Object.entries(N).map(function(F,W){var U=Object.entries(F[1]).filter(M).map(function(z){return z[1].affordable=C&&f.points>=z[1].price,z[1]}).sort(S[A]);if(U.length!==0)return P&&(U=U.reverse()),O=!0,(0,e.createComponentVNode)(2,m,{title:F[0],items:U,gridLayout:V},F[0])});return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,mt:.5,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,children:O?R:(0,e.createComponentVNode)(2,o.Box,{color:"label",children:"No items matching your criteria was found!"})})})},c=function(u,s){var d=u.gridLayout,v=u.setGridLayout,g=(0,t.useLocalState)(s,"search",""),C=g[0],f=g[1],N=(0,t.useLocalState)(s,"sort",""),V=N[0],B=N[1],I=(0,t.useLocalState)(s,"descending",!1),L=I[0],w=I[1];return(0,e.createComponentVNode)(2,o.Box,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Input,{mt:.2,placeholder:"Search by item name..",width:"100%",onInput:function(){function A(x,E){return f(E)}return A}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{icon:d?"list":"table-cells-large",height:1.75,tooltip:d?"Toggle List Layout":"Toggle Grid Layout",tooltipPosition:"bottom-start",onClick:function(){function A(){return v(!d)}return A}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"30%",children:(0,e.createComponentVNode)(2,o.Dropdown,{selected:"Alphabetical",options:Object.keys(S),width:"100%",onSelected:function(){function A(x){return B(x)}return A}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{icon:L?"arrow-down":"arrow-up",height:1.75,tooltip:L?"Descending order":"Ascending order",tooltipPosition:"bottom-start",onClick:function(){function A(){return w(!L)}return A}()})})]})})},m=function(u,s){var d=(0,t.useBackend)(s),v=d.act,g=d.data,C=u.title,f=u.items,N=u.gridLayout,V=y(u,b);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Collapsible,Object.assign({open:!0,title:C},V,{children:f.map(function(B){return N?(0,e.createComponentVNode)(2,o.ImageButton,{mb:.5,imageSize:57.5,dmIcon:B.icon,dmIconState:B.icon_state,disabled:!g.has_id||g.id.points0&&(0,e.createComponentVNode)(2,o.Box,{className:"Newscaster__menuButton--unread",children:ae>=10?"9+":ae})}),(0,e.createComponentVNode)(2,s,{icon:"briefcase",title:"Job Openings",selected:R===1,onClick:function(){function le(){return x("jobs")}return le}()}),(0,e.createComponentVNode)(2,o.Divider)]}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:F.map(function(le){return(0,e.createComponentVNode)(2,s,{icon:le.icon,title:le.name,selected:R===2&&F[U-1]===le,onClick:function(){function Z(){return x("channel",{uid:le.uid})}return Z}(),children:le.unread>0&&(0,e.createComponentVNode)(2,o.Box,{className:"Newscaster__menuButton--unread",children:le.unread>=10?"9+":le.unread})},le)})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:[(0,e.createComponentVNode)(2,o.Divider),(!!P||!!D)&&(0,e.createFragment)([(0,e.createComponentVNode)(2,s,{security:!0,icon:"exclamation-circle",title:"Edit Wanted Notice",mb:"0.5rem",onClick:function(){function le(){return(0,y.modalOpen)(w,"wanted_notice")}return le}()}),(0,e.createComponentVNode)(2,s,{security:!0,icon:me?"minus-square":"minus-square-o",title:"Censor Mode: "+(me?"On":"Off"),mb:"0.5rem",onClick:function(){function le(){return q(!me)}return le}()}),(0,e.createComponentVNode)(2,o.Divider)],4),(0,e.createComponentVNode)(2,s,{icon:"pen-alt",title:"New Story",mb:"0.5rem",onClick:function(){function le(){return(0,y.modalOpen)(w,"create_story")}return le}()}),(0,e.createComponentVNode)(2,s,{icon:"plus-circle",title:"New Channel",onClick:function(){function le(){return(0,y.modalOpen)(w,"create_channel")}return le}()}),(0,e.createComponentVNode)(2,o.Divider),(0,e.createComponentVNode)(2,s,{icon:O?"spinner":"print",iconSpin:O,title:O?"Printing...":"Print Newspaper",onClick:function(){function le(){return x("print_newspaper")}return le}()}),(0,e.createComponentVNode)(2,s,{icon:M?"volume-mute":"volume-up",title:"Mute: "+(M?"On":"Off"),onClick:function(){function le(){return x("toggle_mute")}return le}()})]})]})}),(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,width:"100%",children:[(0,e.createComponentVNode)(2,S.TemporaryNotice),re]})]})})]})}return I}(),s=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=L.icon,P=E===void 0?"":E,D=L.iconSpin,M=L.selected,O=M===void 0?!1:M,R=L.security,F=R===void 0?!1:R,W=L.onClick,U=L.title,z=L.children,$=i(L,k);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Box,Object.assign({className:(0,a.classes)(["Newscaster__menuButton",O&&"Newscaster__menuButton--selected",F&&"Newscaster__menuButton--security"]),onClick:W},$,{children:[O&&(0,e.createComponentVNode)(2,o.Box,{className:"Newscaster__menuButton--selectedBar"}),(0,e.createComponentVNode)(2,o.Icon,{name:P,spin:D,size:"2"}),(0,e.createComponentVNode)(2,o.Box,{className:"Newscaster__menuButton--title",children:U}),z]})))},d=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=A.data,P=E.screen,D=E.is_admin,M=E.channel_idx,O=E.channel_can_manage,R=E.channels,F=E.stories,W=E.wanted,U=(0,t.useLocalState)(w,"fullStories",[]),z=U[0],$=U[1],G=(0,t.useLocalState)(w,"censorMode",!1),X=G[0],J=G[1],se=P===2&&M>-1?R[M-1]:null;return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[!!W&&(0,e.createComponentVNode)(2,g,{story:W,wanted:!0}),(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Icon,{name:se?se.icon:"newspaper",mr:"0.5rem"}),se?se.name:"Headlines"],0),children:F.length>0?F.slice().reverse().map(function(ie){return!z.includes(ie.uid)&&ie.body.length+3>c?Object.assign({},ie,{body_short:ie.body.substr(0,c-4)+"..."}):ie}).map(function(ie,me){return(0,e.createComponentVNode)(2,g,{story:ie},me)}):(0,e.createComponentVNode)(2,o.Box,{className:"Newscaster__emptyNotice",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"times",size:"3"}),(0,e.createVNode)(1,"br"),"There are no stories at this time."]})}),!!se&&(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,height:"40%",title:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Icon,{name:"info-circle",mr:"0.5rem"}),(0,e.createTextVNode)("About")],4),buttons:(0,e.createFragment)([X&&(0,e.createComponentVNode)(2,o.Button,{disabled:!!se.admin&&!D,selected:se.censored,icon:se.censored?"comment-slash":"comment",content:se.censored?"Uncensor Channel":"Censor Channel",mr:"0.5rem",onClick:function(){function ie(){return x("censor_channel",{uid:se.uid})}return ie}()}),(0,e.createComponentVNode)(2,o.Button,{disabled:!O,icon:"cog",content:"Manage",onClick:function(){function ie(){return(0,y.modalOpen)(w,"manage_channel",{uid:se.uid})}return ie}()})],0),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Description",children:se.description||"N/A"}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Owner",children:se.author||"N/A"}),!!D&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Ckey",children:se.author_ckey}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Public",children:se.public?"Yes":"No"}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Total Views",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"eye",mr:"0.5rem"}),F.reduce(function(ie,me){return ie+me.view_count},0).toLocaleString()]})]})})]})},v=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=A.data,P=E.jobs,D=E.wanted,M=Object.entries(P).reduce(function(O,R){var F=R[0],W=R[1];return O+W.length},0);return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[!!D&&(0,e.createComponentVNode)(2,g,{story:D,wanted:!0}),(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Icon,{name:"briefcase",mr:"0.5rem"}),(0,e.createTextVNode)("Job Openings")],4),buttons:(0,e.createComponentVNode)(2,o.Box,{mt:"0.25rem",color:"label",children:"Work for a better future at Nanotrasen"}),children:M>0?m.map(function(O){return Object.assign({},l[O],{id:O,jobs:P[O]})}).filter(function(O){return!!O&&O.jobs.length>0}).map(function(O){return(0,e.createComponentVNode)(2,o.Section,{className:(0,a.classes)(["Newscaster__jobCategory","Newscaster__jobCategory--"+O.id]),title:O.title,buttons:(0,e.createComponentVNode)(2,o.Box,{mt:"0.25rem",color:"label",children:O.fluff_text}),children:O.jobs.map(function(R){return(0,e.createComponentVNode)(2,o.Box,{class:(0,a.classes)(["Newscaster__jobOpening",!!R.is_command&&"Newscaster__jobOpening--command"]),children:["\u2022 ",R.title]},R.title)})},O.id)}):(0,e.createComponentVNode)(2,o.Box,{className:"Newscaster__emptyNotice",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"times",size:"3"}),(0,e.createVNode)(1,"br"),"There are no openings at this time."]})}),(0,e.createComponentVNode)(2,o.Section,{height:"17%",children:["Interested in serving Nanotrasen?",(0,e.createVNode)(1,"br"),"Sign up for any of the above position now at the ",(0,e.createVNode)(1,"b",null,"Head of Personnel's Office!",16),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.Box,{as:"small",color:"label",children:"By signing up for a job at Nanotrasen, you agree to transfer your soul to the loyalty department of the omnipresent and helpful watcher of humanity."})]})]})},g=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=A.data,P=L.story,D=L.wanted,M=D===void 0?!1:D,O=E.is_admin,R=(0,t.useLocalState)(w,"fullStories",[]),F=R[0],W=R[1],U=(0,t.useLocalState)(w,"censorMode",!1),z=U[0],$=U[1];return(0,e.createComponentVNode)(2,o.Section,{className:(0,a.classes)(["Newscaster__story",M&&"Newscaster__story--wanted"]),title:(0,e.createFragment)([M&&(0,e.createComponentVNode)(2,o.Icon,{name:"exclamation-circle",mr:"0.5rem"}),P.censor_flags&2&&"[REDACTED]"||P.title||"News from "+P.author],0),buttons:(0,e.createComponentVNode)(2,o.Box,{mt:"0.25rem",children:(0,e.createComponentVNode)(2,o.Box,{color:"label",children:[!M&&z&&(0,e.createComponentVNode)(2,o.Box,{inline:!0,children:(0,e.createComponentVNode)(2,o.Button,{enabled:P.censor_flags&2,icon:P.censor_flags&2?"comment-slash":"comment",content:P.censor_flags&2?"Uncensor":"Censor",mr:"0.5rem",mt:"-0.25rem",onClick:function(){function G(){return x("censor_story",{uid:P.uid})}return G}()})}),(0,e.createComponentVNode)(2,o.Box,{inline:!0,children:[(0,e.createComponentVNode)(2,o.Icon,{name:"user"})," ",P.author," |\xA0",!!O&&(0,e.createFragment)([(0,e.createTextVNode)("ckey: "),P.author_ckey,(0,e.createTextVNode)(" |\xA0")],0),!M&&(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Icon,{name:"eye"}),(0,e.createTextVNode)(" "),P.view_count.toLocaleString(),(0,e.createTextVNode)(" |\xA0")],0),(0,e.createComponentVNode)(2,o.Icon,{name:"clock"})," ",(0,p.timeAgo)(P.publish_time,E.world_time)]})]})}),children:(0,e.createComponentVNode)(2,o.Box,{children:P.censor_flags&2?"[REDACTED]":(0,e.createFragment)([!!P.has_photo&&(0,e.createComponentVNode)(2,C,{name:"story_photo_"+P.uid+".png",float:"right",ml:"0.5rem"}),(P.body_short||P.body).split("\n").map(function(G,X){return(0,e.createComponentVNode)(2,o.Box,{children:G||(0,e.createVNode)(1,"br")},X)}),P.body_short&&(0,e.createComponentVNode)(2,o.Button,{content:"Read more..",mt:"0.5rem",onClick:function(){function G(){return W([].concat(F,[P.uid]))}return G}()}),(0,e.createComponentVNode)(2,o.Box,{clear:"right"})],0)})})},C=function(L,w){var A=L.name,x=i(L,h),E=(0,t.useLocalState)(w,"viewingPhoto",""),P=E[0],D=E[1];return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Box,Object.assign({as:"img",className:"Newscaster__photo",src:A,onClick:function(){function M(){return D(A)}return M}()},x)))},f=function(L,w){var A=(0,t.useLocalState)(w,"viewingPhoto",""),x=A[0],E=A[1];return(0,e.createComponentVNode)(2,o.Modal,{className:"Newscaster__photoZoom",children:[(0,e.createComponentVNode)(2,o.Box,{as:"img",src:x}),(0,e.createComponentVNode)(2,o.Button,{icon:"times",content:"Close",color:"grey",mt:"1rem",onClick:function(){function P(){return E("")}return P}()})]})},N=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=A.data,P=!!L.args.uid&&E.channels.filter(function(te){return te.uid===L.args.uid}).pop();if(L.id==="manage_channel"&&!P){(0,y.modalClose)(w);return}var D=L.id==="manage_channel",M=!!L.args.is_admin,O=L.args.scanned_user,R=(0,t.useLocalState)(w,"author",(P==null?void 0:P.author)||O||"Unknown"),F=R[0],W=R[1],U=(0,t.useLocalState)(w,"name",(P==null?void 0:P.name)||""),z=U[0],$=U[1],G=(0,t.useLocalState)(w,"description",(P==null?void 0:P.description)||""),X=G[0],J=G[1],se=(0,t.useLocalState)(w,"icon",(P==null?void 0:P.icon)||"newspaper"),ie=se[0],me=se[1],q=(0,t.useLocalState)(w,"isPublic",D?!!(P!=null&&P.public):!1),re=q[0],ae=q[1],le=(0,t.useLocalState)(w,"adminLocked",(P==null?void 0:P.admin)===1||!1),Z=le[0],ne=le[1];return(0,e.createComponentVNode)(2,o.Section,{m:"-1rem",pb:"1.5rem",title:D?"Manage "+P.name:"Create New Channel",children:[(0,e.createComponentVNode)(2,o.Box,{mx:"0.5rem",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Owner",children:(0,e.createComponentVNode)(2,o.Input,{disabled:!M,width:"100%",value:F,onInput:function(){function te(fe,pe){return W(pe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Name",children:(0,e.createComponentVNode)(2,o.Input,{width:"100%",placeholder:"50 characters max.",maxLength:"50",value:z,onInput:function(){function te(fe,pe){return $(pe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Description (optional)",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Input,{multiline:!0,width:"100%",placeholder:"128 characters max.",maxLength:"128",value:X,onInput:function(){function te(fe,pe){return J(pe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Icon",children:[(0,e.createComponentVNode)(2,o.Input,{disabled:!M,value:ie,width:"35%",mr:"0.5rem",onInput:function(){function te(fe,pe){return me(pe)}return te}()}),(0,e.createComponentVNode)(2,o.Icon,{name:ie,size:"2",verticalAlign:"middle",mr:"0.5rem"})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Accept Public Stories?",children:(0,e.createComponentVNode)(2,o.Button,{selected:re,icon:re?"toggle-on":"toggle-off",content:re?"Yes":"No",onClick:function(){function te(){return ae(!re)}return te}()})}),M&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"CentComm Lock",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Button,{selected:Z,icon:Z?"lock":"lock-open",content:Z?"On":"Off",tooltip:"Locking this channel will make it editable by nobody but CentComm officers.",tooltipPosition:"top",onClick:function(){function te(){return ne(!Z)}return te}()})})]})}),(0,e.createComponentVNode)(2,o.Button.Confirm,{disabled:F.trim().length===0||z.trim().length===0,icon:"check",color:"good",content:"Submit",position:"absolute",right:"1rem",bottom:"-0.75rem",onClick:function(){function te(){(0,y.modalAnswer)(w,L.id,"",{author:F,name:z.substr(0,49),description:X.substr(0,128),icon:ie,public:re?1:0,admin_locked:Z?1:0})}return te}()})]})},V=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=A.data,P=E.photo,D=E.channels,M=E.channel_idx,O=M===void 0?-1:M,R=!!L.args.is_admin,F=L.args.scanned_user,W=D.slice().sort(function(te,fe){if(O<0)return 0;var pe=D[O-1];if(pe.uid===te.uid)return-1;if(pe.uid===fe.uid)return 1}).filter(function(te){return R||!te.frozen&&(te.author===F||!!te.public)}),U=(0,t.useLocalState)(w,"author",F||"Unknown"),z=U[0],$=U[1],G=(0,t.useLocalState)(w,"channel",W.length>0?W[0].name:""),X=G[0],J=G[1],se=(0,t.useLocalState)(w,"title",""),ie=se[0],me=se[1],q=(0,t.useLocalState)(w,"body",""),re=q[0],ae=q[1],le=(0,t.useLocalState)(w,"adminLocked",!1),Z=le[0],ne=le[1];return(0,e.createComponentVNode)(2,o.Section,{m:"-1rem",pb:"1.5rem",title:"Create New Story",children:[(0,e.createComponentVNode)(2,o.Box,{mx:"0.5rem",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Author",children:(0,e.createComponentVNode)(2,o.Input,{disabled:!R,width:"100%",value:z,onInput:function(){function te(fe,pe){return $(pe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Channel",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Dropdown,{selected:X,options:W.map(function(te){return te.name}),mb:"0",width:"100%",onSelected:function(){function te(fe){return J(fe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Divider),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Title",children:(0,e.createComponentVNode)(2,o.Input,{width:"100%",placeholder:"128 characters max.",maxLength:"128",value:ie,onInput:function(){function te(fe,pe){return me(pe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Story Text",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Input,{fluid:!0,multiline:!0,placeholder:"1024 characters max.",maxLength:"1024",rows:"8",width:"100%",value:re,onInput:function(){function te(fe,pe){return ae(pe)}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Photo (optional)",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Button,{icon:"image",selected:P,content:P?"Eject: "+P.name:"Insert Photo",tooltip:!P&&"Attach a photo to this story by holding the photograph in your hand.",onClick:function(){function te(){return x(P?"eject_photo":"attach_photo")}return te}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Preview",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Section,{noTopPadding:!0,title:ie,maxHeight:"13.5rem",overflow:"auto",children:(0,e.createComponentVNode)(2,o.Box,{mt:"0.5rem",children:[!!P&&(0,e.createComponentVNode)(2,C,{name:"inserted_photo_"+P.uid+".png",float:"right"}),re.split("\n").map(function(te,fe){return(0,e.createComponentVNode)(2,o.Box,{children:te||(0,e.createVNode)(1,"br")},fe)}),(0,e.createComponentVNode)(2,o.Box,{clear:"right"})]})})}),R&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"CentComm Lock",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Button,{selected:Z,icon:Z?"lock":"lock-open",content:Z?"On":"Off",tooltip:"Locking this story will make it censorable by nobody but CentComm officers.",tooltipPosition:"top",onClick:function(){function te(){return ne(!Z)}return te}()})})]})}),(0,e.createComponentVNode)(2,o.Button.Confirm,{disabled:z.trim().length===0||X.trim().length===0||ie.trim().length===0||re.trim().length===0,icon:"check",color:"good",content:"Submit",position:"absolute",right:"1rem",bottom:"-0.75rem",onClick:function(){function te(){(0,y.modalAnswer)(w,"create_story","",{author:z,channel:X,title:ie.substr(0,127),body:re.substr(0,1023),admin_locked:Z?1:0})}return te}()})]})},B=function(L,w){var A=(0,t.useBackend)(w),x=A.act,E=A.data,P=E.photo,D=E.wanted,M=!!L.args.is_admin,O=L.args.scanned_user,R=(0,t.useLocalState)(w,"author",(D==null?void 0:D.author)||O||"Unknown"),F=R[0],W=R[1],U=(0,t.useLocalState)(w,"name",(D==null?void 0:D.title.substr(8))||""),z=U[0],$=U[1],G=(0,t.useLocalState)(w,"description",(D==null?void 0:D.body)||""),X=G[0],J=G[1],se=(0,t.useLocalState)(w,"adminLocked",(D==null?void 0:D.admin_locked)===1||!1),ie=se[0],me=se[1];return(0,e.createComponentVNode)(2,o.Section,{m:"-1rem",pb:"1.5rem",title:"Manage Wanted Notice",children:[(0,e.createComponentVNode)(2,o.Box,{mx:"0.5rem",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Authority",children:(0,e.createComponentVNode)(2,o.Input,{disabled:!M,width:"100%",value:F,onInput:function(){function q(re,ae){return W(ae)}return q}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Name",children:(0,e.createComponentVNode)(2,o.Input,{width:"100%",value:z,maxLength:"128",onInput:function(){function q(re,ae){return $(ae)}return q}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Description",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Input,{multiline:!0,width:"100%",value:X,maxLength:"512",rows:"4",onInput:function(){function q(re,ae){return J(ae)}return q}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Photo (optional)",verticalAlign:"top",children:[(0,e.createComponentVNode)(2,o.Button,{icon:"image",selected:P,content:P?"Eject: "+P.name:"Insert Photo",tooltip:!P&&"Attach a photo to this wanted notice by holding the photograph in your hand.",tooltipPosition:"top",onClick:function(){function q(){return x(P?"eject_photo":"attach_photo")}return q}()}),!!P&&(0,e.createComponentVNode)(2,C,{name:"inserted_photo_"+P.uid+".png",float:"right"})]}),M&&(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"CentComm Lock",verticalAlign:"top",children:(0,e.createComponentVNode)(2,o.Button,{selected:ie,icon:ie?"lock":"lock-open",content:ie?"On":"Off",tooltip:"Locking this wanted notice will make it editable by nobody but CentComm officers.",tooltipPosition:"top",onClick:function(){function q(){return me(!ie)}return q}()})})]})}),(0,e.createComponentVNode)(2,o.Button.Confirm,{disabled:!D,icon:"eraser",color:"danger",content:"Clear",position:"absolute",right:"7.25rem",bottom:"-0.75rem",onClick:function(){function q(){x("clear_wanted_notice"),(0,y.modalClose)(w)}return q}()}),(0,e.createComponentVNode)(2,o.Button.Confirm,{disabled:F.trim().length===0||z.trim().length===0||X.trim().length===0,icon:"check",color:"good",content:"Submit",position:"absolute",right:"1rem",bottom:"-0.75rem",onClick:function(){function q(){(0,y.modalAnswer)(w,L.id,"",{author:F,name:z.substr(0,127),description:X.substr(0,511),admin_locked:ie?1:0})}return q}()})]})};(0,y.modalRegisterBodyOverride)("create_channel",N),(0,y.modalRegisterBodyOverride)("manage_channel",N),(0,y.modalRegisterBodyOverride)("create_story",V),(0,y.modalRegisterBodyOverride)("wanted_notice",B)},48286:function(T,r,n){"use strict";r.__esModule=!0,r.Noticeboard=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),p=n(98595),b=r.Noticeboard=function(){function y(S,k){var h=(0,t.useBackend)(k),i=h.act,c=h.data,m=c.papers;return(0,e.createComponentVNode)(2,p.Window,{width:600,height:300,theme:"noticeboard",children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:m.map(function(l){return(0,e.createComponentVNode)(2,o.Stack.Item,{align:"center",width:"22.45%",height:"85%",onClick:function(){function u(){return i("interact",{paper:l.ref})}return u}(),onContextMenu:function(){function u(s){s.preventDefault(),i("showFull",{paper:l.ref})}return u}(),children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,fontSize:.75,title:l.name,children:(0,a.decodeHtmlEntities)(l.contents)})},l.ref)})})})})}return y}()},41166:function(T,r,n){"use strict";r.__esModule=!0,r.NuclearBomb=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.NuclearBomb=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data;return i.extended?(0,e.createComponentVNode)(2,o.Window,{width:350,height:290,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Authorization",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Auth Disk",children:(0,e.createComponentVNode)(2,t.Button,{icon:i.authdisk?"eject":"id-card",selected:i.authdisk,content:i.diskname?i.diskname:"-----",tooltip:i.authdisk?"Eject Disk":"Insert Disk",onClick:function(){function c(){return h("auth")}return c}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Auth Code",children:(0,e.createComponentVNode)(2,t.Button,{icon:"key",disabled:!i.authdisk,selected:i.authcode,content:i.codemsg,onClick:function(){function c(){return h("code")}return c}()})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Arming & Disarming",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Bolted to floor",children:(0,e.createComponentVNode)(2,t.Button,{icon:i.anchored?"check":"times",selected:i.anchored,disabled:!i.authdisk,content:i.anchored?"YES":"NO",onClick:function(){function c(){return h("toggle_anchor")}return c}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Time Left",children:(0,e.createComponentVNode)(2,t.Button,{icon:"stopwatch",content:i.time,disabled:!i.authfull,tooltip:"Set Timer",onClick:function(){function c(){return h("set_time")}return c}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Safety",children:(0,e.createComponentVNode)(2,t.Button,{icon:i.safety?"check":"times",selected:i.safety,disabled:!i.authfull,content:i.safety?"ON":"OFF",tooltip:i.safety?"Disable Safety":"Enable Safety",onClick:function(){function c(){return h("toggle_safety")}return c}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Arm/Disarm",children:(0,e.createComponentVNode)(2,t.Button,{icon:(i.timer,"bomb"),disabled:i.safety||!i.authfull,color:"red",content:i.timer?"DISARM THE NUKE":"ARM THE NUKE",onClick:function(){function c(){return h("toggle_armed")}return c}()})})]})})]})}):(0,e.createComponentVNode)(2,o.Window,{width:350,height:115,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Deployment",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"exclamation-triangle",content:"Deploy Nuclear Device (will bolt device to floor)",onClick:function(){function c(){return h("deploy")}return c}()})})})})}return b}()},52416:function(T,r,n){"use strict";r.__esModule=!0,r.NumberInputModal=void 0;var e=n(89005),a=n(51057),t=n(19203),o=n(92986),p=n(72253),b=n(36036),y=n(98595),S=r.NumberInputModal=function(){function h(i,c){var m=(0,p.useBackend)(c),l=m.act,u=m.data,s=u.init_value,d=u.large_buttons,v=u.message,g=v===void 0?"":v,C=u.timeout,f=u.title,N=(0,p.useLocalState)(c,"input",s),V=N[0],B=N[1],I=function(){function A(x){x!==V&&B(x)}return A}(),L=function(){function A(x){x!==V&&B(x)}return A}(),w=140+Math.max(Math.ceil(g.length/3),g.length>0&&d?5:0);return(0,e.createComponentVNode)(2,y.Window,{title:f,width:270,height:w,children:[C&&(0,e.createComponentVNode)(2,a.Loader,{value:C}),(0,e.createComponentVNode)(2,y.Window.Content,{onKeyDown:function(){function A(x){var E=window.event?x.which:x.keyCode;E===o.KEY_ENTER&&l("submit",{entry:V}),E===o.KEY_ESCAPE&&l("cancel")}return A}(),children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,children:(0,e.createComponentVNode)(2,b.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.Box,{color:"label",children:g})}),(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,k,{input:V,onClick:L,onChange:I})}),(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,t.InputButtons,{input:V})})]})})})]})}return h}(),k=function(i,c){var m=(0,p.useBackend)(c),l=m.act,u=m.data,s=u.min_value,d=u.max_value,v=u.init_value,g=u.round_value,C=i.input,f=i.onClick,N=i.onChange,V=Math.round(C!==s?Math.max(C/2,s):d/2),B=C===s&&s>0||C===1;return(0,e.createComponentVNode)(2,b.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Button,{disabled:C===s,icon:"angle-double-left",onClick:function(){function I(){return f(s)}return I}(),tooltip:C===s?"Min":"Min ("+s+")"})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.RestrictedInput,{autoFocus:!0,autoSelect:!0,fluid:!0,allowFloats:!g,minValue:s,maxValue:d,onChange:function(){function I(L,w){return N(w)}return I}(),onEnter:function(){function I(L,w){return l("submit",{entry:w})}return I}(),value:C})}),(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Button,{disabled:C===d,icon:"angle-double-right",onClick:function(){function I(){return f(d)}return I}(),tooltip:C===d?"Max":"Max ("+d+")"})}),(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Button,{disabled:B,icon:"divide",onClick:function(){function I(){return f(V)}return I}(),tooltip:B?"Split":"Split ("+V+")"})}),(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Button,{disabled:C===v,icon:"redo",onClick:function(){function I(){return f(v)}return I}(),tooltip:v?"Reset ("+v+")":"Reset"})})]})}},1218:function(T,r,n){"use strict";r.__esModule=!0,r.OperatingComputer=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(98595),p=n(36036),b=[["good","Conscious"],["average","Unconscious"],["bad","DEAD"]],y=[["Resp.","oxyLoss"],["Toxin","toxLoss"],["Brute","bruteLoss"],["Burn","fireLoss"]],S={average:[.25,.5],bad:[.5,1/0]},k=["bad","average","average","good","average","average","bad"],h=r.OperatingComputer=function(){function l(u,s){var d=(0,t.useBackend)(s),v=d.act,g=d.data,C=g.hasOccupant,f=g.choice,N;return f?N=(0,e.createComponentVNode)(2,m):N=C?(0,e.createComponentVNode)(2,i):(0,e.createComponentVNode)(2,c),(0,e.createComponentVNode)(2,o.Window,{width:650,height:455,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,p.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Tabs,{children:[(0,e.createComponentVNode)(2,p.Tabs.Tab,{selected:!f,icon:"user",onClick:function(){function V(){return v("choiceOff")}return V}(),children:"Patient"}),(0,e.createComponentVNode)(2,p.Tabs.Tab,{selected:!!f,icon:"cog",onClick:function(){function V(){return v("choiceOn")}return V}(),children:"Options"})]})}),(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,p.Section,{fill:!0,scrollable:!0,children:N})})]})})})}return l}(),i=function(u,s){var d=(0,t.useBackend)(s),v=d.data,g=v.occupant;return(0,e.createComponentVNode)(2,p.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,p.Section,{fill:!0,title:"Patient",children:(0,e.createComponentVNode)(2,p.LabeledList,{children:[(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Name",children:g.name}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Status",color:b[g.stat][0],children:b[g.stat][1]}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Health",children:(0,e.createComponentVNode)(2,p.ProgressBar,{min:"0",max:g.maxHealth,value:g.health/g.maxHealth,ranges:{good:[.5,1/0],average:[0,.5],bad:[-1/0,0]}})}),y.map(function(C,f){return(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:C[0]+" Damage",children:(0,e.createComponentVNode)(2,p.ProgressBar,{min:"0",max:"100",value:g[C[1]]/100,ranges:S,children:(0,a.round)(g[C[1]])},f)},f)}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Temperature",children:(0,e.createComponentVNode)(2,p.ProgressBar,{min:"0",max:g.maxTemp,value:g.bodyTemperature/g.maxTemp,color:k[g.temperatureSuitability+3],children:[(0,a.round)(g.btCelsius),"\xB0C, ",(0,a.round)(g.btFaren),"\xB0F"]})}),!!g.hasBlood&&(0,e.createFragment)([(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Blood Level",children:(0,e.createComponentVNode)(2,p.ProgressBar,{min:"0",max:g.bloodMax,value:g.bloodLevel/g.bloodMax,ranges:{bad:[-1/0,.6],average:[.6,.9],good:[.6,1/0]},children:[g.bloodPercent,"%, ",g.bloodLevel,"cl"]})}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Pulse",children:[g.pulse," BPM"]})],4)]})})}),(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Section,{title:"Current Procedure",level:"2",children:g.inSurgery?(0,e.createComponentVNode)(2,p.LabeledList,{children:[(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Procedure",children:g.surgeryName}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Next Step",children:g.stepName})]}):(0,e.createComponentVNode)(2,p.Box,{color:"label",children:"No procedure ongoing."})})})]})},c=function(){return(0,e.createComponentVNode)(2,p.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,align:"center",textAlign:"center",color:"label",children:[(0,e.createComponentVNode)(2,p.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),"No patient detected."]})})},m=function(u,s){var d=(0,t.useBackend)(s),v=d.act,g=d.data,C=g.verbose,f=g.health,N=g.healthAlarm,V=g.oxy,B=g.oxyAlarm,I=g.crit;return(0,e.createComponentVNode)(2,p.LabeledList,{children:[(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Loudspeaker",children:(0,e.createComponentVNode)(2,p.Button,{selected:C,icon:C?"toggle-on":"toggle-off",content:C?"On":"Off",onClick:function(){function L(){return v(C?"verboseOff":"verboseOn")}return L}()})}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Health Announcer",children:(0,e.createComponentVNode)(2,p.Button,{selected:f,icon:f?"toggle-on":"toggle-off",content:f?"On":"Off",onClick:function(){function L(){return v(f?"healthOff":"healthOn")}return L}()})}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Health Announcer Threshold",children:(0,e.createComponentVNode)(2,p.Knob,{bipolar:!0,minValue:-100,maxValue:100,value:N,stepPixelSize:5,ml:"0",onChange:function(){function L(w,A){return v("health_adj",{new:A})}return L}()})}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Oxygen Alarm",children:(0,e.createComponentVNode)(2,p.Button,{selected:V,icon:V?"toggle-on":"toggle-off",content:V?"On":"Off",onClick:function(){function L(){return v(V?"oxyOff":"oxyOn")}return L}()})}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Oxygen Alarm Threshold",children:(0,e.createComponentVNode)(2,p.Knob,{bipolar:!0,minValue:-100,maxValue:100,value:B,stepPixelSize:5,ml:"0",onChange:function(){function L(w,A){return v("oxy_adj",{new:A})}return L}()})}),(0,e.createComponentVNode)(2,p.LabeledList.Item,{label:"Critical Alert",children:(0,e.createComponentVNode)(2,p.Button,{selected:I,icon:I?"toggle-on":"toggle-off",content:I?"On":"Off",onClick:function(){function L(){return v(I?"critOff":"critOn")}return L}()})})]})}},46892:function(T,r,n){"use strict";r.__esModule=!0,r.Orbit=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),p=n(98595),b=n(35840);function y(d,v){var g=typeof Symbol!="undefined"&&d[Symbol.iterator]||d["@@iterator"];if(g)return(g=g.call(d)).next.bind(g);if(Array.isArray(d)||(g=S(d))||v&&d&&typeof d.length=="number"){g&&(d=g);var C=0;return function(){return C>=d.length?{done:!0}:{done:!1,value:d[C++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function S(d,v){if(d){if(typeof d=="string")return k(d,v);var g={}.toString.call(d).slice(8,-1);return g==="Object"&&d.constructor&&(g=d.constructor.name),g==="Map"||g==="Set"?Array.from(d):g==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(g)?k(d,v):void 0}}function k(d,v){(v==null||v>d.length)&&(v=d.length);for(var g=0,C=Array(v);gg},m=function(v,g){var C=v.name,f=g.name;if(!C||!f)return 0;var N=C.match(h),V=f.match(h);if(N&&V&&C.replace(h,"")===f.replace(h,"")){var B=parseInt(N[1],10),I=parseInt(V[1],10);return B-I}return c(C,f)},l=function(v,g){var C=v.searchText,f=v.source,N=v.title,V=v.color,B=v.sorted,I=f.filter(i(C));return B&&I.sort(m),f.length>0&&(0,e.createComponentVNode)(2,o.Section,{title:N+" - ("+f.length+")",children:I.map(function(L){return(0,e.createComponentVNode)(2,u,{thing:L,color:V},L.name)})})},u=function(v,g){var C=(0,t.useBackend)(g),f=C.act,N=v.color,V=v.thing;return(0,e.createComponentVNode)(2,o.Button,{color:N,tooltip:V.assigned_role?(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Box,{as:"img",mr:"0.5em",className:(0,b.classes)(["job_icons16x16",V.assigned_role_sprite])})," ",V.assigned_role]}):"",tooltipPosition:"bottom",onClick:function(){function B(){return f("orbit",{ref:V.ref})}return B}(),children:[V.name,V.orbiters&&(0,e.createComponentVNode)(2,o.Box,{inline:!0,ml:1,children:["(",V.orbiters," ",(0,e.createComponentVNode)(2,o.Icon,{name:"eye"}),")"]})]})},s=r.Orbit=function(){function d(v,g){for(var C=(0,t.useBackend)(g),f=C.act,N=C.data,V=N.alive,B=N.antagonists,I=N.highlights,L=N.response_teams,w=N.tourist,A=N.auto_observe,x=N.dead,E=N.ssd,P=N.ghosts,D=N.misc,M=N.npcs,O=(0,t.useLocalState)(g,"searchText",""),R=O[0],F=O[1],W={},U=y(B),z;!(z=U()).done;){var $=z.value;W[$.antag]===void 0&&(W[$.antag]=[]),W[$.antag].push($)}var G=Object.entries(W);G.sort(function(J,se){return c(J[0],se[0])});var X=function(){function J(se){for(var ie=0,me=[G.map(function(ae){var le=ae[0],Z=ae[1];return Z}),w,I,V,P,E,x,M,D];ie0&&(0,e.createComponentVNode)(2,o.Section,{title:"Antagonists",children:G.map(function(J){var se=J[0],ie=J[1];return(0,e.createComponentVNode)(2,o.Section,{title:se+" - ("+ie.length+")",level:2,children:ie.filter(i(R)).sort(m).map(function(me){return(0,e.createComponentVNode)(2,u,{color:"bad",thing:me},me.name)})},se)})}),I.length>0&&(0,e.createComponentVNode)(2,l,{title:"Highlights",source:I,searchText:R,color:"teal"}),(0,e.createComponentVNode)(2,l,{title:"Response Teams",source:L,searchText:R,color:"purple"}),(0,e.createComponentVNode)(2,l,{title:"Tourists",source:w,searchText:R,color:"violet"}),(0,e.createComponentVNode)(2,l,{title:"Alive",source:V,searchText:R,color:"good"}),(0,e.createComponentVNode)(2,l,{title:"Ghosts",source:P,searchText:R,color:"grey"}),(0,e.createComponentVNode)(2,l,{title:"SSD",source:E,searchText:R,color:"grey"}),(0,e.createComponentVNode)(2,l,{title:"Dead",source:x,searchText:R,sorted:!1}),(0,e.createComponentVNode)(2,l,{title:"NPCs",source:M,searchText:R,sorted:!1}),(0,e.createComponentVNode)(2,l,{title:"Misc",source:D,searchText:R,sorted:!1})]})})}return d}()},15421:function(T,r,n){"use strict";r.__esModule=!0,r.OreRedemption=void 0;var e=n(89005),a=n(35840),t=n(72253),o=n(36036),p=n(98595),b=n(9394);function y(d){if(d==null)throw new TypeError("Cannot destructure "+d)}var S=(0,b.createLogger)("OreRedemption"),k=function(v){return v.toLocaleString("en-US")+" pts"},h=r.OreRedemption=function(){function d(v,g){return(0,e.createComponentVNode)(2,p.Window,{width:490,height:750,children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,i,{height:"100%"})}),(0,e.createComponentVNode)(2,c),(0,e.createComponentVNode)(2,m)]})})})}return d}(),i=function(v,g){var C=(0,t.useBackend)(g),f=C.act,N=C.data,V=N.id,B=N.points,I=N.disk,L=Object.assign({},(y(v),v));return(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({},L,{children:[(0,e.createComponentVNode)(2,o.Box,{color:"average",textAlign:"center",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"exclamation-triangle",mr:"0.5rem"}),"This machine only accepts ore. Gibtonite is not accepted."]}),(0,e.createComponentVNode)(2,o.Divider),(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Unclaimed Points",color:B>0?"good":"grey",bold:B>0&&"good",children:k(B)})}),(0,e.createComponentVNode)(2,o.Divider),I?(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Design disk",children:[(0,e.createComponentVNode)(2,o.Button,{selected:!0,bold:!0,icon:"eject",content:I.name,tooltip:"Ejects the design disk.",onClick:function(){function w(){return f("eject_disk")}return w}()}),(0,e.createComponentVNode)(2,o.Button,{disabled:!I.design||!I.compatible,icon:"upload",content:"Download",tooltip:"Downloads the design on the disk into the machine.",onClick:function(){function w(){return f("download")}return w}()})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Stored design",children:(0,e.createComponentVNode)(2,o.Box,{color:I.design&&(I.compatible?"good":"bad"),children:I.design||"N/A"})})]}):(0,e.createComponentVNode)(2,o.Box,{color:"label",children:"No design disk inserted."})]})))},c=function(v,g){var C=(0,t.useBackend)(g),f=C.act,N=C.data,V=N.sheets,B=Object.assign({},(y(v),v));return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,height:"20%",children:(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({fill:!0,scrollable:!0,className:"OreRedemption__Ores",p:"0"},B,{children:[(0,e.createComponentVNode)(2,l,{title:"Sheets",columns:[["Available","25%"],["Ore Value","15%"],["Smelt","20%"]]}),V.map(function(I){return(0,e.createComponentVNode)(2,u,{ore:I},I.id)})]})))})},m=function(v,g){var C=(0,t.useBackend)(g),f=C.act,N=C.data,V=N.alloys,B=Object.assign({},(y(v),v));return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.normalizeProps)((0,e.createComponentVNode)(2,o.Section,Object.assign({fill:!0,scrollable:!0,className:"OreRedemption__Ores",p:"0"},B,{children:[(0,e.createComponentVNode)(2,l,{title:"Alloys",columns:[["Recipe","50%"],["Available","11%"],["Smelt","20%"]]}),V.map(function(I){return(0,e.createComponentVNode)(2,s,{ore:I},I.id)})]})))})},l=function(v,g){var C;return(0,e.createComponentVNode)(2,o.Box,{className:"OreHeader",children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:v.title}),(C=v.columns)==null?void 0:C.map(function(f){return(0,e.createComponentVNode)(2,o.Stack.Item,{basis:f[1],textAlign:"center",color:"label",bold:!0,children:f[0]},f)})]})})},u=function(v,g){var C=(0,t.useBackend)(g),f=C.act,N=v.ore;if(!(N.value&&N.amount<=0&&!(["metal","glass"].indexOf(N.id)>-1)))return(0,e.createComponentVNode)(2,o.Box,{className:"SheetLine",children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"45%",align:"middle",children:(0,e.createComponentVNode)(2,o.Stack,{align:"center",children:[(0,e.createComponentVNode)(2,o.Stack.Item,{className:(0,a.classes)(["materials32x32",N.id])}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:N.name})]})}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"20%",textAlign:"center",color:N.amount>=1?"good":"gray",bold:N.amount>=1,align:"center",children:N.amount.toLocaleString("en-US")}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"20%",textAlign:"center",align:"center",children:N.value}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"20%",textAlign:"center",align:"center",lineHeight:"32px",children:(0,e.createComponentVNode)(2,o.NumberInput,{width:"40%",value:0,minValue:0,maxValue:Math.min(N.amount,50),stepPixelSize:6,onChange:function(){function V(B,I){return f(N.value?"sheet":"alloy",{id:N.id,amount:I})}return V}()})})]})})},s=function(v,g){var C=(0,t.useBackend)(g),f=C.act,N=v.ore;return(0,e.createComponentVNode)(2,o.Box,{className:"SheetLine",children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"7%",align:"middle",children:(0,e.createComponentVNode)(2,o.Box,{className:(0,a.classes)(["alloys32x32",N.id])})}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"30%",textAlign:"middle",align:"center",children:N.name}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"35%",textAlign:"middle",color:N.amount>=1?"good":"gray",align:"center",children:N.description}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"10%",textAlign:"center",color:N.amount>=1?"good":"gray",bold:N.amount>=1,align:"center",children:N.amount.toLocaleString("en-US")}),(0,e.createComponentVNode)(2,o.Stack.Item,{basis:"20%",textAlign:"center",align:"center",lineHeight:"32px",children:(0,e.createComponentVNode)(2,o.NumberInput,{width:"40%",value:0,minValue:0,maxValue:Math.min(N.amount,50),stepPixelSize:6,onChange:function(){function V(B,I){return f(N.value?"sheet":"alloy",{id:N.id,amount:I})}return V}()})})]})})}},52754:function(T,r,n){"use strict";r.__esModule=!0,r.PAI=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(71253),b=n(70752),y=function(h){var i;try{i=b("./"+h+".js")}catch(m){if(m.code==="MODULE_NOT_FOUND")return(0,p.routingError)("notFound",h);throw m}var c=i[h];return c||(0,p.routingError)("missingExport",h)},S=r.PAI=function(){function k(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.app_template,s=l.app_icon,d=l.app_title,v=y(u);return(0,e.createComponentVNode)(2,o.Window,{width:600,height:650,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{p:1,fill:!0,scrollable:!0,title:(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:s,mr:1}),d,u!=="pai_main_menu"&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{ml:2,mb:0,content:"Back",icon:"arrow-left",onClick:function(){function g(){return m("Back")}return g}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Home",icon:"arrow-up",onClick:function(){function g(){return m("MASTER_back")}return g}()})],4)]}),children:(0,e.createComponentVNode)(2,v)})})})})})}return k}()},85175:function(T,r,n){"use strict";r.__esModule=!0,r.PDA=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(71253),b=n(59395),y=function(c){var m;try{m=b("./"+c+".js")}catch(u){if(u.code==="MODULE_NOT_FOUND")return(0,p.routingError)("notFound",c);throw u}var l=m[c];return l||(0,p.routingError)("missingExport",c)},S=r.PDA=function(){function i(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=s.app,v=s.owner;if(!v)return(0,e.createComponentVNode)(2,o.Window,{width:350,height:105,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Error",children:"No user data found. Please swipe an ID card."})})});var g=y(d.template);return(0,e.createComponentVNode)(2,o.Window,{width:600,height:650,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,k)}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,p:1,pb:0,title:(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:d.icon,mr:1}),d.name]}),children:(0,e.createComponentVNode)(2,g)})}),(0,e.createComponentVNode)(2,t.Stack.Item,{mt:7.5,children:(0,e.createComponentVNode)(2,h)})]})})})}return i}(),k=function(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=s.idInserted,v=s.idLink,g=s.stationTime,C=s.cartridge_name;return(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{ml:.5,children:(0,e.createComponentVNode)(2,t.Button,{icon:"id-card",color:"transparent",onClick:function(){function f(){return u("Authenticate")}return f}(),content:d?v:"No ID Inserted"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"sd-card",color:"transparent",onClick:function(){function f(){return u("Eject")}return f}(),content:C?["Eject "+C]:"No Cartridge Inserted"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"right",bold:!0,mr:1,mt:.5,children:g})]})},h=function(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=s.app;return(0,e.createComponentVNode)(2,t.Box,{height:"45px",className:"PDA__footer",backgroundColor:"#1b1b1b",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:[!!d.has_back&&(0,e.createComponentVNode)(2,t.Stack.Item,{basis:"33%",mr:-.5,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,className:"PDA__footer__button",color:"transparent",iconColor:d.has_back?"white":"disabled",icon:"arrow-alt-circle-left-o",onClick:function(){function v(){return u("Back")}return v}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{basis:d.has_back?"33%":"100%",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,className:"PDA__footer__button",color:"transparent",iconColor:d.is_home?"disabled":"white",icon:"home",onClick:function(){function v(){u("Home")}return v}()})})]})})}},68654:function(T,r,n){"use strict";r.__esModule=!0,r.Pacman=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(49968),b=r.Pacman=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.active,l=c.anchored,u=c.broken,s=c.emagged,d=c.fuel_type,v=c.fuel_usage,g=c.fuel_stored,C=c.fuel_cap,f=c.is_ai,N=c.tmp_current,V=c.tmp_max,B=c.tmp_overheat,I=c.output_max,L=c.power_gen,w=c.output_set,A=c.has_fuel,x=g/C,E=N/V,P=w*L,D=Math.round(g/v*2),M=Math.round(D/60),O=D>120?M+" minutes":D+" seconds";return(0,e.createComponentVNode)(2,o.Window,{width:500,height:225,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(u||!l)&&(0,e.createComponentVNode)(2,t.Section,{title:"Status",children:[!!u&&(0,e.createComponentVNode)(2,t.Box,{color:"orange",children:"The generator is malfunctioning!"}),!u&&!l&&(0,e.createComponentVNode)(2,t.Box,{color:"orange",children:"The generator needs to be anchored to the floor with a wrench."})]}),!u&&!!l&&(0,e.createVNode)(1,"div",null,[(0,e.createComponentVNode)(2,t.Section,{title:"Status",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:m?"power-off":"times",content:m?"On":"Off",tooltip:"Toggles the generator on/off. Requires fuel.",tooltipPosition:"left",disabled:!A,selected:m,onClick:function(){function R(){return i("toggle_power")}return R}()}),children:(0,e.createComponentVNode)(2,t.Flex,{direction:"row",children:[(0,e.createComponentVNode)(2,t.Flex.Item,{width:"50%",className:"ml-1",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power setting",children:[(0,e.createComponentVNode)(2,t.NumberInput,{value:w,minValue:1,maxValue:I*(s?2.5:1),step:1,className:"mt-1",onDrag:function(){function R(F,W){return i("change_power",{change_power:W})}return R}()}),"(",(0,p.formatPower)(P),")"]})})}),(0,e.createComponentVNode)(2,t.Flex.Item,{width:"50%",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Temperature",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:E,ranges:{green:[-1/0,.33],orange:[.33,.66],red:[.66,1/0]},children:[N," \u2103"]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:[B>50&&(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"CRITICAL OVERHEAT!"}),B>20&&B<=50&&(0,e.createComponentVNode)(2,t.Box,{color:"orange",children:"WARNING: Overheating!"}),B>1&&B<=20&&(0,e.createComponentVNode)(2,t.Box,{color:"orange",children:"Temperature High"}),B===0&&(0,e.createComponentVNode)(2,t.Box,{color:"green",children:"Optimal"})]})]})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Fuel",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:"Eject Fuel",tooltip:"Ejects fuel. Generator needs to be offline.",tooltipPosition:"left",disabled:m||f||!A,onClick:function(){function R(){return i("eject_fuel")}return R}()}),children:(0,e.createComponentVNode)(2,t.Grid,{children:[(0,e.createComponentVNode)(2,t.Grid.Column,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Type",children:d}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Fuel level",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:x,ranges:{red:[-1/0,.33],orange:[.33,.66],green:[.66,1/0]},children:[Math.round(g/1e3)," dm\xB3"]})})]})}),(0,e.createComponentVNode)(2,t.Grid.Column,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Fuel usage",children:[v/1e3," dm\xB3/s"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Fuel depletion",children:[!!A&&(v?O:"N/A"),!A&&(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Out of fuel"})]})]})})]})})],4)]})})}return y}()},1701:function(T,r,n){"use strict";r.__esModule=!0,r.PanDEMIC=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.PanDEMIC=function(){function l(u,s){var d=(0,a.useBackend)(s),v=d.data,g=v.beakerLoaded,C=v.beakerContainsBlood,f=v.beakerContainsVirus,N=v.resistances,V=N===void 0?[]:N,B;return g?C?C&&!f&&(B=(0,e.createFragment)([(0,e.createTextVNode)("No disease detected in provided blood sample.")],4)):B=(0,e.createFragment)([(0,e.createTextVNode)("No blood sample found in the loaded container.")],4):B=(0,e.createFragment)([(0,e.createTextVNode)("No container loaded.")],4),(0,e.createComponentVNode)(2,o.Window,{width:575,height:510,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[B&&!f?(0,e.createComponentVNode)(2,t.Section,{title:"Container Information",buttons:(0,e.createComponentVNode)(2,b,{fill:!0,vertical:!0}),children:(0,e.createComponentVNode)(2,t.NoticeBox,{children:B})}):(0,e.createComponentVNode)(2,k),(V==null?void 0:V.length)>0&&(0,e.createComponentVNode)(2,m,{align:"bottom"})]})})})}return l}(),b=function(u,s){var d=(0,a.useBackend)(s),v=d.act,g=d.data,C=g.beakerLoaded;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:"Eject",disabled:!C,onClick:function(){function f(){return v("eject_beaker")}return f}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"trash-alt",confirmIcon:"eraser",content:"Destroy",confirmContent:"Destroy",disabled:!C,onClick:function(){function f(){return v("destroy_eject_beaker")}return f}()})],4)},y=function(u,s){var d=(0,a.useBackend)(s),v=d.act,g=d.data,C=g.beakerContainsVirus,f=u.strain,N=f.commonName,V=f.description,B=f.diseaseAgent,I=f.bloodDNA,L=f.bloodType,w=f.possibleTreatments,A=f.transmissionRoute,x=f.isAdvanced,E=(0,e.createFragment)([(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Blood DNA",children:I?(0,e.createVNode)(1,"span",null,I,0,{style:{"font-family":"'Courier New', monospace"}}):"Undetectable"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Blood Type",children:(0,e.createVNode)(1,"div",null,null,1,{dangerouslySetInnerHTML:{__html:L!=null?L:"Undetectable"}})})],4);if(!C)return(0,e.createComponentVNode)(2,t.LabeledList,{children:E});var P;return x&&(N!=null&&N!=="Unknown"?P=(0,e.createComponentVNode)(2,t.Button,{icon:"print",content:"Print Release Forms",onClick:function(){function D(){return v("print_release_forms",{strain_index:u.strainIndex})}return D}(),style:{"margin-left":"auto"}}):P=(0,e.createComponentVNode)(2,t.Button,{icon:"pen",content:"Name Disease",onClick:function(){function D(){return v("name_strain",{strain_index:u.strainIndex})}return D}(),style:{"margin-left":"auto"}})),(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Common Name",className:"common-name-label",children:(0,e.createComponentVNode)(2,t.Stack,{horizontal:!0,align:"center",children:[N!=null?N:"Unknown",P]})}),V&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Description",children:V}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Disease Agent",children:B}),E,(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Spread Vector",children:A!=null?A:"None"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Possible Cures",children:w!=null?w:"None"})]})},S=function(u,s){var d,v=(0,a.useBackend)(s),g=v.act,C=v.data,f=!!C.synthesisCooldown,N=(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{icon:f?"spinner":"clone",iconSpin:f,content:"Clone",disabled:f,onClick:function(){function V(){return g("clone_strain",{strain_index:u.strainIndex})}return V}()}),u.sectionButtons],0);return(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:(d=u.sectionTitle)!=null?d:"Strain Information",buttons:N,children:(0,e.createComponentVNode)(2,y,{strain:u.strain,strainIndex:u.strainIndex})})})},k=function(u,s){var d,v=(0,a.useBackend)(s),g=v.act,C=v.data,f=C.selectedStrainIndex,N=C.strains,V=N[f-1];if(N.length===0)return(0,e.createComponentVNode)(2,t.Section,{title:"Container Information",buttons:(0,e.createComponentVNode)(2,b),children:(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No disease detected in provided blood sample."})});if(N.length===1){var B;return(0,e.createFragment)([(0,e.createComponentVNode)(2,S,{strain:N[0],strainIndex:1,sectionButtons:(0,e.createComponentVNode)(2,b)}),((B=N[0].symptoms)==null?void 0:B.length)>0&&(0,e.createComponentVNode)(2,i,{strain:N[0]})],0)}var I=(0,e.createComponentVNode)(2,b);return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Culture Information",fill:!0,buttons:I,children:(0,e.createComponentVNode)(2,t.Flex,{direction:"column",style:{height:"100%"},children:[(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,t.Tabs,{children:N.map(function(L,w){var A;return(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"virus",selected:f-1===w,onClick:function(){function x(){return g("switch_strain",{strain_index:w+1})}return x}(),children:(A=L.commonName)!=null?A:"Unknown"},w)})})}),(0,e.createComponentVNode)(2,S,{strain:V,strainIndex:f}),((d=V.symptoms)==null?void 0:d.length)>0&&(0,e.createComponentVNode)(2,i,{className:"remove-section-bottom-padding",strain:V})]})})})},h=function(u){return u.reduce(function(s,d){return s+d},0)},i=function(u){var s=u.strain.symptoms;return(0,e.createComponentVNode)(2,t.Flex.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{title:"Infection Symptoms",fill:!0,className:u.className,children:(0,e.createComponentVNode)(2,t.Table,{className:"symptoms-table",children:[(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Name"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Stealth"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Resistance"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Stage Speed"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Transmissibility"})]}),s.map(function(d,v){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.name}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.stealth}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.resistance}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.stageSpeed}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d.transmissibility})]},v)}),(0,e.createComponentVNode)(2,t.Table.Row,{className:"table-spacer"}),(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{style:{"font-weight":"bold"},children:"Total"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:h(s.map(function(d){return d.stealth}))}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:h(s.map(function(d){return d.resistance}))}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:h(s.map(function(d){return d.stageSpeed}))}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:h(s.map(function(d){return d.transmissibility}))})]})]})})})},c=["flask","vial","eye-dropper"],m=function(u,s){var d=(0,a.useBackend)(s),v=d.act,g=d.data,C=g.synthesisCooldown,f=g.beakerContainsVirus,N=g.resistances;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Antibodies",fill:!0,children:(0,e.createComponentVNode)(2,t.Stack,{horizontal:!0,wrap:!0,children:N.map(function(V,B){return(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:c[B%c.length],disabled:!!C,onClick:function(){function I(){return v("clone_vaccine",{resistance_index:B+1})}return I}(),mr:"0.5em"}),V]},B)})})})})}},67921:function(T,r,n){"use strict";r.__esModule=!0,r.ParticleAccelerator=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(25328),p=n(79646),b=n(36352),y=n(98595),S=n(35840),k=n(38307),h=function(u){switch(u){case 1:return"north";case 2:return"south";case 4:return"east";case 8:return"west";case 5:return"northeast";case 6:return"southeast";case 9:return"northwest";case 10:return"southwest"}return""},i=r.ParticleAccelerator=function(){function l(u,s){var d=(0,a.useBackend)(s),v=d.act,g=d.data,C=g.assembled,f=g.power,N=g.strength,V=g.max_strength,B=g.icon,I=g.layout_1,L=g.layout_2,w=g.layout_3,A=g.orientation;return(0,e.createComponentVNode)(2,y.Window,{width:395,height:C?160:A==="north"||A==="south"?540:465,children:(0,e.createComponentVNode)(2,y.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Control Panel",buttons:(0,e.createComponentVNode)(2,t.Button,{dmIcon:"sync",content:"Connect",onClick:function(){function x(){return v("scan")}return x}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",mb:"5px",children:(0,e.createComponentVNode)(2,t.Box,{color:C?"good":"bad",children:C?"Operational":"Error: Verify Configuration"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:(0,e.createComponentVNode)(2,t.Button,{icon:f?"power-off":"times",content:f?"On":"Off",selected:f,disabled:!C,onClick:function(){function x(){return v("power")}return x}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Strength",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"backward",disabled:!C||N===0,onClick:function(){function x(){return v("remove_strength")}return x}(),mr:"4px"}),N,(0,e.createComponentVNode)(2,t.Button,{icon:"forward",disabled:!C||N===V,onClick:function(){function x(){return v("add_strength")}return x}(),ml:"4px"})]})]})}),C?"":(0,e.createComponentVNode)(2,t.Section,{title:A?"EM Acceleration Chamber Orientation: "+(0,o.capitalize)(A):"Place EM Acceleration Chamber Next To Console",children:A===0?"":A==="north"||A==="south"?(0,e.createComponentVNode)(2,m):(0,e.createComponentVNode)(2,c)})]})})}return l}(),c=function(u,s){var d=(0,a.useBackend)(s),v=d.act,g=d.data,C=g.assembled,f=g.power,N=g.strength,V=g.max_strength,B=g.icon,I=g.layout_1,L=g.layout_2,w=g.layout_3,A=g.orientation;return(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,b.TableRow,{width:"40px",children:(A==="east"?I:w).slice().map(function(x){return(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Tooltip,{content:(0,e.createVNode)(1,"span",null,[x.name,(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)(" "),"Status: "+x.status,(0,e.createVNode)(1,"br"),"Direction: "+h(x.dir)],0,{style:{wordWrap:"break-word"}}),children:(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:B,dmIconState:x.icon_state,dmDirection:x.dir,style:{"border-style":"solid","border-width":"2px","border-color":x.status==="good"?"green":x.status==="Incomplete"?"orange":"red",padding:"2px"}})})},x.name)})}),(0,e.createComponentVNode)(2,b.TableRow,{width:"40px",children:L.slice().map(function(x){return(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Tooltip,{content:(0,e.createVNode)(1,"span",null,[x.name,(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)(" "),"Status: "+x.status,(0,e.createVNode)(1,"br"),"Direction: "+h(x.dir)],0,{style:{wordWrap:"break-word"}}),children:(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:B,dmIconState:x.icon_state,dmDirection:x.dir,style:{"border-style":"solid","border-width":"2px","border-color":x.status==="good"?"green":x.status==="Incomplete"?"orange":"red",padding:"2px"}})})},x.name)})}),(0,e.createComponentVNode)(2,b.TableRow,{width:"40px",children:(A==="east"?w:I).slice().map(function(x){return(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Tooltip,{content:(0,e.createVNode)(1,"span",null,[x.name,(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)(" "),"Status: "+x.status,(0,e.createVNode)(1,"br"),"Direction: "+h(x.dir)],0,{style:{wordWrap:"break-word"}}),children:(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:B,dmIconState:x.icon_state,dmDirection:x.dir,style:{"border-style":"solid","border-width":"2px","border-color":x.status==="good"?"green":x.status==="Incomplete"?"orange":"red",padding:"2px"}})})},x.name)})})]})},m=function(u,s){var d=(0,a.useBackend)(s),v=d.act,g=d.data,C=g.assembled,f=g.power,N=g.strength,V=g.max_strength,B=g.icon,I=g.layout_1,L=g.layout_2,w=g.layout_3,A=g.orientation;return(0,e.createComponentVNode)(2,t.Grid,{children:[(0,e.createComponentVNode)(2,p.GridColumn,{width:"40px",children:(A==="north"?I:w).slice().map(function(x){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Tooltip,{content:(0,e.createVNode)(1,"span",null,[x.name,(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)(" "),"Status: "+x.status,(0,e.createVNode)(1,"br"),"Direction: "+h(x.dir)],0,{style:{wordWrap:"break-word"}}),children:(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:B,dmIconState:x.icon_state,dmDirection:x.dir,style:{"border-style":"solid","border-width":"2px","border-color":x.status==="good"?"green":x.status==="Incomplete"?"orange":"red",padding:"2px"}})})},x.name)})}),(0,e.createComponentVNode)(2,p.GridColumn,{children:L.slice().map(function(x){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Tooltip,{content:(0,e.createVNode)(1,"span",null,[x.name,(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)(" "),"Status: "+x.status,(0,e.createVNode)(1,"br"),"Direction: "+h(x.dir)],0,{style:{wordWrap:"break-word"}}),children:(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:B,dmIconState:x.icon_state,dmDirection:x.dir,style:{"border-style":"solid","border-width":"2px","border-color":x.status==="good"?"green":x.status==="Incomplete"?"orange":"red",padding:"2px"}})})},x.name)})}),(0,e.createComponentVNode)(2,p.GridColumn,{width:"40px",children:(A==="north"?w:I).slice().map(function(x){return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,tooltip:x.status,children:(0,e.createComponentVNode)(2,t.Tooltip,{content:(0,e.createVNode)(1,"span",null,[x.name,(0,e.createTextVNode)(" "),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)(" "),"Status: "+x.status,(0,e.createVNode)(1,"br"),"Direction: "+h(x.dir)],0,{style:{wordWrap:"break-word"}}),children:(0,e.createComponentVNode)(2,t.ImageButton,{dmIcon:B,dmIconState:x.icon_state,dmDirection:x.dir,style:{"border-style":"solid","border-width":"2px","border-color":x.status==="good"?"green":x.status==="Incomplete"?"orange":"red",padding:"2px"}})})},x.name)})})]})}},71432:function(T,r,n){"use strict";r.__esModule=!0,r.PdaPainter=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.PdaPainter=function(){function k(h,i){var c=(0,a.useBackend)(i),m=c.data,l=m.has_pda;return(0,e.createComponentVNode)(2,o.Window,{width:510,height:505,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:l?(0,e.createComponentVNode)(2,y):(0,e.createComponentVNode)(2,b)})})}return k}(),b=function(h,i){var c=(0,a.useBackend)(i),m=c.act;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,textAlign:"center",align:"center",color:"silver",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"download",size:5,mb:"10px"}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{width:"160px",textAlign:"center",content:"Insert PDA",onClick:function(){function l(){return m("insert_pda")}return l}()})]})})})},y=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.pda_colors;return(0,e.createComponentVNode)(2,t.Stack,{fill:!0,horizontal:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,S)}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,t.Table,{className:"PdaPainter__list",children:Object.keys(u).map(function(s){return(0,e.createComponentVNode)(2,t.Table.Row,{onClick:function(){function d(){return m("choose_pda",{selectedPda:s})}return d}(),children:[(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,children:(0,e.createVNode)(1,"img",null,null,1,{src:"data:image/png;base64,"+u[s][0],style:{"vertical-align":"middle",width:"32px",margin:"0px","margin-left":"0px","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"}})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:s})]},s)})})})})]})},S=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.current_appearance,s=l.preview_appearance;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Current PDA",children:[(0,e.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+u,style:{"vertical-align":"middle",width:"160px",margin:"0px","margin-left":"0px","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"}}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"eject",content:"Eject",color:"green",onClick:function(){function d(){return m("eject_pda")}return d}()}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",icon:"paint-roller",content:"Paint PDA",onClick:function(){function d(){return m("paint_pda")}return d}()})]}),(0,e.createComponentVNode)(2,t.Section,{title:"Preview",children:(0,e.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+s,style:{"vertical-align":"middle",width:"160px",margin:"0px","margin-left":"0px","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"}})})]})}},33388:function(T,r,n){"use strict";r.__esModule=!0,r.PersonalCrafting=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.PersonalCrafting=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.busy,u=m.category,s=m.display_craftable_only,d=m.display_compact,v=m.prev_cat,g=m.next_cat,C=m.subcategory,f=m.prev_subcat,N=m.next_subcat;return(0,e.createComponentVNode)(2,o.Window,{width:700,height:800,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[!!l&&(0,e.createComponentVNode)(2,t.Dimmer,{fontSize:"32px",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"cog",spin:1})," Crafting..."]}),(0,e.createComponentVNode)(2,t.Section,{title:u,buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:"Show Craftable Only",icon:s?"check-square-o":"square-o",selected:s,onClick:function(){function V(){return c("toggle_recipes")}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Compact Mode",icon:d?"check-square-o":"square-o",selected:d,onClick:function(){function V(){return c("toggle_compact")}return V}()})],4),children:[(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Button,{content:v,icon:"arrow-left",onClick:function(){function V(){return c("backwardCat")}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:g,icon:"arrow-right",onClick:function(){function V(){return c("forwardCat")}return V}()})]}),C&&(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Button,{content:f,icon:"arrow-left",onClick:function(){function V(){return c("backwardSubCat")}return V}()}),(0,e.createComponentVNode)(2,t.Button,{content:N,icon:"arrow-right",onClick:function(){function V(){return c("forwardSubCat")}return V}()})]}),d?(0,e.createComponentVNode)(2,b):(0,e.createComponentVNode)(2,y)]})]})})}return S}(),b=function(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.display_craftable_only,u=m.can_craft,s=m.cant_craft;return(0,e.createComponentVNode)(2,t.Box,{mt:1,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[u.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:d.name,children:[(0,e.createComponentVNode)(2,t.Button,{icon:"hammer",content:"Craft",onClick:function(){function v(){return c("make",{make:d.ref})}return v}()}),d.catalyst_text&&(0,e.createComponentVNode)(2,t.Button,{tooltip:d.catalyst_text,content:"Catalysts",color:"transparent"}),(0,e.createComponentVNode)(2,t.Button,{tooltip:d.req_text,content:"Requirements",color:"transparent"}),d.tool_text&&(0,e.createComponentVNode)(2,t.Button,{tooltip:d.tool_text,content:"Tools",color:"transparent"})]},d.name)}),!l&&s.map(function(d){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:d.name,children:[(0,e.createComponentVNode)(2,t.Button,{icon:"hammer",content:"Craft",disabled:!0}),d.catalyst_text&&(0,e.createComponentVNode)(2,t.Button,{tooltip:d.catalyst_text,content:"Catalysts",color:"transparent"}),(0,e.createComponentVNode)(2,t.Button,{tooltip:d.req_text,content:"Requirements",color:"transparent"}),d.tool_text&&(0,e.createComponentVNode)(2,t.Button,{tooltip:d.tool_text,content:"Tools",color:"transparent"})]},d.name)})]})})},y=function(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.display_craftable_only,u=m.can_craft,s=m.cant_craft;return(0,e.createComponentVNode)(2,t.Box,{mt:1,children:[u.map(function(d){return(0,e.createComponentVNode)(2,t.Section,{title:d.name,buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"hammer",content:"Craft",onClick:function(){function v(){return c("make",{make:d.ref})}return v}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[d.catalyst_text&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Catalysts",children:d.catalyst_text}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Requirements",children:d.req_text}),d.tool_text&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tools",children:d.tool_text})]})},d.name)}),!l&&s.map(function(d){return(0,e.createComponentVNode)(2,t.Section,{title:d.name,buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"hammer",content:"Craft",disabled:!0}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[d.catalyst_text&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Catalysts",children:d.catalyst_text}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Requirements",children:d.req_text}),d.tool_text&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tools",children:d.tool_text})]})},d.name)})]})}},56150:function(T,r,n){"use strict";r.__esModule=!0,r.Photocopier=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.Photocopier=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data;return(0,e.createComponentVNode)(2,o.Window,{width:400,height:440,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Photocopier",color:"silver",children:[(0,e.createComponentVNode)(2,t.Stack,{mb:1,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:12,children:"Copies:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"2em",bold:!0,children:m.copynumber}),(0,e.createComponentVNode)(2,t.Stack.Item,{float:"right",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"minus",textAlign:"center",content:"",onClick:function(){function l(){return c("minus")}return l}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"plus",textAlign:"center",content:"",onClick:function(){function l(){return c("add")}return l}()})]})]}),(0,e.createComponentVNode)(2,t.Stack,{mb:2,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:12,children:"Toner:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,children:m.toner})]}),(0,e.createComponentVNode)(2,t.Stack,{mb:1,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:12,children:"Inserted Document:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",disabled:!m.copyitem&&!m.mob,content:m.copyitem?m.copyitem:m.mob?m.mob+"'s ass!":"document",onClick:function(){function l(){return c("removedocument")}return l}()})})]}),(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:12,children:"Inserted Folder:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",disabled:!m.folder,content:m.folder?m.folder:"folder",onClick:function(){function l(){return c("removefolder")}return l}()})})]})]}),(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,b)}),(0,e.createComponentVNode)(2,y)]})})})}return S}(),b=function(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.issilicon;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"copy",float:"center",textAlign:"center",content:"Copy",onClick:function(){function u(){return c("copy")}return u}()}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"file-import",float:"center",textAlign:"center",content:"Scan",onClick:function(){function u(){return c("scandocument")}return u}()}),!!l&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"file",color:"green",float:"center",textAlign:"center",content:"Print Text",onClick:function(){function u(){return c("ai_text")}return u}()}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"image",color:"green",float:"center",textAlign:"center",content:"Print Image",onClick:function(){function u(){return c("ai_pic")}return u}()})],4)],0)},y=function(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data;return(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Scanned Files",children:m.files.map(function(l){return(0,e.createComponentVNode)(2,t.Section,{title:l.name,buttons:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"print",content:"Print",disabled:m.toner<=0,onClick:function(){function u(){return c("filecopy",{uid:l.uid})}return u}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"trash-alt",content:"Delete",color:"bad",onClick:function(){function u(){return c("deletefile",{uid:l.uid})}return u}()})]})},l.name)})})}},84676:function(T,r,n){"use strict";r.__esModule=!0,r.PoolController=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=["tempKey"];function b(h,i){if(h==null)return{};var c={};for(var m in h)if({}.hasOwnProperty.call(h,m)){if(i.includes(m))continue;c[m]=h[m]}return c}var y={scalding:{label:"Scalding",color:"#FF0000",icon:"fa fa-arrow-circle-up",requireEmag:!0},warm:{label:"Warm",color:"#990000",icon:"fa fa-arrow-circle-up"},normal:{label:"Normal",color:null,icon:"fa fa-arrow-circle-right"},cool:{label:"Cool",color:"#009999",icon:"fa fa-arrow-circle-down"},frigid:{label:"Frigid",color:"#00CCCC",icon:"fa fa-arrow-circle-down",requireEmag:!0}},S=function(i,c){var m=i.tempKey,l=b(i,p),u=y[m];if(!u)return null;var s=(0,a.useBackend)(c),d=s.data,v=s.act,g=d.currentTemp,C=u.label,f=u.icon,N=m===g,V=function(){v("setTemp",{temp:m})};return(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.Button,Object.assign({color:"transparent",selected:N,onClick:V},l,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:f}),C]})))},k=r.PoolController=function(){function h(i,c){for(var m=(0,a.useBackend)(c),l=m.data,u=l.emagged,s=l.currentTemp,d=y[s]||y.normal,v=d.label,g=d.color,C=[],f=0,N=Object.entries(y);f50?"battery-half":"battery-quarter")||g==="C"&&"bolt"||g==="F"&&"battery-full"||g==="M"&&"slash",color:g==="N"&&(C>50?"yellow":"red")||g==="C"&&"yellow"||g==="F"&&"green"||g==="M"&&"orange"}),(0,e.createComponentVNode)(2,S.Box,{inline:!0,width:"36px",textAlign:"right",children:(0,o.toFixed)(C)+"%"})],4)};u.defaultHooks=p.pureComponentHooks;var s=function(v){var g,C,f=v.status;switch(f){case"AOn":g=!0,C=!0;break;case"AOff":g=!0,C=!1;break;case"On":g=!1,C=!0;break;case"Off":g=!1,C=!1;break}var N=(C?"On":"Off")+(" ["+(g?"auto":"manual")+"]");return(0,e.createComponentVNode)(2,S.ColorBox,{color:C?"good":"bad",content:g?void 0:"M",title:N})};s.defaultHooks=p.pureComponentHooks},50992:function(T,r,n){"use strict";r.__esModule=!0,r.PrisonerImplantManager=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(29319),p=n(3939),b=n(321),y=n(5485),S=n(98595),k=r.PrisonerImplantManager=function(){function h(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.loginState,d=u.prisonerInfo,v=u.chemicalInfo,g=u.trackingInfo,C;if(!s.logged_in)return(0,e.createComponentVNode)(2,S.Window,{theme:"security",width:500,height:850,children:(0,e.createComponentVNode)(2,S.Window.Content,{children:(0,e.createComponentVNode)(2,y.LoginScreen)})});var f=[1,5,10];return(0,e.createComponentVNode)(2,S.Window,{theme:"security",width:500,height:850,children:[(0,e.createComponentVNode)(2,p.ComplexModal),(0,e.createComponentVNode)(2,S.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.LoginInfo),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Prisoner Points Manager System",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Prisoner",children:(0,e.createComponentVNode)(2,t.Button,{icon:d.name?"eject":"id-card",selected:d.name,content:d.name?d.name:"-----",tooltip:d.name?"Eject ID":"Insert ID",onClick:function(){function N(){return l("id_card")}return N}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Points",children:[d.points!==null?d.points:"-/-",(0,e.createComponentVNode)(2,t.Button,{ml:2,icon:"minus-square",disabled:d.points===null,content:"Reset",onClick:function(){function N(){return l("reset_points")}return N}()})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Point Goal",children:[d.goal!==null?d.goal:"-/-",(0,e.createComponentVNode)(2,t.Button,{ml:2,icon:"pen",disabled:d.goal===null,content:"Edit",onClick:function(){function N(){return(0,p.modalOpen)(c,"set_points")}return N}()})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{children:(0,e.createVNode)(1,"box",null,[(0,e.createTextVNode)("1 minute of prison time should roughly equate to 150 points."),(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Sentences should not exceed 5000 points."),(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Permanent prisoners should not be given a point goal."),(0,e.createVNode)(1,"br"),(0,e.createVNode)(1,"br"),(0,e.createTextVNode)("Prisoners who meet their point goal will be able to automatically access their locker and return to the station using the shuttle.")],4,{hidden:d.goal===null})})]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Tracking Implants",children:g.map(function(N){return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{p:1,backgroundColor:"rgba(255, 255, 255, 0.05)",children:[(0,e.createComponentVNode)(2,t.Box,{bold:!0,children:["Subject: ",N.subject]}),(0,e.createComponentVNode)(2,t.Box,{children:[" ",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Location",children:N.location}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Health",children:N.health}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Prisoner",children:(0,e.createComponentVNode)(2,t.Button,{icon:"exclamation-triangle",content:"Warn",tooltip:"Broadcast a message to this poor sod",onClick:function(){function V(){return(0,p.modalOpen)(c,"warn",{uid:N.uid})}return V}()})})]})]},N.subject)]}),(0,e.createVNode)(1,"br")],4)})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Chemical Implants",children:v.map(function(N){return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{p:1,backgroundColor:"rgba(255, 255, 255, 0.05)",children:[(0,e.createComponentVNode)(2,t.Box,{bold:!0,children:["Subject: ",N.name]}),(0,e.createComponentVNode)(2,t.Box,{children:[" ",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Remaining Reagents",children:N.volume})}),f.map(function(V){return(0,e.createComponentVNode)(2,t.Button,{mt:2,disabled:N.volumec;return(0,e.createComponentVNode)(2,t.ImageButton,{fluid:!0,title:N.name,dmIcon:N.icon,dmIconState:N.icon_state,buttonsAlt:(0,e.createComponentVNode)(2,t.Button,{bold:!0,translucent:!0,fontSize:1.5,tooltip:V&&"Not enough tickets",disabled:V,onClick:function(){function B(){return h("purchase",{purchase:N.itemID})}return B}(),children:[N.cost,(0,e.createComponentVNode)(2,t.Icon,{m:0,mt:.25,name:"ticket",color:V?"bad":"good",size:1.6})]}),children:N.desc},N.name)})})})})})})}return b}()},94813:function(T,r,n){"use strict";r.__esModule=!0,r.RCD=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(3939),b=n(49148),y=r.RCD=function(){function l(u,s){return(0,e.createComponentVNode)(2,o.Window,{width:480,height:670,children:[(0,e.createComponentVNode)(2,p.ComplexModal),(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,S),(0,e.createComponentVNode)(2,k),(0,e.createComponentVNode)(2,i),(0,e.createComponentVNode)(2,c)]})})]})}return l}(),S=function(u,s){var d=(0,a.useBackend)(s),v=d.data,g=v.matter,C=v.max_matter,f=C*.7,N=C*.25;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Matter Storage",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ranges:{good:[f,1/0],average:[N,f],bad:[-1/0,N]},value:g,maxValue:C,children:(0,e.createComponentVNode)(2,t.Stack.Item,{textAlign:"center",children:g+" / "+C+" units"})})})})},k=function(){return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Construction Type",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,h,{mode_type:"Floors and Walls"}),(0,e.createComponentVNode)(2,h,{mode_type:"Airlocks"}),(0,e.createComponentVNode)(2,h,{mode_type:"Windows"}),(0,e.createComponentVNode)(2,h,{mode_type:"Deconstruction"})]})})})},h=function(u,s){var d=(0,a.useBackend)(s),v=d.act,g=d.data,C=u.mode_type,f=g.mode;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,color:"transparent",content:C,selected:f===C?1:0,onClick:function(){function N(){return v("mode",{mode:C})}return N}()})})},i=function(u,s){var d=(0,a.useBackend)(s),v=d.act,g=d.data,C=g.door_name,f=g.electrochromic,N=g.airlock_glass;return(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Airlock Settings",children:(0,e.createComponentVNode)(2,t.Stack,{textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,color:"transparent",icon:"pen-alt",content:(0,e.createFragment)([(0,e.createTextVNode)("Rename: "),(0,e.createVNode)(1,"b",null,C,0)],0),onClick:function(){function V(){return(0,p.modalOpen)(s,"renameAirlock")}return V}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:N===1&&(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:f?"toggle-on":"toggle-off",content:"Electrochromic",selected:f,onClick:function(){function V(){return v("electrochromic")}return V}()})})]})})})},c=function(u,s){var d=(0,a.useBackend)(s),v=d.act,g=d.data,C=g.tab,f=g.locked,N=g.one_access,V=g.selected_accesses,B=g.regions;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Tabs,{fluid:!0,children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"cog",selected:C===1,onClick:function(){function I(){return v("set_tab",{tab:1})}return I}(),children:"Airlock Types"}),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:C===2,icon:"list",onClick:function(){function I(){return v("set_tab",{tab:2})}return I}(),children:"Airlock Access"})]})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:C===1?(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Types",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,m,{check_number:0})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,m,{check_number:1})})]})}):C===2&&f?(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Access",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"lock-open",content:"Unlock",onClick:function(){function I(){return v("set_lock",{new_lock:"unlock"})}return I}()}),children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",align:"center",color:"label",children:[(0,e.createComponentVNode)(2,t.Icon,{name:"lock",size:"5",mb:3}),(0,e.createVNode)(1,"br"),"Airlock access selection is currently locked."]})})}):(0,e.createComponentVNode)(2,b.AccessList,{sectionButtons:(0,e.createComponentVNode)(2,t.Button,{icon:"lock",content:"Lock",onClick:function(){function I(){return v("set_lock",{new_lock:"lock"})}return I}()}),usedByRcd:1,rcdButtons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:N,content:"One",onClick:function(){function I(){return v("set_one_access",{access:"one"})}return I}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:!N,width:4,content:"All",onClick:function(){function I(){return v("set_one_access",{access:"all"})}return I}()})],4),accesses:B,selectedList:V,accessMod:function(){function I(L){return v("set",{access:L})}return I}(),grantAll:function(){function I(){return v("grant_all")}return I}(),denyAll:function(){function I(){return v("clear_all")}return I}(),grantDep:function(){function I(L){return v("grant_region",{region:L})}return I}(),denyDep:function(){function I(L){return v("deny_region",{region:L})}return I}()})})],4)},m=function(u,s){for(var d=(0,a.useBackend)(s),v=d.act,g=d.data,C=g.door_types_ui_list,f=g.door_type,N=u.check_number,V=[],B=0;Bp?w=(0,e.createComponentVNode)(2,t.Box,{color:"red",bold:!0,mb:1,children:"There are new messages"}):w=(0,e.createComponentVNode)(2,t.Box,{color:"label",mb:1,children:"There are no new messages"}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Main Menu",buttons:(0,e.createComponentVNode)(2,t.Button,{width:9,content:L?"Speaker Off":"Speaker On",selected:!L,icon:L?"volume-mute":"volume-up",onClick:function(){function A(){return N("toggleSilent")}return A}()}),children:[w,(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"View Messages",icon:B>p?"envelope-open-text":"envelope",onClick:function(){function A(){return N("setScreen",{setScreen:6})}return A}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{mt:1,children:[(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"Request Assistance",icon:"hand-paper",onClick:function(){function A(){return N("setScreen",{setScreen:1})}return A}()}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"Request Supplies",icon:"box",onClick:function(){function A(){return N("setScreen",{setScreen:2})}return A}()}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"Request Secondary Goal",icon:"clipboard-list",onClick:function(){function A(){return N("setScreen",{setScreen:11})}return A}()}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"Relay Anonymous Information",icon:"comment",onClick:function(){function A(){return N("setScreen",{setScreen:3})}return A}()})]})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{mt:1,children:(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"Print Shipping Label",icon:"tag",onClick:function(){function A(){return N("setScreen",{setScreen:9})}return A}()}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"View Shipping Logs",icon:"clipboard-list",onClick:function(){function A(){return N("setScreen",{setScreen:10})}return A}()})]})}),!!I&&(0,e.createComponentVNode)(2,t.Stack.Item,{mt:1,children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,lineHeight:3,content:"Send Station-Wide Announcement",icon:"bullhorn",onClick:function(){function A(){return N("setScreen",{setScreen:8})}return A}()})})]})})},i=function(g,C){var f=(0,a.useBackend)(C),N=f.act,V=f.data,B=V.department,I=[],L;switch(g.purpose){case"ASSISTANCE":I=V.assist_dept,L="Request assistance from another department";break;case"SUPPLIES":I=V.supply_dept,L="Request supplies from another department";break;case"INFO":I=V.info_dept,L="Relay information to another department";break}return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:L,buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function w(){return N("setScreen",{setScreen:0})}return w}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:I.filter(function(w){return w!==B}).map(function(w){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:w,textAlign:"right",className:"candystripe",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Message",icon:"envelope",onClick:function(){function A(){return N("writeInput",{write:w,priority:y})}return A}()}),(0,e.createComponentVNode)(2,t.Button,{content:"High Priority",icon:"exclamation-circle",onClick:function(){function A(){return N("writeInput",{write:w,priority:S})}return A}()})]},w)})})})})},c=function(g,C){var f=(0,a.useBackend)(C),N=f.act,V=f.data,B;switch(g.type){case"SUCCESS":B="Message sent successfully";break;case"FAIL":B="Unable to contact messaging server";break}return(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:B,buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function I(){return N("setScreen",{setScreen:0})}return I}()})})},m=function(g,C){var f=(0,a.useBackend)(C),N=f.act,V=f.data,B,I;switch(g.type){case"MESSAGES":B=V.message_log,I="Message Log";break;case"SHIPPING":B=V.shipping_log,I="Shipping label print log";break}return B.reverse(),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:I,buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function L(){return N("setScreen",{setScreen:0})}return L}()}),children:B.map(function(L){return(0,e.createComponentVNode)(2,t.Box,{textAlign:"left",children:[L.map(function(w,A){return(0,e.createVNode)(1,"div",null,w,0,null,A)}),(0,e.createVNode)(1,"hr")]},L)})})})},l=function(g,C){var f=(0,a.useBackend)(C),N=f.act,V=f.data,B=V.recipient,I=V.message,L=V.msgVerified,w=V.msgStamped;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Message Authentication",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function A(){return N("setScreen",{setScreen:0})}return A}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Recipient",children:B}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Message",children:I}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Validated by",color:"green",children:L}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Stamped by",color:"blue",children:w})]})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,textAlign:"center",content:"Send Message",icon:"envelope",onClick:function(){function A(){return N("department",{department:B})}return A}()})})})],4)},u=function(g,C){var f=(0,a.useBackend)(C),N=f.act,V=f.data,B=V.message,I=V.announceAuth;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Station-Wide Announcement",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function L(){return N("setScreen",{setScreen:0})}return L}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Edit Message",icon:"edit",onClick:function(){function L(){return N("writeAnnouncement")}return L}()})],4),children:B})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{children:[I?(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",color:"green",children:"ID verified. Authentication accepted."}):(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",color:"label",children:"Swipe your ID card to authenticate yourself"}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,mt:2,textAlign:"center",content:"Send Announcement",icon:"bullhorn",disabled:!(I&&B),onClick:function(){function L(){return N("sendAnnouncement")}return L}()})]})})],4)},s=function(g,C){var f=(0,a.useBackend)(C),N=f.act,V=f.data,B=V.shipDest,I=V.msgVerified,L=V.ship_dept;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{textAlign:"center",children:(0,e.createComponentVNode)(2,t.Section,{title:"Print Shipping Label",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function w(){return N("setScreen",{setScreen:0})}return w}()}),children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Destination",children:B}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Validated by",children:I})]}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,mt:1,textAlign:"center",content:"Print Label",icon:"print",disabled:!(B&&I),onClick:function(){function w(){return N("printLabel")}return w}()})]})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Destinations",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:L.map(function(w){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:w,textAlign:"right",className:"candystripe",children:(0,e.createComponentVNode)(2,t.Button,{content:B===w?"Selected":"Select",selected:B===w,onClick:function(){function A(){return N("shipSelect",{shipSelect:w})}return A}()})},w)})})})})],4)},d=function(g,C){var f=(0,a.useBackend)(C),N=f.act,V=f.data,B=V.secondaryGoalAuth,I=V.secondaryGoalEnabled;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Request Secondary Goal",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Back",icon:"arrow-left",onClick:function(){function L(){return N("setScreen",{setScreen:0})}return L}()})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{children:[I?B?(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",color:"green",children:"ID verified. Authentication accepted."}):(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",color:"label",children:"Swipe your ID card to authenticate yourself"}):(0,e.createComponentVNode)(2,t.Box,{textAlign:"center",color:"label",children:"Complete your current goal first!"}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,mt:2,textAlign:"center",content:"Request Secondary Goal",icon:"clipboard-list",disabled:!(B&&I),onClick:function(){function L(){return N("requestSecondaryGoal")}return L}()})]})})],4)}},9861:function(T,r,n){"use strict";r.__esModule=!0,r.RndBackupConsole=r.LinkMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.RndBackupConsole=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.network_name,l=c.has_disk,u=c.disk_name,s=c.linked,d=c.techs,v=c.last_timestamp;return(0,e.createComponentVNode)(2,o.Window,{width:900,height:600,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Device Info",children:[(0,e.createComponentVNode)(2,t.Box,{mb:2,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Network",children:s?(0,e.createComponentVNode)(2,t.Button,{content:m,icon:"unlink",selected:1,onClick:function(){function g(){return i("unlink")}return g}()}):"None"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Loaded Disk",children:l?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:u+" (Last backup: "+v+")",icon:"save",selected:1,onClick:function(){function g(){return i("eject_disk")}return g}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"sign-in-alt",content:"Save all",onClick:function(){function g(){return i("saveall2disk")}return g}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"sign-out-alt",content:"Load all",onClick:function(){function g(){return i("saveall2network")}return g}()})],4):"None"})]})}),!!s||(0,e.createComponentVNode)(2,b)]}),(0,e.createComponentVNode)(2,t.Box,{mt:2,children:(0,e.createComponentVNode)(2,t.Section,{title:"Tech Info",children:(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Tech Name"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network Level"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Disk Level"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Actions"})]}),Object.keys(d).map(function(g){return!(d[g].network_level>0||d[g].disk_level>0)||(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:d[g].name}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d[g].network_level||"None"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:d[g].disk_level||"None"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"sign-in-alt",content:"Load to network",disabled:!l||!s,onClick:function(){function C(){return i("savetech2network",{tech:g})}return C}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"sign-out-alt",content:"Load to disk",disabled:!l||!s,onClick:function(){function C(){return i("savetech2disk",{tech:g})}return C}()})]})]},g)})]})})})]})})}return y}(),b=r.LinkMenu=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.controllers;return(0,e.createComponentVNode)(2,t.Section,{title:"Setup Linkage",children:(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network Address"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network ID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Link"})]}),m.map(function(l){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:l.addr}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:l.net_id}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Link",icon:"link",onClick:function(){function u(){return i("linktonetworkcontroller",{target_controller:l.addr})}return u}()})})]},l.addr)})]})})}return y}()},37556:function(T,r,n){"use strict";r.__esModule=!0,r.DataDiskMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o="design",p="tech",b=function(c,m){var l=(0,a.useBackend)(m),u=l.data,s=l.act,d=u.disk_data;return d?(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Name",children:d.name}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Level",children:d.level}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Description",children:d.desc})]}),(0,e.createComponentVNode)(2,t.Box,{mt:"10px",children:(0,e.createComponentVNode)(2,t.Button,{content:"Upload to Database",icon:"arrow-up",onClick:function(){function v(){return s("updt_tech")}return v}()})})]}):null},y=function(c,m){var l=(0,a.useBackend)(m),u=l.data,s=l.act,d=u.disk_data;if(!d)return null;var v=d.name,g=d.lathe_types,C=d.materials,f=g.join(", ");return(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Name",children:v}),f?(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Lathe Types",children:f}):null,(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Required Materials"})]}),C.map(function(N){return(0,e.createComponentVNode)(2,t.Box,{children:["- ",(0,e.createVNode)(1,"span",null,N.name,0,{style:{"text-transform":"capitalize"}})," x ",N.amount]},N.name)}),(0,e.createComponentVNode)(2,t.Box,{mt:"10px",children:(0,e.createComponentVNode)(2,t.Button,{content:"Upload to Database",icon:"arrow-up",onClick:function(){function N(){return s("updt_design")}return N}()})})]})},S=function(c,m){var l=(0,a.useBackend)(m),u=l.act,s=l.data,d=s.disk_data;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.Section,Object.assign({buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button.Confirm,{content:"Erase",icon:"eraser",disabled:!d,onClick:function(){function v(){return u("erase_disk")}return v}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Eject",icon:"eject",onClick:function(){function v(){u("eject_disk")}return v}()})],4)},c)))},k=function(c,m){var l=(0,a.useBackend)(m),u=l.data,s=l.act,d=u.disk_type,v=u.to_copy,g=c.title;return(0,e.createComponentVNode)(2,S,{title:g,children:(0,e.createComponentVNode)(2,t.Box,{overflowY:"auto",overflowX:"hidden",maxHeight:"450px",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:v.sort(function(C,f){return C.name.localeCompare(f.name)}).map(function(C){var f=C.name,N=C.id;return(0,e.createComponentVNode)(2,t.LabeledList.Item,{noColon:!0,label:f,children:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-down",content:"Copy to Disk",onClick:function(){function V(){d===p?s("copy_tech",{id:N}):s("copy_design",{id:N})}return V}()})},N)})})})})},h=r.DataDiskMenu=function(){function i(c,m){var l=(0,a.useBackend)(m),u=l.data,s=u.disk_type,d=u.disk_data;if(!s)return(0,e.createComponentVNode)(2,t.Section,{title:"Data Disk",children:"No disk loaded."});switch(s){case o:return d?(0,e.createComponentVNode)(2,S,{title:"Design Disk",children:(0,e.createComponentVNode)(2,y)}):(0,e.createComponentVNode)(2,k,{title:"Design Disk"});case p:return d?(0,e.createComponentVNode)(2,S,{title:"Technology Disk",children:(0,e.createComponentVNode)(2,b)}):(0,e.createComponentVNode)(2,k,{title:"Technology Disk"});default:return(0,e.createFragment)([(0,e.createTextVNode)("UNRECOGNIZED DISK TYPE")],4)}}return i}()},58147:function(T,r,n){"use strict";r.__esModule=!0,r.DeconstructionMenu=void 0;var e=n(89005),a=n(35840),t=n(72253),o=n(36036),p=r.DeconstructionMenu=function(){function y(S,k){var h=(0,t.useBackend)(k),i=h.data,c=h.act,m=i.tech_levels,l=i.loaded_item,u=i.linked_destroy;return u?l?(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Section,{title:"Object Analysis",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{content:"Deconstruct",icon:"microscope",onClick:function(){function s(){c("deconstruct")}return s}()}),(0,e.createComponentVNode)(2,o.Button,{content:"Eject",icon:"eject",onClick:function(){function s(){c("eject_item")}return s}()})],4),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Name",children:l.name})})}),(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.Table,{id:"research-levels",children:[(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell),(0,e.createComponentVNode)(2,o.Table.Cell,{header:!0,children:"Research Field"}),(0,e.createComponentVNode)(2,o.Table.Cell,{header:!0,children:"Current Level"}),(0,e.createComponentVNode)(2,o.Table.Cell,{header:!0,children:"Object Level"}),(0,e.createComponentVNode)(2,o.Table.Cell,{header:!0,children:"New Level"})]}),m.map(function(s){return(0,e.createComponentVNode)(2,b,{techLevel:s},s.id)})]})})],4):(0,e.createComponentVNode)(2,o.Section,{title:"Deconstruction Menu",children:"No item loaded. Standing by..."}):(0,e.createComponentVNode)(2,o.Section,{title:"Deconstruction Menu",children:"NO DESTRUCTIVE ANALYZER LINKED TO CONSOLE"})}return y}(),b=function(S,k){var h=S.techLevel,i=h.name,c=h.desc,m=h.level,l=h.object_level,u=h.ui_icon,s=l!=null,d=s&&l>=m?Math.max(l,m+1):m;return(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{icon:"circle-info",tooltip:c})}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:u})," ",i]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:m}),s?(0,e.createComponentVNode)(2,o.Table.Cell,{children:l}):(0,e.createComponentVNode)(2,o.Table.Cell,{className:"research-level-no-effect",children:"-"}),(0,e.createComponentVNode)(2,o.Table.Cell,{className:(0,a.classes)([d!==m&&"upgraded-level"]),children:d})]})}},16830:function(T,r,n){"use strict";r.__esModule=!0,r.LatheCategory=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(52662),p=r.LatheCategory=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.data,i=k.act,c=h.category,m=h.matching_designs,l=h.menu,u=l===4,s=u?"build":"imprint";return(0,e.createComponentVNode)(2,t.Section,{title:c,children:[(0,e.createComponentVNode)(2,o.LatheMaterials),(0,e.createComponentVNode)(2,t.Table,{className:"RndConsole__LatheCategory__MatchingDesigns",children:m.map(function(d){var v=d.id,g=d.name,C=d.can_build,f=d.materials;return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"print",content:g,disabled:C<1,onClick:function(){function N(){return i(s,{id:v,amount:1})}return N}()})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:C>=5?(0,e.createComponentVNode)(2,t.Button,{content:"x5",onClick:function(){function N(){return i(s,{id:v,amount:5})}return N}()}):null}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:C>=10?(0,e.createComponentVNode)(2,t.Button,{content:"x10",onClick:function(){function N(){return i(s,{id:v,amount:10})}return N}()}):null}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.map(function(N){return(0,e.createFragment)([" | ",(0,e.createVNode)(1,"span",N.is_red?"color-red":null,[N.amount,(0,e.createTextVNode)(" "),N.name],0)],0)})})]},v)})})]})}return b}()},70497:function(T,r,n){"use strict";r.__esModule=!0,r.LatheChemicalStorage=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.LatheChemicalStorage=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.data,h=S.act,i=k.loaded_chemicals,c=k.menu===4;return(0,e.createComponentVNode)(2,t.Section,{title:"Chemical Storage",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Purge All",icon:"trash",onClick:function(){function m(){var l=c?"disposeallP":"disposeallI";h(l)}return m}()}),(0,e.createComponentVNode)(2,t.LabeledList,{children:i.map(function(m){var l=m.volume,u=m.name,s=m.id;return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"* "+l+" of "+u,children:(0,e.createComponentVNode)(2,t.Button,{content:"Purge",icon:"trash",onClick:function(){function d(){var v=c?"disposeP":"disposeI";h(v,{id:s})}return d}()})},s)})})]})}return p}()},70864:function(T,r,n){"use strict";r.__esModule=!0,r.LatheMainMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(52662),p=n(68198),b=r.LatheMainMenu=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.data,c=h.act,m=i.menu,l=i.categories,u=m===4?"Protolathe":"Circuit Imprinter";return(0,e.createComponentVNode)(2,t.Section,{title:u+" Menu",children:[(0,e.createComponentVNode)(2,o.LatheMaterials),(0,e.createComponentVNode)(2,p.LatheSearch),(0,e.createComponentVNode)(2,t.Divider),(0,e.createComponentVNode)(2,t.Flex,{wrap:"wrap",children:l.map(function(s){return(0,e.createComponentVNode)(2,t.Flex,{style:{"flex-basis":"50%","margin-bottom":"6px"},children:(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-right",content:s,onClick:function(){function d(){c("setCategory",{category:s})}return d}()})},s)})})]})}return y}()},42878:function(T,r,n){"use strict";r.__esModule=!0,r.LatheMaterialStorage=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.LatheMaterialStorage=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.data,h=S.act,i=k.loaded_materials;return(0,e.createComponentVNode)(2,t.Section,{className:"RndConsole__LatheMaterialStorage",title:"Material Storage",children:(0,e.createComponentVNode)(2,t.Table,{children:i.map(function(c){var m=c.id,l=c.amount,u=c.name,s=function(){function C(f){var N=k.menu===4?"lathe_ejectsheet":"imprinter_ejectsheet";h(N,{id:m,amount:f})}return C}(),d=Math.floor(l/2e3),v=l<1,g=d===1?"":"s";return(0,e.createComponentVNode)(2,t.Table.Row,{className:v?"color-grey":"color-yellow",children:[(0,e.createComponentVNode)(2,t.Table.Cell,{minWidth:"210px",children:["* ",l," of ",u]}),(0,e.createComponentVNode)(2,t.Table.Cell,{minWidth:"110px",children:["(",d," sheet",g,")"]}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:l>=2e3?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:"1x",icon:"eject",onClick:function(){function C(){return s(1)}return C}()}),(0,e.createComponentVNode)(2,t.Button,{content:"C",icon:"eject",onClick:function(){function C(){return s("custom")}return C}()}),l>=2e3*5?(0,e.createComponentVNode)(2,t.Button,{content:"5x",icon:"eject",onClick:function(){function C(){return s(5)}return C}()}):null,(0,e.createComponentVNode)(2,t.Button,{content:"All",icon:"eject",onClick:function(){function C(){return s(50)}return C}()})],0):null})]},m)})})})}return p}()},52662:function(T,r,n){"use strict";r.__esModule=!0,r.LatheMaterials=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.LatheMaterials=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.data,h=k.total_materials,i=k.max_materials,c=k.max_chemicals,m=k.total_chemicals;return(0,e.createComponentVNode)(2,t.Box,{className:"RndConsole__LatheMaterials",mb:"10px",children:(0,e.createComponentVNode)(2,t.Table,{width:"auto",children:[(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Material Amount:"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:h}),i?(0,e.createComponentVNode)(2,t.Table.Cell,{children:" / "+i}):null]}),(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:"Chemical Amount:"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:m}),c?(0,e.createComponentVNode)(2,t.Table.Cell,{children:" / "+c}):null]})]})})}return p}()},9681:function(T,r,n){"use strict";r.__esModule=!0,r.LatheMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(12644),p=n(70864),b=n(16830),y=n(42878),S=n(70497),k=["menu"];function h(u,s){if(u==null)return{};var d={};for(var v in u)if({}.hasOwnProperty.call(u,v)){if(s.includes(v))continue;d[v]=u[v]}return d}var i=t.Tabs.Tab,c=function(s,d){var v=(0,a.useBackend)(d),g=v.act,C=v.data,f=C.menu===o.MENU.LATHE?["nav_protolathe",C.submenu_protolathe]:["nav_imprinter",C.submenu_imprinter],N=f[0],V=f[1],B=s.menu,I=h(s,k);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,i,Object.assign({selected:V===B,onClick:function(){function L(){return g(N,{menu:B})}return L}()},I)))},m=function(s){switch(s){case o.PRINTER_MENU.MAIN:return(0,e.createComponentVNode)(2,p.LatheMainMenu);case o.PRINTER_MENU.SEARCH:return(0,e.createComponentVNode)(2,b.LatheCategory);case o.PRINTER_MENU.MATERIALS:return(0,e.createComponentVNode)(2,y.LatheMaterialStorage);case o.PRINTER_MENU.CHEMICALS:return(0,e.createComponentVNode)(2,S.LatheChemicalStorage)}},l=r.LatheMenu=function(){function u(s,d){var v=(0,a.useBackend)(d),g=v.data,C=g.menu,f=g.linked_lathe,N=g.linked_imprinter;return C===o.MENU.LATHE&&!f?(0,e.createComponentVNode)(2,t.Box,{children:"NO PROTOLATHE LINKED TO CONSOLE"}):C===o.MENU.IMPRINTER&&!N?(0,e.createComponentVNode)(2,t.Box,{children:"NO CIRCUIT IMPRITER LINKED TO CONSOLE"}):(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,c,{menu:o.PRINTER_MENU.MAIN,icon:"bars",children:"Main Menu"}),(0,e.createComponentVNode)(2,c,{menu:o.PRINTER_MENU.MATERIALS,icon:"layer-group",children:"Materials"}),(0,e.createComponentVNode)(2,c,{menu:o.PRINTER_MENU.CHEMICALS,icon:"flask-vial",children:"Chemicals"})]}),m(g.menu===o.MENU.LATHE?g.submenu_protolathe:g.submenu_imprinter)]})}return u}()},68198:function(T,r,n){"use strict";r.__esModule=!0,r.LatheSearch=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.LatheSearch=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.act;return(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Input,{placeholder:"Search...",onEnter:function(){function h(i,c){return k("search",{to_search:c})}return h}()})})}return p}()},81421:function(T,r,n){"use strict";r.__esModule=!0,r.LinkMenu=void 0;var e=n(89005),a=n(72253),t=n(98595),o=n(36036),p=r.LinkMenu=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.controllers;return(0,e.createComponentVNode)(2,t.Window,{width:800,height:550,children:(0,e.createComponentVNode)(2,t.Window.Content,{children:(0,e.createComponentVNode)(2,o.Section,{title:"Setup Linkage",children:(0,e.createComponentVNode)(2,o.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,o.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Network Address"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Network ID"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Link"})]}),c.map(function(m){return(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:m.addr}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:m.net_id}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{content:"Link",icon:"link",onClick:function(){function l(){return h("linktonetworkcontroller",{target_controller:m.addr})}return l}()})})]},m.addr)})]})})})})}return b}()},6256:function(T,r,n){"use strict";r.__esModule=!0,r.SettingsMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.SettingsMenu=function(){function y(S,k){return(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,p),(0,e.createComponentVNode)(2,b)]})}return y}(),p=function(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.sync,l=c.admin;return(0,e.createComponentVNode)(2,t.Section,{title:"Settings",children:(0,e.createComponentVNode)(2,t.Flex,{direction:"column",align:"flex-start",children:(0,e.createComponentVNode)(2,t.Button,{color:"red",icon:"unlink",content:"Disconnect from Research Network",onClick:function(){function u(){i("unlink")}return u}()})})})},b=function(S,k){var h=(0,a.useBackend)(k),i=h.data,c=h.act,m=i.linked_destroy,l=i.linked_lathe,u=i.linked_imprinter;return(0,e.createComponentVNode)(2,t.Section,{title:"Linked Devices",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"link",content:"Re-sync with Nearby Devices",onClick:function(){function s(){return c("find_device")}return s}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Destructive Analyzer",children:(0,e.createComponentVNode)(2,t.Button,{icon:"unlink",disabled:!m,content:m?"Unlink":"Undetected",onClick:function(){function s(){return c("disconnect",{item:"destroy"})}return s}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Protolathe",children:(0,e.createComponentVNode)(2,t.Button,{icon:"unlink",disabled:!l,content:l?"Unlink":"Undetected",onClick:function(){function s(){c("disconnect",{item:"lathe"})}return s}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Circuit Imprinter",children:(0,e.createComponentVNode)(2,t.Button,{icon:"unlink",disabled:!u,content:u?"Unlink":"Undetected",onClick:function(){function s(){return c("disconnect",{item:"imprinter"})}return s}()})})]})})}},12644:function(T,r,n){"use strict";r.__esModule=!0,r.RndConsole=r.PRINTER_MENU=r.MENU=void 0;var e=n(89005),a=n(72253),t=n(98595),o=n(36036),p=n(35840),b=n(37556),y=n(9681),S=n(81421),k=n(6256),h=n(58147),i=["menu"];function c(f,N){if(f==null)return{};var V={};for(var B in f)if({}.hasOwnProperty.call(f,B)){if(N.includes(B))continue;V[B]=f[B]}return V}var m=o.Tabs.Tab,l=r.MENU={MAIN:0,DISK:2,DESTROY:3,LATHE:4,IMPRINTER:5,SETTINGS:6},u=r.PRINTER_MENU={MAIN:0,SEARCH:1,MATERIALS:2,CHEMICALS:3},s=function(N){switch(N){case l.MAIN:return(0,e.createComponentVNode)(2,C);case l.DISK:return(0,e.createComponentVNode)(2,b.DataDiskMenu);case l.DESTROY:return(0,e.createComponentVNode)(2,h.DeconstructionMenu);case l.LATHE:case l.IMPRINTER:return(0,e.createComponentVNode)(2,y.LatheMenu);case l.SETTINGS:return(0,e.createComponentVNode)(2,k.SettingsMenu);default:return"UNKNOWN MENU"}},d=function(N,V){var B=(0,a.useBackend)(V),I=B.act,L=B.data,w=L.menu,A=N.menu,x=c(N,i);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,m,Object.assign({selected:w===A,onClick:function(){function E(){return I("nav",{menu:A})}return E}()},x)))},v=r.RndConsole=function(){function f(N,V){var B=(0,a.useBackend)(V),I=B.act,L=B.data;if(!L.linked)return(0,e.createComponentVNode)(2,S.LinkMenu);var w=L.menu,A=L.linked_destroy,x=L.linked_lathe,E=L.linked_imprinter,P=L.wait_message;return(0,e.createComponentVNode)(2,t.Window,{width:800,height:550,children:(0,e.createComponentVNode)(2,t.Window.Content,{children:(0,e.createComponentVNode)(2,o.Box,{className:"RndConsole",children:[(0,e.createComponentVNode)(2,o.Tabs,{children:[(0,e.createComponentVNode)(2,d,{icon:"flask",menu:l.MAIN,children:"Research"}),!!A&&(0,e.createComponentVNode)(2,d,{icon:"microscope",menu:l.DESTROY,children:"Analyze"}),!!x&&(0,e.createComponentVNode)(2,d,{icon:"print",menu:l.LATHE,children:"Protolathe"}),!!E&&(0,e.createComponentVNode)(2,d,{icon:"memory",menu:l.IMPRINTER,children:"Imprinter"}),(0,e.createComponentVNode)(2,d,{icon:"floppy-disk",menu:l.DISK,children:"Disk"}),(0,e.createComponentVNode)(2,d,{icon:"cog",menu:l.SETTINGS,children:"Settings"})]}),s(w),(0,e.createComponentVNode)(2,g)]})})})}return f}(),g=function(N,V){var B=(0,a.useBackend)(V),I=B.data,L=I.wait_message;return L?(0,e.createComponentVNode)(2,o.Box,{className:"RndConsole__Overlay",children:(0,e.createComponentVNode)(2,o.Box,{className:"RndConsole__Overlay__Wrapper",children:(0,e.createComponentVNode)(2,o.NoticeBox,{color:"black",children:L})})}):null},C=function(N,V){var B=(0,a.useBackend)(V),I=B.data,L=I.tech_levels;return(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.Table,{id:"research-levels",children:[(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell),(0,e.createComponentVNode)(2,o.Table.Cell,{header:!0,children:"Research Field"}),(0,e.createComponentVNode)(2,o.Table.Cell,{header:!0,children:"Level"})]}),L.map(function(w){var A=w.id,x=w.name,E=w.desc,P=w.level,D=w.ui_icon;return(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{icon:"circle-info",tooltip:E})}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:D})," ",x]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:P})]},A)})]})})}},29205:function(T,r,n){"use strict";r.__esModule=!0,r.RndNetController=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),p=n(98595),b=r.RndNetController=function(){function k(h,i){var c=(0,t.useBackend)(i),m=c.act,l=c.data,u=l.ion,s=(0,t.useLocalState)(i,"mainTabIndex",0),d=s[0],v=s[1],g=function(){function C(f){switch(f){case 0:return(0,e.createComponentVNode)(2,y);case 1:return(0,e.createComponentVNode)(2,S);default:return"SOMETHING WENT VERY WRONG PLEASE AHELP"}}return C}();return(0,e.createComponentVNode)(2,p.Window,{width:900,height:600,children:(0,e.createComponentVNode)(2,p.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,o.Tabs,{children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"wrench",selected:d===0,onClick:function(){function C(){return v(0)}return C}(),children:"Network Management"},"ConfigPage"),(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"floppy-disk",selected:d===1,onClick:function(){function C(){return v(1)}return C}(),children:"Design Management"},"DesignPage")]}),g(d)]})})}return k}(),y=function(h,i){var c=(0,t.useBackend)(i),m=c.act,l=c.data,u=(0,t.useLocalState)(i,"filterType","ALL"),s=u[0],d=u[1],v=l.network_password,g=l.network_name,C=l.devices,f=[];f.push(s),s==="MSC"&&(f.push("BCK"),f.push("PGN"));var N=s==="ALL"?C:C.filter(function(V){return f.indexOf(V.dclass)>-1});return(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Section,{title:"Network Configuration",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Network Name",children:(0,e.createComponentVNode)(2,o.Button,{content:g||"Unset",selected:g,icon:"edit",onClick:function(){function V(){return m("network_name")}return V}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Network Password",children:(0,e.createComponentVNode)(2,o.Button,{content:v||"Unset",selected:v,icon:"lock",onClick:function(){function V(){return m("network_password")}return V}()})})]})}),(0,e.createComponentVNode)(2,o.Section,{title:"Connected Devices",children:[(0,e.createComponentVNode)(2,o.Tabs,{children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:s==="ALL",onClick:function(){function V(){return d("ALL")}return V}(),icon:"network-wired",children:"All Devices"},"AllDevices"),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:s==="SRV",onClick:function(){function V(){return d("SRV")}return V}(),icon:"server",children:"R&D Servers"},"RNDServers"),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:s==="RDC",onClick:function(){function V(){return d("RDC")}return V}(),icon:"desktop",children:"R&D Consoles"},"RDConsoles"),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:s==="MFB",onClick:function(){function V(){return d("MFB")}return V}(),icon:"industry",children:"Exosuit Fabricators"},"Mechfabs"),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:s==="MSC",onClick:function(){function V(){return d("MSC")}return V}(),icon:"microchip",children:"Miscellaneous Devices"},"Misc")]}),(0,e.createComponentVNode)(2,o.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,o.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Device Name"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Device ID"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Unlink"})]}),N.map(function(V){return(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:V.name}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:V.id}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{content:"Unlink",icon:"unlink",color:"red",onClick:function(){function B(){return m("unlink_device",{dclass:V.dclass,uid:V.id})}return B}()})})]},V.id)})]})]})],4)},S=function(h,i){var c=(0,t.useBackend)(i),m=c.act,l=c.data,u=l.designs,s=(0,t.useLocalState)(i,"searchText",""),d=s[0],v=s[1];return(0,e.createComponentVNode)(2,o.Section,{title:"Design Management",children:[(0,e.createComponentVNode)(2,o.Input,{fluid:!0,placeholder:"Search for designs",mb:2,onInput:function(){function g(C,f){return v(f)}return g}()}),u.filter((0,a.createSearch)(d,function(g){return g.name})).map(function(g){return(0,e.createComponentVNode)(2,o.Button.Checkbox,{fluid:!0,content:g.name,checked:!g.blacklisted,onClick:function(){function C(){return m(g.blacklisted?"unblacklist_design":"blacklist_design",{d_uid:g.uid})}return C}()},g.name)})]})}},63315:function(T,r,n){"use strict";r.__esModule=!0,r.RndServer=void 0;var e=n(89005),a=n(72253),t=n(44879),o=n(36036),p=n(98595),b=r.RndServer=function(){function k(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.active,s=l.network_name;return(0,e.createComponentVNode)(2,p.Window,{width:600,height:500,resizable:!0,children:(0,e.createComponentVNode)(2,p.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,o.Section,{title:"Server Configuration",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Machine power",children:(0,e.createComponentVNode)(2,o.Button,{content:u?"On":"Off",selected:u,icon:"power-off",onClick:function(){function d(){return m("toggle_active")}return d}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Link status",children:s===null?(0,e.createComponentVNode)(2,o.Box,{color:"red",children:"Unlinked"}):(0,e.createComponentVNode)(2,o.Box,{color:"green",children:"Linked"})})]})}),s===null?(0,e.createComponentVNode)(2,S):(0,e.createComponentVNode)(2,y)]})})}return k}(),y=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.network_name;return(0,e.createComponentVNode)(2,o.Section,{title:"Network Info",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Connected network ID",children:u}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Unlink",children:(0,e.createComponentVNode)(2,o.Button,{content:"Unlink",icon:"unlink",color:"red",onClick:function(){function s(){return m("unlink")}return s}()})})]})})},S=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.controllers;return(0,e.createComponentVNode)(2,o.Section,{title:"Detected Cores",children:(0,e.createComponentVNode)(2,o.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,o.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Network ID"}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:"Link"})]}),u.map(function(s){return(0,e.createComponentVNode)(2,o.Table.Row,{children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:s.netname}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{content:"Link",icon:"link",onClick:function(){function d(){return m("link",{addr:s.addr})}return d}()})})]},s.addr)})]})})}},26109:function(T,r,n){"use strict";r.__esModule=!0,r.RobotSelfDiagnosis=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(25328),b=function(k,h){var i=k/h;return i<=.2?"good":i<=.5?"average":"bad"},y=r.RobotSelfDiagnosis=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.data,m=c.component_data;return(0,e.createComponentVNode)(2,o.Window,{width:280,height:480,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:m.map(function(l,u){return(0,e.createComponentVNode)(2,t.Section,{title:(0,p.capitalize)(l.name),children:l.installed<=0?(0,e.createComponentVNode)(2,t.NoticeBox,{m:-.5,height:3.5,color:"red",style:{"font-style":"normal"},children:(0,e.createComponentVNode)(2,t.Flex,{height:"100%",children:(0,e.createComponentVNode)(2,t.Flex.Item,{grow:1,textAlign:"center",align:"center",color:"#e8e8e8",children:l.installed===-1?"Destroyed":"Missing"})})}):(0,e.createComponentVNode)(2,t.Flex,{children:[(0,e.createComponentVNode)(2,t.Flex.Item,{width:"72%",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Brute Damage",color:b(l.brute_damage,l.max_damage),children:l.brute_damage}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Burn Damage",color:b(l.electronic_damage,l.max_damage),children:l.electronic_damage})]})}),(0,e.createComponentVNode)(2,t.Flex.Item,{width:"50%",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Powered",color:l.powered?"good":"bad",children:l.powered?"Yes":"No"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Enabled",color:l.status?"good":"bad",children:l.status?"Yes":"No"})]})})]})},u)})})})}return S}()},97997:function(T,r,n){"use strict";r.__esModule=!0,r.RoboticsControlConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.RoboticsControlConsole=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.can_hack,l=c.safety,u=c.show_lock_all,s=c.cyborgs,d=s===void 0?[]:s;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:460,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[!!u&&(0,e.createComponentVNode)(2,t.Section,{title:"Emergency Lock Down",children:[(0,e.createComponentVNode)(2,t.Button,{icon:l?"lock":"unlock",content:l?"Disable Safety":"Enable Safety",selected:l,onClick:function(){function v(){return i("arm",{})}return v}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"lock",disabled:l,content:"Lock ALL Cyborgs",color:"bad",onClick:function(){function v(){return i("masslock",{})}return v}()})]}),(0,e.createComponentVNode)(2,b,{cyborgs:d,can_hack:m})]})})}return y}(),b=function(S,k){var h=S.cyborgs,i=S.can_hack,c=(0,a.useBackend)(k),m=c.act,l=c.data,u="Detonate";return l.detonate_cooldown>0&&(u+=" ("+l.detonate_cooldown+"s)"),h.length?h.map(function(s){return(0,e.createComponentVNode)(2,t.Section,{title:s.name,buttons:(0,e.createFragment)([!!s.hackable&&!s.emagged&&(0,e.createComponentVNode)(2,t.Button,{icon:"terminal",content:"Hack",color:"bad",onClick:function(){function d(){return m("hackbot",{uid:s.uid})}return d}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:s.locked_down?"unlock":"lock",color:s.locked_down?"good":"default",content:s.locked_down?"Release":"Lockdown",disabled:!l.auth,onClick:function(){function d(){return m("stopbot",{uid:s.uid})}return d}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"bomb",content:u,disabled:!l.auth||l.detonate_cooldown>0,color:"bad",onClick:function(){function d(){return m("killbot",{uid:s.uid})}return d}()})],0),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:(0,e.createComponentVNode)(2,t.Box,{color:s.status?"bad":s.locked_down?"average":"good",children:s.status?"Not Responding":s.locked_down?"Locked Down":"Nominal"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Location",children:(0,e.createComponentVNode)(2,t.Box,{children:s.locstring})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Integrity",children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:s.health>50?"good":"bad",value:s.health/100})}),typeof s.charge=="number"&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cell Charge",children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:s.charge>30?"good":"bad",value:s.charge/100})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cell Capacity",children:(0,e.createComponentVNode)(2,t.Box,{color:s.cell_capacity<3e4?"average":"good",children:s.cell_capacity})})],4)||(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cell",children:(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:"No Power Cell"})}),!!s.is_hacked&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Safeties",children:(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:"DISABLED"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Module",children:s.module}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Master AI",children:(0,e.createComponentVNode)(2,t.Box,{color:s.synchronization?"default":"average",children:s.synchronization||"None"})})]})},s.uid)}):(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No cyborg units detected within access parameters."})}},54431:function(T,r,n){"use strict";r.__esModule=!0,r.Safe=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.Safe=function(){function k(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.dial,s=l.open,d=l.locked,v=l.contents;return(0,e.createComponentVNode)(2,o.Window,{theme:"safe",width:600,height:800,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Box,{className:"Safe--engraving",children:[(0,e.createComponentVNode)(2,b),(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Box,{className:"Safe--engraving--hinge",top:"25%"}),(0,e.createComponentVNode)(2,t.Box,{className:"Safe--engraving--hinge",top:"75%"})]}),(0,e.createComponentVNode)(2,t.Icon,{className:"Safe--engraving--arrow",name:"long-arrow-alt-down",size:"3"}),(0,e.createVNode)(1,"br"),s?(0,e.createComponentVNode)(2,y):(0,e.createComponentVNode)(2,t.Box,{as:"img",className:"Safe--dial",src:"safe_dial.png",style:{transform:"rotate(-"+3.6*u+"deg)","z-index":0}})]}),!s&&(0,e.createComponentVNode)(2,S)]})})}return k}(),b=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.dial,s=l.open,d=l.locked,v=function(C,f){return(0,e.createComponentVNode)(2,t.Button,{disabled:s||f&&!d,icon:"arrow-"+(f?"right":"left"),content:(f?"Right":"Left")+" "+C,iconRight:f,onClick:function(){function N(){return m(f?"turnleft":"turnright",{num:C})}return N}(),style:{"z-index":10}})};return(0,e.createComponentVNode)(2,t.Box,{className:"Safe--dialer",children:[(0,e.createComponentVNode)(2,t.Button,{disabled:d,icon:s?"lock":"lock-open",content:s?"Close":"Open",mb:"0.5rem",onClick:function(){function g(){return m("open")}return g}()}),(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Box,{position:"absolute",children:[v(50),v(10),v(1)]}),(0,e.createComponentVNode)(2,t.Box,{className:"Safe--dialer--right",position:"absolute",right:"5px",children:[v(1,!0),v(10,!0),v(50,!0)]}),(0,e.createComponentVNode)(2,t.Box,{className:"Safe--dialer--number",children:u})]})},y=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.contents;return(0,e.createComponentVNode)(2,t.Box,{className:"Safe--contents",overflow:"auto",children:u.map(function(s,d){return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{mb:"0.5rem",onClick:function(){function v(){return m("retrieve",{index:d+1})}return v}(),children:[(0,e.createComponentVNode)(2,t.Box,{as:"img",src:s.sprite+".png",verticalAlign:"middle",ml:"-6px",mr:"0.5rem"}),s.name]}),(0,e.createVNode)(1,"br")],4,s)})})},S=function(h,i){return(0,e.createComponentVNode)(2,t.Section,{className:"Safe--help",title:"Safe opening instructions (because you all keep forgetting)",children:[(0,e.createComponentVNode)(2,t.Box,{children:["1. Turn the dial left to the first number.",(0,e.createVNode)(1,"br"),"2. Turn the dial right to the second number.",(0,e.createVNode)(1,"br"),"3. Continue repeating this process for each number, switching between left and right each time.",(0,e.createVNode)(1,"br"),"4. Open the safe."]}),(0,e.createComponentVNode)(2,t.Box,{bold:!0,children:"To lock fully, turn the dial to the left after closing the safe."})]})}},29740:function(T,r,n){"use strict";r.__esModule=!0,r.SatelliteControl=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.SatelliteControl=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.satellites,m=i.notice,l=i.meteor_shield,u=i.meteor_shield_coverage,s=i.meteor_shield_coverage_max,d=i.meteor_shield_coverage_percentage;return(0,e.createComponentVNode)(2,o.Window,{width:475,height:400,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[l&&(0,e.createComponentVNode)(2,t.Section,{title:"Station Shield Coverage",children:(0,e.createComponentVNode)(2,t.ProgressBar,{color:d>=100?"good":"average",value:u,maxValue:s,children:[d," %"]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Satellite Network Control",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[m&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Alert",color:"red",children:i.notice}),c.map(function(v){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"#"+v.id,children:[v.mode," ",(0,e.createComponentVNode)(2,t.Button,{content:v.active?"Deactivate":"Activate",icon:"arrow-circle-right",onClick:function(){function g(){return h("toggle",{id:v.id})}return g}()})]},v.id)})]})})]})})}return b}()},44162:function(T,r,n){"use strict";r.__esModule=!0,r.SecureStorage=void 0;var e=n(89005),a=n(35840),t=n(72253),o=n(36036),p=n(98595),b=n(36352),y=n(92986),S=r.SecureStorage=function(){function c(m,l){return(0,e.createComponentVNode)(2,p.Window,{theme:"securestorage",height:500,width:280,children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,h)})})})})}return c}(),k=function(m,l){var u=(0,t.useBackend)(l),s=u.act,d=window.event?m.which:m.keyCode;if(d===y.KEY_ENTER){m.preventDefault(),s("keypad",{digit:"E"});return}if(d===y.KEY_ESCAPE){m.preventDefault(),s("keypad",{digit:"C"});return}if(d===y.KEY_BACKSPACE){m.preventDefault(),s("backspace");return}if(d>=y.KEY_0&&d<=y.KEY_9){m.preventDefault(),s("keypad",{digit:d-y.KEY_0});return}if(d>=y.KEY_NUMPAD_0&&d<=y.KEY_NUMPAD_9){m.preventDefault(),s("keypad",{digit:d-y.KEY_NUMPAD_0});return}},h=function(m,l){var u=(0,t.useBackend)(l),s=u.act,d=u.data,v=d.locked,g=d.no_passcode,C=d.emagged,f=d.user_entered_code,N=[["1","2","3"],["4","5","6"],["7","8","9"],["C","0","E"]],V=g?"":v?"bad":"good";return(0,e.createComponentVNode)(2,o.Section,{fill:!0,onKeyDown:function(){function B(I){return k(I,l)}return B}(),children:[(0,e.createComponentVNode)(2,o.Stack.Item,{height:7.3,children:(0,e.createComponentVNode)(2,o.Box,{className:(0,a.classes)(["SecureStorage__displayBox","SecureStorage__displayBox--"+V]),height:"100%",children:C?"ERROR":f})}),(0,e.createComponentVNode)(2,o.Table,{children:N.map(function(B){return(0,e.createComponentVNode)(2,b.TableRow,{children:B.map(function(I){return(0,e.createComponentVNode)(2,b.TableCell,{children:(0,e.createComponentVNode)(2,i,{number:I})},I)})},B[0])})})]})},i=function(m,l){var u=(0,t.useBackend)(l),s=u.act,d=u.data,v=m.number;return(0,e.createComponentVNode)(2,o.Button,{fluid:!0,bold:!0,mb:"6px",content:v,textAlign:"center",fontSize:"60px",lineHeight:1.25,width:"80px",className:(0,a.classes)(["SecureStorage__Button","SecureStorage__Button--keypad","SecureStorage__Button--"+v]),onClick:function(){function g(){return s("keypad",{digit:v})}return g}()})}},6272:function(T,r,n){"use strict";r.__esModule=!0,r.SecurityRecords=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),p=n(98595),b=n(3939),y=n(321),S=n(5485),k=n(22091),h={"*Execute*":"execute","*Arrest*":"arrest",Incarcerated:"incarcerated",Parolled:"parolled",Released:"released",Demote:"demote",Search:"search",Monitor:"monitor"},i=function(f,N){(0,b.modalOpen)(f,"edit",{field:N.edit,value:N.value})},c=r.SecurityRecords=function(){function C(f,N){var V=(0,t.useBackend)(N),B=V.act,I=V.data,L=I.loginState,w=I.currentPage,A;if(L.logged_in)w===1?A=(0,e.createComponentVNode)(2,l):w===2&&(A=(0,e.createComponentVNode)(2,d));else return(0,e.createComponentVNode)(2,p.Window,{theme:"security",width:800,height:900,children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,S.LoginScreen)})});return(0,e.createComponentVNode)(2,p.Window,{theme:"security",width:800,height:900,children:[(0,e.createComponentVNode)(2,b.ComplexModal),(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,y.LoginInfo),(0,e.createComponentVNode)(2,k.TemporaryNotice),(0,e.createComponentVNode)(2,m),A]})})]})}return C}(),m=function(f,N){var V=(0,t.useBackend)(N),B=V.act,I=V.data,L=I.currentPage,w=I.general;return(0,e.createComponentVNode)(2,o.Stack.Item,{m:0,children:(0,e.createComponentVNode)(2,o.Tabs,{children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"list",selected:L===1,onClick:function(){function A(){return B("page",{page:1})}return A}(),children:"List Records"}),L===2&&w&&!w.empty&&(0,e.createComponentVNode)(2,o.Tabs.Tab,{icon:"file",selected:L===2,children:["Record: ",w.fields[0].value]})]})})},l=function(f,N){var V=(0,t.useBackend)(N),B=V.act,I=V.data,L=I.records,w=(0,t.useLocalState)(N,"searchText",""),A=w[0],x=w[1],E=(0,t.useLocalState)(N,"sortId","name"),P=E[0],D=E[1],M=(0,t.useLocalState)(N,"sortOrder",!0),O=M[0],R=M[1];return(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,s)}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,mt:.5,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,o.Table,{className:"SecurityRecords__list",children:[(0,e.createComponentVNode)(2,o.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,u,{id:"name",children:"Name"}),(0,e.createComponentVNode)(2,u,{id:"id",children:"ID"}),(0,e.createComponentVNode)(2,u,{id:"rank",children:"Assignment"}),(0,e.createComponentVNode)(2,u,{id:"fingerprint",children:"Fingerprint"}),(0,e.createComponentVNode)(2,u,{id:"status",children:"Criminal Status"})]}),L.filter((0,a.createSearch)(A,function(F){return F.name+"|"+F.id+"|"+F.rank+"|"+F.fingerprint+"|"+F.status})).sort(function(F,W){var U=O?1:-1;return F[P].localeCompare(W[P])*U}).map(function(F){return(0,e.createComponentVNode)(2,o.Table.Row,{className:"SecurityRecords__listRow--"+h[F.status],onClick:function(){function W(){return B("view",{uid_gen:F.uid_gen,uid_sec:F.uid_sec})}return W}(),children:[(0,e.createComponentVNode)(2,o.Table.Cell,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"user"})," ",F.name]}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:F.id}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:F.rank}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:F.fingerprint}),(0,e.createComponentVNode)(2,o.Table.Cell,{children:F.status})]},F.id)})]})})})],4)},u=function(f,N){var V=(0,t.useLocalState)(N,"sortId","name"),B=V[0],I=V[1],L=(0,t.useLocalState)(N,"sortOrder",!0),w=L[0],A=L[1],x=f.id,E=f.children;return(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Table.Cell,{children:(0,e.createComponentVNode)(2,o.Button,{color:B!==x&&"transparent",fluid:!0,onClick:function(){function P(){B===x?A(!w):(I(x),A(!0))}return P}(),children:[E,B===x&&(0,e.createComponentVNode)(2,o.Icon,{name:w?"sort-up":"sort-down",ml:"0.25rem;"})]})})})},s=function(f,N){var V=(0,t.useBackend)(N),B=V.act,I=V.data,L=I.isPrinting,w=(0,t.useLocalState)(N,"searchText",""),A=w[0],x=w[1];return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{ml:"0.25rem",content:"New Record",icon:"plus",onClick:function(){function E(){return B("new_general")}return E}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Button,{disabled:L,icon:L?"spinner":"print",iconSpin:!!L,content:"Print Cell Log",onClick:function(){function E(){return(0,b.modalOpen)(N,"print_cell_log")}return E}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Input,{placeholder:"Search by Name, ID, Assignment, Fingerprint, Status",fluid:!0,onInput:function(){function E(P,D){return x(D)}return E}()})})]})},d=function(f,N){var V=(0,t.useBackend)(N),B=V.act,I=V.data,L=I.isPrinting,w=I.general,A=I.security;return!w||!w.fields?(0,e.createComponentVNode)(2,o.Box,{color:"bad",children:"General records lost!"}):(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"General Data",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{disabled:L,icon:L?"spinner":"print",iconSpin:!!L,content:"Print Record",onClick:function(){function x(){return B("print_record")}return x}()}),(0,e.createComponentVNode)(2,o.Button.Confirm,{icon:"trash",tooltip:"WARNING: This will also delete the Security and Medical records associated with this crew member!",tooltipPosition:"bottom-start",content:"Delete Record",onClick:function(){function x(){return B("delete_general")}return x}()})],4),children:(0,e.createComponentVNode)(2,v)})}),!A||!A.fields?(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,color:"bad",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,title:"Security Data",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"pen",content:"Create New Record",onClick:function(){function x(){return B("new_security")}return x}()}),children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{bold:!0,grow:!0,textAlign:"center",fontSize:1.75,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,o.Icon.Stack,{children:[(0,e.createComponentVNode)(2,o.Icon,{name:"scroll",size:5,color:"gray"}),(0,e.createComponentVNode)(2,o.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"Security records lost!"]})})})}):(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Security Data",buttons:(0,e.createComponentVNode)(2,o.Button.Confirm,{icon:"trash",disabled:A.empty,content:"Delete Record",onClick:function(){function x(){return B("delete_security")}return x}()}),children:(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:A.fields.map(function(x,E){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:x.field,preserveWhitespace:!0,children:[(0,a.decodeHtmlEntities)(x.value),!!x.edit&&(0,e.createComponentVNode)(2,o.Button,{icon:"pen",ml:"0.5rem",mb:x.line_break?"1rem":"initial",onClick:function(){function P(){return i(N,x)}return P}()})]},E)})})})})}),(0,e.createComponentVNode)(2,g)],4)],0)},v=function(f,N){var V=(0,t.useBackend)(N),B=V.data,I=B.general;return!I||!I.fields?(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,color:"bad",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,children:"General records lost!"})})}):(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.LabeledList,{children:I.fields.map(function(L,w){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:L.field,preserveWhitespace:!0,children:[(0,a.decodeHtmlEntities)(""+L.value),!!L.edit&&(0,e.createComponentVNode)(2,o.Button,{icon:"pen",ml:"0.5rem",mb:L.line_break?"1rem":"initial",onClick:function(){function A(){return i(N,L)}return A}()})]},w)})})}),!!I.has_photos&&I.photos.map(function(L,w){return(0,e.createComponentVNode)(2,o.Stack.Item,{inline:!0,textAlign:"center",color:"label",ml:0,children:[(0,e.createVNode)(1,"img",null,null,1,{src:L,style:{width:"96px","margin-top":"5rem","margin-bottom":"0.5rem","-ms-interpolation-mode":"nearest-neighbor","image-rendering":"pixelated"}}),(0,e.createVNode)(1,"br"),"Photo #",w+1]},w)})]})},g=function(f,N){var V=(0,t.useBackend)(N),B=V.act,I=V.data,L=I.security;return(0,e.createComponentVNode)(2,o.Stack.Item,{height:"150px",children:(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Comments/Log",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:"comment",content:"Add Entry",onClick:function(){function w(){return(0,b.modalOpen)(N,"comment_add")}return w}()}),children:L.comments.length===0?(0,e.createComponentVNode)(2,o.Box,{color:"label",children:"No comments found."}):L.comments.map(function(w,A){return(0,e.createComponentVNode)(2,o.Box,{preserveWhitespace:!0,children:[(0,e.createComponentVNode)(2,o.Box,{color:"label",inline:!0,children:w.header||"Auto-generated"}),(0,e.createVNode)(1,"br"),w.text||w,(0,e.createComponentVNode)(2,o.Button,{icon:"comment-slash",color:"bad",ml:"0.5rem",onClick:function(){function x(){return B("comment_delete",{id:A+1})}return x}()})]},A)})})})}},5099:function(T,r,n){"use strict";r.__esModule=!0,r.SeedExtractor=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),p=n(98595),b=n(3939);function y(u,s){var d=typeof Symbol!="undefined"&&u[Symbol.iterator]||u["@@iterator"];if(d)return(d=d.call(u)).next.bind(d);if(Array.isArray(u)||(d=S(u))||s&&u&&typeof u.length=="number"){d&&(u=d);var v=0;return function(){return v>=u.length?{done:!0}:{done:!1,value:u[v++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function S(u,s){if(u){if(typeof u=="string")return k(u,s);var d={}.toString.call(u).slice(8,-1);return d==="Object"&&u.constructor&&(d=u.constructor.name),d==="Map"||d==="Set"?Array.from(u):d==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(d)?k(u,s):void 0}}function k(u,s){(s==null||s>u.length)&&(s=u.length);for(var d=0,v=Array(s);d=A},g=function(w,A){return w<=A},C=s.split(" "),f=[],N=function(){var w=I.value,A=w.split(":");if(A.length===0)return 0;if(A.length===1)return f.push(function(P){return(P.name+" ("+P.variant+")").toLocaleLowerCase().includes(A[0].toLocaleLowerCase())}),0;if(A.length>2)return{v:function(){function P(D){return!1}return P}()};var x,E=d;if(A[1][A[1].length-1]==="-"?(E=g,x=Number(A[1].substring(0,A[1].length-1))):A[1][A[1].length-1]==="+"?(E=v,x=Number(A[1].substring(0,A[1].length-1))):x=Number(A[1]),isNaN(x))return{v:function(){function P(D){return!1}return P}()};switch(A[0].toLocaleLowerCase()){case"l":case"life":case"lifespan":f.push(function(P){return E(P.lifespan,x)});break;case"e":case"end":case"endurance":f.push(function(P){return E(P.endurance,x)});break;case"m":case"mat":case"maturation":f.push(function(P){return E(P.maturation,x)});break;case"pr":case"prod":case"production":f.push(function(P){return E(P.production,x)});break;case"y":case"yield":f.push(function(P){return E(P.yield,x)});break;case"po":case"pot":case"potency":f.push(function(P){return E(P.potency,x)});break;case"s":case"stock":case"c":case"count":case"a":case"amount":f.push(function(P){return E(P.amount,x)});break;default:return{v:function(){function P(D){return!1}return P}()}}},V,B=y(C),I;!(I=B()).done;)if(V=N(),V!==0&&V)return V.v;return function(L){for(var w=0,A=f;w=1?Number(E):1)}return A}()})]})]})}},2916:function(T,r,n){"use strict";r.__esModule=!0,r.ShuttleConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.ShuttleConsole=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data;return(0,e.createComponentVNode)(2,o.Window,{width:350,height:150,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Location",children:i.status?i.status:(0,e.createComponentVNode)(2,t.NoticeBox,{color:"red",children:"Shuttle Missing"})}),!!i.shuttle&&(!!i.docking_ports_len&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Send to ",children:i.docking_ports.map(function(c){return(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-right",content:c.name,onClick:function(){function m(){return h("move",{move:c.id})}return m}()},c.name)})})||(0,e.createFragment)([(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",color:"red",children:(0,e.createComponentVNode)(2,t.NoticeBox,{color:"red",children:"Shuttle Locked"})}),!!i.admin_controlled&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Authorization",children:(0,e.createComponentVNode)(2,t.Button,{icon:"exclamation-circle",content:"Request Authorization",disabled:!i.status,onClick:function(){function c(){return h("request")}return c}()})})],0))]})})})})}return b}()},39401:function(T,r,n){"use strict";r.__esModule=!0,r.ShuttleManipulator=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.ShuttleManipulator=function(){function k(h,i){var c=(0,a.useLocalState)(i,"tabIndex",0),m=c[0],l=c[1],u=function(){function s(d){switch(d){case 0:return(0,e.createComponentVNode)(2,b);case 1:return(0,e.createComponentVNode)(2,y);case 2:return(0,e.createComponentVNode)(2,S);default:return"WE SHOULDN'T BE HERE!"}}return s}();return(0,e.createComponentVNode)(2,o.Window,{width:650,height:700,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Box,{fillPositionedParent:!0,children:[(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:m===0,onClick:function(){function s(){return l(0)}return s}(),icon:"info-circle",children:"Status"},"Status"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:m===1,onClick:function(){function s(){return l(1)}return s}(),icon:"file-import",children:"Templates"},"Templates"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:m===2,onClick:function(){function s(){return l(2)}return s}(),icon:"tools",children:"Modification"},"Modification")]}),u(m)]})})})}return k}(),b=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.shuttles;return(0,e.createComponentVNode)(2,t.Box,{children:u.map(function(s){return(0,e.createComponentVNode)(2,t.Section,{title:s.name,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"ID",children:s.id}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Shuttle Timer",children:s.timeleft}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Shuttle Mode",children:s.mode}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Shuttle Status",children:s.status}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Actions",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Jump To",icon:"location-arrow",onClick:function(){function d(){return m("jump_to",{type:"mobile",id:s.id})}return d}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Fast Travel",icon:"fast-forward",onClick:function(){function d(){return m("fast_travel",{id:s.id})}return d}()})]})]})},s.name)})})},y=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.templates_tabs,s=l.existing_shuttle,d=l.templates;return(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Tabs,{children:u.map(function(v){return(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:v===s.id,icon:"file",onClick:function(){function g(){return m("select_template_category",{cat:v})}return g}(),children:v},v)})}),!!s&&d[s.id].templates.map(function(v){return(0,e.createComponentVNode)(2,t.Section,{title:v.name,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[v.description&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Description",children:v.description}),v.admin_notes&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Admin Notes",children:v.admin_notes}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Actions",children:(0,e.createComponentVNode)(2,t.Button,{content:"Load Template",icon:"download",onClick:function(){function g(){return m("select_template",{shuttle_id:v.shuttle_id})}return g}()})})]})},v.name)})]})},S=function(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.existing_shuttle,s=l.selected;return(0,e.createComponentVNode)(2,t.Box,{children:[u?(0,e.createComponentVNode)(2,t.Section,{title:"Selected Shuttle: "+u.name,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:u.status}),u.timer&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Timer",children:u.timeleft}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Actions",children:(0,e.createComponentVNode)(2,t.Button,{content:"Jump To",icon:"location-arrow",onClick:function(){function d(){return m("jump_to",{type:"mobile",id:u.id})}return d}()})})]})}):(0,e.createComponentVNode)(2,t.Section,{title:"Selected Shuttle: None"}),s?(0,e.createComponentVNode)(2,t.Section,{title:"Selected Template: "+s.name,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[s.description&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Description",children:s.description}),s.admin_notes&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Admin Notes",children:s.admin_notes}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Actions",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Preview",icon:"eye",onClick:function(){function d(){return m("preview",{shuttle_id:s.shuttle_id})}return d}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Load",icon:"download",onClick:function(){function d(){return m("load",{shuttle_id:s.shuttle_id})}return d}()})]})]})}):(0,e.createComponentVNode)(2,t.Section,{title:"Selected Template: None"})]})}},88284:function(T,r,n){"use strict";r.__esModule=!0,r.Sleeper=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=n(98595),b=[["good","Alive"],["average","Critical"],["bad","DEAD"]],y=[["Resp.","oxyLoss"],["Toxin","toxLoss"],["Brute","bruteLoss"],["Burn","fireLoss"]],S={average:[.25,.5],bad:[.5,1/0]},k=["bad","average","average","good","average","average","bad"],h=r.Sleeper=function(){function d(v,g){var C=(0,t.useBackend)(g),f=C.act,N=C.data,V=N.hasOccupant,B=V?(0,e.createComponentVNode)(2,i):(0,e.createComponentVNode)(2,s);return(0,e.createComponentVNode)(2,p.Window,{width:550,height:760,children:(0,e.createComponentVNode)(2,p.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:B}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,l)})]})})})}return d}(),i=function(v,g){var C=(0,t.useBackend)(g),f=C.act,N=C.data,V=N.occupant;return(0,e.createFragment)([(0,e.createComponentVNode)(2,c),(0,e.createComponentVNode)(2,m),(0,e.createComponentVNode)(2,u)],4)},c=function(v,g){var C=(0,t.useBackend)(g),f=C.act,N=C.data,V=N.occupant,B=N.auto_eject_dead;return(0,e.createComponentVNode)(2,o.Section,{title:"Occupant",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Box,{color:"label",inline:!0,children:"Auto-eject if dead:\xA0"}),(0,e.createComponentVNode)(2,o.Button,{icon:B?"toggle-on":"toggle-off",selected:B,content:B?"On":"Off",onClick:function(){function I(){return f("auto_eject_dead_"+(B?"off":"on"))}return I}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"user-slash",content:"Eject",onClick:function(){function I(){return f("ejectify")}return I}()})],4),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Name",children:V.name}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Health",children:(0,e.createComponentVNode)(2,o.ProgressBar,{min:"0",max:V.maxHealth,value:V.health/V.maxHealth,ranges:{good:[.5,1/0],average:[0,.5],bad:[-1/0,0]},children:(0,a.round)(V.health,0)})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Status",color:b[V.stat][0],children:b[V.stat][1]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Temperature",children:(0,e.createComponentVNode)(2,o.ProgressBar,{min:"0",max:V.maxTemp,value:V.bodyTemperature/V.maxTemp,color:k[V.temperatureSuitability+3],children:[(0,a.round)(V.btCelsius,0),"\xB0C,",(0,a.round)(V.btFaren,0),"\xB0F"]})}),!!V.hasBlood&&(0,e.createFragment)([(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Blood Level",children:(0,e.createComponentVNode)(2,o.ProgressBar,{min:"0",max:V.bloodMax,value:V.bloodLevel/V.bloodMax,ranges:{bad:[-1/0,.6],average:[.6,.9],good:[.6,1/0]},children:[V.bloodPercent,"%, ",V.bloodLevel,"cl"]})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Pulse",verticalAlign:"middle",children:[V.pulse," BPM"]})],4)]})})},m=function(v,g){var C=(0,t.useBackend)(g),f=C.data,N=f.occupant;return(0,e.createComponentVNode)(2,o.Section,{title:"Occupant Damage",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:y.map(function(V,B){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:V[0],children:(0,e.createComponentVNode)(2,o.ProgressBar,{min:"0",max:"100",value:N[V[1]]/100,ranges:S,children:(0,a.round)(N[V[1]],0)},B)},B)})})})},l=function(v,g){var C=(0,t.useBackend)(g),f=C.act,N=C.data,V=N.hasOccupant,B=N.isBeakerLoaded,I=N.beakerMaxSpace,L=N.beakerFreeSpace,w=N.dialysis,A=w&&L>0;return(0,e.createComponentVNode)(2,o.Section,{title:"Dialysis",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{disabled:!B||L<=0||!V,selected:A,icon:A?"toggle-on":"toggle-off",content:A?"Active":"Inactive",onClick:function(){function x(){return f("togglefilter")}return x}()}),(0,e.createComponentVNode)(2,o.Button,{disabled:!B,icon:"eject",content:"Eject",onClick:function(){function x(){return f("removebeaker")}return x}()})],4),children:B?(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Remaining Space",children:(0,e.createComponentVNode)(2,o.ProgressBar,{min:"0",max:I,value:L/I,ranges:{good:[.5,1/0],average:[.25,.5],bad:[-1/0,.25]},children:[L,"u"]})})}):(0,e.createComponentVNode)(2,o.Box,{color:"label",children:"No beaker loaded."})})},u=function(v,g){var C=(0,t.useBackend)(g),f=C.act,N=C.data,V=N.occupant,B=N.chemicals,I=N.maxchem,L=N.amounts;return(0,e.createComponentVNode)(2,o.Section,{title:"Occupant Chemicals",children:B.map(function(w,A){var x="",E;return w.overdosing?(x="bad",E=(0,e.createComponentVNode)(2,o.Box,{color:"bad",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"exclamation-circle"}),"\xA0 Overdosing!"]})):w.od_warning&&(x="average",E=(0,e.createComponentVNode)(2,o.Box,{color:"average",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"exclamation-triangle"}),"\xA0 Close to overdosing"]})),(0,e.createComponentVNode)(2,o.Box,{backgroundColor:"rgba(0, 0, 0, 0.33)",mb:"0.5rem",children:(0,e.createComponentVNode)(2,o.Section,{title:w.title,level:"3",mx:"0",lineHeight:"18px",buttons:E,children:(0,e.createComponentVNode)(2,o.Stack,{children:[(0,e.createComponentVNode)(2,o.ProgressBar,{min:"0",max:I,value:w.occ_amount/I,color:x,title:"Amount of chemicals currently inside the occupant / Total amount injectable by this machine",mr:"0.5rem",children:[w.pretty_amount,"/",I,"u"]}),L.map(function(P,D){return(0,e.createComponentVNode)(2,o.Button,{disabled:!w.injectable||w.occ_amount+P>I||V.stat===2,icon:"syringe",content:"Inject "+P+"u",title:"Inject "+P+"u of "+w.title+" into the occupant",mb:"0",height:"19px",onClick:function(){function M(){return f("chemical",{chemid:w.id,amount:P})}return M}()},D)})]})})},A)})})},s=function(v,g){return(0,e.createComponentVNode)(2,o.Section,{fill:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,o.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,align:"center",color:"label",children:[(0,e.createComponentVNode)(2,o.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,e.createVNode)(1,"br"),"No occupant detected."]})})})}},21597:function(T,r,n){"use strict";r.__esModule=!0,r.SlotMachine=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.SlotMachine=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data;if(i.money===null)return(0,e.createComponentVNode)(2,o.Window,{width:350,height:90,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Box,{children:"Could not scan your card or could not find account!"}),(0,e.createComponentVNode)(2,t.Box,{children:"Please wear or hold your ID and try again."})]})})});var c;return i.plays===1?c=i.plays+" player has tried their luck today!":c=i.plays+" players have tried their luck today!",(0,e.createComponentVNode)(2,o.Window,{width:300,height:151,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Box,{lineHeight:2,children:c}),(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Credits Remaining",children:(0,e.createComponentVNode)(2,t.AnimatedNumber,{value:i.money})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"10 credits to spin",children:(0,e.createComponentVNode)(2,t.Button,{icon:"coins",disabled:i.working,content:i.working?"Spinning...":"Spin",onClick:function(){function m(){return h("spin")}return m}()})})]}),(0,e.createComponentVNode)(2,t.Box,{bold:!0,lineHeight:2,color:i.resultlvl,children:i.result})]})})})}return b}()},46348:function(T,r,n){"use strict";r.__esModule=!0,r.Smartfridge=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.Smartfridge=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.secure,m=i.can_dry,l=i.drying,u=i.contents;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:500,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[!!c&&(0,e.createComponentVNode)(2,t.NoticeBox,{children:"Secure Access: Please have your identification ready."}),(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:m?"Drying rack":"Contents",buttons:!!m&&(0,e.createComponentVNode)(2,t.Button,{width:4,icon:l?"power-off":"times",content:l?"On":"Off",selected:l,onClick:function(){function s(){return h("drying")}return s}()}),children:[!u&&(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{bold:!0,grow:!0,textAlign:"center",align:"center",color:"average",children:[(0,e.createComponentVNode)(2,t.Icon.Stack,{children:[(0,e.createComponentVNode)(2,t.Icon,{name:"cookie-bite",size:5,color:"brown"}),(0,e.createComponentVNode)(2,t.Icon,{name:"slash",size:5,color:"red"})]}),(0,e.createVNode)(1,"br"),"No products loaded."]})}),!!u&&u.slice().sort(function(s,d){return s.display_name.localeCompare(d.display_name)}).map(function(s){return(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:"55%",children:s.display_name}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:"25%",children:["(",s.quantity," in stock)"]}),(0,e.createComponentVNode)(2,t.Stack.Item,{width:13,children:[(0,e.createComponentVNode)(2,t.Button,{width:3,icon:"arrow-down",tooltip:"Dispense one.",content:"1",onClick:function(){function d(){return h("vend",{index:s.vend,amount:1})}return d}()}),(0,e.createComponentVNode)(2,t.NumberInput,{width:"40px",minValue:0,value:0,maxValue:s.quantity,step:1,stepPixelSize:3,onChange:function(){function d(v,g){return h("vend",{index:s.vend,amount:g})}return d}()}),(0,e.createComponentVNode)(2,t.Button,{width:4,icon:"arrow-down",content:"All",tooltip:"Dispense all.",tooltipPosition:"bottom-start",onClick:function(){function d(){return h("vend",{index:s.vend,amount:s.quantity})}return d}()})]})]},s)})]})]})})})}return b}()},86162:function(T,r,n){"use strict";r.__esModule=!0,r.Smes=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(49968),p=n(98595),b=1e3,y=r.Smes=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.capacityPercent,u=m.capacity,s=m.charge,d=m.inputAttempt,v=m.inputting,g=m.inputLevel,C=m.inputLevelMax,f=m.inputAvailable,N=m.outputPowernet,V=m.outputAttempt,B=m.outputting,I=m.outputLevel,L=m.outputLevelMax,w=m.outputUsed,A=l>=100&&"good"||v&&"average"||"bad",x=B&&"good"||s>0&&"average"||"bad";return(0,e.createComponentVNode)(2,p.Window,{width:340,height:345,children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Stored Energy",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:l*.01,ranges:{good:[.5,1/0],average:[.15,.5],bad:[-1/0,.15]}})}),(0,e.createComponentVNode)(2,t.Section,{title:"Input",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Charge Mode",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:d?"sync-alt":"times",selected:d,onClick:function(){function E(){return c("tryinput")}return E}(),children:d?"Auto":"Off"}),children:(0,e.createComponentVNode)(2,t.Box,{color:A,children:l>=100&&"Fully Charged"||v&&"Charging"||"Not Charging"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Target Input",children:(0,e.createComponentVNode)(2,t.Stack,{inline:!0,width:"100%",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"fast-backward",disabled:g===0,onClick:function(){function E(){return c("input",{target:"min"})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"backward",disabled:g===0,onClick:function(){function E(){return c("input",{adjust:-1e4})}return E}()})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Slider,{value:g/b,fillValue:f/b,minValue:0,maxValue:C/b,step:5,stepPixelSize:4,format:function(){function E(P){return(0,o.formatPower)(P*b,1)}return E}(),onChange:function(){function E(P,D){return c("input",{target:D*b})}return E}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"forward",disabled:g===C,onClick:function(){function E(){return c("input",{adjust:1e4})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fast-forward",disabled:g===C,onClick:function(){function E(){return c("input",{target:"max"})}return E}()})]})]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Available",children:(0,o.formatPower)(f)})]})}),(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Output",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Output Mode",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:V?"power-off":"times",selected:V,onClick:function(){function E(){return c("tryoutput")}return E}(),children:V?"On":"Off"}),children:(0,e.createComponentVNode)(2,t.Box,{color:x,children:N?B?"Sending":s>0?"Not Sending":"No Charge":"Not Connected"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Target Output",children:(0,e.createComponentVNode)(2,t.Stack,{inline:!0,width:"100%",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"fast-backward",disabled:I===0,onClick:function(){function E(){return c("output",{target:"min"})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"backward",disabled:I===0,onClick:function(){function E(){return c("output",{adjust:-1e4})}return E}()})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Slider,{value:I/b,minValue:0,maxValue:L/b,step:5,stepPixelSize:4,format:function(){function E(P){return(0,o.formatPower)(P*b,1)}return E}(),onChange:function(){function E(P,D){return c("output",{target:D*b})}return E}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"forward",disabled:I===L,onClick:function(){function E(){return c("output",{adjust:1e4})}return E}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fast-forward",disabled:I===L,onClick:function(){function E(){return c("output",{target:"max"})}return E}()})]})]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Outputting",children:(0,o.formatPower)(w)})]})})]})})})}return S}()},63584:function(T,r,n){"use strict";r.__esModule=!0,r.SolarControl=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.SolarControl=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=0,m=1,l=2,u=i.generated,s=i.generated_ratio,d=i.tracking_state,v=i.tracking_rate,g=i.connected_panels,C=i.connected_tracker,f=i.cdir,N=i.direction,V=i.rotating_direction;return(0,e.createComponentVNode)(2,o.Window,{width:490,height:277,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Status",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"sync",content:"Scan for new hardware",onClick:function(){function B(){return h("refresh")}return B}()}),children:(0,e.createComponentVNode)(2,t.Grid,{children:[(0,e.createComponentVNode)(2,t.Grid.Column,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Solar tracker",color:C?"good":"bad",children:C?"OK":"N/A"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Solar panels",color:g>0?"good":"bad",children:g})]})}),(0,e.createComponentVNode)(2,t.Grid.Column,{size:2,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power output",children:(0,e.createComponentVNode)(2,t.ProgressBar,{ranges:{good:[.66,1/0],average:[.33,.66],bad:[-1/0,.33]},minValue:0,maxValue:1,value:s,children:u+" W"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Panel orientation",children:[f,"\xB0 (",N,")"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tracker rotation",children:[d===l&&(0,e.createComponentVNode)(2,t.Box,{children:" Automated "}),d===m&&(0,e.createComponentVNode)(2,t.Box,{children:[" ",v,"\xB0/h (",V,")"," "]}),d===c&&(0,e.createComponentVNode)(2,t.Box,{children:" Tracker offline "})]})]})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Controls",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Panel orientation",children:[d!==l&&(0,e.createComponentVNode)(2,t.NumberInput,{unit:"\xB0",step:1,stepPixelSize:1,minValue:0,maxValue:359,value:f,onDrag:function(){function B(I,L){return h("cdir",{cdir:L})}return B}()}),d===l&&(0,e.createComponentVNode)(2,t.Box,{lineHeight:"19px",children:" Automated "})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tracker status",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"times",content:"Off",selected:d===c,onClick:function(){function B(){return h("track",{track:c})}return B}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"clock-o",content:"Timed",selected:d===m,onClick:function(){function B(){return h("track",{track:m})}return B}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"sync",content:"Auto",selected:d===l,disabled:!C,onClick:function(){function B(){return h("track",{track:l})}return B}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tracker rotation",children:[d===m&&(0,e.createComponentVNode)(2,t.NumberInput,{unit:"\xB0/h",step:1,stepPixelSize:1,minValue:-7200,maxValue:7200,value:v,format:function(){function B(I){var L=Math.sign(I)>0?"+":"-";return L+Math.abs(I)}return B}(),onDrag:function(){function B(I,L){return h("tdir",{tdir:L})}return B}()}),d===c&&(0,e.createComponentVNode)(2,t.Box,{lineHeight:"19px",children:" Tracker offline "}),d===l&&(0,e.createComponentVNode)(2,t.Box,{lineHeight:"19px",children:" Automated "})]})]})})]})})}return b}()},38096:function(T,r,n){"use strict";r.__esModule=!0,r.SpawnersMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.SpawnersMenu=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.spawners||[];return(0,e.createComponentVNode)(2,o.Window,{width:700,height:600,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Section,{children:c.map(function(m){return(0,e.createComponentVNode)(2,t.Section,{mb:.5,title:m.name+" ("+m.amount_left+" left)",level:2,buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-circle-right",content:"Jump",onClick:function(){function l(){return h("jump",{ID:m.uids})}return l}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-circle-right",content:"Spawn",onClick:function(){function l(){return h("spawn",{ID:m.uids})}return l}()})],4),children:[(0,e.createComponentVNode)(2,t.Box,{style:{"white-space":"pre-wrap"},mb:1,fontSize:"16px",children:m.desc}),!!m.fluff&&(0,e.createComponentVNode)(2,t.Box,{style:{"white-space":"pre-wrap"},textColor:"#878787",fontSize:"14px",children:m.fluff}),!!m.important_info&&(0,e.createComponentVNode)(2,t.Box,{style:{"white-space":"pre-wrap"},mt:1,bold:!0,color:"red",fontSize:"18px",children:m.important_info})]},m.name)})})})})}return b}()},30586:function(T,r,n){"use strict";r.__esModule=!0,r.SpecMenu=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.SpecMenu=function(){function h(i,c){return(0,e.createComponentVNode)(2,o.Window,{width:1100,height:600,theme:"nologo",children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,b),(0,e.createComponentVNode)(2,y),(0,e.createComponentVNode)(2,S),(0,e.createComponentVNode)(2,k)]})})})}return h}(),b=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.subclasses;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,basis:"25%",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Hemomancer",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Choose",onClick:function(){function d(){return l("hemomancer")}return d}()}),children:[(0,e.createVNode)(1,"h3",null,"Focuses on blood magic and the manipulation of blood around you.",16),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Vampiric claws",16),(0,e.createTextVNode)(": Unlocked at 150 blood, allows you to summon a robust pair of claws that attack rapidly, drain a targets blood, and heal you.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood Barrier",16),(0,e.createTextVNode)(": Unlocked at 250 blood, allows you to select two turfs and create a wall between them.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood tendrils",16),(0,e.createTextVNode)(": Unlocked at 250 blood, allows you to slow everyone in a targeted 3x3 area after a short delay.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Sanguine pool",16),(0,e.createTextVNode)(": Unlocked at 400 blood, allows you to travel at high speeds for a short duration. Doing this leaves behind blood splatters. You can move through anything but walls and space when doing this.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Predator senses",16),(0,e.createTextVNode)(": Unlocked at 600 blood, allows you to sniff out anyone within the same sector as you.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood eruption",16),(0,e.createTextVNode)(": Unlocked at 800 blood, allows you to manipulate all nearby blood splatters, in 4 tiles around you, into spikes that impale anyone stood ontop of them.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Full power",16),(0,e.createComponentVNode)(2,t.Divider),(0,e.createVNode)(1,"b",null,"The blood bringers rite",16),(0,e.createTextVNode)(": When toggled you will rapidly drain the blood of everyone who is nearby and use it to heal yourself slightly and remove any incapacitating effects rapidly.")],4)]})})},y=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.subclasses;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,basis:"25%",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Umbrae",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Choose",onClick:function(){function d(){return l("umbrae")}return d}()}),children:[(0,e.createVNode)(1,"h3",null,"Focuses on darkness, stealth ambushing and mobility.",16),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Cloak of darkness",16),(0,e.createTextVNode)(": Unlocked at 150 blood, when toggled, allows you to become nearly invisible and move rapidly when in dark regions. While active, burn damage is more effective against you.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Shadow anchor",16),(0,e.createTextVNode)(": Unlocked at 250 blood, casting it will create an anchor at the cast location after a short delay. If you then cast the ability again, you are teleported back to the anchor. If you do not cast again within 2 minutes, you will do a fake recall, causing a clone to appear at the anchor and making yourself invisible. It will not teleport you between Z levels.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Shadow snare",16),(0,e.createTextVNode)(": Unlocked at 250 blood, allows you to summon a trap that when crossed blinds and ensnares the victim. This trap is hard to see, but withers in the light.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Dark passage",16),(0,e.createTextVNode)(": Unlocked at 400 blood, allows you to target a turf on screen, you will then teleport to that turf.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Extinguish",16),(0,e.createTextVNode)(": Unlocked at 600 blood, allows you to snuff out nearby electronic light sources and glowshrooms.")],4),(0,e.createVNode)(1,"b",null,"Shadow boxing",16),": Unlocked at 800 blood, sends out shadow clones towards a target, damaging them while you remain in range.",(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Full power",16),(0,e.createComponentVNode)(2,t.Divider),(0,e.createVNode)(1,"b",null,"Eternal darkness",16),(0,e.createTextVNode)(": When toggled, you consume yourself in unholy darkness, only the strongest of lights will be able to see through it. Inside the radius, nearby creatures will freeze and energy projectiles will deal less damage.")],4),(0,e.createVNode)(1,"p",null,"In addition, you also gain permanent X-ray vision.",16)]})})},S=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.subclasses;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,basis:"25%",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Gargantua",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Choose",onClick:function(){function d(){return l("gargantua")}return d}()}),children:[(0,e.createVNode)(1,"h3",null,"Focuses on tenacity and melee damage.",16),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Rejuvenate",16),(0,e.createTextVNode)(": Will heal you at an increased rate based on how much damage you have taken.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood swell",16),(0,e.createTextVNode)(": Unlocked at 150 blood, increases your resistance to physical damage, stuns and stamina for 30 seconds. While it is active you cannot fire guns.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Seismic stomp",16),(0,e.createTextVNode)(": Unlocked at 250 blood, allows you to stomp the ground to send out a shockwave, knocking people back.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood rush",16),(0,e.createTextVNode)(": Unlocked at 250 blood, gives you a short speed boost when cast.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood swell II",16),(0,e.createTextVNode)(": Unlocked at 400 blood, increases all melee damage by 10.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Overwhelming force",16),(0,e.createTextVNode)(": Unlocked at 600 blood, when toggled, if you bump into a door that you do not have access to, it will force it open. In addition, you cannot be pushed or pulled while it is active.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Demonic grasp",16),(0,e.createTextVNode)(": Unlocked at 800 blood, allows you to send out a demonic hand to snare someone. If you are on disarm/grab intent you will push/pull the target, respectively.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Charge",16),(0,e.createTextVNode)(": Unlocked at 800 blood, you gain the ability to charge at a target. Destroying and knocking back pretty much anything you collide with.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Full Power",16),(0,e.createComponentVNode)(2,t.Divider),(0,e.createVNode)(1,"b",null,"Desecrated Duel",16),(0,e.createTextVNode)(": Leap towards a visible enemy, creating an arena upon landing, infusing you with increased regeneration, and granting you resistance to internal damages.")],4)]})})},k=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.subclasses;return(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,basis:"25%",children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Dantalion",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Choose",onClick:function(){function d(){return l("dantalion")}return d}()}),children:[(0,e.createVNode)(1,"h3",null,"Focuses on thralling and illusions.",16),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Enthrall",16),(0,e.createTextVNode)(": Unlocked at 150 blood, Thralls your target to your will, requires you to stand still. Does not work on mindshielded or already enthralled/mindslaved people.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Thrall cap",16),(0,e.createTextVNode)(": You can only thrall a max of 1 person at a time. This can be increased at 400 blood, 600 blood and at full power to a max of 4 thralls.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Thrall commune",16),(0,e.createTextVNode)(": Unlocked at 150 blood, Allows you to talk to your thralls, your thralls can talk back in the same way.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Subspace swap",16),(0,e.createTextVNode)(": Unlocked at 250 blood, allows you to swap positions with a target.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Pacify",16),(0,e.createTextVNode)(": Unlocked at 250 blood, allows you to pacify a target, preventing them from causing harm for 40 seconds.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Decoy",16),(0,e.createTextVNode)(": Unlocked at 400 blood, briefly turn invisible and send out an illusion to fool everyone nearby.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Rally thralls",16),(0,e.createTextVNode)(": Unlocked at 600 blood, removes all incapacitating effects from nearby thralls.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Blood bond",16),(0,e.createTextVNode)(": Unlocked at 800 blood, when cast, all nearby thralls become linked to you. If anyone in the network takes damage, it is shared equally between everyone in the network. If a thrall goes out of range, they will be removed from the network.")],4),(0,e.createVNode)(1,"p",null,[(0,e.createVNode)(1,"b",null,"Full Power",16),(0,e.createComponentVNode)(2,t.Divider),(0,e.createVNode)(1,"b",null,"Mass Hysteria",16),(0,e.createTextVNode)(": Casts a powerful illusion that blinds and then makes everyone nearby perceive others as random animals.")],4)]})})}},95152:function(T,r,n){"use strict";r.__esModule=!0,r.StackCraft=void 0;var e=n(89005),a=n(72253),t=n(88510),o=n(64795),p=n(25328),b=n(98595),y=n(36036),S=r.StackCraft=function(){function s(){return(0,e.createComponentVNode)(2,b.Window,{width:350,height:500,children:(0,e.createComponentVNode)(2,b.Window.Content,{children:(0,e.createComponentVNode)(2,k)})})}return s}(),k=function(d,v){var g=(0,a.useBackend)(v),C=g.data,f=C.amount,N=C.recipes,V=(0,a.useLocalState)(v,"searchText",""),B=V[0],I=V[1],L=h(N,(0,p.createSearch)(B)),w=(0,a.useLocalState)(v,"",!1),A=w[0],x=w[1];return(0,e.createComponentVNode)(2,y.Section,{fill:!0,scrollable:!0,title:"Amount: "+f,buttons:(0,e.createFragment)([A&&(0,e.createComponentVNode)(2,y.Input,{width:12.5,value:B,placeholder:"Find recipe",onInput:function(){function E(P,D){return I(D)}return E}()}),(0,e.createComponentVNode)(2,y.Button,{ml:.5,tooltip:"Search",tooltipPosition:"bottom-end",icon:"magnifying-glass",selected:A,onClick:function(){function E(){return x(!A)}return E}()})],0),children:L?(0,e.createComponentVNode)(2,l,{recipes:L}):(0,e.createComponentVNode)(2,y.NoticeBox,{children:"No recipes found!"})})},h=function s(d,v){var g=(0,o.flow)([(0,t.map)(function(C){var f=C[0],N=C[1];return i(N)?v(f)?C:[f,s(N,v)]:v(f)?C:[f,void 0]}),(0,t.filter)(function(C){var f=C[0],N=C[1];return N!==void 0}),(0,t.sortBy)(function(C){var f=C[0],N=C[1];return f}),(0,t.sortBy)(function(C){var f=C[0],N=C[1];return!i(N)}),(0,t.reduce)(function(C,f){var N=f[0],V=f[1];return C[N]=V,C},{})])(Object.entries(d));return Object.keys(g).length?g:void 0},i=function(d){return d.uid===void 0},c=function(d,v){return d.required_amount>v?0:Math.floor(v/d.required_amount)},m=function(d,v){for(var g=(0,a.useBackend)(v),C=g.act,f=d.recipe,N=d.max_possible_multiplier,V=Math.min(N,Math.floor(f.max_result_amount/f.result_amount)),B=[5,10,25],I=[],L=function(){var E=A[w];V>=E&&I.push((0,e.createComponentVNode)(2,y.Button,{bold:!0,translucent:!0,fontSize:.85,width:"32px",content:E*f.result_amount+"x",onClick:function(){function P(){return C("make",{recipe_uid:f.uid,multiplier:E})}return P}()}))},w=0,A=B;w1?I+"x ":"",M=L>1?"s":"",O=""+D+V,R=L+" sheet"+M,F=c(B,N);return(0,e.createComponentVNode)(2,y.ImageButton,{fluid:!0,base64:P,dmIcon:x,dmIconState:E,imageSize:32,disabled:!F,tooltip:R,buttons:w>1&&F>1&&(0,e.createComponentVNode)(2,m,{recipe:B,max_possible_multiplier:F}),onClick:function(){function W(){return C("make",{recipe_uid:A,multiplier:1})}return W}(),children:O})}},38307:function(T,r,n){"use strict";r.__esModule=!0,r.StationAlertConsoleContent=r.StationAlertConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.StationAlertConsole=function(){function y(){return(0,e.createComponentVNode)(2,o.Window,{width:325,height:500,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,b)})})}return y}(),b=r.StationAlertConsoleContent=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.data,c=i.alarms||[],m=c.Fire||[],l=c.Atmosphere||[],u=c.Power||[];return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{title:"Fire Alarms",children:(0,e.createVNode)(1,"ul",null,[m.length===0&&(0,e.createVNode)(1,"li","color-good","Systems Nominal",16),m.map(function(s){return(0,e.createVNode)(1,"li","color-average",s,0,null,s)})],0)}),(0,e.createComponentVNode)(2,t.Section,{title:"Atmospherics Alarms",children:(0,e.createVNode)(1,"ul",null,[l.length===0&&(0,e.createVNode)(1,"li","color-good","Systems Nominal",16),l.map(function(s){return(0,e.createVNode)(1,"li","color-average",s,0,null,s)})],0)}),(0,e.createComponentVNode)(2,t.Section,{title:"Power Alarms",children:(0,e.createVNode)(1,"ul",null,[u.length===0&&(0,e.createVNode)(1,"li","color-good","Systems Nominal",16),u.map(function(s){return(0,e.createVNode)(1,"li","color-average",s,0,null,s)})],0)})],4)}return y}()},96091:function(T,r,n){"use strict";r.__esModule=!0,r.StationTraitsPanel=void 0;var e=n(89005),a=n(88510),t=n(42127),o=n(72253),p=n(36036),b=n(98595),y=function(i){return i[i.SetupFutureStationTraits=0]="SetupFutureStationTraits",i[i.ViewStationTraits=1]="ViewStationTraits",i}(y||{}),S=function(c,m){var l=(0,o.useBackend)(m),u=l.act,s=l.data,d=s.future_station_traits,v=(0,o.useLocalState)(m,"selectedFutureTrait",null),g=v[0],C=v[1],f=Object.fromEntries(s.valid_station_traits.map(function(V){return[V.name,V.path]})),N=Object.keys(f);return N.sort(),(0,e.createComponentVNode)(2,p.Box,{children:[(0,e.createComponentVNode)(2,p.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,p.Dropdown,{displayText:!g&&"Select trait to add...",onSelected:C,options:N,selected:g,width:"100%"})}),(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Button,{color:"green",icon:"plus",onClick:function(){function V(){if(g){var B=f[g],I=[B];if(d){var L,w=d.map(function(A){return A.path});if(w.indexOf(B)!==-1)return;I=(L=I).concat.apply(L,w)}u("setup_future_traits",{station_traits:I})}}return V}(),children:"Add"})})]}),(0,e.createComponentVNode)(2,p.Divider),Array.isArray(d)?d.length>0?(0,e.createComponentVNode)(2,p.Stack,{vertical:!0,fill:!0,children:d.map(function(V){return(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,children:V.name}),(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Button,{color:"red",icon:"times",onClick:function(){function B(){u("setup_future_traits",{station_traits:(0,a.filterMap)(d,function(I){if(I.path!==V.path)return I.path})})}return B}(),children:"Delete"})})]})},V.path)})}):(0,e.createComponentVNode)(2,p.Box,{textAlign:"center",children:[(0,e.createComponentVNode)(2,p.Box,{children:"No station traits will run next round."}),(0,e.createComponentVNode)(2,p.Button,{mt:1,fluid:!0,color:"good",icon:"times",tooltip:"The next round will roll station traits randomly, just like normal",onClick:function(){function V(){return u("clear_future_traits")}return V}(),children:"Run Station Traits Normally"})]}):(0,e.createComponentVNode)(2,p.Box,{textAlign:"center",children:[(0,e.createComponentVNode)(2,p.Box,{children:"No future station traits are planned."}),(0,e.createComponentVNode)(2,p.Button,{mt:1,fluid:!0,color:"red",icon:"times",onClick:function(){function V(){return u("setup_future_traits",{station_traits:[]})}return V}(),children:"Prevent station traits from running next round"})]})]})},k=function(c,m){var l=(0,o.useBackend)(m),u=l.act,s=l.data;return s.current_traits.length>0?(0,e.createComponentVNode)(2,p.Stack,{vertical:!0,fill:!0,children:s.current_traits.map(function(d){return(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{grow:!0,children:d.name}),(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Button.Confirm,{content:"Revert",color:"red",disabled:s.too_late_to_revert||!d.can_revert,tooltip:!d.can_revert&&"This trait is not revertable."||s.too_late_to_revert&&"It's too late to revert station traits, the round has already started.",icon:"times",onClick:function(){function v(){return u("revert",{ref:d.ref})}return v}()})})]})},d.ref)})}):(0,e.createComponentVNode)(2,p.Box,{textAlign:"center",children:"There are no active station traits."})},h=r.StationTraitsPanel=function(){function i(c,m){var l=(0,o.useLocalState)(m,"station_traits_tab",y.ViewStationTraits),u=l[0],s=l[1],d;switch(u){case y.SetupFutureStationTraits:d=(0,e.createComponentVNode)(2,S);break;case y.ViewStationTraits:d=(0,e.createComponentVNode)(2,k);break;default:(0,t.exhaustiveCheck)(u)}return(0,e.createComponentVNode)(2,b.Window,{title:"Modify Station Traits",height:350,width:350,children:(0,e.createComponentVNode)(2,b.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,p.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,p.Stack.Item,{children:(0,e.createComponentVNode)(2,p.Tabs,{children:[(0,e.createComponentVNode)(2,p.Tabs.Tab,{icon:"eye",selected:u===y.ViewStationTraits,onClick:function(){function v(){return s(y.ViewStationTraits)}return v}(),children:"View"}),(0,e.createComponentVNode)(2,p.Tabs.Tab,{icon:"edit",selected:u===y.SetupFutureStationTraits,onClick:function(){function v(){return s(y.SetupFutureStationTraits)}return v}(),children:"Edit"})]})}),(0,e.createComponentVNode)(2,p.Stack.Item,{m:0,children:[(0,e.createComponentVNode)(2,p.Divider),d]})]})})})}return i}()},39409:function(T,r,n){"use strict";r.__esModule=!0,r.StripMenu=void 0;var e=n(89005),a=n(88510),t=n(79140),o=n(72253),p=n(36036),b=n(98595),y=5,S=9,k=function(g){return g===0?5:9},h="64px",i=function(g){return g[0]+"/"+g[1]},c=function(g){var C=g.align,f=g.children;return(0,e.createComponentVNode)(2,p.Box,{style:{position:"absolute",left:C==="left"?"6px":"48px","text-align":C,"text-shadow":"2px 2px 2px #000",top:"2px"},children:f})},m={enable_internals:{icon:"lungs",text:"Enable internals"},disable_internals:{icon:"lungs",text:"Disable internals"},enable_lock:{icon:"lock",text:"Enable lock"},disable_lock:{icon:"unlock",text:"Disable lock"},suit_sensors:{icon:"tshirt",text:"Adjust suit sensors"},remove_accessory:{icon:"medal",text:"Remove accessory"},dislodge_headpocket:{icon:"head-side-virus",text:"Dislodge headpocket"}},l={eyes:{displayName:"eyewear",gridSpot:i([0,0]),image:"inventory-glasses.png"},head:{displayName:"headwear",gridSpot:i([0,1]),image:"inventory-head.png"},mask:{displayName:"mask",gridSpot:i([1,1]),image:"inventory-mask.png"},neck:{displayName:"neck",gridSpot:i([1,0]),image:"inventory-neck.png"},pet_collar:{displayName:"collar",gridSpot:i([1,1]),image:"inventory-collar.png"},right_ear:{displayName:"right ear",gridSpot:i([0,2]),image:"inventory-ears.png"},left_ear:{displayName:"left ear",gridSpot:i([1,2]),image:"inventory-ears.png"},parrot_headset:{displayName:"headset",gridSpot:i([1,2]),image:"inventory-ears.png"},handcuffs:{displayName:"handcuffs",gridSpot:i([1,3])},legcuffs:{displayName:"legcuffs",gridSpot:i([1,4])},jumpsuit:{displayName:"uniform",gridSpot:i([2,0]),image:"inventory-uniform.png"},suit:{displayName:"suit",gridSpot:i([2,1]),image:"inventory-suit.png"},gloves:{displayName:"gloves",gridSpot:i([2,2]),image:"inventory-gloves.png"},right_hand:{displayName:"right hand",gridSpot:i([2,3]),image:"inventory-hand_r.png",additionalComponent:(0,e.createComponentVNode)(2,c,{align:"left",children:"R"})},left_hand:{displayName:"left hand",gridSpot:i([2,4]),image:"inventory-hand_l.png",additionalComponent:(0,e.createComponentVNode)(2,c,{align:"right",children:"L"})},shoes:{displayName:"shoes",gridSpot:i([3,1]),image:"inventory-shoes.png"},suit_storage:{displayName:"suit storage",gridSpot:i([4,0]),image:"inventory-suit_storage.png"},id:{displayName:"ID",gridSpot:i([4,1]),image:"inventory-id.png"},belt:{displayName:"belt",gridSpot:i([4,2]),image:"inventory-belt.png"},back:{displayName:"backpack",gridSpot:i([4,3]),image:"inventory-back.png"},left_pocket:{displayName:"left pocket",gridSpot:i([3,4]),image:"inventory-pocket.png"},right_pocket:{displayName:"right pocket",gridSpot:i([3,3]),image:"inventory-pocket.png"},pda:{displayName:"PDA",gridSpot:i([4,4]),image:"inventory-pda.png"}},u={eyes:{displayName:"eyewear",gridSpot:i([0,0]),image:"inventory-glasses.png"},head:{displayName:"headwear",gridSpot:i([0,1]),image:"inventory-head.png"},mask:{displayName:"mask",gridSpot:i([1,1]),image:"inventory-mask.png"},neck:{displayName:"neck",gridSpot:i([1,0]),image:"inventory-neck.png"},pet_collar:{displayName:"collar",gridSpot:i([1,1]),image:"inventory-collar.png"},right_ear:{displayName:"right ear",gridSpot:i([0,2]),image:"inventory-ears.png"},left_ear:{displayName:"left ear",gridSpot:i([1,2]),image:"inventory-ears.png"},parrot_headset:{displayName:"headset",gridSpot:i([1,2]),image:"inventory-ears.png"},handcuffs:{displayName:"handcuffs",gridSpot:i([1,3])},legcuffs:{displayName:"legcuffs",gridSpot:i([1,4])},jumpsuit:{displayName:"uniform",gridSpot:i([2,0]),image:"inventory-uniform.png"},suit:{displayName:"suit",gridSpot:i([2,1]),image:"inventory-suit.png"},gloves:{displayName:"gloves",gridSpot:i([2,2]),image:"inventory-gloves.png"},right_hand:{displayName:"right hand",gridSpot:i([4,4]),image:"inventory-hand_r.png",additionalComponent:(0,e.createComponentVNode)(2,c,{align:"left",children:"R"})},left_hand:{displayName:"left hand",gridSpot:i([4,5]),image:"inventory-hand_l.png",additionalComponent:(0,e.createComponentVNode)(2,c,{align:"right",children:"L"})},shoes:{displayName:"shoes",gridSpot:i([3,1]),image:"inventory-shoes.png"},suit_storage:{displayName:"suit storage",gridSpot:i([4,0]),image:"inventory-suit_storage.png"},id:{displayName:"ID",gridSpot:i([4,1]),image:"inventory-id.png"},belt:{displayName:"belt",gridSpot:i([4,2]),image:"inventory-belt.png"},back:{displayName:"backpack",gridSpot:i([4,3]),image:"inventory-back.png"},left_pocket:{displayName:"left pocket",gridSpot:i([4,7]),image:"inventory-pocket.png"},right_pocket:{displayName:"right pocket",gridSpot:i([4,6]),image:"inventory-pocket.png"},pda:{displayName:"PDA",gridSpot:i([4,8]),image:"inventory-pda.png"}},s=function(v){return v[v.Completely=1]="Completely",v[v.Hidden=2]="Hidden",v}(s||{}),d=r.StripMenu=function(){function v(g,C){var f=(0,o.useBackend)(C),N=f.act,V=f.data,B=new Map;if(V.show_mode===0)for(var I=0,L=Object.keys(V.items);I=.01})},(0,a.sortBy)(function(w){return-w.amount})])(g.gases||[]),L=Math.max.apply(Math,[1].concat(I.map(function(w){return w.amount})));return(0,e.createComponentVNode)(2,S.Window,{width:550,height:185,children:(0,e.createComponentVNode)(2,S.Window.Content,{children:(0,e.createComponentVNode)(2,b.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{width:"270px",children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Metrics",children:(0,e.createComponentVNode)(2,b.LabeledList,{children:[(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Integrity",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:f/100,ranges:{good:[.9,1/0],average:[.5,.9],bad:[-1/0,.5]}})}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Relative EER",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:N,minValue:0,maxValue:5e3,ranges:{good:[-1/0,5e3],average:[5e3,7e3],bad:[7e3,1/0]},children:(0,o.toFixed)(N)+" MeV/cm3"})}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Temperature",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:i(V),minValue:0,maxValue:i(1e4),ranges:{teal:[-1/0,i(80)],good:[i(80),i(373)],average:[i(373),i(1e3)],bad:[i(1e3),1/0]},children:(0,o.toFixed)(V)+" K"})}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Pressure",children:(0,e.createComponentVNode)(2,b.ProgressBar,{value:i(B),minValue:0,maxValue:i(5e4),ranges:{good:[i(1),i(300)],average:[-1/0,i(1e3)],bad:[i(1e3),1/0]},children:(0,o.toFixed)(B)+" kPa"})})]})})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,basis:0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Gases",buttons:(0,e.createComponentVNode)(2,b.Button,{icon:"arrow-left",content:"Back",onClick:function(){function w(){return v("back")}return w}()}),children:(0,e.createComponentVNode)(2,b.LabeledList,{children:I.map(function(w){return(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:(0,y.getGasLabel)(w.name),children:(0,e.createComponentVNode)(2,b.ProgressBar,{color:(0,y.getGasColor)(w.name),value:w.amount,minValue:0,maxValue:L,children:(0,o.toFixed)(w.amount,2)+"%"})},w.name)})})})})]})})})}},46029:function(T,r,n){"use strict";r.__esModule=!0,r.SyndicateComputerSimple=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.SyndicateComputerSimple=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data;return(0,e.createComponentVNode)(2,o.Window,{theme:"syndicate",width:400,height:400,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:i.rows.map(function(c){return(0,e.createComponentVNode)(2,t.Section,{title:c.title,buttons:(0,e.createComponentVNode)(2,t.Button,{content:c.buttontitle,disabled:c.buttondisabled,tooltip:c.buttontooltip,tooltipPosition:"left",onClick:function(){function m(){return h(c.buttonact)}return m}()}),children:[c.status,!!c.bullets&&(0,e.createComponentVNode)(2,t.Box,{children:c.bullets.map(function(m){return(0,e.createComponentVNode)(2,t.Box,{children:m},m)})})]},c.title)})})})}return b}()},36372:function(T,r,n){"use strict";r.__esModule=!0,r.TEG=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=function(S){return S.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,")},b=r.TEG=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data;return c.error?(0,e.createComponentVNode)(2,o.Window,{width:500,height:400,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Error",children:[c.error,(0,e.createComponentVNode)(2,t.Button,{icon:"circle",content:"Recheck",onClick:function(){function m(){return i("check")}return m}()})]})})}):(0,e.createComponentVNode)(2,o.Window,{width:500,height:400,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Cold Loop ("+c.cold_dir+")",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cold Inlet",children:[p(c.cold_inlet_temp)," K, ",p(c.cold_inlet_pressure)," kPa"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cold Outlet",children:[p(c.cold_outlet_temp)," K, ",p(c.cold_outlet_pressure)," kPa"]})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Hot Loop ("+c.hot_dir+")",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Hot Inlet",children:[p(c.hot_inlet_temp)," K, ",p(c.hot_inlet_pressure)," kPa"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Hot Outlet",children:[p(c.hot_outlet_temp)," K, ",p(c.hot_outlet_pressure)," kPa"]})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Power Output",children:[p(c.output_power)," W",!!c.warning_switched&&(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Warning: Cold inlet temperature exceeds hot inlet temperature."}),!!c.warning_cold_pressure&&(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Warning: Cold circulator inlet pressure is under 1,000 kPa."}),!!c.warning_hot_pressure&&(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Warning: Hot circulator inlet pressure is under 1,000 kPa."})]})]})})}return y}()},56441:function(T,r,n){"use strict";r.__esModule=!0,r.TachyonArrayContent=r.TachyonArray=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.TachyonArray=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.records,l=m===void 0?[]:m,u=c.explosion_target,s=c.toxins_tech,d=c.printing;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:600,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Shift's Target",children:u}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Toxins Level",children:s}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Administration",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"print",content:"Print All Logs",disabled:!l.length||d,align:"center",onClick:function(){function v(){return i("print_logs")}return v}()}),(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"trash",content:"Delete All Logs",disabled:!l.length,color:"bad",align:"center",onClick:function(){function v(){return i("delete_logs")}return v}()})]})]})}),l.length?(0,e.createComponentVNode)(2,b):(0,e.createComponentVNode)(2,t.NoticeBox,{children:"No Records"})]})})}return y}(),b=r.TachyonArrayContent=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.records,l=m===void 0?[]:m;return(0,e.createComponentVNode)(2,t.Section,{title:"Logged Explosions",children:(0,e.createComponentVNode)(2,t.Flex,{children:(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Time"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Epicenter"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Actual Size"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Theoretical Size"})]}),l.map(function(u){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.logged_time}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.epicenter}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.actual_size_message}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.theoretical_size_message}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button.Confirm,{icon:"trash",content:"Delete",color:"bad",onClick:function(){function s(){return i("delete_record",{index:u.index})}return s}()})})]},u.index)})]})})})})}return y}()},1754:function(T,r,n){"use strict";r.__esModule=!0,r.Tank=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.Tank=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c;return i.has_mask?c=(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Mask",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,width:"76%",icon:i.connected?"check":"times",content:i.connected?"Internals On":"Internals Off",selected:i.connected,onClick:function(){function m(){return h("internals")}return m}()})}):c=(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Mask",color:"red",children:"No Mask Equipped"}),(0,e.createComponentVNode)(2,o.Window,{width:325,height:135,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Tank Pressure",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:i.tankPressure/1013,ranges:{good:[.35,1/0],average:[.15,.35],bad:[-1/0,.15]},children:i.tankPressure+" kPa"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Release Pressure",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"fast-backward",disabled:i.ReleasePressure===i.minReleasePressure,tooltip:"Min",onClick:function(){function m(){return h("pressure",{pressure:"min"})}return m}()}),(0,e.createComponentVNode)(2,t.NumberInput,{animated:!0,value:parseFloat(i.releasePressure),width:"65px",unit:"kPa",minValue:i.minReleasePressure,maxValue:i.maxReleasePressure,onChange:function(){function m(l,u){return h("pressure",{pressure:u})}return m}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"fast-forward",disabled:i.ReleasePressure===i.maxReleasePressure,tooltip:"Max",onClick:function(){function m(){return h("pressure",{pressure:"max"})}return m}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"undo",content:"",disabled:i.ReleasePressure===i.defaultReleasePressure,tooltip:"Reset",onClick:function(){function m(){return h("pressure",{pressure:"reset"})}return m}()})]}),c]})})})})}return b}()},7579:function(T,r,n){"use strict";r.__esModule=!0,r.TankDispenser=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.TankDispenser=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.o_tanks,m=i.p_tanks;return(0,e.createComponentVNode)(2,o.Window,{width:250,height:105,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,content:"Dispense Oxygen Tank ("+c+")",disabled:c===0,icon:"arrow-circle-down",onClick:function(){function l(){return h("oxygen")}return l}()})}),(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{mt:1,fluid:!0,content:"Dispense Plasma Tank ("+m+")",disabled:m===0,icon:"arrow-circle-down",onClick:function(){function l(){return h("plasma")}return l}()})})]})})})}return b}()},16136:function(T,r,n){"use strict";r.__esModule=!0,r.TcommsCore=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.TcommsCore=function(){function h(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.ion,d=(0,a.useLocalState)(c,"tabIndex",0),v=d[0],g=d[1],C=function(){function f(N){switch(N){case 0:return(0,e.createComponentVNode)(2,y);case 1:return(0,e.createComponentVNode)(2,S);case 2:return(0,e.createComponentVNode)(2,k);default:return"SOMETHING WENT VERY WRONG PLEASE AHELP"}}return f}();return(0,e.createComponentVNode)(2,o.Window,{width:900,height:520,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[s===1&&(0,e.createComponentVNode)(2,b),(0,e.createComponentVNode)(2,t.Tabs,{children:[(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"wrench",selected:v===0,onClick:function(){function f(){return g(0)}return f}(),children:"Configuration"},"ConfigPage"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"link",selected:v===1,onClick:function(){function f(){return g(1)}return f}(),children:"Device Linkage"},"LinkagePage"),(0,e.createComponentVNode)(2,t.Tabs.Tab,{icon:"user-times",selected:v===2,onClick:function(){function f(){return g(2)}return f}(),children:"User Filtering"},"FilterPage")]}),C(v)]})})}return h}(),b=function(){return(0,e.createComponentVNode)(2,t.NoticeBox,{children:"ERROR: An Ionospheric overload has occured. Please wait for the machine to reboot. This cannot be manually done."})},y=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.active,d=u.sectors_available,v=u.nttc_toggle_jobs,g=u.nttc_toggle_job_color,C=u.nttc_toggle_name_color,f=u.nttc_toggle_command_bold,N=u.nttc_job_indicator_type,V=u.nttc_setting_language,B=u.network_id;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{title:"Status",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Machine Power",children:(0,e.createComponentVNode)(2,t.Button,{content:s?"On":"Off",selected:s,icon:"power-off",onClick:function(){function I(){return l("toggle_active")}return I}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Sector Coverage",children:d})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Radio Configuration",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Job Announcements",children:(0,e.createComponentVNode)(2,t.Button,{content:v?"On":"Off",selected:v,icon:"user-tag",onClick:function(){function I(){return l("nttc_toggle_jobs")}return I}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Job Departmentalisation",children:(0,e.createComponentVNode)(2,t.Button,{content:g?"On":"Off",selected:g,icon:"clipboard-list",onClick:function(){function I(){return l("nttc_toggle_job_color")}return I}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Name Departmentalisation",children:(0,e.createComponentVNode)(2,t.Button,{content:C?"On":"Off",selected:C,icon:"user-tag",onClick:function(){function I(){return l("nttc_toggle_name_color")}return I}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Command Amplification",children:(0,e.createComponentVNode)(2,t.Button,{content:f?"On":"Off",selected:f,icon:"volume-up",onClick:function(){function I(){return l("nttc_toggle_command_bold")}return I}()})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Advanced",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Job Announcement Format",children:(0,e.createComponentVNode)(2,t.Button,{content:N||"Unset",selected:N,icon:"pencil-alt",onClick:function(){function I(){return l("nttc_job_indicator_type")}return I}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Language Conversion",children:(0,e.createComponentVNode)(2,t.Button,{content:V||"Unset",selected:V,icon:"globe",onClick:function(){function I(){return l("nttc_setting_language")}return I}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Network ID",children:(0,e.createComponentVNode)(2,t.Button,{content:B||"Unset",selected:B,icon:"server",onClick:function(){function I(){return l("network_id")}return I}()})})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Maintenance",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Import Configuration",icon:"file-import",onClick:function(){function I(){return l("import")}return I}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Export Configuration",icon:"file-export",onClick:function(){function I(){return l("export")}return I}()})]})],4)},S=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.link_password,d=u.relay_entries;return(0,e.createComponentVNode)(2,t.Section,{title:"Device Linkage",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Linkage Password",children:(0,e.createComponentVNode)(2,t.Button,{content:s||"Unset",selected:s,icon:"lock",onClick:function(){function v(){return l("change_password")}return v}()})})}),(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network Address"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network ID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Sector"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Status"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Unlink"})]}),d.map(function(v){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:v.addr}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:v.net_id}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:v.sector}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:v.status===1?(0,e.createComponentVNode)(2,t.Box,{color:"green",children:"Online"}):(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Offline"})}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Unlink",icon:"unlink",onClick:function(){function g(){return l("unlink",{addr:v.addr})}return g}()})})]},v.addr)})]})]})},k=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=m.data,s=u.filtered_users;return(0,e.createComponentVNode)(2,t.Section,{title:"User Filtering",buttons:(0,e.createComponentVNode)(2,t.Button,{content:"Add User",icon:"user-plus",onClick:function(){function d(){return l("add_filter")}return d}()}),children:(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{style:{width:"90%"},children:"User"}),(0,e.createComponentVNode)(2,t.Table.Cell,{style:{width:"10%"},children:"Actions"})]}),s.map(function(d){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:d}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Remove",icon:"user-times",onClick:function(){function v(){return l("remove_filter",{user:d})}return v}()})})]},d)})]})})}},88046:function(T,r,n){"use strict";r.__esModule=!0,r.TcommsRelay=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.TcommsRelay=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.linked,u=m.active,s=m.network_id;return(0,e.createComponentVNode)(2,o.Window,{width:600,height:292,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Relay Configuration",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Machine Power",children:(0,e.createComponentVNode)(2,t.Button,{content:u?"On":"Off",selected:u,icon:"power-off",onClick:function(){function d(){return c("toggle_active")}return d}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Network ID",children:(0,e.createComponentVNode)(2,t.Button,{content:s||"Unset",selected:s,icon:"server",onClick:function(){function d(){return c("network_id")}return d}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Link Status",children:l===1?(0,e.createComponentVNode)(2,t.Box,{color:"green",children:"Linked"}):(0,e.createComponentVNode)(2,t.Box,{color:"red",children:"Unlinked"})})]})}),l===1?(0,e.createComponentVNode)(2,b):(0,e.createComponentVNode)(2,y)]})})}return S}(),b=function(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.linked_core_id,u=m.linked_core_addr,s=m.hidden_link;return(0,e.createComponentVNode)(2,t.Section,{title:"Link Status",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Linked Core ID",children:l}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Linked Core Address",children:u}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Hidden Link",children:(0,e.createComponentVNode)(2,t.Button,{content:s?"Yes":"No",icon:s?"eye-slash":"eye",selected:s,onClick:function(){function d(){return c("toggle_hidden_link")}return d}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Unlink",children:(0,e.createComponentVNode)(2,t.Button,{content:"Unlink",icon:"unlink",color:"red",onClick:function(){function d(){return c("unlink")}return d}()})})]})})},y=function(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.cores;return(0,e.createComponentVNode)(2,t.Section,{title:"Detected Cores",children:(0,e.createComponentVNode)(2,t.Table,{m:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network Address"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Network ID"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Sector"}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:"Link"})]}),l.map(function(u){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.addr}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.net_id}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:u.sector}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{content:"Link",icon:"link",onClick:function(){function s(){return c("link",{addr:u.addr})}return s}()})})]},u.addr)})]})})}},20802:function(T,r,n){"use strict";r.__esModule=!0,r.Teleporter=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.Teleporter=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.targetsTeleport?i.targetsTeleport:{},m=0,l=1,u=2,s=i.calibrated,d=i.calibrating,v=i.powerstation,g=i.regime,C=i.teleporterhub,f=i.target,N=i.locked,V=i.adv_beacon_allowed,B=i.advanced_beacon_locking;return(0,e.createComponentVNode)(2,o.Window,{width:350,height:270,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:[(!v||!C)&&(0,e.createComponentVNode)(2,t.Section,{fill:!0,title:"Error",children:[C,!v&&(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:" Powerstation not linked "}),v&&!C&&(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:" Teleporter hub not linked "})]}),v&&C&&(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Status",buttons:(0,e.createFragment)(!!V&&(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{inline:!0,color:"label",children:"Advanced Beacon Locking:\xA0"}),(0,e.createComponentVNode)(2,t.Button,{selected:B,icon:B?"toggle-on":"toggle-off",content:B?"Enabled":"Disabled",onClick:function(){function I(){return h("advanced_beacon_locking",{on:B?0:1})}return I}()})],4),0),children:[(0,e.createComponentVNode)(2,t.Stack,{mb:1,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:8.5,color:"label",children:"Teleport target:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[g===m&&(0,e.createComponentVNode)(2,t.Dropdown,{width:18.2,selected:f,disabled:d,options:Object.keys(c),color:f!=="None"?"default":"bad",onSelected:function(){function I(L){return h("settarget",{x:c[L].x,y:c[L].y,z:c[L].z,tptarget:c[L].pretarget})}return I}()}),g===l&&(0,e.createComponentVNode)(2,t.Dropdown,{width:18.2,selected:f,disabled:d,options:Object.keys(c),color:f!=="None"?"default":"bad",onSelected:function(){function I(L){return h("settarget",{x:c[L].x,y:c[L].y,z:c[L].z,tptarget:c[L].pretarget})}return I}()}),g===u&&(0,e.createComponentVNode)(2,t.Box,{children:f})]})]}),(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:8.5,color:"label",children:"Regime:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,content:"Gate",tooltip:"Teleport to another teleport hub.",tooltipPosition:"top",color:g===l?"good":null,onClick:function(){function I(){return h("setregime",{regime:l})}return I}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,content:"Teleporter",tooltip:"One-way teleport.",tooltipPosition:"top",color:g===m?"good":null,onClick:function(){function I(){return h("setregime",{regime:m})}return I}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,content:"GPS",tooltip:"Teleport to a location stored in a GPS device.",tooltipPosition:"top-end",color:g===u?"good":null,disabled:!N,onClick:function(){function I(){return h("setregime",{regime:u})}return I}()})})]}),(0,e.createComponentVNode)(2,t.Stack,{label:"Calibration",mt:1,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:8.5,color:"label",children:"Calibration:"}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[f!=="None"&&(0,e.createComponentVNode)(2,t.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{width:15.8,textAlign:"center",mt:.5,children:d&&(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"In Progress"})||s&&(0,e.createComponentVNode)(2,t.Box,{color:"good",children:"Optimal"})||(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:"Sub-Optimal"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button,{icon:"sync-alt",tooltip:"Calibrates the hub. Accidents may occur when the calibration is not optimal.",tooltipPosition:"bottom-end",disabled:!!(s||d),onClick:function(){function I(){return h("calibrate")}return I}()})})]}),f==="None"&&(0,e.createComponentVNode)(2,t.Box,{lineHeight:"21px",children:"No target set"})]})]})]}),!!(N&&v&&C&&g===u)&&(0,e.createComponentVNode)(2,t.Section,{title:"GPS",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Button,{content:"Upload GPS data",tooltip:"Loads the GPS data from the device.",icon:"upload",onClick:function(){function I(){return h("load")}return I}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Eject",tooltip:"Ejects the GPS device",icon:"eject",onClick:function(){function I(){return h("eject")}return I}()})]})})]})})})})}return b}()},48517:function(T,r,n){"use strict";r.__esModule=!0,r.TelescienceConsole=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.TelescienceConsole=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.last_msg,m=i.linked_pad,l=i.held_gps,u=i.lastdata,s=i.power_levels,d=i.current_max_power,v=i.current_power,g=i.current_bearing,C=i.current_elevation,f=i.current_sector,N=i.working,V=i.max_z,B=(0,a.useLocalState)(S,"dummyrot",g),I=B[0],L=B[1];return(0,e.createComponentVNode)(2,o.Window,{width:400,height:500,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:[(0,e.createComponentVNode)(2,t.Section,{title:"Status",children:(0,e.createFragment)([c,!(u.length>0)||(0,e.createVNode)(1,"ul",null,u.map(function(w){return(0,e.createVNode)(1,"li",null,w,0,null,w)}),0)],0)}),(0,e.createComponentVNode)(2,t.Section,{title:"Telepad Status",children:m===1?(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Bearing",children:(0,e.createComponentVNode)(2,t.Box,{inline:!0,position:"relative",children:[(0,e.createComponentVNode)(2,t.NumberInput,{unit:"\xB0",width:6.1,lineHeight:1.5,step:.1,minValue:0,maxValue:360,disabled:N,value:g,onDrag:function(){function w(A,x){return L(x)}return w}(),onChange:function(){function w(A,x){return h("setbear",{bear:x})}return w}()}),(0,e.createComponentVNode)(2,t.Icon,{ml:1,size:1,name:"arrow-up",rotation:I})]})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Elevation",children:(0,e.createComponentVNode)(2,t.NumberInput,{width:6.1,lineHeight:1.5,step:.1,minValue:0,maxValue:100,disabled:N,value:C,onChange:function(){function w(A,x){return h("setelev",{elev:x})}return w}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power Level",children:s.map(function(w,A){return(0,e.createComponentVNode)(2,t.Button,{content:w,selected:v===w,disabled:A>=d-1||N,onClick:function(){function x(){return h("setpwr",{pwr:A+1})}return x}()},w)})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Target Sector",children:(0,e.createComponentVNode)(2,t.NumberInput,{width:6.1,lineHeight:1.5,step:1,minValue:2,maxValue:V,value:f,disabled:N,onChange:function(){function w(A,x){return h("setz",{newz:x})}return w}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Telepad Actions",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Send",disabled:N,onClick:function(){function w(){return h("pad_send")}return w}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Receive",disabled:N,onClick:function(){function w(){return h("pad_receive")}return w}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Crystal Maintenance",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Recalibrate Crystals",disabled:N,onClick:function(){function w(){return h("recal_crystals")}return w}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Eject Crystals",disabled:N,onClick:function(){function w(){return h("eject_crystals")}return w}()})]})]}):(0,e.createFragment)([(0,e.createTextVNode)("No pad linked to console. Please use a multitool to link a pad.")],4)}),(0,e.createComponentVNode)(2,t.Section,{title:"GPS Actions",children:l===1?(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{disabled:l===0||N,content:"Eject GPS",onClick:function(){function w(){return h("eject_gps")}return w}()}),(0,e.createComponentVNode)(2,t.Button,{disabled:l===0||N,content:"Store Coordinates",onClick:function(){function w(){return h("store_to_gps")}return w}()})],4):(0,e.createFragment)([(0,e.createTextVNode)("Please insert a GPS to store coordinates to it.")],4)})]})})}return b}()},21800:function(T,r,n){"use strict";r.__esModule=!0,r.TempGun=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=n(98595),b=r.TempGun=function(){function h(i,c){var m=(0,t.useBackend)(c),l=m.act,u=m.data,s=u.target_temperature,d=u.temperature,v=u.max_temp,g=u.min_temp;return(0,e.createComponentVNode)(2,p.Window,{width:250,height:121,children:(0,e.createComponentVNode)(2,p.Window.Content,{children:(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Target Temperature",children:[(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,step:10,stepPixelSize:6,minValue:g,maxValue:v,value:s,format:function(){function C(f){return(0,a.toFixed)(f,2)}return C}(),width:"50px",onDrag:function(){function C(f,N){return l("target_temperature",{target_temperature:N})}return C}()}),"\xB0C"]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Current Temperature",children:(0,e.createComponentVNode)(2,o.Box,{color:y(d),bold:d>500-273.15,children:[(0,e.createComponentVNode)(2,o.AnimatedNumber,{value:(0,a.round)(d,2)}),"\xB0C"]})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Power Cost",children:(0,e.createComponentVNode)(2,o.Box,{color:k(d),children:S(d)})})]})})})})}return h}(),y=function(i){return i<=-100?"blue":i<=0?"teal":i<=100?"green":i<=200?"orange":"red"},S=function(i){return i<=100-273.15?"High":i<=250-273.15?"Medium":i<=300-273.15?"Low":i<=400-273.15?"Medium":"High"},k=function(i){return i<=100-273.15?"red":i<=250-273.15?"orange":i<=300-273.15?"green":i<=400-273.15?"orange":"red"}},24410:function(T,r,n){"use strict";r.__esModule=!0,r.sanitizeMultiline=r.removeAllSkiplines=r.TextInputModal=void 0;var e=n(89005),a=n(51057),t=n(19203),o=n(72253),p=n(92986),b=n(36036),y=n(98595),S=r.sanitizeMultiline=function(){function c(m){return m.replace(/(\n|\r\n){3,}/,"\n\n")}return c}(),k=r.removeAllSkiplines=function(){function c(m){return m.replace(/[\r\n]+/,"")}return c}(),h=r.TextInputModal=function(){function c(m,l){var u=(0,o.useBackend)(l),s=u.act,d=u.data,v=d.max_length,g=d.message,C=g===void 0?"":g,f=d.multiline,N=d.placeholder,V=d.timeout,B=d.title,I=(0,o.useLocalState)(l,"input",N||""),L=I[0],w=I[1],A=function(){function P(D){if(D!==L){var M=f?S(D):k(D);w(M)}}return P}(),x=f||L.length>=40,E=130+(C.length>40?Math.ceil(C.length/4):0)+(x?80:0);return(0,e.createComponentVNode)(2,y.Window,{title:B,width:325,height:E,children:[V&&(0,e.createComponentVNode)(2,a.Loader,{value:V}),(0,e.createComponentVNode)(2,y.Window.Content,{onKeyDown:function(){function P(D){var M=window.event?D.which:D.keyCode;M===p.KEY_ENTER&&(!x||!D.shiftKey)&&s("submit",{entry:L}),M===p.KEY_ESCAPE&&s("cancel")}return P}(),children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,children:(0,e.createComponentVNode)(2,b.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Box,{color:"label",children:C})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,i,{input:L,onType:A})}),(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,t.InputButtons,{input:L,message:L.length+"/"+v})})]})})})]})}return c}(),i=function(m,l){var u=(0,o.useBackend)(l),s=u.act,d=u.data,v=d.max_length,g=d.multiline,C=m.input,f=m.onType,N=g||C.length>=40;return(0,e.createComponentVNode)(2,b.TextArea,{autoFocus:!0,autoSelect:!0,height:g||C.length>=40?"100%":"1.8rem",maxLength:v,onEscape:function(){function V(){return s("cancel")}return V}(),onEnter:function(){function V(B){N&&B.shiftKey||(B.preventDefault(),s("submit",{entry:C}))}return V}(),onInput:function(){function V(B,I){return f(I)}return V}(),placeholder:"Type something...",value:C})}},25036:function(T,r,n){"use strict";r.__esModule=!0,r.ThermoMachine=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=n(98595),b=r.ThermoMachine=function(){function y(S,k){var h=(0,t.useBackend)(k),i=h.act,c=h.data;return(0,e.createComponentVNode)(2,p.Window,{width:300,height:225,children:(0,e.createComponentVNode)(2,p.Window.Content,{children:[(0,e.createComponentVNode)(2,o.Section,{title:"Status",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Temperature",children:[(0,e.createComponentVNode)(2,o.AnimatedNumber,{value:c.temperature,format:function(){function m(l){return(0,a.toFixed)(l,2)}return m}()})," K"]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Pressure",children:[(0,e.createComponentVNode)(2,o.AnimatedNumber,{value:c.pressure,format:function(){function m(l){return(0,a.toFixed)(l,2)}return m}()})," kPa"]})]})}),(0,e.createComponentVNode)(2,o.Section,{title:"Controls",buttons:(0,e.createComponentVNode)(2,o.Button,{icon:c.on?"power-off":"times",content:c.on?"On":"Off",selected:c.on,onClick:function(){function m(){return i("power")}return m}()}),children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Setting",textAlign:"center",children:(0,e.createComponentVNode)(2,o.Button,{fluid:!0,icon:c.cooling?"temperature-low":"temperature-high",content:c.cooling?"Cooling":"Heating",selected:c.cooling,onClick:function(){function m(){return i("cooling")}return m}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Target Temperature",children:[(0,e.createComponentVNode)(2,o.Button,{icon:"fast-backward",disabled:c.target===c.min,title:"Minimum temperature",onClick:function(){function m(){return i("target",{target:c.min})}return m}()}),(0,e.createComponentVNode)(2,o.NumberInput,{animated:!0,value:Math.round(c.target),unit:"K",width:5.4,lineHeight:1.4,minValue:Math.round(c.min),maxValue:Math.round(c.max),step:5,stepPixelSize:3,onDrag:function(){function m(l,u){return i("target",{target:u})}return m}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"fast-forward",disabled:c.target===c.max,title:"Maximum Temperature",onClick:function(){function m(){return i("target",{target:c.max})}return m}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"sync",disabled:c.target===c.initial,title:"Room Temperature",onClick:function(){function m(){return i("target",{target:c.initial})}return m}()})]})]})})]})})}return y}()},20035:function(T,r,n){"use strict";r.__esModule=!0,r.TransferValve=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.TransferValve=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.tank_one,m=i.tank_two,l=i.attached_device,u=i.valve;return(0,e.createComponentVNode)(2,o.Window,{width:460,height:285,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Valve Status",children:(0,e.createComponentVNode)(2,t.Button,{icon:u?"unlock":"lock",content:u?"Open":"Closed",disabled:!c||!m,onClick:function(){function s(){return h("toggle")}return s}()})})})}),(0,e.createComponentVNode)(2,t.Section,{title:"Assembly",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"cog",content:"Configure Assembly",disabled:!l,onClick:function(){function s(){return h("device")}return s}()}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Attachment",children:l?(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:l,disabled:!l,onClick:function(){function s(){return h("remove_device")}return s}()}):(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"No Assembly"})})})}),(0,e.createComponentVNode)(2,t.Section,{title:"Attachment One",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Attachment",children:c?(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:c,disabled:!c,onClick:function(){function s(){return h("tankone")}return s}()}):(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"No Tank"})})})}),(0,e.createComponentVNode)(2,t.Section,{title:"Attachment Two",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Attachment",children:m?(0,e.createComponentVNode)(2,t.Button,{icon:"eject",content:m,disabled:!m,onClick:function(){function s(){return h("tanktwo")}return s}()}):(0,e.createComponentVNode)(2,t.Box,{color:"average",children:"No Tank"})})})})]})})}return b}()},78166:function(T,r,n){"use strict";r.__esModule=!0,r.TurbineComputer=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=n(44879),b=r.TurbineComputer=function(){function k(h,i){var c=(0,a.useBackend)(i),m=c.act,l=c.data,u=l.compressor,s=l.compressor_broken,d=l.turbine,v=l.turbine_broken,g=l.online,C=!!(u&&!s&&d&&!v);return(0,e.createComponentVNode)(2,o.Window,{width:400,height:200,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Status",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{icon:g?"power-off":"times",content:g?"Online":"Offline",selected:g,disabled:!C,onClick:function(){function f(){return m("toggle_power")}return f}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"times",content:"Disconnect",onClick:function(){function f(){return m("disconnect")}return f}()})],4),children:C?(0,e.createComponentVNode)(2,S):(0,e.createComponentVNode)(2,y)})})})}return k}(),y=function(h,i){var c=(0,a.useBackend)(i),m=c.data,l=m.compressor,u=m.compressor_broken,s=m.turbine,d=m.turbine_broken,v=m.online;return(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Compressor Status",color:!l||u?"bad":"good",children:u?l?"Offline":"Missing":"Online"}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Turbine Status",color:!s||d?"bad":"good",children:d?s?"Offline":"Missing":"Online"})]})},S=function(h,i){var c=(0,a.useBackend)(i),m=c.data,l=m.rpm,u=m.temperature,s=m.power,d=m.bearing_heat;return(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Turbine Speed",children:[l," RPM"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Internal Temp",children:[u," K"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Generated Power",children:[s," W"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Bearing Heat",children:(0,e.createComponentVNode)(2,t.ProgressBar,{value:d,minValue:0,maxValue:100,ranges:{good:[-1/0,60],average:[60,90],bad:[90,1/0]},children:(0,p.toFixed)(d)+"%"})})]})}},52847:function(T,r,n){"use strict";r.__esModule=!0,r.Uplink=void 0;var e=n(89005),a=n(88510),t=n(64795),o=n(25328),p=n(72253),b=n(36036),y=n(98595),S=n(3939),k=function(g){switch(g){case 0:return(0,e.createComponentVNode)(2,i);case 1:return(0,e.createComponentVNode)(2,c);case 2:return(0,e.createComponentVNode)(2,d);default:return"SOMETHING WENT VERY WRONG PLEASE AHELP"}},h=r.Uplink=function(){function v(g,C){var f=(0,p.useBackend)(C),N=f.act,V=f.data,B=V.cart,I=(0,p.useLocalState)(C,"tabIndex",0),L=I[0],w=I[1],A=(0,p.useLocalState)(C,"searchText",""),x=A[0],E=A[1];return(0,e.createComponentVNode)(2,y.Window,{width:900,height:600,theme:"syndicate",children:[(0,e.createComponentVNode)(2,S.ComplexModal),(0,e.createComponentVNode)(2,y.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,b.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Tabs,{children:[(0,e.createComponentVNode)(2,b.Tabs.Tab,{selected:L===0,onClick:function(){function P(){w(0),E("")}return P}(),icon:"store",children:"View Market"},"PurchasePage"),(0,e.createComponentVNode)(2,b.Tabs.Tab,{selected:L===1,onClick:function(){function P(){w(1),E("")}return P}(),icon:"shopping-cart",children:["View Shopping Cart ",B&&B.length?"("+B.length+")":""]},"Cart"),(0,e.createComponentVNode)(2,b.Tabs.Tab,{selected:L===2,onClick:function(){function P(){w(2),E("")}return P}(),icon:"user",children:"Exploitable Information"},"ExploitableInfo"),(0,e.createComponentVNode)(2,b.Tabs.Tab,{onClick:function(){function P(){return N("lock")}return P}(),icon:"lock",children:"Lock Uplink"},"LockUplink")]})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:k(L)})]})})]})}return v}(),i=function(g,C){var f=(0,p.useBackend)(C),N=f.act,V=f.data,B=V.crystals,I=V.cats,L=(0,p.useLocalState)(C,"uplinkItems",I[0].items),w=L[0],A=L[1],x=(0,p.useLocalState)(C,"searchText",""),E=x[0],P=x[1],D=function(U,z){z===void 0&&(z="");var $=(0,o.createSearch)(z,function(G){var X=G.hijack_only===1?"|hijack":"";return G.name+"|"+G.desc+"|"+G.cost+"tc"+X});return(0,t.flow)([(0,a.filter)(function(G){return G==null?void 0:G.name}),z&&(0,a.filter)($),(0,a.sortBy)(function(G){return G==null?void 0:G.name})])(U)},M=function(U){if(P(U),U==="")return A(I[0].items);A(D(I.map(function(z){return z.items}).flat(),U))},O=(0,p.useLocalState)(C,"showDesc",1),R=O[0],F=O[1];return(0,e.createComponentVNode)(2,b.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.Stack,{vertical:!0,children:(0,e.createComponentVNode)(2,b.Stack.Item,{children:(0,e.createComponentVNode)(2,b.Section,{title:"Current Balance: "+B+"TC",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,b.Button.Checkbox,{content:"Show Descriptions",checked:R,onClick:function(){function W(){return F(!R)}return W}()}),(0,e.createComponentVNode)(2,b.Button,{content:"Random Item",icon:"question",onClick:function(){function W(){return N("buyRandom")}return W}()}),(0,e.createComponentVNode)(2,b.Button,{content:"Refund Currently Held Item",icon:"undo",onClick:function(){function W(){return N("refund")}return W}()})],4),children:(0,e.createComponentVNode)(2,b.Input,{fluid:!0,placeholder:"Search Equipment",onInput:function(){function W(U,z){M(z)}return W}(),value:E})})})}),(0,e.createComponentVNode)(2,b.Stack,{fill:!0,mt:.3,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{width:"30%",children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,b.Tabs,{vertical:!0,children:I.map(function(W){return(0,e.createComponentVNode)(2,b.Tabs.Tab,{selected:E!==""?!1:W.items===w,onClick:function(){function U(){A(W.items),P("")}return U}(),children:W.cat},W)})})})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,b.Stack,{vertical:!0,children:w.map(function(W){return(0,e.createComponentVNode)(2,b.Stack.Item,{p:1,backgroundColor:"rgba(255, 0, 0, 0.1)",children:(0,e.createComponentVNode)(2,l,{i:W,showDecription:R},(0,o.decodeHtmlEntities)(W.name))},(0,o.decodeHtmlEntities)(W.name))})})})})]})]})},c=function(g,C){var f=(0,p.useBackend)(C),N=f.act,V=f.data,B=V.cart,I=V.crystals,L=V.cart_price,w=(0,p.useLocalState)(C,"showDesc",0),A=w[0],x=w[1];return(0,e.createComponentVNode)(2,b.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Current Balance: "+I+"TC",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,b.Button.Checkbox,{content:"Show Descriptions",checked:A,onClick:function(){function E(){return x(!A)}return E}()}),(0,e.createComponentVNode)(2,b.Button,{content:"Empty Cart",icon:"trash",onClick:function(){function E(){return N("empty_cart")}return E}(),disabled:!B}),(0,e.createComponentVNode)(2,b.Button,{content:"Purchase Cart ("+L+"TC)",icon:"shopping-cart",onClick:function(){function E(){return N("purchase_cart")}return E}(),disabled:!B||L>I})],4),children:(0,e.createComponentVNode)(2,b.Stack,{vertical:!0,children:B?B.map(function(E){return(0,e.createComponentVNode)(2,b.Stack.Item,{p:1,mr:1,backgroundColor:"rgba(255, 0, 0, 0.1)",children:(0,e.createComponentVNode)(2,l,{i:E,showDecription:A,buttons:(0,e.createComponentVNode)(2,s,{i:E})})},(0,o.decodeHtmlEntities)(E.name))}):(0,e.createComponentVNode)(2,b.Box,{italic:!0,children:"Your Shopping Cart is empty!"})})})}),(0,e.createComponentVNode)(2,m)]})},m=function(g,C){var f=(0,p.useBackend)(C),N=f.act,V=f.data,B=V.cats,I=V.lucky_numbers;return(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Suggested Purchases",buttons:(0,e.createComponentVNode)(2,b.Button,{icon:"dice",content:"See more suggestions",onClick:function(){function L(){return N("shuffle_lucky_numbers")}return L}()}),children:(0,e.createComponentVNode)(2,b.Stack,{wrap:!0,children:I.map(function(L){return B[L.cat].items[L.item]}).filter(function(L){return L!=null}).map(function(L,w){return(0,e.createComponentVNode)(2,b.Stack.Item,{p:1,mb:1,ml:1,width:34,backgroundColor:"rgba(255, 0, 0, 0.15)",children:(0,e.createComponentVNode)(2,l,{grow:!0,i:L})},w)})})})})},l=function(g,C){var f=g.i,N=g.showDecription,V=N===void 0?1:N,B=g.buttons,I=B===void 0?(0,e.createComponentVNode)(2,u,{i:f}):B;return(0,e.createComponentVNode)(2,b.Section,{title:(0,o.decodeHtmlEntities)(f.name),showBottom:V,buttons:I,children:V?(0,e.createComponentVNode)(2,b.Box,{italic:!0,children:(0,o.decodeHtmlEntities)(f.desc)}):null})},u=function(g,C){var f=(0,p.useBackend)(C),N=f.act,V=f.data,B=g.i,I=V.crystals;return(0,e.createFragment)([(0,e.createComponentVNode)(2,b.Button,{icon:"shopping-cart",color:B.hijack_only===1&&"red",tooltip:"Add to cart.",tooltipPosition:"left",onClick:function(){function L(){return N("add_to_cart",{item:B.obj_path})}return L}(),disabled:B.cost>I}),(0,e.createComponentVNode)(2,b.Button,{content:"Buy ("+B.cost+"TC)"+(B.refundable?" [Refundable]":""),color:B.hijack_only===1&&"red",tooltip:B.hijack_only===1&&"Hijack Agents Only!",tooltipPosition:"left",onClick:function(){function L(){return N("buyItem",{item:B.obj_path})}return L}(),disabled:B.cost>I})],4)},s=function(g,C){var f=(0,p.useBackend)(C),N=f.act,V=f.data,B=g.i,I=V.exploitable;return(0,e.createComponentVNode)(2,b.Stack,{children:[(0,e.createComponentVNode)(2,b.Button,{icon:"times",content:"("+B.cost*B.amount+"TC)",tooltip:"Remove from cart.",tooltipPosition:"left",onClick:function(){function L(){return N("remove_from_cart",{item:B.obj_path})}return L}()}),(0,e.createComponentVNode)(2,b.Button,{icon:"minus",tooltip:B.limit===0&&"Discount already redeemed!",ml:"5px",onClick:function(){function L(){return N("set_cart_item_quantity",{item:B.obj_path,quantity:--B.amount})}return L}(),disabled:B.amount<=0}),(0,e.createComponentVNode)(2,b.Button.Input,{content:B.amount,width:"45px",tooltipPosition:"bottom-end",tooltip:B.limit===0&&"Discount already redeemed!",onCommit:function(){function L(w,A){return N("set_cart_item_quantity",{item:B.obj_path,quantity:A})}return L}(),disabled:B.limit!==-1&&B.amount>=B.limit&&B.amount<=0}),(0,e.createComponentVNode)(2,b.Button,{mb:.3,icon:"plus",tooltipPosition:"bottom-start",tooltip:B.limit===0&&"Discount already redeemed!",onClick:function(){function L(){return N("set_cart_item_quantity",{item:B.obj_path,quantity:++B.amount})}return L}(),disabled:B.limit!==-1&&B.amount>=B.limit})]})},d=function(g,C){var f=(0,p.useBackend)(C),N=f.act,V=f.data,B=V.exploitable,I=(0,p.useLocalState)(C,"selectedRecord",B[0]),L=I[0],w=I[1],A=(0,p.useLocalState)(C,"searchText",""),x=A[0],E=A[1],P=function(O,R){R===void 0&&(R="");var F=(0,o.createSearch)(R,function(W){return W.name});return(0,t.flow)([(0,a.filter)(function(W){return W==null?void 0:W.name}),R&&(0,a.filter)(F),(0,a.sortBy)(function(W){return W.name})])(O)},D=P(B,x);return(0,e.createComponentVNode)(2,b.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,b.Stack.Item,{width:"30%",children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:"Exploitable Records",children:[(0,e.createComponentVNode)(2,b.Input,{fluid:!0,mb:1,placeholder:"Search Crew",onInput:function(){function M(O,R){return E(R)}return M}()}),(0,e.createComponentVNode)(2,b.Tabs,{vertical:!0,children:D.map(function(M){return(0,e.createComponentVNode)(2,b.Tabs.Tab,{selected:M===L,onClick:function(){function O(){return w(M)}return O}(),children:M.name},M)})})]})}),(0,e.createComponentVNode)(2,b.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,b.Section,{fill:!0,scrollable:!0,title:L.name,children:(0,e.createComponentVNode)(2,b.LabeledList,{children:[(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Age",children:L.age}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Fingerprint",children:L.fingerprint}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Rank",children:L.rank}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Sex",children:L.sex}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Species",children:L.species})]})})})]})}},12261:function(T,r,n){"use strict";r.__esModule=!0,r.Vending=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=function(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=S.product,l=S.productStock,u=S.productIcon,s=S.productIconState,d=c.chargesMoney,v=c.user,g=c.usermoney,C=c.inserted_cash,f=c.vend_ready,N=c.inserted_item_name,V=!d||m.price===0,B="ERROR!",I="";V?(B="FREE",I="arrow-circle-down"):(B=m.price,I="shopping-cart");var L=!f||l===0||!V&&m.price>g&&m.price>C;return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,children:(0,e.createComponentVNode)(2,t.DmIcon,{verticalAlign:"middle",icon:u,icon_state:s,fallback:(0,e.createComponentVNode)(2,t.Icon,{p:.66,name:"spinner",size:2,spin:!0})})}),(0,e.createComponentVNode)(2,t.Table.Cell,{bold:!0,children:m.name}),(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Box,{color:l<=0&&"bad"||l<=m.max_amount/2&&"average"||"good",children:[l," in stock"]})}),(0,e.createComponentVNode)(2,t.Table.Cell,{collapsing:!0,textAlign:"center",children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,disabled:L,icon:I,content:B,textAlign:"left",onClick:function(){function w(){return i("vend",{inum:m.inum})}return w}()})})]})},b=r.Vending=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.user,l=c.usermoney,u=c.inserted_cash,s=c.chargesMoney,d=c.product_records,v=d===void 0?[]:d,g=c.hidden_records,C=g===void 0?[]:g,f=c.stock,N=c.vend_ready,V=c.inserted_item_name,B=c.panel_open,I=c.speaker,L;return L=[].concat(v),c.extended_inventory&&(L=[].concat(L,C)),L=L.filter(function(w){return!!w}),(0,e.createComponentVNode)(2,o.Window,{title:"Vending Machine",width:450,height:Math.min((s?171:89)+L.length*32,585),children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[!!s&&(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"User",buttons:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:!!V&&(0,e.createComponentVNode)(2,t.Button,{fluid:!0,icon:"eject",content:(0,e.createVNode)(1,"span",null,V,0,{style:{"text-transform":"capitalize"}}),onClick:function(){function w(){return i("eject_item",{})}return w}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{disabled:!u,icon:"money-bill-wave-alt",content:u?(0,e.createFragment)([(0,e.createVNode)(1,"b",null,u,0),(0,e.createTextVNode)(" credits")],0):"Dispense Change",tooltip:u?"Dispense Change":null,textAlign:"left",onClick:function(){function w(){return i("change")}return w}()})})]}),children:m&&(0,e.createComponentVNode)(2,t.Box,{children:["Welcome, ",(0,e.createVNode)(1,"b",null,m.name,0),", ",(0,e.createVNode)(1,"b",null,m.job||"Unemployed",0),"!",(0,e.createVNode)(1,"br"),"Your balance is ",(0,e.createVNode)(1,"b",null,[l,(0,e.createTextVNode)(" credits")],0),".",(0,e.createVNode)(1,"br")]})})}),!!B&&(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{title:"Maintenance",children:(0,e.createComponentVNode)(2,t.Button,{icon:I?"check":"volume-mute",selected:I,content:"Speaker",textAlign:"left",onClick:function(){function w(){return i("toggle_voice",{})}return w}()})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:"Products",children:(0,e.createComponentVNode)(2,t.Table,{children:L.map(function(w){return(0,e.createComponentVNode)(2,p,{product:w,productStock:f[w.name],productIcon:w.icon,productIconState:w.icon_state},w.name)})})})})]})})})}return y}()},68971:function(T,r,n){"use strict";r.__esModule=!0,r.VolumeMixer=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.VolumeMixer=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.channels;return(0,e.createComponentVNode)(2,o.Window,{width:350,height:Math.min(95+c.length*50,565),children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,children:c.map(function(m,l){return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.25rem",color:"label",mt:l>0&&"0.5rem",children:m.name}),(0,e.createComponentVNode)(2,t.Box,{mt:"0.5rem",children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{mr:.5,children:(0,e.createComponentVNode)(2,t.Button,{width:"24px",color:"transparent",children:(0,e.createComponentVNode)(2,t.Icon,{name:"volume-off",size:"1.5",mt:"0.1rem",onClick:function(){function u(){return h("volume",{channel:m.num,volume:0})}return u}()})})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,mx:"0.5rem",children:(0,e.createComponentVNode)(2,t.Slider,{minValue:0,maxValue:100,stepPixelSize:3.13,value:m.volume,onChange:function(){function u(s,d){return h("volume",{channel:m.num,volume:d})}return u}()})}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{width:"24px",color:"transparent",children:(0,e.createComponentVNode)(2,t.Icon,{name:"volume-up",size:"1.5",mt:"0.1rem",onClick:function(){function u(){return h("volume",{channel:m.num,volume:100})}return u}()})})})]})})],4,m.num)})})})})}return b}()},2510:function(T,r,n){"use strict";r.__esModule=!0,r.VotePanel=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.VotePanel=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.remaining,m=i.question,l=i.choices,u=i.user_vote,s=i.counts,d=i.show_counts;return(0,e.createComponentVNode)(2,o.Window,{width:400,height:360,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,title:m,children:[(0,e.createComponentVNode)(2,t.Box,{mb:1.5,ml:.5,children:["Time remaining: ",Math.round(c/10),"s"]}),l.map(function(v){return(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{mb:1,fluid:!0,translucent:!0,lineHeight:3,multiLine:v,content:v+(d?" ("+(s[v]||0)+")":""),onClick:function(){function g(){return h("vote",{target:v})}return g}(),selected:v===u})},v)})]})})})}return b}()},30138:function(T,r,n){"use strict";r.__esModule=!0,r.Wires=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.Wires=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.wires||[],m=i.status||[],l=56+c.length*23+(status?0:15+m.length*17);return(0,e.createComponentVNode)(2,o.Window,{width:350,height:l,children:(0,e.createComponentVNode)(2,o.Window.Content,{children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Section,{fill:!0,scrollable:!0,children:(0,e.createComponentVNode)(2,t.LabeledList,{children:c.map(function(u){return(0,e.createComponentVNode)(2,t.LabeledList.Item,{className:"candystripe",label:u.color_name,labelColor:u.seen_color,color:u.seen_color,buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Button,{content:u.cut?"Mend":"Cut",onClick:function(){function s(){return h("cut",{wire:u.color})}return s}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Pulse",onClick:function(){function s(){return h("pulse",{wire:u.color})}return s}()}),(0,e.createComponentVNode)(2,t.Button,{content:u.attached?"Detach":"Attach",onClick:function(){function s(){return h("attach",{wire:u.color})}return s}()})],4),children:!!u.wire&&(0,e.createVNode)(1,"i",null,[(0,e.createTextVNode)("("),u.wire,(0,e.createTextVNode)(")")],0)},u.seen_color)})})})}),!!m.length&&(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Section,{children:m.map(function(u){return(0,e.createComponentVNode)(2,t.Box,{color:"lightgray",children:u},u)})})})]})})})}return b}()},21400:function(T,r,n){"use strict";r.__esModule=!0,r.WizardApprenticeContract=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(98595),p=r.WizardApprenticeContract=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.used;return(0,e.createComponentVNode)(2,o.Window,{width:500,height:555,children:(0,e.createComponentVNode)(2,o.Window.Content,{scrollable:!0,children:[(0,e.createComponentVNode)(2,t.Section,{title:"Contract of Apprenticeship",children:["Using this contract, you may summon an apprentice to aid you on your mission.",(0,e.createVNode)(1,"p",null,"If you are unable to establish contact with your apprentice, you can feed the contract back to the spellbook to refund your points.",16),c?(0,e.createComponentVNode)(2,t.Box,{bold:!0,color:"red",children:"You've already summoned an apprentice or you are in process of summoning one."}):""]}),(0,e.createComponentVNode)(2,t.Section,{title:"Which school of magic is your apprentice studying?",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Fire",children:["Your apprentice is skilled in bending fire. ",(0,e.createVNode)(1,"br"),"They know Fireball, Sacred Flame, and Ethereal Jaunt.",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{content:"Select",disabled:c,onClick:function(){function m(){return h("fire")}return m}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Translocation",children:["Your apprentice is able to defy physics, learning how to move through bluespace. ",(0,e.createVNode)(1,"br"),"They know Teleport, Blink and Ethereal Jaunt.",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{content:"Select",disabled:c,onClick:function(){function m(){return h("translocation")}return m}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Restoration",children:["Your apprentice is dedicated to supporting your magical prowess.",(0,e.createVNode)(1,"br"),"They come equipped with a Staff of Healing, have the unique ability to teleport back to you, and know Charge and Knock.",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{content:"Select",disabled:c,onClick:function(){function m(){return h("restoration")}return m}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Stealth",children:["Your apprentice is learning the art of infiltrating mundane facilities. ",(0,e.createVNode)(1,"br"),"They know Mindswap, Knock, Homing Toolbox, and Disguise Self, all of which can be cast without robes. They also join you in a Maintenance Dweller disguise, complete with Gloves of Shock Immunity and a Belt of Tools.",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{content:"Select",disabled:c,onClick:function(){function m(){return h("stealth")}return m}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Honk",children:["Your apprentice is here to spread the Honkmother's blessings.",(0,e.createVNode)(1,"br"),"They know Banana Touch, Instant Summons, Ethereal Jaunt, and come equipped with a Staff of Slipping."," ",(0,e.createVNode)(1,"br"),"While under your tutelage, they have been 'blessed' with clown shoes that are impossible to remove.",(0,e.createVNode)(1,"br"),(0,e.createComponentVNode)(2,t.Button,{content:"Select",disabled:c,onClick:function(){function m(){return h("honk")}return m}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Divider)]})})]})})}return b}()},49148:function(T,r,n){"use strict";r.__esModule=!0,r.AccessList=void 0;var e=n(89005),a=n(88510),t=n(72253),o=n(36036);function p(h,i){var c=typeof Symbol!="undefined"&&h[Symbol.iterator]||h["@@iterator"];if(c)return(c=c.call(h)).next.bind(c);if(Array.isArray(h)||(c=b(h))||i&&h&&typeof h.length=="number"){c&&(h=c);var m=0;return function(){return m>=h.length?{done:!0}:{done:!1,value:h[m++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function b(h,i){if(h){if(typeof h=="string")return y(h,i);var c={}.toString.call(h).slice(8,-1);return c==="Object"&&h.constructor&&(c=h.constructor.name),c==="Map"||c==="Set"?Array.from(h):c==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c)?y(h,i):void 0}}function y(h,i){(i==null||i>h.length)&&(i=h.length);for(var c=0,m=Array(i);c0&&!V.includes(R.ref)&&!f.includes(R.ref),checked:f.includes(R.ref),onClick:function(){function F(){return B(R.ref)}return F}()},R.desc)})]})]})})}return h}()},26991:function(T,r,n){"use strict";r.__esModule=!0,r.AtmosScan=void 0;var e=n(89005),a=n(88510),t=n(72253),o=n(36036),p=function(S,k,h,i,c){return Si?"average":S>c?"bad":"good"},b=r.AtmosScan=function(){function y(S,k){var h=S.data.aircontents;return(0,e.createComponentVNode)(2,o.Box,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,a.filter)(function(i){return i.val!=="0"||i.entry==="Pressure"||i.entry==="Temperature"})(h).map(function(i){return(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:i.entry,color:p(i.val,i.bad_low,i.poor_low,i.poor_high,i.bad_high),children:[i.val,i.units]},i.entry)})})})}return y}()},85870:function(T,r,n){"use strict";r.__esModule=!0,r.BeakerContents=void 0;var e=n(89005),a=n(36036),t=n(15964),o=function(y){return y+" unit"+(y===1?"":"s")},p=r.BeakerContents=function(){function b(y){var S=y.beakerLoaded,k=y.beakerContents,h=k===void 0?[]:k,i=y.buttons;return(0,e.createComponentVNode)(2,a.Stack,{vertical:!0,children:[!S&&(0,e.createComponentVNode)(2,a.Stack.Item,{color:"label",children:"No beaker loaded."})||h.length===0&&(0,e.createComponentVNode)(2,a.Stack.Item,{color:"label",children:"Beaker is empty."}),h.map(function(c,m){return(0,e.createComponentVNode)(2,a.Stack,{children:[(0,e.createComponentVNode)(2,a.Stack.Item,{color:"label",grow:!0,children:[o(c.volume)," of ",c.name]},c.name),!!i&&(0,e.createComponentVNode)(2,a.Stack.Item,{children:i(c,m)})]},c.name)})]})}return b}();p.propTypes={beakerLoaded:t.bool,beakerContents:t.array,buttons:t.arrayOf(t.element)}},92963:function(T,r,n){"use strict";r.__esModule=!0,r.BotStatus=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.BotStatus=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.act,h=S.data,i=h.locked,c=h.noaccess,m=h.maintpanel,l=h.on,u=h.autopatrol,s=h.canhack,d=h.emagged,v=h.remote_disabled;return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.NoticeBox,{children:["Swipe an ID card to ",i?"unlock":"lock"," this interface."]}),(0,e.createComponentVNode)(2,t.Section,{title:"General Settings",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:(0,e.createComponentVNode)(2,t.Button,{icon:l?"power-off":"times",content:l?"On":"Off",selected:l,disabled:c,onClick:function(){function g(){return k("power")}return g}()})}),u!==null&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Patrol",children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:u,content:"Auto Patrol",disabled:c,onClick:function(){function g(){return k("autopatrol")}return g}()})}),!!m&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Maintenance Panel",children:(0,e.createComponentVNode)(2,t.Box,{color:"bad",children:"Panel Open!"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Safety System",children:(0,e.createComponentVNode)(2,t.Box,{color:d?"bad":"good",children:d?"DISABLED!":"Enabled"})}),!!s&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Hacking",children:(0,e.createComponentVNode)(2,t.Button,{icon:"terminal",content:d?"Restore Safties":"Hack",disabled:c,color:"bad",onClick:function(){function g(){return k("hack")}return g}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Remote Access",children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:!v,content:"AI Remote Control",disabled:c,onClick:function(){function g(){return k("disableremote")}return g}()})})]})})],4)}return p}()},3939:function(T,r,n){"use strict";r.__esModule=!0,r.modalRegisterBodyOverride=r.modalOpen=r.modalClose=r.modalAnswer=r.ComplexModal=void 0;var e=n(89005),a=n(72253),t=n(36036),o={},p=r.modalOpen=function(){function h(i,c,m){var l=(0,a.useBackend)(i),u=l.act,s=l.data,d=Object.assign(s.modal?s.modal.args:{},m||{});u("modal_open",{id:c,arguments:JSON.stringify(d)})}return h}(),b=r.modalRegisterBodyOverride=function(){function h(i,c){o[i]=c}return h}(),y=r.modalAnswer=function(){function h(i,c,m,l){var u=(0,a.useBackend)(i),s=u.act,d=u.data;if(d.modal){var v=Object.assign(d.modal.args||{},l||{});s("modal_answer",{id:c,answer:m,arguments:JSON.stringify(v)})}}return h}(),S=r.modalClose=function(){function h(i,c){var m=(0,a.useBackend)(i),l=m.act;l("modal_close",{id:c})}return h}(),k=r.ComplexModal=function(){function h(i,c){var m=(0,a.useBackend)(c),l=m.data;if(l.modal){var u=l.modal,s=u.id,d=u.text,v=u.type,g,C=(0,e.createComponentVNode)(2,t.Button,{className:"Button--modal",icon:"arrow-left",content:"Cancel",onClick:function(){function L(){return S(c)}return L}()}),f,N,V="auto";if(o[s])f=o[s](l.modal,c);else if(v==="input"){var B=l.modal.value;g=function(){function L(w){return y(c,s,B)}return L}(),f=(0,e.createComponentVNode)(2,t.Input,{value:l.modal.value,placeholder:"ENTER to submit",width:"100%",my:"0.5rem",autofocus:!0,onChange:function(){function L(w,A){B=A}return L}()}),N=(0,e.createComponentVNode)(2,t.Box,{mt:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"arrow-left",content:"Cancel",color:"grey",onClick:function(){function L(){return S(c)}return L}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"check",content:"Confirm",color:"good",float:"right",m:"0",onClick:function(){function L(){return y(c,s,B)}return L}()}),(0,e.createComponentVNode)(2,t.Box,{clear:"both"})]})}else if(v==="choice"){var I=typeof l.modal.choices=="object"?Object.values(l.modal.choices):l.modal.choices;f=(0,e.createComponentVNode)(2,t.Dropdown,{options:I,selected:l.modal.value,width:"100%",my:"0.5rem",onSelected:function(){function L(w){return y(c,s,w)}return L}()}),V="initial"}else v==="bento"?f=(0,e.createComponentVNode)(2,t.Stack,{spacingPrecise:"1",wrap:"wrap",my:"0.5rem",maxHeight:"1%",children:l.modal.choices.map(function(L,w){return(0,e.createComponentVNode)(2,t.Stack.Item,{flex:"1 1 auto",children:(0,e.createComponentVNode)(2,t.Button,{selected:w+1===parseInt(l.modal.value,10),onClick:function(){function A(){return y(c,s,w+1)}return A}(),children:(0,e.createVNode)(1,"img",null,null,1,{src:L})})},w)})}):v==="boolean"&&(N=(0,e.createComponentVNode)(2,t.Box,{mt:"0.5rem",children:[(0,e.createComponentVNode)(2,t.Button,{icon:"times",content:l.modal.no_text,color:"bad",float:"left",mb:"0",onClick:function(){function L(){return y(c,s,0)}return L}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"check",content:l.modal.yes_text,color:"good",float:"right",m:"0",onClick:function(){function L(){return y(c,s,1)}return L}()}),(0,e.createComponentVNode)(2,t.Box,{clear:"both"})]}));return(0,e.createComponentVNode)(2,t.Modal,{maxWidth:i.maxWidth||window.innerWidth/2+"px",maxHeight:i.maxHeight||window.innerHeight/2+"px",onEnter:g,mx:"auto",overflowY:V,"padding-bottom":"5px",children:[d&&(0,e.createComponentVNode)(2,t.Box,{inline:!0,children:d}),o[s]&&C,f,N]})}}return h}()},41874:function(T,r,n){"use strict";r.__esModule=!0,r.CrewManifest=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(25328),p=n(76910),b=p.COLORS.department,y=["Captain","Head of Security","Chief Engineer","Chief Medical Officer","Research Director","Head of Personnel","Quartermaster"],S=function(m){return y.indexOf(m)!==-1?"green":"orange"},k=function(m){if(y.indexOf(m)!==-1)return!0},h=function(m){return m.length>0&&(0,e.createComponentVNode)(2,t.Table,{children:[(0,e.createComponentVNode)(2,t.Table.Row,{header:!0,color:"white",children:[(0,e.createComponentVNode)(2,t.Table.Cell,{width:"50%",children:"Name"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"35%",children:"Rank"}),(0,e.createComponentVNode)(2,t.Table.Cell,{width:"15%",children:"Active"})]}),m.map(function(l){return(0,e.createComponentVNode)(2,t.Table.Row,{color:S(l.rank),bold:k(l.rank),children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,o.decodeHtmlEntities)(l.name)}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,o.decodeHtmlEntities)(l.rank)}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:l.active})]},l.name+l.rank)})]})},i=r.CrewManifest=function(){function c(m,l){var u=(0,a.useBackend)(l),s=u.act,d;if(m.data)d=m.data;else{var v=(0,a.useBackend)(l),g=v.data;d=g}var C=d,f=C.manifest,N=f.heads,V=f.sec,B=f.eng,I=f.med,L=f.sci,w=f.ser,A=f.sup,x=f.misc;return(0,e.createComponentVNode)(2,t.Box,{children:[(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.command,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Command"})}),level:2,children:h(N)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.security,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Security"})}),level:2,children:h(V)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.engineering,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Engineering"})}),level:2,children:h(B)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.medical,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Medical"})}),level:2,children:h(I)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.science,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Science"})}),level:2,children:h(L)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.service,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Service"})}),level:2,children:h(w)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{backgroundColor:b.supply,m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Supply"})}),level:2,children:h(A)}),(0,e.createComponentVNode)(2,t.Section,{title:(0,e.createComponentVNode)(2,t.Box,{m:-1,pt:1,pb:1,children:(0,e.createComponentVNode)(2,t.Box,{ml:1,textAlign:"center",fontSize:1.4,children:"Misc"})}),level:2,children:h(x)})]})}return c}()},19203:function(T,r,n){"use strict";r.__esModule=!0,r.InputButtons=void 0;var e=n(89005),a=n(36036),t=n(72253),o=r.InputButtons=function(){function p(b,y){var S=(0,t.useBackend)(y),k=S.act,h=S.data,i=h.large_buttons,c=h.swapped_buttons,m=b.input,l=b.message,u=b.disabled,s=(0,e.createComponentVNode)(2,a.Button,{color:"good",content:"Submit",bold:!!i,fluid:!!i,onClick:function(){function v(){return k("submit",{entry:m})}return v}(),textAlign:"center",tooltip:i&&l,disabled:u,width:!i&&6}),d=(0,e.createComponentVNode)(2,a.Button,{color:"bad",content:"Cancel",bold:!!i,fluid:!!i,onClick:function(){function v(){return k("cancel")}return v}(),textAlign:"center",width:!i&&6});return(0,e.createComponentVNode)(2,a.Flex,{fill:!0,align:"center",direction:c?"row-reverse":"row",justify:"space-around",children:[i?(0,e.createComponentVNode)(2,a.Flex.Item,{grow:!0,ml:c?.5:0,mr:c?0:.5,children:d}):(0,e.createComponentVNode)(2,a.Flex.Item,{children:d}),!i&&l&&(0,e.createComponentVNode)(2,a.Flex.Item,{children:(0,e.createComponentVNode)(2,a.Box,{color:"label",textAlign:"center",children:l})}),i?(0,e.createComponentVNode)(2,a.Flex.Item,{grow:!0,mr:c?.5:0,ml:c?0:.5,children:s}):(0,e.createComponentVNode)(2,a.Flex.Item,{children:s})]})}return p}()},195:function(T,r,n){"use strict";r.__esModule=!0,r.InterfaceLockNoticeBox=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.InterfaceLockNoticeBox=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.act,h=S.data,i=b.siliconUser,c=i===void 0?h.siliconUser:i,m=b.locked,l=m===void 0?h.locked:m,u=b.normallyLocked,s=u===void 0?h.normallyLocked:u,d=b.onLockStatusChange,v=d===void 0?function(){return k("lock")}:d,g=b.accessText,C=g===void 0?"an ID card":g;return c?(0,e.createComponentVNode)(2,t.NoticeBox,{color:c&&"grey",children:(0,e.createComponentVNode)(2,t.Flex,{align:"center",children:[(0,e.createComponentVNode)(2,t.Flex.Item,{children:"Interface lock status:"}),(0,e.createComponentVNode)(2,t.Flex.Item,{grow:"1"}),(0,e.createComponentVNode)(2,t.Flex.Item,{children:(0,e.createComponentVNode)(2,t.Button,{m:"0",color:s?"red":"green",icon:s?"lock":"unlock",content:s?"Locked":"Unlocked",onClick:function(){function f(){v&&v(!l)}return f}()})})]})}):(0,e.createComponentVNode)(2,t.NoticeBox,{children:["Swipe ",C," to ",l?"unlock":"lock"," this interface."]})}return p}()},51057:function(T,r,n){"use strict";r.__esModule=!0,r.Loader=void 0;var e=n(89005),a=n(44879),t=n(36036),o=r.Loader=function(){function p(b){var y=b.value;return(0,e.createVNode)(1,"div","AlertModal__Loader",(0,e.createComponentVNode)(2,t.Box,{className:"AlertModal__LoaderProgress",style:{width:(0,a.clamp01)(y)*100+"%"}}),2)}return p}()},321:function(T,r,n){"use strict";r.__esModule=!0,r.LoginInfo=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.LoginInfo=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.act,h=S.data,i=h.loginState;if(h)return(0,e.createComponentVNode)(2,t.NoticeBox,{info:!0,children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,mt:.5,children:["Logged in as: ",i.name," (",i.rank,")"]}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:[(0,e.createComponentVNode)(2,t.Button,{icon:"eject",disabled:!i.id,content:"Eject ID",color:"good",onClick:function(){function c(){return k("login_eject")}return c}()}),(0,e.createComponentVNode)(2,t.Button,{icon:"sign-out-alt",content:"Logout",color:"good",onClick:function(){function c(){return k("login_logout")}return c}()})]})]})})}return p}()},5485:function(T,r,n){"use strict";r.__esModule=!0,r.LoginScreen=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.LoginScreen=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.act,h=S.data,i=h.loginState,c=h.isAI,m=h.isRobot,l=h.isAdmin;return(0,e.createComponentVNode)(2,t.Section,{title:"Welcome",fill:!0,stretchContents:!0,children:(0,e.createComponentVNode)(2,t.Flex,{height:"100%",align:"center",justify:"center",children:(0,e.createComponentVNode)(2,t.Flex.Item,{textAlign:"center",mt:"-2rem",children:[(0,e.createComponentVNode)(2,t.Box,{fontSize:"1.5rem",bold:!0,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"user-circle",verticalAlign:"middle",size:3,mr:"1rem"}),"Guest"]}),(0,e.createComponentVNode)(2,t.Box,{color:"label",my:"1rem",children:["ID:",(0,e.createComponentVNode)(2,t.Button,{icon:"id-card",content:i.id?i.id:"----------",ml:"0.5rem",onClick:function(){function u(){return k("login_insert")}return u}()})]}),(0,e.createComponentVNode)(2,t.Button,{icon:"sign-in-alt",disabled:!i.id,content:"Login",onClick:function(){function u(){return k("login_login",{login_type:1})}return u}()}),!!c&&(0,e.createComponentVNode)(2,t.Button,{icon:"sign-in-alt",content:"Login as AI",onClick:function(){function u(){return k("login_login",{login_type:2})}return u}()}),!!m&&(0,e.createComponentVNode)(2,t.Button,{icon:"sign-in-alt",content:"Login as Cyborg",onClick:function(){function u(){return k("login_login",{login_type:3})}return u}()}),!!l&&(0,e.createComponentVNode)(2,t.Button,{icon:"sign-in-alt",content:"CentComm Secure Login",onClick:function(){function u(){return k("login_login",{login_type:4})}return u}()})]})})})}return p}()},62411:function(T,r,n){"use strict";r.__esModule=!0,r.Operating=void 0;var e=n(89005),a=n(36036),t=n(15964),o=r.Operating=function(){function p(b){var y=b.operating,S=b.name;if(y)return(0,e.createComponentVNode)(2,a.Dimmer,{children:(0,e.createComponentVNode)(2,a.Flex,{mb:"30px",children:(0,e.createComponentVNode)(2,a.Flex.Item,{bold:!0,color:"silver",textAlign:"center",children:[(0,e.createComponentVNode)(2,a.Icon,{name:"spinner",spin:!0,size:4,mb:"15px"}),(0,e.createVNode)(1,"br"),"The ",S," is processing..."]})})})}return p}();o.propTypes={operating:t.bool,name:t.string}},13545:function(T,r,n){"use strict";r.__esModule=!0,r.Signaler=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=r.Signaler=function(){function b(y,S){var k=(0,t.useBackend)(S),h=k.act,i=y.data,c=i.code,m=i.frequency,l=i.minFrequency,u=i.maxFrequency;return(0,e.createComponentVNode)(2,o.Section,{children:[(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Frequency",children:(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,step:.2,stepPixelSize:6,minValue:l/10,maxValue:u/10,value:m/10,format:function(){function s(d){return(0,a.toFixed)(d,1)}return s}(),width:"80px",onDrag:function(){function s(d,v){return h("freq",{freq:v})}return s}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Code",children:(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,step:1,stepPixelSize:6,minValue:1,maxValue:100,value:c,width:"80px",onDrag:function(){function s(d,v){return h("code",{code:v})}return s}()})})]}),(0,e.createComponentVNode)(2,o.Button,{mt:1,fluid:!0,icon:"arrow-up",content:"Send Signal",textAlign:"center",onClick:function(){function s(){return h("signal")}return s}()})]})}return b}()},41984:function(T,r,n){"use strict";r.__esModule=!0,r.SimpleRecords=void 0;var e=n(89005),a=n(72253),t=n(25328),o=n(64795),p=n(88510),b=n(36036),y=r.SimpleRecords=function(){function h(i,c){var m=i.data.records;return(0,e.createComponentVNode)(2,b.Box,{children:m?(0,e.createComponentVNode)(2,k,{data:i.data,recordType:i.recordType}):(0,e.createComponentVNode)(2,S,{data:i.data})})}return h}(),S=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=i.data.recordsList,s=(0,a.useLocalState)(c,"searchText",""),d=s[0],v=s[1],g=function(N,V){V===void 0&&(V="");var B=(0,t.createSearch)(V,function(I){return I.Name});return(0,o.flow)([(0,p.filter)(function(I){return I==null?void 0:I.Name}),V&&(0,p.filter)(B),(0,p.sortBy)(function(I){return I.Name})])(u)},C=g(u,d);return(0,e.createComponentVNode)(2,b.Box,{children:[(0,e.createComponentVNode)(2,b.Input,{fluid:!0,mb:1,placeholder:"Search records...",onInput:function(){function f(N,V){return v(V)}return f}()}),C.map(function(f){return(0,e.createComponentVNode)(2,b.Box,{children:(0,e.createComponentVNode)(2,b.Button,{mb:.5,content:f.Name,icon:"user",onClick:function(){function N(){return l("Records",{target:f.uid})}return N}()})},f)})]})},k=function(i,c){var m=(0,a.useBackend)(c),l=m.act,u=i.data.records,s=u.general,d=u.medical,v=u.security,g;switch(i.recordType){case"MED":g=(0,e.createComponentVNode)(2,b.Section,{level:2,title:"Medical Data",children:d?(0,e.createComponentVNode)(2,b.LabeledList,{children:[(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Blood Type",children:d.blood_type}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Minor Disabilities",children:d.mi_dis}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Details",children:d.mi_dis_d}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Major Disabilities",children:d.ma_dis}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Details",children:d.ma_dis_d}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Allergies",children:d.alg}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Details",children:d.alg_d}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Current Diseases",children:d.cdi}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Details",children:d.cdi_d}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Important Notes",preserveWhitespace:!0,children:d.notes})]}):(0,e.createComponentVNode)(2,b.Box,{color:"red",bold:!0,children:"Medical record lost!"})});break;case"SEC":g=(0,e.createComponentVNode)(2,b.Section,{level:2,title:"Security Data",children:v?(0,e.createComponentVNode)(2,b.LabeledList,{children:[(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Criminal Status",children:v.criminal}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Minor Crimes",children:v.mi_crim}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Details",children:v.mi_crim_d}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Major Crimes",children:v.ma_crim}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Details",children:v.ma_crim_d}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Important Notes",preserveWhitespace:!0,children:v.notes})]}):(0,e.createComponentVNode)(2,b.Box,{color:"red",bold:!0,children:"Security record lost!"})});break}return(0,e.createComponentVNode)(2,b.Box,{children:[(0,e.createComponentVNode)(2,b.Section,{title:"General Data",children:s?(0,e.createComponentVNode)(2,b.LabeledList,{children:[(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Name",children:s.name}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Sex",children:s.sex}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Species",children:s.species}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Age",children:s.age}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Rank",children:s.rank}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Fingerprint",children:s.fingerprint}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Physical Status",children:s.p_stat}),(0,e.createComponentVNode)(2,b.LabeledList.Item,{label:"Mental Status",children:s.m_stat})]}):(0,e.createComponentVNode)(2,b.Box,{color:"red",bold:!0,children:"General record lost!"})}),g]})}},22091:function(T,r,n){"use strict";r.__esModule=!0,r.TemporaryNotice=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.TemporaryNotice=function(){function p(b,y){var S,k=(0,a.useBackend)(y),h=k.act,i=k.data,c=i.temp;if(c){var m=(S={},S[c.style]=!0,S);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,t.NoticeBox,Object.assign({},m,{children:(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,mt:.5,children:c.text}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{icon:"times-circle",onClick:function(){function l(){return h("cleartemp")}return l}()})})]})})))}}return p}()},95213:function(T,r,n){"use strict";r.__esModule=!0,r.goonstation_PTL=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(49968),p=n(98595);/** +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * @file * @copyright 2020 * @author Sovexe (https://github.com/Sovexe) * @license ISC +<<<<<<< HEAD */var b=r.goonstation_PTL=function(){function g(l,c){var m=(0,a.useBackend)(c),i=m.data,u=i.total_earnings,s=i.total_energy,d=i.name,v=d===void 0?"Power Transmission Laser":d;return(0,e.createComponentVNode)(2,f.Window,{title:"Power Transmission Laser",width:"310",height:"485",children:(0,e.createComponentVNode)(2,f.Window.Content,{children:[(0,e.createComponentVNode)(2,y),(0,e.createComponentVNode)(2,I),(0,e.createComponentVNode)(2,k),(0,e.createComponentVNode)(2,t.NoticeBox,{success:!0,children:["Earned Credits : ",u?(0,o.formatMoney)(u):0]}),(0,e.createComponentVNode)(2,t.NoticeBox,{success:!0,children:["Energy Sold : ",s?(0,o.formatSiUnit)(s,0,"J"):"0 J"]})]})})}return g}(),y=function(l,c){var m=(0,a.useBackend)(c),i=m.data,u=i.max_capacity,s=i.held_power,d=i.input_total,v=i.max_grid_load;return(0,e.createComponentVNode)(2,t.Section,{title:"Status",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Reserve energy",children:s?(0,o.formatSiUnit)(s,0,"J"):"0 J"})}),(0,e.createComponentVNode)(2,t.ProgressBar,{mt:"0.5em",mb:"0.5em",ranges:{good:[.8,1/0],average:[.5,.8],bad:[-1/0,.5]},value:s/u}),(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Grid Saturation"})}),(0,e.createComponentVNode)(2,t.ProgressBar,{mt:"0.5em",ranges:{good:[.8,1/0],average:[.5,.8],bad:[-1/0,.5]},value:Math.min(d,u-s)/v})]})},I=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.input_total,d=u.accepting_power,v=u.sucking_power,h=u.input_number,C=u.power_format;return(0,e.createComponentVNode)(2,t.Section,{title:"Input Controls",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Input Circuit",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"power-off",color:d?"green":"red",onClick:function(){function p(){return i("toggle_input")}return p}(),children:d?"Enabled":"Disabled"}),children:(0,e.createComponentVNode)(2,t.Box,{color:v&&"good"||d&&"average"||"bad",children:v&&"Online"||d&&"Idle"||"Offline"})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Input Level",children:s?(0,o.formatPower)(s):"0 W"})]}),(0,e.createComponentVNode)(2,t.Box,{mt:"0.5em",children:[(0,e.createComponentVNode)(2,t.NumberInput,{mr:"0.5em",animated:!0,size:1.25,inline:!0,step:1,stepPixelSize:2,minValue:0,maxValue:999,value:h,onChange:function(){function p(N,V){return i("set_input",{set_input:V})}return p}()}),(0,e.createComponentVNode)(2,t.Button,{selected:C===1,onClick:function(){function p(){return i("inputW")}return p}(),children:"W"}),(0,e.createComponentVNode)(2,t.Button,{selected:C===Math.pow(10,3),onClick:function(){function p(){return i("inputKW")}return p}(),children:"KW"}),(0,e.createComponentVNode)(2,t.Button,{selected:C===Math.pow(10,6),onClick:function(){function p(){return i("inputMW")}return p}(),children:"MW"}),(0,e.createComponentVNode)(2,t.Button,{selected:C===Math.pow(10,9),onClick:function(){function p(){return i("inputGW")}return p}(),children:"GW"})]})]})},k=function(l,c){var m=(0,a.useBackend)(c),i=m.act,u=m.data,s=u.output_total,d=u.firing,v=u.accepting_power,h=u.output_number,C=u.output_multiplier,p=u.target,N=u.held_power;return(0,e.createComponentVNode)(2,t.Section,{title:"Output Controls",children:[(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Laser Circuit",buttons:(0,e.createComponentVNode)(2,t.Stack,{Horizontal:!0,children:[(0,e.createComponentVNode)(2,t.Button,{icon:"crosshairs",color:p===""?"green":"red",onClick:function(){function V(){return i("target")}return V}(),children:p}),(0,e.createComponentVNode)(2,t.Button,{icon:"power-off",color:d?"green":"red",disabled:!d&&Nu,onClick:function(){function S(){return k("purchaseSoftware",{key:V.key})}return S}()},V.key)}),c.filter(function(V){return!N[V.key]}).length===0&&"No software available!"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Installed Software",children:[m.filter(function(V){return V.key!=="mainmenu"}).map(function(V){return(0,e.createComponentVNode)(2,t.Button,{content:V.name,icon:V.icon,onClick:function(){function S(){return k("startSoftware",{software_key:V.key})}return S}()},V.key)}),m.length===0&&"No software installed!"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Installed Toggles",children:[i.map(function(V){return(0,e.createComponentVNode)(2,t.Button,{content:V.name,icon:V.icon,selected:V.active,onClick:function(){function S(){return k("setToggle",{toggle_key:V.key})}return S}()},V.key)}),i.length===0&&"No toggles installed!"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Select Emotion",children:s.map(function(V){return(0,e.createComponentVNode)(2,t.Button,{content:V.name,selected:V.id===d,onClick:function(){function S(){return k("setEmotion",{emotion:V.id})}return S}()},V.id)})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Select Speaking State",children:v.map(function(V){return(0,e.createComponentVNode)(2,t.Button,{content:V.name,selected:V.name===h,onClick:function(){function S(){return k("setSpeechStyle",{speech_state:V.name})}return S}()},V.id)})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Select Chassis Type",children:C.map(function(V){return(0,e.createComponentVNode)(2,t.Button,{content:V.name,selected:V.icon===p,onClick:function(){function S(){return k("setChassis",{chassis_to_change:V.icon})}return S}()},V.id)})})]})})}return f}()},2983:function(T,r,n){"use strict";r.__esModule=!0,r.pai_manifest=void 0;var e=n(89005),a=n(72253),t=n(41874),o=r.pai_manifest=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.act,g=I.data;return(0,e.createComponentVNode)(2,t.CrewManifest,{data:g.app_data})}return f}()},40758:function(T,r,n){"use strict";r.__esModule=!0,r.pai_medrecords=void 0;var e=n(89005),a=n(72253),t=n(41984),o=r.pai_medrecords=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.data;return(0,e.createComponentVNode)(2,t.SimpleRecords,{data:k.app_data,recordType:"MED"})}return f}()},98599:function(T,r,n){"use strict";r.__esModule=!0,r.pai_messenger=void 0;var e=n(89005),a=n(72253),t=n(77595),o=r.pai_messenger=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.act,g=I.data,l=g.app_data.active_convo;return l?(0,e.createComponentVNode)(2,t.ActiveConversation,{data:g.app_data}):(0,e.createComponentVNode)(2,t.MessengerList,{data:g.app_data})}return f}()},50775:function(T,r,n){"use strict";r.__esModule=!0,r.pai_radio=void 0;var e=n(89005),a=n(72253),t=n(44879),o=n(36036),f=r.pai_radio=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.app_data,m=c.minFrequency,i=c.maxFrequency,u=c.frequency,s=c.broadcasting;return(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Frequency",children:[(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,step:.2,stepPixelSize:6,minValue:m/10,maxValue:i/10,value:u/10,format:function(){function d(v){return(0,t.toFixed)(v,1)}return d}(),onChange:function(){function d(v,h){return g("freq",{freq:h})}return d}()}),(0,e.createComponentVNode)(2,o.Button,{tooltip:"Reset",icon:"undo",onClick:function(){function d(){return g("freq",{freq:"145.9"})}return d}()})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Broadcast Nearby Speech",children:(0,e.createComponentVNode)(2,o.Button,{onClick:function(){function d(){return g("toggleBroadcast")}return d}(),selected:s,content:s?"Enabled":"Disabled"})})]})}return b}()},48623:function(T,r,n){"use strict";r.__esModule=!0,r.pai_secrecords=void 0;var e=n(89005),a=n(72253),t=n(41984),o=r.pai_secrecords=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.data;return(0,e.createComponentVNode)(2,t.SimpleRecords,{data:k.app_data,recordType:"SEC"})}return f}()},47297:function(T,r,n){"use strict";r.__esModule=!0,r.pai_signaler=void 0;var e=n(89005),a=n(72253),t=n(13545),o=r.pai_signaler=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.act,g=I.data;return(0,e.createComponentVNode)(2,t.Signaler,{data:g.app_data})}return f}()},78532:function(T,r,n){"use strict";r.__esModule=!0,r.pda_atmos_scan=void 0;var e=n(89005),a=n(72253),t=n(26991),o=r.pda_atmos_scan=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.data;return(0,e.createComponentVNode)(2,t.AtmosScan,{data:k})}return f}()},2395:function(T,r,n){"use strict";r.__esModule=!0,r.pda_games=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(1331),f=r.pda_games=function(){function b(y,I){var k=(0,a.useBackend)(I),g=k.act,l=k.data,c=l.games,m=function(){function i(u){switch(u){case"Minesweeper":return(0,e.createComponentVNode)(2,o.IconStack,{children:[(0,e.createComponentVNode)(2,o.Icon,{ml:"0",mt:"10px",name:"flag",size:"6",color:"gray",rotation:30}),(0,e.createComponentVNode)(2,o.Icon,{ml:"9px",mt:"23px",name:"bomb",size:"3",color:"black"})]});default:return(0,e.createComponentVNode)(2,o.Icon,{ml:"16px",mt:"10px",name:"gamepad",size:"6"})}}return i}();return(0,e.createComponentVNode)(2,t.Box,{children:c.map(function(i){return(0,e.createComponentVNode)(2,t.Button,{width:"33%",textAlign:"center",translucent:!0,onClick:function(){function u(){return g("play",{id:i.id})}return u}(),children:[m(i.name),(0,e.createComponentVNode)(2,t.Box,{children:i.name})]},i.name)})})}return b}()},40253:function(T,r,n){"use strict";r.__esModule=!0,r.pda_janitor=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.pda_janitor=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.act,g=I.data,l=g.janitor,c=l.user_loc,m=l.mops,i=l.buckets,u=l.cleanbots,s=l.carts,d=l.janicarts;return(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Location",children:[c.x,",",c.y]}),m&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Mop Locations",children:m.map(function(v){return(0,e.createComponentVNode)(2,t.Box,{children:[v.x,",",v.y," (",v.dir,") - ",v.status]},v)})}),i&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Mop Bucket Locations",children:i.map(function(v){return(0,e.createComponentVNode)(2,t.Box,{children:[v.x,",",v.y," (",v.dir,") - [",v.volume,"/",v.max_volume,"]"]},v)})}),u&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cleanbot Locations",children:u.map(function(v){return(0,e.createComponentVNode)(2,t.Box,{children:[v.x,",",v.y," (",v.dir,") - ",v.status]},v)})}),s&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Janitorial Cart Locations",children:s.map(function(v){return(0,e.createComponentVNode)(2,t.Box,{children:[v.x,",",v.y," (",v.dir,") - [",v.volume,"/",v.max_volume,"]"]},v)})}),d&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Janicart Locations",children:d.map(function(v){return(0,e.createComponentVNode)(2,t.Box,{children:[v.x,",",v.y," (",v.direction_from_user,")"]},v)})})]})}return f}()},58293:function(T,r,n){"use strict";r.__esModule=!0,r.pda_main_menu=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),f=r.pda_main_menu=function(){function b(y,I){var k=(0,t.useBackend)(I),g=k.act,l=k.data,c=l.owner,m=l.ownjob,i=l.idInserted,u=l.categories,s=l.pai,d=l.notifying;return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Owner",color:"average",children:[c,", ",m]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"ID",children:(0,e.createComponentVNode)(2,o.Button,{icon:"sync",content:"Update PDA Info",disabled:!i,onClick:function(){function v(){return g("UpdateInfo")}return v}()})})]})})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{title:"Functions",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:u.map(function(v){var h=l.apps[v];return!h||!h.length?null:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:v,children:h.map(function(C){return(0,e.createComponentVNode)(2,o.Button,{icon:C.uid in d?C.notify_icon:C.icon,iconSpin:C.uid in d,color:C.uid in d?"red":"transparent",content:C.name,onClick:function(){function p(){return g("StartProgram",{program:C.uid})}return p}()},C.uid)})},v)})})})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:!!s&&(0,e.createComponentVNode)(2,o.Section,{title:"pAI",children:[(0,e.createComponentVNode)(2,o.Button,{fluid:!0,icon:"cog",content:"Configuration",onClick:function(){function v(){return g("pai",{option:1})}return v}()}),(0,e.createComponentVNode)(2,o.Button,{fluid:!0,icon:"eject",content:"Eject pAI",onClick:function(){function v(){return g("pai",{option:2})}return v}()})]})})]})}return b}()},58059:function(T,r,n){"use strict";r.__esModule=!0,r.pda_manifest=void 0;var e=n(89005),a=n(72253),t=n(41874),o=r.pda_manifest=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.act,g=I.data;return(0,e.createComponentVNode)(2,t.CrewManifest)}return f}()},18147:function(T,r,n){"use strict";r.__esModule=!0,r.pda_medical=void 0;var e=n(89005),a=n(72253),t=n(41984),o=r.pda_medical=function(){function f(b,y){var I=(0,a.useBackend)(y),k=I.data;return(0,e.createComponentVNode)(2,t.SimpleRecords,{data:k,recordType:"MED"})}return f}()},77595:function(T,r,n){"use strict";r.__esModule=!0,r.pda_messenger=r.MessengerList=r.ActiveConversation=void 0;var e=n(89005),a=n(88510),t=n(72253),o=n(36036),f=r.pda_messenger=function(){function k(g,l){var c=(0,t.useBackend)(l),m=c.act,i=c.data,u=i.active_convo;return u?(0,e.createComponentVNode)(2,b,{data:i}):(0,e.createComponentVNode)(2,y,{data:i})}return k}(),b=r.ActiveConversation=function(){function k(g,l){var c=(0,t.useBackend)(l),m=c.act,i=g.data,u=i.convo_name,s=i.convo_job,d=i.messages,v=i.active_convo,h=(0,t.useLocalState)(l,"clipboardMode",!1),C=h[0],p=h[1],N=(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Conversation with "+u+" ("+s+")",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{icon:"eye",selected:C,tooltip:"Enter Clipboard Mode",tooltipPosition:"bottom-start",onClick:function(){function V(){return p(!C)}return V}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"comment",onClick:function(){function V(){return m("Message",{target:v})}return V}(),content:"Reply"})],4),children:(0,a.filter)(function(V){return V.target===v})(d).map(function(V,S){return(0,e.createComponentVNode)(2,o.Box,{textAlign:V.sent?"right":"left",position:"relative",mb:1,children:[(0,e.createComponentVNode)(2,o.Icon,{fontSize:2.5,color:V.sent?"#4d9121":"#cd7a0d",position:"absolute",left:V.sent?null:"0px",right:V.sent?"0px":null,bottom:"-4px",style:{"z-index":"0",transform:V.sent?"scale(-1, 1)":null},name:"comment"}),(0,e.createComponentVNode)(2,o.Box,{inline:!0,backgroundColor:V.sent?"#4d9121":"#cd7a0d",p:1,maxWidth:"100%",position:"relative",textAlign:V.sent?"left":"right",style:{"z-index":"1","border-radius":"10px","word-break":"normal"},children:[V.sent?"You:":"Them:"," ",V.message]})]},S)})});return C&&(N=(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Conversation with "+u+" ("+s+")",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{icon:"eye",selected:C,tooltip:"Exit Clipboard Mode",tooltipPosition:"bottom-start",onClick:function(){function V(){return p(!C)}return V}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"comment",onClick:function(){function V(){return m("Message",{target:v})}return V}(),content:"Reply"})],4),children:(0,a.filter)(function(V){return V.target===v})(d).map(function(V,S){return(0,e.createComponentVNode)(2,o.Box,{color:V.sent?"#4d9121":"#cd7a0d",style:{"word-break":"normal"},children:[V.sent?"You:":"Them:"," ",(0,e.createComponentVNode)(2,o.Box,{inline:!0,children:V.message})]},S)})})),(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{mb:.5,children:(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Messenger Functions",children:(0,e.createComponentVNode)(2,o.Button.Confirm,{content:"Delete Conversations",confirmContent:"Are you sure?",icon:"trash",confirmIcon:"trash",onClick:function(){function V(){return m("Clear",{option:"Convo"})}return V}()})})})}),N]})}return k}(),y=r.MessengerList=function(){function k(g,l){var c=(0,t.useBackend)(l),m=c.act,i=g.data,u=i.convopdas,s=i.pdas,d=i.charges,v=i.silent,h=i.toff,C=i.ringtone_list,p=i.ringtone,N=(0,t.useLocalState)(l,"searchTerm",""),V=N[0],S=N[1];return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{mb:5,children:[(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Messenger Functions",children:[(0,e.createComponentVNode)(2,o.Button,{selected:!v,icon:v?"volume-mute":"volume-up",onClick:function(){function B(){return m("Toggle Ringer")}return B}(),children:["Ringer: ",v?"Off":"On"]}),(0,e.createComponentVNode)(2,o.Button,{color:h?"bad":"green",icon:"power-off",onClick:function(){function B(){return m("Toggle Messenger")}return B}(),children:["Messenger: ",h?"Off":"On"]}),(0,e.createComponentVNode)(2,o.Button,{icon:"trash",color:"bad",onClick:function(){function B(){return m("Clear",{option:"All"})}return B}(),children:"Delete All Conversations"}),(0,e.createComponentVNode)(2,o.Button,{icon:"bell",onClick:function(){function B(){return m("Ringtone")}return B}(),children:"Set Custom Ringtone"}),(0,e.createComponentVNode)(2,o.Dropdown,{selected:p,width:"100px",options:Object.keys(C),onSelected:function(){function B(L){return m("Available_Ringtones",{selected_ringtone:L})}return B}()})]})}),!h&&(0,e.createComponentVNode)(2,o.Box,{children:[!!d&&(0,e.createComponentVNode)(2,o.Box,{mt:.5,mb:1,children:(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Cartridge Special Function",children:[d," charges left."]})})}),!u.length&&!s.length&&(0,e.createComponentVNode)(2,o.Box,{children:"No current conversations"})||(0,e.createComponentVNode)(2,o.Box,{children:["Search:"," ",(0,e.createComponentVNode)(2,o.Input,{mt:.5,value:V,onInput:function(){function B(L,w){S(w)}return B}()})]})]})||(0,e.createComponentVNode)(2,o.Box,{color:"bad",children:"Messenger Offline."})]}),(0,e.createComponentVNode)(2,I,{title:"Current Conversations",data:i,pdas:u,msgAct:"Select Conversation",searchTerm:V}),(0,e.createComponentVNode)(2,I,{title:"Other PDAs",pdas:s,msgAct:"Message",data:i,searchTerm:V})]})}return k}(),I=function(g,l){var c=(0,t.useBackend)(l),m=c.act,i=g.data,u=g.pdas,s=g.title,d=g.msgAct,v=g.searchTerm,h=i.charges,C=i.plugins;return!u||!u.length?(0,e.createComponentVNode)(2,o.Section,{title:s,children:"No PDAs found."}):(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:s,children:u.filter(function(p){return p.Name.toLowerCase().includes(v.toLowerCase())}).map(function(p){return(0,e.createComponentVNode)(2,o.Stack,{m:.5,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Button,{fluid:!0,icon:"arrow-circle-down",content:p.Name,onClick:function(){function N(){return m(d,{target:p.uid})}return N}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:!!h&&C.map(function(N){return(0,e.createComponentVNode)(2,o.Button,{icon:N.icon,content:N.name,onClick:function(){function V(){return m("Messenger Plugin",{plugin:N.uid,target:p.uid})}return V}()},N.uid)})})]},p.uid)})})}},90382:function(T,r,n){"use strict";r.__esModule=!0,r.pda_minesweeper=r.MineSweeperLeaderboard=r.MineSweeperGame=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.pda_minesweeper=function(){function I(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=(0,a.useLocalState)(g,"window","Game"),u=i[0],s=i[1],d={Game:"Leaderboard",Leaderboard:"Game"};return(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:u==="Game"?(0,e.createComponentVNode)(2,f):(0,e.createComponentVNode)(2,b)}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,fontSize:2,lineHeight:1.75,icon:u==="Game"?"book":"gamepad",onClick:function(){function v(){return s(d[u])}return v}(),children:d[u]})})]})}return I}(),f=r.MineSweeperGame=function(){function I(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.matrix,u=m.flags,s=m.bombs,d={1:"blue",2:"green",3:"red",4:"darkblue",5:"brown",6:"lightblue",7:"black",8:"white"},v=function(){function h(C,p,N){c("Square",{X:C,Y:p,mode:N})}return h}();return(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:Object.keys(i).map(function(h){return(0,e.createComponentVNode)(2,t.Box,{children:Object.keys(i[h]).map(function(C){return(0,e.createComponentVNode)(2,t.Button,{m:.25,height:2,width:2,className:i[h][C].open?"Minesweeper__open":"Minesweeper__closed",bold:!0,color:"transparent",icon:i[h][C].open?i[h][C].bomb?"bomb":"":i[h][C].flag?"flag":"",textColor:i[h][C].open?i[h][C].bomb?"black":d[i[h][C].around]:i[h][C].flag?"red":"gray",onClick:function(){function p(N){return v(h,C,"bomb")}return p}(),onContextMenu:function(){function p(N){event.preventDefault(),v(h,C,"flag")}return p}(),children:i[h][C].open&&!i[h][C].bomb&&i[h][C].around?i[h][C].around:" "},C)})},h)})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,className:"Minesweeper__infobox",children:(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,textAlign:"left",pt:1,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{pl:2,fontSize:2,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"bomb",color:"gray"})," : ",s]}),(0,e.createComponentVNode)(2,t.Stack.Divider),(0,e.createComponentVNode)(2,t.Stack.Item,{pl:2,fontSize:2,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"flag",color:"red"})," : ",u]})]})})]})}return I}(),b=r.MineSweeperLeaderboard=function(){function I(k,g){var l=(0,a.useBackend)(g),c=l.act,m=l.data,i=m.leaderboard,u=(0,a.useLocalState)(g,"sortId","time"),s=u[0],d=u[1],v=(0,a.useLocalState)(g,"sortOrder",!1),h=v[0],C=v[1];return(0,e.createComponentVNode)(2,t.Table,{className:"Minesweeper__list",children:[(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,y,{id:"name",children:"Nick"}),(0,e.createComponentVNode)(2,y,{id:"time",children:"Time"})]}),i&&i.sort(function(p,N){var V=h?1:-1;return p[s].localeCompare(N[s])*V}).map(function(p,N){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:p.name}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:p.time})]},N)})]})}return I}(),y=function(k,g){var l=(0,a.useLocalState)(g,"sortId","time"),c=l[0],m=l[1],i=(0,a.useLocalState)(g,"sortOrder",!1),u=i[0],s=i[1],d=k.id,v=k.children;return(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,color:"transparent",onClick:function(){function h(){c===d?s(!u):(m(d),s(!0))}return h}(),children:[v,c===d&&(0,e.createComponentVNode)(2,t.Icon,{name:u?"sort-up":"sort-down",ml:"0.25rem;"})]})})}},24635:function(T,r,n){"use strict";r.__esModule=!0,r.pda_mule=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.pda_mule=function(){function y(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=c.mulebot,i=m.active;return(0,e.createComponentVNode)(2,t.Box,{children:i?(0,e.createComponentVNode)(2,b):(0,e.createComponentVNode)(2,f)})}return y}(),f=function(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=c.mulebot,i=m.bots;return i.map(function(u){return(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{content:u.Name,icon:"cog",onClick:function(){function s(){return l("control",{bot:u.uid})}return s}()})},u.Name)})},b=function(I,k){var g=(0,a.useBackend)(k),l=g.act,c=g.data,m=c.mulebot,i=m.botstatus,u=m.active,s=i.mode,d=i.loca,v=i.load,h=i.powr,C=i.dest,p=i.home,N=i.retn,V=i.pick,S;switch(s){case 0:S="Ready";break;case 1:S="Loading/Unloading";break;case 2:case 12:S="Navigating to delivery location";break;case 3:S="Navigating to Home";break;case 4:S="Waiting for clear path";break;case 5:case 6:S="Calculating navigation path";break;case 7:S="Unable to locate destination";break;default:S=s;break}return(0,e.createComponentVNode)(2,t.Section,{title:u,children:[s===-1&&(0,e.createComponentVNode)(2,t.Box,{color:"red",bold:!0,children:"Waiting for response..."}),(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Location",children:d}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:S}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:[h,"%"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Home",children:p}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Destination",children:(0,e.createComponentVNode)(2,t.Button,{content:C?C+" (Set)":"None (Set)",onClick:function(){function B(){return l("target")}return B}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Load",children:(0,e.createComponentVNode)(2,t.Button,{content:v?v+" (Unload)":"None",disabled:!v,onClick:function(){function B(){return l("unload")}return B}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Auto Pickup",children:(0,e.createComponentVNode)(2,t.Button,{content:V?"Yes":"No",selected:V,onClick:function(){function B(){return l("set_pickup_type",{autopick:V?0:1})}return B}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Auto Return",children:(0,e.createComponentVNode)(2,t.Button,{content:N?"Yes":"No",selected:N,onClick:function(){function B(){return l("set_auto_return",{autoret:N?0:1})}return B}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Controls",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Stop",icon:"stop",onClick:function(){function B(){return l("stop")}return B}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Proceed",icon:"play",onClick:function(){function B(){return l("start")}return B}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Return Home",icon:"home",onClick:function(){function B(){return l("home")}return B}()})]})]})]})}},23734:function(T,r,n){"use strict";r.__esModule=!0,r.pda_nanobank=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),f=r.pda_nanobank=function(){function i(u,s){var d=(0,t.useBackend)(s),v=d.act,h=d.data,C=h.logged_in,p=h.owner_name,N=h.money;return C?(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Box,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account Name",children:p}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account Balance",children:["$",N]})]})}),(0,e.createComponentVNode)(2,o.Box,{children:[(0,e.createComponentVNode)(2,b),(0,e.createComponentVNode)(2,y)]})],4):(0,e.createComponentVNode)(2,l)}return i}(),b=function(u,s){var d=(0,t.useBackend)(s),v=d.data,h=v.is_premium,C=(0,t.useLocalState)(s,"tabIndex",1),p=C[0],N=C[1];return(0,e.createComponentVNode)(2,o.Tabs,{mt:2,children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:p===1,onClick:function(){function V(){return N(1)}return V}(),children:[(0,e.createComponentVNode)(2,o.Icon,{mr:1,name:"list"}),"Transfers"]}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:p===2,onClick:function(){function V(){return N(2)}return V}(),children:[(0,e.createComponentVNode)(2,o.Icon,{mr:1,name:"list"}),"Account Actions"]}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:p===3,onClick:function(){function V(){return N(3)}return V}(),children:[(0,e.createComponentVNode)(2,o.Icon,{mr:1,name:"list"}),"Transaction History"]}),!!h&&(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:p===4,onClick:function(){function V(){return N(4)}return V}(),children:[(0,e.createComponentVNode)(2,o.Icon,{mr:1,name:"list"}),"Supply Orders"]})]})},y=function(u,s){var d=(0,t.useLocalState)(s,"tabIndex",1),v=d[0],h=(0,t.useBackend)(s),C=h.data,p=C.db_status;if(!p)return(0,e.createComponentVNode)(2,o.Box,{children:"Account Database Connection Severed"});switch(v){case 1:return(0,e.createComponentVNode)(2,I);case 2:return(0,e.createComponentVNode)(2,k);case 3:return(0,e.createComponentVNode)(2,g);case 4:return(0,e.createComponentVNode)(2,m);default:return"You are somehow on a tab that doesn't exist! Please let a coder know."}},I=function(u,s){var d,v=(0,t.useBackend)(s),h=v.act,C=v.data,p=C.requests,N=C.available_accounts,V=C.money,S=(0,t.useLocalState)(s,"selectedAccount"),B=S[0],L=S[1],w=(0,t.useLocalState)(s,"transferAmount"),A=w[0],x=w[1],E=(0,t.useLocalState)(s,"searchText",""),P=E[0],D=E[1],M=[];return N.map(function(R){return M[R.name]=R.UID}),(0,e.createFragment)([(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account",children:[(0,e.createComponentVNode)(2,o.Input,{placeholder:"Search by account name",onInput:function(){function R(O,F){return D(F)}return R}()}),(0,e.createComponentVNode)(2,o.Dropdown,{mt:.6,width:"190px",options:N.filter((0,a.createSearch)(P,function(R){return R.name})).map(function(R){return R.name}),selected:(d=N.filter(function(R){return R.UID===B})[0])==null?void 0:d.name,onSelected:function(){function R(O){return L(M[O])}return R}()})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Amount",children:(0,e.createComponentVNode)(2,o.Input,{placeholder:"Up to 5000",onInput:function(){function R(O,F){return x(F)}return R}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Actions",children:[(0,e.createComponentVNode)(2,o.Button.Confirm,{bold:!0,icon:"paper-plane",width:"auto",disabled:V0&&d.map(function(h){return(0,e.createComponentVNode)(2,t.Box,{children:["#",h.Number,' - "',h.Name,'" for "',h.OrderedBy,'"']},h)})}),(0,e.createComponentVNode)(2,t.Section,{title:"Approved Orders",children:s>0&&u.map(function(h){return(0,e.createComponentVNode)(2,t.Box,{children:["#",h.Number,' - "',h.Name,'" for "',h.ApprovedBy,'"']},h)})})]})}return f}()},17617:function(T,r,n){"use strict";r.__esModule=!0,r.Layout=void 0;var e=n(89005),a=n(35840),t=n(55937),o=n(24826),f=["className","theme","children"],b=["className","scrollable","children"];/** * @file * @copyright 2020 Aleksej Komarov @@ -264,13 +473,29 @@ * @copyright 2020 Aleksej Komarov * @license MIT */var d=(0,l.createLogger)("Window"),v=[400,600],h=r.Window=function(V){function S(){return V.apply(this,arguments)||this}u(S,V);var B=S.prototype;return B.componentDidMount=function(){function L(){var w=(0,f.useBackend)(this.context),A=w.suspended;A||(d.log("mounting"),this.updateGeometry())}return L}(),B.componentDidUpdate=function(){function L(w){var A=this.props.width!==w.width||this.props.height!==w.height;A&&this.updateGeometry()}return L}(),B.updateGeometry=function(){function L(){var w,A=(0,f.useBackend)(this.context),x=A.config,E=Object.assign({size:v},x.window);this.props.width&&this.props.height&&(E.size=[this.props.width,this.props.height]),(w=x.window)!=null&&w.key&&(0,g.setWindowKey)(x.window.key),(0,g.recallWindowGeometry)(E)}return L}(),B.render=function(){function L(){var w,A=this.props,x=A.theme,E=A.title,P=A.children,D=(0,f.useBackend)(this.context),M=D.config,R=D.suspended,O=(0,I.useDebug)(this.context),F=O.debugLayout,_=(0,t.useDispatch)(this.context),U=(w=M.window)==null?void 0:w.fancy,z=M.user&&(M.user.observer?M.statusu,onClick:function(){function B(){return k("purchaseSoftware",{key:V.key})}return B}()},V.key)}),c.filter(function(V){return!N[V.key]}).length===0&&"No software available!"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Installed Software",children:[m.filter(function(V){return V.key!=="mainmenu"}).map(function(V){return(0,e.createComponentVNode)(2,t.Button,{content:V.name,icon:V.icon,onClick:function(){function B(){return k("startSoftware",{software_key:V.key})}return B}()},V.key)}),m.length===0&&"No software installed!"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Installed Toggles",children:[l.map(function(V){return(0,e.createComponentVNode)(2,t.Button,{content:V.name,icon:V.icon,selected:V.active,onClick:function(){function B(){return k("setToggle",{toggle_key:V.key})}return B}()},V.key)}),l.length===0&&"No toggles installed!"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Select Emotion",children:s.map(function(V){return(0,e.createComponentVNode)(2,t.Button,{content:V.name,selected:V.id===d,onClick:function(){function B(){return k("setEmotion",{emotion:V.id})}return B}()},V.id)})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Select Speaking State",children:v.map(function(V){return(0,e.createComponentVNode)(2,t.Button,{content:V.name,selected:V.name===g,onClick:function(){function B(){return k("setSpeechStyle",{speech_state:V.name})}return B}()},V.id)})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Select Chassis Type",children:C.map(function(V){return(0,e.createComponentVNode)(2,t.Button,{content:V.name,selected:V.icon===f,onClick:function(){function B(){return k("setChassis",{chassis_to_change:V.icon})}return B}()},V.id)})})]})})}return p}()},2983:function(T,r,n){"use strict";r.__esModule=!0,r.pai_manifest=void 0;var e=n(89005),a=n(72253),t=n(41874),o=r.pai_manifest=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.act,h=S.data;return(0,e.createComponentVNode)(2,t.CrewManifest,{data:h.app_data})}return p}()},40758:function(T,r,n){"use strict";r.__esModule=!0,r.pai_medrecords=void 0;var e=n(89005),a=n(72253),t=n(41984),o=r.pai_medrecords=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.data;return(0,e.createComponentVNode)(2,t.SimpleRecords,{data:k.app_data,recordType:"MED"})}return p}()},98599:function(T,r,n){"use strict";r.__esModule=!0,r.pai_messenger=void 0;var e=n(89005),a=n(72253),t=n(77595),o=r.pai_messenger=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.act,h=S.data,i=h.app_data.active_convo;return i?(0,e.createComponentVNode)(2,t.ActiveConversation,{data:h.app_data}):(0,e.createComponentVNode)(2,t.MessengerList,{data:h.app_data})}return p}()},50775:function(T,r,n){"use strict";r.__esModule=!0,r.pai_radio=void 0;var e=n(89005),a=n(72253),t=n(44879),o=n(36036),p=r.pai_radio=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.app_data,m=c.minFrequency,l=c.maxFrequency,u=c.frequency,s=c.broadcasting;return(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Frequency",children:[(0,e.createComponentVNode)(2,o.NumberInput,{animate:!0,step:.2,stepPixelSize:6,minValue:m/10,maxValue:l/10,value:u/10,format:function(){function d(v){return(0,t.toFixed)(v,1)}return d}(),onChange:function(){function d(v,g){return h("freq",{freq:g})}return d}()}),(0,e.createComponentVNode)(2,o.Button,{tooltip:"Reset",icon:"undo",onClick:function(){function d(){return h("freq",{freq:"145.9"})}return d}()})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Broadcast Nearby Speech",children:(0,e.createComponentVNode)(2,o.Button,{onClick:function(){function d(){return h("toggleBroadcast")}return d}(),selected:s,content:s?"Enabled":"Disabled"})})]})}return b}()},48623:function(T,r,n){"use strict";r.__esModule=!0,r.pai_secrecords=void 0;var e=n(89005),a=n(72253),t=n(41984),o=r.pai_secrecords=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.data;return(0,e.createComponentVNode)(2,t.SimpleRecords,{data:k.app_data,recordType:"SEC"})}return p}()},47297:function(T,r,n){"use strict";r.__esModule=!0,r.pai_signaler=void 0;var e=n(89005),a=n(72253),t=n(13545),o=r.pai_signaler=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.act,h=S.data;return(0,e.createComponentVNode)(2,t.Signaler,{data:h.app_data})}return p}()},78532:function(T,r,n){"use strict";r.__esModule=!0,r.pda_atmos_scan=void 0;var e=n(89005),a=n(72253),t=n(26991),o=r.pda_atmos_scan=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.data;return(0,e.createComponentVNode)(2,t.AtmosScan,{data:k})}return p}()},2395:function(T,r,n){"use strict";r.__esModule=!0,r.pda_games=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(1331),p=r.pda_games=function(){function b(y,S){var k=(0,a.useBackend)(S),h=k.act,i=k.data,c=i.games,m=function(){function l(u){switch(u){case"Minesweeper":return(0,e.createComponentVNode)(2,o.IconStack,{children:[(0,e.createComponentVNode)(2,o.Icon,{ml:"0",mt:"10px",name:"flag",size:"6",color:"gray",rotation:30}),(0,e.createComponentVNode)(2,o.Icon,{ml:"9px",mt:"23px",name:"bomb",size:"3",color:"black"})]});default:return(0,e.createComponentVNode)(2,o.Icon,{ml:"16px",mt:"10px",name:"gamepad",size:"6"})}}return l}();return(0,e.createComponentVNode)(2,t.Box,{children:c.map(function(l){return(0,e.createComponentVNode)(2,t.Button,{width:"33%",textAlign:"center",translucent:!0,onClick:function(){function u(){return h("play",{id:l.id})}return u}(),children:[m(l.name),(0,e.createComponentVNode)(2,t.Box,{children:l.name})]},l.name)})})}return b}()},40253:function(T,r,n){"use strict";r.__esModule=!0,r.pda_janitor=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.pda_janitor=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.act,h=S.data,i=h.janitor,c=i.user_loc,m=i.mops,l=i.buckets,u=i.cleanbots,s=i.carts,d=i.janicarts;return(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Location",children:[c.x,",",c.y]}),m&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Mop Locations",children:m.map(function(v){return(0,e.createComponentVNode)(2,t.Box,{children:[v.x,",",v.y," (",v.dir,") - ",v.status]},v)})}),l&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Mop Bucket Locations",children:l.map(function(v){return(0,e.createComponentVNode)(2,t.Box,{children:[v.x,",",v.y," (",v.dir,") - [",v.volume,"/",v.max_volume,"]"]},v)})}),u&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Cleanbot Locations",children:u.map(function(v){return(0,e.createComponentVNode)(2,t.Box,{children:[v.x,",",v.y," (",v.dir,") - ",v.status]},v)})}),s&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Janitorial Cart Locations",children:s.map(function(v){return(0,e.createComponentVNode)(2,t.Box,{children:[v.x,",",v.y," (",v.dir,") - [",v.volume,"/",v.max_volume,"]"]},v)})}),d&&(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Janicart Locations",children:d.map(function(v){return(0,e.createComponentVNode)(2,t.Box,{children:[v.x,",",v.y," (",v.direction_from_user,")"]},v)})})]})}return p}()},58293:function(T,r,n){"use strict";r.__esModule=!0,r.pda_main_menu=void 0;var e=n(89005),a=n(44879),t=n(72253),o=n(36036),p=r.pda_main_menu=function(){function b(y,S){var k=(0,t.useBackend)(S),h=k.act,i=k.data,c=i.owner,m=i.ownjob,l=i.idInserted,u=i.categories,s=i.pai,d=i.notifying;return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Owner",color:"average",children:[c,", ",m]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"ID",children:(0,e.createComponentVNode)(2,o.Button,{icon:"sync",content:"Update PDA Info",disabled:!l,onClick:function(){function v(){return h("UpdateInfo")}return v}()})})]})})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:(0,e.createComponentVNode)(2,o.Section,{title:"Functions",children:(0,e.createComponentVNode)(2,o.LabeledList,{children:u.map(function(v){var g=i.apps[v];return!g||!g.length?null:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:v,children:g.map(function(C){return(0,e.createComponentVNode)(2,o.Button,{icon:C.uid in d?C.notify_icon:C.icon,iconSpin:C.uid in d,color:C.uid in d?"red":"transparent",content:C.name,onClick:function(){function f(){return h("StartProgram",{program:C.uid})}return f}()},C.uid)})},v)})})})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:!!s&&(0,e.createComponentVNode)(2,o.Section,{title:"pAI",children:[(0,e.createComponentVNode)(2,o.Button,{fluid:!0,icon:"cog",content:"Configuration",onClick:function(){function v(){return h("pai",{option:1})}return v}()}),(0,e.createComponentVNode)(2,o.Button,{fluid:!0,icon:"eject",content:"Eject pAI",onClick:function(){function v(){return h("pai",{option:2})}return v}()})]})})]})}return b}()},58059:function(T,r,n){"use strict";r.__esModule=!0,r.pda_manifest=void 0;var e=n(89005),a=n(72253),t=n(41874),o=r.pda_manifest=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.act,h=S.data;return(0,e.createComponentVNode)(2,t.CrewManifest)}return p}()},18147:function(T,r,n){"use strict";r.__esModule=!0,r.pda_medical=void 0;var e=n(89005),a=n(72253),t=n(41984),o=r.pda_medical=function(){function p(b,y){var S=(0,a.useBackend)(y),k=S.data;return(0,e.createComponentVNode)(2,t.SimpleRecords,{data:k,recordType:"MED"})}return p}()},77595:function(T,r,n){"use strict";r.__esModule=!0,r.pda_messenger=r.MessengerList=r.ActiveConversation=void 0;var e=n(89005),a=n(88510),t=n(72253),o=n(36036),p=r.pda_messenger=function(){function k(h,i){var c=(0,t.useBackend)(i),m=c.act,l=c.data,u=l.active_convo;return u?(0,e.createComponentVNode)(2,b,{data:l}):(0,e.createComponentVNode)(2,y,{data:l})}return k}(),b=r.ActiveConversation=function(){function k(h,i){var c=(0,t.useBackend)(i),m=c.act,l=h.data,u=l.convo_name,s=l.convo_job,d=l.messages,v=l.active_convo,g=(0,t.useLocalState)(i,"clipboardMode",!1),C=g[0],f=g[1],N=(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Conversation with "+u+" ("+s+")",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{icon:"eye",selected:C,tooltip:"Enter Clipboard Mode",tooltipPosition:"bottom-start",onClick:function(){function V(){return f(!C)}return V}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"comment",onClick:function(){function V(){return m("Message",{target:v})}return V}(),content:"Reply"})],4),children:(0,a.filter)(function(V){return V.target===v})(d).map(function(V,B){return(0,e.createComponentVNode)(2,o.Box,{textAlign:V.sent?"right":"left",position:"relative",mb:1,children:[(0,e.createComponentVNode)(2,o.Icon,{fontSize:2.5,color:V.sent?"#4d9121":"#cd7a0d",position:"absolute",left:V.sent?null:"0px",right:V.sent?"0px":null,bottom:"-4px",style:{"z-index":"0",transform:V.sent?"scale(-1, 1)":null},name:"comment"}),(0,e.createComponentVNode)(2,o.Box,{inline:!0,backgroundColor:V.sent?"#4d9121":"#cd7a0d",p:1,maxWidth:"100%",position:"relative",textAlign:V.sent?"left":"right",style:{"z-index":"1","border-radius":"10px","word-break":"normal"},children:[V.sent?"You:":"Them:"," ",V.message]})]},B)})});return C&&(N=(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:"Conversation with "+u+" ("+s+")",buttons:(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Button,{icon:"eye",selected:C,tooltip:"Exit Clipboard Mode",tooltipPosition:"bottom-start",onClick:function(){function V(){return f(!C)}return V}()}),(0,e.createComponentVNode)(2,o.Button,{icon:"comment",onClick:function(){function V(){return m("Message",{target:v})}return V}(),content:"Reply"})],4),children:(0,a.filter)(function(V){return V.target===v})(d).map(function(V,B){return(0,e.createComponentVNode)(2,o.Box,{color:V.sent?"#4d9121":"#cd7a0d",style:{"word-break":"normal"},children:[V.sent?"You:":"Them:"," ",(0,e.createComponentVNode)(2,o.Box,{inline:!0,children:V.message})]},B)})})),(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{mb:.5,children:(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Messenger Functions",children:(0,e.createComponentVNode)(2,o.Button.Confirm,{content:"Delete Conversations",confirmContent:"Are you sure?",icon:"trash",confirmIcon:"trash",onClick:function(){function V(){return m("Clear",{option:"Convo"})}return V}()})})})}),N]})}return k}(),y=r.MessengerList=function(){function k(h,i){var c=(0,t.useBackend)(i),m=c.act,l=h.data,u=l.convopdas,s=l.pdas,d=l.charges,v=l.silent,g=l.toff,C=l.ringtone_list,f=l.ringtone,N=(0,t.useLocalState)(i,"searchTerm",""),V=N[0],B=N[1];return(0,e.createComponentVNode)(2,o.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{mb:5,children:[(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Messenger Functions",children:[(0,e.createComponentVNode)(2,o.Button,{selected:!v,icon:v?"volume-mute":"volume-up",onClick:function(){function I(){return m("Toggle Ringer")}return I}(),children:["Ringer: ",v?"Off":"On"]}),(0,e.createComponentVNode)(2,o.Button,{color:g?"bad":"green",icon:"power-off",onClick:function(){function I(){return m("Toggle Messenger")}return I}(),children:["Messenger: ",g?"Off":"On"]}),(0,e.createComponentVNode)(2,o.Button,{icon:"trash",color:"bad",onClick:function(){function I(){return m("Clear",{option:"All"})}return I}(),children:"Delete All Conversations"}),(0,e.createComponentVNode)(2,o.Button,{icon:"bell",onClick:function(){function I(){return m("Ringtone")}return I}(),children:"Set Custom Ringtone"}),(0,e.createComponentVNode)(2,o.Dropdown,{selected:f,width:"100px",options:Object.keys(C),onSelected:function(){function I(L){return m("Available_Ringtones",{selected_ringtone:L})}return I}()})]})}),!g&&(0,e.createComponentVNode)(2,o.Box,{children:[!!d&&(0,e.createComponentVNode)(2,o.Box,{mt:.5,mb:1,children:(0,e.createComponentVNode)(2,o.LabeledList,{children:(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Cartridge Special Function",children:[d," charges left."]})})}),!u.length&&!s.length&&(0,e.createComponentVNode)(2,o.Box,{children:"No current conversations"})||(0,e.createComponentVNode)(2,o.Box,{children:["Search:"," ",(0,e.createComponentVNode)(2,o.Input,{mt:.5,value:V,onInput:function(){function I(L,w){B(w)}return I}()})]})]})||(0,e.createComponentVNode)(2,o.Box,{color:"bad",children:"Messenger Offline."})]}),(0,e.createComponentVNode)(2,S,{title:"Current Conversations",data:l,pdas:u,msgAct:"Select Conversation",searchTerm:V}),(0,e.createComponentVNode)(2,S,{title:"Other PDAs",pdas:s,msgAct:"Message",data:l,searchTerm:V})]})}return k}(),S=function(h,i){var c=(0,t.useBackend)(i),m=c.act,l=h.data,u=h.pdas,s=h.title,d=h.msgAct,v=h.searchTerm,g=l.charges,C=l.plugins;return!u||!u.length?(0,e.createComponentVNode)(2,o.Section,{title:s,children:"No PDAs found."}):(0,e.createComponentVNode)(2,o.Section,{fill:!0,scrollable:!0,title:s,children:u.filter(function(f){return f.Name.toLowerCase().includes(v.toLowerCase())}).map(function(f){return(0,e.createComponentVNode)(2,o.Stack,{m:.5,children:[(0,e.createComponentVNode)(2,o.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,o.Button,{fluid:!0,icon:"arrow-circle-down",content:f.Name,onClick:function(){function N(){return m(d,{target:f.uid})}return N}()})}),(0,e.createComponentVNode)(2,o.Stack.Item,{children:!!g&&C.map(function(N){return(0,e.createComponentVNode)(2,o.Button,{icon:N.icon,content:N.name,onClick:function(){function V(){return m("Messenger Plugin",{plugin:N.uid,target:f.uid})}return V}()},N.uid)})})]},f.uid)})})}},90382:function(T,r,n){"use strict";r.__esModule=!0,r.pda_minesweeper=r.MineSweeperLeaderboard=r.MineSweeperGame=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.pda_minesweeper=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=(0,a.useLocalState)(h,"window","Game"),u=l[0],s=l[1],d={Game:"Leaderboard",Leaderboard:"Game"};return(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,textAlign:"center",children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:u==="Game"?(0,e.createComponentVNode)(2,p):(0,e.createComponentVNode)(2,b)}),(0,e.createComponentVNode)(2,t.Stack.Item,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:!0,fontSize:2,lineHeight:1.75,icon:u==="Game"?"book":"gamepad",onClick:function(){function v(){return s(d[u])}return v}(),children:d[u]})})]})}return S}(),p=r.MineSweeperGame=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.matrix,u=m.flags,s=m.bombs,d={1:"blue",2:"green",3:"red",4:"darkblue",5:"brown",6:"lightblue",7:"black",8:"white"},v=function(){function g(C,f,N){c("Square",{X:C,Y:f,mode:N})}return g}();return(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{children:Object.keys(l).map(function(g){return(0,e.createComponentVNode)(2,t.Box,{children:Object.keys(l[g]).map(function(C){return(0,e.createComponentVNode)(2,t.Button,{m:.25,height:2,width:2,className:l[g][C].open?"Minesweeper__open":"Minesweeper__closed",bold:!0,color:"transparent",icon:l[g][C].open?l[g][C].bomb?"bomb":"":l[g][C].flag?"flag":"",textColor:l[g][C].open?l[g][C].bomb?"black":d[l[g][C].around]:l[g][C].flag?"red":"gray",onClick:function(){function f(N){return v(g,C,"bomb")}return f}(),onContextMenu:function(){function f(N){event.preventDefault(),v(g,C,"flag")}return f}(),children:l[g][C].open&&!l[g][C].bomb&&l[g][C].around?l[g][C].around:" "},C)})},g)})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,className:"Minesweeper__infobox",children:(0,e.createComponentVNode)(2,t.Stack,{vertical:!0,textAlign:"left",pt:1,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{pl:2,fontSize:2,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"bomb",color:"gray"})," : ",s]}),(0,e.createComponentVNode)(2,t.Stack.Divider),(0,e.createComponentVNode)(2,t.Stack.Item,{pl:2,fontSize:2,children:[(0,e.createComponentVNode)(2,t.Icon,{name:"flag",color:"red"})," : ",u]})]})})]})}return S}(),b=r.MineSweeperLeaderboard=function(){function S(k,h){var i=(0,a.useBackend)(h),c=i.act,m=i.data,l=m.leaderboard,u=(0,a.useLocalState)(h,"sortId","time"),s=u[0],d=u[1],v=(0,a.useLocalState)(h,"sortOrder",!1),g=v[0],C=v[1];return(0,e.createComponentVNode)(2,t.Table,{className:"Minesweeper__list",children:[(0,e.createComponentVNode)(2,t.Table.Row,{bold:!0,children:[(0,e.createComponentVNode)(2,y,{id:"name",children:"Nick"}),(0,e.createComponentVNode)(2,y,{id:"time",children:"Time"})]}),l&&l.sort(function(f,N){var V=g?1:-1;return f[s].localeCompare(N[s])*V}).map(function(f,N){return(0,e.createComponentVNode)(2,t.Table.Row,{children:[(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.name}),(0,e.createComponentVNode)(2,t.Table.Cell,{children:f.time})]},N)})]})}return S}(),y=function(k,h){var i=(0,a.useLocalState)(h,"sortId","time"),c=i[0],m=i[1],l=(0,a.useLocalState)(h,"sortOrder",!1),u=l[0],s=l[1],d=k.id,v=k.children;return(0,e.createComponentVNode)(2,t.Table.Cell,{children:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,color:"transparent",onClick:function(){function g(){c===d?s(!u):(m(d),s(!0))}return g}(),children:[v,c===d&&(0,e.createComponentVNode)(2,t.Icon,{name:u?"sort-up":"sort-down",ml:"0.25rem;"})]})})}},24635:function(T,r,n){"use strict";r.__esModule=!0,r.pda_mule=void 0;var e=n(89005),a=n(72253),t=n(36036),o=r.pda_mule=function(){function y(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.mulebot,l=m.active;return(0,e.createComponentVNode)(2,t.Box,{children:l?(0,e.createComponentVNode)(2,b):(0,e.createComponentVNode)(2,p)})}return y}(),p=function(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.mulebot,l=m.bots;return l.map(function(u){return(0,e.createComponentVNode)(2,t.Box,{children:(0,e.createComponentVNode)(2,t.Button,{content:u.Name,icon:"cog",onClick:function(){function s(){return i("control",{bot:u.uid})}return s}()})},u.Name)})},b=function(S,k){var h=(0,a.useBackend)(k),i=h.act,c=h.data,m=c.mulebot,l=m.botstatus,u=m.active,s=l.mode,d=l.loca,v=l.load,g=l.powr,C=l.dest,f=l.home,N=l.retn,V=l.pick,B;switch(s){case 0:B="Ready";break;case 1:B="Loading/Unloading";break;case 2:case 12:B="Navigating to delivery location";break;case 3:B="Navigating to Home";break;case 4:B="Waiting for clear path";break;case 5:case 6:B="Calculating navigation path";break;case 7:B="Unable to locate destination";break;default:B=s;break}return(0,e.createComponentVNode)(2,t.Section,{title:u,children:[s===-1&&(0,e.createComponentVNode)(2,t.Box,{color:"red",bold:!0,children:"Waiting for response..."}),(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Location",children:d}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Status",children:B}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Power",children:[g,"%"]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Home",children:f}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Destination",children:(0,e.createComponentVNode)(2,t.Button,{content:C?C+" (Set)":"None (Set)",onClick:function(){function I(){return i("target")}return I}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Current Load",children:(0,e.createComponentVNode)(2,t.Button,{content:v?v+" (Unload)":"None",disabled:!v,onClick:function(){function I(){return i("unload")}return I}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Auto Pickup",children:(0,e.createComponentVNode)(2,t.Button,{content:V?"Yes":"No",selected:V,onClick:function(){function I(){return i("set_pickup_type",{autopick:V?0:1})}return I}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Auto Return",children:(0,e.createComponentVNode)(2,t.Button,{content:N?"Yes":"No",selected:N,onClick:function(){function I(){return i("set_auto_return",{autoret:N?0:1})}return I}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Controls",children:[(0,e.createComponentVNode)(2,t.Button,{content:"Stop",icon:"stop",onClick:function(){function I(){return i("stop")}return I}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Proceed",icon:"play",onClick:function(){function I(){return i("start")}return I}()}),(0,e.createComponentVNode)(2,t.Button,{content:"Return Home",icon:"home",onClick:function(){function I(){return i("home")}return I}()})]})]})]})}},23734:function(T,r,n){"use strict";r.__esModule=!0,r.pda_nanobank=void 0;var e=n(89005),a=n(25328),t=n(72253),o=n(36036),p=r.pda_nanobank=function(){function l(u,s){var d=(0,t.useBackend)(s),v=d.act,g=d.data,C=g.logged_in,f=g.owner_name,N=g.money;return C?(0,e.createFragment)([(0,e.createComponentVNode)(2,o.Box,{children:(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account Name",children:f}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account Balance",children:["$",N]})]})}),(0,e.createComponentVNode)(2,o.Box,{children:[(0,e.createComponentVNode)(2,b),(0,e.createComponentVNode)(2,y)]})],4):(0,e.createComponentVNode)(2,i)}return l}(),b=function(u,s){var d=(0,t.useBackend)(s),v=d.data,g=v.is_premium,C=(0,t.useLocalState)(s,"tabIndex",1),f=C[0],N=C[1];return(0,e.createComponentVNode)(2,o.Tabs,{mt:2,children:[(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:f===1,onClick:function(){function V(){return N(1)}return V}(),children:[(0,e.createComponentVNode)(2,o.Icon,{mr:1,name:"list"}),"Transfers"]}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:f===2,onClick:function(){function V(){return N(2)}return V}(),children:[(0,e.createComponentVNode)(2,o.Icon,{mr:1,name:"list"}),"Account Actions"]}),(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:f===3,onClick:function(){function V(){return N(3)}return V}(),children:[(0,e.createComponentVNode)(2,o.Icon,{mr:1,name:"list"}),"Transaction History"]}),!!g&&(0,e.createComponentVNode)(2,o.Tabs.Tab,{selected:f===4,onClick:function(){function V(){return N(4)}return V}(),children:[(0,e.createComponentVNode)(2,o.Icon,{mr:1,name:"list"}),"Supply Orders"]})]})},y=function(u,s){var d=(0,t.useLocalState)(s,"tabIndex",1),v=d[0],g=(0,t.useBackend)(s),C=g.data,f=C.db_status;if(!f)return(0,e.createComponentVNode)(2,o.Box,{children:"Account Database Connection Severed"});switch(v){case 1:return(0,e.createComponentVNode)(2,S);case 2:return(0,e.createComponentVNode)(2,k);case 3:return(0,e.createComponentVNode)(2,h);case 4:return(0,e.createComponentVNode)(2,m);default:return"You are somehow on a tab that doesn't exist! Please let a coder know."}},S=function(u,s){var d,v=(0,t.useBackend)(s),g=v.act,C=v.data,f=C.requests,N=C.available_accounts,V=C.money,B=(0,t.useLocalState)(s,"selectedAccount"),I=B[0],L=B[1],w=(0,t.useLocalState)(s,"transferAmount"),A=w[0],x=w[1],E=(0,t.useLocalState)(s,"searchText",""),P=E[0],D=E[1],M=[];return N.map(function(O){return M[O.name]=O.UID}),(0,e.createFragment)([(0,e.createComponentVNode)(2,o.LabeledList,{children:[(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Account",children:[(0,e.createComponentVNode)(2,o.Input,{placeholder:"Search by account name",onInput:function(){function O(R,F){return D(F)}return O}()}),(0,e.createComponentVNode)(2,o.Dropdown,{mt:.6,width:"190px",options:N.filter((0,a.createSearch)(P,function(O){return O.name})).map(function(O){return O.name}),selected:(d=N.filter(function(O){return O.UID===I})[0])==null?void 0:d.name,onSelected:function(){function O(R){return L(M[R])}return O}()})]}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Amount",children:(0,e.createComponentVNode)(2,o.Input,{placeholder:"Up to 5000",onInput:function(){function O(R,F){return x(F)}return O}()})}),(0,e.createComponentVNode)(2,o.LabeledList.Item,{label:"Actions",children:[(0,e.createComponentVNode)(2,o.Button.Confirm,{bold:!0,icon:"paper-plane",width:"auto",disabled:V0&&d.map(function(g){return(0,e.createComponentVNode)(2,t.Box,{children:["#",g.Number,' - "',g.Name,'" for "',g.OrderedBy,'"']},g)})}),(0,e.createComponentVNode)(2,t.Section,{title:"Approved Orders",children:s>0&&u.map(function(g){return(0,e.createComponentVNode)(2,t.Box,{children:["#",g.Number,' - "',g.Name,'" for "',g.ApprovedBy,'"']},g)})})]})}return p}()},17617:function(T,r,n){"use strict";r.__esModule=!0,r.Layout=void 0;var e=n(89005),a=n(35840),t=n(55937),o=n(24826),p=["className","theme","children"],b=["className","scrollable","children"];/** * @file * @copyright 2020 Aleksej Komarov * @license MIT - */var n=r.captureExternalLinks=function(){function e(){document.addEventListener("click",function(a){for(var t=a.target;;){if(!t||t===document.body)return;var o=String(t.tagName).toLowerCase();if(o==="a")break;t=t.parentElement}var f=t.getAttribute("href")||"",b=f.charAt(0)==="?"||f.startsWith("byond://");if(!b){a.preventDefault();var y=f;y.toLowerCase().startsWith("www")&&(y="https://"+y),Byond.sendMessage({type:"openLink",url:y})}})}return e}()},9394:function(T,r,n){"use strict";r.__esModule=!0,r.logger=r.createLogger=void 0;var e=n(7435);/** + */function y(h,i){if(h==null)return{};var c={};for(var m in h)if({}.hasOwnProperty.call(h,m)){if(i.includes(m))continue;c[m]=h[m]}return c}var S=r.Layout=function(){function h(i){var c=i.className,m=i.theme,l=m===void 0?"nanotrasen":m,u=i.children,s=y(i,p);return document.documentElement.className="theme-"+l,(0,e.createVNode)(1,"div","theme-"+l,(0,e.normalizeProps)((0,e.createVNode)(1,"div",(0,a.classes)(["Layout",c].concat((0,t.computeBoxClassName)(s))),u,0,Object.assign({},(0,t.computeBoxProps)(s)))),2)}return h}(),k=function(i){var c=i.className,m=i.scrollable,l=i.children,u=y(i,b);return(0,e.normalizeProps)((0,e.createVNode)(1,"div",(0,a.classes)(["Layout__content",m&&"Layout__content--scrollable",c,(0,t.computeBoxClassName)(u)]),l,0,Object.assign({},(0,t.computeBoxProps)(u))))};k.defaultHooks={onComponentDidMount:function(){function h(i){return(0,o.addScrollableNode)(i)}return h}(),onComponentWillUnmount:function(){function h(i){return(0,o.removeScrollableNode)(i)}return h}()},S.Content=k},96945:function(T,r,n){"use strict";r.__esModule=!0,r.Pane=void 0;var e=n(89005),a=n(35840),t=n(72253),o=n(36036),p=n(99851),b=n(17617),y=["theme","children","className"],S=["className","fitted","children"];/** * @file * @copyright 2020 Aleksej Komarov * @license MIT + */function k(c,m){if(c==null)return{};var l={};for(var u in c)if({}.hasOwnProperty.call(c,u)){if(m.includes(u))continue;l[u]=c[u]}return l}var h=r.Pane=function(){function c(m,l){var u=m.theme,s=m.children,d=m.className,v=k(m,y),g=(0,t.useBackend)(l),C=g.suspended,f=(0,p.useDebug)(l),N=f.debugLayout;return(0,e.normalizeProps)((0,e.createComponentVNode)(2,b.Layout,Object.assign({className:(0,a.classes)(["Window",d]),theme:u},v,{children:(0,e.createComponentVNode)(2,o.Box,{fillPositionedParent:!0,className:N&&"debug-layout",children:!C&&s})})))}return c}(),i=function(m){var l=m.className,u=m.fitted,s=m.children,d=k(m,S);return(0,e.normalizeProps)((0,e.createComponentVNode)(2,b.Layout.Content,Object.assign({className:(0,a.classes)(["Window__content",l])},d,{children:u&&s||(0,e.createVNode)(1,"div","Window__contentPadding",s,0)})))};h.Content=i},34827:function(T,r,n){"use strict";r.__esModule=!0,r.Window=void 0;var e=n(89005),a=n(35840),t=n(85307),o=n(25328),p=n(72253),b=n(36036),y=n(76910),S=n(99851),k=n(77384),h=n(35421),i=n(9394),c=n(17617),m=["className","fitted","children"];function l(V,B){if(V==null)return{};var I={};for(var L in V)if({}.hasOwnProperty.call(V,L)){if(B.includes(L))continue;I[L]=V[L]}return I}function u(V,B){V.prototype=Object.create(B.prototype),V.prototype.constructor=V,s(V,B)}function s(V,B){return s=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(I,L){return I.__proto__=L,I},s(V,B)}/** +* @file +* @copyright 2020 Aleksej Komarov +* @license MIT +*/var d=(0,i.createLogger)("Window"),v=[400,600],g=r.Window=function(V){function B(){return V.apply(this,arguments)||this}u(B,V);var I=B.prototype;return I.componentDidMount=function(){function L(){var w=(0,p.useBackend)(this.context),A=w.suspended;A||(d.log("mounting"),this.updateGeometry())}return L}(),I.componentDidUpdate=function(){function L(w){var A=this.props.width!==w.width||this.props.height!==w.height;A&&this.updateGeometry()}return L}(),I.updateGeometry=function(){function L(){var w,A=(0,p.useBackend)(this.context),x=A.config,E=Object.assign({size:v},x.window);this.props.width&&this.props.height&&(E.size=[this.props.width,this.props.height]),(w=x.window)!=null&&w.key&&(0,h.setWindowKey)(x.window.key),(0,h.recallWindowGeometry)(E)}return L}(),I.render=function(){function L(){var w,A=this.props,x=A.theme,E=A.title,P=A.children,D=(0,p.useBackend)(this.context),M=D.config,O=D.suspended,R=(0,S.useDebug)(this.context),F=R.debugLayout,W=(0,t.useDispatch)(this.context),U=(w=M.window)==null?void 0:w.fancy,z=M.user&&(M.user.observer?M.status>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */var n=r.captureExternalLinks=function(){function e(){document.addEventListener("click",function(a){for(var t=a.target;;){if(!t||t===document.body)return;var o=String(t.tagName).toLowerCase();if(o==="a")break;t=t.parentElement}var p=t.getAttribute("href")||"",b=p.charAt(0)==="?"||p.startsWith("byond://");if(!b){a.preventDefault();var y=p;y.toLowerCase().startsWith("www")&&(y="https://"+y),Byond.sendMessage({type:"openLink",url:y})}})}return e}()},9394:function(T,r,n){"use strict";r.__esModule=!0,r.logger=r.createLogger=void 0;var e=n(7435);/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT +<<<<<<< HEAD */var a=0,t=1,o=2,f=3,b=4,y=function(l,c){for(var m=arguments.length,i=new Array(m>2?m-2:0),u=2;u=o){var s=[c].concat(i).map(function(d){return typeof d=="string"?d:d instanceof Error?d.stack||String(d):JSON.stringify(d)}).filter(function(d){return d}).join(" ")+"\nUser Agent: "+navigator.userAgent;Byond.sendMessage({type:"log",message:s})}},I=r.createLogger=function(){function g(l){return{debug:function(){function c(){for(var m=arguments.length,i=new Array(m),u=0;u2?m-2:0),u=2;u=o){var s=[c].concat(l).map(function(d){return typeof d=="string"?d:d instanceof Error?d.stack||String(d):JSON.stringify(d)}).filter(function(d){return d}).join(" ")+"\nUser Agent: "+navigator.userAgent;Byond.sendMessage({type:"log",message:s})}},S=r.createLogger=function(){function h(i){return{debug:function(){function c(){for(var m=arguments.length,l=new Array(m),u=0;u0;){var f=g.shift(),N=f(v);try{C=b(N)}catch(B){if(B.code!=="MODULE_NOT_FOUND")throw B}}if(!C)return y("notFound",v);var V=C[v];return V||y("missingExport",v)}return i}()},72178:function(T,r,n){"use strict";r.__esModule=!0,r.configureStore=r.StoreProvider=void 0;var e=n(64795),a=n(85307),t=n(89005),o=n(79140),p=n(72253),b=n(99851),y=n(9394);function S(u,s){u.prototype=Object.create(s.prototype),u.prototype.constructor=u,k(u,s)}function k(u,s){return k=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(d,v){return d.__proto__=v,d},k(u,s)}/** +* @file +* @copyright 2020 Aleksej Komarov +* @license MIT +*/var h=(0,y.createLogger)("store"),i=r.configureStore=function(){function u(s){var d,v;s===void 0&&(s={});var g=s,C=g.sideEffects,f=C===void 0?!0:C,N=(0,e.flow)([(0,a.combineReducers)({debug:b.debugReducer,backend:p.backendReducer}),s.reducer]),V=f?[].concat(((d=s.middleware)==null?void 0:d.pre)||[],[o.assetMiddleware,p.backendMiddleware],((v=s.middleware)==null?void 0:v.post)||[]):[],B=a.applyMiddleware.apply(void 0,V),I=(0,a.createStore)(N,B);return window.__store__=I,window.__augmentStack__=m(I),I}return u}(),c=function(s){return function(d){return function(v){var g=v.type,C=v.payload;return g==="update"||g==="backend/update"?h.debug("action",{type:g}):h.debug("action",v),d(v)}}},m=function(s){return function(d,v){var g,C;v?typeof v=="object"&&!v.stack&&(v.stack=d):(v=new Error(d.split("\n")[0]),v.stack=d),h.log("FatalError:",v);var f=s.getState(),N=f==null||(g=f.backend)==null?void 0:g.config,V=d;return V+="\nUser Agent: "+navigator.userAgent,V+="\nState: "+JSON.stringify({ckey:N==null||(C=N.client)==null?void 0:C.ckey,interface:N==null?void 0:N.interface,window:N==null?void 0:N.window}),V}},l=r.StoreProvider=function(u){function s(){return u.apply(this,arguments)||this}S(s,u);var d=s.prototype;return d.getChildContext=function(){function v(){var g=this.props.store;return{store:g}}return v}(),d.render=function(){function v(){return this.props.children}return v}(),s}(t.Component)},51364:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(36036);/** +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * @file * @copyright 2021 Aleksej Komarov * @license MIT - */var t=r.meta={title:"Blink",render:function(){function f(){return(0,e.createComponentVNode)(2,o)}return f}()},o=function(b,y){return(0,e.createComponentVNode)(2,a.Section,{children:(0,e.createComponentVNode)(2,a.Blink,{children:"Blink"})})}},32453:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(36036),t=n(37168);/** + */var t=r.meta={title:"Blink",render:function(){function p(){return(0,e.createComponentVNode)(2,o)}return p}()},o=function(b,y){return(0,e.createComponentVNode)(2,a.Section,{children:(0,e.createComponentVNode)(2,a.Blink,{children:"Blink"})})}},32453:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(36036),t=n(37168);/** * @file * @copyright 2021 Aleksej Komarov * @license MIT +<<<<<<< HEAD */var o=r.meta={title:"BlockQuote",render:function(){function b(){return(0,e.createComponentVNode)(2,f)}return b}()},f=function(y,I){return(0,e.createComponentVNode)(2,a.Section,{children:(0,e.createComponentVNode)(2,a.BlockQuote,{children:(0,e.createComponentVNode)(2,t.BoxWithSampleText)})})}},83531:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(36036);/** +======= + */var o=r.meta={title:"BlockQuote",render:function(){function b(){return(0,e.createComponentVNode)(2,p)}return b}()},p=function(y,S){return(0,e.createComponentVNode)(2,a.Section,{children:(0,e.createComponentVNode)(2,a.BlockQuote,{children:(0,e.createComponentVNode)(2,t.BoxWithSampleText)})})}},83531:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(36036);/** +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb * @file * @copyright 2021 Aleksej Komarov * @license MIT - */var t=r.meta={title:"Box",render:function(){function f(){return(0,e.createComponentVNode)(2,o)}return f}()},o=function(b,y){return(0,e.createComponentVNode)(2,a.Section,{children:[(0,e.createComponentVNode)(2,a.Box,{bold:!0,children:"bold"}),(0,e.createComponentVNode)(2,a.Box,{italic:!0,children:"italic"}),(0,e.createComponentVNode)(2,a.Box,{opacity:.5,children:"opacity 0.5"}),(0,e.createComponentVNode)(2,a.Box,{opacity:.25,children:"opacity 0.25"}),(0,e.createComponentVNode)(2,a.Box,{m:2,children:"m: 2"}),(0,e.createComponentVNode)(2,a.Box,{textAlign:"left",children:"left"}),(0,e.createComponentVNode)(2,a.Box,{textAlign:"center",children:"center"}),(0,e.createComponentVNode)(2,a.Box,{textAlign:"right",children:"right"})]})}},74198:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(72253),t=n(36036);/** + */var t=r.meta={title:"Box",render:function(){function p(){return(0,e.createComponentVNode)(2,o)}return p}()},o=function(b,y){return(0,e.createComponentVNode)(2,a.Section,{children:[(0,e.createComponentVNode)(2,a.Box,{bold:!0,children:"bold"}),(0,e.createComponentVNode)(2,a.Box,{italic:!0,children:"italic"}),(0,e.createComponentVNode)(2,a.Box,{opacity:.5,children:"opacity 0.5"}),(0,e.createComponentVNode)(2,a.Box,{opacity:.25,children:"opacity 0.25"}),(0,e.createComponentVNode)(2,a.Box,{m:2,children:"m: 2"}),(0,e.createComponentVNode)(2,a.Box,{textAlign:"left",children:"left"}),(0,e.createComponentVNode)(2,a.Box,{textAlign:"center",children:"center"}),(0,e.createComponentVNode)(2,a.Box,{textAlign:"right",children:"right"})]})}},74198:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(72253),t=n(36036);/** * @file * @copyright 2021 Aleksej Komarov * @license MIT +<<<<<<< HEAD */var o=r.meta={title:"Button",render:function(){function I(){return(0,e.createComponentVNode)(2,y)}return I}()},f=["red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey","gold"],b=["good","average","bad","black","white"],y=function(k,g){var l=(0,a.useLocalState)(g,"translucent",!1),c=l[0],m=l[1];return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.Box,{mb:1,children:[(0,e.createComponentVNode)(2,t.Button,{content:"Simple"}),(0,e.createComponentVNode)(2,t.Button,{selected:!0,content:"Selected"}),(0,e.createComponentVNode)(2,t.Button,{altSelected:!0,content:"Alt Selected"}),(0,e.createComponentVNode)(2,t.Button,{disabled:!0,content:"Disabled"}),(0,e.createComponentVNode)(2,t.Button,{color:"transparent",content:"Transparent"}),(0,e.createComponentVNode)(2,t.Button,{icon:"cog",content:"Icon"}),(0,e.createComponentVNode)(2,t.Button,{icon:"power-off"}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,content:"Fluid"}),(0,e.createComponentVNode)(2,t.Button,{my:1,lineHeight:2,minWidth:15,textAlign:"center",content:"With Box props"})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Color States",buttons:(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:c,onClick:function(){function i(){return m(!c)}return i}(),content:"Translucent"}),children:b.map(function(i){return(0,e.createComponentVNode)(2,t.Button,{translucent:c,color:i,content:i},i)})}),(0,e.createComponentVNode)(2,t.Section,{title:"Available Colors",children:f.map(function(i){return(0,e.createComponentVNode)(2,t.Button,{translucent:c,color:i,content:i},i)})}),(0,e.createComponentVNode)(2,t.Section,{title:"Text Colors",children:f.map(function(i){return(0,e.createComponentVNode)(2,t.Box,{inline:!0,mx:"7px",color:i,children:i},i)})})],4)}},51956:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(9394);/** * @file * @copyright 2021 Aleksej Komarov @@ -336,13 +577,57 @@ * @copyright 2021 Aleksej Komarov * @license MIT */var o=r.meta={title:"Themes",render:function(){function b(){return(0,e.createComponentVNode)(2,f)}return b}()},f=function(y,I){var k=(0,a.useLocalState)(I,"kitchenSinkTheme"),g=k[0],l=k[1];return(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Use theme",children:(0,e.createComponentVNode)(2,t.Input,{placeholder:"theme_name",value:g,onInput:function(){function c(m,i){return l(i)}return c}()})})})})}},28717:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(36036);/** +======= + */var o=r.meta={title:"Button",render:function(){function S(){return(0,e.createComponentVNode)(2,y)}return S}()},p=["red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey","gold"],b=["good","average","bad","black","white"],y=function(k,h){var i=(0,a.useLocalState)(h,"translucent",!1),c=i[0],m=i[1];return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.Box,{mb:1,children:[(0,e.createComponentVNode)(2,t.Button,{content:"Simple"}),(0,e.createComponentVNode)(2,t.Button,{selected:!0,content:"Selected"}),(0,e.createComponentVNode)(2,t.Button,{altSelected:!0,content:"Alt Selected"}),(0,e.createComponentVNode)(2,t.Button,{disabled:!0,content:"Disabled"}),(0,e.createComponentVNode)(2,t.Button,{color:"transparent",content:"Transparent"}),(0,e.createComponentVNode)(2,t.Button,{icon:"cog",content:"Icon"}),(0,e.createComponentVNode)(2,t.Button,{icon:"power-off"}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,content:"Fluid"}),(0,e.createComponentVNode)(2,t.Button,{my:1,lineHeight:2,minWidth:15,textAlign:"center",content:"With Box props"})]})}),(0,e.createComponentVNode)(2,t.Section,{title:"Color States",buttons:(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:c,onClick:function(){function l(){return m(!c)}return l}(),content:"Translucent"}),children:b.map(function(l){return(0,e.createComponentVNode)(2,t.Button,{translucent:c,color:l,content:l},l)})}),(0,e.createComponentVNode)(2,t.Section,{title:"Available Colors",children:p.map(function(l){return(0,e.createComponentVNode)(2,t.Button,{translucent:c,color:l,content:l},l)})}),(0,e.createComponentVNode)(2,t.Section,{title:"Text Colors",children:p.map(function(l){return(0,e.createComponentVNode)(2,t.Box,{inline:!0,mx:"7px",color:l,children:l},l)})})],4)}},51956:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(72253),t=n(36036),o=n(9394);/** + * @file + * @copyright 2021 Aleksej Komarov + * @license MIT + */var p=r.meta={title:"ByondUi",render:function(){function y(){return(0,e.createComponentVNode)(2,b)}return y}()},b=function(S,k){var h=(0,a.useLocalState)(k,"byondUiEvalCode","Byond.winset('"+Byond.windowId+"', {\n 'is-visible': true,\n})"),i=h[0],c=h[1];return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{title:"Button",children:(0,e.createComponentVNode)(2,t.ByondUi,{params:{type:"button",text:"Button"}})}),(0,e.createComponentVNode)(2,t.Section,{title:"Make BYOND calls",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"chevron-right",onClick:function(){function m(){return setTimeout(function(){try{var l=new Function("return ("+i+")")();l&&l.then?(o.logger.log("Promise"),l.then(o.logger.log)):o.logger.log(l)}catch(u){o.logger.log(u)}})}return m}(),children:"Evaluate"}),children:(0,e.createComponentVNode)(2,t.Box,{as:"textarea",width:"100%",height:"10em",onChange:function(){function m(l){return c(l.target.value)}return m}(),children:i})})],4)}},17466:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(36036),t=n(37168);/** + * @file + * @copyright 2021 Aleksej Komarov + * @license MIT + */var o=r.meta={title:"Collapsible",render:function(){function b(){return(0,e.createComponentVNode)(2,p)}return b}()},p=function(y,S){return(0,e.createComponentVNode)(2,a.Section,{children:(0,e.createComponentVNode)(2,a.Collapsible,{title:"Collapsible Demo",buttons:(0,e.createComponentVNode)(2,a.Button,{icon:"cog"}),children:(0,e.createComponentVNode)(2,t.BoxWithSampleText)})})}},89241:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(72253),t=n(36036);/** + * @file + * @copyright 2021 Aleksej Komarov + * @license MIT + */var o=r.meta={title:"Flex & Sections",render:function(){function b(){return(0,e.createComponentVNode)(2,p)}return b}()},p=function(y,S){var k=(0,a.useLocalState)(S,"fs_grow",1),h=k[0],i=k[1],c=(0,a.useLocalState)(S,"fs_direction","column"),m=c[0],l=c[1],u=(0,a.useLocalState)(S,"fs_fill",!0),s=u[0],d=u[1],v=(0,a.useLocalState)(S,"fs_title",!0),g=v[0],C=v[1];return(0,e.createComponentVNode)(2,t.Flex,{height:"100%",direction:"column",children:[(0,e.createComponentVNode)(2,t.Flex.Item,{mb:1,children:(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Button,{fluid:!0,onClick:function(){function f(){return l(m==="column"?"row":"column")}return f}(),children:'Flex direction="'+m+'"'}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,onClick:function(){function f(){return i(+!h)}return f}(),children:"Flex.Item grow={"+h+"}"}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,onClick:function(){function f(){return d(!s)}return f}(),children:"Section fill={"+String(s)+"}"}),(0,e.createComponentVNode)(2,t.Button,{fluid:!0,selected:g,onClick:function(){function f(){return C(!g)}return f}(),children:"Section title"})]})}),(0,e.createComponentVNode)(2,t.Flex.Item,{grow:1,children:(0,e.createComponentVNode)(2,t.Flex,{height:"100%",direction:m,children:[(0,e.createComponentVNode)(2,t.Flex.Item,{mr:m==="row"&&1,mb:m==="column"&&1,grow:h,children:(0,e.createComponentVNode)(2,t.Section,{title:g&&"Section 1",fill:s,children:"Content"})}),(0,e.createComponentVNode)(2,t.Flex.Item,{grow:h,children:(0,e.createComponentVNode)(2,t.Section,{title:g&&"Section 2",fill:s,children:"Content"})})]})})]})}},48779:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(72253),t=n(36036);/** + * @file + * @copyright 2024 Aylong (https://github.com/AyIong) + * @license MIT + */var o=r.meta={title:"ImageButton",render:function(){function S(){return(0,e.createComponentVNode)(2,y)}return S}()},p=["red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey","gold"],b=["good","average","bad","black","white"],y=function(k,h){var i=(0,a.useLocalState)(h,"fluid1",!0),c=i[0],m=i[1],l=(0,a.useLocalState)(h,"fluid2",!1),u=l[0],s=l[1],d=(0,a.useLocalState)(h,"fluid3",!1),v=d[0],g=d[1],C=(0,a.useLocalState)(h,"disabled",!1),f=C[0],N=C[1],V=(0,a.useLocalState)(h,"selected",!1),B=V[0],I=V[1],L=(0,a.useLocalState)(h,"addImage",!1),w=L[0],A=L[1],x=(0,a.useLocalState)(h,"base64",""),E=x[0],P=x[1],D=(0,a.useLocalState)(h,"title","Image Button"),M=D[0],O=D[1],R=(0,a.useLocalState)(h,"content","You can put anything in there"),F=R[0],W=R[1],U=(0,a.useLocalState)(h,"imageSize",64),z=U[0],$=U[1];return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Stack,{children:[(0,e.createComponentVNode)(2,t.Stack.Item,{basis:"50%",children:(0,e.createComponentVNode)(2,t.LabeledList,{children:w?(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"base64",children:(0,e.createComponentVNode)(2,t.Input,{value:E,onInput:function(){function G(X,J){return P(J)}return G}()})}):(0,e.createFragment)([(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Title",children:(0,e.createComponentVNode)(2,t.Input,{value:M,onInput:function(){function G(X,J){return O(J)}return G}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Content",children:(0,e.createComponentVNode)(2,t.Input,{value:F,onInput:function(){function G(X,J){return W(J)}return G}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Image Size",children:(0,e.createComponentVNode)(2,t.Slider,{width:10,value:z,minValue:0,maxValue:256,step:1,onChange:function(){function G(X,J){return $(J)}return G}()})})],4)})}),(0,e.createComponentVNode)(2,t.Stack.Item,{basis:"50%",children:(0,e.createComponentVNode)(2,t.Stack,{fill:!0,vertical:!0,children:[(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:c,onClick:function(){function G(){return m(!c)}return G}(),children:"Fluid"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:f,onClick:function(){function G(){return N(!f)}return G}(),children:"Disabled"})}),(0,e.createComponentVNode)(2,t.Stack.Item,{grow:!0,children:(0,e.createComponentVNode)(2,t.Button.Checkbox,{fluid:!0,checked:B,onClick:function(){function G(){return I(!B)}return G}(),children:"Selected"})})]})})]}),(0,e.createComponentVNode)(2,t.Stack.Item,{mt:1,children:(0,e.createComponentVNode)(2,t.ImageButton,{m:!c&&0,fluid:c,base64:E,imageSize:z,title:M,tooltip:!c&&F,disabled:f,selected:B,buttonsAlt:c,buttons:(0,e.createComponentVNode)(2,t.Button,{fluid:!0,translucent:c,compact:!c,color:!c&&"transparent",selected:w,onClick:function(){function G(){return A(!w)}return G}(),children:"Add Image"}),children:F})})]}),(0,e.createComponentVNode)(2,t.Section,{title:"Color States",buttons:(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:u,onClick:function(){function G(){return s(!u)}return G}(),children:"Fluid"}),children:b.map(function(G){return(0,e.createComponentVNode)(2,t.ImageButton,{fluid:u,color:G,imageSize:u?24:48,children:G},G)})}),(0,e.createComponentVNode)(2,t.Section,{title:"Available Colors",buttons:(0,e.createComponentVNode)(2,t.Button.Checkbox,{checked:v,onClick:function(){function G(){return g(!v)}return G}(),children:"Fluid"}),children:p.map(function(G){return(0,e.createComponentVNode)(2,t.ImageButton,{fluid:v,color:G,imageSize:v?24:48,children:G},G)})})],4)}},21394:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(72253),t=n(36036);/** + * @file + * @copyright 2021 Aleksej Komarov + * @license MIT + */var o=r.meta={title:"Input",render:function(){function b(){return(0,e.createComponentVNode)(2,p)}return b}()},p=function(y,S){var k=(0,a.useLocalState)(S,"number",0),h=k[0],i=k[1],c=(0,a.useLocalState)(S,"text","Sample text"),m=c[0],l=c[1];return(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Input (onChange)",children:(0,e.createComponentVNode)(2,t.Input,{value:m,onChange:function(){function u(s,d){return l(d)}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Input (onInput)",children:(0,e.createComponentVNode)(2,t.Input,{value:m,onInput:function(){function u(s,d){return l(d)}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"NumberInput (onChange)",children:(0,e.createComponentVNode)(2,t.NumberInput,{animated:!0,width:"40px",step:1,stepPixelSize:5,value:h,minValue:-100,maxValue:100,onChange:function(){function u(s,d){return i(d)}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"NumberInput (onDrag)",children:(0,e.createComponentVNode)(2,t.NumberInput,{animated:!0,width:"40px",step:1,stepPixelSize:5,value:h,minValue:-100,maxValue:100,onDrag:function(){function u(s,d){return i(d)}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Slider (onDrag)",children:(0,e.createComponentVNode)(2,t.Slider,{step:1,stepPixelSize:5,value:h,minValue:-100,maxValue:100,onDrag:function(){function u(s,d){return i(d)}return u}()})}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Knob (onDrag)",children:[(0,e.createComponentVNode)(2,t.Knob,{inline:!0,size:1,step:1,stepPixelSize:2,value:h,minValue:-100,maxValue:100,onDrag:function(){function u(s,d){return i(d)}return u}()}),(0,e.createComponentVNode)(2,t.Knob,{ml:1,inline:!0,bipolar:!0,size:1,step:1,stepPixelSize:2,value:h,minValue:-100,maxValue:100,onDrag:function(){function u(s,d){return i(d)}return u}()})]}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Rotating Icon",children:(0,e.createComponentVNode)(2,t.Box,{inline:!0,position:"relative",children:(0,e.createComponentVNode)(2,t.DraggableControl,{value:h,minValue:-100,maxValue:100,dragMatrix:[0,-1],step:1,stepPixelSize:5,onDrag:function(){function u(s,d){return i(d)}return u}(),children:function(){function u(s){return(0,e.createComponentVNode)(2,t.Box,{onMouseDown:s.handleDragStart,children:[(0,e.createComponentVNode)(2,t.Icon,{size:4,color:"yellow",name:"times",rotation:s.displayValue*4}),s.inputElement]})}return u}()})})})]})})}},43932:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(36036),t=r.meta={title:"Popper",render:function(){function p(){return(0,e.createComponentVNode)(2,o)}return p}()},o=function(){return(0,e.createFragment)([(0,e.createComponentVNode)(2,a.Popper,{popperContent:(0,e.createComponentVNode)(2,a.Box,{style:{background:"white",border:"2px solid blue"},children:"Loogatme!"}),options:{placement:"bottom"},children:(0,e.createComponentVNode)(2,a.Box,{style:{border:"5px solid white",height:"300px",width:"200px"}})}),(0,e.createComponentVNode)(2,a.Popper,{popperContent:(0,e.createComponentVNode)(2,a.Box,{style:{background:"white",border:"2px solid blue"},children:"I am on the right!"}),options:{placement:"right"},children:(0,e.createComponentVNode)(2,a.Box,{style:{border:"5px solid white",height:"500px",width:"100px"}})})],4)}},33270:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(72253),t=n(36036);/** * @file * @copyright 2021 Aleksej Komarov * @license MIT - */var t=r.meta={title:"Tooltip",render:function(){function f(){return(0,e.createComponentVNode)(2,o)}return f}()},o=function(){var b=["top","left","right","bottom","bottom-start","bottom-end"];return(0,e.createComponentVNode)(2,a.Section,{children:[(0,e.createComponentVNode)(2,a.Box,{children:[(0,e.createComponentVNode)(2,a.Tooltip,{content:"Tooltip text.",children:(0,e.createComponentVNode)(2,a.Box,{inline:!0,position:"relative",mr:1,children:"Box (hover me)."})}),(0,e.createComponentVNode)(2,a.Button,{tooltip:"Tooltip text.",content:"Button"})]}),(0,e.createComponentVNode)(2,a.Box,{mt:1,children:b.map(function(y){return(0,e.createComponentVNode)(2,a.Button,{color:"transparent",tooltip:"Tooltip text.",tooltipPosition:y,content:y},y)})})]})}},37168:function(T,r,n){"use strict";r.__esModule=!0,r.BoxWithSampleText=void 0;var e=n(89005),a=n(36036);/** + */var o=r.meta={title:"ProgressBar",render:function(){function b(){return(0,e.createComponentVNode)(2,p)}return b}()},p=function(y,S){var k=(0,a.useLocalState)(S,"progress",.5),h=k[0],i=k[1];return(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.ProgressBar,{ranges:{good:[.5,1/0],bad:[-1/0,.1],average:[0,.5]},minValue:-1,maxValue:1,value:h,children:["Value: ",Number(h).toFixed(1)]}),(0,e.createComponentVNode)(2,t.Box,{mt:1,children:[(0,e.createComponentVNode)(2,t.Button,{content:"-0.1",onClick:function(){function c(){return i(h-.1)}return c}()}),(0,e.createComponentVNode)(2,t.Button,{content:"+0.1",onClick:function(){function c(){return i(h+.1)}return c}()})]})]})}},77766:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(36036);/** * @file * @copyright 2021 Aleksej Komarov * @license MIT + */var t=r.meta={title:"Stack",render:function(){function y(){return(0,e.createComponentVNode)(2,b)}return y}()},o=function(){return(0,e.createComponentVNode)(2,a.Box,{inline:!0,width:1,height:1,children:"A"})},p=function(){return(0,e.createFragment)([(0,e.createComponentVNode)(2,a.Stack.Item,{children:(0,e.createComponentVNode)(2,o)}),(0,e.createComponentVNode)(2,a.Stack.Divider),(0,e.createComponentVNode)(2,a.Stack.Item,{children:(0,e.createComponentVNode)(2,o)})],4)},b=function(S,k){return(0,e.createComponentVNode)(2,a.Section,{fill:!0,children:(0,e.createComponentVNode)(2,a.Stack,{fill:!0,className:"debug-layout",children:[(0,e.createComponentVNode)(2,p),(0,e.createComponentVNode)(2,a.Stack.Item,{grow:1,children:(0,e.createComponentVNode)(2,a.Stack,{fill:!0,vertical:!0,zebra:!0,children:[(0,e.createComponentVNode)(2,p),(0,e.createComponentVNode)(2,a.Stack.Item,{children:(0,e.createComponentVNode)(2,a.Stack,{fill:!0,children:[(0,e.createComponentVNode)(2,p),(0,e.createComponentVNode)(2,a.Stack.Item,{grow:1}),(0,e.createComponentVNode)(2,p),(0,e.createComponentVNode)(2,p)]})}),(0,e.createComponentVNode)(2,a.Stack.Item,{grow:1}),(0,e.createComponentVNode)(2,p)]})})]})})}},30187:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(27108),t=n(36036),o=n(49968);/** + * @file + * @copyright 2021 Aleksej Komarov + * @license MIT + */var p=r.meta={title:"Storage",render:function(){function y(){return(0,e.createComponentVNode)(2,b)}return y}()},b=function(S,k){return window.localStorage?(0,e.createComponentVNode)(2,t.Section,{title:"Local Storage",buttons:(0,e.createComponentVNode)(2,t.Button,{icon:"recycle",onClick:function(){function h(){localStorage.clear(),a.storage.clear()}return h}(),children:"Clear"}),children:(0,e.createComponentVNode)(2,t.LabeledList,{children:[(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Keys in use",children:localStorage.length}),(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Remaining space",children:(0,o.formatSiUnit)(localStorage.remainingSpace,0,"B")})]})}):(0,e.createComponentVNode)(2,t.NoticeBox,{children:"Local storage is not available."})}},46554:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(72253),t=n(36036);/** + * @file + * @copyright 2021 Aleksej Komarov + * @license MIT + */var o=r.meta={title:"Tabs",render:function(){function y(){return(0,e.createComponentVNode)(2,b)}return y}()},p=["Tab #1","Tab #2","Tab #3","Tab #4"],b=function(S,k){var h=(0,a.useLocalState)(k,"tabIndex",0),i=h[0],c=h[1],m=(0,a.useLocalState)(k,"tabProps",{}),l=m[0],u=m[1];return(0,e.createFragment)([(0,e.createComponentVNode)(2,t.Section,{children:[(0,e.createComponentVNode)(2,t.Button.Checkbox,{inline:!0,content:"vertical",checked:l.vertical,onClick:function(){function s(){return u(Object.assign({},l,{vertical:!l.vertical}))}return s}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{inline:!0,content:"leftSlot",checked:l.leftSlot,onClick:function(){function s(){return u(Object.assign({},l,{leftSlot:!l.leftSlot}))}return s}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{inline:!0,content:"rightSlot",checked:l.rightSlot,onClick:function(){function s(){return u(Object.assign({},l,{rightSlot:!l.rightSlot}))}return s}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{inline:!0,content:"icon",checked:l.icon,onClick:function(){function s(){return u(Object.assign({},l,{icon:!l.icon}))}return s}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{inline:!0,content:"fluid",checked:l.fluid,onClick:function(){function s(){return u(Object.assign({},l,{fluid:!l.fluid}))}return s}()}),(0,e.createComponentVNode)(2,t.Button.Checkbox,{inline:!0,content:"left aligned",checked:l.leftAligned,onClick:function(){function s(){return u(Object.assign({},l,{leftAligned:!l.leftAligned}))}return s}()})]}),(0,e.createComponentVNode)(2,t.Section,{fitted:!0,children:(0,e.createComponentVNode)(2,t.Tabs,{vertical:l.vertical,fluid:l.fluid,textAlign:l.leftAligned&&"left",children:p.map(function(s,d){return(0,e.createComponentVNode)(2,t.Tabs.Tab,{selected:d===i,icon:l.icon&&"info-circle",leftSlot:l.leftSlot&&(0,e.createComponentVNode)(2,t.Button,{circular:!0,compact:!0,color:"transparent",icon:"times"}),rightSlot:l.rightSlot&&(0,e.createComponentVNode)(2,t.Button,{circular:!0,compact:!0,color:"transparent",icon:"times"}),onClick:function(){function v(){return c(d)}return v}(),children:s},d)})})})],4)}},53276:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(72253),t=n(36036);/** + * @file + * @copyright 2021 Aleksej Komarov + * @license MIT + */var o=r.meta={title:"Themes",render:function(){function b(){return(0,e.createComponentVNode)(2,p)}return b}()},p=function(y,S){var k=(0,a.useLocalState)(S,"kitchenSinkTheme"),h=k[0],i=k[1];return(0,e.createComponentVNode)(2,t.Section,{children:(0,e.createComponentVNode)(2,t.LabeledList,{children:(0,e.createComponentVNode)(2,t.LabeledList.Item,{label:"Use theme",children:(0,e.createComponentVNode)(2,t.Input,{placeholder:"theme_name",value:h,onInput:function(){function c(m,l){return i(l)}return c}()})})})})}},28717:function(T,r,n){"use strict";r.__esModule=!0,r.meta=void 0;var e=n(89005),a=n(36036);/** +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb + * @file + * @copyright 2021 Aleksej Komarov + * @license MIT + */var t=r.meta={title:"Tooltip",render:function(){function p(){return(0,e.createComponentVNode)(2,o)}return p}()},o=function(){var b=["top","left","right","bottom","bottom-start","bottom-end"];return(0,e.createComponentVNode)(2,a.Section,{children:[(0,e.createComponentVNode)(2,a.Box,{children:[(0,e.createComponentVNode)(2,a.Tooltip,{content:"Tooltip text.",children:(0,e.createComponentVNode)(2,a.Box,{inline:!0,position:"relative",mr:1,children:"Box (hover me)."})}),(0,e.createComponentVNode)(2,a.Button,{tooltip:"Tooltip text.",content:"Button"})]}),(0,e.createComponentVNode)(2,a.Box,{mt:1,children:b.map(function(y){return(0,e.createComponentVNode)(2,a.Button,{color:"transparent",tooltip:"Tooltip text.",tooltipPosition:y,content:y},y)})})]})}},37168:function(T,r,n){"use strict";r.__esModule=!0,r.BoxWithSampleText=void 0;var e=n(89005),a=n(36036);/** + * @file + * @copyright 2021 Aleksej Komarov + * @license MIT +<<<<<<< HEAD */var t=r.BoxWithSampleText=function(){function o(f){return(0,e.normalizeProps)((0,e.createComponentVNode)(2,a.Box,Object.assign({},f,{children:[(0,e.createComponentVNode)(2,a.Box,{italic:!0,children:"Jackdaws love my big sphinx of quartz."}),(0,e.createComponentVNode)(2,a.Box,{mt:1,bold:!0,children:"The wide electrification of the southern provinces will give a powerful impetus to the growth of agriculture."})]})))}return o}()},67160:function(){},23542:function(){},30386:function(){},98996:function(){},50578:function(){},4444:function(){},77870:function(){},23632:function(){},56492:function(){},39108:function(){},11714:function(){},73492:function(){},49641:function(){},17570:function(){},61858:function(){},32882:function(){},70752:function(T,r,n){var e={"./pai_atmosphere.js":80818,"./pai_bioscan.js":23903,"./pai_directives.js":64988,"./pai_doorjack.js":13813,"./pai_main_menu.js":66025,"./pai_manifest.js":2983,"./pai_medrecords.js":40758,"./pai_messenger.js":98599,"./pai_radio.js":50775,"./pai_secrecords.js":48623,"./pai_signaler.js":47297};function a(o){var f=t(o);return n(f)}function t(o){if(!n.o(e,o)){var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}return e[o]}a.keys=function(){return Object.keys(e)},a.resolve=t,T.exports=a,a.id=70752},59395:function(T,r,n){var e={"./pda_atmos_scan.js":78532,"./pda_games.js":2395,"./pda_janitor.js":40253,"./pda_main_menu.js":58293,"./pda_manifest.js":58059,"./pda_medical.js":18147,"./pda_messenger.js":77595,"./pda_minesweeper.js":90382,"./pda_mule.js":24635,"./pda_nanobank.js":23734,"./pda_notes.js":97085,"./pda_power.js":57513,"./pda_secbot.js":99808,"./pda_security.js":77168,"./pda_signaler.js":21773,"./pda_status_display.js":81857,"./pda_supplyrecords.js":70287};function a(o){var f=t(o);return n(f)}function t(o){if(!n.o(e,o)){var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}return e[o]}a.keys=function(){return Object.keys(e)},a.resolve=t,T.exports=a,a.id=59395},32054:function(T,r,n){var e={"./AICard":1090,"./AICard.js":1090,"./AIFixer":39454,"./AIFixer.js":39454,"./APC":88422,"./APC.js":88422,"./ATM":99660,"./ATM.js":99660,"./AccountsUplinkTerminal":86423,"./AccountsUplinkTerminal.js":86423,"./AdminAntagMenu":23001,"./AdminAntagMenu.js":23001,"./AgentCard":39683,"./AgentCard.tsx":39683,"./AiAirlock":56793,"./AiAirlock.js":56793,"./AirAlarm":72475,"./AirAlarm.js":72475,"./AirlockAccessController":12333,"./AirlockAccessController.js":12333,"./AirlockElectronics":28736,"./AirlockElectronics.js":28736,"./AlertModal":47365,"./AlertModal.tsx":47365,"./AppearanceChanger":71824,"./AppearanceChanger.js":71824,"./AtmosAlertConsole":72285,"./AtmosAlertConsole.js":72285,"./AtmosControl":65805,"./AtmosControl.js":65805,"./AtmosFilter":87816,"./AtmosFilter.js":87816,"./AtmosMixer":52977,"./AtmosMixer.js":52977,"./AtmosPump":11748,"./AtmosPump.js":11748,"./AtmosTankControl":69321,"./AtmosTankControl.js":69321,"./AugmentMenu":92444,"./AugmentMenu.js":92444,"./Autolathe":59179,"./Autolathe.js":59179,"./BioChipPad":5147,"./BioChipPad.js":5147,"./Biogenerator":64273,"./Biogenerator.js":64273,"./BloomEdit":47823,"./BloomEdit.js":47823,"./BlueSpaceArtilleryControl":18621,"./BlueSpaceArtilleryControl.js":18621,"./BluespaceTap":27629,"./BluespaceTap.js":27629,"./BodyScanner":33758,"./BodyScanner.js":33758,"./BookBinder":67963,"./BookBinder.js":67963,"./BotCall":61925,"./BotCall.js":61925,"./BotClean":20464,"./BotClean.js":20464,"./BotFloor":69479,"./BotFloor.js":69479,"./BotHonk":59887,"./BotHonk.js":59887,"./BotMed":80063,"./BotMed.js":80063,"./BotSecurity":74439,"./BotSecurity.js":74439,"./BrigCells":10833,"./BrigCells.js":10833,"./BrigTimer":45761,"./BrigTimer.js":45761,"./CameraConsole":26300,"./CameraConsole.js":26300,"./Canister":52927,"./Canister.js":52927,"./CardComputer":51793,"./CardComputer.js":51793,"./CargoConsole":64083,"./CargoConsole.js":64083,"./Chameleon":36232,"./Chameleon.tsx":36232,"./ChangelogView":87331,"./ChangelogView.js":87331,"./CheckboxListInputModal":91360,"./CheckboxListInputModal.tsx":91360,"./ChemDispenser":36108,"./ChemDispenser.js":36108,"./ChemHeater":13146,"./ChemHeater.js":13146,"./ChemMaster":56541,"./ChemMaster.tsx":56541,"./CloningConsole":37173,"./CloningConsole.js":37173,"./CloningPod":98723,"./CloningPod.js":98723,"./CoinMint":18259,"./CoinMint.tsx":18259,"./ColorPickerModal":93858,"./ColorPickerModal.tsx":93858,"./ColourMatrixTester":8444,"./ColourMatrixTester.js":8444,"./CommunicationsComputer":63818,"./CommunicationsComputer.js":63818,"./CompostBin":20562,"./CompostBin.js":20562,"./Contractor":21813,"./Contractor.js":21813,"./ConveyorSwitch":54151,"./ConveyorSwitch.js":54151,"./CrewMonitor":73169,"./CrewMonitor.js":73169,"./Cryo":63987,"./Cryo.js":63987,"./CryopodConsole":86099,"./CryopodConsole.js":86099,"./DNAModifier":12692,"./DNAModifier.js":12692,"./DecalPainter":76430,"./DecalPainter.js":76430,"./DestinationTagger":41074,"./DestinationTagger.js":41074,"./DisposalBin":46500,"./DisposalBin.js":46500,"./DnaVault":33233,"./DnaVault.js":33233,"./DroneConsole":33681,"./DroneConsole.js":33681,"./EFTPOS":17263,"./EFTPOS.js":17263,"./ERTManager":76382,"./ERTManager.js":76382,"./EconomyManager":90217,"./EconomyManager.js":90217,"./Electropack":82565,"./Electropack.js":82565,"./Emojipedia":11243,"./Emojipedia.tsx":11243,"./EvolutionMenu":36730,"./EvolutionMenu.js":36730,"./ExosuitFabricator":17370,"./ExosuitFabricator.js":17370,"./ExperimentConsole":59128,"./ExperimentConsole.js":59128,"./ExternalAirlockController":97086,"./ExternalAirlockController.js":97086,"./FaxMachine":96142,"./FaxMachine.js":96142,"./FilingCabinet":74123,"./FilingCabinet.js":74123,"./FloorPainter":83767,"./FloorPainter.js":83767,"./GPS":53424,"./GPS.js":53424,"./GeneModder":89124,"./GeneModder.js":89124,"./GenericCrewManifest":73053,"./GenericCrewManifest.js":73053,"./GhostHudPanel":42914,"./GhostHudPanel.js":42914,"./GlandDispenser":25825,"./GlandDispenser.js":25825,"./GravityGen":10270,"./GravityGen.js":10270,"./GuestPass":48657,"./GuestPass.js":48657,"./HandheldChemDispenser":67834,"./HandheldChemDispenser.js":67834,"./HealthSensor":46098,"./HealthSensor.js":46098,"./Holodeck":36771,"./Holodeck.js":36771,"./Instrument":25471,"./Instrument.js":25471,"./KeyComboModal":13618,"./KeyComboModal.tsx":13618,"./KeycardAuth":35655,"./KeycardAuth.js":35655,"./KitchenMachine":62955,"./KitchenMachine.js":62955,"./LawManager":9525,"./LawManager.js":9525,"./LibraryComputer":85066,"./LibraryComputer.js":85066,"./LibraryManager":9516,"./LibraryManager.js":9516,"./ListInputModal":90447,"./ListInputModal.tsx":90447,"./Loadout":26826,"./Loadout.tsx":26826,"./MODsuit":77613,"./MODsuit.js":77613,"./MagnetController":78624,"./MagnetController.js":78624,"./MechBayConsole":72106,"./MechBayConsole.js":72106,"./MechaControlConsole":7466,"./MechaControlConsole.js":7466,"./MedicalRecords":79625,"./MedicalRecords.js":79625,"./MerchVendor":54989,"./MerchVendor.js":54989,"./MiningVendor":87684,"./MiningVendor.js":87684,"./NTRecruiter":59783,"./NTRecruiter.js":59783,"./Newscaster":64713,"./Newscaster.js":64713,"./Noticeboard":48286,"./Noticeboard.tsx":48286,"./NuclearBomb":41166,"./NuclearBomb.js":41166,"./NumberInputModal":52416,"./NumberInputModal.tsx":52416,"./OperatingComputer":1218,"./OperatingComputer.js":1218,"./Orbit":46892,"./Orbit.js":46892,"./OreRedemption":15421,"./OreRedemption.js":15421,"./PAI":52754,"./PAI.js":52754,"./PDA":85175,"./PDA.js":85175,"./Pacman":68654,"./Pacman.js":68654,"./PanDEMIC":1701,"./PanDEMIC.tsx":1701,"./ParticleAccelerator":67921,"./ParticleAccelerator.js":67921,"./PdaPainter":71432,"./PdaPainter.js":71432,"./PersonalCrafting":33388,"./PersonalCrafting.js":33388,"./Photocopier":56150,"./Photocopier.js":56150,"./PoolController":84676,"./PoolController.js":84676,"./PortablePump":57003,"./PortablePump.js":57003,"./PortableScrubber":70069,"./PortableScrubber.js":70069,"./PortableTurret":59955,"./PortableTurret.js":59955,"./PowerMonitor":61631,"./PowerMonitor.js":61631,"./PrisonerImplantManager":50992,"./PrisonerImplantManager.js":50992,"./PrisonerShuttleConsole":53952,"./PrisonerShuttleConsole.js":53952,"./PrizeCounter":97852,"./PrizeCounter.tsx":97852,"./RCD":94813,"./RCD.js":94813,"./RPD":18738,"./RPD.js":18738,"./Radio":80299,"./Radio.js":80299,"./RankedListInputModal":14846,"./RankedListInputModal.tsx":14846,"./ReagentGrinder":48125,"./ReagentGrinder.js":48125,"./ReagentsEditor":58262,"./ReagentsEditor.tsx":58262,"./RemoteSignaler":30207,"./RemoteSignaler.js":30207,"./RequestConsole":25472,"./RequestConsole.js":25472,"./RndBackupConsole":9861,"./RndBackupConsole.js":9861,"./RndConsole":12644,"./RndConsole/":12644,"./RndConsole/AnalyzerMenu":68303,"./RndConsole/AnalyzerMenu.js":68303,"./RndConsole/DataDiskMenu":37556,"./RndConsole/DataDiskMenu.js":37556,"./RndConsole/LatheCategory":16830,"./RndConsole/LatheCategory.js":16830,"./RndConsole/LatheChemicalStorage":70497,"./RndConsole/LatheChemicalStorage.js":70497,"./RndConsole/LatheMainMenu":70864,"./RndConsole/LatheMainMenu.js":70864,"./RndConsole/LatheMaterialStorage":42878,"./RndConsole/LatheMaterialStorage.js":42878,"./RndConsole/LatheMaterials":52662,"./RndConsole/LatheMaterials.js":52662,"./RndConsole/LatheMenu":9681,"./RndConsole/LatheMenu.js":9681,"./RndConsole/LatheSearch":68198,"./RndConsole/LatheSearch.js":68198,"./RndConsole/LinkMenu":81421,"./RndConsole/LinkMenu.js":81421,"./RndConsole/SettingsMenu":6256,"./RndConsole/SettingsMenu.js":6256,"./RndConsole/index":12644,"./RndConsole/index.js":12644,"./RndNetController":29205,"./RndNetController.js":29205,"./RndServer":63315,"./RndServer.js":63315,"./RobotSelfDiagnosis":26109,"./RobotSelfDiagnosis.js":26109,"./RoboticsControlConsole":97997,"./RoboticsControlConsole.js":97997,"./Safe":54431,"./Safe.js":54431,"./SatelliteControl":29740,"./SatelliteControl.js":29740,"./SecureStorage":44162,"./SecureStorage.js":44162,"./SecurityRecords":6272,"./SecurityRecords.js":6272,"./SeedExtractor":5099,"./SeedExtractor.js":5099,"./ShuttleConsole":2916,"./ShuttleConsole.js":2916,"./ShuttleManipulator":39401,"./ShuttleManipulator.js":39401,"./SingularityMonitor":86013,"./SingularityMonitor.js":86013,"./Sleeper":88284,"./Sleeper.js":88284,"./SlotMachine":21597,"./SlotMachine.js":21597,"./Smartfridge":46348,"./Smartfridge.js":46348,"./Smes":86162,"./Smes.js":86162,"./SolarControl":63584,"./SolarControl.js":63584,"./SpawnersMenu":38096,"./SpawnersMenu.js":38096,"./SpecMenu":30586,"./SpecMenu.js":30586,"./StackCraft":95152,"./StackCraft.js":95152,"./StationAlertConsole":38307,"./StationAlertConsole.js":38307,"./StationTraitsPanel":96091,"./StationTraitsPanel.tsx":96091,"./StripMenu":39409,"./StripMenu.tsx":39409,"./SuitStorage":69514,"./SuitStorage.js":69514,"./SupermatterMonitor":15022,"./SupermatterMonitor.js":15022,"./SyndicateComputerSimple":46029,"./SyndicateComputerSimple.js":46029,"./TEG":36372,"./TEG.js":36372,"./TachyonArray":56441,"./TachyonArray.js":56441,"./Tank":1754,"./Tank.js":1754,"./TankDispenser":7579,"./TankDispenser.js":7579,"./TcommsCore":16136,"./TcommsCore.js":16136,"./TcommsRelay":88046,"./TcommsRelay.js":88046,"./Teleporter":20802,"./Teleporter.js":20802,"./TelescienceConsole":48517,"./TelescienceConsole.js":48517,"./TempGun":21800,"./TempGun.js":21800,"./TextInputModal":24410,"./TextInputModal.tsx":24410,"./ThermoMachine":25036,"./ThermoMachine.js":25036,"./TransferValve":20035,"./TransferValve.js":20035,"./TurbineComputer":78166,"./TurbineComputer.js":78166,"./Uplink":52847,"./Uplink.js":52847,"./Vending":12261,"./Vending.js":12261,"./VolumeMixer":68971,"./VolumeMixer.js":68971,"./VotePanel":2510,"./VotePanel.js":2510,"./Wires":30138,"./Wires.js":30138,"./WizardApprenticeContract":21400,"./WizardApprenticeContract.js":21400,"./common/AccessList":49148,"./common/AccessList.js":49148,"./common/AtmosScan":26991,"./common/AtmosScan.js":26991,"./common/BeakerContents":85870,"./common/BeakerContents.js":85870,"./common/BotStatus":92963,"./common/BotStatus.js":92963,"./common/ComplexModal":3939,"./common/ComplexModal.js":3939,"./common/CrewManifest":41874,"./common/CrewManifest.js":41874,"./common/InputButtons":19203,"./common/InputButtons.tsx":19203,"./common/InterfaceLockNoticeBox":195,"./common/InterfaceLockNoticeBox.js":195,"./common/Loader":51057,"./common/Loader.tsx":51057,"./common/LoginInfo":321,"./common/LoginInfo.js":321,"./common/LoginScreen":5485,"./common/LoginScreen.js":5485,"./common/Operating":62411,"./common/Operating.js":62411,"./common/Signaler":13545,"./common/Signaler.js":13545,"./common/SimpleRecords":41984,"./common/SimpleRecords.js":41984,"./common/TemporaryNotice":22091,"./common/TemporaryNotice.js":22091,"./goonstation_PTL":95213,"./goonstation_PTL/":95213,"./goonstation_PTL/index":95213,"./goonstation_PTL/index.js":95213,"./pai/pai_atmosphere":80818,"./pai/pai_atmosphere.js":80818,"./pai/pai_bioscan":23903,"./pai/pai_bioscan.js":23903,"./pai/pai_directives":64988,"./pai/pai_directives.js":64988,"./pai/pai_doorjack":13813,"./pai/pai_doorjack.js":13813,"./pai/pai_main_menu":66025,"./pai/pai_main_menu.js":66025,"./pai/pai_manifest":2983,"./pai/pai_manifest.js":2983,"./pai/pai_medrecords":40758,"./pai/pai_medrecords.js":40758,"./pai/pai_messenger":98599,"./pai/pai_messenger.js":98599,"./pai/pai_radio":50775,"./pai/pai_radio.js":50775,"./pai/pai_secrecords":48623,"./pai/pai_secrecords.js":48623,"./pai/pai_signaler":47297,"./pai/pai_signaler.js":47297,"./pda/pda_atmos_scan":78532,"./pda/pda_atmos_scan.js":78532,"./pda/pda_games":2395,"./pda/pda_games.js":2395,"./pda/pda_janitor":40253,"./pda/pda_janitor.js":40253,"./pda/pda_main_menu":58293,"./pda/pda_main_menu.js":58293,"./pda/pda_manifest":58059,"./pda/pda_manifest.js":58059,"./pda/pda_medical":18147,"./pda/pda_medical.js":18147,"./pda/pda_messenger":77595,"./pda/pda_messenger.js":77595,"./pda/pda_minesweeper":90382,"./pda/pda_minesweeper.js":90382,"./pda/pda_mule":24635,"./pda/pda_mule.js":24635,"./pda/pda_nanobank":23734,"./pda/pda_nanobank.js":23734,"./pda/pda_notes":97085,"./pda/pda_notes.js":97085,"./pda/pda_power":57513,"./pda/pda_power.js":57513,"./pda/pda_secbot":99808,"./pda/pda_secbot.js":99808,"./pda/pda_security":77168,"./pda/pda_security.js":77168,"./pda/pda_signaler":21773,"./pda/pda_signaler.js":21773,"./pda/pda_status_display":81857,"./pda/pda_status_display.js":81857,"./pda/pda_supplyrecords":70287,"./pda/pda_supplyrecords.js":70287};function a(o){var f=t(o);return n(f)}function t(o){if(!n.o(e,o)){var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}return e[o]}a.keys=function(){return Object.keys(e)},a.resolve=t,T.exports=a,a.id=32054},4085:function(T,r,n){var e={"./Blink.stories.js":51364,"./BlockQuote.stories.js":32453,"./Box.stories.js":83531,"./Button.stories.js":74198,"./ByondUi.stories.js":51956,"./Collapsible.stories.js":17466,"./Flex.stories.js":89241,"./ImageButton.stories.js":48779,"./Input.stories.js":21394,"./Popper.stories.js":43932,"./ProgressBar.stories.js":33270,"./Stack.stories.js":77766,"./Storage.stories.js":30187,"./Tabs.stories.js":46554,"./Themes.stories.js":53276,"./Tooltip.stories.js":28717};function a(o){var f=t(o);return n(f)}function t(o){if(!n.o(e,o)){var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}return e[o]}a.keys=function(){return Object.keys(e)},a.resolve=t,T.exports=a,a.id=4085},10320:function(T,r,n){"use strict";var e=n(55747),a=n(89393),t=TypeError;T.exports=function(o){if(e(o))return o;throw new t(a(o)+" is not a function")}},32606:function(T,r,n){"use strict";var e=n(1031),a=n(89393),t=TypeError;T.exports=function(o){if(e(o))return o;throw new t(a(o)+" is not a constructor")}},35908:function(T,r,n){"use strict";var e=n(45015),a=String,t=TypeError;T.exports=function(o){if(e(o))return o;throw new t("Can't set "+a(o)+" as a prototype")}},80575:function(T,r,n){"use strict";var e=n(24697),a=n(80674),t=n(74595).f,o=e("unscopables"),f=Array.prototype;f[o]===void 0&&t(f,o,{configurable:!0,value:a(null)}),T.exports=function(b){f[o][b]=!0}},35483:function(T,r,n){"use strict";var e=n(50233).charAt;T.exports=function(a,t,o){return t+(o?e(a,t).length:1)}},60077:function(T,r,n){"use strict";var e=n(21287),a=TypeError;T.exports=function(t,o){if(e(o,t))return t;throw new a("Incorrect invocation")}},30365:function(T,r,n){"use strict";var e=n(77568),a=String,t=TypeError;T.exports=function(o){if(e(o))return o;throw new t(a(o)+" is not an object")}},70377:function(T){"use strict";T.exports=typeof ArrayBuffer!="undefined"&&typeof DataView!="undefined"},3782:function(T,r,n){"use strict";var e=n(40033);T.exports=e(function(){if(typeof ArrayBuffer=="function"){var a=new ArrayBuffer(8);Object.isExtensible(a)&&Object.defineProperty(a,"a",{value:8})}})},4246:function(T,r,n){"use strict";var e=n(70377),a=n(58310),t=n(74685),o=n(55747),f=n(77568),b=n(45299),y=n(2281),I=n(89393),k=n(37909),g=n(55938),l=n(73936),c=n(21287),m=n(36917),i=n(76649),u=n(24697),s=n(16738),d=n(5419),v=d.enforce,h=d.get,C=t.Int8Array,p=C&&C.prototype,N=t.Uint8ClampedArray,V=N&&N.prototype,S=C&&m(C),B=p&&m(p),L=Object.prototype,w=t.TypeError,A=u("toStringTag"),x=s("TYPED_ARRAY_TAG"),E="TypedArrayConstructor",P=e&&!!i&&y(t.opera)!=="Opera",D=!1,M,R,O,F={Int8Array:1,Uint8Array:1,Uint8ClampedArray:1,Int16Array:2,Uint16Array:2,Int32Array:4,Uint32Array:4,Float32Array:4,Float64Array:8},_={BigInt64Array:8,BigUint64Array:8},U=function(){function ie(me){if(!f(me))return!1;var q=y(me);return q==="DataView"||b(F,q)||b(_,q)}return ie}(),z=function ie(me){var q=m(me);if(f(q)){var re=h(q);return re&&b(re,E)?re[E]:ie(q)}},$=function(me){if(!f(me))return!1;var q=y(me);return b(F,q)||b(_,q)},G=function(me){if($(me))return me;throw new w("Target is not a typed array")},X=function(me){if(o(me)&&(!i||c(S,me)))return me;throw new w(I(me)+" is not a typed array constructor")},J=function(me,q,re,ae){if(a){if(re)for(var le in F){var Z=t[le];if(Z&&b(Z.prototype,me))try{delete Z.prototype[me]}catch(ne){try{Z.prototype[me]=q}catch(te){}}}(!B[me]||re)&&g(B,me,re?q:P&&p[me]||q,ae)}},se=function(me,q,re){var ae,le;if(a){if(i){if(re){for(ae in F)if(le=t[ae],le&&b(le,me))try{delete le[me]}catch(Z){}}if(!S[me]||re)try{return g(S,me,re?q:P&&S[me]||q)}catch(Z){}else return}for(ae in F)le=t[ae],le&&(!le[me]||re)&&g(le,me,q)}};for(M in F)R=t[M],O=R&&R.prototype,O?v(O)[E]=R:P=!1;for(M in _)R=t[M],O=R&&R.prototype,O&&(v(O)[E]=R);if((!P||!o(S)||S===Function.prototype)&&(S=function(){function ie(){throw new w("Incorrect invocation")}return ie}(),P))for(M in F)t[M]&&i(t[M],S);if((!P||!B||B===L)&&(B=S.prototype,P))for(M in F)t[M]&&i(t[M].prototype,B);if(P&&m(V)!==B&&i(V,B),a&&!b(B,A)){D=!0,l(B,A,{configurable:!0,get:function(){function ie(){return f(this)?this[x]:void 0}return ie}()});for(M in F)t[M]&&k(t[M],x,M)}T.exports={NATIVE_ARRAY_BUFFER_VIEWS:P,TYPED_ARRAY_TAG:D&&x,aTypedArray:G,aTypedArrayConstructor:X,exportTypedArrayMethod:J,exportTypedArrayStaticMethod:se,getTypedArrayConstructor:z,isView:U,isTypedArray:$,TypedArray:S,TypedArrayPrototype:B}},37336:function(T,r,n){"use strict";var e=n(74685),a=n(67250),t=n(58310),o=n(70377),f=n(70520),b=n(37909),y=n(73936),I=n(30145),k=n(40033),g=n(60077),l=n(61365),c=n(10188),m=n(43806),i=n(95867),u=n(91784),s=n(36917),d=n(76649),v=n(88471),h=n(54602),C=n(5781),p=n(5774),N=n(84925),V=n(5419),S=f.PROPER,B=f.CONFIGURABLE,L="ArrayBuffer",w="DataView",A="prototype",x="Wrong length",E="Wrong index",P=V.getterFor(L),D=V.getterFor(w),M=V.set,R=e[L],O=R,F=O&&O[A],_=e[w],U=_&&_[A],z=Object.prototype,$=e.Array,G=e.RangeError,X=a(v),J=a([].reverse),se=u.pack,ie=u.unpack,me=function(Ne){return[Ne&255]},q=function(Ne){return[Ne&255,Ne>>8&255]},re=function(Ne){return[Ne&255,Ne>>8&255,Ne>>16&255,Ne>>24&255]},ae=function(Ne){return Ne[3]<<24|Ne[2]<<16|Ne[1]<<8|Ne[0]},le=function(Ne){return se(i(Ne),23,4)},Z=function(Ne){return se(Ne,52,8)},ne=function(Ne,Be,be){y(Ne[A],Be,{configurable:!0,get:function(){function Le(){return be(this)[Be]}return Le}()})},te=function(Ne,Be,be,Le){var we=D(Ne),xe=m(be),Re=!!Le;if(xe+Be>we.byteLength)throw new G(E);var He=we.bytes,ye=xe+we.byteOffset,de=h(He,ye,ye+Be);return Re?de:J(de)},fe=function(Ne,Be,be,Le,we,xe){var Re=D(Ne),He=m(be),ye=Le(+we),de=!!xe;if(He+Be>Re.byteLength)throw new G(E);for(var he=Re.bytes,ke=He+Re.byteOffset,ve=0;vewe)throw new G("Wrong offset");if(be=be===void 0?we-xe:c(be),xe+be>we)throw new G(x);M(this,{type:w,buffer:Ne,byteLength:be,byteOffset:xe,bytes:Le.bytes}),t||(this.buffer=Ne,this.byteLength=be,this.byteOffset=xe)}return Ce}(),U=_[A],t&&(ne(O,"byteLength",P),ne(_,"buffer",D),ne(_,"byteLength",D),ne(_,"byteOffset",D)),I(U,{getInt8:function(){function Ce(Ne){return te(this,1,Ne)[0]<<24>>24}return Ce}(),getUint8:function(){function Ce(Ne){return te(this,1,Ne)[0]}return Ce}(),getInt16:function(){function Ce(Ne){var Be=te(this,2,Ne,arguments.length>1?arguments[1]:!1);return(Be[1]<<8|Be[0])<<16>>16}return Ce}(),getUint16:function(){function Ce(Ne){var Be=te(this,2,Ne,arguments.length>1?arguments[1]:!1);return Be[1]<<8|Be[0]}return Ce}(),getInt32:function(){function Ce(Ne){return ae(te(this,4,Ne,arguments.length>1?arguments[1]:!1))}return Ce}(),getUint32:function(){function Ce(Ne){return ae(te(this,4,Ne,arguments.length>1?arguments[1]:!1))>>>0}return Ce}(),getFloat32:function(){function Ce(Ne){return ie(te(this,4,Ne,arguments.length>1?arguments[1]:!1),23)}return Ce}(),getFloat64:function(){function Ce(Ne){return ie(te(this,8,Ne,arguments.length>1?arguments[1]:!1),52)}return Ce}(),setInt8:function(){function Ce(Ne,Be){fe(this,1,Ne,me,Be)}return Ce}(),setUint8:function(){function Ce(Ne,Be){fe(this,1,Ne,me,Be)}return Ce}(),setInt16:function(){function Ce(Ne,Be){fe(this,2,Ne,q,Be,arguments.length>2?arguments[2]:!1)}return Ce}(),setUint16:function(){function Ce(Ne,Be){fe(this,2,Ne,q,Be,arguments.length>2?arguments[2]:!1)}return Ce}(),setInt32:function(){function Ce(Ne,Be){fe(this,4,Ne,re,Be,arguments.length>2?arguments[2]:!1)}return Ce}(),setUint32:function(){function Ce(Ne,Be){fe(this,4,Ne,re,Be,arguments.length>2?arguments[2]:!1)}return Ce}(),setFloat32:function(){function Ce(Ne,Be){fe(this,4,Ne,le,Be,arguments.length>2?arguments[2]:!1)}return Ce}(),setFloat64:function(){function Ce(Ne,Be){fe(this,8,Ne,Z,Be,arguments.length>2?arguments[2]:!1)}return Ce}()});else{var pe=S&&R.name!==L;!k(function(){R(1)})||!k(function(){new R(-1)})||k(function(){return new R,new R(1.5),new R(NaN),R.length!==1||pe&&!B})?(O=function(){function Ce(Ne){return g(this,F),C(new R(m(Ne)),this,O)}return Ce}(),O[A]=F,F.constructor=O,p(O,R)):pe&&B&&b(R,"name",L),d&&s(U)!==z&&d(U,z);var ce=new _(new O(2)),Ve=a(U.setInt8);ce.setInt8(0,2147483648),ce.setInt8(1,2147483649),(ce.getInt8(0)||!ce.getInt8(1))&&I(U,{setInt8:function(){function Ce(Ne,Be){Ve(this,Ne,Be<<24>>24)}return Ce}(),setUint8:function(){function Ce(Ne,Be){Ve(this,Ne,Be<<24>>24)}return Ce}()},{unsafe:!0})}N(O,L),N(_,w),T.exports={ArrayBuffer:O,DataView:_}},71447:function(T,r,n){"use strict";var e=n(46771),a=n(13912),t=n(24760),o=n(95108),f=Math.min;T.exports=[].copyWithin||function(){function b(y,I){var k=e(this),g=t(k),l=a(y,g),c=a(I,g),m=arguments.length>2?arguments[2]:void 0,i=f((m===void 0?g:a(m,g))-c,g-l),u=1;for(c0;)c in k?k[l]=k[c]:o(k,l),l+=u,c+=u;return k}return b}()},88471:function(T,r,n){"use strict";var e=n(46771),a=n(13912),t=n(24760);T.exports=function(){function o(f){for(var b=e(this),y=t(b),I=arguments.length,k=a(I>1?arguments[1]:void 0,y),g=I>2?arguments[2]:void 0,l=g===void 0?y:a(g,y);l>k;)b[k++]=f;return b}return o}()},35601:function(T,r,n){"use strict";var e=n(22603).forEach,a=n(55528),t=a("forEach");T.exports=t?[].forEach:function(){function o(f){return e(this,f,arguments.length>1?arguments[1]:void 0)}return o}()},78008:function(T,r,n){"use strict";var e=n(24760);T.exports=function(a,t,o){for(var f=0,b=arguments.length>2?o:e(t),y=new a(b);b>f;)y[f]=t[f++];return y}},73174:function(T,r,n){"use strict";var e=n(75754),a=n(91495),t=n(46771),o=n(40125),f=n(76571),b=n(1031),y=n(24760),I=n(60102),k=n(77455),g=n(59201),l=Array;T.exports=function(){function c(m){var i=t(m),u=b(this),s=arguments.length,d=s>1?arguments[1]:void 0,v=d!==void 0;v&&(d=e(d,s>2?arguments[2]:void 0));var h=g(i),C=0,p,N,V,S,B,L;if(h&&!(this===l&&f(h)))for(N=u?new this:[],S=k(i,h),B=S.next;!(V=a(B,S)).done;C++)L=v?o(S,d,[V.value,C],!0):V.value,I(N,C,L);else for(p=y(i),N=u?new this(p):l(p);p>C;C++)L=v?d(i[C],C):i[C],I(N,C,L);return N.length=C,N}return c}()},14211:function(T,r,n){"use strict";var e=n(57591),a=n(13912),t=n(24760),o=function(b){return function(y,I,k){var g=e(y),l=t(g);if(l===0)return!b&&-1;var c=a(k,l),m;if(b&&I!==I){for(;l>c;)if(m=g[c++],m!==m)return!0}else for(;l>c;c++)if((b||c in g)&&g[c]===I)return b||c||0;return!b&&-1}};T.exports={includes:o(!0),indexOf:o(!1)}},22603:function(T,r,n){"use strict";var e=n(75754),a=n(67250),t=n(37457),o=n(46771),f=n(24760),b=n(57823),y=a([].push),I=function(g){var l=g===1,c=g===2,m=g===3,i=g===4,u=g===6,s=g===7,d=g===5||u;return function(v,h,C,p){for(var N=o(v),V=t(N),S=f(V),B=e(h,C),L=0,w=p||b,A=l?w(v,S):c||s?w(v,0):void 0,x,E;S>L;L++)if((d||L in V)&&(x=V[L],E=B(x,L,N),g))if(l)A[L]=E;else if(E)switch(g){case 3:return!0;case 5:return x;case 6:return L;case 2:y(A,x)}else switch(g){case 4:return!1;case 7:y(A,x)}return u?-1:m||i?i:A}};T.exports={forEach:I(0),map:I(1),filter:I(2),some:I(3),every:I(4),find:I(5),findIndex:I(6),filterReject:I(7)}},1325:function(T,r,n){"use strict";var e=n(61267),a=n(57591),t=n(61365),o=n(24760),f=n(55528),b=Math.min,y=[].lastIndexOf,I=!!y&&1/[1].lastIndexOf(1,-0)<0,k=f("lastIndexOf"),g=I||!k;T.exports=g?function(){function l(c){if(I)return e(y,this,arguments)||0;var m=a(this),i=o(m);if(i===0)return-1;var u=i-1;for(arguments.length>1&&(u=b(u,t(arguments[1]))),u<0&&(u=i+u);u>=0;u--)if(u in m&&m[u]===c)return u||0;return-1}return l}():y},44091:function(T,r,n){"use strict";var e=n(40033),a=n(24697),t=n(5026),o=a("species");T.exports=function(f){return t>=51||!e(function(){var b=[],y=b.constructor={};return y[o]=function(){return{foo:1}},b[f](Boolean).foo!==1})}},55528:function(T,r,n){"use strict";var e=n(40033);T.exports=function(a,t){var o=[][a];return!!o&&e(function(){o.call(null,t||function(){return 1},1)})}},56844:function(T,r,n){"use strict";var e=n(10320),a=n(46771),t=n(37457),o=n(24760),f=TypeError,b="Reduce of empty array with no initial value",y=function(k){return function(g,l,c,m){var i=a(g),u=t(i),s=o(i);if(e(l),s===0&&c<2)throw new f(b);var d=k?s-1:0,v=k?-1:1;if(c<2)for(;;){if(d in u){m=u[d],d+=v;break}if(d+=v,k?d<0:s<=d)throw new f(b)}for(;k?d>=0:s>d;d+=v)d in u&&(m=l(m,u[d],d,i));return m}};T.exports={left:y(!1),right:y(!0)}},13345:function(T,r,n){"use strict";var e=n(58310),a=n(37386),t=TypeError,o=Object.getOwnPropertyDescriptor,f=e&&!function(){if(this!==void 0)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(b){return b instanceof TypeError}}();T.exports=f?function(b,y){if(a(b)&&!o(b,"length").writable)throw new t("Cannot set read only .length");return b.length=y}:function(b,y){return b.length=y}},54602:function(T,r,n){"use strict";var e=n(67250);T.exports=e([].slice)},90274:function(T,r,n){"use strict";var e=n(54602),a=Math.floor,t=function o(f,b){var y=f.length;if(y<8)for(var I=1,k,g;I0;)f[g]=f[--g];g!==I++&&(f[g]=k)}else for(var l=a(y/2),c=o(e(f,0,l),b),m=o(e(f,l),b),i=c.length,u=m.length,s=0,d=0;s1?arguments[1]:void 0),E;E=E?E.next:A.first;)for(x(E.value,E.key,this);E&&E.removed;)E=E.previous}return L}(),has:function(){function L(w){return!!B(this,w)}return L}()}),t(N,h?{get:function(){function L(w){var A=B(this,w);return A&&A.value}return L}(),set:function(){function L(w,A){return S(this,w===0?0:w,A)}return L}()}:{add:function(){function L(w){return S(this,w=w===0?0:w,w)}return L}()}),l&&a(N,"size",{configurable:!0,get:function(){function L(){return V(this).size}return L}()}),p}return s}(),setStrong:function(){function s(d,v,h){var C=v+" Iterator",p=u(v),N=u(C);I(d,v,function(V,S){i(this,{type:C,target:V,state:p(V),kind:S,last:void 0})},function(){for(var V=N(this),S=V.kind,B=V.last;B&&B.removed;)B=B.previous;return!V.target||!(V.last=B=B?B.next:V.state.first)?(V.target=void 0,k(void 0,!0)):k(S==="keys"?B.key:S==="values"?B.value:[B.key,B.value],!1)},h?"entries":"values",!h,!0),g(v)}return s}()}},39895:function(T,r,n){"use strict";var e=n(67250),a=n(30145),t=n(81969).getWeakData,o=n(60077),f=n(30365),b=n(42871),y=n(77568),I=n(49450),k=n(22603),g=n(45299),l=n(5419),c=l.set,m=l.getterFor,i=k.find,u=k.findIndex,s=e([].splice),d=0,v=function(N){return N.frozen||(N.frozen=new h)},h=function(){this.entries=[]},C=function(N,V){return i(N.entries,function(S){return S[0]===V})};h.prototype={get:function(){function p(N){var V=C(this,N);if(V)return V[1]}return p}(),has:function(){function p(N){return!!C(this,N)}return p}(),set:function(){function p(N,V){var S=C(this,N);S?S[1]=V:this.entries.push([N,V])}return p}(),delete:function(){function p(N){var V=u(this.entries,function(S){return S[0]===N});return~V&&s(this.entries,V,1),!!~V}return p}()},T.exports={getConstructor:function(){function p(N,V,S,B){var L=N(function(E,P){o(E,w),c(E,{type:V,id:d++,frozen:void 0}),b(P)||I(P,E[B],{that:E,AS_ENTRIES:S})}),w=L.prototype,A=m(V),x=function(){function E(P,D,M){var R=A(P),O=t(f(D),!0);return O===!0?v(R).set(D,M):O[R.id]=M,P}return E}();return a(w,{delete:function(){function E(P){var D=A(this);if(!y(P))return!1;var M=t(P);return M===!0?v(D).delete(P):M&&g(M,D.id)&&delete M[D.id]}return E}(),has:function(){function E(P){var D=A(this);if(!y(P))return!1;var M=t(P);return M===!0?v(D).has(P):M&&g(M,D.id)}return E}()}),a(w,S?{get:function(){function E(P){var D=A(this);if(y(P)){var M=t(P);return M===!0?v(D).get(P):M?M[D.id]:void 0}}return E}(),set:function(){function E(P,D){return x(this,P,D)}return E}()}:{add:function(){function E(P){return x(this,P,!0)}return E}()}),L}return p}()}},45150:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(67250),o=n(41314),f=n(55938),b=n(81969),y=n(49450),I=n(60077),k=n(55747),g=n(42871),l=n(77568),c=n(40033),m=n(92490),i=n(84925),u=n(5781);T.exports=function(s,d,v){var h=s.indexOf("Map")!==-1,C=s.indexOf("Weak")!==-1,p=h?"set":"add",N=a[s],V=N&&N.prototype,S=N,B={},L=function(R){var O=t(V[R]);f(V,R,R==="add"?function(){function F(_){return O(this,_===0?0:_),this}return F}():R==="delete"?function(F){return C&&!l(F)?!1:O(this,F===0?0:F)}:R==="get"?function(){function F(_){return C&&!l(_)?void 0:O(this,_===0?0:_)}return F}():R==="has"?function(){function F(_){return C&&!l(_)?!1:O(this,_===0?0:_)}return F}():function(){function F(_,U){return O(this,_===0?0:_,U),this}return F}())},w=o(s,!k(N)||!(C||V.forEach&&!c(function(){new N().entries().next()})));if(w)S=v.getConstructor(d,s,h,p),b.enable();else if(o(s,!0)){var A=new S,x=A[p](C?{}:-0,1)!==A,E=c(function(){A.has(1)}),P=m(function(M){new N(M)}),D=!C&&c(function(){for(var M=new N,R=5;R--;)M[p](R,R);return!M.has(-0)});P||(S=d(function(M,R){I(M,V);var O=u(new N,M,S);return g(R)||y(R,O[p],{that:O,AS_ENTRIES:h}),O}),S.prototype=V,V.constructor=S),(E||D)&&(L("delete"),L("has"),h&&L("get")),(D||x)&&L(p),C&&V.clear&&delete V.clear}return B[s]=S,e({global:!0,constructor:!0,forced:S!==N},B),i(S,s),C||v.setStrong(S,s,h),S}},5774:function(T,r,n){"use strict";var e=n(45299),a=n(97921),t=n(27193),o=n(74595);T.exports=function(f,b,y){for(var I=a(b),k=o.f,g=t.f,l=0;l"+g+""}},5959:function(T){"use strict";T.exports=function(r,n){return{value:r,done:n}}},37909:function(T,r,n){"use strict";var e=n(58310),a=n(74595),t=n(87458);T.exports=e?function(o,f,b){return a.f(o,f,t(1,b))}:function(o,f,b){return o[f]=b,o}},87458:function(T){"use strict";T.exports=function(r,n){return{enumerable:!(r&1),configurable:!(r&2),writable:!(r&4),value:n}}},60102:function(T,r,n){"use strict";var e=n(58310),a=n(74595),t=n(87458);T.exports=function(o,f,b){e?a.f(o,f,t(0,b)):o[f]=b}},67206:function(T,r,n){"use strict";var e=n(67250),a=n(40033),t=n(24051).start,o=RangeError,f=isFinite,b=Math.abs,y=Date.prototype,I=y.toISOString,k=e(y.getTime),g=e(y.getUTCDate),l=e(y.getUTCFullYear),c=e(y.getUTCHours),m=e(y.getUTCMilliseconds),i=e(y.getUTCMinutes),u=e(y.getUTCMonth),s=e(y.getUTCSeconds);T.exports=a(function(){return I.call(new Date(-50000000000001))!=="0385-07-25T07:06:39.999Z"})||!a(function(){I.call(new Date(NaN))})?function(){function d(){if(!f(k(this)))throw new o("Invalid time value");var v=this,h=l(v),C=m(v),p=h<0?"-":h>9999?"+":"";return p+t(b(h),p?6:4,0)+"-"+t(u(v)+1,2,0)+"-"+t(g(v),2,0)+"T"+t(c(v),2,0)+":"+t(i(v),2,0)+":"+t(s(v),2,0)+"."+t(C,3,0)+"Z"}return d}():I},10886:function(T,r,n){"use strict";var e=n(30365),a=n(13396),t=TypeError;T.exports=function(o){if(e(this),o==="string"||o==="default")o="string";else if(o!=="number")throw new t("Incorrect hint");return a(this,o)}},73936:function(T,r,n){"use strict";var e=n(20001),a=n(74595);T.exports=function(t,o,f){return f.get&&e(f.get,o,{getter:!0}),f.set&&e(f.set,o,{setter:!0}),a.f(t,o,f)}},55938:function(T,r,n){"use strict";var e=n(55747),a=n(74595),t=n(20001),o=n(18231);T.exports=function(f,b,y,I){I||(I={});var k=I.enumerable,g=I.name!==void 0?I.name:b;if(e(y)&&t(y,g,I),I.global)k?f[b]=y:o(b,y);else{try{I.unsafe?f[b]&&(k=!0):delete f[b]}catch(l){}k?f[b]=y:a.f(f,b,{value:y,enumerable:!1,configurable:!I.nonConfigurable,writable:!I.nonWritable})}return f}},30145:function(T,r,n){"use strict";var e=n(55938);T.exports=function(a,t,o){for(var f in t)e(a,f,t[f],o);return a}},18231:function(T,r,n){"use strict";var e=n(74685),a=Object.defineProperty;T.exports=function(t,o){try{a(e,t,{value:o,configurable:!0,writable:!0})}catch(f){e[t]=o}return o}},95108:function(T,r,n){"use strict";var e=n(89393),a=TypeError;T.exports=function(t,o){if(!delete t[o])throw new a("Cannot delete property "+e(o)+" of "+e(t))}},58310:function(T,r,n){"use strict";var e=n(40033);T.exports=!e(function(){return Object.defineProperty({},1,{get:function(){function a(){return 7}return a}()})[1]!==7})},12689:function(T,r,n){"use strict";var e=n(74685),a=n(77568),t=e.document,o=a(t)&&a(t.createElement);T.exports=function(f){return o?t.createElement(f):{}}},21291:function(T){"use strict";var r=TypeError,n=9007199254740991;T.exports=function(e){if(e>n)throw r("Maximum allowed index exceeded");return e}},652:function(T,r,n){"use strict";var e=n(63318),a=e.match(/firefox\/(\d+)/i);T.exports=!!a&&+a[1]},8180:function(T,r,n){"use strict";var e=n(73730),a=n(81702);T.exports=!e&&!a&&typeof window=="object"&&typeof document=="object"},49197:function(T){"use strict";T.exports=typeof Bun=="function"&&Bun&&typeof Bun.version=="string"},73730:function(T){"use strict";T.exports=typeof Deno=="object"&&Deno&&typeof Deno.version=="object"},19228:function(T,r,n){"use strict";var e=n(63318);T.exports=/MSIE|Trident/.test(e)},51802:function(T,r,n){"use strict";var e=n(63318);T.exports=/ipad|iphone|ipod/i.test(e)&&typeof Pebble!="undefined"},83433:function(T,r,n){"use strict";var e=n(63318);T.exports=/(?:ipad|iphone|ipod).*applewebkit/i.test(e)},81702:function(T,r,n){"use strict";var e=n(74685),a=n(7462);T.exports=a(e.process)==="process"},63383:function(T,r,n){"use strict";var e=n(63318);T.exports=/web0s(?!.*chrome)/i.test(e)},63318:function(T){"use strict";T.exports=typeof navigator!="undefined"&&String(navigator.userAgent)||""},5026:function(T,r,n){"use strict";var e=n(74685),a=n(63318),t=e.process,o=e.Deno,f=t&&t.versions||o&&o.version,b=f&&f.v8,y,I;b&&(y=b.split("."),I=y[0]>0&&y[0]<4?1:+(y[0]+y[1])),!I&&a&&(y=a.match(/Edge\/(\d+)/),(!y||y[1]>=74)&&(y=a.match(/Chrome\/(\d+)/),y&&(I=+y[1]))),T.exports=I},9342:function(T,r,n){"use strict";var e=n(63318),a=e.match(/AppleWebKit\/(\d+)\./);T.exports=!!a&&+a[1]},89453:function(T){"use strict";T.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},63964:function(T,r,n){"use strict";var e=n(74685),a=n(27193).f,t=n(37909),o=n(55938),f=n(18231),b=n(5774),y=n(41314);T.exports=function(I,k){var g=I.target,l=I.global,c=I.stat,m,i,u,s,d,v;if(l?i=e:c?i=e[g]||f(g,{}):i=e[g]&&e[g].prototype,i)for(u in k){if(d=k[u],I.dontCallGetSet?(v=a(i,u),s=v&&v.value):s=i[u],m=y(l?u:g+(c?".":"#")+u,I.forced),!m&&s!==void 0){if(typeof d==typeof s)continue;b(d,s)}(I.sham||s&&s.sham)&&t(d,"sham",!0),o(i,u,d,I)}}},40033:function(T){"use strict";T.exports=function(r){try{return!!r()}catch(n){return!0}}},79942:function(T,r,n){"use strict";n(79669);var e=n(91495),a=n(55938),t=n(14489),o=n(40033),f=n(24697),b=n(37909),y=f("species"),I=RegExp.prototype;T.exports=function(k,g,l,c){var m=f(k),i=!o(function(){var v={};return v[m]=function(){return 7},""[k](v)!==7}),u=i&&!o(function(){var v=!1,h=/a/;return k==="split"&&(h={},h.constructor={},h.constructor[y]=function(){return h},h.flags="",h[m]=/./[m]),h.exec=function(){return v=!0,null},h[m](""),!v});if(!i||!u||l){var s=/./[m],d=g(m,""[k],function(v,h,C,p,N){var V=h.exec;return V===t||V===I.exec?i&&!N?{done:!0,value:e(s,h,C,p)}:{done:!0,value:e(v,C,h,p)}:{done:!1}});a(String.prototype,k,d[0]),a(I,m,d[1])}c&&b(I[m],"sham",!0)}},65561:function(T,r,n){"use strict";var e=n(37386),a=n(24760),t=n(21291),o=n(75754),f=function b(y,I,k,g,l,c,m,i){for(var u=l,s=0,d=m?o(m,i):!1,v,h;s0&&e(v)?(h=a(v),u=b(y,I,v,h,u,c-1)-1):(t(u+1),y[u]=v),u++),s++;return u};T.exports=f},50730:function(T,r,n){"use strict";var e=n(40033);T.exports=!e(function(){return Object.isExtensible(Object.preventExtensions({}))})},61267:function(T,r,n){"use strict";var e=n(55050),a=Function.prototype,t=a.apply,o=a.call;T.exports=typeof Reflect=="object"&&Reflect.apply||(e?o.bind(t):function(){return o.apply(t,arguments)})},75754:function(T,r,n){"use strict";var e=n(71138),a=n(10320),t=n(55050),o=e(e.bind);T.exports=function(f,b){return a(f),b===void 0?f:t?o(f,b):function(){return f.apply(b,arguments)}}},55050:function(T,r,n){"use strict";var e=n(40033);T.exports=!e(function(){var a=function(){}.bind();return typeof a!="function"||a.hasOwnProperty("prototype")})},66284:function(T,r,n){"use strict";var e=n(67250),a=n(10320),t=n(77568),o=n(45299),f=n(54602),b=n(55050),y=Function,I=e([].concat),k=e([].join),g={},l=function(m,i,u){if(!o(g,i)){for(var s=[],d=0;d]*>)/g,I=/\$([$&'`]|\d{1,2})/g;T.exports=function(k,g,l,c,m,i){var u=l+k.length,s=c.length,d=I;return m!==void 0&&(m=a(m),d=y),f(i,d,function(v,h){var C;switch(o(h,0)){case"$":return"$";case"&":return k;case"`":return b(g,0,l);case"'":return b(g,u);case"<":C=m[b(h,1,-1)];break;default:var p=+h;if(p===0)return v;if(p>s){var N=t(p/10);return N===0?v:N<=s?c[N-1]===void 0?o(h,1):c[N-1]+o(h,1):v}C=c[p-1]}return C===void 0?"":C})}},74685:function(T,r,n){"use strict";var e=function(t){return t&&t.Math===Math&&t};T.exports=e(typeof globalThis=="object"&&globalThis)||e(typeof window=="object"&&window)||e(typeof self=="object"&&self)||e(typeof n.g=="object"&&n.g)||e(!1)||function(){return this}()||Function("return this")()},45299:function(T,r,n){"use strict";var e=n(67250),a=n(46771),t=e({}.hasOwnProperty);T.exports=Object.hasOwn||function(){function o(f,b){return t(a(f),b)}return o}()},79195:function(T){"use strict";T.exports={}},72259:function(T){"use strict";T.exports=function(r,n){try{arguments.length}catch(e){}}},5315:function(T,r,n){"use strict";var e=n(4009);T.exports=e("document","documentElement")},36223:function(T,r,n){"use strict";var e=n(58310),a=n(40033),t=n(12689);T.exports=!e&&!a(function(){return Object.defineProperty(t("div"),"a",{get:function(){function o(){return 7}return o}()}).a!==7})},91784:function(T){"use strict";var r=Array,n=Math.abs,e=Math.pow,a=Math.floor,t=Math.log,o=Math.LN2,f=function(I,k,g){var l=r(g),c=g*8-k-1,m=(1<>1,u=k===23?e(2,-24)-e(2,-77):0,s=I<0||I===0&&1/I<0?1:0,d=0,v,h,C;for(I=n(I),I!==I||I===1/0?(h=I!==I?1:0,v=m):(v=a(t(I)/o),C=e(2,-v),I*C<1&&(v--,C*=2),v+i>=1?I+=u/C:I+=u*e(2,1-i),I*C>=2&&(v++,C/=2),v+i>=m?(h=0,v=m):v+i>=1?(h=(I*C-1)*e(2,k),v+=i):(h=I*e(2,i-1)*e(2,k),v=0));k>=8;)l[d++]=h&255,h/=256,k-=8;for(v=v<0;)l[d++]=v&255,v/=256,c-=8;return l[--d]|=s*128,l},b=function(I,k){var g=I.length,l=g*8-k-1,c=(1<>1,i=l-7,u=g-1,s=I[u--],d=s&127,v;for(s>>=7;i>0;)d=d*256+I[u--],i-=8;for(v=d&(1<<-i)-1,d>>=-i,i+=k;i>0;)v=v*256+I[u--],i-=8;if(d===0)d=1-m;else{if(d===c)return v?NaN:s?-1/0:1/0;v+=e(2,k),d-=m}return(s?-1:1)*v*e(2,d-k)};T.exports={pack:f,unpack:b}},37457:function(T,r,n){"use strict";var e=n(67250),a=n(40033),t=n(7462),o=Object,f=e("".split);T.exports=a(function(){return!o("z").propertyIsEnumerable(0)})?function(b){return t(b)==="String"?f(b,""):o(b)}:o},5781:function(T,r,n){"use strict";var e=n(55747),a=n(77568),t=n(76649);T.exports=function(o,f,b){var y,I;return t&&e(y=f.constructor)&&y!==b&&a(I=y.prototype)&&I!==b.prototype&&t(o,I),o}},40492:function(T,r,n){"use strict";var e=n(67250),a=n(55747),t=n(40095),o=e(Function.toString);a(t.inspectSource)||(t.inspectSource=function(f){return o(f)}),T.exports=t.inspectSource},81969:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(79195),o=n(77568),f=n(45299),b=n(74595).f,y=n(37310),I=n(81644),k=n(81834),g=n(16738),l=n(50730),c=!1,m=g("meta"),i=0,u=function(N){b(N,m,{value:{objectID:"O"+i++,weakData:{}}})},s=function(N,V){if(!o(N))return typeof N=="symbol"?N:(typeof N=="string"?"S":"P")+N;if(!f(N,m)){if(!k(N))return"F";if(!V)return"E";u(N)}return N[m].objectID},d=function(N,V){if(!f(N,m)){if(!k(N))return!0;if(!V)return!1;u(N)}return N[m].weakData},v=function(N){return l&&c&&k(N)&&!f(N,m)&&u(N),N},h=function(){C.enable=function(){},c=!0;var N=y.f,V=a([].splice),S={};S[m]=1,N(S).length&&(y.f=function(B){for(var L=N(B),w=0,A=L.length;wB;B++)if(w=P(i[B]),w&&y(m,w))return w;return new c(!1)}V=I(i,S)}for(A=h?i.next:V.next;!(x=a(A,V)).done;){try{w=P(x.value)}catch(D){g(V,"throw",D)}if(typeof w=="object"&&w&&y(m,w))return w}return new c(!1)}},28649:function(T,r,n){"use strict";var e=n(91495),a=n(30365),t=n(78060);T.exports=function(o,f,b){var y,I;a(o);try{if(y=t(o,"return"),!y){if(f==="throw")throw b;return b}y=e(y,o)}catch(k){I=!0,y=k}if(f==="throw")throw b;if(I)throw y;return a(y),b}},5656:function(T,r,n){"use strict";var e=n(67635).IteratorPrototype,a=n(80674),t=n(87458),o=n(84925),f=n(83967),b=function(){return this};T.exports=function(y,I,k,g){var l=I+" Iterator";return y.prototype=a(e,{next:t(+!g,k)}),o(y,l,!1,!0),f[l]=b,y}},65574:function(T,r,n){"use strict";var e=n(63964),a=n(91495),t=n(4493),o=n(70520),f=n(55747),b=n(5656),y=n(36917),I=n(76649),k=n(84925),g=n(37909),l=n(55938),c=n(24697),m=n(83967),i=n(67635),u=o.PROPER,s=o.CONFIGURABLE,d=i.IteratorPrototype,v=i.BUGGY_SAFARI_ITERATORS,h=c("iterator"),C="keys",p="values",N="entries",V=function(){return this};T.exports=function(S,B,L,w,A,x,E){b(L,B,w);var P=function(X){if(X===A&&F)return F;if(!v&&X&&X in R)return R[X];switch(X){case C:return function(){function J(){return new L(this,X)}return J}();case p:return function(){function J(){return new L(this,X)}return J}();case N:return function(){function J(){return new L(this,X)}return J}()}return function(){return new L(this)}},D=B+" Iterator",M=!1,R=S.prototype,O=R[h]||R["@@iterator"]||A&&R[A],F=!v&&O||P(A),_=B==="Array"&&R.entries||O,U,z,$;if(_&&(U=y(_.call(new S)),U!==Object.prototype&&U.next&&(!t&&y(U)!==d&&(I?I(U,d):f(U[h])||l(U,h,V)),k(U,D,!0,!0),t&&(m[D]=V))),u&&A===p&&O&&O.name!==p&&(!t&&s?g(R,"name",p):(M=!0,F=function(){function G(){return a(O,this)}return G}())),A)if(z={values:P(p),keys:x?F:P(C),entries:P(N)},E)for($ in z)(v||M||!($ in R))&&l(R,$,z[$]);else e({target:B,proto:!0,forced:v||M},z);return(!t||E)&&R[h]!==F&&l(R,h,F,{name:A}),m[B]=F,z}},67635:function(T,r,n){"use strict";var e=n(40033),a=n(55747),t=n(77568),o=n(80674),f=n(36917),b=n(55938),y=n(24697),I=n(4493),k=y("iterator"),g=!1,l,c,m;[].keys&&(m=[].keys(),"next"in m?(c=f(f(m)),c!==Object.prototype&&(l=c)):g=!0);var i=!t(l)||e(function(){var u={};return l[k].call(u)!==u});i?l={}:I&&(l=o(l)),a(l[k])||b(l,k,function(){return this}),T.exports={IteratorPrototype:l,BUGGY_SAFARI_ITERATORS:g}},83967:function(T){"use strict";T.exports={}},24760:function(T,r,n){"use strict";var e=n(10188);T.exports=function(a){return e(a.length)}},20001:function(T,r,n){"use strict";var e=n(67250),a=n(40033),t=n(55747),o=n(45299),f=n(58310),b=n(70520).CONFIGURABLE,y=n(40492),I=n(5419),k=I.enforce,g=I.get,l=String,c=Object.defineProperty,m=e("".slice),i=e("".replace),u=e([].join),s=f&&!a(function(){return c(function(){},"length",{value:8}).length!==8}),d=String(String).split("String"),v=T.exports=function(h,C,p){m(l(C),0,7)==="Symbol("&&(C="["+i(l(C),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),p&&p.getter&&(C="get "+C),p&&p.setter&&(C="set "+C),(!o(h,"name")||b&&h.name!==C)&&(f?c(h,"name",{value:C,configurable:!0}):h.name=C),s&&p&&o(p,"arity")&&h.length!==p.arity&&c(h,"length",{value:p.arity});try{p&&o(p,"constructor")&&p.constructor?f&&c(h,"prototype",{writable:!1}):h.prototype&&(h.prototype=void 0)}catch(V){}var N=k(h);return o(N,"source")||(N.source=u(d,typeof C=="string"?C:"")),h};Function.prototype.toString=v(function(){function h(){return t(this)&&g(this).source||y(this)}return h}(),"toString")},82040:function(T){"use strict";var r=Math.expm1,n=Math.exp;T.exports=!r||r(10)>22025.465794806718||r(10)<22025.465794806718||r(-2e-17)!==-2e-17?function(){function e(a){var t=+a;return t===0?t:t>-1e-6&&t<1e-6?t+t*t/2:n(t)-1}return e}():r},14950:function(T,r,n){"use strict";var e=n(22172),a=Math.abs,t=2220446049250313e-31,o=1/t,f=function(y){return y+o-o};T.exports=function(b,y,I,k){var g=+b,l=a(g),c=e(g);if(lI||i!==i?c*(1/0):c*i}},95867:function(T,r,n){"use strict";var e=n(14950),a=11920928955078125e-23,t=34028234663852886e22,o=11754943508222875e-54;T.exports=Math.fround||function(){function f(b){return e(b,a,t,o)}return f}()},75002:function(T){"use strict";var r=Math.log,n=Math.LOG10E;T.exports=Math.log10||function(){function e(a){return r(a)*n}return e}()},90874:function(T){"use strict";var r=Math.log;T.exports=Math.log1p||function(){function n(e){var a=+e;return a>-1e-8&&a<1e-8?a-a*a/2:r(1+a)}return n}()},22172:function(T){"use strict";T.exports=Math.sign||function(){function r(n){var e=+n;return e===0||e!==e?e:e<0?-1:1}return r}()},21119:function(T){"use strict";var r=Math.ceil,n=Math.floor;T.exports=Math.trunc||function(){function e(a){var t=+a;return(t>0?n:r)(t)}return e}()},37713:function(T,r,n){"use strict";var e=n(74685),a=n(44915),t=n(75754),o=n(60375).set,f=n(9547),b=n(83433),y=n(51802),I=n(63383),k=n(81702),g=e.MutationObserver||e.WebKitMutationObserver,l=e.document,c=e.process,m=e.Promise,i=a("queueMicrotask"),u,s,d,v,h;if(!i){var C=new f,p=function(){var V,S;for(k&&(V=c.domain)&&V.exit();S=C.get();)try{S()}catch(B){throw C.head&&u(),B}V&&V.enter()};!b&&!k&&!I&&g&&l?(s=!0,d=l.createTextNode(""),new g(p).observe(d,{characterData:!0}),u=function(){d.data=s=!s}):!y&&m&&m.resolve?(v=m.resolve(void 0),v.constructor=m,h=t(v.then,v),u=function(){h(p)}):k?u=function(){c.nextTick(p)}:(o=t(o,e),u=function(){o(p)}),i=function(V){C.head||u(),C.add(V)}}T.exports=i},81837:function(T,r,n){"use strict";var e=n(10320),a=TypeError,t=function(f){var b,y;this.promise=new f(function(I,k){if(b!==void 0||y!==void 0)throw new a("Bad Promise constructor");b=I,y=k}),this.resolve=e(b),this.reject=e(y)};T.exports.f=function(o){return new t(o)}},86213:function(T,r,n){"use strict";var e=n(72586),a=TypeError;T.exports=function(t){if(e(t))throw new a("The method doesn't accept regular expressions");return t}},3294:function(T,r,n){"use strict";var e=n(74685),a=e.isFinite;T.exports=Number.isFinite||function(){function t(o){return typeof o=="number"&&a(o)}return t}()},28506:function(T,r,n){"use strict";var e=n(74685),a=n(40033),t=n(67250),o=n(12605),f=n(92648).trim,b=n(4198),y=t("".charAt),I=e.parseFloat,k=e.Symbol,g=k&&k.iterator,l=1/I(b+"-0")!==-1/0||g&&!a(function(){I(Object(g))});T.exports=l?function(){function c(m){var i=f(o(m)),u=I(i);return u===0&&y(i,0)==="-"?-0:u}return c}():I},13693:function(T,r,n){"use strict";var e=n(74685),a=n(40033),t=n(67250),o=n(12605),f=n(92648).trim,b=n(4198),y=e.parseInt,I=e.Symbol,k=I&&I.iterator,g=/^[+-]?0x/i,l=t(g.exec),c=y(b+"08")!==8||y(b+"0x16")!==22||k&&!a(function(){y(Object(k))});T.exports=c?function(){function m(i,u){var s=f(o(i));return y(s,u>>>0||(l(g,s)?16:10))}return m}():y},41143:function(T,r,n){"use strict";var e=n(58310),a=n(67250),t=n(91495),o=n(40033),f=n(18450),b=n(89235),y=n(12867),I=n(46771),k=n(37457),g=Object.assign,l=Object.defineProperty,c=a([].concat);T.exports=!g||o(function(){if(e&&g({b:1},g(l({},"a",{enumerable:!0,get:function(){function d(){l(this,"b",{value:3,enumerable:!1})}return d}()}),{b:2})).b!==1)return!0;var m={},i={},u=Symbol("assign detection"),s="abcdefghijklmnopqrst";return m[u]=7,s.split("").forEach(function(d){i[d]=d}),g({},m)[u]!==7||f(g({},i)).join("")!==s})?function(){function m(i,u){for(var s=I(i),d=arguments.length,v=1,h=b.f,C=y.f;d>v;)for(var p=k(arguments[v++]),N=h?c(f(p),h(p)):f(p),V=N.length,S=0,B;V>S;)B=N[S++],(!e||t(C,p,B))&&(s[B]=p[B]);return s}return m}():g},80674:function(T,r,n){"use strict";var e=n(30365),a=n(24239),t=n(89453),o=n(79195),f=n(5315),b=n(12689),y=n(19417),I=">",k="<",g="prototype",l="script",c=y("IE_PROTO"),m=function(){},i=function(C){return k+l+I+C+k+"/"+l+I},u=function(C){C.write(i("")),C.close();var p=C.parentWindow.Object;return C=null,p},s=function(){var C=b("iframe"),p="java"+l+":",N;return C.style.display="none",f.appendChild(C),C.src=String(p),N=C.contentWindow.document,N.open(),N.write(i("document.F=Object")),N.close(),N.F},d,v=function(){try{d=new ActiveXObject("htmlfile")}catch(p){}v=typeof document!="undefined"?document.domain&&d?u(d):s():u(d);for(var C=t.length;C--;)delete v[g][t[C]];return v()};o[c]=!0,T.exports=Object.create||function(){function h(C,p){var N;return C!==null?(m[g]=e(C),N=new m,m[g]=null,N[c]=C):N=v(),p===void 0?N:a.f(N,p)}return h}()},24239:function(T,r,n){"use strict";var e=n(58310),a=n(80944),t=n(74595),o=n(30365),f=n(57591),b=n(18450);r.f=e&&!a?Object.defineProperties:function(){function y(I,k){o(I);for(var g=f(k),l=b(k),c=l.length,m=0,i;c>m;)t.f(I,i=l[m++],g[i]);return I}return y}()},74595:function(T,r,n){"use strict";var e=n(58310),a=n(36223),t=n(80944),o=n(30365),f=n(767),b=TypeError,y=Object.defineProperty,I=Object.getOwnPropertyDescriptor,k="enumerable",g="configurable",l="writable";r.f=e?t?function(){function c(m,i,u){if(o(m),i=f(i),o(u),typeof m=="function"&&i==="prototype"&&"value"in u&&l in u&&!u[l]){var s=I(m,i);s&&s[l]&&(m[i]=u.value,u={configurable:g in u?u[g]:s[g],enumerable:k in u?u[k]:s[k],writable:!1})}return y(m,i,u)}return c}():y:function(){function c(m,i,u){if(o(m),i=f(i),o(u),a)try{return y(m,i,u)}catch(s){}if("get"in u||"set"in u)throw new b("Accessors not supported");return"value"in u&&(m[i]=u.value),m}return c}()},27193:function(T,r,n){"use strict";var e=n(58310),a=n(91495),t=n(12867),o=n(87458),f=n(57591),b=n(767),y=n(45299),I=n(36223),k=Object.getOwnPropertyDescriptor;r.f=e?k:function(){function g(l,c){if(l=f(l),c=b(c),I)try{return k(l,c)}catch(m){}if(y(l,c))return o(!a(t.f,l,c),l[c])}return g}()},81644:function(T,r,n){"use strict";var e=n(7462),a=n(57591),t=n(37310).f,o=n(54602),f=typeof window=="object"&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],b=function(I){try{return t(I)}catch(k){return o(f)}};T.exports.f=function(){function y(I){return f&&e(I)==="Window"?b(I):t(a(I))}return y}()},37310:function(T,r,n){"use strict";var e=n(53726),a=n(89453),t=a.concat("length","prototype");r.f=Object.getOwnPropertyNames||function(){function o(f){return e(f,t)}return o}()},89235:function(T,r){"use strict";r.f=Object.getOwnPropertySymbols},36917:function(T,r,n){"use strict";var e=n(45299),a=n(55747),t=n(46771),o=n(19417),f=n(9225),b=o("IE_PROTO"),y=Object,I=y.prototype;T.exports=f?y.getPrototypeOf:function(k){var g=t(k);if(e(g,b))return g[b];var l=g.constructor;return a(l)&&g instanceof l?l.prototype:g instanceof y?I:null}},81834:function(T,r,n){"use strict";var e=n(40033),a=n(77568),t=n(7462),o=n(3782),f=Object.isExtensible,b=e(function(){f(1)});T.exports=b||o?function(){function y(I){return!a(I)||o&&t(I)==="ArrayBuffer"?!1:f?f(I):!0}return y}():f},21287:function(T,r,n){"use strict";var e=n(67250);T.exports=e({}.isPrototypeOf)},53726:function(T,r,n){"use strict";var e=n(67250),a=n(45299),t=n(57591),o=n(14211).indexOf,f=n(79195),b=e([].push);T.exports=function(y,I){var k=t(y),g=0,l=[],c;for(c in k)!a(f,c)&&a(k,c)&&b(l,c);for(;I.length>g;)a(k,c=I[g++])&&(~o(l,c)||b(l,c));return l}},18450:function(T,r,n){"use strict";var e=n(53726),a=n(89453);T.exports=Object.keys||function(){function t(o){return e(o,a)}return t}()},12867:function(T,r){"use strict";var n={}.propertyIsEnumerable,e=Object.getOwnPropertyDescriptor,a=e&&!n.call({1:2},1);r.f=a?function(){function t(o){var f=e(this,o);return!!f&&f.enumerable}return t}():n},57377:function(T,r,n){"use strict";var e=n(4493),a=n(74685),t=n(40033),o=n(9342);T.exports=e||!t(function(){if(!(o&&o<535)){var f=Math.random();__defineSetter__.call(null,f,function(){}),delete a[f]}})},76649:function(T,r,n){"use strict";var e=n(38656),a=n(77568),t=n(16952),o=n(35908);T.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var f=!1,b={},y;try{y=e(Object.prototype,"__proto__","set"),y(b,[]),f=b instanceof Array}catch(I){}return function(){function I(k,g){return t(k),o(g),a(k)&&(f?y(k,g):k.__proto__=g),k}return I}()}():void 0)},70915:function(T,r,n){"use strict";var e=n(58310),a=n(40033),t=n(67250),o=n(36917),f=n(18450),b=n(57591),y=n(12867).f,I=t(y),k=t([].push),g=e&&a(function(){var c=Object.create(null);return c[2]=2,!I(c,2)}),l=function(m){return function(i){for(var u=b(i),s=f(u),d=g&&o(u)===null,v=s.length,h=0,C=[],p;v>h;)p=s[h++],(!e||(d?p in u:I(u,p)))&&k(C,m?[p,u[p]]:u[p]);return C}};T.exports={entries:l(!0),values:l(!1)}},2509:function(T,r,n){"use strict";var e=n(2650),a=n(2281);T.exports=e?{}.toString:function(){function t(){return"[object "+a(this)+"]"}return t}()},13396:function(T,r,n){"use strict";var e=n(91495),a=n(55747),t=n(77568),o=TypeError;T.exports=function(f,b){var y,I;if(b==="string"&&a(y=f.toString)&&!t(I=e(y,f))||a(y=f.valueOf)&&!t(I=e(y,f))||b!=="string"&&a(y=f.toString)&&!t(I=e(y,f)))return I;throw new o("Can't convert object to primitive value")}},97921:function(T,r,n){"use strict";var e=n(4009),a=n(67250),t=n(37310),o=n(89235),f=n(30365),b=a([].concat);T.exports=e("Reflect","ownKeys")||function(){function y(I){var k=t.f(f(I)),g=o.f;return g?b(k,g(I)):k}return y}()},61765:function(T,r,n){"use strict";var e=n(74685);T.exports=e},10729:function(T){"use strict";T.exports=function(r){try{return{error:!1,value:r()}}catch(n){return{error:!0,value:n}}}},74854:function(T,r,n){"use strict";var e=n(74685),a=n(67512),t=n(55747),o=n(41314),f=n(40492),b=n(24697),y=n(8180),I=n(73730),k=n(4493),g=n(5026),l=a&&a.prototype,c=b("species"),m=!1,i=t(e.PromiseRejectionEvent),u=o("Promise",function(){var s=f(a),d=s!==String(a);if(!d&&g===66||k&&!(l.catch&&l.finally))return!0;if(!g||g<51||!/native code/.test(s)){var v=new a(function(p){p(1)}),h=function(N){N(function(){},function(){})},C=v.constructor={};if(C[c]=h,m=v.then(function(){})instanceof h,!m)return!0}return!d&&(y||I)&&!i});T.exports={CONSTRUCTOR:u,REJECTION_EVENT:i,SUBCLASSING:m}},67512:function(T,r,n){"use strict";var e=n(74685);T.exports=e.Promise},66628:function(T,r,n){"use strict";var e=n(30365),a=n(77568),t=n(81837);T.exports=function(o,f){if(e(o),a(f)&&f.constructor===o)return f;var b=t.f(o),y=b.resolve;return y(f),b.promise}},48199:function(T,r,n){"use strict";var e=n(67512),a=n(92490),t=n(74854).CONSTRUCTOR;T.exports=t||!a(function(o){e.all(o).then(void 0,function(){})})},34550:function(T,r,n){"use strict";var e=n(74595).f;T.exports=function(a,t,o){o in a||e(a,o,{configurable:!0,get:function(){function f(){return t[o]}return f}(),set:function(){function f(b){t[o]=b}return f}()})}},9547:function(T){"use strict";var r=function(){this.head=null,this.tail=null};r.prototype={add:function(){function n(e){var a={item:e,next:null},t=this.tail;t?t.next=a:this.head=a,this.tail=a}return n}(),get:function(){function n(){var e=this.head;if(e){var a=this.head=e.next;return a===null&&(this.tail=null),e.item}}return n}()},T.exports=r},28340:function(T,r,n){"use strict";var e=n(91495),a=n(30365),t=n(55747),o=n(7462),f=n(14489),b=TypeError;T.exports=function(y,I){var k=y.exec;if(t(k)){var g=e(k,y,I);return g!==null&&a(g),g}if(o(y)==="RegExp")return e(f,y,I);throw new b("RegExp#exec called on incompatible receiver")}},14489:function(T,r,n){"use strict";var e=n(91495),a=n(67250),t=n(12605),o=n(70901),f=n(62115),b=n(16639),y=n(80674),I=n(5419).get,k=n(39173),g=n(35688),l=b("native-string-replace",String.prototype.replace),c=RegExp.prototype.exec,m=c,i=a("".charAt),u=a("".indexOf),s=a("".replace),d=a("".slice),v=function(){var N=/a/,V=/b*/g;return e(c,N,"a"),e(c,V,"a"),N.lastIndex!==0||V.lastIndex!==0}(),h=f.BROKEN_CARET,C=/()??/.exec("")[1]!==void 0,p=v||C||h||k||g;p&&(m=function(){function N(V){var S=this,B=I(S),L=t(V),w=B.raw,A,x,E,P,D,M,R;if(w)return w.lastIndex=S.lastIndex,A=e(m,w,L),S.lastIndex=w.lastIndex,A;var O=B.groups,F=h&&S.sticky,_=e(o,S),U=S.source,z=0,$=L;if(F&&(_=s(_,"y",""),u(_,"g")===-1&&(_+="g"),$=d(L,S.lastIndex),S.lastIndex>0&&(!S.multiline||S.multiline&&i(L,S.lastIndex-1)!=="\n")&&(U="(?: "+U+")",$=" "+$,z++),x=new RegExp("^(?:"+U+")",_)),C&&(x=new RegExp("^"+U+"$(?!\\s)",_)),v&&(E=S.lastIndex),P=e(c,F?x:S,$),F?P?(P.input=d(P.input,z),P[0]=d(P[0],z),P.index=S.lastIndex,S.lastIndex+=P[0].length):S.lastIndex=0:v&&P&&(S.lastIndex=S.global?P.index+P[0].length:E),C&&P&&P.length>1&&e(l,P[0],x,function(){for(D=1;Db)","g");return o.exec("b").groups.a!=="b"||"b".replace(o,"$
    c")!=="bc"})},16952:function(T,r,n){"use strict";var e=n(42871),a=TypeError;T.exports=function(t){if(e(t))throw new a("Can't call method on "+t);return t}},44915:function(T,r,n){"use strict";var e=n(74685),a=n(58310),t=Object.getOwnPropertyDescriptor;T.exports=function(o){if(!a)return e[o];var f=t(e,o);return f&&f.value}},5700:function(T){"use strict";T.exports=Object.is||function(){function r(n,e){return n===e?n!==0||1/n===1/e:n!==n&&e!==e}return r}()},78362:function(T,r,n){"use strict";var e=n(74685),a=n(61267),t=n(55747),o=n(49197),f=n(63318),b=n(54602),y=n(24986),I=e.Function,k=/MSIE .\./.test(f)||o&&function(){var g=e.Bun.version.split(".");return g.length<3||g[0]==="0"&&(g[1]<3||g[1]==="3"&&g[2]==="0")}();T.exports=function(g,l){var c=l?2:1;return k?function(m,i){var u=y(arguments.length,1)>c,s=t(m)?m:I(m),d=u?b(arguments,c):[],v=u?function(){a(s,this,d)}:s;return l?g(v,i):g(v)}:g}},58491:function(T,r,n){"use strict";var e=n(4009),a=n(73936),t=n(24697),o=n(58310),f=t("species");T.exports=function(b){var y=e(b);o&&y&&!y[f]&&a(y,f,{configurable:!0,get:function(){function I(){return this}return I}()})}},84925:function(T,r,n){"use strict";var e=n(74595).f,a=n(45299),t=n(24697),o=t("toStringTag");T.exports=function(f,b,y){f&&!y&&(f=f.prototype),f&&!a(f,o)&&e(f,o,{configurable:!0,value:b})}},19417:function(T,r,n){"use strict";var e=n(16639),a=n(16738),t=e("keys");T.exports=function(o){return t[o]||(t[o]=a(o))}},40095:function(T,r,n){"use strict";var e=n(4493),a=n(74685),t=n(18231),o="__core-js_shared__",f=T.exports=a[o]||t(o,{});(f.versions||(f.versions=[])).push({version:"3.37.1",mode:e?"pure":"global",copyright:"\xA9 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.37.1/LICENSE",source:"https://github.com/zloirock/core-js"})},16639:function(T,r,n){"use strict";var e=n(40095);T.exports=function(a,t){return e[a]||(e[a]=t||{})}},28987:function(T,r,n){"use strict";var e=n(30365),a=n(32606),t=n(42871),o=n(24697),f=o("species");T.exports=function(b,y){var I=e(b).constructor,k;return I===void 0||t(k=e(I)[f])?y:a(k)}},88539:function(T,r,n){"use strict";var e=n(40033);T.exports=function(a){return e(function(){var t=""[a]('"');return t!==t.toLowerCase()||t.split('"').length>3})}},50233:function(T,r,n){"use strict";var e=n(67250),a=n(61365),t=n(12605),o=n(16952),f=e("".charAt),b=e("".charCodeAt),y=e("".slice),I=function(g){return function(l,c){var m=t(o(l)),i=a(c),u=m.length,s,d;return i<0||i>=u?g?"":void 0:(s=b(m,i),s<55296||s>56319||i+1===u||(d=b(m,i+1))<56320||d>57343?g?f(m,i):s:g?y(m,i,i+2):(s-55296<<10)+(d-56320)+65536)}};T.exports={codeAt:I(!1),charAt:I(!0)}},34125:function(T,r,n){"use strict";var e=n(63318);T.exports=/Version\/10(?:\.\d+){1,2}(?: [\w./]+)?(?: Mobile\/\w+)? Safari\//.test(e)},24051:function(T,r,n){"use strict";var e=n(67250),a=n(10188),t=n(12605),o=n(62443),f=n(16952),b=e(o),y=e("".slice),I=Math.ceil,k=function(l){return function(c,m,i){var u=t(f(c)),s=a(m),d=u.length,v=i===void 0?" ":t(i),h,C;return s<=d||v===""?u:(h=s-d,C=b(v,I(h/v.length)),C.length>h&&(C=y(C,0,h)),l?u+C:C+u)}};T.exports={start:k(!1),end:k(!0)}},62443:function(T,r,n){"use strict";var e=n(61365),a=n(12605),t=n(16952),o=RangeError;T.exports=function(){function f(b){var y=a(t(this)),I="",k=e(b);if(k<0||k===1/0)throw new o("Wrong number of repetitions");for(;k>0;(k>>>=1)&&(y+=y))k&1&&(I+=y);return I}return f}()},43476:function(T,r,n){"use strict";var e=n(92648).end,a=n(90012);T.exports=a("trimEnd")?function(){function t(){return e(this)}return t}():"".trimEnd},90012:function(T,r,n){"use strict";var e=n(70520).PROPER,a=n(40033),t=n(4198),o="\u200B\x85\u180E";T.exports=function(f){return a(function(){return!!t[f]()||o[f]()!==o||e&&t[f].name!==f})}},43885:function(T,r,n){"use strict";var e=n(92648).start,a=n(90012);T.exports=a("trimStart")?function(){function t(){return e(this)}return t}():"".trimStart},92648:function(T,r,n){"use strict";var e=n(67250),a=n(16952),t=n(12605),o=n(4198),f=e("".replace),b=RegExp("^["+o+"]+"),y=RegExp("(^|[^"+o+"])["+o+"]+$"),I=function(g){return function(l){var c=t(a(l));return g&1&&(c=f(c,b,"")),g&2&&(c=f(c,y,"$1")),c}};T.exports={start:I(1),end:I(2),trim:I(3)}},52357:function(T,r,n){"use strict";var e=n(5026),a=n(40033),t=n(74685),o=t.String;T.exports=!!Object.getOwnPropertySymbols&&!a(function(){var f=Symbol("symbol detection");return!o(f)||!(Object(f)instanceof Symbol)||!Symbol.sham&&e&&e<41})},52360:function(T,r,n){"use strict";var e=n(91495),a=n(4009),t=n(24697),o=n(55938);T.exports=function(){var f=a("Symbol"),b=f&&f.prototype,y=b&&b.valueOf,I=t("toPrimitive");b&&!b[I]&&o(b,I,function(k){return e(y,this)},{arity:1})}},66570:function(T,r,n){"use strict";var e=n(52357);T.exports=e&&!!Symbol.for&&!!Symbol.keyFor},60375:function(T,r,n){"use strict";var e=n(74685),a=n(61267),t=n(75754),o=n(55747),f=n(45299),b=n(40033),y=n(5315),I=n(54602),k=n(12689),g=n(24986),l=n(83433),c=n(81702),m=e.setImmediate,i=e.clearImmediate,u=e.process,s=e.Dispatch,d=e.Function,v=e.MessageChannel,h=e.String,C=0,p={},N="onreadystatechange",V,S,B,L;b(function(){V=e.location});var w=function(D){if(f(p,D)){var M=p[D];delete p[D],M()}},A=function(D){return function(){w(D)}},x=function(D){w(D.data)},E=function(D){e.postMessage(h(D),V.protocol+"//"+V.host)};(!m||!i)&&(m=function(){function P(D){g(arguments.length,1);var M=o(D)?D:d(D),R=I(arguments,1);return p[++C]=function(){a(M,void 0,R)},S(C),C}return P}(),i=function(){function P(D){delete p[D]}return P}(),c?S=function(D){u.nextTick(A(D))}:s&&s.now?S=function(D){s.now(A(D))}:v&&!l?(B=new v,L=B.port2,B.port1.onmessage=x,S=t(L.postMessage,L)):e.addEventListener&&o(e.postMessage)&&!e.importScripts&&V&&V.protocol!=="file:"&&!b(E)?(S=E,e.addEventListener("message",x,!1)):N in k("script")?S=function(D){y.appendChild(k("script"))[N]=function(){y.removeChild(this),w(D)}}:S=function(D){setTimeout(A(D),0)}),T.exports={set:m,clear:i}},46438:function(T,r,n){"use strict";var e=n(67250);T.exports=e(1 .valueOf)},13912:function(T,r,n){"use strict";var e=n(61365),a=Math.max,t=Math.min;T.exports=function(o,f){var b=e(o);return b<0?a(b+f,0):t(b,f)}},61484:function(T,r,n){"use strict";var e=n(24843),a=TypeError;T.exports=function(t){var o=e(t,"number");if(typeof o=="number")throw new a("Can't convert number to bigint");return BigInt(o)}},43806:function(T,r,n){"use strict";var e=n(61365),a=n(10188),t=RangeError;T.exports=function(o){if(o===void 0)return 0;var f=e(o),b=a(f);if(f!==b)throw new t("Wrong length or index");return b}},57591:function(T,r,n){"use strict";var e=n(37457),a=n(16952);T.exports=function(t){return e(a(t))}},61365:function(T,r,n){"use strict";var e=n(21119);T.exports=function(a){var t=+a;return t!==t||t===0?0:e(t)}},10188:function(T,r,n){"use strict";var e=n(61365),a=Math.min;T.exports=function(t){var o=e(t);return o>0?a(o,9007199254740991):0}},46771:function(T,r,n){"use strict";var e=n(16952),a=Object;T.exports=function(t){return a(e(t))}},56043:function(T,r,n){"use strict";var e=n(16140),a=RangeError;T.exports=function(t,o){var f=e(t);if(f%o)throw new a("Wrong offset");return f}},16140:function(T,r,n){"use strict";var e=n(61365),a=RangeError;T.exports=function(t){var o=e(t);if(o<0)throw new a("The argument can't be less than 0");return o}},24843:function(T,r,n){"use strict";var e=n(91495),a=n(77568),t=n(71399),o=n(78060),f=n(13396),b=n(24697),y=TypeError,I=b("toPrimitive");T.exports=function(k,g){if(!a(k)||t(k))return k;var l=o(k,I),c;if(l){if(g===void 0&&(g="default"),c=e(l,k,g),!a(c)||t(c))return c;throw new y("Can't convert object to primitive value")}return g===void 0&&(g="number"),f(k,g)}},767:function(T,r,n){"use strict";var e=n(24843),a=n(71399);T.exports=function(t){var o=e(t,"string");return a(o)?o:o+""}},2650:function(T,r,n){"use strict";var e=n(24697),a=e("toStringTag"),t={};t[a]="z",T.exports=String(t)==="[object z]"},12605:function(T,r,n){"use strict";var e=n(2281),a=String;T.exports=function(t){if(e(t)==="Symbol")throw new TypeError("Cannot convert a Symbol value to a string");return a(t)}},15409:function(T){"use strict";var r=Math.round;T.exports=function(n){var e=r(n);return e<0?0:e>255?255:e&255}},89393:function(T){"use strict";var r=String;T.exports=function(n){try{return r(n)}catch(e){return"Object"}}},80185:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(91495),o=n(58310),f=n(86563),b=n(4246),y=n(37336),I=n(60077),k=n(87458),g=n(37909),l=n(5841),c=n(10188),m=n(43806),i=n(56043),u=n(15409),s=n(767),d=n(45299),v=n(2281),h=n(77568),C=n(71399),p=n(80674),N=n(21287),V=n(76649),S=n(37310).f,B=n(3805),L=n(22603).forEach,w=n(58491),A=n(73936),x=n(74595),E=n(27193),P=n(78008),D=n(5419),M=n(5781),R=D.get,O=D.set,F=D.enforce,_=x.f,U=E.f,z=a.RangeError,$=y.ArrayBuffer,G=$.prototype,X=y.DataView,J=b.NATIVE_ARRAY_BUFFER_VIEWS,se=b.TYPED_ARRAY_TAG,ie=b.TypedArray,me=b.TypedArrayPrototype,q=b.isTypedArray,re="BYTES_PER_ELEMENT",ae="Wrong length",le=function(ce,Ve){A(ce,Ve,{configurable:!0,get:function(){function Ce(){return R(this)[Ve]}return Ce}()})},Z=function(ce){var Ve;return N(G,ce)||(Ve=v(ce))==="ArrayBuffer"||Ve==="SharedArrayBuffer"},ne=function(ce,Ve){return q(ce)&&!C(Ve)&&Ve in ce&&l(+Ve)&&Ve>=0},te=function(){function pe(ce,Ve){return Ve=s(Ve),ne(ce,Ve)?k(2,ce[Ve]):U(ce,Ve)}return pe}(),fe=function(){function pe(ce,Ve,Ce){return Ve=s(Ve),ne(ce,Ve)&&h(Ce)&&d(Ce,"value")&&!d(Ce,"get")&&!d(Ce,"set")&&!Ce.configurable&&(!d(Ce,"writable")||Ce.writable)&&(!d(Ce,"enumerable")||Ce.enumerable)?(ce[Ve]=Ce.value,ce):_(ce,Ve,Ce)}return pe}();o?(J||(E.f=te,x.f=fe,le(me,"buffer"),le(me,"byteOffset"),le(me,"byteLength"),le(me,"length")),e({target:"Object",stat:!0,forced:!J},{getOwnPropertyDescriptor:te,defineProperty:fe}),T.exports=function(pe,ce,Ve){var Ce=pe.match(/\d+/)[0]/8,Ne=pe+(Ve?"Clamped":"")+"Array",Be="get"+pe,be="set"+pe,Le=a[Ne],we=Le,xe=we&&we.prototype,Re={},He=function(ve,Se){var Pe=R(ve);return Pe.view[Be](Se*Ce+Pe.byteOffset,!0)},ye=function(ve,Se,Pe){var je=R(ve);je.view[be](Se*Ce+je.byteOffset,Ve?u(Pe):Pe,!0)},de=function(ve,Se){_(ve,Se,{get:function(){function Pe(){return He(this,Se)}return Pe}(),set:function(){function Pe(je){return ye(this,Se,je)}return Pe}(),enumerable:!0})};J?f&&(we=ce(function(ke,ve,Se,Pe){return I(ke,xe),M(function(){return h(ve)?Z(ve)?Pe!==void 0?new Le(ve,i(Se,Ce),Pe):Se!==void 0?new Le(ve,i(Se,Ce)):new Le(ve):q(ve)?P(we,ve):t(B,we,ve):new Le(m(ve))}(),ke,we)}),V&&V(we,ie),L(S(Le),function(ke){ke in we||g(we,ke,Le[ke])}),we.prototype=xe):(we=ce(function(ke,ve,Se,Pe){I(ke,xe);var je=0,Fe=0,ze,We,Ue;if(!h(ve))Ue=m(ve),We=Ue*Ce,ze=new $(We);else if(Z(ve)){ze=ve,Fe=i(Se,Ce);var Xe=ve.byteLength;if(Pe===void 0){if(Xe%Ce)throw new z(ae);if(We=Xe-Fe,We<0)throw new z(ae)}else if(We=c(Pe)*Ce,We+Fe>Xe)throw new z(ae);Ue=We/Ce}else return q(ve)?P(we,ve):t(B,we,ve);for(O(ke,{buffer:ze,byteOffset:Fe,byteLength:We,length:Ue,view:new X(ze)});je1?arguments[1]:void 0,v=d!==void 0,h=y(u),C,p,N,V,S,B,L,w;if(h&&!I(h))for(L=b(u,h),w=L.next,u=[];!(B=a(w,L)).done;)u.push(B.value);for(v&&s>2&&(d=e(d,arguments[2])),p=f(u),N=new(g(i))(p),V=k(N),C=0;p>C;C++)S=v?d(u[C],C):u[C],N[C]=V?l(S):+S;return N}return c}()},31082:function(T,r,n){"use strict";var e=n(4246),a=n(28987),t=e.aTypedArrayConstructor,o=e.getTypedArrayConstructor;T.exports=function(f){return t(a(f,o(f)))}},16738:function(T,r,n){"use strict";var e=n(67250),a=0,t=Math.random(),o=e(1 .toString);T.exports=function(f){return"Symbol("+(f===void 0?"":f)+")_"+o(++a+t,36)}},1062:function(T,r,n){"use strict";var e=n(52357);T.exports=e&&!Symbol.sham&&typeof Symbol.iterator=="symbol"},80944:function(T,r,n){"use strict";var e=n(58310),a=n(40033);T.exports=e&&a(function(){return Object.defineProperty(function(){},"prototype",{value:42,writable:!1}).prototype!==42})},24986:function(T){"use strict";var r=TypeError;T.exports=function(n,e){if(n=51||!a(function(){var d=[];return d[m]=!1,d.concat()[0]!==d}),u=function(v){if(!o(v))return!1;var h=v[m];return h!==void 0?!!h:t(v)},s=!i||!g("concat");e({target:"Array",proto:!0,arity:1,forced:s},{concat:function(){function d(v){var h=f(this),C=k(h,0),p=0,N,V,S,B,L;for(N=-1,S=arguments.length;N1?arguments[1]:void 0)}return f}()})},68933:function(T,r,n){"use strict";var e=n(63964),a=n(88471),t=n(80575);e({target:"Array",proto:!0},{fill:a}),t("fill")},47830:function(T,r,n){"use strict";var e=n(63964),a=n(22603).filter,t=n(44091),o=t("filter");e({target:"Array",proto:!0,forced:!o},{filter:function(){function f(b){return a(this,b,arguments.length>1?arguments[1]:void 0)}return f}()})},64094:function(T,r,n){"use strict";var e=n(63964),a=n(22603).findIndex,t=n(80575),o="findIndex",f=!0;o in[]&&Array(1)[o](function(){f=!1}),e({target:"Array",proto:!0,forced:f},{findIndex:function(){function b(y){return a(this,y,arguments.length>1?arguments[1]:void 0)}return b}()}),t(o)},13455:function(T,r,n){"use strict";var e=n(63964),a=n(22603).find,t=n(80575),o="find",f=!0;o in[]&&Array(1)[o](function(){f=!1}),e({target:"Array",proto:!0,forced:f},{find:function(){function b(y){return a(this,y,arguments.length>1?arguments[1]:void 0)}return b}()}),t(o)},32384:function(T,r,n){"use strict";var e=n(63964),a=n(65561),t=n(10320),o=n(46771),f=n(24760),b=n(57823);e({target:"Array",proto:!0},{flatMap:function(){function y(I){var k=o(this),g=f(k),l;return t(I),l=b(k,0),l.length=a(l,k,k,g,0,1,I,arguments.length>1?arguments[1]:void 0),l}return y}()})},61915:function(T,r,n){"use strict";var e=n(63964),a=n(65561),t=n(46771),o=n(24760),f=n(61365),b=n(57823);e({target:"Array",proto:!0},{flat:function(){function y(){var I=arguments.length?arguments[0]:void 0,k=t(this),g=o(k),l=b(k,0);return l.length=a(l,k,k,g,0,I===void 0?1:f(I)),l}return y}()})},25579:function(T,r,n){"use strict";var e=n(63964),a=n(35601);e({target:"Array",proto:!0,forced:[].forEach!==a},{forEach:a})},63532:function(T,r,n){"use strict";var e=n(63964),a=n(73174),t=n(92490),o=!t(function(f){Array.from(f)});e({target:"Array",stat:!0,forced:o},{from:a})},33425:function(T,r,n){"use strict";var e=n(63964),a=n(14211).includes,t=n(40033),o=n(80575),f=t(function(){return!Array(1).includes()});e({target:"Array",proto:!0,forced:f},{includes:function(){function b(y){return a(this,y,arguments.length>1?arguments[1]:void 0)}return b}()}),o("includes")},43894:function(T,r,n){"use strict";var e=n(63964),a=n(71138),t=n(14211).indexOf,o=n(55528),f=a([].indexOf),b=!!f&&1/f([1],1,-0)<0,y=b||!o("indexOf");e({target:"Array",proto:!0,forced:y},{indexOf:function(){function I(k){var g=arguments.length>1?arguments[1]:void 0;return b?f(this,k,g)||0:t(this,k,g)}return I}()})},99636:function(T,r,n){"use strict";var e=n(63964),a=n(37386);e({target:"Array",stat:!0},{isArray:a})},34570:function(T,r,n){"use strict";var e=n(57591),a=n(80575),t=n(83967),o=n(5419),f=n(74595).f,b=n(65574),y=n(5959),I=n(4493),k=n(58310),g="Array Iterator",l=o.set,c=o.getterFor(g);T.exports=b(Array,"Array",function(i,u){l(this,{type:g,target:e(i),index:0,kind:u})},function(){var i=c(this),u=i.target,s=i.index++;if(!u||s>=u.length)return i.target=void 0,y(void 0,!0);switch(i.kind){case"keys":return y(s,!1);case"values":return y(u[s],!1)}return y([s,u[s]],!1)},"values");var m=t.Arguments=t.Array;if(a("keys"),a("values"),a("entries"),!I&&k&&m.name!=="values")try{f(m,"name",{value:"values"})}catch(i){}},94432:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(37457),o=n(57591),f=n(55528),b=a([].join),y=t!==Object,I=y||!f("join",",");e({target:"Array",proto:!0,forced:I},{join:function(){function k(g){return b(o(this),g===void 0?",":g)}return k}()})},24683:function(T,r,n){"use strict";var e=n(63964),a=n(1325);e({target:"Array",proto:!0,forced:a!==[].lastIndexOf},{lastIndexOf:a})},69984:function(T,r,n){"use strict";var e=n(63964),a=n(22603).map,t=n(44091),o=t("map");e({target:"Array",proto:!0,forced:!o},{map:function(){function f(b){return a(this,b,arguments.length>1?arguments[1]:void 0)}return f}()})},32089:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(1031),o=n(60102),f=Array,b=a(function(){function y(){}return!(f.of.call(y)instanceof y)});e({target:"Array",stat:!0,forced:b},{of:function(){function y(){for(var I=0,k=arguments.length,g=new(t(this)?this:f)(k);k>I;)o(g,I,arguments[I++]);return g.length=k,g}return y}()})},29645:function(T,r,n){"use strict";var e=n(63964),a=n(56844).right,t=n(55528),o=n(5026),f=n(81702),b=!f&&o>79&&o<83,y=b||!t("reduceRight");e({target:"Array",proto:!0,forced:y},{reduceRight:function(){function I(k){return a(this,k,arguments.length,arguments.length>1?arguments[1]:void 0)}return I}()})},60206:function(T,r,n){"use strict";var e=n(63964),a=n(56844).left,t=n(55528),o=n(5026),f=n(81702),b=!f&&o>79&&o<83,y=b||!t("reduce");e({target:"Array",proto:!0,forced:y},{reduce:function(){function I(k){var g=arguments.length;return a(this,k,g,g>1?arguments[1]:void 0)}return I}()})},4788:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(37386),o=a([].reverse),f=[1,2];e({target:"Array",proto:!0,forced:String(f)===String(f.reverse())},{reverse:function(){function b(){return t(this)&&(this.length=this.length),o(this)}return b}()})},58672:function(T,r,n){"use strict";var e=n(63964),a=n(37386),t=n(1031),o=n(77568),f=n(13912),b=n(24760),y=n(57591),I=n(60102),k=n(24697),g=n(44091),l=n(54602),c=g("slice"),m=k("species"),i=Array,u=Math.max;e({target:"Array",proto:!0,forced:!c},{slice:function(){function s(d,v){var h=y(this),C=b(h),p=f(d,C),N=f(v===void 0?C:v,C),V,S,B;if(a(h)&&(V=h.constructor,t(V)&&(V===i||a(V.prototype))?V=void 0:o(V)&&(V=V[m],V===null&&(V=void 0)),V===i||V===void 0))return l(h,p,N);for(S=new(V===void 0?i:V)(u(N-p,0)),B=0;p1?arguments[1]:void 0)}return f}()})},48968:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(10320),o=n(46771),f=n(24760),b=n(95108),y=n(12605),I=n(40033),k=n(90274),g=n(55528),l=n(652),c=n(19228),m=n(5026),i=n(9342),u=[],s=a(u.sort),d=a(u.push),v=I(function(){u.sort(void 0)}),h=I(function(){u.sort(null)}),C=g("sort"),p=!I(function(){if(m)return m<70;if(!(l&&l>3)){if(c)return!0;if(i)return i<603;var S="",B,L,w,A;for(B=65;B<76;B++){switch(L=String.fromCharCode(B),B){case 66:case 69:case 70:case 72:w=3;break;case 68:case 71:w=4;break;default:w=2}for(A=0;A<47;A++)u.push({k:L+A,v:w})}for(u.sort(function(x,E){return E.v-x.v}),A=0;Ay(w)?1:-1}};e({target:"Array",proto:!0,forced:N},{sort:function(){function S(B){B!==void 0&&t(B);var L=o(this);if(p)return B===void 0?s(L):s(L,B);var w=[],A=f(L),x,E;for(E=0;Eh-V+N;B--)g(v,B-1)}else if(N>V)for(B=h-V;B>C;B--)L=B+V-1,w=B+N-1,L in v?v[w]=v[L]:g(v,w);for(B=0;B9490626562425156e-8?o(g)+b:a(g-1+f(g-1)*f(g+1))}return I}()})},59660:function(T,r,n){"use strict";var e=n(63964),a=Math.asinh,t=Math.log,o=Math.sqrt;function f(y){var I=+y;return!isFinite(I)||I===0?I:I<0?-f(-I):t(I+o(I*I+1))}var b=!(a&&1/a(0)>0);e({target:"Math",stat:!0,forced:b},{asinh:f})},15383:function(T,r,n){"use strict";var e=n(63964),a=Math.atanh,t=Math.log,o=!(a&&1/a(-0)<0);e({target:"Math",stat:!0,forced:o},{atanh:function(){function f(b){var y=+b;return y===0?y:t((1+y)/(1-y))/2}return f}()})},92866:function(T,r,n){"use strict";var e=n(63964),a=n(22172),t=Math.abs,o=Math.pow;e({target:"Math",stat:!0},{cbrt:function(){function f(b){var y=+b;return a(y)*o(t(y),.3333333333333333)}return f}()})},86107:function(T,r,n){"use strict";var e=n(63964),a=Math.floor,t=Math.log,o=Math.LOG2E;e({target:"Math",stat:!0},{clz32:function(){function f(b){var y=b>>>0;return y?31-a(t(y+.5)*o):32}return f}()})},29248:function(T,r,n){"use strict";var e=n(63964),a=n(82040),t=Math.cosh,o=Math.abs,f=Math.E,b=!t||t(710)===1/0;e({target:"Math",stat:!0,forced:b},{cosh:function(){function y(I){var k=a(o(I)-1)+1;return(k+1/(k*f*f))*(f/2)}return y}()})},52540:function(T,r,n){"use strict";var e=n(63964),a=n(82040);e({target:"Math",stat:!0,forced:a!==Math.expm1},{expm1:a})},79007:function(T,r,n){"use strict";var e=n(63964),a=n(95867);e({target:"Math",stat:!0},{fround:a})},77199:function(T,r,n){"use strict";var e=n(63964),a=Math.hypot,t=Math.abs,o=Math.sqrt,f=!!a&&a(1/0,NaN)!==1/0;e({target:"Math",stat:!0,arity:2,forced:f},{hypot:function(){function b(y,I){for(var k=0,g=0,l=arguments.length,c=0,m,i;g0?(i=m/c,k+=i*i):k+=m;return c===1/0?1/0:c*o(k)}return b}()})},6522:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=Math.imul,o=a(function(){return t(4294967295,5)!==-5||t.length!==2});e({target:"Math",stat:!0,forced:o},{imul:function(){function f(b,y){var I=65535,k=+b,g=+y,l=I&k,c=I&g;return 0|l*c+((I&k>>>16)*c+l*(I&g>>>16)<<16>>>0)}return f}()})},95542:function(T,r,n){"use strict";var e=n(63964),a=n(75002);e({target:"Math",stat:!0},{log10:a})},2966:function(T,r,n){"use strict";var e=n(63964),a=n(90874);e({target:"Math",stat:!0},{log1p:a})},20997:function(T,r,n){"use strict";var e=n(63964),a=Math.log,t=Math.LN2;e({target:"Math",stat:!0},{log2:function(){function o(f){return a(f)/t}return o}()})},57400:function(T,r,n){"use strict";var e=n(63964),a=n(22172);e({target:"Math",stat:!0},{sign:a})},45571:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(82040),o=Math.abs,f=Math.exp,b=Math.E,y=a(function(){return Math.sinh(-2e-17)!==-2e-17});e({target:"Math",stat:!0,forced:y},{sinh:function(){function I(k){var g=+k;return o(g)<1?(t(g)-t(-g))/2:(f(g-1)-f(-g-1))*(b/2)}return I}()})},54800:function(T,r,n){"use strict";var e=n(63964),a=n(82040),t=Math.exp;e({target:"Math",stat:!0},{tanh:function(){function o(f){var b=+f,y=a(b),I=a(-b);return y===1/0?1:I===1/0?-1:(y-I)/(t(b)+t(-b))}return o}()})},15709:function(T,r,n){"use strict";var e=n(84925);e(Math,"Math",!0)},76059:function(T,r,n){"use strict";var e=n(63964),a=n(21119);e({target:"Math",stat:!0},{trunc:a})},96614:function(T,r,n){"use strict";var e=n(63964),a=n(4493),t=n(58310),o=n(74685),f=n(61765),b=n(67250),y=n(41314),I=n(45299),k=n(5781),g=n(21287),l=n(71399),c=n(24843),m=n(40033),i=n(37310).f,u=n(27193).f,s=n(74595).f,d=n(46438),v=n(92648).trim,h="Number",C=o[h],p=f[h],N=C.prototype,V=o.TypeError,S=b("".slice),B=b("".charCodeAt),L=function(M){var R=c(M,"number");return typeof R=="bigint"?R:w(R)},w=function(M){var R=c(M,"number"),O,F,_,U,z,$,G,X;if(l(R))throw new V("Cannot convert a Symbol value to a number");if(typeof R=="string"&&R.length>2){if(R=v(R),O=B(R,0),O===43||O===45){if(F=B(R,2),F===88||F===120)return NaN}else if(O===48){switch(B(R,1)){case 66:case 98:_=2,U=49;break;case 79:case 111:_=8,U=55;break;default:return+R}for(z=S(R,2),$=z.length,G=0;G<$;G++)if(X=B(z,G),X<48||X>U)return NaN;return parseInt(z,_)}}return+R},A=y(h,!C(" 0o1")||!C("0b1")||C("+0x1")),x=function(M){return g(N,M)&&m(function(){d(M)})},E=function(){function D(M){var R=arguments.length<1?0:C(L(M));return x(this)?k(Object(R),this,E):R}return D}();E.prototype=N,A&&!a&&(N.constructor=E),e({global:!0,constructor:!0,wrap:!0,forced:A},{Number:E});var P=function(M,R){for(var O=t?i(R):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,isFinite,isInteger,isNaN,isSafeInteger,parseFloat,parseInt,fromString,range".split(","),F=0,_;O.length>F;F++)I(R,_=O[F])&&!I(M,_)&&s(M,_,u(R,_))};a&&p&&P(f[h],p),(A||a)&&P(f[h],C)},324:function(T,r,n){"use strict";var e=n(63964);e({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{EPSILON:Math.pow(2,-52)})},90426:function(T,r,n){"use strict";var e=n(63964),a=n(3294);e({target:"Number",stat:!0},{isFinite:a})},95443:function(T,r,n){"use strict";var e=n(63964),a=n(5841);e({target:"Number",stat:!0},{isInteger:a})},87968:function(T,r,n){"use strict";var e=n(63964);e({target:"Number",stat:!0},{isNaN:function(){function a(t){return t!==t}return a}()})},55007:function(T,r,n){"use strict";var e=n(63964),a=n(5841),t=Math.abs;e({target:"Number",stat:!0},{isSafeInteger:function(){function o(f){return a(f)&&t(f)<=9007199254740991}return o}()})},55323:function(T,r,n){"use strict";var e=n(63964);e({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{MAX_SAFE_INTEGER:9007199254740991})},13521:function(T,r,n){"use strict";var e=n(63964);e({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{MIN_SAFE_INTEGER:-9007199254740991})},5006:function(T,r,n){"use strict";var e=n(63964),a=n(28506);e({target:"Number",stat:!0,forced:Number.parseFloat!==a},{parseFloat:a})},99009:function(T,r,n){"use strict";var e=n(63964),a=n(13693);e({target:"Number",stat:!0,forced:Number.parseInt!==a},{parseInt:a})},85770:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(61365),o=n(46438),f=n(62443),b=n(40033),y=RangeError,I=String,k=Math.floor,g=a(f),l=a("".slice),c=a(1 .toFixed),m=function h(C,p,N){return p===0?N:p%2===1?h(C,p-1,N*C):h(C*C,p/2,N)},i=function(C){for(var p=0,N=C;N>=4096;)p+=12,N/=4096;for(;N>=2;)p+=1,N/=2;return p},u=function(C,p,N){for(var V=-1,S=N;++V<6;)S+=p*C[V],C[V]=S%1e7,S=k(S/1e7)},s=function(C,p){for(var N=6,V=0;--N>=0;)V+=C[N],C[N]=k(V/p),V=V%p*1e7},d=function(C){for(var p=6,N="";--p>=0;)if(N!==""||p===0||C[p]!==0){var V=I(C[p]);N=N===""?V:N+g("0",7-V.length)+V}return N},v=b(function(){return c(8e-5,3)!=="0.000"||c(.9,0)!=="1"||c(1.255,2)!=="1.25"||c(0xde0b6b3a7640080,0)!=="1000000000000000128"})||!b(function(){c({})});e({target:"Number",proto:!0,forced:v},{toFixed:function(){function h(C){var p=o(this),N=t(C),V=[0,0,0,0,0,0],S="",B="0",L,w,A,x;if(N<0||N>20)throw new y("Incorrect fraction digits");if(p!==p)return"NaN";if(p<=-1e21||p>=1e21)return I(p);if(p<0&&(S="-",p=-p),p>1e-21)if(L=i(p*m(2,69,1))-69,w=L<0?p*m(2,-L,1):p/m(2,L,1),w*=4503599627370496,L=52-L,L>0){for(u(V,0,w),A=N;A>=7;)u(V,1e7,0),A-=7;for(u(V,m(10,A,1),0),A=L-1;A>=23;)s(V,8388608),A-=23;s(V,1<0?(x=B.length,B=S+(x<=N?"0."+g("0",N-x)+B:l(B,0,x-N)+"."+l(B,x-N))):B=S+B,B}return h}()})},23532:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(40033),o=n(46438),f=a(1 .toPrecision),b=t(function(){return f(1,void 0)!=="1"})||!t(function(){f({})});e({target:"Number",proto:!0,forced:b},{toPrecision:function(){function y(I){return I===void 0?f(o(this)):f(o(this),I)}return y}()})},87119:function(T,r,n){"use strict";var e=n(63964),a=n(41143);e({target:"Object",stat:!0,arity:2,forced:Object.assign!==a},{assign:a})},78618:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(80674);e({target:"Object",stat:!0,sham:!a},{create:t})},27129:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(57377),o=n(10320),f=n(46771),b=n(74595);a&&e({target:"Object",proto:!0,forced:t},{__defineGetter__:function(){function y(I,k){b.f(f(this),I,{get:o(k),enumerable:!0,configurable:!0})}return y}()})},31943:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(24239).f;e({target:"Object",stat:!0,forced:Object.defineProperties!==t,sham:!a},{defineProperties:t})},3579:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(74595).f;e({target:"Object",stat:!0,forced:Object.defineProperty!==t,sham:!a},{defineProperty:t})},97397:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(57377),o=n(10320),f=n(46771),b=n(74595);a&&e({target:"Object",proto:!0,forced:t},{__defineSetter__:function(){function y(I,k){b.f(f(this),I,{set:o(k),enumerable:!0,configurable:!0})}return y}()})},85028:function(T,r,n){"use strict";var e=n(63964),a=n(70915).entries;e({target:"Object",stat:!0},{entries:function(){function t(o){return a(o)}return t}()})},8225:function(T,r,n){"use strict";var e=n(63964),a=n(50730),t=n(40033),o=n(77568),f=n(81969).onFreeze,b=Object.freeze,y=t(function(){b(1)});e({target:"Object",stat:!0,forced:y,sham:!a},{freeze:function(){function I(k){return b&&o(k)?b(f(k)):k}return I}()})},43331:function(T,r,n){"use strict";var e=n(63964),a=n(49450),t=n(60102);e({target:"Object",stat:!0},{fromEntries:function(){function o(f){var b={};return a(f,function(y,I){t(b,y,I)},{AS_ENTRIES:!0}),b}return o}()})},62289:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(57591),o=n(27193).f,f=n(58310),b=!f||a(function(){o(1)});e({target:"Object",stat:!0,forced:b,sham:!f},{getOwnPropertyDescriptor:function(){function y(I,k){return o(t(I),k)}return y}()})},56196:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(97921),o=n(57591),f=n(27193),b=n(60102);e({target:"Object",stat:!0,sham:!a},{getOwnPropertyDescriptors:function(){function y(I){for(var k=o(I),g=f.f,l=t(k),c={},m=0,i,u;l.length>m;)u=g(k,i=l[m++]),u!==void 0&&b(c,i,u);return c}return y}()})},2950:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(81644).f,o=a(function(){return!Object.getOwnPropertyNames(1)});e({target:"Object",stat:!0,forced:o},{getOwnPropertyNames:t})},28603:function(T,r,n){"use strict";var e=n(63964),a=n(52357),t=n(40033),o=n(89235),f=n(46771),b=!a||t(function(){o.f(1)});e({target:"Object",stat:!0,forced:b},{getOwnPropertySymbols:function(){function y(I){var k=o.f;return k?k(f(I)):[]}return y}()})},44205:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(46771),o=n(36917),f=n(9225),b=a(function(){o(1)});e({target:"Object",stat:!0,forced:b,sham:!f},{getPrototypeOf:function(){function y(I){return o(t(I))}return y}()})},83186:function(T,r,n){"use strict";var e=n(63964),a=n(81834);e({target:"Object",stat:!0,forced:Object.isExtensible!==a},{isExtensible:a})},76065:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(77568),o=n(7462),f=n(3782),b=Object.isFrozen,y=f||a(function(){b(1)});e({target:"Object",stat:!0,forced:y},{isFrozen:function(){function I(k){return!t(k)||f&&o(k)==="ArrayBuffer"?!0:b?b(k):!1}return I}()})},13411:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(77568),o=n(7462),f=n(3782),b=Object.isSealed,y=f||a(function(){b(1)});e({target:"Object",stat:!0,forced:y},{isSealed:function(){function I(k){return!t(k)||f&&o(k)==="ArrayBuffer"?!0:b?b(k):!1}return I}()})},76882:function(T,r,n){"use strict";var e=n(63964),a=n(5700);e({target:"Object",stat:!0},{is:a})},26634:function(T,r,n){"use strict";var e=n(63964),a=n(46771),t=n(18450),o=n(40033),f=o(function(){t(1)});e({target:"Object",stat:!0,forced:f},{keys:function(){function b(y){return t(a(y))}return b}()})},53118:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(57377),o=n(46771),f=n(767),b=n(36917),y=n(27193).f;a&&e({target:"Object",proto:!0,forced:t},{__lookupGetter__:function(){function I(k){var g=o(this),l=f(k),c;do if(c=y(g,l))return c.get;while(g=b(g))}return I}()})},42514:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(57377),o=n(46771),f=n(767),b=n(36917),y=n(27193).f;a&&e({target:"Object",proto:!0,forced:t},{__lookupSetter__:function(){function I(k){var g=o(this),l=f(k),c;do if(c=y(g,l))return c.set;while(g=b(g))}return I}()})},84353:function(T,r,n){"use strict";var e=n(63964),a=n(77568),t=n(81969).onFreeze,o=n(50730),f=n(40033),b=Object.preventExtensions,y=f(function(){b(1)});e({target:"Object",stat:!0,forced:y,sham:!o},{preventExtensions:function(){function I(k){return b&&a(k)?b(t(k)):k}return I}()})},62987:function(T,r,n){"use strict";var e=n(63964),a=n(77568),t=n(81969).onFreeze,o=n(50730),f=n(40033),b=Object.seal,y=f(function(){b(1)});e({target:"Object",stat:!0,forced:y,sham:!o},{seal:function(){function I(k){return b&&a(k)?b(t(k)):k}return I}()})},48993:function(T,r,n){"use strict";var e=n(63964),a=n(76649);e({target:"Object",stat:!0},{setPrototypeOf:a})},52917:function(T,r,n){"use strict";var e=n(2650),a=n(55938),t=n(2509);e||a(Object.prototype,"toString",t,{unsafe:!0})},4972:function(T,r,n){"use strict";var e=n(63964),a=n(70915).values;e({target:"Object",stat:!0},{values:function(){function t(o){return a(o)}return t}()})},28913:function(T,r,n){"use strict";var e=n(63964),a=n(28506);e({global:!0,forced:parseFloat!==a},{parseFloat:a})},36382:function(T,r,n){"use strict";var e=n(63964),a=n(13693);e({global:!0,forced:parseInt!==a},{parseInt:a})},48865:function(T,r,n){"use strict";var e=n(63964),a=n(91495),t=n(10320),o=n(81837),f=n(10729),b=n(49450),y=n(48199);e({target:"Promise",stat:!0,forced:y},{all:function(){function I(k){var g=this,l=o.f(g),c=l.resolve,m=l.reject,i=f(function(){var u=t(g.resolve),s=[],d=0,v=1;b(k,function(h){var C=d++,p=!1;v++,a(u,g,h).then(function(N){p||(p=!0,s[C]=N,--v||c(s))},m)}),--v||c(s)});return i.error&&m(i.value),l.promise}return I}()})},70641:function(T,r,n){"use strict";var e=n(63964),a=n(4493),t=n(74854).CONSTRUCTOR,o=n(67512),f=n(4009),b=n(55747),y=n(55938),I=o&&o.prototype;if(e({target:"Promise",proto:!0,forced:t,real:!0},{catch:function(){function g(l){return this.then(void 0,l)}return g}()}),!a&&b(o)){var k=f("Promise").prototype.catch;I.catch!==k&&y(I,"catch",k,{unsafe:!0})}},75946:function(T,r,n){"use strict";var e=n(63964),a=n(4493),t=n(81702),o=n(74685),f=n(91495),b=n(55938),y=n(76649),I=n(84925),k=n(58491),g=n(10320),l=n(55747),c=n(77568),m=n(60077),i=n(28987),u=n(60375).set,s=n(37713),d=n(72259),v=n(10729),h=n(9547),C=n(5419),p=n(67512),N=n(74854),V=n(81837),S="Promise",B=N.CONSTRUCTOR,L=N.REJECTION_EVENT,w=N.SUBCLASSING,A=C.getterFor(S),x=C.set,E=p&&p.prototype,P=p,D=E,M=o.TypeError,R=o.document,O=o.process,F=V.f,_=F,U=!!(R&&R.createEvent&&o.dispatchEvent),z="unhandledrejection",$="rejectionhandled",G=0,X=1,J=2,se=1,ie=2,me,q,re,ae,le=function(be){var Le;return c(be)&&l(Le=be.then)?Le:!1},Z=function(be,Le){var we=Le.value,xe=Le.state===X,Re=xe?be.ok:be.fail,He=be.resolve,ye=be.reject,de=be.domain,he,ke,ve;try{Re?(xe||(Le.rejection===ie&&ce(Le),Le.rejection=se),Re===!0?he=we:(de&&de.enter(),he=Re(we),de&&(de.exit(),ve=!0)),he===be.promise?ye(new M("Promise-chain cycle")):(ke=le(he))?f(ke,he,He,ye):He(he)):ye(we)}catch(Se){de&&!ve&&de.exit(),ye(Se)}},ne=function(be,Le){be.notified||(be.notified=!0,s(function(){for(var we=be.reactions,xe;xe=we.get();)Z(xe,be);be.notified=!1,Le&&!be.rejection&&fe(be)}))},te=function(be,Le,we){var xe,Re;U?(xe=R.createEvent("Event"),xe.promise=Le,xe.reason=we,xe.initEvent(be,!1,!0),o.dispatchEvent(xe)):xe={promise:Le,reason:we},!L&&(Re=o["on"+be])?Re(xe):be===z&&d("Unhandled promise rejection",we)},fe=function(be){f(u,o,function(){var Le=be.facade,we=be.value,xe=pe(be),Re;if(xe&&(Re=v(function(){t?O.emit("unhandledRejection",we,Le):te(z,Le,we)}),be.rejection=t||pe(be)?ie:se,Re.error))throw Re.value})},pe=function(be){return be.rejection!==se&&!be.parent},ce=function(be){f(u,o,function(){var Le=be.facade;t?O.emit("rejectionHandled",Le):te($,Le,be.value)})},Ve=function(be,Le,we){return function(xe){be(Le,xe,we)}},Ce=function(be,Le,we){be.done||(be.done=!0,we&&(be=we),be.value=Le,be.state=J,ne(be,!0))},Ne=function Be(be,Le,we){if(!be.done){be.done=!0,we&&(be=we);try{if(be.facade===Le)throw new M("Promise can't be resolved itself");var xe=le(Le);xe?s(function(){var Re={done:!1};try{f(xe,Le,Ve(Be,Re,be),Ve(Ce,Re,be))}catch(He){Ce(Re,He,be)}}):(be.value=Le,be.state=X,ne(be,!1))}catch(Re){Ce({done:!1},Re,be)}}};if(B&&(P=function(){function Be(be){m(this,D),g(be),f(me,this);var Le=A(this);try{be(Ve(Ne,Le),Ve(Ce,Le))}catch(we){Ce(Le,we)}}return Be}(),D=P.prototype,me=function(){function Be(be){x(this,{type:S,done:!1,notified:!1,parent:!1,reactions:new h,rejection:!1,state:G,value:void 0})}return Be}(),me.prototype=b(D,"then",function(){function Be(be,Le){var we=A(this),xe=F(i(this,P));return we.parent=!0,xe.ok=l(be)?be:!0,xe.fail=l(Le)&&Le,xe.domain=t?O.domain:void 0,we.state===G?we.reactions.add(xe):s(function(){Z(xe,we)}),xe.promise}return Be}()),q=function(){var be=new me,Le=A(be);this.promise=be,this.resolve=Ve(Ne,Le),this.reject=Ve(Ce,Le)},V.f=F=function(be){return be===P||be===re?new q(be):_(be)},!a&&l(p)&&E!==Object.prototype)){ae=E.then,w||b(E,"then",function(){function Be(be,Le){var we=this;return new P(function(xe,Re){f(ae,we,xe,Re)}).then(be,Le)}return Be}(),{unsafe:!0});try{delete E.constructor}catch(Be){}y&&y(E,D)}e({global:!0,constructor:!0,wrap:!0,forced:B},{Promise:P}),I(P,S,!1,!0),k(S)},69861:function(T,r,n){"use strict";var e=n(63964),a=n(4493),t=n(67512),o=n(40033),f=n(4009),b=n(55747),y=n(28987),I=n(66628),k=n(55938),g=t&&t.prototype,l=!!t&&o(function(){g.finally.call({then:function(){function m(){}return m}()},function(){})});if(e({target:"Promise",proto:!0,real:!0,forced:l},{finally:function(){function m(i){var u=y(this,f("Promise")),s=b(i);return this.then(s?function(d){return I(u,i()).then(function(){return d})}:i,s?function(d){return I(u,i()).then(function(){throw d})}:i)}return m}()}),!a&&b(t)){var c=f("Promise").prototype.finally;g.finally!==c&&k(g,"finally",c,{unsafe:!0})}},53092:function(T,r,n){"use strict";n(75946),n(48865),n(70641),n(16937),n(41719),n(59321)},16937:function(T,r,n){"use strict";var e=n(63964),a=n(91495),t=n(10320),o=n(81837),f=n(10729),b=n(49450),y=n(48199);e({target:"Promise",stat:!0,forced:y},{race:function(){function I(k){var g=this,l=o.f(g),c=l.reject,m=f(function(){var i=t(g.resolve);b(k,function(u){a(i,g,u).then(l.resolve,c)})});return m.error&&c(m.value),l.promise}return I}()})},41719:function(T,r,n){"use strict";var e=n(63964),a=n(81837),t=n(74854).CONSTRUCTOR;e({target:"Promise",stat:!0,forced:t},{reject:function(){function o(f){var b=a.f(this),y=b.reject;return y(f),b.promise}return o}()})},59321:function(T,r,n){"use strict";var e=n(63964),a=n(4009),t=n(4493),o=n(67512),f=n(74854).CONSTRUCTOR,b=n(66628),y=a("Promise"),I=t&&!f;e({target:"Promise",stat:!0,forced:t||f},{resolve:function(){function k(g){return b(I&&this===y?o:this,g)}return k}()})},29674:function(T,r,n){"use strict";var e=n(63964),a=n(61267),t=n(10320),o=n(30365),f=n(40033),b=!f(function(){Reflect.apply(function(){})});e({target:"Reflect",stat:!0,forced:b},{apply:function(){function y(I,k,g){return a(t(I),k,o(g))}return y}()})},81543:function(T,r,n){"use strict";var e=n(63964),a=n(4009),t=n(61267),o=n(66284),f=n(32606),b=n(30365),y=n(77568),I=n(80674),k=n(40033),g=a("Reflect","construct"),l=Object.prototype,c=[].push,m=k(function(){function s(){}return!(g(function(){},[],s)instanceof s)}),i=!k(function(){g(function(){})}),u=m||i;e({target:"Reflect",stat:!0,forced:u,sham:u},{construct:function(){function s(d,v){f(d),b(v);var h=arguments.length<3?d:f(arguments[2]);if(i&&!m)return g(d,v,h);if(d===h){switch(v.length){case 0:return new d;case 1:return new d(v[0]);case 2:return new d(v[0],v[1]);case 3:return new d(v[0],v[1],v[2]);case 4:return new d(v[0],v[1],v[2],v[3])}var C=[null];return t(c,C,v),new(t(o,d,C))}var p=h.prototype,N=I(y(p)?p:l),V=t(d,N,v);return y(V)?V:N}return s}()})},9373:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(30365),o=n(767),f=n(74595),b=n(40033),y=b(function(){Reflect.defineProperty(f.f({},1,{value:1}),1,{value:2})});e({target:"Reflect",stat:!0,forced:y,sham:!a},{defineProperty:function(){function I(k,g,l){t(k);var c=o(g);t(l);try{return f.f(k,c,l),!0}catch(m){return!1}}return I}()})},45093:function(T,r,n){"use strict";var e=n(63964),a=n(30365),t=n(27193).f;e({target:"Reflect",stat:!0},{deleteProperty:function(){function o(f,b){var y=t(a(f),b);return y&&!y.configurable?!1:delete f[b]}return o}()})},5815:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(30365),o=n(27193);e({target:"Reflect",stat:!0,sham:!a},{getOwnPropertyDescriptor:function(){function f(b,y){return o.f(t(b),y)}return f}()})},88527:function(T,r,n){"use strict";var e=n(63964),a=n(30365),t=n(36917),o=n(9225);e({target:"Reflect",stat:!0,sham:!o},{getPrototypeOf:function(){function f(b){return t(a(b))}return f}()})},63074:function(T,r,n){"use strict";var e=n(63964),a=n(91495),t=n(77568),o=n(30365),f=n(98373),b=n(27193),y=n(36917);function I(k,g){var l=arguments.length<3?k:arguments[2],c,m;if(o(k)===l)return k[g];if(c=b.f(k,g),c)return f(c)?c.value:c.get===void 0?void 0:a(c.get,l);if(t(m=y(k)))return I(m,g,l)}e({target:"Reflect",stat:!0},{get:I})},66390:function(T,r,n){"use strict";var e=n(63964);e({target:"Reflect",stat:!0},{has:function(){function a(t,o){return o in t}return a}()})},7784:function(T,r,n){"use strict";var e=n(63964),a=n(30365),t=n(81834);e({target:"Reflect",stat:!0},{isExtensible:function(){function o(f){return a(f),t(f)}return o}()})},50551:function(T,r,n){"use strict";var e=n(63964),a=n(97921);e({target:"Reflect",stat:!0},{ownKeys:a})},76483:function(T,r,n){"use strict";var e=n(63964),a=n(4009),t=n(30365),o=n(50730);e({target:"Reflect",stat:!0,sham:!o},{preventExtensions:function(){function f(b){t(b);try{var y=a("Object","preventExtensions");return y&&y(b),!0}catch(I){return!1}}return f}()})},63915:function(T,r,n){"use strict";var e=n(63964),a=n(30365),t=n(35908),o=n(76649);o&&e({target:"Reflect",stat:!0},{setPrototypeOf:function(){function f(b,y){a(b),t(y);try{return o(b,y),!0}catch(I){return!1}}return f}()})},92046:function(T,r,n){"use strict";var e=n(63964),a=n(91495),t=n(30365),o=n(77568),f=n(98373),b=n(40033),y=n(74595),I=n(27193),k=n(36917),g=n(87458);function l(m,i,u){var s=arguments.length<4?m:arguments[3],d=I.f(t(m),i),v,h,C;if(!d){if(o(h=k(m)))return l(h,i,u,s);d=g(0)}if(f(d)){if(d.writable===!1||!o(s))return!1;if(v=I.f(s,i)){if(v.get||v.set||v.writable===!1)return!1;v.value=u,y.f(s,i,v)}else y.f(s,i,g(0,u))}else{if(C=d.set,C===void 0)return!1;a(C,s,u)}return!0}var c=b(function(){var m=function(){},i=y.f(new m,"a",{configurable:!0});return Reflect.set(m.prototype,"a",1,i)!==!1});e({target:"Reflect",stat:!0,forced:c},{set:l})},51454:function(T,r,n){"use strict";var e=n(58310),a=n(74685),t=n(67250),o=n(41314),f=n(5781),b=n(37909),y=n(80674),I=n(37310).f,k=n(21287),g=n(72586),l=n(12605),c=n(73392),m=n(62115),i=n(34550),u=n(55938),s=n(40033),d=n(45299),v=n(5419).enforce,h=n(58491),C=n(24697),p=n(39173),N=n(35688),V=C("match"),S=a.RegExp,B=S.prototype,L=a.SyntaxError,w=t(B.exec),A=t("".charAt),x=t("".replace),E=t("".indexOf),P=t("".slice),D=/^\?<[^\s\d!#%&*+<=>@^][^\s!#%&*+<=>@^]*>/,M=/a/g,R=/a/g,O=new S(M)!==M,F=m.MISSED_STICKY,_=m.UNSUPPORTED_Y,U=e&&(!O||F||p||N||s(function(){return R[V]=!1,S(M)!==M||S(R)===R||String(S(M,"i"))!=="/a/i"})),z=function(ie){for(var me=ie.length,q=0,re="",ae=!1,le;q<=me;q++){if(le=A(ie,q),le==="\\"){re+=le+A(ie,++q);continue}!ae&&le==="."?re+="[\\s\\S]":(le==="["?ae=!0:le==="]"&&(ae=!1),re+=le)}return re},$=function(ie){for(var me=ie.length,q=0,re="",ae=[],le=y(null),Z=!1,ne=!1,te=0,fe="",pe;q<=me;q++){if(pe=A(ie,q),pe==="\\")pe+=A(ie,++q);else if(pe==="]")Z=!1;else if(!Z)switch(!0){case pe==="[":Z=!0;break;case pe==="(":w(D,P(ie,q+1))&&(q+=2,ne=!0),re+=pe,te++;continue;case(pe===">"&&ne):if(fe===""||d(le,fe))throw new L("Invalid capture group name");le[fe]=!0,ae[ae.length]=[fe,te],ne=!1,fe="";continue}ne?fe+=pe:re+=pe}return[re,ae]};if(o("RegExp",U)){for(var G=function(){function se(ie,me){var q=k(B,this),re=g(ie),ae=me===void 0,le=[],Z=ie,ne,te,fe,pe,ce,Ve;if(!q&&re&&ae&&ie.constructor===G)return ie;if((re||k(B,ie))&&(ie=ie.source,ae&&(me=c(Z))),ie=ie===void 0?"":l(ie),me=me===void 0?"":l(me),Z=ie,p&&"dotAll"in M&&(te=!!me&&E(me,"s")>-1,te&&(me=x(me,/s/g,""))),ne=me,F&&"sticky"in M&&(fe=!!me&&E(me,"y")>-1,fe&&_&&(me=x(me,/y/g,""))),N&&(pe=$(ie),ie=pe[0],le=pe[1]),ce=f(S(ie,me),q?this:B,G),(te||fe||le.length)&&(Ve=v(ce),te&&(Ve.dotAll=!0,Ve.raw=G(z(ie),ne)),fe&&(Ve.sticky=!0),le.length&&(Ve.groups=le)),ie!==Z)try{b(ce,"source",Z===""?"(?:)":Z)}catch(Ce){}return ce}return se}(),X=I(S),J=0;X.length>J;)i(G,S,X[J++]);B.constructor=G,G.prototype=B,u(a,"RegExp",G,{constructor:!0})}h("RegExp")},79669:function(T,r,n){"use strict";var e=n(63964),a=n(14489);e({target:"RegExp",proto:!0,forced:/./.exec!==a},{exec:a})},23057:function(T,r,n){"use strict";var e=n(74685),a=n(58310),t=n(73936),o=n(70901),f=n(40033),b=e.RegExp,y=b.prototype,I=a&&f(function(){var k=!0;try{b(".","d")}catch(d){k=!1}var g={},l="",c=k?"dgimsy":"gimsy",m=function(v,h){Object.defineProperty(g,v,{get:function(){function C(){return l+=h,!0}return C}()})},i={dotAll:"s",global:"g",ignoreCase:"i",multiline:"m",sticky:"y"};k&&(i.hasIndices="d");for(var u in i)m(u,i[u]);var s=Object.getOwnPropertyDescriptor(y,"flags").get.call(g);return s!==c||l!==c});I&&t(y,"flags",{configurable:!0,get:o})},57983:function(T,r,n){"use strict";var e=n(70520).PROPER,a=n(55938),t=n(30365),o=n(12605),f=n(40033),b=n(73392),y="toString",I=RegExp.prototype,k=I[y],g=f(function(){return k.call({source:"a",flags:"b"})!=="/a/b"}),l=e&&k.name!==y;(g||l)&&a(I,y,function(){function c(){var m=t(this),i=o(m.source),u=o(b(m));return"/"+i+"/"+u}return c}(),{unsafe:!0})},1963:function(T,r,n){"use strict";var e=n(45150),a=n(41028);e("Set",function(t){return function(){function o(){return t(this,arguments.length?arguments[0]:void 0)}return o}()},a)},17953:function(T,r,n){"use strict";n(1963)},95309:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("anchor")},{anchor:function(){function o(f){return a(this,"a","name",f)}return o}()})},82256:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("big")},{big:function(){function o(){return a(this,"big","","")}return o}()})},49484:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("blink")},{blink:function(){function o(){return a(this,"blink","","")}return o}()})},38931:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("bold")},{bold:function(){function o(){return a(this,"b","","")}return o}()})},30442:function(T,r,n){"use strict";var e=n(63964),a=n(50233).codeAt;e({target:"String",proto:!0},{codePointAt:function(){function t(o){return a(this,o)}return t}()})},6403:function(T,r,n){"use strict";var e=n(63964),a=n(71138),t=n(27193).f,o=n(10188),f=n(12605),b=n(86213),y=n(16952),I=n(45490),k=n(4493),g=a("".slice),l=Math.min,c=I("endsWith"),m=!k&&!c&&!!function(){var i=t(String.prototype,"endsWith");return i&&!i.writable}();e({target:"String",proto:!0,forced:!m&&!c},{endsWith:function(){function i(u){var s=f(y(this));b(u);var d=arguments.length>1?arguments[1]:void 0,v=s.length,h=d===void 0?v:l(o(d),v),C=f(u);return g(s,h-C.length,h)===C}return i}()})},39308:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("fixed")},{fixed:function(){function o(){return a(this,"tt","","")}return o}()})},91550:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("fontcolor")},{fontcolor:function(){function o(f){return a(this,"font","color",f)}return o}()})},75008:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("fontsize")},{fontsize:function(){function o(f){return a(this,"font","size",f)}return o}()})},9867:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(13912),o=RangeError,f=String.fromCharCode,b=String.fromCodePoint,y=a([].join),I=!!b&&b.length!==1;e({target:"String",stat:!0,arity:1,forced:I},{fromCodePoint:function(){function k(g){for(var l=[],c=arguments.length,m=0,i;c>m;){if(i=+arguments[m++],t(i,1114111)!==i)throw new o(i+" is not a valid code point");l[m]=i<65536?f(i):f(((i-=65536)>>10)+55296,i%1024+56320)}return y(l,"")}return k}()})},43673:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(86213),o=n(16952),f=n(12605),b=n(45490),y=a("".indexOf);e({target:"String",proto:!0,forced:!b("includes")},{includes:function(){function I(k){return!!~y(f(o(this)),f(t(k)),arguments.length>1?arguments[1]:void 0)}return I}()})},56027:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("italics")},{italics:function(){function o(){return a(this,"i","","")}return o}()})},12354:function(T,r,n){"use strict";var e=n(50233).charAt,a=n(12605),t=n(5419),o=n(65574),f=n(5959),b="String Iterator",y=t.set,I=t.getterFor(b);o(String,"String",function(k){y(this,{type:b,string:a(k),index:0})},function(){function k(){var g=I(this),l=g.string,c=g.index,m;return c>=l.length?f(void 0,!0):(m=e(l,c),g.index+=m.length,f(m,!1))}return k}())},50340:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("link")},{link:function(){function o(f){return a(this,"a","href",f)}return o}()})},22515:function(T,r,n){"use strict";var e=n(91495),a=n(79942),t=n(30365),o=n(42871),f=n(10188),b=n(12605),y=n(16952),I=n(78060),k=n(35483),g=n(28340);a("match",function(l,c,m){return[function(){function i(u){var s=y(this),d=o(u)?void 0:I(u,l);return d?e(d,u,s):new RegExp(u)[l](b(s))}return i}(),function(i){var u=t(this),s=b(i),d=m(c,u,s);if(d.done)return d.value;if(!u.global)return g(u,s);var v=u.unicode;u.lastIndex=0;for(var h=[],C=0,p;(p=g(u,s))!==null;){var N=b(p[0]);h[C]=N,N===""&&(u.lastIndex=k(s,f(u.lastIndex),v)),C++}return C===0?null:h}]})},5143:function(T,r,n){"use strict";var e=n(63964),a=n(24051).end,t=n(34125);e({target:"String",proto:!0,forced:t},{padEnd:function(){function o(f){return a(this,f,arguments.length>1?arguments[1]:void 0)}return o}()})},93514:function(T,r,n){"use strict";var e=n(63964),a=n(24051).start,t=n(34125);e({target:"String",proto:!0,forced:t},{padStart:function(){function o(f){return a(this,f,arguments.length>1?arguments[1]:void 0)}return o}()})},5416:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(57591),o=n(46771),f=n(12605),b=n(24760),y=a([].push),I=a([].join);e({target:"String",stat:!0},{raw:function(){function k(g){var l=t(o(g).raw),c=b(l);if(!c)return"";for(var m=arguments.length,i=[],u=0;;){if(y(i,f(l[u++])),u===c)return I(i,"");u")!=="7"});o("replace",function(x,E,P){var D=w?"$":"$0";return[function(){function M(R,O){var F=c(this),_=I(R)?void 0:i(R,v);return _?a(_,R,F,O):a(E,l(F),R,O)}return M}(),function(M,R){var O=b(this),F=l(M);if(typeof R=="string"&&V(R,D)===-1&&V(R,"$<")===-1){var _=P(E,O,F,R);if(_.done)return _.value}var U=y(R);U||(R=l(R));var z=O.global,$;z&&($=O.unicode,O.lastIndex=0);for(var G=[],X;X=s(O,F),!(X===null||(N(G,X),!z));){var J=l(X[0]);J===""&&(O.lastIndex=m(F,g(O.lastIndex),$))}for(var se="",ie=0,me=0;me=ie&&(se+=S(F,ie,re)+le,ie=re+q.length)}return se+S(F,ie)}]},!A||!L||w)},63272:function(T,r,n){"use strict";var e=n(91495),a=n(79942),t=n(30365),o=n(42871),f=n(16952),b=n(5700),y=n(12605),I=n(78060),k=n(28340);a("search",function(g,l,c){return[function(){function m(i){var u=f(this),s=o(i)?void 0:I(i,g);return s?e(s,i,u):new RegExp(i)[g](y(u))}return m}(),function(m){var i=t(this),u=y(m),s=c(l,i,u);if(s.done)return s.value;var d=i.lastIndex;b(d,0)||(i.lastIndex=0);var v=k(i,u);return b(i.lastIndex,d)||(i.lastIndex=d),v===null?-1:v.index}]})},34325:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("small")},{small:function(){function o(){return a(this,"small","","")}return o}()})},39930:function(T,r,n){"use strict";var e=n(91495),a=n(67250),t=n(79942),o=n(30365),f=n(42871),b=n(16952),y=n(28987),I=n(35483),k=n(10188),g=n(12605),l=n(78060),c=n(28340),m=n(62115),i=n(40033),u=m.UNSUPPORTED_Y,s=4294967295,d=Math.min,v=a([].push),h=a("".slice),C=!i(function(){var N=/(?:)/,V=N.exec;N.exec=function(){return V.apply(this,arguments)};var S="ab".split(N);return S.length!==2||S[0]!=="a"||S[1]!=="b"}),p="abbc".split(/(b)*/)[1]==="c"||"test".split(/(?:)/,-1).length!==4||"ab".split(/(?:ab)*/).length!==2||".".split(/(.?)(.?)/).length!==4||".".split(/()()/).length>1||"".split(/.?/).length;t("split",function(N,V,S){var B="0".split(void 0,0).length?function(L,w){return L===void 0&&w===0?[]:e(V,this,L,w)}:V;return[function(){function L(w,A){var x=b(this),E=f(w)?void 0:l(w,N);return E?e(E,w,x,A):e(B,g(x),w,A)}return L}(),function(L,w){var A=o(this),x=g(L);if(!p){var E=S(B,A,x,w,B!==V);if(E.done)return E.value}var P=y(A,RegExp),D=A.unicode,M=(A.ignoreCase?"i":"")+(A.multiline?"m":"")+(A.unicode?"u":"")+(u?"g":"y"),R=new P(u?"^(?:"+A.source+")":A,M),O=w===void 0?s:w>>>0;if(O===0)return[];if(x.length===0)return c(R,x)===null?[x]:[];for(var F=0,_=0,U=[];_1?arguments[1]:void 0,s.length)),v=f(u);return g(s,d,d+v.length)===v}return i}()})},74498:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("strike")},{strike:function(){function o(){return a(this,"strike","","")}return o}()})},15812:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("sub")},{sub:function(){function o(){return a(this,"sub","","")}return o}()})},57726:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("sup")},{sup:function(){function o(){return a(this,"sup","","")}return o}()})},70604:function(T,r,n){"use strict";n(99159);var e=n(63964),a=n(43476);e({target:"String",proto:!0,name:"trimEnd",forced:"".trimEnd!==a},{trimEnd:a})},85404:function(T,r,n){"use strict";var e=n(63964),a=n(43885);e({target:"String",proto:!0,name:"trimStart",forced:"".trimLeft!==a},{trimLeft:a})},99159:function(T,r,n){"use strict";var e=n(63964),a=n(43476);e({target:"String",proto:!0,name:"trimEnd",forced:"".trimRight!==a},{trimRight:a})},34965:function(T,r,n){"use strict";n(85404);var e=n(63964),a=n(43885);e({target:"String",proto:!0,name:"trimStart",forced:"".trimStart!==a},{trimStart:a})},8448:function(T,r,n){"use strict";var e=n(63964),a=n(92648).trim,t=n(90012);e({target:"String",proto:!0,forced:t("trim")},{trim:function(){function o(){return a(this)}return o}()})},79250:function(T,r,n){"use strict";var e=n(85889);e("asyncIterator")},49899:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(91495),o=n(67250),f=n(4493),b=n(58310),y=n(52357),I=n(40033),k=n(45299),g=n(21287),l=n(30365),c=n(57591),m=n(767),i=n(12605),u=n(87458),s=n(80674),d=n(18450),v=n(37310),h=n(81644),C=n(89235),p=n(27193),N=n(74595),V=n(24239),S=n(12867),B=n(55938),L=n(73936),w=n(16639),A=n(19417),x=n(79195),E=n(16738),P=n(24697),D=n(55557),M=n(85889),R=n(52360),O=n(84925),F=n(5419),_=n(22603).forEach,U=A("hidden"),z="Symbol",$="prototype",G=F.set,X=F.getterFor(z),J=Object[$],se=a.Symbol,ie=se&&se[$],me=a.RangeError,q=a.TypeError,re=a.QObject,ae=p.f,le=N.f,Z=h.f,ne=S.f,te=o([].push),fe=w("symbols"),pe=w("op-symbols"),ce=w("wks"),Ve=!re||!re[$]||!re[$].findChild,Ce=function(he,ke,ve){var Se=ae(J,ke);Se&&delete J[ke],le(he,ke,ve),Se&&he!==J&&le(J,ke,Se)},Ne=b&&I(function(){return s(le({},"a",{get:function(){function de(){return le(this,"a",{value:7}).a}return de}()})).a!==7})?Ce:le,Be=function(he,ke){var ve=fe[he]=s(ie);return G(ve,{type:z,tag:he,description:ke}),b||(ve.description=ke),ve},be=function(){function de(he,ke,ve){he===J&&be(pe,ke,ve),l(he);var Se=m(ke);return l(ve),k(fe,Se)?(ve.enumerable?(k(he,U)&&he[U][Se]&&(he[U][Se]=!1),ve=s(ve,{enumerable:u(0,!1)})):(k(he,U)||le(he,U,u(1,s(null))),he[U][Se]=!0),Ne(he,Se,ve)):le(he,Se,ve)}return de}(),Le=function(){function de(he,ke){l(he);var ve=c(ke),Se=d(ve).concat(ye(ve));return _(Se,function(Pe){(!b||t(xe,ve,Pe))&&be(he,Pe,ve[Pe])}),he}return de}(),we=function(){function de(he,ke){return ke===void 0?s(he):Le(s(he),ke)}return de}(),xe=function(){function de(he){var ke=m(he),ve=t(ne,this,ke);return this===J&&k(fe,ke)&&!k(pe,ke)?!1:ve||!k(this,ke)||!k(fe,ke)||k(this,U)&&this[U][ke]?ve:!0}return de}(),Re=function(){function de(he,ke){var ve=c(he),Se=m(ke);if(!(ve===J&&k(fe,Se)&&!k(pe,Se))){var Pe=ae(ve,Se);return Pe&&k(fe,Se)&&!(k(ve,U)&&ve[U][Se])&&(Pe.enumerable=!0),Pe}}return de}(),He=function(){function de(he){var ke=Z(c(he)),ve=[];return _(ke,function(Se){!k(fe,Se)&&!k(x,Se)&&te(ve,Se)}),ve}return de}(),ye=function(he){var ke=he===J,ve=Z(ke?pe:c(he)),Se=[];return _(ve,function(Pe){k(fe,Pe)&&(!ke||k(J,Pe))&&te(Se,fe[Pe])}),Se};y||(se=function(){function de(){if(g(ie,this))throw new q("Symbol is not a constructor");var he=!arguments.length||arguments[0]===void 0?void 0:i(arguments[0]),ke=E(he),ve=function(){function Se(Pe){var je=this===void 0?a:this;je===J&&t(Se,pe,Pe),k(je,U)&&k(je[U],ke)&&(je[U][ke]=!1);var Fe=u(1,Pe);try{Ne(je,ke,Fe)}catch(ze){if(!(ze instanceof me))throw ze;Ce(je,ke,Fe)}}return Se}();return b&&Ve&&Ne(J,ke,{configurable:!0,set:ve}),Be(ke,he)}return de}(),ie=se[$],B(ie,"toString",function(){function de(){return X(this).tag}return de}()),B(se,"withoutSetter",function(de){return Be(E(de),de)}),S.f=xe,N.f=be,V.f=Le,p.f=Re,v.f=h.f=He,C.f=ye,D.f=function(de){return Be(P(de),de)},b&&(L(ie,"description",{configurable:!0,get:function(){function de(){return X(this).description}return de}()}),f||B(J,"propertyIsEnumerable",xe,{unsafe:!0}))),e({global:!0,constructor:!0,wrap:!0,forced:!y,sham:!y},{Symbol:se}),_(d(ce),function(de){M(de)}),e({target:z,stat:!0,forced:!y},{useSetter:function(){function de(){Ve=!0}return de}(),useSimple:function(){function de(){Ve=!1}return de}()}),e({target:"Object",stat:!0,forced:!y,sham:!b},{create:we,defineProperty:be,defineProperties:Le,getOwnPropertyDescriptor:Re}),e({target:"Object",stat:!0,forced:!y},{getOwnPropertyNames:He}),R(),O(se,z),x[U]=!0},10933:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(74685),o=n(67250),f=n(45299),b=n(55747),y=n(21287),I=n(12605),k=n(73936),g=n(5774),l=t.Symbol,c=l&&l.prototype;if(a&&b(l)&&(!("description"in c)||l().description!==void 0)){var m={},i=function(){function p(){var N=arguments.length<1||arguments[0]===void 0?void 0:I(arguments[0]),V=y(c,this)?new l(N):N===void 0?l():l(N);return N===""&&(m[V]=!0),V}return p}();g(i,l),i.prototype=c,c.constructor=i;var u=String(l("description detection"))==="Symbol(description detection)",s=o(c.valueOf),d=o(c.toString),v=/^Symbol\((.*)\)[^)]+$/,h=o("".replace),C=o("".slice);k(c,"description",{configurable:!0,get:function(){function p(){var N=s(this);if(f(m,N))return"";var V=d(N),S=u?C(V,7,-1):h(V,v,"$1");return S===""?void 0:S}return p}()}),e({global:!0,constructor:!0,forced:!0},{Symbol:i})}},30828:function(T,r,n){"use strict";var e=n(63964),a=n(4009),t=n(45299),o=n(12605),f=n(16639),b=n(66570),y=f("string-to-symbol-registry"),I=f("symbol-to-string-registry");e({target:"Symbol",stat:!0,forced:!b},{for:function(){function k(g){var l=o(g);if(t(y,l))return y[l];var c=a("Symbol")(l);return y[l]=c,I[c]=l,c}return k}()})},53795:function(T,r,n){"use strict";var e=n(85889);e("hasInstance")},87806:function(T,r,n){"use strict";var e=n(85889);e("isConcatSpreadable")},64677:function(T,r,n){"use strict";var e=n(85889);e("iterator")},33313:function(T,r,n){"use strict";n(49899),n(30828),n(6862),n(53008),n(28603)},6862:function(T,r,n){"use strict";var e=n(63964),a=n(45299),t=n(71399),o=n(89393),f=n(16639),b=n(66570),y=f("symbol-to-string-registry");e({target:"Symbol",stat:!0,forced:!b},{keyFor:function(){function I(k){if(!t(k))throw new TypeError(o(k)+" is not a symbol");if(a(y,k))return y[k]}return I}()})},48058:function(T,r,n){"use strict";var e=n(85889);e("match")},51583:function(T,r,n){"use strict";var e=n(85889);e("replace")},82403:function(T,r,n){"use strict";var e=n(85889);e("search")},34265:function(T,r,n){"use strict";var e=n(85889);e("species")},3295:function(T,r,n){"use strict";var e=n(85889);e("split")},1078:function(T,r,n){"use strict";var e=n(85889),a=n(52360);e("toPrimitive"),a()},63207:function(T,r,n){"use strict";var e=n(4009),a=n(85889),t=n(84925);a("toStringTag"),t(e("Symbol"),"Symbol")},80520:function(T,r,n){"use strict";var e=n(85889);e("unscopables")},99872:function(T,r,n){"use strict";var e=n(67250),a=n(4246),t=n(71447),o=e(t),f=a.aTypedArray,b=a.exportTypedArrayMethod;b("copyWithin",function(){function y(I,k){return o(f(this),I,k,arguments.length>2?arguments[2]:void 0)}return y}())},73364:function(T,r,n){"use strict";var e=n(4246),a=n(22603).every,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("every",function(){function f(b){return a(t(this),b,arguments.length>1?arguments[1]:void 0)}return f}())},58166:function(T,r,n){"use strict";var e=n(4246),a=n(88471),t=n(61484),o=n(2281),f=n(91495),b=n(67250),y=n(40033),I=e.aTypedArray,k=e.exportTypedArrayMethod,g=b("".slice),l=y(function(){var c=0;return new Int8Array(2).fill({valueOf:function(){function m(){return c++}return m}()}),c!==1});k("fill",function(){function c(m){var i=arguments.length;I(this);var u=g(o(this),0,3)==="Big"?t(m):+m;return f(a,this,u,i>1?arguments[1]:void 0,i>2?arguments[2]:void 0)}return c}(),l)},23793:function(T,r,n){"use strict";var e=n(4246),a=n(22603).filter,t=n(45399),o=e.aTypedArray,f=e.exportTypedArrayMethod;f("filter",function(){function b(y){var I=a(o(this),y,arguments.length>1?arguments[1]:void 0);return t(this,I)}return b}())},13917:function(T,r,n){"use strict";var e=n(4246),a=n(22603).findIndex,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("findIndex",function(){function f(b){return a(t(this),b,arguments.length>1?arguments[1]:void 0)}return f}())},43820:function(T,r,n){"use strict";var e=n(4246),a=n(22603).find,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("find",function(){function f(b){return a(t(this),b,arguments.length>1?arguments[1]:void 0)}return f}())},80756:function(T,r,n){"use strict";var e=n(80185);e("Float32",function(a){return function(){function t(o,f,b){return a(this,o,f,b)}return t}()})},70567:function(T,r,n){"use strict";var e=n(80185);e("Float64",function(a){return function(){function t(o,f,b){return a(this,o,f,b)}return t}()})},19852:function(T,r,n){"use strict";var e=n(4246),a=n(22603).forEach,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("forEach",function(){function f(b){a(t(this),b,arguments.length>1?arguments[1]:void 0)}return f}())},40379:function(T,r,n){"use strict";var e=n(86563),a=n(4246).exportTypedArrayStaticMethod,t=n(3805);a("from",t,e)},92770:function(T,r,n){"use strict";var e=n(4246),a=n(14211).includes,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("includes",function(){function f(b){return a(t(this),b,arguments.length>1?arguments[1]:void 0)}return f}())},81069:function(T,r,n){"use strict";var e=n(4246),a=n(14211).indexOf,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("indexOf",function(){function f(b){return a(t(this),b,arguments.length>1?arguments[1]:void 0)}return f}())},60037:function(T,r,n){"use strict";var e=n(80185);e("Int16",function(a){return function(){function t(o,f,b){return a(this,o,f,b)}return t}()})},44195:function(T,r,n){"use strict";var e=n(80185);e("Int32",function(a){return function(){function t(o,f,b){return a(this,o,f,b)}return t}()})},66756:function(T,r,n){"use strict";var e=n(80185);e("Int8",function(a){return function(){function t(o,f,b){return a(this,o,f,b)}return t}()})},63689:function(T,r,n){"use strict";var e=n(74685),a=n(40033),t=n(67250),o=n(4246),f=n(34570),b=n(24697),y=b("iterator"),I=e.Uint8Array,k=t(f.values),g=t(f.keys),l=t(f.entries),c=o.aTypedArray,m=o.exportTypedArrayMethod,i=I&&I.prototype,u=!a(function(){i[y].call([1])}),s=!!i&&i.values&&i[y]===i.values&&i.values.name==="values",d=function(){function v(){return k(c(this))}return v}();m("entries",function(){function v(){return l(c(this))}return v}(),u),m("keys",function(){function v(){return g(c(this))}return v}(),u),m("values",d,u||!s,{name:"values"}),m(y,d,u||!s,{name:"values"})},5659:function(T,r,n){"use strict";var e=n(4246),a=n(67250),t=e.aTypedArray,o=e.exportTypedArrayMethod,f=a([].join);o("join",function(){function b(y){return f(t(this),y)}return b}())},25014:function(T,r,n){"use strict";var e=n(4246),a=n(61267),t=n(1325),o=e.aTypedArray,f=e.exportTypedArrayMethod;f("lastIndexOf",function(){function b(y){var I=arguments.length;return a(t,o(this),I>1?[y,arguments[1]]:[y])}return b}())},32189:function(T,r,n){"use strict";var e=n(4246),a=n(22603).map,t=n(31082),o=e.aTypedArray,f=e.exportTypedArrayMethod;f("map",function(){function b(y){return a(o(this),y,arguments.length>1?arguments[1]:void 0,function(I,k){return new(t(I))(k)})}return b}())},23030:function(T,r,n){"use strict";var e=n(4246),a=n(86563),t=e.aTypedArrayConstructor,o=e.exportTypedArrayStaticMethod;o("of",function(){function f(){for(var b=0,y=arguments.length,I=new(t(this))(y);y>b;)I[b]=arguments[b++];return I}return f}(),a)},49110:function(T,r,n){"use strict";var e=n(4246),a=n(56844).right,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("reduceRight",function(){function f(b){var y=arguments.length;return a(t(this),b,y,y>1?arguments[1]:void 0)}return f}())},24309:function(T,r,n){"use strict";var e=n(4246),a=n(56844).left,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("reduce",function(){function f(b){var y=arguments.length;return a(t(this),b,y,y>1?arguments[1]:void 0)}return f}())},56445:function(T,r,n){"use strict";var e=n(4246),a=e.aTypedArray,t=e.exportTypedArrayMethod,o=Math.floor;t("reverse",function(){function f(){for(var b=this,y=a(b).length,I=o(y/2),k=0,g;k1?arguments[1]:void 0,1),h=b(d);if(i)return a(l,this,h,v);var C=this.length,p=o(h),N=0;if(p+v>C)throw new I("Wrong length");for(;Nm;)u[m]=l[m++];return u}return I}(),y)},88739:function(T,r,n){"use strict";var e=n(4246),a=n(22603).some,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("some",function(){function f(b){return a(t(this),b,arguments.length>1?arguments[1]:void 0)}return f}())},60415:function(T,r,n){"use strict";var e=n(74685),a=n(71138),t=n(40033),o=n(10320),f=n(90274),b=n(4246),y=n(652),I=n(19228),k=n(5026),g=n(9342),l=b.aTypedArray,c=b.exportTypedArrayMethod,m=e.Uint16Array,i=m&&a(m.prototype.sort),u=!!i&&!(t(function(){i(new m(2),null)})&&t(function(){i(new m(2),{})})),s=!!i&&!t(function(){if(k)return k<74;if(y)return y<67;if(I)return!0;if(g)return g<602;var v=new m(516),h=Array(516),C,p;for(C=0;C<516;C++)p=C%4,v[C]=515-C,h[C]=C-2*p+3;for(i(v,function(N,V){return(N/4|0)-(V/4|0)}),C=0;C<516;C++)if(v[C]!==h[C])return!0}),d=function(h){return function(C,p){return h!==void 0?+h(C,p)||0:p!==p?-1:C!==C?1:C===0&&p===0?1/C>0&&1/p<0?1:-1:C>p}};c("sort",function(){function v(h){return h!==void 0&&o(h),s?i(this,h):f(l(this),d(h))}return v}(),!s||u)},72532:function(T,r,n){"use strict";var e=n(4246),a=n(10188),t=n(13912),o=n(31082),f=e.aTypedArray,b=e.exportTypedArrayMethod;b("subarray",function(){function y(I,k){var g=f(this),l=g.length,c=t(I,l),m=o(g);return new m(g.buffer,g.byteOffset+c*g.BYTES_PER_ELEMENT,a((k===void 0?l:t(k,l))-c))}return y}())},62207:function(T,r,n){"use strict";var e=n(74685),a=n(61267),t=n(4246),o=n(40033),f=n(54602),b=e.Int8Array,y=t.aTypedArray,I=t.exportTypedArrayMethod,k=[].toLocaleString,g=!!b&&o(function(){k.call(new b(1))}),l=o(function(){return[1,2].toLocaleString()!==new b([1,2]).toLocaleString()})||!o(function(){b.prototype.toLocaleString.call([1,2])});I("toLocaleString",function(){function c(){return a(k,g?f(y(this)):y(this),f(arguments))}return c}(),l)},906:function(T,r,n){"use strict";var e=n(4246).exportTypedArrayMethod,a=n(40033),t=n(74685),o=n(67250),f=t.Uint8Array,b=f&&f.prototype||{},y=[].toString,I=o([].join);a(function(){y.call({})})&&(y=function(){function g(){return I(this)}return g}());var k=b.toString!==y;e("toString",y,k)},78824:function(T,r,n){"use strict";var e=n(80185);e("Uint16",function(a){return function(){function t(o,f,b){return a(this,o,f,b)}return t}()})},72846:function(T,r,n){"use strict";var e=n(80185);e("Uint32",function(a){return function(){function t(o,f,b){return a(this,o,f,b)}return t}()})},24575:function(T,r,n){"use strict";var e=n(80185);e("Uint8",function(a){return function(){function t(o,f,b){return a(this,o,f,b)}return t}()})},71968:function(T,r,n){"use strict";var e=n(80185);e("Uint8",function(a){return function(){function t(o,f,b){return a(this,o,f,b)}return t}()},!0)},80040:function(T,r,n){"use strict";var e=n(50730),a=n(74685),t=n(67250),o=n(30145),f=n(81969),b=n(45150),y=n(39895),I=n(77568),k=n(5419).enforce,g=n(40033),l=n(21820),c=Object,m=Array.isArray,i=c.isExtensible,u=c.isFrozen,s=c.isSealed,d=c.freeze,v=c.seal,h=!a.ActiveXObject&&"ActiveXObject"in a,C,p=function(E){return function(){function P(){return E(this,arguments.length?arguments[0]:void 0)}return P}()},N=b("WeakMap",p,y),V=N.prototype,S=t(V.set),B=function(){return e&&g(function(){var E=d([]);return S(new N,E,1),!u(E)})};if(l)if(h){C=y.getConstructor(p,"WeakMap",!0),f.enable();var L=t(V.delete),w=t(V.has),A=t(V.get);o(V,{delete:function(){function x(E){if(I(E)&&!i(E)){var P=k(this);return P.frozen||(P.frozen=new C),L(this,E)||P.frozen.delete(E)}return L(this,E)}return x}(),has:function(){function x(E){if(I(E)&&!i(E)){var P=k(this);return P.frozen||(P.frozen=new C),w(this,E)||P.frozen.has(E)}return w(this,E)}return x}(),get:function(){function x(E){if(I(E)&&!i(E)){var P=k(this);return P.frozen||(P.frozen=new C),w(this,E)?A(this,E):P.frozen.get(E)}return A(this,E)}return x}(),set:function(){function x(E,P){if(I(E)&&!i(E)){var D=k(this);D.frozen||(D.frozen=new C),w(this,E)?S(this,E,P):D.frozen.set(E,P)}else S(this,E,P);return this}return x}()})}else B()&&o(V,{set:function(){function x(E,P){var D;return m(E)&&(u(E)?D=d:s(E)&&(D=v)),S(this,E,P),D&&D(E),this}return x}()})},90846:function(T,r,n){"use strict";n(80040)},67042:function(T,r,n){"use strict";var e=n(45150),a=n(39895);e("WeakSet",function(t){return function(){function o(){return t(this,arguments.length?arguments[0]:void 0)}return o}()},a)},40348:function(T,r,n){"use strict";n(67042)},5606:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(60375).clear;e({global:!0,bind:!0,enumerable:!0,forced:a.clearImmediate!==t},{clearImmediate:t})},83006:function(T,r,n){"use strict";n(5606),n(27807)},25764:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(37713),o=n(10320),f=n(24986),b=n(40033),y=n(58310),I=b(function(){return y&&Object.getOwnPropertyDescriptor(a,"queueMicrotask").value.length!==1});e({global:!0,enumerable:!0,dontCallGetSet:!0,forced:I},{queueMicrotask:function(){function k(g){f(arguments.length,1),t(o(g))}return k}()})},27807:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(60375).set,o=n(78362),f=a.setImmediate?o(t,!1):t;e({global:!0,bind:!0,enumerable:!0,forced:a.setImmediate!==f},{setImmediate:f})},45569:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(78362),o=t(a.setInterval,!0);e({global:!0,bind:!0,forced:a.setInterval!==o},{setInterval:o})},5213:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(78362),o=t(a.setTimeout,!0);e({global:!0,bind:!0,forced:a.setTimeout!==o},{setTimeout:o})},69401:function(T,r,n){"use strict";n(45569),n(5213)},7435:function(T){"use strict";/** * @file * @copyright 2020 Aleksej Komarov @@ -352,3 +637,14 @@ * @copyright 2020 Aleksej Komarov * @license MIT */r.perf.mark("inception",(y=window.performance)==null||(y=y.timing)==null?void 0:y.navigationStart),r.perf.mark("init");var I=(0,f.configureStore)(),k=(0,o.createRenderer)(function(){(0,a.loadIconRefMap)();var l=Y(71253),c=l.getRoutedComponent,m=c(I);return(0,T.createComponentVNode)(2,f.StoreProvider,{store:I,children:(0,T.createComponentVNode)(2,m)})}),g=function l(){if(document.readyState==="loading"){document.addEventListener("DOMContentLoaded",l);return}(0,b.setupGlobalEvents)(),(0,e.setupHotKeys)(),(0,t.captureExternalLinks)(),I.subscribe(k),Byond.subscribe(function(c,m){return I.dispatch({type:c,payload:m})})};g()}()})();})(); +======= + */var t=r.BoxWithSampleText=function(){function o(p){return(0,e.normalizeProps)((0,e.createComponentVNode)(2,a.Box,Object.assign({},p,{children:[(0,e.createComponentVNode)(2,a.Box,{italic:!0,children:"Jackdaws love my big sphinx of quartz."}),(0,e.createComponentVNode)(2,a.Box,{mt:1,bold:!0,children:"The wide electrification of the southern provinces will give a powerful impetus to the growth of agriculture."})]})))}return o}()},67160:function(){},23542:function(){},30386:function(){},98996:function(){},50578:function(){},4444:function(){},77870:function(){},23632:function(){},56492:function(){},39108:function(){},11714:function(){},73492:function(){},49641:function(){},17570:function(){},61858:function(){},32882:function(){},70752:function(T,r,n){var e={"./pai_atmosphere.js":80818,"./pai_bioscan.js":23903,"./pai_directives.js":64988,"./pai_doorjack.js":13813,"./pai_main_menu.js":66025,"./pai_manifest.js":2983,"./pai_medrecords.js":40758,"./pai_messenger.js":98599,"./pai_radio.js":50775,"./pai_secrecords.js":48623,"./pai_signaler.js":47297};function a(o){var p=t(o);return n(p)}function t(o){if(!n.o(e,o)){var p=new Error("Cannot find module '"+o+"'");throw p.code="MODULE_NOT_FOUND",p}return e[o]}a.keys=function(){return Object.keys(e)},a.resolve=t,T.exports=a,a.id=70752},59395:function(T,r,n){var e={"./pda_atmos_scan.js":78532,"./pda_games.js":2395,"./pda_janitor.js":40253,"./pda_main_menu.js":58293,"./pda_manifest.js":58059,"./pda_medical.js":18147,"./pda_messenger.js":77595,"./pda_minesweeper.js":90382,"./pda_mule.js":24635,"./pda_nanobank.js":23734,"./pda_notes.js":97085,"./pda_power.js":57513,"./pda_secbot.js":99808,"./pda_security.js":77168,"./pda_signaler.js":21773,"./pda_status_display.js":81857,"./pda_supplyrecords.js":70287};function a(o){var p=t(o);return n(p)}function t(o){if(!n.o(e,o)){var p=new Error("Cannot find module '"+o+"'");throw p.code="MODULE_NOT_FOUND",p}return e[o]}a.keys=function(){return Object.keys(e)},a.resolve=t,T.exports=a,a.id=59395},32054:function(T,r,n){var e={"./AICard":1090,"./AICard.js":1090,"./AIFixer":39454,"./AIFixer.js":39454,"./APC":88422,"./APC.js":88422,"./ATM":99660,"./ATM.js":99660,"./AccountsUplinkTerminal":86423,"./AccountsUplinkTerminal.js":86423,"./AgentCard":39683,"./AgentCard.tsx":39683,"./AiAirlock":56793,"./AiAirlock.js":56793,"./AirAlarm":72475,"./AirAlarm.js":72475,"./AirlockAccessController":12333,"./AirlockAccessController.js":12333,"./AirlockElectronics":28736,"./AirlockElectronics.js":28736,"./AlertModal":47365,"./AlertModal.tsx":47365,"./AppearanceChanger":71824,"./AppearanceChanger.js":71824,"./AtmosAlertConsole":72285,"./AtmosAlertConsole.js":72285,"./AtmosControl":65805,"./AtmosControl.js":65805,"./AtmosFilter":87816,"./AtmosFilter.js":87816,"./AtmosMixer":52977,"./AtmosMixer.js":52977,"./AtmosPump":11748,"./AtmosPump.js":11748,"./AtmosTankControl":69321,"./AtmosTankControl.js":69321,"./AugmentMenu":92444,"./AugmentMenu.js":92444,"./Autolathe":59179,"./Autolathe.js":59179,"./BioChipPad":5147,"./BioChipPad.js":5147,"./Biogenerator":64273,"./Biogenerator.js":64273,"./BloomEdit":47823,"./BloomEdit.js":47823,"./BlueSpaceArtilleryControl":18621,"./BlueSpaceArtilleryControl.js":18621,"./BluespaceTap":27629,"./BluespaceTap.js":27629,"./BodyScanner":33758,"./BodyScanner.js":33758,"./BookBinder":67963,"./BookBinder.js":67963,"./BotCall":61925,"./BotCall.js":61925,"./BotClean":20464,"./BotClean.js":20464,"./BotFloor":69479,"./BotFloor.js":69479,"./BotHonk":59887,"./BotHonk.js":59887,"./BotMed":80063,"./BotMed.js":80063,"./BotSecurity":74439,"./BotSecurity.js":74439,"./BrigCells":10833,"./BrigCells.js":10833,"./BrigTimer":45761,"./BrigTimer.js":45761,"./CameraConsole":26300,"./CameraConsole.js":26300,"./Canister":52927,"./Canister.js":52927,"./CardComputer":51793,"./CardComputer.js":51793,"./CargoConsole":64083,"./CargoConsole.js":64083,"./Chameleon":36232,"./Chameleon.tsx":36232,"./ChangelogView":87331,"./ChangelogView.js":87331,"./CheckboxListInputModal":91360,"./CheckboxListInputModal.tsx":91360,"./ChemDispenser":36108,"./ChemDispenser.js":36108,"./ChemHeater":13146,"./ChemHeater.js":13146,"./ChemMaster":56541,"./ChemMaster.tsx":56541,"./CloningConsole":37173,"./CloningConsole.js":37173,"./CloningPod":98723,"./CloningPod.js":98723,"./CoinMint":18259,"./CoinMint.tsx":18259,"./ColorPickerModal":93858,"./ColorPickerModal.tsx":93858,"./ColourMatrixTester":8444,"./ColourMatrixTester.js":8444,"./CommunicationsComputer":63818,"./CommunicationsComputer.js":63818,"./CompostBin":20562,"./CompostBin.js":20562,"./Contractor":21813,"./Contractor.js":21813,"./ConveyorSwitch":54151,"./ConveyorSwitch.js":54151,"./CrewMonitor":73169,"./CrewMonitor.js":73169,"./Cryo":63987,"./Cryo.js":63987,"./CryopodConsole":86099,"./CryopodConsole.js":86099,"./DNAModifier":12692,"./DNAModifier.js":12692,"./DestinationTagger":41074,"./DestinationTagger.js":41074,"./DisposalBin":46500,"./DisposalBin.js":46500,"./DnaVault":33233,"./DnaVault.js":33233,"./DroneConsole":33681,"./DroneConsole.js":33681,"./EFTPOS":17263,"./EFTPOS.js":17263,"./ERTManager":76382,"./ERTManager.js":76382,"./EconomyManager":90217,"./EconomyManager.js":90217,"./Electropack":82565,"./Electropack.js":82565,"./Emojipedia":11243,"./Emojipedia.tsx":11243,"./EvolutionMenu":36730,"./EvolutionMenu.js":36730,"./ExosuitFabricator":17370,"./ExosuitFabricator.js":17370,"./ExperimentConsole":59128,"./ExperimentConsole.js":59128,"./ExternalAirlockController":97086,"./ExternalAirlockController.js":97086,"./FaxMachine":96142,"./FaxMachine.js":96142,"./FilingCabinet":74123,"./FilingCabinet.js":74123,"./FloorPainter":83767,"./FloorPainter.js":83767,"./GPS":53424,"./GPS.js":53424,"./GeneModder":89124,"./GeneModder.js":89124,"./GenericCrewManifest":73053,"./GenericCrewManifest.js":73053,"./GhostHudPanel":42914,"./GhostHudPanel.js":42914,"./GlandDispenser":25825,"./GlandDispenser.js":25825,"./GravityGen":10270,"./GravityGen.js":10270,"./GuestPass":48657,"./GuestPass.js":48657,"./HandheldChemDispenser":67834,"./HandheldChemDispenser.js":67834,"./HealthSensor":46098,"./HealthSensor.js":46098,"./Holodeck":36771,"./Holodeck.js":36771,"./Instrument":25471,"./Instrument.js":25471,"./KeyComboModal":13618,"./KeyComboModal.tsx":13618,"./KeycardAuth":35655,"./KeycardAuth.js":35655,"./KitchenMachine":62955,"./KitchenMachine.js":62955,"./LawManager":9525,"./LawManager.js":9525,"./LibraryComputer":85066,"./LibraryComputer.js":85066,"./LibraryManager":9516,"./LibraryManager.js":9516,"./ListInputModal":90447,"./ListInputModal.tsx":90447,"./Loadout":26826,"./Loadout.tsx":26826,"./MODsuit":77613,"./MODsuit.js":77613,"./MagnetController":78624,"./MagnetController.js":78624,"./MechBayConsole":72106,"./MechBayConsole.js":72106,"./MechaControlConsole":7466,"./MechaControlConsole.js":7466,"./MedicalRecords":79625,"./MedicalRecords.js":79625,"./MerchVendor":54989,"./MerchVendor.js":54989,"./MiningVendor":87684,"./MiningVendor.js":87684,"./NTRecruiter":59783,"./NTRecruiter.js":59783,"./Newscaster":64713,"./Newscaster.js":64713,"./Noticeboard":48286,"./Noticeboard.tsx":48286,"./NuclearBomb":41166,"./NuclearBomb.js":41166,"./NumberInputModal":52416,"./NumberInputModal.tsx":52416,"./OperatingComputer":1218,"./OperatingComputer.js":1218,"./Orbit":46892,"./Orbit.js":46892,"./OreRedemption":15421,"./OreRedemption.js":15421,"./PAI":52754,"./PAI.js":52754,"./PDA":85175,"./PDA.js":85175,"./Pacman":68654,"./Pacman.js":68654,"./PanDEMIC":1701,"./PanDEMIC.tsx":1701,"./ParticleAccelerator":67921,"./ParticleAccelerator.js":67921,"./PdaPainter":71432,"./PdaPainter.js":71432,"./PersonalCrafting":33388,"./PersonalCrafting.js":33388,"./Photocopier":56150,"./Photocopier.js":56150,"./PoolController":84676,"./PoolController.js":84676,"./PortablePump":57003,"./PortablePump.js":57003,"./PortableScrubber":70069,"./PortableScrubber.js":70069,"./PortableTurret":59955,"./PortableTurret.js":59955,"./PowerMonitor":61631,"./PowerMonitor.js":61631,"./PrisonerImplantManager":50992,"./PrisonerImplantManager.js":50992,"./PrisonerShuttleConsole":53952,"./PrisonerShuttleConsole.js":53952,"./PrizeCounter":97852,"./PrizeCounter.tsx":97852,"./RCD":94813,"./RCD.js":94813,"./RPD":18738,"./RPD.js":18738,"./Radio":80299,"./Radio.js":80299,"./RankedListInputModal":14846,"./RankedListInputModal.tsx":14846,"./ReagentGrinder":48125,"./ReagentGrinder.js":48125,"./ReagentsEditor":58262,"./ReagentsEditor.tsx":58262,"./RemoteSignaler":30207,"./RemoteSignaler.js":30207,"./RequestConsole":25472,"./RequestConsole.js":25472,"./RndBackupConsole":9861,"./RndBackupConsole.js":9861,"./RndConsole":12644,"./RndConsole/":12644,"./RndConsole/DataDiskMenu":37556,"./RndConsole/DataDiskMenu.js":37556,"./RndConsole/DeconstructionMenu":58147,"./RndConsole/DeconstructionMenu.js":58147,"./RndConsole/LatheCategory":16830,"./RndConsole/LatheCategory.js":16830,"./RndConsole/LatheChemicalStorage":70497,"./RndConsole/LatheChemicalStorage.js":70497,"./RndConsole/LatheMainMenu":70864,"./RndConsole/LatheMainMenu.js":70864,"./RndConsole/LatheMaterialStorage":42878,"./RndConsole/LatheMaterialStorage.js":42878,"./RndConsole/LatheMaterials":52662,"./RndConsole/LatheMaterials.js":52662,"./RndConsole/LatheMenu":9681,"./RndConsole/LatheMenu.js":9681,"./RndConsole/LatheSearch":68198,"./RndConsole/LatheSearch.js":68198,"./RndConsole/LinkMenu":81421,"./RndConsole/LinkMenu.js":81421,"./RndConsole/SettingsMenu":6256,"./RndConsole/SettingsMenu.js":6256,"./RndConsole/index":12644,"./RndConsole/index.js":12644,"./RndNetController":29205,"./RndNetController.js":29205,"./RndServer":63315,"./RndServer.js":63315,"./RobotSelfDiagnosis":26109,"./RobotSelfDiagnosis.js":26109,"./RoboticsControlConsole":97997,"./RoboticsControlConsole.js":97997,"./Safe":54431,"./Safe.js":54431,"./SatelliteControl":29740,"./SatelliteControl.js":29740,"./SecureStorage":44162,"./SecureStorage.js":44162,"./SecurityRecords":6272,"./SecurityRecords.js":6272,"./SeedExtractor":5099,"./SeedExtractor.js":5099,"./ShuttleConsole":2916,"./ShuttleConsole.js":2916,"./ShuttleManipulator":39401,"./ShuttleManipulator.js":39401,"./Sleeper":88284,"./Sleeper.js":88284,"./SlotMachine":21597,"./SlotMachine.js":21597,"./Smartfridge":46348,"./Smartfridge.js":46348,"./Smes":86162,"./Smes.js":86162,"./SolarControl":63584,"./SolarControl.js":63584,"./SpawnersMenu":38096,"./SpawnersMenu.js":38096,"./SpecMenu":30586,"./SpecMenu.js":30586,"./StackCraft":95152,"./StackCraft.js":95152,"./StationAlertConsole":38307,"./StationAlertConsole.js":38307,"./StationTraitsPanel":96091,"./StationTraitsPanel.tsx":96091,"./StripMenu":39409,"./StripMenu.tsx":39409,"./SuitStorage":69514,"./SuitStorage.js":69514,"./SupermatterMonitor":15022,"./SupermatterMonitor.js":15022,"./SyndicateComputerSimple":46029,"./SyndicateComputerSimple.js":46029,"./TEG":36372,"./TEG.js":36372,"./TachyonArray":56441,"./TachyonArray.js":56441,"./Tank":1754,"./Tank.js":1754,"./TankDispenser":7579,"./TankDispenser.js":7579,"./TcommsCore":16136,"./TcommsCore.js":16136,"./TcommsRelay":88046,"./TcommsRelay.js":88046,"./Teleporter":20802,"./Teleporter.js":20802,"./TelescienceConsole":48517,"./TelescienceConsole.js":48517,"./TempGun":21800,"./TempGun.js":21800,"./TextInputModal":24410,"./TextInputModal.tsx":24410,"./ThermoMachine":25036,"./ThermoMachine.js":25036,"./TransferValve":20035,"./TransferValve.js":20035,"./TurbineComputer":78166,"./TurbineComputer.js":78166,"./Uplink":52847,"./Uplink.js":52847,"./Vending":12261,"./Vending.js":12261,"./VolumeMixer":68971,"./VolumeMixer.js":68971,"./VotePanel":2510,"./VotePanel.js":2510,"./Wires":30138,"./Wires.js":30138,"./WizardApprenticeContract":21400,"./WizardApprenticeContract.js":21400,"./common/AccessList":49148,"./common/AccessList.js":49148,"./common/AtmosScan":26991,"./common/AtmosScan.js":26991,"./common/BeakerContents":85870,"./common/BeakerContents.js":85870,"./common/BotStatus":92963,"./common/BotStatus.js":92963,"./common/ComplexModal":3939,"./common/ComplexModal.js":3939,"./common/CrewManifest":41874,"./common/CrewManifest.js":41874,"./common/InputButtons":19203,"./common/InputButtons.tsx":19203,"./common/InterfaceLockNoticeBox":195,"./common/InterfaceLockNoticeBox.js":195,"./common/Loader":51057,"./common/Loader.tsx":51057,"./common/LoginInfo":321,"./common/LoginInfo.js":321,"./common/LoginScreen":5485,"./common/LoginScreen.js":5485,"./common/Operating":62411,"./common/Operating.js":62411,"./common/Signaler":13545,"./common/Signaler.js":13545,"./common/SimpleRecords":41984,"./common/SimpleRecords.js":41984,"./common/TemporaryNotice":22091,"./common/TemporaryNotice.js":22091,"./goonstation_PTL":95213,"./goonstation_PTL/":95213,"./goonstation_PTL/index":95213,"./goonstation_PTL/index.js":95213,"./pai/pai_atmosphere":80818,"./pai/pai_atmosphere.js":80818,"./pai/pai_bioscan":23903,"./pai/pai_bioscan.js":23903,"./pai/pai_directives":64988,"./pai/pai_directives.js":64988,"./pai/pai_doorjack":13813,"./pai/pai_doorjack.js":13813,"./pai/pai_main_menu":66025,"./pai/pai_main_menu.js":66025,"./pai/pai_manifest":2983,"./pai/pai_manifest.js":2983,"./pai/pai_medrecords":40758,"./pai/pai_medrecords.js":40758,"./pai/pai_messenger":98599,"./pai/pai_messenger.js":98599,"./pai/pai_radio":50775,"./pai/pai_radio.js":50775,"./pai/pai_secrecords":48623,"./pai/pai_secrecords.js":48623,"./pai/pai_signaler":47297,"./pai/pai_signaler.js":47297,"./pda/pda_atmos_scan":78532,"./pda/pda_atmos_scan.js":78532,"./pda/pda_games":2395,"./pda/pda_games.js":2395,"./pda/pda_janitor":40253,"./pda/pda_janitor.js":40253,"./pda/pda_main_menu":58293,"./pda/pda_main_menu.js":58293,"./pda/pda_manifest":58059,"./pda/pda_manifest.js":58059,"./pda/pda_medical":18147,"./pda/pda_medical.js":18147,"./pda/pda_messenger":77595,"./pda/pda_messenger.js":77595,"./pda/pda_minesweeper":90382,"./pda/pda_minesweeper.js":90382,"./pda/pda_mule":24635,"./pda/pda_mule.js":24635,"./pda/pda_nanobank":23734,"./pda/pda_nanobank.js":23734,"./pda/pda_notes":97085,"./pda/pda_notes.js":97085,"./pda/pda_power":57513,"./pda/pda_power.js":57513,"./pda/pda_secbot":99808,"./pda/pda_secbot.js":99808,"./pda/pda_security":77168,"./pda/pda_security.js":77168,"./pda/pda_signaler":21773,"./pda/pda_signaler.js":21773,"./pda/pda_status_display":81857,"./pda/pda_status_display.js":81857,"./pda/pda_supplyrecords":70287,"./pda/pda_supplyrecords.js":70287};function a(o){var p=t(o);return n(p)}function t(o){if(!n.o(e,o)){var p=new Error("Cannot find module '"+o+"'");throw p.code="MODULE_NOT_FOUND",p}return e[o]}a.keys=function(){return Object.keys(e)},a.resolve=t,T.exports=a,a.id=32054},4085:function(T,r,n){var e={"./Blink.stories.js":51364,"./BlockQuote.stories.js":32453,"./Box.stories.js":83531,"./Button.stories.js":74198,"./ByondUi.stories.js":51956,"./Collapsible.stories.js":17466,"./Flex.stories.js":89241,"./ImageButton.stories.js":48779,"./Input.stories.js":21394,"./Popper.stories.js":43932,"./ProgressBar.stories.js":33270,"./Stack.stories.js":77766,"./Storage.stories.js":30187,"./Tabs.stories.js":46554,"./Themes.stories.js":53276,"./Tooltip.stories.js":28717};function a(o){var p=t(o);return n(p)}function t(o){if(!n.o(e,o)){var p=new Error("Cannot find module '"+o+"'");throw p.code="MODULE_NOT_FOUND",p}return e[o]}a.keys=function(){return Object.keys(e)},a.resolve=t,T.exports=a,a.id=4085},10320:function(T,r,n){"use strict";var e=n(55747),a=n(89393),t=TypeError;T.exports=function(o){if(e(o))return o;throw new t(a(o)+" is not a function")}},32606:function(T,r,n){"use strict";var e=n(1031),a=n(89393),t=TypeError;T.exports=function(o){if(e(o))return o;throw new t(a(o)+" is not a constructor")}},35908:function(T,r,n){"use strict";var e=n(45015),a=String,t=TypeError;T.exports=function(o){if(e(o))return o;throw new t("Can't set "+a(o)+" as a prototype")}},80575:function(T,r,n){"use strict";var e=n(24697),a=n(80674),t=n(74595).f,o=e("unscopables"),p=Array.prototype;p[o]===void 0&&t(p,o,{configurable:!0,value:a(null)}),T.exports=function(b){p[o][b]=!0}},35483:function(T,r,n){"use strict";var e=n(50233).charAt;T.exports=function(a,t,o){return t+(o?e(a,t).length:1)}},60077:function(T,r,n){"use strict";var e=n(21287),a=TypeError;T.exports=function(t,o){if(e(o,t))return t;throw new a("Incorrect invocation")}},30365:function(T,r,n){"use strict";var e=n(77568),a=String,t=TypeError;T.exports=function(o){if(e(o))return o;throw new t(a(o)+" is not an object")}},70377:function(T){"use strict";T.exports=typeof ArrayBuffer!="undefined"&&typeof DataView!="undefined"},3782:function(T,r,n){"use strict";var e=n(40033);T.exports=e(function(){if(typeof ArrayBuffer=="function"){var a=new ArrayBuffer(8);Object.isExtensible(a)&&Object.defineProperty(a,"a",{value:8})}})},4246:function(T,r,n){"use strict";var e=n(70377),a=n(58310),t=n(74685),o=n(55747),p=n(77568),b=n(45299),y=n(2281),S=n(89393),k=n(37909),h=n(55938),i=n(73936),c=n(21287),m=n(36917),l=n(76649),u=n(24697),s=n(16738),d=n(5419),v=d.enforce,g=d.get,C=t.Int8Array,f=C&&C.prototype,N=t.Uint8ClampedArray,V=N&&N.prototype,B=C&&m(C),I=f&&m(f),L=Object.prototype,w=t.TypeError,A=u("toStringTag"),x=s("TYPED_ARRAY_TAG"),E="TypedArrayConstructor",P=e&&!!l&&y(t.opera)!=="Opera",D=!1,M,O,R,F={Int8Array:1,Uint8Array:1,Uint8ClampedArray:1,Int16Array:2,Uint16Array:2,Int32Array:4,Uint32Array:4,Float32Array:4,Float64Array:8},W={BigInt64Array:8,BigUint64Array:8},U=function(){function ie(me){if(!p(me))return!1;var q=y(me);return q==="DataView"||b(F,q)||b(W,q)}return ie}(),z=function ie(me){var q=m(me);if(p(q)){var re=g(q);return re&&b(re,E)?re[E]:ie(q)}},$=function(me){if(!p(me))return!1;var q=y(me);return b(F,q)||b(W,q)},G=function(me){if($(me))return me;throw new w("Target is not a typed array")},X=function(me){if(o(me)&&(!l||c(B,me)))return me;throw new w(S(me)+" is not a typed array constructor")},J=function(me,q,re,ae){if(a){if(re)for(var le in F){var Z=t[le];if(Z&&b(Z.prototype,me))try{delete Z.prototype[me]}catch(ne){try{Z.prototype[me]=q}catch(te){}}}(!I[me]||re)&&h(I,me,re?q:P&&f[me]||q,ae)}},se=function(me,q,re){var ae,le;if(a){if(l){if(re){for(ae in F)if(le=t[ae],le&&b(le,me))try{delete le[me]}catch(Z){}}if(!B[me]||re)try{return h(B,me,re?q:P&&B[me]||q)}catch(Z){}else return}for(ae in F)le=t[ae],le&&(!le[me]||re)&&h(le,me,q)}};for(M in F)O=t[M],R=O&&O.prototype,R?v(R)[E]=O:P=!1;for(M in W)O=t[M],R=O&&O.prototype,R&&(v(R)[E]=O);if((!P||!o(B)||B===Function.prototype)&&(B=function(){function ie(){throw new w("Incorrect invocation")}return ie}(),P))for(M in F)t[M]&&l(t[M],B);if((!P||!I||I===L)&&(I=B.prototype,P))for(M in F)t[M]&&l(t[M].prototype,I);if(P&&m(V)!==I&&l(V,I),a&&!b(I,A)){D=!0,i(I,A,{configurable:!0,get:function(){function ie(){return p(this)?this[x]:void 0}return ie}()});for(M in F)t[M]&&k(t[M],x,M)}T.exports={NATIVE_ARRAY_BUFFER_VIEWS:P,TYPED_ARRAY_TAG:D&&x,aTypedArray:G,aTypedArrayConstructor:X,exportTypedArrayMethod:J,exportTypedArrayStaticMethod:se,getTypedArrayConstructor:z,isView:U,isTypedArray:$,TypedArray:B,TypedArrayPrototype:I}},37336:function(T,r,n){"use strict";var e=n(74685),a=n(67250),t=n(58310),o=n(70377),p=n(70520),b=n(37909),y=n(73936),S=n(30145),k=n(40033),h=n(60077),i=n(61365),c=n(10188),m=n(43806),l=n(95867),u=n(91784),s=n(36917),d=n(76649),v=n(88471),g=n(54602),C=n(5781),f=n(5774),N=n(84925),V=n(5419),B=p.PROPER,I=p.CONFIGURABLE,L="ArrayBuffer",w="DataView",A="prototype",x="Wrong length",E="Wrong index",P=V.getterFor(L),D=V.getterFor(w),M=V.set,O=e[L],R=O,F=R&&R[A],W=e[w],U=W&&W[A],z=Object.prototype,$=e.Array,G=e.RangeError,X=a(v),J=a([].reverse),se=u.pack,ie=u.unpack,me=function(Ne){return[Ne&255]},q=function(Ne){return[Ne&255,Ne>>8&255]},re=function(Ne){return[Ne&255,Ne>>8&255,Ne>>16&255,Ne>>24&255]},ae=function(Ne){return Ne[3]<<24|Ne[2]<<16|Ne[1]<<8|Ne[0]},le=function(Ne){return se(l(Ne),23,4)},Z=function(Ne){return se(Ne,52,8)},ne=function(Ne,Be,be){y(Ne[A],Be,{configurable:!0,get:function(){function Le(){return be(this)[Be]}return Le}()})},te=function(Ne,Be,be,Le){var we=D(Ne),xe=m(be),Re=!!Le;if(xe+Be>we.byteLength)throw new G(E);var He=we.bytes,ye=xe+we.byteOffset,de=g(He,ye,ye+Be);return Re?de:J(de)},fe=function(Ne,Be,be,Le,we,xe){var Re=D(Ne),He=m(be),ye=Le(+we),de=!!xe;if(He+Be>Re.byteLength)throw new G(E);for(var he=Re.bytes,ke=He+Re.byteOffset,ve=0;vewe)throw new G("Wrong offset");if(be=be===void 0?we-xe:c(be),xe+be>we)throw new G(x);M(this,{type:w,buffer:Ne,byteLength:be,byteOffset:xe,bytes:Le.bytes}),t||(this.buffer=Ne,this.byteLength=be,this.byteOffset=xe)}return Ce}(),U=W[A],t&&(ne(R,"byteLength",P),ne(W,"buffer",D),ne(W,"byteLength",D),ne(W,"byteOffset",D)),S(U,{getInt8:function(){function Ce(Ne){return te(this,1,Ne)[0]<<24>>24}return Ce}(),getUint8:function(){function Ce(Ne){return te(this,1,Ne)[0]}return Ce}(),getInt16:function(){function Ce(Ne){var Be=te(this,2,Ne,arguments.length>1?arguments[1]:!1);return(Be[1]<<8|Be[0])<<16>>16}return Ce}(),getUint16:function(){function Ce(Ne){var Be=te(this,2,Ne,arguments.length>1?arguments[1]:!1);return Be[1]<<8|Be[0]}return Ce}(),getInt32:function(){function Ce(Ne){return ae(te(this,4,Ne,arguments.length>1?arguments[1]:!1))}return Ce}(),getUint32:function(){function Ce(Ne){return ae(te(this,4,Ne,arguments.length>1?arguments[1]:!1))>>>0}return Ce}(),getFloat32:function(){function Ce(Ne){return ie(te(this,4,Ne,arguments.length>1?arguments[1]:!1),23)}return Ce}(),getFloat64:function(){function Ce(Ne){return ie(te(this,8,Ne,arguments.length>1?arguments[1]:!1),52)}return Ce}(),setInt8:function(){function Ce(Ne,Be){fe(this,1,Ne,me,Be)}return Ce}(),setUint8:function(){function Ce(Ne,Be){fe(this,1,Ne,me,Be)}return Ce}(),setInt16:function(){function Ce(Ne,Be){fe(this,2,Ne,q,Be,arguments.length>2?arguments[2]:!1)}return Ce}(),setUint16:function(){function Ce(Ne,Be){fe(this,2,Ne,q,Be,arguments.length>2?arguments[2]:!1)}return Ce}(),setInt32:function(){function Ce(Ne,Be){fe(this,4,Ne,re,Be,arguments.length>2?arguments[2]:!1)}return Ce}(),setUint32:function(){function Ce(Ne,Be){fe(this,4,Ne,re,Be,arguments.length>2?arguments[2]:!1)}return Ce}(),setFloat32:function(){function Ce(Ne,Be){fe(this,4,Ne,le,Be,arguments.length>2?arguments[2]:!1)}return Ce}(),setFloat64:function(){function Ce(Ne,Be){fe(this,8,Ne,Z,Be,arguments.length>2?arguments[2]:!1)}return Ce}()});else{var pe=B&&O.name!==L;!k(function(){O(1)})||!k(function(){new O(-1)})||k(function(){return new O,new O(1.5),new O(NaN),O.length!==1||pe&&!I})?(R=function(){function Ce(Ne){return h(this,F),C(new O(m(Ne)),this,R)}return Ce}(),R[A]=F,F.constructor=R,f(R,O)):pe&&I&&b(O,"name",L),d&&s(U)!==z&&d(U,z);var ce=new W(new R(2)),Ve=a(U.setInt8);ce.setInt8(0,2147483648),ce.setInt8(1,2147483649),(ce.getInt8(0)||!ce.getInt8(1))&&S(U,{setInt8:function(){function Ce(Ne,Be){Ve(this,Ne,Be<<24>>24)}return Ce}(),setUint8:function(){function Ce(Ne,Be){Ve(this,Ne,Be<<24>>24)}return Ce}()},{unsafe:!0})}N(R,L),N(W,w),T.exports={ArrayBuffer:R,DataView:W}},71447:function(T,r,n){"use strict";var e=n(46771),a=n(13912),t=n(24760),o=n(95108),p=Math.min;T.exports=[].copyWithin||function(){function b(y,S){var k=e(this),h=t(k),i=a(y,h),c=a(S,h),m=arguments.length>2?arguments[2]:void 0,l=p((m===void 0?h:a(m,h))-c,h-i),u=1;for(c0;)c in k?k[i]=k[c]:o(k,i),i+=u,c+=u;return k}return b}()},88471:function(T,r,n){"use strict";var e=n(46771),a=n(13912),t=n(24760);T.exports=function(){function o(p){for(var b=e(this),y=t(b),S=arguments.length,k=a(S>1?arguments[1]:void 0,y),h=S>2?arguments[2]:void 0,i=h===void 0?y:a(h,y);i>k;)b[k++]=p;return b}return o}()},35601:function(T,r,n){"use strict";var e=n(22603).forEach,a=n(55528),t=a("forEach");T.exports=t?[].forEach:function(){function o(p){return e(this,p,arguments.length>1?arguments[1]:void 0)}return o}()},78008:function(T,r,n){"use strict";var e=n(24760);T.exports=function(a,t,o){for(var p=0,b=arguments.length>2?o:e(t),y=new a(b);b>p;)y[p]=t[p++];return y}},73174:function(T,r,n){"use strict";var e=n(75754),a=n(91495),t=n(46771),o=n(40125),p=n(76571),b=n(1031),y=n(24760),S=n(60102),k=n(77455),h=n(59201),i=Array;T.exports=function(){function c(m){var l=t(m),u=b(this),s=arguments.length,d=s>1?arguments[1]:void 0,v=d!==void 0;v&&(d=e(d,s>2?arguments[2]:void 0));var g=h(l),C=0,f,N,V,B,I,L;if(g&&!(this===i&&p(g)))for(N=u?new this:[],B=k(l,g),I=B.next;!(V=a(I,B)).done;C++)L=v?o(B,d,[V.value,C],!0):V.value,S(N,C,L);else for(f=y(l),N=u?new this(f):i(f);f>C;C++)L=v?d(l[C],C):l[C],S(N,C,L);return N.length=C,N}return c}()},14211:function(T,r,n){"use strict";var e=n(57591),a=n(13912),t=n(24760),o=function(b){return function(y,S,k){var h=e(y),i=t(h);if(i===0)return!b&&-1;var c=a(k,i),m;if(b&&S!==S){for(;i>c;)if(m=h[c++],m!==m)return!0}else for(;i>c;c++)if((b||c in h)&&h[c]===S)return b||c||0;return!b&&-1}};T.exports={includes:o(!0),indexOf:o(!1)}},22603:function(T,r,n){"use strict";var e=n(75754),a=n(67250),t=n(37457),o=n(46771),p=n(24760),b=n(57823),y=a([].push),S=function(h){var i=h===1,c=h===2,m=h===3,l=h===4,u=h===6,s=h===7,d=h===5||u;return function(v,g,C,f){for(var N=o(v),V=t(N),B=p(V),I=e(g,C),L=0,w=f||b,A=i?w(v,B):c||s?w(v,0):void 0,x,E;B>L;L++)if((d||L in V)&&(x=V[L],E=I(x,L,N),h))if(i)A[L]=E;else if(E)switch(h){case 3:return!0;case 5:return x;case 6:return L;case 2:y(A,x)}else switch(h){case 4:return!1;case 7:y(A,x)}return u?-1:m||l?l:A}};T.exports={forEach:S(0),map:S(1),filter:S(2),some:S(3),every:S(4),find:S(5),findIndex:S(6),filterReject:S(7)}},1325:function(T,r,n){"use strict";var e=n(61267),a=n(57591),t=n(61365),o=n(24760),p=n(55528),b=Math.min,y=[].lastIndexOf,S=!!y&&1/[1].lastIndexOf(1,-0)<0,k=p("lastIndexOf"),h=S||!k;T.exports=h?function(){function i(c){if(S)return e(y,this,arguments)||0;var m=a(this),l=o(m);if(l===0)return-1;var u=l-1;for(arguments.length>1&&(u=b(u,t(arguments[1]))),u<0&&(u=l+u);u>=0;u--)if(u in m&&m[u]===c)return u||0;return-1}return i}():y},44091:function(T,r,n){"use strict";var e=n(40033),a=n(24697),t=n(5026),o=a("species");T.exports=function(p){return t>=51||!e(function(){var b=[],y=b.constructor={};return y[o]=function(){return{foo:1}},b[p](Boolean).foo!==1})}},55528:function(T,r,n){"use strict";var e=n(40033);T.exports=function(a,t){var o=[][a];return!!o&&e(function(){o.call(null,t||function(){return 1},1)})}},56844:function(T,r,n){"use strict";var e=n(10320),a=n(46771),t=n(37457),o=n(24760),p=TypeError,b="Reduce of empty array with no initial value",y=function(k){return function(h,i,c,m){var l=a(h),u=t(l),s=o(l);if(e(i),s===0&&c<2)throw new p(b);var d=k?s-1:0,v=k?-1:1;if(c<2)for(;;){if(d in u){m=u[d],d+=v;break}if(d+=v,k?d<0:s<=d)throw new p(b)}for(;k?d>=0:s>d;d+=v)d in u&&(m=i(m,u[d],d,l));return m}};T.exports={left:y(!1),right:y(!0)}},13345:function(T,r,n){"use strict";var e=n(58310),a=n(37386),t=TypeError,o=Object.getOwnPropertyDescriptor,p=e&&!function(){if(this!==void 0)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(b){return b instanceof TypeError}}();T.exports=p?function(b,y){if(a(b)&&!o(b,"length").writable)throw new t("Cannot set read only .length");return b.length=y}:function(b,y){return b.length=y}},54602:function(T,r,n){"use strict";var e=n(67250);T.exports=e([].slice)},90274:function(T,r,n){"use strict";var e=n(54602),a=Math.floor,t=function o(p,b){var y=p.length;if(y<8)for(var S=1,k,h;S0;)p[h]=p[--h];h!==S++&&(p[h]=k)}else for(var i=a(y/2),c=o(e(p,0,i),b),m=o(e(p,i),b),l=c.length,u=m.length,s=0,d=0;s1?arguments[1]:void 0),E;E=E?E.next:A.first;)for(x(E.value,E.key,this);E&&E.removed;)E=E.previous}return L}(),has:function(){function L(w){return!!I(this,w)}return L}()}),t(N,g?{get:function(){function L(w){var A=I(this,w);return A&&A.value}return L}(),set:function(){function L(w,A){return B(this,w===0?0:w,A)}return L}()}:{add:function(){function L(w){return B(this,w=w===0?0:w,w)}return L}()}),i&&a(N,"size",{configurable:!0,get:function(){function L(){return V(this).size}return L}()}),f}return s}(),setStrong:function(){function s(d,v,g){var C=v+" Iterator",f=u(v),N=u(C);S(d,v,function(V,B){l(this,{type:C,target:V,state:f(V),kind:B,last:void 0})},function(){for(var V=N(this),B=V.kind,I=V.last;I&&I.removed;)I=I.previous;return!V.target||!(V.last=I=I?I.next:V.state.first)?(V.target=void 0,k(void 0,!0)):k(B==="keys"?I.key:B==="values"?I.value:[I.key,I.value],!1)},g?"entries":"values",!g,!0),h(v)}return s}()}},39895:function(T,r,n){"use strict";var e=n(67250),a=n(30145),t=n(81969).getWeakData,o=n(60077),p=n(30365),b=n(42871),y=n(77568),S=n(49450),k=n(22603),h=n(45299),i=n(5419),c=i.set,m=i.getterFor,l=k.find,u=k.findIndex,s=e([].splice),d=0,v=function(N){return N.frozen||(N.frozen=new g)},g=function(){this.entries=[]},C=function(N,V){return l(N.entries,function(B){return B[0]===V})};g.prototype={get:function(){function f(N){var V=C(this,N);if(V)return V[1]}return f}(),has:function(){function f(N){return!!C(this,N)}return f}(),set:function(){function f(N,V){var B=C(this,N);B?B[1]=V:this.entries.push([N,V])}return f}(),delete:function(){function f(N){var V=u(this.entries,function(B){return B[0]===N});return~V&&s(this.entries,V,1),!!~V}return f}()},T.exports={getConstructor:function(){function f(N,V,B,I){var L=N(function(E,P){o(E,w),c(E,{type:V,id:d++,frozen:void 0}),b(P)||S(P,E[I],{that:E,AS_ENTRIES:B})}),w=L.prototype,A=m(V),x=function(){function E(P,D,M){var O=A(P),R=t(p(D),!0);return R===!0?v(O).set(D,M):R[O.id]=M,P}return E}();return a(w,{delete:function(){function E(P){var D=A(this);if(!y(P))return!1;var M=t(P);return M===!0?v(D).delete(P):M&&h(M,D.id)&&delete M[D.id]}return E}(),has:function(){function E(P){var D=A(this);if(!y(P))return!1;var M=t(P);return M===!0?v(D).has(P):M&&h(M,D.id)}return E}()}),a(w,B?{get:function(){function E(P){var D=A(this);if(y(P)){var M=t(P);return M===!0?v(D).get(P):M?M[D.id]:void 0}}return E}(),set:function(){function E(P,D){return x(this,P,D)}return E}()}:{add:function(){function E(P){return x(this,P,!0)}return E}()}),L}return f}()}},45150:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(67250),o=n(41314),p=n(55938),b=n(81969),y=n(49450),S=n(60077),k=n(55747),h=n(42871),i=n(77568),c=n(40033),m=n(92490),l=n(84925),u=n(5781);T.exports=function(s,d,v){var g=s.indexOf("Map")!==-1,C=s.indexOf("Weak")!==-1,f=g?"set":"add",N=a[s],V=N&&N.prototype,B=N,I={},L=function(O){var R=t(V[O]);p(V,O,O==="add"?function(){function F(W){return R(this,W===0?0:W),this}return F}():O==="delete"?function(F){return C&&!i(F)?!1:R(this,F===0?0:F)}:O==="get"?function(){function F(W){return C&&!i(W)?void 0:R(this,W===0?0:W)}return F}():O==="has"?function(){function F(W){return C&&!i(W)?!1:R(this,W===0?0:W)}return F}():function(){function F(W,U){return R(this,W===0?0:W,U),this}return F}())},w=o(s,!k(N)||!(C||V.forEach&&!c(function(){new N().entries().next()})));if(w)B=v.getConstructor(d,s,g,f),b.enable();else if(o(s,!0)){var A=new B,x=A[f](C?{}:-0,1)!==A,E=c(function(){A.has(1)}),P=m(function(M){new N(M)}),D=!C&&c(function(){for(var M=new N,O=5;O--;)M[f](O,O);return!M.has(-0)});P||(B=d(function(M,O){S(M,V);var R=u(new N,M,B);return h(O)||y(O,R[f],{that:R,AS_ENTRIES:g}),R}),B.prototype=V,V.constructor=B),(E||D)&&(L("delete"),L("has"),g&&L("get")),(D||x)&&L(f),C&&V.clear&&delete V.clear}return I[s]=B,e({global:!0,constructor:!0,forced:B!==N},I),l(B,s),C||v.setStrong(B,s,g),B}},5774:function(T,r,n){"use strict";var e=n(45299),a=n(97921),t=n(27193),o=n(74595);T.exports=function(p,b,y){for(var S=a(b),k=o.f,h=t.f,i=0;i"+h+""}},5959:function(T){"use strict";T.exports=function(r,n){return{value:r,done:n}}},37909:function(T,r,n){"use strict";var e=n(58310),a=n(74595),t=n(87458);T.exports=e?function(o,p,b){return a.f(o,p,t(1,b))}:function(o,p,b){return o[p]=b,o}},87458:function(T){"use strict";T.exports=function(r,n){return{enumerable:!(r&1),configurable:!(r&2),writable:!(r&4),value:n}}},60102:function(T,r,n){"use strict";var e=n(58310),a=n(74595),t=n(87458);T.exports=function(o,p,b){e?a.f(o,p,t(0,b)):o[p]=b}},67206:function(T,r,n){"use strict";var e=n(67250),a=n(40033),t=n(24051).start,o=RangeError,p=isFinite,b=Math.abs,y=Date.prototype,S=y.toISOString,k=e(y.getTime),h=e(y.getUTCDate),i=e(y.getUTCFullYear),c=e(y.getUTCHours),m=e(y.getUTCMilliseconds),l=e(y.getUTCMinutes),u=e(y.getUTCMonth),s=e(y.getUTCSeconds);T.exports=a(function(){return S.call(new Date(-50000000000001))!=="0385-07-25T07:06:39.999Z"})||!a(function(){S.call(new Date(NaN))})?function(){function d(){if(!p(k(this)))throw new o("Invalid time value");var v=this,g=i(v),C=m(v),f=g<0?"-":g>9999?"+":"";return f+t(b(g),f?6:4,0)+"-"+t(u(v)+1,2,0)+"-"+t(h(v),2,0)+"T"+t(c(v),2,0)+":"+t(l(v),2,0)+":"+t(s(v),2,0)+"."+t(C,3,0)+"Z"}return d}():S},10886:function(T,r,n){"use strict";var e=n(30365),a=n(13396),t=TypeError;T.exports=function(o){if(e(this),o==="string"||o==="default")o="string";else if(o!=="number")throw new t("Incorrect hint");return a(this,o)}},73936:function(T,r,n){"use strict";var e=n(20001),a=n(74595);T.exports=function(t,o,p){return p.get&&e(p.get,o,{getter:!0}),p.set&&e(p.set,o,{setter:!0}),a.f(t,o,p)}},55938:function(T,r,n){"use strict";var e=n(55747),a=n(74595),t=n(20001),o=n(18231);T.exports=function(p,b,y,S){S||(S={});var k=S.enumerable,h=S.name!==void 0?S.name:b;if(e(y)&&t(y,h,S),S.global)k?p[b]=y:o(b,y);else{try{S.unsafe?p[b]&&(k=!0):delete p[b]}catch(i){}k?p[b]=y:a.f(p,b,{value:y,enumerable:!1,configurable:!S.nonConfigurable,writable:!S.nonWritable})}return p}},30145:function(T,r,n){"use strict";var e=n(55938);T.exports=function(a,t,o){for(var p in t)e(a,p,t[p],o);return a}},18231:function(T,r,n){"use strict";var e=n(74685),a=Object.defineProperty;T.exports=function(t,o){try{a(e,t,{value:o,configurable:!0,writable:!0})}catch(p){e[t]=o}return o}},95108:function(T,r,n){"use strict";var e=n(89393),a=TypeError;T.exports=function(t,o){if(!delete t[o])throw new a("Cannot delete property "+e(o)+" of "+e(t))}},58310:function(T,r,n){"use strict";var e=n(40033);T.exports=!e(function(){return Object.defineProperty({},1,{get:function(){function a(){return 7}return a}()})[1]!==7})},12689:function(T,r,n){"use strict";var e=n(74685),a=n(77568),t=e.document,o=a(t)&&a(t.createElement);T.exports=function(p){return o?t.createElement(p):{}}},21291:function(T){"use strict";var r=TypeError,n=9007199254740991;T.exports=function(e){if(e>n)throw r("Maximum allowed index exceeded");return e}},652:function(T,r,n){"use strict";var e=n(63318),a=e.match(/firefox\/(\d+)/i);T.exports=!!a&&+a[1]},8180:function(T,r,n){"use strict";var e=n(73730),a=n(81702);T.exports=!e&&!a&&typeof window=="object"&&typeof document=="object"},49197:function(T){"use strict";T.exports=typeof Bun=="function"&&Bun&&typeof Bun.version=="string"},73730:function(T){"use strict";T.exports=typeof Deno=="object"&&Deno&&typeof Deno.version=="object"},19228:function(T,r,n){"use strict";var e=n(63318);T.exports=/MSIE|Trident/.test(e)},51802:function(T,r,n){"use strict";var e=n(63318);T.exports=/ipad|iphone|ipod/i.test(e)&&typeof Pebble!="undefined"},83433:function(T,r,n){"use strict";var e=n(63318);T.exports=/(?:ipad|iphone|ipod).*applewebkit/i.test(e)},81702:function(T,r,n){"use strict";var e=n(74685),a=n(7462);T.exports=a(e.process)==="process"},63383:function(T,r,n){"use strict";var e=n(63318);T.exports=/web0s(?!.*chrome)/i.test(e)},63318:function(T){"use strict";T.exports=typeof navigator!="undefined"&&String(navigator.userAgent)||""},5026:function(T,r,n){"use strict";var e=n(74685),a=n(63318),t=e.process,o=e.Deno,p=t&&t.versions||o&&o.version,b=p&&p.v8,y,S;b&&(y=b.split("."),S=y[0]>0&&y[0]<4?1:+(y[0]+y[1])),!S&&a&&(y=a.match(/Edge\/(\d+)/),(!y||y[1]>=74)&&(y=a.match(/Chrome\/(\d+)/),y&&(S=+y[1]))),T.exports=S},9342:function(T,r,n){"use strict";var e=n(63318),a=e.match(/AppleWebKit\/(\d+)\./);T.exports=!!a&&+a[1]},89453:function(T){"use strict";T.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},63964:function(T,r,n){"use strict";var e=n(74685),a=n(27193).f,t=n(37909),o=n(55938),p=n(18231),b=n(5774),y=n(41314);T.exports=function(S,k){var h=S.target,i=S.global,c=S.stat,m,l,u,s,d,v;if(i?l=e:c?l=e[h]||p(h,{}):l=e[h]&&e[h].prototype,l)for(u in k){if(d=k[u],S.dontCallGetSet?(v=a(l,u),s=v&&v.value):s=l[u],m=y(i?u:h+(c?".":"#")+u,S.forced),!m&&s!==void 0){if(typeof d==typeof s)continue;b(d,s)}(S.sham||s&&s.sham)&&t(d,"sham",!0),o(l,u,d,S)}}},40033:function(T){"use strict";T.exports=function(r){try{return!!r()}catch(n){return!0}}},79942:function(T,r,n){"use strict";n(79669);var e=n(91495),a=n(55938),t=n(14489),o=n(40033),p=n(24697),b=n(37909),y=p("species"),S=RegExp.prototype;T.exports=function(k,h,i,c){var m=p(k),l=!o(function(){var v={};return v[m]=function(){return 7},""[k](v)!==7}),u=l&&!o(function(){var v=!1,g=/a/;return k==="split"&&(g={},g.constructor={},g.constructor[y]=function(){return g},g.flags="",g[m]=/./[m]),g.exec=function(){return v=!0,null},g[m](""),!v});if(!l||!u||i){var s=/./[m],d=h(m,""[k],function(v,g,C,f,N){var V=g.exec;return V===t||V===S.exec?l&&!N?{done:!0,value:e(s,g,C,f)}:{done:!0,value:e(v,C,g,f)}:{done:!1}});a(String.prototype,k,d[0]),a(S,m,d[1])}c&&b(S[m],"sham",!0)}},65561:function(T,r,n){"use strict";var e=n(37386),a=n(24760),t=n(21291),o=n(75754),p=function b(y,S,k,h,i,c,m,l){for(var u=i,s=0,d=m?o(m,l):!1,v,g;s0&&e(v)?(g=a(v),u=b(y,S,v,g,u,c-1)-1):(t(u+1),y[u]=v),u++),s++;return u};T.exports=p},50730:function(T,r,n){"use strict";var e=n(40033);T.exports=!e(function(){return Object.isExtensible(Object.preventExtensions({}))})},61267:function(T,r,n){"use strict";var e=n(55050),a=Function.prototype,t=a.apply,o=a.call;T.exports=typeof Reflect=="object"&&Reflect.apply||(e?o.bind(t):function(){return o.apply(t,arguments)})},75754:function(T,r,n){"use strict";var e=n(71138),a=n(10320),t=n(55050),o=e(e.bind);T.exports=function(p,b){return a(p),b===void 0?p:t?o(p,b):function(){return p.apply(b,arguments)}}},55050:function(T,r,n){"use strict";var e=n(40033);T.exports=!e(function(){var a=function(){}.bind();return typeof a!="function"||a.hasOwnProperty("prototype")})},66284:function(T,r,n){"use strict";var e=n(67250),a=n(10320),t=n(77568),o=n(45299),p=n(54602),b=n(55050),y=Function,S=e([].concat),k=e([].join),h={},i=function(m,l,u){if(!o(h,l)){for(var s=[],d=0;d]*>)/g,S=/\$([$&'`]|\d{1,2})/g;T.exports=function(k,h,i,c,m,l){var u=i+k.length,s=c.length,d=S;return m!==void 0&&(m=a(m),d=y),p(l,d,function(v,g){var C;switch(o(g,0)){case"$":return"$";case"&":return k;case"`":return b(h,0,i);case"'":return b(h,u);case"<":C=m[b(g,1,-1)];break;default:var f=+g;if(f===0)return v;if(f>s){var N=t(f/10);return N===0?v:N<=s?c[N-1]===void 0?o(g,1):c[N-1]+o(g,1):v}C=c[f-1]}return C===void 0?"":C})}},74685:function(T,r,n){"use strict";var e=function(t){return t&&t.Math===Math&&t};T.exports=e(typeof globalThis=="object"&&globalThis)||e(typeof window=="object"&&window)||e(typeof self=="object"&&self)||e(typeof n.g=="object"&&n.g)||e(!1)||function(){return this}()||Function("return this")()},45299:function(T,r,n){"use strict";var e=n(67250),a=n(46771),t=e({}.hasOwnProperty);T.exports=Object.hasOwn||function(){function o(p,b){return t(a(p),b)}return o}()},79195:function(T){"use strict";T.exports={}},72259:function(T){"use strict";T.exports=function(r,n){try{arguments.length}catch(e){}}},5315:function(T,r,n){"use strict";var e=n(4009);T.exports=e("document","documentElement")},36223:function(T,r,n){"use strict";var e=n(58310),a=n(40033),t=n(12689);T.exports=!e&&!a(function(){return Object.defineProperty(t("div"),"a",{get:function(){function o(){return 7}return o}()}).a!==7})},91784:function(T){"use strict";var r=Array,n=Math.abs,e=Math.pow,a=Math.floor,t=Math.log,o=Math.LN2,p=function(S,k,h){var i=r(h),c=h*8-k-1,m=(1<>1,u=k===23?e(2,-24)-e(2,-77):0,s=S<0||S===0&&1/S<0?1:0,d=0,v,g,C;for(S=n(S),S!==S||S===1/0?(g=S!==S?1:0,v=m):(v=a(t(S)/o),C=e(2,-v),S*C<1&&(v--,C*=2),v+l>=1?S+=u/C:S+=u*e(2,1-l),S*C>=2&&(v++,C/=2),v+l>=m?(g=0,v=m):v+l>=1?(g=(S*C-1)*e(2,k),v+=l):(g=S*e(2,l-1)*e(2,k),v=0));k>=8;)i[d++]=g&255,g/=256,k-=8;for(v=v<0;)i[d++]=v&255,v/=256,c-=8;return i[--d]|=s*128,i},b=function(S,k){var h=S.length,i=h*8-k-1,c=(1<>1,l=i-7,u=h-1,s=S[u--],d=s&127,v;for(s>>=7;l>0;)d=d*256+S[u--],l-=8;for(v=d&(1<<-l)-1,d>>=-l,l+=k;l>0;)v=v*256+S[u--],l-=8;if(d===0)d=1-m;else{if(d===c)return v?NaN:s?-1/0:1/0;v+=e(2,k),d-=m}return(s?-1:1)*v*e(2,d-k)};T.exports={pack:p,unpack:b}},37457:function(T,r,n){"use strict";var e=n(67250),a=n(40033),t=n(7462),o=Object,p=e("".split);T.exports=a(function(){return!o("z").propertyIsEnumerable(0)})?function(b){return t(b)==="String"?p(b,""):o(b)}:o},5781:function(T,r,n){"use strict";var e=n(55747),a=n(77568),t=n(76649);T.exports=function(o,p,b){var y,S;return t&&e(y=p.constructor)&&y!==b&&a(S=y.prototype)&&S!==b.prototype&&t(o,S),o}},40492:function(T,r,n){"use strict";var e=n(67250),a=n(55747),t=n(40095),o=e(Function.toString);a(t.inspectSource)||(t.inspectSource=function(p){return o(p)}),T.exports=t.inspectSource},81969:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(79195),o=n(77568),p=n(45299),b=n(74595).f,y=n(37310),S=n(81644),k=n(81834),h=n(16738),i=n(50730),c=!1,m=h("meta"),l=0,u=function(N){b(N,m,{value:{objectID:"O"+l++,weakData:{}}})},s=function(N,V){if(!o(N))return typeof N=="symbol"?N:(typeof N=="string"?"S":"P")+N;if(!p(N,m)){if(!k(N))return"F";if(!V)return"E";u(N)}return N[m].objectID},d=function(N,V){if(!p(N,m)){if(!k(N))return!0;if(!V)return!1;u(N)}return N[m].weakData},v=function(N){return i&&c&&k(N)&&!p(N,m)&&u(N),N},g=function(){C.enable=function(){},c=!0;var N=y.f,V=a([].splice),B={};B[m]=1,N(B).length&&(y.f=function(I){for(var L=N(I),w=0,A=L.length;wI;I++)if(w=P(l[I]),w&&y(m,w))return w;return new c(!1)}V=S(l,B)}for(A=g?l.next:V.next;!(x=a(A,V)).done;){try{w=P(x.value)}catch(D){h(V,"throw",D)}if(typeof w=="object"&&w&&y(m,w))return w}return new c(!1)}},28649:function(T,r,n){"use strict";var e=n(91495),a=n(30365),t=n(78060);T.exports=function(o,p,b){var y,S;a(o);try{if(y=t(o,"return"),!y){if(p==="throw")throw b;return b}y=e(y,o)}catch(k){S=!0,y=k}if(p==="throw")throw b;if(S)throw y;return a(y),b}},5656:function(T,r,n){"use strict";var e=n(67635).IteratorPrototype,a=n(80674),t=n(87458),o=n(84925),p=n(83967),b=function(){return this};T.exports=function(y,S,k,h){var i=S+" Iterator";return y.prototype=a(e,{next:t(+!h,k)}),o(y,i,!1,!0),p[i]=b,y}},65574:function(T,r,n){"use strict";var e=n(63964),a=n(91495),t=n(4493),o=n(70520),p=n(55747),b=n(5656),y=n(36917),S=n(76649),k=n(84925),h=n(37909),i=n(55938),c=n(24697),m=n(83967),l=n(67635),u=o.PROPER,s=o.CONFIGURABLE,d=l.IteratorPrototype,v=l.BUGGY_SAFARI_ITERATORS,g=c("iterator"),C="keys",f="values",N="entries",V=function(){return this};T.exports=function(B,I,L,w,A,x,E){b(L,I,w);var P=function(X){if(X===A&&F)return F;if(!v&&X&&X in O)return O[X];switch(X){case C:return function(){function J(){return new L(this,X)}return J}();case f:return function(){function J(){return new L(this,X)}return J}();case N:return function(){function J(){return new L(this,X)}return J}()}return function(){return new L(this)}},D=I+" Iterator",M=!1,O=B.prototype,R=O[g]||O["@@iterator"]||A&&O[A],F=!v&&R||P(A),W=I==="Array"&&O.entries||R,U,z,$;if(W&&(U=y(W.call(new B)),U!==Object.prototype&&U.next&&(!t&&y(U)!==d&&(S?S(U,d):p(U[g])||i(U,g,V)),k(U,D,!0,!0),t&&(m[D]=V))),u&&A===f&&R&&R.name!==f&&(!t&&s?h(O,"name",f):(M=!0,F=function(){function G(){return a(R,this)}return G}())),A)if(z={values:P(f),keys:x?F:P(C),entries:P(N)},E)for($ in z)(v||M||!($ in O))&&i(O,$,z[$]);else e({target:I,proto:!0,forced:v||M},z);return(!t||E)&&O[g]!==F&&i(O,g,F,{name:A}),m[I]=F,z}},67635:function(T,r,n){"use strict";var e=n(40033),a=n(55747),t=n(77568),o=n(80674),p=n(36917),b=n(55938),y=n(24697),S=n(4493),k=y("iterator"),h=!1,i,c,m;[].keys&&(m=[].keys(),"next"in m?(c=p(p(m)),c!==Object.prototype&&(i=c)):h=!0);var l=!t(i)||e(function(){var u={};return i[k].call(u)!==u});l?i={}:S&&(i=o(i)),a(i[k])||b(i,k,function(){return this}),T.exports={IteratorPrototype:i,BUGGY_SAFARI_ITERATORS:h}},83967:function(T){"use strict";T.exports={}},24760:function(T,r,n){"use strict";var e=n(10188);T.exports=function(a){return e(a.length)}},20001:function(T,r,n){"use strict";var e=n(67250),a=n(40033),t=n(55747),o=n(45299),p=n(58310),b=n(70520).CONFIGURABLE,y=n(40492),S=n(5419),k=S.enforce,h=S.get,i=String,c=Object.defineProperty,m=e("".slice),l=e("".replace),u=e([].join),s=p&&!a(function(){return c(function(){},"length",{value:8}).length!==8}),d=String(String).split("String"),v=T.exports=function(g,C,f){m(i(C),0,7)==="Symbol("&&(C="["+l(i(C),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),f&&f.getter&&(C="get "+C),f&&f.setter&&(C="set "+C),(!o(g,"name")||b&&g.name!==C)&&(p?c(g,"name",{value:C,configurable:!0}):g.name=C),s&&f&&o(f,"arity")&&g.length!==f.arity&&c(g,"length",{value:f.arity});try{f&&o(f,"constructor")&&f.constructor?p&&c(g,"prototype",{writable:!1}):g.prototype&&(g.prototype=void 0)}catch(V){}var N=k(g);return o(N,"source")||(N.source=u(d,typeof C=="string"?C:"")),g};Function.prototype.toString=v(function(){function g(){return t(this)&&h(this).source||y(this)}return g}(),"toString")},82040:function(T){"use strict";var r=Math.expm1,n=Math.exp;T.exports=!r||r(10)>22025.465794806718||r(10)<22025.465794806718||r(-2e-17)!==-2e-17?function(){function e(a){var t=+a;return t===0?t:t>-1e-6&&t<1e-6?t+t*t/2:n(t)-1}return e}():r},14950:function(T,r,n){"use strict";var e=n(22172),a=Math.abs,t=2220446049250313e-31,o=1/t,p=function(y){return y+o-o};T.exports=function(b,y,S,k){var h=+b,i=a(h),c=e(h);if(iS||l!==l?c*(1/0):c*l}},95867:function(T,r,n){"use strict";var e=n(14950),a=11920928955078125e-23,t=34028234663852886e22,o=11754943508222875e-54;T.exports=Math.fround||function(){function p(b){return e(b,a,t,o)}return p}()},75002:function(T){"use strict";var r=Math.log,n=Math.LOG10E;T.exports=Math.log10||function(){function e(a){return r(a)*n}return e}()},90874:function(T){"use strict";var r=Math.log;T.exports=Math.log1p||function(){function n(e){var a=+e;return a>-1e-8&&a<1e-8?a-a*a/2:r(1+a)}return n}()},22172:function(T){"use strict";T.exports=Math.sign||function(){function r(n){var e=+n;return e===0||e!==e?e:e<0?-1:1}return r}()},21119:function(T){"use strict";var r=Math.ceil,n=Math.floor;T.exports=Math.trunc||function(){function e(a){var t=+a;return(t>0?n:r)(t)}return e}()},37713:function(T,r,n){"use strict";var e=n(74685),a=n(44915),t=n(75754),o=n(60375).set,p=n(9547),b=n(83433),y=n(51802),S=n(63383),k=n(81702),h=e.MutationObserver||e.WebKitMutationObserver,i=e.document,c=e.process,m=e.Promise,l=a("queueMicrotask"),u,s,d,v,g;if(!l){var C=new p,f=function(){var V,B;for(k&&(V=c.domain)&&V.exit();B=C.get();)try{B()}catch(I){throw C.head&&u(),I}V&&V.enter()};!b&&!k&&!S&&h&&i?(s=!0,d=i.createTextNode(""),new h(f).observe(d,{characterData:!0}),u=function(){d.data=s=!s}):!y&&m&&m.resolve?(v=m.resolve(void 0),v.constructor=m,g=t(v.then,v),u=function(){g(f)}):k?u=function(){c.nextTick(f)}:(o=t(o,e),u=function(){o(f)}),l=function(V){C.head||u(),C.add(V)}}T.exports=l},81837:function(T,r,n){"use strict";var e=n(10320),a=TypeError,t=function(p){var b,y;this.promise=new p(function(S,k){if(b!==void 0||y!==void 0)throw new a("Bad Promise constructor");b=S,y=k}),this.resolve=e(b),this.reject=e(y)};T.exports.f=function(o){return new t(o)}},86213:function(T,r,n){"use strict";var e=n(72586),a=TypeError;T.exports=function(t){if(e(t))throw new a("The method doesn't accept regular expressions");return t}},3294:function(T,r,n){"use strict";var e=n(74685),a=e.isFinite;T.exports=Number.isFinite||function(){function t(o){return typeof o=="number"&&a(o)}return t}()},28506:function(T,r,n){"use strict";var e=n(74685),a=n(40033),t=n(67250),o=n(12605),p=n(92648).trim,b=n(4198),y=t("".charAt),S=e.parseFloat,k=e.Symbol,h=k&&k.iterator,i=1/S(b+"-0")!==-1/0||h&&!a(function(){S(Object(h))});T.exports=i?function(){function c(m){var l=p(o(m)),u=S(l);return u===0&&y(l,0)==="-"?-0:u}return c}():S},13693:function(T,r,n){"use strict";var e=n(74685),a=n(40033),t=n(67250),o=n(12605),p=n(92648).trim,b=n(4198),y=e.parseInt,S=e.Symbol,k=S&&S.iterator,h=/^[+-]?0x/i,i=t(h.exec),c=y(b+"08")!==8||y(b+"0x16")!==22||k&&!a(function(){y(Object(k))});T.exports=c?function(){function m(l,u){var s=p(o(l));return y(s,u>>>0||(i(h,s)?16:10))}return m}():y},41143:function(T,r,n){"use strict";var e=n(58310),a=n(67250),t=n(91495),o=n(40033),p=n(18450),b=n(89235),y=n(12867),S=n(46771),k=n(37457),h=Object.assign,i=Object.defineProperty,c=a([].concat);T.exports=!h||o(function(){if(e&&h({b:1},h(i({},"a",{enumerable:!0,get:function(){function d(){i(this,"b",{value:3,enumerable:!1})}return d}()}),{b:2})).b!==1)return!0;var m={},l={},u=Symbol("assign detection"),s="abcdefghijklmnopqrst";return m[u]=7,s.split("").forEach(function(d){l[d]=d}),h({},m)[u]!==7||p(h({},l)).join("")!==s})?function(){function m(l,u){for(var s=S(l),d=arguments.length,v=1,g=b.f,C=y.f;d>v;)for(var f=k(arguments[v++]),N=g?c(p(f),g(f)):p(f),V=N.length,B=0,I;V>B;)I=N[B++],(!e||t(C,f,I))&&(s[I]=f[I]);return s}return m}():h},80674:function(T,r,n){"use strict";var e=n(30365),a=n(24239),t=n(89453),o=n(79195),p=n(5315),b=n(12689),y=n(19417),S=">",k="<",h="prototype",i="script",c=y("IE_PROTO"),m=function(){},l=function(C){return k+i+S+C+k+"/"+i+S},u=function(C){C.write(l("")),C.close();var f=C.parentWindow.Object;return C=null,f},s=function(){var C=b("iframe"),f="java"+i+":",N;return C.style.display="none",p.appendChild(C),C.src=String(f),N=C.contentWindow.document,N.open(),N.write(l("document.F=Object")),N.close(),N.F},d,v=function(){try{d=new ActiveXObject("htmlfile")}catch(f){}v=typeof document!="undefined"?document.domain&&d?u(d):s():u(d);for(var C=t.length;C--;)delete v[h][t[C]];return v()};o[c]=!0,T.exports=Object.create||function(){function g(C,f){var N;return C!==null?(m[h]=e(C),N=new m,m[h]=null,N[c]=C):N=v(),f===void 0?N:a.f(N,f)}return g}()},24239:function(T,r,n){"use strict";var e=n(58310),a=n(80944),t=n(74595),o=n(30365),p=n(57591),b=n(18450);r.f=e&&!a?Object.defineProperties:function(){function y(S,k){o(S);for(var h=p(k),i=b(k),c=i.length,m=0,l;c>m;)t.f(S,l=i[m++],h[l]);return S}return y}()},74595:function(T,r,n){"use strict";var e=n(58310),a=n(36223),t=n(80944),o=n(30365),p=n(767),b=TypeError,y=Object.defineProperty,S=Object.getOwnPropertyDescriptor,k="enumerable",h="configurable",i="writable";r.f=e?t?function(){function c(m,l,u){if(o(m),l=p(l),o(u),typeof m=="function"&&l==="prototype"&&"value"in u&&i in u&&!u[i]){var s=S(m,l);s&&s[i]&&(m[l]=u.value,u={configurable:h in u?u[h]:s[h],enumerable:k in u?u[k]:s[k],writable:!1})}return y(m,l,u)}return c}():y:function(){function c(m,l,u){if(o(m),l=p(l),o(u),a)try{return y(m,l,u)}catch(s){}if("get"in u||"set"in u)throw new b("Accessors not supported");return"value"in u&&(m[l]=u.value),m}return c}()},27193:function(T,r,n){"use strict";var e=n(58310),a=n(91495),t=n(12867),o=n(87458),p=n(57591),b=n(767),y=n(45299),S=n(36223),k=Object.getOwnPropertyDescriptor;r.f=e?k:function(){function h(i,c){if(i=p(i),c=b(c),S)try{return k(i,c)}catch(m){}if(y(i,c))return o(!a(t.f,i,c),i[c])}return h}()},81644:function(T,r,n){"use strict";var e=n(7462),a=n(57591),t=n(37310).f,o=n(54602),p=typeof window=="object"&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],b=function(S){try{return t(S)}catch(k){return o(p)}};T.exports.f=function(){function y(S){return p&&e(S)==="Window"?b(S):t(a(S))}return y}()},37310:function(T,r,n){"use strict";var e=n(53726),a=n(89453),t=a.concat("length","prototype");r.f=Object.getOwnPropertyNames||function(){function o(p){return e(p,t)}return o}()},89235:function(T,r){"use strict";r.f=Object.getOwnPropertySymbols},36917:function(T,r,n){"use strict";var e=n(45299),a=n(55747),t=n(46771),o=n(19417),p=n(9225),b=o("IE_PROTO"),y=Object,S=y.prototype;T.exports=p?y.getPrototypeOf:function(k){var h=t(k);if(e(h,b))return h[b];var i=h.constructor;return a(i)&&h instanceof i?i.prototype:h instanceof y?S:null}},81834:function(T,r,n){"use strict";var e=n(40033),a=n(77568),t=n(7462),o=n(3782),p=Object.isExtensible,b=e(function(){p(1)});T.exports=b||o?function(){function y(S){return!a(S)||o&&t(S)==="ArrayBuffer"?!1:p?p(S):!0}return y}():p},21287:function(T,r,n){"use strict";var e=n(67250);T.exports=e({}.isPrototypeOf)},53726:function(T,r,n){"use strict";var e=n(67250),a=n(45299),t=n(57591),o=n(14211).indexOf,p=n(79195),b=e([].push);T.exports=function(y,S){var k=t(y),h=0,i=[],c;for(c in k)!a(p,c)&&a(k,c)&&b(i,c);for(;S.length>h;)a(k,c=S[h++])&&(~o(i,c)||b(i,c));return i}},18450:function(T,r,n){"use strict";var e=n(53726),a=n(89453);T.exports=Object.keys||function(){function t(o){return e(o,a)}return t}()},12867:function(T,r){"use strict";var n={}.propertyIsEnumerable,e=Object.getOwnPropertyDescriptor,a=e&&!n.call({1:2},1);r.f=a?function(){function t(o){var p=e(this,o);return!!p&&p.enumerable}return t}():n},57377:function(T,r,n){"use strict";var e=n(4493),a=n(74685),t=n(40033),o=n(9342);T.exports=e||!t(function(){if(!(o&&o<535)){var p=Math.random();__defineSetter__.call(null,p,function(){}),delete a[p]}})},76649:function(T,r,n){"use strict";var e=n(38656),a=n(77568),t=n(16952),o=n(35908);T.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var p=!1,b={},y;try{y=e(Object.prototype,"__proto__","set"),y(b,[]),p=b instanceof Array}catch(S){}return function(){function S(k,h){return t(k),o(h),a(k)&&(p?y(k,h):k.__proto__=h),k}return S}()}():void 0)},70915:function(T,r,n){"use strict";var e=n(58310),a=n(40033),t=n(67250),o=n(36917),p=n(18450),b=n(57591),y=n(12867).f,S=t(y),k=t([].push),h=e&&a(function(){var c=Object.create(null);return c[2]=2,!S(c,2)}),i=function(m){return function(l){for(var u=b(l),s=p(u),d=h&&o(u)===null,v=s.length,g=0,C=[],f;v>g;)f=s[g++],(!e||(d?f in u:S(u,f)))&&k(C,m?[f,u[f]]:u[f]);return C}};T.exports={entries:i(!0),values:i(!1)}},2509:function(T,r,n){"use strict";var e=n(2650),a=n(2281);T.exports=e?{}.toString:function(){function t(){return"[object "+a(this)+"]"}return t}()},13396:function(T,r,n){"use strict";var e=n(91495),a=n(55747),t=n(77568),o=TypeError;T.exports=function(p,b){var y,S;if(b==="string"&&a(y=p.toString)&&!t(S=e(y,p))||a(y=p.valueOf)&&!t(S=e(y,p))||b!=="string"&&a(y=p.toString)&&!t(S=e(y,p)))return S;throw new o("Can't convert object to primitive value")}},97921:function(T,r,n){"use strict";var e=n(4009),a=n(67250),t=n(37310),o=n(89235),p=n(30365),b=a([].concat);T.exports=e("Reflect","ownKeys")||function(){function y(S){var k=t.f(p(S)),h=o.f;return h?b(k,h(S)):k}return y}()},61765:function(T,r,n){"use strict";var e=n(74685);T.exports=e},10729:function(T){"use strict";T.exports=function(r){try{return{error:!1,value:r()}}catch(n){return{error:!0,value:n}}}},74854:function(T,r,n){"use strict";var e=n(74685),a=n(67512),t=n(55747),o=n(41314),p=n(40492),b=n(24697),y=n(8180),S=n(73730),k=n(4493),h=n(5026),i=a&&a.prototype,c=b("species"),m=!1,l=t(e.PromiseRejectionEvent),u=o("Promise",function(){var s=p(a),d=s!==String(a);if(!d&&h===66||k&&!(i.catch&&i.finally))return!0;if(!h||h<51||!/native code/.test(s)){var v=new a(function(f){f(1)}),g=function(N){N(function(){},function(){})},C=v.constructor={};if(C[c]=g,m=v.then(function(){})instanceof g,!m)return!0}return!d&&(y||S)&&!l});T.exports={CONSTRUCTOR:u,REJECTION_EVENT:l,SUBCLASSING:m}},67512:function(T,r,n){"use strict";var e=n(74685);T.exports=e.Promise},66628:function(T,r,n){"use strict";var e=n(30365),a=n(77568),t=n(81837);T.exports=function(o,p){if(e(o),a(p)&&p.constructor===o)return p;var b=t.f(o),y=b.resolve;return y(p),b.promise}},48199:function(T,r,n){"use strict";var e=n(67512),a=n(92490),t=n(74854).CONSTRUCTOR;T.exports=t||!a(function(o){e.all(o).then(void 0,function(){})})},34550:function(T,r,n){"use strict";var e=n(74595).f;T.exports=function(a,t,o){o in a||e(a,o,{configurable:!0,get:function(){function p(){return t[o]}return p}(),set:function(){function p(b){t[o]=b}return p}()})}},9547:function(T){"use strict";var r=function(){this.head=null,this.tail=null};r.prototype={add:function(){function n(e){var a={item:e,next:null},t=this.tail;t?t.next=a:this.head=a,this.tail=a}return n}(),get:function(){function n(){var e=this.head;if(e){var a=this.head=e.next;return a===null&&(this.tail=null),e.item}}return n}()},T.exports=r},28340:function(T,r,n){"use strict";var e=n(91495),a=n(30365),t=n(55747),o=n(7462),p=n(14489),b=TypeError;T.exports=function(y,S){var k=y.exec;if(t(k)){var h=e(k,y,S);return h!==null&&a(h),h}if(o(y)==="RegExp")return e(p,y,S);throw new b("RegExp#exec called on incompatible receiver")}},14489:function(T,r,n){"use strict";var e=n(91495),a=n(67250),t=n(12605),o=n(70901),p=n(62115),b=n(16639),y=n(80674),S=n(5419).get,k=n(39173),h=n(35688),i=b("native-string-replace",String.prototype.replace),c=RegExp.prototype.exec,m=c,l=a("".charAt),u=a("".indexOf),s=a("".replace),d=a("".slice),v=function(){var N=/a/,V=/b*/g;return e(c,N,"a"),e(c,V,"a"),N.lastIndex!==0||V.lastIndex!==0}(),g=p.BROKEN_CARET,C=/()??/.exec("")[1]!==void 0,f=v||C||g||k||h;f&&(m=function(){function N(V){var B=this,I=S(B),L=t(V),w=I.raw,A,x,E,P,D,M,O;if(w)return w.lastIndex=B.lastIndex,A=e(m,w,L),B.lastIndex=w.lastIndex,A;var R=I.groups,F=g&&B.sticky,W=e(o,B),U=B.source,z=0,$=L;if(F&&(W=s(W,"y",""),u(W,"g")===-1&&(W+="g"),$=d(L,B.lastIndex),B.lastIndex>0&&(!B.multiline||B.multiline&&l(L,B.lastIndex-1)!=="\n")&&(U="(?: "+U+")",$=" "+$,z++),x=new RegExp("^(?:"+U+")",W)),C&&(x=new RegExp("^"+U+"$(?!\\s)",W)),v&&(E=B.lastIndex),P=e(c,F?x:B,$),F?P?(P.input=d(P.input,z),P[0]=d(P[0],z),P.index=B.lastIndex,B.lastIndex+=P[0].length):B.lastIndex=0:v&&P&&(B.lastIndex=B.global?P.index+P[0].length:E),C&&P&&P.length>1&&e(i,P[0],x,function(){for(D=1;Db)","g");return o.exec("b").groups.a!=="b"||"b".replace(o,"$c")!=="bc"})},16952:function(T,r,n){"use strict";var e=n(42871),a=TypeError;T.exports=function(t){if(e(t))throw new a("Can't call method on "+t);return t}},44915:function(T,r,n){"use strict";var e=n(74685),a=n(58310),t=Object.getOwnPropertyDescriptor;T.exports=function(o){if(!a)return e[o];var p=t(e,o);return p&&p.value}},5700:function(T){"use strict";T.exports=Object.is||function(){function r(n,e){return n===e?n!==0||1/n===1/e:n!==n&&e!==e}return r}()},78362:function(T,r,n){"use strict";var e=n(74685),a=n(61267),t=n(55747),o=n(49197),p=n(63318),b=n(54602),y=n(24986),S=e.Function,k=/MSIE .\./.test(p)||o&&function(){var h=e.Bun.version.split(".");return h.length<3||h[0]==="0"&&(h[1]<3||h[1]==="3"&&h[2]==="0")}();T.exports=function(h,i){var c=i?2:1;return k?function(m,l){var u=y(arguments.length,1)>c,s=t(m)?m:S(m),d=u?b(arguments,c):[],v=u?function(){a(s,this,d)}:s;return i?h(v,l):h(v)}:h}},58491:function(T,r,n){"use strict";var e=n(4009),a=n(73936),t=n(24697),o=n(58310),p=t("species");T.exports=function(b){var y=e(b);o&&y&&!y[p]&&a(y,p,{configurable:!0,get:function(){function S(){return this}return S}()})}},84925:function(T,r,n){"use strict";var e=n(74595).f,a=n(45299),t=n(24697),o=t("toStringTag");T.exports=function(p,b,y){p&&!y&&(p=p.prototype),p&&!a(p,o)&&e(p,o,{configurable:!0,value:b})}},19417:function(T,r,n){"use strict";var e=n(16639),a=n(16738),t=e("keys");T.exports=function(o){return t[o]||(t[o]=a(o))}},40095:function(T,r,n){"use strict";var e=n(4493),a=n(74685),t=n(18231),o="__core-js_shared__",p=T.exports=a[o]||t(o,{});(p.versions||(p.versions=[])).push({version:"3.37.1",mode:e?"pure":"global",copyright:"\xA9 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.37.1/LICENSE",source:"https://github.com/zloirock/core-js"})},16639:function(T,r,n){"use strict";var e=n(40095);T.exports=function(a,t){return e[a]||(e[a]=t||{})}},28987:function(T,r,n){"use strict";var e=n(30365),a=n(32606),t=n(42871),o=n(24697),p=o("species");T.exports=function(b,y){var S=e(b).constructor,k;return S===void 0||t(k=e(S)[p])?y:a(k)}},88539:function(T,r,n){"use strict";var e=n(40033);T.exports=function(a){return e(function(){var t=""[a]('"');return t!==t.toLowerCase()||t.split('"').length>3})}},50233:function(T,r,n){"use strict";var e=n(67250),a=n(61365),t=n(12605),o=n(16952),p=e("".charAt),b=e("".charCodeAt),y=e("".slice),S=function(h){return function(i,c){var m=t(o(i)),l=a(c),u=m.length,s,d;return l<0||l>=u?h?"":void 0:(s=b(m,l),s<55296||s>56319||l+1===u||(d=b(m,l+1))<56320||d>57343?h?p(m,l):s:h?y(m,l,l+2):(s-55296<<10)+(d-56320)+65536)}};T.exports={codeAt:S(!1),charAt:S(!0)}},34125:function(T,r,n){"use strict";var e=n(63318);T.exports=/Version\/10(?:\.\d+){1,2}(?: [\w./]+)?(?: Mobile\/\w+)? Safari\//.test(e)},24051:function(T,r,n){"use strict";var e=n(67250),a=n(10188),t=n(12605),o=n(62443),p=n(16952),b=e(o),y=e("".slice),S=Math.ceil,k=function(i){return function(c,m,l){var u=t(p(c)),s=a(m),d=u.length,v=l===void 0?" ":t(l),g,C;return s<=d||v===""?u:(g=s-d,C=b(v,S(g/v.length)),C.length>g&&(C=y(C,0,g)),i?u+C:C+u)}};T.exports={start:k(!1),end:k(!0)}},62443:function(T,r,n){"use strict";var e=n(61365),a=n(12605),t=n(16952),o=RangeError;T.exports=function(){function p(b){var y=a(t(this)),S="",k=e(b);if(k<0||k===1/0)throw new o("Wrong number of repetitions");for(;k>0;(k>>>=1)&&(y+=y))k&1&&(S+=y);return S}return p}()},43476:function(T,r,n){"use strict";var e=n(92648).end,a=n(90012);T.exports=a("trimEnd")?function(){function t(){return e(this)}return t}():"".trimEnd},90012:function(T,r,n){"use strict";var e=n(70520).PROPER,a=n(40033),t=n(4198),o="\u200B\x85\u180E";T.exports=function(p){return a(function(){return!!t[p]()||o[p]()!==o||e&&t[p].name!==p})}},43885:function(T,r,n){"use strict";var e=n(92648).start,a=n(90012);T.exports=a("trimStart")?function(){function t(){return e(this)}return t}():"".trimStart},92648:function(T,r,n){"use strict";var e=n(67250),a=n(16952),t=n(12605),o=n(4198),p=e("".replace),b=RegExp("^["+o+"]+"),y=RegExp("(^|[^"+o+"])["+o+"]+$"),S=function(h){return function(i){var c=t(a(i));return h&1&&(c=p(c,b,"")),h&2&&(c=p(c,y,"$1")),c}};T.exports={start:S(1),end:S(2),trim:S(3)}},52357:function(T,r,n){"use strict";var e=n(5026),a=n(40033),t=n(74685),o=t.String;T.exports=!!Object.getOwnPropertySymbols&&!a(function(){var p=Symbol("symbol detection");return!o(p)||!(Object(p)instanceof Symbol)||!Symbol.sham&&e&&e<41})},52360:function(T,r,n){"use strict";var e=n(91495),a=n(4009),t=n(24697),o=n(55938);T.exports=function(){var p=a("Symbol"),b=p&&p.prototype,y=b&&b.valueOf,S=t("toPrimitive");b&&!b[S]&&o(b,S,function(k){return e(y,this)},{arity:1})}},66570:function(T,r,n){"use strict";var e=n(52357);T.exports=e&&!!Symbol.for&&!!Symbol.keyFor},60375:function(T,r,n){"use strict";var e=n(74685),a=n(61267),t=n(75754),o=n(55747),p=n(45299),b=n(40033),y=n(5315),S=n(54602),k=n(12689),h=n(24986),i=n(83433),c=n(81702),m=e.setImmediate,l=e.clearImmediate,u=e.process,s=e.Dispatch,d=e.Function,v=e.MessageChannel,g=e.String,C=0,f={},N="onreadystatechange",V,B,I,L;b(function(){V=e.location});var w=function(D){if(p(f,D)){var M=f[D];delete f[D],M()}},A=function(D){return function(){w(D)}},x=function(D){w(D.data)},E=function(D){e.postMessage(g(D),V.protocol+"//"+V.host)};(!m||!l)&&(m=function(){function P(D){h(arguments.length,1);var M=o(D)?D:d(D),O=S(arguments,1);return f[++C]=function(){a(M,void 0,O)},B(C),C}return P}(),l=function(){function P(D){delete f[D]}return P}(),c?B=function(D){u.nextTick(A(D))}:s&&s.now?B=function(D){s.now(A(D))}:v&&!i?(I=new v,L=I.port2,I.port1.onmessage=x,B=t(L.postMessage,L)):e.addEventListener&&o(e.postMessage)&&!e.importScripts&&V&&V.protocol!=="file:"&&!b(E)?(B=E,e.addEventListener("message",x,!1)):N in k("script")?B=function(D){y.appendChild(k("script"))[N]=function(){y.removeChild(this),w(D)}}:B=function(D){setTimeout(A(D),0)}),T.exports={set:m,clear:l}},46438:function(T,r,n){"use strict";var e=n(67250);T.exports=e(1 .valueOf)},13912:function(T,r,n){"use strict";var e=n(61365),a=Math.max,t=Math.min;T.exports=function(o,p){var b=e(o);return b<0?a(b+p,0):t(b,p)}},61484:function(T,r,n){"use strict";var e=n(24843),a=TypeError;T.exports=function(t){var o=e(t,"number");if(typeof o=="number")throw new a("Can't convert number to bigint");return BigInt(o)}},43806:function(T,r,n){"use strict";var e=n(61365),a=n(10188),t=RangeError;T.exports=function(o){if(o===void 0)return 0;var p=e(o),b=a(p);if(p!==b)throw new t("Wrong length or index");return b}},57591:function(T,r,n){"use strict";var e=n(37457),a=n(16952);T.exports=function(t){return e(a(t))}},61365:function(T,r,n){"use strict";var e=n(21119);T.exports=function(a){var t=+a;return t!==t||t===0?0:e(t)}},10188:function(T,r,n){"use strict";var e=n(61365),a=Math.min;T.exports=function(t){var o=e(t);return o>0?a(o,9007199254740991):0}},46771:function(T,r,n){"use strict";var e=n(16952),a=Object;T.exports=function(t){return a(e(t))}},56043:function(T,r,n){"use strict";var e=n(16140),a=RangeError;T.exports=function(t,o){var p=e(t);if(p%o)throw new a("Wrong offset");return p}},16140:function(T,r,n){"use strict";var e=n(61365),a=RangeError;T.exports=function(t){var o=e(t);if(o<0)throw new a("The argument can't be less than 0");return o}},24843:function(T,r,n){"use strict";var e=n(91495),a=n(77568),t=n(71399),o=n(78060),p=n(13396),b=n(24697),y=TypeError,S=b("toPrimitive");T.exports=function(k,h){if(!a(k)||t(k))return k;var i=o(k,S),c;if(i){if(h===void 0&&(h="default"),c=e(i,k,h),!a(c)||t(c))return c;throw new y("Can't convert object to primitive value")}return h===void 0&&(h="number"),p(k,h)}},767:function(T,r,n){"use strict";var e=n(24843),a=n(71399);T.exports=function(t){var o=e(t,"string");return a(o)?o:o+""}},2650:function(T,r,n){"use strict";var e=n(24697),a=e("toStringTag"),t={};t[a]="z",T.exports=String(t)==="[object z]"},12605:function(T,r,n){"use strict";var e=n(2281),a=String;T.exports=function(t){if(e(t)==="Symbol")throw new TypeError("Cannot convert a Symbol value to a string");return a(t)}},15409:function(T){"use strict";var r=Math.round;T.exports=function(n){var e=r(n);return e<0?0:e>255?255:e&255}},89393:function(T){"use strict";var r=String;T.exports=function(n){try{return r(n)}catch(e){return"Object"}}},80185:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(91495),o=n(58310),p=n(86563),b=n(4246),y=n(37336),S=n(60077),k=n(87458),h=n(37909),i=n(5841),c=n(10188),m=n(43806),l=n(56043),u=n(15409),s=n(767),d=n(45299),v=n(2281),g=n(77568),C=n(71399),f=n(80674),N=n(21287),V=n(76649),B=n(37310).f,I=n(3805),L=n(22603).forEach,w=n(58491),A=n(73936),x=n(74595),E=n(27193),P=n(78008),D=n(5419),M=n(5781),O=D.get,R=D.set,F=D.enforce,W=x.f,U=E.f,z=a.RangeError,$=y.ArrayBuffer,G=$.prototype,X=y.DataView,J=b.NATIVE_ARRAY_BUFFER_VIEWS,se=b.TYPED_ARRAY_TAG,ie=b.TypedArray,me=b.TypedArrayPrototype,q=b.isTypedArray,re="BYTES_PER_ELEMENT",ae="Wrong length",le=function(ce,Ve){A(ce,Ve,{configurable:!0,get:function(){function Ce(){return O(this)[Ve]}return Ce}()})},Z=function(ce){var Ve;return N(G,ce)||(Ve=v(ce))==="ArrayBuffer"||Ve==="SharedArrayBuffer"},ne=function(ce,Ve){return q(ce)&&!C(Ve)&&Ve in ce&&i(+Ve)&&Ve>=0},te=function(){function pe(ce,Ve){return Ve=s(Ve),ne(ce,Ve)?k(2,ce[Ve]):U(ce,Ve)}return pe}(),fe=function(){function pe(ce,Ve,Ce){return Ve=s(Ve),ne(ce,Ve)&&g(Ce)&&d(Ce,"value")&&!d(Ce,"get")&&!d(Ce,"set")&&!Ce.configurable&&(!d(Ce,"writable")||Ce.writable)&&(!d(Ce,"enumerable")||Ce.enumerable)?(ce[Ve]=Ce.value,ce):W(ce,Ve,Ce)}return pe}();o?(J||(E.f=te,x.f=fe,le(me,"buffer"),le(me,"byteOffset"),le(me,"byteLength"),le(me,"length")),e({target:"Object",stat:!0,forced:!J},{getOwnPropertyDescriptor:te,defineProperty:fe}),T.exports=function(pe,ce,Ve){var Ce=pe.match(/\d+/)[0]/8,Ne=pe+(Ve?"Clamped":"")+"Array",Be="get"+pe,be="set"+pe,Le=a[Ne],we=Le,xe=we&&we.prototype,Re={},He=function(ve,Se){var Pe=O(ve);return Pe.view[Be](Se*Ce+Pe.byteOffset,!0)},ye=function(ve,Se,Pe){var je=O(ve);je.view[be](Se*Ce+je.byteOffset,Ve?u(Pe):Pe,!0)},de=function(ve,Se){W(ve,Se,{get:function(){function Pe(){return He(this,Se)}return Pe}(),set:function(){function Pe(je){return ye(this,Se,je)}return Pe}(),enumerable:!0})};J?p&&(we=ce(function(ke,ve,Se,Pe){return S(ke,xe),M(function(){return g(ve)?Z(ve)?Pe!==void 0?new Le(ve,l(Se,Ce),Pe):Se!==void 0?new Le(ve,l(Se,Ce)):new Le(ve):q(ve)?P(we,ve):t(I,we,ve):new Le(m(ve))}(),ke,we)}),V&&V(we,ie),L(B(Le),function(ke){ke in we||h(we,ke,Le[ke])}),we.prototype=xe):(we=ce(function(ke,ve,Se,Pe){S(ke,xe);var je=0,Fe=0,ze,We,Ue;if(!g(ve))Ue=m(ve),We=Ue*Ce,ze=new $(We);else if(Z(ve)){ze=ve,Fe=l(Se,Ce);var Xe=ve.byteLength;if(Pe===void 0){if(Xe%Ce)throw new z(ae);if(We=Xe-Fe,We<0)throw new z(ae)}else if(We=c(Pe)*Ce,We+Fe>Xe)throw new z(ae);Ue=We/Ce}else return q(ve)?P(we,ve):t(I,we,ve);for(R(ke,{buffer:ze,byteOffset:Fe,byteLength:We,length:Ue,view:new X(ze)});je1?arguments[1]:void 0,v=d!==void 0,g=y(u),C,f,N,V,B,I,L,w;if(g&&!S(g))for(L=b(u,g),w=L.next,u=[];!(I=a(w,L)).done;)u.push(I.value);for(v&&s>2&&(d=e(d,arguments[2])),f=p(u),N=new(h(l))(f),V=k(N),C=0;f>C;C++)B=v?d(u[C],C):u[C],N[C]=V?i(B):+B;return N}return c}()},31082:function(T,r,n){"use strict";var e=n(4246),a=n(28987),t=e.aTypedArrayConstructor,o=e.getTypedArrayConstructor;T.exports=function(p){return t(a(p,o(p)))}},16738:function(T,r,n){"use strict";var e=n(67250),a=0,t=Math.random(),o=e(1 .toString);T.exports=function(p){return"Symbol("+(p===void 0?"":p)+")_"+o(++a+t,36)}},1062:function(T,r,n){"use strict";var e=n(52357);T.exports=e&&!Symbol.sham&&typeof Symbol.iterator=="symbol"},80944:function(T,r,n){"use strict";var e=n(58310),a=n(40033);T.exports=e&&a(function(){return Object.defineProperty(function(){},"prototype",{value:42,writable:!1}).prototype!==42})},24986:function(T){"use strict";var r=TypeError;T.exports=function(n,e){if(n=51||!a(function(){var d=[];return d[m]=!1,d.concat()[0]!==d}),u=function(v){if(!o(v))return!1;var g=v[m];return g!==void 0?!!g:t(v)},s=!l||!h("concat");e({target:"Array",proto:!0,arity:1,forced:s},{concat:function(){function d(v){var g=p(this),C=k(g,0),f=0,N,V,B,I,L;for(N=-1,B=arguments.length;N1?arguments[1]:void 0)}return p}()})},68933:function(T,r,n){"use strict";var e=n(63964),a=n(88471),t=n(80575);e({target:"Array",proto:!0},{fill:a}),t("fill")},47830:function(T,r,n){"use strict";var e=n(63964),a=n(22603).filter,t=n(44091),o=t("filter");e({target:"Array",proto:!0,forced:!o},{filter:function(){function p(b){return a(this,b,arguments.length>1?arguments[1]:void 0)}return p}()})},64094:function(T,r,n){"use strict";var e=n(63964),a=n(22603).findIndex,t=n(80575),o="findIndex",p=!0;o in[]&&Array(1)[o](function(){p=!1}),e({target:"Array",proto:!0,forced:p},{findIndex:function(){function b(y){return a(this,y,arguments.length>1?arguments[1]:void 0)}return b}()}),t(o)},13455:function(T,r,n){"use strict";var e=n(63964),a=n(22603).find,t=n(80575),o="find",p=!0;o in[]&&Array(1)[o](function(){p=!1}),e({target:"Array",proto:!0,forced:p},{find:function(){function b(y){return a(this,y,arguments.length>1?arguments[1]:void 0)}return b}()}),t(o)},32384:function(T,r,n){"use strict";var e=n(63964),a=n(65561),t=n(10320),o=n(46771),p=n(24760),b=n(57823);e({target:"Array",proto:!0},{flatMap:function(){function y(S){var k=o(this),h=p(k),i;return t(S),i=b(k,0),i.length=a(i,k,k,h,0,1,S,arguments.length>1?arguments[1]:void 0),i}return y}()})},61915:function(T,r,n){"use strict";var e=n(63964),a=n(65561),t=n(46771),o=n(24760),p=n(61365),b=n(57823);e({target:"Array",proto:!0},{flat:function(){function y(){var S=arguments.length?arguments[0]:void 0,k=t(this),h=o(k),i=b(k,0);return i.length=a(i,k,k,h,0,S===void 0?1:p(S)),i}return y}()})},25579:function(T,r,n){"use strict";var e=n(63964),a=n(35601);e({target:"Array",proto:!0,forced:[].forEach!==a},{forEach:a})},63532:function(T,r,n){"use strict";var e=n(63964),a=n(73174),t=n(92490),o=!t(function(p){Array.from(p)});e({target:"Array",stat:!0,forced:o},{from:a})},33425:function(T,r,n){"use strict";var e=n(63964),a=n(14211).includes,t=n(40033),o=n(80575),p=t(function(){return!Array(1).includes()});e({target:"Array",proto:!0,forced:p},{includes:function(){function b(y){return a(this,y,arguments.length>1?arguments[1]:void 0)}return b}()}),o("includes")},43894:function(T,r,n){"use strict";var e=n(63964),a=n(71138),t=n(14211).indexOf,o=n(55528),p=a([].indexOf),b=!!p&&1/p([1],1,-0)<0,y=b||!o("indexOf");e({target:"Array",proto:!0,forced:y},{indexOf:function(){function S(k){var h=arguments.length>1?arguments[1]:void 0;return b?p(this,k,h)||0:t(this,k,h)}return S}()})},99636:function(T,r,n){"use strict";var e=n(63964),a=n(37386);e({target:"Array",stat:!0},{isArray:a})},34570:function(T,r,n){"use strict";var e=n(57591),a=n(80575),t=n(83967),o=n(5419),p=n(74595).f,b=n(65574),y=n(5959),S=n(4493),k=n(58310),h="Array Iterator",i=o.set,c=o.getterFor(h);T.exports=b(Array,"Array",function(l,u){i(this,{type:h,target:e(l),index:0,kind:u})},function(){var l=c(this),u=l.target,s=l.index++;if(!u||s>=u.length)return l.target=void 0,y(void 0,!0);switch(l.kind){case"keys":return y(s,!1);case"values":return y(u[s],!1)}return y([s,u[s]],!1)},"values");var m=t.Arguments=t.Array;if(a("keys"),a("values"),a("entries"),!S&&k&&m.name!=="values")try{p(m,"name",{value:"values"})}catch(l){}},94432:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(37457),o=n(57591),p=n(55528),b=a([].join),y=t!==Object,S=y||!p("join",",");e({target:"Array",proto:!0,forced:S},{join:function(){function k(h){return b(o(this),h===void 0?",":h)}return k}()})},24683:function(T,r,n){"use strict";var e=n(63964),a=n(1325);e({target:"Array",proto:!0,forced:a!==[].lastIndexOf},{lastIndexOf:a})},69984:function(T,r,n){"use strict";var e=n(63964),a=n(22603).map,t=n(44091),o=t("map");e({target:"Array",proto:!0,forced:!o},{map:function(){function p(b){return a(this,b,arguments.length>1?arguments[1]:void 0)}return p}()})},32089:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(1031),o=n(60102),p=Array,b=a(function(){function y(){}return!(p.of.call(y)instanceof y)});e({target:"Array",stat:!0,forced:b},{of:function(){function y(){for(var S=0,k=arguments.length,h=new(t(this)?this:p)(k);k>S;)o(h,S,arguments[S++]);return h.length=k,h}return y}()})},29645:function(T,r,n){"use strict";var e=n(63964),a=n(56844).right,t=n(55528),o=n(5026),p=n(81702),b=!p&&o>79&&o<83,y=b||!t("reduceRight");e({target:"Array",proto:!0,forced:y},{reduceRight:function(){function S(k){return a(this,k,arguments.length,arguments.length>1?arguments[1]:void 0)}return S}()})},60206:function(T,r,n){"use strict";var e=n(63964),a=n(56844).left,t=n(55528),o=n(5026),p=n(81702),b=!p&&o>79&&o<83,y=b||!t("reduce");e({target:"Array",proto:!0,forced:y},{reduce:function(){function S(k){var h=arguments.length;return a(this,k,h,h>1?arguments[1]:void 0)}return S}()})},4788:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(37386),o=a([].reverse),p=[1,2];e({target:"Array",proto:!0,forced:String(p)===String(p.reverse())},{reverse:function(){function b(){return t(this)&&(this.length=this.length),o(this)}return b}()})},58672:function(T,r,n){"use strict";var e=n(63964),a=n(37386),t=n(1031),o=n(77568),p=n(13912),b=n(24760),y=n(57591),S=n(60102),k=n(24697),h=n(44091),i=n(54602),c=h("slice"),m=k("species"),l=Array,u=Math.max;e({target:"Array",proto:!0,forced:!c},{slice:function(){function s(d,v){var g=y(this),C=b(g),f=p(d,C),N=p(v===void 0?C:v,C),V,B,I;if(a(g)&&(V=g.constructor,t(V)&&(V===l||a(V.prototype))?V=void 0:o(V)&&(V=V[m],V===null&&(V=void 0)),V===l||V===void 0))return i(g,f,N);for(B=new(V===void 0?l:V)(u(N-f,0)),I=0;f1?arguments[1]:void 0)}return p}()})},48968:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(10320),o=n(46771),p=n(24760),b=n(95108),y=n(12605),S=n(40033),k=n(90274),h=n(55528),i=n(652),c=n(19228),m=n(5026),l=n(9342),u=[],s=a(u.sort),d=a(u.push),v=S(function(){u.sort(void 0)}),g=S(function(){u.sort(null)}),C=h("sort"),f=!S(function(){if(m)return m<70;if(!(i&&i>3)){if(c)return!0;if(l)return l<603;var B="",I,L,w,A;for(I=65;I<76;I++){switch(L=String.fromCharCode(I),I){case 66:case 69:case 70:case 72:w=3;break;case 68:case 71:w=4;break;default:w=2}for(A=0;A<47;A++)u.push({k:L+A,v:w})}for(u.sort(function(x,E){return E.v-x.v}),A=0;Ay(w)?1:-1}};e({target:"Array",proto:!0,forced:N},{sort:function(){function B(I){I!==void 0&&t(I);var L=o(this);if(f)return I===void 0?s(L):s(L,I);var w=[],A=p(L),x,E;for(E=0;Eg-V+N;I--)h(v,I-1)}else if(N>V)for(I=g-V;I>C;I--)L=I+V-1,w=I+N-1,L in v?v[w]=v[L]:h(v,w);for(I=0;I9490626562425156e-8?o(h)+b:a(h-1+p(h-1)*p(h+1))}return S}()})},59660:function(T,r,n){"use strict";var e=n(63964),a=Math.asinh,t=Math.log,o=Math.sqrt;function p(y){var S=+y;return!isFinite(S)||S===0?S:S<0?-p(-S):t(S+o(S*S+1))}var b=!(a&&1/a(0)>0);e({target:"Math",stat:!0,forced:b},{asinh:p})},15383:function(T,r,n){"use strict";var e=n(63964),a=Math.atanh,t=Math.log,o=!(a&&1/a(-0)<0);e({target:"Math",stat:!0,forced:o},{atanh:function(){function p(b){var y=+b;return y===0?y:t((1+y)/(1-y))/2}return p}()})},92866:function(T,r,n){"use strict";var e=n(63964),a=n(22172),t=Math.abs,o=Math.pow;e({target:"Math",stat:!0},{cbrt:function(){function p(b){var y=+b;return a(y)*o(t(y),.3333333333333333)}return p}()})},86107:function(T,r,n){"use strict";var e=n(63964),a=Math.floor,t=Math.log,o=Math.LOG2E;e({target:"Math",stat:!0},{clz32:function(){function p(b){var y=b>>>0;return y?31-a(t(y+.5)*o):32}return p}()})},29248:function(T,r,n){"use strict";var e=n(63964),a=n(82040),t=Math.cosh,o=Math.abs,p=Math.E,b=!t||t(710)===1/0;e({target:"Math",stat:!0,forced:b},{cosh:function(){function y(S){var k=a(o(S)-1)+1;return(k+1/(k*p*p))*(p/2)}return y}()})},52540:function(T,r,n){"use strict";var e=n(63964),a=n(82040);e({target:"Math",stat:!0,forced:a!==Math.expm1},{expm1:a})},79007:function(T,r,n){"use strict";var e=n(63964),a=n(95867);e({target:"Math",stat:!0},{fround:a})},77199:function(T,r,n){"use strict";var e=n(63964),a=Math.hypot,t=Math.abs,o=Math.sqrt,p=!!a&&a(1/0,NaN)!==1/0;e({target:"Math",stat:!0,arity:2,forced:p},{hypot:function(){function b(y,S){for(var k=0,h=0,i=arguments.length,c=0,m,l;h0?(l=m/c,k+=l*l):k+=m;return c===1/0?1/0:c*o(k)}return b}()})},6522:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=Math.imul,o=a(function(){return t(4294967295,5)!==-5||t.length!==2});e({target:"Math",stat:!0,forced:o},{imul:function(){function p(b,y){var S=65535,k=+b,h=+y,i=S&k,c=S&h;return 0|i*c+((S&k>>>16)*c+i*(S&h>>>16)<<16>>>0)}return p}()})},95542:function(T,r,n){"use strict";var e=n(63964),a=n(75002);e({target:"Math",stat:!0},{log10:a})},2966:function(T,r,n){"use strict";var e=n(63964),a=n(90874);e({target:"Math",stat:!0},{log1p:a})},20997:function(T,r,n){"use strict";var e=n(63964),a=Math.log,t=Math.LN2;e({target:"Math",stat:!0},{log2:function(){function o(p){return a(p)/t}return o}()})},57400:function(T,r,n){"use strict";var e=n(63964),a=n(22172);e({target:"Math",stat:!0},{sign:a})},45571:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(82040),o=Math.abs,p=Math.exp,b=Math.E,y=a(function(){return Math.sinh(-2e-17)!==-2e-17});e({target:"Math",stat:!0,forced:y},{sinh:function(){function S(k){var h=+k;return o(h)<1?(t(h)-t(-h))/2:(p(h-1)-p(-h-1))*(b/2)}return S}()})},54800:function(T,r,n){"use strict";var e=n(63964),a=n(82040),t=Math.exp;e({target:"Math",stat:!0},{tanh:function(){function o(p){var b=+p,y=a(b),S=a(-b);return y===1/0?1:S===1/0?-1:(y-S)/(t(b)+t(-b))}return o}()})},15709:function(T,r,n){"use strict";var e=n(84925);e(Math,"Math",!0)},76059:function(T,r,n){"use strict";var e=n(63964),a=n(21119);e({target:"Math",stat:!0},{trunc:a})},96614:function(T,r,n){"use strict";var e=n(63964),a=n(4493),t=n(58310),o=n(74685),p=n(61765),b=n(67250),y=n(41314),S=n(45299),k=n(5781),h=n(21287),i=n(71399),c=n(24843),m=n(40033),l=n(37310).f,u=n(27193).f,s=n(74595).f,d=n(46438),v=n(92648).trim,g="Number",C=o[g],f=p[g],N=C.prototype,V=o.TypeError,B=b("".slice),I=b("".charCodeAt),L=function(M){var O=c(M,"number");return typeof O=="bigint"?O:w(O)},w=function(M){var O=c(M,"number"),R,F,W,U,z,$,G,X;if(i(O))throw new V("Cannot convert a Symbol value to a number");if(typeof O=="string"&&O.length>2){if(O=v(O),R=I(O,0),R===43||R===45){if(F=I(O,2),F===88||F===120)return NaN}else if(R===48){switch(I(O,1)){case 66:case 98:W=2,U=49;break;case 79:case 111:W=8,U=55;break;default:return+O}for(z=B(O,2),$=z.length,G=0;G<$;G++)if(X=I(z,G),X<48||X>U)return NaN;return parseInt(z,W)}}return+O},A=y(g,!C(" 0o1")||!C("0b1")||C("+0x1")),x=function(M){return h(N,M)&&m(function(){d(M)})},E=function(){function D(M){var O=arguments.length<1?0:C(L(M));return x(this)?k(Object(O),this,E):O}return D}();E.prototype=N,A&&!a&&(N.constructor=E),e({global:!0,constructor:!0,wrap:!0,forced:A},{Number:E});var P=function(M,O){for(var R=t?l(O):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,isFinite,isInteger,isNaN,isSafeInteger,parseFloat,parseInt,fromString,range".split(","),F=0,W;R.length>F;F++)S(O,W=R[F])&&!S(M,W)&&s(M,W,u(O,W))};a&&f&&P(p[g],f),(A||a)&&P(p[g],C)},324:function(T,r,n){"use strict";var e=n(63964);e({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{EPSILON:Math.pow(2,-52)})},90426:function(T,r,n){"use strict";var e=n(63964),a=n(3294);e({target:"Number",stat:!0},{isFinite:a})},95443:function(T,r,n){"use strict";var e=n(63964),a=n(5841);e({target:"Number",stat:!0},{isInteger:a})},87968:function(T,r,n){"use strict";var e=n(63964);e({target:"Number",stat:!0},{isNaN:function(){function a(t){return t!==t}return a}()})},55007:function(T,r,n){"use strict";var e=n(63964),a=n(5841),t=Math.abs;e({target:"Number",stat:!0},{isSafeInteger:function(){function o(p){return a(p)&&t(p)<=9007199254740991}return o}()})},55323:function(T,r,n){"use strict";var e=n(63964);e({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{MAX_SAFE_INTEGER:9007199254740991})},13521:function(T,r,n){"use strict";var e=n(63964);e({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{MIN_SAFE_INTEGER:-9007199254740991})},5006:function(T,r,n){"use strict";var e=n(63964),a=n(28506);e({target:"Number",stat:!0,forced:Number.parseFloat!==a},{parseFloat:a})},99009:function(T,r,n){"use strict";var e=n(63964),a=n(13693);e({target:"Number",stat:!0,forced:Number.parseInt!==a},{parseInt:a})},85770:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(61365),o=n(46438),p=n(62443),b=n(40033),y=RangeError,S=String,k=Math.floor,h=a(p),i=a("".slice),c=a(1 .toFixed),m=function g(C,f,N){return f===0?N:f%2===1?g(C,f-1,N*C):g(C*C,f/2,N)},l=function(C){for(var f=0,N=C;N>=4096;)f+=12,N/=4096;for(;N>=2;)f+=1,N/=2;return f},u=function(C,f,N){for(var V=-1,B=N;++V<6;)B+=f*C[V],C[V]=B%1e7,B=k(B/1e7)},s=function(C,f){for(var N=6,V=0;--N>=0;)V+=C[N],C[N]=k(V/f),V=V%f*1e7},d=function(C){for(var f=6,N="";--f>=0;)if(N!==""||f===0||C[f]!==0){var V=S(C[f]);N=N===""?V:N+h("0",7-V.length)+V}return N},v=b(function(){return c(8e-5,3)!=="0.000"||c(.9,0)!=="1"||c(1.255,2)!=="1.25"||c(0xde0b6b3a7640080,0)!=="1000000000000000128"})||!b(function(){c({})});e({target:"Number",proto:!0,forced:v},{toFixed:function(){function g(C){var f=o(this),N=t(C),V=[0,0,0,0,0,0],B="",I="0",L,w,A,x;if(N<0||N>20)throw new y("Incorrect fraction digits");if(f!==f)return"NaN";if(f<=-1e21||f>=1e21)return S(f);if(f<0&&(B="-",f=-f),f>1e-21)if(L=l(f*m(2,69,1))-69,w=L<0?f*m(2,-L,1):f/m(2,L,1),w*=4503599627370496,L=52-L,L>0){for(u(V,0,w),A=N;A>=7;)u(V,1e7,0),A-=7;for(u(V,m(10,A,1),0),A=L-1;A>=23;)s(V,8388608),A-=23;s(V,1<0?(x=I.length,I=B+(x<=N?"0."+h("0",N-x)+I:i(I,0,x-N)+"."+i(I,x-N))):I=B+I,I}return g}()})},23532:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(40033),o=n(46438),p=a(1 .toPrecision),b=t(function(){return p(1,void 0)!=="1"})||!t(function(){p({})});e({target:"Number",proto:!0,forced:b},{toPrecision:function(){function y(S){return S===void 0?p(o(this)):p(o(this),S)}return y}()})},87119:function(T,r,n){"use strict";var e=n(63964),a=n(41143);e({target:"Object",stat:!0,arity:2,forced:Object.assign!==a},{assign:a})},78618:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(80674);e({target:"Object",stat:!0,sham:!a},{create:t})},27129:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(57377),o=n(10320),p=n(46771),b=n(74595);a&&e({target:"Object",proto:!0,forced:t},{__defineGetter__:function(){function y(S,k){b.f(p(this),S,{get:o(k),enumerable:!0,configurable:!0})}return y}()})},31943:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(24239).f;e({target:"Object",stat:!0,forced:Object.defineProperties!==t,sham:!a},{defineProperties:t})},3579:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(74595).f;e({target:"Object",stat:!0,forced:Object.defineProperty!==t,sham:!a},{defineProperty:t})},97397:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(57377),o=n(10320),p=n(46771),b=n(74595);a&&e({target:"Object",proto:!0,forced:t},{__defineSetter__:function(){function y(S,k){b.f(p(this),S,{set:o(k),enumerable:!0,configurable:!0})}return y}()})},85028:function(T,r,n){"use strict";var e=n(63964),a=n(70915).entries;e({target:"Object",stat:!0},{entries:function(){function t(o){return a(o)}return t}()})},8225:function(T,r,n){"use strict";var e=n(63964),a=n(50730),t=n(40033),o=n(77568),p=n(81969).onFreeze,b=Object.freeze,y=t(function(){b(1)});e({target:"Object",stat:!0,forced:y,sham:!a},{freeze:function(){function S(k){return b&&o(k)?b(p(k)):k}return S}()})},43331:function(T,r,n){"use strict";var e=n(63964),a=n(49450),t=n(60102);e({target:"Object",stat:!0},{fromEntries:function(){function o(p){var b={};return a(p,function(y,S){t(b,y,S)},{AS_ENTRIES:!0}),b}return o}()})},62289:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(57591),o=n(27193).f,p=n(58310),b=!p||a(function(){o(1)});e({target:"Object",stat:!0,forced:b,sham:!p},{getOwnPropertyDescriptor:function(){function y(S,k){return o(t(S),k)}return y}()})},56196:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(97921),o=n(57591),p=n(27193),b=n(60102);e({target:"Object",stat:!0,sham:!a},{getOwnPropertyDescriptors:function(){function y(S){for(var k=o(S),h=p.f,i=t(k),c={},m=0,l,u;i.length>m;)u=h(k,l=i[m++]),u!==void 0&&b(c,l,u);return c}return y}()})},2950:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(81644).f,o=a(function(){return!Object.getOwnPropertyNames(1)});e({target:"Object",stat:!0,forced:o},{getOwnPropertyNames:t})},28603:function(T,r,n){"use strict";var e=n(63964),a=n(52357),t=n(40033),o=n(89235),p=n(46771),b=!a||t(function(){o.f(1)});e({target:"Object",stat:!0,forced:b},{getOwnPropertySymbols:function(){function y(S){var k=o.f;return k?k(p(S)):[]}return y}()})},44205:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(46771),o=n(36917),p=n(9225),b=a(function(){o(1)});e({target:"Object",stat:!0,forced:b,sham:!p},{getPrototypeOf:function(){function y(S){return o(t(S))}return y}()})},83186:function(T,r,n){"use strict";var e=n(63964),a=n(81834);e({target:"Object",stat:!0,forced:Object.isExtensible!==a},{isExtensible:a})},76065:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(77568),o=n(7462),p=n(3782),b=Object.isFrozen,y=p||a(function(){b(1)});e({target:"Object",stat:!0,forced:y},{isFrozen:function(){function S(k){return!t(k)||p&&o(k)==="ArrayBuffer"?!0:b?b(k):!1}return S}()})},13411:function(T,r,n){"use strict";var e=n(63964),a=n(40033),t=n(77568),o=n(7462),p=n(3782),b=Object.isSealed,y=p||a(function(){b(1)});e({target:"Object",stat:!0,forced:y},{isSealed:function(){function S(k){return!t(k)||p&&o(k)==="ArrayBuffer"?!0:b?b(k):!1}return S}()})},76882:function(T,r,n){"use strict";var e=n(63964),a=n(5700);e({target:"Object",stat:!0},{is:a})},26634:function(T,r,n){"use strict";var e=n(63964),a=n(46771),t=n(18450),o=n(40033),p=o(function(){t(1)});e({target:"Object",stat:!0,forced:p},{keys:function(){function b(y){return t(a(y))}return b}()})},53118:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(57377),o=n(46771),p=n(767),b=n(36917),y=n(27193).f;a&&e({target:"Object",proto:!0,forced:t},{__lookupGetter__:function(){function S(k){var h=o(this),i=p(k),c;do if(c=y(h,i))return c.get;while(h=b(h))}return S}()})},42514:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(57377),o=n(46771),p=n(767),b=n(36917),y=n(27193).f;a&&e({target:"Object",proto:!0,forced:t},{__lookupSetter__:function(){function S(k){var h=o(this),i=p(k),c;do if(c=y(h,i))return c.set;while(h=b(h))}return S}()})},84353:function(T,r,n){"use strict";var e=n(63964),a=n(77568),t=n(81969).onFreeze,o=n(50730),p=n(40033),b=Object.preventExtensions,y=p(function(){b(1)});e({target:"Object",stat:!0,forced:y,sham:!o},{preventExtensions:function(){function S(k){return b&&a(k)?b(t(k)):k}return S}()})},62987:function(T,r,n){"use strict";var e=n(63964),a=n(77568),t=n(81969).onFreeze,o=n(50730),p=n(40033),b=Object.seal,y=p(function(){b(1)});e({target:"Object",stat:!0,forced:y,sham:!o},{seal:function(){function S(k){return b&&a(k)?b(t(k)):k}return S}()})},48993:function(T,r,n){"use strict";var e=n(63964),a=n(76649);e({target:"Object",stat:!0},{setPrototypeOf:a})},52917:function(T,r,n){"use strict";var e=n(2650),a=n(55938),t=n(2509);e||a(Object.prototype,"toString",t,{unsafe:!0})},4972:function(T,r,n){"use strict";var e=n(63964),a=n(70915).values;e({target:"Object",stat:!0},{values:function(){function t(o){return a(o)}return t}()})},28913:function(T,r,n){"use strict";var e=n(63964),a=n(28506);e({global:!0,forced:parseFloat!==a},{parseFloat:a})},36382:function(T,r,n){"use strict";var e=n(63964),a=n(13693);e({global:!0,forced:parseInt!==a},{parseInt:a})},48865:function(T,r,n){"use strict";var e=n(63964),a=n(91495),t=n(10320),o=n(81837),p=n(10729),b=n(49450),y=n(48199);e({target:"Promise",stat:!0,forced:y},{all:function(){function S(k){var h=this,i=o.f(h),c=i.resolve,m=i.reject,l=p(function(){var u=t(h.resolve),s=[],d=0,v=1;b(k,function(g){var C=d++,f=!1;v++,a(u,h,g).then(function(N){f||(f=!0,s[C]=N,--v||c(s))},m)}),--v||c(s)});return l.error&&m(l.value),i.promise}return S}()})},70641:function(T,r,n){"use strict";var e=n(63964),a=n(4493),t=n(74854).CONSTRUCTOR,o=n(67512),p=n(4009),b=n(55747),y=n(55938),S=o&&o.prototype;if(e({target:"Promise",proto:!0,forced:t,real:!0},{catch:function(){function h(i){return this.then(void 0,i)}return h}()}),!a&&b(o)){var k=p("Promise").prototype.catch;S.catch!==k&&y(S,"catch",k,{unsafe:!0})}},75946:function(T,r,n){"use strict";var e=n(63964),a=n(4493),t=n(81702),o=n(74685),p=n(91495),b=n(55938),y=n(76649),S=n(84925),k=n(58491),h=n(10320),i=n(55747),c=n(77568),m=n(60077),l=n(28987),u=n(60375).set,s=n(37713),d=n(72259),v=n(10729),g=n(9547),C=n(5419),f=n(67512),N=n(74854),V=n(81837),B="Promise",I=N.CONSTRUCTOR,L=N.REJECTION_EVENT,w=N.SUBCLASSING,A=C.getterFor(B),x=C.set,E=f&&f.prototype,P=f,D=E,M=o.TypeError,O=o.document,R=o.process,F=V.f,W=F,U=!!(O&&O.createEvent&&o.dispatchEvent),z="unhandledrejection",$="rejectionhandled",G=0,X=1,J=2,se=1,ie=2,me,q,re,ae,le=function(be){var Le;return c(be)&&i(Le=be.then)?Le:!1},Z=function(be,Le){var we=Le.value,xe=Le.state===X,Re=xe?be.ok:be.fail,He=be.resolve,ye=be.reject,de=be.domain,he,ke,ve;try{Re?(xe||(Le.rejection===ie&&ce(Le),Le.rejection=se),Re===!0?he=we:(de&&de.enter(),he=Re(we),de&&(de.exit(),ve=!0)),he===be.promise?ye(new M("Promise-chain cycle")):(ke=le(he))?p(ke,he,He,ye):He(he)):ye(we)}catch(Se){de&&!ve&&de.exit(),ye(Se)}},ne=function(be,Le){be.notified||(be.notified=!0,s(function(){for(var we=be.reactions,xe;xe=we.get();)Z(xe,be);be.notified=!1,Le&&!be.rejection&&fe(be)}))},te=function(be,Le,we){var xe,Re;U?(xe=O.createEvent("Event"),xe.promise=Le,xe.reason=we,xe.initEvent(be,!1,!0),o.dispatchEvent(xe)):xe={promise:Le,reason:we},!L&&(Re=o["on"+be])?Re(xe):be===z&&d("Unhandled promise rejection",we)},fe=function(be){p(u,o,function(){var Le=be.facade,we=be.value,xe=pe(be),Re;if(xe&&(Re=v(function(){t?R.emit("unhandledRejection",we,Le):te(z,Le,we)}),be.rejection=t||pe(be)?ie:se,Re.error))throw Re.value})},pe=function(be){return be.rejection!==se&&!be.parent},ce=function(be){p(u,o,function(){var Le=be.facade;t?R.emit("rejectionHandled",Le):te($,Le,be.value)})},Ve=function(be,Le,we){return function(xe){be(Le,xe,we)}},Ce=function(be,Le,we){be.done||(be.done=!0,we&&(be=we),be.value=Le,be.state=J,ne(be,!0))},Ne=function Be(be,Le,we){if(!be.done){be.done=!0,we&&(be=we);try{if(be.facade===Le)throw new M("Promise can't be resolved itself");var xe=le(Le);xe?s(function(){var Re={done:!1};try{p(xe,Le,Ve(Be,Re,be),Ve(Ce,Re,be))}catch(He){Ce(Re,He,be)}}):(be.value=Le,be.state=X,ne(be,!1))}catch(Re){Ce({done:!1},Re,be)}}};if(I&&(P=function(){function Be(be){m(this,D),h(be),p(me,this);var Le=A(this);try{be(Ve(Ne,Le),Ve(Ce,Le))}catch(we){Ce(Le,we)}}return Be}(),D=P.prototype,me=function(){function Be(be){x(this,{type:B,done:!1,notified:!1,parent:!1,reactions:new g,rejection:!1,state:G,value:void 0})}return Be}(),me.prototype=b(D,"then",function(){function Be(be,Le){var we=A(this),xe=F(l(this,P));return we.parent=!0,xe.ok=i(be)?be:!0,xe.fail=i(Le)&&Le,xe.domain=t?R.domain:void 0,we.state===G?we.reactions.add(xe):s(function(){Z(xe,we)}),xe.promise}return Be}()),q=function(){var be=new me,Le=A(be);this.promise=be,this.resolve=Ve(Ne,Le),this.reject=Ve(Ce,Le)},V.f=F=function(be){return be===P||be===re?new q(be):W(be)},!a&&i(f)&&E!==Object.prototype)){ae=E.then,w||b(E,"then",function(){function Be(be,Le){var we=this;return new P(function(xe,Re){p(ae,we,xe,Re)}).then(be,Le)}return Be}(),{unsafe:!0});try{delete E.constructor}catch(Be){}y&&y(E,D)}e({global:!0,constructor:!0,wrap:!0,forced:I},{Promise:P}),S(P,B,!1,!0),k(B)},69861:function(T,r,n){"use strict";var e=n(63964),a=n(4493),t=n(67512),o=n(40033),p=n(4009),b=n(55747),y=n(28987),S=n(66628),k=n(55938),h=t&&t.prototype,i=!!t&&o(function(){h.finally.call({then:function(){function m(){}return m}()},function(){})});if(e({target:"Promise",proto:!0,real:!0,forced:i},{finally:function(){function m(l){var u=y(this,p("Promise")),s=b(l);return this.then(s?function(d){return S(u,l()).then(function(){return d})}:l,s?function(d){return S(u,l()).then(function(){throw d})}:l)}return m}()}),!a&&b(t)){var c=p("Promise").prototype.finally;h.finally!==c&&k(h,"finally",c,{unsafe:!0})}},53092:function(T,r,n){"use strict";n(75946),n(48865),n(70641),n(16937),n(41719),n(59321)},16937:function(T,r,n){"use strict";var e=n(63964),a=n(91495),t=n(10320),o=n(81837),p=n(10729),b=n(49450),y=n(48199);e({target:"Promise",stat:!0,forced:y},{race:function(){function S(k){var h=this,i=o.f(h),c=i.reject,m=p(function(){var l=t(h.resolve);b(k,function(u){a(l,h,u).then(i.resolve,c)})});return m.error&&c(m.value),i.promise}return S}()})},41719:function(T,r,n){"use strict";var e=n(63964),a=n(81837),t=n(74854).CONSTRUCTOR;e({target:"Promise",stat:!0,forced:t},{reject:function(){function o(p){var b=a.f(this),y=b.reject;return y(p),b.promise}return o}()})},59321:function(T,r,n){"use strict";var e=n(63964),a=n(4009),t=n(4493),o=n(67512),p=n(74854).CONSTRUCTOR,b=n(66628),y=a("Promise"),S=t&&!p;e({target:"Promise",stat:!0,forced:t||p},{resolve:function(){function k(h){return b(S&&this===y?o:this,h)}return k}()})},29674:function(T,r,n){"use strict";var e=n(63964),a=n(61267),t=n(10320),o=n(30365),p=n(40033),b=!p(function(){Reflect.apply(function(){})});e({target:"Reflect",stat:!0,forced:b},{apply:function(){function y(S,k,h){return a(t(S),k,o(h))}return y}()})},81543:function(T,r,n){"use strict";var e=n(63964),a=n(4009),t=n(61267),o=n(66284),p=n(32606),b=n(30365),y=n(77568),S=n(80674),k=n(40033),h=a("Reflect","construct"),i=Object.prototype,c=[].push,m=k(function(){function s(){}return!(h(function(){},[],s)instanceof s)}),l=!k(function(){h(function(){})}),u=m||l;e({target:"Reflect",stat:!0,forced:u,sham:u},{construct:function(){function s(d,v){p(d),b(v);var g=arguments.length<3?d:p(arguments[2]);if(l&&!m)return h(d,v,g);if(d===g){switch(v.length){case 0:return new d;case 1:return new d(v[0]);case 2:return new d(v[0],v[1]);case 3:return new d(v[0],v[1],v[2]);case 4:return new d(v[0],v[1],v[2],v[3])}var C=[null];return t(c,C,v),new(t(o,d,C))}var f=g.prototype,N=S(y(f)?f:i),V=t(d,N,v);return y(V)?V:N}return s}()})},9373:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(30365),o=n(767),p=n(74595),b=n(40033),y=b(function(){Reflect.defineProperty(p.f({},1,{value:1}),1,{value:2})});e({target:"Reflect",stat:!0,forced:y,sham:!a},{defineProperty:function(){function S(k,h,i){t(k);var c=o(h);t(i);try{return p.f(k,c,i),!0}catch(m){return!1}}return S}()})},45093:function(T,r,n){"use strict";var e=n(63964),a=n(30365),t=n(27193).f;e({target:"Reflect",stat:!0},{deleteProperty:function(){function o(p,b){var y=t(a(p),b);return y&&!y.configurable?!1:delete p[b]}return o}()})},5815:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(30365),o=n(27193);e({target:"Reflect",stat:!0,sham:!a},{getOwnPropertyDescriptor:function(){function p(b,y){return o.f(t(b),y)}return p}()})},88527:function(T,r,n){"use strict";var e=n(63964),a=n(30365),t=n(36917),o=n(9225);e({target:"Reflect",stat:!0,sham:!o},{getPrototypeOf:function(){function p(b){return t(a(b))}return p}()})},63074:function(T,r,n){"use strict";var e=n(63964),a=n(91495),t=n(77568),o=n(30365),p=n(98373),b=n(27193),y=n(36917);function S(k,h){var i=arguments.length<3?k:arguments[2],c,m;if(o(k)===i)return k[h];if(c=b.f(k,h),c)return p(c)?c.value:c.get===void 0?void 0:a(c.get,i);if(t(m=y(k)))return S(m,h,i)}e({target:"Reflect",stat:!0},{get:S})},66390:function(T,r,n){"use strict";var e=n(63964);e({target:"Reflect",stat:!0},{has:function(){function a(t,o){return o in t}return a}()})},7784:function(T,r,n){"use strict";var e=n(63964),a=n(30365),t=n(81834);e({target:"Reflect",stat:!0},{isExtensible:function(){function o(p){return a(p),t(p)}return o}()})},50551:function(T,r,n){"use strict";var e=n(63964),a=n(97921);e({target:"Reflect",stat:!0},{ownKeys:a})},76483:function(T,r,n){"use strict";var e=n(63964),a=n(4009),t=n(30365),o=n(50730);e({target:"Reflect",stat:!0,sham:!o},{preventExtensions:function(){function p(b){t(b);try{var y=a("Object","preventExtensions");return y&&y(b),!0}catch(S){return!1}}return p}()})},63915:function(T,r,n){"use strict";var e=n(63964),a=n(30365),t=n(35908),o=n(76649);o&&e({target:"Reflect",stat:!0},{setPrototypeOf:function(){function p(b,y){a(b),t(y);try{return o(b,y),!0}catch(S){return!1}}return p}()})},92046:function(T,r,n){"use strict";var e=n(63964),a=n(91495),t=n(30365),o=n(77568),p=n(98373),b=n(40033),y=n(74595),S=n(27193),k=n(36917),h=n(87458);function i(m,l,u){var s=arguments.length<4?m:arguments[3],d=S.f(t(m),l),v,g,C;if(!d){if(o(g=k(m)))return i(g,l,u,s);d=h(0)}if(p(d)){if(d.writable===!1||!o(s))return!1;if(v=S.f(s,l)){if(v.get||v.set||v.writable===!1)return!1;v.value=u,y.f(s,l,v)}else y.f(s,l,h(0,u))}else{if(C=d.set,C===void 0)return!1;a(C,s,u)}return!0}var c=b(function(){var m=function(){},l=y.f(new m,"a",{configurable:!0});return Reflect.set(m.prototype,"a",1,l)!==!1});e({target:"Reflect",stat:!0,forced:c},{set:i})},51454:function(T,r,n){"use strict";var e=n(58310),a=n(74685),t=n(67250),o=n(41314),p=n(5781),b=n(37909),y=n(80674),S=n(37310).f,k=n(21287),h=n(72586),i=n(12605),c=n(73392),m=n(62115),l=n(34550),u=n(55938),s=n(40033),d=n(45299),v=n(5419).enforce,g=n(58491),C=n(24697),f=n(39173),N=n(35688),V=C("match"),B=a.RegExp,I=B.prototype,L=a.SyntaxError,w=t(I.exec),A=t("".charAt),x=t("".replace),E=t("".indexOf),P=t("".slice),D=/^\?<[^\s\d!#%&*+<=>@^][^\s!#%&*+<=>@^]*>/,M=/a/g,O=/a/g,R=new B(M)!==M,F=m.MISSED_STICKY,W=m.UNSUPPORTED_Y,U=e&&(!R||F||f||N||s(function(){return O[V]=!1,B(M)!==M||B(O)===O||String(B(M,"i"))!=="/a/i"})),z=function(ie){for(var me=ie.length,q=0,re="",ae=!1,le;q<=me;q++){if(le=A(ie,q),le==="\\"){re+=le+A(ie,++q);continue}!ae&&le==="."?re+="[\\s\\S]":(le==="["?ae=!0:le==="]"&&(ae=!1),re+=le)}return re},$=function(ie){for(var me=ie.length,q=0,re="",ae=[],le=y(null),Z=!1,ne=!1,te=0,fe="",pe;q<=me;q++){if(pe=A(ie,q),pe==="\\")pe+=A(ie,++q);else if(pe==="]")Z=!1;else if(!Z)switch(!0){case pe==="[":Z=!0;break;case pe==="(":w(D,P(ie,q+1))&&(q+=2,ne=!0),re+=pe,te++;continue;case(pe===">"&&ne):if(fe===""||d(le,fe))throw new L("Invalid capture group name");le[fe]=!0,ae[ae.length]=[fe,te],ne=!1,fe="";continue}ne?fe+=pe:re+=pe}return[re,ae]};if(o("RegExp",U)){for(var G=function(){function se(ie,me){var q=k(I,this),re=h(ie),ae=me===void 0,le=[],Z=ie,ne,te,fe,pe,ce,Ve;if(!q&&re&&ae&&ie.constructor===G)return ie;if((re||k(I,ie))&&(ie=ie.source,ae&&(me=c(Z))),ie=ie===void 0?"":i(ie),me=me===void 0?"":i(me),Z=ie,f&&"dotAll"in M&&(te=!!me&&E(me,"s")>-1,te&&(me=x(me,/s/g,""))),ne=me,F&&"sticky"in M&&(fe=!!me&&E(me,"y")>-1,fe&&W&&(me=x(me,/y/g,""))),N&&(pe=$(ie),ie=pe[0],le=pe[1]),ce=p(B(ie,me),q?this:I,G),(te||fe||le.length)&&(Ve=v(ce),te&&(Ve.dotAll=!0,Ve.raw=G(z(ie),ne)),fe&&(Ve.sticky=!0),le.length&&(Ve.groups=le)),ie!==Z)try{b(ce,"source",Z===""?"(?:)":Z)}catch(Ce){}return ce}return se}(),X=S(B),J=0;X.length>J;)l(G,B,X[J++]);I.constructor=G,G.prototype=I,u(a,"RegExp",G,{constructor:!0})}g("RegExp")},79669:function(T,r,n){"use strict";var e=n(63964),a=n(14489);e({target:"RegExp",proto:!0,forced:/./.exec!==a},{exec:a})},23057:function(T,r,n){"use strict";var e=n(74685),a=n(58310),t=n(73936),o=n(70901),p=n(40033),b=e.RegExp,y=b.prototype,S=a&&p(function(){var k=!0;try{b(".","d")}catch(d){k=!1}var h={},i="",c=k?"dgimsy":"gimsy",m=function(v,g){Object.defineProperty(h,v,{get:function(){function C(){return i+=g,!0}return C}()})},l={dotAll:"s",global:"g",ignoreCase:"i",multiline:"m",sticky:"y"};k&&(l.hasIndices="d");for(var u in l)m(u,l[u]);var s=Object.getOwnPropertyDescriptor(y,"flags").get.call(h);return s!==c||i!==c});S&&t(y,"flags",{configurable:!0,get:o})},57983:function(T,r,n){"use strict";var e=n(70520).PROPER,a=n(55938),t=n(30365),o=n(12605),p=n(40033),b=n(73392),y="toString",S=RegExp.prototype,k=S[y],h=p(function(){return k.call({source:"a",flags:"b"})!=="/a/b"}),i=e&&k.name!==y;(h||i)&&a(S,y,function(){function c(){var m=t(this),l=o(m.source),u=o(b(m));return"/"+l+"/"+u}return c}(),{unsafe:!0})},1963:function(T,r,n){"use strict";var e=n(45150),a=n(41028);e("Set",function(t){return function(){function o(){return t(this,arguments.length?arguments[0]:void 0)}return o}()},a)},17953:function(T,r,n){"use strict";n(1963)},95309:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("anchor")},{anchor:function(){function o(p){return a(this,"a","name",p)}return o}()})},82256:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("big")},{big:function(){function o(){return a(this,"big","","")}return o}()})},49484:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("blink")},{blink:function(){function o(){return a(this,"blink","","")}return o}()})},38931:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("bold")},{bold:function(){function o(){return a(this,"b","","")}return o}()})},30442:function(T,r,n){"use strict";var e=n(63964),a=n(50233).codeAt;e({target:"String",proto:!0},{codePointAt:function(){function t(o){return a(this,o)}return t}()})},6403:function(T,r,n){"use strict";var e=n(63964),a=n(71138),t=n(27193).f,o=n(10188),p=n(12605),b=n(86213),y=n(16952),S=n(45490),k=n(4493),h=a("".slice),i=Math.min,c=S("endsWith"),m=!k&&!c&&!!function(){var l=t(String.prototype,"endsWith");return l&&!l.writable}();e({target:"String",proto:!0,forced:!m&&!c},{endsWith:function(){function l(u){var s=p(y(this));b(u);var d=arguments.length>1?arguments[1]:void 0,v=s.length,g=d===void 0?v:i(o(d),v),C=p(u);return h(s,g-C.length,g)===C}return l}()})},39308:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("fixed")},{fixed:function(){function o(){return a(this,"tt","","")}return o}()})},91550:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("fontcolor")},{fontcolor:function(){function o(p){return a(this,"font","color",p)}return o}()})},75008:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("fontsize")},{fontsize:function(){function o(p){return a(this,"font","size",p)}return o}()})},9867:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(13912),o=RangeError,p=String.fromCharCode,b=String.fromCodePoint,y=a([].join),S=!!b&&b.length!==1;e({target:"String",stat:!0,arity:1,forced:S},{fromCodePoint:function(){function k(h){for(var i=[],c=arguments.length,m=0,l;c>m;){if(l=+arguments[m++],t(l,1114111)!==l)throw new o(l+" is not a valid code point");i[m]=l<65536?p(l):p(((l-=65536)>>10)+55296,l%1024+56320)}return y(i,"")}return k}()})},43673:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(86213),o=n(16952),p=n(12605),b=n(45490),y=a("".indexOf);e({target:"String",proto:!0,forced:!b("includes")},{includes:function(){function S(k){return!!~y(p(o(this)),p(t(k)),arguments.length>1?arguments[1]:void 0)}return S}()})},56027:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("italics")},{italics:function(){function o(){return a(this,"i","","")}return o}()})},12354:function(T,r,n){"use strict";var e=n(50233).charAt,a=n(12605),t=n(5419),o=n(65574),p=n(5959),b="String Iterator",y=t.set,S=t.getterFor(b);o(String,"String",function(k){y(this,{type:b,string:a(k),index:0})},function(){function k(){var h=S(this),i=h.string,c=h.index,m;return c>=i.length?p(void 0,!0):(m=e(i,c),h.index+=m.length,p(m,!1))}return k}())},50340:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("link")},{link:function(){function o(p){return a(this,"a","href",p)}return o}()})},22515:function(T,r,n){"use strict";var e=n(91495),a=n(79942),t=n(30365),o=n(42871),p=n(10188),b=n(12605),y=n(16952),S=n(78060),k=n(35483),h=n(28340);a("match",function(i,c,m){return[function(){function l(u){var s=y(this),d=o(u)?void 0:S(u,i);return d?e(d,u,s):new RegExp(u)[i](b(s))}return l}(),function(l){var u=t(this),s=b(l),d=m(c,u,s);if(d.done)return d.value;if(!u.global)return h(u,s);var v=u.unicode;u.lastIndex=0;for(var g=[],C=0,f;(f=h(u,s))!==null;){var N=b(f[0]);g[C]=N,N===""&&(u.lastIndex=k(s,p(u.lastIndex),v)),C++}return C===0?null:g}]})},5143:function(T,r,n){"use strict";var e=n(63964),a=n(24051).end,t=n(34125);e({target:"String",proto:!0,forced:t},{padEnd:function(){function o(p){return a(this,p,arguments.length>1?arguments[1]:void 0)}return o}()})},93514:function(T,r,n){"use strict";var e=n(63964),a=n(24051).start,t=n(34125);e({target:"String",proto:!0,forced:t},{padStart:function(){function o(p){return a(this,p,arguments.length>1?arguments[1]:void 0)}return o}()})},5416:function(T,r,n){"use strict";var e=n(63964),a=n(67250),t=n(57591),o=n(46771),p=n(12605),b=n(24760),y=a([].push),S=a([].join);e({target:"String",stat:!0},{raw:function(){function k(h){var i=t(o(h).raw),c=b(i);if(!c)return"";for(var m=arguments.length,l=[],u=0;;){if(y(l,p(i[u++])),u===c)return S(l,"");u")!=="7"});o("replace",function(x,E,P){var D=w?"$":"$0";return[function(){function M(O,R){var F=c(this),W=S(O)?void 0:l(O,v);return W?a(W,O,F,R):a(E,i(F),O,R)}return M}(),function(M,O){var R=b(this),F=i(M);if(typeof O=="string"&&V(O,D)===-1&&V(O,"$<")===-1){var W=P(E,R,F,O);if(W.done)return W.value}var U=y(O);U||(O=i(O));var z=R.global,$;z&&($=R.unicode,R.lastIndex=0);for(var G=[],X;X=s(R,F),!(X===null||(N(G,X),!z));){var J=i(X[0]);J===""&&(R.lastIndex=m(F,h(R.lastIndex),$))}for(var se="",ie=0,me=0;me=ie&&(se+=B(F,ie,re)+le,ie=re+q.length)}return se+B(F,ie)}]},!A||!L||w)},63272:function(T,r,n){"use strict";var e=n(91495),a=n(79942),t=n(30365),o=n(42871),p=n(16952),b=n(5700),y=n(12605),S=n(78060),k=n(28340);a("search",function(h,i,c){return[function(){function m(l){var u=p(this),s=o(l)?void 0:S(l,h);return s?e(s,l,u):new RegExp(l)[h](y(u))}return m}(),function(m){var l=t(this),u=y(m),s=c(i,l,u);if(s.done)return s.value;var d=l.lastIndex;b(d,0)||(l.lastIndex=0);var v=k(l,u);return b(l.lastIndex,d)||(l.lastIndex=d),v===null?-1:v.index}]})},34325:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("small")},{small:function(){function o(){return a(this,"small","","")}return o}()})},39930:function(T,r,n){"use strict";var e=n(91495),a=n(67250),t=n(79942),o=n(30365),p=n(42871),b=n(16952),y=n(28987),S=n(35483),k=n(10188),h=n(12605),i=n(78060),c=n(28340),m=n(62115),l=n(40033),u=m.UNSUPPORTED_Y,s=4294967295,d=Math.min,v=a([].push),g=a("".slice),C=!l(function(){var N=/(?:)/,V=N.exec;N.exec=function(){return V.apply(this,arguments)};var B="ab".split(N);return B.length!==2||B[0]!=="a"||B[1]!=="b"}),f="abbc".split(/(b)*/)[1]==="c"||"test".split(/(?:)/,-1).length!==4||"ab".split(/(?:ab)*/).length!==2||".".split(/(.?)(.?)/).length!==4||".".split(/()()/).length>1||"".split(/.?/).length;t("split",function(N,V,B){var I="0".split(void 0,0).length?function(L,w){return L===void 0&&w===0?[]:e(V,this,L,w)}:V;return[function(){function L(w,A){var x=b(this),E=p(w)?void 0:i(w,N);return E?e(E,w,x,A):e(I,h(x),w,A)}return L}(),function(L,w){var A=o(this),x=h(L);if(!f){var E=B(I,A,x,w,I!==V);if(E.done)return E.value}var P=y(A,RegExp),D=A.unicode,M=(A.ignoreCase?"i":"")+(A.multiline?"m":"")+(A.unicode?"u":"")+(u?"g":"y"),O=new P(u?"^(?:"+A.source+")":A,M),R=w===void 0?s:w>>>0;if(R===0)return[];if(x.length===0)return c(O,x)===null?[x]:[];for(var F=0,W=0,U=[];W1?arguments[1]:void 0,s.length)),v=p(u);return h(s,d,d+v.length)===v}return l}()})},74498:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("strike")},{strike:function(){function o(){return a(this,"strike","","")}return o}()})},15812:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("sub")},{sub:function(){function o(){return a(this,"sub","","")}return o}()})},57726:function(T,r,n){"use strict";var e=n(63964),a=n(72506),t=n(88539);e({target:"String",proto:!0,forced:t("sup")},{sup:function(){function o(){return a(this,"sup","","")}return o}()})},70604:function(T,r,n){"use strict";n(99159);var e=n(63964),a=n(43476);e({target:"String",proto:!0,name:"trimEnd",forced:"".trimEnd!==a},{trimEnd:a})},85404:function(T,r,n){"use strict";var e=n(63964),a=n(43885);e({target:"String",proto:!0,name:"trimStart",forced:"".trimLeft!==a},{trimLeft:a})},99159:function(T,r,n){"use strict";var e=n(63964),a=n(43476);e({target:"String",proto:!0,name:"trimEnd",forced:"".trimRight!==a},{trimRight:a})},34965:function(T,r,n){"use strict";n(85404);var e=n(63964),a=n(43885);e({target:"String",proto:!0,name:"trimStart",forced:"".trimStart!==a},{trimStart:a})},8448:function(T,r,n){"use strict";var e=n(63964),a=n(92648).trim,t=n(90012);e({target:"String",proto:!0,forced:t("trim")},{trim:function(){function o(){return a(this)}return o}()})},79250:function(T,r,n){"use strict";var e=n(85889);e("asyncIterator")},49899:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(91495),o=n(67250),p=n(4493),b=n(58310),y=n(52357),S=n(40033),k=n(45299),h=n(21287),i=n(30365),c=n(57591),m=n(767),l=n(12605),u=n(87458),s=n(80674),d=n(18450),v=n(37310),g=n(81644),C=n(89235),f=n(27193),N=n(74595),V=n(24239),B=n(12867),I=n(55938),L=n(73936),w=n(16639),A=n(19417),x=n(79195),E=n(16738),P=n(24697),D=n(55557),M=n(85889),O=n(52360),R=n(84925),F=n(5419),W=n(22603).forEach,U=A("hidden"),z="Symbol",$="prototype",G=F.set,X=F.getterFor(z),J=Object[$],se=a.Symbol,ie=se&&se[$],me=a.RangeError,q=a.TypeError,re=a.QObject,ae=f.f,le=N.f,Z=g.f,ne=B.f,te=o([].push),fe=w("symbols"),pe=w("op-symbols"),ce=w("wks"),Ve=!re||!re[$]||!re[$].findChild,Ce=function(he,ke,ve){var Se=ae(J,ke);Se&&delete J[ke],le(he,ke,ve),Se&&he!==J&&le(J,ke,Se)},Ne=b&&S(function(){return s(le({},"a",{get:function(){function de(){return le(this,"a",{value:7}).a}return de}()})).a!==7})?Ce:le,Be=function(he,ke){var ve=fe[he]=s(ie);return G(ve,{type:z,tag:he,description:ke}),b||(ve.description=ke),ve},be=function(){function de(he,ke,ve){he===J&&be(pe,ke,ve),i(he);var Se=m(ke);return i(ve),k(fe,Se)?(ve.enumerable?(k(he,U)&&he[U][Se]&&(he[U][Se]=!1),ve=s(ve,{enumerable:u(0,!1)})):(k(he,U)||le(he,U,u(1,s(null))),he[U][Se]=!0),Ne(he,Se,ve)):le(he,Se,ve)}return de}(),Le=function(){function de(he,ke){i(he);var ve=c(ke),Se=d(ve).concat(ye(ve));return W(Se,function(Pe){(!b||t(xe,ve,Pe))&&be(he,Pe,ve[Pe])}),he}return de}(),we=function(){function de(he,ke){return ke===void 0?s(he):Le(s(he),ke)}return de}(),xe=function(){function de(he){var ke=m(he),ve=t(ne,this,ke);return this===J&&k(fe,ke)&&!k(pe,ke)?!1:ve||!k(this,ke)||!k(fe,ke)||k(this,U)&&this[U][ke]?ve:!0}return de}(),Re=function(){function de(he,ke){var ve=c(he),Se=m(ke);if(!(ve===J&&k(fe,Se)&&!k(pe,Se))){var Pe=ae(ve,Se);return Pe&&k(fe,Se)&&!(k(ve,U)&&ve[U][Se])&&(Pe.enumerable=!0),Pe}}return de}(),He=function(){function de(he){var ke=Z(c(he)),ve=[];return W(ke,function(Se){!k(fe,Se)&&!k(x,Se)&&te(ve,Se)}),ve}return de}(),ye=function(he){var ke=he===J,ve=Z(ke?pe:c(he)),Se=[];return W(ve,function(Pe){k(fe,Pe)&&(!ke||k(J,Pe))&&te(Se,fe[Pe])}),Se};y||(se=function(){function de(){if(h(ie,this))throw new q("Symbol is not a constructor");var he=!arguments.length||arguments[0]===void 0?void 0:l(arguments[0]),ke=E(he),ve=function(){function Se(Pe){var je=this===void 0?a:this;je===J&&t(Se,pe,Pe),k(je,U)&&k(je[U],ke)&&(je[U][ke]=!1);var Fe=u(1,Pe);try{Ne(je,ke,Fe)}catch(ze){if(!(ze instanceof me))throw ze;Ce(je,ke,Fe)}}return Se}();return b&&Ve&&Ne(J,ke,{configurable:!0,set:ve}),Be(ke,he)}return de}(),ie=se[$],I(ie,"toString",function(){function de(){return X(this).tag}return de}()),I(se,"withoutSetter",function(de){return Be(E(de),de)}),B.f=xe,N.f=be,V.f=Le,f.f=Re,v.f=g.f=He,C.f=ye,D.f=function(de){return Be(P(de),de)},b&&(L(ie,"description",{configurable:!0,get:function(){function de(){return X(this).description}return de}()}),p||I(J,"propertyIsEnumerable",xe,{unsafe:!0}))),e({global:!0,constructor:!0,wrap:!0,forced:!y,sham:!y},{Symbol:se}),W(d(ce),function(de){M(de)}),e({target:z,stat:!0,forced:!y},{useSetter:function(){function de(){Ve=!0}return de}(),useSimple:function(){function de(){Ve=!1}return de}()}),e({target:"Object",stat:!0,forced:!y,sham:!b},{create:we,defineProperty:be,defineProperties:Le,getOwnPropertyDescriptor:Re}),e({target:"Object",stat:!0,forced:!y},{getOwnPropertyNames:He}),O(),R(se,z),x[U]=!0},10933:function(T,r,n){"use strict";var e=n(63964),a=n(58310),t=n(74685),o=n(67250),p=n(45299),b=n(55747),y=n(21287),S=n(12605),k=n(73936),h=n(5774),i=t.Symbol,c=i&&i.prototype;if(a&&b(i)&&(!("description"in c)||i().description!==void 0)){var m={},l=function(){function f(){var N=arguments.length<1||arguments[0]===void 0?void 0:S(arguments[0]),V=y(c,this)?new i(N):N===void 0?i():i(N);return N===""&&(m[V]=!0),V}return f}();h(l,i),l.prototype=c,c.constructor=l;var u=String(i("description detection"))==="Symbol(description detection)",s=o(c.valueOf),d=o(c.toString),v=/^Symbol\((.*)\)[^)]+$/,g=o("".replace),C=o("".slice);k(c,"description",{configurable:!0,get:function(){function f(){var N=s(this);if(p(m,N))return"";var V=d(N),B=u?C(V,7,-1):g(V,v,"$1");return B===""?void 0:B}return f}()}),e({global:!0,constructor:!0,forced:!0},{Symbol:l})}},30828:function(T,r,n){"use strict";var e=n(63964),a=n(4009),t=n(45299),o=n(12605),p=n(16639),b=n(66570),y=p("string-to-symbol-registry"),S=p("symbol-to-string-registry");e({target:"Symbol",stat:!0,forced:!b},{for:function(){function k(h){var i=o(h);if(t(y,i))return y[i];var c=a("Symbol")(i);return y[i]=c,S[c]=i,c}return k}()})},53795:function(T,r,n){"use strict";var e=n(85889);e("hasInstance")},87806:function(T,r,n){"use strict";var e=n(85889);e("isConcatSpreadable")},64677:function(T,r,n){"use strict";var e=n(85889);e("iterator")},33313:function(T,r,n){"use strict";n(49899),n(30828),n(6862),n(53008),n(28603)},6862:function(T,r,n){"use strict";var e=n(63964),a=n(45299),t=n(71399),o=n(89393),p=n(16639),b=n(66570),y=p("symbol-to-string-registry");e({target:"Symbol",stat:!0,forced:!b},{keyFor:function(){function S(k){if(!t(k))throw new TypeError(o(k)+" is not a symbol");if(a(y,k))return y[k]}return S}()})},48058:function(T,r,n){"use strict";var e=n(85889);e("match")},51583:function(T,r,n){"use strict";var e=n(85889);e("replace")},82403:function(T,r,n){"use strict";var e=n(85889);e("search")},34265:function(T,r,n){"use strict";var e=n(85889);e("species")},3295:function(T,r,n){"use strict";var e=n(85889);e("split")},1078:function(T,r,n){"use strict";var e=n(85889),a=n(52360);e("toPrimitive"),a()},63207:function(T,r,n){"use strict";var e=n(4009),a=n(85889),t=n(84925);a("toStringTag"),t(e("Symbol"),"Symbol")},80520:function(T,r,n){"use strict";var e=n(85889);e("unscopables")},99872:function(T,r,n){"use strict";var e=n(67250),a=n(4246),t=n(71447),o=e(t),p=a.aTypedArray,b=a.exportTypedArrayMethod;b("copyWithin",function(){function y(S,k){return o(p(this),S,k,arguments.length>2?arguments[2]:void 0)}return y}())},73364:function(T,r,n){"use strict";var e=n(4246),a=n(22603).every,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("every",function(){function p(b){return a(t(this),b,arguments.length>1?arguments[1]:void 0)}return p}())},58166:function(T,r,n){"use strict";var e=n(4246),a=n(88471),t=n(61484),o=n(2281),p=n(91495),b=n(67250),y=n(40033),S=e.aTypedArray,k=e.exportTypedArrayMethod,h=b("".slice),i=y(function(){var c=0;return new Int8Array(2).fill({valueOf:function(){function m(){return c++}return m}()}),c!==1});k("fill",function(){function c(m){var l=arguments.length;S(this);var u=h(o(this),0,3)==="Big"?t(m):+m;return p(a,this,u,l>1?arguments[1]:void 0,l>2?arguments[2]:void 0)}return c}(),i)},23793:function(T,r,n){"use strict";var e=n(4246),a=n(22603).filter,t=n(45399),o=e.aTypedArray,p=e.exportTypedArrayMethod;p("filter",function(){function b(y){var S=a(o(this),y,arguments.length>1?arguments[1]:void 0);return t(this,S)}return b}())},13917:function(T,r,n){"use strict";var e=n(4246),a=n(22603).findIndex,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("findIndex",function(){function p(b){return a(t(this),b,arguments.length>1?arguments[1]:void 0)}return p}())},43820:function(T,r,n){"use strict";var e=n(4246),a=n(22603).find,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("find",function(){function p(b){return a(t(this),b,arguments.length>1?arguments[1]:void 0)}return p}())},80756:function(T,r,n){"use strict";var e=n(80185);e("Float32",function(a){return function(){function t(o,p,b){return a(this,o,p,b)}return t}()})},70567:function(T,r,n){"use strict";var e=n(80185);e("Float64",function(a){return function(){function t(o,p,b){return a(this,o,p,b)}return t}()})},19852:function(T,r,n){"use strict";var e=n(4246),a=n(22603).forEach,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("forEach",function(){function p(b){a(t(this),b,arguments.length>1?arguments[1]:void 0)}return p}())},40379:function(T,r,n){"use strict";var e=n(86563),a=n(4246).exportTypedArrayStaticMethod,t=n(3805);a("from",t,e)},92770:function(T,r,n){"use strict";var e=n(4246),a=n(14211).includes,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("includes",function(){function p(b){return a(t(this),b,arguments.length>1?arguments[1]:void 0)}return p}())},81069:function(T,r,n){"use strict";var e=n(4246),a=n(14211).indexOf,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("indexOf",function(){function p(b){return a(t(this),b,arguments.length>1?arguments[1]:void 0)}return p}())},60037:function(T,r,n){"use strict";var e=n(80185);e("Int16",function(a){return function(){function t(o,p,b){return a(this,o,p,b)}return t}()})},44195:function(T,r,n){"use strict";var e=n(80185);e("Int32",function(a){return function(){function t(o,p,b){return a(this,o,p,b)}return t}()})},66756:function(T,r,n){"use strict";var e=n(80185);e("Int8",function(a){return function(){function t(o,p,b){return a(this,o,p,b)}return t}()})},63689:function(T,r,n){"use strict";var e=n(74685),a=n(40033),t=n(67250),o=n(4246),p=n(34570),b=n(24697),y=b("iterator"),S=e.Uint8Array,k=t(p.values),h=t(p.keys),i=t(p.entries),c=o.aTypedArray,m=o.exportTypedArrayMethod,l=S&&S.prototype,u=!a(function(){l[y].call([1])}),s=!!l&&l.values&&l[y]===l.values&&l.values.name==="values",d=function(){function v(){return k(c(this))}return v}();m("entries",function(){function v(){return i(c(this))}return v}(),u),m("keys",function(){function v(){return h(c(this))}return v}(),u),m("values",d,u||!s,{name:"values"}),m(y,d,u||!s,{name:"values"})},5659:function(T,r,n){"use strict";var e=n(4246),a=n(67250),t=e.aTypedArray,o=e.exportTypedArrayMethod,p=a([].join);o("join",function(){function b(y){return p(t(this),y)}return b}())},25014:function(T,r,n){"use strict";var e=n(4246),a=n(61267),t=n(1325),o=e.aTypedArray,p=e.exportTypedArrayMethod;p("lastIndexOf",function(){function b(y){var S=arguments.length;return a(t,o(this),S>1?[y,arguments[1]]:[y])}return b}())},32189:function(T,r,n){"use strict";var e=n(4246),a=n(22603).map,t=n(31082),o=e.aTypedArray,p=e.exportTypedArrayMethod;p("map",function(){function b(y){return a(o(this),y,arguments.length>1?arguments[1]:void 0,function(S,k){return new(t(S))(k)})}return b}())},23030:function(T,r,n){"use strict";var e=n(4246),a=n(86563),t=e.aTypedArrayConstructor,o=e.exportTypedArrayStaticMethod;o("of",function(){function p(){for(var b=0,y=arguments.length,S=new(t(this))(y);y>b;)S[b]=arguments[b++];return S}return p}(),a)},49110:function(T,r,n){"use strict";var e=n(4246),a=n(56844).right,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("reduceRight",function(){function p(b){var y=arguments.length;return a(t(this),b,y,y>1?arguments[1]:void 0)}return p}())},24309:function(T,r,n){"use strict";var e=n(4246),a=n(56844).left,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("reduce",function(){function p(b){var y=arguments.length;return a(t(this),b,y,y>1?arguments[1]:void 0)}return p}())},56445:function(T,r,n){"use strict";var e=n(4246),a=e.aTypedArray,t=e.exportTypedArrayMethod,o=Math.floor;t("reverse",function(){function p(){for(var b=this,y=a(b).length,S=o(y/2),k=0,h;k1?arguments[1]:void 0,1),g=b(d);if(l)return a(i,this,g,v);var C=this.length,f=o(g),N=0;if(f+v>C)throw new S("Wrong length");for(;Nm;)u[m]=i[m++];return u}return S}(),y)},88739:function(T,r,n){"use strict";var e=n(4246),a=n(22603).some,t=e.aTypedArray,o=e.exportTypedArrayMethod;o("some",function(){function p(b){return a(t(this),b,arguments.length>1?arguments[1]:void 0)}return p}())},60415:function(T,r,n){"use strict";var e=n(74685),a=n(71138),t=n(40033),o=n(10320),p=n(90274),b=n(4246),y=n(652),S=n(19228),k=n(5026),h=n(9342),i=b.aTypedArray,c=b.exportTypedArrayMethod,m=e.Uint16Array,l=m&&a(m.prototype.sort),u=!!l&&!(t(function(){l(new m(2),null)})&&t(function(){l(new m(2),{})})),s=!!l&&!t(function(){if(k)return k<74;if(y)return y<67;if(S)return!0;if(h)return h<602;var v=new m(516),g=Array(516),C,f;for(C=0;C<516;C++)f=C%4,v[C]=515-C,g[C]=C-2*f+3;for(l(v,function(N,V){return(N/4|0)-(V/4|0)}),C=0;C<516;C++)if(v[C]!==g[C])return!0}),d=function(g){return function(C,f){return g!==void 0?+g(C,f)||0:f!==f?-1:C!==C?1:C===0&&f===0?1/C>0&&1/f<0?1:-1:C>f}};c("sort",function(){function v(g){return g!==void 0&&o(g),s?l(this,g):p(i(this),d(g))}return v}(),!s||u)},72532:function(T,r,n){"use strict";var e=n(4246),a=n(10188),t=n(13912),o=n(31082),p=e.aTypedArray,b=e.exportTypedArrayMethod;b("subarray",function(){function y(S,k){var h=p(this),i=h.length,c=t(S,i),m=o(h);return new m(h.buffer,h.byteOffset+c*h.BYTES_PER_ELEMENT,a((k===void 0?i:t(k,i))-c))}return y}())},62207:function(T,r,n){"use strict";var e=n(74685),a=n(61267),t=n(4246),o=n(40033),p=n(54602),b=e.Int8Array,y=t.aTypedArray,S=t.exportTypedArrayMethod,k=[].toLocaleString,h=!!b&&o(function(){k.call(new b(1))}),i=o(function(){return[1,2].toLocaleString()!==new b([1,2]).toLocaleString()})||!o(function(){b.prototype.toLocaleString.call([1,2])});S("toLocaleString",function(){function c(){return a(k,h?p(y(this)):y(this),p(arguments))}return c}(),i)},906:function(T,r,n){"use strict";var e=n(4246).exportTypedArrayMethod,a=n(40033),t=n(74685),o=n(67250),p=t.Uint8Array,b=p&&p.prototype||{},y=[].toString,S=o([].join);a(function(){y.call({})})&&(y=function(){function h(){return S(this)}return h}());var k=b.toString!==y;e("toString",y,k)},78824:function(T,r,n){"use strict";var e=n(80185);e("Uint16",function(a){return function(){function t(o,p,b){return a(this,o,p,b)}return t}()})},72846:function(T,r,n){"use strict";var e=n(80185);e("Uint32",function(a){return function(){function t(o,p,b){return a(this,o,p,b)}return t}()})},24575:function(T,r,n){"use strict";var e=n(80185);e("Uint8",function(a){return function(){function t(o,p,b){return a(this,o,p,b)}return t}()})},71968:function(T,r,n){"use strict";var e=n(80185);e("Uint8",function(a){return function(){function t(o,p,b){return a(this,o,p,b)}return t}()},!0)},80040:function(T,r,n){"use strict";var e=n(50730),a=n(74685),t=n(67250),o=n(30145),p=n(81969),b=n(45150),y=n(39895),S=n(77568),k=n(5419).enforce,h=n(40033),i=n(21820),c=Object,m=Array.isArray,l=c.isExtensible,u=c.isFrozen,s=c.isSealed,d=c.freeze,v=c.seal,g=!a.ActiveXObject&&"ActiveXObject"in a,C,f=function(E){return function(){function P(){return E(this,arguments.length?arguments[0]:void 0)}return P}()},N=b("WeakMap",f,y),V=N.prototype,B=t(V.set),I=function(){return e&&h(function(){var E=d([]);return B(new N,E,1),!u(E)})};if(i)if(g){C=y.getConstructor(f,"WeakMap",!0),p.enable();var L=t(V.delete),w=t(V.has),A=t(V.get);o(V,{delete:function(){function x(E){if(S(E)&&!l(E)){var P=k(this);return P.frozen||(P.frozen=new C),L(this,E)||P.frozen.delete(E)}return L(this,E)}return x}(),has:function(){function x(E){if(S(E)&&!l(E)){var P=k(this);return P.frozen||(P.frozen=new C),w(this,E)||P.frozen.has(E)}return w(this,E)}return x}(),get:function(){function x(E){if(S(E)&&!l(E)){var P=k(this);return P.frozen||(P.frozen=new C),w(this,E)?A(this,E):P.frozen.get(E)}return A(this,E)}return x}(),set:function(){function x(E,P){if(S(E)&&!l(E)){var D=k(this);D.frozen||(D.frozen=new C),w(this,E)?B(this,E,P):D.frozen.set(E,P)}else B(this,E,P);return this}return x}()})}else I()&&o(V,{set:function(){function x(E,P){var D;return m(E)&&(u(E)?D=d:s(E)&&(D=v)),B(this,E,P),D&&D(E),this}return x}()})},90846:function(T,r,n){"use strict";n(80040)},67042:function(T,r,n){"use strict";var e=n(45150),a=n(39895);e("WeakSet",function(t){return function(){function o(){return t(this,arguments.length?arguments[0]:void 0)}return o}()},a)},40348:function(T,r,n){"use strict";n(67042)},5606:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(60375).clear;e({global:!0,bind:!0,enumerable:!0,forced:a.clearImmediate!==t},{clearImmediate:t})},83006:function(T,r,n){"use strict";n(5606),n(27807)},25764:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(37713),o=n(10320),p=n(24986),b=n(40033),y=n(58310),S=b(function(){return y&&Object.getOwnPropertyDescriptor(a,"queueMicrotask").value.length!==1});e({global:!0,enumerable:!0,dontCallGetSet:!0,forced:S},{queueMicrotask:function(){function k(h){p(arguments.length,1),t(o(h))}return k}()})},27807:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(60375).set,o=n(78362),p=a.setImmediate?o(t,!1):t;e({global:!0,bind:!0,enumerable:!0,forced:a.setImmediate!==p},{setImmediate:p})},45569:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(78362),o=t(a.setInterval,!0);e({global:!0,bind:!0,forced:a.setInterval!==o},{setInterval:o})},5213:function(T,r,n){"use strict";var e=n(63964),a=n(74685),t=n(78362),o=t(a.setTimeout,!0);e({global:!0,bind:!0,forced:a.setTimeout!==o},{setTimeout:o})},69401:function(T,r,n){"use strict";n(45569),n(5213)},7435:function(T){"use strict";/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */var r,n=[],e=[],a=function(){if(0)var k;window.onunload=function(){return r&&r.close()}},t=function(k){return e.push(k)},o=function(k){var h=[],i=function(u){return typeof u=="number"&&!Number.isFinite(u)?{__number__:String(u)}:typeof u=="undefined"?{__undefined__:!0}:u},c=function(u,s){if(typeof s=="object"){if(s===null)return s;if(h.includes(s))return"[circular ref]";h.push(s);var d=s instanceof Error||s.code&&s.message&&s.message.includes("Error");return d?{__error__:!0,string:String(s),stack:s.stack}:Array.isArray(s)?s.map(i):s}return i(s)},m=JSON.stringify(k,c);return h=null,m},p=function(k){if(0)var h,i,c},b=function(k,h){if(0)var i,c,m},y=function(){};T.exports={subscribe:t,sendMessage:p,sendLogEntry:b,setupHotReloading:y}}},kt={};function Y(T){var r=kt[T];if(r!==void 0)return r.exports;var n=kt[T]={exports:{}};return Jt[T](n,n.exports,Y),n.exports}(function(){Y.g=function(){if(typeof globalThis=="object")return globalThis;try{return this||new Function("return this")()}catch(T){if(typeof window=="object")return window}}()})(),function(){Y.o=function(T,r){return Object.prototype.hasOwnProperty.call(T,r)}}();var Rn={};(function(){"use strict";Y(33313),Y(10933),Y(79250),Y(53795),Y(87806),Y(64677),Y(48058),Y(51583),Y(82403),Y(34265),Y(3295),Y(1078),Y(63207),Y(80520),Y(39600),Y(93237),Y(32057),Y(68933),Y(47830),Y(13455),Y(64094),Y(61915),Y(32384),Y(25579),Y(63532),Y(33425),Y(43894),Y(99636),Y(34570),Y(94432),Y(24683),Y(69984),Y(32089),Y(60206),Y(29645),Y(4788),Y(58672),Y(19356),Y(48968),Y(49852),Y(2712),Y(864),Y(54243),Y(75621),Y(26267),Y(50095),Y(33451),Y(74587),Y(25082),Y(47421),Y(32122),Y(6306),Y(90216),Y(84663),Y(92332),Y(98329),Y(9631),Y(47091),Y(59660),Y(15383),Y(92866),Y(86107),Y(29248),Y(52540),Y(79007),Y(77199),Y(6522),Y(95542),Y(2966),Y(20997),Y(57400),Y(45571),Y(54800),Y(15709),Y(76059),Y(96614),Y(324),Y(90426),Y(95443),Y(87968),Y(55007),Y(55323),Y(13521),Y(5006),Y(99009),Y(85770),Y(23532),Y(87119),Y(78618),Y(27129),Y(31943),Y(3579),Y(97397),Y(85028),Y(8225),Y(43331),Y(62289),Y(56196),Y(2950),Y(44205),Y(76882),Y(83186),Y(76065),Y(13411),Y(26634),Y(53118),Y(42514),Y(84353),Y(62987),Y(48993),Y(52917),Y(4972),Y(28913),Y(36382),Y(53092),Y(69861),Y(29674),Y(81543),Y(9373),Y(45093),Y(63074),Y(5815),Y(88527),Y(66390),Y(7784),Y(50551),Y(76483),Y(92046),Y(63915),Y(51454),Y(79669),Y(23057),Y(57983),Y(17953),Y(30442),Y(6403),Y(9867),Y(43673),Y(12354),Y(22515),Y(5143),Y(93514),Y(5416),Y(11619),Y(44590),Y(63272),Y(39930),Y(4038),Y(8448),Y(70604),Y(34965),Y(95309),Y(82256),Y(49484),Y(38931),Y(39308),Y(91550),Y(75008),Y(56027),Y(50340),Y(34325),Y(74498),Y(15812),Y(57726),Y(80756),Y(70567),Y(66756),Y(60037),Y(44195),Y(24575),Y(71968),Y(78824),Y(72846),Y(99872),Y(73364),Y(58166),Y(23793),Y(43820),Y(13917),Y(19852),Y(40379),Y(92770),Y(81069),Y(63689),Y(5659),Y(25014),Y(32189),Y(23030),Y(24309),Y(49110),Y(56445),Y(30939),Y(48321),Y(88739),Y(60415),Y(72532),Y(62207),Y(906),Y(90846),Y(40348),Y(83006),Y(25764),Y(69401),Y(95012),Y(30236)})(),function(){"use strict";var T=Y(89005);Y(67160),Y(23542),Y(30386),Y(98996),Y(50578),Y(4444),Y(77870),Y(39108),Y(11714),Y(73492),Y(49641),Y(17570),Y(61858),Y(32882),Y(23632),Y(56492);var r=Y(85822),n=Y(7435),e=Y(56518),a=Y(26427),t=Y(18498),o=Y(49060),p=Y(72178),b=Y(24826),y;/** + * @file + * @copyright 2020 Aleksej Komarov + * @license MIT + */r.perf.mark("inception",(y=window.performance)==null||(y=y.timing)==null?void 0:y.navigationStart),r.perf.mark("init");var S=(0,p.configureStore)(),k=(0,o.createRenderer)(function(){(0,a.loadIconRefMap)();var i=Y(71253),c=i.getRoutedComponent,m=c(S);return(0,T.createComponentVNode)(2,p.StoreProvider,{store:S,children:(0,T.createComponentVNode)(2,m)})}),h=function i(){if(document.readyState==="loading"){document.addEventListener("DOMContentLoaded",i);return}(0,b.setupGlobalEvents)(),(0,e.setupHotKeys)(),(0,t.captureExternalLinks)(),S.subscribe(k),Byond.subscribe(function(c,m){return S.dispatch({type:c,payload:m})})};h()}()})();})(); +>>>>>>> 9ceda37a45c065c791d79be916749c10c3f554cb diff --git a/tgui/public/tgui.html b/tgui/public/tgui.html index cf55b01a26b5a..5eae2a4a96e21 100644 --- a/tgui/public/tgui.html +++ b/tgui/public/tgui.html @@ -1,730 +1,673 @@ - - - - - - - - - - + // If we're a Chromium client, just use the fancy method + if (window.cef_to_byond) { + cef_to_byond('byond://' + url); + return; + } - - - + } + + document.body.insertAdjacentHTML( + "afterbegin", + "" + + inline_html + + "" + ); +}; + + + + + - - - - - - - - - -
    - - -
    - - - A fatal exception has occurred at 002B:C562F1B7 in TGUI. The current - application will be terminated. Please remain calm. Get to the nearest - NTNet workstation and send the copy of the following stack trace to: - https://github.com/ParadiseSS13/Paradise. Thank you for your cooperation. - -
    - + + + + + + + + +
    + + +
    + + + A fatal exception has occurred at 002B:C562F1B7 in TGUI. The current + application will be terminated. Please remain calm. Get to the nearest + NTNet workstation and send the copy of the following stack trace to: + https://github.com/ParadiseSS13/Paradise. Thank you for your cooperation. + +
    + +
    + + - - - - + + diff --git a/tgui/yarn.lock b/tgui/yarn.lock index efa4ca333076a..d96bc6e28be27 100644 --- a/tgui/yarn.lock +++ b/tgui/yarn.lock @@ -2434,7 +2434,7 @@ __metadata: languageName: node linkType: hard -"@types/eslint-scope@npm:^3.7.3, @types/eslint-scope@npm:^3.7.7": +"@types/eslint-scope@npm:^3.7.3": version: 3.7.7 resolution: "@types/eslint-scope@npm:3.7.7" dependencies: @@ -2461,13 +2461,6 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:^1.0.6": - version: 1.0.6 - resolution: "@types/estree@npm:1.0.6" - checksum: 10/9d35d475095199c23e05b431bcdd1f6fec7380612aed068b14b2a08aa70494de8a9026765a5a91b1073f636fb0368f6d8973f518a31391d519e20c59388ed88d - languageName: node - linkType: hard - "@types/graceful-fs@npm:^4.1.3": version: 4.1.9 resolution: "@types/graceful-fs@npm:4.1.9" @@ -2690,16 +2683,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/ast@npm:1.14.1" - dependencies: - "@webassemblyjs/helper-numbers": "npm:1.13.2" - "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" - checksum: 10/f83e6abe38057f5d87c1fb356513a371a8b43c9b87657f2790741a66b1ef8ecf958d1391bc42f27c5fb33f58ab8286a38ea849fdd21f433cd4df1307424bab45 - languageName: node - linkType: hard - "@webassemblyjs/floating-point-hex-parser@npm:1.11.6": version: 1.11.6 resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.11.6" @@ -2707,13 +2690,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/floating-point-hex-parser@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.13.2" - checksum: 10/e866ec8433f4a70baa511df5e8f2ebcd6c24f4e2cc6274c7c5aabe2bcce3459ea4680e0f35d450e1f3602acf3913b6b8e4f15069c8cfd34ae8609fb9a7d01795 - languageName: node - linkType: hard - "@webassemblyjs/helper-api-error@npm:1.11.6": version: 1.11.6 resolution: "@webassemblyjs/helper-api-error@npm:1.11.6" @@ -2721,13 +2697,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-api-error@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/helper-api-error@npm:1.13.2" - checksum: 10/48b5df7fd3095bb252f59a139fe2cbd999a62ac9b488123e9a0da3906ad8a2f2da7b2eb21d328c01a90da987380928706395c2897d1f3ed9e2125b6d75a920d0 - languageName: node - linkType: hard - "@webassemblyjs/helper-buffer@npm:1.12.1": version: 1.12.1 resolution: "@webassemblyjs/helper-buffer@npm:1.12.1" @@ -2735,13 +2704,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-buffer@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/helper-buffer@npm:1.14.1" - checksum: 10/9690afeafa5e765a34620aa6216e9d40f9126d4e37e9726a2594bf60cab6b211ef20ab6670fd3c4449dd4a3497e69e49b2b725c8da0fb213208c7f45f15f5d5b - languageName: node - linkType: hard - "@webassemblyjs/helper-numbers@npm:1.11.6": version: 1.11.6 resolution: "@webassemblyjs/helper-numbers@npm:1.11.6" @@ -2753,17 +2715,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-numbers@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/helper-numbers@npm:1.13.2" - dependencies: - "@webassemblyjs/floating-point-hex-parser": "npm:1.13.2" - "@webassemblyjs/helper-api-error": "npm:1.13.2" - "@xtuc/long": "npm:4.2.2" - checksum: 10/e4c7d0b09811e1cda8eec644a022b560b28f4e974f50195375ccd007df5ee48a922a6dcff5ac40b6a8ec850d56d0ea6419318eee49fec7819ede14e90417a6a4 - languageName: node - linkType: hard - "@webassemblyjs/helper-wasm-bytecode@npm:1.11.6": version: 1.11.6 resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.11.6" @@ -2771,13 +2722,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-wasm-bytecode@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.13.2" - checksum: 10/3edd191fff7296df1ef3b023bdbe6cb5ea668f6386fd197ccfce46015c6f2a8cc9763cfb86503a0b94973ad27996645afff2252ee39a236513833259a47af6ed - languageName: node - linkType: hard - "@webassemblyjs/helper-wasm-section@npm:1.12.1": version: 1.12.1 resolution: "@webassemblyjs/helper-wasm-section@npm:1.12.1" @@ -2790,18 +2734,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-wasm-section@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/helper-wasm-section@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": "npm:1.14.1" - "@webassemblyjs/helper-buffer": "npm:1.14.1" - "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" - "@webassemblyjs/wasm-gen": "npm:1.14.1" - checksum: 10/6b73874f906532512371181d7088460f767966f26309e836060c5a8e4e4bfe6d523fb5f4c034b34aa22ebb1192815f95f0e264298769485c1f0980fdd63ae0ce - languageName: node - linkType: hard - "@webassemblyjs/ieee754@npm:1.11.6": version: 1.11.6 resolution: "@webassemblyjs/ieee754@npm:1.11.6" @@ -2811,15 +2743,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/ieee754@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/ieee754@npm:1.13.2" - dependencies: - "@xtuc/ieee754": "npm:^1.2.0" - checksum: 10/d7e3520baa37a7309fa7db4d73d69fb869878853b1ebd4b168821bd03fcc4c0e1669c06231315b0039035d9a7a462e53de3ad982da4a426a4b0743b5888e8673 - languageName: node - linkType: hard - "@webassemblyjs/leb128@npm:1.11.6": version: 1.11.6 resolution: "@webassemblyjs/leb128@npm:1.11.6" @@ -2829,15 +2752,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/leb128@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/leb128@npm:1.13.2" - dependencies: - "@xtuc/long": "npm:4.2.2" - checksum: 10/3a10542c86807061ec3230bac8ee732289c852b6bceb4b88ebd521a12fbcecec7c432848284b298154f28619e2746efbed19d6904aef06c49ef20a0b85f650cf - languageName: node - linkType: hard - "@webassemblyjs/utf8@npm:1.11.6": version: 1.11.6 resolution: "@webassemblyjs/utf8@npm:1.11.6" @@ -2845,13 +2759,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/utf8@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/utf8@npm:1.13.2" - checksum: 10/27885e5d19f339501feb210867d69613f281eda695ac508f04d69fa3398133d05b6870969c0242b054dc05420ed1cc49a64dea4fe0588c18d211cddb0117cc54 - languageName: node - linkType: hard - "@webassemblyjs/wasm-edit@npm:^1.12.1": version: 1.12.1 resolution: "@webassemblyjs/wasm-edit@npm:1.12.1" @@ -2868,22 +2775,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/wasm-edit@npm:^1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wasm-edit@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": "npm:1.14.1" - "@webassemblyjs/helper-buffer": "npm:1.14.1" - "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" - "@webassemblyjs/helper-wasm-section": "npm:1.14.1" - "@webassemblyjs/wasm-gen": "npm:1.14.1" - "@webassemblyjs/wasm-opt": "npm:1.14.1" - "@webassemblyjs/wasm-parser": "npm:1.14.1" - "@webassemblyjs/wast-printer": "npm:1.14.1" - checksum: 10/c62c50eadcf80876713f8c9f24106b18cf208160ab842fcb92060fd78c37bf37e7fcf0b7cbf1afc05d230277c2ce0f3f728432082c472dd1293e184a95f9dbdd - languageName: node - linkType: hard - "@webassemblyjs/wasm-gen@npm:1.12.1": version: 1.12.1 resolution: "@webassemblyjs/wasm-gen@npm:1.12.1" @@ -2897,19 +2788,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/wasm-gen@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wasm-gen@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": "npm:1.14.1" - "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" - "@webassemblyjs/ieee754": "npm:1.13.2" - "@webassemblyjs/leb128": "npm:1.13.2" - "@webassemblyjs/utf8": "npm:1.13.2" - checksum: 10/6085166b0987d3031355fe17a4f9ef0f412e08098d95454059aced2bd72a4c3df2bc099fa4d32d640551fc3eca1ac1a997b44432e46dc9d84642688e42c17ed4 - languageName: node - linkType: hard - "@webassemblyjs/wasm-opt@npm:1.12.1": version: 1.12.1 resolution: "@webassemblyjs/wasm-opt@npm:1.12.1" @@ -2922,18 +2800,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/wasm-opt@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wasm-opt@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": "npm:1.14.1" - "@webassemblyjs/helper-buffer": "npm:1.14.1" - "@webassemblyjs/wasm-gen": "npm:1.14.1" - "@webassemblyjs/wasm-parser": "npm:1.14.1" - checksum: 10/fa5d1ef8d2156e7390927f938f513b7fb4440dd6804b3d6c8622b7b1cf25a3abf1a5809f615896d4918e04b27b52bc3cbcf18faf2d563cb563ae0a9204a492db - languageName: node - linkType: hard - "@webassemblyjs/wasm-parser@npm:1.12.1, @webassemblyjs/wasm-parser@npm:^1.12.1": version: 1.12.1 resolution: "@webassemblyjs/wasm-parser@npm:1.12.1" @@ -2948,20 +2814,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/wasm-parser@npm:1.14.1, @webassemblyjs/wasm-parser@npm:^1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wasm-parser@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": "npm:1.14.1" - "@webassemblyjs/helper-api-error": "npm:1.13.2" - "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" - "@webassemblyjs/ieee754": "npm:1.13.2" - "@webassemblyjs/leb128": "npm:1.13.2" - "@webassemblyjs/utf8": "npm:1.13.2" - checksum: 10/07d9805fda88a893c984ed93d5a772d20d671e9731358ab61c6c1af8e0e58d1c42fc230c18974dfddebc9d2dd7775d514ba4d445e70080b16478b4b16c39c7d9 - languageName: node - linkType: hard - "@webassemblyjs/wast-printer@npm:1.12.1": version: 1.12.1 resolution: "@webassemblyjs/wast-printer@npm:1.12.1" @@ -2972,16 +2824,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/wast-printer@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wast-printer@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": "npm:1.14.1" - "@xtuc/long": "npm:4.2.2" - checksum: 10/cef09aad2fcd291bfcf9efdae2ea1e961a1ba0f925d1d9dcdd8c746d32fbaf431b6d26a0241699c0e39f82139018aa720b4ceb84ac6f4c78f13072747480db69 - languageName: node - linkType: hard - "@webpack-cli/configtest@npm:^2.1.1": version: 2.1.1 resolution: "@webpack-cli/configtest@npm:2.1.1" @@ -3062,6 +2904,15 @@ __metadata: languageName: node linkType: hard +"acorn-import-attributes@npm:^1.9.5": + version: 1.9.5 + resolution: "acorn-import-attributes@npm:1.9.5" + peerDependencies: + acorn: ^8 + checksum: 10/8bfbfbb6e2467b9b47abb4d095df717ab64fce2525da65eabee073e85e7975fb3a176b6c8bba17c99a7d8ede283a10a590272304eb54a93c4aa1af9790d47a8b + languageName: node + linkType: hard + "acorn-jsx@npm:^5.3.2": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" @@ -3096,15 +2947,6 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.14.0": - version: 8.14.0 - resolution: "acorn@npm:8.14.0" - bin: - acorn: bin/acorn - checksum: 10/6df29c35556782ca9e632db461a7f97947772c6c1d5438a81f0c873a3da3a792487e83e404d1c6c25f70513e91aa18745f6eafb1fcc3a43ecd1920b21dd173d2 - languageName: node - linkType: hard - "agent-base@npm:6": version: 6.0.2 resolution: "agent-base@npm:6.0.2" @@ -3618,20 +3460,6 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.24.0": - version: 4.24.2 - resolution: "browserslist@npm:4.24.2" - dependencies: - caniuse-lite: "npm:^1.0.30001669" - electron-to-chromium: "npm:^1.5.41" - node-releases: "npm:^2.0.18" - update-browserslist-db: "npm:^1.1.1" - bin: - browserslist: cli.js - checksum: 10/f8a9d78bbabe466c57ffd5c50a9e5582a5df9aa68f43078ca62a9f6d0d6c70ba72eca72d0a574dbf177cf55cdca85a46f7eb474917a47ae5398c66f8b76f7d1c - languageName: node - linkType: hard - "bser@npm:2.1.1": version: 2.1.1 resolution: "bser@npm:2.1.1" @@ -3716,13 +3544,6 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001669": - version: 1.0.30001680 - resolution: "caniuse-lite@npm:1.0.30001680" - checksum: 10/38ec7e06e18ef1040740f93dff65dc4c9a7593376a783a96370f3845c586ed1d464e26b992d97919938fb07b68a4f2fb1609f66c586c3f1e7310e6511b81793f - languageName: node - linkType: hard - "chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -3980,13 +3801,13 @@ __metadata: linkType: hard "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": - version: 7.0.6 - resolution: "cross-spawn@npm:7.0.6" + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" dependencies: path-key: "npm:^3.1.0" shebang-command: "npm:^2.0.0" which: "npm:^2.0.1" - checksum: 10/0d52657d7ae36eb130999dffff1168ec348687b48dd38e2ff59992ed916c88d328cf1d07ff4a4a10bc78de5e1c23f04b306d569e42f7a2293915c081e4dfee86 + checksum: 10/e1a13869d2f57d974de0d9ef7acbf69dc6937db20b918525a01dacb5032129bd552d290d886d981e99f1b624cb03657084cc87bd40f115c07ecf376821c729ce languageName: node linkType: hard @@ -4273,13 +4094,6 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.41": - version: 1.5.63 - resolution: "electron-to-chromium@npm:1.5.63" - checksum: 10/fef9b9538102800f2429cef20c17efafa6b72eff3e4ae2d41e4887b6b46212c92f0bd560b6397dce7ec7274de655a79be1a863fddd33519a1ce9d173af5b063c - languageName: node - linkType: hard - "emittery@npm:^0.13.1": version: 0.13.1 resolution: "emittery@npm:0.13.1" @@ -4616,13 +4430,6 @@ __metadata: languageName: node linkType: hard -"escalade@npm:^3.2.0": - version: 3.2.0 - resolution: "escalade@npm:3.2.0" - checksum: 10/9d7169e3965b2f9ae46971afa392f6e5a25545ea30f2e2dd99c9b0a95a3f52b5653681a84f5b2911a413ddad2d7a93d3514165072f349b5ffc59c75a899970d6 - languageName: node - linkType: hard - "escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" @@ -7166,11 +6973,11 @@ __metadata: linkType: hard "nanoid@npm:^3.3.7": - version: 3.3.8 - resolution: "nanoid@npm:3.3.8" + version: 3.3.7 + resolution: "nanoid@npm:3.3.7" bin: nanoid: bin/nanoid.cjs - checksum: 10/2d1766606cf0d6f47b6f0fdab91761bb81609b2e3d367027aff45e6ee7006f660fb7e7781f4a34799fe6734f1268eeed2e37a5fdee809ade0c2d4eb11b0f9c40 + checksum: 10/ac1eb60f615b272bccb0e2b9cd933720dad30bf9708424f691b8113826bb91aca7e9d14ef5d9415a6ba15c266b37817256f58d8ce980c82b0ba3185352565679 languageName: node linkType: hard @@ -7229,13 +7036,6 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.18": - version: 2.0.18 - resolution: "node-releases@npm:2.0.18" - checksum: 10/241e5fa9556f1c12bafb83c6c3e94f8cf3d8f2f8f904906ecef6e10bcaa1d59aa61212d4651bec70052015fc54bd3fdcdbe7fc0f638a17e6685aa586c076ec4e - languageName: node - linkType: hard - "nopt@npm:^7.0.0": version: 7.2.0 resolution: "nopt@npm:7.2.0" @@ -7552,13 +7352,6 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.1.0": - version: 1.1.1 - resolution: "picocolors@npm:1.1.1" - checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 - languageName: node - linkType: hard - "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" @@ -8800,7 +8593,7 @@ __metadata: style-loader: "npm:^4.0.0" terser-webpack-plugin: "npm:^5.3.10" typescript: "npm:^5.5.3" - webpack: "npm:^5.97.0" + webpack: "npm:^5.94.0" webpack-bundle-analyzer: "npm:^4.10.2" webpack-cli: "npm:^5.1.4" languageName: unknown @@ -9125,20 +8918,6 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.1.1": - version: 1.1.1 - resolution: "update-browserslist-db@npm:1.1.1" - dependencies: - escalade: "npm:^3.2.0" - picocolors: "npm:^1.1.0" - peerDependencies: - browserslist: ">= 4.21.0" - bin: - update-browserslist-db: cli.js - checksum: 10/7678dd8609750588d01aa7460e8eddf2ff9d16c2a52fb1811190e0d056390f1fdffd94db3cf8fb209cf634ab4fa9407886338711c71cc6ccade5eeb22b093734 - languageName: node - linkType: hard - "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -9339,17 +9118,17 @@ __metadata: languageName: node linkType: hard -"webpack@npm:^5.97.0": - version: 5.97.1 - resolution: "webpack@npm:5.97.1" +"webpack@npm:^5.94.0": + version: 5.95.0 + resolution: "webpack@npm:5.95.0" dependencies: - "@types/eslint-scope": "npm:^3.7.7" - "@types/estree": "npm:^1.0.6" - "@webassemblyjs/ast": "npm:^1.14.1" - "@webassemblyjs/wasm-edit": "npm:^1.14.1" - "@webassemblyjs/wasm-parser": "npm:^1.14.1" - acorn: "npm:^8.14.0" - browserslist: "npm:^4.24.0" + "@types/estree": "npm:^1.0.5" + "@webassemblyjs/ast": "npm:^1.12.1" + "@webassemblyjs/wasm-edit": "npm:^1.12.1" + "@webassemblyjs/wasm-parser": "npm:^1.12.1" + acorn: "npm:^8.7.1" + acorn-import-attributes: "npm:^1.9.5" + browserslist: "npm:^4.21.10" chrome-trace-event: "npm:^1.0.2" enhanced-resolve: "npm:^5.17.1" es-module-lexer: "npm:^1.2.1" @@ -9371,7 +9150,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: 10/665bd3b8c84b20f0b1f250159865e4d3e9b76c682030313d49124d5f8e96357ccdcc799dd9fe0ebf010fdb33dbc59d9863d79676a308e868e360ac98f7c09987 + checksum: 10/0377ad3a550b041f26237c96fb55754625b0ce6bae83c1c2447e3262ad056b0b0ad770dcbb92b59f188e9a2bd56155ce910add17dcf023cfbe78bdec774380c1 languageName: node linkType: hard diff --git a/tools/UpdatePaths/Scripts/27268_snake_case_remap.txt b/tools/UpdatePaths/Scripts/27268_snake_case_remap.txt deleted file mode 100644 index 87ee4c8e2af7c..0000000000000 --- a/tools/UpdatePaths/Scripts/27268_snake_case_remap.txt +++ /dev/null @@ -1,183 +0,0 @@ -/datum/sprite_accessory/head_accessory/kidan/kidan_Mantie_Curled/@SUBTYPES : /datum/sprite_accessory/head_accessory/kidan/kidan_mantie_curled/@SUBTYPES{@OLD} -/datum/sprite_accessory/head_accessory/kidan/kidan_Mantie_Long/@SUBTYPES : /datum/sprite_accessory/head_accessory/kidan/kidan_mantie_long/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/splatterLayer/asteroidMonsters/@SUBTYPES : /datum/map_generator_module/splatter_layer/asteroid_monsters/@SUBTYPES{@OLD} -/obj/item/storage/backpack/duffel/syndie/shotgunXLmags/@SUBTYPES : /obj/item/storage/backpack/duffel/syndie/shotgun_xl_mags/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/splatterLayer/asteroidWalls/@SUBTYPES : /datum/map_generator_module/splatter_layer/asteroid_walls/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/bottomLayer/asteroidTurfs/@SUBTYPES : /datum/map_generator_module/bottom_layer/asteroid_turfs/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/bottomLayer/asteroidWalls/@SUBTYPES : /datum/map_generator_module/bottom_layer/asteroid_walls/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/splatterLayer/syndieMobs/@SUBTYPES : /datum/map_generator_module/splatter_layer/syndie_mobs/@SUBTYPES{@OLD} -/obj/item/clothing/accessory/medal/fluff/XannZxiax/@SUBTYPES : /obj/item/clothing/accessory/medal/fluff/xann_zxiax/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/bottomLayer/syndieFloor/@SUBTYPES : /datum/map_generator_module/bottom_layer/syndie_floor/@SUBTYPES{@OLD} -/datum/action/item_action/YEEEAAAAAHHHHHHHHHHHHH/@SUBTYPES : /datum/action/item_action/yeeeaaaaahhhhhhhhhhhhh/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/bottomLayer/grassTurfs/@SUBTYPES : /datum/map_generator_module/bottom_layer/grass_turfs/@SUBTYPES{@OLD} -/obj/item/reagent_containers/iv_bag/blood/AMinus/@SUBTYPES : /obj/item/reagent_containers/iv_bag/blood/a_minus/@SUBTYPES{@OLD} -/obj/item/reagent_containers/iv_bag/blood/BMinus/@SUBTYPES : /obj/item/reagent_containers/iv_bag/blood/b_minus/@SUBTYPES{@OLD} -/obj/item/reagent_containers/iv_bag/blood/OMinus/@SUBTYPES : /obj/item/reagent_containers/iv_bag/blood/o_minus/@SUBTYPES{@OLD} -/datum/action/item_action/equip_unequip_TED_Gun/@SUBTYPES : /datum/action/item_action/equip_unequip_ted_gun/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/denseLayer/grassTufts/@SUBTYPES : /datum/map_generator_module/dense_layer/grass_tufts/@SUBTYPES{@OLD} -/obj/item/reagent_containers/iv_bag/blood/APlus/@SUBTYPES : /obj/item/reagent_containers/iv_bag/blood/a_plus/@SUBTYPES{@OLD} -/obj/item/reagent_containers/iv_bag/blood/BPlus/@SUBTYPES : /obj/item/reagent_containers/iv_bag/blood/b_plus/@SUBTYPES{@OLD} -/obj/item/reagent_containers/iv_bag/blood/OPlus/@SUBTYPES : /obj/item/reagent_containers/iv_bag/blood/o_plus/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/border/asteroidWalls/@SUBTYPES : /datum/map_generator_module/border/asteroid_walls/@SUBTYPES{@OLD} -/mob/living/simple_animal/pet/dog/fox/Syndifox/@SUBTYPES : /mob/living/simple_animal/pet/dog/fox/syndifox/@SUBTYPES{@OLD} -/mob/living/simple_animal/hostile/bear/Hudson/@SUBTYPES : /mob/living/simple_animal/hostile/bear/hudson/@SUBTYPES{@OLD} -/mob/living/simple_animal/pet/dog/fox/Renault/@SUBTYPES : /mob/living/simple_animal/pet/dog/fox/renault/@SUBTYPES{@OLD} -/obj/item/gun/projectile/automatic/pistol/APS/@SUBTYPES : /obj/item/gun/projectile/automatic/pistol/aps/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/border/syndieWalls/@SUBTYPES : /datum/map_generator_module/border/syndie_walls/@SUBTYPES{@OLD} -/mob/living/simple_animal/pet/dog/corgi/Lisa/@SUBTYPES : /mob/living/simple_animal/pet/dog/corgi/lisa/@SUBTYPES{@OLD} -/mob/living/simple_animal/mouse/white/Brain/@SUBTYPES : /mob/living/simple_animal/mouse/white/brain/@SUBTYPES{@OLD} -/mob/living/simple_animal/pet/dog/corgi/Ian/@SUBTYPES : /mob/living/simple_animal/pet/dog/corgi/ian/@SUBTYPES{@OLD} -/area/station/security/prison/cell_block/A/@SUBTYPES : /area/station/security/prison/cell_block/a/@SUBTYPES{@OLD} -/obj/item/food/sliceable/SmokedSalmon_maki/@SUBTYPES : /obj/item/food/sliceable/smoked_salmon_maki/@SUBTYPES{@OLD} -/obj/item/reagent_containers/hypospray/CMO/@SUBTYPES : /obj/item/reagent_containers/hypospray/cmo/@SUBTYPES{@OLD} -/atom/movable/screen/blob/ReadaptChemical/@SUBTYPES : /atom/movable/screen/blob/readapt_chemical/@SUBTYPES{@OLD} -/atom/movable/screen/guardian/Communicate/@SUBTYPES : /atom/movable/screen/guardian/communicate/@SUBTYPES{@OLD} -/atom/movable/screen/guardian/ToggleLight/@SUBTYPES : /atom/movable/screen/guardian/toggle_light/@SUBTYPES{@OLD} -/datum/crafting_recipe/sushi_SmokedSalmon/@SUBTYPES : /datum/crafting_recipe/sushi_smoked_salmon/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/syndieFurniture/@SUBTYPES : /datum/map_generator_module/syndie_furniture/@SUBTYPES{@OLD} -/datum/supply_packs/engineering/engine/PA/@SUBTYPES : /datum/supply_packs/engineering/engine/particle_accelerator/@SUBTYPES{@OLD} -/datum/uplink_item/ammo/bulldog_XLmagsbag/@SUBTYPES : /datum/uplink_item/ammo/bulldog_xl_magsbag/@SUBTYPES{@OLD} -/mob/living/simple_animal/mouse/brown/Tom/@SUBTYPES : /mob/living/simple_animal/mouse/brown/tom/@SUBTYPES{@OLD} -/mob/living/simple_animal/pet/cat/Runtime/@SUBTYPES : /mob/living/simple_animal/pet/cat/runtime/@SUBTYPES{@OLD} -/atom/movable/screen/act_intent/robot/AI/@SUBTYPES : /atom/movable/screen/act_intent/robot/ai/@SUBTYPES{@OLD} -/atom/movable/screen/guardian/ToggleMode/@SUBTYPES : /atom/movable/screen/guardian/toggle_mode/@SUBTYPES{@OLD} -/datum/crafting_recipe/SmokedSalmon_maki/@SUBTYPES : /datum/crafting_recipe/smoked_salmon_maki/@SUBTYPES{@OLD} -/datum/middleClickOverride/badminClicker/@SUBTYPES : /datum/middle_click_override/badmin_clicker/@SUBTYPES{@OLD} -/datum/objective/abductee/POWERUNLIMITED/@SUBTYPES : /datum/objective/abductee/powerunlimited/@SUBTYPES{@OLD} -/mob/living/simple_animal/cockroach/Brad/@SUBTYPES : /mob/living/simple_animal/cockroach/brad/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/splatterLayer/@SUBTYPES : /datum/map_generator_module/splatter_layer/@SUBTYPES{@OLD} -/datum/uplink_item/stealthy_weapons/RSG/@SUBTYPES : /datum/uplink_item/stealthy_weapons/rsg/@SUBTYPES{@OLD} -/mob/living/simple_animal/pet/cat/Syndi/@SUBTYPES : /mob/living/simple_animal/pet/cat/syndi/@SUBTYPES{@OLD} -/obj/item/ammo_box/magazine/m12g/XtrLrg/@SUBTYPES : /obj/item/ammo_box/magazine/m12g/xtr_lrg/@SUBTYPES{@OLD} -/obj/item/clothing/head/collectable/HoP/@SUBTYPES : /obj/item/clothing/head/collectable/hop/@SUBTYPES{@OLD} -/obj/item/clothing/head/collectable/HoS/@SUBTYPES : /obj/item/clothing/head/collectable/hos/@SUBTYPES{@OLD} -/obj/item/food/sliceable/TobikoEgg_maki/@SUBTYPES : /obj/item/food/sliceable/tobiko_egg_maki/@SUBTYPES{@OLD} -/obj/machinery/computer/HolodeckControl/@SUBTYPES : /obj/machinery/computer/holodeck_control/@SUBTYPES{@OLD} -/obj/structure/closet/secure_closet/CMO/@SUBTYPES : /obj/structure/closet/secure_closet/cmo/@SUBTYPES{@OLD} -/atom/movable/screen/blob/RelocateCore/@SUBTYPES : /atom/movable/screen/blob/relocate_core/@SUBTYPES{@OLD} -/atom/movable/screen/blob/ResourceBlob/@SUBTYPES : /atom/movable/screen/blob/resource_blob/@SUBTYPES{@OLD} -/atom/movable/screen/guardian/Manifest/@SUBTYPES : /atom/movable/screen/guardian/manifest/@SUBTYPES{@OLD} -/datum/crafting_recipe/sushi_TobikoEgg/@SUBTYPES : /datum/crafting_recipe/sushi_tobiko_egg/@SUBTYPES{@OLD} -/datum/recipe/grill/sushi_SmokedSalmon/@SUBTYPES : /datum/recipe/grill/sushi_smoked_salmon/@SUBTYPES{@OLD} -/datum/spell/aoe/conjure/summonEdSwarm/@SUBTYPES : /datum/spell/aoe/conjure/summon_ed_swarm/@SUBTYPES{@OLD} -/mob/living/simple_animal/pet/cat/Proc/@SUBTYPES : /mob/living/simple_animal/pet/cat/proc_cat/@SUBTYPES{@OLD} -/obj/item/circuitboard/HolodeckControl/@SUBTYPES : /obj/item/circuitboard/holodeck_control/@SUBTYPES{@OLD} -/obj/structure/closet/secure_closet/RD/@SUBTYPES : /obj/structure/closet/secure_closet/rd/@SUBTYPES{@OLD} -/atom/movable/screen/blob/Blobbernaut/@SUBTYPES : /atom/movable/screen/blob/blobbernaut/@SUBTYPES{@OLD} -/atom/movable/screen/blob/FactoryBlob/@SUBTYPES : /atom/movable/screen/blob/factory_blob/@SUBTYPES{@OLD} -/atom/movable/screen/blob/StorageBlob/@SUBTYPES : /atom/movable/screen/blob/storage_blob/@SUBTYPES{@OLD} -/datum/crafting_recipe/TobikoEgg_maki/@SUBTYPES : /datum/crafting_recipe/tobiko_egg_maki/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/bottomLayer/@SUBTYPES : /datum/map_generator_module/bottom_layer/@SUBTYPES{@OLD} -/mob/living/simple_animal/crab/Coffee/@SUBTYPES : /mob/living/simple_animal/crab/coffee/@SUBTYPES{@OLD} -/mob/living/simple_animal/parrot/Poly/@SUBTYPES : /mob/living/simple_animal/parrot/poly/@SUBTYPES{@OLD} -/mob/living/simple_animal/pet/cat/Var/@SUBTYPES : /mob/living/simple_animal/pet/cat/var_cat/@SUBTYPES{@OLD} -/obj/machinery/disposal/deliveryChute/@SUBTYPES : /obj/machinery/disposal/delivery_chute/@SUBTYPES{@OLD} -/area/ruin/unpowered/BMPship/Midship/@SUBTYPES : /area/ruin/unpowered/bmp_ship/midship/@SUBTYPES{@OLD} -/atom/movable/screen/blob/JumpToCore/@SUBTYPES : /atom/movable/screen/blob/jump_to_core/@SUBTYPES{@OLD} -/atom/movable/screen/blob/JumpToNode/@SUBTYPES : /atom/movable/screen/blob/jump_to_node/@SUBTYPES{@OLD} -/atom/movable/screen/guardian/Recall/@SUBTYPES : /atom/movable/screen/guardian/recall/@SUBTYPES{@OLD} -/datum/bottler_recipe/Applepocalypse/@SUBTYPES : /datum/bottler_recipe/applepocalypse/@SUBTYPES{@OLD} -/datum/bottler_recipe/Paradise_Punch/@SUBTYPES : /datum/bottler_recipe/paradise_punch/@SUBTYPES{@OLD} -/datum/chemical_reaction/kahluaVodka/@SUBTYPES : /datum/chemical_reaction/kahlua_vodka/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/denseLayer/@SUBTYPES : /datum/map_generator_module/dense_layer/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/randBushes/@SUBTYPES : /datum/map_generator_module/rand_bushes/@SUBTYPES{@OLD} -/datum/status_effect/hippocraticOath/@SUBTYPES : /datum/status_effect/hippocratic_oath/@SUBTYPES{@OLD} -/obj/item/food/sliceable/Masago_maki/@SUBTYPES : /obj/item/food/sliceable/masago_maki/@SUBTYPES{@OLD} -/obj/item/food/sliceable/Tamago_maki/@SUBTYPES : /obj/item/food/sliceable/tamago_maki/@SUBTYPES{@OLD} -/obj/item/food/sliceable/Tobiko_maki/@SUBTYPES : /obj/item/food/sliceable/tobiko_maki/@SUBTYPES{@OLD} -/datum/bottler_recipe/Berry_Banned2/@SUBTYPES : /datum/bottler_recipe/berry_banned2/@SUBTYPES{@OLD} -/datum/bottler_recipe/Blackeye_Brew/@SUBTYPES : /datum/bottler_recipe/blackeye_brew/@SUBTYPES{@OLD} -/datum/bottler_recipe/Grape_Granade/@SUBTYPES : /datum/bottler_recipe/grape_granade/@SUBTYPES{@OLD} -/datum/crafting_recipe/sushi_Masago/@SUBTYPES : /datum/crafting_recipe/sushi_masago/@SUBTYPES{@OLD} -/datum/crafting_recipe/sushi_Tobiko/@SUBTYPES : /datum/crafting_recipe/sushi_tobiko/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/deadTrees/@SUBTYPES : /datum/map_generator_module/dead_trees/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/pineTrees/@SUBTYPES : /datum/map_generator_module/pine_trees/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/randRocks/@SUBTYPES : /datum/map_generator_module/rand_rocks/@SUBTYPES{@OLD} -/datum/recipe/grill/sushi_TobikoEgg/@SUBTYPES : /datum/recipe/grill/sushi_tobiko_egg/@SUBTYPES{@OLD} -/obj/item/food/sliceable/Ikura_maki/@SUBTYPES : /obj/item/food/sliceable/ikura_maki/@SUBTYPES{@OLD} -/obj/item/food/sliceable/Inari_maki/@SUBTYPES : /obj/item/food/sliceable/inari_maki/@SUBTYPES{@OLD} -/area/ruin/unpowered/BMPship/Delta/@SUBTYPES : /area/ruin/unpowered/bmp_ship/delta/@SUBTYPES{@OLD} -/atom/movable/screen/blob/BlobHelp/@SUBTYPES : /atom/movable/screen/blob/blob_help/@SUBTYPES{@OLD} -/atom/movable/screen/blob/NodeBlob/@SUBTYPES : /atom/movable/screen/blob/node_blob/@SUBTYPES{@OLD} -/datum/action/changeling/absorbDNA/@SUBTYPES : /datum/action/changeling/absorb_dna/@SUBTYPES{@OLD} -/datum/bottler_recipe/Berry_Banned/@SUBTYPES : /datum/bottler_recipe/berry_banned/@SUBTYPES{@OLD} -/datum/crafting_recipe/Masago_maki/@SUBTYPES : /datum/crafting_recipe/masago_maki/@SUBTYPES{@OLD} -/datum/crafting_recipe/Tobiko_maki/@SUBTYPES : /datum/crafting_recipe/tobiko_maki/@SUBTYPES{@OLD} -/datum/crafting_recipe/sushi_Ikura/@SUBTYPES : /datum/crafting_recipe/sushi_ikura/@SUBTYPES{@OLD} -/datum/crafting_recipe/sushi_Inari/@SUBTYPES : /datum/crafting_recipe/sushi_inari/@SUBTYPES{@OLD} -/obj/item/food/sliceable/Sake_maki/@SUBTYPES : /obj/item/food/sliceable/sake_maki/@SUBTYPES{@OLD} -/area/ruin/unpowered/BMPship/Fore/@SUBTYPES : /area/ruin/unpowered/bmp_ship/fore/@SUBTYPES{@OLD} -/datum/bottler_recipe/Meteor_Malt/@SUBTYPES : /datum/bottler_recipe/meteor_malt/@SUBTYPES{@OLD} -/datum/chemical_reaction/slimeRNG/@SUBTYPES : /datum/chemical_reaction/slime_rng/@SUBTYPES{@OLD} -/datum/crafting_recipe/Ikura_maki/@SUBTYPES : /datum/crafting_recipe/ikura_maki/@SUBTYPES{@OLD} -/datum/crafting_recipe/Inari_maki/@SUBTYPES : /datum/crafting_recipe/inari_maki/@SUBTYPES{@OLD} -/datum/crafting_recipe/sushi_Sake/@SUBTYPES : /datum/crafting_recipe/sushi_sake/@SUBTYPES{@OLD} -/obj/item/aiModule/protectStation/@SUBTYPES : /obj/item/ai_module/protect_station/@SUBTYPES{@OLD} -/obj/item/food/sliceable/Ebi_maki/@SUBTYPES : /obj/item/food/sliceable/ebi_maki/@SUBTYPES{@OLD} -/obj/item/food/sliceable/Tai_maki/@SUBTYPES : /obj/item/food/sliceable/tai_maki/@SUBTYPES{@OLD} -/obj/item/food/sushi_SmokedSalmon/@SUBTYPES : /obj/item/food/sushi_smoked_salmon/@SUBTYPES{@OLD} -/area/ruin/unpowered/BMPship/Aft/@SUBTYPES : /area/ruin/unpowered/bmp_ship/aft/@SUBTYPES{@OLD} -/datum/crafting_recipe/Sake_maki/@SUBTYPES : /datum/crafting_recipe/sake_maki/@SUBTYPES{@OLD} -/datum/crafting_recipe/sushi_Ebi/@SUBTYPES : /datum/crafting_recipe/sushi_ebi/@SUBTYPES{@OLD} -/datum/crafting_recipe/sushi_Tai/@SUBTYPES : /datum/crafting_recipe/sushi_tai/@SUBTYPES{@OLD} -/datum/recipe/grill/sushi_Masago/@SUBTYPES : /datum/recipe/grill/sushi_masago/@SUBTYPES{@OLD} -/datum/recipe/grill/sushi_Tamago/@SUBTYPES : /datum/recipe/grill/sushi_tamago/@SUBTYPES{@OLD} -/datum/recipe/grill/sushi_Tobiko/@SUBTYPES : /datum/recipe/grill/sushi_tobiko/@SUBTYPES{@OLD} -/obj/item/aiModule/oneCrewMember/@SUBTYPES : /obj/item/ai_module/one_crew_member/@SUBTYPES{@OLD} -/atom/movable/screen/blob/Split/@SUBTYPES : /atom/movable/screen/blob/split/@SUBTYPES{@OLD} -/datum/crafting_recipe/Ebi_maki/@SUBTYPES : /datum/crafting_recipe/ebi_maki/@SUBTYPES{@OLD} -/datum/crafting_recipe/Tai_maki/@SUBTYPES : /datum/crafting_recipe/tai_maki/@SUBTYPES{@OLD} -/datum/recipe/grill/sushi_Ikura/@SUBTYPES : /datum/recipe/grill/sushi_ikura/@SUBTYPES{@OLD} -/datum/recipe/grill/sushi_Inari/@SUBTYPES : /datum/recipe/grill/sushi_inari/@SUBTYPES{@OLD} -/datum/recipe/grill/sushi_Unagi/@SUBTYPES : /datum/recipe/grill/sushi_unagi/@SUBTYPES{@OLD} -/datum/ErrorViewer/ErrorSource/@SUBTYPES : /datum/error_viewer/error_source/@SUBTYPES{@OLD} -/datum/objective/revenantFluff/@SUBTYPES : /datum/objective/revenant_fluff/@SUBTYPES{@OLD} -/datum/recipe/grill/sushi_Sake/@SUBTYPES : /datum/recipe/grill/sushi_sake/@SUBTYPES{@OLD} -/obj/item/food/sushi_TobikoEgg/@SUBTYPES : /obj/item/food/sushi_tobiko_egg/@SUBTYPES{@OLD} -/datum/ErrorViewer/ErrorCache/@SUBTYPES : /datum/error_viewer/error_cache/@SUBTYPES{@OLD} -/datum/ErrorViewer/ErrorEntry/@SUBTYPES : /datum/error_viewer/error_entry/@SUBTYPES{@OLD} -/datum/recipe/grill/sushi_Ebi/@SUBTYPES : /datum/recipe/grill/sushi_ebi/@SUBTYPES{@OLD} -/datum/recipe/grill/sushi_Tai/@SUBTYPES : /datum/recipe/grill/sushi_tai/@SUBTYPES{@OLD} -/datum/uplink_item/bundles_TC/@SUBTYPES : /datum/uplink_item/bundles_tc/@SUBTYPES{@OLD} -/area/ruin/unpowered/BMPship/@SUBTYPES : /area/ruin/unpowered/bmp_ship/@SUBTYPES{@OLD} -/datum/dog_fashion/head/HoS/@SUBTYPES : /datum/dog_fashion/head/hos/@SUBTYPES{@OLD} -/obj/item/clothing/head/HoS/@SUBTYPES : /obj/item/clothing/head/hos/@SUBTYPES{@OLD} -/obj/item/food/sushi_Masago/@SUBTYPES : /obj/item/food/sushi_masago/@SUBTYPES{@OLD} -/obj/item/food/sushi_Tamago/@SUBTYPES : /obj/item/food/sushi_tamago/@SUBTYPES{@OLD} -/obj/item/food/sushi_Tobiko/@SUBTYPES : /obj/item/food/sushi_tobiko/@SUBTYPES{@OLD} -/obj/item/stack/packageWrap/@SUBTYPES : /obj/item/stack/package_wrap/@SUBTYPES{@OLD} -/datum/crafting_recipe/IED/@SUBTYPES : /datum/crafting_recipe/ied/@SUBTYPES{@OLD} -/datum/middleClickOverride/@SUBTYPES : /datum/middle_click_override/@SUBTYPES{@OLD} -/obj/item/food/sushi_Ikura/@SUBTYPES : /obj/item/food/sushi_ikura/@SUBTYPES{@OLD} -/obj/item/food/sushi_Inari/@SUBTYPES : /obj/item/food/sushi_inari/@SUBTYPES{@OLD} -/obj/item/food/sushi_Unagi/@SUBTYPES : /obj/item/food/sushi_unagi/@SUBTYPES{@OLD} -/obj/item/storage/box/PDAs/@SUBTYPES : /obj/item/storage/box/pdas/@SUBTYPES{@OLD} -/obj/structure/bigDelivery/@SUBTYPES : /obj/structure/big_delivery/@SUBTYPES{@OLD} -/datum/mapGeneratorModule/@SUBTYPES : /datum/map_generator_module/@SUBTYPES{@OLD} -/obj/item/food/sushi_Sake/@SUBTYPES : /obj/item/food/sushi_sake/@SUBTYPES{@OLD} -/obj/item/shippingPackage/@SUBTYPES : /obj/item/shipping_package/@SUBTYPES{@OLD} -/obj/item/aiModule/toyAI/@SUBTYPES : /obj/item/aiModule/toy_ai/@SUBTYPES{@OLD} -/obj/item/food/sushi_Ebi/@SUBTYPES : /obj/item/food/sushi_ebi/@SUBTYPES{@OLD} -/obj/item/food/sushi_Tai/@SUBTYPES : /obj/item/food/sushi_tai/@SUBTYPES{@OLD} -/obj/item/smallDelivery/@SUBTYPES : /obj/item/small_delivery/@SUBTYPES{@OLD} -/datum/design/BS_RPED/@SUBTYPES : /datum/design/bs_rped/@SUBTYPES{@OLD} -/obj/item/paper/Court/@SUBTYPES : /obj/item/paper/court/@SUBTYPES{@OLD} -/obj/item/paper/Toxin/@SUBTYPES : /obj/item/paper/toxin/@SUBTYPES{@OLD} -/obj/structure/AIcore/@SUBTYPES : /obj/structure/ai_core/@SUBTYPES{@OLD} -/datum/paiController/@SUBTYPES : /datum/pai_controller/@SUBTYPES{@OLD} -/datum/prize_item/AI/@SUBTYPES : /datum/prize_item/ai/@SUBTYPES{@OLD} -/obj/item/CQC_manual/@SUBTYPES : /obj/item/cqc_manual/@SUBTYPES{@OLD} -/obj/item/badminBook/@SUBTYPES : /obj/item/badmin_book/@SUBTYPES{@OLD} -/obj/item/destTagger/@SUBTYPES : /obj/item/dest_tagger/@SUBTYPES{@OLD} -/datum/mapGenerator/@SUBTYPES : /datum/map_generator/@SUBTYPES{@OLD} -/datum/sortInstance/@SUBTYPES : /datum/sort_instance/@SUBTYPES{@OLD} -/datum/ErrorViewer/@SUBTYPES : /datum/error_viewer/@SUBTYPES{@OLD} -/datum/SDQL_parser/@SUBTYPES : /datum/sdql_parser/@SUBTYPES{@OLD} -/datum/design/RPED/@SUBTYPES : /datum/design/rped/@SUBTYPES{@OLD} -/datum/holiday/UFO/@SUBTYPES : /datum/holiday/ufo/@SUBTYPES{@OLD} -/obj/item/FixOVein/@SUBTYPES : /obj/item/fix_o_vein/@SUBTYPES{@OLD} -/obj/item/aiModule/@SUBTYPES : /obj/item/ai_module/@SUBTYPES{@OLD} -/mob/camera/aiEye/@SUBTYPES : /mob/camera/ai_eye/@SUBTYPES{@OLD} -/datum/AI_Module/@SUBTYPES : /datum/ai_module/@SUBTYPES{@OLD} -/obj/item/toy/AI/@SUBTYPES : /obj/item/toy/ai/@SUBTYPES{@OLD} -/datum/gear/pAI/@SUBTYPES : /datum/gear/pai/@SUBTYPES{@OLD} diff --git a/tools/UpdatePaths/Scripts/27362_remove_redundant_typepaths.txt b/tools/UpdatePaths/Scripts/27362_remove_redundant_typepaths.txt deleted file mode 100644 index 72bf7b56e72a2..0000000000000 --- a/tools/UpdatePaths/Scripts/27362_remove_redundant_typepaths.txt +++ /dev/null @@ -1,15 +0,0 @@ -/obj/effect/forcefield/mime/advanced : /obj/effect/forcefield/mime/@SUBTYPES{@OLD} -/obj/effect/spawner/away/lootdrop : /obj/effect/spawner/away_lootdrop/@SUBTYPES{@OLD} -/obj/effect/spawner/random/janitor/supplies : /obj/effect/spawner/random/jani_supplies/@SUBTYPES{@OLD} -/obj/effect/spawner/random/mod/maint : /obj/effect/spawner/random/mod_maint/@SUBTYPES{@OLD} -/obj/item/clothing/head/beret/solgov/command : /obj/item/clothing/head/beret/command/@SUBTYPES{@OLD} -/obj/item/clothing/head/space/prisoner_gulag : /obj/item/clothing/head/helmet/space/prisoner_gulag/@SUBTYPES{@OLD} -/obj/item/clothing/suit/greatcoat/sec : /obj/item/clothing/suit/sec_greatcoat/@SUBTYPES{@OLD} -/obj/item/clothing/under/misc/gimmick/rank/captain/suit : /obj/item/clothing/under/misc/gimmick_captain_suit/@SUBTYPES{@OLD} -/obj/item/ectoplasm/revenant : /obj/item/ectoplasm/@SUBTYPES{@OLD} -/obj/item/effect/snare : /obj/effect/snare/@SUBTYPES{@OLD} -/obj/item/storage/hidden/implant : /obj/item/storage/hidden_implant/@SUBTYPES{@OLD} -/obj/structure/closet/malf/suits : /obj/structure/closet/malf_suits/@SUBTYPES{@OLD} -/obj/structure/closet/secure_closet/syndicate/depot : /obj/structure/closet/secure_closet/depot/@SUBTYPES{@OLD} -/obj/structure/ladder/unusable : /obj/structure/ladder/@SUBTYPES{@OLD} -/obj/structure/moth/cocoon : /obj/structure/moth_cocoon/@SUBTYPES{@OLD} diff --git a/tools/UpdatePaths/Scripts/27386_cable_directions_and_areas.txt b/tools/UpdatePaths/Scripts/27386_cable_directions_and_areas.txt deleted file mode 100644 index 444c53d00544d..0000000000000 --- a/tools/UpdatePaths/Scripts/27386_cable_directions_and_areas.txt +++ /dev/null @@ -1,2 +0,0 @@ -/obj/structure/cable/@SUBTYPES : /obj/structure/cable/@SUBTYPES{@OLD;d1=@SKIP;d2=@SKIP} -/area : /area/space diff --git a/tools/UpdatePaths/Scripts/27407_ale_beer_repath.txt b/tools/UpdatePaths/Scripts/27407_ale_beer_repath.txt deleted file mode 100644 index f0407327eb202..0000000000000 --- a/tools/UpdatePaths/Scripts/27407_ale_beer_repath.txt +++ /dev/null @@ -1,2 +0,0 @@ -/obj/item/reagent_containers/drinks/cans/beer/@SUBTYPES : /obj/item/reagent_containers/drinks/bottle/beer/@SUBTYPES{@OLD} -/obj/item/reagent_containers/drinks/cans/ale : /obj/item/reagent_containers/drinks/bottle/ale{@OLD} \ No newline at end of file diff --git a/tools/UpdatePaths/Scripts/27445_lootspawn_migration.txt b/tools/UpdatePaths/Scripts/27445_lootspawn_migration.txt deleted file mode 100644 index 9e77b3befbbd4..0000000000000 --- a/tools/UpdatePaths/Scripts/27445_lootspawn_migration.txt +++ /dev/null @@ -1,21 +0,0 @@ -/obj/effect/spawner/lootdrop/crate_spawner : /obj/effect/spawner/random/loot/crate -/obj/effect/spawner/lootdrop/three_course_meal : /obj/effect/spawner/random/food_or_drink/three_course_meal - -/obj/effect/spawner/lootdrop/trade_sol/civ : /obj/effect/spawner/random/traders/civilian -/obj/effect/spawner/lootdrop/trade_sol/minerals : /obj/effect/spawner/random/traders/minerals -/obj/effect/spawner/lootdrop/trade_sol/donksoft : /obj/effect/spawner/random/traders/donksoft -/obj/effect/spawner/lootdrop/trade_sol/sci : /obj/effect/spawner/random/traders/science -/obj/effect/spawner/lootdrop/trade_sol/med : /obj/effect/spawner/random/traders/medical -/obj/effect/spawner/lootdrop/trade_sol/sec : /obj/effect/spawner/random/traders/security -/obj/effect/spawner/lootdrop/trade_sol/eng : /obj/effect/spawner/random/traders/engineering -/obj/effect/spawner/lootdrop/trade_sol/largeitem : /obj/effect/spawner/random/traders/large_item -/obj/effect/spawner/lootdrop/trade_sol/vehicle : /obj/effect/spawner/random/traders/vehicle -/obj/effect/spawner/lootdrop/trade_sol/serv : /obj/effect/spawner/random/traders/service - -/obj/effect/spawner/lootdrop/bluespace_tap/@SUBTYPES : /obj/effect/spawner/random/bluespace_tap/@SUBTYPES -/obj/effect/spawner/lootdrop/trade_sol/@SUBTYPES : /obj/effect/spawner/random/traders/@SUBTYPES - -/obj/effect/spawner/lootdrop/telecomms_core_table : /obj/effect/spawner/random/telecomms_core_table -/obj/effect/spawner/lootdrop/wizardcrash : /obj/effect/spawner/random/wizardcrash -/obj/effect/spawner/lootdrop/pizzaparty : /obj/effect/spawner/random/pizzaparty -/obj/effect/spawner/lootdrop/seed_vault : /obj/effect/spawner/random/seed_vault diff --git a/tools/UpdatePaths/Scripts/27583_newscaster_directionals.txt b/tools/UpdatePaths/Scripts/27583_newscaster_directionals.txt deleted file mode 100644 index 24905bc55bd53..0000000000000 --- a/tools/UpdatePaths/Scripts/27583_newscaster_directionals.txt +++ /dev/null @@ -1,16 +0,0 @@ -/obj/machinery/newscaster/security_unit{dir=1;name="south bump";pixel_y=-28} : /obj/machinery/newscaster/security_unit/directional/south -/obj/machinery/newscaster/security_unit{dir=4;name="west bump";pixel_x=-28} : /obj/machinery/newscaster/security_unit/directional/west -/obj/machinery/newscaster/security_unit{dir=8;name="east bump";pixel_x=28} : /obj/machinery/newscaster/security_unit/directional/east -/obj/machinery/newscaster/security_unit{dir=8;name="west bump";pixel_x=28} : /obj/machinery/newscaster/security_unit/directional/east -/obj/machinery/newscaster/security_unit{name="north bump";pixel_y=28} : /obj/machinery/newscaster/security_unit/directional/north -/obj/machinery/newscaster{desc="A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. Strange that it's on a Union station.";name="custom placement";pixel_x=27} : /obj/machinery/newscaster/directional/east{desc="A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. Strange that it's on a Union station."} -/obj/machinery/newscaster{desc="A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. Strange that it's on a Union station.";name="custom placement";pixel_x=30} : /obj/machinery/newscaster/directional/east{desc="A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. Strange that it's on a Union station."} -/obj/machinery/newscaster{dir=1;name="south bump";pixel_y=-28} : /obj/machinery/newscaster/directional/south -/obj/machinery/newscaster{dir=4;name="west bump";pixel_x=-28} : /obj/machinery/newscaster/directional/west -/obj/machinery/newscaster{dir=8;name="east bump";pixel_x=28} : /obj/machinery/newscaster/directional/east -/obj/machinery/newscaster{name="north bump";pixel_y=28} : /obj/machinery/newscaster/directional/north -/obj/machinery/newscaster{name="south bump";pixel_y=-32} : /obj/machinery/newscaster/directional/south -/obj/machinery/newscaster{pixel_x=-30} : /obj/machinery/newscaster/directional/west -/obj/machinery/newscaster{pixel_y=-30} : /obj/machinery/newscaster/directional/south -/obj/machinery/newscaster{pixel_y=30} : /obj/machinery/newscaster/directional/north -/obj/machinery/newscaster{pixel_y=32} : /obj/machinery/newscaster/directional/north diff --git a/tools/UpdatePaths/Scripts/27682_legacy_random_spawners.txt b/tools/UpdatePaths/Scripts/27682_legacy_random_spawners.txt deleted file mode 100644 index 5130792700bfe..0000000000000 --- a/tools/UpdatePaths/Scripts/27682_legacy_random_spawners.txt +++ /dev/null @@ -1,9 +0,0 @@ -/obj/random/toolbox : /obj/effect/spawner/random/engineering/toolbox -/obj/random/tool : /obj/effect/spawner/random/engineering/tools -/obj/random/technology_scanner : @DELETE -/obj/random/tech_supply : @DELETE -/obj/random/bomb_supply : @DELETE -/obj/random/powercell : /obj/item/stock_parts/cell, /obj/item/stock_parts/cell/high, /obj/item/stock_parts/cell/super, /obj/item/stock_parts/cell/hyper -/obj/random/plushie : /obj/effect/spawner/random/plushies -/obj/random/mech : /obj/effect/spawner/random/toy/mech_figure -/obj/random/carp_plushie : /obj/effect/spawner/random/toy/carp_plushie diff --git a/tools/UpdatePaths/Scripts/27882_grimeycarpet.txt b/tools/UpdatePaths/Scripts/27882_grimeycarpet.txt deleted file mode 100644 index 5fbed8a165ac0..0000000000000 --- a/tools/UpdatePaths/Scripts/27882_grimeycarpet.txt +++ /dev/null @@ -1 +0,0 @@ -/turf/simulated/floor/plasteel{icon_state ="grimy"} : /turf/simulated/floor/carpet/grimey {@OLD;icon_state=@SKIP;dir=@SKIP} \ No newline at end of file diff --git a/tools/ci/check_grep2.py b/tools/ci/check_grep2.py index 2ed127bae2b9b..cb3cbcb5bafbe 100644 --- a/tools/ci/check_grep2.py +++ b/tools/ci/check_grep2.py @@ -139,12 +139,12 @@ def check_tgui_ui_new_argument(idx, line): FOR_ALL_NOT_DATUMS = re.compile(r"for\s*\(\s*var\/((?:atom|area|turf|obj|mob)(?:\/\w+))\)") def check_datum_loops(idx, line): if FOR_ALL_DATUMS.search(line) or FOR_ALL_NOT_DATUMS.search(line): - return [( + return Failure( idx + 1, # yes this will concatenate the strings, don't look too hard "Found a for loop without explicit contents. If you're trying to loop over everything in the world, first double check that you truly need to, and if so specify \'in world\'.\n" "If you're trying to check bare datums, please ensure that your value is only cast to /datum, and please make sure you use \'as anything\', or use a global list instead." - )] + ) HREF_OLD_STYLE = re.compile(r"href[\s='\"\\]*\?") def check_href_styles(idx, line): @@ -181,12 +181,6 @@ def check_istype_src(idx, line): if CONDITIONAL_ISTYPE_SRC.search(line): return [(idx + 1, "Our coding requirements prohibit use of istype(src, /any_type). Consider making the behavior dependent on a variable and/or overriding a proc instead.")] -CAMEL_CASE_TYPE_NAMES = re.compile(r"^/[\w]\S+/{1}([a-zA-Z]+([A-Z][a-z]+)+|([A-Z]+[a-z]+))$") -def check_camel_case_type_names(idx, line): - if result := CAMEL_CASE_TYPE_NAMES.search(line): - type_result = result.group(0) - return [(idx + 1, f"name of type {type_result} is not in snake_case format.")] - CODE_CHECKS = [ check_space_indentation, check_mixed_indentation, @@ -203,7 +197,6 @@ def check_camel_case_type_names(idx, line): check_initialize_missing_mapload, check_empty_list_whitespace, check_istype_src, - check_camel_case_type_names, ] diff --git a/tools/ci/check_legacy_attack_chain.py b/tools/ci/check_legacy_attack_chain.py deleted file mode 100644 index 92a8d30067d70..0000000000000 --- a/tools/ci/check_legacy_attack_chain.py +++ /dev/null @@ -1,236 +0,0 @@ -import os -import sys -import time -from dataclasses import dataclass -from collections import namedtuple, defaultdict - -from avulto import DMM, DME, DMI, Dir, Path as p, paths, ProcDecl, TypeDecl -from avulto.ast import NodeKind -from avulto import exceptions - - -RED = "\033[0;31m" -GREEN = "\033[0;32m" -BLUE = "\033[0;34m" -NC = "\033[0m" # No Color - - -@dataclass(frozen=True) -class AttackChainCall: - proc_decl: ProcDecl - var_name: str - var_type: p | None - call_name: str - source_info: any - legacy: bool - - def make_error_message(self): - return f"{self.proc_decl.type_path}/{self.proc_decl.name}(...) calls {self.call_name}(...) on var {self.var_type}/{self.var_name}" - - def format_error(self): - if os.getenv("GITHUB_ACTIONS") == "true": - return f"::error file={self.source_info.file_path},line={self.source_info.line},title=Attack Chain::{self.source_info.file_path}:{self.source_info.line}: {RED}{self.make_error_message()}{NC}" - - else: - return f"{self.source_info.file_path}:{self.source_info.line}: {RED}{self.make_error_message()}{NC}" - - -def make_error_from_procdecl(proc_decl: ProcDecl, msg) -> str: - if os.getenv("GITHUB_ACTIONS") == "true": - return f"::error file={proc_decl.source_info.file_path},line={proc_decl.source_info.line},title=Attack Chain::{proc_decl.source_info.file_path}:{proc_decl.source_info.line}: {RED}{msg}{NC}" - - else: - return f"{proc_decl.source_info.file_path}:{proc_decl.source_info.line}: {RED}{msg}{NC}" - - -# Walker for determining if a proc contains any calls to a legacy attack chain -# proc on an object that is in the type tree of our migrating type. -# -# We check local, proc-argument, and type-declaration scope to find variables of -# matching names for when an attack chain proc is called, and attempt to find -# that variable's matching type. If the type matches, then the call site is -# calling a legacy proc on that type. -class AttackChainCallWalker: - def __init__(self, type_decl: TypeDecl, proc_decl: ProcDecl): - self.type_decl = type_decl - self.proc_decl = proc_decl - self.local_vars = dict() - self.attack_chain_calls = list() - - def get_var_type(self, name): - if name == "src": - return self.type_decl.path - if name in self.local_vars: - return self.local_vars[name] - for arg in self.proc_decl.args: - if arg.arg_name == name: - return arg.arg_type - - try: - vd = self.type_decl.var_decl(name, parents=True) - if vd.declared_type: - return vd.declared_type - except: - pass - - return None - - def add_attack_call(self, var_name, chain_call, source_info, legacy): - var_type = self.get_var_type(var_name) - CALLS[var_type].add( - AttackChainCall( - self.proc_decl, - var_name, - self.get_var_type(var_name), - chain_call, - source_info, - legacy=legacy, - ) - ) - - def visit_Var(self, node, source_info): - self.local_vars[str(node.name)] = node.declared_type - - def visit_Expr(self, node, source_info): - if node.kind == NodeKind.CALL: - legacy = False - record = False - if "__legacy__attackchain" in node.name.name: - legacy = True - record = True - elif node.name.name in NEW_PROCS: - legacy = False - record = True - if record and node.expr: - if node.expr.kind == NodeKind.IDENTIFIER: - self.add_attack_call( - str(node.expr), node.name.name, source_info, legacy - ) - elif node.expr.kind == NodeKind.CONSTANT: - if not node.expr.constant.val: - self.add_attack_call("src", node.name.name, source_info, legacy) - - -# Ignored types will never be part of the attack chain. -IGNORED_TYPES = [ - p("/area"), - p("/client"), - p("/database"), - p("/datum"), - p("/dm_filter"), - p("/exception"), - p("/generator"), - p("/icon"), - p("/image"), - p("/matrix"), - p("/mutable_appearance"), - p("/particles"), - p("/regex"), - p("/sound"), -] - -# Assisted types are the ones which actually perform negotiation between old/new -# attack chains, and will not be migrated until everything else is. -ASSISTED_TYPES = [ - p("/atom"), - p("/mob"), - p("/mob/living"), - p("/obj"), - p("/obj/item"), -] - -NEW_PROCS = [ - "activate_self", - "after_attack", - "attack_by", - "attack", - "attacked", - "interact_with_atom", - "item_interaction", -] - - -if __name__ == "__main__": - print("check_legacy_attack_chain started") - - exit_code = 0 - start = time.time() - - CALLS = defaultdict(set) - ERROR_STRINGS = list() - LEGACY_PROCS = defaultdict(list) - MODERN_PROCS = defaultdict(list) - SETTING_CACHE = dict() - - dme = DME.from_file("paradise.dme", parse_procs=True) - - for pth in dme.subtypesof("/"): - td = dme.types[pth] - if any( - [ - pth.child_of(assisted_type, strict=True) - for assisted_type in ASSISTED_TYPES - ] - ): - try: - SETTING_CACHE[pth] = bool( - td.var_decl("new_attack_chain", parents=True).const_val - ) - except: - SETTING_CACHE[pth] = False - for proc_name in td.proc_names(modified=True): - if "__legacy__attackchain" in proc_name: - for proc_decl in td.proc_decls(proc_name): - LEGACY_PROCS[pth].append(proc_decl) - elif proc_name in NEW_PROCS: - for proc_decl in td.proc_decls(proc_name): - MODERN_PROCS[pth].append(proc_decl) - for proc_decl in td.proc_decls(): - walker = AttackChainCallWalker(td, proc_decl) - proc_decl.walk(walker) - - for pth in sorted(SETTING_CACHE.keys()): - new_attack_chain = SETTING_CACHE[pth] - cursor = pth - if new_attack_chain: - if LEGACY_PROCS[pth]: - exit_code = 1 - for proc_decl in sorted(LEGACY_PROCS[pth], key=lambda x: x.name): - ERROR_STRINGS.append( - make_error_from_procdecl( - proc_decl, - f"migrated type with legacy proc {pth}/{proc_decl.name}(...)", - ) - ) - while cursor not in ASSISTED_TYPES and not cursor.is_root: - if LEGACY_PROCS[cursor] and not SETTING_CACHE[cursor]: - exit_code = 1 - print(f"new_attack_chain on {pth} but related type {cursor} is not") - cursor = cursor.parent - if pth in CALLS and any([x.legacy for x in CALLS[pth]]): - for call in CALLS[pth]: - if call.legacy: - ERROR_STRINGS.append(call.format_error()) - elif pth not in ASSISTED_TYPES: - if MODERN_PROCS[pth]: - exit_code = 1 - for proc_decl in sorted(MODERN_PROCS[pth], key=lambda x: x.name): - ERROR_STRINGS.append( - make_error_from_procdecl( - proc_decl, - f"legacy type with migrated proc {pth}/{proc_decl.name}(...)", - ) - ) - if pth in CALLS and any([not x.legacy for x in CALLS[pth]]): - exit_code = 1 - for call in CALLS[pth]: - if not call.legacy: - ERROR_STRINGS.append(call.format_error()) - - for legacy_proc_error in sorted(ERROR_STRINGS): - print(legacy_proc_error) - - end = time.time() - print(f"check_legacy_attack_chain tests completed in {end - start:.2f}s\n") - - sys.exit(exit_code) diff --git a/tools/ci/unticked_files.py b/tools/ci/unticked_files.py index 1ee042b30aa6b..5ab3f6d41ba97 100644 --- a/tools/ci/unticked_files.py +++ b/tools/ci/unticked_files.py @@ -21,7 +21,7 @@ INCLUDER_FILES = [ 'paradise.dme', 'code/modules/tgs/includes.dm', - 'code/tests/game_tests.dm', + 'code/modules/unit_tests/_unit_tests.dm', ] IGNORE_FILES = { diff --git a/tools/maplint/lints/area_basetype.yml b/tools/maplint/lints/area_basetype.yml deleted file mode 100644 index 83a147aaedb53..0000000000000 --- a/tools/maplint/lints/area_basetype.yml +++ /dev/null @@ -1,3 +0,0 @@ -help: "Use a subtype instead of /area." -=/area: - banned: true diff --git a/tools/maplint/lints/directional_newscasters.yml b/tools/maplint/lints/directional_newscasters.yml deleted file mode 100644 index 41177c5714874..0000000000000 --- a/tools/maplint/lints/directional_newscasters.yml +++ /dev/null @@ -1,13 +0,0 @@ -help: 'Use the specific directional subtypes for this newscaster.' -/obj/machinery/newscaster: - banned_variables: - - pixel_x - - pixel_y -=/obj/machinery/newscaster: - banned: true -=/obj/machinery/newscaster/directional: - banned: true -=/obj/machinery/newscaster/security_unit: - banned: true -=/obj/machinery/newscaster/security_unit/directional: - banned: true diff --git a/tools/maplint/lints/invalid_space_neighbors.yml b/tools/maplint/lints/invalid_space_neighbors.yml deleted file mode 100644 index 28037fd7d08af..0000000000000 --- a/tools/maplint/lints/invalid_space_neighbors.yml +++ /dev/null @@ -1,6 +0,0 @@ -/area/space: - banned_neighbors: - - /obj/machinery/door/airlock -=/area/space: - banned_neighbors: - - /obj/structure diff --git a/tools/maplint/lints/stack_tile.yml b/tools/maplint/lints/stack_tile.yml deleted file mode 100644 index 568dbed394ecf..0000000000000 --- a/tools/maplint/lints/stack_tile.yml +++ /dev/null @@ -1,2 +0,0 @@ -=/obj/item/stack/tile: - banned: true diff --git a/tools/maplint/lints/tile_mineral.yml b/tools/maplint/lints/tile_mineral.yml deleted file mode 100644 index 271dde768fc9b..0000000000000 --- a/tools/maplint/lints/tile_mineral.yml +++ /dev/null @@ -1,2 +0,0 @@ -=/obj/item/stack/tile/mineral: - banned: true diff --git a/tools/maplint/lints/unary_vents.yml b/tools/maplint/lints/unary_vents.yml deleted file mode 100644 index 080c2bd88097e..0000000000000 --- a/tools/maplint/lints/unary_vents.yml +++ /dev/null @@ -1,5 +0,0 @@ -/obj/machinery/atmospherics/unary: - banned_neighbors: - - /obj/machinery/atmospherics/pipe/manifold/hidden/supply - - /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers - diff --git a/tools/maplint/lints/wall_stacking.yml b/tools/maplint/lints/wall_stacking.yml index 7c14af178bd7f..43f818a9fa19d 100644 --- a/tools/maplint/lints/wall_stacking.yml +++ b/tools/maplint/lints/wall_stacking.yml @@ -5,4 +5,3 @@ - /obj/effect/spawner/window - /obj/machinery/door/airlock - /obj/effect/decal - - /obj/machinery/light diff --git a/tools/migrate_attack_chain.py b/tools/migrate_attack_chain.py deleted file mode 100644 index 0e80d383f139d..0000000000000 --- a/tools/migrate_attack_chain.py +++ /dev/null @@ -1,100 +0,0 @@ -from dataclasses import dataclass, field -import sys - -from avulto import DME, Path as p - - -@dataclass(frozen=True) -class MigrationPlan: - target_path: p - toggle_on: p - additional_paths: list[p] = field(default_factory=list) - - -ASSISTED_PATHS = [ - p("/obj"), - p("/obj/item"), - p("/mob"), - p("/mob/living"), - p("/atom"), -] - - -def has_legacy_procs(dme: DME, pth: p) -> bool: - td = dme.type_decl(pth) - proc_names = td.proc_names(modified=True) - return any([x for x in proc_names if "legacy__attackchain" in x]) - - -def get_migration_plan( - dme: DME, target_path: p, checked_types: set | None = None -) -> None | MigrationPlan: - if checked_types is None: - checked_types = set() - td = dme.type_decl(target_path) - new_attack_chain = td.var_decl("new_attack_chain", parents=True) - if new_attack_chain.const_val: - print( - f"Type {target_path} appears to be migrated already. Run CI tests to confirm valid migration." - ) - return - - additional_paths = set() - for subtype in dme.subtypesof(target_path): - if has_legacy_procs(dme, subtype): - additional_paths.add(subtype) - if subtype not in checked_types: - checked_types.add(subtype) - migration_plan = get_migration_plan(dme, subtype, checked_types) - if migration_plan: - additional_paths.update(migration_plan.additional_paths) - - toggle_on = target_path - parent = target_path - while not any([parent == x for x in ASSISTED_PATHS]): - parent = parent.parent - if not has_legacy_procs(dme, parent): - continue - if parent in ASSISTED_PATHS: - continue - - toggle_on = parent - if parent not in checked_types: - checked_types.add(parent) - migration_plan = get_migration_plan(dme, parent, checked_types) - if migration_plan: - additional_paths.update(migration_plan.additional_paths) - - additional_paths.add(parent) - - return MigrationPlan( - target_path=target_path, - toggle_on=toggle_on, - additional_paths=additional_paths, - ) - - -if __name__ == "__main__": - if len(sys.argv) != 2: - print("usage: migrate_attack_chain.py /target/path") - sys.exit(1) - dme = DME.from_file("paradise.dme") - target_path = p(sys.argv[1]) - - if not target_path.child_of("/atom"): - print(f"Type {target_path} is not an atom.") - sys.exit(1) - if target_path in ASSISTED_PATHS: - print(f"Type {target_path} should not be migrated.") - sys.exit(1) - - migration_plan = get_migration_plan(dme, target_path) - if migration_plan: - print(f"Migration Plan for Path {target_path}") - if migration_plan.additional_paths: - print("Required Additional Migrations:") - for addl_path in sorted(migration_plan.additional_paths): - print(f"\t{addl_path}") - else: - print("No Additional Migrations Required") - print(f"Toggle `new_attack_chain = TRUE` on:\n\t{migration_plan.toggle_on}") diff --git a/tools/pr_sql/27268/snake_case_type_remap.json b/tools/pr_sql/27268/snake_case_type_remap.json deleted file mode 100644 index 1736a89de6f15..0000000000000 --- a/tools/pr_sql/27268/snake_case_type_remap.json +++ /dev/null @@ -1,335 +0,0 @@ -[ - { - "original": "/area/ruin/unpowered/BMPship", - "replace": "/area/ruin/unpowered/bm_pship", - "override": "/area/ruin/unpowered/bmp_ship" - }, - { - "original": "/area/ruin/unpowered/BMPship/Aft", - "replace": "/area/ruin/unpowered/bm_pship/aft", - "override": "/area/ruin/unpowered/bmp_ship/aft" - }, - { - "original": "/area/ruin/unpowered/BMPship/Delta", - "replace": "/area/ruin/unpowered/bm_pship/delta", - "override": "/area/ruin/unpowered/bmp_ship/delta" - }, - { - "original": "/area/ruin/unpowered/BMPship/Fore", - "replace": "/area/ruin/unpowered/bm_pship/fore", - "override": "/area/ruin/unpowered/bmp_ship/fore" - }, - { - "original": "/area/ruin/unpowered/BMPship/Midship", - "replace": "/area/ruin/unpowered/bm_pship/midship", - "override": "/area/ruin/unpowered/bmp_ship/midship" - }, - { "original": "/area/station/security/prison/cell_block/A", "replace": "/area/station/security/prison/cell_block/a" }, - { "original": "/atom/movable/screen/act_intent/robot/AI", "replace": "/atom/movable/screen/act_intent/robot/ai" }, - { "original": "/atom/movable/screen/blob/BlobHelp", "replace": "/atom/movable/screen/blob/blob_help" }, - { "original": "/atom/movable/screen/blob/Blobbernaut", "replace": "/atom/movable/screen/blob/blobbernaut" }, - { "original": "/atom/movable/screen/blob/FactoryBlob", "replace": "/atom/movable/screen/blob/factory_blob" }, - { "original": "/atom/movable/screen/blob/JumpToCore", "replace": "/atom/movable/screen/blob/jump_to_core" }, - { "original": "/atom/movable/screen/blob/JumpToNode", "replace": "/atom/movable/screen/blob/jump_to_node" }, - { "original": "/atom/movable/screen/blob/NodeBlob", "replace": "/atom/movable/screen/blob/node_blob" }, - { "original": "/atom/movable/screen/blob/ReadaptChemical", "replace": "/atom/movable/screen/blob/readapt_chemical" }, - { "original": "/atom/movable/screen/blob/RelocateCore", "replace": "/atom/movable/screen/blob/relocate_core" }, - { "original": "/atom/movable/screen/blob/ResourceBlob", "replace": "/atom/movable/screen/blob/resource_blob" }, - { "original": "/atom/movable/screen/blob/Split", "replace": "/atom/movable/screen/blob/split" }, - { "original": "/atom/movable/screen/blob/StorageBlob", "replace": "/atom/movable/screen/blob/storage_blob" }, - { "original": "/atom/movable/screen/guardian/Communicate", "replace": "/atom/movable/screen/guardian/communicate" }, - { "original": "/atom/movable/screen/guardian/Manifest", "replace": "/atom/movable/screen/guardian/manifest" }, - { "original": "/atom/movable/screen/guardian/Recall", "replace": "/atom/movable/screen/guardian/recall" }, - { "original": "/atom/movable/screen/guardian/ToggleLight", "replace": "/atom/movable/screen/guardian/toggle_light" }, - { "original": "/atom/movable/screen/guardian/ToggleMode", "replace": "/atom/movable/screen/guardian/toggle_mode" }, - { "original": "/datum/AI_Module", "replace": "/datum/ai_module" }, - { "original": "/datum/ErrorViewer", "replace": "/datum/error_viewer" }, - { "original": "/datum/ErrorViewer/ErrorCache", "replace": "/datum/error_viewer/error_cache" }, - { "original": "/datum/ErrorViewer/ErrorEntry", "replace": "/datum/error_viewer/error_entry" }, - { "original": "/datum/ErrorViewer/ErrorSource", "replace": "/datum/error_viewer/error_source" }, - { "original": "/datum/SDQL_parser", "replace": "/datum/sdql_parser" }, - { "original": "/datum/action/changeling/absorbDNA", "replace": "/datum/action/changeling/absorb_dna" }, - { - "original": "/datum/action/item_action/YEEEAAAAAHHHHHHHHHHHHH", - "replace": "/datum/action/item_action/yeeeaaaaahhhhhhhhhhhhh" - }, - { - "original": "/datum/action/item_action/equip_unequip_TED_Gun", - "replace": "/datum/action/item_action/equip_unequip_ted_gun" - }, - { "original": "/datum/bottler_recipe/Applepocalypse", "replace": "/datum/bottler_recipe/applepocalypse" }, - { "original": "/datum/bottler_recipe/Berry_Banned", "replace": "/datum/bottler_recipe/berry_banned" }, - { "original": "/datum/bottler_recipe/Berry_Banned2", "replace": "/datum/bottler_recipe/berry_banned2" }, - { "original": "/datum/bottler_recipe/Blackeye_Brew", "replace": "/datum/bottler_recipe/blackeye_brew" }, - { "original": "/datum/bottler_recipe/Grape_Granade", "replace": "/datum/bottler_recipe/grape_granade" }, - { "original": "/datum/bottler_recipe/Meteor_Malt", "replace": "/datum/bottler_recipe/meteor_malt" }, - { "original": "/datum/bottler_recipe/Paradise_Punch", "replace": "/datum/bottler_recipe/paradise_punch" }, - { "original": "/datum/chemical_reaction/kahluaVodka", "replace": "/datum/chemical_reaction/kahlua_vodka" }, - { "original": "/datum/chemical_reaction/slimeRNG", "replace": "/datum/chemical_reaction/slime_rng" }, - { "original": "/datum/crafting_recipe/Ebi_maki", "replace": "/datum/crafting_recipe/ebi_maki" }, - { "original": "/datum/crafting_recipe/IED", "replace": "/datum/crafting_recipe/ied" }, - { "original": "/datum/crafting_recipe/Ikura_maki", "replace": "/datum/crafting_recipe/ikura_maki" }, - { "original": "/datum/crafting_recipe/Inari_maki", "replace": "/datum/crafting_recipe/inari_maki" }, - { "original": "/datum/crafting_recipe/Masago_maki", "replace": "/datum/crafting_recipe/masago_maki" }, - { "original": "/datum/crafting_recipe/Sake_maki", "replace": "/datum/crafting_recipe/sake_maki" }, - { "original": "/datum/crafting_recipe/SmokedSalmon_maki", "replace": "/datum/crafting_recipe/smoked_salmon_maki" }, - { "original": "/datum/crafting_recipe/Tai_maki", "replace": "/datum/crafting_recipe/tai_maki" }, - { "original": "/datum/crafting_recipe/TobikoEgg_maki", "replace": "/datum/crafting_recipe/tobiko_egg_maki" }, - { "original": "/datum/crafting_recipe/Tobiko_maki", "replace": "/datum/crafting_recipe/tobiko_maki" }, - { "original": "/datum/crafting_recipe/sushi_Ebi", "replace": "/datum/crafting_recipe/sushi_ebi" }, - { "original": "/datum/crafting_recipe/sushi_Ikura", "replace": "/datum/crafting_recipe/sushi_ikura" }, - { "original": "/datum/crafting_recipe/sushi_Inari", "replace": "/datum/crafting_recipe/sushi_inari" }, - { "original": "/datum/crafting_recipe/sushi_Masago", "replace": "/datum/crafting_recipe/sushi_masago" }, - { "original": "/datum/crafting_recipe/sushi_Sake", "replace": "/datum/crafting_recipe/sushi_sake" }, - { "original": "/datum/crafting_recipe/sushi_SmokedSalmon", "replace": "/datum/crafting_recipe/sushi_smoked_salmon" }, - { "original": "/datum/crafting_recipe/sushi_Tai", "replace": "/datum/crafting_recipe/sushi_tai" }, - { "original": "/datum/crafting_recipe/sushi_Tobiko", "replace": "/datum/crafting_recipe/sushi_tobiko" }, - { "original": "/datum/crafting_recipe/sushi_TobikoEgg", "replace": "/datum/crafting_recipe/sushi_tobiko_egg" }, - { "original": "/datum/design/BS_RPED", "replace": "/datum/design/bs_rped" }, - { "original": "/datum/design/RPED", "replace": "/datum/design/rped" }, - { - "original": "/datum/dog_fashion/head/HoS", - "replace": "/datum/dog_fashion/head/ho_s", - "override": "/datum/dog_fashion/head/hos" - }, - { "original": "/datum/gear/pAI", "replace": "/datum/gear/p_ai", "override": "/datum/gear/pai" }, - { "original": "/datum/holiday/UFO", "replace": "/datum/holiday/ufo" }, - { "original": "/datum/mapGenerator", "replace": "/datum/map_generator" }, - { "original": "/datum/mapGeneratorModule", "replace": "/datum/map_generator_module" }, - { - "original": "/datum/mapGeneratorModule/border/asteroidWalls", - "replace": "/datum/map_generator_module/border/asteroid_walls" - }, - { - "original": "/datum/mapGeneratorModule/border/syndieWalls", - "replace": "/datum/map_generator_module/border/syndie_walls" - }, - { "original": "/datum/mapGeneratorModule/bottomLayer", "replace": "/datum/map_generator_module/bottom_layer" }, - { - "original": "/datum/mapGeneratorModule/bottomLayer/asteroidTurfs", - "replace": "/datum/map_generator_module/bottom_layer/asteroid_turfs" - }, - { - "original": "/datum/mapGeneratorModule/bottomLayer/asteroidWalls", - "replace": "/datum/map_generator_module/bottom_layer/asteroid_walls" - }, - { - "original": "/datum/mapGeneratorModule/bottomLayer/grassTurfs", - "replace": "/datum/map_generator_module/bottom_layer/grass_turfs" - }, - { - "original": "/datum/mapGeneratorModule/bottomLayer/syndieFloor", - "replace": "/datum/map_generator_module/bottom_layer/syndie_floor" - }, - { "original": "/datum/mapGeneratorModule/deadTrees", "replace": "/datum/map_generator_module/dead_trees" }, - { "original": "/datum/mapGeneratorModule/denseLayer", "replace": "/datum/map_generator_module/dense_layer" }, - { - "original": "/datum/mapGeneratorModule/denseLayer/grassTufts", - "replace": "/datum/map_generator_module/dense_layer/grass_tufts" - }, - { "original": "/datum/mapGeneratorModule/pineTrees", "replace": "/datum/map_generator_module/pine_trees" }, - { "original": "/datum/mapGeneratorModule/randBushes", "replace": "/datum/map_generator_module/rand_bushes" }, - { "original": "/datum/mapGeneratorModule/randRocks", "replace": "/datum/map_generator_module/rand_rocks" }, - { "original": "/datum/mapGeneratorModule/splatterLayer", "replace": "/datum/map_generator_module/splatter_layer" }, - { - "original": "/datum/mapGeneratorModule/splatterLayer/asteroidMonsters", - "replace": "/datum/map_generator_module/splatter_layer/asteroid_monsters" - }, - { - "original": "/datum/mapGeneratorModule/splatterLayer/asteroidWalls", - "replace": "/datum/map_generator_module/splatter_layer/asteroid_walls" - }, - { - "original": "/datum/mapGeneratorModule/splatterLayer/syndieMobs", - "replace": "/datum/map_generator_module/splatter_layer/syndie_mobs" - }, - { - "original": "/datum/mapGeneratorModule/syndieFurniture", - "replace": "/datum/map_generator_module/syndie_furniture" - }, - { "original": "/datum/middleClickOverride", "replace": "/datum/middle_click_override" }, - { "original": "/datum/middleClickOverride/badminClicker", "replace": "/datum/middle_click_override/badmin_clicker" }, - { "original": "/datum/objective/abductee/POWERUNLIMITED", "replace": "/datum/objective/abductee/powerunlimited" }, - { "original": "/datum/objective/revenantFluff", "replace": "/datum/objective/revenant_fluff" }, - { "original": "/datum/paiController", "replace": "/datum/pai_controller" }, - { "original": "/datum/prize_item/AI", "replace": "/datum/prize_item/ai" }, - { "original": "/datum/recipe/grill/sushi_Ebi", "replace": "/datum/recipe/grill/sushi_ebi" }, - { "original": "/datum/recipe/grill/sushi_Ikura", "replace": "/datum/recipe/grill/sushi_ikura" }, - { "original": "/datum/recipe/grill/sushi_Inari", "replace": "/datum/recipe/grill/sushi_inari" }, - { "original": "/datum/recipe/grill/sushi_Masago", "replace": "/datum/recipe/grill/sushi_masago" }, - { "original": "/datum/recipe/grill/sushi_Sake", "replace": "/datum/recipe/grill/sushi_sake" }, - { "original": "/datum/recipe/grill/sushi_SmokedSalmon", "replace": "/datum/recipe/grill/sushi_smoked_salmon" }, - { "original": "/datum/recipe/grill/sushi_Tai", "replace": "/datum/recipe/grill/sushi_tai" }, - { "original": "/datum/recipe/grill/sushi_Tamago", "replace": "/datum/recipe/grill/sushi_tamago" }, - { "original": "/datum/recipe/grill/sushi_Tobiko", "replace": "/datum/recipe/grill/sushi_tobiko" }, - { "original": "/datum/recipe/grill/sushi_TobikoEgg", "replace": "/datum/recipe/grill/sushi_tobiko_egg" }, - { "original": "/datum/recipe/grill/sushi_Unagi", "replace": "/datum/recipe/grill/sushi_unagi" }, - { "original": "/datum/sortInstance", "replace": "/datum/sort_instance" }, - { "original": "/datum/spell/aoe/conjure/summonEdSwarm", "replace": "/datum/spell/aoe/conjure/summon_ed_swarm" }, - { - "original": "/datum/sprite_accessory/head_accessory/kidan/kidan_Mantie_Curled", - "replace": "/datum/sprite_accessory/head_accessory/kidan/kidan_mantie_curled" - }, - { - "original": "/datum/sprite_accessory/head_accessory/kidan/kidan_Mantie_Long", - "replace": "/datum/sprite_accessory/head_accessory/kidan/kidan_mantie_long" - }, - { "original": "/datum/status_effect/hippocraticOath", "replace": "/datum/status_effect/hippocratic_oath" }, - { - "original": "/datum/supply_packs/engineering/engine/PA", - "replace": "/datum/supply_packs/engineering/engine/pa", - "override": "/datum/supply_packs/engineering/engine/particle_accelerator" - }, - { - "original": "/datum/uplink_item/ammo/bulldog_XLmagsbag", - "replace": "/datum/uplink_item/ammo/bulldog_x_lmagsbag", - "override": "/datum/uplink_item/ammo/bulldog_xl_magsbag" - }, - { "original": "/datum/uplink_item/bundles_TC", "replace": "/datum/uplink_item/bundles_tc" }, - { "original": "/datum/uplink_item/stealthy_weapons/RSG", "replace": "/datum/uplink_item/stealthy_weapons/rsg" }, - { "original": "/mob/camera/aiEye", "replace": "/mob/camera/ai_eye" }, - { "original": "/mob/living/simple_animal/cockroach/Brad", "replace": "/mob/living/simple_animal/cockroach/brad" }, - { "original": "/mob/living/simple_animal/crab/Coffee", "replace": "/mob/living/simple_animal/crab/coffee" }, - { - "original": "/mob/living/simple_animal/hostile/bear/Hudson", - "replace": "/mob/living/simple_animal/hostile/bear/hudson" - }, - { "original": "/mob/living/simple_animal/mouse/brown/Tom", "replace": "/mob/living/simple_animal/mouse/brown/tom" }, - { - "original": "/mob/living/simple_animal/mouse/white/Brain", - "replace": "/mob/living/simple_animal/mouse/white/brain" - }, - { "original": "/mob/living/simple_animal/parrot/Poly", "replace": "/mob/living/simple_animal/parrot/poly" }, - { - "original": "/mob/living/simple_animal/pet/cat/Proc", - "replace": "/mob/living/simple_animal/pet/cat/proc", - "override": "/mob/living/simple_animal/pet/cat/proc_cat" - }, - { "original": "/mob/living/simple_animal/pet/cat/Runtime", "replace": "/mob/living/simple_animal/pet/cat/runtime" }, - { "original": "/mob/living/simple_animal/pet/cat/Syndi", "replace": "/mob/living/simple_animal/pet/cat/syndi" }, - { - "original": "/mob/living/simple_animal/pet/cat/Var", - "replace": "/mob/living/simple_animal/pet/cat/var", - "override": "/mob/living/simple_animal/pet/cat/var_cat" - }, - { - "original": "/mob/living/simple_animal/pet/dog/corgi/Ian", - "replace": "/mob/living/simple_animal/pet/dog/corgi/ian" - }, - { - "original": "/mob/living/simple_animal/pet/dog/corgi/Lisa", - "replace": "/mob/living/simple_animal/pet/dog/corgi/lisa" - }, - { - "original": "/mob/living/simple_animal/pet/dog/fox/Renault", - "replace": "/mob/living/simple_animal/pet/dog/fox/renault" - }, - { - "original": "/mob/living/simple_animal/pet/dog/fox/Syndifox", - "replace": "/mob/living/simple_animal/pet/dog/fox/syndifox" - }, - { "original": "/obj/item/CQC_manual", "replace": "/obj/item/cqc_manual" }, - { "original": "/obj/item/FixOVein", "replace": "/obj/item/fix_o_vein" }, - { "original": "/obj/item/aiModule", "replace": "/obj/item/ai_module" }, - { "original": "/obj/item/aiModule/oneCrewMember", "replace": "/obj/item/ai_module/one_crew_member" }, - { "original": "/obj/item/aiModule/protectStation", "replace": "/obj/item/ai_module/protect_station" }, - { "original": "/obj/item/aiModule/toyAI", "replace": "/obj/item/aiModule/toy_ai" }, - { "original": "/obj/item/ammo_box/magazine/m12g/XtrLrg", "replace": "/obj/item/ammo_box/magazine/m12g/xtr_lrg" }, - { "original": "/obj/item/badminBook", "replace": "/obj/item/badmin_book" }, - { "original": "/obj/item/circuitboard/HolodeckControl", "replace": "/obj/item/circuitboard/holodeck_control" }, - { - "original": "/obj/item/clothing/accessory/medal/fluff/XannZxiax", - "replace": "/obj/item/clothing/accessory/medal/fluff/xann_zxiax" - }, - { - "original": "/obj/item/clothing/head/HoS", - "replace": "/obj/item/clothing/head/ho_s", - "override": "/obj/item/clothing/head/hos" - }, - { - "original": "/obj/item/clothing/head/collectable/HoP", - "replace": "/obj/item/clothing/head/collectable/ho_p", - "override": "/obj/item/clothing/head/collectable/hop" - }, - { - "original": "/obj/item/clothing/head/collectable/HoS", - "replace": "/obj/item/clothing/head/collectable/ho_s", - "override": "/obj/item/clothing/head/collectable/hos" - }, - { "original": "/obj/item/destTagger", "replace": "/obj/item/dest_tagger" }, - { "original": "/obj/item/food/sliceable/Ebi_maki", "replace": "/obj/item/food/sliceable/ebi_maki" }, - { "original": "/obj/item/food/sliceable/Ikura_maki", "replace": "/obj/item/food/sliceable/ikura_maki" }, - { "original": "/obj/item/food/sliceable/Inari_maki", "replace": "/obj/item/food/sliceable/inari_maki" }, - { "original": "/obj/item/food/sliceable/Masago_maki", "replace": "/obj/item/food/sliceable/masago_maki" }, - { "original": "/obj/item/food/sliceable/Sake_maki", "replace": "/obj/item/food/sliceable/sake_maki" }, - { - "original": "/obj/item/food/sliceable/SmokedSalmon_maki", - "replace": "/obj/item/food/sliceable/smoked_salmon_maki" - }, - { "original": "/obj/item/food/sliceable/Tai_maki", "replace": "/obj/item/food/sliceable/tai_maki" }, - { "original": "/obj/item/food/sliceable/Tamago_maki", "replace": "/obj/item/food/sliceable/tamago_maki" }, - { "original": "/obj/item/food/sliceable/TobikoEgg_maki", "replace": "/obj/item/food/sliceable/tobiko_egg_maki" }, - { "original": "/obj/item/food/sliceable/Tobiko_maki", "replace": "/obj/item/food/sliceable/tobiko_maki" }, - { "original": "/obj/item/food/sushi_Ebi", "replace": "/obj/item/food/sushi_ebi" }, - { "original": "/obj/item/food/sushi_Ikura", "replace": "/obj/item/food/sushi_ikura" }, - { "original": "/obj/item/food/sushi_Inari", "replace": "/obj/item/food/sushi_inari" }, - { "original": "/obj/item/food/sushi_Masago", "replace": "/obj/item/food/sushi_masago" }, - { "original": "/obj/item/food/sushi_Sake", "replace": "/obj/item/food/sushi_sake" }, - { "original": "/obj/item/food/sushi_SmokedSalmon", "replace": "/obj/item/food/sushi_smoked_salmon" }, - { "original": "/obj/item/food/sushi_Tai", "replace": "/obj/item/food/sushi_tai" }, - { "original": "/obj/item/food/sushi_Tamago", "replace": "/obj/item/food/sushi_tamago" }, - { "original": "/obj/item/food/sushi_Tobiko", "replace": "/obj/item/food/sushi_tobiko" }, - { "original": "/obj/item/food/sushi_TobikoEgg", "replace": "/obj/item/food/sushi_tobiko_egg" }, - { "original": "/obj/item/food/sushi_Unagi", "replace": "/obj/item/food/sushi_unagi" }, - { - "original": "/obj/item/gun/projectile/automatic/pistol/APS", - "replace": "/obj/item/gun/projectile/automatic/pistol/aps" - }, - { "original": "/obj/item/paper/Court", "replace": "/obj/item/paper/court" }, - { "original": "/obj/item/paper/Toxin", "replace": "/obj/item/paper/toxin" }, - { "original": "/obj/item/reagent_containers/hypospray/CMO", "replace": "/obj/item/reagent_containers/hypospray/cmo" }, - { - "original": "/obj/item/reagent_containers/iv_bag/blood/AMinus", - "replace": "/obj/item/reagent_containers/iv_bag/blood/a_minus" - }, - { - "original": "/obj/item/reagent_containers/iv_bag/blood/APlus", - "replace": "/obj/item/reagent_containers/iv_bag/blood/a_plus" - }, - { - "original": "/obj/item/reagent_containers/iv_bag/blood/BMinus", - "replace": "/obj/item/reagent_containers/iv_bag/blood/b_minus" - }, - { - "original": "/obj/item/reagent_containers/iv_bag/blood/BPlus", - "replace": "/obj/item/reagent_containers/iv_bag/blood/b_plus" - }, - { - "original": "/obj/item/reagent_containers/iv_bag/blood/OMinus", - "replace": "/obj/item/reagent_containers/iv_bag/blood/o_minus" - }, - { - "original": "/obj/item/reagent_containers/iv_bag/blood/OPlus", - "replace": "/obj/item/reagent_containers/iv_bag/blood/o_plus" - }, - { "original": "/obj/item/shippingPackage", "replace": "/obj/item/shipping_package" }, - { "original": "/obj/item/smallDelivery", "replace": "/obj/item/small_delivery" }, - { "original": "/obj/item/stack/packageWrap", "replace": "/obj/item/stack/package_wrap" }, - { - "original": "/obj/item/storage/backpack/duffel/syndie/shotgunXLmags", - "replace": "/obj/item/storage/backpack/duffel/syndie/shotgun_x_lmags", - "override": "/obj/item/storage/backpack/duffel/syndie/shotgun_xl_mags" - }, - { - "original": "/obj/item/storage/box/PDAs", - "replace": "/obj/item/storage/box/pd_as", - "override": "/obj/item/storage/box/pdas" - }, - { "original": "/obj/item/toy/AI", "replace": "/obj/item/toy/ai" }, - { "original": "/obj/machinery/computer/HolodeckControl", "replace": "/obj/machinery/computer/holodeck_control" }, - { "original": "/obj/machinery/disposal/deliveryChute", "replace": "/obj/machinery/disposal/delivery_chute" }, - { "original": "/obj/structure/AIcore", "replace": "/obj/structure/a_icore", "override": "/obj/structure/ai_core" }, - { "original": "/obj/structure/bigDelivery", "replace": "/obj/structure/big_delivery" }, - { "original": "/obj/structure/closet/secure_closet/CMO", "replace": "/obj/structure/closet/secure_closet/cmo" }, - { "original": "/obj/structure/closet/secure_closet/RD", "replace": "/obj/structure/closet/secure_closet/rd" } -] diff --git a/tools/pr_sql/27268/snake_case_typepaths.py b/tools/pr_sql/27268/snake_case_typepaths.py deleted file mode 100644 index f3217954cc15b..0000000000000 --- a/tools/pr_sql/27268/snake_case_typepaths.py +++ /dev/null @@ -1,186 +0,0 @@ -# :wave: hello fellow contributors, this script is brought to you ad-free by AffectedArc07 and Warriorstar -# In order to run this script on Windows, you need to make sure you have Python **3** installed. Tested on 3.10.4 -# In addition you must have the mysql-connector-python module installed (can be done through pip :D) -# if you do not have that module installed, you cannot run this script - -# To run this, supply the following args in a command shell -# python 62-63.py address username password database -# Example: -# python 62-63.py 127.0.0.1 sirryan2002 myubersecretdbpassword paradise_gamedb - -from pathlib import Path -from datetime import datetime -import argparse -import json - -import mysql.connector - - -def log(msg): - print(f"[{datetime.utcnow()}] {msg}") - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument( - "address", help="MySQL server address (use localhost for the current computer)" - ) - parser.add_argument("username", help="MySQL login username") - parser.add_argument("password", help="MySQL login password") - parser.add_argument("database", help="Database name") - - args = parser.parse_args() - db = mysql.connector.connect( - host=args.address, user=args.username, passwd=args.password, db=args.database - ) - cursor = db.cursor() - log(f"Connected to {args.database}") - - # want these ordered by length from longest to shortest so shorter replacements - # don't replace pieces of larger replacements - renames = sorted( - json.load(open(Path(__file__).parent / "snake_case_type_remap.json")), - key=lambda x: len(x["original"]), - reverse=True, - ) - - log("feedback: running query") - cursor = db.cursor() - cursor.execute( - """ - SELECT round_id, key_name, json, id - FROM feedback - ORDER BY id DESC - """ - ) - - log("feedback: fetching all data") - rows = cursor.fetchall() - log(f"feedback: processing {len(rows)} rows...") - - sql_statements = list() - for row in rows: - row_replacements = [] - for rename in renames: - if rename["original"] in row[2]: - row_replacements.append(rename) - if row_replacements: - for replacement in sorted( - row_replacements, key=lambda x: len(x["original"]), reverse=True - ): - update_sql = ( - """UPDATE feedback SET json = REPLACE(json, %s, %s) WHERE id = %s""", - ( - replacement["original"], - replacement.get("override", replacement["replace"]), - row[3], - ), - ) - - sql_statements.append(update_sql) - - log(f"feedback: running {len(sql_statements)} SQL updates") - - if len(sql_statements) > 0: - cursor = db.cursor() - for update_sql in sql_statements: - cursor.execute(*update_sql) - - log("feedback: committing data") - db.commit() - - log("json_datum_saves: running query") - cursor = db.cursor() - cursor.execute( - """ - SELECT id, slotjson - FROM json_datum_saves - ORDER BY id DESC - """ - ) - - log("json_datum_saves: fetching all data") - rows = cursor.fetchall() - log(f"json_datum_saves: processing {len(rows)} rows...") - - sql_statements = list() - for row in rows: - row_replacements = [] - for rename in renames: - if rename["original"] in row[1]: - row_replacements.append(rename) - if row_replacements: - for replacement in sorted( - row_replacements, key=lambda x: len(x["original"]), reverse=True - ): - update_sql = ( - """UPDATE json_datum_saves SET slotjson = REPLACE(slotjson, %s, %s) WHERE id = %s""", - ( - replacement["original"], - replacement.get("override", replacement["replace"]), - row[0], - ), - ) - - sql_statements.append(update_sql) - - log(f"json_datum_saves: running {len(sql_statements)} SQL updates") - - if len(sql_statements) > 0: - cursor = db.cursor() - for update_sql in sql_statements: - cursor.execute(*update_sql) - - log("json_datum_saves: committing data") - db.commit() - - log("characters: running query") - cursor = db.cursor() - cursor.execute( - """ - SELECT id, gear - FROM characters - ORDER BY id DESC - """ - ) - - log("characters: fetching all data") - rows = cursor.fetchall() - log(f"characters: processing {len(rows)} rows...") - - sql_statements = list() - for row in rows: - row_replacements = [] - for rename in renames: - if rename["original"] in row[1]: - row_replacements.append(rename) - if row_replacements: - for replacement in sorted( - row_replacements, key=lambda x: len(x["original"]), reverse=True - ): - update_sql = ( - """UPDATE characters SET gear = REPLACE(gear, %s, %s) WHERE id = %s""", - ( - replacement["original"], - replacement.get("override", replacement["replace"]), - row[0], - ), - ) - - sql_statements.append(update_sql) - - log(f"characters: running {len(sql_statements)} SQL updates") - - if len(sql_statements) > 0: - cursor = db.cursor() - for update_sql in sql_statements: - cursor.execute(*update_sql) - - log("characters: committing data") - db.commit() - - log("done.") - - -if __name__ == "__main__": - main() diff --git a/tools/pr_sql/27474/neckconvert.py b/tools/pr_sql/27474/neckconvert.py deleted file mode 100644 index 3d2299be274aa..0000000000000 --- a/tools/pr_sql/27474/neckconvert.py +++ /dev/null @@ -1,49 +0,0 @@ -import mysql.connector, argparse, json - -parser = argparse.ArgumentParser() -parser.add_argument("address", help="MySQL server address (use localhost for the current computer)") -parser.add_argument("username", help="MySQL login username") -parser.add_argument("password", help="MySQL login password") -parser.add_argument("database", help="Database name") - -args = parser.parse_args() -db = mysql.connector.connect(host=args.address, user=args.username, passwd=args.password, db=args.database) -cursor = db.cursor() -print("Connected to {}".format(args.database)) - -paths_to_nuke = ["/datum/gear/accessory/scarf", "/datum/gear/accessory/scarf/red", "/datum/gear/accessory/scarf/green", "/datum/gear/accessory/scarf/darkblue", "/datum/gear/accessory/scarf/purple", "/datum/gear/accessory/scarf/yellow", "/datum/gear/accessory/scarf/orange", "/datum/gear/accessory/scarf/lightblue", "/datum/gear/accessory/scarf/white", "/datum/gear/accessory/scarf/black", "/datum/gear/accessory/scarf/zebra", "/datum/gear/accessory/scarf/christmas", "/datum/gear/accessory/scarf/stripedred", "/datum/gear/accessory/scarf/stripedgreen", "/datum/gear/accessory/scarf/stripedblue", "/datum/gear/accessory/tieblue", "/datum/gear/accessory/tiered", "/datum/gear/accessory/tieblack", "/datum/gear/accessory/tiehorrible", "/datum/gear/accessory/stethoscope", "/datum/gear/accessory/locket/silver", "/datum/gear/accessory/locket", "/datum/gear/accessory/necklace/long", "/datum/gear/accessory/necklace", "/datum/gear/suit/mantle", "/datum/gear/suit/old_scarf", "/datum/gear/suit/regal_shawl", "/datum/gear/suit/mantle/job", "/datum/gear/suit/mantle/job/captain", "/datum/gear/suit/mantle/job/ce", "/datum/gear/suit/mantle/job/cmo", "/datum/gear/suit/mantle/job/hos", "/datum/gear/suit/mantle/job/hop", "/datum/gear/suit/mantle/job/rd"] - -print("Loading data...") -load_qry = "SELECT id, gear FROM characters WHERE gear IS NOT NULL AND gear != ''" # fucking allowing empty strings instead of nullables -cursor.execute(load_qry) -res = cursor.fetchall() - -to_replace = [] - -for row in res: - row_id = row[0] - loadout = json.loads(row[1]) - - edited = False - for entry in paths_to_nuke: - if entry in loadout: - if isinstance(loadout, dict): # why the fuck are there dictionaries in the DB - del(loadout[entry]) - else: - loadout.remove(entry) - edited = True - - if edited: - to_replace.append([row_id, loadout]) - -print("Loaded {} rows to update".format(len(to_replace))) - -update_qry = "UPDATE characters SET gear=%s WHERE id=%s" -for entry in to_replace: - cursor.execute(update_qry, [json.dumps(entry[1]), entry[0]]) - -print("Updates complete") -cursor.close() -print("Saving...") -db.commit() -print("Done!") diff --git a/tools/requirements.txt b/tools/requirements.txt index 751e8771deeb3..98e5e48cab09d 100644 --- a/tools/requirements.txt +++ b/tools/requirements.txt @@ -6,6 +6,3 @@ json5==0.9.14 # changelogs PyYaml==6.0.1 # maplint also beautifulsoup4==4.12.2 - -# various CI checks -avulto==0.1.4
      -
    • Class: Autonomous Power Loader
    • -
    • Scope: Logistics and Construction
    • -
    • Weight: 820kg (without operator and with empty cargo compartment)
    • -
    • Height: 2.5m
    • -
    • Width: 1.8m
    • -
    • Top speed: 5km/hour
    • -
    • Operation in vacuum/hostile environment: Possible -
    • Airtank Volume: 500liters
    • -
    • Devices: -
        -
      • Hydraulic Clamp
      • -
      • High-speed Drill
      • -
      -
    • -
    • Propulsion Device: Powercell-powered electro-hydraulic system.
    • -
    • Powercell capacity: Varies.
    • -