using DatReaderWriter.DBObjs;
using WorldBuilder.Shared.Models;
namespace AcDream.Core.World;
///
/// Bridges acdream's dat types into WorldBuilder's data shapes for the
/// Phase N rendering migration. See
/// docs/architecture/worldbuilder-inventory.md for the full strategy.
///
internal static class WbSceneryAdapter
{
private const int VerticesPerSide = 9;
private const int TerrainSize = VerticesPerSide * VerticesPerSide; // 81
///
/// Builds a 9×9 = 81-entry array from a
/// 's packed terrain bits + height bytes. WB's
/// TerrainUtils.OnRoad / GetNormal / GetHeight
/// consume this shape.
///
/// Field mapping (TerrainInfo → ):
/// TerrainInfo.Road (bits 0-1) →
/// TerrainInfo.Type (bits 2-6) →
/// TerrainInfo.Scenery (bits 11-15) →
/// LandBlock.Height[i] →
///
///
/// No runtime length guards are needed here because
/// DatReaderWriter.DBObjs.LandBlock's default constructor
/// self-initializes both Terrain and Height to fixed-length
/// arrays of exactly 81 elements (9×9 vertices per landblock). Any caller
/// that constructs a synthetic with partial arrays
/// will receive an at the first
/// mis-sized index, which is the correct fast-fail behaviour for a
/// contract violation of this kind.
///
public static TerrainEntry[] BuildTerrainEntries(LandBlock block)
{
ArgumentNullException.ThrowIfNull(block);
var entries = new TerrainEntry[TerrainSize];
for (int i = 0; i < TerrainSize; i++)
{
var ti = block.Terrain[i];
entries[i] = new TerrainEntry(
height: block.Height[i],
texture: (byte)ti.Type,
scenery: ti.Scenery,
road: ti.Road,
encounters: null);
}
return entries;
}
}