namespace Server.Engines.Pathing.Cache;
///
/// Per-chunk storage backing StepCache. Holds raw walkability masks and
/// destination Z values for each of 256 cells in a 16x16 chunk, plus build-time
/// metadata (multis version, multi-Z bitmap) and LRU bookkeeping.
///
internal sealed class StepChunk
{
public const int CellsPerChunk = 256; // 16 x 16
/// Bit i of Mask[c] = "can step from cell c to neighbor (Direction)i". Raw — no diagonal corner-cut applied here.
public readonly byte[] Mask = new byte[CellsPerChunk];
public readonly sbyte[] SourceZ = new sbyte[CellsPerChunk];
public readonly sbyte[] DestZN = new sbyte[CellsPerChunk];
public readonly sbyte[] DestZNE = new sbyte[CellsPerChunk];
public readonly sbyte[] DestZE = new sbyte[CellsPerChunk];
public readonly sbyte[] DestZSE = new sbyte[CellsPerChunk];
public readonly sbyte[] DestZS = new sbyte[CellsPerChunk];
public readonly sbyte[] DestZSW = new sbyte[CellsPerChunk];
public readonly sbyte[] DestZW = new sbyte[CellsPerChunk];
public readonly sbyte[] DestZNW = new sbyte[CellsPerChunk];
///
/// 32 bytes = 256 bits. Bit set = cell has >1 walkable surface; route to slow path.
/// TODO(PR2): lazy-init this. The vast majority of chunks are entirely single-Z, so
/// allocating 32 bytes per chunk wastes ~256KB at full cap. Make nullable; allocate
/// on first MarkCellMultiZ; IsCellMultiZ short-circuits to false when null.
///
public readonly byte[] MultiZCells = new byte[32];
/// Snapshot of Sector.MultisVersion at the time this chunk was built.
public int BuiltMultisVersion;
/// Updated on every cache hit/miss. Used by LRU fallback eviction.
public long LastTouchedTicks;
/// True if any cell in this chunk has more than one walkable surface (set during build).
public bool HasAnyMultiZ;
public bool IsCellMultiZ(int cellIndex) => (MultiZCells[cellIndex >> 3] & (1 << (cellIndex & 7))) != 0;
public void MarkCellMultiZ(int cellIndex)
{
MultiZCells[cellIndex >> 3] |= (byte)(1 << (cellIndex & 7));
HasAnyMultiZ = true;
}
}