diff --git a/MosswartMassacre/PluginCore.cs b/MosswartMassacre/PluginCore.cs
index cacdeeb..c73f492 100644
--- a/MosswartMassacre/PluginCore.cs
+++ b/MosswartMassacre/PluginCore.cs
@@ -577,6 +577,7 @@ namespace MosswartMassacre
WriteToChat("/mm http - Local http-command server enable|disable");
WriteToChat("/mm remotecommand - Listen to allegiance !do/!dot enable|disable");
WriteToChat("/mm getmetastate - Gets the current metastate");
+ WriteToChat("/mm nextwp - Advance VTank to next waypoint");
break;
case "debug":
DispatchChatToBoxWithPluginIntercept("/ub give bajs to Town Crier");
@@ -657,6 +658,35 @@ namespace MosswartMassacre
}
break;
+ case "nextwp":
+ double result = VtankControl.VtAdvanceWaypoint();
+ if (result == 1)
+ {
+ WriteToChat("Advanced VTank to next waypoint.");
+ }
+ else
+ {
+ WriteToChat("Failed to advance VTank waypoint. Is VTank running?");
+ }
+ break;
+
+ case "vtanktest":
+ try
+ {
+ WriteToChat("Testing VTank interface...");
+ WriteToChat($"VTank Instance: {(vTank.Instance != null ? "Found" : "NULL")}");
+ WriteToChat($"VTank Type: {vTank.Instance?.GetType()?.Name ?? "NULL"}");
+ WriteToChat($"NavCurrent: {vTank.Instance?.NavCurrent ?? -1}");
+ WriteToChat($"NavNumPoints: {vTank.Instance?.NavNumPoints ?? -1}");
+ WriteToChat($"NavType: {vTank.Instance?.NavType}");
+ WriteToChat($"MacroEnabled: {vTank.Instance?.MacroEnabled}");
+ }
+ catch (Exception ex)
+ {
+ WriteToChat($"VTank test error: {ex.Message}");
+ }
+ break;
+
default:
WriteToChat($"Unknown /mm command: {subCommand}. Try /mm help");
break;
diff --git a/MosswartMassacre/VtankControl.cs b/MosswartMassacre/VtankControl.cs
index 686dcbb..7b5e4d6 100644
--- a/MosswartMassacre/VtankControl.cs
+++ b/MosswartMassacre/VtankControl.cs
@@ -104,5 +104,125 @@ namespace MosswartMassacre
{
return vTank.Instance.MacroEnabled;
}
+
+ ///
+ /// Advances VTank to the next waypoint in the current navigation route.
+ ///
+ ///
+ /// 1 if the waypoint was advanced successfully; 0 on failure.
+ ///
+ public static double VtAdvanceWaypoint()
+ {
+ try
+ {
+ var externalInterface = vTank.Instance;
+
+ // Basic validation
+ if (externalInterface.NavNumPoints == 0)
+ {
+ return 0; // No waypoints
+ }
+
+ int currentWaypoint = externalInterface.NavCurrent;
+ int totalWaypoints = externalInterface.NavNumPoints;
+
+ // Check if we can advance
+ if (currentWaypoint >= totalWaypoints - 1)
+ {
+ return 0; // Already at last waypoint
+ }
+
+ // Check navigation type
+ var navType = (int)externalInterface.NavType;
+ if (navType == 2 || navType == 4) // Target or Once
+ {
+ return 0;
+ }
+
+ // Access the cExternalInterfaceTrustedRelay and get the PC (PluginCore) reference
+ // From decompiled code: external interface uses PC.NavCurrent which references dz.o.l
+ var interfaceType = externalInterface.GetType();
+
+ // Look for any way to get to the PluginCore instance
+ // The interface should have access to PC or some way to reach it
+
+ // Try to get the underlying assembly and find the PC static field
+ var assembly = interfaceType.Assembly;
+ var pluginCoreType = assembly.GetType("uTank2.PluginCore");
+
+ if (pluginCoreType != null)
+ {
+ // Get the static PC field
+ var pcField = pluginCoreType.GetField("PC", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
+
+ if (pcField != null)
+ {
+ var pluginCoreInstance = pcField.GetValue(null);
+
+ if (pluginCoreInstance != null)
+ {
+ // Try to call the advance method 'i' on the PluginCore instance
+ // Need to specify parameter types to avoid "Ambiguous match found"
+ Type[] parameterTypes = new Type[] { typeof(object), assembly.GetType("MetaViewWrappers.MVControlEventArgs") };
+ var advanceMethod = pluginCoreType.GetMethod("i",
+ System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
+ null, parameterTypes, null);
+
+ if (advanceMethod != null)
+ {
+ // Call with parameters matching: i(object A_0, MVControlEventArgs A_1)
+ advanceMethod.Invoke(pluginCoreInstance, new object[] { null, null });
+ return 1;
+ }
+ }
+ }
+
+ // Fallback: try to access dz static field directly
+ var dzField = pluginCoreType.GetField("dz", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
+
+ if (dzField != null)
+ {
+ var dzObject = dzField.GetValue(null);
+
+ if (dzObject != null)
+ {
+ // Navigate the dz.o.l path
+ var dzType = dzObject.GetType();
+ var oField = dzType.GetField("o", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
+
+ if (oField != null)
+ {
+ var oObject = oField.GetValue(dzObject);
+ if (oObject != null)
+ {
+ var oType = oObject.GetType();
+ var lField = oType.GetField("l", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
+
+ if (lField != null)
+ {
+ // Get current value and increment it
+ int current = (int)lField.GetValue(oObject);
+ current++;
+ if (current >= totalWaypoints)
+ {
+ current = totalWaypoints - 1;
+ }
+ lField.SetValue(oObject, current);
+ return 1;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+ }
+ catch (System.Exception ex)
+ {
+ PluginCore.WriteToChat("VTank advance error: " + ex.Message);
+ return 0;
+ }
+ }
}
}