mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Grid delta states (#3635)
This commit is contained in:
@@ -103,10 +103,15 @@ public abstract partial class SharedMapSystem
|
||||
|
||||
component.ChunkSize = state.ChunkSize;
|
||||
|
||||
if (state.ChunkData == null && state.FullGridData == null)
|
||||
return;
|
||||
|
||||
var modified = new List<(Vector2i position, Tile tile)>();
|
||||
MapManager.SuppressOnTileChanged = true;
|
||||
|
||||
// delta state
|
||||
if (state.ChunkData != null)
|
||||
{
|
||||
var modified = new List<(Vector2i position, Tile tile)>();
|
||||
MapManager.SuppressOnTileChanged = true;
|
||||
foreach (var chunkData in state.ChunkData)
|
||||
{
|
||||
if (chunkData.IsDeleted())
|
||||
@@ -143,19 +148,55 @@ public abstract partial class SharedMapSystem
|
||||
chunk.SuppressCollisionRegeneration = false;
|
||||
component.RegenerateCollision(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
MapManager.SuppressOnTileChanged = false;
|
||||
|
||||
if (modified.Count != 0)
|
||||
// full state
|
||||
if (state.FullGridData != null)
|
||||
{
|
||||
foreach (var index in component.Chunks.Keys)
|
||||
{
|
||||
RaiseLocalEvent(uid, new GridModifiedEvent(component, modified), true);
|
||||
if (!state.FullGridData.ContainsKey(index))
|
||||
component.RemoveChunk(index);
|
||||
}
|
||||
|
||||
foreach (var (index, tiles) in state.FullGridData)
|
||||
{
|
||||
var chunk = component.GetOrAddChunk(index);
|
||||
chunk.SuppressCollisionRegeneration = true;
|
||||
DebugTools.Assert(tiles.Length == component.ChunkSize * component.ChunkSize);
|
||||
|
||||
var counter = 0;
|
||||
for (ushort x = 0; x < component.ChunkSize; x++)
|
||||
{
|
||||
for (ushort y = 0; y < component.ChunkSize; y++)
|
||||
{
|
||||
var tile = tiles[counter++];
|
||||
if (chunk.GetTile(x, y) == tile)
|
||||
continue;
|
||||
|
||||
chunk.SetTile(x, y, tile);
|
||||
modified.Add((new Vector2i(chunk.X * component.ChunkSize + x, chunk.Y * component.ChunkSize + y), tile));
|
||||
}
|
||||
}
|
||||
|
||||
chunk.SuppressCollisionRegeneration = false;
|
||||
component.RegenerateCollision(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
MapManager.SuppressOnTileChanged = false;
|
||||
if (modified.Count != 0)
|
||||
RaiseLocalEvent(uid, new GridModifiedEvent(component, modified), true);
|
||||
}
|
||||
|
||||
private void OnGridGetState(EntityUid uid, MapGridComponent component, ref ComponentGetState args)
|
||||
{
|
||||
// TODO: Actual deltas.
|
||||
if (args.FromTick <= component.CreationTick)
|
||||
{
|
||||
GetFullState(component, ref args);
|
||||
return;
|
||||
}
|
||||
|
||||
List<ChunkDatum>? chunkData;
|
||||
var fromTick = args.FromTick;
|
||||
|
||||
@@ -170,7 +211,7 @@ public abstract partial class SharedMapSystem
|
||||
|
||||
foreach (var (tick, indices) in chunks)
|
||||
{
|
||||
if (tick < fromTick)
|
||||
if (tick < fromTick && fromTick != GameTick.Zero)
|
||||
continue;
|
||||
|
||||
chunkData.Add(ChunkDatum.CreateDeleted(indices));
|
||||
@@ -197,7 +238,27 @@ public abstract partial class SharedMapSystem
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Mark it as delta proper
|
||||
args.State = new MapGridComponentState(component.ChunkSize, chunkData);
|
||||
}
|
||||
|
||||
private void GetFullState(MapGridComponent component, ref ComponentGetState args)
|
||||
{
|
||||
var chunkData = new Dictionary<Vector2i, Tile[]>();
|
||||
|
||||
foreach (var (index, chunk) in component.GetMapChunks())
|
||||
{
|
||||
var tileBuffer = new Tile[component.ChunkSize * (uint)component.ChunkSize];
|
||||
|
||||
for (var x = 0; x < component.ChunkSize; x++)
|
||||
{
|
||||
for (var y = 0; y < component.ChunkSize; y++)
|
||||
{
|
||||
tileBuffer[x * component.ChunkSize + y] = chunk.GetTile((ushort)x, (ushort)y);
|
||||
}
|
||||
}
|
||||
chunkData.Add(index, tileBuffer);
|
||||
}
|
||||
|
||||
args.State = new MapGridComponentState(component.ChunkSize, chunkData);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Map.Enumerators;
|
||||
using Robust.Shared.Map.Events;
|
||||
using Robust.Shared.Maths;
|
||||
@@ -901,7 +902,7 @@ namespace Robust.Shared.Map.Components
|
||||
/// Serialized state of a <see cref="MapGridComponentState"/>.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
internal sealed class MapGridComponentState : ComponentState
|
||||
internal sealed class MapGridComponentState : ComponentState, IComponentDeltaState
|
||||
{
|
||||
/// <summary>
|
||||
/// The size of the chunks in the map grid.
|
||||
@@ -914,12 +915,65 @@ namespace Robust.Shared.Map.Components
|
||||
public List<ChunkDatum>? ChunkData;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of <see cref="MapGridComponentState"/>.
|
||||
/// Networked chunk data containing the full grid state.
|
||||
/// </summary>
|
||||
public Dictionary<Vector2i, Tile[]>? FullGridData;
|
||||
|
||||
public bool FullState => FullGridData != null;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new grid component delta state.
|
||||
/// </summary>
|
||||
public MapGridComponentState(ushort chunkSize, List<ChunkDatum>? chunkData)
|
||||
{
|
||||
ChunkSize = chunkSize;
|
||||
ChunkData = chunkData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new full component state.
|
||||
/// </summary>
|
||||
public MapGridComponentState(ushort chunkSize, Dictionary<Vector2i, Tile[]> fullGridData)
|
||||
{
|
||||
ChunkSize = chunkSize;
|
||||
FullGridData = fullGridData;
|
||||
}
|
||||
|
||||
public void ApplyToFullState(ComponentState fullState)
|
||||
{
|
||||
var state = (MapGridComponentState)fullState;
|
||||
DebugTools.Assert(!FullState && state.FullState);
|
||||
|
||||
state.ChunkSize = ChunkSize;
|
||||
|
||||
if (ChunkData == null)
|
||||
return;
|
||||
|
||||
foreach (var data in ChunkData)
|
||||
{
|
||||
if (data.IsDeleted())
|
||||
state.FullGridData!.Remove(data.Index);
|
||||
else
|
||||
state.FullGridData![data.Index] = data.TileData;
|
||||
}
|
||||
}
|
||||
|
||||
public ComponentState CreateNewFullState(ComponentState fullState)
|
||||
{
|
||||
var state = (MapGridComponentState)fullState;
|
||||
DebugTools.Assert(!FullState && state.FullState);
|
||||
|
||||
var fullGridData = new Dictionary<Vector2i, Tile[]>(state.FullGridData!.Count);
|
||||
|
||||
foreach (var (key, value) in state.FullGridData)
|
||||
{
|
||||
var arr = fullGridData[key] = new Tile[value.Length];
|
||||
Array.Copy(value, arr, value.Length);
|
||||
}
|
||||
|
||||
var newState = new MapGridComponentState(ChunkSize, fullGridData);
|
||||
ApplyToFullState(newState);
|
||||
return newState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
|
||||
new EntityUid(512),
|
||||
new []
|
||||
{
|
||||
new ComponentChange(0, new MapGridComponentState(16, null), default)
|
||||
new ComponentChange(0, new MapGridComponentState(16, chunkData: null), default)
|
||||
}, default);
|
||||
|
||||
serializer.Serialize(stream, payload);
|
||||
|
||||
Reference in New Issue
Block a user