diff --git a/Projects/UOContent.Tests/Fixtures/TestServerInitializer.cs b/Projects/UOContent.Tests/Fixtures/TestServerInitializer.cs
index 33bdb3634..076f88141 100644
--- a/Projects/UOContent.Tests/Fixtures/TestServerInitializer.cs
+++ b/Projects/UOContent.Tests/Fixtures/TestServerInitializer.cs
@@ -30,6 +30,13 @@ internal static class TestServerInitializer
private static bool _initialized;
private static readonly Lock _lock = new();
+ ///
+ /// True if the UO client tile data was found and loaded. When false (e.g. CI, where the
+ /// copyrighted client files are absent), tile/map/multi-dependent tests must skip rather than
+ /// fail. Guard such tests with Skip.If(!TestServerInitializer.TileDataLoaded, ...).
+ ///
+ public static bool TileDataLoaded { get; private set; }
+
public static void Initialize()
{
lock (_lock)
@@ -62,7 +69,10 @@ internal static class TestServerInitializer
// flags are populated before anything that reads TileData (MultiData, MovementImpl,
// CheckMovement). Without this, TileData.MaxItemValue is 0 at MultiData.Configure()
// time, causing every MCL tile ID to be masked to 0 and stored as ID=0 in Tiles[x][y].
- ForceLoadTileData();
+ // The copyrighted client files are absent on CI; when tiledata.mul is missing we skip
+ // the tile/map/multi-dependent bootstrap and leave TileDataLoaded false so those tests
+ // skip instead of failing the whole collection from the fixture constructor.
+ TileDataLoaded = TryForceLoadTileData();
// Production runs every static Configure() via AssemblyHandler.Invoke("Configure");
// the fixture calls a curated subset, so configure the pathfinding singleton here so
@@ -70,11 +80,15 @@ internal static class TestServerInitializer
// calls Find. ServerConfiguration is already loaded above, so the setting resolves.
BitmapAStarAlgorithm.Configure();
- // Multi component lists (multi.mul / MultiCollection.uop). Production invokes this via
- // AssemblyHandler.Invoke("Configure"); the curated fixture subset must call it so that
- // BaseMulti.Components (MultiData.GetComponents) returns real footprints instead of
- // MultiComponentList.Empty. Required by the Multi pathfinding tests.
- MultiData.Configure();
+ if (TileDataLoaded)
+ {
+ // Multi component lists (multi.mul / MultiCollection.uop). Production invokes this via
+ // AssemblyHandler.Invoke("Configure"); the curated fixture subset must call it so that
+ // BaseMulti.Components (MultiData.GetComponents) returns real footprints instead of
+ // MultiComponentList.Empty. Required by the Multi pathfinding tests. Depends on the
+ // client files, so it only runs when tile data loaded.
+ MultiData.Configure();
+ }
World.Configure();
Timer.Init(0);
@@ -86,14 +100,23 @@ internal static class TestServerInitializer
DecayScheduler.Configure();
Server.Engines.Spawners.SpawnerJsonSerializer.Configure();
- VerifyTrammelTileDataLoaded();
+ if (TileDataLoaded)
+ {
+ VerifyTrammelTileDataLoaded();
+ }
_initialized = true;
}
}
- private static void ForceLoadTileData()
+ private static bool TryForceLoadTileData()
{
+ var tileDataPath = Core.FindDataFile("tiledata.mul", false);
+ if (string.IsNullOrEmpty(tileDataPath) || !File.Exists(tileDataPath))
+ {
+ return false;
+ }
+
var loadMethod = typeof(TileData).GetMethod(
"Load",
BindingFlags.Static | BindingFlags.NonPublic
@@ -105,6 +128,7 @@ internal static class TestServerInitializer
);
}
loadMethod.Invoke(null, null);
+ return true;
}
private static void VerifyTrammelTileDataLoaded()
diff --git a/Projects/UOContent.Tests/Fixtures/TileDataRequirement.cs b/Projects/UOContent.Tests/Fixtures/TileDataRequirement.cs
new file mode 100644
index 000000000..7b9af1f27
--- /dev/null
+++ b/Projects/UOContent.Tests/Fixtures/TileDataRequirement.cs
@@ -0,0 +1,18 @@
+using Xunit;
+
+namespace Server.Tests;
+
+///
+/// Shared guard for tests that require the copyrighted UO client tile/map data (tiledata.mul and
+/// friends), which is absent on CI. Call as the first statement of a
+/// [SkippableFact]/[SkippableTheory] so the test is skipped — not failed — when the
+/// data was not loaded. See .
+///
+internal static class TileDataRequirement
+{
+ public static void SkipIfMissing() =>
+ Skip.If(
+ !TestServerInitializer.TileDataLoaded,
+ "Requires UO client tile data (tiledata.mul); absent on CI."
+ );
+}
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/BitmapAStarAlgorithmTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/BitmapAStarAlgorithmTests.cs
index ab9497729..20d729c0f 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/BitmapAStarAlgorithmTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/BitmapAStarAlgorithmTests.cs
@@ -130,9 +130,10 @@ public class BitmapAStarAlgorithmTests
blocker.Delete();
}
- [Fact]
+ [SkippableFact]
public void DynamicObstaclePass_RejectsCellOccupiedByImpassableItem()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[1];
Assert.NotNull(map);
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/BoatPathTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/BoatPathTests.cs
index a9796de7f..694374757 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/BoatPathTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/BoatPathTests.cs
@@ -17,9 +17,10 @@ public class BoatPathTests
private const int WaterX = 1450;
private const int WaterY = 1770;
- [Fact]
+ [SkippableFact]
public void BoatDeck_HasWalkableSurfaceCells()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[MapId];
@@ -44,9 +45,10 @@ public class BoatPathTests
}
}
- [Fact]
+ [SkippableFact]
public void BoatDeck_FootprintShape_IsPositionInvariant()
{
+ TileDataRequirement.SkipIfMissing();
// The property Phase 2's local-frame, movement-invariant boat cache must preserve:
// the deck's covered-cell shape (in local coords) is identical at two world positions.
var map = Map.Maps[MapId];
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/FoundationRedesignTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/FoundationRedesignTests.cs
index 3fdb4fa3e..e82520ce9 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/FoundationRedesignTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/FoundationRedesignTests.cs
@@ -17,9 +17,10 @@ public class FoundationRedesignTests
private const int PlaceX = 1500;
private const int PlaceY = 1600;
- [Fact]
+ [SkippableFact]
public void SwappingComponents_ChangesFootprint()
{
+ TileDataRequirement.SkipIfMissing();
var foundation = new SwappableFoundation(0x74); // GuildHouse footprint
try
{
@@ -38,9 +39,10 @@ public class FoundationRedesignTests
}
}
- [Fact]
+ [SkippableFact]
public void RedesignReRegistered_RoutesNewFootprintToLivePath()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[MapId];
Assert.NotNull(map);
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/HousePathRoutingTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/HousePathRoutingTests.cs
index 41caa6255..8ecbd0591 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/HousePathRoutingTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/HousePathRoutingTests.cs
@@ -22,9 +22,10 @@ public class HousePathRoutingTests
public WalkerStub() => Body = 0xC9;
}
- [Fact]
+ [SkippableFact]
public void PathAround_NeverTraversesAWallCell()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var prevThreshold = StepCache.Instance.MissPromotionThreshold;
StepCache.Instance.MissPromotionThreshold = 1;
@@ -74,9 +75,10 @@ public class HousePathRoutingTests
}
}
- [Fact]
+ [SkippableFact]
public void Demolish_ReopensCoveredCells()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[MapId];
Assert.NotNull(map);
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiEdgeCaseTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiEdgeCaseTests.cs
index eb12df7d6..8aa0b8d19 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiEdgeCaseTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiEdgeCaseTests.cs
@@ -25,9 +25,10 @@ public class MultiEdgeCaseTests
/// GetStaticAndMultiTiles yields tiles from BOTH multis; the synthesizer must still
/// agree with CheckMovement everywhere over the union footprint + halo.
///
- [Fact]
+ [SkippableFact]
public void OverlappingMultis_SynthesizerMatchesCheckMovement()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[MapId];
@@ -75,9 +76,10 @@ public class MultiEdgeCaseTests
/// blocks the rest — that vacuity is a fixture concern, not a synthesizer divergence (the
/// synthesizer agrees with the oracle at every direction either way).
///
- [Fact]
+ [SkippableFact]
public void BoatOverWater_SynthesizerMatchesCheckMovement()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[MapId];
@@ -98,9 +100,10 @@ public class MultiEdgeCaseTests
/// re-registration pattern HouseFoundation uses on commit) and assert the synthesizer reads
/// the LIVE, post-redesign Components — i.e. it matches CheckMovement on the NEW shape.
///
- [Fact]
+ [SkippableFact]
public void RedesignedFoundation_SynthesizerMatchesNewFootprint()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[MapId];
@@ -136,10 +139,11 @@ public class MultiEdgeCaseTests
/// dungeon cave-wall corner; add InlineData rows here — the assertion already covers them by
/// construction. (Left intentionally unhunted: do not invent tree/dungeon coords.)
///
- [Theory]
+ [SkippableTheory]
[InlineData(MapId, HouseX, HouseY)] // known-good open Trammel placement (passes today)
public void UserSuppliedScenarios_SynthesizerMatchesCheckMovement(int mapId, int x, int y)
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[mapId];
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiMaskCacheTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiMaskCacheTests.cs
index 8a544897c..7487ce8de 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiMaskCacheTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiMaskCacheTests.cs
@@ -12,9 +12,10 @@ public class MultiMaskCacheTests
private const int PlaceX = 1480;
private const int PlaceY = 1620;
- [Fact]
+ [SkippableFact]
public void TryResolveCoveringMulti_FindsPlacedMulti_AndLocalIndices()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[MapId];
map.GetAverageZ(PlaceX, PlaceY, out _, out var z, out _);
@@ -38,9 +39,10 @@ public class MultiMaskCacheTests
}
}
- [Fact]
+ [SkippableFact]
public void IsInteriorLocalCell_TrueDeepInside_FalseAtEdge()
{
+ TileDataRequirement.SkipIfMissing();
var multi = new TestMulti(GuildHouseId);
try
{
@@ -122,9 +124,10 @@ public class MultiMaskCacheTests
Assert.False(MultiMaskCache.TerrainTopBelow(map, PlaceX, PlaceY, (sbyte)(ground - 50)));
}
- [Fact]
+ [SkippableFact]
public void PathThroughHouseInterior_IncrementsMultiMaskCacheHits()
{
+ TileDataRequirement.SkipIfMissing();
// (PlaceX,PlaceY)=(1480,1620) is cluttered (footprint overlaps tall map statics → dirty), so it
// would never serve the interior cache under the footprint-clean gate. Use a known flat/clear
// spot so a house there is footprint-clean and its interior cells serve from the cache.
@@ -242,9 +245,10 @@ public class MultiMaskCacheTests
}
}
- [Fact]
+ [SkippableFact]
public void ComputeFootprintClean_TrueAtNormalPlacement_FalseWhenSunk()
{
+ TileDataRequirement.SkipIfMissing();
// (PlaceX,PlaceY) is a cluttered spot whose footprint overlaps tall map statics, so a guild
// house there is never footprint-clean. Use a known flat/clear spot for the clean assertion.
const int CleanX = 1560;
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiMaskSynthesisTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiMaskSynthesisTests.cs
index 923784f4f..b415ec3d6 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiMaskSynthesisTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiMaskSynthesisTests.cs
@@ -11,9 +11,10 @@ public class MultiMaskSynthesisTests
private const int PlaceX = 1480;
private const int PlaceY = 1620;
- [Fact]
+ [SkippableFact]
public void ComputeMultiMaskAt_MatchesCheckMovement_OverFootprintAndHalo()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[MapId];
map.GetAverageZ(PlaceX, PlaceY, out _, out var z, out _);
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiSplitRoutingTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiSplitRoutingTests.cs
index 4775b8fac..1103cdb83 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiSplitRoutingTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiSplitRoutingTests.cs
@@ -17,9 +17,10 @@ public class MultiSplitRoutingTests
private const int PlaceX = 1500;
private const int PlaceY = 1600;
- [Fact]
+ [SkippableFact]
public void PlacedMulti_RoutesFootprintAndHalo_ToFallthroughMulti()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[MapId];
Assert.NotNull(map);
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiWalkabilityTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiWalkabilityTests.cs
index 59e583ac6..d8d46e7f8 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiWalkabilityTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/Multi/MultiWalkabilityTests.cs
@@ -23,9 +23,10 @@ public class MultiWalkabilityTests
public WalkerStub() => Body = 0xC9;
}
- [Fact]
+ [SkippableFact]
public void WallCell_CannotBeEnteredFromAnyAdjacentCell()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[MapId];
map.GetAverageZ(PlaceX, PlaceY, out _, out var z, out _);
@@ -86,9 +87,10 @@ public class MultiWalkabilityTests
}
}
- [Fact]
+ [SkippableFact]
public void FloorCell_IsStandable()
{
+ TileDataRequirement.SkipIfMissing();
StepCache.Instance.Clear();
var map = Map.Maps[MapId];
map.GetAverageZ(PlaceX, PlaceY, out _, out var z, out _);
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/StepCacheFileTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/StepCacheFileTests.cs
index 0d865d08d..1ef3aa8ab 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/StepCacheFileTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/StepCacheFileTests.cs
@@ -347,9 +347,10 @@ public class StepCacheFileTests
/// to which proves the
/// default lazy behavior.
///
- [Fact]
+ [SkippableFact]
public void TryOpenLazyReader_WithPreloadFlag_MaterializesAllChunksImmediately()
{
+ TileDataRequirement.SkipIfMissing();
var cache = StepCache.Instance;
cache.Clear();
cache.MissPromotionThreshold = 1;
@@ -401,9 +402,10 @@ public class StepCacheFileTests
}
}
- [Fact]
+ [SkippableFact]
public void LazyReaderHit_BypassesMissTrackerOnFirstTouch()
{
+ TileDataRequirement.SkipIfMissing();
var cache = StepCache.Instance;
cache.Clear();
cache.MissPromotionThreshold = 1; // eager build for save phase
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/StepCacheLifecycleTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/StepCacheLifecycleTests.cs
index 244c51534..436f78c7e 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/StepCacheLifecycleTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/StepCacheLifecycleTests.cs
@@ -54,9 +54,10 @@ public class StepCacheLifecycleTests
Assert.Equal(1L, stats.FallthroughNotBuilt);
}
- [Fact]
+ [SkippableFact]
public void TryGetMask_SecondTouchWithinWindow_PromotesAndBuilds()
{
+ TileDataRequirement.SkipIfMissing();
var cache = StepCache.Instance;
cache.Clear();
cache.MissPromotionThreshold = 2;
@@ -112,9 +113,10 @@ public class StepCacheLifecycleTests
Assert.Equal(2L, cache.GetStats().FallthroughNotBuilt);
}
- [Fact]
+ [SkippableFact]
public void TryGetMask_MultipleCallsInSameFindGeneration_StayInFallthrough()
{
+ TileDataRequirement.SkipIfMissing();
var cache = StepCache.Instance;
cache.Clear();
cache.MissPromotionThreshold = 2;
@@ -207,9 +209,10 @@ public class StepCacheLifecycleTests
Assert.Equal((byte)0, lookup.WalkMask);
}
- [Fact]
+ [SkippableFact]
public void MultiCoveredCell_AndHalo_RouteToFallthrough()
{
+ TileDataRequirement.SkipIfMissing();
var cache = StepCache.Instance;
cache.Clear();
cache.MissPromotionThreshold = 1; // eager build so a multi-free cell serves immediately
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/StepCacheParityTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/StepCacheParityTests.cs
index 149a9fe13..0dc1eb12f 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/StepCacheParityTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/StepCacheParityTests.cs
@@ -111,9 +111,10 @@ public class StepCacheParityTests
/// (Atlantic coast) and asserts at least one cell has a non-zero WetMask. Catches the
/// failure mode where StepProbe silently bakes zero swim output everywhere.
///
- [Fact]
+ [SkippableFact]
public void SwimBake_ProducesWetCells_OnKnownWaterRegion()
{
+ TileDataRequirement.SkipIfMissing();
var map = Map.Maps[1];
Assert.NotNull(map);
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/StepProbeParityTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/StepProbeParityTests.cs
index df8ff5da5..429d60ca7 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/StepProbeParityTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/StepProbeParityTests.cs
@@ -14,11 +14,12 @@ public class StaticWalkabilityParityTests
_output = output;
}
- [Theory]
+ [SkippableTheory]
[InlineData("britain_inn_dense", 1480, 1610, 32)]
[InlineData("trammel_open_plain", 1500, 1600, 32)]
public void BakerMatchesCheckMovement(string label, int xStart, int yStart, int size)
{
+ TileDataRequirement.SkipIfMissing();
var map = Map.Maps[1];
Assert.NotNull(map);
diff --git a/Projects/UOContent.Tests/Tests/Engines/Pathing/StepProbeTests.cs b/Projects/UOContent.Tests/Tests/Engines/Pathing/StepProbeTests.cs
index cfca235da..9a32d66bf 100644
--- a/Projects/UOContent.Tests/Tests/Engines/Pathing/StepProbeTests.cs
+++ b/Projects/UOContent.Tests/Tests/Engines/Pathing/StepProbeTests.cs
@@ -124,9 +124,10 @@ public class StepProbeTests
Assert.True(found, "Expected at least one fully-flat open cell in (1500..1532, 1600..1632)");
}
- [Fact]
+ [SkippableFact]
public void ComputeMaskAt_BritainInnDense_HasCellWithBlockedDirections()
{
+ TileDataRequirement.SkipIfMissing();
// Invariant: inside the dense Britain inn region, at least one cell must have
// at least one direction blocked by a static. Protects against a regression
// where the baker reports everything as walkable (the original false-pass bug).
@@ -181,9 +182,10 @@ public class StepProbeTests
}
}
- [Fact]
+ [SkippableFact]
public void ComputeMaskAt_PinnedCell_TrammelOpenPlainOrigin()
{
+ TileDataRequirement.SkipIfMissing();
// PINNING test: locks specific output for Trammel (1500, 1600).
// Cell at z=10 with mask 0xC1 (N + W + NW only walkable). The other five
// directions are blocked by water (E/SE/S/SW are wet tiles, NE is shore).
@@ -214,9 +216,10 @@ public class StepProbeTests
Assert.Equal((sbyte)10, result.GetWalkZ(Direction.Up));
}
- [Fact]
+ [SkippableFact]
public void ComputeMaskAt_PinnedCell_BritainInnDenseOrigin()
{
+ TileDataRequirement.SkipIfMissing();
// PINNING test: locks specific output for Trammel (1480, 1610).
// Cell at z=20 with mask 0x3F (N/NE/E/SE/S/SW walkable, W/NW blocked by
// a wall to the west). All walkable directions stay flat at z=20.
diff --git a/Projects/UOContent.Tests/Tests/Mobiles/AI/ApproachTargetTests.cs b/Projects/UOContent.Tests/Tests/Mobiles/AI/ApproachTargetTests.cs
index fa3eb23bd..923f4aff9 100644
--- a/Projects/UOContent.Tests/Tests/Mobiles/AI/ApproachTargetTests.cs
+++ b/Projects/UOContent.Tests/Tests/Mobiles/AI/ApproachTargetTests.cs
@@ -176,9 +176,10 @@ public class ApproachTargetTests
Assert.True(caught, "chaser must catch a target that walks away then stops");
}
- [Fact]
+ [SkippableFact]
public void UnreachableTarget_GivesUp_AndIdles()
{
+ TileDataRequirement.SkipIfMissing();
var map = Map.Maps[1];
Assert.NotNull(map);
map.GetAverageZ(1500, 1601, out _, out var z, out _);
@@ -243,9 +244,10 @@ public class ApproachTargetTests
Assert.True(stayedIdle, "after giving up, the creature must idle, not shuffle");
}
- [Fact]
+ [SkippableFact]
public void WallBetween_RoutesAround_ReachesTarget()
{
+ TileDataRequirement.SkipIfMissing();
var map = Map.Maps[1];
Assert.NotNull(map);
map.GetAverageZ(1500, 1600, out _, out var z, out _);