fix(tiles): 修复 Kurast / Mesa / Desert / Barricade 的瓦片引用缺失 (Issue #83)

- wilderness.ts: 在 applyGroundTransitions 中增加 options.levelTypeName 守卫,避免对非 Act 1 关卡执行 Act 1 地面与水岸过渡,消除 Desert (43) 与 Barricade (112, 117) 的无效瓦片生成。
- wilderness-acts.ts:
  - Kurast (79, 80, 81): 大街、桥梁与堤岸 balustrade 改用 Kurast 实际存在的 style 20 (Floors.dt1 / Walls.dt1),消除不存在的 style 5 / style 4 引用。
  - Mesa (104, 105, 106): 峡谷地面根据 levelTypeName 区分,Act 4 - Mesa 使用 Mesa Floor.dt1 的 style 10 峡谷地表,消除仅在 Lava 存在的 style 20 引用。
- wilderness-siege.ts:
  - Siege (110): 攻城木桩栅栏与破损立柱改用 fence.dt1 存在的 style 2 sequence 10 (type 1 与 type 7);投石台墙壁使用 palisade wall;废墟使用 camp.dt1 的 style 18 地砖与墙壁。

TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
This commit is contained in:
troytt 2026-09-18 11:25:02 +00:00
parent 6a59edd0cb
commit ef9380864c
3 changed files with 36 additions and 26 deletions

View File

@ -472,13 +472,14 @@ export function stampAct3KurastCauseway(
}
}
if (x >= walkwayLeft && x <= walkwayRight) {
// Paved stone causeway: style 5, prop1 194
paintFloor(canvas, x, y, makeFloor(5, 0, 194), true)
// Paved stone causeway: style 20, prop1 194
paintFloor(canvas, x, y, makeFloor(20, 0, 194), true)
clearWalls(canvas, x, y)
causewayCells += 1
} else if (x === walkwayLeft - 1 || x === walkwayRight + 1) {
// Stone balustrade wall: style 1, prop1 129
paintWall(canvas, x, y, makeWall(1, 0, 1, 129))
// Stone balustrade wall: style 20, prop1 129
const wallType = x === walkwayLeft - 1 ? 1 : 2
paintWall(canvas, x, y, makeWall(20, 0, wallType, 129))
balustradeCells += 1
} else {
// Deep canal water: style 2, sequence 0, prop1 2
@ -543,7 +544,7 @@ export function initAct3OutdoorLevel(
for (let dx = -1; dx <= 1; dx += 1) {
const x = hubX + dx
if (!isInsidePreset(x, y, placedRects, 0)) {
paintFloor(canvas, x, y, makeFloor(5, 0, 194))
paintFloor(canvas, x, y, makeFloor(20, 0, 194))
clearWalls(canvas, x, y)
causewayCells += 1
}
@ -554,7 +555,7 @@ export function initAct3OutdoorLevel(
for (let dy = -1; dy <= 1; dy += 1) {
const y = hubY + dy
if (!isInsidePreset(x, y, placedRects, 0)) {
paintFloor(canvas, x, y, makeFloor(5, 0, 194))
paintFloor(canvas, x, y, makeFloor(20, 0, 194))
clearWalls(canvas, x, y)
causewayCells += 1
}
@ -567,7 +568,7 @@ export function initAct3OutdoorLevel(
// Stone Bridge crossing at East-West avenue
if (Math.abs(y - hubY) <= 2) {
for (let dx = 0; dx < 4; dx += 1) {
paintFloor(canvas, canalX + dx, y, makeFloor(4, 0, 2), true)
paintFloor(canvas, canalX + dx, y, makeFloor(20, 0, 194), true)
clearWalls(canvas, canalX + dx, y)
}
riverBridges += 1
@ -582,8 +583,8 @@ export function initAct3OutdoorLevel(
}
}
// Stone canal embankments
paintWall(canvas, canalX - 1, y, makeWall(1, 0, 1, 129))
paintWall(canvas, canalX + 4, y, makeWall(1, 0, 1, 129))
paintWall(canvas, canalX - 1, y, makeWall(20, 0, 1, 129))
paintWall(canvas, canalX + 4, y, makeWall(20, 0, 2, 129))
embankmentWalls += 2
}
}
@ -660,12 +661,15 @@ export function initAct4OutdoorLevel(
}
rockyBridges += 1
} else {
// Boiling lava chasm: style 20, sequence 3, prop1 2
// Boiling lava chasm for Act 4 - Lava, or rocky canyon floor for Act 4 - Mesa
const isLava = request.levelTypeName === 'Act 4 - Lava'
const chasmStyle = isLava ? 20 : 10
const chasmSeq = isLava ? 3 : 0
for (let dy = -2; dy <= 2; dy += 1) {
const y = centerY + dy
if (y >= 0 && y < height) {
if (!isInsidePreset(x, y, placedRects, 1)) {
paintFloor(canvas, x, y, makeFloor(20, 3, 2), true)
paintFloor(canvas, x, y, makeFloor(chasmStyle, chasmSeq, 2), true)
clearWalls(canvas, x, y)
lavaChasmCells += 1
}

View File

@ -184,22 +184,22 @@ function stampBreachedBarricade(
})
breachFloorCount += 1
} else if (y === breachY - 1 || y === breachY + breachHeight) {
// Splintered end-cap post at the breach edge
// Splintered end-cap post at the breach edge (fence.dt1 type 7 pillar)
setWall(canvas, x, y, {
style: 2,
sequence: rng.int(1, 2),
sequence: 10,
prop1: 129,
type: 1,
type: 7,
unknown1: 0,
unknown2: 0,
hidden: false,
})
wallCount += 1
} else {
// Intact spiked wooden palisade
// Intact spiked wooden palisade (fence.dt1 type 1 left wall)
setWall(canvas, x, y, {
style: 2,
sequence: 0,
sequence: 10,
prop1: 129,
type: 1,
unknown1: 0,
@ -247,9 +247,9 @@ function stampCatapultPlatform(
(originY > 26 && dy === 0 && dx >= 1 && dx <= 2)
if (isPerimeter && !isAccessGap) {
setWall(canvas, x, y, {
style: 4,
sequence: 0,
prop1: 2,
style: 2,
sequence: 10,
prop1: 129,
type: 1,
unknown1: 0,
unknown2: 0,
@ -261,7 +261,7 @@ function stampCatapultPlatform(
}
/**
* Stamp crumbled stone fort ruins (style: 1) interspersed between strips.
* Stamp crumbled stone fort ruins (style: 18) interspersed between strips.
* Features weathered stone flagstone floors and broken masonry walls.
*/
function stampFortRuin(
@ -278,22 +278,22 @@ function stampFortRuin(
const x = originX + dx
if (x < 4 || x >= canvas.width - 4) continue
// Ruined flagstone floor
// Ruined camp flagstone floor (camp.dt1 style 18 floor)
setFloor(canvas, x, y, {
style: 1,
sequence: rng.int(0, 2),
style: 18,
sequence: rng.int(0, 4),
prop1: 2,
unknown1: 0,
unknown2: 0,
hidden: false,
})
// Weathered/crumbled perimeter wall with missing sections
// Weathered/crumbled perimeter wall with missing sections (camp.dt1 style 18 wall)
const isPerimeter = dx === 0 || dx === size - 1 || dy === 0 || dy === size - 1
if (isPerimeter && rng.next() > 0.35) {
setWall(canvas, x, y, {
style: 1,
sequence: rng.int(0, 4),
style: 18,
sequence: rng.int(0, 2),
prop1: 129,
type: 1,
unknown1: 0,

View File

@ -1508,6 +1508,12 @@ export function applyGroundTransitions(
canvas: Canvas,
options?: GroundTransitionOptions,
): GroundTransitionResult {
// Ground transition auto-tiling LUTs (DIRT_PATH_TILE_LUT, WATER_EDGE_TILE_LUT) are specific
// to Act 1 Wilderness dirt roads and river water. Skip for other level types.
if (options?.levelTypeName !== undefined && options.levelTypeName !== 'Act 1 - Wilderness') {
return { transitionCells: 0, roadTransitions: 0, waterTransitions: 0 }
}
// Build set of available floor tiles if libraries are provided
const availableTiles = new Set<string>()
if (options?.libraries && options.libraries.length > 0) {