Gas tile overlay state handling changes (#12691)
This commit is contained in:
81
Content.Shared/Atmos/Components/GasTileOverlayComponent.cs
Normal file
81
Content.Shared/Atmos/Components/GasTileOverlayComponent.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Atmos.Components;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed class GasTileOverlayComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The tiles that have had their atmos data updated since last tick
|
||||
/// </summary>
|
||||
public readonly HashSet<Vector2i> InvalidTiles = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gas data stored in chunks to make PVS / bubbling easier.
|
||||
/// </summary>
|
||||
public readonly Dictionary<Vector2i, GasOverlayChunk> Chunks = new();
|
||||
|
||||
/// <summary>
|
||||
/// Tick at which PVS was last toggled. Ensures that all players receive a full update when toggling PVS.
|
||||
/// </summary>
|
||||
public GameTick ForceTick { get; set; }
|
||||
}
|
||||
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class GasTileOverlayState : ComponentState, IComponentDeltaState
|
||||
{
|
||||
public readonly Dictionary<Vector2i, GasOverlayChunk> Chunks;
|
||||
public bool FullState => AllChunks == null;
|
||||
|
||||
// required to infer deleted/missing chunks for delta states
|
||||
public HashSet<Vector2i>? AllChunks;
|
||||
|
||||
public GasTileOverlayState(Dictionary<Vector2i, GasOverlayChunk> chunks)
|
||||
{
|
||||
Chunks = chunks;
|
||||
}
|
||||
|
||||
public void ApplyToFullState(ComponentState fullState)
|
||||
{
|
||||
DebugTools.Assert(!FullState);
|
||||
var state = (GasTileOverlayState) fullState;
|
||||
DebugTools.Assert(state.FullState);
|
||||
|
||||
foreach (var key in state.Chunks.Keys)
|
||||
{
|
||||
if (!AllChunks!.Contains(key))
|
||||
state.Chunks.Remove(key);
|
||||
}
|
||||
|
||||
foreach (var (chunk, data) in Chunks)
|
||||
{
|
||||
state.Chunks[chunk] = new(data);
|
||||
}
|
||||
}
|
||||
|
||||
public ComponentState CreateNewFullState(ComponentState fullState)
|
||||
{
|
||||
DebugTools.Assert(!FullState);
|
||||
var state = (GasTileOverlayState) fullState;
|
||||
DebugTools.Assert(state.FullState);
|
||||
|
||||
var chunks = new Dictionary<Vector2i, GasOverlayChunk>(state.Chunks.Count);
|
||||
|
||||
foreach (var (chunk, data) in Chunks)
|
||||
{
|
||||
chunks[chunk] = new(data);
|
||||
}
|
||||
|
||||
foreach (var (chunk, data) in state.Chunks)
|
||||
{
|
||||
if (AllChunks!.Contains(chunk))
|
||||
chunks.TryAdd(chunk, new(data));
|
||||
}
|
||||
|
||||
return new GasTileOverlayState(chunks);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Shared.Atmos.Prototypes;
|
||||
using Content.Shared.GameTicking;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
@@ -21,8 +20,6 @@ namespace Content.Shared.Atmos.EntitySystems
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
|
||||
|
||||
List<int> visibleGases = new();
|
||||
|
||||
for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++)
|
||||
@@ -35,8 +32,6 @@ namespace Content.Shared.Atmos.EntitySystems
|
||||
VisibleGasId = visibleGases.ToArray();
|
||||
}
|
||||
|
||||
public abstract void Reset(RoundRestartCleanupEvent ev);
|
||||
|
||||
public static Vector2i GetGasChunkIndices(Vector2i indices)
|
||||
{
|
||||
return new((int) MathF.Floor((float) indices.X / ChunkSize), (int) MathF.Floor((float) indices.Y / ChunkSize));
|
||||
|
||||
@@ -33,6 +33,19 @@ namespace Content.Shared.Atmos
|
||||
}
|
||||
}
|
||||
|
||||
public GasOverlayChunk(GasOverlayChunk data)
|
||||
{
|
||||
Index = data.Index;
|
||||
Origin = data.Origin;
|
||||
for (int i = 0; i < ChunkSize; i++)
|
||||
{
|
||||
// This does not clone the opacity array. However, this chunk cloning is only used by the client,
|
||||
// which never modifies that directly. So this should be fine.
|
||||
var array = TileData[i] = new GasOverlayData[ChunkSize];
|
||||
Array.Copy(data.TileData[i], array, ChunkSize);
|
||||
}
|
||||
}
|
||||
|
||||
public ref GasOverlayData GetData(Vector2i gridIndices)
|
||||
{
|
||||
DebugTools.Assert(InBounds(gridIndices));
|
||||
|
||||
Reference in New Issue
Block a user