diff --git a/MosswartMassacre/MosswartMassacre.csproj b/MosswartMassacre/MosswartMassacre.csproj index 792b73e..b2d0613 100644 --- a/MosswartMassacre/MosswartMassacre.csproj +++ b/MosswartMassacre/MosswartMassacre.csproj @@ -58,6 +58,12 @@ False lib\Decal.Interop.Inject.dll + + False + False + ..\..\..\..\..\..\Program Files (x86)\Decal 3.0\.NET 4.0 PIA\Decal.Interop.D3DService.DLL + False + ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll @@ -151,6 +157,8 @@ + + @@ -160,7 +168,6 @@ - @@ -169,6 +176,8 @@ Resources.resx + + @@ -183,6 +192,7 @@ + diff --git a/MosswartMassacre/PluginCore.cs b/MosswartMassacre/PluginCore.cs index 074ccb5..aa05bbb 100644 --- a/MosswartMassacre/PluginCore.cs +++ b/MosswartMassacre/PluginCore.cs @@ -12,6 +12,7 @@ using System.Threading.Tasks; using System.Timers; using Decal.Adapter; using Decal.Adapter.Wrappers; +using MosswartMassacre.Views; namespace MosswartMassacre { @@ -34,6 +35,7 @@ namespace MosswartMassacre public bool WebSocketEnabled { get; set; } = false; public bool InventoryLogEnabled { get; set; } = false; private MossyInventory _inventoryLogger; + public static NavVisualization navVisualization; private static Queue rareMessageQueue = new Queue(); private static DateTime _lastSent = DateTime.MinValue; @@ -60,8 +62,8 @@ namespace MosswartMassacre updateTimer.Elapsed += UpdateStats; updateTimer.Start(); - // Initialize the view (UI) - MainView.ViewInit(); + // Initialize the view (UI) - use tabbed interface by default + TabbedMainView.ViewInit(); // Enable TLS1.2 ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12; @@ -73,6 +75,9 @@ namespace MosswartMassacre _inventoryLogger = new MossyInventory(); + // Initialize navigation visualization system + navVisualization = new NavVisualization(); + } @@ -108,7 +113,7 @@ namespace MosswartMassacre } // Clean up the view - MainView.ViewDestroy(); + TabbedMainView.ViewDestroy(); //Disable vtank interface vTank.Disable(); // sluta lyssna på commands @@ -117,6 +122,13 @@ namespace MosswartMassacre //shutdown inv _inventoryLogger.Dispose(); + // Clean up navigation visualization + if (navVisualization != null) + { + navVisualization.Dispose(); + navVisualization = null; + } + MyHost = null; } catch (Exception ex) @@ -137,7 +149,8 @@ namespace MosswartMassacre HttpServerEnabled = PluginSettings.Instance.HttpServerEnabled; TelemetryEnabled = PluginSettings.Instance.TelemetryEnabled; CharTag = PluginSettings.Instance.CharTag; - MainView.SetRareMetaToggleState(RareMetaEnabled); + TabbedMainView.SetRareMetaToggleState(RareMetaEnabled); + TabbedMainView.RefreshSettingsFromConfig(); // Refresh all UI settings after loading if (TelemetryEnabled) Telemetry.Start(); if (WebSocketEnabled) @@ -225,13 +238,13 @@ namespace MosswartMassacre totalKills++; lastKillTime = DateTime.Now; CalculateKillsPerInterval(); - MainView.UpdateKillStats(totalKills, killsPer5Min, killsPerHour); + TabbedMainView.UpdateKillStats(totalKills, killsPer5Min, killsPerHour); } if (IsRareDiscoveryMessage(e.Text, out string rareText)) { rareCount++; - MainView.UpdateRareCount(rareCount); + TabbedMainView.UpdateRareCount(rareCount); if (RareMetaEnabled) { @@ -311,11 +324,11 @@ namespace MosswartMassacre { // Update the elapsed time TimeSpan elapsed = DateTime.Now - statsStartTime; - MainView.UpdateElapsedTime(elapsed); + TabbedMainView.UpdateElapsedTime(elapsed); // Recalculate kill rates CalculateKillsPerInterval(); - MainView.UpdateKillStats(totalKills, killsPer5Min, killsPerHour); + TabbedMainView.UpdateKillStats(totalKills, killsPer5Min, killsPerHour); } catch (Exception ex) { @@ -413,14 +426,14 @@ namespace MosswartMassacre killsPerHour = 0; WriteToChat("Stats have been reset."); - MainView.UpdateKillStats(totalKills, killsPer5Min, killsPerHour); - MainView.UpdateRareCount(rareCount); + TabbedMainView.UpdateKillStats(totalKills, killsPer5Min, killsPerHour); + TabbedMainView.UpdateRareCount(rareCount); } public static void ToggleRareMeta() { PluginSettings.Instance.RareMetaEnabled = !PluginSettings.Instance.RareMetaEnabled; RareMetaEnabled = PluginSettings.Instance.RareMetaEnabled; - MainView.SetRareMetaToggleState(RareMetaEnabled); + TabbedMainView.SetRareMetaToggleState(RareMetaEnabled); } [DllImport("Decal.dll")] @@ -550,7 +563,7 @@ namespace MosswartMassacre case "meta": RareMetaEnabled = !RareMetaEnabled; WriteToChat($"Rare meta state is now {(RareMetaEnabled ? "ON" : "OFF")}"); - MainView.SetRareMetaToggleState(RareMetaEnabled); // <-- sync the UI + TabbedMainView.SetRareMetaToggleState(RareMetaEnabled); // <-- sync the UI break; case "http": diff --git a/MosswartMassacre/PluginSettings.cs b/MosswartMassacre/PluginSettings.cs index 0a7a9e5..e68f71e 100644 --- a/MosswartMassacre/PluginSettings.cs +++ b/MosswartMassacre/PluginSettings.cs @@ -20,6 +20,10 @@ namespace MosswartMassacre private bool _webSocketEnabled = false; private bool _inventorylog = true; private string _charTag = "default"; + private int _mainWindowX = 100; + private int _mainWindowY = 100; + private bool _useTabbedInterface = true; + private string _vtankProfilesPath = ""; public static PluginSettings Instance => _instance ?? throw new InvalidOperationException("PluginSettings not initialized"); @@ -151,5 +155,29 @@ namespace MosswartMassacre get => _inventorylog; set { _inventorylog = value; Save(); } } + + public int MainWindowX + { + get => _mainWindowX; + set { _mainWindowX = value; Save(); } + } + + public int MainWindowY + { + get => _mainWindowY; + set { _mainWindowY = value; Save(); } + } + + public bool UseTabbedInterface + { + get => _useTabbedInterface; + set { _useTabbedInterface = value; Save(); } + } + + public string VTankProfilesPath + { + get => _vtankProfilesPath; + set { _vtankProfilesPath = value; Save(); } + } } } diff --git a/README.md b/README.md index 16858c3..1b74fc4 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,13 @@ A collection of DECAL plugins for Asheron's Call, providing utility overlays and - On button click, it logs a chat message; extend the `btnCycle.Hit` handler to add gear-cycling logic. ## MosswartMassacre - Tracks monster kills and rare drops, with multiple utility features. + Tracks monster kills and rare drops, with multiple utility features including navigation route visualization. ### Features - **Kill Tracking**: Counts total kills and computes rates (kills/5 min, kills/hour). - **Rare Discoveries**: Increments rare count and can automatically set rare meta state. - - **UI Overlay**: Displays stats and provides buttons to reset stats or toggle rare meta. + - **Navigation Visualization** ✅ **NEW**: Visualize VTank navigation routes in 3D with route comparison capabilities. + - **Tabbed UI Interface**: Enhanced interface with Main, Settings, Statistics, and Navigation tabs. - **Command Interface** (`/mm` commands): - `/mm help` : Show available commands. - `/mm report` : Display current stats in chat. @@ -49,6 +50,13 @@ A collection of DECAL plugins for Asheron's Call, providing utility overlays and - Listens on `http://localhost:8085/`. - Accepts POST data: `target=&command=`, then sends a /tell and executes the command. + ### Navigation Visualization ✅ NEW + - **VTank Integration**: Automatically detects VTank installation and loads .nav files. + - **3D Route Display**: Shows navigation routes as red lines in the game world. + - **Route Comparison**: Visualize different routes alongside UtilityBelt's active navigation. + - **Supported Formats**: All VTank nav types (Circular, Linear, Target, Once) and waypoint types. + - **Usage**: Enable in Navigation tab, select route from dropdown, click "Load Route". + ### Configuration - Per-character YAML config stored at `/.yaml`. - Settings include: @@ -57,6 +65,7 @@ A collection of DECAL plugins for Asheron's Call, providing utility overlays and - `http_server_enabled` - `telemetry_enabled` - `char_tag` + - `vtank_profiles_path` ✅ **NEW**: Custom VTank profiles directory - Config is auto-generated on first run; modify it or use UI/commands to update. ### Telemetry @@ -66,6 +75,7 @@ A collection of DECAL plugins for Asheron's Call, providing utility overlays and ## Dependencies - Decal.Adapter (v2.9.8.3) - Decal.Interop.Core & Decal.Interop.Inject + - Decal.Interop.D3DService ✅ **NEW**: For 3D navigation visualization - VirindiViewService - Newtonsoft.Json (v13.0.3) - YamlDotNet (v16.3.0)