Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pipe pressure damage #20931

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions Content.Server/NodeContainer/NodeGroups/PipeNet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using Content.Server.Atmos.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos;
using Content.Shared.Damage;
using Robust.Shared.Random;
using Robust.Shared.Utility;

namespace Content.Server.NodeContainer.NodeGroups
Expand All @@ -21,6 +23,9 @@ public sealed class PipeNet : BaseNodeGroup, IPipeNet
[ViewVariables] public GasMixture Air { get; set; } = new() {Temperature = Atmospherics.T20C};

[ViewVariables] private AtmosphereSystem? _atmosphereSystem;
[ViewVariables] private DamageableSystem? _damage;
[ViewVariables] private IEntityManager? _entMan;
[ViewVariables] private IRobustRandom? _random;

public EntityUid? Grid { get; private set; }

Expand All @@ -38,11 +43,53 @@ public override void Initialize(Node sourceNode, IEntityManager entMan)

_atmosphereSystem = entMan.EntitySysManager.GetEntitySystem<AtmosphereSystem>();
_atmosphereSystem.AddPipeNet(Grid.Value, this);
_damage = entMan.EntitySysManager.GetEntitySystem<DamageableSystem>();
_entMan = entMan;
_random = IoCManager.Resolve<IRobustRandom>();
}

/// <summary>
/// Calculate pressure damage for pipe. There is no damage if the pressure is below MaxPressure,
/// and damage scales exponentially beyond that.
/// </summary>
private int PressureDamage(PipeNode pipe)
{
const float tau = 10; // number of atmos ticks to break pipe at nominal overpressure
var diff = pipe.Air.Pressure - pipe.MaxPressure;
const float alpha = 100/tau;
return diff > 0 ? (int)(alpha*float.Exp(diff / pipe.MaxPressure)) : 0;
}

public void Update()
{
_atmosphereSystem?.React(Air, this);

// Check each pipe node for overpressure and apply damage if needed
foreach (var node in Nodes)
{
if (node is PipeNode pipe && pipe.MaxPressure > 0)
{
// Prefer damaging pipes that are already damaged. This means that only one pipe
// fails instead of the whole pipenet bursting at the same time.
const float baseChance = 0.5f;
float p = baseChance;
if (_entMan != null && _entMan.TryGetComponent<DamageableComponent>(pipe.Owner, out var damage))
{
p += (float)damage.TotalDamage * (1 - baseChance);
}

if (_random != null && _random.Prob(1-p))
continue;

int dam = PressureDamage(pipe);
if (dam > 0)
{
var dspec = new DamageSpecifier();
dspec.DamageDict.Add("Structural", dam);
_damage?.TryChangeDamage(pipe.Owner, dspec);
}
}
}
}

public override void LoadNodes(List<Node> groupNodes)
Expand Down
6 changes: 6 additions & 0 deletions Content.Server/NodeContainer/Nodes/PipeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ public GasMixture Air

private const float DefaultVolume = 200f;

/// <summary>
/// Pressure beyond which this pipe node starts taking damage. Set to zero for no pressure damage.
/// </summary>
[DataField]
public float MaxPressure = 0;

public override void Initialize(EntityUid owner, IEntityManager entMan)
{
base.Initialize(owner, entMan);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
!type:PipeNode
nodeGroupID: Pipe
pipeDirection: Longitudinal
maxPressure: 6750
- type: Sprite
layers:
- state: pipeStraight
Expand All @@ -102,6 +103,7 @@
!type:PipeNode
nodeGroupID: Pipe
pipeDirection: SWBend
maxPressure: 6750
- type: Sprite
layers:
- state: pipeBend
Expand All @@ -121,6 +123,7 @@
!type:PipeNode
nodeGroupID: Pipe
pipeDirection: TSouth
maxPressure: 6750
- type: Sprite
layers:
- state: pipeTJunction
Expand All @@ -142,6 +145,7 @@
!type:PipeNode
nodeGroupID: Pipe
pipeDirection: Fourway
maxPressure: 6750
- type: Sprite
layers:
- state: pipeFourway
Expand Down
Loading