private static async Task <bool> CreateNewInstance(AreaTransition transition) { var name = transition.Name; if (!await Coroutines.InteractWith(transition, true)) { GlobalLog.Error($"[CreateNewInstance] Fail to interact with \"{name}\" transition."); return(false); } if (!await Wait.For(() => LokiPoe.InGameState.InstanceManagerUi.IsOpened, "instance manager opening")) { return(false); } if (Settings.Instance.ArtificialDelays) { await Wait.ArtificialDelay(); } GlobalLog.Debug($"[CreateNewInstance] Creating new instance for \"{name}\"."); var err = LokiPoe.InGameState.InstanceManagerUi.JoinNewInstance(); if (err != LokiPoe.InGameState.JoinInstanceResult.None) { GlobalLog.Error($"[CreateNewInstance] Fail to create a new instance. Error: \"{err}\"."); return(false); } GlobalLog.Debug($"[CreateNewInstance] New instance for \"{name}\" has been successfully created."); return(true); }
public static async Task AtOnce(Vector2i pos, string destination, int minDistance = 20) { if (LokiPoe.MyPosition.Distance(pos) <= minDistance) { return; } while (LokiPoe.MyPosition.Distance(pos) > minDistance) { if (LogInterval.Elapsed) { await Coroutines.CloseBlockingWindows(); GlobalLog.Debug($"[MoveAtOnce] Moving to {destination} at {pos} (distance: {LokiPoe.MyPosition.Distance(pos)})"); } if (!LokiPoe.IsInGame || LokiPoe.Me.IsDead || BotManager.IsStopping) { return; } TowardsWalkable(pos, destination); await Wait.Sleep(50); } await Coroutines.FinishCurrentAction(); }
public static async Task <bool> PickItemToCursor(this InventoryControlWrapper inventory, Vector2i itemPos, bool rightClick = false) { var item = inventory.Inventory.FindItemByPos(itemPos); if (item == null) { GlobalLog.Error($"[PickItemToCursor] Cannot find item at {itemPos}"); return(false); } GlobalLog.Debug($"[PickItemToCursor] Now going to pick \"{item.Name}\" at {itemPos} to cursor."); int id = item.LocalId; if (rightClick) { var err = inventory.UseItem(id); if (err != UseItemResult.None) { GlobalLog.Error($"[PickItemToCursor] Fail to pick item to cursor. Error: \"{err}\"."); return(false); } } else { var err = inventory.Pickup(id); if (err != PickupResult.None) { GlobalLog.Error($"[PickItemToCursor] Fail to pick item to cursor. Error: \"{err}\"."); return(false); } } return(await Wait.For(() => Cursor.Item != null, "item appear under cursor")); }
public static async Task <bool> TakePortal(Portal portal) { if (portal == null) { GlobalLog.Error("[TakePortal] Portal object is null."); return(false); } var pos = portal.WalkablePosition(); await pos.ComeAtOnce(); await Wait.SleepSafe(200); GlobalLog.Debug($"[TakePortal] Now going to take portal to \"{pos.Name}\"."); var hash = LokiPoe.LocalData.AreaHash; if (!await Interact(portal)) { return(false); } if (!await Wait.ForAreaChange(hash)) { return(false); } GlobalLog.Debug($"[TakePortal] Portal to \"{pos.Name}\" has been successfully taken."); return(true); }
public static async Task <bool> Interact(NetworkObject obj, Func <bool> success, string desc, int timeout = 3000) { if (obj == null) { GlobalLog.Error("[Interact] Object for interaction is null."); return(false); } var name = obj.Name; GlobalLog.Debug($"[Interact] Now going to interact with \"{name}\"."); await Coroutines.CloseBlockingWindows(); await Coroutines.FinishCurrentAction(); await Wait.LatencySleep(); if (await Coroutines.InteractWith(obj)) { if (!await Wait.For(success, desc, 100, timeout)) { return(false); } GlobalLog.Debug($"[Interact] \"{name}\" has been successfully interacted."); return(true); } GlobalLog.Error($"[Interact] Fail to interact with \"{name}\"."); await Wait.SleepSafe(300, 500); return(false); }
private static async Task <bool> GoToHideoutViaCommand() { // Aggressive protection against exceptions, make sure this will never run unless everything is perfect. _goToHideoutViaCommandFailSafe = true; GlobalLog.Debug("[GoToHideoutViaCommand] Now going to hideout via chat command."); var areaHash = LokiPoe.LocalData.AreaHash; var err = LokiPoe.InGameState.ChatPanel.Commands.hideout(); if (err != LokiPoe.InGameState.ChatResult.None) { GlobalLog.Error($"[GoToHideoutViaCommand] Fail to use /hideout command. Fail-safe activated. Error: \"{err}\"."); return(false); } var changed = await Wait.ForAreaChange(areaHash); if (!changed) { GlobalLog.Error("[GoToHideoutViaCommand] Wait.ForAreaChange failed. Fail-safe activated."); } else { _goToHideoutViaCommandFailSafe = false; } return(changed); }
public static async Task LatencySleep() { var ms = Math.Max((int)(LatencyTracker.Current * 1.15), 25); GlobalLog.Debug($"[LatencySleep] {ms} ms."); await Coroutine.Sleep(ms); }
public static async Task <bool> PickItemToCursor(this InventoryControlWrapper inventory, bool rightClick = false) { var item = inventory.CustomTabItem; if (item == null) { GlobalLog.Error("[PickItemToCursor] Custom inventory control is empty."); return(false); } GlobalLog.Debug($"[PickItemToCursor] Now going to pick \"{item.Name}\" to cursor."); if (rightClick) { var err = inventory.UseItem(); if (err != UseItemResult.None) { GlobalLog.Error($"[PickItemToCursor] Fail to pick item to cursor. Error: \"{err}\"."); return(false); } } else { var err = inventory.Pickup(); if (err != PickupResult.None) { GlobalLog.Error($"[PickItemToCursor] Fail to pick item to cursor. Error: \"{err}\"."); return(false); } } return(await Wait.For(() => Cursor.Item != null, "item appear under cursor")); }
public static async Task <bool> OpenStashTab(string tabName) { if (!await OpenStash()) { return(false); } if (StashUi.TabControl.CurrentTabName != tabName) { GlobalLog.Debug($"[OpenStashTab] Now switching to tab \"{tabName}\"."); var id = StashUi.StashTabInfo.InventoryId; var err = StashUi.TabControl.SwitchToTabMouse(tabName); if (err != SwitchToTabResult.None) { GlobalLog.Error($"[OpenStashTab] Fail to switch to tab \"{tabName}\". Error \"{err}\"."); return(false); } if (!await Wait.For(() => StashUi.StashTabInfo != null && StashUi.StashTabInfo.InventoryId != id, "stash tab switching")) { return(false); } await Wait.SleepSafe(200); } return(true); }
public static async Task <bool> Interact(NetworkObject obj, int attempts) { if (obj == null) { GlobalLog.Error("[Interact] Object for interaction is null."); return(false); } var name = obj.Name; GlobalLog.Debug($"[Interact] Now going to interact with \"{name}\"."); for (int i = 1; i <= attempts; i++) { if (!LokiPoe.IsInGame || LokiPoe.Me.IsDead) { break; } await Coroutines.CloseBlockingWindows(); await Coroutines.FinishCurrentAction(); await Wait.LatencySleep(); if (await Coroutines.InteractWith(obj)) { GlobalLog.Debug($"[Interact] \"{name}\" has been successfully interacted."); return(true); } GlobalLog.Error($"[Interact] Fail to interact with \"{name}\". Attempt: {i}/{attempts}."); await Wait.SleepSafe(100, 200); } return(false); }
public static async Task ArtificialDelay() { var settings = Settings.Instance; var ms = LokiPoe.Random.Next(settings.MinArtificialDelay, settings.MaxArtificialDelay + 1); GlobalLog.Debug($"[ArtificialDelay] Now waiting for {ms} ms."); await Coroutine.Sleep(ms); }
public static async Task <bool> TpToTown(bool forceNewPortal = false, bool repeatUntilInTown = true) { if (ErrorManager.GetErrorCount("TpToTown") > 5) { GlobalLog.Debug("[TpToTown] We failed to take a portal to town more than 5 times. Now going to log out."); return(await Logout()); } GlobalLog.Debug("[TpToTown] Now going to open and take a portal to town."); var area = World.CurrentArea; if (area.IsTown || area.IsHideoutArea) { GlobalLog.Error("[TpToTown] We are already in town/hideout."); return(false); } if (!area.IsOverworldArea && !area.IsMap && !area.IsCorruptedArea && !area.IsMapRoom && !area.IsTempleOfAtzoatl) { GlobalLog.Warn($"[TpToTown] Cannot create portals in this area ({area.Name}). Now going to log out."); return(await Logout()); } Portal portal; if (forceNewPortal || (portal = PortalInRangeOf(70)) == null) { portal = await CreateTownPortal(); if (portal == null) { GlobalLog.Error("[TpToTown] Fail to create a new town portal. Now going to log out."); return(await Logout()); } } else { GlobalLog.Debug($"[TpToTown] There is a ready-to-use portal at a distance of {portal.Distance}. Now going to take it."); } if (!await TakePortal(portal)) { ErrorManager.ReportError("TpToTown"); return(false); } var newArea = World.CurrentArea; if (repeatUntilInTown && newArea.IsCombatArea) { GlobalLog.Debug($"[TpToTown] After taking a portal we appeared in another combat area ({newArea.Name}). Now calling TpToTown again."); return(await TpToTown(forceNewPortal)); } GlobalLog.Debug($"[TpToTown] We have been successfully teleported from \"{area.Name}\" to \"{newArea.Name}\"."); return(true); }
// Requires more work, "Fail to join any instances" case public static async Task <bool> ForAreaChangeV2(uint areaHash, string loadingAreaText) { bool isOnLoadingScreen = false; int timeout = 5000; var timer = Stopwatch.StartNew(); while (timer.ElapsedMilliseconds < timeout) { if (ExilePather.AreaHash != areaHash) { GlobalLog.Debug("[WaitForAreaChange] Area hash has been changed."); return(true); } if (LokiPoe.InGameState.IsEnteringAreaTextShown) { GlobalLog.Debug("[WaitForAreaChange] Entering area text is shown."); isOnLoadingScreen = true; break; } var text = LokiPoe.InGameState.EnteringAreaText; if (!string.IsNullOrEmpty(text) && text != loadingAreaText) { GlobalLog.Debug("[WaitForAreaChange] Entering area text has been changed."); isOnLoadingScreen = true; break; } await Coroutine.Sleep(50); GlobalLog.Debug($"[WaitForAreaChange] Waiting for loading screen ({Math.Round(timer.ElapsedMilliseconds / 1000f, 2)}/{timeout / 1000f})"); } if (!isOnLoadingScreen) { GlobalLog.Error("[WaitForAreaChange] Wait for loading screen timeout."); return(false); } timeout = 1000 * 60 * 5; timer = Stopwatch.StartNew(); while (timer.ElapsedMilliseconds < timeout) { if (ExilePather.AreaHash != areaHash) { return(true); } await Coroutine.Sleep(500); GlobalLog.Debug($"[WaitForAreaChange] Waiting for area hash change ({Math.Round(timer.ElapsedMilliseconds / 1000f, 2)}/{timeout / 1000f})"); } GlobalLog.Error("[WaitForAreaChange] Wait for area hash change timeout."); return(false); }
public static async Task <bool> Logout() { GlobalLog.Debug("[Logout] Now going to log out."); var err = LokiPoe.EscapeState.LogoutToTitleScreen(); if (err != LokiPoe.EscapeState.LogoutError.None) { GlobalLog.Error($"[Logout] Fail to log out. Error: \"{err}\"."); return(false); } return(await Wait.For(() => LokiPoe.IsInLoginScreen, "log out", 500, 5000)); }
public static async Task <bool> TakeTransition(AreaTransition transition, bool newInstance = false) { if (transition == null) { GlobalLog.Error("[TakeTransition] Transition object is null."); return(false); } var pos = transition.WalkablePosition(); var type = transition.TransitionType; GlobalLog.Debug($"[TakeTransition] Now going to enter \"{pos.Name}\"."); await pos.ComeAtOnce(); await Coroutines.FinishCurrentAction(); await Wait.SleepSafe(100); var hash = LokiPoe.LocalData.AreaHash; var myPos = LokiPoe.MyPosition; bool entered = newInstance ? await CreateNewInstance(transition) : await Interact(transition); if (!entered) { return(false); } if (type == TransitionTypes.Local) { if (!await Wait.For(() => myPos.Distance(LokiPoe.MyPosition) > 15, "local transition")) { return(false); } await Wait.SleepSafe(250); } else { if (!await Wait.ForAreaChange(hash)) { return(false); } } GlobalLog.Debug($"[TakeTransition] \"{pos.Name}\" has been successfully entered."); return(true); }
public static bool Towards(Vector2i pos, string destination) { if (LogInterval.Elapsed) { GlobalLog.Debug($"[MoveTowards] Moving towards {destination} at {pos} (distance: {LokiPoe.MyPosition.Distance(pos)})"); } if (!PlayerMoverManager.MoveTowards(pos)) { GlobalLog.Error($"[MoveTowards] Fail to move towards {destination} at {pos}"); return(false); } return(true); }
public static async Task <bool> FastMoveFromPremiumStashTab(InventoryControlWrapper control) { if (control == null) { GlobalLog.Error("[FastMoveFromPremiumStashTab] Inventory control is null."); return(false); } var item = control.CustomTabItem; if (item == null) { GlobalLog.Error("[FastMoveFromPremiumStashTab] Inventory control has no item."); return(false); } var itemName = item.Name; var stackCount = item.StackCount; var tabName = StashUi.TabControl.CurrentTabName; GlobalLog.Debug($"[FastMoveFromPremiumStashTab] Fast moving \"{itemName}\" from \"{tabName}\" tab."); var moved = control.FastMove(); if (moved != FastMoveResult.None) { GlobalLog.Error($"[FastMoveFromPremiumStashTab] Fast move error: \"{moved}\"."); return(false); } if (await Wait.For(() => { var i = control.CustomTabItem; return(i == null || i.StackCount < stackCount); }, "fast move")) { GlobalLog.Debug($"[FastMoveFromPremiumStashTab] \"{itemName}\" has been successfully fast moved from \"{tabName}\" tab."); if (Settings.Instance.ArtificialDelays) { await Wait.ArtificialDelay(); } return(true); } GlobalLog.Error($"[FastMoveFromPremiumStashTab] Fast move timeout for \"{itemName}\" in \"{tabName}\" tab."); return(false); }
public static async Task <bool> FastMoveToVendor(Vector2i itemPos) { var item = InventoryUi.InventoryControl_Main.Inventory.FindItemByPos(itemPos); if (item == null) { GlobalLog.Error($"[FastMoveToVendor] Fail to find item at {itemPos} in player's inventory."); return(false); } var itemName = item.FullName; GlobalLog.Debug($"[FastMoveToVendor] Fast moving \"{itemName}\" at {itemPos} from player's inventory."); var err = InventoryUi.InventoryControl_Main.FastMove(item.LocalId); if (err != FastMoveResult.None && err != FastMoveResult.ItemTransparent) { GlobalLog.Error($"[FastMoveToVendor] Fast move error: \"{err}\"."); return(false); } if (await Wait.For(() => { var movedItem = InventoryUi.InventoryControl_Main.Inventory.FindItemByPos(itemPos); if (movedItem == null) { GlobalLog.Error("[FastMoveToVendor] Unexpected error. Item became null instead of transparent."); return(false); } return(InventoryUi.InventoryControl_Main.IsItemTransparent(movedItem.LocalId)); }, "fast move")) { GlobalLog.Debug($"[FastMoveToVendor] \"{itemName}\" at {itemPos} has been successfully fast moved from player's inventory."); if (Settings.Instance.ArtificialDelays) { await Wait.ArtificialDelay(); } return(true); } GlobalLog.Error($"[FastMoveToVendor] Fast move timeout for \"{itemName}\" at {itemPos} in player's inventory."); return(false); }
public void MarkTabAsFull(string tabName, string itemMetadata) { var tab = FullTabs.Find(t => t.Name == tabName); if (tab == null) { FullTabs.Add(new FullTabInfo(tabName, itemMetadata)); GlobalLog.Debug($"[MarkTabAsFull] New tab added. Name: \"{tabName}\". Metadata: \"{itemMetadata ?? "null"}\"."); } else if (itemMetadata != null) { tab.ControlsMetadata.Add(itemMetadata); GlobalLog.Debug($"[MarkTabAsFull] Existing tab updated. Name: \"{tabName}\". Metadata: \"{itemMetadata}\"."); } else { GlobalLog.Debug($"[MarkTabAsFull] \"{tabName}\" is already marked as full."); } }
public static async Task <bool> FastMoveFromStashTab(Vector2i itemPos) { var tabName = StashUi.TabControl.CurrentTabName; var item = StashUi.InventoryControl.Inventory.FindItemByPos(itemPos); if (item == null) { GlobalLog.Error($"[FastMoveFromStashTab] Fail to find item at {itemPos} in \"{tabName}\" tab."); return(false); } var itemName = item.FullName; var stackCount = item.StackCount; GlobalLog.Debug($"[FastMoveFromStashTab] Fast moving \"{itemName}\" at {itemPos} from \"{tabName}\" tab."); var err = StashUi.InventoryControl.FastMove(item.LocalId); if (err != FastMoveResult.None) { GlobalLog.Error($"[FastMoveFromStashTab] Fast move error: \"{err}\"."); return(false); } if (await Wait.For(() => { var i = StashUi.InventoryControl.Inventory.FindItemByPos(itemPos); return(i == null || i.StackCount < stackCount); }, "fast move")) { GlobalLog.Debug($"[FastMoveFromStashTab] \"{itemName}\" at {itemPos} has been successfully fast moved from \"{tabName}\" tab."); if (Settings.Instance.ArtificialDelays) { await Wait.ArtificialDelay(); } return(true); } GlobalLog.Error($"[FastMoveFromStashTab] Fast move timeout for \"{itemName}\" at {itemPos} in \"{tabName}\" tab."); return(false); }
public static async Task <bool> FindTabWithCurrency(string name) { var tabs = new List <string>(Settings.Instance.GetTabsForCurrency(name)); // Moving currently opened stash tab to the front of the list, so bot does search in it first if (tabs.Count > 1 && StashUi.IsOpened) { var currentTab = StashUi.StashTabInfo.DisplayName; var index = tabs.IndexOf(currentTab); if (index > 0) { var tab = tabs[index]; tabs.RemoveAt(index); tabs.Insert(0, tab); } } foreach (var tab in tabs) { GlobalLog.Debug($"[FindTabWithCurrency] Looking for \"{name}\" in \"{tab}\" tab."); if (!await OpenStashTab(tab)) { ErrorManager.ReportError(); continue; } if (StashUi.StashTabInfo.IsPublicFlagged) { GlobalLog.Error($"[FindTabWithCurrency] Stash tab \"{tab}\" is public. Cannot use currency from it."); continue; } var amount = GetCurrencyAmountInStashTab(name); if (amount > 0) { GlobalLog.Debug($"[FindTabWithCurrency] Found {amount} \"{name}\" in \"{tab}\" tab."); return(true); } GlobalLog.Debug($"[FindTabWithCurrency] There are no \"{name}\" in \"{tab}\" tab."); } return(false); }
public static async Task <bool> For(Func <bool> condition, string desc, Func <int> step, int timeout = 3000) { if (condition()) { return(true); } var timer = Stopwatch.StartNew(); while (timer.ElapsedMilliseconds < timeout) { await StuckDetectionSleep(step()); GlobalLog.Debug($"[WaitFor] Waiting for {desc} ({Math.Round(timer.ElapsedMilliseconds / 1000f, 2)}/{timeout / 1000f})"); if (condition()) { return(true); } } GlobalLog.Error($"[WaitFor] Wait for {desc} timeout."); return(false); }
public static async Task <bool> TryTo(Func <Task <bool> > action, string desc, int attempts, int interval = 1000) { for (int i = 1; i <= attempts; ++i) { if (!LokiPoe.IsInGame || LokiPoe.Me.IsDead) { break; } if (desc != null) { GlobalLog.Debug($"[TryTo] {desc} attempt: {i}/{attempts}"); } if (await action()) { return(true); } await Wait.SleepSafe(interval); } return(false); }
public static async Task <bool> FastMoveFromInventory(Vector2i itemPos) { var item = InventoryUi.InventoryControl_Main.Inventory.FindItemByPos(itemPos); if (item == null) { GlobalLog.Error($"[FastMoveFromInventory] Fail to find item at {itemPos} in player's inventory."); return(false); } var itemName = item.FullName; GlobalLog.Debug($"[FastMoveFromInventory] Fast moving \"{itemName}\" at {itemPos} from player's inventory."); var err = InventoryUi.InventoryControl_Main.FastMove(item.LocalId); if (err != FastMoveResult.None) { GlobalLog.Error($"[FastMoveFromInventory] Fast move error: \"{err}\"."); return(false); } if (await Wait.For(() => InventoryUi.InventoryControl_Main.Inventory.FindItemByPos(itemPos) == null, "fast move")) { GlobalLog.Debug($"[FastMoveFromInventory] \"{itemName}\" at {itemPos} has been successfully fast moved from player's inventory."); if (Settings.Instance.ArtificialDelays) { await Wait.ArtificialDelay(); } return(true); } GlobalLog.Error($"[FastMoveFromInventory] Fast move timeout for \"{itemName}\" at {itemPos} in player's inventory."); return(false); }
private static async Task <bool> GoToHideoutViaWaypoint() { if (!LokiPoe.InGameState.WorldUi.IsOpened) { if (!await OpenWaypoint()) { GlobalLog.Error("[GoToHideoutViaWaypoint] Fail to open a waypoint."); return(false); } } GlobalLog.Debug("[GoToHideoutViaWaypoint] Now going to take a waypoint to hideout."); var areaHash = LokiPoe.LocalData.AreaHash; var err = LokiPoe.InGameState.WorldUi.GoToHideout(); if (err != LokiPoe.InGameState.TakeWaypointResult.None) { GlobalLog.Error($"[GoToHideoutViaWaypoint] Fail to take a waypoint to hideout. Error: \"{err}\"."); return(false); } return(await Wait.ForAreaChange(areaHash)); }
public static async Task <bool> TakeWaypoint(AreaInfo area, bool newInstance = false) { if (!LokiPoe.InGameState.WorldUi.IsOpened) { if (!await OpenWaypoint()) { GlobalLog.Error("[TakeWaypoint] Fail to open a waypoint."); return(false); } } GlobalLog.Debug($"[TakeWaypoint] Now going to take a waypoint to {area}"); var areaHash = LokiPoe.LocalData.AreaHash; var err = LokiPoe.InGameState.WorldUi.TakeWaypoint(area.Id, newInstance); if (err != LokiPoe.InGameState.TakeWaypointResult.None) { GlobalLog.Error($"[TakeWaypoint] Fail to take a waypoint to {area}. Error: \"{err}\"."); return(false); } return(await Wait.ForAreaChange(areaHash)); }
public static async Task <WithdrawResult> WithdrawCurrency(string name) { foreach (var tab in Settings.Instance.GetTabsForCurrency(name)) { GlobalLog.Debug($"[WithdrawCurrency] Looking for \"{name}\" in \"{tab}\" tab."); if (!await OpenStashTab(tab)) { return(WithdrawResult.Error); } var tabType = StashUi.StashTabInfo.TabType; if (tabType == InventoryTabType.Currency) { var control = GetControlWithCurrency(name); if (control == null) { GlobalLog.Debug($"[WithdrawCurrency] There are no \"{name}\" in \"{tab}\" tab."); continue; } if (!await FastMoveFromPremiumStashTab(control)) { return(WithdrawResult.Error); } GlobalLog.Debug($"[WithdrawCurrency] \"{name}\" have been successfully taken from \"{tab}\" tab."); return(WithdrawResult.Success); } if (tabType == InventoryTabType.Essence) { var control = StashUi.EssenceTab.NonEssences.FirstOrDefault(c => c.CustomTabItem?.Name == name); if (control == null) { GlobalLog.Debug($"[WithdrawCurrency] There are no \"{name}\" in \"{tab}\" tab."); continue; } if (!await FastMoveFromPremiumStashTab(control)) { return(WithdrawResult.Error); } GlobalLog.Debug($"[WithdrawCurrency] \"{name}\" have been successfully taken from \"{tab}\" tab."); return(WithdrawResult.Success); } if (tabType == InventoryTabType.Divination || tabType == InventoryTabType.Map || tabType == InventoryTabType.Fragment) { GlobalLog.Error($"[WithdrawCurrency] Unsupported behavior. Current stash tab is {tabType}."); continue; } var item = StashTabItems.Where(i => i.Name == name).OrderByDescending(i => i.StackCount).FirstOrDefault(); if (item == null) { GlobalLog.Debug($"[WithdrawCurrency] There are no \"{name}\" in \"{tab}\" tab."); continue; } if (!await FastMoveFromStashTab(item.LocationTopLeft)) { return(WithdrawResult.Error); } GlobalLog.Debug($"[WithdrawCurrency] \"{name}\" have been successfully taken from \"{tab}\" tab."); return(WithdrawResult.Success); } return(WithdrawResult.Unavailable); }
public static async Task <bool> PlaceItemFromCursor(this InventoryControlWrapper inventory, Vector2i pos) { var cursorItem = Cursor.Item; if (cursorItem == null) { GlobalLog.Error("[PlaceItemFromCursor] Cursor item is null."); return(false); } GlobalLog.Debug($"[PlaceItemFromCursor] Now going to place \"{cursorItem.Name}\" from cursor to {pos}."); //apply item on another item, if we are in VirtualUse mode if (Cursor.Mode == LokiPoe.InGameState.CursorItemModes.VirtualUse) { var destItem = inventory.Inventory.FindItemByPos(pos); if (destItem == null) { GlobalLog.Error("[PlaceItemFromCursor] Destination item is null."); return(false); } int destItemId = destItem.LocalId; var applied = inventory.ApplyCursorTo(destItem.LocalId); if (applied != ApplyCursorResult.None) { GlobalLog.Error($"[PlaceItemFromCursor] Fail to place item from cursor. Error: \"{applied}\"."); return(false); } //wait for destination item change, it cannot become null, ID should change return(await Wait.For(() => { var item = inventory.Inventory.FindItemByPos(pos); return item != null && item.LocalId != destItemId; }, "destination item change")); } //in other cases, place item to empty inventory slot or swap it with another item int cursorItemId = cursorItem.LocalId; var placed = inventory.PlaceCursorInto(pos.X, pos.Y, true); if (placed != PlaceCursorIntoResult.None) { GlobalLog.Error($"[PlaceItemFromCursor] Fail to place item from cursor. Error: \"{placed}\"."); return(false); } //wait for cursor item change, if we placed - it should become null, if we swapped - ID should change if (!await Wait.For(() => { var item = Cursor.Item; return(item == null || item.LocalId != cursorItemId); }, "cursor item change")) { return(false); } if (Settings.Instance.ArtificialDelays) { await Wait.ArtificialDelay(); } return(true); }