diff --git a/Content.Server/Body/Systems/BloodstreamSystem.cs b/Content.Server/Body/Systems/BloodstreamSystem.cs index 9816c8c3f6..6d85affad3 100644 --- a/Content.Server/Body/Systems/BloodstreamSystem.cs +++ b/Content.Server/Body/Systems/BloodstreamSystem.cs @@ -205,10 +205,13 @@ public sealed class BloodstreamSystem : EntitySystem } // TODO probably cache this or something. humans get hurt a lot - if (!_prototypeManager.TryIndex(ent.Comp.DamageBleedModifiers, out var modifiers)) + if (!_prototypeManager.TryIndex(ent.Comp.DamageBleedModifiers, out var modifiers)) return; - var bloodloss = DamageSpecifier.ApplyModifierSet(args.DamageDelta, modifiers); + // some reagents may deal and heal different damage types in the same tick, which means DamageIncreased will be true + // but we only want to consider the dealt damage when causing bleeding + var damage = DamageSpecifier.GetPositive(args.DamageDelta); + var bloodloss = DamageSpecifier.ApplyModifierSet(damage, modifiers); if (bloodloss.Empty) return; @@ -227,7 +230,7 @@ public sealed class BloodstreamSystem : EntitySystem var prob = Math.Clamp(totalFloat / 25, 0, 1); if (totalFloat > 0 && _robustRandom.Prob(prob)) { - TryModifyBloodLevel(ent, (-total) / 5, ent); + TryModifyBloodLevel(ent, -total / 5, ent); _audio.PlayPvs(ent.Comp.InstantBloodSound, ent); } diff --git a/Content.Shared/Damage/DamageSpecifier.cs b/Content.Shared/Damage/DamageSpecifier.cs index 7f505b807f..51472a56bd 100644 --- a/Content.Shared/Damage/DamageSpecifier.cs +++ b/Content.Shared/Damage/DamageSpecifier.cs @@ -23,7 +23,7 @@ namespace Content.Shared.Damage [JsonPropertyName("types")] [DataField("types", customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] [UsedImplicitly] - private Dictionary? _damageTypeDictionary; + private Dictionary? _damageTypeDictionary; [JsonPropertyName("groups")] [DataField("groups", customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] @@ -152,7 +152,7 @@ namespace Content.Shared.Damage if (modifierSet.Coefficients.TryGetValue(key, out var coefficient)) newValue *= coefficient; // coefficients can heal you, e.g. cauterizing bleeding - if(newValue != 0) + if (newValue != 0) newDamage.DamageDict[key] = FixedPoint2.New(newValue); } @@ -183,6 +183,38 @@ namespace Content.Shared.Damage return newDamage; } + /// + /// Returns a new DamageSpecifier that only contains the entries with positive value. + /// + public static DamageSpecifier GetPositive(DamageSpecifier damageSpec) + { + DamageSpecifier newDamage = new(); + + foreach (var (key, value) in damageSpec.DamageDict) + { + if (value > 0) + newDamage.DamageDict[key] = value; + } + + return newDamage; + } + + /// + /// Returns a new DamageSpecifier that only contains the entries with negative value. + /// + public static DamageSpecifier GetNegative(DamageSpecifier damageSpec) + { + DamageSpecifier newDamage = new(); + + foreach (var (key, value) in damageSpec.DamageDict) + { + if (value < 0) + newDamage.DamageDict[key] = value; + } + + return newDamage; + } + /// /// Remove any damage entries with zero damage. /// diff --git a/Resources/Prototypes/Damage/modifier_sets.yml b/Resources/Prototypes/Damage/modifier_sets.yml index 3a3a372b6e..0f023e2470 100644 --- a/Resources/Prototypes/Damage/modifier_sets.yml +++ b/Resources/Prototypes/Damage/modifier_sets.yml @@ -237,21 +237,24 @@ # Represents which damage types should be modified # in relation to how they cause bleed rate. +# Make sure to add any new damage type here. - type: damageModifierSet id: BloodlossHuman coefficients: - Blunt: 0.08 - Slash: 0.25 - Piercing: 0.2 - Shock: 0.0 - Cold: 0.0 - Heat: -0.5 # heat damage cauterizes wounds, but will still hurt obviously. - Poison: 0.0 - Radiation: 0.0 Asphyxiation: 0.0 Bloodloss: 0.0 # no double dipping - Cellular: 0.0 + Blunt: 0.08 Caustic: 0.0 + Cellular: 0.0 + Cold: 0.0 + Heat: -0.5 # heat damage cauterizes wounds, but will still hurt obviously. + Holy: 0 + Piercing: 0.2 + Poison: 0.0 + Radiation: 0.0 + Shock: 0.0 + Slash: 0.25 + Structural: 0.0 - type: damageModifierSet id: SlimePet # Very survivable slimes