diff --git a/ARDiscard/Configuration.cs b/ARDiscard/Configuration.cs index 50049f1..5371652 100644 --- a/ARDiscard/Configuration.cs +++ b/ARDiscard/Configuration.cs @@ -26,6 +26,7 @@ internal sealed class Configuration : IPluginConfiguration public sealed class ArmouryConfiguration { public bool DiscardFromArmouryChest { get; set; } = false; + public bool CheckMainHandOffHand { get; set; } = false; public bool CheckLeftSideGear { get; set; } = false; public bool CheckRightSideGear { get; set; } = false; public int MaximumGearItemLevel { get; set; } = 45; diff --git a/ARDiscard/GameData/InternalConfiguration.cs b/ARDiscard/GameData/InternalConfiguration.cs index 48be626..b7186fa 100644 --- a/ARDiscard/GameData/InternalConfiguration.cs +++ b/ARDiscard/GameData/InternalConfiguration.cs @@ -29,6 +29,8 @@ internal static class InternalConfiguration .ToList() .AsReadOnly(); + public static readonly IList UltimateWeapons = new List(); + /// /// Items that are unique/untradeable, but should still be possible to discard. This is moreso because /// 99% of the unique/untradeable items should NOT be selectable for discard, but these are OK. diff --git a/ARDiscard/GameData/InventoryUtils.cs b/ARDiscard/GameData/InventoryUtils.cs index 0a83969..8aa7494 100644 --- a/ARDiscard/GameData/InventoryUtils.cs +++ b/ARDiscard/GameData/InventoryUtils.cs @@ -18,6 +18,12 @@ internal sealed class InventoryUtils InventoryType.Inventory4 }; + private static readonly InventoryType[] MainHandOffHandInventoryTypes = + { + InventoryType.ArmoryMainHand, + InventoryType.ArmoryOffHand, + }; + private static readonly InventoryType[] LeftSideGearInventoryTypes = { InventoryType.ArmoryHead, @@ -60,20 +66,12 @@ internal sealed class InventoryUtils if (_configuration.Armoury.DiscardFromArmouryChest) { var gearsetItems = GetAllGearsetItems(); - - if (_configuration.Armoury.CheckLeftSideGear) - { - foreach (InventoryType inventoryType in LeftSideGearInventoryTypes) - toDiscard.AddRange(GetItemsToDiscard(inventoryManager, inventoryType, itemCounts, - gearsetItems)); - } - - if (_configuration.Armoury.CheckRightSideGear) - { - foreach (InventoryType inventoryType in RightSideGearInventoryTypes) - toDiscard.AddRange(GetItemsToDiscard(inventoryManager, inventoryType, itemCounts, - gearsetItems)); - } + toDiscard.AddRange(GetArmouryItemsToDiscard(_configuration.Armoury.CheckMainHandOffHand, inventoryManager, + MainHandOffHandInventoryTypes, itemCounts, gearsetItems)); + toDiscard.AddRange(GetArmouryItemsToDiscard(_configuration.Armoury.CheckLeftSideGear, inventoryManager, + LeftSideGearInventoryTypes, itemCounts, gearsetItems)); + toDiscard.AddRange(GetArmouryItemsToDiscard(_configuration.Armoury.CheckRightSideGear, inventoryManager, + RightSideGearInventoryTypes, itemCounts, gearsetItems)); } return toDiscard @@ -81,6 +79,18 @@ internal sealed class InventoryUtils .ToList(); } + private unsafe IEnumerable GetArmouryItemsToDiscard(bool condition, InventoryManager* inventoryManager, + InventoryType[] inventoryTypes, Dictionary itemCounts, List? gearsetItems) + { + if (condition) + { + foreach (InventoryType inventoryType in inventoryTypes) + return GetItemsToDiscard(inventoryManager, inventoryType, itemCounts, gearsetItems); + } + + return new List(); + } + public unsafe InventoryItem* GetNextItemToDiscard(ItemFilter? itemFilter) { List allItemsToDiscard = GetAllItemsToDiscard(); @@ -106,10 +116,12 @@ internal sealed class InventoryUtils else itemCounts[item->ItemID] = item->Quantity; - if (InternalConfiguration.BlacklistedItems.Contains(item->ItemID)) + if (InternalConfiguration.BlacklistedItems.Contains(item->ItemID) || + InternalConfiguration.UltimateWeapons.Contains(item->ItemID)) continue; - if (!_itemCache.TryGetItem(item->ItemID, out ItemCache.CachedItemInfo? itemInfo) || !itemInfo.CanBeDiscarded()) + if (!_itemCache.TryGetItem(item->ItemID, out ItemCache.CachedItemInfo? itemInfo) || + !itemInfo.CanBeDiscarded()) continue; // no info, who knows what that item is // skip gear if we're unable to load gearsets or it is used in a gearset @@ -177,7 +189,8 @@ internal sealed class InventoryUtils public unsafe void Discard(InventoryItem* item) { - if (InternalConfiguration.BlacklistedItems.Contains(item->ItemID)) + if (InternalConfiguration.BlacklistedItems.Contains(item->ItemID) || + InternalConfiguration.UltimateWeapons.Contains(item->ItemID)) throw new Exception($"Can't discard {item->ItemID}"); AgentInventoryContext.Instance()->DiscardItem(item, item->Container, item->Slot, 0); diff --git a/ARDiscard/GameData/ItemCache.cs b/ARDiscard/GameData/ItemCache.cs index 6e13428..94bac4f 100644 --- a/ARDiscard/GameData/ItemCache.cs +++ b/ARDiscard/GameData/ItemCache.cs @@ -33,6 +33,11 @@ internal sealed class ItemCache UiCategoryName = item.ItemUICategory.Value!.Name.ToString(), EquipSlotCategory = item.EquipSlotCategory.Row, }; + + if (item is { Rarity: 3, MateriaSlotCount: 3, RowId: < 33154 or > 33358 }) + { + InternalConfiguration.UltimateWeapons.Add(item.RowId); + } } foreach (var shopItem in dataManager.GetExcelSheet()!) @@ -115,15 +120,12 @@ internal sealed class ItemCache public bool CanBeDiscarded() { - if (InternalConfiguration.BlacklistedItems.Contains(ItemId)) + if (InternalConfiguration.BlacklistedItems.Contains(ItemId) || InternalConfiguration.UltimateWeapons.Contains(ItemId)) return false; if (UiCategory is UiCategories.Currency or UiCategories.Crystals or UiCategories.Unobtainable) return false; - if (EquipSlotCategory is 1 or 2 or 13 or 14) - return false; - if (InternalConfiguration.WhitelistedItems.Contains(ItemId)) return true; diff --git a/ARDiscard/Windows/ConfigWindow.cs b/ARDiscard/Windows/ConfigWindow.cs index ace758c..d9b1bea 100644 --- a/ARDiscard/Windows/ConfigWindow.cs +++ b/ARDiscard/Windows/ConfigWindow.cs @@ -283,6 +283,13 @@ internal sealed class ConfigWindow : LImGui.LWindow ImGui.BeginDisabled(!discardFromArmouryChest); ImGui.Indent(30); + bool mainHandOffHand = _configuration.Armoury.CheckMainHandOffHand; + if (ImGui.Checkbox("Discard when items are found in Main Hand/Off Hand (Weapons and Tools)", ref mainHandOffHand)) + { + _configuration.Armoury.CheckMainHandOffHand = mainHandOffHand; + Save(); + } + bool leftSideGear = _configuration.Armoury.CheckLeftSideGear; if (ImGui.Checkbox("Discard when items are found in Head/Body/Hands/Legs/Feet", ref leftSideGear)) {