[ADD] One psionic ability - #1109
Conversation
|
RSI Diff Bot; head commit bae8512 merging into 5d329d8 Resources/Textures/_White/Objects/Weapons/Guns/Launchers/psionic_hook_launcher.rsi
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughДобавлена псионическая способность «Крюк»: новые action-события и do-after, сетевые компоненты для крюка и снаряда, системы управления спавном/деспауном и поведением снаряда (выстрел, попадание, возврат), прототипы оружия/снаряда, локализация и метаданные текстур. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested labels
Suggested reviewers
🚥 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. ✨ 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 |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (3)
Resources/Textures/_White/Objects/Weapons/Guns/Launchers/psionic_hook_launcher.rsi/meta.json (1)
5-27: Непоследовательное форматирование JSON.Отступы в массиве
states(строки 9-27) отличаются от остальной части файла (строки 2-8). Рекомендуется использовать единообразное форматирование.♻️ Предлагаемое исправление
{ "version": 1, "license": "CC-BY-SA-3.0", "copyright": "by kekoven1 (github)", "size": { "x": 32, "y": 32 }, - "states": [ - { - "name": "icon" - }, - { - "name": "projectile" - }, - { - "name": "rope" - }, - { - "name": "inhand-right", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - } - ] + "states": [ + { + "name": "icon" + }, + { + "name": "projectile" + }, + { + "name": "rope" + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + } + ] }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Resources/Textures/_White/Objects/Weapons/Guns/Launchers/psionic_hook_launcher.rsi/meta.json` around lines 5 - 27, Массив "states" имеет несоответствующие отступы; приведи форматирование блока "states" и его элементов ("icon", "projectile", "rope", "inhand-right", "inhand-left") в соответствие с остальной частью файла (тот же уровень отступов как у поля "size"), исправив лишние пробелы/отступы перед "[" и каждой записи объекта, сохранив существующую JSON-структуру и порядок полей.Content.Shared/_White/Psionics/Hook/PsionicHookPowerComponent.cs (1)
1-2: Неиспользуемые импорты.Импорты
Content.Shared.HumanoidиContent.Shared.Preferencesне используются в данном компоненте и могут быть удалены.♻️ Предлагаемое исправление
-using Content.Shared.Humanoid; -using Content.Shared.Preferences; using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Utility;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Shared/_White/Psionics/Hook/PsionicHookPowerComponent.cs` around lines 1 - 2, В файле PsionicHookPowerComponent.cs в компоненте PsionicHookPowerComponent обнаружены неиспользуемые импорты Content.Shared.Humanoid и Content.Shared.Preferences — удалите эти using-директивы из верхней части файла (уберите упоминания Content.Shared.Humanoid и Content.Shared.Preferences), затем пересоберите/прогоните анализатор, чтобы убедиться, что больше нет неиспользуемых зависимостей.Content.Shared/_White/Psionics/Hook/PsionicHookComponent.cs (1)
12-14: Исправьте опечатку в сериализуемом имени поля, пока оно новое.
HookJointSpiteвыглядит как typo и одновременно задаёт имя для[DataField]. Пока на это поле ещё не завязались прототипы и внешний код, безопаснее переименовать его вHookJointSprite.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Shared/_White/Psionics/Hook/PsionicHookComponent.cs` around lines 12 - 14, Rename the serializable field HookJointSpite in PsionicHookComponent to HookJointSprite (update the field name and any references) so the [DataField] uses the corrected name; ensure the SpriteSpecifier initialization and ViewVariables attribute remain unchanged and update any usages of HookJointSpite elsewhere in the codebase to the new identifier HookJointSprite.
🤖 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/_White/Psionics/Hook/HookPowerSystem.cs`:
- Around line 23-27: The component currently only removes component.Hook during
repeated use (OnPowerUse) so if PsionicHookPowerComponent is removed another way
the WeaponPsionicHook entity can remain; add cleanup by subscribing to the
component shutdown/removal event in Initialize (e.g.
SubscribeLocalEvent<PsionicHookPowerComponent,
ComponentShutdown>(OnHookComponentShutdown)) and implement
OnHookComponentShutdown(PsionicHookPowerComponent component, ComponentShutdown
args) to check component.Hook, forcibly delete that entity (ensure you handle
entity validity and Unremoveable state using the entity manager
delete/force-delete API), and then set component.Hook = null to avoid dangling
references; keep existing OnPowerUse and OnUncuff intact.
- Around line 91-95: Проблема: код читает CuffableComponent.LastAddedCuffs без
проверки наличия наручников, что может привести к выходу за границы если цель
уже раскована; исправьте в методе где используется
TryComp<CuffableComponent>(uid, out var cuffs) — после успешного получения cuffs
убедитесь, что контейнер наручников не пуст (например проверкой Count/IsEmpty
или наличия LastAddedCuffs безопасным способом) перед обращением к
LastAddedCuffs и вызовом _cuffs.Uncuff(uid, uid, lastAddedCuffs); если пустой —
просто вернуть/пропустить операцию do-after.
- Around line 12-14: The SpawnImplantSystem is performing world-changing actions
in shared code; move it into the server assembly and mark it server-only:
relocate the class SpawnImplantSystem from Content.Shared to Content.Server,
change its namespace to Content.Server._White.Psionics.Abilities, update any
using directives, and ensure it is compiled only in the server project; keep
logic that calls SpawnEntity, Del, TryPickupAnyHand and PlayPvs (and which
mutates component.Hook or spawns entities) on the server side and remove/replace
any client-side hooks or event handlers that could run on clients to avoid
prediction/duplication of sound and state. Ensure any registrations/DI that
referenced the old shared system are updated to the new server namespace so the
system runs only on the server.
In `@Content.Shared/_White/Psionics/Hook/HookSystem.cs`:
- Around line 94-105: The current branch only treats entities with the "Wall"
tag as surfaces to pull the shooter toward, causing hits on other stationary
things (doors, windows, vehicles) to fall through to the _throw branch; update
the condition in HookSystem (around Transform(args.Target), the
_tags.HasTag(args.Target, "Wall") check and the consequent branches) to detect
stationary/anchored/solid surfaces instead of only the "Wall" tag—for example
check the target's physics/rigidbody/anchored state or existence of a
Static/Immovable body (or a dedicated "Stationary" tag) and, when that test
passes, perform the pull (use shooterPos/targetPos direction * power * 2 and
_throw.TryThrow(shooter,..., hookComp.BasePower, shooter)); otherwise keep the
current fallback behavior that calls _layingDown.TryLieDown(args.Target) and
_throw.TryThrow(args.Target,...). Ensure you reference Transform(args.Target),
_tags.HasTag, _layingDown.TryLieDown, _throw.TryThrow, hookComp.BasePower,
args.Target and shooter when making the change.
---
Nitpick comments:
In `@Content.Shared/_White/Psionics/Hook/PsionicHookComponent.cs`:
- Around line 12-14: Rename the serializable field HookJointSpite in
PsionicHookComponent to HookJointSprite (update the field name and any
references) so the [DataField] uses the corrected name; ensure the
SpriteSpecifier initialization and ViewVariables attribute remain unchanged and
update any usages of HookJointSpite elsewhere in the codebase to the new
identifier HookJointSprite.
In `@Content.Shared/_White/Psionics/Hook/PsionicHookPowerComponent.cs`:
- Around line 1-2: В файле PsionicHookPowerComponent.cs в компоненте
PsionicHookPowerComponent обнаружены неиспользуемые импорты
Content.Shared.Humanoid и Content.Shared.Preferences — удалите эти
using-директивы из верхней части файла (уберите упоминания
Content.Shared.Humanoid и Content.Shared.Preferences), затем
пересоберите/прогоните анализатор, чтобы убедиться, что больше нет
неиспользуемых зависимостей.
In
`@Resources/Textures/_White/Objects/Weapons/Guns/Launchers/psionic_hook_launcher.rsi/meta.json`:
- Around line 5-27: Массив "states" имеет несоответствующие отступы; приведи
форматирование блока "states" и его элементов ("icon", "projectile", "rope",
"inhand-right", "inhand-left") в соответствие с остальной частью файла (тот же
уровень отступов как у поля "size"), исправив лишние пробелы/отступы перед "[" и
каждой записи объекта, сохранив существующую JSON-структуру и порядок полей.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: fe4a2475-bf26-4ff5-837a-49e801e47bbd
⛔ Files ignored due to path filters (6)
Resources/Textures/_White/Interface/Actions/psionic_hook.rsi/icon.pngis excluded by!**/*.pngResources/Textures/_White/Objects/Weapons/Guns/Launchers/psionic_hook_launcher.rsi/icon.pngis excluded by!**/*.pngResources/Textures/_White/Objects/Weapons/Guns/Launchers/psionic_hook_launcher.rsi/inhand-left.pngis excluded by!**/*.pngResources/Textures/_White/Objects/Weapons/Guns/Launchers/psionic_hook_launcher.rsi/inhand-right.pngis excluded by!**/*.pngResources/Textures/_White/Objects/Weapons/Guns/Launchers/psionic_hook_launcher.rsi/projectile.pngis excluded by!**/*.pngResources/Textures/_White/Objects/Weapons/Guns/Launchers/psionic_hook_launcher.rsi/rope.pngis excluded by!**/*.png
📒 Files selected for processing (13)
Content.Shared/_White/Actions/Events/PsionicHookActionEvent.csContent.Shared/_White/Psionics/Hook/HookPowerSystem.csContent.Shared/_White/Psionics/Hook/HookSystem.csContent.Shared/_White/Psionics/Hook/PsionicHookComponent.csContent.Shared/_White/Psionics/Hook/PsionicHookPowerComponent.csResources/Locale/ru-RU/_white/abilities/psionic.ftlResources/Locale/ru-RU/_white/weapons/ranged/launchers.ftlResources/Prototypes/_White/Actions/psionics.ymlResources/Prototypes/_White/Entities/Objects/Weapons/Guns/Launchers/launchers.ymlResources/Prototypes/_White/Entities/Objects/Weapons/Guns/Projectiles/projectiles.ymlResources/Prototypes/_White/Psionics/psionics.ymlResources/Textures/_White/Interface/Actions/psionic_hook.rsi/meta.jsonResources/Textures/_White/Objects/Weapons/Guns/Launchers/psionic_hook_launcher.rsi/meta.json
| public override void Initialize() | ||
| { | ||
| SubscribeLocalEvent<PsionicHookPowerComponent, PsionicHookPowerActionEvent>(OnPowerUse); | ||
| SubscribeLocalEvent<CuffableComponent, PsionicUncuffDoAfterEvent>(OnUncuff); | ||
| } |
There was a problem hiding this comment.
Добавьте очистку уже призванного хука при снятии способности.
Сейчас component.Hook удаляется только при повторном использовании action. Если PsionicHookPowerComponent снимут другим путём, ссылка потеряется, а WeaponPsionicHook останется в мире или в руке; с учётом Unremoveable это может навсегда занять слот руки.
Возможный вариант
public override void Initialize()
{
SubscribeLocalEvent<PsionicHookPowerComponent, PsionicHookPowerActionEvent>(OnPowerUse);
SubscribeLocalEvent<CuffableComponent, PsionicUncuffDoAfterEvent>(OnUncuff);
+ SubscribeLocalEvent<PsionicHookPowerComponent, ComponentShutdown>(OnHookPowerShutdown);
}
+private void OnHookPowerShutdown(EntityUid uid, PsionicHookPowerComponent component, ComponentShutdown args)
+{
+ if (component.Hook is not { } hook || Deleted(hook))
+ return;
+
+ QueueDel(hook);
+ component.Hook = null;
+}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public override void Initialize() | |
| { | |
| SubscribeLocalEvent<PsionicHookPowerComponent, PsionicHookPowerActionEvent>(OnPowerUse); | |
| SubscribeLocalEvent<CuffableComponent, PsionicUncuffDoAfterEvent>(OnUncuff); | |
| } | |
| public override void Initialize() | |
| { | |
| SubscribeLocalEvent<PsionicHookPowerComponent, PsionicHookPowerActionEvent>(OnPowerUse); | |
| SubscribeLocalEvent<CuffableComponent, PsionicUncuffDoAfterEvent>(OnUncuff); | |
| SubscribeLocalEvent<PsionicHookPowerComponent, ComponentShutdown>(OnHookPowerShutdown); | |
| } | |
| private void OnHookPowerShutdown(EntityUid uid, PsionicHookPowerComponent component, ComponentShutdown args) | |
| { | |
| if (component.Hook is not { } hook || Deleted(hook)) | |
| return; | |
| QueueDel(hook); | |
| component.Hook = null; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Content.Shared/_White/Psionics/Hook/HookPowerSystem.cs` around lines 23 - 27,
The component currently only removes component.Hook during repeated use
(OnPowerUse) so if PsionicHookPowerComponent is removed another way the
WeaponPsionicHook entity can remain; add cleanup by subscribing to the component
shutdown/removal event in Initialize (e.g.
SubscribeLocalEvent<PsionicHookPowerComponent,
ComponentShutdown>(OnHookComponentShutdown)) and implement
OnHookComponentShutdown(PsionicHookPowerComponent component, ComponentShutdown
args) to check component.Hook, forcibly delete that entity (ensure you handle
entity validity and Unremoveable state using the entity manager
delete/force-delete API), and then set component.Hook = null to avoid dangling
references; keep existing OnPowerUse and OnUncuff intact.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
Content.Shared/_White/Psionics/Hook/HookSystem.cs (1)
96-96:⚠️ Potential issue | 🔴 CriticalКритическая опечатка:
Achorned→Anchored.Сборка падает из-за опечатки в названии свойства.
TransformComponentне содержитAchorned, правильное название —Anchored.🐛 Исправление
- if (_tags.HasTag(args.Target, "Wall") || transform.Achorned) + if (_tags.HasTag(args.Target, "Wall") || transform.Anchored)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Shared/_White/Psionics/Hook/HookSystem.cs` at line 96, The condition in HookSystem.cs uses a misspelled property transform.Achorned which causes a build error; change it to the correct TransformComponent property name transform.Anchored (i.e., replace "Achorned" with "Anchored") in the if condition that checks _tags.HasTag(args.Target, "Wall") || transform.Achorned so the code reads _tags.HasTag(args.Target, "Wall") || transform.Anchored; ensure you import or reference the correct TransformComponent type if needed.
🧹 Nitpick comments (3)
Content.Shared/_White/Psionics/Hook/HookSystem.cs (3)
86-87: Избыточная проверкаprojectile.Shooterна null.Эта проверка уже выполнена в методе
OnProjectileHit(строка 66) перед вызовомHookThrow.♻️ Предлагаемое исправление
private void HookThrow(Entity<ProjectilePsionicHookComponent> ent, ProjectileHitEvent args, ProjectileComponent projectile, PsionicComponent psionic) { var power = MathF.Pow(psionic.CurrentAmplification, 1.3f); var hookComp = ent.Comp; - if (projectile.Shooter is null) - return; - var shooter = projectile.Shooter.Value;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Shared/_White/Psionics/Hook/HookSystem.cs` around lines 86 - 87, В методе HookThrow удалите избыточную проверку на null для projectile.Shooter, т.к. она уже проверяется в OnProjectileHit перед вызовом HookThrow; откройте HookThrow и удалите блок "if (projectile.Shooter is null) return;" (или эквивалентную проверку), оставив логику обработки попадания без дублируемой проверки.
11-11: Неиспользуемый импортMathNet.Numerics.Providers.LinearAlgebra.В файле используется только
MathF.PowизSystem, а не функции из MathNet. Этот импорт можно удалить.🧹 Предлагаемое исправление
-using MathNet.Numerics.Providers.LinearAlgebra;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Shared/_White/Psionics/Hook/HookSystem.cs` at line 11, В файле HookSystem.cs есть неиспользуемый импорт MathNet.Numerics.Providers.LinearAlgebra — удалите строку using MathNet.Numerics.Providers.LinearAlgebra; и оставьте только нужные пространства имён (в коде используются MathF.Pow из System), чтобы убрать ненужную зависимость и предупреждение компилятора.
50-59: Избыточный вызовDirty(uid, component)после цикла.
Dirtyуже вызывается внутри цикла на строке 50. Повторный вызов на строке 59 не нужен, если цикл выполнился хотя бы один раз.♻️ Предлагаемое исправление
Dirty(shotUid.Value, visuals); } - - Dirty(uid, component); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Shared/_White/Psionics/Hook/HookSystem.cs` around lines 50 - 59, The trailing redundant call to Dirty(uid, component) after the loop should be removed because Dirty is already invoked inside the loop; locate the block that sets up visuals using EnsureComp<JointVisualsComponent>(shotUid.Value), assigns visuals.Sprite/OffsetA/Target and calls Dirty(shotUid.Value, visuals), and simply delete the extra Dirty(uid, component) after that block (or, if you intended to handle the case where the loop never executed, wrap that call in a conditional that checks whether any iteration occurred), ensuring only the necessary Dirty calls remain.
🤖 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/_White/Psionics/Hook/HookSystem.cs`:
- Around line 128-135: Переписать участок так, чтобы перед вызовом
_gun.ChangeBasicEntityAmmoCount(gun, 1) выполнялась проверка существования
сущности gun: убедиться, что component.Gun не равен null и сущность всё ещё
существует (например через EntityManager.EntityExists(gun) или соответствующий
метод в текущем контексте), и только после этого вызывать
ChangeBasicEntityAmmoCount; также сохранить текущую логику с
TryComp<PsionicHookComponent>(gun, out var hookComp) и Dirty(gun, hookComp) без
изменений.
---
Duplicate comments:
In `@Content.Shared/_White/Psionics/Hook/HookSystem.cs`:
- Line 96: The condition in HookSystem.cs uses a misspelled property
transform.Achorned which causes a build error; change it to the correct
TransformComponent property name transform.Anchored (i.e., replace "Achorned"
with "Anchored") in the if condition that checks _tags.HasTag(args.Target,
"Wall") || transform.Achorned so the code reads _tags.HasTag(args.Target,
"Wall") || transform.Anchored; ensure you import or reference the correct
TransformComponent type if needed.
---
Nitpick comments:
In `@Content.Shared/_White/Psionics/Hook/HookSystem.cs`:
- Around line 86-87: В методе HookThrow удалите избыточную проверку на null для
projectile.Shooter, т.к. она уже проверяется в OnProjectileHit перед вызовом
HookThrow; откройте HookThrow и удалите блок "if (projectile.Shooter is null)
return;" (или эквивалентную проверку), оставив логику обработки попадания без
дублируемой проверки.
- Line 11: В файле HookSystem.cs есть неиспользуемый импорт
MathNet.Numerics.Providers.LinearAlgebra — удалите строку using
MathNet.Numerics.Providers.LinearAlgebra; и оставьте только нужные пространства
имён (в коде используются MathF.Pow из System), чтобы убрать ненужную
зависимость и предупреждение компилятора.
- Around line 50-59: The trailing redundant call to Dirty(uid, component) after
the loop should be removed because Dirty is already invoked inside the loop;
locate the block that sets up visuals using
EnsureComp<JointVisualsComponent>(shotUid.Value), assigns
visuals.Sprite/OffsetA/Target and calls Dirty(shotUid.Value, visuals), and
simply delete the extra Dirty(uid, component) after that block (or, if you
intended to handle the case where the loop never executed, wrap that call in a
conditional that checks whether any iteration occurred), ensuring only the
necessary Dirty calls remain.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 1f8c69b6-b6b7-4a8e-bfb7-fb430d778765
📒 Files selected for processing (2)
Content.Shared/_White/Psionics/Hook/HookPowerSystem.csContent.Shared/_White/Psionics/Hook/HookSystem.cs
🚧 Files skipped from review as they are similar to previous changes (1)
- Content.Shared/_White/Psionics/Hook/HookPowerSystem.cs
| var gun = component.Gun; | ||
| if (TryComp<PsionicHookComponent>(gun, out var hookComp)) | ||
| { | ||
| hookComp.Projectile = null; | ||
| Dirty(gun, hookComp); | ||
| } | ||
|
|
||
| _gun.ChangeBasicEntityAmmoCount(gun, 1); |
There was a problem hiding this comment.
Отсутствует проверка существования сущности gun перед изменением боеприпасов.
Если gun был удалён, но у него не было PsionicHookComponent, код всё равно попытается вызвать ChangeBasicEntityAmmoCount на несуществующей сущности.
🛡️ Предлагаемое исправление
var gun = component.Gun;
+ if (Deleted(gun))
+ {
+ QueueDel(uid);
+ return;
+ }
+
if (TryComp<PsionicHookComponent>(gun, out var hookComp))
{
hookComp.Projectile = null;
Dirty(gun, hookComp);
}
_gun.ChangeBasicEntityAmmoCount(gun, 1);📝 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.
| var gun = component.Gun; | |
| if (TryComp<PsionicHookComponent>(gun, out var hookComp)) | |
| { | |
| hookComp.Projectile = null; | |
| Dirty(gun, hookComp); | |
| } | |
| _gun.ChangeBasicEntityAmmoCount(gun, 1); | |
| var gun = component.Gun; | |
| if (Deleted(gun)) | |
| { | |
| QueueDel(uid); | |
| return; | |
| } | |
| if (TryComp<PsionicHookComponent>(gun, out var hookComp)) | |
| { | |
| hookComp.Projectile = null; | |
| Dirty(gun, hookComp); | |
| } | |
| _gun.ChangeBasicEntityAmmoCount(gun, 1); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Content.Shared/_White/Psionics/Hook/HookSystem.cs` around lines 128 - 135,
Переписать участок так, чтобы перед вызовом _gun.ChangeBasicEntityAmmoCount(gun,
1) выполнялась проверка существования сущности gun: убедиться, что component.Gun
не равен null и сущность всё ещё существует (например через
EntityManager.EntityExists(gun) или соответствующий метод в текущем контексте),
и только после этого вызывать ChangeBasicEntityAmmoCount; также сохранить
текущую логику с TryComp<PsionicHookComponent>(gun, out var hookComp) и
Dirty(gun, hookComp) без изменений.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Resources/Prototypes/Psionics/PsionicPowerPool.yml`:
- Line 21: Перенесите WWDP-специфичную запись PsionicHookPower из базового
PsionicPowerPool.yml в _White-слой: удалите добавление PsionicHookPower (тот
самый "PsionicHookPower: 1" в блоках weight) из основного
Resources/Prototypes/Psionics/PsionicPowerPool.yml и добавьте ту же запись с
комментарием и весом под соответствующие weightedRandom-блоки (например
RandomPsionicPowerPool и ElementalistPowerPool) в файл псевдо-слоя для
модификаций (файл с тем же структурным именем в _White), чтобы WWDP-специфичные
способности (PsionicHookPower и подобные ClonePower) хранились только в
_White-слое.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: d908563d-51fa-4177-b996-cb703a43564c
📒 Files selected for processing (1)
Resources/Prototypes/Psionics/PsionicPowerPool.yml
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
Content.Shared/_White/Psionics/Hook/HookPowerSystem.cs (2)
11-13:⚠️ Potential issue | 🟠 MajorЭта система всё ещё не стала server-only.
Одного
namespace Content.Server...здесь недостаточно: пока файл физически лежит вContent.Shared/..., он продолжит собираться вместе с shared-кодом. Для логики соSpawnEntity,Del,TryPickupAnyHand,PlayPvsи изменениемcomponent.Hookсам файл нужно переносить вContent.Server/..., а в shared оставлять только компоненты/ивенты.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Shared/_White/Psionics/Hook/HookPowerSystem.cs` around lines 11 - 13, Файл с системой SpawnImplantSystem содержит серверную логику (вызовы SpawnEntity, Del, TryPickupAnyHand, PlayPvs и изменение component.Hook) и поэтому должен быть перемещён из Content.Shared в Content.Server; оставьте в Shared только компоненты/ивенты, а сам класс SpawnImplantSystem перенесите в соответствующий namespace и директорию Content.Server; убедитесь, что все using/референсы обновлены и что код больше не компилируется в сборку shared после перемещения.
22-26:⚠️ Potential issue | 🟠 MajorДобавьте cleanup хука при снятии
PsionicHookPowerComponent.Сейчас удаление есть только в ветке повторного использования action. Если компонент снимут другим путём, ссылка на хук потеряется, а сама сущность останется в мире или в руке.
Возможный вариант
public override void Initialize() { SubscribeLocalEvent<PsionicHookPowerComponent, PsionicHookPowerActionEvent>(OnPowerUse); SubscribeLocalEvent<CuffableComponent, PsionicUncuffDoAfterEvent>(OnUncuff); + SubscribeLocalEvent<PsionicHookPowerComponent, ComponentShutdown>(OnHookPowerShutdown); } + +private void OnHookPowerShutdown(EntityUid uid, PsionicHookPowerComponent component, ComponentShutdown args) +{ + if (component.Hook is not { } hook || Deleted(hook)) + return; + + QueueDel(hook); + component.Hook = null; +}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Content.Shared/_White/Psionics/Hook/HookPowerSystem.cs` around lines 22 - 26, The component stores a spawned/attached hook that is only cleaned up in the reuse/action branch, so if PsionicHookPowerComponent is removed by any other path the hook reference and entity remain; add a removal handler that cleans up the hook when the component is removed: implement a component removal callback (e.g., OnRemove/OnComponentRemove or subscribe to ComponentRemoveEvent for PsionicHookPowerComponent) that checks the component's stored hook reference (the hook entity/field on PsionicHookPowerComponent) and deletes/detaches it and clears the reference, and ensure any related state (cooldowns/flags) is also reset; keep the existing handlers OnPowerUse and OnUncuff untouched but ensure the new removal handler runs for all non-action removals.
🤖 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/_White/Psionics/Hook/HookSystem.cs`:
- Around line 159-168: В блоке обработки возврата крюка предотвратите «перелёт»
через sourcePos: вычисляйте шаг как min(hookComp.ReturnSpeed * frameTime,
distance) и перемещайте снаряд на direction.Normalized() * step вместо прямого
hookComp.ReturnSpeed * frameTime; при достижении нулевой/малой оставшейся
дистанции вызывать GimmeHookBack(uid, hookComp) (как сейчас) и не делать
дальнейшего SetWorldPosition. Ссылки: hookComp.ReturnSpeed, frameTime, distance,
projectilePos, direction.Normalized(), GimmeHookBack и
_transform.SetWorldPosition.
- Around line 79-80: Перед вызовом MathF.Pow при вычислении переменной power в
HookSystem замените прямое использование psionic.CurrentAmplification на
безопасную валидацию: убедитесь, что значение является конечным (не
Infinity/NaN) и неотрицательным (например, с помощью float.IsFinite(...) и
проверки >= 0), при некорректном значении подставьте безопасный дефолт/клиппинг
(0 или минимально допустимое), и только затем вычисляйте power =
MathF.Pow(validAmplification, 1.3f); также добавьте защиту на случай, если
результат MathF.Pow окажется NaN — в таком случае присвойте power = 0 и
логируйте/отлавливайте аномалию; ориентируйтесь на символы
psionic.CurrentAmplification, переменную power и использование MathF.Pow в
HookSystem.
---
Duplicate comments:
In `@Content.Shared/_White/Psionics/Hook/HookPowerSystem.cs`:
- Around line 11-13: Файл с системой SpawnImplantSystem содержит серверную
логику (вызовы SpawnEntity, Del, TryPickupAnyHand, PlayPvs и изменение
component.Hook) и поэтому должен быть перемещён из Content.Shared в
Content.Server; оставьте в Shared только компоненты/ивенты, а сам класс
SpawnImplantSystem перенесите в соответствующий namespace и директорию
Content.Server; убедитесь, что все using/референсы обновлены и что код больше не
компилируется в сборку shared после перемещения.
- Around line 22-26: The component stores a spawned/attached hook that is only
cleaned up in the reuse/action branch, so if PsionicHookPowerComponent is
removed by any other path the hook reference and entity remain; add a removal
handler that cleans up the hook when the component is removed: implement a
component removal callback (e.g., OnRemove/OnComponentRemove or subscribe to
ComponentRemoveEvent for PsionicHookPowerComponent) that checks the component's
stored hook reference (the hook entity/field on PsionicHookPowerComponent) and
deletes/detaches it and clears the reference, and ensure any related state
(cooldowns/flags) is also reset; keep the existing handlers OnPowerUse and
OnUncuff untouched but ensure the new removal handler runs for all non-action
removals.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 0b89b5b2-132b-4419-b9ce-0bdf8568d4a4
📒 Files selected for processing (3)
Content.Shared/_White/Psionics/Hook/HookPowerSystem.csContent.Shared/_White/Psionics/Hook/HookSystem.csResources/Locale/en-US/_white/abilities/psionic.ftl
✅ Files skipped from review due to trivial changes (1)
- Resources/Locale/en-US/_white/abilities/psionic.ftl
| var power = MathF.Pow(psionic.CurrentAmplification, 1.3f); | ||
| var hookComp = ent.Comp; |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In .NET/C#, what does MathF.Powreturn for a negative base with a fractional exponent such asMathF.Pow(-1f, 1.3f)?
💡 Result:
MathF.Pow(-1f, 1.3f) returns Single.NaN (a floating-point “not a number”), because the base is negative and the exponent is a finite non-integer (fractional) value. [1]
Source(s)
[1] Microsoft Learn — MathF.Pow(Single, Single) Method (remarks table: “x < 0 …, y finite non-integer → NaN”). (learn.microsoft.com)
Citations:
🏁 Script executed:
# First, locate the exact file and examine the context around lines 79-80
fd -t f "HookSystem.cs" --exec wc -l {} \;Repository: WWhiteDreamProject/wwdpublic
Length of output: 127
🏁 Script executed:
# Read the HookSystem.cs file to see the context
cat -n "Content.Shared/_White/Psionics/Hook/HookSystem.cs" | sed -n '70,90p'Repository: WWhiteDreamProject/wwdpublic
Length of output: 903
🏁 Script executed:
# Check PsionicComponent.cs for CurrentAmplification definition
fd -t f "PsionicComponent.cs" | xargs cat -n | sed -n '150,180p'Repository: WWhiteDreamProject/wwdpublic
Length of output: 1610
🏁 Script executed:
# Search for any validation or bounds on CurrentAmplification
rg "CurrentAmplification" -A 3 -B 3Repository: WWhiteDreamProject/wwdpublic
Length of output: 31194
Добавьте валидацию CurrentAmplification перед передачей в MathF.Pow.
Сейчас значение приходит без проверок, и для отрицательной или невалидной амплификации MathF.Pow(..., 1.3f) вернёт NaN. Это сломает физику возврата/притягивания крюка.
Рекомендуемый вариант
- var power = MathF.Pow(psionic.CurrentAmplification, 1.3f);
+ var amplification = float.IsFinite(psionic.CurrentAmplification)
+ ? MathF.Max(psionic.CurrentAmplification, 0f)
+ : 0f;
+ var power = MathF.Pow(amplification, 1.3f);📝 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.
| var power = MathF.Pow(psionic.CurrentAmplification, 1.3f); | |
| var hookComp = ent.Comp; | |
| var amplification = float.IsFinite(psionic.CurrentAmplification) | |
| ? MathF.Max(psionic.CurrentAmplification, 0f) | |
| : 0f; | |
| var power = MathF.Pow(amplification, 1.3f); | |
| var hookComp = ent.Comp; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Content.Shared/_White/Psionics/Hook/HookSystem.cs` around lines 79 - 80,
Перед вызовом MathF.Pow при вычислении переменной power в HookSystem замените
прямое использование psionic.CurrentAmplification на безопасную валидацию:
убедитесь, что значение является конечным (не Infinity/NaN) и неотрицательным
(например, с помощью float.IsFinite(...) и проверки >= 0), при некорректном
значении подставьте безопасный дефолт/клиппинг (0 или минимально допустимое), и
только затем вычисляйте power = MathF.Pow(validAmplification, 1.3f); также
добавьте защиту на случай, если результат MathF.Pow окажется NaN — в таком
случае присвойте power = 0 и логируйте/отлавливайте аномалию; ориентируйтесь на
символы psionic.CurrentAmplification, переменную power и использование MathF.Pow
в HookSystem.
| if (distance < 0.7f) | ||
| { | ||
| if (_netManager.IsServer) | ||
| GimmeHookBack(uid, hookComp); | ||
|
|
||
| continue; | ||
| } | ||
|
|
||
| var movement = direction.Normalized() * hookComp.ReturnSpeed * frameTime; | ||
| _transform.SetWorldPosition(uid, projectilePos + movement); |
There was a problem hiding this comment.
Зажмите шаг возврата по оставшейся дистанции.
Если hookComp.ReturnSpeed * frameTime окажется больше distance, снаряд перелетит sourcePos, на следующем кадре развернётся и может зациклиться вокруг оружия, так и не попав в ветку возврата боеприпаса.
Возможный вариант
- var movement = direction.Normalized() * hookComp.ReturnSpeed * frameTime;
- _transform.SetWorldPosition(uid, projectilePos + movement);
+ var step = hookComp.ReturnSpeed * frameTime;
+ if (step >= distance)
+ {
+ _transform.SetWorldPosition(uid, sourcePos);
+ if (_netManager.IsServer)
+ GimmeHookBack(uid, hookComp);
+ continue;
+ }
+
+ var movement = direction / distance * step;
+ _transform.SetWorldPosition(uid, projectilePos + movement);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Content.Shared/_White/Psionics/Hook/HookSystem.cs` around lines 159 - 168, В
блоке обработки возврата крюка предотвратите «перелёт» через sourcePos:
вычисляйте шаг как min(hookComp.ReturnSpeed * frameTime, distance) и перемещайте
снаряд на direction.Normalized() * step вместо прямого hookComp.ReturnSpeed *
frameTime; при достижении нулевой/малой оставшейся дистанции вызывать
GimmeHookBack(uid, hookComp) (как сейчас) и не делать дальнейшего
SetWorldPosition. Ссылки: hookComp.ReturnSpeed, frameTime, distance,
projectilePos, direction.Normalized(), GimmeHookBack и
_transform.SetWorldPosition.
|
я не знаю почему он ругается всё есть всё работает |
|
это делает меня мёртвым капец |
|
портреты кровью рисую |
|
@Remuchi Проверь код, пожалуйста, быстренько. Псионика потом все равно уйдет на переработку, но в принципе идейно - нормально. |




Описание.
описание1
описание2
хук
или скорпион
сила зависит от силы псионика
мог где-то накосячить в коде
Медиа
https://youtu.be/8xUnMcWJQlU
Изменения
🆑