using AcDream.App.Streaming; using Xunit; namespace AcDream.Core.Tests.Streaming; /// /// The GameWindow side of the dungeon streaming gate (AP-36): given the player's /// CURRENT cell, decide whether to collapse streaming and where to pin the observer. /// The StreamingController's reaction to these inputs is covered by /// ; this fixture covers the /// INPUT computation — in particular the teleport-hold rule (#145/#138). /// public class DungeonStreamingGateTests { // A 0x0007 Town Network dungeon cell (landblock 0x0007, cell 0x0145). private const uint DungeonCell = 0x00070145u; // An outdoor terrain cell near Holtburg (landblock 0xAB34, structure cell 0x0001). private const uint OutdoorCell = 0xAB340001u; [Fact] public void SealedDungeonCell_NotHold_CollapsesAndPinsObserverToCellLandblock() { var r = DungeonStreamingGate.Compute( isTeleportHold: false, currCellIsSealedDungeon: true, currCellId: DungeonCell); Assert.True(r.InsideDungeon); Assert.Equal(0x0007u, r.ObserverLandblockKey); // 0x00070145 >> 16 } [Fact] public void OutdoorCell_NotHold_NoCollapse_NoObserverOverride() { var r = DungeonStreamingGate.Compute( isTeleportHold: false, currCellIsSealedDungeon: false, currCellId: OutdoorCell); Assert.False(r.InsideDungeon); Assert.Null(r.ObserverLandblockKey); } [Fact] public void TeleportHold_StaleSealedDungeonCurrCell_SuppressesGate() { // #145/#138 — teleport OUT of a dungeon. During the arrival hold the player is // unplaced, so CurrCell is still the frozen SOURCE dungeon cell. The gate MUST be // suppressed: streaming has to follow the DESTINATION (the PortalSpace observer // pin), not re-pin onto the source dungeon. The pre-fix logic returned // (true, 0x0007) here, which kept streaming collapsed on the source dungeon → the // outdoor destination never hydrated → 600-frame timeout → force-snap to ocean. var r = DungeonStreamingGate.Compute( isTeleportHold: true, currCellIsSealedDungeon: true, currCellId: DungeonCell); Assert.False(r.InsideDungeon); Assert.Null(r.ObserverLandblockKey); } [Fact] public void TeleportHold_OutdoorCurrCell_AlsoNoCollapse() { // Sanity: an outdoor→outdoor or building→outdoor hold is already correct, but the // suppression rule must not change that. var r = DungeonStreamingGate.Compute( isTeleportHold: true, currCellIsSealedDungeon: false, currCellId: OutdoorCell); Assert.False(r.InsideDungeon); Assert.Null(r.ObserverLandblockKey); } }