예제 #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
        public static async Task CombineStacks(IEnumerable <BagSlot> bagSlotsEnumerable)
        {
            var bagSlots = bagSlotsEnumerable.ToArray();

            if (!bagSlots.Any())
            {
                return;
            }

            var groupedSlots = bagSlots
                               .Where(x => x.IsValid && x.IsFilled && (x.Item?.StackSize ?? 0) > 1)
                               .GroupBy(x => x.TrueItemId)
                               .Where(x => x.Count(slot => slot.Count < slot.Item.StackSize) > 1);

            foreach (var slotGrouping in groupedSlots)
            {
                if (slotGrouping.Key > ItemSortInfo.CollectableOffset)
                {
                    continue;
                }
                LogSuccess($"Combining stacks of {ItemSortStatus.GetSortInfo(slotGrouping.Key).Name}");

                var bagSlotArray = slotGrouping.OrderByDescending(x => x.Count).ToArray();
                int moveToIndex  = Array.FindIndex(bagSlotArray, x => x.Count < x.Item.StackSize);
                if (moveToIndex < 0)
                {
                    continue;
                }
                for (int i = bagSlotArray.Length - 1; i > moveToIndex; i--)
                {
                    var moveFromSlot = bagSlotArray[i];
                    if (moveFromSlot == null || !moveFromSlot.IsValid || !moveFromSlot.IsFilled)
                    {
                        continue;
                    }

                    uint curCount = bagSlotArray[moveToIndex].Count;
                    bool result   = moveFromSlot.Move(bagSlotArray[moveToIndex]);
                    if (result)
                    {
                        await Coroutine.Wait(3000, () => curCount != bagSlotArray[moveToIndex].Count);
                    }

                    await Coroutine.Yield();

                    BagSlot curMoveTo = bagSlotArray[moveToIndex];
                    if (curMoveTo.Count >= curMoveTo.Item.StackSize)
                    {
                        moveToIndex = Array.FindIndex(bagSlotArray, x => x.IsValid && x.IsFilled && x.Count < x.Item.StackSize);
                    }
                }
            }
        }
        private void AddNewItem_Click(object sender, EventArgs e)
        {
            var toAddIds = new HashSet <uint>();

            using (AddNewItemForm newItemForm = new AddNewItemForm())
            {
                DialogResult dr = newItemForm.ShowDialog(this);
                if (dr != DialogResult.OK)
                {
                    return;
                }

                SearchResult selectedItem = newItemForm.SelectedSearchResult;
                if (selectedItem == null || selectedItem.RawItemId == 0)
                {
                    return;
                }

                if (newItemForm.ModifierNone)
                {
                    toAddIds.Add(selectedItem.RawItemId);
                }
                else if (newItemForm.ModifierHQ)
                {
                    toAddIds.Add(selectedItem.RawItemId + QualityOffset);
                }
                else if (newItemForm.ModifierCollectable)
                {
                    toAddIds.Add(selectedItem.RawItemId + CollectableOffset);
                }
                else
                {
                    return;
                }

                if (newItemForm.IncludeHQ)
                {
                    toAddIds.Add(selectedItem.RawItemId + QualityOffset);
                }
                if (newItemForm.IncludeCollectable)
                {
                    toAddIds.Add(selectedItem.RawItemId + CollectableOffset);
                }
            }

            foreach (uint toAddId in toAddIds)
            {
                ItemSortInfo sortInfo  = ItemSortStatus.GetSortInfo(toAddId);
                var          shouldAdd = true;
                foreach (var indexInfoPair in AutoRetainerSortSettings.Instance.InventoryOptions)
                {
                    if (indexInfoPair.Key == _index)
                    {
                        continue;
                    }
                    if (!indexInfoPair.Value.ContainsItem(sortInfo))
                    {
                        continue;
                    }
                    if (sortInfo.ItemInfo.Unique)
                    {
                        continue;
                    }

                    DialogResult dr = MessageBox.Show(
                        string.Format(Strings.AddNewItem_AlreadyExists_Warning, indexInfoPair.Value.Name, sortInfo.Name, indexInfoPair.Value.Name, _sortInfo.Name),
                        Strings.WarningCaption,
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Warning);

                    if (dr == DialogResult.Yes)
                    {
                        indexInfoPair.Value.SpecificItems.Remove(sortInfo);
                    }
                    else
                    {
                        shouldAdd = false;
                        break;
                    }
                }

                if (!shouldAdd)
                {
                    continue;
                }
                AutoRetainerSort.LogSuccess($"Added {sortInfo.Name} to {_sortInfo.Name}!");
                _bsItems.Add(sortInfo);
            }

            AutoRetainerSortSettings.Instance.Save();
        }
예제 #4
0
        public static void PopulateSettings(string settingsPath)
        {
            if (string.IsNullOrEmpty(settingsPath))
            {
                AutoRetainerSort.LogCritical("Provided Lisbeth settings path is invalid!");
                return;
            }

            JObject settingsJObject         = GetJObject(settingsPath);
            LisbethRetainerRules knownRules = new LisbethRetainerRules(settingsJObject);

            foreach (var indexInfoPair in AutoRetainerSortSettings.Instance.InventoryOptions)
            {
                if (!knownRules.RulesByIndex.ContainsKey(indexInfoPair.Key))
                {
                    continue;
                }
                var ruleList = knownRules.RulesByIndex[indexInfoPair.Key];
                foreach (uint itemId in indexInfoPair.Value.SpecificItems.Select(x => x.RawItemId).Distinct())
                {
                    ruleList.Add(new LisbethRetainerRules.ItemRule(itemId));
                }
            }

            foreach (CachedInventory cachedInventory in ItemSortStatus.GetAllInventories())
            {
                if (!knownRules.RulesByIndex.ContainsKey(cachedInventory.Index))
                {
                    continue;
                }
                var ruleList = knownRules.RulesByIndex[cachedInventory.Index];
                foreach (ItemSortInfo sortInfo in cachedInventory.ItemCounts.Select(x => ItemSortStatus.GetSortInfo(x.Key)).Distinct())
                {
                    if (sortInfo.ItemInfo.Unique || sortInfo.ItemInfo.StackSize <= 1)
                    {
                        continue;
                    }
                    ruleList.Add(new LisbethRetainerRules.ItemRule(sortInfo.RawItemId));
                }
            }

            SetRules(settingsJObject, knownRules);

            using (StreamWriter outputFile = new StreamWriter(settingsPath, false))
            {
                outputFile.Write(JsonConvert.SerializeObject(settingsJObject, Formatting.None));
            }
        }
예제 #5
0
        private void AutoSetup_Click(object sender, EventArgs e)
        {
            if (!AutoRetainerSortSettings.Instance.InventoryOptions.ContainsKey(ItemSortStatus.PlayerInventoryIndex))
            {
                DialogResult dr = MessageBox.Show(
                    "It looks like you don't have the player inventory added to the indexes... somehow. Do you want me to re-add that for you?",
                    "Um.",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Warning
                    );

                if (dr == DialogResult.Yes)
                {
                    AutoRetainerSortSettings.Instance.InventoryOptions.Add(ItemSortStatus.PlayerInventoryIndex, new InventorySortInfo("Player Inventory"));
                }
            }

            if (!AutoRetainerSortSettings.Instance.InventoryOptions.ContainsKey(ItemSortStatus.SaddlebagInventoryIndex))
            {
                DialogResult dr = MessageBox.Show(
                    "It looks like you don't have the chocobo saddlebag added to the indexes. Do you want me to re-add that for you?",
                    "Hey Listen!",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Information
                    );

                if (dr == DialogResult.Yes)
                {
                    AutoRetainerSortSettings.Instance.InventoryOptions.Add(ItemSortStatus.SaddlebagInventoryIndex, new InventorySortInfo("Chocobo Saddlebag"));
                }
            }

            MessageBox.Show(
                Strings.AutoSetup_CacheAdvice,
                "Careful!",
                MessageBoxButtons.OK,
                MessageBoxIcon.Information);

            DialogResult warningResult = MessageBox.Show(
                Strings.AutoSetup_OverwriteWarning,
                "Warning!",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Warning);

            if (warningResult == DialogResult.No)
            {
                return;
            }

            bool conflictUnsorted = MessageBox.Show(
                Strings.AutoSetup_ConflictQuestion,
                "Conflict?",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question) == DialogResult.Yes;

            var newInventorySetup = AutoRetainerSortSettings.Instance.InventoryOptions;

            foreach (InventorySortInfo inventorySortInfo in newInventorySetup.Values)
            {
                inventorySortInfo.SortTypes.Clear();
            }

            var orderedRetainerList = RetainerList.Instance.OrderedRetainerList;

            for (var i = 0; i < orderedRetainerList.Length; i++)
            {
                if (newInventorySetup.ContainsKey(i))
                {
                    continue;
                }
                RetainerInfo retInfo = orderedRetainerList[i];
                if (!retInfo.Active)
                {
                    continue;
                }

                newInventorySetup.Add(i, new InventorySortInfo(retInfo.Name));
            }

            AutoRetainerSortSettings.Instance.InventoryOptions = newInventorySetup;

            ItemSortStatus.UpdateFromCache(orderedRetainerList);

            var sortTypeCounts = new Dictionary <SortType, Dictionary <int, int> >();

            foreach (SortType sortType in Enum.GetValues(typeof(SortType)).Cast <SortType>())
            {
                sortTypeCounts[sortType] = new Dictionary <int, int>();
            }

            foreach (CachedInventory cachedInventory in ItemSortStatus.GetAllInventories())
            {
                foreach (SortType sortType in cachedInventory.ItemCounts.Select(x => ItemSortStatus.GetSortInfo(x.Key).SortType))
                {
                    var indexCountDic = sortTypeCounts[sortType];
                    if (indexCountDic.ContainsKey(cachedInventory.Index))
                    {
                        indexCountDic[cachedInventory.Index]++;
                    }
                    else
                    {
                        indexCountDic.Add(cachedInventory.Index, 1);
                    }
                }
            }

            foreach (var typeDicPair in sortTypeCounts)
            {
                SortType sortType   = typeDicPair.Key;
                int      indexCount = typeDicPair.Value.Keys.Count;
                if (indexCount == 0)
                {
                    continue;
                }
                if (indexCount > 1 && conflictUnsorted)
                {
                    continue;
                }

                int desiredIndex = typeDicPair.Value.OrderByDescending(x => x.Value).First().Key;
                AutoRetainerSortSettings.Instance.InventoryOptions[desiredIndex].SortTypes.Add(new SortTypeWithCount(sortType));
            }

            ResetBindingSource();
            AutoRetainerSortSettings.Instance.Save();
            AutoRetainerSort.LogSuccess("Auto-Setup done!");
        }
예제 #6
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);
        }
예제 #7
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);
        }
예제 #8
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());
                }
            }
        }