(2.x) Update Lists/locked items tabs

This commit is contained in:
Liza 2023-10-10 12:08:26 +02:00
parent 189d4fb0a7
commit 6564a49369
Signed by: liza
GPG Key ID: 7199F8D727D55F67
2 changed files with 503 additions and 202 deletions

View File

@ -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; }

View File

@ -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,146 +72,294 @@ 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)
{ {
ImGuiEx.SetNextItemFullWidth(); ImGui.PushID($"List{list.Id}");
ImGui.InputTextWithHint("", "Filter...", ref _searchString, 256);
foreach (var ventures in _gameCache.Ventures if (ImGuiComponents.IconButton(FontAwesomeIcon.Cog))
.Where(x => x.Name.ToLower().Contains(_searchString.ToLower()))
.OrderBy(x => x.Level)
.ThenBy(x => x.Name)
.ThenBy(x => x.ItemId)
.GroupBy(x => x.ItemId))
{ {
var venture = ventures.First(); _currentEditPopups[list.Id] = new TemporaryConfig
if (ImGui.Selectable(
$"{venture.Name} ({string.Join(" ", ventures.Select(x => x.CategoryName))})##SelectVenture{venture.RowId}"))
{ {
_configuration.QueuedItems.Add(new Configuration.QueuedItem Name = list.Name,
{ ListType = list.Type,
ItemId = venture.ItemId, ListPriority = list.Priority,
RemainingQuantity = 0, };
}); ImGui.OpenPopup($"##EditList{list.Id}");
_searchString = string.Empty;
Save();
}
} }
DrawVentureListEditorPopup(list, ref listToDelete);
ImGui.EndCombo(); ImGui.SameLine();
} if (ImGui.CollapsingHeader($"{list.Name} {(list.Type == Configuration.ListType.CollectOneTime ? SeIconChar.BoxedNumber1.ToIconChar() : SeIconChar.Circle.ToIconChar())}"))
ImGui.Separator();
ImGui.Indent(30);
Configuration.QueuedItem? itemToRemove = null;
Configuration.QueuedItem? itemToAdd = null;
int indexToAdd = 0;
for (int i = 0; i < _configuration.QueuedItems.Count; ++i)
{
var item = _configuration.QueuedItems[i];
ImGui.PushID($"QueueItem{i}");
var ventures = _gameCache.Ventures.Where(x => x.ItemId == item.ItemId).ToList();
var venture = ventures.First();
if (!_enableDragDrop)
{ {
ImGui.SetNextItemWidth(130); ImGui.Indent(30);
int quantity = item.RemainingQuantity; DrawVentureListItemSelection(list);
if (ImGui.InputInt($"{venture.Name} ({string.Join(" ", ventures.Select(x => x.CategoryName))})", ImGui.Unindent(30);
ref quantity, 100))
{
item.RemainingQuantity = quantity;
Save();
}
} }
else
{
ImGui.Selectable($"{item.RemainingQuantity}x {venture.Name}");
if (ImGui.BeginDragDropSource())
{
ImGui.SetDragDropPayload("ArcDragDrop", nint.Zero, 0);
_dragDropSource = item;
ImGui.EndDragDropSource();
}
if (ImGui.BeginDragDropTarget())
{
if (_dragDropSource != null && ImGui.AcceptDragDropPayload("ArcDragDrop").NativePtr != null)
{
itemToAdd = _dragDropSource;
indexToAdd = i;
_dragDropSource = null;
}
ImGui.EndDragDropTarget();
}
}
ImGui.OpenPopupOnItemClick($"###ctx{i}", ImGuiPopupFlags.MouseButtonRight);
if (ImGui.BeginPopupContextItem($"###ctx{i}"))
{
if (ImGui.MenuItem($"Remove {venture.Name}"))
itemToRemove = item;
ImGui.EndPopup();
}
ImGui.PopID(); ImGui.PopID();
} }
if (itemToRemove != null) if (listToDelete != null)
{ {
_configuration.QueuedItems.Remove(itemToRemove); _configuration.ItemLists.Remove(listToDelete);
Save(); Save();
} }
if (itemToAdd != null) ImGui.Separator();
{ DrawNewVentureList();
_pluginLog.Information($"Updating {itemToAdd.ItemId} → {indexToAdd}");
_configuration.QueuedItems.Remove(itemToAdd);
_configuration.QueuedItems.Insert(indexToAdd, itemToAdd);
Save();
}
ImGui.Unindent(30);
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.SameLine();
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Check, "Remove all finished items"))
{
if (_configuration.QueuedItems.RemoveAll(q => q.RemainingQuantity == 0) > 0)
Save();
}
ImGui.EndTabItem(); 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();
ImGui.InputTextWithHint("", "Filter...", ref _searchString, 256);
foreach (var ventures in _gameCache.Ventures
.Where(x => x.Name.ToLower().Contains(_searchString.ToLower()))
.OrderBy(x => x.Level)
.ThenBy(x => x.Name)
.ThenBy(x => x.ItemId)
.GroupBy(x => x.ItemId))
{
var venture = ventures.First();
if (ImGui.Selectable(
$"{venture.Name} ({string.Join(" ", ventures.Select(x => x.CategoryName))})##SelectVenture{venture.RowId}"))
{
list.Items.Add(new Configuration.QueuedItem
{
ItemId = venture.ItemId,
RemainingQuantity = 0,
});
_searchString = string.Empty;
Save();
}
}
ImGui.EndCombo();
}
ImGui.Separator();
Configuration.QueuedItem? itemToRemove = null;
Configuration.QueuedItem? itemToAdd = null;
int indexToAdd = 0;
float windowX = ImGui.GetContentRegionAvail().X;
for (int i = 0; i < list.Items.Count; ++i)
{
var item = list.Items[i];
ImGui.PushID($"QueueItem{i}");
var ventures = _gameCache.Ventures.Where(x => x.ItemId == item.ItemId).ToList();
var venture = ventures.First();
ImGui.SetNextItemWidth(130);
int quantity = item.RemainingQuantity;
if (ImGui.InputInt($"{venture.Name} ({string.Join(" ", ventures.Select(x => x.CategoryName))})",
ref quantity, 100))
{
item.RemainingQuantity = quantity;
Save();
}
ImGui.SameLine(windowX - 30);
ImGui.BeginDisabled(i == 0);
if (ImGuiComponents.IconButton($"##Up{i}", FontAwesomeIcon.ArrowUp))
{
itemToAdd = item;
indexToAdd = i - 1;
}
ImGui.EndDisabled();
ImGui.SameLine(0, 0);
ImGui.BeginDisabled(i == list.Items.Count - 1);
if (ImGuiComponents.IconButton($"##Down{i}", FontAwesomeIcon.ArrowDown))
{
itemToAdd = item;
indexToAdd = i + 1;
}
ImGui.EndDisabled();
ImGui.SameLine();
if (ImGuiComponents.IconButton($"##Remove{i}", FontAwesomeIcon.Times))
itemToRemove = item;
ImGui.PopID();
}
if (itemToRemove != null)
{
list.Items.Remove(itemToRemove);
Save();
}
if (itemToAdd != null)
{
_pluginLog.Information($"Updating {itemToAdd.ItemId} → {indexToAdd}");
list.Items.Remove(itemToAdd);
list.Items.Insert(indexToAdd, itemToAdd);
Save();
}
if (list.Items.Count > 0 && list.Type == Configuration.ListType.CollectOneTime)
{
ImGui.BeginDisabled(list.Items.All(x => x.RemainingQuantity > 0));
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Check, "Remove all finished items"))
{
list.Items.RemoveAll(q => q.RemainingQuantity <= 0);
Save();
}
ImGui.EndDisabled();
ImGui.Spacing();
}
}
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,87 +511,176 @@ 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();
var assignedCharacters = _configuration.Characters
.Where(x => x.Type == Configuration.CharacterType.PartOfCharacterGroup &&
x.CharacterGroupId == group.Id)
.ToList();
string countLabel = assignedCharacters.Count == 0 ? "no characters"
: assignedCharacters.Count == 1 ? "1 character"
: $"{assignedCharacters.Count} characters";
if (ImGui.CollapsingHeader($"{group.Name} ({countLabel})"))
{ {
ImGui.Indent(30); _currentEditPopups[group.Id] = new TemporaryConfig
if (ImGui.BeginTabBar("GroupOptions"))
{ {
if (ImGui.BeginTabItem("Venture Lists")) Name = group.Name,
{ };
DrawListSelection(group.Id.ToString(), group.ItemListIds); ImGui.OpenPopup($"##EditGroup{group.Id}");
ImGui.EndTabItem();
}
if (ImGui.BeginTabItem("Characters"))
{
ImGui.Text("Characters in this group:");
ImGui.Indent(30);
foreach (var character in assignedCharacters.OrderBy(x => x.WorldName)
.ThenBy(x => x.LocalContentId))
ImGui.TextUnformatted($"{character.CharacterName} @ {character.WorldName}");
ImGui.Unindent(30);
}
ImGui.EndTabBar();
}
ImGui.Unindent(30);
} }
DrawCharacterGroupEditorPopup(group, out var assignedCharacters, ref groupToDelete);
ImGui.SameLine();
DrawCharacterGroup(group, assignedCharacters);
ImGui.PopID(); ImGui.PopID();
} }
ImGui.Separator(); if (groupToDelete != null)
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Plus, "Add Group"))
ImGui.OpenPopup("##AddGroup");
if (ImGui.BeginPopup("##AddGroup"))
{ {
bool save = ImGui.InputTextWithHint("", "Group Name...", ref _newGroupName, 64, ImGuiInputTextFlags.EnterReturnsTrue); _configuration.CharacterGroups.Remove(groupToDelete);
bool canSave = _newGroupName.Length >= 2 && Save();
!_configuration.CharacterGroups.Any(x => _newGroupName.EqualsIgnoreCase(x.Name));
ImGui.BeginDisabled(!canSave);
save |= ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Save, "Save");
ImGui.EndDisabled();
if (canSave && save)
{
_configuration.CharacterGroups.Add(new Configuration.CharacterGroup
{
Id = Guid.NewGuid(),
Name = _newGroupName,
Icon = FontAwesomeIcon.None,
ItemListIds = new(),
});
_newGroupName = string.Empty;
ImGui.CloseCurrentPopup();
Save();
}
ImGui.EndPopup();
} }
ImGui.Separator();
DrawNewCharacterGroup();
ImGui.EndTabItem(); 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 &&
x.CharacterGroupId == group.Id)
.OrderBy(x => x.WorldName)
.ThenBy(x => x.LocalContentId)
.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"
: assignedCharacters.Count == 1 ? "1 character"
: $"{assignedCharacters.Count} characters";
if (ImGui.CollapsingHeader($"{group.Name} ({countLabel})"))
{
ImGui.Indent(30);
if (ImGui.BeginTabBar("GroupOptions"))
{
if (ImGui.BeginTabItem("Venture Lists"))
{
DrawVentureListSelection(group.Id.ToString(), group.ItemListIds);
ImGui.EndTabItem();
}
if (ImGui.BeginTabItem("Characters"))
{
ImGui.Text("Characters in this group:");
ImGui.Indent(30);
foreach (var character in assignedCharacters.OrderBy(x => x.WorldName)
.ThenBy(x => x.LocalContentId))
ImGui.TextUnformatted($"{character.CharacterName} @ {character.WorldName}");
ImGui.Unindent(30);
}
ImGui.EndTabBar();
}
ImGui.Unindent(30);
}
}
private void DrawNewCharacterGroup()
{
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Plus, "Add Group"))
ImGui.OpenPopup("##AddGroup");
if (ImGui.BeginPopup("##AddGroup"))
{
(bool save, bool canSave) = DrawGroupEditor(_newGroup, null);
ImGui.BeginDisabled(!canSave);
save |= ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Save, "Save");
ImGui.EndDisabled();
if (save && canSave)
{
_configuration.CharacterGroups.Add(new Configuration.CharacterGroup
{
Id = Guid.NewGuid(),
Name = _newGroup.Name,
Icon = FontAwesomeIcon.None,
ItemListIds = new(),
});
_newGroup = new() { Name = string.Empty };
ImGui.CloseCurrentPopup();
Save();
}
ImGui.EndPopup();
}
}
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; }
}
} }