using Dalamud.Bindings.ImGui; using Dalamud.Game.Text; using Dalamud.Interface; using Dalamud.Interface.Colors; using Dalamud.Interface.Utility.Raii; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using Questionable.Controller; using Questionable.Data; using Questionable.Functions; using Questionable.Model; using Questionable.Model.Questing; namespace Questionable.Windows.QuestComponents; internal sealed class QuestTooltipComponent { private readonly QuestRegistry _questRegistry; private readonly QuestData _questData; private readonly TerritoryData _territoryData; private readonly QuestFunctions _questFunctions; private readonly UiUtils _uiUtils; private readonly Configuration _configuration; public QuestTooltipComponent(QuestRegistry questRegistry, QuestData questData, TerritoryData territoryData, QuestFunctions questFunctions, UiUtils uiUtils, Configuration configuration) { _questRegistry = questRegistry; _questData = questData; _territoryData = territoryData; _questFunctions = questFunctions; _uiUtils = uiUtils; _configuration = configuration; } public void Draw(IQuestInfo questInfo) { using ImRaii.IEndObject endObject = ImRaii.Tooltip(); if (endObject) { DrawInner(questInfo, showItemRewards: true); } } public void DrawInner(IQuestInfo questInfo, bool showItemRewards) { ImU8String text = new ImU8String(0, 2); text.AppendFormatted(SeIconChar.LevelEn.ToIconString()); text.AppendFormatted(questInfo.Level); ImGui.Text(text); ImGui.SameLine(); var (col, _, text2) = _uiUtils.GetQuestStyle(questInfo.QuestId); ImGui.TextColored(in col, text2); if (questInfo is QuestInfo { IsSeasonalEvent: not false }) { ImGui.SameLine(); ImGui.TextUnformatted("Event"); } if (questInfo.IsRepeatable) { ImGui.SameLine(); ImGui.TextUnformatted("Repeatable"); } if (questInfo is QuestInfo { CompletesInstantly: not false }) { ImGui.SameLine(); ImGui.TextUnformatted("Instant"); } if (_questRegistry.TryGetQuest(questInfo.QuestId, out Quest quest)) { if (quest.Root.Disabled) { ImGui.SameLine(); ImGui.TextColored(ImGuiColors.DalamudRed, "Disabled"); } if (quest.Root.Author.Count == 1) { text = new ImU8String(8, 1); text.AppendLiteral("Author: "); text.AppendFormatted(quest.Root.Author[0]); ImGui.Text(text); } else { text = new ImU8String(9, 1); text.AppendLiteral("Authors: "); text.AppendFormatted(string.Join(", ", quest.Root.Author)); ImGui.Text(text); } } else { ImGui.SameLine(); ImGui.TextColored(ImGuiColors.DalamudRed, "NoQuestPath"); } DrawQuestUnlocks(questInfo, 0, showItemRewards); } private void DrawQuestUnlocks(IQuestInfo questInfo, int counter, bool showItemRewards) { if (counter >= 10 || (counter != 0 && questInfo.IsMainScenarioQuest)) { return; } if (counter > 0) { ImGui.Indent(); } if (questInfo.PreviousQuests.Count > 0) { if (counter == 0) { ImGui.Separator(); } if (questInfo.PreviousQuests.Count > 1) { if (questInfo.PreviousQuestJoin == EQuestJoin.All) { ImGui.Text("Requires all:"); } else if (questInfo.PreviousQuestJoin == EQuestJoin.AtLeastOne) { ImGui.Text("Requires one:"); } } foreach (PreviousQuestInfo previousQuest in questInfo.PreviousQuests) { if (_questData.TryGetQuestInfo(previousQuest.QuestId, out IQuestInfo questInfo2)) { var (color, fontAwesomeIcon, _) = _uiUtils.GetQuestStyle(previousQuest.QuestId); if (!_questRegistry.IsKnownQuest(questInfo2.QuestId)) { color = ImGuiColors.DalamudGrey; } _uiUtils.ChecklistItem(FormatQuestUnlockName(questInfo2, (byte)((!_questFunctions.IsQuestComplete(previousQuest.QuestId)) ? previousQuest.Sequence : 0)), color, fontAwesomeIcon); if (questInfo2 is QuestInfo questInfo3 && (counter <= 2 || fontAwesomeIcon != FontAwesomeIcon.Check)) { DrawQuestUnlocks(questInfo3, counter + 1, showItemRewards: false); } } else { using (ImRaii.Disabled()) { _uiUtils.ChecklistItem($"Unknown Quest ({previousQuest.QuestId})", ImGuiColors.DalamudGrey, FontAwesomeIcon.Question); } } } } if (questInfo is QuestInfo questInfo4) { if (questInfo4.MoogleDeliveryLevel > 0) { ImU8String text = new ImU8String(23, 1); text.AppendLiteral("Requires Carrier Level "); text.AppendFormatted(questInfo4.MoogleDeliveryLevel); ImGui.Text(text); } if (counter == 0 && questInfo4.QuestLocks.Count > 0) { ImGui.Separator(); if (questInfo4.QuestLocks.Count > 1) { if (questInfo4.QuestLockJoin == EQuestJoin.All) { ImGui.Text("Blocked by (if all completed):"); } else if (questInfo4.QuestLockJoin == EQuestJoin.AtLeastOne) { ImGui.Text("Blocked by (if at least completed):"); } } else { ImGui.Text("Blocked by (if completed):"); } foreach (QuestId questLock in questInfo4.QuestLocks) { IQuestInfo questInfo5 = _questData.GetQuestInfo(questLock); var (color2, icon, _) = _uiUtils.GetQuestStyle(questLock); if (!_questRegistry.IsKnownQuest(questInfo5.QuestId)) { color2 = ImGuiColors.DalamudGrey; } _uiUtils.ChecklistItem(FormatQuestUnlockName(questInfo5, 0), color2, icon); } } if (counter == 0 && questInfo4.PreviousInstanceContent.Count > 0) { ImGui.Separator(); if (questInfo4.PreviousInstanceContent.Count > 1) { if (questInfo.PreviousQuestJoin == EQuestJoin.All) { ImGui.Text("Requires all:"); } else if (questInfo.PreviousQuestJoin == EQuestJoin.AtLeastOne) { ImGui.Text("Requires one:"); } } else { ImGui.Text("Requires:"); } foreach (ushort item in questInfo4.PreviousInstanceContent) { string text2 = _territoryData.GetInstanceName(item) ?? "?"; var (color3, icon2) = UiUtils.GetInstanceStyle(item); _uiUtils.ChecklistItem(text2, color3, icon2); } } if (counter == 0 && questInfo4.GrandCompany != GrandCompany.None) { ImGui.Separator(); string text3 = questInfo4.GrandCompany switch { GrandCompany.Maelstrom => "Maelstrom", GrandCompany.TwinAdder => "Twin Adder", GrandCompany.ImmortalFlames => "Immortal Flames", _ => "None", }; GrandCompany grandCompany = _questFunctions.GetGrandCompany(); _uiUtils.ChecklistItem("Grand Company: " + text3, questInfo4.GrandCompany == grandCompany); } if (showItemRewards && questInfo4.ItemRewards.Count > 0) { ImGui.Separator(); ImGui.Text("Item Rewards:"); foreach (ItemReward itemReward in questInfo4.ItemRewards) { ImGui.BulletText(itemReward.Name); } } } if (counter > 0) { ImGui.Unindent(); } } private string FormatQuestUnlockName(IQuestInfo questInfo, byte sequence = 0) { string text = questInfo.Name; if (_configuration.Advanced.AdditionalStatusInformation && sequence != 0) { text = text + " " + SeIconChar.ItemLevel.ToIconString(); } if (questInfo.IsMainScenarioQuest) { return text + $" ({questInfo.QuestId}, MSQ)"; } return text + $" ({questInfo.QuestId})"; } }