Skip to content

ReBELL Act 3 Patch I - #1489

Draft
MightBeNotReal wants to merge 7 commits into
Rxup:masterfrom
MightBeNotReal:fixes-and-changes
Draft

ReBELL Act 3 Patch I#1489
MightBeNotReal wants to merge 7 commits into
Rxup:masterfrom
MightBeNotReal:fixes-and-changes

Conversation

@MightBeNotReal

@MightBeNotReal MightBeNotReal commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

About the PR

Lechenie teper rabotaet adekvatno
Povischena vischivaemost lyudey, nebolschaya pererabotka woundov

Requirements

  • I have read and am following the Pull Request and Changelog Guidelines.
  • I have tested this pull request and written instructions on how to test it
  • I have added media to this PR or it does not require an in-game showcase.

Summary by CodeRabbit

  • Новые возможности

    • Добавлена вероятность автоматического объединения новых ран с уже существующими; в расчёте учитываются тяжесть и шанс конкретной раны.
    • Вероятность объединения теперь регулируется серверным параметром wounding.wound_merge_ratio.
  • Исправления

    • Исправлено изменение тяжести при повторных повреждениях/лечении: оно корректно ограничивается снизу нулём.
    • Лечение точнее выбирает, какие раны можно исцелять, и корректнее обрабатывает кровотечения по порогам; повторное лечение корректно прекращается, когда подходящих повреждений больше нет.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Draft detected.

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

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7108ac49-d303-4475-8059-9464f422f7d7

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

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Добавлена вероятностная механика слияния ран с новым CVar и параметром компонента. API системы ран переведены на типизированные сущности. Обновлены расчёты тяжести, целостности и burn-to-ash, а проверка и выполнение медицинского лечения переработаны.

Changes

Система ран и лечения

Layer / File(s) Summary
Контракт вероятности слияния
Content.Shared/Backmen/CCVar/CCVars.ReBELL.cs, Content.Shared/Backmen/Surgery/Wounds/Components/*
Добавлены WoundMergeRatio, MergeChance и индекс ран по типу повреждения; контейнер ран стал обязательным.
Расчёт слияния и обработка тяжести
Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.cs
Добавлен вероятностный выбор слияния, унифицирован расчёт изменения тяжести и обновлены публичные API системы ран.
Обновление состояния и серверное применение
Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.cs, Content.Server/Backmen/Surgery/Wounds/Systems/ServerWoundSystem.cs, Content.Shared/Backmen/Body/..., Content.Shared/Backmen/Damage/...
Операции изменения, лечения, добавления и удаления ран переведены на Entity<T>; обновления целостности и порогов используют новые сигнатуры.
Проверка и выполнение лечения
Content.Shared/Medical/Healing/HealingSystem.cs
Проверка лечимых ран учитывает кровотечения, типы повреждений, травмы и медицинскую цель; алгоритм лечения и повторные действия переработаны.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant HealingSystem
  participant MedicalTarget
  participant WoundSystem
  participant TraumaSystem
  HealingSystem->>MedicalTarget: разрешить цель лечения
  MedicalTarget-->>HealingSystem: вернуть woundable
  HealingSystem->>WoundSystem: проверить лечимые раны
  WoundSystem->>TraumaSystem: проверить блокировки травмами
  TraumaSystem-->>WoundSystem: вернуть состояние блокировки
  WoundSystem-->>HealingSystem: вернуть результат проверки
  HealingSystem->>WoundSystem: применить лечение к выбранной ране
Loading

Suggested reviewers: rxup, rxup

Poem

Я, кролик, слияние ран наблюдал,
Шанс по severity ловко считал.
Лекарство нашло, что пора исцелить,
А травмы велели немного подождать.
Пушистый коммит скачет вперёд! 🐇

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.77% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive Заголовок связан с проектом и патчем, но слишком общий и не отражает изменение ран и лечения. Укажите ключевое изменение, например: «Обновление системы ран и лечения в ReBELL Act 3».
✅ 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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

❤️ Share

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

@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: 6

🤖 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/Surgery/Wounds/Systems/WoundSystem.Wounding.cs`:
- Around line 529-537: Update the CanContinueWound call in the wound-processing
flow to use severityApplied instead of damagePiece.Value when calculating
whether the wound continues. Keep the original damagePiece.Value for the
existing non-probability inputs unless they specifically represent the modified
severity.
- Around line 414-415: Не применяйте RollForWoundMerging к операциям лечения:
добавьте условие, позволяющее пропускать эту проверку при отрицательной
severity, чтобы GetWoundsChanged мог выбрать существующую рану и сохранить
лечение. Для положительной тяжести оставьте текущую проверку слияния без
изменений.
- Around line 375-387: Normalize the merge chance in RollForWoundMerging by
validating _woundMergeRatio before division and returning false for an invalid
or non-positive coefficient. After calculating the chance from MergeChance and
severity, clamp it to the [0, 1] range before passing it to Random.Prob.

In `@Content.Shared/Medical/Healing/HealingSystem.cs`:
- Around line 156-213: Обновите AreHealableWoundsPresent и связанный исполнитель
лечения так, чтобы рана считалась подходящей только после проверок типа урона,
CanHealWound и блокирующих травм. Не обрабатывайте кровоточащую рану до этих
ограничений; сначала выберите валидную рану, затем сбрасывайте кровотечение и
изменяйте её тяжесть, используя те же условия в обоих местах.
- Around line 266-271: В логике лечения вокруг вычисления healed ограничьте
фактически снятую тяжесть текущей тяжестью раны, сохраняя её в healed как
положительное значение. Передайте в _wounds.ApplyWoundSeverity отрицательную
величину этого фактически снятого значения, а не исходную лечебную дельту.
Примените ту же корректировку во втором аналогичном участке.
- Around line 243-245: Update TryHeal and OnBodyDoAfter to track whether
TryModifyBloodLevel actually changed the entity’s blood level, and treat that
change as successful alongside wound healing. In the success check covering the
referenced blood-modification paths, return before item consumption when neither
blood nor wounds changed; preserve consumption only when at least one effect
succeeded.
🪄 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: f2ca088c-6b74-4af1-9bb1-cd18d3c8b2cf

📥 Commits

Reviewing files that changed from the base of the PR and between 53b82ee and 71db386.

📒 Files selected for processing (5)
  • Content.Server/Backmen/Surgery/Wounds/Systems/ServerWoundSystem.cs
  • Content.Shared/Backmen/CCVar/CCVars.ReBELL.cs
  • Content.Shared/Backmen/Surgery/Wounds/Components/WoundComponent.cs
  • Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.cs
  • Content.Shared/Medical/Healing/HealingSystem.cs

Comment on lines +375 to +387
[PublicAPI]
public bool RollForWoundMerging(
Entity<WoundComponent?> woundProgenitor,
FixedPoint2 severity)
{
if (severity < FixedPoint2.Zero)
return false;

if (!WoundQuery.Resolve(woundProgenitor, ref woundProgenitor.Comp))
return false;

var chance = woundProgenitor.Comp.MergeChance * (severity / _woundMergeRatio);
return Random.Prob((float) chance);

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Проверить принятую в проекте нормализацию аргументов Random.Prob.
rg -n -C3 'Random\.Prob\s*\(' --glob '*.cs'

Repository: Rxup/space-station-14

Length of output: 159


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== WoundSystem.Wounding.cs around target ==\n'
sed -n '330,430p' Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.cs

printf '\n== Search for wound merge ratio / merge chance usage ==\n'
rg -n -C2 '_woundMergeRatio|MergeChance|CanContinueWound|GetWoundsChanged|RollForWoundMerging' Content.Shared/Backmen/Surgery/Wounds -g '*.cs'

printf '\n== Search for Random.Prob definition/reference in repo ==\n'
rg -n -C2 'Random\.Prob|class Random|static .*Prob' --glob '*.cs'

Repository: Rxup/space-station-14

Length of output: 9303


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.cs'
printf '\n== %s: relevant methods ==\n' "$file"
sed -n '1,260p' "$file" | nl -ba | sed -n '1,260p'

Repository: Rxup/space-station-14

Length of output: 294


🌐 Web query:

Robust.Shared.Random.Random.Prob source contract probability range

💡 Result:

The Robust.Shared.Random.RandomExtensions.Prob method is an extension method for IRobustRandom that determines whether an event occurs based on a provided probability [1]. The probability parameter, typically named chance, must be in the range [1], inclusive [1]. The implementation uses a DebugTools assertion to enforce this constraint, ensuring the value is less than or equal to 1 and greater than or equal to 0 [1]. If the input value falls outside this range, the assertion will trigger [1]. The method functions by comparing a generated random double (via random.NextDouble) against the provided chance value; it returns true if the random value is less than the chance [1].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.cs'
nl -ba "$file" | sed -n '1,260p' | awk '
  /_woundMergeRatio|CanContinueWound|GetWoundsChanged|RollForWoundMerging/ {print; for(i=1;i<=18;i++){getline; print}}'

Repository: Rxup/space-station-14

Length of output: 199


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== GetWoundsChanged and nearby logic ==\n'
sed -n '500,560p' Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.cs

printf '\n== WoundMergeRatio config definition and defaults ==\n'
rg -n -C3 'WoundMergeRatio|woundMergeRatio' --glob '*.cs' --glob '*.toml' --glob '*.yml' --glob '*.yaml'

printf '\n== Any direct Random.Prob usage in repo ==\n'
rg -n -C2 'Prob\(' --glob '*.cs'

Repository: Rxup/space-station-14

Length of output: 2613


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== CCVars.WoundMergeRatio references ==\n'
rg -n -C3 'WoundMergeRatio' --glob '*.cs' --glob '*.toml' --glob '*.yml' --glob '*.yaml'

printf '\n== WoundSystem.Wounding.cs: section around merge ratio init ==\n'
sed -n '45,70p' Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.cs

printf '\n== WoundSystem.Wounding.cs: section around severity application ==\n'
sed -n '520,550p' Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.cs

Repository: Rxup/space-station-14

Length of output: 200


Нормализуйте шанс слияния ран.
Random.Prob ожидает значение в [0, 1], а здесь при большом severity/MergeChance или невалидном _woundMergeRatio может уйти некорректный шанс. Добавьте проверку коэффициента и Clamp перед вызовом.

🤖 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/Surgery/Wounds/Systems/WoundSystem.Wounding.cs` around
lines 375 - 387, Normalize the merge chance in RollForWoundMerging by validating
_woundMergeRatio before division and returning false for an invalid or
non-positive coefficient. After calculating the chance from MergeChance and
severity, clamp it to the [0, 1] range before passing it to Random.Prob.

Comment thread Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.cs Outdated
Comment on lines +529 to +537
var severityApplied = damagePiece.Value > 0
? ApplySeverityModifiers(woundable, damagePiece.Value, component)
: damagePiece.Value;

if (!CanContinueWound(
woundable,
damagePiece.Key,
damagePiece.Value,
out var continuedWound,

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 | 🟠 Major | ⚡ Quick win

Используйте модифицированную тяжесть при расчёте слияния.

Вероятность сейчас рассчитывается из damagePiece.Value, хотя к продолжаемой ране применяется severityApplied. Из-за этого множители тяжести изменяют нанесённый урон, но не шанс создания новой раны.

Предлагаемое исправление
             if (!CanContinueWound(
                     woundable,
                     damagePiece.Key,
-                    damagePiece.Value,
+                    severityApplied,
                     out var continuedWound,
                     component))
📝 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
var severityApplied = damagePiece.Value > 0
? ApplySeverityModifiers(woundable, damagePiece.Value, component)
: damagePiece.Value;
if (!CanContinueWound(
woundable,
damagePiece.Key,
damagePiece.Value,
out var continuedWound,
var severityApplied = damagePiece.Value > 0
? ApplySeverityModifiers(woundable, damagePiece.Value, component)
: damagePiece.Value;
if (!CanContinueWound(
woundable,
damagePiece.Key,
severityApplied,
out var continuedWound,
component))
🤖 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/Surgery/Wounds/Systems/WoundSystem.Wounding.cs` around
lines 529 - 537, Update the CanContinueWound call in the wound-processing flow
to use severityApplied instead of damagePiece.Value when calculating whether the
wound continues. Keep the original damagePiece.Value for the existing
non-probability inputs unless they specifically represent the modified severity.

Comment on lines +156 to +213
private bool AreHealableWoundsPresent(
Entity<WoundableComponent> woundable,
HealingComponent healing,
EntityUid body,
EntityUid user)
{
var healableWoundsPresent = false;
var bleedingWounds = 0;
var nonhealableWounds = 0;
foreach (var wound in _wounds.GetWoundableWounds(woundable, woundable))
{
if (TryComp(wound, out BleedInflicterComponent? bleeds))
{
if (bleeds.IsBleeding && bleeds.BleedingAmount > healing.UnableToHealBleedsThreshold)
{
bleedingWounds++;
continue;
}

healableWoundsPresent = true;
break;
}

if (!healing.Damage.DamageDict.ContainsKey(wound.Comp.DamageType))
{
nonhealableWounds++;
continue;
}

if (!_wounds.CanHealWound(wound, wound))
continue;

healableWoundsPresent = true;
break;
}

if (nonhealableWounds > 0)
{
var popup = Loc.GetString("medical-item-no-healable-damage", ("target", body));
if (_trauma.AnyTraumasBlockingHealing(woundable, woundable))
{
popup = Loc.GetString("medical-item-requires-partial-surgery-rebell", ("target", body));
}
else
{
if (bleedingWounds > nonhealableWounds)
popup = Loc.GetString("medical-item-cant-use-bleeding-heavy", ("target", body));
}

_popupSystem.PopupPredicted(
popup,
body,
user,
PopupType.MediumCaution);
}

return healableWoundsPresent;
}

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 | 🟠 Major | ⚡ Quick win

Используйте единые ограничения при выборе и лечении раны.

Кровоточащая рана признаётся лечимой до проверок DamageDict и CanHealWound, а травма влияет только на popup. Затем исполнитель сбрасывает кровотечение и применяет лечение без этих проверок. В результате неподдерживаемые или заблокированные раны можно изменить.

Сначала выберите рану по всем ограничениям, включая травму, и только затем изменяйте кровотечение и тяжесть.

Also applies to: 248-272

🤖 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/Medical/Healing/HealingSystem.cs` around lines 156 - 213,
Обновите AreHealableWoundsPresent и связанный исполнитель лечения так, чтобы
рана считалась подходящей только после проверок типа урона, CanHealWound и
блокирующих травм. Не обрабатывайте кровоточащую рану до этих ограничений;
сначала выберите валидную рану, затем сбрасывайте кровотечение и изменяйте её
тяжесть, используя те же условия в обоих местах.

Comment on lines +243 to +245
// TODO: When complex bloodstream is implemented, rework adding blood
if (healing.ModifyBloodLevel != 0)
_bloodstreamSystem.TryModifyBloodLevel(ent, healing.ModifyBloodLevel);

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 | 🟠 Major | ⚡ Quick win

Учитывайте восстановление крови как успешное действие.

TryHeal разрешает предметы только для восстановления крови, но OnBodyDoAfter после изменения крови проверяет лишь лечение ран. Такой предмет показывает ошибку, а настоящая неудача всё равно продолжает выполнение и расходует предмет.

Учитывайте фактическое изменение крови в результате и делайте return до расходования предмета, если не изменились ни кровь, ни раны.

Also applies to: 275-283, 424-435

🤖 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/Medical/Healing/HealingSystem.cs` around lines 243 - 245,
Update TryHeal and OnBodyDoAfter to track whether TryModifyBloodLevel actually
changed the entity’s blood level, and treat that change as successful alongside
wound healing. In the success check covering the referenced blood-modification
paths, return before item consumption when neither blood nor wounds changed;
preserve consumption only when at least one effect succeeded.

Comment on lines +266 to +271
healed = wound.Comp.WoundSeverityPoint > value
? value
: wound.Comp.WoundSeverityPoint;

// TODO: When I rework the bloodstream system, I will also rework the healing logic
_wounds.ApplyWoundSeverity(wound, value, wound);

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

Записывайте фактически снятую тяжесть раны.

healed получает отрицательную лечебную дельту и может превышать оставшуюся тяжесть раны, поэтому административный журнал показывает отрицательное или завышенное лечение. Ограничьте величину текущей тяжестью, примените её с отрицательным знаком, а в healed сохраните положительный результат.

Also applies to: 317-324

🤖 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/Medical/Healing/HealingSystem.cs` around lines 266 - 271, В
логике лечения вокруг вычисления healed ограничьте фактически снятую тяжесть
текущей тяжестью раны, сохраняя её в healed как положительное значение.
Передайте в _wounds.ApplyWoundSeverity отрицательную величину этого фактически
снятого значения, а не исходную лечебную дельту. Примените ту же корректировку
во втором аналогичном участке.

@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

♻️ Duplicate comments (2)
Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.cs (2)

387-401: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

_woundMergeRatio всё ещё не проверяется перед делением.

Clamp для итогового шанса добавлен, но коэффициент _woundMergeRatio (из CVar) не проверяется на <= 0 перед severity / _woundMergeRatio. При _woundMergeRatio == 0 получим float.PositiveInfinity (или NaN, если severity == 0), а Random.Prob в Robust.Shared ожидает строго [0,1] и падает на DebugTools.Assert вне этого диапазона. Именно это было запрошено в предыдущем ревью, но реализован только Clamp результата, а не защита коэффициента.

Предлагаемое исправление
     public bool RollForWoundMerging(
         Entity<WoundComponent?> woundProgenitor,
         FixedPoint2 severity)
     {
         if (severity < FixedPoint2.Zero)
             return false;
 
         if (!WoundQuery.Resolve(woundProgenitor, ref woundProgenitor.Comp))
             return false;
 
+        if (_woundMergeRatio <= 0f)
+            return false;
+
         var chance =
             FixedPoint2.Clamp(woundProgenitor.Comp.MergeChance * (severity / _woundMergeRatio), 0f, 1f);
         return Random.Prob((float) chance);
     }
🤖 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/Surgery/Wounds/Systems/WoundSystem.Wounding.cs` around
lines 387 - 401, В методе RollForWoundMerging добавьте проверку _woundMergeRatio
до вычисления severity / _woundMergeRatio: при значении <= FixedPoint2.Zero
немедленно возвращайте false. Сохраните существующие проверки severity,
разрешения компонента и последующий Clamp для корректных положительных значений
коэффициента.

534-559: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Решения о слиянии/добавлении раны принимаются по немодифицированному damagePiece.Value, а не по severityApplied.

severityApplied (с учётом ApplySeverityModifiers) вычисляется на строках 538-540, но:

  • CanContinueWound(ent, damagePiece.Key, damagePiece.Value, ...) (542-547) получает исходное damagePiece.Value, поэтому мультипликаторы тяжести не влияют на шанс слияния (RollForWoundMerging), хотя именно они применяются к фактически наносимому урону в ветке "continue" (573-577).
  • В ветке создания новой раны CanAddWound(ent, damagePiece.Key, damagePiece.Value, component) (549-553) тоже проверяет порог по необработанному значению, а сама рана создаётся уже с пересчитанным severity = ApplySeverityModifiers(...) (559) — то есть решение и итоговое значение может рассинхронизироваться (мультипликатор мог опустить/поднять значение относительно порога WoundThresholds[WoundSeverity.Healed]).

Это то же замечание, что уже поднималось для CanContinueWound в предыдущем ревью, и остаётся неисправленным.

Предлагаемое исправление
             if (!CanContinueWound(
                     ent,
                     damagePiece.Key,
-                    damagePiece.Value,
+                    severityApplied,
                     out var continuedWound,
                     component))
             {
-                if (damagePiece.Value <= 0 || !CanAddWound(
+                if (severityApplied <= 0 || !CanAddWound(
                         ent,
                         damagePiece.Key,
-                        damagePiece.Value,
+                        severityApplied,
                         component))
                 {
                     actuallyInducedDamage.DamageDict[damagePiece.Key] = 0;
                     continue;
                 }
 
-                var severity = ApplySeverityModifiers(ent, damagePiece.Value, component);
+                var severity = severityApplied;
🤖 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/Surgery/Wounds/Systems/WoundSystem.Wounding.cs` around
lines 534 - 559, Use severityApplied consistently for wound continuation and
creation decisions in the damage-processing loop: pass it to CanContinueWound
and CanAddWound instead of damagePiece.Value. Keep the existing
damagePiece.Value handling for healing checks and ensure the subsequent wound
severity uses the same modified value.
🤖 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/Surgery/Wounds/Systems/WoundSystem.cs`:
- Around line 274-303: Update RaiseWoundEvents and the GetWoundsChanged flow so
an already-resolved wound delta is classified as an existing wound without
invoking CanContinueWound or RollForWoundMerging again. Add a dedicated overload
or explicit continued-wound parameter, pass woundUid through RaiseWoundEvents,
and ensure the resulting WoundsChangedEvent includes the delta in changedWounds
while preserving the existing behavior for newly applied wound deltas.

---

Duplicate comments:
In `@Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.cs`:
- Around line 387-401: В методе RollForWoundMerging добавьте проверку
_woundMergeRatio до вычисления severity / _woundMergeRatio: при значении <=
FixedPoint2.Zero немедленно возвращайте false. Сохраните существующие проверки
severity, разрешения компонента и последующий Clamp для корректных положительных
значений коэффициента.
- Around line 534-559: Use severityApplied consistently for wound continuation
and creation decisions in the damage-processing loop: pass it to
CanContinueWound and CanAddWound instead of damagePiece.Value. Keep the existing
damagePiece.Value handling for healing checks and ensure the subsequent wound
severity uses the same modified value.
🪄 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: c235646a-6833-4a98-b3ab-49cd861ebc00

📥 Commits

Reviewing files that changed from the base of the PR and between 71db386 and b3fc0f2.

📒 Files selected for processing (10)
  • Content.Server/Backmen/Body/Systems/BkmBurnWoundableSystem.cs
  • Content.Server/Backmen/Surgery/Wounds/Systems/ServerWoundSystem.cs
  • Content.Shared/Backmen/Body/OrganRelations/BkmDetachedBodySystem.cs
  • Content.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Woundables.cs
  • Content.Shared/Backmen/Damage/DamageableSystem.Backmen.cs
  • Content.Shared/Backmen/Surgery/Wounds/Components/WoundComponent.cs
  • Content.Shared/Backmen/Surgery/Wounds/Components/WoundableComponent.cs
  • Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.cs
  • Content.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.cs
  • Content.Shared/Medical/Healing/HealingSystem.cs
🚧 Files skipped from review as they are similar to previous changes (2)
  • Content.Shared/Backmen/Surgery/Wounds/Components/WoundComponent.cs
  • Content.Shared/Medical/Healing/HealingSystem.cs

Comment on lines +274 to 303
protected void RaiseWoundEvents(
Entity<WoundComponent?> woundEnt,
Entity<WoundableComponent?> woundable,
FixedPoint2 oldSeverity)
{
if (!WoundableQuery.Resolve(woundableEnt, ref woundableComp, false) || woundableComp.Wounds == null)
var (woundUid, woundComp) = woundEnt;
if (!WoundQuery.Resolve(woundUid, ref woundComp, false))
return;

if (!woundableComp.Wounds.Contains(uid))
var (woundableEnt, woundableComp) = woundable;
if (!WoundableQuery.Resolve(woundableEnt, ref woundableComp, false))
return;

var delta = wound.WoundSeverityPoint - oldSeverity;
if (!woundableComp.Wounds.Contains(woundUid))
return;

var delta = woundComp.WoundSeverityPoint - oldSeverity;
var damageSpec = new DamageSpecifier();

damageSpec.DamageDict.Add(wound.DamageType, delta);
damageSpec.DamageDict.Add(woundComp.DamageType, delta);

var woundChangedEvent = new WoundChangedEvent(wound, delta);
RaiseLocalEvent(uid, ref woundChangedEvent);
var woundChangedEvent = new WoundChangedEvent(woundComp, delta);
RaiseLocalEvent(woundUid, ref woundChangedEvent);

// Raise woundable effects without computing the severity changes, so we do not accidentally duplicate the severity.
GetWoundsChanged(woundableEnt, woundableEnt, damageSpec, false, woundableComp);
GetWoundsChanged(woundable, woundableEnt, damageSpec, false);

var ev = new WoundSeverityPointChangedEvent(wound, oldSeverity, wound.WoundSeverityPoint);
RaiseLocalEvent(uid, ref ev);
var ev = new WoundSeverityPointChangedEvent(woundComp, oldSeverity, woundComp.WoundSeverityPoint);
RaiseLocalEvent(woundUid, ref ev);
}

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 | 🟠 Major | 🏗️ Heavy lift

RaiseWoundEvents создаёт побочный случайный бросок слияния при каждом изменении тяжести раны.

RaiseWoundEvents вызывает GetWoundsChanged(woundable, woundableEnt, damageSpec, false) только для того, чтобы разослать WoundsDeltaChanged/WoundSeverityPointChangedEvent по уже применённой дельте конкретной раны (woundEnt). Но внутри GetWoundsChanged для этой же дельты снова вызывается CanContinueWoundRollForWoundMerging, то есть новый Random.Prob бросок — сверх того, что уже был выполнен (или не требовался, при лечении) в вызывающем коде (ApplyWoundSeverity/TryContinueWound).

Если этот повторный бросок не проходит, дельта в GetWoundsChanged попадает в ветку "новая рана" (woundsToAdd), а не в changedWounds; так как performLogic=false, рана фактически не создаётся, и дельта полностью выпадает и из changedWounds, и из addedWounds итогового WoundsChangedEvent/WoundsDeltaChanged. Реальное состояние раны при этом остаётся верным (изменено напрямую в ApplyWoundSeverity до этого вызова), но подписчики событий (боль, UI, целевые оверлеи) иногда будут получать неполные данные об изменении — исключительно из-за случайности.

Стоит завести отдельный путь пересчёта делты для уже известной раны (например, отдельный оверлоад GetWoundsChanged/явную передачу continuedWound), который не проходит через CanContinueWound/RollForWoundMerging повторно.

🤖 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/Surgery/Wounds/Systems/WoundSystem.cs` around lines
274 - 303, Update RaiseWoundEvents and the GetWoundsChanged flow so an
already-resolved wound delta is classified as an existing wound without invoking
CanContinueWound or RollForWoundMerging again. Add a dedicated overload or
explicit continued-wound parameter, pass woundUid through RaiseWoundEvents, and
ensure the resulting WoundsChangedEvent includes the delta in changedWounds
while preserving the existing behavior for newly applied wound deltas.

@MightBeNotReal
MightBeNotReal marked this pull request as draft July 19, 2026 20:50
@github-actions github-actions Bot added size/L and removed size/M labels Jul 20, 2026
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant