diff --git a/.editorconfig b/.editorconfig
index 72e85029ef6..c07643f1122 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -2,21 +2,11 @@
root = true
[*]
-indent_style = tab
-end_of_line = lf
charset = utf-8
-trim_trailing_whitespace = true
+end_of_line = lf
+indent_style = space
insert_final_newline = true
+trim_trailing_whitespace = true
-[*.yml]
-indent_style = space
-indent_size = 2
-
-[*.py]
-indent_style = space
-
-[*.md]
-trim_trailing_whitespace = false
-
-[Dockerfile]
-indent_style = space
+[*.{dm,json,md}]
+indent_style = tab
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 9dc03c27c7e..93617d90cdb 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -8,17 +8,18 @@ These are just guidelines, not rules, use your best judgment and feel free to pr
#### Table Of Contents
[What should I know before I get started?](#what-should-i-know-before-i-get-started)
- * [Code of Conduct](#code-of-conduct)
+
+- [Code of Conduct](#code-of-conduct)
[How Can I Contribute?](#how-can-i-contribute)
- * [Your First Code Contribution](#your-first-code-contribution)
- * [VOREStation Coding Standards](#vorestation-coding-standards)
- * [Pull Requests](#pull-requests)
- * [Git Commit Messages](#git-commit-messages)
+
+- [Your First Code Contribution](#your-first-code-contribution)
+- [VOREStation Coding Standards](#vorestation-coding-standards)
+- [Pull Requests](#pull-requests)
+- [Git Commit Messages](#git-commit-messages)
[Licensing](#Licensing)
-
## What should I know before I get started?
### Code of Conduct
@@ -36,23 +37,24 @@ Unsure where to begin contributing to VOREStation? You can start by looking thro
Any code submissions that do not meet our coding standards are likely to be rejected, or at the very least, have a maintainer request changes on your PR. Save time and follow these standards from the start.
-* Change whitespace as little as possible. Do not randomly add/remove whitespace.
-* Map changes must be in tgm format. See the [Mapmerge2 Readme] for details, or use [StrongDMM] which can automatically save maps as tgm.
+- Change whitespace as little as possible. Do not randomly add/remove whitespace.
+- Map changes must be in tgm format. See the [Mapmerge2 Readme] for details, or use [StrongDMM] which can automatically save maps as tgm.
### Pull Requests
-* Your submission must pass CI checking. The checks are important, prevent many common mistakes, and even experienced coders get caught by it sometimes. If you think there is a bug in CI, open an issue. (One known CI issue is comments in the middle of multi-line lists, just don't do it)
-* Your PR should not have an excessive number of commits unless it is a large project or includes many separate remote commits. If you need to keep tweaking your PR to pass CI or to satisfy a maintainer's requests and are making many commits, you should squash them in the end and update your PR accordingly so these commits don't clog up the history.
-* You can create a WIP PR, and if so, please mark it with [WIP] in the title **and make it a draft pr** so it can be labeled appropriately. These can't sit forever, though.
-* If your pull request has many no-conflict merge commits ('merge from master' into your PR branch), it cannot be merged. Squash and make a new PR/forcepush to your PR branch.
+- Your submission must pass CI checking. The checks are important, prevent many common mistakes, and even experienced coders get caught by it sometimes. If you think there is a bug in CI, open an issue. (One known CI issue is comments in the middle of multi-line lists, just don't do it)
+- Your PR should not have an excessive number of commits unless it is a large project or includes many separate remote commits. If you need to keep tweaking your PR to pass CI or to satisfy a maintainer's requests and are making many commits, you should squash them in the end and update your PR accordingly so these commits don't clog up the history.
+- You can create a WIP PR, and if so, please mark it with [WIP] in the title **and make it a draft pr** so it can be labeled appropriately. These can't sit forever, though.
+- If your pull request has many no-conflict merge commits ('merge from master' into your PR branch), it cannot be merged. Squash and make a new PR/forcepush to your PR branch.
### Git Commit Messages
-* Limit the first line to 72 characters or less, otherwise it truncates the title with '...', wrapping the rest into the description.
-* Reference issues and pull requests liberally.
-* Use the GitHub magic words "Fixed/Fixes/Fix, Resolved/Resolves/Resolve, Closed/Closes/Close", as in, "Closes #1928", as this will automatically close that issue when the PR is merged if it is a fix for that issue.
+- Limit the first line to 72 characters or less, otherwise it truncates the title with '...', wrapping the rest into the description.
+- Reference issues and pull requests liberally.
+- Use the GitHub magic words "Fixed/Fixes/Fix, Resolved/Resolves/Resolve, Closed/Closes/Close", as in, "Closes #1928", as this will automatically close that issue when the PR is merged if it is a fix for that issue.
## Licensing
+
VOREStation is licensed under the GNU Affero General Public License version 3, which can be found in full in LICENSE-AGPL3.txt.
Commits with a git authorship date prior to `1420675200 +0000` (2015/01/08 00:00) are licensed under the GNU General Public License version 3, which can be found in full in LICENSE-GPL3.txt.
diff --git a/.github/ISSUE_TEMPLATE/0-feature.yml b/.github/ISSUE_TEMPLATE/0-feature.yml
index d8adbbed9ca..b11425ae424 100644
--- a/.github/ISSUE_TEMPLATE/0-feature.yml
+++ b/.github/ISSUE_TEMPLATE/0-feature.yml
@@ -1,29 +1,29 @@
name: "✨ New feature"
description: Suggest an idea for this codebase
title: "✨
"
-type: 'feature'
-labels: ['Type: Feature/Suggestion']
+type: "feature"
+labels: ["Type: Feature/Suggestion"]
body:
-- type: textarea
- attributes:
- label: Brief description of the feature
- description: "Please provide a clear and concise description of what the feature should be."
- validations:
- required: true
+ - type: textarea
+ attributes:
+ label: Brief description of the feature
+ description: "Please provide a clear and concise description of what the feature should be."
+ validations:
+ required: true
-- type: textarea
- attributes:
- label: What you want to happen
- description: "Please use as much detail as possible when describing the feature behavior, including any context that might be relevant."
- validations:
- required: false
+ - type: textarea
+ attributes:
+ label: What you want to happen
+ description: "Please use as much detail as possible when describing the feature behavior, including any context that might be relevant."
+ validations:
+ required: false
-- type: textarea
- attributes:
- label: Anything else you may wish to add
- description: |
- Location if it's a mapping issue, screenshots, sprites, etc.
+ - type: textarea
+ attributes:
+ label: Anything else you may wish to add
+ description: |
+ Location if it's a mapping issue, screenshots, sprites, etc.
- Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
- validations:
- required: false
+ Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/1-bug_report.yml b/.github/ISSUE_TEMPLATE/1-bug_report.yml
index 82ae8a0b68e..0553f226602 100644
--- a/.github/ISSUE_TEMPLATE/1-bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/1-bug_report.yml
@@ -1,56 +1,56 @@
name: General Bug
description: Create a report to help us improve
-title: '[GENERAL] '
-type: 'bug'
-labels: 'Type: Bug'
+title: "[GENERAL] "
+type: "bug"
+labels: "Type: Bug"
body:
-- type: textarea
- attributes:
- label: Brief description of the bug
- description: "Please provide a clear and concise description of what the bug is."
- validations:
- required: true
+ - type: textarea
+ attributes:
+ label: Brief description of the bug
+ description: "Please provide a clear and concise description of what the bug is."
+ validations:
+ required: true
-- type: textarea
- attributes:
- label: What you expected to happen
- description: "What normally happens when this occurs? Keep in mind that behavior may be different on other servers."
- validations:
- required: false
+ - type: textarea
+ attributes:
+ label: What you expected to happen
+ description: "What normally happens when this occurs? Keep in mind that behavior may be different on other servers."
+ validations:
+ required: false
-- type: textarea
- attributes:
- label: What actually happened
- description: "Please use as much detail as possible when describing the bug behavior, including any context (things you did before) that might be relevant."
- validations:
- required: false
+ - type: textarea
+ attributes:
+ label: What actually happened
+ description: "Please use as much detail as possible when describing the bug behavior, including any context (things you did before) that might be relevant."
+ validations:
+ required: false
-- type: textarea
- attributes:
- label: Reproduction steps
- description: "How do you trigger this bug? Please walk us through it step by step."
- value: |
- 1.
- 2.
- 3.
- ...
- render: bash
- validations:
- required: true
+ - type: textarea
+ attributes:
+ label: Reproduction steps
+ description: "How do you trigger this bug? Please walk us through it step by step."
+ value: |
+ 1.
+ 2.
+ 3.
+ ...
+ render: bash
+ validations:
+ required: true
-- type: textarea
- attributes:
- label: Server Revision Info
- description: "Copy-paste the entirety of the 'Show Server Revision' verb found under the OOC tab."
- validations:
- required: false
+ - type: textarea
+ attributes:
+ label: Server Revision Info
+ description: "Copy-paste the entirety of the 'Show Server Revision' verb found under the OOC tab."
+ validations:
+ required: false
-- type: textarea
- attributes:
- label: Anything else you may wish to add
- description: |
- Location if it's a mapping issue, screenshots, sprites, etc.
+ - type: textarea
+ attributes:
+ label: Anything else you may wish to add
+ description: |
+ Location if it's a mapping issue, screenshots, sprites, etc.
- Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
- validations:
- required: false
+ Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/2-ui_report.yml b/.github/ISSUE_TEMPLATE/2-ui_report.yml
index 10673160864..137c2114c8b 100644
--- a/.github/ISSUE_TEMPLATE/2-ui_report.yml
+++ b/.github/ISSUE_TEMPLATE/2-ui_report.yml
@@ -1,42 +1,42 @@
name: UI Bug
description: File a bug report, specific to any UI related things.
-title: '[UI] '
-labels: 'Type: Bug'
-type: 'bug'
+title: "[UI] "
+labels: "Type: Bug"
+type: "bug"
body:
-- type: textarea
- attributes:
- label: Brief description of the bug
- description: "Please provide a clear and concise description of what the bug is."
- validations:
- required: true
+ - type: textarea
+ attributes:
+ label: Brief description of the bug
+ description: "Please provide a clear and concise description of what the bug is."
+ validations:
+ required: true
-- type: textarea
- attributes:
- label: Reproduction steps
- description: "How do you trigger this bug? Please walk us through it step by step."
- value: |
- 1.
- 2.
- 3.
- ...
- render: bash
- validations:
- required: true
+ - type: textarea
+ attributes:
+ label: Reproduction steps
+ description: "How do you trigger this bug? Please walk us through it step by step."
+ value: |
+ 1.
+ 2.
+ 3.
+ ...
+ render: bash
+ validations:
+ required: true
-- type: textarea
- attributes:
- label: Server Revision Info
- description: "Copy-paste the entirety of the 'Show Server Revision' verb found under the OOC tab."
- validations:
- required: false
+ - type: textarea
+ attributes:
+ label: Server Revision Info
+ description: "Copy-paste the entirety of the 'Show Server Revision' verb found under the OOC tab."
+ validations:
+ required: false
-- type: textarea
- attributes:
- label: Anything else you may wish to add
- description: |
- Location if it's a mapping issue, screenshots, sprites, etc.
+ - type: textarea
+ attributes:
+ label: Anything else you may wish to add
+ description: |
+ Location if it's a mapping issue, screenshots, sprites, etc.
- Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
- validations:
- required: false
+ Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/3-map_report.yml b/.github/ISSUE_TEMPLATE/3-map_report.yml
index 7354a820d54..e5a9b523598 100644
--- a/.github/ISSUE_TEMPLATE/3-map_report.yml
+++ b/.github/ISSUE_TEMPLATE/3-map_report.yml
@@ -1,56 +1,56 @@
name: Map Bug
description: Create a report, specific to any map related things.
-title: '[MAPPING] '
-type: 'bug'
-labels: ['Type: Bug', 'Type: Map']
+title: "[MAPPING] "
+type: "bug"
+labels: ["Type: Bug", "Type: Map"]
body:
-- type: textarea
- attributes:
- label: Brief description of the bug
- description: "Please provide a clear and concise description of what the bug is."
- validations:
- required: true
+ - type: textarea
+ attributes:
+ label: Brief description of the bug
+ description: "Please provide a clear and concise description of what the bug is."
+ validations:
+ required: true
-- type: textarea
- attributes:
- label: What you expected to happen
- description: "What normally happens when this occurs? Keep in mind that behavior may be different on other servers."
- validations:
- required: false
+ - type: textarea
+ attributes:
+ label: What you expected to happen
+ description: "What normally happens when this occurs? Keep in mind that behavior may be different on other servers."
+ validations:
+ required: false
-- type: textarea
- attributes:
- label: What actually happened
- description: "Please use as much detail as possible when describing the bug behavior, including any context (things you did before) that might be relevant."
- validations:
- required: false
+ - type: textarea
+ attributes:
+ label: What actually happened
+ description: "Please use as much detail as possible when describing the bug behavior, including any context (things you did before) that might be relevant."
+ validations:
+ required: false
-- type: textarea
- attributes:
- label: Reproduction steps
- description: "How do you trigger this bug? Please walk us through it step by step."
- value: |
- 1.
- 2.
- 3.
- ...
- render: bash
- validations:
- required: true
+ - type: textarea
+ attributes:
+ label: Reproduction steps
+ description: "How do you trigger this bug? Please walk us through it step by step."
+ value: |
+ 1.
+ 2.
+ 3.
+ ...
+ render: bash
+ validations:
+ required: true
-- type: textarea
- attributes:
- label: Server Revision Info
- description: "Copy-paste the entirety of the 'Show Server Revision' verb found under the OOC tab."
- validations:
- required: false
+ - type: textarea
+ attributes:
+ label: Server Revision Info
+ description: "Copy-paste the entirety of the 'Show Server Revision' verb found under the OOC tab."
+ validations:
+ required: false
-- type: textarea
- attributes:
- label: Anything else you may wish to add
- description: |
- Location if it's a mapping issue, screenshots, sprites, etc.
+ - type: textarea
+ attributes:
+ label: Anything else you may wish to add
+ description: |
+ Location if it's a mapping issue, screenshots, sprites, etc.
- Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
- validations:
- required: false
+ Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
+ validations:
+ required: false
diff --git a/.github/boring-cyborg.yml b/.github/boring-cyborg.yml
index 9472efeeded..1fcf03a145e 100644
--- a/.github/boring-cyborg.yml
+++ b/.github/boring-cyborg.yml
@@ -6,36 +6,36 @@
labelPRBasedOnFilePath:
# Add 'Type: Map' to any changes to .dmm files
"Type: Map":
- - '**/*.dmm'
+ - "**/*.dmm"
# Add 'Type: Map' to any changes to image files
"Type: Icon":
- - '**/*.dmi'
- - '**/*.png'
- - '**/*.jpg'
+ - "**/*.dmi"
+ - "**/*.png"
+ - "**/*.jpg"
# Add 'Type: Sound' to any change to sound files
"Type: Sound":
- - '**/*.ogg'
- - '**/*.mp3'
- - '**/*.wav'
+ - "**/*.ogg"
+ - "**/*.mp3"
+ - "**/*.wav"
# Add 'Type: Fluff' to any change to *custom_items*
"Type: Fluff":
- - '**/*custom_items*'
- - '**/*loadout_fluff*'
- - 'config/alienwhitelist.txt'
- - 'config/jobwhitelist.txt'
- - 'config/custom_sprites.txt'
+ - "**/*custom_items*"
+ - "**/*loadout_fluff*"
+ - "config/alienwhitelist.txt"
+ - "config/jobwhitelist.txt"
+ - "config/custom_sprites.txt"
# Contains changes to system folders
"Type: .git or .github":
- - '.github/**'
- - '.git/**'
-
+ - ".github/**"
+ - ".git/**"
+
# Contains changes to the TGUI bundle
"Type: TGUI Bundle":
- - 'tgui/public/**'
+ - "tgui/public/**"
##### Greetings ########################################################################################################
# Comment to be posted to welcome users when they open their first PR
@@ -95,7 +95,7 @@ firstIssueWelcomeComment: >
###### PR/Branch Up-To-Date Checker ####################################################################################
# Check if the branch is up to date with master when certain files are modified
#checkUpToDate:
-# # The default branch is "master", change the branch if you want to check against a different target branch
+# # The default branch is "master", change the branch if you want to check against a different target branch
# targetBranch: master
# files:
# # File paths that you want to check for
diff --git a/.github/code_of_conduct.md b/.github/code_of_conduct.md
index 06161256c88..0d17f66bae4 100644
--- a/.github/code_of_conduct.md
+++ b/.github/code_of_conduct.md
@@ -8,19 +8,19 @@ In the interest of fostering an open and welcoming environment, we as contributo
Examples of behavior that contributes to creating a positive environment include:
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
+- Using welcoming and inclusive language
+- Being respectful of differing viewpoints and experiences
+- Gracefully accepting constructive criticism
+- Focusing on what is best for the community
+- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
-* The use of sexualized language or imagery and unwelcome sexual attention or advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a professional setting
+- The use of sexualized language or imagery and unwelcome sexual attention or advances
+- Trolling, insulting/derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or electronic address, without explicit permission
+- Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
diff --git a/.github/stale.yml b/.github/stale.yml
index 7622dac94df..9cd3ffa6088 100644
--- a/.github/stale.yml
+++ b/.github/stale.yml
@@ -7,11 +7,11 @@ daysUntilClose: 30
# - pinned
# - security
# Label to use when marking an issue as stale
-staleLabel: 'Status: No Response'
+staleLabel: "Status: No Response"
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
-closeComment: false
\ No newline at end of file
+closeComment: false
diff --git a/.github/workflows/autochangelog.yml b/.github/workflows/autochangelog.yml
index f6ad147fbf3..3feaaf87c23 100644
--- a/.github/workflows/autochangelog.yml
+++ b/.github/workflows/autochangelog.yml
@@ -13,24 +13,24 @@ jobs:
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true
steps:
- - name: Checkout
- uses: actions/checkout@v4
+ - name: Checkout
+ uses: actions/checkout@v4
- - name: Generate App Token
- id: app-token-generation
- uses: actions/create-github-app-token@v2
- if: env.APP_PRIVATE_KEY != '' && env.APP_ID != ''
- with:
- app-id: ${{ secrets.APP_ID }}
- private-key: ${{ secrets.APP_PRIVATE_KEY }}
- env:
- APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
- APP_ID: ${{ secrets.APP_ID }}
+ - name: Generate App Token
+ id: app-token-generation
+ uses: actions/create-github-app-token@v2
+ if: env.APP_PRIVATE_KEY != '' && env.APP_ID != ''
+ with:
+ app-id: ${{ secrets.APP_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
+ env:
+ APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
+ APP_ID: ${{ secrets.APP_ID }}
- - name: Run auto changelog
- uses: actions/github-script@v7
- with:
- script: |
- const { processAutoChangelog } = await import('${{ github.workspace }}/tools/pull_request_hooks/autoChangelog.js')
- await processAutoChangelog({ github, context })
- github-token: ${{ steps.app-token-generation.outputs.token || secrets.GITHUB_TOKEN }}
+ - name: Run auto changelog
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const { processAutoChangelog } = await import('${{ github.workspace }}/tools/pull_request_hooks/autoChangelog.js')
+ await processAutoChangelog({ github, context })
+ github-token: ${{ steps.app-token-generation.outputs.token || secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a3b0fb7e60d..058a32d65a3 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,7 +18,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
- fetch-depth: 0
+ fetch-depth: 0
# Caches
- name: Setup Bun
uses: ./.github/actions/setup_bun
@@ -113,7 +113,7 @@ jobs:
if: ( !contains(github.event.head_commit.message, '[ci skip]') )
strategy:
matrix:
- map: ['USE_MAP_TETHER', 'USE_MAP_STELLARDELIGHT', 'USE_MAP_GROUNDBASE']
+ map: ["USE_MAP_TETHER", "USE_MAP_STELLARDELIGHT", "USE_MAP_GROUNDBASE"]
# name: Integration Tests (${{ matrix.map }})
name: Integration Tests
# needs: ['run_linters', 'dreamchecker']
@@ -170,7 +170,7 @@ jobs:
tests_successful:
if: ( !contains(github.event.head_commit.message, '[ci skip]') )
name: Integration Tests
- needs: ['run_linters', 'dreamchecker', 'unit_tests', 'extra_map_tests']
+ needs: ["run_linters", "dreamchecker", "unit_tests", "extra_map_tests"]
runs-on: ubuntu-24.04
steps:
- name: Report Success
diff --git a/.github/workflows/compile_changelogs.yml b/.github/workflows/compile_changelogs.yml
index 642ce2df676..83329b1c2de 100644
--- a/.github/workflows/compile_changelogs.yml
+++ b/.github/workflows/compile_changelogs.yml
@@ -2,7 +2,7 @@ name: Compile changelogs
on:
schedule:
- - cron: "0 0 * * *"
+ - cron: "0 0 * * *"
workflow_dispatch:
jobs:
@@ -23,7 +23,7 @@ jobs:
#if: steps.value_holder.outputs.ACTIONS_ENABLED
uses: actions/setup-python@v5
with:
- python-version: '3.x'
+ python-version: "3.x"
- name: "Install deps"
#if: steps.value_holder.outputs.ACTIONS_ENABLED
diff --git a/.github/workflows/remove_guide_comments.yml b/.github/workflows/remove_guide_comments.yml
index 621d860c5cd..2c65239133f 100644
--- a/.github/workflows/remove_guide_comments.yml
+++ b/.github/workflows/remove_guide_comments.yml
@@ -8,11 +8,11 @@ jobs:
remove_guide_comments:
runs-on: ubuntu-latest
steps:
- - name: Checkout
- uses: actions/checkout@v4
- - name: Remove guide comments
- uses: actions/github-script@v7
- with:
- script: |
- const { removeGuideComments } = await import('${{ github.workspace }}/tools/pull_request_hooks/removeGuideComments.js')
- await removeGuideComments({ github, context })
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Remove guide comments
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const { removeGuideComments } = await import('${{ github.workspace }}/tools/pull_request_hooks/removeGuideComments.js')
+ await removeGuideComments({ github, context })
diff --git a/.github/workflows/render_nanomaps.yml b/.github/workflows/render_nanomaps.yml
index dcc33316e37..099d96e7773 100644
--- a/.github/workflows/render_nanomaps.yml
+++ b/.github/workflows/render_nanomaps.yml
@@ -3,13 +3,13 @@
# The file names and locations are VERY important here
# DO NOT EDIT THIS UNLESS YOU KNOW WHAT YOU ARE DOING
# -aa
-name: 'Render Nanomaps'
+name: "Render Nanomaps"
on:
push:
branches:
- master
paths:
- - 'maps/**'
+ - "maps/**"
workflow_dispatch:
permissions: {}
@@ -19,51 +19,51 @@ jobs:
contents: write # to push to branch
pull-requests: write # to create pull requests (repo-sync/pull-request)
- name: 'Generate NanoMaps'
+ name: "Generate NanoMaps"
runs-on: ubuntu-24.04
steps:
- - name: Clone
- uses: actions/checkout@v4
+ - name: Clone
+ uses: actions/checkout@v4
- - name: Branch
- run: |
- git fetch origin
- git branch -f nanomaps_generation
- git checkout nanomaps_generation
- git reset --hard origin/master
- - name: Restore SpacemanDMM cache
- uses: actions/cache@v4
- with:
- path: ~/SpacemanDMM
- key: ${{ runner.os }}-spacemandmm-${{ hashFiles('dependencies.sh') }}
- restore-keys: |
- ${{ runner.os }}-spacemandmm-
- - name: Install Tools
- run: |
- sudo apt update
- bash tools/ci/install_spaceman_dmm.sh dmm-tools
- sudo apt install -y imagemagick
- - name: Ensure +x on github-actions directory
- run: chmod -R +x ./tools/github-actions
+ - name: Branch
+ run: |
+ git fetch origin
+ git branch -f nanomaps_generation
+ git checkout nanomaps_generation
+ git reset --hard origin/master
+ - name: Restore SpacemanDMM cache
+ uses: actions/cache@v4
+ with:
+ path: ~/SpacemanDMM
+ key: ${{ runner.os }}-spacemandmm-${{ hashFiles('dependencies.sh') }}
+ restore-keys: |
+ ${{ runner.os }}-spacemandmm-
+ - name: Install Tools
+ run: |
+ sudo apt update
+ bash tools/ci/install_spaceman_dmm.sh dmm-tools
+ sudo apt install -y imagemagick
+ - name: Ensure +x on github-actions directory
+ run: chmod -R +x ./tools/github-actions
- - name: Generate Maps
- run: tools/github-actions/nanomap-renderer-invoker.sh
+ - name: Generate Maps
+ run: tools/github-actions/nanomap-renderer-invoker.sh
- - name: Commit Maps
- run: |
- git config --local user.email "action@github.com"
- git config --local user.name "NanoMap Generation"
- git add .
- git commit -m "NanoMap Auto-Update (`date`)" -a || true
- git push -f -u origin nanomaps_generation
+ - name: Commit Maps
+ run: |
+ git config --local user.email "action@github.com"
+ git config --local user.name "NanoMap Generation"
+ git add .
+ git commit -m "NanoMap Auto-Update (`date`)" -a || true
+ git push -f -u origin nanomaps_generation
- - name: Create Pull Request
- uses: repo-sync/pull-request@v2
- with:
- source_branch: "nanomaps_generation"
- destination_branch: "master"
- pr_title: "Automatic NanoMap Update"
- pr_body: "This pull request updates the nanomap images to the latest version of the map."
- pr_label: "Infrastructure"
- pr_allow_empty: false
- github_token: ${{ secrets.GITHUB_TOKEN }}
+ - name: Create Pull Request
+ uses: repo-sync/pull-request@v2
+ with:
+ source_branch: "nanomaps_generation"
+ destination_branch: "master"
+ pr_title: "Automatic NanoMap Update"
+ pr_body: "This pull request updates the nanomap images to the latest version of the map."
+ pr_label: "Infrastructure"
+ pr_allow_empty: false
+ github_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.prettierignore b/.prettierignore
index 43eea47231b..bfb94bab391 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -7,6 +7,7 @@ juke
**/build
**/dist
**/node_modules
+html/templates
# File names / types
*.min.*
diff --git a/.prettierrc.yml b/.prettierrc.yml
new file mode 100644
index 00000000000..ce6d6543462
--- /dev/null
+++ b/.prettierrc.yml
@@ -0,0 +1 @@
+# This file is okay being empty as it will tell prettier to run in the repo
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 42b452ee258..9cbb34b3630 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -1,14 +1,14 @@
{
- "recommendations": [
+ "recommendations": [
"gbasood.byond-dm-language-support",
"platymuus.dm-langclient",
"stylemistake.auto-comment-blocks",
"eamodio.gitlens",
"oderwat.indent-rainbow",
"rexebin.darkpurple-black",
- "dbaeumer.vscode-eslint",
"donkie.vscode-tgstation-test-adapter",
"icrawl.discord-vscode",
- "esbenp.prettier-vscode"
+ "esbenp.prettier-vscode",
+ "biomejs.biome"
]
}
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 80b1d58f759..18ec2abd958 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -1,9 +1,9 @@
{
- // Use IntelliSense to learn about possible attributes.
- // Hover to view descriptions of existing attributes.
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": [
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
{
"type": "byond",
"request": "launch",
@@ -40,10 +40,7 @@
"request": "launch",
"program": "${command:dreammaker.returnDreamDaemonPath}",
"cwd": "${workspaceRoot}",
- "args": [
- "${command:dreammaker.getFilenameDmb}",
- "-trusted"
- ],
+ "args": ["${command:dreammaker.getFilenameDmb}", "-trusted"],
"preLaunchTask": "Build All"
},
{
@@ -52,11 +49,8 @@
"request": "launch",
"program": "${command:dreammaker.returnDreamDaemonPath}",
"cwd": "${workspaceRoot}",
- "args": [
- "${command:dreammaker.getFilenameDmb}",
- "-trusted"
- ],
+ "args": ["${command:dreammaker.getFilenameDmb}", "-trusted"],
"preLaunchTask": "Build All (low memory mode)"
}
- ]
+ ]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index ab1c3b2217e..d600dfc6af4 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,73 +1,35 @@
{
- "eslint.workingDirectories": ["./tgui"],
- "workbench.editorAssociations": {
- "*.dmi": "dmiEditor.dmiEditor"
- },
- "editor.codeActionsOnSave": {
- "source.fixAll.eslint": "explicit"
+ "editor.codeActionsOnSave": {
+ "source.fixAll.biome": "explicit"
},
- "files.eol": "\n",
- "files.encoding": "utf8",
- "files.insertFinalNewline": true,
- "files.trimFinalNewlines": true,
- "files.trimTrailingWhitespace": true,
- "files.associations": {
- "*.{dme,dmf,dmm,dm}": "dm",
- },
+ "files.eol": "\n",
+ "files.encoding": "utf8",
+ "files.insertFinalNewline": true,
+ "files.trimFinalNewlines": true,
+ "files.trimTrailingWhitespace": true,
+ "editor.insertSpaces": false,
"git.branchProtection": ["master"],
- "gitlens.advanced.blame.customArguments": [
- "-w", "--ignore-revs-file", ".git-blame-ignore-revs"
- ],
- "search.exclude": {
- "**/node_modules": true,
- },
- "tgstationTestExplorer.project.resultsType": "json",
- "[dm]": {
- "files.eol": "\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],
+ "gitlens.advanced.blame.customArguments": ["-w"],
+ "tgstationTestExplorer.project.resultsType": "json",
+ "[javascript][typescript][javascriptreact][typescriptreact][css][json][jsonc]": {
+ "editor.defaultFormatter": "biomejs.biome",
+ "editor.formatOnSave": true,
+ "editor.rulers": [80]
+ },
+ "[yaml][markdown][html][scss]": {
"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.defaultFormatter": "esbenp.prettier-vscode",
- "editor.formatOnSave": true
- },
- "[typescriptreact]": {
- "editor.rulers": [120],
- "editor.defaultFormatter": "esbenp.prettier-vscode",
- "editor.formatOnSave": true
- },
- "[scss]": {
- "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"
+ "editor.formatOnSave": true,
+ "editor.rulers": [80]
+ },
+ "workbench.editorAssociations": {
+ "*.dmi": "dmiEditor.dmiEditor"
+ },
+ "search.exclude": {
+ "**/node_modules": true
+ },
+ "debug.onTaskErrors": "abort",
+ "dreammaker.objectTreePane": true,
+ "dreammaker.autoUpdate": true,
+ "dreammaker.tickOnCreate": true,
+ "tgstationTestExplorer.project.DMEName": "vorestation.dme"
}
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 5efaf21e8fb..45a6cbb9dcb 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -12,11 +12,7 @@
"DM_EXE": "${config:dreammaker.byondPath}"
}
},
- "problemMatcher": [
- "$dreammaker",
- "$tsc",
- "$eslint-stylish"
- ],
+ "problemMatcher": ["$dreammaker", "$tsc", "$eslint-stylish"],
"group": {
"kind": "build",
"isDefault": true
@@ -37,11 +33,7 @@
"DM_EXE": "${config:dreammaker.byondPath}"
}
},
- "problemMatcher": [
- "$dreammaker",
- "$tsc",
- "$eslint-stylish"
- ],
+ "problemMatcher": ["$dreammaker", "$tsc", "$eslint-stylish"],
"group": {
"kind": "build"
},
@@ -61,11 +53,7 @@
"DM_EXE": "${config:dreammaker.byondPath}"
}
},
- "problemMatcher": [
- "$dreammaker",
- "$tsc",
- "$eslint-stylish"
- ],
+ "problemMatcher": ["$dreammaker", "$tsc", "$eslint-stylish"],
"group": {
"kind": "build"
},
@@ -85,11 +73,7 @@
"DM_EXE": "${config:dreammaker.byondPath}"
}
},
- "problemMatcher": [
- "$dreammaker",
- "$tsc",
- "$eslint-stylish"
- ],
+ "problemMatcher": ["$dreammaker", "$tsc", "$eslint-stylish"],
"group": {
"kind": "build"
},
@@ -109,11 +93,7 @@
"DM_EXE": "${config:dreammaker.byondPath}"
}
},
- "problemMatcher": [
- "$dreammaker",
- "$tsc",
- "$eslint-stylish"
- ],
+ "problemMatcher": ["$dreammaker", "$tsc", "$eslint-stylish"],
"group": {
"kind": "build"
},
@@ -133,11 +113,7 @@
"DM_EXE": "${config:dreammaker.byondPath}"
}
},
- "problemMatcher": [
- "$dreammaker",
- "$tsc",
- "$eslint-stylish"
- ],
+ "problemMatcher": ["$dreammaker", "$tsc", "$eslint-stylish"],
"group": {
"kind": "build"
},
@@ -147,9 +123,7 @@
{
"type": "dreammaker",
"dme": "vorestation.dme",
- "problemMatcher": [
- "$dreammaker"
- ],
+ "problemMatcher": ["$dreammaker"],
"group": "build",
"label": "dm: build - vorestation.dme"
},
@@ -164,10 +138,7 @@
"windows": {
"command": ".\\bin\\tgui-build.cmd"
},
- "problemMatcher": [
- "$tsc",
- "$eslint-stylish"
- ],
+ "problemMatcher": ["$tsc", "$eslint-stylish"],
"group": "build",
"label": "tgui: build"
},
@@ -177,10 +148,7 @@
"windows": {
"command": ".\\bin\\tgui-dev.cmd"
},
- "problemMatcher": [
- "$tsc",
- "$eslint-stylish"
- ],
+ "problemMatcher": ["$tsc", "$eslint-stylish"],
"group": "build",
"label": "tgui: dev server"
},
@@ -190,10 +158,7 @@
"windows": {
"command": ".\\bin\\tgui-bench.cmd"
},
- "problemMatcher": [
- "$tsc",
- "$eslint-stylish"
- ],
+ "problemMatcher": ["$tsc", "$eslint-stylish"],
"group": "build",
"label": "tgui: bench"
},
@@ -203,10 +168,7 @@
"windows": {
"command": ".\\bin\\tgui-sonar.cmd"
},
- "problemMatcher": [
- "$tsc",
- "$eslint-stylish"
- ],
+ "problemMatcher": ["$tsc", "$eslint-stylish"],
"group": "build",
"label": "tgui: sonar"
},
@@ -216,10 +178,7 @@
"windows": {
"command": ".\\bin\\tgfont.cmd"
},
- "problemMatcher": [
- "$tsc",
- "$eslint-stylish"
- ],
+ "problemMatcher": ["$tsc", "$eslint-stylish"],
"group": "build",
"label": "tgui: rebuild tgfont"
}
diff --git a/ATTRIBUTIONS.md b/ATTRIBUTIONS.md
index f1e5784a1ea..ceaf2d56747 100644
--- a/ATTRIBUTIONS.md
+++ b/ATTRIBUTIONS.md
@@ -109,4 +109,4 @@
**Title:** Gooborgs
**Creator / Copyright:** Toriate
**License Holders:** Matica
-**License:** [CC BY-NC-SA 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/)
\ No newline at end of file
+**License:** [CC BY-NC-SA 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/)
diff --git a/README.md b/README.md
index 28724e3d8ce..9a70c8bdcb5 100644
--- a/README.md
+++ b/README.md
@@ -15,13 +15,14 @@ VOREStation is a fork of the Polaris code branch, itself a fork of the Baystatio
---
### LICENSE
+
The code for VOREStation is licensed under the [GNU Affero General Public License](http://www.gnu.org/licenses/agpl.html) version 3, which can be found in full in LICENSE-AGPL3.txt.
Code with a git authorship date prior to `1420675200 +0000` (2015/01/08 00:00) are licensed under the GNU General Public License version 3, which can be found in full in LICENSE-GPL3.txt.
All code whose authorship dates are not prior to `1420675200 +0000` is assumed to be licensed under AGPL v3, if you wish to license under GPL v3 please make this clear in the commit message and any added files.
-If you wish to develop and host this codebase in a closed source manner you may use all code prior to `1420675200 +0000`, which is licensed under GPL v3. The major change here is that if you host a server using any code licensed under AGPLv3 you are required to provide full source code for your servers users as well including addons and modifications you have made.
+If you wish to develop and host this codebase in a closed source manner you may use all code prior to `1420675200 +0000`, which is licensed under GPL v3. The major change here is that if you host a server using any code licensed under AGPLv3 you are required to provide full source code for your servers users as well including addons and modifications you have made.
See [here](https://www.gnu.org/licenses/why-affero-gpl.html) for more information.
@@ -38,11 +39,12 @@ All assets including icons and sound are under a [CC BY-SA 3.0](http://creativec
Attributions and other licenses with links to original works are noted in [ATTRIBUTIONS.md](./ATTRIBUTIONS.md).
### GETTING THE CODE
+
The simplest way to obtain the code is using the github .zip feature. If you do this, you won't be able to make a Pull Request later, though. You'll need to use the git method.
Click [here](https://github.com/VOREStation/VOREStation/archive/master.zip) to get the latest code as a .zip file, then unzip it to wherever you want.
-The more complicated and easier to update method is using git. You'll need to download git or some client from [here](http://git-scm.com/). When that's installed, right click in any folder and click on "Git Bash". When that opens, type in:
+The more complicated and easier to update method is using git. You'll need to download git or some client from [here](http://git-scm.com/). When that's installed, right click in any folder and click on "Git Bash". When that opens, type in:
git clone https://github.com/VOREStation/VOREStation.git
@@ -52,7 +54,7 @@ This will take a while to download, but it provides an easier method for updatin
### INSTALLATION
-First-time installation should be fairly straightforward. First, you'll need BYOND installed. You can get it from [here](http://www.byond.com/).
+First-time installation should be fairly straightforward. First, you'll need BYOND installed. You can get it from [here](http://www.byond.com/).
**The quick way**. Find `bin/server.cmd` in this folder and double click it to automatically build and host the server on port 1337.
@@ -60,17 +62,17 @@ First-time installation should be fairly straightforward. First, you'll need BY
**Building vorestation in DreamMaker directly is deprecated and might produce errors**, such as `'tgui.bundle.js': cannot find file`.
-If you see any errors or warnings, something has gone wrong - possibly a corrupt download or the files extracted wrong, or a code issue on the main repo. Ask on IRC.
+If you see any errors or warnings, something has gone wrong - possibly a corrupt download or the files extracted wrong, or a code issue on the main repo. Ask on IRC.
-Once that's done, open up the config folder. You'll want to edit config.txt to set the probabilities for different gamemodes in Secret and to set your server location so that all your players don't get disconnected at the end of each round. It's recommended you don't turn on the gamemodes with probability 0, as they have various issues and aren't currently being tested, so they may have unknown and bizarre bugs.
+Once that's done, open up the config folder. You'll want to edit config.txt to set the probabilities for different gamemodes in Secret and to set your server location so that all your players don't get disconnected at the end of each round. It's recommended you don't turn on the gamemodes with probability 0, as they have various issues and aren't currently being tested, so they may have unknown and bizarre bugs.
-You'll also want to edit admins.txt to remove the default admins and add your own. "Host" is the highest level of access, and the other recommended admin levels for now are "Game Admin" and "Moderator". The format is:
+You'll also want to edit admins.txt to remove the default admins and add your own. "Host" is the highest level of access, and the other recommended admin levels for now are "Game Admin" and "Moderator". The format is:
byondkey - Rank
-where the BYOND key must be in lowercase and the admin rank must be properly capitalised. There are a bunch more admin ranks, but these two should be enough for most servers, assuming you have trustworthy admins.
+where the BYOND key must be in lowercase and the admin rank must be properly capitalised. There are a bunch more admin ranks, but these two should be enough for most servers, assuming you have trustworthy admins.
-Finally, to start the server, run Dream Daemon and enter the path to your compiled vorestation.dmb file. Make sure to set the port to the one you specified in the config.txt, and set the Security box to 'Trusted'. Then press GO and the server should start up and be ready to join.
+Finally, to start the server, run Dream Daemon and enter the path to your compiled vorestation.dmb file. Make sure to set the port to the one you specified in the config.txt, and set the Security box to 'Trusted'. Then press GO and the server should start up and be ready to join.
---
@@ -99,4 +101,4 @@ For a basic setup, simply copy every file from config/example to config.
### SQL Setup
-The SQL backend for the library and stats tracking requires a MySQL server. Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/tgstation_schema.sql. More detailed setup instructions arecoming soon, for now ask in our Discord.
+The SQL backend for the library and stats tracking requires a MySQL server. Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/tgstation_schema.sql. More detailed setup instructions arecoming soon, for now ask in our Discord.
diff --git a/SECURITY.md b/SECURITY.md
index a47f021db13..35be45b502b 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -10,9 +10,9 @@ Please be as descriptive as possible!
## Older Libraries/Dependencies
-Some of our libraries may not be used in a way that makes
-them vulnerable, because we tend to only use a couple of
-functions out of them. If that's the case and we think that
-your vulnerability won't apply to our use-case, then
-it may be closed, even if we're using an older version
+Some of our libraries may not be used in a way that makes
+them vulnerable, because we tend to only use a couple of
+functions out of them. If that's the case and we think that
+your vulnerability won't apply to our use-case, then
+it may be closed, even if we're using an older version
of the library.
diff --git a/bin/tgui-bench.cmd b/bin/tgui-bench.cmd
deleted file mode 100644
index 333115f7954..00000000000
--- a/bin/tgui-bench.cmd
+++ /dev/null
@@ -1,3 +0,0 @@
-@echo off
-call "%~dp0\..\tools\build\build.bat" --wait-on-error tgui-bench %*
-pause
diff --git a/bin/tgui-fix.cmd b/bin/tgui-fix.cmd
index f2844408ef8..9c5123bd76d 100644
--- a/bin/tgui-fix.cmd
+++ b/bin/tgui-fix.cmd
@@ -1,2 +1,2 @@
@echo off
-call "%~dp0\..\tools\build\build.bat" --wait-on-error tgui-fix %*
+call "%~dp0\..\tools\build\build.bat" --wait-on-error tgui-lint %*
diff --git a/biome.json b/biome.json
new file mode 100644
index 00000000000..81114a5cc9a
--- /dev/null
+++ b/biome.json
@@ -0,0 +1,68 @@
+{
+ "$schema": "https://biomejs.dev/schemas/2.1.1/schema.json",
+ "assist": {
+ "actions": {
+ "source": {
+ "organizeImports": "on"
+ }
+ },
+ "enabled": true
+ },
+ "css": {
+ "formatter": {
+ "quoteStyle": "double"
+ }
+ },
+ "files": {
+ "ignoreUnknown": false,
+ "includes": [
+ "**",
+ "!**/node_modules",
+ "!tgui/public",
+ "tgui/public/tgui.html",
+ "!tgui/packages/tgui-setup/helpers.js"
+ ]
+ },
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "tab",
+ "lineEnding": "lf"
+ },
+ "javascript": {
+ "formatter": {
+ "indentStyle": "space",
+ "quoteStyle": "single"
+ }
+ },
+ "linter": {
+ "enabled": true,
+ "rules": {
+ "recommended": true,
+ "a11y": "off",
+ "correctness": {
+ "noUnusedImports": "warn",
+ "noUnusedVariables": "off",
+ "useExhaustiveDependencies": "off",
+ "noUnusedFunctionParameters": "off",
+ "useHookAtTopLevel": "off"
+ },
+ "security": {
+ "noDangerouslySetInnerHtml": "off"
+ },
+ "style": {
+ "noNonNullAssertion": "off"
+ },
+ "suspicious": {
+ "noArrayIndexKey": "off",
+ "noExplicitAny": "off",
+ "noImplicitAnyLet": "off",
+ "noAssignInExpressions": "warn"
+ }
+ }
+ },
+ "vcs": {
+ "clientKind": "git",
+ "enabled": false,
+ "useIgnoreFile": false
+ }
+}
diff --git a/bun.lock b/bun.lock
new file mode 100644
index 00000000000..d234ff9912a
--- /dev/null
+++ b/bun.lock
@@ -0,0 +1,32 @@
+{
+ "lockfileVersion": 1,
+ "workspaces": {
+ "": {
+ "devDependencies": {
+ "@biomejs/biome": "^2.1.2",
+ "prettier": "^3.6.2",
+ },
+ },
+ },
+ "packages": {
+ "@biomejs/biome": ["@biomejs/biome@2.1.2", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.1.2", "@biomejs/cli-darwin-x64": "2.1.2", "@biomejs/cli-linux-arm64": "2.1.2", "@biomejs/cli-linux-arm64-musl": "2.1.2", "@biomejs/cli-linux-x64": "2.1.2", "@biomejs/cli-linux-x64-musl": "2.1.2", "@biomejs/cli-win32-arm64": "2.1.2", "@biomejs/cli-win32-x64": "2.1.2" }, "bin": { "biome": "bin/biome" } }, "sha512-yq8ZZuKuBVDgAS76LWCfFKHSYIAgqkxVB3mGVVpOe2vSkUTs7xG46zXZeNPRNVjiJuw0SZ3+J2rXiYx0RUpfGg=="],
+
+ "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.1.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-leFAks64PEIjc7MY/cLjE8u5OcfBKkcDB0szxsWUB4aDfemBep1WVKt0qrEyqZBOW8LPHzrFMyDl3FhuuA0E7g=="],
+
+ "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.1.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-Nmmv7wRX5Nj7lGmz0FjnWdflJg4zii8Ivruas6PBKzw5SJX/q+Zh2RfnO+bBnuKLXpj8kiI2x2X12otpH6a32A=="],
+
+ "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.1.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-NWNy2Diocav61HZiv2enTQykbPP/KrA/baS7JsLSojC7Xxh2nl9IczuvE5UID7+ksRy2e7yH7klm/WkA72G1dw=="],
+
+ "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.1.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-qgHvafhjH7Oca114FdOScmIKf1DlXT1LqbOrrbR30kQDLFPEOpBG0uzx6MhmsrmhGiCFCr2obDamu+czk+X0HQ=="],
+
+ "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.1.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Km/UYeVowygTjpX6sGBzlizjakLoMQkxWbruVZSNE6osuSI63i4uCeIL+6q2AJlD3dxoiBJX70dn1enjQnQqwA=="],
+
+ "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.1.2", "", { "os": "linux", "cpu": "x64" }, "sha512-xlB3mU14ZUa3wzLtXfmk2IMOGL+S0aHFhSix/nssWS/2XlD27q+S6f0dlQ8WOCbYoXcuz8BCM7rCn2lxdTrlQA=="],
+
+ "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.1.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-G8KWZli5ASOXA3yUQgx+M4pZRv3ND16h77UsdunUL17uYpcL/UC7RkWTdkfvMQvogVsAuz5JUcBDjgZHXxlKoA=="],
+
+ "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.1.2", "", { "os": "win32", "cpu": "x64" }, "sha512-9zajnk59PMpjBkty3bK2IrjUsUHvqe9HWwyAWQBjGLE7MIBjbX2vwv1XPEhmO2RRuGoTkVx3WCanHrjAytICLA=="],
+
+ "prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
+ }
+}
diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm
index f2b893ad56b..871a0d610ba 100644
--- a/code/_helpers/global_lists.dm
+++ b/code/_helpers/global_lists.dm
@@ -425,7 +425,7 @@ GLOBAL_LIST_INIT(vr_mob_tf_options, list(
"Frog" = /mob/living/simple_mob/vore/aggressive/frog,
"Seagull" =/mob/living/simple_mob/vore/seagull,
"Fox" = /mob/living/simple_mob/animal/passive/fox,
- //"Racoon" = /mob/living/simple_mob/animal/passive/raccoon_ch, //TODO: Port from Downstream
+ "Racoon" = /mob/living/simple_mob/animal/passive/raccoon,
"Shantak" = /mob/living/simple_mob/animal/sif/shantak,
"Goose" = /mob/living/simple_mob/animal/space/goose,
"Space shark" = /mob/living/simple_mob/animal/space/shark,
@@ -488,7 +488,7 @@ GLOBAL_LIST_INIT(vr_mob_spawner_options, list(
"Seagull" =/mob/living/simple_mob/vore/seagull,
"Corgi" = /mob/living/simple_mob/animal/passive/dog/corgi,
//"Armadillo" = /mob/living/simple_mob/animal/passive/armadillo, //TODO: Port from Downstream
- //"Racoon" = /mob/living/simple_mob/animal/passive/raccoon_ch, //TODO: Port from Downstream
+ "Racoon" = /mob/living/simple_mob/animal/passive/raccoon,
"Goose" = /mob/living/simple_mob/animal/space/goose,
"Frog" = /mob/living/simple_mob/vore/aggressive/frog,
"Dust jumper" = /mob/living/simple_mob/vore/alienanimals/dustjumper,
diff --git a/code/controllers/subsystems/mobs.dm b/code/controllers/subsystems/mobs.dm
index cf248b9749b..36043e9748f 100644
--- a/code/controllers/subsystems/mobs.dm
+++ b/code/controllers/subsystems/mobs.dm
@@ -121,14 +121,14 @@ SUBSYSTEM_DEF(mobs)
var/podname = placeofdeath ? placeofdeath.name : "Unknown area"
var/list/data = list(
- "name" = L.real_name,
- "byondkey" = L.key,
- "job" = L.mind.assigned_role,
- "special" = L.mind.special_role,
+ "name" = "[L.real_name]",
+ "byondkey" = "[L.key]",
+ "job" = "[L.mind.assigned_role]",
+ "special" = "[L.mind.special_role]",
"pod" = podname,
"tod" = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss"),
- "laname" = L.lastattacker ? L.lastattacker:real_name : null,
- "lakey" = L.lastattacker ? L.lastattacker:key : null,
+ "laname" = L.lastattacker ? L.lastattacker:real_name : "",
+ "lakey" = L.lastattacker ? L.lastattacker:key : "",
"gender" = L.gender,
"bruteloss" = L.getBruteLoss(),
"fireloss" = L.getFireLoss(),
diff --git a/code/controllers/subsystems/statpanel.dm b/code/controllers/subsystems/statpanel.dm
index f00d1fa6ce6..0639d31400b 100644
--- a/code/controllers/subsystems/statpanel.dm
+++ b/code/controllers/subsystems/statpanel.dm
@@ -148,7 +148,7 @@ SUBSYSTEM_DEF(statpanels)
var/atom/atom_icon = description_holders["icon"]
var/shown_icon = target.examine_icon
- if(!shown_icon)
+ if(!shown_icon && atom_icon)
if(ismob(atom_icon) || length(atom_icon.overlays) > 0)
var/force_south = FALSE
if(isliving(atom_icon))
diff --git a/code/datums/components/COMPONENT_TEMPLATE.md b/code/datums/components/COMPONENT_TEMPLATE.md
index 7b082058885..d458f597cc5 100644
--- a/code/datums/components/COMPONENT_TEMPLATE.md
+++ b/code/datums/components/COMPONENT_TEMPLATE.md
@@ -1,7 +1,6 @@
-
# Template file for your new component
-See _component.dm for detailed explanations
+See \_component.dm for detailed explanations
```dm
/datum/component/mycomponent
diff --git a/code/datums/components/README.md b/code/datums/components/README.md
index db8bf10a327..bb711e795d1 100644
--- a/code/datums/components/README.md
+++ b/code/datums/components/README.md
@@ -4,6 +4,6 @@
Loosely adapted from /vg/. This is an entity component system for adding behaviours to datums when inheritance doesn't quite cut it. By using signals and events instead of direct inheritance, you can inject behaviours without hacky overloads. It requires a different method of thinking, but is not hard to use correctly. If a behaviour can have application across more than one thing. Make it generic, make it a component. Atom/mob/obj event? Give it a signal, and forward it's arguments with a `SendSignal()` call. Now every component that want's to can also know about this happening.
-### [HackMD page for an introduction to the system as a whole.](https://hackmd.io/@tgstation/SignalsComponentsElements)
+### [HackMD page for an introduction to the system as a whole.](https://hackmd.io/@tgstation/SignalsComponentsElements)
-### See/Define signals and their arguments in [__DEFINES\components.dm](../../__DEFINES/components.dm)
+### See/Define signals and their arguments in [\_\_DEFINES\components.dm](../../__DEFINES/components.dm)
diff --git a/code/datums/elements/ELEMENT_TEMPLATE.md b/code/datums/elements/ELEMENT_TEMPLATE.md
index 4bc1f72f2dc..33586bd94e5 100644
--- a/code/datums/elements/ELEMENT_TEMPLATE.md
+++ b/code/datums/elements/ELEMENT_TEMPLATE.md
@@ -1,7 +1,6 @@
-
# Template file for your new element
-See _element.dm for detailed explanations
+See \_element.dm for detailed explanations
```dm
/datum/element/myelement
diff --git a/code/datums/elements/lootable/_lootable.dm b/code/datums/elements/lootable/_lootable.dm
index 76e542d969b..5717091aa90 100644
--- a/code/datums/elements/lootable/_lootable.dm
+++ b/code/datums/elements/lootable/_lootable.dm
@@ -34,7 +34,7 @@ GLOBAL_LIST_INIT(unique_gamma_loot,list(\
UnregisterSignal(target, COMSIG_LOOT_REWARD)
/// Calculates and drops loot, the source's turf is where it will be dropped, L is the searching mob, and searched_by is a passed list for storing who has searched a loot pile.
-/datum/element/lootable/proc/loot(atom/source,mob/living/L,var/list/searched_by)
+/datum/element/lootable/proc/loot(atom/source,mob/living/L,var/list/searched_by, wake_chance = 0)
SIGNAL_HANDLER
// The loot's all gone.
if(loot_depletion && loot_left <= 0)
@@ -91,6 +91,10 @@ GLOBAL_LIST_INIT(unique_gamma_loot,list(\
if("alium")
final_message = span_alium(final_message)
to_chat(L, span_info(final_message))
+ var/disturbed_sleep = rand(1,100) //spawning of mobs, for now only the trash panda.
+ if(disturbed_sleep <= wake_chance)
+ new /mob/living/simple_mob/animal/passive/raccoon(get_turf(source))
+ source.visible_message("A raccoon jumps out of the trash!.")
// Check if we should delete on depletion
if(!loot_depletion)
diff --git a/code/game/objects/structures/trash_pile_vr.dm b/code/game/objects/structures/trash_pile_vr.dm
index a08c2a8933b..da85d3cb920 100644
--- a/code/game/objects/structures/trash_pile_vr.dm
+++ b/code/game/objects/structures/trash_pile_vr.dm
@@ -128,7 +128,7 @@
hider = null
to_chat(user,span_danger("Some sort of creature leaps out of \the [src]!"))
else
- SEND_SIGNAL(src,COMSIG_LOOT_REWARD,user,searchedby)
+ SEND_SIGNAL(src,COMSIG_LOOT_REWARD,user,searchedby, 5)
busy = FALSE
else
return ..()
diff --git a/code/js/view_variables.js b/code/js/view_variables.js
index 86ca8cadc69..1b29528706a 100644
--- a/code/js/view_variables.js
+++ b/code/js/view_variables.js
@@ -1,33 +1,33 @@
function updateSearch() {
- var filter_text = document.getElementById('filter');
- var filter = filter_text.value.toLowerCase();
+ var filter_text = document.getElementById("filter");
+ var filter = filter_text.value.toLowerCase();
- var vars_ol = document.getElementById('vars');
- var lis = vars_ol.children;
- // the above line can be changed to vars_ol.getElementsByTagName("li") to filter child lists too
- // potential todo: implement a per-admin toggle for this
+ var vars_ol = document.getElementById("vars");
+ var lis = vars_ol.children;
+ // the above line can be changed to vars_ol.getElementsByTagName("li") to filter child lists too
+ // potential todo: implement a per-admin toggle for this
- for(var i = 0; i < lis.length; i++) {
- var li = lis[i];
- if(filter == "" || li.innerText.toLowerCase().indexOf(filter) != -1) {
- li.style.display = "block";
- } else {
- li.style.display = "none";
- }
- }
+ for (var i = 0; i < lis.length; i++) {
+ var li = lis[i];
+ if (filter == "" || li.innerText.toLowerCase().indexOf(filter) != -1) {
+ li.style.display = "block";
+ } else {
+ li.style.display = "none";
+ }
+ }
}
function selectTextField() {
- var filter_text = document.getElementById('filter');
- filter_text.focus();
- filter_text.select();
+ var filter_text = document.getElementById("filter");
+ filter_text.focus();
+ filter_text.select();
}
function loadPage(list) {
- if(list.options[list.selectedIndex].value == "") {
- return;
- }
+ if (list.options[list.selectedIndex].value == "") {
+ return;
+ }
- location.href=list.options[list.selectedIndex].value;
- list.selectedIndex = 0;
+ location.href = list.options[list.selectedIndex].value;
+ list.selectedIndex = 0;
}
diff --git a/code/modules/admin/verbs/adminfun.dm b/code/modules/admin/verbs/adminfun.dm
index 9383ceb8d45..5bcbcfdec96 100644
--- a/code/modules/admin/verbs/adminfun.dm
+++ b/code/modules/admin/verbs/adminfun.dm
@@ -60,7 +60,7 @@ ADMIN_VERB(gib_them, (R_ADMIN|R_FUN), "Gib", ADMIN_VERB_NO_DESCRIPTION, ADMIN_CA
victim.gib()
feedback_add_details("admin_verb","GIB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-ADMIN_VERB(gib_self, R_HOLDER, "Gibself", "Give yourself the same treatment you give others.", ADMIN_CATEGORY_FUN)
+ADMIN_VERB(gib_self, R_HOLDER, "Gibself", "Give yourself the same treatment you give others.", "Fun.Do Not")
var/confirm = tgui_alert(user, "You sure?", "Confirm", list("Yes", "No"))
if(!confirm)
return
diff --git a/code/modules/asset_cache/readme.md b/code/modules/asset_cache/readme.md
index 82e6bea896c..b2f8914708b 100644
--- a/code/modules/asset_cache/readme.md
+++ b/code/modules/asset_cache/readme.md
@@ -24,14 +24,12 @@ Call .get_url_mappings() to get an associated list with the urls your assets can
See the documentation for `/datum/asset_transport` for the backend api the asset datums utilize.
-The global variable `SSassets.transport` contains the currently configured transport.
-
-
+The global variable `SSassets.transport` contains the currently configured transport.
### Notes:
Because byond browse() calls use non-blocking queues, if your code uses output() (which bypasses all of these queues) to invoke javascript functions you will need to first have the javascript announce to the server it has loaded before trying to invoke js functions.
-To make your code work with any CDNs configured by the server, you must make sure assets are referenced from the url returned by `get_url_mappings()` or by asset_transport's `get_asset_url()`. (TGUI also has helpers for this.) If this can not be easily done, you can bypass the cdn using legacy assets, see the simple asset datum for details.
+To make your code work with any CDNs configured by the server, you must make sure assets are referenced from the url returned by `get_url_mappings()` or by asset_transport's `get_asset_url()`. (TGUI also has helpers for this.) If this can not be easily done, you can bypass the cdn using legacy assets, see the simple asset datum for details.
CSS files that use url() can be made to use the CDN without needing to rewrite all url() calls in code by using the namespaced helper datum. See the documentation for `/datum/asset/simple/namespaced` for details.
diff --git a/code/modules/asset_cache/validate_assets.html b/code/modules/asset_cache/validate_assets.html
index 9728bb5c285..d55c8892cb1 100644
--- a/code/modules/asset_cache/validate_assets.html
+++ b/code/modules/asset_cache/validate_assets.html
@@ -1,29 +1,31 @@
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/code/modules/awaymissions/overmap_renamer/readme.md b/code/modules/awaymissions/overmap_renamer/readme.md
index e370bbfaebb..eca39b34a03 100644
--- a/code/modules/awaymissions/overmap_renamer/readme.md
+++ b/code/modules/awaymissions/overmap_renamer/readme.md
@@ -1,4 +1,4 @@
-/*
+/\*
How to use - for mappers:
@@ -7,8 +7,8 @@ How to use - for mappers:
There, create a new object as given in the following example:
/obj/effect/landmark/overmap_renamer/debris_field/examplelandmark
- name = "Debris field example landmark that hints at which POI it came from!!!"
- descriptors = list("This element appears when you hover over the obj in the nav console", "if someone manages to examine it", "This is what the printed paper says")
+ name = "Debris field example landmark that hints at which POI it came from!!!"
+ descriptors = list("This element appears when you hover over the obj in the nav console", "if someone manages to examine it", "This is what the printed paper says")
Make sure you use exactly 3 elements, no more and no less and make sure each element is enclosed in a "".
If you want to only change one element, fill in the other ones with the appropriate /obj/effect/overmap/visitable/ subtype's name, desc or scanner_desc your Z level corresponds to.
@@ -21,7 +21,7 @@ How to use - for mappers:
When making such landmarks: reserve them for MAJOR POIs - stuff a ship's scanner might pick up as having a significance.
A small shuttle in the debris field shouldn't get a landmark
The big alien derelict? Now that's worthy of a special landmark!
- The idea of this system is for us to be able to treat existing Z levels as technically different locations.
+ The idea of this system is for us to be able to treat existing Z levels as technically different locations.
Did you want to make an abandoned mining facility overmap adventure? Now this system will let you turn the DF into one (if the dice permits)
Adding a new POI to a brand new lateloaded Z level (you can check which Z levels are handled by the renamer in code\controllers\subsystems\overmap_renamer_vr.dm)
@@ -30,7 +30,7 @@ How to use - for mappers:
Your task will become a bit more difficult now. Create a new .dm file following convention already estabilished with debrisfield_renamer.dm
Within this file, define your /obj/effect/landmark/overmap_renamer/newname here
- add the following line:
+ add the following line:
var/static/reference //leave thus null. The initialization will change this to contain reference to your overmap object instance. Saves us from excess looping
name = "obvious reference to the lateloaded Z in question here"
Within this file, create a new /obj/effect/landmark/overmap_renamer/newname/Initialize()
@@ -44,9 +44,6 @@ How to use - for mappers:
change the if(D == "Debris Field") section in your new if statement just like you did for the landmark!
And you're done! Refer to the "How to add a landmark" section on the top from now on.
-
-
-
Important procs, vars etc. contained within the following files:
@@ -69,10 +66,9 @@ Important procs, vars etc. contained within the following files:
/obj/effect/landmark/overmap_renamer/debris_field/Initialize() - Copy the entire thing, and change the "Debris Field" to your obj's var/unique_identifier
code\controllers\subsystems\overmap_renamer_vr.dm
- /datum/controller/subsystem/overmap_renamer/proc/update_names() - Checks which Z levels are loaded, modifies them
+ /datum/controller/subsystem/overmap_renamer/proc/update_names() - Checks which Z levels are loaded, modifies them
To add new Z levels to the renamer, simply copy the if statement and its contents for debris field,
taking care to change the "Debris Field - Z1 Space" to the name var defined in your lateloaded Z level's map_template datum
example: maps\offmap_vr\common_offmaps.dm and then the /datum/map_template/common_lateload/away_debrisfield
-
-*/
+\*/
diff --git a/code/modules/client/preference_setup/loadout/02_loadout.dm b/code/modules/client/preference_setup/loadout/02_loadout.dm
index c290a2ad0fc..b79d5738199 100644
--- a/code/modules/client/preference_setup/loadout/02_loadout.dm
+++ b/code/modules/client/preference_setup/loadout/02_loadout.dm
@@ -53,7 +53,7 @@ var/list/gear_datums = list()
for(var/j in entries)
entries["[j]"] = path2text_list(entries["[j]"])
pref.gear_list["[i]"] = entries
- pref.gear_slot = save_data["gear_slot"]
+ pref.gear_slot = save_data["gear_slot"] || 1
/datum/category_item/player_setup_item/loadout/loadout/save_character(list/save_data)
var/list/all_gear = list()
diff --git a/code/modules/client/preferences/README.md b/code/modules/client/preferences/README.md
index fabfb779c90..f822667968b 100644
--- a/code/modules/client/preferences/README.md
+++ b/code/modules/client/preferences/README.md
@@ -1,6 +1,6 @@
# Preferences (by Mothblocks)
-This does not contain all the information on specific values--you can find those as doc-comments in relevant paths, such as `/datum/preference`. Rather, this gives you an overview for creating *most* preferences, and getting your foot in the door to create more advanced ones.
+This does not contain all the information on specific values--you can find those as doc-comments in relevant paths, such as `/datum/preference`. Rather, this gives you an overview for creating _most_ preferences, and getting your foot in the door to create more advanced ones.
## Anatomy of a preference (A.K.A. how do I make one?)
@@ -10,6 +10,7 @@ Most preferences consist of two parts:
2. A tgui representation in a TypeScript file.
Every `/datum/preference` requires these three values be set:
+
1. `category` - See [Categories](#Categories).
2. `savefile_key` - The value which will be saved in the savefile. This will also be the identifier for tgui.
3. `savefile_identifier` - Whether or not this is a character specific preference (`PREFERENCE_CHARACTER`) or one that affects the player (`PREFERENCE_PLAYER`). As an example: hair color is `PREFERENCE_CHARACTER` while your UI settings are `PREFERENCE_PLAYER`, since they do not change between characters.
@@ -22,15 +23,15 @@ From here, you will want to write code resembling:
import { Feature } from "../base";
export const savefile_key_here: Feature = {
- name: "Preference Name Here",
- component: Component,
+ name: "Preference Name Here",
+ component: Component,
- // Necessary for game preferences, unused for others
- category: "CATEGORY",
+ // Necessary for game preferences, unused for others
+ category: "CATEGORY",
- // Optional, shown as a tooltip
- description: "This preference will blow your mind!",
-}
+ // Optional, shown as a tooltip
+ description: "This preference will blow your mind!",
+};
```
`T` and `Component` depend on the type of preference you're making. Here are all common examples...
@@ -59,9 +60,9 @@ Your `.tsx` file would look like:
import { Feature, FeatureNumberInput } from "../base";
export const legs: Feature = {
- name: "Legs",
- component: FeatureNumberInput,
-}
+ name: "Legs",
+ component: FeatureNumberInput,
+};
```
## Toggle preferences
@@ -84,12 +85,13 @@ Your `.tsx` file would look like:
import { CheckboxInput, FeatureToggle } from "../base";
export const enable_breathing: FeatureToggle = {
- name: "Enable breathing",
- component: CheckboxInput,
-}
+ name: "Enable breathing",
+ component: CheckboxInput,
+};
```
## Choiced preferences
+
A choiced preference is one where the only options are in a distinct few amount of choices. Examples include skin tone, shirt, and UI style.
To create one, derive from `/datum/preference/choiced`.
@@ -118,14 +120,15 @@ Your `.tsx` file would then look like:
import { FeatureChoiced, FeatureDropdownInput } from "../base";
export const favorite_drink: FeatureChoiced = {
- name: "Favorite drink",
- component: FeatureDropdownInput,
+ name: "Favorite drink",
+ component: FeatureDropdownInput,
};
```
This will create a dropdown input for your preference.
### Choiced preferences - Icons
+
Choiced preferences can generate icons. This is how the clothing/species preferences work, for instance. However, if we just want a basic dropdown input with icons, it would look like this:
```dm
@@ -155,12 +158,13 @@ Then, change your `.tsx` file to look like:
import { FeatureChoiced, FeatureIconnedDropdownInput } from "../base";
export const favorite_drink: FeatureChoiced = {
- name: "Favorite drink",
- component: FeatureIconnedDropdownInput,
+ name: "Favorite drink",
+ component: FeatureIconnedDropdownInput,
};
```
### Choiced preferences - Display names
+
Sometimes the values you want to save in code aren't the same as the ones you want to display. You can specify display names to change this.
The only thing you will add is "compiled data".
@@ -182,7 +186,8 @@ The only thing you will add is "compiled data".
Your `.tsx` file does not change. The UI will figure it out for you!
## Color preferences
-These refer to colors, such as your OOC color. When read, these values will be given as 6 hex digits, *without* the pound sign.
+
+These refer to colors, such as your OOC color. When read, these values will be given as 6 hex digits, _without_ the pound sign.
```dm
/datum/preference/color/eyeliner_color
@@ -197,12 +202,13 @@ Your `.tsx` file would look like:
import { FeatureColorInput, Feature } from "../base";
export const eyeliner_color: Feature = {
- name: "Eyeliner color",
- component: FeatureColorInput,
+ name: "Eyeliner color",
+ component: FeatureColorInput,
};
```
## Name preferences
+
These refer to an alternative name. Examples include AI names and backup human names.
These exist in `code/modules/client/preferences/names.dm`.
@@ -255,6 +261,7 @@ If your preference is `PREFERENCE_CHARACTER`, it MUST override `apply_to_human`,
You can also read preferences directly with `prefs.read_preference(/datum/preference/type/here)`, which will return the stored value.
## Categories
+
Every preference needs to be in a `category`. These can be found in `code/__DEFINES/preferences.dm`.
```dm
@@ -306,7 +313,7 @@ Compiled data is sent to the `serverData` field in the `FeatureValueProps`.
If you have good knowledge with tgui (especially TypeScript), you'll be able to create your own component to represent preferences.
-The `component` field in a feature accepts __any__ component that accepts `FeatureValueProps`.
+The `component` field in a feature accepts **any** component that accepts `FeatureValueProps`.
This will give you the fields:
@@ -335,18 +342,21 @@ For a basic example of how this can look, observe `CheckboxInput`:
```tsx
export const CheckboxInput = (
- props: FeatureValueProps
+ props: FeatureValueProps,
) => {
- return ( {
- props.handleSetValue(!props.value);
- }}
- />);
+ return (
+ {
+ props.handleSetValue(!props.value);
+ }}
+ />
+ );
};
```
## Advanced - Middleware
+
A `/datum/preference_middleware` is a way to inject your own data at specific points, as well as hijack actions.
Middleware can hijack actions by specifying `action_delegations`:
@@ -422,20 +432,20 @@ import { Antagonist, Category } from "../base";
import { multiline } from "common/string";
const Changeling: Antagonist = {
- key: "changeling", // This must be the same as your filename
- name: "Changeling",
- description: [
- multiline`
+ key: "changeling", // This must be the same as your filename
+ name: "Changeling",
+ description: [
+ multiline`
A highly intelligent alien predator that is capable of altering their
shape to flawlessly resemble a human.
`,
- multiline`
+ multiline`
Transform yourself or others into different identities, and buy from an
arsenal of biological weaponry with the DNA you collect.
`,
- ],
- category: Category.Roundstart, // Category.Roundstart, Category.Midround, or Category.Latejoin
+ ],
+ category: Category.Roundstart, // Category.Roundstart, Category.Midround, or Category.Latejoin
};
export default Changeling;
@@ -453,4 +463,4 @@ If `antag_preference` is set, it will refer to that preference instead of `antag
## Updating special_roles
-In `code/__DEFINES/role_preferences.dm` (the same place you'll need to make your ROLE_\* defined), simply add your antagonist to the `special_roles` assoc list. The key is your ROLE, the value is the number of days since your first game in order to play as that antagonist.
+In `code/__DEFINES/role_preferences.dm` (the same place you'll need to make your ROLE\_\* defined), simply add your antagonist to the `special_roles` assoc list. The key is your ROLE, the value is the number of days since your first game in order to play as that antagonist.
diff --git a/code/modules/keybindings/readme.md b/code/modules/keybindings/readme.md
index 3f8b992b93d..c9ad3772e56 100644
--- a/code/modules/keybindings/readme.md
+++ b/code/modules/keybindings/readme.md
@@ -33,9 +33,9 @@ No client-set keybindings at this time, but it shouldn't be too hard if someone
Notes about certain keys:
-* `Tab` has client-sided behavior but acts normally
-* `T`, `O`, and `M` move focus to the input when pressed. This fires the keyUp macro right away.
-* `\` needs to be escaped in the dmf so any usage is `\\`
+- `Tab` has client-sided behavior but acts normally
+- `T`, `O`, and `M` move focus to the input when pressed. This fires the keyUp macro right away.
+- `\` needs to be escaped in the dmf so any usage is `\\`
You cannot `TICK_CHECK` or check `world.tick_usage` inside of procs called by key down and up
events. They happen outside of a byond tick and have no meaning there. Key looping
diff --git a/code/modules/maint_recycler/code/vendor_datums/readme b/code/modules/maint_recycler/code/vendor_datums/readme
index a8984f3bd45..cbc5778daa3 100644
--- a/code/modules/maint_recycler/code/vendor_datums/readme
+++ b/code/modules/maint_recycler/code/vendor_datums/readme
@@ -1,26 +1,26 @@
Adding something to the recycling vendor? Cool! Try and abide by the following design rules, though!
-* Is it a "gamer tool" that directly helps with station round progression? Probably shouldn't have it! This includes things like diamonds, rare materials, etc.
- (the materials that ARE in the vendor are the more "useless" ones, with the intended purpose of allowing people to get some materials for hangouts a bit easier if there's no cargo)
- Steel and Glass are the exception here, because they're common enough that I don't really think people will use metacurrency to get meager amounts. obviously if that's not the case I'll tweak it.
+- Is it a "gamer tool" that directly helps with station round progression? Probably shouldn't have it! This includes things like diamonds, rare materials, etc.
+ (the materials that ARE in the vendor are the more "useless" ones, with the intended purpose of allowing people to get some materials for hangouts a bit easier if there's no cargo)
+ Steel and Glass are the exception here, because they're common enough that I don't really think people will use metacurrency to get meager amounts. obviously if that's not the case I'll tweak it.
-* is it recycleable?
- If so - make sure it costs more than you can recycle it for.
+- is it recycleable?
+ If so - make sure it costs more than you can recycle it for.
-* Is it something that has huge potential to be annoying when used?
- Things like Photon nades, voice changers, etc. While they COULD technically be classified as scene tools, in reality, it's just going to result in people being a PITA with them. we don't want to encourage that behaviour!
+- Is it something that has huge potential to be annoying when used?
+ Things like Photon nades, voice changers, etc. While they COULD technically be classified as scene tools, in reality, it's just going to result in people being a PITA with them. we don't want to encourage that behaviour!
Basically! does the hypothetical stock addition fall into any of these? if not, put a bit of thought into it!
-* Scene tools. Stuff that has minimal impact on the game There's two subcategories of it.
- * Stuff that explicitly can't interact with people without consent - NIF laws, capture crystals, etc.
- * Stuff that has potential to. The various spicy chemicals, size guns, the various TF guns, etc.
- Both of these should be good to go, but, you know. assume the worst. don't make a gas grenade with shrink chems.
+- Scene tools. Stuff that has minimal impact on the game There's two subcategories of it.
+ - Stuff that explicitly can't interact with people without consent - NIF laws, capture crystals, etc.
+ - Stuff that has potential to. The various spicy chemicals, size guns, the various TF guns, etc.
+ Both of these should be good to go, but, you know. assume the worst. don't make a gas grenade with shrink chems.
-* Mischief. Nothing overtly illegal or griefy, but stuff that'd otherwise be slightly inconvienent to get.
- Insuls (for the hideout), and uhhh....
+- Mischief. Nothing overtly illegal or griefy, but stuff that'd otherwise be slightly inconvienent to get.
+ Insuls (for the hideout), and uhhh....
-* Rare stuff
- Stuff that makes people go "awooga" and want to spend points on it, but can be achieved elsewhere. Stuff like NIFs, Bluespace harpoons, etc. Stuff you can already get on station, just a way to do so more consistently. Note that AT BEST these should be tied with the station version of the item. we still want people to go to science for 90% of the NIFs they get.
+- Rare stuff
+ Stuff that makes people go "awooga" and want to spend points on it, but can be achieved elsewhere. Stuff like NIFs, Bluespace harpoons, etc. Stuff you can already get on station, just a way to do so more consistently. Note that AT BEST these should be tied with the station version of the item. we still want people to go to science for 90% of the NIFs they get.
-* Showoff items. Stuff that makes other people go awooga. this shouldn't be anything actually useful. Just silly stuff akin to the fish hats. Golden tools, etc.
+- Showoff items. Stuff that makes other people go awooga. this shouldn't be anything actually useful. Just silly stuff akin to the fish hats. Golden tools, etc.
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm
index a4749ebdc16..75b124f87e9 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm
@@ -205,7 +205,7 @@
victim = L
break
- if(victim)
+ if(victim?.reagents)
victim.reagents.add_reagent(REAGENT_ID_WARNINGTOXIN, poison_per_bite)
victim.AdjustWeakened(2)
victim.visible_message(span_danger("\The [src] has bitten \the [victim]!"))
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/raccoon.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/raccoon.dm
new file mode 100644
index 00000000000..311c5638423
--- /dev/null
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/raccoon.dm
@@ -0,0 +1,58 @@
+//raccoon
+/mob/living/simple_mob/animal/passive/raccoon
+ name = "raccoon"
+ desc = "A raccoon, also known as a trash panda."
+ tt_desc = "E purgamentum raccoonus"
+ icon = 'icons/mob/animal_vr.dmi'
+ icon_state = "raccoon"
+ item_state = "raccoon"
+ icon_living = "raccoon"
+ icon_dead = "raccoon_dead"
+ icon_rest = "raccoon_rest"
+
+ ai_holder_type = /datum/ai_holder/simple_mob/passive/raccoon
+ say_list_type = /datum/say_list/raccoon
+
+ see_in_dark = 6
+ movement_cooldown = 3
+
+ response_help = "pets"
+ response_disarm = "gently pushes aside"
+ response_harm = "kicks"
+ has_hands = TRUE
+
+ min_oxy = 16 //Require atleast 16kPA oxygen
+ minbodytemp = 223 //Below -50 Degrees Celsius
+ maxbodytemp = 323 //Above 50 Degrees Celsius
+
+ meat_amount = 1
+ meat_type = /obj/item/reagent_containers/food/snacks/meat
+
+ vore_active = TRUE
+ vore_capacity = 1
+ vore_icons = SA_ICON_LIVING | SA_ICON_REST
+ center_offset = 0
+
+ species_sounds = "Raccoon"
+ pain_emote_1p = list("chitter")
+ pain_emote_3p = list("chitters")
+
+/mob/living/simple_mob/animal/passive/raccoon/Initialize(mapload)
+ . = ..()
+ ghostjoin = 1
+ ghostjoin_icon()
+ GLOB.active_ghost_pods += src
+
+/mob/living/simple_mob/animal/passive/raccoon/Destroy()
+ GLOB.active_ghost_pods -= src
+ . = ..()
+
+/datum/say_list/raccoon
+ speak = list("HSSSSS")
+ emote_see = list("shakes their head", "shivers","grooms self", "nibbles on some trash")
+ emote_hear = list("purrs")
+
+/datum/ai_holder/simple_mob/passive/raccoon
+ flee_when_dying = TRUE
+ dying_threshold = 0.9
+ speak_chance = 1
diff --git a/code/modules/reagents/readme.md b/code/modules/reagents/readme.md
index ef274b6f9e6..b444112141d 100644
--- a/code/modules/reagents/readme.md
+++ b/code/modules/reagents/readme.md
@@ -1,306 +1,305 @@
-/*
+/\*
NOTE: IF YOU UPDATE THE REAGENT-SYSTEM, ALSO UPDATE THIS README.
-Structure: /////////////////// //////////////////////////
- // Mob or object // -------> // Reagents var (datum) // Is a reference to the datum that holds the reagents.
- /////////////////// //////////////////////////
- | |
- The object that holds everything. V
- reagent_list var (list) A List of datums, each datum is a reagent.
+Structure: /////////////////// //////////////////////////
+// Mob or object // -------> // Reagents var (datum) // Is a reference to the datum that holds the reagents.
+/////////////////// //////////////////////////
+| |
+The object that holds everything. V
+reagent_list var (list) A List of datums, each datum is a reagent.
- | | |
- V V V
-
- reagents (datums) Reagents. I.e. Water , antitoxins or mercury.
+ | | |
+ V V V
+ reagents (datums) Reagents. I.e. Water , antitoxins or mercury.
Random important notes:
- An objects on_reagent_change will be called every time the objects reagents change.
- Useful if you want to update the objects icon etc.
+ An objects on_reagent_change will be called every time the objects reagents change.
+ Useful if you want to update the objects icon etc.
About the Holder:
- The holder (reagents datum) is the datum that holds a list of all reagents
- currently in the object.It also has all the procs needed to manipulate reagents
+ The holder (reagents datum) is the datum that holds a list of all reagents
+ currently in the object.It also has all the procs needed to manipulate reagents
- Vars:
- list/datum/reagent/reagent_list
- List of reagent datums.
+ Vars:
+ list/datum/reagent/reagent_list
+ List of reagent datums.
- total_volume
- Total volume of all reagents.
+ total_volume
+ Total volume of all reagents.
- maximum_volume
- Maximum volume.
+ maximum_volume
+ Maximum volume.
- atom/my_atom
- Reference to the object that contains this.
+ atom/my_atom
+ Reference to the object that contains this.
- Procs:
+ Procs:
- get_free_space()
- Returns the remaining free volume in the holder.
+ get_free_space()
+ Returns the remaining free volume in the holder.
- get_master_reagent()
- Returns the reference to the reagent with the largest volume
+ get_master_reagent()
+ Returns the reference to the reagent with the largest volume
- get_master_reagent_name()
- Ditto, but returns the name.
+ get_master_reagent_name()
+ Ditto, but returns the name.
- get_master_reagent_id()
- Ditto, but returns ID.
+ get_master_reagent_id()
+ Ditto, but returns ID.
- update_total()
- Updates total volume, called automatically.
+ update_total()
+ Updates total volume, called automatically.
- handle_reactions()
- Checks reagents and triggers any reactions that happen. Usually called automatically.
+ handle_reactions()
+ Checks reagents and triggers any reactions that happen. Usually called automatically.
- add_reagent(var/id, var/amount, var/data = null, var/safety = 0)
- Adds [amount] units of [id] reagent. [data] will be passed to reagent's mix_data() or initialize_data(). If [safety] is 0, handle_reactions() will be called. Returns 1 if successful, 0 otherwise.
+ add_reagent(var/id, var/amount, var/data = null, var/safety = 0)
+ Adds [amount] units of [id] reagent. [data] will be passed to reagent's mix_data() or initialize_data(). If [safety] is 0, handle_reactions() will be called. Returns 1 if successful, 0 otherwise.
- remove_reagent(var/id, var/amount, var/safety = 0)
- Ditto, but removes reagent. Returns 1 if successful, 0 otherwise.
+ remove_reagent(var/id, var/amount, var/safety = 0)
+ Ditto, but removes reagent. Returns 1 if successful, 0 otherwise.
- del_reagent(var/id)
- Removes all of the reagent.
+ del_reagent(var/id)
+ Removes all of the reagent.
- has_reagent(var/id, var/amount = 0)
- Checks if holder has at least [amount] of [id] reagent. Returns 1 if the reagent is found and volume is above [amount]. Returns 0 otherwise.
+ has_reagent(var/id, var/amount = 0)
+ Checks if holder has at least [amount] of [id] reagent. Returns 1 if the reagent is found and volume is above [amount]. Returns 0 otherwise.
- clear_reagents()
- Removes all reagents.
+ clear_reagents()
+ Removes all reagents.
- get_reagent_amount(var/id)
- Returns reagent volume. Returns 0 if reagent is not found.
+ get_reagent_amount(var/id)
+ Returns reagent volume. Returns 0 if reagent is not found.
- get_data(var/id)
- Returns get_data() of the reagent.
+ get_data(var/id)
+ Returns get_data() of the reagent.
- get_reagents()
- Returns a string containing all reagent ids and volumes, e.g. "carbon(4),nittrogen(5)".
+ get_reagents()
+ Returns a string containing all reagent ids and volumes, e.g. "carbon(4),nittrogen(5)".
- remove_any(var/amount = 1)
- Removes up to [amount] of reagents from [src]. Returns actual amount removed.
+ remove_any(var/amount = 1)
+ Removes up to [amount] of reagents from [src]. Returns actual amount removed.
- trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
- Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). If [copy] is 1, copies reagents instead.
+ trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
+ Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). If [copy] is 1, copies reagents instead.
- touch(var/atom/target)
- When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent.
- This does not handle transferring reagents to things.
- For example, splashing someone with water will get them wet and extinguish them if they are on fire,
- even if they are wearing an impermeable suit that prevents the reagents from contacting the skin.
- Basically just defers to touch_mob(target), touch_turf(target), or touch_obj(target), depending on target's type.
- Not recommended to use this directly, since trans_to() calls it before attempting to transfer.
+ touch(var/atom/target)
+ When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent.
+ This does not handle transferring reagents to things.
+ For example, splashing someone with water will get them wet and extinguish them if they are on fire,
+ even if they are wearing an impermeable suit that prevents the reagents from contacting the skin.
+ Basically just defers to touch_mob(target), touch_turf(target), or touch_obj(target), depending on target's type.
+ Not recommended to use this directly, since trans_to() calls it before attempting to transfer.
- touch_mob(var/mob/target)
- Calls each reagent's touch_mob(target).
+ touch_mob(var/mob/target)
+ Calls each reagent's touch_mob(target).
- touch_turf(var/turf/target)
- Calls each reagent's touch_turf(target).
+ touch_turf(var/turf/target)
+ Calls each reagent's touch_turf(target).
- touch_obj(var/obj/target)
- Calls each reagent's touch_obj(target).
+ touch_obj(var/obj/target)
+ Calls each reagent's touch_obj(target).
- trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
- The general proc for applying reagents to things externally (as opposed to directly injected into the contents).
- It first calls touch, then the appropriate trans_to_*() or splash_mob().
- If for some reason you want touch effects to be bypassed (e.g. injecting stuff directly into a reagent container or person), call the appropriate trans_to_*() proc.
-
- Calls touch() before checking the type of [target], calling splash_mob(target, amount), trans_to_turf(target, amount, multiplier, copy), or trans_to_obj(target, amount, multiplier, copy).
+ trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
+ The general proc for applying reagents to things externally (as opposed to directly injected into the contents).
+ It first calls touch, then the appropriate trans_to_*() or splash_mob().
+ If for some reason you want touch effects to be bypassed (e.g. injecting stuff directly into a reagent container or person), call the appropriate trans_to_*() proc.
- trans_id_to(var/atom/target, var/id, var/amount = 1)
- Transfers [amount] of [id] to [target]. Returns amount transferred.
+ Calls touch() before checking the type of [target], calling splash_mob(target, amount), trans_to_turf(target, amount, multiplier, copy), or trans_to_obj(target, amount, multiplier, copy).
- splash_mob(var/mob/target, var/amount = 1, var/clothes = 1)
- Checks mob's clothing if [clothes] is 1 and transfers [amount] reagents to mob's skin.
- Don't call this directly. Call apply_to() instead.
+ trans_id_to(var/atom/target, var/id, var/amount = 1)
+ Transfers [amount] of [id] to [target]. Returns amount transferred.
- trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0)
- Transfers [amount] reagents to the mob's appropriate holder, depending on [type]. Ignores protection.
+ splash_mob(var/mob/target, var/amount = 1, var/clothes = 1)
+ Checks mob's clothing if [clothes] is 1 and transfers [amount] reagents to mob's skin.
+ Don't call this directly. Call apply_to() instead.
- trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
- Turfs don't currently have any reagents. Puts [amount] reagents into a temporary holder, calls touch_turf(target) from it, and deletes it.
+ trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0)
+ Transfers [amount] reagents to the mob's appropriate holder, depending on [type]. Ignores protection.
- trans_to_obj(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
- If target has reagents, transfers [amount] to it. Otherwise, same as trans_to_turf().
+ trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
+ Turfs don't currently have any reagents. Puts [amount] reagents into a temporary holder, calls touch_turf(target) from it, and deletes it.
- atom/proc/create_reagents(var/max_vol)
- Creates a new reagent datum.
+ trans_to_obj(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
+ If target has reagents, transfers [amount] to it. Otherwise, same as trans_to_turf().
+
+ atom/proc/create_reagents(var/max_vol)
+ Creates a new reagent datum.
About Reagents:
- Reagents are all the things you can mix and fille in bottles etc. This can be anything from
- rejuvs over water to... iron.
+ Reagents are all the things you can mix and fille in bottles etc. This can be anything from
+ rejuvs over water to... iron.
- Vars:
+ Vars:
- name
- Name that shows up in-game.
+ name
+ Name that shows up in-game.
- id
- ID that is used for internal tracking. MUST BE UNIQUE.
+ id
+ ID that is used for internal tracking. MUST BE UNIQUE.
- description
- Description that shows up in-game.
+ description
+ Description that shows up in-game.
- datum/reagents/holder
- Reference to holder.
+ datum/reagents/holder
+ Reference to holder.
- reagent_state
- Could be GAS, LIQUID, or SOLID. Affects nothing. Reserved for future use.
+ reagent_state
+ Could be GAS, LIQUID, or SOLID. Affects nothing. Reserved for future use.
- list/data
- Use varies by reagent. Custom variable. For example, blood stores blood group and viruses.
+ list/data
+ Use varies by reagent. Custom variable. For example, blood stores blood group and viruses.
- volume
- Current volume.
+ volume
+ Current volume.
- metabolism
- How quickly reagent is processed in mob's bloodstream; by default aslo affects ingest and touch metabolism.
+ metabolism
+ How quickly reagent is processed in mob's bloodstream; by default aslo affects ingest and touch metabolism.
- ingest_met
- How quickly reagent is processed when ingested; [metabolism] is used if zero.
+ ingest_met
+ How quickly reagent is processed when ingested; [metabolism] is used if zero.
- touch_met
- Ditto when touching.
+ touch_met
+ Ditto when touching.
- dose
- How much of the reagent has been processed, limited by [max_dose]. Used for reagents with varying effects (e.g. ethanol or rezadone) and overdosing.
+ dose
+ How much of the reagent has been processed, limited by [max_dose]. Used for reagents with varying effects (e.g. ethanol or rezadone) and overdosing.
- max_dose
- Maximum amount of reagent that has ever been in a mob. Exists so dose won't grow infinitely when small amounts of reagent are added over time.
+ max_dose
+ Maximum amount of reagent that has ever been in a mob. Exists so dose won't grow infinitely when small amounts of reagent are added over time.
- overdose
- If [dose] is bigger than [overdose], overdose() proc is called every tick.
+ overdose
+ If [dose] is bigger than [overdose], overdose() proc is called every tick.
- scannable
- If set to 1, will show up on health analyzers by name.
+ scannable
+ If set to 1, will show up on health analyzers by name.
- affects_dead
- If set to 1, will affect dead players. Used by Adminordrazine.
+ affects_dead
+ If set to 1, will affect dead players. Used by Adminordrazine.
- glass_icon_state
- Used by drinks. icon_state of the glass when this reagent is the master reagent.
+ glass_icon_state
+ Used by drinks. icon_state of the glass when this reagent is the master reagent.
- glass_name
- Ditto for glass name.
+ glass_name
+ Ditto for glass name.
- glass_desc
- Ditto for glass desciption.
+ glass_desc
+ Ditto for glass desciption.
- glass_center_of_mass_x
- glass_center_of_mass_y
- Used for glass placement on tables.
+ glass_center_of_mass_x
+ glass_center_of_mass_y
+ Used for glass placement on tables.
- color
- "#RRGGBB" or "#RRGGBBAA" where A is alpha channel.
+ color
+ "#RRGGBB" or "#RRGGBBAA" where A is alpha channel.
- color_weight
- How much reagent affects color of holder. Used by paint.
+ color_weight
+ How much reagent affects color of holder. Used by paint.
- Procs:
+ Procs:
- remove_self(var/amount)
- Removes [amount] of itself.
+ remove_self(var/amount)
+ Removes [amount] of itself.
- touch_mob(var/mob/M)
- Called when reagent is in another holder and not splashing the mob. Can be used with noncarbons.
+ touch_mob(var/mob/M)
+ Called when reagent is in another holder and not splashing the mob. Can be used with noncarbons.
- touch_obj(var/obj/O)
- How reagent reacts with objects.
+ touch_obj(var/obj/O)
+ How reagent reacts with objects.
- touch_turf(var/turf/T)
- How reagent reacts with turfs.
+ touch_turf(var/turf/T)
+ How reagent reacts with turfs.
- on_mob_life(var/mob/living/carbon/M, var/alien, var/location)
- Makes necessary checks and calls one of affect procs.
+ on_mob_life(var/mob/living/carbon/M, var/alien, var/location)
+ Makes necessary checks and calls one of affect procs.
- affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
- How reagent affects mob when injected. [removed] is the amount of reagent that has been removed this tick. [alien] is the mob's reagent flag.
+ affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ How reagent affects mob when injected. [removed] is the amount of reagent that has been removed this tick. [alien] is the mob's reagent flag.
- affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
- Ditto, ingested. Defaults to affect_blood with halved dose.
+ affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
+ Ditto, ingested. Defaults to affect_blood with halved dose.
- affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
- Ditto, touching.
+ affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
+ Ditto, touching.
- overdose(var/mob/living/carbon/M, var/alien)
- Called when dose is above overdose. Defaults to M.adjustToxLoss(REM).
+ overdose(var/mob/living/carbon/M, var/alien)
+ Called when dose is above overdose. Defaults to M.adjustToxLoss(REM).
- initialize_data(var/newdata)
- Called when reagent is created. Defaults to setting [data] to [newdata].
+ initialize_data(var/newdata)
+ Called when reagent is created. Defaults to setting [data] to [newdata].
- mix_data(var/newdata, var/newamount)
- Called when [newamount] of reagent with [newdata] data is added to the current reagent. Used by paint.
+ mix_data(var/newdata, var/newamount)
+ Called when [newamount] of reagent with [newdata] data is added to the current reagent. Used by paint.
- get_data()
- Returns data. Can be overriden.
+ get_data()
+ Returns data. Can be overriden.
About Recipes:
- Recipes are simple datums that contain a list of required reagents and a result.
- They also have a proc that is called when the recipe is matched.
+ Recipes are simple datums that contain a list of required reagents and a result.
+ They also have a proc that is called when the recipe is matched.
- Vars:
+ Vars:
- name
- Name of the reaction, currently unused.
+ name
+ Name of the reaction, currently unused.
- id
- ID of the reaction, must be unique.
+ id
+ ID of the reaction, must be unique.
- result
- ID of the resulting reagent. Can be null.
+ result
+ ID of the resulting reagent. Can be null.
- list/required_reagents
- Reagents that are required for the reaction and are used up during it.
+ list/required_reagents
+ Reagents that are required for the reaction and are used up during it.
- list/catalysts
- Ditto, but not used up.
+ list/catalysts
+ Ditto, but not used up.
- list/inhibitors
- Opposite, prevent the reaction from happening.
+ list/inhibitors
+ Opposite, prevent the reaction from happening.
- result_amount
- Amount of resulting reagent.
+ result_amount
+ Amount of resulting reagent.
- mix_message
- Message that is shown to mobs when reaction happens.
+ mix_message
+ Message that is shown to mobs when reaction happens.
- Procs:
+ Procs:
- can_happen(var/datum/reagents/holder)
- Customizable. If it returns 0, reaction will not happen. Defaults to always returning 1. Used by slime core reactions.
+ can_happen(var/datum/reagents/holder)
+ Customizable. If it returns 0, reaction will not happen. Defaults to always returning 1. Used by slime core reactions.
- on_reaction(var/datum/reagents/holder, var/created_volume)
- Called when reaction happens. Used by explosives.
+ on_reaction(var/datum/reagents/holder, var/created_volume)
+ Called when reaction happens. Used by explosives.
- send_data(var/datum/reagents/T)
- Sets resulting reagent's data. Used by blood paint.
+ send_data(var/datum/reagents/T)
+ Sets resulting reagent's data. Used by blood paint.
About the Tools:
- By default, all atom have a reagents var - but its empty. if you want to use an object for the chem.
- system you'll need to add something like this in its new proc:
+ By default, all atom have a reagents var - but its empty. if you want to use an object for the chem.
+ system you'll need to add something like this in its new proc:
- atom/proc/create_reagents(var/max_volume)
+ atom/proc/create_reagents(var/max_volume)
- Other important stuff:
+ Other important stuff:
- amount_per_transfer_from_this var
- This var is mostly used by beakers and bottles.
- It simply tells us how much to transfer when
- 'pouring' our reagents into something else.
+ amount_per_transfer_from_this var
+ This var is mostly used by beakers and bottles.
+ It simply tells us how much to transfer when
+ 'pouring' our reagents into something else.
- atom/proc/is_open_container()
- Checks atom/var/flags & OPENCONTAINER.
- If this returns 1 , you can use syringes, beakers etc
- to manipulate the contents of this object.
- If it's 0, you'll need to write your own custom reagent
- transfer code since you will not be able to use the standard
- tools to manipulate it.
+ atom/proc/is_open_container()
+ Checks atom/var/flags & OPENCONTAINER.
+ If this returns 1 , you can use syringes, beakers etc
+ to manipulate the contents of this object.
+ If it's 0, you'll need to write your own custom reagent
+ transfer code since you will not be able to use the standard
+ tools to manipulate it.
-*/
+\*/
diff --git a/code/modules/shuttles/upgrade_guide.md b/code/modules/shuttles/upgrade_guide.md
index 7c2c73f422e..4e7275b4a63 100644
--- a/code/modules/shuttles/upgrade_guide.md
+++ b/code/modules/shuttles/upgrade_guide.md
@@ -1,35 +1,37 @@
# "Landmark" Shuttles Conversion
+
This guide helps with updating maps and shuttle datums from the old "area" based system to the "landmark" based system.
## Summary
-The old shuttle datum worked with areas (`/area`). You are probably familiar with every shuttle having a few cookie-cutter shaped areas it travels between.
+
+The old shuttle datum worked with areas (`/area`). You are probably familiar with every shuttle having a few cookie-cutter shaped areas it travels between.
When the shuttle "moved" it was translated from its current area to the destination area. The areas had to be _exactly_ the same shape so
-that each turf in the origin area got translated to the equivalent place at the target.\
+that each turf in the origin area got translated to the equivalent place at the target.\
Since _all possible_ destinations had to have a dedicated area (and areas in BYOND can't overlap) this means it is impossible for two shuttles to travel to the same spot, even at different times.
In the new system shuttle destinations are represented by "landmark" objects (`/obj/effect/shuttle_landmark`).
When a shuttle is "moved" it is translated from its current landmark to the destination landmark, with each turf keeping its same position _relative_ to the landmarks.
-In other words, whatever a turf's x/y/z offsets are from the origin landmark, it will be moved to the same x/y/z offset from the destination landmark.
+In other words, whatever a turf's x/y/z offsets are from the origin landmark, it will be moved to the same x/y/z offset from the destination landmark.
## Landmark Objects
+
Shuttle destinations are represented by `/obj/effect/shuttle_landmark` objects on the map.
-* `name` - Pretty name of the nav point, used on overmap and in messages and console UI.
-* `landmark_tag` - Globally unique ID, used by everything else to refer to this landmark.
-* `docking_controller` - ID of the controller on the dock side (initialize to id_tag, becomes reference). Leave null if not applicable.
-* `base_area` - Type path of the `/area` that should be here when a shuttle is *not* present.
-* `base_turf` - Type path of the `/turf` that should be here when a shuttle is *not* present.
-* `shuttle_restricted` - If not null, only the named shuttle is allowed to use this landmark. (TODO: Overmap functionality)
-* `flags` - Bitfield - defaults to `SLANDMARK_FLAG_AUTOSET`, can be any combination of:
- * `SLANDMARK_FLAG_AUTOSET` (1) - If set, will initialize base_area and base_turf to same as where it was spawned at.
- * `SLANDMARK_FLAG_ZERO_G` (2) - If set, Zero-G shuttles moved here will lose gravity unless the area has ambient gravity.
-* `special_dock_targets` - Used to configure shuttles with multiple docking controllers on the shuttle. Map of shuttle `name` -> `id_tag` of the docking controller it should use for this landmark. (Think of a shuttle with airlocks on both sides, each with their own controller. This would tell it which side to use.)
-
+- `name` - Pretty name of the nav point, used on overmap and in messages and console UI.
+- `landmark_tag` - Globally unique ID, used by everything else to refer to this landmark.
+- `docking_controller` - ID of the controller on the dock side (initialize to id_tag, becomes reference). Leave null if not applicable.
+- `base_area` - Type path of the `/area` that should be here when a shuttle is _not_ present.
+- `base_turf` - Type path of the `/turf` that should be here when a shuttle is _not_ present.
+- `shuttle_restricted` - If not null, only the named shuttle is allowed to use this landmark. (TODO: Overmap functionality)
+- `flags` - Bitfield - defaults to `SLANDMARK_FLAG_AUTOSET`, can be any combination of:
+ - `SLANDMARK_FLAG_AUTOSET` (1) - If set, will initialize base_area and base_turf to same as where it was spawned at.
+ - `SLANDMARK_FLAG_ZERO_G` (2) - If set, Zero-G shuttles moved here will lose gravity unless the area has ambient gravity.
+- `special_dock_targets` - Used to configure shuttles with multiple docking controllers on the shuttle. Map of shuttle `name` -> `id_tag` of the docking controller it should use for this landmark. (Think of a shuttle with airlocks on both sides, each with their own controller. This would tell it which side to use.)
## Shuttle Types
-
### Ferry Shuttles
+
These shuttles go back and forth between two locations (normally called "station" and "offsite").
Examples: Mining shuttle, Arrivals Shuttle, etc.
@@ -38,24 +40,22 @@ New Type Path: `/datum/shuttle/autodock/ferry`
##### New Vars:
-Name|Type|Required?|Info
----|---|---|---
-shuttle_area |`/area` typepath(s)|Yes| Can be a single path or list of paths.
+| Name | Type | Required? | Info |
+| ------------ | ------------------- | --------- | -------------------------------------- |
+| shuttle_area | `/area` typepath(s) | Yes | Can be a single path or list of paths. |
##### Replaced vars:
-Old|New|Required?|Info
-:---:|:---:|:---:|---
-area_station |landmark_station |Yes|Tag of the landmark for the "station" location.
-area_offsite |landmark_offsite |Yes|Tag of the landmark for the "offsite" location.
-area_transition |landmark_transition |No|Tag of the landmark for the "transition" location used during long_jump()
-dock_target_station |On landmark |No|`id_tag` docking controller *on the dock* has been moved to the `docking_controller` var on the landmark_station landmark obj.
-dock_target_offsite |On landmark |No|`id_tag` docking controller *on the dock* has been moved to the `docking_controller` var on the landmark_offsite landmark obj.
-
-
-
+| Old | New | Required? | Info |
+| :-----------------: | :-----------------: | :-------: | ------------------------------------------------------------------------------------------------------------------------------ |
+| area_station | landmark_station | Yes | Tag of the landmark for the "station" location. |
+| area_offsite | landmark_offsite | Yes | Tag of the landmark for the "offsite" location. |
+| area_transition | landmark_transition | No | Tag of the landmark for the "transition" location used during long_jump() |
+| dock_target_station | On landmark | No | `id_tag` docking controller _on the dock_ has been moved to the `docking_controller` var on the landmark_station landmark obj. |
+| dock_target_offsite | On landmark | No | `id_tag` docking controller _on the dock_ has been moved to the `docking_controller` var on the landmark_offsite landmark obj. |
### Multi Shuttles
+
These shuttles go between a list of configured locations, one of which is its starting location.
Examples: Skipjack, Syndicate Shuttle
@@ -64,61 +64,64 @@ New Type Path: `/datum/shuttle/autodock/multi`
##### New Vars:
-Name|Type|Required?|Info
----|---|---|---
-shuttle_area |`/area` typepath(s)|Yes| Can be a single path or list of paths.
+| Name | Type | Required? | Info |
+| ------------ | ------------------- | --------- | -------------------------------------- |
+| shuttle_area | `/area` typepath(s) | Yes | Can be a single path or list of paths. |
##### Replaced vars:
-Old|New|Required?|Info
-:---:|:---:|:---:|---
-origin |current_location |Yes|Tag of the landmark where the shuttle is at startup.
-interim |landmark_transition |No|Tag of the landmark for the "transition" location used during long_jump()
-start_location |N/A |No|No longer necessary, automatically determined from the value of `origin`
-destinations |destination_tags |Yes|List of destinations the shuttle can travel to. Used to be associative list of *name* -> *area typepath*, now is normal list of landmark tag ids. Name is now read from the landmark obj.
-destination_dock_targets|On landmarks |No|Used to be associative list of *name* -> *id_tag* for which docking controller *on the dock* to use at each destination. This is now specified by the `docking_controller` var on each landmark obj.
-
-
+| Old | New | Required? | Info |
+| :----------------------: | :-----------------: | :-------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| origin | current_location | Yes | Tag of the landmark where the shuttle is at startup. |
+| interim | landmark_transition | No | Tag of the landmark for the "transition" location used during long_jump() |
+| start_location | N/A | No | No longer necessary, automatically determined from the value of `origin` |
+| destinations | destination_tags | Yes | List of destinations the shuttle can travel to. Used to be associative list of _name_ -> _area typepath_, now is normal list of landmark tag ids. Name is now read from the landmark obj. |
+| destination_dock_targets | On landmarks | No | Used to be associative list of _name_ -> _id_tag_ for which docking controller _on the dock_ to use at each destination. This is now specified by the `docking_controller` var on each landmark obj. |
### Web Shuttles
-These shuttles travel along a network of locations connected by routes. Instead of being able to travel to any of its destinations, it can only travel to destinations connected by a route to its current location. Added by Polaris as an upgrade to Multi Shuttles.
+
+These shuttles travel along a network of locations connected by routes. Instead of being able to travel to any of its destinations, it can only travel to destinations connected by a route to its current location. Added by Polaris as an upgrade to Multi Shuttles.
Note: While cool, it is likely that the upcoming "overmap" shuttles will be even cooler, and may eventually replace some web shuttles.
-Examples: Southern Cross' Ninja Shuttle, Tether's Excursion Shuttle
+Examples: Southern Cross' Ninja Shuttle, Tether's Excursion Shuttle
Old Type Path: `/datum/shuttle/web_shuttle`\
New Type Path: `/datum/shuttle/autodock/web_shuttle`
##### New Vars:
-Name|Type|Required?|Info
----|---|---|---
-shuttle_area |`/area` typepath(s)|Yes| Can be a single path or list of paths.
+| Name | Type | Required? | Info |
+| ------------ | ------------------- | --------- | -------------------------------------- |
+| shuttle_area | `/area` typepath(s) | Yes | Can be a single path or list of paths. |
##### Replaced vars:
-Old|New|Required?|Info
-:---:|:---:|:---:|---
-current_area |current_location |Yes|Tag of the landmark where the shuttle is at startup.
+| Old | New | Required? | Info |
+| :----------: | :--------------: | :-------: | ---------------------------------------------------- |
+| current_area | current_location | Yes | Tag of the landmark where the shuttle is at startup. |
#### Web Destination Configuration (`/datum/shuttle_destination`)
-The network of routes for each web shuttle is configured by defining datums. These are mostly unchanged but use landmarks instead of areas now.
+
+The network of routes for each web shuttle is configured by defining datums. These are mostly unchanged but use landmarks instead of areas now.
##### Replaced vars:
-Old|New|Required?|Info
-:---:|:---:|:---:|---
-my_area |my_landmark |Yes|Tag of the landmark associated with this destination.
-preferred_interim_area |preferred_interim_tag |No|Tag of the landmark for the "transition" location used during long_jump()
-dock_target |On landmark |No|`id_tag` docking controller *on the dock* has been moved to the `docking_controller` var on the my_landmark landmark obj.
+| Old | New | Required? | Info |
+| :--------------------: | :-------------------: | :-------: | ------------------------------------------------------------------------------------------------------------------------- |
+| my_area | my_landmark | Yes | Tag of the landmark associated with this destination. |
+| preferred_interim_area | preferred_interim_tag | No | Tag of the landmark for the "transition" location used during long_jump() |
+| dock_target | On landmark | No | `id_tag` docking controller _on the dock_ has been moved to the `docking_controller` var on the my_landmark landmark obj. |
### Misc Shuttle Types
+
Other shuttle types that are either unused or unchanged in particular.
#### Escape Pods
+
Special case of ferry shuttles that use escape pod berth controllers.
-Type path changed from `/datum/shuttle/ferry/escape_pod` to `/datum/shuttle/autodock/ferry/escape_pod`
+Type path changed from `/datum/shuttle/ferry/escape_pod` to `/datum/shuttle/autodock/ferry/escape_pod`
Follow same instructions as for other ferry shuttles.
#### Multidock Ferry Shuttles
+
`/datum/shuttle/ferry/multidock` was a variant of ferry shuttles that could use a different docking port at each location.
Obsolete since is now natively supported by all dockable shuttles.
diff --git a/code/modules/tgchat/README.md b/code/modules/tgchat/README.md
index 71acb47c458..d2a99e5ffd2 100644
--- a/code/modules/tgchat/README.md
+++ b/code/modules/tgchat/README.md
@@ -5,6 +5,7 @@
### Message Format
TgChat handles sending messages from the server to the client through the use of JSON payloads, of which the format will change depending on the type of message and the intended client endpoint. An example of the payload for chat messages is as follows:
+
```json
{
"sequence": 0,
@@ -13,13 +14,13 @@ TgChat handles sending messages from the server to the client through the use of
"text": ". . .", // ?optional !atleast-one
"html": ". . .", // ?optional !atleast-one
"avoidHighlighting": 0 // ?optional
- },
+ }
}
```
### Reliability
-In the past there have been issues where BYOND will silently and without reason lose a message we sent to the client, to detect this and recover from it seamlessly TgChat also has a baked in reliability layer. This reliability layer is very primitive, and simply keeps track of received sequence numbers. Should the client receive an unexpected sequence number TgChat asks the server to resend any missing packets.
+In the past there have been issues where BYOND will silently and without reason lose a message we sent to the client, to detect this and recover from it seamlessly TgChat also has a baked in reliability layer. This reliability layer is very primitive, and simply keeps track of received sequence numbers. Should the client receive an unexpected sequence number TgChat asks the server to resend any missing packets.
### Ping System
diff --git a/code/modules/tgs/README.md b/code/modules/tgs/README.md
index 35ca73d7e9a..473442fd119 100644
--- a/code/modules/tgs/README.md
+++ b/code/modules/tgs/README.md
@@ -5,9 +5,9 @@ This folder should be placed on its own inside a codebase that wishes to use the
- [includes.dm](./includes.dm) is the file that should be included by DM code, it handles including the rest.
- The [core](./core) folder includes all code not directly part of any API version.
- The other versioned folders contain code for the different DMAPI versions.
- - [v3210](./v3210) contains the final TGS3 API.
- - [v4](./v4) is the legacy DMAPI 4 (Used in TGS 4.0.X versions).
- - [v5](./v5) is the current DMAPI version used by TGS >=4.1.
+ - [v3210](./v3210) contains the final TGS3 API.
+ - [v4](./v4) is the legacy DMAPI 4 (Used in TGS 4.0.X versions).
+ - [v5](./v5) is the current DMAPI version used by TGS >=4.1.
- [LICENSE](./LICENSE) is the MIT license for the DMAPI.
APIs communicate with TGS in two ways. All versions implement TGS -> DM communication using /world/Topic. DM -> TGS communication, called the bridge method, is different for each version.
diff --git a/code/modules/tgs/core/README.md b/code/modules/tgs/core/README.md
index 965e21b549a..7886a857149 100644
--- a/code/modules/tgs/core/README.md
+++ b/code/modules/tgs/core/README.md
@@ -2,7 +2,7 @@
This folder contains all DMAPI code not directly involved in an API.
-- [_definitions.dm](./definitions.dm) contains defines needed across DMAPI internals.
+- [\_definitions.dm](./definitions.dm) contains defines needed across DMAPI internals.
- [byond_world_export.dm](./byond_world_export.dm) contains the default `/datum/tgs_http_handler` implementation which uses `world.Export()`.
- [core.dm](./core.dm) contains the implementations of the `/world/proc/TgsXXX()` procs. Many map directly to the `/datum/tgs_api` functions. It also contains the /datum selection and setup code.
- [datum.dm](./datum.dm) contains the `/datum/tgs_api` declarations that all APIs must implement.
diff --git a/code/modules/tgs/v5/README.md b/code/modules/tgs/v5/README.md
index a8a0c748e7b..fb374c2f872 100644
--- a/code/modules/tgs/v5/README.md
+++ b/code/modules/tgs/v5/README.md
@@ -2,8 +2,8 @@
This DMAPI implements bridge requests using HTTP GET requests to TGS. It has no security restrictions.
-- [__interop_version.dm](./__interop_version.dm) contains the version of the API used between the DMAPI and TGS.
-- [_defines.dm](./_defines.dm) contains constant definitions.
+- [\_\_interop_version.dm](./__interop_version.dm) contains the version of the API used between the DMAPI and TGS.
+- [\_defines.dm](./_defines.dm) contains constant definitions.
- [api.dm](./api.dm) contains the bulk of the API code.
- [bridge.dm](./bridge.dm) contains functions related to making bridge requests.
- [chunking.dm](./chunking.dm) contains common function for splitting large raw data sets into chunks BYOND can natively process.
diff --git a/code/modules/tickets/tickets.dm b/code/modules/tickets/tickets.dm
index 3e44ca419af..1b44f6a5c3c 100644
--- a/code/modules/tickets/tickets.dm
+++ b/code/modules/tickets/tickets.dm
@@ -169,7 +169,7 @@ GLOBAL_DATUM_INIT(tickets, /datum/tickets, new)
if(C.current_ticket)
var/datum/ticket/T = C.current_ticket
T.AddInteraction("Client disconnected.")
- T.initiator.mob.clear_alert("open ticket")
+ T.initiator.mob?.clear_alert("open ticket")
T.initiator = null
T = null
@@ -413,7 +413,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/statclick/ticket_list)
switch(level)
if(0)
for (var/client/C in GLOB.admins)
- var/chat_msg = span_mentor_channel(span_admin_pm_notice(span_adminhelp("Ticket [TicketHref("#[id]", ref_src)]") + span_bold(" (Mentor): [LinkedReplyName(ref_src)] [FullMonty(ref_src, check_rights_for(C, (R_ADMIN|R_SERVER|R_MOD)))]:") + msg))
+ var/chat_msg = span_mentor_channel(span_admin_pm_notice(span_adminhelp("Ticket [TicketHref("#[id]", ref_src)]") + span_bold(" (Mentor): [LinkedReplyName(ref_src)] [FullMonty(ref_src, check_rights_for(C, (R_ADMIN|R_SERVER|R_MOD)))]: ") + msg))
if (C.prefs?.read_preference(/datum/preference/toggle/play_mentorhelp_ping))
C << 'sound/effects/mentorhelp.mp3'
to_chat(C, chat_msg)
diff --git a/code/modules/tooltip/tooltip.html b/code/modules/tooltip/tooltip.html
index ee355fa80e6..096a3c51f6b 100644
--- a/code/modules/tooltip/tooltip.html
+++ b/code/modules/tooltip/tooltip.html
@@ -1,269 +1,410 @@
-
+
-
- Tooltip
-
-
-
+
+
+
+
+
-
-
+ //Go get the map details
+ window.location =
+ "byond://winget?callback=tooltip.updateCallback;id=mapwindow.map;property=size,view-size";
+ },
+ };
+
+