268 lines
8.4 KiB
C#
268 lines
8.4 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Game.ClientState.Objects.Types;
|
|
using Dalamud.Interface;
|
|
using Dalamud.Interface.Colors;
|
|
using Dalamud.Interface.Components;
|
|
using Dalamud.Interface.Utility.Raii;
|
|
using Dalamud.Interface.Windowing;
|
|
using Dalamud.Plugin;
|
|
using Dalamud.Plugin.Services;
|
|
using FFXIVClientStructs.FFXIV.Client.Game.UI;
|
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
|
using LLib.GameUI;
|
|
using LLib.ImGui;
|
|
using Questionable.Controller;
|
|
using Questionable.Controller.GameUi;
|
|
using Questionable.Data;
|
|
using Questionable.Functions;
|
|
using Questionable.Model;
|
|
using Questionable.Model.Questing;
|
|
using Questionable.Windows.QuestComponents;
|
|
|
|
namespace Questionable.Windows;
|
|
|
|
internal sealed class QuestSelectionWindow : LWindow
|
|
{
|
|
private const string WindowId = "###QuestionableQuestSelection";
|
|
|
|
private readonly QuestData _questData;
|
|
|
|
private readonly IGameGui _gameGui;
|
|
|
|
private readonly IChatGui _chatGui;
|
|
|
|
private readonly QuestFunctions _questFunctions;
|
|
|
|
private readonly QuestController _questController;
|
|
|
|
private readonly QuestRegistry _questRegistry;
|
|
|
|
private readonly IDalamudPluginInterface _pluginInterface;
|
|
|
|
private readonly TerritoryData _territoryData;
|
|
|
|
private readonly IClientState _clientState;
|
|
|
|
private readonly UiUtils _uiUtils;
|
|
|
|
private readonly QuestTooltipComponent _questTooltipComponent;
|
|
|
|
private List<IQuestInfo> _quests = new List<IQuestInfo>();
|
|
|
|
private List<IQuestInfo> _offeredQuests = new List<IQuestInfo>();
|
|
|
|
private bool _onlyAvailableQuests = true;
|
|
|
|
public QuestSelectionWindow(QuestData questData, IGameGui gameGui, IChatGui chatGui, QuestFunctions questFunctions, QuestController questController, QuestRegistry questRegistry, IDalamudPluginInterface pluginInterface, TerritoryData territoryData, IClientState clientState, UiUtils uiUtils, QuestTooltipComponent questTooltipComponent)
|
|
: base("Quest Selection###QuestionableQuestSelection")
|
|
{
|
|
_questData = questData;
|
|
_gameGui = gameGui;
|
|
_chatGui = chatGui;
|
|
_questFunctions = questFunctions;
|
|
_questController = questController;
|
|
_questRegistry = questRegistry;
|
|
_pluginInterface = pluginInterface;
|
|
_territoryData = territoryData;
|
|
_clientState = clientState;
|
|
_uiUtils = uiUtils;
|
|
_questTooltipComponent = questTooltipComponent;
|
|
base.Size = new Vector2(500f, 200f);
|
|
base.SizeCondition = ImGuiCond.Once;
|
|
base.SizeConstraints = new WindowSizeConstraints
|
|
{
|
|
MinimumSize = new Vector2(500f, 200f)
|
|
};
|
|
}
|
|
|
|
public unsafe void OpenForTarget(IGameObject? gameObject)
|
|
{
|
|
if (gameObject != null)
|
|
{
|
|
uint dataId = gameObject.DataId;
|
|
string value = gameObject.Name.ToString();
|
|
base.WindowName = $"Quests starting with {value} [{dataId}]{"###QuestionableQuestSelection"}";
|
|
_quests = _questData.GetAllByIssuerDataId(dataId);
|
|
if (_gameGui.TryGetAddonByName<AddonSelectIconString>("SelectIconString", out var addonPtr))
|
|
{
|
|
List<string?> answers = InteractionUiController.GetChoices(addonPtr);
|
|
_offeredQuests = _quests.Where((IQuestInfo x) => answers.Any((string y) => GameFunctions.GameStringEquals(x.Name, y))).ToList();
|
|
}
|
|
else
|
|
{
|
|
_offeredQuests = new List<IQuestInfo>();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_quests = new List<IQuestInfo>();
|
|
_offeredQuests = new List<IQuestInfo>();
|
|
}
|
|
base.IsOpenAndUncollapsed = _quests.Count > 0;
|
|
}
|
|
|
|
public unsafe void OpenForCurrentZone()
|
|
{
|
|
ushort territoryId = _clientState.TerritoryType;
|
|
string nameAndId = _territoryData.GetNameAndId(territoryId);
|
|
base.WindowName = "Quests starting in " + nameAndId + "###QuestionableQuestSelection";
|
|
_quests = (from x in _questRegistry.AllQuests
|
|
where x.FindSequence(0)?.FindStep(0)?.TerritoryId == territoryId
|
|
select _questData.GetQuestInfo(x.Id)).ToList();
|
|
foreach (ref MarkerInfo unacceptedQuestMarker in Map.Instance()->UnacceptedQuestMarkers)
|
|
{
|
|
MarkerInfo current = unacceptedQuestMarker;
|
|
QuestId questId = QuestId.FromRowId(current.ObjectiveId);
|
|
if (_quests.All((IQuestInfo q) => q.QuestId != questId))
|
|
{
|
|
_quests.Add(_questData.GetQuestInfo(questId));
|
|
}
|
|
}
|
|
_offeredQuests = new List<IQuestInfo>();
|
|
base.IsOpenAndUncollapsed = true;
|
|
}
|
|
|
|
public override void OnClose()
|
|
{
|
|
_quests = new List<IQuestInfo>();
|
|
_offeredQuests = new List<IQuestInfo>();
|
|
}
|
|
|
|
public override void DrawContent()
|
|
{
|
|
if (_offeredQuests.Count != 0)
|
|
{
|
|
ImGui.Checkbox("Only show quests currently offered", ref _onlyAvailableQuests);
|
|
}
|
|
using ImRaii.IEndObject endObject = ImRaii.Table("QuestSelection", 4, ImGuiTableFlags.Borders | ImGuiTableFlags.ScrollY);
|
|
if (!endObject)
|
|
{
|
|
ImGui.Text("Not table");
|
|
return;
|
|
}
|
|
float x;
|
|
using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
|
{
|
|
x = ImGui.CalcTextSize(FontAwesomeIcon.Copy.ToIconString()).X;
|
|
}
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
float initWidthOrWeight = ImGui.CalcTextSize(FontAwesomeIcon.Copy.ToIconString()).X + ImGui.CalcTextSize(FontAwesomeIcon.Copy.ToIconString()).X + ImGui.CalcTextSize(FontAwesomeIcon.Copy.ToIconString()).X + 6f * ImGui.GetStyle().FramePadding.X + 2f * ImGui.GetStyle().ItemSpacing.X;
|
|
ImGui.PopFont();
|
|
ImGui.TableSetupColumn("Id", ImGuiTableColumnFlags.WidthFixed, 50f * ImGui.GetIO().FontGlobalScale);
|
|
ImGui.TableSetupColumn("", ImGuiTableColumnFlags.WidthFixed, x);
|
|
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.None, 200f);
|
|
ImGui.TableSetupColumn("Actions", ImGuiTableColumnFlags.WidthFixed, initWidthOrWeight);
|
|
ImGui.TableHeadersRow();
|
|
foreach (IQuestInfo item in (_offeredQuests.Count != 0 && _onlyAvailableQuests) ? _offeredQuests : _quests)
|
|
{
|
|
ImGui.TableNextRow();
|
|
string text = item.QuestId.ToString();
|
|
Quest quest;
|
|
bool flag = _questRegistry.TryGetQuest(item.QuestId, out quest);
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
ImGui.AlignTextToFramePadding();
|
|
ImGui.TextUnformatted(text);
|
|
}
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
ImGui.AlignTextToFramePadding();
|
|
var (col, icon, _) = _uiUtils.GetQuestStyle(item.QuestId);
|
|
using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
|
{
|
|
if (flag)
|
|
{
|
|
ImGui.TextColored(in col, icon.ToIconString());
|
|
}
|
|
else
|
|
{
|
|
ImGui.TextColored(ImGuiColors.DalamudGrey, icon.ToIconString());
|
|
}
|
|
}
|
|
if (ImGui.IsItemHovered())
|
|
{
|
|
_questTooltipComponent.Draw(item);
|
|
}
|
|
}
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
ImGui.AlignTextToFramePadding();
|
|
if (quest != null && quest.Root.Disabled)
|
|
{
|
|
using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
|
{
|
|
ImGui.TextColored(ImGuiColors.DalamudOrange, FontAwesomeIcon.Ban.ToIconString());
|
|
ImGui.SameLine();
|
|
}
|
|
}
|
|
ImGui.TextUnformatted(item.Name);
|
|
}
|
|
if (!ImGui.TableNextColumn())
|
|
{
|
|
continue;
|
|
}
|
|
using (ImRaii.PushId(text))
|
|
{
|
|
bool num = ImGuiComponents.IconButton(FontAwesomeIcon.Copy);
|
|
if (ImGui.IsItemHovered())
|
|
{
|
|
ImGui.SetTooltip("Copy as file name");
|
|
}
|
|
if (num)
|
|
{
|
|
CopyToClipboard(item, suffix: true);
|
|
}
|
|
else if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
|
{
|
|
CopyToClipboard(item, suffix: false);
|
|
}
|
|
ImGui.SameLine();
|
|
if (quest == null)
|
|
{
|
|
continue;
|
|
}
|
|
EInteractionType? eInteractionType = quest.FindSequence(0)?.LastStep()?.InteractionType;
|
|
if (!eInteractionType.HasValue || eInteractionType != EInteractionType.AcceptQuest || !_questFunctions.IsReadyToAcceptQuest(item.QuestId))
|
|
{
|
|
continue;
|
|
}
|
|
ImGui.BeginDisabled(_questController.NextQuest != null || _questController.SimulatedQuest != null);
|
|
bool num2 = ImGuiComponents.IconButton(FontAwesomeIcon.Play);
|
|
if (ImGui.IsItemHovered())
|
|
{
|
|
ImGui.SetTooltip("Start as next quest");
|
|
}
|
|
if (num2)
|
|
{
|
|
_questController.SetNextQuest(quest);
|
|
if (!_questController.ManualPriorityQuests.Contains(quest))
|
|
{
|
|
_questController.ManualPriorityQuests.Insert(0, quest);
|
|
}
|
|
_questController.Start("QuestSelectionWindow");
|
|
}
|
|
ImGui.SameLine();
|
|
bool num3 = ImGuiComponents.IconButton(FontAwesomeIcon.AngleDoubleRight);
|
|
if (ImGui.IsItemHovered())
|
|
{
|
|
ImGui.SetTooltip("Set as next quest");
|
|
}
|
|
if (num3)
|
|
{
|
|
_questController.SetNextQuest(quest);
|
|
}
|
|
ImGui.EndDisabled();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CopyToClipboard(IQuestInfo quest, bool suffix)
|
|
{
|
|
string text = $"{quest.QuestId}_{quest.SimplifiedName}{(suffix ? ".json" : "")}";
|
|
ImGui.SetClipboardText(text);
|
|
_chatGui.Print("Copied '" + text + "' to clipboard");
|
|
}
|
|
}
|