mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-22 11:38:12 +01:00
Unit Test rework & Master/Ticker update (#17912)
* Unit Test rework & Master/Ticker update * Fixes and working unit testing * Fixes * Test fixes and FA update * Fixed runtimes * Radio subsystem * move that glob wherever later * ident * CIBUILDING compile option * Fixed runtimes * Some changes to the workflow * CI Split * More split * Pathing * Linters and Annotators * ci dir fix * Missing undef fixed * Enable grep checks * More test conversions * More split * Correct file * Removes unneeded inputs * oop * More dependency changes * More conversions * Conversion fixes * Fixes * Some assert fixes * Corrects start gate * Converted some README.dms to README.mds * Removes duplicate proc * Removes unused defines * Example configs * fix dll access viol by double calling * Post-rebase fixes * Cleans up names global list * Undef restart counter * More code/game/ cleanup * Statpanel update * Skybox * add * Fix ticker * Roundend fix * Persistence dependency update * Reordering * Reordering * Reordering * Initstage fix * . * . * Reorder * Reorder * Circle * Mobs * Air * Test fix * CI Script Fix * Configs * More ticker stuff * This is now in 'reboot world' * Restart world announcements * no glob in PreInit * to define * Update * Removed old include * Make this file normal again * moved * test * shared unit testing objects * Updates batched_spritesheets and universal_icon * . * job data debug * rm that * init order * show us * . * i wonder * . * . * urg * do we not have a job ID? * . * rm sleep for now * updated rust-g linux binaries * binaries update 2 * binaries update 3 * testing something * change that * test something * . * . * . * locavar * test * move that * . * debug * don't run this test * strack trace it * cleaner * . * . * cras again * also comment this out * return to official rust g * Update robot_icons.dm * monitor the generation * . --------- Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
+42
-163
@@ -1,178 +1,57 @@
|
||||
name: CI
|
||||
name: CI Suite
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- "project/**"
|
||||
merge_group:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
BASENAME: "vorestation"
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
start_gate:
|
||||
if: ( !contains(github.event.head_commit.message, '[ci skip]') )
|
||||
name: Start Gate
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Mandatory Empty Step
|
||||
run: exit 0
|
||||
|
||||
run_linters:
|
||||
if: ( !contains(github.event.head_commit.message, '[ci skip]') )
|
||||
name: Run Linters
|
||||
runs-on: ubuntu-24.04
|
||||
concurrency:
|
||||
group: run_linters-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# Caches
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup_bun
|
||||
- name: Restore Bootstrap cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: tools/bootstrap/.cache
|
||||
key: ${{ runner.os }}-bootstrap-${{ hashFiles('tools/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-bootstrap-
|
||||
- name: Restore Rust cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cargo
|
||||
key: ${{ runner.os }}-rust-${{ hashFiles('tools/ci/ci_dependencies.sh')}}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-rust-
|
||||
- name: Restore Cutter cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: tools/icon_cutter/cache
|
||||
key: ${{ runner.os }}-cutter-${{ hashFiles('dependencies.sh') }}
|
||||
# End Caches
|
||||
- name: Install Tools
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
bash tools/ci/install_ripgrep.sh
|
||||
bash tools/ci/install_spaceman_dmm.sh dmm-tools
|
||||
tools/bootstrap/python -c ''
|
||||
- name: Run Validation Tests
|
||||
run: bash tools/ci/validate_files.sh
|
||||
- name: Run Define Sanity Checks
|
||||
run: tools/bootstrap/python -m define_sanity.check
|
||||
- name: Run DMI Tests
|
||||
run: tools/bootstrap/python -m dmi.test
|
||||
- name: Run Map Checks
|
||||
run: |
|
||||
tools/bootstrap/python -m tools.maplint.source
|
||||
tools/bootstrap/python -m mapmerge2.dmm_test
|
||||
- name: Run TGUI Checks
|
||||
run: tools/build/build.sh --ci lint tgui-test
|
||||
- name: Run Nanomap Checks
|
||||
run: tools/github-actions/nanomap-renderer-invoker.sh --testing
|
||||
needs: start_gate
|
||||
uses: ./.github/workflows/run_linters.yml
|
||||
|
||||
dreamchecker:
|
||||
if: ( !contains(github.event.head_commit.message, '[ci skip]') )
|
||||
name: DreamChecker
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Restore SpacemanDMM Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/SpacemanDMM
|
||||
key: ${{ runner.os }}-dreamchecker-${{ hashFiles('dependencies.sh')}}
|
||||
restore-keys: ${{ runner.os }}-dreamchecker
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
tools/ci/install_spaceman_dmm.sh dreamchecker
|
||||
|
||||
- name: Run Linter
|
||||
id: linter
|
||||
run: |
|
||||
~/dreamchecker > ${GITHUB_WORKSPACE}/output-annotations.txt 2>&1
|
||||
|
||||
- name: Annotate Linter
|
||||
uses: yogstation13/DreamAnnotate@v2
|
||||
if: always()
|
||||
with:
|
||||
outputFile: output-annotations.txt
|
||||
|
||||
odlint:
|
||||
name: Lint with OpenDream
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 9
|
||||
- uses: actions/checkout@v4
|
||||
- uses: robinraju/release-downloader@v1.12
|
||||
with:
|
||||
repository: "OpenDreamProject/OpenDream"
|
||||
tag: "latest"
|
||||
fileName: "DMCompiler_linux-x64.tar.gz"
|
||||
extract: true
|
||||
- run: ./DMCompiler_linux-x64/DMCompiler --suppress-unimplemented vorestation.dme
|
||||
|
||||
unit_tests:
|
||||
timeout-minutes: 30
|
||||
if: ( !contains(github.event.head_commit.message, '[ci skip]') )
|
||||
strategy:
|
||||
matrix:
|
||||
map: ["USE_MAP_TETHER", "USE_MAP_STELLARDELIGHT", "USE_MAP_GROUNDBASE"]
|
||||
# name: Integration Tests (${{ matrix.map }})
|
||||
run_all_tests:
|
||||
name: Integration Tests
|
||||
# needs: ['run_linters', 'dreamchecker']
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Ensure +x on CI directory
|
||||
run: |
|
||||
chmod -R +x ./tools/ci
|
||||
- name: Restore BYOND from Cache
|
||||
uses: ./.github/actions/restore_or_install_byond
|
||||
with:
|
||||
major: ${{ inputs.major }}
|
||||
minor: ${{ inputs.minor }}
|
||||
- name: Install RUST_G Dependencies
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt update || true
|
||||
sudo apt install zlib1g-dev:i386
|
||||
ldd librust_g.so
|
||||
ldd libbapi_dmm_reader.so
|
||||
ldd libverdigris.so
|
||||
- name: Unit Tests
|
||||
run: tools/ci/compile_and_run.sh
|
||||
env:
|
||||
EXTRA_ARGS: "-DUNIT_TEST -D${{ matrix.map }}"
|
||||
RUN: "1"
|
||||
needs: start_gate
|
||||
uses: ./.github/workflows/perform_regular_version_tests.yml
|
||||
with:
|
||||
maps: '{"paths":["USE_MAP_TETHER","USE_MAP_STELLARDELIGHT","USE_MAP_GROUNDBASE"]}'
|
||||
max_required_byond_client: 516
|
||||
|
||||
extra_map_tests:
|
||||
if: ( !contains(github.event.head_commit.message, '[ci skip]') )
|
||||
name: Map Tests
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Ensure +x on CI directory
|
||||
run: |
|
||||
chmod -R +x ./tools/ci
|
||||
- name: Restore BYOND from Cache
|
||||
uses: ./.github/actions/restore_or_install_byond
|
||||
with:
|
||||
major: ${{ inputs.major }}
|
||||
minor: ${{ inputs.minor }}
|
||||
- name: Compile POIs
|
||||
run: tools/ci/compile_and_run.sh
|
||||
env:
|
||||
EXTRA_ARGS: "-DMAP_TEST"
|
||||
RUN: "0"
|
||||
- name: Compile away missions
|
||||
run: tools/ci/compile_and_run.sh
|
||||
env:
|
||||
EXTRA_ARGS: "-DAWAY_MISSION_TEST -DUSE_MAP_TETHER" # Only Tether has support for all away missions
|
||||
RUN: "0"
|
||||
run_extra_map_tests:
|
||||
name: Extra Map Tests
|
||||
needs: start_gate
|
||||
uses: ./.github/workflows/run_extra_map_tests.yml
|
||||
|
||||
tests_successful:
|
||||
if: ( !contains(github.event.head_commit.message, '[ci skip]') )
|
||||
name: Integration Tests
|
||||
needs: ["run_linters", "dreamchecker", "unit_tests", "extra_map_tests"]
|
||||
completion_gate: # Serves as a non-moving target for branch rulesets
|
||||
if: always() && !cancelled()
|
||||
name: Completion Gate
|
||||
needs:
|
||||
[
|
||||
run_all_tests,
|
||||
run_extra_map_tests,
|
||||
run_linters,
|
||||
]
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Report Success
|
||||
run: |
|
||||
echo "Jobs Successful!"
|
||||
- name: Decide whether the needed jobs succeeded or failed
|
||||
uses: re-actors/alls-green@release/v1
|
||||
with:
|
||||
jobs: ${{ toJSON(needs) }}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
name: Run Regular BYOND Version Tests
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
maps:
|
||||
required: true
|
||||
type: string
|
||||
max_required_byond_client:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: ./.github/workflows/run_integration_tests.yml
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
map: ${{ fromJSON(inputs.maps).paths }}
|
||||
|
||||
with:
|
||||
map: ${{ matrix.map }}
|
||||
max_required_byond_client: ${{ inputs.max_required_byond_client }}
|
||||
@@ -0,0 +1,51 @@
|
||||
name: Run Extra Map Tests
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
major:
|
||||
required: false
|
||||
type: string
|
||||
minor:
|
||||
required: false
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
run_extra_map_tests:
|
||||
# If `inputs.major` is specified, this will output `Run Tests (major.minor; map; max)`.
|
||||
# For example, `Run Tests (515.1627; runtimestation; 515)`.
|
||||
#
|
||||
# Otherwise, it will output `Run Tests (map; max)`.
|
||||
# For example, `Run Tests (runtimestation; 515)`.
|
||||
name: Run Extra Map Tests (${{ inputs.major && format('{0}.{1}; ', inputs.major, inputs.minor) || '' }})
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Ensure +x on CI directory
|
||||
run: |
|
||||
chmod -R +x ./tools/ci
|
||||
- name: Restore BYOND from Cache
|
||||
uses: ./.github/actions/restore_or_install_byond
|
||||
with:
|
||||
major: ${{ inputs.major }}
|
||||
minor: ${{ inputs.minor }}
|
||||
- name: Install RUST_G Dependencies
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt update || true
|
||||
sudo apt install zlib1g-dev:i386
|
||||
ldd librust_g.so
|
||||
ldd libbapi_dmm_reader.so
|
||||
ldd libverdigris.so
|
||||
- name: Compile POIs
|
||||
run: tools/ci/compile_and_run.sh
|
||||
env:
|
||||
EXTRA_ARGS: "-DMAP_TEST"
|
||||
RUN: "0"
|
||||
- name: Compile away missions
|
||||
run: tools/ci/compile_and_run.sh
|
||||
env:
|
||||
EXTRA_ARGS: "-DAWAY_MISSION_TEST -DUSE_MAP_TETHER" # Only Tether has support for all away missions
|
||||
RUN: "0"
|
||||
@@ -0,0 +1,82 @@
|
||||
name: Run Integration Tests
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
map:
|
||||
required: true
|
||||
type: string
|
||||
major:
|
||||
required: false
|
||||
type: string
|
||||
minor:
|
||||
required: false
|
||||
type: string
|
||||
max_required_byond_client:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
run_integration_tests:
|
||||
# If `inputs.major` is specified, this will output `Run Tests (major.minor; map; max)`.
|
||||
# For example, `Run Tests (515.1627; runtimestation; 515)`.
|
||||
#
|
||||
# Otherwise, it will output `Run Tests (map; max)`.
|
||||
# For example, `Run Tests (runtimestation; 515)`.
|
||||
name: Run Tests (${{ inputs.major && format('{0}.{1}; ', inputs.major, inputs.minor) || '' }}${{ inputs.map }}; ${{ inputs.max_required_byond_client }})
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Ensure +x on CI directory
|
||||
run: |
|
||||
chmod -R +x ./tools/ci
|
||||
- name: Restore BYOND from Cache
|
||||
uses: ./.github/actions/restore_or_install_byond
|
||||
with:
|
||||
major: ${{ inputs.major }}
|
||||
minor: ${{ inputs.minor }}
|
||||
- name: Install RUST_G Dependencies
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt update || true
|
||||
sudo apt install zlib1g-dev:i386
|
||||
ldd librust_g.so
|
||||
ldd libbapi_dmm_reader.so
|
||||
ldd libverdigris.so
|
||||
- name: Unit Tests
|
||||
id: run_tests
|
||||
run: tools/ci/compile_and_run.sh
|
||||
env:
|
||||
EXTRA_ARGS: "-DUNIT_TESTS -D${{ inputs.map }}"
|
||||
RUN: "1"
|
||||
- name: On test fail, write a step summary
|
||||
if: always() && steps.run_tests.outcome == 'failure'
|
||||
run: |
|
||||
# Get a JSON array of failed unit tests
|
||||
FAILED_UNIT_TESTS=$(jq 'to_entries | map(.value | select(.status == 1))' data/unit_tests.json)
|
||||
|
||||
FAIL_COUNT=$(echo $FAILED_UNIT_TESTS | jq 'length')
|
||||
|
||||
echo "# Test failures" >> $GITHUB_STEP_SUMMARY
|
||||
echo "$FAIL_COUNT tests failed." >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
for i in $( seq $FAIL_COUNT ); do
|
||||
CURRENT_FAIL=$(echo $FAILED_UNIT_TESTS | jq --arg i $i '.[($i | tonumber) - 1]')
|
||||
|
||||
TEST=$(echo $CURRENT_FAIL | jq --raw-output '.name')
|
||||
|
||||
echo "### $TEST" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
echo $CURRENT_FAIL | jq --raw-output '.message' >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
done
|
||||
- name: Check client Compatibility
|
||||
if: always() && steps.compile_tests.outcome == 'success'
|
||||
uses: tgstation/byond-client-compatibility-check@v3
|
||||
with:
|
||||
dmb-location: vorestation.dmb
|
||||
max-required-client-version: ${{inputs.max_required_byond_client}}
|
||||
@@ -0,0 +1,111 @@
|
||||
name: Run Linters
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
linters:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 5
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# Caches
|
||||
- name: Restore SpacemanDMM cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/SpacemanDMM
|
||||
key: ${{ runner.os }}-spacemandmm-${{ hashFiles('dependencies.sh') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-spacemandmm-
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup_bun
|
||||
- name: Restore Bootstrap cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: tools/bootstrap/.cache
|
||||
key: ${{ runner.os }}-bootstrap-${{ hashFiles('tools/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-bootstrap-
|
||||
- name: Restore Rust cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cargo
|
||||
key: ${{ runner.os }}-rust-${{ hashFiles('tools/ci/ci_dependencies.sh')}}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-rust-
|
||||
- name: Restore Cutter cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: tools/icon_cutter/cache
|
||||
key: ${{ runner.os }}-cutter-${{ hashFiles('dependencies.sh') }}
|
||||
# End Caches
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4.2.0
|
||||
with:
|
||||
dotnet-version: 9.x
|
||||
- name: Install OpenDream
|
||||
uses: robinraju/release-downloader@v1.12
|
||||
with:
|
||||
repository: "OpenDreamProject/OpenDream"
|
||||
tag: "latest"
|
||||
fileName: "DMCompiler_linux-x64.tar.gz"
|
||||
extract: true
|
||||
- name: Install Tools
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
bash tools/ci/install_spaceman_dmm.sh dreamchecker
|
||||
bash tools/ci/install_ripgrep.sh
|
||||
tools/bootstrap/python -c ''
|
||||
- name: Give Linters A Go
|
||||
id: linter-setup
|
||||
run: ":"
|
||||
- name: Ensure genesis_call.dme is unchanged
|
||||
if: steps.linter-setup.conclusion == 'success' && !cancelled()
|
||||
run: bash tools/ci/check_genesis.sh
|
||||
- name: Run Grep Checks
|
||||
if: steps.linter-setup.conclusion == 'success' && !cancelled()
|
||||
run: bash tools/ci/check_grep.sh
|
||||
#- name: Ticked File Enforcement
|
||||
# if: steps.linter-setup.conclusion == 'success' && !cancelled()
|
||||
# run: |
|
||||
# tools/bootstrap/python tools/ticked_file_enforcement/ticked_file_enforcement.py < tools/ticked_file_enforcement/schemas/tgstation_dme.json
|
||||
# tools/bootstrap/python tools/ticked_file_enforcement/ticked_file_enforcement.py < tools/ticked_file_enforcement/schemas/unit_tests.json
|
||||
- name: Run Define Sanity Checks
|
||||
run: tools/bootstrap/python -m define_sanity.check
|
||||
- name: Run DreamChecker
|
||||
if: steps.linter-setup.conclusion == 'success' && !cancelled()
|
||||
shell: bash
|
||||
run: ~/dreamchecker 2>&1 | bash tools/ci/annotate_dm.sh
|
||||
- name: Run OpenDream
|
||||
if: steps.linter-setup.conclusion == 'success' && !cancelled()
|
||||
run: ./DMCompiler_linux-x64/DMCompiler vorestation.dme --suppress-unimplemented --define=CIBUILDING | bash tools/ci/annotate_od.sh
|
||||
- name: Run Map Checks
|
||||
if: steps.linter-setup.conclusion == 'success' && !cancelled()
|
||||
run: |
|
||||
tools/bootstrap/python -m mapmerge2.dmm_test
|
||||
tools/bootstrap/python -m tools.maplint.source
|
||||
- name: Check Cutter
|
||||
if: steps.linter-setup.conclusion == 'success' && !cancelled()
|
||||
run: tools/bootstrap/python -m tools.icon_cutter.check
|
||||
- name: Run DMI Tests
|
||||
if: steps.linter-setup.conclusion == 'success' && !cancelled()
|
||||
run: tools/bootstrap/python -m dmi.test
|
||||
#- name: Check File Directories
|
||||
# if: steps.linter-setup.conclusion == 'success' && !cancelled()
|
||||
# run: bash tools/ci/check_filedirs.sh tgstation.dme
|
||||
- name: Check Changelogs
|
||||
if: steps.linter-setup.conclusion == 'success' && !cancelled()
|
||||
run: bash tools/ci/check_changelogs.sh
|
||||
- name: Check Miscellaneous Files
|
||||
if: steps.linter-setup.conclusion == 'success' && !cancelled()
|
||||
run: bash tools/ci/check_misc.sh
|
||||
- name: Run TGUI Checks
|
||||
if: steps.linter-setup.conclusion == 'success' && !cancelled()
|
||||
run: tools/build/build.sh --ci lint tgui-test
|
||||
|
||||
|
||||
- name: Run Nanomap Checks
|
||||
run: tools/github-actions/nanomap-renderer-invoker.sh --testing
|
||||
+11
-5
@@ -1,13 +1,19 @@
|
||||
###Files and folders specified here will never be tracked.
|
||||
|
||||
#Ignore compiled files and other files generated during compilation.
|
||||
*.dmb
|
||||
*.rsc
|
||||
*.m.dme
|
||||
*.test.dme
|
||||
*.lk
|
||||
*.int
|
||||
*.backup
|
||||
|
||||
#ignore misc BYOND files
|
||||
Thumbs.db
|
||||
vchat.db
|
||||
vchat.db*
|
||||
*.log
|
||||
*.int
|
||||
*.rsc
|
||||
*.dmb
|
||||
*.lk
|
||||
*.backup
|
||||
*.before
|
||||
*.pyc
|
||||
*.pid
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
if("To Kill")
|
||||
to_chat(user, span_boldwarning("Your wish is granted, but at a terrible cost..."))
|
||||
to_chat(user, span_warning("The Wish Granter punishes you for your wickedness, claiming your soul and warping your body to match the darkness in your heart."))
|
||||
ticker.mode.traitors += user.mind
|
||||
SSticker.mode.traitors += user.mind
|
||||
user.mind.special_role = "traitor"
|
||||
var/datum/objective/hijack/hijack = new
|
||||
hijack.owner = user.mind
|
||||
|
||||
@@ -169,10 +169,10 @@
|
||||
//Radio remote control
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = radio_controller.add_object(src, frequency, radio_filter = RADIO_ATMOSIA)
|
||||
radio_connection = SSradio.add_object(src, frequency, radio_filter = RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
|
||||
@@ -144,10 +144,10 @@
|
||||
//Radio remote control
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = radio_controller.add_object(src, frequency, radio_filter = RADIO_ATMOSIA)
|
||||
radio_connection = SSradio.add_object(src, frequency, radio_filter = RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
|
||||
@@ -121,10 +121,10 @@ Thus, the two variables affect pump operation are set in New():
|
||||
//Radio remote control
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = radio_controller.add_object(src, frequency, radio_filter = RADIO_ATMOSIA)
|
||||
radio_connection = SSradio.add_object(src, frequency, radio_filter = RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/machinery/atmospherics/trinary/atmos_filter/proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
|
||||
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/atmos_filter/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -295,10 +295,10 @@
|
||||
//Radio remote control
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/digital/proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
|
||||
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -100,10 +100,10 @@
|
||||
flick("inject", src)
|
||||
|
||||
/obj/machinery/atmospherics/unary/outlet_injector/proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = radio_controller.add_object(src, frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency)
|
||||
|
||||
/obj/machinery/atmospherics/unary/outlet_injector/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
|
||||
@@ -90,9 +90,9 @@
|
||||
add_underlay(T,, dir)
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
radio_connection = radio_controller.add_object(src, frequency, radio_filter_in)
|
||||
radio_connection = SSradio.add_object(src, frequency, radio_filter_in)
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
|
||||
@@ -258,10 +258,10 @@
|
||||
icon_state = "valve[open]nopower"
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital/proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
|
||||
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
/*
|
||||
|
||||
Zone Air System:
|
||||
# Zone Air System
|
||||
|
||||
This air system divides the station into impermeable areas called zones.
|
||||
When something happens, i.e. a door opening or a wall being taken down,
|
||||
zones equalize and eventually merge. Making an airtight area closes the connection again.
|
||||
|
||||
Control Flow:
|
||||
## Control Flow:
|
||||
Every air tick:
|
||||
Marked turfs are updated with update_air_properties(), followed by post_update_air_properties().
|
||||
Edges, including those generated by connections in the previous step, are processed. This is where gas is exchanged.
|
||||
Fire is processed.
|
||||
Marked zones have their air archived.
|
||||
|
||||
Important Functions:
|
||||
## Important Functions:
|
||||
|
||||
SSair.mark_for_update(turf)
|
||||
When stuff happens, call this. It works on everything. You basically don't need to worry about any other
|
||||
@@ -24,5 +22,3 @@ Notes for people who used ZAS before:
|
||||
To get the zones that are connected to a zone, use this loop:
|
||||
for(var/connection_edge/zone/edge in zone.edges)
|
||||
var/zone/connected_zone = edge.get_connected_zone(zone)
|
||||
|
||||
*/
|
||||
+32
-11
@@ -1,5 +1,4 @@
|
||||
#define MC_TICK_CHECK ( ( TICK_USAGE > Master.current_ticklimit || src.state != SS_RUNNING ) ? pause() : 0 )
|
||||
#define CURRENT_RUNLEVEL (2 ** (Master.current_runlevel - 1))
|
||||
|
||||
#define MC_SPLIT_TICK_INIT(phase_count) var/original_tick_limit = Master.current_ticklimit; var/split_tick_phases = ##phase_count
|
||||
#define MC_SPLIT_TICK \
|
||||
@@ -30,7 +29,14 @@
|
||||
#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;}
|
||||
|
||||
#define START_PROCESSING(Processor, Datum) if (!(Datum.datum_flags & DF_ISPROCESSING)) {Datum.datum_flags |= DF_ISPROCESSING;Processor.processing += Datum}
|
||||
#define STOP_PROCESSING(Processor, Datum) Datum.datum_flags &= ~DF_ISPROCESSING;Processor.processing -= Datum
|
||||
#define STOP_PROCESSING(Processor, Datum) Datum.datum_flags &= ~DF_ISPROCESSING;Processor.processing -= Datum;Processor.currentrun -= Datum
|
||||
|
||||
/// Returns true if the MC is initialized and running.
|
||||
/// Optional argument init_stage controls what stage the mc must have initialized to count as initialized. Defaults to INITSTAGE_MAX if not specified.
|
||||
#define MC_RUNNING(INIT_STAGE...) (Master && Master.processing > 0 && Master.current_runlevel && Master.init_stage_completed >= (max(min(INITSTAGE_MAX, ##INIT_STAGE), 1)))
|
||||
|
||||
#define MC_LOOP_RTN_NEWSTAGES 1
|
||||
#define MC_LOOP_RTN_GRACEFUL_EXIT 2
|
||||
|
||||
//! SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier)
|
||||
|
||||
@@ -65,17 +71,26 @@
|
||||
/// This flag overrides SS_KEEP_TIMING
|
||||
#define SS_POST_FIRE_TIMING 64
|
||||
|
||||
/// If this subsystem doesn't initialize, it should not report as a hard error in CI.
|
||||
/// This should be used for subsystems that are flaky for complicated reasons, such as
|
||||
/// the Lua subsystem, which relies on auxtools, which is unstable.
|
||||
/// It should not be used simply to silence CI.
|
||||
#define SS_OK_TO_FAIL_INIT 128
|
||||
|
||||
//! SUBSYSTEM STATES
|
||||
#define SS_IDLE 0 /// aint doing shit.
|
||||
#define SS_QUEUED 1 /// queued to run
|
||||
#define SS_RUNNING 2 /// actively running
|
||||
#define SS_PAUSED 3 /// paused by mc_tick_check
|
||||
#define SS_SLEEPING 4 /// fire() slept.
|
||||
#define SS_PAUSING 5 /// in the middle of pausing
|
||||
#define SS_IDLE 0 /// ain't doing shit.
|
||||
#define SS_QUEUED 1 /// queued to run
|
||||
#define SS_RUNNING 2 /// actively running
|
||||
#define SS_PAUSED 3 /// paused by mc_tick_check
|
||||
#define SS_SLEEPING 4 /// fire() slept.
|
||||
#define SS_PAUSING 5 /// in the middle of pausing
|
||||
|
||||
// Subsystem init stages
|
||||
#define INITSTAGE_EARLY 1 //! Early init stuff that doesn't need to wait for mapload
|
||||
#define INITSTAGE_MAIN 2 //! Main init stage
|
||||
#define INITSTAGE_MAX 2 //! Highest initstage.
|
||||
#define INITSTAGE_FIRST 1
|
||||
#define INITSTAGE_EARLY 2 //! Early init stuff that doesn't need to wait for mapload
|
||||
#define INITSTAGE_MAIN 3 //! Main init stage
|
||||
#define INITSTAGE_LAST 4
|
||||
#define INITSTAGE_MAX 4 //! Highest initstage.
|
||||
|
||||
#define SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/##X);\
|
||||
/datum/controller/subsystem/##X/New(){\
|
||||
@@ -108,6 +123,10 @@
|
||||
/datum/controller/subsystem/verb_manager/##X/fire() {..() /*just so it shows up on the profiler*/} \
|
||||
/datum/controller/subsystem/verb_manager/##X
|
||||
|
||||
|
||||
|
||||
/////// OLD DEFINES
|
||||
|
||||
// Boilerplate code for multi-step processors. See machines.dm for example use.
|
||||
#define INTERNAL_PROCESS_STEP(this_step, initial_step, proc_to_call, cost_var, next_step)\
|
||||
if(current_step == this_step || (initial_step && !resumed)) /* So we start at step 1 if not resumed.*/ {\
|
||||
@@ -120,3 +139,5 @@ if(current_step == this_step || (initial_step && !resumed)) /* So we start at st
|
||||
resumed = 0;\
|
||||
current_step = next_step;\
|
||||
}
|
||||
|
||||
#define CURRENT_RUNLEVEL (2 ** (Master.current_runlevel - 1))
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
// CI will override these as appropriate
|
||||
// #define MAP_TEST 0
|
||||
// #define AWAY_MISSION_TEST 0
|
||||
// #define UNIT_TEST 0
|
||||
// #define UNIT_TESTS 1
|
||||
|
||||
#if defined(CIBUILDING) && !defined(OPENDREAM)
|
||||
#define UNIT_TESTS
|
||||
#endif
|
||||
|
||||
// Comment/Uncomment this to turn off/on shuttle code debugging logs
|
||||
#define DEBUG_SHUTTLES
|
||||
|
||||
@@ -206,6 +206,12 @@ What is the naming convention for planes or layers?
|
||||
|
||||
#define PLANE_ADMIN3 99 //Purely for shenanigans (above HUD)
|
||||
|
||||
///Plane of the "splash" icon used that shows on the lobby screen
|
||||
#define SPLASHSCREEN_PLANE 100
|
||||
|
||||
///cinematics are "below" the splash screen
|
||||
#define CINEMATIC_LAYER -1
|
||||
|
||||
|
||||
//////////////////////////
|
||||
/atom/proc/hud_layerise()
|
||||
|
||||
@@ -929,6 +929,6 @@
|
||||
#define COMSIG_HOSE_FORCEPUMP "hose_force_pump"
|
||||
|
||||
//Unittest data update
|
||||
#ifdef UNIT_TEST
|
||||
#ifdef UNIT_TESTS
|
||||
#define COMSIG_UNITTEST_DATA "unittest_send_data"
|
||||
#endif
|
||||
|
||||
@@ -3,5 +3,26 @@
|
||||
// All signals send the source datum of the signal as the first argument
|
||||
|
||||
///Subsystem signals
|
||||
///From base of datum/controller/subsystem/Initialize
|
||||
///From base of /datum/controller/master/init_subsystem()
|
||||
#define COMSIG_SUBSYSTEM_POST_INITIALIZE "subsystem_post_initialize"
|
||||
|
||||
///Called when the ticker enters the pre-game phase
|
||||
#define COMSIG_TICKER_ENTER_PREGAME "comsig_ticker_enter_pregame"
|
||||
|
||||
///Called when the ticker sets up the game for start
|
||||
#define COMSIG_TICKER_ENTER_SETTING_UP "comsig_ticker_enter_setting_up"
|
||||
|
||||
///Called when the ticker fails to set up the game for start
|
||||
#define COMSIG_TICKER_ERROR_SETTING_UP "comsig_ticker_error_setting_up"
|
||||
|
||||
/// Called when the round has started, but before GAME_STATE_PLAYING.
|
||||
#define COMSIG_TICKER_ROUND_STARTING "comsig_ticker_round_starting"
|
||||
|
||||
// Point of interest signals
|
||||
/// Sent from base of /datum/controller/subsystem/points_of_interest/proc/on_poi_element_added : (atom/new_poi)
|
||||
#define COMSIG_ADDED_POINT_OF_INTEREST "added_point_of_interest"
|
||||
/// Sent from base of /datum/controller/subsystem/points_of_interest/proc/on_poi_element_removed : (atom/old_poi)
|
||||
#define COMSIG_REMOVED_POINT_OF_INTEREST "removed_point_of_interest"
|
||||
|
||||
///Sent after awards are saved in the database (/datum/controller/subsystem/achievements/save_achievements_to_db)
|
||||
#define COMSIG_ACHIEVEMENTS_SAVED_TO_DB "achievements_saved_to_db"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,3 @@
|
||||
// Ticker game states, turns out these are equivilent to runlevels1
|
||||
#define GAME_STATE_INIT 0 // RUNLEVEL_INIT
|
||||
#define GAME_STATE_PREGAME 1 // RUNLEVEL_LOBBY
|
||||
#define GAME_STATE_SETTING_UP 2 // RUNLEVEL_SETUP
|
||||
#define GAME_STATE_PLAYING 3 // RUNLEVEL_GAME
|
||||
#define GAME_STATE_FINISHED 4 // RUNLEVEL_POSTGAME
|
||||
|
||||
//End game state, to manage round end.
|
||||
#define END_GAME_NOT_OVER 1 // Still playing normally
|
||||
#define END_GAME_MODE_FINISHED 2 // Mode has finished but game has not, wait for game to end too.
|
||||
|
||||
@@ -90,3 +90,5 @@ GLOBAL_VAR_INIT(refid_filter, TYPEID(filter(type="angular_blur")))
|
||||
#define isnum_safe(x) ( isnum((x)) && !isnan((x)) && !isinf((x)) )
|
||||
|
||||
#define ismopable(A) (A && (A.plane <= OBJ_PLANE)) //If something can be cleaned by floor-cleaning devices such as mops or clean bots
|
||||
|
||||
#define isfloorturf(A) (istype(A, /turf/simulated/floor))
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/*ALL MOB-RELATED DEFINES THAT DON'T BELONG IN ANOTHER FILE GO HERE*/
|
||||
|
||||
//Misc mob defines
|
||||
|
||||
//Ready states at roundstart for mob/dead/new_player
|
||||
#define PLAYER_NOT_READY 0
|
||||
#define PLAYER_READY_TO_PLAY 1
|
||||
|
||||
// /mob/var/stat things.
|
||||
#define CONSCIOUS 0
|
||||
#define UNCONSCIOUS 1
|
||||
|
||||
@@ -168,6 +168,9 @@
|
||||
*/
|
||||
#define rustg_dmi_inject_metadata(path, metadata) RUSTG_CALL(RUST_G, "dmi_inject_metadata")(path, metadata)
|
||||
|
||||
#define rustg_create_qr_code_png(path, data) RUSTG_CALL(RUST_G, "create_qr_code_png")(path, data)
|
||||
#define rustg_create_qr_code_svg(data) RUSTG_CALL(RUST_G, "create_qr_code_svg")(data)
|
||||
|
||||
#define rustg_file_read(fname) RUSTG_CALL(RUST_G, "file_read")(fname)
|
||||
#define rustg_file_exists(fname) (RUSTG_CALL(RUST_G, "file_exists")(fname) == "true")
|
||||
#define rustg_file_write(text, fname) RUSTG_CALL(RUST_G, "file_write")(text, fname)
|
||||
|
||||
@@ -84,24 +84,6 @@
|
||||
}\
|
||||
}
|
||||
|
||||
// SS runlevels
|
||||
|
||||
#define RUNLEVEL_INIT 0 // "Initialize Only" - Used for subsystems that should never be fired (Should also have SS_NO_FIRE set)
|
||||
#define RUNLEVEL_LOBBY 1 // Initial runlevel before setup. Returns to here if setup fails.
|
||||
#define RUNLEVEL_SETUP 2 // While the gamemode setup is running. I.E gameticker.setup()
|
||||
#define RUNLEVEL_GAME 4 // After successful game ticker setup, while the round is running.
|
||||
#define RUNLEVEL_POSTGAME 8 // When round completes but before reboot
|
||||
|
||||
#define RUNLEVELS_DEFAULT (RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME)
|
||||
|
||||
GLOBAL_LIST_INIT(runlevel_flags, list(
|
||||
RUNLEVEL_LOBBY,
|
||||
RUNLEVEL_SETUP,
|
||||
RUNLEVEL_GAME,
|
||||
RUNLEVEL_POSTGAME
|
||||
))
|
||||
#define RUNLEVEL_FLAG_TO_INDEX(flag) (log(2, flag) + 1) // Convert from the runlevel bitfield constants to index in runlevel_flags list
|
||||
|
||||
//! ### SS initialization hints
|
||||
/**
|
||||
* Negative values indicate a failure or warning of some kind, positive are good.
|
||||
@@ -120,59 +102,8 @@ GLOBAL_LIST_INIT(runlevel_flags, list(
|
||||
/// If your system doesn't need to be initialized (by being disabled or something)
|
||||
#define SS_INIT_NO_NEED 3
|
||||
|
||||
//! ### SS initialization load orders
|
||||
// Subsystem init_order, from highest priority to lowest priority
|
||||
// Subsystems shutdown in the reverse of the order they initialize in
|
||||
// The numbers just define the ordering, they are meaningless otherwise.
|
||||
#define INIT_ORDER_SERVER_MAINT 93
|
||||
#define INIT_ORDER_ADMIN_VERBS 84 // needs to be pretty high, admins can't do much without it
|
||||
#define INIT_ORDER_LOBBY 82
|
||||
#define INIT_ORDER_WEBHOOKS 50
|
||||
#define INIT_ORDER_SQLITE 41
|
||||
#define INIT_ORDER_GARBAGE 40
|
||||
#define INIT_ORDER_DBCORE 39
|
||||
#define INIT_ORDER_MEDIA_TRACKS 38 // Gotta get that lobby music up, yo
|
||||
#define INIT_ORDER_INPUT 37
|
||||
#define INIT_ORDER_CHEMISTRY 35
|
||||
#define INIT_ORDER_ROBOT_SPRITES 34
|
||||
#define INIT_ORDER_VIS 32
|
||||
#define INIT_ORDER_MAPPING 25
|
||||
#define INIT_ORDER_RESEARCH 24
|
||||
#define INIT_ORDER_SOUNDS 23
|
||||
#define INIT_ORDER_INSTRUMENTS 22
|
||||
#define INIT_ORDER_DECALS 20
|
||||
#define INIT_ORDER_PLANTS 19 // Must initialize before atoms.
|
||||
#define INIT_ORDER_PLANETS 18
|
||||
#define INIT_ORDER_JOB 17
|
||||
#define INIT_ORDER_ALARM 16 // Must initialize before atoms.
|
||||
#define INIT_ORDER_TRANSCORE 15
|
||||
#define INIT_ORDER_ATOMS 14
|
||||
#define INIT_ORDER_HOLOMAPS 13
|
||||
#define INIT_ORDER_POIS 12
|
||||
#define INIT_ORDER_MACHINES 10
|
||||
#define INIT_ORDER_STARMOVER 4
|
||||
#define INIT_ORDER_SHUTTLES 3
|
||||
#define INIT_ORDER_TIMER 1
|
||||
#define INIT_ORDER_DEFAULT 0
|
||||
#define INIT_ORDER_LIGHTING 0
|
||||
#define INIT_ORDER_AIR -1
|
||||
#define INIT_ORDER_ASSETS -5
|
||||
#define INIT_ORDER_NIGHTSHIFT -6
|
||||
#define INIT_ORDER_OVERLAY -7
|
||||
#define INIT_ORDER_XENOARCH -20
|
||||
#define INIT_ORDER_CIRCUIT -21
|
||||
#define INIT_ORDER_AI -22
|
||||
#define INIT_ORDER_AI_FAST -23
|
||||
#define INIT_ORDER_GAME_MASTER -24
|
||||
#define INIT_ORDER_PERSISTENCE -25
|
||||
#define INIT_ORDER_SKYBOX -30 //Visual only, irrelevant to gameplay, but needs to be late enough to have overmap populated fully
|
||||
#define INIT_ORDER_TICKER -50
|
||||
#define INIT_ORDER_MAPRENAME -60 //Initiating after Ticker to ensure everything is loaded and everything we rely on us working
|
||||
#define INIT_ORDER_WIKI -61
|
||||
#define INIT_ORDER_ATC -70
|
||||
#define INIT_ORDER_LOOT -80
|
||||
#define INIT_ORDER_STATPANELS -98
|
||||
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
|
||||
/// Successfully initialized, BUT do not announce it to players (generally to hide game mechanics it would otherwise spoil)
|
||||
#define SS_INIT_NO_MESSAGE 4
|
||||
|
||||
// Subsystem fire priority, from lowest to highest priority
|
||||
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
|
||||
@@ -193,6 +124,7 @@ GLOBAL_LIST_INIT(runlevel_flags, list(
|
||||
#define FIRE_PRIORITY_AI 10
|
||||
#define FIRE_PRIORITY_STARMOVER 11
|
||||
#define FIRE_PRIORITY_GARBAGE 15
|
||||
#define FIRE_PRIORITY_DATABASE 16
|
||||
#define FIRE_PRIORITY_ASSETS 20
|
||||
#define FIRE_PRIORITY_POIS 20
|
||||
#define FIRE_PRIORITY_ALARM 20
|
||||
@@ -217,6 +149,36 @@ GLOBAL_LIST_INIT(runlevel_flags, list(
|
||||
#define FIRE_PRIORITY_DELAYED_VERBS 950
|
||||
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
|
||||
|
||||
|
||||
// SS runlevels
|
||||
|
||||
#define RUNLEVEL_LOBBY (1<<0)
|
||||
#define RUNLEVEL_SETUP (1<<1)
|
||||
#define RUNLEVEL_GAME (1<<2)
|
||||
#define RUNLEVEL_POSTGAME (1<<3)
|
||||
|
||||
#define RUNLEVELS_DEFAULT (RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME)
|
||||
|
||||
//SSticker.current_state values
|
||||
/// Game is loading
|
||||
#define GAME_STATE_STARTUP 0
|
||||
/// Game is loaded and in pregame lobby
|
||||
#define GAME_STATE_PREGAME 1
|
||||
/// Game is attempting to start the round
|
||||
#define GAME_STATE_SETTING_UP 2
|
||||
/// Game has round in progress
|
||||
#define GAME_STATE_PLAYING 3
|
||||
/// Game has round finished
|
||||
#define GAME_STATE_FINISHED 4
|
||||
|
||||
// Used for SSticker.force_ending
|
||||
/// Default, round is not being forced to end.
|
||||
#define END_ROUND_AS_NORMAL 0
|
||||
/// End the round now as normal
|
||||
#define FORCE_END_ROUND 1
|
||||
/// For admin forcing roundend, can be used to distinguish the two
|
||||
#define ADMIN_FORCE_END_ROUND 2
|
||||
|
||||
/**
|
||||
Create a new timer and add it to the queue.
|
||||
* Arguments:
|
||||
@@ -227,5 +189,8 @@ GLOBAL_LIST_INIT(runlevel_flags, list(
|
||||
*/
|
||||
#define addtimer(args...) _addtimer(args, file = __FILE__, line = __LINE__)
|
||||
|
||||
// The change in the world's time from the subsystem's last fire in seconds.
|
||||
#define DELTA_WORLD_TIME(ss) ((world.time - ss.last_fire) * 0.1)
|
||||
|
||||
/// The timer key used to know how long subsystem initialization takes
|
||||
#define SS_INIT_TIMER_KEY "ss_init"
|
||||
|
||||
@@ -34,3 +34,101 @@
|
||||
#define MS2DS(T) ((T) MILLISECONDS)
|
||||
|
||||
#define DS2MS(T) ((T) * 100)
|
||||
|
||||
/*Timezones*/
|
||||
|
||||
/// Line Islands Time
|
||||
#define TIMEZONE_LINT 14
|
||||
|
||||
// Chatham Daylight Time
|
||||
#define TIMEZONE_CHADT 13.75
|
||||
|
||||
/// Tokelau Time
|
||||
#define TIMEZONE_TKT 13
|
||||
|
||||
/// Tonga Time
|
||||
#define TIMEZONE_TOT 13
|
||||
|
||||
/// New Zealand Daylight Time
|
||||
#define TIMEZONE_NZDT 13
|
||||
|
||||
/// New Zealand Standard Time
|
||||
#define TIMEZONE_NZST 12
|
||||
|
||||
/// Norfolk Time
|
||||
#define TIMEZONE_NFT 11
|
||||
|
||||
/// Lord Howe Standard Time
|
||||
#define TIMEZONE_LHST 10.5
|
||||
|
||||
/// Australian Eastern Standard Time
|
||||
#define TIMEZONE_AEST 10
|
||||
|
||||
/// Australian Central Standard Time
|
||||
#define TIMEZONE_ACST 9.5
|
||||
|
||||
/// Australian Central Western Standard Time
|
||||
#define TIMEZONE_ACWST 8.75
|
||||
|
||||
/// Australian Western Standard Time
|
||||
#define TIMEZONE_AWST 8
|
||||
|
||||
/// Christmas Island Time
|
||||
#define TIMEZONE_CXT 7
|
||||
|
||||
/// Cocos Islands Time
|
||||
#define TIMEZONE_CCT 6.5
|
||||
|
||||
/// Central European Summer Time
|
||||
#define TIMEZONE_CEST 2
|
||||
|
||||
/// Coordinated Universal Time
|
||||
#define TIMEZONE_UTC 0
|
||||
|
||||
/// Eastern Daylight Time
|
||||
#define TIMEZONE_EDT -4
|
||||
|
||||
/// Eastern Standard Time
|
||||
#define TIMEZONE_EST -5
|
||||
|
||||
/// Central Daylight Time
|
||||
#define TIMEZONE_CDT -5
|
||||
|
||||
/// Central Standard Time
|
||||
#define TIMEZONE_CST -6
|
||||
|
||||
/// Mountain Daylight Time
|
||||
#define TIMEZONE_MDT -6
|
||||
|
||||
/// Mountain Standard Time
|
||||
#define TIMEZONE_MST -7
|
||||
|
||||
/// Pacific Daylight Time
|
||||
#define TIMEZONE_PDT -7
|
||||
|
||||
/// Pacific Standard Time
|
||||
#define TIMEZONE_PST -8
|
||||
|
||||
/// Alaska Daylight Time
|
||||
#define TIMEZONE_AKDT -8
|
||||
|
||||
/// Alaska Standard Time
|
||||
#define TIMEZONE_AKST -9
|
||||
|
||||
/// Hawaii-Aleutian Daylight Time
|
||||
#define TIMEZONE_HDT -9
|
||||
|
||||
/// Hawaii Standard Time
|
||||
#define TIMEZONE_HST -10
|
||||
|
||||
/// Cook Island Time
|
||||
#define TIMEZONE_CKT -10
|
||||
|
||||
/// Niue Time
|
||||
#define TIMEZONE_NUT -11
|
||||
|
||||
/// Anywhere on Earth
|
||||
#define TIMEZONE_ANYWHERE_ON_EARTH -12
|
||||
|
||||
/// in the grim darkness of the thirteenth space station there is no timezones, since they break IC game times. Use this for all IC/round time values
|
||||
#define NO_TIMEZONE 0
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/// File path used for the "enable tracy next round" functionality
|
||||
#define TRACY_ENABLE_PATH "data/enable_tracy"
|
||||
|
||||
/// The DLL path for byond-tracy.
|
||||
#define TRACY_DLL_PATH (world.system_type == MS_WINDOWS ? "prof.dll" : "./libprof.so")
|
||||
@@ -28,6 +28,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
*/
|
||||
#define TRAIT_XENO_HOST "xeno_host" //Tracks whether we're gonna be a baby alien's mummy.
|
||||
#define TRAIT_MIMING "miming" //Tracks whether you're a mime or not.
|
||||
/// "Magic" trait that blocks the mob from moving or interacting with anything. Used for transient stuff like mob transformations or incorporality in special cases.
|
||||
/// Will block movement, `Life()` (!!!), and other stuff based on the mob.
|
||||
#define TRAIT_NO_TRANSFORM "block_transformations"
|
||||
/*
|
||||
#define TRAIT_STUNIMMUNE "stun_immunity"
|
||||
#define TRAIT_STUNRESISTANCE "stun_resistance"
|
||||
|
||||
@@ -38,3 +38,6 @@
|
||||
locate(max(CENTER.x-(H_RADIUS),1), max(CENTER.y-(V_RADIUS),1), CENTER.z), \
|
||||
locate(min(CENTER.x+(H_RADIUS),world.maxx), min(CENTER.y+(V_RADIUS),world.maxy), CENTER.z) \
|
||||
)
|
||||
|
||||
///Returns all turfs in a zlevel
|
||||
#define Z_TURFS(ZLEVEL) block(1, 1, ZLEVEL, world.maxx, world.maxy, ZLEVEL)
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#define ASCII_ESC ascii2text(27)
|
||||
#define ASCII_RED "[ASCII_ESC]\[31m"
|
||||
#define ASCII_GREEN "[ASCII_ESC]\[32m"
|
||||
#define ASCII_YELLOW "[ASCII_ESC]\[33m"
|
||||
#define ASCII_RESET "[ASCII_ESC]\[0m"
|
||||
@@ -83,3 +83,5 @@ GLOBAL_DATUM_INIT(buildmode_hud, /icon, icon('icons/misc/buildmode.dmi'))
|
||||
//Keyed list for caching icons so you don't need to make them for records, IDs, etc all separately.
|
||||
//Could be useful for AI impersonation or something at some point?
|
||||
GLOBAL_LIST_EMPTY(cached_character_icons)
|
||||
|
||||
GLOBAL_VAR_INIT(triai, FALSE)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/// Cache of the states of icon files
|
||||
GLOBAL_LIST_EMPTY(icon_states_cache)
|
||||
/// Cache of the states of icon files, stored associatively with TRUE for lookup
|
||||
GLOBAL_LIST_EMPTY(icon_states_cache_lookup)
|
||||
@@ -1,8 +1,10 @@
|
||||
#define ALL_POSSIBLE_DIRS list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST) // Use this define as Subsystem PreInit comes after GLOB
|
||||
|
||||
GLOBAL_LIST_INIT(cardinal, list(NORTH, SOUTH, EAST, WEST))
|
||||
GLOBAL_LIST_INIT(cardinalz, list(NORTH, SOUTH, EAST, WEST, UP, DOWN))
|
||||
GLOBAL_LIST_INIT(cornerdirs, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
|
||||
GLOBAL_LIST_INIT(cornerdirsz, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST, NORTH|UP, EAST|UP, WEST|UP, SOUTH|UP, NORTH|DOWN, EAST|DOWN, WEST|DOWN, SOUTH|DOWN))
|
||||
GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
|
||||
GLOBAL_LIST_INIT(alldirs, ALL_POSSIBLE_DIRS)
|
||||
GLOBAL_LIST_INIT(reverse_dir, list( // reverse_dir[dir] = reverse of dir
|
||||
2, 1, 3, 8, 10, 9, 11, 4, 6, 5, 7, 12, 14, 13, 15,
|
||||
32, 34, 33, 35, 40, 42, 41, 43, 36, 38, 37, 39, 44, 46, 45, 47,
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
GLOBAL_LIST_INIT(ai_names, world.file2list("strings/names/ai.txt"))
|
||||
GLOBAL_LIST_INIT(wizard_first, world.file2list("strings/names/wizardfirst.txt"))
|
||||
GLOBAL_LIST_INIT(wizard_second, world.file2list("strings/names/wizardsecond.txt"))
|
||||
GLOBAL_LIST_INIT(ninja_titles, world.file2list("strings/names/ninjatitle.txt"))
|
||||
GLOBAL_LIST_INIT(ninja_names, world.file2list("strings/names/ninjaname.txt"))
|
||||
GLOBAL_LIST_INIT(commando_names, world.file2list("strings/names/death_commando.txt"))
|
||||
GLOBAL_LIST_INIT(first_names, world.file2list("strings/names/first.txt"))
|
||||
GLOBAL_LIST_INIT(first_names_male, world.file2list("strings/names/first_male.txt"))
|
||||
GLOBAL_LIST_INIT(first_names_female, world.file2list("strings/names/first_female.txt"))
|
||||
GLOBAL_LIST_INIT(last_names, world.file2list("strings/names/last.txt"))
|
||||
GLOBAL_LIST_INIT(clown_names, world.file2list("strings/names/clown.txt"))
|
||||
|
||||
GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt"))
|
||||
GLOBAL_LIST_INIT(adjectives, world.file2list("strings/names/adjectives.txt"))
|
||||
//loaded on startup because of "
|
||||
//would include in rsc if ' was used
|
||||
@@ -0,0 +1,184 @@
|
||||
|
||||
/*
|
||||
Frequency range: 1200 to 1600
|
||||
Radiochat range: 1441 to 1489 (most devices refuse to be tune to other frequency, even during mapmaking)
|
||||
Radio:
|
||||
1459 - standard radio chat
|
||||
1351 - Science
|
||||
1353 - Command
|
||||
1355 - Medical
|
||||
1357 - Engineering
|
||||
1359 - Security
|
||||
1341 - deathsquad
|
||||
1443 - Confession Intercom
|
||||
1347 - Cargo techs
|
||||
1349 - Service people
|
||||
Devices:
|
||||
1451 - tracking implant
|
||||
1457 - RSD default
|
||||
On the map:
|
||||
1311 for prison shuttle console (in fact, it is not used)
|
||||
1433 for engine components
|
||||
1435 for status displays
|
||||
1437 for atmospherics/fire alerts
|
||||
1439 for air pumps, air scrubbers, atmo control
|
||||
1441 for atmospherics - supply tanks
|
||||
1443 for atmospherics - distribution loop/mixed air tank
|
||||
1445 for bot nav beacons
|
||||
1447 for mulebot, secbot and ed209 control
|
||||
1449 for airlock controls, electropack, magnets
|
||||
1451 for toxin lab access
|
||||
1453 for engineering access
|
||||
1455 for AI access
|
||||
*/
|
||||
|
||||
var/const/RADIO_LOW_FREQ = 1200
|
||||
var/const/PUBLIC_LOW_FREQ = 1441
|
||||
var/const/PUBLIC_HIGH_FREQ = 1489
|
||||
var/const/RADIO_HIGH_FREQ = 1600
|
||||
|
||||
var/const/BOT_FREQ = 1447
|
||||
var/const/COMM_FREQ = 1353
|
||||
var/const/ERT_FREQ = 1345
|
||||
var/const/AI_FREQ = 1343
|
||||
var/const/DTH_FREQ = 1341
|
||||
var/const/SYND_FREQ = 1213
|
||||
var/const/RAID_FREQ = 1277
|
||||
var/const/ENT_FREQ = 1461 //entertainment frequency. This is not a diona exclusive frequency.
|
||||
|
||||
// department channels
|
||||
var/const/PUB_FREQ = 1459
|
||||
var/const/SEC_FREQ = 1359
|
||||
var/const/ENG_FREQ = 1357
|
||||
var/const/MED_FREQ = 1355
|
||||
var/const/SCI_FREQ = 1351
|
||||
var/const/SRV_FREQ = 1349
|
||||
var/const/SUP_FREQ = 1347
|
||||
var/const/EXP_FREQ = 1361
|
||||
|
||||
// internal department channels
|
||||
var/const/MED_I_FREQ = 1485
|
||||
var/const/SEC_I_FREQ = 1475
|
||||
|
||||
var/const/TALON_FREQ = 1363 //VOREStation Add
|
||||
var/const/CSN_FREQ = 1365 //VOREStation Add
|
||||
|
||||
var/list/radiochannels = list(
|
||||
CHANNEL_COMMON = PUB_FREQ,
|
||||
CHANNEL_SCIENCE = SCI_FREQ,
|
||||
CHANNEL_COMMAND = COMM_FREQ,
|
||||
CHANNEL_MEDICAL = MED_FREQ,
|
||||
CHANNEL_ENGINEERING = ENG_FREQ,
|
||||
CHANNEL_SECURITY = SEC_FREQ,
|
||||
CHANNEL_RESPONSE_TEAM = ERT_FREQ,
|
||||
CHANNEL_SPECIAL_OPS = DTH_FREQ,
|
||||
CHANNEL_MERCENARY = SYND_FREQ,
|
||||
CHANNEL_RAIDER = RAID_FREQ,
|
||||
CHANNEL_SUPPLY = SUP_FREQ,
|
||||
CHANNEL_SERVICE = SRV_FREQ,
|
||||
CHANNEL_EXPLORATION = EXP_FREQ,
|
||||
CHANNEL_AI_PRIVATE = AI_FREQ,
|
||||
CHANNEL_ENTERTAINMENT = ENT_FREQ,
|
||||
CHANNEL_MEDICAL_1 = MED_I_FREQ,
|
||||
CHANNEL_SECURITY_1 = SEC_I_FREQ,
|
||||
CHANNEL_TALON = TALON_FREQ, //VOREStation Add
|
||||
CHANNEL_CASINO = CSN_FREQ,
|
||||
)
|
||||
|
||||
// Hey, if anyone ever needs to update tgui/packages/tgui/constants.js with new radio channels
|
||||
// I've kept this around just for you.
|
||||
/* /client/verb/generate_tgui_radio_constants()
|
||||
set name = "Generate TGUI Radio Constants"
|
||||
set category = "Generate TGUI Radio Constants"
|
||||
var/list/channel_info = list()
|
||||
for(var/i in RADIO_LOW_FREQ to RADIO_HIGH_FREQ)
|
||||
for(var/key in radiochannels)
|
||||
if(i == radiochannels[key])
|
||||
channel_info.Add(list(list("name" = key, "freq" = i, "color" = frequency_span_class(i))))
|
||||
for(var/list/channel in channel_info)
|
||||
switch(channel["color"])
|
||||
if("deadsay") channel["color"] = "#530FAD"
|
||||
if("radio") channel["color"] = "#008000"
|
||||
if("deptradio") channel["color"] = "#ff00ff"
|
||||
if("newscaster") channel["color"] = "#750000"
|
||||
if("comradio") channel["color"] = "#193A7A"
|
||||
if("syndradio") channel["color"] = "#6D3F40"
|
||||
if("centradio") channel["color"] = "#5C5C8A"
|
||||
if("airadio") channel["color"] = "#FF00FF"
|
||||
if("entradio") channel["color"] = "#339966"
|
||||
if("secradio") channel["color"] = "#A30000"
|
||||
if("engradio") channel["color"] = "#A66300"
|
||||
if("medradio") channel["color"] = "#008160"
|
||||
if("sciradio") channel["color"] = "#993399"
|
||||
if("supradio") channel["color"] = "#5F4519"
|
||||
if("srvradio") channel["color"] = "#6eaa2c"
|
||||
if("expradio") channel["color"] = "#555555"
|
||||
to_chat(src, json_encode(channel_info)) */
|
||||
|
||||
|
||||
// central command channels, i.e deathsquid & response teams
|
||||
var/list/CENT_FREQS = list(ERT_FREQ, DTH_FREQ)
|
||||
|
||||
// Antag channels, i.e. Syndicate
|
||||
var/list/ANTAG_FREQS = list(SYND_FREQ, RAID_FREQ)
|
||||
|
||||
//Department channels, arranged lexically
|
||||
var/list/DEPT_FREQS = list(AI_FREQ, COMM_FREQ, ENG_FREQ, ENT_FREQ, MED_FREQ, SEC_FREQ, SCI_FREQ, SRV_FREQ, SUP_FREQ)
|
||||
|
||||
var/list/OFFMAP_FREQS = list(TALON_FREQ, CSN_FREQ) //VOREStation Add
|
||||
|
||||
/proc/frequency_span_class(var/frequency)
|
||||
// Antags!
|
||||
if (frequency in ANTAG_FREQS)
|
||||
return "syndradio"
|
||||
// CentCom channels (deathsquid and ert)
|
||||
if(frequency in CENT_FREQS)
|
||||
return "centradio"
|
||||
// command channel
|
||||
if(frequency == COMM_FREQ)
|
||||
return "comradio"
|
||||
// AI private channel
|
||||
if(frequency == AI_FREQ)
|
||||
return "airadio"
|
||||
// department radio formatting (poorly optimized, ugh)
|
||||
if(frequency == SEC_FREQ)
|
||||
return "secradio"
|
||||
if (frequency == ENG_FREQ)
|
||||
return "engradio"
|
||||
if(frequency == SCI_FREQ)
|
||||
return "sciradio"
|
||||
if(frequency == MED_FREQ)
|
||||
return "medradio"
|
||||
if(frequency == SUP_FREQ) // cargo
|
||||
return "supradio"
|
||||
if(frequency == SRV_FREQ) // service
|
||||
return "srvradio"
|
||||
if(frequency == EXP_FREQ) // explorer
|
||||
return "expradio"
|
||||
if(frequency == ENT_FREQ) // entertainment
|
||||
return "entradio"
|
||||
if(frequency in DEPT_FREQS)
|
||||
return "deptradio"
|
||||
//VOREStation Add
|
||||
if(frequency in OFFMAP_FREQS)
|
||||
return "expradio"
|
||||
//VOREStation Add End
|
||||
return "radio"
|
||||
|
||||
/* filters */
|
||||
//When devices register with the radio controller, they might register under a certain filter.
|
||||
//Other devices can then choose to send signals to only those devices that belong to a particular filter.
|
||||
//This is done for performance, so we don't send signals to lots of machines unnecessarily.
|
||||
|
||||
//This filter is special because devices belonging to default also recieve signals sent to any other filter.
|
||||
var/const/RADIO_DEFAULT = "radio_default"
|
||||
|
||||
var/const/RADIO_TO_AIRALARM = "radio_airalarm" //air alarms
|
||||
var/const/RADIO_FROM_AIRALARM = "radio_airalarm_rcvr" //devices interested in recieving signals from air alarms
|
||||
var/const/RADIO_CHAT = "radio_telecoms"
|
||||
var/const/RADIO_ATMOSIA = "radio_atmos"
|
||||
var/const/RADIO_NAVBEACONS = "radio_navbeacon"
|
||||
var/const/RADIO_AIRLOCK = "radio_airlock"
|
||||
var/const/RADIO_SECBOT = "radio_secbot"
|
||||
var/const/RADIO_MULEBOT = "radio_mulebot"
|
||||
var/const/RADIO_MAGNETS = "radio_magnet"
|
||||
@@ -1017,3 +1017,32 @@ GLOBAL_LIST_EMPTY(json_cache)
|
||||
///uses sort_list() but uses the var's name specifically. This should probably be using mergeAtom() instead
|
||||
/proc/sort_names(list/list_to_sort, order=1)
|
||||
return sortTim(list_to_sort.Copy(), order >= 0 ? GLOBAL_PROC_REF(cmp_name_asc) : GLOBAL_PROC_REF(cmp_name_dsc))
|
||||
|
||||
/// Compares 2 lists, returns TRUE if they are the same
|
||||
/proc/deep_compare_list(list/list_1, list/list_2)
|
||||
if(list_1 == list_2)
|
||||
return TRUE
|
||||
|
||||
if(!islist(list_1) || !islist(list_2))
|
||||
return FALSE
|
||||
|
||||
if(list_1.len != list_2.len)
|
||||
return FALSE
|
||||
|
||||
for(var/i in 1 to list_1.len)
|
||||
var/key_1 = list_1[i]
|
||||
var/key_2 = list_2[i]
|
||||
if (islist(key_1) && islist(key_2))
|
||||
if(!deep_compare_list(key_1, key_2))
|
||||
return FALSE
|
||||
else if(key_1 != key_2)
|
||||
return FALSE
|
||||
if(istext(key_1) || islist(key_1) || ispath(key_1) || isdatum(key_1) || key_1 == world)
|
||||
var/value_1 = list_1[key_1]
|
||||
var/value_2 = list_2[key_1]
|
||||
if (islist(value_1) && islist(value_2))
|
||||
if(!deep_compare_list(value_1, value_2))
|
||||
return FALSE
|
||||
else if(value_1 != value_2)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -647,10 +647,15 @@
|
||||
/proc/SecondsToTicks(var/seconds)
|
||||
return seconds * 10
|
||||
|
||||
/proc/window_flash(var/client_or_usr)
|
||||
if (!client_or_usr)
|
||||
///Flash the window of a player
|
||||
/proc/window_flash(client/flashed_client, ignorepref = FALSE)
|
||||
if(ismob(flashed_client))
|
||||
var/mob/player_mob = flashed_client
|
||||
if(player_mob.client)
|
||||
flashed_client = player_mob.client
|
||||
if(!flashed_client || (!flashed_client.prefs.read_preference(/datum/preference/toggle/window_flashing) && !ignorepref))
|
||||
return
|
||||
winset(client_or_usr, "mainwindow", "flash=5")
|
||||
winset(flashed_client, "mainwindow", "flash=5")
|
||||
|
||||
/**
|
||||
* Get a bounding box of a list of atoms.
|
||||
|
||||
@@ -815,6 +815,26 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
|
||||
var/icon/I = getFlatIcon(thing, force_south = force_south)
|
||||
return icon2html(I, target, sourceonly = sourceonly)
|
||||
|
||||
/// Returns rustg-parsed metadata for an icon, universal icon, or DMI file, using cached values where possible
|
||||
/// Returns null if passed object is not a filepath or icon with a valid DMI file
|
||||
/proc/icon_metadata(file)
|
||||
var/static/list/icon_metadata_cache = list()
|
||||
if(istype(file, /datum/universal_icon))
|
||||
var/datum/universal_icon/u_icon = file
|
||||
file = u_icon.icon_file
|
||||
var/file_string = "[file]"
|
||||
if(!istext(file) && !(isfile(file) && length(file_string)))
|
||||
return null
|
||||
var/list/cached_metadata = icon_metadata_cache[file_string]
|
||||
if(islist(cached_metadata))
|
||||
return cached_metadata
|
||||
var/list/metadata_result = rustg_dmi_read_metadata(file_string)
|
||||
if(!islist(metadata_result) || !length(metadata_result))
|
||||
CRASH("Error while reading DMI metadata for path '[file_string]': [metadata_result]")
|
||||
else
|
||||
icon_metadata_cache[file_string] = metadata_result
|
||||
return metadata_result
|
||||
|
||||
/// Checks whether a given icon state exists in a given icon file. If `file` and `state` both exist,
|
||||
/// this will return `TRUE` - otherwise, it will return `FALSE`.
|
||||
///
|
||||
@@ -836,3 +856,25 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
|
||||
icon_states_cache[file][istate] = TRUE
|
||||
|
||||
return !isnull(icon_states_cache[file][state])
|
||||
|
||||
/// Cached, rustg-based alternative to icon_states()
|
||||
/proc/icon_states_fast(file)
|
||||
if(isnull(file))
|
||||
return null
|
||||
if(isnull(GLOB.icon_states_cache[file]))
|
||||
compile_icon_states_cache(file)
|
||||
return GLOB.icon_states_cache[file]
|
||||
|
||||
/proc/compile_icon_states_cache(file)
|
||||
GLOB.icon_states_cache[file] = list()
|
||||
GLOB.icon_states_cache_lookup[file] = list()
|
||||
// Try to use rustg first
|
||||
var/list/metadata = icon_metadata(file)
|
||||
if(islist(metadata) && islist(metadata["states"]))
|
||||
for(var/list/state_data as anything in metadata["states"])
|
||||
GLOB.icon_states_cache[file] += state_data["name"]
|
||||
GLOB.icon_states_cache_lookup[file][state_data["name"]] = TRUE
|
||||
else // Otherwise, we have to use the slower BYOND proc
|
||||
for(var/istate in icon_states(file))
|
||||
GLOB.icon_states_cache[file] += istate
|
||||
GLOB.icon_states_cache_lookup[file][istate] = TRUE
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
WRITE_LOG(GLOB.diary, "TOPIC: [text]")
|
||||
|
||||
/proc/log_unit_test(text)
|
||||
to_world_log("## UNIT_TEST: [text]")
|
||||
to_world_log("## UNIT_TESTS: [text]")
|
||||
|
||||
#ifdef REFERENCE_TRACKING_LOG
|
||||
#define log_reftracker(msg) WRITE_LOG(GLOB.diary, "## REF SEARCH [msg]")
|
||||
|
||||
@@ -93,9 +93,9 @@
|
||||
|
||||
if(!current_species || current_species.name_language == null)
|
||||
if(gender==FEMALE)
|
||||
return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
|
||||
return capitalize(pick(GLOB.first_names_female)) + " " + capitalize(pick(GLOB.last_names))
|
||||
else
|
||||
return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
|
||||
return capitalize(pick(GLOB.first_names_male)) + " " + capitalize(pick(GLOB.last_names))
|
||||
else
|
||||
return current_species.get_random_name(gender)
|
||||
|
||||
|
||||
@@ -195,9 +195,9 @@ GLOBAL_VAR(syndicate_code_response) //Code response for traitors.
|
||||
if(names.len&&prob(70))
|
||||
code_phrase += pick(names)
|
||||
else
|
||||
code_phrase += pick(pick(first_names_male,first_names_female))
|
||||
code_phrase += pick(pick(GLOB.first_names_male, GLOB.first_names_female))
|
||||
code_phrase += " "
|
||||
code_phrase += pick(last_names)
|
||||
code_phrase += pick(GLOB.last_names)
|
||||
if(2)
|
||||
code_phrase += pick(GLOB.joblist)//Returns a job.
|
||||
safety -= 1
|
||||
@@ -213,9 +213,9 @@ GLOBAL_VAR(syndicate_code_response) //Code response for traitors.
|
||||
if(1)
|
||||
code_phrase += pick(nouns)
|
||||
if(2)
|
||||
code_phrase += pick(adjectives)
|
||||
code_phrase += pick(GLOB.adjectives)
|
||||
if(3)
|
||||
code_phrase += pick(verbs)
|
||||
code_phrase += pick(GLOB.verbs)
|
||||
if(words==1)
|
||||
code_phrase += "."
|
||||
else
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/datum/controller/subsystem/ticker/proc/declare_completion(was_forced = END_ROUND_AS_NORMAL)
|
||||
set waitfor = FALSE
|
||||
|
||||
for(var/datum/callback/roundend_callbacks as anything in round_end_events)
|
||||
roundend_callbacks.InvokeAsync()
|
||||
LAZYCLEARLIST(round_end_events)
|
||||
|
||||
to_world(span_filter_system("<br><br><br><H1>A round of [mode.name] has ended!</H1>"))
|
||||
for(var/mob/Player in GLOB.player_list)
|
||||
if(Player.mind && !isnewplayer(Player))
|
||||
if(Player.stat != DEAD)
|
||||
var/turf/playerTurf = get_turf(Player)
|
||||
if(emergency_shuttle.departed && emergency_shuttle.evac)
|
||||
if(isNotAdminLevel(playerTurf.z))
|
||||
to_chat(Player, span_filter_system(span_blue(span_bold("You survived the round, but remained on [station_name()] as [Player.real_name]."))))
|
||||
else
|
||||
to_chat(Player, span_filter_system(span_green(span_bold("You managed to survive the events on [station_name()] as [Player.real_name]."))))
|
||||
else if(isAdminLevel(playerTurf.z))
|
||||
to_chat(Player, span_filter_system(span_green(span_bold("You successfully underwent crew transfer after events on [station_name()] as [Player.real_name]."))))
|
||||
else if(issilicon(Player))
|
||||
to_chat(Player, span_filter_system(span_green(span_bold("You remain operational after the events on [station_name()] as [Player.real_name]."))))
|
||||
else
|
||||
to_chat(Player, span_filter_system(span_blue(span_bold("You missed the crew transfer after the events on [station_name()] as [Player.real_name]."))))
|
||||
else
|
||||
if(isobserver(Player))
|
||||
var/mob/observer/dead/O = Player
|
||||
if(!O.started_as_observer)
|
||||
to_chat(Player, span_filter_system(span_red(span_bold("You did not survive the events on [station_name()]..."))))
|
||||
else
|
||||
to_chat(Player, span_filter_system(span_red(span_bold("You did not survive the events on [station_name()]..."))))
|
||||
to_world(span_filter_system("<br>"))
|
||||
|
||||
for (var/mob/living/silicon/ai/aiPlayer in GLOB.mob_list)
|
||||
if (aiPlayer.stat != 2)
|
||||
to_world(span_filter_system(span_bold("[aiPlayer.name]'s laws at the end of the round were:"))) // VOREStation edit
|
||||
else
|
||||
to_world(span_filter_system(span_bold("[aiPlayer.name]'s laws when it was deactivated were:"))) // VOREStation edit
|
||||
aiPlayer.show_laws(1)
|
||||
|
||||
if (aiPlayer.connected_robots.len)
|
||||
var/robolist = span_bold("The AI's loyal minions were:") + " "
|
||||
for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots)
|
||||
robolist += "[robo.name][robo.stat?" (Deactivated), ":", "]" // VOREStation edit
|
||||
to_world(span_filter_system("[robolist]"))
|
||||
|
||||
var/dronecount = 0
|
||||
|
||||
for (var/mob/living/silicon/robot/robo in GLOB.mob_list)
|
||||
|
||||
if(istype(robo, /mob/living/silicon/robot/platform))
|
||||
var/mob/living/silicon/robot/platform/tank = robo
|
||||
if(!tank.has_had_player)
|
||||
continue
|
||||
|
||||
if(istype(robo,/mob/living/silicon/robot/drone) && !istype(robo,/mob/living/silicon/robot/drone/swarm))
|
||||
dronecount++
|
||||
continue
|
||||
|
||||
if (!robo.connected_ai)
|
||||
if (robo.stat != 2)
|
||||
to_world(span_filter_system(span_bold("[robo.name] survived as an AI-less stationbound synthetic! Its laws were:"))) // VOREStation edit
|
||||
else
|
||||
to_world(span_filter_system(span_bold("[robo.name] was unable to survive the rigors of being a stationbound synthetic without an AI. Its laws were:"))) // VOREStation edit
|
||||
|
||||
if(robo) //How the hell do we lose robo between here and the world messages directly above this?
|
||||
robo.laws.show_laws(world)
|
||||
|
||||
if(dronecount)
|
||||
to_world(span_filter_system(span_bold("There [dronecount>1 ? "were" : "was"] [dronecount] industrious maintenance [dronecount>1 ? "drones" : "drone"] at the end of this round.")))
|
||||
|
||||
mode.declare_completion()//To declare normal completion.
|
||||
|
||||
//Ask the event manager to print round end information
|
||||
SSevents.RoundEnd()
|
||||
|
||||
//Print a list of antagonists to the server log
|
||||
var/list/total_antagonists = list()
|
||||
//Look into all mobs in world, dead or alive
|
||||
for(var/datum/mind/Mind in minds)
|
||||
var/temprole = Mind.special_role
|
||||
if(temprole) //if they are an antagonist of some sort.
|
||||
if(temprole in total_antagonists) //If the role exists already, add the name to it
|
||||
total_antagonists[temprole] += ", [Mind.name]([Mind.key])"
|
||||
else
|
||||
total_antagonists.Add(temprole) //If the role doesnt exist in the list, create it and add the mob
|
||||
total_antagonists[temprole] += ": [Mind.name]([Mind.key])"
|
||||
|
||||
//Now print them all into the log!
|
||||
log_game("Antagonists at round end were...")
|
||||
for(var/i in total_antagonists)
|
||||
log_game("[i]s[total_antagonists[i]].")
|
||||
|
||||
SSdbcore.SetRoundEnd()
|
||||
|
||||
sleep(5 SECONDS)
|
||||
ready_for_reboot = TRUE
|
||||
standard_reboot()
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/standard_reboot()
|
||||
if(ready_for_reboot)
|
||||
if(mode.station_was_nuked)
|
||||
Reboot("Station destroyed by Nuclear Device.", "nuke")
|
||||
else
|
||||
Reboot("Round ended.", "proper completion")
|
||||
else
|
||||
CRASH("Attempted standard reboot without ticker roundend completion")
|
||||
@@ -13,7 +13,10 @@
|
||||
|
||||
// Sorts subsystems by init_order
|
||||
/proc/cmp_subsystem_init(datum/controller/subsystem/a, datum/controller/subsystem/b)
|
||||
return initial(b.init_order) - initial(a.init_order) //uses initial() so it can be used on types
|
||||
return a.init_order - b.init_order
|
||||
|
||||
/proc/cmp_subsystem_init_stage(datum/controller/subsystem/a, datum/controller/subsystem/b)
|
||||
return initial(a.init_stage) - initial(b.init_stage)
|
||||
|
||||
// Sorts subsystems by priority
|
||||
/proc/cmp_subsystem_priority(datum/controller/subsystem/a, datum/controller/subsystem/b)
|
||||
|
||||
+12
-6
@@ -121,24 +121,30 @@ GLOBAL_VAR_INIT(round_start_time, 0)
|
||||
rollovercheck_last_timeofday = world.timeofday
|
||||
return midnight_rollovers
|
||||
|
||||
//Increases delay as the server gets more overloaded,
|
||||
//as sleeps aren't cheap and sleeping only to wake up and sleep again is wasteful
|
||||
///Increases delay as the server gets more overloaded, as sleeps aren't cheap and sleeping only to wake up and sleep again is wasteful
|
||||
#define DELTA_CALC max(((max(TICK_USAGE, world.cpu) / 100) * max(Master.sleep_delta-1,1)), 1)
|
||||
|
||||
//returns the number of ticks slept
|
||||
///returns the number of ticks slept
|
||||
/proc/stoplag(initial_delay)
|
||||
if (!Master || !(Master.current_runlevel & RUNLEVELS_DEFAULT))
|
||||
if (!Master || Master.init_stage_completed < INITSTAGE_MAX)
|
||||
sleep(world.tick_lag)
|
||||
return 1
|
||||
if (!initial_delay)
|
||||
initial_delay = world.tick_lag
|
||||
// Unit tests are not the normal environemnt. The mc can get absolutely thigh crushed, and sleeping procs running for ages is much more common
|
||||
// We don't want spurious hard deletes off this, so let's only sleep for the requested period of time here yeah?
|
||||
#ifdef UNIT_TESTS
|
||||
sleep(initial_delay)
|
||||
return CEILING(DS2TICKS(initial_delay), 1)
|
||||
#else
|
||||
. = 0
|
||||
var/i = DS2TICKS(initial_delay)
|
||||
do
|
||||
. += CEILING(i*DELTA_CALC, 1)
|
||||
sleep(i*world.tick_lag*DELTA_CALC)
|
||||
. += CEILING(i * DELTA_CALC, 1)
|
||||
sleep(i * world.tick_lag * DELTA_CALC)
|
||||
i *= 2
|
||||
while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit))
|
||||
#endif
|
||||
|
||||
#undef DELTA_CALC
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
if(is_incorporeal())
|
||||
return 0
|
||||
|
||||
if(!ticker)
|
||||
if(!SSticker)
|
||||
to_chat(src, "You cannot attack people before the game has started.")
|
||||
return 0
|
||||
|
||||
|
||||
@@ -143,6 +143,15 @@
|
||||
show_when_dead = TRUE
|
||||
plane = PLANE_PLAYER_HUD_ABOVE
|
||||
|
||||
/obj/screen/fullscreen/cinematic_backdrop
|
||||
icon = 'icons/hud/screen_gen.dmi'
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
icon_state = "flash"
|
||||
plane = SPLASHSCREEN_PLANE
|
||||
layer = CINEMATIC_LAYER
|
||||
color = COLOR_BLACK
|
||||
show_when_dead = TRUE
|
||||
|
||||
/obj/screen/fullscreen/lighting_backdrop
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "flash"
|
||||
|
||||
@@ -79,7 +79,7 @@ ADMIN_VERB(debug_controller, R_DEBUG, "Debug Controller", "Debug the various per
|
||||
//Goon PS stuff, and other yet-to-be-subsystem things.
|
||||
options["LEGACY: master_controller"] = master_controller
|
||||
options["LEGACY: job_master"] = job_master
|
||||
options["LEGACY: radio_controller"] = radio_controller
|
||||
options["LEGACY: SSradio"] = SSradio
|
||||
options["LEGACY: emergency_shuttle"] = emergency_shuttle
|
||||
options["LEGACY: paiController"] = paiController
|
||||
options["LEGACY: cameranet"] = cameranet
|
||||
|
||||
@@ -1,394 +0,0 @@
|
||||
/*
|
||||
HOW IT WORKS
|
||||
|
||||
The radio_controller is a global object maintaining all radio transmissions, think about it as about "ether".
|
||||
Note that walkie-talkie, intercoms and headsets handle transmission using nonstandard way.
|
||||
procs:
|
||||
|
||||
add_object(obj/device as obj, var/new_frequency as num, var/radio_filter as text|null = null)
|
||||
Adds listening object.
|
||||
parameters:
|
||||
device - device receiving signals, must have proc receive_signal (see description below).
|
||||
one device may listen several frequencies, but not same frequency twice.
|
||||
new_frequency - see possibly frequencies below;
|
||||
radio_filter - thing for optimization. Optional, but recommended.
|
||||
All filters should be consolidated in this file, see defines later.
|
||||
Device without listening filter will receive all signals (on specified frequency).
|
||||
Device with filter will receive any signals sent without filter.
|
||||
Device with filter will not receive any signals sent with different filter.
|
||||
returns:
|
||||
Reference to frequency object.
|
||||
|
||||
remove_object (obj/device, old_frequency)
|
||||
Obliviously, after calling this proc, device will not receive any signals on old_frequency.
|
||||
Other frequencies will left unaffected.
|
||||
|
||||
return_frequency(var/frequency as num)
|
||||
returns:
|
||||
Reference to frequency object. Use it if you need to send and do not need to listen.
|
||||
|
||||
radio_frequency is a global object maintaining list of devices that listening specific frequency.
|
||||
procs:
|
||||
|
||||
post_signal(obj/source as obj|null, datum/signal/signal, var/radio_filter as text|null = null, var/range as num|null = null)
|
||||
Sends signal to all devices that wants such signal.
|
||||
parameters:
|
||||
source - object, emitted signal. Usually, devices will not receive their own signals.
|
||||
signal - see description below.
|
||||
radio_filter - described above.
|
||||
range - radius of regular byond's square circle on that z-level. null means everywhere, on all z-levels.
|
||||
|
||||
obj/proc/receive_signal(datum/signal/signal, var/receive_method as num, var/receive_param)
|
||||
Handler from received signals. By default does nothing. Define your own for your object.
|
||||
Avoid of sending signals directly from this proc, use spawn(-1). DO NOT use sleep() here or call procs that sleep please. If you must, use spawn()
|
||||
parameters:
|
||||
signal - see description below. Extract all needed data from the signal before doing sleep(), spawn() or return!
|
||||
receive_method - may be TRANSMISSION_WIRE or TRANSMISSION_RADIO.
|
||||
TRANSMISSION_WIRE is currently unused.
|
||||
receive_param - for TRANSMISSION_RADIO here comes frequency.
|
||||
|
||||
datum/signal
|
||||
vars:
|
||||
source
|
||||
an object that emitted signal. Used for debug and bearing.
|
||||
data
|
||||
list with transmitting data. Usual use pattern:
|
||||
data["msg"] = "hello world"
|
||||
encryption
|
||||
Some number symbolizing "encryption key".
|
||||
Note that game actually do not use any cryptography here.
|
||||
If receiving object don't know right key, it must ignore encrypted signal in its receive_signal.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Frequency range: 1200 to 1600
|
||||
Radiochat range: 1441 to 1489 (most devices refuse to be tune to other frequency, even during mapmaking)
|
||||
|
||||
Radio:
|
||||
1459 - standard radio chat
|
||||
1351 - Science
|
||||
1353 - Command
|
||||
1355 - Medical
|
||||
1357 - Engineering
|
||||
1359 - Security
|
||||
1341 - deathsquad
|
||||
1443 - Confession Intercom
|
||||
1347 - Cargo techs
|
||||
1349 - Service people
|
||||
|
||||
Devices:
|
||||
1451 - tracking implant
|
||||
1457 - RSD default
|
||||
|
||||
On the map:
|
||||
1311 for prison shuttle console (in fact, it is not used)
|
||||
1433 for engine components
|
||||
1435 for status displays
|
||||
1437 for atmospherics/fire alerts
|
||||
1439 for air pumps, air scrubbers, atmo control
|
||||
1441 for atmospherics - supply tanks
|
||||
1443 for atmospherics - distribution loop/mixed air tank
|
||||
1445 for bot nav beacons
|
||||
1447 for mulebot, secbot and ed209 control
|
||||
1449 for airlock controls, electropack, magnets
|
||||
1451 for toxin lab access
|
||||
1453 for engineering access
|
||||
1455 for AI access
|
||||
*/
|
||||
|
||||
var/const/RADIO_LOW_FREQ = 1200
|
||||
var/const/PUBLIC_LOW_FREQ = 1441
|
||||
var/const/PUBLIC_HIGH_FREQ = 1489
|
||||
var/const/RADIO_HIGH_FREQ = 1600
|
||||
|
||||
var/const/BOT_FREQ = 1447
|
||||
var/const/COMM_FREQ = 1353
|
||||
var/const/ERT_FREQ = 1345
|
||||
var/const/AI_FREQ = 1343
|
||||
var/const/DTH_FREQ = 1341
|
||||
var/const/SYND_FREQ = 1213
|
||||
var/const/RAID_FREQ = 1277
|
||||
var/const/ENT_FREQ = 1461 //entertainment frequency. This is not a diona exclusive frequency.
|
||||
|
||||
// department channels
|
||||
var/const/PUB_FREQ = 1459
|
||||
var/const/SEC_FREQ = 1359
|
||||
var/const/ENG_FREQ = 1357
|
||||
var/const/MED_FREQ = 1355
|
||||
var/const/SCI_FREQ = 1351
|
||||
var/const/SRV_FREQ = 1349
|
||||
var/const/SUP_FREQ = 1347
|
||||
var/const/EXP_FREQ = 1361
|
||||
|
||||
// internal department channels
|
||||
var/const/MED_I_FREQ = 1485
|
||||
var/const/SEC_I_FREQ = 1475
|
||||
|
||||
var/const/TALON_FREQ = 1363 //VOREStation Add
|
||||
var/const/CSN_FREQ = 1365 //VOREStation Add
|
||||
|
||||
var/list/radiochannels = list(
|
||||
CHANNEL_COMMON = PUB_FREQ,
|
||||
CHANNEL_SCIENCE = SCI_FREQ,
|
||||
CHANNEL_COMMAND = COMM_FREQ,
|
||||
CHANNEL_MEDICAL = MED_FREQ,
|
||||
CHANNEL_ENGINEERING = ENG_FREQ,
|
||||
CHANNEL_SECURITY = SEC_FREQ,
|
||||
CHANNEL_RESPONSE_TEAM = ERT_FREQ,
|
||||
CHANNEL_SPECIAL_OPS = DTH_FREQ,
|
||||
CHANNEL_MERCENARY = SYND_FREQ,
|
||||
CHANNEL_RAIDER = RAID_FREQ,
|
||||
CHANNEL_SUPPLY = SUP_FREQ,
|
||||
CHANNEL_SERVICE = SRV_FREQ,
|
||||
CHANNEL_EXPLORATION = EXP_FREQ,
|
||||
CHANNEL_AI_PRIVATE = AI_FREQ,
|
||||
CHANNEL_ENTERTAINMENT = ENT_FREQ,
|
||||
CHANNEL_MEDICAL_1 = MED_I_FREQ,
|
||||
CHANNEL_SECURITY_1 = SEC_I_FREQ,
|
||||
CHANNEL_TALON = TALON_FREQ, //VOREStation Add
|
||||
CHANNEL_CASINO = CSN_FREQ,
|
||||
)
|
||||
|
||||
// Hey, if anyone ever needs to update tgui/packages/tgui/constants.js with new radio channels
|
||||
// I've kept this around just for you.
|
||||
/* /client/verb/generate_tgui_radio_constants()
|
||||
set name = "Generate TGUI Radio Constants"
|
||||
set category = "Generate TGUI Radio Constants"
|
||||
|
||||
var/list/channel_info = list()
|
||||
|
||||
for(var/i in RADIO_LOW_FREQ to RADIO_HIGH_FREQ)
|
||||
for(var/key in radiochannels)
|
||||
if(i == radiochannels[key])
|
||||
channel_info.Add(list(list("name" = key, "freq" = i, "color" = frequency_span_class(i))))
|
||||
|
||||
for(var/list/channel in channel_info)
|
||||
switch(channel["color"])
|
||||
if("deadsay") channel["color"] = "#530FAD"
|
||||
if("radio") channel["color"] = "#008000"
|
||||
if("deptradio") channel["color"] = "#ff00ff"
|
||||
if("newscaster") channel["color"] = "#750000"
|
||||
if("comradio") channel["color"] = "#193A7A"
|
||||
if("syndradio") channel["color"] = "#6D3F40"
|
||||
if("centradio") channel["color"] = "#5C5C8A"
|
||||
if("airadio") channel["color"] = "#FF00FF"
|
||||
if("entradio") channel["color"] = "#339966"
|
||||
if("secradio") channel["color"] = "#A30000"
|
||||
if("engradio") channel["color"] = "#A66300"
|
||||
if("medradio") channel["color"] = "#008160"
|
||||
if("sciradio") channel["color"] = "#993399"
|
||||
if("supradio") channel["color"] = "#5F4519"
|
||||
if("srvradio") channel["color"] = "#6eaa2c"
|
||||
if("expradio") channel["color"] = "#555555"
|
||||
|
||||
to_chat(src, json_encode(channel_info)) */
|
||||
|
||||
|
||||
// central command channels, i.e deathsquid & response teams
|
||||
var/list/CENT_FREQS = list(ERT_FREQ, DTH_FREQ)
|
||||
|
||||
// Antag channels, i.e. Syndicate
|
||||
var/list/ANTAG_FREQS = list(SYND_FREQ, RAID_FREQ)
|
||||
|
||||
//Department channels, arranged lexically
|
||||
var/list/DEPT_FREQS = list(AI_FREQ, COMM_FREQ, ENG_FREQ, ENT_FREQ, MED_FREQ, SEC_FREQ, SCI_FREQ, SRV_FREQ, SUP_FREQ)
|
||||
|
||||
var/list/OFFMAP_FREQS = list(TALON_FREQ, CSN_FREQ) //VOREStation Add
|
||||
|
||||
/proc/frequency_span_class(var/frequency)
|
||||
// Antags!
|
||||
if (frequency in ANTAG_FREQS)
|
||||
return "syndradio"
|
||||
// CentCom channels (deathsquid and ert)
|
||||
if(frequency in CENT_FREQS)
|
||||
return "centradio"
|
||||
// command channel
|
||||
if(frequency == COMM_FREQ)
|
||||
return "comradio"
|
||||
// AI private channel
|
||||
if(frequency == AI_FREQ)
|
||||
return "airadio"
|
||||
// department radio formatting (poorly optimized, ugh)
|
||||
if(frequency == SEC_FREQ)
|
||||
return "secradio"
|
||||
if (frequency == ENG_FREQ)
|
||||
return "engradio"
|
||||
if(frequency == SCI_FREQ)
|
||||
return "sciradio"
|
||||
if(frequency == MED_FREQ)
|
||||
return "medradio"
|
||||
if(frequency == SUP_FREQ) // cargo
|
||||
return "supradio"
|
||||
if(frequency == SRV_FREQ) // service
|
||||
return "srvradio"
|
||||
if(frequency == EXP_FREQ) // explorer
|
||||
return "expradio"
|
||||
if(frequency == ENT_FREQ) // entertainment
|
||||
return "entradio"
|
||||
if(frequency in DEPT_FREQS)
|
||||
return "deptradio"
|
||||
//VOREStation Add
|
||||
if(frequency in OFFMAP_FREQS)
|
||||
return "expradio"
|
||||
//VOREStation Add End
|
||||
return "radio"
|
||||
|
||||
/* filters */
|
||||
//When devices register with the radio controller, they might register under a certain filter.
|
||||
//Other devices can then choose to send signals to only those devices that belong to a particular filter.
|
||||
//This is done for performance, so we don't send signals to lots of machines unnecessarily.
|
||||
|
||||
//This filter is special because devices belonging to default also recieve signals sent to any other filter.
|
||||
var/const/RADIO_DEFAULT = "radio_default"
|
||||
|
||||
var/const/RADIO_TO_AIRALARM = "radio_airalarm" //air alarms
|
||||
var/const/RADIO_FROM_AIRALARM = "radio_airalarm_rcvr" //devices interested in recieving signals from air alarms
|
||||
var/const/RADIO_CHAT = "radio_telecoms"
|
||||
var/const/RADIO_ATMOSIA = "radio_atmos"
|
||||
var/const/RADIO_NAVBEACONS = "radio_navbeacon"
|
||||
var/const/RADIO_AIRLOCK = "radio_airlock"
|
||||
var/const/RADIO_SECBOT = "radio_secbot"
|
||||
var/const/RADIO_MULEBOT = "radio_mulebot"
|
||||
var/const/RADIO_MAGNETS = "radio_magnet"
|
||||
|
||||
var/global/datum/controller/radio/radio_controller
|
||||
|
||||
/hook/startup/proc/createRadioController()
|
||||
radio_controller = new /datum/controller/radio()
|
||||
return 1
|
||||
|
||||
//callback used by objects to react to incoming radio signals
|
||||
/obj/proc/receive_signal(datum/signal/signal, receive_method, receive_param)
|
||||
return null
|
||||
|
||||
//The global radio controller
|
||||
/datum/controller/radio
|
||||
var/list/datum/radio_frequency/frequencies = list()
|
||||
|
||||
/datum/controller/radio/proc/add_object(obj/device as obj, var/new_frequency as num, var/radio_filter = null as text|null)
|
||||
var/f_text = num2text(new_frequency)
|
||||
var/datum/radio_frequency/frequency = frequencies[f_text]
|
||||
|
||||
if(!frequency)
|
||||
frequency = new
|
||||
frequency.frequency = new_frequency
|
||||
frequencies[f_text] = frequency
|
||||
|
||||
frequency.add_listener(device, radio_filter)
|
||||
return frequency
|
||||
|
||||
/datum/controller/radio/proc/remove_object(obj/device, old_frequency)
|
||||
var/f_text = num2text(old_frequency)
|
||||
var/datum/radio_frequency/frequency = frequencies[f_text]
|
||||
|
||||
if(frequency)
|
||||
frequency.remove_listener(device)
|
||||
|
||||
if(frequency.devices.len == 0)
|
||||
qdel(frequency)
|
||||
frequencies -= f_text
|
||||
|
||||
return 1
|
||||
|
||||
/datum/controller/radio/proc/return_frequency(var/new_frequency as num)
|
||||
var/f_text = num2text(new_frequency)
|
||||
var/datum/radio_frequency/frequency = frequencies[f_text]
|
||||
|
||||
if(!frequency)
|
||||
frequency = new
|
||||
frequency.frequency = new_frequency
|
||||
frequencies[f_text] = frequency
|
||||
|
||||
return frequency
|
||||
|
||||
/datum/radio_frequency
|
||||
var/frequency as num
|
||||
var/list/list/obj/devices = list()
|
||||
|
||||
/datum/radio_frequency/proc/post_signal(obj/source as obj|null, datum/signal/signal, var/radio_filter = null as text|null, var/range = null as num|null)
|
||||
var/turf/start_point
|
||||
if(range)
|
||||
start_point = get_turf(source)
|
||||
if(!start_point)
|
||||
qdel(signal)
|
||||
return 0
|
||||
if (radio_filter)
|
||||
send_to_filter(source, signal, radio_filter, start_point, range)
|
||||
send_to_filter(source, signal, RADIO_DEFAULT, start_point, range)
|
||||
else
|
||||
//Broadcast the signal to everyone!
|
||||
for (var/next_filter in devices)
|
||||
send_to_filter(source, signal, next_filter, start_point, range)
|
||||
|
||||
//Sends a signal to all machines belonging to a given filter. Should be called by post_signal()
|
||||
/datum/radio_frequency/proc/send_to_filter(obj/source, datum/signal/signal, var/radio_filter, var/turf/start_point = null, var/range = null)
|
||||
if (range && !start_point)
|
||||
return
|
||||
|
||||
for(var/obj/device in devices[radio_filter])
|
||||
if(device == source)
|
||||
continue
|
||||
if(range)
|
||||
var/turf/end_point = get_turf(device)
|
||||
if(!end_point)
|
||||
continue
|
||||
if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range)
|
||||
continue
|
||||
|
||||
device.receive_signal(signal, TRANSMISSION_RADIO, frequency)
|
||||
|
||||
/datum/radio_frequency/proc/add_listener(obj/device as obj, var/radio_filter as text|null)
|
||||
if (!radio_filter)
|
||||
radio_filter = RADIO_DEFAULT
|
||||
//log_admin("add_listener(device=[device],radio_filter=[radio_filter]) frequency=[frequency]")
|
||||
var/list/obj/devices_line = devices[radio_filter]
|
||||
if (!devices_line)
|
||||
devices_line = new
|
||||
devices[radio_filter] = devices_line
|
||||
devices_line+=device
|
||||
// var/list/obj/devices_line___ = devices[filter_str]
|
||||
// var/l = devices_line___.len
|
||||
//log_admin("DEBUG: devices_line.len=[devices_line.len]")
|
||||
//log_admin("DEBUG: devices(filter_str).len=[l]")
|
||||
|
||||
/datum/radio_frequency/proc/remove_listener(obj/device)
|
||||
for (var/devices_filter in devices)
|
||||
var/list/devices_line = devices[devices_filter]
|
||||
devices_line-=device
|
||||
while (null in devices_line)
|
||||
devices_line -= null
|
||||
if (devices_line.len==0)
|
||||
devices -= devices_filter
|
||||
|
||||
/datum/signal
|
||||
var/obj/source
|
||||
|
||||
var/transmission_method = 0 //unused at the moment
|
||||
//0 = wire
|
||||
//1 = radio transmission
|
||||
//2 = subspace transmission
|
||||
|
||||
var/list/data = list()
|
||||
var/encryption
|
||||
|
||||
var/frequency = 0
|
||||
|
||||
/datum/signal/proc/copy_from(datum/signal/model)
|
||||
source = model.source
|
||||
transmission_method = model.transmission_method
|
||||
data = model.data
|
||||
encryption = model.encryption
|
||||
frequency = model.frequency
|
||||
|
||||
/datum/signal/proc/debug_print()
|
||||
if (source)
|
||||
. = "signal = {source = '[source]' ([source:x],[source:y],[source:z])\n"
|
||||
else
|
||||
. = "signal = {source = '[source]' ()\n"
|
||||
for (var/i in data)
|
||||
. += "data\[\"[i]\"\] = \"[data[i]]\"\n"
|
||||
if(islist(data[i]))
|
||||
var/list/L = data[i]
|
||||
for(var/t in L)
|
||||
. += "data\[\"[i]\"\] list has: [t]"
|
||||
@@ -24,6 +24,9 @@
|
||||
/// If the configuration is loaded
|
||||
var/loaded = FALSE
|
||||
|
||||
/// If a reload is in progress
|
||||
var/reload_in_progress = FALSE
|
||||
|
||||
/// A regex that matches words blocked IC
|
||||
var/static/regex/ic_filter_regex
|
||||
|
||||
@@ -64,13 +67,23 @@
|
||||
var/static/list/configuration_errors
|
||||
|
||||
/datum/controller/configuration/proc/admin_reload()
|
||||
if(IsAdminAdvancedProcCall())
|
||||
if(IsAdminAdvancedProcCall() || !PreConfigReload())
|
||||
return
|
||||
log_admin("[key_name_admin(usr)] has forcefully reloaded the configuration from disk.")
|
||||
message_admins("[key_name_admin(usr)] has forcefully reloaded the configuration from disk.")
|
||||
full_wipe()
|
||||
Load(world.params[OVERRIDE_CONFIG_DIRECTORY_PARAMETER])
|
||||
|
||||
/datum/controller/configuration/proc/PreConfigReload()
|
||||
if(reload_in_progress)
|
||||
to_chat(usr, span_warning("Another user is already reloading the config!"))
|
||||
return FALSE
|
||||
|
||||
reload_in_progress = TRUE
|
||||
world.TgsTriggerEvent("tg-PreConfigReload", wait_for_completion = TRUE)
|
||||
reload_in_progress = FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/controller/configuration/proc/Load(_directory)
|
||||
if(IsAdminAdvancedProcCall()) //If admin proccall is detected down the line it will horribly break everything.
|
||||
return
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
/datum/config_entry/number/walk_speed
|
||||
default = 0
|
||||
|
||||
/datum/config_entry/flag/force_random_names
|
||||
|
||||
///Mob specific modifiers. NOTE: These will affect different mob types in different ways
|
||||
/datum/config_entry/number/human_delay
|
||||
default = 0
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
/// server name (the name of the game window)
|
||||
/datum/config_entry/string/servername
|
||||
|
||||
/// Countdown between lobby and the round starting.
|
||||
/datum/config_entry/number/lobby_countdown
|
||||
default = 120
|
||||
integer = FALSE
|
||||
min_val = 0
|
||||
|
||||
/// Post round murder death kill countdown.
|
||||
/datum/config_entry/number/round_end_countdown
|
||||
default = 25
|
||||
integer = FALSE
|
||||
min_val = 0
|
||||
|
||||
/// generate numeric suffix based on server port
|
||||
/datum/config_entry/flag/server_suffix
|
||||
|
||||
@@ -222,9 +234,6 @@
|
||||
|
||||
// var/static/Tickcomp = 0 // FIXME: Unused
|
||||
|
||||
/// use socket_talk to communicate with other processes
|
||||
/datum/config_entry/flag/socket_talk
|
||||
|
||||
// var/static/list/resource_urls = null // FIXME: Unused
|
||||
|
||||
/// Ghosts can turn on Antagovision to see a HUD of who is the bad guys this round.
|
||||
@@ -787,6 +796,60 @@
|
||||
/datum/config_entry/flag/discord_ahelps_all
|
||||
default = FALSE
|
||||
|
||||
/datum/config_entry/number/mc_tick_rate/base_mc_tick_rate
|
||||
integer = FALSE
|
||||
default = 1
|
||||
|
||||
/datum/config_entry/number/mc_tick_rate/high_pop_mc_tick_rate
|
||||
integer = FALSE
|
||||
default = 1.1
|
||||
|
||||
/datum/config_entry/number/mc_tick_rate/high_pop_mc_mode_amount
|
||||
default = 65
|
||||
|
||||
/datum/config_entry/number/mc_tick_rate/disable_high_pop_mc_mode_amount
|
||||
default = 60
|
||||
|
||||
/datum/config_entry/number/mc_tick_rate
|
||||
abstract_type = /datum/config_entry/number/mc_tick_rate
|
||||
|
||||
/datum/config_entry/number/mc_tick_rate/ValidateAndSet(str_val)
|
||||
. = ..()
|
||||
if (.)
|
||||
Master.UpdateTickRate()
|
||||
|
||||
/datum/config_entry/flag/resume_after_initializations
|
||||
|
||||
/datum/config_entry/flag/resume_after_initializations/ValidateAndSet(str_val)
|
||||
. = ..()
|
||||
if(. && MC_RUNNING())
|
||||
world.sleep_offline = !config_entry_value
|
||||
|
||||
/datum/config_entry/number/rounds_until_hard_restart
|
||||
default = -1
|
||||
min_val = 0
|
||||
|
||||
/datum/config_entry/flag/auto_profile
|
||||
|
||||
/datum/config_entry/number/profiler_interval
|
||||
default = 300 SECONDS
|
||||
|
||||
/datum/config_entry/number/drift_dump_threshold
|
||||
default = 4 SECONDS
|
||||
|
||||
/datum/config_entry/number/drift_profile_delay
|
||||
default = 15 SECONDS
|
||||
|
||||
/datum/config_entry/flag/forbid_all_profiling
|
||||
|
||||
/datum/config_entry/flag/forbid_admin_profiling
|
||||
|
||||
/datum/config_entry/flag/toast_notification_on_init
|
||||
|
||||
/// If admins with +DEBUG can initialize byond-tracy midround.
|
||||
/datum/config_entry/flag/allow_tracy_start
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
/// If admins with +DEBUG can queue byond-tracy to run the next round.
|
||||
/datum/config_entry/flag/allow_tracy_queue
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
@@ -161,8 +161,8 @@
|
||||
|
||||
/datum/emergency_shuttle_controller/proc/get_shuttle_prep_time()
|
||||
// During mutiny rounds, the shuttle takes twice as long.
|
||||
if(ticker && ticker.mode)
|
||||
return SHUTTLE_PREPTIME * ticker.mode.shuttle_delay
|
||||
if(SSticker && SSticker.mode)
|
||||
return SHUTTLE_PREPTIME * SSticker.mode.shuttle_delay
|
||||
return SHUTTLE_PREPTIME
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,9 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
|
||||
var/running = TRUE
|
||||
|
||||
/datum/controller/failsafe/New()
|
||||
// Ensure usr is null, to prevent any potential weirdness resulting from the failsafe having a usr if it's manually restarted.
|
||||
usr = null
|
||||
|
||||
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
|
||||
if(Failsafe != src)
|
||||
if(istype(Failsafe))
|
||||
@@ -149,7 +152,7 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
|
||||
/proc/recover_all_SS_and_recreate_master()
|
||||
del(Master)
|
||||
var/list/subsytem_types = subtypesof(/datum/controller/subsystem)
|
||||
sortTim(subsytem_types, GLOBAL_PROC_REF(cmp_subsystem_init))
|
||||
sortTim(subsytem_types, GLOBAL_PROC_REF(cmp_subsystem_init_stage))
|
||||
for(var/I in subsytem_types)
|
||||
new I
|
||||
. = Recreate_MC()
|
||||
|
||||
+25
-21
@@ -1,9 +1,10 @@
|
||||
// See initialization order in /code/game/world.dm
|
||||
GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
|
||||
/datum/controller/global_vars
|
||||
name = "Global Variables"
|
||||
|
||||
var/list/gvars_datum_protected_varlist
|
||||
var/static/list/gvars_datum_protected_varlist
|
||||
var/list/gvars_datum_in_built_vars
|
||||
var/list/gvars_datum_init_order
|
||||
|
||||
@@ -13,30 +14,24 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
GLOB = src
|
||||
|
||||
var/datum/controller/exclude_these = new
|
||||
gvars_datum_in_built_vars = exclude_these.vars + list("gvars_datum_protected_varlist", "gvars_datum_in_built_vars", "gvars_datum_init_order")
|
||||
// I know this is dumb but the nested vars list hangs a ref to the datum. This fixes that
|
||||
// I have an issue report open, lummox has not responded. It might be a FeaTuRE
|
||||
// Sooo we gotta be dumb
|
||||
var/list/controller_vars = exclude_these.vars.Copy()
|
||||
controller_vars["vars"] = null
|
||||
gvars_datum_in_built_vars = controller_vars + list(NAMEOF(src, gvars_datum_protected_varlist), NAMEOF(src, gvars_datum_in_built_vars), NAMEOF(src, gvars_datum_init_order))
|
||||
|
||||
log_world("[vars.len - gvars_datum_in_built_vars.len] global variables")
|
||||
QDEL_IN(exclude_these, 0) //signal logging isn't ready
|
||||
|
||||
Initialize(exclude_these)
|
||||
Initialize()
|
||||
|
||||
/datum/controller/global_vars/Destroy(force)
|
||||
stack_trace("There was an attempt to qdel the global vars holder!")
|
||||
if(!force)
|
||||
return QDEL_HINT_LETMELIVE
|
||||
|
||||
QDEL_NULL(statclick)
|
||||
gvars_datum_protected_varlist.Cut()
|
||||
gvars_datum_in_built_vars.Cut()
|
||||
|
||||
GLOB = null
|
||||
|
||||
return ..()
|
||||
// This is done to prevent an exploit where admins can get around protected vars
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
return QDEL_HINT_IWILLGC
|
||||
|
||||
/datum/controller/global_vars/stat_entry(msg)
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
msg = "GLOB: [statclick.update("Edit")]"
|
||||
msg = "Edit"
|
||||
return msg
|
||||
|
||||
/datum/controller/global_vars/vv_edit_var(var_name, var_value)
|
||||
@@ -44,6 +39,14 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/*
|
||||
/datum/controller/global_vars/vv_get_var(var_name)
|
||||
switch(var_name)
|
||||
if (NAMEOF(src, vars))
|
||||
return debug_variable(var_name, list(), 0, src)
|
||||
return debug_variable(var_name, vars[var_name], 0, src, display_flags = VV_ALWAYS_CONTRACT_LIST)
|
||||
*/
|
||||
|
||||
/datum/controller/global_vars/Initialize()
|
||||
gvars_datum_init_order = list()
|
||||
gvars_datum_protected_varlist = list(NAMEOF(src, gvars_datum_protected_varlist) = TRUE)
|
||||
@@ -55,8 +58,8 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
var/list/expected_global_procs = vars - gvars_datum_in_built_vars
|
||||
for(var/I in global_procs)
|
||||
expected_global_procs -= replacetext("[I]", "InitGlobal", "")
|
||||
var/english_missing = expected_global_procs.Join(", ")
|
||||
log_world("Missing procs: [english_missing]")
|
||||
log_world("Missing procs: [expected_global_procs.Join(", ")]")
|
||||
|
||||
for(var/I in global_procs)
|
||||
var/start_tick = world.time
|
||||
call(src, I)()
|
||||
@@ -64,4 +67,5 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
if(end_tick - start_tick)
|
||||
warning("Global [replacetext("[I]", "InitGlobal", "")] slept during initialization!")
|
||||
|
||||
// Someone make it so this call isn't necessary
|
||||
populate_legacy_globals()
|
||||
|
||||
+507
-202
File diff suppressed because it is too large
Load Diff
@@ -42,7 +42,7 @@ var/global/last_tick_duration = 0
|
||||
transfer_controller = new
|
||||
admin_notice(span_danger("Initializations complete."), R_DEBUG)
|
||||
|
||||
// #if UNIT_TEST
|
||||
// #if UNIT_TESTS
|
||||
// # define CHECK_SLEEP_MASTER // For unit tests we don't care about a smooth lobby screen experience. We care about speed.
|
||||
// #else
|
||||
// # define CHECK_SLEEP_MASTER if(++initialized_objects > 500) { initialized_objects=0;sleep(world.tick_lag); }
|
||||
|
||||
@@ -13,27 +13,48 @@
|
||||
/// Name of the subsystem - you must change this
|
||||
name = "fire coderbus"
|
||||
|
||||
/// Order of initialization. Higher numbers are initialized first, lower numbers later. Use or create defines such as [INIT_ORDER_DEFAULT] so we can see the order in one file.
|
||||
var/init_order = INIT_ORDER_DEFAULT
|
||||
/// Determines which subsystems this subsystem is dependant on to initialize. Will initialize after all specified subsystems.
|
||||
/// If init_stage is earlier than a dependent subsystem, will throw an error and push the init stage forward to that subsystem.
|
||||
/// Usage: Put the typepaths of the subsystems that need to init before this one in this list.
|
||||
var/list/dependencies = list()
|
||||
|
||||
/// The inverse of the dependencies. Can be set manually, but will also get evaluated at runtime. Turns into a list of instances at runtime.
|
||||
/// Usage: Put the typepaths of the subsystems that need to init after this one in this list.
|
||||
var/list/dependents
|
||||
|
||||
/// ID of the subsystem. Set automatically when the dependency graph is evaluated. Used primarily in determining order.
|
||||
var/ordering_id = 0
|
||||
|
||||
/// Do not modify. Automatically set when the dependency graph is evaluated. Similar to ordering_id, but evaluated after init_stage.
|
||||
var/init_order = 0
|
||||
|
||||
/// Time to wait (in deciseconds) between each call to fire(). Must be a positive integer.
|
||||
var/wait = 20
|
||||
|
||||
/// Priority Weight: When mutiple subsystems need to run in the same tick, higher priority subsystems will be given a higher share of the tick before MC_TICK_CHECK triggers a sleep, higher priority subsystems also run before lower priority subsystems.
|
||||
/// Priority Weight: When multiple subsystems need to run in the same tick, higher priority subsystems will be given a higher share of the tick before MC_TICK_CHECK triggers a sleep, higher priority subsystems also run before lower priority subsystems
|
||||
var/priority = FIRE_PRIORITY_DEFAULT
|
||||
|
||||
/// [Subsystem Flags][SS_NO_INIT] to control binary behavior. Flags must be set at compile time or before preinit finishes to take full effect. (You can also restart the mc to force them to process again)
|
||||
var/flags = NONE
|
||||
|
||||
/// This var is set to TRUE after the subsystem has been initialized.
|
||||
var/subsystem_initialized = FALSE
|
||||
/// Which stage does this subsystem init at. Earlier stages can fire while later stages init.
|
||||
var/init_stage = INITSTAGE_MAIN
|
||||
|
||||
/// This var is set to `INITIALIZATION_INNEW_REGULAR` after the subsystem has been initialized.
|
||||
var/initialized = FALSE
|
||||
|
||||
/// Set to 0 to prevent fire() calls, mostly for admin use or subsystems that may be resumed later
|
||||
/// use the [SS_NO_FIRE] flag instead for systems that never fire to keep it from even being added to list that is checked every tick
|
||||
var/can_fire = TRUE
|
||||
|
||||
///Bitmap of what game states can this subsystem fire at. See [RUNLEVELS_DEFAULT] for more details.
|
||||
var/runlevels = RUNLEVELS_DEFAULT
|
||||
var/runlevels = RUNLEVELS_DEFAULT //points of the game at which the SS can fire
|
||||
|
||||
/**
|
||||
* boolean set by admins. if TRUE then this subsystem will stop the world profiler after ignite() returns and start it again when called.
|
||||
* used so that you can audit a specific subsystem or group of subsystems' synchronous call chain.
|
||||
*/
|
||||
var/profiler_focused = FALSE
|
||||
|
||||
/*
|
||||
* The following variables are managed by the MC and should not be modified directly.
|
||||
@@ -54,6 +75,9 @@
|
||||
/// Running average of the amount of tick usage (in percents of a game tick) the subsystem has spent past its allocated time without pausing
|
||||
var/tick_overrun = 0
|
||||
|
||||
/// Flat list of usage and time, every odd index is a log time, every even index is a usage
|
||||
var/list/rolling_usage = list()
|
||||
|
||||
/// How much of a tick (in percents of a tick) were we allocated last fire.
|
||||
var/tick_allocation_last = 0
|
||||
|
||||
@@ -78,6 +102,9 @@
|
||||
/// Tracks the amount of completed runs for the subsystem
|
||||
var/times_fired = 0
|
||||
|
||||
/// How many fires have we been requested to postpone
|
||||
var/postponed_fires = 0
|
||||
|
||||
/// Time the subsystem entered the queue, (for timing and priority reasons)
|
||||
var/queued_time = 0
|
||||
|
||||
@@ -92,9 +119,13 @@
|
||||
/// Previous subsystem in the queue of subsystems to run this tick
|
||||
var/datum/controller/subsystem/queue_prev
|
||||
|
||||
/// String to store an applicable error message for a subsystem crashing, used to help debug crashes in contexts such as Continuous Integration/Unit Tests
|
||||
var/initialization_failure_message = null
|
||||
|
||||
//Do not blindly add vars here to the bottom, put it where it goes above
|
||||
//If your var only has two values, put it in as a flag.
|
||||
|
||||
|
||||
//Do not override
|
||||
///datum/controller/subsystem/New()
|
||||
|
||||
@@ -107,7 +138,7 @@
|
||||
///This is used so the mc knows when the subsystem sleeps. do not override.
|
||||
/datum/controller/subsystem/proc/ignite(resumed = FALSE)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
set waitfor = 0
|
||||
set waitfor = FALSE
|
||||
. = SS_IDLE
|
||||
|
||||
tick_allocation_last = Master.current_ticklimit-(TICK_USAGE)
|
||||
@@ -131,7 +162,7 @@
|
||||
///Sleeping in here prevents future fires until returned.
|
||||
/datum/controller/subsystem/proc/fire(resumed = FALSE)
|
||||
flags |= SS_NO_FIRE
|
||||
throw EXCEPTION("Subsystem [src]([type]) does not fire() but did not set the SS_NO_FIRE flag. Please add the SS_NO_FIRE flag to any subsystem that doesn't fire so it doesn't get added to the processing list and waste cpu.")
|
||||
CRASH("Subsystem [src]([type]) does not fire() but did not set the SS_NO_FIRE flag. Please add the SS_NO_FIRE flag to any subsystem that doesn't fire so it doesn't get added to the processing list and waste cpu.")
|
||||
|
||||
/datum/controller/subsystem/Destroy()
|
||||
dequeue()
|
||||
@@ -141,6 +172,31 @@
|
||||
Master.subsystems -= src
|
||||
return ..()
|
||||
|
||||
|
||||
/** Update next_fire for the next run.
|
||||
* reset_time (bool) - Ignore things that would normally alter the next fire, like tick_overrun, and last_fire. (also resets postpone)
|
||||
*/
|
||||
/datum/controller/subsystem/proc/update_nextfire(reset_time = FALSE)
|
||||
var/queue_node_flags = flags
|
||||
|
||||
if (reset_time)
|
||||
postponed_fires = 0
|
||||
if (queue_node_flags & SS_TICKER)
|
||||
next_fire = world.time + (world.tick_lag * wait)
|
||||
else
|
||||
next_fire = world.time + wait
|
||||
return
|
||||
|
||||
if (queue_node_flags & SS_TICKER)
|
||||
next_fire = world.time + (world.tick_lag * wait)
|
||||
else if (queue_node_flags & SS_POST_FIRE_TIMING)
|
||||
next_fire = world.time + wait + (world.tick_lag * (tick_overrun/100))
|
||||
else if (queue_node_flags & SS_KEEP_TIMING)
|
||||
next_fire += wait
|
||||
else
|
||||
next_fire = queued_time + wait + (world.tick_lag * (tick_overrun/100))
|
||||
|
||||
|
||||
///Queue it to run.
|
||||
/// (we loop thru a linked list until we get to the end or find the right point)
|
||||
/// (this lets us sort our run order correctly without having to re-sort the entire already sorted list)
|
||||
@@ -155,8 +211,8 @@
|
||||
queue_node_priority = queue_node.queued_priority
|
||||
queue_node_flags = queue_node.flags
|
||||
|
||||
if (queue_node_flags & SS_TICKER)
|
||||
if (!(SS_flags & SS_TICKER))
|
||||
if (queue_node_flags & (SS_TICKER|SS_BACKGROUND) == SS_TICKER)
|
||||
if ((SS_flags & (SS_TICKER|SS_BACKGROUND)) != SS_TICKER)
|
||||
continue
|
||||
if (queue_node_priority < SS_priority)
|
||||
break
|
||||
@@ -207,9 +263,9 @@
|
||||
queue_next.queue_prev = queue_prev
|
||||
if (queue_prev)
|
||||
queue_prev.queue_next = queue_next
|
||||
if (src == Master.queue_tail)
|
||||
if (Master && (src == Master.queue_tail))
|
||||
Master.queue_tail = queue_prev
|
||||
if (src == Master.queue_head)
|
||||
if (Master && (src == Master.queue_head))
|
||||
Master.queue_head = queue_next
|
||||
queued_time = 0
|
||||
if (state == SS_QUEUED)
|
||||
@@ -228,14 +284,13 @@
|
||||
/datum/controller/subsystem/proc/OnConfigLoad()
|
||||
|
||||
/**
|
||||
* Used to initialize the subsystem. This is expected to be overriden by subtypes.
|
||||
* Used to initialize the subsystem. This is expected to be overridden by subtypes.
|
||||
*/
|
||||
/datum/controller/subsystem/Initialize()
|
||||
return SS_INIT_NONE
|
||||
|
||||
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
|
||||
/datum/controller/subsystem/stat_entry(msg)
|
||||
if(can_fire && !(SS_NO_FIRE & flags))
|
||||
if(can_fire && !(SS_NO_FIRE & flags) && init_stage <= Master.init_stage_completed)
|
||||
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
|
||||
else
|
||||
msg = "OFFLINE\t[msg]"
|
||||
@@ -254,45 +309,30 @@
|
||||
if (SS_IDLE)
|
||||
. = " "
|
||||
|
||||
//could be used to postpone a costly subsystem for (default one) var/cycles, cycles
|
||||
//for instance, during cpu intensive operations like explosions
|
||||
/// Causes the next "cycle" fires to be missed. Effect is accumulative but can reset by calling update_nextfire(reset_time = TRUE)
|
||||
/datum/controller/subsystem/proc/postpone(cycles = 1)
|
||||
if(next_fire - world.time < wait)
|
||||
next_fire += (wait*cycles)
|
||||
if (can_fire && cycles >= 1)
|
||||
postponed_fires += cycles
|
||||
|
||||
/// Prunes out of date entries in our rolling usage list
|
||||
/datum/controller/subsystem/proc/prune_rolling_usage()
|
||||
var/list/rolling_usage = src.rolling_usage
|
||||
var/cut_to = 0
|
||||
while(cut_to + 2 <= length(rolling_usage) && rolling_usage[cut_to + 1] < DS2TICKS(world.time - Master.rolling_usage_length))
|
||||
cut_to += 2
|
||||
if(cut_to)
|
||||
rolling_usage.Cut(1, cut_to + 1)
|
||||
|
||||
//usually called via datum/controller/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash)
|
||||
//should attempt to salvage what it can from the old instance of subsystem
|
||||
/datum/controller/subsystem/Recover()
|
||||
|
||||
// Suspends this subsystem from being queued for running. If already in the queue, sleeps until idle. Returns FALSE if the subsystem was already suspended.
|
||||
/datum/controller/subsystem/proc/suspend()
|
||||
. = (can_fire > 0) // Return true if we were previously runnable, false if previously suspended.
|
||||
can_fire = FALSE
|
||||
// Safely sleep in a loop until the subsystem is idle, (or its been un-suspended somehow)
|
||||
while(can_fire <= 0 && state != SS_IDLE)
|
||||
stoplag() // Safely sleep in a loop until
|
||||
|
||||
// Wakes a suspended subsystem.
|
||||
/datum/controller/subsystem/proc/wake()
|
||||
can_fire = TRUE
|
||||
|
||||
// This subsystem has destabilized the game and is being put on warning. At this point there may be
|
||||
// an opportunity to clean up the subsystem or check it for errors in ways that would otherwise be too slow.
|
||||
// You should log the errors/cleanup results, so you can fix the problem rather than using this as a crutch.
|
||||
/datum/controller/subsystem/proc/fail()
|
||||
var/msg = "[name] subsystem being blamed for MC failure"
|
||||
log_world(msg)
|
||||
log_game(msg)
|
||||
|
||||
// DO NOT ATTEMPT RECOVERY. Only log debugging info. You should leave the subsystem as it is.
|
||||
// Attempting recovery here could make things worse, create hard recursions with the MC disabling it every run, etc.
|
||||
/datum/controller/subsystem/proc/critfail()
|
||||
var/msg = "[name] subsystem received final blame for MC failure"
|
||||
log_world(msg)
|
||||
log_game(msg)
|
||||
|
||||
/datum/controller/subsystem/vv_edit_var(var_name, var_value)
|
||||
switch (var_name)
|
||||
if (NAMEOF(src, can_fire))
|
||||
//this is so the subsystem doesn't rapid fire to make up missed ticks causing more lag
|
||||
if (var_value)
|
||||
update_nextfire(reset_time = TRUE)
|
||||
if (NAMEOF(src, queued_priority)) //editing this breaks things.
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
@@ -3,7 +3,7 @@ GENERAL_PROTECT_DATUM(/datum/controller/subsystem/admin_verbs)
|
||||
SUBSYSTEM_DEF(admin_verbs)
|
||||
name = "Admin Verbs"
|
||||
flags = SS_NO_FIRE
|
||||
//init_stage = INITSTAGE_EARLY
|
||||
init_stage = INITSTAGE_EARLY
|
||||
/// A list of all admin verbs indexed by their type.
|
||||
var/list/datum/admin_verb/admin_verbs_by_type = list()
|
||||
/// A list of all admin verbs indexed by their visibility flag.
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
SUBSYSTEM_DEF(ai)
|
||||
name = "AI"
|
||||
init_order = INIT_ORDER_AI
|
||||
priority = FIRE_PRIORITY_AI
|
||||
wait = 2 SECONDS
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/air,
|
||||
/datum/controller/subsystem/mobs
|
||||
)
|
||||
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
SUBSYSTEM_DEF(aifast)
|
||||
name = "AI (Fast)"
|
||||
init_order = INIT_ORDER_AI_FAST
|
||||
priority = FIRE_PRIORITY_AI
|
||||
wait = 0.25 SECONDS // Every quarter second
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/ai
|
||||
)
|
||||
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
|
||||
|
||||
@@ -65,7 +65,9 @@ Class Procs:
|
||||
|
||||
SUBSYSTEM_DEF(air)
|
||||
name = "Air"
|
||||
init_order = INIT_ORDER_AIR
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/atoms
|
||||
)
|
||||
priority = FIRE_PRIORITY_AIR
|
||||
wait = 2 SECONDS // seconds (We probably can speed this up actually)
|
||||
flags = SS_BACKGROUND // TODO - Should this really be background? It might be important.
|
||||
|
||||
@@ -6,7 +6,7 @@ SUBSYSTEM_DEF(atc)
|
||||
priority = FIRE_PRIORITY_ATC
|
||||
runlevels = RUNLEVEL_GAME
|
||||
wait = 2 SECONDS
|
||||
init_order = INIT_ORDER_ATC
|
||||
init_stage = INITSTAGE_LAST
|
||||
flags = SS_BACKGROUND
|
||||
|
||||
VAR_PRIVATE/next_tick = 0
|
||||
|
||||
@@ -16,6 +16,11 @@ SUBSYSTEM_DEF(airflow)
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
priority = FIRE_PRIORITY_AIRFLOW
|
||||
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/atoms,
|
||||
/datum/controller/subsystem/air
|
||||
)
|
||||
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ SUBSYSTEM_DEF(alarm)
|
||||
name = "Alarm"
|
||||
wait = 2 SECONDS
|
||||
priority = FIRE_PRIORITY_ALARM
|
||||
init_order = INIT_ORDER_ALARM
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/mapping
|
||||
)
|
||||
var/list/datum/alarm/all_handlers
|
||||
var/tmp/list/currentrun = null
|
||||
var/static/list/active_alarm_cache = list()
|
||||
|
||||
@@ -13,10 +13,11 @@ SUBSYSTEM_DEF(asset_loading)
|
||||
while(length(generate_queue))
|
||||
var/datum/asset/to_load = generate_queue[generate_queue.len]
|
||||
|
||||
to_load.queued_generation()
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
to_load.queued_generation()
|
||||
|
||||
last_queue_len = length(generate_queue)
|
||||
generate_queue.len--
|
||||
// We just emptied the queue
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
SUBSYSTEM_DEF(assets)
|
||||
name = "Assets"
|
||||
init_order = INIT_ORDER_ASSETS
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/holomaps,
|
||||
/datum/controller/subsystem/robot_sprites
|
||||
///datum/controller/subsystem/persistent_paintings,
|
||||
///datum/controller/subsystem/greyscale_previews,
|
||||
)
|
||||
flags = SS_NO_FIRE
|
||||
var/list/datum/asset_cache_item/cache = list()
|
||||
var/list/preload = list()
|
||||
@@ -32,7 +37,7 @@ SUBSYSTEM_DEF(assets)
|
||||
|
||||
transport.Initialize(cache)
|
||||
|
||||
subsystem_initialized = TRUE
|
||||
initialized = TRUE
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
/datum/controller/subsystem/assets/Recover()
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
SUBSYSTEM_DEF(atoms)
|
||||
name = "Atoms"
|
||||
init_order = INIT_ORDER_ATOMS
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/garbage,
|
||||
/datum/controller/subsystem/mapping,
|
||||
/datum/controller/subsystem/planets,
|
||||
/datum/controller/subsystem/transcore,
|
||||
/datum/controller/subsystem/chemistry,
|
||||
/datum/controller/subsystem/sounds,
|
||||
/datum/controller/subsystem/job
|
||||
)
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
/// A stack of list(source, desired initialized state)
|
||||
@@ -8,7 +16,7 @@ SUBSYSTEM_DEF(atoms)
|
||||
var/list/initialized_state = list()
|
||||
var/base_initialized
|
||||
|
||||
var/initialized = INITIALIZATION_INSSATOMS
|
||||
var/atom_initialized = INITIALIZATION_INSSATOMS
|
||||
var/list/late_loaders = list()
|
||||
|
||||
var/list/BadInitializeCalls = list()
|
||||
@@ -25,19 +33,19 @@ SUBSYSTEM_DEF(atoms)
|
||||
var/list/mapload_init_times = list()
|
||||
#endif
|
||||
|
||||
initialized = INITIALIZATION_INSSATOMS
|
||||
atom_initialized = INITIALIZATION_INSSATOMS
|
||||
|
||||
/datum/controller/subsystem/atoms/Initialize()
|
||||
init_start_time = world.time
|
||||
|
||||
initialized = INITIALIZATION_INNEW_MAPLOAD
|
||||
atom_initialized = INITIALIZATION_INNEW_MAPLOAD
|
||||
InitializeAtoms()
|
||||
initialized = INITIALIZATION_INNEW_REGULAR
|
||||
atom_initialized = INITIALIZATION_INNEW_REGULAR
|
||||
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms, list/atoms_to_return)
|
||||
if(initialized == INITIALIZATION_INSSATOMS)
|
||||
if(atom_initialized == INITIALIZATION_INSSATOMS)
|
||||
return
|
||||
|
||||
// Generate a unique mapload source for this run of InitializeAtoms
|
||||
@@ -142,9 +150,9 @@ SUBSYSTEM_DEF(atoms)
|
||||
/// Accepts a state and a source, the most recent state is used, sources exist to prevent overriding old values accidentally
|
||||
/datum/controller/subsystem/atoms/proc/set_tracked_initalized(state, source)
|
||||
if(!length(initialized_state))
|
||||
base_initialized = initialized
|
||||
base_initialized = atom_initialized
|
||||
initialized_state += list(list(source, state))
|
||||
initialized = state
|
||||
atom_initialized = state
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/clear_tracked_initalize(source)
|
||||
if(!length(initialized_state))
|
||||
@@ -155,18 +163,18 @@ SUBSYSTEM_DEF(atoms)
|
||||
break
|
||||
|
||||
if(!length(initialized_state))
|
||||
initialized = base_initialized
|
||||
atom_initialized = base_initialized
|
||||
base_initialized = INITIALIZATION_INNEW_REGULAR
|
||||
return
|
||||
initialized = initialized_state[length(initialized_state)][2]
|
||||
atom_initialized = initialized_state[length(initialized_state)][2]
|
||||
|
||||
/// Returns TRUE if anything is currently being initialized
|
||||
/datum/controller/subsystem/atoms/proc/initializing_something()
|
||||
return length(initialized_state) > 1
|
||||
|
||||
/datum/controller/subsystem/atoms/Recover()
|
||||
initialized = SSatoms.initialized
|
||||
if(initialized == INITIALIZATION_INNEW_MAPLOAD)
|
||||
atom_initialized = SSatoms.atom_initialized
|
||||
if(atom_initialized == INITIALIZATION_INNEW_MAPLOAD)
|
||||
InitializeAtoms()
|
||||
initialized_state = SSatoms.initialized_state
|
||||
BadInitializeCalls = SSatoms.BadInitializeCalls
|
||||
@@ -187,7 +195,7 @@ SUBSYSTEM_DEF(atoms)
|
||||
|
||||
/// Prepares an atom to be deleted once the atoms SS is initialized.
|
||||
/datum/controller/subsystem/atoms/proc/prepare_deletion(atom/target)
|
||||
if (initialized == INITIALIZATION_INNEW_REGULAR)
|
||||
if (atom_initialized == INITIALIZATION_INNEW_REGULAR)
|
||||
// Atoms SS has already completed, just kill it now.
|
||||
qdel(target)
|
||||
else
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
SUBSYSTEM_DEF(character_setup)
|
||||
name = "Character Setup"
|
||||
init_order = INIT_ORDER_DEFAULT
|
||||
priority = FIRE_PRIORITY_CHARSETUP
|
||||
flags = SS_BACKGROUND | SS_NO_INIT
|
||||
wait = 1 SECOND
|
||||
|
||||
@@ -8,7 +8,7 @@ SUBSYSTEM_DEF(chat)
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
wait = 1
|
||||
priority = FIRE_PRIORITY_CHAT
|
||||
init_order = INIT_ORDER_CHAT
|
||||
init_stage = INITSTAGE_LAST
|
||||
|
||||
/// Assosciates a ckey with a list of messages to send to them.
|
||||
var/list/list/datum/chat_payload/client_to_payloads = list()
|
||||
|
||||
@@ -2,7 +2,9 @@ SUBSYSTEM_DEF(chemistry)
|
||||
name = "Chemistry"
|
||||
wait = 20
|
||||
flags = SS_NO_FIRE
|
||||
init_order = INIT_ORDER_CHEMISTRY
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/garbage
|
||||
)
|
||||
|
||||
var/list/chemical_reactions = list()
|
||||
var/list/chemical_reactions_by_product = list()
|
||||
|
||||
@@ -4,8 +4,12 @@
|
||||
//
|
||||
SUBSYSTEM_DEF(circuit)
|
||||
name = "Circuit"
|
||||
init_order = INIT_ORDER_CIRCUIT
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/atoms
|
||||
)
|
||||
|
||||
var/list/all_components = list() // Associative list of [component_name]:[component_path] pairs
|
||||
var/list/cached_components = list() // Associative list of [component_path]:[component] pairs
|
||||
var/list/all_assemblies = list() // Associative list of [assembly_name]:[assembly_path] pairs
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
HOW IT WORKS
|
||||
|
||||
The SSradio is a global object maintaining all radio transmissions, think about it as about "ether".
|
||||
Note that walkie-talkie, intercoms and headsets handle transmission using nonstandard way.
|
||||
procs:
|
||||
|
||||
add_object(obj/device as obj, var/new_frequency as num, var/radio_filter as text|null = null)
|
||||
Adds listening object.
|
||||
parameters:
|
||||
device - device receiving signals, must have proc receive_signal (see description below).
|
||||
one device may listen several frequencies, but not same frequency twice.
|
||||
new_frequency - see possibly frequencies below;
|
||||
radio_filter - thing for optimization. Optional, but recommended.
|
||||
All filters should be consolidated in this file, see defines later.
|
||||
Device without listening filter will receive all signals (on specified frequency).
|
||||
Device with filter will receive any signals sent without filter.
|
||||
Device with filter will not receive any signals sent with different filter.
|
||||
returns:
|
||||
Reference to frequency object.
|
||||
|
||||
remove_object (obj/device, old_frequency)
|
||||
Obliviously, after calling this proc, device will not receive any signals on old_frequency.
|
||||
Other frequencies will left unaffected.
|
||||
|
||||
return_frequency(var/frequency as num)
|
||||
returns:
|
||||
Reference to frequency object. Use it if you need to send and do not need to listen.
|
||||
|
||||
radio_frequency is a global object maintaining list of devices that listening specific frequency.
|
||||
procs:
|
||||
|
||||
post_signal(obj/source as obj|null, datum/signal/signal, var/radio_filter as text|null = null, var/range as num|null = null)
|
||||
Sends signal to all devices that wants such signal.
|
||||
parameters:
|
||||
source - object, emitted signal. Usually, devices will not receive their own signals.
|
||||
signal - see description below.
|
||||
radio_filter - described above.
|
||||
range - radius of regular byond's square circle on that z-level. null means everywhere, on all z-levels.
|
||||
|
||||
obj/proc/receive_signal(datum/signal/signal, var/receive_method as num, var/receive_param)
|
||||
Handler from received signals. By default does nothing. Define your own for your object.
|
||||
Avoid of sending signals directly from this proc, use spawn(-1). DO NOT use sleep() here or call procs that sleep please. If you must, use spawn()
|
||||
parameters:
|
||||
signal - see description below. Extract all needed data from the signal before doing sleep(), spawn() or return!
|
||||
receive_method - may be TRANSMISSION_WIRE or TRANSMISSION_RADIO.
|
||||
TRANSMISSION_WIRE is currently unused.
|
||||
receive_param - for TRANSMISSION_RADIO here comes frequency.
|
||||
|
||||
datum/signal
|
||||
vars:
|
||||
source
|
||||
an object that emitted signal. Used for debug and bearing.
|
||||
data
|
||||
list with transmitting data. Usual use pattern:
|
||||
data["msg"] = "hello world"
|
||||
encryption
|
||||
Some number symbolizing "encryption key".
|
||||
Note that game actually do not use any cryptography here.
|
||||
If receiving object don't know right key, it must ignore encrypted signal in its receive_signal.
|
||||
|
||||
*/
|
||||
|
||||
SUBSYSTEM_DEF(radio)
|
||||
name = "Radio"
|
||||
flags = SS_NO_FIRE
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/machines
|
||||
)
|
||||
var/list/datum/radio_frequency/frequencies = list()
|
||||
|
||||
/datum/controller/subsystem/radio/Initialize()
|
||||
GLOB.autospeaker = new (null, FALSE, null, null, TRUE) //Set up Global Announcer
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
/datum/controller/subsystem/radio/proc/add_object(obj/device as obj, var/new_frequency as num, var/radio_filter = null as text|null)
|
||||
var/f_text = num2text(new_frequency)
|
||||
var/datum/radio_frequency/frequency = frequencies[f_text]
|
||||
|
||||
if(!frequency)
|
||||
frequency = new
|
||||
frequency.frequency = new_frequency
|
||||
frequencies[f_text] = frequency
|
||||
|
||||
frequency.add_listener(device, radio_filter)
|
||||
return frequency
|
||||
|
||||
/datum/controller/subsystem/radio/proc/remove_object(obj/device, old_frequency)
|
||||
var/f_text = num2text(old_frequency)
|
||||
var/datum/radio_frequency/frequency = frequencies[f_text]
|
||||
|
||||
if(frequency)
|
||||
frequency.remove_listener(device)
|
||||
|
||||
if(frequency.devices.len == 0)
|
||||
qdel(frequency)
|
||||
frequencies -= f_text
|
||||
|
||||
return 1
|
||||
|
||||
/datum/controller/subsystem/radio/proc/return_frequency(var/new_frequency as num)
|
||||
var/f_text = num2text(new_frequency)
|
||||
var/datum/radio_frequency/frequency = frequencies[f_text]
|
||||
|
||||
if(!frequency)
|
||||
frequency = new
|
||||
frequency.frequency = new_frequency
|
||||
frequencies[f_text] = frequency
|
||||
|
||||
return frequency
|
||||
|
||||
//Frequency channels
|
||||
|
||||
/datum/radio_frequency
|
||||
var/frequency as num
|
||||
var/list/list/obj/devices = list()
|
||||
|
||||
/datum/radio_frequency/proc/post_signal(obj/source as obj|null, datum/signal/signal, var/radio_filter = null as text|null, var/range = null as num|null)
|
||||
var/turf/start_point
|
||||
if(range)
|
||||
start_point = get_turf(source)
|
||||
if(!start_point)
|
||||
qdel(signal)
|
||||
return 0
|
||||
if (radio_filter)
|
||||
send_to_filter(source, signal, radio_filter, start_point, range)
|
||||
send_to_filter(source, signal, RADIO_DEFAULT, start_point, range)
|
||||
else
|
||||
//Broadcast the signal to everyone!
|
||||
for (var/next_filter in devices)
|
||||
send_to_filter(source, signal, next_filter, start_point, range)
|
||||
|
||||
//Sends a signal to all machines belonging to a given filter. Should be called by post_signal()
|
||||
/datum/radio_frequency/proc/send_to_filter(obj/source, datum/signal/signal, var/radio_filter, var/turf/start_point = null, var/range = null)
|
||||
if (range && !start_point)
|
||||
return
|
||||
|
||||
for(var/obj/device in devices[radio_filter])
|
||||
if(device == source)
|
||||
continue
|
||||
if(range)
|
||||
var/turf/end_point = get_turf(device)
|
||||
if(!end_point)
|
||||
continue
|
||||
if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range)
|
||||
continue
|
||||
|
||||
device.receive_signal(signal, TRANSMISSION_RADIO, frequency)
|
||||
|
||||
/datum/radio_frequency/proc/add_listener(obj/device as obj, var/radio_filter as text|null)
|
||||
if (!radio_filter)
|
||||
radio_filter = RADIO_DEFAULT
|
||||
//log_admin("add_listener(device=[device],radio_filter=[radio_filter]) frequency=[frequency]")
|
||||
var/list/obj/devices_line = devices[radio_filter]
|
||||
if (!devices_line)
|
||||
devices_line = new
|
||||
devices[radio_filter] = devices_line
|
||||
devices_line+=device
|
||||
// var/list/obj/devices_line___ = devices[filter_str]
|
||||
// var/l = devices_line___.len
|
||||
//log_admin("DEBUG: devices_line.len=[devices_line.len]")
|
||||
//log_admin("DEBUG: devices(filter_str).len=[l]")
|
||||
|
||||
/datum/radio_frequency/proc/remove_listener(obj/device)
|
||||
for (var/devices_filter in devices)
|
||||
var/list/devices_line = devices[devices_filter]
|
||||
devices_line-=device
|
||||
while (null in devices_line)
|
||||
devices_line -= null
|
||||
if (devices_line.len==0)
|
||||
devices -= devices_filter
|
||||
|
||||
/datum/signal
|
||||
var/obj/source
|
||||
|
||||
var/transmission_method = 0 //unused at the moment
|
||||
//0 = wire
|
||||
//1 = radio transmission
|
||||
//2 = subspace transmission
|
||||
|
||||
var/list/data = list()
|
||||
var/encryption
|
||||
|
||||
var/frequency = 0
|
||||
|
||||
/datum/signal/proc/copy_from(datum/signal/model)
|
||||
source = model.source
|
||||
transmission_method = model.transmission_method
|
||||
data = model.data
|
||||
encryption = model.encryption
|
||||
frequency = model.frequency
|
||||
|
||||
/datum/signal/proc/debug_print()
|
||||
if (source)
|
||||
. = "signal = {source = '[source]' ([source:x],[source:y],[source:z])\n"
|
||||
else
|
||||
. = "signal = {source = '[source]' ()\n"
|
||||
for (var/i in data)
|
||||
. += "data\[\"[i]\"\] = \"[data[i]]\"\n"
|
||||
if(islist(data[i]))
|
||||
var/list/L = data[i]
|
||||
for(var/t in L)
|
||||
. += "data\[\"[i]\"\] list has: [t]"
|
||||
|
||||
//callback used by objects to react to incoming radio signals
|
||||
/obj/proc/receive_signal(datum/signal/signal, receive_method, receive_param)
|
||||
return null
|
||||
@@ -1,8 +1,10 @@
|
||||
SUBSYSTEM_DEF(dbcore)
|
||||
name = "Database"
|
||||
flags = SS_TICKER
|
||||
init_stage = INITSTAGE_EARLY
|
||||
wait = 10 // Not seconds because we're running on SS_TICKER
|
||||
init_order = INIT_ORDER_DBCORE
|
||||
runlevels = RUNLEVEL_LOBBY|RUNLEVELS_DEFAULT
|
||||
priority = FIRE_PRIORITY_DATABASE
|
||||
|
||||
var/failed_connection_timeout = 0
|
||||
|
||||
@@ -41,6 +43,7 @@ SUBSYSTEM_DEF(dbcore)
|
||||
//var/db_daemon_started = FALSE
|
||||
|
||||
/datum/controller/subsystem/dbcore/Initialize()
|
||||
Connect()
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
/datum/controller/subsystem/dbcore/stat_entry(msg)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
SUBSYSTEM_DEF(events)
|
||||
name = "Events" // VOREStation Edit - This is still the main events subsystem for us.
|
||||
wait = 2 SECONDS
|
||||
init_stage = INITSTAGE_LAST
|
||||
|
||||
var/tmp/list/currentrun = null
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ SUBSYSTEM_DEF(event_ticker)
|
||||
name = "Events (Ticker)"
|
||||
wait = 2 SECONDS
|
||||
runlevels = RUNLEVEL_GAME
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/events
|
||||
)
|
||||
|
||||
// List of `/datum/event2/event`s that are currently active, and receiving process() ticks.
|
||||
var/list/active_events = list()
|
||||
|
||||
@@ -96,7 +96,7 @@ SUBSYSTEM_DEF(game_master)
|
||||
// These are ran before committing to an event.
|
||||
// Returns TRUE if the system is allowed to procede, otherwise returns FALSE.
|
||||
/datum/controller/subsystem/game_master/proc/pre_event_checks(quiet = FALSE)
|
||||
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
|
||||
if(!SSticker || SSticker.current_state != GAME_STATE_PLAYING)
|
||||
if(!quiet)
|
||||
log_game_master("Unable to start event: Ticker is nonexistent, or the game is not ongoing.")
|
||||
return FALSE
|
||||
|
||||
@@ -27,8 +27,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
wait = 2 SECONDS
|
||||
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
init_order = INIT_ORDER_GARBAGE
|
||||
// init_stage = INITSTAGE_EARLY
|
||||
init_stage = INITSTAGE_FIRST
|
||||
|
||||
var/list/collection_timeout = list(GC_FILTER_QUEUE, GC_CHECK_QUEUE, GC_DEL_QUEUE) // deciseconds to wait before moving something up in the queue to the next level
|
||||
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
//
|
||||
SUBSYSTEM_DEF(holomaps)
|
||||
name = "HoloMiniMaps"
|
||||
init_order = INIT_ORDER_HOLOMAPS
|
||||
flags = SS_NO_FIRE
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/atoms
|
||||
)
|
||||
var/static/holomaps_initialized = FALSE
|
||||
var/static/list/holoMiniMaps = list()
|
||||
var/static/list/extraMiniMaps = list()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(input)
|
||||
name = "Input"
|
||||
wait = 1 // SS_TICKER means this runs every tick
|
||||
init_order = INIT_ORDER_INPUT
|
||||
init_stage = INITSTAGE_EARLY
|
||||
flags = SS_TICKER | SS_NO_INIT
|
||||
priority = FIRE_PRIORITY_INPUT
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
|
||||
@@ -6,7 +6,12 @@
|
||||
SUBSYSTEM_DEF(internal_wiki)
|
||||
name = "Wiki"
|
||||
wait = 1
|
||||
init_order = INIT_ORDER_WIKI
|
||||
//dependencies = list(
|
||||
// /datum/controller/subsystem/chemistry,
|
||||
// /datum/controller/subsystem/plants,
|
||||
// /datum/controller/subsystem/supply
|
||||
//)
|
||||
init_stage = INITSTAGE_LAST
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
VAR_PRIVATE/list/pages = list()
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
SUBSYSTEM_DEF(job)
|
||||
name = "Job"
|
||||
init_order = INIT_ORDER_JOB
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/mapping,
|
||||
)
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/list/occupations = list() //List of all jobs
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
SUBSYSTEM_DEF(lighting)
|
||||
name = "Lighting"
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/machines
|
||||
)
|
||||
wait = 1
|
||||
init_order = INIT_ORDER_LIGHTING
|
||||
flags = SS_TICKER
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY // Do some work during lobby waiting period. May as well.
|
||||
var/sun_mult = 1.0
|
||||
@@ -19,8 +21,8 @@ SUBSYSTEM_DEF(lighting)
|
||||
|
||||
|
||||
/datum/controller/subsystem/lighting/Initialize()
|
||||
if(!subsystem_initialized)
|
||||
subsystem_initialized = TRUE
|
||||
if(!initialized)
|
||||
initialized = TRUE
|
||||
create_all_lighting_objects()
|
||||
|
||||
for(var/datum/planet/planet in SSplanets.planets)
|
||||
@@ -177,5 +179,5 @@ SUBSYSTEM_DEF(lighting)
|
||||
/datum/controller/subsystem/lighting
|
||||
|
||||
/datum/controller/subsystem/lighting/Recover()
|
||||
subsystem_initialized = SSlighting.subsystem_initialized
|
||||
initialized = SSlighting.initialized
|
||||
..()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
SUBSYSTEM_DEF(lobby_monitor)
|
||||
name = "Lobby Art"
|
||||
init_order = INIT_ORDER_LOBBY
|
||||
// init_stage = INITSTAGE_EARLY
|
||||
init_stage = INITSTAGE_EARLY
|
||||
flags = SS_NO_INIT
|
||||
wait = 1 SECOND
|
||||
runlevels = ALL
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
|
||||
SUBSYSTEM_DEF(machines)
|
||||
name = "Machines"
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/points_of_interest
|
||||
)
|
||||
priority = FIRE_PRIORITY_MACHINES
|
||||
init_order = INIT_ORDER_MACHINES
|
||||
flags = SS_KEEP_TIMING
|
||||
runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME
|
||||
|
||||
|
||||
@@ -1,19 +1,32 @@
|
||||
// Handles map-related tasks, mostly here to ensure it does so after the MC initializes.
|
||||
SUBSYSTEM_DEF(mapping)
|
||||
name = "Mapping"
|
||||
init_order = INIT_ORDER_MAPPING
|
||||
//dependencies = list(
|
||||
// /datum/controller/subsystem/job,
|
||||
///datum/controller/subsystem/processing/station,
|
||||
// /datum/controller/subsystem/chemistry
|
||||
// ///datum/controller/subsystem/processing/reagents
|
||||
//)
|
||||
dependencies = list(
|
||||
///datum/controller/subsystem/garbage,
|
||||
/datum/controller/subsystem/vis_overlays,
|
||||
/datum/controller/subsystem/chemistry
|
||||
)
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/list/map_templates = list()
|
||||
var/obj/effect/landmark/engine_loader/engine_loader
|
||||
var/list/shelter_templates = list()
|
||||
|
||||
// TODO: Implement Later
|
||||
var/datum/map/current_map
|
||||
|
||||
/datum/controller/subsystem/mapping/Recover()
|
||||
flags |= SS_NO_INIT // Make extra sure we don't initialize twice.
|
||||
shelter_templates = SSmapping.shelter_templates
|
||||
|
||||
/datum/controller/subsystem/mapping/Initialize()
|
||||
if(subsystem_initialized)
|
||||
if(initialized)
|
||||
return
|
||||
world.max_z_changed() // This is to set up the player z-level list, maxz hasn't actually changed (probably)
|
||||
load_map_templates()
|
||||
@@ -24,6 +37,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
// TODO - Other stuff related to maps and areas could be moved here too. Look at /tg
|
||||
// Lateload Code related to Expedition areas.
|
||||
if(using_map) // VOREStation Edit: Re-enable this.
|
||||
current_map = using_map
|
||||
loadLateMaps()
|
||||
|
||||
if(CONFIG_GET(flag/generate_map)) // VOREStation Edit: Re-order this.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(media_tracks)
|
||||
name = "Media Tracks"
|
||||
flags = SS_NO_FIRE
|
||||
init_order = INIT_ORDER_MEDIA_TRACKS
|
||||
init_stage = INITSTAGE_EARLY
|
||||
|
||||
/// Every track, including secret
|
||||
var/list/all_tracks = list()
|
||||
|
||||
@@ -12,6 +12,12 @@ SUBSYSTEM_DEF(mobs)
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/atoms,
|
||||
/datum/controller/subsystem/points_of_interest,
|
||||
/datum/controller/subsystem/shuttles
|
||||
)
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/log_extensively = FALSE
|
||||
var/list/timelog = list()
|
||||
@@ -96,22 +102,14 @@ SUBSYSTEM_DEF(mobs)
|
||||
log_game(msg)
|
||||
log_world(msg)
|
||||
|
||||
/datum/controller/subsystem/mobs/fail()
|
||||
..()
|
||||
log_recent()
|
||||
|
||||
/datum/controller/subsystem/mobs/critfail()
|
||||
..()
|
||||
log_recent()
|
||||
|
||||
/datum/controller/subsystem/mobs/proc/report_death(var/mob/living/L)
|
||||
if(!L)
|
||||
return
|
||||
if(!L.key || !L.mind)
|
||||
return
|
||||
if(!ticker || !ticker.mode)
|
||||
if(!SSticker || !SSticker.mode)
|
||||
return
|
||||
ticker.mode.check_win()
|
||||
SSticker.mode.check_win()
|
||||
|
||||
// Don't bother with the rest if we've not got a DB to do anything with
|
||||
if(!CONFIG_GET(flag/enable_stat_tracking) || !CONFIG_GET(flag/sql_enabled))
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
SUBSYSTEM_DEF(nightshift)
|
||||
name = "Night Shift"
|
||||
init_order = INIT_ORDER_NIGHTSHIFT
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/lighting
|
||||
)
|
||||
priority = FIRE_PRIORITY_NIGHTSHIFT
|
||||
wait = 60 SECONDS
|
||||
flags = SS_NO_TICK_CHECK
|
||||
|
||||
@@ -3,7 +3,9 @@ SUBSYSTEM_DEF(overlays)
|
||||
flags = SS_TICKER
|
||||
wait = 1 // SS_TICKER - Ticks
|
||||
priority = FIRE_PRIORITY_OVERLAYS
|
||||
init_order = INIT_ORDER_OVERLAY
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/atoms
|
||||
)
|
||||
|
||||
/// The queue of atoms that need overlay updates.
|
||||
var/static/tmp/list/queue = list()
|
||||
|
||||
@@ -4,8 +4,12 @@ Readme at code\modules\awaymissions\overmap_renamer\readme.md
|
||||
|
||||
SUBSYSTEM_DEF(overmap_renamer)
|
||||
name = "Overmap Renamer"
|
||||
init_order = INIT_ORDER_MAPRENAME //Loaded very late in initializations. Must come before mapping and objs. Uses both as inputs.
|
||||
runlevels = RUNLEVEL_INIT
|
||||
//Loaded very late in initializations. Must come before mapping and objs. Uses both as inputs.
|
||||
init_stage = INITSTAGE_LAST
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/skybox
|
||||
)
|
||||
runlevels = RUNLEVEL_SETUP
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
SUBSYSTEM_DEF(persistence)
|
||||
name = "Persistence"
|
||||
init_order = INIT_ORDER_PERSISTENCE
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/mapping,
|
||||
/datum/controller/subsystem/atoms,
|
||||
/datum/controller/subsystem/points_of_interest
|
||||
)
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/list/tracking_values = list()
|
||||
var/list/persistence_datums = list()
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
SUBSYSTEM_DEF(ping)
|
||||
name = "Ping"
|
||||
priority = FIRE_PRIORITY_PING
|
||||
// init_stage = INITSTAGE_EARLY
|
||||
init_stage = INITSTAGE_EARLY
|
||||
wait = 4 SECONDS
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
SUBSYSTEM_DEF(planets)
|
||||
name = "Planets"
|
||||
init_order = INIT_ORDER_PLANETS
|
||||
priority = FIRE_PRIORITY_PLANETS
|
||||
wait = 2 SECONDS
|
||||
flags = SS_BACKGROUND
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/plants
|
||||
)
|
||||
|
||||
var/static/list/planets = list()
|
||||
var/static/list/z_to_planet = list()
|
||||
@@ -75,7 +77,7 @@ SUBSYSTEM_DEF(planets)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
#ifndef UNIT_TEST // Don't be updating temperatures and such during unit tests
|
||||
#ifndef UNIT_TESTS // Don't be updating temperatures and such during unit tests
|
||||
var/list/needs_temp_update = src.needs_temp_update
|
||||
while(needs_temp_update.len)
|
||||
var/datum/planet/P = needs_temp_update[needs_temp_update.len]
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
SUBSYSTEM_DEF(plants)
|
||||
name = "Plants"
|
||||
init_order = INIT_ORDER_PLANTS
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/mapping
|
||||
)
|
||||
priority = FIRE_PRIORITY_PLANTS
|
||||
wait = PLANT_TICK_TIME
|
||||
|
||||
|
||||
@@ -3,8 +3,10 @@ SUBSYSTEM_DEF(points_of_interest)
|
||||
name = "Points of Interest"
|
||||
wait = 1 SECONDS
|
||||
priority = FIRE_PRIORITY_POIS
|
||||
init_order = INIT_ORDER_POIS
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT //POIs can be loaded mid-round.
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/holomaps
|
||||
)
|
||||
var/list/obj/effect/landmark/poi_loader/poi_queue = list()
|
||||
|
||||
/datum/controller/subsystem/points_of_interest/Initialize()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(instruments)
|
||||
name = "Instruments"
|
||||
wait = 0.5
|
||||
init_order = INIT_ORDER_INSTRUMENTS
|
||||
flags = SS_KEEP_TIMING
|
||||
priority = FIRE_PRIORITY_INSTRUMENTS
|
||||
/// List of all instrument data, associative id = datum
|
||||
|
||||
@@ -96,14 +96,6 @@ SUBSYSTEM_DEF(processing)
|
||||
log_game(msg)
|
||||
log_world(msg)
|
||||
|
||||
/datum/controller/subsystem/processing/fail()
|
||||
..()
|
||||
log_recent()
|
||||
|
||||
/datum/controller/subsystem/processing/critfail()
|
||||
..()
|
||||
log_recent()
|
||||
|
||||
/datum/proc/DebugSubsystemProcess(var/wait, var/times_fired, var/datum/controller/subsystem/processing/subsystem)
|
||||
subsystem.debug_last_thing = src
|
||||
var/start_tick = world.time
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
SUBSYSTEM_DEF(profiler)
|
||||
name = "Profiler"
|
||||
init_stage = INITSTAGE_FIRST
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
wait = 300 SECONDS
|
||||
var/fetch_cost = 0
|
||||
var/write_cost = 0
|
||||
|
||||
/datum/controller/subsystem/profiler/stat_entry(msg)
|
||||
msg += "F:[round(fetch_cost,1)]ms"
|
||||
msg += "|W:[round(write_cost,1)]ms"
|
||||
return msg
|
||||
|
||||
/datum/controller/subsystem/profiler/Initialize()
|
||||
if(CONFIG_GET(flag/auto_profile))
|
||||
StartProfiling()
|
||||
else
|
||||
StopProfiling() //Stop the early start profiler
|
||||
wait = CONFIG_GET(number/profiler_interval)
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
/datum/controller/subsystem/profiler/OnConfigLoad()
|
||||
if(CONFIG_GET(flag/auto_profile))
|
||||
StartProfiling()
|
||||
can_fire = TRUE
|
||||
else
|
||||
StopProfiling()
|
||||
can_fire = FALSE
|
||||
|
||||
/datum/controller/subsystem/profiler/fire()
|
||||
DumpFile()
|
||||
|
||||
/datum/controller/subsystem/profiler/Shutdown()
|
||||
if(CONFIG_GET(flag/auto_profile))
|
||||
DumpFile(allow_yield = FALSE)
|
||||
world.Profile(PROFILE_CLEAR, type = "sendmaps")
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/profiler/proc/StartProfiling()
|
||||
world.Profile(PROFILE_START)
|
||||
world.Profile(PROFILE_START, type = "sendmaps")
|
||||
|
||||
/datum/controller/subsystem/profiler/proc/StopProfiling()
|
||||
world.Profile(PROFILE_STOP)
|
||||
world.Profile(PROFILE_STOP, type = "sendmaps")
|
||||
|
||||
/datum/controller/subsystem/profiler/proc/DumpFile(allow_yield = TRUE)
|
||||
var/timer = TICK_USAGE_REAL
|
||||
var/current_profile_data = world.Profile(PROFILE_REFRESH, format = "json")
|
||||
var/current_sendmaps_data = world.Profile(PROFILE_REFRESH, type = "sendmaps", format="json")
|
||||
fetch_cost = MC_AVERAGE(fetch_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
if(allow_yield)
|
||||
CHECK_TICK
|
||||
|
||||
if(!length(current_profile_data)) //Would be nice to have explicit proc to check this
|
||||
stack_trace("Warning, profiling stopped manually before dump.")
|
||||
var/prof_file = file("[GLOB.log_directory]/profiler/profiler-[round(world.time * 0.1, 10)].json")
|
||||
if(fexists(prof_file))
|
||||
fdel(prof_file)
|
||||
if(!length(current_sendmaps_data)) //Would be nice to have explicit proc to check this
|
||||
stack_trace("Warning, sendmaps profiling stopped manually before dump.")
|
||||
var/sendmaps_file = file("[GLOB.log_directory]/profiler/sendmaps-[round(world.time * 0.1, 10)].json")
|
||||
if(fexists(sendmaps_file))
|
||||
fdel(sendmaps_file)
|
||||
|
||||
timer = TICK_USAGE_REAL
|
||||
WRITE_FILE(prof_file, current_profile_data)
|
||||
WRITE_FILE(sendmaps_file, current_sendmaps_data)
|
||||
write_cost = MC_AVERAGE(write_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user