diff --git a/src/AcDream.Plugins.MossTank/MossTankPanel.cs b/src/AcDream.Plugins.MossTank/MossTankPanel.cs index 32fc9133..830b1a03 100644 --- a/src/AcDream.Plugins.MossTank/MossTankPanel.cs +++ b/src/AcDream.Plugins.MossTank/MossTankPanel.cs @@ -1033,9 +1033,26 @@ internal sealed partial class MossTankPanel public string SelectedRouteMode => _navigationSettings.Mode == RouteMode.Target ? "Follow" : _navigationSettings.Mode.ToString(); - public IReadOnlyList RouteRecallNames => - Enum.GetNames(); - public string SelectedRouteRecall => _routeRecallKind.ToString(); + // D-2 (round E architecture re-check): the combo used to show + // Enum.GetNames' bare C# identifiers ("PrimaryPortalRecall", + // "ParadoxTouchedOlthoiInfestedAreaRecall", ...) instead of VTank's + // real recall names — RouteInsertModeNames/RouteModeNames above + // already route their own display captions through a dedicated + // string, not the enum's own ToString(); this brings Recall in line + // via the same RecallDisplayName table AddRouteRecallCore/RecallLabel + // already use. + public IReadOnlyList RouteRecallNames + { + get + { + RouteRecallKind[] values = Enum.GetValues(); + var names = new string[values.Length]; + for (int i = 0; i < values.Length; i++) + names[i] = RouteWaypoint.RecallDisplayName(values[i]); + return names; + } + } + public string SelectedRouteRecall => RouteWaypoint.RecallDisplayName(_routeRecallKind); public IReadOnlyList RouteProfileNames => _routeProfiles.AvailableNames; public string SelectedRouteProfile => _routeProfiles.Selected; @@ -1116,10 +1133,19 @@ internal sealed partial class MossTankPanel RefreshRouteEditor(); SaveRouteProfile(); }; + // D-2: parses the SAME display string RouteRecallNames/SelectedRouteRecall + // now show (Enum.TryParse against the bare C# identifier no longer + // matches what the combo actually sends back). public Action SelectRouteRecall => value => { - if (Enum.TryParse(value, ignoreCase: true, out RouteRecallKind recall)) - _routeRecallKind = recall; + foreach (RouteRecallKind kind in Enum.GetValues()) + { + if (RouteWaypoint.RecallDisplayName(kind).Equals(value, StringComparison.OrdinalIgnoreCase)) + { + _routeRecallKind = kind; + return; + } + } }; public Action SelectRouteWaypoint => index => _selectedRouteWaypoint = ClampRow(index, _navigationSettings.Waypoints.Count); diff --git a/src/AcDream.Plugins.MossTank/mosstank.xml b/src/AcDream.Plugins.MossTank/mosstank.xml index fc318aab..e33c5c2a 100644 --- a/src/AcDream.Plugins.MossTank/mosstank.xml +++ b/src/AcDream.Plugins.MossTank/mosstank.xml @@ -709,7 +709,16 @@ VTank's one slash-command entry) in VTank's own combo order — see RouteRecallKind's own doc comment for the deviation from the earlier 4-entry model. --> - + diff --git a/tests/AcDream.Plugins.MossTank.Tests/MossTankPanelTests.cs b/tests/AcDream.Plugins.MossTank.Tests/MossTankPanelTests.cs index d88fbfee..3b74dd81 100644 --- a/tests/AcDream.Plugins.MossTank.Tests/MossTankPanelTests.cs +++ b/tests/AcDream.Plugins.MossTank.Tests/MossTankPanelTests.cs @@ -2475,6 +2475,49 @@ public sealed class MossTankPanelTests Assert.Contains("77", panel.RouteWaypointTextColumn[1]); } + /// + /// D-2 (round E architecture re-check): the combo used to show + /// Enum.GetNames' bare C# identifiers ("PrimaryPortalRecall", + /// "ParadoxTouchedOlthoiInfestedAreaRecall", ...) — RouteRecallNames/ + /// SelectedRouteRecall must show VTank's real recall names (the same + /// RecallDisplayName table AddRouteRecallCore already uses), in + /// VTank's own combo order, and SelectRouteRecall must parse THAT + /// display string back rather than the enum identifier. + /// + [Fact] + public void RouteRecallComboShowsVtankNamesNotEnumIdentifiers() + { + var automation = new FakeAutomation { NavigationSnapshot = NavigationAt(0f) }; + var panel = new MossTankPanel(new FakeHost(automation)); + + Assert.Equal( + [ + "Primary Portal Recall", "Secondary Portal Recall", "Lifestone Recall", + "Lifestone Sending", "Portal Recall", "Recall Aphus Lassel", + "Recall the Sanctuary", "Recall to the Singularity Caul", + "Glenden Wood Recall", "Aerlinthe Recall", "Mount Lethe Recall", + "Ulgrim's Recall", "Bur Recall", + "Paradox-touched Olthoi Infested Area Recall", + "Call of the Mhoire Forge", "Colosseum Recall", "Facility Hub Recall", + "Gear Knight Invasion Area Camp Recall", "Lost City of Neftet Recall", + "Return to the Keep", "Rynthid Recall", "Viridian Rise Recall", + "Viridian Rise Great Tree Recall", "Celestial Hand Stronghold Recall", + "Radiant Blood Stronghold Recall", "Eldrytch Web Stronghold Recall", + "Marketplace Recall", + ], + panel.RouteRecallNames); + + // Default selection reads as a real name, not "PrimaryPortalRecall". + Assert.Equal("Primary Portal Recall", panel.SelectedRouteRecall); + + panel.SelectRouteRecall("Lifestone Recall"); + Assert.Equal("Lifestone Recall", panel.SelectedRouteRecall); + + panel.AddRouteRecall(); + Assert.Contains("Lifestone Recall", panel.RouteNotice, StringComparison.Ordinal); + Assert.Contains("Lifestone Recall", Assert.Single(panel.RouteWaypointTextColumn)); + } + [Fact] public void RoutePauseSecondsFieldParsesAndClampsInput() {