🐛 improve occlusion detection with wider tile check

Expands isOccluded() from same-column-only to a 3x4 tile window
(tileX+-1, tileY+1..4) to catch trees whose canopy extends sideways
and well above the trunk tile. Outline scale bumped to 1.15.
This commit is contained in:
2026-03-23 20:02:40 +00:00
parent 5f646d54ca
commit 84b6e51746

View File

@@ -589,7 +589,7 @@ export class VillagerSystem {
// Silhouette: same texture, white fill, fixed high depth so it shows through
// trees and buildings. Visibility is toggled per frame by isOccluded().
const outlineSprite = this.scene.add.image(v.x, v.y, 'villager')
.setScale(1.1)
.setScale(1.15)
.setTintFill(0xaaddff)
.setAlpha(0.85)
.setDepth(900)
@@ -648,19 +648,22 @@ export class VillagerSystem {
/**
* Returns true if a world object (tree, rock, or building) with a higher tileY
* than the Nisse exists on the same column, meaning the Nisse is visually
* behind that object. Checks 13 tiles below to account for tall tree canopies.
* exists in the vicinity of the Nisse and would visually occlude them.
* Checks a 3-column × 4-row window below the Nisse's tile to account for
* wide tree canopies that extend above and to the sides of the trunk tile.
* @param tileX - Nisse's current tile column
* @param tileY - Nisse's current tile row
*/
private isOccluded(tileX: number, tileY: number): boolean {
const state = stateManager.getState()
for (let dy = 1; dy <= 3; dy++) {
const checkY = tileY + dy
if (this.worldSystem.hasResourceAt(tileX, checkY)) return true
if (Object.values(state.world.buildings).some(
b => b.tileX === tileX && b.tileY === checkY && b.kind !== 'stockpile_zone'
)) return true
const buildings = Object.values(state.world.buildings)
for (let dx = -1; dx <= 1; dx++) {
for (let dy = 1; dy <= 4; dy++) {
const cx = tileX + dx
const cy = tileY + dy
if (this.worldSystem.hasResourceAt(cx, cy)) return true
if (buildings.some(b => b.tileX === cx && b.tileY === cy && b.kind !== 'stockpile_zone')) return true
}
}
return false
}