Skip to content

[TWEAK] Обнова КПБ - визуал и звуки#2640

Open
kerfus-owo wants to merge 35 commits intoAdventureTimeSS14:masterfrom
kerfus-owo:ipc-visuals
Open

[TWEAK] Обнова КПБ - визуал и звуки#2640
kerfus-owo wants to merge 35 commits intoAdventureTimeSS14:masterfrom
kerfus-owo:ipc-visuals

Conversation

@kerfus-owo
Copy link
Contributor

@kerfus-owo kerfus-owo commented Mar 19, 2026

Описание PR

  • При смерти КПБ, их монитор будет трескаться, а фонарик выключатся. При ремонте и первое и второе будет восстанавливаться.
  • Теперь удалённые через MidroundCustomization слоты будут сохранятся в буфер на случай обратного добавления.
  • Экран: "Красный текст" теперь переименован в просто: "Текст", а его спрайт стал белым.
  • Теперь предсмертный хрип у КПБ корректно работает и имеет актуальный текст.
  • Добавлено немного локали для эмоций.
  • Добавлено три новых особенности для КПБ - Непропорциональный, голосовой модуль (мужской) и голосовой модуль (женский).
  • Теперь в меню редактора экрана у КПБ имеется галочка, отвечающая за то, будет ли их фонарь наследовать цвет экрана.

Вроде бы ничего не забыл...

Почему / Баланс

  • Заслуженный апдейт КПБ за несколько месяцев.

Медиа

Галочка для наследования цвета с экрана у фонаря:
image
Фонарь наследует цвет экрана:
image
Черта непропорциональный (нет слота под комбинезон, встроенные датчики и ячейки под КПК с карманами):
image
Колесо эмоций с одной из особенностей на голосовой модуль (эксклюзивные звуки имеются):
image
Умерший КПБ с сломанным монитором и новым предсмертным хрипом:
image
Новый "красный" текст:
image

Чейнджлог

🆑 Kerfus

  • add: Добавлено три новых эксклюзивные особенности для расы КПБ - Непропорциональный, голосовой модуль (мужской) и голосовой модуль (женский).
  • tweak: Удалённые с помощью MidroundCustomization черты внешности теперь будут сохранятся в буфере на случай повторного добавления. Кратко - монитор КПБ можно будет выключить и включить, при этом не настраивая цвет заново.
  • tweak: Теперь встроенный фонарь КПБ может наследовать цвет их экрана! (изменяется во время раунда.)
  • tweak: Теперь при смерти КПБ, их монитор будет трескаться, а фонарик выключатся. При ремонте, и то и другое будет восстанавливаться.
  • tweak: Изменён экран КПБ: "Красный текст".
  • tweak: Добавлено немного новой локализации для эмоций.
  • fix: Исправлен предсмертный хрип у КПБ, включая актуализацию текста под расу.

@github-actions github-actions bot added Status: Needs Review Changes: UI Изменение интерфейса Changes: Sprites Изменение спрайтов Changes: Localization Изменение локализации Changes: Audio size/M and removed Status: Needs Review labels Mar 19, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 19, 2026

RSI Diff Bot; head commit 585e8b9 merging into 55e3e56
This PR makes changes to 1 or more RSIs. Here is a summary of all changes:

Resources/Textures/ADT/Mobs/Customization/Ipc/ipc_screens.rsi

State Old New Status
ipc_screen_redtext Removed
ipc_screen_broken Added
ipc_screen_text Added

Edit: diff updated after 585e8b9

@Unlumy
Copy link
Collaborator

Unlumy commented Mar 19, 2026

Алло-алло? Да-да, вайбкод

@kerfus-owo
Copy link
Contributor Author

Алло-алло? Да-да, вайбкод

Уволен

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 19, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Коротко: добавлена поддержка управления цветом point‑light в MidroundCustomization (UI-чекбокс, BUI‑сообщение, серверная обработка включения), серверная логика кастомизации расширена: буферизация/восстановление маркировок при удалении/добавлении слотов, правила замены слотов по состоянию моба и привязка point‑light к цвету первой отметки facial‑hair. Также введены изменения для IPC: трейты с whitelist/переписыванием компонентов, новые маркировки/спрайты/звуки/локализации и логика отключения point‑light при смерти.

Possibly related PRs

  • [TWEAK] Босые КПБ #2589: изменения по добавлению/использованию полей whitelist/blacklist и флага переписывания в TraitPrototype — напрямую связаны с внесёнными изменениями трейтов.
  • [TWEAK] Внешность КПБ #1951: правки ассетов и прототипов IPC (markings/RSI/point‑light/дисплей) — пересекаются с изменениями IPC-прототипов и ресурсов.
  • всякая фигня для кебебе #2312: изменения MidroundCustomizationComponent и связанных полей/логики серверной кастомизации — сильная кодовая связь.

Suggested labels

Status: Needs Review

Suggested reviewers

  • Unlumy
  • Schrodinger71
  • FaDeOkno
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.12% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed Заголовок релевантен основным изменениям в PR: обновление визуала и звуков КПБ, включая новые экраны, эмоции и особенности.
Description check ✅ Passed Описание полностью релевантно изменениям: подробно описаны все основные функции (поведение при смерти, буферизация слотов, переименование экрана, звуки и новые особенности).

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

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: 8

Caution

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

⚠️ Outside diff range comments (1)
Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs (1)

190-206: ⚠️ Potential issue | 🟠 Major

Цвет фонарика рассинхронизируется после удаления/добавления слота экрана.

После RemoveMarking/AddMarking вы не пересчитываете point light, а UpdatePointLightColorIfEnabled() при пустом FacialHair просто выходит. В итоге при включённом наследовании фонарик продолжает светить старым цветом до следующего ручного переключения или перекраски.

💡 Что поправить
@@
         _humanoid.RemoveMarking(uid, args.Category, args.Slot);
+        if (args.Category == MarkingCategories.FacialHair)
+            UpdatePointLightColorIfEnabled(uid, component);

         _audio.PlayPvs(component.ChangeMarkingSound, uid);
         UpdateInterface(uid, component);
@@
         _humanoid.AddMarking(uid, markingId, colors.Count > 0 ? colors[0] : Color.White);
         _humanoid.SetMarkingColor(uid, args.Category, newSlotIndex, colors, force: false);
+        if (args.Category == MarkingCategories.FacialHair)
+            UpdatePointLightColorIfEnabled(uid, component);

         UpdateInterface(uid, component);
@@
         if (!TryComp<HumanoidAppearanceComponent>(uid, out var humanoid) ||
             !humanoid.MarkingSet.TryGetCategory(MarkingCategories.FacialHair, out var markings) ||
             markings.Count == 0 || markings[0].MarkingColors.Count == 0)
-            return;
+        {
+            _pointLight.SetColor(uid, component.OriginalPointLightColor);
+            return;
+        }

Also applies to: 227-264, 528-540

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`
around lines 190 - 206, Remove/add slot handlers (e.g., OnRemoveSlotDoAfter and
the corresponding AddSlot handler in MidroundCustomizationSystem) update
markings but do not recalc the facial point light, leaving inherited point light
color stale; after calling _humanoid.RemoveMarking/_humanoid.AddMarking and
UpdateInterface(uid, component) call UpdatePointLightColorIfEnabled(uid,
component) (or the existing point-light update helper) to recompute the point
light color when FacialHair/markings change so the light stays in sync; apply
the same fix to the other similar handlers mentioned (lines around 227-264 and
528-540).
🧹 Nitpick comments (10)
Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs (1)

81-81: Сделайте технический комментарий нейтральным и однозначным

Фраза на Line 81 с “Надеюсь…” выглядит как временная заметка и ухудшает поддержку. Лучше оставить короткое техническое описание причины изменения без субъективной формулировки.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs` at line
81, Replace the subjective Russian inline comment in CrewMonitoringServerSystem
(the comment currently containing “Надеюсь…”) with a neutral, technical one:
succinctly state why the change is needed (e.g., that without this change a
remnant entity with OnMob: true remains in the monitor) and remove any
speculative or personal wording; locate the comment near the
CrewMonitoringServerSystem class/method and update it to a single clear sentence
describing the behavior being fixed.
Content.Shared/Medical/SuitSensors/SuitSensorComponent.cs (1)

99-100: Добавьте /// <summary> для OnMob.

Поле переключает новый режим работы сенсора, но сейчас его смысл приходится искать в SharedSuitSensorSystem. Короткая XML-документация здесь сильно упростит поддержку.

📝 Вариант правки
     //ADT-Tweak-Start
+    /// <summary>
+    ///     Если true, сенсор считается встроенным в моба и привязывает <see cref="User"/> к владельцу сущности.
+    /// </summary>
     [DataField, AutoNetworkedField]
     public bool OnMob = false;
     //ADT-Tweak-End

As per coding guidelines "и предлагай /// summary документацию к C# коду, к важным функциям или классам".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Shared/Medical/SuitSensors/SuitSensorComponent.cs` around lines 99 -
100, Add an XML summary comment for the OnMob field explaining its purpose:
above the [DataField, AutoNetworkedField] public bool OnMob = false; declaration
add a /// <summary> that states this boolean toggles the sensor's new operating
mode (i.e., when true the component uses the alternate/“OnMob” behavior
implemented in SharedSuitSensorSystem), and note default value/behavior if
helpful; ensure the comment is concise and placed immediately above the field
declaration.
Content.Shared/ADT/Silicons/MobIpcComponent.cs (1)

6-13: Рекомендуется добавить XML-документацию для компонента и полей.

Компонент и его поля не имеют /// <summary> документации. Это поможет понять назначение полей другим разработчикам.

📝 Предложенная документация
 namespace Content.Shared.ADT.Silicon;

+/// <summary>
+///     Компонент для управления специфичным поведением IPC (КПБ).
+/// </summary>
 [RegisterComponent]
 public sealed partial class MobIpcComponent : Component
 {
+    /// <summary>
+    ///     Если true - точечный свет (фонарик) будет выключаться при смерти IPC.
+    /// </summary>
     [DataField]
     public bool DisablePointLightOnDeath = false;

+    /// <summary>
+    ///     Флаг, указывающий что свет был выключен из-за смерти (для восстановления при ремонте).
+    /// </summary>
     [DataField]
     public bool LightDisabledByDeath;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Shared/ADT/Silicons/MobIpcComponent.cs` around lines 6 - 13, Добавьте
XML-документацию для компонента и его полей: добавьте /// <summary> описывающий
назначение класса MobIpcComponent и его роли, затем /// <summary> для поля
DisablePointLightOnDeath (объяснить, что делает флаг — отключает ли точечный
свет при смерти) и для поля LightDisabledByDeath (объяснить, что хранит
состояние — было ли свет отключён при смерти). Убедитесь, что комментарии
коротко описывают поведение и возможные значения флагов, используя имена
MobIpcComponent, DisablePointLightOnDeath и LightDisabledByDeath для локализации
изменений.
Content.Shared/ADT/Silicons/MobIpcSystem.cs (1)

6-6: Добавьте /// <summary> для новой системы.

Новый публичный EntitySystem будет проще сопровождать, если сразу зафиксировать, что он отвечает за отключение фонарика IPC при смерти и его восстановление после ремонта.

✍️ Вариант документации
+/// <summary>
+/// Отключает фонарик IPC при смерти и возвращает его состояние после восстановления.
+/// </summary>
 public sealed class MobIpcSystem : EntitySystem
As per coding guidelines: "предлагай /// summary документацию к C# коду, к важным функциям или классам".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Shared/ADT/Silicons/MobIpcSystem.cs` at line 6, Добавьте
XML-документацию для нового публичного класса MobIpcSystem: вставьте над
объявлением класса /// <summary>…</summary> с коротким описанием его
ответственности — отключение фонарика IPC при смерти и восстановление после
ремонта (укажите, что это EntitySystem, управляющая поведением фонарика при
состояниях сущности). Упомяните в тексте класса имя MobIpcSystem и ключевые
сценарии (on death, on repair) чтобы следующий разработчик быстро понял
назначение.
Content.Server/ADT/MidroundCustomization/MidroundCustomizationComponent.cs (3)

1-5: Нарушен алфавитный порядок using.

Согласно гайдлайнам проекта, using должны быть в алфавитном порядке. Content.Shared.Mobs должен быть после Content.Shared.Humanoid.Markings.

♻️ Предлагаемый порядок
 using Content.Shared.DoAfter;
 using Content.Shared.Humanoid.Markings;
+using Content.Shared.Mobs;
 using Robust.Shared.Audio;
 using Robust.Shared.Prototypes;
-using Content.Shared.Mobs;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationComponent.cs`
around lines 1 - 5, Reorder the using directives in
MidroundCustomizationComponent.cs to follow project alphabetical guidelines:
place Content.Shared.Mobs after Content.Shared.Humanoid.Markings and ensure all
other usings (e.g., Content.Shared.DoAfter, Content.Shared.Humanoid.Markings,
Robust.Shared.Audio, Robust.Shared.Prototypes) are sorted alphabetically; update
the top-of-file using block so the usings are in strict alphabetical order.

12-29: Рекомендуется добавить XML-документацию для класса ChangeSlotOnStateEntry.

Класс определяет важную структуру данных для изменения слотов по состоянию моба. Добавление /// <summary> поможет понять назначение класса и его полей.

📝 Предлагаемая документация
 [DataDefinition]
+/// <summary>
+/// Определяет запись для изменения маркинг-слота при определённом состоянии моба.
+/// </summary>
 public sealed partial class ChangeSlotOnStateEntry
 {
+    /// <summary>
+    /// Состояние моба, при котором применяется изменение.
+    /// </summary>
     [DataField(required: true)]
     public MobState State { get; set; }

+    /// <summary>
+    /// Категория маркинга для изменения.
+    /// </summary>
     [DataField(required: true)]
     public MarkingCategories Category { get; set; }

+    /// <summary>
+    /// Номер слота в категории.
+    /// </summary>
     [DataField(required: true)]
     public int Slot { get; set; }

+    /// <summary>
+    /// ID маркинга для установки. Пустая строка означает удаление.
+    /// </summary>
     [DataField(required: true)]
     public string Marking { get; set; } = string.Empty;

+    /// <summary>
+    /// Цвета маркинга.
+    /// </summary>
     [DataField]
     public List<Color> Colors { get; set; } = new();
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationComponent.cs`
around lines 12 - 29, Add XML documentation for the ChangeSlotOnStateEntry data
class: add a /// <summary> on the ChangeSlotOnStateEntry type describing its
role in changing a marking slot when a mob enters a given MobState, and add
brief /// <summary> comments for each public property (State, Category, Slot,
Marking, Colors) explaining what they represent (e.g., State = target MobState,
Category = marking category, Slot = slot index, Marking = marking id/string,
Colors = optional color overrides). Keep descriptions concise and use standard
XML doc tags so IDEs and generated docs will surface the intent.

103-112: Рекомендуется добавить XML-документацию для новых полей.

Поля PointLightColor, PointLightColorEnabled, OriginalPointLightColor, RemovedMarkingsBuffer и OriginalMarkings не имеют описания их назначения.

📝 Предлагаемая документация
+    /// <summary>
+    /// Включает возможность изменения цвета точечного освещения.
+    /// </summary>
     [DataField]
     public bool PointLightColor = false;

+    /// <summary>
+    /// Включён ли в данный момент цвет точечного освещения от экрана.
+    /// </summary>
     [DataField, AutoNetworkedField]
     public bool PointLightColorEnabled;

+    /// <summary>
+    /// Исходный цвет точечного освещения для восстановления.
+    /// </summary>
     public Color OriginalPointLightColor = Color.White;

+    /// <summary>
+    /// Буфер удалённых маркингов для возможного восстановления.
+    /// </summary>
     public Dictionary<MarkingCategories, (string Marking, List<Color> Colors)> RemovedMarkingsBuffer { get; set; } = new();
+
+    /// <summary>
+    /// Оригинальные маркинги по категориям и слотам до изменения состояния.
+    /// </summary>
     public Dictionary<(MarkingCategories Category, int Slot), (string Marking, List<Color> Colors)> OriginalMarkings = new();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationComponent.cs`
around lines 103 - 112, Add XML documentation comments for the new fields to
explain their purpose and usage: add <summary> (and <remarks> where helpful) for
PointLightColor, PointLightColorEnabled, OriginalPointLightColor,
RemovedMarkingsBuffer, and OriginalMarkings; describe that PointLightColor
toggles using a point light color override, PointLightColorEnabled is the
networked toggle, OriginalPointLightColor stores the pre-customization color,
RemovedMarkingsBuffer holds markings temporarily removed keyed by
MarkingCategories, and OriginalMarkings stores original marking data keyed by
(MarkingCategories, slot) so other devs understand intent and
serialization/networking behavior.
Resources/Prototypes/ADT/Voice/speech_emote_sounds.yml (1)

62-66: Непоследовательный отступ в YAML.

Элементы files в коллекциях IPCSpits, IPCMaleCoughs, IPCMaleYawn, IPCFemaleCoughs, IPCFemaleYawn используют 2 пробела вместо 4, что нарушает единообразие форматирования в файле.

♻️ Пример исправления для IPCSpits (строки 64-66)
 - type: soundCollection
   id: IPCSpits
   files:
-  - /Audio/ADT/Voice/IPC/i_spit_1.ogg
-  - /Audio/ADT/Voice/IPC/i_spit_2.ogg
+    - /Audio/ADT/Voice/IPC/i_spit_1.ogg
+    - /Audio/ADT/Voice/IPC/i_spit_2.ogg
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Resources/Prototypes/ADT/Voice/speech_emote_sounds.yml` around lines 62 - 66,
Collections IPCSpits, IPCMaleCoughs, IPCMaleYawn, IPCFemaleCoughs and
IPCFemaleYawn contain `files` entries indented with 2 spaces instead of the
project standard 4; update each `files` list under those collection keys (e.g.,
IPCSpits, IPCMaleCoughs, IPCMaleYawn, IPCFemaleCoughs, IPCFemaleYawn) to use
4-space indentation so the `files` items align uniformly with other collections
in speech_emote_sounds.yml.
Resources/Prototypes/ADT/SoundCollections/emotes.yml (2)

81-90: Непоследовательный отступ в YAML для коллекций IPCMaleCoughs и IPCMaleYawn.

Элементы files используют 2 пробела вместо 4, что нарушает единообразие форматирования.

♻️ Предлагаемое исправление
 - type: soundCollection
   id: IPCMaleCoughs
   files:
-  - /Audio/ADT/Voice/IPC/i_male_cough_1.ogg
-  - /Audio/ADT/Voice/IPC/i_male_cough_2.ogg
+    - /Audio/ADT/Voice/IPC/i_male_cough_1.ogg
+    - /Audio/ADT/Voice/IPC/i_male_cough_2.ogg

 - type: soundCollection
   id: IPCMaleYawn
   files:
-  - /Audio/ADT/Voice/IPC/i_male_yawn.ogg
+    - /Audio/ADT/Voice/IPC/i_male_yawn.ogg
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Resources/Prototypes/ADT/SoundCollections/emotes.yml` around lines 81 - 90,
Коллекции soundCollection с id IPCMaleCoughs и IPCMaleYawn имеют
несоответствующий отступ для ключа и элементов files (используются 2 пробела);
откорректируй YAML, выровняв ключ files и все его пунктовые элементы до 4
пробелов (сохрани тире для элементов списка) чтобы форматирование в этих записях
стало последовательным и валидным.

121-130: Аналогичная проблема с отступами для IPCFemaleCoughs и IPCFemaleYawn.

♻️ Предлагаемое исправление
 - type: soundCollection
   id: IPCFemaleCoughs
   files:
-  - /Audio/ADT/Voice/IPC/i_female_cough_1.ogg
-  - /Audio/ADT/Voice/IPC/i_female_cough_2.ogg
+    - /Audio/ADT/Voice/IPC/i_female_cough_1.ogg
+    - /Audio/ADT/Voice/IPC/i_female_cough_2.ogg

 - type: soundCollection
   id: IPCFemaleYawn
   files:
-  - /Audio/ADT/Voice/IPC/i_female_yawn.ogg
+    - /Audio/ADT/Voice/IPC/i_female_yawn.ogg
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Resources/Prototypes/ADT/SoundCollections/emotes.yml` around lines 121 - 130,
The YAML entries for the sound collections IPCFemaleCoughs and IPCFemaleYawn
have incorrect indentation; update both items so the list item marker and its
mapping keys are properly indented (e.g., the '-' for each sound collection and
its child keys 'type', 'id', and 'files' align like other soundCollection
entries) and ensure the file paths under 'files' are indented one level deeper
than 'files'; modify the entries for IPCFemaleCoughs and IPCFemaleYawn to match
the correct indentation pattern used by other soundCollection blocks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`:
- Around line 499-525: The handler OnPointLightColorToggle must validate that
point-light customization is permitted before changing state: add an early
return at the start of OnPointLightColorToggle if the
MidroundCustomizationComponent's PointLightColor flag is false (i.e., if
component.PointLightColor == false) so the method does not flip
PointLightColorEnabled or apply colors for entities that don't support point
light customization; keep the rest of the logic unchanged and only proceed when
component.PointLightColor is true.

In `@Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs`:
- Around line 85-87: The timeout check in CrewMonitoringServerSystem.cs is using
dif.Seconds (which returns only the seconds component) causing incorrect timeout
logic; update the comparison to use the full duration via dif.TotalSeconds
(i.e., compute dif = _gameTiming.CurTime - sensor.Timestamp and compare
dif.TotalSeconds to component.SensorTimeout) so sensors are removed correctly
(affecting the block that currently calls toRemove.Add(address) when the timeout
is exceeded).

In `@Content.Shared/Medical/SuitSensors/SharedSuitSensorSystem.cs`:
- Around line 84-92: The code sets ent.Comp.User and marks Dirty(ent) when
ent.Comp.OnMob is true but skips assigning ent.Comp.StationId via
_stationSystem.GetOwningStation, which can leave StationId null; update the
OnMob branch in SharedSuitSensorSystem (the block that currently does
ent.Comp.User = ent.Owner; Dirty(ent);) to also initialize ent.Comp.StationId
using _stationSystem.GetOwningStation(ent.Owner) if StationId is null, and apply
the same fix to the analogous startup initialization path later (the block
around where RecursiveSensor()/OnPlayerSpawn are mentioned) so OnMob sensors
receive the fallback StationId like non-OnMob sensors.
- Around line 230-237: The added if (!ent.Comp.OnMob) wrapper causes the
owner/interaction check to be skipped for mobile targets, letting bystanders
start do-afters; remove the surrounding OnMob conditional so the existing
protection runs unconditionally: keep the inner condition that checks
ent.Comp.User, compares args.User != ent.Comp.User and calls
_actionBlocker.CanInteract(ent.Comp.User.Value, null), but ensure it is executed
regardless of ent.Comp.OnMob in SharedSuitSensorSystem so only the owner (or
when the owner cannot interact) can be bypassed.

In `@Resources/Audio/ADT/Voice/IPC/attributions.yml`:
- Around line 62-79: The YAML has malformed file entries like
[i_male_cry_1.ogg"] causing schema validation errors; fix each files: section so
the values are a proper YAML sequence of strings (e.g. files: followed by -
"i_male_cry_1.ogg" or - i_male_cry_1.ogg) ensuring quotes are balanced and
square brackets are removed from entries referencing i_male_cry_1.ogg,
i_male_cry_2.ogg, i_male_cry_3.ogg and i_male_cry_4.ogg so each filename is a
plain or quoted string in the list.

In `@Resources/Locale/ru-RU/ADT/traits/neutral.ftl`:
- Around line 41-42: В тексте ресурса для ключа trait-disproportionate-desc
исправьте орфографические ошибки: заменить "непропорциоально" на
"непропорционально" и "а так же" на "а также" (сделать слитно), оставив
остальную формулировку без изменений; проверьте также ключ
trait-disproportionate-name на соответствие термину "Непропорциональный".

In `@Resources/Prototypes/ADT/Traits/quirks.yml`:
- Around line 190-244: Квирки ADTFemaleIPC и ADTMaleIPC заменяют компонент Tag
(rewriteComponents: true) но в их components -> Tag списках отсутствует тег
SiliconEmotes, из‑за чего блокировки эмотов для силиконов ломаются; откройте
определения trait с id ADTFemaleIPC и ADTMaleIPC и добавьте "SiliconEmotes" в
массив tags внутри компонента Tag рядом с ADTSiliconEmotes для обоих квирков.

---

Outside diff comments:
In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`:
- Around line 190-206: Remove/add slot handlers (e.g., OnRemoveSlotDoAfter and
the corresponding AddSlot handler in MidroundCustomizationSystem) update
markings but do not recalc the facial point light, leaving inherited point light
color stale; after calling _humanoid.RemoveMarking/_humanoid.AddMarking and
UpdateInterface(uid, component) call UpdatePointLightColorIfEnabled(uid,
component) (or the existing point-light update helper) to recompute the point
light color when FacialHair/markings change so the light stays in sync; apply
the same fix to the other similar handlers mentioned (lines around 227-264 and
528-540).

---

Nitpick comments:
In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationComponent.cs`:
- Around line 1-5: Reorder the using directives in
MidroundCustomizationComponent.cs to follow project alphabetical guidelines:
place Content.Shared.Mobs after Content.Shared.Humanoid.Markings and ensure all
other usings (e.g., Content.Shared.DoAfter, Content.Shared.Humanoid.Markings,
Robust.Shared.Audio, Robust.Shared.Prototypes) are sorted alphabetically; update
the top-of-file using block so the usings are in strict alphabetical order.
- Around line 12-29: Add XML documentation for the ChangeSlotOnStateEntry data
class: add a /// <summary> on the ChangeSlotOnStateEntry type describing its
role in changing a marking slot when a mob enters a given MobState, and add
brief /// <summary> comments for each public property (State, Category, Slot,
Marking, Colors) explaining what they represent (e.g., State = target MobState,
Category = marking category, Slot = slot index, Marking = marking id/string,
Colors = optional color overrides). Keep descriptions concise and use standard
XML doc tags so IDEs and generated docs will surface the intent.
- Around line 103-112: Add XML documentation comments for the new fields to
explain their purpose and usage: add <summary> (and <remarks> where helpful) for
PointLightColor, PointLightColorEnabled, OriginalPointLightColor,
RemovedMarkingsBuffer, and OriginalMarkings; describe that PointLightColor
toggles using a point light color override, PointLightColorEnabled is the
networked toggle, OriginalPointLightColor stores the pre-customization color,
RemovedMarkingsBuffer holds markings temporarily removed keyed by
MarkingCategories, and OriginalMarkings stores original marking data keyed by
(MarkingCategories, slot) so other devs understand intent and
serialization/networking behavior.

In `@Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs`:
- Line 81: Replace the subjective Russian inline comment in
CrewMonitoringServerSystem (the comment currently containing “Надеюсь…”) with a
neutral, technical one: succinctly state why the change is needed (e.g., that
without this change a remnant entity with OnMob: true remains in the monitor)
and remove any speculative or personal wording; locate the comment near the
CrewMonitoringServerSystem class/method and update it to a single clear sentence
describing the behavior being fixed.

In `@Content.Shared/ADT/Silicons/MobIpcComponent.cs`:
- Around line 6-13: Добавьте XML-документацию для компонента и его полей:
добавьте /// <summary> описывающий назначение класса MobIpcComponent и его роли,
затем /// <summary> для поля DisablePointLightOnDeath (объяснить, что делает
флаг — отключает ли точечный свет при смерти) и для поля LightDisabledByDeath
(объяснить, что хранит состояние — было ли свет отключён при смерти). Убедитесь,
что комментарии коротко описывают поведение и возможные значения флагов,
используя имена MobIpcComponent, DisablePointLightOnDeath и LightDisabledByDeath
для локализации изменений.

In `@Content.Shared/ADT/Silicons/MobIpcSystem.cs`:
- Line 6: Добавьте XML-документацию для нового публичного класса MobIpcSystem:
вставьте над объявлением класса /// <summary>…</summary> с коротким описанием
его ответственности — отключение фонарика IPC при смерти и восстановление после
ремонта (укажите, что это EntitySystem, управляющая поведением фонарика при
состояниях сущности). Упомяните в тексте класса имя MobIpcSystem и ключевые
сценарии (on death, on repair) чтобы следующий разработчик быстро понял
назначение.

In `@Content.Shared/Medical/SuitSensors/SuitSensorComponent.cs`:
- Around line 99-100: Add an XML summary comment for the OnMob field explaining
its purpose: above the [DataField, AutoNetworkedField] public bool OnMob =
false; declaration add a /// <summary> that states this boolean toggles the
sensor's new operating mode (i.e., when true the component uses the
alternate/“OnMob” behavior implemented in SharedSuitSensorSystem), and note
default value/behavior if helpful; ensure the comment is concise and placed
immediately above the field declaration.

In `@Resources/Prototypes/ADT/SoundCollections/emotes.yml`:
- Around line 81-90: Коллекции soundCollection с id IPCMaleCoughs и IPCMaleYawn
имеют несоответствующий отступ для ключа и элементов files (используются 2
пробела); откорректируй YAML, выровняв ключ files и все его пунктовые элементы
до 4 пробелов (сохрани тире для элементов списка) чтобы форматирование в этих
записях стало последовательным и валидным.
- Around line 121-130: The YAML entries for the sound collections
IPCFemaleCoughs and IPCFemaleYawn have incorrect indentation; update both items
so the list item marker and its mapping keys are properly indented (e.g., the
'-' for each sound collection and its child keys 'type', 'id', and 'files' align
like other soundCollection entries) and ensure the file paths under 'files' are
indented one level deeper than 'files'; modify the entries for IPCFemaleCoughs
and IPCFemaleYawn to match the correct indentation pattern used by other
soundCollection blocks.

In `@Resources/Prototypes/ADT/Voice/speech_emote_sounds.yml`:
- Around line 62-66: Collections IPCSpits, IPCMaleCoughs, IPCMaleYawn,
IPCFemaleCoughs and IPCFemaleYawn contain `files` entries indented with 2 spaces
instead of the project standard 4; update each `files` list under those
collection keys (e.g., IPCSpits, IPCMaleCoughs, IPCMaleYawn, IPCFemaleCoughs,
IPCFemaleYawn) to use 4-space indentation so the `files` items align uniformly
with other collections in speech_emote_sounds.yml.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e8a13f08-a00b-49b6-a8c7-fe2c8801afa4

📥 Commits

Reviewing files that changed from the base of the PR and between c1f609c and 7b5a61f.

⛔ Files ignored due to path filters (38)
  • Resources/Audio/ADT/Voice/IPC/i_female_cough_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_cough_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_cry_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_cry_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_cry_3.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_cry_4.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_giggle_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_giggle_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_laugh_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_laugh_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_sigh_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_sigh_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_sneeze_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_sneeze_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_yawn.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_cough_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_cough_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_cry_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_cry_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_cry_3.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_cry_4.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_laugh_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_laugh_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_sigh_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_sigh_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_sneeze_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_sneeze_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_yawn.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_neutral_sneeze.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_spit_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_spit_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_whistle_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_whistle_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_whistle_3.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_whistle_4.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Textures/ADT/Mobs/Customization/Ipc/ipc_screens.rsi/ipc_screen_broken.png is excluded by !**/*.png, !**/*.png
  • Resources/Textures/ADT/Mobs/Customization/Ipc/ipc_screens.rsi/ipc_screen_redtext.png is excluded by !**/*.png, !**/*.png
  • Resources/Textures/ADT/Mobs/Customization/Ipc/ipc_screens.rsi/ipc_screen_text.png is excluded by !**/*.png, !**/*.png
📒 Files selected for processing (30)
  • Content.Client/ADT/Lobby/UI/QuirksWindow.xaml.cs
  • Content.Client/ADT/MidroundCustomization/MidroundCustomizationBoundUserInterface.cs
  • Content.Client/ADT/MidroundCustomization/MidroundCustomizationWindow.xaml
  • Content.Client/ADT/MidroundCustomization/MidroundCustomizationWindow.xaml.cs
  • Content.Server/ADT/MidroundCustomization/MidroundCustomizationComponent.cs
  • Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs
  • Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs
  • Content.Server/Mobs/DeathgaspComponent.cs
  • Content.Server/Mobs/DeathgaspSystem.cs
  • Content.Server/Traits/TraitSystem.cs
  • Content.Shared/ADT/MidroundCustomization/BUI.cs
  • Content.Shared/ADT/Silicons/MobIpcComponent.cs
  • Content.Shared/ADT/Silicons/MobIpcSystem.cs
  • Content.Shared/Medical/SuitSensors/SharedSuitSensorSystem.cs
  • Content.Shared/Medical/SuitSensors/SuitSensorComponent.cs
  • Content.Shared/Traits/TraitPrototype.cs
  • Resources/Audio/ADT/Voice/IPC/attributions.yml
  • Resources/Locale/ru-RU/ADT/Chat/emotes.ftl
  • Resources/Locale/ru-RU/ADT/prototypes/Entities/Mobs/Customization/Markings/ipc.ftl
  • Resources/Locale/ru-RU/ADT/traits/neutral.ftl
  • Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/ipc_screens.yml
  • Resources/Prototypes/ADT/Entities/Mobs/Species/ipc.yml
  • Resources/Prototypes/ADT/InventoryTemplates/ipc_inventory_template.yml
  • Resources/Prototypes/ADT/SoundCollections/emotes.yml
  • Resources/Prototypes/ADT/Traits/quirks.yml
  • Resources/Prototypes/ADT/Voice/speech_emote_sounds.yml
  • Resources/Prototypes/ADT/Voice/speech_emotes.yml
  • Resources/Prototypes/Voice/disease_emotes.yml
  • Resources/Prototypes/Voice/speech_emotes.yml
  • Resources/Textures/ADT/Mobs/Customization/Ipc/ipc_screens.rsi/meta.json

@minokaa
Copy link
Contributor

minokaa commented Mar 19, 2026

@coderabbitai проверь код на вайбкодинг

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 19, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

Сейчас проверю код на признаки вайбкодинга.


🏁 Script executed:

#!/bin/bash
# Check MidroundCustomizationSystem.cs for code quality
fd "MidroundCustomizationSystem.cs" --exec cat {}

echo "=== MobIpcSystem.cs ==="
fd "MobIpcSystem.cs" --exec cat {}

echo "=== DeathgaspSystem.cs ==="
fd "DeathgaspSystem.cs" --exec cat {}

echo "=== TraitSystem.cs ==="
fd "TraitSystem.cs" Content.Server --exec cat {}

echo "=== QuirksWindow.xaml.cs ==="
fd "QuirksWindow.xaml.cs" --exec cat {}

Length of output: 32356


@minokaa Проверил. Вот конкретные признаки вайбкодинга:


🔴 1. Несоответствие названий (MidroundCustomizationSystem.cs)

Система называется MidroundCustomization, но все внутренние обработчики и события названы SlimeHair*:

// В системе MidroundCustomization:
private void OnSlimeHairSelect(...)
private void OnTrySlimeHairChangeColor(...)
private void OnTrySlimeHairAddSlot(...)
// ...и т.д.

Это классика копипаста из старой системы SlimeHair без переименования.


🔴 2. Мёртвый код — избыточная проверка (OnPointLightColorToggle)

if (component.PointLightColorEnabled == args.Enabled)
    return; // если Enabled == true, то PointLightColorEnabled == false ГАРАНТИРОВАНО

if (args.Enabled)
{
    if (!component.PointLightColorEnabled) // ← эта проверка ВСЕГДА true здесь, мёртвый код
    {
        if (_pointLight.TryGetLight(uid, out var light))
            component.OriginalPointLightColor = light.Color;
    }
    ...
}

🟡 3. Огромное дублирование шаблона DoAfter

Четыре пары обработчиков (Pitch, MinVar, MaxVar, Proto) — почти идентичные копии:

// Паттерн повторяется 4 раза дословно:
private void OnTryChangeBark__X__(...)
{
    _doAfterSystem.Cancel(component.DoAfter);
    component.DoAfter = null;
    var doAfter = new SlimeHairChangeBark__X__DoAfterEvent() { __X__ = message.__X__ };
    _doAfterSystem.TryStartDoAfter(...);
    component.DoAfter = doAfterId;
}

Всё это можно было свернуть в один generic-хелпер.


🟡 4. Убрана сортировка квирков без замены (QuirksWindow.xaml.cs)

По AI-summary, убраны два вызова protoList.Sort(...). Теперь порядок квирков в UI — в каком порядке вернёт ToList() после фильтрации, то есть не определён.


🟡 5. Незакрытый TODO и неформальные комментарии

// TODO: Исправить проблему с генокрадом  ← известный баг, не зафиксирован

// using this makes the UI feel like total ass  ← неформально
// que

Итог: Код рабочий и логически связный, но несёт явные следы copy-paste из SlimeHair-системы без рефакторинга, один случай мёртвого кода, и существенное дублирование в bark-обработчиках. Классика "написал ИИ, проверил глазами, пушнул".


🧠 Learnings used
Learnt from: KashRas2
Repo: AdventureTimeSS14/space_station_ADT PR: 0
File: :0-0
Timestamp: 2025-09-12T18:36:18.833Z
Learning: Пользователь KashRas2 в проекте AdventureTimeSS14/space_station_ADT запросил доработку BookPrinter с добавлением кулдауна загрузки в 1 час (только для загрузки, не для выгрузки) и полным рефакторингом кода для улучшения читаемости с русскими комментариями и логической структурой.

Learnt from: Schrodinger71
Repo: AdventureTimeSS14/space_station_ADT PR: 1824
File: Content.Client/ADT/Minesweeper/MinesweeperWindow.xaml.cs:40-48
Timestamp: 2025-08-25T09:01:23.849Z
Learning: В проекте AdventureTimeSS14 пользователь Schrodinger71 запрашивает создание FTL файлов локализации для новых UI компонентов, следуя правилам проекта о выносе жёстко вписанных строк из .cs кода в ftl файлы с использованием Loc.GetString().

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

🧹 Nitpick comments (1)
Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs (1)

16-19: Отсортируйте using по алфавиту в общем блоке.

Новые импорты здесь выбились из порядка для /ADT/-файлов: Content.Shared.Mobs* сейчас стоит после System.Linq, а Robust.Shared.GameObjects — после Robust.Shared.Prototypes.

♻️ Минимальная правка
 using Content.Shared.Humanoid.Markings;
 using Content.Shared.Interaction;
+using Content.Shared.Mobs;
+using Content.Shared.Mobs.Components;
 using Content.Shared.Preferences;
 using Content.Shared.UserInterface;
 using Robust.Server.GameObjects;
 using Robust.Shared.Audio.Systems;
+using Robust.Shared.GameObjects;
 using Robust.Shared.Prototypes;
 using System.Linq;
-using Content.Shared.Mobs;
-using Content.Shared.Mobs.Components;
-using Robust.Shared.GameObjects;

As per coding guidelines "И ещё смотри за тем чтобы using был в алфавитном порядке в наших /ADT/ системах и компонентах".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`
around lines 16 - 19, Сортировка using в файле нарушена: в
MidroundCustomizationSystem.cs переместите все директивы using в общий блок и
отсортируйте их по алфавиту; конкретно упорядочите записи включая System.Linq,
Content.Shared.Mobs, Content.Shared.Mobs.Components, Robust.Shared.GameObjects
(и Robust.Shared.Prototypes, если присутствует) так, чтобы они шли в
лексикографическом порядке внутри одного блока using.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`:
- Around line 195-205: Validate args.Slot is within bounds (>= 0 and <
markings.Count) before any indexing or passing it to RemoveMarking: when
TryComp<HumanoidAppearanceComponent> and humanoid.MarkingSet.TryGetCategory(...)
succeed, check args.Slot >= 0 && args.Slot < markings.Count before reading
markings[args.Slot] and writing component.RemovedMarkingsBuffer[args.Category];
if the slot is invalid skip the buffer save and do not call
_humanoid.RemoveMarking(uid, args.Category, args.Slot). Keep the existing
UpdatePointLightColorIfEnabled(uid, component) call only after a successful
removal.
- Around line 588-610: Apply bounds checking for entries in ChangeSlotOnState
inside ApplyStateChanges: before calling _humanoid.SetMarkingId or
_humanoid.SetMarkingColor, ensure the entry.Slot is >= 0 and that
humanoid.MarkingSet.TryGetCategory(entry.Category, out var list) returns true
and entry.Slot < list.Count; if the checks fail, skip that entry. Mirror the
same validation logic used in RecordOriginals to avoid negative or out-of-range
slot indices causing exceptions when using SetMarkingId/SetMarkingColor.
- Around line 560-576: The transition logic for ChangeSlotOnState fails to clear
previous overrides when switching between two managed states; update the handler
so that when both oldManaged and newManaged are true (i.e., args.OldMobState and
args.NewMobState are both in component.ChangeSlotOnState) you first reset the
managed slots by calling RevertToOriginals(uid, component, humanoid) (to clear
OriginalMarkings), then call ApplyStateChanges(uid, component, args.NewMobState,
humanoid) to apply the new state's overrides; keep existing paths for
only-entering (RecordOriginals) and only-leaving behavior unchanged.

---

Nitpick comments:
In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`:
- Around line 16-19: Сортировка using в файле нарушена: в
MidroundCustomizationSystem.cs переместите все директивы using в общий блок и
отсортируйте их по алфавиту; конкретно упорядочите записи включая System.Linq,
Content.Shared.Mobs, Content.Shared.Mobs.Components, Robust.Shared.GameObjects
(и Robust.Shared.Prototypes, если присутствует) так, чтобы они шли в
лексикографическом порядке внутри одного блока using.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 88d0e01b-c97a-46bf-b790-416d8c6f0c16

📥 Commits

Reviewing files that changed from the base of the PR and between 7b5a61f and 5c097ef.

📒 Files selected for processing (7)
  • Content.Client/ADT/MidroundCustomization/MidroundCustomizationWindow.xaml
  • Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs
  • Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs
  • Content.Shared/Medical/SuitSensors/SharedSuitSensorSystem.cs
  • Resources/Audio/ADT/Voice/IPC/attributions.yml
  • Resources/Locale/ru-RU/ADT/actions/ipsscreen.ftl
  • Resources/Locale/ru-RU/ADT/traits/neutral.ftl
✅ Files skipped from review due to trivial changes (3)
  • Resources/Audio/ADT/Voice/IPC/attributions.yml
  • Resources/Locale/ru-RU/ADT/traits/neutral.ftl
  • Resources/Locale/ru-RU/ADT/actions/ipsscreen.ftl
🚧 Files skipped from review as they are similar to previous changes (3)
  • Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs
  • Content.Client/ADT/MidroundCustomization/MidroundCustomizationWindow.xaml
  • Content.Shared/Medical/SuitSensors/SharedSuitSensorSystem.cs

@kerfus-owo
Copy link
Contributor Author

@coderabbitai проверь PR пж

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 19, 2026

PR description images описание:

  • Image 1: Тёмная сцена с КПБ-спрайтом вверху и точечным источником света (фонариком) внизу — демонстрация работы встроенного фонарика.
  • Image 2: Скриншот с КПБ PRTTP-GS-32 и открытым контекстным меню; выделен пункт "Переключить фонарик", открыто подменю "Датчики" (Выкл./Бинарные/Здоровье/Координаты). Стрелки указывают на хотбар и подменю.
  • Image 3: Круговое меню эмоций с КПБ в центре и различными иконками эмоций — показывает новые локализованные эмоции.
  • Image 4: Текстовое сообщение смерти: "PRTTP-GS-32 замирает и недвижимо оседает, её монитор трескается и выключается..." — предсмертный хрип КПБ.
  • Image 5: Обновлённый спрайт КПБ — робот с прямоугольной головой с белыми горизонтальными полосами (экран), чёрным корпусом и ногами.

@kerfus-owo, запускаю полный ревью PR. Одну секунду 🕶️


🧠 Learnings used
Learnt from: Schrodinger71
Repo: AdventureTimeSS14/space_station_ADT PR: 1824
File: Content.Client/ADT/Minesweeper/MinesweeperWindow.xaml.cs:40-48
Timestamp: 2025-08-25T09:01:23.849Z
Learning: В проекте AdventureTimeSS14 пользователь Schrodinger71 запрашивает создание FTL файлов локализации для новых UI компонентов, следуя правилам проекта о выносе жёстко вписанных строк из .cs кода в ftl файлы с использованием Loc.GetString().

Learnt from: KashRas2
Repo: AdventureTimeSS14/space_station_ADT PR: 0
File: :0-0
Timestamp: 2025-08-25T21:26:49.133Z
Learning: Пользователь KashRas2 запросил исправление проблемы с обнаружением невидимых персонажей роботом Бипски в Space Station 14. Была добавлена система проверки невидимости через SharedStealthSystem.GetVisibility() и CheckStealthWhitelist() во все HTN операторы, которые используют EntityLookupSystem.GetEntitiesInRange() для поиска целей. Это включает PickNearbyWantedOperator, EntityWhitelistOperator и PickNearbyContrabandOperator.

Learnt from: Schrodinger71
Repo: AdventureTimeSS14/space_station_ADT PR: 0
File: :0-0
Timestamp: 2026-02-24T07:56:31.049Z
Learning: В проекте AdventureTimeSS14/space_station_ADT CodeRabbit не должен approve-ать pull request пока ВСЕ его review комментарии не решены и весь функционал полностью завершён, даже если пользователь явно просит об approve. Пользователь Schrodinger71 указал, что approval должен означать готовность к мёрджу без оговорок.

Learnt from: KashRas2
Repo: AdventureTimeSS14/space_station_ADT PR: 0
File: :0-0
Timestamp: 2025-09-12T18:36:18.833Z
Learning: Пользователь KashRas2 в проекте AdventureTimeSS14/space_station_ADT запросил доработку BookPrinter с добавлением кулдауна загрузки в 1 час (только для загрузки, не для выгрузки) и полным рефакторингом кода для улучшения читаемости с русскими комментариями и логической структурой.

Learnt from: Schrodinger71
Repo: AdventureTimeSS14/space_station_ADT PR: 2530
File: Content.Shared/Preferences/HumanoidCharacterProfile.cs:698-702
Timestamp: 2026-02-23T23:11:37.097Z
Learning: В проекте AdventureTimeSS14/space_station_ADT проверка домена для HeadshotUrl в HumanoidCharacterProfile.EnsureValid() должна быть регистрозависимой (case-sensitive). Пользователь Schrodinger71 явно указал, что это намеренное решение для контроля валидных URL.

Learnt from: kerfus-owo
Repo: AdventureTimeSS14/space_station_ADT PR: 2640
File: Content.Shared/Medical/SuitSensors/SharedSuitSensorSystem.cs:230-237
Timestamp: 2026-03-19T06:12:39.516Z
Learning: В проекте AdventureTimeSS14/space_station_ADT в файле Content.Shared/Medical/SuitSensors/SharedSuitSensorSystem.cs метод OnVerb намеренно пропускает проверку дееспособности цели (_actionBlocker.CanInteract) когда SuitSensorComponent.OnMob == true. Это сделано специально для КПБ (IPC), у которых датчик встроен в тело, а не является носимым предметом — любой может менять режим датчика без необходимости выводить КПБ из строя.

Learnt from: KashRas2
Repo: AdventureTimeSS14/space_station_ADT PR: 0
File: :0-0
Timestamp: 2025-08-25T21:16:52.331Z
Learning: Пользователь KashRas2 запросил реализацию системы автоматического задержания людей с контрабандой для NPC Бипски в Space Station 14. Была создана система на базе HTN (Hierarchical Task Network) с приоритетным поведением: сначала арест розыскных, затем контрабандистов, затем патрулирование. Использована существующая система баллов контрабанды через CriminalRecord.Points.

Learnt from: BitBoxxxer
Repo: AdventureTimeSS14/space_station_ADT PR: 0
File: :0-0
Timestamp: 2024-11-14T19:41:52.431Z
Learning: В этом репозитории автоматические обзоры отключены, и пользователь предпочитает также отключить статусные сообщения от CodeRabbit, установив `reviews.review_status` в `false` в файле `.coderabbit.yaml`.

Learnt from: Schrodinger71
Repo: AdventureTimeSS14/space_station_ADT PR: 1824
File: Content.Client/ADT/Minesweeper/MinesweeperWindow.xaml.cs:58-66
Timestamp: 2025-08-26T08:13:09.713Z
Learning: Пользователь Schrodinger71 в проекте AdventureTimeSS14/space_station_ADT предпочитает превращать неиспользуемые интерактивные элементы UI в информационные индикаторы вместо добавления дублирующей функциональности.

Learnt from: KashRas2
Repo: AdventureTimeSS14/space_station_ADT PR: 0
File: :0-0
Timestamp: 2025-08-26T12:39:43.556Z
Learning: Пользователь KashRas2 запросил добавление проверки должности в систему обнаружения контрабанды для NPC Бипски в Space Station 14. Была создана модифицированная версия PickNearbyContrabandOperator с функцией ShouldArrestForContraband(), которая проверяет JobPrototype через MindSystem и SharedRoleSystem, исключая из ареста службу безопасности, командование, медперсонал и другие важные должности. Используется список ExcludedJobs и дополнительные проверки доступов через JobPrototype.Access.

Learnt from: KashRas2
Repo: AdventureTimeSS14/space_station_ADT PR: 0
File: :0-0
Timestamp: 2025-09-12T18:27:15.856Z
Learning: Пользователь KashRas2 в проекте AdventureTimeSS14/space_station_ADT запросил добавление кулдауна длительностью в час для загрузки книг в BookPrinter, при этом выгрузка должна оставаться без ограничений. Также требовался рефакторинг кода для улучшения читаемости.

Learnt from: kerfus-owo
Repo: AdventureTimeSS14/space_station_ADT PR: 1951
File: Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/ipc_screens.yml:9-13
Timestamp: 2025-09-17T15:29:24.652Z
Learning: В SS14 (Space Station 14) поле `shader: unshaded` в конфигурации маркингов IPC может размещаться на уровне маркинга (с отступом 2 пробела), а не обязательно внутри каждого элемента sprites. Такое размещение корректно работает для применения эффекта свечения экранов.

Learnt from: Darkiich
Repo: AdventureTimeSS14/space_station_ADT PR: 0
File: :0-0
Timestamp: 2026-01-21T21:44:22.539Z
Learning: Для репозитория AdventureTimeSS14/space_station_ADT инструкция по тону (tone instructions): "ты теперь мистер крутой, который надевает солнечные очки при ревью ПРа".
✅ Actions performed

Full review triggered.

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: 2

Caution

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

⚠️ Outside diff range comments (1)
Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs (1)

155-163: ⚠️ Potential issue | 🟠 Major

Провалидируйте args.Slot до SetMarkingColor().

Отрицательный или выходящий за границы slot из BUI здесь всё ещё проходит на сервер без проверки и сразу уходит в _humanoid.SetMarkingColor(). Это оставляет незащищённую ветку для невалидного клиентского ввода.

💡 Минимальная правка
     private void OnChangeColorDoAfter(EntityUid uid, MidroundCustomizationComponent component, SlimeHairChangeColorDoAfterEvent args)
     {
         if (args.Handled || args.Target == null || args.Cancelled)
             return;
+
+        if (!TryComp<HumanoidAppearanceComponent>(uid, out var humanoid) ||
+            !humanoid.MarkingSet.TryGetCategory(args.Category, out var markings) ||
+            args.Slot < 0 ||
+            args.Slot >= markings.Count)
+            return;
 
         _humanoid.SetMarkingColor(uid, args.Category, args.Slot, args.Colors, force: false);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`
around lines 155 - 163, In OnChangeColorDoAfter, validate args.Slot before
calling _humanoid.SetMarkingColor: check that args.Slot is >= 0 and within the
allowed slot range for the relevant category (e.g. compare against a slot
count/array on MidroundCustomizationComponent or a known max slots for the
category); if the slot is out of range, bail out (return) or mark the event
handled instead of calling _humanoid.SetMarkingColor; keep the existing
UpdatePointLightColorIfEnabled call only for valid slots.
♻️ Duplicate comments (1)
Resources/Locale/ru-RU/ADT/traits/neutral.ftl (1)

41-42: ⚠️ Potential issue | 🟡 Minor

Пунктуационная ошибка.

В строке 42 пропущена запятая перед "а также": "карманы а также датчики" → "карманы, а также датчики".

✏️ Исправление
 trait-disproportionate-name = Непропорциональный
-trait-disproportionate-desc = Ваше тело непропорционально, не позволяя носить комбинезоны. Взамен вы снабжены встроенными разъёмами под КПК, карманы а также датчики.
+trait-disproportionate-desc = Ваше тело непропорционально, не позволяя носить комбинезоны. Взамен вы снабжены встроенными разъёмами под КПК, карманы, а также датчики.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Resources/Locale/ru-RU/ADT/traits/neutral.ftl` around lines 41 - 42, В
описании trait-disproportionate-desc исправьте пунктуацию: вставьте запятую
перед "а также" — изменить фразу "карманы а также датчики" на "карманы, а также
датчики" в строке значения trait-disproportionate-desc.
🧹 Nitpick comments (6)
Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs (1)

80-81: Сделайте комментарий здесь техническим, а не разговорным.

Фраза Надеюсь это ничего не сломает не объясняет, какой инвариант защищает этот блок. Лучше явно зафиксировать причину второго прохода удаления и, если это важно, отдельно упомянуть кейс встроенных датчиков OnMob: true.

💬 Вариант правки
-        // Без этих изменений, в мониторинге остаётся ремнант сущности с OnMob: true. Надеюсь это ничего не сломает.
+        // Собираем истёкшие записи отдельно и удаляем их после обхода,
+        // чтобы не модифицировать SensorStatus во время foreach.
+        // Это также очищает устаревшие записи встроенных датчиков (`OnMob: true`).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs` around
lines 80 - 81, Replace the conversational Russian comment around the
"ADT-Tweak-Start" block in CrewMonitoringServerSystem (the comment above the
second removal pass) with a concise technical explanation that documents the
invariant being protected and why a second removal pass is necessary: state that
the extra pass ensures entities flagged OnMob (embedded sensors) do not remain
as remnants after the first cleanup, describe the specific invariant (no
monitoring entities should persist with OnMob == true after cleanup), and
mention any edge-case behavior for embedded sensors so future maintainers
understand why the deletion is repeated.
Content.Shared/ADT/Silicons/MobIpcComponent.cs (1)

6-14: Рекомендуется добавить XML-документацию к компоненту.

Компонент MobIpcComponent и его поля не имеют /// <summary> документации. Для лучшей читаемости и поддержки кода рекомендуется добавить описание назначения компонента.

Также LightDisabledByDeath является runtime-флагом состояния. Если это поле не предназначено для сериализации из YAML-прототипов, атрибут [DataField] можно убрать.

📝 Предложение по документации
 namespace Content.Shared.ADT.Silicon;
 
+/// <summary>
+/// Компонент для КПБ (IPC), управляющий поведением point-light при смерти моба.
+/// </summary>
 [RegisterComponent]
 public sealed partial class MobIpcComponent : Component
 {
+    /// <summary>
+    /// Если true, point-light будет отключаться при смерти моба.
+    /// </summary>
     [DataField]
     public bool DisablePointLightOnDeath = false;
 
+    /// <summary>
+    /// Runtime-флаг: true, если свет был отключён системой при смерти.
+    /// </summary>
-    [DataField]
     public bool LightDisabledByDeath;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Shared/ADT/Silicons/MobIpcComponent.cs` around lines 6 - 14, Добавьте
XML-документацию для компонента MobIpcComponent и его публичных полей: поместите
/// <summary>...</summary> над объявлением класса MobIpcComponent и над полями
DisablePointLightOnDeath и LightDisabledByDeath, кратко описав назначение
компонента и каждого поля; если LightDisabledByDeath используется только как
runtime-флаг и не должен сериализоваться из прототипов, удалите атрибут
[DataField] с поля LightDisabledByDeath, оставив его как обычное публичное поле.
Content.Shared/Medical/SuitSensors/SuitSensorComponent.cs (1)

97-101: Рекомендуется добавить XML-документацию для поля OnMob.

Поле OnMob не имеет /// <summary> документации, в отличие от остальных полей компонента.

📝 Предложение по документации
 //ADT-Tweak-Start
+    /// <summary>
+    /// Если true, датчик встроен в моба (КПБ/IPC) и не требует ношения одежды для активации.
+    /// </summary>
     [DataField, AutoNetworkedField]
     public bool OnMob = false;
 //ADT-Tweak-End
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Shared/Medical/SuitSensors/SuitSensorComponent.cs` around lines 97 -
101, Add an XML summary for the public bool field OnMob in SuitSensorComponent
to match the style of the other documented fields; update the declaration marked
with [DataField, AutoNetworkedField] and the symbol name OnMob by inserting a
/// <summary> that briefly explains what OnMob controls (e.g., whether sensors
detect mobs/creatures or operate on mobile entities) and any important behavior
or default meaning so the field is documented consistently with the rest of the
component.
Content.Shared/ADT/Silicons/MobIpcSystem.cs (1)

6-39: Рекомендуется добавить XML-документацию к системе.

Система MobIpcSystem не имеет документации. Рекомендуется добавить /// <summary> для класса и метода OnMobStateChanged.

📝 Предложение по документации
 namespace Content.Shared.ADT.Silicon;
 
+/// <summary>
+/// Система управления поведением КПБ (IPC) при изменении состояния моба.
+/// Отключает point-light при смерти и восстанавливает при оживлении.
+/// </summary>
 public sealed class MobIpcSystem : EntitySystem
 {
     [Dependency] private readonly SharedPointLightSystem _pointLight = default!;
 
     public override void Initialize()
     {
         base.Initialize();
 
         SubscribeLocalEvent<MobIpcComponent, MobStateChangedEvent>(OnMobStateChanged);
     }
 
+    /// <summary>
+    /// Обрабатывает изменение состояния моба: отключает свет при смерти, включает при оживлении.
+    /// </summary>
     private void OnMobStateChanged(Entity<MobIpcComponent> ent, ref MobStateChangedEvent args)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Shared/ADT/Silicons/MobIpcSystem.cs` around lines 6 - 39, Add XML
documentation comments for the MobIpcSystem class and its OnMobStateChanged
method: add a /// <summary> for MobIpcSystem describing that it subscribes to
mob state changes and manages point light behavior on death/resurrection, and
add /// <summary> on OnMobStateChanged explaining it handles
MobStateChangedEvent, disables the point light when NewMobState==MobState.Dead
(respecting DisablePointLightOnDeath), marks LightDisabledByDeath and calls
Dirty, and restores the light when transitioning from Dead if
LightDisabledByDeath was set; also add <param> tags for the ent and args
parameters to describe their roles and mention any side effects (calls to
SharedPointLightSystem methods and Dirty).
Content.Client/ADT/MidroundCustomization/MidroundCustomizationWindow.xaml.cs (1)

1-21: Рекомендуется упорядочить using-директивы.

В соответствии с coding guidelines, using-директивы в файлах /ADT/ должны быть в алфавитном порядке. Сейчас System.Linq и System.Numerics расположены в конце (строки 20-21), хотя должны быть в начале или среди других namespace'ов по алфавиту.

♻️ Предлагаемое исправление
-using Content.Client.ADT.Bark;
+using System.Linq;
+using System.Numerics;
+using Content.Client.ADT.Bark;
 using Content.Client.ADT.SpeechBarks;
...
 using Robust.Shared.Prototypes;
-using System.Linq;
-using System.Numerics;

As per coding guidelines: "смотри за тем чтобы using был в алфавитном порядке в наших /ADT/ системах и компонентах"

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Client/ADT/MidroundCustomization/MidroundCustomizationWindow.xaml.cs`
around lines 1 - 21, The using directives at the top of
MidroundCustomizationWindow.xaml.cs are not alphabetized; reorder all using
statements in that file (the ones above the class MidroundCustomizationWindow)
into strict alphabetical order (by namespace string) so System.* (System.Linq,
System.Numerics) appear in the correct position among the others, preserving any
blank lines grouping (e.g., framework vs project usings) if present and ensuring
no duplicates are introduced.
Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs (1)

504-530: Упростите предопределённые ветки в OnPointLightColorToggle().

После раннего выхода по текущему состоянию обе внутренние проверки уже известны заранее: в ветке args.Enabled флаг ещё выключен, а в else — ещё включён. Сейчас это просто лишний шум в обработчике.

♻️ Упрощение без изменения поведения
         if (args.Enabled)
         {
-            // сохраняем оригинальный цвет при первом включении
-            if (!component.PointLightColorEnabled)
-            {
-                if (_pointLight.TryGetLight(uid, out var light))
-                    component.OriginalPointLightColor = light.Color;
-            }
+            if (_pointLight.TryGetLight(uid, out var light))
+                component.OriginalPointLightColor = light.Color;
 
             component.PointLightColorEnabled = true;
             UpdatePointLightColorIfEnabled(uid, component);
         }
         else
         {
-            if (component.PointLightColorEnabled)
-            {
-                _pointLight.SetColor(uid, component.OriginalPointLightColor);
-            }
+            _pointLight.SetColor(uid, component.OriginalPointLightColor);
             component.PointLightColorEnabled = false;
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`
around lines 504 - 530, The handler OnPointLightColorToggle contains redundant
inner checks for PointLightColorEnabled after already returning when
component.PointLightColorEnabled == args.Enabled; remove those unnecessary
conditionals: in the args.Enabled branch assume the flag was previously
false—capture OriginalPointLightColor via _pointLight.TryGetLight once, set
component.PointLightColorEnabled = true and call
UpdatePointLightColorIfEnabled(uid, component); in the else branch assume the
flag was previously true—call _pointLight.SetColor(uid,
component.OriginalPointLightColor) and then set component.PointLightColorEnabled
= false; keep all referenced symbols
(MidroundCustomizationComponent.PointLightColorEnabled, OriginalPointLightColor,
_pointLight.TryGetLight, _pointLight.SetColor, UpdatePointLightColorIfEnabled,
args.Enabled) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/ipc_screens.yml`:
- Around line 735-742: The ADTIPCScreenBroken marking entry is missing the
shader setting so it won't glow like the other IPC screen markings; update the
marking block with id ADTIPCScreenBroken (bodyPart: FacialHair, markingCategory:
FacialHair, sprites state ipc_screen_broken) to include "shader: unshaded"
alongside the existing sprite entry so it matches the other IPC screen markings
and restores the glow effect.

In `@Resources/Prototypes/ADT/Traits/quirks.yml`:
- Around line 190-244: Make ADTFemaleIPC and ADTMaleIPC mutually exclusive by
adding a mutual exclusion key to each trait so they cannot both be applied;
specifically, add a field like mutuallyExclusiveWith: [ADTMaleIPC] to the
ADTFemaleIPC trait and mutuallyExclusiveWith: [ADTFemaleIPC] to the ADTMaleIPC
trait (use the project's existing exclusion/key name if different but reference
the trait IDs ADTFemaleIPC and ADTMaleIPC so the engine prevents both quirks
from being selected together).

---

Outside diff comments:
In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`:
- Around line 155-163: In OnChangeColorDoAfter, validate args.Slot before
calling _humanoid.SetMarkingColor: check that args.Slot is >= 0 and within the
allowed slot range for the relevant category (e.g. compare against a slot
count/array on MidroundCustomizationComponent or a known max slots for the
category); if the slot is out of range, bail out (return) or mark the event
handled instead of calling _humanoid.SetMarkingColor; keep the existing
UpdatePointLightColorIfEnabled call only for valid slots.

---

Duplicate comments:
In `@Resources/Locale/ru-RU/ADT/traits/neutral.ftl`:
- Around line 41-42: В описании trait-disproportionate-desc исправьте
пунктуацию: вставьте запятую перед "а также" — изменить фразу "карманы а также
датчики" на "карманы, а также датчики" в строке значения
trait-disproportionate-desc.

---

Nitpick comments:
In
`@Content.Client/ADT/MidroundCustomization/MidroundCustomizationWindow.xaml.cs`:
- Around line 1-21: The using directives at the top of
MidroundCustomizationWindow.xaml.cs are not alphabetized; reorder all using
statements in that file (the ones above the class MidroundCustomizationWindow)
into strict alphabetical order (by namespace string) so System.* (System.Linq,
System.Numerics) appear in the correct position among the others, preserving any
blank lines grouping (e.g., framework vs project usings) if present and ensuring
no duplicates are introduced.

In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`:
- Around line 504-530: The handler OnPointLightColorToggle contains redundant
inner checks for PointLightColorEnabled after already returning when
component.PointLightColorEnabled == args.Enabled; remove those unnecessary
conditionals: in the args.Enabled branch assume the flag was previously
false—capture OriginalPointLightColor via _pointLight.TryGetLight once, set
component.PointLightColorEnabled = true and call
UpdatePointLightColorIfEnabled(uid, component); in the else branch assume the
flag was previously true—call _pointLight.SetColor(uid,
component.OriginalPointLightColor) and then set component.PointLightColorEnabled
= false; keep all referenced symbols
(MidroundCustomizationComponent.PointLightColorEnabled, OriginalPointLightColor,
_pointLight.TryGetLight, _pointLight.SetColor, UpdatePointLightColorIfEnabled,
args.Enabled) unchanged.

In `@Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs`:
- Around line 80-81: Replace the conversational Russian comment around the
"ADT-Tweak-Start" block in CrewMonitoringServerSystem (the comment above the
second removal pass) with a concise technical explanation that documents the
invariant being protected and why a second removal pass is necessary: state that
the extra pass ensures entities flagged OnMob (embedded sensors) do not remain
as remnants after the first cleanup, describe the specific invariant (no
monitoring entities should persist with OnMob == true after cleanup), and
mention any edge-case behavior for embedded sensors so future maintainers
understand why the deletion is repeated.

In `@Content.Shared/ADT/Silicons/MobIpcComponent.cs`:
- Around line 6-14: Добавьте XML-документацию для компонента MobIpcComponent и
его публичных полей: поместите /// <summary>...</summary> над объявлением класса
MobIpcComponent и над полями DisablePointLightOnDeath и LightDisabledByDeath,
кратко описав назначение компонента и каждого поля; если LightDisabledByDeath
используется только как runtime-флаг и не должен сериализоваться из прототипов,
удалите атрибут [DataField] с поля LightDisabledByDeath, оставив его как обычное
публичное поле.

In `@Content.Shared/ADT/Silicons/MobIpcSystem.cs`:
- Around line 6-39: Add XML documentation comments for the MobIpcSystem class
and its OnMobStateChanged method: add a /// <summary> for MobIpcSystem
describing that it subscribes to mob state changes and manages point light
behavior on death/resurrection, and add /// <summary> on OnMobStateChanged
explaining it handles MobStateChangedEvent, disables the point light when
NewMobState==MobState.Dead (respecting DisablePointLightOnDeath), marks
LightDisabledByDeath and calls Dirty, and restores the light when transitioning
from Dead if LightDisabledByDeath was set; also add <param> tags for the ent and
args parameters to describe their roles and mention any side effects (calls to
SharedPointLightSystem methods and Dirty).

In `@Content.Shared/Medical/SuitSensors/SuitSensorComponent.cs`:
- Around line 97-101: Add an XML summary for the public bool field OnMob in
SuitSensorComponent to match the style of the other documented fields; update
the declaration marked with [DataField, AutoNetworkedField] and the symbol name
OnMob by inserting a /// <summary> that briefly explains what OnMob controls
(e.g., whether sensors detect mobs/creatures or operate on mobile entities) and
any important behavior or default meaning so the field is documented
consistently with the rest of the component.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2ed136f3-83b6-46fc-b128-69f874e7ad48

📥 Commits

Reviewing files that changed from the base of the PR and between c1f609c and d791d7f.

⛔ Files ignored due to path filters (38)
  • Resources/Audio/ADT/Voice/IPC/i_female_cough_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_cough_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_cry_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_cry_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_cry_3.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_cry_4.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_giggle_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_giggle_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_laugh_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_laugh_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_sigh_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_sigh_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_sneeze_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_sneeze_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_female_yawn.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_cough_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_cough_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_cry_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_cry_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_cry_3.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_cry_4.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_laugh_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_laugh_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_sigh_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_sigh_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_sneeze_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_sneeze_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_male_yawn.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_neutral_sneeze.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_spit_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_spit_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_whistle_1.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_whistle_2.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_whistle_3.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Audio/ADT/Voice/IPC/i_whistle_4.ogg is excluded by !**/*.ogg, !**/*.ogg
  • Resources/Textures/ADT/Mobs/Customization/Ipc/ipc_screens.rsi/ipc_screen_broken.png is excluded by !**/*.png, !**/*.png
  • Resources/Textures/ADT/Mobs/Customization/Ipc/ipc_screens.rsi/ipc_screen_redtext.png is excluded by !**/*.png, !**/*.png
  • Resources/Textures/ADT/Mobs/Customization/Ipc/ipc_screens.rsi/ipc_screen_text.png is excluded by !**/*.png, !**/*.png
📒 Files selected for processing (31)
  • Content.Client/ADT/Lobby/UI/QuirksWindow.xaml.cs
  • Content.Client/ADT/MidroundCustomization/MidroundCustomizationBoundUserInterface.cs
  • Content.Client/ADT/MidroundCustomization/MidroundCustomizationWindow.xaml
  • Content.Client/ADT/MidroundCustomization/MidroundCustomizationWindow.xaml.cs
  • Content.Server/ADT/MidroundCustomization/MidroundCustomizationComponent.cs
  • Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs
  • Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs
  • Content.Server/Mobs/DeathgaspComponent.cs
  • Content.Server/Mobs/DeathgaspSystem.cs
  • Content.Server/Traits/TraitSystem.cs
  • Content.Shared/ADT/MidroundCustomization/BUI.cs
  • Content.Shared/ADT/Silicons/MobIpcComponent.cs
  • Content.Shared/ADT/Silicons/MobIpcSystem.cs
  • Content.Shared/Medical/SuitSensors/SharedSuitSensorSystem.cs
  • Content.Shared/Medical/SuitSensors/SuitSensorComponent.cs
  • Content.Shared/Traits/TraitPrototype.cs
  • Resources/Audio/ADT/Voice/IPC/attributions.yml
  • Resources/Locale/ru-RU/ADT/Chat/emotes.ftl
  • Resources/Locale/ru-RU/ADT/actions/ipsscreen.ftl
  • Resources/Locale/ru-RU/ADT/prototypes/Entities/Mobs/Customization/Markings/ipc.ftl
  • Resources/Locale/ru-RU/ADT/traits/neutral.ftl
  • Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/ipc_screens.yml
  • Resources/Prototypes/ADT/Entities/Mobs/Species/ipc.yml
  • Resources/Prototypes/ADT/InventoryTemplates/ipc_inventory_template.yml
  • Resources/Prototypes/ADT/SoundCollections/emotes.yml
  • Resources/Prototypes/ADT/Traits/quirks.yml
  • Resources/Prototypes/ADT/Voice/speech_emote_sounds.yml
  • Resources/Prototypes/ADT/Voice/speech_emotes.yml
  • Resources/Prototypes/Voice/disease_emotes.yml
  • Resources/Prototypes/Voice/speech_emotes.yml
  • Resources/Textures/ADT/Mobs/Customization/Ipc/ipc_screens.rsi/meta.json

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: 1

🧹 Nitpick comments (1)
Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs (1)

16-19: Нарушен алфавитный порядок using.

Новые импорты размещены в конце файла, но должны быть интегрированы в алфавитном порядке согласно правилам проекта для /ADT/ систем.

♻️ Исправление порядка
 using Content.Shared.Interaction;
+using Content.Shared.Mobs;
+using Content.Shared.Mobs.Components;
 using Content.Shared.Preferences;
 using Content.Shared.UserInterface;
 using Robust.Server.GameObjects;
 using Robust.Shared.Audio.Systems;
+using Robust.Shared.GameObjects;
 using Robust.Shared.Prototypes;
 using System.Linq;
-using Content.Shared.Mobs;
-using Content.Shared.Mobs.Components;
-using Robust.Shared.GameObjects;

As per coding guidelines: «using был в алфавитном порядке в наших /ADT/ системах и компонентах».

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`
around lines 16 - 19, The using directives for MidroundCustomizationSystem are
not alphabetized; reorder the existing usings (System.Linq, Content.Shared.Mobs,
Content.Shared.Mobs.Components, Robust.Shared.GameObjects) into proper
alphabetical order and integrate any new imports accordingly so the top-of-file
usings for the MidroundCustomizationSystem follow the project's /ADT/
alphabetical convention.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`:
- Around line 625-638: RevertToOriginals currently iterates
component.OriginalMarkings and calls _humanoid.SetMarkingId/SetMarkingColor
without validating that the (cat, slot) still exists; replicate the slot-bounds
check used in ApplyStateChanges: for each (cat, slot) fetch the current
MarkingSet for that category (via the humanoid/marking API used elsewhere),
ensure slot is within the set's valid range (slot >= 0 && slot <
markingSet.Slots/Count), and only then call _humanoid.SetMarkingId and
_humanoid.SetMarkingColor; if the marking set or slot is missing, skip that
entry to avoid out-of-range errors.

---

Nitpick comments:
In `@Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs`:
- Around line 16-19: The using directives for MidroundCustomizationSystem are
not alphabetized; reorder the existing usings (System.Linq, Content.Shared.Mobs,
Content.Shared.Mobs.Components, Robust.Shared.GameObjects) into proper
alphabetical order and integrate any new imports accordingly so the top-of-file
usings for the MidroundCustomizationSystem follow the project's /ADT/
alphabetical convention.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9a77c1e0-9490-4997-8405-ed2c2d21f847

📥 Commits

Reviewing files that changed from the base of the PR and between d791d7f and 0f7319a.

📒 Files selected for processing (3)
  • Content.Server/ADT/MidroundCustomization/MidroundCustomizationSystem.cs
  • Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs
  • Resources/Locale/ru-RU/ADT/traits/neutral.ftl
🚧 Files skipped from review as they are similar to previous changes (2)
  • Resources/Locale/ru-RU/ADT/traits/neutral.ftl
  • Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Changes: Audio Changes: Localization Изменение локализации Changes: Sprites Изменение спрайтов Changes: UI Изменение интерфейса size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants