예제 #1
0
        private static async Task <bool> DepositLoop(int index)
        {
            string name = ItemSortStatus.GetByIndex(index).Name;

            if (ItemSortStatus.GetByIndex(ItemSortStatus.PlayerInventoryIndex).AllBelong())
            {
                LogCritical($"We tried depositing to {name} but everything in the Player Inventory belongs there...?");
                return(false);
            }
            if (BagsFreeSlotCount(index) == 0)
            {
                LogCritical($"We tried depositing to {name} but their inventory was full!");
                return(false);
            }
            Log($"Depositing items to {name}...");
            var moveCount = 0;

            foreach (BagSlot bagSlot in GeneralFunctions.MainBagsFilledSlots())
            {
                if (BagsFreeSlotCount(index) == 0)
                {
                    LogCritical($"Stopping deposits to {name} because their inventory is full!");
                    return(false);
                }
                var sortInfo = ItemSortStatus.GetSortInfo(bagSlot.TrueItemId);
                if (sortInfo.SortStatus(index) == SortStatus.BelongsInIndex)
                {
                    bool moveResult;
                    if (index == ItemSortStatus.SaddlebagInventoryIndex)
                    {
                        moveResult = await bagSlot.TryAddToSaddlebag(bagSlot.Count, AutoRetainerSortSettings.Instance.ItemMoveWaitMs);
                    }
                    else
                    {
                        moveResult = await bagSlot.TryEntrustToRetainer(bagSlot.Count, AutoRetainerSortSettings.Instance.ItemMoveWaitMs);
                    }

                    if (moveResult)
                    {
                        LogSuccess($"Deposited {sortInfo.Name}.");
                        if (sortInfo.ItemInfo.Unique)
                        {
                            ItemSortStatus.PlayerInventoryUniques.Remove(sortInfo.TrueItemId);
                            ItemSortStatus.TryingToMoveUniques.Remove(sortInfo.TrueItemId);
                        }

                        moveCount++;
                    }
                    else
                    {
                        LogCritical($"Something went wrong with depositing {sortInfo.Name}, it's still in the same slot!");
                    }
                }
            }

            return(moveCount > 0);
        }
예제 #2
0
        private static bool ShouldSortLoop(int index)
        {
            if (ItemSortStatus.FilledAndSortedInventories.Contains(index))
            {
                return(false);
            }
            if (ItemSortStatus.FilledAndSortedInventories.Contains(ItemSortStatus.PlayerInventoryIndex))
            {
                return(false);
            }
            if (ItemSortStatus.PlayerInventory.DestinationCountsByIndex().ContainsKey(index))
            {
                return(true);
            }

            return(!ItemSortStatus.GetByIndex(index).AllBelong());
        }
예제 #3
0
        private static async Task DepositFromPlayer()
        {
            if (ItemSortStatus.PlayerInventory.AllBelong())
            {
                LogCritical("Everything in our player inventory belongs there already! How am I supposed to deposit items like this?");
                return;
            }

            var orderedSortStatusCounts = ItemSortStatus.PlayerInventory.DestinationCountsByIndex()
                                          .OrderByDescending(x => x.Value);

            foreach (var indexCountPair in orderedSortStatusCounts)
            {
                if (ItemSortStatus.GetByIndex(indexCountPair.Key).FreeSlots == 0)
                {
                    continue;
                }
                await SortLoop(indexCountPair.Key);
            }
        }
예제 #4
0
        private async Task <bool> Run()
        {
            if (AutoRetainerSortSettings.Instance.InventoryOptions.Count == 0)
            {
                LogCritical("You don't have any inventories (or sorting rules for them) added yet! Go check the settings?");
                TreeRoot.Stop("No sort settings.");
                return(false);
            }

            if (!ItemSortStatus.AnyRulesExist())
            {
                LogCritical("You don't have any sorting rules set up... maybe go hit the Auto-Setup button?");
                TreeRoot.Stop("No sort settings.");
                return(false);
            }

            LogCritical($"The journey begins! {Strings.AutoSetup_CacheAdvice}");
            await GeneralFunctions.StopBusy(true, true, false);

            var retData = await HelperFunctions.GetOrderedRetainerArray(true);

            if (retData.Length == 0)
            {
                LogCritical("No retainers. Exiting.");
                TreeRoot.Stop("No retainer data found.");
                return(false);
            }

            foreach (var pair in AutoRetainerSortSettings.Instance.InventoryOptions)
            {
                if (pair.Key < 0)
                {
                    continue;
                }

                if (pair.Key >= retData.Length)
                {
                    LogCritical($"{pair.Value.Name}'s index of {pair.Key.ToString()} doesn't exist in retainer data.");
                    TreeRoot.Stop("Invalid index.");
                    return(false);
                }

                if (!retData[pair.Key].Active)
                {
                    LogCritical($"{pair.Value.Name} isn't an active retainer!");
                    TreeRoot.Stop("Retainer inactive.");
                    return(false);
                }
            }

            ItemSortStatus.ItemSortInfoCache.Clear();

            await ItemFinder.FlashSaddlebags();

            ItemSortStatus.UpdateFromCache(retData);

            if (AutoRetainerSortSettings.Instance.PrintMoves)
            {
                alreadyPrintedUniques.Clear();
                foreach (CachedInventory cachedInventory in ItemSortStatus.GetAllInventories())
                {
                    PrintMoves(cachedInventory.Index);
                }
            }

            while (ItemSortStatus.AnyUnsorted())
            {
                if (ItemSortStatus.FilledAndSortedInventories.Contains(ItemSortStatus.PlayerInventoryIndex))
                {
                    LogCritical("Everything currently in the player's inventory belongs there, but it's full! Can't move items like this. I quit.");
                    break;
                }

                await DepositFromPlayer();
                await RetrieveFromInventories();

                await Coroutine.Sleep(250);

                ItemSortStatus.UpdateFromCache(retData);
                await Coroutine.Sleep(250);
            }

            foreach (CachedInventory cachedInventory in ItemSortStatus.GetAllInventories())
            {
                foreach (ItemSortInfo sortInfo in cachedInventory.ItemCounts.Select(x => ItemSortStatus.GetSortInfo(x.Key)))
                {
                    int[] localIndexCache = sortInfo.MatchingIndexes.ToArray();
                    if (localIndexCache.Length == 0)
                    {
                        continue;
                    }
                    if (sortInfo.SortStatus(cachedInventory.Index) == SortStatus.MoveButUnable)
                    {
                        if (ItemSortStatus.FilledAndSortedInventories.Contains(cachedInventory.Index) || (cachedInventory.FreeSlots == 0 && cachedInventory.AllBelong()))
                        {
                            LogCritical($"We want to move {sortInfo.Name} to {ItemSortStatus.GetByIndex(localIndexCache[0]).Name} but it's full and everything there belongs. Too bad!");
                        }
                        else if (sortInfo.ItemInfo.Unique)
                        {
                            if (localIndexCache.Length == 1)
                            {
                                LogCritical($"We want to move {sortInfo.Name} to {ItemSortStatus.GetByIndex(localIndexCache[0]).Name} but it's unique and that inventory already has one. Too bad!");
                            }
                            else
                            {
                                LogCritical($"We want to move {sortInfo.Name} but it's unique and all inventories set for it already have one. Too bad!");
                            }
                        }
                        else
                        {
                            LogCritical($"We want to move {sortInfo.Name} to {ItemSortStatus.GetByIndex(localIndexCache[0]).Name} " +
                                        $"but it can't be moved there for... some reason. IndexStatus: {sortInfo.IndexStatus(cachedInventory.Index).ToString()}");
                        }
                    }
                }
            }

            await GeneralFunctions.ExitRetainer(true);

            if (AutoRetainerSortSettings.Instance.AutoGenLisbeth)
            {
                string lisbethSettingsPath = LisbethRuleGenerator.GetSettingsPath();
                if (!string.IsNullOrEmpty(lisbethSettingsPath))
                {
                    LisbethRuleGenerator.PopulateSettings(lisbethSettingsPath);
                    LogSuccess("Auto-populated Lisbeth's retainer item rules!");
                    MessageBox.Show(
                        Strings.LisbethRules_RestartRB,
                        "Just Letting You Know...",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                }
                else
                {
                    LogCritical("Couldn't find Lisbeth settings path! We won't auto-generate retainer rules.");
                }
            }

            TreeRoot.Stop("Done sorting inventories.");
            return(false);
        }
예제 #5
0
        private static async Task <bool> RetrieveLoop(int index)
        {
            string name = ItemSortStatus.GetByIndex(index).Name;

            if (ItemSortStatus.GetByIndex(index).AllBelong())
            {
                LogCritical($"We tried to retrieve items from {name} but everything in their inventory already belongs there...?");
                return(false);
            }
            if (InventoryManager.FreeSlots == 0)
            {
                LogCritical($"We tried to retrieve items from {name} but our player inventory is full!");
                return(false);
            }

            Log($"Retrieving items from {name}...");
            var movedCount = 0;

            foreach (BagSlot bagSlot in InventoryManager.GetBagsByInventoryBagId(BagIdsByIndex(index)).SelectMany(x => x.FilledSlots))
            {
                if (InventoryManager.FreeSlots == 0)
                {
                    LogCritical($"Stopping retrievals from {name} because our player inventory is full!");
                    return(false);
                }
                var sortInfo = ItemSortStatus.GetSortInfo(bagSlot.TrueItemId);
                if (sortInfo.ItemInfo.Unique && InventoryManager.FilledSlots.Any(x => x.TrueItemId == sortInfo.TrueItemId))
                {
                    continue;
                }
                if (sortInfo.SortStatus(index) == SortStatus.Move)
                {
                    bool moveResult;
                    if (index == ItemSortStatus.SaddlebagInventoryIndex)
                    {
                        moveResult = await bagSlot.TryRemoveFromSaddlebag(bagSlot.Count, AutoRetainerSortSettings.Instance.ItemMoveWaitMs);
                    }
                    else
                    {
                        moveResult = await bagSlot.TryRetrieveFromRetainer(bagSlot.Count, AutoRetainerSortSettings.Instance.ItemMoveWaitMs);
                    }

                    if (moveResult)
                    {
                        string belongsInName = ItemSortStatus.GetByIndex(sortInfo.MatchingIndexes[0]).Name;
                        if (sortInfo.ItemInfo.Unique)
                        {
                            var localIndexCache = sortInfo.MatchingIndexes.ToArray();
                            for (int i = 0; i < localIndexCache.Length; i++)
                            {
                                var cachedInventory = ItemSortStatus.GetByIndex(localIndexCache[i]);
                                if (cachedInventory.ItemCounts.ContainsKey(sortInfo.TrueItemId))
                                {
                                    continue;
                                }
                                belongsInName = cachedInventory.Name;
                                break;
                            }
                        }
                        LogSuccess($"Retrieved {sortInfo.Name}. It belongs in {belongsInName}.");
                        if (sortInfo.ItemInfo.Unique)
                        {
                            ItemSortStatus.PlayerInventoryUniques.Add(sortInfo.TrueItemId);
                            ItemSortStatus.TryingToMoveUniques.Remove(sortInfo.TrueItemId);
                        }

                        movedCount++;
                    }
                    else
                    {
                        LogCritical($"Something went wrong with retrieving {sortInfo.Name}, it's still in the same slot!");
                    }
                }
            }

            return(movedCount > 0);
        }
예제 #6
0
        private static async Task SortLoop(int index)
        {
            LogDebug($"We're gonna go try to sort {ItemSortStatus.GetByIndex(index).Name}!");

            if (index < ItemSortStatus.PlayerInventoryIndex)
            {
                LogCritical($"Tried to sort index of #{index.ToString()} but that's out of range...");
                return;
            }

            if (index < ItemSortStatus.SaddlebagInventoryIndex)
            {
                LogCritical($"Tried to sort the player's inventory, but we can't do anything with that alone...");
                return;
            }

            if (InventoryManager.FreeSlots == 0 && ItemSortStatus.GetByIndex(index).FreeSlots == 0)
            {
                LogCritical($"Both our player inventory and {ItemSortStatus.GetByIndex(index).Name} are completely full! Can't move anything around like this.");
                return;
            }

            bool openingSaddlebag = index == ItemSortStatus.SaddlebagInventoryIndex;
            await GeneralFunctions.ExitRetainer(openingSaddlebag);

            if (openingSaddlebag)
            {
                await InventoryBuddy.Instance.Open();

                if (!InventoryBuddy.Instance.IsOpen)
                {
                    LogCritical($"We were unable to open the saddlebag!");
                    return;
                }
            }
            else
            {
                await RetainerRoutine.SelectRetainer(index);

                RetainerTasks.OpenInventory();
                await Coroutine.Wait(3000, RetainerTasks.IsInventoryOpen);

                if (!RetainerTasks.IsInventoryOpen())
                {
                    LogCritical($"We were unable to open Retainer #{index.ToString()}!");
                    return;
                }
            }

            await Coroutine.Sleep(200);

            await CombineStacks(GeneralFunctions.MainBagsFilledSlots());
            await CombineStacks(InventoryManager.GetBagsByInventoryBagId(BagIdsByIndex(index)).SelectMany(x => x.FilledSlots));

            while (ShouldSortLoop(index))
            {
                bool depositResult = await DepositLoop(index);

                UpdatePlayerInventory();
                UpdateOpenedInventory(index);

                bool retrieveResult = await RetrieveLoop(index);

                UpdatePlayerInventory();
                UpdateOpenedInventory(index);

                await Coroutine.Sleep(250);

                if (!depositResult || !retrieveResult)
                {
                    break;
                }
            }

            if (openingSaddlebag)
            {
                InventoryBuddy.Instance.Close();
            }
            else
            {
                await GeneralFunctions.ExitRetainer();
            }

            await Coroutine.Sleep(250);
        }
예제 #7
0
        private static void PrintMoves(int index)
        {
            foreach (ItemSortInfo sortInfo in ItemSortStatus.GetByIndex(index).ItemCounts.Select(x => ItemSortStatus.GetSortInfo(x.Key)))
            {
                if (sortInfo.SortStatus(index) != SortStatus.Move)
                {
                    continue;
                }
                if (alreadyPrintedUniques.Contains(sortInfo.TrueItemId))
                {
                    continue;
                }

                if (sortInfo.ItemInfo.Unique)
                {
                    alreadyPrintedUniques.Add(sortInfo.TrueItemId);
                }

                int[]         localIndexCache = sortInfo.MatchingIndexes.ToArray();
                StringBuilder sb = new StringBuilder();
                sb.Append($"We want to move {sortInfo.Name} from {ItemSortStatus.GetByIndex(index).Name}");
                bool isFull = localIndexCache.All(x => ItemSortStatus.FilledAndSortedInventories.Contains(x));
                if (sortInfo.ItemInfo.Unique)
                {
                    var uniqueNoSpace = true;
                    for (int i = 0; i < localIndexCache.Length; i++)
                    {
                        if (ItemSortStatus.GetByIndex(localIndexCache[i]).ItemCounts.ContainsKey(sortInfo.TrueItemId))
                        {
                            continue;
                        }
                        sb.Append($" to {ItemSortStatus.GetByIndex(localIndexCache[i]).Name}");
                        uniqueNoSpace = false;
                        break;
                    }
                    isFull = uniqueNoSpace;
                }
                else
                {
                    sb.Append($" to {ItemSortStatus.GetByIndex(localIndexCache[0]).Name}");
                }

                if (sortInfo.ItemInfo.Unique && isFull)
                {
                    sb.Append("... but it's unique and there's no available space.");
                }
                else if (isFull)
                {
                    sb.Append("... but it's full.");
                }
                else
                {
                    sb.Append(".");
                }

                if (isFull)
                {
                    LogCritical(sb.ToString());
                }
                else
                {
                    Log(sb.ToString());
                }
            }
        }