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; + } + } } }