Skip to content

hotfix 23.06.2026#1464

Merged
Rxup merged 2 commits into
masterfrom
hotfix-23062026
Jun 23, 2026
Merged

hotfix 23.06.2026#1464
Rxup merged 2 commits into
masterfrom
hotfix-23062026

Conversation

@Rxup

@Rxup Rxup commented Jun 23, 2026

Copy link
Copy Markdown
Owner

fix #1461

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Fixed reattachment of severed limbs while associated organs remain preserved.
    • Improved handling of arachne graft operations and rejuvenation compatibility.
    • Corrected internal organ targeting during surgical procedures to prevent organ resolution on incorrect body parts.
  • New Features

    • Added validation and error messaging for incompatible graft operations.
  • Chores

    • Removed visual scaling system for detached organs.

@github-actions github-actions Bot added S: Untriaged size/M Changes: Localization Can be reviewed or fixed by people who are knowledgeable with translation labels Jun 23, 2026
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Rxup, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 40 minutes and 26 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c6c17b45-68db-426d-ad15-07bbdc8c0f01

📥 Commits

Reviewing files that changed from the base of the PR and between d39d160 and 29096f7.

📒 Files selected for processing (5)
  • Content.IntegrationTests/Tests/Backmen/Body/GibDetachedBodyTest.cs
  • Content.Server/Explosion/EntitySystems/ExplosionSystem.cs
  • Content.Shared/Backmen/Body/OrganRelations/DetachableOrganSystem.cs
  • Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Body.cs
  • Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.cs

Walkthrough

Добавлен host-part-ограниченный метод TryGetInternalOrgansForHostPart в BkmBodySharedSystem; хирургические шаги переключены на него вместо TryGetBodyPartOrgans. Команда GraftArachne получила валидацию NPC-тел с новой ошибкой FlatOrgansError. NubodyForceRestore пропускает человеческие конечности при активном arachne-grafting. Исправлено преждевременное удаление стопы при detached-бандлах. Добавлены три интеграционных теста. Удалён LooseOrganVisualSystem.

Changes

Улучшения системы тела

Layer / File(s) Summary
Host-part-scoped API внутренних органов и перевод хирургии
Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Woundables.cs, Content.Shared/Backmen/Surgery/SharedSurgerySystem.Steps.cs, Content.Shared/Backmen/Surgery/SharedSurgerySystem.cs, Resources/Prototypes/Body/base_organs.yml, Content.IntegrationTests/Tests/Backmen/Surgery/InternalOrganSurgeryTest.cs
Добавлены BodySupportsArachneGraft и TryGetInternalOrgansForHostPart в BkmBodySharedSystem. Все пять обработчиков шагов хирургии и OnOrganConditionValid переключены на новый метод с args.Part как lookup. Прототипы базовых органов дополнены компонентами Eyes, Heart, Liver. Тест InternalOrganSurgeryTest проверяет положительные и отрицательные сценарии привязки органов к host-part.
Валидация arachne graft, пропуск в NubodyForceRestore и SyncLegEntitiesForBody
Content.Server/Backmen/Administration/Commands/Toolshed/GraftArachneCommand.cs, Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Body.cs, Resources/Locale/en-US/backmen/toolshed.ftl, Resources/Locale/ru-RU/backmen/toolshed.ftl, Content.IntegrationTests/Tests/Backmen/Body/GraftArachneRejuvenateTest.cs
GraftArachneCommand проверяет BodySupportsArachneGraft, при отказе регистрирует FlatOrgansError и прерывается; после WireGraftRelationships вызывается SyncLegEntitiesForBody. NubodyForceRestore пропускает категории человеческих ног при активном arachne-graft и завершается вызовами SyncLegEntities/UpdateMovementSpeed. Добавлена публичная обёртка SyncLegEntitiesForBody. Тест GraftArachneRejuvenateTest покрывает цикл graft→rejuvenate→graft и отказ NPC.
Сохранение стопы при detached-бандле и удаление LooseOrganVisualSystem
Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Body.cs, Content.IntegrationTests/Tests/Backmen/Body/DetachedLegFootReattachTest.cs, Content.Client/Backmen/Body/LooseOrganVisualSystem.cs
OnOrganRemovedFromBody теперь учитывает BkmDetachedBodyComponent и не удаляет стопу при переносе ноги из detached-бандла. LooseOrganVisualSystem (клиентское масштабирование loose-органов) удалён. Тест DetachedLegFootReattachTest проверяет, что стопа сохраняется и категория FootLeft доступна после повторного присоединения.

Sequence Diagram(s)

sequenceDiagram
  rect rgba(135, 100, 200, 0.5)
    Note over GraftArachneCommand,BkmBodySharedSystem: Arachne Graft Flow
  end
  participant Admin as Admin/Toolshed
  participant GraftArachneCommand
  participant BkmBodySharedSystem
  participant OrganRelationsSystem

  Admin->>GraftArachneCommand: GraftArachne(ctx, entityUid)
  GraftArachneCommand->>BkmBodySharedSystem: BodySupportsArachneGraft(input)
  alt NPC с плоскими органами
    BkmBodySharedSystem-->>GraftArachneCommand: false
    GraftArachneCommand-->>Admin: ctx.ReportError(FlatOrgansError), null
  else Тело поддерживает graft
    BkmBodySharedSystem-->>GraftArachneCommand: true
    GraftArachneCommand->>GraftArachneCommand: вставка arachne-органов, spider legs
    GraftArachneCommand->>OrganRelationsSystem: WireGraftRelationships(body)
    GraftArachneCommand->>BkmBodySharedSystem: SyncLegEntitiesForBody(body, bodyComp)
    BkmBodySharedSystem-->>GraftArachneCommand: leg entities синхронизированы
  end
Loading
sequenceDiagram
  rect rgba(50, 150, 100, 0.5)
    Note over SharedSurgerySystem,BkmBodySharedSystem: Surgery organ step (новый путь)
  end
  participant SharedSurgerySystem
  participant BkmBodySharedSystem
  participant InternalOrganHostCategory

  SharedSurgerySystem->>BkmBodySharedSystem: TryGetInternalOrgansForHostPart(body, args.Part, organType)
  BkmBodySharedSystem->>BkmBodySharedSystem: TryGetBodyPartOrgans(body, organType) → все органы типа
  BkmBodySharedSystem->>InternalOrganHostCategory: фильтр по ожидаемой host-категории для args.Part
  InternalOrganHostCategory-->>BkmBodySharedSystem: отфильтрованный список (Id, OrganComponent)
  BkmBodySharedSystem-->>SharedSurgerySystem: true + список / false
  SharedSurgerySystem->>SharedSurgerySystem: отмена шага или операция с первым органом
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 Прыг-скок по системе тел,
паук и нога нашли свой удел.
Стопа не пропала при детаче — ура!
Хирург видит органы строго по месту с утра.
FlatOrgansError теперь бережёт,
а тест подтвердит — всё правильно шьёт! 🕷️

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive Название 'hotfix 23.06.2026' является расплывчатым и не содержит описательной информации о характере изменений в PR. Замените название на более информативное, описывающее основную цель изменений, например: 'Fix arachne graft validation and organ surgery resolution' или 'Refactor organ body integration logic with arachne graft support'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotfix-23062026

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

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Body.cs (1)

246-272: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Не обходите финальную синхронизацию при removeWounds: false.

Line 246 возвращает управление до Line 271-272, поэтому ForceRestoreBody(..., removeWounds: false) после восстановления органов не пересоберет LegEntities и не обновит скорость.

🐛 Возможное исправление
-        if (!removeWounds)
-            return;
+        void FinishRestore()
+        {
+            _organRelations.WireRelationships((ent, ent.Comp!));
+            SyncLegEntities((ent, ent.Comp!));
+            UpdateMovementSpeed(ent, ent.Comp!);
+        }
+
+        if (!removeWounds)
+        {
+            FinishRestore();
+            return;
+        }
 
         if (_trauma.TryGetBodyTraumas(ent, out var traumas, bodyComp: ent.Comp))
         {
             foreach (var trauma in traumas)
@@
-        _organRelations.WireRelationships((ent, ent.Comp!));
-        SyncLegEntities((ent, ent.Comp!));
-        UpdateMovementSpeed(ent, ent.Comp!);
+        FinishRestore();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Body.cs` around lines
246 - 272, When removeWounds is false, the early return statement in the if
block prevents the final synchronization calls from executing, leaving the body
state unsynchronized after organ restoration. Move the SyncLegEntities and
UpdateMovementSpeed calls outside of the conditional removeWounds block so they
execute regardless of whether wounds are being removed, ensuring complete body
synchronization in all cases.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Woundables.cs`:
- Around line 160-163: The code retrieves the OrganComponent from hostPart and
uses its category to find organs in bodyId, but does not verify that hostPart
actually belongs to bodyId. This allows a body part from a different body to
incorrectly match organs in bodyId if they share the same category. Add a
validation check after obtaining hostOrgan (where you verify it exists and has a
category) to also ensure that hostOrgan.Body matches the bodyId parameter before
proceeding to search for organs with TryGetBodyPartOrgans.

---

Outside diff comments:
In `@Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Body.cs`:
- Around line 246-272: When removeWounds is false, the early return statement in
the if block prevents the final synchronization calls from executing, leaving
the body state unsynchronized after organ restoration. Move the SyncLegEntities
and UpdateMovementSpeed calls outside of the conditional removeWounds block so
they execute regardless of whether wounds are being removed, ensuring complete
body synchronization in all cases.
🪄 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: 03b32e48-57a7-48de-a9c4-187dd063ca51

📥 Commits

Reviewing files that changed from the base of the PR and between 59d4cd2 and d39d160.

📒 Files selected for processing (12)
  • Content.Client/Backmen/Body/LooseOrganVisualSystem.cs
  • Content.IntegrationTests/Tests/Backmen/Body/DetachedLegFootReattachTest.cs
  • Content.IntegrationTests/Tests/Backmen/Body/GraftArachneRejuvenateTest.cs
  • Content.IntegrationTests/Tests/Backmen/Surgery/InternalOrganSurgeryTest.cs
  • Content.Server/Backmen/Administration/Commands/Toolshed/GraftArachneCommand.cs
  • Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Body.cs
  • Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Woundables.cs
  • Content.Shared/Backmen/Surgery/SharedSurgerySystem.Steps.cs
  • Content.Shared/Backmen/Surgery/SharedSurgerySystem.cs
  • Resources/Locale/en-US/backmen/toolshed.ftl
  • Resources/Locale/ru-RU/backmen/toolshed.ftl
  • Resources/Prototypes/Body/base_organs.yml
💤 Files with no reviewable changes (1)
  • Content.Client/Backmen/Body/LooseOrganVisualSystem.cs

Comment on lines +160 to +163
if (!TryComp<OrganComponent>(hostPart, out var hostOrgan) || hostOrgan.Category is not { } hostCategory)
return false;

if (!TryGetBodyPartOrgans(bodyId, organComponentType, out var all) || all == null)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Проверьте, что hostPart принадлежит bodyId.

Line 160 берет категорию у hostPart, но не сверяет hostOrgan.Body; поэтому вызов с торсом/головой другого тела все равно найдет внутренние органы в bodyId для этой категории.

🐛 Возможное исправление
-        if (!TryComp<OrganComponent>(hostPart, out var hostOrgan) || hostOrgan.Category is not { } hostCategory)
+        if (!TryComp<OrganComponent>(hostPart, out var hostOrgan) || hostOrgan.Category is not { } hostCategory)
+            return false;
+
+        if (hostOrgan.Body != bodyId)
             return false;
📝 Committable suggestion

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

Suggested change
if (!TryComp<OrganComponent>(hostPart, out var hostOrgan) || hostOrgan.Category is not { } hostCategory)
return false;
if (!TryGetBodyPartOrgans(bodyId, organComponentType, out var all) || all == null)
if (!TryComp<OrganComponent>(hostPart, out var hostOrgan) || hostOrgan.Category is not { } hostCategory)
return false;
if (hostOrgan.Body != bodyId)
return false;
if (!TryGetBodyPartOrgans(bodyId, organComponentType, out var all) || all == null)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Woundables.cs` around
lines 160 - 163, The code retrieves the OrganComponent from hostPart and uses
its category to find organs in bodyId, but does not verify that hostPart
actually belongs to bodyId. This allows a body part from a different body to
incorrectly match organs in bodyId if they share the same category. Add a
validation check after obtaining hostOrgan (where you verify it exists and has a
category) to also ensure that hostOrgan.Body matches the bodyId parameter before
proceeding to search for organs with TryGetBodyPartOrgans.

@Rxup Rxup merged commit 32a0246 into master Jun 23, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Changes: Localization Can be reviewed or fixed by people who are knowledgeable with translation S: Untriaged size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant