Чудо-Юдо. Новый монстр Недр. H/M#613
Conversation
WalkthroughДобавлена новая серверная система для сущности SCP "NothingThere" с поддержкой множественных механик. Реализованы компоненты для управления телом, трансформации в яйцо и осадок (empower), включая отслеживание убийств и звукового сопровождения. Система включает обработку действий игроков (вход в тело, трансформация, боевые манипуляции), управление состоянием сущности через фазы, спаренную карту для временного захвата, и интеграцию с системой ума (mind transfer). Добавлены прототипы сущностей, действий, оружия и локализации на русском языке. Sequence Diagram(s)sequenceDiagram
participant Player as Игрок/Исполнитель
participant NothingThere as Система NothingThere
participant Target as Цель (Мобиль)
participant Mind as Система Ума
participant PausedMap as Приостановленная Карта
Player->>NothingThere: Активирует "Вход в Тело"
NothingThere->>NothingThere: Проверяет валидность цели<br/>(не ротт, гуманоид, мёртв)
NothingThere->>Player: Начало DoAfter (EnterBodyWindUp)
Player-->>NothingThere: DoAfter завершён
NothingThere->>Mind: Переносит ум игрока на цель
NothingThere->>Target: Переводит в MobState.Alive
NothingThere->>NothingThere: Обновляет пороги урона мобили
NothingThere->>PausedMap: Переводит исходное тело на карту
NothingThere->>NothingThere: Останавливает музыку преследования
sequenceDiagram
participant NothingThere as Сущность NothingThere
participant System as Система
participant Audio as Аудиосистема
participant Map as Система Карт
Note over NothingThere: Phase 0: Инициализация
NothingThere->>System: MapInitEvent
System->>NothingThere: Регистрирует действия (Enter, Egg, Projectile)
Note over NothingThere: Phase 1: Трансформация Яйца
System->>System: Ждёт EggTransformEnd
System->>NothingThere: Полиморфизм в TrueMorph
System->>Audio: Воспроизводит HatchSound
Note over NothingThere: Phase 2: Усиление (Empower)
NothingThere->>System: Игрок активирует действие Goodbye
System->>NothingThere: Выдаёт оружие (GoodbyeProto/HitProto)
NothingThere->>Audio: Звук усиления при использовании
System->>NothingThere: Переводит NeedItems = false
sequenceDiagram
participant ControlledBody as Контролируемое Тело
participant NothingThere as Система NothingThere
participant Audio as Аудиосистема
participant Destructible as Система Разрушения
participant MindSystem as Система Ума
ControlledBody->>ControlledBody: Переходит в Dead/Critical
NothingThere->>MindSystem: Восстанавливает ум на OriginalBody
NothingThere->>Audio: Воспроизводит ExitSound
NothingThere->>Destructible: Вызывает Gib()
Destructible->>Destructible: Удаляет сущность
Destructible->>Audio: Звук гибели
NothingThere->>NothingThere: Синхронизирует KillCount
NothingThere->>Audio: Перезапускает музыку преследования
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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: 22
🤖 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/Imperial/SCP/NothingThere/Components/ImperialControlledNothingThereComponent.cs`:
- Around line 19-23: OriginalBody and KillCount are runtime-only state but are
currently marked with [DataField]; remove the [DataField] attributes and instead
annotate these fields with [ViewVariables] (e.g., [ViewVariables] or
[ViewVariables(VVAccess.ReadWrite)] as appropriate) in the
ImperialControlledNothingThereComponent so they are visible/editable in VV and
not treated as prototype-configured values; keep their runtime defaults
(OriginalBody = EntityUid.Invalid, KillCount = 0) and leave ExitSound as the
DataField-configured prototype value.
In
`@Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereComponent.cs`:
- Line 59: Поля runtime-состояния в компоненте ImperialNothingThereComponent
(`Empowered` и `NeedGoodbye`) не помечены атрибутом [ViewVariables]; добавьте
атрибут [ViewVariables] над определениями этих полей в классе
ImperialNothingThereComponent, чтобы они были видимы в отладке/инспекторах
(оставьте типы и имена полей без изменений).
- Line 43: Поля компонента ImperialNothingThereComponent — EggEntityProto,
TrueEntityProto, GoodbyeProto и HitProto — содержат идентификаторы прототипов,
но не помечены атрибутом [DataField], из‑за чего их нельзя переопределить через
YAML; откройте класс ImperialNothingThereComponent и добавить атрибут
[DataField] к каждому из этих полей (если их нужно конфигурировать из
прототипов), либо — если пропи́сно намеренно неизменяемо — пометить их
[ViewVariables] для отладки; убедитесь, что имена полей в [DataField("...")]
соответствуют ожидаемым YAML-ключам и что типы (EntProtoId?) остаются без
изменений.
- Around line 8-9: Файл содержит неиспользуемые директивы using: remove the
unused imports Content.Shared.Mobs.Systems and Content.Shared.Mobs from the top
of the ImperialNothingThereComponent file; locate the
ImperialNothingThereComponent class in the
Content.Server.Imperial.SCP.NothingThere.Components namespace and delete the two
using lines (using Content.Shared.Mobs.Systems; and using Content.Shared.Mobs;)
so only required namespaces remain.
In
`@Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereGoodbyeComponent.cs`:
- Around line 6-10: The field Used is a runtime-only flag and should not be a
prototype-configured DataField: remove the [DataField] attribute from Used and
mark it with [ViewVariables] instead; conversely ensure HitProto (EntProtoId
HitProto = "ImperialNothingThereHit") is marked with [DataField] (e.g.
[DataField("hitProto")]) so it’s serializable from YAML; leave EmpowerSound
as-is. Modify these attributes on the ImperialNothingThereGoodbyeComponent to
separate runtime state (Used) from prototype-configurable fields (HitProto,
EmpowerSound).
In
`@Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThere.ChaseMusic.cs`:
- Around line 27-33: The component currently sets comp.IsPlaying = true
unconditionally even if _audio.PlayPvs(...) returns null; change the logic so
you first call _audio.PlayPvs(comp.ChaseSound, uid,
AudioParams.Default.WithLoop(true)) and assign its ?.Entity to
comp.PlayingStream, then only set comp.IsPlaying = true if comp.PlayingStream is
not null (otherwise leave/set comp.IsPlaying = false) so failed PlayPvs attempts
don't mark the component as playing and prevent future retries.
In
`@Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.Arsenal.cs`:
- Around line 96-104: The handler continues executing when
TryComp<HandsComponent>(args.User, out var hands) fails; after setting
args.Handled = true you must return to avoid using null/uninitialized hands in
_hands.GetActiveHand and the Timer callback. Modify the block around TryComp so
that when it returns false you set args.Handled = true and immediately return
from the method (ensuring the if has braces or an explicit return), leaving the
subsequent calls to _audio.PlayPvs, comp.Used, _hands.GetActiveHand, Timer.Spawn
and _hands.DoDrop only reachable when hands is present.
- Around line 60-65: Привяжите do-after к изначальному предмету и руке: при
создании DoAfterArgs (в месте с вызовом new DoAfterArgs(...)) установите
NeedHand = true и передайте туда текущий активный предмет/руку (например
сохраните var initItem = GetActiveItem() и передайте его в поле/параметр
DoAfterArgs, либо используйте доступное поле для Used/TargetEntity), затем в
обработчике OnGoodbyeDoAfter используйте переданный в args объект (а не повторно
вызывать GetActiveItem()) и добавьте безопасную проверку handd на null/valid
перед использованием/удалением предмета.
- Around line 34-49: The code clears comp.NeedGoodbye before attempting pickup
so a failed TryForcePickup causes the goodbye to be lost; move the mutation so
NeedGoodbye is only set to false after a successful pickup. In
ImperialNothingThereSystem.Arsenal (look for the spawn/try-pickup block using
Spawn, Transform(uid).Coordinates, _hands.TryForcePickup, hit, comp.NeedGoodbye
and comp.NeedItems), only set comp.NeedGoodbye = false inside the branch taken
when TryForcePickup returns true (and keep QueueDel/return behavior on failure),
and ensure comp.NeedItems is updated consistently after success.
In
`@Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.BodyControl.cs`:
- Around line 112-118: The code currently drops all items via
TryComp<HandsComponent> and _hands.TryDrop(...) then calls
RemComp<HandsComponent>(target), which can break other systems expecting the
component; instead stop removing the component: in the block that finds
HandsComponent (via TryComp<HandsComponent>(target, out var hands)) drop each
held item using _hands.TryDrop((target, hands), hand) but do not call
RemComp<HandsComponent>(target); if you need to reset state, clear or reset the
hands collection on the found HandsComponent instance (e.g., empty or set a
disabled flag) rather than removing the component so other systems still see a
valid HandsComponent.
- Line 100: The code sets var target = args.Target ?? EntityUid.Invalid and then
proceeds to call TryComp/EnsureComp on that invalid ID; add an early
null/invalid check for args.Target to avoid operating on EntityUid.Invalid.
Inside the method in ImperialNothingThereSystem (BodyControl logic), if
args.Target is null or target == EntityUid.Invalid return immediately (or skip
the rest of the handling) before calling TryComp, EnsureComp, or any component
operations on target. Ensure the check references args.Target and the local
variable target so subsequent code is only executed for a valid EntityUid.
- Around line 165-189: The Gib method raises GibbedBeforeDeletionEvent but never
actually deletes the entity, which breaks subscribers that expect the entity to
be removed (e.g., TransferMindOnGibSystem, ForensicsSystem, ImplantedSystem).
Modify Gib (method name Gib, parameter ent) to raise BeingGibbedEvent and
GibbedBeforeDeletionEvent before performing the final deletion, then delete the
entity (e.g., call the project's delete method such as
EntityManager.DeleteEntity(ent) or the appropriate _destructible/_entityManager
delete method) after RaiseLocalEvent(ent, ref beforeDeletion) so subscribers run
with the entity still present but it is removed immediately afterwards.
- Line 123: The expression uses the null-coalescing operator with the wrong
precedence so `??` never triggers: change the assignment of nddde to either add
parentheses around the coalescing operation like var nddde = ddde +
(comp.Threshold ?? FixedPoint2.New(400.0f)); or, if the intent is that Threshold
be nullable, make comp.Threshold a nullable FixedPoint2? and then use the same
parenthesized expression (ddde + (comp.Threshold ?? FixedPoint2.New(400.0f))) to
ensure the default is applied when Threshold is null.
- Around line 143-164: OnControlledMobStateChanged uses comp.OriginalBody
without validating it; if OriginalBody is EntityUid.Invalid the calls to
Transform(newb) and subsequent ops will fail. Fix by early-returning (or
aborting the death/transfer logic) when comp.OriginalBody is invalid: check
ImperialControlledNothingThereComponent.OriginalBody at start of the death
branch in OnControlledMobStateChanged and only call Transform(newb),
_transform.SetParent/_transform.SetCoordinates, _mind.TransferTo,
_audio.PlayPvs, Gib, and TryComp(...) when OriginalBody is a valid EntityUid;
otherwise skip those steps (or queue cleanup) to avoid operating on an invalid
entity.
In
`@Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.Egg.cs`:
- Around line 52-53: PolymorphEntity может вернуть EntityUid.Invalid, но код
всегда вызывает _audio.PlayPvs(egg.HatchSound, newb); — добавьте проверку на
валидность после вызова PolymorphEntity: var newb =
_polymorph.PolymorphEntity(entity, egg.TrueMorph) ?? EntityUid.Invalid; if (newb
== EntityUid.Invalid) return; // либо пропустить воспроизведение и дальнейшие
шаги; иначе вызовите _audio.PlayPvs(egg.HatchSound, newb). Это предотвратит
попытки проигрывать звук на невалидном uid и повторные срабатывания в апдейте.
In
`@Content.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.PausedMap.cs`:
- Around line 14-20: В обработчике OnRoundRestart, после вызова
Del(PausedMap.Value) явно сбросьте свойство PausedMap в null, чтобы избежать
хранения удалённого EntityUid; то есть в методе OnRoundRestart (работающем с
PausedMap и проверяющем Exists) после удаления сущности вызвать присвоение
PausedMap = null, чтобы состояние было предсказуемым и EnsurePausedMap не
полагался только на Exists.
In
`@Content.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereGoodbyeDoAfterEvent.cs`:
- Around line 8-13: Remove the redundant empty constructor and the unnecessary
override of Clone() in the ImperialNothingThereGoodbyeDoAfterEvent class: delete
the explicit parameterless constructor and the public override DoAfterEvent
Clone() => this; method so the class uses the compiler-generated constructor and
the base SimpleDoAfterEvent.Clone implementation.
In `@Resources/Locale/ru-RU/Imperial/SCP/dimensionenteraction.ftl`:
- Line 6: В строке ключа nothingthere-hammaggotson-haha исправьте незакрытые
форматирующие теги: корректно закройте вложенные теги в обратном порядке их
открытия (например добавьте недостающие [/bold], затем [/font], затем [/color]
или соответствующие закрывающие теги), чтобы все открытые [color=red], [font
size=14], [bold] были закрыты.
In `@Resources/Locale/ru-RU/Imperial/Seriozha/SCP/locale.ftl`:
- Line 198: В описании локали для ent-CloakNDAWhite (ключ .desc в locale.ftl)
исправьте опечатку и формулировку: заменить «Ауидо» на «аудио» и «Для удобности»
на «Для удобства», т.е. обновить значение .desc соответствующего объекта
(ent-CloakNDAWhite) на корректную фразу с этими правками.
In `@Resources/Prototypes/Imperial/SCP/Actions/nothingthere.yml`:
- Around line 1-12: The action ImperialNothingThereEnterBodyAction is missing
parent: BaseAction causing it to not inherit default components; add parent:
BaseAction to the ImperialNothingThereEnterBodyAction YAML entry so it matches
ImperialNothingThereGibBodyAction, ImperialNothingThereEggAction and
ImperialNothingThereHelloAction, then verify that any required base components
(e.g., Action, TargetAction, EntityTargetAction) are not duplicated or
contradicted after inheritance and adjust/remove explicit component declarations
if they conflict with BaseAction defaults.
- Around line 52-68: The entity ImperialNothingThereProjectileAction is missing
inheritance from BaseAction; update the entity definition for
ImperialNothingThereProjectileAction to include a parent: BaseAction entry
(matching other actions in the file) so it inherits base action behavior while
keeping its existing components (Action, TargetAction, WorldTargetAction)
intact.
In `@Resources/Prototypes/Imperial/Seriozha/misc/misc.yml`:
- Around line 50-68: Вынести общие поля для CloakNDADelexor и CloakNDAWhite в
общий абстрактный parent: создайте новый прототип (например CloakNDABase) с
parent: ClothingNeckBase и общими полями name, suffix, description и общим
components-секцией за исключением уникального sprite; затем обновите
CloakNDADelexor и CloakNDAWhite чтобы они наследовали от CloakNDABase и
оставляли только id и уникальный Sprite (sprite:
Imperial/Seriozha/misc/Customization/nda_cloak.rsi и sprite:
Imperial/Seriozha/misc/Customization/white_cloak.rsi соответственно).
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 3d22ef9c-2d1e-416b-bf57-8c912e0e87d3
⛔ Files ignored due to path filters (32)
Resources/Audio/Imperial/SCP/nothingthere_empower.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_enter.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_gibbody.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_goodbyehit.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_hatch.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_heartbeat.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_hello.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_idle.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_idle_true.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_projectile.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_punch1.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_punch2.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_run1.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_run2.oggis excluded by!**/*.oggResources/Audio/Imperial/SCP/nothingthere_scream.oggis excluded by!**/*.oggResources/Textures/Imperial/SCP/nothingthere1.rsi/jared.pngis excluded by!**/*.pngResources/Textures/Imperial/SCP/nothingthere2.rsi/jared.pngis excluded by!**/*.pngResources/Textures/Imperial/SCP/nothingthere2.rsi/jared2.pngis excluded by!**/*.pngResources/Textures/Imperial/SCP/nothingthereegg.rsi/icon.pngis excluded by!**/*.pngResources/Textures/Imperial/SCP/nothingtherewpn1.rsi/icon.pngis excluded by!**/*.pngResources/Textures/Imperial/SCP/nothingtherewpn1.rsi/inhand-left.pngis excluded by!**/*.pngResources/Textures/Imperial/SCP/nothingtherewpn1.rsi/inhand-right.pngis excluded by!**/*.pngResources/Textures/Imperial/SCP/nothingtherewpn2.rsi/icon.pngis excluded by!**/*.pngResources/Textures/Imperial/SCP/nothingtherewpn2.rsi/inhand-left.pngis excluded by!**/*.pngResources/Textures/Imperial/SCP/nothingtherewpn2.rsi/inhand-right.pngis excluded by!**/*.pngResources/Textures/Imperial/SCP/nothingtherewpn2.rsi/jared.pngis excluded by!**/*.pngResources/Textures/Imperial/Seriozha/misc/Customization/nda_cloak.rsi/equipped-NECK.pngis excluded by!**/*.pngResources/Textures/Imperial/Seriozha/misc/Customization/nda_cloak.rsi/icon.pngis excluded by!**/*.pngResources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/equipped-NECK.pngis excluded by!**/*.pngResources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/icon.pngis excluded by!**/*.pngResources/Textures/Imperial/Seriozha/misc/Customization/white_cloak.rsi/equipped-NECK.pngis excluded by!**/*.pngResources/Textures/Imperial/Seriozha/misc/Customization/white_cloak.rsi/icon.pngis excluded by!**/*.png
📒 Files selected for processing (31)
Content.Server/Imperial/SCP/NothingThere/Components/ImperialControlledNothingThereComponent.csContent.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereComponent.csContent.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereGoodbyeComponent.csContent.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThere.ChaseMusic.csContent.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.Arsenal.csContent.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.BodyControl.csContent.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.Egg.csContent.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.PausedMap.csContent.Server/Imperial/SCP/NothingThere/Systems/ImperialNothingThereSystem.csContent.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereEggEvent.csContent.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereEnterBodyEvent.csContent.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereGibBodyEvent.csContent.Shared/Imperial/SCP/NothingThere/Events/ImperialNothingThereGoodbyeDoAfterEvent.csResources/Locale/ru-RU/Imperial/SCP/actions.ftlResources/Locale/ru-RU/Imperial/SCP/dimensionenteraction.ftlResources/Locale/ru-RU/Imperial/SCP/entities.ftlResources/Locale/ru-RU/Imperial/SCP/popup.ftlResources/Locale/ru-RU/Imperial/Seriozha/SCP/locale.ftlResources/Prototypes/Imperial/SCP/Actions/nothingthere.ymlResources/Prototypes/Imperial/SCP/Entities/nothingthere.ymlResources/Prototypes/Imperial/SCP/Entities/weapon.ymlResources/Prototypes/Imperial/SCP/Misc/nothingtherepolymorph.ymlResources/Prototypes/Imperial/Seriozha/misc/misc.ymlResources/Textures/Imperial/SCP/nothingthere1.rsi/meta.jsonResources/Textures/Imperial/SCP/nothingthere2.rsi/meta.jsonResources/Textures/Imperial/SCP/nothingthereegg.rsi/meta.jsonResources/Textures/Imperial/SCP/nothingtherewpn1.rsi/meta.jsonResources/Textures/Imperial/SCP/nothingtherewpn2.rsi/meta.jsonResources/Textures/Imperial/Seriozha/misc/Customization/nda_cloak.rsi/meta.jsonResources/Textures/Imperial/Seriozha/misc/Customization/violet_cloak.rsi/meta.jsonResources/Textures/Imperial/Seriozha/misc/Customization/white_cloak.rsi/meta.json
| public EntityUid OriginalBody = EntityUid.Invalid; | ||
| [DataField("exitSound")] | ||
| public SoundSpecifier ExitSound = new SoundPathSpecifier("/Audio/Imperial/SCP/nothingthere_gibbody.ogg"); | ||
| [DataField("killCount")] | ||
| public int KillCount = 0; |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Не храните runtime-состояние как prototype-конфиг.
По текущему использованию OriginalBody и KillCount меняются только в рантайме. Лучше пометить их как runtime-поля для VV, иначе KillCount можно случайно зашить в YAML, а OriginalBody вообще не видно при отладке.
Based on learnings: In the Imperial SS14 project, fields of components that are not configured via YAML prototypes (runtime state) should be marked with the [ViewVariables] attribute, while fields configured via prototypes should use [DataField].
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@Content.Server/Imperial/SCP/NothingThere/Components/ImperialControlledNothingThereComponent.cs`
around lines 19 - 23, OriginalBody and KillCount are runtime-only state but are
currently marked with [DataField]; remove the [DataField] attributes and instead
annotate these fields with [ViewVariables] (e.g., [ViewVariables] or
[ViewVariables(VVAccess.ReadWrite)] as appropriate) in the
ImperialControlledNothingThereComponent so they are visible/editable in VV and
not treated as prototype-configured values; keep their runtime defaults
(OriginalBody = EntityUid.Invalid, KillCount = 0) and leave ExitSound as the
DataField-configured prototype value.
| using Content.Shared.Mobs.Systems; | ||
| using Content.Shared.Mobs; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Неиспользуемые директивы using.
Content.Shared.Mobs.Systems и Content.Shared.Mobs импортированы, но типы из них не используются в этом файле компонента. Рекомендуется удалить неиспользуемые импорты.
♻️ Предлагаемое исправление
-using Content.Shared.Mobs.Systems;
-using Content.Shared.Mobs;📝 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.
| using Content.Shared.Mobs.Systems; | |
| using Content.Shared.Mobs; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereComponent.cs`
around lines 8 - 9, Файл содержит неиспользуемые директивы using: remove the
unused imports Content.Shared.Mobs.Systems and Content.Shared.Mobs from the top
of the ImperialNothingThereComponent file; locate the
ImperialNothingThereComponent class in the
Content.Server.Imperial.SCP.NothingThere.Components namespace and delete the two
using lines (using Content.Shared.Mobs.Systems; and using Content.Shared.Mobs;)
so only required namespaces remain.
|
|
||
| [DataField("phase")] | ||
| public int Phase = 0; | ||
| public EntProtoId? EggEntityProto = "ImperialSCPNothingThereEgg"; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Отсутствуют атрибуты [DataField] для полей с прототипами.
Поля EggEntityProto, TrueEntityProto, GoodbyeProto и HitProto содержат идентификаторы прототипов, но не имеют атрибута [DataField]. Это означает, что их нельзя переопределить через YAML конфигурацию. Если это намеренно — добавьте [ViewVariables] для отладки, иначе добавьте [DataField].
Based on learnings: "fields configured via prototypes should use [DataField]".
♻️ Предлагаемое исправление
-public EntProtoId? EggEntityProto = "ImperialSCPNothingThereEgg";
+[DataField("eggEntityProto")]
+public EntProtoId? EggEntityProto = "ImperialSCPNothingThereEgg";-public EntProtoId? TrueEntityProto = "ImperialSCPNothingThereTrue";
+[DataField("trueEntityProto")]
+public EntProtoId? TrueEntityProto = "ImperialSCPNothingThereTrue";-public EntProtoId GoodbyeProto = "ImperialNothingThereEmpowerHit";
+[DataField("goodbyeProto")]
+public EntProtoId GoodbyeProto = "ImperialNothingThereEmpowerHit";-public EntProtoId HitProto = "ImperialNothingThereHit";
+[DataField("hitProto")]
+public EntProtoId HitProto = "ImperialNothingThereHit";Also applies to: 55-55, 74-75
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereComponent.cs`
at line 43, Поля компонента ImperialNothingThereComponent — EggEntityProto,
TrueEntityProto, GoodbyeProto и HitProto — содержат идентификаторы прототипов,
но не помечены атрибутом [DataField], из‑за чего их нельзя переопределить через
YAML; откройте класс ImperialNothingThereComponent и добавить атрибут
[DataField] к каждому из этих полей (если их нужно конфигурировать из
прототипов), либо — если пропи́сно намеренно неизменяемо — пометить их
[ViewVariables] для отладки; убедитесь, что имена полей в [DataField("...")]
соответствуют ожидаемым YAML-ключам и что типы (EntProtoId?) остаются без
изменений.
| [DataField("hatchSound")] | ||
| public SoundSpecifier HatchSound = new SoundPathSpecifier("/Audio/Imperial/SCP/nothingthere_hatch.ogg"); | ||
|
|
||
| public bool Empowered = false; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Отсутствуют атрибуты [ViewVariables] для runtime-состояния.
Поля Empowered и NeedGoodbye являются runtime-состоянием (не конфигурируются через YAML), но не имеют атрибута [ViewVariables]. Согласно практикам проекта, runtime state должен быть помечен [ViewVariables] для удобства отладки.
Based on learnings: "fields of components that are not configured via YAML prototypes (runtime state) should be marked with the [ViewVariables] attribute".
♻️ Предлагаемое исправление
-public bool Empowered = false;
+[ViewVariables]
+public bool Empowered = false;-public bool NeedGoodbye = false;
+[ViewVariables]
+public bool NeedGoodbye = false;Also applies to: 78-78
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereComponent.cs`
at line 59, Поля runtime-состояния в компоненте ImperialNothingThereComponent
(`Empowered` и `NeedGoodbye`) не помечены атрибутом [ViewVariables]; добавьте
атрибут [ViewVariables] над определениями этих полей в классе
ImperialNothingThereComponent, чтобы они были видимы в отладке/инспекторах
(оставьте типы и имена полей без изменений).
There was a problem hiding this comment.
Добавьте либо атрибут ViewVariables, либо DataField
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "=== Snippet (1..200) with line numbers ==="
nl -ba Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereComponent.cs | sed -n '1,200p'
echo
echo "=== Grep for target fields (with context) ==="
rg -n -C2 $'\\b(Empowered|NeedGoodbye)\\b' -- Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereComponent.cs || true
Length of output: 84
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
file='Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereComponent.cs'
echo "=== File exists? ==="
if [[ -f "$file" ]]; then
echo "yes: $file"
else
echo "no: $file"
exit 0
fi
echo
echo "=== Content with line numbers (1..240) ==="
# Use awk to add line numbers (nl may not be available)
awk '{printf "%6d %s\n", NR, $0}' "$file" | sed -n '1,240p'
echo
echo "=== Locate Empowered / NeedGoodbye declarations (with 3 lines context) ==="
if command -v rg >/dev/null 2>&1; then
rg -n -C3 $'\\b(Empowered|NeedGoodbye)\\b' -- "$file" || true
else
grep -nE -C3 '\b(Empowered|NeedGoodbye)\b' "$file" || true
fi
echo
echo "=== Search prototypes for empowered/needgoodbye keys to detect YAML-configurability ==="
if command -v rg >/dev/null 2>&1; then
rg -n -i --glob 'Resources/Prototypes/**' -- $'\\b(empowered|needgoodbye)\\b' || true
else
grep -RInEi '\b(empowered|needgoodbye)\b' Resources/Prototypes || true
fi
Length of output: 5538
@The-Fiafi спасибо! Подтвердил по коду и прототипам:
- Line 59: Empowered — без атрибута.
- Line 78: NeedGoodbye — без атрибута.
- В Resources/Prototypes/** нет ключей empowered/needgoodbye для этого компонента (нашлись только «empowered burger», не относящиеся к SCP).
С учётом ранее зафиксированного правила проекта (runtime поля помечаем [ViewVariables]), предлагаю добавить [ViewVariables] к обоим полям.
Минимальное исправление: отметить runtime‑поля [ViewVariables].
Если хотите сделать их настраиваемыми из YAML, скажите — заменю на [DataField("empowered")] и [DataField("needGoodbye")] (или добавлю их вдобавок к [ViewVariables], как уже сделано для EmpowerDamage).
🧠 Learnings used
Learnt from: The-Fiafi
Repo: imperial-space/SS14-public PR: 531
File: Content.Server/Imperial/SCP/ChaseMusic/Components/ImperialSCPChaseMusicComponent.cs:14-16
Timestamp: 2026-01-24T12:55:23.032Z
Learning: In the Imperial SS14 project, fields of components that are not configured via YAML prototypes (runtime state) should be marked with the [ViewVariables] attribute, while fields configured via prototypes should use [DataField]. This guideline applies to all C# component files under Content.Server; review each field to determine whether it’s prototype-configured and assign the appropriate attribute accordingly.
Learnt from: The-Fiafi
Repo: imperial-space/SS14-public PR: 545
File: Content.Server/Imperial/XxRaay/Systems/AnimatronicTargetSystem.cs:21-21
Timestamp: 2026-02-01T14:57:29.328Z
Learning: Enforce C# private field naming: all private fields must start with an underscore and use camelCase (e.g., _transformSystem). This rule applies across the repository (imperial-space/SS14-public) to maintain consistency in all C# files.
Learnt from: The-Fiafi
Repo: imperial-space/SS14-public PR: 565
File: Content.Server/Imperial/XenoGenetcs/ServerXenoGeneticsSystem.cs:16-16
Timestamp: 2026-02-19T18:00:42.014Z
Learning: In C# files across the repository, mark classes as sealed when there is no explicit need for inheritance. This project-wide coding standard (confirmed by The-Fiafi) helps prevent unintended inheritance and encourages explicit design. Exceptions should be made only where inheritance is actually required (e.g., for extensibility, mockable abstraction, or framework constraints). Ensure consistency by auditing classes in Content.Server/Imperial/XenoGenetcs/ServerXenoGeneticsSystem.cs and related files, applying sealed where inheritance is not needed.
Failed to handle agent chat message. Please try again.
| [DataField] | ||
| public bool Used = false; | ||
| public EntProtoId HitProto = "ImperialNothingThereHit"; | ||
| [DataField("empowerSound")] | ||
| public SoundSpecifier EmpowerSound = new SoundPathSpecifier("/Audio/Imperial/SCP/nothingthere_empower.ogg"); |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Разделите prototype-конфиг и runtime-состояние по атрибутам.
Used выглядит как чистый runtime-флаг, а HitProto, если его нужно переопределять из YAML, сейчас вообще не сериализуется. В текущем виде состояние хуже дебажится, а конфиг поля легко потерять молча.
Based on learnings: In the Imperial SS14 project, fields of components that are not configured via YAML prototypes (runtime state) should be marked with the [ViewVariables] attribute, while fields configured via prototypes should use [DataField].
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@Content.Server/Imperial/SCP/NothingThere/Components/ImperialNothingThereGoodbyeComponent.cs`
around lines 6 - 10, The field Used is a runtime-only flag and should not be a
prototype-configured DataField: remove the [DataField] attribute from Used and
mark it with [ViewVariables] instead; conversely ensure HitProto (EntProtoId
HitProto = "ImperialNothingThereHit") is marked with [DataField] (e.g.
[DataField("hitProto")]) so it’s serializable from YAML; leave EmpowerSound
as-is. Modify these attributes on the ImperialNothingThereGoodbyeComponent to
separate runtime state (Used) from prototype-configurable fields (HitProto,
EmpowerSound).
| {$name} попал в ваше измерение! Удачной охоты ^_^ No newline at end of file | ||
| {$name} попал в ваше измерение! Удачной охоты ^_^ | ||
|
|
||
| nothingthere-hammaggotson-haha = [color=red][font size=14][bold]Вы чувствуете, что вы нашли то, чего искали. Ваше истинное "Я".[/font] |
There was a problem hiding this comment.
Незакрытый тег [/font] в строке локализации.
В строке nothingthere-hammaggotson-haha открыт тег [font size=14], но отсутствует закрывающий [/font]. Это может вызвать проблемы с форматированием текста в игре.
🐛 Предлагаемое исправление
-nothingthere-hammaggotson-haha = [color=red][font size=14][bold]Вы чувствуете, что вы нашли то, чего искали. Ваше истинное "Я".[/font]
+nothingthere-hammaggotson-haha = [color=red][font size=14][bold]Вы чувствуете, что вы нашли то, чего искали. Ваше истинное "Я".[/bold][/font][/color]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Resources/Locale/ru-RU/Imperial/SCP/dimensionenteraction.ftl` at line 6, В
строке ключа nothingthere-hammaggotson-haha исправьте незакрытые форматирующие
теги: корректно закройте вложенные теги в обратном порядке их открытия (например
добавьте недостающие [/bold], затем [/font], затем [/color] или соответствующие
закрывающие теги), чтобы все открытые [color=red], [font size=14], [bold] были
закрыты.
| ent-CloakNDADelexor = Плащ командования Недр | ||
| .desc = Выдается только самым значимым сотрудникам Недр. | ||
| ent-CloakNDAWhite = Подозрительный плащ Недр | ||
| .desc = Помните, Совет всегда видит и слышит вас. Для удобности и компактности в плаще уже вшиты диктофон и записывающее Ауидо устройство. Выдаётся всем, кому не лень. |
There was a problem hiding this comment.
Исправьте опечатку в описании ent-CloakNDAWhite.
На Line 198, вероятно, опечатка: Ауидо → аудио (и лучше Для удобства, а не Для удобности).
Предлагаемая правка
- .desc = Помните, Совет всегда видит и слышит вас. Для удобности и компактности в плаще уже вшиты диктофон и записывающее Ауидо устройство. Выдаётся всем, кому не лень.
+ .desc = Помните, Совет всегда видит и слышит вас. Для удобства и компактности в плаще уже вшиты диктофон и записывающее аудио-устройство. Выдаётся всем, кому не лень.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Resources/Locale/ru-RU/Imperial/Seriozha/SCP/locale.ftl` at line 198, В
описании локали для ent-CloakNDAWhite (ключ .desc в locale.ftl) исправьте
опечатку и формулировку: заменить «Ауидо» на «аудио» и «Для удобности» на «Для
удобства», т.е. обновить значение .desc соответствующего объекта
(ent-CloakNDAWhite) на корректную фразу с этими правками.
| - type: entity | ||
| id: ImperialNothingThereEnterBodyAction | ||
| name: Control body | ||
| description: cubism | ||
| components: | ||
| - type: Action | ||
| icon: { sprite : Mobs/Species/Human/organs.rsi, state: "brain" } | ||
| iconOn: { sprite : Mobs/Species/Human/organs.rsi, state: "brain" } | ||
| priority: 1 | ||
| - type: TargetAction | ||
| - type: EntityTargetAction | ||
| event: !type:ImperialNothingThereEnterBodyEvent |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Отсутствует parent: BaseAction для согласованности с другими действиями.
Действия ImperialNothingThereGibBodyAction, ImperialNothingThereEggAction и ImperialNothingThereHelloAction наследуются от BaseAction, но ImperialNothingThereEnterBodyAction — нет. Это может привести к отсутствию базовых компонентов или настроек по умолчанию.
♻️ Предлагаемое исправление
- type: entity
+ parent: BaseAction
id: ImperialNothingThereEnterBodyAction
name: Control body
description: cubism📝 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.
| - type: entity | |
| id: ImperialNothingThereEnterBodyAction | |
| name: Control body | |
| description: cubism | |
| components: | |
| - type: Action | |
| icon: { sprite : Mobs/Species/Human/organs.rsi, state: "brain" } | |
| iconOn: { sprite : Mobs/Species/Human/organs.rsi, state: "brain" } | |
| priority: 1 | |
| - type: TargetAction | |
| - type: EntityTargetAction | |
| event: !type:ImperialNothingThereEnterBodyEvent | |
| - type: entity | |
| parent: BaseAction | |
| id: ImperialNothingThereEnterBodyAction | |
| name: Control body | |
| description: cubism | |
| components: | |
| - type: Action | |
| icon: { sprite : Mobs/Species/Human/organs.rsi, state: "brain" } | |
| iconOn: { sprite : Mobs/Species/Human/organs.rsi, state: "brain" } | |
| priority: 1 | |
| - type: TargetAction | |
| - type: EntityTargetAction | |
| event: !type:ImperialNothingThereEnterBodyEvent |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Resources/Prototypes/Imperial/SCP/Actions/nothingthere.yml` around lines 1 -
12, The action ImperialNothingThereEnterBodyAction is missing parent: BaseAction
causing it to not inherit default components; add parent: BaseAction to the
ImperialNothingThereEnterBodyAction YAML entry so it matches
ImperialNothingThereGibBodyAction, ImperialNothingThereEggAction and
ImperialNothingThereHelloAction, then verify that any required base components
(e.g., Action, TargetAction, EntityTargetAction) are not duplicated or
contradicted after inheritance and adjust/remove explicit component declarations
if they conflict with BaseAction defaults.
| - type: entity | ||
| id: ImperialNothingThereProjectileAction | ||
| name: Throw bone shard | ||
| description: yeah. | ||
| components: | ||
| - type: Action | ||
| useDelay: 5 | ||
| itemIconStyle: BigAction | ||
| sound: !type:SoundPathSpecifier | ||
| path: /Audio/Imperial/SCP/nothingthere_hello.ogg | ||
| icon: { sprite : Objects/Materials/materials.rsi, state: "bones" } | ||
| - type: TargetAction | ||
| checkCanAccess: false | ||
| range: 60 | ||
| - type: WorldTargetAction | ||
| event: !type:ProjectileSpellEvent | ||
| prototype: ImperialProjectileBoneShard |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Отсутствует parent: BaseAction для ImperialNothingThereProjectileAction.
По аналогии с другими действиями в этом файле, рекомендуется добавить наследование от BaseAction для согласованности.
♻️ Предлагаемое исправление
- type: entity
+ parent: BaseAction
id: ImperialNothingThereProjectileAction
name: Throw bone shard
description: yeah.📝 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.
| - type: entity | |
| id: ImperialNothingThereProjectileAction | |
| name: Throw bone shard | |
| description: yeah. | |
| components: | |
| - type: Action | |
| useDelay: 5 | |
| itemIconStyle: BigAction | |
| sound: !type:SoundPathSpecifier | |
| path: /Audio/Imperial/SCP/nothingthere_hello.ogg | |
| icon: { sprite : Objects/Materials/materials.rsi, state: "bones" } | |
| - type: TargetAction | |
| checkCanAccess: false | |
| range: 60 | |
| - type: WorldTargetAction | |
| event: !type:ProjectileSpellEvent | |
| prototype: ImperialProjectileBoneShard | |
| - type: entity | |
| parent: BaseAction | |
| id: ImperialNothingThereProjectileAction | |
| name: Throw bone shard | |
| description: yeah. | |
| components: | |
| - type: Action | |
| useDelay: 5 | |
| itemIconStyle: BigAction | |
| sound: !type:SoundPathSpecifier | |
| path: /Audio/Imperial/SCP/nothingthere_hello.ogg | |
| icon: { sprite : Objects/Materials/materials.rsi, state: "bones" } | |
| - type: TargetAction | |
| checkCanAccess: false | |
| range: 60 | |
| - type: WorldTargetAction | |
| event: !type:ProjectileSpellEvent | |
| prototype: ImperialProjectileBoneShard |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Resources/Prototypes/Imperial/SCP/Actions/nothingthere.yml` around lines 52 -
68, The entity ImperialNothingThereProjectileAction is missing inheritance from
BaseAction; update the entity definition for
ImperialNothingThereProjectileAction to include a parent: BaseAction entry
(matching other actions in the file) so it inherits base action behavior while
keeping its existing components (Action, TargetAction, WorldTargetAction)
intact.
| - type: entity | ||
| parent: ClothingNeckBase | ||
| id: CloakNDADelexor | ||
| name: vampire cloak | ||
| suffix: Seriozha, Кастомизация, Недра | ||
| description: Worn by high ranking vampires of the transylvanian society of vampires. | ||
| components: | ||
| - type: Sprite | ||
| sprite: Imperial/Seriozha/misc/Customization/nda_cloak.rsi | ||
|
|
||
| - type: entity | ||
| parent: ClothingNeckBase | ||
| id: CloakNDAWhite | ||
| name: vampire cloak | ||
| suffix: Seriozha, Кастомизация, Недра | ||
| description: Worn by high ranking vampires of the transylvanian society of vampires. | ||
| components: | ||
| - type: Sprite | ||
| sprite: Imperial/Seriozha/misc/Customization/white_cloak.rsi |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Снизьте дублирование в новых прототипах плащей.
CloakNDADelexor и CloakNDAWhite повторяют одни и те же поля; лучше вынести их в общий абстрактный parent.
Вариант рефактора
+- type: entity
+ abstract: true
+ parent: ClothingNeckBase
+ id: CloakNDABase
+ name: vampire cloak
+ suffix: Seriozha, Кастомизация, Недра
+ description: Worn by high ranking vampires of the transylvanian society of vampires.
+ components:
+ - type: Sprite
+
- type: entity
- parent: ClothingNeckBase
+ parent: CloakNDABase
id: CloakNDADelexor
- name: vampire cloak
- suffix: Seriozha, Кастомизация, Недра
- description: Worn by high ranking vampires of the transylvanian society of vampires.
components:
- type: Sprite
sprite: Imperial/Seriozha/misc/Customization/nda_cloak.rsi
- type: entity
- parent: ClothingNeckBase
+ parent: CloakNDABase
id: CloakNDAWhite
- name: vampire cloak
- suffix: Seriozha, Кастомизация, Недра
- description: Worn by high ranking vampires of the transylvanian society of vampires.
components:
- type: Sprite
sprite: Imperial/Seriozha/misc/Customization/white_cloak.rsi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Resources/Prototypes/Imperial/Seriozha/misc/misc.yml` around lines 50 - 68,
Вынести общие поля для CloakNDADelexor и CloakNDAWhite в общий абстрактный
parent: создайте новый прототип (например CloakNDABase) с parent:
ClothingNeckBase и общими полями name, suffix, description и общим
components-секцией за исключением уникального sprite; затем обновите
CloakNDADelexor и CloakNDAWhite чтобы они наследовали от CloakNDABase и
оставляли только id и уникальный Sprite (sprite:
Imperial/Seriozha/misc/Customization/nda_cloak.rsi и sprite:
Imperial/Seriozha/misc/Customization/white_cloak.rsi соответственно).
| { | ||
| [DataField("gibBodyAction")] | ||
| public EntProtoId GibBodyAction = "ImperialNothingThereGibBodyAction"; | ||
| [AutoNetworkedField, DataField("gibBodyEntity")] |
There was a problem hiding this comment.
Ваш компонент не помечен сетевым
| [RegisterComponent] | ||
| public sealed partial class ImperialControlledNothingThereComponent : Component | ||
| { | ||
| [DataField("gibBodyAction")] |
| public EntityUid? GibBodyEntity; | ||
|
|
||
| public EntityUid OriginalBody = EntityUid.Invalid; | ||
| [DataField("exitSound")] |
| public EntityUid OriginalBody = EntityUid.Invalid; | ||
| [DataField("exitSound")] | ||
| public SoundSpecifier ExitSound = new SoundPathSpecifier("/Audio/Imperial/SCP/nothingthere_gibbody.ogg"); | ||
| [DataField("killCount")] |
There was a problem hiding this comment.
Это не должно быть датафилдом
| [RegisterComponent] | ||
| public sealed partial class ImperialNothingThereComponent : Component | ||
| { | ||
| [DataField("chaseSound")] |
| if (_mobStateSystem.IsDead(uid) || _mobStateSystem.IsCritical(uid)) | ||
| { | ||
| var transformB = Transform(uid); | ||
| var coords = transformB.Coordinates; |
| return gibbed; | ||
| } | ||
|
|
||
| private const float GibletLaunchImpulse = 150; |
| } | ||
|
|
||
| private const float GibletLaunchImpulse = 150; | ||
| private const float GibletLaunchImpulseVariance = 3; |
| var hands = EnsureComp<HandsComponent>(uid); | ||
| if (_hands.TryGetEmptyHand((uid, hands), out var emptyHand)) | ||
| { | ||
| var hit = EntityUid.Invalid; |
There was a problem hiding this comment.
Никогда не используйте таким образом EntityUid.Invalid. Для этого есть null-able типы
| public bool NeedGoodbye = false; | ||
| [DataField("projectileAction")] | ||
| public EntProtoId ProjectileAction = "ImperialNothingThereProjectileAction"; | ||
| [AutoNetworkedField, DataField("projectileEntity")] |
There was a problem hiding this comment.
Ваш компонент не помечен сетевым
The-Fiafi
left a comment
There was a problem hiding this comment.
Уберите у датафилдов передачу строки.
| [DataField("hatchSound")] | ||
| public SoundSpecifier HatchSound = new SoundPathSpecifier("/Audio/Imperial/SCP/nothingthere_hatch.ogg"); | ||
|
|
||
| public bool Empowered = false; |
There was a problem hiding this comment.
Добавьте либо атрибут ViewVariables, либо DataField
| public EntProtoId HitProto = "ImperialNothingThereHit"; | ||
| [DataField] | ||
| public bool NeedItems = false; | ||
| public bool NeedGoodbye = false; |
There was a problem hiding this comment.
Добавьте либо атрибут ViewVariables, либо DataField
| [AutoNetworkedField, DataField("gibBodyEntity")] | ||
| public EntityUid? GibBodyEntity; | ||
|
|
||
| public EntityUid OriginalBody = EntityUid.Invalid; |
There was a problem hiding this comment.
Добавьте либо атрибут ViewVariables, либо DataField
|
Апстримните ветку |
О ПР`е
Тип: feat
Изменения: Ивентовый контент
Технические детали
Нет
Изменения кода официальных разработчиков
Нет
Summary by CodeRabbit
Изменения в релизе