refactor(wilderness): 移除凭空发明的程序化十字矮石墙网络,回归原版自然地貌阻隔 (#65)
- 将 stampThemedDividers 重构为兼容性 no-op,完全废弃人为硬编码的十字切分矮石墙 - generateWilderness 移除 stampOutdoorDividers 调用,回归原版 Act 1-5 依据 DS1 预设边界及地形生成的自然阻隔机制 - 更新 wilderness 单元与多幕道路测试,验证 0 人造矮石墙及真实地貌阻隔保留 TAG=agy CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
This commit is contained in:
parent
a7e526da64
commit
d0efb04395
|
|
@ -3327,145 +3327,24 @@ export function stampThemedRoads(
|
|||
}
|
||||
|
||||
/**
|
||||
* General outdoor divider network laying connected stone walls, sandstone berms,
|
||||
* or balustrades with proper corner joins, gate archways, and endcaps.
|
||||
* General outdoor divider network.
|
||||
* @deprecated Procedural cross divider networks were removed in Issue #65 to restore
|
||||
* Blizzard DRLG fidelity. In original Diablo II, wilderness barriers are formed naturally
|
||||
* by cliff borders, water bodies, and LvlSub substitutions without artificial cross stone walls.
|
||||
*/
|
||||
export function stampThemedDividers(
|
||||
canvas: Canvas,
|
||||
gridWidth: number,
|
||||
gridHeight: number,
|
||||
inX: number,
|
||||
outY: number,
|
||||
placedRects: readonly PlacedPresetRect[],
|
||||
rng: Rng,
|
||||
theme: OutdoorDividerTheme,
|
||||
_canvas: Canvas,
|
||||
_gridWidth: number,
|
||||
_gridHeight: number,
|
||||
_inX: number,
|
||||
_outY: number,
|
||||
_placedRects: readonly PlacedPresetRect[],
|
||||
_rng: Rng,
|
||||
_theme: OutdoorDividerTheme,
|
||||
stats?: WildernessStats,
|
||||
): void {
|
||||
if (gridWidth < 6 || gridHeight < 6) return
|
||||
|
||||
const wallStyle = theme.wallStyle
|
||||
const wallProp1 = theme.wallProp1 ?? 129
|
||||
const placedCells = new Set<string>()
|
||||
|
||||
const makeWall = (type: number, sequence: number): Ds1Wall => ({
|
||||
prop1: wallProp1,
|
||||
sequence,
|
||||
style: wallStyle,
|
||||
type,
|
||||
unknown1: 0,
|
||||
unknown2: 0,
|
||||
hidden: false,
|
||||
})
|
||||
|
||||
const placeWall = (x: number, y: number, wall: Ds1Wall): void => {
|
||||
const cell = canvas.cells[y]?.[x]
|
||||
if (!cell) return
|
||||
const targetWalls = cell.walls as Ds1Wall[]
|
||||
if (targetWalls.length > 0) {
|
||||
targetWalls[0] = wall
|
||||
} else {
|
||||
targetWalls.push(wall)
|
||||
}
|
||||
placedCells.add(`${x},${y}`)
|
||||
}
|
||||
|
||||
// Offset divider lines by 2 blocks (16 tiles) from the main road spine
|
||||
const offsetBlockY = rng.int(0, 1) === 0 ? -2 : 2
|
||||
const offsetBlockX = rng.int(0, 1) === 0 ? -2 : 2
|
||||
const wallY = Math.max(12, Math.min(canvas.height - 12, (outY + offsetBlockY) * TILES_PER_BLOCK))
|
||||
const wallX = Math.max(12, Math.min(canvas.width - 12, (inX + offsetBlockX) * TILES_PER_BLOCK))
|
||||
|
||||
const isCellBlockedForWall = (x: number, y: number): boolean => {
|
||||
if (x < 6 || x >= canvas.width - 6 || y < 6 || y >= canvas.height - 6) return true
|
||||
// Leave 2-tile margin around all placed special presets
|
||||
for (const r of placedRects) {
|
||||
if (x >= r.x - 2 && x < r.x + r.w + 2 && y >= r.y - 2 && y < r.y + r.h + 2) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// Leave 3-tile wide archway gate openings wherever a road, bridge, or water passes
|
||||
for (let dy = -1; dy <= 1; dy += 1) {
|
||||
for (let dx = -1; dx <= 1; dx += 1) {
|
||||
const c = canvas.cells[y + dy]?.[x + dx]
|
||||
if (!c) continue
|
||||
if (c.floors.some(f => !f.hidden && (f.style === 5 || f.style === 1 || f.style === 4 || f.style === 2 || f.style === 3 || theme.roadStyles?.includes(f.style)))) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
const cell = canvas.cells[y]?.[x]
|
||||
if (!cell) return true
|
||||
if (cell.walls.some(w => !w.hidden && w.prop1 !== 0)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
// Build valid tile masks along wallY (EW) and wallX (NS), inserting periodic pasture gates
|
||||
const validEW: boolean[] = Array.from({ length: canvas.width }, (_, x) => {
|
||||
const isPastureGate = (x % 24) >= 11 && (x % 24) <= 13 && Math.abs(x - wallX) > 3
|
||||
return !isPastureGate && !isCellBlockedForWall(x, wallY)
|
||||
})
|
||||
const validNS: boolean[] = Array.from({ length: canvas.height }, (_, y) => {
|
||||
const isPastureGate = (y % 24) >= 11 && (y % 24) <= 13 && Math.abs(y - wallY) > 3
|
||||
return !isPastureGate && !isCellBlockedForWall(wallX, y)
|
||||
})
|
||||
|
||||
const extractRuns = (mask: readonly boolean[]): Array<{ start: number; end: number }> => {
|
||||
const runs: Array<{ start: number; end: number }> = []
|
||||
let start = -1
|
||||
for (let i = 0; i < mask.length; i += 1) {
|
||||
if (mask[i]) {
|
||||
if (start === -1) start = i
|
||||
} else if (start !== -1) {
|
||||
if (i - start >= 4) runs.push({ start, end: i - 1 })
|
||||
start = -1
|
||||
}
|
||||
}
|
||||
if (start !== -1 && mask.length - start >= 4) {
|
||||
runs.push({ start, end: mask.length - 1 })
|
||||
}
|
||||
return runs
|
||||
}
|
||||
|
||||
const ewRuns = extractRuns(validEW)
|
||||
const nsRuns = extractRuns(validNS)
|
||||
|
||||
const ewCoversCorner = ewRuns.some(r => wallX >= r.start && wallX <= r.end)
|
||||
const nsCoversCorner = nsRuns.some(r => wallY >= r.start && wallY <= r.end)
|
||||
const hasCornerJoin = ewCoversCorner && nsCoversCorner
|
||||
|
||||
// Stamp East-West divider wall segments (`type = 2`)
|
||||
for (const run of ewRuns) {
|
||||
for (let x = run.start; x <= run.end; x += 1) {
|
||||
if (x === wallX && hasCornerJoin) {
|
||||
placeWall(x, wallY, makeWall(3, 0)) // Corner / Cross join (`type=3`)
|
||||
} else if (x === run.start) {
|
||||
placeWall(x, wallY, makeWall(2, 1)) // West / Right-of-gap End-Cap (`type=2, seq=1`)
|
||||
} else if (x === run.end) {
|
||||
placeWall(x, wallY, makeWall(2, 2)) // East / Left-of-gap End-Cap (`type=2, seq=2`)
|
||||
} else {
|
||||
placeWall(x, wallY, makeWall(2, 0)) // Continuous EW Wall (`type=2, seq=0`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stamp North-South divider wall segments (`type = 1`)
|
||||
for (const run of nsRuns) {
|
||||
for (let y = run.start; y <= run.end; y += 1) {
|
||||
if (y === wallY && hasCornerJoin) {
|
||||
placeWall(wallX, y, makeWall(3, 0)) // Corner / Cross join (`type=3`)
|
||||
} else if (y === run.start) {
|
||||
placeWall(wallX, y, makeWall(1, 1)) // North / Bottom-of-gap End-Cap (`type=1, seq=1`)
|
||||
} else if (y === run.end) {
|
||||
placeWall(wallX, y, makeWall(1, 2)) // South / Top-of-gap End-Cap (`type=1, seq=2`)
|
||||
} else {
|
||||
placeWall(wallX, y, makeWall(1, 0)) // Continuous NS Wall (`type=1, seq=0`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stats) {
|
||||
stats.proceduralDividerCells = (stats.proceduralDividerCells ?? 0) + placedCells.size
|
||||
stats.proceduralWallCells = (stats.proceduralWallCells ?? 0) + placedCells.size
|
||||
stats.proceduralDividerCells = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5480,20 +5359,6 @@ export function generateWilderness(request: WildernessRequest): WildernessResult
|
|||
request.levelsTable,
|
||||
stats,
|
||||
)
|
||||
stampOutdoorDividers(
|
||||
canvas,
|
||||
act,
|
||||
request.levelId,
|
||||
gridWidth,
|
||||
gridHeight,
|
||||
inX,
|
||||
outY,
|
||||
allPlacedRects,
|
||||
rng,
|
||||
request.levelTypeName,
|
||||
request.levelsTable,
|
||||
stats,
|
||||
)
|
||||
|
||||
// Act 2 Desert Topography: Canyons, oasis pools, sand caravan trails, tomb entrances (DRLGOUTDESR_InitAct2OutdoorLevel)
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ describe("Wilderness Features & Border Rules", () => {
|
|||
}
|
||||
}
|
||||
|
||||
expect(stoneWallCount).toBeGreaterThan(20)
|
||||
expect(stoneWallCount).toBe(0)
|
||||
expect(dirtRoadCount).toBeGreaterThan(30)
|
||||
})
|
||||
|
||||
|
|
@ -364,7 +364,7 @@ describe("Wilderness Features & Border Rules", () => {
|
|||
expect(result.level.cells[75]![44]!.floors[0]!.style).toBe(5)
|
||||
expect(result.level.cells[44]![75]!.floors[0]!.style).toBe(5)
|
||||
|
||||
// 3. Verify interior stone wall segments (style=2, prop1=129) use continuous sequence=0 and end-caps sequence=1/2
|
||||
// 3. Verify no artificial interior stone wall segments (style=2, prop1=129) are stamped (Issue #65)
|
||||
let foundContinuousEW = false
|
||||
let foundEndCapEW = false
|
||||
for (let y = 10; y < 70; y += 1) {
|
||||
|
|
@ -376,8 +376,8 @@ describe("Wilderness Features & Border Rules", () => {
|
|||
}
|
||||
}
|
||||
}
|
||||
expect(foundContinuousEW).toBe(true)
|
||||
expect(foundEndCapEW).toBe(true)
|
||||
expect(foundContinuousEW).toBe(false)
|
||||
expect(foundEndCapEW).toBe(false)
|
||||
})
|
||||
|
||||
test("records unresolved presets and notes when requested preset piece is missing", () => {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ describe('Multi-Act Outdoor Roads & Boundary Divider Networks', () => {
|
|||
expect(spurFound).toBe(true)
|
||||
})
|
||||
|
||||
it('stampAct2SandstoneBerms paints sandstone berms with style: 1, prop1: 129, corner joins, and road archway breaks', () => {
|
||||
it('stampAct2SandstoneBerms is a no-op removing artificial cross dividers (Issue #65)', () => {
|
||||
const canvas = createCanvas(width, height, 1, 1, 0)
|
||||
const rng = new Rng(42)
|
||||
const placedRects: PlacedPresetRect[] = []
|
||||
|
|
@ -126,12 +126,7 @@ describe('Multi-Act Outdoor Roads & Boundary Divider Networks', () => {
|
|||
stampAct2SandstoneBerms(canvas, gridW, gridH, inX, outY, placedRects, rng)
|
||||
|
||||
const bermWalls = countWallTiles(canvas, 1, 129)
|
||||
expect(bermWalls).toBeGreaterThan(20)
|
||||
|
||||
// Berms should not block the road where the road crosses the divider
|
||||
// Highway crosses dividing lines at (inX * 8 + 4, outY * 8 + 4)
|
||||
const crossRoad = canvas.cells[outY * TILES_PER_BLOCK + 4]?.[inX * TILES_PER_BLOCK + 4]
|
||||
expect(crossRoad?.walls.some(w => w.style === 1 && w.prop1 === 129)).toBe(false)
|
||||
expect(bermWalls).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -149,7 +144,7 @@ describe('Multi-Act Outdoor Roads & Boundary Divider Networks', () => {
|
|||
expect(avenueFloors).toBeGreaterThan(50)
|
||||
})
|
||||
|
||||
it('stampAct3KurastBalustrades paints balustrades with style: 1, prop1: 129', () => {
|
||||
it('stampAct3KurastBalustrades is a no-op removing artificial cross dividers (Issue #65)', () => {
|
||||
const canvas = createCanvas(width, height, 1, 1, 0)
|
||||
const rng = new Rng(100)
|
||||
const placedRects: PlacedPresetRect[] = []
|
||||
|
|
@ -158,7 +153,7 @@ describe('Multi-Act Outdoor Roads & Boundary Divider Networks', () => {
|
|||
stampAct3KurastBalustrades(canvas, gridW, gridH, inX, outY, placedRects, rng)
|
||||
|
||||
const balustradeWalls = countWallTiles(canvas, 1, 129)
|
||||
expect(balustradeWalls).toBeGreaterThan(20)
|
||||
expect(balustradeWalls).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -176,7 +171,7 @@ describe('Multi-Act Outdoor Roads & Boundary Divider Networks', () => {
|
|||
expect(snowRoadFloors).toBeGreaterThan(50)
|
||||
})
|
||||
|
||||
it('stampAct5FrozenTrailDivides paints frozen trail divides with style: 2, prop1: 129', () => {
|
||||
it('stampAct5FrozenTrailDivides is a no-op removing artificial cross dividers (Issue #65)', () => {
|
||||
const canvas = createCanvas(width, height, 1, 1, 0)
|
||||
const rng = new Rng(555)
|
||||
const placedRects: PlacedPresetRect[] = []
|
||||
|
|
@ -185,49 +180,49 @@ describe('Multi-Act Outdoor Roads & Boundary Divider Networks', () => {
|
|||
stampAct5FrozenTrailDivides(canvas, gridW, gridH, inX, outY, placedRects, rng)
|
||||
|
||||
const frozenDivides = countWallTiles(canvas, 2, 129)
|
||||
expect(frozenDivides).toBeGreaterThan(20)
|
||||
expect(frozenDivides).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Unified Dispatchers: stampOutdoorRoads & stampOutdoorDividers', () => {
|
||||
it('dispatches Act 2 Desert based on levelId 41', () => {
|
||||
it('dispatches Act 2 Desert based on levelId 41 without artificial cross dividers', () => {
|
||||
const canvas = createCanvas(width, height, 1, 1, 0)
|
||||
const rng = new Rng(123)
|
||||
stampOutdoorRoads(canvas, 1, 41, gridW, gridH, inX, outY, [], rng)
|
||||
stampOutdoorDividers(canvas, 1, 41, gridW, gridH, inX, outY, [], rng)
|
||||
|
||||
expect(countFloorTiles(canvas, 1, 194)).toBeGreaterThan(40)
|
||||
expect(countWallTiles(canvas, 1, 129)).toBeGreaterThan(15)
|
||||
expect(countWallTiles(canvas, 1, 129)).toBe(0)
|
||||
})
|
||||
|
||||
it('dispatches Act 3 Kurast based on levelId 80', () => {
|
||||
it('dispatches Act 3 Kurast based on levelId 80 without artificial cross dividers', () => {
|
||||
const canvas = createCanvas(width, height, 1, 1, 0)
|
||||
const rng = new Rng(123)
|
||||
stampOutdoorRoads(canvas, 1, 80, gridW, gridH, inX, outY, [], rng)
|
||||
stampOutdoorDividers(canvas, 1, 80, gridW, gridH, inX, outY, [], rng)
|
||||
|
||||
expect(countFloorTiles(canvas, 1, 194)).toBeGreaterThan(40)
|
||||
expect(countWallTiles(canvas, 1, 129)).toBeGreaterThan(15)
|
||||
expect(countWallTiles(canvas, 1, 129)).toBe(0)
|
||||
})
|
||||
|
||||
it('dispatches Act 5 Snow based on levelId 111', () => {
|
||||
it('dispatches Act 5 Snow based on levelId 111 without artificial cross dividers', () => {
|
||||
const canvas = createCanvas(width, height, 1, 1, 0)
|
||||
const rng = new Rng(123)
|
||||
stampOutdoorRoads(canvas, 1, 111, gridW, gridH, inX, outY, [], rng)
|
||||
stampOutdoorDividers(canvas, 1, 111, gridW, gridH, inX, outY, [], rng)
|
||||
|
||||
expect(countFloorTiles(canvas, 1, 194)).toBeGreaterThan(40)
|
||||
expect(countWallTiles(canvas, 2, 129)).toBeGreaterThan(15)
|
||||
expect(countWallTiles(canvas, 2, 129)).toBe(0)
|
||||
})
|
||||
|
||||
it('dispatches Act 1 Dirt Roads based on levelId 3', () => {
|
||||
it('dispatches Act 1 Dirt Roads based on levelId 3 without artificial cross dividers', () => {
|
||||
const canvas = createCanvas(width, height, 1, 1, 0)
|
||||
const rng = new Rng(123)
|
||||
stampOutdoorRoads(canvas, 1, 3, gridW, gridH, inX, outY, [], rng)
|
||||
stampOutdoorDividers(canvas, 1, 3, gridW, gridH, inX, outY, [], rng)
|
||||
|
||||
expect(countFloorTiles(canvas, 5, 194)).toBeGreaterThan(40)
|
||||
expect(countWallTiles(canvas, 2, 129)).toBeGreaterThan(15)
|
||||
expect(countWallTiles(canvas, 2, 129)).toBe(0)
|
||||
})
|
||||
|
||||
it('dispatches based on levelTypeName when levelId is generic', () => {
|
||||
|
|
@ -235,19 +230,19 @@ describe('Multi-Act Outdoor Roads & Boundary Divider Networks', () => {
|
|||
stampOutdoorRoads(c2, 1, 999, gridW, gridH, inX, outY, [], new Rng(1), 'Act 2 - Desert')
|
||||
stampOutdoorDividers(c2, 1, 999, gridW, gridH, inX, outY, [], new Rng(1), 'Act 2 - Desert')
|
||||
expect(countFloorTiles(c2, 1, 194)).toBeGreaterThan(40)
|
||||
expect(countWallTiles(c2, 1, 129)).toBeGreaterThan(15)
|
||||
expect(countWallTiles(c2, 1, 129)).toBe(0)
|
||||
|
||||
const c3 = createCanvas(width, height, 1, 1, 0)
|
||||
stampOutdoorRoads(c3, 1, 999, gridW, gridH, inX, outY, [], new Rng(1), 'Act 3 - Kurast')
|
||||
stampOutdoorDividers(c3, 1, 999, gridW, gridH, inX, outY, [], new Rng(1), 'Act 3 - Kurast')
|
||||
expect(countFloorTiles(c3, 1, 194)).toBeGreaterThan(40)
|
||||
expect(countWallTiles(c3, 1, 129)).toBeGreaterThan(15)
|
||||
expect(countWallTiles(c3, 1, 129)).toBe(0)
|
||||
|
||||
const c5 = createCanvas(width, height, 1, 1, 0)
|
||||
stampOutdoorRoads(c5, 1, 999, gridW, gridH, inX, outY, [], new Rng(1), 'Act 5 - Barricade')
|
||||
stampOutdoorDividers(c5, 1, 999, gridW, gridH, inX, outY, [], new Rng(1), 'Act 5 - Barricade')
|
||||
expect(countFloorTiles(c5, 1, 194)).toBeGreaterThan(40)
|
||||
expect(countWallTiles(c5, 2, 129)).toBeGreaterThan(15)
|
||||
expect(countWallTiles(c5, 2, 129)).toBe(0)
|
||||
})
|
||||
|
||||
it('dispatches based on act number fallback', () => {
|
||||
|
|
@ -255,7 +250,7 @@ describe('Multi-Act Outdoor Roads & Boundary Divider Networks', () => {
|
|||
stampOutdoorRoads(c2, 2, 999, gridW, gridH, inX, outY, [], new Rng(1))
|
||||
stampOutdoorDividers(c2, 2, 999, gridW, gridH, inX, outY, [], new Rng(1))
|
||||
expect(countFloorTiles(c2, 1, 194)).toBeGreaterThan(40)
|
||||
expect(countWallTiles(c2, 1, 129)).toBeGreaterThan(15)
|
||||
expect(countWallTiles(c2, 1, 129)).toBe(0)
|
||||
})
|
||||
|
||||
it('strictly skips Cow Level (levelId 39)', () => {
|
||||
|
|
@ -279,7 +274,7 @@ describe('Multi-Act Outdoor Roads & Boundary Divider Networks', () => {
|
|||
levels: [borderDs1],
|
||||
}
|
||||
|
||||
it('generates Act 2 Rocky Waste (Level 41) with caravan routes and sandstone berms', () => {
|
||||
it('generates Act 2 Rocky Waste (Level 41) with caravan routes and authentic canyon topography walls', () => {
|
||||
const result = generateWilderness({
|
||||
levelId: 41,
|
||||
levelName: 'Rocky Waste',
|
||||
|
|
@ -309,7 +304,7 @@ describe('Multi-Act Outdoor Roads & Boundary Divider Networks', () => {
|
|||
expect(sandstoneBerms).toBeGreaterThan(15)
|
||||
})
|
||||
|
||||
it('generates Act 3 Kurast Bazaar (Level 80) with Kurast avenues and balustrades', () => {
|
||||
it('generates Act 3 Kurast Bazaar (Level 80) with Kurast avenues and authentic causeway balustrades', () => {
|
||||
const act3Border: WildernessPiece = {
|
||||
name: 'Act 3 - Kurast Border',
|
||||
border: true,
|
||||
|
|
@ -344,7 +339,7 @@ describe('Multi-Act Outdoor Roads & Boundary Divider Networks', () => {
|
|||
expect(balustrades).toBeGreaterThan(15)
|
||||
})
|
||||
|
||||
it('generates Act 5 Frigid Highlands (Level 111) with snow roads and frozen trail divides', () => {
|
||||
it('generates Act 5 Frigid Highlands (Level 111) with snow roads and authentic siege barricade walls', () => {
|
||||
const act5Border: WildernessPiece = {
|
||||
name: 'Act 5 - Barricade Border',
|
||||
border: true,
|
||||
|
|
|
|||
|
|
@ -280,8 +280,8 @@ describe('BordType 0 really is one cluster for the whole level', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('Procedural terrain pass telemetry tracks real cell counts (Issue #62)', () => {
|
||||
test('Act 1 wilderness tracks procedural road and divider wall cells matching canvas', () => {
|
||||
describe('Procedural terrain pass telemetry tracks real cell counts (Issue #62 & #65)', () => {
|
||||
test('Act 1 wilderness tracks procedural road cells with zero artificial dividers (Issue #65)', () => {
|
||||
const result = generateWilderness({
|
||||
levelId: 2,
|
||||
levelName: 'Cold Plains',
|
||||
|
|
@ -296,10 +296,10 @@ describe('Procedural terrain pass telemetry tracks real cell counts (Issue #62)'
|
|||
})
|
||||
|
||||
expect(result.stats.proceduralRoadCells).toBeGreaterThan(0)
|
||||
expect(result.stats.proceduralDividerCells).toBeGreaterThan(0)
|
||||
expect(result.stats.proceduralWallCells).toBe(result.stats.proceduralDividerCells)
|
||||
expect(result.stats.proceduralDividerCells).toBe(0)
|
||||
expect(result.stats.proceduralWallCells).toBe(0)
|
||||
|
||||
// Count actual divider wall cells on canvas (walls with style 2, prop1 129)
|
||||
// Verify 0 artificial divider wall cells on canvas (walls with style 2, prop1 129)
|
||||
let wallCount = 0
|
||||
for (let y = 0; y < result.level.height; y += 1) {
|
||||
for (let x = 0; x < result.level.width; x += 1) {
|
||||
|
|
@ -309,7 +309,7 @@ describe('Procedural terrain pass telemetry tracks real cell counts (Issue #62)'
|
|||
}
|
||||
}
|
||||
}
|
||||
expect(result.stats.proceduralWallCells).toBe(wallCount)
|
||||
expect(wallCount).toBe(0)
|
||||
})
|
||||
|
||||
test('Act 2 desert tracks procedural roads, water (oasis), and walls (canyon + berms)', () => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue