diff --git a/.github/workflows/autowiki.yml b/.github/workflows/autowiki.yml index c6f85bade91d5..10d3cea1e6761 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 cd4271bbd4d01..33af3581a22b4 100644 --- a/.github/workflows/ci_suite.yml +++ b/.github/workflows/ci_suite.yml @@ -3,9 +3,11 @@ on: push: branches: - master + - "project/**" pull_request: branches: - master + - "project/**" merge_group: branches: - master @@ -18,8 +20,7 @@ jobs: start_gate: if: ( !contains(github.event.head_commit.message, '[ci skip]') ) name: Start Gate - runs-on: ubuntu-22.04 - + runs-on: ubuntu-latest steps: - name: Mandatory Empty Step run: exit 0 @@ -29,6 +30,7 @@ jobs: needs: start_gate runs-on: ubuntu-22.04 timeout-minutes: 5 + steps: - uses: actions/checkout@v3 with: @@ -121,8 +123,9 @@ jobs: compile_all_maps: name: Compile Maps needs: start_gate - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest timeout-minutes: 5 + steps: - uses: actions/checkout@v3 @@ -201,15 +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, run_all_tests, compile_all_maps, run_linters] + needs: [test_windows, compile_all_maps, run_linters, run_all_tests] runs-on: ubuntu-latest steps: - - name: Mandatory Empty Step - run: exit 0 + - 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/rerun_flaky_tests.yml b/.github/workflows/rerun_flaky_tests.yml index e3cbda05749b3..b705735a0dfb8 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/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 1ab889987695e..16de5230a2bb3 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/game/objects/items/storage/guncases.dm b/code/game/objects/items/storage/guncases.dm index 2feb49af03f7b..8fba125036eb2 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/modules/client/loadout/_loadout.dm b/code/modules/client/loadout/_loadout.dm index a0e5d6cab3c33..44c1cff4ffa5f 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 a8acc15446544..d52c9a8b58fc0 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 2f7e59c288b7d..f660d35f676ac 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 1d11857663ad6..1edeed63530a6 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/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm index 982b3804f586e..1524a4aa6466c 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 89cce9c24d644..81e5da317553b 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/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 648ad96640f24..479e35794e601 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -460,6 +460,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/detective) 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 ab85fb9a01c4f..347aeb5a0502f 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -144,6 +144,8 @@ 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 mag_type = /obj/item/ammo_box/magazine/internal/shot/com w_class = WEIGHT_CLASS_BULKY @@ -372,8 +374,8 @@ EMPTY_GUN_HELPER(shotgun/automatic/bulldog/inteq) 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 aaf37d4c95563..8661a9588bc79 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 eff3d67b2df1a..344d0a53880da 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/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index ba42b9bc9f462..8d180db5d1e94 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 0e0248162fc8a..4b6cc0498c276 100644 --- a/code/modules/unit_tests/create_and_destroy.dm +++ b/code/modules/unit_tests/create_and_destroy.dm @@ -143,14 +143,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 @@ -160,6 +158,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) @@ -181,7 +180,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 @@ -214,4 +213,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 858c6d2f2840b..dc05295203e63 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 3dba4d7c8e03b..31c5d432dfa01 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 a09395d421037..8e85797e713e7 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 ff71ba99e3c08..fd76394a835a2 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 9797eb3ee3669..93a806555870f 100644 Binary files a/icons/mob/inhands/weapons/swords_righthand.dmi and b/icons/mob/inhands/weapons/swords_righthand.dmi differ