using System.Collections.Generic;
using System.Numerics;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.ViewVariables;
namespace Robust.Server.Physics.Components;
///
/// Holds data for grid-split nodes so we can quickly check if a grid should split.
///
[RegisterComponent]
public sealed partial class GridSplitNodeComponent : Component
{
[ViewVariables]
public readonly Dictionary Nodes = new();
}
public sealed class ChunkNodeGroup
{
internal MapChunk Chunk = default!;
public HashSet Nodes = new();
}
public sealed class ChunkSplitNode
{
public ChunkNodeGroup Group = default!;
public List Indices { get; } = new();
public HashSet Neighbors { get; } = new();
public int TileCount
{
get
{
var count = 0;
foreach (var box in Indices)
{
count += box.Width * box.Height;
}
return count;
}
}
public void AddIndex(Vector2i index)
{
Indices.Add(new Box2i(index.X, index.Y, index.X + 1, index.Y + 1));
}
public void CompactIndices()
{
if (Indices.Count <= 1)
return;
var tiles = new List(TileCount);
foreach (var index in GetTileIndices())
{
tiles.Add(index);
}
tiles.Sort((a, b) =>
{
var y = a.Y.CompareTo(b.Y);
return y != 0 ? y : a.X.CompareTo(b.X);
});
Indices.Clear();
var start = tiles[0];
var previous = start;
for (var i = 1; i < tiles.Count; i++)
{
var tile = tiles[i];
if (tile.Y == previous.Y && tile.X == previous.X + 1)
{
previous = tile;
continue;
}
Indices.Add(new Box2i(start.X, start.Y, previous.X + 1, previous.Y + 1));
start = previous = tile;
}
Indices.Add(new Box2i(start.X, start.Y, previous.X + 1, previous.Y + 1));
}
public bool Contains(Vector2i index)
{
foreach (var box in Indices)
{
if (!box.ContainsTile(index))
continue;
return true;
}
return false;
}
public IEnumerable GetTileIndices()
{
foreach (var box in Indices)
{
for (var x = box.Left; x < box.Right; x++)
{
for (var y = box.Bottom; y < box.Top; y++)
{
yield return new Vector2i(x, y);
}
}
}
}
public Vector2 GetCentre()
{
var centre = Vector2.Zero;
var count = 0;
foreach (var index in GetTileIndices())
{
centre += index;
count++;
}
centre /= count;
return centre;
}
}