test(physics): P4 review - RestrictionObj prevalence inspection over the installed cell DAT
103,766 of 729,888 EnvCells (14%, 1,293 landblocks - the entire housing estate, 0x70xxxxxx GUIDs) carry a baked RestrictionObj. The AP-71 gate as wired (CanMoveInto unmodeled, fail-closed) would therefore lock every housing interior for everyone; retail's CanMoveInto (0x0058da40) is fail-OPEN for unowned houses and for a null RestrictionDB. Fix directed back to the P4 implementer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
ce941de5cb
commit
3b5e099241
1 changed files with 94 additions and 0 deletions
|
|
@ -0,0 +1,94 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using AcDream.Core.Tests.Conformance;
|
||||||
|
using DatReaderWriter;
|
||||||
|
using DatReaderWriter.Options;
|
||||||
|
using Xunit;
|
||||||
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
|
namespace AcDream.Core.Tests.Physics;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AP-129 inspection (Campaign P P4 Opus review, 2026-07-30): measures how
|
||||||
|
/// many EnvCells in the INSTALLED cell DAT actually carry a baked
|
||||||
|
/// <c>RestrictionObj</c>. Decides the blast radius of the AP-71
|
||||||
|
/// fail-closed gate: with <c>CanMoveInto</c> unmodeled (AP-129), every
|
||||||
|
/// restricted cell refuses entry for every non-bypass player — harmless
|
||||||
|
/// if the flag is rare/authored-for-housing-only, a live lockout if it is
|
||||||
|
/// broadly baked into ordinary interiors. Inspection only; skips cleanly
|
||||||
|
/// when the installed DATs are absent (CI), following the
|
||||||
|
/// DoorSetupGfxObjInspectionTests pattern.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class RestrictionObjPrevalenceInspectionTests
|
||||||
|
{
|
||||||
|
private readonly ITestOutputHelper _output;
|
||||||
|
|
||||||
|
public RestrictionObjPrevalenceInspectionTests(ITestOutputHelper output)
|
||||||
|
=> _output = output;
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CountRestrictionObjCells_InstalledCellDat()
|
||||||
|
{
|
||||||
|
string? datDir = ConformanceDats.ResolveDatDir();
|
||||||
|
if (datDir is null)
|
||||||
|
return; // installed dats absent (CI) — skip cleanly
|
||||||
|
|
||||||
|
using var dats = new DatCollection(datDir, DatAccessType.Read);
|
||||||
|
|
||||||
|
// Bake-tool enumeration shape (BakeRunner.EnumerateEnvCellIds):
|
||||||
|
// LandBlockInfo (xxxxFFFE) NumCells ranges name every EnvCell id.
|
||||||
|
var landblockInfoIds = new List<uint>();
|
||||||
|
foreach (var file in dats.Cell.Tree)
|
||||||
|
{
|
||||||
|
if ((file.Id & 0xFFFFu) == 0xFFFEu)
|
||||||
|
landblockInfoIds.Add(file.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int totalCells = 0;
|
||||||
|
int restricted = 0;
|
||||||
|
var restrictedLandblocks = new HashSet<uint>();
|
||||||
|
var samples = new List<string>();
|
||||||
|
|
||||||
|
foreach (uint infoId in landblockInfoIds)
|
||||||
|
{
|
||||||
|
if (!dats.Cell.TryGet<DatReaderWriter.DBObjs.LandBlockInfo>(
|
||||||
|
infoId, out var info)
|
||||||
|
|| info is null
|
||||||
|
|| info.NumCells == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint firstCellId = (infoId & 0xFFFF_0000u) | 0x0100u;
|
||||||
|
for (uint offset = 0; offset < info.NumCells; offset++)
|
||||||
|
{
|
||||||
|
uint cellId = firstCellId + offset;
|
||||||
|
if (!dats.Cell.TryGet<DatReaderWriter.DBObjs.EnvCell>(
|
||||||
|
cellId, out var cell)
|
||||||
|
|| cell is null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalCells++;
|
||||||
|
if (cell.RestrictionObj != 0)
|
||||||
|
{
|
||||||
|
restricted++;
|
||||||
|
restrictedLandblocks.Add(cellId & 0xFFFF_0000u);
|
||||||
|
if (samples.Count < 40)
|
||||||
|
{
|
||||||
|
samples.Add(
|
||||||
|
$"cell 0x{cellId:X8} restrictionObj 0x{cell.RestrictionObj:X8}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_output.WriteLine(
|
||||||
|
$"EnvCells scanned: {totalCells}; with RestrictionObj != 0: "
|
||||||
|
+ $"{restricted}; distinct landblocks: {restrictedLandblocks.Count}");
|
||||||
|
foreach (string s in samples)
|
||||||
|
_output.WriteLine(s);
|
||||||
|
|
||||||
|
Assert.True(totalCells > 0, "installed cell DAT enumerated no EnvCells");
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue