Compare commits

..

No commits in common. "master" and "v5.3" have entirely different histories.
master ... v5.3

20 changed files with 130 additions and 237 deletions

View File

@ -990,7 +990,7 @@ csharp_space_around_binary_operators = before_and_after
csharp_using_directive_placement = outside_namespace:silent csharp_using_directive_placement = outside_namespace:silent
csharp_prefer_simple_using_statement = true:suggestion csharp_prefer_simple_using_statement = true:suggestion
csharp_prefer_braces = true:silent csharp_prefer_braces = true:silent
csharp_style_namespace_declarations = file_scoped:silent csharp_style_namespace_declarations = block_scoped:silent
csharp_style_prefer_method_group_conversion = true:silent csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_top_level_statements = true:silent csharp_style_prefer_top_level_statements = true:silent
csharp_style_prefer_primary_constructors = true:suggestion csharp_style_prefer_primary_constructors = true:suggestion

View File

@ -1,15 +1,66 @@
<Project Sdk="Dalamud.NET.Sdk/9.0.2"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Version>6.3</Version> <TargetFramework>net8.0-windows</TargetFramework>
<Version>5.3</Version>
<LangVersion>12</LangVersion>
<Nullable>enable</Nullable>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<OutputPath>dist</OutputPath> <OutputPath>dist</OutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DebugType>portable</DebugType>
<PathMap Condition="$(SolutionDir) != ''">$(SolutionDir)=X:\</PathMap>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<DebugType>portable</DebugType>
</PropertyGroup> </PropertyGroup>
<Import Project="..\LLib\LLib.targets"/> <PropertyGroup>
<Import Project="..\LLib\RenameZip.targets"/> <DalamudLibPath>$(appdata)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
</PropertyGroup>
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))'">
<DalamudLibPath>$(DALAMUD_HOME)/</DalamudLibPath>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\AutoRetainerAPI\AutoRetainerAPI\AutoRetainerAPI.csproj"/> <ProjectReference Include="..\AutoRetainerAPI\AutoRetainerAPI\AutoRetainerAPI.csproj"/>
<ProjectReference Include="..\ECommons\ECommons\ECommons.csproj"/> <ProjectReference Include="..\ECommons\ECommons\ECommons.csproj"/>
<ProjectReference Include="..\LLib\LLib.csproj"/> <ProjectReference Include="..\LLib\LLib.csproj"/>
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.12"/>
</ItemGroup>
<ItemGroup>
<Reference Include="Dalamud">
<HintPath>$(DalamudLibPath)Dalamud.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="ImGui.NET">
<HintPath>$(DalamudLibPath)ImGui.NET.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Lumina">
<HintPath>$(DalamudLibPath)Lumina.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Lumina.Excel">
<HintPath>$(DalamudLibPath)Lumina.Excel.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>$(DalamudLibPath)Newtonsoft.Json.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="FFXIVClientStructs">
<HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
<Target Name="RenameLatestZip" AfterTargets="PackagePlugin">
<Exec Command="rename $(OutDir)$(AssemblyName)\latest.zip $(AssemblyName)-$(Version).zip"/>
</Target>
</Project> </Project>

View File

@ -2,13 +2,7 @@
"Name": "Discard Helper", "Name": "Discard Helper",
"Author": "Liza Carvelli", "Author": "Liza Carvelli",
"Punchline": "Discard items automatically via a command or as a post-venture task for AutoRetainer", "Punchline": "Discard items automatically via a command or as a post-venture task for AutoRetainer",
"Description": "Small plugin to help keep your inventory organized (especially when automating retainers or submersibles) by discarding items you don't want (e.g. Stuffed Alphas)", "Description": "",
"RepoUrl": "https://git.carvel.li/liza/ARDiscard", "RepoUrl": "https://git.carvel.li/liza/ARDiscard",
"IconUrl": "https://plugins.carvel.li/icons/ARDiscard.png", "IconUrl": "https://plugins.carvel.li/icons/ARDiscard.png"
"Tags": [
"autoretainer",
"automation",
"discard",
"yeet"
]
} }

View File

@ -11,7 +11,7 @@ using Dalamud.Memory;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using ECommons; using ECommons;
using ECommons.Automation.NeoTaskManager; using ECommons.Automation;
using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Component.GUI; using FFXIVClientStructs.FFXIV.Component.GUI;
@ -27,7 +27,7 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
private readonly ConfigWindow _configWindow; private readonly ConfigWindow _configWindow;
private readonly DiscardWindow _discardWindow; private readonly DiscardWindow _discardWindow;
private readonly IDalamudPluginInterface _pluginInterface; private readonly DalamudPluginInterface _pluginInterface;
private readonly IChatGui _chatGui; private readonly IChatGui _chatGui;
private readonly IClientState _clientState; private readonly IClientState _clientState;
private readonly IPluginLog _pluginLog; private readonly IPluginLog _pluginLog;
@ -35,7 +35,6 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
private readonly ICommandManager _commandManager; private readonly ICommandManager _commandManager;
private readonly InventoryUtils _inventoryUtils; private readonly InventoryUtils _inventoryUtils;
private readonly IconCache _iconCache; private readonly IconCache _iconCache;
private readonly GameStrings _gameStrings;
private readonly AutoRetainerApi _autoRetainerApi; private readonly AutoRetainerApi _autoRetainerApi;
[SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "Obsolete in ECommons")] [SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "Obsolete in ECommons")]
@ -46,15 +45,14 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
private DateTime _cancelDiscardAfter = DateTime.MaxValue; private DateTime _cancelDiscardAfter = DateTime.MaxValue;
[SuppressMessage("Maintainability", "CA1506")] public AutoDiscardPlogon(DalamudPluginInterface pluginInterface, ICommandManager commandManager, IChatGui chatGui,
public AutoDiscardPlogon(IDalamudPluginInterface pluginInterface, ICommandManager commandManager, IChatGui chatGui,
IDataManager dataManager, IClientState clientState, ICondition condition, IPluginLog pluginLog, IDataManager dataManager, IClientState clientState, ICondition condition, IPluginLog pluginLog,
IGameGui gameGui, ITextureProvider textureProvider, IContextMenu contextMenu) IGameGui gameGui, ITextureProvider textureProvider, IContextMenu contextMenu)
{ {
ArgumentNullException.ThrowIfNull(dataManager); ArgumentNullException.ThrowIfNull(dataManager);
_pluginInterface = pluginInterface; _pluginInterface = pluginInterface;
_configuration = (Configuration?)_pluginInterface.GetPluginConfig() ?? Configuration.CreateNew(); _configuration = (Configuration?)_pluginInterface.GetPluginConfig() ?? new Configuration();
MigrateConfiguration(_configuration); MigrateConfiguration(_configuration);
_chatGui = chatGui; _chatGui = chatGui;
_clientState = clientState; _clientState = clientState;
@ -80,10 +78,8 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
listManager.FinishInitialization(); listManager.FinishInitialization();
_iconCache = new IconCache(textureProvider); _iconCache = new IconCache(textureProvider);
_gameStrings = new GameStrings(dataManager, pluginLog);
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw; _pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
_pluginInterface.UiBuilder.OpenMainUi += OpenDiscardUi;
_pluginInterface.UiBuilder.OpenConfigUi += OpenConfigUi; _pluginInterface.UiBuilder.OpenConfigUi += OpenConfigUi;
_discardWindow = new(_inventoryUtils, itemCache, _iconCache, clientState, condition, _configuration); _discardWindow = new(_inventoryUtils, itemCache, _iconCache, clientState, condition, _configuration);
@ -97,8 +93,8 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
_discardWindow.OpenConfigurationClicked += (_, _) => OpenConfigUi(); _discardWindow.OpenConfigurationClicked += (_, _) => OpenConfigUi();
_discardWindow.DiscardAllClicked += (_, filter) => _discardWindow.DiscardAllClicked += (_, filter) =>
{ {
_taskManager?.Abort(); _taskManager!.Abort();
_taskManager?.Enqueue(() => DiscardNextItem(PostProcessType.ManuallyStarted, filter)); _taskManager.Enqueue(() => DiscardNextItem(PostProcessType.ManuallyStarted, filter));
}; };
ECommonsMain.Init(_pluginInterface, this); ECommonsMain.Init(_pluginInterface, this);
@ -124,14 +120,6 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
configuration.Version = 2; configuration.Version = 2;
_pluginInterface.SavePluginConfig(configuration); _pluginInterface.SavePluginConfig(configuration);
} }
if (configuration.Version == 2)
{
if (!configuration.BlacklistedItems.Contains(2820))
configuration.BlacklistedItems.Add(2820);
configuration.Version = 3;
_pluginInterface.SavePluginConfig(configuration);
}
} }
private void CheckRetainerPostProcess(string retainerName) => private void CheckRetainerPostProcess(string retainerName) =>
@ -189,9 +177,7 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
_taskManager.Enqueue(() => DiscardNextItem(PostProcessType.ManuallyStarted, ItemFilter.None)); _taskManager.Enqueue(() => DiscardNextItem(PostProcessType.ManuallyStarted, ItemFilter.None));
} }
private void OpenDiscardWindow(string command, string arguments) => OpenDiscardUi(); private void OpenDiscardWindow(string command, string arguments)
private void OpenDiscardUi()
{ {
_discardWindow.IsOpen = !_discardWindow.IsOpen; _discardWindow.IsOpen = !_discardWindow.IsOpen;
} }
@ -212,11 +198,11 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
var (inventoryType, slot) = (nextItem->Container, nextItem->Slot); var (inventoryType, slot) = (nextItem->Container, nextItem->Slot);
_pluginLog.Information( _pluginLog.Information(
$"Discarding itemId {nextItem->ItemId} in slot {nextItem->Slot} of container {nextItem->Container}."); $"Discarding itemId {nextItem->ItemID} in slot {nextItem->Slot} of container {nextItem->Container}.");
_inventoryUtils.Discard(nextItem); _inventoryUtils.Discard(nextItem);
_cancelDiscardAfter = DateTime.Now.AddSeconds(15); _cancelDiscardAfter = DateTime.Now.AddSeconds(15);
_taskManager.EnqueueDelay(20); _taskManager.DelayNext(20);
_taskManager.Enqueue(() => ConfirmDiscardItem(type, itemFilter, inventoryType, slot)); _taskManager.Enqueue(() => ConfirmDiscardItem(type, itemFilter, inventoryType, slot));
} }
} }
@ -231,7 +217,7 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
((AddonSelectYesno*)addon)->YesButton->AtkComponentBase.SetEnabledState(true); ((AddonSelectYesno*)addon)->YesButton->AtkComponentBase.SetEnabledState(true);
addon->FireCallbackInt(0); addon->FireCallbackInt(0);
_taskManager.EnqueueDelay(20); _taskManager.DelayNext(20);
_taskManager.Enqueue(() => ContinueAfterDiscard(type, itemFilter, inventoryType, slot)); _taskManager.Enqueue(() => ContinueAfterDiscard(type, itemFilter, inventoryType, slot));
} }
else else
@ -246,14 +232,14 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
{ {
_pluginLog.Information( _pluginLog.Information(
$"Addon is not (yet) visible, still trying to discard item in slot {slot} in inventory {inventoryType}"); $"Addon is not (yet) visible, still trying to discard item in slot {slot} in inventory {inventoryType}");
_taskManager.EnqueueDelay(100); _taskManager.DelayNext(100);
_taskManager.Enqueue(() => ConfirmDiscardItem(type, itemFilter, inventoryType, slot)); _taskManager.Enqueue(() => ConfirmDiscardItem(type, itemFilter, inventoryType, slot));
} }
else else
{ {
_pluginLog.Information( _pluginLog.Information(
$"Addon is not (yet) visible, but slot or inventory type changed, retrying from start"); $"Addon is not (yet) visible, but slot or inventory type changed, retrying from start");
_taskManager.EnqueueDelay(100); _taskManager.DelayNext(100);
_taskManager.Enqueue(() => DiscardNextItem(type, itemFilter)); _taskManager.Enqueue(() => DiscardNextItem(type, itemFilter));
} }
} }
@ -279,14 +265,14 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
{ {
_pluginLog.Verbose( _pluginLog.Verbose(
$"ContinueAfterDiscard: Waiting for server response until {_cancelDiscardAfter}"); $"ContinueAfterDiscard: Waiting for server response until {_cancelDiscardAfter}");
_taskManager.EnqueueDelay(20); _taskManager.DelayNext(20);
_taskManager.Enqueue(() => ContinueAfterDiscard(type, itemFilter, inventoryType, slot)); _taskManager.Enqueue(() => ContinueAfterDiscard(type, itemFilter, inventoryType, slot));
} }
} }
else else
{ {
_pluginLog.Information("ContinueAfterDiscard: Discovered different item to discard"); _pluginLog.Information("ContinueAfterDiscard: Discovered different item to discard");
_taskManager.Enqueue(() => DiscardNextItem(type, itemFilter)); _taskManager.EnqueueImmediate(() => DiscardNextItem(type, itemFilter));
} }
} }
@ -324,7 +310,6 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
_iconCache.Dispose(); _iconCache.Dispose();
_pluginInterface.UiBuilder.OpenConfigUi -= OpenConfigUi; _pluginInterface.UiBuilder.OpenConfigUi -= OpenConfigUi;
_pluginInterface.UiBuilder.OpenMainUi -= OpenDiscardUi;
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw; _pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
_commandManager.RemoveHandler("/discard"); _commandManager.RemoveHandler("/discard");
_commandManager.RemoveHandler("/discardall"); _commandManager.RemoveHandler("/discardall");
@ -344,7 +329,7 @@ public sealed class AutoDiscardPlogon : IDalamudPlugin
var textNode = addon->UldManager.NodeList[15]->GetAsAtkTextNode(); var textNode = addon->UldManager.NodeList[15]->GetAsAtkTextNode();
var text = MemoryHelper.ReadSeString(&textNode->NodeText).ExtractText(); var text = MemoryHelper.ReadSeString(&textNode->NodeText).ExtractText();
_pluginLog.Information($"YesNo prompt: {text}"); _pluginLog.Information($"YesNo prompt: {text}");
if (_gameStrings.DiscardItem.IsMatch(text) || _gameStrings.DiscardCollectable.IsMatch(text)) if (text.StartsWith("Discard", StringComparison.Ordinal))
{ {
return addon; return addon;
} }

View File

@ -5,7 +5,7 @@ namespace ARDiscard;
internal sealed class Configuration : IPluginConfiguration internal sealed class Configuration : IPluginConfiguration
{ {
public int Version { get; set; } = 3; public int Version { get; set; } = 2;
public bool RunAfterVenture { get; set; } public bool RunAfterVenture { get; set; }
public bool RunBeforeLogout { get; set; } public bool RunBeforeLogout { get; set; }
public List<uint> DiscardingItems { get; set; } = new(); public List<uint> DiscardingItems { get; set; } = new();
@ -45,12 +45,4 @@ internal sealed class Configuration : IPluginConfiguration
public bool GroupByCategory { get; set; } = true; public bool GroupByCategory { get; set; } = true;
public bool ShowIcons { get; set; } = true; public bool ShowIcons { get; set; } = true;
} }
public static Configuration CreateNew()
{
return new Configuration
{
BlacklistedItems = [2820]
};
}
} }

View File

@ -49,7 +49,7 @@ internal sealed class ContextMenuIntegration : IDisposable
_contextMenu.OnMenuOpened += MenuOpened; _contextMenu.OnMenuOpened += MenuOpened;
} }
private void MenuOpened(IMenuOpenedArgs args) private void MenuOpened(MenuOpenedArgs args)
{ {
if (!IsEnabled()) if (!IsEnabled())
return; return;
@ -106,7 +106,7 @@ internal sealed class ContextMenuIntegration : IDisposable
} }
} }
private void AddToDiscardList(IMenuItemClickedArgs args) => private void AddToDiscardList(MenuItemClickedArgs args) =>
AddToDiscardList(((MenuTargetInventory)args.Target).TargetItem!.Value.ItemId); AddToDiscardList(((MenuTargetInventory)args.Target).TargetItem!.Value.ItemId);
private void AddToDiscardList(uint itemId) private void AddToDiscardList(uint itemId)
@ -126,7 +126,7 @@ internal sealed class ContextMenuIntegration : IDisposable
} }
} }
private void RemoveFromDiscardList(IMenuItemClickedArgs args) => private void RemoveFromDiscardList(MenuItemClickedArgs args) =>
RemoveFromDiscardList(((MenuTargetInventory)args.Target).TargetItem!.Value.ItemId); RemoveFromDiscardList(((MenuTargetInventory)args.Target).TargetItem!.Value.ItemId);
private void RemoveFromDiscardList(uint itemId) private void RemoveFromDiscardList(uint itemId)

View File

@ -12,7 +12,7 @@ internal sealed class AutoDiscardIpc
private readonly Configuration _configuration; private readonly Configuration _configuration;
private readonly ICallGateProvider<IReadOnlySet<uint>> _getItemsToDiscard; private readonly ICallGateProvider<IReadOnlySet<uint>> _getItemsToDiscard;
public AutoDiscardIpc(IDalamudPluginInterface pluginInterface, Configuration configuration) public AutoDiscardIpc(DalamudPluginInterface pluginInterface, Configuration configuration)
{ {
_configuration = configuration; _configuration = configuration;

View File

@ -1,21 +0,0 @@
using System.Data;
using System.Text.RegularExpressions;
using Dalamud.Plugin.Services;
using LLib;
using Lumina.Excel.GeneratedSheets;
namespace ARDiscard.GameData;
internal sealed class GameStrings
{
public GameStrings(IDataManager dataManager, IPluginLog pluginLog)
{
DiscardItem = dataManager.GetRegex<Addon>(110, addon => addon.Text, pluginLog)
?? throw new ConstraintException($"Unable to resolve {nameof(DiscardItem)}");
DiscardCollectable = dataManager.GetRegex<Addon>(153, addon => addon.Text, pluginLog)
?? throw new ConstraintException($"Unable to resolve {nameof(DiscardCollectable)}");
}
public Regex DiscardItem { get; }
public Regex DiscardCollectable { get; }
}

View File

@ -78,7 +78,7 @@ internal sealed class InventoryUtils
} }
return toDiscard return toDiscard
.Where(x => itemCounts[x.InventoryItem->ItemId] < _configuration.IgnoreItemCountWhenAbove) .Where(x => itemCounts[x.InventoryItem->ItemID] < _configuration.IgnoreItemCountWhenAbove)
.ToList(); .ToList();
} }
@ -99,7 +99,7 @@ internal sealed class InventoryUtils
{ {
List<ItemWrapper> allItemsToDiscard = GetAllItemsToDiscard(); List<ItemWrapper> allItemsToDiscard = GetAllItemsToDiscard();
ItemWrapper? toDiscard = allItemsToDiscard.FirstOrDefault(x => ItemWrapper? toDiscard = allItemsToDiscard.FirstOrDefault(x =>
itemFilter == null || itemFilter.ItemIds.Contains(x.InventoryItem->ItemId)); itemFilter == null || itemFilter.ItemIds.Contains(x.InventoryItem->ItemID));
return toDiscard != null ? toDiscard.InventoryItem : null; return toDiscard != null ? toDiscard.InventoryItem : null;
} }
@ -113,36 +113,36 @@ internal sealed class InventoryUtils
for (int i = 0; i < container->Size; ++i) for (int i = 0; i < container->Size; ++i)
{ {
var item = container->GetInventorySlot(i); var item = container->GetInventorySlot(i);
if (item != null && item->ItemId != 0) if (item != null && item->ItemID != 0)
{ {
if (itemCounts.TryGetValue(item->ItemId, out uint itemCount)) if (itemCounts.TryGetValue(item->ItemID, out uint itemCount))
itemCounts[item->ItemId] = itemCount + item->Quantity; itemCounts[item->ItemID] = itemCount + item->Quantity;
else else
itemCounts[item->ItemId] = item->Quantity; itemCounts[item->ItemID] = item->Quantity;
if (_listManager.IsBlacklisted(item->ItemId)) if (_listManager.IsBlacklisted(item->ItemID))
continue; continue;
if (!_itemCache.TryGetItem(item->ItemId, out ItemCache.CachedItemInfo? itemInfo) || if (!_itemCache.TryGetItem(item->ItemID, out ItemCache.CachedItemInfo? itemInfo) ||
!itemInfo.CanBeDiscarded(_listManager)) !itemInfo.CanBeDiscarded(_listManager))
continue; // no info, who knows what that item is 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 // skip gear if we're unable to load gearsets or it is used in a gearset
if (itemInfo.EquipSlotCategory > 0 && (gearsetItems == null || gearsetItems.Contains(item->ItemId))) if (itemInfo.EquipSlotCategory > 0 && (gearsetItems == null || gearsetItems.Contains(item->ItemID)))
continue; continue;
if (itemInfo is { EquipSlotCategory: > 0, CanBeBoughtFromCalamitySalvager: false } && if (itemInfo is { EquipSlotCategory: > 0, CanBeBoughtFromCalamitySalvager: false } &&
itemInfo.ILvl >= _configuration.Armoury.MaximumGearItemLevel) itemInfo.ILvl >= _configuration.Armoury.MaximumGearItemLevel)
continue; continue;
if (_configuration.IgnoreItemWithSignature && item->CrafterContentId != 0) if (_configuration.IgnoreItemWithSignature && item->CrafterContentID != 0)
continue; continue;
//PluginLog.Verbose($"{i} → {item->ItemID}"); //PluginLog.Verbose($"{i} → {item->ItemID}");
if (_configuration.DiscardingItems.Contains(item->ItemId)) if (_configuration.DiscardingItems.Contains(item->ItemID))
{ {
_pluginLog.Verbose( _pluginLog.Verbose(
$"Found item {item->ItemId} to discard in inventory {inventoryType} in slot {i}"); $"Found item {item->ItemID} to discard in inventory {inventoryType} in slot {i}");
toDiscard.Add(new ItemWrapper { InventoryItem = item }); toDiscard.Add(new ItemWrapper { InventoryItem = item });
} }
} }
@ -169,23 +169,23 @@ internal sealed class InventoryUtils
{ {
var gearsetItems = new[] var gearsetItems = new[]
{ {
gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.MainHand), gearset->MainHand,
gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.OffHand), gearset->OffHand,
gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.Head), gearset->Head,
gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.Body), gearset->Body,
gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.Hands), gearset->Hands,
gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.Legs), gearset->Legs,
gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.Feet), gearset->Feet,
gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.Ears), gearset->Ears,
gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.Neck), gearset->Neck,
gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.Wrists), gearset->Wrists,
gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.RingLeft), gearset->RingRight,
gearset->GetItem(RaptureGearsetModule.GearsetItemIndex.RingRight), gearset->RingLeft,
}; };
foreach (var gearsetItem in gearsetItems) foreach (var gearsetItem in gearsetItems)
{ {
if (gearsetItem.ItemId != 0) if (gearsetItem.ItemID != 0)
allGearsetItems.Add(gearsetItem.ItemId); allGearsetItems.Add(gearsetItem.ItemID);
} }
} }
} }
@ -195,8 +195,8 @@ internal sealed class InventoryUtils
public unsafe void Discard(InventoryItem* item) public unsafe void Discard(InventoryItem* item)
{ {
if (_listManager.IsBlacklisted(item->ItemId)) if (_listManager.IsBlacklisted(item->ItemID))
throw new ArgumentException($"Can't discard {item->ItemId}", nameof(item)); throw new ArgumentException($"Can't discard {item->ItemID}", nameof(item));
AgentInventoryContext.Instance()->DiscardItem(item, item->Container, item->Slot, 0); AgentInventoryContext.Instance()->DiscardItem(item, item->Container, item->Slot, 0);
} }

View File

@ -62,14 +62,6 @@ internal sealed class ItemCache
cachedItemInfo.CanBeBoughtFromCalamitySalvager = true; cachedItemInfo.CanBeBoughtFromCalamitySalvager = true;
} }
foreach (var collectableItem in dataManager.GetExcelSheet<CollectablesShopItem>()!)
{
if (collectableItem.RowId == 0)
continue;
listManager.AddToInternalWhitelist(collectableItem.Item.Row);
}
// only look at msq + regional side quests // only look at msq + regional side quests
foreach (var quest in dataManager.GetExcelSheet<Quest>()!.Where(x => x.JournalGenre.Value?.JournalCategory.Value?.JournalSection.Row is 0 or 1 or 3)) foreach (var quest in dataManager.GetExcelSheet<Quest>()!.Where(x => x.JournalGenre.Value?.JournalCategory.Value?.JournalSection.Row is 0 or 1 or 3))
{ {
@ -80,14 +72,8 @@ internal sealed class ItemCache
listManager.AddToInternalWhitelist(item.RowId); listManager.AddToInternalWhitelist(item.RowId);
} }
} }
MaxDungeonItemLevel = _items.Values.Where(x => x.Rarity == 2)
.Select(x => (int)x.ILvl)
.Max();
} }
public int MaxDungeonItemLevel { get; }
private bool CanDiscardItemsFromQuest(LazyRow<Quest> quest) private bool CanDiscardItemsFromQuest(LazyRow<Quest> quest)
{ {
return quest.Row > 0 && return quest.Row > 0 &&

View File

@ -11,6 +11,8 @@ internal sealed class ListManager : IListManager
/// </summary> /// </summary>
private ISet<uint> _blacklistedItems = new List<uint> private ISet<uint> _blacklistedItems = new List<uint>
{ {
2820, // red onion helm
16039, // ala mhigan earrings 16039, // ala mhigan earrings
24589, // aetheryte earrings 24589, // aetheryte earrings
33648, // menphina's earrings 33648, // menphina's earrings
@ -265,25 +267,6 @@ internal sealed class ListManager : IListManager
32048, // Umbral Levinsand 32048, // Umbral Levinsand
#endregion #endregion
#region Irregular Tomestones (after the event is over)
24909, // Philosophy
26536, // Mythology
28648, // Soldiery
30272, // Law
31339, // Esoterics
33329, // Pageantry
33330, // Lore
35834, // Scripture
36658, // Verity
38211, // Creation
39365, // Mendacity
39919, // Tenfold Pageantry
41305, // Genesis I
41306, // Genesis II
#endregion
}; };
private readonly Configuration _configuration; private readonly Configuration _configuration;

View File

@ -15,7 +15,7 @@ namespace ARDiscard.Windows;
internal sealed class ConfigWindow : LWindow internal sealed class ConfigWindow : LWindow
{ {
private readonly IDalamudPluginInterface _pluginInterface; private readonly DalamudPluginInterface _pluginInterface;
private readonly Configuration _configuration; private readonly Configuration _configuration;
private readonly ItemCache _itemCache; private readonly ItemCache _itemCache;
private readonly IListManager _listManager; private readonly IListManager _listManager;
@ -29,7 +29,7 @@ internal sealed class ConfigWindow : LWindow
public event EventHandler? DiscardNowClicked; public event EventHandler? DiscardNowClicked;
public event EventHandler? ConfigSaved; public event EventHandler? ConfigSaved;
public ConfigWindow(IDalamudPluginInterface pluginInterface, Configuration configuration, ItemCache itemCache, public ConfigWindow(DalamudPluginInterface pluginInterface, Configuration configuration, ItemCache itemCache,
IListManager listManager, IClientState clientState, ICondition condition) IListManager listManager, IClientState clientState, ICondition condition)
: base("Auto Discard###AutoDiscardConfig") : base("Auto Discard###AutoDiscardConfig")
{ {
@ -65,10 +65,7 @@ internal sealed class ConfigWindow : LWindow
Save(); Save();
} }
ImGui.SameLine(ImGui.GetContentRegionAvail().X + ImGui.SameLine(ImGui.GetWindowWidth() - 115 * ImGuiHelpers.GlobalScale);
ImGui.GetStyle().WindowPadding.X -
ImGui.CalcTextSize("Preview Discards").X -
ImGui.GetStyle().ItemSpacing.X);
ImGui.BeginDisabled(!_clientState.IsLoggedIn || ImGui.BeginDisabled(!_clientState.IsLoggedIn ||
!(_condition[ConditionFlag.NormalConditions] || _condition[ConditionFlag.Mounted]) || !(_condition[ConditionFlag.NormalConditions] || _condition[ConditionFlag.Mounted]) ||
DiscardNowClicked == null); DiscardNowClicked == null);
@ -234,8 +231,7 @@ internal sealed class ConfigWindow : LWindow
if (ImGui.InputInt("Ignore items >= this ilvl (Armoury Chest only)", if (ImGui.InputInt("Ignore items >= this ilvl (Armoury Chest only)",
ref maximumItemLevel)) ref maximumItemLevel))
{ {
_configuration.Armoury.MaximumGearItemLevel = _configuration.Armoury.MaximumGearItemLevel = Math.Max(0, Math.Min(625, maximumItemLevel));
Math.Max(0, Math.Min(_itemCache.MaxDungeonItemLevel, maximumItemLevel));
Save(); Save();
} }

View File

@ -14,7 +14,7 @@ namespace ARDiscard.Windows
protected override string RightSideLabel => "Items that will be automatically discarded"; protected override string RightSideLabel => "Items that will be automatically discarded";
internal required ExcludedListTab ExcludedTab { private get; init; } internal required ExcludedListTab ExcludedTab { private get; init; }
public IEnumerable<uint> ToSavedItems() public override IEnumerable<uint> ToSavedItems()
{ {
SelectedItems.RemoveAll(x => ExcludedTab.IsBlacklistedInConfiguration(x.ItemId)); SelectedItems.RemoveAll(x => ExcludedTab.IsBlacklistedInConfiguration(x.ItemId));
return SelectedItems.Select(x => x.ItemId); return SelectedItems.Select(x => x.ItemId);

View File

@ -5,8 +5,6 @@ using System.Linq;
using ARDiscard.GameData; using ARDiscard.GameData;
using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Conditions;
using Dalamud.Interface.Internal; using Dalamud.Interface.Internal;
using Dalamud.Interface.Textures;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Utility; using Dalamud.Interface.Utility;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Common.Math; using FFXIVClientStructs.FFXIV.Common.Math;
@ -98,11 +96,7 @@ internal sealed class DiscardWindow : LWindow
if (ImGui.Button("Open Configuration")) if (ImGui.Button("Open Configuration"))
OpenConfigurationClicked!.Invoke(this, EventArgs.Empty); OpenConfigurationClicked!.Invoke(this, EventArgs.Empty);
ImGui.EndDisabled(); ImGui.EndDisabled();
ImGui.SameLine(ImGui.GetWindowWidth() - 160 * ImGuiHelpers.GlobalScale);
ImGui.SameLine(ImGui.GetContentRegionAvail().X +
ImGui.GetStyle().WindowPadding.X -
ImGui.CalcTextSize("Discard all selected items").X -
ImGui.GetStyle().ItemSpacing.X);
ImGui.BeginDisabled(Locked || ImGui.BeginDisabled(Locked ||
!_clientState.IsLoggedIn || !_clientState.IsLoggedIn ||
!(_condition[ConditionFlag.NormalConditions] || _condition[ConditionFlag.Mounted]) || !(_condition[ConditionFlag.NormalConditions] || _condition[ConditionFlag.Mounted]) ||
@ -123,7 +117,7 @@ internal sealed class DiscardWindow : LWindow
{ {
if (_configuration.Preview.ShowIcons) if (_configuration.Preview.ShowIcons)
{ {
using IDalamudTextureWrap? icon = _iconCache.GetIcon(displayedItem.IconId); IDalamudTextureWrap? icon = _iconCache.GetIcon(displayedItem.IconId);
if (icon != null) if (icon != null)
{ {
ImGui.Image(icon.ImGuiHandle, new Vector2(23, 23)); ImGui.Image(icon.ImGuiHandle, new Vector2(23, 23));
@ -156,8 +150,8 @@ internal sealed class DiscardWindow : LWindow
_displayedItems = _inventoryUtils.GetAllItemsToDiscard() _displayedItems = _inventoryUtils.GetAllItemsToDiscard()
.GroupBy(x => new .GroupBy(x => new
{ {
ItemId = x.InventoryItem->ItemId, ItemId = x.InventoryItem->ItemID,
ItemInfo = _itemCache.GetItem(x.InventoryItem->ItemId), ItemInfo = _itemCache.GetItem(x.InventoryItem->ItemID),
}) })
.Where(x => x.Key.ItemInfo != null) .Where(x => x.Key.ItemInfo != null)
.Select(x => new SelectableItem .Select(x => new SelectableItem

View File

@ -20,7 +20,7 @@ internal sealed class ExcludedListTab : ItemListTab
protected override string RightSideLabel => "Items that will never be discarded"; protected override string RightSideLabel => "Items that will never be discarded";
public IEnumerable<uint> ToSavedItems() public override IEnumerable<uint> ToSavedItems()
{ {
return SelectedItems return SelectedItems
.Select(x => x.ItemId) .Select(x => x.ItemId)

View File

@ -26,6 +26,8 @@ internal abstract class ItemListTab
protected abstract string RightSideLabel { get; } protected abstract string RightSideLabel { get; }
protected List<(uint ItemId, string Name)> SelectedItems { get; } = new(); protected List<(uint ItemId, string Name)> SelectedItems { get; } = new();
public abstract IEnumerable<uint> ToSavedItems();
public void Draw() public void Draw()
{ {
var ws = ImGui.GetWindowSize(); var ws = ImGui.GetWindowSize();
@ -141,6 +143,8 @@ internal abstract class ItemListTab
protected virtual (string Name, bool Enabled) AsLeftSideDisplay(uint itemId, string name) => (name, true); protected virtual (string Name, bool Enabled) AsLeftSideDisplay(uint itemId, string name) => (name, true);
protected virtual (string Name, bool Enabled) AsRightSideDisplay(uint itemId, string name) => (name, true);
protected void Save() => _parent.Save(); protected void Save() => _parent.Save();
private void UpdateResults() private void UpdateResults()

View File

@ -4,92 +4,21 @@
"net8.0-windows7.0": { "net8.0-windows7.0": {
"DalamudPackager": { "DalamudPackager": {
"type": "Direct", "type": "Direct",
"requested": "[2.1.13, )", "requested": "[2.1.12, )",
"resolved": "2.1.13", "resolved": "2.1.12",
"contentHash": "rMN1omGe8536f4xLMvx9NwfvpAc9YFFfeXJ1t4P4PE6Gu8WCIoFliR1sh07hM+bfODmesk/dvMbji7vNI+B/pQ==" "contentHash": "Sc0PVxvgg4NQjcI8n10/VfUQBAS4O+Fw2pZrAqBdRMbthYGeogzu5+xmIGCGmsEZ/ukMOBuAqiNiB5qA3MRalg=="
},
"DotNet.ReproducibleBuilds": {
"type": "Direct",
"requested": "[1.1.1, )",
"resolved": "1.1.1",
"contentHash": "+H2t/t34h6mhEoUvHi8yGXyuZ2GjSovcGYehJrS2MDm2XgmPfZL2Sdxg+uL2lKgZ4M6tTwKHIlxOob2bgh0NRQ==",
"dependencies": {
"Microsoft.SourceLink.AzureRepos.Git": "1.1.1",
"Microsoft.SourceLink.Bitbucket.Git": "1.1.1",
"Microsoft.SourceLink.GitHub": "1.1.1",
"Microsoft.SourceLink.GitLab": "1.1.1"
}
},
"Microsoft.SourceLink.Gitea": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "KOBodmDnlWGIqZt2hT47Q69TIoGhIApDVLCyyj9TT5ct8ju16AbHYcB4XeknoHX562wO1pMS/1DfBIZK+V+sxg==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "8.0.0",
"Microsoft.SourceLink.Common": "8.0.0"
}
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.SourceLink.AzureRepos.Git": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "qB5urvw9LO2bG3eVAkuL+2ughxz2rR7aYgm2iyrB8Rlk9cp2ndvGRCvehk3rNIhRuNtQaeKwctOl1KvWiklv5w==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"Microsoft.SourceLink.Bitbucket.Git": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "cDzxXwlyWpLWaH0em4Idj0H3AmVo3L/6xRXKssYemx+7W52iNskj/SQ4FOmfCb8YQt39otTDNMveCZzYtMoucQ==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Microsoft.SourceLink.GitHub": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "IaJGnOv/M7UQjRJks7B6p7pbPnOwisYGOIzqCz5ilGFTApZ3ktOR+6zJ12ZRPInulBmdAf1SrGdDG2MU8g6XTw==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"Microsoft.SourceLink.GitLab": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "tvsg47DDLqqedlPeYVE2lmiTpND8F0hkrealQ5hYltSmvruy/Gr5nHAKSsjyw5L3NeM/HLMI5ORv7on/M4qyZw==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
}, },
"autoretainerapi": { "autoretainerapi": {
"type": "Project", "type": "Project",
"dependencies": { "dependencies": {
"ECommons": "[2.2.0.2, )" "ECommons": "[2.1.0.7, )"
} }
}, },
"ecommons": { "ecommons": {
"type": "Project" "type": "Project"
}, },
"llib": { "llib": {
"type": "Project", "type": "Project"
"dependencies": {
"DalamudPackager": "[2.1.13, )"
}
} }
} }
} }

@ -1 +1 @@
Subproject commit 1c8745ef2757585d2683b4a83c44c8db81ff8955 Subproject commit 6f0aaa55bce6ec79fd4d72f84f21597b39e5445d

@ -1 +1 @@
Subproject commit 07c07e09101e0c8a5f770dbea2ca6eafea5ec705 Subproject commit d238d4188e8b47b11252d75cb5e4b678b8da2756

2
LLib

@ -1 +1 @@
Subproject commit fde09c705b648f03c287814191a554f0a4b92cc4 Subproject commit 3792244261a9f5426a7916f5a6dd1966238ba84a