Добавление нового объекта 933. Его механики#954
Добавление нового объекта 933. Его механики#954helper342 wants to merge 47 commits intospace-sunrise:masterfrom
Conversation
Refactor code structure for improved readability and maintainability
…ocalization; remove unused server-side code and enhance face erasure logic for victims.
Refactor SCP-933 master system to improve interaction mechanics and l…
Cursor/scp 933 victims d9b6c
Rename controlled component to Scp933FaceTornComponent; trim master component; update en-US strings. Includes staged RSI meta change. Made-with: Cursor
Made-with: Cursor
Deletes Content.Server._Scp/Scp9332 orphan file; real 933 is Content.Server/_Scp/Scp933 only. Made-with: Cursor
Cursor/scp 933 victims d9b6c
…ity with do-after events. Added sound effects for applying and removing tape, and updated dependencies for interaction and audio systems. Removed outdated update logic and improved event handling for tape application and removal.
Refactor Scp933MasterSystem to implement full SCP-933 tape functional…
|
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:
📝 WalkthroughWalkthroughДобавлены новые компоненты и системы для механики SCP‑933: предмет «изолента», маска‑лента, состояния «лицо заклеено/порваны ленты», ожидание превращения в хозяина и серверная логика для снятия/надевания/рвала ленты и применения бонусов хозяина. Changes
Sequence Diagram(s)sequenceDiagram
participant Игрок as Игрок
participant TapeSystem as Scp933TapeSystem
participant Цель as Цель (Humanoid)
participant MasterSys as SharedScp933MasterSystem
participant Компоненты as Компоненты/Сервер
Игрок->>TapeSystem: Использует DuctTape (TryPeelTape)
TapeSystem->>Компоненты: Создаёт DoAfter (peel)
Note over TapeSystem: Ожидание DoAfter завершения
TapeSystem->>Компоненты: Спавнит TapeMask, уменьшает UseCount, воспроизводит звук
Игрок->>TapeSystem: Применяет маску к Цели (TryApplyTape)
TapeSystem->>Компоненты: Создаёт DoAfter (apply)
Note over TapeSystem: Ожидание DoAfter завершения
TapeSystem->>Цель: Экипирует mask, добавляет TapedFaceComponent, применяет MutedComponent
Игрок->>TapeSystem: Рвёт ленту у Цели (TryRipTape)
TapeSystem->>Компоненты: Создаёт DoAfter (rip)
Note over TapeSystem: Ожидание DoAfter завершения
alt Результат → превращение в хозяина
TapeSystem->>MasterSys: ConvertToMaster / ApplyHostBuffs
MasterSys->>Компоненты: Добавляет Scp933MasterComponent, EraseFaceFor933, настраивает пороги/баффы
else Результат → лицо порвано
TapeSystem->>MasterSys: ApplyFaceTornAfterRip
MasterSys->>Цель: Добавляет Scp933FaceTornComponent, мутит, скрывает лицо
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (2 errors, 1 warning)
✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Всё заяц, сиди ещё час |
|
Ух еба, даже заяц не ноет |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 10
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Content.Server/_Scp/Scp933/Scp933MasterSystem.cs`:
- Around line 319-323: Здесь мы модифицируем tapeMask.EmergencyRipAvailable
после того, как та же сущность помечена на удаление (removed -> QueueDel),
поэтому изменение не сохранится; переместите присвоение
tapeMask.EmergencyRipAvailable = false так, чтобы оно выполнялось до вызова
QueueDel(removed.Value) (или, если флаг должен быть глобальным, вместо изменения
tapeMask установите/сбросьте соответствующий системный флаг в
Scp933MasterSystem), и убедитесь, что вы используете тот же объект tapeMask (и
проверяете args.EmergencyMode) перед удалением, чтобы изменение вступило в силу.
- Around line 65-66: Remove the redundant TryComp<DuctTapeComponent> call since
`tape` is already an Entity<DuctTapeComponent> and its component is accessible
via `tape.Comp`; replace the TryComp usage with a null-check (or guard) on
`tape.Comp` and return if it is null, ensuring any subsequent uses reference
`tape.Comp` directly (refer to the variable `tape`, the component type
`DuctTapeComponent`, and the existing TryComp<DuctTapeComponent> call to locate
the code).
- Around line 99-100: В методе OnPeelTapeDoAfter есть лишний вызов
TryComp<DuctTapeComponent> для переменной tape; удалите этот дублирующий TryComp
и вместо него используйте уже полученный компонент (ductTape) из предыдущей
проверки/контекста или выполните единственный TryComp в согласованном месте,
чтобы избежать повторного запроса компонента DuctTapeComponent для сущности
tape.
- Around line 172-173: Remove the redundant TryComp check: the variable tapeMask
is an Entity<Scp933TapeMaskComponent> and always has the component, so delete
the if (!TryComp<Scp933TapeMaskComponent>(tapeMask, out _)) return; guard in
Scp933MasterSystem (remove the TryComp call and early return) and use the
component directly where needed (e.g., access via the entity/typed variable or
Comp/GetComponent calls that assume presence).
In `@Content.Shared/_Scp/Scp933/Scp933MasterSystem.cs`:
- Around line 76-90: EraseFaceFor933 currently calls
_humanoid.SetLayerVisibility eight times which can trigger Dirty() repeatedly;
change to use a batched update by using the SetLayerVisibility overload that
accepts a ref bool dirty (or otherwise accumulate a dirty flag) — e.g. create a
local bool dirty = false, call _humanoid.SetLayerVisibility(humanoidEnt,
HumanoidVisualLayers.Eyes, false, ref dirty) for each layer (Eyes, Snout, Head,
Hair, FacialHair, HeadTop, HeadSide, SnoutCover), then after the loop call the
single dirty commit method (e.g. _humanoid.Dirty(humanoidEnt) or the API's
equivalent) if dirty is true so only one Dirty() is emitted; keep references to
EraseFaceFor933, _humanoid.SetLayerVisibility, HumanoidVisualLayers and the
Entity<HumanoidAppearanceComponent?> usage to locate the code.
- Around line 162-165: Метод Clone() в Scp933RipTapeDoAfterEvent не должен
возвращать this — нужно вернуть новый экземпляр с копией состояния; измените
реализацию метода Clone() (в классе Scp933RipTapeDoAfterEvent / метод Clone)
чтобы создавать и возвращать новый объект и скопировать все мутируемые поля
(минимум ExpectedMask и EmergencyMode) и при необходимости другие наследуемые
поля/идентификаторы, вместо возвращения this, чтобы избежать повреждения данных
при сериализации/параллельной обработке.
In `@Resources/Locale/ru-RU/_prototypes/_scp/entities/objects/scp/scp933.ftl`:
- Around line 1-22: This file uses general keys like scp933-duct-tape,
scp933-master-desc, scp933-apply-success-user, etc., but prototype files must
use the ent-{PrototypeID} schema and prototype attributes; rename these keys to
the prototype format (e.g., ent-scp933, ent-scp933.desc for the prototype
description and ent-scp933.suffix where applicable) and convert per-item
prototype attributes to .desc/.suffix forms (replace scp933-duct-tape ->
ent-scp933.duct-tape or ent-scp933.duct-tape.desc as appropriate); move shared
runtime strings (like tape/equip/fail/peel messages such as scp933-tape-already,
scp933-tape-equip-fail, scp933-peel-start, scp933-apply-success-target, etc.)
out of this _prototypes file into the common runtime locale (e.g.,
Resources/Locale/ru-RU/_Scp/ or equivalent) so only prototype-specific metadata
remains here.
- Around line 1-22: Fix Russian typos and clarify target-action wording while
keeping parser-safe, lowercase item names: change scp933-duct-tape and
scp933-tape-mask values to start with lowercase (e.g., "изолента", "ленточка
изоленты"); correct spelling in scp933-master-desc ("первая жертва" or
"первая/основная жертва" instead of "первинная"), scp933-tape-equip-fail ("Лента
тут не прикрепляется" or "Лента не прикрепляется здесь" instead of "Лента не
крепиться здесь"), scp933-peel-hand-fail ("скручивается" instead of
"скручиваеться") and any other misspellings; change scp933-apply-start from "Вы
начинаете заклеивать своё лицо." to a target-focused phrase like "Вы начинаете
заклеивать лицо цели." to avoid implying self-action; ensure all edited strings
remain grammatically correct, consistent in meaning with other keys
(scp933-apply-success-user, scp933-apply-success-target,
scp933-victim-face-torn) and contain no extra punctuation that could break the
parser.
In `@Resources/Prototypes/_Scp/Entities/Clothing/Masks/masks.yml`:
- Around line 40-45: Добавьте в файлы локализации ru-RU и en-US отсутствующие
ключи для прототипа ClothingMaskScp933Tape: как минимум
ent-ClothingMaskScp933Tape, ent-ClothingMaskScp933Tape.desc и, если требуется по
шаблону, ent-ClothingMaskScp933Tape.suffix; поместите в соответствующие .ftl
файлы переводы названия и описания (русский и английский) и убедитесь, что имена
ключей точно совпадают с id прототипа ClothingMaskScp933Tape и со схемой
локализации, используемой для других масок (например с префиксом ent- и
суффиксом .desc/.suffix).
In `@Resources/Prototypes/_Scp/Entities/Objects/Scp/scp933.yml`:
- Line 1: Remove the redundant fork marker "# Fire added" from scp933.yml in the
_Scp/Entities/Objects/Scp directory because this is a new fork-only file and
fork markers are only required when modifying upstream files; open scp933.yml,
delete the leading comment line containing "# Fire added" (ensure any intended
Russian description remains intact) and save the file so the file no longer
begins with the fork marker.
🪄 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: 05fa677f-13e2-435d-afa5-c430aafe67e1
⛔ Files ignored due to path filters (7)
Resources/Audio/_Scp/Scp933/ducttape.oggis excluded by!**/*.oggResources/Audio/_Scp/Scp933/peeloff.oggis excluded by!**/*.oggResources/Textures/_Scp/Objects/Scp/scp-933.rsi/equipped.pngis excluded by!**/*.pngResources/Textures/_Scp/Objects/Scp/scp-933.rsi/peel.pngis excluded by!**/*.pngResources/Textures/_Scp/Objects/Scp/scp-933.rsi/tape.pngis excluded by!**/*.pngResources/Textures/_Scp/Structures/Wallmounts/scp-posters.rsi/scp933.pngis excluded by!**/*.pngResources/Textures/_Scp/Structures/Wallmounts/signs-directional.rsi/933.pngis excluded by!**/*.png
📒 Files selected for processing (16)
Content.Server/_Scp/Scp933/Scp933MasterSystem.csContent.Shared/_Scp/Scp933/DuctTapeComponent.csContent.Shared/_Scp/Scp933/Scp933FaceTornComponent.csContent.Shared/_Scp/Scp933/Scp933MasterComponent.csContent.Shared/_Scp/Scp933/Scp933MasterSystem.csContent.Shared/_Scp/Scp933/Scp933PendingHostComponent.csContent.Shared/_Scp/Scp933/Scp933TapeMaskComponent.csContent.Shared/_Scp/Scp933/TapedFaceComponent.csContent.Shared/_Scp/Scp933/TapedFaceSystem.csResources/Locale/en-US/_Scp/scp933.ftlResources/Locale/ru-RU/_prototypes/_scp/entities/objects/scp/scp933.ftlResources/Prototypes/_Scp/Entities/Clothing/Masks/masks.ymlResources/Prototypes/_Scp/Entities/Objects/Scp/scp933.ymlResources/Textures/_Scp/Objects/Scp/scp-933.rsi/meta.jsonResources/Textures/_Scp/Structures/Wallmounts/scp-posters.rsi/meta.jsonResources/Textures/_Scp/Structures/Wallmounts/signs-directional.rsi/meta.json
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
Content.Server/_Scp/Scp933/Scp933TapeSystem.cs (1)
142-159:⚠️ Potential issue | 🟠 MajorНе снимайте
MutedComponentбез собственного маркера SCP-933.Если цель уже была заглушена другой механикой, вы всё равно ставите
MutedByScp933 = true, а на снятии маски безусловно делаетеRemComp<MutedComponent>. Это удалит чужой mute. Здесь нужен отдельный маркер/учёт причины, и тот же паттерн надо применить в веткеApplyFaceTornAfterRip/OnFaceTornShutdown.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Server/_Scp/Scp933/Scp933TapeSystem.cs` around lines 142 - 159, You currently add/remove MutedComponent unconditionally which can remove mutes applied by other systems; instead add a dedicated marker component (e.g., Scp933MutedComponent) when you mute in ApplyTapeMask/OnTapeMaskGotEquipped and only remove the shared MutedComponent if that marker is present on the target. Concretely: when muting (EnsureComp<MutedComponent>(...), tapeMask.Comp.MutedByScp933 = true) also AddComp<Scp933MutedComponent>(args.Equipee) (do not skip adding the marker even if MutedComponent already existed); when unmuting (OnTapeMaskGotUnequipped and in ApplyFaceTornAfterRip / OnFaceTornShutdown) check HasComp<Scp933MutedComponent>(args.Equipee) before calling RemComp<MutedComponent>, then Remove the marker and clear tapeMask.Comp.MutedByScp933/Dirty as before; apply the same marker-check pattern in both face-torn methods.
🤖 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/Scp933/Scp933MasterSystem.cs`:
- Around line 62-63: После удаления элемента из коллекции FaceTornVictims в
Scp933MasterComponent пометьте компонент как изменённый для сетевой
синхронизации: в блоке где проверяется TryComp<Scp933MasterComponent>(bearer,
out var master) и выполняется master.FaceTornVictims.Remove(ent) вызовите
Dirty(bearer, master) (или Dirty(ent) если уместно) сразу после Remove, чтобы
изменения коллекции были отправлены клиентам.
---
Duplicate comments:
In `@Content.Server/_Scp/Scp933/Scp933TapeSystem.cs`:
- Around line 142-159: You currently add/remove MutedComponent unconditionally
which can remove mutes applied by other systems; instead add a dedicated marker
component (e.g., Scp933MutedComponent) when you mute in
ApplyTapeMask/OnTapeMaskGotEquipped and only remove the shared MutedComponent if
that marker is present on the target. Concretely: when muting
(EnsureComp<MutedComponent>(...), tapeMask.Comp.MutedByScp933 = true) also
AddComp<Scp933MutedComponent>(args.Equipee) (do not skip adding the marker even
if MutedComponent already existed); when unmuting (OnTapeMaskGotUnequipped and
in ApplyFaceTornAfterRip / OnFaceTornShutdown) check
HasComp<Scp933MutedComponent>(args.Equipee) before calling
RemComp<MutedComponent>, then Remove the marker and clear
tapeMask.Comp.MutedByScp933/Dirty as before; apply the same marker-check pattern
in both face-torn methods.
🪄 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: 75e9773c-c31b-4d70-b886-f86725f9d6b1
📒 Files selected for processing (7)
Content.Server/_Scp/Scp933/Scp933MasterSystem.csContent.Server/_Scp/Scp933/Scp933TapeSystem.csContent.Shared/_Scp/Scp933/Scp933FaceTornComponent.csContent.Shared/_Scp/Scp933/Scp933MasterComponent.csContent.Shared/_Scp/Scp933/Scp933MasterSystem.csContent.Shared/_Scp/Scp933/Scp933MutedTagComponent.csContent.Shared/_Scp/Scp933/Scp933TapeMaskComponent.cs
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (2)
Content.Shared/_Scp/Scp933/Scp933MasterSystem.cs (1)
145-161: 🧹 Nitpick | 🔵 TrivialРассмотрите использование
SimpleDoAfterEventбез ручногоClone().Для событий без состояния (
Scp933PeelTapeDoAfterEvent,Scp933ApplyTapeDoAfterEvent) можно использовать базовыйSimpleDoAfterEventбез переопределенияClone(), если он корректно обрабатывает клонирование.Предлагаемый рефакторинг (если SimpleDoAfterEvent поддерживает автоклонирование)
[Serializable, NetSerializable] -public sealed partial class Scp933PeelTapeDoAfterEvent : SimpleDoAfterEvent -{ - public override DoAfterEvent Clone() - { - return new Scp933PeelTapeDoAfterEvent(); - } -} +public sealed partial class Scp933PeelTapeDoAfterEvent : SimpleDoAfterEvent; [Serializable, NetSerializable] -public sealed partial class Scp933ApplyTapeDoAfterEvent : DoAfterEvent -{ - public override DoAfterEvent Clone() - { - return new Scp933ApplyTapeDoAfterEvent(); - } -} +public sealed partial class Scp933ApplyTapeDoAfterEvent : SimpleDoAfterEvent;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Shared/_Scp/Scp933/Scp933MasterSystem.cs` around lines 145 - 161, Эти два пустых события (Scp933PeelTapeDoAfterEvent и Scp933ApplyTapeDoAfterEvent) лишь повторяют поведение SimpleDoAfterEvent, поэтому уберите их кастомные классы/переопределения Clone() и используйте SimpleDoAfterEvent напрямую (или замените их типы/создания на SimpleDoAfterEvent) — проверьте все места, где упоминаются Scp933PeelTapeDoAfterEvent и Scp933ApplyTapeDoAfterEvent, и замените их на SimpleDoAfterEvent, удалив ненужные определения Clone() в Scp933PeelTapeDoAfterEvent и Scp933ApplyTapeDoAfterEvent если SimpleDoAfterEvent самостоятельно корректно клонируется.Content.Server/_Scp/Scp933/Scp933TapeSystem.cs (1)
150-158:⚠️ Potential issue | 🟠 MajorРиск перезаписи чужого
MutedComponent.Если у сущности уже есть
MutedComponentот другой механики, текущий код установитMutedByScp933 = true, и при снятии маски удалит чужой мут.Предлагаемое исправление
private void OnTapeMaskGotEquipped(Entity<Scp933TapeMaskComponent> tapeMask, ref GotEquippedEvent args) { if (args.Slot != "mask") return; - EnsureComp<MutedComponent>(args.Equipee); - tapeMask.Comp.MutedByScp933 = true; + if (!HasComp<MutedComponent>(args.Equipee)) + { + EnsureComp<MutedComponent>(args.Equipee); + tapeMask.Comp.MutedByScp933 = true; + } Dirty(tapeMask); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Server/_Scp/Scp933/Scp933TapeSystem.cs` around lines 150 - 158, В текущем OnTapeMaskGotEquipped вы можете перезаписать чужой MutedComponent — измените логику: вместо безусловного EnsureComp+перезаписи, сначала попытайтесь получить существующий компонент через TryGetComp(args.Equipee, out MutedComponent comp); если не найден — создайте его через EnsureComp; в обоих случаях выставьте только флаг comp.MutedByScp933 = true и вызовите Dirty(comp) (не затирая другие флаги). Также откройте обработчик снятия (OnTapeMaskGotUnequipped) и измените его так, чтобы он только очищал comp.MutedByScp933 и удалял сам MutedComponent только если ни один из флагов (например MutedByScp933 и другие) не установлен; используйте RemComp только в этом безопасном случае.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Content.Server/_Scp/Scp933/Scp933TapeSystem.cs`:
- Around line 431-438: Re-evaluate the emergency rip condition at completion:
inside TryCompleteRipTape (before calling DoRipTape/ConvertToMaster) call
CanRipTape(target, expectedMask, out var tapeMask) again and recompute
emergencyMode (or bail out) so you don't proceed with a stale emergencyMode
computed in TryRipTape; ensure DoRipTape/ConvertToMaster only run when the
rechecked emergencyMode is still valid (or update the flag passed to DoRipTape)
to prevent multiple masters being created.
In `@Content.Shared/_Scp/Scp933/Scp933MasterSystem.cs`:
- Around line 131-134: After modifying the Scp933FaceTornComponent instance
(obtained via EnsureComp<Scp933FaceTornComponent>(victim)) — setting TornBy and
MutedByScp933 — mark the component dirty so the AutoNetworkedField changes are
synchronized by calling Dirty for the entity/component (e.g., Dirty(victim,
torn) or Dirty(victim)) immediately after those assignments.
In `@Resources/Locale/en-US/_prototypes/_scp/entities/clothing/masks/masks.ftl`:
- Around line 5-6: Lowercase the entity key ent-ClothingMaskScp933Tape to
ent-clothingmaskscp933tape and update its .desc to a more natural phrasing with
a capitalized sentence start (e.g., change ".desc = Silver strips pressed over
the eyes. It does not breathe with you." to ".desc = Silver strips pressed over
the eyes. They do not move with your breathing."). Ensure you modify the entry
with the exact identifiers ent-ClothingMaskScp933Tape ->
ent-clothingmaskscp933tape and the corresponding .desc line.
---
Duplicate comments:
In `@Content.Server/_Scp/Scp933/Scp933TapeSystem.cs`:
- Around line 150-158: В текущем OnTapeMaskGotEquipped вы можете перезаписать
чужой MutedComponent — измените логику: вместо безусловного
EnsureComp+перезаписи, сначала попытайтесь получить существующий компонент через
TryGetComp(args.Equipee, out MutedComponent comp); если не найден — создайте его
через EnsureComp; в обоих случаях выставьте только флаг comp.MutedByScp933 =
true и вызовите Dirty(comp) (не затирая другие флаги). Также откройте обработчик
снятия (OnTapeMaskGotUnequipped) и измените его так, чтобы он только очищал
comp.MutedByScp933 и удалял сам MutedComponent только если ни один из флагов
(например MutedByScp933 и другие) не установлен; используйте RemComp только в
этом безопасном случае.
In `@Content.Shared/_Scp/Scp933/Scp933MasterSystem.cs`:
- Around line 145-161: Эти два пустых события (Scp933PeelTapeDoAfterEvent и
Scp933ApplyTapeDoAfterEvent) лишь повторяют поведение SimpleDoAfterEvent,
поэтому уберите их кастомные классы/переопределения Clone() и используйте
SimpleDoAfterEvent напрямую (или замените их типы/создания на
SimpleDoAfterEvent) — проверьте все места, где упоминаются
Scp933PeelTapeDoAfterEvent и Scp933ApplyTapeDoAfterEvent, и замените их на
SimpleDoAfterEvent, удалив ненужные определения Clone() в
Scp933PeelTapeDoAfterEvent и Scp933ApplyTapeDoAfterEvent если SimpleDoAfterEvent
самостоятельно корректно клонируется.
🪄 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: ec8ce2ad-8394-43ca-8eb5-9f72616d342d
📒 Files selected for processing (4)
Content.Server/_Scp/Scp933/Scp933TapeSystem.csContent.Shared/_Scp/Scp933/Scp933MasterSystem.csResources/Locale/en-US/_prototypes/_scp/entities/clothing/masks/masks.ftlResources/Locale/ru-RU/_prototypes/_scp/entities/clothing/masks/masks.ftl
коммитфикс8.1
|
@coderabbitai Проверь опять |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 103554
По поводу вопроса С моей стороны замечаний нет. 🎉 |
|
@coderabbitai Ещё жалобы от @ThereDrD0 ожидаются или всё уже оптимизировано и готово к merge? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 78326
🔴 Открытые треды от
|
| Файл | Замечание |
|---|---|
Content.Server/.../Scp933MasterSystem.cs |
Использовать отдельный компонент для возможных целей SCP-933 вместо HumanoidAppearanceComponent |
Content.Server/.../Scp933MasterSystem.cs |
Слоты вынести в компонент как список (настраиваемый через YAML) |
Content.Server/.../Scp933MasterSystem.cs |
Валидацию делать внутри поля компонента через get/set, а не в системе |
Content.Server/.../Scp933MasterSystem.cs |
Хардкод — должно настраиваться через компоненты |
Content.Shared/.../DuctTapeComponent.cs |
Почему не Stack-компонент вместо своего счётчика UseCount? |
Content.Shared/.../Scp933MasterComponent.cs |
[ViewVariables(VVAccess.ReadOnly)] → достаточно просто [ViewVariables] |
Content.Shared/.../Scp933MasterSystem.cs |
Серверный код перенести на сервер |
Content.Shared/.../Scp933MasterSystem.cs |
Слои для скрытия лица сделать списком в компоненте и проходить циклом, а не хардкодить |
🟡 Мои открытые замечания (из последнего ревью, актуальные):
| Файл | Замечание |
|---|---|
Content.Server/.../Scp933TapeSystem.cs (строка ~431) |
Повторно проверять emergencyMode при завершении DoAfter, чтобы не создавать лишних мастеров |
Content.Shared/.../Scp933MasterSystem.cs (строка ~131) |
Вызывать Dirty(victim, torn) после установки TornBy/MutedByScp933 для сетевой синхронизации |
Content.Server/.../Scp933TapeSystem.cs (строка ~150) |
MutedComponent может удалить чужой мут — нужен маркер-компонент Scp933MutedTagComponent |
Итого: PR ещё требует доработки. Основные блокеры — замечания @ThereDrD0.
|
А ну пересмотрит коммиты |
|
✅ Actions performedReview triggered.
|
|
@coderabbitai Что там по ревью, отчёт |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 43412
CI: ✅ Diff RSI — пройдено | ⏳ Label — в процессе 🔴 Открытые треды от
|
| Файл | Замечание |
|---|---|
Content.Server/.../Scp933MasterSystem.cs |
Использовать отдельный компонент для возможных целей SCP-933 вместо проверки HumanoidAppearanceComponent |
Content.Server/.../Scp933MasterSystem.cs |
Слои вынести в компонент как список (настраиваемый через YAML) |
Content.Server/.../Scp933MasterSystem.cs |
Валидацию делать внутри поля компонента через get/set |
Content.Server/.../Scp933MasterSystem.cs |
Хардкод — должно настраиваться через компоненты |
Content.Shared/.../DuctTapeComponent.cs |
Использовать стандартный Stack-компонент вместо своего счётчика UseCount |
Content.Shared/.../Scp933MasterComponent.cs |
[ViewVariables(VVAccess.ReadOnly)] → заменить на просто [ViewVariables] |
Content.Shared/.../Scp933MasterSystem.cs |
Серверный код перенести на сервер |
Content.Shared/.../Scp933MasterSystem.cs |
Слои для EraseFaceFor933 сделать списком в компоненте с циклом вместо хардкода |
🟡 Мои открытые замечания (из последнего ревью, commit 442f10b0):
| Файл | Замечание | Приоритет |
|---|---|---|
Content.Server/.../Scp933TapeSystem.cs (~431) |
Повторно вычислять emergencyMode внутри TryCompleteRipTape перед созданием мастера, а не использовать устаревший флаг |
🟠 Major |
Content.Shared/.../Scp933MasterSystem.cs (~131) |
Вызвать Dirty(victim, torn) после установки TornBy/MutedByScp933 для сетевой синхронизации |
🟠 Major |
Content.Server/.../Scp933TapeSystem.cs (~150) |
MutedComponent может удалить чужой мут — нужна проверка: добавлять MutedByScp933 = true только если компонент не существовал до этого |
🟠 Major |
Content.Shared/.../Scp933MasterSystem.cs (~145) |
Scp933PeelTapeDoAfterEvent / Scp933ApplyTapeDoAfterEvent можно заменить напрямую на SimpleDoAfterEvent |
🔵 Nitpick |
Итого: Есть 8 нерезолвнутых тредов от @ThereDrD0 + 3 actionable замечания от меня. До мержа нужно разобраться как минимум с замечаниями ThereDrD0 (они блокируют аппрув).
There was a problem hiding this comment.
♻️ Duplicate comments (3)
Content.Server/_Scp/Scp933/Scp933TapeSystem.cs (1)
150-174:⚠️ Potential issue | 🟠 MajorНекорректное отслеживание
MutedComponent— чужой mute может быть удалён.Текущая логика:
- При надевании
EnsureComp<MutedComponent>ничего не делает, если компонент уже был- Но
MutedByScp933 = trueустанавливается всегда- При снятии маски удаляется
MutedComponent, даже если он был добавлен другой механикойНужно проверять, был ли
MutedComponentдо надевания маски.🛡️ Предлагаемое исправление
private void OnTapeMaskGotEquipped(Entity<Scp933TapeMaskComponent> tapeMask, ref GotEquippedEvent args) { if (args.Slot != "mask") return; + // Не перезаписывать чужой mute + if (HasComp<MutedComponent>(args.Equipee)) + { + tapeMask.Comp.MutedByScp933 = false; + Dirty(tapeMask); + return; + } + EnsureComp<MutedComponent>(args.Equipee); tapeMask.Comp.MutedByScp933 = true; Dirty(tapeMask); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Server/_Scp/Scp933/Scp933TapeSystem.cs` around lines 150 - 174, The code currently always sets tapeMask.Comp.MutedByScp933 = true on equip which can remove someone else's mute on unequip; change OnTapeMaskGotEquipped to first check bool hadMuted = HasComp<MutedComponent>(args.Equipee) and only call EnsureComp<MutedComponent>(args.Equipee) if needed, then set tapeMask.Comp.MutedByScp933 = !hadMuted (true only if we added the component), and call Dirty(tapeMask) only when MutedByScp933 was set; leave OnTapeMaskGotUnequipped as-is because it already only removes the MutedComponent when tapeMask.Comp.MutedByScp933 is true (so this will now correctly only remove mutes we added). Ensure you reference OnTapeMaskGotEquipped, OnTapeMaskGotUnequipped, MutedByScp933, EnsureComp<MutedComponent>, HasComp<MutedComponent>, RemComp<MutedComponent>, and Dirty(tapeMask) when making the change.Content.Shared/_Scp/Scp933/Scp933MasterSystem.cs (2)
146-162: 🧹 Nitpick | 🔵 TrivialИзбыточное переопределение
Clone()для событий без состояния.
Scp933PeelTapeDoAfterEventнаследуетSimpleDoAfterEvent, который уже предоставляет корректныйClone(). Аналогично,Scp933ApplyTapeDoAfterEventне имеет полей состояния и может наследоватьSimpleDoAfterEvent.♻️ Упрощённый вариант
[Serializable, NetSerializable] public sealed partial class Scp933PeelTapeDoAfterEvent : SimpleDoAfterEvent { - public override DoAfterEvent Clone() - { - return new Scp933PeelTapeDoAfterEvent(); - } } [Serializable, NetSerializable] -public sealed partial class Scp933ApplyTapeDoAfterEvent : DoAfterEvent +public sealed partial class Scp933ApplyTapeDoAfterEvent : SimpleDoAfterEvent { - public override DoAfterEvent Clone() - { - return new Scp933ApplyTapeDoAfterEvent(); - } }Как указал ThereDrD0 в прошлом ревью:
SimpleDoAfterEventне требует ручного переопределенияClone().🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Shared/_Scp/Scp933/Scp933MasterSystem.cs` around lines 146 - 162, Переопределения Clone() избыточны: удалите метод Clone() в классах Scp933PeelTapeDoAfterEvent и Scp933ApplyTapeDoAfterEvent, и сделайте Scp933ApplyTapeDoAfterEvent наследником SimpleDoAfterEvent (как уже сделано для Scp933PeelTapeDoAfterEvent), чтобы оба события использовали стандартную реализацию SimpleDoAfterEvent без собственных Clone().
108-111: 🧹 Nitpick | 🔵 TrivialИзбыточная проверка
HasCompпередEnsureComp.
EnsureComp<T>уже возвращает существующий компонент, если он есть — дополнительная проверкаHasCompне нужна.♻️ Упрощённый вариант
- if (HasComp<Scp933MasterComponent>(victim)) - return; - EnsureComp<Scp933MasterComponent>(victim);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Shared/_Scp/Scp933/Scp933MasterSystem.cs` around lines 108 - 111, The upfront HasComp<Scp933MasterComponent>(victim) check is redundant because EnsureComp<Scp933MasterComponent>(victim) will return the existing component; remove the if-check and simply call EnsureComp<Scp933MasterComponent>(victim) (or assign its return to a variable if you need to use the component), keeping references to Scp933MasterComponent and victim to locate the change.
🤖 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.Server/_Scp/Scp933/Scp933TapeSystem.cs`:
- Around line 150-174: The code currently always sets
tapeMask.Comp.MutedByScp933 = true on equip which can remove someone else's mute
on unequip; change OnTapeMaskGotEquipped to first check bool hadMuted =
HasComp<MutedComponent>(args.Equipee) and only call
EnsureComp<MutedComponent>(args.Equipee) if needed, then set
tapeMask.Comp.MutedByScp933 = !hadMuted (true only if we added the component),
and call Dirty(tapeMask) only when MutedByScp933 was set; leave
OnTapeMaskGotUnequipped as-is because it already only removes the MutedComponent
when tapeMask.Comp.MutedByScp933 is true (so this will now correctly only remove
mutes we added). Ensure you reference OnTapeMaskGotEquipped,
OnTapeMaskGotUnequipped, MutedByScp933, EnsureComp<MutedComponent>,
HasComp<MutedComponent>, RemComp<MutedComponent>, and Dirty(tapeMask) when
making the change.
In `@Content.Shared/_Scp/Scp933/Scp933MasterSystem.cs`:
- Around line 146-162: Переопределения Clone() избыточны: удалите метод Clone()
в классах Scp933PeelTapeDoAfterEvent и Scp933ApplyTapeDoAfterEvent, и сделайте
Scp933ApplyTapeDoAfterEvent наследником SimpleDoAfterEvent (как уже сделано для
Scp933PeelTapeDoAfterEvent), чтобы оба события использовали стандартную
реализацию SimpleDoAfterEvent без собственных Clone().
- Around line 108-111: The upfront HasComp<Scp933MasterComponent>(victim) check
is redundant because EnsureComp<Scp933MasterComponent>(victim) will return the
existing component; remove the if-check and simply call
EnsureComp<Scp933MasterComponent>(victim) (or assign its return to a variable if
you need to use the component), keeping references to Scp933MasterComponent and
victim to locate the change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4b0e57eb-5769-4542-9c07-57e03623b26a
📒 Files selected for processing (3)
Content.Server/_Scp/Scp933/Scp933TapeSystem.csContent.Shared/_Scp/Scp933/Scp933MasterSystem.csResources/Locale/en-US/_prototypes/_scp/entities/clothing/masks/masks.ftl
ThereDrD0
left a comment
There was a problem hiding this comment.
Иди доделывай. И хватит использовать кролика для проверки того, сдалал ли ты ревью, он плохо справляется и ты не делаешь половину запрошенного.
Сам смотри, что нужно делать и делай это
| [Dependency] private readonly DamageableSystem _damageable = default!; | ||
| [Dependency] private readonly MobThresholdSystem _mobThresholds = default!; | ||
| public bool HasAnyScp933Host() | ||
| { | ||
| var query = EntityQueryEnumerator<Scp933MasterComponent>(); | ||
| return query.MoveNext(out _, out _); | ||
| } |
There was a problem hiding this comment.
| [Dependency] private readonly DamageableSystem _damageable = default!; | |
| [Dependency] private readonly MobThresholdSystem _mobThresholds = default!; | |
| public bool HasAnyScp933Host() | |
| { | |
| var query = EntityQueryEnumerator<Scp933MasterComponent>(); | |
| return query.MoveNext(out _, out _); | |
| } | |
| [Dependency] private readonly DamageableSystem _damageable = default!; | |
| [Dependency] private readonly MobThresholdSystem _mobThresholds = default!; | |
| public bool HasAnyScp933Host() | |
| { | |
| var query = EntityQueryEnumerator<Scp933MasterComponent>(); | |
| return query.MoveNext(out _, out _); | |
| } |
| if (TryComp<MeleeWeaponComponent>(uid, out var melee)) | ||
| { | ||
| melee.Damage = new DamageSpecifier { DamageDict = { ["Blunt"] = master.HostBluntDamage } }; | ||
| Dirty(uid, melee); | ||
| } |
There was a problem hiding this comment.
Сразу храни в компоненте DamageSpecifier, тогда будет ещё меньше хардкода и код лучше
| if (args.Slot != "mask") | ||
| return; |
There was a problem hiding this comment.
Слот должен храниться в компоненте, желательно списком возможных слотов
| private void OnTargetMove(Entity<HumanoidAppearanceComponent> target, ref MoveEvent args) | ||
| { | ||
| if (!_targetToActiveDoAfters.TryGetValue(target.Owner, out var activeDoAfters)) | ||
| return; | ||
|
|
||
| foreach (var doAfterId in activeDoAfters) | ||
| { | ||
| _doAfter.Cancel(doAfterId); | ||
| } | ||
|
|
||
| _targetToActiveDoAfters.Remove(target.Owner); | ||
| } |
There was a problem hiding this comment.
- Ультралаг едишен
- Зачем ты переизобретаешь существующую логику работу дуафтеров
Оно и так автоматически должно работать если ты правильно делаешь
| { | ||
| tape.Comp.UseCount--; | ||
| if (tape.Comp.UseCount <= 0) | ||
| { | ||
| QueueDel(tape); | ||
| return; | ||
| } | ||
|
|
||
| Dirty(tape); | ||
| } |
There was a problem hiding this comment.
Ты так и не использовал логику стаков уже готовую, делай по аналогии с материалами
| TryCompletePeelTape(tape, args.User); | ||
| } | ||
|
|
||
| private void OnHumanoidInteractUsing(Entity<HumanoidAppearanceComponent> target, ref InteractUsingEvent args) |
There was a problem hiding this comment.
Опять же не использован отдельный компонент для этого





Краткое описание | Short description
О великий 933 был добавлен, наконец я смогу заклеить дыру в 173.
Объект 933 — это клейкая лента, создающая сущности, которые подчиняются первому заражённому и пытаются наклеить ленту на всех, срывая при этом лицо.
Ссылка на багрепорт/Предложение | Related Issue/Bug Report
Медиа (Видео/Скриншоты) | Media (Video/Screenshots)
Changelog
Добавлен SCP-933, включая: сам объект 933, 933-1, 933-2 (Хост) и 933-2 (Миньон). Механика: Наклеивания ленты, отклеивания, порабощение персонала в ряды SCP-933.
🆑 Fire Helper/Helper_Never_Dies
Summary by CodeRabbit
Новые функции
Локализация