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)