(2.x) Update Lists/locked items tabs
This commit is contained in:
parent
189d4fb0a7
commit
6564a49369
@ -18,13 +18,20 @@ internal sealed class Configuration : IPluginConfiguration
|
|||||||
public required Guid Id { get; set; }
|
public required Guid Id { get; set; }
|
||||||
public required string Name { get; set; }
|
public required string Name { get; set; }
|
||||||
public required ListType Type { get; set; } = ListType.CollectOneTime;
|
public required ListType Type { get; set; } = ListType.CollectOneTime;
|
||||||
|
public required ListPriority Priority { get; set; } = ListPriority.InOrder;
|
||||||
public List<QueuedItem> Items { get; set; } = new();
|
public List<QueuedItem> Items { get; set; } = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ListType
|
public enum ListType
|
||||||
{
|
{
|
||||||
CollectOneTime,
|
CollectOneTime,
|
||||||
KeepAlways,
|
KeepStocked,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ListPriority
|
||||||
|
{
|
||||||
|
InOrder,
|
||||||
|
Balanced,
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class QueuedItem
|
public sealed class QueuedItem
|
||||||
@ -33,7 +40,7 @@ internal sealed class Configuration : IPluginConfiguration
|
|||||||
public required int RemainingQuantity { get; set; }
|
public required int RemainingQuantity { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CharacterGroup
|
public sealed class CharacterGroup
|
||||||
{
|
{
|
||||||
public required Guid Id { get; set; }
|
public required Guid Id { get; set; }
|
||||||
public required string Name { get; set; }
|
public required string Name { get; set; }
|
||||||
|
@ -23,6 +23,8 @@ internal sealed class ConfigWindow : Window
|
|||||||
private static readonly Vector4 ColorGreen = ImGuiColors.HealerGreen;
|
private static readonly Vector4 ColorGreen = ImGuiColors.HealerGreen;
|
||||||
private static readonly Vector4 ColorRed = ImGuiColors.DalamudRed;
|
private static readonly Vector4 ColorRed = ImGuiColors.DalamudRed;
|
||||||
private static readonly Vector4 ColorGrey = ImGuiColors.DalamudGrey;
|
private static readonly Vector4 ColorGrey = ImGuiColors.DalamudGrey;
|
||||||
|
private static readonly string[] StockingTypeLabels = { "Collect Once", "Keep in Stock" };
|
||||||
|
private static readonly string[] PriorityLabels = { "Collect in order of the list", "Collect item with lowest inventory first" };
|
||||||
|
|
||||||
private readonly DalamudPluginInterface _pluginInterface;
|
private readonly DalamudPluginInterface _pluginInterface;
|
||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
@ -31,10 +33,15 @@ internal sealed class ConfigWindow : Window
|
|||||||
private readonly ICommandManager _commandManager;
|
private readonly ICommandManager _commandManager;
|
||||||
private readonly IPluginLog _pluginLog;
|
private readonly IPluginLog _pluginLog;
|
||||||
|
|
||||||
|
private readonly Dictionary<Guid, TemporaryConfig> _currentEditPopups = new();
|
||||||
private string _searchString = string.Empty;
|
private string _searchString = string.Empty;
|
||||||
private Configuration.QueuedItem? _dragDropSource;
|
private TemporaryConfig _newGroup = new() { Name = string.Empty };
|
||||||
private bool _enableDragDrop;
|
private TemporaryConfig _newList = new()
|
||||||
private string _newGroupName = string.Empty;
|
{
|
||||||
|
Name = string.Empty,
|
||||||
|
ListType = Configuration.ListType.CollectOneTime,
|
||||||
|
ListPriority = Configuration.ListPriority.InOrder
|
||||||
|
};
|
||||||
private bool _checkPerCharacter = true;
|
private bool _checkPerCharacter = true;
|
||||||
private bool _onlyShowMissing = true;
|
private bool _onlyShowMissing = true;
|
||||||
|
|
||||||
@ -65,20 +72,192 @@ internal sealed class ConfigWindow : Window
|
|||||||
{
|
{
|
||||||
if (ImGui.BeginTabBar("ARConfigTabs"))
|
if (ImGui.BeginTabBar("ARConfigTabs"))
|
||||||
{
|
{
|
||||||
//DrawItemQueue();
|
DrawVentureLists();
|
||||||
DrawCharacters();
|
|
||||||
DrawCharacterGroups();
|
DrawCharacterGroups();
|
||||||
//DrawGatheredItemsToCheck();
|
DrawCharacters();
|
||||||
|
DrawGatheredItemsToCheck();
|
||||||
ImGui.EndTabBar();
|
ImGui.EndTabBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
private unsafe void DrawVentureLists()
|
||||||
private unsafe void DrawItemQueue()
|
|
||||||
{
|
{
|
||||||
if (ImGui.BeginTabItem("Item Lists"))
|
if (ImGui.BeginTabItem("Venture Lists"))
|
||||||
{
|
{
|
||||||
if (ImGui.BeginCombo("Add Item...##VentureSelection", ""))
|
Configuration.ItemList? listToDelete = null;
|
||||||
|
foreach (var list in _configuration.ItemLists)
|
||||||
|
{
|
||||||
|
ImGui.PushID($"List{list.Id}");
|
||||||
|
|
||||||
|
if (ImGuiComponents.IconButton(FontAwesomeIcon.Cog))
|
||||||
|
{
|
||||||
|
_currentEditPopups[list.Id] = new TemporaryConfig
|
||||||
|
{
|
||||||
|
Name = list.Name,
|
||||||
|
ListType = list.Type,
|
||||||
|
ListPriority = list.Priority,
|
||||||
|
};
|
||||||
|
ImGui.OpenPopup($"##EditList{list.Id}");
|
||||||
|
}
|
||||||
|
DrawVentureListEditorPopup(list, ref listToDelete);
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGui.CollapsingHeader($"{list.Name} {(list.Type == Configuration.ListType.CollectOneTime ? SeIconChar.BoxedNumber1.ToIconChar() : SeIconChar.Circle.ToIconChar())}"))
|
||||||
|
{
|
||||||
|
ImGui.Indent(30);
|
||||||
|
DrawVentureListItemSelection(list);
|
||||||
|
ImGui.Unindent(30);
|
||||||
|
}
|
||||||
|
ImGui.PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listToDelete != null)
|
||||||
|
{
|
||||||
|
_configuration.ItemLists.Remove(listToDelete);
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
DrawNewVentureList();
|
||||||
|
ImGui.EndTabItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawVentureListEditorPopup(Configuration.ItemList list, ref Configuration.ItemList? listToDelete)
|
||||||
|
{
|
||||||
|
var assignedCharacters = _configuration.Characters
|
||||||
|
.Where(x => x.Type == Configuration.CharacterType.Standalone && x.ItemListIds.Contains(list.Id))
|
||||||
|
.OrderBy(x => x.WorldName)
|
||||||
|
.ThenBy(x => x.LocalContentId)
|
||||||
|
.ToList();
|
||||||
|
var assignedGroups = _configuration.CharacterGroups
|
||||||
|
.Where(x => x.ItemListIds.Contains(list.Id))
|
||||||
|
.ToList();
|
||||||
|
if (_currentEditPopups.TryGetValue(list.Id, out TemporaryConfig? temporaryConfig) &&
|
||||||
|
ImGui.BeginPopup($"##EditList{list.Id}"))
|
||||||
|
{
|
||||||
|
var (save, canSave) = DrawVentureListEditor(temporaryConfig, list);
|
||||||
|
ImGui.BeginDisabled(!canSave || (list.Name == temporaryConfig.Name &&
|
||||||
|
list.Type == temporaryConfig.ListType &&
|
||||||
|
list.Priority == temporaryConfig.ListPriority));
|
||||||
|
save |= ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Save, "Save");
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
|
if (save && canSave)
|
||||||
|
{
|
||||||
|
list.Name = temporaryConfig.Name;
|
||||||
|
list.Type = temporaryConfig.ListType;
|
||||||
|
|
||||||
|
if (list.Type == Configuration.ListType.CollectOneTime)
|
||||||
|
list.Priority = Configuration.ListPriority.InOrder;
|
||||||
|
else
|
||||||
|
list.Priority = temporaryConfig.ListPriority;
|
||||||
|
|
||||||
|
ImGui.CloseCurrentPopup();
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.BeginDisabled(assignedCharacters.Count > 0 || assignedGroups.Count > 0);
|
||||||
|
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Times, "Delete"))
|
||||||
|
{
|
||||||
|
listToDelete = list;
|
||||||
|
ImGui.CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
if ((assignedCharacters.Count > 0 || assignedGroups.Count > 0) &&
|
||||||
|
ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
||||||
|
{
|
||||||
|
ImGui.BeginTooltip();
|
||||||
|
ImGui.Text(
|
||||||
|
$"Remove this list from the {assignedCharacters.Count} character(s) and {assignedGroups.Count} group(s) using it before deleting it.");
|
||||||
|
foreach (var character in assignedCharacters)
|
||||||
|
ImGui.BulletText($"{character.CharacterName} @ {character.WorldName}");
|
||||||
|
foreach (var group in assignedGroups)
|
||||||
|
ImGui.BulletText($"{group.Name}");
|
||||||
|
ImGui.EndTooltip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawNewVentureList()
|
||||||
|
{
|
||||||
|
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Plus, "Add Venture List"))
|
||||||
|
ImGui.OpenPopup("##AddList");
|
||||||
|
|
||||||
|
if (ImGui.BeginPopup("##AddList"))
|
||||||
|
{
|
||||||
|
(bool save, bool canSave) = DrawVentureListEditor(_newList, null);
|
||||||
|
|
||||||
|
ImGui.BeginDisabled(!canSave);
|
||||||
|
save |= ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Save, "Save");
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
|
if (save && canSave)
|
||||||
|
{
|
||||||
|
_configuration.ItemLists.Add(new Configuration.ItemList
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid(),
|
||||||
|
Name = _newList.Name,
|
||||||
|
Type = _newList.ListType,
|
||||||
|
Priority = _newList.ListPriority,
|
||||||
|
});
|
||||||
|
|
||||||
|
_newList = new()
|
||||||
|
{
|
||||||
|
Name = string.Empty,
|
||||||
|
ListType = Configuration.ListType.CollectOneTime,
|
||||||
|
ListPriority = Configuration.ListPriority.InOrder
|
||||||
|
};
|
||||||
|
|
||||||
|
ImGui.CloseCurrentPopup();
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private (bool Save, bool CanSave) DrawVentureListEditor(TemporaryConfig temporaryConfig, Configuration.ItemList? list)
|
||||||
|
{
|
||||||
|
string listName = temporaryConfig.Name;
|
||||||
|
bool save = ImGui.InputTextWithHint("", "List Name...", ref listName, 64,
|
||||||
|
ImGuiInputTextFlags.EnterReturnsTrue);
|
||||||
|
bool canSave = IsValidListName(listName, list);
|
||||||
|
temporaryConfig.Name = listName;
|
||||||
|
|
||||||
|
ImGui.PushID($"Type{list?.Id ?? Guid.Empty}");
|
||||||
|
int type = (int)temporaryConfig.ListType;
|
||||||
|
if (ImGui.Combo("", ref type, StockingTypeLabels, StockingTypeLabels.Length))
|
||||||
|
{
|
||||||
|
temporaryConfig.ListType = (Configuration.ListType)type;
|
||||||
|
if (temporaryConfig.ListType == Configuration.ListType.CollectOneTime)
|
||||||
|
temporaryConfig.ListPriority = Configuration.ListPriority.InOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.PopID();
|
||||||
|
|
||||||
|
if (temporaryConfig.ListType == Configuration.ListType.KeepStocked)
|
||||||
|
{
|
||||||
|
ImGui.PushID($"Priority{list?.Id ?? Guid.Empty}");
|
||||||
|
int priority = (int)temporaryConfig.ListPriority;
|
||||||
|
if (ImGui.Combo("", ref priority, PriorityLabels, PriorityLabels.Length))
|
||||||
|
temporaryConfig.ListPriority = (Configuration.ListPriority)priority;
|
||||||
|
ImGui.PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (save, canSave);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawVentureListItemSelection(Configuration.ItemList list)
|
||||||
|
{
|
||||||
|
ImGuiEx.SetNextItemFullWidth();
|
||||||
|
if (ImGui.BeginCombo($"##VentureSelection{list.Id}", "Add Item..."))
|
||||||
{
|
{
|
||||||
ImGuiEx.SetNextItemFullWidth();
|
ImGuiEx.SetNextItemFullWidth();
|
||||||
ImGui.InputTextWithHint("", "Filter...", ref _searchString, 256);
|
ImGui.InputTextWithHint("", "Filter...", ref _searchString, 256);
|
||||||
@ -94,7 +273,7 @@ internal sealed class ConfigWindow : Window
|
|||||||
if (ImGui.Selectable(
|
if (ImGui.Selectable(
|
||||||
$"{venture.Name} ({string.Join(" ", ventures.Select(x => x.CategoryName))})##SelectVenture{venture.RowId}"))
|
$"{venture.Name} ({string.Join(" ", ventures.Select(x => x.CategoryName))})##SelectVenture{venture.RowId}"))
|
||||||
{
|
{
|
||||||
_configuration.QueuedItems.Add(new Configuration.QueuedItem
|
list.Items.Add(new Configuration.QueuedItem
|
||||||
{
|
{
|
||||||
ItemId = venture.ItemId,
|
ItemId = venture.ItemId,
|
||||||
RemainingQuantity = 0,
|
RemainingQuantity = 0,
|
||||||
@ -109,20 +288,17 @@ internal sealed class ConfigWindow : Window
|
|||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
ImGui.Indent(30);
|
|
||||||
|
|
||||||
Configuration.QueuedItem? itemToRemove = null;
|
Configuration.QueuedItem? itemToRemove = null;
|
||||||
Configuration.QueuedItem? itemToAdd = null;
|
Configuration.QueuedItem? itemToAdd = null;
|
||||||
int indexToAdd = 0;
|
int indexToAdd = 0;
|
||||||
for (int i = 0; i < _configuration.QueuedItems.Count; ++i)
|
float windowX = ImGui.GetContentRegionAvail().X;
|
||||||
|
for (int i = 0; i < list.Items.Count; ++i)
|
||||||
{
|
{
|
||||||
var item = _configuration.QueuedItems[i];
|
var item = list.Items[i];
|
||||||
ImGui.PushID($"QueueItem{i}");
|
ImGui.PushID($"QueueItem{i}");
|
||||||
var ventures = _gameCache.Ventures.Where(x => x.ItemId == item.ItemId).ToList();
|
var ventures = _gameCache.Ventures.Where(x => x.ItemId == item.ItemId).ToList();
|
||||||
var venture = ventures.First();
|
var venture = ventures.First();
|
||||||
|
|
||||||
if (!_enableDragDrop)
|
|
||||||
{
|
|
||||||
ImGui.SetNextItemWidth(130);
|
ImGui.SetNextItemWidth(130);
|
||||||
int quantity = item.RemainingQuantity;
|
int quantity = item.RemainingQuantity;
|
||||||
if (ImGui.InputInt($"{venture.Name} ({string.Join(" ", ventures.Select(x => x.CategoryName))})",
|
if (ImGui.InputInt($"{venture.Name} ({string.Join(" ", ventures.Select(x => x.CategoryName))})",
|
||||||
@ -131,80 +307,59 @@ internal sealed class ConfigWindow : Window
|
|||||||
item.RemainingQuantity = quantity;
|
item.RemainingQuantity = quantity;
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
ImGui.SameLine(windowX - 30);
|
||||||
|
ImGui.BeginDisabled(i == 0);
|
||||||
|
if (ImGuiComponents.IconButton($"##Up{i}", FontAwesomeIcon.ArrowUp))
|
||||||
{
|
{
|
||||||
ImGui.Selectable($"{item.RemainingQuantity}x {venture.Name}");
|
itemToAdd = item;
|
||||||
|
indexToAdd = i - 1;
|
||||||
if (ImGui.BeginDragDropSource())
|
|
||||||
{
|
|
||||||
ImGui.SetDragDropPayload("ArcDragDrop", nint.Zero, 0);
|
|
||||||
_dragDropSource = item;
|
|
||||||
|
|
||||||
ImGui.EndDragDropSource();
|
|
||||||
}
|
}
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
ImGui.SameLine(0, 0);
|
||||||
|
ImGui.BeginDisabled(i == list.Items.Count - 1);
|
||||||
|
if (ImGuiComponents.IconButton($"##Down{i}", FontAwesomeIcon.ArrowDown))
|
||||||
{
|
{
|
||||||
if (_dragDropSource != null && ImGui.AcceptDragDropPayload("ArcDragDrop").NativePtr != null)
|
itemToAdd = item;
|
||||||
{
|
indexToAdd = i + 1;
|
||||||
itemToAdd = _dragDropSource;
|
|
||||||
indexToAdd = i;
|
|
||||||
|
|
||||||
_dragDropSource = null;
|
|
||||||
}
|
}
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
ImGui.SameLine();
|
||||||
}
|
if (ImGuiComponents.IconButton($"##Remove{i}", FontAwesomeIcon.Times))
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.OpenPopupOnItemClick($"###ctx{i}", ImGuiPopupFlags.MouseButtonRight);
|
|
||||||
if (ImGui.BeginPopupContextItem($"###ctx{i}"))
|
|
||||||
{
|
|
||||||
if (ImGui.MenuItem($"Remove {venture.Name}"))
|
|
||||||
itemToRemove = item;
|
itemToRemove = item;
|
||||||
|
|
||||||
ImGui.EndPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemToRemove != null)
|
if (itemToRemove != null)
|
||||||
{
|
{
|
||||||
_configuration.QueuedItems.Remove(itemToRemove);
|
list.Items.Remove(itemToRemove);
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemToAdd != null)
|
if (itemToAdd != null)
|
||||||
{
|
{
|
||||||
_pluginLog.Information($"Updating {itemToAdd.ItemId} → {indexToAdd}");
|
_pluginLog.Information($"Updating {itemToAdd.ItemId} → {indexToAdd}");
|
||||||
_configuration.QueuedItems.Remove(itemToAdd);
|
list.Items.Remove(itemToAdd);
|
||||||
_configuration.QueuedItems.Insert(indexToAdd, itemToAdd);
|
list.Items.Insert(indexToAdd, itemToAdd);
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.Unindent(30);
|
if (list.Items.Count > 0 && list.Type == Configuration.ListType.CollectOneTime)
|
||||||
|
|
||||||
if (_configuration.QueuedItems.Count > 0)
|
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
if (ImGuiComponents.IconButtonWithText(_enableDragDrop ? FontAwesomeIcon.Times : FontAwesomeIcon.Sort, _enableDragDrop ? "Disable Drag&Drop" : "Enable Drag&Drop"))
|
|
||||||
{
|
{
|
||||||
_enableDragDrop = !_enableDragDrop;
|
ImGui.BeginDisabled(list.Items.All(x => x.RemainingQuantity > 0));
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Check, "Remove all finished items"))
|
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Check, "Remove all finished items"))
|
||||||
{
|
{
|
||||||
if (_configuration.QueuedItems.RemoveAll(q => q.RemainingQuantity == 0) > 0)
|
list.Items.RemoveAll(q => q.RemainingQuantity <= 0);
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
ImGui.Spacing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.EndTabItem();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
private void DrawCharacters()
|
private void DrawCharacters()
|
||||||
{
|
{
|
||||||
if (ImGui.BeginTabItem("Retainers"))
|
if (ImGui.BeginTabItem("Retainers"))
|
||||||
@ -290,7 +445,7 @@ internal sealed class ConfigWindow : Window
|
|||||||
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
|
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
|
||||||
if (character.ItemListIds == null)
|
if (character.ItemListIds == null)
|
||||||
character.ItemListIds = new();
|
character.ItemListIds = new();
|
||||||
DrawListSelection(character.LocalContentId.ToString(), character.ItemListIds);
|
DrawVentureListSelection(character.LocalContentId.ToString(), character.ItemListIds);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -301,11 +456,13 @@ internal sealed class ConfigWindow : Window
|
|||||||
var lists = group.ItemListIds
|
var lists = group.ItemListIds
|
||||||
.Where(listId => listId != Guid.Empty)
|
.Where(listId => listId != Guid.Empty)
|
||||||
.Select(listId => _configuration.ItemLists.SingleOrDefault(x => x.Id == listId))
|
.Select(listId => _configuration.ItemLists.SingleOrDefault(x => x.Id == listId))
|
||||||
|
.Where(list => list != null)
|
||||||
|
.Cast<Configuration.ItemList>()
|
||||||
.ToList();
|
.ToList();
|
||||||
if (lists.Count > 0)
|
if (lists.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var list in lists)
|
foreach (var list in lists)
|
||||||
ImGui.TextUnformatted($"{SeIconChar.LinkMarker.ToIconChar()} {list.Name}");
|
ImGui.BulletText($"{list.Name}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ImGui.TextColored(ImGuiColors.DalamudRed, "(None)");
|
ImGui.TextColored(ImGuiColors.DalamudRed, "(None)");
|
||||||
@ -354,17 +511,88 @@ internal sealed class ConfigWindow : Window
|
|||||||
{
|
{
|
||||||
if (ImGui.BeginTabItem("Groups"))
|
if (ImGui.BeginTabItem("Groups"))
|
||||||
{
|
{
|
||||||
|
Configuration.CharacterGroup? groupToDelete = null;
|
||||||
foreach (var group in _configuration.CharacterGroups)
|
foreach (var group in _configuration.CharacterGroups)
|
||||||
{
|
{
|
||||||
ImGui.PushID($"##Group{group.Id}");
|
ImGui.PushID($"##Group{group.Id}");
|
||||||
|
|
||||||
ImGuiComponents.IconButton(FontAwesomeIcon.Cog);
|
if (ImGuiComponents.IconButton(FontAwesomeIcon.Cog))
|
||||||
ImGui.SameLine();
|
{
|
||||||
|
_currentEditPopups[group.Id] = new TemporaryConfig
|
||||||
|
{
|
||||||
|
Name = group.Name,
|
||||||
|
};
|
||||||
|
ImGui.OpenPopup($"##EditGroup{group.Id}");
|
||||||
|
}
|
||||||
|
|
||||||
var assignedCharacters = _configuration.Characters
|
DrawCharacterGroupEditorPopup(group, out var assignedCharacters, ref groupToDelete);
|
||||||
|
ImGui.SameLine();
|
||||||
|
DrawCharacterGroup(group, assignedCharacters);
|
||||||
|
|
||||||
|
ImGui.PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupToDelete != null)
|
||||||
|
{
|
||||||
|
_configuration.CharacterGroups.Remove(groupToDelete);
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
DrawNewCharacterGroup();
|
||||||
|
ImGui.EndTabItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawCharacterGroupEditorPopup(Configuration.CharacterGroup group, out List<Configuration.CharacterConfiguration> assignedCharacters, ref Configuration.CharacterGroup? groupToDelete)
|
||||||
|
{
|
||||||
|
assignedCharacters = _configuration.Characters
|
||||||
.Where(x => x.Type == Configuration.CharacterType.PartOfCharacterGroup &&
|
.Where(x => x.Type == Configuration.CharacterType.PartOfCharacterGroup &&
|
||||||
x.CharacterGroupId == group.Id)
|
x.CharacterGroupId == group.Id)
|
||||||
|
.OrderBy(x => x.WorldName)
|
||||||
|
.ThenBy(x => x.LocalContentId)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
if (_currentEditPopups.TryGetValue(group.Id, out TemporaryConfig? temporaryConfig) && ImGui.BeginPopup($"##EditGroup{group.Id}"))
|
||||||
|
{
|
||||||
|
(bool save, bool canSave) = DrawGroupEditor(temporaryConfig, group);
|
||||||
|
|
||||||
|
ImGui.BeginDisabled(!canSave || group.Name == temporaryConfig.Name);
|
||||||
|
save |= ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Save, "Save");
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
|
if (save && canSave)
|
||||||
|
{
|
||||||
|
group.Name = temporaryConfig.Name;
|
||||||
|
|
||||||
|
ImGui.CloseCurrentPopup();
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.BeginDisabled(assignedCharacters.Count > 0);
|
||||||
|
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Times, "Delete"))
|
||||||
|
{
|
||||||
|
groupToDelete = group;
|
||||||
|
ImGui.CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
if (assignedCharacters.Count > 0 && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
||||||
|
{
|
||||||
|
ImGui.BeginTooltip();
|
||||||
|
ImGui.Text(
|
||||||
|
$"Remove the {assignedCharacters.Count} character(s) from this group before deleting it.");
|
||||||
|
foreach (var character in assignedCharacters)
|
||||||
|
ImGui.BulletText($"{character.CharacterName} @ {character.WorldName}");
|
||||||
|
ImGui.EndTooltip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawCharacterGroup(Configuration.CharacterGroup group, List<Configuration.CharacterConfiguration> assignedCharacters)
|
||||||
|
{
|
||||||
string countLabel = assignedCharacters.Count == 0 ? "no characters"
|
string countLabel = assignedCharacters.Count == 0 ? "no characters"
|
||||||
: assignedCharacters.Count == 1 ? "1 character"
|
: assignedCharacters.Count == 1 ? "1 character"
|
||||||
: $"{assignedCharacters.Count} characters";
|
: $"{assignedCharacters.Count} characters";
|
||||||
@ -375,7 +603,7 @@ internal sealed class ConfigWindow : Window
|
|||||||
{
|
{
|
||||||
if (ImGui.BeginTabItem("Venture Lists"))
|
if (ImGui.BeginTabItem("Venture Lists"))
|
||||||
{
|
{
|
||||||
DrawListSelection(group.Id.ToString(), group.ItemListIds);
|
DrawVentureListSelection(group.Id.ToString(), group.ItemListIds);
|
||||||
ImGui.EndTabItem();
|
ImGui.EndTabItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,47 +622,65 @@ internal sealed class ConfigWindow : Window
|
|||||||
|
|
||||||
ImGui.Unindent(30);
|
ImGui.Unindent(30);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.PopID();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.Separator();
|
private void DrawNewCharacterGroup()
|
||||||
|
{
|
||||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Plus, "Add Group"))
|
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Plus, "Add Group"))
|
||||||
ImGui.OpenPopup("##AddGroup");
|
ImGui.OpenPopup("##AddGroup");
|
||||||
|
|
||||||
if (ImGui.BeginPopup("##AddGroup"))
|
if (ImGui.BeginPopup("##AddGroup"))
|
||||||
{
|
{
|
||||||
bool save = ImGui.InputTextWithHint("", "Group Name...", ref _newGroupName, 64, ImGuiInputTextFlags.EnterReturnsTrue);
|
(bool save, bool canSave) = DrawGroupEditor(_newGroup, null);
|
||||||
bool canSave = _newGroupName.Length >= 2 &&
|
|
||||||
!_configuration.CharacterGroups.Any(x => _newGroupName.EqualsIgnoreCase(x.Name));
|
|
||||||
ImGui.BeginDisabled(!canSave);
|
ImGui.BeginDisabled(!canSave);
|
||||||
save |= ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Save, "Save");
|
save |= ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Save, "Save");
|
||||||
ImGui.EndDisabled();
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
if (canSave && save)
|
if (save && canSave)
|
||||||
{
|
{
|
||||||
_configuration.CharacterGroups.Add(new Configuration.CharacterGroup
|
_configuration.CharacterGroups.Add(new Configuration.CharacterGroup
|
||||||
{
|
{
|
||||||
Id = Guid.NewGuid(),
|
Id = Guid.NewGuid(),
|
||||||
Name = _newGroupName,
|
Name = _newGroup.Name,
|
||||||
Icon = FontAwesomeIcon.None,
|
Icon = FontAwesomeIcon.None,
|
||||||
ItemListIds = new(),
|
ItemListIds = new(),
|
||||||
});
|
});
|
||||||
|
|
||||||
_newGroupName = string.Empty;
|
_newGroup = new() { Name = string.Empty };
|
||||||
|
|
||||||
ImGui.CloseCurrentPopup();
|
ImGui.CloseCurrentPopup();
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.EndPopup();
|
ImGui.EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.EndTabItem();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
private (bool Save, bool CanSave) DrawGroupEditor(TemporaryConfig group, Configuration.CharacterGroup? existingGroup)
|
||||||
|
{
|
||||||
|
string name = group.Name;
|
||||||
|
bool save = ImGui.InputTextWithHint("", "Group Name...", ref name, 64, ImGuiInputTextFlags.EnterReturnsTrue);
|
||||||
|
bool canSave = IsValidGroupName(name, existingGroup);
|
||||||
|
|
||||||
|
group.Name = name;
|
||||||
|
return (save, canSave);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsValidGroupName(string name, Configuration.CharacterGroup? existingGroup)
|
||||||
|
{
|
||||||
|
return name.Length >= 2 &&
|
||||||
|
!name.Contains('%') &&
|
||||||
|
!_configuration.CharacterGroups.Any(x => x != existingGroup && name.EqualsIgnoreCase(x.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsValidListName(string name, Configuration.ItemList? existingList)
|
||||||
|
{
|
||||||
|
return name.Length >= 2 &&
|
||||||
|
!name.Contains('%') &&
|
||||||
|
!_configuration.ItemLists.Any(x => x != existingList && name.EqualsIgnoreCase(x.Name));
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawGatheredItemsToCheck()
|
private void DrawGatheredItemsToCheck()
|
||||||
{
|
{
|
||||||
if (ImGui.BeginTabItem("Locked Items"))
|
if (ImGui.BeginTabItem("Locked Items"))
|
||||||
@ -444,7 +690,8 @@ internal sealed class ConfigWindow : Window
|
|||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
var itemsToCheck =
|
var itemsToCheck =
|
||||||
_configuration.QueuedItems
|
_configuration.ItemLists
|
||||||
|
.SelectMany(x => x.Items)
|
||||||
.Select(x => x.ItemId)
|
.Select(x => x.ItemId)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.Select(itemId => new
|
.Select(itemId => new
|
||||||
@ -462,10 +709,10 @@ internal sealed class ConfigWindow : Window
|
|||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var charactersToCheck = _configuration.Characters
|
var charactersToCheck = _configuration.Characters
|
||||||
.Where(x => x.Managed)
|
.Where(x => x.Type != Configuration.CharacterType.NotManaged)
|
||||||
.OrderBy(x => x.WorldName)
|
.OrderBy(x => x.WorldName)
|
||||||
.ThenBy(x => x.LocalContentId)
|
.ThenBy(x => x.LocalContentId)
|
||||||
.Select(x => new CheckedCharacter(x, itemsToCheck))
|
.Select(x => new CheckedCharacter(_configuration, x, itemsToCheck))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (_checkPerCharacter)
|
if (_checkPerCharacter)
|
||||||
@ -552,9 +799,9 @@ internal sealed class ConfigWindow : Window
|
|||||||
|
|
||||||
ImGui.EndTabItem();
|
ImGui.EndTabItem();
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
|
||||||
private void DrawListSelection(string id, List<Guid> selectedLists)
|
private void DrawVentureListSelection(string id, List<Guid> selectedLists)
|
||||||
{
|
{
|
||||||
ImGui.PushID($"##ListSelection{id}");
|
ImGui.PushID($"##ListSelection{id}");
|
||||||
|
|
||||||
@ -565,17 +812,21 @@ internal sealed class ConfigWindow : Window
|
|||||||
Id = Guid.Empty,
|
Id = Guid.Empty,
|
||||||
Name = "---",
|
Name = "---",
|
||||||
Type = Configuration.ListType.CollectOneTime,
|
Type = Configuration.ListType.CollectOneTime,
|
||||||
|
Priority = Configuration.ListPriority.InOrder,
|
||||||
}
|
}
|
||||||
}.Concat(_configuration.ItemLists)
|
}.Concat(_configuration.ItemLists)
|
||||||
.Select(x => (x.Id, x.Name, x)).ToList();
|
.Select(x => (x.Id, x.Name, x)).ToList();
|
||||||
int? itemToRemove = null;
|
int? itemToRemove = null;
|
||||||
|
int? itemToAdd = null;
|
||||||
|
int indexToAdd = 0;
|
||||||
|
float windowX = ImGui.GetContentRegionAvail().X;
|
||||||
for (int i = 0; i < selectedLists.Count; ++i)
|
for (int i = 0; i < selectedLists.Count; ++i)
|
||||||
{
|
{
|
||||||
|
|
||||||
ImGui.PushID($"##{id}_Item{i}");
|
ImGui.PushID($"##{id}_Item{i}");
|
||||||
var listId = selectedLists[i];
|
var listId = selectedLists[i];
|
||||||
var listIndex = itemLists.FindIndex(x => x.Id == listId);
|
var listIndex = itemLists.FindIndex(x => x.Id == listId);
|
||||||
|
|
||||||
|
ImGui.SetNextItemWidth(windowX - 76);
|
||||||
if (ImGui.Combo("", ref listIndex, itemLists.Select(x => x.Name).ToArray(), itemLists.Count))
|
if (ImGui.Combo("", ref listIndex, itemLists.Select(x => x.Name).ToArray(), itemLists.Count))
|
||||||
{
|
{
|
||||||
selectedLists[i] = itemLists[listIndex].Id;
|
selectedLists[i] = itemLists[listIndex].Id;
|
||||||
@ -583,22 +834,22 @@ internal sealed class ConfigWindow : Window
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (ImGuiComponents.IconButton($"##Jump{i}", FontAwesomeIcon.Edit))
|
ImGui.BeginDisabled(i == 0);
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
if (ImGuiComponents.IconButton($"##Up{i}", FontAwesomeIcon.ArrowUp))
|
if (ImGuiComponents.IconButton($"##Up{i}", FontAwesomeIcon.ArrowUp))
|
||||||
{
|
{
|
||||||
|
itemToAdd = i;
|
||||||
|
indexToAdd = i - 1;
|
||||||
}
|
}
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
ImGui.SameLine(0, 0);
|
ImGui.SameLine(0, 0);
|
||||||
|
ImGui.BeginDisabled(i == selectedLists.Count - 1);
|
||||||
if (ImGuiComponents.IconButton($"##Down{i}", FontAwesomeIcon.ArrowDown))
|
if (ImGuiComponents.IconButton($"##Down{i}", FontAwesomeIcon.ArrowDown))
|
||||||
{
|
{
|
||||||
|
itemToAdd = i;
|
||||||
|
indexToAdd = i + 1;
|
||||||
}
|
}
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (ImGuiComponents.IconButton($"##Remove{i}", FontAwesomeIcon.Times))
|
if (ImGuiComponents.IconButton($"##Remove{i}", FontAwesomeIcon.Times))
|
||||||
@ -617,8 +868,8 @@ internal sealed class ConfigWindow : Window
|
|||||||
var list = itemLists[listIndex].List;
|
var list = itemLists[listIndex].List;
|
||||||
ImGui.Indent(30);
|
ImGui.Indent(30);
|
||||||
ImGui.Text(list.Type == Configuration.ListType.CollectOneTime
|
ImGui.Text(list.Type == Configuration.ListType.CollectOneTime
|
||||||
? $"{SeIconChar.LinkMarker.ToIconString()} Items on this list will be collected once."
|
? $"{SeIconChar.BoxedNumber1.ToIconString()} Items on this list will be collected once."
|
||||||
: $"{SeIconChar.LinkMarker.ToIconString()} Items on this list will be kept in stock on each character.");
|
: $"{SeIconChar.Circle.ToIconString()} Items on this list will be kept in stock on each character.");
|
||||||
ImGui.Spacing();
|
ImGui.Spacing();
|
||||||
foreach (var item in list.Items)
|
foreach (var item in list.Items)
|
||||||
{
|
{
|
||||||
@ -639,6 +890,14 @@ internal sealed class ConfigWindow : Window
|
|||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (itemToAdd != null)
|
||||||
|
{
|
||||||
|
Guid listId = selectedLists[itemToAdd.Value];
|
||||||
|
selectedLists.RemoveAt(itemToAdd.Value);
|
||||||
|
selectedLists.Insert(indexToAdd, listId);
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
var unusedLists = itemLists.Where(x => x.Id != Guid.Empty && !selectedLists.Contains(x.Id)).ToList();
|
var unusedLists = itemLists.Where(x => x.Id != Guid.Empty && !selectedLists.Contains(x.Id)).ToList();
|
||||||
ImGui.BeginDisabled(unusedLists.Count == 0);
|
ImGui.BeginDisabled(unusedLists.Count == 0);
|
||||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Plus, "Add Venture List to this Group"))
|
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Plus, "Add Venture List to this Group"))
|
||||||
@ -669,16 +928,44 @@ internal sealed class ConfigWindow : Window
|
|||||||
|
|
||||||
private sealed class CheckedCharacter
|
private sealed class CheckedCharacter
|
||||||
{
|
{
|
||||||
public CheckedCharacter(Configuration.CharacterConfiguration character,
|
public CheckedCharacter(Configuration configuration, Configuration.CharacterConfiguration character,
|
||||||
List<CheckedItem> itemsToCheck)
|
List<CheckedItem> itemsToCheck)
|
||||||
{
|
{
|
||||||
Character = character;
|
Character = character;
|
||||||
|
|
||||||
|
List<Guid> itemListIds = new();
|
||||||
|
if (character.Type == Configuration.CharacterType.Standalone)
|
||||||
|
{
|
||||||
|
itemListIds = character.ItemListIds;
|
||||||
|
}
|
||||||
|
else if (character.Type == Configuration.CharacterType.PartOfCharacterGroup)
|
||||||
|
{
|
||||||
|
var group = configuration.CharacterGroups.SingleOrDefault(x => x.Id == character.CharacterGroupId);
|
||||||
|
if (group != null)
|
||||||
|
itemListIds = group.ItemListIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
var itemIdsOnLists = itemListIds.Where(listId => listId != Guid.Empty)
|
||||||
|
.Select(listId => configuration.ItemLists.SingleOrDefault(x => x.Id == listId))
|
||||||
|
.Where(list => list != null)
|
||||||
|
.SelectMany(list => list!.Items)
|
||||||
|
.Select(x => x.ItemId)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
foreach (var item in itemsToCheck)
|
foreach (var item in itemsToCheck)
|
||||||
{
|
{
|
||||||
|
// check if the item is on any relevant list
|
||||||
|
if (!itemIdsOnLists.Contains(item.ItemId))
|
||||||
|
{
|
||||||
|
Items[item.ItemId] = ColorGrey;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we are the correct job
|
||||||
bool enabled = character.Retainers.Any(x => item.Ventures.Any(v => v.MatchesJob(x.Job)));
|
bool enabled = character.Retainers.Any(x => item.Ventures.Any(v => v.MatchesJob(x.Job)));
|
||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
|
// do we have it gathered on this char?
|
||||||
if (character.GatheredItems.Contains(item.GatheredItem.GatheredItemId))
|
if (character.GatheredItems.Contains(item.GatheredItem.GatheredItemId))
|
||||||
Items[item.ItemId] = ColorGreen;
|
Items[item.ItemId] = ColorGreen;
|
||||||
else
|
else
|
||||||
@ -706,4 +993,11 @@ internal sealed class ConfigWindow : Window
|
|||||||
public required List<Venture> Ventures { get; init; }
|
public required List<Venture> Ventures { get; init; }
|
||||||
public required uint ItemId { get; init; }
|
public required uint ItemId { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sealed class TemporaryConfig
|
||||||
|
{
|
||||||
|
public required string Name { get; set; }
|
||||||
|
public Configuration.ListType ListType { get; set; }
|
||||||
|
public Configuration.ListPriority ListPriority { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user