This commit is contained in:
Boki 2026-02-26 22:22:33 -05:00
parent 657d307485
commit 566dae8997
6 changed files with 72 additions and 60 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 MiB

After

Width:  |  Height:  |  Size: 7 MiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 MiB

After

Width:  |  Height:  |  Size: 6.2 MiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 KiB

After

Width:  |  Height:  |  Size: 323 KiB

Before After
Before After

View file

@ -129,37 +129,15 @@ public class KulemakExecutor : MappingExecutor
}
await Sleep(Delays.PostStashOpen);
// Scan inventory now that stash (and inventory panel) is open
var scanResult = await _inventory.SnapshotInventory();
if (scanResult.Occupied.Count > 0)
var (lootTab, lootFolder) = ResolveTabPath(_config.Kulemak.LootTabPath);
if (lootTab == null)
{
var (lootTab, lootFolder) = ResolveTabPath(_config.Kulemak.LootTabPath);
if (lootTab != null)
{
await _inventory.ClickStashTab(lootTab, lootFolder);
Log.Information("Depositing {Count} inventory items to loot tab", scanResult.Occupied.Count);
await _game.KeyDown(InputSender.VK.SHIFT);
await _game.HoldCtrl();
foreach (var cell in scanResult.Occupied)
{
var center = _screen.Grid.GetCellCenter(GridLayouts.Inventory, cell.Row, cell.Col);
await _game.LeftClickAt(center.X, center.Y);
await Sleep(Delays.ClickInterval);
}
await _game.ReleaseCtrl();
await _game.KeyUp(InputSender.VK.SHIFT);
await Sleep(Delays.PostEscape);
}
else
{
Log.Warning("Loot tab path not configured or not found, skipping deposit");
}
Log.Warning("Loot tab path not configured or not found, skipping deposit");
}
else
{
Log.Information("Inventory empty, skipping loot deposit");
await _inventory.ClickStashTab(lootTab, lootFolder);
await _inventory.DepositAllToOpenStash();
}
if (invTab != null)
@ -465,30 +443,7 @@ public class KulemakExecutor : MappingExecutor
if (lootTab != null)
await _inventory.ClickStashTab(lootTab, lootFolder);
for (var pass = 0; pass < 3; pass++)
{
var scanResult = await _inventory.SnapshotInventory();
if (scanResult.Items.Count == 0)
{
if (pass > 0) Log.Information("Inventory clear after {Pass} passes", pass);
break;
}
Log.Information("Depositing {Count} items to loot tab (pass {Pass})", scanResult.Items.Count, pass + 1);
await _game.KeyDown(InputSender.VK.SHIFT);
await _game.HoldCtrl();
foreach (var item in scanResult.Items)
{
var center = _screen.Grid.GetCellCenter(GridLayouts.Inventory, item.Row, item.Col);
await _game.LeftClickAt(center.X, center.Y);
await Sleep(Delays.ClickInterval);
}
await _game.ReleaseCtrl();
await _game.KeyUp(InputSender.VK.SHIFT);
await Sleep(Delays.PostEscape);
}
await _inventory.DepositAllToOpenStash();
// Grab 1 invitation for the next run while stash is still open
if (grabInvitation)

View file

@ -19,6 +19,7 @@ public interface IInventoryManager
Task<bool> WaitForAreaTransition(int timeoutMs, Func<Task>? triggerAction = null);
Task<(int X, int Y)?> FindAndClickNameplate(string name, int maxRetries = 3, int retryDelayMs = 1000, System.Drawing.Rectangle? scanRegion = null, string? savePath = null);
Task DepositItemsToStash(List<PlacedItem> items);
Task DepositAllToOpenStash();
Task<bool> SalvageItems(List<PlacedItem> items);
Task<bool> IdentifyItems();
(bool[,] Grid, List<PlacedItem> Items, int Free) GetInventoryState();

View file

@ -130,14 +130,73 @@ public class InventoryManager : IInventoryManager
}
await Helpers.Sleep(Delays.PostStashOpen);
Log.Information("Depositing {Count} items to stash", items.Count);
await CtrlClickItems(items, GridLayouts.Inventory);
await SnapshotInventory();
await DepositAllToOpenStash();
await _game.PressEscape();
await Helpers.Sleep(Delays.PostEscape);
Log.Information("Items deposited to stash");
Log.Information("Deposit complete");
}
/// <summary>
/// Deposit one item at a time while stash is already open.
/// Scans → clicks first occupied cell → rescans → repeats.
/// Cells that remain occupied after clicking are marked as false positives and skipped.
/// </summary>
public async Task DepositAllToOpenStash()
{
await _game.KeyDown(Game.InputSender.VK.SHIFT);
await _game.HoldCtrl();
var falsePositives = new HashSet<(int Row, int Col)>();
(int Row, int Col)? lastClicked = null;
for (var i = 0; i < 60; i++)
{
if (lastClicked == null)
{
_game.MoveMouseInstant(1700, 700);
await Helpers.Sleep(50);
}
var scan = await _screen.Grid.Scan("inventory");
LastScreenshot = await _screen.CaptureRegion(GridLayouts.Inventory.Region);
Updated?.Invoke();
// If we clicked a cell last iteration, check if it's still there (= false positive)
if (lastClicked.HasValue &&
scan.Occupied.Any(c => c.Row == lastClicked.Value.Row && c.Col == lastClicked.Value.Col))
{
Log.Debug("Cell ({Row},{Col}) still occupied after click — false positive",
lastClicked.Value.Row, lastClicked.Value.Col);
falsePositives.Add(lastClicked.Value);
}
lastClicked = null;
var candidates = scan.Occupied
.Where(c => !falsePositives.Contains((c.Row, c.Col)))
.ToList();
if (candidates.Count == 0)
{
Log.Information(scan.Occupied.Count > 0
? $"All {scan.Occupied.Count} remaining occupied cells are false positives, done"
: "Inventory empty");
break;
}
var cell = candidates[0];
var center = _screen.Grid.GetCellCenter(GridLayouts.Inventory, cell.Row, cell.Col);
Log.Information("Depositing cell ({Row},{Col}) — {Real} candidates / {Total} detected",
cell.Row, cell.Col, candidates.Count, scan.Occupied.Count);
_game.MoveMouseInstant(center.X, center.Y);
await Helpers.RandomDelay(50, 100);
_game.LeftMouseDown();
_game.LeftMouseUp();
lastClicked = (cell.Row, cell.Col);
await Helpers.RandomDelay(50, 100);
}
await _game.ReleaseCtrl();
await _game.KeyUp(Game.InputSender.VK.SHIFT);
}
public async Task<bool> SalvageItems(List<PlacedItem> items)
@ -237,10 +296,7 @@ public class InventoryManager : IInventoryManager
}
await ScanInventory(PostAction.Stash);
var allItems = Tracker.GetItems();
if (allItems.Count > 0)
await DepositItemsToStash(allItems);
await DepositItemsToStash(Tracker.GetItems());
Tracker.Clear();
Log.Information("Inventory processing complete");