fix(core): Phase B.2 — require indoor floor below terrain for outdoor→indoor transition
Previous cellId-mask fix was necessary but insufficient: the engine correctly identified the player as outdoor, but then immediately transitioned to an indoor cell because a CellSurface floor polygon covered the player's XY at a Z within stepUpHeight. The floor polygon was a roof or upper floor of a nearby building that happens to sit at terrain level — not a walkable indoor floor the player should snap to. Fix: outdoor→indoor transition now requires bestCellZ < terrainZ - 1. A genuine indoor transition is into a cell whose floor is BELOW the terrain surface (basement, ground floor of elevated building). Cells at or above terrain Z are roofs/upper floors viewed from outside and must not capture the player. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
05d835ff33
commit
5280950806
1 changed files with 12 additions and 1 deletions
|
|
@ -129,9 +129,20 @@ public sealed class PhysicsEngine
|
|||
targetCellId = physics.Terrain.ComputeOutdoorCellId(localCandX, localCandY);
|
||||
}
|
||||
else if (!currentlyIndoor && bestCellZ is not null
|
||||
&& MathF.Abs(bestCellZ.Value - currentPos.Z) < stepUpHeight + 2f)
|
||||
&& MathF.Abs(bestCellZ.Value - currentPos.Z) < stepUpHeight + 2f
|
||||
&& bestCellZ.Value < terrainZ - 1f)
|
||||
{
|
||||
// Walked into an indoor cell from outdoor — transition to indoor.
|
||||
// The extra guard `bestCellZ < terrainZ - 1` prevents transitioning
|
||||
// into cells whose floor is AT or ABOVE terrain level — those are
|
||||
// typically roofs, upper floors, or building footprints that overlap
|
||||
// the outdoor terrain. A genuine indoor transition is into a cell
|
||||
// whose floor is BELOW the terrain surface (basements, ground floors
|
||||
// of buildings that sit on elevated terrain). Without this guard,
|
||||
// standing near any building with a floor polygon covering the
|
||||
// player's XY triggers an indoor transition and snaps Z to the
|
||||
// cell's floor — which for multi-story buildings can be 30+ units
|
||||
// below the outdoor terrain.
|
||||
targetZ = bestCellZ.Value;
|
||||
targetCellId = bestCell!.CellId & 0xFFFFu;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue