diff --git a/GearCycler/GearCore.cs b/GearCycler/GearCore.cs
new file mode 100644
index 0000000..09b380a
--- /dev/null
+++ b/GearCycler/GearCore.cs
@@ -0,0 +1,45 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using Decal.Adapter;
+using Decal.Adapter.Wrappers;
+using VirindiViewService;
+using VirindiViewService.Controls;
+
+namespace GearCycler
+{
+ [ComVisible(true)]
+ [Guid("9b6a07e1-ae78-47f4-b09c-174f6a27d7a3")] // Replace with your own unique GUID if needed
+ [FriendlyName("GearCycler")]
+ public class GearCore : PluginBase
+ {
+ public HudView view;
+ private HudButton btnCycle;
+
+ protected override void Startup()
+ {
+ try
+ {
+ string xml = File.ReadAllText("ViewXML\\mainview.xml");
+ view = HudView.ReadXmlLayout(xml);
+ view.Visible = true;
+
+ btnCycle = (HudButton)view.Controls["btnCycle"];
+ btnCycle.Hit += (s, e) =>
+ {
+ CoreManager.Current.Actions.AddChatText("[GearCycler] Button clicked!", 1);
+ };
+ }
+ catch (Exception ex)
+ {
+ CoreManager.Current.Actions.AddChatText($"[GearCycler] Failed to load UI: {ex.Message}", 1);
+ }
+ }
+
+ protected override void Shutdown()
+ {
+ btnCycle?.Dispose();
+ view?.Dispose();
+ }
+ }
+}
diff --git a/GearCycler/GearCycler.csproj b/GearCycler/GearCycler.csproj
new file mode 100644
index 0000000..b4344de
--- /dev/null
+++ b/GearCycler/GearCycler.csproj
@@ -0,0 +1,81 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {1293560E-2A56-417F-8116-8CE0420DC97C}
+ Library
+ Properties
+ GearCycler
+ GearCycler
+ v4.8
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ TRACE;DEBUG;VVS_REFERENCED;DECAL_INTEROP
+ prompt
+ 4
+ x86
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\MosswartMassacre\lib\Decal.Adapter.dll
+
+
+ False
+ True
+ ..\MosswartMassacre\lib\Decal.Interop.Core.DLL
+
+
+ False
+ True
+ ..\MosswartMassacre\lib\Decal.Interop.Inject.dll
+
+
+
+
+
+
+
+
+
+
+
+ ..\MosswartMassacre\lib\VirindiViewService.dll
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GearCycler/Properties/AssemblyInfo.cs b/GearCycler/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c45a3b8
--- /dev/null
+++ b/GearCycler/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GearCycler")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("GearCycler")]
+[assembly: AssemblyCopyright("Copyright © 2025")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f5462318-d26a-4ab0-8981-80edd9ec9c99")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/GearCycler/Properties/Resources.Designer.cs b/GearCycler/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..40b9adf
--- /dev/null
+++ b/GearCycler/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace GearCycler.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GearCycler.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/GearCycler/Properties/Resources.resx b/GearCycler/Properties/Resources.resx
new file mode 100644
index 0000000..4fdb1b6
--- /dev/null
+++ b/GearCycler/Properties/Resources.resx
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/GearCycler/ViewXML/mainView.xml b/GearCycler/ViewXML/mainView.xml
new file mode 100644
index 0000000..1300d02
--- /dev/null
+++ b/GearCycler/ViewXML/mainView.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/GearCycler/lib/Decal.Adapter.dll b/GearCycler/lib/Decal.Adapter.dll
new file mode 100644
index 0000000..c27e132
Binary files /dev/null and b/GearCycler/lib/Decal.Adapter.dll differ
diff --git a/GearCycler/lib/Decal.Interop.Core.DLL b/GearCycler/lib/Decal.Interop.Core.DLL
new file mode 100644
index 0000000..b8de808
Binary files /dev/null and b/GearCycler/lib/Decal.Interop.Core.DLL differ
diff --git a/GearCycler/lib/Decal.Interop.Inject.dll b/GearCycler/lib/Decal.Interop.Inject.dll
new file mode 100644
index 0000000..f186c93
Binary files /dev/null and b/GearCycler/lib/Decal.Interop.Inject.dll differ
diff --git a/GearCycler/lib/VirindiViewService.dll b/GearCycler/lib/VirindiViewService.dll
new file mode 100644
index 0000000..1e3f4fc
Binary files /dev/null and b/GearCycler/lib/VirindiViewService.dll differ
diff --git a/GearCycler/lib/VirindiViewService.xml b/GearCycler/lib/VirindiViewService.xml
new file mode 100644
index 0000000..c43230e
--- /dev/null
+++ b/GearCycler/lib/VirindiViewService.xml
@@ -0,0 +1,386 @@
+
+
+
+ VirindiViewService
+
+
+
+
+ Implies Top and Left
+
+
+
+
+ Provides theme elements, which can be drawn by controls.
+
+
+
+
+ Displays an element from the current theme.
+
+
+
+
+ The base class for all Virindi Views controls.
+
+
+
+
+ Called after this control is added to a ControlGroup. This is when the Name and details have been set.
+
+
+
+
+ Add and initialize a child control of this control. The child may be removed by disposing it.
+
+
+
+
+
+ Called when a child of this control is disposed.
+
+
+
+
+
+ Recursively disposes all children and removes this control from the view, if it is initialized.
+
+
+
+
+ Handles a mouse wheel event. Parent controls must pass this on to applicable children if necessary.
+
+
+
+
+
+
+ Fires the MouseEvent event for mouse down, and sets this control as the focus control if CanTakeFocus is true.
+
+ Parent controls must pass this on to applicable children if necessary.
+
+
+
+
+
+ Fires the MouseEvent event for mouse up as well as the Hit event.
+
+ Parent controls must pass this on to applicable children if necessary.
+
+
+
+
+
+
+ Fired when the mousedown originated outside the current view. The base version of this method
+ passes on the event to all children if the 'up' point is within its saved rect.
+
+ Mouseup point
+
+
+
+ Tracks mouseover and fires the MouseOverChange event, as well as the MouseEvent event for mouse move.
+
+ Parent controls must pass this on to applicable children if necessary.
+
+
+
+
+
+ Parses a key message and fires the specific key event methods.
+
+ Key events are only sent to the control with focus.
+
+
+
+
+
+
+
+
+ WARNING: ONLY A PARENT CONTROL SHOULD CALL THIS METHOD.
+
+ This method is overridden in derived controls to handle the actual control drawing. Overridden methods should call
+ the base, draw, and recursively call this method on all child controls.
+
+
+
+
+
+ WARNING: ONLY A PARENT CONTROL SHOULD CALL THIS METHOD.
+
+ Notifies a control of changed saved draw options. This method saves its parameters in the Savedxxx properties.
+ Parent controls should override this method and recursively notify children of their new draw options, altering
+ their pClipRegion to reflect their new position in the View.
+
+ This base method also fires the DrawStateChange and ThemeChanged events.
+
+ This control's area, relative to the view area.
+ The theme applied to this control.
+ The context of this control, eg. inside a listbox.
+ The position of the View, in game window coordinates.
+
+
+
+ WARNING: ONLY A PARENT CONTROL SHOULD SET THIS PROPERTY.
+
+
+
+
+ List of XmlAttributes present on the XmlNode that was used to construct this control, if the control was loaded from XML. Otherwise, empty.
+
+
+
+
+ The XmlNode used to construct this control, if the control was loaded from XML. Otherwise, null.
+
+
+
+
+ The name that this control will be initialized with.
+
+
+
+
+ A multiline uneditable scrolling text box.
+
+
+
+
+ A single image control.
+
+
+
+
+ A button using custom images.
+
+
+
+
+ A doubly-linked list with a Dictionary index. Duplicate items are not allowed.
+ -Add is O(1)
+ -Contains is O(1)
+ -Remove is O(1)
+ -Get/set by index is O(n)
+ -Insert is O(n)
+ -RemoveAt is O(n)
+ Additionally, a cached pointer (with associated index) is kept pointing to the last used index item.
+ When looking up an item by index, the list is walked from the head, tail, or cached index pointer.
+ Thus, doing multiple operations in index order is O(1) even without an enumerator.
+
+
+
+
+
+ This method gets the node corresponding to a particular index. To get there,
+ the list is traversed from the head, tail, or cached index pointer (if valid).
+
+
+
+
+
+
+ Web browser control, using Awesomium (free license version)
+
+
+
+
+ A horizontal scrollbar.
+
+
+
+
+ Summary description for ByteCursor.
+
+
+
+
+ A checkbox with optional associated text. Uses its parent to provide the background.
+
+
+
+
+ A single-line text input box.
+
+
+
+
+ Called before render so the required size of the new target area can be calculated.
+ The returned value is the size of the desired draw area, not including outer borders and
+ style-dependent padding. This size must be less than or equal to MaximumSize in each dimension.
+
+
+
+
+
+
+ Draw this element. When this is called, the background and borders will already have been drawn, and
+ target will already be in BeginRender. This method should leave the target in render mode.
+
+
+
+
+
+
+
+ A renderer for string-only tooltips.
+
+
+
+
+ Represents an unordered set of items. Duplicates are not allowed.
+ (This is really just a dictionary which only holds keys.)
+ Should be used when a collection of non-duplicate items is needed and
+ the order doesn't matter.
+
+
+
+
+ A series of titled tabs along the top, each one having an associated control which appears
+ on the bottom when its tab is enabled.
+
+
+
+
+ A progressbar.
+
+
+
+
+ A regular pushbutton-style control.
+
+
+
+
+ Calls the non-hooked IDirect3DDevice9::BeginScene function. When rendering inside a VVS view or texture, use DxTexture.BeginRender() instead.
+
+
+
+
+
+ Calls the non-hooked IDirect3DDevice9::EndScene function. When rendering inside a VVS view or texture, use DxTexture.EndRender() instead.
+
+
+
+
+
+ Gets the current instance of the VVS bar.
+
+
+
+
+ A console containing game chat.
+
+
+
+
+ Initializes Direct3D drawing and sets the rendertarget to this texture. Calls to this method should be minimized to improve performance. DxTexture.EndRender() must be called after calling this method.
+
+
+
+
+
+
+
+
+
+ Ends Direct3D rendering and resets the rendertarget. Must be called after DxTexture.BeginRender().
+
+
+
+
+ Note: Before use, FlushSprite() may need to be called to ensure correct ordering.
+
+
+
+
+
+
+
+
+ Note: Before use, you must call BeginUserDrawOperation().
+
+
+
+
+
+
+
+
+ Note: Before use, you must call BeginUserDrawOperation().
+
+
+
+
+
+
+
+
+
+ A vertically scrolling list, containing a number of rows and columns. Every row
+ has the same number and types of columns. Each column contains a specified control type.
+
+
+
+
+ A number of images on top of each other, which always draw in the proper order.
+
+
+
+
+ A simple text display control. Uses its parent to provide the background.
+
+
+
+
+ A container for multiple controls with set locations and sizes within.
+
+
+
+
+ A dropdown list.
+
+
+
+
+ If the context menu is not visible, it is created at the specified point.
+
+
+
+
+ If the context menu is not visible, it is created at the specified point with the specified theme.
+
+
+
+
+ Provides information about an associated tooltip.
+
+
+
+
+ The HudControl that the tip is attached to.
+
+
+
+
+ Deprecated.
+ Returns the text associated with a tooltip only if the tip contains a cStringRenderer.
+
+
+
+
+ A vertical scrollbar.
+
+
+
+
+ A horizontal slider.
+
+
+
+
+ A control that allows easy access to underlying draw methods.
+
+
+
+
diff --git a/GearCycler/mainView.xml b/GearCycler/mainView.xml
new file mode 100644
index 0000000..d68a2a3
--- /dev/null
+++ b/GearCycler/mainView.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/MosswartMassacre/DelayedCommandManager.cs b/MosswartMassacre/DelayedCommandManager.cs
new file mode 100644
index 0000000..4976e4b
--- /dev/null
+++ b/MosswartMassacre/DelayedCommandManager.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using Decal.Adapter;
+
+namespace MosswartMassacre
+{
+ public static class DelayedCommandManager
+ {
+ static List delayedCommands = new List();
+ static bool isDelayListening = false;
+
+ public static void AddDelayedCommand(string command, double delay)
+ {
+ var delayed = new DelayedCommand(command, delay);
+ delayedCommands.Add(delayed);
+ delayedCommands.Sort((x, y) => x.RunAt.CompareTo(y.RunAt));
+
+ if (!isDelayListening)
+ {
+ isDelayListening = true;
+ CoreManager.Current.RenderFrame += Core_RenderFrame_Delay;
+ }
+ }
+
+ private static void Core_RenderFrame_Delay(object sender, EventArgs e)
+ {
+ try
+ {
+ while (delayedCommands.Count > 0 && delayedCommands[0].RunAt <= DateTime.UtcNow)
+ {
+ PluginCore.WriteToChat($"[Debug] Executing delayed: {delayedCommands[0].Command}");
+ CoreManager.Current.Actions.InvokeChatParser(delayedCommands[0].Command);
+ delayedCommands.RemoveAt(0);
+ }
+
+ if (delayedCommands.Count == 0)
+ {
+ CoreManager.Current.RenderFrame -= Core_RenderFrame_Delay;
+ isDelayListening = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ PluginCore.WriteToChat("Error in delayed command system: " + ex.Message);
+ }
+ }
+ }
+
+ public class DelayedCommand
+ {
+ public string Command { get; set; }
+ public double Delay { get; set; }
+ public DateTime RunAt { get; set; }
+
+ public DelayedCommand(string command, double delay)
+ {
+ Command = command;
+ Delay = delay;
+ RunAt = DateTime.UtcNow.AddMilliseconds(delay);
+ }
+ }
+}
diff --git a/MosswartMassacre/MainView.cs b/MosswartMassacre/MainView.cs
index a5755ac..8a98ed1 100644
--- a/MosswartMassacre/MainView.cs
+++ b/MosswartMassacre/MainView.cs
@@ -12,6 +12,8 @@ namespace MosswartMassacre
private static IStaticText lblElapsedTime;
private static IStaticText lblRareCount;
private static IButton btnRestart;
+ private static IButton btnToggleRareMeta;
+ private static bool rareMetaEnabled = true;
public static void ViewInit()
{
@@ -29,6 +31,9 @@ namespace MosswartMassacre
lblRareCount = (IStaticText)View["lblRareCount"];
btnRestart = (IButton)View["btnRestart"];
btnRestart.Hit += OnRestartClick;
+ btnToggleRareMeta = (IButton)View["btnToggleRareMeta"];
+ btnToggleRareMeta.Hit += OnToggleRareMetaClick;
+ btnToggleRareMeta.Text = "Meta: ON";
PluginCore.WriteToChat("View initialized.");
}
@@ -45,6 +50,7 @@ namespace MosswartMassacre
View.Dispose();
PluginCore.WriteToChat("View destroyed.");
btnRestart.Hit -= OnRestartClick;
+ btnToggleRareMeta.Hit -= OnToggleRareMetaClick;
}
catch (Exception ex)
{
@@ -71,5 +77,12 @@ namespace MosswartMassacre
{
PluginCore.RestartStats();
}
+ private static void OnToggleRareMetaClick(object sender, EventArgs e)
+ {
+ rareMetaEnabled = !rareMetaEnabled;
+ btnToggleRareMeta.Text = rareMetaEnabled ? "Meta: ON" : "Meta: OFF";
+ PluginCore.rareMetaEnabled = rareMetaEnabled; // Share toggle with PluginCore
+ PluginCore.WriteToChat($"[Debug] rareMetaEnabled is now: {rareMetaEnabled}");
+ }
}
}
diff --git a/MosswartMassacre/MosswartMassacre.csproj b/MosswartMassacre/MosswartMassacre.csproj
index e689bbb..92b72c9 100644
--- a/MosswartMassacre/MosswartMassacre.csproj
+++ b/MosswartMassacre/MosswartMassacre.csproj
@@ -49,6 +49,7 @@
+
@@ -60,6 +61,7 @@
+
diff --git a/MosswartMassacre/PluginCore.cs b/MosswartMassacre/PluginCore.cs
index 4e8d488..aa2d4af 100644
--- a/MosswartMassacre/PluginCore.cs
+++ b/MosswartMassacre/PluginCore.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Timers;
using Decal.Adapter;
@@ -17,6 +19,10 @@ namespace MosswartMassacre
internal static double killsPerHour = 0;
internal static DateTime statsStartTime = DateTime.Now;
internal static Timer updateTimer;
+ internal static bool rareMetaEnabled = true;
+ private static Queue rareMessageQueue = new Queue();
+ private static DateTime _lastSent = DateTime.MinValue;
+ private static readonly Queue _chatQueue = new Queue();
protected override void Startup()
{
@@ -73,7 +79,7 @@ namespace MosswartMassacre
{
try
{
- // WriteToChat($"[Debug] Chat Color: {e.Color}, Message: {e.Text}");
+ // WriteToChat($"[Debug] Chat Color: {e.Color}, Message: {e.Text}");
if (IsKilledByMeMessage(e.Text))
{
@@ -83,10 +89,40 @@ namespace MosswartMassacre
MainView.UpdateKillStats(totalKills, killsPer5Min, killsPerHour);
}
- if (IsRareDiscoveryMessage(e.Text))
+ if (IsRareDiscoveryMessage(e.Text, out string rareText))
{
rareCount++;
- MainView.UpdateRareCount(rareCount);
+ MainView.UpdateRareCount(rareCount);
+
+ if (rareMetaEnabled)
+ {
+ Decal_DispatchOnChatCommand("/vt setmetastate loot_rare");
+ }
+
+ DelayedCommandManager.AddDelayedCommand($"/a {rareText}", 3000);
+ }
+ if (e.Text.EndsWith("!testrare\""))
+ {
+ string simulatedText = $"{CoreManager.Current.CharacterFilter.Name} has discovered the Ancient Pickle!";
+
+ if (IsRareDiscoveryMessage(simulatedText, out string simulatedRareText))
+ {
+ rareCount++;
+ MainView.UpdateRareCount(rareCount);
+
+ if (rareMetaEnabled)
+ {
+ Decal_DispatchOnChatCommand("/vt setmetastate loot_rare");
+ }
+
+ DelayedCommandManager.AddDelayedCommand($"/a {simulatedRareText}", 3000);
+ }
+ else
+ {
+ WriteToChat("[Test] Simulated rare message didn't match the regex.");
+ }
+
+ return;
}
if (e.Color == 18 && e.Text.EndsWith("!report\""))
{
@@ -181,22 +217,18 @@ namespace MosswartMassacre
return false;
}
- private bool IsRareDiscoveryMessage(string text)
+ private bool IsRareDiscoveryMessage(string text, out string rareTextOnly)
{
+ rareTextOnly = null;
+
// Match pattern: " has discovered the !"
string pattern = @"^(?['A-Za-z ]+)\s(?has discovered the .*!$)";
Match match = Regex.Match(text, pattern);
- if (match.Success)
+ if (match.Success && match.Groups["name"].Value == CoreManager.Current.CharacterFilter.Name)
{
- // Capture the name from the matched text
- string name = match.Groups["name"].Value;
-
- // Compare the captured name to the player's name
- if (name == CoreManager.Current.CharacterFilter.Name)
- {
- return true;
- }
+ rareTextOnly = match.Groups["text"].Value; // just "has discovered the Ancient Pickle!"
+ return true;
}
return false;
@@ -217,5 +249,30 @@ namespace MosswartMassacre
MainView.UpdateKillStats(totalKills, killsPer5Min, killsPerHour);
MainView.UpdateRareCount(rareCount);
}
+ [DllImport("Decal.dll")]
+ private static extern int DispatchOnChatCommand(ref IntPtr str, [MarshalAs(UnmanagedType.U4)] int target);
+
+ public static bool Decal_DispatchOnChatCommand(string cmd)
+ {
+ IntPtr bstr = Marshal.StringToBSTR(cmd);
+
+ try
+ {
+ bool eaten = (DispatchOnChatCommand(ref bstr, 1) & 0x1) > 0;
+ return eaten;
+ }
+ finally
+ {
+ Marshal.FreeBSTR(bstr);
+ }
+ }
+ public static void DispatchChatToBoxWithPluginIntercept(string cmd)
+ {
+ if (!Decal_DispatchOnChatCommand(cmd))
+ CoreManager.Current.Actions.InvokeChatParser(cmd);
+ }
+
}
}
+
+
diff --git a/MosswartMassacre/ViewXML/mainView.xml b/MosswartMassacre/ViewXML/mainView.xml
index e3d64db..78e6865 100644
--- a/MosswartMassacre/ViewXML/mainView.xml
+++ b/MosswartMassacre/ViewXML/mainView.xml
@@ -1,12 +1,14 @@
-
+
-
+
+
+
diff --git a/MosswartMassacre/lib/VirindiViewService.xml b/MosswartMassacre/lib/VirindiViewService.xml
new file mode 100644
index 0000000..c43230e
--- /dev/null
+++ b/MosswartMassacre/lib/VirindiViewService.xml
@@ -0,0 +1,386 @@
+
+
+
+ VirindiViewService
+
+
+
+
+ Implies Top and Left
+
+
+
+
+ Provides theme elements, which can be drawn by controls.
+
+
+
+
+ Displays an element from the current theme.
+
+
+
+
+ The base class for all Virindi Views controls.
+
+
+
+
+ Called after this control is added to a ControlGroup. This is when the Name and details have been set.
+
+
+
+
+ Add and initialize a child control of this control. The child may be removed by disposing it.
+
+
+
+
+
+ Called when a child of this control is disposed.
+
+
+
+
+
+ Recursively disposes all children and removes this control from the view, if it is initialized.
+
+
+
+
+ Handles a mouse wheel event. Parent controls must pass this on to applicable children if necessary.
+
+
+
+
+
+
+ Fires the MouseEvent event for mouse down, and sets this control as the focus control if CanTakeFocus is true.
+
+ Parent controls must pass this on to applicable children if necessary.
+
+
+
+
+
+ Fires the MouseEvent event for mouse up as well as the Hit event.
+
+ Parent controls must pass this on to applicable children if necessary.
+
+
+
+
+
+
+ Fired when the mousedown originated outside the current view. The base version of this method
+ passes on the event to all children if the 'up' point is within its saved rect.
+
+ Mouseup point
+
+
+
+ Tracks mouseover and fires the MouseOverChange event, as well as the MouseEvent event for mouse move.
+
+ Parent controls must pass this on to applicable children if necessary.
+
+
+
+
+
+ Parses a key message and fires the specific key event methods.
+
+ Key events are only sent to the control with focus.
+
+
+
+
+
+
+
+
+ WARNING: ONLY A PARENT CONTROL SHOULD CALL THIS METHOD.
+
+ This method is overridden in derived controls to handle the actual control drawing. Overridden methods should call
+ the base, draw, and recursively call this method on all child controls.
+
+
+
+
+
+ WARNING: ONLY A PARENT CONTROL SHOULD CALL THIS METHOD.
+
+ Notifies a control of changed saved draw options. This method saves its parameters in the Savedxxx properties.
+ Parent controls should override this method and recursively notify children of their new draw options, altering
+ their pClipRegion to reflect their new position in the View.
+
+ This base method also fires the DrawStateChange and ThemeChanged events.
+
+ This control's area, relative to the view area.
+ The theme applied to this control.
+ The context of this control, eg. inside a listbox.
+ The position of the View, in game window coordinates.
+
+
+
+ WARNING: ONLY A PARENT CONTROL SHOULD SET THIS PROPERTY.
+
+
+
+
+ List of XmlAttributes present on the XmlNode that was used to construct this control, if the control was loaded from XML. Otherwise, empty.
+
+
+
+
+ The XmlNode used to construct this control, if the control was loaded from XML. Otherwise, null.
+
+
+
+
+ The name that this control will be initialized with.
+
+
+
+
+ A multiline uneditable scrolling text box.
+
+
+
+
+ A single image control.
+
+
+
+
+ A button using custom images.
+
+
+
+
+ A doubly-linked list with a Dictionary index. Duplicate items are not allowed.
+ -Add is O(1)
+ -Contains is O(1)
+ -Remove is O(1)
+ -Get/set by index is O(n)
+ -Insert is O(n)
+ -RemoveAt is O(n)
+ Additionally, a cached pointer (with associated index) is kept pointing to the last used index item.
+ When looking up an item by index, the list is walked from the head, tail, or cached index pointer.
+ Thus, doing multiple operations in index order is O(1) even without an enumerator.
+
+
+
+
+
+ This method gets the node corresponding to a particular index. To get there,
+ the list is traversed from the head, tail, or cached index pointer (if valid).
+
+
+
+
+
+
+ Web browser control, using Awesomium (free license version)
+
+
+
+
+ A horizontal scrollbar.
+
+
+
+
+ Summary description for ByteCursor.
+
+
+
+
+ A checkbox with optional associated text. Uses its parent to provide the background.
+
+
+
+
+ A single-line text input box.
+
+
+
+
+ Called before render so the required size of the new target area can be calculated.
+ The returned value is the size of the desired draw area, not including outer borders and
+ style-dependent padding. This size must be less than or equal to MaximumSize in each dimension.
+
+
+
+
+
+
+ Draw this element. When this is called, the background and borders will already have been drawn, and
+ target will already be in BeginRender. This method should leave the target in render mode.
+
+
+
+
+
+
+
+ A renderer for string-only tooltips.
+
+
+
+
+ Represents an unordered set of items. Duplicates are not allowed.
+ (This is really just a dictionary which only holds keys.)
+ Should be used when a collection of non-duplicate items is needed and
+ the order doesn't matter.
+
+
+
+
+ A series of titled tabs along the top, each one having an associated control which appears
+ on the bottom when its tab is enabled.
+
+
+
+
+ A progressbar.
+
+
+
+
+ A regular pushbutton-style control.
+
+
+
+
+ Calls the non-hooked IDirect3DDevice9::BeginScene function. When rendering inside a VVS view or texture, use DxTexture.BeginRender() instead.
+
+
+
+
+
+ Calls the non-hooked IDirect3DDevice9::EndScene function. When rendering inside a VVS view or texture, use DxTexture.EndRender() instead.
+
+
+
+
+
+ Gets the current instance of the VVS bar.
+
+
+
+
+ A console containing game chat.
+
+
+
+
+ Initializes Direct3D drawing and sets the rendertarget to this texture. Calls to this method should be minimized to improve performance. DxTexture.EndRender() must be called after calling this method.
+
+
+
+
+
+
+
+
+
+ Ends Direct3D rendering and resets the rendertarget. Must be called after DxTexture.BeginRender().
+
+
+
+
+ Note: Before use, FlushSprite() may need to be called to ensure correct ordering.
+
+
+
+
+
+
+
+
+ Note: Before use, you must call BeginUserDrawOperation().
+
+
+
+
+
+
+
+
+ Note: Before use, you must call BeginUserDrawOperation().
+
+
+
+
+
+
+
+
+
+ A vertically scrolling list, containing a number of rows and columns. Every row
+ has the same number and types of columns. Each column contains a specified control type.
+
+
+
+
+ A number of images on top of each other, which always draw in the proper order.
+
+
+
+
+ A simple text display control. Uses its parent to provide the background.
+
+
+
+
+ A container for multiple controls with set locations and sizes within.
+
+
+
+
+ A dropdown list.
+
+
+
+
+ If the context menu is not visible, it is created at the specified point.
+
+
+
+
+ If the context menu is not visible, it is created at the specified point with the specified theme.
+
+
+
+
+ Provides information about an associated tooltip.
+
+
+
+
+ The HudControl that the tip is attached to.
+
+
+
+
+ Deprecated.
+ Returns the text associated with a tooltip only if the tip contains a cStringRenderer.
+
+
+
+
+ A vertical scrollbar.
+
+
+
+
+ A horizontal slider.
+
+
+
+
+ A control that allows easy access to underlying draw methods.
+
+
+
+
diff --git a/mossy.sln b/mossy.sln
index c847a0b..bb3ea64 100644
--- a/mossy.sln
+++ b/mossy.sln
@@ -1,12 +1,14 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
-VisualStudioVersion = 17.13.35919.96 d17.13
+VisualStudioVersion = 17.13.35919.96
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MosswartMassacre", "MosswartMassacre\MosswartMassacre.csproj", "{8C97E839-4D05-4A5F-B0C8-E8E778654322}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GearCycler", "GearCycler\GearCycler.csproj", "{1293560E-2A56-417F-8116-8CE0420DC97C}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -17,6 +19,10 @@ Global
{8C97E839-4D05-4A5F-B0C8-E8E778654322}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C97E839-4D05-4A5F-B0C8-E8E778654322}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C97E839-4D05-4A5F-B0C8-E8E778654322}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1293560E-2A56-417F-8116-8CE0420DC97C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1293560E-2A56-417F-8116-8CE0420DC97C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1293560E-2A56-417F-8116-8CE0420DC97C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1293560E-2A56-417F-8116-8CE0420DC97C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE