diff --git a/.github/workflows/build_bapi.yml b/.github/workflows/build_bapi.yml new file mode 100644 index 00000000000..d21b25f254d --- /dev/null +++ b/.github/workflows/build_bapi.yml @@ -0,0 +1,93 @@ +name: Build BAPI +on: + issue_comment: + types: [created] + +jobs: + build-bapi: + if: | + github.event.issue.pull_request && + (github.event.comment.body == '!build_bapi') && + ((github.event.sender.id == github.event.issue.user.id) || + (github.event.comment.author_association == 'COLLABORATOR') || + (github.event.comment.author_association == 'MEMBER') || + (github.event.comment.author_association == 'OWNER')) + + runs-on: ubuntu-latest + steps: + - name: Like the comment + env: + BASE_REPOSITORY: ${{ github.repository }} + GH_TOKEN: ${{ github.token }} + run: | + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/$BASE_REPOSITORY/issues/comments/${{ github.event.comment.id }}/reactions \ + -f content='+1' + + - name: PR Data + run: | + pr_json=$(curl -L -s --fail-with-body -H "Authorization: token ${{ github.token }}" ${{ github.event.issue.pull_request.url }}) + if [ `jq -r '.maintainer_can_modify' <<<$pr_json` == "false" ] ; then + gh pr comment ${{ github.event.issue.html_url }} --body 'GitHub Actions can not push to the repository without "Allow edits and access to secrets by maintainers" checked.' + echo "FAIL_NOTIFIED=true" >> "$GITHUB_ENV" + exit 1 + fi + echo "PR_REPO=`jq -r '.head.repo.full_name' <<<$pr_json`" >> $GITHUB_ENV + echo "PR_BRANCH=`jq -r '.head.ref' <<<$pr_json`" >> $GITHUB_ENV + echo "PR_HEAD_LABEL=`jq -r '.head.label' <<<$pr_json`" >> $GITHUB_ENV + + - uses: actions/checkout@v4 + with: + repository: ${{ env.PR_REPO }} + ref: ${{ env.PR_BRANCH }} + token: ${{ github.token }} + + - name: Build BAPI + env: + BASE_BRANCH: ${{ github.event.repository.default_branch }} + BASE_REPOSITORY: ${{ github.repository }} + GH_TOKEN: ${{ github.token }} + run: | + # Get the code. + git config user.name AuroraBuildBot + git config user.email "action@github.com" + git pull origin "$PR_BRANCH" --depth=$((ahead_by + 1)) + git remote add upstream "https://github.com/$BASE_REPOSITORY.git" + git fetch upstream "$BASE_BRANCH" --depth=$((behind_by + 1)) + cd rust/bapi + + # Get dependencies. + rustup target add i686-unknown-linux-gnu + rustup target add i686-pc-windows-gnu + sudo dpkg --add-architecture i386 + sudo apt-get update + sudo apt-get install zlib1g-dev:i386 lib32gcc-11-dev mingw-w64 mingw-w64-i686-dev + + # Build it. + cargo build --release --target i686-unknown-linux-gnu + cargo build --release --target i686-pc-windows-gnu + + # Copy the built targets to their checked-in locations. + cp target/i686-unknown-linux-gnu/release/libbapi.so ../../tools/ci/libbapi_ci.so + cp target/i686-pc-windows-gnu/release/bapi.dll ../../bapi.dll + + # Check if a workflow file would be modified by the merge (permissions prevent pushes if so) + latest_workflow_commit=$(git log -n 1 --pretty=format:"%H" upstream/$BASE_BRANCH -- .github/workflows) + if ! git branch --contains $latest_workflow_commit | grep -q "$(git rev-parse --abbrev-ref HEAD)"; then + gh pr comment ${{ github.event.issue.html_url }} --body "GitHub Actions can not push to this branch as workflow files have been changed since your branch was last updated. Please update your branch past https://github.com/$BASE_REPOSITORY/commit/$latest_workflow_commit before using this command again." + echo "FAIL_NOTIFIED=true" >> "$GITHUB_ENV" + exit 1 + fi + + git commit -a -m "Build BAPI" --allow-empty + git push origin + + - name: Notify Failure + if: failure() && env.FAIL_NOTIFIED != 'true' + env: + GH_TOKEN: ${{ github.token }} + run: | + gh pr comment ${{ github.event.issue.html_url }} -b 'Building BAPI failed, see the action run log for details: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' diff --git a/.github/workflows/byond.yml b/.github/workflows/byond.yml index 0fa594cd786..2fc304bcebd 100644 --- a/.github/workflows/byond.yml +++ b/.github/workflows/byond.yml @@ -24,7 +24,7 @@ env: FLYWAY_BUILD: "" SPACEMAN_DMM_VERSION: "" NODE_VERSION: "" - NODE_VERSION_PRECISE: "" + NODE_VERSION_LTS: "" PYTHON_VERSION: "" #If we want the runner to open an SSH shell for us to inspect it, fairly nieche, don't touch if you don't know what you're doing @@ -99,7 +99,7 @@ jobs: # https://megalinter.io/latest/ - name: Check EditorConfig Compliance id: ml - uses: oxsecurity/megalinter/flavors/python@v7.3.0 + uses: oxsecurity/megalinter/flavors/python@v7.10.0 # Env config options outlined in https://megalinter.io/configuration/ env: PRINT_ALPACA: false @@ -237,7 +237,7 @@ jobs: uses: actions/setup-node@v3 with: cache-dependency-path: tgui/yarn.lock - node-version: ${{ env.NODE_VERSION_PRECISE }} + node-version: ${{ env.NODE_VERSION_LTS }} cache: 'yarn' #Lint TGUI @@ -294,9 +294,14 @@ jobs: run: | tools/bootstrap/python -m dmi.test - - name: Check DMM-Test + - name: Run Map Checks run: | tools/bootstrap/python -m mapmerge2.dmm_test + tools/bootstrap/python -m tools.maplint.source + + - name: Scan DMMs + run: | + tools/bootstrap/python -m dmm_scanner.scan_camera_ctags ########################################### ############## GENERIC TESTS ############## @@ -946,7 +951,7 @@ jobs: strategy: matrix: map: [runtime] - pod: [ruins] + pod: [ruins-1, ruins-2, ruins-3] fail-fast: false steps: diff --git a/.github/workflows/update_changelog.yml b/.github/workflows/update_changelog.yml index 350ae01e294..2f4432a19e1 100644 --- a/.github/workflows/update_changelog.yml +++ b/.github/workflows/update_changelog.yml @@ -1,36 +1,53 @@ name: "Build Changelog" on: + schedule: + - cron: "0 0 * * *" workflow_dispatch: - push: - branches: - - master - paths: - - 'html/changelogs/**' jobs: - update-changelog: - concurrency: changelog + compile: + name: "Compile changelogs" runs-on: ubuntu-22.04 - if: "!contains(github.event.head_commit.message, '[ci skip]')" steps: - - name: Checkout Repository - uses: actions/checkout@v3 - with: - token: ${{ secrets.BOT_TOKEN_AURORA }} - - - name: Update Changelogs - run: | - tools/bootstrap/python tools/GenerateChangelog/ss13_genchangelog.py html/changelog.html html/changelogs - - - name: Commit Changelogs - run: | - git pull origin master - git config --local user.email "action@github.com" - git config --local user.name "AuroraBuildBot" - git add --force html/* - git commit -m "Automatic Changelog compile [ci skip]" -a || true - - - name: Push - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.BOT_TOKEN_AURORA }} + - name: "Check for BOT_TOKEN_AURORA secret and pass true to output if it exists to be checked by later steps" + id: value_holder + env: + ENABLER_SECRET: ${{ secrets.BOT_TOKEN_AURORA }} + run: | + unset SECRET_EXISTS + if [ -n "$ENABLER_SECRET" ]; then SECRET_EXISTS=true ; fi + echo "ACTIONS_ENABLED=$SECRET_EXISTS" >> $GITHUB_OUTPUT + - name: "Setup python" + if: steps.value_holder.outputs.ACTIONS_ENABLED + uses: actions/setup-python@v1 + with: + python-version: '3.x' + - name: "Install deps" + if: steps.value_holder.outputs.ACTIONS_ENABLED + run: | + python -m pip install --upgrade pip + python -m pip install pyyaml + sudo apt-get install dos2unix + - name: "Checkout" + if: steps.value_holder.outputs.ACTIONS_ENABLED + uses: actions/checkout@v4 + with: + fetch-depth: 25 + persist-credentials: false + - name: "Compile" + if: steps.value_holder.outputs.ACTIONS_ENABLED + run: | + tools/bootstrap/python tools/GenerateChangelog/ss13_genchangelog.py html/changelogs + - name: Commit + if: steps.value_holder.outputs.ACTIONS_ENABLED + run: | + git config --local user.email "action@github.com" + git config --local user.name "Changelogs" + git pull origin master + git add html/changelogs + git commit -m "Automatic changelog compile [ci skip]" -a || true + - name: "Push" + if: steps.value_holder.outputs.ACTIONS_ENABLED + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.BOT_TOKEN_AURORA || secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index ca34f48a911..f8e2e95003d 100644 --- a/.gitignore +++ b/.gitignore @@ -67,4 +67,6 @@ __pycache__/ .python-version define_sanity_output.txt -tools/bootstrap/.cache/venv/ + +# Unit test / coverage reports +.cache diff --git a/.vscode/settings.json b/.vscode/settings.json index 2a55b46c08c..053af42a14d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -38,5 +38,8 @@ "editor.rulers": [80], "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true - } + }, + "rust-analyzer.linkedProjects": [ + "rust/bapi/Cargo.toml" + ] } diff --git a/SpacemanDMM.toml b/SpacemanDMM.toml index 34b6abbf4b1..d16b1bd694b 100644 --- a/SpacemanDMM.toml +++ b/SpacemanDMM.toml @@ -20,6 +20,14 @@ invalid_lint_directive_value = "error" invalid_set_value = "error" unknown_linter_setting = "error" override_missing_keyword_arg = "error" +must_not_override = "error" +must_call_parent = "error" +final_var = "error" +private_var = "error" +protected_var = "error" +must_be_pure = "error" +must_not_sleep = "error" +redefined_proc = "error" ambiguous_in_lhs = "error" ambiguous_not_bitwise = "error" no_typehint_implicit_new = "error" diff --git a/aurorastation.dme b/aurorastation.dme index 4c939bd13ea..3ee42fbe921 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -23,7 +23,6 @@ #include "code\__DEFINES\_compile_helpers.dm" #include "code\__DEFINES\_flags.dm" #include "code\__DEFINES\_helpers.dm" -#include "code\__DEFINES\_layers.dm" #include "code\__DEFINES\_macros.dm" #include "code\__DEFINES\_protect.dm" #include "code\__DEFINES\_tick.dm" @@ -73,6 +72,7 @@ #include "code\__DEFINES\important_recursive_contents.dm" #include "code\__DEFINES\items_clothing.dm" #include "code\__DEFINES\jobs.dm" +#include "code\__DEFINES\layers.dm" #include "code\__DEFINES\lighting.dm" #include "code\__DEFINES\logging.dm" #include "code\__DEFINES\machinery.dm" @@ -93,6 +93,7 @@ #include "code\__DEFINES\overmap.dm" #include "code\__DEFINES\path.dm" #include "code\__DEFINES\pipes.dm" +#include "code\__DEFINES\prefs.dm" #include "code\__DEFINES\procpath.dm" #include "code\__DEFINES\profiler_tracy.dm" #include "code\__DEFINES\projectiles.dm" @@ -105,11 +106,13 @@ #include "code\__DEFINES\research.dm" #include "code\__DEFINES\robopen.dm" #include "code\__DEFINES\ruin_tags.dm" +#include "code\__DEFINES\rust_bapi.dm" #include "code\__DEFINES\rust_g.dm" #include "code\__DEFINES\rust_g_debug.dm" #include "code\__DEFINES\rust_g_overrides.dm" #include "code\__DEFINES\ship_weapons.dm" #include "code\__DEFINES\shuttle.dm" +#include "code\__DEFINES\si.dm" #include "code\__DEFINES\singletons.dm" #include "code\__DEFINES\smart_token_bucket.dm" #include "code\__DEFINES\solar.dm" @@ -148,6 +151,7 @@ #include "code\__DEFINES\dcs\signals\signals_record.dm" #include "code\__DEFINES\dcs\signals\signals_spatial_grid.dm" #include "code\__DEFINES\dcs\signals\signals_subsystem.dm" +#include "code\__DEFINES\dcs\signals\signals_turf.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_main.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_movable.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_movement.dm" @@ -236,8 +240,10 @@ #include "code\__HELPERS\sorting\__main.dm" #include "code\__HELPERS\sorting\cmp.dm" #include "code\__HELPERS\sorting\TimSort.dm" +#include "code\_globalvars\configuration.dm" #include "code\_globalvars\edible.dm" #include "code\_globalvars\logging.dm" +#include "code\_globalvars\tgui.dm" #include "code\_onclick\adjacent.dm" #include "code\_onclick\ai.dm" #include "code\_onclick\click.dm" @@ -267,6 +273,7 @@ #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\skybox.dm" #include "code\_onclick\hud\spell_screen_objects.dm" +#include "code\_onclick\hud\rendering\_renderer.dm" #include "code\_onclick\hud\screen_object_types\ai_screen_objs.dm" #include "code\_onclick\hud\screen_object_types\borer.dm" #include "code\_onclick\hud\screen_object_types\internals.dm" @@ -413,11 +420,15 @@ #include "code\datums\tgs_event_handler.dm" #include "code\datums\tgui_module.dm" #include "code\datums\weakrefs.dm" +#include "code\datums\changelog\changelog.dm" #include "code\datums\components\_component.dm" #include "code\datums\components\connect_mob_behalf.dm" #include "code\datums\components\local_network.dm" #include "code\datums\components\armor\armor.dm" #include "code\datums\components\base_name\base_name.dm" +#include "code\datums\components\eye\_eye.dm" +#include "code\datums\components\eye\blueprints.dm" +#include "code\datums\components\eye\freelook.dm" #include "code\datums\components\multitool\_multitool.dm" #include "code\datums\components\multitool\multitool.dm" #include "code\datums\components\multitool\circuitboards\circuitboards.dm" @@ -486,6 +497,11 @@ #include "code\datums\outfits\event\outfit_nanotrasen.dm" #include "code\datums\outfits\event\outfit_scc.dm" #include "code\datums\outfits\event\outfit_tfcl.dm" +#include "code\datums\outfits\event\outfit_generic\_generic.dm" +#include "code\datums\outfits\event\outfit_generic\engineering.dm" +#include "code\datums\outfits\event\outfit_generic\medical.dm" +#include "code\datums\outfits\event\outfit_generic\science.dm" +#include "code\datums\outfits\event\outfit_generic\security.dm" #include "code\datums\radio\frequency.dm" #include "code\datums\radio\signal.dm" #include "code\datums\repositories\cameras.dm" @@ -659,7 +675,8 @@ #include "code\game\gamemodes\cult\items\sword.dm" #include "code\game\gamemodes\cult\items\talisman.dm" #include "code\game\gamemodes\cult\items\tome.dm" -#include "code\game\gamemodes\cult\runes\_runes.dm" +#include "code\game\gamemodes\cult\runes\_rune_datum.dm" +#include "code\game\gamemodes\cult\runes\_rune_obj.dm" #include "code\game\gamemodes\cult\runes\armor.dm" #include "code\game\gamemodes\cult\runes\blind_others.dm" #include "code\game\gamemodes\cult\runes\blood_boil.dm" @@ -675,7 +692,6 @@ #include "code\game\gamemodes\cult\runes\manifest_ghost.dm" #include "code\game\gamemodes\cult\runes\raise_dead.dm" #include "code\game\gamemodes\cult\runes\reveal_runes.dm" -#include "code\game\gamemodes\cult\runes\rune.dm" #include "code\game\gamemodes\cult\runes\sacrifice.dm" #include "code\game\gamemodes\cult\runes\see_invisible.dm" #include "code\game\gamemodes\cult\runes\stun.dm" @@ -1213,6 +1229,7 @@ #include "code\game\objects\items\weapons\circuitboards\machinery\recharge_station.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\research.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\shieldgen.dm" +#include "code\game\objects\items\weapons\circuitboards\machinery\ship.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\telecomms.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\trashcompactor.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\trolley.dm" @@ -1243,6 +1260,7 @@ #include "code\game\objects\items\weapons\implants\implants\emp.dm" #include "code\game\objects\items\weapons\implants\implants\explosive.dm" #include "code\game\objects\items\weapons\implants\implants\freedom.dm" +#include "code\game\objects\items\weapons\implants\implants\galatean.dm" #include "code\game\objects\items\weapons\implants\implants\health_tracker.dm" #include "code\game\objects\items\weapons\implants\implants\loyalty.dm" #include "code\game\objects\items\weapons\implants\implants\mindshield.dm" @@ -1342,6 +1360,7 @@ #include "code\game\objects\structures\tranqcabinet.dm" #include "code\game\objects\structures\trash_pile.dm" #include "code\game\objects\structures\under_wardrobe.dm" +#include "code\game\objects\structures\undetonated_nuke.dm" #include "code\game\objects\structures\urban.dm" #include "code\game\objects\structures\warp_drive.dm" #include "code\game\objects\structures\watercloset.dm" @@ -1463,6 +1482,18 @@ #include "code\modules\admin\stickyban.dm" #include "code\modules\admin\ticket.dm" #include "code\modules\admin\topic.dm" +#include "code\modules\admin\buildmode\advanced.dm" +#include "code\modules\admin\buildmode\basic.dm" +#include "code\modules\admin\buildmode\buildmode.dm" +#include "code\modules\admin\buildmode\buttons.dm" +#include "code\modules\admin\buildmode\click_handler.dm" +#include "code\modules\admin\buildmode\edit.dm" +#include "code\modules\admin\buildmode\ladders.dm" +#include "code\modules\admin\buildmode\light_maker.dm" +#include "code\modules\admin\buildmode\move_into.dm" +#include "code\modules\admin\buildmode\relocate_to.dm" +#include "code\modules\admin\buildmode\room_builder.dm" +#include "code\modules\admin\buildmode\throw_at.dm" #include "code\modules\admin\callproc\callproc.dm" #include "code\modules\admin\DB ban\ban_mirroring.dm" #include "code\modules\admin\DB ban\functions.dm" @@ -1510,7 +1541,6 @@ #include "code\modules\admin\verbs\atmosdebug.dm" #include "code\modules\admin\verbs\bluespacetech.dm" #include "code\modules\admin\verbs\BrokenInhands.dm" -#include "code\modules\admin\verbs\buildmode.dm" #include "code\modules\admin\verbs\cinematic.dm" #include "code\modules\admin\verbs\clear_toxins.dm" #include "code\modules\admin\verbs\custom_event.dm" @@ -1624,7 +1654,7 @@ #include "code\modules\background\origins\origins\diona\coalition.dm" #include "code\modules\background\origins\origins\diona\deep_space.dm" #include "code\modules\background\origins\origins\diona\eridani.dm" -#include "code\modules\background\origins\origins\diona\eum.dm" +#include "code\modules\background\origins\origins\diona\hieroaetheria.dm" #include "code\modules\background\origins\origins\diona\moghes.dm" #include "code\modules\background\origins\origins\diona\narrows.dm" #include "code\modules\background\origins\origins\diona\nralakk.dm" @@ -1735,7 +1765,6 @@ #include "code\modules\client\preferences_spawnpoints.dm" #include "code\modules\client\preferences_toggles.dm" #include "code\modules\client\ui_style.dm" -#include "code\modules\client\preference_setup\_defines.dm" #include "code\modules\client\preference_setup\preference_setup.dm" #include "code\modules\client\preference_setup\preferences_sql.dm" #include "code\modules\client\preference_setup\antagonism\01_candidacy.dm" @@ -1797,6 +1826,7 @@ #include "code\modules\clothing\ears\xeno\bulwark.dm" #include "code\modules\clothing\ears\xeno\skrell.dm" #include "code\modules\clothing\ears\xeno\tajara.dm" +#include "code\modules\clothing\factions\assunzione.dm" #include "code\modules\clothing\factions\dominia.dm" #include "code\modules\clothing\factions\einstein.dm" #include "code\modules\clothing\factions\elyra.dm" @@ -2052,10 +2082,12 @@ #include "code\modules\effects\map_effects\sound_emitter.dm" #include "code\modules\effects\map_effects\window_spawner.dm" #include "code\modules\effects\map_effects\marker\_defines.dm" +#include "code\modules\effects\map_effects\marker\_marker.dm" #include "code\modules\effects\map_effects\marker\airlock_.dm" #include "code\modules\effects\map_effects\marker\airlock_docking.dm" #include "code\modules\effects\map_effects\marker\airlock_helper.dm" #include "code\modules\effects\map_effects\marker\airlock_shuttle.dm" +#include "code\modules\effects\map_effects\marker\large_tank.dm" #include "code\modules\effects\maze_generation\maze_generator.dm" #include "code\modules\effects\maze_generation\maze_generator_blockwise.dm" #include "code\modules\effects\maze_generation\maze_helper_atoms.dm" @@ -2360,6 +2392,8 @@ #include "code\modules\maps\planet_types\lore\burzsia.dm" #include "code\modules\maps\planet_types\lore\konyang.dm" #include "code\modules\maps\planet_types\lore\srandmarr.dm" +#include "code\modules\maps\planet_types\lore\tauceti.dm" +#include "code\modules\maps\planet_types\lore\uueoaesa.dm" #include "code\modules\martial_arts\gunkata.dm" #include "code\modules\martial_arts\martial.dm" #include "code\modules\martial_arts\plasma_fist.dm" @@ -2437,6 +2471,7 @@ #include "code\modules\mob\abstract\freelook\ai\chunk.dm" #include "code\modules\mob\abstract\freelook\ai\eye.dm" #include "code\modules\mob\abstract\freelook\ai\update_triggers.dm" +#include "code\modules\mob\abstract\freelook\blueprints\blueprints.dm" #include "code\modules\mob\abstract\new_player\character_traits.dm" #include "code\modules\mob\abstract\new_player\login.dm" #include "code\modules\mob\abstract\new_player\logout.dm" @@ -2882,7 +2917,6 @@ #include "code\modules\organs\internal\species\tajara.dm" #include "code\modules\organs\internal\species\unathi.dm" #include "code\modules\organs\internal\species\vaurca.dm" -#include "code\modules\organs\subtypes\augment.dm" #include "code\modules\organs\subtypes\autakh.dm" #include "code\modules\organs\subtypes\diona.dm" #include "code\modules\organs\subtypes\industrial.dm" @@ -2896,10 +2930,42 @@ #include "code\modules\organs\subtypes\vaurca.dm" #include "code\modules\organs\subtypes\xenos.dm" #include "code\modules\organs\subtypes\zombie.dm" +#include "code\modules\organs\subtypes\augment\augment.dm" +#include "code\modules\organs\subtypes\augment\augment_tool.dm" +#include "code\modules\organs\subtypes\augment\augments\cohlear.dm" +#include "code\modules\organs\subtypes\augment\augments\combitool.dm" +#include "code\modules\organs\subtypes\augment\augments\corrective_lens.dm" +#include "code\modules\organs\subtypes\augment\augments\crayon.dm" +#include "code\modules\organs\subtypes\augment\augments\cyber_hair.dm" +#include "code\modules\organs\subtypes\augment\augments\cybrong_analyzer.dm" +#include "code\modules\organs\subtypes\augment\augments\drill.dm" +#include "code\modules\organs\subtypes\augment\augments\emotional_manipulator.dm" +#include "code\modules\organs\subtypes\augment\augments\enhanced_vision.dm" +#include "code\modules\organs\subtypes\augment\augments\ethanol_burner.dm" +#include "code\modules\organs\subtypes\augment\augments\eye_sensors.dm" +#include "code\modules\organs\subtypes\augment\augments\fluff.dm" +#include "code\modules\organs\subtypes\augment\augments\fuel_cell.dm" +#include "code\modules\organs\subtypes\augment\augments\gustatorial_centre.dm" +#include "code\modules\organs\subtypes\augment\augments\health_analyzer.dm" +#include "code\modules\organs\subtypes\augment\augments\language_processor.dm" +#include "code\modules\organs\subtypes\augment\augments\lighter.dm" +#include "code\modules\organs\subtypes\augment\augments\memory_inhibitor.dm" +#include "code\modules\organs\subtypes\augment\augments\pen.dm" +#include "code\modules\organs\subtypes\augment\augments\phalanx_facial_plate.dm" +#include "code\modules\organs\subtypes\augment\augments\psi_receiver.dm" +#include "code\modules\organs\subtypes\augment\augments\sight_lights.dm" +#include "code\modules\organs\subtypes\augment\augments\suspension.dm" +#include "code\modules\organs\subtypes\augment\augments\synthetic_cords.dm" +#include "code\modules\organs\subtypes\augment\augments\taste_booster.dm" +#include "code\modules\organs\subtypes\augment\augments\tesla.dm" +#include "code\modules\organs\subtypes\augment\augments\timepiece.dm" +#include "code\modules\organs\subtypes\augment\augments\translator.dm" +#include "code\modules\organs\subtypes\augment\augments\zengu_plate.dm" #include "code\modules\organs\subtypes\parasite\_parasite.dm" #include "code\modules\organs\subtypes\parasite\black_kois.dm" #include "code\modules\organs\subtypes\parasite\heart_fluke.dm" #include "code\modules\organs\subtypes\parasite\kois.dm" +#include "code\modules\organs\subtypes\parasite\tumours.dm" #include "code\modules\organs\subtypes\parasite\worms.dm" #include "code\modules\organs\subtypes\parasite\zombie.dm" #include "code\modules\overmap\_defines.dm" @@ -2951,11 +3017,13 @@ #include "code\modules\overmap\exoplanets\decor\turfs\carpet.dm" #include "code\modules\overmap\exoplanets\decor\turfs\concrete.dm" #include "code\modules\overmap\exoplanets\decor\turfs\crystal.dm" +#include "code\modules\overmap\exoplanets\decor\turfs\diona.dm" #include "code\modules\overmap\exoplanets\decor\turfs\foundation.dm" #include "code\modules\overmap\exoplanets\decor\turfs\grass.dm" #include "code\modules\overmap\exoplanets\decor\turfs\ice.dm" #include "code\modules\overmap\exoplanets\decor\turfs\konyang.dm" #include "code\modules\overmap\exoplanets\decor\turfs\linoleum.dm" +#include "code\modules\overmap\exoplanets\decor\turfs\marble.dm" #include "code\modules\overmap\exoplanets\decor\turfs\mineral.dm" #include "code\modules\overmap\exoplanets\decor\turfs\plating.dm" #include "code\modules\overmap\exoplanets\decor\turfs\sand.dm" @@ -3326,6 +3394,7 @@ #include "code\modules\research\designs\circuit\mining_circuits.dm" #include "code\modules\research\designs\circuit\misc_electronics.dm" #include "code\modules\research\designs\circuit\shield_designs.dm" +#include "code\modules\research\designs\circuit\ship_circuits.dm" #include "code\modules\research\designs\circuit\tcom_designs.dm" #include "code\modules\research\designs\mechfab\hardsuit\modules.dm" #include "code\modules\research\designs\mechfab\hardsuit\rigs.dm" @@ -3687,9 +3756,10 @@ #include "maps\away\away_site\abandoned_diner\abandoned_diner.dm" #include "maps\away\away_site\abandoned_diner\abandoned_diner_areas.dm" #include "maps\away\away_site\abandoned_diner\abandoned_diner_landmarks.dm" -#include "maps\away\away_site\abandoned_industrial\abandoned_industrial_station.dm" +#include "maps\away\away_site\abandoned_industrial\abandoned_industrial_station_.dm" #include "maps\away\away_site\abandoned_industrial\abandoned_industrial_station_areas.dm" #include "maps\away\away_site\abandoned_industrial\abandoned_industrial_station_items.dm" +#include "maps\away\away_site\abandoned_industrial\abandoned_industrial_station_landmarks.dm" #include "maps\away\away_site\abandoned_mining\cursed.dm" #include "maps\away\away_site\abandoned_propellant_depot\abandoned_propellant_depot_.dm" #include "maps\away\away_site\abandoned_propellant_depot\abandoned_propellant_depot_areas.dm" @@ -3701,6 +3771,11 @@ #include "maps\away\away_site\crystal_planet_outpost\crystal_planet_outpost_.dm" #include "maps\away\away_site\crystal_planet_outpost\crystal_planet_outpost_areas.dm" #include "maps\away\away_site\crystal_planet_outpost\crystal_planet_outpost_landmarks.dm" +#include "maps\away\away_site\cult_base\cult_base_.dm" +#include "maps\away\away_site\cult_base\cult_base_areas.dm" +#include "maps\away\away_site\cult_base\cult_base_ghostroles.dm" +#include "maps\away\away_site\cult_base\cult_base_items.dm" +#include "maps\away\away_site\cult_base\cult_base_landmarks.dm" #include "maps\away\away_site\first_aurora\first_aurora.dm" #include "maps\away\away_site\hivebot_hub\hivebot_hub.dm" #include "maps\away\away_site\idris_wreck\idris_wreck.dm" @@ -3725,14 +3800,20 @@ #include "maps\away\away_site\tajara\mining_jack\mining_jack.dm" #include "maps\away\away_site\tajara\mining_jack\mining_jack_areas.dm" #include "maps\away\away_site\tajara\mining_jack\mining_jack_ghostroles.dm" +#include "maps\away\away_site\tajara\mining_jack\mining_jack_landmarks.dm" #include "maps\away\away_site\tajara\peoples_station\peoples_station.dm" #include "maps\away\away_site\tajara\peoples_station\peoples_station_ghostroles.dm" +#include "maps\away\away_site\tajara\peoples_station\peoples_station_landmarks.dm" #include "maps\away\away_site\tajara\peoples_station\peoples_station_zones.dm" #include "maps\away\away_site\tajara\pra_satellite\pra_satellite.dm" -#include "maps\away\away_site\tajara\saniorios_smuggler\saniorios_smuggler.dm" +#include "maps\away\away_site\tajara\saniorios_outpost\saniorios_landmarks.dm" +#include "maps\away\away_site\tajara\saniorios_outpost\saniorios_outpost.dm" +#include "maps\away\away_site\tajara\saniorios_outpost\saniorios_outpost_ghostroles.dm" +#include "maps\away\away_site\tajara\saniorios_outpost\saniorios_outpost_zones.dm" #include "maps\away\away_site\tajara\scrapper\scrapper.dm" #include "maps\away\away_site\tajara\scrapper\scrapper_areas.dm" #include "maps\away\away_site\tajara\scrapper\scrapper_ghostroles.dm" +#include "maps\away\away_site\tajara\scrapper\scrapper_landmarks.dm" #include "maps\away\away_site\tajara\taj_safehouse\tajara_safehouse.dm" #include "maps\away\away_site\tajara\taj_safehouse\tajara_safehouse_ghostroles.dm" #include "maps\away\away_site\wrecked_nt_ship\wrecked_nt_ship.dm" @@ -3769,6 +3850,7 @@ #include "maps\away\ships\dominia\dominian_unathi_privateer\dominian_unathi_privateer_ghostroles.dm" #include "maps\away\ships\dpra\hailstorm\hailstorm_areas.dm" #include "maps\away\ships\dpra\hailstorm\hailstorm_ghostroles.dm" +#include "maps\away\ships\dpra\hailstorm\hailstorm_landmarks.dm" #include "maps\away\ships\dpra\hailstorm\hailstorm_ship.dm" #include "maps\away\ships\einstein\ee_spy_ship.dm" #include "maps\away\ships\einstein\ee_spy_ship_ghostroles.dm" @@ -3822,11 +3904,13 @@ #include "maps\away\ships\nka\nka_merchant\nka_merchant.dm" #include "maps\away\ships\nka\nka_merchant\nka_merchant_areas.dm" #include "maps\away\ships\nka\nka_merchant\nka_merchant_ghostroles.dm" +#include "maps\away\ships\nka\nka_merchant\nka_merchant_landmarks.dm" #include "maps\away\ships\orion\orion_express_ship.dm" #include "maps\away\ships\orion\orion_express_ship_ghostroles.dm" #include "maps\away\ships\pra\database_freighter\database_freighter.dm" #include "maps\away\ships\pra\database_freighter\database_freighter_areas.dm" #include "maps\away\ships\pra\database_freighter\database_freighter_ghostroles.dm" +#include "maps\away\ships\pra\database_freighter\database_landmarks.dm" #include "maps\away\ships\pra\headmaster\headmaster_areas.dm" #include "maps\away\ships\pra\headmaster\headmaster_ghostroles.dm" #include "maps\away\ships\pra\headmaster\headmaster_ship.dm" @@ -3837,19 +3921,22 @@ #include "maps\away\ships\scc\scc_scout_ship_areas.dm" #include "maps\away\ships\scc\scc_scout_ship_ghostroles.dm" #include "maps\away\ships\scc\scc_scout_ship_landmarks.dm" -#include "maps\away\ships\sol_merc\fsf_patrol_ship.dm" -#include "maps\away\ships\sol_merc\fsf_patrol_ship_ghostroles.dm" -#include "maps\away\ships\sol_pirate\sfa_patrol_ship.dm" -#include "maps\away\ships\sol_pirate\sfa_patrol_ship_ghostroles.dm" -#include "maps\away\ships\sol_ssmd\ssmd_ship.dm" -#include "maps\away\ships\sol_ssmd\ssmd_ship_ghostroles.dm" +#include "maps\away\ships\sol\sol_merc\fsf_patrol_ship.dm" +#include "maps\away\ships\sol\sol_merc\fsf_patrol_ship_areas.dm" +#include "maps\away\ships\sol\sol_merc\fsf_patrol_ship_ghostroles.dm" +#include "maps\away\ships\sol\sol_pirate\sfa_patrol_ship.dm" +#include "maps\away\ships\sol\sol_pirate\sfa_patrol_ship_ghostroles.dm" +#include "maps\away\ships\sol\sol_ssmd\ssmd_ship.dm" +#include "maps\away\ships\sol\sol_ssmd\ssmd_ship_ghostroles.dm" #include "maps\away\ships\tajara\circus\adhomian_circus.dm" #include "maps\away\ships\tajara\circus\adhomian_circus_areas.dm" #include "maps\away\ships\tajara\circus\adhomian_circus_items.dm" +#include "maps\away\ships\tajara\circus\adhomian_circus_landmarks.dm" #include "maps\away\ships\tajara\circus\adhomian_circus_roles.dm" #include "maps\away\ships\tajara\taj_smuggler\tajaran_smuggler.dm" #include "maps\away\ships\tajara\taj_smuggler\tajaran_smuggler_areas.dm" #include "maps\away\ships\tajara\taj_smuggler\tajaran_smuggler_ghostroles.dm" +#include "maps\away\ships\tajara\taj_smuggler\tajaran_smuggler_landmarks.dm" #include "maps\away\ships\tirakqi_smuggler\tirakqi_smuggler.dm" #include "maps\away\ships\tirakqi_smuggler\tirakqi_smuggler_areas.dm" #include "maps\away\ships\tirakqi_smuggler\tirakqi_smuggler_ghostroles.dm" @@ -3866,6 +3953,10 @@ #include "maps\away\ships\unathi_pirate\tarwa\unathi_pirate_tarwa_ghostroles.dm" #include "maps\away\ships\wildlands_militia\militia_ship.dm" #include "maps\away\ships\wildlands_militia\militia_ship_ghostroles.dm" +#include "maps\away\ships\xanu\xanu_frigate.dm" +#include "maps\away\ships\xanu\xanu_frigate_areas.dm" +#include "maps\away\ships\xanu\xanu_frigate_ghostroles.dm" +#include "maps\away\ships\xanu\xanu_frigate_landmarks.dm" #include "maps\away\ships\yacht\yacht.dm" #include "maps\away\ships\yacht\yacht_areas.dm" #include "maps\away\ships\yacht_civ\yacht_civ_.dm" @@ -3926,6 +4017,14 @@ #include "maps\random_ruins\exoplanets\asteroid\coalition_base\coalition_base.dm" #include "maps\random_ruins\exoplanets\asteroid\mystery_ship\mystery_ship_areas.dm" #include "maps\random_ruins\exoplanets\asteroid\old_outpost\old_outpost.dm" +#include "maps\random_ruins\exoplanets\biesel\abandoned_warehouse_1.dm" +#include "maps\random_ruins\exoplanets\biesel\abandoned_warehouse_2.dm" +#include "maps\random_ruins\exoplanets\biesel\biesel_camp_site.dm" +#include "maps\random_ruins\exoplanets\biesel\biesel_crash.dm" +#include "maps\random_ruins\exoplanets\biesel\cargo_ruins_1.dm" +#include "maps\random_ruins\exoplanets\biesel\cargo_ruins_2.dm" +#include "maps\random_ruins\exoplanets\biesel\cargo_ruins_3.dm" +#include "maps\random_ruins\exoplanets\biesel\pra_camp_site.dm" #include "maps\random_ruins\exoplanets\burzsia\burzsia_dead_ipc.dm" #include "maps\random_ruins\exoplanets\burzsia\burzsia_mining.dm" #include "maps\random_ruins\exoplanets\crashed_pod\crashed_pod.dm" @@ -3964,10 +4063,74 @@ #include "maps\random_ruins\exoplanets\konyang\abandoned\office.dm" #include "maps\random_ruins\exoplanets\konyang\abandoned\rural_clinic.dm" #include "maps\random_ruins\exoplanets\lava\lava.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_bar.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_dead_guwandi.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_diona_traders.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_fishing_spot.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_gawgaryn_bikers.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_gawgaryn_riders.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_guild_mining.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_guwandi.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_hegemony_base.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_heph_mining.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_kataphract_wasteland.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_kung_fu.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_memorial.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_otzek_herd.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_ruined_base.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_siakh.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_skakh.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_thakh.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_threshbeast_herd.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_untouched_tyrant.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_untouched_village.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_battlefield.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_bomb.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_crash.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_crater.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_dorviza.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_izwesk.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_klax.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_mikuetz.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_oasis.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_ozeuoi.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_priests.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_queendom.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_reclaimer.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_tomb.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_tyrant.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_vihnmes.dm" +#include "maps\random_ruins\exoplanets\moghes\moghes_wasteland_village.dm" +#include "maps\random_ruins\exoplanets\new_gibson\gibson_mining.dm" +#include "maps\random_ruins\exoplanets\new_gibson\gibson_resupply.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_autakh.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_bar.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_battlefield.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_farm.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_fishing_spot.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_freewater.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_guild_mining.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_hegemony_base.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_heph_mining.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_nt_ruin.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_otzek_herd.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_rev_memorial.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_skrell_base.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_sol_base.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_threshbeast_herd.dm" +#include "maps\random_ruins\exoplanets\ouerea\ouerea_village.dm" #include "maps\random_ruins\exoplanets\raskara\pra_exploration_drone.dm" #include "maps\random_ruins\exoplanets\raskara\raskara_okon.dm" #include "maps\random_ruins\exoplanets\raskara\raskara_ritual.dm" #include "maps\random_ruins\exoplanets\raskara\raskara_wreck.dm" +#include "maps\random_ruins\exoplanets\uueoaesa\heph_mining_station.dm" +#include "maps\random_ruins\exoplanets\uueoaesa\heph_survey_post.dm" +#include "maps\random_ruins\exoplanets\uueoaesa\izweski_probe.dm" +#include "maps\random_ruins\exoplanets\uueoaesa\kazhkz_crash.dm" +#include "maps\random_ruins\exoplanets\uueoaesa\miners_guild_outpost.dm" +#include "maps\random_ruins\exoplanets\uueoaesa\pid_crashed_shuttle.dm" +#include "maps\random_ruins\exoplanets\uueoaesa\pid_kois_farm.dm" +#include "maps\random_ruins\exoplanets\uueoaesa\sol_listening_post.dm" #include "maps\random_ruins\space_ruins\space_ruins.dm" #include "maps\runtime\runtime_overmap.dm" #include "maps\runtime\code\runtime.dm" diff --git a/code/ZAS/Debug.dm b/code/ZAS/Debug.dm index 9ea464d4c8b..e314c8cc543 100644 --- a/code/ZAS/Debug.dm +++ b/code/ZAS/Debug.dm @@ -12,8 +12,8 @@ var/image/mark = image('icons/zone.dmi', icon_state = "mark") /turf/var/tmp/dbg_img /turf/proc/dbg(image/img, d = 0) if(d > 0) img.dir = d - cut_overlay(dbg_img) - add_overlay(img) + CutOverlays(dbg_img) + AddOverlays(img) dbg_img = img /proc/soft_assert(thing,fail) diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index 879da329629..e4a1286c3cd 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -129,7 +129,7 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin icon = 'icons/effects/fire.dmi' icon_state = "wavey_fire" light_color = LIGHT_COLOR_FIRE - layer = ABOVE_MOB_LAYER + layer = FIRE_LAYER var/firelevel = 1 //Calculated by gas_mixture.calculate_firelevel() diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm index e55949a4f87..db757c341a4 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -53,11 +53,11 @@ var/image/contamination_overlay = image('icons/effects/contamination.dmi') //Do a contamination overlay? Temporary measure to keep contamination less deadly than it was. if(!contaminated) contaminated = 1 - add_overlay(contamination_overlay, TRUE) + AddOverlays(contamination_overlay, ATOM_ICON_CACHE_PROTECTED) /obj/item/proc/decontaminate() contaminated = 0 - cut_overlay(contamination_overlay, TRUE) + CutOverlays(contamination_overlay, ATOM_ICON_CACHE_PROTECTED) /mob/proc/contaminate() @@ -167,17 +167,3 @@ var/image/contamination_overlay = image('icons/effects/contamination.dmi') if(w_uniform) w_uniform.contaminate() if(shoes) shoes.contaminate() if(gloves) gloves.contaminate() - - -/turf/Entered(atom/movable/thing, turf/oldLoc) - . = ..(thing, oldLoc) - //Items that are in phoron, but not on a mob, can still be contaminated. - var/obj/item/I = thing - if(istype(I) && vsc.plc.CLOTH_CONTAMINATION && I.can_contaminate()) - var/datum/gas_mixture/env = return_air(1) - if(!env) - return - for(var/g in env.gas) - if(gas_data.flags[g] & XGM_GAS_CONTAMINANT && env.gas[g] > gas_data.overlay_limit[g] + 1) - I.contaminate() - break diff --git a/code/__DEFINES/MC.dm b/code/__DEFINES/MC.dm index a68d33ecfe7..4e8369bd454 100644 --- a/code/__DEFINES/MC.dm +++ b/code/__DEFINES/MC.dm @@ -28,8 +28,8 @@ #define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;} -// #define START_PROCESSING(Processor, Datum) if (!(Datum.datum_flags & DF_ISPROCESSING)) {Datum.datum_flags |= DF_ISPROCESSING;Processor.processing += Datum} -// #define STOP_PROCESSING(Processor, Datum) Datum.datum_flags &= ~DF_ISPROCESSING;Processor.processing -= Datum;Processor.currentrun -= Datum +#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 /// Returns true if the MC is initialized and running. /// Optional argument init_stage controls what stage the mc must have initializted to count as initialized. Defaults to INITSTAGE_MAX if not specified. diff --git a/code/__DEFINES/_flags.dm b/code/__DEFINES/_flags.dm index cdcaaf21c3d..2dfb225b529 100644 --- a/code/__DEFINES/_flags.dm +++ b/code/__DEFINES/_flags.dm @@ -5,6 +5,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 // for /datum/var/datum_flags #define DF_USE_TAG (1<<0) +#define DF_ISPROCESSING (1<<2) ///Whether /atom/Initialize() has already run for the object #define INITIALIZED_1 (1<<5) diff --git a/code/__DEFINES/_layers.dm b/code/__DEFINES/_layers.dm deleted file mode 100644 index cc0a6698011..00000000000 --- a/code/__DEFINES/_layers.dm +++ /dev/null @@ -1,71 +0,0 @@ -#define PLANE_SPACE_BACKGROUND -99 -#define PLANE_SPACE_PARALLAX (PLANE_SPACE_BACKGROUND + 1) // -98 -#define PLANE_SKYBOX (PLANE_SPACE_PARALLAX + 1) // -97 -#define PLANE_SPACE_DUST (PLANE_SPACE_PARALLAX + 1) // -96 -#define PLANE_ABOVE_PARALLAX (PLANE_SPACE_DUST + 1) // -95 -#define PLANE_DEFAULT 0 -#define DECAL_PLATING_LAYER (TURF_LAYER + 0.01) -// TURF_LAYER 2 -#define LOWER_ON_TURF_LAYER (TURF_LAYER + 0.05) // under the below -#define ON_TURF_LAYER (TURF_LAYER + 0.1) // sitting on the turf - should be preferred over direct use of TURF_LAYER -#define DECAL_LAYER (ON_TURF_LAYER + 0.01) -#define AO_LAYER (ON_TURF_LAYER + 0.1) -#define UNDER_PIPE_LAYER (PIPE_LAYER - 0.1) -#define PIPE_LAYER 2.4 //under wires with their 2.44 -#define CABLE_LAYER 2.44 -#define ABOVE_CABLE_LAYER (CABLE_LAYER + 0.1) -#define LAYER_TABLE 2.8 -#define LAYER_UNDER_TABLE 2.79 -#define LAYER_ABOVE_TABLE 2.81 -#define BELOW_OBJ_LAYER 2.9 -// OBJ_LAYER 3 -#define DOOR_OPEN_LAYER 3 -#define ABOVE_OBJ_LAYER 3.01 -#define UNDERDOOR 3.09 //Just barely under a closed door. -#define WINDOW_PANE_LAYER 3.2 -#define DOOR_CLOSED_LAYER 3.6 //Above most items if closed -#define BELOW_MOB_LAYER 3.7 -// MOB_LAYER 4 -#define ABOVE_MOB_LAYER 4.1 -#define ABOVE_ALL_MOB_LAYER 4.5 -#define INGAME_HUD_EFFECT_LAYER 5 -#define LIGHTING_LAYER 11 -#define EFFECTS_ABOVE_LIGHTING_LAYER 12 // For overlays you want to be above light. -#define UNDER_HUD_LAYER 19 -#define HUD_LAYER 20 //Above lighting, but below obfuscation. For in-game HUD effects (whereas SCREEN_LAYER is for abstract/OOC things like inventory slots) -#define OBFUSCATION_LAYER 21 //Where images covering the view for eyes are put -#define SCREEN_LAYER 22 //Mob HUD/effects layer -#define CINEMA_LAYER 23 - - - -#define OVERMAP_SECTOR_LAYER 3.01 -#define OVERMAP_IMPORTANT_SECTOR_LAYER 3.02 -#define OVERMAP_SHIP_LAYER 3.03 -#define OVERMAP_SHUTTLE_LAYER 3.03 - -#define MECH_UNDER_LAYER 4 -#define MECH_BASE_LAYER 4.01 -#define MECH_HATCH_LAYER 4.02 -#define MECH_HEAD_LAYER 4.03 -#define MECH_EYES_LAYER 4.04 -#define MECH_LEG_LAYER 4.05 -#define MECH_ARM_LAYER 4.06 -#define MECH_DECAL_LAYER 4.07 -#define MECH_GEAR_LAYER 4.08 -#define MECH_ABOVE_LAYER 4.09 - -// Blob Layers -#define BLOB_SHIELD_LAYER 4.11 -#define BLOB_NODE_LAYER 4.12 -#define BLOB_CORE_LAYER 4.13 - -#define MIMICED_LIGHTING_LAYER 4.21 // Z-Mimic-managed lighting - -#define CLICKCATCHER_PLANE -100 - -#define DEFAULT_APPEARANCE_FLAGS (PIXEL_SCALE) - -/image/proc/turf_decal_layerise() - plane = PLANE_DEFAULT - layer = DECAL_LAYER diff --git a/code/__DEFINES/_macros.dm b/code/__DEFINES/_macros.dm index c83fb38f4ff..050551b3368 100644 --- a/code/__DEFINES/_macros.dm +++ b/code/__DEFINES/_macros.dm @@ -177,6 +177,9 @@ /// Decrease the size of L by 1 from the end. Is the old last entry index. #define LIST_DEC(L) ((L).len--) +/// Explicitly set the length of L to NEWLEN, adding nulls or dropping entries. Is the same value as NEWLEN. +#define LIST_RESIZE(L, NEWLEN) ((L).len = (NEWLEN)) + /// Drops x into the the src's location, and then nulls its reference. #define DROP_NULL(x) if(x) { x.dropInto(loc); x = null} diff --git a/code/__DEFINES/access.dm b/code/__DEFINES/access.dm index c3af191248e..4c2dbc8e770 100644 --- a/code/__DEFINES/access.dm +++ b/code/__DEFINES/access.dm @@ -694,11 +694,13 @@ #define ACCESS_COALITION 221 /datum/access/coalition id = ACCESS_COALITION + desc = "Coalition of Colonies" access_type = ACCESS_TYPE_CENTCOM #define ACCESS_COALITION_NAVY 222 /datum/access/coalition_navy id = ACCESS_COALITION_NAVY + desc = "Coalition Navy" access_type = ACCESS_TYPE_CENTCOM #define ACCESS_GADPATHUR_NAVY 223 @@ -721,6 +723,16 @@ id = ACCESS_HOUSE_VOLVALAAD_SHIP access_type = ACCESS_TYPE_CENTCOM +#define ACCESS_OZEUOI 227 +/datum/access/moghes_wasteland_ozeuoi + id = ACCESS_OZEUOI + access_type = ACCESS_TYPE_CENTCOM + +#define ACCESS_AUTAKH 228 +/datum/access/autakh + id = ACCESS_AUTAKH + access_type = ACCESS_TYPE_CENTCOM + //guest rooms - for any ship/event that requires hotel-esque rooms #define ACCESS_GUEST_ROOMS 230 //use with req_one_access diff --git a/code/__DEFINES/atmos.dm b/code/__DEFINES/atmos.dm index 6cc3f6b3561..ae6f22c4f8d 100644 --- a/code/__DEFINES/atmos.dm +++ b/code/__DEFINES/atmos.dm @@ -139,4 +139,13 @@ #define CONNECT_TYPE_FUEL 16 #define CONNECT_TYPE_AUX 32 -var/global/list/pipe_colors = list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "black" = PIPE_COLOR_BLACK, "purple" = PIPE_COLOR_PURPLE) +GLOBAL_LIST_INIT(pipe_colors, list( + "grey" = PIPE_COLOR_GREY, + "red" = PIPE_COLOR_RED, + "blue" = PIPE_COLOR_BLUE, + "cyan" = PIPE_COLOR_CYAN, + "green" = PIPE_COLOR_GREEN, + "yellow" = PIPE_COLOR_YELLOW, + "black" = PIPE_COLOR_BLACK, + "purple" = PIPE_COLOR_PURPLE +)) diff --git a/code/__DEFINES/background.dm b/code/__DEFINES/background.dm index c9edaac02d5..8f9aa929d03 100644 --- a/code/__DEFINES/background.dm +++ b/code/__DEFINES/background.dm @@ -10,7 +10,10 @@ #define CITIZENSHIP_IZWESKI "Izweski Hegemony" #define CITIZENSHIP_NRALAKK "Nralakk Federation" -#define CITIZENSHIP_EUM "Co-Operative Territories of EUM" + +#define CITIZENSHIP_CONSORTIUM "The Consortium of Hieroaetheria" +#define CITIZENSHIP_GLAORR "The Union of Gla'orr" +#define CITIZENSHIP_EKANE "The Eternal Republic of The Ekane" #define CITIZENSHIP_PRA "People's Republic of Adhomai" #define CITIZENSHIP_DPRA "Democratic People's Republic of Adhomai" @@ -63,8 +66,6 @@ #define RELIGION_ETERNAL "Orthodox Eternal" #define RELIGION_ETERNAL_ICHOR "Ichor Eternal" #define RELIGION_ETERNAL_IRON "Iron Eternal" -#define RELIGION_MADA "Maraka" -#define RELIGION_GLEANERS "Lights Accord" //accent defines @@ -169,13 +170,20 @@ #define ACCENT_SKRELLSOL "Solarian Skrell Standard" #define ACCENT_SKRELLCOC "Coalition Skrell Standard" #define ACCENT_SKRELLCETI "Biesellite Skrell Standard" -#define ACCENT_SKRELLEUM "Nral'Daaq" +#define ACCENT_SKRELLCONSORTIUM "Skrell Consortium Standard" #define ACCENT_SROM "Inner Voice" #define ACCENT_TATTUQIG "Tattuqig" #define ACCENT_ROOTSONG "Rootsong" #define ACCENT_VOIDSONG "Voidsong" -#define ACCENT_ANCIENTSONG "Ancientsong" +#define ACCENT_HIEROAETHERIAN "Hieroaetherian Old" +#define ACCENT_RAPTURIAN "Rapturian Voidsong" +#define ACCENT_CONSORTIUM "Consortium Standard" +#define ACCENT_GLAORR "Gla'orr Received Pronunciation" +#define ACCENT_EKANE "Ekanian" +#define ACCENT_ANU "Anu" +#define ACCENT_GENTLEWINDS "Gentle Winds" +#define ACCENT_HOPESTENDRILS "Hope's Tendrils" #define ACCENT_CRIMSONSONG "Crimsonsong" #define ACCENT_IRONSONG "Ironsong" #define ACCENT_SANDSONG "Sandsong" @@ -214,9 +222,11 @@ #define RELIGIONS_SOLARIAN list(RELIGION_NONE, RELIGION_CHRISTIANITY, RELIGION_ISLAM, RELIGION_SHINTO, RELIGION_BUDDHISM, RELIGION_HINDU, RELIGION_TAOISM, RELIGION_JUDAISM, RELIGION_SIKHISM, RELIGION_OTHER, RELIGION_TRINARY) #define CITIZENSHIPS_SOLARIAN list(CITIZENSHIP_SOL, CITIZENSHIP_BIESEL, CITIZENSHIP_ERIDANI, CITIZENSHIP_COALITION) -#define CITIZENSHIPS_NRALAKK list(CITIZENSHIP_NRALAKK, CITIZENSHIP_EUM) +#define CITIZENSHIPS_NRALAKK list(CITIZENSHIP_NRALAKK, CITIZENSHIP_CONSORTIUM) #define RELIGIONS_NRALAKK list(RELIGION_QEBLAK, RELIGION_WEISHII, RELIGION_SUURKA, RELIGION_KIRGUL, RELIGION_UNIVALVISM, RELIGION_OTHER, RELIGION_NONE) +#define CITIZENSHIPS_HIEROAETHERIA list(CITIZENSHIP_CONSORTIUM, CITIZENSHIP_GLAORR, CITIZENSHIP_EKANE) + #define RELIGIONS_ADHOMAI list(RELIGION_TWINSUNS, RELIGION_MATAKE, RELIGION_RASKARA, RELIGION_NONE, RELIGION_OTHER) #define CITIZENSHIPS_ADHOMAI list(CITIZENSHIP_PRA, CITIZENSHIP_DPRA, CITIZENSHIP_NKA) @@ -225,6 +235,6 @@ #define RELIGIONS_UNATHI list(RELIGION_THAKH, RELIGION_AUTAKH, RELIGION_SKAKH, RELIGION_SIAKH) #define ALL_CITIZENSHIPS list(CITIZENSHIP_BIESEL, CITIZENSHIP_SOL, CITIZENSHIP_COALITION, CITIZENSHIP_ELYRA, CITIZENSHIP_ELYRA,\ -CITIZENSHIP_ELYRA_NCP, CITIZENSHIP_ERIDANI, CITIZENSHIP_DOMINIA, CITIZENSHIP_IZWESKI, CITIZENSHIP_NRALAKK, CITIZENSHIP_EUM,\ +CITIZENSHIP_ELYRA_NCP, CITIZENSHIP_ERIDANI, CITIZENSHIP_DOMINIA, CITIZENSHIP_IZWESKI, CITIZENSHIP_NRALAKK,\ CITIZENSHIP_PRA, CITIZENSHIP_DPRA, CITIZENSHIP_NKA, CITIZENSHIP_FREE_COUNCIL, CITIZENSHIP_ZORA, CITIZENSHIP_KLAX, CITIZENSHIP_CTHUR,\ -CITIZENSHIP_NONE, CITIZENSHIP_GOLDEN) +CITIZENSHIP_NONE, CITIZENSHIP_GOLDEN, CITIZENSHIP_CONSORTIUM, CITIZENSHIP_GLAORR, CITIZENSHIP_EKANE) diff --git a/code/__DEFINES/chemistry.dm b/code/__DEFINES/chemistry.dm index 6ad8dcec322..de7aa5398d5 100644 --- a/code/__DEFINES/chemistry.dm +++ b/code/__DEFINES/chemistry.dm @@ -71,6 +71,7 @@ #define CE_STRAIGHTWALK "straightwalk" // prevents the confused walking chem side effect #define CE_NOSTUTTER "nostutter" // helps alleviate stuttering #define CE_HAUNTED "haunted" // Spectrocybin's ghost vision +#define CE_BLOODTHIN "bloodthin" // Makes you bleed out quicker // Apply healing effects #define CE_ANTIBIOTIC "antibiotic" // Thetamycin @@ -92,6 +93,7 @@ #define CE_HEPATOTOXIC "livertoxic" // Liver damage #define CE_CARDIOTOXIC "hearttoxic" // Heart damage #define CE_PNEUMOTOXIC "lungtoxic" // Lung damage +#define CE_OCULOTOXIC "eyetoxic" // Eye damage //Alcohol #define INTOX_BUZZED 0.01 @@ -105,15 +107,15 @@ #define INTOX_DEATH 0.45 //How many units of intoxication to remove per second -#define INTOX_FILTER_HEALTHY 0.10 -#define INTOX_FILTER_BRUISED 0.07 -#define INTOX_FILTER_DAMAGED 0.03 +#define INTOX_FILTER_HEALTHY 0.015 +#define INTOX_FILTER_BRUISED 0.007 +#define INTOX_FILTER_DAMAGED 0.003 #define BASE_DIZZY 50 //Base dizziness from getting drunk. #define DIZZY_ADD_SCALE 15 //Amount added for every 0.01 percent over the JUDGEIMP limit -#define BASE_VOMIT_CHANCE 10 //Base chance -#define VOMIT_CHANCE_SCALE 2.5 //Percent change added for every 0.01 percent over the VOMIT limit +#define BASE_VOMIT_CHANCE 1 //Base chance +#define VOMIT_CHANCE_SCALE 1 //Percent change added for every 0.01 percent over the VOMIT limit #define REAGENTS_FREE_SPACE(R) (R.maximum_volume - R.total_volume) diff --git a/code/__DEFINES/color.dm b/code/__DEFINES/color.dm index 6da480f868d..34492d7b6d9 100644 --- a/code/__DEFINES/color.dm +++ b/code/__DEFINES/color.dm @@ -92,6 +92,7 @@ #define COLOR_DIAMOND "#d8d4ea" #define COLOR_TCFL "#849bc1" #define COLOR_IAC "#96bcde" +#define COLOR_COALITION "#949ea3" #define COLOR_RIPLEY "#ffbc37" #define COLOR_CULT "#402821" #define COLOR_CULT_REINFORCED "#8f3329" @@ -101,6 +102,7 @@ #define COLOR_SNOW "#9CADAD" #define COLOR_LING_HIVEMIND "#583012" #define COLOR_LINOLEUM "#4E4D41" +#define COLOR_LEATHER "#5C4831" #define COLOR_TOOLS "#eac041" @@ -108,6 +110,7 @@ #define COLOR_TILED "#737878" #define COLOR_TILED_2 "#7A6E70" +#define COLOR_CONCRETE "#676661" // Blood colors #define COLOR_HUMAN_BLOOD "#A10808" diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm index b75c241ed24..8411e2829cc 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm @@ -16,3 +16,5 @@ #define COMPONENT_ATOM_BLOCK_EXIT (1<<0) ///from base of atom/Exited(): (atom/movable/gone, direction) #define COMSIG_ATOM_EXITED "atom_exited" +///from base of atom/has_gravity(): (turf/location, list/forced_gravities) +#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" diff --git a/code/__DEFINES/dcs/signals/signals_turf.dm b/code/__DEFINES/dcs/signals/signals_turf.dm new file mode 100644 index 00000000000..71737d4eb0a --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_turf.dm @@ -0,0 +1,6 @@ +// Turf signals. Format: +// When the signal is called: (signal arguments) +// All signals send the source datum of the signal as the first argument + +///from base of atom/has_gravity(): (atom/asker, list/forced_gravities) +#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity" diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index eb061cca3df..05f362a49ad 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -10,6 +10,11 @@ var/global/list/bitflags = list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define ZM_ALLOW_ATMOS 4 // If this turf permits passage of air. #define ZM_MIMIC_NO_AO 8 // If the turf shouldn't apply regular turf AO and only do Z-mimic AO. #define ZM_NO_OCCLUDE 16 // Don't occlude below atoms if we're a non-mimic z-turf. +#define ZM_MIMIC_BASETURF 32 // We dont want to show space, we want to show the base turf of the area (for stuff like glass floors) + +// Movable flags. +#define ZMM_IGNORE 1 //! Do not copy this movable. +#define ZMM_MANGLE_PLANES 2 //! Check this movable's overlays/underlays for explicit plane use and mangle for compatibility with Z-Mimic. If you're using emissive overlays, you probably should be using this flag. Expensive, only use if necessary. // Convenience flag. #define ZM_MIMIC_DEFAULTS (ZM_MIMIC_BELOW) @@ -18,10 +23,11 @@ var/global/list/bitflags = list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 var/list/mimic_defines = list( "ZM_MIMIC_BELOW", "ZM_MIMIC_OVERWRITE", - "ZM_ALLOW_LIGHTING", +// "ZM_ALLOW_LIGHTING", //Exists on Nebula, but not Aurora? "ZM_ALLOW_ATMOS", "ZM_MIMIC_NO_AO", - "ZM_NO_OCCLUDE" + "ZM_NO_OCCLUDE", + "ZM_MIMIC_BASETURF" ) //EMP protection @@ -46,6 +52,8 @@ var/list/mimic_defines = list( /// If a dense atom like a platform does not allow movement through it like a window pane BUT allows pickup. #define ATOM_FLAG_ALWAYS_ALLOW_PICKUP FLAG(7) +#define ATOM_AWAITING_OVERLAY_UPDATE FLAG(10) + // Movable flags. /// Does this object require proximity checking in Enter()? diff --git a/code/__DEFINES/global.dm b/code/__DEFINES/global.dm index 3e032671341..4197e95d48f 100644 --- a/code/__DEFINES/global.dm +++ b/code/__DEFINES/global.dm @@ -36,9 +36,6 @@ GLOBAL_PROTECT(href_logfile) GLOBAL_VAR_INIT(game_version, "Aurorastation") GLOBAL_PROTECT(game_version) -GLOBAL_VAR_INIT(changelog_hash, "") -GLOBAL_PROTECT(changelog_hash) - GLOBAL_VAR_INIT(game_year, (text2num(time2text(world.realtime, "YYYY")) + 442)) GLOBAL_VAR_INIT(round_progressing, 1) @@ -69,16 +66,12 @@ GLOBAL_DATUM(lobby_mobs_location, /turf) //Spawnpoints. GLOBAL_LIST_EMPTY(latejoin) -GLOBAL_LIST_EMPTY(latejoin_gateway) GLOBAL_LIST_EMPTY(latejoin_cryo) -GLOBAL_LIST_EMPTY(latejoin_cryo_command) GLOBAL_LIST_EMPTY(latejoin_cyborg) -GLOBAL_LIST_EMPTY(latejoin_merchant) GLOBAL_LIST_EMPTY(latejoin_living_quarters_lift) GLOBAL_LIST_EMPTY(kickoffsloc) GLOBAL_LIST_EMPTY(virtual_reality_spawn) -GLOBAL_LIST_EMPTY(asteroid_spawn) // Asteroid "Dungeons" spawn at these. GLOBAL_LIST_EMPTY(tdome1) GLOBAL_LIST_EMPTY(tdome2) GLOBAL_LIST_EMPTY(tdomeobserve) diff --git a/code/__DEFINES/icon_layering.dm b/code/__DEFINES/icon_layering.dm index c56dfba8a6b..eac113a0eeb 100644 --- a/code/__DEFINES/icon_layering.dm +++ b/code/__DEFINES/icon_layering.dm @@ -7,36 +7,37 @@ #define TAIL_SOUTH_LAYER 6 #define TAIL_SOUTH_ACC_LAYER 7 #define SHOES_LAYER_ALT 8 -#define UNIFORM_LAYER 9 -#define DAMAGE_LAYER 10 -#define ID_LAYER 11 -#define BANDAGE_LAYER 12 -#define SHOES_LAYER 13 -#define GLOVES_LAYER 14 -#define BELT_LAYER 15 -#define WRISTS_LAYER_ALT 16 -#define SUIT_LAYER 17 -#define ID_LAYER_ALT 18 -#define TAIL_NORTH_LAYER 19 -#define TAIL_NORTH_ACC_LAYER 20 -#define HAIR_LAYER_ALT 21 -#define GLASSES_LAYER 22 -#define BELT_LAYER_ALT 23 -#define SUIT_STORE_LAYER 24 -#define BACK_LAYER 25 -#define HAIR_LAYER 26 -#define GLASSES_LAYER_ALT 27 -#define L_EAR_LAYER 28 -#define R_EAR_LAYER 29 -#define FACEMASK_LAYER 30 -#define HEAD_LAYER 31 -#define GLASSES_LAYER_OVER 32 -#define COLLAR_LAYER 33 -#define HANDCUFF_LAYER 34 -#define LEGCUFF_LAYER 35 -#define L_HAND_LAYER 36 -#define R_HAND_LAYER 37 -#define WRISTS_LAYER 38 -#define FIRE_LAYER_UPPER 39 -#define TOTAL_LAYERS 39 +#define WRISTS_LAYER_UNDER 9 +#define UNIFORM_LAYER 10 +#define MOB_DAMAGE_LAYER 11 +#define ID_LAYER 12 +#define BANDAGE_LAYER 13 +#define SHOES_LAYER 14 +#define GLOVES_LAYER 15 +#define BELT_LAYER 16 +#define WRISTS_LAYER_UNIFORM 17 +#define SUIT_LAYER 18 +#define ID_LAYER_ALT 19 +#define TAIL_NORTH_LAYER 20 +#define TAIL_NORTH_ACC_LAYER 21 +#define HAIR_LAYER_ALT 22 +#define GLASSES_LAYER 23 +#define BELT_LAYER_ALT 24 +#define SUIT_STORE_LAYER 25 +#define BACK_LAYER 26 +#define HAIR_LAYER 27 +#define GLASSES_LAYER_ALT 28 +#define L_EAR_LAYER 29 +#define R_EAR_LAYER 30 +#define FACEMASK_LAYER 31 +#define HEAD_LAYER 32 +#define GLASSES_LAYER_OVER 33 +#define COLLAR_LAYER 34 +#define WRISTS_LAYER_OVER 35 +#define HANDCUFF_LAYER 36 +#define LEGCUFF_LAYER 37 +#define L_HAND_LAYER 38 +#define R_HAND_LAYER 39 +#define FIRE_LAYER_UPPER 40 +#define TOTAL_LAYERS 40 //////////////////////////// diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm new file mode 100644 index 00000000000..9149e00ba79 --- /dev/null +++ b/code/__DEFINES/layers.dm @@ -0,0 +1,204 @@ +// Planes, layers, and defaults for _renderer.dm +/* + from stddef.dm, planes & layers built into byond. + + FLOAT_LAYER = -1 + AREA_LAYER = 1 + TURF_LAYER = 2 + OBJ_LAYER = 3 + MOB_LAYER = 4 + FLY_LAYER = 5 + EFFECTS_LAYER = 5000 + TOPDOWN_LAYER = 10000 + BACKGROUND_LAYER = 20000 + ------ + + FLOAT_PLANE = -32767 +*/ + +#define LOWEST_PLANE -200 + +#define CLICKCATCHER_PLANE -100 + +#define SPACE_PLANE -99 + #define SPACE_LAYER 1 + +#define SKYBOX_PLANE -98 + #define SKYBOX_LAYER 1 + +#define DUST_PLANE -97 + #define DEBRIS_LAYER 1 + #define DUST_LAYER 2 + +// Openspace uses planes -80 through -70. +#define OPENTURF_MAX_PLANE -70 +#define OPENTURF_MAX_DEPTH 10 // The maxiumum number of planes deep we'll go before we just dump everything on the same plane. + +#define OVER_OPENSPACE_PLANE -4 + +#define WARP_EFFECT_PLANE -3 + +#define BLACKNESS_PLANE 0 //Blackness plane as per DM documentation. + +#define DEFAULT_PLANE 1 + #define PLATING_LAYER 1 + //ABOVE PLATING + #define HOLOMAP_LAYER 1.01 + #define DECAL_PLATING_LAYER 1.02 + #define DISPOSALS_PIPE_LAYER 1.03 + #define LATTICE_LAYER 1.04 + #define PIPE_LAYER 1.05 + #define WIRE_LAYER 1.06 + #define WIRE_TERMINAL_LAYER 1.07 + #define ABOVE_WIRE_LAYER 1.08 + //TURF_LAYER 2 + #define TURF_DETAIL_LAYER 2.01 + #define TURF_SHADOW_LAYER 2.02 + //ABOVE TURF + #define DECAL_LAYER 2.03 + #define RUNE_LAYER 2.04 + #define ABOVE_TILE_LAYER 2.05 + #define EXPOSED_PIPE_LAYER 2.06 + #define EXPOSED_WIRE_LAYER 2.07 + #define EXPOSED_WIRE_TERMINAL_LAYER 2.08 + #define CATWALK_LAYER 2.09 + #define ABOVE_CATWALK_LAYER 2.10 + #define BLOOD_LAYER 2.11 + #define MOUSETRAP_LAYER 2.12 + #define PLANT_LAYER 2.13 + #define AO_LAYER 2.14 + //HIDING MOB + #define HIDING_MOB_LAYER 2.15 + #define SHALLOW_FLUID_LAYER 2.16 + #define MOB_SHADOW_LAYER 2.17 + // OBJ + #define BELOW_DOOR_LAYER 2.18 + #define OPEN_DOOR_LAYER 2.19 + #define BELOW_TABLE_LAYER 2.20 + #define TABLE_LAYER 2.21 + #define ABOVE_TABLE_LAYER 2.22 + #define BELOW_OBJ_LAYER 2.23 + #define STRUCTURE_LAYER 2.24 + //OBJ_LAYER 3 + #define ABOVE_OBJ_LAYER 3.01 + #define UNDERDOOR 3.015 //Just barely under a closed door. TODO: Obsolete? + #define CLOSED_DOOR_LAYER 3.02 + #define ABOVE_DOOR_LAYER 3.03 + #define SIDE_WINDOW_LAYER 3.04 + #define FULL_WINDOW_LAYER 3.05 + #define ABOVE_WINDOW_LAYER 3.06 + #define HOLOMAP_OVERLAY_LAYER 3.061 + //LYING MOB AND HUMAN + #define LYING_MOB_LAYER 3.07 + #define LYING_HUMAN_LAYER 3.08 + #define BASE_ABOVE_OBJ_LAYER 3.09 + //HUMAN + #define BASE_HUMAN_LAYER 3.10 + //MOB_LAYER 4 + #define MECH_BASE_LAYER 4.01 + #define MECH_INTERMEDIATE_LAYER 4.02 + #define MECH_PILOT_LAYER 4.03 + #define MECH_LEG_LAYER 4.04 + #define MECH_COCKPIT_LAYER 4.05 + #define MECH_ARM_LAYER 4.06 + #define MECH_HEAD_LAYER 4.07 + #define MECH_GEAR_LAYER 4.08 + #define MECH_DECAL_LAYER 4.09 + //ABOVE_HUMAN + #define ABOVE_HUMAN_LAYER 4.10 + #define ABOVE_ABOVE_HUMAN_LAYER 4.101 + #define VEHICLE_LOAD_LAYER 4.11 + #define CAMERA_LAYER 4.12 + //BLOB + #define BLOB_SHIELD_LAYER 4.13 + #define BLOB_NODE_LAYER 4.14 + #define BLOB_CORE_LAYER 4.15 + //EFFECTS BELOW LIGHTING + #define BELOW_PROJECTILE_LAYER 4.16 + #define DEEP_FLUID_LAYER 4.17 + #define FIRE_LAYER 4.18 + #define PROJECTILE_LAYER 4.19 + #define ABOVE_PROJECTILE_LAYER 4.20 + #define SINGULARITY_LAYER 4.21 + #define POINTER_LAYER 4.22 + #define MIMICED_LIGHTING_LAYER 4.23 // Z-Mimic-managed lighting + //FLY_LAYER 5 + //OBSERVER + #define OBSERVER_LAYER 5.1 + #define OBFUSCATION_LAYER 5.2 + + #define OVERMAP_SECTOR_LAYER 60 + #define OVERMAP_IMPORTANT_SECTOR_LAYER 61 + #define OVERMAP_SHIP_LAYER 62 + #define OVERMAP_SHUTTLE_LAYER 63 + + #define AREA_LAYER 999 + +#define OBSERVER_PLANE 3 + +#define LIGHTING_PLANE 4 + #define LIGHTING_LAYER 1 + +#define EFFECTS_ABOVE_LIGHTING_PLANE 5 + #define EYEGLOW_LAYER 1 + #define BEAM_PROJECTILE_LAYER 2 + #define SUPERMATTER_WALL_LAYER 3 + #define LIGHTNING_LAYER 4 + +#define FULLSCREEN_PLANE 6 + #define FULLSCREEN_LAYER 1 + #define DAMAGE_LAYER 2 + #define IMPAIRED_LAYER 3 + #define BLIND_LAYER 4 + #define CRIT_LAYER 5 + +#define HUD_PLANE 7 + #define UNDER_HUD_LAYER 1 + #define HUD_BASE_LAYER 2 + #define HUD_ITEM_LAYER 3 + #define HUD_ABOVE_ITEM_LAYER 4 + #define RADIAL_BACKGROUND_LAYER 5 + #define RADIAL_BASE_LAYER 6 + #define RADIAL_CONTENT_LAYER 7 + +//-------------------- Rendering --------------------- + +/// Semantics - The final compositor or a filter effect renderer +#define RENDER_GROUP_NONE null + +/// Things to be drawn within the game context +#define RENDER_GROUP_SCENE 990 + +/// Things to be drawn within the screen context +#define RENDER_GROUP_SCREEN 995 + +/// The final render group, for compositing +#define RENDER_GROUP_FINAL 999 + +/// Integer (One of `*_PLANE`). The atom's rendering plane. See `code\__defines\__renderer.dm` for a list of valid planes. Also see the DM Reference for `plane var (atom)`. +/atom/plane = DEFAULT_PLANE + +#define DEFAULT_APPEARANCE_FLAGS (PIXEL_SCALE) + +#define DEFAULT_RENDERER_APPEARANCE_FLAGS (PLANE_MASTER | NO_CLIENT_COLOR) + +/atom/appearance_flags = DEFAULT_APPEARANCE_FLAGS +/atom/movable/appearance_flags = DEFAULT_APPEARANCE_FLAGS | TILE_BOUND // Most AMs are not visibly bigger than a tile. +/image/appearance_flags = DEFAULT_APPEARANCE_FLAGS +/mutable_appearance/appearance_flags = DEFAULT_APPEARANCE_FLAGS // Inherits /image but re docs, subject to change + +/atom/proc/hud_layerise() + plane = HUD_PLANE + layer = HUD_ITEM_LAYER + +/image/proc/turf_decal_layerise() + plane = DEFAULT_PLANE + layer = DECAL_LAYER + +/image/proc/plating_decal_layerise() + plane = DEFAULT_PLANE + layer = DECAL_PLATING_LAYER + +/atom/proc/reset_plane_and_layer() + plane = initial(plane) + layer = initial(layer) diff --git a/code/__DEFINES/machinery.dm b/code/__DEFINES/machinery.dm index 2e57c309280..495fac0beba 100644 --- a/code/__DEFINES/machinery.dm +++ b/code/__DEFINES/machinery.dm @@ -1,6 +1,5 @@ -#define KILOWATTS *1000 -#define MEGAWATTS *1000000 -#define GIGAWATTS *1000000000 +//Watts, yes this is stupid but it's just for visual reference to the code reader, so deal with it +#define WATTS *1 /** * Multiplier for watts per tick <> cell storage (e.g., 0.02 means if there is a load of 1000 watts, 20 units will be taken from a cell per second) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 13a4c60d3ef..368493a4dac 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -135,6 +135,7 @@ #define AREA_FLAG_PRISON BITFLAG(6) // Marks prison area for purposes of checking if brigged/imprisoned #define AREA_FLAG_NO_GHOST_TELEPORT_ACCESS BITFLAG(7) // Marks whether ghosts should not have teleport access to this area #define AREA_FLAG_INDESTRUCTIBLE_TURFS BITFLAG(8) //Marks whether or not turfs in this area can be destroyed by explosions +#define AREA_FLAG_IS_BACKGROUND BITFLAG(9) //Marks whether or not blueprints can create areas on top of this area // Convoluted setup so defines can be supplied by Bay12 main server compile script. // Should still work fine for people jamming the icons into their repo. diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 58cf86bccdb..09e3c0c3c57 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -146,39 +146,42 @@ #define BP_ZOMBIE_PARASITE "black tumour" #define BP_WORM_HEART "heart fluke" #define BP_WORM_NERVE "nerve fluke" +#define BP_TUMOUR_NONSPREADING "benign tumour" +#define BP_TUMOUR_SPREADING "malignant tumour" //Augment organs -#define BP_AUG_TIMEPIECE "integrated timepiece" -#define BP_AUG_TOOL "retractable combitool" -#define BP_AUG_PEN "retractable combipen" -#define BP_AUG_CRAYON "retractable crayon" -#define BP_AUG_CYBORG_ANALYZER "retractable cyborg analyzer" -#define BP_AUG_LIGHTER "retractable lighter" -#define BP_AUG_HEALTHSCAN "integrated health scanner" -#define BP_AUG_DRILL "integrated mining drill" -#define BP_AUG_GUSTATORIAL "integrated gustatorial centre" -#define BP_AUG_TESLA "tesla spine" -#define BP_AUG_EYE_SENSORS "integrated eyes sensors" -#define BP_AUG_HAIR "synthetic hair extensions" -#define BP_AUG_CORDS "synthetic vocal cords" -#define BP_AUG_COCHLEAR "cochlear implant" -#define BP_AUG_SUSPENSION "calf suspension" -#define BP_AUG_TASTE_BOOSTER "taste booster" -#define BP_AUG_RADIO "integrated radio" -#define BP_AUG_FUEL_CELL "integrated fuel cell" +#define BP_AUG_ACC_CORDS "modified synthetic vocal cords" #define BP_AUG_AIR_ANALYZER "integrated air analyzer" -#define BP_AUG_LANGUAGE "integrated language processor" -#define BP_AUG_ETHANOL_BURNER "integrated ethanol burner" -#define BP_AUG_PSI "psionic receiver" #define BP_AUG_CALF_OVERRIDE "calf overdrive" -#define BP_AUG_MEMORY "memory inhibitor" +#define BP_AUG_COCHLEAR "cochlear implant" +#define BP_AUG_CORDS "synthetic vocal cords" +#define BP_AUG_CORRECTIVE_LENS "corrective lenses" +#define BP_AUG_CRAYON "retractable crayon" +#define BP_AUG_CYBORG_ANALYZER "retractable cyborg analyzer" +#define BP_AUG_DRILL "integrated mining drill" #define BP_AUG_EMOTION "emotional manipulator" #define BP_AUG_ENCHANED_VISION "vision enhanced retinas" +#define BP_AUG_ETHANOL_BURNER "integrated ethanol burner" +#define BP_AUG_EYE_SENSORS "integrated eyes sensors" +#define BP_AUG_FUEL_CELL "integrated fuel cell" +#define BP_AUG_GLARE_DAMPENER "glare dampeners" +#define BP_AUG_GUSTATORIAL "integrated gustatorial centre" +#define BP_AUG_HAIR "synthetic hair extensions" +#define BP_AUG_HEALTHSCAN "integrated health scanner" +#define BP_AUG_LANGUAGE "integrated language processor" +#define BP_AUG_LIGHTER "retractable lighter" +#define BP_AUG_MAGBOOT "integrated mag-claws" +#define BP_AUG_MEMORY "memory inhibitor" +#define BP_AUG_PEN "retractable combipen" +#define BP_AUG_PSI "psionic receiver" +#define BP_AUG_RADIO "integrated radio" #define BP_AUG_SIGHTLIGHTS "ocular installed sightlights" -#define BP_AUG_CORRECTIVE_LENS "corrective lenses" -#define BP_AUG_GLARE_DAMPENER "glare dampeners" -#define BP_AUG_ACC_CORDS "modified synthetic vocal cords" -#define BP_AUG_MAGBOOT "integrated mag-claws" +#define BP_AUG_SUSPENSION "calf suspension" +#define BP_AUG_TASTE_BOOSTER "taste booster" +#define BP_AUG_TESLA "tesla spine" +#define BP_AUG_TIMEPIECE "integrated timepiece" +#define BP_AUG_TRANSLATOR "universal translator" +#define BP_AUG_TOOL "retractable combitool" //Organ defines #define PROCESS_ACCURACY 10 @@ -216,10 +219,11 @@ #define APPEARANCE_EYE_COLOR 256 #define APPEARANCE_CULTURE 512 #define APPEARANCE_LANGUAGE 1024 +#define APPEARANCE_PROSTHETICS 2048 #define APPEARANCE_ALL 65535 #define APPEARANCE_ALL_HAIR (APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR) #define APPEARANCE_PLASTICSURGERY (APPEARANCE_ALL & ~APPEARANCE_RACE) -#define APPEARANCE_SURGERYKIT (APPEARANCE_PLASTICSURGERY & ~APPEARANCE_LANGUAGE) +#define APPEARANCE_SURGERYKIT (APPEARANCE_PLASTICSURGERY & ~APPEARANCE_LANGUAGE & ~ APPEARANCE_PROSTHETICS) // Click cooldown #define DEFAULT_ATTACK_COOLDOWN 8 //Default timeout for aggressive actions @@ -420,6 +424,13 @@ #define PROSTHETIC_TESLA "Tesla Powered Prosthetics" #define PROSTHETIC_TESLA_BODY "Industrial Tesla Powered Prosthetics" #define PROSTHETIC_VAURCA "Vaurca Robotic Limb" +#define PROSTHETIC_UNBRANDED "Unbranded" +#define PROSTHETIC_HOPLAN "Hoplan Head" +#define PROSTHETIC_RAXUS "Raxus Head" +#define PROSTHETIC_INDRICUS "Indricus Head" + +//Prosthetics that aren't restricted by species +#define PROSTHETICS_UNRESTRICTED list(PROSTHETIC_BC, PROSTHETIC_HI, PROSTHETIC_XMG, PROSTHETIC_UNBRANDED, PROSTHETIC_ZH) //Brain Damage defines #define BRAIN_DAMAGE_MILD 10 diff --git a/code/__DEFINES/origin_traits.dm b/code/__DEFINES/origin_traits.dm index e3b61db362d..2a173f55e21 100644 --- a/code/__DEFINES/origin_traits.dm +++ b/code/__DEFINES/origin_traits.dm @@ -8,6 +8,8 @@ #define TRAIT_ORIGIN_HOT_RESISTANCE "hot_resistance" #define TRAIT_ORIGIN_NO_ANIMAL_PROTEIN "no_animal_protein" #define TRAIT_ORIGIN_LIGHT_SENSITIVE "light_sensitive" +#define TRAIT_ORIGIN_STAMINA_BONUS "stamina_bonus" +#define TRAIT_ORIGIN_PAIN_RESISTANCE "pain_resistance" //Vaurca-specific traits #define TRAIT_ORIGIN_ELECTRONIC_WARFARE "electronic_warfare" diff --git a/code/__DEFINES/prefs.dm b/code/__DEFINES/prefs.dm new file mode 100644 index 00000000000..4d058b8ac1e --- /dev/null +++ b/code/__DEFINES/prefs.dm @@ -0,0 +1,18 @@ +#define EQUIP_PREVIEW_LOADOUT 1 +#define EQUIP_PREVIEW_JOB 2 +#define EQUIP_PREVIEW_ALL (EQUIP_PREVIEW_LOADOUT|EQUIP_PREVIEW_JOB) + +/// External organ. Is a prosthesis with a robo-limb manufacturer. +#define ORGAN_PREF_CYBORG "cyborg" +/// External organ. Amputated. +#define ORGAN_PREF_AMPUTATED "amputated" +/// External organ. Nymph-limb. +#define ORGAN_PREF_NYMPH "nymph" + +/// Internal organ. Assisted, so halfway through mechanical. +#define ORGAN_PREF_ASSISTED "assisted" +/// Internal organ. Mechanical, so has a robo-limb manufacturer. +#define ORGAN_PREF_MECHANICAL "mechanical" +/// Internal organ. Removed, used for appendixes. +#define ORGAN_PREF_REMOVED "removed" +/// Note that a "normal" limb or organ has no pref, so there's no define for it. diff --git a/code/__DEFINES/profiler_tracy.dm b/code/__DEFINES/profiler_tracy.dm index 8559b39833c..8459041a224 100644 --- a/code/__DEFINES/profiler_tracy.dm +++ b/code/__DEFINES/profiler_tracy.dm @@ -3,16 +3,27 @@ // and https://github.com/ParadiseSS13/byond-tracy // Tracy Client https://github.com/wolfpld/tracy -var/byond_tracy_running = 0 // Whether byond-tracy is currently running or not, no matter what version. -var/byond_tracy_running_v = null // Which version of byond-tracy is currently running, so we call the right binary on destruction. +#define DISK_VERSION "disk" +#define CONNECTION_VERSION "connection" + +/// Whether byond-tracy is currently running or not, no matter what version. +GLOBAL_VAR_INIT(byond_tracy_running, FALSE) + +/// Which version of byond-tracy is currently running, so we call the right binary on destruction. +GLOBAL_VAR_INIT(byond_tracy_running_v, FALSE) + +/// The path we have invoked to load byond tracy +GLOBAL_VAR_INIT(byond_tracy_path, FALSE) /world/New() + CAN_BE_REDEFINED(TRUE) if(GLOB.config.enable_byond_tracy) prof_init("tracy_disk") // This start's Affectedarc07's version of Tracy. Writing a .utracy file to the disk. . = ..() /world/Del() - if(byond_tracy_running) + CAN_BE_REDEFINED(TRUE) + if(GLOB.byond_tracy_running) prof_destroy() . = ..() @@ -20,14 +31,23 @@ var/byond_tracy_running_v = null // Which version of byond-tracy is currently ru set name = "Start Tracy Profiler" set category = "Debug" set desc = "Starts the tracy profiler, which will await the client connection or save utracy files to the server's disk." - if(!byond_tracy_running) + if(!GLOB.byond_tracy_running) switch(alert("Are you sure? Tracy will remain active until the server restarts.", "Tracy Init", "No", "Yes")) if("Yes") switch(alert("Which version of Tracy would you like to run?", "Tracy Version", "Cancel", "Connection Based", "Disk Based")) if("Connection Based") - prof_init("tracy") // This start's mafemergency's original version of Tracy. Requiring a direct connection, not writing to the disk. + world.SetConfig("env", "UTRACY_BIND_ADDRESS", "0.0.0.0") + + var/port = input("What port would you like to use?", "Tracy Port", "8086") as num + if(!(port == 8086 || port > 4096)) + alert("Invalid port. Please enter a valid port number, either 8086 or bigger than 4096.") + return + + world.SetConfig("env", "UTRACY_BIND_PORT", "[port]") + prof_init(CONNECTION_VERSION) // This start's mafemergency's original version of Tracy. Requiring a direct connection, not writing to the disk. + if("Disk Based") - prof_init("tracy_disk") // This start's Affectedarc07's version of Tracy. Writing a .utracy file to the disk. + prof_init(DISK_VERSION) // This start's Affectedarc07's version of Tracy. Writing a .utracy file to the disk. /** * Starts Tracy. @@ -36,14 +56,28 @@ var/byond_tracy_running_v = null // Which version of byond-tracy is currently ru var/lib switch(version) - if("tracy") lib = "tracy.dll" - if("tracy_disk") lib = "tracy-disk.dll" + if(CONNECTION_VERSION) + if(world.system_type == MS_WINDOWS) + lib = "tracy.dll" + else if(world.system_type == UNIX) + lib = "libprof.so" + else + CRASH("unsupported platform") + + if(DISK_VERSION) + if(world.system_type == MS_WINDOWS) + lib = "tracy-disk.dll" + else if(world.system_type == UNIX) + lib = "libprof-disk.so" //this doesn't currently exist btw + else + CRASH("unsupported platform") + GLOB.byond_tracy_path = lib var/init = call_ext(lib, "init")() if("0" != init) CRASH("[lib] init error: [init]") - byond_tracy_running = 1 - byond_tracy_running_v = version + GLOB.byond_tracy_running = TRUE + GLOB.byond_tracy_running_v = version /** * Stops Tracy. @@ -52,11 +86,27 @@ var/byond_tracy_running_v = null // Which version of byond-tracy is currently ru /proc/prof_destroy() var/lib - switch(byond_tracy_running_v) - if("tracy") lib = "tracy.dll" - if("tracy_disk") lib = "tracy-disk.dll" + switch(GLOB.byond_tracy_running_v) + if(CONNECTION_VERSION) + if(world.system_type == MS_WINDOWS) + lib = "tracy.dll" + else if(world.system_type == UNIX) + lib = "libprof.so" + else + CRASH("unsupported platform") + + if(DISK_VERSION) + if(world.system_type == MS_WINDOWS) + lib = "tracy-disk.dll" + else if(world.system_type == UNIX) + lib = "libprof-disk.so" //this doesn't currently exist btw + else + CRASH("unsupported platform") call_ext(lib, "destroy")() - byond_tracy_running = 0 - byond_tracy_running_v = null + GLOB.byond_tracy_running = FALSE + GLOB.byond_tracy_running_v = null + +#undef DISK_VERSION +#undef CONNECTION_VERSION diff --git a/code/__DEFINES/rust_bapi.dm b/code/__DEFINES/rust_bapi.dm new file mode 100644 index 00000000000..0c8bfe9b753 --- /dev/null +++ b/code/__DEFINES/rust_bapi.dm @@ -0,0 +1,39 @@ + +// Default automatic .dll/.so detection. +// Look for it in the build location first, then in `.`, then in standard places. + +/* This comment bypasses grep checks */ /var/__bapi + +/proc/__detect_bapi() + if(world.system_type == UNIX) +#ifdef CIBUILDING + // CI override, use libbapi_ci.so if possible. + if(fexists("./tools/ci/libbapi_ci.so")) + return __bapi = "tools/ci/libbapi_ci.so" +#endif + // First check if it's built in the usual place. + if(fexists("./bapi/target/i686-unknown-linux-gnu/release/libbapi.so")) + return __bapi = "./bapi/target/i686-unknown-linux-gnu/release/libbapi.so" + // Then check in the current directory. + if(fexists("./libbapi.so")) + return __bapi = "./libbapi.so" + // And elsewhere. + return __bapi = "libbapi.so" + else + // First check if it's built in the usual place. + if(fexists("./rust/bapi/target/i686-pc-windows-msvc/release/bapi.dll")) + return __bapi = "./rust/bapi/target/i686-pc-windows-msvc/release/bapi.dll" + // Then check in the current directory. + if(fexists("./bapi.dll")) + return __bapi = "./bapi.dll" + // And elsewhere. + return __bapi = "bapi.dll" + +#define BAPI (__bapi || __detect_bapi()) + +#define BAPI_CALL(func, args...) call_ext(BAPI, "byond:[#func]_ffi")(args) + +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- + +#define bapi_hello_world(arg) BAPI_CALL(hello_world, arg) diff --git a/code/__DEFINES/ship_weapons.dm b/code/__DEFINES/ship_weapons.dm index 29bec771f1e..7ce3ee7076b 100644 --- a/code/__DEFINES/ship_weapons.dm +++ b/code/__DEFINES/ship_weapons.dm @@ -2,7 +2,7 @@ #define SHIP_CALIBER_406MM "406mm" #define SHIP_CALIBER_40MM "40mm" #define SHIP_CALIBER_90MM "90mm" -#define SHIP_CALIBER_ZTA "zero-point warp beam" +#define SHIP_CALIBER_ZAT "zero-point warp beam" #define SHIP_CALIBER_178MM "178mm" #define SHIP_CALIBER_COILGUN "tungsten rod" #define SHIP_CALIBER_200MM "200mm" @@ -25,7 +25,7 @@ #define SHIP_AMMO_IMPACT_LASER "laser" #define SHIP_AMMO_IMPACT_BUNKERBUSTER "bunker-buster" #define SHIP_AMMO_IMPACT_PLASMA "plasma" -#define SHIP_AMMO_IMPACT_ZTA "zero-point warp beam" +#define SHIP_AMMO_IMPACT_ZAT "zero-point warp beam" #define SHIP_AMMO_IMPACT_BLASTER "blaster charge" #define FIRING_EFFECT_FLAG_THROW_MOBS 1 diff --git a/code/__DEFINES/si.dm b/code/__DEFINES/si.dm new file mode 100644 index 00000000000..b63f048e0b3 --- /dev/null +++ b/code/__DEFINES/si.dm @@ -0,0 +1,21 @@ +// Prefix values. +#define QUECTO * 1e-30 +#define RONTO * 1e-27 +#define YOCTO * 1e-24 +#define ZEPTO * 1e-21 +#define ATTO * 1e-18 +#define FEMPTO * 1e-15 +#define PICO * 1e-12 +#define NANO * 1e-9 +#define MICRO * 1e-6 +#define MILLI * 1e-3 +#define KILO * 1e3 +#define MEGA * 1e6 +#define GIGA * 1e9 +#define TERA * 1e12 +#define PETA * 1e15 +#define EXA * 1e18 +#define ZETTA * 1e21 +#define YOTTA * 1e24 +#define RONNA * 1e27 +#define QUETTA * 1e30 diff --git a/code/__DEFINES/space_sectors.dm b/code/__DEFINES/space_sectors.dm index 8020ce1e087..ea646bf42b8 100644 --- a/code/__DEFINES/space_sectors.dm +++ b/code/__DEFINES/space_sectors.dm @@ -39,9 +39,12 @@ #define ALL_GENERIC_SECTORS list(SECTOR_STAR_NURSERY, SECTOR_GENERIC) //For sectors where corporate entities can or should appear. Corporate ships having this tag can be seen more reliably -#define ALL_CORPORATE_SECTORS list(ALL_TAU_CETI_SECTORS, SECTOR_SRANDMARR, SECTOR_UUEOAESA, ALL_COALITION_SECTORS, ALL_GENERIC_SECTORS, SECTOR_GAKAL, SECTOR_NRRAHRAHUL, SECTOR_BADLANDS)//Currently excludes Elyran sectors and Light's Edge +#define ALL_CORPORATE_SECTORS list(ALL_TAU_CETI_SECTORS, SECTOR_SRANDMARR, SECTOR_UUEOAESA, ALL_COALITION_SECTORS, ALL_GENERIC_SECTORS, SECTOR_NRRAHRAHUL, SECTOR_BADLANDS)//Currently excludes Elyran sectors and Light's Edge //For highly dangerous sectors with high piracy. Civilian and leisure ships should be less common or not found here. #define ALL_DANGEROUS_SECTORS list(SECTOR_BADLANDS, ALL_VOID_SECTORS) +/// all non-generic, named and specific sectors, where generic planets or the like should not spawn +#define ALL_SPECIFIC_SECTORS list(SECTOR_TAU_CETI, SECTOR_SRANDMARR, SECTOR_HANEUNIM, SECTOR_BURZSIA, SECTOR_UUEOAESA, SECTOR_NEW_ANKARA, SECTOR_AEMAQ, SECTOR_NRRAHRAHUL, SECTOR_GAKAL) + #define ALL_POSSIBLE_SECTORS list(ALL_TAU_CETI_SECTORS, ALL_BADLAND_SECTORS, ALL_COALITION_SECTORS, ALL_VOID_SECTORS, ALL_GENERIC_SECTORS, ALL_CORPORATE_SECTORS) diff --git a/code/__DEFINES/species.dm b/code/__DEFINES/species.dm index f50d8d79de3..e27da1f94c3 100644 --- a/code/__DEFINES/species.dm +++ b/code/__DEFINES/species.dm @@ -112,3 +112,31 @@ SPECIES_UNATHI, \ SPECIES_VAURCA_WORKER, SPECIES_VAURCA_WARRIOR, SPECIES_VAURCA_BULWARK, SPECIES_VAURCA_BREEDER, \ ) + +#define ALL_HUMAN_SPECIES list(\ + SPECIES_HUMAN, SPECIES_HUMAN_OFFWORLD, SPECIES_HUMAN_VATGROWN, \ + ) + +#define ALL_DIONA_SPECIES list(\ + SPECIES_DIONA, SPECIES_DIONA_COEUS, \ + ) + +#define ALL_SKRELL_SPECIES list(\ + SPECIES_SKRELL, SPECIES_SKRELL_AXIORI, \ + ) + +#define ALL_TAJARA_SPECIES list(\ + SPECIES_TAJARA, SPECIES_TAJARA_ZHAN, SPECIES_TAJARA_MSAI, SPECIES_TAJARA_TESLA_BODY, \ + ) + +#define ALL_VAURCA_SPECIES list(\ + SPECIES_VAURCA_WORKER, SPECIES_VAURCA_WARRIOR, SPECIES_VAURCA_BREEDER, SPECIES_VAURCA_WARFORM, SPECIES_VAURCA_BULWARK, \ + ) + +#define ALL_IPC_SPECIES list(\ + SPECIES_IPC, SPECIES_IPC_BISHOP, SPECIES_IPC_G1, SPECIES_IPC_G2, SPECIES_IPC_SHELL, \ + SPECIES_IPC_UNBRANDED, SPECIES_IPC_UNBRANDED_REMOTE, SPECIES_IPC_XION, SPECIES_IPC_ZENGHU, \ + SPECIES_IPC_SHELL_ROGUE, SPECIES_IPC_XION_REMOTE, SPECIES_IPC_PURPOSE_HK, \ + ) + + diff --git a/code/__DEFINES/subsystem-priority.dm b/code/__DEFINES/subsystem-priority.dm index 5a17e0f0082..c8fc867e158 100644 --- a/code/__DEFINES/subsystem-priority.dm +++ b/code/__DEFINES/subsystem-priority.dm @@ -56,7 +56,6 @@ // SS_BACKGROUND -#define SS_PRIORITY_PROCESSING 50 // Generic datum processor. Replaces objects processor. //#define FIRE_PRIORITY_DEFAULT 50 // This is defined somewhere else. #define SS_PRIORITY_PSYCHICS 30 #define SS_PRIORITY_EVAC 30 // Processes the evac controller. diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 8fe6a8fcbdf..ef9f46ee067 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -1,7 +1,3 @@ -// -- SSprocessing stuff -- -#define START_PROCESSING(Processor, Datum) if (!Datum.isprocessing) {Datum.isprocessing = 1;Processor.processing += Datum} -#define STOP_PROCESSING(Processor, Datum) Datum.isprocessing = 0;Processor.processing -= Datum - /// START specific to SSmachinery #define START_PROCESSING_MACHINE(machine, flag)\ if(!istype(machine, /obj/machinery)) CRASH("A non-machine [log_info_line(machine)] was queued to process on the machinery subsystem.");\ @@ -11,7 +7,9 @@ /// STOP specific to SSmachinery #define STOP_PROCESSING_MACHINE(machine, flag)\ machine.processing_flags &= ~flag;\ - if(machine.processing_flags == 0) STOP_PROCESSING(SSmachinery, machine) + if(machine.processing_flags == 0){\ + machine.datum_flags &= ~DF_ISPROCESSING;\ + SSmachinery.processing -= machine} //! ## Timing subsystem /** @@ -100,8 +98,8 @@ // -- SSoverlays -- -#define CUT_OVERLAY_IN(ovr, time) addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, cut_overlay), ovr), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME) -#define ATOM_USING_SSOVERLAY(atom) (atom.our_overlays || atom.priority_overlays) +#define CUT_OVERLAY_IN(ovr, time) addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, CutOverlays), ovr), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME) +#define ATOM_USING_SSOVERLAY(atom) (atom.atom_overlay_cache || atom.atom_protected_overlay_cache) // -- SSticker -- #define ROUND_IS_STARTED (SSticker.current_state >= GAME_STATE_PLAYING) @@ -113,10 +111,10 @@ #define EFFECT_DESTROY 2 // qdel. // Effect helpers. -#define QUEUE_EFFECT(effect) if (!effect.isprocessing) {effect.isprocessing = TRUE; SSeffects.effect_systems += effect;} -#define QUEUE_VISUAL(visual) if (!visual.isprocessing) {visual.isprocessing = TRUE; SSeffects.visuals += visual;} -#define STOP_EFFECT(effect) effect.isprocessing = FALSE; SSeffects.effect_systems -= effect; -#define STOP_VISUAL(visual) visual.isprocessing = FALSE; SSeffects.visuals -= visual; +#define QUEUE_EFFECT(effect) if (!(effect.datum_flags & DF_ISPROCESSING)) {effect.datum_flags |= DF_ISPROCESSING; SSeffects.effect_systems += effect;} +#define QUEUE_VISUAL(visual) if (!(visual.datum_flags & DF_ISPROCESSING)) {visual.datum_flags |= DF_ISPROCESSING; SSeffects.visuals += visual;} +#define STOP_EFFECT(effect) effect.datum_flags &= ~DF_ISPROCESSING; SSeffects.effect_systems -= effect; +#define STOP_VISUAL(visual) visual.datum_flags &= ~DF_ISPROCESSING; SSeffects.visuals -= visual; // -- SSfalling -- #define ADD_FALLING_ATOM(atom) if (!atom.multiz_falling) { atom.multiz_falling = 1; SSfalling.falling[atom] = 0; } @@ -255,6 +253,7 @@ #define FIRE_PRIORITY_GARBAGE 15 #define FIRE_PRIORITY_ASSETS 20 #define FIRE_PRIORITY_PATHFINDING 23 +#define FIRE_PRIORITY_PROCESS 25 #define FIRE_PRIORITY_DEFAULT 50 #define FIRE_PRIORITY_STATPANEL 390 #define FIRE_PRIORITY_CHAT 400 diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm index e1f89bb1317..ef53d466e84 100644 --- a/code/__DEFINES/tgs.dm +++ b/code/__DEFINES/tgs.dm @@ -145,6 +145,7 @@ * * minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated. Can be one of [TGS_SECURITY_ULTRASAFE], [TGS_SECURITY_SAFE], or [TGS_SECURITY_TRUSTED]. */ /world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE) + CAN_BE_REDEFINED(TRUE) return /** @@ -155,6 +156,7 @@ * This function should not be called before ..() in [/world/proc/New]. */ /world/proc/TgsInitializationComplete() + CAN_BE_REDEFINED(TRUE) return /// Put this at the start of [/world/proc/Topic]. @@ -164,6 +166,7 @@ * Call this as late as possible in [world/proc/Reboot] (BEFORE ..()). */ /world/proc/TgsReboot() + CAN_BE_REDEFINED(TRUE) return // DATUM DEFINITIONS @@ -201,6 +204,7 @@ * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards. */ /datum/tgs_version/proc/Wildcard() + CAN_BE_REDEFINED(TRUE) return /** @@ -209,6 +213,7 @@ * other_version - The [/datum/tgs_version] to compare against. */ /datum/tgs_version/proc/Equals(datum/tgs_version/other_version) + CAN_BE_REDEFINED(TRUE) return /// Represents a merge of a GitHub pull request. @@ -395,16 +400,19 @@ /// Returns the maximum supported [/datum/tgs_version] of the DMAPI. /world/proc/TgsMaximumApiVersion() + CAN_BE_REDEFINED(TRUE) return /// Returns the minimum supported [/datum/tgs_version] of the DMAPI. /world/proc/TgsMinimumApiVersion() + CAN_BE_REDEFINED(TRUE) return /** * Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise. */ /world/proc/TgsAvailable() + CAN_BE_REDEFINED(TRUE) return // No function below this succeeds if it TgsAvailable() returns FALSE or if TgsNew() has yet to be called. @@ -416,6 +424,7 @@ * If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again. */ /world/proc/TgsEndProcess() + CAN_BE_REDEFINED(TRUE) return /** @@ -425,6 +434,7 @@ * admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies. */ /world/proc/TgsTargetedChatBroadcast(datum/tgs_message_content/message, admin_only = FALSE) + CAN_BE_REDEFINED(TRUE) return /** @@ -434,6 +444,7 @@ * user: The [/datum/tgs_chat_user] to PM. */ /world/proc/TgsChatPrivateMessage(datum/tgs_message_content/message, datum/tgs_chat_user/user) + CAN_BE_REDEFINED(TRUE) return /** @@ -443,38 +454,47 @@ * channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to. */ /world/proc/TgsChatBroadcast(datum/tgs_message_content/message, list/channels = null) + CAN_BE_REDEFINED(TRUE) return /// Returns the current [/datum/tgs_version] of TGS if it is running the server, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsVersion() + CAN_BE_REDEFINED(TRUE) return /// Returns the current [/datum/tgs_version] of the DMAPI being used if it was activated, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsApiVersion() + CAN_BE_REDEFINED(TRUE) return /// Returns the name of the TGS instance running the game if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsInstanceName() + CAN_BE_REDEFINED(TRUE) return /// Return the current [/datum/tgs_revision_information] of the running server if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsRevision() + CAN_BE_REDEFINED(TRUE) return /// Returns the current BYOND security level as a TGS_SECURITY_ define if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsSecurityLevel() + CAN_BE_REDEFINED(TRUE) return /// Returns the current BYOND visibility level as a TGS_VISIBILITY_ define if TGS is present, null otherwise. Requires TGS to be using interop API version 5 or higher otherwise the string "___unimplemented" wil be returned. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsVisibility() + CAN_BE_REDEFINED(TRUE) return /// Returns a list of active [/datum/tgs_revision_information/test_merge]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsTestMerges() + CAN_BE_REDEFINED(TRUE) return /// Returns a list of connected [/datum/tgs_chat_channel]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsChatChannelInfo() + CAN_BE_REDEFINED(TRUE) return /* diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 7b07c65dc7f..08424513949 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -119,6 +119,7 @@ // common trait sources #define TRAIT_GENERIC "generic" #define GENERIC_ITEM_TRAIT "generic_item" +#define DISABILITY_TRAIT "disability" /// cannot be removed without admin intervention #define ROUNDSTART_TRAIT "roundstart" @@ -174,3 +175,12 @@ /// Traits given by psionics. #define TRAIT_SOURCE_PSIONICS "psionics" + + +// DISABILITY TRAITS + +/// Causes the mob to take twice as long to clot their wounds +#define TRAIT_DISABILITY_HEMOPHILIA "disability_hemophilia" + +/// Causes the mob to never clot their wounds +#define TRAIT_DISABILITY_HEMOPHILIA_MAJOR "disability_hemophilia_major" diff --git a/code/__DEFINES/zcopy.dm b/code/__DEFINES/zcopy.dm index 833c5cffd5f..3df518d6de1 100644 --- a/code/__DEFINES/zcopy.dm +++ b/code/__DEFINES/zcopy.dm @@ -1,5 +1,2 @@ -#define OPENTURF_MAX_PLANE -71 -#define OPENTURF_CAP_PLANE -70 // The multiplier goes here so it'll be on top of every other overlay. -#define OPENTURF_MAX_DEPTH 10 // The maxiumum number of planes deep we'll go before we just dump everything on the same plane. #define SHADOWER_DARKENING_FACTOR 0.7 // The multiplication factor for openturf shadower darkness. Lighting will be multiplied by this. #define SHADOWER_DARKENING_COLOR "#999999" // The above, but as an RGB string for lighting-less turfs. diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index e1762023d41..166460940b0 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -104,6 +104,8 @@ #define LAZYISIN(L, I) (L ? (I in L) : FALSE) #define LAZYDISTINCTADD(L, I) if(!L) { L = list(); } L |= I; #define LAZYREPLACEKEY(L, K, NK) if(L) { if(L[K]) { L[NK] = L[K] } else {L += NK} L -= K; } +///Inserts an item into the list at position X, if the list is null it will initialize it +#define LAZYINSERT(L, I, X) if(!L) { L = list(); } L.Insert(X, I); // Shims for some list procs in lists.dm. #define isemptylist(L) (!LAZYLEN(L)) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 2e9edd7d8b8..c58b867c6fd 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -26,7 +26,9 @@ GLOBAL_LIST_EMPTY(topic_commands_names) GLOBAL_PROTECT(topic_commands_names) /// List of all landmarks. -GLOBAL_LIST_EMPTY(landmarks_list) +GLOBAL_LIST_EMPTY_TYPED(landmarks_list, /obj/effect/landmark) +/// List of all ruin landmarks. +GLOBAL_LIST_EMPTY_TYPED(ruin_landmarks, /obj/effect/landmark/ruin) /// Assoc list of force spawnpoints for event maps. GLOBAL_LIST_EMPTY(force_spawnpoints) /// List of all jobstypes, minus borg, merchant and AI. @@ -121,10 +123,6 @@ GLOBAL_DATUM_INIT(cameranet, /datum/visualnet/camera, new) /// Escape locations for Nar'Sie. Escape shuttles, generally. GLOBAL_LIST_EMPTY(escape_list) -/// Escape exits for universe states. -GLOBAL_LIST_EMPTY(endgame_exits) -/// Safe spawns for universe states. -GLOBAL_LIST_EMPTY(endgame_safespawns) GLOBAL_LIST_INIT(syndicate_access, list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE, ACCESS_EXTERNAL_AIRLOCKS)) diff --git a/code/__HELPERS/icon_smoothing.dm b/code/__HELPERS/icon_smoothing.dm index db27cb8cc89..77c4aefcdc8 100644 --- a/code/__HELPERS/icon_smoothing.dm +++ b/code/__HELPERS/icon_smoothing.dm @@ -233,10 +233,10 @@ var/istate = "[((x + y) ^ ~(x * y) + z) % 25]" underlay_appearance.icon = 'icons/turf/space.dmi' underlay_appearance.icon_state = istate - underlay_appearance.plane = PLANE_SPACE_BACKGROUND + underlay_appearance.plane = SPACE_PLANE var/image/dust = image('icons/turf/space_parallax1.dmi', istate) - dust.plane = PLANE_SPACE_DUST + dust.plane = DUST_PLANE dust.alpha = 80 dust.blend_mode = BLEND_ADD U += dust @@ -295,7 +295,7 @@ var/turf/T = get_step(src, reverse_ndir(adjacency)) if(is_type_in_list(T, can_blend_with)) if(attach_overlay) - add_overlay("[reverse_ndir(adjacency)]_[attach_overlay]", overlay_layer) + AddOverlays("[reverse_ndir(adjacency)]_[attach_overlay]", overlay_layer) walls_found |= adjacency dir_mods["[adjacency]"] = "-[blend_overlay]" for(var/adjacency in list(N_NORTH, N_SOUTH)) @@ -307,7 +307,7 @@ if(((adjacencies & adjacency) && (adjacencies && diagonal)) && (has_adjacency || has_diagonal)) dir_mods["[adjacency][diagonal]"] = "-[prefix][walls_found & adjacency ? "wall" : "win"]-[suffix][walls_found & diagonal ? "wall" : "win"]" if(attach_overlay) - add_overlay("[prefix][suffix]_[attach_overlay]", overlay_layer) + AddOverlays("[prefix][suffix]_[attach_overlay]", overlay_layer) return dir_mods /proc/ndir_to_initial(var/ndir) @@ -409,10 +409,10 @@ LAZYADD(New, se) if(Old) - cut_overlay(Old) + CutOverlays(Old) if(New) - add_overlay(New) + AddOverlays(New) if (icon_state && !(smoothing_flags & SMOOTH_NO_CLEAR_ICON)) icon_state = null @@ -558,7 +558,7 @@ /atom/proc/clear_smooth_overlays() SHOULD_NOT_SLEEP(TRUE) - cut_overlay(list(top_left_corner, top_right_corner, bottom_left_corner, bottom_right_corner)) + CutOverlays(list(top_left_corner, top_right_corner, bottom_left_corner, bottom_right_corner)) top_left_corner = null top_right_corner = null bottom_right_corner = null @@ -577,7 +577,7 @@ O += sw bottom_right_corner = se O += se - add_overlay(O) + AddOverlays(O) /proc/reverse_ndir(ndir) SHOULD_NOT_SLEEP(TRUE) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 425d11be3ec..faa63ffee7a 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -118,27 +118,27 @@ mob underlays += image(icon='old_or_unused.dmi',icon_state="red", pixel_x = -32) // Testing image overlays - add_overlay(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = -32)) - add_overlay(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = 32)) - add_overlay(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = -32, pixel_y = -32)) + AddOverlays(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = -32)) + AddOverlays(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = 32)) + AddOverlays(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = -32, pixel_y = -32)) // Testing icon file overlays (defaults to mob's state) - add_overlay('_flat_demoIcons2.dmi') + AddOverlays('_flat_demoIcons2.dmi') // Testing icon_state overlays (defaults to mob's icon) - add_overlay("white") + AddOverlays("white") // Testing dynamic icon overlays var/icon/I = icon('old_or_unused.dmi', icon_state="aqua") I.Shift(NORTH,16,1) - add_overlay(I) + AddOverlays(I) // Testing dynamic image overlays I=image(icon=I,pixel_x = -32, pixel_y = 32) - add_overlay(I) + AddOverlays(I) // Testing object types (and layers) - add_overlay(/obj/effect/overlay_test) + AddOverlays(/obj/effect/overlay_test) loc = locate (10,10,1) verb @@ -166,9 +166,9 @@ mob // Update the label to show it winset(src,"imageLabel","image='[REF(I)]'"); - Add_Overlay() + AddOverlays() set name = "4. Add Overlay" - add_overlay(image(icon='old_or_unused.dmi',icon_state="yellow",pixel_x = rand(-64,32), pixel_y = rand(-64,32)) + AddOverlays(image(icon='old_or_unused.dmi',icon_state="yellow",pixel_x = rand(-64,32), pixel_y = rand(-64,32)) Stress_Test() set name = "5. Stress Test" @@ -176,7 +176,7 @@ mob // The third parameter forces it to generate a new one, even if it's already cached getFlatIcon(src,0,2) if(prob(5)) - Add_Overlay() + AddOverlays() Browse_Icon() Cache_Test() @@ -793,7 +793,7 @@ world camo_image.pixel_y-- if(5) camo_image.pixel_y++ - add_overlay(camo_image)//And finally add the overlay. + AddOverlays(camo_image)//And finally add the overlay. /proc/build_disappear_icon(atom/A) var/icon/disappear_icon = new(getFlatIcon(A)) @@ -988,14 +988,14 @@ lighting determines lighting capturing (optional), suppress_errors suppreses err /// so if the given object is associated with an icon that was in the rsc when the game was compiled, this returns a path. otherwise it returns "" /proc/get_icon_dmi_path(icon/icon) /// the dmi file path we attempt to return if the given object argument is associated with a stringifiable icon - /// if successful, this looks like "icons/path/to/dmi_file.dmi" + /// if successful, this looks like 'icons/path/to/dmi_file.dmi' var/icon_path = "" if(isatom(icon) || istype(icon, /image) || istype(icon, /mutable_appearance)) var/atom/atom_icon = icon icon = atom_icon.icon //atom icons compiled in from 'icons/path/to/dmi_file.dmi' are weird and not really icon objects that you generate with icon(). - //if theyre unchanged dmi's then they're stringifiable to "icons/path/to/dmi_file.dmi" + //if theyre unchanged dmi's then they're stringifiable to 'icons/path/to/dmi_file.dmi' if(isicon(icon) && isfile(icon)) //icons compiled in from 'icons/path/to/dmi_file.dmi' at compile time are weird and arent really /icon objects, @@ -1008,7 +1008,7 @@ lighting determines lighting capturing (optional), suppress_errors suppreses err else if(isicon(icon) && "[icon]" == "/icon") // icon objects generated from icon() at runtime are icons, but they ARENT files themselves, they represent icon files. // if the files they represent are compile time dmi files in the rsc, then - // the rsc reference returned by fcopy_rsc() will be stringifiable to "icons/path/to/dmi_file.dmi" + // the rsc reference returned by fcopy_rsc() will be stringifiable to 'icons/path/to/dmi_file.dmi' var/rsc_ref = fcopy_rsc(icon) var/icon_ref = text_ref(rsc_ref) @@ -1205,9 +1205,9 @@ lighting determines lighting capturing (optional), suppress_errors suppreses err set waitfor = FALSE if(!overlay_image) return - add_overlay(overlay_image) + AddOverlays(overlay_image) sleep(duration) - cut_overlay(overlay_image) + CutOverlays(overlay_image) /// Perform a shake on an atom, resets its position afterwards /atom/proc/Shake(pixelshiftx = 2, pixelshifty = 2, duration = 2.5 SECONDS, shake_interval = 0.02 SECONDS) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 110c94eb3a7..4d02ecc68f9 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -32,6 +32,7 @@ continue if(!(species in S.species_allowed)) continue + valid_hairstyles[hairstyle] = GLOB.hair_styles_list[hairstyle] if(valid_hairstyles.len) @@ -39,8 +40,8 @@ return h_style -/// Species must be a datum. -/proc/random_facial_hair_style(gender, species = /datum/species/human) +/// Species must be a datum type. +/proc/random_facial_hair_style(gender, species = /datum/species/human, organ_status, robolimb_manufacturer) var/f_style = "Shaved" var/list/valid_facialhairstyles = list() @@ -52,6 +53,8 @@ continue if(!(species in S.species_allowed)) continue + if(!check_robolimb_appropriate(S, organ_status, robolimb_manufacturer)) + continue valid_facialhairstyles[facialhairstyle] = GLOB.facial_hair_styles_list[facialhairstyle] @@ -60,6 +63,33 @@ return f_style +/** + * This proc checks if a sprite_accessory appropriate for a given organ and robolimb. The second argument must be an ORGAN_PREF define. + * This can easily be made into a more general helper if needed by just turning organ_status into a boolean and feeding an instance into robolimb_manufacturer, maybe. +*/ +/proc/check_robolimb_appropriate(datum/sprite_accessory/S, organ_status, robolimb_manufacturer) + if(S.robotize_type_required) + if(S.required_organ) + // Null robotize_type_required means it doesn't matter what prosthetic type we use. + if(isnull(S.robotize_type_required)) + return TRUE + if(organ_status == ORGAN_PREF_CYBORG) + if(length(S.robotize_type_required)) + var/datum/robolimb/R + if(GLOB.all_robolimbs[robolimb_manufacturer]) + R = GLOB.all_robolimbs[robolimb_manufacturer] + else + R = GLOB.basic_robolimb + if(!(R.company in S.robotize_type_required)) + return FALSE + else + // Empty list means we can't have a prosthetic type to use this marking. + return FALSE + else if(length(S.robotize_type_required)) + // There's a robotize type required and our limb is not a prosthetic. + return FALSE + return TRUE + /proc/sanitize_name(name, species = SPECIES_HUMAN) var/datum/species/current_species if(species) @@ -207,6 +237,7 @@ Proc for attack log creation, because really why not if((src in GLOB.living_mob_list) || (src in GLOB.dead_mob_list)) return FALSE GLOB.dead_mob_list += src + GLOB.death_event.raise_event(src) return TRUE // Returns true if the mob was removed form the dead list diff --git a/code/__HELPERS/overlay.dm b/code/__HELPERS/overlay.dm index 8ef01ff8f09..53d9c16b3f9 100644 --- a/code/__HELPERS/overlay.dm +++ b/code/__HELPERS/overlay.dm @@ -39,11 +39,11 @@ overlay.blend_mode = BLEND_ADD a_cache_icon[icon_state] = overlay - target.add_overlay(list(multiply, overlay)) + target.AddOverlays(list(multiply, overlay)) /proc/make_screen_overlay(icon, icon_state, brightness_factor = null, glow_radius = 1) var/image/overlay = image(icon, icon_state) - overlay.layer = EFFECTS_ABOVE_LIGHTING_LAYER + overlay.plane = EFFECTS_ABOVE_LIGHTING_PLANE var/image/underlay = image(overlay) underlay.alpha = 128 underlay.filters = filter(type="bloom", offset=glow_radius, size=glow_radius*2, threshold="#000") diff --git a/code/__HELPERS/paths/path.dm b/code/__HELPERS/paths/path.dm index bd23596c051..e7040d743c1 100644 --- a/code/__HELPERS/paths/path.dm +++ b/code/__HELPERS/paths/path.dm @@ -336,7 +336,7 @@ src.thrown = !!construct_from.throwing src.anchored = construct_from.anchored - src.has_gravity = has_gravity(construct_from) + src.has_gravity = construct_from.has_gravity() if(ismob(construct_from)) var/mob/living/mob_construct = construct_from src.incapacitated = mob_construct.incapacitated() diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 7a400e884f6..ab47363a992 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -392,22 +392,21 @@ //is in the other string at the same spot (assuming it is not a replace char). //This is used for fingerprints /proc/stringmerge(text,compare,replace = "*") - var/newtext = text if(length(text) != length(compare)) - return 0 - for(var/i = 1, i < length(text), i++) - var/a = copytext(text,i,i+1) - var/b = copytext(compare,i,i+1) - //if it isn't both the same letter, or if they are both the replacement character - //(no way to know what it was supposed to be) - if(a != b) - if(a == replace) //if A is the replacement char - newtext = copytext(newtext,1,i) + b + copytext(newtext, i+1) - else if(b == replace) //if B is the replacement char - newtext = copytext(newtext,1,i) + a + copytext(newtext, i+1) - else //The lists disagree, Uh-oh! - return 0 - return newtext + CRASH("Stringmerge received strings of differing lengths") + + var/list/text_chars = splittext_char(text, "") + var/list/compare_chars = splittext_char(compare, "") + var/text_char + var/compare_char + for(var/i in 1 to length(text_chars)) + text_char = text_chars[i] + compare_char = compare_chars[i] + if(text_char == compare_char) + continue + if(text_char == replace) + text_chars[i] = compare_char + return jointext(text_chars, "") /** @@ -439,16 +438,7 @@ * * character - The character you want to know how many are in the string */ /proc/charcount(text, character = "*") - if(!text || !character) - return 0 - var/count = 0 - var/lentext = length(text) - var/a = "" - for(var/i = 1, i <= lentext, i += length(a)) - a = text[i] - if(a == character) - count++ - return count + return length(splittext_char(text, character)) - 1 /proc/reverse_text(text = "") diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index b697ba8f5ce..e46af4d1f50 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -662,7 +662,7 @@ Turf and target are seperate in case you want to teleport some distance from a t * * Arguments: * * user: The user to check for. - * * delay: The delay in ticks to wait before returning TRUE. + * * delay: The delay in deciseconds to wait before returning TRUE. * * target: The target to check for. Optional. * * do_flags: Flags that determine what the user and target can and cannot do, defined in [mobs.dm]. Defaults to DO_DEFAULT. * * incapacitation_flags: Incapacitation flags that determines if the user can be incapacitated. Defaults to INCAPACITATION_DEFAULT. diff --git a/code/___linters/spaceman_dmm.dm b/code/___linters/spaceman_dmm.dm index fec95b9d822..563b55e521d 100644 --- a/code/___linters/spaceman_dmm.dm +++ b/code/___linters/spaceman_dmm.dm @@ -59,6 +59,9 @@ ///If wrapped in this, will not lint. #define UNLINT(X) SpacemanDMM_unlint(X) + ///The proc can be redefined in other parts of the codebase + #define CAN_BE_REDEFINED(X) set SpacemanDMM_can_be_redefined = X + ///If set, overriding their value isn't permitted by types that inherit it. #define VAR_FINAL var/SpacemanDMM_final @@ -77,6 +80,7 @@ #define SHOULD_BE_PURE(X) #define PRIVATE_PROC(X) #define PROTECTED_PROC(X) + #define CAN_BE_REDEFINED(X) #define VAR_FINAL var #define VAR_PRIVATE var #define VAR_PROTECTED var diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm new file mode 100644 index 00000000000..4b0a2af4ac3 --- /dev/null +++ b/code/_globalvars/configuration.dm @@ -0,0 +1 @@ +GLOBAL_VAR_INIT(changelog_hash, "") diff --git a/code/_globalvars/tgui.dm b/code/_globalvars/tgui.dm new file mode 100644 index 00000000000..1a2c46c10d8 --- /dev/null +++ b/code/_globalvars/tgui.dm @@ -0,0 +1 @@ +GLOBAL_DATUM(changelog_tgui, /datum/changelog) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 39d8d1bcc2b..e523618ddcb 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -10,10 +10,6 @@ Note that AI have no need for the adjacency proc, and so this proc is a lot cleaner. */ /mob/living/silicon/ai/DblClickOn(var/atom/A, params) - if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked - build_click(src, client.buildmode, params, A) - return - if(control_disabled || stat) return if(ismob(A)) @@ -27,10 +23,6 @@ return next_click = world.time + 1 - if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked - build_click(src, client.buildmode, params, A) - return - if(stat) return diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 33bb17cb4e3..0e4dad6f917 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -17,12 +17,16 @@ */ /atom/Click(location,control,params) - if(src) - usr.ClickOn(src, params) + var/datum/click_handler/click_handler = usr.GetClickHandler() + click_handler.OnClick(src, params) /atom/DblClick(var/location, var/control, var/params) - if(src) - usr.DblClickOn(src, params) + var/datum/click_handler/click_handler = usr.GetClickHandler() + click_handler.OnDblClick(src, params) + + if(istype(usr.machine,/obj/machinery/computer/security)) + var/obj/machinery/computer/security/console = usr.machine + console.jump_on_click(usr,src) /atom/proc/allow_click_through(var/atom/A, var/params, var/mob/user) return FALSE @@ -36,10 +40,6 @@ /mob/proc/OnMouseDrag(src_object, over_object, src_location, over_location, src_control, over_control, params) if(istype(loc, /atom)) var/atom/A = loc - if(client && client.buildmode) - build_click(src, client.buildmode, params, A) - return - if(A.RelayMouseDrag(src_object, over_object, src_location, over_location, src_control, over_control, params, src)) return @@ -52,7 +52,7 @@ /** * Standard mob ClickOn() - * Handles exceptions: Buildmode, middle click, modified clicks, mech actions + * Handles exceptions: middle click, modified clicks, mech actions * * After that, mostly just check your state, check whether you're holding an item, * check whether you're adjacent to the target, then pass off the click to whoever @@ -82,11 +82,10 @@ return return B.ClickOn(A, params) - if(client && client.buildmode) - build_click(src, client.buildmode, params, A) - return - var/list/modifiers = params2list(params) + if(modifiers["right"]) + RightClickOn(A) + return TRUE if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) return TRUE @@ -212,10 +211,13 @@ /mob/living/UnarmedAttack(var/atom/A, var/proximity_flag) if(!(GAME_STATE & RUNLEVELS_PLAYING)) to_chat(src, "You cannot attack people before the game has started.") - return 0 + return FALSE if(stat) - return 0 + return FALSE + + if(check_sting(src, A)) + return FALSE return 1 @@ -307,6 +309,12 @@ /mob/proc/TurfAdjacent(var/turf/T) return T.AdjacentQuick(src) +/mob/proc/RightClickOn(atom/A) + A.RightClick(src) + +/atom/proc/RightClick(mob/user) + return + /* Control+Shift click Unused except for AI @@ -422,3 +430,95 @@ var/global/list/click_catchers set hidden = 1 set name = ".mouse" LogMouseMacro(".mouse", params) + +/* + Custom Click Handlinig +*/ + +/mob + var/datum/stack/click_handlers + + +var/const/CLICK_HANDLER_NONE = 0 +var/const/CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT = 1 +var/const/CLICK_HANDLER_ALL = (~0) + +/datum/click_handler + var/mob/user + var/handler_flags = CLICK_HANDLER_NONE + +/datum/click_handler/New(mob/user) + ..() + src.user = user + if(handler_flags & CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT) + RegisterSignal(user, COMSIG_MOB_LOGOUT, /datum/click_handler/proc/OnMobLogout, TRUE) + +/datum/click_handler/Destroy() + if(handler_flags & CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT) + UnregisterSignal(user, COMSIG_MOB_LOGOUT) + user = null + . = ..() + +/datum/click_handler/proc/Enter() + return + +/datum/click_handler/proc/Exit() + return + + +/datum/click_handler/proc/OnMobLogout() + user.RemoveClickHandler(src) + +/datum/click_handler/proc/OnClick(var/atom/A, var/params) + return + +/datum/click_handler/proc/OnDblClick(var/atom/A, var/params) + return + +/datum/click_handler/default/OnClick(var/atom/A, var/params) + user.ClickOn(A, params) + +/datum/click_handler/default/OnDblClick(var/atom/A, var/params) + user.DblClickOn(A, params) + +/mob/proc/GetClickHandler(var/datum/click_handler/popped_handler) + if(!click_handlers) + click_handlers = new() + if(click_handlers.is_empty()) + PushClickHandler(/datum/click_handler/default) + return click_handlers.Top() + +/mob/proc/RemoveClickHandler(var/datum/click_handler/click_handler) + if(!click_handlers) + return + + var/was_top = click_handlers.Top() == click_handler + + if(was_top) + click_handler.Exit() + click_handlers.Remove(click_handler) + qdel(click_handler) + + if(!was_top) + return + click_handler = click_handlers.Top() + if(click_handler) + click_handler.Enter() + +/mob/proc/PopClickHandler() + if(!click_handlers) + return + RemoveClickHandler(click_handlers.Top()) + +/mob/proc/PushClickHandler(var/datum/click_handler/new_click_handler_type) + if((initial(new_click_handler_type.handler_flags) & CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT) && !client) + return FALSE + if(!click_handlers) + click_handlers = new() + var/datum/click_handler/click_handler = click_handlers.Top() + if(click_handler) + click_handler.Exit() + + click_handler = new new_click_handler_type(src) + click_handler.Enter() + click_handlers.Push(click_handler) diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 5028af39eee..40ecc88f1cf 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -11,10 +11,6 @@ return next_click = world.time + 1 - if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked - build_click(src, client.buildmode, params, A) - return - var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) diff --git a/code/_onclick/hud/ability_screen_objects.dm b/code/_onclick/hud/ability_screen_objects.dm index fd6192d25e4..b94e9666613 100644 --- a/code/_onclick/hud/ability_screen_objects.dm +++ b/code/_onclick/hud/ability_screen_objects.dm @@ -149,16 +149,6 @@ return O return -/mob/living/LateLogin() - . = ..() - if(ability_master) - ability_master.toggle_open(2) - client.screen -= ability_master - -/mob/living/Initialize() - . = ..() - ability_master = new /obj/screen/movable/ability_master(FALSE, src) - ///////////ACTUAL ABILITIES//////////// //This is what you click to do things// /////////////////////////////////////// diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index 9e760cefd0b..4cf276fcd09 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -10,6 +10,12 @@ #define AB_CHECK_ALIVE 8 #define AB_CHECK_INSIDE 16 +///Eye action targets the parent datum. +#define PARENT_TARGET 0 +///Eye action targets the eye mob itself. +#define EYE_TARGET 1 +///Eye action targets the eye component. +#define COMPONENT_TARGET 2 /datum/action var/name = "Generic Action" @@ -148,7 +154,7 @@ icon = owner.button_icon icon_state = owner.background_icon_state - cut_overlays() + ClearOverlays() var/image/img if(owner.action_type == AB_ITEM && owner.target) var/obj/item/I = owner.target @@ -159,7 +165,7 @@ img.pixel_y = 0 if(owner.button_icon_color) img.color = owner.button_icon_color - add_overlay(img) + AddOverlays(img) if(!owner.IsAvailable()) color = rgb(128,0,0,128) @@ -194,8 +200,8 @@ return /obj/screen/movable/action_button/hide_toggle/update_icon() - cut_overlays() - add_overlay(hidden ? "show" : "hide") + ClearOverlays() + AddOverlays(hidden ? "show" : "hide") //This is the proc used to update all the action buttons. Properly defined in /mob/living/ /mob/proc/update_action_buttons() @@ -288,6 +294,31 @@ to_chat(usr, SPAN_NOTICE("You press the button on the exterior of \the [target_clothing].")) target_clothing.action_circuit.activate_pin(1) +/datum/action/eye + action_type = AB_GENERIC + check_flags = AB_CHECK_LYING|AB_CHECK_STUNNED + ///The type of /mob/abstract/eye used by the action. + var/eye_type = /mob/abstract/eye + ///The relevant owner of the proc to be called by the eye action. + var/target_type = PARENT_TARGET + +/datum/action/eye/New(var/datum/component/eye/eye_component) + if(!istype(eye_component)) + crash_with("Attempted to generate eye action [src], but no eye component was provided!") + switch(target_type) + if(PARENT_TARGET) + return ..(eye_component.parent) + if(EYE_TARGET) + return ..(eye_component.component_eye) + if(COMPONENT_TARGET) + return ..(eye_component) + else + crash_with("Attempted to generate eye action [src] but an improper target_type ([target_type]) was defined.") + +/datum/action/eye/CheckRemoval(mob/living/user) + if(!user.eyeobj || !istype(user.eyeobj, eye_type)) + return TRUE + #undef AB_WEST_OFFSET #undef AB_NORTH_OFFSET #undef AB_MAX_COLUMNS diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm index e04c2c34d83..013f70c38cb 100644 --- a/code/_onclick/hud/ai.dm +++ b/code/_onclick/hud/ai.dm @@ -3,7 +3,7 @@ var/mob/living/silicon/ai/myai = mymob myai.computer.screen_loc = ui_ai_crew_monitor - myai.computer.layer = SCREEN_LAYER + myai.computer.layer = HUD_BASE_LAYER adding = list( new /obj/screen/ai/core, diff --git a/code/_onclick/hud/captive_brain_hud.dm b/code/_onclick/hud/captive_brain_hud.dm index 60148589c21..c8abae4ebc8 100644 --- a/code/_onclick/hud/captive_brain_hud.dm +++ b/code/_onclick/hud/captive_brain_hud.dm @@ -9,7 +9,7 @@ resist.icon = 'icons/mob/screen/captive_brain.dmi' resist.icon_state = "resist" resist.screen_loc = "EAST-8,BOTTOM:8" - resist.layer = SCREEN_LAYER + resist.layer = HUD_ABOVE_ITEM_LAYER adding += resist mymob.client.screen += src.adding diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 8c256cc7826..8f571ed64b9 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -67,7 +67,8 @@ icon_state = "default" screen_loc = "CENTER-7,CENTER-7" mouse_opacity = MOUSE_OPACITY_TRANSPARENT - layer = HUD_LAYER - 0.1 + plane = FULLSCREEN_PLANE + layer = FULLSCREEN_LAYER var/severity = 0 var/allstate = 0 //shows if it should show up for dead people too @@ -77,24 +78,27 @@ /obj/screen/fullscreen/brute icon_state = "brutedamageoverlay" + layer = DAMAGE_LAYER /obj/screen/fullscreen/oxy icon_state = "oxydamageoverlay" + layer = DAMAGE_LAYER /obj/screen/fullscreen/crit icon_state = "passage" + layer = CRIT_LAYER /obj/screen/fullscreen/strong_pain icon_state = "strong_pain" - layer = OBFUSCATION_LAYER + layer = CRIT_LAYER /obj/screen/fullscreen/blind icon_state = "blackimageoverlay" - layer = OBFUSCATION_LAYER + layer = BLIND_LAYER /obj/screen/fullscreen/blackout icon_state = "blackout" - layer = OBFUSCATION_LAYER + layer = BLIND_LAYER /obj/screen/fullscreen/impaired icon_state = "impairedoverlay" @@ -143,7 +147,13 @@ /obj/screen/fullscreen/frenzy icon_state = "frenzyoverlay" - layer = OBFUSCATION_LAYER + layer = BLIND_LAYER /obj/screen/fullscreen/teleport icon_state = "teleport" + +/obj/screen/fullscreen/blueprints + icon = 'icons/effects/blueprints.dmi' + icon_state = "base" + screen_loc = ui_entire_screen + alpha = 100 diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index b52062bdf78..52533877624 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -27,7 +27,6 @@ var/list/global_huds screen.screen_loc = "SOUTHWEST to NORTHEAST" // Will tile up to the whole screen, scaling beyond 15x15 if needed. screen.icon = 'icons/obj/hud_tiled.dmi' screen.icon_state = icon_state - screen.layer = SCREEN_LAYER screen.mouse_opacity = MOUSE_OPACITY_TRANSPARENT screen.color = color @@ -38,7 +37,7 @@ var/list/global_huds druggy = new /obj/screen() druggy.screen_loc = ui_entire_screen druggy.icon_state = "druggy" - druggy.layer = 17 + druggy.layer = IMPAIRED_LAYER druggy.mouse_opacity = MOUSE_OPACITY_TRANSPARENT druggy.alpha = 127 druggy.blend_mode = BLEND_MULTIPLY @@ -47,7 +46,7 @@ var/list/global_huds blurry = new /obj/screen() blurry.screen_loc = ui_entire_screen blurry.icon_state = "blurry" - blurry.layer = 17 + blurry.layer = IMPAIRED_LAYER blurry.mouse_opacity = MOUSE_OPACITY_TRANSPARENT blurry.alpha = 100 @@ -98,18 +97,18 @@ var/list/global_huds for(i = 1, i <= 4, i++) O = vimpaired[i] O.icon_state = "dither50" - O.layer = 17 + O.layer = IMPAIRED_LAYER O.mouse_opacity = MOUSE_OPACITY_TRANSPARENT O = darkMask[i] O.icon_state = "dither50" - O.layer = 17 + O.layer = IMPAIRED_LAYER O.mouse_opacity = MOUSE_OPACITY_TRANSPARENT for(i = 5, i <= 8, i++) O = darkMask[i] O.icon_state = "black" - O.layer = 17 + O.layer = IMPAIRED_LAYER O.mouse_opacity = MOUSE_OPACITY_TRANSPARENT /* diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 864a28e0b63..649e772e952 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -28,7 +28,6 @@ hud_type = slot_data["slot_type"] inv_box = new hud_type() inv_box.icon = ui_style - inv_box.layer = SCREEN_LAYER inv_box.color = ui_color inv_box.alpha = ui_alpha inv_box.hud = src @@ -53,7 +52,6 @@ using.icon = ui_style using.icon_state = "other" using.screen_loc = ui_inventory - using.layer = SCREEN_LAYER using.color = ui_color using.alpha = ui_alpha src.adding += using @@ -68,7 +66,6 @@ using.screen_loc = ui_acti using.color = ui_color using.alpha = ui_alpha - using.layer = SCREEN_LAYER src.adding += using action_intent = using @@ -85,7 +82,6 @@ using.icon = ico using.screen_loc = ui_acti using.alpha = ui_alpha - using.layer = SCREEN_LAYER src.adding += using help_intent = using @@ -97,7 +93,6 @@ using.icon = ico using.screen_loc = ui_acti using.alpha = ui_alpha - using.layer = SCREEN_LAYER src.adding += using disarm_intent = using @@ -109,7 +104,6 @@ using.icon = ico using.screen_loc = ui_acti using.alpha = ui_alpha - using.layer = SCREEN_LAYER src.adding += using grab_intent = using @@ -121,7 +115,6 @@ using.icon = ico using.screen_loc = ui_acti using.alpha = ui_alpha - using.layer = SCREEN_LAYER src.adding += using hurt_intent = using //end intent small hud objects @@ -141,7 +134,6 @@ using.icon = ui_style using.icon_state = "act_drop" using.screen_loc = ui_drop_throw - using.layer = SCREEN_LAYER using.color = ui_color using.alpha = ui_alpha src.hotkeybuttons += using @@ -153,7 +145,6 @@ using.icon = ui_style using.icon_state = "act_equip" using.screen_loc = ui_equip - using.layer = SCREEN_LAYER using.color = ui_color using.alpha = ui_alpha src.adding += using @@ -167,7 +158,6 @@ inv_box.icon_state = "r_hand_active" inv_box.screen_loc = ui_rhand inv_box.slot_id = slot_r_hand - inv_box.layer = SCREEN_LAYER inv_box.color = ui_color inv_box.alpha = ui_alpha @@ -183,7 +173,6 @@ inv_box.icon_state = "l_hand_active" inv_box.screen_loc = ui_lhand inv_box.slot_id = slot_l_hand - inv_box.layer = SCREEN_LAYER inv_box.color = ui_color inv_box.alpha = ui_alpha src.l_hand_hud_object = inv_box @@ -196,7 +185,6 @@ using.icon = ui_style using.icon_state = "hand1" using.screen_loc = ui_swaphand1 - using.layer = SCREEN_LAYER using.color = ui_color using.alpha = ui_alpha using.hud = src @@ -207,7 +195,6 @@ using.icon = ui_style using.icon_state = "hand2" using.screen_loc = ui_swaphand2 - using.layer = SCREEN_LAYER using.color = ui_color using.alpha = ui_alpha using.hud = src @@ -219,7 +206,6 @@ using.icon = ui_style using.icon_state = "act_resist" using.screen_loc = ui_pull_resist - using.layer = SCREEN_LAYER using.color = ui_color using.alpha = ui_alpha src.hotkeybuttons += using @@ -355,8 +341,8 @@ mymob.zone_sel.icon = ui_style mymob.zone_sel.color = ui_color mymob.zone_sel.alpha = ui_alpha - mymob.zone_sel.cut_overlays() - mymob.zone_sel.add_overlay(image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")) + mymob.zone_sel.ClearOverlays() + mymob.zone_sel.AddOverlays(image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")) hud_elements |= mymob.zone_sel //Handle the gun settings buttons @@ -545,7 +531,7 @@ icon = set_icon var/image/status_overlay = image('icons/mob/screen/hud_status.dmi', null, set_overlay) status_overlay.appearance_flags = RESET_COLOR - add_overlay(status_overlay) + AddOverlays(status_overlay) status_message = set_status_message return ..() diff --git a/code/_onclick/hud/morph.dm b/code/_onclick/hud/morph.dm index 61203779f2a..12dcb8023eb 100644 --- a/code/_onclick/hud/morph.dm +++ b/code/_onclick/hud/morph.dm @@ -16,8 +16,8 @@ mymob.zone_sel = new /obj/screen/zone_sel() mymob.zone_sel.icon = 'icons/mob/screen/morph.dmi' - mymob.zone_sel.cut_overlays() - mymob.zone_sel.add_overlay(image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")) + mymob.zone_sel.ClearOverlays() + mymob.zone_sel.AddOverlays(image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")) var/obj/screen/resist = new /obj/screen() resist.name = "resist" diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index ec8eb462ef6..bb88ce688f1 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -20,13 +20,11 @@ blobpwrdisplay.name = "blob power" blobpwrdisplay.icon_state = "block" blobpwrdisplay.screen_loc = ui_health - blobpwrdisplay.layer = SCREEN_LAYER blobhealthdisplay = new /obj/screen() blobhealthdisplay.name = "blob health" blobhealthdisplay.icon_state = "block" blobhealthdisplay.screen_loc = ui_internal - blobhealthdisplay.layer = SCREEN_LAYER mymob.client.screen = null @@ -47,7 +45,6 @@ using.icon = ui_style using.icon_state = "intent_"+mymob.a_intent using.screen_loc = ui_zonesel - using.layer = SCREEN_LAYER src.adding += using action_intent = using @@ -61,7 +58,6 @@ using.name = "help" using.icon = ico using.screen_loc = ui_zonesel - using.layer = SCREEN_LAYER src.adding += using help_intent = using @@ -72,7 +68,6 @@ using.name = "disarm" using.icon = ico using.screen_loc = ui_zonesel - using.layer = SCREEN_LAYER src.adding += using disarm_intent = using @@ -83,7 +78,6 @@ using.name = "grab" using.icon = ico using.screen_loc = ui_zonesel - using.layer = SCREEN_LAYER src.adding += using grab_intent = using @@ -94,7 +88,6 @@ using.name = I_HURT using.icon = ico using.screen_loc = ui_zonesel - using.layer = SCREEN_LAYER src.adding += using hurt_intent = using @@ -140,8 +133,8 @@ mymob.zone_sel = new /obj/screen/zone_sel() mymob.zone_sel.icon = 'icons/mob/screen/construct.dmi' - mymob.zone_sel.cut_overlays() - mymob.zone_sel.add_overlay(image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")) + mymob.zone_sel.ClearOverlays() + mymob.zone_sel.AddOverlays(image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")) mymob.purged = new /obj/screen() mymob.purged.icon = 'icons/mob/screen/construct.dmi' diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index c007f121b5e..709f7be8b62 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -5,7 +5,7 @@ GLOBAL_LIST_EMPTY(radial_menus) /obj/screen/radial icon = 'icons/mob/screen/radial.dmi' - layer = HUD_LAYER + layer = RADIAL_BASE_LAYER var/datum/radial_menu/parent /obj/screen/radial/Destroy() @@ -241,7 +241,7 @@ GLOBAL_LIST_EMPTY(radial_menus) /datum/radial_menu/proc/extract_image(E) var/mutable_appearance/MA = new /mutable_appearance(E) if(MA) - MA.layer = HUD_LAYER + MA.layer = RADIAL_CONTENT_LAYER MA.appearance_flags |= RESET_TRANSFORM return MA @@ -258,7 +258,7 @@ GLOBAL_LIST_EMPTY(radial_menus) return current_user = M.client //Blank - menu_holder = image(icon = 'icons/effects/effects.dmi', loc = anchor, icon_state = "nothing", layer = HUD_LAYER) + menu_holder = image(icon = 'icons/effects/effects.dmi', loc = anchor, icon_state = "nothing", layer = RADIAL_BACKGROUND_LAYER) menu_holder.appearance_flags |= KEEP_APART|RESET_ALPHA|RESET_COLOR|RESET_TRANSFORM menu_holder.add_vis_contents(elements + close_button) current_user.images += menu_holder diff --git a/code/_onclick/hud/rendering/_render_readme.md b/code/_onclick/hud/rendering/_render_readme.md new file mode 100644 index 00000000000..3f1cd6c99af --- /dev/null +++ b/code/_onclick/hud/rendering/_render_readme.md @@ -0,0 +1,62 @@ +# The Render Readme + +1. [Byond internal functionality](#byond-internal-functionality) +2. [Known internal snowflake](#known-internal-snowflake) +3. [The rendering solution](#the-rendering-solution) +4. [Render plates](#render-plates) + +## Byond internal functionality +This part of the guide will assume that you have read the byond reference entry for rendering at www.byond.com/docs/ref//#/{notes}/renderer + +When you create an atom, this will always create an internal byond structure called an "appearance". This appearance you will likely be familiar with, as it is exposed through the /atom/var/appearance var. This appearance var holds data on how to render the object, ie what icon/icon_state/color etc it is using. Note that appearance vars will always copy, and do not hold a reference. When you update a var, for example lets pretend we add a filter, the appearance will be updated to include the filter. Note that, however, vis_contents objets are uniquely excluded from appearances. Then, when the filter is updated, the appearance will be recreated, and the atom marked as "dirty". After it has been updated, the SendMaps() function (sometimes also called maptick), which is a internal byond function that iterates over all objects in a clients view and in the clients.mob.contents, checks for "dirty" atoms, then resends any "dirty" appearances to clients as needed and unmarks them as dirty. This function is notoriosly slow, but we can see it's tick usage through the world.map_cpu var. We can also avoid more complex checks checking whether an object is visible on a clients screen by using the TILE_BOUND appearance flag. + +Finally, we arrive at clientside behavior, where we have two main clientside functions: GetMapIcons, and Render. GetMapIcons is repsonsible for actual rendering calculations on the clientside, such as "Group Icons and Set bounds", which performs clientside calculations for transform matrixes. Note that particles here are handled in a seperate thread and are not diplayed in the clientside profiler. Render handles the actual drawing of the screen. + +## Known internal snowflake +The following is an incomplete list of pitfalls that come from byond snowflake that are known, this list is obviously incomplete. + +1. Transforms are very slow on clientside. This is not usually noticable, but if you start using large amounts of them it will grind you to a halt quickly, regardless of whether its on overlays or objs +2. The darkness plane. The darkness plane has specific variables it needs to render correctly, and these can be found in the plane masters file. it is composed internally of two parts, a black mask over the clients screen, and a non rendering mask that blocks all luminosity=0 turfs and their contents from rendering if the SEE_BLACKNESS flag is set properly. It behaves very oddly, such as forcing itself to ALWAYS render or pre-render on blend_multiply blend mode or refusing to render the black mask properly otherwise. The blocker will always block rendering but the mask can be layered under other objects. +3. render_target/source. Render_target/source will only copy certain rendering instructions, and these are only defined as "etc." in the byond reference. Known non copied appearance vars include: blend_mode, plane, layer, vis_contents, mouse_opacity... +4. Large icons on the screen that peek over the edge will instead of only rendering partly like you would expect will instead stretch the screen while not adgusting the render buffer, which means that you can actively see as tiles and map objects are rendered. You can use this for an easy "offscreen" UI. +5. Numerically large filters on objects of any size will torpedo performance, even though large objects with small filters will perform massively better. (ie blur(size=20) BAD) +6. Texture Atlas: the texture atlas byond uses to render icons is very susceptible to corruption and can regularily replace icons with other icons or just not render at all. This can be exasperated by alt tabbing or pausing the dreamseeker process. +7. The renderer is awful code and lummox said he will try changing a large part of it for 515 so keep an eye on that +8. Byond uses DirectX 9 (Lummox said he wants to update to DirectX 11) +9. Particles are just fancy overlays and are not independent of their owner +10. Maptick items inside mob.contents are cheaper compared to most other movables + +## The rendering solution +One of the main issues with making pretty effects is how objects can only render to one plane, and how filters can only be applied to single objects. Quite simply it means we cant apply effects to multiple planes at once, and an effect to one plane only by treating it as a single unit: + +![](https://raw.githubusercontent.com/tgstation/documentation-assets/main/rendering/renderpipe_old.png) + +A semi-fix to stop from having to apply effects to every single plane is to use the render controllers, to automatically apply filters and colors automatically onto their controlled planes. + +The solution is thus instead we replace plane masters rendering directly to client with planes that render multiple planes onto them as objects in order to be able to affect multiple planes while treating them as a single object. This is done by relaying the plane using a "render relay" onto a "render plate" which acts as a plane master of plane masters of sorts, and since planes are rendered onto it as single objects any filters we apply to them will render over the planes, treating them as a single unit. + +![](https://raw.githubusercontent.com/tgstation/documentation-assets/main/rendering/renderpipe_refactored.png) + +We can also choose to render these by decreasing the scaling all applied effects (effect_size/number_of_plates_rendered_to) then rendering it onto multiple planes: + +![](https://raw.githubusercontent.com/tgstation/documentation-assets/main/rendering/renderpipe_refactored_multiple.png) + +Through these this allows us to treat planes as single objects, and lets us distort them as a single unit, most notably works wonders with the displacement filter. Specifically, here you can displacement_filter a plane onto a plate, which then will treat all the other planes rendered on that plate as a single unit. + +## Render plates + +The rendering system uses two objects to unify planes: render_relay and render_plates. Render relays use render_target/source and the relay_render_to_plane proc to replicate the plane master on the render relay. This render relay is then rendered onto a render_plate, which is a plane master that renders the render_relays onto itself. This plate can then be hierachically rendered with the same process until it reaches the master render_plate, which is the plate that will actually render to the player. These plates naturally in the byond style have quirks. For example, rendering to two plates will double any effects such as color or filters, and as such you need to carefully manage how you render them. Keep in mind as well that when sorting the layers for rendering on a plane that they should not be negative, this is handled automatically in relay_render_to_plane. When debugging note that mouse_opacity can act bizzarly with this method, such as only allowing you to click things that are layered over objects on a certain plane but auomatically setting the mouse_opacity should be handling this. Note that if you decide to manipulate a plane with internal byond objects that you will have to manually extrapolate the vars that are set if you want to render them to another plane (See blackness plane for example), and that this is not documented anywhere. + + +Goodluck and godspeed with coding + - Just another contributor + +## Baystation/Aurorastation Differences + +The bay implementation differs in some points but you can treat the prior sections as broadly accurate. + +- Locally we have refactored and simplified the above concepts down to `/atom/movable/renderer` and undifferentiated relay movables. +- There is no type destinction between renderers intended to draw normal entities and renderers intended to draw other renderers. +- We instead refer to these as "Plane Renderers" and "Group Renderers", and note that Group Renderers may render *other* Group Renderers in turn. +- We additionally add the extra "Effect Renderer" as a distinct concept. Effect renderers are more virtual, and drawn to other renderers by filters instead. +- See the comments in _renderer.dm for detail next to code. \ No newline at end of file diff --git a/code/_onclick/hud/rendering/_renderer.dm b/code/_onclick/hud/rendering/_renderer.dm new file mode 100644 index 00000000000..bec1cc93e78 --- /dev/null +++ b/code/_onclick/hud/rendering/_renderer.dm @@ -0,0 +1,264 @@ +/* * +* Renderers +* Renderers are virtual objects that act as draw groups of things, including +* other Renderers. Renderers are similar to older uses of PLANE_MASTER but +* employ render targets using the "*" slate prefix to draw off-screen, to be +* composited in a controlled and flexible order and in some cases, reuse for +* visual effects. +*/ + +/// The base /renderer definition and defaults. +/atom/movable/renderer + abstract_type = /atom/movable/renderer + appearance_flags = DEFAULT_RENDERER_APPEARANCE_FLAGS + screen_loc = "CENTER" + plane = LOWEST_PLANE + blend_mode = BLEND_OVERLAY + + /// The compositing renderer this renderer belongs to. + var/group = RENDER_GROUP_FINAL + + /// The relay movable used to composite this renderer to its group. + var/atom/movable/relay // Also see https://secure.byond.com/forum/?post=2141928 maybe. + + /// Optional blend mode override for the renderer's composition relay. + var/relay_blend_mode + + /// If text, uses the text or, if TRUE, uses "*AUTO-[name]" + var/render_target_name = TRUE + + var/mob/owner = null + + +/atom/movable/renderer/Destroy() + owner = null + QDEL_NULL(relay) + return ..() + + +INITIALIZE_IMMEDIATE(/atom/movable/renderer) + + +/atom/movable/renderer/Initialize(mapload, mob/owner) + . = ..() + if (. == INITIALIZE_HINT_QDEL) + return + src.owner = owner + if (isnull(group)) + if (istext(render_target_name)) + render_target = render_target_name + return + if (istext(render_target_name)) + render_target = render_target_name + else if (render_target_name) + render_target = "*[ckey(name)]" + relay = new + relay.screen_loc = "CENTER" + relay.appearance_flags = PASS_MOUSE | NO_CLIENT_COLOR | KEEP_TOGETHER + relay.name = "[render_target] relay" + relay.mouse_opacity = mouse_opacity + relay.render_source = render_target + relay.layer = (plane + abs(LOWEST_PLANE)) * 0.5 + relay.plane = group + if (isnull(relay_blend_mode)) + relay.blend_mode = blend_mode + else + relay.blend_mode = relay_blend_mode + +/** +* Graphic preferences +* +* Some renderers may be able to use a graphic preference to determine how to display effects. For example reduce particle counts or filter variables. +*/ +/atom/movable/renderer/proc/GraphicsUpdate() + return + + +/** +* Renderers on /mob +* We attach renderers to mobs for their lifespan. Only mobs with clients get +* renderers, and they are removed again when the mob loses its client. Mobs +* get their own unique renderer instances but it would not be inconceivable +* to share them globally. +*/ + +/// The list of renderers associated with this mob. +/mob/var/list/atom/movable/renderer/renderers + + +/// Creates the mob's renderers on /Login() +/mob/proc/CreateRenderers() + if (!renderers) + renderers = list() + for (var/atom/movable/renderer/renderer as anything in subtypesof(/atom/movable/renderer)) + if(ispath(renderer, /atom/movable/renderer/shared)) + continue + renderer = new renderer (null, src) + renderers[renderer] = renderer.plane // (renderer = plane) format for visual debugging + if (renderer.relay) + my_client.screen += renderer.relay + my_client.screen += renderer + + for (var/atom/movable/renderer/zrenderer as anything in GLOB.zmimic_renderers) + if (zrenderer.relay) + my_client.screen += zrenderer.relay + my_client.screen += zrenderer + +/// Removes the mob's renderers on /Logout() +/mob/proc/RemoveRenderers() + if(my_client) + for(var/atom/movable/renderer/renderer as anything in renderers) + my_client.screen -= renderer + if (renderer.relay) + my_client.screen -= renderer.relay + qdel(renderer) + for (var/atom/movable/renderer/renderer as anything in GLOB.zmimic_renderers) + my_client.screen -= renderer + if (renderers) + renderers.Cut() + +/* * +* Plane Renderers +* We treat some renderers as planes with layers. When some atom has the same plane +* as a Plane Renderer, it is drawn by that renderer. The layer of the atom determines +* its draw order within the scope of the renderer. The draw order of same-layered things +* is probably by atom contents order, but can be assumed not to matter - if it's out of +* order, it should have a more appropriate layer value. +* Higher plane values are composited over lower. Here, they are ordered from under to over. +*/ + +/// Handles byond internal letterboxing. Avoid touching. +/atom/movable/renderer/letterbox + name = "Letterbox" + group = RENDER_GROUP_SCENE + plane = BLACKNESS_PLANE + blend_mode = BLEND_MULTIPLY + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/atom/movable/renderer/space + name = "Space" + group = RENDER_GROUP_SCENE + plane = SPACE_PLANE + +/atom/movable/renderer/skybox + name = "Skybox" + group = RENDER_GROUP_SCENE + plane = SKYBOX_PLANE + relay_blend_mode = BLEND_MULTIPLY + +//Z Mimic planemasters -> Could apply scaling for parallax though that requires copying appearances from adjacent turfs +GLOBAL_LIST_EMPTY(zmimic_renderers) + +/hook/startup/proc/create_global_renderers() //Some (most) renderers probably do not need to be instantiated per mob. So may as well make them global and just add to screen + //Zmimic planemasters + for(var/i = 0 to OPENTURF_MAX_DEPTH) + GLOB.zmimic_renderers += new /atom/movable/renderer/shared/zmimic(null, null, OPENTURF_MAX_PLANE - i) + + return TRUE + +/atom/movable/renderer/shared/zmimic + name = "Zrenderer" + group = RENDER_GROUP_SCENE + +/atom/movable/renderer/shared/zmimic/Initialize(mapload, _owner, _plane) + plane = _plane + name = "Zrenderer [plane]" + . = ..() + +/atom/movable/renderer/shared/zmimic/Destroy() + GLOB.zmimic_renderers -= src + return ..() + +// Draws the game world; live mobs, items, turfs, etc. +/atom/movable/renderer/game + name = "Game" + group = RENDER_GROUP_SCENE + plane = DEFAULT_PLANE + +/// Draws observers; ghosts, camera eyes, etc. +/atom/movable/renderer/observers + name = "Observers" + group = RENDER_GROUP_SCENE + plane = OBSERVER_PLANE + + +/// Draws darkness effects. +/atom/movable/renderer/lighting + name = "Lighting" + group = RENDER_GROUP_SCENE + plane = LIGHTING_PLANE + relay_blend_mode = BLEND_MULTIPLY + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/// Draws visuals that should not be affected by darkness. +/atom/movable/renderer/above_lighting + name = "Above Lighting" + group = RENDER_GROUP_SCENE + plane = EFFECTS_ABOVE_LIGHTING_PLANE + + +/// Draws full screen visual effects, like pain and bluespace. +/atom/movable/renderer/screen_effects + name = "Screen Effects" + group = RENDER_GROUP_SCENE + plane = FULLSCREEN_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + + +/// Draws user interface elements. +/atom/movable/renderer/interface + name = "Interface" + group = RENDER_GROUP_SCREEN + plane = HUD_PLANE + + +/* * +* Group renderers +* We treat some renderers as render groups that other renderers subscribe to. Renderers +* subscribe themselves to groups by setting a group value equal to the plane of a Group +* Renderer. This value is used for the Renderer's relay to include it into the Group, and +* the Renderer's plane is used as the relay's layer. +* Group renderers can subscribe themselves to other Group Renderers. This allows for more +* granular manipulation of how the final scene is composed. +*/ + +/// Render group for stuff INSIDE the typical game context - people, items, lighting, etc. +/atom/movable/renderer/scene_group + name = "Scene Group" + group = RENDER_GROUP_FINAL + plane = RENDER_GROUP_SCENE + +/// Render group for stuff OUTSIDE the typical game context - UI, full screen effects, etc. +/atom/movable/renderer/screen_group + name = "Screen Group" + group = RENDER_GROUP_FINAL + plane = RENDER_GROUP_SCREEN + + +/// Render group for final compositing before user display. +/atom/movable/renderer/final_group + name = "Final Group" + group = RENDER_GROUP_NONE + plane = RENDER_GROUP_FINAL + + +/* * +* Effect Renderers +* Some renderers are used to produce complex screen effects. These are drawn using filters +* rather than composition groups, and may be added to another renderer in the following +* fashion. Setting a render_target_name with no group is the expected patter for Effect +* Renderers as it allows them to draw to a slate that will be empty unless a relevant +* behavior, such as the effect atom below, causes them to be noticeable. +*/ + +/// Renders the /obj/effect/warp example effect as well as gravity catapult effects +/atom/movable/renderer/warp + name = "Warp Effect" + group = RENDER_GROUP_NONE + plane = WARP_EFFECT_PLANE + render_target_name = "*warp" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/atom/movable/renderer/scene_group/Initialize() + . = ..() + filters += filter(type = "displace", render_source = "*warp", size = 5) diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index c3eb5d39cba..a060fd232c2 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -22,7 +22,6 @@ var/obj/screen/robot_inventory using.icon = 'icons/mob/screen/robot.dmi' using.icon_state = "radio" using.screen_loc = ui_movi - using.layer = SCREEN_LAYER src.adding += using //Module select @@ -48,7 +47,6 @@ var/obj/screen/robot_inventory using.icon = 'icons/mob/screen/robot.dmi' using.icon_state = mymob.a_intent using.screen_loc = ui_acti - using.layer = SCREEN_LAYER src.adding += using action_intent = using @@ -94,7 +92,6 @@ var/obj/screen/robot_inventory using.icon = 'icons/mob/screen/robot.dmi' using.icon_state = "panel" using.screen_loc = ui_borg_panel - using.layer = SCREEN_LAYER src.adding += using //Store @@ -121,13 +118,12 @@ var/obj/screen/robot_inventory mymob.zone_sel = new /obj/screen/zone_sel() mymob.zone_sel.icon = 'icons/mob/screen/robot.dmi' - mymob.zone_sel.cut_overlays() - mymob.zone_sel.add_overlay(image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")) + mymob.zone_sel.ClearOverlays() + mymob.zone_sel.AddOverlays(image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")) // Computer device hud if(r.computer) r.computer.screen_loc = ui_oxygen - r.computer.layer = SCREEN_LAYER //Handle the gun settings buttons @@ -225,8 +221,7 @@ var/obj/screen/robot_inventory A.screen_loc = "CENTER[x]:16,SOUTH+[y]:7" else A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7" - A.layer = SCREEN_LAYER - + A.hud_layerise() x++ if(x == 4) x = -4 diff --git a/code/_onclick/hud/screen_object_types/ai_screen_objs.dm b/code/_onclick/hud/screen_object_types/ai_screen_objs.dm index f5abd78b3f7..69cc930186b 100644 --- a/code/_onclick/hud/screen_object_types/ai_screen_objs.dm +++ b/code/_onclick/hud/screen_object_types/ai_screen_objs.dm @@ -34,7 +34,6 @@ /obj/screen/ai icon = 'icons/mob/screen/ai.dmi' - layer = SCREEN_LAYER /obj/screen/ai/core name = "AI Core" diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 5c21866f2f6..50c87fef0ec 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -9,7 +9,8 @@ /obj/screen name = "" icon = 'icons/mob/screen/generic.dmi' - layer = SCREEN_LAYER + plane = HUD_PLANE + layer = HUD_BASE_LAYER unacidable = 1 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. @@ -55,7 +56,7 @@ /obj/screen/inventory/MouseExited() ..() - cut_overlay(object_overlays) + CutOverlays(object_overlays) object_overlays.Cut() /obj/screen/inventory/proc/add_overlays() @@ -73,7 +74,7 @@ else item_overlay.color = "#00ff00" object_overlays += item_overlay - add_overlay(object_overlays) + AddOverlays(object_overlays) /obj/screen/inventory/proc/set_color_for(var/set_color, var/set_time) if(color_changed) @@ -137,7 +138,6 @@ /obj/screen/storage name = "storage" - layer = SCREEN_LAYER screen_loc = "7,7 to 10,8" /obj/screen/storage/Click() @@ -153,7 +153,7 @@ /obj/screen/storage/background name = "background storage" - layer = SCREEN_LAYER+0.01 + layer = HUD_BASE_LAYER /obj/screen/storage/background/Initialize(mapload, var/obj/set_master, var/set_icon_state) . = ..() @@ -221,7 +221,7 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT alpha = 128 anchored = TRUE - layer = SCREEN_LAYER + 0.1 + plane = HUD_ITEM_LAYER /obj/screen/zone_sel/MouseExited(location, control, params) if(!isobserver(usr) && hovering_choice) @@ -281,9 +281,9 @@ SEND_SIGNAL(user, COMSIG_MOB_ZONE_SEL_CHANGE, user) /obj/screen/zone_sel/update_icon() - cut_overlays() + ClearOverlays() selecting_appearance = mutable_appearance('icons/mob/zone_sel.dmi', "[selecting]") - add_overlay(selecting_appearance) + AddOverlays(selecting_appearance) /obj/screen/Click(location, control, params) if(!usr) @@ -453,7 +453,6 @@ /obj/screen/movement_intent name = "mov_intent" screen_loc = ui_movi - layer = SCREEN_LAYER //This updates the run/walk button on the hud /obj/screen/movement_intent/proc/update_move_icon(var/mob/living/user) @@ -495,15 +494,14 @@ C.m_intent = M_WALK //Just incase C.hud_used.move_intent.icon_state = "walking" return 1 + switch(usr.m_intent) if(M_RUN) usr.m_intent = M_WALK if(M_WALK) if(!(usr.get_species() in BLACKLIST_SPECIES_RUNNING)) usr.m_intent = M_RUN - if(M_LAY) - // No funny "haha i get the bonuses then stand up" var/obj/item/gun/gun_in_hand = C.get_type_in_hands(/obj/item/gun) if(gun_in_hand?.wielded) @@ -514,7 +512,6 @@ usr.m_intent = M_WALK if(modifiers["button"] == "middle" && !C.lying) // See /mob/proc/update_canmove() for more logic on the lying FSM - // You want this bonus weapon or not? Wield it when you are lying, not before! var/obj/item/gun/gun_in_hand = C.get_type_in_hands(/obj/item/gun) if(gun_in_hand?.wielded) @@ -522,6 +519,10 @@ return C.m_intent = M_LAY + // this works in conjunction with M_LAY to make the mob stand up or lie down instantly + C.update_canmove() + C.update_icon() + else if(istype(usr, /mob/living/simple_animal/hostile/morph)) var/mob/living/simple_animal/hostile/morph/M = usr switch(usr.m_intent) @@ -553,7 +554,7 @@ if(!removed_hand_overlay) var/state = (hud.l_hand_hud_object == src) ? "l_hand_removed" : "r_hand_removed" removed_hand_overlay = image("icon" = 'icons/mob/screen_gen.dmi', "icon_state" = state) - cut_overlays() + ClearOverlays() if(hud.mymob && ishuman(hud.mymob)) var/mob/living/carbon/human/H = hud.mymob var/obj/item/organ/external/O @@ -562,11 +563,11 @@ else O = H.organs_by_name[BP_R_HAND] if(!O || O.is_stump()) - add_overlay(removed_hand_overlay) + AddOverlays(removed_hand_overlay) else if(O && (!O.is_usable() || O.is_malfunctioning())) - add_overlay(disabled_hand_overlay) + AddOverlays(disabled_hand_overlay) if(H.handcuffed) - add_overlay(handcuff_overlay) + AddOverlays(handcuff_overlay) /obj/screen/inventory/back name = "back" diff --git a/code/_onclick/hud/skybox.dm b/code/_onclick/hud/skybox.dm index 9ffcac7ce27..fb556c18ee3 100644 --- a/code/_onclick/hud/skybox.dm +++ b/code/_onclick/hud/skybox.dm @@ -4,8 +4,7 @@ anchored = TRUE simulated = FALSE screen_loc = "CENTER:-224,CENTER:-224" - plane = PLANE_SKYBOX - blend_mode = BLEND_MULTIPLY + plane = SKYBOX_PLANE /client var/obj/skybox/skybox @@ -30,9 +29,3 @@ . = ..() if(. && client) client.update_skybox(old_z != GET_Z(src)) - -/mob/forceMove() - var/old_z = GET_Z(src) - . = ..() - if(. && client) - client.update_skybox(old_z != GET_Z(src)) diff --git a/code/_onclick/hud/spell_screen_objects.dm b/code/_onclick/hud/spell_screen_objects.dm index 87d626a90e7..c2bfb485cb6 100644 --- a/code/_onclick/hud/spell_screen_objects.dm +++ b/code/_onclick/hud/spell_screen_objects.dm @@ -44,14 +44,14 @@ spell_holder.client.screen -= O O.handle_icon_updates = 0 showing = 0 - cut_overlays() - add_overlay(closed_state) + ClearOverlays() + AddOverlays(closed_state) else if(forced_state != 1) open_spellmaster() update_spells(1) showing = 1 - cut_overlays() - add_overlay(open_state) + ClearOverlays() + AddOverlays(open_state) /obj/screen/movable/spell_master/proc/open_spellmaster() var/list/screen_loc_xy = text2list(screen_loc,",") @@ -178,7 +178,7 @@ if((last_charge == spell.charge_counter || !handle_icon_updates) && !forced_update) return //nothing to see here - cut_overlay(spell.hud_state) + CutOverlays(spell.hud_state) if(spell.charge_type == Sp_RECHARGE || spell.charge_type == Sp_CHARGES) if(spell.charge_counter < spell.charge_max) @@ -186,27 +186,27 @@ if(spell.charge_counter > 0) var/icon/partial_charge = icon(src.icon, "[spell_base]_spell_ready") partial_charge.Crop(1, 1, partial_charge.Width(), round(partial_charge.Height() * spell.charge_counter / spell.charge_max)) - add_overlay(partial_charge) + AddOverlays(partial_charge) if(last_charged_icon) - cut_overlay(last_charged_icon) + CutOverlays(last_charged_icon) last_charged_icon = partial_charge else if(last_charged_icon) - cut_overlay(last_charged_icon) + CutOverlays(last_charged_icon) last_charged_icon = null else icon_state = "[spell_base]_spell_ready" if(last_charged_icon) - cut_overlay(last_charged_icon) + CutOverlays(last_charged_icon) else icon_state = "[spell_base]_spell_ready" - add_overlay(spell.hud_state) + AddOverlays(spell.hud_state) last_charge = spell.charge_counter - cut_overlay("silence") + CutOverlays("silence") if(spell.silenced) - add_overlay("silence") + AddOverlays("silence") /obj/screen/spell/Click() if(!usr || !spell) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 1b56771b3e0..68041b7fd22 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -76,13 +76,6 @@ avoid code duplication. This includes items that may sometimes act as a standard return TRUE return ..() -/mob/living/simple_animal/attackby(obj/item/I, mob/living/user) - if(I.damtype == DAMAGE_PAIN) - playsound(loc, 'sound/weapons/tap.ogg', I.get_clamped_volume(), 1, -1) - return TRUE - else - return ..() - // Proximity_flag is 1 if this afterattack was called on something adjacent, in your square, or on your person. // Click parameters is the params string from byond Click() code, see that documentation. /obj/item/proc/afterattack(atom/target, mob/user, proximity_flag, click_parameters) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 0cac821fad8..8abdab43ccc 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -11,9 +11,6 @@ to_chat(src, "You will no longer examine things you click on.") /mob/abstract/observer/DblClickOn(var/atom/A, var/params) - if(client.buildmode) - build_click(src, client.buildmode, params, A) - return if(can_reenter_corpse && mind && mind.current) if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it reenter_corpse() // (cloning scanner, body bag, closet, mech, etc) @@ -29,9 +26,6 @@ forceMove(get_turf(A)) /mob/abstract/observer/ClickOn(var/atom/A, var/params) - if(client.buildmode) - build_click(src, client.buildmode, params, A) - return if(!canClick()) return setClickCooldown(4) // You are responsible for checking config.ghost_interaction when you override this function diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 19a216c7f35..fe0ed44f5c8 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -39,9 +39,6 @@ /mob/proc/attack_empty_hand(var/bp_hand) return -/mob/living/carbon/human/RestrainedClickOn(var/atom/A) - return - /mob/living/carbon/human/RangedAttack(var/atom/A) var/obj/item/clothing/gloves/GV = gloves var/obj/item/clothing/glasses/GS = glasses @@ -174,5 +171,10 @@ /mob/living/CtrlClickOn(var/atom/A) . = ..() + + if(client && client.hardsuit_click_mode == 2) //HARDSUIT_MODE_CTRL_CLICK + if(HardsuitClickOn(A)) + return + if(!. && a_intent == I_GRAB && length(available_maneuvers)) . = perform_maneuver(prepared_maneuver || available_maneuvers[1], A) diff --git a/code/_onclick/rig.dm b/code/_onclick/rig.dm index 588079e33a1..a0eeeb8b375 100644 --- a/code/_onclick/rig.dm +++ b/code/_onclick/rig.dm @@ -41,12 +41,6 @@ return ..() -/mob/living/CtrlClickOn(atom/A) - if(client && client.hardsuit_click_mode == HARDSUIT_MODE_CTRL_CLICK) - if(HardsuitClickOn(A)) - return - ..() - /mob/living/proc/can_use_rig() return 0 diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index b7569a3342a..7476dbd6acf 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -250,6 +250,7 @@ GLOBAL_LIST_EMPTY(gamemode_cache) var/wikiurl var/forumurl var/forum_passphrase + var/rulesurl var/githuburl //Alert level description @@ -646,6 +647,9 @@ GENERAL_PROTECT_DATUM(/datum/configuration) if ("forumurl") GLOB.config.forumurl = value + if ("rulesurl") + GLOB.config.rulesurl = value + if ("forum_passphrase") GLOB.config.forum_passphrase = value diff --git a/code/controllers/subsystems/air.dm b/code/controllers/subsystems/air.dm index 402b1e8371e..6deb7bcc6f6 100644 --- a/code/controllers/subsystems/air.dm +++ b/code/controllers/subsystems/air.dm @@ -202,7 +202,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun T.post_update_air_properties() T.needs_air_update = 0 #ifdef ZASDBG - T.cut_overlay(mark) + T.CutOverlays(mark) updated++ #endif @@ -219,7 +219,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun T.post_update_air_properties() T.needs_air_update = 0 #ifdef ZASDBG - T.cut_overlay(mark) + T.CutOverlays(mark) updated++ #endif @@ -368,7 +368,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun return tiles_to_update += T #ifdef ZASDBG - T.add_overlay(mark) + T.AddOverlays(mark) #endif T.needs_air_update = 1 diff --git a/code/controllers/subsystems/chemistry.dm b/code/controllers/subsystems/chemistry.dm index 3dbcb08ff52..fce5cff387e 100644 --- a/code/controllers/subsystems/chemistry.dm +++ b/code/controllers/subsystems/chemistry.dm @@ -70,7 +70,9 @@ SUBSYSTEM_DEF(chemistry) /datum/controller/subsystem/chemistry/proc/initialize_specific_heats() for(var/_R in subtypesof(/singleton/reagent/)) - check_specific_heat(_R) + var/singleton/reagent/reagent = _R + if(!is_abstract(reagent)) + check_specific_heat(_R) /datum/controller/subsystem/chemistry/stat_entry(msg) msg = "AH:[active_holders.len]" diff --git a/code/controllers/subsystems/economy.dm b/code/controllers/subsystems/economy.dm index 2b49f579e95..757cf76cf5e 100644 --- a/code/controllers/subsystems/economy.dm +++ b/code/controllers/subsystems/economy.dm @@ -139,7 +139,7 @@ SUBSYSTEM_DEF(economy) if(!R.stamped) R.stamped = new R.stamped += /obj/item/stamp - R.add_overlay(stampoverlay) + R.AddOverlays(stampoverlay) R.stamps += "
This paper has been stamped by the Accounts Database." //add the account diff --git a/code/controllers/subsystems/effects.dm b/code/controllers/subsystems/effects.dm index ef369add3ee..afb4ba1fbcb 100644 --- a/code/controllers/subsystems/effects.dm +++ b/code/controllers/subsystems/effects.dm @@ -24,7 +24,7 @@ SUBSYSTEM_DEF(effects) var/datum/effect_system/E = current_effects[current_effects.len] current_effects.len-- - if (QDELETED(E) || !E.isprocessing) + if (QDELETED(E) || !(E.datum_flags & DF_ISPROCESSING)) if (MC_TICK_CHECK) return continue @@ -47,7 +47,7 @@ SUBSYSTEM_DEF(effects) var/obj/effect/visual/V = current_visuals[current_visuals.len] current_visuals.len-- - if (QDELETED(V) || !V.isprocessing) + if (QDELETED(V) || !(V.datum_flags & DF_ISPROCESSING)) visuals -= V if (MC_TICK_CHECK) return diff --git a/code/controllers/subsystems/evacuation/evacuation_pods.dm b/code/controllers/subsystems/evacuation/evacuation_pods.dm index 61d4aebce3f..1f2f4ba0811 100644 --- a/code/controllers/subsystems/evacuation/evacuation_pods.dm +++ b/code/controllers/subsystems/evacuation/evacuation_pods.dm @@ -176,7 +176,6 @@ screen_loc = "WEST,SOUTH to EAST,NORTH" color = "#ff9900" blend_mode = BLEND_SUBTRACT - layer = SCREEN_LAYER #undef EVAC_OPT_ABANDON_SHIP #undef EVAC_OPT_BLUESPACE_JUMP diff --git a/code/controllers/subsystems/ghostroles.dm b/code/controllers/subsystems/ghostroles.dm index 9af6bde3f65..ceef74018cf 100644 --- a/code/controllers/subsystems/ghostroles.dm +++ b/code/controllers/subsystems/ghostroles.dm @@ -33,6 +33,7 @@ SUBSYSTEM_DEF(ghostroles) for (var/identifier in spawnpoints) CHECK_TICK + spawnpoints[identifier] = shuffle(spawnpoints[identifier]) update_spawnpoint_status_by_identifier(identifier) for(var/spawn_type in spawn_types) @@ -51,7 +52,8 @@ SUBSYSTEM_DEF(ghostroles) spawnpoints[P.identifier] = list() spawnpoints[P.identifier] += P - //Only update the status if the round is started. During initialization that´s taken care of at the end of init. + + // Only update the status if the round is started. During initialization that´s taken care of at the end of init. if(ROUND_IS_STARTED) update_spawnpoint_status(P) @@ -141,6 +143,7 @@ SUBSYSTEM_DEF(ghostroles) "short_name" = G.short_name, "name" = G.name, "desc" = G.desc, + "desc_ooc" = G.desc_ooc, "type" = G.type, "cant_spawn" = cant_spawn, "can_edit" = G.can_edit(user), diff --git a/code/controllers/subsystems/icon_cache.dm b/code/controllers/subsystems/icon_cache.dm index e2289dcb4e2..8cc103521d7 100644 --- a/code/controllers/subsystems/icon_cache.dm +++ b/code/controllers/subsystems/icon_cache.dm @@ -99,7 +99,7 @@ SUBSYSTEM_DEF(icon_cache) /datum/controller/subsystem/icon_cache/proc/build_dust_cache() for (var/i in 0 to 25) var/image/im = image('icons/turf/space_parallax1.dmi',"[i]") - im.plane = PLANE_SPACE_DUST + im.plane = DUST_PLANE im.alpha = 80 im.blend_mode = BLEND_ADD space_dust_cache["[i]"] = im diff --git a/code/controllers/subsystems/icon_updates.dm b/code/controllers/subsystems/icon_updates.dm index dccb6012f9e..ef1d8e0d170 100644 --- a/code/controllers/subsystems/icon_updates.dm +++ b/code/controllers/subsystems/icon_updates.dm @@ -14,9 +14,6 @@ SUBSYSTEM_DEF(icon_update) ///Deferred list, contains atoms that were not ready to be processed in the previous run VAR_PRIVATE/list/deferred = list() -/datum/controller/subsystem/icon_update/New() - NEW_SS_GLOBAL(SSicon_update) - /datum/controller/subsystem/icon_update/stat_entry(msg) msg = "QU:[icon_update_queue.len]" return ..() diff --git a/code/controllers/subsystems/initialization/atlas.dm b/code/controllers/subsystems/initialization/atlas.dm index 4e627df880b..fbdfc1f561c 100644 --- a/code/controllers/subsystems/initialization/atlas.dm +++ b/code/controllers/subsystems/initialization/atlas.dm @@ -173,7 +173,6 @@ SUBSYSTEM_DEF(atlas) world.map_panic("Selected map does not exist!") load_map_meta() - setup_spawnpoints() world.update_status() @@ -212,6 +211,8 @@ SUBSYSTEM_DEF(atlas) current_sector.setup_current_sector() + setup_spawnpoints() + return SS_INIT_SUCCESS /datum/controller/subsystem/atlas/proc/load_map_directory(directory, overwrite_default_z = FALSE) diff --git a/code/controllers/subsystems/initialization/map_finalization.dm b/code/controllers/subsystems/initialization/map_finalization.dm index 619921acabf..4f0e2035e74 100644 --- a/code/controllers/subsystems/initialization/map_finalization.dm +++ b/code/controllers/subsystems/initialization/map_finalization.dm @@ -18,9 +18,6 @@ SUBSYSTEM_DEF(finalize) load_space_ruin() - if(GLOB.config.dungeon_chance > 0) - place_dungeon_spawns() - if(GLOB.config.generate_asteroid) time = world.time SSatlas.current_map.generate_asteroid() @@ -66,49 +63,6 @@ SUBSYSTEM_DEF(finalize) SSatlas.current_map.restricted_levels.Add(world.maxz) QDEL_NULL(maploader) -/datum/controller/subsystem/finalize/proc/place_dungeon_spawns() - var/map_directory = "maps/dungeon_spawns/" - var/list/files = flist(map_directory) - var/start_time = world.time - var/dungeons_placed = 0 - var/dmm_suite/maploader = new - - var/dungeon_chance = GLOB.config.dungeon_chance - - log_subsystem_mapfinalization("Attempting to create asteroid dungeons for [length(GLOB.asteroid_spawn)] different areas, with [length(files) - 1] possible dungeons, with a [dungeon_chance]% chance to spawn a dungeon per area.") - - for(var/turf/spawn_location in GLOB.asteroid_spawn) - - if(length(files) <= 0) //Sanity - log_subsystem_mapfinalization("There aren't enough dungeon map files to fill the entire dungeon map. There may be less dungeons than expected.") - break - - if(prob(dungeon_chance)) - - var/chosen_dungeon = pick(files) - - if(!dd_hassuffix(chosen_dungeon,".dmm")) //Don't read anything that isn't a map file - files -= chosen_dungeon - log_subsystem_mapfinalization_error("ALERT: [chosen_dungeon] is not a .dmm file! Skipping!") - continue - - var/map_file = file("[map_directory][chosen_dungeon]") - - if(isfile(map_file)) //Sanity - log_subsystem_mapfinalization("Loading dungeon '[chosen_dungeon]' at coordinates [spawn_location.x], [spawn_location.y], [spawn_location.z].") - maploader.load_map(map_file,spawn_location.x,spawn_location.y,spawn_location.z) - dungeons_placed += 1 - else - log_subsystem_mapfinalization_error("ERROR: Something weird happened with the file: [chosen_dungeon].") - log_mapping("ERROR: Something weird happened with the file: [chosen_dungeon].") - - if(dd_hassuffix(chosen_dungeon,"_unique.dmm")) //Unique dungeons should only spawn once. - files -= chosen_dungeon - - log_subsystem_mapfinalization("Loaded [dungeons_placed] asteroid dungeons in [(world.time - start_time)/10] seconds.") - - qdel(maploader) - /datum/controller/subsystem/finalize/proc/generate_contact_report() if(!selected_mission) return diff --git a/code/controllers/subsystems/initialization/xenoarch.dm b/code/controllers/subsystems/initialization/xenoarch.dm index a5981b77104..69bbdeeed93 100644 --- a/code/controllers/subsystems/initialization/xenoarch.dm +++ b/code/controllers/subsystems/initialization/xenoarch.dm @@ -62,7 +62,7 @@ SUBSYSTEM_DEF(xenoarch) var/datum/find/F = archeo_turf.finds[1] if(F.excavation_required <= F.view_range) archeo_turf.archaeo_overlay = "overlay_archaeo[rand(1,3)]" - archeo_turf.add_overlay(archeo_turf.archaeo_overlay) + archeo_turf.AddOverlays(archeo_turf.archaeo_overlay) //have a chance for an artifact to spawn here, but not in animal or plant digsites if(isnull(M.artifact_find) && digsite != 1 && digsite != 2) diff --git a/code/controllers/subsystems/job.dm b/code/controllers/subsystems/job.dm index 2e98e1472fa..a2676b7cf09 100644 --- a/code/controllers/subsystems/job.dm +++ b/code/controllers/subsystems/job.dm @@ -54,6 +54,9 @@ SUBSYSTEM_DEF(jobs) continue occupations += job name_occupations[job.title] = job + if(LAZYLEN(job.alt_titles)) + for(var/alt_title in job.alt_titles) + name_occupations[alt_title] = job type_occupations[J] = job if(!length(bitflag_to_job["[job.department_flag]"])) bitflag_to_job["[job.department_flag]"] = list() @@ -583,11 +586,7 @@ SUBSYSTEM_DEF(jobs) if(spawnpos && istype(spawnpos)) if(spawnpos.check_job_spawning(rank)) if(istype(spawnpos, /datum/spawnpoint/cryo) && (rank in command_positions)) - var/datum/spawnpoint/cryo/C = spawnpos - if(length(C.command_turfs)) - H.forceMove(pick(C.command_turfs)) - else - H.forceMove(pick(spawnpos.turfs)) + H.forceMove(pick(spawnpos.turfs)) else H.forceMove(pick(spawnpos.turfs)) . = spawnpos.msg @@ -860,7 +859,7 @@ SUBSYSTEM_DEF(jobs) T.icon_state = "nothing" T.maptext_height = 64 T.maptext_width = 512 - T.layer = SCREEN_LAYER+1 + T.layer = HUD_ABOVE_ITEM_LAYER T.plane = FLOAT_PLANE T.screen_loc = "LEFT+1,BOTTOM+2" diff --git a/code/controllers/subsystems/machinery.dm b/code/controllers/subsystems/machinery.dm index 9ec5eeb53f8..86e07244d66 100644 --- a/code/controllers/subsystems/machinery.dm +++ b/code/controllers/subsystems/machinery.dm @@ -5,22 +5,19 @@ #define START_PROCESSING_IN_LIST(Datum, List) \ -if (Datum.isprocessing) {\ - if(Datum.isprocessing != "SSmachinery.[#List]")\ - {\ - crash_with("Failed to start processing. [log_info_line(Datum)] is already being processed by [Datum.isprocessing] but queue attempt occured on SSmachinery.[#List]."); \ - }\ +if (Datum.datum_flags & DF_ISPROCESSING) {\ + crash_with("Failed to start processing. [log_info_line(Datum)] is already being processed but queue attempt occured on SSmachinery.[#List]."); \ } else {\ - Datum.isprocessing = "SSmachinery.[#List]";\ + Datum.datum_flags |= DF_ISPROCESSING;\ SSmachinery.List += Datum;\ } #define STOP_PROCESSING_IN_LIST(Datum, List) \ -if(Datum.isprocessing) {\ +if(Datum.datum_flags & DF_ISPROCESSING) {\ if(SSmachinery.List.Remove(Datum)) {\ - Datum.isprocessing = null;\ + (Datum.datum_flags &= ~DF_ISPROCESSING);\ } else {\ - crash_with("Failed to stop processing. [log_info_line(Datum)] is being processed by [isprocessing] and not found in SSmachinery.[#List]"); \ + crash_with("Failed to stop processing. [log_info_line(Datum)] is being processed and not found in SSmachinery.[#List]"); \ }\ } @@ -35,9 +32,9 @@ if(Datum.isprocessing) {\ SUBSYSTEM_DEF(machinery) name = "Machinery" - priority = SS_PRIORITY_MACHINERY init_order = INIT_ORDER_MACHINES - flags = SS_POST_FIRE_TIMING + priority = SS_PRIORITY_MACHINERY + flags = SS_KEEP_TIMING wait = 2 SECONDS var/static/tmp/current_step = SSMACHINERY_PIPENETS @@ -164,7 +161,7 @@ SUBSYSTEM_DEF(machinery) network = queue[i] if (QDELETED(network)) if (network) - network.isprocessing = null + network.datum_flags &= ~DF_ISPROCESSING pipenets -= network continue network.process(wait * 0.1) @@ -186,7 +183,7 @@ SUBSYSTEM_DEF(machinery) continue // Hard delete; unlikely but possible. Soft deletes are handled below and expected. if(machine in processing) processing.Remove(machine) - machine.isprocessing = null + machine.datum_flags &= ~DF_ISPROCESSING WARNING("[log_info_line(machine)] was found illegally queued on SSmachines.") continue else if(resumed) @@ -200,7 +197,7 @@ SUBSYSTEM_DEF(machinery) if (QDELETED(machine)) if (machine) - machine.isprocessing = null + machine.datum_flags &= ~DF_ISPROCESSING processing -= machine continue //process_all was moved here because of calls overhead for no benefits @@ -222,7 +219,7 @@ SUBSYSTEM_DEF(machinery) network = queue[i] if (QDELETED(network)) if (network) - network.isprocessing = null + network.datum_flags &= ~DF_ISPROCESSING powernets -= network continue network.reset(wait) @@ -240,11 +237,11 @@ SUBSYSTEM_DEF(machinery) item = queue[i] if (QDELETED(item)) if (item) - item.isprocessing = null + item.datum_flags &= ~DF_ISPROCESSING power_objects -= item continue if (!item.pwr_drain(wait)) - item.isprocessing = null + item.datum_flags &= ~DF_ISPROCESSING power_objects -= item if (no_mc_tick) CHECK_TICK diff --git a/code/controllers/subsystems/news.dm b/code/controllers/subsystems/news.dm index 73812185370..b2f85fcf9c3 100644 --- a/code/controllers/subsystems/news.dm +++ b/code/controllers/subsystems/news.dm @@ -150,7 +150,7 @@ SUBSYSTEM_DEF(news) alert_readers(FC.announcement) /datum/controller/subsystem/news/proc/alert_readers(var/annoncement) - set waitfor = FALSE + SHOULD_NOT_SLEEP(TRUE) for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) NEWSCASTER.newsAlert(annoncement) NEWSCASTER.update_icon() diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm index 760861a1860..e28f7189932 100644 --- a/code/controllers/subsystems/overlays.dm +++ b/code/controllers/subsystems/overlays.dm @@ -1,248 +1,307 @@ +/// SSoverlays. Target the normal overlay cache. +var/global/const/ATOM_ICON_CACHE_NORMAL = FLAG(0) + +/// SSoverlays. Target the protected overlay cache. +var/global/const/ATOM_ICON_CACHE_PROTECTED = FLAG(1) + +/// SSoverlays. Target both normal and protected overlay caches. +var/global/const/ATOM_ICON_CACHE_ALL = (ATOM_ICON_CACHE_NORMAL | ATOM_ICON_CACHE_PROTECTED) + + SUBSYSTEM_DEF(overlays) - name = "Overlay" + name = "Overlays" flags = SS_TICKER - runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY - wait = 1 + wait = 1 // ticks priority = SS_PRIORITY_OVERLAY init_order = INIT_ORDER_OVERLAY - var/list/processing = list() + /// The queue of atoms that need under/overlay updates. + var/static/list/atom/queue = list() - var/idex = 1 - var/list/overlay_icon_state_caches = list() - var/list/overlay_icon_cache = list() - initialized = FALSE + /// A list([icon] = list([state] = [appearance], ...), ...) cache of appearances. + var/static/list/state_cache = list() -/datum/controller/subsystem/overlays/stat_entry(msg) - msg = "Ov:[processing.len - (idex - 1)]" - return ..() + /// A list([icon] = [appearance], ...) cache of appearances. + var/static/list/icon_cache = list() + + /// The number of appearances currently cached. + var/static/cache_size = 0 + + initialized = FALSE -/datum/controller/subsystem/overlays/Initialize() +/datum/controller/subsystem/overlays/Recover() + LIST_RESIZE(queue, 0) + LIST_RESIZE(state_cache, 0) + LIST_RESIZE(icon_cache, 0) + cache_size = 0 + var/count = 0 + for (var/atom/atom) + atom.atom_flags &= ~ATOM_AWAITING_OVERLAY_UPDATE + if (++count % 500) + continue + CHECK_TICK + +/datum/controller/subsystem/overlays/Initialize(start_uptime) initialized = TRUE - Flush() + fire(FALSE, TRUE) return SS_INIT_SUCCESS -/datum/controller/subsystem/overlays/Recover() - overlay_icon_state_caches = SSoverlays.overlay_icon_state_caches - overlay_icon_cache = SSoverlays.overlay_icon_cache - processing = SSoverlays.processing +/datum/controller/subsystem/overlays/stat_entry(msg) + msg = "Queued Atoms: [length(queue)], Cache Size: [cache_size]" + return ..() -/datum/controller/subsystem/overlays/fire(resumed = FALSE, mc_check = TRUE) - var/list/processing = src.processing - while(idex <= processing.len) - var/atom/thing = processing[idex++] +/datum/controller/subsystem/overlays/fire(resumed, no_mc_tick) + var/queue_length = length(queue) + if (queue_length) + var/atom/atom + for (var/i = 1 to queue_length) + atom = queue[i] + if (QDELETED(atom)) + continue + if (atom.atom_flags & ATOM_AWAITING_OVERLAY_UPDATE) + atom.UpdateOverlays() + if (no_mc_tick) + if (i % 1000) + continue + CHECK_TICK + else if (MC_TICK_CHECK) + queue.Cut(1, i + 1) + return + queue.Cut(1, queue_length + 1) + +/datum/controller/subsystem/overlays/proc/GetStateAppearance(icon, state) + var/list/subcache = state_cache[icon] + if (!subcache) + subcache = list() + state_cache[icon] = subcache + if (!subcache[state]) + var/image/image = image(icon, null, state) + subcache[state] = image.appearance + ++cache_size + return subcache[state] + + +/datum/controller/subsystem/overlays/proc/GetIconAppearance(icon) + if (!icon_cache[icon]) + var/image/image = image(icon) + icon_cache[icon] = image.appearance + ++cache_size + return icon_cache[icon] + + +/datum/controller/subsystem/overlays/proc/GetAppearanceList(atom/subject, list/sources) + if (!sources) + return list() + if (!islist(sources)) + sources = list(sources) + var/list/result = list() + var/icon/icon = subject.icon + var/atom/entry + for (var/i = 1 to length(sources)) + entry = sources[i] + if (!entry) + continue + else if (istext(entry)) + result += GetStateAppearance(icon, entry) + else if (isicon(entry)) + result += GetIconAppearance(entry) + else + if (isloc(entry)) + if (entry.atom_flags & ATOM_AWAITING_OVERLAY_UPDATE) + entry.UpdateOverlays() + if (!ispath(entry)) + result += entry.appearance + else + var/image/image = entry + result += image.appearance + return result + + +/// Immediately runs an overlay update. +/atom/proc/ImmediateOverlayUpdate() + SHOULD_NOT_OVERRIDE(TRUE) + UpdateOverlays() + +/** +* Shared behavior for ClearOverlays & CutUnderlays. Do not use directly. +* null: nothing changed, do nothing +* FALSE: update should be queued +* TRUE: update should be queued, cache should be nulled +*/ +/atom/proc/CutCacheBehavior(sources, cache) + SHOULD_NOT_OVERRIDE(TRUE) + var/initial_length = length(cache) + if (!initial_length) + return + cache -= sources + var/after_length = length(cache) + if (!after_length) + return TRUE + if (initial_length > after_length) + return FALSE + + +/// Enqueues the atom for an overlay update if not already queued +/atom/proc/QueueOverlayUpdate() + SHOULD_NOT_OVERRIDE(TRUE) + if (atom_flags & ATOM_AWAITING_OVERLAY_UPDATE) + return + atom_flags |= ATOM_AWAITING_OVERLAY_UPDATE + SSoverlays.queue += src - if(!QDELETED(thing) && thing.overlay_queued) // Don't double-process if something already forced a compile. - thing.compile_overlays() - if(mc_check) - if(MC_TICK_CHECK) - break +/// Builds the atom's overlay state from caches +/atom/proc/UpdateOverlays() + SHOULD_NOT_OVERRIDE(TRUE) + atom_flags &= ~ATOM_AWAITING_OVERLAY_UPDATE + if (QDELING(src)) + LIST_RESIZE(overlays, 0) + return + if (length(atom_protected_overlay_cache)) + if (length(atom_overlay_cache)) + overlays = atom_protected_overlay_cache + atom_overlay_cache else - CHECK_TICK - - if (idex > 1) - processing.Cut(1, idex) - idex = 1 - -/datum/controller/subsystem/overlays/proc/Flush() - if(processing.len) - log_subsystem("overlays", "Flushing [processing.len] overlays.") - fire(mc_check = FALSE) - -/atom/proc/compile_overlays() - var/list/oo = our_overlays - var/list/po = priority_overlays - if(LAZYLEN(po) && LAZYLEN(oo)) - overlays = oo + po - else if(LAZYLEN(oo)) - overlays = oo - else if(LAZYLEN(po)) - overlays = po + overlays = atom_protected_overlay_cache + else if (length(atom_overlay_cache)) + overlays = atom_overlay_cache else - overlays.Cut() - - overlay_queued = FALSE - -/atom/movable/compile_overlays() - ..() - UPDATE_OO_IF_PRESENT - -/turf/compile_overlays() - ..() - if (istype(above)) - update_above() - -/proc/iconstate2appearance(icon, iconstate) - var/static/image/stringbro = new() - var/list/icon_states_cache = SSoverlays.overlay_icon_state_caches - var/list/cached_icon = icon_states_cache[icon] - if (cached_icon) - var/cached_appearance = cached_icon["[iconstate]"] - if (cached_appearance) - return cached_appearance - stringbro.icon = icon - stringbro.icon_state = iconstate - if (!cached_icon) //not using the macro to save an associated lookup - cached_icon = list() - icon_states_cache[icon] = cached_icon - var/cached_appearance = stringbro.appearance - cached_icon["[iconstate]"] = cached_appearance - return cached_appearance - -/proc/icon2appearance(icon) - var/static/image/iconbro = new() - var/list/icon_cache = SSoverlays.overlay_icon_cache - . = icon_cache[icon] - if (!.) - iconbro.icon = icon - . = iconbro.appearance - icon_cache[icon] = . - -#define APPEARANCEIFY(origin, target) \ - if (istext(origin)) { \ - target = iconstate2appearance(icon, origin); \ - } \ - else if (isicon(origin)) { \ - target = icon2appearance(origin); \ - } \ - else { \ - appearance_bro.appearance = origin; \ - if (!ispath(origin)) { \ - appearance_bro.dir = origin.dir; \ - } \ - target = appearance_bro.appearance; \ - } - -/atom/proc/build_appearance_list(atom/new_overlays) - var/static/image/appearance_bro = new - if (islist(new_overlays)) - listclearnulls(new_overlays) - for (var/i in 1 to length(new_overlays)) - var/image/cached_overlay = new_overlays[i] - APPEARANCEIFY(cached_overlay, new_overlays[i]) - return new_overlays + LIST_RESIZE(overlays, 0) + + +/// Clears the atom's overlay cache(s) and queues an update if needed. Use CLEAR_TARGET_* flags. +/atom/proc/ClearOverlays(cache_target = ATOM_ICON_CACHE_NORMAL) + SHOULD_NOT_OVERRIDE(TRUE) + if (cache_target & ATOM_ICON_CACHE_PROTECTED) + if (!atom_protected_overlay_cache) + return + LAZYCLEARLIST(atom_protected_overlay_cache) + QueueOverlayUpdate() + if (cache_target & ATOM_ICON_CACHE_NORMAL) + if (!atom_overlay_cache) + return + LAZYCLEARLIST(atom_overlay_cache) + QueueOverlayUpdate() + + +/** + * Adds specific overlay(s) to the atom. + * It is designed so any of the types allowed to be added to /atom/overlays can be added here too. More details below. + * + * @param sources The overlay(s) to add. These may be + * - A string: In which case it is treated as an icon_state of the atom's icon. + * - An icon: It is treated as an icon. + * - An atom: Its own overlays are compiled and then it's appearance is added. (Meaning its current apperance is frozen). + * - An image: Image's apperance is added (i.e. subsequently editing the image will not edit the overlay) + * - A type path: Added to overlays as is. Does whatever it is BYOND does when you add paths to overlays. + * - Or a list containing any of the above. + * @param cache_target If ATOM_ICON_CACHE_PROTECTED, add to the protected cache instead of normal. + */ +/atom/proc/AddOverlays(sources, cache_target = ATOM_ICON_CACHE_NORMAL) + SHOULD_NOT_OVERRIDE(TRUE) + if (!sources) + return + sources = SSoverlays.GetAppearanceList(src, sources) + if (!length(sources)) + return + if (cache_target & ATOM_ICON_CACHE_PROTECTED) + if (atom_protected_overlay_cache) + atom_protected_overlay_cache += sources + else + atom_protected_overlay_cache = sources + else if (atom_overlay_cache) + atom_overlay_cache += sources else - APPEARANCEIFY(new_overlays, .) - -#undef APPEARANCEIFY -#define NOT_QUEUED_ALREADY (!(overlay_queued)) -#define QUEUE_FOR_COMPILE overlay_queued = TRUE; SSoverlays.processing += src; - -/atom/proc/cut_overlays(priority = FALSE, force_compile = FALSE) - var/list/cached_overlays = our_overlays - var/list/cached_priority = priority_overlays - - var/need_compile = FALSE - - if(LAZYLEN(cached_overlays)) //don't queue empty lists, don't cut priority overlays - cached_overlays.Cut() //clear regular overlays - need_compile = TRUE - - if(priority && LAZYLEN(cached_priority)) - cached_priority.Cut() - need_compile = TRUE - - if(need_compile) - if(!SS_IS_RUNNING(SSoverlays)) - compile_overlays() - else if(NOT_QUEUED_ALREADY) - QUEUE_FOR_COMPILE - -/atom/proc/cut_overlay(list/overlays, priority = FALSE, force_compile = FALSE) - if(!overlays) + atom_overlay_cache = sources + QueueOverlayUpdate() + + +/** + * Removes specific overlay(s) from the atom's normal or protected overlay cache and queue an update. + * + * @param overlays The overlays to removed. See AddOverlays for legal source types. + * @param cache_target A mask of ICON_CACHE_TARGET_*. + */ +/atom/proc/CutOverlays(sources, cache_target = ATOM_ICON_CACHE_NORMAL) + SHOULD_NOT_OVERRIDE(TRUE) + if (!sources) return + sources = SSoverlays.GetAppearanceList(src, sources) + if (!length(sources)) + return + var/update + if (cache_target & ATOM_ICON_CACHE_PROTECTED) + var/outcome = CutCacheBehavior(sources, atom_protected_overlay_cache) + if (!isnull(outcome)) + update = TRUE + if (outcome == TRUE) + atom_protected_overlay_cache = null + if (cache_target & ATOM_ICON_CACHE_NORMAL) + var/outcome = CutCacheBehavior(sources, atom_overlay_cache) + if (!isnull(outcome)) + update = TRUE + if (outcome == TRUE) + atom_overlay_cache = null + if (update) + QueueOverlayUpdate() + + +/// AddOverlays with ClearOverlays first. See AddOverlays for behavior. +/atom/proc/SetOverlays(sources, cache_target = ATOM_ICON_CACHE_NORMAL) + SHOULD_NOT_OVERRIDE(TRUE) + ClearOverlays(cache_target) + AddOverlays(sources, cache_target) + + +/** + * Copy the overlays from another atom. + * + * @param other The atom to copy overlays from. + * @param clear If TRUE, clear before adding other's overlays. + * @param cache_target A mask of ICON_CACHE_TARGET_* indicating what to copy. + */ +/atom/proc/CopyOverlays(atom/other, clear, cache_target = ATOM_ICON_CACHE_NORMAL) + SHOULD_NOT_OVERRIDE(TRUE) + if (clear) + ClearOverlays(cache_target) + if (!istype(other)) + return + if (cache_target & ATOM_ICON_CACHE_PROTECTED) + AddOverlays(other.atom_protected_overlay_cache, ATOM_ICON_CACHE_PROTECTED) + if (cache_target & ATOM_ICON_CACHE_NORMAL) + AddOverlays(other.atom_overlay_cache, ATOM_ICON_CACHE_NORMAL) - overlays = build_appearance_list(overlays) - - var/list/cached_overlays = our_overlays //sanic - var/list/cached_priority = priority_overlays - var/init_o_len = LAZYLEN(cached_overlays) - var/init_p_len = LAZYLEN(cached_priority) //starter pokemon - - LAZYREMOVE(cached_overlays, overlays) - if(priority) - LAZYREMOVE(cached_priority, overlays) - if(force_compile && !SS_IS_RUNNING(SSoverlays)) - compile_overlays() - else if(NOT_QUEUED_ALREADY && ((init_o_len != LAZYLEN(cached_priority)) || (init_p_len != LAZYLEN(cached_overlays)))) - QUEUE_FOR_COMPILE +// Skin-deep API parity for images. +// Reference for permitted types. -/atom/proc/add_overlay(list/overlays, priority = FALSE, force_compile = FALSE) - if(!overlays) - return +/// Adds sources to the image's overlays. +/image/proc/AddOverlays(sources) + SHOULD_NOT_OVERRIDE(TRUE) + overlays |= sources - overlays = build_appearance_list(overlays) - if (!overlays || (islist(overlays) && !overlays.len)) - // No point trying to compile if we don't have any overlays. - return +/// Removes sources from the image's overlays. +/image/proc/CutOverlays(sources) + SHOULD_NOT_OVERRIDE(TRUE) + overlays -= sources - if(priority) - LAZYADD(priority_overlays, overlays) - else - LAZYADD(our_overlays, overlays) - if(force_compile && !SS_IS_RUNNING(SSoverlays)) - compile_overlays() - else if(NOT_QUEUED_ALREADY) - QUEUE_FOR_COMPILE +/// Removes all of the image's overlays. +/image/proc/ClearOverlays() + SHOULD_NOT_OVERRIDE(TRUE) + LIST_RESIZE(overlays, 0) -/atom/proc/set_overlays(list/overlays, priority = FALSE, force_compile = FALSE) // Sets overlays to a list, equivalent to cut_overlays() + add_overlays(). - if (!overlays) - return - - overlays = build_appearance_list(overlays) - if (priority) - LAZYCLEARLIST(priority_overlays) - if (overlays) - LAZYADD(priority_overlays, overlays) - else - LAZYCLEARLIST(our_overlays) - if (overlays) - LAZYADD(our_overlays, overlays) - - if(force_compile && !SS_IS_RUNNING(SSoverlays)) - compile_overlays() - else if (NOT_QUEUED_ALREADY) - QUEUE_FOR_COMPILE - -/atom/proc/copy_overlays(atom/other, cut_old = FALSE, force_compile = FALSE) //copys our_overlays from another atom - if(!other) - if(cut_old) - cut_overlays() +/// Copies the overlays from the atom other, clearing first if set, and using the caches indicated. +/image/proc/CopyOverlays(atom/other, clear, cache_target = ATOM_ICON_CACHE_ALL) + SHOULD_NOT_OVERRIDE(TRUE) + if (clear) + LIST_RESIZE(overlays, 0) + if (!istype(other)) return + if (cache_target & ATOM_ICON_CACHE_PROTECTED) + overlays |= other.atom_protected_overlay_cache + if (cache_target & ATOM_ICON_CACHE_NORMAL) + overlays |= other.atom_overlay_cache - var/list/cached_other = other.our_overlays - if(cached_other) - if(cut_old) - our_overlays = cached_other.Copy() - else - our_overlays |= cached_other - if(force_compile && !SS_IS_RUNNING(SSoverlays)) - compile_overlays() - else if(NOT_QUEUED_ALREADY) - QUEUE_FOR_COMPILE - else if(cut_old) - cut_overlays() - -#undef NOT_QUEUED_ALREADY -#undef QUEUE_FOR_COMPILE - -//TODO: Better solution for these? -/image/proc/add_overlay(x) - overlays += x - -/image/proc/cut_overlay(x) - overlays -= x - -/image/proc/cut_overlays(x) - overlays.Cut() - -/atom - var/tmp/list/our_overlays //our local copy of (non-priority) overlays without byond magic. Use procs in SSoverlays to manipulate - var/tmp/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4. - var/tmp/overlay_queued diff --git a/code/controllers/subsystems/processing/airflow.dm b/code/controllers/subsystems/processing/airflow.dm index b0f3ccd57ba..bf873eb7282 100644 --- a/code/controllers/subsystems/processing/airflow.dm +++ b/code/controllers/subsystems/processing/airflow.dm @@ -15,6 +15,7 @@ PROCESSING_SUBSYSTEM_DEF(airflow) priority = SS_PRIORITY_AIRFLOW /datum/controller/subsystem/processing/airflow/fire(resumed = FALSE) + CAN_BE_REDEFINED(TRUE) if (!resumed) currentrun = processing.Copy() // Defined in parent. diff --git a/code/controllers/subsystems/processing/nanoui.dm b/code/controllers/subsystems/processing/nanoui.dm index d7a5ed71c0a..85881096c5b 100644 --- a/code/controllers/subsystems/processing/nanoui.dm +++ b/code/controllers/subsystems/processing/nanoui.dm @@ -8,9 +8,6 @@ PROCESSING_SUBSYSTEM_DEF(nanoui) // NanoUI stuff. var/list/open_uis = list() -/datum/controller/subsystem/processing/nanoui/New() - NEW_SS_GLOBAL(SSnanoui) - /** * Get an open /nanoui ui for the current user, src_object and ui_key and try to update it with data * diff --git a/code/controllers/subsystems/processing/ntsl2.dm b/code/controllers/subsystems/processing/ntsl2.dm index 7516c1d5e52..c248e8e7a83 100644 --- a/code/controllers/subsystems/processing/ntsl2.dm +++ b/code/controllers/subsystems/processing/ntsl2.dm @@ -140,6 +140,7 @@ PROCESSING_SUBSYSTEM_DEF(ntsl2) /datum/controller/subsystem/processing/ntsl2/fire(resumed) + CAN_BE_REDEFINED(TRUE) for(var/task_id in tasks) var/task = tasks[task_id] var/datum/http_request/req = task["request"] diff --git a/code/controllers/subsystems/processing/obj_tab_items.dm b/code/controllers/subsystems/processing/obj_tab_items.dm index 53786daf011..48a986a7cdb 100644 --- a/code/controllers/subsystems/processing/obj_tab_items.dm +++ b/code/controllers/subsystems/processing/obj_tab_items.dm @@ -7,6 +7,7 @@ PROCESSING_SUBSYSTEM_DEF(obj_tab_items) // I know this is mostly copypasta, but I want to change the processing logic // Sorry bestie :( /datum/controller/subsystem/processing/obj_tab_items/fire(resumed = FALSE) + CAN_BE_REDEFINED(TRUE) if (!resumed) currentrun = processing.Copy() //cache for sanic speed (lists are references anyways) diff --git a/code/controllers/subsystems/processing/processing.dm b/code/controllers/subsystems/processing/processing.dm index e83e45f412b..eccfa750ad2 100644 --- a/code/controllers/subsystems/processing/processing.dm +++ b/code/controllers/subsystems/processing/processing.dm @@ -1,8 +1,10 @@ //Used to process objects. Fires once every two seconds. + SUBSYSTEM_DEF(processing) name = "Processing" - priority = SS_PRIORITY_PROCESSING + priority = FIRE_PRIORITY_PROCESS flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT + wait = 1 SECONDS var/stat_tag = "P" //Used for logging var/list/processing = list() @@ -21,17 +23,31 @@ SUBSYSTEM_DEF(processing) while(current_run.len) var/datum/thing = current_run[current_run.len] current_run.len-- - if(!QDELETED(thing)) - if (thing.process(wait, times_fired) == PROCESS_KILL) - stop_processing(thing) - else + if(QDELETED(thing)) processing -= thing + else if(thing.process(wait * 0.1) == PROCESS_KILL) + // fully stop so that a future START_PROCESSING will work + STOP_PROCESSING(src, thing) if (MC_TICK_CHECK) return -// Helper so PROCESS_KILL works. -/datum/controller/subsystem/processing/proc/stop_processing(datum/D) - STOP_PROCESSING(src, D) + +/** + * 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 seconds_per_tick that is sent as a parameter, + * Additionally, any "prob" you use in this proc should instead use the SPT_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 -= seconds_per_tick`, not `mytimer -= 1`. This way, `mytimer` will always have the unit of seconds + * - Damaging a mob, do `L.adjustFireLoss(20 * seconds_per_tick)`, 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(SPT_PROB(25, seconds_per_tick))`, 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(seconds_per_tick) + set waitfor = FALSE + return PROCESS_KILL /datum/controller/subsystem/processing/ExplosionStart() can_fire = FALSE diff --git a/code/controllers/subsystems/processing/psi.dm b/code/controllers/subsystems/processing/psi.dm index 5a70aedb4b3..6c3cb671f13 100644 --- a/code/controllers/subsystems/processing/psi.dm +++ b/code/controllers/subsystems/processing/psi.dm @@ -15,6 +15,7 @@ PROCESSING_SUBSYSTEM_DEF(psi) var/list/all_psi_complexes = list() /datum/controller/subsystem/processing/psi/fire(resumed) + CAN_BE_REDEFINED(TRUE) ..() if((world.time >= (last_nlom_awareness_check + 30 MINUTES)) && !checking_nlom && !completing_nlom) checking_nlom = TRUE diff --git a/code/controllers/subsystems/processing/tgui.dm b/code/controllers/subsystems/processing/tgui.dm index b437c03baf6..6d298f446c6 100644 --- a/code/controllers/subsystems/processing/tgui.dm +++ b/code/controllers/subsystems/processing/tgui.dm @@ -26,8 +26,7 @@ PROCESSING_SUBSYSTEM_DEF(tgui) /// The HTML base used for all UIs. var/basehtml -/datum/controller/subsystem/processing/tgui/New() - NEW_SS_GLOBAL(SStgui) +/datum/controller/subsystem/processing/tgui/PreInit() basehtml = file2text('tgui/public/tgui.html') // Inject inline polyfills var/polyfill = file2text('tgui/public/tgui-polyfill.min.js') @@ -43,6 +42,7 @@ PROCESSING_SUBSYSTEM_DEF(tgui) return ..() /datum/controller/subsystem/processing/tgui/fire(resumed = FALSE) + CAN_BE_REDEFINED(TRUE) if(!resumed) src.current_run = open_uis.Copy() // Cache for sanic speed (lists are references anyways) diff --git a/code/controllers/subsystems/runechat.dm b/code/controllers/subsystems/runechat.dm index 663bb8cf347..8b99a635326 100644 --- a/code/controllers/subsystems/runechat.dm +++ b/code/controllers/subsystems/runechat.dm @@ -5,6 +5,7 @@ TIMER_SUBSYSTEM_DEF(runechat) var/list/datum/callback/message_queue = list() /datum/controller/subsystem/timer/runechat/fire(resumed) + CAN_BE_REDEFINED(TRUE) . = ..() //poggers while(message_queue.len) var/datum/callback/queued_message = message_queue[message_queue.len] diff --git a/code/controllers/subsystems/skybox.dm b/code/controllers/subsystems/skybox.dm index 16c5c7e6e1e..27456738003 100644 --- a/code/controllers/subsystems/skybox.dm +++ b/code/controllers/subsystems/skybox.dm @@ -17,13 +17,13 @@ SUBSYSTEM_DEF(skybox) space_appearance_cache = new(26) for (var/i in 0 to 25) var/mutable_appearance/dust = mutable_appearance('icons/turf/space_dust.dmi', "[i]") - dust.plane = PLANE_SPACE_DUST + dust.plane = DUST_PLANE dust.alpha = 80 dust.blend_mode = BLEND_ADD var/mutable_appearance/space = new /mutable_appearance(/turf/space) space.name = "space" - space.plane = PLANE_SPACE_BACKGROUND + space.plane = SPACE_PLANE space.icon_state = "white" space.overlays += dust space_appearance_cache[i + 1] = space.appearance diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm index 02b72fb220f..1f4ad87ffd9 100644 --- a/code/controllers/subsystems/ticker.dm +++ b/code/controllers/subsystems/ticker.dm @@ -639,7 +639,7 @@ var/datum/controller/subsystem/ticker/SSticker cinematic = new /obj/screen{ icon = 'icons/effects/station_explosion.dmi'; icon_state = "station_intact"; - layer = CINEMA_LAYER; + layer = HUD_ABOVE_ITEM_LAYER; mouse_opacity = MOUSE_OPACITY_TRANSPARENT; screen_loc = "1,0" } diff --git a/code/controllers/subsystems/zcopy.dm b/code/controllers/subsystems/zcopy.dm index 3670eea3209..ba0081f6e05 100644 --- a/code/controllers/subsystems/zcopy.dm +++ b/code/controllers/subsystems/zcopy.dm @@ -16,13 +16,19 @@ SUBSYSTEM_DEF(zcopy) var/multiqueue_skips_turf = 0 var/multiqueue_skips_object = 0 + // Caches for fixup. + var/list/fixup_cache = list() + var/list/fixup_known_good = list() + + // Fixup stats. + var/fixup_miss = 0 + var/fixup_noop = 0 + var/fixup_hit = 0 + // Highest Z level in a given Z-group for absolute layering. // zstm[zlev] = group_max var/list/zlev_maximums = list() -/datum/controller/subsystem/zcopy/New() - NEW_SS_GLOBAL(SSzcopy) - // for admin proc-call /datum/controller/subsystem/zcopy/proc/update_all() can_fire = FALSE @@ -90,6 +96,10 @@ SUBSYSTEM_DEF(zcopy) Skips: \ Turfs [multiqueue_skips_turf] \ Objects [multiqueue_skips_object]\ + Fixups: \ + Hits [fixup_hit] \ + Miss [fixup_miss]\ + No Operation [fixup_noop]\ " return ..() @@ -159,20 +169,14 @@ SUBSYSTEM_DEF(zcopy) // Z-Turf on the bottom-most level, just fake-copy space. // If this is ever true, that turf should always pass this condition, so don't bother cleaning up beyond the Destroy() hook. if (!T.below) // Z-turf on the bottom-most level, just fake-copy space. - if (T.z_flags & ZM_MIMIC_OVERWRITE) - T.appearance = SSskybox.space_appearance_cache[(((T.x + T.y) ^ ~(T.x * T.y) + T.z) % 25) + 1] - T.name = initial(T.name) - T.desc = initial(T.desc) - T.gender = initial(T.gender) + flush_z_state(T) + if(T.z_flags & ZM_MIMIC_BASETURF) + simple_appearance_copy(T, get_base_turf_by_area(T), OPENTURF_MAX_PLANE) else - // Some openturfs have icons, so we can't overwrite their appearance. - if (!T.mimic_underlay) - T.mimic_underlay = new(T) - var/atom/movable/openspace/turf_proxy/TO = T.mimic_underlay - TO.appearance = SSskybox.space_appearance_cache[(((T.x + T.y) ^ ~(T.x * T.y) + T.z) % 25) + 1] - TO.name = T.name - TO.gender = T.gender // Need to grab this too so PLURAL works properly in examine. - TO.mouse_opacity = initial(TO.mouse_opacity) + simple_appearance_copy(T, SSskybox.space_appearance_cache[(((T.x + T.y) ^ ~(T.x * T.y) + T.z) % 25) + 1]) + + T.z_generation += 1 + T.z_queued -= 1 if (no_mc_tick) CHECK_TICK @@ -197,10 +201,32 @@ SUBSYSTEM_DEF(zcopy) var/t_target = OPENTURF_MAX_PLANE - turf_depth // This is where the turf (but not the copied atoms) gets put. + + // Turf is set to mimic baseturf, handle that and bail. + if (T.z_flags & ZM_MIMIC_BASETURF) + flush_z_state(T) + simple_appearance_copy(T, get_base_turf_by_area(T), t_target) + + if (T.above) + T.above.update_mimic() + + T.z_queued -= 1 + + if (no_mc_tick) + CHECK_TICK + else if (MC_TICK_CHECK) + break + continue + + // If we previously were MZ_MIMIC_BASETURF, there might be an orphaned proxy. + else if (T.mimic_underlay) + QDEL_NULL(T.mimic_underlay) + // Handle space parallax & starlight. if (T.below.z_eventually_space) T.z_eventually_space = TRUE - t_target = PLANE_SPACE_BACKGROUND + if ((T.below.z_flags & ZM_MIMIC_OVERWRITE) || T.below.type == /turf/space) + t_target = SPACE_PLANE if (T.z_flags & ZM_MIMIC_OVERWRITE) // This openturf doesn't care about its icon, so we can just overwrite it. @@ -245,7 +271,7 @@ SUBSYSTEM_DEF(zcopy) // Add everything below us to the update queue. for (var/thing in T.below) var/atom/movable/object = thing - if (QDELETED(object) || object.no_z_overlay || object.loc != T.below || object.invisibility == INVISIBILITY_ABSTRACT) + if (QDELETED(object) || (object.z_flags & ZMM_IGNORE) || object.loc != T.below || object.invisibility == INVISIBILITY_ABSTRACT) // Don't queue deleted stuff, stuff that's not visible, blacklisted stuff, or stuff that's centered on another tile but intersects ours. continue @@ -261,18 +287,24 @@ SUBSYSTEM_DEF(zcopy) var/override_depth var/original_type = object.type var/original_z = object.z + var/have_performed_fixup = FALSE + switch (object.type) if (/atom/movable/openspace/mimic) var/atom/movable/openspace/mimic/OOO = object original_type = OOO.mimiced_type override_depth = OOO.override_depth original_z = OOO.original_z + have_performed_fixup = OOO.have_performed_fixup if (/atom/movable/openspace/turf_proxy, /atom/movable/openspace/turf_mimic) // If we're a turf overlay (the mimic for a non-OVERWRITE turf), we need to make sure copies of us respect space parallax too if (T.z_eventually_space) // Yes, this is an awful hack; I don't want to add yet another override_* var. - override_depth = OPENTURF_MAX_PLANE - PLANE_SPACE_BACKGROUND + override_depth = OPENTURF_MAX_PLANE - SPACE_PLANE + + if (/atom/movable/openspace/turf_mimic) + original_z += 1 var/atom/movable/openspace/mimic/OO = object.bound_overlay @@ -292,6 +324,7 @@ SUBSYSTEM_DEF(zcopy) OO.mimiced_type = original_type OO.override_depth = override_depth OO.original_z = original_z + OO.have_performed_fixup ||= have_performed_fixup // Multi-queue to maintain ordering of updates to these // queueing it multiple times will result in only the most recent @@ -351,6 +384,7 @@ SUBSYSTEM_DEF(zcopy) OO.set_dir(OO.associated_atom.dir) OO.appearance = OO.associated_atom + OO.z_flags = OO.associated_atom.z_flags OO.plane = OPENTURF_MAX_PLANE - OO.depth OO.opacity = FALSE @@ -359,6 +393,13 @@ SUBSYSTEM_DEF(zcopy) if (OO.bound_overlay) // If we have a bound overlay, queue it too. OO.update_above() + // If an atom has explicit plane sets on its overlays/underlays, we need to replace the appearance so they can be mangled to work with our planing. + if (OO.z_flags & ZMM_MANGLE_PLANES) + var/new_appearance = fixup_appearance_planes(OO.appearance) + if (new_appearance) + OO.appearance = new_appearance + OO.have_performed_fixup = TRUE + if (no_mc_tick) CHECK_TICK else if (MC_TICK_CHECK) @@ -368,11 +409,132 @@ SUBSYSTEM_DEF(zcopy) curr_ov.Cut(1, qo_idex) qo_idex = 1 +/datum/controller/subsystem/zcopy/proc/flush_z_state(turf/T) + if (T.below) // Z-Mimic turfs aren't necessarily above another turf. + if (T.below.mimic_above_copy) + QDEL_NULL(T.below.mimic_above_copy) + if (T.below.mimic_proxy) + QDEL_NULL(T.below.mimic_proxy) + QDEL_NULL(T.mimic_underlay) + for (var/atom/movable/openspace/mimic/OO in T) + qdel(OO) + +/datum/controller/subsystem/zcopy/proc/simple_appearance_copy(turf/T, new_appearance, target_plane) + if (T.z_flags & ZM_MIMIC_OVERWRITE) + T.appearance = new_appearance + T.name = initial(T.name) + T.desc = initial(T.desc) + T.gender = initial(T.gender) + if (T.plane == 0 && target_plane) + T.plane = target_plane + else + // Some openturfs have icons, so we can't overwrite their appearance. + if (!T.mimic_underlay) + T.mimic_underlay = new(T) + var/atom/movable/openspace/turf_proxy/TO = T.mimic_underlay + TO.appearance = new_appearance + TO.name = T.name + TO.gender = T.gender // Need to grab this too so PLURAL works properly in examine. + TO.mouse_opacity = initial(TO.mouse_opacity) + if (TO.plane == 0 && target_plane) + TO.plane = target_plane + +/// Generate a new appearance from `appearance` with planes mangled to work with Z-Mimic. Do not pass a depth. +/datum/controller/subsystem/zcopy/proc/fixup_appearance_planes(appearance, depth = 0) + + // Adding this to guard against a reported runtime - supposed to be impossible, so cause is unclear. + if(!appearance) + return null + + if (fixup_known_good[appearance]) + fixup_hit += 1 + return null + if (fixup_cache[appearance]) + fixup_hit += 1 + return fixup_cache[appearance] + + // If you have more than 4 layers of overlays within overlays, I dunno what to say. + if (depth > 4) + var/icon_name = "[appearance:icon]" + WARNING("Fixup of appearance with icon [icon_name || ""] exceeded maximum recursion limit, bailing") + return null + + var/plane_needs_fix = FALSE + + // Don't fixup the root object's plane. + if (depth > 0) + switch (appearance:plane) + if (DEFAULT_PLANE, FLOAT_PLANE) + plane_needs_fix = FALSE //For lint + else + plane_needs_fix = TRUE + + // Scan & fix overlays + var/list/fixed_overlays + if (appearance:overlays:len) + var/mutated = FALSE + var/fixed_appearance + for (var/i in 1 to appearance:overlays:len) + if ((fixed_appearance = .(appearance:overlays[i], depth + 1))) + mutated = TRUE + if (!fixed_overlays) + fixed_overlays = new( length(appearance:overlays)) + fixed_overlays[i] = fixed_appearance + + if (mutated) + for (var/i in 1 to length(fixed_overlays)) + if (fixed_overlays[i] == null) + fixed_overlays[i] = appearance:overlays[i] + + // Scan & fix underlays + var/list/fixed_underlays + if (appearance:underlays:len) + var/mutated = FALSE + var/fixed_appearance + for (var/i in 1 to appearance:underlays:len) + if ((fixed_appearance = .(appearance:underlays[i], depth + 1))) + mutated = TRUE + if (!fixed_underlays) + fixed_underlays = new( length(appearance:underlays)) + fixed_underlays[i] = fixed_appearance + + if (mutated) + for (var/i in 1 to length(fixed_overlays)) + if (fixed_underlays[i] == null) + fixed_underlays[i] = appearance:underlays[i] + + // If we did nothing (no violations), don't bother creating a new appearance + if (!plane_needs_fix && !fixed_overlays && !fixed_underlays) + fixup_noop += 1 + fixup_known_good[appearance] = TRUE + return null + + fixup_miss += 1 + + var/mutable_appearance/MA = new(appearance) + if (plane_needs_fix) + MA.plane = depth == 0 ? DEFAULT_PLANE : FLOAT_PLANE + MA.layer = FLY_LAYER // probably fine + + if (fixed_overlays) + MA.overlays = fixed_overlays + + if (fixed_underlays) + MA.underlays = fixed_underlays + + fixup_cache[appearance] = MA.appearance + + return MA + #define FMT_DEPTH(X) (X == null ? "(null)" : X) // This is a dummy object used so overlays can be shown in the analyzer. /atom/movable/openspace/debug +/atom/movable/openspace/debug/turf + var/turf/parent + var/computed_depth + /client/proc/analyze_openturf(turf/T) set name = "Analyze Openturf" set desc = "Show the layering of an openturf and everything it's mimicking." @@ -381,6 +543,17 @@ SUBSYSTEM_DEF(zcopy) if (!check_rights(R_DEBUG)) return + var/real_update_count = 0 + var/claimed_update_count = T.z_queued + var/list/tq = SSzcopy.queued_turfs.Copy() + for (var/turf/Tu in tq) + if (Tu == T) + real_update_count += 1 + + CHECK_TICK + + var/list/temp_objects = list() + var/is_above_space = T.is_above_space() var/list/out = list( "", @@ -395,10 +568,26 @@ SUBSYSTEM_DEF(zcopy) "Below: [!T.below ? "(nothing)" : "[T.below] at [T.below.x],[T.below.y],[T.below.z]"]", "Depth: [FMT_DEPTH(T.z_depth)] [T.z_depth == OPENTURF_MAX_DEPTH ? "(max)" : ""]", "Generation: [T.z_generation]", + "Update count: Claimed [claimed_update_count], Actual [real_update_count] - [claimed_update_count == real_update_count ? "OK" : "MISMATCH"]", "