diff --git a/.github/workflows/autowiki.yml b/.github/workflows/autowiki.yml index c6f85bade91d..10d3cea1e676 100644 --- a/.github/workflows/autowiki.yml +++ b/.github/workflows/autowiki.yml @@ -43,7 +43,7 @@ jobs: sudo apt update || true sudo apt install -o APT::Immediate-configure=false libssl-dev:i386 bash tools/ci/install_rust_g.sh - + - name: Cache dependencies if: steps.secrets_set.outputs.SECRETS_ENABLED uses: actions/cache@v3 diff --git a/.github/workflows/ci_suite.yml b/.github/workflows/ci_suite.yml index 915b6021e98c..33af3581a22b 100644 --- a/.github/workflows/ci_suite.yml +++ b/.github/workflows/ci_suite.yml @@ -3,17 +3,34 @@ on: push: branches: - master + - "project/**" pull_request: branches: - master + - "project/**" merge_group: branches: - master + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: + start_gate: + if: ( !contains(github.event.head_commit.message, '[ci skip]') ) + name: Start Gate + runs-on: ubuntu-latest + steps: + - name: Mandatory Empty Step + run: exit 0 + run_linters: - if: ${{ ! contains(github.event.head_commit.message, '[ci skip]') }} name: Run Linters + needs: start_gate runs-on: ubuntu-22.04 + timeout-minutes: 5 + steps: - uses: actions/checkout@v3 with: @@ -53,40 +70,62 @@ jobs: run: | pip3 install setuptools bash tools/ci/install_node.sh - bash tools/ci/install_spaceman_dmm.sh dreamchecker cargo install ripgrep --features pcre2 tools/bootstrap/python -c '' - - name: Run Linters + - name: Give Linters A Go + id: linter-setup + run: exit 0 + - name: Run Grep Checks + if: steps.linter-setup.conclusion == 'success' && !cancelled() + run: bash tools/ci/check_grep.sh + - name: Run DreamChecker + if: steps.linter-setup.conclusion == 'success' && !cancelled() + run: ~/dreamchecker 2>&1 | bash tools/ci/annotate_dm.sh + - name: Run Map Checks + if: steps.linter-setup.conclusion == 'success' && !cancelled() run: | - tools/bootstrap/python -m tools.maplint.source --github - tools/build/build --ci lint tgui-test - bash tools/ci/check_filedirs.sh shiptest.dme - bash tools/ci/check_changelogs.sh - bash tools/ci/check_misc.sh - bash tools/ci/check_grep.sh - tools/bootstrap/python -m dmi.test tools/bootstrap/python -m mapmerge2.dmm_test - ~/dreamchecker > ${GITHUB_WORKSPACE}/output-annotations.txt 2>&1 - - - name: Annotate Lints - if: always() - uses: yogstation13/DreamAnnotate@v2 - with: - outputFile: output-annotations.txt - - - name: Run Check Regex + tools/bootstrap/python -m tools.maplint.source + - name: Run DMI Tests + if: steps.linter-setup.conclusion == 'success' && !cancelled() + run: tools/bootstrap/python -m dmi.test + - name: Check File Directories + if: steps.linter-setup.conclusion == 'success' && !cancelled() + run: bash tools/ci/check_filedirs.sh shiptest.dme + - name: Check Changelogs + if: steps.linter-setup.conclusion == 'success' && !cancelled() + run: bash tools/ci/check_changelogs.sh + - name: Check Miscellaneous Files + if: steps.linter-setup.conclusion == 'success' && !cancelled() + run: bash tools/ci/check_misc.sh + - name: Run TGUI Checks + if: steps.linter-setup.conclusion == 'success' && !cancelled() + run: tools/build/build --ci lint tgui-test + - name: Run Regex Checks + if: steps.linter-setup.conclusion == 'success' && !cancelled() run: | tools/bootstrap/python -m ci.check_regex --log-changes-only --github-actions + cat check_regex_output.txt + + - name: Install OpenDream + uses: robinraju/release-downloader@v1.9 + with: + repository: "OpenDreamProject/OpenDream" + tag: "latest" + fileName: "DMCompiler_linux-x64.tar.gz" + extract: true - - name: Annotate Regex Matches + - name: Run OpenDream Linter run: | - cat check_regex_output.txt + ./DMCompiler_linux-x64/DMCompiler shiptest.dme --suppress-unimplemented --define=CIBUILDING | bash tools/ci/annotate_od.sh compile_all_maps: - if: ${{ ! contains(github.event.head_commit.message, '[ci skip]') }} name: Compile Maps + needs: start_gate runs-on: ubuntu-latest + timeout-minutes: 5 + steps: - uses: actions/checkout@v3 @@ -106,39 +145,41 @@ jobs: tools/build/build --ci dm -DCIBUILDING -DCITESTING -DALL_MAPS -DFULL_INIT run_all_tests: - if: ${{ ! contains(github.event.head_commit.message, '[ci skip]') }} name: Integration Tests + needs: start_gate strategy: fail-fast: false matrix: - arg: [ - "BASIC_TESTS", - "CREATE_AND_DESTROY_TEST", - "PLANET_GEN_TEST", - "RUIN_PLACEMENT_TEST", - "SHIP_PLACEMENT_TEST" - ] + arg: + [ + "BASIC_TESTS", + "CREATE_AND_DESTROY_TEST", + "PLANET_GEN_TEST", + "RUIN_PLACEMENT_TEST", + "SHIP_PLACEMENT_TEST", + ] uses: ./.github/workflows/run_integration_tests.yml with: arg: ${{ matrix.arg }} -# run_alternate_tests: -# if: "!contains(github.event.head_commit.message, '[ci skip]')" -# name: Alternate Tests -# strategy: -# fail-fast: false -# matrix: -# major: [515] -# minor: [1614] -# uses: ./.github/workflows/run_integration_tests.yml -# with: -# major: ${{ matrix.major }} -# minor: ${{ matrix.minor }} + # run_alternate_tests: + # if: "!contains(github.event.head_commit.message, '[ci skip]')" + # name: Alternate Tests + # strategy: + # fail-fast: false + # matrix: + # major: [515] + # minor: [1614] + # uses: ./.github/workflows/run_integration_tests.yml + # with: + # major: ${{ matrix.major }} + # minor: ${{ matrix.minor }} test_windows: - if: ${{ ! contains(github.event.head_commit.message, '[ci skip]') }} name: Windows Build + needs: start_gate runs-on: windows-latest + timeout-minutes: 5 steps: - uses: actions/checkout@v3 @@ -163,7 +204,18 @@ jobs: bash tools/deploy.sh ./deploy - name: Deploy artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: deploy path: deploy + + completion_gate: # Serves as a non-moving target for branch rulesets + if: always() && !cancelled() + name: Completion Gate + needs: [test_windows, compile_all_maps, run_linters, run_all_tests] + runs-on: ubuntu-latest + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/codeowner_reviews.yml b/.github/workflows/codeowner_reviews.yml index 753f575f90d7..6799c5d14b37 100644 --- a/.github/workflows/codeowner_reviews.yml +++ b/.github/workflows/codeowner_reviews.yml @@ -6,6 +6,7 @@ on: pull_request_target jobs: assign-users: runs-on: ubuntu-latest + timeout-minutes: 5 steps: # Checks-out your repository under $GITHUB_WORKSPACE, so the job can access it diff --git a/.github/workflows/rerun_flaky_tests.yml b/.github/workflows/rerun_flaky_tests.yml index e3cbda05749b..b705735a0dfb 100644 --- a/.github/workflows/rerun_flaky_tests.yml +++ b/.github/workflows/rerun_flaky_tests.yml @@ -3,7 +3,7 @@ on: workflow_run: workflows: [Checks] types: - - completed + - completed permissions: actions: write @@ -15,23 +15,23 @@ jobs: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt == 1 }} steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Rerun flaky tests - uses: actions/github-script@v6 - with: - script: | - const { rerunFlakyTests } = await import('${{ github.workspace }}/tools/pull_request_hooks/rerunFlakyTests.js') - await rerunFlakyTests({ github, context }) + - name: Checkout + uses: actions/checkout@v3 + - name: Rerun flaky tests + uses: actions/github-script@v6 + with: + script: | + const { rerunFlakyTests } = await import('${{ github.workspace }}/tools/pull_request_hooks/rerunFlakyTests.js') + await rerunFlakyTests({ github, context }) report_flaky_tests: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.run_attempt == 2 }} steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Report flaky tests - uses: actions/github-script@v6 - with: - script: | - const { reportFlakyTests } = await import('${{ github.workspace }}/tools/pull_request_hooks/rerunFlakyTests.js') - await reportFlakyTests({ github, context }) + - name: Checkout + uses: actions/checkout@v3 + - name: Report flaky tests + uses: actions/github-script@v6 + with: + script: | + const { reportFlakyTests } = await import('${{ github.workspace }}/tools/pull_request_hooks/rerunFlakyTests.js') + await reportFlakyTests({ github, context }) diff --git a/.github/workflows/run_integration_tests.yml b/.github/workflows/run_integration_tests.yml index 9c83d6ab013d..699151fe6f99 100644 --- a/.github/workflows/run_integration_tests.yml +++ b/.github/workflows/run_integration_tests.yml @@ -14,9 +14,11 @@ on: required: false default: ALL_TESTS type: string + jobs: run_integration_tests: runs-on: ubuntu-latest + timeout-minutes: 15 services: mysql: image: mysql:latest diff --git a/.github/workflows/tgs_test.yml b/.github/workflows/tgs_test.yml index a92b6cac76a3..4b7853aa77cf 100644 --- a/.github/workflows/tgs_test.yml +++ b/.github/workflows/tgs_test.yml @@ -3,7 +3,9 @@ on: push: branches: - master + - 'project/**' - 'gh-readonly-queue/master/**' + - 'gh-readonly-queue/project/**' paths: - '.tgs.yml' - '.github/workflows/tgs_test.yml' @@ -12,11 +14,13 @@ on: - 'code/__DEFINES/tgs.dm' - 'code/game/world.dm' - 'code/modules/tgs/**' + - 'tools/bootstrap/**' - 'tools/tgs_scripts/**' - 'tools/tgs_test/**' pull_request: branches: - master + - 'project/**' paths: - '.tgs.yml' - '.github/workflows/tgs_test.yml' @@ -25,6 +29,7 @@ on: - 'code/__DEFINES/tgs.dm' - 'code/game/world.dm' - 'code/modules/tgs/**' + - 'tools/bootstrap/**' - 'tools/tgs_scripts/**' - 'tools/tgs_test/**' merge_group: @@ -54,12 +59,12 @@ jobs: - 5000:5000 #Can't use env here for some reason steps: - name: Setup dotnet - uses: actions/setup-dotnet@v2 + uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x - name: Checkout Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Test TGS Integration run: dotnet run -c Release --project tools/tgs_test ${{ github.repository }} /tgs_instances/tgstation ${{ env.TGS_API_PORT }} ${{ github.event.pull_request.head.sha || github.sha }} ${{ secrets.GITHUB_TOKEN }} ${{ env.PR_NUMBER }} diff --git a/.gitignore b/.gitignore index 94713bc82e1c..196353141536 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ *.lk *.int *.backup +/shiptest.json ### https://raw.github.com/github/gitignore/cc542de017c606138a87ee4880e5f06b3a306def/Global/Linux.gitignore *~ diff --git a/__odlint.dm b/__odlint.dm new file mode 100644 index 000000000000..b7c120514a1d --- /dev/null +++ b/__odlint.dm @@ -0,0 +1,10 @@ +// This file is included right at the start of the DME. +// Its purpose is to enable multiple lints (pragmas) that are supported by OpenDream to better validate the codebase +// These are essentially nitpicks the DM compiler should pick up on but doesnt + +#if !defined(SPACEMAN_DMM) && defined(OPENDREAM) +// This is in a separate file as a hack to avoid SpacemanDMM +// evaluating the #pragma lines, even if its outside a block it cares about +// (Also so people can code-own it. Shoutout to AA) +#include "tools/ci/od_lints.dm" +#endif diff --git a/check_regex.yaml b/check_regex.yaml index a9ed6b699d7f..95d3738da5dc 100644 --- a/check_regex.yaml +++ b/check_regex.yaml @@ -57,7 +57,7 @@ standards: - no_more: [ - 34, + 32, "indentions inside defines", '^(\s*)#define (\w*)( {2,}| ?\t+)(?!(\/\/|\/\*))', ] diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 68ef8b65b127..384b7fcc46c7 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -447,3 +447,7 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE #define ROUND_END_NOT_DELAYED 0 #define ROUND_END_DELAYED 1 #define ROUND_END_TGS 2 + +/// A null statement to guard against EmptyBlock lint without necessitating the use of pass() +/// Used to avoid proc-call overhead. But use sparingly. Probably pointless in most places. +#define EMPTY_BLOCK_GUARD ; diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 1ab889987695..16de5230a2bb 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -10,14 +10,22 @@ #define WRITE_LOG(log, text) rustg_log_write(log, text, "true") #define WRITE_LOG_NO_FORMAT(log, text) rustg_log_write(log, text, "false") -//print a warning message to world.log +#ifdef UNIT_TESTS +#define WARNING(MSG) log_world("::warning file=[__FILE__],line=[__LINE__]::[MSG] src: [UNLINT(src)] usr: [usr].") +#else #define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [UNLINT(src)] usr: [usr].") +#endif +/// Print a warning message to world.log /proc/warning(msg) msg = "## WARNING: [msg]" log_world(msg) -//not an error or a warning, but worth to mention on the world log, just in case. +#ifdef UNIT_TESTS +#define NOTICE(MSG) log_world("::notice file=[__FILE__],line=[__LINE__]::[MSG] src: [UNLINT(src)] usr: [usr].") +#else #define NOTICE(MSG) notice(MSG) +#endif +///not an error or a warning, but worth to mention on the world log, just in case. /proc/notice(msg) msg = "## NOTICE: [msg]" log_world(msg) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 452a522870a0..3770b4e847ad 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -94,8 +94,8 @@ return "northwest" if(SOUTHWEST) return "southwest" - else - return + + return NONE //Turns text into proper directions /proc/text2dir(direction) @@ -116,8 +116,8 @@ return SOUTHEAST if("SOUTHWEST") return SOUTHWEST - else - return + + return NONE //Converts an angle (degrees) into an ss13 direction GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH,SOUTHWEST,WEST,NORTHWEST)) diff --git a/code/_compile_options.dm b/code/_compile_options.dm index ee7638ea853d..9ff2cbe896ae 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -63,7 +63,7 @@ #warn compiling in TESTING mode. testing() debug messages will be visible. #endif -#ifdef CIBUILDING +#if defined(CIBUILDING) && !defined(OPENDREAM) #define UNIT_TESTS #endif @@ -90,3 +90,16 @@ // A reasonable number of maximum overlays an object needs // If you think you need more, rethink it #define MAX_ATOM_OVERLAYS 100 + +#if defined(OPENDREAM) + #if !defined(CIBUILDING) + #warn You are building with OpenDream. Remember to build TGUI manually. + #warn You can do this by running tgui-build.cmd from the bin directory. + #endif +#else + #if !defined(CBT) && !defined(SPACEMAN_DMM) + #warn Building with Dream Maker is no longer supported and will result in errors. + #warn In order to build, run BUILD.cmd in the root directory. + #warn Consider switching to VSCode editor instead, where you can press Ctrl+Shift+B to build. + #endif +#endif diff --git a/code/controllers/subsystem/acid.dm b/code/controllers/subsystem/acid.dm index 0ea8967e263c..efbc5e7d260e 100644 --- a/code/controllers/subsystem/acid.dm +++ b/code/controllers/subsystem/acid.dm @@ -33,8 +33,7 @@ SUBSYSTEM_DEF(acid) return continue - if(O.acid_level && O.acid_processing()) - else + if(!O.acid_level || !O.acid_processing()) O.update_appearance() processing -= O diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 6c15d00869f2..695b6519f9c7 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -364,17 +364,17 @@ */ /datum/proc/GetExactComponent(datum/component/c_type) RETURN_TYPE(c_type) - if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED || initial(c_type.dupe_mode) == COMPONENT_DUPE_SELECTIVE) + var/initial_type_mode = initial(c_type.dupe_mode) + if(initial_type_mode == COMPONENT_DUPE_ALLOWED || initial_type_mode == COMPONENT_DUPE_SELECTIVE) stack_trace("GetComponent was called to get a component of which multiple copies could be on an object. This can easily break and should be changed. Type: \[[c_type]\]") - var/list/dc = datum_components - if(!dc) + var/list/all_components = datum_components + if(!all_components) return null - var/datum/component/C = dc[c_type] - if(C) - if(length(C)) - C = C[1] - if(C.type == c_type) - return C + var/datum/component/potential_component + if(length(all_components)) + potential_component = all_components[c_type] + if(potential_component?.type == c_type) + return potential_component return null /** diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index 729c50f2349f..f5129fb761b1 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -153,9 +153,9 @@ Behavior that's still missing from this component that original food items had t SIGNAL_HANDLER if(!(food_flags & FOOD_IN_CONTAINER)) - switch (bitecount) - if (0) - return + switch(bitecount) + if(0) + EMPTY_BLOCK_GUARD if(1) examine_list += "[parent] was bitten by someone!" if(2,3) diff --git a/code/datums/components/radioactive.dm b/code/datums/components/radioactive.dm index 9306f6aae899..26d98b99e80e 100644 --- a/code/datums/components/radioactive.dm +++ b/code/datums/components/radioactive.dm @@ -55,7 +55,6 @@ var/filter = master.get_filter("rad_glow") if(filter) animate(filter, alpha = 110, time = 15, loop = -1) - animate(alpha = 40, time = 25) /datum/component/radioactive/InheritComponent(datum/component/C, i_am_original, _strength, _source, _half_life, _can_contaminate) if(!i_am_original) diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 17c5dc2ef39c..9bd38b62c9fa 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -168,7 +168,6 @@ else dat += "
[bdat]" - else else dat += "{Log In}" var/datum/browser/popup = new(user, "med_rec", "Medical Records Console", 600, 400) @@ -375,7 +374,6 @@ if(istype(active1.fields["photo_side"], /obj/item/photo)) var/obj/item/photo/P = active1.fields["photo_side"] P.show(usr) - else else if(href_list["p_stat"]) if(active1) @@ -488,16 +486,12 @@ for(var/datum/data/record/R in GLOB.data_core.medical) if((lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"]))) active2 = R - else - //Foreach continue //goto(3229) if(!(active2)) temp = text("Could not locate record [].", sanitize(t1)) else for(var/datum/data/record/E in GLOB.data_core.general) if((E.fields["name"] == active2.fields["name"] || E.fields["id"] == active2.fields["id"])) active1 = E - else - //Foreach continue //goto(3334) screen = 4 else if(href_list["print_p"]) diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 37759d04b13e..cdfad1556187 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -228,7 +228,6 @@ dat += "New Security Record

" dat += "Delete Record (ALL)
Print Record
Print Wanted Poster
Print Missing Persons Poster
Back

" dat += "{Log Out}" - else else dat += "{Log In}" var/datum/browser/popup = new(user, "secure_rec", "Security Records Console", 600, 400) diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index d703ae86ca7d..cd6fafd4dbef 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -235,7 +235,7 @@ . = TRUE if("select_stencil") var/stencil = params["item"] - if(stencil in all_drawables + randoms) + if(stencil in (all_drawables + randoms)) drawtype = stencil . = TRUE text_buffer = "" @@ -320,7 +320,7 @@ temp = "symbol" else if(drawing in drawings) temp = "drawing" - else if(drawing in graffiti|oriented) + else if(drawing in (graffiti|oriented)) temp = "graffiti" var/graf_rot diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index e259e56ccd0e..70871e2ddc77 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -410,7 +410,7 @@ GLOBAL_LIST_EMPTY(PDAs) //BASIC FUNCTIONS=================================== if("Refresh")//Refresh, goes to the end of the proc. - + EMPTY_BLOCK_GUARD if("Return")//Return if(mode<=9) mode = 0 diff --git a/code/game/objects/items/devices/mines.dm b/code/game/objects/items/devices/mines.dm index 6319cc1a638d..4f2169350d79 100644 --- a/code/game/objects/items/devices/mines.dm +++ b/code/game/objects/items/devices/mines.dm @@ -469,7 +469,7 @@ shrapnel_magnitude = 4 /obj/item/mine/pressure/explosive/fire/mine_effect(mob/victim) - if(victim && victim.is_holding(src))//in case it's been picked up + if(victim?.is_holding(src))//in case it's been picked up for(var/turf/T in view(4,victim)) T.IgniteTurf(15) new /obj/effect/hotspot(T) diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm index a08b1398aad8..0882034b165a 100644 --- a/code/game/objects/items/pet_carrier.dm +++ b/code/game/objects/items/pet_carrier.dm @@ -31,13 +31,13 @@ /obj/item/pet_carrier/Exited(atom/movable/occupant) . = ..() - if(occupant in occupants && isliving(occupant)) + if((occupant in occupants) && isliving(occupant)) var/mob/living/L = occupant occupants -= occupant occupant_weight -= L.mob_size /obj/item/pet_carrier/handle_atom_del(atom/A) - if(A in occupants && isliving(A)) + if((A in occupants) && isliving(A)) var/mob/living/L = A occupants -= L occupant_weight -= L.mob_size @@ -178,7 +178,7 @@ add_occupant(target) /obj/item/pet_carrier/proc/add_occupant(mob/living/occupant) - if(occupant in occupants || !istype(occupant)) + if((occupant in occupants) || !istype(occupant)) return occupant.forceMove(src) occupants += occupant diff --git a/code/game/objects/items/storage/guncases.dm b/code/game/objects/items/storage/guncases.dm index c846dd36b050..760a84f4e3aa 100644 --- a/code/game/objects/items/storage/guncases.dm +++ b/code/game/objects/items/storage/guncases.dm @@ -3,6 +3,8 @@ desc = "A large box designed for holding firearms and magazines safely." icon = 'icons/obj/guncase.dmi' icon_state = "guncase" + lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' item_state = "infiltrator_case" force = 12 throwforce = 12 diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index e0e115b81d01..363a83d965a3 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -24,11 +24,8 @@ /obj/proc/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir, armour_penetration = 0) if(damage_flag == "melee" && damage_amount < damage_deflection) return 0 - switch(damage_type) - if(BRUTE) - if(BURN) - else - return 0 + if(damage_type != BRUTE && damage_type != BURN) + return 0 var/armor_protection = 0 if(damage_flag) armor_protection = armor.getRating(damage_flag) diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index 089b6f8f792c..fa4fe485015d 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -50,7 +50,7 @@ new /obj/item/clothing/mask/breath(src) if ("nothing") - // doot + EMPTY_BLOCK_GUARD // teehee if ("delete") diff --git a/code/game/objects/structures/crateshelf.dm b/code/game/objects/structures/crateshelf.dm index 3b1387f5490b..0bf1cfa64c4f 100644 --- a/code/game/objects/structures/crateshelf.dm +++ b/code/game/objects/structures/crateshelf.dm @@ -123,6 +123,7 @@ crate.SpinAnimation(rand(4,7), 1) // Spin the crates around a little as they fall. Randomness is applied so it doesn't look weird. switch(pick(1, 1, 1, 1, 2, 2, 3)) // Randomly pick whether to do nothing, open the crate, or break it open. if(1) // Believe it or not, this does nothing. + EMPTY_BLOCK_GUARD if(2) // Open the crate! if(crate.open()) // Break some open, cause a little chaos. crate.visible_message(span_warning("[crate]'s lid falls open!")) diff --git a/code/modules/admin/permissionedit.dm b/code/modules/admin/permissionedit.dm index 5e354e0f6550..0046d353dc5c 100644 --- a/code/modules/admin/permissionedit.dm +++ b/code/modules/admin/permissionedit.dm @@ -214,7 +214,7 @@ . = ckey(admin_key) if(!.) return FALSE - if(!admin_ckey && (. in GLOB.admin_datums+GLOB.deadmins)) + if(!admin_ckey && (. in (GLOB.admin_datums+GLOB.deadmins))) to_chat(usr, "[admin_key] is already an admin.", confidential = TRUE) return FALSE if(use_db) diff --git a/code/modules/admin/view_variables/debug_variables.dm b/code/modules/admin/view_variables/debug_variables.dm index 68d2b4c2ec64..60528592f4e0 100644 --- a/code/modules/admin/view_variables/debug_variables.dm +++ b/code/modules/admin/view_variables/debug_variables.dm @@ -1,23 +1,24 @@ #define VV_HTML_ENCODE(thing) (sanitize ? html_encode(thing) : thing) /// Get displayed variable in VV variable list -/proc/debug_variable(name, value, level, datum/D, sanitize = TRUE) //if D is a list, name will be index, and value will be assoc value. +/proc/debug_variable(name, value, level, datum/owner, sanitize = TRUE) //if D is a list, name will be index, and value will be assoc value. var/header - if(D) - if(islist(D)) + if(owner) + if(islist(owner)) + var/list/owner_list = owner var/index = name if (value) - name = D[name] //name is really the index until this line + name = owner_list[name] //name is really the index until this line else - value = D[name] - header = "
  • ([VV_HREF_TARGET_1V(D, VV_HK_LIST_EDIT, "E", index)]) ([VV_HREF_TARGET_1V(D, VV_HK_LIST_CHANGE, "C", index)]) ([VV_HREF_TARGET_1V(D, VV_HK_LIST_REMOVE, "-", index)]) " + value = owner_list[name] + header = "
  • ([VV_HREF_TARGET_1V(owner, VV_HK_LIST_EDIT, "E", index)]) ([VV_HREF_TARGET_1V(owner, VV_HK_LIST_CHANGE, "C", index)]) ([VV_HREF_TARGET_1V(owner, VV_HK_LIST_REMOVE, "-", index)]) " else - header = "
  • ([VV_HREF_TARGET_1V(D, VV_HK_BASIC_EDIT, "E", name)]) ([VV_HREF_TARGET_1V(D, VV_HK_BASIC_CHANGE, "C", name)]) ([VV_HREF_TARGET_1V(D, VV_HK_BASIC_MASSEDIT, "M", name)]) " + header = "
  • ([VV_HREF_TARGET_1V(owner, VV_HK_BASIC_EDIT, "E", name)]) ([VV_HREF_TARGET_1V(owner, VV_HK_BASIC_CHANGE, "C", name)]) ([VV_HREF_TARGET_1V(owner, VV_HK_BASIC_MASSEDIT, "M", name)]) " else header = "
  • " var/item var/name_part = VV_HTML_ENCODE(name) - if(level > 0 || islist(D)) //handling keys in assoc lists + if(level > 0 || islist(owner)) //handling keys in assoc lists if(istype(name,/datum)) name_part = "[VV_HTML_ENCODE(name)] [REF(name)]" else if(islist(name)) diff --git a/code/modules/client/loadout/_loadout.dm b/code/modules/client/loadout/_loadout.dm index a0e5d6cab3c3..44c1cff4ffa5 100644 --- a/code/modules/client/loadout/_loadout.dm +++ b/code/modules/client/loadout/_loadout.dm @@ -20,11 +20,11 @@ GLOBAL_LIST_EMPTY(gear_datums) if(G == initial(G.subtype_path)) continue - if(!use_name) - WARNING("Loadout - Missing display name: [G]") + if(!use_name && initial(G.path)) + WARNING("Loadout gear [G] is missing display name") continue if(!initial(G.path) && use_category != "OOC") //OOC category does not contain actual items - WARNING("Loadout - Missing path definition: [G]") + WARNING("Loadout gear [G] is missing path definition") continue if(!GLOB.loadout_categories[use_category]) diff --git a/code/modules/client/loadout/loadout_accessories.dm b/code/modules/client/loadout/loadout_accessories.dm index a8acc1544654..d52c9a8b58fc 100644 --- a/code/modules/client/loadout/loadout_accessories.dm +++ b/code/modules/client/loadout/loadout_accessories.dm @@ -98,6 +98,9 @@ subtype_path = /datum/gear/accessory/mask slot = ITEM_SLOT_MASK +/datum/gear/accessory/mask/bandana + subtype_path = /datum/gear/accessory/mask/bandana + /datum/gear/accessory/mask/bandana/red display_name = "bandana, red" path = /obj/item/clothing/mask/bandana/red diff --git a/code/modules/client/loadout/loadout_hat.dm b/code/modules/client/loadout/loadout_hat.dm index 2f7e59c288b7..f660d35f676a 100644 --- a/code/modules/client/loadout/loadout_hat.dm +++ b/code/modules/client/loadout/loadout_hat.dm @@ -80,6 +80,9 @@ //Soft caps +/datum/gear/hat/softcap + subtype_path = /datum/gear/hat/softcap + /datum/gear/hat/softcap/red display_name = "cap, red" path = /obj/item/clothing/head/soft/red diff --git a/code/modules/client/loadout/loadout_suit.dm b/code/modules/client/loadout/loadout_suit.dm index 1d11857663ad..1edeed63530a 100644 --- a/code/modules/client/loadout/loadout_suit.dm +++ b/code/modules/client/loadout/loadout_suit.dm @@ -88,6 +88,9 @@ path = /obj/item/clothing/suit/toggle/hazard //Suspenders +/datum/gear/suit/suspenders + subtype_path = /datum/gear/suit/suspenders + /datum/gear/suit/suspenders/red display_name = "suspenders, red" path = /obj/item/clothing/suit/toggle/suspenders diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 9954d785cc74..18c9a5374443 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -893,7 +893,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) mutant_category = 0 // end generic adjective - if("wings" in pref_species.default_features && GLOB.r_wings_list.len >1) + if(("wings" in pref_species.default_features) && GLOB.r_wings_list.len >1) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 416fa20df39c..c5d7e6ec98f9 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -184,7 +184,7 @@ . = ..() UnregisterSignal(M, COMSIG_MOB_SAY) -/obj/item/clothing/head/warden/drill/proc/handle_speech(datum/source, mob/speech_args) +/obj/item/clothing/head/warden/drill/proc/handle_speech(datum/source, list/speech_args) var/message = speech_args[SPEECH_MESSAGE] if(message[1] != "*") switch (mode) diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index b2636b02871b..1271717fc537 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -201,7 +201,7 @@ . = ..() UnregisterSignal(M, COMSIG_MOB_SAY) -/obj/item/clothing/head/frenchberet/proc/handle_speech(datum/source, mob/speech_args) +/obj/item/clothing/head/frenchberet/proc/handle_speech(datum/source, list/speech_args) var/message = speech_args[SPEECH_MESSAGE] if(message[1] != "*") message = " [message]" diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm index 982b3804f586..1524a4aa6466 100644 --- a/code/modules/clothing/suits/cloaks.dm +++ b/code/modules/clothing/suits/cloaks.dm @@ -5,7 +5,6 @@ desc = "It's a cape that can be worn around your neck." icon = 'icons/obj/clothing/cloaks.dmi' icon_state = "qmcloak" - item_state = "qmcloak" w_class = WEIGHT_CLASS_SMALL body_parts_covered = CHEST|GROIN|LEGS|ARMS flags_inv = HIDESUITSTORAGE diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index 89cce9c24d64..81e5da317553 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -103,7 +103,7 @@ name = "waistcoat" desc = "For some classy, murderous fun." icon_state = "waistcoat" - item_state = "waistcoat" + item_state = "det_suit" minimize_when_attached = FALSE attachment_slot = null @@ -119,13 +119,11 @@ name = "syndicate maid apron" desc = "Practical? No. Tactical? Also no. Cute? Most definitely yes." icon_state = "maidapronsynd" - item_state = "maidapronsynd" /obj/item/clothing/accessory/maidapron/inteq name = "inteq maid apron" desc = "A 'tactical' apron to protect you from all sorts of spills, from dough to blood!" icon_state = "inteqmaidapron" - item_state = "inteqmaidapron" ////////// //Medals// @@ -408,7 +406,6 @@ name = "shoulder holster" desc = "A holster to carry a handgun and ammo. WARNING: Badasses only." icon_state = "holster" - item_state = "holster" pocket_storage_component_path = /datum/component/storage/concrete/pockets/holster attachment_slot = null diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index ec10f7dfb0f2..90b180587638 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -593,6 +593,7 @@ broh.losebreath++ switch(broh.losebreath) if(-INFINITY to 0) + EMPTY_BLOCK_GUARD if(1 to 2) if(prob(30)) user.visible_message("[broh]'s eyes water as [broh.p_they()] chug the can of [src]!") diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 3ff72083450a..406c59ae0d04 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -433,7 +433,7 @@ mind.active = FALSE //we wish to transfer the key manually mind.original_character_slot_index = client.prefs.default_slot mind.transfer_to(H) //won't transfer key since the mind is not active - mind.set_original_character(H) + H.mind.set_original_character(H) H.name = real_name client.init_verbs() diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 5005930855e4..beb44db426de 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -712,7 +712,7 @@ if(ignite_turfs) T.IgniteTurf(power,flame_color) for(var/mob/living/L in T.contents) - if(L in hit_list || L == source) + if((L in hit_list) || L == source) continue hit_list += L L.adjustFireLoss(20) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index c800acc46786..d1b28067a804 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -452,8 +452,6 @@ else client.eye = client.mob client.perspective = MOB_PERSPECTIVE - else - //Do nothing else //Reset to common defaults: mob if on turf, otherwise current loc if(isturf(loc)) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index db9a8db4ec2c..e8d5f5c508c6 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -147,7 +147,7 @@ if(20) newletter += "[newletter][newletter]" else - // do nothing + EMPTY_BLOCK_GUARD . += "[newletter]" return sanitize(.) @@ -192,7 +192,7 @@ if(5) newletter = "glor" else - // do nothing + EMPTY_BLOCK_GUARD . += newletter return sanitize(.) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index ea8d5fcbfff2..32d91294bc84 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -337,7 +337,7 @@ /// triggered on wield of two handed item /obj/item/gun/proc/on_wield(obj/item/source, mob/user) wielded = TRUE - INVOKE_ASYNC(src, .proc.do_wield, user) + INVOKE_ASYNC(src, PROC_REF(do_wield), user) /obj/item/gun/proc/do_wield(mob/user) user.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/gun, multiplicative_slowdown = wield_slowdown) diff --git a/code/modules/projectiles/guns/ballistic/assault.dm b/code/modules/projectiles/guns/ballistic/assault.dm index 091c1aba92ba..0141667d1ce6 100644 --- a/code/modules/projectiles/guns/ballistic/assault.dm +++ b/code/modules/projectiles/guns/ballistic/assault.dm @@ -230,17 +230,10 @@ return secondary.screwdriver_act(user, attack_obj,) return ..() - -/obj/item/gun/ballistic/automatic/assault/e40/can_shoot() - var/current_firemode = gun_firemodes[firemode_index] - if(current_firemode != FIREMODE_OTHER) - return ..() - return secondary.can_shoot() - /obj/item/gun/ballistic/automatic/assault/e40/on_wield(obj/item/source, mob/user) wielded = TRUE secondary.wielded = TRUE - INVOKE_ASYNC(src, .proc.do_wield, user) + INVOKE_ASYNC(src, PROC_REF(do_wield), user) /obj/item/gun/ballistic/automatic/assault/e40/do_wield(mob/user) . = ..() diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 2c7b664ff3b5..752af51a57e5 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -463,6 +463,7 @@ desc = "A small law enforcement firearm. Originally commissioned by Nanotrasen for their Private Investigation division, it has become extremely popular among independent civilians as a cheap, compact sidearm. Uses .38 Special rounds." fire_sound = 'sound/weapons/gun/revolver/shot_light.ogg' icon_state = "detective" + item_state = "hp_generic" icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi' lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi' righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi' @@ -572,6 +573,7 @@ EMPTY_GUN_HELPER(revolver/viper) mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi' icon_state = "montagne" + item_state = "hp_generic" manufacturer = MANUFACTURER_HUNTERSPRIDE spread_unwielded = 15 recoil = 0 diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 26c796555ebd..30ccb528a4e9 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -153,6 +153,8 @@ EMPTY_GUN_HELPER(shotgun/hellfire) desc = "A semi-automatic shotgun with tactical furniture and six-shell capacity underneath." icon_state = "cshotgun" item_state = "shotgun_combat" + lefthand_file = 'icons/mob/inhands/weapons/64x_guns_left.dmi' + righthand_file = 'icons/mob/inhands/weapons/64x_guns_right.dmi' fire_delay = 0.5 SECONDS default_ammo_type = /obj/item/ammo_box/magazine/internal/shot/com allowed_ammo_types = list( @@ -398,8 +400,8 @@ EMPTY_GUN_HELPER(shotgun/doublebarrel) name = "improvised shotgun" desc = "A length of pipe and miscellaneous bits of scrap fashioned into a rudimentary single-shot shotgun." icon = 'icons/obj/guns/projectile.dmi' - lefthand_file = GUN_LEFTHAND_ICON - righthand_file = GUN_RIGHTHAND_ICON + lefthand_file = 'icons/mob/inhands/weapons/64x_guns_left.dmi' + righthand_file = 'icons/mob/inhands/weapons/64x_guns_right.dmi' mob_overlay_icon = null base_icon_state = "ishotgun" diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 9c75aa56edcc..4eba20701ac7 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -3,6 +3,7 @@ desc = "A basic energy-based gun." icon = 'icons/obj/guns/energy.dmi' icon_state = "laser" + item_state = "spur" muzzleflash_iconstate = "muzzle_flash_laser" muzzle_flash_color = COLOR_SOFT_RED diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index f5f82ff43fb9..c17c1cb8a005 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -2,8 +2,6 @@ name = "SL L-204 laser gun" desc = "A basic energy-based laser gun that fires concentrated beams of light which pass through glass and thin metal." - icon_state = "laser" - item_state = "laser" w_class = WEIGHT_CLASS_NORMAL custom_materials = list(/datum/material/iron=2000) ammo_type = list(/obj/item/ammo_casing/energy/lasergun) diff --git a/code/modules/projectiles/guns/manufacturer/scarborough/ballistics.dm b/code/modules/projectiles/guns/manufacturer/scarborough/ballistics.dm index 6d1dff192407..dc599c84bb7f 100644 --- a/code/modules/projectiles/guns/manufacturer/scarborough/ballistics.dm +++ b/code/modules/projectiles/guns/manufacturer/scarborough/ballistics.dm @@ -886,7 +886,7 @@ NO_MAG_GUN_HELPER(automatic/assault/hydra/dmr) /obj/item/gun/ballistic/automatic/assault/hydra/underbarrel_gl/on_wield(obj/item/source, mob/user) wielded = TRUE secondary.wielded = TRUE - INVOKE_ASYNC(src, .proc.do_wield, user) + INVOKE_ASYNC(src, PROC_REF(do_wield), user) /obj/item/gun/ballistic/automatic/assault/hydra/underbarrel_gl/do_wield(mob/user) . = ..() diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index d37048250e62..bb6bafc9e74c 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -63,7 +63,7 @@ M.adjust_blindness(-1) switch(current_cycle) if(1 to 20) - //nothing + EMPTY_BLOCK_GUARD //nothing if(21 to INFINITY) if(prob(current_cycle-10)) M.cure_nearsighted(list(EYE_DAMAGE)) diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 9e4b2120774e..82bda376fc3c 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -119,7 +119,7 @@ F.fry(volume) F.reagents.add_reagent(/datum/reagent/consumable/cooking_oil, reac_volume) -/datum/reagent/consumable/cooking_oil/expose_mob(mob/living/M, method = TOUCH, method = SMOKE, reac_volume, show_message = 1, touch_protection = 0) +/datum/reagent/consumable/cooking_oil/expose_mob(mob/living/M, method = TOUCH, reac_volume, show_message = 1, touch_protection = 0) if(!istype(M)) return var/boiling = FALSE diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index 97196cf64ecc..ebfc08db3a48 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -776,7 +776,7 @@ ///obj/item/bodypart/proc/break_bone_feedback() owner.visible_message("You hear a cracking sound coming from [owner]'s [name].", "You feel something crack in your [name]!", "You hear an awful cracking sound.") - playsound(owner, list('sound/health/bone/bone_break1.ogg','sound/health/bone/bone_break2.ogg','sound/health/bone/bone_break3.ogg','sound/health/bone/bone_break4.ogg','sound/health/bone/bone_break5.ogg','sound/health/bone/bone_break6.ogg'), 100, FALSE, -1) + playsound(owner, pick(list('sound/health/bone/bone_break1.ogg','sound/health/bone/bone_break2.ogg','sound/health/bone/bone_break3.ogg','sound/health/bone/bone_break4.ogg','sound/health/bone/bone_break5.ogg','sound/health/bone/bone_break6.ogg')), 100, FALSE, -1) /obj/item/bodypart/proc/fix_bone() // owner.update_inv_splints() breaks diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 16e76901f957..5364a69c3483 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -45,6 +45,8 @@ /// Use this when something shouldn't happen and is of note, but shouldn't block CI. /// Does not mark the test as failed. #define TEST_NOTICE(source, message) source.log_for_test((##message), "notice", __FILE__, __LINE__) +/// TEST_NOTICE but more important +#define TEST_WARNING(source, message) source.log_for_test((##message), "warning", __FILE__, __LINE__) /// Constants indicating unit test completion status #define UNIT_TEST_PASSED 0 @@ -70,7 +72,7 @@ #ifdef BASIC_TESTS -//#include "icons/inhands.dm" +#include "icons/inhands.dm" #include "icons/missing_icons.dm" #include "icons/spritesheets.dm" #include "icons/worn_icons.dm" diff --git a/code/modules/unit_tests/create_and_destroy.dm b/code/modules/unit_tests/create_and_destroy.dm index b7c1b924fd53..ed3d9c6ed0a7 100644 --- a/code/modules/unit_tests/create_and_destroy.dm +++ b/code/modules/unit_tests/create_and_destroy.dm @@ -141,14 +141,12 @@ // Drastically lower the amount of time it takes to GC, since we don't have clients that can hold it up. SSgarbage.collection_timeout[GC_QUEUE_CHECK] = 10 SECONDS - //Prevent the garbage subsystem from harddeling anything, if only to save time - SSgarbage.collection_timeout[GC_QUEUE_HARDDELETE] = 10000 HOURS //Clear it, just in case cached_contents.Cut() var/list/queues_we_care_about = list() - // All up to harddel - for(var/i in 1 to GC_QUEUE_HARDDELETE - 1) + // All of em, I want hard deletes too, since we rely on the debug info from them + for(var/i in 1 to GC_QUEUE_HARDDELETE) queues_we_care_about += i //Now that we've qdel'd everything, let's sleep until the gc has processed all the shit we care about @@ -158,6 +156,7 @@ time_needed += SSgarbage.collection_timeout[index] var/start_time = world.time + var/real_start_time = REALTIMEOFDAY var/garbage_queue_processed = FALSE sleep(time_needed) @@ -179,7 +178,7 @@ garbage_queue_processed = TRUE break - if(world.time > start_time + time_needed + 30 MINUTES) //If this gets us gitbanned I'm going to laugh so hard + if(REALTIMEOFDAY > real_start_time + time_needed + 30 MINUTES) //If this gets us gitbanned I'm going to laugh so hard TEST_FAIL("Something has gone horribly wrong, the garbage queue has been processing for well over 30 minutes. What the hell did you do") break @@ -215,4 +214,3 @@ SSticker.delay_end = FALSE //This shouldn't be needed, but let's be polite SSgarbage.collection_timeout[GC_QUEUE_CHECK] = GC_CHECK_QUEUE - SSgarbage.collection_timeout[GC_QUEUE_HARDDELETE] = GC_DEL_QUEUE diff --git a/code/modules/unit_tests/icons/inhands.dm b/code/modules/unit_tests/icons/inhands.dm index 858c6d2f2840..dc05295203e6 100644 --- a/code/modules/unit_tests/icons/inhands.dm +++ b/code/modules/unit_tests/icons/inhands.dm @@ -53,7 +53,7 @@ match_message += (match_message ? " & '[file_place]'" : " - Matching sprite found in: '[file_place]'") if(!(skip_left || skip_right) && !lefthand_file && !righthand_file) - TEST_FAIL("Missing both icon files for [item_path].\n\titem_state = \"[item_state]\"[match_message]") + TEST_NOTICE(src, "Missing both icon files for [item_path].\n\titem_state = \"[item_state]\"[match_message]") continue var/missing_left @@ -80,7 +80,7 @@ if(!match_message && right_fallback && left_fallback) fallback_log_message += "\n\t[item_path] has invalid value, using fallback icon.\n\titem_state = \"[item_state]\"" continue - TEST_FAIL("Missing inhand sprites for [item_path] in both '[lefthand_file]' & '[righthand_file]'.\n\titem_state = \"[item_state]\"[match_message]") + TEST_NOTICE(src, "Missing inhand sprites for [item_path] in both '[lefthand_file]' & '[righthand_file]'.\n\titem_state = \"[item_state]\"[match_message]") else if(missing_left) TEST_FAIL("Missing left inhand sprite for [item_path] in '[lefthand_file]'[left_fallback ? ", using fallback icon" : null].\n\titem_state = \"[item_state]\"[match_message]") else if(missing_right) @@ -90,5 +90,5 @@ TEST_FAIL("Invalid item_state values should be set to null if there isn't a valid icon.[fallback_log_message]") if(unset_inhand_var_message) - log_test("\tNotice - Possible inhand icon matches found. It is best to be explicit with inhand sprite values.[unset_inhand_var_message]") + TEST_NOTICE(src, "Possible inhand icon matches found. It is best to be explicit with inhand sprite values.[unset_inhand_var_message]") diff --git a/code/modules/unit_tests/icons/worn_icons.dm b/code/modules/unit_tests/icons/worn_icons.dm index 3dba4d7c8e03..31c5d432dfa0 100644 --- a/code/modules/unit_tests/icons/worn_icons.dm +++ b/code/modules/unit_tests/icons/worn_icons.dm @@ -5,6 +5,7 @@ /// Make sure this location is also present in tools/deploy.sh /// If you need additional paths ontop of this second one, you can add another generate_possible_icon_states_list("your/folder/path/") below the if(additional_icon_location) block in Run(), and make sure to add that path to tools/deploy.sh as well. var/additional_icon_location = null + var/required_test = TRUE /datum/unit_test/mob_overlay_icons/proc/generate_possible_icon_states_list(directory_path) if(!directory_path) @@ -16,6 +17,9 @@ else possible_icon_states += generate_possible_icon_states_list("[directory_path][file_path]") +/datum/unit_test/mob_overlay_icons/proc/types_to_search() + return subtypesof(/obj/item/clothing) + /datum/unit_test/mob_overlay_icons/Run() generate_possible_icon_states_list() if(additional_icon_location) @@ -23,7 +27,7 @@ var/list/already_warned_icons = list() - for(var/obj/item/item_path as anything in (subtypesof(/obj/item/clothing))) + for(var/obj/item/item_path as anything in types_to_search()) var/cached_slot_flags = initial(item_path.slot_flags) if(!cached_slot_flags || (cached_slot_flags & ITEM_SLOT_LPOCKET) || (cached_slot_flags & ITEM_SLOT_RPOCKET) || initial(item_path.item_flags) & ABSTRACT) continue @@ -45,7 +49,10 @@ if(mob_overlay_icon) //easiest to check since we override everything. this automatically includes downstream support. if(!(icon_state in icon_states(mob_overlay_icon, 1))) - TEST_FAIL("[item_path] using invalid [mob_overlay_state ? "mob_overlay_state" : "icon_state"], \"[icon_state]\" in mob_overlay_icon override file, '[mob_overlay_icon]'[match_message]") + if(required_test) + TEST_FAIL("[item_path] using invalid [mob_overlay_state ? "mob_overlay_state" : "icon_state"], \"[icon_state]\" in mob_overlay_icon override file, '[mob_overlay_icon]'[match_message]") + else + TEST_NOTICE(src, "[item_path] using invalid [mob_overlay_state ? "mob_overlay_state" : "icon_state"], \"[icon_state]\" in mob_overlay_icon override file, '[mob_overlay_icon]'[match_message]") continue var/icon_file //checks against all the default icon locations if one isn't defined. @@ -61,15 +68,6 @@ fail_reasons += "[item_path] using invalid [mob_overlay_state ? "mob_overlay_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]" spacer = "\n\t" - /* - if(cached_slot_flags & ITEM_SLOT_ID) - icon_file = 'icons/mob/clothing/id.dmi' - if(!(icon_state in icon_states(icon_file, 1))) - already_warned_icons += icon_state - fail_reasons += "[spacer][item_path] using invalid [mob_overlay_state ? "mob_overlay_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]" - spacer = "\n\t" - */ - if(cached_slot_flags & ITEM_SLOT_GLOVES) icon_file = 'icons/mob/clothing/hands.dmi' if(!(icon_state in icon_states(icon_file, 1))) @@ -113,4 +111,13 @@ spacer = "\n\t" if(fail_reasons) - TEST_FAIL(fail_reasons) + if(required_test) + TEST_FAIL(fail_reasons) + else + TEST_NOTICE(src, fail_reasons) + +/datum/unit_test/mob_overlay_icons/not_clothing + required_test = FALSE + +/datum/unit_test/mob_overlay_icons/not_clothing/types_to_search() + return (subtypesof(/obj/item) - subtypesof(/obj/item/clothing)) diff --git a/code/modules/unit_tests/outfit_sanity.dm b/code/modules/unit_tests/outfit_sanity.dm index a09395d42103..8e85797e713e 100644 --- a/code/modules/unit_tests/outfit_sanity.dm +++ b/code/modules/unit_tests/outfit_sanity.dm @@ -6,7 +6,7 @@ if (outfit.random != TRUE) \ TEST_FAIL("[outfit.name]'s [#outfit_key] is invalid! Could not equip a [outfit.##outfit_key] into that slot."); \ else \ - log_test("[outfit.name]'s [#outfit_key] is invalid! Could not equip a [outfit.##outfit_key] into that slot."); \ + TEST_NOTICE(src, "[outfit.name]'s [#outfit_key] is invalid! Could not equip a [outfit.##outfit_key] into that slot."); \ } \ } @@ -72,7 +72,7 @@ if (outfit.random != TRUE) TEST_FAIL("[outfit.name]'s backpack_contents are invalid! Couldn't add [path] to backpack.") else - log_test("[outfit.name]'s backpack_contents are invalid! Couldn't add [path] to backpack.") + TEST_NOTICE(src, "[outfit.name]'s backpack_contents are invalid! Couldn't add [path] to backpack.") #undef CHECK_OUTFIT_SLOT diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi index ff71ba99e3c0..fd76394a835a 100644 Binary files a/icons/mob/inhands/weapons/guns_lefthand.dmi and b/icons/mob/inhands/weapons/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/swords_righthand.dmi b/icons/mob/inhands/weapons/swords_righthand.dmi index 9797eb3ee366..93a806555870 100644 Binary files a/icons/mob/inhands/weapons/swords_righthand.dmi and b/icons/mob/inhands/weapons/swords_righthand.dmi differ diff --git a/shiptest.dme b/shiptest.dme index 111baf30254e..802166bd74c4 100644 --- a/shiptest.dme +++ b/shiptest.dme @@ -13,6 +13,7 @@ // END_PREFERENCES // BEGIN_INCLUDE +#include "__odlint.dm" #include "_maps\_basemap.dm" #include "code\__byond_version_compat.dm" #include "code\_compile_options.dm" diff --git a/tgui/public/tgui.html b/tgui/public/tgui.html index a518c5f5aacf..5bd21f1b50de 100644 --- a/tgui/public/tgui.html +++ b/tgui/public/tgui.html @@ -510,9 +510,6 @@ + "" ); }; - -// Signal tgui that we're ready to receive updates -Byond.sendMessage('ready');