diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..b1d2dbdb58 --- /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 5e9dfae55f..c5587f6042 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 678486f019..9998d5c82b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -3,9 +3,3 @@ # This list is alphabetized by User -> Filename KEEP IT THAT WAY # 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 diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 73e550111f..b8ec75ce5c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,7 +1,7 @@ --- -name: Bug report +name: General Bug report about: Create a report to help us improve -title: '' +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 0000000000..a3aa174357 --- /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 0000000000..83dfec32e7 --- /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/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..9d69be5ecb --- /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 71a53a5b2d..cb6ecabe46 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 1760c46fae..80d46b6f49 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,49 @@ 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: + # YW EDIT start + #strategy: + # matrix: + # map: ['tether', 'stellar_delight', 'groundbase'] + # name: Integration Tests (${{ matrix.map }}) + # YW EDIT: end 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 +95,42 @@ jobs: env: TEST_DEFINE: "UNIT_TEST" TEST_FILE: "code/_unit_tests.dm" + # YW EDIT: start + #MAP: ${{ matrix.map }} + #REPLACE: true + # YW EDIT: end 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" + # YW EDIT: start + #MAP: ${{ matrix.map }} + #REPLACE: false + # YW EDIT: end 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" + # YW EDIT: start + #MAP: ${{ matrix.map }} + #REPLACE: false + # YW EDIT: end RUN: "0" + # YW EDIT: start + #tests_successful: + #name: Integration Tests + #needs: ['file_tests', 'dreamchecker', 'unit_tests'] + #runs-on: ubuntu-latest + #steps: + #- name: Report Success + #run: | + #echo "Jobs Successful!" + # YW EDIT: end diff --git a/.github/workflows/render_nanomaps.yml b/.github/workflows/render_nanomaps.yml index fd5536ea48..57f305772c 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 dc0a34ed43..d282eb9540 100644 --- a/.gitignore +++ b/.gitignore @@ -1,53 +1,57 @@ -#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 -/maps/RandomZLevels/backup/blackmarketpackers.dmm -/maps/backup/virgo-1.dmm -/maps/backup/virgo-2.dmm -/tools/midi2piano/.vs/midi2piano/v14/.suo -/tools/midi2piano/midi2piano/bin/x86/Debug/Sanford.Multimedia.Midi.dll -/tools/midi2piano/midi2piano/bin/x86/Debug/midi2piano.exe -/tools/midi2piano/midi2piano/bin/x86/Debug/midi2piano.pdb -/tools/midi2piano/midi2piano/obj/x86/Debug/DesignTimeResolveAssemblyReferencesInput.cache -/tools/midi2piano/midi2piano/obj/x86/Debug/midi2piano.Form1.resources -/tools/midi2piano/midi2piano/obj/x86/Debug/midi2piano.csproj.FileListAbsolute.txt -/tools/midi2piano/midi2piano/obj/x86/Debug/midi2piano.csproj.GenerateResource.Cache -/tools/midi2piano/midi2piano/obj/x86/Debug/midi2piano.csprojResolveAssemblyReference.cache -/tools/midi2piano/midi2piano/obj/x86/Debug/midi2piano.exe -/tools/midi2piano/midi2piano/obj/x86/Debug/midi2piano.pdb -/maps/backup -/maps/original -/maps/RandomZLevels/backup -/tools/midi2piano.zip -/maps/yw/backup +#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 +node_modules/ +package-lock.json +# YW ADDITION: start +/maps/RandomZLevels/backup/blackmarketpackers.dmm +/maps/backup/virgo-1.dmm +/maps/backup/virgo-2.dmm +/tools/midi2piano/.vs/midi2piano/v14/.suo +/tools/midi2piano/midi2piano/bin/x86/Debug/Sanford.Multimedia.Midi.dll +/tools/midi2piano/midi2piano/bin/x86/Debug/midi2piano.exe +/tools/midi2piano/midi2piano/bin/x86/Debug/midi2piano.pdb +/tools/midi2piano/midi2piano/obj/x86/Debug/DesignTimeResolveAssemblyReferencesInput.cache +/tools/midi2piano/midi2piano/obj/x86/Debug/midi2piano.Form1.resources +/tools/midi2piano/midi2piano/obj/x86/Debug/midi2piano.csproj.FileListAbsolute.txt +/tools/midi2piano/midi2piano/obj/x86/Debug/midi2piano.csproj.GenerateResource.Cache +/tools/midi2piano/midi2piano/obj/x86/Debug/midi2piano.csprojResolveAssemblyReference.cache +/tools/midi2piano/midi2piano/obj/x86/Debug/midi2piano.exe +/tools/midi2piano/midi2piano/obj/x86/Debug/midi2piano.pdb +/maps/backup +/maps/original +/maps/RandomZLevels/backup +/tools/midi2piano.zip +/maps/yw/backup maps/yw/cryogaia-04-maintenance.dmm.before maps/yw/cryogaia-05-main.dmm.before maps/yw/cryogaia-03-transit.dmm.before maps/yw/cryogaia-02-mining.dmm.before maps/yw/cryogaia-01-centcomm.dmm.before maps/yw/residential/residential.dmm.before +# YW ADDITION: end diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 19a0ceb7de..4ce9b60b73 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,5 @@ { "recommendations": [ - "gbasood.byond-dm-language-support", "platymuus.dm-langclient", "stylemistake.auto-comment-blocks", "eamodio.gitlens", @@ -9,6 +8,8 @@ "dbaeumer.vscode-eslint", "editorconfig.editorconfig", "donkie.vscode-tgstation-test-adapter", - "icrawl.discord-vscode" + "icrawl.discord-vscode", + "esbenp.prettier-vscode", + "anturk.dmi-editor" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 64cfc2bb26..6ceb9cb8d4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,36 +1,71 @@ { "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": { "**/.yarn": true, "**/.pnp.*": true }, - "workbench.editorAssociations": { - "*.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/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 7b8b7155f6..686efa6508 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -261,7 +261,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") @@ -272,7 +272,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 665d912b00..514216e7fa 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -225,7 +225,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 dae4648790..1b51693389 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 077be63b30..3487482be3 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/ZAS/Variable Settings.dm b/code/ZAS/Variable Settings.dm index 067fc6d1d8..c4643632dc 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/cooldowns.dm b/code/__defines/cooldowns.dm new file mode 100644 index 0000000000..c3855d7ab3 --- /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 ae3773be74..1ae4237a0d 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 497520f813..9d882883a4 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -173,3 +173,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 27d116999a..c84f88b0ec 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 6ed1384429..9c5896a806 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 d9a5f7a847..df7a90632c 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/tgui.dm b/code/__defines/tgui.dm index c261e5ecdc..1215382ce7 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/_helpers/_lists.dm b/code/_helpers/_lists.dm index c359227f05..85d9472d9a 100644 --- a/code/_helpers/_lists.dm +++ b/code/_helpers/_lists.dm @@ -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 76b1b0d4d8..953df677ab 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() @@ -539,12 +541,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/sanitize_values.dm b/code/_helpers/sanitize_values.dm index 4b521f9bfb..3d04200269 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 bfa7256c9f..79f43551e7 100644 --- a/code/_helpers/text.dm +++ b/code/_helpers/text.dm @@ -408,6 +408,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 +528,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 690e4f1833..ddfcec7421 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 94914550b3..33398d6a87 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. @@ -1364,7 +1365,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) diff --git a/code/_helpers/unsorted_vr.dm b/code/_helpers/unsorted_vr.dm index daf4db48d7..0890c1f9c6 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 d122d9045f..737b317abe 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 14feaf1b5f..f1a7f22248 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 6298747901..642ec99c73 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 40e5977c83..39d36738aa 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 a06df0c082..03fd9bac74 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -422,16 +422,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() diff --git a/code/controllers/subsystems/game_master.dm b/code/controllers/subsystems/game_master.dm index 06a6060227..5315a3dbe8 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/media_tracks.dm b/code/controllers/subsystems/media_tracks.dm index 53805bcbec..58fd0ec858 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 c40a0b0e35..5217b72f9a 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 af096c33a8..c30d559e4b 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/throwing.dm b/code/controllers/subsystems/throwing.dm index 6c3a799b28..101c71a147 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 d5c1094fd3..f5f2ff99b9 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() ) ) @@ -404,14 +404,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 252f1fa789..3d367cb79c 100644 --- a/code/controllers/subsystems/vote.dm +++ b/code/controllers/subsystems/vote.dm @@ -1,394 +1,399 @@ -SUBSYSTEM_DEF(vote) - name = "Vote" - wait = 10 - priority = FIRE_PRIORITY_VOTE - runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT - flags = SS_KEEP_TIMING | SS_NO_INIT - var/list/round_voters = list() - - //Current vote - var/initiator - var/started_time - var/time_remaining - var/duration - var/mode - var/question - var/gamemode_vote_called = FALSE // Have we had a gamemode vote this round? Only auto-call if we haven't - var/list/choices = list() - var/list/gamemode_names = list() - var/list/voted = list() - var/list/current_votes = list() - var/list/additional_text = list() - -/datum/controller/subsystem/vote/fire(resumed) - if(mode) - time_remaining = round((started_time + duration - world.time)/10) - if(mode == VOTE_GAMEMODE && ticker.current_state >= GAME_STATE_SETTING_UP) - to_chat(world, "Gamemode vote aborted: Game has already started.") - reset() - return - if(time_remaining <= 0) - result() - reset() - -/datum/controller/subsystem/vote/proc/autotransfer() - // Before doing the vote, see if anyone is playing. - // If not, just do the transfer. - var/players_are_in_round = FALSE - for(var/mob/living/L as anything in player_list) // Mobs with clients attached. - if(!istype(L)) // Exclude ghosts and other weird things. - continue - if(L.stat == DEAD) // Dead mobs aren't playing. - continue - // Everything else is, however. - players_are_in_round = TRUE - break - - if(!players_are_in_round) - log_debug("The crew transfer shuttle would have been called at vote time due to no players being present.") //YW Edit -// init_shift_change(null, 1) //YW Edit - return - - initiate_vote(VOTE_CREW_TRANSFER, "the server", 1) - log_debug("The server has called a crew transfer vote.") - -/datum/controller/subsystem/vote/proc/autogamemode() - initiate_vote(VOTE_GAMEMODE, "the server", 1) - log_debug("The server has called a gamemode vote.") - -/datum/controller/subsystem/vote/proc/reset() - initiator = null - started_time = null - duration = null - time_remaining = null - mode = null - question = null - choices.Cut() - voted.Cut() - current_votes.Cut() - additional_text.Cut() - -/datum/controller/subsystem/vote/proc/get_result() // Get the highest number of votes - var/greatest_votes = 0 - var/total_votes = 0 - - for(var/option in choices) - var/votes = choices[option] - total_votes += votes - if(votes > greatest_votes) - greatest_votes = votes - - if(!config.vote_no_default && choices.len) // Default-vote for everyone who didn't vote - var/non_voters = (GLOB.clients.len - total_votes) - if(non_voters > 0) - if(mode == VOTE_RESTART) - choices["Continue Playing"] += non_voters - if(choices["Continue Playing"] >= greatest_votes) - greatest_votes = choices["Continue Playing"] - else if(mode == VOTE_GAMEMODE) - if(master_mode in choices) - choices[master_mode] += non_voters - if(choices[master_mode] >= greatest_votes) - greatest_votes = choices[master_mode] - else if(mode == VOTE_CREW_TRANSFER) - var/factor = 0.5 - switch(world.time / (10 * 60)) // minutes - if(0 to 60) - factor = 0.5 - if(61 to 120) - factor = 0.8 - if(121 to 240) - factor = 1 - if(241 to 300) - factor = 1.2 - else - factor = 1.4 - choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor) - to_world("Crew Transfer Factor: [factor]") - greatest_votes = max(choices["Initiate Crew Transfer"], choices["Extend the Shift"]) //VOREStation Edit - - . = list() // Get all options with that many votes and return them in a list - if(greatest_votes) - for(var/option in choices) - if(choices[option] == greatest_votes) - . += option - -/datum/controller/subsystem/vote/proc/announce_result() - var/list/winners = get_result() - var/text - if(winners.len > 0) - if(winners.len > 1) - if(mode != VOTE_GAMEMODE || ticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes - text = "Vote Tied Between:\n" - for(var/option in winners) - text += "\t[option]\n" - . = pick(winners) - - for(var/key in current_votes) - if(choices[current_votes[key]] == .) - round_voters += key // Keep track of who voted for the winning round. - if(mode != VOTE_GAMEMODE || . == "Extended" || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes - text += "Vote Result: [mode == VOTE_GAMEMODE ? gamemode_names[.] : .]" - else - text += "The vote has ended." - - else - text += "Vote Result: Inconclusive - No Votes!" - if(mode == VOTE_ADD_ANTAGONIST) - antag_add_failed = 1 - log_vote(text) - to_chat(world, "[text]") - -/datum/controller/subsystem/vote/proc/result() - . = announce_result() - var/restart = 0 - if(.) - switch(mode) - if(VOTE_RESTART) - if(. == "Restart Round") - restart = 1 - if(VOTE_GAMEMODE) - if(master_mode != .) - world.save_mode(.) - if(ticker && ticker.mode) - restart = 1 - else - master_mode = . - if(VOTE_CREW_TRANSFER) - if(. == "Initiate Crew Transfer") - init_shift_change(null, 1) - if(VOTE_ADD_ANTAGONIST) - if(isnull(.) || . == "None") - antag_add_failed = 1 - else - additional_antag_types |= antag_names_to_ids[.] - - if(mode == VOTE_GAMEMODE) //fire this even if the vote fails. - if(!round_progressing) - round_progressing = 1 - to_world("The round will start soon.") - - if(restart) - to_world("World restarting due to vote...") - feedback_set_details("end_error", "restart vote") - if(blackbox) - blackbox.save_all_data_to_sql() - sleep(50) - log_game("Rebooting due to restart vote") - world.Reboot() - -/datum/controller/subsystem/vote/proc/submit_vote(ckey, newVote) - if(mode) - if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder) - return - if(current_votes[ckey]) - choices[choices[current_votes[ckey]]]-- - if(newVote && newVote >= 1 && newVote <= choices.len) - choices[choices[newVote]]++ - current_votes[ckey] = newVote - else - current_votes[ckey] = null - -/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, automatic = FALSE, time = config.vote_period) - if(!mode) - if(started_time != null && !(check_rights(R_ADMIN|R_EVENT) || automatic)) - var/next_allowed_time = (started_time + config.vote_delay) - if(next_allowed_time > world.time) - return 0 - - reset() - - switch(vote_type) - if(VOTE_RESTART) - choices.Add("Restart Round", "Continue Playing") - if(VOTE_GAMEMODE) - if(ticker.current_state >= GAME_STATE_SETTING_UP) - return 0 - choices.Add(config.votable_modes) - for(var/F in choices) - var/datum/game_mode/M = gamemode_cache[F] - if(!M) - continue - gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works - additional_text.Add("[M.required_players]") - gamemode_names["secret"] = "Secret" - if(VOTE_CREW_TRANSFER) - if(!check_rights(R_ADMIN|R_MOD|R_EVENT, 0)) // The gods care not for the affairs of the mortals - if(get_security_level() == "red" || get_security_level() == "delta") - to_chat(initiator_key, "The current alert status is too high to call for a crew transfer!") - return 0 - if(ticker.current_state <= GAME_STATE_SETTING_UP) - to_chat(initiator_key, "The crew transfer button has been disabled!") - return 0 - question = "Your PDA beeps with a message from Central. Would you like an additional four hours to finish ongoing projects?" //Yawn Wider Edit - choices.Add("Initiate Crew Transfer", "Extend the Shift") //VOREStation Edit - if(VOTE_ADD_ANTAGONIST) - if(!config.allow_extra_antags || ticker.current_state >= GAME_STATE_SETTING_UP) - return 0 - for(var/antag_type in all_antag_types) - var/datum/antagonist/antag = all_antag_types[antag_type] - if(!(antag.id in additional_antag_types) && antag.is_votable()) - choices.Add(antag.role_text) - choices.Add("None") - if(VOTE_CUSTOM) - question = sanitizeSafe(input(usr, "What is the vote for?") as text|null) - 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)) - if(!option || mode || !usr.client) - break - choices.Add(option) - else - return 0 - - mode = vote_type - initiator = initiator_key - started_time = world.time - duration = time - var/text = "[capitalize(mode)] vote started by [initiator]." - if(mode == VOTE_CUSTOM) - text += "\n[question]" - - log_vote(text) - - to_world("[text]\nType vote or click here to place your votes.\nYou have [config.vote_period / 10] seconds to vote.") - if(vote_type == VOTE_CREW_TRANSFER || vote_type == VOTE_GAMEMODE || vote_type == VOTE_CUSTOM) - world << sound('sound/misc/notice1.ogg', repeat = 0, wait = 0, volume = 50, channel = 3) //YW Edit - - - if(mode == VOTE_GAMEMODE && round_progressing) - gamemode_vote_called = TRUE - round_progressing = 0 - to_world("Round start has been delayed.") - - time_remaining = round(config.vote_period / 10) - return 1 - return 0 - -/datum/controller/subsystem/vote/proc/interface(var/client/C) - if(!istype(C)) - return - var/admin = FALSE - if(C.holder) - if(C.holder.rights & R_ADMIN|R_EVENT) - admin = TRUE - - . = "Voting Panel" - if(mode) - if(question) - . += "

    Vote: '[question]'

    " - else - . += "

    Vote: [capitalize(mode)]

    " - . += "Time Left: [time_remaining] s
    " - . += "" - if(mode == VOTE_GAMEMODE) - .+= "" - - for(var/i = 1 to choices.len) - var/votes = choices[choices[i]] - if(!votes) - votes = 0 - . += "" - var/thisVote = (current_votes[C.ckey] == i) - if(mode == VOTE_GAMEMODE) - . += "" - else - . += "" - if (additional_text.len >= i) - . += additional_text[i] - . += "" - - . += "" - - . += "
    ChoicesVotesMinimum Players
    [thisVote ? "" : ""][gamemode_names[choices[i]]][thisVote ? "" : ""][votes][thisVote ? "" : ""][choices[i]][thisVote ? "" : ""][votes]
    Unvote

    " - if(admin) - . += "(Cancel Vote) " - else - . += "

    Start a vote:



    " - - . += "Close" - -/datum/controller/subsystem/vote/Topic(href, href_list[]) - if(!usr || !usr.client) - return - switch(href_list["vote"]) - if("close") - usr << browse(null, "window=vote") - return - - if("cancel") - if(usr.client.holder) - if("Yes" == tgui_alert(usr, "You are about to cancel this vote. Are you sure?", "Cancel Vote", list("No", "Yes"))) - reset() - if("toggle_restart") - if(usr.client.holder) - config.allow_vote_restart = !config.allow_vote_restart - if("toggle_gamemode") - if(usr.client.holder) - config.allow_vote_mode = !config.allow_vote_mode - - if(VOTE_RESTART) - if(config.allow_vote_restart || usr.client.holder) - initiate_vote(VOTE_RESTART, usr.key) - if(VOTE_GAMEMODE) - if(config.allow_vote_mode || usr.client.holder) - initiate_vote(VOTE_GAMEMODE, usr.key) - if(VOTE_CREW_TRANSFER) - if(config.allow_vote_restart || usr.client.holder) - initiate_vote(VOTE_CREW_TRANSFER, usr.key) - if(VOTE_ADD_ANTAGONIST) - if(config.allow_extra_antags || usr.client.holder) - initiate_vote(VOTE_ADD_ANTAGONIST, usr.key) - if(VOTE_CUSTOM) - if(usr.client.holder) - initiate_vote(VOTE_CUSTOM, usr.key) - - if("unvote") - submit_vote(usr.ckey, null) - - else - var/t = round(text2num(href_list["vote"])) - if(t) // It starts from 1, so there's no problem - submit_vote(usr.ckey, t) - usr.client.vote() - -/client/verb/vote() - set category = "OOC" - set name = "Vote" - - if(SSvote) - src << browse(SSvote.interface(src), "window=vote;size=500x[300 + SSvote.choices.len * 25]") +SUBSYSTEM_DEF(vote) + name = "Vote" + wait = 10 + priority = FIRE_PRIORITY_VOTE + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT + flags = SS_KEEP_TIMING | SS_NO_INIT + var/list/round_voters = list() + + //Current vote + var/initiator + var/started_time + var/time_remaining + var/duration + var/mode + var/question + var/gamemode_vote_called = FALSE // Have we had a gamemode vote this round? Only auto-call if we haven't + var/list/choices = list() + var/list/gamemode_names = list() + var/list/voted = list() + var/list/current_votes = list() + var/list/additional_text = list() + +/datum/controller/subsystem/vote/fire(resumed) + if(mode) + time_remaining = round((started_time + duration - world.time)/10) + if(mode == VOTE_GAMEMODE && ticker.current_state >= GAME_STATE_SETTING_UP) + to_chat(world, "Gamemode vote aborted: Game has already started.") + reset() + return + if(time_remaining <= 0) + result() + reset() + +/datum/controller/subsystem/vote/proc/autotransfer() + // Before doing the vote, see if anyone is playing. + // If not, just do the transfer. + var/players_are_in_round = FALSE + for(var/mob/living/L as anything in player_list) // Mobs with clients attached. + if(!istype(L)) // Exclude ghosts and other weird things. + continue + if(L.stat == DEAD) // Dead mobs aren't playing. + continue + // Everything else is, however. + players_are_in_round = TRUE + break + + if(!players_are_in_round) + log_debug("The crew transfer shuttle would have been called at vote time due to no players being present.") //YW Edit +// init_shift_change(null, 1) //YW Edit + return + + initiate_vote(VOTE_CREW_TRANSFER, "the server", 1) + log_debug("The server has called a crew transfer vote.") + +/datum/controller/subsystem/vote/proc/autogamemode() + initiate_vote(VOTE_GAMEMODE, "the server", 1) + log_debug("The server has called a gamemode vote.") + +/datum/controller/subsystem/vote/proc/reset() + initiator = null + started_time = null + duration = null + time_remaining = null + mode = null + question = null + choices.Cut() + voted.Cut() + current_votes.Cut() + additional_text.Cut() + +/datum/controller/subsystem/vote/proc/get_result() // Get the highest number of votes + var/greatest_votes = 0 + var/total_votes = 0 + + for(var/option in choices) + var/votes = choices[option] + total_votes += votes + if(votes > greatest_votes) + greatest_votes = votes + + if(!config.vote_no_default && choices.len) // Default-vote for everyone who didn't vote + var/non_voters = (GLOB.clients.len - total_votes) + if(non_voters > 0) + if(mode == VOTE_RESTART) + choices["Continue Playing"] += non_voters + if(choices["Continue Playing"] >= greatest_votes) + greatest_votes = choices["Continue Playing"] + else if(mode == VOTE_GAMEMODE) + if(master_mode in choices) + choices[master_mode] += non_voters + if(choices[master_mode] >= greatest_votes) + greatest_votes = choices[master_mode] + else if(mode == VOTE_CREW_TRANSFER) + var/factor = 0.5 + switch(world.time / (10 * 60)) // minutes + if(0 to 60) + factor = 0.5 + if(61 to 120) + factor = 0.8 + if(121 to 240) + factor = 1 + if(241 to 300) + factor = 1.2 + else + factor = 1.4 + choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor) + to_world("Crew Transfer Factor: [factor]") + greatest_votes = max(choices["Initiate Crew Transfer"], choices["Extend the Shift"]) //VOREStation Edit + + . = list() // Get all options with that many votes and return them in a list + if(greatest_votes) + for(var/option in choices) + if(choices[option] == greatest_votes) + . += option + +/datum/controller/subsystem/vote/proc/announce_result() + var/list/winners = get_result() + var/text + if(winners.len > 0) + if(winners.len > 1) + if(mode != VOTE_GAMEMODE || ticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes + text = "Vote Tied Between:\n" + for(var/option in winners) + text += "\t[option]\n" + . = pick(winners) + + for(var/key in current_votes) + if(choices[current_votes[key]] == .) + round_voters += key // Keep track of who voted for the winning round. + if(mode != VOTE_GAMEMODE || . == "Extended" || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes + text += "Vote Result: [mode == VOTE_GAMEMODE ? gamemode_names[.] : .]" + else + text += "The vote has ended." + + else + text += "Vote Result: Inconclusive - No Votes!" + if(mode == VOTE_ADD_ANTAGONIST) + antag_add_failed = 1 + log_vote(text) + to_chat(world, "[text]") + +/datum/controller/subsystem/vote/proc/result() + . = announce_result() + var/restart = 0 + if(.) + switch(mode) + if(VOTE_RESTART) + if(. == "Restart Round") + restart = 1 + if(VOTE_GAMEMODE) + if(master_mode != .) + world.save_mode(.) + if(ticker && ticker.mode) + restart = 1 + else + master_mode = . + if(VOTE_CREW_TRANSFER) + if(. == "Initiate Crew Transfer") + init_shift_change(null, 1) + if(VOTE_ADD_ANTAGONIST) + if(isnull(.) || . == "None") + antag_add_failed = 1 + else + additional_antag_types |= antag_names_to_ids[.] + + if(mode == VOTE_GAMEMODE) //fire this even if the vote fails. + if(!round_progressing) + round_progressing = 1 + to_world("The round will start soon.") + + if(restart) + to_world("World restarting due to vote...") + feedback_set_details("end_error", "restart vote") + if(blackbox) + blackbox.save_all_data_to_sql() + sleep(50) + log_game("Rebooting due to restart vote") + world.Reboot() + +/datum/controller/subsystem/vote/proc/submit_vote(ckey, newVote) + if(mode) + if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder) + return + if(current_votes[ckey]) + choices[choices[current_votes[ckey]]]-- + if(newVote && newVote >= 1 && newVote <= choices.len) + choices[choices[newVote]]++ + current_votes[ckey] = newVote + else + current_votes[ckey] = null + +/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, automatic = FALSE, time = config.vote_period) + if(!mode) + if(started_time != null && !(check_rights(R_ADMIN|R_EVENT) || automatic)) + var/next_allowed_time = (started_time + config.vote_delay) + if(next_allowed_time > world.time) + return 0 + + reset() + + switch(vote_type) + if(VOTE_RESTART) + choices.Add("Restart Round", "Continue Playing") + if(VOTE_GAMEMODE) + if(ticker.current_state >= GAME_STATE_SETTING_UP) + return 0 + choices.Add(config.votable_modes) + for(var/F in choices) + var/datum/game_mode/M = gamemode_cache[F] + if(!M) + continue + gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works + additional_text.Add("[M.required_players]") + gamemode_names["secret"] = "Secret" + if(VOTE_CREW_TRANSFER) + if(!check_rights(R_ADMIN|R_MOD|R_EVENT, 0)) // The gods care not for the affairs of the mortals + if(get_security_level() == "red" || get_security_level() == "delta") + to_chat(initiator_key, "The current alert status is too high to call for a crew transfer!") + return 0 + if(ticker.current_state <= GAME_STATE_SETTING_UP) + to_chat(initiator_key, "The crew transfer button has been disabled!") + return 0 + question = "Your PDA beeps with a message from Central. Would you like an additional four hours to finish ongoing projects?" //Yawn Wider Edit + choices.Add("Initiate Crew Transfer", "Extend the Shift") //VOREStation Edit + if(VOTE_ADD_ANTAGONIST) + if(!config.allow_extra_antags || ticker.current_state >= GAME_STATE_SETTING_UP) + return 0 + for(var/antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[antag_type] + if(!(antag.id in additional_antag_types) && antag.is_votable()) + choices.Add(antag.role_text) + choices.Add("None") + if(VOTE_CUSTOM) + 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(tgui_input_text(usr, "Please enter an option or hit cancel to finish"))) + if(!option || mode || !usr.client) + break + choices.Add(option) + else + return 0 + + mode = vote_type + initiator = initiator_key + started_time = world.time + duration = time + var/text = "[capitalize(mode)] vote started by [initiator]." + if(mode == VOTE_CUSTOM) + text += "\n[question]" + + log_vote(text) + + to_world("[text]\nType vote or click here to place your votes.\nYou have [config.vote_period / 10] seconds to vote.") + if(vote_type == VOTE_CREW_TRANSFER || vote_type == VOTE_GAMEMODE || vote_type == VOTE_CUSTOM) + world << sound('sound/misc/notice1.ogg', repeat = 0, wait = 0, volume = 50, channel = 3) //YW Edit + + + if(mode == VOTE_GAMEMODE && round_progressing) + gamemode_vote_called = TRUE + round_progressing = 0 + to_world("Round start has been delayed.") + + time_remaining = round(config.vote_period / 10) + return 1 + return 0 + +/datum/controller/subsystem/vote/proc/interface(var/client/C) + if(!istype(C)) + return + var/admin = FALSE + if(C.holder) + if(C.holder.rights & R_ADMIN|R_EVENT) + admin = TRUE + + . = "Voting Panel" + if(mode) + if(question) + . += "

    Vote: '[question]'

    " + else + . += "

    Vote: [capitalize(mode)]

    " + . += "Time Left: [time_remaining] s
    " + . += "" + if(mode == VOTE_GAMEMODE) + .+= "" + + for(var/i = 1 to choices.len) + var/votes = choices[choices[i]] + if(!votes) + votes = 0 + . += "" + var/thisVote = (current_votes[C.ckey] == i) + if(mode == VOTE_GAMEMODE) + . += "" + else + . += "" + if (additional_text.len >= i) + . += additional_text[i] + . += "" + + . += "" + + . += "
    ChoicesVotesMinimum Players
    [thisVote ? "" : ""][gamemode_names[choices[i]]][thisVote ? "" : ""][votes][thisVote ? "" : ""][choices[i]][thisVote ? "" : ""][votes]
    Unvote

    " + if(admin) + . += "(Cancel Vote) " + else + . += "

    Start a vote:



    " + + . += "Close" + +/datum/controller/subsystem/vote/Topic(href, href_list[]) + if(!usr || !usr.client) + return + switch(href_list["vote"]) + if("close") + usr << browse(null, "window=vote") + return + + if("cancel") + if(usr.client.holder) + if("Yes" == tgui_alert(usr, "You are about to cancel this vote. Are you sure?", "Cancel Vote", list("No", "Yes"))) + reset() + if("toggle_restart") + if(usr.client.holder) + config.allow_vote_restart = !config.allow_vote_restart + if("toggle_gamemode") + if(usr.client.holder) + config.allow_vote_mode = !config.allow_vote_mode + + if(VOTE_RESTART) + if(config.allow_vote_restart || usr.client.holder) + 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) + if(VOTE_CREW_TRANSFER) + if(config.allow_vote_restart || usr.client.holder) + initiate_vote(VOTE_CREW_TRANSFER, usr.key) + if(VOTE_ADD_ANTAGONIST) + if(config.allow_extra_antags || usr.client.holder) + initiate_vote(VOTE_ADD_ANTAGONIST, usr.key) + if(VOTE_CUSTOM) + if(usr.client.holder) + initiate_vote(VOTE_CUSTOM, usr.key) + + if("unvote") + submit_vote(usr.ckey, null) + + else + var/t = round(text2num(href_list["vote"])) + if(t) // It starts from 1, so there's no problem + submit_vote(usr.ckey, t) + usr.client.vote() + +/client/verb/vote() + set category = "OOC" + set name = "Vote" + + if(SSvote) + src << browse(SSvote.interface(src), "window=vote;size=500x[300 + SSvote.choices.len * 25]") diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 75c3c64c7f..fef1bcd25d 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/managed_browsers/feedback_form.dm b/code/datums/managed_browsers/feedback_form.dm index b380018bea..c6160ffc59 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 895bd36fae..0236036338 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 736fdff021..e4ec5954e2 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -190,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 @@ -198,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) @@ -296,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 @@ -314,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 @@ -410,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 diff --git a/code/datums/outfits/jobs/civilian.dm b/code/datums/outfits/jobs/civilian.dm index 1d299a81db..554666cbca 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/materials.dm b/code/datums/supplypacks/materials.dm index 5e181d8af8..3268d05a46 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 6db5602175..66c8a2d4b4 100644 --- a/code/datums/supplypacks/misc_vr.dm +++ b/code/datums/supplypacks/misc_vr.dm @@ -102,6 +102,18 @@ containername = "solgov medical hardsuit crate" //YW EDIT access = access_engine +/* YW EDIT: comments out breacher rig +/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/supply.dm b/code/datums/supplypacks/supply.dm index eff6fb84fd..70f8386a91 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 f1db67a647..f6742fb815 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/defines/procs/announce.dm b/code/defines/procs/announce.dm index 568eb0f743..858875a982 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 84c5b2317e..3dd683377f 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 c2c56c7be1..223db7dda8 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 e1b73b064b..fd3ee867f9 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/atoms.dm b/code/game/atoms.dm index 3df1820fa9..b0703f63a4 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -27,7 +27,7 @@ // Overlays ///Our local copy of (non-priority) overlays without byond magic. Use procs in SSoverlays to manipulate - var/list/our_overlays + var/list/our_overlays ///Overlays that should remain on top and not normally removed when using cut_overlay functions, like c4. var/list/priority_overlays ///vis overlays managed by SSvis_overlays to automaticaly turn them like other overlays @@ -35,7 +35,7 @@ ///Our local copy of filter data so we can add/remove it var/list/filter_data - + //Detective Work, used for the duplicate data points kept in the scanners var/list/original_atom // Track if we are already had initialize() called to prevent double-initialization. @@ -681,7 +681,7 @@ if(!isnull(.)) datum_flags |= DF_VAR_EDITED return - + . = ..() /atom/proc/atom_say(message) @@ -716,7 +716,7 @@ . = ..() 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 3f78c6fba4..238015d6ed 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/gamemodes/changeling/powers/mimic_voice.dm b/code/game/gamemodes/changeling/powers/mimic_voice.dm index 6b84c577ff..be4a055dc1 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 fac7066de4..3ad86499bd 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 cee83656cb..9b31ad9a50 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 88efd6154e..7af06d8d33 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 d8229e1562..2ee412194e 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 aec6442f8d..7c51611bf2 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 cb2a3fcb4b..9b6b532f96 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 dcadf53ffb..ab83319bc5 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/job_vr.dm b/code/game/jobs/job/job_vr.dm index a416a3af48..0f2599b8aa 100644 --- a/code/game/jobs/job/job_vr.dm +++ b/code/game/jobs/job/job_vr.dm @@ -17,6 +17,9 @@ //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 + // 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 +42,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 diff --git a/code/game/jobs/job/medical_vr.dm b/code/game/jobs/job/medical_vr.dm index 6d5ee57c4e..0124acc391 100644 --- a/code/game/jobs/job/medical_vr.dm +++ b/code/game/jobs/job/medical_vr.dm @@ -71,10 +71,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) // YW Edit: removes search and rescue /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" \ No newline at end of file diff --git a/code/game/jobs/job/security_vr.dm b/code/game/jobs/job/security_vr.dm index 082531d944..94f1468b6a 100644 --- a/code/game/jobs/job/security_vr.dm +++ b/code/game/jobs/job/security_vr.dm @@ -45,7 +45,7 @@ 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 +54,7 @@ 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" \ No newline at end of file diff --git a/code/game/machinery/air_alarm.dm b/code/game/machinery/air_alarm.dm index dd653d746a..ca40f0dc53 100644 --- a/code/game/machinery/air_alarm.dm +++ b/code/game/machinery/air_alarm.dm @@ -675,7 +675,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") @@ -729,7 +729,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 f9a1437041..364d4bf377 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 783ee16225..cb11dce0b5 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 0ecc4e8488..aebf87273d 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -1,371 +1,371 @@ -/obj/machinery/autolathe - name = "autolathe" - desc = "It produces items using metal and glass." - icon_state = "autolathe" - density = TRUE - anchored = TRUE - use_power = USE_POWER_IDLE - idle_power_usage = 10 - active_power_usage = 2000 - clicksound = "keyboard" - clickvol = 30 - - circuit = /obj/item/weapon/circuitboard/autolathe - - var/static/datum/category_collection/autolathe/autolathe_recipes - - var/hacked = 0 - var/disabled = 0 - var/shocked = 0 - var/busy = 0 - - var/input_dir = NORTH //YWedit - var/input_dir_name = "North"//YWEdit - - var/mat_efficiency = 1 - var/build_time = 50 - - var/datum/wires/autolathe/wires = null - - var/mb_rating = 0 - var/man_rating = 0 - - var/filtertext - -/obj/machinery/autolathe/Initialize() - AddComponent(/datum/component/material_container, subtypesof(/datum/material), 0, MATCONTAINER_EXAMINE, _after_insert = CALLBACK(src, .proc/AfterMaterialInsert)) - . = ..() - if(!autolathe_recipes) - autolathe_recipes = new() - wires = new(src) - - default_apply_parts() - RefreshParts() - -/obj/machinery/autolathe/Destroy() - qdel(wires) - wires = null - return ..() - -/obj/machinery/autolathe/tgui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "Autolathe", name) - ui.open() - -/obj/machinery/autolathe/tgui_status(mob/user) - if(disabled) - return STATUS_CLOSE - return ..() - -/obj/machinery/autolathe/tgui_static_data(mob/user) - var/list/data = ..() - - var/list/categories = list() - var/list/recipes = list() - for(var/datum/category_group/autolathe/A in autolathe_recipes.categories) - categories += A.name - for(var/datum/category_item/autolathe/M in A.items) - if(M.hidden && !hacked) - continue - if(M.man_rating > man_rating) - continue - recipes.Add(list(list( - "category" = A.name, - "name" = M.name, - "ref" = REF(M), - "requirements" = M.resources, - "hidden" = M.hidden, - "coeff_applies" = !M.no_scale, - "is_stack" = M.is_stack, - ))) - data["recipes"] = recipes - data["categories"] = categories - - return data - -/obj/machinery/autolathe/ui_assets(mob/user) - return list( - get_asset_datum(/datum/asset/spritesheet/sheetmaterials) - ) - -/obj/machinery/autolathe/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) - var/list/data = ..() - data["busy"] = busy - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - data["materials"] = materials.tgui_data() - data["mat_efficiency"] = mat_efficiency - return data - -/obj/machinery/autolathe/interact(mob/user) - if(panel_open) - return wires.Interact(user) - - if(disabled) - to_chat(user, "\The [src] is disabled!") - return - - if(shocked) - shock(user, 50) - - tgui_interact(user) - -/obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(busy) - to_chat(user, "\The [src] is busy. Please wait for completion of previous operation.") - return - - if(default_deconstruction_screwdriver(user, O)) - interact(user) - return - if(default_deconstruction_crowbar(user, O)) - return - if(default_part_replacement(user, O)) - return - - if(stat) - return - - if(panel_open) - //Don't eat multitools or wirecutters used on an open lathe. - if(O.is_multitool() || O.is_wirecutter()) - wires.Interact(user) - return - - if(is_robot_module(O)) - return 0 - - if(istype(O,/obj/item/ammo_magazine/clip) || istype(O,/obj/item/ammo_magazine/s357) || istype(O,/obj/item/ammo_magazine/s38) || istype (O,/obj/item/ammo_magazine/s44)/* VOREstation Edit*/) // Prevents ammo recycling exploit with speedloaders. - to_chat(user, "\The [O] is too hazardous to recycle with the autolathe!") - return - - return ..() - -/obj/machinery/autolathe/attack_hand(mob/user as mob) - user.set_machine(src) - interact(user) - -/obj/machinery/autolathe/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) - if(..()) - return TRUE - - usr.set_machine(src) - add_fingerprint(usr) - - if(busy) - to_chat(usr, "The autolathe is busy. Please wait for completion of previous operation.") - return - switch(action) - if("make") - var/datum/category_item/autolathe/making = locate(params["make"]) - if(!istype(making)) - return - if(making.hidden && !hacked) - return - - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - - var/list/materials_used = list() - - var/multiplier = (params["multiplier"] || 1) - - if(making.is_stack) - var/max_sheets - for(var/material in making.resources) - var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient - var/sheets = round(materials.get_material_amount(material) / round(making.resources[material] * coeff)) - if(isnull(max_sheets) || max_sheets > sheets) - max_sheets = sheets - 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 - if(!multiplier || multiplier <= 0 || multiplier > max_sheets || tgui_status(usr, state) != STATUS_INTERACTIVE) - return FALSE - - //Check if we still have the materials. - var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient - - for(var/datum/material/used_material as anything in making.resources) - var/amount_needed = making.resources[used_material] * coeff * multiplier - materials_used[used_material] = amount_needed - - if(LAZYLEN(materials_used)) - if(!materials.has_materials(materials_used)) - return - - materials.use_materials(materials_used) - - busy = making.name - update_use_power(USE_POWER_ACTIVE) - - update_icon() // So lid closes - - sleep(build_time) - - busy = 0 - update_use_power(USE_POWER_IDLE) - update_icon() // So lid opens - - //Sanity check. - if(!making || !src) - return - - //Create the desired item. - var/obj/item/I = new making.path(src.loc) - - if(LAZYLEN(I.matter)) // Sadly we must obey the laws of equivalent exchange. - I.matter.Cut() - else - I.matter = list() - - for(var/material in making.resources) // Handle the datum's autoscaling for waste, so we're properly wasting material, but not so much if we have efficiency. - I.matter[material] = round(making.resources[material] / (making.no_scale ? 1 : 1.25)) * (making.no_scale ? 1 : mat_efficiency) - - flick("[initial(icon_state)]_finish", src) - if(multiplier > 1) - if(istype(I, /obj/item/stack)) - var/obj/item/stack/S = I - S.set_amount(multiplier) - else - for(multiplier; multiplier > 1; --multiplier) // Create multiple items if it's not a stack. - I = new making.path(src.loc) - // We've already deducted the cost of multiple items. Process the matter the same. - if(LAZYLEN(I.matter)) - I.matter.Cut() - - else - I.matter = list() - - for(var/material in making.resources) - I.matter[material] = round(making.resources[material] / (making.no_scale ? 1 : 1.25)) * (making.no_scale ? 1 : mat_efficiency) - return TRUE - return FALSE - -/obj/machinery/autolathe/update_icon() - cut_overlays() - - icon_state = initial(icon_state) - - if(panel_open) - add_overlay("[icon_state]_panel") - if(stat & NOPOWER) - return - if(busy) - icon_state = "[icon_state]_work" - -//Updates overall lathe storage size. -/obj/machinery/autolathe/RefreshParts() - ..() - mb_rating = 0 - man_rating = 0 - for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts) - mb_rating += MB.rating - for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) - man_rating += M.rating - - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - materials.max_amount = mb_rating * 75000 - - build_time = 50 / man_rating - mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5 - update_tgui_static_data(usr) - -/obj/machinery/autolathe/dismantle() - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - materials.retrieve_all() - return ..() - -/obj/machinery/autolathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted) - flick("autolathe_loading", src)//plays metal insertion animation - // use_power(min(1000, amount_inserted / 100)) - SStgui.update_uis(src) - -/obj/machinery/autolathe/examine(mob/user) - . = ..() - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - if(in_range(user, src) || isobserver(user)) - . += "The status display reads: Storing up to [materials.max_amount] material units.
    Material consumption at [mat_efficiency*100]%.
    " - -//YWAdd start. -/* commented out until i can be assed to actually fix the code -/obj/machinery/autolathe/verb/eatmaterialsnearby() - set name = "Recycle nearby materials" - set category = "Object" - set src in oview(1) - - var/filltype = 0 // Used to determine message. - var/total_used = 0 // Amount of material used. - if(busy) - visible_message("[bicon(src)]\The [src] beeps, \"Autolathe is busy. Please wait for completion of previous operation\"") - return - busy = 1 - for(var/obj/item/eating in get_step(src,input_dir)) - if(istype(eating,/obj/item/ammo_magazine/clip) || istype(eating,/obj/item/ammo_magazine/s357) || istype(eating,/obj/item/ammo_magazine/s38) || istype(eating,/obj/item/ammo_magazine/s44) || istype(eating,/obj/item/stack)) - continue - - if(!eating.matter) - continue - - - var/mass_per_sheet = 0 // Amount of material constituting one sheet. - for(var/material in eating.matter) - - if(isnull(stored_material[material]) || isnull(storage_capacity[material])) - continue - - if(stored_material[material] >= storage_capacity[material]) - continue - - var/total_material = eating.matter[material] - - - if(stored_material[material] + total_material > storage_capacity[material]) - total_material = storage_capacity[material] - stored_material[material] - filltype = 1 - else - filltype = 2 - - stored_material[material] += total_material - total_used += total_material - mass_per_sheet += eating.matter[material] - - if(!filltype) - visible_message("[bicon(src)]\The [src] beeps, \"Storage is full. Operation aborted\"") - break - - flick("autolathe_loading", src) - - if(istype(eating,/obj/item/stack)) - var/obj/item/stack/stack = eating - stack.use(max(1, round(total_used/mass_per_sheet))) // Always use at least 1 to prevent infinite materials. - else - qdel(eating) - sleep(10*mat_efficiency) - - busy = 0 - if(filltype == 1) - visible_message("[bicon(src)] \The [src] beeps, \"Storage capacity full. Operation terminated. Materials recycled: [total_used]\"") - else - visible_message("[bicon(src)] \The [src] beeps, \"All materials recycled. Operation terminated. Materials recycled: [total_used]\"") - - - -/obj/machinery/autolathe/verb/setrecyclepos() - set name = "Set recycle input" - set category = "Object" - set src in oview(1) - - input_dir_name = input("Which direction ?") in list("North", "South", "East", "West") - switch(input_dir_name) - if("North") - input_dir = NORTH - if("South") - input_dir = SOUTH - if("East") - input_dir = EAST - if("West") - input_dir = WEST - to_chat(src, "You set the material input to [input_dir_name]") -*/ +/obj/machinery/autolathe + name = "autolathe" + desc = "It produces items using metal and glass." + icon_state = "autolathe" + density = TRUE + anchored = TRUE + use_power = USE_POWER_IDLE + idle_power_usage = 10 + active_power_usage = 2000 + clicksound = "keyboard" + clickvol = 30 + + circuit = /obj/item/weapon/circuitboard/autolathe + + var/static/datum/category_collection/autolathe/autolathe_recipes + + var/hacked = 0 + var/disabled = 0 + var/shocked = 0 + var/busy = 0 + + var/input_dir = NORTH //YWedit + var/input_dir_name = "North"//YWEdit + + var/mat_efficiency = 1 + var/build_time = 50 + + var/datum/wires/autolathe/wires = null + + var/mb_rating = 0 + var/man_rating = 0 + + var/filtertext + +/obj/machinery/autolathe/Initialize() + AddComponent(/datum/component/material_container, subtypesof(/datum/material), 0, MATCONTAINER_EXAMINE, _after_insert = CALLBACK(src, .proc/AfterMaterialInsert)) + . = ..() + if(!autolathe_recipes) + autolathe_recipes = new() + wires = new(src) + + default_apply_parts() + RefreshParts() + +/obj/machinery/autolathe/Destroy() + qdel(wires) + wires = null + return ..() + +/obj/machinery/autolathe/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Autolathe", name) + ui.open() + +/obj/machinery/autolathe/tgui_status(mob/user) + if(disabled) + return STATUS_CLOSE + return ..() + +/obj/machinery/autolathe/tgui_static_data(mob/user) + var/list/data = ..() + + var/list/categories = list() + var/list/recipes = list() + for(var/datum/category_group/autolathe/A in autolathe_recipes.categories) + categories += A.name + for(var/datum/category_item/autolathe/M in A.items) + if(M.hidden && !hacked) + continue + if(M.man_rating > man_rating) + continue + recipes.Add(list(list( + "category" = A.name, + "name" = M.name, + "ref" = REF(M), + "requirements" = M.resources, + "hidden" = M.hidden, + "coeff_applies" = !M.no_scale, + "is_stack" = M.is_stack, + ))) + data["recipes"] = recipes + data["categories"] = categories + + return data + +/obj/machinery/autolathe/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/sheetmaterials) + ) + +/obj/machinery/autolathe/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + data["busy"] = busy + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + data["materials"] = materials.tgui_data() + data["mat_efficiency"] = mat_efficiency + return data + +/obj/machinery/autolathe/interact(mob/user) + if(panel_open) + return wires.Interact(user) + + if(disabled) + to_chat(user, "\The [src] is disabled!") + return + + if(shocked) + shock(user, 50) + + tgui_interact(user) + +/obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(busy) + to_chat(user, "\The [src] is busy. Please wait for completion of previous operation.") + return + + if(default_deconstruction_screwdriver(user, O)) + interact(user) + return + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) + return + + if(stat) + return + + if(panel_open) + //Don't eat multitools or wirecutters used on an open lathe. + if(O.is_multitool() || O.is_wirecutter()) + wires.Interact(user) + return + + if(is_robot_module(O)) + return 0 + + if(istype(O,/obj/item/ammo_magazine/clip) || istype(O,/obj/item/ammo_magazine/s357) || istype(O,/obj/item/ammo_magazine/s38) || istype (O,/obj/item/ammo_magazine/s44)/* VOREstation Edit*/) // Prevents ammo recycling exploit with speedloaders. + to_chat(user, "\The [O] is too hazardous to recycle with the autolathe!") + return + + return ..() + +/obj/machinery/autolathe/attack_hand(mob/user as mob) + user.set_machine(src) + interact(user) + +/obj/machinery/autolathe/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + usr.set_machine(src) + add_fingerprint(usr) + + if(busy) + to_chat(usr, "The autolathe is busy. Please wait for completion of previous operation.") + return + switch(action) + if("make") + var/datum/category_item/autolathe/making = locate(params["make"]) + if(!istype(making)) + return + if(making.hidden && !hacked) + return + + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + + var/list/materials_used = list() + + var/multiplier = (params["multiplier"] || 1) + + if(making.is_stack) + var/max_sheets + for(var/material in making.resources) + var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient + var/sheets = round(materials.get_material_amount(material) / round(making.resources[material] * coeff)) + if(isnull(max_sheets) || max_sheets > sheets) + max_sheets = sheets + 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 = 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 + + //Check if we still have the materials. + var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient + + for(var/datum/material/used_material as anything in making.resources) + var/amount_needed = making.resources[used_material] * coeff * multiplier + materials_used[used_material] = amount_needed + + if(LAZYLEN(materials_used)) + if(!materials.has_materials(materials_used)) + return + + materials.use_materials(materials_used) + + busy = making.name + update_use_power(USE_POWER_ACTIVE) + + update_icon() // So lid closes + + sleep(build_time) + + busy = 0 + update_use_power(USE_POWER_IDLE) + update_icon() // So lid opens + + //Sanity check. + if(!making || !src) + return + + //Create the desired item. + var/obj/item/I = new making.path(src.loc) + + if(LAZYLEN(I.matter)) // Sadly we must obey the laws of equivalent exchange. + I.matter.Cut() + else + I.matter = list() + + for(var/material in making.resources) // Handle the datum's autoscaling for waste, so we're properly wasting material, but not so much if we have efficiency. + I.matter[material] = round(making.resources[material] / (making.no_scale ? 1 : 1.25)) * (making.no_scale ? 1 : mat_efficiency) + + flick("[initial(icon_state)]_finish", src) + if(multiplier > 1) + if(istype(I, /obj/item/stack)) + var/obj/item/stack/S = I + S.set_amount(multiplier) + else + for(multiplier; multiplier > 1; --multiplier) // Create multiple items if it's not a stack. + I = new making.path(src.loc) + // We've already deducted the cost of multiple items. Process the matter the same. + if(LAZYLEN(I.matter)) + I.matter.Cut() + + else + I.matter = list() + + for(var/material in making.resources) + I.matter[material] = round(making.resources[material] / (making.no_scale ? 1 : 1.25)) * (making.no_scale ? 1 : mat_efficiency) + return TRUE + return FALSE + +/obj/machinery/autolathe/update_icon() + cut_overlays() + + icon_state = initial(icon_state) + + if(panel_open) + add_overlay("[icon_state]_panel") + if(stat & NOPOWER) + return + if(busy) + icon_state = "[icon_state]_work" + +//Updates overall lathe storage size. +/obj/machinery/autolathe/RefreshParts() + ..() + mb_rating = 0 + man_rating = 0 + for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts) + mb_rating += MB.rating + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + man_rating += M.rating + + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + materials.max_amount = mb_rating * 75000 + + build_time = 50 / man_rating + mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5 + update_tgui_static_data(usr) + +/obj/machinery/autolathe/dismantle() + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + materials.retrieve_all() + return ..() + +/obj/machinery/autolathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted) + flick("autolathe_loading", src)//plays metal insertion animation + // use_power(min(1000, amount_inserted / 100)) + SStgui.update_uis(src) + +/obj/machinery/autolathe/examine(mob/user) + . = ..() + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Storing up to [materials.max_amount] material units.
    Material consumption at [mat_efficiency*100]%.
    " + +//YWAdd start. +/* commented out until i can be assed to actually fix the code +/obj/machinery/autolathe/verb/eatmaterialsnearby() + set name = "Recycle nearby materials" + set category = "Object" + set src in oview(1) + + var/filltype = 0 // Used to determine message. + var/total_used = 0 // Amount of material used. + if(busy) + visible_message("[bicon(src)]\The [src] beeps, \"Autolathe is busy. Please wait for completion of previous operation\"") + return + busy = 1 + for(var/obj/item/eating in get_step(src,input_dir)) + if(istype(eating,/obj/item/ammo_magazine/clip) || istype(eating,/obj/item/ammo_magazine/s357) || istype(eating,/obj/item/ammo_magazine/s38) || istype(eating,/obj/item/ammo_magazine/s44) || istype(eating,/obj/item/stack)) + continue + + if(!eating.matter) + continue + + + var/mass_per_sheet = 0 // Amount of material constituting one sheet. + for(var/material in eating.matter) + + if(isnull(stored_material[material]) || isnull(storage_capacity[material])) + continue + + if(stored_material[material] >= storage_capacity[material]) + continue + + var/total_material = eating.matter[material] + + + if(stored_material[material] + total_material > storage_capacity[material]) + total_material = storage_capacity[material] - stored_material[material] + filltype = 1 + else + filltype = 2 + + stored_material[material] += total_material + total_used += total_material + mass_per_sheet += eating.matter[material] + + if(!filltype) + visible_message("[bicon(src)]\The [src] beeps, \"Storage is full. Operation aborted\"") + break + + flick("autolathe_loading", src) + + if(istype(eating,/obj/item/stack)) + var/obj/item/stack/stack = eating + stack.use(max(1, round(total_used/mass_per_sheet))) // Always use at least 1 to prevent infinite materials. + else + qdel(eating) + sleep(10*mat_efficiency) + + busy = 0 + if(filltype == 1) + visible_message("[bicon(src)] \The [src] beeps, \"Storage capacity full. Operation terminated. Materials recycled: [total_used]\"") + else + visible_message("[bicon(src)] \The [src] beeps, \"All materials recycled. Operation terminated. Materials recycled: [total_used]\"") + + + +/obj/machinery/autolathe/verb/setrecyclepos() + set name = "Set recycle input" + set category = "Object" + set src in oview(1) + + input_dir_name = input("Which direction ?") in list("North", "South", "East", "West") + switch(input_dir_name) + if("North") + input_dir = NORTH + if("South") + input_dir = SOUTH + if("East") + input_dir = EAST + if("West") + input_dir = WEST + to_chat(src, "You set the material input to [input_dir_name]") +*/ //YWAdd END. \ No newline at end of file diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 0660bff759..a73eb6fe91 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 1e6cc6030a..5bc0272997 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -1182,7 +1182,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 c15a9d1524..75b860330d 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 fb8507074d..1984171af6 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -170,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 5962f9aa8f..27009d097b 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 ac4868bc17..ceae88e54d 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 e805e151bd..ce345e429e 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 d2f6074c78..7412f6b464 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 d90a46000f..906c41ea6d 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 70c97af29d..315b56e847 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 955b99009a..0e184683ec 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/magnet.dm b/code/game/machinery/magnet.dm index f713cea2d0..e2b76f3632 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 7e6721f109..1002e3fa21 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 90a623d0b9..1e1fff180e 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -150,7 +150,7 @@ Transponder Codes: