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

Garteg Murder #211

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
3 changes: 0 additions & 3 deletions Content.Server/Content.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,5 @@
<ProjectReference Include="..\RobustToolbox\Robust.Server\Robust.Server.csproj" />
<ProjectReference Include="..\Content.Shared\Content.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Objectives\Interfaces\" />
</ItemGroup>
<Import Project="..\RobustToolbox\MSBuild\Robust.Properties.targets" />
</Project>
43 changes: 43 additions & 0 deletions Content.Server/_EE/Atmos/AtmosphereSystem.EE.API.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Atmos.Components;
using Content.Shared.Atmos;


namespace Content.Server.Atmos.EntitySystems;

/// <summary>
/// This handles...
/// </summary>
public partial class AtmosphereSystem
{
public TileAtmosphere? GetTileAtmosphere(Entity<GridAtmosphereComponent?> grid, Vector2i tile)
{
if (!_atmosQuery.Resolve(grid, ref grid.Comp, false))
return null;

return grid.Comp.Tiles.TryGetValue(tile, out var atmosTile) ? atmosTile : null;
}

public bool TryGetTileAtmosphere(Entity<GridAtmosphereComponent?> grid, Vector2i tile, [NotNullWhen(true)] out TileAtmosphere? tileAtmosphere)
{
if (!_atmosQuery.Resolve(grid, ref grid.Comp, false))
{
tileAtmosphere = null;
return false;
}

var success = grid.Comp.Tiles.TryGetValue(tile, out var atmosTile);
tileAtmosphere = success ? atmosTile : null;
return success;
}

public TileEnumerator GetAdjacentTileAtmospheres(Entity<GridAtmosphereComponent?> grid, Vector2i tile, bool includeBlocked = false, bool excite = false)
{
if (!_atmosQuery.Resolve(grid, ref grid.Comp, false))
return TileEnumerator.Empty;

return !grid.Comp.Tiles.TryGetValue(tile, out var atmosTile)
? TileEnumerator.Empty
: new(atmosTile.AdjacentTiles);
}
}
31 changes: 31 additions & 0 deletions Content.Server/_EE/Atmos/TileEnumerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Diagnostics.CodeAnalysis;
using Content.Shared.Atmos;

namespace Content.Server.Atmos;

public struct TileEnumerator
{
public readonly TileAtmosphere?[] Tiles;
public int Index = 0;

public static readonly TileEnumerator Empty = new([]);

internal TileEnumerator(TileAtmosphere?[] tiles)
{
Tiles = tiles;
}

public bool MoveNext([NotNullWhen(true)] out TileAtmosphere? tileAtmosphere)
{
while (Index < Tiles.Length)
{
tileAtmosphere = Tiles[Index++];

if (tileAtmosphere != null)
return true;
}

tileAtmosphere = null;
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;


namespace Content.Server._EE.PressureDestructible.Components;


/// <summary>
/// This is used in making pressure destroy structures.
/// </summary>
[RegisterComponent]
public sealed partial class PressureDestructibleComponent : Component
{
/// <summary>
/// How much pressure could this entity reasonably withstand?
/// </summary>
[DataField]
public float MaxPressureDifferential { get; set; }

/// <summary>
/// How much damage, as a percentage, will the entity take?
/// </summary>
[DataField]
public int Damage { get; set; } = 20;

[DataField("nextUpdate", customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan NextUpdate { get; set; }

[DataField]
public TimeSpan CheckInterval { get; set; } = TimeSpan.FromSeconds(5);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Content.Server._EE.PressureDestructible.Components;


/// <summary>
/// This is used for setting an entity as immune to pressure destructible.
/// </summary>
[RegisterComponent]
public sealed partial class PressureDestructibleImmuneComponent : Component;
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using Content.Server._EE.PressureDestructible.Components;
using Content.Server.Atmos;
using Content.Server.Atmos.EntitySystems;
using Content.Shared.Atmos;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Robust.Server.GameObjects;
using Robust.Shared.Timing;

namespace Content.Server._EE.PressureDestructible.EntitySystems;


/// <summary>
/// This handles destroying entities based on pressure if it has a PressureDestructible component
/// </summary>
public sealed class PressureDestructibleSystem : EntitySystem
{
[Dependency] private TransformSystem _transform = default!;
[Dependency] private AtmosphereSystem _atmosphere = default!;
[Dependency] private DamageableSystem _damageable = default!;
[Dependency] private IGameTiming _gameTiming = default!;

public override void Update(float frameTime)
{
base.Update(frameTime);

var query = EntityManager.EntityQueryEnumerator<PressureDestructibleComponent, DamageableComponent>();
while (query.MoveNext(out var uid, out var pressureDestructible, out var damageable))
{
if (_gameTiming.CurTime < pressureDestructible.NextUpdate || pressureDestructible.MaxPressureDifferential == 0)
continue;

pressureDestructible.NextUpdate = _gameTiming.CurTime + pressureDestructible.CheckInterval;

if (uid == EntityUid.Invalid || !Exists(uid))
continue;

var grid = _transform.GetGrid(uid);
var currentTile = _transform.GetGridOrMapTilePosition(uid);

if (grid == null || grid == EntityUid.Invalid || !Exists(grid))
continue;

var hasAtmos = _atmosphere.TryGetTileAtmosphere((grid.Value, null), currentTile, out _);

if (!hasAtmos)
continue;

var adjacentTiles = new HashSet<TileAtmosphere>();
var directionsToCheck = new[] { AtmosDirection.North, AtmosDirection.East, AtmosDirection.South, AtmosDirection.West };

foreach (var direction in directionsToCheck)
{
var adjacentTile = currentTile.Offset(direction);

if (!_atmosphere.TryGetTileAtmosphere(grid.Value, adjacentTile, out var adjacentAtmos))
continue;

adjacentTiles.Add(adjacentAtmos);
}

var greatestDifference = 0f;
TileAtmosphere? largestPressureTile = null;

foreach (var tileAtmos in adjacentTiles)
{
var largestPressure = largestPressureTile?.Air?.Pressure ?? 0;
var tileMix = _atmosphere.GetTileMixture(grid.Value, null, tileAtmos.GridIndices, true);
var tilePressure = tileMix?.Pressure!;

if (tilePressure == null)
return;

var difference = MathF.Abs(largestPressure - (float) tilePressure);

if (tilePressure == 0)
continue;

if (difference > greatestDifference)
greatestDifference = difference;

if (tilePressure > largestPressure)
largestPressureTile = tileAtmos;
}

if (greatestDifference < pressureDestructible.MaxPressureDifferential || HasComp<PressureDestructibleImmuneComponent>(uid))
continue;

var damageSpecifier = damageable.Damage;
var currentDamage = damageSpecifier["Blunt"];

damageSpecifier.DamageDict["Blunt"] = currentDamage + pressureDestructible.Damage;
_damageable.SetDamage(uid, damageable, damageSpecifier);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
components:
- type: Clickable
- type: InteractionOutline
- type: PressureDestructible
maxPressureDifferential: 12500.0
- type: Sprite
sprite: Objects/Misc/inflatable_wall.rsi
state: inflatable_wall
Expand Down Expand Up @@ -47,6 +49,8 @@
components:
- type: Clickable
- type: InteractionOutline
- type: PressureDestructible
maxPressureDifferential: 12500.0
- type: Sprite
sprite: Objects/Misc/inflatable_door.rsi
state: closed
Expand Down
2 changes: 2 additions & 0 deletions Resources/Prototypes/Entities/Structures/Windows/plasma.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
price: 60
- type: RadiationBlocker
resistance: 4
- type: PressureDestructible
maxPressureDifferential: 3000

- type: entity
id: PlasmaWindowDirectional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
trackAllDamage: true
damageOverlay:
sprite: Structures/Windows/cracks.rsi
- type: PressureDestructible
maxPressureDifferential: 100000.0

- type: entity
parent: ReinforcedWindow
Expand Down Expand Up @@ -134,6 +136,8 @@
acts: [ "Destruction" ]
- type: StaticPrice
price: 22
- type: PressureDestructible
maxPressureDifferential: 5000.0

- type: entity
parent: ReinforcedWindow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
sprite: Structures/Windows/cracks.rsi
- type: StaticPrice
price: 132
- type: PressureDestructible
maxPressureDifferential: 0.0

- type: entity
id: PlasmaReinforcedWindowDirectional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
price: 140
- type: RadiationBlocker
resistance: 10
- type: PressureDestructible
maxPressureDifferential: 0.0

- type: entity
id: UraniumReinforcedWindowDirectional
Expand Down Expand Up @@ -100,6 +102,8 @@
acts: [ "Destruction" ]
- type: StaticPrice
price: 70
- type: PressureDestructible
maxPressureDifferential: 7500.0

- type: entity
parent: ReinforcedUraniumWindow
Expand Down
4 changes: 4 additions & 0 deletions Resources/Prototypes/Entities/Structures/Windows/window.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@
allowedVerbs:
- KnockOn
- LickObject
- type: PressureDestructible
maxPressureDifferential: 2000.0

- type: entity
id: WindowRCDResistant
Expand Down Expand Up @@ -194,6 +196,8 @@
allowedVerbs:
- KnockOn
- LickObject
- type: PressureDestructible
maxPressureDifferential: 3000.0

- type: entity
id: WindowDirectionalRCDResistant
Expand Down
Loading