Skip to content

Commit

Permalink
Added persistent config.
Browse files Browse the repository at this point in the history
  • Loading branch information
awgil committed May 5, 2024
1 parent 37d03a2 commit d7e1ef9
Show file tree
Hide file tree
Showing 12 changed files with 264 additions and 160 deletions.
88 changes: 88 additions & 0 deletions vnavmesh/Config.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using ImGuiNET;
using Newtonsoft.Json.Linq;
using System;
using System.IO;

namespace Navmesh;

public class Config
{
private const int _version = 1;

public bool AutoLoadNavmesh = true;
public bool EnableDTR = true;
public bool AlignCameraToMovement;
public bool ShowWaypoints;
public bool ForceShowGameCollision;

public event Action? Modified;

public void NotifyModified() => Modified?.Invoke();

public void Draw()
{
if (ImGui.Checkbox("Automatically load/build navigation data when changing zones", ref AutoLoadNavmesh))
NotifyModified();
if (ImGui.Checkbox("Enable DTR bar", ref EnableDTR))
NotifyModified();
if (ImGui.Checkbox("Align camera to movement direction", ref AlignCameraToMovement))
NotifyModified();
if (ImGui.Checkbox("Show active waypoints", ref ShowWaypoints))
NotifyModified();
if (ImGui.Checkbox("Always visualize game collision", ref ForceShowGameCollision))
NotifyModified();
}

public void Save(FileInfo file)
{
try
{
JObject jContents = new()
{
{ "Version", _version },
{ "Payload", JObject.FromObject(this) }
};
File.WriteAllText(file.FullName, jContents.ToString());
}
catch (Exception e)
{
Service.Log.Error($"Failed to save config to {file.FullName}: {e}");
}
}

public void Load(FileInfo file)
{
try
{
var contents = File.ReadAllText(file.FullName);
var json = JObject.Parse(contents);
var version = (int?)json["Version"] ?? 0;
if (json["Payload"] is JObject payload)
{
payload = ConvertConfig(payload, version);
var thisType = GetType();
foreach (var (f, data) in payload)
{
var thisField = thisType.GetField(f);
if (thisField != null)
{
var value = data?.ToObject(thisField.FieldType);
if (value != null)
{
thisField.SetValue(this, value);
}
}
}
}
}
catch (Exception e)
{
Service.Log.Error($"Failed to load config from {file.FullName}: {e}");
}
}

private static JObject ConvertConfig(JObject payload, int version)
{
return payload;
}
}
4 changes: 1 addition & 3 deletions vnavmesh/DTRProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ namespace Navmesh;

public class DTRProvider : IDisposable
{
public bool ShowDtrBar = true;

private NavmeshManager _manager;
private DtrBarEntry _dtrBarEntry;

Expand All @@ -23,7 +21,7 @@ public void Dispose()

public void Update()
{
_dtrBarEntry.Shown = ShowDtrBar;
_dtrBarEntry.Shown = Service.Config.EnableDTR;
if (_dtrBarEntry.Shown)
{
var loadProgress = _manager.LoadTaskProgress;
Expand Down
1 change: 0 additions & 1 deletion vnavmesh/Debug/DebugExtractedCollision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public void Draw()
{
DrawDefinition();
DrawExtractor();
_coll.DrawVisualizers();
}

private unsafe void DrawDefinition()
Expand Down
6 changes: 1 addition & 5 deletions vnavmesh/Debug/DebugGameCollision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ namespace Navmesh.Debug;

public unsafe class DebugGameCollision : IDisposable
{
public bool ForceShowVisualization;

private UITree _tree = new();
private DebugDrawer _dd;
private BitMask _shownLayers = new(1);
Expand Down Expand Up @@ -86,8 +84,6 @@ public void Draw()
DrawSceneRaycasts(s, i);
++i;
}

DrawVisualizers();
}

public void DrawVisualizers()
Expand Down Expand Up @@ -216,7 +212,7 @@ private void DrawSettings()
private void DrawSceneColliders(Scene* s, int index)
{
using var n = _tree.Node($"Scene {index}: {s->NumColliders} colliders, {s->NumLoading} loading, streaming={SphereStr(s->StreamingSphere)}###scene_{index}");
if (n.SelectedOrHovered || ForceShowVisualization)
if (n.SelectedOrHovered || Service.Config.ForceShowGameCollision)
foreach (var coll in s->Colliders)
if (FilterCollider(coll))
VisualizeCollider(coll, _materialId, _materialMask);
Expand Down
1 change: 0 additions & 1 deletion vnavmesh/Debug/DebugLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public void Draw()
if (terr != null)
DrawFile($"Territory {Service.ClientState.TerritoryType}", $"bg/{terr.Bg}.lvb");
DrawComparison(LayoutWorld.Instance()->ActiveLayout);
_coll.DrawVisualizers();
_insts.Clear();
}

Expand Down
17 changes: 0 additions & 17 deletions vnavmesh/Debug/DebugNavmeshManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,7 @@ public void Draw()
ImGui.SameLine();
ImGui.TextUnformatted($"Current target: {_target}");

ImGui.Checkbox("Show mesh status in DTR Bar", ref _dtr.ShowDtrBar);
ImGui.Checkbox("Allow movement", ref _path.MovementAllowed);
ImGui.Checkbox("Align camera to movement direction", ref _path.AlignCamera);
ImGui.Checkbox("Auto load mesh when changing zone", ref _manager.AutoLoad);
ImGui.Checkbox("Use raycasts", ref _manager.UseRaycasts);
ImGui.Checkbox("Use string pulling", ref _manager.UseStringPulling);
if (ImGui.Button("Pathfind to target using navmesh"))
Expand All @@ -87,20 +84,6 @@ public void Draw()
if (ImGui.Button("Pathfind to target using volume"))
_asyncMove.MoveTo(_target, true);

// draw current path
if (player != null)
{
var from = playerPos;
var color = 0xff00ff00;
foreach (var to in _path.Waypoints)
{
_dd.DrawWorldLine(from, to, color);
_dd.DrawWorldPointFilled(to, 3, 0xff0000ff);
from = to;
color = 0xff00ffff;
}
}

DrawPosition("Player", playerPos);
DrawPosition("Target", _target);
DrawPosition("Flag", MapUtils.FlagToPoint(_manager.Query) ?? default);
Expand Down
207 changes: 103 additions & 104 deletions vnavmesh/IPCProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,111 +4,110 @@
using System.Numerics;
using System.Threading;

namespace Navmesh
namespace Navmesh;

class IPCProvider : IDisposable
{
class IPCProvider : IDisposable
private List<Action> _disposeActions = new();

public IPCProvider(NavmeshManager navmeshManager, FollowPath followPath, AsyncMoveRequest move, MainWindow mainWindow, DTRProvider dtr)
{
RegisterFunc("Nav.IsReady", () => navmeshManager.Navmesh != null);
RegisterFunc("Nav.BuildProgress", () => navmeshManager.LoadTaskProgress);
RegisterFunc("Nav.Reload", () => navmeshManager.Reload(true));
RegisterFunc("Nav.Rebuild", () => navmeshManager.Reload(false));
RegisterFunc("Nav.Pathfind", (Vector3 from, Vector3 to, bool fly) => navmeshManager.QueryPath(from, to, fly));
RegisterFunc("Nav.PathfindCancelable", (Vector3 from, Vector3 to, bool fly, CancellationToken cancel) => navmeshManager.QueryPath(from, to, fly, cancel));
RegisterAction("Nav.PathfindCancelAll", navmeshManager.CancelAllQueries);
RegisterFunc("Nav.PathfindInProgress", () => navmeshManager.PathfindInProgress);
RegisterFunc("Nav.PathfindNumQueued", () => navmeshManager.NumQueuedPathfindRequests);
RegisterFunc("Nav.IsAutoLoad", () => Service.Config.AutoLoadNavmesh);
RegisterAction("Nav.SetAutoLoad", (bool v) => { Service.Config.AutoLoadNavmesh = v; Service.Config.NotifyModified(); });

RegisterFunc("Query.Mesh.NearestPoint", (Vector3 p, float halfExtentXZ, float halfExtentY) => navmeshManager.Query?.FindNearestPointOnMesh(p, halfExtentXZ, halfExtentY));
RegisterFunc("Query.Mesh.PointOnFloor", (Vector3 p, bool allowUnlandable, float halfExtentXZ) => navmeshManager.Query?.FindPointOnFloor(p, halfExtentXZ));

RegisterAction("Path.MoveTo", (List<Vector3> waypoints, bool fly) => followPath.Move(waypoints, !fly));
RegisterAction("Path.Stop", followPath.Stop);
RegisterFunc("Path.IsRunning", () => followPath.Waypoints.Count > 0);
RegisterFunc("Path.NumWaypoints", () => followPath.Waypoints.Count);
RegisterFunc("Path.ListWaypoints", () => followPath.Waypoints);
RegisterFunc("Path.GetMovementAllowed", () => followPath.MovementAllowed);
RegisterAction("Path.SetMovementAllowed", (bool v) => followPath.MovementAllowed = v);
RegisterFunc("Path.GetAlignCamera", () => Service.Config.AlignCameraToMovement);
RegisterAction("Path.SetAlignCamera", (bool v) => { Service.Config.AlignCameraToMovement = v; Service.Config.NotifyModified(); });
RegisterFunc("Path.GetTolerance", () => followPath.Tolerance);
RegisterAction("Path.SetTolerance", (float v) => followPath.Tolerance = v);

RegisterFunc("SimpleMove.PathfindAndMoveTo", (Vector3 dest, bool fly) => move.MoveTo(dest, fly));
RegisterFunc("SimpleMove.PathfindInProgress", () => move.TaskInProgress);

RegisterFunc("Window.IsOpen", () => mainWindow.IsOpen);
RegisterAction("Window.SetOpen", (bool v) => mainWindow.IsOpen = v);

RegisterFunc("DTR.IsShown", () => Service.Config.EnableDTR);
RegisterAction("DTR.SetShown", (bool v) => { Service.Config.EnableDTR = v; Service.Config.NotifyModified(); });
}

public void Dispose()
{
foreach (var a in _disposeActions)
a();
}

private void RegisterFunc<TRet>(string name, Func<TRet> func)
{
var p = Service.PluginInterface.GetIpcProvider<TRet>("vnavmesh." + name);
p.RegisterFunc(func);
_disposeActions.Add(p.UnregisterFunc);
}

private void RegisterFunc<TRet, T1>(string name, Func<T1, TRet> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, TRet>("vnavmesh." + name);
p.RegisterFunc(func);
_disposeActions.Add(p.UnregisterFunc);
}

private void RegisterFunc<TRet, T1, T2>(string name, Func<T1, T2, TRet> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, T2, TRet>("vnavmesh." + name);
p.RegisterFunc(func);
_disposeActions.Add(p.UnregisterFunc);
}

private void RegisterFunc<TRet, T1, T2, T3>(string name, Func<T1, T2, T3, TRet> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, T2, T3, TRet>("vnavmesh." + name);
p.RegisterFunc(func);
_disposeActions.Add(p.UnregisterFunc);
}

private void RegisterFunc<TRet, T1, T2, T3, T4>(string name, Func<T1, T2, T3, T4, TRet> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, T2, T3, T4, TRet>("vnavmesh." + name);
p.RegisterFunc(func);
_disposeActions.Add(p.UnregisterFunc);
}

private void RegisterAction(string name, Action func)
{
var p = Service.PluginInterface.GetIpcProvider<object>("vnavmesh." + name);
p.RegisterAction(func);
_disposeActions.Add(p.UnregisterAction);
}

private void RegisterAction<T1>(string name, Action<T1> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, object>("vnavmesh." + name);
p.RegisterAction(func);
_disposeActions.Add(p.UnregisterAction);
}

private void RegisterAction<T1, T2>(string name, Action<T1, T2> func)
{
private List<Action> _disposeActions = new();

public IPCProvider(NavmeshManager navmeshManager, FollowPath followPath, AsyncMoveRequest move, MainWindow mainWindow, DTRProvider dtr)
{
RegisterFunc("Nav.IsReady", () => navmeshManager.Navmesh != null);
RegisterFunc("Nav.BuildProgress", () => navmeshManager.LoadTaskProgress);
RegisterFunc("Nav.Reload", () => navmeshManager.Reload(true));
RegisterFunc("Nav.Rebuild", () => navmeshManager.Reload(false));
RegisterFunc("Nav.Pathfind", (Vector3 from, Vector3 to, bool fly) => navmeshManager.QueryPath(from, to, fly));
RegisterFunc("Nav.PathfindCancelable", (Vector3 from, Vector3 to, bool fly, CancellationToken cancel) => navmeshManager.QueryPath(from, to, fly, cancel));
RegisterAction("Nav.PathfindCancelAll", navmeshManager.CancelAllQueries);
RegisterFunc("Nav.PathfindInProgress", () => navmeshManager.PathfindInProgress);
RegisterFunc("Nav.PathfindNumQueued", () => navmeshManager.NumQueuedPathfindRequests);
RegisterFunc("Nav.IsAutoLoad", () => navmeshManager.AutoLoad);
RegisterAction("Nav.SetAutoLoad", (bool v) => navmeshManager.AutoLoad = v);

RegisterFunc("Query.Mesh.NearestPoint", (Vector3 p, float halfExtentXZ, float halfExtentY) => navmeshManager.Query?.FindNearestPointOnMesh(p, halfExtentXZ, halfExtentY));
RegisterFunc("Query.Mesh.PointOnFloor", (Vector3 p, bool allowUnlandable, float halfExtentXZ) => navmeshManager.Query?.FindPointOnFloor(p, halfExtentXZ));

RegisterAction("Path.MoveTo", (List<Vector3> waypoints, bool fly) => followPath.Move(waypoints, !fly));
RegisterAction("Path.Stop", followPath.Stop);
RegisterFunc("Path.IsRunning", () => followPath.Waypoints.Count > 0);
RegisterFunc("Path.NumWaypoints", () => followPath.Waypoints.Count);
RegisterFunc("Path.ListWaypoints", () => followPath.Waypoints);
RegisterFunc("Path.GetMovementAllowed", () => followPath.MovementAllowed);
RegisterAction("Path.SetMovementAllowed", (bool v) => followPath.MovementAllowed = v);
RegisterFunc("Path.GetAlignCamera", () => followPath.AlignCamera);
RegisterAction("Path.SetAlignCamera", (bool v) => followPath.AlignCamera = v);
RegisterFunc("Path.GetTolerance", () => followPath.Tolerance);
RegisterAction("Path.SetTolerance", (float v) => followPath.Tolerance = v);

RegisterFunc("SimpleMove.PathfindAndMoveTo", (Vector3 dest, bool fly) => move.MoveTo(dest, fly));
RegisterFunc("SimpleMove.PathfindInProgress", () => move.TaskInProgress);

RegisterFunc("Window.IsOpen", () => mainWindow.IsOpen);
RegisterAction("Window.SetOpen", (bool v) => mainWindow.IsOpen = v);

RegisterFunc("DTR.IsShown", () => dtr.ShowDtrBar);
RegisterAction("DTR.SetShown", (bool v) => dtr.ShowDtrBar = v);
}

public void Dispose()
{
foreach (var a in _disposeActions)
a();
}

private void RegisterFunc<TRet>(string name, Func<TRet> func)
{
var p = Service.PluginInterface.GetIpcProvider<TRet>("vnavmesh." + name);
p.RegisterFunc(func);
_disposeActions.Add(p.UnregisterFunc);
}

private void RegisterFunc<TRet, T1>(string name, Func<T1, TRet> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, TRet>("vnavmesh." + name);
p.RegisterFunc(func);
_disposeActions.Add(p.UnregisterFunc);
}

private void RegisterFunc<TRet, T1, T2>(string name, Func<T1, T2, TRet> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, T2, TRet>("vnavmesh." + name);
p.RegisterFunc(func);
_disposeActions.Add(p.UnregisterFunc);
}

private void RegisterFunc<TRet, T1, T2, T3>(string name, Func<T1, T2, T3, TRet> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, T2, T3, TRet>("vnavmesh." + name);
p.RegisterFunc(func);
_disposeActions.Add(p.UnregisterFunc);
}

private void RegisterFunc<TRet, T1, T2, T3, T4>(string name, Func<T1, T2, T3, T4, TRet> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, T2, T3, T4, TRet>("vnavmesh." + name);
p.RegisterFunc(func);
_disposeActions.Add(p.UnregisterFunc);
}

private void RegisterAction(string name, Action func)
{
var p = Service.PluginInterface.GetIpcProvider<object>("vnavmesh." + name);
p.RegisterAction(func);
_disposeActions.Add(p.UnregisterAction);
}

private void RegisterAction<T1>(string name, Action<T1> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, object>("vnavmesh." + name);
p.RegisterAction(func);
_disposeActions.Add(p.UnregisterAction);
}

private void RegisterAction<T1, T2>(string name, Action<T1, T2> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, T2, object>("vnavmesh." + name);
p.RegisterAction(func);
_disposeActions.Add(p.UnregisterAction);
}
var p = Service.PluginInterface.GetIpcProvider<T1, T2, object>("vnavmesh." + name);
p.RegisterAction(func);
_disposeActions.Add(p.UnregisterAction);
}
}
Loading

0 comments on commit d7e1ef9

Please sign in to comment.