using System.Collections.Generic; using System.Numerics; using System.Threading; using System.Threading.Tasks; using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using Dalamud.Plugin.Ipc.Exceptions; using Microsoft.Extensions.Logging; namespace Questionable.External; internal sealed class NavmeshIpc { private readonly ILogger _logger; private readonly ICallGateSubscriber _isNavReady; private readonly ICallGateSubscriber>> _navPathfind; private readonly ICallGateSubscriber, bool, object> _pathMoveTo; private readonly ICallGateSubscriber _pathStop; private readonly ICallGateSubscriber _pathIsRunning; private readonly ICallGateSubscriber> _pathListWaypoints; private readonly ICallGateSubscriber _pathSetTolerance; private readonly ICallGateSubscriber _queryPointOnFloor; private readonly ICallGateSubscriber _buildProgress; public bool IsReady { get { try { return _isNavReady.InvokeFunc(); } catch (IpcError) { return false; } } } public bool IsPathRunning { get { try { return _pathIsRunning.InvokeFunc(); } catch (IpcError) { return false; } } } public NavmeshIpc(IDalamudPluginInterface pluginInterface, ILogger logger) { _logger = logger; _isNavReady = pluginInterface.GetIpcSubscriber("vnavmesh.Nav.IsReady"); _navPathfind = pluginInterface.GetIpcSubscriber>>("vnavmesh.Nav.PathfindCancelable"); _pathMoveTo = pluginInterface.GetIpcSubscriber, bool, object>("vnavmesh.Path.MoveTo"); _pathStop = pluginInterface.GetIpcSubscriber("vnavmesh.Path.Stop"); _pathIsRunning = pluginInterface.GetIpcSubscriber("vnavmesh.Path.IsRunning"); _pathListWaypoints = pluginInterface.GetIpcSubscriber>("vnavmesh.Path.ListWaypoints"); _pathSetTolerance = pluginInterface.GetIpcSubscriber("vnavmesh.Path.SetTolerance"); _queryPointOnFloor = pluginInterface.GetIpcSubscriber("vnavmesh.Query.Mesh.PointOnFloor"); _buildProgress = pluginInterface.GetIpcSubscriber("vnavmesh.Nav.BuildProgress"); } public void Stop() { try { _pathStop.InvokeAction(); } catch (IpcError exception) { _logger.LogWarning(exception, "Could not stop navigating via navmesh"); } } public Task> Pathfind(Vector3 localPlayerPosition, Vector3 targetPosition, bool fly, CancellationToken cancellationToken) { try { _pathSetTolerance.InvokeAction(0.25f); return _navPathfind.InvokeFunc(localPlayerPosition, targetPosition, fly, cancellationToken); } catch (IpcError exception) { _logger.LogWarning(exception, "Could not pathfind via navmesh"); return Task.FromException>(exception); } } public void MoveTo(List position, bool fly) { Stop(); try { _pathMoveTo.InvokeAction(position, fly); } catch (IpcError exception) { _logger.LogWarning(exception, "Could not move via navmesh"); } } public Vector3? GetPointOnFloor(Vector3 position, bool unlandable) { try { return _queryPointOnFloor.InvokeFunc(position, unlandable, 0.2f); } catch (IpcError) { return null; } } public List GetWaypoints() { if (IsPathRunning) { try { return _pathListWaypoints.InvokeFunc(); } catch (IpcError) { return new List(); } } return new List(); } public int GetBuildProgress() { try { float num = _buildProgress.InvokeFunc(); if (num < 0f) { return 100; } return (int)(num * 100f); } catch (IpcError) { return 0; } } }