StepUpHeight: when Tab enters player mode, read Setup.StepUpHeight from the player entity's dat and apply it to the controller (fallback 2f for non-Setup entities or when the dat value is zero). Previously hardcoded to 5.0 which made step-up too permissive. Road exclusion: SceneryGenerator now skips terrain vertices where bits 0-1 of the raw terrain word are non-zero. These bits encode the road type (GetRoad() in ACViewer's Landblock.cs). Trees, rocks and bushes will no longer be placed on road surfaces. Added SceneryGenerator.IsRoadVertex(ushort) public helper + 9 unit tests (theory + fact) verifying the road-bit convention matches TerrainInfo.Road. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
53 lines
2 KiB
C#
53 lines
2 KiB
C#
using AcDream.Core.World;
|
|
using DatReaderWriter.Types;
|
|
|
|
namespace AcDream.Core.Tests.World;
|
|
|
|
/// <summary>
|
|
/// Tests for SceneryGenerator road-exclusion logic.
|
|
/// The full Generate() pipeline requires real dat files (Region, Scene, etc.)
|
|
/// so road-check behavior is tested via the internal IsRoadVertex helper,
|
|
/// which is the single gate that guards against placing trees on roads.
|
|
/// </summary>
|
|
public class SceneryGeneratorTests
|
|
{
|
|
// Terrain word layout (ushort):
|
|
// bits 0-1 = Road (non-zero → on a road)
|
|
// bits 2-6 = TerrainType
|
|
// bits 11-15 = SceneType
|
|
|
|
[Theory]
|
|
[InlineData(0x0000, false)] // no road bits
|
|
[InlineData(0x0001, true)] // road bit 0 set
|
|
[InlineData(0x0002, true)] // road bit 1 set
|
|
[InlineData(0x0003, true)] // both road bits set
|
|
[InlineData(0x007C, false)] // terrain type bits only, no road
|
|
[InlineData(0xF800, false)] // scenery bits only, no road
|
|
[InlineData(0xF803, true)] // road + scenery bits
|
|
public void IsRoadVertex_CorrectlyIdentifiesRoadBits(ushort raw, bool expectedIsRoad)
|
|
{
|
|
Assert.Equal(expectedIsRoad, SceneryGenerator.IsRoadVertex(raw));
|
|
}
|
|
|
|
[Fact]
|
|
public void IsRoadVertex_ZeroTerrain_IsNotRoad()
|
|
{
|
|
// A fully blank terrain entry (no type, no road, no scene) is not a road.
|
|
Assert.False(SceneryGenerator.IsRoadVertex(0));
|
|
}
|
|
|
|
[Fact]
|
|
public void IsRoadVertex_MatchesTerrainInfoRoadProperty()
|
|
{
|
|
// Verify that IsRoadVertex agrees with the typed TerrainInfo.Road property
|
|
// for a sample of raw values, ensuring the bit convention is consistent.
|
|
for (ushort raw = 0; raw < 4; raw++)
|
|
{
|
|
TerrainInfo ti = raw;
|
|
bool expectedFromStruct = ti.Road != 0;
|
|
bool actual = SceneryGenerator.IsRoadVertex(raw);
|
|
Assert.True(actual == expectedFromStruct,
|
|
$"raw=0x{raw:X4}: IsRoadVertex={actual} but TerrainInfo.Road={ti.Road}");
|
|
}
|
|
}
|
|
}
|