Skip to content

Децентрализация механик Scp173#984

Draft
WardexOfficial wants to merge 6 commits into
space-sunrise:masterfrom
WardexOfficial:decent-scp-173
Draft

Децентрализация механик Scp173#984
WardexOfficial wants to merge 6 commits into
space-sunrise:masterfrom
WardexOfficial:decent-scp-173

Conversation

@WardexOfficial

@WardexOfficial WardexOfficial commented Apr 28, 2026

Copy link
Copy Markdown
Collaborator

Краткое описание | Short description

Разбитие механик Scp173 на раздельные системы.

TODO

  • Создание отдельной системы невозможности движения при взгляде
  • Создание отдельной системы для действия "Скачок"
  • Создание отдельной системы для действия "Оскрвенить"
  • Создание отдельной системы для действия "Засорить тайл"
  • Создание отдельной системы мгновенного убийства при соприкосновении

Summary by CodeRabbit

Изменения

  • Refactor
    • Переработана система контроля движения и атак SCP-173 при наблюдении. Внедрён новый компонент для более гибкого управления поведением сущности. Функциональность остаётся неизменной.

Added ScpRestrictMovementOnVisibility component to SCP-173.
Removed unused movement event subscriptions and related methods for Scp173Component.
@coderabbitai

coderabbitai Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 423bf2d9-08fc-408b-9ec7-c5a889f2e4cc

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Обзор

Рефакторинг перемещает логику ограничения движения SCP-173 из специфичной системы в новую универсальную систему ScpRestrictMovementOnVisibility. Удалены обработчики событий из SharedScp173System, добавлены новый компонент и система для контроля движения на основе видимости, обновлена конфигурация прототипа SCP-173.

Изменения

Когорта / Файл(ы) Резюме
Удаление из системы SCP-173
Content.Shared/_Scp/Scp173/SharedScp173System.cs
Удалены подписки на события движения/атаки (AttackAttemptEvent, ChangeDirectionAttemptEvent, UpdateCanMoveEvent, MoveInputEvent, MoveEvent) и связанные обработчики, которые отменяли движение/атаку при наблюдении и обновляли доступность движения.
Новая система ограничения движения при видимости
Content.Shared/_Scp/Other/ScpRestrictMovementOnVisibility/ScpRestrictMovementOnVisibilityComponent.cs, Content.Shared/_Scp/Other/ScpRestrictMovementOnVisibility/SharedRestrictMovementOnVisibilitySystem.cs
Добавлены сетевой компонент с полями белых/чёрных списков контейнеров и новая система SharedRestrictMovementOnVisibilitySystem, которая обрабатывает события движения/атаки, проверяет видимость и отменяет действия при необходимости.
Обновление прототипа
Resources/Prototypes/_Scp/Entities/Mobs/Player/Scp/Main/scp173.yml
Добавлен компонент ScpRestrictMovementOnVisibility с конфигурацией белого списка контейнеров для SCP-173, удалён BOM-символ.

Оцениваемые затраты на код-ревью

🎯 3 (Moderate) | ⏱️ ~20 минут

Стихотворение

🐰 Когда в системе рефакторинг поет,
Движенье SCP везде найдет!
От873 к новой системе скачок,
Видимость следит — и враг бежит в ночок,
Компоненты танцуют в едине судьбе! ✨


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning, 3 inconclusive)

Check name Status Explanation Resolution
Ss14 C# Rules ❌ Error Имя файла SharedRestrictMovementOnVisibilitySystem.cs не совпадает с именем класса SharedScpRestrictMovementOnVisibilitySystem, что нарушает SS14 C# соглашения о наименовании. Переименуйте файл в SharedScpRestrictMovementOnVisibilitySystem.cs в соответствии с именем главного класса.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Ss14 Yaml/Ftl Rules ❓ Inconclusive Проверка не может быть завершена полностью из-за технической невозможности доступа к репозиторию и отсутствия полной информации о синтаксисе YAML в резюме PR. Требуется локальная проверка файла scp173.yml на правильность синтаксиса компонентов, отсутствие Cyrillic текста в fallback значениях и соответствие upstream-дружественным паттернам.
Ss14 Prototype ↔ Ftl Parity ❓ Inconclusive PR модифицирует scp173.yml, требуя проверки парности SS14 Prototype ↔ FTL, но невозможно получить доступ к содержимому файла для проверки изменений полей, видимых игроку. Требуется прямой доступ к содержимому scp173.yml для проверки: были ли изменены поля name/description/suffix и добавлены ли соответствующие записи FTL.
Ss14 Prediction Safety ❓ Inconclusive Unable to access repository code to verify SS14 Prediction Safety requirements for SharedRestrictMovementOnVisibilitySystem implementation. Examine complete implementation of SharedRestrictMovementOnVisibilitySystem.cs and ScpRestrictMovementOnVisibilityComponent.cs to verify no IRobustRandom use, no predicted side effects, and deterministic prediction safety.
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Название PR точно соответствует основному изменению: рефакторинг механик SCP-173 путем извлечения логики ограничения движения в отдельную систему, что является первой частью децентрализации.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Ss14 Bridge Sync ✅ Passed PR changes are game code files only (.agent directories, canonical rules/skills files, and bridge files in .agents/.claude/.cursor/.github do not exist or are not modified)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@Content.Shared/_Scp/Other/ScpRestrictMovementOnVisibility/ScpRestrictMovementOnVisibilityComponent`:
- Around line 9-12: Поле ContainersMoveBlacklist не помечено как сериализуемое и
потому остаётся null при десериализации; добавьте атрибут [DataField] над
объявлением ContainersMoveBlacklist, точно так же как у ContainersMoveWhitelist,
чтобы YAML/префабные чёрные списки правильно загружались; проверьте в методе
SharedScpRestrictMovementOnVisibilitySystem.IsInContainer() / CheckBoth() что
тип и nullability поля совпадают с ContainersMoveWhitelist.

In
`@Content.Shared/_Scp/Other/ScpRestrictMovementOnVisibility/SharedScpRestrictMovementOnVisibilitySystem`:
- Around line 19-31: Initialize the private field _insideQuery in Initialize()
by assigning it the result of GetEntityQuery<InsideEntityStorageComponent>() so
IsInContainer() isn't using a null/uninitialized query; update the Initialize
method (where SubscribeLocalEvent calls are) to set _insideQuery =
GetEntityQuery<InsideEntityStorageComponent>() before any code paths that may
call IsInContainer().
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4873f7ef-233e-459c-a1c7-f0cef1b1c488

📥 Commits

Reviewing files that changed from the base of the PR and between 43e6167 and fc68d49.

📒 Files selected for processing (4)
  • Content.Shared/_Scp/Other/ScpRestrictMovementOnVisibility/ScpRestrictMovementOnVisibilityComponent
  • Content.Shared/_Scp/Other/ScpRestrictMovementOnVisibility/SharedScpRestrictMovementOnVisibilitySystem
  • Content.Shared/_Scp/Scp173/SharedScp173System.cs
  • Resources/Prototypes/_Scp/Entities/Mobs/Player/Scp/Main/scp173.yml

@WardexOfficial

Copy link
Copy Markdown
Collaborator Author

@ThereDrD0 этот тоже закинуть бы в Драфт

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@Content.Shared/_Scp/Other/ScpRestrictMovementOnVisibility/SharedRestrictMovementOnVisibilitySystem.cs`:
- Line 12: The file name does not match the public class name; rename the file
containing the class SharedScpRestrictMovementOnVisibilitySystem to
SharedScpRestrictMovementOnVisibilitySystem.cs so the C# file name matches the
public class name and follows project conventions.
- Around line 35-88: Change the event handler methods from public to private:
OnAttackAttempt, OnDirectionAttempt, OnMoveAttempt, OnMoveInput, and OnMove in
SharedRestrictMovementOnVisibilitySystem; these handlers are only subscribed via
SubscribeLocalEvent and not part of the public API, so update their access
modifiers to private (ensure no external code relies on them being public).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e9a8413d-d764-48ed-939d-98f9c77d30df

📥 Commits

Reviewing files that changed from the base of the PR and between fc68d49 and 086e98d.

📒 Files selected for processing (2)
  • Content.Shared/_Scp/Other/ScpRestrictMovementOnVisibility/ScpRestrictMovementOnVisibilityComponent.cs
  • Content.Shared/_Scp/Other/ScpRestrictMovementOnVisibility/SharedRestrictMovementOnVisibilitySystem.cs


namespace Content.Shared._Scp.Other.ScpRestrictMovementOnVisibility;

public sealed class SharedScpRestrictMovementOnVisibilitySystem : EntitySystem

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Имя файла не соответствует имени класса.

Файл называется SharedRestrictMovementOnVisibilitySystem.cs, а класс — SharedScpRestrictMovementOnVisibilitySystem. По конвенциям C# имя файла должно совпадать с именем класса.

🔧 Предлагаемое исправление

Переименуйте файл в SharedScpRestrictMovementOnVisibilitySystem.cs.

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

In
`@Content.Shared/_Scp/Other/ScpRestrictMovementOnVisibility/SharedRestrictMovementOnVisibilitySystem.cs`
at line 12, The file name does not match the public class name; rename the file
containing the class SharedScpRestrictMovementOnVisibilitySystem to
SharedScpRestrictMovementOnVisibilitySystem.cs so the C# file name matches the
public class name and follows project conventions.

Comment on lines +35 to +88
public void OnAttackAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref AttackAttemptEvent args)
{
if (IsInContainer(ent, out _))
{
args.Cancel();
return;
}

if (_watching.IsWatchedByAny(ent, useTimeCompensation: true))
{
args.Cancel();
return;
}
}

public void OnDirectionAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref ChangeDirectionAttemptEvent args)
{
// В контейнере можно двигаться
if (IsInContainer(ent, out _))
return;

if (!_watching.IsWatchedByAny(ent, useTimeCompensation: true))
return;

args.Cancel();
}

public void OnMoveAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref UpdateCanMoveEvent args)
{
// В контейнере можно двигаться
if (IsInContainer(ent, out _))
return;

if (!_watching.IsWatchedByAny(ent, useTimeCompensation: true))
return;

args.Cancel();
}

public void OnMoveInput(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref MoveInputEvent args)
{
// Метод подвязанный на MoveInputEvent так же нужен, вместе с методом на MoveEvent
// Этот метод исправляет проблему, когда сущность должен мочь двинуться, но ему об этом никто не сказал
// То есть последний вопрос от сущности МОГУ ЛИ Я ДВИНУТЬСЯ был когда он еще мог двинуться, через MoveEvent
// Потом он перестал мочь, и следственно больше НЕ МОЖЕТ задать вопрос, может они двинуться
// Это фикслось в игре сменой направления спрайта мышкой
// Но данный метод как раз будет спрашивать у сущности, может ли он сдвинуться, когда как раз не двигается
_blocker.UpdateCanMove(ent);
}

public void OnMove(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref MoveEvent args)
{
_blocker.UpdateCanMove(ent);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Обработчики событий должны быть private.

Методы OnAttackAttempt, OnDirectionAttempt, OnMoveAttempt, OnMoveInput, OnMove используются только для подписки через SubscribeLocalEvent и не являются частью публичного API системы.

♻️ Предлагаемое исправление
-    public void OnAttackAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref AttackAttemptEvent args)
+    private void OnAttackAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref AttackAttemptEvent args)
-    public void OnDirectionAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref ChangeDirectionAttemptEvent args)
+    private void OnDirectionAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref ChangeDirectionAttemptEvent args)
-    public void OnMoveAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref UpdateCanMoveEvent args)
+    private void OnMoveAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref UpdateCanMoveEvent args)
-    public void OnMoveInput(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref MoveInputEvent args)
+    private void OnMoveInput(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref MoveInputEvent args)
-    public void OnMove(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref MoveEvent args)
+    private void OnMove(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref MoveEvent args)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void OnAttackAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref AttackAttemptEvent args)
{
if (IsInContainer(ent, out _))
{
args.Cancel();
return;
}
if (_watching.IsWatchedByAny(ent, useTimeCompensation: true))
{
args.Cancel();
return;
}
}
public void OnDirectionAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref ChangeDirectionAttemptEvent args)
{
// В контейнере можно двигаться
if (IsInContainer(ent, out _))
return;
if (!_watching.IsWatchedByAny(ent, useTimeCompensation: true))
return;
args.Cancel();
}
public void OnMoveAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref UpdateCanMoveEvent args)
{
// В контейнере можно двигаться
if (IsInContainer(ent, out _))
return;
if (!_watching.IsWatchedByAny(ent, useTimeCompensation: true))
return;
args.Cancel();
}
public void OnMoveInput(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref MoveInputEvent args)
{
// Метод подвязанный на MoveInputEvent так же нужен, вместе с методом на MoveEvent
// Этот метод исправляет проблему, когда сущность должен мочь двинуться, но ему об этом никто не сказал
// То есть последний вопрос от сущности МОГУ ЛИ Я ДВИНУТЬСЯ был когда он еще мог двинуться, через MoveEvent
// Потом он перестал мочь, и следственно больше НЕ МОЖЕТ задать вопрос, может они двинуться
// Это фикслось в игре сменой направления спрайта мышкой
// Но данный метод как раз будет спрашивать у сущности, может ли он сдвинуться, когда как раз не двигается
_blocker.UpdateCanMove(ent);
}
public void OnMove(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref MoveEvent args)
{
_blocker.UpdateCanMove(ent);
}
private void OnAttackAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref AttackAttemptEvent args)
{
if (IsInContainer(ent, out _))
{
args.Cancel();
return;
}
if (_watching.IsWatchedByAny(ent, useTimeCompensation: true))
{
args.Cancel();
return;
}
}
private void OnDirectionAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref ChangeDirectionAttemptEvent args)
{
// В контейнере можно двигаться
if (IsInContainer(ent, out _))
return;
if (!_watching.IsWatchedByAny(ent, useTimeCompensation: true))
return;
args.Cancel();
}
private void OnMoveAttempt(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref UpdateCanMoveEvent args)
{
// В контейнере можно двигаться
if (IsInContainer(ent, out _))
return;
if (!_watching.IsWatchedByAny(ent, useTimeCompensation: true))
return;
args.Cancel();
}
private void OnMoveInput(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref MoveInputEvent args)
{
// Метод подвязанный на MoveInputEvent так же нужен, вместе с методом на MoveEvent
// Этот метод исправляет проблему, когда сущность должен мочь двинуться, но ему об этом никто не сказал
// То есть последний вопрос от сущности МОГУ ЛИ Я ДВИНУТЬСЯ был когда он еще мог двинуться, через MoveEvent
// Потом он перестал мочь, и следственно больше НЕ МОЖЕТ задать вопрос, может они двинуться
// Это фикслось в игре сменой направления спрайта мышкой
// Но данный метод как раз будет спрашивать у сущности, может ли он сдвинуться, когда как раз не двигается
_blocker.UpdateCanMove(ent);
}
private void OnMove(Entity<ScpRestrictMovementOnVisibilityComponent> ent, ref MoveEvent args)
{
_blocker.UpdateCanMove(ent);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Content.Shared/_Scp/Other/ScpRestrictMovementOnVisibility/SharedRestrictMovementOnVisibilitySystem.cs`
around lines 35 - 88, Change the event handler methods from public to private:
OnAttackAttempt, OnDirectionAttempt, OnMoveAttempt, OnMoveInput, and OnMove in
SharedRestrictMovementOnVisibilitySystem; these handlers are only subscribed via
SubscribeLocalEvent and not part of the public API, so update their access
modifiers to private (ensure no external code relies on them being public).

@ThereDrD0

Copy link
Copy Markdown
Collaborator

Ты сам можешь закидывать и возвращать, кнопка есть

@WardexOfficial WardexOfficial marked this pull request as draft April 28, 2026 10:58
@WardexOfficial

Copy link
Copy Markdown
Collaborator Author

Заметка для меня: https://discord.com/channels/1051873590301184031/1498716212396429382/1498716212396429382

#НЕЗАБЫТЬ

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants