More blood tweaks (#6811)
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Server.Nutrition.Components;
|
||||
using Content.Server.Nutrition.EntitySystems;
|
||||
using Content.Shared.Administration;
|
||||
@@ -58,6 +60,7 @@ namespace Content.Server.Administration.Commands
|
||||
entMan.GetComponentOrNull<HungerComponent>(targetUid)?.ResetFood();
|
||||
entMan.GetComponentOrNull<ThirstComponent>(targetUid)?.ResetThirst();
|
||||
|
||||
// TODO holy shit make this an event my man!
|
||||
EntitySystem.Get<StatusEffectsSystem>().TryRemoveAllStatusEffects(target);
|
||||
|
||||
if (entMan.TryGetComponent(target, out FlammableComponent? flammable))
|
||||
@@ -75,6 +78,13 @@ namespace Content.Server.Administration.Commands
|
||||
EntitySystem.Get<CreamPieSystem>().SetCreamPied(target, creamPied, false);
|
||||
}
|
||||
|
||||
if (entMan.TryGetComponent(target, out BloodstreamComponent? bloodStream))
|
||||
{
|
||||
var sys = EntitySystem.Get<BloodstreamSystem>();
|
||||
sys.TryModifyBleedAmount(target, -bloodStream.BleedAmount, bloodStream);
|
||||
sys.TryModifyBloodLevel(target, bloodStream.BloodSolution.AvailableVolume, bloodStream);
|
||||
}
|
||||
|
||||
if (entMan.HasComponent<JitteringComponent>(target))
|
||||
{
|
||||
entMan.RemoveComponent<JitteringComponent>(target);
|
||||
|
||||
@@ -36,6 +36,12 @@ namespace Content.Server.Body.Components
|
||||
[DataField("bleedReductionAmount")]
|
||||
public float BleedReductionAmount = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// How high can <see cref="BleedAmount"/> go?
|
||||
/// </summary>
|
||||
[DataField("maxBleedAmount")]
|
||||
public float MaxBleedAmount = 20.0f;
|
||||
|
||||
/// <summary>
|
||||
/// What percentage of current blood is necessary to avoid dealing blood loss damage?
|
||||
/// </summary>
|
||||
@@ -89,6 +95,12 @@ namespace Content.Server.Body.Components
|
||||
[DataField("instantBloodSound")]
|
||||
public SoundSpecifier InstantBloodSound = new SoundCollectionSpecifier("blood");
|
||||
|
||||
/// <summary>
|
||||
/// The sound to be played when some damage actually heals bleeding rather than starting it.
|
||||
/// </summary>
|
||||
[DataField("bloodHealedSound")]
|
||||
public SoundSpecifier BloodHealedSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg");
|
||||
|
||||
// TODO probably damage bleed thresholds.
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -3,6 +3,7 @@ using Content.Server.Body.Components;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Server.Fluids.EntitySystems;
|
||||
using Content.Server.HealthExaminable;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Prototypes;
|
||||
@@ -21,6 +22,7 @@ public sealed class BloodstreamSystem : EntitySystem
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||
[Dependency] private readonly SpillableSystem _spillableSystem = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||
|
||||
@@ -63,7 +65,7 @@ public sealed class BloodstreamSystem : EntitySystem
|
||||
// as well as stop their bleeding to a certain extent.
|
||||
if (bloodstream.BleedAmount > 0)
|
||||
{
|
||||
TryModifyBloodLevel(uid, (-bloodstream.BleedAmount) / 10, bloodstream);
|
||||
TryModifyBloodLevel(uid, (-bloodstream.BleedAmount) / 20, bloodstream);
|
||||
TryModifyBleedAmount(uid, -bloodstream.BleedReductionAmount, bloodstream);
|
||||
}
|
||||
|
||||
@@ -113,17 +115,28 @@ public sealed class BloodstreamSystem : EntitySystem
|
||||
if (bloodloss.Empty)
|
||||
return;
|
||||
|
||||
var oldBleedAmount = component.BleedAmount;
|
||||
var total = bloodloss.Total;
|
||||
var totalFloat = total.Float();
|
||||
TryModifyBleedAmount(uid, totalFloat, component);
|
||||
|
||||
var prob = Math.Clamp(totalFloat / 50, 0, 1);
|
||||
if (_robustRandom.Prob(prob))
|
||||
var healPopupProb = Math.Clamp(Math.Abs(totalFloat) / 25, 0, 1);
|
||||
if (totalFloat > 0 && _robustRandom.Prob(prob))
|
||||
{
|
||||
// This is gonna hurt.
|
||||
TryModifyBloodLevel(uid, (-total) / 5, component);
|
||||
SoundSystem.Play(Filter.Pvs(uid), component.InstantBloodSound.GetSound(), uid, AudioParams.Default);
|
||||
}
|
||||
else if (totalFloat < 0 && oldBleedAmount > 0 && _robustRandom.Prob(healPopupProb))
|
||||
{
|
||||
// Magically, this damage has healed some bleeding, likely
|
||||
// because it's burn damage that cauterized their wounds.
|
||||
|
||||
// We'll play a special sound and popup for feedback.
|
||||
SoundSystem.Play(Filter.Pvs(uid), component.BloodHealedSound.GetSound(), uid, AudioParams.Default);
|
||||
_popupSystem.PopupEntity(Loc.GetString("bloodstream-component-wounds-cauterized"), uid,
|
||||
Filter.Entities(uid));
|
||||
; }
|
||||
}
|
||||
|
||||
private void OnHealthBeingExamined(EntityUid uid, BloodstreamComponent component, HealthBeingExaminedEvent args)
|
||||
@@ -208,7 +221,7 @@ public sealed class BloodstreamSystem : EntitySystem
|
||||
return false;
|
||||
|
||||
component.BleedAmount += amount;
|
||||
component.BleedAmount = Math.Clamp(component.BleedAmount, 0, 40);
|
||||
component.BleedAmount = Math.Clamp(component.BleedAmount, 0, component.MaxBleedAmount);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,13 @@ namespace Content.Server.Fluids.Components
|
||||
[ViewVariables] [DataField("overflowVolume")]
|
||||
public FixedPoint2 OverflowVolume = DefaultOverflowVolume;
|
||||
|
||||
/// <summary>
|
||||
/// How much should this puddle's opacity be multiplied by?
|
||||
/// Useful for puddles that have a high overflow volume but still want to be mostly opaque.
|
||||
/// </summary>
|
||||
[DataField("opacityModifier")]
|
||||
public float OpacityModifier = 1.0f;
|
||||
|
||||
public FixedPoint2 OverflowLeft => CurrentVolume - OverflowVolume;
|
||||
|
||||
[DataField("solution")] public string SolutionName { get; set; } = DefaultSolutionName;
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Content.Server.Fluids.EntitySystems
|
||||
|
||||
// Opacity based on level of fullness to overflow
|
||||
// Hard-cap lower bound for visibility reasons
|
||||
var volumeScale = puddleComponent.CurrentVolume.Float() / puddleComponent.OverflowVolume.Float();
|
||||
var volumeScale = puddleComponent.CurrentVolume.Float() / puddleComponent.OverflowVolume.Float() * puddleComponent.OpacityModifier;
|
||||
var puddleSolution = _solutionContainerSystem.EnsureSolution(uid, puddleComponent.SolutionName);
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
bloodstream-component-looks-pale = [color=bisque]{CAPITALIZE(SUBJECT($target))} looks pale.[/color]
|
||||
bloodstream-component-bleeding = [color=red]{CAPITALIZE(SUBJECT($target))} {CONJUGATE-BE($target)} bleeding.[/color]
|
||||
bloodstream-component-profusely-bleeding = [color=crimson]{CAPITALIZE(SUBJECT($target))} {CONJUGATE-BE($target)} profusely bleeding![/color]
|
||||
|
||||
bloodstream-component-wounds-cauterized = You feel your wounds painfully close!
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
Piercing: 2.0
|
||||
Shock: 0.0
|
||||
Cold: 0.0
|
||||
Heat: 0.0
|
||||
Heat: -0.25 # heat damage cauterizes wounds!
|
||||
Poison: 0.0
|
||||
Radiation: 0.0
|
||||
Asphyxiation: 0.0
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
- type: Puddle
|
||||
slipThreshold: 20
|
||||
overflowVolume: 50
|
||||
opacityModifier: 8
|
||||
- type: Evaporation
|
||||
evaporateTime: 400 # very slow
|
||||
- type: Appearance
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
name: blood
|
||||
group: Biological
|
||||
desc: I hope this is ketchup.
|
||||
color: "#9e1010"
|
||||
color: "#800000"
|
||||
physicalDesc: ferrous
|
||||
metabolisms:
|
||||
Drink:
|
||||
|
||||
Reference in New Issue
Block a user