diff --git a/.github/workflows/ci_suite.yml b/.github/workflows/ci_suite.yml index e76e224522a0..716686b51433 100644 --- a/.github/workflows/ci_suite.yml +++ b/.github/workflows/ci_suite.yml @@ -6,21 +6,23 @@ on: merge_group: jobs: run_linters: - if: "!contains(github.event.head_commit.message, '[ci skip]')" + if: ( !contains(github.event.head_commit.message, '[ci skip]') ) name: Run Linters runs-on: ubuntu-latest concurrency: group: run_linters-${{ github.head_ref || github.run_id }} cancel-in-progress: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Restore SpacemanDMM cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/SpacemanDMM key: ${{ runner.os }}-spacemandmm-${{ secrets.CACHE_PURGE_KEY }} - name: Restore Yarn cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: tgui/.yarn/cache key: ${{ runner.os }}-yarn-${{ secrets.CACHE_PURGE_KEY }}-${{ hashFiles('tgui/yarn.lock') }} @@ -28,7 +30,7 @@ jobs: ${{ runner.os }}-build- ${{ runner.os }}- - name: Restore Rust cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cargo key: ${{ runner.os }}-rust @@ -75,7 +77,7 @@ jobs: - run: ./DMCompiler_linux-x64/DMCompiler --suppress-unimplemented colonialmarines.dme compile_all_maps: - if: "!contains(github.event.head_commit.message, '[ci skip]')" + if: ( !contains(github.event.head_commit.message, '[ci skip]') ) name: Compile Maps runs-on: ubuntu-latest steps: @@ -92,7 +94,7 @@ jobs: tools/build/build --ci dm -DCIBUILDING -DCITESTING -DALL_MAPS find_all_maps: - if: "!contains(github.event.head_commit.message, '[ci skip]')" + if: ( !contains(github.event.head_commit.message, '[ci skip]') ) name: Find Maps to Test runs-on: ubuntu-latest outputs: @@ -117,7 +119,7 @@ jobs: ALTERNATE_TESTS_JSON=$(jq -nRc '[inputs | capture("^(?[0-9]+)\\.(?[0-9]+): (?.+)$")]' .github/alternate_byond_versions.txt) echo "alternate_tests=$ALTERNATE_TESTS_JSON" >> $GITHUB_OUTPUT run_all_tests: - if: "!contains(github.event.head_commit.message, '[ci skip]')" + if: ( !contains(github.event.head_commit.message, '[ci skip]') ) name: Unit Tests needs: [find_all_maps] strategy: @@ -132,7 +134,7 @@ jobs: map: ${{ matrix.map }} run_alternate_tests: - if: "!contains(github.event.head_commit.message, '[ci skip]') && needs.find_all_maps.outputs.alternate_tests != '[]'" + if: ( !contains(github.event.head_commit.message, '[ci skip]') && needs.find_all_maps.outputs.alternate_tests != '[]' ) name: Alternate Tests needs: [find_all_maps] strategy: @@ -149,7 +151,7 @@ jobs: minor: ${{ matrix.setup.minor }} check_alternate_tests: - if: "!contains(github.event.head_commit.message, '[ci skip]') && needs.find_all_maps.outputs.alternate_tests != '[]'" + if: ( !contains(github.event.head_commit.message, '[ci skip]') && needs.find_all_maps.outputs.alternate_tests != '[]' ) name: Check Alternate Tests needs: [run_alternate_tests] runs-on: ubuntu-latest @@ -157,7 +159,7 @@ jobs: - run: echo Alternate tests passed. test_windows: - if: "!contains(github.event.head_commit.message, '[ci skip]')" + if: ( !contains(github.event.head_commit.message, '[ci skip]') ) name: Windows Build runs-on: windows-latest concurrency: diff --git a/.github/workflows/generate_documentation.yml b/.github/workflows/generate_documentation.yml index c2898dfa9c57..7c178d1ac93b 100644 --- a/.github/workflows/generate_documentation.yml +++ b/.github/workflows/generate_documentation.yml @@ -5,7 +5,7 @@ on: - master jobs: generate_documentation: - if: "!contains(github.event.head_commit.message, '[ci skip]')" + if: ( !contains(github.event.head_commit.message, '[ci skip]') ) runs-on: ubuntu-latest concurrency: gen-docs steps: diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index c3648df6ba29..3141b9fd2369 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -425,7 +425,8 @@ SUBSYSTEM_DEF(ticker) var/mob/M = J.spawn_in_player(player) if(istype(M)) J.equip_job(M) - EquipCustomItems(M) + if(player.ckey in GLOB.donator_items) + to_chat(player, SPAN_BOLDNOTICE("You have gear available in the personal gear vendor near Requisitions.")) if(M.client) var/client/C = M.client @@ -455,7 +456,9 @@ SUBSYSTEM_DEF(ticker) captainless = FALSE if(player.job) GLOB.RoleAuthority.equip_role(player, GLOB.RoleAuthority.roles_by_name[player.job], late_join = FALSE) - EquipCustomItems(player) + if(player.ckey in GLOB.donator_items) + to_chat(player, SPAN_BOLDNOTICE("You have gear available in the personal gear vendor near Requisitions.")) + if(player.client) var/client/C = player.client if(C.player_data && C.player_data.playtime_loaded && length(C.player_data.playtimes) == 0) diff --git a/code/game/machinery/nuclearbomb.dm b/code/game/machinery/nuclearbomb.dm index 35cd8ce1bbb1..1ee8cfd66e70 100644 --- a/code/game/machinery/nuclearbomb.dm +++ b/code/game/machinery/nuclearbomb.dm @@ -576,7 +576,7 @@ GLOBAL_VAR_INIT(bomb_set, FALSE) hive = GLOB.hive_datum[hivenumber] if(!length(hive.totalXenos)) return - xeno_announcement(SPAN_XENOANNOUNCE("We get a sense of impending doom... the hive killer is ready to be activated."), hive.hivenumber, XENO_GENERAL_ANNOUNCE) + xeno_announcement(SPAN_XENOANNOUNCE("We get a sense of impending doom... the hive killer is ready to be activated. Our only chance now is to disable the device itself."), hive.hivenumber, XENO_GENERAL_ANNOUNCE) return announcement_helper("DECRYPTION IN [floor(decryption_time/10)] SECONDS.", "[MAIN_AI_SYSTEM] Nuclear Tracker", humans_uscm, 'sound/misc/notice1.ogg') diff --git a/code/game/objects/structures/fence.dm b/code/game/objects/structures/fence.dm index 1f6bf6625d06..c2c7d516107b 100644 --- a/code/game/objects/structures/fence.dm +++ b/code/game/objects/structures/fence.dm @@ -162,14 +162,14 @@ if(W.flags_item & NOBLUDGEON) return - if(HAS_TRAIT(W, TRAIT_TOOL_WIRECUTTERS) || istype(W, /obj/item/attachable/bayonet)) + if(HAS_TRAIT(W, TRAIT_TOOL_WIRECUTTERS) || istype(W, /obj/item/attachable/bayonet) || istype(W, /obj/item/weapon/bracer_attachment)) user.visible_message(SPAN_NOTICE("[user] starts cutting through [src] with [W]."), SPAN_NOTICE("You start cutting through [src] with [W].")) playsound(src.loc, 'sound/items/Wirecutter.ogg', 25, 1) - //Bayonets are 3/4th as effective at cutting fences + //Bayonets and Wristblades are 3/4th as effective at cutting fences var duration = 10 * user.get_skill_duration_multiplier(SKILL_CONSTRUCTION) - if(istype(W, /obj/item/attachable/bayonet)) + if(istype(W, /obj/item/attachable/bayonet) || istype(W, /obj/item/weapon/bracer_attachment)) duration *= 1.5 if(do_after(user, duration, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) diff --git a/code/modules/cm_marines/Donator_Kits.dm b/code/modules/cm_marines/Donator_Kits.dm deleted file mode 100644 index b0c9ec51e946..000000000000 --- a/code/modules/cm_marines/Donator_Kits.dm +++ /dev/null @@ -1,589 +0,0 @@ -/obj/item/storage/box/donator_kit - name = "donated box" - desc = "A cardboard box stamped with a dollar sign and filled with trinkets. Appears to have been donated by a wealthy sponsor." - icon = 'icons/obj/items/storage/kits.dmi' - icon_state = "donator_kit" - item_state = "giftbag" - var/list/donor_gear = list() - var/donor_key = "GENERIC" //Key the kit is assigned to. If GENERIC, not tied to particular donor. - var/kit_variant - max_w_class = SIZE_TINY - -/obj/item/storage/box/donator_kit/New() - if(kit_variant) - name = "[name] ([kit_variant])" - ..() - -/obj/item/storage/box/donator_kit/fill_preset_inventory() - for(var/donor_item in donor_gear) - new donor_item(src) - -/obj/item/storage/box/donator_kit/open(mob/user) - if((donor_key != "GENERIC") && (donor_key != user.ckey)) - to_chat(user, SPAN_BOLDWARNING("You cannot open a donator kit you do not own!")) - return FALSE - ..() - -/obj/item/storage/box/donator_kit/verb/destroy_kit() - set name = "Destroy Kit" - set category = "Object" - set src in oview(1) - - var/mob/user = usr - - if((donor_key != "GENERIC") && (donor_key != user.ckey)) - to_chat(user, SPAN_BOLDWARNING("You cannot destroy a donator kit you do not own!")) - return FALSE - - log_admin("[key_name(user)] deleted a donator kit.") - qdel(src) - -/obj/item/storage/box/donator_kit/generic_omega //Generic set given to various donors - kit_variant = "Team Omega (G)" - donor_gear = list( - /obj/item/clothing/under/marine/fluff/standard_jumpsuit, - /obj/item/clothing/suit/storage/marine/fluff/standard_armor, - /obj/item/clothing/head/helmet/marine/fluff/standard_helmet, - ) - -//Unless specified in comments as otherwise, subtype of box/donator_kit/ is CKEY of the donator (example: /obj/item/storage/box/donator_kit/sasoperative) -/obj/item/storage/box/donator_kit/adjective - donor_key = "adjective" - donor_gear = list(/obj/item/clothing/suit/storage/marine/fluff/adjective) - -/obj/item/storage/box/donator_kit/alexwarhammer - donor_key = "alexwarhammer" - donor_gear = list(/obj/item/clothing/glasses/fluff/alexwarhammer) - -/obj/item/storage/box/donator_kit/allan1234 - donor_key = "allan1234" - donor_gear = list(/obj/item/clothing/under/marine/fluff/allan1234) - -/obj/item/storage/box/donator_kit/arachnidnexus - donor_key = "arachnidnexus" - donor_gear = list(/obj/item/clothing/under/marine/fluff/arach) - -/obj/item/storage/box/donator_kit/bibblesless - donor_key = "bibblesless" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/bibblesless) - -/obj/item/storage/box/donator_kit/biolock - donor_key = "biolock" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/biolock, - /obj/item/clothing/suit/storage/marine/light/fluff/biolock, - ) - -/obj/item/storage/box/donator_kit/bunny232 - donor_key = "bunny232" - donor_gear = list(/obj/item/clothing/glasses/fluff/eyepatch) - -/obj/item/storage/box/donator_kit/bwoincognito - donor_key = "bwoincognito" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/bwoincognito, - /obj/item/clothing/suit/storage/marine/fluff/bwoincognito, - /obj/item/clothing/under/marine/fluff/bwoincognito, - ) - -/obj/item/storage/box/donator_kit/chris1464 - donor_key = "chris1464" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/chris1464, - /obj/item/clothing/suit/storage/marine/fluff/chris1464, - /obj/item/clothing/under/marine/fluff/chris1464, - ) - -/obj/item/storage/box/donator_kit/commandercookies - donor_key = "commandercookies" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/commandercookies, - /obj/item/clothing/suit/storage/marine/fluff/commandercookies, - ) - -/obj/item/storage/box/donator_kit/commissar //used by both ckeys 'hycinth' and 'technokat' - donor_key = "hycinth" - kit_variant = "Commissar" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/commissar, - /obj/item/clothing/suit/storage/marine/fluff/commissar, - /obj/item/clothing/under/marine/fluff/commissar, - /obj/item/storage/belt/marine/fluff/commissar, - ) - -/obj/item/storage/box/donator_kit/commissar/technokat - donor_key = "technokat" - -/obj/item/storage/box/donator_kit/crazyh206 - donor_key = "crazyh206" - donor_gear = list(/obj/item/clothing/suit/storage/marine/fluff/crazyh206) - -/obj/item/storage/box/donator_kit/devilzhand - donor_key = "devilzhand" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/devilzhand, - /obj/item/clothing/suit/storage/marine/fluff/devilzhand, - ) - -/obj/item/storage/box/donator_kit/dingledangle - donor_key = "dingledangle" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/dingledangle) - -/obj/item/storage/box/donator_kit/dinobubba7 - donor_key = "dinobubba7" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/dino, - /obj/item/clothing/suit/storage/marine/fluff/dino, - ) - -/obj/item/storage/box/donator_kit/docdemo - donor_key = "docdemo" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/goldtrimberet) - -/obj/item/storage/box/donator_kit/dudewithatude - donor_key = "dudewithatude" - donor_gear = list(/obj/item/clothing/suit/storage/marine/fluff/dudewithatude) - -/obj/item/storage/box/donator_kit/eastgermanstasi - donor_key = "eastgermanstasi" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/eastgerman) - -/obj/item/storage/box/donator_kit/edgelord - donor_key = "edgelord" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/edgelord) - -/obj/item/storage/box/donator_kit/eonoc - donor_key = "eonoc" - donor_gear = list(/obj/item/clothing/suit/storage/marine/fluff/eonoc) - -/obj/item/storage/box/donator_kit/fairedan - donor_key = "fairedan" - donor_gear = list( - /obj/item/clothing/suit/storage/marine/fluff/fairedan, - /obj/item/clothing/under/marine/fluff/fairedan, - ) - -/obj/item/storage/box/donator_kit/feodrich - donor_key = "feodrich" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/feodrich, - /obj/item/clothing/shoes/marine/fluff/feodrich, - /obj/item/clothing/suit/storage/marine/fluff/feodrich, - /obj/item/clothing/under/marine/fluff/feodrich, - ) - -/obj/item/storage/box/donator_kit/fernkiller - donor_key = "fernkiller" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/fernkiller) - -/obj/item/storage/box/donator_kit/feweh - donor_key = "feweh" - donor_gear = list( - /obj/item/clothing/mask/fluff/feweh, - /obj/item/clothing/suit/storage/marine/fluff/feweh, - /obj/item/clothing/under/marine/fluff/feweh, - ) - -/obj/item/storage/box/donator_kit/fickmacher_selena //ckey fickmacher has two sets - donor_key = "fickmacher" - kit_variant = "Selena" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/fickmacher, - /obj/item/clothing/suit/storage/marine/fluff/fickmacher, - /obj/item/clothing/under/marine/fluff/fickmacher, - ) - -/obj/item/storage/box/donator_kit/fickmacher_hart - donor_key = "fickmacher" - kit_variant = "Hart" - donor_gear = list( - /obj/item/clothing/mask/fluff/fickmacher2, - /obj/item/clothing/suit/storage/marine/fluff/fickmacher2, - /obj/item/clothing/under/marine/fluff/fickmacher2, - ) - -/obj/item/storage/box/donator_kit/fridrich - donor_key = "fridrich" - donor_gear = list(/obj/item/clothing/suit/storage/marine/fluff/fridrich) - -/obj/item/storage/box/donator_kit/ghostdex - donor_key = "ghostdex" - donor_gear = list( - /obj/item/clothing/mask/cigarette/fluff/ghostdex, - /obj/item/tool/lighter/zippo/fluff/ghostdex, - ) - -/obj/item/storage/box/donator_kit/graciegrace0 - donor_key = "graciegrace0" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/medicae_helmet, - /obj/item/clothing/suit/storage/marine/fluff/medicae_armor, - /obj/item/clothing/under/marine/fluff/medicae_jumpsuit, - ) - -/obj/item/storage/box/donator_kit/gromoi - donor_key = "gromoi" - donor_gear = list( - /obj/item/clothing/suit/storage/marine/fluff/gromi, - /obj/item/clothing/under/marine/fluff/gromi, - ) - -/obj/item/storage/box/donator_kit/haveatya - donor_key = "haveatya" - donor_gear = list( - /obj/item/clothing/glasses/fluff/haveatya, - /obj/item/clothing/head/helmet/marine/fluff/haveatya, - /obj/item/clothing/under/marine/fluff/turtleneck, //generic item - ) - -/obj/item/storage/box/donator_kit/jackmcintyre - donor_key = "jackmcintyre" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/jackmcintyre, - /obj/item/clothing/suit/storage/marine/fluff/jackmcintyre, - /obj/item/clothing/under/marine/fluff/jackmcintyre, - /obj/item/clothing/under/marine/fluff/jackmcintyre_alt, - ) - -/obj/item/storage/box/donator_kit/jdobbin49 - donor_key = "jdobbin49" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/jdobbin49) - -/obj/item/storage/box/donator_kit/jedijasun - donor_key = "jedijasun" - donor_gear = list(/obj/item/clothing/gloves/marine/fluff/jedijas) - -/obj/item/storage/box/donator_kit/johnkilla56 - donor_key = "johnkilla56" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/john56, - /obj/item/clothing/mask/fluff/john56, - /obj/item/clothing/suit/storage/marine/fluff/john56, - /obj/item/clothing/under/marine/fluff/john56, - ) - -/obj/item/storage/box/donator_kit/juninho77 - donor_key = "juninho77" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/juniho, - /obj/item/clothing/suit/storage/marine/fluff/juninho, - /obj/item/clothing/under/marine/fluff/juninho, - ) - -/obj/item/storage/box/donator_kit/kilinger - donor_key = "kilinger" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/goldshieldberet) - -/obj/item/storage/box/donator_kit/kyrac - donor_key = "kyrac" - donor_gear = list( - /obj/item/clothing/under/marine/fluff/turtleneck, - /obj/item/clothing/glasses/fluff/eyepatch, - ) - -/obj/item/storage/box/donator_kit/laser243 - donor_key = "laser243" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/laser243, - /obj/item/clothing/suit/storage/marine/fluff/laser243, - ) - -/obj/item/storage/box/donator_kit/leondark16 - donor_key = "leondark16" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/leondark) - -/obj/item/storage/box/donator_kit/lestatanderson - donor_key = "lestatanderson" - donor_gear = list(/obj/item/clothing/suit/storage/marine/fluff/cia) - -/obj/item/storage/box/donator_kit/limodish - donor_key = "limodish" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/limo, - /obj/item/clothing/mask/fluff/limo, - /obj/item/clothing/suit/storage/marine/fluff/limo, - /obj/item/clothing/under/marine/fluff/turtleneck, //generic item - ) - -/obj/item/storage/box/donator_kit/lostmixup - donor_key = "lostmixup" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/lostmixup, - /obj/item/clothing/mask/fluff/lostmixup, - /obj/item/clothing/suit/storage/marine/fluff/lostmixup, - ) - -/obj/item/storage/box/donator_kit/markvalentine - donor_key = "markvalentine" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/valentine, - /obj/item/clothing/suit/storage/marine/fluff/valentine, - /obj/item/clothing/under/marine/fluff/valentine, - ) - -/obj/item/storage/box/donator_kit/mitii - donor_key = "mitii" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/mitii, - /obj/item/clothing/suit/storage/marine/fluff/mitii, - /obj/item/storage/backpack/marine/fluff/mitii, - ) - -/obj/item/storage/box/donator_kit/mrbark45 - donor_key = "mrbark45" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/bark) - -/obj/item/storage/box/donator_kit/nickiskool - donor_key = "nickiskool" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/nickiskool, - /obj/item/clothing/suit/storage/marine/fluff/nickiskool, - /obj/item/clothing/under/marine/fluff/nickiskool, - ) - -/obj/item/storage/box/donator_kit/ningajai - donor_key = "ningajai" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/ningajai) - -/obj/item/storage/box/donator_kit/obeystylez - donor_key = "obeystylez" - donor_gear = list( - /obj/item/clothing/gloves/black/obey, - /obj/item/clothing/mask/fluff/balaclava, //generic item - /obj/item/clothing/suit/storage/marine/fluff/obey, - /obj/item/clothing/under/marine/fluff/turtleneck, //generic item - ) - -/obj/item/storage/box/donator_kit/officialjake - donor_key = "officialjake" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/officialjake) - -/obj/item/storage/box/donator_kit/oneonethreeeight - donor_key = "oneonethreeeight" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/oneonethreeeight, - /obj/item/clothing/suit/storage/marine/fluff/oneonethreeeight, - /obj/item/clothing/under/marine/fluff/oneonethreeeight, - ) - -/obj/item/storage/box/donator_kit/paradox1i7 - donor_key = "paradox1i7" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/paradox, - /obj/item/clothing/suit/storage/marine/fluff/paradox, - /obj/item/clothing/under/marine/fluff/paradox, - ) - -/obj/item/storage/box/donator_kit/poops_buttly - donor_key = "poops_buttly" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/kaila, - /obj/item/clothing/suit/storage/marine/fluff/kaila, - ) - -/obj/item/storage/box/donator_kit/radicalscorpion - donor_key = "radicalscorpion" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/radical, - /obj/item/clothing/mask/fluff/balaclava, //generic item - /obj/item/clothing/suit/storage/marine/fluff/radical, - /obj/item/clothing/under/marine/fluff/radical, - ) - -/obj/item/storage/box/donator_kit/robin63 - donor_key = "robin63" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/robin) - -/obj/item/storage/box/donator_kit/rogue1131 - donor_key = "rogue1131" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/titus, - /obj/item/clothing/suit/storage/marine/fluff/titus, - ) - -/obj/item/storage/box/donator_kit/sadokist - donor_key = "sadokist" - donor_gear = list( - /obj/item/clothing/glasses/fluff/sadokist, - /obj/item/clothing/head/helmet/marine/fluff/sadokist, - /obj/item/clothing/suit/storage/marine/fluff/sadokist, - /obj/item/storage/backpack/marine/fluff/sadokist, - ) - -/obj/item/storage/box/donator_kit/sailordave - donor_key = "sailordave" - donor_gear = list(/obj/item/clothing/under/marine/fluff/sailordave) - -/obj/item/storage/box/donator_kit/sasoperative_elite //sasoperative has several sets - donor_key = "sasoperative" - kit_variant = "Elite" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/sas_elite, - /obj/item/clothing/mask/fluff/sas_elite, - /obj/item/clothing/suit/storage/marine/fluff/sas_elite, - /obj/item/clothing/under/marine/fluff/sas_elite, - ) - -/obj/item/storage/box/donator_kit/sasoperative_juggernaut - donor_key = "sasoperative" - kit_variant = "Juggernaut" - donor_gear = list( - /obj/item/storage/backpack/marine/satchel/fluff/sas_juggernaut, - /obj/item/clothing/head/helmet/marine/fluff/sas_juggernaut, - /obj/item/clothing/suit/storage/marine/fluff/sas_juggernaut, - ) - -/obj/item/storage/box/donator_kit/sasoperative_legion - donor_key = "sasoperative" - kit_variant = "Legion" - donor_gear = list( - /obj/item/clothing/suit/storage/marine/light/fluff/sas_legion, - /obj/item/clothing/head/helmet/marine/fluff/sas_legion, - /obj/item/storage/backpack/marine/satchel/fluff/sas_legion, - ) - -/obj/item/storage/box/donator_kit/seloc_aferah - donor_key = "seloc_aferah" - donor_gear = list(/obj/item/clothing/head/helmet/marine/fluff/deejay) - -/obj/item/storage/box/donator_kit/starscream123 - donor_key = "starscream123" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/starscream, - /obj/item/clothing/mask/fluff/starscream, - /obj/item/clothing/suit/storage/marine/fluff/starscream, - /obj/item/clothing/under/marine/fluff/starscream, - ) - -/obj/item/storage/box/donator_kit/steelpoint - donor_key = "steelpoint" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/steelpoint, - /obj/item/clothing/shoes/marine/fluff/steelpoint, - /obj/item/clothing/suit/storage/marine/fluff/steelpoint, - /obj/item/clothing/under/marine/fluff/steelpoint, - ) - -/obj/item/storage/box/donator_kit/stobarico - donor_key = "stobarico" - donor_gear = list(/obj/item/clothing/suit/storage/marine/fluff/stobarico) - -/obj/item/storage/box/donator_kit/theflagbearer - donor_key = "theflagbearer" - donor_gear = list(/obj/item/clothing/under/marine/fluff/leeeverett) - -/obj/item/storage/box/donator_kit/theultimatechimera - donor_key = "theultimatechimera" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/chimera, - /obj/item/clothing/suit/storage/marine/fluff/chimera, - ) - -/obj/item/storage/box/donator_kit/tophatpenguin_wooki //ckey tophatpenguin has two sets - donor_key = "tophatpenguin" - kit_variant = "Wooki" - donor_gear = list( - /obj/item/clothing/suit/storage/marine/fluff/penguin, - /obj/item/clothing/under/marine/fluff/wooki, - /obj/item/clothing/head/helmet/marine/fluff/penguin, - ) - -/obj/item/storage/box/donator_kit/tophatpenguin_santa - donor_key = "tophatpenguin" - kit_variant = "Santa" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/santahat, - /obj/item/clothing/suit/storage/marine/fluff/santa, - ) - -/obj/item/storage/box/donator_kit/totalanarchy - donor_key = "totalanarchy" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/totalanarchy, - /obj/item/clothing/mask/fluff/totalanarchy, - /obj/item/clothing/suit/storage/marine/fluff/totalanarchy, - /obj/item/clothing/under/marine/fluff/totalanarchy, - ) - -/obj/item/storage/box/donator_kit/tranquill - donor_key = "tranquill" - donor_gear = list(/obj/item/clothing/suit/storage/marine/fluff/tranquill) - -/obj/item/storage/box/donator_kit/trblackdragon - donor_key = "trblackdragon" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/trblackdragon, - /obj/item/clothing/suit/storage/marine/fluff/trblackdragon, - ) - -/obj/item/storage/box/donator_kit/tristan63 - donor_key = "tristan63" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/tristan, - /obj/item/clothing/suit/storage/marine/fluff/tristan, - /obj/item/clothing/under/marine/fluff/tristan, - ) - -/obj/item/storage/box/donator_kit/tyran68 - donor_key = "tyran68" - donor_gear = list(/obj/item/clothing/suit/storage/marine/fluff/tyran) - -/obj/item/storage/box/donator_kit/shotgunbill - donor_key = "shotgunbill" - donor_gear = list(/obj/item/clothing/head/collectable/petehat) - -/obj/item/storage/box/donator_kit/vintagepalmer - donor_key = "vintagepalmer" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/vintage, - /obj/item/clothing/shoes/marine/fluff/vintage, - /obj/item/clothing/suit/storage/marine/fluff/vintage, - /obj/item/clothing/under/marine/fluff/vintage, - ) - -/obj/item/storage/box/donator_kit/whiteblood17 - donor_key = "whiteblood17" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/whiteblood17, - /obj/item/clothing/under/marine/fluff/whiteblood17, - ) - -/obj/item/storage/box/donator_kit/wrightthewrong - donor_key = "wrightthewrong" - donor_gear = list( - /obj/item/clothing/glasses/fluff/wright, - /obj/item/clothing/suit/storage/marine/fluff/wright, - /obj/item/clothing/under/marine/fluff/turtleneck, //generic item - ) - -/obj/item/storage/box/donator_kit/zegara - donor_key = "zegara" - donor_gear = list(/obj/item/clothing/suit/storage/marine/fluff/zegara) - -/obj/item/storage/box/donator_kit/zynax - donor_key = "zynax" - donor_gear = list( - /obj/item/clothing/mask/fluff/balaclava, //generic item - /obj/item/clothing/suit/storage/marine/fluff/Zynax, - /obj/item/clothing/under/marine/fluff/turtleneck, //generic item - /obj/item/clothing/under/marine/fluff/Zynax, - ) - -/obj/item/storage/box/donator_kit/mileswolfe - donor_key = "mileswolfe" - donor_gear = list(/obj/item/clothing/under/marine/fluff/mileswolfe) - -/obj/item/storage/box/donator_kit/killaninja12 - donor_key = "killaninja12" - donor_gear = list( - /obj/item/clothing/head/helmet/marine/fluff/killaninja12, - /obj/item/clothing/suit/storage/marine/fluff/killaninja12, - ) - -/obj/item/storage/box/donator_kit/noize - donor_key = "noize" - donor_gear = list(/obj/item/clothing/suit/storage/marine/fluff/forwardslashn) - -/obj/item/storage/box/donator_kit/deanthelis - donor_key = "deanthelis" - donor_gear = list(/obj/item/clothing/head/beret/marine/techofficer) diff --git a/code/modules/cm_marines/custom_items.dm b/code/modules/cm_marines/custom_items.dm new file mode 100644 index 000000000000..9f686b1da348 --- /dev/null +++ b/code/modules/cm_marines/custom_items.dm @@ -0,0 +1,171 @@ +GLOBAL_LIST_FILE_LOAD(custom_items, "config/custom_items.txt") +GLOBAL_LIST_EMPTY(donator_items) + +/obj/structure/machinery/personal_gear_vendor + name = "personal gear vendor" + desc = "A console that allows the user to retrieve their personal possessions from the ASRS." + icon = 'icons/obj/structures/machinery/computer.dmi' + icon_state = "cellconsole" + density = TRUE + unacidable = TRUE + unslashable = TRUE + ///a random item that can be claimed if there is no valid kit + var/static/list/random_personal_possessions = list() + ///assoc list of ckeys to list of kits redeemed + var/static/list/ckeys_redeemed_kits = list() + +/obj/structure/machinery/personal_gear_vendor/Initialize(mapload, ...) + . = ..() + if(!length(GLOB.donator_items)) + generate_donor_kits() + + if(!length(random_personal_possessions)) + generate_random_possessions() + +/obj/structure/machinery/personal_gear_vendor/proc/generate_donor_kits(regenerate_kits = FALSE) + if(regenerate_kits) + GLOB.donator_items = list() + + for(var/current_line in GLOB.custom_items) + if(!length(current_line)) //empty line + continue + if(copytext(current_line, 1, 2) == "#") //comment line + continue + + var/donor_key + var/list/kit_gear = list() + var/kit_name = "Default" + + var/split_line = splittext(current_line, ":") + + donor_key = trim(split_line[1]) + if(length(split_line) > 2) //if someone has multiple kits, name them + kit_name = trim(split_line[2]) + + for(var/current_item in splittext(split_line[length(split_line)], ",")) + var/current_path = text2path(trim(current_item)) + if(!current_path) + stack_trace("Missing typepath in Donator Gear. [donor_key] has an invalid typepath for [current_item].") + continue + kit_gear += current_path + + if(!length(kit_gear)) //shouldnt let them get empty kits + stack_trace("Missing gear in Donator Gear. [donor_key] has an empty Donator Kit.") + continue + + if(kit_name in GLOB.donator_items[donor_key]) //multiple kits with same name + stack_trace("Duplicate kit in Donator Gear. [donor_key] has multiple [kit_name] Donator Kits.") + continue + + GLOB.donator_items[donor_key] += list("[kit_name]" = kit_gear) + +/obj/structure/machinery/personal_gear_vendor/proc/generate_random_possessions(regenerate_kits = FALSE) + if(regenerate_kits) + random_personal_possessions = list() + + for(var/datum/gear/current_gear as anything in subtypesof(/datum/gear)) + if(!initial(current_gear.display_name)) + continue + random_personal_possessions += initial(current_gear.path) + +/obj/structure/machinery/personal_gear_vendor/attack_hand(mob/living/user) + if(..()) + return TRUE + + if(!ishuman(user)) + return FALSE + + var/list/possible_kits = list() + if(user.ckey in GLOB.donator_items) + possible_kits += GLOB.donator_items[user.ckey] + + if(user.ckey in ckeys_redeemed_kits) + if(length(ckeys_redeemed_kits[user.ckey]) >= length(possible_kits)) + // They are a donator but have gotten everything + to_chat(user, SPAN_NOTICE("You have already retrieved your kit(s).")) + return TRUE + + if(length(possible_kits) == 0) //if no donor kit they can get something else + var/random_item_path = pick(random_personal_possessions) + var/random_item = new random_item_path(get_turf(src)) + user.put_in_any_hand_if_possible(random_item) + to_chat(user, SPAN_NOTICE("You take [random_item] from [src].")) + LAZYADD(ckeys_redeemed_kits[user.ckey], random_item_path) + return TRUE + + // Remove any kits already grabbed + for(var/item in ckeys_redeemed_kits[user.ckey]) + possible_kits -= item + + if(length(possible_kits) == 1) + user.put_in_any_hand_if_possible(new /obj/item/storage/box/donator_kit(get_turf(src), user.ckey, possible_kits[possible_kits[1]])) + to_chat(user, SPAN_NOTICE("You retrieve your kit from [src].")) + LAZYADD(ckeys_redeemed_kits[user.ckey], possible_kits[1]) + return TRUE + + if(length(possible_kits) >= 2) + var/kit_choice = tgui_input_list(user, "Pick a kit to take:", "Donation Kit Selection", possible_kits) + if(!kit_choice) + to_chat(user, SPAN_NOTICE("You choose not to take any kits.")) + return TRUE + if(!user.Adjacent(src)) + to_chat(user, SPAN_NOTICE("You are too far from [src].")) + return TRUE + user.put_in_any_hand_if_possible(new /obj/item/storage/box/donator_kit(get_turf(src), user.ckey, possible_kits[kit_choice])) + to_chat(user, SPAN_NOTICE("You retrieve your kit from [src].")) + LAZYADD(ckeys_redeemed_kits[user.ckey], kit_choice) + return TRUE + +/obj/structure/machinery/personal_gear_vendor/attackby(obj/item/attacking_item, mob/user) + if(!istype(attacking_item, /obj/item/storage/box/donator_kit)) + return ..() + + var/obj/item/storage/box/donator_kit/kit = attacking_item + if(!kit.allowed(user)) + to_chat(user, SPAN_WARNING("[src] denies [kit].")) + return TRUE + to_chat(user, SPAN_NOTICE("You return [kit] to [src].")) + user.drop_held_item(kit) + kit.forceMove(src) + qdel(kit) + return TRUE + +/obj/item/storage/box/donator_kit + name = "personal gear kit" + desc = "A cardboard box stamped with a dollar sign and filled with trinkets. It contains someones personal possessions.." + icon = 'icons/obj/items/storage/kits.dmi' + icon_state = "donator_kit" + item_state = "giftbag" + max_w_class = SIZE_TINY + var/linked_ckey + +/obj/item/storage/box/donator_kit/get_examine_text(mob/user) + . = ..() + if(linked_ckey && user.ckey == linked_ckey) + . += SPAN_INFO("This kit can only be opened by you.") + . += SPAN_INFO("This kit can be deleted by returning it to the personal gear vendor.") + +/obj/item/storage/box/donator_kit/Initialize(mapload, owner_ckey, list/selected_kit) + . = ..() + if(owner_ckey) + linked_ckey = owner_ckey + + for(var/current_item in selected_kit) + new current_item(src) + +/obj/item/storage/box/donator_kit/open(mob/user) + if(!allowed(user)) + to_chat(user, SPAN_NOTICE("You do not have access to [src].")) + return + return ..() + +/obj/item/storage/box/donator_kit/empty(mob/user, turf/drop_to) + if(!allowed(user)) + to_chat(user, SPAN_NOTICE("You do not have access to [src].")) + return + return ..() + +/obj/item/storage/box/donator_kit/allowed(mob/user) + if(linked_ckey && user.ckey != linked_ckey) + return FALSE + return TRUE diff --git a/code/modules/cm_preds/yaut_actions.dm b/code/modules/cm_preds/yaut_actions.dm index 8930e133989d..444d83097b39 100644 --- a/code/modules/cm_preds/yaut_actions.dm +++ b/code/modules/cm_preds/yaut_actions.dm @@ -274,7 +274,7 @@ /datum/yautja_emote_panel/proc/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, "YautjaEmotes") + ui = new(user, src, "Emotes", "Yautja Audio Panel") ui.open() /datum/yautja_emote_panel/ui_data(mob/user) @@ -291,6 +291,7 @@ var/list/data = list() data["categories"] = yautja_categories + data["theme"] = "crtgreen" data["emotes"] = list() for(var/datum/emote/living/carbon/human/yautja/emote as anything in yautja_emotes) diff --git a/code/modules/customitems/item_spawning.dm b/code/modules/customitems/item_spawning.dm deleted file mode 100644 index e9733d0635ed..000000000000 --- a/code/modules/customitems/item_spawning.dm +++ /dev/null @@ -1,34 +0,0 @@ -//switch this out to use a database at some point -//list of ckey/ real_name and item paths -//gives item to specific people when they join if it can -//for multiple items just add mutliple entries, unless i change it to be a listlistlist -//yes, it has to be an item, you can't pick up nonitems - -GLOBAL_LIST_FILE_LOAD(custom_items, "config/custom_items.txt") - -/proc/EquipCustomItems(mob/living/carbon/human/M) - for(var/line in GLOB.custom_items) - // split & clean up - var/list/Entry = splittext(line, ":") - for(var/i = 1 to length(Entry)) - Entry[i] = trim(Entry[i]) - - if(length(Entry) < 2) - continue; - - if(Entry[1] == M.ckey) - var/list/Paths = splittext(Entry[2], ",") - for(var/P in Paths) - var/ok = FALSE // TRUE if the item was placed successfully - P = trim(P) - var/path = text2path(P) - if(!path) continue - - var/obj/item/Item = new path() - for(var/obj/item/storage/S in M.contents) // Try to place it in any item that can store stuff, on the mob. - if (S.handle_item_insertion(Item, TRUE)) - ok = TRUE - break - - if (ok == FALSE) // Finally, since everything else failed, place it on the ground - Item.forceMove(get_turf(M.loc)) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 60bd986b8393..26569bfed6b3 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -154,20 +154,6 @@ Contains most of the procs that are called when a mob is attacked by something return TRUE return FALSE -/mob/living/carbon/human/emp_act(severity) - . = ..() - for(var/obj/O in src) - if(!O) - continue - O.emp_act(severity) - for(var/obj/limb/O in limbs) - if(O.status & LIMB_DESTROYED) - continue - O.emp_act(severity) - for(var/datum/internal_organ/I in O.internal_organs) - if(I.robotic == FALSE) - continue - I.emp_act(severity) //Returns 1 if the attack hit, 0 if it missed. diff --git a/code/modules/mob/living/carbon/human/species/working_joe/_species.dm b/code/modules/mob/living/carbon/human/species/working_joe/_species.dm index 0273fe6b903f..64da16df062c 100644 --- a/code/modules/mob/living/carbon/human/species/working_joe/_species.dm +++ b/code/modules/mob/living/carbon/human/species/working_joe/_species.dm @@ -65,7 +65,7 @@ /datum/joe_emote_panel/proc/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, "JoeEmotes") + ui = new(user, src, "Emotes", "Working Joe Voice Synthesizer") ui.open() @@ -84,6 +84,7 @@ /datum/joe_emote_panel/ui_static_data(mob/user) var/list/data = list() + data["theme"] = "crtblue" data["categories"] = GLOB.wj_categories data["emotes"] = list() diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/burrower/burrower_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/burrower/burrower_abilities.dm index ad109583c43c..d8ee01d2d067 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/burrower/burrower_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/burrower/burrower_abilities.dm @@ -27,8 +27,5 @@ macro_path = /datum/action/xeno_action/verb/verb_tremor action_type = XENO_ACTION_CLICK ability_primacy = XENO_PRIMARY_ACTION_4 - -/datum/action/xeno_action/onclick/tremor/use_ability() - var/mob/living/carbon/xenomorph/X = owner - X.tremor() - return ..() + xeno_cooldown = 45 SECONDS + plasma_cost = 100 diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/burrower/burrower_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/burrower/burrower_powers.dm index 8117eade469a..62d8b60d1200 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/burrower/burrower_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/burrower/burrower_powers.dm @@ -187,44 +187,40 @@ T.tunnel_desc = "[new_name]" return -/datum/action/xeno_action/onclick/tremor/action_cooldown_check() - var/mob/living/carbon/xenomorph/xeno = owner - return !xeno.used_tremor -/mob/living/carbon/xenomorph/proc/tremor() //More support focused version of crusher earthquakes. - if(HAS_TRAIT(src, TRAIT_ABILITY_BURROWED) || is_ventcrawling) - to_chat(src, SPAN_XENOWARNING("We must be above ground to do this.")) +/datum/action/xeno_action/onclick/tremor/use_ability(atom/target) + var/mob/living/carbon/xenomorph/burrower_tremor = owner + + if (HAS_TRAIT(burrower_tremor, TRAIT_ABILITY_BURROWED)) + to_chat(burrower_tremor, SPAN_XENOWARNING("We must be above ground to do this.")) return - if(!check_state()) + if (burrower_tremor.is_ventcrawling) + to_chat(burrower_tremor, SPAN_XENOWARNING("We must be above ground to do this.")) return - if(used_tremor) - to_chat(src, SPAN_XENOWARNING("We aren't ready to cause more tremors yet!")) + if (!action_cooldown_check()) + return + + if (!burrower_tremor.check_state()) + return + if (!check_and_use_plasma_owner()) return - if(!check_plasma(100)) return + playsound(burrower_tremor, 'sound/effects/alien_footstep_charge3.ogg', 75, 0) + to_chat(burrower_tremor, SPAN_XENOWARNING("We dig ourselves into the ground and cause tremors.")) + burrower_tremor.create_stomp() - use_plasma(100) - playsound(loc, 'sound/effects/alien_footstep_charge3.ogg', 75, 0) - visible_message(SPAN_XENODANGER("[src] digs itself into the ground and shakes the earth itself, causing violent tremors!"), \ - SPAN_XENODANGER("We dig into the ground and shake it around, causing violent tremors!")) - create_stomp() //Adds the visual effect. Wom wom wom - used_tremor = 1 - for(var/mob/living/carbon/carbon_target in range(7, loc)) + for(var/mob/living/carbon/carbon_target in range(7, burrower_tremor)) to_chat(carbon_target, SPAN_WARNING("You struggle to remain on your feet as the ground shakes beneath your feet!")) shake_camera(carbon_target, 2, 3) - if(get_dist(loc, carbon_target) <= 3 && !src.can_not_harm(carbon_target)) + if(get_dist(burrower_tremor, carbon_target) <= 3 && !burrower_tremor.can_not_harm(carbon_target)) if(carbon_target.mob_size >= MOB_SIZE_BIG) carbon_target.apply_effect(1, SLOW) else carbon_target.apply_effect(1, WEAKEN) to_chat(carbon_target, SPAN_WARNING("The violent tremors make you lose your footing!")) - spawn(caste.tremor_cooldown) - used_tremor = 0 - to_chat(src, SPAN_NOTICE("We gather enough strength to cause tremors again.")) - for(var/X in actions) - var/datum/action/act = X - act.update_button_icon() + apply_cooldown() + return ..() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Burrower.dm b/code/modules/mob/living/carbon/xenomorph/castes/Burrower.dm index 106dcdcacb62..c691a68659fb 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Burrower.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Burrower.dm @@ -31,7 +31,7 @@ burrow_cooldown = 20 tunnel_cooldown = 70 widen_cooldown = 70 - tremor_cooldown = 450 + minimum_evolve_time = 7 MINUTES diff --git a/code/modules/mob/living/carbon/xenomorph/say.dm b/code/modules/mob/living/carbon/xenomorph/say.dm index 9f99cdb45455..650351c14fd2 100644 --- a/code/modules/mob/living/carbon/xenomorph/say.dm +++ b/code/modules/mob/living/carbon/xenomorph/say.dm @@ -107,6 +107,9 @@ to_chat(src, SPAN_WARNING("There is no Queen. You are alone.")) return + if(!filter_message(src, message)) + return + log_hivemind("[key_name(src)] : [message]") var/track = "" diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 66dee6ef9fa2..e80538353210 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -291,7 +291,8 @@ var/mob/living/carbon/human/character = create_character(TRUE) //creates the human and transfers vars and mind GLOB.RoleAuthority.equip_role(character, player_rank, late_join = TRUE) - EquipCustomItems(character) + if(character.ckey in GLOB.donator_items) + to_chat(character, SPAN_BOLDNOTICE("You have gear available in the personal gear vendor near Requisitions.")) if((GLOB.security_level > SEC_LEVEL_BLUE || SShijack.hijack_status) && player_rank.gets_emergency_kit) to_chat(character, SPAN_HIGHDANGER("As you stagger out of hypersleep, the sleep bay blares: '[SShijack.evac_status ? "VESSEL UNDERGOING EVACUATION PROCEDURES, SELF DEFENSE KIT PROVIDED" : "VESSEL IN HEIGHTENED ALERT STATUS, SELF DEFENSE KIT PROVIDED"]'.")) diff --git a/code/modules/organs/limbs.dm b/code/modules/organs/limbs.dm index 333bc9c524f9..8e9a755a2ea0 100644 --- a/code/modules/organs/limbs.dm +++ b/code/modules/organs/limbs.dm @@ -186,6 +186,10 @@ droplimb(0, 0, "EMP") else take_damage(damage, 0, 1, 1, used_weapon = "EMP") + for(var/datum/internal_organ/internal_organ in internal_organs) + if(internal_organ.robotic == FALSE) + continue + internal_organ.emp_act(severity) /// If this limb can be dropped as a result of an EMP /obj/limb/proc/can_emp_delimb() diff --git a/code/modules/projectiles/guns/rifles.dm b/code/modules/projectiles/guns/rifles.dm index ff7cfbf21c8b..3192244d1e20 100644 --- a/code/modules/projectiles/guns/rifles.dm +++ b/code/modules/projectiles/guns/rifles.dm @@ -1664,7 +1664,7 @@ /obj/item/weapon/gun/rifle/l42a/abr40 name = "\improper ABR-40 hunting rifle" - desc = "The civilian version of the L42A battle rifle. Almost identical and even cross-compatible with L42 magazines, just don't take the stock off.." + desc = "The civilian version of the L42A battle rifle. Almost identical and even cross-compatible with L42 magazines, just don't take the stock off." desc_lore = "The ABR-40 was created along-side the L42A as a hunting rifle for civilians. Sporting faux wooden furniture and a legally-mandated 12 round magazine, it's still highly accurate and deadly, a favored pick of experienced hunters and retired Marines. However, it's very limited in attachment selection, only being able to fit rail attachments, and the differences in design from the L42 force an awkward pose when attempting to hold it one-handed. Removing the stock is not recommended." icon = 'icons/obj/items/weapons/guns/guns_by_faction/colony.dmi' icon_state = "abr40" diff --git a/colonialmarines.dme b/colonialmarines.dme index 7e1ed4d91f5c..423b66356dd5 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -1651,8 +1651,8 @@ #include "code\modules\cm_marines\altitude_control_console.dm" #include "code\modules\cm_marines\anti_air.dm" #include "code\modules\cm_marines\codebook.dm" +#include "code\modules\cm_marines\custom_items.dm" #include "code\modules\cm_marines\Donator_Items.dm" -#include "code\modules\cm_marines\Donator_Kits.dm" #include "code\modules\cm_marines\dropship_ammo.dm" #include "code\modules\cm_marines\dropship_equipment.dm" #include "code\modules\cm_marines\m2c.dm" @@ -1725,7 +1725,6 @@ #include "code\modules\cm_tech\techs\marine\tier3\cryorine.dm" #include "code\modules\cm_tech\techs\marine\tier4\nuke.dm" #include "code\modules\cm_tech\trees\marine.dm" -#include "code\modules\customitems\item_spawning.dm" #include "code\modules\decorators\admin_runtime_decorator.dm" #include "code\modules\decorators\cassette_decorator.dm" #include "code\modules\decorators\christmas.dm" diff --git a/html/changelogs/AutoChangeLog-pr-7567.yml b/html/changelogs/AutoChangeLog-pr-7567.yml new file mode 100644 index 000000000000..a56f55b2b5f8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7567.yml @@ -0,0 +1,4 @@ +author: "Red-byte3D" +delete-after: True +changes: + - code_imp: "rewrote tremor code" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-7571.yml b/html/changelogs/AutoChangeLog-pr-7571.yml new file mode 100644 index 000000000000..d72f42d335bf --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7571.yml @@ -0,0 +1,4 @@ +author: "An A Jay" +delete-after: True +changes: + - balance: "Gave predators the ability to cut through fences" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-7590.yml b/html/changelogs/AutoChangeLog-pr-7590.yml new file mode 100644 index 000000000000..1d26f928366d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7590.yml @@ -0,0 +1,4 @@ +author: "harryob" +delete-after: True +changes: + - ui: "adds a search bar to the pred/wj emote panels" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-7592.yml b/html/changelogs/AutoChangeLog-pr-7592.yml new file mode 100644 index 000000000000..1ea40b7b367b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7592.yml @@ -0,0 +1,4 @@ +author: "zzzmike" +delete-after: True +changes: + - qol: "nuclear device messaging more helpful for newbies" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-7593.yml b/html/changelogs/AutoChangeLog-pr-7593.yml new file mode 100644 index 000000000000..94f591ffdf5f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7593.yml @@ -0,0 +1,4 @@ +author: "AlanParkerMasters" +delete-after: True +changes: + - rscdel: "A single period from the ABR-40 description that shouldn't be there." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-7605.yml b/html/changelogs/AutoChangeLog-pr-7605.yml new file mode 100644 index 000000000000..070ba7d97877 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7605.yml @@ -0,0 +1,4 @@ +author: "cuberound" +delete-after: True +changes: + - bugfix: "emp act is called once on each limb not three time" \ No newline at end of file diff --git a/html/changelogs/archive/2024-11.yml b/html/changelogs/archive/2024-11.yml index b7d7e72a17c3..f274f989045f 100644 --- a/html/changelogs/archive/2024-11.yml +++ b/html/changelogs/archive/2024-11.yml @@ -268,3 +268,20 @@ - bugfix: makes UPP synth lobby joinable for events zzzmike: - rscadd: tip of the round regarding lesser known cryotube utility +2024-11-16: + BeagleGaming1: + - rscadd: Adds the personal gear vendor, where people can get their donator items + or a random loadout item + - rscadd: Custom Items can be gotten from Requisitions instead of spawning with + them + - config: Changes to config/custom_items.txt +2024-11-18: + Drulikar: + - code_imp: dmm_test now checks if there are pending mapmerge2 conversions. + - code_imp: Improved dmm_test error handling + - code_imp: mapmerge2 now uses keys sequentially rather than randomly. + - code_imp: mapmerge2 fixup script now assigns upstream remote if needed, and checks/fixes + pending mapmerge2 conversions. + SASoperative: + - rscadd: Personal Gear Vendor allows retrieval of additional kits for multi-kit + donators diff --git a/maps/map_files/USS_Almayer/USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm index dce44a720577..e85786719749 100644 --- a/maps/map_files/USS_Almayer/USS_Almayer.dmm +++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm @@ -45261,6 +45261,10 @@ /obj/structure/machinery/light{ dir = 8 }, +/obj/structure/machinery/personal_gear_vendor{ + dir = 8; + pixel_x = -4 + }, /turf/open/floor/almayer/plate, /area/almayer/squads/req) "oMi" = ( diff --git a/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm b/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm index 2129895439fb..0727066a1b51 100644 --- a/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm +++ b/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm @@ -4394,6 +4394,9 @@ /area/whiskey_outpost/outside/south) "tj" = ( /obj/structure/machinery/light/small, +/obj/structure/machinery/personal_gear_vendor{ + pixel_x = 6 + }, /turf/open/floor/asteroidfloor/north, /area/whiskey_outpost) "tk" = ( diff --git a/tgui/packages/tgui/components/Input.tsx b/tgui/packages/tgui/components/Input.tsx index 82b0d1904236..dce80c7a8a18 100644 --- a/tgui/packages/tgui/components/Input.tsx +++ b/tgui/packages/tgui/components/Input.tsx @@ -164,6 +164,9 @@ export function Input(props: Props) { monospace && 'Input--monospace', className, ])} + onClick={() => { + inputRef.current?.focus(); + }} {...rest} >
.
diff --git a/tgui/packages/tgui/interfaces/JoeEmotes.tsx b/tgui/packages/tgui/interfaces/Emotes.tsx similarity index 71% rename from tgui/packages/tgui/interfaces/JoeEmotes.tsx rename to tgui/packages/tgui/interfaces/Emotes.tsx index 7bb347c7048c..83f19fc5ff5b 100644 --- a/tgui/packages/tgui/interfaces/JoeEmotes.tsx +++ b/tgui/packages/tgui/interfaces/Emotes.tsx @@ -1,8 +1,16 @@ +import { BooleanLike } from 'common/react'; import { useState } from 'react'; -import { BooleanLike } from '../../common/react'; import { useBackend } from '../backend'; -import { Box, Button, Divider, Section, Stack, Tabs } from '../components'; +import { + Box, + Button, + Divider, + Input, + Section, + Stack, + Tabs, +} from '../components'; import { Window } from '../layouts'; type Emote = { @@ -16,15 +24,22 @@ type BackendContext = { categories: string[]; emotes: Emote[]; on_cooldown: BooleanLike; + theme: string; }; -const EmoteTab = (props) => { +const EmoteTab = () => { const { data, act } = useBackend(); const { categories, emotes, on_cooldown } = data; - const [categoryIndex, setCategoryIndex] = useState('Farewell'); + const [categoryIndex, setCategoryIndex] = useState(categories[0]); + + const [search, setSearch] = useState(''); + const mapped_emote = emotes.filter( - (emote) => emote && emote.category === categoryIndex, + (emote) => + (emote && !search && emote.category === categoryIndex) || + (search && emote.text.toLowerCase().includes(search.toLowerCase())), ); + return ( @@ -35,11 +50,21 @@ const EmoteTab = (props) => { }} > + setSearch(val)} + onEnter={() => { + mapped_emote[0] + ? act('emote', { emotePath: mapped_emote[0].path }) + : null; + }} + /> {categories.map((item, key) => ( { + setSearch(''); setCategoryIndex(item); }} > @@ -73,8 +98,8 @@ const EmoteTab = (props) => { - - - - - ))} - - - - - ); -}; - -export const YautjaEmotes = (props) => { - return ( - - - - - - ); -}; diff --git a/tools/maplint/source/dmm.py b/tools/maplint/source/dmm.py index 0a1045e1b838..46329f9c3508 100644 --- a/tools/maplint/source/dmm.py +++ b/tools/maplint/source/dmm.py @@ -94,7 +94,12 @@ def parse_pop(self): break elif content_end == "{": while (var_edit := self.parse_var_edit()) is not None: + if var_edit[0] == None and var_edit[1] == None: + break content.var_edits[var_edit[0]] = var_edit[1] + else: + continue # inner loop didn't break + break # inner loop did break indicating a }) elif content_end == ",": continue @@ -106,6 +111,8 @@ def parse_var_edit(self): line = self.next_line() if line == "\t},": return None + if line == "\t})": + return None, None var_edit_match = REGEX_VAR_EDIT.match(line) self.expect(var_edit_match is not None, "Var edits ended too early, expected a newline in between.") @@ -128,6 +135,8 @@ def parse_constant(self, constant): return Filename(constant[1:-1]) elif (list_match := re.match(r'^list\((?P.*)\)$', constant)): return ["NYI: list"] + elif (list_match := re.match(r'^newlist\((?P.*)\)$', constant)): + return ["NYI: newlist"] else: self.raise_error(f"Unknown constant type: {constant}") diff --git a/tools/mapmerge2/dmm.py b/tools/mapmerge2/dmm.py index bc12a39b3556..d44ddaa1a3a8 100644 --- a/tools/mapmerge2/dmm.py +++ b/tools/mapmerge2/dmm.py @@ -11,7 +11,7 @@ Coordinate = namedtuple('Coordinate', ['x', 'y', 'z']) class DMM: - __slots__ = ['key_length', 'size', 'dictionary', 'grid', 'header'] + __slots__ = ['key_length', 'size', 'dictionary', 'grid', 'header', 'lowest_free'] def __init__(self, key_length, size): self.key_length = key_length @@ -19,6 +19,7 @@ def __init__(self, key_length, size): self.dictionary = bidict.bidict() self.grid = {} self.header = None + self.lowest_free = 0 @staticmethod def from_file(fname): @@ -60,10 +61,14 @@ def set_tile(self, coord, tile): def generate_new_key(self): self._ensure_free_keys(1) max_key = max_key_for(self.key_length) - # choose one of the free keys at random - key = random.randint(0, max_key - 1) + # choose one of the free keys + key = self.lowest_free while key in self.dictionary: - key = random.randint(0, max_key - 1) + key = key + 1 + if key >= max_key: + print("The value for lowest_free was invalid!") + key = 0 + self.lowest_free = key return key def overwrite_key(self, key, fixed, bad_keys): @@ -90,6 +95,7 @@ def remove_unused_keys(self, modified_keys = None): unused_keys.remove(key) for key in unused_keys: del self.dictionary[key] + self.lowest_free = 0 def _presave_checks(self): # last-second handling of bogus keys to help prevent and fix broken maps diff --git a/tools/mapmerge2/dmm_test.py b/tools/mapmerge2/dmm_test.py index 02f5383f2abb..306e45fdb7a3 100644 --- a/tools/mapmerge2/dmm_test.py +++ b/tools/mapmerge2/dmm_test.py @@ -1,25 +1,88 @@ import os import sys +import pygit2 + from .dmm import * +from .mapmerge import merge_map + +def green(text): + return "\033[32m" + str(text) + "\033[0m" + +def red(text): + return "\033[31m" + str(text) + "\033[0m" + +def has_tgm_header(fname): + with open(fname, 'r', encoding=ENCODING) as f: + data = f.read(len(TGM_HEADER)) + return data.startswith(TGM_HEADER) +class LintException(Exception): + pass def _self_test(): - # test: can we load every DMM in the tree + repo = pygit2.Repository(pygit2.discover_repository(os.getcwd())) + + # Read the HEAD and ancestor commits + # Assumption: origin on the runner is what we'd normally call upstream + ancestor = repo.merge_base(repo.head.target, repo.revparse_single("refs/remotes/origin/master").id) + ancestor_commit = None + if not ancestor: + print("Unable to determine merge base!") + else: + ancestor_commit = repo[ancestor] + print("Determined ancestor commit SHA to be:", ancestor) + count = 0 + failed = 0 for dirpath, dirnames, filenames in os.walk('.'): if '.git' in dirnames: dirnames.remove('.git') for filename in filenames: if filename.endswith('.dmm'): fullpath = os.path.join(dirpath, filename) + path = fullpath.replace("\\", "/").removeprefix("./") try: - DMM.from_file(fullpath) + # test: can we load every DMM + index_map = DMM.from_file(fullpath) + + # test: is every DMM in TGM format + if not has_tgm_header(fullpath): + raise LintException('Map is not in TGM format! Please run `/tools/mapmerge2/I Forgot To Map Merge.bat`') + + # test: does every DMM convert cleanly + if ancestor_commit: + try: + ancestor_blob = ancestor_commit.tree[path] + except KeyError: + # New map, no entry in ancestor + print("New map? Could not find ancestor version of", path) + merged_map = merge_map(index_map, index_map) # basically only tests unused keys + original_bytes = index_map.to_bytes() + merged_bytes = merged_map.to_bytes() + if original_bytes != merged_bytes: + raise LintException('New map is pending updates! Please run `/tools/mapmerge2/I Forgot To Map Merge.bat`') + else: + # Entry in ancestor, merge the index over it + ancestor_map = DMM.from_bytes(ancestor_blob.read_raw()) + merged_map = merge_map(index_map, ancestor_map) + original_bytes = index_map.to_bytes() + merged_bytes = merged_map.to_bytes() + if original_bytes != merged_bytes: + raise LintException('Map is pending updates! Please run `/tools/mapmerge2/I Forgot To Map Merge.bat`') + except LintException as error: + failed += 1 + print(red(f'Failed on: {path}')) + print(error) except Exception: - print('Failed on:', fullpath) + failed += 1 + print(red(f'Failed on: {path}')) raise count += 1 - print(f"{os.path.relpath(__file__)}: successfully parsed {count} .dmm files") + print(f"{os.path.relpath(__file__)}: {green(f'successfully parsed {count-failed} .dmm files')}") + if failed > 0: + print(f"{os.path.relpath(__file__)}: {red(f'failed to parse {failed} .dmm files')}") + exit(1) def _usage(): diff --git a/tools/mapmerge2/fixup.py b/tools/mapmerge2/fixup.py index 6953e7ab7782..42b83cff44ec 100644 --- a/tools/mapmerge2/fixup.py +++ b/tools/mapmerge2/fixup.py @@ -40,7 +40,7 @@ def insert_into_tree(repo, tree_builder, path, blob_oid): tree_builder.insert(first, inner.write(), pygit2.GIT_FILEMODE_TREE) -def main(repo): +def main(repo : pygit2.Repository): if repo.index.conflicts: print("You need to resolve merge conflicts first.") return 1 @@ -51,54 +51,65 @@ def main(repo): continue if status & STATUS_INDEX: print("You have changes staged for commit. Commit them or unstage them first.") - print("If you are about to commit maps for the first time, run `Run Before Committing.bat`.") + print("If you are about to commit maps for the first time and can't use hooks, run `Run Before Committing.bat`.") return 1 if path.endswith(".dmm") and (status & STATUS_WT): print("You have modified maps. Commit them first.") - print("If you are about to commit maps for the first time, run `Run Before Committing.bat`.") + print("If you are about to commit maps for the first time and can't use hooks, run `Run Before Committing.bat`.") return 1 - # Read the HEAD commit. - head_commit = repo[repo.head.target] - head_files = {} - for path, blob in walk_tree(head_commit.tree): - if path.endswith(".dmm"): - data = blob.read_raw() - if not data.startswith(TGM_HEADER): - head_files[path] = dmm.DMM.from_bytes(data) + # Set up upstream remote if needed + try: + repo.remotes.create("upstream", "https://github.com/cmss13-devs/cmss13.git") + except ValueError: + pass + else: + print("Adding upstream remote...") - if not head_files: - print("All committed maps appear to be in the correct format.") - print("If you are about to commit maps for the first time, run `Run Before Committing.bat`.") + # Read the HEAD and ancestor commits. + head_commit = repo[repo.head.target] + repo.remotes["upstream"].fetch() + ancestor = repo.merge_base(repo.head.target, repo.revparse_single("refs/remotes/upstream/master").id) + if not ancestor: + print("Unable to automatically fix anything because merge base could not be determined.") return 1 + ancestor_commit = repo[ancestor] + print("Determined ancestor commit SHA to be:", ancestor) - # Work backwards to find a base for each map, converting as found. + # Walk the head commit tree and convert as needed converted = {} - if len(head_commit.parents) != 1: - print("Unable to automatically fix anything because HEAD is a merge commit.") - return 1 commit_message_lines = [] - working_commit = head_commit.parents[0] - while len(converted) < len(head_files): - for path in head_files.keys() - converted.keys(): + for path, blob in walk_tree(head_commit.tree): + if path.endswith(".dmm"): + head_data = blob.read_raw() + head_map = dmm.DMM.from_bytes(head_data) + + # test: does every DMM convert cleanly (including TGM conversion) try: - blob = working_commit.tree[path] + ancestor_blob = ancestor_commit.tree[path] except KeyError: - commit_message_lines.append(f"{'new':{ABBREV_LEN}}: {path}") - print(f"Converting new map: {path}") - converted[path] = head_files[path] + # New map, no entry in ancestor + merged_map = merge_map(head_map, head_map) + merged_bytes = merged_map.to_bytes() + if head_data != merged_bytes: + print(f"Updating new map: {path}") + commit_message_lines.append(f"{'new':{ABBREV_LEN}}: {path}") + converted[path] = merged_map else: - data = blob.read_raw() - if data.startswith(TGM_HEADER): - str_id = str(working_commit.id)[:ABBREV_LEN] + # Entry in ancestor + ancestor_map = dmm.DMM.from_bytes(ancestor_blob.read_raw()) + merged_map = merge_map(head_map, ancestor_map) + merged_bytes = merged_map.to_bytes() + if head_data != merged_bytes: + print(f"Updating map: {path}") + str_id = str(ancestor_commit.id)[:ABBREV_LEN] commit_message_lines.append(f"{str_id}: {path}") - print(f"Converting map: {path}") - converted[path] = merge_map(head_files[path], dmm.DMM.from_bytes(data)) - if len(working_commit.parents) != 1: - print("A merge commit was encountered before good versions of these maps were found:") - print("\n".join(f" {x}" for x in head_files.keys() - converted.keys())) - return 1 - working_commit = working_commit.parents[0] + converted[path] = merged_map + + if not converted: + print("All committed maps appear to be okay.") + print("If you are about to commit maps for the first time and can't use hooks, run `Run Before Committing.bat`.") + return 1 # Okay, do the actual work. tree_builder = repo.TreeBuilder(head_commit.tree) @@ -118,7 +129,7 @@ def main(repo): repo.head.name, signature, # author signature, # committer - f'Convert maps to TGM\n\n{joined}\n\nAutomatically commited by: {os.path.relpath(__file__, repo.workdir)}', + f'Fixup maps in TGM format\n\n{joined}\n\nAutomatically commited by: {os.path.relpath(__file__, repo.workdir)}', tree_builder.write(), [head_commit.id], ) diff --git a/tools/mapmerge2/mapmerge.py b/tools/mapmerge2/mapmerge.py index d9cdea24cfb6..43d2696c4be8 100644 --- a/tools/mapmerge2/mapmerge.py +++ b/tools/mapmerge2/mapmerge.py @@ -4,7 +4,7 @@ from . import frontend from .dmm import * -def merge_map(new_map, old_map, delete_unused=False): +def merge_map(new_map, old_map, delete_unused=True, suppress_notices=False): if new_map.key_length != old_map.key_length: print("Warning: Key lengths differ, taking new map") print(f" Old: {old_map.key_length}") @@ -65,8 +65,9 @@ def select_key(assigned): select_key(fresh_key) # step two: delete unused keys - if unused_keys: - #print(f"Notice: Trimming {len(unused_keys)} unused dictionary keys.") + if unused_keys and delete_unused: + if not suppress_notices: + print(f"Notice: Trimming {len(unused_keys)} unused dictionary keys.") for key in unused_keys: del merged.dictionary[key]