diff --git a/vnavmesh/Debug/DebugNavmeshManager.cs b/vnavmesh/Debug/DebugNavmeshManager.cs index e42531f..359e3fb 100644 --- a/vnavmesh/Debug/DebugNavmeshManager.cs +++ b/vnavmesh/Debug/DebugNavmeshManager.cs @@ -67,7 +67,7 @@ public void Draw() ImGui.TextUnformatted($"Current target: {_target}"); ImGui.Checkbox("Allow movement", ref _path.MovementAllowed); - ImGui.Checkbox("Auto mesh on TerritoryChanged", ref _manager.AutoMesh); + ImGui.Checkbox("Auto load mesh when changing zone", ref _manager.AutoLoad); ImGui.Checkbox("Use raycasts", ref _path.UseRaycasts); ImGui.Checkbox("Use string pulling", ref _path.UseStringPulling); if (ImGui.Button("Pathfind to target using navmesh")) diff --git a/vnavmesh/IPCProvider.cs b/vnavmesh/IPCProvider.cs new file mode 100644 index 0000000..9b1eb00 --- /dev/null +++ b/vnavmesh/IPCProvider.cs @@ -0,0 +1,62 @@ +using Navmesh.Movement; +using System; +using System.Collections.Generic; +using System.Numerics; + +namespace Navmesh +{ + class IPCProvider : IDisposable + { + private List _disposeActions = new(); + + public IPCProvider(NavmeshManager navmeshManager, FollowPath followPath, MainWindow mainWindow) + { + Register("Nav.IsReady", () => navmeshManager.Navmesh != null); + Register("Nav.BuildProgress", () => navmeshManager.TaskProgress); + Register("Nav.Reload", () => navmeshManager.Reload(true)); + Register("Nav.Rebuild", () => navmeshManager.Reload(false)); + Register("Nav.IsAutoLoad", () => navmeshManager.AutoLoad); + Register("Nav.SetAutoLoad", v => navmeshManager.AutoLoad = v); + + Register("Path.MoveTo", followPath.MoveTo); + Register("Path.FlyTo", followPath.FlyTo); + Register("Path.Stop", followPath.Stop); + Register("Path.IsRunning", () => followPath.Waypoints.Count > 0); + Register("Path.NumWaypoints", () => followPath.Waypoints.Count); + Register("Path.GetMovementAllowed", () => followPath.MovementAllowed); + Register("Path.SetMovementAllowed", v => followPath.MovementAllowed = v); + Register("Path.GetTolerance", () => followPath.Tolerance); + Register("Path.SetTolerance", v => followPath.Tolerance = v); + + Register("Window.IsOpen", () => mainWindow.IsOpen); + Register("Window.SetOpen", v => mainWindow.IsOpen = v); + } + + public void Dispose() + { + foreach (var a in _disposeActions) + a(); + } + + private void Register(string name, Func func) + { + var p = Service.PluginInterface.GetIpcProvider("vnavmesh." + name); + p.RegisterFunc(func); + _disposeActions.Add(p.UnregisterFunc); + } + + private void Register(string name, Action func) + { + var p = Service.PluginInterface.GetIpcProvider("vnavmesh." + name); + p.RegisterAction(func); + _disposeActions.Add(p.UnregisterAction); + } + + private void Register(string name, Action func) + { + var p = Service.PluginInterface.GetIpcProvider("vnavmesh." + name); + p.RegisterAction(func); + _disposeActions.Add(p.UnregisterAction); + } + } +} diff --git a/vnavmesh/NavmeshManager.cs b/vnavmesh/NavmeshManager.cs index 05e5144..bd52c5f 100644 --- a/vnavmesh/NavmeshManager.cs +++ b/vnavmesh/NavmeshManager.cs @@ -9,7 +9,7 @@ namespace Navmesh; // manager that loads navmesh matching current zone public class NavmeshManager : IDisposable { - public bool AutoMesh = true; + public bool AutoLoad = true; // whether we load/build mesh automatically when changing zone public event Action? OnNavmeshChanged; public Navmesh? Navmesh => _navmesh; public float TaskProgress => _task != null ? _taskProgress : -1; // returns negative value if task is not running @@ -42,8 +42,6 @@ public void Dispose() public void Update() { - if (!AutoMesh) - return; if (_task != null) { if (!_task.IsCompleted) @@ -67,6 +65,13 @@ public void Update() if (curKey == _lastKey) return; // everything up-to-date + if (!AutoLoad) + { + if (_lastKey.Length == 0) + return; // nothing is loaded, and auto-load is forbidden + curKey = ""; // just unload existing mesh + } + Service.Log.Info($"Starting transition from '{_lastKey}' to '{curKey}'"); _lastKey = curKey; Reload(true); @@ -79,7 +84,7 @@ public bool Reload(bool allowLoadFromCache) Service.Log.Error($"Can't initiate reload - another task is already in progress"); return false; // some task is already in progress... } - AutoMesh = true; + ClearState(); if (_lastKey.Length > 0) { diff --git a/vnavmesh/Plugin.cs b/vnavmesh/Plugin.cs index 8a0cd92..8ca8bee 100644 --- a/vnavmesh/Plugin.cs +++ b/vnavmesh/Plugin.cs @@ -16,7 +16,8 @@ public sealed class Plugin : IDalamudPlugin private NavmeshManager _navmeshManager; private FollowPath _followPath; private MainWindow _wndMain; - + private IPCProvider _ipcProvider; + public Plugin(DalamudPluginInterface dalamud) { if (!dalamud.ConfigDirectory.Exists) @@ -32,9 +33,11 @@ public Plugin(DalamudPluginInterface dalamud) _navmeshManager = new(new($"{dalamud.ConfigDirectory.FullName}/meshcache")); _followPath = new(_navmeshManager); - _wndMain = new(_navmeshManager, _followPath); + _ipcProvider = new(_navmeshManager, _followPath, _wndMain); + WindowSystem.AddWindow(_wndMain); + //_wndMain.IsOpen = true; dalamud.UiBuilder.Draw += WindowSystem.Draw; dalamud.UiBuilder.OpenConfigUi += () => _wndMain.IsOpen = true; @@ -53,11 +56,7 @@ public Plugin(DalamudPluginInterface dalamud) ShowInHelp = true, }); - _wndMain.IsOpen = true; - Service.Framework.Update += OnUpdate; - - VNavmeshIPC.Initialize(_navmeshManager, _followPath, _wndMain); } public void Dispose() @@ -66,11 +65,11 @@ public void Dispose() Service.CommandManager.RemoveHandler("/vnavmesh"); WindowSystem.RemoveAllWindows(); - _wndMain.Dispose(); + _ipcProvider.Dispose(); + _wndMain.Dispose(); _followPath.Dispose(); _navmeshManager.Dispose(); - VNavmeshIPC.Dispose(); } private void OnUpdate(IFramework fwk) diff --git a/vnavmesh/Service.cs b/vnavmesh/Service.cs index e9a032e..83fc555 100644 --- a/vnavmesh/Service.cs +++ b/vnavmesh/Service.cs @@ -22,7 +22,7 @@ public class Service [PluginService] public static ITextureProvider TextureProvider { get; private set; } = null!; [PluginService] public static IAddonLifecycle AddonLifecycle { get; private set; } = null!; [PluginService] public static IFramework Framework { get; private set; } = null!; - [PluginService] public static DalamudPluginInterface PluginInterface { get; private set; } + [PluginService] public static DalamudPluginInterface PluginInterface { get; private set; } = null!; public static Lumina.GameData LuminaGameData => DataManager.GameData; public static T? LuminaRow(uint row) where T : Lumina.Excel.ExcelRow => LuminaGameData.GetExcelSheet(Lumina.Data.Language.English)?.GetRow(row); diff --git a/vnavmesh/VNavmeshIPC.cs b/vnavmesh/VNavmeshIPC.cs deleted file mode 100644 index 8a7b641..0000000 --- a/vnavmesh/VNavmeshIPC.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Navmesh.Movement; -using System.Numerics; - -namespace Navmesh -{ - internal static class VNavmeshIPC - { - private static NavmeshManager _navmeshManager; - private static FollowPath _followPath; - private static MainWindow _mainWindow; - - internal static void Initialize(NavmeshManager navmeshManager, FollowPath followPath, MainWindow mainWindow) - { - Service.PluginInterface.GetIpcProvider("vnavmesh.NavmeshIsNull").RegisterFunc(NavmeshIsNull); - Service.PluginInterface.GetIpcProvider("vnavmesh.TaskProgress").RegisterFunc(TaskProgress); - Service.PluginInterface.GetIpcProvider("vnavmesh.WaypointsCount").RegisterFunc(WaypointsCount); - Service.PluginInterface.GetIpcProvider("vnavmesh.MoveTo").RegisterAction(MoveTo); - Service.PluginInterface.GetIpcProvider("vnavmesh.MoveDir").RegisterAction(MoveDir); - Service.PluginInterface.GetIpcProvider("vnavmesh.MoveTarget").RegisterAction(MoveTarget); - Service.PluginInterface.GetIpcProvider("vnavmesh.FlyTo").RegisterAction(FlyTo); - Service.PluginInterface.GetIpcProvider("vnavmesh.FlyDir").RegisterAction(FlyDir); - Service.PluginInterface.GetIpcProvider("vnavmesh.FlyTarget").RegisterAction(FlyTarget); - Service.PluginInterface.GetIpcProvider("vnavmesh.MovementAllowed").RegisterFunc(MovementAllowed); - Service.PluginInterface.GetIpcProvider("vnavmesh.SetMovementAllowed").RegisterAction(SetMovementAllowed); - Service.PluginInterface.GetIpcProvider("vnavmesh.Tolerance").RegisterFunc(Tolerance); - Service.PluginInterface.GetIpcProvider("vnavmesh.SetTolerance").RegisterAction(SetTolerance); - Service.PluginInterface.GetIpcProvider("vnavmesh.Stop").RegisterAction(Stop); - Service.PluginInterface.GetIpcProvider("vnavmesh.AutoMesh").RegisterAction(AutoMesh); - Service.PluginInterface.GetIpcProvider("vnavmesh.Reload").RegisterAction(Reload); - Service.PluginInterface.GetIpcProvider("vnavmesh.Rebuild").RegisterAction(Rebuild); - Service.PluginInterface.GetIpcProvider("vnavmesh.MainWindowIsOpen").RegisterAction(MainWindowIsOpen); - - _navmeshManager = navmeshManager; - _followPath = followPath; - _mainWindow = mainWindow; - } - - internal static void Dispose() - { - Service.PluginInterface.GetIpcProvider("vnavmesh.NavmeshIsNull").UnregisterFunc(); - Service.PluginInterface.GetIpcProvider("vnavmesh.TaskProgress").UnregisterFunc(); - Service.PluginInterface.GetIpcProvider("vnavmesh.WaypointsCount").UnregisterFunc(); - Service.PluginInterface.GetIpcProvider("vnavmesh.MoveTo").UnregisterAction(); - Service.PluginInterface.GetIpcProvider("vnavmesh.MoveDir").UnregisterAction(); - Service.PluginInterface.GetIpcProvider("vnavmesh.MoveTarget").UnregisterAction(); - Service.PluginInterface.GetIpcProvider("vnavmesh.FlyTo").UnregisterAction(); - Service.PluginInterface.GetIpcProvider("vnavmesh.FlyDir").UnregisterAction(); - Service.PluginInterface.GetIpcProvider("vnavmesh.FlyTarget").UnregisterAction(); - Service.PluginInterface.GetIpcProvider("vnavmesh.IsMovementAllowed").UnregisterFunc(); - Service.PluginInterface.GetIpcProvider("vnavmesh.SetMovementAllowed").UnregisterAction(); - Service.PluginInterface.GetIpcProvider("vnavmesh.Tolerance").UnregisterFunc(); - Service.PluginInterface.GetIpcProvider("vnavmesh.SetTolerance").UnregisterAction(); - Service.PluginInterface.GetIpcProvider("vnavmesh.Stop").UnregisterAction(); - Service.PluginInterface.GetIpcProvider("vnavmesh.AutoMesh").UnregisterAction(); - Service.PluginInterface.GetIpcProvider("vnavmesh.Reload").UnregisterAction(); - Service.PluginInterface.GetIpcProvider("vnavmesh.Rebuild").UnregisterAction(); - Service.PluginInterface.GetIpcProvider("vnavmesh.MainWindowIsOpen").UnregisterAction(); - } - - private static bool NavmeshIsNull() => _navmeshManager.Navmesh is null; - private static float TaskProgress() => _navmeshManager.TaskProgress; - private static int WaypointsCount() => _followPath.Waypoints.Count; - private static void MoveTo(Vector3 position) => MoveToCommand(position, false, false); - private static void MoveDir(Vector3 position) => MoveToCommand(position, true, false); - private static void MoveTarget() - { - var moveTarget = Service.TargetManager.Target; - if (moveTarget != null) - _followPath.MoveTo(moveTarget.Position); - } - - private static void FlyTo(Vector3 position) => MoveToCommand(position, false, true); - private static void FlyDir(Vector3 position) => MoveToCommand(position, true, true); - private static void FlyTarget() - { - var moveTarget = Service.TargetManager.Target; - if (moveTarget != null) - _followPath.FlyTo(moveTarget.Position); - } - - private static void SetMovementAllowed(bool allowed) => _followPath.MovementAllowed = allowed; - private static bool MovementAllowed() => _followPath.MovementAllowed; - private static void SetTolerance(float tolerance) => _followPath.Tolerance = tolerance; - private static float Tolerance() => _followPath.Tolerance; - private static void Stop() =>_followPath.Stop(); - private static void AutoMesh(bool autoMesh) => _navmeshManager.AutoMesh = autoMesh; - private static void Reload() => _navmeshManager.Reload(true); - private static void Rebuild() => _navmeshManager.Reload(false); - private static void MainWindowIsOpen(bool isOpen) => _mainWindow.IsOpen = isOpen; - - private static void MoveToCommand(Vector3 offset, bool relativeToPlayer, bool fly) - { - var originActor = relativeToPlayer ? Service.ClientState.LocalPlayer : null; - var origin = originActor?.Position ?? new(); - - if (fly) - _followPath.FlyTo(origin + offset); - else - _followPath.MoveTo(origin + offset); - } - } -}