added chest looter
This commit is contained in:
parent
2eb9a7773e
commit
c90a11fc29
4 changed files with 1603 additions and 4 deletions
1346
MosswartMassacre/ChestLooter.cs
Normal file
1346
MosswartMassacre/ChestLooter.cs
Normal file
File diff suppressed because it is too large
Load diff
122
MosswartMassacre/ChestLooterSettings.cs
Normal file
122
MosswartMassacre/ChestLooterSettings.cs
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MosswartMassacre
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Settings for the Chest Looter feature
|
||||||
|
/// These settings are persisted per-character via PluginSettings
|
||||||
|
/// </summary>
|
||||||
|
public class ChestLooterSettings
|
||||||
|
{
|
||||||
|
// Target configuration
|
||||||
|
public string ChestName { get; set; } = "";
|
||||||
|
public string KeyName { get; set; } = "";
|
||||||
|
|
||||||
|
// Feature toggles
|
||||||
|
public bool Enabled { get; set; } = false;
|
||||||
|
public bool EnableChests { get; set; } = true;
|
||||||
|
public bool AutoSalvageAfterLooting { get; set; } = false;
|
||||||
|
public bool JumpWhenLooting { get; set; } = false;
|
||||||
|
public bool BlockVtankMelee { get; set; } = false;
|
||||||
|
public bool TestMode { get; set; } = false;
|
||||||
|
public bool VerboseLogging { get; set; } = false;
|
||||||
|
|
||||||
|
// Timing and retry settings
|
||||||
|
public int DelaySpeed { get; set; } = 1000; // Delay for unlock/open/close in ms
|
||||||
|
public int OverallSpeed { get; set; } = 100; // Overall looter tick rate in ms
|
||||||
|
public int MaxUnlockAttempts { get; set; } = 10; // Max attempts to unlock chest
|
||||||
|
public int MaxOpenAttempts { get; set; } = 10; // Max attempts to open chest
|
||||||
|
public int AttemptsBeforeBlacklisting { get; set; } = 500; // Item loot attempts before giving up
|
||||||
|
|
||||||
|
// Jump looting settings
|
||||||
|
public int JumpHeight { get; set; } = 100; // Jump height (full bar is 1000)
|
||||||
|
|
||||||
|
// UI state
|
||||||
|
public bool ShowChestLooterTab { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor with default values
|
||||||
|
/// </summary>
|
||||||
|
public ChestLooterSettings()
|
||||||
|
{
|
||||||
|
// All defaults set via property initializers above
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate settings and apply constraints
|
||||||
|
/// </summary>
|
||||||
|
public void Validate()
|
||||||
|
{
|
||||||
|
// Ensure OverallSpeed isn't too fast (can cause issues)
|
||||||
|
if (OverallSpeed < 100)
|
||||||
|
OverallSpeed = 100;
|
||||||
|
|
||||||
|
// Ensure delays are reasonable
|
||||||
|
if (DelaySpeed < 500)
|
||||||
|
DelaySpeed = 500;
|
||||||
|
|
||||||
|
// Ensure attempt limits are positive
|
||||||
|
if (MaxUnlockAttempts < 1)
|
||||||
|
MaxUnlockAttempts = 1;
|
||||||
|
if (MaxOpenAttempts < 1)
|
||||||
|
MaxOpenAttempts = 1;
|
||||||
|
if (AttemptsBeforeBlacklisting < 1)
|
||||||
|
AttemptsBeforeBlacklisting = 1;
|
||||||
|
|
||||||
|
// Clamp jump height to reasonable range
|
||||||
|
if (JumpHeight < 0)
|
||||||
|
JumpHeight = 0;
|
||||||
|
if (JumpHeight > 1000)
|
||||||
|
JumpHeight = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reset all settings to default values
|
||||||
|
/// </summary>
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
ChestName = "";
|
||||||
|
KeyName = "";
|
||||||
|
Enabled = false;
|
||||||
|
EnableChests = true;
|
||||||
|
AutoSalvageAfterLooting = false;
|
||||||
|
JumpWhenLooting = false;
|
||||||
|
BlockVtankMelee = false;
|
||||||
|
TestMode = false;
|
||||||
|
VerboseLogging = false;
|
||||||
|
DelaySpeed = 1000;
|
||||||
|
OverallSpeed = 100;
|
||||||
|
MaxUnlockAttempts = 10;
|
||||||
|
MaxOpenAttempts = 10;
|
||||||
|
AttemptsBeforeBlacklisting = 500;
|
||||||
|
JumpHeight = 100;
|
||||||
|
ShowChestLooterTab = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a copy of these settings
|
||||||
|
/// </summary>
|
||||||
|
public ChestLooterSettings Clone()
|
||||||
|
{
|
||||||
|
return new ChestLooterSettings
|
||||||
|
{
|
||||||
|
ChestName = this.ChestName,
|
||||||
|
KeyName = this.KeyName,
|
||||||
|
Enabled = this.Enabled,
|
||||||
|
EnableChests = this.EnableChests,
|
||||||
|
AutoSalvageAfterLooting = this.AutoSalvageAfterLooting,
|
||||||
|
JumpWhenLooting = this.JumpWhenLooting,
|
||||||
|
BlockVtankMelee = this.BlockVtankMelee,
|
||||||
|
TestMode = this.TestMode,
|
||||||
|
VerboseLogging = this.VerboseLogging,
|
||||||
|
DelaySpeed = this.DelaySpeed,
|
||||||
|
OverallSpeed = this.OverallSpeed,
|
||||||
|
MaxUnlockAttempts = this.MaxUnlockAttempts,
|
||||||
|
MaxOpenAttempts = this.MaxOpenAttempts,
|
||||||
|
AttemptsBeforeBlacklisting = this.AttemptsBeforeBlacklisting,
|
||||||
|
JumpHeight = this.JumpHeight,
|
||||||
|
ShowChestLooterTab = this.ShowChestLooterTab
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -119,7 +119,8 @@ namespace MosswartMassacre
|
||||||
public static bool AggressiveChatStreamingEnabled { get; set; } = true;
|
public static bool AggressiveChatStreamingEnabled { get; set; } = true;
|
||||||
private MossyInventory _inventoryLogger;
|
private MossyInventory _inventoryLogger;
|
||||||
public static NavVisualization navVisualization;
|
public static NavVisualization navVisualization;
|
||||||
|
public static ChestLooter chestLooter;
|
||||||
|
|
||||||
// Quest Management for always-on quest streaming
|
// Quest Management for always-on quest streaming
|
||||||
public static QuestManager questManager;
|
public static QuestManager questManager;
|
||||||
private static Timer questStreamingTimer;
|
private static Timer questStreamingTimer;
|
||||||
|
|
@ -215,6 +216,8 @@ namespace MosswartMassacre
|
||||||
// Initialize navigation visualization system
|
// Initialize navigation visualization system
|
||||||
navVisualization = new NavVisualization();
|
navVisualization = new NavVisualization();
|
||||||
|
|
||||||
|
// Note: ChestLooter is initialized in LoginComplete after PluginSettings.Initialize()
|
||||||
|
|
||||||
// Note: DECAL Harmony patches will be initialized in LoginComplete event
|
// Note: DECAL Harmony patches will be initialized in LoginComplete event
|
||||||
// where the chat system is available for error messages
|
// where the chat system is available for error messages
|
||||||
|
|
||||||
|
|
@ -329,6 +332,21 @@ namespace MosswartMassacre
|
||||||
|
|
||||||
PluginSettings.Initialize(); // Safe to call now
|
PluginSettings.Initialize(); // Safe to call now
|
||||||
|
|
||||||
|
// Initialize chest looter system (needs PluginSettings to be ready)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
chestLooter = new ChestLooter(CoreManager.Current, PluginSettings.Instance.ChestLooterSettings);
|
||||||
|
chestLooter.Initialize();
|
||||||
|
chestLooter.StatusChanged += (sender, status) =>
|
||||||
|
{
|
||||||
|
VVSTabbedMainView.UpdateChestLooterStatus(status);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
WriteToChat($"[ChestLooter] Initialization failed: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
// Apply the values
|
// Apply the values
|
||||||
RareMetaEnabled = PluginSettings.Instance.RareMetaEnabled;
|
RareMetaEnabled = PluginSettings.Instance.RareMetaEnabled;
|
||||||
WebSocketEnabled = PluginSettings.Instance.WebSocketEnabled;
|
WebSocketEnabled = PluginSettings.Instance.WebSocketEnabled;
|
||||||
|
|
@ -494,6 +512,21 @@ namespace MosswartMassacre
|
||||||
// 1. Initialize settings - CRITICAL first step
|
// 1. Initialize settings - CRITICAL first step
|
||||||
PluginSettings.Initialize();
|
PluginSettings.Initialize();
|
||||||
|
|
||||||
|
// 1b. Initialize chest looter system (needs PluginSettings to be ready)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
chestLooter = new ChestLooter(CoreManager.Current, PluginSettings.Instance.ChestLooterSettings);
|
||||||
|
chestLooter.Initialize();
|
||||||
|
chestLooter.StatusChanged += (sender, status) =>
|
||||||
|
{
|
||||||
|
VVSTabbedMainView.UpdateChestLooterStatus(status);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
WriteToChat($"[ChestLooter] Initialization failed: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
// 2. Apply the values from settings
|
// 2. Apply the values from settings
|
||||||
RareMetaEnabled = PluginSettings.Instance.RareMetaEnabled;
|
RareMetaEnabled = PluginSettings.Instance.RareMetaEnabled;
|
||||||
WebSocketEnabled = PluginSettings.Instance.WebSocketEnabled;
|
WebSocketEnabled = PluginSettings.Instance.WebSocketEnabled;
|
||||||
|
|
@ -1216,7 +1249,7 @@ namespace MosswartMassacre
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Hot reload fallback - use CoreManager directly like the original template
|
// Hot reload fallback1 - use CoreManager directly like the original template
|
||||||
CoreManager.Current.Actions.AddChatText("[Mosswart Massacre] " + message, 1);
|
CoreManager.Current.Actions.AddChatText("[Mosswart Massacre] " + message, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1277,7 +1310,7 @@ namespace MosswartMassacre
|
||||||
}
|
}
|
||||||
private void HandleMmCommand(string text)
|
private void HandleMmCommand(string text)
|
||||||
{
|
{
|
||||||
// Remove the /mm prefix and trim extra whitespace
|
// Remove the /mm prefix and trim extra whitespace test
|
||||||
string[] args = text.Substring(3).Trim().Split(' ');
|
string[] args = text.Substring(3).Trim().Split(' ');
|
||||||
|
|
||||||
if (args.Length == 0 || string.IsNullOrEmpty(args[0]))
|
if (args.Length == 0 || string.IsNullOrEmpty(args[0]))
|
||||||
|
|
@ -1356,6 +1389,10 @@ namespace MosswartMassacre
|
||||||
WriteToChat("/mm http - Local http-command server enable|disable");
|
WriteToChat("/mm http - Local http-command server enable|disable");
|
||||||
WriteToChat("/mm remotecommand - Listen to allegiance !do/!dot enable|disable");
|
WriteToChat("/mm remotecommand - Listen to allegiance !do/!dot enable|disable");
|
||||||
WriteToChat("/mm getmetastate - Gets the current metastate");
|
WriteToChat("/mm getmetastate - Gets the current metastate");
|
||||||
|
WriteToChat("/mm setchest <name> - Set chest name for looter");
|
||||||
|
WriteToChat("/mm setkey <name> - Set key name for looter");
|
||||||
|
WriteToChat("/mm lootchest - Start chest looting");
|
||||||
|
WriteToChat("/mm stoploot - Stop chest looting");
|
||||||
WriteToChat("/mm nextwp - Advance VTank to next waypoint");
|
WriteToChat("/mm nextwp - Advance VTank to next waypoint");
|
||||||
WriteToChat("/mm decalstatus - Check Harmony patch status (UtilityBelt version)");
|
WriteToChat("/mm decalstatus - Check Harmony patch status (UtilityBelt version)");
|
||||||
WriteToChat("/mm decaldebug - Enable/disable plugin message debug output + WebSocket streaming");
|
WriteToChat("/mm decaldebug - Enable/disable plugin message debug output + WebSocket streaming");
|
||||||
|
|
@ -1460,6 +1497,69 @@ namespace MosswartMassacre
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "setchest":
|
||||||
|
if (args.Length < 2)
|
||||||
|
{
|
||||||
|
WriteToChat("[ChestLooter] Usage: /mm setchest <chest name>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string chestName = string.Join(" ", args.Skip(1));
|
||||||
|
if (chestLooter != null)
|
||||||
|
{
|
||||||
|
chestLooter.SetChestName(chestName);
|
||||||
|
if (PluginSettings.Instance?.ChestLooterSettings != null)
|
||||||
|
{
|
||||||
|
PluginSettings.Instance.ChestLooterSettings.ChestName = chestName;
|
||||||
|
PluginSettings.Save();
|
||||||
|
}
|
||||||
|
Views.VVSTabbedMainView.RefreshChestLooterUI();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "setkey":
|
||||||
|
if (args.Length < 2)
|
||||||
|
{
|
||||||
|
WriteToChat("[ChestLooter] Usage: /mm setkey <key name>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string keyName = string.Join(" ", args.Skip(1));
|
||||||
|
if (chestLooter != null)
|
||||||
|
{
|
||||||
|
chestLooter.SetKeyName(keyName);
|
||||||
|
if (PluginSettings.Instance?.ChestLooterSettings != null)
|
||||||
|
{
|
||||||
|
PluginSettings.Instance.ChestLooterSettings.KeyName = keyName;
|
||||||
|
PluginSettings.Save();
|
||||||
|
}
|
||||||
|
Views.VVSTabbedMainView.RefreshChestLooterUI();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "lootchest":
|
||||||
|
if (chestLooter != null)
|
||||||
|
{
|
||||||
|
if (!chestLooter.StartByName())
|
||||||
|
{
|
||||||
|
WriteToChat("[ChestLooter] Failed to start. Check chest/key names are set.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteToChat("[ChestLooter] Chest looter not initialized");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "stoploot":
|
||||||
|
if (chestLooter != null)
|
||||||
|
{
|
||||||
|
chestLooter.Stop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteToChat("[ChestLooter] Chest looter not initialized");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case "vtanktest":
|
case "vtanktest":
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,37 @@
|
||||||
<control progid="DecalControls.PushButton" name="btnOpenFlagTracker" left="10" top="10" width="150" height="30" text="Open Mossy Tracker"/>
|
<control progid="DecalControls.PushButton" name="btnOpenFlagTracker" left="10" top="10" width="150" height="30" text="Open Mossy Tracker"/>
|
||||||
</control>
|
</control>
|
||||||
</page>
|
</page>
|
||||||
|
|
||||||
|
<page label="Chest Looter">
|
||||||
|
<control progid="DecalControls.FixedLayout" clipped="">
|
||||||
|
<!-- Header -->
|
||||||
|
<control progid="DecalControls.StaticText" name="lblChestLooterHeader" left="10" top="10" width="250" height="20" text="Automated Chest Looting" style="FontBold"/>
|
||||||
|
|
||||||
|
<!-- Chest Name Configuration -->
|
||||||
|
<control progid="DecalControls.StaticText" name="lblChestNameLabel" left="20" top="40" width="100" height="16" text="Chest Name:"/>
|
||||||
|
<control progid="DecalControls.Edit" name="txtChestName" left="125" top="38" width="180" height="20" text=""/>
|
||||||
|
<control progid="DecalControls.PushButton" name="btnSetChest" left="310" top="37" width="100" height="22" text="Set from Selection"/>
|
||||||
|
|
||||||
|
<!-- Key Name Configuration -->
|
||||||
|
<control progid="DecalControls.StaticText" name="lblKeyNameLabel" left="20" top="70" width="100" height="16" text="Key Name:"/>
|
||||||
|
<control progid="DecalControls.Edit" name="txtKeyName" left="125" top="68" width="180" height="20" text=""/>
|
||||||
|
<control progid="DecalControls.PushButton" name="btnSetKey" left="310" top="67" width="100" height="22" text="Set from Selection"/>
|
||||||
|
|
||||||
|
<!-- Control Buttons -->
|
||||||
|
<control progid="DecalControls.PushButton" name="btnStartLooter" left="20" top="105" width="120" height="30" text="Start Looting"/>
|
||||||
|
<control progid="DecalControls.PushButton" name="btnStopLooter" left="145" top="105" width="120" height="30" text="Stop"/>
|
||||||
|
|
||||||
|
<!-- Settings -->
|
||||||
|
<control progid="DecalControls.StaticText" name="lblLooterSettingsHeader" left="10" top="145" width="200" height="16" text="Options" style="FontBold"/>
|
||||||
|
<control progid="DecalControls.Checkbox" name="chkEnableChests" left="20" top="165" width="200" height="20" text="Enable Chest Looting" checked="true"/>
|
||||||
|
|
||||||
|
<!-- Status Display -->
|
||||||
|
<control progid="DecalControls.StaticText" name="lblLooterStatus" left="10" top="195" width="380" height="20" text="Status: Ready"/>
|
||||||
|
|
||||||
|
<!-- Instructions -->
|
||||||
|
<control progid="DecalControls.StaticText" name="lblLooterInstructions" left="10" top="220" width="380" height="30" text="Set chest/key names, then click Start. Uses VTank loot profile. Commands: /mm setchest, /mm setkey, /mm lootchest"/>
|
||||||
|
</control>
|
||||||
|
</page>
|
||||||
|
|
||||||
</control>
|
</control>
|
||||||
</view>
|
</view>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue