From b650d3298e23a3d6eb6481c5f98b7a1d25116af0 Mon Sep 17 00:00:00 2001 From: Vasilis The Pikachu Date: Mon, 7 Jul 2025 00:01:55 +0200 Subject: [PATCH 1/6] Revert "HoP's beret (#38601)" This reverts commit e9c90fe66dec0ed9579847807d9babe934a66bae. Please check the maintainer meeting for details --- .../Catalog/Fills/Lockers/dressers.yml | 1 - .../Entities/Clothing/Head/hats.yml | 17 ---------- .../Jobs/Command/head_of_personnel.yml | 5 --- .../Prototypes/Loadouts/loadout_groups.yml | 1 - .../Recipes/Lathes/Packs/clothing.yml | 1 - .../Prototypes/Recipes/Lathes/clothing.yml | 5 --- .../beret_hop.rsi/equipped-HELMET-hamster.png | Bin 861 -> 0 bytes .../Hats/beret_hop.rsi/equipped-HELMET.png | Bin 902 -> 0 bytes .../Clothing/Head/Hats/beret_hop.rsi/icon.png | Bin 415 -> 0 bytes .../Head/Hats/beret_hop.rsi/inhand-left.png | Bin 695 -> 0 bytes .../Head/Hats/beret_hop.rsi/inhand-right.png | Bin 789 -> 0 bytes .../Head/Hats/beret_hop.rsi/meta.json | 30 ------------------ 12 files changed, 60 deletions(-) delete mode 100644 Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/equipped-HELMET-hamster.png delete mode 100644 Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/equipped-HELMET.png delete mode 100644 Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/icon.png delete mode 100644 Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/inhand-left.png delete mode 100644 Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/inhand-right.png delete mode 100644 Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/meta.json diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml b/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml index 237b8a4748..e111b51cff 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml @@ -50,7 +50,6 @@ - type: StorageFill contents: - id: ClothingHeadHatHopcap - - id: ClothingHeadHatBeretHop - id: ClothingOuterWinterHoP - id: ClothingEyesGlasses - id: ClothingNeckCloakHop diff --git a/Resources/Prototypes/Entities/Clothing/Head/hats.yml b/Resources/Prototypes/Entities/Clothing/Head/hats.yml index 26e0c6aba2..ec7801802b 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hats.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hats.yml @@ -1360,20 +1360,3 @@ path: /Audio/Items/flashlight_on.ogg soundDeactivate: path: /Audio/Items/flashlight_off.ogg - -- type: entity - parent: ClothingHeadBase - id: ClothingHeadHatBeretHop - name: head of personnel's beret - description: A dark blue beret with a ruby inserted in the center, for true connoisseurs of bureaucracy! - components: - - type: Sprite - sprite: Clothing/Head/Hats/beret_hop.rsi - - type: Clothing - sprite: Clothing/Head/Hats/beret_hop.rsi - - type: Tag - tags: - - HamsterWearable - - ClothMade - - Recyclable - - WhitelistChameleon \ No newline at end of file diff --git a/Resources/Prototypes/Loadouts/Jobs/Command/head_of_personnel.yml b/Resources/Prototypes/Loadouts/Jobs/Command/head_of_personnel.yml index 0855100e61..45223bea14 100644 --- a/Resources/Prototypes/Loadouts/Jobs/Command/head_of_personnel.yml +++ b/Resources/Prototypes/Loadouts/Jobs/Command/head_of_personnel.yml @@ -35,11 +35,6 @@ equipment: head: ClothingHeadHatHopcap -- type: loadout - id: HoPBeret - equipment: - head: ClothingHeadHatBeretHop - # Neck - type: loadout id: HoPCloak diff --git a/Resources/Prototypes/Loadouts/loadout_groups.yml b/Resources/Prototypes/Loadouts/loadout_groups.yml index b3c8aa8129..39b6be2b04 100644 --- a/Resources/Prototypes/Loadouts/loadout_groups.yml +++ b/Resources/Prototypes/Loadouts/loadout_groups.yml @@ -153,7 +153,6 @@ minLimit: 0 loadouts: - HoPHead - - HoPBeret - type: loadoutGroup id: HoPJumpsuit diff --git a/Resources/Prototypes/Recipes/Lathes/Packs/clothing.yml b/Resources/Prototypes/Recipes/Lathes/Packs/clothing.yml index 808f1c680a..aa95781729 100644 --- a/Resources/Prototypes/Recipes/Lathes/Packs/clothing.yml +++ b/Resources/Prototypes/Recipes/Lathes/Packs/clothing.yml @@ -33,7 +33,6 @@ - ClothingUniformJumpskirtCapFormalDress # HoP - ClothingHeadHatHopcap - - ClothingHeadHatBeretHop - ClothingUniformJumpsuitHoP - ClothingUniformJumpskirtHoP # Generic diff --git a/Resources/Prototypes/Recipes/Lathes/clothing.yml b/Resources/Prototypes/Recipes/Lathes/clothing.yml index cf6e082b64..c5f81153e2 100644 --- a/Resources/Prototypes/Recipes/Lathes/clothing.yml +++ b/Resources/Prototypes/Recipes/Lathes/clothing.yml @@ -810,11 +810,6 @@ id: ClothingHeadHatHopcap result: ClothingHeadHatHopcap -- type: latheRecipe - parent: BaseCommandHatRecipe - id: ClothingHeadHatBeretHop - result: ClothingHeadHatBeretHop - - type: latheRecipe parent: BaseCommandHatRecipe id: ClothingHeadHatQMsoft diff --git a/Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/equipped-HELMET-hamster.png b/Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/equipped-HELMET-hamster.png deleted file mode 100644 index b55441dd0200112d64aeb49b73363a558b8b50b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 861 zcmV-j1ETziP)Px&7fD1xRCt{2n$K<$Q543%!wd|}3>0ZF!G&V$q8mY|?yQOFLl}J$;}f`ZZ{jnk z%P#6d7fnTI#EnL2bRovZwzTw*1H)VwQ%aEN^4SXLOGEVUE{ktu(RzhnJg+s!jlfU9K1d+Fgx!CX>I`Z+OfM8jijfX zw(Wf{y8{5KmNj^QQ#l~4^|qTEz`|20Evj_nA79$xx3|jP2 zvafUo6wM?-075vvL>?Pljrp1e|KdhGMWKj}@Wd4zAKvWA^zn2RI73JsJaB#ukcJHi zT0qdS0YM808a5zk0YM{wD=dLx>Yn@9jnlgk^269?z}OpbqA8$Xz6Kn;)#>bRLD;tE zF|_1l-?r6Q|9_{}J{$_c?zEt)Q3x&WIc^tU21L?nUk7^}_IkZImAbnEinrKH4$ zULs$)I4uxQVfNQI%K!XKh#GF2PdsNp)mD1-`R;!O%me`7ac#-34r%T+*YNQ6eHg{N z*eWgHPST{;4T!SU7PDxQh#TbC~{c3Va<1qkIuvDRuri@86< zoT1U47WOrm=P6K#X@u2kui;Y(IZdH_SQ%N_e5TbrwOGDRf_W`M?+Mb55U? n8HQmPhG7_nVHk#C&Le*S@*URI3?Lay00000NkvXXu0mjfITU{1 diff --git a/Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/equipped-HELMET.png deleted file mode 100644 index 1b491f4c1e01f3517a915758c74236b902386ee6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 902 zcmV;119|+3P)Px&KuJVFRCt{2noV!iMi|F`W3Sg{Hx5Z?BsK@SNgyGrSaE0&cTR{4UxjNwK(BlV zdf?Xb0Z?x}utB^@gcaSC3TdkbX+g>6#f?Xfz?7fT*sInHC)psxKNJ0UcFU%(Qg;cmf(tXf#=h;!^RA1b84KT|9tH zV0(k#?%n36KYoF!*<%-BB^=Ym2jTw3!J0lAP1<4IIDVz*#N|dy5l`sB+c&WC6o8wT zuIX#NE&#d83kUb|;&b=di95vnqCQ7;+MqCav=nx7E&|Lppyjnp4e82u$3@t;8v_vMP z++exWR(hNY6A6m10JI1Sfx!y<&-fwV6p9@D$jHw4SKwR231B+`+c*JiCtw>Vfb9fq z;{>psfNh)rwiB?8(O%$VPG49g2!f$&{Xd@-wpWSyzd^hBeva>lNGYk+#*uQPw69VE zOrE>U=XUbr)AOa0=)ZVecy6tJaLZi{M@f=Ryb|lVumImpFYXVr%skQ|#G|K=#E;BD z`DQjJ{vF^1u$_QyoB*~Hu#FSIb^^9>0@zN#HckNB2^;~ZzQ(xJW@zcum?8tR;b!cW zz`SK7dw&_ne>6F_A9$xJOQptzbYL9cSb(K!th>Y`qX+Ii_~(_n63Aoin?0JG+i%ei z)?j`D*82dw>~+-wsZo3*0S+sk!J3JyJ#G%(8O^```d5CwaZ3+IMs?hHM}(5Wwp z$CD_74^+w&e;gRU1Q*gZA%xG?=4wTFQR;i1aWVgw;vEi$!{Kl^91e%W;cz${4u`|x caGWeY0FgZS$LjglR{#J207*qoM6N<$f*Mz(od5s; diff --git a/Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/icon.png b/Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/icon.png deleted file mode 100644 index 09a41f29640f6515cbfa07f62c7fcb6f7970545e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 415 zcmV;Q0bu@#P)Px$SxH1eR9J=Wlg~;5Q5431cQj|h3KGUr2t-A+g}W9$LEE09hv)%%h+d+$JwfE6 zMGFlbrIkWLfu)S7b6Z%b{h51>7D4y7y@&IC=R4mX62ypjRW*^yrgFS40{@d*5ZR!>V;ycu)V;xGM~IDiw^ z>Z_H2=OiWBGHkow3&Zl{zh$5u-G=6wG4_9a#5 zAE7^(#ky!>&Hi+7RoCTow+ujO`Yh^-w#t86C>_v z$omh%bCU9-XkpS9!Nf-f6GU{Kh$RSuDKZFU@G)vg?}GQ&xDDbuI%n(cVJu&!EpWMY znQw#H#jK$2Z5PZ^Wcs?5uRL_Gv-xK5@_UZov*$I>ZO;Ec_Z(q46nKD(v24xe{U2D9L^vNOtEBX-WUB~LC?9Vt84MDl$r#XTv&{FLbN9Y-BMzZsjXVBVz$7;;oF}Et^Lhu=l4xAU&Fj)LY>gA z$X|hKmrbmdro9eb`nqA0t3mL6bq9vDh)_@Y)4jGz0wMZLr^F5}IK))Keu0+qN9(PwRi&r&X{m#%ph!d(#bz2^43>Qyy8D@6?It?M(BGerw#3d_1Eh&xUNn|v6} zI-jSDKPY&0F1;u2ysf$B@$Dn)PctbmNU&zw?D_NT0r~rK3=V<5!%8Pv9?a; z=NC-S-S{NJY{*}L-pB}+k5!OoyRO#dIv W|6@FrYYH$WGI+ZBxvXPx%&q+ioGvoZ{_ZeHs48Sl9 z!!QiPFbu;m40FaH0GOPdMlv@F0-=x|l)*tac79Xc+K1D3&YeUW5@{1wbrXiB0px&0 zKOAchB9RFt$f~S{nlFTgrL5VO!_3|v0s!gMQCwVT#&!RoLV8eQXav~Z2CP~$UIgT| zjWrUrO4Ee6vXnI?k}1IG1Jc=Myzm{;Gr^DWJ`~gEB{F%p(MbO3!UNo2d;%m>c$2@_ z=4!7Ad-s=fLvHebn?vQ7douxGXat2+dv)so@LmkM$)~gKq;d%WaQEs>cT}TYv$tSG zSOJwE@4{VRf4@C8I`yxjGkFvNiN?|g{7b-dtX#qb_DBc=cD)Kn2@)ElW5dXgg%j8T zbK(wuetg#T{Ne2~2_nO`ZOf4of&|veaPRu%*_LJPp##9Uy+xnOB?$nNR3#_!VviKd z-?*^3Lb{&7>Sx!8D`e3JUw^X##_cUKlGy~%2LZsbTds5J8QJ+pLNkDr*%B9laR>iT zQalJ6aOPkGR0~iI8=zW%YS;kP0#w5Ws1~3aHbAui)vy7_9T@e00jfBb0eWsUY8}ep zC7@b>YS;kP0#u`S9&&PCKY!TLp1pl9im&MjJ+FXZ@<+wuLQf4SzIuFQUtCQ%^UnY_ zK(zqXbo~}6IJ*)FZ@LEH0GOKxUOZ~sf(GLICg^CuVLyUO0|V~vp|_*#XKr2wO^9pq zKo=G8HkCQ_078@Xub8*L08)pgpOy!5EUfT^NW@F`LsQC=TFbu;m%nA4lk`l^Y T=SO$+00000NkvXXu0mjfLLX%( diff --git a/Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/meta.json b/Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/meta.json deleted file mode 100644 index b5ca3514c5..0000000000 --- a/Resources/Textures/Clothing/Head/Hats/beret_hop.rsi/meta.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "version": 1, - "license": "CC-BY-SA-3.0", - "copyright": "Sprited by upnostnote (Discord), resprite by 96flo (Discord)", - "size": { - "x": 32, - "y": 32 - }, - "states": [ - { - "name": "icon" - }, - { - "name": "equipped-HELMET", - "directions": 4 - }, - { - "name": "equipped-HELMET-hamster", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - }, - { - "name": "inhand-right", - "directions": 4 - } - ] -} \ No newline at end of file From 87b8f1c7df0cf73943b7e89b0defa8096308c86e Mon Sep 17 00:00:00 2001 From: Vasilis The Pikachu Date: Mon, 7 Jul 2025 00:02:16 +0200 Subject: [PATCH 2/6] Revert "Readds the Hypereutactic Blade for traitors, adds Hypereutatic blade for Nukies (#37182)" This reverts commit c03afeb29cf3ed5e751e8d206e79f9f24981484e. Please check the maintainer meeting for details --- .../Locale/en-US/store/uplink-catalog.ftl | 3 -- .../Prototypes/Catalog/uplink_catalog.yml | 46 ------------------- .../Objects/Weapons/Melee/e_sword.yml | 22 ++------- 3 files changed, 5 insertions(+), 66 deletions(-) diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl index 6aa07ce9da..3c7218b69c 100644 --- a/Resources/Locale/en-US/store/uplink-catalog.ftl +++ b/Resources/Locale/en-US/store/uplink-catalog.ftl @@ -23,9 +23,6 @@ uplink-esword-double-desc = A much more expensive counter part to the normal ene uplink-hypereutactic-blade-name = Hypereutactic Blade uplink-hypereutactic-blade-desc = A gigantic energy sword with power that matches its looks. Requires two hands. Slow and unwieldy, yet pretty adept at reflecting. Previously made infamous by an operative wearing a joy mask. You wouldn't want to see this coming at you down the hall! -uplink-hypereutatic-blade-name = Hypereutatic Blade -uplink-hypereutatic-blade-desc = A gigantic off-brand energy sword. Requires two hands. Slow and unwieldy, can reflect decently. Often mistaken for the Hypereutactic Blade. - uplink-edagger-name = Energy Dagger uplink-edagger-desc = A small energy blade conveniently disguised in the form of a pen. diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index 653a17e5f8..2095edabff 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -66,52 +66,6 @@ categories: - UplinkWeaponry -- type: listing - id: UplinkHyperEutacticBlade - name: uplink-hypereutactic-blade-name - description: uplink-hypereutactic-blade-desc - icon: { sprite: /Textures/Objects/Weapons/Melee/hypereutactic_blade.rsi, state: icon } - discountCategory: veryRareDiscounts - discountDownTo: - Telecrystal: 15 - productEntity: HyperEutacticBlade - cost: - Telecrystal: 18 - categories: - - UplinkWeaponry - conditions: - - !type:BuyerWhitelistCondition - blacklist: - components: - - SurplusBundle - - !type:StoreWhitelistCondition - blacklist: - tags: - - NukeOpsUplink - -- type: listing - id: UplinkHyperEutaticBlade - name: uplink-hypereutatic-blade-name - description: uplink-hypereutatic-blade-desc - icon: { sprite: /Textures/Objects/Weapons/Melee/hypereutactic_blade.rsi, state: icon } - discountCategory: veryRareDiscounts - discountDownTo: - Telecrystal: 13 - productEntity: HyperEutaticBlade - cost: - Telecrystal: 16 - categories: - - UplinkWeaponry - conditions: - - !type:BuyerWhitelistCondition - blacklist: - components: - - SurplusBundle - - !type:StoreWhitelistCondition - whitelist: - tags: - - NukeOpsUplink - - type: listing id: UplinkEnergyDagger name: uplink-edagger-name diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index 21554eba07..f879e2891e 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -296,12 +296,11 @@ Slash: 12 Heat: 12 Structural: 15 - # Disabled until the wield active sfx no longer stacks - #- type: ItemToggleActiveSound - # activeSound: - # path: /Audio/Weapons/ebladehum.ogg - # params: - # volume: 3 + - type: ItemToggleActiveSound + activeSound: + path: /Audio/Weapons/ebladehum.ogg + params: + volume: 3 - type: ComponentToggler components: - type: Sharp @@ -387,17 +386,6 @@ reflectProb: 1.0 spread: 75 -# Nukie variant, reduced reflection rate. -- type: entity - parent: HyperEutacticBlade - id: HyperEutaticBlade - name: hypereutatic-blade - description: Often mistaken for the Hypereutactic Blade. This mass produced, off-brand, knockoff gets the same job done but with less reflection. - components: - - type: Reflect - reflectProb: 0.75 - spread: 75 - # Borgs - type: entity suffix: One-Handed, For Borgs From 575694e5b5898d1ad1cfd94c1930ee5d7ccbfb96 Mon Sep 17 00:00:00 2001 From: Vasilis The Pikachu Date: Mon, 7 Jul 2025 00:10:04 +0200 Subject: [PATCH 3/6] Changelog removal --- Resources/Changelog/Changelog.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index cf05e28dbe..f0137f6dbb 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -3660,15 +3660,6 @@ id: 8704 time: '2025-06-21T22:23:39.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/38486 -- author: keronshb - changes: - - message: Added the Hypereutactic Blade back to the Traitor Uplink - type: Add - - message: Added the Hypereutatic Blade to the Nukie uplink - type: Add - id: 8705 - time: '2025-06-22T16:50:59.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/37182 - author: Cojoke-dot changes: - message: Pacifists can now use the Staff of Healing From f5fd2dcb761b2f48ae14aa59ae63c7276cc16a96 Mon Sep 17 00:00:00 2001 From: Hannah Giovanna Dawson Date: Sun, 6 Jul 2025 23:30:44 +0100 Subject: [PATCH 4/6] Scurret naming fixes (#38776) Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- .../NameIdentifier/NameIdentifierSystem.cs | 49 ++++++++++++------- .../NameIdentifier/NameIdentifierComponent.cs | 10 ++-- .../en-US/datasets/names/scurret_first.ftl | 31 ++++++++++++ .../en-US/datasets/names/scurret_last.ftl | 38 ++++++++++++-- .../Prototypes/Datasets/Names/scurret.yml | 4 +- .../Prototypes/Entities/Mobs/NPCs/scurret.yml | 10 +++- 6 files changed, 112 insertions(+), 30 deletions(-) diff --git a/Content.Server/NameIdentifier/NameIdentifierSystem.cs b/Content.Server/NameIdentifier/NameIdentifierSystem.cs index 0a9f87557a..1e5ed67a63 100644 --- a/Content.Server/NameIdentifier/NameIdentifierSystem.cs +++ b/Content.Server/NameIdentifier/NameIdentifierSystem.cs @@ -20,7 +20,7 @@ public sealed class NameIdentifierSystem : EntitySystem /// Free IDs available per . /// [ViewVariables] - public readonly Dictionary> CurrentIds = new(); + public readonly Dictionary> CurrentIds = []; public override void Initialize() { @@ -35,18 +35,22 @@ public sealed class NameIdentifierSystem : EntitySystem InitialSetupPrototypes(); } - private void OnComponentShutdown(EntityUid uid, NameIdentifierComponent component, ComponentShutdown args) + private void OnComponentShutdown(Entity ent, ref ComponentShutdown args) { - if (CurrentIds.TryGetValue(component.Group, out var ids)) + if (ent.Comp.Group is null) + return; + + if (CurrentIds.TryGetValue(ent.Comp.Group, out var ids) && ids.Count > 0) { // Avoid inserting the value right back at the end or shuffling in place: // just pick a random spot to put it and then move that one to the end. var randomIndex = _robustRandom.Next(ids.Count); var random = ids[randomIndex]; - ids[randomIndex] = component.Identifier; + ids[randomIndex] = ent.Comp.Identifier; ids.Add(random); } - _nameModifier.RefreshNameModifiers(uid); + + _nameModifier.RefreshNameModifiers(ent.Owner); } /// @@ -83,46 +87,53 @@ public sealed class NameIdentifierSystem : EntitySystem : $"{randomVal}"; } - private void OnMapInit(EntityUid uid, NameIdentifierComponent component, MapInitEvent args) + private void OnMapInit(Entity ent, ref MapInitEvent args) { - if (!_prototypeManager.TryIndex(component.Group, out var group)) + if (ent.Comp.Group is null) + return; + + if (!_prototypeManager.TryIndex(ent.Comp.Group, out var group)) return; int id; string uniqueName; // If it has an existing valid identifier then use that, otherwise generate a new one. - if (component.Identifier != -1 && - CurrentIds.TryGetValue(component.Group, out var ids) && - ids.Remove(component.Identifier)) + if (ent.Comp.Identifier != -1 && + CurrentIds.TryGetValue(ent.Comp.Group, out var ids) && + ids.Remove(ent.Comp.Identifier)) { - id = component.Identifier; + id = ent.Comp.Identifier; uniqueName = group.Prefix is not null ? $"{group.Prefix}-{id}" : $"{id}"; } else { - uniqueName = GenerateUniqueName(uid, group, out id); - component.Identifier = id; + uniqueName = GenerateUniqueName(ent, group, out id); + ent.Comp.Identifier = id; } - component.FullIdentifier = group.FullName + ent.Comp.FullIdentifier = group.FullName ? uniqueName : $"({uniqueName})"; - Dirty(uid, component); - _nameModifier.RefreshNameModifiers(uid); + Dirty(ent); + _nameModifier.RefreshNameModifiers(ent.Owner); } private void OnRefreshNameModifiers(Entity ent, ref RefreshNameModifiersEvent args) { + if (ent.Comp.Group is null) + return; + // Don't apply the modifier if the component is being removed if (ent.Comp.LifeStage > ComponentLifeStage.Running) return; - if (!_prototypeManager.TryIndex(ent.Comp.Group, out var group)) + if (!_prototypeManager.TryIndex(ent.Comp.Group, out var group)) return; + var format = group.FullName ? "name-identifier-format-full" : "name-identifier-format-append"; // We apply the modifier with a low priority to keep it near the base name // "Beep (Si-4562) the zombie" instead of "Beep the zombie (Si-4562)" @@ -188,13 +199,13 @@ public sealed class NameIdentifierSystem : EntitySystem foreach (var proto in set.Modified.Values) { - var name_proto = (NameIdentifierGroupPrototype) proto; + var name_proto = (NameIdentifierGroupPrototype)proto; // Only bother adding new ones. if (CurrentIds.ContainsKey(proto.ID)) continue; - var ids = GetOrCreateIdList(name_proto); + var ids = GetOrCreateIdList(name_proto); FillGroup(name_proto, ids); } } diff --git a/Content.Shared/NameIdentifier/NameIdentifierComponent.cs b/Content.Shared/NameIdentifier/NameIdentifierComponent.cs index 49be08a6a3..f9f9eef49b 100644 --- a/Content.Shared/NameIdentifier/NameIdentifierComponent.cs +++ b/Content.Shared/NameIdentifier/NameIdentifierComponent.cs @@ -1,5 +1,5 @@ using Robust.Shared.GameStates; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Prototypes; namespace Content.Shared.NameIdentifier; @@ -9,18 +9,18 @@ namespace Content.Shared.NameIdentifier; [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class NameIdentifierComponent : Component { - [DataField("group", required: true, customTypeSerializer:typeof(PrototypeIdSerializer))] - public string Group = string.Empty; + [DataField] + public ProtoId? Group; /// /// The randomly generated ID for this entity. /// - [DataField("identifier"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + [DataField, AutoNetworkedField] public int Identifier = -1; /// /// The full name identifier for this entity. /// - [DataField("fullIdentifier"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + [DataField, AutoNetworkedField] public string FullIdentifier = string.Empty; } diff --git a/Resources/Locale/en-US/datasets/names/scurret_first.ftl b/Resources/Locale/en-US/datasets/names/scurret_first.ftl index 4bbbf943f0..a01a6db8bb 100644 --- a/Resources/Locale/en-US/datasets/names/scurret_first.ftl +++ b/Resources/Locale/en-US/datasets/names/scurret_first.ftl @@ -1,3 +1,19 @@ +# Scurrets from Planet Wawa have two parts to their name - a 'chosen' and 'qualitative' name. + +# The chosen name is picked by the scurret themselves, +# encompassing a trait or value they hold themselves +# to or have a high value for. Scurrets sometimes change this +# name to denote an important moment in their life. + +# It appears to be common for scurret sets to share the same +# chosen name, with the gaining of a pup's own chosen name +# signalling their transition to adulthood in the community. + +# Given the scurret language is untranslated, these names are +# usually guessed via charades or Pictionary. + +# When all else fails, to NT and her crews, Wa is as good a name as any. + names-scurret-first-dataset-1 = Wa names-scurret-first-dataset-2 = Calm names-scurret-first-dataset-3 = Contented @@ -34,3 +50,18 @@ names-scurret-first-dataset-33 = Wise names-scurret-first-dataset-34 = Alert names-scurret-first-dataset-35 = Uplifting names-scurret-first-dataset-36 = Considerate +names-scurret-first-dataset-37 = Surviving +names-scurret-first-dataset-38 = Meditating +names-scurret-first-dataset-39 = Hunting +names-scurret-first-dataset-40 = Watching +names-scurret-first-dataset-41 = Resting +names-scurret-first-dataset-42 = Delivering +names-scurret-first-dataset-43 = Swimming +names-scurret-first-dataset-44 = Swinging +names-scurret-first-dataset-45 = Exploding +names-scurret-first-dataset-46 = Romancing +names-scurret-first-dataset-47 = Far-Seeing +names-scurret-first-dataset-48 = Loyal +names-scurret-first-dataset-49 = Inquisitive +# After consulting with lawyers, NT added this one to the dictionary. +names-scurret-first-dataset-50 = Legally Distinct diff --git a/Resources/Locale/en-US/datasets/names/scurret_last.ftl b/Resources/Locale/en-US/datasets/names/scurret_last.ftl index effe2180f0..bac9b818d1 100644 --- a/Resources/Locale/en-US/datasets/names/scurret_last.ftl +++ b/Resources/Locale/en-US/datasets/names/scurret_last.ftl @@ -1,3 +1,19 @@ +# Scurrets from Planet Wawa have two parts to their name - a 'chosen' and 'qualitative' name. + +# The qualitative name is usually related to an important feature +# of Wawa's wetland habitats that the scurret is associated with +# by their community. + +# Scurret pups, due to both their quantity and complete lack +# of any survival instinct, lack a qualitative name entirely. +# Researchers believe their parents simply give them a number. + +# Given that the scurret language is untranslated, these names are +# usually deduced via the showing of photographs, annoyed and +# repeated pointing at nearby objects, or games of Pictionary. + +# When all else fails, to NT and her crews, Wa is as good a name as any. + names-scurret-last-dataset-1 = Wa names-scurret-last-dataset-2 = Trees names-scurret-last-dataset-3 = Plants @@ -6,12 +22,12 @@ names-scurret-last-dataset-5 = Rivers names-scurret-last-dataset-6 = Groves names-scurret-last-dataset-7 = Lakes names-scurret-last-dataset-8 = Marshes -names-scurret-last-dataset-9 = Spring +names-scurret-last-dataset-9 = Springs names-scurret-last-dataset-10 = Reeds names-scurret-last-dataset-11 = Sunshine names-scurret-last-dataset-12 = Rain names-scurret-last-dataset-13 = Clouds -names-scurret-last-dataset-14 = Snowfall +names-scurret-last-dataset-14 = Snowfalls names-scurret-last-dataset-15 = Stones names-scurret-last-dataset-16 = Pebbles names-scurret-last-dataset-17 = Fishes @@ -25,7 +41,7 @@ names-scurret-last-dataset-24 = Alders names-scurret-last-dataset-25 = Birches names-scurret-last-dataset-26 = Poplars names-scurret-last-dataset-27 = Marigolds -names-scurret-last-dataset-28 = Robins +names-scurret-last-dataset-28 = Rowans names-scurret-last-dataset-29 = Orchids names-scurret-last-dataset-30 = Rushes names-scurret-last-dataset-31 = Lillies @@ -33,4 +49,20 @@ names-scurret-last-dataset-32 = Violets names-scurret-last-dataset-33 = Maples names-scurret-last-dataset-34 = Oaks names-scurret-last-dataset-35 = Hazels +# AND SIR GIDEON OFNIR names-scurret-last-dataset-36 = the All-Knowing +names-scurret-last-dataset-37 = Tarns +names-scurret-last-dataset-38 = Waters +names-scurret-last-dataset-39 = Reservoirs +names-scurret-last-dataset-40 = Dams +names-scurret-last-dataset-41 = Moors +names-scurret-last-dataset-42 = Fens +names-scurret-last-dataset-43 = Temples +names-scurret-last-dataset-44 = Hills +names-scurret-last-dataset-45 = Copses +names-scurret-last-dataset-46 = Fields +names-scurret-last-dataset-47 = Ancestors +names-scurret-last-dataset-48 = Forests +names-scurret-last-dataset-49 = Secrets +# Nobody's quite sure how this one is in the dictionary. +names-scurret-last-dataset-50 = Space Ferret diff --git a/Resources/Prototypes/Datasets/Names/scurret.yml b/Resources/Prototypes/Datasets/Names/scurret.yml index b3ac08e2ad..9e23557b38 100644 --- a/Resources/Prototypes/Datasets/Names/scurret.yml +++ b/Resources/Prototypes/Datasets/Names/scurret.yml @@ -2,10 +2,10 @@ id: NamesFirstScurret values: prefix: names-scurret-first-dataset- - count: 36 + count: 50 - type: localizedDataset id: NamesLastScurret values: prefix: names-scurret-last-dataset- - count: 36 + count: 50 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml index 19ba323a0a..1f0eb0f9e2 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml @@ -139,6 +139,14 @@ available: - enum.DamageStateVisualLayers.Base: scurret: ScurretColors + # They are of a mysterious gender. + - type: Grammar + attributes: + gender: epicene + proper: true + # Strips the name identifier from them, so they're just "Confident Waters" rather than "Confident Waters (123)" + - type: NameIdentifier + group: null # Emotional Support Scurrets have a ghost role and equipment. At the moment, these are intended to be used for admemes, but # feel free to hook them into random content. @@ -169,4 +177,4 @@ name: Emotional Support Scurret id: MobEmotionalSupportScurret parent: [MobScurret, MobBaseEmotionalSupportScurret] - description: Commonly known as Wawa, from the wetlands of Planet Wawa, these critters make up the bulk of Arnolds's Pizza's "loyal workforce". This one is here as a temp. + description: Commonly known as Wawa, from the wetlands of Planet Wawa, these critters make up the bulk of Arnold's Pizza's "loyal workforce". This one is here as a temp. From 5f7db3b1514e58211041ce1c9c3ed23ef889df7b Mon Sep 17 00:00:00 2001 From: Hannah Giovanna Dawson Date: Sun, 6 Jul 2025 23:42:13 +0100 Subject: [PATCH 5/6] Scurret displacement map fixes (#38775) --- .../Prototypes/Entities/Mobs/NPCs/scurret.yml | 32 ++++++++++++++++++ .../Animals/scurret/displacement.rsi/back.png | Bin 0 -> 279 bytes .../Animals/scurret/displacement.rsi/hand.png | Bin 426 -> 382 bytes .../scurret/displacement.rsi/jumpsuit.png | Bin 329 -> 510 bytes .../scurret/displacement.rsi/meta.json | 4 +++ 5 files changed, 36 insertions(+) create mode 100644 Resources/Textures/Mobs/Animals/scurret/displacement.rsi/back.png diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml index 1f0eb0f9e2..6d328014db 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml @@ -104,6 +104,38 @@ 32: sprite: Mobs/Animals/scurret/displacement.rsi state: neck + ears: + sizeMaps: + 32: + sprite: Mobs/Animals/scurret/displacement.rsi + state: ears + eyes: + sizeMaps: + 32: + sprite: Mobs/Animals/scurret/displacement.rsi + state: eyes + head: + sizeMaps: + 32: + sprite: Mobs/Animals/scurret/displacement.rsi + state: head + mask: + sizeMaps: + 32: + sprite: Mobs/Animals/scurret/displacement.rsi + state: mask + back: + sizeMaps: + 32: + sprite: Mobs/Animals/scurret/displacement.rsi + state: back + - type: Hands + leftHandDisplacement: + sizeMaps: + 32: + sprite: Mobs/Animals/scurret/displacement.rsi + state: hand + - type: InventorySlots - type: Food - type: Hunger diff --git a/Resources/Textures/Mobs/Animals/scurret/displacement.rsi/back.png b/Resources/Textures/Mobs/Animals/scurret/displacement.rsi/back.png new file mode 100644 index 0000000000000000000000000000000000000000..110555738328a9c2754c179f5ede423c3028c6ba GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|E_%8+hE&XX zJIj%)*+7J~zU#V~2Y+6yXw1|{+I*R5VR|O@MjA>Hs>PSL#jRg0Zr^n9Z{*rlS~KTc z?0K$U{ezpwf%}3)gV+K?23?0_hNy;P3|km_88aBAm@hDyuq|NCz@=fIMY7Y zTS?b%1$*pVyDH_q==L8{jMDrkru?hlAr!#Gxq$hC2ZL;b8`BGhddnmC{#HL@TgNiR z0mwBGa$sLjsGMN+;`RAQP7W&{HM2ABJbK%7zr~cq|i4t&wuXDwCm|P|LSGYyG9Ylofi(x`WRWZ zXydWJ-#-7GF@wjE-;r}d00XjXz}8P>uwv+CxxkpA(!l4S%vi!8g`s5U9tK6dbL=7K VG^>)FyPq)tfv2mV%Q~loCICj*mka;^ delta 387 zcmeyzw2FCxK|KRYx}&cn1H;CC?mvmF3=E7`o-U3d6>)E8-sWpE5OC?<|5nxI%Wl)z zKD~h)Tb7!q`6V6u@I>y`QoX~qMf%~5x3BX4`1SCY#{XzPkEmV32C@Ib`!<%;_O4_3 zp;X@;yK7%--u4F3*Y-O^T*H~J%}VhR4i$E}q{QeErNS`t%$@p++t|wlA9SDBO?*4k zzf|BBH>U$o_JqoxfTh<8R9o+cIlOxm{Qs-&#iL>;Lib$U(=g|#bbEG_nvTn@hb$G_ zyfWe(-UaTw$E}b#kwHb*_bY>7%WE@LkQDyXISfie$VT&g3XYH1G!e5m@@fAeA$| zGfQ~*7XRDwLy&=ifiE?}GtJkR ZK?}&{0Adih6g(M3dAjDH|r(ggfD8?HcbH2L$F=0P({uM?U4}u)0=XX=*YZC@Jj)DEe`5cB~XLcI#r2WDX zkD*6vE%273|8HX@aCYcAz(>7od0K}s{D0wTg2l&-(OT5-sYrk&_7(9ibKEo&F26B N002ovPDHLkV1i8^*(3k} delta 289 zcmeyze3EH`VLh{_i(^Q|oVT~`3N Date: Mon, 7 Jul 2025 14:23:45 +0200 Subject: [PATCH 6/6] sanitize MIDI parser (#38806) Co-authored-by: Pieter-Jan Briers --- .../Instruments/MidiParser/MidiParser.cs | 2 ++ .../Instruments/InstrumentSystem.cs | 15 ++++++----- .../Instruments/SharedInstrumentComponent.cs | 26 +++++++++++++++++++ 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/Content.Client/Instruments/MidiParser/MidiParser.cs b/Content.Client/Instruments/MidiParser/MidiParser.cs index 937384e439..0b65e472fc 100644 --- a/Content.Client/Instruments/MidiParser/MidiParser.cs +++ b/Content.Client/Instruments/MidiParser/MidiParser.cs @@ -102,6 +102,8 @@ public static class MidiParser // 0x03 is TrackName, // 0x04 is InstrumentName + // This string can potentially contain control characters, including 0x00 which can cause problems if it ends up in database entries via admin logs + // we sanitize TrackName and InstrumentName after they have been send to the server var text = Encoding.ASCII.GetString(metaData, 0, (int)metaLength); switch (metaType) { diff --git a/Content.Server/Instruments/InstrumentSystem.cs b/Content.Server/Instruments/InstrumentSystem.cs index 420bd44737..f6a2162271 100644 --- a/Content.Server/Instruments/InstrumentSystem.cs +++ b/Content.Server/Instruments/InstrumentSystem.cs @@ -156,6 +156,15 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem return; } + + foreach (var t in msg.Tracks) + { + // Remove any control characters that may be part of the midi file so they don't end up in the admin logs. + t?.SanitizeFields(); + // Truncate any track names too long. + t?.TruncateFields(_cfg.GetCVar(CCVars.MidiMaxChannelNameLength)); + } + var tracksString = string.Join("\n", msg.Tracks .Where(t => t != null) @@ -166,12 +175,6 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem LogImpact.Low, $"{ToPrettyString(args.SenderSession.AttachedEntity)} set the midi channels for {ToPrettyString(uid)} to {tracksString}"); - // Truncate any track names too long. - foreach (var t in msg.Tracks) - { - t?.TruncateFields(_cfg.GetCVar(CCVars.MidiMaxChannelNameLength)); - } - activeInstrument.Tracks = msg.Tracks; Dirty(uid, activeInstrument); diff --git a/Content.Shared/Instruments/SharedInstrumentComponent.cs b/Content.Shared/Instruments/SharedInstrumentComponent.cs index 97eef752eb..41bef64902 100644 --- a/Content.Shared/Instruments/SharedInstrumentComponent.cs +++ b/Content.Shared/Instruments/SharedInstrumentComponent.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Text; using Robust.Shared.Audio.Midi; using Robust.Shared.GameStates; using Robust.Shared.Serialization; @@ -207,6 +208,18 @@ public sealed class MidiTrack ProgramName = Truncate(ProgramName, limit); } + public void SanitizeFields() + { + if (InstrumentName != null) + InstrumentName = Sanitize(InstrumentName); + + if (TrackName != null) + TrackName = Sanitize(TrackName); + + if (ProgramName != null) + ProgramName = Sanitize(ProgramName); + } + private const string Postfix = "…"; // TODO: Make a general method to use in RT? idk if we have that. private string Truncate(string input, int limit) @@ -218,4 +231,17 @@ public sealed class MidiTrack return input.Substring(0, truncatedLength) + Postfix; } + + private static string Sanitize(string input) + { + var sanitized = new StringBuilder(input.Length); + + foreach (char c in input) + { + if (!char.IsControl(c) && c <= 127) // no control characters, only ASCII + sanitized.Append(c); + } + + return sanitized.ToString(); + } }