Example #1
0
        /// <summary>
        /// This functions is meant to use an item on another one, for identification, chancing, anything you can think about
        /// It also supports the +X% quality using stones/scraps
        /// </summary>
        /// <param name="sourceWrapper">The source (inventory) that's holding the item meant to be used</param>
        /// <param name="sourceItem">The item meant to be used</param>
        /// <param name="destinationWrapper">The source (inventory) holding the item meant to be altered</param>
        /// <param name="destinationItem">The item menant to be altered</param>
        /// <param name="d">Delegate/Condition to stop using item</param>
        /// <returns>ApplyCursorResult enum entry</returns>
        public static async Task <ApplyCursorResult> UseItemOnItem(InventoryControlWrapper sourceWrapper, Item sourceItem, InventoryControlWrapper destinationWrapper, Item destinationItem, StopUsingDelegate d = null)
        {
            // If Any of these args are null, throw an application-level exception
            if (sourceWrapper == null)
            {
                throw new ArgumentNullException(nameof(sourceWrapper));
            }
            if (sourceItem == null)
            {
                throw new ArgumentNullException(nameof(sourceItem));
            }
            if (destinationWrapper == null)
            {
                throw new ArgumentNullException(nameof(destinationWrapper));
            }
            if (destinationItem == null)
            {
                throw new ArgumentNullException(nameof(destinationItem));
            }

            // If the item is not modifiable, prevent the logic to be executed
            if (destinationItem.IsCorrupted || destinationItem.IsMirrored)
            {
                CommunityLib.Log.DebugFormat("[CommunityLib] We can\'t alter the item (Corrupted/Mirrored). UnsupportedItem");
                return(ApplyCursorResult.UnsupportedItem);
            }

            if (destinationItem.HasSkillGemsEquipped && sourceItem.FullName == "Jeweller's Orb")
            {
                CommunityLib.Log.DebugFormat("[CommunityLib] We can't change sockets on the item (Has skill gems in it). UnsupportedItem");
                return(ApplyCursorResult.UnsupportedItem);
            }

            var onCursor = sourceWrapper.UseItem(sourceItem.LocalId);

            // We assume it's currency stash tab, do not use LocalId with it
            if (onCursor == UseItemResult.Unsupported)
            {
                CommunityLib.Log.DebugFormat("[CommunityLib] Failed to use item on item. Unsupported");
                onCursor = sourceWrapper.UseItem();
            }

            await Coroutines.LatencyWait();

            // If something else than None is returned, the item can't be put on cursor properly
            if (onCursor != UseItemResult.None)
            {
                if (!await Inputs.WaitForCursorToHaveItem())
                {
                    CommunityLib.Log.ErrorFormat($"[CommunityLib] Failed to use item on item. OnCursor: {onCursor}. Returning item not found");
                    return(ApplyCursorResult.ItemNotFound);
                }
            }

            await Coroutines.LatencyWait();

            // First, we put the item on cursor to start applying
            var err = InventoryControlWrapper.BeginApplyCursor(true);

            if (err != ApplyCursorResult.None)
            {
                CommunityLib.Log.Error($"[CommunityLib] Error returned for BeginApplyCursor : {err}");
                return(ApplyCursorResult.ProcessHookManagerNotEnabled);
            }

            // We store the destination item's location to make sure it has been applied or the delegate (lower in the code) is valid
            var itemLocation = destinationItem.LocationTopLeft;
            int useCount     = 0;

            while (true)
            {
                var initialId = destinationItem.LocalId;

                // Apply item on cursor to the destination item
                err = destinationWrapper.ApplyCursorTo(destinationItem.LocalId);
                //Destination is in utility currency slot?
                if (err == ApplyCursorResult.Unsupported)
                {
                    err = destinationWrapper.ApplyCursorTo();
                }

                // If the error is different of None, break the execution and return the error
                if (err != ApplyCursorResult.None)
                {
                    break;
                }

                // Check if the item has been modified on memory-side
                if (!await WaitForItemToChange(destinationWrapper, initialId))
                {
                    break;
                }

                await Coroutines.LatencyWait();

                //await Coroutines.ReactionWait();

                // If the delegate is null, that means our processing is done, break the loop to return None
                if (d == null)
                {
                    break;
                }

                // We increment usecount to make it usable in delegate
                useCount++;

                // Refresh item to test the delegate (or condition)
                destinationItem = destinationWrapper.Inventory.GetItemAtLocation(itemLocation.X, itemLocation.Y);
                if (d.Invoke(destinationItem, useCount))
                {
                    break;
                }
            }

            // End up the item application
            var err2 = InventoryControlWrapper.EndApplyCursor();
            await Coroutine.Yield();

            await Inputs.WaitForCursorToBeEmpty();

            // IF an error is returned, let caller know
            if (err2 != ApplyCursorResult.None)
            {
                CommunityLib.Log.Error($"[CommunityLib] Error returned for EndApplyCursor : {err2}");
                return(ApplyCursorResult.ProcessHookManagerNotEnabled);
            }

            if (err != ApplyCursorResult.None)
            {
                CommunityLib.Log.ErrorFormat($"[CommunityLib] Failed to use item on item. Error: {err}");
            }
            return(err);
        }
Example #2
0
        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);
        }