mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-09 16:07:40 +00:00
Merge branch 'master' into Dispencer-UI-change
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
.dockerignore
|
||||
.editorconfig
|
||||
.travis.yml
|
||||
GPLv3.txt
|
||||
LICENSE
|
||||
README.md
|
||||
@@ -26,5 +25,4 @@ tgstation.dyn.rsc
|
||||
libmariadb.dll
|
||||
rust_g.dll
|
||||
BSQL.dll
|
||||
appveyor.yml
|
||||
Dockerfile
|
||||
|
||||
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -38,5 +38,8 @@
|
||||
*.dmm text eol=lf merge=dmm
|
||||
*.dmi binary merge=dmi
|
||||
|
||||
##Force tab indents on dm files
|
||||
*.dm whitespace=indent-with-non-tab
|
||||
|
||||
## Force changelog merging to use union
|
||||
html/changelog.html text eol=lf merge=union
|
||||
|
||||
114
.github/workflows/ci_suite.yml
vendored
Normal file
114
.github/workflows/ci_suite.yml
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
name: CI Suite
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
run_linters:
|
||||
if: "!contains(github.event.head_commit.message, '[ci skip]')"
|
||||
name: Run Linters
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: $HOME/SpacemanDMM
|
||||
key: ${{ runner.os }}-spacemandmm
|
||||
- name: Install Tools
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
bash tools/ci/install_build_tools.sh
|
||||
bash tools/ci/install_spaceman_dmm.sh dreamchecker
|
||||
pip3 install -r tools/mapmerge2/requirements.txt
|
||||
- name: Run Linters
|
||||
run: |
|
||||
bash tools/ci/check_filedirs.sh tgstation.dme
|
||||
bash tools/ci/check_changelogs.sh
|
||||
find . -name "*.php" -print0 | xargs -0 -n1 php -l
|
||||
find . -name "*.json" -not -path "*/node_modules/*" -print0 | xargs -0 python3 ./tools/json_verifier.py
|
||||
bash tools/ci/build_tgui.sh
|
||||
bash tools/ci/check_grep.sh
|
||||
python3 tools/mapmerge2/dmi.py --test
|
||||
~/dreamchecker > ${GITHUB_WORKSPACE}/output-annotations.txt 2>&1
|
||||
- name: Annotate Lints
|
||||
uses: yogstation13/DreamAnnotate@v1
|
||||
if: always()
|
||||
with:
|
||||
outputFile: output-annotations.txt
|
||||
|
||||
compile_all_maps:
|
||||
if: "!contains(github.event.head_commit.message, '[ci skip]')"
|
||||
name: Compile Maps
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: $HOME/BYOND
|
||||
key: ${{ runner.os }}-byond
|
||||
- name: Compile All Maps
|
||||
run: |
|
||||
bash tools/ci/install_byond.sh
|
||||
source $HOME/BYOND/byond/bin/byondsetup
|
||||
python3 tools/ci/template_dm_generator.py
|
||||
bash tools/ci/dm.sh -DCIBUILDING -DCITESTING -DALL_MAPS tgstation.dme
|
||||
run_all_tests:
|
||||
if: "!contains(github.event.head_commit.message, '[ci skip]')"
|
||||
name: Integration Tests
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:latest
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
ports:
|
||||
- 3306
|
||||
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: $HOME/BYOND
|
||||
key: ${{ runner.os }}-byond
|
||||
- name: Setup database
|
||||
run: |
|
||||
sudo systemctl start mysql
|
||||
mysql -u root -proot -e 'CREATE DATABASE tg_ci;'
|
||||
mysql -u root -proot tg_ci < SQL/tgstation_schema.sql
|
||||
mysql -u root -proot -e 'CREATE DATABASE tg_ci_prefixed;'
|
||||
mysql -u root -proot tg_ci_prefixed < SQL/tgstation_schema_prefixed.sql
|
||||
- name: Install rust-g
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt update || true
|
||||
sudo apt install libssl1.1:i386
|
||||
bash tools/ci/install_rust_g.sh
|
||||
# - name: Compile and run tests
|
||||
# run: |
|
||||
# bash tools/ci/install_byond.sh
|
||||
# source $HOME/BYOND/byond/bin/byondsetup
|
||||
# bash tools/ci/dm.sh -DCIBUILDING tgstation.dme
|
||||
# bash tools/ci/run_server.sh
|
||||
test_windows:
|
||||
if: "!contains(github.event.head_commit.message, '[ci skip]')"
|
||||
name: Windows Build
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Compile
|
||||
run: pwsh tools/ci/build.ps1
|
||||
- name: Create artifact
|
||||
run: |
|
||||
md deploy
|
||||
bash tools/deploy.sh ./deploy
|
||||
- name: Deploy artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: deploy
|
||||
path: deploy
|
||||
2
.github/workflows/compile_changelogs.yml
vendored
2
.github/workflows/compile_changelogs.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
CHANGELOG_ENABLER: ${{ secrets.CHANGELOG_ENABLER }}
|
||||
run: |
|
||||
unset SECRET_EXISTS
|
||||
if [-n $CHANGELOG_ENABLER]; then SECRET_EXISTS='true' ; fi
|
||||
if [ -n $CHANGELOG_ENABLER ]; then SECRET_EXISTS='true' ; fi
|
||||
echo ::set-output name=CL_ENABLED::${SECRET_EXISTS}
|
||||
- name: "Setup python"
|
||||
if: steps.value_holder.outputs.CL_ENABLED
|
||||
|
||||
22
.github/workflows/docker_publish.yml
vendored
Normal file
22
.github/workflows/docker_publish.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Docker Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build and Publish Docker Image to Registry
|
||||
uses: elgohr/Publish-Docker-Github-Action@master
|
||||
with:
|
||||
name: tgstation/tgstation
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
dockerfile: Dockerfile
|
||||
tags: "latest"
|
||||
cache: true
|
||||
31
.github/workflows/generate_documentation.yml
vendored
Normal file
31
.github/workflows/generate_documentation.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: Generate documentation
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
generate_documentation:
|
||||
if: "!contains(github.event.head_commit.message, '[ci skip]')"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: $HOME/SpacemanDMM
|
||||
key: ${{ runner.os }}-spacemandmm
|
||||
- name: Install SpacemanDMM
|
||||
run: bash tools/ci/install_spaceman_dmm.sh dmdoc
|
||||
- name: Generate documentation
|
||||
run: |
|
||||
~/dmdoc
|
||||
touch dmdoc/.nojekyll
|
||||
echo codedocs.tgstation13.org > dmdoc/CNAME
|
||||
- name: Deploy
|
||||
uses: JamesIves/github-pages-deploy-action@3.7.1
|
||||
with:
|
||||
BRANCH: gh-pages
|
||||
CLEAN: true
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SINGLE_COMMIT: true
|
||||
FOLDER: dmdoc
|
||||
4
.github/workflows/update_tgs_dmapi.yml
vendored
4
.github/workflows/update_tgs_dmapi.yml
vendored
@@ -26,6 +26,7 @@ jobs:
|
||||
library-path: 'code/modules/tgs'
|
||||
|
||||
- name: Commit and Push
|
||||
continue-on-error: true
|
||||
run: |
|
||||
git config user.name tgstation-server
|
||||
git config user.email tgstation-server@users.noreply.github.com
|
||||
@@ -35,6 +36,7 @@ jobs:
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: repo-sync/pull-request@v2
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
source_branch: "tgs-dmapi-update"
|
||||
destination_branch: "master"
|
||||
@@ -42,4 +44,4 @@ jobs:
|
||||
pr_body: "This pull request updates the TGS DMAPI to the latest version. Please note any breaking or unimplemented changes before merging."
|
||||
pr_label: "Tools"
|
||||
pr_allow_empty: false
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github_token: ${{ secrets.TGS_UPDATER }}
|
||||
|
||||
102
.travis.yml
102
.travis.yml
@@ -1,102 +0,0 @@
|
||||
language: generic
|
||||
os: linux
|
||||
dist: xenial
|
||||
|
||||
branches:
|
||||
except:
|
||||
- ___TGS3TempBranch
|
||||
- ___TGSTempBranch
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- name: "Run Linters"
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- python3
|
||||
- python3-pip
|
||||
- python3-setuptools
|
||||
- pcregrep
|
||||
- rustc
|
||||
- cargo
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/SpacemanDMM
|
||||
install:
|
||||
- tools/travis/install_build_tools.sh
|
||||
- tools/travis/install_spaceman_dmm.sh dreamchecker
|
||||
script:
|
||||
- tools/travis/check_filedirs.sh tgstation.dme
|
||||
- tools/travis/check_changelogs.sh
|
||||
- find . -name "*.php" -print0 | xargs -0 -n1 php -l
|
||||
- find . -name "*.json" -not -path "*/node_modules/*" -print0 | xargs -0 python3 ./tools/json_verifier.py
|
||||
- tools/travis/build_tgui.sh
|
||||
- tools/travis/check_grep.sh
|
||||
- python3 tools/travis/check_line_endings.py
|
||||
- ~/dreamchecker
|
||||
|
||||
- name: "Compile All Maps"
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libstdc++6:i386
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/BYOND
|
||||
install:
|
||||
- tools/travis/install_byond.sh
|
||||
- source $HOME/BYOND/byond/bin/byondsetup
|
||||
before_script:
|
||||
- tools/travis/template_dm_generator.py
|
||||
script:
|
||||
- tools/travis/dm.sh -DTRAVISBUILDING -DTRAVISTESTING -DALL_MAPS tgstation.dme
|
||||
|
||||
- name: "Compile and Run Tests"
|
||||
addons:
|
||||
mariadb: '10.2'
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- libstdc++6:i386
|
||||
- gcc-multilib
|
||||
- g++-7
|
||||
- g++-7-multilib
|
||||
- libmariadb-client-lgpl-dev:i386
|
||||
- libmariadbd-dev
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/BYOND
|
||||
- $HOME/libmariadb
|
||||
install:
|
||||
- tools/travis/install_byond.sh
|
||||
- source $HOME/BYOND/byond/bin/byondsetup
|
||||
- tools/travis/install_libmariadb.sh
|
||||
- tools/travis/install_rust_g.sh
|
||||
before_script:
|
||||
- mysql -u root -e 'CREATE DATABASE tg_travis;'
|
||||
- mysql -u root tg_travis < SQL/tgstation_schema.sql
|
||||
- mysql -u root -e 'CREATE DATABASE tg_travis_prefixed;'
|
||||
- mysql -u root tg_travis_prefixed < SQL/tgstation_schema_prefixed.sql
|
||||
- tools/travis/build_bsql.sh
|
||||
script:
|
||||
- tools/travis/dm.sh -DTRAVISBUILDING tgstation.dme || travis_terminate 1
|
||||
- tools/travis/run_server.sh
|
||||
|
||||
# - name: "Generate Documentation"
|
||||
# # Only run for non-PR commits to the real master branch.
|
||||
# if: branch = master AND head_branch IS blank
|
||||
# install:
|
||||
# - tools/travis/install_spaceman_dmm.sh dmdoc
|
||||
# before_script:
|
||||
# # Travis checks out a hash, try to get back on a branch.
|
||||
# - git checkout $TRAVIS_BRANCH || true
|
||||
# script:
|
||||
# - ~/dmdoc
|
||||
# - touch dmdoc/.nojekyll
|
||||
# deploy:
|
||||
# provider: pages
|
||||
# skip_cleanup: true
|
||||
# local_dir: dmdoc
|
||||
# token: $DMDOC_GITHUB_TOKEN
|
||||
# fqdn: codedocs.tgstation13.org
|
||||
11
.vscode/extensions.json
vendored
11
.vscode/extensions.json
vendored
@@ -1,9 +1,10 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"gbasood.byond-dm-language-support",
|
||||
"platymuus.dm-langclient",
|
||||
"recommendations": [
|
||||
"gbasood.byond-dm-language-support",
|
||||
"platymuus.dm-langclient",
|
||||
"EditorConfig.EditorConfig",
|
||||
"arcanis.vscode-zipfs",
|
||||
"dbaeumer.vscode-eslint"
|
||||
]
|
||||
"dbaeumer.vscode-eslint",
|
||||
"kevinkyang.auto-comment-blocks"
|
||||
]
|
||||
}
|
||||
|
||||
50
Dockerfile
50
Dockerfile
@@ -1,14 +1,12 @@
|
||||
FROM tgstation/byond:513.1508 as base
|
||||
FROM tgstation/byond:513.1533 as base
|
||||
|
||||
FROM base as build_base
|
||||
FROM base as rust_g
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
git \
|
||||
ca-certificates
|
||||
|
||||
FROM build_base as rust_g
|
||||
|
||||
WORKDIR /rust_g
|
||||
|
||||
RUN apt-get install -y --no-install-recommends \
|
||||
@@ -27,36 +25,6 @@ RUN /bin/bash -c "source dependencies.sh \
|
||||
&& git checkout FETCH_HEAD \
|
||||
&& ~/.cargo/bin/cargo build --release
|
||||
|
||||
FROM build_base as bsql
|
||||
|
||||
WORKDIR /bsql
|
||||
|
||||
RUN apt-get install -y --no-install-recommends software-properties-common \
|
||||
&& add-apt-repository ppa:ubuntu-toolchain-r/test \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
cmake \
|
||||
make \
|
||||
g++-7 \
|
||||
libmariadb-client-lgpl-dev \
|
||||
&& git init \
|
||||
&& git remote add origin https://github.com/tgstation/BSQL
|
||||
|
||||
COPY dependencies.sh .
|
||||
|
||||
RUN /bin/bash -c "source dependencies.sh \
|
||||
&& git fetch --depth 1 origin \$BSQL_VERSION" \
|
||||
&& git checkout FETCH_HEAD
|
||||
|
||||
WORKDIR /bsql/artifacts
|
||||
|
||||
ENV CC=gcc-7 CXX=g++-7
|
||||
|
||||
RUN ln -s /usr/include/mariadb /usr/include/mysql \
|
||||
&& ln -s /usr/lib/i386-linux-gnu /root/MariaDB \
|
||||
&& cmake .. \
|
||||
&& make
|
||||
|
||||
FROM base as dm_base
|
||||
|
||||
WORKDIR /tgstation
|
||||
@@ -65,26 +33,30 @@ FROM dm_base as build
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN DreamMaker -max_errors 0 tgstation.dme && tools/deploy.sh /deploy
|
||||
RUN DreamMaker -max_errors 0 tgstation.dme \
|
||||
&& tools/deploy.sh /deploy \
|
||||
&& rm /deploy/*.dll
|
||||
|
||||
FROM dm_base
|
||||
|
||||
EXPOSE 1337
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends software-properties-common \
|
||||
&& add-apt-repository ppa:ubuntu-toolchain-r/test \
|
||||
&& apt-get update \
|
||||
&& apt-get upgrade -y \
|
||||
&& apt-get dist-upgrade -y \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
libmariadb2 \
|
||||
mariadb-client \
|
||||
libssl1.0.0 \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& mkdir -p /root/.byond/bin
|
||||
|
||||
COPY --from=rust_g /rust_g/target/release/librust_g.so /root/.byond/bin/rust_g
|
||||
COPY --from=bsql /bsql/artifacts/src/BSQL/libBSQL.so ./
|
||||
COPY --from=build /deploy ./
|
||||
|
||||
#bsql fexists memes
|
||||
RUN ln -s /tgstation/libBSQL.so /root/.byond/bin/libBSQL.so
|
||||
|
||||
VOLUME [ "/tgstation/config", "/tgstation/data" ]
|
||||
|
||||
ENTRYPOINT [ "DreamDaemon", "tgstation.dmb", "-port", "1337", "-trusted", "-close", "-verbose" ]
|
||||
|
||||
@@ -1,2 +1,9 @@
|
||||
[langserver]
|
||||
dreamchecker = true
|
||||
|
||||
[code_standards]
|
||||
disallow_relative_type_definitions = true
|
||||
disallow_relative_proc_definitions = true
|
||||
|
||||
[dmdoc]
|
||||
use_typepath_names = true
|
||||
|
||||
17
TGS3.json
17
TGS3.json
@@ -1,22 +1,9 @@
|
||||
{
|
||||
"documentation": "/tg/station server 3 configuration file",
|
||||
"changelog": {
|
||||
"script": "tools/ss13_genchangelog.py",
|
||||
"arguments": "html/changelog.html html/changelogs",
|
||||
"pip_dependancies": [
|
||||
"PyYaml",
|
||||
"beautifulsoup4"
|
||||
]
|
||||
},
|
||||
"synchronize_paths": [
|
||||
"html/changelog.html",
|
||||
"html/changelogs/*"
|
||||
],
|
||||
"synchronize_paths": [],
|
||||
"static_directories": [
|
||||
"config",
|
||||
"data"
|
||||
],
|
||||
"dlls": [
|
||||
"libmariadb.dll"
|
||||
]
|
||||
"dlls": []
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
/obj/item/mining_scanner,
|
||||
/obj/item/flashlight/lantern,
|
||||
/obj/item/card/id/mining,
|
||||
/obj/item/gps/mining,
|
||||
/obj/item/gps/mining/off,
|
||||
/turf/open/floor/plating,
|
||||
/area/ruin/powered/golem_ship)
|
||||
"d" = (
|
||||
@@ -32,7 +32,7 @@
|
||||
/obj/item/mining_scanner,
|
||||
/obj/item/flashlight/lantern,
|
||||
/obj/item/card/id/mining,
|
||||
/obj/item/gps/mining,
|
||||
/obj/item/gps/mining/off,
|
||||
/turf/open/floor/plating,
|
||||
/area/ruin/powered/golem_ship)
|
||||
"e" = (
|
||||
@@ -71,8 +71,8 @@
|
||||
/area/ruin/powered/golem_ship)
|
||||
"k" = (
|
||||
/obj/machinery/computer/arcade/battle{
|
||||
icon_state = "arcade";
|
||||
dir = 4
|
||||
dir = 4;
|
||||
icon_state = "arcade"
|
||||
},
|
||||
/turf/open/floor/mineral/titanium/purple,
|
||||
/area/ruin/powered/golem_ship)
|
||||
@@ -112,8 +112,8 @@
|
||||
/area/ruin/powered/golem_ship)
|
||||
"s" = (
|
||||
/obj/machinery/computer/arcade/orion_trail{
|
||||
icon_state = "arcade";
|
||||
dir = 4
|
||||
dir = 4;
|
||||
icon_state = "arcade"
|
||||
},
|
||||
/turf/open/floor/mineral/titanium/purple,
|
||||
/area/ruin/powered/golem_ship)
|
||||
|
||||
@@ -111,6 +111,17 @@
|
||||
/obj/structure/alien/resin/membrane,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"ax" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/effect/decal/cleanable/blood/gibs,
|
||||
/obj/structure/alien/weeds/node,
|
||||
/mob/living/simple_animal/hostile/alien/drone,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"ay" = (
|
||||
/obj/structure/stone_tile/slab/cracked,
|
||||
/turf/open/indestructible/boss,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"aA" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/item/flamethrower,
|
||||
@@ -130,6 +141,17 @@
|
||||
},
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"aD" = (
|
||||
/obj/structure/stone_tile/surrounding_tile{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/stone_tile/surrounding_tile,
|
||||
/obj/structure/stone_tile/surrounding_tile/cracked{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/stone_tile/center,
|
||||
/turf/open/chasm/lavaland,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"aE" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/effect/decal/cleanable/ash,
|
||||
@@ -160,6 +182,19 @@
|
||||
/obj/effect/decal/cleanable/blood,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"aK" = (
|
||||
/obj/structure/stone_tile/surrounding_tile/cracked{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/stone_tile/surrounding_tile/cracked{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/stone_tile/surrounding_tile/cracked{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/stone_tile/center/cracked,
|
||||
/turf/open/chasm/lavaland,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"aL" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/item/tank/internals/plasma,
|
||||
@@ -170,6 +205,26 @@
|
||||
/obj/effect/decal/cleanable/blood/xeno,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"aN" = (
|
||||
/obj/structure/stone_tile/block{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/stone_tile{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/stone_tile/cracked,
|
||||
/turf/open/indestructible/boss,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"aO" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/effect/mob_spawn/alien/corpse/humanoid/sentinel,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"aP" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/effect/mob_spawn/alien/corpse/humanoid/hunter,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"aQ" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/structure/bed/nest,
|
||||
@@ -215,13 +270,6 @@
|
||||
/obj/effect/gibspawner/xeno,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"aY" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/effect/decal/cleanable/blood/gibs,
|
||||
/mob/living/simple_animal/hostile/alien/drone,
|
||||
/obj/structure/alien/weeds/node,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"aZ" = (
|
||||
/turf/closed/indestructible/riveted/boss,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
@@ -338,10 +386,6 @@
|
||||
/obj/structure/stone_tile,
|
||||
/turf/open/indestructible/boss,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"bm" = (
|
||||
/obj/structure/stone_tile/slab/cracked,
|
||||
/turf/open/indestructible/boss,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"bn" = (
|
||||
/obj/structure/stone_tile/block{
|
||||
dir = 4
|
||||
@@ -365,12 +409,6 @@
|
||||
/obj/structure/stone_tile/center,
|
||||
/turf/open/chasm/lavaland,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"bp" = (
|
||||
/obj/structure/stone_tile/block{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/chasm/lavaland,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"bq" = (
|
||||
/turf/open/chasm/lavaland,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
@@ -391,33 +429,6 @@
|
||||
},
|
||||
/turf/open/chasm/lavaland,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"bt" = (
|
||||
/obj/structure/stone_tile/surrounding_tile{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/stone_tile/surrounding_tile,
|
||||
/obj/structure/stone_tile/surrounding_tile/cracked{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/stone_tile/center,
|
||||
/turf/open/chasm/lavaland,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"bu" = (
|
||||
/obj/structure/stone_tile/block/cracked{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/chasm/lavaland,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"bv" = (
|
||||
/obj/structure/stone_tile/block{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/stone_tile{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/stone_tile/cracked,
|
||||
/turf/open/indestructible/boss,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"bw" = (
|
||||
/obj/structure/stone_tile/cracked{
|
||||
dir = 4
|
||||
@@ -492,19 +503,6 @@
|
||||
/obj/structure/alien/weeds,
|
||||
/turf/template_noop,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"bE" = (
|
||||
/obj/structure/stone_tile/surrounding_tile/cracked{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/stone_tile/surrounding_tile/cracked{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/stone_tile/surrounding_tile/cracked{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/stone_tile/center/cracked,
|
||||
/turf/open/chasm/lavaland,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"dE" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/structure/bed/nest,
|
||||
@@ -514,6 +512,12 @@
|
||||
/obj/item/clothing/mask/facehugger/impregnated,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"gA" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/structure/bed/nest,
|
||||
/obj/effect/mob_spawn/alien/corpse/humanoid/sentinel,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"iA" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/structure/bed/nest,
|
||||
@@ -522,18 +526,24 @@
|
||||
/obj/item/clothing/mask/facehugger/impregnated,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"kp" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/item/reagent_containers/syringe/alien,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"lG" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/effect/mob_spawn/alien/corpse/humanoid/drone,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"pE" = (
|
||||
/obj/effect/mob_spawn/alien/corpse/humanoid/queen,
|
||||
"lM" = (
|
||||
/obj/structure/stone_tile/block{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/chasm/lavaland,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"nj" = (
|
||||
/obj/effect/mob_spawn/alien/corpse/humanoid/praetorian,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"tY" = (
|
||||
/obj/structure/alien/weeds/node,
|
||||
/obj/effect/mob_spawn/alien/corpse/humanoid/hunter,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"wA" = (
|
||||
@@ -546,12 +556,23 @@
|
||||
/mob/living/simple_animal/hostile/alien/sentinel,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"zj" = (
|
||||
/obj/structure/stone_tile/block/cracked{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/chasm/lavaland,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"Dd" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/effect/decal/cleanable/blood/gibs,
|
||||
/obj/item/storage/backpack/duffelbag/sec/surgery,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"Ha" = (
|
||||
/obj/structure/alien/weeds,
|
||||
/obj/item/reagent_containers/syringe/alien,
|
||||
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/ruin/unpowered/xenonest)
|
||||
"JM" = (
|
||||
/obj/structure/alien/weeds/node,
|
||||
/obj/effect/mob_spawn/alien/corpse/humanoid/drone,
|
||||
@@ -1075,7 +1096,7 @@ ac
|
||||
ac
|
||||
ac
|
||||
bi
|
||||
aY
|
||||
ax
|
||||
ac
|
||||
ac
|
||||
ac
|
||||
@@ -1123,7 +1144,7 @@ an
|
||||
an
|
||||
ac
|
||||
ac
|
||||
am
|
||||
gA
|
||||
ac
|
||||
ac
|
||||
aJ
|
||||
@@ -1278,10 +1299,10 @@ ac
|
||||
Dd
|
||||
ag
|
||||
ak
|
||||
ag
|
||||
aP
|
||||
af
|
||||
ac
|
||||
lG
|
||||
ag
|
||||
ac
|
||||
ac
|
||||
an
|
||||
@@ -1357,7 +1378,7 @@ ab
|
||||
ac
|
||||
af
|
||||
ag
|
||||
ar
|
||||
tY
|
||||
lG
|
||||
ag
|
||||
ag
|
||||
@@ -1511,7 +1532,7 @@ ac
|
||||
ah
|
||||
af
|
||||
ah
|
||||
JM
|
||||
ar
|
||||
Vi
|
||||
ak
|
||||
ag
|
||||
@@ -1618,7 +1639,7 @@ ag
|
||||
wA
|
||||
ag
|
||||
ag
|
||||
pE
|
||||
nj
|
||||
ag
|
||||
at
|
||||
ag
|
||||
@@ -1640,7 +1661,7 @@ ab
|
||||
aZ
|
||||
aZ
|
||||
aZ
|
||||
bm
|
||||
ay
|
||||
aZ
|
||||
aZ
|
||||
aZ
|
||||
@@ -1718,7 +1739,7 @@ ah
|
||||
ar
|
||||
ah
|
||||
ak
|
||||
kp
|
||||
Ha
|
||||
at
|
||||
ag
|
||||
ag
|
||||
@@ -1742,8 +1763,8 @@ ac
|
||||
aZ
|
||||
bc
|
||||
bj
|
||||
bp
|
||||
bt
|
||||
lM
|
||||
aD
|
||||
bx
|
||||
aZ
|
||||
ab
|
||||
@@ -1794,7 +1815,7 @@ ba
|
||||
bd
|
||||
bk
|
||||
bq
|
||||
bu
|
||||
zj
|
||||
by
|
||||
aZ
|
||||
ab
|
||||
@@ -1823,7 +1844,7 @@ ac
|
||||
ag
|
||||
ar
|
||||
ag
|
||||
ag
|
||||
aO
|
||||
ac
|
||||
ab
|
||||
ab
|
||||
@@ -1845,7 +1866,7 @@ aZ
|
||||
be
|
||||
bo
|
||||
bs
|
||||
bE
|
||||
aK
|
||||
bz
|
||||
aZ
|
||||
ab
|
||||
@@ -1896,7 +1917,7 @@ aZ
|
||||
bf
|
||||
bl
|
||||
br
|
||||
bv
|
||||
aN
|
||||
bA
|
||||
aZ
|
||||
ab
|
||||
|
||||
@@ -2729,9 +2729,7 @@
|
||||
/turf/open/floor/carpet,
|
||||
/area/ruin/space/has_grav/skelter/admin)
|
||||
"gx" = (
|
||||
/obj/machinery/door/firedoor{
|
||||
pixel_x = 0
|
||||
},
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "1-2"
|
||||
@@ -2742,9 +2740,7 @@
|
||||
/turf/open/floor/plasteel/showroomfloor,
|
||||
/area/ruin/space/has_grav/skelter/shields)
|
||||
"gy" = (
|
||||
/obj/machinery/door/firedoor{
|
||||
pixel_x = 0
|
||||
},
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/machinery/door/airlock/engineering{
|
||||
name = "Shields"
|
||||
|
||||
@@ -3170,7 +3170,9 @@
|
||||
/turf/open/lava/smooth/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"VY" = (
|
||||
/obj/structure/closet/emcloset,
|
||||
/obj/structure/closet/emcloset{
|
||||
anchored = 1
|
||||
},
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
dir = 1
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "map_files\BoxStation\BoxStation.dmm"
|
||||
#include "map_files\LambdaStation\lambda.dmm"
|
||||
|
||||
#ifdef TRAVISBUILDING
|
||||
#ifdef CIBUILDING
|
||||
#include "templates.dm"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6004,12 +6004,12 @@
|
||||
c_tag = "Security Checkpoint";
|
||||
pixel_x = 22
|
||||
},
|
||||
/obj/machinery/newscaster/security_unit{
|
||||
pixel_y = 32
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
pixel_y = 23
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/security/checkpoint)
|
||||
"aoz" = (
|
||||
@@ -32290,10 +32290,6 @@
|
||||
dir = 8;
|
||||
light_color = "#e8eaff"
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
dir = 4;
|
||||
pixel_x = -22
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hydroponics)
|
||||
"bsl" = (
|
||||
@@ -71184,6 +71180,13 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/yellow/visible,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/engine/atmos)
|
||||
"pMW" = (
|
||||
/obj/machinery/airalarm{
|
||||
dir = 1;
|
||||
pixel_y = -22
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hydroponics)
|
||||
"pZq" = (
|
||||
/obj/structure/disposalpipe/sorting/mail/flip{
|
||||
dir = 8;
|
||||
@@ -121382,7 +121385,7 @@ amV
|
||||
aqI
|
||||
aqB
|
||||
aGO
|
||||
auy
|
||||
pMW
|
||||
aqB
|
||||
aqI
|
||||
amV
|
||||
|
||||
@@ -49530,7 +49530,7 @@
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 10
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/engine/gravity_generator)
|
||||
@@ -113323,10 +113323,6 @@
|
||||
/obj/item/clothing/gloves/color/black,
|
||||
/obj/item/storage/box/evidence,
|
||||
/obj/item/taperecorder,
|
||||
/obj/machinery/airalarm{
|
||||
dir = 8;
|
||||
pixel_x = 24
|
||||
},
|
||||
/obj/effect/turf_decal/tile/neutral{
|
||||
dir = 1
|
||||
},
|
||||
|
||||
@@ -30529,9 +30529,6 @@
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/closet/bombcloset,
|
||||
/obj/machinery/airalarm{
|
||||
pixel_y = 24
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/science/mixing)
|
||||
"aXC" = (
|
||||
@@ -43701,10 +43698,6 @@
|
||||
/obj/structure/window/reinforced{
|
||||
dir = 1
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
dir = 4;
|
||||
pixel_x = -22
|
||||
},
|
||||
/mob/living/simple_animal/chicken{
|
||||
desc = "The arch-nemesis of Kentucky.";
|
||||
name = "Popeye";
|
||||
@@ -46363,9 +46356,6 @@
|
||||
"bwK" = (
|
||||
/obj/structure/flora/grass/jungle/b,
|
||||
/obj/structure/flora/ausbushes/sparsegrass,
|
||||
/obj/machinery/airalarm{
|
||||
pixel_y = 22
|
||||
},
|
||||
/turf/open/floor/grass,
|
||||
/area/chapel/main)
|
||||
"bwL" = (
|
||||
@@ -48132,16 +48122,6 @@
|
||||
},
|
||||
/turf/open/floor/plasteel/showroomfloor,
|
||||
/area/security/brig)
|
||||
"bzx" = (
|
||||
/obj/effect/turf_decal/tile/neutral,
|
||||
/obj/effect/turf_decal/tile/neutral{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/turf_decal/tile/neutral{
|
||||
dir = 4
|
||||
},
|
||||
/turf/closed/wall,
|
||||
/area/crew_quarters/locker)
|
||||
"bzy" = (
|
||||
/obj/machinery/light/small{
|
||||
dir = 8
|
||||
@@ -58156,10 +58136,6 @@
|
||||
icon_state = "plant-02";
|
||||
pixel_y = 3
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
dir = 4;
|
||||
pixel_x = -22
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Prison Wing Cells";
|
||||
dir = 4;
|
||||
@@ -61358,7 +61334,7 @@
|
||||
dir = 10
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/space)
|
||||
/area/security/warden)
|
||||
"bUs" = (
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/machinery/door/airlock/command/glass{
|
||||
@@ -67210,10 +67186,6 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-4"
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
dir = 1;
|
||||
pixel_y = -22
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/security/main)
|
||||
"cdU" = (
|
||||
@@ -71327,9 +71299,9 @@
|
||||
icon_gib = "magicarp_gib";
|
||||
icon_living = "magicarp";
|
||||
icon_state = "magicarp";
|
||||
maxHealth = 200;
|
||||
max_co2 = 5;
|
||||
max_tox = 2;
|
||||
maxHealth = 200;
|
||||
melee_damage_lower = 15;
|
||||
melee_damage_upper = 20;
|
||||
min_oxy = 5;
|
||||
@@ -83281,10 +83253,6 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/yellow/visible{
|
||||
dir = 5
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
dir = 4;
|
||||
pixel_x = -23
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Atmospherics Port Tanks";
|
||||
dir = 4;
|
||||
@@ -108992,7 +108960,7 @@ bss
|
||||
btV
|
||||
aEu
|
||||
bxW
|
||||
bzx
|
||||
bIV
|
||||
bKq
|
||||
bKq
|
||||
bKq
|
||||
|
||||
@@ -1111,10 +1111,6 @@
|
||||
/turf/open/floor/plasteel,
|
||||
/area/security/prison)
|
||||
"acx" = (
|
||||
/obj/machinery/airalarm{
|
||||
dir = 8;
|
||||
pixel_x = 24
|
||||
},
|
||||
/obj/machinery/cryopod{
|
||||
dir = 8
|
||||
},
|
||||
@@ -40497,10 +40493,9 @@
|
||||
/area/maintenance/port)
|
||||
"bBr" = (
|
||||
/obj/machinery/airalarm{
|
||||
dir = 4;
|
||||
pixel_x = -23
|
||||
dir = 1;
|
||||
pixel_y = -22
|
||||
},
|
||||
/obj/structure/displaycase/trophy,
|
||||
/turf/open/floor/wood,
|
||||
/area/library)
|
||||
"bBs" = (
|
||||
@@ -45866,10 +45861,6 @@
|
||||
/area/library)
|
||||
"bML" = (
|
||||
/obj/machinery/light/small,
|
||||
/obj/machinery/airalarm{
|
||||
dir = 1;
|
||||
pixel_y = -22
|
||||
},
|
||||
/turf/open/floor/wood,
|
||||
/area/library)
|
||||
"bMM" = (
|
||||
@@ -59581,6 +59572,10 @@
|
||||
/obj/structure/chair{
|
||||
dir = 1
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
dir = 4;
|
||||
pixel_x = -23
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/medical/surgery)
|
||||
"coz" = (
|
||||
@@ -60135,9 +60130,6 @@
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/disposalpipe/junction/flip{
|
||||
dir = 8
|
||||
},
|
||||
@@ -60145,6 +60137,9 @@
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/research)
|
||||
"cpx" = (
|
||||
@@ -60947,9 +60942,6 @@
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/effect/turf_decal/tile/purple,
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
@@ -60958,6 +60950,10 @@
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/research)
|
||||
"cqP" = (
|
||||
@@ -61465,7 +61461,6 @@
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/machinery/door/airlock/research{
|
||||
@@ -61477,6 +61472,7 @@
|
||||
name = "biohazard containment shutters"
|
||||
},
|
||||
/obj/effect/turf_decal/delivery,
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/storage)
|
||||
"crU" = (
|
||||
@@ -61595,10 +61591,6 @@
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/medical/surgery)
|
||||
"csl" = (
|
||||
/obj/machinery/airalarm{
|
||||
dir = 1;
|
||||
pixel_y = -22
|
||||
},
|
||||
/obj/structure/window/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
@@ -62156,11 +62148,11 @@
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 9
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/storage)
|
||||
"cth" = (
|
||||
@@ -62531,24 +62523,21 @@
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "1-4"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 5
|
||||
},
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 5
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/on{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/storage)
|
||||
"ctY" = (
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 10
|
||||
},
|
||||
/obj/structure/chair/stool,
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 10
|
||||
@@ -62568,10 +62557,6 @@
|
||||
/area/science/storage)
|
||||
"cua" = (
|
||||
/obj/machinery/portable_atmospherics/canister/oxygen,
|
||||
/obj/machinery/airalarm{
|
||||
dir = 8;
|
||||
pixel_x = 24
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/storage)
|
||||
@@ -63127,7 +63112,6 @@
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/storage)
|
||||
"cuU" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
@@ -63668,12 +63652,12 @@
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/storage)
|
||||
"cvW" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/effect/landmark/blobstart,
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/on,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/storage)
|
||||
"cvX" = (
|
||||
@@ -68931,13 +68915,13 @@
|
||||
pixel_x = -25;
|
||||
pixel_y = -5
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
dir = 1;
|
||||
pixel_y = -22
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/corner{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/airalarm/unlocked{
|
||||
dir = 1;
|
||||
pixel_y = -22
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/mixing)
|
||||
"cGm" = (
|
||||
@@ -102705,7 +102689,7 @@ bue
|
||||
bwa
|
||||
bxU
|
||||
bzD
|
||||
bBr
|
||||
dmD
|
||||
bSx
|
||||
bEw
|
||||
bzE
|
||||
@@ -103740,7 +103724,7 @@ bGs
|
||||
bHS
|
||||
bzE
|
||||
bLk
|
||||
bzE
|
||||
bBr
|
||||
bue
|
||||
bPS
|
||||
bPR
|
||||
@@ -117641,7 +117625,7 @@ cmQ
|
||||
cok
|
||||
cpy
|
||||
cqQ
|
||||
cgq
|
||||
crR
|
||||
cti
|
||||
ctZ
|
||||
cuV
|
||||
|
||||
@@ -4924,11 +4924,11 @@
|
||||
/obj/effect/turf_decal/stripes/end{
|
||||
dir = 1
|
||||
},
|
||||
/obj/item/gun/energy/e_gun/hos,
|
||||
/obj/effect/turf_decal/tile/neutral,
|
||||
/obj/effect/turf_decal/tile/neutral{
|
||||
dir = 4
|
||||
},
|
||||
/obj/item/gun/energy/e_gun/hos,
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/crew_quarters/heads/captain/private)
|
||||
"ahI" = (
|
||||
@@ -40544,6 +40544,9 @@
|
||||
name = "Starboard Quater Maintenance APC";
|
||||
pixel_y = -26
|
||||
},
|
||||
/obj/structure/cable/white{
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/turf/open/floor/plating{
|
||||
icon_state = "panelscorched"
|
||||
},
|
||||
|
||||
@@ -2337,9 +2337,12 @@
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/security/prison)
|
||||
"afJ" = (
|
||||
/obj/effect/landmark/carpspawn,
|
||||
/turf/open/space/basic,
|
||||
/area/space/nearstation)
|
||||
/obj/effect/turf_decal/tile/neutral,
|
||||
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hallway/primary/central)
|
||||
"afK" = (
|
||||
/obj/machinery/atmospherics/components/unary/tank/air{
|
||||
dir = 1
|
||||
@@ -16527,6 +16530,9 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
pixel_y = 22
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/quartermaster/warehouse)
|
||||
"aMr" = (
|
||||
@@ -20027,9 +20033,7 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,
|
||||
/turf/open/floor/plating,
|
||||
/area/maintenance/department/crew_quarters/bar)
|
||||
"aUQ" = (
|
||||
@@ -20044,6 +20048,9 @@
|
||||
/obj/effect/turf_decal/tile/neutral{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 10
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/hydroponics)
|
||||
"aUR" = (
|
||||
@@ -20485,8 +20492,16 @@
|
||||
/turf/closed/wall,
|
||||
/area/janitor)
|
||||
"aVT" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/turf/closed/wall,
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/machinery/door/poddoor/shutters{
|
||||
id = "jangarage";
|
||||
name = "Custodial Closet Shutters"
|
||||
},
|
||||
/obj/effect/turf_decal/delivery,
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/janitor)
|
||||
"aVU" = (
|
||||
/obj/machinery/door/window/eastright{
|
||||
@@ -20510,6 +20525,7 @@
|
||||
/obj/effect/turf_decal/tile/neutral{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/janitor)
|
||||
"aVV" = (
|
||||
@@ -20892,9 +20908,6 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Custodial Quarters"
|
||||
},
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
|
||||
dir = 1
|
||||
},
|
||||
/obj/machinery/light/small{
|
||||
dir = 1
|
||||
},
|
||||
@@ -20915,6 +20928,9 @@
|
||||
/obj/effect/turf_decal/tile/neutral{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/janitor)
|
||||
"aWO" = (
|
||||
@@ -20934,6 +20950,9 @@
|
||||
/obj/effect/turf_decal/tile/neutral{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 9
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/janitor)
|
||||
"aWP" = (
|
||||
@@ -23004,9 +23023,6 @@
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hallway/primary/central)
|
||||
"baW" = (
|
||||
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/button/door{
|
||||
id = "jangarage";
|
||||
name = "Custodial Closet Shutters Control";
|
||||
@@ -23014,14 +23030,12 @@
|
||||
req_access_txt = "26"
|
||||
},
|
||||
/obj/effect/turf_decal/tile/neutral,
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hallway/primary/central)
|
||||
"baX" = (
|
||||
/obj/vehicle/ridden/janicart,
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/light{
|
||||
dir = 8
|
||||
},
|
||||
@@ -23034,6 +23048,9 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "2-4"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 6
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/janitor)
|
||||
"baY" = (
|
||||
@@ -23398,6 +23415,9 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 9
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/janitor)
|
||||
"bbY" = (
|
||||
@@ -31173,17 +31193,26 @@
|
||||
"bup" = (
|
||||
/obj/machinery/rnd/destructive_analyzer,
|
||||
/obj/effect/turf_decal/delivery,
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/lab)
|
||||
"buq" = (
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/effect/turf_decal/bot,
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/lab)
|
||||
"bur" = (
|
||||
/obj/effect/turf_decal/delivery,
|
||||
/obj/machinery/rnd/production/protolathe/department/science,
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/lab)
|
||||
"bus" = (
|
||||
@@ -31202,6 +31231,9 @@
|
||||
/obj/machinery/light{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 10
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/lab)
|
||||
"but" = (
|
||||
@@ -31664,6 +31696,7 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/lab)
|
||||
"bvA" = (
|
||||
@@ -32372,6 +32405,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/lab)
|
||||
"bxh" = (
|
||||
@@ -33056,12 +33090,6 @@
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hallway/primary/aft)
|
||||
"byD" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 6
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "2-4"
|
||||
},
|
||||
/obj/machinery/door/airlock/research{
|
||||
name = "R&D Lab";
|
||||
req_one_access_txt = "7;29;30"
|
||||
@@ -33070,6 +33098,12 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 6
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/lab)
|
||||
"byE" = (
|
||||
@@ -33091,7 +33125,6 @@
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/lab)
|
||||
"byG" = (
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/on,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
@@ -33919,10 +33952,6 @@
|
||||
/area/hallway/primary/aft)
|
||||
"bAm" = (
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/hallway/primary/aft)
|
||||
"bAo" = (
|
||||
@@ -33952,7 +33981,6 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-4"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
dir = 1
|
||||
},
|
||||
@@ -34404,17 +34432,14 @@
|
||||
name = "RD Office APC";
|
||||
pixel_x = -25
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/crew_quarters/heads/hor)
|
||||
@@ -34425,8 +34450,8 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 5
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
|
||||
dir = 4
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 6
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/crew_quarters/heads/hor)
|
||||
@@ -34434,6 +34459,9 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/crew_quarters/heads/hor)
|
||||
"bBt" = (
|
||||
@@ -34441,6 +34469,9 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/crew_quarters/heads/hor)
|
||||
"bBu" = (
|
||||
@@ -34478,6 +34509,9 @@
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 9
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/crew_quarters/heads/hor)
|
||||
"bBw" = (
|
||||
@@ -35240,6 +35274,7 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/turf/open/floor/plating,
|
||||
/area/crew_quarters/heads/hor)
|
||||
"bCK" = (
|
||||
@@ -44248,9 +44283,11 @@
|
||||
/turf/open/floor/engine/co2,
|
||||
/area/engine/atmos)
|
||||
"bWh" = (
|
||||
/obj/effect/turf_decal/sand,
|
||||
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/chapel/office)
|
||||
/area/hallway/primary/aft)
|
||||
"bWi" = (
|
||||
/obj/structure/flora/ausbushes/leafybush,
|
||||
/obj/structure/flora/ausbushes/reedbush,
|
||||
@@ -47597,6 +47634,9 @@
|
||||
pixel_x = -25;
|
||||
specialfunctions = 4
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
pixel_y = 22
|
||||
},
|
||||
/turf/open/floor/plasteel/grimy,
|
||||
/area/chapel/main/monastery)
|
||||
"cgM" = (
|
||||
@@ -47945,6 +47985,9 @@
|
||||
pixel_x = -25;
|
||||
specialfunctions = 4
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
pixel_y = 22
|
||||
},
|
||||
/turf/open/floor/plasteel/grimy,
|
||||
/area/chapel/main/monastery)
|
||||
"cip" = (
|
||||
@@ -51432,6 +51475,10 @@
|
||||
name = "Coffin Storage";
|
||||
req_one_access_txt = "22"
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
dir = 8;
|
||||
pixel_x = 24
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/chapel/main/monastery)
|
||||
"cvu" = (
|
||||
@@ -52824,6 +52871,9 @@
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/science/lab)
|
||||
"cCt" = (
|
||||
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/lab)
|
||||
"cCB" = (
|
||||
@@ -53058,6 +53108,9 @@
|
||||
freq = 1400;
|
||||
location = "Research Division"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/science/lab)
|
||||
"cXW" = (
|
||||
@@ -53151,10 +53204,6 @@
|
||||
/area/maintenance/department/security/brig)
|
||||
"dhz" = (
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/structure/chair{
|
||||
dir = 8;
|
||||
name = "Defense"
|
||||
@@ -53163,9 +53212,6 @@
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hallway/primary/aft)
|
||||
"dir" = (
|
||||
@@ -53960,11 +54006,11 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
|
||||
dir = 1
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-8"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hallway/primary/aft)
|
||||
@@ -55488,6 +55534,12 @@
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 6
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "2-4"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hallway/primary/aft)
|
||||
"ioj" = (
|
||||
@@ -55591,6 +55643,9 @@
|
||||
/obj/effect/turf_decal/tile/blue{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hallway/primary/aft)
|
||||
"iyg" = (
|
||||
@@ -56345,9 +56400,13 @@
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/mixing)
|
||||
"koz" = (
|
||||
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
|
||||
/obj/effect/turf_decal/tile/purple,
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hallway/primary/aft)
|
||||
"kpK" = (
|
||||
@@ -56634,10 +56693,14 @@
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/science/xenobiology)
|
||||
"kSb" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/structure/grille,
|
||||
/turf/open/space/basic,
|
||||
/area/space)
|
||||
/obj/structure/chair/office/light{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/on{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/lab)
|
||||
"kSF" = (
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-4"
|
||||
@@ -56711,6 +56774,10 @@
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hallway/primary/aft)
|
||||
"lcU" = (
|
||||
@@ -57121,6 +57188,7 @@
|
||||
/obj/effect/turf_decal/tile/purple{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/lab)
|
||||
"meF" = (
|
||||
@@ -57128,8 +57196,9 @@
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/engine/supermatter)
|
||||
"mfC" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hallway/primary/aft)
|
||||
@@ -59343,6 +59412,7 @@
|
||||
/area/hallway/secondary/exit/departure_lounge)
|
||||
"qVk" = (
|
||||
/obj/machinery/door/poddoor/incinerator_atmos_aux,
|
||||
/obj/structure/lattice/catwalk,
|
||||
/turf/open/space/basic,
|
||||
/area/maintenance/disposal/incinerator)
|
||||
"qVP" = (
|
||||
@@ -59377,6 +59447,10 @@
|
||||
/obj/effect/turf_decal/tile/yellow{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/airalarm{
|
||||
dir = 8;
|
||||
pixel_x = 23
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/construction/mining/aux_base)
|
||||
"qXq" = (
|
||||
@@ -60493,6 +60567,9 @@
|
||||
id = "research_shutters_2";
|
||||
name = "research shutters"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/lab)
|
||||
"tLP" = (
|
||||
@@ -60815,12 +60892,6 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 9
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 9
|
||||
},
|
||||
/obj/structure/chair{
|
||||
dir = 8;
|
||||
name = "Defense"
|
||||
@@ -61500,12 +61571,6 @@
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/xenobiology)
|
||||
"wfG" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/crew_quarters/heads/hor)
|
||||
"wfO" = (
|
||||
/mob/living/simple_animal/hostile/retaliate/poison/snake,
|
||||
/turf/open/floor/plating,
|
||||
@@ -76969,7 +77034,7 @@ aaa
|
||||
bOv
|
||||
bNs
|
||||
bNs
|
||||
bWh
|
||||
bQg
|
||||
bQg
|
||||
bQg
|
||||
bQg
|
||||
@@ -84176,7 +84241,7 @@ bIZ
|
||||
cbb
|
||||
bDi
|
||||
ccO
|
||||
bIZ
|
||||
bva
|
||||
cjm
|
||||
cjm
|
||||
xgh
|
||||
@@ -84436,8 +84501,8 @@ bva
|
||||
bva
|
||||
aht
|
||||
aht
|
||||
kSb
|
||||
kSb
|
||||
fon
|
||||
fon
|
||||
aht
|
||||
aht
|
||||
mau
|
||||
@@ -86691,7 +86756,7 @@ aXL
|
||||
aYL
|
||||
aZN
|
||||
baW
|
||||
aKI
|
||||
afJ
|
||||
aKI
|
||||
beb
|
||||
aKI
|
||||
@@ -86947,8 +87012,8 @@ aVS
|
||||
aXM
|
||||
aVS
|
||||
aVS
|
||||
aXM
|
||||
bbW
|
||||
aVS
|
||||
aVT
|
||||
bbW
|
||||
aVS
|
||||
aVS
|
||||
@@ -87149,7 +87214,7 @@ aaa
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
afJ
|
||||
cFB
|
||||
aby
|
||||
aaa
|
||||
agQ
|
||||
@@ -87456,7 +87521,7 @@ aRJ
|
||||
aSz
|
||||
aSz
|
||||
aUP
|
||||
aVT
|
||||
aVS
|
||||
aWN
|
||||
aXO
|
||||
aYM
|
||||
@@ -89468,7 +89533,7 @@ aaa
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
afJ
|
||||
cFB
|
||||
aaa
|
||||
aaa
|
||||
abI
|
||||
@@ -94932,12 +94997,12 @@ jcT
|
||||
xje
|
||||
tTl
|
||||
tTl
|
||||
tTl
|
||||
bWh
|
||||
gkS
|
||||
tTl
|
||||
tTl
|
||||
tTl
|
||||
koz
|
||||
tTl
|
||||
dgg
|
||||
phJ
|
||||
phJ
|
||||
@@ -95189,7 +95254,7 @@ bjm
|
||||
mhn
|
||||
cqi
|
||||
cqi
|
||||
cqi
|
||||
koz
|
||||
cqi
|
||||
cqi
|
||||
imE
|
||||
@@ -95708,7 +95773,7 @@ duF
|
||||
bxa
|
||||
byE
|
||||
bBp
|
||||
wfG
|
||||
bBp
|
||||
bBp
|
||||
bBp
|
||||
bBp
|
||||
@@ -95961,7 +96026,7 @@ cCl
|
||||
brq
|
||||
byF
|
||||
cCt
|
||||
byF
|
||||
kSb
|
||||
bxc
|
||||
nIU
|
||||
bAo
|
||||
|
||||
15
appveyor.yml
15
appveyor.yml
@@ -1,15 +0,0 @@
|
||||
version: '{build}'
|
||||
skip_branch_with_pr: true
|
||||
shallow_clone: true
|
||||
branches:
|
||||
except:
|
||||
- ___TGS3TempBranch
|
||||
- ___TGSTempBranch
|
||||
cache:
|
||||
- C:\byond\ -> dependencies.sh
|
||||
build_script:
|
||||
- ps: tools/appveyor/build.ps1
|
||||
- ps: "$deployPath = $env:APPVEYOR_BUILD_FOLDER + '/deploy'; bash tools/deploy.sh $deployPath"
|
||||
- ps: "[System.IO.Compression.ZipFile]::CreateFromDirectory($env:APPVEYOR_BUILD_FOLDER + '/deploy', $env:APPVEYOR_BUILD_FOLDER + '/deploy.zip')"
|
||||
artifacts:
|
||||
- path: deploy.zip
|
||||
@@ -22,49 +22,45 @@
|
||||
#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;Processor.currentrun -= Datum
|
||||
|
||||
//SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier)
|
||||
//! SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier)
|
||||
|
||||
//subsystem does not initialize.
|
||||
#define SS_NO_INIT (1<<0)
|
||||
/// subsystem does not initialize.
|
||||
#define SS_NO_INIT 1
|
||||
|
||||
//subsystem does not fire.
|
||||
// (like can_fire = 0, but keeps it from getting added to the processing subsystems list)
|
||||
// (Requires a MC restart to change)
|
||||
#define SS_NO_FIRE (1<<1)
|
||||
/** subsystem does not fire. */
|
||||
/// (like can_fire = 0, but keeps it from getting added to the processing subsystems list)
|
||||
/// (Requires a MC restart to change)
|
||||
#define SS_NO_FIRE 2
|
||||
|
||||
//subsystem only runs on spare cpu (after all non-background subsystems have ran that tick)
|
||||
// SS_BACKGROUND has its own priority bracket
|
||||
#define SS_BACKGROUND (1<<2)
|
||||
/** Subsystem only runs on spare cpu (after all non-background subsystems have ran that tick) */
|
||||
/// SS_BACKGROUND has its own priority bracket, this overrides SS_TICKER's priority bump
|
||||
#define SS_BACKGROUND 4
|
||||
|
||||
//subsystem does not tick check, and should not run unless there is enough time (or its running behind (unless background))
|
||||
#define SS_NO_TICK_CHECK (1<<3)
|
||||
/// subsystem does not tick check, and should not run unless there is enough time (or its running behind (unless background))
|
||||
#define SS_NO_TICK_CHECK 8
|
||||
|
||||
//Treat wait as a tick count, not DS, run every wait ticks.
|
||||
// (also forces it to run first in the tick, above even SS_NO_TICK_CHECK subsystems)
|
||||
// (implies all runlevels because of how it works)
|
||||
// (overrides SS_BACKGROUND)
|
||||
// This is designed for basically anything that works as a mini-mc (like SStimer)
|
||||
#define SS_TICKER (1<<4)
|
||||
/** Treat wait as a tick count, not DS, run every wait ticks. */
|
||||
/// (also forces it to run first in the tick (unless SS_BACKGROUND))
|
||||
/// (implies all runlevels because of how it works)
|
||||
/// This is designed for basically anything that works as a mini-mc (like SStimer)
|
||||
#define SS_TICKER 16
|
||||
|
||||
//keep the subsystem's timing on point by firing early if it fired late last fire because of lag
|
||||
// ie: if a 20ds subsystem fires say 5 ds late due to lag or what not, its next fire would be in 15ds, not 20ds.
|
||||
#define SS_KEEP_TIMING (1<<5)
|
||||
/** keep the subsystem's timing on point by firing early if it fired late last fire because of lag */
|
||||
/// ie: if a 20ds subsystem fires say 5 ds late due to lag or what not, its next fire would be in 15ds, not 20ds.
|
||||
#define SS_KEEP_TIMING 32
|
||||
|
||||
//Calculate its next fire after its fired.
|
||||
// (IE: if a 5ds wait SS takes 2ds to run, its next fire should be 5ds away, not 3ds like it normally would be)
|
||||
// This flag overrides SS_KEEP_TIMING
|
||||
#define SS_POST_FIRE_TIMING (1<<6)
|
||||
/** Calculate its next fire after its fired. */
|
||||
/// (IE: if a 5ds wait SS takes 2ds to run, its next fire should be 5ds away, not 3ds like it normally would be)
|
||||
/// This flag overrides SS_KEEP_TIMING
|
||||
#define SS_POST_FIRE_TIMING 64
|
||||
|
||||
/// Show in stat() by default even if SS_NO_FIRE
|
||||
#define SS_ALWAYS_SHOW_STAT (1<<7)
|
||||
|
||||
//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
|
||||
//! SUBSYSTEM STATES
|
||||
#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
|
||||
|
||||
#define SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/##X);\
|
||||
/datum/controller/subsystem/##X/New(){\
|
||||
|
||||
@@ -1 +1,38 @@
|
||||
#define EXTOOLS (world.system_type == MS_WINDOWS ? "byond-extools.dll" : "libbyond-extools.so")
|
||||
// _extools_api.dm - DM API for extools extension library
|
||||
// (blatently stolen from rust_g)
|
||||
//
|
||||
// To configure, create a `extools.config.dm` and set what you care about from
|
||||
// the following options:
|
||||
//
|
||||
// #define EXTOOLS "path/to/extools"
|
||||
// Override the .dll/.so detection logic with a fixed path or with detection
|
||||
// logic of your own.
|
||||
|
||||
#ifndef EXTOOLS
|
||||
// Default automatic EXTOOLS detection.
|
||||
// On Windows, looks in the standard places for `byond-extools.dll`.
|
||||
// On Linux, looks in the standard places for`libbyond-extools.so`.
|
||||
|
||||
/* This comment bypasses grep checks */ /var/__extools
|
||||
|
||||
/proc/__detect_extools()
|
||||
if (world.system_type == UNIX)
|
||||
if (fexists("./libbyond-extools.so"))
|
||||
// No need for LD_LIBRARY_PATH badness.
|
||||
return __extools = "./libbyond-extools.so"
|
||||
else
|
||||
// It's not in the current directory, so try others
|
||||
return __extools = "libbyond-extools.so"
|
||||
else
|
||||
return __extools = "byond-extools.dll"
|
||||
|
||||
#define EXTOOLS (__extools || __detect_extools())
|
||||
#endif
|
||||
|
||||
#ifndef UNIT_TESTS // use default logging as extools is broken on travis
|
||||
#define EXTOOLS_LOGGING // rust_g is used as a fallback if this is undefined
|
||||
#endif
|
||||
|
||||
/proc/extools_log_write()
|
||||
|
||||
/proc/extools_finalize_logging()
|
||||
|
||||
@@ -163,5 +163,19 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
else if(!HAS_TRAIT(x, TRAIT_KEEP_TOGETHER))\
|
||||
x.appearance_flags &= ~KEEP_TOGETHER
|
||||
|
||||
//dir macros
|
||||
///Returns true if the dir is diagonal, false otherwise
|
||||
#define ISDIAGONALDIR(d) (d&(d-1))
|
||||
///True if the dir is north or south, false therwise
|
||||
#define NSCOMPONENT(d) (d&(NORTH|SOUTH))
|
||||
///True if the dir is east/west, false otherwise
|
||||
#define EWCOMPONENT(d) (d&(EAST|WEST))
|
||||
///Flips the dir for north/south directions
|
||||
#define NSDIRFLIP(d) (d^(NORTH|SOUTH))
|
||||
///Flips the dir for east/west directions
|
||||
#define EWDIRFLIP(d) (d^(EAST|WEST))
|
||||
///Turns the dir by 180 degrees
|
||||
#define DIRFLIP(d) turn(d, 180)
|
||||
|
||||
/// 33554431 (2^24 - 1) is the maximum value our bitflags can reach.
|
||||
#define MAX_BITFLAG_DIGITS 8
|
||||
|
||||
@@ -91,3 +91,6 @@
|
||||
|
||||
#define SPAM_TRIGGER_WARNING 5 //Number of identical messages required before the spam-prevention will warn you to stfu
|
||||
#define SPAM_TRIGGER_AUTOMUTE 10 //Number of identical messages required before the spam-prevention will automute you
|
||||
|
||||
#define STICKYBAN_DB_CACHE_TIME 10 SECONDS
|
||||
#define STICKYBAN_ROGUE_CHECK_TIME 5
|
||||
|
||||
@@ -69,6 +69,9 @@
|
||||
#define LINGBLOOD_EXPLOSION_THRESHOLD (LINGBLOOD_DETECTION_THRESHOLD * LINGBLOOD_EXPLOSION_MULT) //Hey, important to note here: the explosion threshold is explicitly more than, rather than more than or equal to. This stops a single loud ability from triggering the explosion threshold.
|
||||
|
||||
///Heretics --
|
||||
GLOBAL_LIST_EMPTY(living_heart_cache) //A list of all living hearts in existance, for us to iterate through.
|
||||
|
||||
|
||||
#define IS_HERETIC(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic))
|
||||
#define IS_HERETIC_MONSTER(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic_monster))
|
||||
|
||||
|
||||
@@ -6,9 +6,16 @@
|
||||
|
||||
#define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) )
|
||||
|
||||
/// Signifies that this proc is used to handle signals.
|
||||
/// Every proc you pass to RegisterSignal must have this.
|
||||
#define SIGNAL_HANDLER SHOULD_NOT_SLEEP(TRUE)
|
||||
|
||||
/// Signifies that this proc is used to handle signals, but also sleeps.
|
||||
/// Do not use this for new work.
|
||||
#define SIGNAL_HANDLER_DOES_SLEEP
|
||||
|
||||
/// A wrapper for _AddElement that allows us to pretend we're using normal named arguments
|
||||
#define AddElement(arguments...) _AddElement(list(##arguments))
|
||||
|
||||
/// A wrapper for _RemoveElement that allows us to pretend we're using normal named arguments
|
||||
#define RemoveElement(arguments...) _RemoveElement(list(##arguments))
|
||||
|
||||
|
||||
@@ -541,6 +541,9 @@
|
||||
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob)
|
||||
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob)
|
||||
|
||||
// /datum/element/ventcrawling signals
|
||||
#define COMSIG_HANDLE_VENTCRAWL "handle_ventcrawl" //when atom with ventcrawling element attempts to ventcrawl
|
||||
#define COMSIG_CHECK_VENTCRAWL "check_ventcrawl" //to check an atom's ventcrawling element tier (if applicable)
|
||||
// twitch plays
|
||||
/// Returns direction: (wipe_votes)
|
||||
#define COMSIG_TWITCH_PLAYS_MOVEMENT_DATA "twitch_plays_movement_data"
|
||||
|
||||
@@ -72,9 +72,11 @@
|
||||
#define LOADOUT_LIMBS list(LOADOUT_LIMB_NORMAL,LOADOUT_LIMB_PROSTHETIC,LOADOUT_LIMB_AMPUTATED) //you can amputate your legs/arms though
|
||||
|
||||
//loadout saving/loading specific defines
|
||||
#define MAXIMUM_LOADOUT_SAVES 5
|
||||
#define LOADOUT_ITEM "loadout_item"
|
||||
#define LOADOUT_COLOR "loadout_color"
|
||||
#define MAXIMUM_LOADOUT_SAVES 5
|
||||
#define LOADOUT_ITEM "loadout_item"
|
||||
#define LOADOUT_COLOR "loadout_color"
|
||||
#define LOADOUT_CUSTOM_NAME "loadout_custom_name"
|
||||
#define LOADOUT_CUSTOM_DESCRIPTION "loadout_custom_description"
|
||||
|
||||
//loadout item flags
|
||||
#define LOADOUT_CAN_NAME (1<<0) //renaming items
|
||||
|
||||
26
code/__DEFINES/movement.dm
Normal file
26
code/__DEFINES/movement.dm
Normal file
@@ -0,0 +1,26 @@
|
||||
/// The minimum for glide_size to be clamped to.
|
||||
#define MIN_GLIDE_SIZE 1
|
||||
/// The maximum for glide_size to be clamped to.
|
||||
/// This shouldn't be higher than the icon size, and generally you shouldn't be changing this, but it's here just in case.
|
||||
#define MAX_GLIDE_SIZE 32
|
||||
|
||||
/// Compensating for time dialation
|
||||
GLOBAL_VAR_INIT(glide_size_multiplier, 1.0)
|
||||
|
||||
///Broken down, here's what this does:
|
||||
/// divides the world icon_size (32) by delay divided by ticklag to get the number of pixels something should be moving each tick.
|
||||
/// The division result is given a min value of 1 to prevent obscenely slow glide sizes from being set
|
||||
/// Then that's multiplied by the global glide size multiplier. 1.25 by default feels pretty close to spot on. This is just to try to get byond to behave.
|
||||
/// The whole result is then clamped to within the range above.
|
||||
/// Not very readable but it works
|
||||
#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((32 / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE))
|
||||
|
||||
/// Enables smooth movement
|
||||
// #define SMOOTH_MOVEMENT
|
||||
|
||||
/// Set appearance flags in vars
|
||||
#ifdef SMOOTH_MOVEMENT
|
||||
#define SET_APPEARANCE_FLAGS(_flags) appearance_flags = (_flags | LONG_GLIDE)
|
||||
#else
|
||||
#define SET_APPEARANCE_FLAGS(_flags) appearance_flags = _flags
|
||||
#endif
|
||||
@@ -1,19 +1,76 @@
|
||||
// rust_g.dm - DM API for rust_g extension library
|
||||
#define RUST_G "rust_g"
|
||||
//
|
||||
// To configure, create a `rust_g.config.dm` and set what you care about from
|
||||
// the following options:
|
||||
//
|
||||
// #define RUST_G "path/to/rust_g"
|
||||
// Override the .dll/.so detection logic with a fixed path or with detection
|
||||
// logic of your own.
|
||||
//
|
||||
// #define RUSTG_OVERRIDE_BUILTINS
|
||||
// Enable replacement rust-g functions for certain builtins. Off by default.
|
||||
|
||||
#define RUSTG_JOB_NO_RESULTS_YET "NO RESULTS YET"
|
||||
#define RUSTG_JOB_NO_SUCH_JOB "NO SUCH JOB"
|
||||
#define RUSTG_JOB_ERROR "JOB PANICKED"
|
||||
#ifndef RUST_G
|
||||
// Default automatic RUST_G detection.
|
||||
// On Windows, looks in the standard places for `rust_g.dll`.
|
||||
// On Linux, looks in `.`, `$LD_LIBRARY_PATH`, and `~/.byond/bin` for either of
|
||||
// `librust_g.so` (preferred) or `rust_g` (old).
|
||||
|
||||
/* This comment bypasses grep checks */ /var/__rust_g
|
||||
|
||||
/proc/__detect_rust_g()
|
||||
if (world.system_type == UNIX)
|
||||
if (fexists("./librust_g.so"))
|
||||
// No need for LD_LIBRARY_PATH badness.
|
||||
return __rust_g = "./librust_g.so"
|
||||
else if (fexists("./rust_g"))
|
||||
// Old dumb filename.
|
||||
return __rust_g = "./rust_g"
|
||||
else if (fexists("[world.GetConfig("env", "HOME")]/.byond/bin/rust_g"))
|
||||
// Old dumb filename in `~/.byond/bin`.
|
||||
return __rust_g = "rust_g"
|
||||
else
|
||||
// It's not in the current directory, so try others
|
||||
return __rust_g = "librust_g.so"
|
||||
else
|
||||
return __rust_g = "rust_g"
|
||||
|
||||
#define RUST_G (__rust_g || __detect_rust_g())
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This proc generates a cellular automata noise grid which can be used in procedural generation methods.
|
||||
*
|
||||
* Returns a single string that goes row by row, with values of 1 representing an alive cell, and a value of 0 representing a dead cell.
|
||||
*
|
||||
* Arguments:
|
||||
* * percentage: The chance of a turf starting closed
|
||||
* * smoothing_iterations: The amount of iterations the cellular automata simulates before returning the results
|
||||
* * birth_limit: If the number of neighboring cells is higher than this amount, a cell is born
|
||||
* * death_limit: If the number of neighboring cells is lower than this amount, a cell dies
|
||||
* * width: The width of the grid.
|
||||
* * height: The height of the grid.
|
||||
*/
|
||||
#define rustg_cnoise_generate(percentage, smoothing_iterations, birth_limit, death_limit, width, height) \
|
||||
call(RUST_G, "cnoise_generate")(percentage, smoothing_iterations, birth_limit, death_limit, width, height)
|
||||
|
||||
#define rustg_dmi_strip_metadata(fname) call(RUST_G, "dmi_strip_metadata")(fname)
|
||||
#define rustg_dmi_create_png(path, width, height, data) call(RUST_G, "dmi_create_png")(path, width, height, data)
|
||||
#define rustg_dmi_resize_png(path, width, height, resizetype) call(RUST_G, "dmi_resize_png")(path, width, height, resizetype)
|
||||
|
||||
#define rustg_file_read(fname) call(RUST_G, "file_read")(fname)
|
||||
#define rustg_file_exists(fname) call(RUST_G, "file_exists")(fname)
|
||||
#define rustg_file_write(text, fname) call(RUST_G, "file_write")(text, fname)
|
||||
#define rustg_file_append(text, fname) call(RUST_G, "file_append")(text, fname)
|
||||
|
||||
#ifdef RUSTG_OVERRIDE_BUILTINS
|
||||
#define file2text(fname) rustg_file_read("[fname]")
|
||||
#define text2file(text, fname) rustg_file_append(text, "[fname]")
|
||||
#endif
|
||||
|
||||
#define rustg_git_revparse(rev) call(RUST_G, "rg_git_revparse")(rev)
|
||||
#define rustg_git_commit_date(rev) call(RUST_G, "rg_git_commit_date")(rev)
|
||||
|
||||
#define rustg_log_write(fname, text, format) call(RUST_G, "log_write")(fname, text, format)
|
||||
/proc/rustg_log_close_all() return call(RUST_G, "log_close_all")()
|
||||
|
||||
#define RUSTG_HTTP_METHOD_GET "get"
|
||||
#define RUSTG_HTTP_METHOD_PUT "put"
|
||||
#define RUSTG_HTTP_METHOD_DELETE "delete"
|
||||
@@ -23,3 +80,22 @@
|
||||
#define rustg_http_request_blocking(method, url, body, headers) call(RUST_G, "http_request_blocking")(method, url, body, headers)
|
||||
#define rustg_http_request_async(method, url, body, headers) call(RUST_G, "http_request_async")(method, url, body, headers)
|
||||
#define rustg_http_check_request(req_id) call(RUST_G, "http_check_request")(req_id)
|
||||
|
||||
#define RUSTG_JOB_NO_RESULTS_YET "NO RESULTS YET"
|
||||
#define RUSTG_JOB_NO_SUCH_JOB "NO SUCH JOB"
|
||||
#define RUSTG_JOB_ERROR "JOB PANICKED"
|
||||
|
||||
#define rustg_json_is_valid(text) (call(RUST_G, "json_is_valid")(text) == "true")
|
||||
|
||||
#define rustg_log_write(fname, text, format) call(RUST_G, "log_write")(fname, text, format)
|
||||
/proc/rustg_log_close_all() return call(RUST_G, "log_close_all")()
|
||||
|
||||
#define rustg_noise_get_at_coordinates(seed, x, y) call(RUST_G, "noise_get_at_coordinates")(seed, x, y)
|
||||
|
||||
#define rustg_sql_connect_pool(options) call(RUST_G, "sql_connect_pool")(options)
|
||||
#define rustg_sql_query_async(handle, query, params) call(RUST_G, "sql_query_async")(handle, query, params)
|
||||
#define rustg_sql_query_blocking(handle, query, params) call(RUST_G, "sql_query_blocking")(handle, query, params)
|
||||
#define rustg_sql_connected(handle) call(RUST_G, "sql_connected")(handle)
|
||||
#define rustg_sql_disconnect_pool(handle) call(RUST_G, "sql_disconnect_pool")(handle)
|
||||
#define rustg_sql_check_query(job_id) call(RUST_G, "sql_check_query")("[job_id]")
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#define CHANNEL_ADMIN 1023
|
||||
#define CHANNEL_VOX 1022
|
||||
#define CHANNEL_JUKEBOX 1021
|
||||
|
||||
#define CHANNEL_JUKEBOX_START 1016 //The gap between this and CHANNEL_JUKEBOX determines the amount of free jukebox channels. This currently allows 6 jukebox channels to exist.
|
||||
#define CHANNEL_JUSTICAR_ARK 1015
|
||||
#define CHANNEL_HEARTBEAT 1014 //sound channel for heartbeats
|
||||
@@ -15,6 +16,17 @@
|
||||
#define CHANNEL_DIGEST 1009
|
||||
#define CHANNEL_PREYLOOP 1008
|
||||
|
||||
///Default range of a sound.
|
||||
#define SOUND_RANGE 17
|
||||
///default extra range for sounds considered to be quieter
|
||||
#define SHORT_RANGE_SOUND_EXTRARANGE -9
|
||||
///The range deducted from sound range for things that are considered silent / sneaky
|
||||
#define SILENCED_SOUND_EXTRARANGE -11
|
||||
///Percentage of sound's range where no falloff is applied
|
||||
#define SOUND_DEFAULT_FALLOFF_DISTANCE 1 //For a normal sound this would be 1 tile of no falloff
|
||||
///The default exponent of sound falloff
|
||||
#define SOUND_FALLOFF_EXPONENT 6
|
||||
|
||||
//THIS SHOULD ALWAYS BE THE LOWEST ONE!
|
||||
//KEEP IT UPDATED
|
||||
|
||||
@@ -23,6 +35,7 @@
|
||||
#define MAX_INSTRUMENT_CHANNELS (128 * 6)
|
||||
|
||||
#define SOUND_MINIMUM_PRESSURE 10
|
||||
/// remove
|
||||
#define FALLOFF_SOUNDS 1
|
||||
|
||||
|
||||
@@ -53,7 +66,8 @@
|
||||
#define MINING list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\
|
||||
'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\
|
||||
'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\
|
||||
'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint1.ogg', 'sound/ambience/ambilava.ogg')
|
||||
'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint1.ogg',\
|
||||
'sound/ambience/ambilava.ogg')
|
||||
|
||||
#define MEDICAL list('sound/ambience/ambinice.ogg')
|
||||
|
||||
@@ -80,3 +94,55 @@
|
||||
'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\
|
||||
'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\
|
||||
'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg')
|
||||
|
||||
|
||||
#define INTERACTION_SOUND_RANGE_MODIFIER -3
|
||||
#define EQUIP_SOUND_VOLUME 30
|
||||
#define PICKUP_SOUND_VOLUME 15
|
||||
#define DROP_SOUND_VOLUME 20
|
||||
#define YEET_SOUND_VOLUME 90
|
||||
|
||||
|
||||
//default byond sound environments
|
||||
#define SOUND_ENVIRONMENT_NONE -1
|
||||
#define SOUND_ENVIRONMENT_GENERIC 0
|
||||
#define SOUND_ENVIRONMENT_PADDED_CELL 1
|
||||
#define SOUND_ENVIRONMENT_ROOM 2
|
||||
#define SOUND_ENVIRONMENT_BATHROOM 3
|
||||
#define SOUND_ENVIRONMENT_LIVINGROOM 4
|
||||
#define SOUND_ENVIRONMENT_STONEROOM 5
|
||||
#define SOUND_ENVIRONMENT_AUDITORIUM 6
|
||||
#define SOUND_ENVIRONMENT_CONCERT_HALL 7
|
||||
#define SOUND_ENVIRONMENT_CAVE 8
|
||||
#define SOUND_ENVIRONMENT_ARENA 9
|
||||
#define SOUND_ENVIRONMENT_HANGAR 10
|
||||
#define SOUND_ENVIRONMENT_CARPETED_HALLWAY 11
|
||||
#define SOUND_ENVIRONMENT_HALLWAY 12
|
||||
#define SOUND_ENVIRONMENT_STONE_CORRIDOR 13
|
||||
#define SOUND_ENVIRONMENT_ALLEY 14
|
||||
#define SOUND_ENVIRONMENT_FOREST 15
|
||||
#define SOUND_ENVIRONMENT_CITY 16
|
||||
#define SOUND_ENVIRONMENT_MOUNTAINS 17
|
||||
#define SOUND_ENVIRONMENT_QUARRY 18
|
||||
#define SOUND_ENVIRONMENT_PLAIN 19
|
||||
#define SOUND_ENVIRONMENT_PARKING_LOT 20
|
||||
#define SOUND_ENVIRONMENT_SEWER_PIPE 21
|
||||
#define SOUND_ENVIRONMENT_UNDERWATER 22
|
||||
#define SOUND_ENVIRONMENT_DRUGGED 23
|
||||
#define SOUND_ENVIRONMENT_DIZZY 24
|
||||
#define SOUND_ENVIRONMENT_PSYCHOTIC 25
|
||||
//If we ever make custom ones add them here
|
||||
|
||||
//"sound areas": easy way of keeping different types of areas consistent.
|
||||
#define SOUND_AREA_STANDARD_STATION SOUND_ENVIRONMENT_PARKING_LOT
|
||||
#define SOUND_AREA_LARGE_ENCLOSED SOUND_ENVIRONMENT_QUARRY
|
||||
#define SOUND_AREA_SMALL_ENCLOSED SOUND_ENVIRONMENT_BATHROOM
|
||||
#define SOUND_AREA_TUNNEL_ENCLOSED SOUND_ENVIRONMENT_STONEROOM
|
||||
#define SOUND_AREA_LARGE_SOFTFLOOR SOUND_ENVIRONMENT_CARPETED_HALLWAY
|
||||
#define SOUND_AREA_MEDIUM_SOFTFLOOR SOUND_ENVIRONMENT_LIVINGROOM
|
||||
#define SOUND_AREA_SMALL_SOFTFLOOR SOUND_ENVIRONMENT_ROOM
|
||||
#define SOUND_AREA_ASTEROID SOUND_ENVIRONMENT_CAVE
|
||||
#define SOUND_AREA_SPACE SOUND_ENVIRONMENT_UNDERWATER
|
||||
#define SOUND_AREA_LAVALAND SOUND_ENVIRONMENT_MOUNTAINS
|
||||
#define SOUND_AREA_ICEMOON SOUND_ENVIRONMENT_CAVE
|
||||
#define SOUND_AREA_WOODFLOOR SOUND_ENVIRONMENT_CITY
|
||||
|
||||
@@ -29,5 +29,5 @@
|
||||
#endif
|
||||
|
||||
/world/proc/enable_debugger()
|
||||
if (fexists(EXTOOLS))
|
||||
call(EXTOOLS, "debug_initialize")()
|
||||
if (fexists(EXTOOLS))
|
||||
call(EXTOOLS, "debug_initialize")()
|
||||
|
||||
@@ -1,40 +1,90 @@
|
||||
//Update this whenever the db schema changes
|
||||
//make sure you add an update to the schema_version stable in the db changelog
|
||||
//! Defines for subsystems and overlays
|
||||
//!
|
||||
//! Lots of important stuff in here, make sure you have your brain switched on
|
||||
//! when editing this file
|
||||
|
||||
//! ## DB defines
|
||||
/**
|
||||
* DB major schema version
|
||||
*
|
||||
* Update this whenever the db schema changes
|
||||
*
|
||||
* make sure you add an update to the schema_version stable in the db changelog
|
||||
*/
|
||||
#define DB_MAJOR_VERSION 4
|
||||
|
||||
/**
|
||||
* DB minor schema version
|
||||
*
|
||||
* Update this whenever the db schema changes
|
||||
*
|
||||
* make sure you add an update to the schema_version stable in the db changelog
|
||||
*/
|
||||
#define DB_MINOR_VERSION 7
|
||||
|
||||
//Timing subsystem
|
||||
//Don't run if there is an identical unique timer active
|
||||
//if the arguments to addtimer are the same as an existing timer, it doesn't create a new timer, and returns the id of the existing timer
|
||||
//! ## Timing subsystem
|
||||
/**
|
||||
* Don't run if there is an identical unique timer active
|
||||
*
|
||||
* if the arguments to addtimer are the same as an existing timer, it doesn't create a new timer,
|
||||
* and returns the id of the existing timer
|
||||
*/
|
||||
#define TIMER_UNIQUE (1<<0)
|
||||
//For unique timers: Replace the old timer rather then not start this one
|
||||
|
||||
///For unique timers: Replace the old timer rather then not start this one
|
||||
#define TIMER_OVERRIDE (1<<1)
|
||||
//Timing should be based on how timing progresses on clients, not the sever.
|
||||
// tracking this is more expensive,
|
||||
// should only be used in conjuction with things that have to progress client side, such as animate() or sound()
|
||||
|
||||
/**
|
||||
* Timing should be based on how timing progresses on clients, not the server.
|
||||
*
|
||||
* Tracking this is more expensive,
|
||||
* should only be used in conjuction with things that have to progress client side, such as
|
||||
* animate() or sound()
|
||||
*/
|
||||
#define TIMER_CLIENT_TIME (1<<2)
|
||||
//Timer can be stopped using deltimer()
|
||||
|
||||
///Timer can be stopped using deltimer()
|
||||
#define TIMER_STOPPABLE (1<<3)
|
||||
//To be used with TIMER_UNIQUE
|
||||
//prevents distinguishing identical timers with the wait variable
|
||||
|
||||
///prevents distinguishing identical timers with the wait variable
|
||||
///
|
||||
///To be used with TIMER_UNIQUE
|
||||
#define TIMER_NO_HASH_WAIT (1<<4)
|
||||
//Loops the timer repeatedly until qdeleted
|
||||
//In most cases you want a subsystem instead
|
||||
|
||||
///Loops the timer repeatedly until qdeleted
|
||||
///
|
||||
///In most cases you want a subsystem instead, so don't use this unless you have a good reason
|
||||
#define TIMER_LOOP (1<<5)
|
||||
|
||||
#define TIMER_NO_INVOKE_WARNING 600 //number of byond ticks that are allowed to pass before the timer subsystem thinks it hung on something
|
||||
|
||||
///Empty ID define
|
||||
#define TIMER_ID_NULL -1
|
||||
|
||||
#define INITIALIZATION_INSSATOMS 0 //New should not call Initialize
|
||||
#define INITIALIZATION_INNEW_MAPLOAD 2 //New should call Initialize(TRUE)
|
||||
#define INITIALIZATION_INNEW_REGULAR 1 //New should call Initialize(FALSE)
|
||||
//! ## Initialization subsystem
|
||||
|
||||
#define INITIALIZE_HINT_NORMAL 0 //Nothing happens
|
||||
#define INITIALIZE_HINT_LATELOAD 1 //Call LateInitialize
|
||||
#define INITIALIZE_HINT_QDEL 2 //Call qdel on the atom
|
||||
///New should not call Initialize
|
||||
#define INITIALIZATION_INSSATOMS 0
|
||||
///New should call Initialize(TRUE)
|
||||
#define INITIALIZATION_INNEW_MAPLOAD 2
|
||||
///New should call Initialize(FALSE)
|
||||
#define INITIALIZATION_INNEW_REGULAR 1
|
||||
|
||||
//type and all subtypes should always call Initialize in New()
|
||||
//! ### Initialization hints
|
||||
|
||||
///Nothing happens
|
||||
#define INITIALIZE_HINT_NORMAL 0
|
||||
/**
|
||||
* call LateInitialize at the end of all atom Initalization
|
||||
*
|
||||
* The item will be added to the late_loaders list, this is iterated over after
|
||||
* initalization of subsystems is complete and calls LateInitalize on the atom
|
||||
* see [this file for the LateIntialize proc](atom.html#proc/LateInitialize)
|
||||
*/
|
||||
#define INITIALIZE_HINT_LATELOAD 1
|
||||
|
||||
///Call qdel on the atom after intialization
|
||||
#define INITIALIZE_HINT_QDEL 2
|
||||
|
||||
///type and all subtypes should always immediately call Initialize in New()
|
||||
#define INITIALIZE_IMMEDIATE(X) ##X/New(loc, ...){\
|
||||
..();\
|
||||
if(!(flags_1 & INITIALIZED_1)) {\
|
||||
@@ -47,35 +97,40 @@
|
||||
// Subsystems shutdown in the reverse of the order they initialize in
|
||||
// The numbers just define the ordering, they are meaningless otherwise.
|
||||
|
||||
#define INIT_ORDER_PROFILER 100
|
||||
#define INIT_ORDER_FAIL2TOPIC 99
|
||||
#define INIT_ORDER_TITLE 98
|
||||
#define INIT_ORDER_GARBAGE 95
|
||||
#define INIT_ORDER_DBCORE 94
|
||||
#define INIT_ORDER_STATPANELS 93
|
||||
#define INIT_ORDER_BLACKBOX 92
|
||||
#define INIT_ORDER_SERVER_MAINT 91
|
||||
#define INIT_ORDER_INPUT 90
|
||||
#define INIT_ORDER_SOUNDS 85
|
||||
#define INIT_ORDER_PROFILER 102
|
||||
#define INIT_ORDER_FAIL2TOPIC 101
|
||||
#define INIT_ORDER_TITLE 100
|
||||
#define INIT_ORDER_GARBAGE 99
|
||||
#define INIT_ORDER_DBCORE 95
|
||||
#define INIT_ORDER_BLACKBOX 94
|
||||
#define INIT_ORDER_SERVER_MAINT 93
|
||||
#define INIT_ORDER_INPUT 85
|
||||
#define INIT_ORDER_SOUNDS 83
|
||||
#define INIT_ORDER_INSTRUMENTS 82
|
||||
#define INIT_ORDER_VIS 80
|
||||
// #define INIT_ORDER_ACHIEVEMENTS 77
|
||||
#define INIT_ORDER_RESEARCH 75
|
||||
#define INIT_ORDER_EVENTS 70
|
||||
#define INIT_ORDER_JOBS 65
|
||||
#define INIT_ORDER_QUIRKS 60
|
||||
#define INIT_ORDER_TICKER 55
|
||||
#define INIT_ORDER_INSTRUMENTS 53
|
||||
// #define INIT_ORDER_TCG 55
|
||||
#define INIT_ORDER_MAPPING 50
|
||||
#define INIT_ORDER_ECONOMY 45
|
||||
#define INIT_ORDER_NETWORKS 40
|
||||
#define INIT_ORDER_TIMETRACK 47
|
||||
#define INIT_ORDER_NETWORKS 45
|
||||
#define INIT_ORDER_ECONOMY 40
|
||||
#define INIT_ORDER_HOLODECK 35
|
||||
// #define INIT_ORDER_OUTPUTS 35
|
||||
#define INIT_ORDER_ATOMS 30
|
||||
#define INIT_ORDER_LANGUAGE 25
|
||||
#define INIT_ORDER_MACHINES 20
|
||||
#define INIT_ORDER_CIRCUIT 15
|
||||
// #define INIT_ORDER_SKILLS 15
|
||||
#define INIT_ORDER_TIMER 1
|
||||
#define INIT_ORDER_DEFAULT 0
|
||||
#define INIT_ORDER_AIR -1
|
||||
#define INIT_ORDER_AIR_TURFS -2
|
||||
#define INIT_ORDER_PERSISTENCE -2 //before assets because some assets take data from SSPersistence
|
||||
#define INIT_ORDER_MINIMAP -3
|
||||
#define INIT_ORDER_ASSETS -4
|
||||
#define INIT_ORDER_ICON_SMOOTHING -5
|
||||
@@ -86,7 +141,9 @@
|
||||
#define INIT_ORDER_SHUTTLE -21
|
||||
#define INIT_ORDER_MINOR_MAPPING -40
|
||||
#define INIT_ORDER_PATH -50
|
||||
#define INIT_ORDER_PERSISTENCE -95
|
||||
// #define INIT_ORDER_DISCORD -60
|
||||
// #define INIT_ORDER_EXPLOSIONS -69
|
||||
#define INIT_ORDER_STATPANELS -98
|
||||
#define INIT_ORDER_DEMO -99 // o avoid a bunch of changes related to initialization being written, do this last
|
||||
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
|
||||
|
||||
@@ -102,6 +159,7 @@
|
||||
#define FIRE_PRIORITY_GARBAGE 15
|
||||
#define FIRE_PRIORITY_WET_FLOORS 20
|
||||
#define FIRE_PRIORITY_AIR 20
|
||||
#define FIRE_PRIORITY_NPC 20
|
||||
#define FIRE_PRIORITY_PROCESS 25
|
||||
#define FIRE_PRIORITY_THROWING 25
|
||||
#define FIRE_PRIORITY_SPACEDRIFT 30
|
||||
@@ -116,7 +174,6 @@
|
||||
#define FIRE_PRIORITY_AIR_TURFS 40
|
||||
#define FIRE_PRIORITY_DEFAULT 50
|
||||
#define FIRE_PRIORITY_PARALLAX 65
|
||||
#define FIRE_PRIORITY_NPC 80
|
||||
#define FIRE_PRIORITY_MOBS 100
|
||||
#define FIRE_PRIORITY_TGUI 110
|
||||
#define FIRE_PRIORITY_PROJECTILES 200
|
||||
@@ -126,6 +183,8 @@
|
||||
#define FIRE_PRIORITY_CHAT 400
|
||||
#define FIRE_PRIORITY_RUNECHAT 410
|
||||
#define FIRE_PRIORITY_OVERLAYS 500
|
||||
// #define FIRE_PRIORITY_EXPLOSIONS 666
|
||||
#define FIRE_PRIORITY_TIMER 700
|
||||
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
|
||||
|
||||
// SS runlevels
|
||||
@@ -138,6 +197,37 @@
|
||||
|
||||
#define RUNLEVELS_DEFAULT (RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME)
|
||||
|
||||
|
||||
|
||||
//! ## Overlays subsystem
|
||||
|
||||
///Compile all the overlays for an atom from the cache lists
|
||||
// |= on overlays is not actually guaranteed to not add same appearances but we're optimistically using it anyway.
|
||||
#define COMPILE_OVERLAYS(A)\
|
||||
if (TRUE) {\
|
||||
var/list/ad = A.add_overlays;\
|
||||
var/list/rm = A.remove_overlays;\
|
||||
if(LAZYLEN(rm)){\
|
||||
A.overlays -= rm;\
|
||||
rm.Cut();\
|
||||
}\
|
||||
if(LAZYLEN(ad)){\
|
||||
A.overlays |= ad;\
|
||||
ad.Cut();\
|
||||
}\
|
||||
A.flags_1 &= ~OVERLAY_QUEUED_1;\
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Create a new timer and add it to the queue.
|
||||
* Arguments:
|
||||
* * callback the callback to call on timer finish
|
||||
* * wait deciseconds to run the timer for
|
||||
* * flags flags for this timer, see: code\__DEFINES\subsystems.dm
|
||||
*/
|
||||
#define addtimer(args...) _addtimer(args, file = __FILE__, line = __LINE__)
|
||||
|
||||
// SSair run section
|
||||
#define SSAIR_PIPENETS 1
|
||||
#define SSAIR_ATMOSMACHINERY 2
|
||||
@@ -148,19 +238,3 @@
|
||||
#define SSAIR_REBUILD_PIPENETS 7
|
||||
#define SSAIR_EQUALIZE 8
|
||||
#define SSAIR_ACTIVETURFS 9
|
||||
|
||||
// |= on overlays is not actually guaranteed to not add same appearances but we're optimistically using it anyway.
|
||||
#define COMPILE_OVERLAYS(A)\
|
||||
if (TRUE) {\
|
||||
var/list/ad = A.add_overlays;\
|
||||
var/list/rm = A.remove_overlays;\
|
||||
if(LAZYLEN(rm)){\
|
||||
A.overlays -= rm;\
|
||||
A.remove_overlays = null;\
|
||||
}\
|
||||
if(LAZYLEN(ad)){\
|
||||
A.overlays |= ad;\
|
||||
A.add_overlays = null;\
|
||||
}\
|
||||
A.flags_1 &= ~OVERLAY_QUEUED_1;\
|
||||
}
|
||||
|
||||
@@ -253,6 +253,7 @@
|
||||
|
||||
// item traits
|
||||
#define TRAIT_NODROP "nodrop"
|
||||
#define TRAIT_SPOOKY_THROW "spooky_throw"
|
||||
|
||||
// common trait sources
|
||||
#define TRAIT_GENERIC "generic"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define APPROVAL_VOTING "APPROVAL"
|
||||
#define SCHULZE_VOTING "SCHULZE"
|
||||
#define SCORE_VOTING "SCORE"
|
||||
#define MAJORITY_JUDGEMENT_VOTING "MAJORITY_JUDGEMENT"
|
||||
#define HIGHEST_MEDIAN_VOTING "HIGHEST_MEDIAN"
|
||||
#define INSTANT_RUNOFF_VOTING "IRV"
|
||||
|
||||
#define SHOW_RESULTS (1<<0)
|
||||
@@ -18,7 +18,7 @@ GLOBAL_LIST_INIT(vote_type_names,list(\
|
||||
"IRV (single winner ranked choice)" = INSTANT_RUNOFF_VOTING,\
|
||||
"Schulze (ranked choice, higher result=better)" = SCHULZE_VOTING,\
|
||||
"Raw Score (returns results from 0 to 1, winner is 1)" = SCORE_VOTING,\
|
||||
"Majority Judgement (single-winner score voting)" = MAJORITY_JUDGEMENT_VOTING,\
|
||||
"Highest Median (single-winner score voting)" = HIGHEST_MEDIAN_VOTING,\
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(display_vote_settings, list(\
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#define EXTOOLS_LOGGING // rust_g is used as a fallback if this is undefined
|
||||
|
||||
/proc/extools_log_write()
|
||||
|
||||
/proc/extools_finalize_logging()
|
||||
@@ -37,7 +37,7 @@
|
||||
* TYPECONT: The typepath of the contents of the list
|
||||
* COMPARE: The object to compare against, usualy the same as INPUT
|
||||
* COMPARISON: The variable on the objects to compare
|
||||
* COMPTYPE: How the current bin item to compare against COMPARE is fetched. By key or value.
|
||||
* COMPTYPE: How should the values be compared? Either COMPARE_KEY or COMPARE_VALUE.
|
||||
*/
|
||||
#define BINARY_INSERT(INPUT, LIST, TYPECONT, COMPARE, COMPARISON, COMPTYPE) \
|
||||
do {\
|
||||
@@ -49,7 +49,7 @@
|
||||
var/__BIN_LEFT = 1;\
|
||||
var/__BIN_RIGHT = __BIN_CTTL;\
|
||||
var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
|
||||
var/##TYPECONT/__BIN_ITEM;\
|
||||
var ##TYPECONT/__BIN_ITEM;\
|
||||
while(__BIN_LEFT < __BIN_RIGHT) {\
|
||||
__BIN_ITEM = COMPTYPE;\
|
||||
if(__BIN_ITEM.##COMPARISON <= COMPARE.##COMPARISON) {\
|
||||
@@ -67,24 +67,25 @@
|
||||
|
||||
//Returns a list in plain english as a string
|
||||
/proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" )
|
||||
var/total = input.len
|
||||
if (!total)
|
||||
return nothing_text
|
||||
else if (total == 1)
|
||||
return "[input[1]]"
|
||||
else if (total == 2)
|
||||
return "[input[1]][and_text][input[2]]"
|
||||
else
|
||||
var/output = ""
|
||||
var/index = 1
|
||||
while (index < total)
|
||||
if (index == total - 1)
|
||||
comma_text = final_comma_text
|
||||
var/total = length(input)
|
||||
switch(total)
|
||||
if (0)
|
||||
return "[nothing_text]"
|
||||
if (1)
|
||||
return "[input[1]]"
|
||||
if (2)
|
||||
return "[input[1]][and_text][input[2]]"
|
||||
else
|
||||
var/output = ""
|
||||
var/index = 1
|
||||
while (index < total)
|
||||
if (index == total - 1)
|
||||
comma_text = final_comma_text
|
||||
|
||||
output += "[input[index]][comma_text]"
|
||||
index++
|
||||
output += "[input[index]][comma_text]"
|
||||
index++
|
||||
|
||||
return "[output][and_text][input[index]]"
|
||||
return "[output][and_text][input[index]]"
|
||||
|
||||
//Returns list element or null. Should prevent "index out of bounds" error.
|
||||
/proc/listgetindex(list/L, index)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#define testing(msg)
|
||||
#endif
|
||||
|
||||
#ifdef UNIT_TESTS
|
||||
#if defined(UNIT_TESTS) || defined(SPACEMAN_DMM)
|
||||
/proc/log_test(text)
|
||||
WRITE_LOG(GLOB.test_log, text)
|
||||
SEND_TEXT(world.log, text)
|
||||
@@ -191,6 +191,10 @@
|
||||
/proc/log_mapping(text)
|
||||
WRITE_LOG(GLOB.world_map_error_log, text)
|
||||
|
||||
/proc/log_perf(list/perf_info)
|
||||
. = "[perf_info.Join(",")]\n"
|
||||
WRITE_LOG_NO_FORMAT(GLOB.perf_log, .)
|
||||
|
||||
/proc/log_reagent(text)
|
||||
WRITE_LOG(GLOB.reagent_log, text)
|
||||
|
||||
|
||||
@@ -19,22 +19,6 @@
|
||||
/proc/arachnid_name()
|
||||
return "[pick(GLOB.arachnid_first)] [pick(GLOB.arachnid_last)]"
|
||||
|
||||
/proc/church_name()
|
||||
var/static/church_name
|
||||
if (church_name)
|
||||
return church_name
|
||||
|
||||
var/name = ""
|
||||
|
||||
name += pick("Holy", "United", "First", "Second", "Last")
|
||||
|
||||
if (prob(20))
|
||||
name += " Space"
|
||||
|
||||
name += " " + pick("Church", "Cathedral", "Body", "Worshippers", "Movement", "Witnesses")
|
||||
name += " of [religion_name()]"
|
||||
|
||||
return name
|
||||
|
||||
GLOBAL_VAR(command_name)
|
||||
/proc/command_name()
|
||||
@@ -52,17 +36,6 @@ GLOBAL_VAR(command_name)
|
||||
|
||||
return name
|
||||
|
||||
/proc/religion_name()
|
||||
var/static/religion_name
|
||||
if (religion_name)
|
||||
return religion_name
|
||||
|
||||
var/name = ""
|
||||
|
||||
name += pick("bee", "science", "edu", "captain", "assistant", "monkey", "alien", "space", "unit", "sprocket", "gadget", "bomb", "revolution", "beyond", "station", "goon", "robot", "ivor", "hobnob")
|
||||
name += pick("ism", "ia", "ology", "istism", "ites", "ick", "ian", "ity")
|
||||
|
||||
return capitalize(name)
|
||||
|
||||
/proc/station_name()
|
||||
if(!GLOB.station_name)
|
||||
|
||||
@@ -78,21 +78,21 @@
|
||||
//Turns a direction into text
|
||||
/proc/dir2text(direction)
|
||||
switch(direction)
|
||||
if(1)
|
||||
if(NORTH)
|
||||
return "north"
|
||||
if(2)
|
||||
if(SOUTH)
|
||||
return "south"
|
||||
if(4)
|
||||
if(EAST)
|
||||
return "east"
|
||||
if(8)
|
||||
if(WEST)
|
||||
return "west"
|
||||
if(5)
|
||||
if(NORTHEAST)
|
||||
return "northeast"
|
||||
if(6)
|
||||
if(SOUTHEAST)
|
||||
return "southeast"
|
||||
if(9)
|
||||
if(NORTHWEST)
|
||||
return "northwest"
|
||||
if(10)
|
||||
if(SOUTHWEST)
|
||||
return "southwest"
|
||||
else
|
||||
return
|
||||
@@ -101,21 +101,21 @@
|
||||
/proc/text2dir(direction)
|
||||
switch(uppertext(direction))
|
||||
if("NORTH")
|
||||
return 1
|
||||
return NORTH
|
||||
if("SOUTH")
|
||||
return 2
|
||||
return SOUTH
|
||||
if("EAST")
|
||||
return 4
|
||||
return EAST
|
||||
if("WEST")
|
||||
return 8
|
||||
return WEST
|
||||
if("NORTHEAST")
|
||||
return 5
|
||||
return NORTHEAST
|
||||
if("NORTHWEST")
|
||||
return 9
|
||||
return NORTHWEST
|
||||
if("SOUTHEAST")
|
||||
return 6
|
||||
return SOUTHEAST
|
||||
if("SOUTHWEST")
|
||||
return 10
|
||||
return SOUTHWEST
|
||||
else
|
||||
return
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
return .
|
||||
|
||||
//Returns a list of all items of interest with their name
|
||||
/proc/getpois(mobs_only=0,skip_mindless=0)
|
||||
/proc/getpois(mobs_only = FALSE, skip_mindless = FALSE, specify_dead_role = TRUE)
|
||||
var/list/mobs = sortmobs()
|
||||
var/list/namecounts = list()
|
||||
var/list/pois = list()
|
||||
@@ -277,7 +277,7 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
|
||||
if(M.real_name && M.real_name != M.name)
|
||||
name += " \[[M.real_name]\]"
|
||||
if(M.stat == DEAD)
|
||||
if(M.stat == DEAD && specify_dead_role)
|
||||
if(isobserver(M))
|
||||
name += " \[ghost\]"
|
||||
else
|
||||
@@ -1070,7 +1070,7 @@ B --><-- A
|
||||
return closest_atom
|
||||
|
||||
|
||||
proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
|
||||
/proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
|
||||
if (value == FALSE) //nothing should be calling us with a number, so this is safe
|
||||
value = input("Enter type to find (blank for all, cancel to cancel)", "Search for type") as null|text
|
||||
if (isnull(value))
|
||||
@@ -1202,7 +1202,7 @@ GLOBAL_REAL_VAR(list/stack_trace_storage)
|
||||
GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
|
||||
//Version of view() which ignores darkness, because BYOND doesn't have it (I actually suggested it but it was tagged redundant, BUT HEARERS IS A T- /rant).
|
||||
/proc/dview(var/range = world.view, var/center, var/invis_flags = 0)
|
||||
/proc/dview(range = world.view, center, invis_flags = 0)
|
||||
if(!center)
|
||||
return
|
||||
|
||||
@@ -1222,6 +1222,10 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
var/ready_to_die = FALSE
|
||||
|
||||
/mob/dview/Initialize() //Properly prevents this mob from gaining huds or joining any global lists
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
if(flags_1 & INITIALIZED_1)
|
||||
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
||||
flags_1 |= INITIALIZED_1
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
/mob/dview/Destroy(force = FALSE)
|
||||
|
||||
@@ -46,11 +46,11 @@
|
||||
|
||||
//Update this whenever you need to take advantage of more recent byond features
|
||||
#define MIN_COMPILER_VERSION 513
|
||||
#define MIN_COMPILER_BUILD 1508
|
||||
#define MIN_COMPILER_BUILD 1514
|
||||
#if DM_VERSION < MIN_COMPILER_VERSION || DM_BUILD < MIN_COMPILER_BUILD
|
||||
//Don't forget to update this part
|
||||
#error Your version of BYOND is too out-of-date to compile this project. Go to https://secure.byond.com/download and update.
|
||||
#error You need version 513.1508 or higher
|
||||
#error You need version 513.1514 or higher
|
||||
#endif
|
||||
|
||||
//Additional code for the above flags.
|
||||
@@ -62,10 +62,14 @@
|
||||
#define FIND_REF_NO_CHECK_TICK
|
||||
#endif
|
||||
|
||||
#ifdef TRAVISBUILDING
|
||||
#ifdef CIBUILDING
|
||||
#define UNIT_TESTS
|
||||
#endif
|
||||
|
||||
#ifdef TRAVISTESTING
|
||||
#ifdef CITESTING
|
||||
#define TESTING
|
||||
#endif
|
||||
|
||||
// A reasonable number of maximum overlays an object needs
|
||||
// If you think you need more, rethink it
|
||||
#define MAX_ATOM_OVERLAYS 100
|
||||
|
||||
12
code/_globalvars/admin.dm
Normal file
12
code/_globalvars/admin.dm
Normal file
@@ -0,0 +1,12 @@
|
||||
GLOBAL_LIST_EMPTY(stickybanadminexemptions) //stores a list of ckeys exempted from a stickyban (workaround for a bug)
|
||||
GLOBAL_LIST_EMPTY(stickybanadmintexts) //stores the entire stickyban list temporarily
|
||||
GLOBAL_VAR(stickbanadminexemptiontimerid) //stores the timerid of the callback that restores all stickybans after an admin joins
|
||||
|
||||
// /proc/init_smites() //todo: add on the second wave
|
||||
// var/list/smites = list()
|
||||
// for (var/_smite_path in subtypesof(/datum/smite))
|
||||
// var/datum/smite/smite_path = _smite_path
|
||||
// smites[initial(smite_path.name)] = smite_path
|
||||
// return smites
|
||||
|
||||
// GLOBAL_LIST_INIT_TYPED(smites, /datum/smite, init_smites())
|
||||
@@ -274,7 +274,7 @@ GLOBAL_LIST_INIT(redacted_strings, list("\[REDACTED\]", "\[CLASSIFIED\]", "\[ARC
|
||||
GLOBAL_LIST_INIT(wisdoms, world.file2list("strings/wisdoms.txt"))
|
||||
|
||||
//LANGUAGE CHARACTER CUSTOMIZATION
|
||||
GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles"))
|
||||
GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles", "caws", "gekkers", "clucks"))
|
||||
GLOBAL_LIST_INIT(roundstart_tongues, list("default","human tongue" = /obj/item/organ/tongue, "lizard tongue" = /obj/item/organ/tongue/lizard, "skeleton tongue" = /obj/item/organ/tongue/bone, "fly tongue" = /obj/item/organ/tongue/fly, "ipc tongue" = /obj/item/organ/tongue/robot/ipc, "xeno tongue" = /obj/item/organ/tongue/alien))
|
||||
|
||||
//SPECIES BODYPART LISTS
|
||||
|
||||
@@ -8,6 +8,8 @@ GLOBAL_VAR(world_qdel_log)
|
||||
GLOBAL_PROTECT(world_qdel_log)
|
||||
GLOBAL_VAR(world_attack_log)
|
||||
GLOBAL_PROTECT(world_attack_log)
|
||||
// GLOBAL_VAR(world_econ_log)
|
||||
// GLOBAL_PROTECT(world_econ_log)
|
||||
GLOBAL_VAR(world_href_log)
|
||||
GLOBAL_PROTECT(world_href_log)
|
||||
GLOBAL_VAR(round_id)
|
||||
@@ -26,22 +28,28 @@ GLOBAL_VAR(query_debug_log)
|
||||
GLOBAL_PROTECT(query_debug_log)
|
||||
GLOBAL_VAR(world_job_debug_log)
|
||||
GLOBAL_PROTECT(world_job_debug_log)
|
||||
// GLOBAL_VAR(world_mecha_log)
|
||||
// GLOBAL_PROTECT(world_mecha_log)
|
||||
GLOBAL_VAR(world_virus_log)
|
||||
GLOBAL_PROTECT(world_virus_log)
|
||||
GLOBAL_VAR(world_asset_log)
|
||||
GLOBAL_PROTECT(world_asset_log)
|
||||
// GLOBAL_VAR(world_cloning_log)
|
||||
// GLOBAL_PROTECT(world_cloning_log)
|
||||
GLOBAL_VAR(world_map_error_log)
|
||||
GLOBAL_PROTECT(world_map_error_log)
|
||||
GLOBAL_VAR(world_paper_log)
|
||||
GLOBAL_PROTECT(world_paper_log)
|
||||
GLOBAL_VAR(subsystem_log)
|
||||
GLOBAL_PROTECT(subsystem_log)
|
||||
GLOBAL_VAR(reagent_log)
|
||||
GLOBAL_PROTECT(reagent_log)
|
||||
GLOBAL_VAR(world_crafting_log)
|
||||
GLOBAL_PROTECT(world_crafting_log)
|
||||
GLOBAL_VAR(click_log)
|
||||
GLOBAL_PROTECT(click_log)
|
||||
GLOBAL_VAR(tgui_log)
|
||||
GLOBAL_PROTECT(tgui_log)
|
||||
GLOBAL_VAR(world_shuttle_log)
|
||||
GLOBAL_PROTECT(world_shuttle_log)
|
||||
|
||||
GLOBAL_VAR(perf_log)
|
||||
GLOBAL_PROTECT(perf_log)
|
||||
|
||||
// GLOBAL_VAR(demo_log)
|
||||
// GLOBAL_PROTECT(demo_log)
|
||||
|
||||
GLOBAL_LIST_EMPTY(bombers)
|
||||
GLOBAL_PROTECT(bombers)
|
||||
@@ -51,10 +59,7 @@ GLOBAL_LIST_EMPTY(lastsignalers) //keeps last 100 signals here in format: "[src]
|
||||
GLOBAL_PROTECT(lastsignalers)
|
||||
GLOBAL_LIST_EMPTY(lawchanges) //Stores who uploaded laws to which silicon-based lifeform, and what the law was
|
||||
GLOBAL_PROTECT(lawchanges)
|
||||
GLOBAL_VAR(tgui_log)
|
||||
GLOBAL_PROTECT(tgui_log)
|
||||
GLOBAL_VAR(world_shuttle_log)
|
||||
GLOBAL_PROTECT(world_shuttle_log)
|
||||
|
||||
GLOBAL_LIST_EMPTY(combatlog)
|
||||
GLOBAL_PROTECT(combatlog)
|
||||
GLOBAL_LIST_EMPTY(IClog)
|
||||
@@ -75,3 +80,13 @@ GLOBAL_PROTECT(picture_logging_id)
|
||||
GLOBAL_VAR(picture_logging_prefix)
|
||||
GLOBAL_PROTECT(picture_logging_prefix)
|
||||
/////
|
||||
|
||||
//// cit logging
|
||||
GLOBAL_VAR(subsystem_log)
|
||||
GLOBAL_PROTECT(subsystem_log)
|
||||
GLOBAL_VAR(reagent_log)
|
||||
GLOBAL_PROTECT(reagent_log)
|
||||
GLOBAL_VAR(world_crafting_log)
|
||||
GLOBAL_PROTECT(world_crafting_log)
|
||||
GLOBAL_VAR(click_log)
|
||||
GLOBAL_PROTECT(click_log)
|
||||
|
||||
@@ -130,7 +130,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
),
|
||||
/obj/item = list(
|
||||
"TRAIT_NODROP" = TRAIT_NODROP,
|
||||
"TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT
|
||||
"TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT,
|
||||
"TRAIT_SPOOKY_THROW" = TRAIT_SPOOKY_THROW
|
||||
)
|
||||
))
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
|
||||
/obj/screen/alert/shiver
|
||||
name = "Shivering"
|
||||
desc = "You're shivering! Get somewhere warmer and take off any insulating clothing like a space suit."
|
||||
desc = "You're shivering! Get somewhere warmer and take off any insulating clothing like a space suit."
|
||||
|
||||
/obj/screen/alert/lowpressure
|
||||
name = "Low Pressure"
|
||||
@@ -306,6 +306,39 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
|
||||
if(CHECK_MOBILITY(L, MOBILITY_MOVE))
|
||||
return L.resist_fire() //I just want to start a flame in your hearrrrrrtttttt.
|
||||
|
||||
/obj/screen/alert/give // information set when the give alert is made
|
||||
icon_state = "default"
|
||||
var/mob/living/carbon/giver
|
||||
var/obj/item/receiving
|
||||
|
||||
/**
|
||||
* Handles assigning most of the variables for the alert that pops up when an item is offered
|
||||
*
|
||||
* Handles setting the name, description and icon of the alert and tracking the person giving
|
||||
* and the item being offered, also registers a signal that removes the alert from anyone who moves away from the giver
|
||||
* Arguments:
|
||||
* * taker - The person receiving the alert
|
||||
* * giver - The person giving the alert and item
|
||||
* * receiving - The item being given by the giver
|
||||
*/
|
||||
/obj/screen/alert/give/proc/setup(mob/living/carbon/taker, mob/living/carbon/giver, obj/item/receiving)
|
||||
name = "[giver] is offering [receiving]"
|
||||
desc = "[giver] is offering [receiving]. Click this alert to take it."
|
||||
icon_state = "template"
|
||||
cut_overlays()
|
||||
add_overlay(receiving)
|
||||
src.receiving = receiving
|
||||
src.giver = giver
|
||||
RegisterSignal(taker, COMSIG_MOVABLE_MOVED, .proc/removeAlert)
|
||||
|
||||
/obj/screen/alert/give/proc/removeAlert()
|
||||
to_chat(usr, "<span class='warning'>You moved out of range of [giver]!</span>")
|
||||
usr.clear_alert("[giver]")
|
||||
|
||||
/obj/screen/alert/give/Click(location, control, params)
|
||||
. = ..()
|
||||
var/mob/living/carbon/C = usr
|
||||
C.take(giver, receiving)
|
||||
|
||||
//ALIENS
|
||||
|
||||
|
||||
@@ -149,6 +149,15 @@
|
||||
/obj/screen/fullscreen/color_vision/blue
|
||||
color = "#0000ff"
|
||||
|
||||
/obj/screen/fullscreen/cinematic_backdrop
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
icon_state = "flash"
|
||||
plane = SPLASHSCREEN_PLANE
|
||||
layer = SPLASHSCREEN_LAYER - 1
|
||||
color = "#000000"
|
||||
show_when_dead = TRUE
|
||||
|
||||
/obj/screen/fullscreen/lighting_backdrop
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "flash"
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_1(null, C.view)
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_2(null, C.view)
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/planet(null, C.view)
|
||||
if(SSparallax.random_layer)
|
||||
C.parallax_layers_cached += new SSparallax.random_layer
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_3(null, C.view)
|
||||
|
||||
C.parallax_layers = C.parallax_layers_cached.Copy()
|
||||
@@ -52,12 +54,12 @@
|
||||
switch(C.prefs.parallax)
|
||||
if (PARALLAX_INSANE)
|
||||
C.parallax_throttle = FALSE
|
||||
C.parallax_layers_max = 4
|
||||
C.parallax_layers_max = 5
|
||||
return TRUE
|
||||
|
||||
if (PARALLAX_MED)
|
||||
C.parallax_throttle = PARALLAX_DELAY_MED
|
||||
C.parallax_layers_max = 2
|
||||
C.parallax_layers_max = 3
|
||||
return TRUE
|
||||
|
||||
if (PARALLAX_LOW)
|
||||
@@ -68,8 +70,9 @@
|
||||
if (PARALLAX_DISABLE)
|
||||
return FALSE
|
||||
|
||||
//This is high parallax.
|
||||
C.parallax_throttle = PARALLAX_DELAY_DEFAULT
|
||||
C.parallax_layers_max = 3
|
||||
C.parallax_layers_max = 4
|
||||
return TRUE
|
||||
|
||||
/datum/hud/proc/update_parallax_pref(mob/viewmob)
|
||||
@@ -219,15 +222,14 @@
|
||||
L.screen_loc = "CENTER-7:[round(L.offset_x,1)],CENTER-7:[round(L.offset_y,1)]"
|
||||
|
||||
/atom/movable/proc/update_parallax_contents()
|
||||
set waitfor = FALSE
|
||||
if(length(client_mobs_in_contents))
|
||||
for(var/thing in client_mobs_in_contents)
|
||||
var/mob/M = thing
|
||||
if(M && M.client && M.hud_used && length(M.client.parallax_layers))
|
||||
if(M?.client && M.hud_used && length(M.client.parallax_layers))
|
||||
M.hud_used.update_parallax()
|
||||
|
||||
/mob/proc/update_parallax_teleport() //used for arrivals shuttle
|
||||
if(client && client.eye && hud_used && length(client.parallax_layers))
|
||||
if(client?.eye && hud_used && length(client.parallax_layers))
|
||||
var/area/areaobj = get_area(client.eye)
|
||||
hud_used.set_parallax_movedir(areaobj.parallax_movedir, TRUE)
|
||||
|
||||
@@ -287,6 +289,21 @@
|
||||
speed = 1.4
|
||||
layer = 3
|
||||
|
||||
/obj/screen/parallax_layer/random
|
||||
blend_mode = BLEND_OVERLAY
|
||||
speed = 3
|
||||
layer = 3
|
||||
|
||||
/obj/screen/parallax_layer/random/space_gas
|
||||
icon_state = "space_gas"
|
||||
|
||||
/obj/screen/parallax_layer/random/space_gas/Initialize(mapload, view)
|
||||
. = ..()
|
||||
src.add_atom_colour(SSparallax.random_parallax_color, ADMIN_COLOUR_PRIORITY)
|
||||
|
||||
/obj/screen/parallax_layer/random/asteroids
|
||||
icon_state = "asteroids"
|
||||
|
||||
/obj/screen/parallax_layer/planet
|
||||
icon_state = "planet"
|
||||
blend_mode = BLEND_OVERLAY
|
||||
@@ -295,11 +312,11 @@
|
||||
layer = 30
|
||||
|
||||
/obj/screen/parallax_layer/planet/update_status(mob/M)
|
||||
var/turf/T = get_turf(M)
|
||||
if(is_station_level(T.z))
|
||||
invisibility = 0
|
||||
else
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
var/client/C = M.client
|
||||
var/turf/posobj = get_turf(C.eye)
|
||||
if(!posobj)
|
||||
return
|
||||
invisibility = is_station_level(posobj.z) ? 0 : INVISIBILITY_ABSTRACT
|
||||
|
||||
/obj/screen/parallax_layer/planet/update_o()
|
||||
return //Shit wont move
|
||||
return //Shit won't move
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
. = ..()
|
||||
filters += filter(type="alpha", render_source=FIELD_OF_VISION_RENDER_TARGET, flags=MASK_INVERSE)
|
||||
|
||||
/obj/screen/plane_master/openspace/backdrop(mob/mymob)
|
||||
filters = list()
|
||||
filters += filter(type = "drop_shadow", color = "#04080FAA", size = -10)
|
||||
filters += filter(type = "drop_shadow", color = "#04080FAA", size = -15)
|
||||
filters += filter(type = "drop_shadow", color = "#04080FAA", size = -20)
|
||||
@@ -93,13 +91,6 @@
|
||||
else
|
||||
remove_filter("ambient_occlusion")
|
||||
|
||||
//Reserved to chat messages, so they are still displayed above the field of vision masking.
|
||||
/obj/screen/plane_master/chat_messages
|
||||
name = "chat messages plane master"
|
||||
plane = CHAT_PLANE
|
||||
appearance_flags = PLANE_MASTER
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
///Contains all shadow cone masks, whose image overrides are displayed only to their respective owners.
|
||||
/obj/screen/plane_master/field_of_vision
|
||||
name = "field of vision mask plane master"
|
||||
@@ -135,10 +126,14 @@
|
||||
blend_mode = BLEND_MULTIPLY
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/screen/plane_master/lighting/backdrop(mob/mymob)
|
||||
mymob.overlay_fullscreen("lighting_backdrop_lit", /obj/screen/fullscreen/lighting_backdrop/lit)
|
||||
mymob.overlay_fullscreen("lighting_backdrop_unlit", /obj/screen/fullscreen/lighting_backdrop/unlit)
|
||||
|
||||
/obj/screen/plane_master/lighting/Initialize()
|
||||
. = ..()
|
||||
filters += filter(type="alpha", render_source=EMISSIVE_RENDER_TARGET, flags=MASK_INVERSE)
|
||||
filters += filter(type="alpha", render_source=EMISSIVE_UNBLOCKABLE_RENDER_TARGET, flags=MASK_INVERSE)
|
||||
filters += filter(type="alpha", render_source = EMISSIVE_RENDER_TARGET, flags = MASK_INVERSE)
|
||||
filters += filter(type="alpha", render_source = EMISSIVE_UNBLOCKABLE_RENDER_TARGET, flags = MASK_INVERSE)
|
||||
|
||||
/**
|
||||
* Things placed on this mask the lighting plane. Doesn't render directly.
|
||||
@@ -186,7 +181,6 @@
|
||||
render_target = EMISSIVE_BLOCKER_RENDER_TARGET
|
||||
|
||||
///Contains space parallax
|
||||
|
||||
/obj/screen/plane_master/parallax
|
||||
name = "parallax plane master"
|
||||
plane = PLANE_SPACE_PARALLAX
|
||||
@@ -197,12 +191,16 @@
|
||||
name = "parallax whitifier plane master"
|
||||
plane = PLANE_SPACE
|
||||
|
||||
/obj/screen/plane_master/lighting/backdrop(mob/mymob)
|
||||
mymob.overlay_fullscreen("lighting_backdrop_lit", /obj/screen/fullscreen/lighting_backdrop/lit)
|
||||
mymob.overlay_fullscreen("lighting_backdrop_unlit", /obj/screen/fullscreen/lighting_backdrop/unlit)
|
||||
|
||||
/obj/screen/plane_master/camera_static
|
||||
name = "camera static plane master"
|
||||
plane = CAMERA_STATIC_PLANE
|
||||
appearance_flags = PLANE_MASTER
|
||||
blend_mode = BLEND_OVERLAY
|
||||
|
||||
|
||||
//Reserved to chat messages, so they are still displayed above the field of vision masking.
|
||||
/obj/screen/plane_master/chat_messages
|
||||
name = "runechat plane master"
|
||||
plane = CHAT_PLANE
|
||||
appearance_flags = PLANE_MASTER
|
||||
blend_mode = BLEND_OVERLAY
|
||||
|
||||
@@ -12,9 +12,14 @@
|
||||
layer = HUD_LAYER
|
||||
plane = HUD_PLANE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
animate_movement = SLIDE_STEPS
|
||||
speech_span = SPAN_ROBOT
|
||||
vis_flags = VIS_INHERIT_PLANE
|
||||
appearance_flags = APPEARANCE_UI
|
||||
var/obj/master = null //A reference to the object in the slot. Grabs or items, generally.
|
||||
var/datum/hud/hud = null // A reference to the owner HUD, if any.
|
||||
/// A reference to the object in the slot. Grabs or items, generally.
|
||||
var/obj/master = null
|
||||
/// A reference to the owner HUD, if any.
|
||||
var/datum/hud/hud = null
|
||||
/**
|
||||
* Map name assigned to this object.
|
||||
* Automatically set by /client/proc/add_obj_to_map.
|
||||
@@ -60,7 +65,17 @@
|
||||
name = "swap hand"
|
||||
|
||||
/obj/screen/swap_hand/Click()
|
||||
usr.swap_hand()
|
||||
// At this point in client Click() code we have passed the 1/10 sec check and little else
|
||||
// We don't even know if it's a middle click
|
||||
// if(world.time <= usr.next_move)
|
||||
// return 1
|
||||
|
||||
if(usr.incapacitated())
|
||||
return 1
|
||||
|
||||
if(ismob(usr))
|
||||
var/mob/M = usr
|
||||
M.swap_hand()
|
||||
return 1
|
||||
|
||||
/obj/screen/craft
|
||||
@@ -96,17 +111,27 @@
|
||||
H.open_language_menu(usr)
|
||||
|
||||
/obj/screen/inventory
|
||||
var/slot_id // The indentifier for the slot. It has nothing to do with ID cards.
|
||||
var/icon_empty // Icon when empty. For now used only by humans.
|
||||
var/icon_full // Icon when contains an item. For now used only by humans.
|
||||
/// The identifier for the slot. It has nothing to do with ID cards.
|
||||
var/slot_id
|
||||
/// Icon when empty. For now used only by humans.
|
||||
var/icon_empty
|
||||
/// Icon when contains an item. For now used only by humans.
|
||||
var/icon_full
|
||||
/// The overlay when hovering over with an item in your hand
|
||||
var/list/object_overlays = list()
|
||||
layer = HUD_LAYER
|
||||
plane = HUD_PLANE
|
||||
|
||||
/obj/screen/inventory/Click(location, control, params)
|
||||
if(hud?.mymob && (hud.mymob != usr))
|
||||
return
|
||||
// just redirect clicks
|
||||
// At this point in client Click() code we have passed the 1/10 sec check and little else
|
||||
// We don't even know if it's a middle click
|
||||
// if(world.time <= usr.next_move)
|
||||
// return TRUE
|
||||
|
||||
if(usr.incapacitated()) // ignore_stasis = TRUE
|
||||
return TRUE
|
||||
if(ismecha(usr.loc)) // stops inventory actions in a mech
|
||||
return TRUE
|
||||
|
||||
if(hud?.mymob && slot_id)
|
||||
var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id)
|
||||
@@ -150,12 +175,13 @@
|
||||
var/image/item_overlay = image(holding)
|
||||
item_overlay.alpha = 92
|
||||
|
||||
if(!user.can_equip(holding, slot_id, TRUE, TRUE, TRUE))
|
||||
if(!user.can_equip(holding, slot_id, TRUE))
|
||||
item_overlay.color = "#FF0000"
|
||||
else
|
||||
item_overlay.color = "#00ff00"
|
||||
|
||||
object_overlays += item_overlay
|
||||
cut_overlay(object_overlays)
|
||||
// object_overlay = item_overlay
|
||||
add_overlay(object_overlays)
|
||||
|
||||
/obj/screen/inventory/hand
|
||||
@@ -187,10 +213,17 @@
|
||||
|
||||
|
||||
/obj/screen/inventory/hand/Click(location, control, params)
|
||||
if(hud?.mymob && (hud.mymob != usr))
|
||||
return
|
||||
var/mob/user = hud.mymob
|
||||
// just redirect clicks
|
||||
// At this point in client Click() code we have passed the 1/10 sec check and little else
|
||||
// We don't even know if it's a middle click
|
||||
var/mob/user = hud?.mymob
|
||||
if(usr != user)
|
||||
return TRUE
|
||||
// if(world.time <= user.next_move)
|
||||
// return TRUE
|
||||
if(user.incapacitated())
|
||||
return TRUE
|
||||
if (ismecha(user.loc)) // stops inventory actions in a mech
|
||||
return TRUE
|
||||
|
||||
if(user.active_hand_index == held_index)
|
||||
var/obj/item/I = user.get_active_held_item()
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
if(force && damtype != STAMINA && HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
to_chat(user, "<span class='warning'>You don't want to harm other living beings!</span>")
|
||||
return
|
||||
|
||||
|
||||
if(!UseStaminaBufferStandard(user, STAM_COST_ATTACK_MOB_MULT, null, TRUE))
|
||||
return DISCARD_LAST_ACTION
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
name = "Initializing..."
|
||||
var/target
|
||||
|
||||
INITIALIZE_IMMEDIATE(/obj/effect/statclick) //it's new, but rebranded.
|
||||
INITIALIZE_IMMEDIATE(/obj/effect/statclick)
|
||||
|
||||
/obj/effect/statclick/Initialize(mapload, text, target) //Don't port this to Initialize it's too critical
|
||||
. = ..()
|
||||
@@ -33,14 +33,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/statclick) //it's new, but rebranded.
|
||||
usr.client.debug_variables(target)
|
||||
message_admins("Admin [key_name_admin(usr)] is debugging the [target] [class].")
|
||||
|
||||
/obj/effect/statclick/misc_subsystems/Click()
|
||||
if(!usr.client.holder)
|
||||
return
|
||||
var/subsystem = input(usr, "Debug which subsystem?", "Debug nonprocessing subsystem") as null|anything in (Master.subsystems - Master.statworthy_subsystems)
|
||||
if(!subsystem)
|
||||
return
|
||||
usr.client.debug_variables(subsystem)
|
||||
message_admins("Admin [key_name_admin(usr)] is debugging the [subsystem] subsystem.")
|
||||
|
||||
// Debug verbs.
|
||||
/client/proc/restart_controller(controller in list("Master", "Failsafe"))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Failsafe
|
||||
*
|
||||
* Pretty much pokes the MC to make sure it's still alive.
|
||||
* Failsafe
|
||||
*
|
||||
* Pretty much pokes the MC to make sure it's still alive.
|
||||
**/
|
||||
|
||||
GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* StonedMC
|
||||
*
|
||||
* Designed to properly split up a given tick among subsystems
|
||||
* Note: if you read parts of this code and think "why is it doing it that way"
|
||||
* Odds are, there is a reason
|
||||
*
|
||||
/**
|
||||
* StonedMC
|
||||
*
|
||||
* Designed to properly split up a given tick among subsystems
|
||||
* Note: if you read parts of this code and think "why is it doing it that way"
|
||||
* Odds are, there is a reason
|
||||
*
|
||||
**/
|
||||
|
||||
//This is the ABSOLUTE ONLY THING that should init globally like this
|
||||
@@ -28,8 +28,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
|
||||
// List of subsystems to process().
|
||||
var/list/subsystems
|
||||
/// List of subsystems to include in the MC stat panel.
|
||||
var/list/statworthy_subsystems
|
||||
|
||||
// Vars for keeping track of tick drift.
|
||||
var/init_timeofday
|
||||
@@ -41,7 +39,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
///Only run ticker subsystems for the next n ticks.
|
||||
var/skip_ticks = 0
|
||||
|
||||
var/make_runtime = 0
|
||||
var/make_runtime = FALSE
|
||||
|
||||
var/initializations_finished_with_no_players_logged_in //I wonder what this could be?
|
||||
|
||||
@@ -67,9 +65,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
//used by CHECK_TICK as well so that the procs subsystems call can obey that SS's tick limits
|
||||
var/static/current_ticklimit = TICK_LIMIT_RUNNING
|
||||
|
||||
/// Statclick for misc subsystems
|
||||
var/obj/effect/statclick/misc_subsystems/misc_statclick
|
||||
|
||||
/datum/controller/master/New()
|
||||
if(!config)
|
||||
config = new
|
||||
@@ -96,11 +91,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
_subsystems += new I
|
||||
Master = src
|
||||
|
||||
// We want to see all subsystems during init.
|
||||
statworthy_subsystems = subsystems.Copy()
|
||||
|
||||
misc_statclick = new(null, "Debug")
|
||||
|
||||
if(!GLOB)
|
||||
new /datum/controller/global_vars
|
||||
|
||||
@@ -217,7 +207,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
// Sort subsystems by display setting for easy access.
|
||||
sortTim(subsystems, /proc/cmp_subsystem_display)
|
||||
// Set world options.
|
||||
world.fps = CONFIG_GET(number/fps)
|
||||
world.change_fps(CONFIG_GET(number/fps))
|
||||
var/initialized_tod = REALTIMEOFDAY
|
||||
|
||||
if(tgs_prime)
|
||||
@@ -271,14 +261,10 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
var/list/tickersubsystems = list()
|
||||
var/list/runlevel_sorted_subsystems = list(list()) //ensure we always have at least one runlevel
|
||||
var/timer = world.time
|
||||
statworthy_subsystems = list()
|
||||
for (var/thing in subsystems)
|
||||
var/datum/controller/subsystem/SS = thing
|
||||
if (SS.flags & SS_NO_FIRE)
|
||||
if(SS.flags & SS_ALWAYS_SHOW_STAT)
|
||||
statworthy_subsystems += SS
|
||||
continue
|
||||
statworthy_subsystems += SS
|
||||
SS.queued_time = 0
|
||||
SS.queue_next = null
|
||||
SS.queue_prev = null
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
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 = 0
|
||||
var/flags = NONE
|
||||
|
||||
/// This var is set to TRUE after the subsystem has been initialized.
|
||||
var/initialized = FALSE
|
||||
@@ -114,7 +114,7 @@
|
||||
//previously, this would have been named 'process()' but that name is used everywhere for different things!
|
||||
//fire() seems more suitable. This is the procedure that gets called every 'wait' deciseconds.
|
||||
//Sleeping in here prevents future fires until returned.
|
||||
/datum/controller/subsystem/proc/fire(resumed = 0)
|
||||
/datum/controller/subsystem/proc/fire(resumed = FALSE)
|
||||
flags |= SS_NO_FIRE
|
||||
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.")
|
||||
|
||||
|
||||
@@ -241,7 +241,8 @@ SUBSYSTEM_DEF(air)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_turf_equalize(resumed = 0)
|
||||
return process_turf_equalize_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag)
|
||||
if(process_turf_equalize_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag))
|
||||
pause()
|
||||
/*
|
||||
//cache for sanic speed
|
||||
var/fire_count = times_fired
|
||||
@@ -260,7 +261,8 @@ SUBSYSTEM_DEF(air)
|
||||
*/
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_active_turfs(resumed = 0)
|
||||
return process_active_turfs_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag)
|
||||
if(process_active_turfs_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag))
|
||||
pause()
|
||||
/*
|
||||
//cache for sanic speed
|
||||
var/fire_count = times_fired
|
||||
@@ -278,7 +280,8 @@ SUBSYSTEM_DEF(air)
|
||||
*/
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_excited_groups(resumed = 0)
|
||||
return process_excited_groups_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag)
|
||||
if(process_excited_groups_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag))
|
||||
pause()
|
||||
/*
|
||||
if (!resumed)
|
||||
src.currentrun = excited_groups.Copy()
|
||||
|
||||
@@ -11,7 +11,7 @@ SUBSYSTEM_DEF(assets)
|
||||
switch (CONFIG_GET(string/asset_transport))
|
||||
if ("webroot")
|
||||
newtransporttype = /datum/asset_transport/webroot
|
||||
|
||||
|
||||
if (newtransporttype == transport.type)
|
||||
return
|
||||
|
||||
|
||||
@@ -10,33 +10,37 @@ SUBSYSTEM_DEF(atoms)
|
||||
|
||||
var/old_initialized
|
||||
|
||||
var/list/late_loaders
|
||||
var/list/late_loaders = list()
|
||||
|
||||
var/list/BadInitializeCalls = list()
|
||||
|
||||
initialized = INITIALIZATION_INSSATOMS
|
||||
|
||||
/datum/controller/subsystem/atoms/Initialize(timeofday)
|
||||
GLOB.fire_overlay.appearance_flags = RESET_COLOR
|
||||
setupGenetics()
|
||||
setupGenetics() //to set the mutations' sequence
|
||||
|
||||
initialized = INITIALIZATION_INNEW_MAPLOAD
|
||||
InitializeAtoms()
|
||||
initialized = INITIALIZATION_INNEW_REGULAR
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms)
|
||||
if(initialized == INITIALIZATION_INSSATOMS)
|
||||
return
|
||||
|
||||
old_initialized = initialized
|
||||
initialized = INITIALIZATION_INNEW_MAPLOAD
|
||||
|
||||
LAZYINITLIST(late_loaders)
|
||||
|
||||
var/count
|
||||
var/list/mapload_arg = list(TRUE)
|
||||
|
||||
if(atoms)
|
||||
count = atoms.len
|
||||
for(var/I in atoms)
|
||||
var/atom/A = I
|
||||
for(var/I in 1 to count)
|
||||
var/atom/A = atoms[I]
|
||||
if(!(A.flags_1 & INITIALIZED_1))
|
||||
InitAtom(I, mapload_arg)
|
||||
InitAtom(A, mapload_arg)
|
||||
CHECK_TICK
|
||||
else
|
||||
count = 0
|
||||
@@ -49,15 +53,16 @@ SUBSYSTEM_DEF(atoms)
|
||||
testing("Initialized [count] atoms")
|
||||
pass(count)
|
||||
|
||||
initialized = INITIALIZATION_INNEW_REGULAR
|
||||
initialized = old_initialized
|
||||
|
||||
if(late_loaders.len)
|
||||
for(var/I in late_loaders)
|
||||
var/atom/A = I
|
||||
for(var/I in 1 to late_loaders.len)
|
||||
var/atom/A = late_loaders[I]
|
||||
A.LateInitialize()
|
||||
testing("Late initialized [late_loaders.len] atoms")
|
||||
late_loaders.Cut()
|
||||
|
||||
/// Init this specific atom
|
||||
/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments)
|
||||
var/the_type = A.type
|
||||
if(QDELING(A))
|
||||
@@ -150,8 +155,3 @@ SUBSYSTEM_DEF(atoms)
|
||||
var/initlog = InitLog()
|
||||
if(initlog)
|
||||
text2file(initlog, "[GLOB.log_directory]/initialize.log")
|
||||
|
||||
#undef BAD_INIT_QDEL_BEFORE
|
||||
#undef BAD_INIT_DIDNT_INIT
|
||||
#undef BAD_INIT_SLEPT
|
||||
#undef BAD_INIT_NO_HINT
|
||||
|
||||
@@ -14,12 +14,14 @@ SUBSYSTEM_DEF(blackbox)
|
||||
"explosion" = 2,
|
||||
"time_dilation_current" = 3,
|
||||
"science_techweb_unlock" = 2,
|
||||
"round_end_stats" = 2) //associative list of any feedback variables that have had their format changed since creation and their current version, remember to update this
|
||||
"round_end_stats" = 2,
|
||||
"testmerged_prs" = 2) //associative list of any feedback variables that have had their format changed since creation and their current version, remember to update this
|
||||
|
||||
/datum/controller/subsystem/blackbox/Initialize()
|
||||
triggertime = world.time
|
||||
record_feedback("amount", "random_seed", Master.random_seed)
|
||||
record_feedback("amount", "dm_version", DM_VERSION)
|
||||
record_feedback("amount", "dm_build", DM_BUILD)
|
||||
record_feedback("amount", "byond_version", world.byond_version)
|
||||
record_feedback("amount", "byond_build", world.byond_build)
|
||||
. = ..()
|
||||
@@ -39,10 +41,7 @@ SUBSYSTEM_DEF(blackbox)
|
||||
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
var/playercount = 0
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.client)
|
||||
playercount += 1
|
||||
var/playercount = LAZYLEN(GLOB.player_list)
|
||||
var/admincount = GLOB.admins.len
|
||||
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port, round_id) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]')")
|
||||
query_record_playercount.Execute()
|
||||
@@ -88,18 +87,24 @@ SUBSYSTEM_DEF(blackbox)
|
||||
if (!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
// var/list/special_columns = list(
|
||||
// "datetime" = "NOW()"
|
||||
// )
|
||||
var/list/sqlrowlist = list()
|
||||
|
||||
for (var/datum/feedback_variable/FV in feedback)
|
||||
var/sqlversion = 1
|
||||
if(FV.key in versions)
|
||||
sqlversion = versions[FV.key]
|
||||
sqlrowlist += list(list("datetime" = "Now()", "round_id" = GLOB.round_id, "key_name" = "'[sanitizeSQL(FV.key)]'", "key_type" = "'[FV.key_type]'", "version" = "[sqlversion]", "json" = "'[sanitizeSQL(json_encode(FV.json))]'"))
|
||||
sqlrowlist += list(list(
|
||||
"datetime" = "Now()", //legacy
|
||||
"round_id" = GLOB.round_id,
|
||||
"key_name" = sanitizeSQL(FV.key),
|
||||
"key_type" = FV.key_type,
|
||||
"version" = versions[FV.key] || 1,
|
||||
"json" = sanitizeSQL(json_encode(FV.json))
|
||||
))
|
||||
|
||||
if (!length(sqlrowlist))
|
||||
return
|
||||
|
||||
SSdbcore.MassInsert(format_table_name("feedback"), sqlrowlist, ignore_errors = TRUE, delayed = TRUE)
|
||||
SSdbcore.MassInsert(format_table_name("feedback"), sqlrowlist, ignore_errors = TRUE, delayed = TRUE)//, special_columns = special_columns)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/Seal()
|
||||
if(sealed)
|
||||
@@ -169,7 +174,7 @@ feedback data can be recorded in 5 formats:
|
||||
"tally"
|
||||
used to track the number of occurances of multiple related values i.e. how many times each type of gun is fired
|
||||
further calls to the same key will:
|
||||
add or subtract from the saved value of the data key if it already exists
|
||||
add or subtract from the saved value of the data key if it already exists
|
||||
append the key and it's value if it doesn't exist
|
||||
calls: SSblackbox.record_feedback("tally", "example", 1, "sample data")
|
||||
SSblackbox.record_feedback("tally", "example", 4, "sample data")
|
||||
@@ -181,7 +186,7 @@ feedback data can be recorded in 5 formats:
|
||||
the final element in the data list is used as the tracking key, all prior elements are used for nesting
|
||||
all data list elements must be strings
|
||||
further calls to the same key will:
|
||||
add or subtract from the saved value of the data key if it already exists in the same multi-dimensional position
|
||||
add or subtract from the saved value of the data key if it already exists in the same multi-dimensional position
|
||||
append the key and it's value if it doesn't exist
|
||||
calls: SSblackbox.record_feedback("nested tally", "example", 1, list("fruit", "orange", "apricot"))
|
||||
SSblackbox.record_feedback("nested tally", "example", 2, list("fruit", "orange", "orange"))
|
||||
@@ -270,6 +275,18 @@ Versioning
|
||||
/datum/feedback_variable/New(new_key, new_key_type)
|
||||
key = new_key
|
||||
key_type = new_key_type
|
||||
/*
|
||||
/datum/controller/subsystem/blackbox/proc/LogAhelp(ticket, action, message, recipient, sender)
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
var/datum/db_query/query_log_ahelp = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("ticket")] (ticket, action, message, recipient, sender, server_ip, server_port, round_id, timestamp)
|
||||
VALUES (:ticket, :action, :message, :recipient, :sender, INET_ATON(:server_ip), :server_port, :round_id, :time)
|
||||
"}, list("ticket" = ticket, "action" = action, "message" = message, "recipient" = recipient, "sender" = sender, "server_ip" = world.internet_address || "0", "server_port" = world.port, "round_id" = GLOB.round_id, "time" = SQLtime()))
|
||||
query_log_ahelp.Execute()
|
||||
qdel(query_log_ahelp)
|
||||
*/
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/ReportDeath(mob/living/L)
|
||||
set waitfor = FALSE
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*!
|
||||
* Copyright (c) 2020 Aleksej Komarov
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@@ -177,6 +177,25 @@ SUBSYSTEM_DEF(dbcore)
|
||||
return FALSE
|
||||
return new /datum/DBQuery(sql_query, connection)
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/QuerySelect(list/querys, warn = FALSE, qdel = FALSE)
|
||||
if (!islist(querys))
|
||||
if (!istype(querys, /datum/DBQuery))
|
||||
CRASH("Invalid query passed to QuerySelect: [querys]")
|
||||
querys = list(querys)
|
||||
|
||||
for (var/thing in querys)
|
||||
var/datum/DBQuery/query = thing
|
||||
if (warn)
|
||||
INVOKE_ASYNC(query, /datum/DBQuery.proc/warn_execute)
|
||||
else
|
||||
INVOKE_ASYNC(query, /datum/DBQuery.proc/Execute)
|
||||
|
||||
for (var/thing in querys)
|
||||
var/datum/DBQuery/query = thing
|
||||
UNTIL(!query.in_progress)
|
||||
if (qdel)
|
||||
qdel(query)
|
||||
|
||||
/*
|
||||
Takes a list of rows (each row being an associated list of column => value) and inserts them via a single mass query.
|
||||
Rows missing columns present in other rows will resolve to SQL NULL
|
||||
@@ -361,5 +380,5 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
|
||||
//strip sensitive stuff
|
||||
if(findtext(message, ": CreateConnection("))
|
||||
message = "CreateConnection CENSORED"
|
||||
|
||||
|
||||
log_sql("BSQL_DEBUG: [message]")
|
||||
|
||||
@@ -25,7 +25,7 @@ SUBSYSTEM_DEF(events)
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/events/fire(resumed = 0)
|
||||
/datum/controller/subsystem/events/fire(resumed = FALSE)
|
||||
if(!resumed)
|
||||
checkEvent() //only check these if we aren't resuming a paused fire
|
||||
src.currentrun = running.Copy()
|
||||
@@ -37,7 +37,7 @@ SUBSYSTEM_DEF(events)
|
||||
var/datum/thing = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(thing)
|
||||
thing.process()
|
||||
thing.process(wait * 0.1)
|
||||
else
|
||||
running.Remove(thing)
|
||||
if (MC_TICK_CHECK)
|
||||
@@ -91,13 +91,13 @@ SUBSYSTEM_DEF(events)
|
||||
if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0
|
||||
E.max_occurrences = 0
|
||||
else if(. == EVENT_READY)
|
||||
E.random = TRUE
|
||||
E.runEvent(TRUE)
|
||||
E.runEvent(random = TRUE)
|
||||
|
||||
//allows a client to trigger an event
|
||||
//aka Badmin Central
|
||||
// > Not in modules/admin
|
||||
// REEEEEEEEE
|
||||
// Why the heck is this here! Took me so damn long to find!
|
||||
/client/proc/forceEvent()
|
||||
set name = "Trigger Event"
|
||||
set category = "Admin.Events"
|
||||
|
||||
@@ -18,6 +18,7 @@ SUBSYSTEM_DEF(fire_burning)
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
var/delta_time = wait * 0.1
|
||||
|
||||
while(currentrun.len)
|
||||
var/obj/O = currentrun[currentrun.len]
|
||||
@@ -28,10 +29,12 @@ SUBSYSTEM_DEF(fire_burning)
|
||||
return
|
||||
continue
|
||||
|
||||
if(O.resistance_flags & ON_FIRE)
|
||||
O.take_damage(20, BURN, "fire", 0)
|
||||
else
|
||||
processing -= O
|
||||
|
||||
if(O.resistance_flags & ON_FIRE) //in case an object is extinguished while still in currentrun
|
||||
if(!(O.resistance_flags & FIRE_PROOF))
|
||||
O.take_damage(10 * delta_time, BURN, "fire", 0)
|
||||
else
|
||||
O.extinguish()
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
/*!
|
||||
## Debugging GC issues
|
||||
|
||||
In order to debug `qdel()` failures, there are several tools available.
|
||||
To enable these tools, define `TESTING` in [_compile_options.dm](https://github.com/tgstation/-tg-station/blob/master/code/_compile_options.dm).
|
||||
|
||||
First is a verb called "Find References", which lists **every** refererence to an object in the world. This allows you to track down any indirect or obfuscated references that you might have missed.
|
||||
|
||||
Complementing this is another verb, "qdel() then Find References".
|
||||
This does exactly what you'd expect; it calls `qdel()` on the object and then it finds all references remaining.
|
||||
This is great, because it means that `Destroy()` will have been called before it starts to find references,
|
||||
so the only references you'll find will be the ones preventing the object from `qdel()`ing gracefully.
|
||||
|
||||
If you have a datum or something you are not destroying directly (say via the singulo),
|
||||
the next tool is `QDEL_HINT_FINDREFERENCE`. You can return this in `Destroy()` (where you would normally `return ..()`),
|
||||
to print a list of references once it enters the GC queue.
|
||||
|
||||
Finally is a verb, "Show qdel() Log", which shows the deletion log that the garbage subsystem keeps. This is helpful if you are having race conditions or need to review the order of deletions.
|
||||
|
||||
Note that for any of these tools to work `TESTING` must be defined.
|
||||
By using these methods of finding references, you can make your life far, far easier when dealing with `qdel()` failures.
|
||||
*/
|
||||
|
||||
SUBSYSTEM_DEF(garbage)
|
||||
name = "Garbage"
|
||||
priority = FIRE_PRIORITY_GARBAGE
|
||||
@@ -6,7 +29,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
init_order = INIT_ORDER_GARBAGE
|
||||
|
||||
var/list/collection_timeout = list(15 SECONDS, 30 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
|
||||
var/list/collection_timeout = list(2 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
|
||||
|
||||
//Stat tracking
|
||||
var/delslasttick = 0 // number of del()'s we've done this tick
|
||||
@@ -24,10 +47,8 @@ SUBSYSTEM_DEF(garbage)
|
||||
|
||||
//Queue
|
||||
var/list/queues
|
||||
|
||||
#ifdef LEGACY_REFERENCE_TRACKING
|
||||
var/list/reference_find_on_fail = list()
|
||||
var/list/reference_find_on_fail_types = list()
|
||||
#endif
|
||||
|
||||
|
||||
@@ -99,6 +120,9 @@ SUBSYSTEM_DEF(garbage)
|
||||
state = SS_RUNNING
|
||||
break
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/controller/subsystem/garbage/proc/HandleQueue(level = GC_QUEUE_CHECK)
|
||||
if (level == GC_QUEUE_CHECK)
|
||||
delslasttick = 0
|
||||
@@ -139,7 +163,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
++totalgcs
|
||||
pass_counts[level]++
|
||||
#ifdef LEGACY_REFERENCE_TRACKING
|
||||
reference_find_on_fail -= refID //It's deleted we don't care anymore.
|
||||
reference_find_on_fail -= refID //It's deleted we don't care anymore.
|
||||
#endif
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
@@ -153,10 +177,10 @@ SUBSYSTEM_DEF(garbage)
|
||||
D.find_references()
|
||||
#elif defined(LEGACY_REFERENCE_TRACKING)
|
||||
if(reference_find_on_fail[refID])
|
||||
D.find_references()
|
||||
D.find_references_legacy()
|
||||
#ifdef GC_FAILURE_HARD_LOOKUP
|
||||
else
|
||||
D.find_references()
|
||||
D.find_references_legacy()
|
||||
#endif
|
||||
reference_find_on_fail -= refID
|
||||
#endif
|
||||
@@ -190,24 +214,6 @@ SUBSYSTEM_DEF(garbage)
|
||||
queue.Cut(1,count+1)
|
||||
count = 0
|
||||
|
||||
/datum/controller/subsystem/garbage/proc/Queue(datum/D, level = GC_QUEUE_CHECK)
|
||||
if (isnull(D))
|
||||
return
|
||||
if (level > GC_QUEUE_COUNT)
|
||||
HardDelete(D)
|
||||
return
|
||||
var/gctime = world.time
|
||||
var/refid = "\ref[D]"
|
||||
|
||||
#ifdef LEGACY_REFERENCE_TRACKING
|
||||
if(reference_find_on_fail_types[D.type])
|
||||
reference_find_on_fail["\ref[D]"] = TRUE
|
||||
#endif
|
||||
|
||||
D.gc_destroyed = gctime
|
||||
var/list/queue = queues[level]
|
||||
queue[++queue.len] = list(gctime, refid) // not += for byond reasons
|
||||
|
||||
#ifdef LEGACY_REFERENCE_TRACKING
|
||||
/datum/controller/subsystem/garbage/proc/add_type_to_findref(type)
|
||||
if(!ispath(type))
|
||||
@@ -223,6 +229,24 @@ SUBSYSTEM_DEF(garbage)
|
||||
reference_find_on_fail_types = list()
|
||||
#endif
|
||||
|
||||
/datum/controller/subsystem/garbage/proc/Queue(datum/D, level = GC_QUEUE_CHECK)
|
||||
if (isnull(D))
|
||||
return
|
||||
if (level > GC_QUEUE_COUNT)
|
||||
HardDelete(D)
|
||||
return
|
||||
var/gctime = world.time
|
||||
var/refid = "\ref[D]"
|
||||
|
||||
#ifdef LEGACY_REFERENCE_TRACKING
|
||||
if(reference_find_on_fail_types[D.type])
|
||||
SSgarbage.reference_find_on_fail[REF(D)] = TRUE
|
||||
#endif
|
||||
|
||||
D.gc_destroyed = gctime
|
||||
var/list/queue = queues[level]
|
||||
queue[++queue.len] = list(gctime, refid) // not += for byond reasons
|
||||
|
||||
//this is mainly to separate things profile wise.
|
||||
/datum/controller/subsystem/garbage/proc/HardDelete(datum/D)
|
||||
var/time = world.timeofday
|
||||
@@ -275,8 +299,10 @@ SUBSYSTEM_DEF(garbage)
|
||||
/datum/qdel_item/New(mytype)
|
||||
name = "[mytype]"
|
||||
|
||||
// Should be treated as a replacement for the 'del' keyword.
|
||||
// Datums passed to this will be given a chance to clean up references to allow the GC to collect them.
|
||||
|
||||
/// Should be treated as a replacement for the 'del' keyword.
|
||||
///
|
||||
/// Datums passed to this will be given a chance to clean up references to allow the GC to collect them.
|
||||
/proc/qdel(datum/D, force=FALSE, ...)
|
||||
if(!istype(D))
|
||||
del(D)
|
||||
@@ -331,9 +357,10 @@ SUBSYSTEM_DEF(garbage)
|
||||
#ifdef LEGACY_REFERENCE_TRACKING
|
||||
if (QDEL_HINT_FINDREFERENCE) //qdel will, if LEGACY_REFERENCE_TRACKING is enabled, display all references to this object, then queue the object for deletion.
|
||||
SSgarbage.Queue(D)
|
||||
D.find_references_legacy()
|
||||
if (QDEL_HINT_IFFAIL_FINDREFERENCE)
|
||||
SSgarbage.Queue(D)
|
||||
SSgarbage.reference_find_on_fail["\ref[D]"] = TRUE
|
||||
SSgarbage.reference_find_on_fail[REF(D)] = TRUE
|
||||
#endif
|
||||
else
|
||||
#ifdef TESTING
|
||||
|
||||
@@ -33,8 +33,9 @@ SUBSYSTEM_DEF(idlenpcpool)
|
||||
while(currentrun.len)
|
||||
var/mob/living/simple_animal/SA = currentrun[currentrun.len]
|
||||
--currentrun.len
|
||||
if (!SA)
|
||||
if (QDELETED(SA))
|
||||
GLOB.simple_animals[AI_IDLE] -= SA
|
||||
log_world("Found a null in simple_animals list!")
|
||||
continue
|
||||
|
||||
if(!SA.ckey)
|
||||
|
||||
@@ -2,13 +2,13 @@ SUBSYSTEM_DEF(ipintel)
|
||||
name = "XKeyScore"
|
||||
init_order = INIT_ORDER_XKEYSCORE
|
||||
flags = SS_NO_FIRE
|
||||
var/enabled = 0 //disable at round start to avoid checking reconnects
|
||||
var/enabled = FALSE //disable at round start to avoid checking reconnects
|
||||
var/throttle = 0
|
||||
var/errors = 0
|
||||
|
||||
var/list/cache = list()
|
||||
|
||||
/datum/controller/subsystem/ipintel/Initialize(timeofday, zlevel)
|
||||
enabled = 1
|
||||
enabled = TRUE
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -691,21 +691,29 @@ SUBSYSTEM_DEF(job)
|
||||
if(!permitted)
|
||||
continue
|
||||
var/obj/item/I = new G.path
|
||||
if(I && length(i[LOADOUT_COLOR])) //handle loadout colors
|
||||
//handle polychromic items
|
||||
if((G.loadout_flags & LOADOUT_CAN_COLOR_POLYCHROMIC) && length(G.loadout_initial_colors))
|
||||
var/datum/element/polychromic/polychromic = I.comp_lookup["item_worn_overlays"] //stupid way to do it but GetElement does not work for this
|
||||
if(polychromic && istype(polychromic))
|
||||
var/list/polychromic_entry = polychromic.colors_by_atom[I]
|
||||
if(polychromic_entry)
|
||||
if(polychromic.suits_with_helmet_typecache[I.type]) //is this one of those toggleable hood/helmet things?
|
||||
polychromic.connect_helmet(I,i[LOADOUT_COLOR])
|
||||
polychromic.colors_by_atom[I] = i[LOADOUT_COLOR]
|
||||
I.update_icon()
|
||||
else
|
||||
//handle non-polychromic items (they only have one color)
|
||||
I.add_atom_colour(i[LOADOUT_COLOR][1], FIXED_COLOUR_PRIORITY)
|
||||
I.update_icon()
|
||||
if(I)
|
||||
if(length(i[LOADOUT_COLOR])) //handle loadout colors
|
||||
//handle polychromic items
|
||||
if((G.loadout_flags & LOADOUT_CAN_COLOR_POLYCHROMIC) && length(G.loadout_initial_colors))
|
||||
var/datum/element/polychromic/polychromic = I.comp_lookup["item_worn_overlays"] //stupid way to do it but GetElement does not work for this
|
||||
if(polychromic && istype(polychromic))
|
||||
var/list/polychromic_entry = polychromic.colors_by_atom[I]
|
||||
if(polychromic_entry)
|
||||
if(polychromic.suits_with_helmet_typecache[I.type]) //is this one of those toggleable hood/helmet things?
|
||||
polychromic.connect_helmet(I,i[LOADOUT_COLOR])
|
||||
polychromic.colors_by_atom[I] = i[LOADOUT_COLOR]
|
||||
I.update_icon()
|
||||
else
|
||||
//handle non-polychromic items (they only have one color)
|
||||
I.add_atom_colour(i[LOADOUT_COLOR][1], FIXED_COLOUR_PRIORITY)
|
||||
I.update_icon()
|
||||
//when inputting the data it's already sanitized
|
||||
if(i[LOADOUT_CUSTOM_NAME])
|
||||
var/custom_name = i[LOADOUT_CUSTOM_NAME]
|
||||
I.name = custom_name
|
||||
if(i[LOADOUT_CUSTOM_DESCRIPTION])
|
||||
var/custom_description = i[LOADOUT_CUSTOM_DESCRIPTION]
|
||||
I.desc = custom_description
|
||||
if(!M.equip_to_slot_if_possible(I, G.slot, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // If the job's dresscode compliant, try to put it in its slot, first
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
|
||||
@@ -94,8 +94,8 @@ SUBSYSTEM_DEF(jukeboxes)
|
||||
stack_trace("Nonexistant or invalid object associated with jukebox.")
|
||||
continue
|
||||
var/sound/song_played = sound(juketrack.song_path)
|
||||
var/area/currentarea = get_area(jukebox)
|
||||
var/turf/currentturf = get_turf(jukebox)
|
||||
var/area/currentarea = get_area(jukebox)
|
||||
var/list/hearerscache = hearers(7, jukebox)
|
||||
|
||||
song_played.falloff = jukeinfo[4]
|
||||
@@ -116,7 +116,6 @@ SUBSYSTEM_DEF(jukeboxes)
|
||||
inrange = TRUE
|
||||
else
|
||||
song_played.status = SOUND_MUTE | SOUND_UPDATE //Setting volume = 0 doesn't let the sound properties update at all, which is lame.
|
||||
|
||||
M.playsound_local(currentturf, null, 100, channel = jukeinfo[2], S = song_played, envwet = (inrange ? -250 : 0), envdry = (inrange ? 0 : -10000))
|
||||
CHECK_TICK
|
||||
return
|
||||
|
||||
@@ -6,6 +6,7 @@ SUBSYSTEM_DEF(lighting)
|
||||
name = "Lighting"
|
||||
wait = 2
|
||||
init_order = INIT_ORDER_LIGHTING
|
||||
flags = SS_TICKER
|
||||
|
||||
/datum/controller/subsystem/lighting/stat_entry(msg)
|
||||
msg = "L:[length(GLOB.lighting_update_lights)]|C:[length(GLOB.lighting_update_corners)]|O:[length(GLOB.lighting_update_objects)]"
|
||||
|
||||
@@ -2,6 +2,7 @@ SUBSYSTEM_DEF(machines)
|
||||
name = "Machines"
|
||||
init_order = INIT_ORDER_MACHINES
|
||||
flags = SS_KEEP_TIMING
|
||||
wait = 2 SECONDS
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
var/list/powernets = list()
|
||||
@@ -27,7 +28,7 @@ SUBSYSTEM_DEF(machines)
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/machines/fire(resumed = 0)
|
||||
/datum/controller/subsystem/machines/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
for(var/datum/powernet/Powernet in powernets)
|
||||
Powernet.reset() //reset the power state.
|
||||
@@ -36,11 +37,10 @@ SUBSYSTEM_DEF(machines)
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
var/seconds = wait * 0.1
|
||||
while(currentrun.len)
|
||||
var/obj/machinery/thing = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(!QDELETED(thing) && thing.process(seconds) != PROCESS_KILL)
|
||||
if(!QDELETED(thing) && thing.process(wait * 0.1) != PROCESS_KILL)
|
||||
if(thing.use_power)
|
||||
thing.auto_use_power() //add back the power state
|
||||
else
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(min_spawns)
|
||||
name = "Minimum Spawns" /// this hot steaming pile of garbage makes sure theres a minimum of tendrils scattered around
|
||||
init_order = INIT_ORDER_DEFAULT
|
||||
flags = SS_BACKGROUND | SS_NO_FIRE | SS_ALWAYS_SHOW_STAT
|
||||
flags = SS_BACKGROUND | SS_NO_FIRE
|
||||
wait = 2
|
||||
var/where_we_droppin_boys_iterations = 0
|
||||
var/snaxi_snowflake_check = FALSE
|
||||
@@ -71,7 +71,7 @@ GLOBAL_LIST_INIT(minimum_snow_under_spawns, list(
|
||||
continue
|
||||
if(typesof(/turf/open/lava) in orange(9, TT))
|
||||
continue
|
||||
valid_mining_turfs_2.Add(TT)
|
||||
valid_mining_turfs_2.Add(TT)
|
||||
else
|
||||
for(var/z_level in SSmapping.levels_by_trait(ZTRAIT_LAVA_RUINS))
|
||||
for(var/turf/TT in Z_TURFS(z_level))
|
||||
@@ -103,14 +103,14 @@ GLOBAL_LIST_INIT(minimum_snow_under_spawns, list(
|
||||
for(var/mob/living/simple_animal/hostile/megafauna/H in urange(70,RT)) //prevents mob clumps
|
||||
if((istype(MS_tospawn, /mob/living/simple_animal/hostile/megafauna)) && get_dist(RT, H) <= 70)
|
||||
active_spawns.Add(MS_tospawn)
|
||||
continue //let's try not to dump megas too close to each other?
|
||||
continue //let's try not to dump megas too close to each other?
|
||||
if((istype(MS_tospawn, /obj/structure/spawner)) && get_dist(RT, H) <= 40)
|
||||
active_spawns.Add(MS_tospawn)
|
||||
continue //let's at least /try/ to space these out?
|
||||
for(var/obj/structure/spawner/LT in urange(70,RT)) //prevents tendril/mega clumps
|
||||
if((istype(MS_tospawn, /mob/living/simple_animal/hostile/megafauna)) && get_dist(RT, LT) <= 70)
|
||||
active_spawns.Add(MS_tospawn)
|
||||
continue //let's try not to dump megas too close to each other?
|
||||
continue //let's try not to dump megas too close to each other?
|
||||
if((istype(MS_tospawn, /obj/structure/spawner)) && get_dist(RT, LT) <= 40)
|
||||
active_spawns.Add(MS_tospawn)
|
||||
continue //let's at least /try/ to space these out?
|
||||
@@ -127,7 +127,7 @@ GLOBAL_LIST_INIT(minimum_snow_under_spawns, list(
|
||||
for(var/mob/living/simple_animal/hostile/H in urange(70,RT2)) //prevents mob clumps
|
||||
if((istype(MS2_tospawn, /mob/living/simple_animal/hostile/megafauna) || ismegafauna(H)) && get_dist(RT2, H) <= 70)
|
||||
active_spawns_2.Add(MS2_tospawn)
|
||||
continue //let's try not to dump megas too close to each other?
|
||||
continue //let's try not to dump megas too close to each other?
|
||||
if((istype(MS2_tospawn, /obj/structure/spawner)) && get_dist(RT2, H) <= 40)
|
||||
active_spawns_2.Add(MS2_tospawn)
|
||||
continue //let's at least /try/ to space these out?
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define PROB_MOUSE_SPAWN 98
|
||||
|
||||
SUBSYSTEM_DEF(minor_mapping)
|
||||
name = "Minor Mapping"
|
||||
init_order = INIT_ORDER_MINOR_MAPPING
|
||||
@@ -5,29 +7,43 @@ SUBSYSTEM_DEF(minor_mapping)
|
||||
|
||||
/datum/controller/subsystem/minor_mapping/Initialize(timeofday)
|
||||
trigger_migration(CONFIG_GET(number/mice_roundstart))
|
||||
// place_satchels()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/minor_mapping/proc/trigger_migration(num_mice=10)
|
||||
var/list/exposed_wires = find_exposed_wires()
|
||||
|
||||
var/mob/living/simple_animal/mouse/M
|
||||
var/mob/living/simple_animal/mouse/mouse
|
||||
var/turf/proposed_turf
|
||||
|
||||
while((num_mice > 0) && exposed_wires.len)
|
||||
proposed_turf = pick_n_take(exposed_wires)
|
||||
if(!M)
|
||||
M = new(proposed_turf)
|
||||
else
|
||||
M.forceMove(proposed_turf)
|
||||
if(M.environment_is_safe())
|
||||
num_mice -= 1
|
||||
M = null
|
||||
if(prob(PROB_MOUSE_SPAWN))
|
||||
if(!mouse)
|
||||
mouse = new(proposed_turf)
|
||||
else
|
||||
mouse.forceMove(proposed_turf)
|
||||
// else
|
||||
// mouse = new /mob/living/simple_animal/hostile/regalrat/controlled(proposed_turf)
|
||||
if(mouse.environment_is_safe())
|
||||
num_mice -= 1
|
||||
mouse = null
|
||||
|
||||
// /datum/controller/subsystem/minor_mapping/proc/place_satchels(amount=10)
|
||||
// var/list/turfs = find_satchel_suitable_turfs()
|
||||
|
||||
// while(turfs.len && amount > 0)
|
||||
// var/turf/T = pick_n_take(turfs)
|
||||
// var/obj/item/storage/backpack/satchel/flat/F = new(T)
|
||||
|
||||
// SEND_SIGNAL(F, COMSIG_OBJ_HIDE, T.intact)
|
||||
// amount--
|
||||
|
||||
/proc/find_exposed_wires()
|
||||
var/list/exposed_wires = list()
|
||||
exposed_wires.Cut()
|
||||
|
||||
var/list/all_turfs
|
||||
for (var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
all_turfs += block(locate(1,1,z), locate(world.maxx,world.maxy,z))
|
||||
for(var/turf/open/floor/plating/T in all_turfs)
|
||||
if(is_blocked_turf(T))
|
||||
@@ -36,3 +52,15 @@ SUBSYSTEM_DEF(minor_mapping)
|
||||
exposed_wires += T
|
||||
|
||||
return shuffle(exposed_wires)
|
||||
|
||||
// /proc/find_satchel_suitable_turfs()
|
||||
// var/list/suitable = list()
|
||||
|
||||
// for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
// for(var/t in block(locate(1,1,z), locate(world.maxx,world.maxy,z)))
|
||||
// if(isfloorturf(t) && !isplatingturf(t))
|
||||
// suitable += t
|
||||
|
||||
// return shuffle(suitable)
|
||||
|
||||
#undef PROB_MOUSE_SPAWN
|
||||
|
||||
@@ -48,9 +48,16 @@ SUBSYSTEM_DEF(overlays)
|
||||
for (var/thing in queue)
|
||||
count++
|
||||
if(thing)
|
||||
STAT_START_STOPWATCH
|
||||
var/atom/A = thing
|
||||
if(A.overlays.len >= MAX_ATOM_OVERLAYS)
|
||||
//Break it real GOOD
|
||||
stack_trace("Too many overlays on [A.type] - [A.overlays.len], refusing to update and cutting")
|
||||
A.overlays.Cut()
|
||||
continue
|
||||
STAT_START_STOPWATCH
|
||||
COMPILE_OVERLAYS(A)
|
||||
UNSETEMPTY(A.add_overlays)
|
||||
UNSETEMPTY(A.remove_overlays)
|
||||
STAT_STOP_STOPWATCH
|
||||
STAT_LOG_ENTRY(stats, A.type)
|
||||
if(mc_check)
|
||||
@@ -117,9 +124,8 @@ SUBSYSTEM_DEF(overlays)
|
||||
#define QUEUE_FOR_COMPILE flags_1 |= OVERLAY_QUEUED_1; SSoverlays.queue += src;
|
||||
/atom/proc/cut_overlays()
|
||||
LAZYINITLIST(remove_overlays)
|
||||
LAZYINITLIST(add_overlays)
|
||||
remove_overlays = overlays.Copy()
|
||||
add_overlays.Cut()
|
||||
add_overlays = null
|
||||
|
||||
//If not already queued for work and there are overlays to remove
|
||||
if(NOT_QUEUED_ALREADY && remove_overlays.len)
|
||||
@@ -129,7 +135,7 @@ SUBSYSTEM_DEF(overlays)
|
||||
if(!overlays)
|
||||
return
|
||||
overlays = build_appearance_list(overlays)
|
||||
LAZYINITLIST(add_overlays) //always initialized after this point
|
||||
LAZYINITLIST(add_overlays)
|
||||
LAZYINITLIST(remove_overlays)
|
||||
var/a_len = add_overlays.len
|
||||
var/r_len = remove_overlays.len
|
||||
@@ -140,8 +146,9 @@ SUBSYSTEM_DEF(overlays)
|
||||
var/fr_len = remove_overlays.len
|
||||
|
||||
//If not already queued and there is work to be done
|
||||
if(NOT_QUEUED_ALREADY && (fa_len != a_len || fr_len != r_len))
|
||||
if(NOT_QUEUED_ALREADY && (fa_len != a_len || fr_len != r_len ))
|
||||
QUEUE_FOR_COMPILE
|
||||
UNSETEMPTY(add_overlays)
|
||||
|
||||
/atom/proc/add_overlay(list/overlays)
|
||||
if(!overlays)
|
||||
|
||||
@@ -7,13 +7,21 @@ SUBSYSTEM_DEF(parallax)
|
||||
var/list/currentrun
|
||||
var/planet_x_offset = 128
|
||||
var/planet_y_offset = 128
|
||||
var/random_layer
|
||||
var/random_parallax_color
|
||||
|
||||
/datum/controller/subsystem/parallax/Initialize(timeofday)
|
||||
|
||||
//These are cached per client so needs to be done asap so people joining at roundstart do not miss these.
|
||||
/datum/controller/subsystem/parallax/PreInit()
|
||||
. = ..()
|
||||
if(prob(70)) //70% chance to pick a special extra layer
|
||||
random_layer = pick(/obj/screen/parallax_layer/random/space_gas, /obj/screen/parallax_layer/random/asteroids)
|
||||
random_parallax_color = pick(COLOR_TEAL, COLOR_GREEN, COLOR_YELLOW, COLOR_CYAN, COLOR_ORANGE, COLOR_PURPLE)//Special color for random_layer1. Has to be done here so everyone sees the same color. [COLOR_SILVER]
|
||||
planet_y_offset = rand(100, 160)
|
||||
planet_x_offset = rand(100, 160)
|
||||
|
||||
/datum/controller/subsystem/parallax/fire(resumed = 0)
|
||||
|
||||
/datum/controller/subsystem/parallax/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
src.currentrun = GLOB.clients.Copy()
|
||||
|
||||
@@ -21,24 +29,27 @@ SUBSYSTEM_DEF(parallax)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while(length(currentrun))
|
||||
var/client/C = currentrun[currentrun.len]
|
||||
var/client/processing_client = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if (!C || !C.eye)
|
||||
if (QDELETED(processing_client) || !processing_client.eye)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
var/atom/movable/A = C.eye
|
||||
if(!istype(A))
|
||||
continue
|
||||
for (A; isloc(A.loc) && !isturf(A.loc); A = A.loc);
|
||||
|
||||
if(A != C.movingmob)
|
||||
if(C.movingmob != null)
|
||||
C.movingmob.client_mobs_in_contents -= C.mob
|
||||
UNSETEMPTY(C.movingmob.client_mobs_in_contents)
|
||||
LAZYINITLIST(A.client_mobs_in_contents)
|
||||
A.client_mobs_in_contents += C.mob
|
||||
C.movingmob = A
|
||||
var/atom/movable/movable_eye = processing_client.eye
|
||||
if(!istype(movable_eye))
|
||||
continue
|
||||
|
||||
for (movable_eye; isloc(movable_eye.loc) && !isturf(movable_eye.loc); movable_eye = movable_eye.loc);
|
||||
|
||||
if(movable_eye == processing_client.movingmob)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
if(!isnull(processing_client.movingmob))
|
||||
LAZYREMOVE(processing_client.movingmob.client_mobs_in_contents, processing_client.mob)
|
||||
LAZYADD(movable_eye.client_mobs_in_contents, processing_client.mob)
|
||||
processing_client.movingmob = movable_eye
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
currentrun = null
|
||||
|
||||
@@ -18,7 +18,7 @@ SUBSYSTEM_DEF(pathfinder)
|
||||
var/free
|
||||
var/list/flow
|
||||
|
||||
/datum/flowcache/New(var/n)
|
||||
/datum/flowcache/New(n)
|
||||
. = ..()
|
||||
lcount = n
|
||||
run = 0
|
||||
|
||||
@@ -58,6 +58,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
if(CONFIG_GET(flag/use_antag_rep))
|
||||
LoadAntagReputation()
|
||||
LoadRandomizedRecipes()
|
||||
LoadPaintings()
|
||||
|
||||
/**
|
||||
* Saves persistent data relevant to the server: Configurations, past gamemodes, votes, antag rep, etc
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
//Fires five times every second.
|
||||
|
||||
PROCESSING_SUBSYSTEM_DEF(fastprocess)
|
||||
name = "Fast Processing"
|
||||
wait = 2
|
||||
wait = 0.2 SECONDS
|
||||
stat_tag = "FP"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(nanites)
|
||||
name = "Nanites"
|
||||
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
|
||||
wait = 10
|
||||
wait = 1 SECONDS
|
||||
|
||||
var/list/datum/nanite_cloud_backup/cloud_backups = list()
|
||||
var/list/mob/living/nanite_monitored_mobs = list()
|
||||
|
||||
@@ -2,4 +2,4 @@ PROCESSING_SUBSYSTEM_DEF(obj)
|
||||
name = "Objects"
|
||||
priority = FIRE_PRIORITY_OBJ
|
||||
flags = SS_NO_INIT
|
||||
wait = 20
|
||||
wait = 2 SECONDS
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
//Used to process objects. Fires once every second.
|
||||
//Used to process objects.
|
||||
|
||||
SUBSYSTEM_DEF(processing)
|
||||
name = "Processing"
|
||||
priority = FIRE_PRIORITY_PROCESS
|
||||
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
|
||||
wait = 10
|
||||
wait = 1 SECONDS
|
||||
|
||||
var/stat_tag = "P" //Used for logging
|
||||
var/list/processing = list()
|
||||
@@ -14,9 +14,10 @@ SUBSYSTEM_DEF(processing)
|
||||
msg = "[stat_tag]:[length(processing)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/processing/fire(resumed = 0)
|
||||
/datum/controller/subsystem/processing/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
currentrun = processing.Copy()
|
||||
var/delta_time = (flags & SS_TICKER)? (wait * world.tick_lag * 0.1) : (wait * 0.1)
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/current_run = currentrun
|
||||
|
||||
@@ -25,12 +26,26 @@ SUBSYSTEM_DEF(processing)
|
||||
current_run.len--
|
||||
if(QDELETED(thing))
|
||||
processing -= thing
|
||||
else if(thing.process(wait) == PROCESS_KILL)
|
||||
else if(thing.process(delta_time) == PROCESS_KILL)
|
||||
// fully stop so that a future START_PROCESSING will work
|
||||
STOP_PROCESSING(src, thing)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/proc/process()
|
||||
set waitfor = 0
|
||||
|
||||
/**
|
||||
* This proc is called on a datum on every "cycle" if it is being processed by a subsystem. The time between each cycle is determined by the subsystem's "wait" setting.
|
||||
* You can start and stop processing a datum using the START_PROCESSING and STOP_PROCESSING defines.
|
||||
*
|
||||
* Since the wait setting of a subsystem can be changed at any time, it is important that any rate-of-change that you implement in this proc is multiplied by the delta_time that is sent as a parameter,
|
||||
* Additionally, any "prob" you use in this proc should instead use the DT_PROB define to make sure that the final probability per second stays the same even if the subsystem's wait is altered.
|
||||
* Examples where this must be considered:
|
||||
* - Implementing a cooldown timer, use `mytimer -= delta_time`, not `mytimer -= 1`. This way, `mytimer` will always have the unit of seconds
|
||||
* - Damaging a mob, do `L.adjustFireLoss(20 * delta_time)`, not `L.adjustFireLoss(20)`. This way, the damage per second stays constant even if the wait of the subsystem is changed
|
||||
* - Probability of something happening, do `if(DT_PROB(25, delta_time))`, not `if(prob(25))`. This way, if the subsystem wait is e.g. lowered, there won't be a higher chance of this event happening per second
|
||||
*
|
||||
* If you override this do not call parent, as it will return PROCESS_KILL. This is done to prevent objects that dont override process() from staying in the processing list
|
||||
*/
|
||||
/datum/proc/process(delta_time)
|
||||
set waitfor = FALSE
|
||||
return PROCESS_KILL
|
||||
|
||||
@@ -5,8 +5,8 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
name = "Quirks"
|
||||
init_order = INIT_ORDER_QUIRKS
|
||||
flags = SS_BACKGROUND
|
||||
wait = 10
|
||||
runlevels = RUNLEVEL_GAME
|
||||
wait = 1 SECONDS
|
||||
|
||||
var/list/quirks = list() //Assoc. list of all roundstart quirk datum types; "name" = /path/
|
||||
var/list/quirk_names_by_path = list()
|
||||
|
||||
@@ -18,7 +18,7 @@ SUBSYSTEM_DEF(profiler)
|
||||
if(CONFIG_GET(flag/auto_profile))
|
||||
StartProfiling()
|
||||
else
|
||||
StopProfiling() //Stop the early start from world/New
|
||||
StopProfiling() //Stop the early start profiler
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/profiler/fire()
|
||||
@@ -31,12 +31,23 @@ SUBSYSTEM_DEF(profiler)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/profiler/proc/StartProfiling()
|
||||
#if DM_BUILD < 1506
|
||||
stack_trace("Auto profiling unsupported on this byond version")
|
||||
CONFIG_SET(flag/auto_profile, FALSE)
|
||||
#else
|
||||
world.Profile(PROFILE_START)
|
||||
#endif
|
||||
|
||||
/datum/controller/subsystem/profiler/proc/StopProfiling()
|
||||
#if DM_BUILD >= 1506
|
||||
world.Profile(PROFILE_STOP)
|
||||
#endif
|
||||
|
||||
/datum/controller/subsystem/profiler/proc/DumpFile()
|
||||
#if DM_BUILD < 1506
|
||||
stack_trace("Auto profiling unsupported on this byond version")
|
||||
CONFIG_SET(flag/auto_profile, FALSE)
|
||||
#else
|
||||
var/timer = TICK_USAGE_REAL
|
||||
var/current_profile_data = world.Profile(PROFILE_REFRESH,format="json")
|
||||
fetch_cost = MC_AVERAGE(fetch_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
@@ -49,3 +60,4 @@ SUBSYSTEM_DEF(profiler)
|
||||
timer = TICK_USAGE_REAL
|
||||
WRITE_FILE(json_file, current_profile_data)
|
||||
write_cost = MC_AVERAGE(write_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(radiation)
|
||||
name = "Radiation"
|
||||
flags = SS_NO_INIT | SS_BACKGROUND
|
||||
wait = 1 SECONDS
|
||||
|
||||
var/list/warned_atoms = list()
|
||||
|
||||
@@ -13,5 +14,5 @@ PROCESSING_SUBSYSTEM_DEF(radiation)
|
||||
warned_atoms[ref] = TRUE
|
||||
var/atom/master = contamination.parent
|
||||
SSblackbox.record_feedback("tally", "contaminated", 1, master.type)
|
||||
var/msg = "has become contamintaed with enough radiation to contaminate other objects. || Source: [contamination.source] || Strength: [contamination.strength]"
|
||||
var/msg = "has become contaminated with enough radiation to contaminate other objects. || Source: [contamination.source] || Strength: [contamination.strength]"
|
||||
master.investigate_log(msg, INVESTIGATE_RADIATION)
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
#define BUCKET_LIMIT (world.time + TICKS2DS(min(BUCKET_LEN - (SSrunechat.practical_offset - DS2TICKS(world.time - SSrunechat.head_offset)) - 1, BUCKET_LEN - 1)))
|
||||
|
||||
/**
|
||||
* # Runechat Subsystem
|
||||
*
|
||||
* Maintains a timer-like system to handle destruction of runechat messages. Much of this code is modeled
|
||||
* after or adapted from the timer subsystem.
|
||||
*
|
||||
* Note that this has the same structure for storing and queueing messages as the timer subsystem does
|
||||
* for handling timers: the bucket_list is a list of chatmessage datums, each of which are the head
|
||||
* of a circularly linked list. Any given index in bucket_list could be null, representing an empty bucket.
|
||||
*/
|
||||
* # Runechat Subsystem
|
||||
*
|
||||
* Maintains a timer-like system to handle destruction of runechat messages. Much of this code is modeled
|
||||
* after or adapted from the timer subsystem.
|
||||
*
|
||||
* Note that this has the same structure for storing and queueing messages as the timer subsystem does
|
||||
* for handling timers: the bucket_list is a list of chatmessage datums, each of which are the head
|
||||
* of a circularly linked list. Any given index in bucket_list could be null, representing an empty bucket.
|
||||
*/
|
||||
SUBSYSTEM_DEF(runechat)
|
||||
name = "Runechat"
|
||||
flags = SS_TICKER | SS_NO_INIT
|
||||
@@ -131,14 +131,14 @@ SUBSYSTEM_DEF(runechat)
|
||||
bucket_resolution = world.tick_lag
|
||||
|
||||
/**
|
||||
* Enters the runechat subsystem with this chatmessage, inserting it into the end-of-life queue
|
||||
*
|
||||
* This will also account for a chatmessage already being registered, and in which case
|
||||
* the position will be updated to remove it from the previous location if necessary
|
||||
*
|
||||
* Arguments:
|
||||
* * new_sched_destruction Optional, when provided is used to update an existing message with the new specified time
|
||||
*/
|
||||
* Enters the runechat subsystem with this chatmessage, inserting it into the end-of-life queue
|
||||
*
|
||||
* This will also account for a chatmessage already being registered, and in which case
|
||||
* the position will be updated to remove it from the previous location if necessary
|
||||
*
|
||||
* Arguments:
|
||||
* * new_sched_destruction Optional, when provided is used to update an existing message with the new specified time
|
||||
*/
|
||||
/datum/chatmessage/proc/enter_subsystem(new_sched_destruction = 0)
|
||||
// Get local references from subsystem as they are faster to access than the datum references
|
||||
var/list/bucket_list = SSrunechat.bucket_list
|
||||
@@ -169,7 +169,7 @@ SUBSYSTEM_DEF(runechat)
|
||||
|
||||
// Handle insertion into the secondary queue if the required time is outside our tracked amounts
|
||||
if (scheduled_destruction >= BUCKET_LIMIT)
|
||||
BINARY_INSERT(src, SSrunechat.second_queue, datum/chatmessage, src, scheduled_destruction, COMPARE_KEY)
|
||||
BINARY_INSERT(src, SSrunechat.second_queue, /datum/chatmessage, src, scheduled_destruction, COMPARE_KEY)
|
||||
return
|
||||
|
||||
// Get bucket position and a local reference to the datum var, it's faster to access this way
|
||||
@@ -194,8 +194,8 @@ SUBSYSTEM_DEF(runechat)
|
||||
|
||||
|
||||
/**
|
||||
* Removes this chatmessage datum from the runechat subsystem
|
||||
*/
|
||||
* Removes this chatmessage datum from the runechat subsystem
|
||||
*/
|
||||
/datum/chatmessage/proc/leave_subsystem()
|
||||
// Attempt to find the bucket that contains this chat message
|
||||
var/bucket_pos = BUCKET_POS(scheduled_destruction)
|
||||
|
||||
@@ -56,12 +56,13 @@ SUBSYSTEM_DEF(server_maint)
|
||||
for(var/I in currentrun)
|
||||
var/client/C = I
|
||||
//handle kicking inactive players
|
||||
if(round_started && kick_inactive && C.is_afk(afk_period))
|
||||
if(round_started && kick_inactive && !C.holder && C.is_afk(afk_period))
|
||||
var/cmob = C.mob
|
||||
if(!(isobserver(cmob) || (isdead(cmob) && C.holder)))
|
||||
if (!isnewplayer(cmob) || !SSticker.queued_players.Find(cmob))
|
||||
log_access("AFK: [key_name(C)]")
|
||||
to_chat(C, "<span class='danger'>You have been inactive for more than [DisplayTimeText(afk_period)] and have been disconnected.</span>")
|
||||
qdel(C)
|
||||
to_chat(C, "<span class='userdanger'>You have been inactive for more than [DisplayTimeText(afk_period)] and have been disconnected.</span><br><span class='danger'>You may reconnect via the button in the file menu or by <b><u><a href='byond://winset?command=.reconnect'>clicking here to reconnect</a></u></b>.</span>")
|
||||
QDEL_IN(C, 1) //to ensure they get our message before getting disconnected
|
||||
continue
|
||||
|
||||
if (!(!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1)))
|
||||
winset(C, null, "command=.update_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]")
|
||||
@@ -83,4 +84,15 @@ SUBSYSTEM_DEF(server_maint)
|
||||
if(tgsversion)
|
||||
SSblackbox.record_feedback("text", "server_tools", 1, tgsversion.raw_parameter)
|
||||
|
||||
|
||||
/datum/controller/subsystem/server_maint/proc/UpdateHubStatus()
|
||||
// if(!CONFIG_GET(flag/hub) || !CONFIG_GET(number/max_hub_pop))
|
||||
// return FALSE //no point, hub / auto hub controls are disabled
|
||||
|
||||
// var/max_pop = CONFIG_GET(number/max_hub_pop)
|
||||
|
||||
// if(GLOB.clients.len > max_pop)
|
||||
// world.update_hub_visibility(FALSE)
|
||||
// else
|
||||
// world.update_hub_visibility(TRUE)
|
||||
#undef PING_BUFFER_TIME
|
||||
|
||||
@@ -5,34 +5,48 @@ SUBSYSTEM_DEF(sounds)
|
||||
flags = SS_NO_FIRE
|
||||
init_order = INIT_ORDER_SOUNDS
|
||||
var/static/using_channels_max = CHANNEL_HIGHEST_AVAILABLE //BYOND max channels
|
||||
/// Amount of channels to reserve for random usage rather than reservations being allowed to reserve all channels. Also a nice safeguard for when someone screws up.
|
||||
var/static/random_channels_min = 50
|
||||
|
||||
// Hey uh these two needs to be initialized fast because the whole "things get deleted before init" thing.
|
||||
/// Assoc list, "[channel]" = either the datum using it or TRUE for an unsafe-reserved (datumless reservation) channel
|
||||
var/list/using_channels = list()
|
||||
/// Assoc list, `"[channel]" =` either the datum using it or TRUE for an unsafe-reserved (datumless reservation) channel
|
||||
var/list/using_channels
|
||||
/// Assoc list datum = list(channel1, channel2, ...) for what channels something reserved.
|
||||
var/list/using_channels_by_datum = list()
|
||||
/// List of all available channels with associations set to TRUE for fast lookups/allocation.
|
||||
var/list/available_channels
|
||||
var/list/using_channels_by_datum
|
||||
// Special datastructure for fast channel management
|
||||
/// List of all channels as numbers
|
||||
var/list/channel_list
|
||||
/// Associative list of all reserved channels associated to their position. `"[channel_number]" =` index as number
|
||||
var/list/reserved_channels
|
||||
/// lower iteration position - Incremented and looped to get "random" sound channels for normal sounds. The channel at this index is returned when asking for a random channel.
|
||||
var/channel_random_low
|
||||
/// higher reserve position - decremented and incremented to reserve sound channels, anything above this is reserved. The channel at this index is the highest unreserved channel.
|
||||
var/channel_reserve_high
|
||||
|
||||
/datum/controller/subsystem/sounds/Initialize()
|
||||
setup_available_channels()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/sounds/proc/setup_available_channels()
|
||||
available_channels = list()
|
||||
channel_list = list()
|
||||
reserved_channels = list()
|
||||
using_channels = list()
|
||||
using_channels_by_datum = list()
|
||||
for(var/i in 1 to using_channels_max)
|
||||
available_channels[num2text(i)] = TRUE
|
||||
channel_list += i
|
||||
channel_random_low = 1
|
||||
channel_reserve_high = length(channel_list)
|
||||
|
||||
/// Removes a channel from using list.
|
||||
/datum/controller/subsystem/sounds/proc/free_sound_channel(channel)
|
||||
channel = num2text(channel)
|
||||
var/using = using_channels[channel]
|
||||
using_channels -= channel
|
||||
if(using)
|
||||
var/text_channel = num2text(channel)
|
||||
var/using = using_channels[text_channel]
|
||||
using_channels -= text_channel
|
||||
if(using != TRUE) // datum channel
|
||||
using_channels_by_datum[using] -= channel
|
||||
if(!length(using_channels_by_datum[using]))
|
||||
using_channels_by_datum -= using
|
||||
available_channels[channel] = TRUE
|
||||
free_channel(channel)
|
||||
|
||||
/// Frees all the channels a datum is using.
|
||||
/datum/controller/subsystem/sounds/proc/free_datum_channels(datum/D)
|
||||
@@ -40,8 +54,8 @@ SUBSYSTEM_DEF(sounds)
|
||||
if(!L)
|
||||
return
|
||||
for(var/channel in L)
|
||||
using_channels -= channel
|
||||
available_channels[channel] = TRUE
|
||||
using_channels -= num2text(channel)
|
||||
free_channel(channel)
|
||||
using_channels_by_datum -= D
|
||||
|
||||
/// Frees all datumless channels
|
||||
@@ -50,42 +64,72 @@ SUBSYSTEM_DEF(sounds)
|
||||
|
||||
/// NO AUTOMATIC CLEANUP - If you use this, you better manually free it later! Returns an integer for channel.
|
||||
/datum/controller/subsystem/sounds/proc/reserve_sound_channel_datumless()
|
||||
var/channel = random_available_channel_text()
|
||||
if(!channel) //oh no..
|
||||
. = reserve_channel()
|
||||
if(!.) //oh no..
|
||||
return FALSE
|
||||
available_channels -= channel
|
||||
using_channels[channel] = DATUMLESS
|
||||
var/text_channel = num2text(.)
|
||||
using_channels[text_channel] = DATUMLESS
|
||||
LAZYINITLIST(using_channels_by_datum[DATUMLESS])
|
||||
using_channels_by_datum[DATUMLESS] += channel
|
||||
return text2num(channel)
|
||||
using_channels_by_datum[DATUMLESS] += .
|
||||
|
||||
/// Reserves a channel for a datum. Automatic cleanup only when the datum is deleted. Returns an integer for channel.
|
||||
/datum/controller/subsystem/sounds/proc/reserve_sound_channel(datum/D)
|
||||
if(!D) //i don't like typechecks but someone will fuck it up
|
||||
CRASH("Attempted to reserve sound channel without datum using the managed proc.")
|
||||
var/channel = random_available_channel_text()
|
||||
if(!channel)
|
||||
.= reserve_channel()
|
||||
if(!.)
|
||||
return FALSE
|
||||
available_channels -= channel
|
||||
using_channels[channel] = D
|
||||
var/text_channel = num2text(.)
|
||||
using_channels[text_channel] = D
|
||||
LAZYINITLIST(using_channels_by_datum[D])
|
||||
using_channels_by_datum[D] += channel
|
||||
return text2num(channel)
|
||||
using_channels_by_datum[D] += .
|
||||
|
||||
/**
|
||||
* Reserves a channel and updates the datastructure. Private proc.
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/reserve_channel()
|
||||
PRIVATE_PROC(TRUE)
|
||||
if(channel_reserve_high <= random_channels_min) // out of channels
|
||||
return
|
||||
var/channel = channel_list[channel_reserve_high]
|
||||
reserved_channels[num2text(channel)] = channel_reserve_high--
|
||||
return channel
|
||||
|
||||
/**
|
||||
* Frees a channel and updates the datastructure. Private proc.
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/free_channel(number)
|
||||
PRIVATE_PROC(TRUE)
|
||||
var/text_channel = num2text(number)
|
||||
var/index = reserved_channels[text_channel]
|
||||
if(!index)
|
||||
CRASH("Attempted to (internally) free a channel that wasn't reserved.")
|
||||
reserved_channels -= text_channel
|
||||
// push reserve index up, which makes it now on a channel that is reserved
|
||||
channel_reserve_high++
|
||||
// swap the reserved channel wtih the unreserved channel so the reserve index is now on an unoccupied channel and the freed channel is next to be used.
|
||||
channel_list.Swap(channel_reserve_high, index)
|
||||
// now, an existing reserved channel will likely (exception: unreserving last reserved channel) be at index
|
||||
// get it, and update position.
|
||||
var/text_reserved = num2text(channel_list[index])
|
||||
if(!reserved_channels[text_reserved]) //if it isn't already reserved make sure we don't accidently mistakenly put it on reserved list!
|
||||
return
|
||||
reserved_channels[text_reserved] = index
|
||||
|
||||
/// Random available channel, returns text.
|
||||
/datum/controller/subsystem/sounds/proc/random_available_channel_text()
|
||||
return pick(available_channels)
|
||||
if(channel_random_low > channel_reserve_high)
|
||||
channel_random_low = 1
|
||||
. = "[channel_list[channel_random_low++]]"
|
||||
|
||||
/// Random available channel, returns number
|
||||
/datum/controller/subsystem/sounds/proc/random_available_channel()
|
||||
return text2num(pick(available_channels))
|
||||
|
||||
/// If a channel is available
|
||||
/datum/controller/subsystem/sounds/proc/is_channel_available(channel)
|
||||
return available_channels[num2text(channel)]
|
||||
if(channel_random_low > channel_reserve_high)
|
||||
channel_random_low = 1
|
||||
. = channel_list[channel_random_low++]
|
||||
|
||||
/// How many channels we have left.
|
||||
/datum/controller/subsystem/sounds/proc/available_channels_left()
|
||||
return length(available_channels)
|
||||
return length(channel_list) - random_channels_min
|
||||
|
||||
#undef DATUMLESS
|
||||
|
||||
@@ -13,7 +13,7 @@ SUBSYSTEM_DEF(spacedrift)
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/spacedrift/fire(resumed = 0)
|
||||
/datum/controller/subsystem/spacedrift/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
src.currentrun = processing.Copy()
|
||||
|
||||
@@ -47,6 +47,7 @@ SUBSYSTEM_DEF(spacedrift)
|
||||
var/old_dir = AM.dir
|
||||
var/old_loc = AM.loc
|
||||
AM.inertia_moving = TRUE
|
||||
AM.set_glide_size(DELAY_TO_GLIDE_SIZE(AM.inertia_move_delay), FALSE)
|
||||
step(AM, AM.inertia_dir)
|
||||
AM.inertia_moving = FALSE
|
||||
AM.inertia_next_move = world.time + AM.inertia_move_delay
|
||||
|
||||
@@ -203,3 +203,4 @@ SUBSYSTEM_DEF(statpanels)
|
||||
set hidden = TRUE
|
||||
|
||||
statbrowser_ready = TRUE
|
||||
init_verbs()
|
||||
|
||||
@@ -1,34 +1,231 @@
|
||||
SUBSYSTEM_DEF(stickyban)
|
||||
name = "Sticky Ban"
|
||||
name = "PRISM"
|
||||
init_order = INIT_ORDER_STICKY_BAN
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/list/cache = list()
|
||||
var/list/dbcache = list()
|
||||
var/list/confirmed_exempt = list()
|
||||
var/dbcacheexpire = 0
|
||||
|
||||
|
||||
/datum/controller/subsystem/stickyban/Initialize(timeofday)
|
||||
var/list/bannedkeys = world.GetConfig("ban")
|
||||
if (length(GLOB.stickybanadminexemptions))
|
||||
restore_stickybans()
|
||||
var/list/bannedkeys = sticky_banned_ckeys()
|
||||
//sanitize the sticky ban list
|
||||
|
||||
//delete db bans that no longer exist in the database and add new legacy bans to the database
|
||||
if (SSdbcore.Connect() || length(SSstickyban.dbcache))
|
||||
if (length(GLOB.stickybanadminexemptions))
|
||||
restore_stickybans()
|
||||
for (var/oldban in (world.GetConfig("ban") - bannedkeys))
|
||||
var/ckey = ckey(oldban)
|
||||
if (ckey != oldban && (ckey in bannedkeys))
|
||||
continue
|
||||
|
||||
var/list/ban = params2list(world.GetConfig("ban", oldban))
|
||||
if (ban && !ban["fromdb"])
|
||||
if (!import_raw_stickyban_to_db(ckey, ban))
|
||||
log_world("Could not import stickyban on [oldban] into the database. Ignoring")
|
||||
continue
|
||||
dbcacheexpire = 0
|
||||
bannedkeys += ckey
|
||||
world.SetConfig("ban", oldban, null)
|
||||
|
||||
if (length(GLOB.stickybanadminexemptions)) //the previous loop can sleep
|
||||
restore_stickybans()
|
||||
|
||||
for (var/bannedkey in bannedkeys)
|
||||
var/ckey = ckey(bannedkey)
|
||||
var/list/ban = stickyban2list(world.GetConfig("ban", bannedkey))
|
||||
var/list/ban = get_stickyban_from_ckey(bannedkey)
|
||||
|
||||
//byond stores sticky bans by key, that can end up confusing things
|
||||
//i also remove it here so that if any stickybans cause a runtime, they just stop existing
|
||||
world.SetConfig("ban", bannedkey, null)
|
||||
//byond stores sticky bans by key, that's lame
|
||||
if (ckey != bannedkey)
|
||||
world.SetConfig("ban", bannedkey, null)
|
||||
|
||||
if (!ban["ckey"])
|
||||
ban["ckey"] = ckey
|
||||
|
||||
//storing these can break things and isn't needed for sticky ban tracking
|
||||
ban -= "IP"
|
||||
ban -= "computer_id"
|
||||
|
||||
ban["matches_this_round"] = list()
|
||||
ban["existing_user_matches_this_round"] = list()
|
||||
ban["admin_matches_this_round"] = list()
|
||||
ban["pending_matches_this_round"] = list()
|
||||
|
||||
cache[ckey] = ban
|
||||
|
||||
for (var/bannedckey in cache)
|
||||
world.SetConfig("ban", bannedckey, list2stickyban(cache[bannedckey]))
|
||||
world.SetConfig("ban", ckey, list2stickyban(ban))
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/stickyban/proc/Populatedbcache()
|
||||
var/newdbcache = list() //so if we runtime or the db connection dies we don't kill the existing cache
|
||||
|
||||
// var/datum/db_query/query_stickybans = SSdbcore.NewQuery("SELECT ckey, reason, banning_admin, datetime FROM [format_table_name("stickyban")] ORDER BY ckey")
|
||||
// var/datum/db_query/query_ckey_matches = SSdbcore.NewQuery("SELECT stickyban, matched_ckey, first_matched, last_matched, exempt FROM [format_table_name("stickyban_matched_ckey")] ORDER BY first_matched")
|
||||
// var/datum/db_query/query_cid_matches = SSdbcore.NewQuery("SELECT stickyban, matched_cid, first_matched, last_matched FROM [format_table_name("stickyban_matched_cid")] ORDER BY first_matched")
|
||||
// var/datum/db_query/query_ip_matches = SSdbcore.NewQuery("SELECT stickyban, INET_NTOA(matched_ip), first_matched, last_matched FROM [format_table_name("stickyban_matched_ip")] ORDER BY first_matched")
|
||||
|
||||
var/datum/DBQuery/query_stickybans = SSdbcore.NewQuery("SELECT ckey, reason, banning_admin, datetime FROM [format_table_name("stickyban")] ORDER BY ckey")
|
||||
var/datum/DBQuery/query_ckey_matches = SSdbcore.NewQuery("SELECT stickyban, matched_ckey, first_matched, last_matched, exempt FROM [format_table_name("stickyban_matched_ckey")] ORDER BY first_matched")
|
||||
var/datum/DBQuery/query_cid_matches = SSdbcore.NewQuery("SELECT stickyban, matched_cid, first_matched, last_matched FROM [format_table_name("stickyban_matched_cid")] ORDER BY first_matched")
|
||||
var/datum/DBQuery/query_ip_matches = SSdbcore.NewQuery("SELECT stickyban, INET_NTOA(matched_ip), first_matched, last_matched FROM [format_table_name("stickyban_matched_ip")] ORDER BY first_matched")
|
||||
|
||||
SSdbcore.QuerySelect(list(query_stickybans, query_ckey_matches, query_cid_matches, query_ip_matches))
|
||||
|
||||
if (query_stickybans.last_error)
|
||||
qdel(query_stickybans)
|
||||
qdel(query_ckey_matches)
|
||||
qdel(query_cid_matches)
|
||||
qdel(query_ip_matches)
|
||||
return
|
||||
|
||||
while (query_stickybans.NextRow())
|
||||
var/list/ban = list()
|
||||
|
||||
ban["ckey"] = query_stickybans.item[1]
|
||||
ban["message"] = query_stickybans.item[2]
|
||||
ban["reason"] = "(InGameBan)([query_stickybans.item[3]])"
|
||||
ban["admin"] = query_stickybans.item[3]
|
||||
ban["datetime"] = query_stickybans.item[4]
|
||||
ban["type"] = list("sticky")
|
||||
|
||||
newdbcache["[query_stickybans.item[1]]"] = ban
|
||||
|
||||
|
||||
if (!query_ckey_matches.last_error)
|
||||
while (query_ckey_matches.NextRow())
|
||||
var/list/match = list()
|
||||
|
||||
match["stickyban"] = query_ckey_matches.item[1]
|
||||
match["matched_ckey"] = query_ckey_matches.item[2]
|
||||
match["first_matched"] = query_ckey_matches.item[3]
|
||||
match["last_matched"] = query_ckey_matches.item[4]
|
||||
match["exempt"] = text2num(query_ckey_matches.item[5])
|
||||
|
||||
var/ban = newdbcache[query_ckey_matches.item[1]]
|
||||
if (!ban)
|
||||
continue
|
||||
var/keys = ban[text2num(query_ckey_matches.item[5]) ? "whitelist" : "keys"]
|
||||
if (!keys)
|
||||
keys = ban[text2num(query_ckey_matches.item[5]) ? "whitelist" : "keys"] = list()
|
||||
keys[query_ckey_matches.item[2]] = match
|
||||
|
||||
if (!query_cid_matches.last_error)
|
||||
while (query_cid_matches.NextRow())
|
||||
var/list/match = list()
|
||||
|
||||
match["stickyban"] = query_cid_matches.item[1]
|
||||
match["matched_cid"] = query_cid_matches.item[2]
|
||||
match["first_matched"] = query_cid_matches.item[3]
|
||||
match["last_matched"] = query_cid_matches.item[4]
|
||||
|
||||
var/ban = newdbcache[query_cid_matches.item[1]]
|
||||
if (!ban)
|
||||
continue
|
||||
var/computer_ids = ban["computer_id"]
|
||||
if (!computer_ids)
|
||||
computer_ids = ban["computer_id"] = list()
|
||||
computer_ids[query_cid_matches.item[2]] = match
|
||||
|
||||
|
||||
if (!query_ip_matches.last_error)
|
||||
while (query_ip_matches.NextRow())
|
||||
var/list/match = list()
|
||||
|
||||
match["stickyban"] = query_ip_matches.item[1]
|
||||
match["matched_ip"] = query_ip_matches.item[2]
|
||||
match["first_matched"] = query_ip_matches.item[3]
|
||||
match["last_matched"] = query_ip_matches.item[4]
|
||||
|
||||
var/ban = newdbcache[query_ip_matches.item[1]]
|
||||
if (!ban)
|
||||
continue
|
||||
var/IPs = ban["IP"]
|
||||
if (!IPs)
|
||||
IPs = ban["IP"] = list()
|
||||
IPs[query_ip_matches.item[2]] = match
|
||||
|
||||
dbcache = newdbcache
|
||||
dbcacheexpire = world.time+STICKYBAN_DB_CACHE_TIME
|
||||
|
||||
qdel(query_stickybans)
|
||||
qdel(query_ckey_matches)
|
||||
qdel(query_cid_matches)
|
||||
qdel(query_ip_matches)
|
||||
|
||||
|
||||
/datum/controller/subsystem/stickyban/proc/import_raw_stickyban_to_db(ckey, list/ban)
|
||||
. = FALSE
|
||||
if (!ban["admin"])
|
||||
ban["admin"] = "LEGACY"
|
||||
if (!ban["message"])
|
||||
ban["message"] = "Evasion"
|
||||
|
||||
// TODO: USE NEW DB IMPLEMENTATION
|
||||
var/datum/DBQuery/query_create_stickyban = SSdbcore.NewQuery(
|
||||
"INSERT IGNORE INTO [format_table_name("stickyban")] (ckey, reason, banning_admin) VALUES ([ckey], [ban["message"]], ban["admin"]))"
|
||||
)
|
||||
|
||||
if (query_create_stickyban.warn_execute())
|
||||
qdel(query_create_stickyban)
|
||||
return
|
||||
qdel(query_create_stickyban)
|
||||
|
||||
// var/datum/db_query/query_create_stickyban = SSdbcore.NewQuery(
|
||||
// "INSERT IGNORE INTO [format_table_name("stickyban")] (ckey, reason, banning_admin) VALUES (:ckey, :message, :admin)",
|
||||
// list("ckey" = ckey, "message" = ban["message"], "admin" = ban["admin"])
|
||||
// )
|
||||
// if (!query_create_stickyban.warn_execute())
|
||||
// qdel(query_create_stickyban)
|
||||
// return
|
||||
// qdel(query_create_stickyban)
|
||||
|
||||
var/list/sqlckeys = list()
|
||||
var/list/sqlcids = list()
|
||||
var/list/sqlips = list()
|
||||
|
||||
if (ban["keys"])
|
||||
var/list/keys = splittext(ban["keys"], ",")
|
||||
for (var/key in keys)
|
||||
var/list/sqlckey = list()
|
||||
sqlckey["stickyban"] = ckey
|
||||
sqlckey["matched_ckey"] = ckey(key)
|
||||
sqlckey["exempt"] = FALSE
|
||||
sqlckeys[++sqlckeys.len] = sqlckey
|
||||
|
||||
if (ban["whitelist"])
|
||||
var/list/keys = splittext(ban["whitelist"], ",")
|
||||
for (var/key in keys)
|
||||
var/list/sqlckey = list()
|
||||
sqlckey["stickyban"] = ckey
|
||||
sqlckey["matched_ckey"] = ckey(key)
|
||||
sqlckey["exempt"] = TRUE
|
||||
sqlckeys[++sqlckeys.len] = sqlckey
|
||||
|
||||
if (ban["computer_id"])
|
||||
var/list/cids = splittext(ban["computer_id"], ",")
|
||||
for (var/cid in cids)
|
||||
var/list/sqlcid = list()
|
||||
sqlcid["stickyban"] = ckey
|
||||
sqlcid["matched_cid"] = cid
|
||||
sqlcids[++sqlcids.len] = sqlcid
|
||||
|
||||
if (ban["IP"])
|
||||
var/list/ips = splittext(ban["IP"], ",")
|
||||
for (var/ip in ips)
|
||||
var/list/sqlip = list()
|
||||
sqlip["stickyban"] = ckey
|
||||
sqlip["matched_ip"] = ip
|
||||
sqlips[++sqlips.len] = sqlip
|
||||
|
||||
if (length(sqlckeys))
|
||||
SSdbcore.MassInsert(format_table_name("stickyban_matched_ckey"), sqlckeys, ignore_errors = TRUE)
|
||||
|
||||
if (length(sqlcids))
|
||||
SSdbcore.MassInsert(format_table_name("stickyban_matched_cid"), sqlcids, ignore_errors = TRUE)
|
||||
|
||||
if (length(sqlips))
|
||||
SSdbcore.MassInsert(format_table_name("stickyban_matched_ip"), sqlips, ignore_errors = TRUE)
|
||||
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -57,6 +57,7 @@ SUBSYSTEM_DEF(throwing)
|
||||
var/dx
|
||||
var/dy
|
||||
var/force = MOVE_FORCE_DEFAULT
|
||||
var/gentle = FALSE
|
||||
var/pure_diagonal
|
||||
var/diagonal_error
|
||||
var/datum/callback/callback
|
||||
@@ -64,15 +65,44 @@ SUBSYSTEM_DEF(throwing)
|
||||
var/delayed_time = 0
|
||||
var/last_move = 0
|
||||
|
||||
|
||||
/datum/thrownthing/New(thrownthing, target, target_turf, init_dir, maxrange, speed, thrower, diagonals_first, force, gentle, callback, target_zone)
|
||||
. = ..()
|
||||
src.thrownthing = thrownthing
|
||||
RegisterSignal(thrownthing, COMSIG_PARENT_QDELETING, .proc/on_thrownthing_qdel)
|
||||
src.target = target
|
||||
src.target_turf = target_turf
|
||||
src.init_dir = init_dir
|
||||
src.maxrange = maxrange
|
||||
src.speed = speed
|
||||
src.thrower = thrower
|
||||
src.diagonals_first = diagonals_first
|
||||
src.force = force
|
||||
src.gentle = gentle
|
||||
src.callback = callback
|
||||
src.target_zone = target_zone
|
||||
|
||||
|
||||
/datum/thrownthing/Destroy()
|
||||
if(HAS_TRAIT_FROM(thrownthing, TRAIT_SPOOKY_THROW, "revenant"))
|
||||
REMOVE_TRAIT(thrownthing, TRAIT_SPOOKY_THROW, "revenant")
|
||||
SSthrowing.processing -= thrownthing
|
||||
thrownthing.throwing = null
|
||||
thrownthing = null
|
||||
target = null
|
||||
thrower = null
|
||||
callback = null
|
||||
if(callback)
|
||||
QDEL_NULL(callback) //It stores a reference to the thrownthing, its source. Let's clean that.
|
||||
return ..()
|
||||
|
||||
|
||||
///Defines the datum behavior on the thrownthing's qdeletion event.
|
||||
/datum/thrownthing/proc/on_thrownthing_qdel(atom/movable/source, force)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
qdel(src)
|
||||
|
||||
|
||||
/datum/thrownthing/proc/tick()
|
||||
var/atom/movable/AM = thrownthing
|
||||
if (!isturf(AM.loc) || !AM.throwing)
|
||||
@@ -112,7 +142,7 @@ SUBSYSTEM_DEF(throwing)
|
||||
finalize()
|
||||
return
|
||||
|
||||
AM.Move(step, get_dir(AM, step))
|
||||
AM.Move(step, get_dir(AM, step), DELAY_TO_GLIDE_SIZE(1 / speed))
|
||||
|
||||
if (!AM.throwing) // we hit something during our move
|
||||
finalize(hit = TRUE)
|
||||
@@ -136,15 +166,21 @@ SUBSYSTEM_DEF(throwing)
|
||||
if (A == target)
|
||||
hit = TRUE
|
||||
thrownthing.throw_impact(A, src)
|
||||
if(QDELETED(thrownthing)) //throw_impact can delete things, such as glasses smashing
|
||||
return //deletion should already be handled by on_thrownthing_qdel()
|
||||
break
|
||||
if (!hit)
|
||||
thrownthing.throw_impact(get_turf(thrownthing), src) // we haven't hit something yet and we still must, let's hit the ground.
|
||||
if(QDELETED(thrownthing)) //throw_impact can delete things, such as glasses smashing
|
||||
return //deletion should already be handled by on_thrownthing_qdel()
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
else
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
|
||||
if(target)
|
||||
thrownthing.throw_impact(target, src)
|
||||
if(QDELETED(thrownthing)) //throw_impact can delete things, such as glasses smashing
|
||||
return //deletion should already be handled by on_thrownthing_qdel()
|
||||
|
||||
if (callback)
|
||||
callback.Invoke()
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
SUBSYSTEM_DEF(time_track)
|
||||
name = "Time Tracking"
|
||||
wait = 1 SECONDS
|
||||
flags = SS_NO_INIT|SS_NO_TICK_CHECK
|
||||
wait = 10
|
||||
flags = SS_NO_TICK_CHECK
|
||||
init_order = INIT_ORDER_TIMETRACK
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
|
||||
var/time_dilation_current = 0
|
||||
@@ -16,33 +17,81 @@ SUBSYSTEM_DEF(time_track)
|
||||
var/last_tick_byond_time = 0
|
||||
var/last_tick_tickcount = 0
|
||||
|
||||
var/last_measurement = 0
|
||||
var/measurement_delay = 60
|
||||
|
||||
var/stat_time_text
|
||||
var/time_dilation_text
|
||||
/datum/controller/subsystem/time_track/Initialize(start_timeofday)
|
||||
. = ..()
|
||||
GLOB.perf_log = "[GLOB.log_directory]/perf-[GLOB.round_id ? GLOB.round_id : "NULL"]-[SSmapping.config?.map_name].csv"
|
||||
log_perf(
|
||||
list(
|
||||
"time",
|
||||
"players",
|
||||
"tidi",
|
||||
"tidi_fastavg",
|
||||
"tidi_avg",
|
||||
"tidi_slowavg",
|
||||
"maptick",
|
||||
"num_timers",
|
||||
"air_turf_cost",
|
||||
"air_eg_cost",
|
||||
"air_highpressure_cost",
|
||||
"air_hotspots_cost",
|
||||
"air_superconductivity_cost",
|
||||
"air_pipenets_cost",
|
||||
"air_rebuilds_cost",
|
||||
"air_turf_count",
|
||||
"air_eg_count",
|
||||
"air_hotspot_count",
|
||||
"air_network_count",
|
||||
"air_delta_count",
|
||||
"air_superconductive_count"
|
||||
)
|
||||
)
|
||||
|
||||
/datum/controller/subsystem/time_track/fire()
|
||||
stat_time_text = "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]\n\nRound Time: [DisplayTimeText(world.time - SSticker.round_start_time, 1)] \n\nStation Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]\n\n[time_dilation_text]"
|
||||
|
||||
if(++last_measurement == measurement_delay)
|
||||
last_measurement = 0
|
||||
var/current_realtime = REALTIMEOFDAY
|
||||
var/current_byondtime = world.time
|
||||
var/current_tickcount = world.time/world.tick_lag
|
||||
var/current_realtime = REALTIMEOFDAY
|
||||
var/current_byondtime = world.time
|
||||
var/current_tickcount = world.time/world.tick_lag
|
||||
GLOB.glide_size_multiplier = (current_byondtime - last_tick_byond_time) / (current_realtime - last_tick_realtime)
|
||||
|
||||
if (!first_run)
|
||||
var/tick_drift = max(0, (((current_realtime - last_tick_realtime) - (current_byondtime - last_tick_byond_time)) / world.tick_lag))
|
||||
if(times_fired % 10) // everything else is once every 10 seconds
|
||||
return
|
||||
|
||||
time_dilation_current = tick_drift / (current_tickcount - last_tick_tickcount) * 100
|
||||
if (!first_run)
|
||||
var/tick_drift = max(0, (((current_realtime - last_tick_realtime) - (current_byondtime - last_tick_byond_time)) / world.tick_lag))
|
||||
|
||||
time_dilation_avg_fast = MC_AVERAGE_FAST(time_dilation_avg_fast, time_dilation_current)
|
||||
time_dilation_avg = MC_AVERAGE(time_dilation_avg, time_dilation_avg_fast)
|
||||
time_dilation_avg_slow = MC_AVERAGE_SLOW(time_dilation_avg_slow, time_dilation_avg)
|
||||
else
|
||||
first_run = FALSE
|
||||
last_tick_realtime = current_realtime
|
||||
last_tick_byond_time = current_byondtime
|
||||
last_tick_tickcount = current_tickcount
|
||||
SSblackbox.record_feedback("associative", "time_dilation_current", 1, list("[SQLtime()]" = list("current" = "[time_dilation_current]", "avg_fast" = "[time_dilation_avg_fast]", "avg" = "[time_dilation_avg]", "avg_slow" = "[time_dilation_avg_slow]")))
|
||||
time_dilation_text = "Time Dilation: [round(time_dilation_current,1)]% AVG:([round(time_dilation_avg_fast,1)]%, [round(time_dilation_avg,1)]%, [round(time_dilation_avg_slow,1)]%)"
|
||||
time_dilation_current = tick_drift / (current_tickcount - last_tick_tickcount) * 100
|
||||
|
||||
time_dilation_avg_fast = MC_AVERAGE_FAST(time_dilation_avg_fast, time_dilation_current)
|
||||
time_dilation_avg = MC_AVERAGE(time_dilation_avg, time_dilation_avg_fast)
|
||||
time_dilation_avg_slow = MC_AVERAGE_SLOW(time_dilation_avg_slow, time_dilation_avg)
|
||||
else
|
||||
first_run = FALSE
|
||||
last_tick_realtime = current_realtime
|
||||
last_tick_byond_time = current_byondtime
|
||||
last_tick_tickcount = current_tickcount
|
||||
SSblackbox.record_feedback("associative", "time_dilation_current", 1, list("[SQLtime()]" = list("current" = "[time_dilation_current]", "avg_fast" = "[time_dilation_avg_fast]", "avg" = "[time_dilation_avg]", "avg_slow" = "[time_dilation_avg_slow]")))
|
||||
log_perf(
|
||||
list(
|
||||
world.time,
|
||||
length(GLOB.clients),
|
||||
time_dilation_current,
|
||||
time_dilation_avg_fast,
|
||||
time_dilation_avg,
|
||||
time_dilation_avg_slow,
|
||||
MAPTICK_LAST_INTERNAL_TICK_USAGE,
|
||||
length(SStimer.timer_id_dict),
|
||||
SSair.cost_turfs,
|
||||
SSair.cost_groups,
|
||||
SSair.cost_highpressure,
|
||||
SSair.cost_hotspots,
|
||||
SSair.cost_superconductivity,
|
||||
SSair.cost_pipenets,
|
||||
SSair.cost_rebuilds,
|
||||
SSair.get_active_turfs(), //does not return a list, which is what we want
|
||||
SSair.get_amt_excited_groups(),
|
||||
length(SSair.hotspots),
|
||||
length(SSair.networks),
|
||||
length(SSair.high_pressure_delta),
|
||||
length(SSair.active_super_conductivity)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,31 +1,51 @@
|
||||
#define BUCKET_LEN (world.fps*1*60) //how many ticks should we keep in the bucket. (1 minutes worth)
|
||||
/// Controls how many buckets should be kept, each representing a tick. (1 minutes worth)
|
||||
#define BUCKET_LEN (world.fps*1*60)
|
||||
/// Helper for getting the correct bucket for a given timer
|
||||
#define BUCKET_POS(timer) (((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag)+1) % BUCKET_LEN)||BUCKET_LEN)
|
||||
/// Gets the maximum time at which timers will be invoked from buckets, used for deferring to secondary queue
|
||||
#define TIMER_MAX (world.time + TICKS2DS(min(BUCKET_LEN-(SStimer.practical_offset-DS2TICKS(world.time - SStimer.head_offset))-1, BUCKET_LEN-1)))
|
||||
#define TIMER_ID_MAX (2**24) //max float with integer precision
|
||||
/// Max float with integer precision
|
||||
#define TIMER_ID_MAX (2**24)
|
||||
|
||||
/**
|
||||
* # Timer Subsystem
|
||||
*
|
||||
* Handles creation, callbacks, and destruction of timed events.
|
||||
*
|
||||
* It is important to understand the buckets used in the timer subsystem are just a series of circular doubly-linked
|
||||
* lists. The object at a given index in bucket_list is a /datum/timedevent, the head of a circular list, which has prev
|
||||
* and next references for the respective elements in that bucket's circular list.
|
||||
*/
|
||||
SUBSYSTEM_DEF(timer)
|
||||
name = "Timer"
|
||||
wait = 1 //SS_TICKER subsystem, so wait is in ticks
|
||||
wait = 1 // SS_TICKER subsystem, so wait is in ticks
|
||||
init_order = INIT_ORDER_TIMER
|
||||
|
||||
priority = FIRE_PRIORITY_TIMER
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
|
||||
var/list/datum/timedevent/second_queue = list() //awe, yes, you've had first queue, but what about second queue?
|
||||
/// Queue used for storing timers that do not fit into the current buckets
|
||||
var/list/datum/timedevent/second_queue = list()
|
||||
/// A hashlist dictionary used for storing unique timers
|
||||
var/list/hashes = list()
|
||||
|
||||
var/head_offset = 0 //world.time of the first entry in the the bucket.
|
||||
var/practical_offset = 1 //index of the first non-empty item in the bucket.
|
||||
var/bucket_resolution = 0 //world.tick_lag the bucket was designed for
|
||||
var/bucket_count = 0 //how many timers are in the buckets
|
||||
|
||||
var/list/bucket_list = list() //list of buckets, each bucket holds every timer that has to run that byond tick.
|
||||
|
||||
var/list/timer_id_dict = list() //list of all active timers assoicated to their timer id (for easy lookup)
|
||||
|
||||
var/list/clienttime_timers = list() //special snowflake timers that run on fancy pansy "client time"
|
||||
|
||||
/// world.time of the first entry in the bucket list, effectively the 'start time' of the current buckets
|
||||
var/head_offset = 0
|
||||
/// Index of the wrap around pivot for buckets. buckets before this are later running buckets wrapped around from the end of the bucket list.
|
||||
var/practical_offset = 1
|
||||
/// world.tick_lag the bucket was designed for
|
||||
var/bucket_resolution = 0
|
||||
/// How many timers are in the buckets
|
||||
var/bucket_count = 0
|
||||
/// List of buckets, each bucket holds every timer that has to run that byond tick
|
||||
var/list/bucket_list = list()
|
||||
/// List of all active timers associated to their timer ID (for easy lookup)
|
||||
var/list/timer_id_dict = list()
|
||||
/// Special timers that run in real-time, not BYOND time; these are more expensive to run and maintain
|
||||
var/list/clienttime_timers = list()
|
||||
/// Contains the last time that a timer's callback was invoked, or the last tick the SS fired if no timers are being processed
|
||||
var/last_invoke_tick = 0
|
||||
/// Contains the last time that a warning was issued for not invoking callbacks
|
||||
var/static/last_invoke_warning = 0
|
||||
/// Boolean operator controlling if the timer SS will automatically reset buckets if it fails to invoke callbacks for an extended period of time
|
||||
var/static/bucket_auto_reset = TRUE
|
||||
|
||||
/datum/controller/subsystem/timer/PreInit()
|
||||
@@ -38,44 +58,53 @@ SUBSYSTEM_DEF(timer)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/timer/fire(resumed = FALSE)
|
||||
// Store local references to datum vars as it is faster to access them
|
||||
var/lit = last_invoke_tick
|
||||
var/last_check = world.time - TICKS2DS(BUCKET_LEN*1.5)
|
||||
var/list/bucket_list = src.bucket_list
|
||||
var/last_check = world.time - TICKS2DS(BUCKET_LEN * 1.5)
|
||||
|
||||
// If there are no timers being tracked, then consider now to be the last invoked time
|
||||
if(!bucket_count)
|
||||
last_invoke_tick = world.time
|
||||
|
||||
// Check that we have invoked a callback in the last 1.5 minutes of BYOND time,
|
||||
// and throw a warning and reset buckets if this is true
|
||||
if(lit && lit < last_check && head_offset < last_check && last_invoke_warning < last_check)
|
||||
last_invoke_warning = world.time
|
||||
var/msg = "No regular timers processed in the last [BUCKET_LEN*1.5] ticks[bucket_auto_reset ? ", resetting buckets" : ""]!"
|
||||
var/msg = "No regular timers processed in the last [BUCKET_LEN * 1.5] ticks[bucket_auto_reset ? ", resetting buckets" : ""]!"
|
||||
message_admins(msg)
|
||||
WARNING(msg)
|
||||
if(bucket_auto_reset)
|
||||
bucket_resolution = 0
|
||||
|
||||
log_world("Timer bucket reset. world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
var/list/to_log = list("Timer bucket reset. world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
for (var/i in 1 to length(bucket_list))
|
||||
var/datum/timedevent/bucket_head = bucket_list[i]
|
||||
if (!bucket_head)
|
||||
continue
|
||||
|
||||
log_world("Active timers at index [i]:")
|
||||
|
||||
to_log += "Active timers at index [i]:"
|
||||
var/datum/timedevent/bucket_node = bucket_head
|
||||
var/anti_loop_check = 1000
|
||||
do
|
||||
log_world(get_timer_debug_string(bucket_node))
|
||||
to_log += get_timer_debug_string(bucket_node)
|
||||
bucket_node = bucket_node.next
|
||||
anti_loop_check--
|
||||
while(bucket_node && bucket_node != bucket_head && anti_loop_check)
|
||||
log_world("Active timers in the second_queue queue:")
|
||||
|
||||
to_log += "Active timers in the second_queue queue:"
|
||||
for(var/I in second_queue)
|
||||
log_world(get_timer_debug_string(I))
|
||||
to_log += get_timer_debug_string(I)
|
||||
|
||||
var/next_clienttime_timer_index = 0
|
||||
var/len = length(clienttime_timers)
|
||||
// Dump all the logged data to the world log
|
||||
log_world(to_log.Join("\n"))
|
||||
|
||||
for (next_clienttime_timer_index in 1 to len)
|
||||
// Process client-time timers
|
||||
var/static/next_clienttime_timer_index = 0
|
||||
if (next_clienttime_timer_index)
|
||||
clienttime_timers.Cut(1, next_clienttime_timer_index+1)
|
||||
next_clienttime_timer_index = 0
|
||||
for (next_clienttime_timer_index in 1 to length(clienttime_timers))
|
||||
if (MC_TICK_CHECK)
|
||||
next_clienttime_timer_index--
|
||||
break
|
||||
@@ -86,8 +115,8 @@ SUBSYSTEM_DEF(timer)
|
||||
|
||||
var/datum/callback/callBack = ctime_timer.callBack
|
||||
if (!callBack)
|
||||
clienttime_timers.Cut(next_clienttime_timer_index,next_clienttime_timer_index+1)
|
||||
CRASH("Invalid timer: [get_timer_debug_string(ctime_timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset], REALTIMEOFDAY: [REALTIMEOFDAY]")
|
||||
CRASH("Invalid timer: [get_timer_debug_string(ctime_timer)] world.time: [world.time], \
|
||||
head_offset: [head_offset], practical_offset: [practical_offset], REALTIMEOFDAY: [REALTIMEOFDAY]")
|
||||
|
||||
ctime_timer.spent = REALTIMEOFDAY
|
||||
callBack.InvokeAsync()
|
||||
@@ -95,135 +124,93 @@ SUBSYSTEM_DEF(timer)
|
||||
if(ctime_timer.flags & TIMER_LOOP)
|
||||
ctime_timer.spent = 0
|
||||
ctime_timer.timeToRun = REALTIMEOFDAY + ctime_timer.wait
|
||||
BINARY_INSERT(ctime_timer, clienttime_timers, datum/timedevent, ctime_timer, timeToRun, COMPARE_KEY)
|
||||
BINARY_INSERT(ctime_timer, clienttime_timers, /datum/timedevent, ctime_timer, timeToRun, COMPARE_KEY)
|
||||
else
|
||||
qdel(ctime_timer)
|
||||
|
||||
|
||||
// Remove invoked client-time timers
|
||||
if (next_clienttime_timer_index)
|
||||
clienttime_timers.Cut(1, next_clienttime_timer_index+1)
|
||||
next_clienttime_timer_index = 0
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
var/static/list/spent = list()
|
||||
var/static/datum/timedevent/timer
|
||||
// Check for when we need to loop the buckets, this occurs when
|
||||
// the head_offset is approaching BUCKET_LEN ticks in the past
|
||||
if (practical_offset > BUCKET_LEN)
|
||||
head_offset += TICKS2DS(BUCKET_LEN)
|
||||
practical_offset = 1
|
||||
resumed = FALSE
|
||||
|
||||
// Check for when we have to reset buckets, typically from auto-reset
|
||||
if ((length(bucket_list) != BUCKET_LEN) || (world.tick_lag != bucket_resolution))
|
||||
reset_buckets()
|
||||
bucket_list = src.bucket_list
|
||||
resumed = FALSE
|
||||
|
||||
|
||||
if (!resumed)
|
||||
timer = null
|
||||
|
||||
while (practical_offset <= BUCKET_LEN && head_offset + ((practical_offset-1)*world.tick_lag) <= world.time)
|
||||
var/datum/timedevent/head = bucket_list[practical_offset]
|
||||
if (!timer || !head || timer == head)
|
||||
head = bucket_list[practical_offset]
|
||||
timer = head
|
||||
while (timer)
|
||||
// Iterate through each bucket starting from the practical offset
|
||||
while (practical_offset <= BUCKET_LEN && head_offset + ((practical_offset - 1) * world.tick_lag) <= world.time)
|
||||
var/datum/timedevent/timer
|
||||
while ((timer = bucket_list[practical_offset]))
|
||||
var/datum/callback/callBack = timer.callBack
|
||||
if (!callBack)
|
||||
bucket_resolution = null //force bucket recreation
|
||||
CRASH("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
bucket_resolution = null // force bucket recreation
|
||||
CRASH("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], \
|
||||
head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
|
||||
timer.bucketEject() //pop the timer off of the bucket list.
|
||||
|
||||
// Invoke callback if possible
|
||||
if (!timer.spent)
|
||||
spent += timer
|
||||
timer.spent = world.time
|
||||
callBack.InvokeAsync()
|
||||
last_invoke_tick = world.time
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
timer = timer.next
|
||||
if (timer == head)
|
||||
break
|
||||
|
||||
|
||||
bucket_list[practical_offset++] = null
|
||||
|
||||
//we freed up a bucket, lets see if anything in second_queue needs to be shifted to that bucket.
|
||||
var/i = 0
|
||||
var/L = length(second_queue)
|
||||
for (i in 1 to L)
|
||||
timer = second_queue[i]
|
||||
if (timer.timeToRun >= TIMER_MAX)
|
||||
i--
|
||||
break
|
||||
|
||||
if (timer.timeToRun < head_offset)
|
||||
bucket_resolution = null //force bucket recreation
|
||||
stack_trace("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
|
||||
if (timer.callBack && !timer.spent)
|
||||
timer.callBack.InvokeAsync()
|
||||
spent += timer
|
||||
bucket_count++
|
||||
else if(!QDELETED(timer))
|
||||
qdel(timer)
|
||||
continue
|
||||
|
||||
if (timer.timeToRun < head_offset + TICKS2DS(practical_offset-1))
|
||||
bucket_resolution = null //force bucket recreation
|
||||
stack_trace("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
if (timer.callBack && !timer.spent)
|
||||
timer.callBack.InvokeAsync()
|
||||
spent += timer
|
||||
bucket_count++
|
||||
else if(!QDELETED(timer))
|
||||
qdel(timer)
|
||||
continue
|
||||
|
||||
bucket_count++
|
||||
var/bucket_pos = max(1, BUCKET_POS(timer))
|
||||
|
||||
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
|
||||
if (!bucket_head)
|
||||
bucket_list[bucket_pos] = timer
|
||||
timer.next = null
|
||||
timer.prev = null
|
||||
continue
|
||||
|
||||
if (!bucket_head.prev)
|
||||
bucket_head.prev = bucket_head
|
||||
timer.next = bucket_head
|
||||
timer.prev = bucket_head.prev
|
||||
timer.next.prev = timer
|
||||
timer.prev.next = timer
|
||||
if (i)
|
||||
second_queue.Cut(1, i+1)
|
||||
|
||||
timer = null
|
||||
|
||||
bucket_count -= length(spent)
|
||||
|
||||
for (var/i in spent)
|
||||
var/datum/timedevent/qtimer = i
|
||||
if(QDELETED(qtimer))
|
||||
bucket_count++
|
||||
continue
|
||||
if(!(qtimer.flags & TIMER_LOOP))
|
||||
qdel(qtimer)
|
||||
else
|
||||
bucket_count++
|
||||
qtimer.spent = 0
|
||||
qtimer.bucketEject()
|
||||
if(qtimer.flags & TIMER_CLIENT_TIME)
|
||||
qtimer.timeToRun = REALTIMEOFDAY + qtimer.wait
|
||||
if (timer.flags & TIMER_LOOP) // Prepare looping timers to re-enter the queue
|
||||
timer.spent = 0
|
||||
timer.timeToRun = world.time + timer.wait
|
||||
timer.bucketJoin()
|
||||
else
|
||||
qtimer.timeToRun = world.time + qtimer.wait
|
||||
qtimer.bucketJoin()
|
||||
qdel(timer)
|
||||
|
||||
spent.len = 0
|
||||
if (MC_TICK_CHECK)
|
||||
break
|
||||
|
||||
//formated this way to be runtime resistant
|
||||
if (!bucket_list[practical_offset])
|
||||
// Empty the bucket, check if anything in the secondary queue should be shifted to this bucket
|
||||
bucket_list[practical_offset++] = null
|
||||
var/i = 0
|
||||
for (i in 1 to length(second_queue))
|
||||
timer = second_queue[i]
|
||||
if (timer.timeToRun >= TIMER_MAX)
|
||||
i--
|
||||
break
|
||||
|
||||
// Check for timers that are scheduled to run in the past
|
||||
if (timer.timeToRun < head_offset)
|
||||
bucket_resolution = null // force bucket recreation
|
||||
stack_trace("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. \
|
||||
[get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
break
|
||||
|
||||
// Check for timers that are not capable of being scheduled to run without rebuilding buckets
|
||||
if (timer.timeToRun < head_offset + TICKS2DS(practical_offset - 1))
|
||||
bucket_resolution = null // force bucket recreation
|
||||
stack_trace("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to \
|
||||
short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
break
|
||||
|
||||
timer.bucketJoin()
|
||||
if (i)
|
||||
second_queue.Cut(1, i+1)
|
||||
if (MC_TICK_CHECK)
|
||||
break
|
||||
|
||||
/**
|
||||
* Generates a string with details about the timed event for debugging purposes
|
||||
*/
|
||||
/datum/controller/subsystem/timer/proc/get_timer_debug_string(datum/timedevent/TE)
|
||||
. = "Timer: [TE]"
|
||||
. += "Prev: [TE.prev ? TE.prev : "NULL"], Next: [TE.next ? TE.next : "NULL"]"
|
||||
@@ -234,12 +221,16 @@ SUBSYSTEM_DEF(timer)
|
||||
if(!TE.callBack)
|
||||
. += ", NO CALLBACK"
|
||||
|
||||
/**
|
||||
* Destroys the existing buckets and creates new buckets from the existing timed events
|
||||
*/
|
||||
/datum/controller/subsystem/timer/proc/reset_buckets()
|
||||
var/list/bucket_list = src.bucket_list
|
||||
var/list/bucket_list = src.bucket_list // Store local reference to datum var, this is faster
|
||||
var/list/alltimers = list()
|
||||
//collect the timers currently in the bucket
|
||||
|
||||
// Get all timers currently in the buckets
|
||||
for (var/bucket_head in bucket_list)
|
||||
if (!bucket_head)
|
||||
if (!bucket_head) // if bucket is empty for this tick
|
||||
continue
|
||||
var/datum/timedevent/bucket_node = bucket_head
|
||||
do
|
||||
@@ -247,25 +238,38 @@ SUBSYSTEM_DEF(timer)
|
||||
bucket_node = bucket_node.next
|
||||
while(bucket_node && bucket_node != bucket_head)
|
||||
|
||||
// Empty the list by zeroing and re-assigning the length
|
||||
bucket_list.len = 0
|
||||
bucket_list.len = BUCKET_LEN
|
||||
|
||||
// Reset values for the subsystem to their initial values
|
||||
practical_offset = 1
|
||||
bucket_count = 0
|
||||
head_offset = world.time
|
||||
bucket_resolution = world.tick_lag
|
||||
|
||||
// Add all timed events from the secondary queue as well
|
||||
alltimers += second_queue
|
||||
|
||||
// If there are no timers being tracked by the subsystem,
|
||||
// there is no need to do any further rebuilding
|
||||
if (!length(alltimers))
|
||||
return
|
||||
|
||||
// Sort all timers by time to run
|
||||
sortTim(alltimers, .proc/cmp_timer)
|
||||
|
||||
// Get the earliest timer, and if the TTR is earlier than the current world.time,
|
||||
// then set the head offset appropriately to be the earliest time tracked by the
|
||||
// current set of buckets
|
||||
var/datum/timedevent/head = alltimers[1]
|
||||
|
||||
if (head.timeToRun < head_offset)
|
||||
head_offset = head.timeToRun
|
||||
|
||||
// Iterate through each timed event and insert it into an appropriate bucket,
|
||||
// up unto the point that we can no longer insert into buckets as the TTR
|
||||
// is outside the range we are tracking, then insert the remainder into the
|
||||
// secondary queue
|
||||
var/new_bucket_count
|
||||
var/i = 1
|
||||
for (i in 1 to length(alltimers))
|
||||
@@ -273,34 +277,38 @@ SUBSYSTEM_DEF(timer)
|
||||
if (!timer)
|
||||
continue
|
||||
|
||||
var/bucket_pos = BUCKET_POS(timer)
|
||||
// Check that the TTR is within the range covered by buckets, when exceeded we've finished
|
||||
if (timer.timeToRun >= TIMER_MAX)
|
||||
i--
|
||||
break
|
||||
|
||||
|
||||
// Check that timer has a valid callback and hasn't been invoked
|
||||
if (!timer.callBack || timer.spent)
|
||||
WARNING("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
WARNING("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], \
|
||||
head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
if (timer.callBack)
|
||||
qdel(timer)
|
||||
continue
|
||||
|
||||
// Insert the timer into the bucket, and perform necessary circular doubly-linked list operations
|
||||
new_bucket_count++
|
||||
var/bucket_pos = BUCKET_POS(timer)
|
||||
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
|
||||
if (!bucket_head)
|
||||
bucket_list[bucket_pos] = timer
|
||||
timer.next = null
|
||||
timer.prev = null
|
||||
continue
|
||||
|
||||
if (!bucket_head.prev)
|
||||
bucket_head.prev = bucket_head
|
||||
timer.next = bucket_head
|
||||
timer.prev = bucket_head.prev
|
||||
timer.next.prev = timer
|
||||
timer.prev.next = timer
|
||||
|
||||
// Cut the timers that are tracked by the buckets from the secondary queue
|
||||
if (i)
|
||||
alltimers.Cut(1, i+1)
|
||||
alltimers.Cut(1, i + 1)
|
||||
second_queue = alltimers
|
||||
bucket_count = new_bucket_count
|
||||
|
||||
@@ -311,45 +319,64 @@ SUBSYSTEM_DEF(timer)
|
||||
timer_id_dict |= SStimer.timer_id_dict
|
||||
bucket_list |= SStimer.bucket_list
|
||||
|
||||
/**
|
||||
* # Timed Event
|
||||
*
|
||||
* This is the actual timer, it contains the callback and necessary data to maintain
|
||||
* the timer.
|
||||
*
|
||||
* See the documentation for the timer subsystem for an explanation of the buckets referenced
|
||||
* below in next and prev
|
||||
*/
|
||||
/datum/timedevent
|
||||
/// ID used for timers when the TIMER_STOPPABLE flag is present
|
||||
var/id
|
||||
/// The callback to invoke after the timer completes
|
||||
var/datum/callback/callBack
|
||||
/// The time at which the callback should be invoked at
|
||||
var/timeToRun
|
||||
/// The length of the timer
|
||||
var/wait
|
||||
/// Unique hash generated when TIMER_UNIQUE flag is present
|
||||
var/hash
|
||||
/// The source of the timedevent, whatever called addtimer
|
||||
var/source
|
||||
/// Flags associated with the timer, see _DEFINES/subsystems.dm
|
||||
var/list/flags
|
||||
var/spent = 0 //time we ran the timer.
|
||||
var/name //for easy debugging.
|
||||
//cicular doublely linked list
|
||||
/// Time at which the timer was invoked or destroyed
|
||||
var/spent = 0
|
||||
/// An informative name generated for the timer as its representation in strings, useful for debugging
|
||||
var/name
|
||||
/// Next timed event in the bucket
|
||||
var/datum/timedevent/next
|
||||
/// Previous timed event in the bucket
|
||||
var/datum/timedevent/prev
|
||||
|
||||
/datum/timedevent/New(datum/callback/callBack, wait, flags, hash)
|
||||
/datum/timedevent/New(datum/callback/callBack, wait, flags, hash, source)
|
||||
var/static/nextid = 1
|
||||
id = TIMER_ID_NULL
|
||||
src.callBack = callBack
|
||||
src.wait = wait
|
||||
src.flags = flags
|
||||
src.hash = hash
|
||||
src.source = source
|
||||
|
||||
if (flags & TIMER_CLIENT_TIME)
|
||||
timeToRun = REALTIMEOFDAY + wait
|
||||
else
|
||||
timeToRun = world.time + wait
|
||||
// Determine time at which the timer's callback should be invoked
|
||||
timeToRun = (flags & TIMER_CLIENT_TIME ? REALTIMEOFDAY : world.time) + wait
|
||||
|
||||
// Include the timer in the hash table if the timer is unique
|
||||
if (flags & TIMER_UNIQUE)
|
||||
SStimer.hashes[hash] = src
|
||||
|
||||
// Generate ID for the timer if the timer is stoppable, include in the timer id dictionary
|
||||
if (flags & TIMER_STOPPABLE)
|
||||
id = num2text(nextid, 100)
|
||||
if (nextid >= SHORT_REAL_LIMIT)
|
||||
nextid += min(1, 2**round(nextid/SHORT_REAL_LIMIT))
|
||||
nextid += min(1, 2 ** round(nextid / SHORT_REAL_LIMIT))
|
||||
else
|
||||
nextid++
|
||||
SStimer.timer_id_dict[id] = src
|
||||
|
||||
name = "Timer: [id] (\ref[src]), TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT", "TIMER_LOOP")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])"
|
||||
|
||||
if ((timeToRun < world.time || timeToRun < SStimer.head_offset) && !(flags & TIMER_CLIENT_TIME))
|
||||
CRASH("Invalid timer state: Timer created that would require a backtrack to run (addtimer would never let this happen): [SStimer.get_timer_debug_string(src)]")
|
||||
|
||||
@@ -390,23 +417,39 @@ SUBSYSTEM_DEF(timer)
|
||||
prev = null
|
||||
return QDEL_HINT_IWILLGC
|
||||
|
||||
/**
|
||||
* Removes this timed event from any relevant buckets, or the secondary queue
|
||||
*/
|
||||
/datum/timedevent/proc/bucketEject()
|
||||
// Attempt to find bucket that contains this timed event
|
||||
var/bucketpos = BUCKET_POS(src)
|
||||
|
||||
// Store local references for the bucket list and secondary queue
|
||||
// This is faster than referencing them from the datum itself
|
||||
var/list/bucket_list = SStimer.bucket_list
|
||||
var/list/second_queue = SStimer.second_queue
|
||||
|
||||
// Attempt to get the head of the bucket
|
||||
var/datum/timedevent/buckethead
|
||||
if(bucketpos > 0)
|
||||
buckethead = bucket_list[bucketpos]
|
||||
|
||||
// Decrement the number of timers in buckets if the timed event is
|
||||
// the head of the bucket, or has a TTR less than TIMER_MAX implying it fits
|
||||
// into an existing bucket, or is otherwise not present in the secondary queue
|
||||
if(buckethead == src)
|
||||
bucket_list[bucketpos] = next
|
||||
SStimer.bucket_count--
|
||||
else if(timeToRun < TIMER_MAX || next || prev)
|
||||
else if(timeToRun < TIMER_MAX)
|
||||
SStimer.bucket_count--
|
||||
else
|
||||
var/l = length(second_queue)
|
||||
second_queue -= src
|
||||
if(l == length(second_queue))
|
||||
SStimer.bucket_count--
|
||||
|
||||
// Remove the timed event from the bucket, ensuring to maintain
|
||||
// the integrity of the bucket's list if relevant
|
||||
if(prev != next)
|
||||
prev.next = next
|
||||
next.prev = prev
|
||||
@@ -415,32 +458,47 @@ SUBSYSTEM_DEF(timer)
|
||||
next?.prev = null
|
||||
prev = next = null
|
||||
|
||||
/**
|
||||
* Attempts to add this timed event to a bucket, will enter the secondary queue
|
||||
* if there are no appropriate buckets at this time.
|
||||
*
|
||||
* Secondary queueing of timed events will occur when the timespan covered by the existing
|
||||
* buckets is exceeded by the time at which this timed event is scheduled to be invoked.
|
||||
* If the timed event is tracking client time, it will be added to a special bucket.
|
||||
*/
|
||||
/datum/timedevent/proc/bucketJoin()
|
||||
var/list/L
|
||||
// Generate debug-friendly name for timer
|
||||
var/static/list/bitfield_flags = list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT", "TIMER_LOOP")
|
||||
name = "Timer: [id] (\ref[src]), TTR: [timeToRun], wait:[wait] Flags: [jointext(bitfield2list(flags, bitfield_flags), ", ")], \
|
||||
callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), \
|
||||
callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""]), source: [source]"
|
||||
|
||||
// Check if this timed event should be diverted to the client time bucket, or the secondary queue
|
||||
var/list/L
|
||||
if (flags & TIMER_CLIENT_TIME)
|
||||
L = SStimer.clienttime_timers
|
||||
else if (timeToRun >= TIMER_MAX)
|
||||
L = SStimer.second_queue
|
||||
|
||||
if(L)
|
||||
BINARY_INSERT(src, L, datum/timedevent, src, timeToRun, COMPARE_KEY)
|
||||
BINARY_INSERT(src, L, /datum/timedevent, src, timeToRun, COMPARE_KEY)
|
||||
return
|
||||
|
||||
//get the list of buckets
|
||||
// Get a local reference to the bucket list, this is faster than referencing the datum
|
||||
var/list/bucket_list = SStimer.bucket_list
|
||||
|
||||
//calculate our place in the bucket list
|
||||
// Find the correct bucket for this timed event
|
||||
var/bucket_pos = BUCKET_POS(src)
|
||||
|
||||
//get the bucket for our tick
|
||||
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
|
||||
SStimer.bucket_count++
|
||||
//empty bucket, we will just add ourselves
|
||||
|
||||
// If there is no timed event at this position, then the bucket is 'empty'
|
||||
// and we can just set this event to that position
|
||||
if (!bucket_head)
|
||||
bucket_list[bucket_pos] = src
|
||||
return
|
||||
//other wise, lets do a simplified linked list add.
|
||||
|
||||
// Otherwise, we merely add this timed event into the bucket, which is a
|
||||
// circularly doubly-linked list
|
||||
if (!bucket_head.prev)
|
||||
bucket_head.prev = bucket_head
|
||||
next = bucket_head
|
||||
@@ -448,7 +506,9 @@ SUBSYSTEM_DEF(timer)
|
||||
next.prev = src
|
||||
prev.next = src
|
||||
|
||||
///Returns a string of the type of the callback for this timer
|
||||
/**
|
||||
* Returns a string of the type of the callback for this timer
|
||||
*/
|
||||
/datum/timedevent/proc/getcallingtype()
|
||||
. = "ERROR"
|
||||
if (callBack.object == GLOBAL_PROC)
|
||||
@@ -457,14 +517,15 @@ SUBSYSTEM_DEF(timer)
|
||||
. = "[callBack.object.type]"
|
||||
|
||||
/**
|
||||
* Create a new timer and insert it in the queue
|
||||
*
|
||||
* Arguments:
|
||||
* * callback the callback to call on timer finish
|
||||
* * wait deciseconds to run the timer for
|
||||
* * flags flags for this timer, see: code\__DEFINES\subsystems.dm
|
||||
*/
|
||||
/proc/addtimer(datum/callback/callback, wait = 0, flags = 0)
|
||||
* Create a new timer and insert it in the queue.
|
||||
* You should not call this directly, and should instead use the addtimer macro, which includes source information.
|
||||
*
|
||||
* Arguments:
|
||||
* * callback the callback to call on timer finish
|
||||
* * wait deciseconds to run the timer for
|
||||
* * flags flags for this timer, see: code\__DEFINES\subsystems.dm
|
||||
*/
|
||||
/proc/_addtimer(datum/callback/callback, wait = 0, flags = 0, file, line)
|
||||
if (!callback)
|
||||
CRASH("addtimer called without a callback")
|
||||
|
||||
@@ -472,31 +533,30 @@ SUBSYSTEM_DEF(timer)
|
||||
stack_trace("addtimer called with a negative wait. Converting to [world.tick_lag]")
|
||||
|
||||
if (callback.object != GLOBAL_PROC && QDELETED(callback.object) && !QDESTROYING(callback.object))
|
||||
stack_trace("addtimer called with a callback assigned to a qdeleted object. In the future such timers will not be supported and may refuse to run or run with a 0 wait")
|
||||
stack_trace("addtimer called with a callback assigned to a qdeleted object. In the future such timers will not \
|
||||
be supported and may refuse to run or run with a 0 wait")
|
||||
|
||||
wait = max(CEILING(wait, world.tick_lag), world.tick_lag)
|
||||
|
||||
if(wait >= INFINITY)
|
||||
CRASH("Attempted to create timer with INFINITY delay")
|
||||
|
||||
// Generate hash if relevant for timed events with the TIMER_UNIQUE flag
|
||||
var/hash
|
||||
|
||||
if (flags & TIMER_UNIQUE)
|
||||
var/list/hashlist
|
||||
if(flags & TIMER_NO_HASH_WAIT)
|
||||
hashlist = list(callback.object, "([REF(callback.object)])", callback.delegate, flags & TIMER_CLIENT_TIME)
|
||||
else
|
||||
hashlist = list(callback.object, "([REF(callback.object)])", callback.delegate, wait, flags & TIMER_CLIENT_TIME)
|
||||
var/list/hashlist = list(callback.object, "([REF(callback.object)])", callback.delegate, flags & TIMER_CLIENT_TIME)
|
||||
if(!(flags & TIMER_NO_HASH_WAIT))
|
||||
hashlist += wait
|
||||
hashlist += callback.arguments
|
||||
hash = hashlist.Join("|||||||")
|
||||
|
||||
var/datum/timedevent/hash_timer = SStimer.hashes[hash]
|
||||
if(hash_timer)
|
||||
if (hash_timer.spent) //it's pending deletion, pretend it doesn't exist.
|
||||
hash_timer.hash = null //but keep it from accidentally deleting us
|
||||
if (hash_timer.spent) // it's pending deletion, pretend it doesn't exist.
|
||||
hash_timer.hash = null // but keep it from accidentally deleting us
|
||||
else
|
||||
if (flags & TIMER_OVERRIDE)
|
||||
hash_timer.hash = null //no need having it delete it's hash if we are going to replace it
|
||||
hash_timer.hash = null // no need having it delete it's hash if we are going to replace it
|
||||
qdel(hash_timer)
|
||||
else
|
||||
if (hash_timer.flags & TIMER_STOPPABLE)
|
||||
@@ -505,24 +565,23 @@ SUBSYSTEM_DEF(timer)
|
||||
else if(flags & TIMER_OVERRIDE)
|
||||
stack_trace("TIMER_OVERRIDE used without TIMER_UNIQUE")
|
||||
|
||||
var/datum/timedevent/timer = new(callback, wait, flags, hash)
|
||||
var/datum/timedevent/timer = new(callback, wait, flags, hash, file && "[file]:[line]")
|
||||
return timer.id
|
||||
|
||||
/**
|
||||
* Delete a timer
|
||||
*
|
||||
* Arguments:
|
||||
* * id a timerid or a /datum/timedevent
|
||||
*/
|
||||
* Delete a timer
|
||||
*
|
||||
* Arguments:
|
||||
* * id a timerid or a /datum/timedevent
|
||||
*/
|
||||
/proc/deltimer(id)
|
||||
if (!id)
|
||||
return FALSE
|
||||
if (id == TIMER_ID_NULL)
|
||||
CRASH("Tried to delete a null timerid. Use TIMER_STOPPABLE flag")
|
||||
if (!istext(id))
|
||||
if (istype(id, /datum/timedevent))
|
||||
qdel(id)
|
||||
return TRUE
|
||||
if (istype(id, /datum/timedevent))
|
||||
qdel(id)
|
||||
return TRUE
|
||||
//id is string
|
||||
var/datum/timedevent/timer = SStimer.timer_id_dict[id]
|
||||
if (timer && !timer.spent)
|
||||
@@ -531,25 +590,22 @@ SUBSYSTEM_DEF(timer)
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Get the remaining deciseconds on a timer
|
||||
*
|
||||
* Arguments:
|
||||
* * id a timerid or a /datum/timedevent
|
||||
*/
|
||||
* Get the remaining deciseconds on a timer
|
||||
*
|
||||
* Arguments:
|
||||
* * id a timerid or a /datum/timedevent
|
||||
*/
|
||||
/proc/timeleft(id)
|
||||
if (!id)
|
||||
return null
|
||||
if (id == TIMER_ID_NULL)
|
||||
CRASH("Tried to get timeleft of a null timerid. Use TIMER_STOPPABLE flag")
|
||||
if (!istext(id))
|
||||
if (istype(id, /datum/timedevent))
|
||||
var/datum/timedevent/timer = id
|
||||
return timer.timeToRun - world.time
|
||||
if (istype(id, /datum/timedevent))
|
||||
var/datum/timedevent/timer = id
|
||||
return timer.timeToRun - world.time
|
||||
//id is string
|
||||
var/datum/timedevent/timer = SStimer.timer_id_dict[id]
|
||||
if (timer && !timer.spent)
|
||||
return timer.timeToRun - world.time
|
||||
return null
|
||||
return (timer && !timer.spent) ? timer.timeToRun - world.time : null
|
||||
|
||||
#undef BUCKET_LEN
|
||||
#undef BUCKET_POS
|
||||
|
||||
@@ -25,12 +25,12 @@ SUBSYSTEM_DEF(title)
|
||||
SSmapping.HACK_LoadMapConfig()
|
||||
for(var/S in provisional_title_screens)
|
||||
var/list/L = splittext(S,"+")
|
||||
if((L.len == 1 && L[1] != "blank.png")|| (L.len > 1 && ((use_rare_screens && lowertext(L[1]) == "rare") || (lowertext(L[1]) == lowertext(SSmapping.config.map_name)))))
|
||||
if((L.len == 1 && (L[1] != "exclude" && L[1] != "blank.png"))|| (L.len > 1 && ((use_rare_screens && lowertext(L[1]) == "rare") || (lowertext(L[1]) == lowertext(SSmapping.config.map_name)))))
|
||||
title_screens += S
|
||||
|
||||
if(length(title_screens))
|
||||
file_path = "[global.config.directory]/title_screens/images/[pick(title_screens)]"
|
||||
|
||||
|
||||
if(!file_path)
|
||||
file_path = "icons/default_title.dmi"
|
||||
|
||||
|
||||
@@ -5,10 +5,12 @@ SUBSYSTEM_DEF(vis_overlays)
|
||||
init_order = INIT_ORDER_VIS
|
||||
|
||||
var/list/vis_overlay_cache
|
||||
var/list/unique_vis_overlays
|
||||
var/list/currentrun
|
||||
|
||||
/datum/controller/subsystem/vis_overlays/Initialize()
|
||||
vis_overlay_cache = list()
|
||||
unique_vis_overlays = list()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/vis_overlays/fire(resumed = FALSE)
|
||||
@@ -29,31 +31,45 @@ SUBSYSTEM_DEF(vis_overlays)
|
||||
return
|
||||
|
||||
//the "thing" var can be anything with vis_contents which includes images
|
||||
/datum/controller/subsystem/vis_overlays/proc/add_vis_overlay(atom/movable/thing, icon, iconstate, layer, plane, dir, alpha = 255, add_appearance_flags = NONE)
|
||||
. = "[icon]|[iconstate]|[layer]|[plane]|[dir]|[alpha]|[add_appearance_flags]"
|
||||
var/obj/effect/overlay/vis/overlay = vis_overlay_cache[.]
|
||||
if(!overlay)
|
||||
overlay = new
|
||||
overlay.icon = icon
|
||||
overlay.icon_state = iconstate
|
||||
overlay.layer = layer
|
||||
overlay.plane = plane
|
||||
overlay.dir = dir
|
||||
overlay.alpha = alpha
|
||||
overlay.appearance_flags |= add_appearance_flags
|
||||
vis_overlay_cache[.] = overlay
|
||||
/datum/controller/subsystem/vis_overlays/proc/add_vis_overlay(atom/movable/thing, icon, iconstate, layer, plane, dir, alpha = 255, add_appearance_flags = NONE, unique = FALSE)
|
||||
var/obj/effect/overlay/vis/overlay
|
||||
if(!unique)
|
||||
. = "[icon]|[iconstate]|[layer]|[plane]|[dir]|[alpha]|[add_appearance_flags]"
|
||||
overlay = vis_overlay_cache[.]
|
||||
if(!overlay)
|
||||
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
|
||||
vis_overlay_cache[.] = overlay
|
||||
else
|
||||
overlay.unused = 0
|
||||
else
|
||||
overlay.unused = 0
|
||||
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
|
||||
overlay.cache_expiration = -1
|
||||
var/cache_id = "\ref[overlay]@{[world.time]}"
|
||||
unique_vis_overlays += overlay
|
||||
vis_overlay_cache[cache_id] = overlay
|
||||
. = overlay
|
||||
thing.vis_contents += overlay
|
||||
|
||||
if(!isatom(thing)) // Automatic rotation is not supported on non atoms
|
||||
return
|
||||
return overlay
|
||||
|
||||
if(!thing.managed_vis_overlays)
|
||||
thing.managed_vis_overlays = list(overlay)
|
||||
RegisterSignal(thing, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_vis_overlay)
|
||||
else
|
||||
thing.managed_vis_overlays += overlay
|
||||
return overlay
|
||||
|
||||
/datum/controller/subsystem/vis_overlays/proc/_create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
|
||||
var/obj/effect/overlay/vis/overlay = new
|
||||
overlay.icon = icon
|
||||
overlay.icon_state = iconstate
|
||||
overlay.layer = layer
|
||||
overlay.plane = plane
|
||||
overlay.dir = dir
|
||||
overlay.alpha = alpha
|
||||
overlay.appearance_flags |= add_appearance_flags
|
||||
return overlay
|
||||
|
||||
|
||||
/datum/controller/subsystem/vis_overlays/proc/remove_vis_overlay(atom/movable/thing, list/overlays)
|
||||
thing.vis_contents -= overlays
|
||||
@@ -62,15 +78,3 @@ SUBSYSTEM_DEF(vis_overlays)
|
||||
thing.managed_vis_overlays -= overlays
|
||||
if(!length(thing.managed_vis_overlays))
|
||||
thing.managed_vis_overlays = null
|
||||
UnregisterSignal(thing, COMSIG_ATOM_DIR_CHANGE)
|
||||
|
||||
/datum/controller/subsystem/vis_overlays/proc/rotate_vis_overlay(atom/thing, old_dir, new_dir)
|
||||
if(old_dir == new_dir)
|
||||
return
|
||||
var/rotation = dir2angle(old_dir) - dir2angle(new_dir)
|
||||
var/list/overlays_to_remove = list()
|
||||
for(var/i in thing.managed_vis_overlays)
|
||||
var/obj/effect/overlay/vis/overlay = i
|
||||
add_vis_overlay(thing, overlay.icon, overlay.icon_state, overlay.layer, overlay.plane, turn(overlay.dir, rotation), overlay.alpha, overlay.appearance_flags)
|
||||
overlays_to_remove += overlay
|
||||
remove_vis_overlay(thing, overlays_to_remove)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user