CellTransit.AddAllOutsideCells assumed sphere coords were absolute world coords (subtracting lbXf = 0xA9 * 192 = 32448 from the sphere position). Production has used landblock-local coords since Phase A.1 (streaming-center landblock at world origin), so the subtraction produced localX = -32316, gridX = -1346 → out-of-range → early return → ZERO outdoor cells added. For outdoor primary cells the bug was masked by GetNearbyObjects's radial sweep. For indoor primary cells (where #98 gates the outdoor sweep), the door's outdoor cell 0xA9B40029 never reached portalReachableCells, the door's BSP was never queried, and the player walked through Holtburg cottage doors unimpeded. Fix: AddAllOutsideCells treats worldSphereCenter as landblock-local directly. Matches retail CLandCell::add_all_outside_cells which uses the per-cell 6-byte landblock-relative position struct. Existing CellTransitAddAllOutsideCellsTests + CellTransitFindCellSetTests updated to use landblock-local sphere coords (they were the only callers using the world-coord convention; production never did). Apparatus shipped: - DoorBugTrajectoryReplayTests — live-capture-driven replay harness that pinpointed the bug per-field at unit-test speed (<500ms iteration) - AddAllOutsideCells_LandblockLocalSphere_AddsDoorOutdoorCell — direct unit test that demonstrates the fix - FindTransitCellsSphere_IndoorExitPortal_AddsOutsideForCapturedSpherePos — verifies cell-portal traversal at the captured sphere position - DoorSetupGfxObjInspectionTests.HoltburgCottage_CellPortals_DatInspection — dat-direct EnvCell + Environment.Cells + portal-poly inspector - Fixture: tests/AcDream.Core.Tests/Fixtures/door-bug/live-capture.jsonl (tick 13558 walkthrough + tick 22760 outdoor block) Visual verification (user-driven at Holtburg cottage door, ~50cm off-center): - outside→inside RUN: now BLOCKS (was: walks through) - outside→inside WALK: presumed blocks (not retested) - inside→outside RUN: PARTIAL — body intersects door, sphere slides through - inside→outside WALK: same partial behavior The remaining inside→outside asymmetry is a SEPARATE bug in BSP collision response for two-sided polygons. The [bsp-test] probe now fires 245 times for the door entity from indoor (was 0 pre-fix) — door IS being queried; the BSP polygon-level collision response is the new bug. Handoff at docs/research/2026-05-25-door-bug-partial-fix-shipped.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
47 lines
1.6 KiB
C#
47 lines
1.6 KiB
C#
using System.Collections.Generic;
|
|
using System.Numerics;
|
|
using AcDream.Core.Physics;
|
|
using Xunit;
|
|
|
|
namespace AcDream.Core.Tests.Physics;
|
|
|
|
public class CellTransitAddAllOutsideCellsTests
|
|
{
|
|
[Fact]
|
|
public void SphereWellInsideCell_AddsOneCell()
|
|
{
|
|
// A6.P4 (2026-05-24): coords are LANDBLOCK-LOCAL (X/Y in [0, 192]).
|
|
// Player at landblock-local (12, 12, 0) → cell (0,0) in landblock 0xA9B40000.
|
|
// Pre-fix this test passed world coords (32460, 34572) and the function
|
|
// subtracted lbXf=32448 to get local 12. Post-fix the function expects
|
|
// landblock-local directly.
|
|
var candidates = new HashSet<uint>();
|
|
CellTransit.AddAllOutsideCells(
|
|
worldSphereCenter: new Vector3(12f, 12f, 0f),
|
|
sphereRadius: 0.5f,
|
|
currentCellId: 0xA9B40001u,
|
|
candidates);
|
|
|
|
Assert.Single(candidates);
|
|
Assert.Contains(0xA9B40001u, candidates);
|
|
}
|
|
|
|
[Fact]
|
|
public void SphereAtCellEastBoundary_AddsTwoCells()
|
|
{
|
|
// A6.P4 (2026-05-24): landblock-local coords. Player at (23.6, 12, 0)
|
|
// — near +X edge of cell (0,0). Sphere reaches to local X = 23.6 + 0.5
|
|
// = 24.1 → cell (1,0) added.
|
|
var candidates = new HashSet<uint>();
|
|
CellTransit.AddAllOutsideCells(
|
|
worldSphereCenter: new Vector3(23.6f, 12f, 0f),
|
|
sphereRadius: 0.5f,
|
|
currentCellId: 0xA9B40001u,
|
|
candidates);
|
|
|
|
Assert.Equal(2, candidates.Count);
|
|
Assert.Contains(0xA9B40001u, candidates);
|
|
// Cell (1,0): low-16 id = 1 * 8 + 0 + 1 = 9 → 0x0009.
|
|
Assert.Contains(0xA9B40009u, candidates);
|
|
}
|
|
}
|