Merge remote-tracking branch 'origin/master' into dev/pie-lover

This commit is contained in:
Shawrkie Williams
2026-01-09 17:50:05 -05:00
9 changed files with 369 additions and 63 deletions
@@ -209,20 +209,6 @@ public class InventoryLifecycles : IDisposable
public void Dispose() public void Dispose()
{ {
Services.AddonLifecycle.UnregisterListener(AddonEvent.PostSetup, "InventoryBuddy", OnPostSetup); Services.AddonLifecycle.UnregisterListener(OnPostSetup, OnPreFinalize, OnInventoryUpdate, OnSaddleBagUpdate, OnRetainerInventoryUpdate, OnSaddleBagOpen);
Services.AddonLifecycle.UnregisterListener(AddonEvent.PostSetup, "InventoryRetainer, InventoryRetainerLarge", OnPostSetup);
Services.AddonLifecycle.UnregisterListener(AddonEvent.PreFinalize, "InventoryBuddy", OnPreFinalize);
Services.AddonLifecycle.UnregisterListener(AddonEvent.PreFinalize, "InventoryRetainer, InventoryRetainerLarge", OnPreFinalize);
Services.AddonLifecycle.UnregisterListener(AddonEvent.PreRefresh, ["Inventory", "InventoryLarge", "InventoryExpansion"]);
Services.AddonLifecycle.UnregisterListener(AddonEvent.PreRefresh, ["InventoryBuddy"]);
Services.AddonLifecycle.UnregisterListener(AddonEvent.PreRefresh, ["InventoryRetainer", "InventoryRetainerLarge"]);
Services.AddonLifecycle.UnregisterListener(AddonEvent.PostRequestedUpdate, "Inventory", OnInventoryUpdate);
Services.AddonLifecycle.UnregisterListener(AddonEvent.PostRequestedUpdate, "InventoryBuddy", OnSaddleBagUpdate);
Services.AddonLifecycle.UnregisterListener(AddonEvent.PostRequestedUpdate, ["InventoryRetainer", "InventoryRetainerLarge"], OnRetainerInventoryUpdate);
Services.AddonLifecycle.UnregisterListener(AddonEvent.PreShow, ["InventoryBuddy"], OnSaddleBagOpen);
} }
} }
+1 -1
View File
@@ -151,7 +151,7 @@ public class CommandHandler : IDisposable
private static void PrintChat(string message) private static void PrintChat(string message)
{ {
Services.ChatGui.Print($"[AetherBags] {message}"); Services.ChatGui.Print(message, "AetherBags");
} }
public void Dispose() public void Dispose()
+3 -2
View File
@@ -12,8 +12,9 @@ public class CategorySettings
public bool GameCategoriesEnabled { get; set; } = true; public bool GameCategoriesEnabled { get; set; } = true;
public bool UserCategoriesEnabled { get; set; } = true; public bool UserCategoriesEnabled { get; set; } = true;
public bool BisBuddyEnabled { get; set; } = true; public bool BisBuddyEnabled { get; set; } = true;
public PluginFilterMode BisBuddyMode { get; set; } = PluginFilterMode.Highlight;
public bool AllaganToolsCategoriesEnabled { get; set; } = false; public bool AllaganToolsCategoriesEnabled { get; set; } = false;
public AllaganToolsFilterMode AllaganToolsMode { get; set; } = AllaganToolsFilterMode.Highlight; public PluginFilterMode AllaganToolsFilterMode { get; set; } = PluginFilterMode.Highlight;
public List<UserCategoryDefinition> UserCategories { get; set; } = new(); public List<UserCategoryDefinition> UserCategories { get; set; } = new();
} }
@@ -81,7 +82,7 @@ public enum ToggleFilterState
Disallow = 2, Disallow = 2,
} }
public enum AllaganToolsFilterMode public enum PluginFilterMode
{ {
Categorize = 0, Categorize = 0,
Highlight = 1, Highlight = 1,
+141 -22
View File
@@ -7,15 +7,33 @@ using Dalamud.Plugin.Ipc;
namespace AetherBags.IPC; namespace AetherBags.IPC;
public record BisItemEntry(uint ItemId, Vector4 Color);
public record BisItemFilter(
bool IncludePrereqs = true,
bool IncludeMateria = true,
bool IncludeCollected = false,
bool IncludeObtainable = true,
bool IncludeCollectedPrereqs = true
);
public class BisBuddyIPC : IDisposable public class BisBuddyIPC : IDisposable
{ {
private ICallGateSubscriber<bool>? _isInitialized; private ICallGateSubscriber<bool>? _isInitialized;
private ICallGateSubscriber<bool, bool>? _initialized; private ICallGateSubscriber<bool, bool>? _initialized;
private ICallGateSubscriber<List<uint>>? _getBisItems; private ICallGateSubscriber<List<BisItemEntry>>? _getInventoryHighlightItems;
private ICallGateSubscriber<List<uint>, bool>? _bisItemsChanged; private ICallGateSubscriber<List<BisItemEntry>, bool>? _inventoryHighlightItemsChanged;
private ICallGateSubscriber<BisItemFilter, List<BisItemEntry>>? _getBisItemsFiltered;
public bool IsReady { get; private set; } public bool IsReady { get; private set; }
private static readonly Vector3 BisColor = new(0.0f, 0.3f, 0.0f);
public List<BisItemEntry> CachedBisItems { get; } = new();
public Dictionary<uint, BisItemEntry> ItemLookup { get; } = new();
public BisItemFilter? CurrentFilter { get; private set; }
public event Action? OnItemsRefreshed;
public BisBuddyIPC() public BisBuddyIPC()
{ {
@@ -23,57 +41,158 @@ public class BisBuddyIPC : IDisposable
{ {
_isInitialized = Services.PluginInterface.GetIpcSubscriber<bool>("BisBuddy.IsInitialized"); _isInitialized = Services.PluginInterface.GetIpcSubscriber<bool>("BisBuddy.IsInitialized");
_initialized = Services.PluginInterface.GetIpcSubscriber<bool, bool>("BisBuddy.Initialized"); _initialized = Services.PluginInterface.GetIpcSubscriber<bool, bool>("BisBuddy.Initialized");
_getBisItems = Services.PluginInterface.GetIpcSubscriber<List<uint>>("BisBuddy.GetBisItems"); _getInventoryHighlightItems = Services.PluginInterface.GetIpcSubscriber<List<BisItemEntry>>("BisBuddy.GetInventoryHighlightItems");
_bisItemsChanged = Services.PluginInterface.GetIpcSubscriber<List<uint>, bool>("BisBuddy.BisItemsChanged"); _inventoryHighlightItemsChanged = Services.PluginInterface.GetIpcSubscriber<List<BisItemEntry>, bool>("BisBuddy.InventoryHighlightItemsChanged");
_getBisItemsFiltered = Services.PluginInterface.GetIpcSubscriber<BisItemFilter, List<BisItemEntry>>("BisBuddy.GetBisItemsFiltered");
_initialized.Subscribe(OnInitialized); _initialized.Subscribe(OnBisBuddyInitialized);
_bisItemsChanged.Subscribe(UpdateHighlights); _inventoryHighlightItemsChanged.Subscribe(OnInventoryHighlightItemsChanged);
try { IsReady = _isInitialized.InvokeFunc(); } catch { IsReady = false; } try
{
if (IsReady) RequestUpdate(); IsReady = _isInitialized.InvokeFunc();
if (IsReady) RefreshItems();
}
catch
{
IsReady = false;
}
} }
catch (Exception ex) catch (Exception ex)
{ {
Services.Logger.DebugOnly($"BisBuddy not available: {ex.Message}"); Services.Logger.DebugOnly($"BisBuddy not available: {ex.Message}");
IsReady = false;
} }
} }
private void OnInitialized(bool ready) private void OnBisBuddyInitialized(bool ready)
{ {
IsReady = ready; IsReady = ready;
if (ready) RequestUpdate(); if (ready)
else HighlightState.ClearLabel(HighlightSource.BiSBuddy); {
Services.Logger.Information("BisBuddy IPC connected");
RefreshItems();
}
else
{
ClearHighlights();
}
} }
public void RequestUpdate() private void OnInventoryHighlightItemsChanged(List<BisItemEntry> items)
{
if (CurrentFilter == null)
{
UpdateCacheAndHighlights(items);
}
}
public void RefreshItems()
{ {
if (!IsReady) return; if (!IsReady) return;
try try
{ {
var items = _getBisItems?.InvokeFunc(); List<BisItemEntry>? items;
if (items != null) UpdateHighlights(items);
if (CurrentFilter != null)
{
items = _getBisItemsFiltered?.InvokeFunc(CurrentFilter);
}
else
{
items = _getInventoryHighlightItems?.InvokeFunc();
}
if (items != null)
{
UpdateCacheAndHighlights(items);
}
}
catch (Exception ex)
{
Services.Logger.Warning($"Failed to refresh BisBuddy items: {ex.Message}");
IsReady = false;
} }
catch { IsReady = false; }
} }
private void UpdateHighlights(List<uint>? itemIds) public void SetFilter(BisItemFilter? filter)
{ {
if (!System.Config.Categories.BisBuddyEnabled || itemIds == null || itemIds.Count == 0) CurrentFilter = filter;
RefreshItems();
}
public void ShowAllItems()
{
SetFilter(new BisItemFilter(IncludeCollected: true));
}
public void ShowUncollectedOnly()
{
SetFilter(new BisItemFilter(IncludeCollected: false));
}
public void UseInventoryConfig()
{
SetFilter(null);
}
private void UpdateCacheAndHighlights(List<BisItemEntry> items)
{
CachedBisItems.Clear();
ItemLookup.Clear();
foreach (var item in items)
{
CachedBisItems.Add(item);
ItemLookup[item.ItemId] = item;
}
Services.Logger.DebugOnly($"Refreshed {CachedBisItems.Count} BisBuddy items");
ApplyHighlights();
OnItemsRefreshed?.Invoke();
}
private void ApplyHighlights()
{
if (!System.Config.Categories.BisBuddyEnabled || CachedBisItems.Count == 0)
{ {
HighlightState.ClearLabel(HighlightSource.BiSBuddy); HighlightState.ClearLabel(HighlightSource.BiSBuddy);
} }
else else
{ {
HighlightState.SetLabel(HighlightSource.BiSBuddy, itemIds, BisColor); var highlights = new Dictionary<uint, Vector4>(CachedBisItems.Count);
foreach (var item in CachedBisItems)
{
highlights[item.ItemId] = item.Color;
}
HighlightState.SetLabelWithColors(HighlightSource.BiSBuddy, highlights);
} }
InventoryOrchestrator.RefreshHighlights(); InventoryOrchestrator.RefreshHighlights();
} }
private void ClearHighlights()
{
CachedBisItems.Clear();
ItemLookup.Clear();
HighlightState.ClearLabel(HighlightSource.BiSBuddy);
InventoryOrchestrator.RefreshHighlights();
}
public bool IsBisItem(uint itemId)
=> ItemLookup.ContainsKey(itemId);
public BisItemEntry? GetBisItem(uint itemId)
=> ItemLookup.GetValueOrDefault(itemId);
public Vector4? GetItemColor(uint itemId)
=> GetBisItem(itemId)?.Color;
public void Dispose() public void Dispose()
{ {
_initialized?.Unsubscribe(OnInitialized); _initialized?.Unsubscribe(OnBisBuddyInitialized);
_bisItemsChanged?.Unsubscribe(UpdateHighlights); _inventoryHighlightItemsChanged?.Unsubscribe(OnInventoryHighlightItemsChanged);
} }
} }
@@ -21,9 +21,19 @@ public static class CategoryBucketManager
private const uint AllaganFilterKeyFlag = 0x4000_0000; private const uint AllaganFilterKeyFlag = 0x4000_0000;
private const uint BisBuddyKeyFlag = 0x2000_0000;
public static uint MakeAllaganFilterKey(int index) public static uint MakeAllaganFilterKey(int index)
=> AllaganFilterKeyFlag | (uint)(index & 0x3FFF_FFFF); => AllaganFilterKeyFlag | (uint)(index & 0x3FFF_FFFF);
public static uint MakeBisBuddyKey()
=> BisBuddyKeyFlag;
public static bool IsBisBuddyKey(uint key)
=> (key & BisBuddyKeyFlag) != 0
&& (key & AllaganFilterKeyFlag) == 0
&& (key & UserCategoryKeyFlag) == 0;
public static bool IsAllaganFilterKey(uint key) public static bool IsAllaganFilterKey(uint key)
=> (key & AllaganFilterKeyFlag) != 0 && (key & UserCategoryKeyFlag) == 0; => (key & AllaganFilterKeyFlag) != 0 && (key & UserCategoryKeyFlag) == 0;
@@ -219,13 +229,68 @@ public static class CategoryBucketManager
} }
} }
if (bucket.Items. Count == 0) if (bucket.Items.Count == 0)
bucket.Used = false; bucket.Used = false;
index++; index++;
} }
} }
public static void BucketByBisBuddyItems(
Dictionary<ulong, ItemInfo> itemInfoByKey,
Dictionary<uint, CategoryBucket> bucketsByKey,
HashSet<ulong> claimedKeys,
bool bisCategoriesEnabled)
{
if (!bisCategoriesEnabled) return;
if (!System.IPC.BisBuddy.IsReady) return;
var bisItems = System.IPC.BisBuddy.ItemLookup;
if (bisItems.Count == 0) return;
uint bucketKey = MakeBisBuddyKey();
if (!bucketsByKey.TryGetValue(bucketKey, out CategoryBucket? bucket))
{
bucket = new CategoryBucket
{
Key = bucketKey,
Category = new CategoryInfo
{
Name = "[BiS] Best in Slot",
Description = "Items needed for your BiS gearsets",
Color = ColorHelper.GetColor(50),
},
Items = new List<ItemInfo>(capacity: 16),
FilteredItems = new List<ItemInfo>(capacity: 16),
Used = true,
};
bucketsByKey.Add(bucketKey, bucket);
}
else
{
bucket.Used = true;
}
foreach (var itemKvp in itemInfoByKey)
{
ulong itemKey = itemKvp.Key;
ItemInfo item = itemKvp.Value;
if (claimedKeys.Contains(itemKey))
continue;
if (bisItems.ContainsKey(item.Item.ItemId))
{
bucket.Items.Add(item);
claimedKeys.Add(itemKey);
}
}
if (bucket.Items.Count == 0)
bucket.Used = false;
}
public static void BucketUnclaimedToMisc( public static void BucketUnclaimedToMisc(
Dictionary<ulong, ItemInfo> itemInfoByKey, Dictionary<ulong, ItemInfo> itemInfoByKey,
Dictionary<uint, CategoryBucket> bucketsByKey, Dictionary<uint, CategoryBucket> bucketsByKey,
@@ -287,20 +352,27 @@ public static class CategoryBucketManager
if (!bucket.Used) if (!bucket.Used)
continue; continue;
// TODO: Make configurable
bucket.Items.Sort(ItemCountDescComparer.Instance); bucket.Items.Sort(ItemCountDescComparer.Instance);
sortedCategoryKeys.Add(bucket.Key); sortedCategoryKeys.Add(bucket.Key);
} }
// TODO: Make sortable by user
sortedCategoryKeys.Sort((left, right) => sortedCategoryKeys.Sort((left, right) =>
{ {
bool leftUser = IsUserCategoryKey(left); int GetPriority(uint key)
bool rightUser = IsUserCategoryKey(right); {
bool leftAllagan = IsAllaganFilterKey(left); if (IsUserCategoryKey(key)) return 1;
bool rightAllagan = IsAllaganFilterKey(right); if (IsBisBuddyKey(key)) return 2;
if (leftUser != rightUser) return leftUser ? -1 : 1; if (IsAllaganFilterKey(key)) return 3;
if (leftAllagan != rightAllagan) return leftAllagan ? -1 : 1; if (key == 0) return 99;
return 10;
}
return left.CompareTo(right); int leftPrio = GetPriority(left);
int rightPrio = GetPriority(right);
return leftPrio != rightPrio ? leftPrio.CompareTo(rightPrio) : left.CompareTo(right);
}); });
} }
+74 -5
View File
@@ -10,12 +10,16 @@ public enum HighlightSource
BiSBuddy, BiSBuddy,
} }
public record HighlightEntry(uint ItemId, Vector3 Color);
public static class HighlightState public static class HighlightState
{ {
private static readonly Dictionary<HighlightSource, HashSet<uint>> Filters = new(); private static readonly Dictionary<HighlightSource, HashSet<uint>> Filters = new();
private static readonly Dictionary<HighlightSource, (HashSet<uint> ids, Vector3 color)> Labels = new(); private static readonly Dictionary<HighlightSource, (HashSet<uint> ids, Vector3 color)> Labels = new();
private static readonly Dictionary<HighlightSource, Dictionary<uint, HighlightEntry>> PerItemLabels = new();
public static string? SelectedAllaganToolsFilterKey { get; set; } = string.Empty; public static string? SelectedAllaganToolsFilterKey { get; set; } = string.Empty;
public static string? SelectedBisBuddyFilterKey { get; set; } = string.Empty;
public static bool IsFilterActive => Filters.Count > 0; public static bool IsFilterActive => Filters.Count > 0;
@@ -30,24 +34,89 @@ public static class HighlightState
return false; return false;
} }
public static Vector3? GetLabelColor(uint itemId) public static HighlightEntry? GetHighlightEntry(uint itemId)
{ {
foreach (var perItemLabel in PerItemLabels.Values)
{
if (perItemLabel.TryGetValue(itemId, out var entry))
return entry;
}
foreach (var label in Labels.Values) foreach (var label in Labels.Values)
if (label.ids.Contains(itemId)) return label.color; {
if (label.ids.Contains(itemId))
return new HighlightEntry(itemId, label.color);
}
return null; return null;
} }
public static void SetLabel(HighlightSource source, IEnumerable<uint> ids, Vector3 color) public static Vector3? GetLabelColor(uint itemId)
=> Labels[source] = (new HashSet<uint>(ids), color); => GetHighlightEntry(itemId)?.Color;
public static void SetLabel(HighlightSource source, IEnumerable<uint> ids, Vector3 color)
{
PerItemLabels.Remove(source);
Labels[source] = (new HashSet<uint>(ids), color);
}
public static void SetLabelWithColors(HighlightSource source, Dictionary<uint, Vector4> itemColors)
{
Labels.Remove(source);
var entries = new Dictionary<uint, HighlightEntry>(itemColors.Count);
foreach (var (itemId, color) in itemColors)
{
var rgb = new Vector3(
color.X * color.W,
color.Y * color.W,
color.Z * color.W
);
entries[itemId] = new HighlightEntry(itemId, rgb);
}
PerItemLabels[source] = entries;
}
public static void SetLabelWithColors(HighlightSource source, IEnumerable<HighlightEntry> entries)
{
Labels.Remove(source);
var dict = new Dictionary<uint, HighlightEntry>();
foreach (var entry in entries)
{
dict[entry.ItemId] = entry;
}
PerItemLabels[source] = dict;
}
public static void SetLabelWithColors(HighlightSource source, Dictionary<uint, Vector3> itemColors)
{
Labels.Remove(source);
var entries = new Dictionary<uint, HighlightEntry>(itemColors.Count);
foreach (var (itemId, color) in itemColors)
{
entries[itemId] = new HighlightEntry(itemId, color);
}
PerItemLabels[source] = entries;
}
public static void ClearAll() public static void ClearAll()
{ {
Filters.Clear(); Filters.Clear();
Labels.Clear(); Labels.Clear();
PerItemLabels.Clear();
SelectedAllaganToolsFilterKey = string.Empty; SelectedAllaganToolsFilterKey = string.Empty;
} }
public static void ClearFilter(HighlightSource source) => Filters.Remove(source); public static void ClearFilter(HighlightSource source) => Filters.Remove(source);
public static void ClearLabel(HighlightSource source) => Labels.Remove(source);
public static void ClearLabel(HighlightSource source)
{
Labels.Remove(source);
PerItemLabels.Remove(source);
}
} }
@@ -66,6 +66,7 @@ public abstract class InventoryStateBase
bool userCategoriesEnabled = config.Categories.UserCategoriesEnabled && categoriesEnabled; bool userCategoriesEnabled = config.Categories.UserCategoriesEnabled && categoriesEnabled;
bool gameCategoriesEnabled = config.Categories.GameCategoriesEnabled && categoriesEnabled; bool gameCategoriesEnabled = config.Categories.GameCategoriesEnabled && categoriesEnabled;
bool allaganCategoriesEnabled = config.Categories.AllaganToolsCategoriesEnabled && categoriesEnabled; bool allaganCategoriesEnabled = config.Categories.AllaganToolsCategoriesEnabled && categoriesEnabled;
bool bisCategoriesEnabled = config.Categories.BisBuddyEnabled && categoriesEnabled;
// TODO: Cache this when config changes // TODO: Cache this when config changes
var userCategories = config.Categories.UserCategories.Where(c => c.Enabled).ToList(); var userCategories = config.Categories.UserCategories.Where(c => c.Enabled).ToList();
@@ -77,7 +78,7 @@ public abstract class InventoryStateBase
if (allaganCategoriesEnabled) if (allaganCategoriesEnabled)
{ {
if (config.Categories.AllaganToolsMode == AllaganToolsFilterMode.Categorize) if (config.Categories.AllaganToolsFilterMode == PluginFilterMode.Categorize)
{ {
CategoryBucketManager.BucketByAllaganFilters(ItemInfoByKey, BucketsByKey, ClaimedKeys, true); CategoryBucketManager.BucketByAllaganFilters(ItemInfoByKey, BucketsByKey, ClaimedKeys, true);
HighlightState.ClearFilter(HighlightSource.AllaganTools); HighlightState.ClearFilter(HighlightSource.AllaganTools);
@@ -92,6 +93,23 @@ public abstract class InventoryStateBase
HighlightState.ClearFilter(HighlightSource.AllaganTools); HighlightState.ClearFilter(HighlightSource.AllaganTools);
} }
if (bisCategoriesEnabled)
{
if (config.Categories.BisBuddyMode == PluginFilterMode.Categorize)
{
CategoryBucketManager.BucketByBisBuddyItems(ItemInfoByKey, BucketsByKey, ClaimedKeys, true);
HighlightState.ClearFilter(HighlightSource.BiSBuddy);
}
else
{
UpdateAllaganHighlight(HighlightState.SelectedBisBuddyFilterKey);
}
}
else
{
HighlightState.ClearFilter(HighlightSource.BiSBuddy);
}
if (gameCategoriesEnabled) if (gameCategoriesEnabled)
{ {
CategoryBucketManager.BucketByGameCategories( CategoryBucketManager.BucketByGameCategories(
@@ -123,6 +141,25 @@ public abstract class InventoryStateBase
} }
} }
private void UpdateBisBuddyHighlight(string? filterKey)
{
if (string.IsNullOrEmpty(filterKey) || !System.IPC.BisBuddy.IsReady)
{
HighlightState.ClearFilter(HighlightSource.BiSBuddy);
return;
}
var filterItems = System.IPC.AllaganTools.GetFilterItems(filterKey);
if (filterItems != null)
{
HighlightState.SetFilter(HighlightSource.BiSBuddy, filterItems.Keys);
}
else
{
HighlightState.ClearFilter(HighlightSource.BiSBuddy);
}
}
public IReadOnlyList<CategorizedInventory> GetCategories(string filter = "", bool invert = false) public IReadOnlyList<CategorizedInventory> GetCategories(string filter = "", bool invert = false)
=> InventoryFilter.FilterCategories(AllCategories, BucketsByKey, FilteredCategories, filter, invert); => InventoryFilter.FilterCategories(AllCategories, BucketsByKey, FilteredCategories, filter, invert);
@@ -80,6 +80,27 @@ public sealed class CategoryGeneralConfigurationNode : TabbedVerticalListNode
bool bisBuddyReady = System.IPC.BisBuddy?.IsReady ?? false; bool bisBuddyReady = System.IPC.BisBuddy?.IsReady ?? false;
LabeledDropdownNode? bbModeDropdown = new LabeledDropdownNode
{
Size = new Vector2(300, 20),
LabelText = "Filter Display Mode",
LabelTextFlags = TextFlags.AutoAdjustNodeSize,
IsEnabled = config.BisBuddyEnabled && bisBuddyReady,
Options = Enum.GetNames(typeof(PluginFilterMode)).ToList(),
SelectedOption = config.BisBuddyMode.ToString(),
OnOptionSelected = selected =>
{
if (Enum.TryParse<PluginFilterMode>(selected, out var parsed))
{
config.BisBuddyMode = parsed;
if (parsed == PluginFilterMode.Categorize)
HighlightState.ClearFilter(HighlightSource.AllaganTools);
RefreshInventory();
}
}
};
CheckboxNode bisBuddyEnabled = new CheckboxNode CheckboxNode bisBuddyEnabled = new CheckboxNode
{ {
Size = Size with { Y = 18 }, Size = Size with { Y = 18 },
@@ -90,11 +111,13 @@ public sealed class CategoryGeneralConfigurationNode : TabbedVerticalListNode
OnClick = isChecked => OnClick = isChecked =>
{ {
config.BisBuddyEnabled = isChecked; config.BisBuddyEnabled = isChecked;
System.IPC.BisBuddy?.RequestUpdate(); if (bbModeDropdown != null) bbModeDropdown.IsEnabled = isChecked;
if (isChecked) System.IPC.BisBuddy?.RefreshItems();
RefreshInventory(); RefreshInventory();
} }
}; };
AddNode(bisBuddyEnabled); AddNode(bisBuddyEnabled);
AddNode(1, bbModeDropdown);
bool allaganReady = System.IPC.AllaganTools?.IsReady ?? false; bool allaganReady = System.IPC.AllaganTools?.IsReady ?? false;
@@ -104,14 +127,14 @@ public sealed class CategoryGeneralConfigurationNode : TabbedVerticalListNode
LabelText = "Filter Display Mode", LabelText = "Filter Display Mode",
LabelTextFlags = TextFlags.AutoAdjustNodeSize, LabelTextFlags = TextFlags.AutoAdjustNodeSize,
IsEnabled = config.AllaganToolsCategoriesEnabled && allaganReady, IsEnabled = config.AllaganToolsCategoriesEnabled && allaganReady,
Options = Enum.GetNames(typeof(AllaganToolsFilterMode)).ToList(), Options = Enum.GetNames(typeof(PluginFilterMode)).ToList(),
SelectedOption = config.AllaganToolsMode.ToString(), SelectedOption = config.AllaganToolsFilterMode.ToString(),
OnOptionSelected = selected => OnOptionSelected = selected =>
{ {
if (Enum.TryParse<AllaganToolsFilterMode>(selected, out var parsed)) if (Enum.TryParse<PluginFilterMode>(selected, out var parsed))
{ {
config.AllaganToolsMode = parsed; config.AllaganToolsFilterMode = parsed;
if (parsed == AllaganToolsFilterMode.Categorize) if (parsed == PluginFilterMode.Categorize)
HighlightState.ClearFilter(HighlightSource.AllaganTools); HighlightState.ClearFilter(HighlightSource.AllaganTools);
RefreshInventory(); RefreshInventory();
@@ -139,8 +162,7 @@ public sealed class CategoryGeneralConfigurationNode : TabbedVerticalListNode
}; };
AddNode(_allaganToolsCheckbox); AddNode(_allaganToolsCheckbox);
AddTab(1); AddNode(1, atModeDropdown);
AddNode(atModeDropdown);
SubtractTab(1); SubtractTab(1);
} }