using System; using System.Collections.Generic; using System.Linq; using System.Numerics; using Dalamud.Bindings.ImGui; using Dalamud.Interface; using Dalamud.Interface.Components; using Dalamud.Interface.Utility.Raii; using Dalamud.Plugin; using Dalamud.Plugin.Services; using Questionable.Controller; using Questionable.Functions; using Questionable.Model; using Questionable.Model.Questing; using Questionable.Windows.QuestComponents; using Questionable.Windows.Utils; namespace Questionable.Windows.ConfigComponents; internal sealed class StopConditionComponent : ConfigComponent { private readonly IDalamudPluginInterface _pluginInterface; private readonly QuestSelector _questSelector; private readonly QuestRegistry _questRegistry; private readonly QuestFunctions _questFunctions; private readonly QuestTooltipComponent _questTooltipComponent; private readonly UiUtils _uiUtils; private readonly IClientState _clientState; private readonly QuestController _questController; public StopConditionComponent(IDalamudPluginInterface pluginInterface, QuestSelector questSelector, QuestFunctions questFunctions, QuestRegistry questRegistry, QuestTooltipComponent questTooltipComponent, UiUtils uiUtils, IClientState clientState, QuestController questController, Configuration configuration) : base(pluginInterface, configuration) { StopConditionComponent stopConditionComponent = this; _pluginInterface = pluginInterface; _questSelector = questSelector; _questRegistry = questRegistry; _questFunctions = questFunctions; _questTooltipComponent = questTooltipComponent; _uiUtils = uiUtils; _clientState = clientState; _questController = questController; _questSelector.SuggestionPredicate = (Quest quest) => configuration.Stop.QuestsToStopAfter.All((ElementId x) => x != quest.Id); _questSelector.DefaultPredicate = (Quest quest) => quest.Info.IsMainScenarioQuest && questFunctions.IsQuestAccepted(quest.Id); _questSelector.QuestSelected = delegate(Quest quest) { configuration.Stop.QuestsToStopAfter.Add(quest.Id); stopConditionComponent.Save(); }; } public override void DrawTab() { using ImRaii.IEndObject endObject = ImRaii.TabItem("Stop###StopConditionns"); if (!endObject) { return; } bool v = base.Configuration.Stop.Enabled; if (ImGui.Checkbox("Stop Questionable when any of the conditions below are met", ref v)) { base.Configuration.Stop.Enabled = v; Save(); } ImGui.Separator(); using (ImRaii.Disabled(!v)) { ImGui.Text("Stop when character level reaches:"); bool v2 = base.Configuration.Stop.LevelToStopAfter; if (ImGui.Checkbox("Enable level stop condition", ref v2)) { base.Configuration.Stop.LevelToStopAfter = v2; Save(); } using (ImRaii.Disabled(!v2)) { int data = base.Configuration.Stop.TargetLevel; ImGui.SetNextItemWidth(100f); if (ImGui.InputInt("Stop at level", ref data, 1, 5)) { base.Configuration.Stop.TargetLevel = Math.Max(1, Math.Min(100, data)); Save(); } int num = _clientState.LocalPlayer?.Level ?? 0; if (num > 0) { ImGui.SameLine(); ImU8String text = new ImU8String(11, 1); text.AppendLiteral("(Current: "); text.AppendFormatted(num); text.AppendLiteral(")"); ImGui.TextDisabled(text); } } ImGui.Separator(); ImGui.Text("Stop when quest sequence reaches:"); bool v3 = base.Configuration.Stop.SequenceToStopAfter; if (ImGui.Checkbox("Enable quest sequence stop condition", ref v3)) { base.Configuration.Stop.SequenceToStopAfter = v3; Save(); } using (ImRaii.Disabled(!v3)) { int data2 = base.Configuration.Stop.TargetSequence; ImGui.SetNextItemWidth(100f); if (ImGui.InputInt("Stop at sequence", ref data2, 1, 1)) { base.Configuration.Stop.TargetSequence = Math.Max(0, Math.Min(255, data2)); Save(); } QuestController.QuestProgress currentQuest = _questController.CurrentQuest; if (currentQuest != null) { int sequence = currentQuest.Sequence; ImGui.SameLine(); ImU8String text = new ImU8String(11, 1); text.AppendLiteral("(Current: "); text.AppendFormatted(sequence); text.AppendLiteral(")"); ImGui.TextDisabled(text); } } ImGui.Separator(); ImGui.Text("Stop when completing any of the quests selected below:"); DrawCurrentlyAcceptedQuests(); _questSelector.DrawSelection(); List questsToStopAfter = base.Configuration.Stop.QuestsToStopAfter; if (questsToStopAfter.Count > 0) { using (ImRaii.Disabled(!ImGui.IsKeyDown(ImGuiKey.ModCtrl))) { if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Trash, "Clear All")) { base.Configuration.Stop.QuestsToStopAfter.Clear(); Save(); } } if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) { ImGui.SetTooltip("Hold CTRL to enable this button."); } ImGui.Separator(); } Quest quest = null; for (int i = 0; i < questsToStopAfter.Count; i++) { ElementId elementId = questsToStopAfter[i]; if (!_questRegistry.TryGetQuest(elementId, out Quest quest2)) { continue; } ImU8String text = new ImU8String(5, 1); text.AppendLiteral("Quest"); text.AppendFormatted(elementId); using (ImRaii.PushId(text)) { (Vector4, FontAwesomeIcon, string) questStyle = _uiUtils.GetQuestStyle(elementId); bool flag; using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push()) { ImGui.AlignTextToFramePadding(); ImGui.TextColored(in questStyle.Item1, questStyle.Item2.ToIconString()); flag = ImGui.IsItemHovered(); } ImGui.SameLine(); ImGui.AlignTextToFramePadding(); ImGui.Text(quest2.Info.Name); flag |= ImGui.IsItemHovered(); if (flag) { _questTooltipComponent.Draw(quest2.Info); } using (ImRaii.PushFont(UiBuilder.IconFont)) { ImGui.SameLine(ImGui.GetContentRegionAvail().X + ImGui.GetStyle().WindowPadding.X - ImGui.CalcTextSize(FontAwesomeIcon.Times.ToIconString()).X - ImGui.GetStyle().FramePadding.X * 2f); } if (ImGuiComponents.IconButton($"##Remove{i}", FontAwesomeIcon.Times)) { quest = quest2; } } } if (quest != null) { base.Configuration.Stop.QuestsToStopAfter.Remove(quest.Id); Save(); } } } private void DrawCurrentlyAcceptedQuests() { List currentlyAcceptedQuests = GetCurrentlyAcceptedQuests(); ImGui.Text("Currently Accepted Quests:"); using (ImRaii.IEndObject endObject = ImRaii.Child("AcceptedQuestsList", new Vector2(-1f, 120f), border: true)) { if (endObject) { if (currentlyAcceptedQuests.Count > 0) { foreach (Quest item in currentlyAcceptedQuests) { ImU8String id = new ImU8String(13, 1); id.AppendLiteral("AcceptedQuest"); id.AppendFormatted(item.Id); using (ImRaii.PushId(id)) { (Vector4, FontAwesomeIcon, string) questStyle = _uiUtils.GetQuestStyle(item.Id); bool flag = false; bool flag2 = base.Configuration.Stop.QuestsToStopAfter.Contains(item.Id); using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push()) { ImGui.AlignTextToFramePadding(); ImGui.TextColored(flag2 ? new Vector4(0.5f, 0.5f, 0.5f, 1f) : questStyle.Item1, questStyle.Item2.ToIconString()); flag = ImGui.IsItemHovered(); } ImGui.SameLine(); ImGui.AlignTextToFramePadding(); ImGui.TextColored(flag2 ? new Vector4(0.7f, 0.7f, 0.7f, 1f) : new Vector4(1f, 1f, 1f, 1f), item.Info.Name); if (flag | ImGui.IsItemHovered()) { _questTooltipComponent.Draw(item.Info); } using (ImRaii.PushFont(UiBuilder.IconFont)) { ImGui.SameLine(ImGui.GetContentRegionAvail().X + ImGui.GetStyle().WindowPadding.X - ImGui.CalcTextSize(FontAwesomeIcon.Plus.ToIconString()).X - ImGui.GetStyle().FramePadding.X * 2f); } using (ImRaii.Disabled(flag2)) { if (ImGuiComponents.IconButton($"##Add{item.Id}", FontAwesomeIcon.Plus)) { base.Configuration.Stop.QuestsToStopAfter.Add(item.Id); Save(); } } if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) { ImGui.SetTooltip(flag2 ? "Quest already added to stop conditions" : "Add this quest to stop conditions"); } } } } else { ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.7f, 0.7f, 0.7f, 1f)); ImGui.TextWrapped("No quests currently accepted"); ImGui.PopStyleColor(); } } } ImGui.Spacing(); } private List GetCurrentlyAcceptedQuests() { List list = new List(); try { foreach (Quest allQuest in _questRegistry.AllQuests) { if (_questFunctions.IsQuestAccepted(allQuest.Id)) { list.Add(allQuest); } } list.Sort((Quest a, Quest b) => string.Compare(a.Info.Name, b.Info.Name, StringComparison.OrdinalIgnoreCase)); } catch (Exception) { list.Clear(); } return list; } }