From 0444896603ca4680bf3080942a53e1a03ac7276a Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Sat, 20 Dec 2025 12:54:14 -0800 Subject: [PATCH] [Staging/Hotfix] A couple bloodstream fixes. (#41906) Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- .../Body/Systems/SharedBloodstreamSystem.cs | 84 ++++++++++--------- .../Prototypes/Recipes/Reactions/cleaning.yml | 2 + 2 files changed, 48 insertions(+), 38 deletions(-) diff --git a/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs b/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs index 5f3794acd2..e86fd0c06b 100644 --- a/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs +++ b/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs @@ -1,4 +1,3 @@ -using System.Linq; using Content.Shared.Alert; using Content.Shared.Body.Components; using Content.Shared.Body.Events; @@ -71,49 +70,41 @@ public abstract class SharedBloodstreamSystem : EntitySystem bloodstream.NextUpdate += bloodstream.AdjustedUpdateInterval; DirtyField(uid, bloodstream, nameof(BloodstreamComponent.NextUpdate)); // needs to be dirtied on the client so it can be rerolled during prediction - if (!SolutionContainer.ResolveSolution(uid, bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution)) + if (!SolutionContainer.ResolveSolution(uid, bloodstream.BloodSolutionName, ref bloodstream.BloodSolution)) continue; // Blood level regulation. Must be alive. - TryRegulateBloodLevel(uid, bloodstream.BloodRefreshAmount); - - // Removes blood from the bloodstream based on bleed amount (bleed rate) - // as well as stop their bleeding to a certain extent. - if (bloodstream.BleedAmount > 0) - { - var ev = new BleedModifierEvent(bloodstream.BleedAmount, bloodstream.BleedReductionAmount); - RaiseLocalEvent(uid, ref ev); - - // Blood is removed from the bloodstream at a 1-1 rate with the bleed amount - TryBleedOut((uid, bloodstream), ev.BleedAmount); - - // Bleed rate is reduced by the bleed reduction amount in the bloodstream component. - TryModifyBleedAmount((uid, bloodstream), -ev.BleedReductionAmount); - } - - // deal bloodloss damage if their blood level is below a threshold. - var bloodPercentage = GetBloodLevel(uid); - if (bloodPercentage < bloodstream.BloodlossThreshold && !_mobStateSystem.IsDead(uid)) + if (!_mobStateSystem.IsDead(uid)) { - // bloodloss damage is based on the base value, and modified by how low your blood level is. - var amt = bloodstream.BloodlossDamage / (0.1f + bloodPercentage); - - _damageableSystem.TryChangeDamage(uid, amt, ignoreResistances: false, interruptsDoAfters: false); - - // Apply dizziness as a symptom of bloodloss. - // The effect is applied in a way that it will never be cleared without being healthy. - // Multiplying by 2 is arbitrary but works for this case, it just prevents the time from running out - _status.TrySetStatusEffectDuration(uid, Bloodloss); + TryRegulateBloodLevel(uid, bloodstream.BloodRefreshAmount); + + TickBleed((uid, bloodstream)); + + // deal bloodloss damage if their blood level is below a threshold. + var bloodPercentage = GetBloodLevel(uid); + if (bloodPercentage < bloodstream.BloodlossThreshold) + { + // bloodloss damage is based on the base value, and modified by how low your blood level is. + var amt = bloodstream.BloodlossDamage / (0.1f + bloodPercentage); + + _damageableSystem.TryChangeDamage(uid, amt, ignoreResistances: false, interruptsDoAfters: false); + + // Apply dizziness as a symptom of bloodloss. + // The effect is applied in a way that it will never be cleared without being healthy. + // Multiplying by 2 is arbitrary but works for this case, it just prevents the time from running out + _status.TrySetStatusEffectDuration(uid, Bloodloss); + } + else + { + // If they're healthy, we'll try and heal some bloodloss instead. + _damageableSystem.TryChangeDamage(uid, bloodstream.BloodlossHealDamage * bloodPercentage, ignoreResistances: true, interruptsDoAfters: false); + + _status.TryRemoveStatusEffect(uid, Bloodloss); + } } - else if (!_mobStateSystem.IsDead(uid)) + else { - // If they're healthy, we'll try and heal some bloodloss instead. - _damageableSystem.TryChangeDamage( - uid, - bloodstream.BloodlossHealDamage * bloodPercentage, - ignoreResistances: true, interruptsDoAfters: false); - - _status.TryRemoveStatusEffect(uid, Bloodloss); + TickBleed((uid, bloodstream)); } } } @@ -437,6 +428,23 @@ public abstract class SharedBloodstreamSystem : EntitySystem return true; } + public void TickBleed(Entity entity) + { + // Removes blood from the bloodstream based on bleed amount (bleed rate) + // as well as stop their bleeding to a certain extent. + if (entity.Comp.BleedAmount <= 0) + return; + + var ev = new BleedModifierEvent(entity.Comp.BleedAmount, entity.Comp.BleedReductionAmount); + RaiseLocalEvent(entity, ref ev); + + // Blood is removed from the bloodstream at a 1-1 rate with the bleed amount + TryBleedOut(entity.AsNullable(), ev.BleedAmount); + + // Bleed rate is reduced by the bleed reduction amount in the bloodstream component. + TryModifyBleedAmount(entity.AsNullable(), -ev.BleedReductionAmount); + } + /// /// Removes blood by spilling out the bloodstream. /// diff --git a/Resources/Prototypes/Recipes/Reactions/cleaning.yml b/Resources/Prototypes/Recipes/Reactions/cleaning.yml index 079e1bf747..f3440b6efd 100644 --- a/Resources/Prototypes/Recipes/Reactions/cleaning.yml +++ b/Resources/Prototypes/Recipes/Reactions/cleaning.yml @@ -12,6 +12,8 @@ - type: reaction id: AmmoniaFromBlood + requiredMixerCategories: + - Stir # prevents evaporating vox blood, TODO: make it react only X units per second; make bloodstream an open thermal system minTemp: 370 reactants: AmmoniaBlood: -- 2.52.0