hotfix 23.06.2026 V2#1465
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughPR интегрирует несколько крупных изменений: переход голоса профиля на типизированный ChangesРедактор голоса TTS
Arachne graft, трафарет и хирургия
Маркировки и случайные волосы
Flesh worm suffocation alert и status effect
Боеприпасы и оружие
Баланс и иерархия NPC
Sequence Diagram(s)sequenceDiagram
participant Editor as HumanoidProfileEditor
participant Tab as TTSTab
participant Profile as HumanoidCharacterProfile
participant System as HumanoidProfileSystem
participant TTS as TTSSystem
Editor->>Tab: RefreshVoiceTab()
Editor->>Tab: UpdateControls(profile, sex)
Note over Tab: парсит категории, показывает результаты
Tab->>Editor: OnVoiceSelected(voiceId)
Editor->>Profile: WithVoice(voiceId)
Editor->>System: ApplyProfileTo(mob, profile)
System->>System: ResolveVoice(profile)
System->>TTS: TTSComponent.VoicePrototypeId = voice
Tab->>Editor: OnPreviewRequested(voiceId)
Editor->>TTS: RequestGlobalTTS(voiceId, Preview)
sequenceDiagram
participant Surgeon as Хирург
participant Surgery as SurgeryDetachArachneGraft
participant Shared as SharedSurgerySystem
participant Body as BodySystem
participant Mapping as SurgeryBodyPartMapping
Surgeon->>Surgery: инициирует операцию
Surgery->>Shared: SurgeryValidEvent
Shared->>Body: TryGetOrganByCategory(category)
Shared->>Mapping: IsArachneGraftCategory(category)
alt true
Shared->>Mapping: TryGetLastAttachedArachneGraft(body)
Mapping->>Body: перебирает органы в обратном порядке
Mapping-->>Shared: last category
Shared->>Mapping: CanDetachArachneGraftCategory(body, category)
alt совпадает с last
Mapping-->>Shared: true, разрешить
else не совпадает
Mapping-->>Shared: false, отменить
end
else false
Shared-->>Surgery: отменить (не arachne)
end
sequenceDiagram
participant Victim as Жертва(InventoryComponent)
participant Alert as FleshWormSuffocationAlert
participant Shared as SharedFleshWormSystem
participant FleshWorm as FleshWormSystem
Victim->>Alert: Клик на красный alert
Alert->>Shared: FleshWormSuffocationAlertEvent
Shared->>Shared: OnSuffocationAlertClick
alt User == Inventory owner
Shared->>Shared: TryGetFaceWorm из слота mask
alt FleshWormComponent найден
Shared->>FleshWorm: StartRemoveDoAfter(worm, victim)
Shared-->>Alert: args.Handled = true
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~90 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (2)
Content.IntegrationTests/Tests/Backmen/Body/HumanoidFoxMarkingsTest.cs (1)
24-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winДобавьте симметричную проверку для
Sex.Femaleв этом же тесте.Сейчас контракт whitelist/слоёв проверяется только для
Sex.Male; небольшой дублирующий assert-блок дляSex.Femaleснизит риск тихих регрессий при будущих измененияхSexRestriction.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Content.IntegrationTests/Tests/Backmen/Body/HumanoidFoxMarkingsTest.cs` around lines 24 - 35, The test currently only validates tail markings for Sex.Male, which means regressions in Sex.Female handling could go undetected. After the existing assertions for Sex.Male, add a symmetric block that calls markingManager.MarkingsByLayerAndGroupAndSex with HumanoidVisualLayers.Tail, torsoData.Group, and Sex.Female to retrieve female tail markings, then assert that this result also contains FoxTail and WolfTail while not containing TailSnakeAnimated, using the same assertion pattern as the Male block.Content.Client/Corvax/TTS/TTSTab.xaml (1)
23-24: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winСделайте поле поиска более адаптивным по ширине.
MinWidth="400"на Line 23 вместе сMinWidth="275"левой панели (Line 3) увеличивает минимальную ширину всей вкладки и может ломать layout на узких разрешениях. Лучше убрать жёсткий минимум или уменьшить его.💡 Вариант правки
- <LineEdit Name="SearchEdit" MinWidth="400" HorizontalExpand="True" + <LineEdit Name="SearchEdit" HorizontalExpand="True" PlaceHolder="{Loc 'humanoid-profile-editor-voice-placeholder'}"/>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Content.Client/Corvax/TTS/TTSTab.xaml` around lines 23 - 24, The SearchEdit LineEdit control has a MinWidth of 400 pixels which, combined with the left panel's MinWidth of 275 pixels, creates an excessively large minimum width for the entire tab and breaks the layout on narrow screen resolutions. Either remove the MinWidth attribute entirely from the SearchEdit control to allow it to adapt dynamically to available space, or reduce it to a smaller value such as 200 pixels. This will make the search field more responsive and prevent layout issues on narrow resolutions while maintaining usability.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Content.Client/Corvax/TTS/HumanoidProfileEditor.TTS.cs`:
- Around line 58-61: The SetVoice method unconditionally sets IsDirty = true
even when the voice has not actually changed, which bypasses the SetDirty()
method and keeps Save/Reset buttons active unnecessarily. Modify the SetVoice
method to only mark the profile as dirty when newVoice is actually different
from the current voice. Check if the new voice differs from the current voice
before calling SetDirty() or setting IsDirty = true, ensuring the dirty flag is
only set when there is a genuine change.
In `@Content.Client/Corvax/TTS/TTSTab.xaml.cs`:
- Around line 149-160: The previewButton event handler in the TTSTab.xaml.cs
file currently invokes OnPreviewRequested without checking if the voice is
accessible based on the canSelectVoice permission, allowing sponsor-only voices
to be previewed even when selection is blocked. Add a check for canSelectVoice
before invoking OnPreviewRequested in the previewButton.OnPressed event handler
to ensure the preview action respects the same access restrictions as voice
selection.
In
`@Content.Server/Backmen/Administration/Commands/Toolshed/GraftArachneCommand.cs`:
- Around line 106-114: The code calls TryGetValue for "Torso" and "Head"
profiles but ignores the boolean return values indicating whether these keys
exist in the profiles dictionary. If either key is missing, the resulting
torsoProfile or headProfile will be null, leading to incorrect/default
appearance data being applied. Before calling ApplyProfile method, add explicit
null checks for both torsoProfile and headProfile variables to ensure both
required profiles exist in the dictionary before attempting to access their
properties like SkinColor and EyeColor. If either profile is missing, either
skip the ApplyProfile call or handle the missing profile case appropriately.
In `@Content.Shared/Backmen/Surgery/SharedSurgerySystem.cs`:
- Around line 294-303: The inversion logic in the OnArachneGraftOrganValid
method is backwards. The ternary operator at the conditional check
(ent.Comp.Inverse ? !isArachne : isArachne) is reversing the filter in the wrong
direction. Fix this by swapping the conditions in the ternary operator so that
when Inverse is true, arachne organs are correctly blocked and non-arachne
organs are allowed, which is the opposite of the current behavior. Change the
condition to properly invert the organ type filtering based on the Inverse flag.
In `@Content.Shared/Preferences/HumanoidCharacterProfile.cs`:
- Around line 537-546: In the EnsureValid method of HumanoidCharacterProfile.cs,
the voice validation logic only checks if the voice matches the character's sex
and has RoundStart enabled, but does not verify sponsor-only rights. The TTSTab
already enforces this check separately, allowing imported or manually modified
profiles to bypass it. Add an additional validation when assigning the Voice
property to check if the voice prototype has sponsor-only requirements, and if
so, verify that the session/player has the required sponsor access rights. If
the voice is sponsor-only but the player lacks sponsor rights, fall back to the
default voice selection instead of accepting the invalid voice.
In `@Resources/Locale/en-US/_backmen/markings/reptilian.ftl`:
- Around line 85-100: Add the "Lizard, " prefix to the display names of all five
animated snake tail markings (marking-TailSnakeAnimated,
marking-TailSnakeStripeAnimated, marking-TailSnakeStripeAltAnimated,
marking-TailSnakeDualAnimated, and marking-TailSnakeUnderAnimated) to match the
naming convention used in other nearby reptilian tail entries. Each marking's
display name should begin with "Lizard, " followed by the rest of the
description (e.g., "Lizard, Snake tail (animated)").
In `@Resources/Locale/ru-RU/_backmen/markings/reptilian.ftl`:
- Around line 64-76: The new animated snake tail marking translations
(marking-TailSnakeAnimated, marking-TailSnakeStripeAnimated,
marking-TailSnakeDualAnimated, marking-TailSnakeUnderAnimated) lack the "Ящер, "
prefix that other reptilian tail markings have in the file. Add "Ящер, " at the
beginning of each of these four marking translation values to make the reptilian
tail list uniform and consistent throughout the localization file.
In `@Resources/Prototypes/_Backmen/Entities/Surgery/surgeries.yml`:
- Around line 93-94: The type name specified in the YAML for the surgery
condition does not match the actual registered component name. The component
class `SurgeryArachneGraftOrganConditionComponent` is registered as
`SurgeryArachneGraftOrganCondition`, but the YAML entry at line 93 specifies
`type: SurgeryArachneGraftOrgan` (missing "Condition" suffix). Update the type
value from `SurgeryArachneGraftOrgan` to `SurgeryArachneGraftOrganCondition` to
match the registered component name and ensure the condition is properly
applied.
---
Nitpick comments:
In `@Content.Client/Corvax/TTS/TTSTab.xaml`:
- Around line 23-24: The SearchEdit LineEdit control has a MinWidth of 400
pixels which, combined with the left panel's MinWidth of 275 pixels, creates an
excessively large minimum width for the entire tab and breaks the layout on
narrow screen resolutions. Either remove the MinWidth attribute entirely from
the SearchEdit control to allow it to adapt dynamically to available space, or
reduce it to a smaller value such as 200 pixels. This will make the search field
more responsive and prevent layout issues on narrow resolutions while
maintaining usability.
In `@Content.IntegrationTests/Tests/Backmen/Body/HumanoidFoxMarkingsTest.cs`:
- Around line 24-35: The test currently only validates tail markings for
Sex.Male, which means regressions in Sex.Female handling could go undetected.
After the existing assertions for Sex.Male, add a symmetric block that calls
markingManager.MarkingsByLayerAndGroupAndSex with HumanoidVisualLayers.Tail,
torsoData.Group, and Sex.Female to retrieve female tail markings, then assert
that this result also contains FoxTail and WolfTail while not containing
TailSnakeAnimated, using the same assertion pattern as the Male block.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 53fa8791-11ff-4306-9bdd-6859ef9048f5
📒 Files selected for processing (38)
Content.Client/Backmen/Species/Arachne/ArachneSpriteLayerSystem.csContent.Client/Corvax/TTS/HumanoidProfileEditor.TTS.csContent.Client/Corvax/TTS/TTSTab.xamlContent.Client/Corvax/TTS/TTSTab.xaml.csContent.Client/Lobby/UI/HumanoidProfileEditor.Traits.csContent.Client/Lobby/UI/HumanoidProfileEditor.xamlContent.Client/Lobby/UI/HumanoidProfileEditor.xaml.csContent.IntegrationTests/Tests/Backmen/Body/ArachneGraftDetachOrderTest.csContent.IntegrationTests/Tests/Backmen/Body/GibOnTriggerDetachedBodyTest.csContent.IntegrationTests/Tests/Backmen/Body/HumanoidFoxMarkingsTest.csContent.Server/Backmen/Administration/Commands/Toolshed/GraftArachneCommand.csContent.Server/Humanoid/Components/RandomHumanoidAppearanceComponent.csContent.Server/Humanoid/Systems/RandomHumanoidAppearanceSystem.csContent.Shared/Backmen/Surgery/Conditions/SurgeryArachneGraftOrganConditionComponent.csContent.Shared/Backmen/Surgery/SharedSurgerySystem.csContent.Shared/Backmen/Surgery/Steps/SurgeryOrganGraftDetachComponent.csContent.Shared/Backmen/Targeting/SurgeryBodyPartMapping.csContent.Shared/Humanoid/HumanoidCharacterAppearance.csContent.Shared/Humanoid/HumanoidProfileExportV1.csContent.Shared/Preferences/HumanoidCharacterProfile.csContent.Shared/Trigger/Systems/GibOnTriggerSystem.csResources/Locale/en-US/_backmen/markings/reptilian.ftlResources/Locale/en-US/backmen/markings/foxes.ftlResources/Locale/en-US/corvax/tts/tts-ui.ftlResources/Locale/ru-RU/_backmen/markings/reptilian.ftlResources/Locale/ru-RU/backmen/markings/foxes.ftlResources/Locale/ru-RU/corvax/tts/tts-ui.ftlResources/Locale/ru-RU/corvax/tts/tts-voices.ftlResources/Locale/ru-RU/ss14-ru/prototypes/_backmen/entities/surgery/arachne_surgeries.ftlResources/Prototypes/Entities/Clothing/OuterClothing/suits.ymlResources/Prototypes/Entities/Mobs/Player/human.ymlResources/Prototypes/GameRules/events.ymlResources/Prototypes/GameRules/roundstart.ymlResources/Prototypes/_Backmen/Body/Species/foxes.ymlResources/Prototypes/_Backmen/Entities/Mobs/Customization/Markings/fox_markings.ymlResources/Prototypes/_Backmen/Entities/Mobs/NPCs/greytide.ymlResources/Prototypes/_Backmen/Entities/Surgery/arachne_surgeries.ymlResources/Prototypes/_Backmen/Entities/Surgery/surgeries.yml
💤 Files with no reviewable changes (1)
- Content.Client/Lobby/UI/HumanoidProfileEditor.xaml
| private void SetVoice(ProtoId<TTSVoicePrototype> newVoice) | ||
| { | ||
| if (Profile is null) | ||
| return; | ||
|
|
||
| Profile = Profile.WithVoice(voice); | ||
| SetDirty(); | ||
| Profile = Profile?.WithVoice(newVoice); | ||
| IsDirty = true; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Не помечайте профиль dirty без фактического изменения голоса.
IsDirty = true обходит SetDirty() и оставляет Save/Reset активными даже при выборе уже текущего голоса или возврате к исходному значению.
Возможная правка
private void SetVoice(ProtoId<TTSVoicePrototype> newVoice)
{
- Profile = Profile?.WithVoice(newVoice);
- IsDirty = true;
+ if (Profile is null || Profile.Voice == newVoice)
+ return;
+
+ Profile = Profile.WithVoice(newVoice);
+ SetDirty();
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Content.Client/Corvax/TTS/HumanoidProfileEditor.TTS.cs` around lines 58 - 61,
The SetVoice method unconditionally sets IsDirty = true even when the voice has
not actually changed, which bypasses the SetDirty() method and keeps Save/Reset
buttons active unnecessarily. Modify the SetVoice method to only mark the
profile as dirty when newVoice is actually different from the current voice.
Check if the new voice differs from the current voice before calling SetDirty()
or setting IsDirty = true, ensuring the dirty flag is only set when there is a
genuine change.
| var previewButton = new Button | ||
| { | ||
| Text = Loc.GetString("humanoid-profile-editor-voice-play"), | ||
| MinWidth = 30, | ||
| ToolTip = Loc.GetString("humanoid-profile-editor-voice-tooltip-play"), | ||
| StyleClasses = { StyleClass.ButtonOpenLeft } | ||
| }; | ||
|
|
||
| previewButton.OnPressed += _ => | ||
| { | ||
| OnPreviewRequested?.Invoke(voice.ID); | ||
| }; |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Закройте обход sponsor-only через предпрослушивание.
На Line 157-160 OnPreviewRequested вызывается без проверки canSelectVoice, поэтому sponsor-only голос можно использовать через preview даже при заблокированном выборе.
🔒 Предлагаемая правка
var previewButton = new Button
{
Text = Loc.GetString("humanoid-profile-editor-voice-play"),
MinWidth = 30,
- ToolTip = Loc.GetString("humanoid-profile-editor-voice-tooltip-play"),
+ ToolTip = canSelectVoice
+ ? Loc.GetString("humanoid-profile-editor-voice-tooltip-play")
+ : Loc.GetString("humanoid-profile-editor-voice-tooltip-sponsoronly"),
+ Disabled = !canSelectVoice,
StyleClasses = { StyleClass.ButtonOpenLeft }
};
previewButton.OnPressed += _ =>
{
- OnPreviewRequested?.Invoke(voice.ID);
+ if (canSelectVoice)
+ OnPreviewRequested?.Invoke(voice.ID);
};🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Content.Client/Corvax/TTS/TTSTab.xaml.cs` around lines 149 - 160, The
previewButton event handler in the TTSTab.xaml.cs file currently invokes
OnPreviewRequested without checking if the voice is accessible based on the
canSelectVoice permission, allowing sponsor-only voices to be previewed even
when selection is blocked. Add a check for canSelectVoice before invoking
OnPreviewRequested in the previewButton.OnPressed event handler to ensure the
preview action respects the same access restrictions as voice selection.
| profiles.TryGetValue("Torso", out var torsoProfile); | ||
| profiles.TryGetValue("Head", out var headProfile); | ||
|
|
||
| _visualBody.ApplyProfile(body, new OrganProfileData | ||
| { | ||
| Sex = humanoid.Sex, | ||
| SkinColor = torsoProfile.SkinColor, | ||
| EyeColor = headProfile.EyeColor, | ||
| }); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Проверьте обязательные профили перед ApplyProfile
Сейчас результат TryGetValue игнорируется. Если Torso или Head отсутствуют, вы применяете некорректные/дефолтные данные внешности после graft.
💡 Предлагаемый фикс
- profiles.TryGetValue("Torso", out var torsoProfile);
- profiles.TryGetValue("Head", out var headProfile);
+ if (!profiles.TryGetValue("Torso", out var torsoProfile)
+ || !profiles.TryGetValue("Head", out var headProfile))
+ {
+ return;
+ }
_visualBody.ApplyProfile(body, new OrganProfileData
{
Sex = humanoid.Sex,
SkinColor = torsoProfile.SkinColor,
EyeColor = headProfile.EyeColor,
});🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@Content.Server/Backmen/Administration/Commands/Toolshed/GraftArachneCommand.cs`
around lines 106 - 114, The code calls TryGetValue for "Torso" and "Head"
profiles but ignores the boolean return values indicating whether these keys
exist in the profiles dictionary. If either key is missing, the resulting
torsoProfile or headProfile will be null, leading to incorrect/default
appearance data being applied. Before calling ApplyProfile method, add explicit
null checks for both torsoProfile and headProfile variables to ensure both
required profiles exist in the dictionary before attempting to access their
properties like SkinColor and EyeColor. If either profile is missing, either
skip the ApplyProfile call or handle the missing profile case appropriately.
| if (!prototypeManager.TryIndex(Voice, out var voiceProto) || !CanHaveVoice(voiceProto, sex)) | ||
| { | ||
| Voice = prototypeManager | ||
| var defaultVoice = prototypeManager | ||
| .EnumeratePrototypes<TTSVoicePrototype>() | ||
| .FirstOrDefault(v => CanHaveVoice(v, sex) && v.RoundStart)?.ID | ||
| ?? string.Empty; | ||
| .FirstOrDefault(v => CanHaveVoice(v, sex) && v.RoundStart); | ||
|
|
||
| if (defaultVoice is { } voice) | ||
| Voice = new ProtoId<TTSVoicePrototype>(voice.ID); | ||
| else | ||
| Voice = default; |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
Проверьте sponsor-only право в EnsureValid.
Сейчас профиль считается валидным для любого RoundStart-голоса подходящего пола, но TTSTab отдельно запрещает SponsorOnly голоса без доступа. Импортированный или вручную изменённый профиль сможет обойти UI и сохранить sponsor-only voice; добавьте ту же проверку прав по session перед принятием Voice, иначе откатывайте на обычный fallback.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Content.Shared/Preferences/HumanoidCharacterProfile.cs` around lines 537 -
546, In the EnsureValid method of HumanoidCharacterProfile.cs, the voice
validation logic only checks if the voice matches the character's sex and has
RoundStart enabled, but does not verify sponsor-only rights. The TTSTab already
enforces this check separately, allowing imported or manually modified profiles
to bypass it. Add an additional validation when assigning the Voice property to
check if the voice prototype has sponsor-only requirements, and if so, verify
that the session/player has the required sponsor access rights. If the voice is
sponsor-only but the player lacks sponsor rights, fall back to the default voice
selection instead of accepting the invalid voice.
| marking-TailSnakeAnimated = Snake tail (animated) | ||
| marking-TailSnakeAnimated-snake_wagging = Main | ||
|
|
||
| marking-TailSnakeStripeAnimated = Snake tail, striped (animated) | ||
| marking-TailSnakeStripeAnimated-snake_stripe_wagging = Inner | ||
| marking-TailSnakeStripeAnimated-snake_stripe_secondary_wagging = Outer | ||
|
|
||
| marking-TailSnakeStripeAltAnimated = Snake tail, striped alt (animated) | ||
| marking-TailSnakeStripeAltAnimated-snake_stripe_alt_wagging = Inner | ||
| marking-TailSnakeStripeAltAnimated-snake_stripe_alt_secondary_wagging = Outer | ||
|
|
||
| marking-TailSnakeDualAnimated = Snake tail, dual (animated) | ||
| marking-TailSnakeDualAnimated-snake_dual_wagging = Inner | ||
| marking-TailSnakeDualAnimated-snake_dual_secondary_wagging = Outer | ||
|
|
||
| marking-TailSnakeUnderAnimated = Snake tail, under (animated) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Приведите названия новых animated-хвостов к единому формату вида.
В строках marking-TailSnakeAnimated, marking-TailSnakeStripeAnimated, marking-TailSnakeStripeAltAnimated, marking-TailSnakeDualAnimated, marking-TailSnakeUnderAnimated отсутствует префикс Lizard, , который используется у соседних reptilian-tail записей. Это создаёт несогласованность в UI-списке маркировок.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Resources/Locale/en-US/_backmen/markings/reptilian.ftl` around lines 85 -
100, Add the "Lizard, " prefix to the display names of all five animated snake
tail markings (marking-TailSnakeAnimated, marking-TailSnakeStripeAnimated,
marking-TailSnakeStripeAltAnimated, marking-TailSnakeDualAnimated, and
marking-TailSnakeUnderAnimated) to match the naming convention used in other
nearby reptilian tail entries. Each marking's display name should begin with
"Lizard, " followed by the rest of the description (e.g., "Lizard, Snake tail
(animated)").
| marking-TailSnakeAnimated = Хвост змеи (анимированный) | ||
| marking-TailSnakeAnimated-snake_wagging = Основная часть | ||
| marking-TailSnakeStripeAnimated = Хвост змеи, полосатый (анимированный) | ||
| marking-TailSnakeStripeAnimated-snake_stripe_wagging = Верхняя часть | ||
| marking-TailSnakeStripeAnimated-snake_stripe_secondary_wagging = Нижняя часть | ||
| marking-TailSnakeStripeAltAnimated = Хвост змеи, полосатый альт. (анимированный) | ||
| marking-TailSnakeStripeAltAnimated-snake_stripe_alt_wagging = Верхняя часть | ||
| marking-TailSnakeStripeAltAnimated-snake_stripe_alt_secondary_wagging = Нижняя часть | ||
| marking-TailSnakeDualAnimated = Хвост змеи, двойной (анимированный) | ||
| marking-TailSnakeDualAnimated-snake_dual_wagging = Верхняя часть | ||
| marking-TailSnakeDualAnimated-snake_dual_secondary_wagging = Нижняя часть | ||
| marking-TailSnakeUnderAnimated = Хвост змеи, подхвостье (анимированный) | ||
| marking-TailSnakeUnderAnimated-snake_under_wagging = Верхняя часть |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Синхронизируйте префикс вида в новых RU-строках хвостов.
Для новых ключей (marking-TailSnakeAnimated*, marking-TailSnakeStripeAnimated*, marking-TailSnakeDualAnimated*, marking-TailSnakeUnderAnimated*) лучше добавить Ящер, ..., как в остальных reptilian-хвостах, чтобы список выглядел единообразно.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Resources/Locale/ru-RU/_backmen/markings/reptilian.ftl` around lines 64 - 76,
The new animated snake tail marking translations (marking-TailSnakeAnimated,
marking-TailSnakeStripeAnimated, marking-TailSnakeDualAnimated,
marking-TailSnakeUnderAnimated) lack the "Ящер, " prefix that other reptilian
tail markings have in the file. Add "Ящер, " at the beginning of each of these
four marking translation values to make the reptilian tail list uniform and
consistent throughout the localization file.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml`:
- Line 161: The description field for the Drozd SMG contains corrupted character
encoding where `NanotrasenтАЩs` appears as mojibake. Replace this corrupted text
with the correct English text `Nanotrasen's` to fix the encoding issue and
ensure the description displays properly to users.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 80a63aa2-dfee-4460-8cd5-8df5b6c940a1
📒 Files selected for processing (15)
Content.IntegrationTests/Tests/Backmen/UplinkAmmoCaliberTest.csContent.Shared/Backmen/Surgery/SharedSurgerySystem.csResources/Locale/en-US/ss14-ru/prototypes/entities/objects/weapons/guns/pistols/pistols.ftlResources/Locale/en-US/ss14-ru/prototypes/entities/objects/weapons/guns/smgs/smgs.ftlResources/Locale/en-US/store/uplink-catalog.ftlResources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/weapons/guns/pistols/pistols.ftlResources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/weapons/guns/smgs/smgs.ftlResources/Locale/ru-RU/store/uplink-catalog.ftlResources/Prototypes/Catalog/Fills/Backpacks/duffelbag.ymlResources/Prototypes/Catalog/uplink_catalog.ymlResources/Prototypes/Entities/Markers/Spawners/nuke_ops_spawners.ymlResources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.ymlResources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.ymlResources/Prototypes/_Backmen/Catalog/uplink_nomad.ymlResources/Prototypes/_Backmen/Entities/Surgery/surgeries.yml
✅ Files skipped from review due to trivial changes (6)
- Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml
- Resources/Locale/ru-RU/store/uplink-catalog.ftl
- Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/weapons/guns/pistols/pistols.ftl
- Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/weapons/guns/smgs/smgs.ftl
- Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/weapons/guns/smgs/smgs.ftl
- Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/weapons/guns/pistols/pistols.ftl
🚧 Files skipped from review as they are similar to previous changes (2)
- Resources/Prototypes/_Backmen/Entities/Surgery/surgeries.yml
- Content.Shared/Backmen/Surgery/SharedSurgerySystem.cs
| parent: [BaseWeaponSubMachineGun, BaseSecurityContraband] | ||
| id: WeaponSubMachineGunDrozd | ||
| description: A modern SMG manufactured by NanotrasenтАЩs Small Arms Division. It features an exceptional rate of fire in burst mode, useful for holding defensive angles or engaging hostiles at longer ranges. Feeds from .35 SMG magazines. | ||
| description: A modern SMG manufactured by NanotrasenтАЩs Small Arms Division. It features an exceptional rate of fire in burst mode, useful for holding defensive angles or engaging hostiles at longer ranges. Feeds from 9x17 mm SMG magazines. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Исправьте битую кодировку в описании Drozd.
На Line 161 строка содержит NanotrasenтАЩs, что выглядит как mojibake и попадет в пользовательский текст.
💡 Предложение правки
- description: A modern SMG manufactured by NanotrasenтАЩs Small Arms Division. It features an exceptional rate of fire in burst mode, useful for holding defensive angles or engaging hostiles at longer ranges. Feeds from 9x17 mm SMG magazines.
+ description: A modern SMG manufactured by Nanotrasen's Small Arms Division. It features an exceptional rate of fire in burst mode, useful for holding defensive angles or engaging hostiles at longer ranges. Feeds from 9x17 mm SMG magazines.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| description: A modern SMG manufactured by NanotrasenтАЩs Small Arms Division. It features an exceptional rate of fire in burst mode, useful for holding defensive angles or engaging hostiles at longer ranges. Feeds from 9x17 mm SMG magazines. | |
| description: A modern SMG manufactured by Nanotrasen's Small Arms Division. It features an exceptional rate of fire in burst mode, useful for holding defensive angles or engaging hostiles at longer ranges. Feeds from 9x17 mm SMG magazines. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml` at line
161, The description field for the Drozd SMG contains corrupted character
encoding where `NanotrasenтАЩs` appears as mojibake. Replace this corrupted text
with the correct English text `Nanotrasen's` to fix the encoding issue and
ensure the description displays properly to users.
|
@coderabbitai обнови описание pr |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
Resources/Prototypes/_Lavaland/Entities/Mobs/base.yml (1)
31-32: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winУберите дублирующее наследование
StripableInventoryBase.На Line 32
StripableInventoryBaseуже избыточен, так какMobBaseNpcна Line 31 уже тянет его через свою цепочку наследования.Предлагаемый дифф
- type: entity id: MobBaseNpcDungeon parent: - MobBaseNpc - - StripableInventoryBase categories: [ HideSpawnMenu ]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Resources/Prototypes/_Lavaland/Entities/Mobs/base.yml` around lines 31 - 32, The StripableInventoryBase component listed on line 32 is redundant because the MobBaseNpc component on line 31 already includes it through its inheritance chain. Remove the duplicate StripableInventoryBase entry from the component list, keeping only MobBaseNpc to avoid unnecessary duplication in the inheritance hierarchy.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Content.Server/Corvax/TTS/TTSSystem.cs`:
- Around line 51-55: The early return condition in the MapInit logic checks for
HumanoidProfileComponent and exits before assigning a VoicePrototypeId, which
leaves humanoid entities without an initialized voice if the profile doesn't
assign one later. Move the voice prototype assignment logic (the
_prototypeManager.TryGetRandom call and ent.Comp.VoicePrototypeId assignment) to
execute before the early return check for HasComp<HumanoidProfileComponent> so
that all entities, including humanoids, receive a voice during initialization.
In `@Content.Server/Preferences/Managers/ServerPreferencesManager.cs`:
- Around line 109-111: The direct dictionary access to
HumanoidProfileSystem.DefaultSexVoice[sex] in the ServerPreferencesManager voice
profile conversion logic will throw a KeyNotFoundException if sex contains an
invalid value from corrupted or outdated profile data. Replace the direct
indexing with a safe dictionary access pattern (such as TryGetValue or
ContainsKey validation) to gracefully handle cases where the sex key does not
exist in DefaultSexVoice, and provide a fallback default voice value instead of
crashing the profile load.
In `@Content.Shared/Backmen/Flesh/SharedFleshWormSystem.cs`:
- Around line 86-97: The OnSuffocationAlertClick method lacks protection against
duplicate do-after scheduling when the alert is clicked multiple times. Add a
guard check using HasActiveWormRemoveDoAfter before calling StartRemoveDoAfter
to prevent multiple parallel removal attempts, similar to the implementation
already present in OnUnequipAttempt. This check should return early if an active
worm removal do-after is already in progress for the entity.
In `@Resources/Locale/en-US/actions/actions/flesh.ftl`:
- Around line 3-9: Two localization keys in the flesh.ftl file are defined but
not used anywhere in the FleshWormSystem.cs code:
flesh-pudge-throw-worm-try-unequip and flesh-pudge-throw-worm-hit-others. Remove
these two unused localization keys from the flesh.ftl file to keep the
localization resources clean and synchronized with the actual code
implementation.
---
Nitpick comments:
In `@Resources/Prototypes/_Lavaland/Entities/Mobs/base.yml`:
- Around line 31-32: The StripableInventoryBase component listed on line 32 is
redundant because the MobBaseNpc component on line 31 already includes it
through its inheritance chain. Remove the duplicate StripableInventoryBase entry
from the component list, keeping only MobBaseNpc to avoid unnecessary
duplication in the inheritance hierarchy.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 5979d42c-4e32-44de-af7b-0d0c8bcc1df2
📒 Files selected for processing (28)
Content.Client/Backmen/Flesh/FleshWormVisualSystem.csContent.Server/Backmen/Flesh/FleshWormSuffocationStatusEffectSystem.csContent.Server/Backmen/Flesh/FleshWormSystem.csContent.Server/Backmen/Ghost/GhostReJoinSystem.csContent.Server/Body/Systems/InternalsSystem.csContent.Server/Corvax/TTS/TTSSystem.csContent.Server/Preferences/Managers/ServerPreferencesManager.csContent.Shared/Backmen/Flesh/FleshWormComponent.csContent.Shared/Backmen/Flesh/FleshWormSuffocationAlertComponent.csContent.Shared/Backmen/Flesh/FleshWormSuffocationStatusEffectComponent.csContent.Shared/Backmen/Flesh/SharedFleshCultist.csContent.Shared/Backmen/Flesh/SharedFleshWormSystem.csContent.Shared/Humanoid/HumanoidProfileComponent.csContent.Shared/Humanoid/HumanoidProfileSystem.csResources/Locale/en-US/_backmen/alerts/flesh_worm.ftlResources/Locale/en-US/actions/actions/flesh.ftlResources/Locale/ru-RU/_backmen/alerts/flesh_worm.ftlResources/Locale/ru-RU/actions/actions/flesh.ftlResources/Prototypes/_Backmen/Alerts/flesh_worm.ymlResources/Prototypes/_Backmen/Entities/Mobs/NPCs/base.ymlResources/Prototypes/_Backmen/Entities/Mobs/NPCs/bri'ish.ymlResources/Prototypes/_Backmen/Entities/Mobs/NPCs/nanotrasen.ymlResources/Prototypes/_Backmen/Entities/Mobs/NPCs/syndicate.ymlResources/Prototypes/_Backmen/Entities/Mobs/NPCs/unitedearthgovernment.ymlResources/Prototypes/_Backmen/StatusEffects/flesh_worm.ymlResources/Prototypes/_Lavaland/Entities/Mobs/Bosses/uriil.ymlResources/Prototypes/_Lavaland/Entities/Mobs/angels.ymlResources/Prototypes/_Lavaland/Entities/Mobs/base.yml
💤 Files with no reviewable changes (1)
- Content.Server/Body/Systems/InternalsSystem.cs
✅ Files skipped from review due to trivial changes (4)
- Resources/Locale/ru-RU/_backmen/alerts/flesh_worm.ftl
- Content.Shared/Backmen/Flesh/FleshWormSuffocationAlertComponent.cs
- Content.Shared/Backmen/Flesh/FleshWormSuffocationStatusEffectComponent.cs
- Resources/Locale/ru-RU/actions/actions/flesh.ftl
| if (ent.Comp.VoicePrototypeId != null || HasComp<HumanoidProfileComponent>(ent)) | ||
| return; | ||
|
|
||
| if (_prototypeManager.TryGetRandom<TTSVoicePrototype>(_robustRandom, out var newTtsVoice)) | ||
| ent.Comp.VoicePrototypeId = newTtsVoice.ID; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Для humanoid на MapInit голос может остаться неинициализированным.
На Line 51-55 вы выходите при HasComp<HumanoidProfileComponent>(ent) до назначения VoicePrototypeId. В итоге у таких сущностей VoicePrototypeId остаётся null, если профиль не применится позже отдельным вызовом.
💡 Предлагаемое исправление
- if (ent.Comp.VoicePrototypeId != null || HasComp<HumanoidProfileComponent>(ent))
+ if (ent.Comp.VoicePrototypeId != null)
return;
+ if (TryComp<HumanoidProfileComponent>(ent, out var humanoidProfile))
+ {
+ ent.Comp.VoicePrototypeId = humanoidProfile.Voice;
+ Dirty(ent);
+ return;
+ }
+
if (_prototypeManager.TryGetRandom<TTSVoicePrototype>(_robustRandom, out var newTtsVoice))
ent.Comp.VoicePrototypeId = newTtsVoice.ID;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Content.Server/Corvax/TTS/TTSSystem.cs` around lines 51 - 55, The early
return condition in the MapInit logic checks for HumanoidProfileComponent and
exits before assigning a VoicePrototypeId, which leaves humanoid entities
without an initialized voice if the profile doesn't assign one later. Move the
voice prototype assignment logic (the _prototypeManager.TryGetRandom call and
ent.Comp.VoicePrototypeId assignment) to execute before the early return check
for HasComp<HumanoidProfileComponent> so that all entities, including humanoids,
receive a voice during initialization.
| var voice = string.IsNullOrEmpty(profile.Voice) | ||
| ? HumanoidProfileSystem.DefaultSexVoice[sex] | ||
| : new ProtoId<TTSVoicePrototype>(profile.Voice); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Небезопасный доступ к DefaultSexVoice может уронить конвертацию профиля.
На Line 109-111 используется HumanoidProfileSystem.DefaultSexVoice[sex]. При невалидном значении sex (например, из повреждённых/старых данных) это даст KeyNotFoundException и сорвёт загрузку префов.
💡 Предлагаемое исправление
- var voice = string.IsNullOrEmpty(profile.Voice)
- ? HumanoidProfileSystem.DefaultSexVoice[sex]
+ var voice = string.IsNullOrWhiteSpace(profile.Voice)
+ ? HumanoidProfileSystem.DefaultSexVoice.GetValueOrDefault(sex, HumanoidProfileSystem.DefaultVoice)
: new ProtoId<TTSVoicePrototype>(profile.Voice);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| var voice = string.IsNullOrEmpty(profile.Voice) | |
| ? HumanoidProfileSystem.DefaultSexVoice[sex] | |
| : new ProtoId<TTSVoicePrototype>(profile.Voice); | |
| var voice = string.IsNullOrWhiteSpace(profile.Voice) | |
| ? HumanoidProfileSystem.DefaultSexVoice.GetValueOrDefault(sex, HumanoidProfileSystem.DefaultVoice) | |
| : new ProtoId<TTSVoicePrototype>(profile.Voice); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Content.Server/Preferences/Managers/ServerPreferencesManager.cs` around lines
109 - 111, The direct dictionary access to
HumanoidProfileSystem.DefaultSexVoice[sex] in the ServerPreferencesManager voice
profile conversion logic will throw a KeyNotFoundException if sex contains an
invalid value from corrupted or outdated profile data. Replace the direct
indexing with a safe dictionary access pattern (such as TryGetValue or
ContainsKey validation) to gracefully handle cases where the sex key does not
exist in DefaultSexVoice, and provide a fallback default voice value instead of
crashing the profile load.
| private void OnSuffocationAlertClick(Entity<InventoryComponent> ent, ref FleshWormSuffocationAlertEvent args) | ||
| { | ||
| if (args.Handled || args.User != ent.Owner) | ||
| return; | ||
|
|
||
| if (!TryGetFaceWorm(ent, out var worm) || !TryComp<FleshWormComponent>(worm, out var comp)) | ||
| return; | ||
|
|
||
| args.Handled = true; | ||
| StartRemoveDoAfter(args.User, worm, args.User, comp); | ||
| } | ||
|
|
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Предотвратите дублирующиеся do-after при повторных кликах алерта.
В текущем обработчике нет проверки активного FleshWormRemoveDoAfterEvent, поэтому спам кликом по алерту может запланировать несколько параллельных попыток снятия. Добавьте guard через HasActiveWormRemoveDoAfter, как уже сделано в OnUnequipAttempt.
💡 Предлагаемое исправление
private void OnSuffocationAlertClick(Entity<InventoryComponent> ent, ref FleshWormSuffocationAlertEvent args)
{
if (args.Handled || args.User != ent.Owner)
return;
if (!TryGetFaceWorm(ent, out var worm) || !TryComp<FleshWormComponent>(worm, out var comp))
return;
+
+ if (HasActiveWormRemoveDoAfter(args.User))
+ {
+ args.Handled = true;
+ return;
+ }
args.Handled = true;
StartRemoveDoAfter(args.User, worm, args.User, comp);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private void OnSuffocationAlertClick(Entity<InventoryComponent> ent, ref FleshWormSuffocationAlertEvent args) | |
| { | |
| if (args.Handled || args.User != ent.Owner) | |
| return; | |
| if (!TryGetFaceWorm(ent, out var worm) || !TryComp<FleshWormComponent>(worm, out var comp)) | |
| return; | |
| args.Handled = true; | |
| StartRemoveDoAfter(args.User, worm, args.User, comp); | |
| } | |
| private void OnSuffocationAlertClick(Entity<InventoryComponent> ent, ref FleshWormSuffocationAlertEvent args) | |
| { | |
| if (args.Handled || args.User != ent.Owner) | |
| return; | |
| if (!TryGetFaceWorm(ent, out var worm) || !TryComp<FleshWormComponent>(worm, out var comp)) | |
| return; | |
| if (HasActiveWormRemoveDoAfter(args.User)) | |
| { | |
| args.Handled = true; | |
| return; | |
| } | |
| args.Handled = true; | |
| StartRemoveDoAfter(args.User, worm, args.User, comp); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Content.Shared/Backmen/Flesh/SharedFleshWormSystem.cs` around lines 86 - 97,
The OnSuffocationAlertClick method lacks protection against duplicate do-after
scheduling when the alert is clicked multiple times. Add a guard check using
HasActiveWormRemoveDoAfter before calling StartRemoveDoAfter to prevent multiple
parallel removal attempts, similar to the implementation already present in
OnUnequipAttempt. This check should return early if an active worm removal
do-after is already in progress for the entity.
| flesh-pudge-throw-worm-eat-face-user = { CAPITALIZE(THE($worm)) } is eating your face! | ||
| flesh-pudge-throw-worm-bite-user = { CAPITALIZE(THE($worm)) } has bitten your hand! | ||
| flesh-pudge-throw-worm-try-unequip = You can't remove { THE($worm) } from your face. | ||
| flesh-pudge-throw-worm-eat-face-others = { CAPITALIZE(THE($worm)) } is eating { CAPITALIZE(THE($entity)) }'s face! | ||
| flesh-pudge-throw-worm-hit-others = { CAPITALIZE(THE($worm)) } has latched onto { CAPITALIZE(THE($entity)) }'s face! | ||
| flesh-pudge-throw-worm-hit-mob = You have latched onto { CAPITALIZE(THE($entity)) }'s face! | ||
| flesh-pudge-throw-worm-hit-user = { CAPITALIZE(THE($worm)) } has latched onto your face! |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Поиск всех использований обновлённых локализационных ключей
# Проверка использования ключей throw-worm
rg -n "flesh-pudge-throw-worm-(eat-face-user|bite-user|try-unequip|eat-face-others|hit-others|hit-mob|hit-user)" \
--type cs -C 5
# Проверка использования ключей head-trauma
rg -n "flesh-worm-head-trauma-(user|others)" --type cs -C 5Repository: Rxup/space-station-14
Length of output: 159
🏁 Script executed:
# First, let's understand the repository structure and find where these localization keys might be used
find . -type f -name "*.ftl" | head -20Repository: Rxup/space-station-14
Length of output: 1360
🏁 Script executed:
# Search for any usage of flesh-pudge-throw-worm keys across all file types
rg "flesh-pudge-throw-worm" --type-list | head -5
rg "flesh-pudge-throw-worm" -C 3Repository: Rxup/space-station-14
Length of output: 549
🏁 Script executed:
# Search for "pudge" or "worm" in C# files to understand the context
rg "pudge|flesh.*worm" --type cs -C 3 | head -50Repository: Rxup/space-station-14
Length of output: 159
🏁 Script executed:
# Check if there are any recent changes to flesh.ftl or related files
git log --oneline -20 -- "Resources/Locale/en-US/actions/actions/flesh.ftl" 2>/dev/null || echo "Git history not available"Repository: Rxup/space-station-14
Length of output: 174
🏁 Script executed:
# View the actual flesh.ftl file
cat Resources/Locale/en-US/actions/actions/flesh.ftlRepository: Rxup/space-station-14
Length of output: 3590
🏁 Script executed:
# Check git diff to see what changed in flesh.ftl
git diff HEAD~1 HEAD -- Resources/Locale/en-US/actions/actions/flesh.ftl 2>/dev/null || echo "No git diff available"Repository: Rxup/space-station-14
Length of output: 181
🏁 Script executed:
# Search for the flesh entity/component in C# code
rg "flesh|pudge|worm" --type cs -i | head -100Repository: Rxup/space-station-14
Length of output: 159
🏁 Script executed:
# Look for how localization keys are typically referenced
rg "flesh-pudge|Loc\.GetString" --type cs -C 2 | head -50Repository: Rxup/space-station-14
Length of output: 159
🏁 Script executed:
# Search for "Vomit Worm" or files that might implement this action
rg "Vomit Worm" --type cs
rg -i "pudge|worm" --type cs -l | head -20Repository: Rxup/space-station-14
Length of output: 159
🏁 Script executed:
# Look for action implementations or components
rg "PopupAction|GetString.*flesh" --type cs -C 3 | head -50Repository: Rxup/space-station-14
Length of output: 159
🏁 Script executed:
# Search in yml/yaml files for entity definitions
rg -i "pudge|flesh.*worm" --type yaml | head -50Repository: Rxup/space-station-14
Length of output: 159
🏁 Script executed:
# Check the entire codebase structure for flesh-related files
fd "flesh|pudge|worm" -i --type f | grep -E "\.(cs|yml|yaml)$"Repository: Rxup/space-station-14
Length of output: 3463
🏁 Script executed:
# View FleshWormSystem.cs to see localization usage
cat Content.Server/Backmen/Flesh/FleshWormSystem.cs | head -150Repository: Rxup/space-station-14
Length of output: 6301
🏁 Script executed:
# View FleshPudgeSystem.cs
cat Content.Server/Backmen/Flesh/FleshPudgeSystem.csRepository: Rxup/space-station-14
Length of output: 6258
🏁 Script executed:
# Check the actions definition in flesh_cultist.yml
cat Resources/Prototypes/_Backmen/Actions/flesh_cultist.ymlRepository: Rxup/space-station-14
Length of output: 7178
🏁 Script executed:
# Search for the localization keys in FleshWormSystem
rg "flesh-pudge-throw-worm|flesh-worm-head-trauma" Content.Server/Backmen/Flesh/FleshWormSystem.cs -C 5Repository: Rxup/space-station-14
Length of output: 2460
🏁 Script executed:
# Get more of FleshWormSystem to find the localization calls
wc -l Content.Server/Backmen/Flesh/FleshWormSystem.csRepository: Rxup/space-station-14
Length of output: 211
🏁 Script executed:
# View the rest of FleshWormSystem - focusing on parts with Loc.GetString calls
grep -n "Loc.GetString\|flesh-pudge\|flesh-worm" Content.Server/Backmen/Flesh/FleshWormSystem.csRepository: Rxup/space-station-14
Length of output: 944
🏁 Script executed:
# Check if there are any other uses of flesh-pudge-throw-worm-try-unequip or flesh-pudge-throw-worm-hit-others
rg "flesh-pudge-throw-worm-try-unequip|flesh-pudge-throw-worm-hit-others" --type csRepository: Rxup/space-station-14
Length of output: 159
🏁 Script executed:
# Search for where "try-unequip" or "hit-others" might be used
rg "try-unequip|hit-others" --type cs -C 3Repository: Rxup/space-station-14
Length of output: 159
🏁 Script executed:
# Check if there are unequip-related localization calls in FleshWormSystem
rg -i "unequip" Content.Server/Backmen/Flesh/FleshWormSystem.cs -C 3Repository: Rxup/space-station-14
Length of output: 3465
Не все локализационные строки используются в коде.
Из семи локализационных ключей, определённых в flesh.ftl (строки 3-9), только пять фактически используются в FleshWormSystem.cs. Ключи flesh-pudge-throw-worm-try-unequip и flesh-pudge-throw-worm-hit-others определены в файле локализации, но не имеют соответствующих вызовов Loc.GetString() в коде.
Для используемых строк параметры передаются корректно:
flesh-pudge-throw-worm-hit-user,flesh-pudge-throw-worm-eat-face-user,flesh-pudge-throw-worm-bite-userпередают("worm", uid/worm)flesh-pudge-throw-worm-eat-face-othersпередает("worm", uid)и("entity", targetId)flesh-worm-head-trauma-user,flesh-worm-head-trauma-othersпередают необходимые параметры
Удалите неиспользуемые ключи из файла локализации либо добавьте соответствующие вызовы в код.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Resources/Locale/en-US/actions/actions/flesh.ftl` around lines 3 - 9, Two
localization keys in the flesh.ftl file are defined but not used anywhere in the
FleshWormSystem.cs code: flesh-pudge-throw-worm-try-unequip and
flesh-pudge-throw-worm-hit-others. Remove these two unused localization keys
from the flesh.ftl file to keep the localization resources clean and
synchronized with the actual code implementation.
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
gh pr edit 1465 --repo Rxup/space-station-14 --body "Closes `#1461`
## Обзор изменений
### 🔊 TTS (Text-to-Speech)
- Добавлен новый UI-компонент `TTSTab` с поиском, фильтрацией по категориям и предпрослушиванием голосов
- Рефакторинг редактора профиля (`HumanoidProfileEditor`): вкладка голоса вынесена в отдельный таб
- Тип поля \`Voice\` в \`HumanoidCharacterProfile\` изменён с \`string\` на \`ProtoId<TTSVoicePrototype>\`
- Добавлены новые локализационные строки для TTS UI (en-US, ru-RU)
- Добавлен \`Voice\` в модель экспорта профиля \`HumanoidProfileExportV1\`
### 🕷️ Хирургия Арахни
- Добавлен новый компонент условия \`SurgeryArachneGraftOrganConditionComponent\`
- Добавлен новый компонент шага \`SurgeryOrganGraftDetachComponent\` для отсоединения графтов в обратном порядке установки
- Добавлены вспомогательные методы в \`SurgeryBodyPartMapping\`: порядок установки, проверка последнего графта, возможность отсоединения
- Добавлена операция \`SurgeryDetachArachneGraft\`
- Расширены шаги хирургий \`SurgeryGraftArachneAbdomen\`, \`SurgeryGraftArachneFront\`, \`SurgeryGraftSpiderLeg{Left,Right}\`
- Обновлена визуализация стенсил-маски в \`ArachneSpriteLayerSystem\`
- Добавлена синхронизация пола/цвета органов после пересадки в \`GraftArachneCommand\`
- Новые интеграционные тесты: \`ArachneGraftDetachOrderTest\`, \`GibOnTriggerDetachedBodyTest\`
### 🔫 Боеприпасы (калибр 9x17 мм)
- SMG C20r и Drozd переведены на патроны 9x17 мм (вместо .35 авто)
- Обновлены uplink-каталоги, спавнеры нукопсов и дуффелбэги под новый калибр
- Обновлены описания Viper (5.7x28 мм), Mk58, C20r, Drozd в локализациях (en-US, ru-RU)
- Листинги \`UplinkMagazine9x17\` и \`UplinkMagazinePistol9x17\` в \`uplink_nomad.yml\` отключены (закомментированы); патроны 9x17 добавлены напрямую в ammo-backpack
- Добавлен интеграционный тест \`UplinkAmmoCaliberTest\`
### 💀 Нукопсы / Ниндзя
- Добавлен компонент \`PainImmune\` для \`MobHumanSyndicateAgentNukeops\`, \`MobHumanNukeOp\`, \`MobHumanLoneNuclearOperative\`, \`NinjaSpawn\`, \`LoneOpsSpawn\` и ролевых loadout'ов нукопсов
- Улучшена маскировка костюма нидзя: \`Stealth\` minVisibility/lastVisibility снижены до -1, добавлен \`StealthOnMove\`
### 🦊 Маркировки (Лисы / Рептилии)
- Добавлены анимированные варианты змеиных хвостов (en-US, ru-RU)
- Добавлены маркировки внутреннего хвоста лисы (\`FoxTailinner\`, \`FoxTailinnerAnimated\`)
- Обновлена конфигурация видов лис (\`foxes.yml\`): добавлены \`VisualOrganMarkings\` для всех конечностей
- Добавлен интеграционный тест \`HumanoidFoxMarkingsTest\`
- Исправлен \`groupWhitelist\` для \`FoxTailinnerAnimated\`
### 🎲 Рандомизация персонажей
- Добавлен флаг \`RandomizeHair\` в \`RandomHumanoidProfileComponent\`
- NPC ГрейТайд теперь получают рандомные волосы (\`randomizeHair: true\`)
- Добавлен метод \`WithRandomHair\` в \`HumanoidCharacterAppearance\`
### 🔧 Прочее
- Исправлена установка заголовка вкладки трейтов (индекс 3) в \`HumanoidProfileEditor\`
- Добавлен \`GibOnTriggerSystem\` с проверкой сервер/клиент и поддержкой \`BodyComponent\`"Length of output: 3900
Closes Обзор изменений🔊 TTS (Text-to-Speech)
🕷️ Хирургия Арахни
🔫 Боеприпасы (калибр 9x17 мм)
💀 Нукопсы / Ниндзя
🦊 Маркировки (Лисы / Рептилии)
🎲 Рандомизация персонажей
🔧 Прочее
|
#1461
Summary by CodeRabbit
Summary by CodeRabbit
Новые возможности
Bug Fixes
Tests
Локализация и контент