phase(N.1): add ACME-conformant per-vertex road check

Phase N.1 hotfix: scenery near a road still rendered in acdream
even with WB-backed generation. Investigation (worktree session
2026-05-08) showed ACME WorldBuilder skips the entire vertex when
its road bit is set, before any per-object spawn rolls. ACME line:
  references/WorldBuilder-ACME-Edition/WorldBuilder/Editors/Landscape/GameScene.cs:1074
  if (entry.Road != 0) continue;

This check was previously REMOVED in commit 833d167 with a comment
claiming retail doesn't have it. The comment was wrong: ACME mirrors
retail and keeps the check, and the upstream Chorizite/WorldBuilder
we forked omits it (which is why our newly-WB-backed Generate path
still produced the bad tree). Adding back to both Generate (legacy)
and GenerateViaWb (WB-backed) for parity.

This does NOT regress #49: the 9x9 loop expansion that recovered
missing edge-vertex scenery is unchanged. Only vertices whose own
road bit is set are now skipped -- same as ACME.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-08 10:23:53 +02:00
parent ecf4fe9f10
commit e279c46aac

View file

@ -100,10 +100,14 @@ public static class SceneryGenerator
uint terrainType = (uint)((raw >> 2) & 0x1F); // bits 2-6
uint sceneType = (uint)((raw >> 11) & 0x1F); // bits 11-15
// NOTE: retail does NOT skip based on this vertex's road bit.
// The road test happens AFTER displacement via the 4-corner
// polygonal OnRoad check (see below). Removing the
// pre-displacement early-exit restores retail behavior.
// ACME-conformant per-vertex road check (GameScene.cs:1074).
// If this vertex itself is a road vertex, skip ALL scenery
// generation for it. This is retail behavior — the earlier
// claim that retail doesn't have this check (commit 833d167)
// was wrong. The post-displacement OnRoad check below is
// independent and still applies for non-road vertices whose
// displaced position lands on the road ribbon.
if ((raw & 0x3) != 0) continue;
if (terrainType >= region.TerrainInfo.TerrainTypes.Count) continue;
var sceneTypeList = region.TerrainInfo.TerrainTypes[(int)terrainType].SceneTypes;
@ -300,6 +304,10 @@ public static class SceneryGenerator
int i = x * VerticesPerSide + y;
ushort raw = block.Terrain[i];
// ACME-conformant per-vertex road check (GameScene.cs:1074).
// Skip the entire vertex if its road bit is set.
if ((raw & 0x3) != 0) continue;
uint terrainType = (uint)((raw >> 2) & 0x1F);
uint sceneType = (uint)((raw >> 11) & 0x1F);