diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000000..b1d2dbdb588 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{dme,dmf,dmm,dm}] +end_of_line = crlf +indent_style = tab + +[*.md] +trim_trailing_whitespace = false + +[*.py] +indent_style = space +indent_size = 4 + +[*.yml] +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index 5e9dfae55f1..c5587f60421 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,10 +1,16 @@ -# dmm map merger hook -# needs additional setup, see tools/mapmerge/install.txt -# *.dmm merge=merge-dmm - -# dmi icon merger hook -# needs additional setup, see tools/dmitool/merging.txt -*.dmi merge=merge-dmi - -# force changelog merging to use union -html/changelog.html merge=union +## Enforce binary mode +*.dll binary +*.exe binary +*.so binary +*.zip binary + +# dmm map merger hook +# needs additional setup, see tools/mapmerge/install.txt +# *.dmm merge=merge-dmm + +# dmi icon merger hook +# needs additional setup, see tools/dmitool/merging.txt +*.dmi merge=merge-dmi + +# force changelog merging to use union +html/changelog.html merge=union diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 678486f0195..1b5698ba5ef 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,8 +4,9 @@ # In the event that multiple org members are to be informed of changes # to the same file or dir, add them to the end under Multiple Owners -# ShadowLarkens -/code/__DEFINES/tgui.dm @ShadowLarkens -/code/controllers/subsystem/tgui.dm @ShadowLarkens -/code/modules/tgui @ShadowLarkens -/tgui @ShadowLarkens \ No newline at end of file +# ItsSelis + +/code/__DEFINES/tgui.dm @ItsSelis +/code/controllers/subsystem/tgui.dm @ItsSelis +/code/modules/tgui @ItsSelis +/tgui @ItsSelis diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/bug_report.md similarity index 90% rename from .github/ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE/bug_report.md index e26a763524d..b8ec75ce5cf 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,3 +1,12 @@ +--- +name: General Bug report +about: Create a report to help us improve +title: '[GENERAL] ' +labels: 'Type: Bug' +assignees: '' + +--- + diff --git a/.github/ISSUE_TEMPLATE/map_report.md b/.github/ISSUE_TEMPLATE/map_report.md new file mode 100644 index 00000000000..a3aa174357f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/map_report.md @@ -0,0 +1,29 @@ +--- +name: Map Bug report +about: Create a report, specific to any map related things. +title: '[MAPPING] ' +labels: ['Type: Bug', 'Type: Map'] +assignees: '' + +--- + + + + + + +#### Brief description of the bug + + +#### What you expected to happen + + +#### What actually happened + + +#### Code Revision +- (Found using the "Show Server Revision" verb under the OOC tab.) + + +#### Anything else you may wish to add: +- (Location if it's a mapping issue, screenshots, sprites, etc.) diff --git a/.github/ISSUE_TEMPLATE/ui_report.md b/.github/ISSUE_TEMPLATE/ui_report.md new file mode 100644 index 00000000000..83dfec32e75 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/ui_report.md @@ -0,0 +1,35 @@ +--- +name: UI Bug report +about: Create a report, specific to any UI related things. +title: '[UI] ' +labels: 'Type: Bug' +assignees: '' + +--- + + + + + + +#### Brief description of the bug + + +#### What you expected to happen + + +#### What actually happened + + +#### Steps to reproduce +- (Step 1) +- (Step 2) +- (and so on) + + +#### Code Revision +- (Found using the "Show Server Revision" verb under the OOC tab.) + + +#### Anything else you may wish to add: +- (Location if it's a mapping issue, screenshots, sprites, etc.) diff --git a/.github/boring-cyborg.yml b/.github/boring-cyborg.yml index 8dfea4c815b..9472efeeded 100644 --- a/.github/boring-cyborg.yml +++ b/.github/boring-cyborg.yml @@ -32,6 +32,10 @@ labelPRBasedOnFilePath: "Type: .git or .github": - '.github/**' - '.git/**' + + # Contains changes to the TGUI bundle + "Type: TGUI Bundle": + - 'tgui/public/**' ##### Greetings ######################################################################################################## # Comment to be posted to welcome users when they open their first PR @@ -99,4 +103,4 @@ firstIssueWelcomeComment: > # # It helps avoid multiple heads in alembic migrations in a collaborative development project. # - airflow/migrations/* # - airflow/migrations/**/* -# - airflow/alembic.ini \ No newline at end of file +# - airflow/alembic.ini diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000000..9d69be5ecba --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 + +updates: + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: "daily" + - package-ecosystem: npm + directory: "/tools" + schedule: + interval: "daily" diff --git a/.github/workflows/autochangelog.yml b/.github/workflows/autochangelog.yml index 71a53a5b2dc..cb6ecabe468 100644 --- a/.github/workflows/autochangelog.yml +++ b/.github/workflows/autochangelog.yml @@ -1,43 +1,43 @@ name: Autochangelog -on: - pull_request_target: - types: closed - branches: - - master - +on: + pull_request_target: + types: closed + branches: + - master + env: - BASENAME: "polaris" + BASENAME: "vorestation" jobs: - autochangelog: - name: Autochangelog - runs-on: ubuntu-20.04 - if: github.event.pull_request.merged == true - steps: - - uses: /actions/checkout@v2 - with: - ref: master - - name: Update repository to master - run: git pull "origin" master - - name: Ensure +x on CI directory - run: | - chmod -R +x ./tools/ci - - uses: actions/setup-python@v2 - with: - python-version: '3.7' - - name: Generate Changelog - run: | - pip install pyyaml - python tools/GenerateChangelog/ss13_autochangelog.py \ - html/changelogs \ - ${{ github.event.pull_request.number }} \ - "${{ github.event.pull_request.user.login }}" \ - "${{ github.event.pull_request.body }}" - python tools/GenerateChangelog/ss13_genchangelog.py \ - html/changelog.html \ - html/changelogs - - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Automatic changelog generation for ${{ github.events.pull_request.number }} - branch: ${{ github.events.pull_request.base }} - commit_user_name: Autochangelog Bot + autochangelog: + name: Autochangelog + runs-on: ubuntu-latest + if: github.event.pull_request.merged == true + steps: + - uses: /actions/checkout@v3 + with: + ref: master + - name: Update repository to master + run: git pull "origin" master + - name: Ensure +x on CI directory + run: | + chmod -R +x ./tools/ci + - uses: actions/setup-python@v4 + with: + python-version: '3.7' + - name: Generate Changelog + run: | + pip install pyyaml + python tools/GenerateChangelog/ss13_autochangelog.py \ + html/changelogs \ + ${{ github.event.pull_request.number }} \ + "${{ github.event.pull_request.user.login }}" \ + "${{ github.event.pull_request.body }}" + python tools/GenerateChangelog/ss13_genchangelog.py \ + html/changelog.html \ + html/changelogs + - uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: Automatic changelog generation for ${{ github.events.pull_request.number }} + branch: ${{ github.events.pull_request.base }} + commit_user_name: Autochangelog Bot diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1760c46faea..b6be2dceba5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,15 +10,25 @@ env: jobs: file_tests: name: Run Linters - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Ensure +x on CI directory run: | chmod -R +x ./tools/ci - name: Install Tools run: | bash tools/ci/install_build_deps.sh + - name: Restore Yarn cache + if: "${{ contains(github.event.pull_request.labels.*.name, 'Type: TGUI Bundle') }}" + uses: actions/cache@v3 + with: + path: tgui/.yarn/cache + key: ${{ runner.os }}-yarn-${{ secrets.CACHE_PURGE_KEY }}-${{ hashFiles('tgui/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-build-${{ secrets.CACHE_PURGE_KEY }}- + ${{ runner.os }}-build- + ${{ runner.os }}- - name: Run Tests run: | tools/ci/validate_files.sh @@ -26,42 +36,47 @@ jobs: dreamchecker: name: DreamChecker - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache SpacemanDMM - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/SpacemanDMM key: ${{ runner.os }}-dreamchecker-${{ hashFiles('dependencies.sh')}} restore-keys: ${{ runner.os }}-dreamchecker - + - name: Install Dependencies run: | tools/ci/install_spaceman_dmm.sh dreamchecker - + - name: Run Linter id: linter run: | ~/dreamchecker > ${GITHUB_WORKSPACE}/output-annotations.txt 2>&1 - + - name: Annotate Linter uses: yogstation13/DreamAnnotate@v1 if: always() - with: + with: outputFile: output-annotations.txt unit_tests: + strategy: + matrix: + map: ['tether', 'stellar_delight', 'groundbase'] + # name: Integration Tests (${{ matrix.map }}) name: Integration Tests - runs-on: ubuntu-20.04 + # needs: ['file_tests', 'dreamchecker'] + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Ensure +x on CI directory run: | chmod -R +x ./tools/ci - name: Setup Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: $HOME/BYOND key: ${{ runner.os }}-byond @@ -78,20 +93,35 @@ jobs: env: TEST_DEFINE: "UNIT_TEST" TEST_FILE: "code/_unit_tests.dm" + MAP: ${{ matrix.map }} + REPLACE: true RUN: "1" - - name: Compile POIs (no run) + - name: Compile POIs run: | tools/ci/install_byond.sh tools/ci/compile_and_run.sh env: TEST_DEFINE: "MAP_TEST" TEST_FILE: "code/_map_tests.dm" + MAP: ${{ matrix.map }} + REPLACE: false RUN: "0" - - name: Compile away missions (no run) + - name: Compile away missions run: | tools/ci/install_byond.sh tools/ci/compile_and_run.sh env: TEST_DEFINE: "AWAY_MISSION_TEST" TEST_FILE: "code/_away_mission_tests.dm" + MAP: ${{ matrix.map }} + REPLACE: false RUN: "0" + + tests_successful: + name: Integration Tests + needs: ['file_tests', 'dreamchecker', 'unit_tests'] + runs-on: ubuntu-latest + steps: + - name: Report Success + run: | + echo "Jobs Successful!" diff --git a/.github/workflows/render_nanomaps.yml b/.github/workflows/render_nanomaps.yml index fd5536ea48e..57f305772c6 100644 --- a/.github/workflows/render_nanomaps.yml +++ b/.github/workflows/render_nanomaps.yml @@ -14,10 +14,10 @@ on: jobs: generate_maps: name: 'Generate NanoMaps' - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Clone - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Branch run: | diff --git a/.gitignore b/.gitignore index 03c676f53d8..b2dd85c6602 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,28 @@ -#ignore misc BYOND files -Thumbs.db -vchat.db -vchat.db* -*.log -*.int -*.rsc -*.dmb -*.lk -*.backup -*.before -*.pyc -*.pid -data -data/ -cfg/ - -#Visual studio stuff -*.vscode/* -!/.vscode/launch.json -!/.vscode/extensions.json -!/.vscode/settings.json -!/.vscode/tasks.json - -code/game/gamemodes/technomancer/spells/projectile/overload.dm -code/game/gamemodes/technomancer/spells/projectile/overload.dm -code/modules/client/preference_setup/loadout/loadout_xeno.dm -temp.dmi +#ignore misc BYOND files +Thumbs.db +vchat.db +vchat.db* +*.log +*.int +*.rsc +*.dmb +*.lk +*.backup +*.before +*.pyc +*.pid +data +data/ +cfg/ + +#Visual studio stuff +*.vscode/* +!/.vscode/launch.json +!/.vscode/extensions.json +!/.vscode/settings.json +!/.vscode/tasks.json + +temp.dmi + +node_modules/ +package-lock.json diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000000..2b7500b2316 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +# We don't want prettier to run on anything outside of the TGUI folder, so we have to do this. +/* + +# We want it to run into the TGUI folder, however. +!/tgui diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 19a0ceb7dec..4b96db2f5a0 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -9,6 +9,7 @@ "dbaeumer.vscode-eslint", "editorconfig.editorconfig", "donkie.vscode-tgstation-test-adapter", - "icrawl.discord-vscode" + "icrawl.discord-vscode", + "esbenp.prettier-vscode" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 64cfc2bb26d..8e110ef9bd9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,7 @@ { "eslint.nodePath": "./tgui/.yarn/sdks", - "eslint.workingDirectories": [ - "./tgui" - ], + "eslint.workingDirectories": ["./tgui"], + "prettier.prettierPath": "./tgui/.yarn/sdks/prettier/index.js", "typescript.tsdk": "./tgui/.yarn/sdks/typescript/lib", "typescript.enablePromptUseWorkspaceTsdk": true, "search.exclude": { @@ -13,24 +12,63 @@ "*.dmi": "imagePreview.previewEditor" }, "files.eol": "\n", + "files.encoding": "utf8", + "files.insertFinalNewline": true, + "files.trimFinalNewlines": true, + "files.trimTrailingWhitespace": true, + "files.associations": { + "*.{dme,dmf,dmm,dm}": "dm", + }, "gitlens.advanced.blame.customArguments": [ - "-w" + "-w", "--ignore-revs-file", ".git-blame-ignore-revs" ], "tgstationTestExplorer.project.resultsType": "json", + "[dm]": { + "files.eol": "\r\n", + "editor.detectIndentation": false, + "editor.insertSpaces": false + }, + "[markdown]": { + "files.trimTrailingWhitespace": false + }, + "[python]": { + "editor.detectIndentation": false, + "editor.insertSpaces": true, + "editor.tabSize": 4 + }, + "[yaml]": { + "editor.detectIndentation": false, + "editor.insertSpaces": true, + "editor.tabSize": 2 + }, "[javascript]": { - "editor.rulers": [ - 120 - ] + "editor.rulers": [120], + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "[javascriptreact]": { + "editor.rulers": [120], + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true }, "[typescript]": { - "editor.rulers": [ - 120 - ] + "editor.rulers": [120], + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "[typescriptreact]": { + "editor.rulers": [120], + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true }, "[scss]": { - "editor.rulers": [ - 120 - ] + "editor.rulers": [120], + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true }, + "debug.onTaskErrors": "abort", + "dreammaker.objectTreePane": true, + "dreammaker.autoUpdate": true, + "dreammaker.tickOnCreate": true, "tgstationTestExplorer.project.DMEName": "tgmc.dme" -} \ No newline at end of file +} diff --git a/_build_dependencies.sh b/_build_dependencies.sh index 8e582bab3de..164aa71c489 100644 --- a/_build_dependencies.sh +++ b/_build_dependencies.sh @@ -2,10 +2,10 @@ # For dreamchecker export SPACEMAN_DMM_VERSION=suite-1.7 # For NanoUI + TGUI -export NODE_VERSION=12 +export NODE_VERSION=16 # Byond Major export BYOND_MAJOR=514 # Byond Minor -export BYOND_MINOR=1569 +export BYOND_MINOR=1585 # Macro Count -export MACRO_COUNT=4 \ No newline at end of file +export MACRO_COUNT=4 diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 54093251d48..02887e8219c 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -257,7 +257,7 @@ if("max") target_pressure = max_pressure_setting if("set") - var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure Control",src.target_pressure) as num + var/new_pressure = tgui_input_number(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure Control",src.target_pressure,max_pressure_setting,0) src.target_pressure = between(0, new_pressure, max_pressure_setting) if("set_flow_rate") @@ -268,7 +268,7 @@ if("max") set_flow_rate = air1.volume if("set") - var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[air1.volume]L/s)","Flow Rate Control",src.set_flow_rate) as num + var/new_flow_rate = tgui_input_number(usr,"Enter new flow rate limit (0-[air1.volume]L/s)","Flow Rate Control",src.set_flow_rate,air1.volume,0) src.set_flow_rate = between(0, new_flow_rate, air1.volume) update_icon() diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 8d2b4662b3a..188f816dce5 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -222,7 +222,7 @@ Thus, the two variables affect pump operation are set in New(): if("max") target_pressure = max_pressure_setting if("set") - var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure control",src.target_pressure) as num + var/new_pressure = tgui_input_number(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure control",src.target_pressure,max_pressure_setting,0) src.target_pressure = between(0, new_pressure, max_pressure_setting) . = TRUE diff --git a/code/ATMOSPHERICS/components/omni_devices/filter.dm b/code/ATMOSPHERICS/components/omni_devices/filter.dm index 4310b167052..74f77dabdec 100644 --- a/code/ATMOSPHERICS/components/omni_devices/filter.dm +++ b/code/ATMOSPHERICS/components/omni_devices/filter.dm @@ -170,7 +170,7 @@ if("set_flow_rate") if(!configuring || use_power) return - var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num + var/new_flow_rate = tgui_input_number(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate,max_flow_rate,0) set_flow_rate = between(0, new_flow_rate, max_flow_rate) . = TRUE if("switch_mode") diff --git a/code/ATMOSPHERICS/components/omni_devices/mixer.dm b/code/ATMOSPHERICS/components/omni_devices/mixer.dm index 7f422df44aa..3dfb13436c1 100644 --- a/code/ATMOSPHERICS/components/omni_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/omni_devices/mixer.dm @@ -183,7 +183,7 @@ . = TRUE if(!configuring || use_power) return - var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num + var/new_flow_rate = tgui_input_number(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate,max_flow_rate,0) set_flow_rate = between(0, new_flow_rate, max_flow_rate) if("switch_mode") . = TRUE @@ -265,7 +265,7 @@ if(non_locked < 1) return - var/new_con = (input(usr,"Enter a new concentration (0-[round(remain_con * 100, 0.5)])%","Concentration control", min(remain_con, old_con)*100) as num) / 100 + var/new_con = (tgui_input_number(usr,"Enter a new concentration (0-[round(remain_con * 100, 0.5)])%","Concentration control", min(remain_con, old_con)*100, round(remain_con * 100, 0.5), 0)) / 100 //cap it between 0 and the max remaining concentration new_con = between(0, new_con, remain_con) diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index 129afcbad9a..c50ff795fff 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -20,7 +20,7 @@ var/hibernate = 0 //Do we even process? var/scrubbing = 1 //0 = siphoning, 1 = scrubbing - var/list/scrubbing_gas = list("carbon_dioxide") + var/list/scrubbing_gas = list("carbon_dioxide", "phoron") var/panic = 0 //is this scrubber panicked? diff --git a/code/ZAS/Variable Settings.dm b/code/ZAS/Variable Settings.dm index 067fc6d1d8e..c4643632dce 100644 --- a/code/ZAS/Variable Settings.dm +++ b/code/ZAS/Variable Settings.dm @@ -147,7 +147,7 @@ var/global/vs_control/vsc = new var/newvar = vw switch(how) if("Numeric") - newvar = input(user,"Enter a number:","Settings",newvar) as num + newvar = tgui_input_number(user,"Enter a number:","Settings",newvar) if("Bit Flag") var/flag = tgui_input_list(user,"Toggle which bit?","Settings", bitflags) flag = text2num(flag) @@ -158,9 +158,9 @@ var/global/vs_control/vsc = new if("Toggle") newvar = !newvar if("Text") - newvar = input(user,"Enter a string:","Settings",newvar) as text + newvar = tgui_input_text(user,"Enter a string:","Settings",newvar) if("Long Text") - newvar = input(user,"Enter text:","Settings",newvar) as message + newvar = tgui_input_text(user,"Enter text:","Settings",newvar, multiline = TRUE) vw = newvar if(ch in plc.settings) plc.vars[ch] = vw diff --git a/code/__defines/belly_modes_vr.dm b/code/__defines/belly_modes_vr.dm index 810f0da00b3..c86e66f1c06 100644 --- a/code/__defines/belly_modes_vr.dm +++ b/code/__defines/belly_modes_vr.dm @@ -1,4 +1,5 @@ // Normal digestion modes +#define DM_DEFAULT "Default" // Not a real bellymode, used for handling on 'selective' bellymode prefs. #define DM_HOLD "Hold" #define DM_HOLD_ABSORBED "Hold Absorbed" // Not a real bellymode, used for handling different idle messages for absorbed prey. #define DM_DIGEST "Digest" @@ -10,6 +11,7 @@ #define DM_SIZE_STEAL "Size Steal" #define DM_HEAL "Heal" #define DM_EGG "Encase In Egg" +#define DM_SELECT "Selective" //Addon mode flags #define DM_FLAG_NUMBING 0x1 diff --git a/code/__defines/cooldowns.dm b/code/__defines/cooldowns.dm new file mode 100644 index 00000000000..c3855d7ab31 --- /dev/null +++ b/code/__defines/cooldowns.dm @@ -0,0 +1,15 @@ +/* + * Cooldown system based on storing world.time on a variable, plus the cooldown time. + * Better performance over timer cooldowns, lower control. Same functionality. +*/ + +#define COOLDOWN_DECLARE(cd_index) var/##cd_index = 0 + +#define COOLDOWN_START(cd_source, cd_index, cd_time) (cd_source.cd_index = world.time + (cd_time)) + +//Returns true if the cooldown has run its course, false otherwise +#define COOLDOWN_FINISHED(cd_source, cd_index) (cd_source.cd_index < world.time) + +#define COOLDOWN_RESET(cd_source, cd_index) cd_source.cd_index = 0 + +#define COOLDOWN_TIMELEFT(cd_source, cd_index) (max(0, cd_source.cd_index - world.time)) \ No newline at end of file diff --git a/code/__defines/dcs/signals.dm b/code/__defines/dcs/signals.dm index ae3773be74c..1ae4237a0d3 100644 --- a/code/__defines/dcs/signals.dm +++ b/code/__defines/dcs/signals.dm @@ -42,8 +42,10 @@ #define COMSIG_PARENT_QDELETING "parent_qdeleting" /// generic topic handler (usr, href_list) #define COMSIG_TOPIC "handle_topic" -/// from datum ui_act (usr, action) +/// from datum tgui_act (usr, action) #define COMSIG_UI_ACT "COMSIG_UI_ACT" +/// from datum tgui_fallback (payload) +#define COMSIG_UI_FALLBACK "COMSIG_UI_FALLBACK" /// fires on the target datum when an element is attached to it (/datum/element) diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index afeef6e0f2f..3edae54b476 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -170,3 +170,17 @@ if (!(DATUM.datum_flags & DF_ISPROCESSING)) {\ #define LOGIN_TYPE_NORMAL 1 #define LOGIN_TYPE_AI 2 #define LOGIN_TYPE_ROBOT 3 + +// Computer Hardware +#define PART_CPU /obj/item/weapon/computer_hardware/processor_unit // CPU. Without it the computer won't run. Better CPUs can run more programs at once. +#define PART_NETWORK /obj/item/weapon/computer_hardware/network_card // Network Card component of this computer. Allows connection to NTNet +#define PART_HDD /obj/item/weapon/computer_hardware/hard_drive // Hard Drive component of this computer. Stores programs and files. + +// Optional hardware (improves functionality, but is not critical for computer to work in most cases) +#define PART_BATTERY /obj/item/weapon/computer_hardware/battery_module // An internal power source for this computer. Can be recharged. +#define PART_CARD /obj/item/weapon/computer_hardware/card_slot // ID Card slot component of this computer. Mostly for HoP modification console that needs ID slot for modification. +#define PART_PRINTER /obj/item/weapon/computer_hardware/nano_printer // Nano Printer component of this computer, for your everyday paperwork needs. +//#define PART_DRIVE /obj/item/weapon/computer_hardware/hard_drive/portable // Portable data storage +//#define PART_AI /obj/item/weapon/computer_hardware/ai_slot // AI slot, an intellicard housing that allows modifications of AIs. +#define PART_TESLA /obj/item/weapon/computer_hardware/tesla_link // Tesla Link, Allows remote charging from nearest APC. +//#define PART_SCANNER /obj/item/weapon/computer_hardware/scanner // One of several optional scanner attachments. diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 1aab1c82e47..d68fd484bf0 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -149,10 +149,25 @@ #define PROGRAM_STATE_BACKGROUND 1 #define PROGRAM_STATE_ACTIVE 2 +#define PROG_MISC "Miscellaneous" +#define PROG_ENG "Engineering" +#define PROG_OFFICE "Office Work" +#define PROG_COMMAND "Command" +#define PROG_SUPPLY "Supply and Shuttles" +#define PROG_ADMIN "NTNet Administration" +#define PROG_UTIL "Utility" +#define PROG_SEC "Security" +#define PROG_MONITOR "Monitoring" + // Caps for NTNet logging. Less than 10 would make logging useless anyway, more than 500 may make the log browser too laggy. Defaults to 100 unless user changes it. #define MAX_NTNET_LOGS 500 #define MIN_NTNET_LOGS 10 +//Built-in email accounts +#define EMAIL_DOCUMENTS "document.server@virgo.local" +#define EMAIL_SYSADMIN "admin@virgo.local" +#define EMAIL_BROADCAST "broadcast@virgo.local" + // Special return values from bullet_act(). Positive return values are already used to indicate the blocked level of the projectile. #define PROJECTILE_CONTINUE -1 //if the projectile should continue flying after calling bullet_act() diff --git a/code/__defines/misc_vr.dm b/code/__defines/misc_vr.dm index 6ed1384429c..9c5896a8066 100644 --- a/code/__defines/misc_vr.dm +++ b/code/__defines/misc_vr.dm @@ -58,6 +58,7 @@ #define PTO_CARGO "Cargo" #define PTO_CIVILIAN "Civilian" #define PTO_CYBORG "Cyborg" +#define PTO_TALON "Talon Contractor" #define DEPARTMENT_TALON "ITV Talon" diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index d9a5f7a847c..df7a90632cc 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -447,3 +447,7 @@ #define DEATHGASP_NO_MESSAGE "no message" #define RESIST_COOLDOWN 2 SECONDS + +#define VISIBLE_GENDER_FORCE_PLURAL 1 // Used by get_visible_gender to return PLURAL +#define VISIBLE_GENDER_FORCE_IDENTIFYING 2 // Used by get_visible_gender to return the mob's identifying gender +#define VISIBLE_GENDER_FORCE_BIOLOGICAL 3 // Used by get_visible_gender to return the mob's biological gender diff --git a/code/__defines/mobs_vr.dm b/code/__defines/mobs_vr.dm index be17f09c39f..51c65f532b2 100644 --- a/code/__defines/mobs_vr.dm +++ b/code/__defines/mobs_vr.dm @@ -25,6 +25,7 @@ #define SPECIES_PROTEAN "Protean" #define SPECIES_RAPALA "Rapala" #define SPECIES_SERGAL "Sergal" +#define SPECIES_ALTEVIAN "Altevian" #define SPECIES_SHADEKIN_CREW "Black-Eyed Shadekin" #define SPECIES_VASILISSAN "Vasilissan" #define SPECIES_VULPKANIN "Vulpkanin" diff --git a/code/__defines/span_vr.dm b/code/__defines/span_vr.dm index 618fd52b3d1..737d1a81ada 100644 --- a/code/__defines/span_vr.dm +++ b/code/__defines/span_vr.dm @@ -40,7 +40,7 @@ #define span_danger(str) ("" + str + "") #define span_warning(str) ("" + str + "") #define span_rose(str) ("" + str + "") -#define span_info(str) ("" + str + "" +#define span_info(str) ("" + str + "") #define span_notice(str) ("" + str + "") #define span_alium(str) ("" + str + "") #define span_cult(str) ("" + str + "") diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm index 67d6b6e7d6f..b133acc9ec6 100644 --- a/code/__defines/species_languages.dm +++ b/code/__defines/species_languages.dm @@ -86,18 +86,15 @@ #define LANGUAGE_ROOTLOCAL "Local Rootspeak" #define LANGUAGE_ROOTGLOBAL "Global Rootspeak" #define LANGUAGE_CULT "Cult" -#define LANGUAGE_OCCULT "Occult" #define LANGUAGE_CHANGELING "Changeling" #define LANGUAGE_VOX "Vox-Pidgin" #define LANGUAGE_TERMINUS "Terminus" -#define LANGUAGE_SKRELLIANFAR "High Skrellian" #define LANGUAGE_MINBUS "Minbus" #define LANGUAGE_EVENT1 "Occursus" #define LANGUAGE_AKHANI "Akhani" #define LANGUAGE_ALAI "Alai" #define LANGUAGE_ZADDAT "Vedahq" #define LANGUAGE_PROMETHEAN "Promethean Biolinguistics" -#define LANGUAGE_BLOB "Chemosense Transmission" #define LANGUAGE_GIBBERISH "Babel" // Language flags. @@ -111,6 +108,7 @@ #define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message #define NO_STUTTER 256 // No stuttering, slurring, or other speech problems #define ALT_TRANSMIT 512 // Language is not based on vision or sound (Todo: add this into the say code and use it for the rootspeak languages) +#define INAUDIBLE 1024 // Language is not audible (similar to nonverbal) but is still using hearing-based recognition #define SKIN_NORMAL 0 #define SKIN_THREAT 1 diff --git a/code/__defines/species_languages_vr.dm b/code/__defines/species_languages_vr.dm index 32457d95679..e8cf9a88b9c 100644 --- a/code/__defines/species_languages_vr.dm +++ b/code/__defines/species_languages_vr.dm @@ -1,7 +1,6 @@ #define SPECIES_WHITELIST_SELECTABLE 0x20 // Can select and customize, but not join as #define LANGUAGE_DRUDAKAR "D'Rudak'Ar" -#define LANGUAGE_SLAVIC "Pan-Slavic" #define LANGUAGE_BIRDSONG "Birdsong" #define LANGUAGE_SAGARU "Sagaru" #define LANGUAGE_CANILUNZT "Canilunzt" @@ -10,12 +9,9 @@ #define LANGUAGE_ENOCHIAN "Enochian" #define LANGUAGE_VESPINAE "Vespinae" #define LANGUAGE_SPACER "Spacer" -#define LANGUAGE_CLOWNISH "Coulrian" #define LANGUAGE_TAVAN "Tavan" +#define LANGUAGE_ECHOSONG "Echo Song" -#define LANGUAGE_CHIMPANZEE "Chimpanzee" -#define LANGUAGE_NEAERA "Neaera" -#define LANGUAGE_STOK "Stok" -#define LANGUAGE_FARWA "Farwa" +#define LANGUAGE_ANIMAL "Animal" #define LANGUAGE_SHADEKIN "Shadekin Empathy" diff --git a/code/__defines/sprite_sheets.dm b/code/__defines/sprite_sheets.dm index 603bb82d5f0..2194efca239 100644 --- a/code/__defines/sprite_sheets.dm +++ b/code/__defines/sprite_sheets.dm @@ -11,7 +11,8 @@ SPECIES_SERGAL = 'icons/inventory/suit/mob_vr_sergal.dmi',\ SPECIES_NEVREAN = 'icons/inventory/suit/mob_vr_sergal.dmi',\ SPECIES_VULPKANIN = 'icons/inventory/suit/mob_vr_vulpkanin.dmi',\ SPECIES_ZORREN_HIGH = 'icons/inventory/suit/mob_vr_vulpkanin.dmi',\ -SPECIES_FENNEC = 'icons/inventory/suit/mob_vr_vulpkanin.dmi') +SPECIES_FENNEC = 'icons/inventory/suit/mob_vr_vulpkanin.dmi',\ +SPECIES_ALTEVIAN = 'icons/inventory/suit/mob_vr_altevian.dmi') #define VR_SPECIES_SPRITE_SHEETS_HEAD_MOB list(\ SPECIES_HUMAN = 'icons/inventory/head/mob.dmi',\ SPECIES_TAJ = 'icons/inventory/head/mob_tajaran.dmi',\ @@ -24,7 +25,8 @@ SPECIES_SERGAL = 'icons/inventory/head/mob_vr_sergal.dmi',\ SPECIES_NEVREAN = 'icons/inventory/head/mob_vr_sergal.dmi',\ SPECIES_VULPKANIN = 'icons/inventory/head/mob_vr_vulpkanin.dmi',\ SPECIES_ZORREN_HIGH = 'icons/inventory/head/mob_vr_vulpkanin.dmi',\ -SPECIES_FENNEC = 'icons/inventory/head/mob_vr_vulpkanin.dmi') +SPECIES_FENNEC = 'icons/inventory/head/mob_vr_vulpkanin.dmi',\ +SPECIES_ALTEVIAN = 'icons/inventory/head/mob_vr_altevian.dmi') #define VR_SPECIES_SPRITE_SHEETS_HANDS_MOB list(\ SPECIES_HUMAN = 'icons/inventory/hands/mob.dmi',\ SPECIES_TAJ = 'icons/inventory/hands/mob_tajaran.dmi',\ @@ -64,7 +66,8 @@ SPECIES_SERGAL = 'icons/inventory/suit/item_vr_sergal.dmi',\ SPECIES_NEVREAN = 'icons/inventory/suit/item_vr_sergal.dmi',\ SPECIES_VULPKANIN = 'icons/inventory/suit/item_vr_vulpkanin.dmi',\ SPECIES_ZORREN_HIGH = 'icons/inventory/suit/item_vr_vulpkanin.dmi',\ -SPECIES_FENNEC = 'icons/inventory/suit/item_vr_vulpkanin.dmi') +SPECIES_FENNEC = 'icons/inventory/suit/item_vr_vulpkanin.dmi',\ +SPECIES_ALTEVIAN = 'icons/inventory/suit/item_vr_altevian.dmi') #define VR_SPECIES_SPRITE_SHEETS_HEAD_ITEM list(\ SPECIES_HUMAN = 'icons/inventory/head/item.dmi',\ SPECIES_TAJ = 'icons/inventory/head/item_tajaran.dmi',\ @@ -77,7 +80,8 @@ SPECIES_SERGAL = 'icons/inventory/head/item_vr_sergal.dmi',\ SPECIES_NEVREAN = 'icons/inventory/head/item_vr_sergal.dmi',\ SPECIES_VULPKANIN = 'icons/inventory/head/item_vr_vulpkanin.dmi',\ SPECIES_ZORREN_HIGH = 'icons/inventory/head/item_vr_vulpkanin.dmi',\ -SPECIES_FENNEC = 'icons/inventory/head/item_vr_vulpkanin.dmi') +SPECIES_FENNEC = 'icons/inventory/head/item_vr_vulpkanin.dmi',\ +SPECIES_ALTEVIAN = 'icons/inventory/head/item_vr_altevian.dmi') #define VR_SPECIES_SPRITE_SHEETS_HANDS_ITEM list(\ SPECIES_HUMAN = 'icons/inventory/hands/item.dmi',\ SPECIES_TAJ = 'icons/inventory/hands/item_tajaran.dmi',\ @@ -118,7 +122,8 @@ SPECIES_SERGAL = 'icons/inventory/suit/mob_vr_sergal.dmi',\ SPECIES_NEVREAN = 'icons/inventory/suit/mob_vr_sergal.dmi',\ SPECIES_VULPKANIN = 'icons/inventory/suit/mob_vr_vulpkanin.dmi',\ SPECIES_ZORREN_HIGH = 'icons/inventory/suit/mob_vr_vulpkanin.dmi',\ -SPECIES_FENNEC = 'icons/inventory/suit/mob_vr_vulpkanin.dmi') +SPECIES_FENNEC = 'icons/inventory/suit/mob_vr_vulpkanin.dmi',\ +SPECIES_ALTEVIAN = 'icons/inventory/suit/mob_vr_altevian.dmi') #define ALL_VR_SPRITE_SHEETS_HEAD_MOB list(\ SPECIES_HUMAN = 'icons/inventory/head/mob_vr.dmi',\ SPECIES_TAJ = 'icons/inventory/head/mob_vr_tajaran.dmi',\ @@ -131,7 +136,8 @@ SPECIES_SERGAL = 'icons/inventory/head/mob_vr_sergal.dmi',\ SPECIES_NEVREAN = 'icons/inventory/head/mob_vr_sergal.dmi',\ SPECIES_VULPKANIN = 'icons/inventory/head/mob_vr_vulpkanin.dmi',\ SPECIES_ZORREN_HIGH = 'icons/inventory/head/mob_vr_vulpkanin.dmi',\ -SPECIES_FENNEC = 'icons/inventory/head/mob_vr_vulpkanin.dmi') +SPECIES_FENNEC = 'icons/inventory/head/mob_vr_vulpkanin.dmi',\ +SPECIES_ALTEVIAN = 'icons/inventory/head/mob_vr_altevian.dmi') #define ALL_VR_SPRITE_SHEETS_HANDS_MOB list(\ SPECIES_HUMAN = 'icons/inventory/hands/mob_vr.dmi',\ SPECIES_TAJ = 'icons/inventory/hands/mob_vr_tajaran.dmi',\ @@ -171,7 +177,8 @@ SPECIES_SERGAL = 'icons/inventory/suit/item_vr_sergal.dmi',\ SPECIES_NEVREAN = 'icons/inventory/suit/item_vr_sergal.dmi',\ SPECIES_VULPKANIN = 'icons/inventory/suit/item_vr_vulpkanin.dmi',\ SPECIES_ZORREN_HIGH = 'icons/inventory/suit/item_vr_vulpkanin.dmi',\ -SPECIES_FENNEC = 'icons/inventory/suit/item_vr_vulpkanin.dmi') +SPECIES_FENNEC = 'icons/inventory/suit/item_vr_vulpkanin.dmi',\ +SPECIES_ALTEVIAN = 'icons/inventory/suit/item_vr_altevian.dmi') #define ALL_VR_SPRITE_SHEETS_HEAD_ITEM list(\ SPECIES_HUMAN = 'icons/inventory/head/item_vr.dmi',\ SPECIES_TAJ = 'icons/inventory/head/item_vr_tajaran.dmi',\ @@ -184,7 +191,8 @@ SPECIES_SERGAL = 'icons/inventory/head/item_vr_sergal.dmi',\ SPECIES_NEVREAN = 'icons/inventory/head/item_vr_sergal.dmi',\ SPECIES_VULPKANIN = 'icons/inventory/head/item_vr_vulpkanin.dmi',\ SPECIES_ZORREN_HIGH = 'icons/inventory/head/item_vr_vulpkanin.dmi',\ -SPECIES_FENNEC = 'icons/inventory/head/item_vr_vulpkanin.dmi') +SPECIES_FENNEC = 'icons/inventory/head/item_vr_vulpkanin.dmi',\ +SPECIES_ALTEVIAN = 'icons/inventory/head/item_vr_altevian.dmi') #define ALL_VR_SPRITE_SHEETS_HANDS_ITEM list(\ SPECIES_HUMAN = 'icons/inventory/hands/item_vr.dmi',\ SPECIES_TAJ = 'icons/inventory/hands/item_vr_tajaran.dmi',\ diff --git a/code/__defines/tgui.dm b/code/__defines/tgui.dm index c261e5ecdcf..1215382ce78 100644 --- a/code/__defines/tgui.dm +++ b/code/__defines/tgui.dm @@ -5,6 +5,8 @@ /// Maximum ping timeout allowed to detect zombie windows #define TGUI_PING_TIMEOUT 4 SECONDS +/// Used for rate-limiting to prevent DoS by excessively refreshing a TGUI window +#define TGUI_REFRESH_FULL_UPDATE_COOLDOWN 5 SECONDS /// Window does not exist #define TGUI_WINDOW_CLOSED 0 diff --git a/code/_global_vars/mobs.dm b/code/_global_vars/mobs.dm index 7e60dc71ea2..9e1027bc888 100644 --- a/code/_global_vars/mobs.dm +++ b/code/_global_vars/mobs.dm @@ -1,5 +1,7 @@ GLOBAL_LIST_EMPTY(admins) //all clients whom are admins GLOBAL_PROTECT(admins) +GLOBAL_LIST_EMPTY(mentors) +GLOBAL_PROTECT(mentors) GLOBAL_LIST_EMPTY(deadmins) //all ckeys who have used the de-admin verb. GLOBAL_LIST_EMPTY(stealthminID) GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client diff --git a/code/_global_vars/religion.dm b/code/_global_vars/religion.dm deleted file mode 100644 index 7dab008b193..00000000000 --- a/code/_global_vars/religion.dm +++ /dev/null @@ -1,8 +0,0 @@ -// All religion stuff -GLOBAL_VAR(religion) -GLOBAL_VAR(deity) - -//bible -GLOBAL_VAR(bible_name) -GLOBAL_VAR(bible_icon_state) -GLOBAL_VAR(bible_item_state) diff --git a/code/_helpers/_lists.dm b/code/_helpers/_lists.dm index c359227f057..5631fa88079 100644 --- a/code/_helpers/_lists.dm +++ b/code/_helpers/_lists.dm @@ -53,7 +53,7 @@ // atoms/items/objects can be pretty and whatnot var/atom/A = item if(output_icons && isicon(A.icon) && !ismob(A)) // mobs tend to have unusable icons - item_str += "[bicon(A)] " + item_str += "\icon[A][bicon(A)] " switch(determiners) if(DET_NONE) item_str += A.name if(DET_DEFINITE) item_str += "\the [A]" @@ -217,6 +217,17 @@ This actually tests if they have the same entries and values. return 0 return 1 +/* +Checks if a list has the same entries and values as an element of big. +*/ +/proc/in_as_list(var/list/little, var/list/big) + if(!islist(big)) + return 0 + for(var/element in big) + if(same_entries(little, element)) + return 1 + return 0 + /* * Returns list containing entries that are in either list but not both. * If skipref = 1, repeated elements are treated as one. @@ -870,4 +881,3 @@ var/global/list/json_cache = list() else used_key_list[input_key] = 1 return input_key - \ No newline at end of file diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm index 76b1b0d4d84..d7d180d4dfa 100644 --- a/code/_helpers/global_lists_vr.dm +++ b/code/_helpers/global_lists_vr.dm @@ -5,8 +5,10 @@ var/global/list/hair_accesories_list= list()// Stores /datum/sprite_accessory/hair_accessory indexed by type var/global/list/negative_traits = list() // Negative custom species traits, indexed by path var/global/list/neutral_traits = list() // Neutral custom species traits, indexed by path -var/global/list/everyone_traits = list() // Neutral traits available to all species, indexed by path var/global/list/positive_traits = list() // Positive custom species traits, indexed by path +var/global/list/everyone_traits_positive = list() // Neutral traits available to all species, indexed by path +var/global/list/everyone_traits_neutral = list() // Neutral traits available to all species, indexed by path +var/global/list/everyone_traits_negative = list() // Neutral traits available to all species, indexed by path var/global/list/traits_costs = list() // Just path = cost list, saves time in char setup var/global/list/all_traits = list() // All of 'em at once (same instances) var/global/list/active_ghost_pods = list() @@ -63,6 +65,7 @@ var/global/list/classic_vore_sounds = list( "Rustle 3 (cloth)" = 'sound/effects/rustle3.ogg', "Rustle 4 (cloth)" = 'sound/effects/rustle4.ogg', "Rustle 5 (cloth)" = 'sound/effects/rustle5.ogg', + "Zipper" = 'sound/items/zip.ogg', "None" = null) var/global/list/classic_release_sounds = list( @@ -71,6 +74,7 @@ var/global/list/classic_release_sounds = list( "Rustle 3 (cloth)" = 'sound/effects/rustle3.ogg', "Rustle 4 (cloth)" = 'sound/effects/rustle4.ogg', "Rustle 5 (cloth)" = 'sound/effects/rustle5.ogg', + "Zipper" = 'sound/items/zip.ogg', "Splatter" = 'sound/effects/splat.ogg', "None" = null ) @@ -93,6 +97,7 @@ var/global/list/fancy_vore_sounds = list( "Rustle 3 (cloth)" = 'sound/effects/rustle3.ogg', "Rustle 4 (cloth)" = 'sound/effects/rustle4.ogg', "Rustle 5 (cloth)" = 'sound/effects/rustle5.ogg', + "Zipper" = 'sound/items/zip.ogg', "None" = null ) @@ -102,6 +107,7 @@ var/global/list/fancy_release_sounds = list( "Rustle 3 (cloth)" = 'sound/effects/rustle3.ogg', "Rustle 4 (cloth)" = 'sound/effects/rustle4.ogg', "Rustle 5 (cloth)" = 'sound/effects/rustle5.ogg', + "Zipper" = 'sound/items/zip.ogg', "Stomach Move" = 'sound/vore/sunesound/pred/stomachmove.ogg', "Pred Escape" = 'sound/vore/sunesound/pred/escape.ogg', "Splatter" = 'sound/effects/splat.ogg', @@ -230,7 +236,8 @@ var/global/list/edible_trash = list(/obj/item/broken_device, /obj/item/weapon/storage/wallet, /obj/item/weapon/storage/vore_egg, /obj/item/weapon/bikehorn/tinytether, - /obj/item/capture_crystal + /obj/item/capture_crystal, + /obj/item/roulette_ball ) var/global/list/contamination_flavors = list( @@ -539,12 +546,16 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN, switch(category) if(-INFINITY to -0.1) negative_traits[traitpath] = T + if(!(T.custom_only)) + everyone_traits_negative[traitpath] = T if(0) neutral_traits[traitpath] = T if(!(T.custom_only)) - everyone_traits[traitpath] = T + everyone_traits_neutral[traitpath] = T if(0.1 to INFINITY) positive_traits[traitpath] = T + if(!(T.custom_only)) + everyone_traits_positive[traitpath] = T // Weaver recipe stuff diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm index 5d68dc9a8c0..5dc784d1b3d 100644 --- a/code/_helpers/logging.dm +++ b/code/_helpers/logging.dm @@ -37,7 +37,7 @@ /proc/log_debug(text) if (config.log_debug) - WRITE_LOG(debug_log, "DEBUG: [text]") + WRITE_LOG(debug_log, "DEBUG: [sanitize(text)]") for(var/client/C in GLOB.admins) if(C.is_preference_enabled(/datum/client_preference/debug/show_debug_logs)) diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 140f88886df..6cd91a852bd 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -138,9 +138,9 @@ Proc for attack log creation, because really why not /proc/get_exposed_defense_zone(var/atom/movable/target) var/obj/item/weapon/grab/G = locate() in target if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people. - return pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg") + return pick(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG) else - return pick("chest", "groin") + return pick(BP_TORSO, BP_GROIN) /proc/do_mob(mob/user , mob/target, time = 30, target_zone = 0, uninterruptible = FALSE, progress = TRUE, ignore_movement = FALSE, exclusive = FALSE) if(!user || !target) diff --git a/code/_helpers/sanitize_values.dm b/code/_helpers/sanitize_values.dm index 4b521f9bfbb..3d042002691 100644 --- a/code/_helpers/sanitize_values.dm +++ b/code/_helpers/sanitize_values.dm @@ -6,6 +6,16 @@ return number return default +// Checks if the given input is a valid list index; returns true/false and doesn't change anything. +/proc/is_valid_index(input, list/given_list) + if(!isnum(input)) + return FALSE + if(input != round(input)) + return FALSE + if(input < 1 || input > length(given_list)) + return FALSE + return TRUE + /proc/sanitize_text(text, default="") if(istext(text)) return text @@ -44,3 +54,60 @@ if(65 to 70) . += ascii2text(ascii+32) //letters A to F - translates to lowercase else return default return . + +//Valid format codes: YY, YEAR, MM, DD, hh, mm, ss, :, -. " " (space). Invalid format will return default. +/proc/sanitize_time(time, default, format = "hh:mm") + if(!istext(time) || !(length(time) == length(format))) + return default + var/fragment = "" + . = list() + for(var/i = 1, i <= length(format), i++) + fragment += copytext(format,i,i+1) + if(fragment in list("YY", "YEAR", "MM", "DD", "hh", "mm", "ss")) + . += sanitize_one_time(copytext(time, i - length(fragment) + 1, i + 1), copytext(default, i - length(fragment) + 1, i + 1), fragment) + fragment = "" + else if(fragment in list(":", "-", " ")) + . += fragment + fragment = "" + if(fragment) + return default //This means the format was improper. + return JOINTEXT(.) + +//Internal proc, expects valid format and text input of equal length to format. +/proc/sanitize_one_time(input, default, format) + var/list/ainput = list() + for(var/i = 1, i <= length(input), i++) + ainput += text2ascii(input, i) + switch(format) + if("YY") + if(!(ainput[1] in 48 to 57) || !(ainput[2] in 48 to 57))//0 to 9 + return (default || "00") + return input + if("YEAR") + for(var/i = 1, i <= 4, i++) + if(!(ainput[i] in 48 to 57))//0 to 9 + return (default || "0000") + return input + if("MM") + var/early = (ainput[1] == 48) && (ainput[2] in 49 to 57) //01 to 09 + var/late = (ainput[1] == 49) && (ainput[2] in 48 to 50) //10 to 12 + if(!(early || late)) + return (default || "01") + return input + if("DD") + var/early = (ainput[1] == 48) && (ainput[2] in 49 to 57) //01 to 09 + var/mid = (ainput[1] in 49 to 50) && (ainput[2] in 48 to 57) //10 to 29 + var/late = (ainput[1] == 51) && (ainput[2] in 48 to 49) //30 to 31 + if(!(early || mid || late)) + return (default || "01") + return input + if("hh") + var/early = (ainput[1] in 48 to 49) && (ainput[2] in 48 to 57) //00 to 19 + var/late = (ainput[1] == 50) && (ainput[2] in 48 to 51) //20 to 23 + if(!(early || late)) + return (default || "00") + return input + if("mm", "ss") + if(!(ainput[1] in 48 to 53) || !(ainput[2] in 48 to 57)) //0 to 5, 0 to 9 + return (default || "00") + return input diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm index bfa7256c9fd..daf02d38a26 100644 --- a/code/_helpers/text.dm +++ b/code/_helpers/text.dm @@ -343,8 +343,15 @@ if(!text_tag_cache[tagname]) var/icon/tag = icon(text_tag_icons, tagname) text_tag_cache[tagname] = bicon(tag, TRUE, "text_tag") + if(C.chatOutput.broken) + return "[tagdesc]" return text_tag_cache[tagname] +/proc/create_text_tag_old(var/tagname, var/tagdesc = tagname, var/client/C = null) + if(!(C && C.is_preference_enabled(/datum/client_preference/chat_tags))) + return tagdesc + return "[tagdesc]" + /proc/contains_az09(var/input) for(var/i=1, i<=length(input), i++) var/ascii_char = text2ascii(input,i) @@ -408,6 +415,58 @@ t = replacetext(t, "\[editorbr\]", "") return t +//pencode translation to html for tags exclusive to digital files (currently email, nanoword, report editor fields, +//modular scanner data and txt file printing) and prints from them +/proc/digitalPencode2html(var/text) + text = replacetext(text, "\[pre\]", "
")
+	text = replacetext(text, "\[/pre\]", "
") + text = replacetext(text, "\[fontred\]", "") // to pass html tag integrity unit test + text = replacetext(text, "\[fontblue\]", "")// to pass html tag integrity unit test + text = replacetext(text, "\[fontgreen\]", "") + text = replacetext(text, "\[/font\]", "") + text = replacetext(text, "\[redacted\]", "R E D A C T E D") + return pencode2html(text) + +//Will kill most formatting; not recommended. +/proc/html2pencode(t) + t = replacetext(t, "
", "\[pre\]")
+	t = replacetext(t, "
", "\[/pre\]") + t = replacetext(t, "", "\[fontred\]")// to pass html tag integrity unit test + t = replacetext(t, "", "\[fontblue\]")// to pass html tag integrity unit test + t = replacetext(t, "", "\[fontgreen\]") + t = replacetext(t, "", "\[/font\]") + t = replacetext(t, "
", "\[br\]") + t = replacetext(t, "
", "\[br\]") + t = replacetext(t, "", "\[b\]") + t = replacetext(t, "", "\[/b\]") + t = replacetext(t, "", "\[i\]") + t = replacetext(t, "", "\[/i\]") + t = replacetext(t, "", "\[u\]") + t = replacetext(t, "", "\[/u\]") + t = replacetext(t, "
", "\[center\]") + t = replacetext(t, "
", "\[/center\]") + t = replacetext(t, "

", "\[h1\]") + t = replacetext(t, "

", "\[/h1\]") + t = replacetext(t, "

", "\[h2\]") + t = replacetext(t, "

", "\[/h2\]") + t = replacetext(t, "

", "\[h3\]") + t = replacetext(t, "

", "\[/h3\]") + t = replacetext(t, "
  • ", "\[*\]") + t = replacetext(t, "
    ", "\[hr\]") + t = replacetext(t, "", "\[/list\]") + t = replacetext(t, "", "\[grid\]") + t = replacetext(t, "
    ", "\[/grid\]") + t = replacetext(t, "", "\[row\]") + t = replacetext(t, "", "\[cell\]") + t = replacetext(t, "", "\[logo\]") + t = replacetext(t, "", "\[redlogo\]") + t = replacetext(t, "", "\[sglogo\]") + t = replacetext(t, "", "\[field\]") + t = replacetext(t, "R E D A C T E D", "\[redacted\]") + t = strip_html_properly(t) + return t + // Random password generator /proc/GenerateKey() //Feel free to move to Helpers. @@ -476,23 +535,43 @@ #define gender2text(gender) capitalize(gender) -/// Used to get a properly sanitized input, of max_length -/// no_trim is self explanatory but it prevents the input from being trimed if you intend to parse newlines or whitespace. +/** + * Used to get a properly sanitized input. Returns null if cancel is pressed. + * + * Arguments + ** user - Target of the input prompt. + ** message - The text inside of the prompt. + ** title - The window title of the prompt. + ** max_length - If you intend to impose a length limit - default is 1024. + ** no_trim - Prevents the input from being trimmed if you intend to parse newlines or whitespace. +*/ /proc/stripped_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) - var/name = input(user, message, title, default) as text|null - + var/user_input = input(user, message, title, default) as text|null + if(isnull(user_input)) // User pressed cancel + return if(no_trim) - return copytext(html_encode(name), 1, max_length) + return copytext(html_encode(user_input), 1, max_length) else - return trim(html_encode(name), max_length) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into <) + return trim(html_encode(user_input), max_length) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into <) -// Used to get a properly sanitized multiline input, of max_length +/** + * Used to get a properly sanitized input in a larger box. Works very similarly to stripped_input. + * + * Arguments + ** user - Target of the input prompt. + ** message - The text inside of the prompt. + ** title - The window title of the prompt. + ** max_length - If you intend to impose a length limit - default is 1024. + ** no_trim - Prevents the input from being trimmed if you intend to parse newlines or whitespace. +*/ /proc/stripped_multiline_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) - var/name = input(user, message, title, default) as message|null + var/user_input = input(user, message, title, default) as message|null + if(isnull(user_input)) // User pressed cancel + return if(no_trim) - return copytext(html_encode(name), 1, max_length) + return copytext(html_encode(user_input), 1, max_length) else - return trim(html_encode(name), max_length) + return trim(html_encode(user_input), max_length) //Adds 'char' ahead of 'text' until there are 'count' characters total /proc/add_leading(text, count, char = " ") diff --git a/code/_helpers/turfs.dm b/code/_helpers/turfs.dm index bea5e6780c4..9de7b925ad2 100644 --- a/code/_helpers/turfs.dm +++ b/code/_helpers/turfs.dm @@ -131,7 +131,7 @@ var/old_icon1 = T.icon var/old_decals = T.decals ? T.decals.Copy() : null - B.Destroy() + //B.Destroy() X = B.ChangeTurf(T.type) X.set_dir(old_dir1) X.icon_state = old_icon_state1 diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 37da921409d..f09cb94b0e7 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -344,7 +344,8 @@ Turf and target are seperate in case you want to teleport some distance from a t var/newname for(var/i=1,i<=3,i++) //we get 3 attempts to pick a suitable name. - newname = input(src,"You are \a [role]. Would you like to change your name to something else?", "Name change",oldname) as text + //newname = tgui_input_text(src,"You are \a [role]. Would you like to change your name to something else?", "Name change",oldname) + newname = input(src,"You are \a [role]. Would you like to change your name to something else?", "Name change",oldname) if((world.time-time_passed)>3000) return //took too long newname = sanitizeName(newname, ,allow_numbers) //returns null if the name doesn't meet some basic requirements. Tidies up a few other things like bad-characters. @@ -1160,7 +1161,7 @@ var/list/WALLITEMS = list( if(length(temp_col )<2) temp_col = "0[temp_col]" colour += temp_col - return colour + return "#[colour]" /proc/color_square(red, green, blue, hex) var/color = hex ? hex : "#[num2hex(red, 2)][num2hex(green, 2)][num2hex(blue, 2)]" @@ -1361,7 +1362,7 @@ var/mob/dview/dview_mob = new /proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) if (value == FALSE) //nothing should be calling us with a number, so this is safe - value = input(usr, "Enter type to find (blank for all, cancel to cancel)", "Search for type") as null|text + value = tgui_input_text(usr, "Enter type to find (blank for all, cancel to cancel)", "Search for type") if (isnull(value)) return value = trim(value) @@ -1493,7 +1494,7 @@ GLOBAL_REAL_VAR(list/stack_trace_storage) . += new /obj/screen/plane_master/lighting //Lighting system (but different!) . += new /obj/screen/plane_master/o_light_visual //Object lighting (using masks) . += new /obj/screen/plane_master/emissive //Emissive overlays - + . += new /obj/screen/plane_master/ghosts //Ghosts! . += new /obj/screen/plane_master{plane = PLANE_AI_EYE} //AI Eye! diff --git a/code/_helpers/unsorted_vr.dm b/code/_helpers/unsorted_vr.dm index daf4db48d78..0890c1f9c63 100644 --- a/code/_helpers/unsorted_vr.dm +++ b/code/_helpers/unsorted_vr.dm @@ -18,7 +18,8 @@ continue if(vent.welded) continue - if(istype(get_area(vent), /area/crew_quarters/sleep)) //No going to dorms + var/area/A = get_area(vent) + if(A.forbid_events) continue vent_list += vent if(!vent_list.len) diff --git a/code/_macros.dm b/code/_macros.dm index d122d9045f0..737b317abe0 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -42,4 +42,6 @@ #define WORLD_ICON_SIZE 32 //Needed for the R-UST port -#define PIXEL_MULTIPLIER WORLD_ICON_SIZE/32 //Needed for the R-UST port \ No newline at end of file +#define PIXEL_MULTIPLIER WORLD_ICON_SIZE/32 //Needed for the R-UST port + +#define JOINTEXT(X) jointext(X, null) diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 14feaf1b5f8..f1a7f222484 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -47,6 +47,7 @@ #define ui_construct_purge "EAST:00,CENTER-1:15" #define ui_construct_fire "EAST-1:16,CENTER+1:13" //above health, slightly to the left #define ui_construct_pull "EAST-1:28,SOUTH+1:10" //above the zone_sel icon +#define ui_pai_comms "EAST-1:28,SOUTH+1:5" //Lower right, persistant menu #define ui_dropbutton "EAST-4:22,SOUTH:5" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 62987479014..642ec99c73a 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -192,7 +192,7 @@ var/list/global_huds = list( var/icon/ui_style var/ui_color var/ui_alpha - + // TGMC Ammo HUD Port var/list/obj/screen/ammo_hud_list = list() @@ -368,6 +368,9 @@ var/list/global_huds = list( toggle_hud_vis(full) /mob/proc/toggle_hud_vis(full) + if(!client) + return FALSE + if(hud_used.hud_shown) hud_used.hud_shown = 0 if(hud_used.adding) @@ -405,7 +408,8 @@ var/list/global_huds = list( return TRUE /mob/living/carbon/human/toggle_hud_vis(full) - ..() + if(!(. = ..())) + return FALSE // Prevents humans from hiding a few hud elements if(!hud_used.hud_shown) // transitioning to hidden @@ -466,7 +470,7 @@ var/list/global_huds = list( /mob/new_player/add_click_catcher() return - + /* TGMC Ammo HUD Port * These procs call to screen_objects.dm's respective procs. * All these do is manage the amount of huds on screen and set the HUD. diff --git a/code/_onclick/hud/movable_screen_objects.dm b/code/_onclick/hud/movable_screen_objects.dm index 40e5977c83e..39d36738aa0 100644 --- a/code/_onclick/hud/movable_screen_objects.dm +++ b/code/_onclick/hud/movable_screen_objects.dm @@ -114,7 +114,7 @@ M.maptext = "Movable" M.maptext_width = 64 - var/screen_l = input(usr,"Where on the screen? (Formatted as 'X,Y' e.g: '1,1' for bottom left)","Spawn Movable UI Object") as text + var/screen_l = tgui_input_text(usr,"Where on the screen? (Formatted as 'X,Y' e.g: '1,1' for bottom left)","Spawn Movable UI Object") if(!screen_l) return @@ -133,7 +133,7 @@ S.maptext = "Snap" S.maptext_width = 64 - var/screen_l = input(usr,"Where on the screen? (Formatted as 'X,Y' e.g: '1,1' for bottom left)","Spawn Snap UI Object") as text + var/screen_l = tgui_input_text(usr,"Where on the screen? (Formatted as 'X,Y' e.g: '1,1' for bottom left)","Spawn Snap UI Object") if(!screen_l) return diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index c1a4795001e..c9c15433d43 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -19,7 +19,7 @@ /obj/screen/Destroy() master = null return ..() - + /obj/screen/proc/component_click(obj/screen/component_button/component, params) return @@ -46,9 +46,8 @@ object_overlays.Cut() /obj/screen/inventory/proc/add_overlays() - var/mob/user = hud.mymob - - if(hud && user && slot_id) + if(hud && hud.mymob && slot_id) + var/mob/user = hud.mymob var/obj/item/holding = user.get_active_hand() if(!holding || user.get_equipped_item(slot_id)) @@ -422,16 +421,28 @@ usr.a_intent_change("right") if(I_HELP) usr.a_intent = I_HELP - usr.hud_used.action_intent.icon_state = "intent_help" + if(ispAI(usr)) + usr.a_intent_change(I_HELP) + else + usr.hud_used.action_intent.icon_state = "intent_help" if(I_HURT) usr.a_intent = I_HURT - usr.hud_used.action_intent.icon_state = "intent_harm" + if(ispAI(usr)) + usr.a_intent_change(I_HURT) + else + usr.hud_used.action_intent.icon_state = "intent_harm" if(I_GRAB) usr.a_intent = I_GRAB - usr.hud_used.action_intent.icon_state = "intent_grab" + if(ispAI(usr)) + usr.a_intent_change(I_GRAB) + else + usr.hud_used.action_intent.icon_state = "intent_grab" if(I_DISARM) usr.a_intent = I_DISARM - usr.hud_used.action_intent.icon_state = "intent_disarm" + if(ispAI(usr)) + usr.a_intent_change(I_DISARM) + else + usr.hud_used.action_intent.icon_state = "intent_disarm" if("pull") usr.stop_pulling() @@ -607,7 +618,7 @@ var/mob/living/carbon/C = hud.mymob if(C.handcuffed) add_overlay(handcuff_overlay) - + // PIP stuff /obj/screen/component_button var/obj/screen/parent @@ -622,7 +633,7 @@ // Character setup stuff /obj/screen/setup_preview - + var/datum/preferences/pref /obj/screen/setup_preview/Destroy() @@ -693,7 +704,7 @@ INITIALIZE_IMMEDIATE(/obj/screen/splash) * size of the screen. This is not ideal, as filter() is faster, and has * alpha masks, but the alpha masks it has can't be animated, so the 'ping' * mode of this device isn't possible using that technique. - * + * * The markers use that technique, though, so at least there's that. */ /obj/screen/movable/mapper_holder @@ -711,7 +722,7 @@ INITIALIZE_IMMEDIATE(/obj/screen/splash) var/obj/screen/mapper/mask_full/mask_full var/obj/screen/mapper/mask_ping/mask_ping var/obj/screen/mapper/bg/bg - + var/obj/screen/mapper/frame/frame var/obj/screen/mapper/powbutton/powbutton var/obj/screen/mapper/mapbutton/mapbutton @@ -724,7 +735,7 @@ INITIALIZE_IMMEDIATE(/obj/screen/splash) . = ..() owner = newowner - + mask_full = new(src) // Full white square mask mask_ping = new(src) // Animated 'pinging' mask bg = new(src) // Background color, holds map in vis_contents, uses mult against masks @@ -732,19 +743,19 @@ INITIALIZE_IMMEDIATE(/obj/screen/splash) frame = new(src) // Decorative frame powbutton = new(src) // Clickable button mapbutton = new(src) // Clickable button - + frame.icon_state = initial(frame.icon_state)+owner.hud_frame_hint /** * The vis_contents layout is: this(frame,extras_holder,mask(bg(map))) * bg is set to BLEND_MULTIPLY against the mask to crop it. */ - + mask_full.vis_contents.Add(bg) mask_ping.vis_contents.Add(bg) frame.vis_contents.Add(powbutton,mapbutton) vis_contents.Add(frame) - + /obj/screen/movable/mapper_holder/Destroy() qdel_null(mask_full) @@ -764,12 +775,12 @@ INITIALIZE_IMMEDIATE(/obj/screen/splash) running = TRUE if(ping) vis_contents.Add(mask_ping) - else + else vis_contents.Add(mask_full) bg.vis_contents.Cut() bg.vis_contents.Add(map) - + if(extras && !extras_holder) extras_holder = extras vis_contents += extras_holder @@ -782,7 +793,7 @@ INITIALIZE_IMMEDIATE(/obj/screen/splash) off() else on() - + /obj/screen/movable/mapper_holder/proc/mapClick() if(owner) if(running) @@ -913,10 +924,10 @@ INITIALIZE_IMMEDIATE(/obj/screen/splash) var/static/list/ammo_screen_loc_list = list(ui_ammo_hud1, ui_ammo_hud2, ui_ammo_hud3 ,ui_ammo_hud4) /obj/screen/ammo/proc/add_hud(var/mob/living/user, var/obj/item/weapon/gun/G) - + if(!user?.client) return - + if(!G) CRASH("/obj/screen/ammo/proc/add_hud() has been called from [src] without the required param of G") diff --git a/code/controllers/communications.dm b/code/controllers/communications.dm index 3839853567b..acfa32d52f7 100644 --- a/code/controllers/communications.dm +++ b/code/controllers/communications.dm @@ -126,6 +126,7 @@ var/const/MED_I_FREQ = 1485 var/const/SEC_I_FREQ = 1475 var/const/TALON_FREQ = 1363 //VOREStation Add +var/const/CSN_FREQ = 1365 //VOREStation Add var/list/radiochannels = list( "Common" = PUB_FREQ, @@ -145,7 +146,8 @@ var/list/radiochannels = list( "Entertainment" = ENT_FREQ, "Medical(I)" = MED_I_FREQ, "Security(I)" = SEC_I_FREQ, - "Talon" = TALON_FREQ //VOREStation Add + "Talon" = TALON_FREQ, //VOREStation Add + "Casino" = CSN_FREQ, ) // Hey, if anyone ever needs to update tgui/packages/tgui/constants.js with new radio channels @@ -155,7 +157,7 @@ var/list/radiochannels = list( set category = "Generate TGUI Radio Constants" var/list/channel_info = list() - + for(var/i in RADIO_LOW_FREQ to RADIO_HIGH_FREQ) for(var/key in radiochannels) if(i == radiochannels[key]) @@ -192,7 +194,7 @@ var/list/ANTAG_FREQS = list(SYND_FREQ, RAID_FREQ) //Department channels, arranged lexically var/list/DEPT_FREQS = list(AI_FREQ, COMM_FREQ, ENG_FREQ, ENT_FREQ, MED_FREQ, SEC_FREQ, SCI_FREQ, SRV_FREQ, SUP_FREQ) -var/list/OFFMAP_FREQS = list(TALON_FREQ) //VOREStation Add +var/list/OFFMAP_FREQS = list(TALON_FREQ, CSN_FREQ) //VOREStation Add /proc/frequency_span_class(var/frequency) // Antags! diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 2da3f710251..2ebe6ea8c15 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -78,6 +78,7 @@ var/list/gamemode_cache = list() var/static/kick_inactive = 0 //force disconnect for inactive players after this many minutes, if non-0 var/static/show_mods = 0 var/static/show_devs = 0 + var/static/show_mentors = 0 var/static/show_event_managers = 0 var/static/mods_can_tempban = 0 var/static/mods_can_job_tempban = 0 @@ -216,7 +217,7 @@ var/list/gamemode_cache = list() var/python_path = "" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix var/use_lib_nudge = 0 //Use the C library nudge instead of the python nudge. var/use_overmap = 0 - + var/static/list/engine_map = list("Supermatter Engine", "Edison's Bane") // Comma separated list of engines to choose from. Blank means fully random. // Event settings @@ -289,7 +290,7 @@ var/list/gamemode_cache = list() // How strictly the loadout enforces object species whitelists var/loadout_whitelist = LOADOUT_WHITELIST_LAX - + var/static/vgs_access_identifier = null // VOREStation Edit - VGS var/static/vgs_server_port = null // VOREStation Edit - VGS @@ -652,6 +653,9 @@ var/list/gamemode_cache = list() if("show_devs") config.show_devs = 1 + if("show_mentors") + config.show_mentors = 1 + if("show_event_managers") config.show_event_managers = 1 @@ -955,10 +959,10 @@ var/list/gamemode_cache = list() if("suggested_byond_version") config.suggested_byond_version = text2num(value) - + if("suggested_byond_build") config.suggested_byond_build = text2num(value) - + // VOREStation Edit Start - Can't be in _vr file because it is loaded too late. if("vgs_access_identifier") config.vgs_access_identifier = value diff --git a/code/controllers/subsystems/game_master.dm b/code/controllers/subsystems/game_master.dm index 06a60602273..5315a3dbe8a 100644 --- a/code/controllers/subsystems/game_master.dm +++ b/code/controllers/subsystems/game_master.dm @@ -350,13 +350,13 @@ SUBSYSTEM_DEF(game_master) choose_game_master(usr) if(href_list["set_staleness"]) - var/amount = input(usr, "How much staleness should there be?", "Game Master") as null|num + var/amount = tgui_input_number(usr, "How much staleness should there be?", "Game Master") if(!isnull(amount)) staleness = amount message_admins("GM staleness was set to [amount] by [usr.key].") if(href_list["set_danger"]) - var/amount = input(usr, "How much danger should there be?", "Game Master") as null|num + var/amount = tgui_input_number(usr, "How much danger should there be?", "Game Master") if(!isnull(amount)) danger = amount message_admins("GM danger was set to [amount] by [usr.key].") diff --git a/code/controllers/subsystems/job.dm b/code/controllers/subsystems/job.dm index f265f39955a..2aa6d84cb69 100644 --- a/code/controllers/subsystems/job.dm +++ b/code/controllers/subsystems/job.dm @@ -131,12 +131,13 @@ SUBSYSTEM_DEF(job) return department_datums[primary_department] +/datum/controller/subsystem/job/proc/get_ping_role(var/role) + var/datum/job/J = get_job(role) + if(J.requestable) + return get_primary_department_of_job(J) + // Someday it might be good to port code/game/jobs/job_controller.dm to here and clean it up. - - - - /datum/controller/subsystem/job/proc/job_debug_message(message) if(debug_messages) log_debug("JOB DEBUG: [message]") \ No newline at end of file diff --git a/code/controllers/subsystems/media_tracks.dm b/code/controllers/subsystems/media_tracks.dm index 53805bcbec2..58fd0ec858f 100644 --- a/code/controllers/subsystems/media_tracks.dm +++ b/code/controllers/subsystems/media_tracks.dm @@ -74,7 +74,7 @@ SUBSYSTEM_DEF(media_tracks) return // Required - var/url = input(C, "REQUIRED: Provide URL for track, or paste JSON if you know what you're doing. See code comments.", "Track URL") as message|null + var/url = tgui_input_text(C, "REQUIRED: Provide URL for track, or paste JSON if you know what you're doing. See code comments.", "Track URL", multiline = TRUE) if(!url) return @@ -112,20 +112,20 @@ SUBSYSTEM_DEF(media_tracks) sort_tracks() return - var/title = input(C, "REQUIRED: Provide title for track", "Track Title") as text|null + var/title = tgui_input_text(C, "REQUIRED: Provide title for track", "Track Title") if(!title) return - var/duration = input(C, "REQUIRED: Provide duration for track (in deciseconds, aka seconds*10)", "Track Duration") as num|null + var/duration = tgui_input_number(C, "REQUIRED: Provide duration for track (in deciseconds, aka seconds*10)", "Track Duration") if(!duration) return // Optional - var/artist = input(C, "Optional: Provide artist for track", "Track Artist") as text|null + var/artist = tgui_input_text(C, "Optional: Provide artist for track", "Track Artist") if(isnull(artist)) // Cancel rather than empty string return - var/genre = input(C, "Optional: Provide genre for track (try to match an existing one)", "Track Genre") as text|null + var/genre = tgui_input_text(C, "Optional: Provide genre for track (try to match an existing one)", "Track Genre") if(isnull(genre)) // Cancel rather than empty string return @@ -160,7 +160,7 @@ SUBSYSTEM_DEF(media_tracks) if(!check_rights(R_DEBUG|R_FUN)) return - var/track = input(C, "Input track title or URL to remove (must be exact)", "Remove Track") as text|null + var/track = tgui_input_text(C, "Input track title or URL to remove (must be exact)", "Remove Track") if(!track) return diff --git a/code/controllers/subsystems/persist_vr.dm b/code/controllers/subsystems/persist_vr.dm index c40a0b0e35d..5217b72f9ae 100644 --- a/code/controllers/subsystems/persist_vr.dm +++ b/code/controllers/subsystems/persist_vr.dm @@ -59,6 +59,8 @@ SUBSYSTEM_DEF(persist) var/client/C = M.client var/wait_in_hours = wait / (1 HOUR) var/pto_factored = wait_in_hours * J.timeoff_factor + if(J.playtime_only) + pto_factored = 0 LAZYINITLIST(C.department_hours) LAZYINITLIST(C.play_hours) var/dept_hours = C.department_hours diff --git a/code/controllers/subsystems/supply.dm b/code/controllers/subsystems/supply.dm index af096c33a81..c30d559e4ba 100644 --- a/code/controllers/subsystems/supply.dm +++ b/code/controllers/subsystems/supply.dm @@ -363,15 +363,15 @@ SUBSYSTEM_DEF(supply) // Will add an item entry to the specified export receipt on the user-side list /datum/controller/subsystem/supply/proc/add_export_item(var/datum/exported_crate/E, var/mob/user) - var/new_name = input(user, "Name", "Please enter the name of the item.") as null|text + var/new_name = tgui_input_text(user, "Name", "Please enter the name of the item.") if(!new_name) return - var/new_quantity = input(user, "Name", "Please enter the quantity of the item.") as null|num + var/new_quantity = tgui_input_number(user, "Name", "Please enter the quantity of the item.") if(!new_quantity) return - var/new_value = input(user, "Name", "Please enter the value of the item.") as null|num + var/new_value = tgui_input_number(user, "Name", "Please enter the value of the item.") if(!new_value) return diff --git a/code/controllers/subsystems/tgui.dm b/code/controllers/subsystems/tgui.dm index a0d96cf80c1..d70d06017af 100644 --- a/code/controllers/subsystems/tgui.dm +++ b/code/controllers/subsystems/tgui.dm @@ -23,6 +23,10 @@ SUBSYSTEM_DEF(tgui) /datum/controller/subsystem/tgui/PreInit() basehtml = file2text('tgui/public/tgui.html') + // Inject inline polyfills + var/polyfill = file2text('tgui/public/tgui-polyfill.min.js') + polyfill = "" + basehtml = replacetextEx(basehtml, "", polyfill) /datum/controller/subsystem/tgui/Shutdown() close_all_uis() diff --git a/code/controllers/subsystems/throwing.dm b/code/controllers/subsystems/throwing.dm index 6c3a799b28f..101c71a1479 100644 --- a/code/controllers/subsystems/throwing.dm +++ b/code/controllers/subsystems/throwing.dm @@ -145,6 +145,9 @@ SUBSYSTEM_DEF(throwing) AM.Move(step, get_dir(AM, step)) + if (!AM) // Us moving somehow destroyed us? + return + if (!AM.throwing) // we hit something during our move finalize(hit = TRUE) return diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm index f2776508e24..ad20bbb8898 100644 --- a/code/controllers/subsystems/ticker.dm +++ b/code/controllers/subsystems/ticker.dm @@ -50,9 +50,9 @@ var/global/datum/controller/subsystem/ticker/ticker pregame_timeleft = config.pregame_time send2mainirc("Server lobby is loaded and open at byond://[config.serverurl ? config.serverurl : (config.server ? config.server : "[world.address]:[world.port]")]") SSwebhooks.send( - WEBHOOK_ROUNDPREP, + WEBHOOK_ROUNDPREP, list( - "map" = station_name(), + "map" = station_name(), "url" = get_world_url() ) ) @@ -397,14 +397,19 @@ var/global/datum/controller/subsystem/ticker/ticker if(player && player.ready && player.mind?.assigned_role) var/datum/job/J = SSjob.get_job(player.mind.assigned_role) + // Ask their new_player mob to spawn them + if(!player.spawn_checks_vr(player.mind.assigned_role)) + var/datum/job/job_datum = job_master.GetJob(J.title) + job_datum.current_positions-- + player.mind.assigned_role = null + continue //VOREStation Add + // Snowflakey AI treatment if(J?.mob_type & JOB_SILICON_AI) player.close_spawn_windows() player.AIize(move = TRUE) continue - // Ask their new_player mob to spawn them - if(!player.spawn_checks_vr(player.mind.assigned_role)) continue //VOREStation Add var/mob/living/carbon/human/new_char = player.create_character() // Created their playable character, delete their /mob/new_player diff --git a/code/controllers/subsystems/vote.dm b/code/controllers/subsystems/vote.dm index 658cff17164..352550a9a56 100644 --- a/code/controllers/subsystems/vote.dm +++ b/code/controllers/subsystems/vote.dm @@ -231,11 +231,11 @@ SUBSYSTEM_DEF(vote) choices.Add(antag.role_text) choices.Add("None") if(VOTE_CUSTOM) - question = sanitizeSafe(input(usr, "What is the vote for?") as text|null) + question = sanitizeSafe(tgui_input_text(usr, "What is the vote for?")) if(!question) return 0 for(var/i = 1 to 10) - var/option = capitalize(sanitize(input(usr, "Please enter an option or hit cancel to finish") as text|null)) + var/option = capitalize(sanitize(tgui_input_text(usr, "Please enter an option or hit cancel to finish"))) if(!option || mode || !usr.client) break choices.Add(option) @@ -362,7 +362,12 @@ SUBSYSTEM_DEF(vote) if(VOTE_RESTART) if(config.allow_vote_restart || usr.client.holder) - initiate_vote(VOTE_RESTART, usr.key) + var/admin_number_present = send2irc_adminless_only(usr.ckey, usr) + if(admin_number_present <= 0 || usr.client.holder) + if(tgui_alert(usr, "Are you sure you want to start a RESTART VOTE? You should only do this if the server is dying and no staff are around to investigate.", "RESTART VOTE", list("No", "Yes I want to start a RESTART VOTE")) == "Yes I want to start a RESTART VOTE") + initiate_vote(VOTE_RESTART, usr.key) + else + to_chat(usr, "You can't start a RESTART VOTE while there are staff around. If you are having an issue with the round, please ahelp it.") if(VOTE_GAMEMODE) if(config.allow_vote_mode || usr.client.holder) initiate_vote(VOTE_GAMEMODE, usr.key) diff --git a/code/datums/autolathe/devices_vr.dm b/code/datums/autolathe/devices_vr.dm index 9d92132caa4..65af7b630cc 100644 --- a/code/datums/autolathe/devices_vr.dm +++ b/code/datums/autolathe/devices_vr.dm @@ -1,3 +1,3 @@ /datum/category_item/autolathe/devices/sleevecard name = "sleevecard" - path =/obj/item/device/sleevecard + path =/obj/item/device/paicard/sleevecard diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 75c3c64c7f2..fef1bcd25de 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -68,7 +68,7 @@ names += componentsubtypes names += "---Elements---" names += sortTim(subtypesof(/datum/element), /proc/cmp_typepaths_asc) - var/result = input(usr, "Choose a component/element to add:", "Add Component/Element", names) + var/result = tgui_input_list(usr, "Choose a component/element to add:", "Add Component/Element", names) if(!usr || !result || result == "---Components---" || result == "---Elements---") return if(QDELETED(src)) diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index abc7ade225f..194341a106c 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -1,3 +1,10 @@ +var/bluespace_item_types = newlist(/obj/item/weapon/storage/backpack/holding, +/obj/item/weapon/storage/bag/trash/holding, +/obj/item/weapon/storage/pouch/holding, +/obj/item/weapon/storage/belt/utility/holding, +/obj/item/weapon/storage/belt/medical/holding +) + //wrapper /proc/do_teleport(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null, local=TRUE) //VOREStation Edit new /datum/teleport/instant/science(arglist(args)) @@ -151,19 +158,25 @@ /datum/teleport/instant/science/setPrecision(aprecision) ..() - if(istype(teleatom, /obj/item/weapon/storage/backpack/holding)) - precision = rand(1,100) - var/list/bagholding = teleatom.search_contents_for(/obj/item/weapon/storage/backpack/holding) + var/list/bluespace_things = newlist() + + for (var/item in bluespace_item_types) + if (istype(teleatom, item)) + precision = rand(1, 100) + bluespace_things |= teleatom.search_contents_for(item) + //VOREStation Addition Start: Prevent taurriding abuse if(istype(teleatom, /mob/living)) var/mob/living/L = teleatom if(LAZYLEN(L.buckled_mobs)) for(var/mob/rider in L.buckled_mobs) - bagholding += rider.search_contents_for(/obj/item/weapon/storage/backpack/holding) + for (var/item in bluespace_item_types) + bluespace_things |= rider.search_contents_for(item) //VOREStation Addition End: Prevent taurriding abuse - if(bagholding.len) - precision = max(rand(1,100)*bagholding.len,100) + + if(bluespace_things.len) + precision = max(rand(1,100)*bluespace_things.len,100) if(istype(teleatom, /mob/living)) var/mob/living/MM = teleatom to_chat(MM, "The Bluespace interface on your [teleatom] interferes with the teleport!") diff --git a/code/datums/managed_browsers/feedback_form.dm b/code/datums/managed_browsers/feedback_form.dm index b380018bea6..c6160ffc598 100644 --- a/code/datums/managed_browsers/feedback_form.dm +++ b/code/datums/managed_browsers/feedback_form.dm @@ -99,7 +99,7 @@ GENERAL_PROTECT_DATUM(/datum/managed_browser/feedback_form) if(href_list["feedback_edit_body"]) // This is deliberately not sanitized here, and is instead checked when hitting the submission button, // as we want to give the user a chance to fix it without needing to rewrite the whole thing. - feedback_body = input(my_client, "Please write your feedback here.", "Feedback Body", feedback_body) as null|message + feedback_body = tgui_input_text(my_client, "Please write your feedback here.", "Feedback Body", feedback_body, multiline = TRUE, prevent_enter = TRUE) display() // Refresh the window with new information. return diff --git a/code/datums/managed_browsers/feedback_viewer.dm b/code/datums/managed_browsers/feedback_viewer.dm index 895bd36fae4..02360363384 100644 --- a/code/datums/managed_browsers/feedback_viewer.dm +++ b/code/datums/managed_browsers/feedback_viewer.dm @@ -132,29 +132,29 @@ return if(href_list["filter_id"]) - var/id_to_search = input(my_client, "Write feedback ID here.", "Filter by ID", null) as null|num + var/id_to_search = tgui_input_number(my_client, "Write feedback ID here.", "Filter by ID", null) if(id_to_search) last_query = feedback_filter(SQLITE_FEEDBACK_COLUMN_ID, id_to_search, TRUE) if(href_list["filter_author"]) - var/author_to_search = input(my_client, "Write desired key or hash here. Partial keys/hashes are allowed.", "Filter by Author", null) as null|text + var/author_to_search = tgui_input_text(my_client, "Write desired key or hash here. Partial keys/hashes are allowed.", "Filter by Author", null) if(author_to_search) last_query = feedback_filter(SQLITE_FEEDBACK_COLUMN_AUTHOR, author_to_search) if(href_list["filter_topic"]) - var/topic_to_search = input(my_client, "Write desired topic here. Partial topics are allowed. \ - \nThe current topics in the config are [english_list(config.sqlite_feedback_topics)].", "Filter by Topic", null) as null|text + var/topic_to_search = tgui_input_text(my_client, "Write desired topic here. Partial topics are allowed. \ + \nThe current topics in the config are [english_list(config.sqlite_feedback_topics)].", "Filter by Topic", null) if(topic_to_search) last_query = feedback_filter(SQLITE_FEEDBACK_COLUMN_TOPIC, topic_to_search) if(href_list["filter_content"]) - var/content_to_search = input(my_client, "Write desired content to find here. Partial matches are allowed.", "Filter by Content", null) as null|message + var/content_to_search = tgui_input_text(my_client, "Write desired content to find here. Partial matches are allowed.", "Filter by Content", null, multiline = TRUE) if(content_to_search) last_query = feedback_filter(SQLITE_FEEDBACK_COLUMN_CONTENT, content_to_search) if(href_list["filter_datetime"]) - var/datetime_to_search = input(my_client, "Write desired datetime. Partial matches are allowed.\n\ - Format is 'YYYY-MM-DD HH:MM:SS'.", "Filter by Datetime", null) as null|text + var/datetime_to_search = tgui_input_text(my_client, "Write desired datetime. Partial matches are allowed.\n\ + Format is 'YYYY-MM-DD HH:MM:SS'.", "Filter by Datetime", null) if(datetime_to_search) last_query = feedback_filter(SQLITE_FEEDBACK_COLUMN_DATETIME, datetime_to_search) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index a35c23cd6b4..e4ec5954e26 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -75,6 +75,8 @@ //used to store what traits the player had picked out in their preferences before joining, in text form. var/list/traits = list() + var/datum/religion/my_religion + /datum/mind/New(var/key) src.key = key purchase_log = list() @@ -188,7 +190,7 @@ assigned_role = new_role else if (href_list["memory_edit"]) - var/new_memo = sanitize(input("Write new memory", "Memory", memory) as null|message) + var/new_memo = sanitize(tgui_input_text(usr, "Write new memory", "Memory", memory, multiline = TRUE, prevent_enter = TRUE)) if (isnull(new_memo)) return memory = new_memo @@ -196,7 +198,7 @@ var/datum/mind/mind = locate(href_list["amb_edit"]) if(!mind) return - var/new_ambition = input("Enter a new ambition", "Memory", mind.ambitions) as null|message + var/new_ambition = tgui_input_text(usr, "Enter a new ambition", "Memory", mind.ambitions, multiline = TRUE, prevent_enter = TRUE) if(isnull(new_ambition)) return if(mind) @@ -294,7 +296,7 @@ if(objective&&objective.type==text2path("/datum/objective/[new_obj_type]")) def_num = objective.target_amount - var/target_number = input("Input target number:", "Objective", def_num) as num|null + var/target_number = tgui_input_number(usr, "Input target number:", "Objective", def_num) if (isnull(target_number))//Ordinarily, you wouldn't need isnull. In this case, the value may already exist. return @@ -312,7 +314,7 @@ new_objective.target_amount = target_number if ("custom") - var/expl = sanitize(input("Custom objective:", "Objective", objective ? objective.explanation_text : "") as text|null) + var/expl = sanitize(tgui_input_text(usr, "Custom objective:", "Objective", objective ? objective.explanation_text : "")) if (!expl) return new_objective = new /datum/objective new_objective.owner = src @@ -408,7 +410,7 @@ // var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink() No longer needed, uses stored in mind var/crystals crystals = tcrystals - crystals = input("Amount of telecrystals for [key]", crystals) as null|num + crystals = tgui_input_number(usr, "Amount of telecrystals for [key]", crystals) if (!isnull(crystals)) tcrystals = crystals @@ -571,4 +573,4 @@ /mob/living/simple_mob/construct/juggernaut/mind_initialize() . = ..() mind.assigned_role = "Juggernaut" - mind.special_role = "Cultist" + mind.special_role = "Cultist" \ No newline at end of file diff --git a/code/datums/outfits/jobs/civilian.dm b/code/datums/outfits/jobs/civilian.dm index 1d299a81dbd..554666cbca8 100644 --- a/code/datums/outfits/jobs/civilian.dm +++ b/code/datums/outfits/jobs/civilian.dm @@ -31,8 +31,9 @@ /decl/hierarchy/outfit/job/service/bartender/post_equip(mob/living/carbon/human/H) ..() - for(var/obj/item/clothing/accessory/permit/gun/bar/permit in H.back.contents) - permit.set_name(H.real_name) + if(H.back) + for(var/obj/item/clothing/accessory/permit/gun/bar/permit in H.back.contents) + permit.set_name(H.real_name) /decl/hierarchy/outfit/job/service/bartender/barista name = OUTFIT_JOB_NAME("Barista") diff --git a/code/datums/supplypacks/atmospherics.dm b/code/datums/supplypacks/atmospherics.dm index a18b6308923..e6fb05f2207 100644 --- a/code/datums/supplypacks/atmospherics.dm +++ b/code/datums/supplypacks/atmospherics.dm @@ -106,7 +106,7 @@ cost = 35 containertype = /obj/structure/closet/crate/aether containername = "Emergency crate" - +/* /datum/supply_pack/atmos/firefighting name = "Firefighting equipment" contains = list( @@ -118,4 +118,4 @@ ) cost = 35 containertype = /obj/structure/closet/crate/aether - containername = "Firefighting crate" \ No newline at end of file + containername = "Firefighting crate"*/ \ No newline at end of file diff --git a/code/datums/supplypacks/materials.dm b/code/datums/supplypacks/materials.dm index 5e181d8af8a..3268d05a46c 100644 --- a/code/datums/supplypacks/materials.dm +++ b/code/datums/supplypacks/materials.dm @@ -66,17 +66,19 @@ /obj/fiftyspawner/tealcarpet ) -/datum/supply_pack/materials/arcade_carpet - name = "Retro carpets" +/datum/supply_pack/materials/retrocarpet + name = "Retro carpet" containertype = /obj/structure/closet/crate/grayson - containername = "Retro carpets crate" + containername = "Retro carpet crate" cost = 15 contains = list( - /obj/fiftyspawner/decocarpet, - /obj/fiftyspawner/retrocarpet + /obj/fiftyspawner/geocarpet, + /obj/fiftyspawner/retrocarpet, + /obj/fiftyspawner/retrocarpet_red, + /obj/fiftyspawner/happycarpet ) -/datum/supply_pack/misc/linoleum +/datum/supply_pack/materials/linoleum name = "Linoleum" containertype = /obj/structure/closet/crate/grayson containername = "Linoleum crate" diff --git a/code/datums/supplypacks/misc_vr.dm b/code/datums/supplypacks/misc_vr.dm index 63f055d2d45..539e88f75b2 100644 --- a/code/datums/supplypacks/misc_vr.dm +++ b/code/datums/supplypacks/misc_vr.dm @@ -102,6 +102,16 @@ containername = "Commonwealth engineering hardsuit crate" access = access_engine +/datum/supply_pack/misc/breacher_rig + name = "unathi breacher hardsuit (empty)" + contains = list( + /obj/item/weapon/rig/breacher = 1 + ) + cost = 250 + containertype = /obj/structure/closet/crate/secure/gear + containername = "unathi breacher hardsuit crate" + access = access_armory + /datum/supply_pack/misc/zero_rig name = "null hardsuit (jets)" contains = list( diff --git a/code/datums/supplypacks/recreation.dm b/code/datums/supplypacks/recreation.dm index ba6a33d48cb..40caa4c405b 100644 --- a/code/datums/supplypacks/recreation.dm +++ b/code/datums/supplypacks/recreation.dm @@ -35,6 +35,15 @@ containertype = /obj/structure/closet/crate/allico containername = "foam weapon crate" +/datum/supply_pack/recreation/donksoftborg + name = "Donk-Soft Cyborg Blaster Crate" + contains = list( + /obj/item/borg/upgrade/toygun = 2, + ) + cost = 35 + containertype = /obj/structure/closet/crate/allico + containername = "foam weapon crate" + /datum/supply_pack/recreation/donksoftvend name = "Donk-Soft Vendor Crate" contains = list() diff --git a/code/datums/supplypacks/security.dm b/code/datums/supplypacks/security.dm index 18cc82af767..5c4ddf1a6a2 100644 --- a/code/datums/supplypacks/security.dm +++ b/code/datums/supplypacks/security.dm @@ -287,7 +287,7 @@ containertype = /obj/structure/closet/crate/secure/lawson containername = "Riot armor crate" access = access_armory - +/* /datum/supply_pack/security/riot_sprayer name = "Gear - Riot sprayer" contains = list( @@ -296,7 +296,7 @@ cost = 40 containertype = /obj/structure/closet/crate/secure/lawson containername = "Riot sprayer crate" - access = access_armory + access = access_armory*/ /datum/supply_pack/security/ablative_armor name = "Armor - Ablative" diff --git a/code/datums/supplypacks/supply.dm b/code/datums/supplypacks/supply.dm index eff6fb84fd0..70f8386a914 100644 --- a/code/datums/supplypacks/supply.dm +++ b/code/datums/supplypacks/supply.dm @@ -9,18 +9,30 @@ /datum/supply_pack/supply/food name = "Kitchen supply crate" contains = list( - /obj/item/weapon/reagent_containers/food/condiment/flour = 6, + /obj/item/weapon/reagent_containers/food/condiment/carton/flour = 6, /obj/item/weapon/reagent_containers/food/drinks/milk = 3, /obj/item/weapon/reagent_containers/food/drinks/soymilk = 2, /obj/item/weapon/storage/fancy/egg_box = 2, /obj/item/weapon/reagent_containers/food/snacks/tofu = 4, /obj/item/weapon/reagent_containers/food/snacks/meat = 4, - /obj/item/weapon/reagent_containers/food/condiment/yeast = 3 + /obj/item/weapon/reagent_containers/food/condiment/yeast = 3, + /obj/item/weapon/reagent_containers/food/condiment/sprinkles = 1 ) cost = 10 containertype = /obj/structure/closet/crate/freezer/centauri containername = "Food crate" +/datum/supply_pack/supply/fancyfood + name = "Artisanal food delivery" + contains = list( + /obj/item/weapon/reagent_containers/food/condiment/carton/flour/rustic = 6, + /obj/item/weapon/reagent_containers/food/condiment/carton/sugar/rustic = 6 + ) + cost = 25 + containertype = /obj/structure/closet/crate/freezer/centauri + containername = "Artisanal food crate" + + /datum/supply_pack/supply/toner name = "Toner cartridges" contains = list(/obj/item/device/toner = 6) diff --git a/code/datums/uplink/announcements.dm b/code/datums/uplink/announcements.dm index f1db67a6474..f6742fb815c 100644 --- a/code/datums/uplink/announcements.dm +++ b/code/datums/uplink/announcements.dm @@ -16,10 +16,10 @@ item_cost = 20 /datum/uplink_item/abstract/announcements/fake_centcom/extra_args(var/mob/user) - var/title = sanitize(input(usr, "Enter your announcement title.", "Announcement Title") as null|text) + var/title = sanitize(tgui_input_text(usr, "Enter your announcement title.", "Announcement Title")) if(!title) return - var/message = sanitize(input(usr, "Enter your announcement message.", "Announcement Title") as null|text) + var/message = sanitize(tgui_input_text(usr, "Enter your announcement message.", "Announcement Title")) if(!message) return return list("title" = title, "message" = message) diff --git a/code/datums/uplink/badassery.dm b/code/datums/uplink/badassery.dm index 8addcc3f64e..8208894af4f 100644 --- a/code/datums/uplink/badassery.dm +++ b/code/datums/uplink/badassery.dm @@ -91,4 +91,4 @@ var/obj/structure/largecrate/C = /obj/structure/largecrate icon = image(initial(C.icon), initial(C.icon_state)) - return "[bicon(icon)]" \ No newline at end of file + return "\icon[icon][bicon(icon)]" \ No newline at end of file diff --git a/code/datums/uplink/tools.dm b/code/datums/uplink/tools.dm index eee41e96993..9c1a46d632f 100644 --- a/code/datums/uplink/tools.dm +++ b/code/datums/uplink/tools.dm @@ -6,22 +6,22 @@ /datum/uplink_item/item/tools/binoculars name = "Binoculars" - item_cost = 5 + item_cost = 3 path = /obj/item/device/binoculars /datum/uplink_item/item/tools/toolbox // Leaving the basic as an option since powertools are loud. name = "Fully Loaded Toolbox" - item_cost = 5 + item_cost = 3 path = /obj/item/weapon/storage/toolbox/syndicate /datum/uplink_item/item/tools/powertoolbox name = "Fully Loaded Powertool Box" - item_cost = 10 + item_cost = 5 path = /obj/item/weapon/storage/toolbox/syndicate/powertools /datum/uplink_item/item/tools/clerical name = "Morphic Clerical Kit" - item_cost = 10 + item_cost = 5 path = /obj/item/weapon/storage/box/syndie_kit/clerical /datum/uplink_item/item/tools/encryptionkey_radio @@ -42,7 +42,7 @@ /datum/uplink_item/item/tools/duffle name = "Black Duffle Bag" - item_cost = 10 + item_cost = 5 path = /obj/item/weapon/storage/backpack/dufflebag/syndie /datum/uplink_item/item/tools/duffle/med @@ -61,7 +61,7 @@ /datum/uplink_item/item/tools/space_suit name = "Space Suit" - item_cost = 15 + item_cost = 10 path = /obj/item/weapon/storage/box/syndie_kit/space /datum/uplink_item/item/tools/encryptionkey_binary @@ -71,7 +71,7 @@ /datum/uplink_item/item/tools/hacking_tool name = "Door Hacking Tool" - item_cost = 20 + item_cost = 15 path = /obj/item/device/multitool/hacktool desc = "Appears and functions as a standard multitool until the mode is toggled by applying a screwdriver appropriately. \ When in hacking mode this device will grant full access to any standard airlock within 20 to 40 seconds. \ @@ -79,7 +79,7 @@ /datum/uplink_item/item/tools/ai_detector name = "Anti-Surveillance Tool" - item_cost = 20 + item_cost = 15 path = /obj/item/device/multitool/ai_detector desc = "This functions like a normal multitool, but includes an integrated camera network sensor that will warn the holder if they are being \ watched, by changing color and beeping. It is able to detect both AI visual surveillance and security camera utilization from terminals, and \ @@ -87,20 +87,20 @@ /datum/uplink_item/item/tools/radio_jammer name = "Subspace Jammer" - item_cost = 25 + item_cost = 20 path = /obj/item/device/radio_jammer desc = "A device which is capable of disrupting subspace communications, preventing the use of headsets, PDAs, and communicators within \ a radius of seven meters. It runs off weapon cells, which can be replaced as needed. One cell will last for approximately ten minutes." /datum/uplink_item/item/tools/wall_elecrtifier name = "Wall Electrifier" - item_cost = 10 + item_cost = 5 path = /obj/item/weapon/cell/spike desc = "A modified powercell which will electrify walls and reinforced floors in a 3x3 tile range around it. Always active." /datum/uplink_item/item/tools/emag name = "Cryptographic Sequencer" - item_cost = 30 + item_cost = 20 path = /obj/item/weapon/card/emag /datum/uplink_item/item/tools/graviton @@ -111,7 +111,7 @@ /datum/uplink_item/item/tools/thermal name = "Thermal Imaging Glasses" - item_cost = 30 + item_cost = 25 path = /obj/item/clothing/glasses/thermal/syndi /datum/uplink_item/item/tools/packagebomb diff --git a/code/datums/uplink/uplink_items.dm b/code/datums/uplink/uplink_items.dm index 7156f807bdb..7fcdbd8dc2a 100644 --- a/code/datums/uplink/uplink_items.dm +++ b/code/datums/uplink/uplink_items.dm @@ -130,7 +130,7 @@ var/datum/uplink/uplink = new() /datum/uplink_item/item/log_icon() var/obj/I = path - return "[bicon(I)]" + return "\icon[I][bicon(I)]" /******************************** * * @@ -144,7 +144,7 @@ var/datum/uplink/uplink = new() if(!default_abstract_uplink_icon) default_abstract_uplink_icon = image('icons/obj/pda.dmi', "pda-syn") - return "[bicon(default_abstract_uplink_icon)]" + return "\icon[default_abstract_uplink_icon][bicon(default_abstract_uplink_icon)]" /* * Crated goods. diff --git a/code/datums/wires/camera.dm b/code/datums/wires/camera.dm index 571e2a22e6c..c572ad8d27c 100644 --- a/code/datums/wires/camera.dm +++ b/code/datums/wires/camera.dm @@ -57,7 +57,7 @@ C.light_disabled = !C.light_disabled if(WIRE_CAM_ALARM) - C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*") + C.visible_message("\icon[C][bicon(C)] *beep*", "\icon[C][bicon(C)] *beep*") ..() /datum/wires/camera/proc/CanDeconstruct() diff --git a/code/datums/wires/jukebox.dm b/code/datums/wires/jukebox.dm index 125bbd78ef8..cec0f4d370b 100644 --- a/code/datums/wires/jukebox.dm +++ b/code/datums/wires/jukebox.dm @@ -31,16 +31,16 @@ var/obj/machinery/media/jukebox/A = holder switch(wire) if(WIRE_MAIN_POWER1) - holder.visible_message("[bicon(holder)] The power light flickers.") + holder.visible_message("\icon[holder][bicon(holder)] The power light flickers.") A.shock(usr, 90) if(WIRE_JUKEBOX_HACK) - holder.visible_message("[bicon(holder)] The parental guidance light flickers.") + holder.visible_message("\icon[holder][bicon(holder)] The parental guidance light flickers.") if(WIRE_REVERSE) - holder.visible_message("[bicon(holder)] The data light blinks ominously.") + holder.visible_message("\icon[holder][bicon(holder)] The data light blinks ominously.") if(WIRE_SPEEDUP) - holder.visible_message("[bicon(holder)] The speakers squeaks.") + holder.visible_message("\icon[holder][bicon(holder)] The speakers squeaks.") if(WIRE_SPEEDDOWN) - holder.visible_message("[bicon(holder)] The speakers rumble.") + holder.visible_message("\icon[holder][bicon(holder)] The speakers rumble.") if(WIRE_START) A.StartPlaying() if(WIRE_STOP) diff --git a/code/datums/wires/mines.dm b/code/datums/wires/mines.dm index 5e757ad16c3..55ea718c3f4 100644 --- a/code/datums/wires/mines.dm +++ b/code/datums/wires/mines.dm @@ -21,15 +21,15 @@ switch(wire) if(WIRE_EXPLODE) - C.visible_message("[bicon(C)] *BEEE-*", "[bicon(C)] *BEEE-*") + C.visible_message("\icon[C][bicon(C)] *BEEE-*", "\icon[C][bicon(C)] *BEEE-*") C.explode() if(WIRE_EXPLODE_DELAY) - C.visible_message("[bicon(C)] *BEEE-*", "[bicon(C)] *BEEE-*") + C.visible_message("\icon[C][bicon(C)] *BEEE-*", "\icon[C][bicon(C)] *BEEE-*") C.explode() if(WIRE_DISARM) - C.visible_message("[bicon(C)] *click!*", "[bicon(C)] *click!*") + C.visible_message("\icon[C][bicon(C)] *click!*", "\icon[C][bicon(C)] *click!*") var/obj/effect/mine/MI = new C.mineitemtype(get_turf(C)) if(C.trap) @@ -41,15 +41,15 @@ qdel(C) if(WIRE_BADDISARM) - C.visible_message("[bicon(C)] *BEEPBEEPBEEP*", "[bicon(C)] *BEEPBEEPBEEP*") + C.visible_message("\icon[C][bicon(C)] *BEEPBEEPBEEP*", "\icon[C][bicon(C)] *BEEPBEEPBEEP*") spawn(20) C.explode() if(WIRE_TRAP) - C.visible_message("[bicon(C)] *click!*", "[bicon(C)] *click!*") + C.visible_message("\icon[C][bicon(C)] *click!*", "\icon[C][bicon(C)] *click!*") if(mend) - C.visible_message("[bicon(C)] - The mine recalibrates[C.camo_net ? ", revealing \the [C.trap] inside." : "."]") + C.visible_message("\icon[C][bicon(C)] - The mine recalibrates[C.camo_net ? ", revealing \the [C.trap] inside." : "."]") C.alpha = 255 @@ -61,21 +61,21 @@ return switch(wire) if(WIRE_EXPLODE) - C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*") + C.visible_message("\icon[C][bicon(C)] *beep*", "\icon[C][bicon(C)] *beep*") if(WIRE_EXPLODE_DELAY) - C.visible_message("[bicon(C)] *BEEPBEEPBEEP*", "[bicon(C)] *BEEPBEEPBEEP*") + C.visible_message("\icon[C][bicon(C)] *BEEPBEEPBEEP*", "\icon[C][bicon(C)] *BEEPBEEPBEEP*") spawn(20) C.explode() if(WIRE_DISARM) - C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*") + C.visible_message("\icon[C][bicon(C)] *ping*", "\icon[C][bicon(C)] *ping*") if(WIRE_BADDISARM) - C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*") + C.visible_message("\icon[C][bicon(C)] *ping*", "\icon[C][bicon(C)] *ping*") if(WIRE_TRAP) - C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*") + C.visible_message("\icon[C][bicon(C)] *ping*", "\icon[C][bicon(C)] *ping*") ..() diff --git a/code/datums/wires/particle_accelerator.dm b/code/datums/wires/particle_accelerator.dm index e3fd198b3ba..1787039622b 100644 --- a/code/datums/wires/particle_accelerator.dm +++ b/code/datums/wires/particle_accelerator.dm @@ -26,7 +26,7 @@ C.interface_control = !C.interface_control if(WIRE_PARTICLE_POWER_LIMIT) - C.visible_message("[bicon(C)][C] makes a large whirring noise.") + C.visible_message("\icon[C][bicon(C)][C] makes a large whirring noise.") /datum/wires/particle_acc/control_box/on_cut(wire, mend) var/obj/machinery/particle_accelerator/control_box/C = holder diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index 568eb0f743e..858875a9827 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -40,7 +40,7 @@ if(!msg_sanitized) message = sanitize(message, extra = 0) - message_title = sanitizeSafe(message_title) + message_title = sanitizeSafe(message_title) var/list/zlevels if(zlevel) diff --git a/code/game/antagonist/antagonist_create.dm b/code/game/antagonist/antagonist_create.dm index 84c5b2317e2..3dd683377f0 100644 --- a/code/game/antagonist/antagonist_create.dm +++ b/code/game/antagonist/antagonist_create.dm @@ -118,7 +118,7 @@ /datum/antagonist/proc/set_antag_name(var/mob/living/player) // Choose a name, if any. - var/newname = sanitize(input(player, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text, MAX_NAME_LEN) + var/newname = sanitize(tgui_input_text(player, "You are a [role_text]. Would you like to change your name to something else?", "Name change", null, MAX_NAME_LEN), MAX_NAME_LEN) if (newname) player.real_name = newname player.name = player.real_name diff --git a/code/game/antagonist/antagonist_objectives.dm b/code/game/antagonist/antagonist_objectives.dm index c2c56c7be1b..223db7dda83 100644 --- a/code/game/antagonist/antagonist_objectives.dm +++ b/code/game/antagonist/antagonist_objectives.dm @@ -41,9 +41,9 @@ to_chat(src, "While you may perhaps have goals, this verb's meant to only be visible \ to antagonists. Please make a bug report!") return - var/new_ambitions = input(src, "Write a short sentence of what your character hopes to accomplish \ + var/new_ambitions = tgui_input_text(src, "Write a short sentence of what your character hopes to accomplish \ today as an antagonist. Remember that this is purely optional. It will be shown at the end of the \ - round for everybody else.", "Ambitions", mind.ambitions) as null|message + round for everybody else.", "Ambitions", mind.ambitions, multiline = TRUE) if(isnull(new_ambitions)) return new_ambitions = sanitize(new_ambitions) diff --git a/code/game/antagonist/station/rogue_ai.dm b/code/game/antagonist/station/rogue_ai.dm index e1b73b064b8..fd3ee867f93 100644 --- a/code/game/antagonist/station/rogue_ai.dm +++ b/code/game/antagonist/station/rogue_ai.dm @@ -97,7 +97,7 @@ var/datum/antagonist/rogue_ai/malf testing("rogue_ai set_antag_name called on non-silicon mob [player]!") return // Choose a name, if any. - var/newname = sanitize(input(player, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text, MAX_NAME_LEN) + var/newname = sanitize(tgui_input_text(player, "You are a [role_text]. Would you like to change your name to something else?", "Name change", null, MAX_NAME_LEN), MAX_NAME_LEN) if (newname) player.SetName(newname) if(player.mind) player.mind.name = player.name diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index e73b80ca035..0dc346ca816 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -1010,6 +1010,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station flags = RAD_SHIELDED ambience = AMBIENCE_GENERIC forbid_events = TRUE + forbid_singulo = TRUE /area/crew_quarters/toilet name = "\improper Dormitory Toilets" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 67ffb298d25..579678bd45e 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -51,6 +51,7 @@ var/sound_env = STANDARD_STATION var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf var/forbid_events = FALSE // If true, random events will not start inside this area. + var/forbid_singulo = FALSE // If true singulo will not move in. var/no_spoilers = FALSE // If true, makes it much more difficult to see what is inside an area with things like mesons. var/soundproofed = FALSE // If true, blocks sounds from other areas and prevents hearers on other areas from hearing the sounds within. @@ -386,7 +387,7 @@ var/list/mob/living/forced_ambiance_list = new /area/Entered(mob/M) if(!istype(M) || !M.ckey) return - + if(!isliving(M)) M.lastarea = src return @@ -455,6 +456,10 @@ var/list/mob/living/forced_ambiance_list = new return // Being buckled to something solid keeps you in place. if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.item_flags & NOSLIP)) return + if(H.incorporeal_move) // VOREstation edit - Phaseshifted beings should not be affected by gravity + return + if(H.species.can_zero_g_move || H.species.can_space_freemove) + return if(H.m_intent == "run") H.AdjustStunned(6) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 95f064d4931..e61dd0e956f 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -222,7 +222,7 @@ var/global/list/pre_init_created_atoms // atom creation ordering means some stuf else f_name += "oil-stained [name][infix]." - var/list/output = list("[bicon(src)] That's [f_name] [suffix]", desc) + var/list/output = list("\icon[src.examine_icon()][bicon(src)] That's [f_name] [suffix]", desc) if(user.client?.prefs.examine_text_mode == EXAMINE_MODE_INCLUDE_USAGE) output += description_info @@ -713,7 +713,7 @@ var/global/list/pre_init_created_atoms // atom creation ordering means some stuf . = ..() SEND_SIGNAL(src, COMSIG_ATOM_EXITED, AM, new_loc) -/atom/proc/get_visible_gender() +/atom/proc/get_visible_gender(mob/user, force) return gender /atom/proc/interact(mob/user) diff --git a/code/game/base_turf.dm b/code/game/base_turf.dm index 3f78c6fba48..238015d6ed6 100644 --- a/code/game/base_turf.dm +++ b/code/game/base_turf.dm @@ -19,7 +19,7 @@ if(!holder) return - var/choice = input(usr, "Which Z-level do you wish to set the base turf for?") as num|null + var/choice = tgui_input_number(usr, "Which Z-level do you wish to set the base turf for?") if(!choice) return diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 3d945e58167..931b2980913 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -24,14 +24,16 @@ /proc/randmutb(var/mob/living/M) if(!M) return M.dna.check_integrity() - var/block = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK) + //var/block = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK) // Most of these are disabled anyway. + var/block = pick(FAKEBLOCK,CLUMSYBLOCK,BLINDBLOCK,DEAFBLOCK) M.dna.SetSEState(block, 1) // Give Random Good Mutation to M /proc/randmutg(var/mob/living/M) if(!M) return M.dna.check_integrity() - var/block = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK) + //var/block = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK) // Much like above, most of these blocks are disabled in code. + var/block = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,REGENERATEBLOCK,REMOTETALKBLOCK) M.dna.SetSEState(block, 1) // Random Appearance Mutation diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 1f2815426b4..58338edf220 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -24,7 +24,7 @@ var/languages=null var/list/flavor=null var/gender = null - var/list/body_descriptors = null + var/list/body_descriptors = null // Guess we'll keep null. var/list/genetic_modifiers = list() // Modifiers with the MODIFIER_GENETIC flag are saved. Note that only the type is saved, not an instance. /datum/dna2/record/proc/GetData() @@ -54,7 +54,8 @@ newrecord.implant = implant newrecord.flavor = flavor newrecord.gender = gender - newrecord.body_descriptors = body_descriptors.Copy() + if(body_descriptors) + newrecord.body_descriptors = body_descriptors.Copy() newrecord.genetic_modifiers = genetic_modifiers.Copy() return newrecord diff --git a/code/game/gamemodes/changeling/powers/mimic_voice.dm b/code/game/gamemodes/changeling/powers/mimic_voice.dm index 6b84c577ff6..be4a055dc1b 100644 --- a/code/game/gamemodes/changeling/powers/mimic_voice.dm +++ b/code/game/gamemodes/changeling/powers/mimic_voice.dm @@ -22,7 +22,7 @@ to_chat(src, "We return our vocal glands to their original location.") return - var/mimic_voice = sanitize(input(usr, "Enter a name to mimic.", "Mimic Voice", null), MAX_NAME_LEN) + var/mimic_voice = sanitize(tgui_input_text(usr, "Enter a name to mimic.", "Mimic Voice", null, MAX_NAME_LEN), MAX_NAME_LEN) if(!mimic_voice) return diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index fac7066de48..3ad86499bda 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -611,7 +611,7 @@ var/list/sacrificed = list() // returns 0 if the rune is not used. returns 1 if the rune is used. /obj/effect/rune/proc/communicate() . = 1 // Default output is 1. If the rune is deleted it will return 1 - var/input = input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "")//sanitize() below, say() and whisper() have their own + var/input = tgui_input_text(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "")//sanitize() below, say() and whisper() have their own if(!input) if (istype(src)) fizzle() diff --git a/code/game/gamemodes/events/holidays/Holidays.dm b/code/game/gamemodes/events/holidays/Holidays.dm index cee83656cb9..9b31ad9a50e 100644 --- a/code/game/gamemodes/events/holidays/Holidays.dm +++ b/code/game/gamemodes/events/holidays/Holidays.dm @@ -214,8 +214,8 @@ var/global/list/Holiday = list() //Holidays are lists now, so we can have more t Holiday = list() - var/H = input(src,"What holiday is it today?","Set Holiday") as text - var/B = input(src,"Now explain what the holiday is about","Set Holiday") as message + var/H = tgui_input_text(src,"What holiday is it today?","Set Holiday") + var/B = tgui_input_text(src,"Now explain what the holiday is about","Set Holiday", multiline = TRUE, prevent_enter = TRUE) Holiday[H] = B diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 88efd6154e6..7af06d8d33d 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -59,23 +59,23 @@ var/global/list/additional_antag_types = list() var/choice = "" switch(href_list["set"]) if("shuttle_delay") - choice = input(usr, "Enter a new shuttle delay multiplier") as num + choice = tgui_input_number(usr, "Enter a new shuttle delay multiplier", null, null, 20, 1) if(!choice || choice < 1 || choice > 20) return shuttle_delay = choice if("antag_scaling") - choice = input(usr, "Enter a new antagonist cap scaling coefficient.") as num + choice = tgui_input_number(usr, "Enter a new antagonist cap scaling coefficient.", null, null, 100, 0) if(isnull(choice) || choice < 0 || choice > 100) return antag_scaling_coeff = choice if("event_modifier_moderate") - choice = input(usr, "Enter a new moderate event time modifier.") as num + choice = tgui_input_number(usr, "Enter a new moderate event time modifier.", null, null, 100, 0) if(isnull(choice) || choice < 0 || choice > 100) return event_delay_mod_moderate = choice refresh_event_modifiers() if("event_modifier_severe") - choice = input(usr, "Enter a new moderate event time modifier.") as num + choice = tgui_input_number(usr, "Enter a new moderate event time modifier.", null, null, 100, 0) if(isnull(choice) || choice < 0 || choice > 100) return event_delay_mod_major = choice diff --git a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm index d8229e1562a..2ee412194ef 100644 --- a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm +++ b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm @@ -93,8 +93,8 @@ if(!ability_prechecks(user, price)) return - var/title = input(usr, "Select message title: ") - var/text = input(usr, "Select message text: ") + var/title = tgui_input_text(usr, "Select message title: ") + var/text = tgui_input_text(usr, "Select message text: ") if(!title || !text || !ability_pay(user, price)) to_chat(user, "Hack Aborted") return diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index aec6442f8d1..7c51611bf2d 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -124,10 +124,10 @@ if("Location") mode = 1 - var/locationx = input(usr, "Please input the x coordinate to search for.", "Location?" , "") as num + var/locationx = tgui_input_number(usr, "Please input the x coordinate to search for.", "Location?" , "") if(!locationx || !(usr in view(1,src))) return - var/locationy = input(usr, "Please input the y coordinate to search for.", "Location?" , "") as num + var/locationy = tgui_input_number(usr, "Please input the y coordinate to search for.", "Location?" , "") if(!locationy || !(usr in view(1,src))) return @@ -160,7 +160,7 @@ to_chat(usr, "You set the pinpointer to locate [targetitem]") if("DNA") - var/DNAstring = input(usr, "Input DNA string to search for." , "Please Enter String." , "") + var/DNAstring = tgui_input_text(usr, "Input DNA string to search for." , "Please Enter String." , "") if(!DNAstring) return for(var/mob/living/carbon/M in mob_list) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index cb2a3fcb4b7..9b6b532f964 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -481,7 +481,7 @@ var/global/list/all_objectives = list() var/tmp_obj = new custom_target var/custom_name = tmp_obj:name qdel(tmp_obj) - custom_name = sanitize(input(usr, "Enter target name:", "Objective target", custom_name) as text|null) + custom_name = sanitize(tgui_input_text(usr, "Enter target name:", "Objective target", custom_name)) if (!custom_name) return target_name = custom_name steal_target = custom_target diff --git a/code/game/gamemodes/technomancer/spells/illusion.dm b/code/game/gamemodes/technomancer/spells/illusion.dm index dcadf53ffb1..ab83319bc59 100644 --- a/code/game/gamemodes/technomancer/spells/illusion.dm +++ b/code/game/gamemodes/technomancer/spells/illusion.dm @@ -49,12 +49,12 @@ if("Cancel") return if("Speak") - var/what_to_say = input(user, "What do you want \the [illusion] to say?","Illusion Speak") as null|text + var/what_to_say = tgui_input_text(user, "What do you want \the [illusion] to say?","Illusion Speak") //what_to_say = sanitize(what_to_say) //Sanitize occurs inside say() already. if(what_to_say) illusion.say(what_to_say) if("Emote") - var/what_to_emote = input(user, "What do you want \the [illusion] to do?","Illusion Emote") as null|text + var/what_to_emote = tgui_input_text(user, "What do you want \the [illusion] to do?","Illusion Emote") if(what_to_emote) illusion.emote(what_to_emote) diff --git a/code/game/jobs/job/assistant_vr.dm b/code/game/jobs/job/assistant_vr.dm index 7bfdadca50e..8be93935052 100644 --- a/code/game/jobs/job/assistant_vr.dm +++ b/code/game/jobs/job/assistant_vr.dm @@ -27,6 +27,7 @@ job_description = "An Intern does whatever is requested of them, often doing so in process of learning \ another job. Though they are part of the crew, they have no real authority." timeoff_factor = 0 // Interns, noh + requestable = FALSE /datum/alt_title/intern_eng title = "Apprentice Engineer" @@ -96,6 +97,7 @@ supervisors = "nobody! You don't work here" job_description = "A Visitor is just there to visit the place. They have no real authority or responsibility." timeoff_factor = 0 + requestable = FALSE alt_titles = list("Guest" = /datum/alt_title/guest, "Traveler" = /datum/alt_title/traveler) /datum/job/assistant/New() diff --git a/code/game/jobs/job/civilian_chaplain.dm b/code/game/jobs/job/civilian_chaplain.dm index 5fba7b155dc..f811abf9572 100644 --- a/code/game/jobs/job/civilian_chaplain.dm +++ b/code/game/jobs/job/civilian_chaplain.dm @@ -29,20 +29,14 @@ return var/obj/item/weapon/storage/bible/B = locate(/obj/item/weapon/storage/bible) in H - if(!B) + var/obj/item/weapon/card/id/I = locate(/obj/item/weapon/card/id) in H + + if(!B || !I) return - if(GLOB.religion) - B.deity_name = GLOB.deity - B.name = GLOB.bible_name - B.icon_state = GLOB.bible_icon_state - B.item_state = GLOB.bible_item_state - to_chat(H, "There is already an established religion onboard the station. You are an acolyte of [GLOB.deity]. Defer to the [title].") - return - - INVOKE_ASYNC(src, .proc/religion_prompts, H, B) + INVOKE_ASYNC(src, .proc/religion_prompts, H, B, I) -/datum/job/chaplain/proc/religion_prompts(mob/living/carbon/human/H, obj/item/weapon/storage/bible/B) +/datum/job/chaplain/proc/religion_prompts(mob/living/carbon/human/H, obj/item/weapon/storage/bible/B, obj/item/weapon/card/id/I) var/religion_name = "Unitarianism" var/new_religion = sanitize(input(H, "You are the crew services officer. Would you like to change your religion? Default is Unitarianism", "Name change", religion_name), MAX_NAME_LEN) if(!new_religion) @@ -83,18 +77,48 @@ B.name = "Guru Granth Sahib" else B.name = "The Holy Book of [new_religion]" - feedback_set_details("religion_name","[new_religion]") var/deity_name = "Hashem" var/new_deity = sanitize(input(H, "Would you like to change your deity? Default is Hashem", "Name change", deity_name), MAX_NAME_LEN) if((length(new_deity) == 0) || (new_deity == "Hashem")) new_deity = deity_name - B.deity_name = new_deity - GLOB.religion = new_religion - GLOB.bible_name = B.name - GLOB.deity = B.deity_name - feedback_set_details("religion_deity","[new_deity]") - + var/new_title = sanitize(input(H, "Would you like to change your title?", "Title Change", I.assignment), MAX_NAME_LEN) + var/list/all_jobs = get_job_datums() + + // Are they trying to fake an actual existent job + var/faking_job = FALSE + + for (var/datum/job/J in all_jobs) + if (J.title == new_title || (new_title in get_alternate_titles(J.title))) + faking_job = TRUE + + if (length(new_title) != 0 && !faking_job) + I.assignment = new_title + + H.mind.my_religion = new /datum/religion(new_religion, new_deity, B.name, "bible", "bible", new_title) + + B.deity_name = H.mind.my_religion.deity + I.assignment = H.mind.my_religion.title + I.name = text("[I.registered_name]'s ID Card ([I.assignment])") + data_core.manifest_modify(I.registered_name, I.assignment, I.rank) + +/datum/religion + var/religion = "Unitarianism" + var/deity = "Hashem" + var/bible_name = "Bible" + var/bible_icon_state = "bible" + var/bible_item_state = "bible" + var/title = "Chaplain" + var/configured = FALSE + +/datum/religion/New(var/r, var/d, var/bn, var/bis, var/bits, var/t) + . = ..() + religion = r + deity = d + bible_name = bn + bible_icon_state = bis + bible_item_state = bits + title = t \ No newline at end of file diff --git a/code/game/jobs/job/engineering_vr.dm b/code/game/jobs/job/engineering_vr.dm index 86c3f2e6b15..9eda21a90bc 100644 --- a/code/game/jobs/job/engineering_vr.dm +++ b/code/game/jobs/job/engineering_vr.dm @@ -23,17 +23,28 @@ /datum/alt_title/maintenance_manager title = "Maintenance Manager" +/datum/job/chief_engineer/get_request_reasons() + return list("Engine setup", "Construction project", "Repairs necessary") + /datum/job/engineer pto_type = PTO_ENGINEERING alt_titles = list("Maintenance Technician" = /datum/alt_title/maint_tech, "Engine Technician" = /datum/alt_title/engine_tech, - "Electrician" = /datum/alt_title/electrician, "Construction Engineer" = /datum/alt_title/construction_engi) + "Electrician" = /datum/alt_title/electrician, "Construction Engineer" = /datum/alt_title/construction_engi, "Engineering Contractor" = /datum/alt_title/engineering_contractor) /datum/alt_title/construction_engi title = "Construction Engineer" title_blurb = "A Construction Engineer fulfills similar duties to other engineers, but usually occupies spare time with construction of extra facilities in dedicated areas or \ as additions to station layout." +/datum/alt_title/engineering_contractor + title = "Engineering Contractor" + title_blurb = "An Engineering Contractor fulfills similar duties to other engineers, but isn't directly employed by NT proper." + +/datum/job/engineer/get_request_reasons() + return list("Engine setup", "Construction project", "Repairs necessary") + + /datum/job/atmos @@ -49,4 +60,7 @@ /datum/alt_title/disposals_tech title = "Disposals Technician" - title_blurb = "A Disposals Technician is an Atmospheric Technician still and can fulfill all the same duties, although specializes more in disposals delivery system's operations and configurations." \ No newline at end of file + title_blurb = "A Disposals Technician is an Atmospheric Technician still and can fulfill all the same duties, although specializes more in disposals delivery system's operations and configurations." + +/datum/job/atmos/get_request_reasons() + return list("Construction project", "Repairs necessary") \ No newline at end of file diff --git a/code/game/jobs/job/job_vr.dm b/code/game/jobs/job/job_vr.dm index a416a3af489..ac8b6be0b40 100644 --- a/code/game/jobs/job/job_vr.dm +++ b/code/game/jobs/job/job_vr.dm @@ -17,6 +17,11 @@ //Time required in the department as other jobs before playing this one (in hours) var/dept_time_required = 0 + //Do we forbid ourselves from earning PTO? + var/playtime_only = FALSE + + var/requestable = TRUE + // Check client-specific availability rules. /datum/job/proc/player_has_enough_pto(client/C) return timeoff_factor >= 0 || (C && LAZYACCESS(C.department_hours, pto_type) > 0) @@ -39,7 +44,7 @@ if(C && config.use_playtime_restriction_for_jobs && dept_time_required) var/remaining_time_needed = dept_time_required for(var/key in C.play_hours) - if(isnum(C.play_hours[key])) + if(isnum(C.play_hours[key]) && !(key == PTO_TALON)) remaining_time_needed = max(0, remaining_time_needed - C.play_hours[key]) return remaining_time_needed return 0 @@ -55,4 +60,7 @@ if(isnum(C.play_hours[PTO_EXPLORATION])) remaining_time_needed = max(0, remaining_time_needed - C.play_hours[PTO_EXPLORATION]) return remaining_time_needed - return 0 \ No newline at end of file + return 0 + +/datum/job/proc/get_request_reasons() + return list() \ No newline at end of file diff --git a/code/game/jobs/job/medical_vr.dm b/code/game/jobs/job/medical_vr.dm index 6d5ee57c4e4..c3883d18bf0 100644 --- a/code/game/jobs/job/medical_vr.dm +++ b/code/game/jobs/job/medical_vr.dm @@ -21,14 +21,16 @@ /datum/alt_title/healthcare_manager title = "Healthcare Manager" +/datum/job/cmo/get_request_reasons() + return list("Surgery pending", "Viral outbreak") + /datum/job/doctor spawn_positions = 5 pto_type = PTO_MEDICAL alt_titles = list("Physician" = /datum/alt_title/physician, "Medical Practitioner" = /datum/alt_title/medical_practitioner, "Surgeon" = /datum/alt_title/surgeon, "Emergency Physician" = /datum/alt_title/emergency_physician, "Nurse" = /datum/alt_title/nurse, "Orderly" = /datum/alt_title/orderly, - "Virologist" = /datum/alt_title/virologist) - + "Virologist" = /datum/alt_title/virologist, "Medical Contractor" = /datum/alt_title/medical_contractor) /datum/alt_title/physician title = "Physician" @@ -42,6 +44,13 @@ and dirty labor around the department." title_outfit = /decl/hierarchy/outfit/job/medical/doctor/nurse +/datum/alt_title/medical_contractor + title = "Medical Contractor" + title_blurb = "A Medical Contractor can be anything from a full-blown doctor to the likes of a nurse or orderly, but isn't directly employed by NT proper." + +/datum/job/doctor/get_request_reasons() + return list("Surgery pending", "Viral outbreak") + /datum/job/chemist pto_type = PTO_MEDICAL @@ -71,10 +80,13 @@ /datum/job/paramedic pto_type = PTO_MEDICAL - alt_titles = list("Emergency Medical Technician" = /datum/alt_title/emt, "Medical Responder" = /datum/alt_title/medical_responder) + alt_titles = list("Emergency Medical Technician" = /datum/alt_title/emt, "Medical Responder" = /datum/alt_title/medical_responder, "Search and Rescue" = /datum/alt_title/sar) /datum/alt_title/medical_responder title = "Medical Responder" title_blurb = "A Medical Responder is primarily concerned with the recovery of patients who are unable to make it to the Medical Department on their \ own. They are capable of keeping a patient stabilized until they reach the hands of someone with more training." - title_outfit = /decl/hierarchy/outfit/job/medical/paramedic/emt \ No newline at end of file + title_outfit = /decl/hierarchy/outfit/job/medical/paramedic/emt + +/datum/alt_title/sar + title = "Search and Rescue" diff --git a/code/game/jobs/job/security_vr.dm b/code/game/jobs/job/security_vr.dm index 082531d944e..2ab3925c313 100644 --- a/code/game/jobs/job/security_vr.dm +++ b/code/game/jobs/job/security_vr.dm @@ -16,6 +16,9 @@ /datum/alt_title/security_manager title = "Security Manager" +/datum/job/hos/get_request_reasons() + return list("Wildlife management", "Forensic investigation") + /datum/job/warden pto_type = PTO_SECURITY @@ -28,6 +31,9 @@ /datum/alt_title/armory_superintendent title = "Armory Superintendent" +/datum/job/warden/get_request_reasons() + return list("Wildlife management") + /datum/job/detective pto_type = PTO_SECURITY @@ -39,13 +45,16 @@ /datum/alt_title/security_inspector title = "Security Inspector" +/datum/job/detective/get_request_reasons() + return list("Forensic investigation") + /datum/job/officer total_positions = 5 spawn_positions = 5 pto_type = PTO_SECURITY alt_titles = list("Patrol Officer" = /datum/alt_title/patrol_officer, "Security Guard" = /datum/alt_title/security_guard, - "Security Deputy" = /datum/alt_title/security_guard, "Junior Officer" = /datum/alt_title/junior_officer) + "Security Deputy" = /datum/alt_title/security_guard, "Junior Officer" = /datum/alt_title/junior_officer, "Security Contractor" = /datum/alt_title/security_contractor) /datum/alt_title/patrol_officer title = "Patrol Officer" @@ -54,4 +63,10 @@ title = "Security Guard" /datum/alt_title/security_deputy - title = "Security Deputy" \ No newline at end of file + title = "Security Deputy" + +/datum/alt_title/security_contractor + title = "Security Contractor" + +/datum/job/officer/get_request_reasons() + return list("Wildlife management") \ No newline at end of file diff --git a/code/game/jobs/job/special_vr.dm b/code/game/jobs/job/special_vr.dm index 6e3f1df8277..295a2ad2784 100644 --- a/code/game/jobs/job/special_vr.dm +++ b/code/game/jobs/job/special_vr.dm @@ -64,6 +64,7 @@ job_description = "A Clown is there to entertain the crew and keep high morale using various harmless pranks and ridiculous jokes!" whitelist_only = 1 latejoin_only = 0 + requestable = FALSE outfit_type = /decl/hierarchy/outfit/job/clown pto_type = PTO_CIVILIAN alt_titles = list("Jester" = /datum/alt_title/jester, "Fool" = /datum/alt_title/fool) @@ -95,6 +96,7 @@ alt_titles = list("Poseur" = /datum/alt_title/poseur) whitelist_only = 1 latejoin_only = 0 + requestable = FALSE outfit_type = /decl/hierarchy/outfit/job/mime pto_type = PTO_CIVILIAN diff --git a/code/game/machinery/air_alarm.dm b/code/game/machinery/air_alarm.dm index 55b0c0ea2f4..3cb7ac5b343 100644 --- a/code/game/machinery/air_alarm.dm +++ b/code/game/machinery/air_alarm.dm @@ -672,7 +672,7 @@ var/list/selected = TLV["temperature"] var/max_temperature = min(selected[3] - T0C, MAX_TEMPERATURE) var/min_temperature = max(selected[2] - T0C, MIN_TEMPERATURE) - var/input_temperature = input(usr, "What temperature would you like the system to mantain? (Capped between [min_temperature] and [max_temperature]C)", "Thermostat Controls", target_temperature - T0C) as num|null + var/input_temperature = tgui_input_number(usr, "What temperature would you like the system to mantain? (Capped between [min_temperature] and [max_temperature]C)", "Thermostat Controls", target_temperature - T0C, max_temperature, min_temperature) if(isnum(input_temperature)) if(input_temperature > max_temperature || input_temperature < min_temperature) to_chat(usr, "Temperature must be between [min_temperature]C and [max_temperature]C") @@ -726,7 +726,7 @@ var/env = params["env"] var/name = params["var"] - var/value = input(usr, "New [name] for [env]:", name, TLV[env][name]) as num|null + var/value = tgui_input_number(usr, "New [name] for [env]:", name, TLV[env][name]) if(!isnull(value) && !..()) if(value < 0) TLV[env][name] = -1 diff --git a/code/game/machinery/airconditioner_vr.dm b/code/game/machinery/airconditioner_vr.dm index f9a14370419..364d4bf3771 100644 --- a/code/game/machinery/airconditioner_vr.dm +++ b/code/game/machinery/airconditioner_vr.dm @@ -47,7 +47,7 @@ turn_off() return if(istype(I, /obj/item/device/multitool)) - var/new_temp = input(usr, "Input a new target temperature, in degrees C.","Target Temperature", 20) as num + var/new_temp = tgui_input_number(usr, "Input a new target temperature, in degrees C.","Target Temperature", 20) if(!Adjacent(user) || user.incapacitated()) return new_temp = convert_c2k(new_temp) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 06b78eda0f6..4849c780806 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -332,7 +332,7 @@ update_flag pressure = 10*ONE_ATMOSPHERE . = TRUE else if(pressure == "input") - pressure = input(usr, "New release pressure ([ONE_ATMOSPHERE/10]-[10*ONE_ATMOSPHERE] kPa):", name, release_pressure) as num|null + pressure = tgui_input_number(usr, "New release pressure ([ONE_ATMOSPHERE/10]-[10*ONE_ATMOSPHERE] kPa):", name, release_pressure, 10*ONE_ATMOSPHERE, ONE_ATMOSPHERE/10) if(!isnull(pressure) && !..()) . = TRUE else if(text2num(pressure) != null) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index bc8a8081d0c..3e8cf00207a 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -176,7 +176,7 @@ if(!isnull(materials.get_material_amount(material)) && materials.get_material_amount(material) < round(making.resources[material] * coeff)) max_sheets = 0 //Build list of multipliers for sheets. - multiplier = input(usr, "How many do you want to print? (0-[max_sheets])") as num|null + multiplier = tgui_input_number(usr, "How many do you want to print? (0-[max_sheets])", null, null, max_sheets, 0) if(!multiplier || multiplier <= 0 || multiplier > max_sheets || tgui_status(usr, state) != STATUS_INTERACTIVE) return FALSE diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 0660bff7591..a73eb6fe917 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -80,7 +80,7 @@ if(W.is_screwdriver()) playsound(src, W.usesound, 50, 1) - var/input = sanitize(input(usr, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: "+using_map.station_short+",Security,Secret ", "Set Network", camera_network ? camera_network : NETWORK_DEFAULT)) + var/input = sanitize(tgui_input_text(usr, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: "+using_map.station_short+",Security,Secret ", "Set Network", camera_network ? camera_network : NETWORK_DEFAULT)) if(!input) to_chat(usr, "No input found please hang up and try your call again.") return @@ -92,7 +92,7 @@ var/area/camera_area = get_area(src) var/temptag = "[sanitize(camera_area.name)] ([rand(1, 999)])" - input = sanitizeSafe(input(usr, "How would you like to name the camera?", "Set Camera Name", camera_name ? camera_name : temptag), MAX_NAME_LEN) + input = sanitizeSafe(tgui_input_text(usr, "How would you like to name the camera?", "Set Camera Name", camera_name ? camera_name : temptag), MAX_NAME_LEN) state = 4 var/obj/machinery/camera/C = new(src.loc) diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 68ddf03f2b0..fec159f48d4 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -1120,7 +1120,7 @@ // This is not a status display message, since it's something the character // themselves is meant to see BEFORE putting the money in - to_chat(usr, "[bicon(cashmoney)] That is not enough money.") + to_chat(usr, "\icon[cashmoney][bicon(cashmoney)] That is not enough money.") return 0 if(istype(cashmoney, /obj/item/weapon/spacecash)) @@ -1177,7 +1177,7 @@ // Have the customer punch in the PIN before checking if there's enough money. Prevents people from figuring out acct is // empty at high security levels if(customer_account.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) - var/attempt_pin = input(usr, "Enter pin code", "Vendor transaction") as num + var/attempt_pin = tgui_input_number(usr, "Enter pin code", "Vendor transaction") customer_account = attempt_account_access(I.associated_account_number, attempt_pin, 2) if(!customer_account) diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index c15a9d15243..75b860330dd 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -205,7 +205,7 @@ if(is_authenticated() && modify) var/t1 = params["assign_target"] if(t1 == "Custom") - var/temp_t = sanitize(input(usr, "Enter a custom job assignment.","Assignment"), 45) + var/temp_t = sanitize(tgui_input_text(usr, "Enter a custom job assignment.","Assignment"), 45) //let custom jobs function as an impromptu alt title, mainly for sechuds if(temp_t && modify) modify.assignment = temp_t diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index da7548b8bf8..6b6cd3a1aeb 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -107,6 +107,9 @@ /obj/machinery/computer/guestpass/attackby(obj/I, mob/user) + if(istype(I, /obj/item/weapon/card/id/guest)) + to_chat(user, "The guest pass terminal denies to accept the guest pass.") + return if(istype(I, /obj/item/weapon/card/id)) if(!giver && user.unEquip(I)) I.forceMove(src) @@ -167,15 +170,15 @@ mode = params["mode"] if("giv_name") - var/nam = sanitizeName(input(usr, "Person pass is issued to", "Name", giv_name) as text|null) + var/nam = sanitizeName(tgui_input_text(usr, "Person pass is issued to", "Name", giv_name)) if(nam) giv_name = nam if("reason") - var/reas = sanitize(input(usr, "Reason why pass is issued", "Reason", reason) as text|null) + var/reas = sanitize(tgui_input_text(usr, "Reason why pass is issued", "Reason", reason)) if(reas) reason = reas if("duration") - var/dur = input(usr, "Duration (in minutes) during which pass is valid (up to 360 minutes).", "Duration") as num|null //VOREStation Edit + var/dur = tgui_input_number(usr, "Duration (in minutes) during which pass is valid (up to 360 minutes).", "Duration", null, 360, 0) if(dur) if(dur > 0 && dur <= 360) //VOREStation Edit duration = dur diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 5962f9aa8f6..27009d097b2 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -243,10 +243,10 @@ . = TRUE //Change the password - KEY REQUIRED if("pass") - var/dkey = trim(input(usr, "Please enter the current decryption key.") as text|null) + var/dkey = trim(tgui_input_text(usr, "Please enter the current decryption key.")) if(dkey && dkey != "") if(linkedServer.decryptkey == dkey) - var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):")) + var/newkey = trim(tgui_input_text(usr,"Please enter the new key (3 - 16 characters max):",null,null,16)) if(length(newkey) <= 3) set_temp("NOTICE: Decryption key too short!", "average") else if(length(newkey) > 16) @@ -325,7 +325,7 @@ . = TRUE if("addtoken") - linkedServer.spamfilter += input(usr,"Enter text you want to be filtered out","Token creation") as text|null + linkedServer.spamfilter += tgui_input_text(usr,"Enter text you want to be filtered out","Token creation") . = TRUE if("deltoken") diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index fa0a2ebce01..4f2b4fd4e8f 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -82,7 +82,7 @@ to_chat(usr, "Unauthorized Access.") . = TRUE if("warn") - var/warning = sanitize(input(usr, "Message:", "Enter your message here!", "")) + var/warning = sanitize(tgui_input_text(usr, "Message:", "Enter your message here!", "")) if(!warning) return var/obj/item/weapon/implant/I = locate(params["imp"]) diff --git a/code/game/machinery/computer/supply.dm b/code/game/machinery/computer/supply.dm index e805e151bd5..ce345e429e6 100644 --- a/code/game/machinery/computer/supply.dm +++ b/code/game/machinery/computer/supply.dm @@ -221,12 +221,12 @@ visible_message("[src]'s monitor flashes, \"[reqtime - world.time] seconds remaining until another requisition form may be printed.\"") return FALSE - var/amount = clamp(input(usr, "How many crates? (0 to 20)") as num|null, 0, 20) + var/amount = clamp(tgui_input_number(usr, "How many crates? (0 to 20)", null, null, 20, 0), 0, 20) if(!amount) return FALSE var/timeout = world.time + 600 - var/reason = sanitize(input(usr, "Reason:","Why do you require this item?","") as null|text) + var/reason = sanitize(tgui_input_text(usr, "Reason:","Why do you require this item?","")) if(world.time > timeout) to_chat(usr, "Error. Request timed out.") return FALSE @@ -280,7 +280,7 @@ return FALSE var/timeout = world.time + 600 - var/reason = sanitize(input(usr, "Reason:","Why do you require this item?","") as null|text) + var/reason = sanitize(tgui_input_text(usr, "Reason:","Why do you require this item?","")) if(world.time > timeout) to_chat(usr, "Error. Request timed out.") return FALSE @@ -323,7 +323,7 @@ return FALSE if(!(authorization & SUP_ACCEPT_ORDERS)) return FALSE - var/new_val = sanitize(input(usr, params["edit"], "Enter the new value for this field:", params["default"]) as null|text) + var/new_val = sanitize(tgui_input_text(usr, params["edit"], "Enter the new value for this field:", params["default"])) if(!new_val) return FALSE @@ -396,7 +396,7 @@ var/list/L = E.contents[params["index"]] var/field = tgui_alert(usr, "Select which field to edit", "Field Choice", list("Name", "Quantity", "Value")) - var/new_val = sanitize(input(usr, field, "Enter the new value for this field:", L[lowertext(field)]) as null|text) + var/new_val = sanitize(tgui_input_text(usr, field, "Enter the new value for this field:", L[lowertext(field)])) if(!new_val) return @@ -439,7 +439,7 @@ return FALSE if(!(authorization & SUP_ACCEPT_ORDERS)) return FALSE - var/new_val = sanitize(input(usr, params["edit"], "Enter the new value for this field:", params["default"]) as null|text) + var/new_val = sanitize(tgui_input_text(usr, params["edit"], "Enter the new value for this field:", params["default"])) if(!new_val) return diff --git a/code/game/machinery/computer3/computers/card.dm b/code/game/machinery/computer3/computers/card.dm index d2f6074c784..7412f6b4641 100644 --- a/code/game/machinery/computer3/computers/card.dm +++ b/code/game/machinery/computer3/computers/card.dm @@ -305,7 +305,7 @@ if(auth) var/t1 = href_list["assign"] if(t1 == "Custom") - var/temp_t = sanitize(input(usr, "Enter a custom job assignment.","Assignment")) + var/temp_t = sanitize(tgui_input_text(usr, "Enter a custom job assignment.","Assignment")) if(temp_t) t1 = temp_t set_default_access(t1) diff --git a/code/game/machinery/doorbell_vr.dm b/code/game/machinery/doorbell_vr.dm index d90a46000f1..906c41ea6d2 100644 --- a/code/game/machinery/doorbell_vr.dm +++ b/code/game/machinery/doorbell_vr.dm @@ -129,7 +129,7 @@ if(default_deconstruction_screwdriver(user, W)) return else if(panel_open && istype(W, /obj/item/weapon/pen)) - var/t = sanitizeSafe(input(user, "Enter the name for \the [src].", src.name, initial(src.name)), MAX_NAME_LEN) + var/t = sanitizeSafe(tgui_input_text(user, "Enter the name for \the [src].", src.name, initial(src.name), MAX_NAME_LEN), MAX_NAME_LEN) if(t && in_range(src, user)) name = t else if(panel_open && istype(W, /obj/item/device/multitool)) diff --git a/code/game/machinery/gear_dispenser.dm b/code/game/machinery/gear_dispenser.dm index 70c97af29d7..315b56e8479 100644 --- a/code/game/machinery/gear_dispenser.dm +++ b/code/game/machinery/gear_dispenser.dm @@ -693,7 +693,7 @@ var/list/dispenser_presets = list() * "gearlist" = array of types (yes the types are not valid json, byond parses them into real types.) * "req_one_access" = array of numbers (accesses) */ - var/input = input(usr, "Paste new gear pack JSON below. See example/code comments.", "Admin-load Dispenser", example) as null|message + var/input = tgui_input_text(usr, "Paste new gear pack JSON below. See example/code comments.", "Admin-load Dispenser", example, multiline = TRUE) if(!input) return diff --git a/code/game/machinery/jukebox.dm b/code/game/machinery/jukebox.dm index 955b99009a9..0e184683ec0 100644 --- a/code/game/machinery/jukebox.dm +++ b/code/game/machinery/jukebox.dm @@ -401,20 +401,20 @@ return // Required - var/url = input(C, "REQUIRED: Provide URL for track", "Track URL") as text|null + var/url = tgui_input_text(C, "REQUIRED: Provide URL for track", "Track URL") if(!url) return - var/title = input(C, "REQUIRED: Provide title for track", "Track Title") as text|null + var/title = tgui_input_text(C, "REQUIRED: Provide title for track", "Track Title") if(!title) return - var/duration = input(C, "REQUIRED: Provide duration for track (in deciseconds, aka seconds*10)", "Track Duration") as num|null + var/duration = tgui_input_number(C, "REQUIRED: Provide duration for track (in deciseconds, aka seconds*10)", "Track Duration") if(!duration) return // Optional - var/artist = input(C, "Optional: Provide artist for track", "Track Artist") as text|null + var/artist = tgui_input_text(C, "Optional: Provide artist for track", "Track Artist") if(isnull(artist)) // Cancel rather than empty string return @@ -428,7 +428,7 @@ if(!check_rights(R_FUN|R_ADMIN)) return - var/track = input(C, "Input track title or URL to remove (must be exact)", "Remove Track") as text|null + var/track = tgui_input_text(C, "Input track title or URL to remove (must be exact)", "Remove Track") if(!track) return diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 2ea821b3e9f..6152f07df36 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -111,7 +111,7 @@ Class Procs: var/clickvol = 40 // volume var/interact_offline = 0 // Can the machine be interacted with while de-powered. var/obj/item/weapon/circuitboard/circuit = null - + // 0.0 - 1.0 multipler for prob() based on bullet structure damage // So if this is 1.0 then a 100 damage bullet will always break this structure // If this is 0.5 then a 50 damage bullet will break this structure 25% of the time @@ -281,7 +281,7 @@ Class Procs: /obj/machinery/proc/state(var/msg) for(var/mob/O in hearers(src, null)) - O.show_message("[bicon(src)] [msg]", 2) + O.show_message("\icon[src][bicon(src)] [msg]", 2) /obj/machinery/proc/ping(text=null) if(!text) @@ -436,7 +436,7 @@ Class Procs: for(var/obj/I in contents) if(istype(I,/obj/item/weapon/card/id)) I.forceMove(src.loc) - + if(!circuit) return 0 var/obj/structure/frame/A = new /obj/structure/frame(src.loc) @@ -496,7 +496,7 @@ Class Procs: var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() spark_system.set_up(5, 0, src) spark_system.attach(src) - + var/atom/droploc = drop_location() if(!droploc || !contents.len) // not even a circuit? playsound(src, 'sound/machines/machine_die_short.ogg') @@ -510,17 +510,17 @@ Class Procs: if(severity != 1) for(var/obj/item/weapon/card/id/I in contents) surviving_parts |= I - + // May populate some items to throw around if(!LAZYLEN(component_parts) && circuit) circuit.apply_default_parts(src) - + var/survivability switch(severity) // No survivors if(1) survivability = 0 - + // 1 part survives if(2) survivability = 0 @@ -531,15 +531,15 @@ Class Procs: // 50% of parts destroyed on average if(3) survivability = 50 - + // No parts destroyed, but you lose the frame else survivability = 100 - + for(var/atom/movable/P in contents) if(prob(survivability)) surviving_parts |= P - + if(circuit && severity >= 2) var/datum/frame/frame_types/FT = circuit.board_type if(istype(FT)) diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index 603baf20df5..6bfd03372c4 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -314,7 +314,7 @@ if(speed <= 0) speed = 1 if("setpath") - var/newpath = sanitize(input(usr, "Please define a new path!",,path) as text|null) + var/newpath = sanitize(tgui_input_text(usr, "Please define a new path!",,path)) if(newpath && newpath != "") moving = 0 // stop moving path = newpath diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm index 7f200a4d0f7..7e30fc58089 100644 --- a/code/game/machinery/mass_driver.dm +++ b/code/game/machinery/mass_driver.dm @@ -28,7 +28,7 @@ if(istype(I, /obj/item/device/multitool)) if(panel_open) - var/input = sanitize(input(usr, "What id would you like to give this conveyor?", "Multitool-Conveyor interface", id)) + var/input = sanitize(tgui_input_text(usr, "What id would you like to give this conveyor?", "Multitool-Conveyor interface", id)) if(!input) to_chat(usr, "No input found please hang up and try your call again.") return diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index a0e5014606d..056ef1727a8 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -150,7 +150,7 @@ Transponder Codes: