diff --git a/src/AcDream.Core/World/SceneryGenerator.cs b/src/AcDream.Core/World/SceneryGenerator.cs
index 791c905..8b034c3 100644
--- a/src/AcDream.Core/World/SceneryGenerator.cs
+++ b/src/AcDream.Core/World/SceneryGenerator.cs
@@ -68,6 +68,12 @@ public static class SceneryGenerator
uint terrainType = (uint)((raw >> 2) & 0x1F); // bits 2-6
uint sceneType = (uint)((raw >> 11) & 0x1F); // bits 11-15
+ // Skip road vertices: bits 0-1 of the terrain word encode the road
+ // type (non-zero means this vertex is on a road). Ported from
+ // ACViewer Physics/Common/Landblock.cs GetRoad() and the OnRoad()
+ // check in get_land_scenes(). Roads should not have trees/rocks.
+ if (IsRoadVertex(raw)) continue;
+
if (terrainType >= region.TerrainInfo.TerrainTypes.Count) continue;
var sceneTypeList = region.TerrainInfo.TerrainTypes[(int)terrainType].SceneTypes;
if (sceneType >= sceneTypeList.Count) continue;
@@ -160,6 +166,13 @@ public static class SceneryGenerator
return result;
}
+ ///
+ /// Returns true if the raw terrain word indicates a road vertex.
+ /// Bits 0-1 of the terrain word encode the road type; any non-zero value
+ /// means the vertex is on a road. Ported from ACViewer GetRoad().
+ ///
+ public static bool IsRoadVertex(ushort raw) => (raw & 0x3u) != 0;
+
///
/// Pseudo-random displacement within a cell for a scenery object. Returns a
/// Vector3 in local cell-offset space (the caller adds it to the cell corner