Conversation
- Added AnimatronicControllerBoundUserInterface for managing animatronic interactions. - Created AnimatronicControllerWindow for UI representation of animatronics and waypoints. - Introduced AnimatronicRuntimeComponent to handle animatronic behavior. - Developed AnimatronicControllerSystem to manage UI events and animatronic states. - Added AnimatronicComponent and AnimatronicWaypointComponent for animatronic entities. - Implemented networking events for animatronic control and state updates. - Added prototypes for animatronic entities and waypoints, including visual assets.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughДобавлен полный набор функционала для управления аниматрониками: клиентский UI (AnimatronicControllerWindow и BoundUserInterface), сетевые сообщения/состояния (запрос данных, команды назначения цели и наблюдения, DTO для аниматроников и путевых точек), серверные системы (AnimatronicControllerSystem, AnimatronicTargetSystem, AnimatronicPathfindingSystem, AnimatronicSystem, AnimatronicDamageSystem) и компоненты (Animatronic, AnimatronicWaypoint, путь, урон, контроллер). Добавлены прототипы и ресурсы спрайтов. Клиент запрашивает состояние, отправляет команды; сервер формирует состояние, управляет целями, путями и рассылкой обновлений UI. Sequence Diagram(s)sequenceDiagram
participant User as Пользователь
participant UI as AnimatronicControllerWindow\n(Клиент UI)
participant BUI as AnimatronicControllerBoundUserInterface\n(Клиент BUI)
participant Net as Сеть
participant ACS as AnimatronicControllerSystem\n(Сервер)
participant ATS as AnimatronicTargetSystem\n(Сервер)
participant APS as AnimatronicPathfindingSystem\n(Сервер)
rect rgba(220,240,255,0.5)
Note over User,ACS: Открытие UI и запрос данных
User->>UI: Открывает окно
UI->>BUI: Open() / подписка на события
BUI->>Net: RequestAnimDataEvent
Net->>ACS: Получен запрос
ACS->>ACS: BuildAnimDataState()
ACS->>Net: AnimDataStateEvent
Net->>BUI: Получено состояние
BUI->>UI: UpdateState()
end
rect rgba(240,255,240,0.5)
Note over User,APS: Назначение цели аниматронику
User->>UI: Выбирает waypoint
UI->>BUI: OnAnimatronicWaypointSelected
BUI->>Net: SetAnimatronicTargetEvent(anim, waypoint)
Net->>ACS: Команда получена
ACS->>ATS: SetTarget(anim, waypoint)
ATS->>ATS: Валидация и регистрация в NPCSteering
ATS->>APS: InitializePathRetryIfNeeded(anim)
APS->>APS: Инициация поиска пути
ACS->>Net: AnimDataStateEvent (обновл.)
Net->>BUI: Обновление состояния
BUI->>UI: UpdateState()
end
rect rgba(255,240,240,0.5)
Note over APS,ACS: Движение, достижение и обновление UI
APS->>APS: UpdatePathIfNeeded() / HandlePathAvailability()
APS->>APS: OnReachedTarget() при достижении
APS->>ACS: AnimatronicReachedTargetEvent
ACS->>ACS: UpdateAllOpenUis()
ACS->>Net: AnimDataStateEvent (цель достигнута)
Net->>BUI: Получено обновление
BUI->>UI: UpdateState()
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 12
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (10)
Resources/Textures/Imperial/XxRaay/animatronics.rsi/bonnie.pngis excluded by!**/*.pngResources/Textures/Imperial/XxRaay/animatronics.rsi/chica.pngis excluded by!**/*.pngResources/Textures/Imperial/XxRaay/animatronics.rsi/foxy.pngis excluded by!**/*.pngResources/Textures/Imperial/XxRaay/animatronics.rsi/freddy.pngis excluded by!**/*.pngResources/Textures/Imperial/XxRaay/animatronics.rsi/icon bonnie.pngis excluded by!**/*.pngResources/Textures/Imperial/XxRaay/animatronics.rsi/icon chica.pngis excluded by!**/*.pngResources/Textures/Imperial/XxRaay/animatronics.rsi/icon foxy.pngis excluded by!**/*.pngResources/Textures/Imperial/XxRaay/animatronics.rsi/icon freddy.pngis excluded by!**/*.pngResources/Textures/Imperial/XxRaay/animatronics.rsi/icon metal frame.pngis excluded by!**/*.pngResources/Textures/Imperial/XxRaay/animatronics.rsi/metal frame.pngis excluded by!**/*.png
📒 Files selected for processing (16)
Content.Client/Imperial/XxRaay/UI/AnimatronicControllerBoundUserInterface.csContent.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xamlContent.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.csContent.Server/Imperial/XxRaay/Components/AnimatronicRuntimeComponent.csContent.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicSystem.csContent.Shared/Imperial/XxRaay/Components/AnimatronicComponent.csContent.Shared/Imperial/XxRaay/Components/AnimatronicControllerComponent.csContent.Shared/Imperial/XxRaay/Components/AnimatronicControllerUiKey.csContent.Shared/Imperial/XxRaay/Components/AnimatronicNet.csContent.Shared/Imperial/XxRaay/Components/AnimatronicWaypointComponent.csContent.Shared/Imperial/XxRaay/Components/Events/AnimatronicReachedTargetEvent.csResources/Prototypes/Imperial/XxRaay/animatronic_controller.ymlResources/Prototypes/Imperial/XxRaay/animatronic_waypoints.ymlResources/Prototypes/Imperial/XxRaay/animatronics.ymlResources/Textures/Imperial/XxRaay/animatronics.rsi/meta.json
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: XxRaay
Repo: imperial-space/SS14-public PR: 317
File: Content.Server/Imperial/Power/EntitySystems/Events/SupermatterLightningEvent.cs:9-12
Timestamp: 2025-07-31T09:43:48.369Z
Learning: Пользователь XxRaay в проекте imperial-space/SS14-public предпочитает оставлять комментарии к коду на русском языке и не считает необходимым переводить их на английский.
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28
Timestamp: 2025-08-04T20:34:48.192Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил неточность в анализе using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs - Content.Shared.Item действительно используется (ItemComponent), в отличие от Robust.Shared.Map и Robust.Server.GameObjects которые не используются.
📚 Learning: 2025-09-10T05:01:24.544Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 437
File: Content.Server/Imperial/Ninja/NinjaHeadset/NinjaHeadsetSystem.cs:24-27
Timestamp: 2025-09-10T05:01:24.544Z
Learning: В проекте imperial-space/SS14-public система взаимодействий позволяет экипированным предметам получать события AfterInteractEvent. Когда пользователь взаимодействует с целью, экипированный предмет может получить событие как "используемая" сущность (Used), где args.User - это пользователь, а args.Target - цель взаимодействия. Поэтому подписка SubscribeLocalEvent<ComponentType, AfterInteractEvent> на компоненты экипированных предметов работает корректно.
Applied to files:
Content.Shared/Imperial/XxRaay/Components/Events/AnimatronicReachedTargetEvent.cs
📚 Learning: 2025-07-27T16:27:11.103Z
Learnt from: Stevensegege
Repo: imperial-space/SS14-public PR: 354
File: Resources/Textures/Imperial/Seriozha/SCP/airlocks/doorremoreall.rsi/meta.json:1-14
Timestamp: 2025-07-27T16:27:11.103Z
Learning: В проекте imperial-space/SS14-public пользователь Stevensegege указал, что дублирование метаданных между файлами doorremote.rsi и doorremoreall.rsi в Resources/Textures/Imperial/Seriozha/SCP/airlocks/ является необходимым и преднамеренным решением для данного случая.
Applied to files:
Resources/Textures/Imperial/XxRaay/animatronics.rsi/meta.json
📚 Learning: 2025-08-04T20:34:48.192Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28
Timestamp: 2025-08-04T20:34:48.192Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил неточность в анализе using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs - Content.Shared.Item действительно используется (ItemComponent), в отличие от Robust.Shared.Map и Robust.Server.GameObjects которые не используются.
Applied to files:
Content.Shared/Imperial/XxRaay/Components/AnimatronicControllerComponent.csContent.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs
📚 Learning: 2025-08-04T20:34:48.192Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28
Timestamp: 2025-08-04T20:34:48.192Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил анализ using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs: Content.Shared.Item используется (ItemComponent на строке 70), Robust.Shared.Map используется (IMapManager на строке 44), только Robust.Server.GameObjects действительно не используется и должна быть удалена.
Applied to files:
Content.Shared/Imperial/XxRaay/Components/AnimatronicControllerComponent.cs
🧬 Code graph analysis (9)
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.cs (2)
Content.Shared/Imperial/XxRaay/Components/AnimatronicNet.cs (2)
SetAnimatronicTargetEvent(26-31)SetAnimatronicTargetEvent(33-38)Content.Shared/Imperial/XxRaay/Components/Events/AnimatronicReachedTargetEvent.cs (1)
AnimatronicReachedTargetEvent(8-10)
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs (3)
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.cs (2)
Initialize(38-44)OnSetTarget(46-94)Content.Shared/Imperial/XxRaay/Components/AnimatronicNet.cs (9)
SetAnimatronicTargetEvent(26-31)SetAnimatronicTargetEvent(33-38)SetAnimatronicObservingEvent(46-49)AnimDto(76-78)AnimDto(80-85)WaypointDto(95-97)WaypointDto(99-104)AnimDataStateEvent(58-60)AnimDataStateEvent(62-66)Content.Shared/Imperial/XxRaay/Components/Events/AnimatronicReachedTargetEvent.cs (1)
AnimatronicReachedTargetEvent(8-10)
Content.Shared/Imperial/XxRaay/Components/AnimatronicControllerComponent.cs (3)
Content.Server/Imperial/XxRaay/Components/AnimatronicRuntimeComponent.cs (1)
RegisterComponent(7-11)Content.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs (1)
RegisterComponent(15-65)Content.Shared/Imperial/XxRaay/Components/AnimatronicWaypointComponent.cs (1)
RegisterComponent(9-18)
Content.Shared/Imperial/XxRaay/Components/AnimatronicWaypointComponent.cs (3)
Content.Server/Imperial/XxRaay/Components/AnimatronicRuntimeComponent.cs (1)
RegisterComponent(7-11)Content.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs (1)
RegisterComponent(15-65)Content.Shared/Imperial/XxRaay/Components/AnimatronicControllerComponent.cs (1)
RegisterComponent(9-12)
Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs (2)
Content.Shared/Imperial/XxRaay/Components/AnimatronicNet.cs (6)
AnimDto(76-78)AnimDto(80-85)WaypointDto(95-97)WaypointDto(99-104)AnimDataStateEvent(58-60)AnimDataStateEvent(62-66)Content.Client/Imperial/XxRaay/UI/AnimatronicControllerBoundUserInterface.cs (1)
UpdateState(39-47)
Content.Shared/Imperial/XxRaay/Components/AnimatronicControllerUiKey.cs (1)
Content.Shared/Imperial/XxRaay/Components/AnimatronicNet.cs (6)
NetSerializable(14-17)NetSerializable(19-39)NetSerializable(41-50)NetSerializable(52-67)NetSerializable(69-86)NetSerializable(88-105)
Content.Server/Imperial/XxRaay/Components/AnimatronicRuntimeComponent.cs (3)
Content.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs (1)
RegisterComponent(15-65)Content.Shared/Imperial/XxRaay/Components/AnimatronicControllerComponent.cs (1)
RegisterComponent(9-12)Content.Shared/Imperial/XxRaay/Components/AnimatronicWaypointComponent.cs (1)
RegisterComponent(9-18)
Content.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs (3)
Content.Server/Imperial/XxRaay/Components/AnimatronicRuntimeComponent.cs (1)
RegisterComponent(7-11)Content.Shared/Imperial/XxRaay/Components/AnimatronicControllerComponent.cs (1)
RegisterComponent(9-12)Content.Shared/Imperial/XxRaay/Components/AnimatronicWaypointComponent.cs (1)
RegisterComponent(9-18)
Content.Client/Imperial/XxRaay/UI/AnimatronicControllerBoundUserInterface.cs (2)
Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs (2)
AnimatronicControllerWindow(29-33)UpdateState(35-53)Content.Shared/Imperial/XxRaay/Components/AnimatronicNet.cs (5)
SetAnimatronicTargetEvent(26-31)SetAnimatronicTargetEvent(33-38)SetAnimatronicObservingEvent(46-49)AnimDataStateEvent(58-60)AnimDataStateEvent(62-66)
🔇 Additional comments (15)
Content.Shared/Imperial/XxRaay/Components/AnimatronicWaypointComponent.cs (2)
6-18: Хорошая документация и структура компонента.Компонент правильно оформлен с XML-документацией, атрибутами
RegisterComponentиNetworkedComponent, а также сDataFieldдля сериализации. Структура соответствует паттернам SS14 ECS.
13-14: Текущее состояние: все прототипы корректно инициализируют waypointId.Проверка показала, что все 6 waypoint-прототипов в файле
Resources/Prototypes/Imperial/XxRaay/animatronic_waypoints.ymlявно устанавливают непустые значенияwaypointId(WP1–WP6). СистемыAnimatronicSystemиAnimatronicControllerSystemиспользуют эти значения без ошибок. Дефолтное значениеstring.Emptyявляется невидимым fallback'ом.Хотя код работает корректно в текущем состоянии, с точки зрения defensive programming можно рассмотреть добавление валидации при инициализации компонента, чтобы гарантировать, что пустые ID не будут случайно введены в будущих прототипах.
Resources/Prototypes/Imperial/XxRaay/animatronic_controller.yml (1)
1-27: Хорошо настроенный админский инструмент.Прототип корректно настроен как административный инструмент с ограничениями:
adminOnly: true- доступ только для администраторовsingleUser: true- предотвращает конфликты при одновременном использованииinHandsOnly: true- требует держать в руках, предотвращает злоупотребленияСтруктура соответствует стандартам SS14, и привязка к
AnimatronicControllerBoundUserInterfaceинтегрируется с клиентским UI из других файлов PR.Content.Shared/Imperial/XxRaay/Components/AnimatronicControllerUiKey.cs (1)
6-10: Корректная реализация UI ключа.Enum правильно определён с атрибутом
NetSerializableдля сетевой сериализации и типомbyteдля эффективности. Структура соответствует паттернам SS14 для UI ключей и корректно используется в прототипе контроллера.Resources/Textures/Imperial/XxRaay/animatronics.rsi/meta.json (1)
7-8: Метаданные файла корректны. Атрибуция "Askall" и лицензия CC-BY-SA-3.0 соответствуют стандартам проекта и не требуют изменений.Content.Shared/Imperial/XxRaay/Components/Events/AnimatronicReachedTargetEvent.cs (1)
1-10: LGTM! Корректная реализация события-маркера.Пустое событие, наследующее
EntityEventArgs, является стандартным паттерном для событий-маркеров в ECS-архитектуре. Документация на русском языке соответствует предпочтениям проекта.Content.Shared/Imperial/XxRaay/Components/AnimatronicControllerComponent.cs (1)
1-13: LGTM! Корректная реализация компонента-маркера.Пустой компонент с атрибутами
[RegisterComponent]и[NetworkedComponent]является стандартным паттерном для tag-компонентов, которые просто помечают сущность (в данном случае - портативный контроллер аниматроников). Документация на русском языке соответствует стандартам проекта.Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml (1)
1-15: LGTM! Корректная структура UI для контроллера аниматроников.XAML-разметка выглядит правильно:
- Наследуется от
BaseImperialWindow(соответствует стилю проекта)- Разумные размеры окна (минимум 700×400, по умолчанию 800×450)
ScrollContainerдля списка аниматроников обеспечит прокрутку при большом количестве элементов- Публичный доступ к
ContentsиAnimatronicsListпозволяет code-behind динамически заполнять UIResources/Prototypes/Imperial/XxRaay/animatronics.yml (3)
67-72: Дублирование скорости (Chicken).Та же проблема дублирования
moveSpeed(2.2) иbaseWalkSpeed/baseSprintSpeed(2.2).⛔ Skipped due to learnings
Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 413 File: Resources/Prototypes/Imperial/Crook/misc.yml:474-476 Timestamp: 2025-09-02T08:08:35.555Z Learning: В проекте imperial-space/SS14-public для сущности MobDeathmoth в файле Resources/Prototypes/Imperial/Crook/misc.yml преднамеренно установлено значение baseSprintSpeed (2) меньше чем baseWalkSpeed (3.5) - это дизайнерское решение, а не ошибка.Learnt from: Stevensegege Repo: imperial-space/SS14-public PR: 354 File: Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml:114-117 Timestamp: 2025-07-27T16:35:42.639Z Learning: Пользователь Stevensegege в проекте imperial-space/SS14-public подтвердил, что дублирование пути спрайта в компонентах Sprite и Clothing для entity ImperialSCPMask в файле Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml является преднамеренным дизайнерским решением.Learnt from: Stevensegege Repo: imperial-space/SS14-public PR: 371 File: Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml:20-24 Timestamp: 2025-08-05T20:05:21.550Z Learning: Пользователь Stevensegege в проекте imperial-space/SS14-public подтвердил, что компонент SlowOnDamage с enabled: false в ImperialSCPBase является правильным переопределением родительского компонента из SimpleSpaceMobBase, который содержит настройки speedModifierThresholds.
83-88: Дублирование скорости (Foxar).Та же проблема дублирования
moveSpeed(7) иbaseWalkSpeed/baseSprintSpeed(7).⛔ Skipped due to learnings
Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 413 File: Resources/Prototypes/Imperial/Crook/misc.yml:474-476 Timestamp: 2025-09-02T08:08:35.555Z Learning: В проекте imperial-space/SS14-public для сущности MobDeathmoth в файле Resources/Prototypes/Imperial/Crook/misc.yml преднамеренно установлено значение baseSprintSpeed (2) меньше чем baseWalkSpeed (3.5) - это дизайнерское решение, а не ошибка.Learnt from: Stevensegege Repo: imperial-space/SS14-public PR: 371 File: Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml:20-24 Timestamp: 2025-08-05T20:05:21.550Z Learning: Пользователь Stevensegege в проекте imperial-space/SS14-public подтвердил, что компонент SlowOnDamage с enabled: false в ImperialSCPBase является правильным переопределением родительского компонента из SimpleSpaceMobBase, который содержит настройки speedModifierThresholds.Learnt from: Stevensegege Repo: imperial-space/SS14-public PR: 354 File: Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml:114-117 Timestamp: 2025-07-27T16:35:42.639Z Learning: Пользователь Stevensegege в проекте imperial-space/SS14-public подтвердил, что дублирование пути спрайта в компонентах Sprite и Clothing для entity ImperialSCPMask в файле Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml является преднамеренным дизайнерским решением.Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 437 File: Content.Server/Imperial/Ninja/NinjaHeadset/NinjaHeadsetSystem.cs:0-0 Timestamp: 2025-09-10T04:59:56.355Z Learning: В проекте imperial-space/SS14-public пользователь CrookLv (автор PR #437) уточнил, что DoAfter для копирования частот гарнитурой ниндзя должен прерываться при получении урона или движении, несмотря на то что в описании PR было указано "не должен прерываться". Правильные настройки: BreakOnDamage = true, BreakOnMove = true.
51-56: Дублирование скорости (Bunny).Та же проблема дублирования
moveSpeed(2.2) иbaseWalkSpeed/baseSprintSpeed(2.2).⛔ Skipped due to learnings
Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 413 File: Resources/Prototypes/Imperial/Crook/misc.yml:474-476 Timestamp: 2025-09-02T08:08:35.555Z Learning: В проекте imperial-space/SS14-public для сущности MobDeathmoth в файле Resources/Prototypes/Imperial/Crook/misc.yml преднамеренно установлено значение baseSprintSpeed (2) меньше чем baseWalkSpeed (3.5) - это дизайнерское решение, а не ошибка.Learnt from: Stevensegege Repo: imperial-space/SS14-public PR: 354 File: Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml:114-117 Timestamp: 2025-07-27T16:35:42.639Z Learning: Пользователь Stevensegege в проекте imperial-space/SS14-public подтвердил, что дублирование пути спрайта в компонентах Sprite и Clothing для entity ImperialSCPMask в файле Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml является преднамеренным дизайнерским решением.Learnt from: Stevensegege Repo: imperial-space/SS14-public PR: 371 File: Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml:20-24 Timestamp: 2025-08-05T20:05:21.550Z Learning: Пользователь Stevensegege в проекте imperial-space/SS14-public подтвердил, что компонент SlowOnDamage с enabled: false в ImperialSCPBase является правильным переопределением родительского компонента из SimpleSpaceMobBase, который содержит настройки speedModifierThresholds.Content.Client/Imperial/XxRaay/UI/AnimatronicControllerBoundUserInterface.cs (1)
1-57: LGTM!Реализация
AnimatronicControllerBoundUserInterfaceкорректна и следует стандартным паттернам Robust Toolbox для связывания UI. Подписки на события правильно передают сообщения на сервер, состояние корректно пробрасывается в окно, а освобождение ресурсов реализовано правильно.Content.Shared/Imperial/XxRaay/Components/AnimatronicNet.cs (1)
1-107: LGTM!Сетевые DTO и события реализованы корректно. Все классы имеют необходимые атрибуты
[NetSerializable, Serializable]и параметрless конструкторы для десериализации. Структура данных хорошо организована.Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.cs (1)
46-94: Методы служат разным целям и не являются дублированием.
OnSetTargetвAnimatronicControllerSystemобрабатывает UI-событие и вызываетUpdateUi(), в то время какOnSetTargetвAnimatronicSystemобрабатывает сетевое событие и управляет логикой повтора пути (LastPathRetryTime,LastWaypointUpdateTime) с проверкой статусаNPCSteeringComponent. Несмотря на пересечение в базовой логике установки цели, эти методы имеют различные ответственности и не могут быть объединены без потери функциональности.Likely an incorrect or invalid review comment.
Content.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs (1)
22-23: Удалите неиспользуемое полеMoveSpeed.Поле
MoveSpeedобъявлено, но не используется вAnimatronicSystem,AnimatronicControllerSystemили в остальной кодовой базе. Удалите это поле, если оно не планируется использовать в ближайшем будущем.⛔ Skipped due to learnings
Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 362 File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28 Timestamp: 2025-08-04T20:34:48.192Z Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил анализ using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs: Content.Shared.Item используется (ItemComponent на строке 70), Robust.Shared.Map используется (IMapManager на строке 44), только Robust.Server.GameObjects действительно не используется и должна быть удалена.Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 413 File: Resources/Prototypes/Imperial/Crook/misc.yml:474-476 Timestamp: 2025-09-02T08:08:35.555Z Learning: В проекте imperial-space/SS14-public для сущности MobDeathmoth в файле Resources/Prototypes/Imperial/Crook/misc.yml преднамеренно установлено значение baseSprintSpeed (2) меньше чем baseWalkSpeed (3.5) - это дизайнерское решение, а не ошибка.Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 362 File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28 Timestamp: 2025-08-04T20:34:48.192Z Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил неточность в анализе using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs - Content.Shared.Item действительно используется (ItemComponent), в отличие от Robust.Shared.Map и Robust.Server.GameObjects которые не используются.Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 376 File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:189-197 Timestamp: 2025-08-10T16:44:31.921Z Learning: В файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs в методе IsContrabandItem параметр detector необходимо сохранять, даже если он не используется напрямую в теле метода, так как он передаётся в вызовы вложенных методов IsIgnoredByDetector и IsContrabandAllowed. Удаление этого параметра вызывает ошибки компиляции.Learnt from: Stevensegege Repo: imperial-space/SS14-public PR: 371 File: Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml:20-24 Timestamp: 2025-08-05T20:05:21.550Z Learning: Пользователь Stevensegege в проекте imperial-space/SS14-public подтвердил, что компонент SlowOnDamage с enabled: false в ImperialSCPBase является правильным переопределением родительского компонента из SimpleSpaceMobBase, который содержит настройки speedModifierThresholds.
Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs
Outdated
Show resolved
Hide resolved
Content.Server/Imperial/XxRaay/Components/AnimatronicRuntimeComponent.cs
Outdated
Show resolved
Hide resolved
Content.Server/Imperial/XxRaay/Components/AnimatronicRuntimeComponent.cs
Outdated
Show resolved
Hide resolved
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs
Outdated
Show resolved
Hide resolved
Content.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs
Outdated
Show resolved
Hide resolved
|
Обновите свою локальную ветвь и движок до версии 268.1.0 |
…line systems - Deleted AnimatronicRuntimeComponent as it was no longer needed. - Updated AnimatronicControllerSystem to utilize new target and pathfinding systems. - Refactored AnimatronicSystem to improve target assignment and pathfinding logic. - Enhanced AnimatronicComponent by consolidating properties and removing unused fields. - Added AnimatronicReachedTargetEvent to signal when animatronics reach their targets. - Updated prototypes to include new components for animatronics.
There was a problem hiding this comment.
Actionable comments posted: 6
Fix all issues with AI Agents 🤖
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs:
- Around line 111-115: Метод UpdateUi содержит неиспользуемый параметр user;
уберите параметр user из сигнатуры UpdateUi(EntityUid controller, EntityUid
user) и обновите все вызовы UpdateUi(...) в проекте, либо если нужна информация
о пользователе — используйте user внутри метода для фильтрации/логирования перед
построением состояния (вызов BuildAnimDataState() и _ui.SetUiState(controller,
AnimatronicControllerUiKey.Key, state)); обеспечьте синхронность сигнатур в
местах вызова после изменения.
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs:
- Around line 58-62: The OnAnimatronicCollideEnd handler only removes
OtherEntity from AnimatronicDamageComponent.LastContactDamage on
EndCollideEvent, which can leak entries if the other entity is deleted without
that event; add a handler subscribed to EntityTerminatingEvent (for example
OnOtherEntityTerminating) that takes EntityTerminatingEvent/EntityUid of the
terminating entity and removes that uid from
AnimatronicDamageComponent.LastContactDamage, and ensure the system
registers/unregisters that handler alongside the existing collision handlers so
entries are cleaned when entities are destroyed or teleported.
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicPathfindingSystem.cs:
- Around line 21-24: Remove the empty override of Initialize in the
AnimatronicPathfindingSystem class: the method currently only calls
base.Initialize(), so delete the Initialize() override from
Content.Server.Imperial.XxRaay.Systems.AnimatronicPathfindingSystem to rely on
the base implementation; if there is any future custom initialization needed,
reintroduce an override and add logic there, otherwise do not keep a redundant
method that only forwards to Base.
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs:
- Around line 1-8: Remove the unused System.Numerics using directive from
AnimatronicTargetSystem.cs: open the file, locate the top using directives
(including "using System.Numerics;") and delete that line so only required
namespaces (e.g., Robust.Shared, Content.Shared...) remain; run the compiler or
IDE analyzer to confirm no remaining references to System.Numerics and that
Vector2 types resolve from Robust.Shared.
In @Content.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs:
- Around line 20-24: The field MoveSpeed on AnimatronicComponent is unused;
either remove the declaration 'public float MoveSpeed = 2.0f;' from the
AnimatronicComponent class to eliminate dead code, or if intended for future
behavior, wire it into the animatronic system (e.g., reference MoveSpeed from
the appropriate movement/AI system or component methods such as any movement
update method) and add unit/behavior tests to validate its effect; prefer
removing the unused MoveSpeed field if no consumer is added.
In @Content.Shared/Imperial/XxRaay/Components/AnimatronicConstants.cs:
- Around line 25-28: The DefaultWaypointUpdateInterval in AnimatronicConstants
(public static readonly TimeSpan DefaultWaypointUpdateInterval) is very short
(0.15s) and may harm server performance with many animatronics; increase it to a
less aggressive value (suggest 0.25–0.5 seconds) by updating the
TimeSpan.FromSeconds argument accordingly (e.g., TimeSpan.FromSeconds(0.25) or
TimeSpan.FromSeconds(0.5)) to reduce update frequency while keeping behavior
acceptable.
♻️ Duplicate comments (1)
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs (1)
72-86: Отсутствует проверка прав администратора дляAdminCameraEui.
AdminCameraEui— это административный инструмент. Текущая реализация позволяет любому игроку с доступом к контроллеру аниматроников открыть админ-камеру без проверки прав. Это уязвимость безопасности.🔎 Предлагаемое исправление
Добавьте зависимость и проверку прав:
+using Content.Server.Administration.Managers; [Dependency] private readonly UserInterfaceSystem _ui = default!; [Dependency] private readonly AnimatronicTargetSystem _targetSystem = default!; [Dependency] private readonly AnimatronicPathfindingSystem _pathfindingSystem = default!; [Dependency] private readonly EuiManager _eui = default!; +[Dependency] private readonly IAdminManager _admin = default!; private void OnSetObserving(Entity<AnimatronicControllerComponent> ent, ref SetAnimatronicObservingEvent args) { if (args.Actor is not { Valid: true } player) return; var animUid = GetEntity(args.Animatronic); if (!Exists(animUid) || !HasComp<AnimatronicComponent>(animUid)) return; if (!TryComp<ActorComponent>(player, out var actor)) return; + // Проверка прав администратора + if (!_admin.IsAdmin(actor.PlayerSession)) + return; + var ui = new AdminCameraEui(animUid); _eui.OpenEui(ui, actor.PlayerSession); }
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (11)
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicPathfindingSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.csContent.Shared/Imperial/XxRaay/Components/AnimatronicComponent.csContent.Shared/Imperial/XxRaay/Components/AnimatronicConstants.csContent.Shared/Imperial/XxRaay/Components/AnimatronicDamageComponent.csContent.Shared/Imperial/XxRaay/Components/AnimatronicPathfindingComponent.csContent.Shared/Imperial/XxRaay/Components/Events/AnimatronicReachedTargetEvent.csResources/Prototypes/Imperial/XxRaay/animatronics.yml
🧰 Additional context used
🧠 Learnings (15)
📓 Common learnings
Learnt from: XxRaay
Repo: imperial-space/SS14-public PR: 317
File: Content.Server/Imperial/Power/EntitySystems/Events/SupermatterLightningEvent.cs:9-12
Timestamp: 2025-07-31T09:43:48.369Z
Learning: Пользователь XxRaay в проекте imperial-space/SS14-public предпочитает оставлять комментарии к коду на русском языке и не считает необходимым переводить их на английский.
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28
Timestamp: 2025-08-04T20:34:48.192Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил неточность в анализе using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs - Content.Shared.Item действительно используется (ItemComponent), в отличие от Robust.Shared.Map и Robust.Server.GameObjects которые не используются.
📚 Learning: 2025-09-02T08:08:35.555Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 413
File: Resources/Prototypes/Imperial/Crook/misc.yml:474-476
Timestamp: 2025-09-02T08:08:35.555Z
Learning: В проекте imperial-space/SS14-public для сущности MobDeathmoth в файле Resources/Prototypes/Imperial/Crook/misc.yml преднамеренно установлено значение baseSprintSpeed (2) меньше чем baseWalkSpeed (3.5) - это дизайнерское решение, а не ошибка.
Applied to files:
Resources/Prototypes/Imperial/XxRaay/animatronics.yml
📚 Learning: 2025-08-04T20:34:48.192Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28
Timestamp: 2025-08-04T20:34:48.192Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил анализ using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs: Content.Shared.Item используется (ItemComponent на строке 70), Robust.Shared.Map используется (IMapManager на строке 44), только Robust.Server.GameObjects действительно не используется и должна быть удалена.
Applied to files:
Resources/Prototypes/Imperial/XxRaay/animatronics.ymlContent.Shared/Imperial/XxRaay/Components/AnimatronicDamageComponent.csContent.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.csContent.Shared/Imperial/XxRaay/Components/AnimatronicComponent.csContent.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs
📚 Learning: 2025-08-04T20:34:48.192Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28
Timestamp: 2025-08-04T20:34:48.192Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил неточность в анализе using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs - Content.Shared.Item действительно используется (ItemComponent), в отличие от Robust.Shared.Map и Robust.Server.GameObjects которые не используются.
Applied to files:
Resources/Prototypes/Imperial/XxRaay/animatronics.ymlContent.Server/Imperial/XxRaay/Systems/AnimatronicSystem.csContent.Shared/Imperial/XxRaay/Components/AnimatronicDamageComponent.csContent.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.csContent.Shared/Imperial/XxRaay/Components/AnimatronicComponent.csContent.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.csContent.Shared/Imperial/XxRaay/Components/AnimatronicConstants.csContent.Shared/Imperial/XxRaay/Components/AnimatronicPathfindingComponent.csContent.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs
📚 Learning: 2025-09-10T06:08:33.954Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 437
File: Content.Server/Imperial/Ninja/NinjaHeadset/NinjaHeadsetSystem.cs:71-73
Timestamp: 2025-09-10T06:08:33.954Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv указал, что в NinjaHeadsetSystem удаление проверки !headsetUid.HasValue после TryGetTargetHeadset вызовет ошибку, несмотря на то что метод возвращает true только когда headsetUid устанавливается в валидное значение. Это говорит о наличии крайних случаев или особенностей InventorySystem, требующих обе проверки.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs
📚 Learning: 2025-08-10T16:44:31.921Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 376
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:189-197
Timestamp: 2025-08-10T16:44:31.921Z
Learning: В файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs в методе IsContrabandItem параметр detector необходимо сохранять, даже если он не используется напрямую в теле метода, так как он передаётся в вызовы вложенных методов IsIgnoredByDetector и IsContrabandAllowed. Удаление этого параметра вызывает ошибки компиляции.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.csContent.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs
📚 Learning: 2025-08-08T21:30:17.736Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 376
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:117-148
Timestamp: 2025-08-08T21:30:17.736Z
Learning: В файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs в методе CheckForContraband множественные вызовы IsContrabandItem для одной и той же сущности являются необходимыми - попытка оптимизации через сохранение результата в локальной переменной приводит к появлению проблем в работе системы.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.cs
📚 Learning: 2025-09-03T14:12:14.463Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 418
File: Resources/Prototypes/Imperial/Crook/misc.yml:357-361
Timestamp: 2025-09-03T14:12:14.463Z
Learning: Пользователь CrookLv в проекте imperial-space/SS14-public подтвердил, что высокий структурный урон (Structural: 75) для entity Smiler в файле Resources/Prototypes/Imperial/Crook/misc.yml является преднамеренным дизайнерским решением для контента Backrooms.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs
📚 Learning: 2025-09-04T08:12:23.038Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 423
File: Resources/Prototypes/Imperial/Crook/misc.yml:648-651
Timestamp: 2025-09-04T08:12:23.038Z
Learning: Пользователь CrookLv в проекте imperial-space/SS14-public предпочитает использовать один порог в компоненте SlowOnDamage для сущности BackroomsBacteria вместо множественных порогов для лучшей читаемости состояния здоровья.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.csContent.Shared/Imperial/XxRaay/Components/AnimatronicDamageComponent.cs
📚 Learning: 2025-08-06T23:35:51.099Z
Learnt from: krevetkqqq
Repo: imperial-space/SS14-public PR: 366
File: Content.Server/Imperial/ElectroMouse/ElectroMouseSystem.cs:684-684
Timestamp: 2025-08-06T23:35:51.099Z
Learning: В проекте imperial-space/SS14-public пользователь krevetkqqq объяснил, что DamageDict в DamageableComponent всегда заготовлен со значениями 0 для всех типов урона, поэтому никогда не бывает пустым и не требует проверки на пустоту перед использованием LINQ операций.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.csContent.Shared/Imperial/XxRaay/Components/AnimatronicDamageComponent.csContent.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs
📚 Learning: 2025-08-02T17:48:55.569Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:132-145
Timestamp: 2025-08-02T17:48:55.569Z
Learning: Пользователь CrookLv в проекте imperial-space/SS14-public объяснил, что в системе MetalDetectorSystem не следует реагировать на все предметы с компонентами MeleeWeaponComponent или RangedWeaponComponent, поскольку это приведет к срабатыванию на безобидные предметы (игрушки, баллоны). Система должна полагаться на ContrabandComponent для определения действительно опасных предметов.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs
📚 Learning: 2025-07-27T11:26:21.822Z
Learnt from: Stevensegege
Repo: imperial-space/SS14-public PR: 354
File: Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml:161-161
Timestamp: 2025-07-27T11:26:21.822Z
Learning: Пользователь Stevensegege в проекте imperial-space/SS14-public намеренно установил высокое значение Blunt: 122 для entity ImperialSCPDoc в файле Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml, объясняя это тем, что персонаж должен быть "крутым" - это преднамеренное дизайнерское решение для SCP контента.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.cs
📚 Learning: 2025-08-05T20:05:21.550Z
Learnt from: Stevensegege
Repo: imperial-space/SS14-public PR: 371
File: Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml:20-24
Timestamp: 2025-08-05T20:05:21.550Z
Learning: Пользователь Stevensegege в проекте imperial-space/SS14-public подтвердил, что компонент SlowOnDamage с enabled: false в ImperialSCPBase является правильным переопределением родительского компонента из SimpleSpaceMobBase, который содержит настройки speedModifierThresholds.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.csContent.Shared/Imperial/XxRaay/Components/AnimatronicDamageComponent.csContent.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs
📚 Learning: 2025-10-06T14:45:55.852Z
Learnt from: XxRaay
Repo: imperial-space/SS14-public PR: 468
File: Resources/Prototypes/Imperial/XxRaay/syndiebattle_uplink.yml:2172-2181
Timestamp: 2025-10-06T14:45:55.852Z
Learning: В файле Resources/Prototypes/Imperial/XxRaay/syndiebattle_uplink.yml сущность MobSyndieBattleCatSyndy (syndicat) имеет намеренно нулевой урон в ближнем бою (MeleeWeapon damage.types.Slash: 0), так как это преднамеренное дизайнерское решение.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.cs
📚 Learning: 2025-09-10T05:05:09.383Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 437
File: Content.Server/Imperial/Ninja/NinjaHeadset/NinjaHeadsetSystem.cs:135-139
Timestamp: 2025-09-10T05:05:09.383Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv сообщил, что добавление Dirty(uid, ninjaEncryption) для EncryptionKeyHolderComponent в NinjaHeadsetSystem вызывает ошибки. В SS14 для уведомления об изменениях каналов EncryptionKeyHolderComponent используется событие EncryptionChannelsChangedEvent вместо прямого помечания компонента как Dirty.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs
🧬 Code graph analysis (6)
Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.cs (3)
Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs (3)
AnimatronicTargetSystem(15-75)ClearTarget(48-62)SetTarget(19-46)Content.Server/Imperial/XxRaay/Systems/AnimatronicPathfindingSystem.cs (3)
AnimatronicPathfindingSystem(15-155)Initialize(21-24)InitializePathRetryIfNeeded(143-154)Content.Shared/Imperial/XxRaay/Components/AnimatronicNet.cs (2)
SetAnimatronicTargetEvent(26-31)SetAnimatronicTargetEvent(33-38)
Content.Shared/Imperial/XxRaay/Components/AnimatronicDamageComponent.cs (3)
Content.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs (1)
RegisterComponent(10-31)Content.Shared/Imperial/XxRaay/Components/AnimatronicPathfindingComponent.cs (1)
RegisterComponent(11-38)Content.Shared/Imperial/XxRaay/Components/AnimatronicConstants.cs (1)
AnimatronicConstants(8-44)
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs (4)
Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs (2)
AnimatronicTargetSystem(15-75)SetTarget(19-46)Content.Server/Imperial/XxRaay/Systems/AnimatronicPathfindingSystem.cs (3)
AnimatronicPathfindingSystem(15-155)Initialize(21-24)InitializePathRetryIfNeeded(143-154)Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.cs (2)
Initialize(20-24)OnSetTarget(26-48)Content.Shared/Imperial/XxRaay/Components/Events/AnimatronicReachedTargetEvent.cs (2)
AnimatronicReachedTargetEvent(9-20)AnimatronicReachedTargetEvent(16-19)
Content.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs (4)
Content.Shared/Imperial/XxRaay/Components/AnimatronicDamageComponent.cs (1)
RegisterComponent(12-33)Content.Shared/Imperial/XxRaay/Components/AnimatronicPathfindingComponent.cs (1)
RegisterComponent(11-38)Content.Shared/Imperial/XxRaay/Components/AnimatronicControllerComponent.cs (1)
RegisterComponent(9-12)Content.Shared/Imperial/XxRaay/Components/AnimatronicWaypointComponent.cs (1)
RegisterComponent(9-18)
Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs (1)
Content.Shared/Imperial/XxRaay/Components/AnimatronicConstants.cs (1)
AnimatronicConstants(8-44)
Content.Shared/Imperial/XxRaay/Components/AnimatronicPathfindingComponent.cs (3)
Content.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs (1)
RegisterComponent(10-31)Content.Shared/Imperial/XxRaay/Components/AnimatronicDamageComponent.cs (1)
RegisterComponent(12-33)Content.Shared/Imperial/XxRaay/Components/AnimatronicConstants.cs (1)
AnimatronicConstants(8-44)
🔇 Additional comments (16)
Content.Shared/Imperial/XxRaay/Components/AnimatronicConstants.cs (1)
15-18: Значение ContactDamage = 200 соответствует намеренному дизайну.Это событийный контент FNAF (Five Nights at Freddy's), где аниматроники по задумке являются опасными противниками. Высокий урон согласуется с жанром и назначением контента, а реализация включает 1-секундный кулдаун для контроля частоты применения урона.
Content.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs (2)
1-10: Импорты корректны.Все используемые директивы
usingприменяются в коде:IGameTiming(строка 19),DamageableSystem(строка 20),MobStateSystem(строка 21),IPrototypeManager(строка 22),DamageSpecifierиDamageGroupPrototype(строки 46, 52),FixedPoint2(строка 52),MobStateComponent(строка 35),StartCollideEvent/EndCollideEvent(строки 27-28).
31-56: Логика нанесения урона реализована корректно.Метод правильно проверяет наличие необходимых компонентов, состояние моба, и применяет кулдаун. Использование
ignoreResistances: trueсоответствует ожидаемому поведению аниматроников.Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.cs (2)
26-48: Логика обработки цели реализована корректно.Метод правильно обрабатывает сетевые события, делегирует работу специализированным системам и инициализирует повторный поиск пути при необходимости.
16-18: Неиспользуемая зависимость_steering.Поле
_steering(NPCSteeringSystem) объявлено, но нигде не используется в этой системе. Вся работа со steering делегируется через_targetSystemи_pathfindingSystem.🔎 Предлагаемое исправление
[Dependency] private readonly AnimatronicTargetSystem _targetSystem = default!; [Dependency] private readonly AnimatronicPathfindingSystem _pathfindingSystem = default!; -[Dependency] private readonly NPCSteeringSystem _steering = default!;Также удалите неиспользуемые импорты:
using Content.Shared.Imperial.XxRaay.Components; -using Content.Server.NPC.Systems; using Content.Server.NPC.Components; using Content.Shared.Movement.Components; using Content.Shared.NPC; using Robust.Shared.GameObjects; -using Robust.Shared.Player;⛔ Skipped due to learnings
Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 362 File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28 Timestamp: 2025-08-04T20:34:48.192Z Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил анализ using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs: Content.Shared.Item используется (ItemComponent на строке 70), Robust.Shared.Map используется (IMapManager на строке 44), только Robust.Server.GameObjects действительно не используется и должна быть удалена.Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 362 File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28 Timestamp: 2025-08-04T20:34:48.192Z Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил неточность в анализе using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs - Content.Shared.Item действительно используется (ItemComponent), в отличие от Robust.Shared.Map и Robust.Server.GameObjects которые не используются.Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 437 File: Content.Server/Imperial/Ninja/NinjaHeadset/NinjaHeadsetSystem.cs:71-73 Timestamp: 2025-09-10T06:08:33.954Z Learning: В проекте imperial-space/SS14-public пользователь CrookLv указал, что в NinjaHeadsetSystem удаление проверки !headsetUid.HasValue после TryGetTargetHeadset вызовет ошибку, несмотря на то что метод возвращает true только когда headsetUid устанавливается в валидное значение. Это говорит о наличии крайних случаев или особенностей InventorySystem, требующих обе проверки.Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs (3)
19-46: МетодSetTargetреализован корректно.Логика валидации и установки цели охватывает все edge cases. Обеспечение необходимых компонентов (
InputMoverComponent,ActiveNPCComponent) перед регистрацией steering — правильный подход.
64-74: МетодHasReachedTargetреализован корректно.Проверка карты и расчёт расстояния через
TransformSystem.GetWorldPosition— правильный подход. Использование константыAnimatronicConstants.ReachDistanceобеспечивает единообразие.
57-61: Отсутствует вызовDirtyдляAnimatronicPathfindingComponent.После изменения
LastPathRetryTimeиLastWaypointUpdateTimeнеобходимо вызватьDirty(animatronic, pathfinding)для синхронизации состояния. Хотя эти поля помечены[NonSerialized]вAnimatronicPathfindingComponent, вызов Dirty обеспечит консистентность при наличии других сериализуемых полей.🔎 Предлагаемое исправление
if (TryComp<AnimatronicPathfindingComponent>(animatronic, out var pathfinding)) { pathfinding.LastPathRetryTime = null; pathfinding.LastWaypointUpdateTime = null; + Dirty(animatronic, pathfinding); }⛔ Skipped due to learnings
Learnt from: XxRaay Repo: imperial-space/SS14-public PR: 459 File: Content.Server/Imperial/XxRaay/SyndieBattle/SyndieBattleRuleSystem.cs:296-335 Timestamp: 2025-09-23T17:15:12.540Z Learning: В проекте imperial-space/SS14-public пользователь XxRaay подтвердил, что изменения StoreComponent.Balance и StoreComponent.Categories в методе GiveCustomUplink не требуют явного вызова Dirty() для корректной работы сетевой синхронизации.Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs (3)
88-109: РефакторингBuildAnimDataStateвыполнен корректно.Метод централизует построение состояния UI, устраняя дублирование кода между
UpdateUiиUpdateAllOpenUis. Хорошая практика.
52-70: Логика обработки цели в контроллере корректна.Метод правильно делегирует установку цели
_targetSystemи инициализирует повторный поиск пути при необходимости. Обновление UI после каждого действия обеспечивает актуальность отображаемых данных.
117-129: МетодUpdateAllOpenUisреализован эффективно.Однократный вызов
BuildAnimDataState()перед итерацией контроллеров минимизирует накладные расходы. ПроверкаIsUiOpenпредотвращает лишние обновления.Content.Server/Imperial/XxRaay/Systems/AnimatronicPathfindingSystem.cs (4)
26-51: Цикл обновления реализован корректно.Структура с ранними
continueобеспечивает читаемость. Валидация карты и наличия цели предотвращает ошибки при обработке.
53-81: МетодUpdatePathIfNeededреализован корректно.Логика обновления пути учитывает как изменение координат цели, так и временной интервал обновления. Сброс
FailedPathCountпри обновлении — правильный подход.
83-129: Логика обработки доступности пути корректна, но сложна.Метод правильно обрабатывает различные состояния пути и механизм повторных попыток. Проверка
justRegisteredпредотвращает ложные срабатывания сразу после регистрации.Рассмотрите возможность добавления комментариев для пояснения двух основных ветвей логики (путь доступен vs. путь недоступен) для улучшения поддерживаемости.
131-154: МетодыOnReachedTargetиInitializePathRetryIfNeededреализованы корректно.Событие
AnimatronicReachedTargetEventвызывается с правильнымEntityUid. ПаттернResolveвInitializePathRetryIfNeededобеспечивает гибкость использования метода с опциональным компонентом.Content.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs (1)
1-4: Неиспользуемый импортRobust.Shared.Serialization.Импорт
Robust.Shared.Serializationне используется в этом файле. Атрибут[DataField]не требует этого namespace.🔎 Предлагаемое исправление
using Robust.Shared.GameStates; -using Robust.Shared.Serialization; using Robust.Shared.GameObjects;⛔ Skipped due to learnings
Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 362 File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28 Timestamp: 2025-08-04T20:34:48.192Z Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил неточность в анализе using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs - Content.Shared.Item действительно используется (ItemComponent), в отличие от Robust.Shared.Map и Robust.Server.GameObjects которые не используются.Learnt from: CrookLv Repo: imperial-space/SS14-public PR: 362 File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28 Timestamp: 2025-08-04T20:34:48.192Z Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил анализ using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs: Content.Shared.Item используется (ItemComponent на строке 70), Robust.Shared.Map используется (IMapManager на строке 44), только Robust.Server.GameObjects действительно не используется и должна быть удалена.Learnt from: Ser1-1y Repo: imperial-space/SS14-public PR: 375 File: Content.Shared/Pinpointer/NavMapRequest.cs:9-15 Timestamp: 2025-08-06T16:36:30.691Z Learning: Robust.Shared.Serialization в проекте SS14 корректно сериализует [Serializable, NetSerializable] классы с readonly-полями и без параметрless-конструктора; менять их не нужно.
| private void OnAnimatronicCollideEnd(Entity<AnimatronicDamageComponent> ent, ref EndCollideEvent args) | ||
| { | ||
| var otherUid = args.OtherEntity; | ||
| ent.Comp.LastContactDamage.Remove(otherUid); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Потенциальная утечка памяти при удалении сущностей.
Если сущность удаляется без вызова EndCollideEvent (например, при телепортации или удалении), запись в LastContactDamage останется. Рекомендуется также подписаться на EntityTerminatingEvent для очистки словаря.
🔎 Предлагаемое исправление
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AnimatronicDamageComponent, StartCollideEvent>(OnAnimatronicCollide);
SubscribeLocalEvent<AnimatronicDamageComponent, EndCollideEvent>(OnAnimatronicCollideEnd);
+ SubscribeLocalEvent<AnimatronicDamageComponent, EntityTerminatingEvent>(OnAnimatronicTerminating);
}
+private void OnAnimatronicTerminating(Entity<AnimatronicDamageComponent> ent, ref EntityTerminatingEvent args)
+{
+ ent.Comp.LastContactDamage.Clear();
+}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private void OnAnimatronicCollideEnd(Entity<AnimatronicDamageComponent> ent, ref EndCollideEvent args) | |
| { | |
| var otherUid = args.OtherEntity; | |
| ent.Comp.LastContactDamage.Remove(otherUid); | |
| } | |
| public override void Initialize() | |
| { | |
| base.Initialize(); | |
| SubscribeLocalEvent<AnimatronicDamageComponent, StartCollideEvent>(OnAnimatronicCollide); | |
| SubscribeLocalEvent<AnimatronicDamageComponent, EndCollideEvent>(OnAnimatronicCollideEnd); | |
| SubscribeLocalEvent<AnimatronicDamageComponent, EntityTerminatingEvent>(OnAnimatronicTerminating); | |
| } | |
| private void OnAnimatronicCollideEnd(Entity<AnimatronicDamageComponent> ent, ref EndCollideEvent args) | |
| { | |
| var otherUid = args.OtherEntity; | |
| ent.Comp.LastContactDamage.Remove(otherUid); | |
| } | |
| private void OnAnimatronicTerminating(Entity<AnimatronicDamageComponent> ent, ref EntityTerminatingEvent args) | |
| { | |
| ent.Comp.LastContactDamage.Clear(); | |
| } |
🤖 Prompt for AI Agents
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs around
lines 58-62, The OnAnimatronicCollideEnd handler only removes OtherEntity from
AnimatronicDamageComponent.LastContactDamage on EndCollideEvent, which can leak
entries if the other entity is deleted without that event; add a handler
subscribed to EntityTerminatingEvent (for example OnOtherEntityTerminating) that
takes EntityTerminatingEvent/EntityUid of the terminating entity and removes
that uid from AnimatronicDamageComponent.LastContactDamage, and ensure the
system registers/unregisters that handler alongside the existing collision
handlers so entries are cleaned when entities are destroyed or teleported.
| public override void Initialize() | ||
| { | ||
| base.Initialize(); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Пустой метод Initialize можно удалить.
Метод Initialize содержит только вызов base.Initialize(). В SS14 это необязательно, если нет дополнительной логики инициализации.
🔎 Предлагаемое исправление
-public override void Initialize()
-{
- base.Initialize();
-}
-
public override void Update(float frameTime)📝 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.
| public override void Initialize() | |
| { | |
| base.Initialize(); | |
| } | |
| public override void Update(float frameTime) | |
| { | |
| // Update method body follows... | |
| } |
🤖 Prompt for AI Agents
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicPathfindingSystem.cs
around lines 21-24, Remove the empty override of Initialize in the
AnimatronicPathfindingSystem class: the method currently only calls
base.Initialize(), so delete the Initialize() override from
Content.Server.Imperial.XxRaay.Systems.AnimatronicPathfindingSystem to rely on
the base implementation; if there is any future custom initialization needed,
reintroduce an override and add logic there, otherwise do not keep a redundant
method that only forwards to Base.
Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs
Outdated
Show resolved
Hide resolved
| /// <summary> | ||
| /// Скорость движения аниматроника. | ||
| /// </summary> | ||
| [DataField("moveSpeed")] | ||
| public float MoveSpeed = 2.0f; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Search for all usages of MoveSpeed in C# files
rg -n 'MoveSpeed' --type=cs -B3 -A3Repository: imperial-space/SS14-public
Length of output: 8233
🏁 Script executed:
# Search for AnimatronicComponent usage and property access
rg -n 'AnimatronicComponent' --type=cs -B2 -A5Repository: imperial-space/SS14-public
Length of output: 7247
🏁 Script executed:
# Search for direct access to MoveSpeed property on AnimatronicComponent
rg -n '\.MoveSpeed|component\.MoveSpeed' --type=csRepository: imperial-space/SS14-public
Length of output: 52
Удалите неиспользуемое поле MoveSpeed.
Поле объявлено, но не используется ни в одной системе. Если оно предназначено для будущего использования, добавьте соответствующий код; в противном случае удалите его.
🤖 Prompt for AI Agents
In @Content.Shared/Imperial/XxRaay/Components/AnimatronicComponent.cs around
lines 20-24, The field MoveSpeed on AnimatronicComponent is unused; either
remove the declaration 'public float MoveSpeed = 2.0f;' from the
AnimatronicComponent class to eliminate dead code, or if intended for future
behavior, wire it into the animatronic system (e.g., reference MoveSpeed from
the appropriate movement/AI system or component methods such as any movement
update method) and add unit/behavior tests to validate its effect; prefer
removing the unused MoveSpeed field if no consumer is added.
| /// <summary> | ||
| /// Интервал по умолчанию для обновления позиции waypoint'а (если он перемещается). | ||
| /// </summary> | ||
| public static readonly TimeSpan DefaultWaypointUpdateInterval = TimeSpan.FromSeconds(0.15); |
There was a problem hiding this comment.
Рассмотрите увеличение интервала обновления позиции waypoint.
Интервал обновления DefaultWaypointUpdateInterval = 0.15 секунды (150 мс) достаточно агрессивный. При наличии нескольких активных аниматроников это может негативно сказаться на производительности сервера из-за частых обновлений позиций.
Рекомендуется увеличить интервал до 0.25-0.5 секунды, если это не критично для игрового процесса.
🤖 Prompt for AI Agents
In @Content.Shared/Imperial/XxRaay/Components/AnimatronicConstants.cs around
lines 25-28, The DefaultWaypointUpdateInterval in AnimatronicConstants (public
static readonly TimeSpan DefaultWaypointUpdateInterval) is very short (0.15s)
and may harm server performance with many animatronics; increase it to a less
aggressive value (suggest 0.25–0.5 seconds) by updating the TimeSpan.FromSeconds
argument accordingly (e.g., TimeSpan.FromSeconds(0.25) or
TimeSpan.FromSeconds(0.5)) to reduce update frequency while keeping behavior
acceptable.
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Fix all issues with AI agents
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs:
- Around line 111-115: The method UpdateUi has an unused parameter user—remove
the user parameter from the UpdateUi signature (keep UpdateUi(EntityUid
controller)) and update all call sites that pass a user (the calls referenced
near lines 44, 49, 57, 69) to call the new two-argument-less signature; ensure
any delegates or event-handler registrations that reference UpdateUi are updated
to match the new signature (use the method name UpdateUi to locate and change
them).
- Around line 72-86: The OnSetObserving handler opens AdminCameraEui without
checking administrative rights; add an IAdminManager dependency (e.g.,
[Dependency] private readonly IAdminManager _admin = default!) to the system
and, inside OnSetObserving before constructing/opening the UI (before new
AdminCameraEui(...) and _eui.OpenEui(...)), call
_admin.GetAdminData(actor.PlayerSession) and return if it is null to prevent
non-admins from opening the admin camera UI.
- Around line 52-70: OnSetTarget currently ignores the boolean result of
_targetSystem.SetTarget; capture its return value, and if it is false log a
warning including animUid and waypoint/args.Clear (and actor if available) so
failures are visible, and only call
_pathfindingSystem.InitializePathRetryIfNeeded and/or proceed with further
actions (like UpdateUi) when SetTarget returned true (or at least document why
UI should still update on failure).
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs:
- Around line 48-52: The code hardcodes the "Brute" damage group; add a
configurable field to AnimatronicDamageComponent (e.g., public string
DamageGroup = "Brute"; annotated with [DataField("damageGroup")]) and change the
lookup in AnimatronicDamageSystem from
_prototype.TryIndex<DamageGroupPrototype>("Brute", out var bruteGroup) to use
the component value:
_prototype.TryIndex<DamageGroupPrototype>(component.DamageGroup, out var
bruteGroup), making sure to null-check component and fall back to the default if
needed.
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs:
- Around line 52-66: ClearTarget currently calls
_steering.Unregister(animatronic) unconditionally; change it to only call
Unregister when the animatronic actually has a target (check anim.TargetWaypoint
!= null) to make the intent explicit and avoid unregistering non-registered
entities; locate the ClearTarget method and wrap or gate the
_steering.Unregister(animatronic) call with a conditional that inspects the
AnimatronicComponent.TargetWaypoint (or equivalent) before calling Unregister,
leaving the rest of the cleanup (clearing TargetWaypoint, Dirty(animatronic,
anim), and resetting AnimatronicPathfindingComponent timing fields) intact.
- Around line 28-50: The method sets anim.TargetWaypoint, calls
Dirty(animatronic, anim), and
EnsureComp<InputMoverComponent>/EnsureComp<ActiveNPCComponent> before attempting
to get the waypoint Transform and register with _steering, so if
TryComp<TransformComponent> fails (or registration fails) the mover/active
components remain incorrectly added; modify the logic in AnimatronicTargetSystem
(the block that uses waypoint, EnsureComp<...>, TryComp<TransformComponent>, and
_steering.Register) to first verify the waypoint Transform and perform the
_steering.Register call (or check Register's success) and only then call
EnsureComp<InputMoverComponent> and EnsureComp<ActiveNPCComponent>, or
alternatively roll back/remove those components (via RemComp or ClearTarget) if
registration fails, ensuring state is consistent when the method returns false.
- Line 21: Private field naming violates convention: rename the injected field
TransformSystem to follow private camelCase with underscore. Change the field
declaration [Dependency] private readonly SharedTransformSystem TransformSystem
= default! to use _transformSystem, and update all usages of TransformSystem
(e.g., the references around the former lines 73-74) to _transformSystem so the
symbol name is consistent across the class.
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs
🧰 Additional context used
🧠 Learnings (11)
📓 Common learnings
Learnt from: XxRaay
Repo: imperial-space/SS14-public PR: 317
File: Content.Server/Imperial/Power/EntitySystems/Events/SupermatterLightningEvent.cs:9-12
Timestamp: 2025-07-31T09:43:48.369Z
Learning: Пользователь XxRaay в проекте imperial-space/SS14-public предпочитает оставлять комментарии к коду на русском языке и не считает необходимым переводить их на английский.
Learnt from: onionsenpai-git
Repo: imperial-space/SS14-public PR: 394
File: Resources/Textures/Imperial/Other/ElysiumPrime/Misc/signs.rsi/meta.json:0-0
Timestamp: 2025-08-22T21:36:29.320Z
Learning: В проекте imperial-space/SS14-public движок корректно работает с горизонтальной упаковкой кадров в RSI спрайтах, даже если ширина PNG превышает size.x в meta.json файле. Пользователь onionsenpai-git подтвердил, что спрайты с размерами 64x32 при size.x=32 в meta.json работают без проблем.
Learnt from: Stevensegege
Repo: imperial-space/SS14-public PR: 354
File: Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml:114-117
Timestamp: 2025-07-27T16:35:42.639Z
Learning: Пользователь Stevensegege в проекте imperial-space/SS14-public подтвердил, что дублирование пути спрайта в компонентах Sprite и Clothing для entity ImperialSCPMask в файле Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml является преднамеренным дизайнерским решением.
📚 Learning: 2025-09-10T06:08:33.954Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 437
File: Content.Server/Imperial/Ninja/NinjaHeadset/NinjaHeadsetSystem.cs:71-73
Timestamp: 2025-09-10T06:08:33.954Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv указал, что в NinjaHeadsetSystem удаление проверки !headsetUid.HasValue после TryGetTargetHeadset вызовет ошибку, несмотря на то что метод возвращает true только когда headsetUid устанавливается в валидное значение. Это говорит о наличии крайних случаев или особенностей InventorySystem, требующих обе проверки.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs
📚 Learning: 2025-08-04T20:34:48.192Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28
Timestamp: 2025-08-04T20:34:48.192Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил неточность в анализе using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs - Content.Shared.Item действительно используется (ItemComponent), в отличие от Robust.Shared.Map и Robust.Server.GameObjects которые не используются.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs
📚 Learning: 2025-09-10T05:05:09.383Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 437
File: Content.Server/Imperial/Ninja/NinjaHeadset/NinjaHeadsetSystem.cs:135-139
Timestamp: 2025-09-10T05:05:09.383Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv сообщил, что добавление Dirty(uid, ninjaEncryption) для EncryptionKeyHolderComponent в NinjaHeadsetSystem вызывает ошибки. В SS14 для уведомления об изменениях каналов EncryptionKeyHolderComponent используется событие EncryptionChannelsChangedEvent вместо прямого помечания компонента как Dirty.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs
📚 Learning: 2025-08-04T20:34:48.192Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28
Timestamp: 2025-08-04T20:34:48.192Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил анализ using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs: Content.Shared.Item используется (ItemComponent на строке 70), Robust.Shared.Map используется (IMapManager на строке 44), только Robust.Server.GameObjects действительно не используется и должна быть удалена.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs
📚 Learning: 2025-08-02T17:48:55.569Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:132-145
Timestamp: 2025-08-02T17:48:55.569Z
Learning: Пользователь CrookLv в проекте imperial-space/SS14-public объяснил, что в системе MetalDetectorSystem не следует реагировать на все предметы с компонентами MeleeWeaponComponent или RangedWeaponComponent, поскольку это приведет к срабатыванию на безобидные предметы (игрушки, баллоны). Система должна полагаться на ContrabandComponent для определения действительно опасных предметов.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs
📚 Learning: 2025-09-10T06:06:57.116Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 437
File: Content.Server/Imperial/Ninja/NinjaHeadset/NinjaHeadsetSystem.cs:10-14
Timestamp: 2025-09-10T06:06:57.116Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv (автор PR #437) сообщил, что добавление using System.Collections.Generic; не требуется в файле Content.Server/Imperial/Ninja/NinjaHeadset/NinjaHeadsetSystem.cs, несмотря на использование HashSet и List в коде.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs
📚 Learning: 2025-08-10T16:44:31.921Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 376
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:189-197
Timestamp: 2025-08-10T16:44:31.921Z
Learning: В файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs в методе IsContrabandItem параметр detector необходимо сохранять, даже если он не используется напрямую в теле метода, так как он передаётся в вызовы вложенных методов IsIgnoredByDetector и IsContrabandAllowed. Удаление этого параметра вызывает ошибки компиляции.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs
📚 Learning: 2025-08-06T23:35:51.099Z
Learnt from: krevetkqqq
Repo: imperial-space/SS14-public PR: 366
File: Content.Server/Imperial/ElectroMouse/ElectroMouseSystem.cs:684-684
Timestamp: 2025-08-06T23:35:51.099Z
Learning: В проекте imperial-space/SS14-public пользователь krevetkqqq объяснил, что DamageDict в DamageableComponent всегда заготовлен со значениями 0 для всех типов урона, поэтому никогда не бывает пустым и не требует проверки на пустоту перед использованием LINQ операций.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs
📚 Learning: 2025-08-05T20:05:21.550Z
Learnt from: Stevensegege
Repo: imperial-space/SS14-public PR: 371
File: Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml:20-24
Timestamp: 2025-08-05T20:05:21.550Z
Learning: Пользователь Stevensegege в проекте imperial-space/SS14-public подтвердил, что компонент SlowOnDamage с enabled: false в ImperialSCPBase является правильным переопределением родительского компонента из SimpleSpaceMobBase, который содержит настройки speedModifierThresholds.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs
📚 Learning: 2025-09-03T14:12:14.463Z
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 418
File: Resources/Prototypes/Imperial/Crook/misc.yml:357-361
Timestamp: 2025-09-03T14:12:14.463Z
Learning: Пользователь CrookLv в проекте imperial-space/SS14-public подтвердил, что высокий структурный урон (Structural: 75) для entity Smiler в файле Resources/Prototypes/Imperial/Crook/misc.yml является преднамеренным дизайнерским решением для контента Backrooms.
Applied to files:
Content.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs
🧬 Code graph analysis (2)
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs (5)
Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs (2)
AnimatronicTargetSystem(18-79)SetTarget(23-50)Content.Server/Imperial/XxRaay/Systems/AnimatronicPathfindingSystem.cs (3)
AnimatronicPathfindingSystem(15-155)Initialize(21-24)InitializePathRetryIfNeeded(143-154)Content.Server/Imperial/XxRaay/Systems/AnimatronicSystem.cs (2)
Initialize(20-24)OnSetTarget(26-48)Content.Shared/Imperial/XxRaay/Components/AnimatronicNet.cs (2)
SetAnimatronicTargetEvent(26-31)SetAnimatronicTargetEvent(33-38)Content.Shared/Imperial/XxRaay/Components/Events/AnimatronicReachedTargetEvent.cs (2)
AnimatronicReachedTargetEvent(9-20)AnimatronicReachedTargetEvent(16-19)
Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs (2)
Content.Server.Database/Model.cs (1)
Server(707-719)Content.Shared/Imperial/XxRaay/Components/AnimatronicConstants.cs (1)
AnimatronicConstants(8-44)
🔇 Additional comments (9)
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs (7)
1-12: LGTM: Импорты корректны.Все using-директивы используются в коде, избыточных импортов нет.
17-22: LGTM: Зависимости корректно объявлены.Все внедренные зависимости используются в методах системы.
24-35: LGTM: Инициализация событий выполнена корректно.Подписки на события BUI и локальное событие AnimatronicReachedTargetEvent настроены правильно.
37-40: LGTM: Обработка события достижения цели.Обновление всех открытых UI при достижении цели аниматроником реализовано корректно.
42-50: LGTM: Обработчики открытия UI и запроса данных.Оба обработчика корректно вызывают обновление UI для пользователя.
88-109: LGTM: Рефакторинг извлечения данных состояния.Метод
BuildAnimDataStateуспешно устраняет дублирование кода, отмеченное в предыдущем review. Логика построения списков аниматроников и вейпоинтов вынесена в отдельный метод, что улучшает читаемость и поддерживаемость кода.
117-129: LGTM: Обновление всех открытых UI.Метод
UpdateAllOpenUisкорректно рассылает обновленное состояние всем открытым интерфейсам контроллеров аниматроников.Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs (1)
68-78: LGTM: корректная проверка достижения цели.Метод
HasReachedTargetкорректно проверяет:
- Валидность MapID (не Nullspace и совпадение карт)
- Расстояние между позициями через мировые координаты
- Использование константы
AnimatronicConstants.ReachDistanceдля порогаЛогика реализована правильно и эффективно.
Content.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs (1)
48-56: Добавьте комментарий, объясняющий игнорирование сопротивлений для контактного урона аниматроников.На строке 55 используется
ignoreResistances: true, игнорирующий броню и защиту цели. Хотя подобный паттерн применяется и для других специальных видов урона (температура, неуничтожимые объекты), отсутствие комментария создаёт неясность о дизайнерском намерении.Если это преднамеренное решение для повышения сложности игровых событий, добавьте пояснительный комментарий. Если это не было обдуманным выбором, рассмотрите удаление параметра.
♻️ Рекомендуемое исправление (вариант 1 – с комментарием)
var damage = new DamageSpecifier(bruteGroup, FixedPoint2.New(damageComp.ContactDamage)); +// Аниматроники игнорируют броню как часть механики события _damageable.TryChangeDamage(otherUid, damage, ignoreResistances: true, origin: ent.Owner);
| private void OnSetTarget(Entity<AnimatronicControllerComponent> ent, ref SetAnimatronicTargetEvent args) | ||
| { | ||
| var animUid = GetEntity(args.Animatronic); | ||
| if (!TryComp<AnimatronicComponent>(animUid, out var anim)) | ||
| { | ||
| UpdateUi(ent.Owner, args.Actor); | ||
| return; | ||
| } | ||
|
|
||
| EntityUid? wpUid = args.Clear ? null : GetEntity(args.Waypoint); | ||
| _targetSystem.SetTarget(animUid, wpUid); | ||
|
|
||
| if (!args.Clear && TryComp<AnimatronicPathfindingComponent>(animUid, out var pathfinding)) | ||
| { | ||
| _pathfindingSystem.InitializePathRetryIfNeeded(animUid, pathfinding); | ||
| } | ||
|
|
||
| UpdateUi(ent.Owner, args.Actor); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Рассмотрите обработку результата SetTarget.
Метод _targetSystem.SetTarget возвращает bool, указывающий на успех операции, но возвращаемое значение не проверяется. Хотя UI всегда обновляется и отобразит текущее состояние, явная проверка и логирование неудачных попыток может помочь при отладке.
♻️ Предлагаемое улучшение
private void OnSetTarget(Entity<AnimatronicControllerComponent> ent, ref SetAnimatronicTargetEvent args)
{
var animUid = GetEntity(args.Animatronic);
if (!TryComp<AnimatronicComponent>(animUid, out var anim))
{
UpdateUi(ent.Owner, args.Actor);
return;
}
EntityUid? wpUid = args.Clear ? null : GetEntity(args.Waypoint);
- _targetSystem.SetTarget(animUid, wpUid);
+ var success = _targetSystem.SetTarget(animUid, wpUid);
+ if (!success && !args.Clear)
+ {
+ // Логирование неудачной попытки установки цели
+ Log.Warning($"Не удалось установить цель для аниматроника {animUid}");
+ }
if (!args.Clear && TryComp<AnimatronicPathfindingComponent>(animUid, out var pathfinding))
{
_pathfindingSystem.InitializePathRetryIfNeeded(animUid, pathfinding);
}
UpdateUi(ent.Owner, args.Actor);
}🤖 Prompt for AI Agents
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs around
lines 52 - 70, OnSetTarget currently ignores the boolean result of
_targetSystem.SetTarget; capture its return value, and if it is false log a
warning including animUid and waypoint/args.Clear (and actor if available) so
failures are visible, and only call
_pathfindingSystem.InitializePathRetryIfNeeded and/or proceed with further
actions (like UpdateUi) when SetTarget returned true (or at least document why
UI should still update on failure).
| private void OnSetObserving(Entity<AnimatronicControllerComponent> ent, ref SetAnimatronicObservingEvent args) | ||
| { | ||
| if (args.Actor is not { Valid: true } player) | ||
| return; | ||
|
|
||
| var animUid = GetEntity(args.Animatronic); | ||
| if (!Exists(animUid) || !HasComp<AnimatronicComponent>(animUid)) | ||
| return; | ||
|
|
||
| if (!TryComp<ActorComponent>(player, out var actor)) | ||
| return; | ||
|
|
||
| var ui = new AdminCameraEui(animUid); | ||
| _eui.OpenEui(ui, actor.PlayerSession); | ||
| } |
There was a problem hiding this comment.
Отсутствует проверка авторизации для AdminCameraEui.
Проблема из предыдущего review все еще актуальна: AdminCameraEui открывается без проверки административных прав пользователя. Любой игрок с доступом к контроллеру аниматроников может открыть админ-камеру.
Необходимо добавить зависимость IAdminManager и проверить права перед открытием EUI:
[Dependency] private readonly IAdminManager _admin = default!;И в методе:
// Проверка прав администратора
if (_admin.GetAdminData(actor.PlayerSession) == null)
return;🤖 Prompt for AI Agents
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs around
lines 72 - 86, The OnSetObserving handler opens AdminCameraEui without checking
administrative rights; add an IAdminManager dependency (e.g., [Dependency]
private readonly IAdminManager _admin = default!) to the system and, inside
OnSetObserving before constructing/opening the UI (before new
AdminCameraEui(...) and _eui.OpenEui(...)), call
_admin.GetAdminData(actor.PlayerSession) and return if it is null to prevent
non-admins from opening the admin camera UI.
There was a problem hiding this comment.
В прототипе управления есть запрет на открытие не админу этого юи
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check the animatronic_controller prototype to verify adminOnly setting
cat Resources/Prototypes/Imperial/XxRaay/animatronic_controller.yml
Length of output: 678
@XxRaay, вы абсолютно правы! Я подтвердил, что в прототипе animatronic_controller.yml действительно установлен флаг adminOnly: true в компоненте ActivatableUI:
- type: ActivatableUI
key: enum.AnimatronicControllerUiKey.Key
singleUser: true
inHandsOnly: true
adminOnly: trueЭто означает, что система ActivatableUI на уровне движка не позволит неадминистраторам открыть данный UI, соответственно они не смогут вызвать события OnSetObserving и другие обработчики. Авторизация корректно обеспечивается на уровне прототипа, дополнительная проверка в коде не требуется. Приношу извинения за неточность в анализе!
🧠 Learnings used
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28
Timestamp: 2025-08-04T20:34:48.192Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил неточность в анализе using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs - Content.Shared.Item действительно используется (ItemComponent), в отличие от Robust.Shared.Map и Robust.Server.GameObjects которые не используются.
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 437
File: Content.Server/Imperial/Ninja/NinjaHeadset/NinjaHeadsetSystem.cs:71-73
Timestamp: 2025-09-10T06:08:33.954Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv указал, что в NinjaHeadsetSystem удаление проверки !headsetUid.HasValue после TryGetTargetHeadset вызовет ошибку, несмотря на то что метод возвращает true только когда headsetUid устанавливается в валидное значение. Это говорит о наличии крайних случаев или особенностей InventorySystem, требующих обе проверки.
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 373
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:113-119
Timestamp: 2025-08-06T14:13:47.824Z
Learning: Пользователь CrookLv в проекте imperial-space/SS14-public подтвердил, что металлоискатель в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs обрабатывает разрешения контрабанды корректно в игре, несмотря на кажущуюся проблему с передачей параметров в метод IsContrabandAllowed.
Learnt from: krevetkqqq
Repo: imperial-space/SS14-public PR: 442
File: Content.Server/Imperial/Seriozha/SCP/Systems/SCP035Systems.cs:117-120
Timestamp: 2025-09-13T10:07:03.031Z
Learning: В проекте imperial-space/SS14-public пользователь krevetkqqq указал, что в SCP035System метод TryUnequip должен использовать OR логику (comp.In != null || !comp.TryinUneq) для отмены снятия, а не AND логику. Это означает, что есть два отдельных условия для блокировки снятия маски, не только когда TryinUneq == false.
Learnt from: XxRaay
Repo: imperial-space/SS14-public PR: 374
File: Content.Server/Imperial/XxRaay/FlagSystem/FlagCaptureSystem.cs:222-242
Timestamp: 2025-08-15T08:14:18.983Z
Learning: Пользователь XxRaay в проекте imperial-space/SS14-public подтвердил корректность работы системы захвата флагов в FlagCaptureSystem.cs, несмотря на кажущиеся несоответствия в названиях фракций между прототипами и кодом. Система предотвращает захват игроком своего же флага.
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:132-145
Timestamp: 2025-08-02T17:48:55.569Z
Learning: Пользователь CrookLv в проекте imperial-space/SS14-public объяснил, что в системе MetalDetectorSystem не следует реагировать на все предметы с компонентами MeleeWeaponComponent или RangedWeaponComponent, поскольку это приведет к срабатыванию на безобидные предметы (игрушки, баллоны). Система должна полагаться на ContrabandComponent для определения действительно опасных предметов.
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 362
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:1-28
Timestamp: 2025-08-04T20:34:48.192Z
Learning: В проекте imperial-space/SS14-public пользователь CrookLv исправил анализ using директив в файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs: Content.Shared.Item используется (ItemComponent на строке 70), Robust.Shared.Map используется (IMapManager на строке 44), только Robust.Server.GameObjects действительно не используется и должна быть удалена.
Learnt from: CrookLv
Repo: imperial-space/SS14-public PR: 376
File: Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs:189-197
Timestamp: 2025-08-10T16:44:31.921Z
Learning: В файле Content.Server/Imperial/Crook/Systems/MetalDetectorSystem.cs в методе IsContrabandItem параметр detector необходимо сохранять, даже если он не используется напрямую в теле метода, так как он передаётся в вызовы вложенных методов IsIgnoredByDetector и IsContrabandAllowed. Удаление этого параметра вызывает ошибки компиляции.
Learnt from: XxRaay
Repo: imperial-space/SS14-public PR: 317
File: Content.Server/Imperial/Power/EntitySystems/Events/SupermatterLightningEvent.cs:9-12
Timestamp: 2025-07-31T09:43:48.369Z
Learning: Пользователь XxRaay в проекте imperial-space/SS14-public предпочитает оставлять комментарии к коду на русском языке и не считает необходимым переводить их на английский.
Learnt from: onionsenpai-git
Repo: imperial-space/SS14-public PR: 394
File: Resources/Textures/Imperial/Other/ElysiumPrime/Misc/signs.rsi/meta.json:0-0
Timestamp: 2025-08-22T21:36:29.320Z
Learning: В проекте imperial-space/SS14-public движок корректно работает с горизонтальной упаковкой кадров в RSI спрайтах, даже если ширина PNG превышает size.x в meta.json файле. Пользователь onionsenpai-git подтвердил, что спрайты с размерами 64x32 при size.x=32 в meta.json работают без проблем.
Learnt from: Stevensegege
Repo: imperial-space/SS14-public PR: 354
File: Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml:114-117
Timestamp: 2025-07-27T16:35:42.639Z
Learning: Пользователь Stevensegege в проекте imperial-space/SS14-public подтвердил, что дублирование пути спрайта в компонентах Sprite и Clothing для entity ImperialSCPMask в файле Resources/Prototypes/Imperial/Seriozha/SCP/SCP.yml является преднамеренным дизайнерским решением.
Content.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.cs
Outdated
Show resolved
Hide resolved
| if (!_prototype.TryIndex<DamageGroupPrototype>("Brute", out var bruteGroup)) | ||
| { | ||
| Log.Error($"AnimatronicDamageSystem: Failed to find Brute damage group prototype"); | ||
| return; | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Рассмотрите вынесение типа урона в конфигурацию компонента.
Тип урона "Brute" жестко закодирован в строке 48. Это ограничивает гибкость системы, если в будущем потребуются аниматроники с другими типами урона (например, Burn или Toxin).
Рекомендуется добавить поле DamageType или DamageGroupId в AnimatronicDamageComponent для настройки типа урона через прототипы.
♻️ Предлагаемое улучшение
В AnimatronicDamageComponent добавьте:
[DataField("damageGroup")]
public string DamageGroup = "Brute";Затем используйте:
-if (!_prototype.TryIndex<DamageGroupPrototype>("Brute", out var bruteGroup))
+if (!_prototype.TryIndex<DamageGroupPrototype>(damageComp.DamageGroup, out var damageGroup))
{
- Log.Error($"AnimatronicDamageSystem: Failed to find Brute damage group prototype");
+ Log.Error($"AnimatronicDamageSystem: Failed to find {damageComp.DamageGroup} damage group prototype");
return;
}
-var damage = new DamageSpecifier(bruteGroup, FixedPoint2.New(damageComp.ContactDamage));
+var damage = new DamageSpecifier(damageGroup, FixedPoint2.New(damageComp.ContactDamage));Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs around
lines 48 - 52, The code hardcodes the "Brute" damage group; add a configurable
field to AnimatronicDamageComponent (e.g., public string DamageGroup = "Brute";
annotated with [DataField("damageGroup")]) and change the lookup in
AnimatronicDamageSystem from _prototype.TryIndex<DamageGroupPrototype>("Brute",
out var bruteGroup) to use the component value:
_prototype.TryIndex<DamageGroupPrototype>(component.DamageGroup, out var
bruteGroup), making sure to null-check component and fall back to the default if
needed.
Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs
Outdated
Show resolved
Hide resolved
| if (waypoint == null) | ||
| { | ||
| ClearTarget(animatronic); | ||
| return true; | ||
| } | ||
|
|
||
| if (!Exists(waypoint.Value) || !HasComp<AnimatronicWaypointComponent>(waypoint.Value)) | ||
| return false; | ||
|
|
||
| anim.TargetWaypoint = waypoint.Value; | ||
| Dirty(animatronic, anim); | ||
|
|
||
| EnsureComp<InputMoverComponent>(animatronic); | ||
| EnsureComp<ActiveNPCComponent>(animatronic); | ||
|
|
||
| if (TryComp<TransformComponent>(waypoint.Value, out var targetXform)) | ||
| { | ||
| _steering.Register(animatronic, targetXform.Coordinates); | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } |
There was a problem hiding this comment.
Потенциальная проблема с консистентностью состояния при неудачной регистрации steering.
В строках 40-41 добавляются компоненты InputMoverComponent и ActiveNPCComponent независимо от того, успешно ли пройдет регистрация в steering на строке 45. Если TryComp<TransformComponent> вернет false или регистрация не удастся, метод вернет false, но компоненты останутся добавленными, что может привести к некорректному состоянию.
Рекомендуется проверить возможность регистрации перед добавлением компонентов или удалить компоненты в случае неудачи.
♻️ Предлагаемое исправление
anim.TargetWaypoint = waypoint.Value;
Dirty(animatronic, anim);
+if (!TryComp<TransformComponent>(waypoint.Value, out var targetXform))
+{
+ anim.TargetWaypoint = null;
+ Dirty(animatronic, anim);
+ return false;
+}
+
EnsureComp<InputMoverComponent>(animatronic);
EnsureComp<ActiveNPCComponent>(animatronic);
-if (TryComp<TransformComponent>(waypoint.Value, out var targetXform))
-{
- _steering.Register(animatronic, targetXform.Coordinates);
- return true;
-}
-
-return false;
+_steering.Register(animatronic, targetXform.Coordinates);
+return true;🤖 Prompt for AI Agents
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs around
lines 28 - 50, The method sets anim.TargetWaypoint, calls Dirty(animatronic,
anim), and EnsureComp<InputMoverComponent>/EnsureComp<ActiveNPCComponent> before
attempting to get the waypoint Transform and register with _steering, so if
TryComp<TransformComponent> fails (or registration fails) the mover/active
components remain incorrectly added; modify the logic in AnimatronicTargetSystem
(the block that uses waypoint, EnsureComp<...>, TryComp<TransformComponent>, and
_steering.Register) to first verify the waypoint Transform and perform the
_steering.Register call (or check Register's success) and only then call
EnsureComp<InputMoverComponent> and EnsureComp<ActiveNPCComponent>, or
alternatively roll back/remove those components (via RemComp or ClearTarget) if
registration fails, ensuring state is consistent when the method returns false.
| public void ClearTarget(EntityUid animatronic) | ||
| { | ||
| if (!TryComp<AnimatronicComponent>(animatronic, out var anim)) | ||
| return; | ||
|
|
||
| anim.TargetWaypoint = null; | ||
| Dirty(animatronic, anim); | ||
| _steering.Unregister(animatronic); | ||
|
|
||
| if (TryComp<AnimatronicPathfindingComponent>(animatronic, out var pathfinding)) | ||
| { | ||
| pathfinding.LastPathRetryTime = null; | ||
| pathfinding.LastWaypointUpdateTime = null; | ||
| } | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Безопасность вызова Unregister без проверки текущего состояния.
На строке 59 вызывается _steering.Unregister(animatronic) без проверки, был ли аниматроник зарегистрирован в steering системе. Хотя NPCSteeringSystem.Unregister может безопасно обрабатывать незарегистрированные сущности, рекомендуется явно проверить anim.TargetWaypoint перед вызовом для ясности логики.
♻️ Предлагаемое улучшение
public void ClearTarget(EntityUid animatronic)
{
if (!TryComp<AnimatronicComponent>(animatronic, out var anim))
return;
+ if (anim.TargetWaypoint == null)
+ return;
+
anim.TargetWaypoint = null;
Dirty(animatronic, anim);
_steering.Unregister(animatronic);
if (TryComp<AnimatronicPathfindingComponent>(animatronic, out var pathfinding))
{
pathfinding.LastPathRetryTime = null;
pathfinding.LastWaypointUpdateTime = null;
}
}🤖 Prompt for AI Agents
In @Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs around
lines 52 - 66, ClearTarget currently calls _steering.Unregister(animatronic)
unconditionally; change it to only call Unregister when the animatronic actually
has a target (check anim.TargetWaypoint != null) to make the intent explicit and
avoid unregistering non-registered entities; locate the ClearTarget method and
wrap or gate the _steering.Unregister(animatronic) call with a conditional that
inspects the AnimatronicComponent.TargetWaypoint (or equivalent) before calling
Unregister, leaving the rest of the cleanup (clearing TargetWaypoint,
Dirty(animatronic, anim), and resetting AnimatronicPathfindingComponent timing
fields) intact.
Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs
Outdated
Show resolved
Hide resolved
Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs
Outdated
Show resolved
Hide resolved
Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs
Outdated
Show resolved
Hide resolved
|
Апстримните ветку |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml`:
- Around line 4-5: Удалите неиспользуемые декларации пространств имён
xmlns:controls и xmlns:ac из XAML в файле AnimatronicControllerWindow.xaml:
найдите атрибуты
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls" и
xmlns:ac="clr-namespace:Content.Client.Imperial.XxRaay.UI" в корневом элементе и
удалите их, оставив только используемые xmlns, чтобы убрать лишние объявления и
предупреждения.
In `@Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs`:
- Around line 87-91: The code currently only handles the valid case of
_entityManager.GetEntity(anim.Entity); add an else branch for when entity.Valid
== false to avoid leaving spriteView empty: clear any previous entity via
spriteView.SetEntity(null) or spriteView.ClearEntity, then set a visible
placeholder or error indicator (e.g., spriteView.ShowPlaceholder("Invalid
entity") or spriteView.SetErrorIcon) so the UI shows that the entity is invalid;
update the block around _entityManager.GetEntity, entity.Valid, and
spriteView.SetEntity accordingly.
- Around line 51-294: CreateAnimatronicCard contains duplicated hex color
literals (e.g. "#888888", "#4CAF50", "#FF4444", "#4A90E2") scattered through the
method; refactor by adding static readonly Color fields on the class (e.g.
AnimatronicControllerWindow.IdleColor, ActiveWaypointColor, ClearButtonColor,
ObservingButtonColor, HoverColor) and replace all literal Color.FromHex(...)
usages (including where you assign originalColor, clearButtonOriginalColor,
observingButtonOriginalColor, and entries in _buttonOriginalColors) with those
constants so colors are centralized and easily changed.
- Around line 25-26: Поле _animCards хранит данные, но нигде не читается —
удалите его и связанные операции заполнения: уберите объявление
Dictionary<NetEntity, PanelContainer> _animCards и удалите код в методе
UpdateState, который записывает в _animCards (поиск по имени _animCards и месту
заполнения на строке 47); если планируется использование вместо удаления —
замените запись/заполнение на реальное чтение/использование там, где требуется,
иначе просто удалите поле и соответствующий блок в UpdateState, чтобы убрать
мёртвый код.
| xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls" | ||
| xmlns:ac="clr-namespace:Content.Client.Imperial.XxRaay.UI" |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Неиспользуемые пространства имён controls и ac.
Оба xmlns-объявления (xmlns:controls и xmlns:ac) не используются в XAML. Их можно удалить.
♻️ Предлагаемое исправление
<i:BaseImperialWindow
xmlns="https://spacestation14.io"
xmlns:i="clr-namespace:Content.Client.Imperial.UI.Windows.BaseImperialWindow"
- xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
- xmlns:ac="clr-namespace:Content.Client.Imperial.XxRaay.UI"
HeaderText="{Loc animatronic-controller-window-title}"📝 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.
| xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls" | |
| xmlns:ac="clr-namespace:Content.Client.Imperial.XxRaay.UI" | |
| <i:BaseImperialWindow | |
| xmlns="https://spacestation14.io" | |
| xmlns:i="clr-namespace:Content.Client.Imperial.UI.Windows.BaseImperialWindow" | |
| HeaderText="{Loc animatronic-controller-window-title}" |
🤖 Prompt for AI Agents
In `@Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml` around
lines 4 - 5, Удалите неиспользуемые декларации пространств имён xmlns:controls и
xmlns:ac из XAML в файле AnimatronicControllerWindow.xaml: найдите атрибуты
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls" и
xmlns:ac="clr-namespace:Content.Client.Imperial.XxRaay.UI" в корневом элементе и
удалите их, оставив только используемые xmlns, чтобы убрать лишние объявления и
предупреждения.
Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs
Outdated
Show resolved
Hide resolved
| private PanelContainer CreateAnimatronicCard(AnimDto anim, List<WaypointDto> waypoints) | ||
| { | ||
| var card = new PanelContainer | ||
| { | ||
| StyleClasses = { "AngleRectPass" }, | ||
| HorizontalExpand = true, | ||
| Margin = new Thickness(0, 0, 0, 5) | ||
| }; | ||
|
|
||
| var cardContent = new BoxContainer | ||
| { | ||
| Orientation = BoxContainer.LayoutOrientation.Horizontal, | ||
| Margin = new Thickness(10, 10, 10, 10), | ||
| SeparationOverride = 0, | ||
| HorizontalExpand = true | ||
| }; | ||
|
|
||
| var spritePanel = new PanelContainer | ||
| { | ||
| PanelOverride = new StyleBoxFlat | ||
| { | ||
| BackgroundColor = Color.FromHex("#2A2A2A") | ||
| }, | ||
| VerticalExpand = true | ||
| }; | ||
|
|
||
| var spriteView = new SpriteView | ||
| { | ||
| OverrideDirection = Direction.South, | ||
| Scale = new Vector2(5f, 5f), | ||
| SetSize = new Vector2(96, 96), | ||
| Margin = new Thickness(5, 5, 5, 5), | ||
| VerticalExpand = true, | ||
| VerticalAlignment = VAlignment.Center | ||
| }; | ||
|
|
||
| var entity = _entityManager.GetEntity(anim.Entity); | ||
| if (entity.Valid) | ||
| { | ||
| spriteView.SetEntity(entity); | ||
| } | ||
|
|
||
| spritePanel.AddChild(spriteView); | ||
|
|
||
| var nameStatusPanel = new PanelContainer | ||
| { | ||
| PanelOverride = new StyleBoxFlat | ||
| { | ||
| BackgroundColor = Color.FromHex("#333333") | ||
| }, | ||
| HorizontalExpand = true, | ||
| VerticalExpand = true | ||
| }; | ||
|
|
||
| var nameStatusContent = new BoxContainer | ||
| { | ||
| Orientation = BoxContainer.LayoutOrientation.Horizontal, | ||
| Margin = new Thickness(5, 5, 5, 5), | ||
| SeparationOverride = 10, | ||
| HorizontalExpand = true | ||
| }; | ||
|
|
||
| var nameStatusContainer = new BoxContainer | ||
| { | ||
| Orientation = BoxContainer.LayoutOrientation.Vertical, | ||
| VerticalExpand = true, | ||
| VerticalAlignment = VAlignment.Center | ||
| }; | ||
|
|
||
| var nameLabel = new Label | ||
| { | ||
| Text = anim.DisplayName, | ||
| StyleClasses = { "LabelSubTextPassExtraBoldServerName" }, | ||
| ModulateSelfOverride = Color.White | ||
| }; | ||
|
|
||
| var statusContainer = new BoxContainer | ||
| { | ||
| Orientation = BoxContainer.LayoutOrientation.Horizontal, | ||
| SeparationOverride = 3 | ||
| }; | ||
|
|
||
| if (anim.CurrentWaypointId != null) | ||
| { | ||
| var dotsLabel = new Label | ||
| { | ||
| Text = Loc.GetString("animatronic-controller-waypoint-separator"), | ||
| StyleClasses = { "LabelSubTextPassMediumBuy" }, | ||
| ModulateSelfOverride = Color.FromHex("#FFD700"), | ||
| VerticalAlignment = VAlignment.Center, | ||
| Margin = new Thickness(0, 0, 3, 0) | ||
| }; | ||
|
|
||
| var waypointLabel = new Label | ||
| { | ||
| Text = anim.CurrentWaypointId, | ||
| StyleClasses = { "LabelSubTextPassMediumBuy" }, | ||
| ModulateSelfOverride = Color.FromHex("#FFD700"), | ||
| VerticalAlignment = VAlignment.Center | ||
| }; | ||
|
|
||
| statusContainer.AddChild(dotsLabel); | ||
| statusContainer.AddChild(waypointLabel); | ||
| } | ||
| else | ||
| { | ||
| var statusLabel = new Label | ||
| { | ||
| Text = Loc.GetString("animatronic-controller-status-idle"), | ||
| StyleClasses = { "LabelSubTextPassMediumBuy" }, | ||
| ModulateSelfOverride = Color.FromHex("#888888") | ||
| }; | ||
| statusContainer.AddChild(statusLabel); | ||
| } | ||
|
|
||
| nameStatusContainer.AddChild(nameLabel); | ||
| nameStatusContainer.AddChild(statusContainer); | ||
|
|
||
| var waypointButtonsContent = new BoxContainer | ||
| { | ||
| Orientation = BoxContainer.LayoutOrientation.Horizontal, | ||
| SeparationOverride = 5, | ||
| HorizontalExpand = true | ||
| }; | ||
|
|
||
| var waypointGrid = new GridContainer | ||
| { | ||
| Columns = 2, | ||
| HorizontalExpand = true | ||
| }; | ||
|
|
||
| foreach (var wp in waypoints) | ||
| { | ||
| var isActive = anim.CurrentWaypointId == wp.WaypointId; | ||
| var wpButton = new Button | ||
| { | ||
| Text = wp.WaypointId, | ||
| HorizontalExpand = true | ||
| }; | ||
|
|
||
| var originalColor = isActive ? Color.FromHex("#4CAF50") : Color.FromHex("#888888"); | ||
| _buttonOriginalColors[wp.Entity] = originalColor; | ||
| wpButton.ModulateSelfOverride = originalColor; | ||
|
|
||
| wpButton.StyleClasses.Add("ButtonOpenBoth"); | ||
|
|
||
| var animEntity = anim.Entity; | ||
| var wpEntity = wp.Entity; | ||
|
|
||
| wpButton.OnPressed += _ => | ||
| { | ||
| OnAnimatronicWaypointSelected?.Invoke(animEntity, wpEntity); | ||
| }; | ||
|
|
||
| wpButton.OnMouseEntered += _ => | ||
| { | ||
| if (!isActive) | ||
| wpButton.ModulateSelfOverride = Color.FromHex("#AAAAAA"); | ||
| }; | ||
|
|
||
| wpButton.OnMouseExited += _ => | ||
| { | ||
| if (!isActive && _buttonOriginalColors.TryGetValue(wpEntity, out var original)) | ||
| wpButton.ModulateSelfOverride = original; | ||
| }; | ||
|
|
||
| waypointGrid.AddChild(wpButton); | ||
| } | ||
|
|
||
| var buttonsContainer = new BoxContainer | ||
| { | ||
| Orientation = BoxContainer.LayoutOrientation.Vertical, | ||
| SeparationOverride = 5, | ||
| VerticalExpand = true | ||
| }; | ||
|
|
||
| var clearButton = new Button | ||
| { | ||
| Text = Loc.GetString("animatronic-controller-button-clear"), | ||
| StyleClasses = { "ButtonOpenBoth" }, | ||
| ModulateSelfOverride = Color.FromHex("#FF4444"), | ||
| VerticalExpand = true, | ||
| HorizontalExpand = true | ||
| }; | ||
|
|
||
| var clearButtonOriginalColor = Color.FromHex("#FF4444"); | ||
| var animEntityForClear = anim.Entity; | ||
| clearButton.OnPressed += _ => | ||
| { | ||
| OnAnimatronicClearTarget?.Invoke(animEntityForClear); | ||
| }; | ||
|
|
||
| clearButton.OnMouseEntered += _ => | ||
| { | ||
| clearButton.ModulateSelfOverride = Color.FromHex("#FF6666"); | ||
| }; | ||
|
|
||
| clearButton.OnMouseExited += _ => | ||
| { | ||
| clearButton.ModulateSelfOverride = clearButtonOriginalColor; | ||
| }; | ||
|
|
||
| var observingButton = new Button | ||
| { | ||
| Text = Loc.GetString("animatronic-controller-button-observing"), | ||
| StyleClasses = { "ButtonOpenBoth" }, | ||
| ModulateSelfOverride = Color.FromHex("#4A90E2"), | ||
| VerticalExpand = true, | ||
| HorizontalExpand = true | ||
| }; | ||
|
|
||
| var observingButtonOriginalColor = Color.FromHex("#4A90E2"); | ||
| var animEntityForObserving = anim.Entity; | ||
| observingButton.OnPressed += _ => | ||
| { | ||
| OnAnimatronicObserving?.Invoke(animEntityForObserving); | ||
| }; | ||
|
|
||
| observingButton.OnMouseEntered += _ => | ||
| { | ||
| observingButton.ModulateSelfOverride = Color.FromHex("#6BA3E8"); | ||
| }; | ||
|
|
||
| observingButton.OnMouseExited += _ => | ||
| { | ||
| observingButton.ModulateSelfOverride = observingButtonOriginalColor; | ||
| }; | ||
|
|
||
| buttonsContainer.AddChild(clearButton); | ||
| buttonsContainer.AddChild(observingButton); | ||
|
|
||
| waypointButtonsContent.AddChild(waypointGrid); | ||
| waypointButtonsContent.AddChild(buttonsContainer); | ||
|
|
||
| nameStatusContent.AddChild(nameStatusContainer); | ||
| nameStatusContent.AddChild(waypointButtonsContent); | ||
| nameStatusPanel.AddChild(nameStatusContent); | ||
|
|
||
| cardContent.AddChild(spritePanel); | ||
| cardContent.AddChild(nameStatusPanel); | ||
| card.AddChild(cardContent); | ||
|
|
||
| return card; | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Дублирование hex-констант цветов.
Одни и те же цветовые коды ("#888888", "#4CAF50", "#FF4444", "#4A90E2" и др.) разбросаны по методу. Рекомендуется вынести их в static readonly Color поля класса для единообразия и простоты изменения.
♻️ Пример
+ private static readonly Color ColorInactive = Color.FromHex("#888888");
+ private static readonly Color ColorActive = Color.FromHex("#4CAF50");
+ private static readonly Color ColorClear = Color.FromHex("#FF4444");
+ private static readonly Color ColorClearHover = Color.FromHex("#FF6666");
+ private static readonly Color ColorObserving = Color.FromHex("#4A90E2");
+ private static readonly Color ColorObservingHover = Color.FromHex("#6BA3E8");
+ private static readonly Color ColorHover = Color.FromHex("#AAAAAA");
+ private static readonly Color ColorGold = Color.FromHex("#FFD700");🤖 Prompt for AI Agents
In `@Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs` around
lines 51 - 294, CreateAnimatronicCard contains duplicated hex color literals
(e.g. "#888888", "#4CAF50", "#FF4444", "#4A90E2") scattered through the method;
refactor by adding static readonly Color fields on the class (e.g.
AnimatronicControllerWindow.IdleColor, ActiveWaypointColor, ClearButtonColor,
ObservingButtonColor, HoverColor) and replace all literal Color.FromHex(...)
usages (including where you assign originalColor, clearButtonOriginalColor,
observingButtonOriginalColor, and entries in _buttonOriginalColors) with those
constants so colors are centralized and easily changed.
| var entity = _entityManager.GetEntity(anim.Entity); | ||
| if (entity.Valid) | ||
| { | ||
| spriteView.SetEntity(entity); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Нет обработки случая невалидной entity.
Если entity.Valid == false, spriteView останется пустым без визуальной индикации. Стоит рассмотреть отображение placeholder-текста или иконки ошибки для отладки.
🤖 Prompt for AI Agents
In `@Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs` around
lines 87 - 91, The code currently only handles the valid case of
_entityManager.GetEntity(anim.Entity); add an else branch for when entity.Valid
== false to avoid leaving spriteView empty: clear any previous entity via
spriteView.SetEntity(null) or spriteView.ClearEntity, then set a visible
placeholder or error indicator (e.g., spriteView.ShowPlaceholder("Invalid
entity") or spriteView.SetErrorIcon) so the UI shows that the entity is invalid;
update the block around _entityManager.GetEntity, entity.Valid, and
spriteView.SetEntity accordingly.
…tor-files Refactor animatronic controller UI and server systems for robustness
There was a problem hiding this comment.
♻️ Duplicate comments (5)
Content.Server/Imperial/XxRaay/Systems/AnimatronicPathfindingSystem.cs (1)
21-24: 🧹 Nitpick | 🔵 TrivialПустой метод
Initializeможно удалить.Метод содержит только вызов
base.Initialize(). В SS14 это необязательно, если нет дополнительной логики инициализации.🔎 Предлагаемое исправление
-public override void Initialize() -{ - base.Initialize(); -} - public override void Update(float frameTime)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Server/Imperial/XxRaay/Systems/AnimatronicPathfindingSystem.cs` around lines 21 - 24, Remove the redundant empty override of Initialize in the AnimatronicPathfindingSystem class: delete the Initialize method that only calls base.Initialize() so the class inherits the base implementation directly (remove the method named Initialize in AnimatronicPathfindingSystem).Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs (2)
81-85: 🧹 Nitpick | 🔵 TrivialНет визуальной индикации для невалидных entity.
Если
entity.Valid == false,spriteViewостанется пустым без визуальной индикации ошибки. Рассмотрите отображение placeholder-текста или иконки для отладки.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs` around lines 81 - 85, При обработке результата _entityManager.GetEntity(anim.Entity) добавьте визуальную индикацию для случая entity.Valid == false: вместо оставления spriteView пустым, вызвать методы представления для отображения плейсхолдера/иконки/текста ошибки (например использовать spriteView.ShowPlaceholder/SetPlaceholder или spriteView.Clear() затем spriteView.SetEmptyState) чтобы явно сообщить о невалидной сущности; внесите изменения в блок, где сейчас вызывается spriteView.SetEntity(entity), чтобы в ветке else вызывать выбранный метод плейсхолдера и при необходимости логировать anim.Entity или короткое сообщение об ошибке для отладки.
45-288: 🧹 Nitpick | 🔵 TrivialРассмотрите вынесение hex-констант цветов в статические поля.
Цветовые коды (
"#888888","#4CAF50","#FF4444","#4A90E2"и др.) дублируются в методе. Вынесение вstatic readonly Colorполя улучшит поддерживаемость.♻️ Пример
+private static readonly Color ColorInactive = Color.FromHex("#888888"); +private static readonly Color ColorActive = Color.FromHex("#4CAF50"); +private static readonly Color ColorClear = Color.FromHex("#FF4444"); +private static readonly Color ColorObserving = Color.FromHex("#4A90E2"); +private static readonly Color ColorHover = Color.FromHex("#AAAAAA"); +private static readonly Color ColorGold = Color.FromHex("#FFD700");🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs` around lines 45 - 288, The method CreateAnimatronicCard contains repeated inline Color.FromHex(...) literals (e.g. "#888888", "#4CAF50", "#FF4444", "#4A90E2", "#FFD700", "#AAAAAA") — extract these hex values into descriptive static readonly Color fields (e.g. IdleColor, ActiveWaypointColor, ClearButtonColor, ObservingButtonColor, WaypointHighlightColor, HoverGrayColor) on the class and replace all direct Color.FromHex calls and local originalColor/clearButtonOriginalColor/observingButtonOriginalColor assignments with those shared fields; ensure _buttonOriginalColors stores the static color references and that all event handlers (OnMouseEntered/OnMouseExited/OnPressed) use the new static fields so colors are not duplicated.Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs (1)
36-48:⚠️ Potential issue | 🟡 MinorПотенциальная проблема консистентности состояния.
Компоненты
InputMoverComponentиActiveNPCComponentдобавляются (строки 39-40) до проверки возможности регистрации в steering (строка 42). ЕслиTryComp<TransformComponent>вернёт false, метод вернёт false, но компоненты останутся добавленными.♻️ Предлагаемое исправление
anim.TargetWaypoint = waypoint.Value; Dirty(animatronic, anim); +if (!TryComp<TransformComponent>(waypoint.Value, out var targetXform)) +{ + anim.TargetWaypoint = null; + Dirty(animatronic, anim); + return false; +} + EnsureComp<InputMoverComponent>(animatronic); EnsureComp<ActiveNPCComponent>(animatronic); -if (TryComp<TransformComponent>(waypoint.Value, out var targetXform)) -{ - _steering.Register(animatronic, targetXform.Coordinates); - return true; -} - -return false; +_steering.Register(animatronic, targetXform.Coordinates); +return true;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs` around lines 36 - 48, Компоненты добавляются до проверки наличия Transform, что оставляет систему в неконсистентном состоянии при неудаче; change the flow in SetTarget (the block using anim.TargetWaypoint, Dirty(animatronic, anim), EnsureComp<InputMoverComponent>, EnsureComp<ActiveNPCComponent>, TryComp<TransformComponent>, and _steering.Register) so that you only call EnsureComp<InputMoverComponent> and EnsureComp<ActiveNPCComponent> after TryComp<TransformComponent> returns true and after _steering.Register succeeds (or else revert/undo the changes), or alternatively perform the TryComp/registration first and only then set anim.TargetWaypoint and call Dirty; pick one approach and adjust the order to guarantee components are not left added when _steering.Register fails.Content.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs (1)
62-66:⚠️ Potential issue | 🟡 MinorПотенциальная утечка памяти при удалении сущностей.
Если сущность удаляется без вызова
EndCollideEvent(например, при телепортации или удалении), запись вLastContactDamageостанется навсегда. Рекомендуется подписаться наEntityTerminatingEventдля очистки словаря.🔎 Предлагаемое исправление
public override void Initialize() { base.Initialize(); SubscribeLocalEvent<AnimatronicDamageComponent, StartCollideEvent>(OnAnimatronicCollide); SubscribeLocalEvent<AnimatronicDamageComponent, EndCollideEvent>(OnAnimatronicCollideEnd); + SubscribeLocalEvent<AnimatronicDamageComponent, EntityTerminatingEvent>(OnAnimatronicTerminating); } +private void OnAnimatronicTerminating(Entity<AnimatronicDamageComponent> ent, ref EntityTerminatingEvent args) +{ + ent.Comp.LastContactDamage.Clear(); +}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs` around lines 62 - 66, The OnAnimatronicCollideEnd handler currently removes OtherEntity from a single AnimatronicDamageComponent.LastContactDamage but won’t catch cases where the collided entity is deleted without EndCollideEvent; subscribe to EntityTerminatingEvent and implement a handler (e.g. OnEntityTerminating or OnAnimatronicEntityTerminating) that, when an entity is terminating, iterates relevant AnimatronicDamageComponent instances and calls LastContactDamage.Remove(terminatingEntityUid) (and if the terminating entity is the component owner, clear LastContactDamage altogether) so stale keys are removed and memory isn’t leaked.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.cs`:
- Around line 81-85: При обработке результата
_entityManager.GetEntity(anim.Entity) добавьте визуальную индикацию для случая
entity.Valid == false: вместо оставления spriteView пустым, вызвать методы
представления для отображения плейсхолдера/иконки/текста ошибки (например
использовать spriteView.ShowPlaceholder/SetPlaceholder или spriteView.Clear()
затем spriteView.SetEmptyState) чтобы явно сообщить о невалидной сущности;
внесите изменения в блок, где сейчас вызывается spriteView.SetEntity(entity),
чтобы в ветке else вызывать выбранный метод плейсхолдера и при необходимости
логировать anim.Entity или короткое сообщение об ошибке для отладки.
- Around line 45-288: The method CreateAnimatronicCard contains repeated inline
Color.FromHex(...) literals (e.g. "#888888", "#4CAF50", "#FF4444", "#4A90E2",
"#FFD700", "#AAAAAA") — extract these hex values into descriptive static
readonly Color fields (e.g. IdleColor, ActiveWaypointColor, ClearButtonColor,
ObservingButtonColor, WaypointHighlightColor, HoverGrayColor) on the class and
replace all direct Color.FromHex calls and local
originalColor/clearButtonOriginalColor/observingButtonOriginalColor assignments
with those shared fields; ensure _buttonOriginalColors stores the static color
references and that all event handlers (OnMouseEntered/OnMouseExited/OnPressed)
use the new static fields so colors are not duplicated.
In `@Content.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.cs`:
- Around line 62-66: The OnAnimatronicCollideEnd handler currently removes
OtherEntity from a single AnimatronicDamageComponent.LastContactDamage but won’t
catch cases where the collided entity is deleted without EndCollideEvent;
subscribe to EntityTerminatingEvent and implement a handler (e.g.
OnEntityTerminating or OnAnimatronicEntityTerminating) that, when an entity is
terminating, iterates relevant AnimatronicDamageComponent instances and calls
LastContactDamage.Remove(terminatingEntityUid) (and if the terminating entity is
the component owner, clear LastContactDamage altogether) so stale keys are
removed and memory isn’t leaked.
In `@Content.Server/Imperial/XxRaay/Systems/AnimatronicPathfindingSystem.cs`:
- Around line 21-24: Remove the redundant empty override of Initialize in the
AnimatronicPathfindingSystem class: delete the Initialize method that only calls
base.Initialize() so the class inherits the base implementation directly (remove
the method named Initialize in AnimatronicPathfindingSystem).
In `@Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs`:
- Around line 36-48: Компоненты добавляются до проверки наличия Transform, что
оставляет систему в неконсистентном состоянии при неудаче; change the flow in
SetTarget (the block using anim.TargetWaypoint, Dirty(animatronic, anim),
EnsureComp<InputMoverComponent>, EnsureComp<ActiveNPCComponent>,
TryComp<TransformComponent>, and _steering.Register) so that you only call
EnsureComp<InputMoverComponent> and EnsureComp<ActiveNPCComponent> after
TryComp<TransformComponent> returns true and after _steering.Register succeeds
(or else revert/undo the changes), or alternatively perform the
TryComp/registration first and only then set anim.TargetWaypoint and call Dirty;
pick one approach and adjust the order to guarantee components are not left
added when _steering.Register fails.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: e4ed3dd3-c4dd-4df3-a5c9-98a9352f5265
📒 Files selected for processing (6)
Content.Client/Imperial/XxRaay/UI/AnimatronicControllerWindow.xaml.csContent.Server/Imperial/XxRaay/Systems/AnimatronicControllerSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicDamageSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicPathfindingSystem.csContent.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.csContent.Shared/Imperial/XxRaay/Components/AnimatronicNet.cs



О ПР`е
Тип: feat
Изменения: Ивентовый контент
Технические детали
Нет
Изменения кода официальных разработчиков
Нет
Summary by CodeRabbit
Новые функции
Документация