diff --git a/debug_loot_capture.png b/debug_loot_capture.png index 39f91ea..902adbf 100644 Binary files a/debug_loot_capture.png and b/debug_loot_capture.png differ diff --git a/debug_loot_detected.png b/debug_loot_detected.png index 50b59ac..2ccb365 100644 Binary files a/debug_loot_detected.png and b/debug_loot_detected.png differ diff --git a/debug_loot_edges.png b/debug_loot_edges.png index 99b4ad7..6743ea0 100644 Binary files a/debug_loot_edges.png and b/debug_loot_edges.png differ diff --git a/src/Poe2Trade.Bot/KulemakExecutor.cs b/src/Poe2Trade.Bot/KulemakExecutor.cs index 6739218..fbd7e43 100644 --- a/src/Poe2Trade.Bot/KulemakExecutor.cs +++ b/src/Poe2Trade.Bot/KulemakExecutor.cs @@ -119,6 +119,8 @@ public class KulemakExecutor : MappingExecutor await _game.FocusGame(); await Sleep(Delays.PostFocus); + var (invTab, invFolder) = ResolveTabPath(_config.Kulemak.InvitationTabPath); + var stashPos = await _inventory.FindAndClickNameplate("Stash"); if (stashPos == null) { @@ -127,14 +129,16 @@ public class KulemakExecutor : MappingExecutor } await Sleep(Delays.PostStashOpen); - var (lootTab, lootFolder) = ResolveTabPath(_config.Kulemak.LootTabPath); - if (lootTab != null) - { - await _inventory.ClickStashTab(lootTab, lootFolder); + // Scan inventory now that stash (and inventory panel) is open + var scanResult = await _screen.Grid.Scan("inventory"); - var scanResult = await _screen.Grid.Scan("inventory"); - if (scanResult.Occupied.Count > 0) + if (scanResult.Occupied.Count > 0) + { + 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(); @@ -148,18 +152,21 @@ public class KulemakExecutor : MappingExecutor await _game.KeyUp(InputSender.VK.SHIFT); await Sleep(Delays.PostEscape); } + else + { + Log.Warning("Loot tab path not configured or not found, skipping deposit"); + } } else { - Log.Warning("Loot tab path not configured or not found, skipping deposit"); + Log.Information("Inventory empty, skipping loot deposit"); } - var (invTab, invFolder) = ResolveTabPath(_config.Kulemak.InvitationTabPath); if (invTab != null) { await _inventory.ClickStashTab(invTab, invFolder); - var layoutName = (invTab.GridCols == 24, invFolder != null) switch + var layoutName = (invTab!.GridCols == 24, invFolder != null) switch { (true, true) => "stash24_folder", (true, false) => "stash24", @@ -169,10 +176,6 @@ public class KulemakExecutor : MappingExecutor await _inventory.GrabItemsFromStash(layoutName, 1, InvitationTemplate); } - else - { - Log.Warning("Invitation tab path not configured or not found, skipping grab"); - } await _game.PressEscape(); _inventory.ResetStashTabState(); @@ -335,7 +338,17 @@ public class KulemakExecutor : MappingExecutor await Sleep(500); await WalkToWorldPosition(wellWorldX, wellWorldY); await Sleep(500); - await ClickClosestTemplateToCenter(CathedralWellTemplate); + if (!await TryClickWell()) + { + Log.Warning("Well not found, walking A+W to get closer"); + await _game.KeyDown(InputSender.VK.A); + await _game.KeyDown(InputSender.VK.W); + await Sleep(1500); + await _game.KeyUp(InputSender.VK.W); + await _game.KeyUp(InputSender.VK.A); + await Sleep(500); + await TryClickWell(); + } await Sleep(200); await WalkToWorldPosition(fightWorldX + 20, fightWorldY +20, cancelWhen: IsBossAlive); @@ -404,6 +417,27 @@ public class KulemakExecutor : MappingExecutor } } + private async Task TryClickWell() + { + const int screenCx = 1280; + const int screenCy = 660; + var centerRegion = new Region(850, 50, 860, 550); + + var matches = await _screen.TemplateMatchAll(CathedralWellTemplate, centerRegion); + if (matches.Count == 0) return false; + + var closest = matches.OrderBy(m => + { + var dx = m.X - screenCx; + var dy = m.Y - screenCy; + return dx * dx + dy * dy; + }).First(); + + Log.Information("Clicking well at ({X},{Y}) conf={Conf:F3}", closest.X, closest.Y, closest.Confidence); + await _game.LeftClickAt(closest.X, closest.Y); + return true; + } + /// /// Store loot with optional invitation grab for the next run. ///