Skip to content

Comments

Hotfix 08.01.26#1414

Merged
KayzelW merged 8 commits intomasterfrom
hotfix-080126
Jan 8, 2026
Merged

Hotfix 08.01.26#1414
KayzelW merged 8 commits intomasterfrom
hotfix-080126

Conversation

@Rxup
Copy link
Owner

@Rxup Rxup commented Jan 8, 2026

Summary by CodeRabbit

Примечания к выпуску

  • Новые функции

    • Языковая подсистема перешла на прототипные идентификаторы; добавлена поддержка акцентов и новая компонента акцента.
    • Публичный метод восстановления тела/органов.
  • Улучшения

    • Расширена обработка речи: поддержка переопределения языка и передачa языка через голосовые/чат-системы.
    • Попугаи и NPC теперь учитывают язык при запоминании/целеполагании.
    • Медреагенты получили тонкие корректировки травм и подавление боли.
  • Оптимизация

    • Множество внутренних констант унифицированы для уменьшения дублирования.
  • Контент

    • Датчики атмосферы — новые газы; добавлены новые HTN-паттерны поведения для существ.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 8, 2026

Walkthrough

Множество приватных полей ProtoId<*> переведены из экземплярных в статические; языковая подсистема мигрирована с string на ProtoId<LanguagePrototype>; добавлены лечение/восстановление тела и эффекты травм в реагентах; расширены HTN-прототипы Glimmer Wisp; добавлены новые статус‑эффекты и данные прототипов. (50 слов)

Changes

Когорта / Файл(ы) Описание
Массовый перенос ProtoId в static
Content.Client/..., Content.Server/..., Content.Shared/... (много файлов, pattern: приватные ProtoId<*>)
Преобразование множества приватных ProtoId<...> полей из private readonly в private static readonly. Проверьте инициализацию в статическом контексте и возможные побочные эффекты при многопоточности/порядке загрузки.
Языковая подсистема — миграция на ProtoId
Content.Server/Backmen/Language/*, Content.Shared/Backmen/Language/Components/*, Content.Server/Backmen/Language/Commands/AdminTranslatorCommand.cs, Content.Server/Backmen/Language/TranslatorSystem.cs
Поля компонентов и API методов (Add/Remove/Set/CanSpeak/CanUnderstand и команды) заменены со string на ProtoId<LanguagePrototype>. Обновлены места сериализации и вызовы; проверить совместимость сериализации и все вызовы API.
Эффекты и восстановление тела
Content.Server/Backmen/Blob/Systems/BlobMobSystem.cs, Content.Shared/Body/Systems/SharedBodySystem.Body.cs, Content.Server/EntityEffects/Effects/MakeSentientEntityEffectSystem.cs, Content.Shared/Backmen/EntityEffects/Effects/AdjustTraumas.cs, Content.Shared/Backmen/Blob/Components/BlobMobComponent.cs
Добавлены зависимости на SharedEntityEffectsSystem/SharedBodySystem, массив HealingEffects, применение эффектов при пульсе, логика CureTick/CureBodyInterval и публичный API ForceRestoreBody. Также рефакторинг доступа к компонентам через Entity<> и использование entity queries. Требует детальной проверки логики восстановления и согласованности эффектов.
Psionics и реагенты
Content.Server/Backmen/Abilities/Psionics/*, Resources/Prototypes/_Backmen/Reagents/psionic.yml, Resources/Prototypes/Reagents/medicine.yml
Введён ProtoId<ReagentPrototype> PsionicRegenerationEssence; прототипы реагентов получили AdjustTraumas/ModifyStatusEffect и изменения в метаболизмах. Проверить идентификаторы и баланс эффектов/травм.
HTN / NPC — Glimmer Wisp
Resources/Prototypes/_Backmen/Entities/Mobs/NPCs/glimmer_monsters.yml, Resources/Prototypes/_Backmen/Entities/Mobs/NPCs/root.yml
Добавлены/перемещены HTN-компаунды и utilityQuery для дальнего боя Wisp; часть компаундов удалена/реорганизована. Проверить целостность HTN‑деревьев и отсутствия дублирующих записей.
API мобов / NPC-оценки
Content.Shared/Mobs/Systems/MobStateSystem.cs, Content.Server/NPC/Systems/NPCUtilitySystem.cs, Content.Server/Backmen/NPC/Queries/Considerations/TargetIsAliveOrSoftCritCon.cs
Добавлен публичный метод IsAliveOrSoftCrit и новая consideration для NPCUtilitySystem — влияет на вычисление оценок AI. Проверить влияние на поведение AI.
Чат/вокализация/акценты — языковая передача
Content.Server/Chat/Systems/ChatSystem.cs, Content.Server/Vocalization/Systems/VocalizationSystem.cs, Content.Server/Speech/AccentSystem.cs, Content.Shared/Chat/SharedChatEvents.cs, Content.Shared/Speech/AccentEvent.cs
TransformSpeech/вокализация и события стали передавать/модифицировать информацию о языке (ProtoId); TransformSpeech теперь принимает язык по ссылке. Проверить последовательность событий и обратную совместимость обработчиков.
Прототипы и данные
Resources/Prototypes/.../sensor.yml, Resources/Prototypes/Reagents/medicine.yml, Resources/Prototypes/Recipes/Reactions/medicine.yml, Resources/Prototypes/_Backmen/StatusEffects/speech.yml
Добавлены новые газы, расширены метаболизмы реагентов, увеличен выход рецепта MindbreakerToxin, добавлены статус‑эффекты речи/акцентов. Проверить загрузку YAML и ссылки на новые прототипы.
Компоненты/сериализация/прочее
Content.Shared/Backmen/Language/Components/Translators/BaseTranslatorComponent.cs, Content.Shared/Backmen/Language/Components/LanguageKnowledgeComponent.cs, Content.Server/Backmen/Speech/Components/LanguageAccentComponent.cs, прочие файлы
Поля списков языков и сериализация изменены (строки → ProtoId<LanguagePrototype>); добавлен флаг RequiresAllLanguages; добавлен компонент LanguageAccentComponent. Проверить сериализацию старых данных и загрузку компонентов.

Sequence Diagram(s)

sequenceDiagram
  participant BlobMobSystem
  participant Entity
  participant SharedEntityEffectsSystem
  participant SharedBodySystem

  Note over BlobMobSystem,Entity: Pulse handler в BlobMobSystem
  BlobMobSystem->>Entity: Применяет расчёт урона/лечения
  BlobMobSystem->>SharedEntityEffectsSystem: ApplyEffects(Entity, HealingEffects)
  SharedEntityEffectsSystem-->>Entity: Добавляет эффекты (trauma adjustments и др.)
  alt CureBodyInterval > 0
    BlobMobSystem->>BlobMobSystem: Инкремент CureTick
    BlobMobSystem->>SharedBodySystem: ForceRestoreBody(Entity) при достижении интервала
    SharedBodySystem-->>Entity: Восстановление частей/органов, удаление ран
  end
Loading

Estimated code review effort

🎯 4 (Сложная) | ⏱️ ~45 минут

Poem

🐰 Я статик в полях разложил, не зря,
Языки в ProtoId — теперь ясна игра.
Эффекты лечат, тело чиню я,
Глиммер целится — свистит в ночи, ура!
Морковку отмечаю — коммит принят, хоп!

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning Заголовок PR крайне неинформативен и не отражает суть изменений в коммите. Замените заголовок на описательный, отражающий основные изменения: например, 'Convert instance fields to static readonly for ProtoId references and refactor language system'.
Docstring Coverage ⚠️ Warning Docstring coverage is 13.68% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch hotfix-080126

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Content.Server/Backmen/Language/LanguageSystem.cs (1)

135-151: Несоответствие типов при вызове UpdateEntityLanguages.

На строке 150 вызывается UpdateEntityLanguages(uid.Owner) с EntityUid, но сигнатура метода на строке 176 ожидает Entity<LanguageSpeakerComponent?, LanguageKnowledgeComponent?>. Это может привести к ошибке компиляции или некорректной работе, если неявное преобразование не поддерживается.

🔧 Предлагаемое исправление
-        UpdateEntityLanguages(uid.Owner);
+        UpdateEntityLanguages((uid.Owner, null, uid.Comp));

Или используйте согласованный паттерн с разрешением обоих компонентов.

🤖 Fix all issues with AI agents
In @Content.Server/Backmen/Blob/Systems/BlobTileSystem.cs:
- Line 11: Удалите неиспользуемый импорт: уберите директиву using
Content.Shared.EntityEffects;. Откройте файл, содержащий класс BlobTileSystem и
удалите строку с этим using, затем пересоберите/перезапустите проверку сборки,
чтобы убедиться, что предупреждение исчезло.

In @Content.Server/Backmen/Language/LanguageSystem.cs:
- Around line 114-130: In AddLanguage, the call UpdateEntityLanguages((ent,
ent.Comp2)) passes the wrong tuple/syntax and component order; replace it with
UpdateEntityLanguages(ent.Owner) so the method receives an
Entity<LanguageSpeakerComponent?, LanguageKnowledgeComponent?> as expected and
the implicit conversion will apply (refer to AddLanguage, UpdateEntityLanguages,
ent.Owner and the LanguageSpeaker/LanguageKnowledge component types).

In @Content.Server/EntityEffects/Effects/MakeSentientEntityEffectSystem.cs:
- Around line 19-22: Fix the misspelled comment markers "start-bakcmen" and
"end-backmen" to "start-backmen" and "end-backmen" (both occurrences) around the
language block that contains the lines with "private static readonly
ProtoId<LanguagePrototype> GlobalHuman = \"TauCetiBasic\";" and "[Dependency]
private readonly LanguageSystem _languageSystem = default!;"; ensure both the
opening and closing markers match "start-backmen" / "end-backmen".

In @Content.Shared/Backmen/Psionics/SharedPsionicsSystem.cs:
- Line 44: Change the instance field PsionicsDisabled to a static readonly field
on SharedPsionicsSystem so the ProtoId<StatusEffectPrototype> value is shared
across all instances; update the declaration of PsionicsDisabled to be static
readonly and ensure any references to PsionicsDisabled remain valid (no other
behavioral changes needed).

In @Resources/Prototypes/_Backmen/Entities/Mobs/NPCs/glimmer_monsters.yml:
- Around line 202-212: В HTN-цепочке обнаружено несогласованное использование
utility-запросов: на этапе выбора цели используется NearbyGunWispTargets, а в
UtilityService — NearbyGunTargets, которые отличаются предикатами
(TargetIsAliveOrSoftCritCon vs TargetIsAliveCon); приведите их к единому
поведению либо явно задокументируйте причину различия: либо замените
UtilityService.proto на тот же запрос (NearbyGunWispTargets) чтобы критерии
выбора и обновления совпадали, либо добавьте комментарий рядом с сервисом
(UtilityService id: RangedService proto: NearbyGunTargets) объясняющий, почему
для обновления цели требуется более строгий/инной предикат, и убедитесь что
соответствующие пред- и постусловия (KeyExistsPrecondition/Target) согласованы с
этим изменением.

In @Resources/Prototypes/Reagents/medicine.yml:
- Around line 299-303: The ReagentCondition inside the AdjustPainFeels block is
missing the required reagent field; update the condition for the
!type:ReagentCondition in the AdjustPainFeels entry to include reagent: Dexalin
(matching the pattern used elsewhere in this file, e.g., other ReagentCondition
entries) so the condition explicitly targets the Dexalin reagent.
- Around line 336-341: В блоке с !type:AdjustPainFeels добавьте в объект
!type:ReagentCondition обязательное поле reagent, чтобы условие содержало
идентификатор реагента для проверки передозировки (например: reagent:
"<reagent_id>"); проверьте все подобные !type:ReagentCondition в этом
файле/шаблоне и добавьте соответствующий reagent для каждого случая, сохранив
существующие поля min, amount и randomise, чтобы условие корректно срабатывало.
🧹 Nitpick comments (12)
Content.Server/Backmen/RoleWhitelist/WhitelistSystem.cs (1)

40-40: Изменение корректно, но обнаружена несогласованность.

Преобразование SpecieDiona из instance поля в static уместно, поскольку это константное значение, используемое только для сравнения. Однако, обратите внимание на строку 55: поле DionaReform имеет аналогичное назначение (идентификатор прототипа с константным значением), но осталось instance полем. Для согласованности рекомендуется также сделать DionaReform статическим.

♻️ Предлагаемое изменение для согласованности
-    private readonly EntProtoId DionaReform = "MobDionaReformed";
+    private static readonly EntProtoId DionaReform = "MobDionaReformed";
Content.Server/Backmen/Chapel/SacrificialAltarSystem.cs (1)

59-60: Правильная оптимизация: преобразование полей в статические.

Изменение этих полей на static readonly является корректным и следует лучшим практикам. Поскольку значения представляют собой неизменяемые идентификаторы прототипов, которые не зависят от состояния экземпляра, их совместное использование на уровне класса улучшает эффективность памяти.

Необязательное замечание: В строке 59 в имени прототипа есть опечатка: "AltarStandartTable" (вероятно, должно быть "AltarStandardTable"). Однако эта опечатка существовала до данного изменения и не относится к текущему рефакторингу.

Content.Server/Backmen/Vampiric/BkmVampireLevelingSystem.cs (2)

199-199: Рассмотрите применение static readonly для единообразия.

Поле VmpShop объявлено как instance readonly, в то время как аналогичные поля BVampieBat и BVampieMouse (строки 216-217) теперь являются static readonly. Поскольку все три поля представляют константные идентификаторы прототипов, было бы логично применить единый паттерн и сделать VmpShop также static readonly.

♻️ Предлагаемое изменение для единообразия
-    private readonly EntProtoId VmpShop = "VmpShop";
+    private static readonly EntProtoId VmpShop = "VmpShop";

240-244: Запутывающие названия enum значений.

Значение VampireStoreType.SkillMouse1 создаёт действие превращения в летучую мышь (BVampieBat), а не в мышь. Это может вводить в заблуждение при сопровождении кода. Рассмотрите возможность переименования enum значений в более описательные имена, например SkillBat и SkillMouse, чтобы отражать фактическую функциональность.

Resources/Prototypes/_Backmen/Reagents/psionic.yml (2)

89-95: Существенное изменение поведения: проверьте игровой баланс.

Изменения в LotophagoiOil:

  1. Время действия увеличено с 5 до 20 секунд (в 4 раза)
  2. Добавлено условие min: 5 единиц реагента
  3. Изменён тип эффекта с GenericStatusEffect на ModifyStatusEffect

Эти изменения значительно влияют на игровую механику. Убедитесь, что новая продолжительность и порог активации соответствуют задуманному балансу.

Рекомендуется протестировать новые параметры в игре и убедиться, что:

  • Эффект активируется при достижении 5 единиц
  • Длительность 20 секунд не создаёт дисбаланс
  • Новый тип эффекта ModifyStatusEffect работает корректно с StatusEffectSeeingRainbow

39-58: Рассмотрите использование уникальных идентификаторов для каждого типа травмы.

Все пять эффектов AdjustTraumas используют одинаковый identifier: "PsionicRegenerationEssence". Хотя система поддерживает это (модификаторы организма и нервов keyed как (identifier, effectOwner) пары), это не соответствует паттерну, используемому в остальной кодовой базе. В medicine.yml каждый реагент использует уникальный идентификатор (Inaprovaline, Oculine, Cognizine).

Для большей ясности и согласованности кода рекомендуется использовать специфичные идентификаторы:

  • "PsionicRegenerationEssence_BoneDamage"
  • "PsionicRegenerationEssence_OrganDamage"
  • "PsionicRegenerationEssence_VeinsDamage"
  • "PsionicRegenerationEssence_NerveDamage"
  • "PsionicRegenerationEssence_Dismemberment"
Content.Server/Backmen/Blob/Systems/BlobCarrierSystem.cs (1)

43-44: Изменение BlobLang корректно, но есть несоответствие в стиле.

Поле BlobLang правильно преобразовано в static readonly. Однако соседнее поле ActionTransformToBlob (строка 43) остаётся экземплярным readonly. Для единообразия стоит рассмотреть преобразование обоих полей в static readonly, так как оба являются константными идентификаторами.

♻️ Опциональный рефакторинг для единообразия
-    private readonly EntProtoId ActionTransformToBlob = "ActionTransformToBlob";
+    private static readonly EntProtoId ActionTransformToBlob = "ActionTransformToBlob";
     private static readonly ProtoId<LanguagePrototype> BlobLang = "Blob";
Content.Server/Backmen/Soul/GolemSystem.cs (1)

118-119: Изменение GolemNames корректно, но стиль неоднороден.

Преобразование GolemNames в static readonly правильное. Обратите внимание, что поля AdminObserver (строка 118) и Ash (строка 181) остаются экземплярными readonly. Если цель PR — унификация константных идентификаторов как static readonly, стоит рассмотреть обновление и этих полей.

♻️ Опциональный рефакторинг для единообразия
-    private readonly EntProtoId AdminObserver = "AdminObserver";
+    private static readonly EntProtoId AdminObserver = "AdminObserver";
     private static readonly ProtoId<LocalizedDatasetPrototype> GolemNames = "NamesGolem";
-    private readonly EntProtoId Ash = "Ash";
+    private static readonly EntProtoId Ash = "Ash";
Content.Shared/Body/Systems/SharedBodySystem.Body.cs (1)

358-358: Рассмотрите проверку результата вставки в контейнер.

На линии 358 результат Containers.Insert(childPart, container) не проверяется, в отличие от аналогичного кода в MapInitParts (линия 201), где неудачная вставка приводит к удалению части и логированию ошибки.

♻️ Предлагаемое исправление
-                        Containers.Insert(childPart, container);
+                        if (!Containers.Insert(childPart, container))
+                        {
+                            Log.Error($"Could not insert part for connection {connection} in body restoration");
+                            QueueDel(childPart);
+                            continue;
+                        }
Content.Shared/Backmen/Blob/Components/BlobMobComponent.cs (1)

24-24: Рассмотрите уровень доступа для CureTick.

Поле CureTick является внутренним состоянием для системы BlobMobSystem. Рекомендуется сделать его приватным с публичным геттером или добавить [ViewVariables] для отладки в VV.

♻️ Предлагаемое исправление
-    public int CureTick = 0;
+    [ViewVariables]
+    public int CureTick { get; set; } = 0;
Content.Server/Backmen/Language/TranslatorSystem.cs (1)

131-138: Рассмотрите перемещение констант в начало класса.

Константы TurnOn и TurnOff объявлены после их первого использования (строка 131). По соглашениям C#, статические readonly поля обычно размещаются в начале класса, рядом с другими полями-зависимостями.

♻️ Предлагаемый рефакторинг
 public sealed class TranslatorSystem : SharedTranslatorSystem
 {
     [Dependency] private readonly SharedContainerSystem _containers = default!;
     [Dependency] private readonly PopupSystem _popup = default!;
     [Dependency] private readonly LanguageSystem _language = default!;
     [Dependency] private readonly PowerCellSystem _powerCell = default!;
+
+    private static readonly LocId TurnOn = "translator-component-turnon";
+    private static readonly LocId TurnOff = "translator-component-shutoff";

     public override void Initialize()

И удалить строки 137-139.

Content.Shared/Backmen/Language/Components/Translators/BaseTranslatorComponent.cs (1)

2-2: Неиспользуемый импорт.

Импорт Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List больше не используется, так как кастомные сериализаторы для языковых списков были удалены.

♻️ Предлагаемое исправление
 using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between d679503 and f755c4e.

📒 Files selected for processing (65)
  • Content.Client/Backmen/Blob/BlobObserverSystem.cs
  • Content.Client/Backmen/Flesh/FleshCultist.cs
  • Content.Client/Backmen/Overlays/Shaders/EtherealOverlay.cs
  • Content.Client/Backmen/Overlays/Systems/NearsightedSystem.cs
  • Content.Client/Backmen/StationAI/AiEnemySystem.cs
  • Content.Client/Backmen/Teams/TdmTeamSystem.cs
  • Content.Client/Backmen/Vampiric/BloodSuckerSystem.cs
  • Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs
  • Content.Server/Backmen/Abilities/Psionics/Abilities/PsionicRegenerationPowerSystem.cs
  • Content.Server/Backmen/Abilities/Psionics/PsionicAbilitiesSystem.cs
  • Content.Server/Backmen/Administration/Bwoink/Gpt/GptCommands.cs
  • Content.Server/Backmen/Antag/SuperPsi/AutoPsiSystem.cs
  • Content.Server/Backmen/Arrivals/CentcommSystem.cs
  • Content.Server/Backmen/Blob/Systems/BlobCarrierSystem.cs
  • Content.Server/Backmen/Blob/Systems/BlobCoreSystem.cs
  • Content.Server/Backmen/Blob/Systems/BlobFactorySystem.cs
  • Content.Server/Backmen/Blob/Systems/BlobMobSystem.cs
  • Content.Server/Backmen/Blob/Systems/BlobTileSystem.cs
  • Content.Server/Backmen/Chapel/SacrificialAltarSystem.cs
  • Content.Server/Backmen/Cloning/MetempsychoticMachineSystem.cs
  • Content.Server/Backmen/Economy/ATM/ATMSystem.cs
  • Content.Server/Backmen/Flesh/FleshCultistSystem.cs
  • Content.Server/Backmen/FootPrint/PuddleFootPrintsSystem.cs
  • Content.Server/Backmen/Fugitive/FugitiveSystem.cs
  • Content.Server/Backmen/GibOnCollide/Systems/GibOnCollideSystem.cs
  • Content.Server/Backmen/Language/Commands/AdminTranslatorCommand.cs
  • Content.Server/Backmen/Language/LanguageSystem.cs
  • Content.Server/Backmen/Language/TranslatorSystem.cs
  • Content.Server/Backmen/Mood/MoodSystem.cs
  • Content.Server/Backmen/NPC/Queries/Considerations/TargetIsAliveOrSoftCritCon.cs
  • Content.Server/Backmen/Psionics/Glimmer/GlimmerReactiveSystem.cs
  • Content.Server/Backmen/Psionics/Invisbility/PsionicInvisibilitySystem.cs
  • Content.Server/Backmen/Psionics/PsionicsSystem.cs
  • Content.Server/Backmen/Research/Oracle/OracleSystem.cs
  • Content.Server/Backmen/RoleWhitelist/WhitelistSystem.cs
  • Content.Server/Backmen/ShipVsShip/ShipVsShipGame.cs
  • Content.Server/Backmen/Shipwrecked/ShipwreckedRuleSystem.cs
  • Content.Server/Backmen/Soul/GolemSystem.cs
  • Content.Server/Backmen/SpecForces/SpecForcesSystem.cs
  • Content.Server/Backmen/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs
  • Content.Server/Backmen/StationAI/AiEnemySystem.cs
  • Content.Server/Backmen/Surgery/Consciousness/Systems/ServerConsciousnessSystem.cs
  • Content.Server/Backmen/Vampiric/BkmVampireLevelingSystem.cs
  • Content.Server/Backmen/Xeno/XenoAgentSystem.cs
  • Content.Server/EntityEffects/Effects/MakeSentientEntityEffectSystem.cs
  • Content.Server/NPC/Systems/NPCUtilitySystem.cs
  • Content.Server/Shuttles/Systems/ShuttleSystem.Impact.cs
  • Content.Server/Silicons/StationAi/StationAiSystem.cs
  • Content.Shared/Backmen/Abilities/Psionics/Abilities/MassSleep/MassSleepPowerSystem.cs
  • Content.Shared/Backmen/Blob/Components/BlobMobComponent.cs
  • Content.Shared/Backmen/EntityEffects/Effects/AdjustTraumas.cs
  • Content.Shared/Backmen/Language/Components/LanguageKnowledgeComponent.cs
  • Content.Shared/Backmen/Language/Components/Translators/BaseTranslatorComponent.cs
  • Content.Shared/Backmen/Psionics/SharedPsionicsSystem.cs
  • Content.Shared/Backmen/Teams/SharedTdmTeamSystem.cs
  • Content.Shared/Body/Systems/SharedBodySystem.Body.cs
  • Content.Shared/Mobs/Systems/MobStateSystem.cs
  • Content.Shared/RCD/Systems/RCDSystem.cs
  • Content.Shared/Salvage/SharedSalvageSystem.Magnet.cs
  • Content.Shared/Silicons/StationAi/SharedStationAiSystem.cs
  • Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml
  • Resources/Prototypes/Reagents/medicine.yml
  • Resources/Prototypes/_Backmen/Entities/Mobs/NPCs/glimmer_monsters.yml
  • Resources/Prototypes/_Backmen/Entities/Mobs/NPCs/root.yml
  • Resources/Prototypes/_Backmen/Reagents/psionic.yml
💤 Files with no reviewable changes (1)
  • Resources/Prototypes/_Backmen/Entities/Mobs/NPCs/root.yml
🧰 Additional context used
🧬 Code graph analysis (6)
Content.Server/Backmen/Flesh/FleshCultistSystem.cs (2)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • LanguagePrototype (66-74)
Content.Shared/Backmen/Language/Systems/SharedLanguageSystem.cs (1)
  • LanguagePrototype (32-36)
Content.Server/EntityEffects/Effects/MakeSentientEntityEffectSystem.cs (1)
Content.Server/Backmen/Language/LanguageSystem.cs (4)
  • LanguagePrototype (66-74)
  • LanguageSystem (11-227)
  • AddLanguage (114-130)
  • SetLanguage (100-109)
Content.Server/Backmen/Language/TranslatorSystem.cs (1)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • SetLanguage (100-109)
Content.Server/Backmen/Xeno/XenoAgentSystem.cs (2)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • LanguagePrototype (66-74)
Content.Shared/Backmen/Language/Systems/SharedLanguageSystem.cs (1)
  • LanguagePrototype (32-36)
Content.Server/Backmen/Blob/Systems/BlobCarrierSystem.cs (2)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • LanguagePrototype (66-74)
Content.Shared/Backmen/Language/Systems/SharedLanguageSystem.cs (1)
  • LanguagePrototype (32-36)
Content.Shared/Body/Systems/SharedBodySystem.Body.cs (2)
Content.Server/Backmen/Surgery/Consciousness/Systems/ServerConsciousnessSystem.cs (1)
  • OnRejuvenate (384-434)
Content.Server/Silicons/StationAi/StationAiSystem.cs (1)
  • OnRejuvenate (322-335)
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: Test Packaging
  • GitHub Check: build (ubuntu-latest)
🔇 Additional comments (89)
Content.Server/Backmen/FootPrint/PuddleFootPrintsSystem.cs (1)

25-25: Отличное улучшение!

Изменение поля WaterId с private readonly на private static readonly семантически корректно и оптимально. Поскольку это константное значение, которое не меняется между экземплярами, использование static уменьшает потребление памяти и явно выражает намерение.

Content.Server/Backmen/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs (1)

56-56: Оптимизация выглядит корректно.

Преобразование поля ShadowkinPower из экземплярного в статическое является правильным решением, так как это константный идентификатор прототипа, который не зависит от состояния экземпляра. Это позволяет избежать дублирования значения в памяти для каждого экземпляра системы без каких-либо функциональных изменений.

Content.Server/Backmen/Mood/MoodSystem.cs (1)

44-44: Изменение корректно: константа правильно объявлена как статическая.

Преобразование поля MoodCategory из экземплярного в статическое уместно, поскольку значение является константой идентификатора категории. Это сокращает накладные расходы памяти на экземпляр и соответствует лучшим практикам для константных значений прототипов.

Content.Server/Backmen/Xeno/XenoAgentSystem.cs (1)

20-20: Отличное улучшение: преобразование в статическое поле.

Изменение поля XenoLanguage на static readonly является правильным решением, поскольку значение "Xeno" представляет собой константный идентификатор прототипа, который не изменяется между экземплярами системы. Это улучшает эффективность использования памяти и семантически более корректно отражает назначение поля.

Content.Shared/Backmen/Teams/SharedTdmTeamSystem.cs (1)

96-98: Технически корректное изменение, но стоит уточнить назначение PR.

Преобразование полей TeamAFaction, TeamBFaction и TeamNeutralFaction в static readonly является правильной практикой, так как идентификаторы прототипов являются константами и должны быть общими для всех экземпляров класса. Это улучшает эффективность использования памяти.

Однако, эти изменения выглядят как рефакторинг, а не исправление критической ошибки. Название PR "Hotfix 08.01.26" предполагает срочное исправление бага. Если эти изменения действительно являются частью hotfix'а, рекомендуется пояснить, какую конкретную проблему они решают.

Content.Client/Backmen/Teams/TdmTeamSystem.cs (1)

25-27: Изменение соответствует лучшим практикам.

Преобразование полей TeamA, TeamB и TeamNoTeam в static readonly технически корректно и следует общепринятым практикам для константных идентификаторов прототипов. Это изменение согласуется с аналогичными изменениями в SharedTdmTeamSystem.cs и обеспечивает единообразие кодовой базы.

Поля используются только для чтения в методе OnGetTeamIcon, поэтому изменение области видимости на static безопасно и эффективно.

Content.Shared/Silicons/StationAi/SharedStationAiSystem.cs (1)

79-79: Отличное улучшение!

Преобразование поля в static readonly является правильным решением для константного идентификатора прототипа. Это повышает эффективность памяти и ясно показывает, что значение является общим для всех экземпляров класса.

Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs (2)

67-68: Отличное улучшение: преобразование в статические константы.

Преобразование этих полей в static readonly логически правильно, так как они представляют собой константные идентификаторы прототипов, которые не изменяются между экземплярами класса. Это снижает использование памяти и явно указывает на намерение использовать их как константы уровня класса.


98-98: LGTM: корректное преобразование в статическую константу.

Преобразование _crewsimovLawset в static readonly соответствует его использованию в качестве константного идентификатора набора законов. Изменение согласуется с общей схемой оптимизации в этом PR.

Content.Server/Backmen/Antag/SuperPsi/AutoPsiSystem.cs (1)

70-70: Изменение технически корректно, но необычно для hotfix.

Преобразование JobPrisoner в static readonly является правильным решением для константного prototype ID - это уменьшает накладные расходы на память и следует лучшим практикам для неизменяемых значений. Все использования поля (строки 87, 136, 246, 254) совместимы со static readonly.

Однако это изменение выглядит как рефакторинг, а не исправление критической ошибки. Для hotfix обычно ожидаются только критические исправления багов.

Пожалуйста, подтвердите, что это изменение действительно необходимо в рамках hotfix, а не должно быть отложено до обычного релиза с рефакторингом.

Content.Server/Backmen/Shipwrecked/ShipwreckedRuleSystem.cs (3)

642-642: Хорошее улучшение производительности.

Преобразование поля в static readonly уместно для константного идентификатора прототипа. Это уменьшает использование памяти, так как значение теперь хранится один раз на уровне класса, а не в каждом экземпляре.


943-945: Корректная оптимизация констант.

Преобразование идентификаторов прототипов кратеров в статические поля соответствует лучшим практикам. Все три поля содержат неизменяемые значения и используются только для чтения в методе MakeCrater.


1888-1889: LGTM! Улучшение согласованности кода.

Преобразование тегов в статические поля завершает рефакторинг константных идентификаторов в этом классе. Изменения безопасны и улучшают эффективность использования памяти.

Content.Server/Backmen/Vampiric/BkmVampireLevelingSystem.cs (1)

216-217: Изменение на static readonly выглядит корректно.

Преобразование полей BVampieBat и BVampieMouse из instance readonly в static readonly семантически правильно, так как это константные идентификаторы прототипов, которые не изменяются для каждого экземпляра. Это снижает накладные расходы на память и соответствует паттерну, описанному в контексте PR.

Content.Shared/Backmen/EntityEffects/Effects/AdjustTraumas.cs (8)

29-38: Отличная оптимизация производительности!

Использование кэшированных entity queries вместо прямых обращений к EntityManager является правильным паттерном для улучшения производительности в ECS-системах. Инициализация выполнена корректно с вызовом base.Initialize().


46-46: Правильный выбор структуры данных.

Использование HashSet<EntityUid> вместо List<EntityUid> гарантирует уникальность целей, что является логичным для данного контекста.


50-56: Четкая и производительная реализация.

LINQ-запрос с использованием _woundableQuery.HasComponent() обеспечивает более быстрый доступ к компонентам по сравнению с прямыми обращениями к EntityManager.


61-66: Последовательная оптимизация.

Аналогичная оптимизация для органов, согласованная с обработкой частей тела.


72-72: Корректное изменение метода выбора.

Замена PickAndTake() на Pick() является правильным решением, так как:

  • possibleTraumaTargets — локальная переменная, которая не используется повторно после выбора цели
  • HashSet не гарантирует порядок элементов, что делает семантику PickAndTake менее актуальной
  • Избегается ненужное изменение коллекции

78-78: Эффективная миграция на query-based доступ.

Использование _organQuery.TryGetComponent() и _woundableQuery.GetComponent() вместо прямых обращений к EntityManager значительно улучшает производительность за счет кэшированных запросов компонентов.

Also applies to: 93-93


95-95: Использование идиоматичного метода.

TryComp() является предпочтительным сокращением для TryGetComponent() в Robust Toolbox.


138-138: Последовательная оптимизация обращений к NerveComponent.

Миграция на _nerveQuery.TryComp() завершает оптимизацию доступа к компонентам в этом классе. Полученный компонент nerve корректно передается в методы _pain системы.

Also applies to: 162-162

Resources/Prototypes/Entities/Structures/Specific/Atmospherics/sensor.yml (1)

28-40: Все определения типов газов и пороговых прототипов присутствуют в кодовой базе.

Добавленные маппинги корректны. Проверка подтвердила, что:

  • Все 11 типов газов (BZ, Pluoxium, Hydrogen, Nitrium, Healium, HyperNoblium, ProtoNitrate, Zauker, Halon, Helium, AntiNoblium) определены в Resources/Prototypes/_Backmen/Atmospherics/gases.yml
  • Все ссылки на пороговые прототипы (stationBZ, stationPluoxium и т.д.) существуют в Resources/Prototypes/Atmospherics/Thresholds/airalarms.yml
  • YAML синтаксис и отступы соответствуют существующему паттерну
Resources/Prototypes/Reagents/medicine.yml (6)

203-227: LGTM!

Блоки AdjustTraumas корректно добавлены с условием температуры, соответствующим существующему EvenHealthChange. Комментарий точно описывает, что лечатся все органы кроме мозга и глаз.


500-506: LGTM!

Лечение повреждений лёгких логично сочетается с существующим эффектом Inaprovaline по снижению удушья в критическом состоянии.


777-779: LGTM!

Уменьшение болевых ощущений (amount: -0.03) корректно для лечебного реагента.


912-914: LGTM!

Безусловное подавление боли соответствует концепции Omnizine как универсального лекарства.


992-998: LGTM!

Лечение травм глаз логично дополняет существующий эффект EyeDamage для Oculine.


1011-1017: LGTM!

Лечение повреждений мозга соответствует назначению Cognizine как реагента, связанного с когнитивными функциями.

Resources/Prototypes/_Backmen/Entities/Mobs/NPCs/glimmer_monsters.yml (5)

112-126: LGTM!

Конфигурация HTN для сущности выглядит корректно. Blackboard параметры определены правильно, rootTask ссылается на WispCombatCompound, который определён ниже в файле.


156-177: LGTM!

Логика приоритетов корректна: побег из контейнера → освобождение от захвата → переход к бою. Порог minPercent: 0.001 обеспечивает переход к стрельбе при наличии любого количества боеприпасов.


188-196: Проверьте использование rangeKey: MeleeRange для дальнобойного боя.

В WispGunCombatCompound используется rangeKey: MeleeRange, хотя это compound для дальнобойного боя с оружием. Возможно, следует использовать RangedRange, который определён в blackboard сущности (линия 123-124).

♻️ Возможное исправление
     - !type:HTNPrimitiveTask
       operator: !type:MoveToOperator
         shutdownState: PlanFinished
         pathfindInPlanning: true
         removeKeyOnFinish: false
         targetKey: TargetCoordinates
         pathfindKey: TargetPathfind
         stopOnLineOfSight: true
-        rangeKey: MeleeRange
+        rangeKey: RangedRange

214-236: LGTM!

Utility-запрос NearbyGunWispTargets хорошо структурирован. Комбинация InverseBoolCurve для критических/оглушённых целей и BoolCurve для обязательных условий (жив, доступен, в зоне видимости) обеспечивает разумную приоритизацию целей.


143-154: Внешние HTN-задачи корректно определены.

DrainPsionicCompound и WispIdleCompound существуют в кодовой базе (определены в Resources/Prototypes/_Backmen/Entities/Mobs/NPCs/root.yml). Ссылки в WispCombatCompound валидны.

Content.Server/Backmen/Abilities/Psionics/Abilities/PsionicRegenerationPowerSystem.cs (3)

16-16: LGTM! Необходимый импорт для типобезопасной работы с реагентами.

Добавление using Content.Shared.Chemistry.Reagent обеспечивает поддержку нового подхода с использованием ProtoId<ReagentPrototype>.


94-95: LGTM! Отличное улучшение типобезопасности.

Замена строковых ссылок на реагенты типобезопасным ProtoId<ReagentPrototype> снижает риск опечаток и повышает надёжность кода. Поле правильно объявлено как private static readonly.


110-110: Прототип реагента корректно определён и используется согласованно.

Проверка подтверждает, что PsionicRegenerationEssence правильно:

  • Определён как статический readonly ProtoId<ReagentPrototype> (линия 94)
  • Соответствует прототипу в YAML (Resources/Prototypes/_Backmen/Reagents/psionic.yml)
  • Используется последовательно на линии 110

Изменение кода корректно.

Resources/Prototypes/_Backmen/Reagents/psionic.yml (3)

96-100: LGTM! Упрощение условий.

Удаление явной ссылки на реагент LotophagoiOil из условий выглядит как корректное упрощение, так как контекст уже находится внутри определения этого реагента.


108-111: LGTM! Условие осталось без изменений функциональности.

Условие для LotoTranscendence moodlet сохранено с порогом min: 6, что выглядит корректно.


132-135: LGTM! Условие ChemRemovePsionic корректно.

Условие активации эффекта удаления псионики при достижении 5 единиц SoulbreakerToxin выглядит разумно.

Content.Server/Backmen/Psionics/Invisbility/PsionicInvisibilitySystem.cs (1)

45-46: Отличное рефакторинг-изменение!

Преобразование полей идентификаторов прототипов в static readonly является правильным подходом для констант, которые не изменяются между экземплярами. Это уменьшает накладные расходы на память и чётко выражает намерение, что эти значения являются константами уровня типа.

Content.Server/Backmen/StationAI/AiEnemySystem.cs (1)

36-36: Правильное изменение.

Константный идентификатор фракции корректно преобразован в статическое поле. Это соответствует лучшим практикам C# для неизменяемых идентификаторов прототипов.

Content.Server/Backmen/Economy/ATM/ATMSystem.cs (1)

73-74: Корректное рефакторинг-изменение.

Преобразование идентификаторов материала и валюты в статические поля является правильным решением. Эти константы не должны изменяться между экземплярами ATMSystem, и статическое хранение оптимально для таких случаев.

Content.Server/Backmen/Cloning/MetempsychoticMachineSystem.cs (1)

36-37: Правильное преобразование полей пулов.

Идентификаторы пулов для метемпсихоза корректно преобразованы в статические константы. Это соответствует общему паттерну рефакторинга в данном PR и является правильным подходом для неизменяемых идентификаторов прототипов.

Content.Server/Backmen/Psionics/PsionicsSystem.cs (1)

121-122: Отличное завершение паттерна рефакторинга.

Преобразование идентификаторов фракций в статические поля завершает последовательный паттерн оптимизации во всех файлах этого PR. Изменения корректны и следуют лучшим практикам для констант уровня типа.

Content.Server/Backmen/SpecForces/SpecForcesSystem.cs (1)

92-92: Оптимизация памяти применена корректно.

Преобразование поля Rxbzz в static readonly уменьшает расход памяти на экземпляр, так как идентификатор прототипа является константой и может быть общим для всех экземпляров класса.

Content.Shared/RCD/Systems/RCDSystem.cs (1)

49-50: Рефакторинг соответствует существующему паттерну.

Преобразование полей деконструкции в static readonly согласуется с уже существующим полем CatwalkTag на строке 51, обеспечивая единообразие кода и снижая накладные расходы памяти.

Content.Client/Backmen/Overlays/Shaders/EtherealOverlay.cs (1)

18-18: LGTM!

Статическое поле для идентификатора прототипа шейдера корректно, так как каждый экземпляр по-прежнему создаёт собственный экземпляр шейдера через InstanceUnique() на строке 23.

Content.Server/Backmen/Research/Oracle/OracleSystem.cs (1)

126-126: Изменение корректно.

Преобразование ResearchDisk5000 в статическое поле снижает потребление памяти, так как идентификатор таблицы прототипов не изменяется между экземплярами.

Content.Server/Backmen/Fugitive/FugitiveSystem.cs (1)

63-63: Оптимизация применена корректно.

Статическое поле FugitiveRole снижает накладные расходы памяти, сохраняя идентификатор прототипа роли на уровне класса, где он используется для проверки роли на строке 275.

Content.Client/Backmen/Flesh/FleshCultist.cs (1)

21-21: Отличное улучшение!

Преобразование FleshcultistFaction в статическое поле правильно, так как значение ProtoId является константой и одинаково для всех экземпляров. Это снижает потребление памяти.

Content.Server/Backmen/Arrivals/CentcommSystem.cs (1)

251-252: LGTM!

Преобразование StationCentComMapPool и StationCentComMapDefault в статические поля корректно. Оба содержат константные идентификаторы прототипов, которые не изменяются между экземплярами.

Content.Server/Shuttles/Systems/ShuttleSystem.Impact.cs (1)

54-54: Правильное изменение.

Поле _platingId корректно преобразовано в статическое, так как идентификатор плиток одинаков для всех экземпляров системы.

Content.Server/Backmen/GibOnCollide/Systems/GibOnCollideSystem.cs (1)

31-31: Изменение одобрено.

BiologicalDamageContainerPrototype правильно сделан статическим полем — идентификатор контейнера повреждений является константой.

Content.Server/Backmen/Psionics/Glimmer/GlimmerReactiveSystem.cs (1)

267-267: LGTM!

Преобразование Electrocution в статическое поле соответствует лучшим практикам, так как идентификатор эффекта статуса является константой.

Content.Server/Backmen/Blob/Systems/BlobTileSystem.cs (1)

39-39: Отличное улучшение!

Преобразование поля BlobFaction в static readonly — это правильная оптимизация. Поскольку значение прототипа является константой и не зависит от экземпляра, это уменьшает использование памяти и повышает производительность.

Content.Server/Backmen/Surgery/Consciousness/Systems/ServerConsciousnessSystem.cs (1)

48-48: Правильная оптимизация.

Преобразование AsphyxiationDamageType в static readonly корректно, так как идентификатор типа урона является константой, которая не должна храниться в каждом экземпляре класса.

Content.Shared/Salvage/SharedSalvageSystem.Magnet.cs (1)

32-32: LGTM!

Изменение _asteroidOreWeights на static readonly соответствует общему паттерну оптимизации в данном PR. Поле содержит константный идентификатор прототипа, который не требует хранения на уровне экземпляра.

Content.Server/Backmen/ShipVsShip/ShipVsShipGame.cs (1)

88-88: Отличное улучшение с двойным эффектом!

Это изменение не только делает поле статическим (как в других файлах), но и добавляет модификатор readonly, который отсутствовал в оригинальном коде. Это предотвращает случайное изменение значения и улучшает безопасность кода.

Content.Client/Backmen/Overlays/Systems/NearsightedSystem.cs (1)

23-23: Корректное изменение.

Преобразование TagName в static readonly соответствует общему паттерну оптимизации в этом PR и правильно применено для константного идентификатора тега.

Content.Client/Backmen/StationAI/AiEnemySystem.cs (1)

25-25: LGTM!

Преобразование константного ProtoId в static readonly — корректная оптимизация, уменьшающая выделение памяти на экземпляр. Значение неизменяемо и безопасно для совместного использования между экземплярами.

Content.Server/Backmen/Administration/Bwoink/Gpt/GptCommands.cs (1)

152-152: LGTM!

Изменение DefaultRuleset на static readonly корректно — это константный идентификатор прототипа, который не зависит от состояния экземпляра.

Content.Client/Backmen/Vampiric/BloodSuckerSystem.cs (1)

24-24: LGTM!

Константный ProtoId для VampireFaction корректно преобразован в static readonly. Значение используется один раз при инициализации для индексации прототипа.

Content.Server/Backmen/Abilities/Psionics/PsionicAbilitiesSystem.cs (1)

86-86: LGTM!

Преобразование RandomPsionicPowerPool в static readonly — стандартная оптимизация для константных идентификаторов прототипов. Использование в методах AddRandomPsionicPower и RemovePsionics остаётся неизменным.

Content.Client/Backmen/Blob/BlobObserverSystem.cs (1)

35-35: LGTM!

Изменение BlobFaction на static readonly корректно. Это константный идентификатор прототипа, используемый для отображения иконки статуса.

Content.Shared/Backmen/Abilities/Psionics/Abilities/MassSleep/MassSleepPowerSystem.cs (1)

53-53: LGTM!

Преобразование ProtoId в static readonly корректно — это неизменяемая структура с константным значением, которая будет разделяться между всеми экземплярами класса.

Content.Server/Silicons/StationAi/StationAiSystem.cs (1)

63-72: LGTM!

Преобразование полей ProtoId в static readonly корректно. Все значения являются константами и не требуют хранения на уровне экземпляра. Это соответствует паттерну рефакторинга, применяемому в данном PR.

Content.Server/Backmen/Flesh/FleshCultistSystem.cs (2)

82-82: LGTM!

Поле FleshLang корректно преобразовано в static readonly — значение константно и используется для регистрации языка у культистов.


274-274: LGTM!

Поле MutationPoint корректно преобразовано в static readonly — используется как идентификатор алерта с постоянным значением.

Content.Shared/Body/Systems/SharedBodySystem.Body.cs (2)

248-257: LGTM! Хорошее выделение публичного API.

Метод ForceRestoreBody корректно инкапсулирует логику восстановления тела, что позволяет использовать её из других систем (например, BlobMobSystem). Атрибут [PublicAPI] правильно документирует намерение.


419-422: LGTM!

Делегирование OnRejuvenate к ForceRestoreBody с использованием AsNullable() — чистый подход, устраняющий дублирование кода.

Content.Server/Backmen/Blob/Systems/BlobCoreSystem.cs (1)

59-61: LGTM!

Преобразование полей BlobHealth, BlobResource и BlobMoney в static readonly корректно. Значения констант используются для алертов и валюты, не требуя хранения на уровне экземпляра.

Content.Shared/Backmen/Blob/Components/BlobMobComponent.cs (1)

26-27: LGTM!

CureBodyInterval правильно инкапсулирован с private set и атрибутом [DataField] для конфигурации через прототипы.

Content.Server/Backmen/Blob/Systems/BlobFactorySystem.cs (1)

74-81: LGTM!

Преобразование всех полей ProtoId<ReagentPrototype> в static readonly корректно. Идентификаторы реагентов являются константами и используются в FillSmokeGas для создания растворов дыма.

Content.Shared/Mobs/Systems/MobStateSystem.cs (1)

34-41: LGTM!

Метод IsAliveOrSoftCrit корректно следует паттерну существующих методов проверки состояния (IsAlive, IsCritical, IsDead). Логика правильная: использует Resolve для получения компонента и проверяет состояние через pattern matching.

Content.Server/Backmen/NPC/Queries/Considerations/TargetIsAliveOrSoftCritCon.cs (1)

1-8: LGTM!

Класс-маркер для системы considerations. Логика обработки реализована в NPCUtilitySystem.GetScore (строки 337-342), что соответствует паттерну других considerations (TargetIsAliveCon, TargetIsCritCon).

Content.Server/EntityEffects/Effects/MakeSentientEntityEffectSystem.cs (1)

34-38: Корректная интеграция языковой системы.

Порядок вызовов правильный: сначала AddLanguage добавляет способность говорить на языке, затем SetLanguage устанавливает его как текущий. Согласно API LanguageSystem (строки 99-108 в relevant snippets), SetLanguage проверяет CanSpeak, поэтому порядок критичен.

Content.Server/NPC/Systems/NPCUtilitySystem.cs (1)

337-342: LGTM!

Новый case для TargetIsAliveOrSoftCritCon корректно интегрирован в switch-выражение. Паттерн идентичен соседним considerations (TargetIsAliveCon, TargetIsCritCon), возвращает 1f при успехе и 0f в противном случае.

Content.Server/Backmen/Blob/Systems/BlobMobSystem.cs (2)

145-160: Логика восстановления тела корректна.

Метод OnPulsed правильно обрабатывает:

  1. Применение урона и эффектов исцеления каждый pulse
  2. Guard clause для отключения восстановления тела при CureBodyInterval <= 0
  3. Инкремент и сброс CureTick для периодического вызова ForceRestoreBody

117-144: Параметры для EyeDamage уже установлены по умолчанию.

Класс EyeDamage (Content.Shared/EntityEffects/Effects/Body/EyeDamageEntityEffectSystem.cs) имеет поле Amount = -1 по умолчанию, что соответствует поведению исцеления. Отрицательное значение (-1) указывает на уменьшение урона глазам, что совпадает с логикой AdjustTraumas в массиве. Использование new EyeDamage() без явных параметров является корректным и применит ожидаемый эффект восстановления.

Content.Shared/Backmen/Language/Components/LanguageKnowledgeComponent.cs (1)

17-24: LGTM!

Рефакторинг с List<string> на List<ProtoId<LanguagePrototype>> — правильное улучшение типизации. Это обеспечивает проверку валидности прототипов на этапе компиляции и согласуется с изменениями в LanguageSystem и TranslatorSystem.

Content.Server/Backmen/Language/Commands/AdminTranslatorCommand.cs (1)

106-128: LGTM!

Изменение возвращаемых типов с IEnumerable<string> на IEnumerable<ProtoId<LanguagePrototype>> для методов ListSpoken, ListUnderstood и ListRequired согласуется с обновлёнными типами в BaseTranslatorComponent. Это обеспечивает типобезопасность и консистентность API.

Content.Server/Backmen/Language/TranslatorSystem.cs (3)

11-11: LGTM!

Импорт Robust.Shared.Prototypes необходим для использования ProtoId<LanguagePrototype> в методе CheckLanguagesMatch.


124-124: LGTM!

Вызов SetLanguage корректно обновлён для использования составной сущности (holder, languageComp), что соответствует новой сигнатуре метода в LanguageSystem.cs.


181-188: LGTM!

Сигнатура CheckLanguagesMatch корректно обновлена для использования ICollection<ProtoId<LanguagePrototype>>, что обеспечивает типобезопасность языковых идентификаторов и согласуется с изменениями в BaseTranslatorComponent и LanguageKnowledgeComponent.

Content.Shared/Backmen/Language/Components/Translators/BaseTranslatorComponent.cs (1)

11-25: LGTM!

Переход от List<string> к List<ProtoId<LanguagePrototype>> для полей SpokenLanguages, UnderstoodLanguages и RequiredLanguages обеспечивает типобезопасность на этапе компиляции и согласованность с обновлённым API языковой системы.

Content.Server/Backmen/Language/LanguageSystem.cs (3)

41-61: LGTM!

Методы CanUnderstand и CanSpeak корректно обновлены для использования ProtoId<LanguagePrototype> вместо строковых идентификаторов, сохраняя при этом логику проверки универсального языка.


100-109: LGTM!

Метод SetLanguage правильно использует ProtoId<LanguagePrototype> и корректно разрешает компонент через _languageSpeakerQuery.Resolve.


176-212: LGTM!

Метод UpdateEntityLanguages корректно обновлён для работы с составной сущностью. Логика разрешения компонентов через Resolve и заполнения событий языков реализована правильно.

using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Destructible;
using Content.Shared.EntityEffects;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for EntityEffects usage in the file
rg 'EntityEffect' Content.Server/Backmen/Blob/Systems/BlobTileSystem.cs

Repository: Rxup/space-station-14

Length of output: 100


🏁 Script executed:

#!/bin/bash
# Read the file to check actual usage
cat -n Content.Server/Backmen/Blob/Systems/BlobTileSystem.cs

Repository: Rxup/space-station-14

Length of output: 10355


Удалите неиспользуемый импорт.

Директива using Content.Shared.EntityEffects; на строке 11 не используется в файле и должна быть удалена.

🤖 Prompt for AI Agents
In @Content.Server/Backmen/Blob/Systems/BlobTileSystem.cs at line 11, Удалите
неиспользуемый импорт: уберите директиву using Content.Shared.EntityEffects;.
Откройте файл, содержащий класс BlobTileSystem и удалите строку с этим using,
затем пересоберите/перезапустите проверку сборки, чтобы убедиться, что
предупреждение исчезло.

Comment on lines 114 to 130
public void AddLanguage(
Entity<LanguageKnowledgeComponent?> uid,
string language,
Entity<LanguageKnowledgeComponent?, LanguageSpeakerComponent?> ent,
ProtoId<LanguagePrototype> language,
bool addSpoken = true,
bool addUnderstood = true)
{
EnsureComp<LanguageKnowledgeComponent>(uid, out uid.Comp);
var speaker = EnsureComp<LanguageSpeakerComponent>(uid);
EnsureComp<LanguageKnowledgeComponent>(ent, out ent.Comp1);
EnsureComp<LanguageSpeakerComponent>(ent, out ent.Comp2);

if (addSpoken && !uid.Comp.SpokenLanguages.Contains(language))
uid.Comp.SpokenLanguages.Add(language);
if (addSpoken && !ent.Comp1.SpokenLanguages.Contains(language))
ent.Comp1.SpokenLanguages.Add(language);

if (addUnderstood && !uid.Comp.UnderstoodLanguages.Contains(language))
uid.Comp.UnderstoodLanguages.Add(language);
if (addUnderstood && !ent.Comp1.UnderstoodLanguages.Contains(language))
ent.Comp1.UnderstoodLanguages.Add(language);

UpdateEntityLanguages((uid, speaker));
UpdateEntityLanguages((ent,ent.Comp2));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for UpdateEntityLanguages method definition
ast-grep --pattern 'UpdateEntityLanguages($$$)'

Repository: Rxup/space-station-14

Length of output: 352


🏁 Script executed:

#!/bin/bash
# Search for UpdateEntityLanguages method definition
rg -A 5 "void UpdateEntityLanguages" Content.Server/Backmen/Language/LanguageSystem.cs

Repository: Rxup/space-station-14

Length of output: 365


🏁 Script executed:

#!/bin/bash
# Check for Entity constructor patterns in the codebase to understand how to construct Entity<T1, T2>
rg "Entity<.*,.*>" Content.Server/Backmen/Language/LanguageSystem.cs -A 2 | head -40

Repository: Rxup/space-station-14

Length of output: 972


🏁 Script executed:

#!/bin/bash
# Search for Entity constructor or similar patterns to understand how to properly construct Entity<T1, T2>
rg "new Entity" Content.Server/Backmen/Language/LanguageSystem.cs

Repository: Rxup/space-station-14

Length of output: 47


🏁 Script executed:

#!/bin/bash
# Get full context around the AddLanguage method
sed -n '110,135p' Content.Server/Backmen/Language/LanguageSystem.cs

Repository: Rxup/space-station-14

Length of output: 1068


🏁 Script executed:

#!/bin/bash
# Let's look at the RemoveLanguage method to see if it has the same issue
sed -n '132,160p' Content.Server/Backmen/Language/LanguageSystem.cs

Repository: Rxup/space-station-14

Length of output: 1166


🏁 Script executed:

#!/bin/bash
# Let's look at more of the file to understand the Entity type and find other calls to UpdateEntityLanguages
rg -B 2 -A 2 "UpdateEntityLanguages" Content.Server/Backmen/Language/LanguageSystem.cs

Repository: Rxup/space-station-14

Length of output: 921


🏁 Script executed:

#!/bin/bash
# Search for Entity type definition to understand how it works
find . -name "*.cs" -type f | xargs grep -l "struct Entity<" | head -5

Repository: Rxup/space-station-14

Length of output: 47


🏁 Script executed:

#!/bin/bash
# Search for Entity struct or class definition more broadly
rg "class Entity<|struct Entity<" -A 10 | head -50

Repository: Rxup/space-station-14

Length of output: 47


🏁 Script executed:

#!/bin/bash
# Let's check if Entity has any implicit operators or constructors by looking at imports and usages
head -30 Content.Server/Backmen/Language/LanguageSystem.cs

Repository: Rxup/space-station-14

Length of output: 1389


🏁 Script executed:

#!/bin/bash
# Search for how Entity<T1, T2> is typically instantiated/used with tuple syntax
rg "Entity<.*>.*\(" Content.Server/Backmen/Language/ -A 1 | head -30

Repository: Rxup/space-station-14

Length of output: 47


🏁 Script executed:

#!/bin/bash
# Look at the SharedLanguageSystem to understand Entity usage patterns
find . -name "SharedLanguageSystem.cs" -type f

Repository: Rxup/space-station-14

Length of output: 130


🏁 Script executed:

#!/bin/bash
# Check SharedLanguageSystem for more context on Entity usage
head -50 ./Content.Shared/Backmen/Language/Systems/SharedLanguageSystem.cs

Repository: Rxup/space-station-14

Length of output: 1783


🏁 Script executed:

#!/bin/bash
# Let's search for Entity usage patterns across the codebase to understand constructor patterns
rg "UpdateEntityLanguages" . --type cs -B 3 | head -60

Repository: Rxup/space-station-14

Length of output: 4838


🏁 Script executed:

#!/bin/bash
# Check if there are multiple overloads of UpdateEntityLanguages
rg -A 1 "public.*UpdateEntityLanguages" Content.Server/Backmen/Language/LanguageSystem.cs

Repository: Rxup/space-station-14

Length of output: 179


🏁 Script executed:

#!/bin/bash
# Search for implicit operators involving Entity or tuple conversions
rg "implicit operator" . --type cs -A 3 | grep -A 3 "Entity"

Repository: Rxup/space-station-14

Length of output: 2548


Исправьте передачу параметра в UpdateEntityLanguages на строке 129.

Вызов UpdateEntityLanguages((ent, ent.Comp2)) некорректен. Метод ожидает Entity<LanguageSpeakerComponent?, LanguageKnowledgeComponent?>, а полученный параметр использует неправильный синтаксис и порядок компонентов. Вместо этого следует передать UpdateEntityLanguages(ent.Owner), что соответствует паттерну, используемому в остальной части кода и позволит неявному оператору правильно преобразовать тип.

🤖 Prompt for AI Agents
In @Content.Server/Backmen/Language/LanguageSystem.cs around lines 114 - 130, In
AddLanguage, the call UpdateEntityLanguages((ent, ent.Comp2)) passes the wrong
tuple/syntax and component order; replace it with
UpdateEntityLanguages(ent.Owner) so the method receives an
Entity<LanguageSpeakerComponent?, LanguageKnowledgeComponent?> as expected and
the implicit conversion will apply (refer to AddLanguage, UpdateEntityLanguages,
ent.Owner and the LanguageSpeaker/LanguageKnowledge component types).

Comment on lines 19 to 22
// start-bakcmen: language
private static readonly ProtoId<LanguagePrototype> GlobalHuman = "TauCetiBasic";
[Dependency] private readonly LanguageSystem _languageSystem = default!;
// end-backmen: language
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Опечатка в комментарии-маркере.

На строке 19 написано start-bakcmen вместо start-backmen. Такая же опечатка на строке 35.

🔧 Предлагаемое исправление
-// start-bakcmen: language
+// start-backmen: language

И на строке 35:

-            // start-bakcmen: language
+            // start-backmen: language
📝 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.

Suggested change
// start-bakcmen: language
private static readonly ProtoId<LanguagePrototype> GlobalHuman = "TauCetiBasic";
[Dependency] private readonly LanguageSystem _languageSystem = default!;
// end-backmen: language
// start-backmen: language
private static readonly ProtoId<LanguagePrototype> GlobalHuman = "TauCetiBasic";
[Dependency] private readonly LanguageSystem _languageSystem = default!;
// end-backmen: language
🤖 Prompt for AI Agents
In @Content.Server/EntityEffects/Effects/MakeSentientEntityEffectSystem.cs
around lines 19 - 22, Fix the misspelled comment markers "start-bakcmen" and
"end-backmen" to "start-backmen" and "end-backmen" (both occurrences) around the
language block that contains the lines with "private static readonly
ProtoId<LanguagePrototype> GlobalHuman = \"TauCetiBasic\";" and "[Dependency]
private readonly LanguageSystem _languageSystem = default!;"; ensure both the
opening and closing markers match "start-backmen" / "end-backmen".

protected EntityQuery<PsionicComponent> PsionicQuery { get; set; }

private readonly ProtoId<StatusEffectPrototype> PsionicsDisabled = "PsionicsDisabled";
private static readonly ProtoId<StatusEffectPrototype> PsionicsDisabled = "PsionicsDisabled";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Отличная оптимизация - преобразование в статическое поле.

Изменение поля PsionicsDisabled с экземплярного на статическое является правильным решением, поскольку значение идентификатора прототипа одинаково для всех экземпляров класса. Это уменьшает использование памяти и соответствует аналогичным изменениям в других файлах данного PR.

🤖 Prompt for AI Agents
In @Content.Shared/Backmen/Psionics/SharedPsionicsSystem.cs at line 44, Change
the instance field PsionicsDisabled to a static readonly field on
SharedPsionicsSystem so the ProtoId<StatusEffectPrototype> value is shared
across all instances; update the declaration of PsionicsDisabled to be static
readonly and ensure any references to PsionicsDisabled remain valid (no other
behavioral changes needed).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Resources/Prototypes/_Backmen/Reagents/psionic.yml (1)

137-138: Отсутствует обязательное поле reagent в ReagentCondition.

Поле Reagent в классе ReagentCondition помечено как required: true, но в строке 137-138 оно не указано. Это приведёт к ошибке валидации прототипа при загрузке. Все остальные ReagentCondition в файле (строки 92-94, 100-102, 112-114) содержат это поле.

🔧 Исправление
         - !type:ChemRemovePsionic
           conditions:
             - !type:ReagentCondition
+              reagent: SoulbreakerToxin
               min: 5
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between f755c4e and fbbbedf.

📒 Files selected for processing (3)
  • Resources/Prototypes/Reagents/medicine.yml
  • Resources/Prototypes/Recipes/Reactions/medicine.yml
  • Resources/Prototypes/_Backmen/Reagents/psionic.yml
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: Test Packaging
🔇 Additional comments (12)
Resources/Prototypes/_Backmen/Reagents/psionic.yml (3)

100-102: LGTM!

Создана логичная прогрессия порогов: 5 единиц для визуального эффекта радуги, 20 единиц для более мощного эффекта перебора псионики. Это обеспечивает хорошее игровое равновесие.


89-94: Прототип StatusEffectSeeingRainbow существует и корректно используется.

Протокол статус-эффекта StatusEffectSeeingRainbow определён в Resources/Prototypes/Entities/StatusEffects/misc.yml и успешно применяется в множестве реагентов по всей кодовой базе. Ссылка на этот прототип в строке 90 корректна.


39-58: Все указанные типы травм и эффект AdjustTraumas существуют и корректно реализованы.

Проверка подтвердила наличие всех пяти типов травм (BoneDamage, OrganDamage, VeinsDamage, NerveDamage, Dismemberment) в enum TraumaType и полную реализацию эффекта AdjustTraumas. Эффект правильно обрабатывает все указанные типы травм в цикле switch. Используемый паттерн соответствует установленным в кодовой базе конвенциям (аналогичная реализация в Blob healing system).

Resources/Prototypes/Reagents/medicine.yml (8)

331-343: Эффекты боли для DexalinPlus согласованы с Dexalin.

Добавленные эффекты боли для DexalinPlus являются усиленной версией эффектов Dexalin, что логично для улучшенного препарата. Более сильное подавление боли (amount: 5, time: 30) и более высокий порог передозировки (min: 25) соответствуют концепции.


502-508: Лечение лёгких для Inaprovaline логично соответствует назначению препарата.

Добавление эффекта AdjustTraumas для лечения повреждений лёгких согласуется с основным назначением Inaprovaline как стабилизирующего препарата, который уже лечит асфиксию. Это расширяет функциональность препарата логичным образом.


779-781: Снижение чувствительности к боли для Siderlac уместно.

Добавление эффекта AdjustPainFeels с отрицательным значением (-0.03) для снижения чувствительности к боли согласуется с назначением Siderlac как препарата, лечащего едкие повреждения.


914-916: Подавление боли для Omnizine соответствует универсальному назначению препарата.

Добавление эффекта SuppressPain логично для Omnizine, который предназначен для лечения всех типов повреждений. Умеренная сила эффекта (amount: 3, time: 4) и отсутствие условий соответствуют роли универсального лекарства.


994-1000: Лечение органных повреждений глаз для Oculine логично.

Добавление эффекта AdjustTraumas для лечения органных повреждений глаз дополняет существующий эффект EyeDamage и соответствует специализированному назначению Oculine как глазного препарата.


1013-1019: Лечение повреждений мозга для Cognizine тематически согласовано.

Добавление эффекта AdjustTraumas для лечения органных повреждений мозга соответствует тематике Cognizine как препарата когнитивного улучшения, который уже может делать существ разумными.


293-304: Все компоненты системы боли реализованы корректно.

Эффекты SuppressPain и AdjustPainFeels существуют и работают как задумано:

  • SuppressPain (amount: 4, time: 8) подавляет боль в критическом состоянии, игнорируя боль на уровне нервной системы
  • AdjustPainFeels (amount: 0.04) увеличивает чувствительность к боли при передозировке на все части тела
  • MobStateCondition с mobstate: Critical валидна

Обратите внимание: AdjustPainFeels имеет RandomiseAmount = true по умолчанию. Поскольку в YAML не указано randomise: false, есть 30% вероятность того, что эффект инвертируется и уменьшит чувствительность вместо увеличения. Если это не является целевым поведением (необычный побочный эффект), рассмотрите добавление randomise: false в конфигурацию.


199-227: Все типы эффектов и компоненты органов для Cryoxadone корректно реализованы.

Проверка подтвердила, что все упомянутые компоненты существуют в кодовой базе:

  • Тип эффекта AdjustTraumas реализован в Content.Shared/Backmen/EntityEffects/Effects/AdjustTraumas.cs
  • Типы травм BoneDamage и OrganDamage определены в enum TraumaType
  • Все компоненты органов зарегистрированы: Lung, Ears, Liver, Heart, Stomach
  • Параметры targetBodyParts, targetOrgans и targetComponents работают корректно
Resources/Prototypes/Recipes/Reactions/medicine.yml (1)

323-326: Рецепт MindbreakerToxin корректен и согласован с кодовой базой.

Проверка подтвердила:

  • Реагент Ectoplasm определён и используется в системе (_Backmen мод)
  • Все компоненты рецепта (Silicon, Hydrogen, Dylovene, Ectoplasm) существуют
  • Синтаксис рецепта верен, продукт MindbreakerToxin: 4 валиден
  • Изменение намеренно отмечено комментарием "# backmen"

Использование MindbreakerToxin в других частях кода (гранаты, таблетки, гидропоника) не требует обновления — они зависят от самого вещества, а не от выхода рецепта.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Content.Server/Backmen/Language/LanguageSystem.cs (1)

201-233: КРИТИЧНО: Несогласованность в использовании Comp1/Comp2.

Обнаружена критическая проблема с читаемостью и поддержкой кода:

  • В методе AddLanguage (строки 140-154): Comp1 = LanguageKnowledgeComponent, Comp2 = LanguageSpeakerComponent
  • В методе UpdateEntityLanguages (строки 201-233): Comp1 = LanguageSpeakerComponent, Comp2 = LanguageKnowledgeComponent

Это противоположный порядок компонентов, что крайне опасно для поддержки и может привести к логическим ошибкам. Настоятельно рекомендуется отказаться от паттерна Comp1/Comp2 в пользу именованных переменных или согласованного порядка параметров типа.

🔧 Предлагаемое исправление
-public void UpdateEntityLanguages(Entity<LanguageSpeakerComponent?, LanguageKnowledgeComponent?> entity)
+public void UpdateEntityLanguages(EntityUid entityUid)
 {
-    if (!_languageSpeakerQuery.Resolve(entity, ref entity.Comp1, logMissing: false))
+    if (!TryComp<LanguageSpeakerComponent>(entityUid, out var speaker))
         return;
 
-    Log.Debug($"{ToPrettyString(entity.Owner)} UpdateEntityLanguages");
+    Log.Debug($"{ToPrettyString(entityUid)} UpdateEntityLanguages");
 
     var ev = new DetermineEntityLanguagesEvent
     {
-        EntityUid = entity
+        EntityUid = entityUid
     };
     // We add the intrinsically known languages first so other systems can manipulate them easily
-    if (Resolve(entity, ref entity.Comp2, logMissing: false))
+    if (TryComp<LanguageKnowledgeComponent>(entityUid, out var knowledge))
     {
-        foreach (var spoken in entity.Comp2.SpokenLanguages)
+        foreach (var spoken in knowledge.SpokenLanguages)
         {
             ev.SpokenLanguages.Add(spoken);
         }
 
-        foreach (var understood in entity.Comp2.UnderstoodLanguages)
+        foreach (var understood in knowledge.UnderstoodLanguages)
         {
             ev.UnderstoodLanguages.Add(understood);
         }
     }
 
-    RaiseLocalEvent(entity, ref ev, false);
+    RaiseLocalEvent(entityUid, ref ev, false);
     RaiseLocalEvent(ref ev);
 
-    entity.Comp1.SpokenLanguages.Clear();
-    entity.Comp1.UnderstoodLanguages.Clear();
+    speaker.SpokenLanguages.Clear();
+    speaker.UnderstoodLanguages.Clear();
 
-    entity.Comp1.SpokenLanguages.AddRange(ev.SpokenLanguages);
-    entity.Comp1.UnderstoodLanguages.AddRange(ev.UnderstoodLanguages);
+    speaker.SpokenLanguages.AddRange(ev.SpokenLanguages);
+    speaker.UnderstoodLanguages.AddRange(ev.UnderstoodLanguages);
 
-    if (!EnsureValidLanguage(entity))
-        RaiseLocalEvent(entity, new LanguagesUpdateEvent());
+    if (!EnsureValidLanguage(entityUid))
+        RaiseLocalEvent(entityUid, new LanguagesUpdateEvent());
 }
🤖 Fix all issues with AI agents
In @Content.Server/Backmen/Disease/Effects/DiseaseGenericStatusEffect.cs:
- Around line 63-72: The Refresh flag logic is inverted in
DiseaseGenericStatusEffect: when args.DiseaseEffect.Type ==
StatusEffectDiseaseType.Add you must call TrySetStatusEffectDuration when
args.DiseaseEffect.Refresh is true (to refresh/replace duration) and call
TryAddStatusEffectDuration when Refresh is false (to accumulate/add time);
update the if/else in the Add branch to swap the two method calls
(_effectsSystem.TrySetStatusEffectDuration and
_effectsSystem.TryAddStatusEffectDuration) so they match the DataField
semantics.

In @Content.Server/Backmen/Language/LanguageSystem.cs:
- Around line 38-45: The OnCanUsePaper handler currently uses CanSpeak to block
paper writing and sets a hardcoded Russian message; change the logic to check
CanUnderstand(ent.AsNullable(), GlobalHuman) instead of CanSpeak, and replace
the hardcoded string assignment to args.FailReason with a localized call using
Loc.GetString("paper-write-blocked-no-language"); also add the suggested
localization key/value ("paper-write-blocked-no-language": "Вы не можете
написать на бумаге, так как не понимаете TauCetiBasic") to the localization
files so the message is translatable.
- Line 66: The test fails because CanUnderstand now expects a
ProtoId<LanguagePrototype> but the test passes a string; update the failing
LanguageTest to supply a ProtoId<LanguagePrototype> instead of "TauCetiBasic" —
either construct a ProtoId<LanguagePrototype> with the same ID or obtain the
ProtoId from the prototype system and pass that into CanUnderstand (the method
name to fix is CanUnderstand on LanguageSystem and the test location is the call
that currently passes the string).

In @Resources/Prototypes/_Backmen/StatusEffects/speech.yml:
- Around line 30-31: The inline comment for the chance value is wrong: the key
chance: 0.4 corresponds to 40%, not 20%; update the comment in
Resources/Prototypes/_Backmen/StatusEffects/speech.yml so it matches the value
(e.g., change “# 20%” to “# 40%”), or if the intended chance was 20% change
chance to 0.2 and keep the comment as “# 20%”; adjust either the numeric value
or the comment so they are consistent.
🧹 Nitpick comments (5)
Content.Server/Backmen/Speech/Components/LanguageAccentComponent.cs (1)

6-14: LGTM!

Компонент LanguageAccentComponent корректно определён с обязательным полем Language и опциональным Chance с разумным значением по умолчанию 0.2f. Структура соответствует паттернам ECS-компонентов проекта.

Рекомендуется добавить XML-документацию для компонента и его полей для улучшения понимания назначения:

♻️ Предложение
+/// <summary>
+/// Компонент для применения языкового акцента к сущности.
+/// </summary>
 [RegisterComponent]
 public sealed partial class LanguageAccentComponent : Component
 {
+    /// <summary>
+    /// Идентификатор языкового прототипа для акцента.
+    /// </summary>
     [DataField(required: true)]
     public ProtoId<LanguagePrototype> Language { get; set; }

+    /// <summary>
+    /// Вероятность применения акцента (0.0 - 1.0).
+    /// </summary>
     [DataField]
     public float Chance { get; set; } = 0.2f;
 }
Content.Server/Animals/Systems/ParrotMemorySystem.cs (2)

107-108: Добавьте документацию для параметра lang.

Параметр lang не имеет описания в XML-комментарии. Рекомендуется добавить краткое описание, например: "Language identifier for the learned message".

📝 Предлагаемое улучшение документации
-    /// <param name="lang"></param>
+    /// <param name="lang">Language identifier for the learned message</param>
     public void TryLearn(Entity<ParrotMemoryComponent?, ParrotListenerComponent?> entity, string incomingMessage, EntityUid source, ProtoId<LanguagePrototype> lang) // backmen

148-148: Передача языка в память работает корректно, но требуется документация.

Параметр lang корректно передаётся через всю цепочку до конструктора SpeechMemory. Однако отсутствует описание параметра в XML-комментарии метода Learn (строка 157).

📝 Предлагаемое улучшение документации
-    /// <param name="lang"></param>
+    /// <param name="lang">Language identifier for the learned message</param>
     private void Learn(Entity<ParrotMemoryComponent> entity, string message, EntityUid source, ProtoId<LanguagePrototype> lang) // backmen

Also applies to: 157-158, 170-170

Content.Server/Backmen/Language/LanguageSystem.cs (2)

47-52: Рассмотрите добавление валидации параметров.

Метод использует ent.Comp.Chance и ent.Comp.Language без проверки валидности. Хотя IRobustRandom.Prob обычно корректно обрабатывает граничные случаи, явная валидация улучшит надёжность кода.

♻️ Предлагаемое улучшение с валидацией
 private void OnLangAccent(Entity<LanguageAccentComponent> ent, ref AccentGetEvent args)
 {
+    if (ent.Comp.Chance <= 0 || string.IsNullOrEmpty(ent.Comp.Language))
+        return;
+        
     if(!_random.Prob(ent.Comp.Chance))
         return;
     args.LanguageOverride = ent.Comp.Language;
 }

140-154: Рассмотрите рефакторинг для улучшения читаемости.

Использование ent.Comp1 и ent.Comp2 для двух разных компонентов на одной сущности затрудняет понимание кода. Неочевидно, что Comp1 — это LanguageKnowledgeComponent, а Comp2 — это LanguageSpeakerComponent. Рекомендуется использовать именованные переменные для ясности.

♻️ Предлагаемый рефакторинг
 public void AddLanguage(
-    Entity<LanguageKnowledgeComponent?, LanguageSpeakerComponent?> ent,
+    EntityUid entity,
     ProtoId<LanguagePrototype> language,
     bool addSpoken = true,
     bool addUnderstood = true)
 {
-    EnsureComp<LanguageKnowledgeComponent>(ent, out ent.Comp1);
-    EnsureComp<LanguageSpeakerComponent>(ent, out ent.Comp2);
+    var knowledge = EnsureComp<LanguageKnowledgeComponent>(entity);
+    var speaker = EnsureComp<LanguageSpeakerComponent>(entity);
 
-    if (addSpoken && !ent.Comp1.SpokenLanguages.Contains(language))
-        ent.Comp1.SpokenLanguages.Add(language);
+    if (addSpoken && !knowledge.SpokenLanguages.Contains(language))
+        knowledge.SpokenLanguages.Add(language);
 
-    if (addUnderstood && !ent.Comp1.UnderstoodLanguages.Contains(language))
-        ent.Comp1.UnderstoodLanguages.Add(language);
+    if (addUnderstood && !knowledge.UnderstoodLanguages.Contains(language))
+        knowledge.UnderstoodLanguages.Add(language);
 
-    UpdateEntityLanguages((ent,ent.Comp2));
+    UpdateEntityLanguages(entity);
 }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between fbbbedf and 151cefe.

📒 Files selected for processing (16)
  • Content.Server/Animals/Systems/ParrotMemorySystem.cs
  • Content.Server/Backmen/Disease/Effects/DiseaseGenericStatusEffect.cs
  • Content.Server/Backmen/Language/LanguageSystem.cs
  • Content.Server/Backmen/Speech/Components/LanguageAccentComponent.cs
  • Content.Server/Chat/Systems/ChatSystem.cs
  • Content.Server/EntityEffects/Effects/MakeSentientEntityEffectSystem.cs
  • Content.Server/Speech/AccentSystem.cs
  • Content.Server/Vocalization/Systems/VocalizationSystem.cs
  • Content.Shared/Animals/Components/ParrotMemoryComponent.cs
  • Content.Shared/Chat/SharedChatEvents.cs
  • Content.Shared/Speech/AccentEvent.cs
  • Resources/Prototypes/_Backmen/Diseases/furry_virus.yml
  • Resources/Prototypes/_Backmen/Diseases/infectious.yml
  • Resources/Prototypes/_Backmen/Diseases/noninfectious.yml
  • Resources/Prototypes/_Backmen/Reagents/psionic.yml
  • Resources/Prototypes/_Backmen/StatusEffects/speech.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • Content.Server/EntityEffects/Effects/MakeSentientEntityEffectSystem.cs
🧰 Additional context used
🧬 Code graph analysis (8)
Content.Shared/Speech/AccentEvent.cs (1)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • LanguagePrototype (91-99)
Content.Shared/Animals/Components/ParrotMemoryComponent.cs (1)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • LanguagePrototype (91-99)
Content.Server/Backmen/Speech/Components/LanguageAccentComponent.cs (1)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • LanguagePrototype (91-99)
Content.Server/Animals/Systems/ParrotMemorySystem.cs (1)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • LanguagePrototype (91-99)
Content.Server/Vocalization/Systems/VocalizationSystem.cs (3)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • LanguagePrototype (91-99)
Content.Server/Chat/Systems/ChatSystem.cs (2)
  • TrySendInGameICMessage (145-159)
  • TrySendInGameICMessage (162-267)
Content.Shared/Chat/SharedChatSystem.cs (2)
  • TrySendInGameICMessage (344-356)
  • TrySendInGameICMessage (370-383)
Content.Shared/Chat/SharedChatEvents.cs (1)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • LanguagePrototype (91-99)
Content.Server/Chat/Systems/ChatSystem.cs (2)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • LanguagePrototype (91-99)
Content.Shared/Chat/SharedChatEvents.cs (2)
  • TransformSpeechEvent (31-42)
  • TransformSpeechEvent (37-41)
Content.Server/Backmen/Language/LanguageSystem.cs (2)
Content.Server/Speech/AccentSystem.cs (1)
  • Initialize (13-16)
Content.Shared/Speech/AccentEvent.cs (2)
  • AccentGetEvent (6-26)
  • AccentGetEvent (21-25)
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Test Packaging
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: build (ubuntu-latest)
🔇 Additional comments (28)
Resources/Prototypes/_Backmen/Reagents/psionic.yml (4)

39-58: LGTM!

Добавленные эффекты AdjustTraumas имеют согласованную структуру и корректные идентификаторы, соответствующие ID реагента. Покрытие всех типов травм (BoneDamage, OrganDamage, VeinsDamage, NerveDamage, Dismemberment) обеспечивает комплексный эффект регенерации.


89-96: LGTM!

Миграция на ModifyStatusEffect с effectProto соответствует общему паттерну изменений в PR. Добавление ReagentCondition с минимальным порогом 5 единиц обеспечивает контролируемое применение эффекта.


97-102: LGTM!

Условие ReagentCondition с порогом в 20 единиц для ChemRerollPsionic корректно вложено и обеспечивает более высокий барьер для активации мощного эффекта перебросa псионических способностей.


103-106: Проверьте отсутствие поля type в ModifyStatusEffect для Scrambled и Slurred.

В отличие от ModifyStatusEffect для StatusEffectSeeingRainbow (строки 89-96), где явно указан type: Add, эти записи не содержат данного поля. Это несоответствие заметно, поскольку в других файлах проекта StatusEffectScrambled используется с type: Update (например, в elements.yml и medicine.yml). Уточните, намеренно ли здесь используются значения по умолчанию или это требует явного указания типа операции для соответствия остальному коду.

Content.Server/Vocalization/Systems/VocalizationSystem.cs (5)

5-7: Зависимости для поддержки языков добавлены корректно.

Импорты и инъекция IPrototypeManager необходимы для разрешения прототипов языков.

Also applies to: 24-24


70-70: Передача языка из события работает корректно.

Параметр tryVocalizeEvent.Language правильно передаётся в метод Speak.


76-76: Расширение сигнатуры метода соответствует требованиям.

Опциональный параметр language добавлен корректно, обеспечивая обратную совместимость.


134-134: Изменение публичного API: TryVocalizeEvent расширен полем Language.

Добавление опционального параметра Language в record struct является breaking change для кода, который явно конструирует это событие с позиционными параметрами. Однако использование значений по умолчанию обеспечивает совместимость для большинства случаев.

Проверьте все места создания TryVocalizeEvent в кодовой базе:

#!/bin/bash
# Поиск всех мест создания TryVocalizeEvent

# Найти конструирование события
rg -nP 'new TryVocalizeEvent\(' --type cs -C3

92-95: Убедитесь в корректной обработке неудачного поиска прототипа языка.

Метод TryIndex возвращает false, если прототип не найден, но результат не проверяется. Однако система чата полностью поддерживает null значения для параметра languageOverride через оператор нулевого слияния (line 217 ChatSystem.cs): var language = languageOverride ?? _language.GetLanguage(source);. Таким образом, если languagePrototype остаётся null, система автоматически использует язык по умолчанию для сущности. Несмотря на это, рекомендуется явно проверить результат TryIndex для большей ясности и явного указания намерения кода.

Content.Shared/Chat/SharedChatEvents.cs (1)

35-35: Добавление поля Language выполнено корректно.

Опциональное поле Language типа LanguagePrototype? добавлено в TransformSpeechEvent без нарушения существующего API. Nullable тип обеспечивает обратную совместимость.

Content.Server/Speech/AccentSystem.cs (2)

4-4: Зависимости добавлены корректно.

Импорт Robust.Shared.Prototypes и инъекция IPrototypeManager необходимы для разрешения прототипов языков.

Also applies to: 10-10


23-31: Логика переопределения языка реализована правильно.

Код корректно проверяет наличие LanguageOverride и результат TryIndex перед использованием прототипа. Null-безопасность обеспечена паттерн-матчингом.

Resources/Prototypes/_Backmen/Diseases/noninfectious.yml (2)

27-31: Прототипы статус-эффектов уже определены и используются правильно.

Оба требуемых прототипа существуют в кодовой базе:

  • StatusEffectForcedSleeping определен в Resources/Prototypes/Entities/StatusEffects/misc.yml
  • StatusEffectSpeechXeno определен в Resources/Prototypes/_Backmen/StatusEffects/speech.yml

Миграция со старых названий на новые завершена успешно и протоколы используются корректно.


107-116: Прототип StatusEffectSpeechXeno определён корректно.

Прототип найден в Resources/Prototypes/_Backmen/StatusEffects/speech.yml (строки 8-13). Он правильно настроен с компонентом XenoAccent, который обеспечивает ожидаемое поведение ксеноморфного акцента. Использование единого ключа StatusEffectSpeechXeno в обоих заболеваниях (XenoVirus и XenoMaidVirus) с разными вероятностями (0.1 для стадии 1 и 0.4 для стадии 2) имеет правильную реализацию.

Resources/Prototypes/_Backmen/Diseases/furry_virus.yml (1)

82-91: Прототип StatusEffectOwO существует и корректно определён.

Прототип StatusEffectOwO успешно найден в Resources/Prototypes/Entities/StatusEffects/speech.yml и содержит компонент OwOAccent в своей конфигурации. Миграция с системы прямого использования компонента на использование прототипа выполнена правильно и соответствует определённому прототипу.

Content.Shared/Speech/AccentEvent.cs (1)

1-2: LGTM!

Добавление свойства LanguageOverride типа ProtoId<LanguagePrototype>? корректно расширяет API события для поддержки переопределения языка при обработке акцентов. Импорты соответствуют используемым типам.

Also applies to: 19-20

Content.Shared/Animals/Components/ParrotMemoryComponent.cs (1)

2-5: LGTM!

Расширение SpeechMemory полем Language типа ProtoId<LanguagePrototype> корректно добавляет поддержку языков для запоминаемых фраз. Изменение сигнатуры record struct согласовано с обновлениями в ParrotMemorySystem.cs.

Also applies to: 62-63

Resources/Prototypes/_Backmen/Diseases/infectious.yml (1)

178-186: LGTM!

Миграция на новые идентификаторы статус-эффектов (StatusEffectSpeechMonkey, StatusEffectForcedSleeping, StatusEffectLangOldFastCodesAccent, StatusEffectLangFleshAccent, StatusEffectOwO, StatusEffectScrambled) выполнена последовательно и соответствует определениям в Resources/Prototypes/_Backmen/StatusEffects/speech.yml.

Also applies to: 231-243, 258-262, 318-319, 351-352

Content.Server/Chat/Systems/ChatSystem.cs (2)

427-427: LGTM!

Вызовы TransformSpeech в SendEntitySpeak и SendEntityWhisper корректно обновлены для передачи language по ссылке, что позволяет методу изменять язык при необходимости.

Also applies to: 500-500


887-904: Сигнатура TransformSpeech корректно обновлена с передачей языка по ссылке.

Логика переопределения языка через TransformSpeechEvent.Language реализована правильно. Все вызовы метода в строках 427 и 500 (SendEntityMessage и SendEntityWhisper) переданы с параметром ref language, что позволяет обновить язык для вызывающего кода. Других вызовов TransformSpeech в кодовой базе нет.

Content.Server/Backmen/Disease/Effects/DiseaseGenericStatusEffect.cs (1)

21-22: LGTM!

Миграция Key на тип EntProtoId и обновление зависимости на Shared.StatusEffectNew.StatusEffectsSystem корректно согласуют код с новой системой статус-эффектов на основе прототипов.

Also applies to: 56-56

Resources/Prototypes/_Backmen/StatusEffects/speech.yml (1)

1-22: LGTM!

Определения статус-эффектов StatusEffectSpeechMonkey, StatusEffectSpeechXeno и StatusEffectLangFleshAccent корректно расширяют MobStatusEffectBase и используют соответствующие компоненты акцентов.

Content.Server/Animals/Systems/ParrotMemorySystem.cs (3)

11-11: Импорты корректны.

Добавленные директивы using необходимы для работы с ProtoId<LanguagePrototype> и соответствуют изменениям в сигнатурах методов.

Also applies to: 18-18


68-68: Корректная передача языка с fallback.

Использование args.Language?.ID ?? "Universal" обеспечивает безопасное значение по умолчанию, когда язык не указан.


76-76: Согласованная обработка языка в событиях радио.

Реализация идентична обработке в OnListen, что обеспечивает консистентность.

Content.Server/Backmen/Language/LanguageSystem.cs (3)

3-3: Зависимости добавлены корректно.

Новые импорты и зависимость IRobustRandom необходимы для реализации проверки записи на бумаге и акцентов с вероятностью.

Also applies to: 7-8, 10-10, 19-19


28-28: Подписки на события настроены корректно.

Новые обработчики событий для проверки записи на бумаге и обработки акцентов зарегистрированы правильно.

Also applies to: 32-32


21-21: Пояснение к константе GlobalHuman: это не "универсальный" язык, а константа для языка по умолчанию (TauCetiBasic). Она служит для проверки, может ли сущность писать на бумаге. UniversalPrototype — это отдельная мета-языковая константа для UniversalLanguageSpeakerComponent, которая предоставляет понимание всех языков. Обе константы предназначены для разных целей и их использование является правильным и преднамеренным, несмотря на то, что в названиях нет явного различия.

Comment on lines +38 to +45
private void OnCanUsePaper(Entity<LanguageSpeakerComponent> ent, ref PaperWriteAttemptEvent args)
{
if (!CanSpeak(ent.AsNullable(), GlobalHuman))
{
args.Cancelled = true;
args.FailReason = "Вы не можете написать на бумаге из за того что не понимаете TauCetiBasic";
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Проверьте логику проверки и локализуйте сообщение об ошибке.

Два замечания:

  1. Логика проверки: Использование CanSpeak для проверки возможности записи на бумаге может быть некорректным. Возможно, следует проверять CanUnderstand, так как письменность больше связана с пониманием языка, чем с устной речью.

  2. Жёстко заданный текст: Сообщение об ошибке на строке 43 захардкожено на русском языке. Следует использовать систему локализации через Loc.GetString() для поддержки многоязычности.

🔧 Предлагаемое исправление
 private void OnCanUsePaper(Entity<LanguageSpeakerComponent> ent, ref PaperWriteAttemptEvent args)
 {
-    if (!CanSpeak(ent.AsNullable(), GlobalHuman))
+    if (!CanUnderstand(ent.AsNullable(), GlobalHuman))
     {
         args.Cancelled = true;
-        args.FailReason = "Вы не можете написать на бумаге из за того что не понимаете TauCetiBasic";
+        args.FailReason = Loc.GetString("paper-write-blocked-no-language");
     }
 }

Потребуется добавить соответствующую локализацию в файлы локализации:

paper-write-blocked-no-language: Вы не можете написать на бумаге, так как не понимаете TauCetiBasic
🤖 Prompt for AI Agents
In @Content.Server/Backmen/Language/LanguageSystem.cs around lines 38 - 45, The
OnCanUsePaper handler currently uses CanSpeak to block paper writing and sets a
hardcoded Russian message; change the logic to check
CanUnderstand(ent.AsNullable(), GlobalHuman) instead of CanSpeak, and replace
the hardcoded string assignment to args.FailReason with a localized call using
Loc.GetString("paper-write-blocked-no-language"); also add the suggested
localization key/value ("paper-write-blocked-no-language": "Вы не можете
написать на бумаге, так как не понимаете TauCetiBasic") to the localization
files so the message is translatable.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @Content.Server/Backmen/Item/PseudoItem/PseudoItemSystem.cs:
- Around line 86-91: The code calls _containerSystem.Remove(ent.Owner,
storage.Container) after TryComp<StorageComponent>(parentUid, out var storage)
but does not guard against storage.Container being null; update the conditional
to only call _containerSystem.Remove when the StorageComponent exists and
storage.Container is not null (i.e., check storage.Container != null) so that
_containerSystem.Remove is never invoked with a null container; use the existing
TryComp<StorageComponent> check around the call that follows
_transformSystem.GetParentUid(ent) to locate where to add the null guard.

In @Content.Shared/Backmen/Item/PseudoItem/SharedPseudoItemSystem.cs:
- Around line 99-100: The current check calls _handsSystem.TryGetActiveItem(uid,
out var item) on the pseudo-item entity (uid) but should check the acting user's
hands; replace the call to use args.User (e.g.,
_handsSystem.TryGetActiveItem(args.User, out var item)) so you verify the user's
active held item, and keep using item.Value as the storage container in the
subsequent logic; ensure any variable names/null-checks are updated accordingly
so you don't assume the pseudo-item has a HandsComponent.
🧹 Nitpick comments (3)
Content.Server/Backmen/Speech/Components/LanguageAccentComponent.cs (1)

12-13: Рассмотрите добавление валидации для поля Chance.

Поле Chance представляет вероятность и должно находиться в диапазоне [0, 1]. Отсутствие проверки границ может привести к логическим ошибкам, если будет установлено недопустимое значение (например, отрицательное или больше 1).

♻️ Рекомендуемое улучшение с валидацией

Если система, использующая компонент, не выполняет валидацию, рассмотрите добавление проверки:

     [DataField, ViewVariables(VVAccess.ReadWrite)]
-    public float Chance { get; set; } = 0.2f;
+    public float Chance
+    {
+        get => _chance;
+        set => _chance = Math.Clamp(value, 0f, 1f);
+    }
+    private float _chance = 0.2f;

Альтернативно, можно добавить XML-документацию, явно указывающую ожидаемый диапазон значений.

Content.Shared/Backmen/EntityEffects/Effects/AdjustTraumas.cs (1)

96-96: Рекомендуется использовать TryGetComponent для defensive coding.

Хотя GetComponent безопасен в данном контексте (цель была отфильтрована на наличие WoundableComponent на строке 54), использование TryGetComponent будет более согласованным с остальным кодом и обеспечит дополнительную защиту от потенциальных изменений в логике фильтрации.

♻️ Предлагаемое улучшение
-                    var comp = _woundableQuery.GetComponent(target);
-                    var bone = comp.Bone.ContainedEntities.FirstOrNull();
-                    if (!_boneQuery.TryComp(bone, out var boneComp))
-                        break;
+                    if (!_woundableQuery.TryGetComponent(target, out var comp))
+                        break;
+                    var bone = comp.Bone.ContainedEntities.FirstOrNull();
+                    if (!_boneQuery.TryComp(bone, out var boneComp))
+                        break;
Content.Shared/Roles/SharedRoleSystem.cs (1)

712-713: Рассмотрите унификацию обработки ошибок для согласованности кода.

В методе используется асимметричный подход к обработке локализации: для roleType применяется Loc.TryGetString с резервным возвратом идентификатора, а для subtype — прямой вызов Loc.GetString. Хотя оба подхода работают корректно (и Loc.GetString широко используется в коде без явной проверки), унификация улучшит читаемость:

♻️ Возможное улучшение для единообразия
-        return string.IsNullOrEmpty(subtype) ? (Loc.TryGetString(roleType, out var val) ? val : roleType) : Loc.GetString(subtype);
+        if (string.IsNullOrEmpty(subtype))
+        {
+            return Loc.TryGetString(roleType, out var val) ? val : roleType;
+        }
+
+        return Loc.TryGetString(subtype, out var subtypeVal) ? subtypeVal : subtype;
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 151cefe and 82c9e4b.

📒 Files selected for processing (8)
  • Content.Server/Backmen/Item/PseudoItem/PseudoItemSystem.cs
  • Content.Server/Backmen/Speech/Components/LanguageAccentComponent.cs
  • Content.Shared/Backmen/EntityEffects/Effects/AdjustTraumas.cs
  • Content.Shared/Backmen/Item/PseudoItem/SharedPseudoItemSystem.cs
  • Content.Shared/Roles/SharedRoleSystem.cs
  • Resources/Prototypes/_Backmen/Entities/Mobs/Species/shadowkin.yml
  • Resources/Prototypes/_Backmen/Reagents/psionic.yml
  • Resources/Prototypes/_Backmen/StatusEffects/speech.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • Resources/Prototypes/_Backmen/StatusEffects/speech.yml
🧰 Additional context used
🧬 Code graph analysis (3)
Content.Shared/Backmen/Item/PseudoItem/SharedPseudoItemSystem.cs (1)
Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs (1)
  • TryGetActiveItem (196-207)
Content.Server/Backmen/Speech/Components/LanguageAccentComponent.cs (1)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • LanguagePrototype (91-99)
Content.Shared/Backmen/EntityEffects/Effects/AdjustTraumas.cs (3)
Content.Server/Backmen/Language/LanguageSystem.cs (1)
  • Initialize (23-36)
Content.Server/Backmen/Blob/Systems/BlobCarrierSystem.cs (1)
  • Initialize (28-41)
Content.Server/Backmen/Blob/Systems/BlobCoreSystem.cs (2)
  • Entity (645-659)
  • Entity (661-706)
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: Test Packaging
🔇 Additional comments (14)
Content.Server/Backmen/Speech/Components/LanguageAccentComponent.cs (1)

1-14: Структура компонента корректна.

Компонент правильно реализован согласно паттернам ECS: используется атрибут [RegisterComponent], поля помечены [DataField] и [ViewVariables], тип ProtoId<LanguagePrototype> соответствует миграции языковой подсистемы. Обязательное поле Language и поле Chance с значением по умолчанию логически обоснованы для компонента акцента.

Resources/Prototypes/_Backmen/Entities/Mobs/Species/shadowkin.yml (1)

20-20: Компонент ShadowkinAccent используется корректно.

Компонент ShadowkinAccent существует в кодовой базе как маркерный компонент без параметров конфигурации (ShadowkinAccentComponent.cs). Система ShadowkinAccentSystem корректно обрабатывает события AccentGetEvent и применяет трансформацию акцента. Применение этого компонента только к сущностям Shadowkin в файле shadowkin.yml логично и правильно. Синтаксис и размещение в YAML соответствуют стандартам проекта.

Content.Shared/Backmen/EntityEffects/Effects/AdjustTraumas.cs (7)

29-32: Отличное добавление EntityQuery полей.

Использование EntityQuery для кэширования запросов компонентов — это стандартная оптимизация производительности в SS14, которая избегает повторных вызовов GetEntityQuery.


34-41: LGTM!

Метод Initialize правильно инициализирует все EntityQuery поля в соответствии с паттерном, используемым в кодовой базе SS14.


49-49: Хорошее изменение: использование HashSet вместо List.

HashSet автоматически предотвращает дублирование целей, что защищает от случаев, когда одна и та же сущность может быть добавлена как часть тела и как орган.


53-59: Логика корректно адаптирована под HashSet.

Замена AddRange на foreach с Add() является правильной адаптацией для работы с HashSet, сохраняя исходную логику фильтрации.


64-69: LGTM!

Изменения согласованы с логикой сбора частей тела и корректно адаптированы для HashSet.


75-75: Правильная замена PickAndTake на Pick.

Поскольку HashSet не поддерживает PickAndTake, и мы выбираем цель только один раз перед немедленным использованием в ApplyTraumaEffects, использование Pick является корректным.


81-81: Отличное использование query-based доступа к компонентам.

Замена прямого доступа через EntityManager на использование EntityQuery полей с TryGetComponent/TryComp — это правильный паттерн для улучшения производительности и безопасности доступа к компонентам.

Also applies to: 98-98, 141-141, 165-165

Resources/Prototypes/_Backmen/Reagents/psionic.yml (1)

92-109: Прототипы статус-эффектов существуют.

Все три прототипа (StatusEffectSeeingRainbow, StatusEffectScrambled и StatusEffectSlurred) определены и корректно используются в кодовой базе.

Content.Server/Backmen/Item/PseudoItem/PseudoItemSystem.cs (4)

22-22: Добавление зависимости ContainerSystem выглядит корректно.

Новая зависимость необходима для использования _containerSystem.Remove в методе ClearState.

Also applies to: 36-36


81-84: Защитная проверка предотвращает повторную очистку.

Ранний выход при !ent.Comp.Active защищает от повторного выполнения логики очистки для уже неактивного состояния.


93-94: Установка состояния и вызов Dirty выполнены корректно.

Стандартный паттерн для обновления состояния компонента и уведомления системы об изменениях.


96-97: RemCompDeferred использование корректно.

Отложенное удаление компонентов — правильный подход для избежания проблем во время обработки событий. Трансформация сущности обрабатывается автоматически через параметр reparent (по умолчанию true) в ContainerSystem.Remove, который переприсоединяет сущность к сетке или карте при удалении из контейнера. Это стандартный паттерн в кодовой базе, используемый в аналогичных системах (CloningPodSystem, MedicalScannerSystem и др.). Явного вызова AttachToGridOrMap не требуется.

Likely an incorrect or invalid review comment.

@KayzelW KayzelW merged commit c2cbc90 into master Jan 8, 2026
11 checks passed
@KayzelW KayzelW deleted the hotfix-080126 branch January 10, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants