forked from liza/Questionable
Add Statistics/Progress window
This commit is contained in:
parent
ba0edc562b
commit
0d2ce03164
@ -44,6 +44,8 @@ internal sealed class QuestRegistry
|
|||||||
public int ValidationIssueCount => _questValidator.IssueCount;
|
public int ValidationIssueCount => _questValidator.IssueCount;
|
||||||
public int ValidationErrorCount => _questValidator.ErrorCount;
|
public int ValidationErrorCount => _questValidator.ErrorCount;
|
||||||
|
|
||||||
|
public event EventHandler? Reloaded;
|
||||||
|
|
||||||
public void Reload()
|
public void Reload()
|
||||||
{
|
{
|
||||||
_questValidator.Reset();
|
_questValidator.Reset();
|
||||||
@ -63,6 +65,7 @@ internal sealed class QuestRegistry
|
|||||||
}
|
}
|
||||||
|
|
||||||
ValidateQuests();
|
ValidateQuests();
|
||||||
|
Reloaded?.Invoke(this, EventArgs.Empty);
|
||||||
_logger.LogInformation("Loaded {Count} quests in total", _quests.Count);
|
_logger.LogInformation("Loaded {Count} quests in total", _quests.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,8 @@ internal sealed class DalamudInitializer : IDisposable
|
|||||||
DebugOverlay debugOverlay,
|
DebugOverlay debugOverlay,
|
||||||
ConfigWindow configWindow,
|
ConfigWindow configWindow,
|
||||||
QuestSelectionWindow questSelectionWindow,
|
QuestSelectionWindow questSelectionWindow,
|
||||||
QuestValidationWindow questValidationWindow)
|
QuestValidationWindow questValidationWindow,
|
||||||
|
JournalProgressWindow journalProgressWindow)
|
||||||
{
|
{
|
||||||
_pluginInterface = pluginInterface;
|
_pluginInterface = pluginInterface;
|
||||||
_framework = framework;
|
_framework = framework;
|
||||||
@ -46,6 +47,7 @@ internal sealed class DalamudInitializer : IDisposable
|
|||||||
_windowSystem.AddWindow(debugOverlay);
|
_windowSystem.AddWindow(debugOverlay);
|
||||||
_windowSystem.AddWindow(questSelectionWindow);
|
_windowSystem.AddWindow(questSelectionWindow);
|
||||||
_windowSystem.AddWindow(questValidationWindow);
|
_windowSystem.AddWindow(questValidationWindow);
|
||||||
|
_windowSystem.AddWindow(journalProgressWindow);
|
||||||
|
|
||||||
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
|
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
|
||||||
_pluginInterface.UiBuilder.OpenMainUi += _questWindow.Toggle;
|
_pluginInterface.UiBuilder.OpenMainUi += _questWindow.Toggle;
|
||||||
|
96
Questionable/Data/JournalData.cs
Normal file
96
Questionable/Data/JournalData.cs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Dalamud.Plugin.Services;
|
||||||
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
using Questionable.Model;
|
||||||
|
|
||||||
|
namespace Questionable.Data;
|
||||||
|
|
||||||
|
internal sealed class JournalData
|
||||||
|
{
|
||||||
|
public JournalData(IDataManager dataManager, QuestData questData)
|
||||||
|
{
|
||||||
|
var genres = dataManager.GetExcelSheet<JournalGenre>()!
|
||||||
|
.Where(x => x.RowId > 0 && x.Icon > 0)
|
||||||
|
.Select(x => new Genre(x, questData.GetAllByJournalGenre(x.RowId)))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var limsaStart = dataManager.GetExcelSheet<QuestRedo>()!.GetRow(1)!;
|
||||||
|
var gridaniaStart = dataManager.GetExcelSheet<QuestRedo>()!.GetRow(2)!;
|
||||||
|
var uldahStart = dataManager.GetExcelSheet<QuestRedo>()!.GetRow(3)!;
|
||||||
|
var genreLimsa = new Genre(uint.MaxValue - 3, "Starting in Limsa Lominsa", 1,
|
||||||
|
new uint[] { 108, 109 }.Concat(limsaStart.Quest.Select(x => x.Row))
|
||||||
|
.Where(x => x != 0)
|
||||||
|
.Select(x => questData.GetQuestInfo((ushort)(x & 0xFFFF))).ToList());
|
||||||
|
var genreGridania = new Genre(uint.MaxValue - 2, "Starting in Gridania", 1,
|
||||||
|
new uint[] { 85, 123, 124 }.Concat(gridaniaStart.Quest.Select(x => x.Row))
|
||||||
|
.Where(x => x != 0)
|
||||||
|
.Select(x => questData.GetQuestInfo((ushort)(x & 0xFFFF))).ToList());
|
||||||
|
var genreUldah = new Genre(uint.MaxValue - 1, "Starting in Ul'dah", 1,
|
||||||
|
new uint[] { 568, 569, 570 }.Concat(uldahStart.Quest.Select(x => x.Row))
|
||||||
|
.Where(x => x != 0)
|
||||||
|
.Select(x => questData.GetQuestInfo((ushort)(x & 0xFFFF)))
|
||||||
|
.ToList());
|
||||||
|
genres.InsertRange(0, [genreLimsa, genreGridania, genreUldah]);
|
||||||
|
genres.Single(x => x.Id == 1)
|
||||||
|
.Quests
|
||||||
|
.RemoveAll(x =>
|
||||||
|
genreLimsa.Quests.Contains(x) || genreGridania.Quests.Contains(x) || genreUldah.Quests.Contains(x));
|
||||||
|
|
||||||
|
Genres = genres.AsReadOnly();
|
||||||
|
Categories = dataManager.GetExcelSheet<JournalCategory>()!
|
||||||
|
.Where(x => x.RowId > 0)
|
||||||
|
.Select(x => new Category(x, Genres.Where(y => y.CategoryId == x.RowId).ToList()))
|
||||||
|
.ToList()
|
||||||
|
.AsReadOnly();
|
||||||
|
Sections = dataManager.GetExcelSheet<JournalSection>()!
|
||||||
|
.Select(x => new Section(x, Categories.Where(y => y.SectionId == x.RowId).ToList()))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReadOnlyList<Genre> Genres { get; }
|
||||||
|
public IReadOnlyList<Category> Categories { get; }
|
||||||
|
public List<Section> Sections { get; set; }
|
||||||
|
|
||||||
|
internal sealed class Genre
|
||||||
|
{
|
||||||
|
public Genre(JournalGenre journalGenre, List<QuestInfo> quests)
|
||||||
|
{
|
||||||
|
Id = journalGenre.RowId;
|
||||||
|
Name = journalGenre.Name.ToString();
|
||||||
|
CategoryId = journalGenre.JournalCategory.Row;
|
||||||
|
Quests = quests;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Genre(uint id, string name, uint categoryId, List<QuestInfo> quests)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
Name = name;
|
||||||
|
CategoryId = categoryId;
|
||||||
|
Quests = quests;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Id { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public uint CategoryId { get; }
|
||||||
|
public List<QuestInfo> Quests { get; }
|
||||||
|
public int QuestCount => Quests.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class Category(JournalCategory journalCategory, IReadOnlyList<Genre> genres)
|
||||||
|
{
|
||||||
|
public uint Id { get; } = journalCategory.RowId;
|
||||||
|
public string Name { get; } = journalCategory.Name.ToString();
|
||||||
|
public uint SectionId { get; } = journalCategory.JournalSection.Row;
|
||||||
|
public IReadOnlyList<Genre> Genres { get; } = genres;
|
||||||
|
public int QuestCount => Genres.Sum(x => x.QuestCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class Section(JournalSection journalSection, IReadOnlyList<Category> categories)
|
||||||
|
{
|
||||||
|
public uint Id { get; } = journalSection.RowId;
|
||||||
|
public string Name { get; } = journalSection.Name.ToString();
|
||||||
|
public IReadOnlyList<Category> Categories { get; } = categories;
|
||||||
|
public int QuestCount => Categories.Sum(x => x.QuestCount);
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@ internal sealed class QuestData
|
|||||||
_quests = dataManager.GetExcelSheet<Quest>()!
|
_quests = dataManager.GetExcelSheet<Quest>()!
|
||||||
.Where(x => x.RowId > 0)
|
.Where(x => x.RowId > 0)
|
||||||
.Where(x => x.IssuerLocation.Row > 0)
|
.Where(x => x.IssuerLocation.Row > 0)
|
||||||
|
.Where(x => x.Festival.Row == 0)
|
||||||
.Select(x => new QuestInfo(x))
|
.Select(x => new QuestInfo(x))
|
||||||
.ToImmutableDictionary(x => x.QuestId, x => x);
|
.ToImmutableDictionary(x => x.QuestId, x => x);
|
||||||
}
|
}
|
||||||
@ -34,4 +35,13 @@ internal sealed class QuestData
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool IsIssuerOfAnyQuest(uint targetId) => _quests.Values.Any(x => x.IssuerDataId == targetId);
|
public bool IsIssuerOfAnyQuest(uint targetId) => _quests.Values.Any(x => x.IssuerDataId == targetId);
|
||||||
|
|
||||||
|
public List<QuestInfo> GetAllByJournalGenre(uint journalGenre)
|
||||||
|
{
|
||||||
|
return _quests.Values
|
||||||
|
.Where(x => x.JournalGenre == journalGenre)
|
||||||
|
.OrderBy(x => x.SortKey)
|
||||||
|
.ThenBy(x => x.QuestId)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,23 @@ internal sealed class QuestInfo
|
|||||||
public QuestInfo(ExcelQuest quest)
|
public QuestInfo(ExcelQuest quest)
|
||||||
{
|
{
|
||||||
QuestId = (ushort)(quest.RowId & 0xFFFF);
|
QuestId = (ushort)(quest.RowId & 0xFFFF);
|
||||||
Name = quest.Name.ToString();
|
|
||||||
|
string suffix = QuestId switch
|
||||||
|
{
|
||||||
|
85 => " (LNC)",
|
||||||
|
108 => " (MRD)",
|
||||||
|
109 => " (ACN)",
|
||||||
|
123 => " (ARC)",
|
||||||
|
124 => " (CNJ)",
|
||||||
|
568 => " (GLA)",
|
||||||
|
569 => " (PGL)",
|
||||||
|
570 => " (THM)",
|
||||||
|
673 => " (Ul'dah)",
|
||||||
|
674 => " (Limsa/Gridania)",
|
||||||
|
_ => "",
|
||||||
|
};
|
||||||
|
|
||||||
|
Name = $"{quest.Name}{suffix}";
|
||||||
Level = quest.ClassJobLevel0;
|
Level = quest.ClassJobLevel0;
|
||||||
IssuerDataId = quest.IssuerStart;
|
IssuerDataId = quest.IssuerStart;
|
||||||
IsRepeatable = quest.IsRepeatable;
|
IsRepeatable = quest.IsRepeatable;
|
||||||
@ -22,6 +38,8 @@ internal sealed class QuestInfo
|
|||||||
PreviousQuestJoin = (QuestJoin)quest.PreviousQuestJoin;
|
PreviousQuestJoin = (QuestJoin)quest.PreviousQuestJoin;
|
||||||
QuestLocks = quest.QuestLock.Select(x => (ushort)(x.Row & 0xFFFFF)).Where(x => x != 0).ToImmutableList();
|
QuestLocks = quest.QuestLock.Select(x => (ushort)(x.Row & 0xFFFFF)).Where(x => x != 0).ToImmutableList();
|
||||||
QuestLockJoin = (QuestJoin)quest.QuestLockJoin;
|
QuestLockJoin = (QuestJoin)quest.QuestLockJoin;
|
||||||
|
JournalGenre = quest.JournalGenre?.Row;
|
||||||
|
SortKey = quest.SortKey;
|
||||||
IsMainScenarioQuest = quest.JournalGenre?.Value?.JournalCategory?.Value?.JournalSection?.Row is 0 or 1;
|
IsMainScenarioQuest = quest.JournalGenre?.Value?.JournalCategory?.Value?.JournalSection?.Row is 0 or 1;
|
||||||
CompletesInstantly = quest.ToDoCompleteSeq[0] == 0;
|
CompletesInstantly = quest.ToDoCompleteSeq[0] == 0;
|
||||||
PreviousInstanceContent = quest.InstanceContent.Select(x => (ushort)x.Row).Where(x => x != 0).ToList();
|
PreviousInstanceContent = quest.InstanceContent.Select(x => (ushort)x.Row).Where(x => x != 0).ToList();
|
||||||
@ -42,6 +60,8 @@ internal sealed class QuestInfo
|
|||||||
public QuestJoin QuestLockJoin { get; }
|
public QuestJoin QuestLockJoin { get; }
|
||||||
public List<ushort> PreviousInstanceContent { get; }
|
public List<ushort> PreviousInstanceContent { get; }
|
||||||
public QuestJoin PreviousInstanceContentJoin { get; }
|
public QuestJoin PreviousInstanceContentJoin { get; }
|
||||||
|
public uint? JournalGenre { get; }
|
||||||
|
public ushort SortKey { get; set; }
|
||||||
public bool IsMainScenarioQuest { get; }
|
public bool IsMainScenarioQuest { get; }
|
||||||
public bool CompletesInstantly { get; }
|
public bool CompletesInstantly { get; }
|
||||||
public GrandCompany GrandCompany { get; }
|
public GrandCompany GrandCompany { get; }
|
||||||
|
@ -89,6 +89,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
|||||||
serviceCollection.AddSingleton<ChatFunctions>();
|
serviceCollection.AddSingleton<ChatFunctions>();
|
||||||
serviceCollection.AddSingleton<AetherCurrentData>();
|
serviceCollection.AddSingleton<AetherCurrentData>();
|
||||||
serviceCollection.AddSingleton<AetheryteData>();
|
serviceCollection.AddSingleton<AetheryteData>();
|
||||||
|
serviceCollection.AddSingleton<JournalData>();
|
||||||
serviceCollection.AddSingleton<QuestData>();
|
serviceCollection.AddSingleton<QuestData>();
|
||||||
serviceCollection.AddSingleton<TerritoryData>();
|
serviceCollection.AddSingleton<TerritoryData>();
|
||||||
serviceCollection.AddSingleton<NavmeshIpc>();
|
serviceCollection.AddSingleton<NavmeshIpc>();
|
||||||
@ -159,6 +160,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
|||||||
serviceCollection.AddSingleton<ActiveQuestComponent>();
|
serviceCollection.AddSingleton<ActiveQuestComponent>();
|
||||||
serviceCollection.AddSingleton<ARealmRebornComponent>();
|
serviceCollection.AddSingleton<ARealmRebornComponent>();
|
||||||
serviceCollection.AddSingleton<CreationUtilsComponent>();
|
serviceCollection.AddSingleton<CreationUtilsComponent>();
|
||||||
|
serviceCollection.AddSingleton<QuestTooltipComponent>();
|
||||||
serviceCollection.AddSingleton<QuickAccessButtonsComponent>();
|
serviceCollection.AddSingleton<QuickAccessButtonsComponent>();
|
||||||
serviceCollection.AddSingleton<RemainingTasksComponent>();
|
serviceCollection.AddSingleton<RemainingTasksComponent>();
|
||||||
|
|
||||||
@ -167,6 +169,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
|||||||
serviceCollection.AddSingleton<DebugOverlay>();
|
serviceCollection.AddSingleton<DebugOverlay>();
|
||||||
serviceCollection.AddSingleton<QuestSelectionWindow>();
|
serviceCollection.AddSingleton<QuestSelectionWindow>();
|
||||||
serviceCollection.AddSingleton<QuestValidationWindow>();
|
serviceCollection.AddSingleton<QuestValidationWindow>();
|
||||||
|
serviceCollection.AddSingleton<JournalProgressWindow>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddQuestValidators(ServiceCollection serviceCollection)
|
private static void AddQuestValidators(ServiceCollection serviceCollection)
|
||||||
|
268
Questionable/Windows/JournalProgressWindow.cs
Normal file
268
Questionable/Windows/JournalProgressWindow.cs
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using Dalamud.Interface;
|
||||||
|
using Dalamud.Interface.Colors;
|
||||||
|
using Dalamud.Interface.Utility.Raii;
|
||||||
|
using Dalamud.Plugin.Services;
|
||||||
|
using ImGuiNET;
|
||||||
|
using LLib.ImGui;
|
||||||
|
using Questionable.Controller;
|
||||||
|
using Questionable.Data;
|
||||||
|
using Questionable.Model;
|
||||||
|
using Questionable.Windows.QuestComponents;
|
||||||
|
|
||||||
|
namespace Questionable.Windows;
|
||||||
|
|
||||||
|
internal sealed class JournalProgressWindow : LWindow, IDisposable
|
||||||
|
{
|
||||||
|
private readonly JournalData _journalData;
|
||||||
|
private readonly QuestRegistry _questRegistry;
|
||||||
|
private readonly GameFunctions _gameFunctions;
|
||||||
|
private readonly UiUtils _uiUtils;
|
||||||
|
private readonly QuestTooltipComponent _questTooltipComponent;
|
||||||
|
private readonly IClientState _clientState;
|
||||||
|
private readonly ICommandManager _commandManager;
|
||||||
|
|
||||||
|
private readonly Dictionary<JournalData.Genre, (int Available, int Completed)> _genreCounts = new();
|
||||||
|
private readonly Dictionary<JournalData.Category, (int Available, int Completed)> _categoryCounts = new();
|
||||||
|
private readonly Dictionary<JournalData.Section, (int Available, int Completed)> _sectionCounts = new();
|
||||||
|
|
||||||
|
public JournalProgressWindow(JournalData journalData,
|
||||||
|
QuestRegistry questRegistry,
|
||||||
|
GameFunctions gameFunctions,
|
||||||
|
UiUtils uiUtils,
|
||||||
|
QuestTooltipComponent questTooltipComponent,
|
||||||
|
IClientState clientState,
|
||||||
|
ICommandManager commandManager)
|
||||||
|
: base("Journal Progress###QuestionableJournalProgress")
|
||||||
|
{
|
||||||
|
_journalData = journalData;
|
||||||
|
_questRegistry = questRegistry;
|
||||||
|
_gameFunctions = gameFunctions;
|
||||||
|
_uiUtils = uiUtils;
|
||||||
|
_questTooltipComponent = questTooltipComponent;
|
||||||
|
_clientState = clientState;
|
||||||
|
_commandManager = commandManager;
|
||||||
|
|
||||||
|
_clientState.Login += RefreshCounts;
|
||||||
|
_clientState.Logout -= ClearCounts;
|
||||||
|
_questRegistry.Reloaded += OnQuestsReloaded;
|
||||||
|
|
||||||
|
SizeConstraints = new WindowSizeConstraints
|
||||||
|
{
|
||||||
|
MinimumSize = new Vector2(700, 500)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnQuestsReloaded(object? sender, EventArgs e) => RefreshCounts();
|
||||||
|
|
||||||
|
public override void OnOpen() => RefreshCounts();
|
||||||
|
|
||||||
|
public override void Draw()
|
||||||
|
{
|
||||||
|
ImGui.Text("The list below contains all quests that appear in your journal.");
|
||||||
|
ImGui.BulletText("'Supported' lists quests that Questionable can do for you");
|
||||||
|
ImGui.BulletText("'Completed' lists quests your current character has completed.");
|
||||||
|
ImGui.BulletText(
|
||||||
|
"Not all quests can be completed even if they're listed as available, e.g. starting city quest chains.");
|
||||||
|
|
||||||
|
ImGui.Spacing();
|
||||||
|
ImGui.Separator();
|
||||||
|
ImGui.Spacing();
|
||||||
|
|
||||||
|
using var table = ImRaii.Table("Quests", 3, ImGuiTableFlags.NoSavedSettings);
|
||||||
|
if (!table)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.NoHide);
|
||||||
|
ImGui.TableSetupColumn("Supported", ImGuiTableColumnFlags.WidthFixed, 120 * ImGui.GetIO().FontGlobalScale);
|
||||||
|
ImGui.TableSetupColumn("Completed", ImGuiTableColumnFlags.WidthFixed, 120 * ImGui.GetIO().FontGlobalScale);
|
||||||
|
ImGui.TableHeadersRow();
|
||||||
|
|
||||||
|
foreach (var section in _journalData.Sections)
|
||||||
|
{
|
||||||
|
DrawSection(section);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawSection(JournalData.Section section)
|
||||||
|
{
|
||||||
|
if (section.QuestCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
(int supported, int completed) = _sectionCounts.GetValueOrDefault(section);
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
bool open = ImGui.TreeNodeEx(section.Name, ImGuiTreeNodeFlags.SpanFullWidth);
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
DrawCount(supported, section.QuestCount);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
DrawCount(completed, section.QuestCount);
|
||||||
|
|
||||||
|
if (open)
|
||||||
|
{
|
||||||
|
foreach (var category in section.Categories)
|
||||||
|
DrawCategory(category);
|
||||||
|
|
||||||
|
ImGui.TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawCategory(JournalData.Category category)
|
||||||
|
{
|
||||||
|
if (category.QuestCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
(int supported, int completed) = _categoryCounts.GetValueOrDefault(category);
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
bool open = ImGui.TreeNodeEx(category.Name, ImGuiTreeNodeFlags.SpanFullWidth);
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
DrawCount(supported, category.QuestCount);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
DrawCount(completed, category.QuestCount);
|
||||||
|
|
||||||
|
if (open)
|
||||||
|
{
|
||||||
|
foreach (var genre in category.Genres)
|
||||||
|
DrawGenre(genre);
|
||||||
|
|
||||||
|
ImGui.TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawGenre(JournalData.Genre genre)
|
||||||
|
{
|
||||||
|
if (genre.QuestCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
(int supported, int completed) = _genreCounts.GetValueOrDefault(genre);
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
bool open = ImGui.TreeNodeEx(genre.Name, ImGuiTreeNodeFlags.SpanFullWidth);
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
DrawCount(supported, genre.QuestCount);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
DrawCount(completed, genre.QuestCount);
|
||||||
|
|
||||||
|
if (open)
|
||||||
|
{
|
||||||
|
foreach (var quest in genre.Quests)
|
||||||
|
DrawQuest(quest);
|
||||||
|
|
||||||
|
ImGui.TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawQuest(QuestInfo questInfo)
|
||||||
|
{
|
||||||
|
_questRegistry.TryGetQuest(questInfo.QuestId, out var quest);
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TreeNodeEx(questInfo.Name,
|
||||||
|
ImGuiTreeNodeFlags.Leaf | ImGuiTreeNodeFlags.NoTreePushOnOpen | ImGuiTreeNodeFlags.SpanFullWidth);
|
||||||
|
|
||||||
|
|
||||||
|
if (ImGui.IsItemClicked() && _commandManager.Commands.TryGetValue("/questinfo", out var commandInfo))
|
||||||
|
{
|
||||||
|
_commandManager.DispatchCommand("/questinfo",
|
||||||
|
questInfo.QuestId.ToString(CultureInfo.InvariantCulture), commandInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.IsItemHovered())
|
||||||
|
_questTooltipComponent.Draw(questInfo);
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
List<string> authors = quest?.Root.Author ?? [];
|
||||||
|
_uiUtils.ChecklistItem(authors.Count > 0 ? string.Join(", ", authors) : string.Empty,
|
||||||
|
quest is { Root.Disabled: false });
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
var (color, icon, text) = _uiUtils.GetQuestStyle(questInfo.QuestId);
|
||||||
|
_uiUtils.ChecklistItem(text, color, icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DrawCount(int count, int total)
|
||||||
|
{
|
||||||
|
string len = 9999.ToString(CultureInfo.CurrentCulture);
|
||||||
|
ImGui.PushFont(UiBuilder.MonoFont);
|
||||||
|
|
||||||
|
string text =
|
||||||
|
$"{count.ToString(CultureInfo.CurrentCulture).PadLeft(len.Length)} / {total.ToString(CultureInfo.CurrentCulture).PadLeft(len.Length)}";
|
||||||
|
if (count == total)
|
||||||
|
ImGui.TextColored(ImGuiColors.ParsedGreen, text);
|
||||||
|
else
|
||||||
|
ImGui.TextUnformatted(text);
|
||||||
|
|
||||||
|
ImGui.PopFont();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshCounts()
|
||||||
|
{
|
||||||
|
_genreCounts.Clear();
|
||||||
|
_categoryCounts.Clear();
|
||||||
|
_sectionCounts.Clear();
|
||||||
|
|
||||||
|
foreach (var genre in _journalData.Genres)
|
||||||
|
{
|
||||||
|
int available = genre.Quests.Count(x =>
|
||||||
|
_questRegistry.TryGetQuest(x.QuestId, out var quest) && !quest.Root.Disabled);
|
||||||
|
int completed = genre.Quests.Count(x => _gameFunctions.IsQuestComplete(x.QuestId));
|
||||||
|
_genreCounts[genre] = (available, completed);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var category in _journalData.Categories)
|
||||||
|
{
|
||||||
|
var counts = _genreCounts
|
||||||
|
.Where(x => category.Genres.Contains(x.Key))
|
||||||
|
.Select(x => x.Value)
|
||||||
|
.ToList();
|
||||||
|
int available = counts.Sum(x => x.Available);
|
||||||
|
int completed = counts.Sum(x => x.Completed);
|
||||||
|
_categoryCounts[category] = (available, completed);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var section in _journalData.Sections)
|
||||||
|
{
|
||||||
|
var counts = _categoryCounts
|
||||||
|
.Where(x => section.Categories.Contains(x.Key))
|
||||||
|
.Select(x => x.Value)
|
||||||
|
.ToList();
|
||||||
|
int available = counts.Sum(x => x.Available);
|
||||||
|
int completed = counts.Sum(x => x.Completed);
|
||||||
|
_sectionCounts[section] = (available, completed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearCounts()
|
||||||
|
{
|
||||||
|
foreach (var genreCount in _genreCounts.ToList())
|
||||||
|
_genreCounts[genreCount.Key] = (genreCount.Value.Available, 0);
|
||||||
|
|
||||||
|
foreach (var categoryCount in _categoryCounts.ToList())
|
||||||
|
_categoryCounts[categoryCount.Key] = (categoryCount.Value.Available, 0);
|
||||||
|
|
||||||
|
foreach (var sectionCount in _sectionCounts.ToList())
|
||||||
|
_sectionCounts[sectionCount.Key] = (sectionCount.Value.Available, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_questRegistry.Reloaded -= OnQuestsReloaded;
|
||||||
|
_clientState.Logout -= ClearCounts;
|
||||||
|
_clientState.Login -= RefreshCounts;
|
||||||
|
}
|
||||||
|
}
|
170
Questionable/Windows/QuestComponents/QuestTooltipComponent.cs
Normal file
170
Questionable/Windows/QuestComponents/QuestTooltipComponent.cs
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
using Dalamud.Interface.Colors;
|
||||||
|
using Dalamud.Interface.Utility.Raii;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
|
using ImGuiNET;
|
||||||
|
using Questionable.Controller;
|
||||||
|
using Questionable.Data;
|
||||||
|
using Questionable.Model;
|
||||||
|
|
||||||
|
namespace Questionable.Windows.QuestComponents;
|
||||||
|
|
||||||
|
internal sealed class QuestTooltipComponent
|
||||||
|
{
|
||||||
|
private readonly QuestRegistry _questRegistry;
|
||||||
|
private readonly QuestData _questData;
|
||||||
|
private readonly TerritoryData _territoryData;
|
||||||
|
private readonly GameFunctions _gameFunctions;
|
||||||
|
private readonly UiUtils _uiUtils;
|
||||||
|
|
||||||
|
public QuestTooltipComponent(
|
||||||
|
QuestRegistry questRegistry,
|
||||||
|
QuestData questData,
|
||||||
|
TerritoryData territoryData,
|
||||||
|
GameFunctions gameFunctions,
|
||||||
|
UiUtils uiUtils)
|
||||||
|
{
|
||||||
|
_questRegistry = questRegistry;
|
||||||
|
_questData = questData;
|
||||||
|
_territoryData = territoryData;
|
||||||
|
_gameFunctions = gameFunctions;
|
||||||
|
_uiUtils = uiUtils;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw(QuestInfo quest)
|
||||||
|
{
|
||||||
|
using var tooltip = ImRaii.Tooltip();
|
||||||
|
if (tooltip)
|
||||||
|
{
|
||||||
|
var (color, _, tooltipText) = _uiUtils.GetQuestStyle(quest.QuestId);
|
||||||
|
ImGui.TextColored(color, tooltipText);
|
||||||
|
if (quest.IsRepeatable)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted("Repeatable");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quest.CompletesInstantly)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted("Instant");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_questRegistry.IsKnownQuest(quest.QuestId))
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted("NoQuestPath");
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawQuestUnlocks(quest, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawQuestUnlocks(QuestInfo quest, int counter)
|
||||||
|
{
|
||||||
|
if (counter >= 10)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (counter != 0 && quest.IsMainScenarioQuest)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (counter > 0)
|
||||||
|
ImGui.Indent();
|
||||||
|
|
||||||
|
if (quest.PreviousQuests.Count > 0)
|
||||||
|
{
|
||||||
|
if (counter == 0)
|
||||||
|
ImGui.Separator();
|
||||||
|
|
||||||
|
if (quest.PreviousQuests.Count > 1)
|
||||||
|
{
|
||||||
|
if (quest.PreviousQuestJoin == QuestInfo.QuestJoin.All)
|
||||||
|
ImGui.Text("Requires all:");
|
||||||
|
else if (quest.PreviousQuestJoin == QuestInfo.QuestJoin.AtLeastOne)
|
||||||
|
ImGui.Text("Requires one:");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var q in quest.PreviousQuests)
|
||||||
|
{
|
||||||
|
var qInfo = _questData.GetQuestInfo(q);
|
||||||
|
var (iconColor, icon, _) = _uiUtils.GetQuestStyle(q);
|
||||||
|
if (!_questRegistry.IsKnownQuest(qInfo.QuestId))
|
||||||
|
iconColor = ImGuiColors.DalamudGrey;
|
||||||
|
|
||||||
|
_uiUtils.ChecklistItem(FormatQuestUnlockName(qInfo), iconColor, icon);
|
||||||
|
|
||||||
|
DrawQuestUnlocks(qInfo, counter + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counter == 0 && quest.QuestLocks.Count > 0)
|
||||||
|
{
|
||||||
|
ImGui.Separator();
|
||||||
|
if (quest.QuestLocks.Count > 1)
|
||||||
|
{
|
||||||
|
if (quest.QuestLockJoin == QuestInfo.QuestJoin.All)
|
||||||
|
ImGui.Text("Blocked by (if all completed):");
|
||||||
|
else if (quest.QuestLockJoin == QuestInfo.QuestJoin.AtLeastOne)
|
||||||
|
ImGui.Text("Blocked by (if at least completed):");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ImGui.Text("Blocked by (if completed):");
|
||||||
|
|
||||||
|
foreach (var q in quest.QuestLocks)
|
||||||
|
{
|
||||||
|
var qInfo = _questData.GetQuestInfo(q);
|
||||||
|
var (iconColor, icon, _) = _uiUtils.GetQuestStyle(q);
|
||||||
|
if (!_questRegistry.IsKnownQuest(qInfo.QuestId))
|
||||||
|
iconColor = ImGuiColors.DalamudGrey;
|
||||||
|
|
||||||
|
_uiUtils.ChecklistItem(FormatQuestUnlockName(qInfo), iconColor, icon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counter == 0 && quest.PreviousInstanceContent.Count > 0)
|
||||||
|
{
|
||||||
|
ImGui.Separator();
|
||||||
|
if (quest.PreviousInstanceContent.Count > 1)
|
||||||
|
{
|
||||||
|
if (quest.PreviousQuestJoin == QuestInfo.QuestJoin.All)
|
||||||
|
ImGui.Text("Requires all:");
|
||||||
|
else if (quest.PreviousQuestJoin == QuestInfo.QuestJoin.AtLeastOne)
|
||||||
|
ImGui.Text("Requires one:");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ImGui.Text("Requires:");
|
||||||
|
|
||||||
|
foreach (var instanceId in quest.PreviousInstanceContent)
|
||||||
|
{
|
||||||
|
string instanceName = _territoryData.GetInstanceName(instanceId) ?? "?";
|
||||||
|
var (iconColor, icon) = UiUtils.GetInstanceStyle(instanceId);
|
||||||
|
_uiUtils.ChecklistItem(instanceName, iconColor, icon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counter == 0 && quest.GrandCompany != GrandCompany.None)
|
||||||
|
{
|
||||||
|
ImGui.Separator();
|
||||||
|
string gcName = quest.GrandCompany switch
|
||||||
|
{
|
||||||
|
GrandCompany.Maelstrom => "Maelstrom",
|
||||||
|
GrandCompany.TwinAdder => "Twin Adder",
|
||||||
|
GrandCompany.ImmortalFlames => "Immortal Flames",
|
||||||
|
_ => "None",
|
||||||
|
};
|
||||||
|
|
||||||
|
GrandCompany currentGrandCompany = _gameFunctions.GetGrandCompany();
|
||||||
|
_uiUtils.ChecklistItem($"Grand Company: {gcName}", quest.GrandCompany == currentGrandCompany);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counter > 0)
|
||||||
|
ImGui.Unindent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatQuestUnlockName(QuestInfo questInfo)
|
||||||
|
{
|
||||||
|
if (questInfo.IsMainScenarioQuest)
|
||||||
|
return $"{questInfo.Name} ({questInfo.QuestId}, MSQ)";
|
||||||
|
else
|
||||||
|
return $"{questInfo.Name} ({questInfo.QuestId})";
|
||||||
|
}
|
||||||
|
}
|
@ -25,15 +25,25 @@ internal sealed class QuickAccessButtonsComponent
|
|||||||
private readonly QuestRegistry _questRegistry;
|
private readonly QuestRegistry _questRegistry;
|
||||||
private readonly NavmeshIpc _navmeshIpc;
|
private readonly NavmeshIpc _navmeshIpc;
|
||||||
private readonly QuestValidationWindow _questValidationWindow;
|
private readonly QuestValidationWindow _questValidationWindow;
|
||||||
|
private readonly JournalProgressWindow _journalProgressWindow;
|
||||||
private readonly IClientState _clientState;
|
private readonly IClientState _clientState;
|
||||||
private readonly ICondition _condition;
|
private readonly ICondition _condition;
|
||||||
private readonly IFramework _framework;
|
private readonly IFramework _framework;
|
||||||
private readonly ICommandManager _commandManager;
|
private readonly ICommandManager _commandManager;
|
||||||
|
|
||||||
public QuickAccessButtonsComponent(QuestController questController, MovementController movementController,
|
public QuickAccessButtonsComponent(QuestController questController,
|
||||||
GameUiController gameUiController, GameFunctions gameFunctions, ChatFunctions chatFunctions,
|
MovementController movementController,
|
||||||
QuestRegistry questRegistry, NavmeshIpc navmeshIpc, QuestValidationWindow questValidationWindow,
|
GameUiController gameUiController,
|
||||||
IClientState clientState, ICondition condition, IFramework framework, ICommandManager commandManager)
|
GameFunctions gameFunctions,
|
||||||
|
ChatFunctions chatFunctions,
|
||||||
|
QuestRegistry questRegistry,
|
||||||
|
NavmeshIpc navmeshIpc,
|
||||||
|
QuestValidationWindow questValidationWindow,
|
||||||
|
JournalProgressWindow journalProgressWindow,
|
||||||
|
IClientState clientState,
|
||||||
|
ICondition condition,
|
||||||
|
IFramework framework,
|
||||||
|
ICommandManager commandManager)
|
||||||
{
|
{
|
||||||
_questController = questController;
|
_questController = questController;
|
||||||
_movementController = movementController;
|
_movementController = movementController;
|
||||||
@ -43,6 +53,7 @@ internal sealed class QuickAccessButtonsComponent
|
|||||||
_questRegistry = questRegistry;
|
_questRegistry = questRegistry;
|
||||||
_navmeshIpc = navmeshIpc;
|
_navmeshIpc = navmeshIpc;
|
||||||
_questValidationWindow = questValidationWindow;
|
_questValidationWindow = questValidationWindow;
|
||||||
|
_journalProgressWindow = journalProgressWindow;
|
||||||
_clientState = clientState;
|
_clientState = clientState;
|
||||||
_condition = condition;
|
_condition = condition;
|
||||||
_framework = framework;
|
_framework = framework;
|
||||||
@ -80,6 +91,11 @@ internal sealed class QuickAccessButtonsComponent
|
|||||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.RedoAlt,"Reload Data"))
|
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.RedoAlt,"Reload Data"))
|
||||||
Reload();
|
Reload();
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGuiComponents.IconButton(FontAwesomeIcon.ChartColumn))
|
||||||
|
_journalProgressWindow.IsOpen = true;
|
||||||
|
|
||||||
|
|
||||||
if (_questRegistry.ValidationIssueCount > 0)
|
if (_questRegistry.ValidationIssueCount > 0)
|
||||||
{
|
{
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
@ -20,6 +20,7 @@ using Questionable.Controller;
|
|||||||
using Questionable.Data;
|
using Questionable.Data;
|
||||||
using Questionable.Model;
|
using Questionable.Model;
|
||||||
using Questionable.Model.V1;
|
using Questionable.Model.V1;
|
||||||
|
using Questionable.Windows.QuestComponents;
|
||||||
|
|
||||||
namespace Questionable.Windows;
|
namespace Questionable.Windows;
|
||||||
|
|
||||||
@ -36,6 +37,7 @@ internal sealed class QuestSelectionWindow : LWindow
|
|||||||
private readonly TerritoryData _territoryData;
|
private readonly TerritoryData _territoryData;
|
||||||
private readonly IClientState _clientState;
|
private readonly IClientState _clientState;
|
||||||
private readonly UiUtils _uiUtils;
|
private readonly UiUtils _uiUtils;
|
||||||
|
private readonly QuestTooltipComponent _questTooltipComponent;
|
||||||
|
|
||||||
private List<QuestInfo> _quests = [];
|
private List<QuestInfo> _quests = [];
|
||||||
private List<QuestInfo> _offeredQuests = [];
|
private List<QuestInfo> _offeredQuests = [];
|
||||||
@ -43,7 +45,8 @@ internal sealed class QuestSelectionWindow : LWindow
|
|||||||
|
|
||||||
public QuestSelectionWindow(QuestData questData, IGameGui gameGui, IChatGui chatGui, GameFunctions gameFunctions,
|
public QuestSelectionWindow(QuestData questData, IGameGui gameGui, IChatGui chatGui, GameFunctions gameFunctions,
|
||||||
QuestController questController, QuestRegistry questRegistry, IDalamudPluginInterface pluginInterface,
|
QuestController questController, QuestRegistry questRegistry, IDalamudPluginInterface pluginInterface,
|
||||||
TerritoryData territoryData, IClientState clientState, UiUtils uiUtils)
|
TerritoryData territoryData, IClientState clientState, UiUtils uiUtils,
|
||||||
|
QuestTooltipComponent questTooltipComponent)
|
||||||
: base($"Quest Selection{WindowId}")
|
: base($"Quest Selection{WindowId}")
|
||||||
{
|
{
|
||||||
_questData = questData;
|
_questData = questData;
|
||||||
@ -56,6 +59,7 @@ internal sealed class QuestSelectionWindow : LWindow
|
|||||||
_territoryData = territoryData;
|
_territoryData = territoryData;
|
||||||
_clientState = clientState;
|
_clientState = clientState;
|
||||||
_uiUtils = uiUtils;
|
_uiUtils = uiUtils;
|
||||||
|
_questTooltipComponent = questTooltipComponent;
|
||||||
|
|
||||||
Size = new Vector2(500, 200);
|
Size = new Vector2(500, 200);
|
||||||
SizeCondition = ImGuiCond.Once;
|
SizeCondition = ImGuiCond.Once;
|
||||||
@ -169,7 +173,7 @@ internal sealed class QuestSelectionWindow : LWindow
|
|||||||
if (ImGui.TableNextColumn())
|
if (ImGui.TableNextColumn())
|
||||||
{
|
{
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
var (color, icon, tooltipText) = _uiUtils.GetQuestStyle(quest.QuestId);
|
var (color, icon, _) = _uiUtils.GetQuestStyle(quest.QuestId);
|
||||||
using (var _ = _pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
using (var _ = _pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
||||||
{
|
{
|
||||||
if (isKnownQuest)
|
if (isKnownQuest)
|
||||||
@ -179,32 +183,7 @@ internal sealed class QuestSelectionWindow : LWindow
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.IsItemHovered())
|
if (ImGui.IsItemHovered())
|
||||||
{
|
_questTooltipComponent.Draw(quest);
|
||||||
using var tooltip = ImRaii.Tooltip();
|
|
||||||
if (tooltip)
|
|
||||||
{
|
|
||||||
ImGui.TextColored(color, tooltipText);
|
|
||||||
if (quest.IsRepeatable)
|
|
||||||
{
|
|
||||||
ImGui.SameLine();
|
|
||||||
ImGui.TextUnformatted("Repeatable");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quest.CompletesInstantly)
|
|
||||||
{
|
|
||||||
ImGui.SameLine();
|
|
||||||
ImGui.TextUnformatted("Instant");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isKnownQuest)
|
|
||||||
{
|
|
||||||
ImGui.SameLine();
|
|
||||||
ImGui.TextUnformatted("NoQuestPath");
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawQuestUnlocks(quest, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.TableNextColumn())
|
if (ImGui.TableNextColumn())
|
||||||
@ -272,113 +251,4 @@ internal sealed class QuestSelectionWindow : LWindow
|
|||||||
ImGui.SetClipboardText(fileName);
|
ImGui.SetClipboardText(fileName);
|
||||||
_chatGui.Print($"Copied '{fileName}' to clipboard");
|
_chatGui.Print($"Copied '{fileName}' to clipboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawQuestUnlocks(QuestInfo quest, int counter)
|
|
||||||
{
|
|
||||||
if (counter >= 10)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (counter != 0 && quest.IsMainScenarioQuest)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (counter > 0)
|
|
||||||
ImGui.Indent();
|
|
||||||
|
|
||||||
if (quest.PreviousQuests.Count > 0)
|
|
||||||
{
|
|
||||||
if (counter == 0)
|
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
if (quest.PreviousQuests.Count > 1)
|
|
||||||
{
|
|
||||||
if (quest.PreviousQuestJoin == QuestInfo.QuestJoin.All)
|
|
||||||
ImGui.Text("Requires all:");
|
|
||||||
else if (quest.PreviousQuestJoin == QuestInfo.QuestJoin.AtLeastOne)
|
|
||||||
ImGui.Text("Requires one:");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var q in quest.PreviousQuests)
|
|
||||||
{
|
|
||||||
var qInfo = _questData.GetQuestInfo(q);
|
|
||||||
var (iconColor, icon, _) = _uiUtils.GetQuestStyle(q);
|
|
||||||
if (!_questRegistry.IsKnownQuest(qInfo.QuestId))
|
|
||||||
iconColor = ImGuiColors.DalamudGrey;
|
|
||||||
|
|
||||||
_uiUtils.ChecklistItem(FormatQuestUnlockName(qInfo), iconColor, icon);
|
|
||||||
|
|
||||||
DrawQuestUnlocks(qInfo, counter + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (counter == 0 && quest.QuestLocks.Count > 0)
|
|
||||||
{
|
|
||||||
ImGui.Separator();
|
|
||||||
if (quest.QuestLocks.Count > 1)
|
|
||||||
{
|
|
||||||
if (quest.QuestLockJoin == QuestInfo.QuestJoin.All)
|
|
||||||
ImGui.Text("Blocked by (if all completed):");
|
|
||||||
else if (quest.QuestLockJoin == QuestInfo.QuestJoin.AtLeastOne)
|
|
||||||
ImGui.Text("Blocked by (if at least completed):");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ImGui.Text("Blocked by (if completed):");
|
|
||||||
|
|
||||||
foreach (var q in quest.QuestLocks)
|
|
||||||
{
|
|
||||||
var qInfo = _questData.GetQuestInfo(q);
|
|
||||||
var (iconColor, icon, _) = _uiUtils.GetQuestStyle(q);
|
|
||||||
if (!_questRegistry.IsKnownQuest(qInfo.QuestId))
|
|
||||||
iconColor = ImGuiColors.DalamudGrey;
|
|
||||||
|
|
||||||
_uiUtils.ChecklistItem(FormatQuestUnlockName(qInfo), iconColor, icon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (counter == 0 && quest.PreviousInstanceContent.Count > 0)
|
|
||||||
{
|
|
||||||
ImGui.Separator();
|
|
||||||
if (quest.PreviousInstanceContent.Count > 1)
|
|
||||||
{
|
|
||||||
if (quest.PreviousQuestJoin == QuestInfo.QuestJoin.All)
|
|
||||||
ImGui.Text("Requires all:");
|
|
||||||
else if (quest.PreviousQuestJoin == QuestInfo.QuestJoin.AtLeastOne)
|
|
||||||
ImGui.Text("Requires one:");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ImGui.Text("Requires:");
|
|
||||||
|
|
||||||
foreach (var instanceId in quest.PreviousInstanceContent)
|
|
||||||
{
|
|
||||||
string instanceName = _territoryData.GetInstanceName(instanceId) ?? "?";
|
|
||||||
var (iconColor, icon) = UiUtils.GetInstanceStyle(instanceId);
|
|
||||||
_uiUtils.ChecklistItem(instanceName, iconColor, icon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (counter == 0 && quest.GrandCompany != GrandCompany.None)
|
|
||||||
{
|
|
||||||
ImGui.Separator();
|
|
||||||
string gcName = quest.GrandCompany switch
|
|
||||||
{
|
|
||||||
GrandCompany.Maelstrom => "Maelstrom",
|
|
||||||
GrandCompany.TwinAdder => "Twin Adder",
|
|
||||||
GrandCompany.ImmortalFlames => "Immortal Flames",
|
|
||||||
_ => "None",
|
|
||||||
};
|
|
||||||
|
|
||||||
GrandCompany currentGrandCompany = _gameFunctions.GetGrandCompany();
|
|
||||||
_uiUtils.ChecklistItem($"Grand Company: {gcName}", quest.GrandCompany == currentGrandCompany);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (counter > 0)
|
|
||||||
ImGui.Unindent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FormatQuestUnlockName(QuestInfo questInfo)
|
|
||||||
{
|
|
||||||
if (questInfo.IsMainScenarioQuest)
|
|
||||||
return $"{questInfo.Name} ({questInfo.QuestId}, MSQ)";
|
|
||||||
else
|
|
||||||
return $"{questInfo.Name} ({questInfo.QuestId})";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user