ReBELL Act 3 Patch I - #1489
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughДобавлена вероятностная механика слияния ран с новым CVar и параметром компонента. API системы ран переведены на типизированные сущности. Обновлены расчёты тяжести, целостности и burn-to-ash, а проверка и выполнение медицинского лечения переработаны. ChangesСистема ран и лечения
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: применить лечение к выбранной ране
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (5)
Content.Server/Backmen/Surgery/Wounds/Systems/ServerWoundSystem.csContent.Shared/Backmen/CCVar/CCVars.ReBELL.csContent.Shared/Backmen/Surgery/Wounds/Components/WoundComponent.csContent.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.csContent.Shared/Medical/Healing/HealingSystem.cs
| [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); |
There was a problem hiding this comment.
🎯 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.csRepository: 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.
| var severityApplied = damagePiece.Value > 0 | ||
| ? ApplySeverityModifiers(woundable, damagePiece.Value, component) | ||
| : damagePiece.Value; | ||
|
|
||
| if (!CanContinueWound( | ||
| woundable, | ||
| damagePiece.Key, | ||
| damagePiece.Value, | ||
| out var continuedWound, |
There was a problem hiding this comment.
🎯 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.
| 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.
| 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; | ||
| } |
There was a problem hiding this comment.
🎯 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 и
блокирующих травм. Не обрабатывайте кровоточащую рану до этих ограничений;
сначала выберите валидную рану, затем сбрасывайте кровотечение и изменяйте её
тяжесть, используя те же условия в обоих местах.
| // TODO: When complex bloodstream is implemented, rework adding blood | ||
| if (healing.ModifyBloodLevel != 0) | ||
| _bloodstreamSystem.TryModifyBloodLevel(ent, healing.ModifyBloodLevel); |
There was a problem hiding this comment.
🎯 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.
| 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); |
There was a problem hiding this comment.
🎯 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 отрицательную величину этого фактически
снятого значения, а не исходную лечебную дельту. Примените ту же корректировку
во втором аналогичном участке.
There was a problem hiding this comment.
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
📒 Files selected for processing (10)
Content.Server/Backmen/Body/Systems/BkmBurnWoundableSystem.csContent.Server/Backmen/Surgery/Wounds/Systems/ServerWoundSystem.csContent.Shared/Backmen/Body/OrganRelations/BkmDetachedBodySystem.csContent.Shared/Backmen/Body/Systems/BkmBodySharedSystem.Woundables.csContent.Shared/Backmen/Damage/DamageableSystem.Backmen.csContent.Shared/Backmen/Surgery/Wounds/Components/WoundComponent.csContent.Shared/Backmen/Surgery/Wounds/Components/WoundableComponent.csContent.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.Wounding.csContent.Shared/Backmen/Surgery/Wounds/Systems/WoundSystem.csContent.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
| 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); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
RaiseWoundEvents создаёт побочный случайный бросок слияния при каждом изменении тяжести раны.
RaiseWoundEvents вызывает GetWoundsChanged(woundable, woundableEnt, damageSpec, false) только для того, чтобы разослать WoundsDeltaChanged/WoundSeverityPointChangedEvent по уже применённой дельте конкретной раны (woundEnt). Но внутри GetWoundsChanged для этой же дельты снова вызывается CanContinueWound → RollForWoundMerging, то есть новый 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.
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
About the PR
Lechenie teper rabotaet adekvatno
Povischena vischivaemost lyudey, nebolschaya pererabotka woundov
Requirements
Summary by CodeRabbit
Новые возможности
wounding.wound_merge_ratio.Исправления