feat(mosstank): add VTank-style automation PoC
This commit is contained in:
parent
f6fe0f2a4f
commit
4e6e9bc9d9
212 changed files with 49462 additions and 416 deletions
|
|
@ -0,0 +1,199 @@
|
|||
using AcDream.Plugin.Abstractions;
|
||||
|
||||
namespace AcDream.Plugins.MossTank.Tests;
|
||||
|
||||
public sealed class VtankNavRouteSerializerTests
|
||||
{
|
||||
[Fact]
|
||||
public void LoadsEveryOfficialNav12WaypointPayload()
|
||||
{
|
||||
const string nav = """
|
||||
uTank2 NAV 1.2
|
||||
1
|
||||
10
|
||||
0
|
||||
12.5
|
||||
-3.25
|
||||
0.5
|
||||
0
|
||||
1
|
||||
13
|
||||
-4
|
||||
0
|
||||
0
|
||||
1234
|
||||
2
|
||||
14
|
||||
-5
|
||||
0
|
||||
0
|
||||
987
|
||||
3
|
||||
15
|
||||
-6
|
||||
0
|
||||
0
|
||||
2500
|
||||
4
|
||||
16
|
||||
-7
|
||||
0
|
||||
0
|
||||
/say hello
|
||||
5
|
||||
17
|
||||
-8
|
||||
0
|
||||
0
|
||||
4321
|
||||
Vendor Bob
|
||||
6
|
||||
18
|
||||
-9
|
||||
0
|
||||
0
|
||||
Portal to Holtburg
|
||||
14
|
||||
True
|
||||
18.5
|
||||
-9.5
|
||||
1
|
||||
7
|
||||
19
|
||||
-10
|
||||
0
|
||||
0
|
||||
Town Crier
|
||||
37
|
||||
True
|
||||
19.5
|
||||
-10.5
|
||||
2
|
||||
8
|
||||
20
|
||||
-11
|
||||
0
|
||||
0
|
||||
9
|
||||
21
|
||||
-12
|
||||
0
|
||||
0
|
||||
180.5
|
||||
True
|
||||
1000.00005
|
||||
""";
|
||||
var settings = new NavigationSettings { Enabled = true };
|
||||
|
||||
bool loaded = VtankNavRouteSerializer.TryLoad(
|
||||
nav,
|
||||
settings,
|
||||
NoOpSpellCatalog.Instance,
|
||||
out string error);
|
||||
|
||||
Assert.True(loaded, error);
|
||||
Assert.True(settings.Enabled);
|
||||
Assert.Equal(RouteMode.Circular, settings.Mode);
|
||||
Assert.Equal(10, settings.Waypoints.Count);
|
||||
Assert.Equal(RouteWaypointType.Point, settings.Waypoints[0].Type);
|
||||
Assert.Equal(12.5, settings.Waypoints[0].Position.EastWest);
|
||||
Assert.Equal(1234u, settings.Waypoints[1].ObjectId);
|
||||
Assert.Equal(987u, settings.Waypoints[2].RecallSpellId);
|
||||
Assert.Equal(2500, settings.Waypoints[3].DurationMilliseconds);
|
||||
Assert.Equal("/say hello", settings.Waypoints[4].Text);
|
||||
Assert.Equal("Vendor Bob", settings.Waypoints[5].ObjectName);
|
||||
Assert.Equal(18.5, settings.Waypoints[6].Position.EastWest);
|
||||
Assert.Equal("Town Crier", settings.Waypoints[7].ObjectName);
|
||||
Assert.Equal(14, settings.Waypoints[6].LegacyObjectClass);
|
||||
Assert.Equal(37, settings.Waypoints[7].LegacyObjectClass);
|
||||
Assert.True(settings.Waypoints[6].LegacyReferenceValid);
|
||||
Assert.Equal(RouteWaypointType.Checkpoint, settings.Waypoints[8].Type);
|
||||
Assert.Equal(180.5f, settings.Waypoints[9].JumpHeadingDegrees);
|
||||
Assert.True(settings.Waypoints[9].JumpRun);
|
||||
Assert.Equal(1000, settings.Waypoints[9].JumpChargeMilliseconds);
|
||||
Assert.Equal(RouteJumpDirection.StrafeRight, settings.Waypoints[9].JumpDirection);
|
||||
|
||||
string saved = VtankNavRouteSerializer.Save(settings);
|
||||
Assert.StartsWith("uTank2 NAV 1.2\r\n", saved, StringComparison.Ordinal);
|
||||
Assert.Contains("1000.00005\r\n", saved, StringComparison.Ordinal);
|
||||
var roundTrip = new NavigationSettings();
|
||||
Assert.True(VtankNavRouteSerializer.TryLoad(
|
||||
saved,
|
||||
roundTrip,
|
||||
NoOpSpellCatalog.Instance,
|
||||
out error), error);
|
||||
Assert.Equal(10, roundTrip.Waypoints.Count);
|
||||
Assert.Equal(14, roundTrip.Waypoints[6].LegacyObjectClass);
|
||||
Assert.Equal(RouteJumpDirection.StrafeRight,
|
||||
roundTrip.Waypoints[9].JumpDirection);
|
||||
Assert.Equal(1000, roundTrip.Waypoints[9].JumpChargeMilliseconds);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadsEmbeddedWrapperAndDoesNotMutateOnFailure()
|
||||
{
|
||||
const string wrapped = """
|
||||
Route Name
|
||||
1
|
||||
uTank2 NAV 1.2
|
||||
4
|
||||
1
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
0
|
||||
""";
|
||||
var settings = new NavigationSettings();
|
||||
Assert.True(VtankNavRouteSerializer.TryLoad(
|
||||
wrapped,
|
||||
settings,
|
||||
NoOpSpellCatalog.Instance,
|
||||
out _));
|
||||
Assert.Equal(RouteMode.Once, settings.Mode);
|
||||
Assert.Single(settings.Waypoints);
|
||||
|
||||
Assert.False(VtankNavRouteSerializer.TryLoad(
|
||||
"broken",
|
||||
settings,
|
||||
NoOpSpellCatalog.Instance,
|
||||
out string error));
|
||||
Assert.NotEmpty(error);
|
||||
Assert.Equal(RouteMode.Once, settings.Mode);
|
||||
Assert.Single(settings.Waypoints);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TargetRoutePreservesSignedRetailObjectIdBitPattern()
|
||||
{
|
||||
var original = new NavigationSettings
|
||||
{
|
||||
Mode = RouteMode.Target,
|
||||
FollowTargetName = "High-bit fellow",
|
||||
FollowTargetObjectId = 0xF1234567u,
|
||||
};
|
||||
|
||||
string saved = VtankNavRouteSerializer.Save(original);
|
||||
var loaded = new NavigationSettings();
|
||||
Assert.True(VtankNavRouteSerializer.TryLoad(
|
||||
saved,
|
||||
loaded,
|
||||
NoOpSpellCatalog.Instance,
|
||||
out string error), error);
|
||||
|
||||
Assert.Equal(RouteMode.Target, loaded.Mode);
|
||||
Assert.Equal("High-bit fellow", loaded.FollowTargetName);
|
||||
Assert.Equal(0xF1234567u, loaded.FollowTargetObjectId);
|
||||
}
|
||||
|
||||
private sealed class NoOpSpellCatalog : ISpellCatalog
|
||||
{
|
||||
public static NoOpSpellCatalog Instance { get; } = new();
|
||||
public IReadOnlyList<PluginSpellInfo> KnownSelfBuffs => [];
|
||||
public bool TryGet(uint spellId, out PluginSpellInfo info)
|
||||
{
|
||||
info = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue