acdream/src/AcDream.Core/World/WbSceneryAdapter.cs
Erik 91fd9de3f6 phase(N.1): document LandBlock length-81 invariant on adapter
Addresses code-review feedback on commit 26cf2b8. The dropped
ArgumentException length guards were correct to drop because
DatReaderWriter.LandBlock self-initializes Terrain[] and Height[]
to length 81 in its constructor — but that invariant was not
documented anywhere visible to future readers. Adds an XML doc
<remarks> block explaining the guarantee so callers constructing
synthetic LandBlocks know what to expect.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:20:53 +02:00

55 lines
2.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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